From 08516fda1498f51c1f63657103b2b92cb9efce42 Mon Sep 17 00:00:00 2001 From: gitea-actions Date: Tue, 11 Aug 2026 13:40:14 +0100 Subject: [PATCH] Serve Two Rivers modules with production MIME type --- .../two-rivers/core/{content.mjs => content.js} | 1 + .../games/two-rivers/core/{save.mjs => save.js} | 2 +- .../games/two-rivers/core/{state.mjs => state.js} | 1 + assets/scripts/games/two-rivers/main.js | 12 ++++++------ .../scenes/{game-scenes.mjs => game-scenes.js} | 2 +- .../two-rivers/systems/{audio.mjs => audio.js} | 1 + .../two-rivers/ui/{interface.mjs => interface.js} | 2 +- play/two-rivers.org | 2 +- tests/two-rivers/game.test.mjs | 14 ++++++++------ 9 files changed, 21 insertions(+), 16 deletions(-) rename assets/scripts/games/two-rivers/core/{content.mjs => content.js} (97%) rename assets/scripts/games/two-rivers/core/{save.mjs => save.js} (98%) rename assets/scripts/games/two-rivers/core/{state.mjs => state.js} (99%) rename assets/scripts/games/two-rivers/scenes/{game-scenes.mjs => game-scenes.js} (99%) rename assets/scripts/games/two-rivers/systems/{audio.mjs => audio.js} (97%) rename assets/scripts/games/two-rivers/ui/{interface.mjs => interface.js} (99%) diff --git a/assets/scripts/games/two-rivers/core/content.mjs b/assets/scripts/games/two-rivers/core/content.js similarity index 97% rename from assets/scripts/games/two-rivers/core/content.mjs rename to assets/scripts/games/two-rivers/core/content.js index fca5667..85dd3bc 100644 --- a/assets/scripts/games/two-rivers/core/content.mjs +++ b/assets/scripts/games/two-rivers/core/content.js @@ -1,3 +1,4 @@ +// Served as .js so strict production MIME checks accept this native ES module. const ROOT = "/assets/games/two-rivers/data"; const FILES = { assets: "assets.json", diff --git a/assets/scripts/games/two-rivers/core/save.mjs b/assets/scripts/games/two-rivers/core/save.js similarity index 98% rename from assets/scripts/games/two-rivers/core/save.mjs rename to assets/scripts/games/two-rivers/core/save.js index aee61f5..9e10526 100644 --- a/assets/scripts/games/two-rivers/core/save.mjs +++ b/assets/scripts/games/two-rivers/core/save.js @@ -1,4 +1,4 @@ -import {normalizeState} from "./state.mjs"; +import {normalizeState} from "./state.js"; export const SAVE_KEY = "zxh_two_rivers_saves_v1"; export const SETTINGS_KEY = "zxh_two_rivers_settings_v1"; diff --git a/assets/scripts/games/two-rivers/core/state.mjs b/assets/scripts/games/two-rivers/core/state.js similarity index 99% rename from assets/scripts/games/two-rivers/core/state.mjs rename to assets/scripts/games/two-rivers/core/state.js index 597255d..81f92af 100644 --- a/assets/scripts/games/two-rivers/core/state.mjs +++ b/assets/scripts/games/two-rivers/core/state.js @@ -1,3 +1,4 @@ +// Native ES module; the .js suffix matches the production server's JavaScript MIME mapping. export const RELATIONSHIPS = ["trust", "respect", "comfort", "humour", "adventure", "romance", "familyApproval"]; export const SAVE_VERSION = 1; diff --git a/assets/scripts/games/two-rivers/main.js b/assets/scripts/games/two-rivers/main.js index c3c0ff2..cc5210f 100644 --- a/assets/scripts/games/two-rivers/main.js +++ b/assets/scripts/games/two-rivers/main.js @@ -1,9 +1,9 @@ -import {loadContent} from "./core/content.mjs"; -import {createStore, freshState} from "./core/state.mjs"; -import {createSaveService} from "./core/save.mjs"; -import {AudioDirector} from "./systems/audio.mjs"; -import {Interface} from "./ui/interface.mjs"; -import {createScenes} from "./scenes/game-scenes.mjs"; +import {loadContent} from "./core/content.js"; +import {createStore, freshState} from "./core/state.js"; +import {createSaveService} from "./core/save.js"; +import {AudioDirector} from "./systems/audio.js"; +import {Interface} from "./ui/interface.js"; +import {createScenes} from "./scenes/game-scenes.js"; const root = document.querySelector("[data-two-rivers]"); diff --git a/assets/scripts/games/two-rivers/scenes/game-scenes.mjs b/assets/scripts/games/two-rivers/scenes/game-scenes.js similarity index 99% rename from assets/scripts/games/two-rivers/scenes/game-scenes.mjs rename to assets/scripts/games/two-rivers/scenes/game-scenes.js index b5b8f86..fb5659a 100644 --- a/assets/scripts/games/two-rivers/scenes/game-scenes.mjs +++ b/assets/scripts/games/two-rivers/scenes/game-scenes.js @@ -1,4 +1,4 @@ -import {requirementMet} from "../core/state.mjs"; +import {requirementMet} from "../core/state.js"; const WIDTH = 1280; const HEIGHT = 720; diff --git a/assets/scripts/games/two-rivers/systems/audio.mjs b/assets/scripts/games/two-rivers/systems/audio.js similarity index 97% rename from assets/scripts/games/two-rivers/systems/audio.mjs rename to assets/scripts/games/two-rivers/systems/audio.js index 8b2a918..dc554b3 100644 --- a/assets/scripts/games/two-rivers/systems/audio.mjs +++ b/assets/scripts/games/two-rivers/systems/audio.js @@ -1,3 +1,4 @@ +// Native ES module served with the production JavaScript MIME type. export class AudioDirector { constructor(records, getSettings) { this.getSettings = getSettings; diff --git a/assets/scripts/games/two-rivers/ui/interface.mjs b/assets/scripts/games/two-rivers/ui/interface.js similarity index 99% rename from assets/scripts/games/two-rivers/ui/interface.mjs rename to assets/scripts/games/two-rivers/ui/interface.js index 5752d9d..7132bf2 100644 --- a/assets/scripts/games/two-rivers/ui/interface.mjs +++ b/assets/scripts/games/two-rivers/ui/interface.js @@ -1,4 +1,4 @@ -import {applyEffects, relationshipStage, RELATIONSHIPS, requirementMet, resolveEnding} from "../core/state.mjs"; +import {applyEffects, relationshipStage, RELATIONSHIPS, requirementMet, resolveEnding} from "../core/state.js"; const LABELS = { trust: "Trust", respect: "Respect", comfort: "Comfort", humour: "Humour", diff --git a/play/two-rivers.org b/play/two-rivers.org index f7696ac..d912e5b 100644 --- a/play/two-rivers.org +++ b/play/two-rivers.org @@ -98,6 +98,6 @@ - + #+END_EXPORT diff --git a/tests/two-rivers/game.test.mjs b/tests/two-rivers/game.test.mjs index 220b80e..78cbbc2 100644 --- a/tests/two-rivers/game.test.mjs +++ b/tests/two-rivers/game.test.mjs @@ -6,9 +6,9 @@ import {fileURLToPath} from "node:url"; import { applyEffects, createStore, freshState, normalizeState, relationshipStage, resolveEnding, requirementMet, RELATIONSHIPS -} from "../../assets/scripts/games/two-rivers/core/state.mjs"; -import {validateContent} from "../../assets/scripts/games/two-rivers/core/content.mjs"; -import {createSaveService, SAVE_KEY} from "../../assets/scripts/games/two-rivers/core/save.mjs"; +} from "../../assets/scripts/games/two-rivers/core/state.js"; +import {validateContent} from "../../assets/scripts/games/two-rivers/core/content.js"; +import {createSaveService, SAVE_KEY} from "../../assets/scripts/games/two-rivers/core/save.js"; const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); const read = (file) => fs.readFileSync(path.join(root, file), "utf8"); @@ -134,17 +134,19 @@ test("page uses local pinned libraries and production source is clean", () => { assert.match(page, /gsap-3\.13\.0\.min\.js/); assert.match(page, /howler-2\.2\.4\.min\.js/); assert.match(page, /games\/two-rivers\/gate\.js\?v=1\.0\.1/); + assert.match(page, /games\/two-rivers\/main\.js\?v=1\.0\.2/); assert.doesNotMatch(page, /https?:\/\//); const source = [ page, read("assets/scripts/games/two-rivers/main.js"), read("assets/scripts/games/two-rivers/gate.js"), - read("assets/scripts/games/two-rivers/core/state.mjs"), - read("assets/scripts/games/two-rivers/ui/interface.mjs"), - read("assets/scripts/games/two-rivers/scenes/game-scenes.mjs") + read("assets/scripts/games/two-rivers/core/state.js"), + read("assets/scripts/games/two-rivers/ui/interface.js"), + read("assets/scripts/games/two-rivers/scenes/game-scenes.js") ].join("\n"); assert.doesNotMatch(source, /\bTODO\b|placeholder implementation|lorem ipsum/i); assert.doesNotMatch(source, /\bReact\b|\bVue\b|\bAngular\b|\bjQuery\b/); + assert.doesNotMatch(source, /\.mjs(?:["'?#]|$)/, "production runtime must use the server's JavaScript MIME mapping"); assert.ok(read("assets/styles/pages/two-rivers.css").length > 15000); });