From 147bbce99ac7534609b40407c7b1e56a3738044d Mon Sep 17 00:00:00 2001 From: "tsevasa@gmail.com" Date: Sun, 14 Jul 2024 02:29:32 +0200 Subject: [PATCH 01/16] Automatic bundling (+ minification in production mode) --- build.mjs | 69 ++++++++++--------- src/client/views/play.html | 138 +------------------------------------ 2 files changed, 38 insertions(+), 169 deletions(-) diff --git a/build.mjs b/build.mjs index 088ec23c8..a5a0113d4 100644 --- a/build.mjs +++ b/build.mjs @@ -1,10 +1,6 @@ import { readdir, cp as copy, rm as remove, readFile, writeFile } from "node:fs/promises"; import { minify } from "terser"; import { DEV_BUILD } from "./src/server/config/config.js"; -import { exit } from "node:process"; - -/** Whether to generate source maps in production */ -const generateSourceMapsInProduction = false; /** * @@ -30,28 +26,22 @@ async function getExtFiles(path, ext) { return files; } -/** - * @param {string} path - * @returns {string} - */ -function getFilenamePath(path) { - const places = path.split("/"); - return places[places.length-1]; -} - +// remove dist await remove("./dist", { recursive: true, force: true, }); +// copy all clientside files over to dist except for the scripts await copy("./src/client", "./dist", { recursive: true, force: true, + filter: filename => { return !/src\/client\/scripts\//.test(filename)} }); -if (DEV_BUILD) exit(); - +// get all client scripts: const clientScript = await getExtFiles("./src/client/scripts", ".js"); +// Not yet implemented: get all client css: const clientStyle = []; // await getExtFiles("./src/client/css", ".css"); const clientFiles = []; @@ -60,27 +50,42 @@ clientFiles.push( ...clientStyle.map(v => `css/${v}`) ); -const filesToWrite = []; +const filesToWrite = []; // array of output files +let gamecode = ""; // string containing all code in /game except for htmlscript.js for (const file of clientFiles) { - const code = await readFile(`./src/client/${file}`, 'utf8'); - - const minifyInput = {}; - minifyInput[`/src/client/${file}`] = code; + // If the file is either a css file or htmlscript.js or not in /game, then copy it over in dev mode, or minify it in production mode: + if (/\.css$/.test(file) || /\/htmlscript\.js$/.test(file) || !/\/game\//.test(file) ){ + if (DEV_BUILD){ + await copy(`./src/client/${file}`, `./dist/${file}` , {force: true} ); + } else { + const code = await readFile(`./src/client/${file}`, 'utf8'); + const minifyInput = {}; + minifyInput[`/src/client/${file}`] = code; + const minified = await minify(code, { + mangle: true, // Disable variable name mangling + compress: true, // Enable compression + sourceMap: false + }); + filesToWrite.push(writeFile(`./dist/${file}`, minified.code, 'utf8')); + } + } + // Collect the code of all js files in /game except for htmlscript.js: + else{ + gamecode += await readFile(`./src/client/${file}`, 'utf8'); + } +} - const minified = await minify(minifyInput, { - mangle: true, // Disable variable name mangling - compress: true, // Enable compression - sourceMap: generateSourceMapsInProduction ? { - includeSources: true, - url: `${getFilenamePath(file)}.map`, - } : false +// Combine all gamecode files into app.js, and minify them in dev mode +if (DEV_BUILD){ + filesToWrite.push(writeFile(`./dist/scripts/game/app.js`, gamecode, 'utf8')); +} else{ + const minifiedgame = await minify(gamecode, { + mangle: true, + compress: true, + sourceMap: false }); - - filesToWrite.push(writeFile(`./dist/${file}`, minified.code, 'utf8')); - if (generateSourceMapsInProduction) { - filesToWrite.push(writeFile(`./dist/${file}.map`, minified.map, 'utf8') ) - } + filesToWrite.push(writeFile(`./dist/scripts/game/app.js`, minifiedgame.code, 'utf8')); } await Promise.all(filesToWrite); \ No newline at end of file diff --git a/src/client/views/play.html b/src/client/views/play.html index 35d63fdbd..5c9ed13cf 100644 --- a/src/client/views/play.html +++ b/src/client/views/play.html @@ -19,143 +19,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 48897bf760fcf3fa6c9f3134de3f42b7c56ddf94 Mon Sep 17 00:00:00 2001 From: "tsevasa@gmail.com" Date: Sun, 14 Jul 2024 02:35:00 +0200 Subject: [PATCH 02/16] removed two superfluous lines --- build.mjs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/build.mjs b/build.mjs index a5a0113d4..5186c6da3 100644 --- a/build.mjs +++ b/build.mjs @@ -56,12 +56,10 @@ let gamecode = ""; // string containing all code in /game except for htmlscript. for (const file of clientFiles) { // If the file is either a css file or htmlscript.js or not in /game, then copy it over in dev mode, or minify it in production mode: if (/\.css$/.test(file) || /\/htmlscript\.js$/.test(file) || !/\/game\//.test(file) ){ - if (DEV_BUILD){ + if (!DEV_BUILD){ await copy(`./src/client/${file}`, `./dist/${file}` , {force: true} ); } else { const code = await readFile(`./src/client/${file}`, 'utf8'); - const minifyInput = {}; - minifyInput[`/src/client/${file}`] = code; const minified = await minify(code, { mangle: true, // Disable variable name mangling compress: true, // Enable compression @@ -77,7 +75,7 @@ for (const file of clientFiles) { } // Combine all gamecode files into app.js, and minify them in dev mode -if (DEV_BUILD){ +if (!DEV_BUILD){ filesToWrite.push(writeFile(`./dist/scripts/game/app.js`, gamecode, 'utf8')); } else{ const minifiedgame = await minify(gamecode, { From f4f11c948382bde8790169448139df90d1dbdc10 Mon Sep 17 00:00:00 2001 From: "tsevasa@gmail.com" Date: Sun, 14 Jul 2024 02:38:00 +0200 Subject: [PATCH 03/16] fixed dev build inversion --- build.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.mjs b/build.mjs index 5186c6da3..09407636a 100644 --- a/build.mjs +++ b/build.mjs @@ -56,7 +56,7 @@ let gamecode = ""; // string containing all code in /game except for htmlscript. for (const file of clientFiles) { // If the file is either a css file or htmlscript.js or not in /game, then copy it over in dev mode, or minify it in production mode: if (/\.css$/.test(file) || /\/htmlscript\.js$/.test(file) || !/\/game\//.test(file) ){ - if (!DEV_BUILD){ + if (DEV_BUILD){ await copy(`./src/client/${file}`, `./dist/${file}` , {force: true} ); } else { const code = await readFile(`./src/client/${file}`, 'utf8'); @@ -75,7 +75,7 @@ for (const file of clientFiles) { } // Combine all gamecode files into app.js, and minify them in dev mode -if (!DEV_BUILD){ +if (DEV_BUILD){ filesToWrite.push(writeFile(`./dist/scripts/game/app.js`, gamecode, 'utf8')); } else{ const minifiedgame = await minify(gamecode, { From 868a094e947fe5d1ca95676d4c75e415d319243e Mon Sep 17 00:00:00 2001 From: "tsevasa@gmail.com" Date: Sun, 14 Jul 2024 03:10:09 +0200 Subject: [PATCH 04/16] made small fix in copy method --- build.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.mjs b/build.mjs index 09407636a..6bb0bd3c3 100644 --- a/build.mjs +++ b/build.mjs @@ -32,11 +32,11 @@ await remove("./dist", { force: true, }); -// copy all clientside files over to dist except for the scripts +// copy all clientside files over to dist except for the game scripts await copy("./src/client", "./dist", { recursive: true, force: true, - filter: filename => { return !/src\/client\/scripts\//.test(filename)} + filter: filename => { return !/game[^$]+/.test(filename)} }); // get all client scripts: From 9d4c4db1079c507537ff0a6fb82dda29b7d014cb Mon Sep 17 00:00:00 2001 From: "tsevasa@gmail.com" Date: Sun, 14 Jul 2024 03:14:37 +0200 Subject: [PATCH 05/16] undo last commit --- build.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.mjs b/build.mjs index 6bb0bd3c3..0f72817bb 100644 --- a/build.mjs +++ b/build.mjs @@ -32,11 +32,11 @@ await remove("./dist", { force: true, }); -// copy all clientside files over to dist except for the game scripts +// copy all clientside files over to dist await copy("./src/client", "./dist", { recursive: true, force: true, - filter: filename => { return !/game[^$]+/.test(filename)} + filter: filename => { return !/game\//.test(filename)} }); // get all client scripts: From d1175bc460a576781a3d7d9502a1df038140fb0c Mon Sep 17 00:00:00 2001 From: "tsevasa@gmail.com" Date: Sun, 14 Jul 2024 03:16:11 +0200 Subject: [PATCH 06/16] commented out regex --- build.mjs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build.mjs b/build.mjs index 0f72817bb..e716f5a66 100644 --- a/build.mjs +++ b/build.mjs @@ -36,7 +36,11 @@ await remove("./dist", { await copy("./src/client", "./dist", { recursive: true, force: true, - filter: filename => { return !/game\//.test(filename)} + filter: filename => { + return true; + // exclude certain files in the future? + // return !/game\//.test(filename) + } }); // get all client scripts: From 1a574490fb72e70810903338c150c45a452ce642 Mon Sep 17 00:00:00 2001 From: Naviary <163621561+Naviary2@users.noreply.github.com> Date: Sat, 13 Jul 2024 23:43:18 -0600 Subject: [PATCH 07/16] Added back commented-out game scripts to header --- src/client/views/play.html | 74 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/src/client/views/play.html b/src/client/views/play.html index 5c9ed13cf..24c8b4c24 100644 --- a/src/client/views/play.html +++ b/src/client/views/play.html @@ -19,8 +19,78 @@ - + + + + From 6cee9dddcc9b97c1944575f7f0a3411b465e5557 Mon Sep 17 00:00:00 2001 From: Naviary <163621561+Naviary2@users.noreply.github.com> Date: Sat, 13 Jul 2024 23:58:46 -0600 Subject: [PATCH 08/16] Moved validation to the bottom --- src/client/views/play.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/client/views/play.html b/src/client/views/play.html index 24c8b4c24..f4fbf1ce9 100644 --- a/src/client/views/play.html +++ b/src/client/views/play.html @@ -89,8 +89,9 @@ - - --> + + + --> From d072789132b7d4ce7b6636822b550fee6cd088ba Mon Sep 17 00:00:00 2001 From: Naviary <163621561+Naviary2@users.noreply.github.com> Date: Sun, 14 Jul 2024 00:01:33 -0600 Subject: [PATCH 09/16] Added validation script back (it's not directly part of the game code) --- src/client/views/play.html | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/client/views/play.html b/src/client/views/play.html index f4fbf1ce9..95b5a2a91 100644 --- a/src/client/views/play.html +++ b/src/client/views/play.html @@ -18,7 +18,8 @@ - + + @@ -89,9 +90,7 @@ - - - --> + --> From e974e5d949b880784b75f3da60e1eac730732ddd Mon Sep 17 00:00:00 2001 From: "tsevasa@gmail.com" Date: Mon, 15 Jul 2024 09:10:29 +0200 Subject: [PATCH 10/16] Finished TODO list for dev mode and prod mode building --- build.mjs | 71 ++-- package-lock.json | 413 +++++++++++++++++++++++ package.json | 1 + src/client/views/play.html | 77 +---- src/server/utility/HTMLScriptInjector.js | 37 +- 5 files changed, 481 insertions(+), 118 deletions(-) diff --git a/build.mjs b/build.mjs index e716f5a66..b3dd633ea 100644 --- a/build.mjs +++ b/build.mjs @@ -32,37 +32,33 @@ await remove("./dist", { force: true, }); -// copy all clientside files over to dist -await copy("./src/client", "./dist", { - recursive: true, - force: true, - filter: filename => { - return true; - // exclude certain files in the future? - // return !/game\//.test(filename) - } -}); - -// get all client scripts: -const clientScript = await getExtFiles("./src/client/scripts", ".js"); -// Not yet implemented: get all client css: -const clientStyle = []; // await getExtFiles("./src/client/css", ".css"); +if (DEV_BUILD){ + // in dev mode, copy all clientside files over to dist and exit + await copy("./src/client", "./dist", { + recursive: true, + force: true + }); +} else{ + // in prod mode, copy all clientside files over to dist, except for those contained in scripts + await copy("./src/client", "./dist", { + recursive: true, + force: true, + filter: filename => { + return !/(\\|\/)scripts(\\|\/)/.test(filename) || /(\\|\/)game$/.test(filename) // make sure to create the scripts/game/folder + } + }); -const clientFiles = []; -clientFiles.push( - ...clientScript.map(v => `scripts/${v}`), - ...clientStyle.map(v => `css/${v}`) -); + // make a list of all client scripts: + const clientFiles = []; + const clientScripts = await getExtFiles("./src/client/scripts", ".js"); + clientFiles.push(...clientScripts.map(v => `scripts/${v}`)); -const filesToWrite = []; // array of output files -let gamecode = ""; // string containing all code in /game except for htmlscript.js + const filesToWrite = []; // array of output files that will need to be written + let gamecode = ""; // string containing all code in /game except for htmlscript.js -for (const file of clientFiles) { - // If the file is either a css file or htmlscript.js or not in /game, then copy it over in dev mode, or minify it in production mode: - if (/\.css$/.test(file) || /\/htmlscript\.js$/.test(file) || !/\/game\//.test(file) ){ - if (DEV_BUILD){ - await copy(`./src/client/${file}`, `./dist/${file}` , {force: true} ); - } else { + for (const file of clientFiles) { + // If the client script is htmlscript.js or not in scripts/game, then minify it and copy it over + if (/\/htmlscript\.js$/.test(file) || !/scripts(\\|\/)+game(\\|\/)/.test(file) ){ const code = await readFile(`./src/client/${file}`, 'utf8'); const minified = await minify(code, { mangle: true, // Disable variable name mangling @@ -71,23 +67,20 @@ for (const file of clientFiles) { }); filesToWrite.push(writeFile(`./dist/${file}`, minified.code, 'utf8')); } + // Collect the code of all js files in /game except for htmlscript.js: + else{ + gamecode += await readFile(`./src/client/${file}`, 'utf8'); + } } - // Collect the code of all js files in /game except for htmlscript.js: - else{ - gamecode += await readFile(`./src/client/${file}`, 'utf8'); - } -} -// Combine all gamecode files into app.js, and minify them in dev mode -if (DEV_BUILD){ - filesToWrite.push(writeFile(`./dist/scripts/game/app.js`, gamecode, 'utf8')); -} else{ + // Combine all gamecode files into app.js const minifiedgame = await minify(gamecode, { mangle: true, compress: true, sourceMap: false }); filesToWrite.push(writeFile(`./dist/scripts/game/app.js`, minifiedgame.code, 'utf8')); -} -await Promise.all(filesToWrite); \ No newline at end of file + // finally, write to the needed files + await Promise.all(filesToWrite); +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 6936dbce8..9991e773a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "date-fns": "^2.23.0", "dotenv": "^16.0.3", "express": "^4.18.2", + "glob": "^11.0.0", "jsonwebtoken": "^9.0.2", "node-forge": "^1.3.1", "nodemailer": "^6.8.0", @@ -39,6 +40,68 @@ "node": ">=6.9.0" } }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", @@ -151,6 +214,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@types/node": { "version": "20.14.10", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", @@ -229,6 +301,17 @@ "node": ">=8" } }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -404,6 +487,22 @@ "node": ">=10" } }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, "node_modules/color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", @@ -484,6 +583,19 @@ "node": ">= 0.10" } }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/date-fns": { "version": "2.30.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", @@ -564,6 +676,11 @@ "url": "https://dotenvx.com" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -699,6 +816,32 @@ "node": ">= 0.8" } }, + "node_modules/foreground-child": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -801,6 +944,28 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/glob": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", + "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -812,6 +977,36 @@ "node": ">= 6" } }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -1018,6 +1213,28 @@ "node": ">=0.12.0" } }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/jackspeak": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.1.tgz", + "integrity": "sha512-cub8rahkh0Q/bw1+GxP7aeSe29hHHn2V4m29nnDlvCdlgU+3UGxkZp7Z53jLUdpX3jdTO0nJZUDl3xvbWc2Xog==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/jsonwebtoken": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", @@ -1098,6 +1315,14 @@ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" }, + "node_modules/lru-cache": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.0.tgz", + "integrity": "sha512-Qv32eSV1RSCfhY3fpPE2GNZ8jgM9X7rdAfemLWqTUxwiyIC4jJ6Sy0fZ8H+oLWevO6i4/bizg7c8d8i6bxrzbA==", + "engines": { + "node": "20 || >=22" + } + }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -1394,6 +1619,11 @@ "wrappy": "1" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -1410,6 +1640,37 @@ "node": ">=0.10.0" } }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -1629,6 +1890,25 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, "node_modules/side-channel": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", @@ -1710,6 +1990,20 @@ "node": ">=8" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -1721,6 +2015,18 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -1872,6 +2178,20 @@ "webidl-conversions": "^3.0.0" } }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/wide-align": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", @@ -1880,6 +2200,99 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/package.json b/package.json index 97454969c..0290600b3 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "date-fns": "^2.23.0", "dotenv": "^16.0.3", "express": "^4.18.2", + "glob": "^11.0.0", "jsonwebtoken": "^9.0.2", "node-forge": "^1.3.1", "nodemailer": "^6.8.0", diff --git a/src/client/views/play.html b/src/client/views/play.html index 95b5a2a91..9eff016bd 100644 --- a/src/client/views/play.html +++ b/src/client/views/play.html @@ -1,8 +1,8 @@ - - + + @@ -19,78 +19,9 @@ + - - - - + diff --git a/src/server/utility/HTMLScriptInjector.js b/src/server/utility/HTMLScriptInjector.js index aa940879b..d9df2692b 100644 --- a/src/server/utility/HTMLScriptInjector.js +++ b/src/server/utility/HTMLScriptInjector.js @@ -11,6 +11,7 @@ const fs = require('fs'); const path = require('path'); +const glob = require('glob'); /** * A cache object that has file paths for the keys, and for the values- @@ -24,9 +25,11 @@ let htmlCache = {}; * @param {string} htmlFilePath - The path of the html document in the project * @param {string} jsFilePath - The path of the javascript file containing the desired javascript code to inject. * @param {string} injectAfterTag - The HTML tag after which the JavaScript code will be injected (typically the ``). + * @param {Object} srcScriptInjections - Optinional argument: An object of the form {string: "htmlcode", injectafter: "tags"}. + * The string will be insterted after the specified tags into the html doc */ -function prepareAndCacheHTML(htmlFilePath, jsFilePath, injectAfterTag) { - injectScript(htmlFilePath, jsFilePath, injectAfterTag) +function prepareAndCacheHTML(htmlFilePath, jsFilePath, injectAfterTag, srcScriptInjections) { + injectScript(htmlFilePath, jsFilePath, injectAfterTag, srcScriptInjections) .then(modifiedHTML => { htmlCache[htmlFilePath] = modifiedHTML; }) @@ -39,9 +42,11 @@ function prepareAndCacheHTML(htmlFilePath, jsFilePath, injectAfterTag) { * @param {string} htmlFilePath - The path of the html document in the project * @param {string} jsFilePath - The path of the javascript file containing the desired javascript code to inject. * @param {string} injectAfterTag - The HTML tag after which the JavaScript code will be injected (typically the ``). + * @param {Object} srcScriptInjections - Optinional argument: An object of the form {string: "htmlcode", injectafter: "tags"}. + * The string will be insterted after the specified tags into the html doc * @returns {Promise} - A promise that resolves with the modified HTML content, or rejects with an error message. */ -function injectScript(htmlFilePath, jsFilePath, injectAfterTag) { +function injectScript(htmlFilePath, jsFilePath, injectAfterTag, srcScriptInjections) { return new Promise((resolve, reject) => { // Read the JavaScript file fs.readFile(jsFilePath, 'utf8', (jsErr, jsData) => { @@ -59,7 +64,11 @@ function injectScript(htmlFilePath, jsFilePath, injectAfterTag) { return; } // Inject the script tag before the specified closing tag - const modifiedHTML = htmlData.replace(injectAfterTag, `${injectAfterTag}${scriptTag}`); + let modifiedHTML = htmlData.replace(injectAfterTag, `${injectAfterTag}${scriptTag}`); + // Inject the code of the optional argument + if (Object.keys(srcScriptInjections).length != 0){ + modifiedHTML = modifiedHTML.replace(srcScriptInjections.injectafter, `${srcScriptInjections.injectafter}${srcScriptInjections.string}`); + } resolve(modifiedHTML); }); }); @@ -92,10 +101,26 @@ function getCachedHTML(htmlFilePath) { // Inject the scripts we want... -{ // Inject into play.html, our OBFUSCATED htmlscript.js script. +{ + // Prepare the injection of our (potentially minified) htmlscript.js script into play.html const htmlFilePath = path.join(__dirname, '..', '..', "..", 'dist', 'views', 'play.html'); const jsFilePath = path.join(__dirname, '..', '..', '..', 'dist', 'scripts', 'game', 'htmlscript.js'); - prepareAndCacheHTML(htmlFilePath, jsFilePath, ''); + + // Prepare the injection of references to all other game scripts into play.html + const HMTL_scriptcall_p1 = `` + const injectafter_string = `${HMTL_scriptcall_p1}validation.js${HMTL_scriptcall_p2}` // we will insert the other game scripts after this exact place in the HTML code + + // Automatically build the list of scripts to be injected by including everything in scripts/game except for htmlscripts.js + let HTML_callGame_JS_string = ""; + const game_JSscripts = glob.sync(`./dist/scripts/game/**/*.js`).filter(file => {return !/htmlscript\.js/.test(file)}); + for (file of game_JSscripts){ + const js_filename = file.split(/(\\|\/)/).slice(4).join(""); // discard "dist/scripts/" + HTML_callGame_JS_string += `\n${HMTL_scriptcall_p1}${js_filename}${HMTL_scriptcall_p2}`; + } + + // Finally, perform the injection + prepareAndCacheHTML(htmlFilePath, jsFilePath, '', {string: HTML_callGame_JS_string, injectafter: injectafter_string}); } module.exports = { From 997d88aaad4e25054d70e4722174c924fd3e27a6 Mon Sep 17 00:00:00 2001 From: "tsevasa@gmail.com" Date: Mon, 15 Jul 2024 10:07:30 +0200 Subject: [PATCH 11/16] cleaned up some comments and navigating.md --- build.mjs | 2 +- docs/NAVIGATING.md | 2 +- src/client/scripts/game/chess/formatconverter.js | 2 +- src/client/scripts/game/chess/variantomega.js | 2 +- src/client/views/play.html | 2 +- src/server/game/variantomega1.js | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build.mjs b/build.mjs index b3dd633ea..8bd9597b6 100644 --- a/build.mjs +++ b/build.mjs @@ -61,7 +61,7 @@ if (DEV_BUILD){ if (/\/htmlscript\.js$/.test(file) || !/scripts(\\|\/)+game(\\|\/)/.test(file) ){ const code = await readFile(`./src/client/${file}`, 'utf8'); const minified = await minify(code, { - mangle: true, // Disable variable name mangling + mangle: true, // Enable variable name mangling compress: true, // Enable compression sourceMap: false }); diff --git a/docs/NAVIGATING.md b/docs/NAVIGATING.md index bbc9cdeff..efdc71812 100644 --- a/docs/NAVIGATING.md +++ b/docs/NAVIGATING.md @@ -2,7 +2,7 @@ This guide gives you several pointers on how to navigate the project. The entire source code of the project is located in [src](../src/). -It is assumed you have already gone through the [Setup](./SETUP.md) process. Whenever you run `nodemon`, [build.mjs](../build.mjs) automatically deploys and minifies all clientside assets of the project from [src](../src/) to the newly created folder `dist`, and an infinite chess server at `https://localhost:3443` is launched. +It is assumed you have already gone through the [Setup](./SETUP.md) process. Whenever you run `nodemon`, [build.mjs](../build.mjs) automatically deploys all clientside assets of the project from [src](../src/) to the newly created folder `dist`, and an infinite chess server at `https://localhost:3443` is launched. ## Server ## diff --git a/src/client/scripts/game/chess/formatconverter.js b/src/client/scripts/game/chess/formatconverter.js index 4c08576fa..83c5b3bb1 100644 --- a/src/client/scripts/game/chess/formatconverter.js +++ b/src/client/scripts/game/chess/formatconverter.js @@ -1,7 +1,7 @@ /* * Universal Infinite Chess Notation [Converter] and Interface - * by Andreas Tsevasa and Naviary + * by Andreas Tsevas and Naviary * https://github.com/tsevasa/infinite-chess-notation * * This script converts primed gamefiles from JSON notation to a diff --git a/src/client/scripts/game/chess/variantomega.js b/src/client/scripts/game/chess/variantomega.js index 6862346d0..3ef3b3f70 100644 --- a/src/client/scripts/game/chess/variantomega.js +++ b/src/client/scripts/game/chess/variantomega.js @@ -22,7 +22,7 @@ const variantomega = (function(){ } /** - * Inits the gamefile for Andreas Tsevasa's "Omega^2". Sets the startSnapshot and gameRules properties. + * Inits the gamefile for Andreas Tsevas's "Omega^2". Sets the startSnapshot and gameRules properties. * @param {gamefile} gamefile - The gamefile */ function initOmegaSquared(gamefile, { Variant, Date }) { diff --git a/src/client/views/play.html b/src/client/views/play.html index 9eff016bd..728e736b3 100644 --- a/src/client/views/play.html +++ b/src/client/views/play.html @@ -21,7 +21,7 @@ - + diff --git a/src/server/game/variantomega1.js b/src/server/game/variantomega1.js index 8e61c7838..719045a66 100644 --- a/src/server/game/variantomega1.js +++ b/src/server/game/variantomega1.js @@ -26,7 +26,7 @@ const variantomega1 = (function(){ } /** - * Inits the gamefile for Andreas Tsevasa's "Omega^2". Sets the startSnapshot and gameRules properties. + * Inits the gamefile for Andreas Tsevas's "Omega^2". Sets the startSnapshot and gameRules properties. * @param {gamefile} gamefile - The gamefile */ function initOmegaSquared(gamefile, { Variant, Date }) { From f5bd78679e8bc94a5e9e861280ac04f8387e9afe Mon Sep 17 00:00:00 2001 From: "tsevasa@gmail.com" Date: Mon, 15 Jul 2024 11:00:42 +0200 Subject: [PATCH 12/16] minor regex improvement --- src/server/utility/HTMLScriptInjector.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/utility/HTMLScriptInjector.js b/src/server/utility/HTMLScriptInjector.js index d9df2692b..ed55c960c 100644 --- a/src/server/utility/HTMLScriptInjector.js +++ b/src/server/utility/HTMLScriptInjector.js @@ -115,7 +115,7 @@ function getCachedHTML(htmlFilePath) { let HTML_callGame_JS_string = ""; const game_JSscripts = glob.sync(`./dist/scripts/game/**/*.js`).filter(file => {return !/htmlscript\.js/.test(file)}); for (file of game_JSscripts){ - const js_filename = file.split(/(\\|\/)/).slice(4).join(""); // discard "dist/scripts/" + const js_filename = file.split(/(\\|\/)+/).slice(4).join(""); // discard "dist/scripts/" HTML_callGame_JS_string += `\n${HMTL_scriptcall_p1}${js_filename}${HMTL_scriptcall_p2}`; } From 94420e4579898c39495260d2a87c5ee6aaec1439 Mon Sep 17 00:00:00 2001 From: "tsevasa@gmail.com" Date: Mon, 15 Jul 2024 11:51:50 +0200 Subject: [PATCH 13/16] improved some comments in HTMLScriptInjector.js --- src/server/utility/HTMLScriptInjector.js | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/server/utility/HTMLScriptInjector.js b/src/server/utility/HTMLScriptInjector.js index ed55c960c..725a615de 100644 --- a/src/server/utility/HTMLScriptInjector.js +++ b/src/server/utility/HTMLScriptInjector.js @@ -25,11 +25,11 @@ let htmlCache = {}; * @param {string} htmlFilePath - The path of the html document in the project * @param {string} jsFilePath - The path of the javascript file containing the desired javascript code to inject. * @param {string} injectAfterTag - The HTML tag after which the JavaScript code will be injected (typically the ``). - * @param {Object} srcScriptInjections - Optinional argument: An object of the form {string: "htmlcode", injectafter: "tags"}. - * The string will be insterted after the specified tags into the html doc + * @param {Object} stringInjection - Optional argument: An object of the form {string: "htmlstring", injectafter: "tags"}. + * The string will be insterted after the specified tags into the html doc */ -function prepareAndCacheHTML(htmlFilePath, jsFilePath, injectAfterTag, srcScriptInjections) { - injectScript(htmlFilePath, jsFilePath, injectAfterTag, srcScriptInjections) +function prepareAndCacheHTML(htmlFilePath, jsFilePath, injectAfterTag, stringInjection) { + injectScript(htmlFilePath, jsFilePath, injectAfterTag, stringInjection) .then(modifiedHTML => { htmlCache[htmlFilePath] = modifiedHTML; }) @@ -42,11 +42,11 @@ function prepareAndCacheHTML(htmlFilePath, jsFilePath, injectAfterTag, srcScript * @param {string} htmlFilePath - The path of the html document in the project * @param {string} jsFilePath - The path of the javascript file containing the desired javascript code to inject. * @param {string} injectAfterTag - The HTML tag after which the JavaScript code will be injected (typically the ``). - * @param {Object} srcScriptInjections - Optinional argument: An object of the form {string: "htmlcode", injectafter: "tags"}. - * The string will be insterted after the specified tags into the html doc + * @param {Object} stringInjection - Optional argument: An object of the form {string: "htmlstring", injectafter: "tags"}. + * The string will be insterted after the specified tags into the html doc * @returns {Promise} - A promise that resolves with the modified HTML content, or rejects with an error message. */ -function injectScript(htmlFilePath, jsFilePath, injectAfterTag, srcScriptInjections) { +function injectScript(htmlFilePath, jsFilePath, injectAfterTag, stringInjection) { return new Promise((resolve, reject) => { // Read the JavaScript file fs.readFile(jsFilePath, 'utf8', (jsErr, jsData) => { @@ -65,9 +65,9 @@ function injectScript(htmlFilePath, jsFilePath, injectAfterTag, srcScriptInjecti } // Inject the script tag before the specified closing tag let modifiedHTML = htmlData.replace(injectAfterTag, `${injectAfterTag}${scriptTag}`); - // Inject the code of the optional argument - if (Object.keys(srcScriptInjections).length != 0){ - modifiedHTML = modifiedHTML.replace(srcScriptInjections.injectafter, `${srcScriptInjections.injectafter}${srcScriptInjections.string}`); + // Inject the string of the optional argument "stringInjection" into the HTML file, if applicable + if (Object.keys(stringInjection).length != 0){ + modifiedHTML = modifiedHTML.replace(stringInjection.injectafter, `${stringInjection.injectafter}${stringInjection.string}`); } resolve(modifiedHTML); }); @@ -114,9 +114,11 @@ function getCachedHTML(htmlFilePath) { // Automatically build the list of scripts to be injected by including everything in scripts/game except for htmlscripts.js let HTML_callGame_JS_string = ""; const game_JSscripts = glob.sync(`./dist/scripts/game/**/*.js`).filter(file => {return !/htmlscript\.js/.test(file)}); + + // Convert the list of scripts into an explicit HTML string that imports them all for (file of game_JSscripts){ const js_filename = file.split(/(\\|\/)+/).slice(4).join(""); // discard "dist/scripts/" - HTML_callGame_JS_string += `\n${HMTL_scriptcall_p1}${js_filename}${HMTL_scriptcall_p2}`; + HTML_callGame_JS_string += `\n\t\t${HMTL_scriptcall_p1}${js_filename}${HMTL_scriptcall_p2}`; } // Finally, perform the injection From ee88f63f4f4272bb2b7eeb29e213a38957d6e3a2 Mon Sep 17 00:00:00 2001 From: "tsevasa@gmail.com" Date: Mon, 15 Jul 2024 13:01:09 +0200 Subject: [PATCH 14/16] improved comments at start of scripts --- build.mjs | 7 +++++++ src/server/utility/HTMLScriptInjector.js | 12 ++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/build.mjs b/build.mjs index 8bd9597b6..9755511a2 100644 --- a/build.mjs +++ b/build.mjs @@ -1,3 +1,10 @@ +// This script deploys all files from /src/client to /dist in order to run the website. +// Depending on the value of DEV_BUILD in /src/server/config/config.js, this happens either in development mode or in production mode. +// Development mode: All files are simply copied over unmodified. +// Production mode: All non-script assets are copied over unmodified, +// but all game scripts in /src/client/scripts/game are concatenated into app.js. +// Further, all scripts are minified with the use of terser. + import { readdir, cp as copy, rm as remove, readFile, writeFile } from "node:fs/promises"; import { minify } from "terser"; import { DEV_BUILD } from "./src/server/config/config.js"; diff --git a/src/server/utility/HTMLScriptInjector.js b/src/server/utility/HTMLScriptInjector.js index 725a615de..234a96e4e 100644 --- a/src/server/utility/HTMLScriptInjector.js +++ b/src/server/utility/HTMLScriptInjector.js @@ -1,8 +1,10 @@ /** * This module, at runtime, creates a list of a few - * of our htmls in which we want to manually injected - * some javascript into before sharing to the client. + * of our htmls into which we want to manually inject + * some javascript before sharing to the client. + * (Currently, htmlscript.js is injected in full into play.html. + * Also, calls to the game scripts in /src/client/scripts/game are injected into play.html) * * We keep the javascript separate in development, so as * to not break Intellisense's sense of the javascript project. @@ -100,7 +102,6 @@ function getCachedHTML(htmlFilePath) { } // Inject the scripts we want... - { // Prepare the injection of our (potentially minified) htmlscript.js script into play.html const htmlFilePath = path.join(__dirname, '..', '..', "..", 'dist', 'views', 'play.html'); @@ -111,17 +112,16 @@ function getCachedHTML(htmlFilePath) { const HMTL_scriptcall_p2 = `" onerror="htmlscript.callback_LoadingError(event)" onload="(() => { htmlscript.removeOnerror.call(this); })()">` const injectafter_string = `${HMTL_scriptcall_p1}validation.js${HMTL_scriptcall_p2}` // we will insert the other game scripts after this exact place in the HTML code - // Automatically build the list of scripts to be injected by including everything in scripts/game except for htmlscripts.js + // Automatically build the list of scripts to be injected into play.html by including everything in scripts/game except for htmlscripts.js let HTML_callGame_JS_string = ""; const game_JSscripts = glob.sync(`./dist/scripts/game/**/*.js`).filter(file => {return !/htmlscript\.js/.test(file)}); - // Convert the list of scripts into an explicit HTML string that imports them all for (file of game_JSscripts){ const js_filename = file.split(/(\\|\/)+/).slice(4).join(""); // discard "dist/scripts/" HTML_callGame_JS_string += `\n\t\t${HMTL_scriptcall_p1}${js_filename}${HMTL_scriptcall_p2}`; } - // Finally, perform the injection + // Finally, perform the injection into play.html prepareAndCacheHTML(htmlFilePath, jsFilePath, '', {string: HTML_callGame_JS_string, injectafter: injectafter_string}); } From 43bb4973acf9b09628a212fbfd5aba2bba02a52b Mon Sep 17 00:00:00 2001 From: "tsevasa@gmail.com" Date: Mon, 15 Jul 2024 13:05:08 +0200 Subject: [PATCH 15/16] made stringInjection argument optional --- src/server/utility/HTMLScriptInjector.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/server/utility/HTMLScriptInjector.js b/src/server/utility/HTMLScriptInjector.js index 234a96e4e..1d91587af 100644 --- a/src/server/utility/HTMLScriptInjector.js +++ b/src/server/utility/HTMLScriptInjector.js @@ -27,10 +27,10 @@ let htmlCache = {}; * @param {string} htmlFilePath - The path of the html document in the project * @param {string} jsFilePath - The path of the javascript file containing the desired javascript code to inject. * @param {string} injectAfterTag - The HTML tag after which the JavaScript code will be injected (typically the ``). - * @param {Object} stringInjection - Optional argument: An object of the form {string: "htmlstring", injectafter: "tags"}. - * The string will be insterted after the specified tags into the html doc + * @param {Object} [stringInjection] - Optional argument: An object of the form {string: "htmlstring", injectafter: "tags"}. + * The string will be insterted after the specified tags into the html doc */ -function prepareAndCacheHTML(htmlFilePath, jsFilePath, injectAfterTag, stringInjection) { +function prepareAndCacheHTML(htmlFilePath, jsFilePath, injectAfterTag, stringInjection = {}) { injectScript(htmlFilePath, jsFilePath, injectAfterTag, stringInjection) .then(modifiedHTML => { htmlCache[htmlFilePath] = modifiedHTML; @@ -44,11 +44,11 @@ function prepareAndCacheHTML(htmlFilePath, jsFilePath, injectAfterTag, stringInj * @param {string} htmlFilePath - The path of the html document in the project * @param {string} jsFilePath - The path of the javascript file containing the desired javascript code to inject. * @param {string} injectAfterTag - The HTML tag after which the JavaScript code will be injected (typically the ``). - * @param {Object} stringInjection - Optional argument: An object of the form {string: "htmlstring", injectafter: "tags"}. - * The string will be insterted after the specified tags into the html doc + * @param {Object} [stringInjection] - Optional argument: An object of the form {string: "htmlstring", injectafter: "tags"}. + * The string will be insterted after the specified tags into the html doc * @returns {Promise} - A promise that resolves with the modified HTML content, or rejects with an error message. */ -function injectScript(htmlFilePath, jsFilePath, injectAfterTag, stringInjection) { +function injectScript(htmlFilePath, jsFilePath, injectAfterTag, stringInjection = {}) { return new Promise((resolve, reject) => { // Read the JavaScript file fs.readFile(jsFilePath, 'utf8', (jsErr, jsData) => { From 0e5c92da2ff0c618b13874ed6be139d42bb1bb6d Mon Sep 17 00:00:00 2001 From: "tsevasa@gmail.com" Date: Mon, 15 Jul 2024 19:03:58 +0200 Subject: [PATCH 16/16] resolve merge conflicts with main --- docs/NAVIGATING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/NAVIGATING.md b/docs/NAVIGATING.md index efdc71812..d2fbcd852 100644 --- a/docs/NAVIGATING.md +++ b/docs/NAVIGATING.md @@ -2,7 +2,7 @@ This guide gives you several pointers on how to navigate the project. The entire source code of the project is located in [src](../src/). -It is assumed you have already gone through the [Setup](./SETUP.md) process. Whenever you run `nodemon`, [build.mjs](../build.mjs) automatically deploys all clientside assets of the project from [src](../src/) to the newly created folder `dist`, and an infinite chess server at `https://localhost:3443` is launched. +It is assumed you have already gone through the [Setup](./SETUP.md) process. Whenever you run `npx nodemon`, [build.mjs](../build.mjs) automatically deploys all clientside assets of the project from [src](../src/) to the newly created folder `dist`, and an infinite chess server at `https://localhost:3443` is launched. ## Server ##