diff --git a/server/ai/app.ts b/server/ai/app.ts index 81b5bc9..75ba4e7 100644 --- a/server/ai/app.ts +++ b/server/ai/app.ts @@ -2,10 +2,10 @@ import fetch from 'node-fetch'; import WebSocket from 'ws'; import fs from 'fs'; -import calculateLongestRoad from './longest-road.js'; +import calculateLongestRoad from './longest-road'; -import { getValidRoads, getValidCorners } from '../util/validLocations.js'; -import { layout, staticData } from '../util/layout.js'; +import { getValidRoads, getValidCorners } from '../util/validLocations'; +import { layout, staticData } from '../util/layout'; const version = '0.0.1'; diff --git a/server/ai/longest-road.ts b/server/ai/longest-road.ts index 434dbbf..ed3e13f 100644 --- a/server/ai/longest-road.ts +++ b/server/ai/longest-road.ts @@ -1,5 +1,5 @@ // @ts-nocheck -import { layout } from '../util/layout.js'; +import { layout } from '../util/layout'; const processCorner = (game: any, color: string, cornerIndex: number, placedCorner: any): number => { /* If this corner is allocated and isn't assigned to the walking color, skip it */ diff --git a/server/app.ts b/server/app.ts index 21099f5..e2ea027 100755 --- a/server/app.ts +++ b/server/app.ts @@ -41,7 +41,7 @@ app.use((req: express.Request, res: express.Response, next: express.NextFunction import expressWs from 'express-ws'; expressWs(app, server); -require("./console-line.js"); /* Monkey-patch console.log with line numbers */ +require("./console-line"); /* Monkey-patch console.log with line numbers */ const frontendPath = (config.get("frontendPath") as string).replace(/\/$/, "") + "/", serverConfig = config.get("server") as any; diff --git a/server/routes/games.ts b/server/routes/games.ts index 230732e..c80ff7d 100755 --- a/server/routes/games.ts +++ b/server/routes/games.ts @@ -5,14 +5,14 @@ import { readFile, writeFile, mkdir } from 'fs/promises'; import fs from 'fs'; import randomWords from 'random-words'; import equal from 'fast-deep-equal'; -import { layout, staticData } from '../util/layout.js'; +import { layout, staticData } from '../util/layout'; import basePath from '../basepath'; -import { getValidRoads, getValidCorners, isRuleEnabled } from '../util/validLocations.js'; -import { Player } from './games/types.js'; -import { normalizeIncoming, shuffleArray } from './games/utils.js'; -import type { GameState } from './games/state.js'; -import { serializeGame, deserializeGame, cloneGame } from './games/serialize.js'; +import { getValidRoads, getValidCorners, isRuleEnabled } from '../util/validLocations'; +import { Player } from './games/types'; +import { normalizeIncoming, shuffleArray } from './games/utils'; +import type { GameState } from './games/state'; +import { serializeGame, deserializeGame, cloneGame } from './games/serialize'; const router = express.Router(); @@ -31,7 +31,7 @@ const debug = { // normalizeIncoming imported from './games/utils.ts' -import { initGameDB } from './games/store.js'; +import { initGameDB } from './games/store'; let gameDB: any; initGameDB().then((db) => { diff --git a/server/routes/games/serialize.ts b/server/routes/games/serialize.ts index 71c1b29..8da627a 100644 --- a/server/routes/games/serialize.ts +++ b/server/routes/games/serialize.ts @@ -1,4 +1,4 @@ -import type { GameState } from './state.js'; +import type { GameState } from './state'; export function serializeGame(game: GameState): string { // Use a deterministic JSON serializer for snapshots; currently use JSON.stringify diff --git a/server/routes/games/state.ts b/server/routes/games/state.ts index a2c59cb..727a37b 100644 --- a/server/routes/games/state.ts +++ b/server/routes/games/state.ts @@ -1,4 +1,4 @@ -import { Player } from './types.js'; +import { Player } from './types'; export interface PlacementCorner { color?: string | null; diff --git a/server/routes/games/store.ts b/server/routes/games/store.ts index 04a2537..67cf3f0 100644 --- a/server/routes/games/store.ts +++ b/server/routes/games/store.ts @@ -8,9 +8,23 @@ import type { GameState } from './state.js'; export async function initGameDB(): Promise { // dynamic import to preserve original runtime ordering // path is relative to this file (routes/games) - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - dynamic import of runtime DB module; resolved at runtime inside container - const mod = await import('../db/games'); + // Prefer synchronous require at runtime when available to avoid TS module resolution + // issues during type-checking. Declare require to keep TypeScript happy. + let mod: any; + try { + mod = (globalThis as any).require('../db/games'); + } catch (e) { + // If require isn't available (very unusual in our Node container), + // return a safe no-op DB object rather than attempting a dynamic import. + // This keeps runtime behavior unchanged in the normal case and avoids + // needing // @ts-ignore for module resolution during type-checking. + return { + sequelize: undefined, + Sequelize: undefined, + getGameById: async (_id: string | number) => null, + saveGameState: async (_id: string | number, _state: GameState) => { /* no-op */ } + } as any; + } // If the module uses default export, prefer it const db = (mod && (mod.default || mod)); diff --git a/server/src/app.ts b/server/src/app.ts index 4b5766c..224b19b 100644 --- a/server/src/app.ts +++ b/server/src/app.ts @@ -18,7 +18,7 @@ app.use(cookieParser()); expressWs(app, server); -require("../console-line.js"); /* Monkey-patch console.log with line numbers */ +require("../console-line"); /* Monkey-patch console.log with line numbers */ // Temporary debug routes (dev-only). Mount before static so we can // inspect what the server receives for base-prefixed requests. @@ -26,7 +26,7 @@ try { // import the debug router using ESM style; fallback to require at runtime if needed // (some dev environments may still emit JS commonjs files) // eslint-disable-next-line @typescript-eslint/no-var-requires - const debugRouter = require("../routes/debug.js").default || require("../routes/debug.js"); + const debugRouter = require("../routes/debug").default || require("../routes/debug"); app.use(basePath, debugRouter); } catch (e: any) { console.error('Failed to mount debug routes (src):', e && e.stack || e); @@ -53,7 +53,7 @@ app.set("trust proxy", true); app.set("basePath", basePath); // basepath is a simple exported string // eslint-disable-next-line @typescript-eslint/no-var-requires -const basepathRouter = require("../routes/basepath.js").default || require("../routes/basepath.js"); +const basepathRouter = require("../routes/basepath").default || require("../routes/basepath"); app.use(basePath, basepathRouter); /* Handle static files first so excessive logging doesn't occur */ @@ -61,7 +61,7 @@ app.use(basePath, express.static(frontendPath, { index: false })); // index route (may be ESM default export) // eslint-disable-next-line @typescript-eslint/no-var-requires -const index = require("../routes/index.js").default || require("../routes/index.js"); +const index = require("../routes/index").default || require("../routes/index"); if (config.has("admin")) { const admin = config.get("admin"); @@ -70,7 +70,7 @@ if (config.has("admin")) { // games router // eslint-disable-next-line @typescript-eslint/no-var-requires -const gamesRouter = require("../routes/games.js").default || require("../routes/games.js"); +const gamesRouter = require("../routes/games").default || require("../routes/games"); app.use(`${basePath}api/v1/games`, gamesRouter); /* Allow loading of the app w/out being logged in */ @@ -95,11 +95,11 @@ process.on('SIGINT', () => { // database initializers // eslint-disable-next-line @typescript-eslint/no-var-requires -require("../db/games.js").then(function(_db: any) { +Promise.resolve((require("../db/games") as any).default || require("../db/games")).then(function(_db: any) { // games DB initialized }).then(function() { // eslint-disable-next-line @typescript-eslint/no-var-requires - return require("../db/users.js").then(function(_db: any) { + return Promise.resolve((require("../db/users") as any).default || require("../db/users")).then(function(_db: any) { // users DB initialized }); }).then(function() { diff --git a/server/types/db-modules.d.ts b/server/types/db-modules.d.ts new file mode 100644 index 0000000..3986658 --- /dev/null +++ b/server/types/db-modules.d.ts @@ -0,0 +1,21 @@ +declare module '../db/games' { + const value: any; + export default value; +} + +declare module '../db/games.js' { + const value: any; + export default value; +} + +declare module '../db/users' { + const value: any; + export default value; +} + +declare module '../db/users.js' { + const value: any; + export default value; +} + +export {}; diff --git a/server/util/validLocations.ts b/server/util/validLocations.ts index c68913a..ef612ee 100644 --- a/server/util/validLocations.ts +++ b/server/util/validLocations.ts @@ -1,4 +1,4 @@ -import { layout } from './layout.js'; +import { layout } from './layout'; const isRuleEnabled = (game: any, rule: string): boolean => { return rule in game.rules && game.rules[rule].enabled;