From e9d2900142b31a01986c4a08cff5fdd0718ea158 Mon Sep 17 00:00:00 2001 From: Magic Date: Mon, 26 May 2025 12:56:10 -0700 Subject: [PATCH] updated workspace Signed-off-by: Magic --- .env.example | 3 + .gitignore | 2 + .vscode/extensions.json | 3 +- context.js => dist/context.js | 0 input.js => dist/input.js | 0 library.js => dist/library.js | 1 + dist/library.min.js | 0 output.js => dist/output.js | 0 eslint.config.js | 19 +- package.json | 6 +- pnpm-lock.yaml | 440 +++++++++++++++++++++++++++++++++- pnpm-workspace.yaml | 2 + utils/ai.dungeon/README.md | 1 + utils/ai.dungeon/index.js | 418 ++++++++++++++++++++++++++++++++ utils/ai.dungeon/package.json | 25 ++ 15 files changed, 908 insertions(+), 12 deletions(-) create mode 100644 .env.example rename context.js => dist/context.js (100%) rename input.js => dist/input.js (100%) rename library.js => dist/library.js (74%) create mode 100644 dist/library.min.js rename output.js => dist/output.js (100%) create mode 100644 pnpm-workspace.yaml create mode 100644 utils/ai.dungeon/README.md create mode 100644 utils/ai.dungeon/index.js create mode 100644 utils/ai.dungeon/package.json diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..69b31b3 --- /dev/null +++ b/.env.example @@ -0,0 +1,3 @@ +# https://play.aidungeon.com/scenario/[AID_SHORTID] +AID_SHORTID="" +AID_TOKEN="" \ No newline at end of file diff --git a/.gitignore b/.gitignore index 65b6d04..05baca0 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,5 @@ lerna-debug.log* .env.test.local .env.production.local .env.local +.env.token +.env.keys diff --git a/.vscode/extensions.json b/.vscode/extensions.json index f55bfff..97e616b 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -4,6 +4,7 @@ "dbaeumer.vscode-eslint", "esbenp.prettier-vscode", "usernamehw.errorlens", - "xyz.local-history" + "xyz.local-history", + "remcohaszing.schemastore" ] } diff --git a/context.js b/dist/context.js similarity index 100% rename from context.js rename to dist/context.js diff --git a/input.js b/dist/input.js similarity index 100% rename from input.js rename to dist/input.js diff --git a/library.js b/dist/library.js similarity index 74% rename from library.js rename to dist/library.js index 1933fd6..fb42900 100644 --- a/library.js +++ b/dist/library.js @@ -1,3 +1,4 @@ +/// // Your "Library" tab should look like this // [source code not public yet] diff --git a/dist/library.min.js b/dist/library.min.js new file mode 100644 index 0000000..e69de29 diff --git a/output.js b/dist/output.js similarity index 100% rename from output.js rename to dist/output.js diff --git a/eslint.config.js b/eslint.config.js index ebb33cd..78abe17 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -9,6 +9,8 @@ export default tseslint.config([ tseslint.configs.recommended, eslintConfigPrettier, { + files: ["**/*.js"], + ignores: ["utils/**"], rules: { "no-undef": "off", "no-var": "error", @@ -18,18 +20,23 @@ export default tseslint.config([ "prefer-regex-literals": ["error", { disallowRedundantWrapping: true }], quotes: ["error", "double", { avoidEscape: true, allowTemplateLiterals: false }], "space-before-blocks": ["error", "always"] - } - }, - { - files: ["context.js", "input.js", "library.js", "output.js"], + }, languageOptions: { ecmaVersion: "latest", sourceType: "script", - globals: globals.es2024 + globals: globals.es2022 } }, { - files: ["tools/*.js", "utils/**/*.js"], + files: ["utils/**/*.js"], + rules: { + "no-var": "error", + "prefer-const": ["error", { destructuring: "all" }], + "prefer-promise-reject-errors": "error", + "prefer-regex-literals": ["error", { disallowRedundantWrapping: true }], + quotes: ["error", "double", { avoidEscape: true, allowTemplateLiterals: false }], + "space-before-blocks": ["error", "always"] + }, languageOptions: { ecmaVersion: "latest", sourceType: "module", diff --git a/package.json b/package.json index d8c5092..e760234 100644 --- a/package.json +++ b/package.json @@ -10,15 +10,17 @@ }, "type": "module", "scripts": { - "minify": "terser ./src/library.js -c -o library.min.js" + "run:Dev": "dotenvx run --env AID_ENV=development -f .env --quiet -- node ./utils/ai.dungeon/index.js", + "run:Prod": "dotenvx run --env AID_ENV=production -f .env --quiet -- node ./utils/ai.dungeon/index.js" }, "devDependencies": { + "@dotenvx/dotenvx": "^1.44.1", "@eslint/js": "^9.27.0", + "ai.dungeon": "workspace:^", "eslint": "^9.27.0", "eslint-config-prettier": "^10.1.5", "globals": "^16.1.0", "prettier": "^3.5.3", - "terser": "^5.39.2", "typescript": "^5.8.3", "typescript-eslint": "^8.32.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 79d9e31..211f0f0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,9 +8,15 @@ importers: .: devDependencies: + '@dotenvx/dotenvx': + specifier: ^1.44.1 + version: 1.44.1 '@eslint/js': specifier: ^9.27.0 version: 9.27.0 + ai.dungeon: + specifier: workspace:^ + version: link:utils/ai.dungeon eslint: specifier: ^9.27.0 version: 9.27.0 @@ -23,9 +29,6 @@ importers: prettier: specifier: ^3.5.3 version: 3.5.3 - terser: - specifier: ^5.39.2 - version: 5.39.2 typescript: specifier: ^5.8.3 version: 5.8.3 @@ -33,8 +36,37 @@ importers: specifier: ^8.32.1 version: 8.32.1(eslint@9.27.0)(typescript@5.8.3) + utils/ai.dungeon: + dependencies: + axios: + specifier: ^1.9.0 + version: 1.9.0 + terser: + specifier: ^5.39.2 + version: 5.39.2 + watchpack: + specifier: ^2.4.2 + version: 2.4.4 + devDependencies: + '@types/node': + specifier: ^22.15.21 + version: 22.15.21 + '@types/watchpack': + specifier: ^2.4.4 + version: 2.4.4 + packages: + '@dotenvx/dotenvx@1.44.1': + resolution: {integrity: sha512-j1QImCqf/XJmhIjC1OPpgiZV9g370HG9MNT9s/CDwCKsoYzNCPEKK+GfsidahJx7yIlBbm+4dPLlGec+bKn7oA==} + hasBin: true + + '@ecies/ciphers@0.2.3': + resolution: {integrity: sha512-tapn6XhOueMwht3E2UzY0ZZjYokdaw9XtL9kEyjhQ/Fb9vL9xTFbOaI+fV0AWvTpYu4BNloC6getKW6NtSg4mA==} + engines: {bun: '>=1', deno: '>=2', node: '>=16'} + peerDependencies: + '@noble/ciphers': ^1.0.0 + '@eslint-community/eslint-utils@4.7.0': resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -114,6 +146,18 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@noble/ciphers@1.3.0': + resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.1': + resolution: {integrity: sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -129,9 +173,18 @@ packages: '@types/estree@1.0.7': resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + '@types/graceful-fs@4.1.9': + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/node@22.15.21': + resolution: {integrity: sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ==} + + '@types/watchpack@2.4.4': + resolution: {integrity: sha512-SbuSavsPxfOPZwVHBgQUVuzYBe6+8KL7dwiJLXaj5rmv3DxktOMwX5WP1J6UontwUbewjVoc7pCgZvqy6rPn+A==} + '@typescript-eslint/eslint-plugin@8.32.1': resolution: {integrity: sha512-6u6Plg9nP/J1GRpe/vcjjabo6Uc5YQPAMxsgQyGC/I0RuukiG1wIe3+Vtg3IrSCVJDmqK3j8adrtzXSENRtFgg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -199,6 +252,12 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + axios@1.9.0: + resolution: {integrity: sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -215,6 +274,10 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -230,6 +293,14 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -252,6 +323,38 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + dotenv@16.5.0: + resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==} + engines: {node: '>=12'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + eciesjs@0.4.15: + resolution: {integrity: sha512-r6kEJXDKecVOCj2nLMuXK/FCPeurW33+3JRpfXVbjLja3XUYFfD9I/JBreH6sUyzcm3G/YQboBjMla6poKeSdA==} + engines: {bun: '>=1', deno: '>=2', node: '>=16'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} @@ -304,6 +407,10 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -320,6 +427,14 @@ packages: fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + fdir@6.4.4: + resolution: {integrity: sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} @@ -339,6 +454,34 @@ packages: flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.2: + resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==} + engines: {node: '>= 6'} + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -347,6 +490,9 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} @@ -355,6 +501,13 @@ packages: resolution: {integrity: sha512-aibexHNbb/jiUSObBgpHLj+sIuUmJnYcgXBlrfsiDZ9rt4aF2TFRbyLgZ2iFQuVZ1K5Mx3FVkbKRSgKrbK3K2g==} engines: {node: '>=18'} + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} @@ -362,6 +515,22 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -390,9 +559,17 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isexe@3.1.1: + resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} + engines: {node: '>=16'} + js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true @@ -420,6 +597,13 @@ packages: lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -428,6 +612,18 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -441,6 +637,18 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + object-treeify@1.1.33: + resolution: {integrity: sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==} + engines: {node: '>= 10'} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -469,6 +677,10 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -478,6 +690,9 @@ packages: engines: {node: '>=14'} hasBin: true + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -509,6 +724,9 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} @@ -516,6 +734,10 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -555,14 +777,26 @@ packages: engines: {node: '>=14.17'} hasBin: true + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + watchpack@2.4.4: + resolution: {integrity: sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==} + engines: {node: '>=10.13.0'} + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true + which@4.0.0: + resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==} + engines: {node: ^16.13.0 || >=18.0.0} + hasBin: true + word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} @@ -573,6 +807,22 @@ packages: snapshots: + '@dotenvx/dotenvx@1.44.1': + dependencies: + commander: 11.1.0 + dotenv: 16.5.0 + eciesjs: 0.4.15 + execa: 5.1.1 + fdir: 6.4.4(picomatch@4.0.2) + ignore: 5.3.2 + object-treeify: 1.1.33 + picomatch: 4.0.2 + which: 4.0.0 + + '@ecies/ciphers@0.2.3(@noble/ciphers@1.3.0)': + dependencies: + '@noble/ciphers': 1.3.0 + '@eslint-community/eslint-utils@4.7.0(eslint@9.27.0)': dependencies: eslint: 9.27.0 @@ -652,6 +902,14 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@noble/ciphers@1.3.0': {} + + '@noble/curves@1.9.1': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/hashes@1.8.0': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -666,8 +924,21 @@ snapshots: '@types/estree@1.0.7': {} + '@types/graceful-fs@4.1.9': + dependencies: + '@types/node': 22.15.21 + '@types/json-schema@7.0.15': {} + '@types/node@22.15.21': + dependencies: + undici-types: 6.21.0 + + '@types/watchpack@2.4.4': + dependencies: + '@types/graceful-fs': 4.1.9 + '@types/node': 22.15.21 + '@typescript-eslint/eslint-plugin@8.32.1(@typescript-eslint/parser@8.32.1(eslint@9.27.0)(typescript@5.8.3))(eslint@9.27.0)(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.12.1 @@ -764,6 +1035,16 @@ snapshots: argparse@2.0.1: {} + asynckit@0.4.0: {} + + axios@1.9.0: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.2 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + balanced-match@1.0.2: {} brace-expansion@1.1.11: @@ -781,6 +1062,11 @@ snapshots: buffer-from@1.1.2: {} + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + callsites@3.1.0: {} chalk@4.1.2: @@ -794,6 +1080,12 @@ snapshots: color-name@1.1.4: {} + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@11.1.0: {} + commander@2.20.3: {} concat-map@0.0.1: {} @@ -810,6 +1102,38 @@ snapshots: deep-is@0.1.4: {} + delayed-stream@1.0.0: {} + + dotenv@16.5.0: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + eciesjs@0.4.15: + dependencies: + '@ecies/ciphers': 0.2.3(@noble/ciphers@1.3.0) + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + escape-string-regexp@4.0.0: {} eslint-config-prettier@10.1.5(eslint@9.27.0): @@ -883,6 +1207,18 @@ snapshots: esutils@2.0.3: {} + execa@5.1.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + fast-deep-equal@3.1.3: {} fast-glob@3.3.3: @@ -901,6 +1237,10 @@ snapshots: dependencies: reusify: 1.1.0 + fdir@6.4.4(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 @@ -921,6 +1261,37 @@ snapshots: flatted@3.3.3: {} + follow-redirects@1.15.9: {} + + form-data@4.0.2: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + mime-types: 2.1.35 + + function-bind@1.1.2: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-stream@6.0.1: {} + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -929,14 +1300,32 @@ snapshots: dependencies: is-glob: 4.0.3 + glob-to-regexp@0.4.1: {} + globals@14.0.0: {} globals@16.1.0: {} + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + graphemer@1.4.0: {} has-flag@4.0.0: {} + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + human-signals@2.1.0: {} + ignore@5.3.2: {} ignore@7.0.4: {} @@ -956,8 +1345,12 @@ snapshots: is-number@7.0.0: {} + is-stream@2.0.1: {} + isexe@2.0.0: {} + isexe@3.1.1: {} + js-yaml@4.1.0: dependencies: argparse: 2.0.1 @@ -983,6 +1376,10 @@ snapshots: lodash.merge@4.6.2: {} + math-intrinsics@1.1.0: {} + + merge-stream@2.0.0: {} + merge2@1.4.1: {} micromatch@4.0.8: @@ -990,6 +1387,14 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mimic-fn@2.1.0: {} + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -1002,6 +1407,16 @@ snapshots: natural-compare@1.4.0: {} + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + object-treeify@1.1.33: {} + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -1029,10 +1444,14 @@ snapshots: picomatch@2.3.1: {} + picomatch@4.0.2: {} + prelude-ls@1.2.1: {} prettier@3.5.3: {} + proxy-from-env@1.1.0: {} + punycode@2.3.1: {} queue-microtask@1.2.3: {} @@ -1053,6 +1472,8 @@ snapshots: shebang-regex@3.0.0: {} + signal-exit@3.0.7: {} + source-map-support@0.5.21: dependencies: buffer-from: 1.1.2 @@ -1060,6 +1481,8 @@ snapshots: source-map@0.6.1: {} + strip-final-newline@2.0.0: {} + strip-json-comments@3.1.1: {} supports-color@7.2.0: @@ -1097,14 +1520,25 @@ snapshots: typescript@5.8.3: {} + undici-types@6.21.0: {} + uri-js@4.4.1: dependencies: punycode: 2.3.1 + watchpack@2.4.4: + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + which@2.0.2: dependencies: isexe: 2.0.0 + which@4.0.0: + dependencies: + isexe: 3.1.1 + word-wrap@1.2.5: {} yocto-queue@0.1.0: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..9a82b7a --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - 'utils/*' diff --git a/utils/ai.dungeon/README.md b/utils/ai.dungeon/README.md new file mode 100644 index 0000000..c34a25d --- /dev/null +++ b/utils/ai.dungeon/README.md @@ -0,0 +1 @@ +# AI Dungeon Scenario Updater diff --git a/utils/ai.dungeon/index.js b/utils/ai.dungeon/index.js new file mode 100644 index 0000000..0ea246e --- /dev/null +++ b/utils/ai.dungeon/index.js @@ -0,0 +1,418 @@ +"use strict"; +import path from "path"; +import fs from "node:fs"; +import Watchpack from "watchpack"; +import axios from "axios"; +import { minify } from "terser"; + +const log = (...msg) => { + console.log("[LOG]", ...msg); +}; +const err = (...msg) => { + console.error("[ERROR]", ...msg); +}; +/** + * @template O + * @param { O } obj + * @returns { string } + */ +const objToStr = (obj) => Object.prototype.toString.call(obj).match(/\[object (.*)\]/)[1]; +/** + * Object is typeof `object` / JSON Object + * @template O + * @param { O } obj + */ +const isObj = (obj) => objToStr(obj) === "Object"; +/** + * Object is `null` or `undefined` + * @template O + * @param { O } obj + */ +const isNull = (obj) => { + return Object.is(obj, null) || Object.is(obj, undefined); +}; +/** + * Object is Blank + * @template O + * @param { O } obj + */ +const isBlank = (obj) => { + return ( + (typeof obj === "string" && Object.is(obj.trim(), "")) || + ((obj instanceof Set || obj instanceof Map) && Object.is(obj.size, 0)) || + (Array.isArray(obj) && Object.is(obj.length, 0)) || + (isObj(obj) && Object.is(Object.keys(obj).length, 0)) + ); +}; +/** + * Object is Empty + * @template O + * @param { O } obj + */ +const isEmpty = (obj) => { + return isNull(obj) || isBlank(obj); +}; + +const toTime = () => { + return new Intl.DateTimeFormat("default", { + hour: "numeric", + minute: "numeric", + second: "numeric", + fractionalSecondDigits: 3 + }).format(new Date()); +}; + +/** + * @param {import('node:fs').PathLike} filePath + * @param {string} encoding + */ +const canAccess = async (filePath, encoding = "utf-8") => { + try { + await fs.promises.access(filePath, fs.promises.constants.R_OK | fs.promises.constants.W_OK); + const data = await fs.promises.readFile(filePath, encoding); + return data.toString(encoding); + } catch (e) { + err(e); + } +}; + +// /** +// * @returns {Promise} +// */ +// const getToken = () => { +// return new Promise((resolve, reject) => { +// if (typeof indexedDB !== "undefined") { +// const dbReq = indexedDB.open("firebaseLocalStorageDb"); +// dbReq.onerror = reject; +// dbReq.onsuccess = (event) => { +// const transaction = event.target.result.transaction(["firebaseLocalStorage"], "readwrite"); +// const objectStore = transaction.objectStore("firebaseLocalStorage"); +// const allKeys = objectStore.getAllKeys(); +// allKeys.onerror = reject; +// allKeys.onsuccess = (evt) => { +// const key = evt.target.result.find((r) => r.includes("firebase:authUser:")); +// objectStore.get(key).onsuccess = (evt) => { +// const { value } = evt.target.result; +// resolve(`AID_TOKEN="${value.stsTokenManager.accessToken}"`); +// }; +// }; +// }; +// } else { +// reject(new Error("indexedDB is not defined.")) +// } +// }); +// }; +const AIDRequest = class { + #_; + /** @type {string} */ + token; + /** + * @type { { operationName: string; variables: {[key: string]: unknown}; query: string; } } + */ + data = {}; + constructor(accessToken) { + this.token = accessToken; + } + get headers() { + return this.#_; + } + /** + * @param {string} data + */ + set headers(data) { + this.#_ = { + authorization: `firebase ${this.token}`, + "content-type": "application/json", + "x-gql-operation-name": data, + "Sec-GPC": "1", + "Sec-Fetch-Dest": "empty", + "Sec-Fetch-Mode": "cors", + "Sec-Fetch-Site": "same-site", + Priority: "u=4" + }; + } + /** + * @param {this["data"]} d + */ + setBody(d) { + d.variables ??= {}; + this.data = d; + return this; + } + format() { + const { headers, data } = this; + return { + headers, + data + }; + } + async fetch(type, shortId) { + const resp = { + data: {} + }; + try { + const template = { + adventure: { + headers: { + "x-gql-operation-name": "GetGameplayAdventure" + }, + body: { + operationName: "GetGameplayAdventure", + variables: { shortId, limit: 1000000, desc: true }, + query: + "query GetGameplayAdventure($shortId: String, $limit: Int, $offset: Int, $desc: Boolean) {\n adventure(shortId: $shortId) {\n id\n publicId\n shortId\n scenarioId\n instructions\n title\n description\n tags\n nsfw\n isOwner\n userJoined\n gameState\n actionCount\n contentType\n createdAt\n showComments\n commentCount\n allowComments\n voteCount\n userVote\n editedAt\n published\n unlisted\n deletedAt\n saveCount\n isSaved\n user {\n id\n isCurrentUser\n isMember\n profile {\n id\n title\n thumbImageUrl\n __typename\n }\n __typename\n }\n shortCode\n thirdPerson\n imageStyle\n memory\n authorsNote\n image\n actionWindow(limit: $limit, offset: $offset, desc: $desc) {\n id\n imageText\n ...ActionSubscriptionAction\n __typename\n }\n allPlayers {\n ...PlayerSubscriptionPlayer\n __typename\n }\n storyCards {\n id\n ...StoryCard\n __typename\n }\n __typename\n }\n}\n\nfragment ActionSubscriptionAction on Action {\n id\n text\n type\n imageUrl\n shareUrl\n imageText\n adventureId\n decisionId\n undoneAt\n deletedAt\n createdAt\n logId\n __typename\n}\n\nfragment PlayerSubscriptionPlayer on Player {\n id\n userId\n characterName\n isTypingAt\n user {\n id\n isMember\n profile {\n id\n title\n thumbImageUrl\n __typename\n }\n __typename\n }\n createdAt\n deletedAt\n blockedAt\n __typename\n}\n\nfragment StoryCard on StoryCard {\n id\n type\n keys\n value\n title\n useForCharacterCreation\n description\n updatedAt\n deletedAt\n __typename\n}" + } + }, + adventureDetails: { + body: { + operationName: "GetAdventureDetails", + variables: { shortId }, + query: + "query GetAdventureDetails($shortId: String) {\n adventureState(shortId: $shortId) {\n id\n details\n __typename\n }\n}" + } + }, + scenario: { + headers: { + "x-gql-operation-name": "GetScenario" + }, + body: { + operationName: "GetScenario", + variables: { shortId }, + query: + "query GetScenario($shortId: String) {\n scenario(shortId: $shortId) {\n id\n contentType\n createdAt\n editedAt\n publicId\n shortId\n title\n description\n prompt\n memory\n authorsNote\n image\n isOwner\n published\n unlisted\n allowComments\n showComments\n commentCount\n voteCount\n userVote\n saveCount\n storyCardCount\n isSaved\n tags\n adventuresPlayed\n thirdPerson\n nsfw\n contentRating\n contentRatingLockedAt\n contentRatingLockedMessage\n tags\n type\n details\n parentScenario {\n id\n shortId\n title\n __typename\n }\n user {\n isCurrentUser\n isMember\n profile {\n title\n thumbImageUrl\n __typename\n }\n __typename\n }\n options {\n id\n userId\n shortId\n title\n prompt\n parentScenarioId\n deletedAt\n __typename\n }\n storyCards {\n id\n ...StoryCard\n __typename\n }\n ...CardSearchable\n __typename\n }\n}\n\nfragment CardSearchable on Searchable {\n id\n contentType\n publicId\n shortId\n title\n description\n image\n tags\n userVote\n voteCount\n published\n unlisted\n publishedAt\n createdAt\n isOwner\n editedAt\n deletedAt\n blockedAt\n isSaved\n saveCount\n commentCount\n userId\n contentRating\n user {\n id\n isMember\n profile {\n id\n title\n thumbImageUrl\n __typename\n }\n __typename\n }\n ... on Adventure {\n actionCount\n userJoined\n playPublicId\n unlisted\n playerCount\n __typename\n }\n ... on Scenario {\n adventuresPlayed\n __typename\n }\n __typename\n}\n\nfragment StoryCard on StoryCard {\n id\n type\n keys\n value\n title\n useForCharacterCreation\n description\n updatedAt\n deletedAt\n __typename\n}" + } + }, + scenarioScripting: { + operationName: "GetScenarioScripting", + variables: { shortId }, + query: + "query GetScenarioScripting($shortId: String) {\n scenario(shortId: $shortId) {\n gameCodeSharedLibrary\n gameCodeOnInput\n gameCodeOnOutput\n gameCodeOnModelContext\n recentScriptLogs\n lastModelContext\n }\n}" + }, + aiVersions: { + headers: { + "x-gql-operation-name": "GetAiVersions" + }, + body: { + operationName: "GetAiVersions", + variables: {}, + query: + "query GetAiVersions {\n aiVisibleVersions {\n success\n message\n aiVisibleVersions {\n id\n type\n versionName\n aiDetails\n aiSettings\n access\n release\n available\n instructions\n engineNameEngine {\n engineName\n available\n availableSettings\n __typename\n }\n __typename\n }\n visibleTextVersions {\n id\n type\n versionName\n aiDetails\n aiSettings\n access\n release\n available\n instructions\n engineNameEngine {\n engineName\n available\n availableSettings\n __typename\n }\n __typename\n }\n visibleImageVersions {\n id\n type\n versionName\n aiDetails\n aiSettings\n access\n release\n available\n instructions\n engineNameEngine {\n engineName\n available\n availableSettings\n __typename\n }\n __typename\n }\n __typename\n }\n}" + } + }, + importStoryCards: { + headers: { + "x-gql-operation-name": "ImportStoryCards" + }, + body: { + operationName: "ImportStoryCards", + variables: { + input: shortId + }, + query: + "mutation ImportStoryCards($input: ImportStoryCardsInput!) { importStoryCards(input: $input) { success message storyCards { keys value type __typename } __typename }}" + } + }, + UpdateScenario: { + headers: { + "x-gql-operation-name": "UpdateScenario" + }, + body: { + operationName: "UpdateScenario", + variables: { + input: shortId + }, + query: + "mutation UpdateScenario($input: ScenarioInput) { updateScenario(input: $input) { scenario { id title description prompt memory authorsNote tags nsfw contentRating contentRatingLockedAt contentRatingLockedMessage published thirdPerson allowComments unlisted image uploadId type details editedAt __typename } message success __typename }}" + } + }, + UpdateScenarioScripts: { + headers: { + "x-gql-operation-name": "UpdateScenarioScripts" + }, + body: { + operationName: "UpdateScenarioScripts", + variables: shortId, + query: + "mutation UpdateScenarioScripts($shortId: String, $gameCode: JSONObject) { updateScenarioScripts(shortId: $shortId, gameCode: $gameCode) { success message scenario { id gameCodeSharedLibrary gameCodeOnInput gameCodeOnOutput gameCodeOnModelContext __typename } __typename }}" + } + }, + UpdateOptionTitle: { + headers: { + "x-gql-operation-name": "UpdateOptionTitle" + }, + body: { + operationName: "UpdateOptionTitle", + variables: { + input: shortId + }, + query: + "mutation UpdateOptionTitle($input: ScenarioInput) { updateScenario(input: $input) { scenario { id shortId title prompt parentScenarioId deletedAt __typename } message success __typename }}" + } + }, + UpdateAdventureState: { + headers: { + "x-gql-operation-name": "UpdateAdventureState" + }, + body: { + operationName: "UpdateAdventureState", + variables: { + input: shortId + }, + query: + "mutation UpdateAdventureState($input: AdventureStateInput) { updateAdventureState(input: $input) { adventure { id details editedAt __typename } message success __typename }}" + } + }, + UpdateAdventurePlot: { + headers: { + "x-gql-operation-name": "UpdateAdventurePlot" + }, + body: { + operationName: "UpdateAdventurePlot", + variables: { + input: shortId + }, + query: + "mutation UpdateAdventurePlot($input: AdventurePlotInput) { updateAdventurePlot(input: $input) { adventure { id thirdPerson memory authorsNote editedAt __typename } message success __typename }}" + } + } + }; + const sel = template[type]; + if (!sel) { + return resp; + } + this.headers = sel.headers; + this.setBody(sel.body); + const req = await axios({ + method: "post", + url: "/graphql", + baseURL: "https://api.aidungeon.com", + timeout: 1000, + responseType: "json", + ...this.format() + }); + Object.assign(resp, req); + return resp; + } catch (ex) { + err(ex); + } + return resp; + } + toJSON() { + const { operationName, variables, query } = this.data; + return { + operationName, + variables, + query + }; + } +}; + +const minifyCode = async (code) => { + return (await minify(code, { ecma: 2022 })).code; +}; + +async function build() { + try { + const { AID_ENV, AID_TOKEN, AID_SHORTID } = process.env; + const isDev = typeof AID_ENV === "string" && AID_ENV === "development"; + const r = new AIDRequest(AID_TOKEN); + const buildFiles = async () => { + try { + const files = await Promise.all([ + canAccess("./src/context.js").then(async (c) => { + if (!isDev) { + await fs.promises.writeFile("./dist/context.js", c); + } + return { onModelContext: c }; + }), + canAccess("./src/input.js").then(async (c) => { + if (!isDev) { + await fs.promises.writeFile("./dist/input.js", c); + } + return { onInput: c }; + }), + canAccess("./src/library.js").then(async (c) => { + if (!isDev) { + await fs.promises.writeFile("./dist/library.js", c); + await fs.promises.writeFile("./dist/library.min.js", await minifyCode(c)); + } + return { sharedLibrary: c }; + }), + canAccess("./src/output.js").then(async (c) => { + if (!isDev) { + await fs.promises.writeFile("./dist/output.js", c); + } + return { onOutput: c }; + }) + ]); + if (!isDev) { + log("Created Files:", { + time: toTime() + }); + } + if (typeof AID_SHORTID === "string" && !isEmpty(AID_SHORTID)) { + const gameCode = {}; + for (const f of files) { + for (const [k, v] of Object.entries(f)) { + gameCode[k] = v; + } + } + const { data } = await r.fetch("UpdateScenarioScripts", { + gameCode, + shortId: AID_SHORTID + }); + if (isEmpty(data.data)) { + err(data); + return; + } + if (data.data.errors && Array.isArray(data.data.errors)) { + throw new Error(data.data.errors[0].message) + } + log("UpdateScenarioScripts:", { + message: data.data.updateScenarioScripts.message, + time: toTime() + }); + } + } catch (ex) { + err(ex); + } + }; + log(`Node ENV: ${AID_ENV}`); + await buildFiles(); + if (isDev) { + const wp = new Watchpack(); + let changed = new Set(); + wp.watch(["context.js", "input.js", "library.js", "output.js"], ["./src"]); + wp.on("change", (changedFile, mtime) => { + if (mtime === null) { + changed.delete(changedFile); + } else { + changed.add(changedFile); + } + }); + wp.on("aggregated", async () => { + // Filter out files that start with a dot from detected changes + // (as they are hidden files or temp files created by an editor). + const changes = Array.from(changed).filter((filePath) => { + return !path.basename(filePath).startsWith("."); + }); + changed = new Set(); + + if (changes.length === 0) { + return; + } + + await buildFiles(); + }); + } else { + process.exit(0); + } + } catch (ex) { + err(ex); + } +} + +build(); + +// export { build }; +// export default build; diff --git a/utils/ai.dungeon/package.json b/utils/ai.dungeon/package.json new file mode 100644 index 0000000..d699e28 --- /dev/null +++ b/utils/ai.dungeon/package.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://json.schemastore.org/package.json", + "name": "ai.dungeon", + "description": "Upload changes to AI Dungeon scenarios", + "version": "1.0.0", + "license": "MIT", + "type": "module", + "main": "./index.js", + "exports": { + ".": { + "import": { + "default": "./index.js" + } + } + }, + "devDependencies": { + "@types/node": "^22.15.21", + "@types/watchpack": "^2.4.4" + }, + "dependencies": { + "axios": "^1.9.0", + "terser": "^5.39.2", + "watchpack": "^2.4.2" + } +}