From a46c8b1caecd60884e947461dcc0ab869014d4f9 Mon Sep 17 00:00:00 2001 From: weeryan17 Date: Fri, 7 Oct 2022 10:18:00 -0400 Subject: [PATCH 01/22] Proper deletion of isolate instance and registerSync function --- src/managers/isolate-manager.ts | 10 ++++++++-- src/utils/registerFunc.ts | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/managers/isolate-manager.ts b/src/managers/isolate-manager.ts index 831bab6..a0c21b0 100644 --- a/src/managers/isolate-manager.ts +++ b/src/managers/isolate-manager.ts @@ -15,14 +15,20 @@ export function setLimit( timeout = newTimeout; } -const isolates: IsolateInstance[] = []; +let isolates: IsolateInstance[] = []; function startKillTask() { setInterval(() => { for (const isolate of isolates) { + if (isolate == undefined) { + continue; + } if (isolate.running == false) { continue; } + if (isolate.startCpuTime == undefined) { + continue; + } const diff: bigint = isolate.backendInstance.cpuTime - isolate.startCpuTime; if (diff >= cpuLimit) { @@ -49,7 +55,7 @@ function handleCatastrophicError(message: string) { function disposeOfInstance(isolate: IsolateInstance) { isolate.backendInstance.dispose(); - delete isolates[isolates.indexOf(isolate)]; + isolates = isolates.filter((isolateL) => isolateL === isolate); } startKillTask(); diff --git a/src/utils/registerFunc.ts b/src/utils/registerFunc.ts index 4e06604..66cc649 100644 --- a/src/utils/registerFunc.ts +++ b/src/utils/registerFunc.ts @@ -35,3 +35,21 @@ export async function registerAsyncButSyncFunction( { arguments: { reference: true } }, ); } + +export async function registerSyncFunction( + context: Context, + name: string, + argCount: number, + callback: any, +) { + const argArgument = new Array(argCount).fill(1).map((_, i) => `arg${i}`); + await context.evalClosure( + ` + global.${name} = function ${name}(${argArgument}) { + return $0.applySync(undefined, [${argArgument}], { arguments: { copy: true } }) + } + `, + [callback], + { arguments: { reference: true } }, + ); +} From ca54780176031cb2126dc0b5e2fdd617300520b6 Mon Sep 17 00:00:00 2001 From: weeryan17 Date: Mon, 10 Oct 2022 11:54:57 -0400 Subject: [PATCH 02/22] RabbitMq Manager --- package-lock.json | 196 +++++++++++++++++++++++++++---- package.json | 3 +- src/api/schemas/getUserById.ts | 17 +++ src/config/parts/index.ts | 4 + src/config/parts/rabbitMQ.ts | 42 +++++++ src/managers/rabbitmq-manager.ts | 74 ++++++++++++ 6 files changed, 315 insertions(+), 21 deletions(-) create mode 100644 src/api/schemas/getUserById.ts create mode 100644 src/config/parts/rabbitMQ.ts create mode 100644 src/managers/rabbitmq-manager.ts diff --git a/package-lock.json b/package-lock.json index 7710bfa..8899f67 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "MIT", "dependencies": { - "@cloudamqp/amqp-client": "^2.1.0", + "amqplib": "^0.10.3", "isolated-vm": "^4.4.1", "joi": "^17.6.2", "neat-config": "^1.0.0", @@ -17,6 +17,7 @@ "winston-console-format": "^1.0.8" }, "devDependencies": { + "@types/amqplib": "^0.8.2", "@types/node": "^18.7.20", "@typescript-eslint/eslint-plugin": "^5.38.0", "@typescript-eslint/parser": "^5.38.0", @@ -32,14 +33,24 @@ "typescript": "^4.8.3" } }, - "node_modules/@cloudamqp/amqp-client": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@cloudamqp/amqp-client/-/amqp-client-2.1.0.tgz", - "integrity": "sha512-2dPPvsSpFFjX73zfpaRBL1abm6M3AdZmuJibDKZAvG+li9+yyALLmQ/7s3qN6n4aFPAHU4RThL7NK+qPUU3/Lw==", + "node_modules/@acuminous/bitsyntax": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@acuminous/bitsyntax/-/bitsyntax-0.1.2.tgz", + "integrity": "sha512-29lUK80d1muEQqiUsSo+3A0yP6CdspgC95EnKBMi22Xlwt79i/En4Vr67+cXhU+cZjbti3TgGGC5wy1stIywVQ==", + "dependencies": { + "buffer-more-ints": "~1.0.0", + "debug": "^4.3.4", + "safe-buffer": "~5.1.2" + }, "engines": { - "node": ">=12.0.0" + "node": ">=0.8" } }, + "node_modules/@acuminous/bitsyntax/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -251,6 +262,22 @@ "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, + "node_modules/@types/amqplib": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/@types/amqplib/-/amqplib-0.8.2.tgz", + "integrity": "sha512-p+TFLzo52f8UanB+Nq6gyUi65yecAcRY3nYowU6MPGFtaJvEDxcnFWrxssSTkF+ts1W3zyQDvgVICLQem5WxRA==", + "dev": true, + "dependencies": { + "@types/bluebird": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bluebird": { + "version": "3.5.37", + "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.37.tgz", + "integrity": "sha512-g2qEd+zkfkTEudA2SrMAeAvY7CrFqtbsLILm2dT2VIeKTqMqVzcdfURlvu6FU3srRgbmXN1Srm94pg34EIehww==", + "dev": true + }, "node_modules/@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -499,6 +526,36 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/amqplib": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.10.3.tgz", + "integrity": "sha512-UHmuSa7n8vVW/a5HGh2nFPqAEr8+cD4dEZ6u9GjP91nHfr1a54RyAKyra7Sb5NH7NBKOUlyQSMXIp0qAixKexw==", + "dependencies": { + "@acuminous/bitsyntax": "^0.1.2", + "buffer-more-ints": "~1.0.0", + "readable-stream": "1.x >=1.1.9", + "url-parse": "~1.5.10" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/amqplib/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/amqplib/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -599,6 +656,11 @@ "node": ">=8" } }, + "node_modules/buffer-more-ints": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", + "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==" + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -776,8 +838,7 @@ "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "node_modules/create-require": { "version": "1.1.1", @@ -803,7 +864,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -1490,8 +1550,7 @@ "node_modules/isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" }, "node_modules/isexe": { "version": "2.0.0", @@ -2025,6 +2084,11 @@ "node": ">=6" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, "node_modules/queue-lit": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/queue-lit/-/queue-lit-1.4.0.tgz", @@ -2097,6 +2161,11 @@ "node": ">=0.10.0" } }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -2572,6 +2641,15 @@ "punycode": "^2.1.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -2748,10 +2826,22 @@ } }, "dependencies": { - "@cloudamqp/amqp-client": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@cloudamqp/amqp-client/-/amqp-client-2.1.0.tgz", - "integrity": "sha512-2dPPvsSpFFjX73zfpaRBL1abm6M3AdZmuJibDKZAvG+li9+yyALLmQ/7s3qN6n4aFPAHU4RThL7NK+qPUU3/Lw==" + "@acuminous/bitsyntax": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@acuminous/bitsyntax/-/bitsyntax-0.1.2.tgz", + "integrity": "sha512-29lUK80d1muEQqiUsSo+3A0yP6CdspgC95EnKBMi22Xlwt79i/En4Vr67+cXhU+cZjbti3TgGGC5wy1stIywVQ==", + "requires": { + "buffer-more-ints": "~1.0.0", + "debug": "^4.3.4", + "safe-buffer": "~5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } }, "@colors/colors": { "version": "1.5.0", @@ -2926,6 +3016,22 @@ "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, + "@types/amqplib": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/@types/amqplib/-/amqplib-0.8.2.tgz", + "integrity": "sha512-p+TFLzo52f8UanB+Nq6gyUi65yecAcRY3nYowU6MPGFtaJvEDxcnFWrxssSTkF+ts1W3zyQDvgVICLQem5WxRA==", + "dev": true, + "requires": { + "@types/bluebird": "*", + "@types/node": "*" + } + }, + "@types/bluebird": { + "version": "3.5.37", + "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.37.tgz", + "integrity": "sha512-g2qEd+zkfkTEudA2SrMAeAvY7CrFqtbsLILm2dT2VIeKTqMqVzcdfURlvu6FU3srRgbmXN1Srm94pg34EIehww==", + "dev": true + }, "@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -3070,6 +3176,35 @@ "uri-js": "^4.2.2" } }, + "amqplib": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.10.3.tgz", + "integrity": "sha512-UHmuSa7n8vVW/a5HGh2nFPqAEr8+cD4dEZ6u9GjP91nHfr1a54RyAKyra7Sb5NH7NBKOUlyQSMXIp0qAixKexw==", + "requires": { + "@acuminous/bitsyntax": "^0.1.2", + "buffer-more-ints": "~1.0.0", + "readable-stream": "1.x >=1.1.9", + "url-parse": "~1.5.10" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + } + } + }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -3149,6 +3284,11 @@ "fill-range": "^7.0.1" } }, + "buffer-more-ints": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", + "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==" + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -3294,8 +3434,7 @@ "core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "create-require": { "version": "1.1.1", @@ -3318,7 +3457,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "requires": { "ms": "2.1.2" } @@ -3827,8 +3965,7 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" }, "isexe": { "version": "2.0.0", @@ -4237,6 +4374,11 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, "queue-lit": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/queue-lit/-/queue-lit-1.4.0.tgz", @@ -4280,6 +4422,11 @@ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -4614,6 +4761,15 @@ "punycode": "^2.1.0" } }, + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/package.json b/package.json index e806ffa..8e71f2e 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "author": "cascadeorg", "license": "MIT", "dependencies": { - "@cloudamqp/amqp-client": "^2.1.0", + "amqplib": "^0.10.3", "isolated-vm": "^4.4.1", "joi": "^17.6.2", "neat-config": "^1.0.0", @@ -25,6 +25,7 @@ "winston-console-format": "^1.0.8" }, "devDependencies": { + "@types/amqplib": "^0.8.2", "@types/node": "^18.7.20", "@typescript-eslint/eslint-plugin": "^5.38.0", "@typescript-eslint/parser": "^5.38.0", diff --git a/src/api/schemas/getUserById.ts b/src/api/schemas/getUserById.ts new file mode 100644 index 0000000..819360a --- /dev/null +++ b/src/api/schemas/getUserById.ts @@ -0,0 +1,17 @@ +import joi from 'joi'; + +export const action = 'getUserById'; + +interface GetUserById { + userId: string; + guildId: string; +} + +export const schema = joi.object({ + userId: joi.string().regex(/\d{18,}/), + guildId: joi.string().regex(/\d{18,}/), +}); + +export const run = (data: GetUserById) => { + return 'NO'; +}; diff --git a/src/config/parts/index.ts b/src/config/parts/index.ts index 4a8664c..b6a30f6 100644 --- a/src/config/parts/index.ts +++ b/src/config/parts/index.ts @@ -1,9 +1,13 @@ import joi from 'joi'; import { LoggingConf, loggingConfSchema } from './logging'; +import { RabbitMQConf, rabbitMqConfSchema } from '@config/parts/rabbitMQ'; + export interface Config { logging: LoggingConf; + rabbitMq: RabbitMQConf; } export const configSchema = joi.object({ logging: loggingConfSchema.default(), + rabbitMq: rabbitMqConfSchema.default(), }); diff --git a/src/config/parts/rabbitMQ.ts b/src/config/parts/rabbitMQ.ts new file mode 100644 index 0000000..1b95ad0 --- /dev/null +++ b/src/config/parts/rabbitMQ.ts @@ -0,0 +1,42 @@ +import joi from 'joi'; + +interface RabbitMQIndividualConf { + username: string; + password: string; + hostname: string; + port: number; // = 5672 + virtualHost: string; // = "/" + type: 'individual'; +} + +interface RabbitMQConnectionStringConfig { + connectionString: string; + type: 'connectionString'; +} + +export type RabbitMQConf = + | RabbitMQIndividualConf + | RabbitMQConnectionStringConfig; + +export const rabbitMqConfSchema = joi + .alternatives() + .try( + joi.object({ + username: joi.string().required(), + password: joi.string().required(), + hostname: joi.string().hostname().required(), + port: joi.number().default(5672), + virtualHost: joi + .string() + .regex(/(\/.*)*\/?/) + .default('/'), + type: joi.string().default('individual').valid('individual'), + }), + joi.object({ + connectionString: joi.string().uri({ + scheme: 'amqp', + }), + type: joi.string().default('connectionString').valid('connectionString'), + }), + ) + .match('one'); diff --git a/src/managers/rabbitmq-manager.ts b/src/managers/rabbitmq-manager.ts new file mode 100644 index 0000000..156229c --- /dev/null +++ b/src/managers/rabbitmq-manager.ts @@ -0,0 +1,74 @@ +import { connect, ConsumeMessage } from 'amqplib'; +import { config } from '@config'; +import { randomUUID } from 'crypto'; +import { scopedLogger } from '@logger'; + +const log = scopedLogger('manager'); + +let connection; +let channel; + +const waitForReplies: QueueConsumer[] = []; + +let queue; + +interface QueueConsumer { + correlationId: string; + resolve: any; + reject: any; +} + +export async function tryConnect() { + let connectionString: string; + if (config.rabbitMq.type == 'individual') { + connectionString = `amqp://${config.rabbitMq.username}:${encodeURIComponent( + config.rabbitMq.password, + )}@${config.rabbitMq.hostname}:${config.rabbitMq.port}${ + config.rabbitMq.virtualHost + }`; + } else { + connectionString = config.rabbitMq.connectionString; + } + + connection = await connect(connectionString); + channel = await connection.createChannel(); + + queue = await channel.assertQueue(''); + + channel.consume(queue, consume).catch((e) => { + log.error(e); + }); + + const res = await sendGetReply(); + const code = res.statusCode; + const shards = res.data['shard-count']; + + log.info(`code: ${code}, chard: ${shards}`); +} + +function consume(message: ConsumeMessage | null) { + const reply = waitForReplies.find((consumer) => { + consumer.correlationId = message.properties.correlationId; + }); + const json = JSON.parse(message.content.toString()); + reply.resolve(json); +} + +async function sendGetReply(): Promise { + const id = randomUUID(); + const prom = new Promise((resolve, reject) => { + waitForReplies.push({ + correlationId: id, + resolve, + reject, + }); + }); + channel.push('', 'meta', Buffer.from(''), { + correlationId: id, + replyTo: queue.queue, + headers: { + action: 'shard-count', + }, + }); + return await prom; +} From 939afc0f757ac02b2570fb1834d853dc36c25db3 Mon Sep 17 00:00:00 2001 From: weeryan17 Date: Mon, 10 Oct 2022 11:55:45 -0400 Subject: [PATCH 03/22] Might as well push this --- src/sandboxed/scripts/user.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/sandboxed/scripts/user.js diff --git a/src/sandboxed/scripts/user.js b/src/sandboxed/scripts/user.js new file mode 100644 index 0000000..1bd2be7 --- /dev/null +++ b/src/sandboxed/scripts/user.js @@ -0,0 +1,20 @@ +class User { + #backingId = "0"; + + name = ""; + nick = ""; + avatar = ""; + discriminator = ""; + +} + +async function getUserByID(id) { + let data = await __cascadeApi({ + + }); +} + +return { + User, + getUserByID +} From 55e9b64991fb956bc6903a9ba13c255800a995b7 Mon Sep 17 00:00:00 2001 From: weeryan17 Date: Mon, 10 Oct 2022 12:03:27 -0400 Subject: [PATCH 04/22] Bug fixes --- src/managers/rabbitmq-manager.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/managers/rabbitmq-manager.ts b/src/managers/rabbitmq-manager.ts index 156229c..4c0fa2c 100644 --- a/src/managers/rabbitmq-manager.ts +++ b/src/managers/rabbitmq-manager.ts @@ -14,8 +14,8 @@ let queue; interface QueueConsumer { correlationId: string; - resolve: any; - reject: any; + resolve: (...args: any[]) => void; + reject: (...args: any[]) => void; } export async function tryConnect() { @@ -38,8 +38,10 @@ export async function tryConnect() { channel.consume(queue, consume).catch((e) => { log.error(e); }); +} - const res = await sendGetReply(); +export async function getShardCount() { + const res = await sendMassageGetReply(); const code = res.statusCode; const shards = res.data['shard-count']; @@ -48,13 +50,13 @@ export async function tryConnect() { function consume(message: ConsumeMessage | null) { const reply = waitForReplies.find((consumer) => { - consumer.correlationId = message.properties.correlationId; + return consumer.correlationId == message.properties.correlationId; }); const json = JSON.parse(message.content.toString()); reply.resolve(json); } -async function sendGetReply(): Promise { +async function sendMassageGetReply(): Promise { const id = randomUUID(); const prom = new Promise((resolve, reject) => { waitForReplies.push({ @@ -63,7 +65,7 @@ async function sendGetReply(): Promise { reject, }); }); - channel.push('', 'meta', Buffer.from(''), { + await channel.publish('', 'meta', Buffer.from(''), { correlationId: id, replyTo: queue.queue, headers: { From 8d6b2d60dca109e34e346613e326d213f40acfcc Mon Sep 17 00:00:00 2001 From: weeryan17 Date: Mon, 10 Oct 2022 12:04:34 -0400 Subject: [PATCH 05/22] no one saw that --- src/managers/rabbitmq-manager.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/managers/rabbitmq-manager.ts b/src/managers/rabbitmq-manager.ts index 4c0fa2c..84eb5e5 100644 --- a/src/managers/rabbitmq-manager.ts +++ b/src/managers/rabbitmq-manager.ts @@ -41,7 +41,7 @@ export async function tryConnect() { } export async function getShardCount() { - const res = await sendMassageGetReply(); + const res = await sendMessageGetReply(); const code = res.statusCode; const shards = res.data['shard-count']; @@ -56,7 +56,7 @@ function consume(message: ConsumeMessage | null) { reply.resolve(json); } -async function sendMassageGetReply(): Promise { +async function sendMessageGetReply(): Promise { const id = randomUUID(); const prom = new Promise((resolve, reject) => { waitForReplies.push({ From e1d4a6056f11f4d536028ec8620e2d5e69f5d235 Mon Sep 17 00:00:00 2001 From: weeryan17 Date: Mon, 10 Oct 2022 15:47:54 -0400 Subject: [PATCH 06/22] Cleanup and rabbitmq timeout. --- src/api/schemas/getUserById.ts | 5 ++-- src/config/parts/index.ts | 2 +- src/config/parts/rabbitMQ.ts | 6 ++--- src/index.ts | 4 ++++ src/managers/isolate-manager.ts | 2 +- src/managers/rabbitmq-manager.ts | 39 +++++++++++++++++++++++++++----- src/utils/regex.ts | 2 ++ 7 files changed, 46 insertions(+), 14 deletions(-) create mode 100644 src/utils/regex.ts diff --git a/src/api/schemas/getUserById.ts b/src/api/schemas/getUserById.ts index 819360a..1601cf7 100644 --- a/src/api/schemas/getUserById.ts +++ b/src/api/schemas/getUserById.ts @@ -1,4 +1,5 @@ import joi from 'joi'; +import { idRegex } from '@utils/regex'; export const action = 'getUserById'; @@ -8,8 +9,8 @@ interface GetUserById { } export const schema = joi.object({ - userId: joi.string().regex(/\d{18,}/), - guildId: joi.string().regex(/\d{18,}/), + userId: joi.string().regex(idRegex), + guildId: joi.string().regex(idRegex), }); export const run = (data: GetUserById) => { diff --git a/src/config/parts/index.ts b/src/config/parts/index.ts index b6a30f6..3bd2ea3 100644 --- a/src/config/parts/index.ts +++ b/src/config/parts/index.ts @@ -9,5 +9,5 @@ export interface Config { export const configSchema = joi.object({ logging: loggingConfSchema.default(), - rabbitMq: rabbitMqConfSchema.default(), + rabbitMq: rabbitMqConfSchema, }); diff --git a/src/config/parts/rabbitMQ.ts b/src/config/parts/rabbitMQ.ts index 1b95ad0..7ea6207 100644 --- a/src/config/parts/rabbitMQ.ts +++ b/src/config/parts/rabbitMQ.ts @@ -1,4 +1,5 @@ import joi from 'joi'; +import { pathRegex } from '@utils/regex'; interface RabbitMQIndividualConf { username: string; @@ -26,10 +27,7 @@ export const rabbitMqConfSchema = joi password: joi.string().required(), hostname: joi.string().hostname().required(), port: joi.number().default(5672), - virtualHost: joi - .string() - .regex(/(\/.*)*\/?/) - .default('/'), + virtualHost: joi.string().regex(pathRegex).default('/'), type: joi.string().default('individual').valid('individual'), }), joi.object({ diff --git a/src/index.ts b/src/index.ts index 466347b..1af77b2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,6 +8,7 @@ import { import { setupScripts } from '@sandboxed/prepare-scripts'; import fs from 'fs'; import { join } from 'path'; +import { getShardCount, tryConnect } from '@managers/rabbitmq-manager'; const log = scopedLogger('command-processor'); @@ -39,6 +40,9 @@ async function bootstrap() { await setupScripts(); log.info('everything setup, running code'); + await tryConnect(); + await getShardCount(); + // run test // TODO temp await test(); diff --git a/src/managers/isolate-manager.ts b/src/managers/isolate-manager.ts index c56aba1..c6083aa 100644 --- a/src/managers/isolate-manager.ts +++ b/src/managers/isolate-manager.ts @@ -3,7 +3,7 @@ import { IsolateInstance } from '@models/isolate-instance'; import { scopedLogger } from '@logger'; import { randomUUID } from 'crypto'; -const log = scopedLogger('manager'); +const log = scopedLogger('isolate-manager'); let killTask: ReturnType | null = null; let cpuLimit = 10000000n; // TODO arbitrary number, need to do more research diff --git a/src/managers/rabbitmq-manager.ts b/src/managers/rabbitmq-manager.ts index 84eb5e5..19a9a85 100644 --- a/src/managers/rabbitmq-manager.ts +++ b/src/managers/rabbitmq-manager.ts @@ -2,8 +2,9 @@ import { connect, ConsumeMessage } from 'amqplib'; import { config } from '@config'; import { randomUUID } from 'crypto'; import { scopedLogger } from '@logger'; +import { string } from 'joi'; -const log = scopedLogger('manager'); +const log = scopedLogger('rabbitmq-manager'); let connection; let channel; @@ -35,13 +36,13 @@ export async function tryConnect() { queue = await channel.assertQueue(''); - channel.consume(queue, consume).catch((e) => { + channel.consume(queue.queue, consume).catch((e) => { log.error(e); }); } export async function getShardCount() { - const res = await sendMessageGetReply(); + const res = await sendMessageGetReply('shard-count', {}); const code = res.statusCode; const shards = res.data['shard-count']; @@ -54,9 +55,23 @@ function consume(message: ConsumeMessage | null) { }); const json = JSON.parse(message.content.toString()); reply.resolve(json); + deleteWait(message.properties.correlationId); } -async function sendMessageGetReply(): Promise { +function deleteWait(id: string): boolean { + let deleted = false; + waitForReplies.filter((wait) => { + deleted = true; + return wait.correlationId != id; + }); + return deleted; +} + +async function sendMessageGetReply( + action: string, + body: Record, + queueName = '', +): Promise { const id = randomUUID(); const prom = new Promise((resolve, reject) => { waitForReplies.push({ @@ -65,12 +80,24 @@ async function sendMessageGetReply(): Promise { reject, }); }); - await channel.publish('', 'meta', Buffer.from(''), { + await channel.publish(queueName, 'meta', Buffer.from(JSON.stringify(body)), { correlationId: id, replyTo: queue.queue, headers: { - action: 'shard-count', + action: action, }, }); + + setTimeout(() => { + const wait = waitForReplies.find((consumer) => { + return consumer.correlationId == id; + }); + if (wait == undefined) { + return; + } + wait.reject(new Error('Timeout elapsed')); + deleteWait(id); + }, 5000); + return await prom; } diff --git a/src/utils/regex.ts b/src/utils/regex.ts new file mode 100644 index 0000000..8594310 --- /dev/null +++ b/src/utils/regex.ts @@ -0,0 +1,2 @@ +export const idRegex = /\d{18,}/; +export const pathRegex = /(\/.*)*\/?/; From f5e468891d64926f5aea9b0ea1640f263d505b28 Mon Sep 17 00:00:00 2001 From: weeryan17 Date: Mon, 10 Oct 2022 16:19:04 -0400 Subject: [PATCH 07/22] Error handling, and proper objects --- src/api/entrypoint.ts | 1 + src/api/schemas/ping.ts | 5 ++-- src/example/file1.js | 6 +++- src/managers/rabbitmq-manager.ts | 48 ++++++++++++++++++++++++++------ 4 files changed, 48 insertions(+), 12 deletions(-) diff --git a/src/api/entrypoint.ts b/src/api/entrypoint.ts index a94908a..80c2fd3 100644 --- a/src/api/entrypoint.ts +++ b/src/api/entrypoint.ts @@ -17,6 +17,7 @@ interface Schema { schema: joi.ObjectSchema; run: (data: any) => any; } + const schemas: Record = {}; export async function setupApi() { diff --git a/src/api/schemas/ping.ts b/src/api/schemas/ping.ts index 711fc8c..2fa0e5b 100644 --- a/src/api/schemas/ping.ts +++ b/src/api/schemas/ping.ts @@ -5,10 +5,11 @@ export const action = 'ping'; interface Input { msg: string; } + export const schema = joi.object({ msg: joi.string().default('pong!'), }); -export const run = (data: Input) => { - return data.msg; +export const run = async (data: Input) => { + throw new Error('test'); }; diff --git a/src/example/file1.js b/src/example/file1.js index 2a93e34..4cae8df 100644 --- a/src/example/file1.js +++ b/src/example/file1.js @@ -4,5 +4,9 @@ log(hello2()); log('-- starting api tests'); log(hello()); -log(await ping()); +try { + log(await ping()); +} catch (e) { + log(e.message); +} log(await ping('pongalong!')); diff --git a/src/managers/rabbitmq-manager.ts b/src/managers/rabbitmq-manager.ts index 19a9a85..909ef70 100644 --- a/src/managers/rabbitmq-manager.ts +++ b/src/managers/rabbitmq-manager.ts @@ -34,7 +34,10 @@ export async function tryConnect() { connection = await connect(connectionString); channel = await connection.createChannel(); - queue = await channel.assertQueue(''); + queue = await channel.assertQueue('', { + exclusive: true, + autoDelete: true, + }); channel.consume(queue.queue, consume).catch((e) => { log.error(e); @@ -42,18 +45,22 @@ export async function tryConnect() { } export async function getShardCount() { - const res = await sendMessageGetReply('shard-count', {}); - const code = res.statusCode; - const shards = res.data['shard-count']; + const res = await sendMessageGetReply('shard_count', {}); + const code = res.status_code; + const shards = res.data.shard_count; - log.info(`code: ${code}, chard: ${shards}`); + log.info(`code: ${code}, shard: ${shards}`); } function consume(message: ConsumeMessage | null) { const reply = waitForReplies.find((consumer) => { return consumer.correlationId == message.properties.correlationId; }); - const json = JSON.parse(message.content.toString()); + const json = JSON.parse(message.content.toString()) as Response; + if (json.error) { + reply.reject(json); + return; + } reply.resolve(json); deleteWait(message.properties.correlationId); } @@ -67,13 +74,36 @@ function deleteWait(id: string): boolean { return deleted; } -async function sendMessageGetReply( +interface ResponseErrorSub { + error_code: string; + message: string; +} + +export type Response = ResponseSuccess | ResponseError; + +interface ResponseSuccess { + status_code: number; + error: undefined; + data: T; +} + +interface ResponseError { + status_code: number; + error: ResponseErrorSub; + data: undefined; +} + +interface ShardCount { + shard_count: number; +} + +export async function sendMessageGetReply( action: string, body: Record, queueName = '', -): Promise { +): Promise> { const id = randomUUID(); - const prom = new Promise((resolve, reject) => { + const prom = new Promise>((resolve, reject) => { waitForReplies.push({ correlationId: id, resolve, From 4acb19ed8db2138e1817eb0a1fdfc564924d67e0 Mon Sep 17 00:00:00 2001 From: weeryan17 Date: Mon, 14 Aug 2023 08:31:35 -0400 Subject: [PATCH 08/22] Implement glob to support sub folders --- .gitignore | 2 + package-lock.json | 1109 +++++++++++++++++++++++++++++++++++++---- package.json | 3 +- src/api/entrypoint.ts | 23 +- 4 files changed, 1035 insertions(+), 102 deletions(-) diff --git a/.gitignore b/.gitignore index 2b6be8e..0ca0618 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ node_modules .env config.json dist + +.fleet diff --git a/package-lock.json b/package-lock.json index 8899f67..1d5e2f2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,8 @@ "license": "MIT", "dependencies": { "amqplib": "^0.10.3", - "isolated-vm": "^4.4.1", + "glob": "^10.3.3", + "isolated-vm": "^4.6.0", "joi": "^17.6.2", "neat-config": "^1.0.0", "winston": "^3.8.2", @@ -160,6 +161,95 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "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/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/@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/@isaacs/cliui/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/@jridgewell/resolve-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", @@ -220,6 +310,15 @@ "node": ">= 8" } }, + "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/@sideway/address": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", @@ -560,7 +659,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -569,7 +667,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -622,8 +719,26 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, "node_modules/binary-extensions": { "version": "2.2.0", @@ -634,6 +749,16 @@ "node": ">=8" } }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -656,6 +781,29 @@ "node": ">=8" } }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "node_modules/buffer-more-ints": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", @@ -725,6 +873,11 @@ "node": ">= 6" } }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -749,7 +902,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -835,6 +987,26 @@ "copyup": "copyfiles" } }, + "node_modules/copyfiles/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -850,7 +1022,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -876,12 +1047,42 @@ } } }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/detect-libc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", + "engines": { + "node": ">=8" + } + }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -915,17 +1116,29 @@ "node": ">=6.0.0" } }, + "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/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/enabled": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -1184,6 +1397,14 @@ "node": ">=0.10.0" } }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "engines": { + "node": ">=6" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -1314,6 +1535,26 @@ "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1343,21 +1584,27 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + }, "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, + "version": "10.3.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.3.tgz", + "integrity": "sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw==", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "foreground-child": "^3.1.0", + "jackspeak": "^2.0.3", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/cjs/src/bin.js" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -1375,6 +1622,28 @@ "node": ">=10.13.0" } }, + "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": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/globals": { "version": "13.17.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", @@ -1425,6 +1694,25 @@ "node": ">=8" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", @@ -1480,6 +1768,11 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, "node_modules/is-arrayish": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", @@ -1510,7 +1803,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "engines": { "node": ">=8" } @@ -1555,16 +1847,35 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/isolated-vm": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/isolated-vm/-/isolated-vm-4.4.1.tgz", - "integrity": "sha512-5aDwxQGm78vHS+qJeUli2ILroG7OS/k3D/Mc0kcT9vyujiL4bV7PYYix1mAvuBm3v44nz2qcfAOqgAbhuACc/w==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/isolated-vm/-/isolated-vm-4.6.0.tgz", + "integrity": "sha512-MEnfC/54q5PED3VJ9UJYJPOlU6mYFHS3ivR9E8yeNNBEFRFUNBnY0xO4Rj3D/SOtFKPNmsQp9NWUYSKZqAoZiA==", "hasInstallScript": true, + "dependencies": { + "prebuild-install": "^7.1.1" + }, "engines": { - "node": ">=10.4.0" + "node": ">=16.0.0" + } + }, + "node_modules/jackspeak": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.3.tgz", + "integrity": "sha512-pF0kfjmg8DJLxDrizHoCZGUFz4P4czQ3HyfW4BU0ffebYkzAVlBywp5zaxW/TM+r0sGbmrQdi8EQQVTJFxnGsQ==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, "node_modules/joi": { @@ -1676,7 +1987,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -1712,6 +2022,17 @@ "node": ">=8.6" } }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -1727,8 +2048,15 @@ "node_modules/minimist": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + }, + "node_modules/minipass": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", + "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", + "engines": { + "node": ">=16 || 14 >=14.17" + } }, "node_modules/mkdirp": { "version": "1.0.4", @@ -1742,6 +2070,11 @@ "node": ">=10" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -1760,6 +2093,11 @@ "url": "https://github.com/sponsors/raouldeheer" } }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -1774,6 +2112,17 @@ "joi": "^17.6.0" } }, + "node_modules/node-abi": { + "version": "3.45.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.45.0.tgz", + "integrity": "sha512-iwXuFrMAcFVi/ZoZiqq8BzAdsLw9kxDfTC0HMyjXfSL/6CSDAGD5UmR7azrAgWV1zKYq7dUUMj4owusBWKLsiQ==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/nodemon": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", @@ -1897,7 +2246,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "dependencies": { "wrappy": "1" } @@ -1991,11 +2339,33 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "engines": { "node": ">=8" } }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", + "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", + "engines": { + "node": "14 || >=16.14" + } + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -2026,6 +2396,31 @@ "queue-lit": "^1.4.0" } }, + "node_modules/prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -2075,6 +2470,15 @@ "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", "dev": true }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -2115,6 +2519,28 @@ } ] }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -2200,6 +2626,26 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -2254,7 +2700,6 @@ "version": "7.3.7", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -2269,7 +2714,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -2281,11 +2725,64 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "engines": { "node": ">=8" } }, + "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/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, "node_modules/simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", @@ -2344,7 +2841,20 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "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", @@ -2358,7 +2868,18 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "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" }, @@ -2399,6 +2920,32 @@ "node": ">=8" } }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/text-hex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", @@ -2580,6 +3127,17 @@ "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" } }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -2665,7 +3223,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -2746,11 +3303,27 @@ "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/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/xtend": { "version": "4.0.2", @@ -2773,8 +3346,7 @@ "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/yargs": { "version": "16.2.0", @@ -2926,6 +3498,64 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "requires": { + "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" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==" + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + } + } + } + }, "@jridgewell/resolve-uri": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", @@ -2974,6 +3604,12 @@ "fastq": "^1.6.0" } }, + "@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 + }, "@sideway/address": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", @@ -3208,14 +3844,12 @@ "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -3256,8 +3890,12 @@ "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "binary-extensions": { "version": "2.2.0", @@ -3265,6 +3903,16 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3284,6 +3932,15 @@ "fill-range": "^7.0.1" } }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "buffer-more-ints": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", @@ -3332,6 +3989,11 @@ } } }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -3371,7 +4033,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "requires": { "color-name": "~1.1.4" } @@ -3429,6 +4090,22 @@ "through2": "^2.0.1", "untildify": "^4.0.0", "yargs": "^16.1.0" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } } }, "core-util-is": { @@ -3446,7 +4123,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -3461,12 +4137,30 @@ "ms": "2.1.2" } }, + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "requires": { + "mimic-response": "^3.1.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "detect-libc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==" + }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -3491,17 +4185,29 @@ "esutils": "^2.0.2" } }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "enabled": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -3685,6 +4391,11 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==" + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -3796,6 +4507,20 @@ "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" }, + "foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3815,18 +4540,39 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + }, "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, + "version": "10.3.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.3.tgz", + "integrity": "sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw==", "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "foreground-child": "^3.1.0", + "jackspeak": "^2.0.3", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, "glob-parent": { @@ -3873,6 +4619,11 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, "ignore": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", @@ -3916,6 +4667,11 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, "is-arrayish": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", @@ -3939,8 +4695,7 @@ "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, "is-glob": { "version": "4.0.3", @@ -3970,13 +4725,24 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "isolated-vm": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/isolated-vm/-/isolated-vm-4.4.1.tgz", - "integrity": "sha512-5aDwxQGm78vHS+qJeUli2ILroG7OS/k3D/Mc0kcT9vyujiL4bV7PYYix1mAvuBm3v44nz2qcfAOqgAbhuACc/w==" + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/isolated-vm/-/isolated-vm-4.6.0.tgz", + "integrity": "sha512-MEnfC/54q5PED3VJ9UJYJPOlU6mYFHS3ivR9E8yeNNBEFRFUNBnY0xO4Rj3D/SOtFKPNmsQp9NWUYSKZqAoZiA==", + "requires": { + "prebuild-install": "^7.1.1" + } + }, + "jackspeak": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.3.tgz", + "integrity": "sha512-pF0kfjmg8DJLxDrizHoCZGUFz4P4czQ3HyfW4BU0ffebYkzAVlBywp5zaxW/TM+r0sGbmrQdi8EQQVTJFxnGsQ==", + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } }, "joi": { "version": "17.6.2", @@ -4069,7 +4835,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "requires": { "yallist": "^4.0.0" } @@ -4096,6 +4861,11 @@ "picomatch": "^2.3.1" } }, + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -4108,8 +4878,12 @@ "minimist": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + }, + "minipass": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", + "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==" }, "mkdirp": { "version": "1.0.4", @@ -4117,6 +4891,11 @@ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -4128,6 +4907,11 @@ "integrity": "sha512-+MrqnJRtxdF+xngFfUUkIMQrUUL0KsxbADUkn23Z/4ibGg192Q+z+CQyiYwvWTsYjJygmMR8+w3ZDa98Zh6ESg==", "dev": true }, + "napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -4142,6 +4926,14 @@ "joi": "^17.6.0" } }, + "node-abi": { + "version": "3.45.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.45.0.tgz", + "integrity": "sha512-iwXuFrMAcFVi/ZoZiqq8BzAdsLw9kxDfTC0HMyjXfSL/6CSDAGD5UmR7azrAgWV1zKYq7dUUMj4owusBWKLsiQ==", + "requires": { + "semver": "^7.3.5" + } + }, "nodemon": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", @@ -4241,7 +5033,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "requires": { "wrappy": "1" } @@ -4310,8 +5101,23 @@ "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "requires": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", + "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==" + } + } }, "path-type": { "version": "4.0.0", @@ -4334,6 +5140,25 @@ "queue-lit": "^1.4.0" } }, + "prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "requires": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + } + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -4368,6 +5193,15 @@ "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", "dev": true }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -4391,6 +5225,24 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" + } + } + }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -4446,6 +5298,22 @@ "dev": true, "requires": { "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } } }, "run-parallel": { @@ -4471,7 +5339,6 @@ "version": "7.3.7", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, "requires": { "lru-cache": "^6.0.0" } @@ -4480,7 +5347,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "requires": { "shebang-regex": "^3.0.0" } @@ -4488,8 +5354,27 @@ "shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" + }, + "simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" + }, + "simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "requires": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } }, "simple-swizzle": { "version": "0.2.2", @@ -4539,7 +5424,16 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -4550,7 +5444,14 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "requires": { "ansi-regex": "^5.0.1" } @@ -4576,6 +5477,29 @@ "has-flag": "^4.0.0" } }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + }, "text-hex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", @@ -4719,6 +5643,14 @@ "tslib": "^1.8.1" } }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -4785,7 +5717,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "requires": { "isexe": "^2.0.0" } @@ -4845,11 +5776,20 @@ "strip-ansi": "^6.0.0" } }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "xtend": { "version": "4.0.2", @@ -4866,8 +5806,7 @@ "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "yargs": { "version": "16.2.0", diff --git a/package.json b/package.json index 8e71f2e..0b8fec7 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ "license": "MIT", "dependencies": { "amqplib": "^0.10.3", - "isolated-vm": "^4.4.1", + "glob": "^10.3.3", + "isolated-vm": "^4.6.0", "joi": "^17.6.2", "neat-config": "^1.0.0", "winston": "^3.8.2", diff --git a/src/api/entrypoint.ts b/src/api/entrypoint.ts index 80c2fd3..0965f56 100644 --- a/src/api/entrypoint.ts +++ b/src/api/entrypoint.ts @@ -2,6 +2,7 @@ import joi from 'joi'; import { promises as fs } from 'fs'; import path from 'path'; import { scopedLogger } from '@logger'; +import { glob } from 'glob'; const log = scopedLogger('runner'); @@ -21,21 +22,11 @@ interface Schema { const schemas: Record = {}; export async function setupApi() { - const files = await fs.readdir(path.join(__dirname, './schemas'), { - withFileTypes: true, - }); - const fileNames = files - .filter((v) => { - // js files are supported in production use, where ts are compiled to js - const isCodefile = v.name.endsWith('.js') || v.name.endsWith('.ts'); - const isNormalFile = v.isFile(); - return isCodefile && isNormalFile; - }) - .map((v) => v.name); - - const importedData = fileNames.map((name) => - require(path.join(__dirname, './schemas', name)), - ); + const globFiles = await glob([ + __dirname + '/schemas/**/*.js', + __dirname + '/schemas/**/*.ts', + ]); + const importedData = globFiles.map((name) => require(name)); importedData.forEach((data: Schema) => { schemas[data.action] = data; }); @@ -64,7 +55,7 @@ export async function callApiMethod(payload: any): Promise { }; const isValidPayloadContent = schema.schema.validate(actionData); - if (!schema) + if (!isValidPayloadContent) return { success: false, error: 'input', From 1e0c5129392f7a007379068bab168cff00f1103a Mon Sep 17 00:00:00 2001 From: weeryan17 Date: Sat, 26 Aug 2023 08:49:56 -0400 Subject: [PATCH 09/22] Start working on accepting process requests --- src/managers/rabbitmq-manager.ts | 75 ++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 13 deletions(-) diff --git a/src/managers/rabbitmq-manager.ts b/src/managers/rabbitmq-manager.ts index 909ef70..94a82a4 100644 --- a/src/managers/rabbitmq-manager.ts +++ b/src/managers/rabbitmq-manager.ts @@ -1,17 +1,21 @@ -import { connect, ConsumeMessage } from 'amqplib'; +import { Channel, connect, Connection, ConsumeMessage, Replies } from 'amqplib'; import { config } from '@config'; import { randomUUID } from 'crypto'; import { scopedLogger } from '@logger'; -import { string } from 'joi'; +import AssertQueue = Replies.AssertQueue; +import { ScriptInfo } from '@models/script-info'; const log = scopedLogger('rabbitmq-manager'); -let connection; -let channel; +let connection: Connection; +let channel: Channel; const waitForReplies: QueueConsumer[] = []; -let queue; +let replyQueue: AssertQueue; +let processQueue: AssertQueue; + +export const MetaRoutingKey = 'meta'; interface QueueConsumer { correlationId: string; @@ -34,28 +38,40 @@ export async function tryConnect() { connection = await connect(connectionString); channel = await connection.createChannel(); - queue = await channel.assertQueue('', { + replyQueue = await channel.assertQueue('', { exclusive: true, autoDelete: true, }); - channel.consume(queue.queue, consume).catch((e) => { + processQueue = await channel.assertQueue('custom_command', {}); + + channel.consume(replyQueue.queue, replyConsume).catch((e) => { + log.error(e); + }); + + channel.consume(processQueue.queue, processConsume).catch((e) => { log.error(e); }); } export async function getShardCount() { - const res = await sendMessageGetReply('shard_count', {}); + const res = await sendMessageGetReply('shard_count'); const code = res.status_code; const shards = res.data.shard_count; log.info(`code: ${code}, shard: ${shards}`); } -function consume(message: ConsumeMessage | null) { +function processConsume(message: ConsumeMessage | null) { + const json = JSON.parse(message.content.toString()) as CommandRequest; + // TODO send to command processor +} + +function replyConsume(message: ConsumeMessage | null) { const reply = waitForReplies.find((consumer) => { return consumer.correlationId == message.properties.correlationId; }); + channel.ack(message); const json = JSON.parse(message.content.toString()) as Response; if (json.error) { reply.reject(json); @@ -81,6 +97,38 @@ interface ResponseErrorSub { export type Response = ResponseSuccess | ResponseError; +type ScriptLang = 'JS' | 'TEXT'; + +interface CommandRequest { + lang: ScriptLang; + entrypoint: string; + files: ScriptInfo; + options: Record; + member: Member; + channel: DiscordChannel; + interactionId: string; +} + +interface Member { + id: string; + name: string; + avatarUrl: string; + nickname: string | null; + discriminator: string | null; +} + +interface DiscordChannel { + id: string; + name: string; + type: string; + position: number; +} + +interface CommandOption { + type: string; + value: number | string; +} + interface ResponseSuccess { status_code: number; error: undefined; @@ -99,8 +147,9 @@ interface ShardCount { export async function sendMessageGetReply( action: string, - body: Record, - queueName = '', + body: Record = {}, + exchangeName = 'amq.direct', + routingKey = MetaRoutingKey, ): Promise> { const id = randomUUID(); const prom = new Promise>((resolve, reject) => { @@ -110,9 +159,9 @@ export async function sendMessageGetReply( reject, }); }); - await channel.publish(queueName, 'meta', Buffer.from(JSON.stringify(body)), { + channel.publish(exchangeName, routingKey, Buffer.from(JSON.stringify(body)), { correlationId: id, - replyTo: queue.queue, + replyTo: replyQueue.queue, headers: { action: action, }, From 411a828be64cd6aed60efd7c9260fb0e10785f6c Mon Sep 17 00:00:00 2001 From: weeryan17 Date: Sat, 26 Aug 2023 08:50:38 -0400 Subject: [PATCH 10/22] global injection --- src/index.ts | 24 ++++++++++++++++++------ src/models/isolate-instance.ts | 17 +++++++++++++---- src/models/script-info.ts | 3 ++- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/index.ts b/src/index.ts index 1af77b2..221a4c6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -16,20 +16,32 @@ async function test() { const instance = createIsolateInstance(); await instance.loadScripts([ { - filename: 'file1.js', + id: '', + name: 'file1.js', code: fs.readFileSync(join(__dirname, 'example/file1.js'), 'utf-8'), }, { - filename: 'file2.js', + id: '', + name: 'file2.js', code: fs.readFileSync(join(__dirname, 'example/file2.js'), 'utf-8'), }, { - filename: 'file3.js', + id: '', + name: 'file3.js', code: fs.readFileSync(join(__dirname, 'example/file3.js'), 'utf-8'), }, ]); - await instance.runScript('file1.js'); + await instance.runScript('file1.js', [ + { + key: 'interactionId', + value: 'test', + }, + { + key: 'guildId', + value: 'test2', + }, + ]); } async function bootstrap() { @@ -40,8 +52,8 @@ async function bootstrap() { await setupScripts(); log.info('everything setup, running code'); - await tryConnect(); - await getShardCount(); + //await tryConnect(); + //await getShardCount(); // run test // TODO temp diff --git a/src/models/isolate-instance.ts b/src/models/isolate-instance.ts index a20229b..860a1cd 100644 --- a/src/models/isolate-instance.ts +++ b/src/models/isolate-instance.ts @@ -67,12 +67,12 @@ export class IsolateInstance { public async loadScripts(scriptInfos: ScriptInfo[]) { for (const script of scriptInfos) { - this.scriptContext.files.set(script.filename, { + this.scriptContext.files.set(script.name, { context: await this.backendInstance.createContext(), module: await this.backendInstance.compileModule(script.code, { - filename: script.filename, + filename: script.name, }), - fileName: script.filename, + fileName: script.name, initiated: false, }); } @@ -82,7 +82,10 @@ export class IsolateInstance { this.loaded = true; } - public async runScript(mainFile: string) { + public async runScript( + mainFile: string, + globals: { key: string; value: any }[], + ) { this.running = true; try { setTimeout(() => { @@ -96,6 +99,12 @@ export class IsolateInstance { } const context = await this.backendInstance.createContext(); await createGlobalContext(context); + for (const id of globals.keys()) { + const key = globals[id].key; + const value = JSON.stringify(globals[id].value); + await context.evalClosure('global.' + key + ' = ' + value); + //await context.global.set(key, globals[key]); + } await this.instantiateModule(scriptInfo.module, context); await scriptInfo.module.evaluate({ copy: true, diff --git a/src/models/script-info.ts b/src/models/script-info.ts index b53c49c..7a8d8e1 100644 --- a/src/models/script-info.ts +++ b/src/models/script-info.ts @@ -1,7 +1,8 @@ import { Module } from 'isolated-vm'; export interface ScriptInfo { + id: string; code: string; - filename: string; + name: string; isolateScript?: Module; } From 3712523f36280b230ed627b641d617bfa50b4c15 Mon Sep 17 00:00:00 2001 From: weeryan17 Date: Sat, 26 Aug 2023 08:50:54 -0400 Subject: [PATCH 11/22] start working on replying --- src/api/schemas/messaging/reply.ts | 22 ++++++++++++++++++++++ src/api/schemas/{ => user}/getUserById.ts | 5 +++-- src/example/file1.js | 8 +++----- src/sandboxed/scripts/reply.js | 15 +++++++++++++++ 4 files changed, 43 insertions(+), 7 deletions(-) create mode 100644 src/api/schemas/messaging/reply.ts rename src/api/schemas/{ => user}/getUserById.ts (70%) create mode 100644 src/sandboxed/scripts/reply.js diff --git a/src/api/schemas/messaging/reply.ts b/src/api/schemas/messaging/reply.ts new file mode 100644 index 0000000..4fa9d91 --- /dev/null +++ b/src/api/schemas/messaging/reply.ts @@ -0,0 +1,22 @@ +import joi from 'joi'; +import { idRegex } from '@utils/regex'; + +export const action = 'reply'; + +interface Reply { + message: string; + guildId: string; + interactionId: string; +} + +export const schema = joi.object({ + message: joi.string().required(), + guildId: joi.string().regex(idRegex).required(), + interactionId: joi.string().required(), // TODO do we use the interaction id or something else (message id)? +}); + +export const run = (data: Reply) => { + console.log(data); + // TODO rabbitmq + return ''; +}; diff --git a/src/api/schemas/getUserById.ts b/src/api/schemas/user/getUserById.ts similarity index 70% rename from src/api/schemas/getUserById.ts rename to src/api/schemas/user/getUserById.ts index 1601cf7..6f53cd8 100644 --- a/src/api/schemas/getUserById.ts +++ b/src/api/schemas/user/getUserById.ts @@ -9,10 +9,11 @@ interface GetUserById { } export const schema = joi.object({ - userId: joi.string().regex(idRegex), - guildId: joi.string().regex(idRegex), + userId: joi.string().regex(idRegex).required(), + guildId: joi.string().regex(idRegex).required(), }); export const run = (data: GetUserById) => { + // TODO rabbitmq return 'NO'; }; diff --git a/src/example/file1.js b/src/example/file1.js index 4cae8df..52df64c 100644 --- a/src/example/file1.js +++ b/src/example/file1.js @@ -1,12 +1,10 @@ -import { hello as hello2 } from 'file2.js'; - -log(hello2()); - log('-- starting api tests'); -log(hello()); +/* try { log(await ping()); } catch (e) { log(e.message); } log(await ping('pongalong!')); +*/ +await reply('test'); diff --git a/src/sandboxed/scripts/reply.js b/src/sandboxed/scripts/reply.js new file mode 100644 index 0000000..d5819e2 --- /dev/null +++ b/src/sandboxed/scripts/reply.js @@ -0,0 +1,15 @@ +async function reply(message) { + await __cascadeApi({ + action: 'reply', + data: { + message: message, + // TODO I don't know if this works if we ingest the interaction id and guild into global + guildId: global.guildId, + interactionId: global.interactionId + } + }); +} + +return { + reply +} From 4d5484e884fd3a98f92fc7a2d85a3adbbf97dec2 Mon Sep 17 00:00:00 2001 From: weeryan17 Date: Sat, 26 Aug 2023 09:18:04 -0400 Subject: [PATCH 12/22] Make reply method work --- src/api/schemas/messaging/reply.ts | 15 ++++++++++++++- src/index.ts | 10 +++++----- src/managers/rabbitmq-manager.ts | 2 ++ 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/api/schemas/messaging/reply.ts b/src/api/schemas/messaging/reply.ts index 4fa9d91..dba0a30 100644 --- a/src/api/schemas/messaging/reply.ts +++ b/src/api/schemas/messaging/reply.ts @@ -1,5 +1,6 @@ import joi from 'joi'; import { idRegex } from '@utils/regex'; +import { getShardCount, sendMessageGetReply } from '@managers/rabbitmq-manager'; export const action = 'reply'; @@ -15,7 +16,19 @@ export const schema = joi.object({ interactionId: joi.string().required(), // TODO do we use the interaction id or something else (message id)? }); -export const run = (data: Reply) => { +export const run = async (data: Reply) => { + const count = await getShardCount(); + const shard = Number((BigInt(data.guildId) >> 22n) % BigInt(count)); + await sendMessageGetReply( + 'channel:interaction:reply:simple', + { + guild_id: data.guildId, + interactionId: data.interactionId, + message: data.message, + }, + 'amq.direct', + 'shard.' + shard, + ); console.log(data); // TODO rabbitmq return ''; diff --git a/src/index.ts b/src/index.ts index 221a4c6..e082d45 100644 --- a/src/index.ts +++ b/src/index.ts @@ -35,11 +35,11 @@ async function test() { await instance.runScript('file1.js', [ { key: 'interactionId', - value: 'test', + value: '488394590458478602', }, { key: 'guildId', - value: 'test2', + value: '488394590458478602', }, ]); } @@ -47,13 +47,13 @@ async function test() { async function bootstrap() { // setup app log.info('setting up modules'); - await setupManager(); + setupManager(); await setupApi(); await setupScripts(); log.info('everything setup, running code'); - //await tryConnect(); - //await getShardCount(); + await tryConnect(); + await getShardCount(); // run test // TODO temp diff --git a/src/managers/rabbitmq-manager.ts b/src/managers/rabbitmq-manager.ts index 94a82a4..8e32364 100644 --- a/src/managers/rabbitmq-manager.ts +++ b/src/managers/rabbitmq-manager.ts @@ -60,6 +60,8 @@ export async function getShardCount() { const shards = res.data.shard_count; log.info(`code: ${code}, shard: ${shards}`); + + return shards; // TODO store shard count } function processConsume(message: ConsumeMessage | null) { From bd5f1c1bada2e57b75b3d3eae68cf7b9bada9f43 Mon Sep 17 00:00:00 2001 From: weeryan17 Date: Sun, 27 Aug 2023 13:47:54 -0400 Subject: [PATCH 13/22] Implement object constructing --- src/api/schemas/messaging/reply.ts | 5 ++--- src/index.ts | 2 +- src/managers/isolate-manager.ts | 2 +- src/models/isolate-instance.ts | 11 +++++++++-- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/api/schemas/messaging/reply.ts b/src/api/schemas/messaging/reply.ts index dba0a30..fc7bf5d 100644 --- a/src/api/schemas/messaging/reply.ts +++ b/src/api/schemas/messaging/reply.ts @@ -13,7 +13,7 @@ interface Reply { export const schema = joi.object({ message: joi.string().required(), guildId: joi.string().regex(idRegex).required(), - interactionId: joi.string().required(), // TODO do we use the interaction id or something else (message id)? + interactionId: joi.string().required(), }); export const run = async (data: Reply) => { @@ -23,13 +23,12 @@ export const run = async (data: Reply) => { 'channel:interaction:reply:simple', { guild_id: data.guildId, - interactionId: data.interactionId, + interaction_id: data.interactionId, message: data.message, }, 'amq.direct', 'shard.' + shard, ); - console.log(data); // TODO rabbitmq return ''; }; diff --git a/src/index.ts b/src/index.ts index e082d45..03f00f5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -57,7 +57,7 @@ async function bootstrap() { // run test // TODO temp - await test(); + //await test(); // clean exit stopManager(); diff --git a/src/managers/isolate-manager.ts b/src/managers/isolate-manager.ts index c6083aa..724263b 100644 --- a/src/managers/isolate-manager.ts +++ b/src/managers/isolate-manager.ts @@ -73,7 +73,7 @@ function disposeOfInstance(id: string) { // we still need to be able to dispose of it if it does happen const foundInstances = []; isolates = isolates.filter((ins) => { - if (ins.id !== id) { + if (ins.id !== id && !ins.backendInstance.isDisposed) { foundInstances.push(ins); return true; } diff --git a/src/models/isolate-instance.ts b/src/models/isolate-instance.ts index 860a1cd..f5b5406 100644 --- a/src/models/isolate-instance.ts +++ b/src/models/isolate-instance.ts @@ -84,7 +84,7 @@ export class IsolateInstance { public async runScript( mainFile: string, - globals: { key: string; value: any }[], + globals: { key: string; value: any; type?: string }[], ) { this.running = true; try { @@ -102,7 +102,14 @@ export class IsolateInstance { for (const id of globals.keys()) { const key = globals[id].key; const value = JSON.stringify(globals[id].value); - await context.evalClosure('global.' + key + ' = ' + value); + const type = globals[id].type; + if (type) { + await context.evalClosure( + 'global.' + key + ' = new ' + type + '(' + value + ');', // const key = new type(value); + ); + } else { + await context.evalClosure('global.' + key + ' = ' + value + ';'); + } //await context.global.set(key, globals[key]); } await this.instantiateModule(scriptInfo.module, context); From e913676561a0bda7fdcec7ce5c7f6b670ccbaeab Mon Sep 17 00:00:00 2001 From: weeryan17 Date: Sun, 27 Aug 2023 13:48:48 -0400 Subject: [PATCH 14/22] Create user who ran command in sandbox --- src/managers/rabbitmq-manager.ts | 34 +++++++++++++++++++++++++++----- src/sandboxed/scripts/reply.js | 4 ++-- src/sandboxed/scripts/user.js | 8 ++++++++ 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/managers/rabbitmq-manager.ts b/src/managers/rabbitmq-manager.ts index 8e32364..4771243 100644 --- a/src/managers/rabbitmq-manager.ts +++ b/src/managers/rabbitmq-manager.ts @@ -4,6 +4,7 @@ import { randomUUID } from 'crypto'; import { scopedLogger } from '@logger'; import AssertQueue = Replies.AssertQueue; import { ScriptInfo } from '@models/script-info'; +import { createIsolateInstance } from '@managers/isolate-manager'; const log = scopedLogger('rabbitmq-manager'); @@ -64,9 +65,31 @@ export async function getShardCount() { return shards; // TODO store shard count } -function processConsume(message: ConsumeMessage | null) { - const json = JSON.parse(message.content.toString()) as CommandRequest; - // TODO send to command processor +async function processConsume(message: ConsumeMessage | null) { + const req = JSON.parse(message.content.toString()) as CommandRequest; + // TODO switch between different command types + // TODO send to command processor instead of doing it here + const instance = createIsolateInstance(); + await instance.loadScripts(req.files); + channel.ack(message); + await instance.runScript( + req.files.find((file) => file.id == req.entrypoint).name, + [ + { + key: 'interactionId', + value: req.interaction_id, + }, + { + key: 'guildId', + value: req.guild_id, + }, + { + key: 'user', + value: req.member, + type: 'User', + }, + ], + ); } function replyConsume(message: ConsumeMessage | null) { @@ -104,11 +127,12 @@ type ScriptLang = 'JS' | 'TEXT'; interface CommandRequest { lang: ScriptLang; entrypoint: string; - files: ScriptInfo; + files: ScriptInfo[]; options: Record; member: Member; channel: DiscordChannel; - interactionId: string; + guild_id: string; + interaction_id: string; } interface Member { diff --git a/src/sandboxed/scripts/reply.js b/src/sandboxed/scripts/reply.js index d5819e2..f65f0a3 100644 --- a/src/sandboxed/scripts/reply.js +++ b/src/sandboxed/scripts/reply.js @@ -4,8 +4,8 @@ async function reply(message) { data: { message: message, // TODO I don't know if this works if we ingest the interaction id and guild into global - guildId: global.guildId, - interactionId: global.interactionId + guildId: guildId, + interactionId: interactionId } }); } diff --git a/src/sandboxed/scripts/user.js b/src/sandboxed/scripts/user.js index 1bd2be7..5d258d6 100644 --- a/src/sandboxed/scripts/user.js +++ b/src/sandboxed/scripts/user.js @@ -6,6 +6,14 @@ class User { avatar = ""; discriminator = ""; + constructor(data) { + this.#backingId = data.id; + this.name = data.name; + this.nick = data.nickname; + this.avatar = data.avatarUrl; + this.discriminator = data.discriminator; + } + } async function getUserByID(id) { From 489e7ded49cb0ef1e7300d0ff77995b824d26fe0 Mon Sep 17 00:00:00 2001 From: weeryan17 Date: Sat, 2 Sep 2023 08:02:21 -0400 Subject: [PATCH 15/22] Embeds This took me an hour and a half according to wakatime :/ --- src/api/common/embed.ts | 107 ++++++++++++++++++++++++ src/api/schemas/messaging/reply.ts | 12 +-- src/api/schemas/messaging/replyEmbed.ts | 9 ++ src/api/schemas/user/getUserById.ts | 10 ++- src/example/file1.js | 10 +-- src/sandboxed/scripts/generalObjects.js | 33 ++++++++ src/sandboxed/scripts/messaging.js | 70 ++++++++++++++++ src/sandboxed/scripts/reply.js | 15 ---- src/sandboxed/scripts/user.js | 4 + 9 files changed, 237 insertions(+), 33 deletions(-) create mode 100644 src/api/common/embed.ts create mode 100644 src/api/schemas/messaging/replyEmbed.ts create mode 100644 src/sandboxed/scripts/generalObjects.js create mode 100644 src/sandboxed/scripts/messaging.js delete mode 100644 src/sandboxed/scripts/reply.js diff --git a/src/api/common/embed.ts b/src/api/common/embed.ts new file mode 100644 index 0000000..d351e27 --- /dev/null +++ b/src/api/common/embed.ts @@ -0,0 +1,107 @@ +import joi from 'joi'; + +export interface Embed { + title?: EmbedTitle; + content?: string; + fields?: EmbedField[]; + author?: EmbedAuthor; + provider?: EmbedProver; + footer?: EmbedFooter; + thumbnail?: string; + image?: string; + color?: number; +} + +export interface EmbedField { + title: string; + inline: boolean; + content: string; +} + +export interface EmbedAuthor { + author: string; + url?: string; + image?: string; +} + +export interface EmbedTitle { + title: string; + url?: string; +} + +export interface EmbedFooter { + footer: string; + url?: string; + timestamp?: Date; +} + +export interface EmbedProver { + provider: string; + url?: string; +} + +export const EmbedSchema = joi + .object({ + title: joi.object({ + title: joi.string().max(256).required(), + url: joi.string().uri(), + }), + content: joi.string().max(4096), + fields: joi.array().items( + joi.object({ + title: joi.string().required().max(256), + content: joi.string().required().max(1024), + inline: joi.boolean().required(), + }), + ), + author: joi.object({ + author: joi.string().max(256).required(), + url: joi.string().uri(), + image: joi.string().uri(), + }), + provider: joi.object({ + provider: joi.string().required(), + url: joi.string().uri(), + }), + footer: joi.object({ + footer: joi.string().max(2048).required(), + url: joi.string().uri(), + timestamp: joi.date(), + }), + thumbnail: joi.string().uri(), + image: joi.string().uri(), + color: joi.number(), + }) + .custom((value: Embed, helpers) => { + if (!value.content && !value.fields) { + return helpers.message({ + error: 'Either content or fields are required', + }); + } + let currentLen = 0; + if (value.fields) { + for (const field of value.fields) { + currentLen += field.title.length + field.content.length; + } + } + if (value.title) { + currentLen += value.title.title.length; + } + if (value.content) { + currentLen += value.content.length; + } + if (value.author) { + currentLen += value.author.author.length; + } + if (value.provider) { + currentLen += value.provider.provider.length; + } + if (value.footer) { + currentLen += value.footer.footer.length; + } + if (currentLen > 6000) { + return helpers.message({ + error: 'All embed content together exceed max length of 6000', + }); + } + }); diff --git a/src/api/schemas/messaging/reply.ts b/src/api/schemas/messaging/reply.ts index fc7bf5d..196b797 100644 --- a/src/api/schemas/messaging/reply.ts +++ b/src/api/schemas/messaging/reply.ts @@ -10,11 +10,13 @@ interface Reply { interactionId: string; } -export const schema = joi.object({ - message: joi.string().required(), - guildId: joi.string().regex(idRegex).required(), - interactionId: joi.string().required(), -}); +export const schema = joi + .object({ + message: joi.string().required(), + guildId: joi.string().regex(idRegex).required(), + interactionId: joi.string().required(), + }) + .required(); export const run = async (data: Reply) => { const count = await getShardCount(); diff --git a/src/api/schemas/messaging/replyEmbed.ts b/src/api/schemas/messaging/replyEmbed.ts new file mode 100644 index 0000000..c4afc8a --- /dev/null +++ b/src/api/schemas/messaging/replyEmbed.ts @@ -0,0 +1,9 @@ +import { Embed, EmbedSchema } from '@api/common/embed'; + +export const action = 'replyEmbed'; + +export const schema = EmbedSchema.required(); + +export const run = async (data: Embed) => { + return 'TODO'; +}; diff --git a/src/api/schemas/user/getUserById.ts b/src/api/schemas/user/getUserById.ts index 6f53cd8..73eb701 100644 --- a/src/api/schemas/user/getUserById.ts +++ b/src/api/schemas/user/getUserById.ts @@ -8,10 +8,12 @@ interface GetUserById { guildId: string; } -export const schema = joi.object({ - userId: joi.string().regex(idRegex).required(), - guildId: joi.string().regex(idRegex).required(), -}); +export const schema = joi + .object({ + userId: joi.string().regex(idRegex).required(), + guildId: joi.string().regex(idRegex).required(), + }) + .required(); export const run = (data: GetUserById) => { // TODO rabbitmq diff --git a/src/example/file1.js b/src/example/file1.js index 52df64c..065c9b2 100644 --- a/src/example/file1.js +++ b/src/example/file1.js @@ -1,10 +1,2 @@ log('-- starting api tests'); -/* -try { - log(await ping()); -} catch (e) { - log(e.message); -} -log(await ping('pongalong!')); -*/ -await reply('test'); +await reply('hello ' + user.name + '!'); diff --git a/src/sandboxed/scripts/generalObjects.js b/src/sandboxed/scripts/generalObjects.js new file mode 100644 index 0000000..f578bd4 --- /dev/null +++ b/src/sandboxed/scripts/generalObjects.js @@ -0,0 +1,33 @@ +class Color { + rgb = 0; + + r() { + + } + + g() { + + } + + b() { + + } + + hex() { + + } + + constructor(rgb) { + this.rgb = rgb; + } + + constructor(r, g, b) { + } + + constructor(hex) { + } +} + +return { + Color +} diff --git a/src/sandboxed/scripts/messaging.js b/src/sandboxed/scripts/messaging.js new file mode 100644 index 0000000..15c8ab9 --- /dev/null +++ b/src/sandboxed/scripts/messaging.js @@ -0,0 +1,70 @@ +class Message { + +} + +class Embed { + title: EmbedTitle|null = null; + content = null; + fields: EmbedField[]|null = null; + author: EmbedAuthor|null = null; + provider: EmbedProvider|null = null; + footer: EmbedFooter|null = null; + thumbnail = null; + image = null; + color: Color|null = null; +} + +class EmbedField { + inline = true; + title = ''; + content = ''; +} + +class EmbedAuthor { + author = '' + url = null + image = null +} + +class EmbedTitle { + title = ''; + url = null; +} + +class EmbedFooter { + footer = ''; + url = null; + timestamp = new Date(); +} + +class EmbedProvider { + provider = ''; + url = null; +} + +async function reply(message) { + await __cascadeApi({ + action: 'reply', + data: { + message: message, + guildId: guildId, + interactionId: interactionId + } + }); +} + +async function replyEmbed(embed) { + +} + +return { + Message, + Embed, + EmbedField, + EmbedAuthor, + EmbedTitle, + EmbedFooter, + EmbedProvider, + reply, + replyEmbed +} diff --git a/src/sandboxed/scripts/reply.js b/src/sandboxed/scripts/reply.js deleted file mode 100644 index f65f0a3..0000000 --- a/src/sandboxed/scripts/reply.js +++ /dev/null @@ -1,15 +0,0 @@ -async function reply(message) { - await __cascadeApi({ - action: 'reply', - data: { - message: message, - // TODO I don't know if this works if we ingest the interaction id and guild into global - guildId: guildId, - interactionId: interactionId - } - }); -} - -return { - reply -} diff --git a/src/sandboxed/scripts/user.js b/src/sandboxed/scripts/user.js index 5d258d6..e80af5d 100644 --- a/src/sandboxed/scripts/user.js +++ b/src/sandboxed/scripts/user.js @@ -14,6 +14,10 @@ class User { this.discriminator = data.discriminator; } + getAsMention() { + return '<@' + this.#backingId + '>' + } + } async function getUserByID(id) { From 7eee8895f1d3a1feb12294ac8e92a608c371975e Mon Sep 17 00:00:00 2001 From: weeryan17 Date: Sun, 3 Sep 2023 07:18:34 -0400 Subject: [PATCH 16/22] Finish up scripting embed structure and methods --- src/api/common/embed.ts | 29 +++--- src/sandboxed/scripts/messaging.js | 142 ++++++++++++++++++++++++++--- src/sandboxed/scripts/user.js | 6 +- 3 files changed, 147 insertions(+), 30 deletions(-) diff --git a/src/api/common/embed.ts b/src/api/common/embed.ts index d351e27..a95bacc 100644 --- a/src/api/common/embed.ts +++ b/src/api/common/embed.ts @@ -1,15 +1,22 @@ import joi from 'joi'; +enum MessageType { + INFO, + SUCCESS, + DANGER, + WARNING, + NEUTRAL, +} + export interface Embed { title?: EmbedTitle; content?: string; fields?: EmbedField[]; author?: EmbedAuthor; - provider?: EmbedProver; footer?: EmbedFooter; thumbnail?: string; image?: string; - color?: number; + color?: number | MessageType; } export interface EmbedField { @@ -35,11 +42,6 @@ export interface EmbedFooter { timestamp?: Date; } -export interface EmbedProver { - provider: string; - url?: string; -} - export const EmbedSchema = joi .object({ title: joi.object({ @@ -59,10 +61,6 @@ export const EmbedSchema = joi url: joi.string().uri(), image: joi.string().uri(), }), - provider: joi.object({ - provider: joi.string().required(), - url: joi.string().uri(), - }), footer: joi.object({ footer: joi.string().max(2048).required(), url: joi.string().uri(), @@ -70,7 +68,11 @@ export const EmbedSchema = joi }), thumbnail: joi.string().uri(), image: joi.string().uri(), - color: joi.number(), + color: joi.alternatives( + // allow color to wither be number representation, or message type + joi.number(), + joi.string().valid('INFO', 'SUCCESS', 'DANGER', 'WARNING', 'NEUTRAL'), + ), }) .custom((value: Embed, helpers) => { if (!value.content && !value.fields) { @@ -93,9 +95,6 @@ export const EmbedSchema = joi if (value.author) { currentLen += value.author.author.length; } - if (value.provider) { - currentLen += value.provider.provider.length; - } if (value.footer) { currentLen += value.footer.footer.length; } diff --git a/src/sandboxed/scripts/messaging.js b/src/sandboxed/scripts/messaging.js index 15c8ab9..12a76d7 100644 --- a/src/sandboxed/scripts/messaging.js +++ b/src/sandboxed/scripts/messaging.js @@ -2,47 +2,150 @@ class Message { } +const messageType = { + INFO: 'INFO', + SUCCESS: 'SUCCESS', + DANGER: 'DANGER', + WARNING: 'WARNING', + NEUTRAL: 'NEUTRAL' +} + class Embed { - title: EmbedTitle|null = null; + title = null; // EmbedTitle | null content = null; - fields: EmbedField[]|null = null; - author: EmbedAuthor|null = null; - provider: EmbedProvider|null = null; - footer: EmbedFooter|null = null; + fields = null; // EmbedField[] | null + author = null; // EmbedAuthor | null + footer = null; // EmbedFooter | null thumbnail = null; image = null; - color: Color|null = null; + color = null; // Color | null + + constructor(data) { + if (!data) { + return; + } + // We can ignore the url if title isn't defined as it does nothing, not sure why discord doesn't have a bug object for that like everything else + // I'm trying to be nicer to the users which is why I put it in a sub object + if (data.title) { + this.title = new EmbedTitle(data.title, data.url); + } + this.content = data.content; + if (data.fields) { + this.fields = []; + for (const field of data.fields) { + this.fields.push(new EmbedField(field)); + } + } + if (data.author) { + this.author = new EmbedAuthor(); + } + // Once again trying to be nice to the user, as timestamp is displayed in the footer I'm adding it to the footer obj + if (data.footer || data.timestamp) { + this.footer = new EmbedFooter(data.footer, data.timestamp); + } + this.thumbnail = data.thumbnail; + this.image = data.image; + if (data.color) { + this.color = new Color(data.color); + } + } + + setTitleString(title) { + if (!(this.title instanceof EmbedTitle)) { + this.title = new EmbedTitle(); + } + this.title.title = title; + return this; + } + + setAuthorName(author) { + if (!(this.author instanceof EmbedAuthor)) { + this.author = new EmbedAuthor(); + } + this.author.author = author; + return this; + } + + setFooterText(footer) { + if (!(this.footer instanceof EmbedFooter)) { + this.footer = new EmbedFooter(); + } + this.footer.footer = footer; + return this; + } + + setFooterTimestamp(date) { + if (!(this.footer instanceof EmbedFooter)) { + this.footer = new EmbedFooter(); + } + this.footer.timestamp = date; + return this; + } } class EmbedField { inline = true; title = ''; content = ''; + + constructor(data) { + if (!data) { + return; + } + this.inline = data.inline; + this.title = data.name; + this.content = data.value; + } } class EmbedAuthor { author = '' url = null image = null + + constructor(data) { + if (!data) { + return; + } + this.author = data.name; + this.url = data.iconUrl; + this.image = data.image; + } } class EmbedTitle { title = ''; url = null; + + constructor(title, url) { + this.title = title; + this.url = url; + } } class EmbedFooter { footer = ''; url = null; - timestamp = new Date(); -} + timestamp = null; // Date | null -class EmbedProvider { - provider = ''; - url = null; + constructor(data, timestamp) { + if (data) { + this.footer = data.text; + this.url = data.url; + } + if (timestamp) { + this.timestamp = timestamp; + } + } } +let replyCalled = false; + async function reply(message) { + if (replyCalled) { + // TODO batter errors + throw new Error("Cannot call reply more then once, if you wish to send another message do channel.sendMessage(), if you wish to edit the reply message use the editMessage() function"); + } await __cascadeApi({ action: 'reply', data: { @@ -51,10 +154,23 @@ async function reply(message) { interactionId: interactionId } }); + replyCalled = true; } async function replyEmbed(embed) { - + if (replyCalled) { + // TODO batter errors + throw new Error("Cannot call reply more then once, if you wish to send another message do channel.sendMessage(), if you wish to edit the reply message use the editMessage() function"); + } + await __cascadeApi({ + action: 'replyEmbed', + data: { + embed: embed, + guildId: guildId, + interactionId: interactionId + } + }); + replyCalled = true; } return { @@ -64,7 +180,7 @@ return { EmbedAuthor, EmbedTitle, EmbedFooter, - EmbedProvider, + messageType, reply, replyEmbed } diff --git a/src/sandboxed/scripts/user.js b/src/sandboxed/scripts/user.js index e80af5d..7139a37 100644 --- a/src/sandboxed/scripts/user.js +++ b/src/sandboxed/scripts/user.js @@ -1,14 +1,16 @@ class User { #backingId = "0"; - name = ""; + username = ""; nick = ""; + displayName = ""; avatar = ""; discriminator = ""; constructor(data) { this.#backingId = data.id; - this.name = data.name; + this.username = data.username; + this.displayName = data.display_name this.nick = data.nickname; this.avatar = data.avatarUrl; this.discriminator = data.discriminator; From 74ee9af10d6edd39f5b897846b762f044410da5c Mon Sep 17 00:00:00 2001 From: weeryan17 Date: Sun, 3 Sep 2023 08:42:14 -0400 Subject: [PATCH 17/22] JOI fixes and celan up embeds --- src/api/common/embed.ts | 61 +++++++++++++++++++++++-- src/api/entrypoint.ts | 10 +++- src/api/schemas/messaging/reply.ts | 2 +- src/api/schemas/messaging/replyEmbed.ts | 39 ++++++++++++++-- src/example/file1.js | 18 +++++++- src/sandboxed/scripts/generalObjects.js | 22 ++++++--- src/sandboxed/scripts/messaging.js | 37 ++++++++------- 7 files changed, 156 insertions(+), 33 deletions(-) diff --git a/src/api/common/embed.ts b/src/api/common/embed.ts index a95bacc..7344c1a 100644 --- a/src/api/common/embed.ts +++ b/src/api/common/embed.ts @@ -1,6 +1,6 @@ import joi from 'joi'; -enum MessageType { +export enum MessageType { INFO, SUCCESS, DANGER, @@ -38,10 +38,64 @@ export interface EmbedTitle { export interface EmbedFooter { footer: string; - url?: string; + iconUrl?: string; timestamp?: Date; } +export function convertToBotEmbed(embed: Embed) { + const botEmbed = { + description: embed.content, + image: embed.image, + thumbnail: embed.thumbnail, + title: undefined, + url: undefined, + timestamp: undefined, + footer: undefined, + fields: undefined, + author: undefined, + color: undefined, + message_type: undefined, + }; + if (embed.title) { + botEmbed.title = embed.title.title; + botEmbed.url = embed.title.url; + } + if (embed.footer) { + if (embed.footer.timestamp) { + botEmbed.timestamp = embed.footer.timestamp; + } + if (embed.footer.footer) { + botEmbed.footer = {}; + botEmbed.footer.text = embed.footer.footer; + botEmbed.footer.icon_url = embed.footer.iconUrl; + } + } + if (embed.fields) { + botEmbed.fields = []; + for (const field of embed.fields) { + botEmbed.fields.push({ + name: field.title, + value: field.content, + inline: field.inline, + }); + } + } + if (embed.author) { + botEmbed.author = {}; + botEmbed.author.name = embed.author.author; + botEmbed.author.url = embed.author.url; + botEmbed.author.icon_url = embed.author.image; + } + if (embed.color) { + if (typeof embed.color == 'number') { + botEmbed.color = embed.color; + } else { + botEmbed.message_type = botEmbed.color; + } + } + return botEmbed; +} + export const EmbedSchema = joi .object({ title: joi.object({ @@ -63,7 +117,7 @@ export const EmbedSchema = joi }), footer: joi.object({ footer: joi.string().max(2048).required(), - url: joi.string().uri(), + iconUrl: joi.string().uri(), timestamp: joi.date(), }), thumbnail: joi.string().uri(), @@ -103,4 +157,5 @@ export const EmbedSchema = joi error: 'All embed content together exceed max length of 6000', }); } + return value; }); diff --git a/src/api/entrypoint.ts b/src/api/entrypoint.ts index 0965f56..3dc6597 100644 --- a/src/api/entrypoint.ts +++ b/src/api/entrypoint.ts @@ -3,6 +3,7 @@ import { promises as fs } from 'fs'; import path from 'path'; import { scopedLogger } from '@logger'; import { glob } from 'glob'; +import { config } from '@config'; const log = scopedLogger('runner'); @@ -55,12 +56,15 @@ export async function callApiMethod(payload: any): Promise { }; const isValidPayloadContent = schema.schema.validate(actionData); - if (!isValidPayloadContent) + if (isValidPayloadContent.error) { + if (config.logging.allowScripts) + log.warn('Failed validation', isValidPayloadContent.error); return { success: false, error: 'input', data: isValidPayloadContent.error, }; + } try { // this is awaited regardless of promise or not @@ -70,7 +74,9 @@ export async function callApiMethod(payload: any): Promise { data, }; } catch (err) { - log.error('Failed to run api method: ' + schema.action, err); + const errorStr: Error | string = + err instanceof Error ? err : JSON.stringify(err, null, 2); + log.error('Failed to run api method: ' + schema.action, errorStr); return { success: false, error: 'exec', diff --git a/src/api/schemas/messaging/reply.ts b/src/api/schemas/messaging/reply.ts index 196b797..dbf8aa5 100644 --- a/src/api/schemas/messaging/reply.ts +++ b/src/api/schemas/messaging/reply.ts @@ -31,6 +31,6 @@ export const run = async (data: Reply) => { 'amq.direct', 'shard.' + shard, ); - // TODO rabbitmq + // TODO return message return ''; }; diff --git a/src/api/schemas/messaging/replyEmbed.ts b/src/api/schemas/messaging/replyEmbed.ts index c4afc8a..5f4615c 100644 --- a/src/api/schemas/messaging/replyEmbed.ts +++ b/src/api/schemas/messaging/replyEmbed.ts @@ -1,9 +1,42 @@ -import { Embed, EmbedSchema } from '@api/common/embed'; +import { convertToBotEmbed, Embed, EmbedSchema } from '@api/common/embed'; +import { getShardCount, sendMessageGetReply } from '@managers/rabbitmq-manager'; +import joi from 'joi'; +import { idRegex } from '@utils/regex'; export const action = 'replyEmbed'; -export const schema = EmbedSchema.required(); +interface ReplyEmbed { + embed: Embed; + guildId: string; + interactionId: string; +} -export const run = async (data: Embed) => { +export const schema = joi + .object({ + embed: EmbedSchema.required(), + guildId: joi.string().regex(idRegex).required(), + interactionId: joi.string().required(), + }) + .required(); + +//export const schema = EmbedSchema.required(); + +export const run = async (data: ReplyEmbed) => { + const botEmbed = convertToBotEmbed(data.embed); + const message = { + embeds: [botEmbed], + }; + const count = await getShardCount(); + const shard = Number((BigInt(data.guildId) >> 22n) % BigInt(count)); + await sendMessageGetReply( + 'channel:interaction:reply:complex', + { + guild_id: data.guildId, + interaction_id: data.interactionId, + message: message, + }, + 'amq.direct', + 'shard.' + shard, + ); return 'TODO'; }; diff --git a/src/example/file1.js b/src/example/file1.js index 065c9b2..1e15b32 100644 --- a/src/example/file1.js +++ b/src/example/file1.js @@ -1,2 +1,18 @@ log('-- starting api tests'); -await reply('hello ' + user.name + '!'); +let embed = new Embed(); +let title = new EmbedTitle(); +title.title = "Test embed" +title.url = "https://cascadebot.org/" +embed.title = title; +let author = new EmbedAuthor(); +//author.author = "Test"; //user.username; +author.url = "https://example.com" +author.image = user.avatar +embed.author = author; +log(embed.author); +embed.content = "Hi " + user.displayName + " this is a test of embeds" +let footer = new EmbedFooter(); +footer.timestamp = new Date(); +footer.footer = "This is a footer"; +embed.footer = footer; +await replyEmbed(embed); diff --git a/src/sandboxed/scripts/generalObjects.js b/src/sandboxed/scripts/generalObjects.js index f578bd4..baa68d4 100644 --- a/src/sandboxed/scripts/generalObjects.js +++ b/src/sandboxed/scripts/generalObjects.js @@ -17,15 +17,25 @@ class Color { } - constructor(rgb) { + /*constructor(rgb) { this.rgb = rgb; + }*/ + + constructor(rRgbHex, g, b) { + if (typeof rRgbHex == "string") { + // TODO convert from hex to rgb + return; + } + if (typeof rRgbHex == "number" && typeof g == "number" && typeof b == "number") { + // TODO combine r g b values into combined rgb number + return; + } + // Assume rRgbHex is the combined rgb number TODO bad assumption? + this.rgb = rRgbHex; } - constructor(r, g, b) { - } - - constructor(hex) { - } + /*constructor(hex) { + }*/ } return { diff --git a/src/sandboxed/scripts/messaging.js b/src/sandboxed/scripts/messaging.js index 12a76d7..25a7b7f 100644 --- a/src/sandboxed/scripts/messaging.js +++ b/src/sandboxed/scripts/messaging.js @@ -11,14 +11,14 @@ const messageType = { } class Embed { - title = null; // EmbedTitle | null - content = null; - fields = null; // EmbedField[] | null - author = null; // EmbedAuthor | null - footer = null; // EmbedFooter | null - thumbnail = null; - image = null; - color = null; // Color | null + title = undefined; // EmbedTitle | undefined + content = undefined; + fields = undefined; // EmbedField[] | undefined + author = undefined; // EmbedAuthor | undefined + footer = undefined; // EmbedFooter | undefined + thumbnail = undefined; + image = undefined; + color = undefined; // Color | messageType | undefined constructor(data) { if (!data) { @@ -37,7 +37,7 @@ class Embed { } } if (data.author) { - this.author = new EmbedAuthor(); + this.author = new EmbedAuthor(data.author); } // Once again trying to be nice to the user, as timestamp is displayed in the footer I'm adding it to the footer obj if (data.footer || data.timestamp) { @@ -48,6 +48,9 @@ class Embed { if (data.color) { this.color = new Color(data.color); } + if (data.message_type) { + this.color = data.message_type; + } } setTitleString(title) { @@ -99,23 +102,23 @@ class EmbedField { } class EmbedAuthor { - author = '' - url = null - image = null + author = ''; + url = undefined; + image = undefined; constructor(data) { if (!data) { return; } this.author = data.name; - this.url = data.iconUrl; + this.url = data.icon_url; this.image = data.image; } } class EmbedTitle { title = ''; - url = null; + url = undefined; constructor(title, url) { this.title = title; @@ -125,13 +128,13 @@ class EmbedTitle { class EmbedFooter { footer = ''; - url = null; - timestamp = null; // Date | null + iconUrl = undefined; + timestamp = undefined; // Date | undefined constructor(data, timestamp) { if (data) { this.footer = data.text; - this.url = data.url; + this.iconUrl = data.icon_url; } if (timestamp) { this.timestamp = timestamp; From 99a97d2c1cc8e93a8cfe516c1dab935f1fb20a1e Mon Sep 17 00:00:00 2001 From: mrjvs Date: Sun, 3 Sep 2023 14:59:37 +0200 Subject: [PATCH 18/22] install libs and fix vulns --- package-lock.json | 192 +++++++++++++++++++++++----------------------- package.json | 5 +- 2 files changed, 100 insertions(+), 97 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1d5e2f2..318c194 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,8 @@ "glob": "^10.3.3", "isolated-vm": "^4.6.0", "joi": "^17.6.2", - "neat-config": "^1.0.0", + "neat-config": "^2.0.0", + "type-fest": "^4.3.1", "winston": "^3.8.2", "winston-console-format": "^1.0.8" }, @@ -26,7 +27,7 @@ "eslint": "^8.24.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-prettier": "^4.2.1", - "nodemon": "^2.0.20", + "nodemon": "^3.0.1", "rimraf": "^3.0.2", "ts-node": "^10.9.1", "tsc-alias": "^1.7.0", @@ -328,9 +329,9 @@ } }, "node_modules/@sideway/formula": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz", - "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" }, "node_modules/@sideway/pinpoint": { "version": "2.0.0", @@ -1659,6 +1660,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globals/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -1921,9 +1934,9 @@ "dev": true }, "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, "bin": { "json5": "lib/cli.js" @@ -2105,11 +2118,12 @@ "dev": true }, "node_modules/neat-config": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/neat-config/-/neat-config-1.0.0.tgz", - "integrity": "sha512-EKvHxsZ9yOUHWhx6MxxzbTDhNK0wiSbfaU42s2OnQuVgR+FwpswaiSm3xX7ST4TcN+rJiEw+GuhfK015vHKwrA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/neat-config/-/neat-config-2.0.0.tgz", + "integrity": "sha512-lSj6iux36bIENAScCXAr1zUrZJIV4uhD6L+H1PDfyB2FfVs2XSDetP6rXzFONL1BI/kaJ4anypAT73zdNdyjEA==", "dependencies": { - "joi": "^17.6.0" + "joi": "^17.6.0", + "zod": "^3.20.6" } }, "node_modules/node-abi": { @@ -2124,9 +2138,9 @@ } }, "node_modules/nodemon": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", - "integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.1.tgz", + "integrity": "sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==", "dev": true, "dependencies": { "chokidar": "^3.5.2", @@ -2134,8 +2148,8 @@ "ignore-by-default": "^1.0.1", "minimatch": "^3.1.2", "pstree.remy": "^1.1.8", - "semver": "^5.7.1", - "simple-update-notifier": "^1.0.7", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", "supports-color": "^5.5.0", "touch": "^3.1.0", "undefsafe": "^2.0.5" @@ -2144,7 +2158,7 @@ "nodemon": "bin/nodemon.js" }, "engines": { - "node": ">=8.10.0" + "node": ">=10" }, "funding": { "type": "opencollective", @@ -2169,15 +2183,6 @@ "node": ">=4" } }, - "node_modules/nodemon/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, "node_modules/nodemon/node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -2697,9 +2702,9 @@ } }, "node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -2792,24 +2797,15 @@ } }, "node_modules/simple-update-notifier": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz", - "integrity": "sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", "dev": true, "dependencies": { - "semver": "~7.0.0" + "semver": "^7.5.3" }, "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/simple-update-notifier/node_modules/semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" + "node": ">=10" } }, "node_modules/slash": { @@ -3151,12 +3147,11 @@ } }, "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.3.1.tgz", + "integrity": "sha512-pphNW/msgOUSkJbH58x8sqpq8uQj6b0ZKGxEsLKMUnGorRcDjrUaLS+39+/ub41JNTwrrMyJcUB8+YZs3mbwqw==", "engines": { - "node": ">=10" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -3278,9 +3273,9 @@ } }, "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -3395,6 +3390,14 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "3.22.2", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.2.tgz", + "integrity": "sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } }, "dependencies": { @@ -3619,9 +3622,9 @@ } }, "@sideway/formula": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz", - "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" }, "@sideway/pinpoint": { "version": "2.0.0", @@ -4591,6 +4594,14 @@ "dev": true, "requires": { "type-fest": "^0.20.2" + }, + "dependencies": { + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } } }, "globby": { @@ -4784,9 +4795,9 @@ "dev": true }, "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true }, "kuler": { @@ -4919,11 +4930,12 @@ "dev": true }, "neat-config": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/neat-config/-/neat-config-1.0.0.tgz", - "integrity": "sha512-EKvHxsZ9yOUHWhx6MxxzbTDhNK0wiSbfaU42s2OnQuVgR+FwpswaiSm3xX7ST4TcN+rJiEw+GuhfK015vHKwrA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/neat-config/-/neat-config-2.0.0.tgz", + "integrity": "sha512-lSj6iux36bIENAScCXAr1zUrZJIV4uhD6L+H1PDfyB2FfVs2XSDetP6rXzFONL1BI/kaJ4anypAT73zdNdyjEA==", "requires": { - "joi": "^17.6.0" + "joi": "^17.6.0", + "zod": "^3.20.6" } }, "node-abi": { @@ -4935,9 +4947,9 @@ } }, "nodemon": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", - "integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.1.tgz", + "integrity": "sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==", "dev": true, "requires": { "chokidar": "^3.5.2", @@ -4945,8 +4957,8 @@ "ignore-by-default": "^1.0.1", "minimatch": "^3.1.2", "pstree.remy": "^1.1.8", - "semver": "^5.7.1", - "simple-update-notifier": "^1.0.7", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", "supports-color": "^5.5.0", "touch": "^3.1.0", "undefsafe": "^2.0.5" @@ -4967,12 +4979,6 @@ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -5336,9 +5342,9 @@ "integrity": "sha512-eehKHKpab6E741ud7ZIMcXhKcP6TSIezPkNZhy5U8xC6+VvrRdUA2tMgxGxaGl4cz7c2Ew5+mg5+wNB16KQqrA==" }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "requires": { "lru-cache": "^6.0.0" } @@ -5385,20 +5391,12 @@ } }, "simple-update-notifier": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz", - "integrity": "sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", "dev": true, "requires": { - "semver": "~7.0.0" - }, - "dependencies": { - "semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true - } + "semver": "^7.5.3" } }, "slash": { @@ -5661,10 +5659,9 @@ } }, "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.3.1.tgz", + "integrity": "sha512-pphNW/msgOUSkJbH58x8sqpq8uQj6b0ZKGxEsLKMUnGorRcDjrUaLS+39+/ub41JNTwrrMyJcUB8+YZs3mbwqw==" }, "typescript": { "version": "4.8.4", @@ -5760,9 +5757,9 @@ } }, "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true }, "wrap-ansi": { @@ -5840,6 +5837,11 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true + }, + "zod": { + "version": "3.22.2", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.2.tgz", + "integrity": "sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg==" } } } diff --git a/package.json b/package.json index 0b8fec7..79040be 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ "glob": "^10.3.3", "isolated-vm": "^4.6.0", "joi": "^17.6.2", - "neat-config": "^1.0.0", + "neat-config": "^2.0.0", + "type-fest": "^4.3.1", "winston": "^3.8.2", "winston-console-format": "^1.0.8" }, @@ -34,7 +35,7 @@ "eslint": "^8.24.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-prettier": "^4.2.1", - "nodemon": "^2.0.20", + "nodemon": "^3.0.1", "rimraf": "^3.0.2", "ts-node": "^10.9.1", "tsc-alias": "^1.7.0", From 763a5ed5317dee584653be62bf6f35f2fab38a74 Mon Sep 17 00:00:00 2001 From: mrjvs Date: Sun, 3 Sep 2023 14:59:43 +0200 Subject: [PATCH 19/22] move config to zod --- src/config/fragments/development.ts | 5 ++- src/config/index.ts | 3 +- src/config/parts/index.ts | 15 ++++---- src/config/parts/logging.ts | 13 +++---- src/config/parts/rabbitMQ.ts | 54 +++++++++-------------------- 5 files changed, 32 insertions(+), 58 deletions(-) diff --git a/src/config/fragments/development.ts b/src/config/fragments/development.ts index 081b994..c5deee1 100644 --- a/src/config/fragments/development.ts +++ b/src/config/fragments/development.ts @@ -1,4 +1,7 @@ -export const developmentFragment = { +import { Config } from '@config/parts'; +import { PartialDeep } from 'type-fest'; + +export const developmentFragment: PartialDeep = { logging: { format: 'pretty', allowScripts: true, diff --git a/src/config/index.ts b/src/config/index.ts index 8f7e4c6..37aab88 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -7,7 +7,8 @@ export const config = createConfigLoader() .addFromCLI('conf-') .addFromFile('.env') .addFromFile('config.json') - .addJOISchema(configSchema) + .addZodSchema(configSchema) .setFragmentKey('usePresets') .addConfigFragments(fragments) + .freeze() .load(); diff --git a/src/config/parts/index.ts b/src/config/parts/index.ts index 3bd2ea3..6376f24 100644 --- a/src/config/parts/index.ts +++ b/src/config/parts/index.ts @@ -1,13 +1,10 @@ -import joi from 'joi'; -import { LoggingConf, loggingConfSchema } from './logging'; -import { RabbitMQConf, rabbitMqConfSchema } from '@config/parts/rabbitMQ'; +import { z } from 'zod'; +import { loggingConfSchema } from './logging'; +import { rabbitMqConfSchema } from '@config/parts/rabbitMQ'; -export interface Config { - logging: LoggingConf; - rabbitMq: RabbitMQConf; -} +export type Config = z.infer; -export const configSchema = joi.object({ - logging: loggingConfSchema.default(), +export const configSchema = z.object({ + logging: loggingConfSchema.default({}), rabbitMq: rabbitMqConfSchema, }); diff --git a/src/config/parts/logging.ts b/src/config/parts/logging.ts index af5c80e..cf4f285 100644 --- a/src/config/parts/logging.ts +++ b/src/config/parts/logging.ts @@ -1,11 +1,6 @@ -import joi from 'joi'; +import { z } from 'zod'; -export interface LoggingConf { - format: 'json' | 'pretty'; - allowScripts: boolean; -} - -export const loggingConfSchema = joi.object({ - format: joi.string().valid('json', 'pretty').default('json'), - allowScripts: joi.boolean().default(false), +export const loggingConfSchema = z.object({ + format: z.enum(['json', 'pretty']).default('json'), + allowScripts: z.coerce.boolean().default(false), }); diff --git a/src/config/parts/rabbitMQ.ts b/src/config/parts/rabbitMQ.ts index 7ea6207..86025d2 100644 --- a/src/config/parts/rabbitMQ.ts +++ b/src/config/parts/rabbitMQ.ts @@ -1,40 +1,18 @@ -import joi from 'joi'; +import { z } from 'zod'; import { pathRegex } from '@utils/regex'; -interface RabbitMQIndividualConf { - username: string; - password: string; - hostname: string; - port: number; // = 5672 - virtualHost: string; // = "/" - type: 'individual'; -} - -interface RabbitMQConnectionStringConfig { - connectionString: string; - type: 'connectionString'; -} - -export type RabbitMQConf = - | RabbitMQIndividualConf - | RabbitMQConnectionStringConfig; - -export const rabbitMqConfSchema = joi - .alternatives() - .try( - joi.object({ - username: joi.string().required(), - password: joi.string().required(), - hostname: joi.string().hostname().required(), - port: joi.number().default(5672), - virtualHost: joi.string().regex(pathRegex).default('/'), - type: joi.string().default('individual').valid('individual'), - }), - joi.object({ - connectionString: joi.string().uri({ - scheme: 'amqp', - }), - type: joi.string().default('connectionString').valid('connectionString'), - }), - ) - .match('one'); +// TODO optional types? +export const rabbitMqConfSchema = z.discriminatedUnion('type', [ + z.object({ + type: z.literal('connectionString'), + connectionString: z.string().url(), // TODO check scheme + }), + z.object({ + type: z.literal('individual'), + username: z.string(), + password: z.string(), + hostname: z.string(), // TODO hostname + port: z.coerce.number().default(5672), + virtualHost: z.string().regex(pathRegex).default('/'), + }), +]); From 21db7c35068945a3f81d7879f60e2964694cd696 Mon Sep 17 00:00:00 2001 From: mrjvs Date: Sun, 3 Sep 2023 15:09:16 +0200 Subject: [PATCH 20/22] linting --- .eslintrc.js | 4 + src/api/entrypoint.ts | 2 - src/api/schemas/ping.ts | 2 +- src/api/schemas/user/getUserById.ts | 2 +- src/index.ts | 2 +- src/isolate-tests.ts | 109 ---------------------------- tsconfig.json | 1 + 7 files changed, 8 insertions(+), 114 deletions(-) delete mode 100644 src/isolate-tests.ts diff --git a/.eslintrc.js b/.eslintrc.js index bc31e71..2e6ca3d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -20,6 +20,10 @@ module.exports = { '@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off', '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-unused-vars': [ + 'warn', + { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }, + ], }, ignorePatterns: ['**/*.js'], }; diff --git a/src/api/entrypoint.ts b/src/api/entrypoint.ts index 3dc6597..8d7873c 100644 --- a/src/api/entrypoint.ts +++ b/src/api/entrypoint.ts @@ -1,6 +1,4 @@ import joi from 'joi'; -import { promises as fs } from 'fs'; -import path from 'path'; import { scopedLogger } from '@logger'; import { glob } from 'glob'; import { config } from '@config'; diff --git a/src/api/schemas/ping.ts b/src/api/schemas/ping.ts index 2fa0e5b..0db535d 100644 --- a/src/api/schemas/ping.ts +++ b/src/api/schemas/ping.ts @@ -10,6 +10,6 @@ export const schema = joi.object({ msg: joi.string().default('pong!'), }); -export const run = async (data: Input) => { +export const run = async (_data: Input) => { throw new Error('test'); }; diff --git a/src/api/schemas/user/getUserById.ts b/src/api/schemas/user/getUserById.ts index 73eb701..b241b84 100644 --- a/src/api/schemas/user/getUserById.ts +++ b/src/api/schemas/user/getUserById.ts @@ -15,7 +15,7 @@ export const schema = joi }) .required(); -export const run = (data: GetUserById) => { +export const run = (_data: GetUserById) => { // TODO rabbitmq return 'NO'; }; diff --git a/src/index.ts b/src/index.ts index 03f00f5..39c75b7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -12,7 +12,7 @@ import { getShardCount, tryConnect } from '@managers/rabbitmq-manager'; const log = scopedLogger('command-processor'); -async function test() { +async function _test() { const instance = createIsolateInstance(); await instance.loadScripts([ { diff --git a/src/isolate-tests.ts b/src/isolate-tests.ts deleted file mode 100644 index 63fbb4e..0000000 --- a/src/isolate-tests.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { Callback, Isolate } from 'isolated-vm'; -import { ScriptInfo } from '@/models/script-info'; -import fs from 'fs'; -import { join } from 'path'; - -const vmInstance = new Isolate({ - memoryLimit: 512, - onCatastrophicError: handleError, -}); - -let startTime = 0n; - -async function doTests() { - const scriptInfoArray: ScriptInfo[] = [ - { - code: fs.readFileSync(join(__dirname, 'example/file1.js'), 'utf-8'), - filename: 'file1.js', - }, - { - code: fs.readFileSync(join(__dirname, 'example/file1.js'), 'utf-8'), - filename: 'file2.js', - }, - ]; - for (const scriptInfoIndex in scriptInfoArray) { - const scriptInfo = scriptInfoArray[scriptInfoIndex]; - scriptInfo.isolateScript = await vmInstance.compileModule(scriptInfo.code, { - filename: scriptInfo.filename, - }); - } - const context = await vmInstance.createContext(); - const jail = context.global; - await jail.set('global', jail.derefInto()); - - await context.global.set( - 'require', - new Callback(function (fileName: string) { - console.log('require function called for file ' + fileName); - const newContext = vmInstance.createContextSync(); - newContext.global.setSync( - 'log', - new Callback(function (message: string) { - console.log(message); - }), - ); - fileName = fileName + '.js'; - // console.log(fileName); - // const script = scriptInfoArray.find((info) => info.filename == fileName); - //let result = script!.isolateScript?.run(newContext); - }), - ); - /*await context.global.set("wait", new Callback(function () { - let resolve: any = null; - setTimeout(() => resolve(), 5000); - return new Promise((r) => resolve = r); - }))*/ - await context.global.set( - 'log', - new Callback(function (message: string) { - console.log(message); - }), - ); - - await context.evalClosure( - ` - global.wait = function timeoutPromise(ms) { - return $0.apply(undefined, [ms], { arguments: { copy: true }, result: { copy: true, promise: true } }) - } - `, - [ - (ms: number) => { - let resolve: any = null; - setTimeout(() => resolve(), ms); - return new Promise((r) => (resolve = r)); - }, - ], - { arguments: { reference: true } }, - ); - - const mainScript = scriptInfoArray.find( - (info) => info.filename == 'file1.js', - ); - try { - await mainScript.isolateScript?.instantiate(context, () => { - throw new Error(); - }); - startTime = vmInstance.cpuTime; - console.log('initial cpu time: ' + startTime); - console.log(await mainScript.isolateScript?.evaluate()); - } catch (e) { - console.log(e); - } -} - -setInterval( - () => - console.log( - 'cpu time ' + - vmInstance.cpuTime + - ' difference ' + - (vmInstance.cpuTime - startTime), - ), - 100, -); - -function handleError(message: string) { - console.error('catastrophic vm instance error:', message); -} - -doTests().catch((err) => console.error(err)); diff --git a/tsconfig.json b/tsconfig.json index ab1f560..8867496 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,6 +11,7 @@ "experimentalDecorators": true, "isolatedModules": false, "emitDecoratorMetadata": true, + "skipLibCheck": true, "paths": { "@*": ["./*"] } From b493667ea8e6344d49a0d7cf1235a1f9cf60b19a Mon Sep 17 00:00:00 2001 From: mrjvs Date: Sun, 3 Sep 2023 15:43:58 +0200 Subject: [PATCH 21/22] Move all schema validation to zod --- package-lock.json | 4 +- package.json | 4 +- src/api/common/embed.ts | 173 ++++++++++-------------- src/api/entrypoint.ts | 21 +-- src/api/schemas/messaging/reply.ts | 20 +-- src/api/schemas/messaging/replyEmbed.ts | 22 ++- src/api/schemas/ping.ts | 12 +- src/api/schemas/readme.md | 4 +- src/api/schemas/user/getUserById.ts | 17 +-- src/models/setup-context.ts | 6 +- 10 files changed, 117 insertions(+), 166 deletions(-) diff --git a/package-lock.json b/package-lock.json index 318c194..63f6f5d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,11 +12,11 @@ "amqplib": "^0.10.3", "glob": "^10.3.3", "isolated-vm": "^4.6.0", - "joi": "^17.6.2", "neat-config": "^2.0.0", "type-fest": "^4.3.1", "winston": "^3.8.2", - "winston-console-format": "^1.0.8" + "winston-console-format": "^1.0.8", + "zod": "^3.22.2" }, "devDependencies": { "@types/amqplib": "^0.8.2", diff --git a/package.json b/package.json index 79040be..e7786d5 100644 --- a/package.json +++ b/package.json @@ -20,11 +20,11 @@ "amqplib": "^0.10.3", "glob": "^10.3.3", "isolated-vm": "^4.6.0", - "joi": "^17.6.2", "neat-config": "^2.0.0", "type-fest": "^4.3.1", "winston": "^3.8.2", - "winston-console-format": "^1.0.8" + "winston-console-format": "^1.0.8", + "zod": "^3.22.2" }, "devDependencies": { "@types/amqplib": "^0.8.2", diff --git a/src/api/common/embed.ts b/src/api/common/embed.ts index 7344c1a..081d5d4 100644 --- a/src/api/common/embed.ts +++ b/src/api/common/embed.ts @@ -1,46 +1,81 @@ -import joi from 'joi'; +import { RequiredKeysOf } from 'type-fest'; +import { z } from 'zod'; -export enum MessageType { - INFO, - SUCCESS, - DANGER, - WARNING, - NEUTRAL, -} +export const messageType = { + INFO: 'INFO', + SUCCESS: 'SUCCESS', + DANGER: 'DANGER', + WARNING: 'WARNING', + NEUTRAL: 'NEUTRAL', +} as const; -export interface Embed { - title?: EmbedTitle; - content?: string; - fields?: EmbedField[]; - author?: EmbedAuthor; - footer?: EmbedFooter; - thumbnail?: string; - image?: string; - color?: number | MessageType; -} +export type MessageType = RequiredKeysOf; -export interface EmbedField { - title: string; - inline: boolean; - content: string; -} +const colorSchema = z.number().or(z.nativeEnum(messageType)); -export interface EmbedAuthor { - author: string; - url?: string; - image?: string; -} +const embedFieldSchema = z.object({ + title: z.string().max(256), + content: z.string().max(1024), + inline: z.boolean(), +}); -export interface EmbedTitle { - title: string; - url?: string; -} +const embedAuthorschema = z.object({ + author: z.string().max(256), + url: z.string().url().optional(), + image: z.string().url().optional(), +}); -export interface EmbedFooter { - footer: string; - iconUrl?: string; - timestamp?: Date; -} +const embedTitleSchema = z.object({ + title: z.string().max(256), + url: z.string().url().optional(), +}); + +const embedFooterSchema = z.object({ + footer: z.string().max(2048), + iconUrl: z.string().url().optional(), + timestamp: z.date().optional(), +}); + +export const EmbedSchema = z + .object({ + title: embedTitleSchema, + content: z.string().max(4096), + fields: z.array(embedFieldSchema), + author: embedAuthorschema, + footer: embedFooterSchema, + thumbnail: z.string().url(), + image: z.string().url(), + color: colorSchema, + }) + .partial() + .refine( + (value) => !value.content && !value.fields, + 'Either content or fields are required', + ) + .refine((value) => { + let currentLen = 0; + if (value.fields) { + for (const field of value.fields) { + currentLen += field.title.length + field.content.length; + } + } + if (value.title) { + currentLen += value.title.title.length; + } + if (value.content) { + currentLen += value.content.length; + } + if (value.author) { + currentLen += value.author.author.length; + } + if (value.footer) { + currentLen += value.footer.footer.length; + } + + return currentLen <= 6000; + }, 'All embed content together exceed max length of 6000'); + +type Embed = z.infer; export function convertToBotEmbed(embed: Embed) { const botEmbed = { @@ -95,67 +130,3 @@ export function convertToBotEmbed(embed: Embed) { } return botEmbed; } - -export const EmbedSchema = joi - .object({ - title: joi.object({ - title: joi.string().max(256).required(), - url: joi.string().uri(), - }), - content: joi.string().max(4096), - fields: joi.array().items( - joi.object({ - title: joi.string().required().max(256), - content: joi.string().required().max(1024), - inline: joi.boolean().required(), - }), - ), - author: joi.object({ - author: joi.string().max(256).required(), - url: joi.string().uri(), - image: joi.string().uri(), - }), - footer: joi.object({ - footer: joi.string().max(2048).required(), - iconUrl: joi.string().uri(), - timestamp: joi.date(), - }), - thumbnail: joi.string().uri(), - image: joi.string().uri(), - color: joi.alternatives( - // allow color to wither be number representation, or message type - joi.number(), - joi.string().valid('INFO', 'SUCCESS', 'DANGER', 'WARNING', 'NEUTRAL'), - ), - }) - .custom((value: Embed, helpers) => { - if (!value.content && !value.fields) { - return helpers.message({ - error: 'Either content or fields are required', - }); - } - let currentLen = 0; - if (value.fields) { - for (const field of value.fields) { - currentLen += field.title.length + field.content.length; - } - } - if (value.title) { - currentLen += value.title.title.length; - } - if (value.content) { - currentLen += value.content.length; - } - if (value.author) { - currentLen += value.author.author.length; - } - if (value.footer) { - currentLen += value.footer.footer.length; - } - if (currentLen > 6000) { - return helpers.message({ - error: 'All embed content together exceed max length of 6000', - }); - } - return value; - }); diff --git a/src/api/entrypoint.ts b/src/api/entrypoint.ts index 8d7873c..f862a3c 100644 --- a/src/api/entrypoint.ts +++ b/src/api/entrypoint.ts @@ -1,20 +1,21 @@ -import joi from 'joi'; +import { z, ZodAny } from 'zod'; import { scopedLogger } from '@logger'; import { glob } from 'glob'; import { config } from '@config'; const log = scopedLogger('runner'); -const actionPayloadSchema = joi +const actionPayloadSchema = z .object({ - action: joi.string().required(), - data: joi.object(), + action: z.string(), + // partial check, first check if action payload structure is correct, specific checks later + data: z.any(), }) .strict(); interface Schema { action: string; - schema: joi.ObjectSchema; + schema: ZodAny; run: (data: any) => any; } @@ -36,8 +37,8 @@ export async function setupApi() { ** all data passed into this method is untrusted */ export async function callApiMethod(payload: any): Promise { - const isValidPayload = actionPayloadSchema.validate(payload); - if (isValidPayload.error) + const isValidPayload = actionPayloadSchema.safeParse(payload); + if (isValidPayload.success === false) return { success: false, error: 'input', @@ -53,8 +54,8 @@ export async function callApiMethod(payload: any): Promise { error: 'action', }; - const isValidPayloadContent = schema.schema.validate(actionData); - if (isValidPayloadContent.error) { + const isValidPayloadContent = schema.schema.safeParse(actionData); + if (isValidPayloadContent.success === false) { if (config.logging.allowScripts) log.warn('Failed validation', isValidPayloadContent.error); return { @@ -66,7 +67,7 @@ export async function callApiMethod(payload: any): Promise { try { // this is awaited regardless of promise or not - const data = await schema.run(isValidPayloadContent.value); + const data = await schema.run(isValidPayloadContent.data); return { success: true, data, diff --git a/src/api/schemas/messaging/reply.ts b/src/api/schemas/messaging/reply.ts index dbf8aa5..cd9ed9d 100644 --- a/src/api/schemas/messaging/reply.ts +++ b/src/api/schemas/messaging/reply.ts @@ -1,22 +1,16 @@ -import joi from 'joi'; +import { z } from 'zod'; import { idRegex } from '@utils/regex'; import { getShardCount, sendMessageGetReply } from '@managers/rabbitmq-manager'; export const action = 'reply'; -interface Reply { - message: string; - guildId: string; - interactionId: string; -} +export const schema = z.object({ + message: z.string(), + guildId: z.string().regex(idRegex), + interactionId: z.string(), +}); -export const schema = joi - .object({ - message: joi.string().required(), - guildId: joi.string().regex(idRegex).required(), - interactionId: joi.string().required(), - }) - .required(); +type Reply = z.infer; export const run = async (data: Reply) => { const count = await getShardCount(); diff --git a/src/api/schemas/messaging/replyEmbed.ts b/src/api/schemas/messaging/replyEmbed.ts index 5f4615c..21c523d 100644 --- a/src/api/schemas/messaging/replyEmbed.ts +++ b/src/api/schemas/messaging/replyEmbed.ts @@ -1,25 +1,19 @@ -import { convertToBotEmbed, Embed, EmbedSchema } from '@api/common/embed'; +import { convertToBotEmbed, EmbedSchema } from '@api/common/embed'; import { getShardCount, sendMessageGetReply } from '@managers/rabbitmq-manager'; -import joi from 'joi'; +import { z } from 'zod'; import { idRegex } from '@utils/regex'; export const action = 'replyEmbed'; -interface ReplyEmbed { - embed: Embed; - guildId: string; - interactionId: string; -} - -export const schema = joi - .object({ - embed: EmbedSchema.required(), - guildId: joi.string().regex(idRegex).required(), - interactionId: joi.string().required(), +export const schema = z + .object({ + embed: EmbedSchema, + guildId: z.string().regex(idRegex), + interactionId: z.string(), }) .required(); -//export const schema = EmbedSchema.required(); +type ReplyEmbed = z.infer; export const run = async (data: ReplyEmbed) => { const botEmbed = convertToBotEmbed(data.embed); diff --git a/src/api/schemas/ping.ts b/src/api/schemas/ping.ts index 0db535d..9d60e47 100644 --- a/src/api/schemas/ping.ts +++ b/src/api/schemas/ping.ts @@ -1,15 +1,11 @@ -import joi from 'joi'; +import { z } from 'zod'; export const action = 'ping'; -interface Input { - msg: string; -} - -export const schema = joi.object({ - msg: joi.string().default('pong!'), +export const schema = z.object({ + msg: z.string().default('pong!'), }); -export const run = async (_data: Input) => { +export const run = async (_data: z.infer) => { throw new Error('test'); }; diff --git a/src/api/schemas/readme.md b/src/api/schemas/readme.md index 185b695..2ecf96d 100644 --- a/src/api/schemas/readme.md +++ b/src/api/schemas/readme.md @@ -4,5 +4,5 @@ this directory contains all schemas for untrusted input, make sure its validated all files in this directory must follow this import structure: 1. `export const action: string` - action name to check - 2. `export const schema: joi.ObjectSchema` - schema to check the action against - 3. `export const run: (data: Input) => any)` - what it runs when the action is executed + 2. `export const schema: z.object({})` - schema to check the action against + 3. `export const run: (data: z.infer) => any)` - what it runs when the action is executed diff --git a/src/api/schemas/user/getUserById.ts b/src/api/schemas/user/getUserById.ts index b241b84..d43e23b 100644 --- a/src/api/schemas/user/getUserById.ts +++ b/src/api/schemas/user/getUserById.ts @@ -1,21 +1,16 @@ -import joi from 'joi'; +import { z } from 'zod'; import { idRegex } from '@utils/regex'; export const action = 'getUserById'; -interface GetUserById { - userId: string; - guildId: string; -} - -export const schema = joi - .object({ - userId: joi.string().regex(idRegex).required(), - guildId: joi.string().regex(idRegex).required(), +export const schema = z + .object({ + userId: z.string().regex(idRegex), + guildId: z.string().regex(idRegex), }) .required(); -export const run = (_data: GetUserById) => { +export const run = (_data: z.infer) => { // TODO rabbitmq return 'NO'; }; diff --git a/src/models/setup-context.ts b/src/models/setup-context.ts index b14e09a..1155671 100644 --- a/src/models/setup-context.ts +++ b/src/models/setup-context.ts @@ -3,11 +3,11 @@ import { scopedLogger } from '@logger'; import { getPrependScript } from '@sandboxed/prepare-scripts'; import { registerAsyncFunction, registerFunction } from '@utils/registerFunc'; import { Context } from 'isolated-vm'; -import joi from 'joi'; +import { z } from 'zod'; import { config } from '@config'; const log = scopedLogger('sandbox'); -const stringSchema = joi.string().required().strict(); +const stringSchema = z.string(); export async function createGlobalContext(ctx: Context) { const jail = ctx.global; @@ -16,7 +16,7 @@ export async function createGlobalContext(ctx: Context) { if (config.logging.allowScripts) { // simple console log for debugging purposes await registerFunction(ctx, 'log', (msg: any) => { - if (stringSchema.validate(msg).error) return false; + if (!stringSchema.safeParse(msg).success) return false; log.debug('SANDBOX: ' + msg); return true; }); From 08fb1b1ac238d18e9debd7621a2c9d7cae73203f Mon Sep 17 00:00:00 2001 From: weeryan17 Date: Mon, 4 Sep 2023 07:32:22 -0400 Subject: [PATCH 22/22] Fix zod validation for config and embeds --- src/api/common/embed.ts | 6 +++--- src/config/parts/rabbitMQ.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/api/common/embed.ts b/src/api/common/embed.ts index 081d5d4..95632a2 100644 --- a/src/api/common/embed.ts +++ b/src/api/common/embed.ts @@ -19,7 +19,7 @@ const embedFieldSchema = z.object({ inline: z.boolean(), }); -const embedAuthorschema = z.object({ +const embedAuthorSchema = z.object({ author: z.string().max(256), url: z.string().url().optional(), image: z.string().url().optional(), @@ -41,7 +41,7 @@ export const EmbedSchema = z title: embedTitleSchema, content: z.string().max(4096), fields: z.array(embedFieldSchema), - author: embedAuthorschema, + author: embedAuthorSchema, footer: embedFooterSchema, thumbnail: z.string().url(), image: z.string().url(), @@ -49,7 +49,7 @@ export const EmbedSchema = z }) .partial() .refine( - (value) => !value.content && !value.fields, + (value) => value.content || value.fields, 'Either content or fields are required', ) .refine((value) => { diff --git a/src/config/parts/rabbitMQ.ts b/src/config/parts/rabbitMQ.ts index 86025d2..7b3712a 100644 --- a/src/config/parts/rabbitMQ.ts +++ b/src/config/parts/rabbitMQ.ts @@ -2,13 +2,13 @@ import { z } from 'zod'; import { pathRegex } from '@utils/regex'; // TODO optional types? -export const rabbitMqConfSchema = z.discriminatedUnion('type', [ +export const rabbitMqConfSchema = z.union([ z.object({ - type: z.literal('connectionString'), + type: z.literal('connectionString').default('connectionString'), connectionString: z.string().url(), // TODO check scheme }), z.object({ - type: z.literal('individual'), + type: z.literal('individual').default('individual'), username: z.string(), password: z.string(), hostname: z.string(), // TODO hostname