From 0644783cc42064ea0568ceabd83778f8757d81cc Mon Sep 17 00:00:00 2001 From: wancat Date: Tue, 27 Feb 2024 12:27:54 +0800 Subject: [PATCH 01/19] feat: use project references to build dependencies efficiently --- app/tsconfig.json | 7 ++++++- package.json | 4 +--- packages/constants/tsconfig.json | 1 + packages/file-graph/tsconfig.json | 1 + packages/models/src/index.ts | 2 ++ packages/models/tsconfig.json | 1 + packages/utils/tsconfig.json | 1 + server/package.json | 4 ++-- server/tsconfig.json | 8 +++++++- tsconfig.json | 3 ++- 10 files changed, 24 insertions(+), 8 deletions(-) diff --git a/app/tsconfig.json b/app/tsconfig.json index b17c94a..dc7801a 100644 --- a/app/tsconfig.json +++ b/app/tsconfig.json @@ -22,5 +22,10 @@ "noFallthroughCasesInSwitch": true }, "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "src/**/*.js"], - "references": [{ "path": "./tsconfig.node.json" }] + "references": [ + { "path": "./tsconfig.node.json" }, + { "path": "../packages/utils" }, + { "path": "../packages/constants" }, + { "path": "../packages/file-graph" } + ] } diff --git a/package.json b/package.json index 04954b1..3888742 100644 --- a/package.json +++ b/package.json @@ -13,9 +13,7 @@ ], "scripts": { "app": "yarn workspace app dev", - "build:deps": "concurrently \"yarn workspace @linux-odyssey/constants build\" \"yarn workspace @linux-odyssey/file-graph build\" \"yarn workspace @linux-odyssey/models build\" \"yarn workspace @linux-odyssey/utils build\"", - "build:apps": "concurrently \"yarn workspace app build\" \"yarn workspace server build\" \"yarn workspace analytics build\"", - "build": "yarn build:deps && yarn build:apps", + "build": "yarn workspace server build && yarn workspace app build && yarn workspace analytics build", "dev": "concurrently -n \"App,Server\" -c \"bgBlue.bold,bgGreen.bold\" \"yarn workspace app dev\" \"yarn workspace server dev\"", "server": "yarn workspace server dev", "cli": "yarn workspace client start", diff --git a/packages/constants/tsconfig.json b/packages/constants/tsconfig.json index bd29af9..318a4cf 100644 --- a/packages/constants/tsconfig.json +++ b/packages/constants/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "../../tsconfig.json", "compilerOptions": { + "composite": true, "outDir": "./dist" }, "include": ["*.js", "*.ts"], diff --git a/packages/file-graph/tsconfig.json b/packages/file-graph/tsconfig.json index bf649ac..ccaf320 100644 --- a/packages/file-graph/tsconfig.json +++ b/packages/file-graph/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "rootDir": "src", + "composite": true, "outDir": "./dist" }, "include": ["src"], diff --git a/packages/models/src/index.ts b/packages/models/src/index.ts index efdfd11..59332a0 100644 --- a/packages/models/src/index.ts +++ b/packages/models/src/index.ts @@ -15,3 +15,5 @@ export default async function connectDB(uri: string) { const db = await mongoose.connect(uri) return db.connection.getClient() } + +console.log('Loaded models package') diff --git a/packages/models/tsconfig.json b/packages/models/tsconfig.json index bf649ac..ccaf320 100644 --- a/packages/models/tsconfig.json +++ b/packages/models/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "rootDir": "src", + "composite": true, "outDir": "./dist" }, "include": ["src"], diff --git a/packages/utils/tsconfig.json b/packages/utils/tsconfig.json index 8f50229..b1b8f57 100644 --- a/packages/utils/tsconfig.json +++ b/packages/utils/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "rootDir": "src", "outDir": "./dist", + "composite": true, "allowJs": false }, "include": ["src"], diff --git a/server/package.json b/server/package.json index c6383ad..02b10c7 100644 --- a/server/package.json +++ b/server/package.json @@ -7,8 +7,8 @@ "start": "node dist/index.js", "setup": "node dist/cli/setup.js", "clean": "node dist/cli/clean.js", - "build": "tsc", - "dev": "concurrently \"tsc -w\" \"sleep 5 && nodemon\"", + "build": "tsc -b", + "dev": "concurrently \"tsc -b --watch\" \"sleep 5 && nodemon\"", "build:quests": "node dist/cli/build.js" }, "dependencies": { diff --git a/server/tsconfig.json b/server/tsconfig.json index efc3d54..321fdda 100644 --- a/server/tsconfig.json +++ b/server/tsconfig.json @@ -4,5 +4,11 @@ "outDir": "./dist" }, "include": ["src"], - "exclude": ["node_modules", "src/*.test.js", "dist"] + "exclude": ["node_modules", "src/*.test.js", "dist"], + "references": [ + { "path": "../packages/constants" }, + { "path": "../packages/file-graph" }, + { "path": "../packages/models" }, + { "path": "../packages/utils" } + ] } diff --git a/tsconfig.json b/tsconfig.json index 2cd1c93..862aad0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,6 +8,7 @@ "strict": true, "skipLibCheck": true, "sourceMap": true, - "declaration": true + "declaration": true, + "declarationMap": true } } From 15278dfab25bf40dfb6f1e526f7acaa315d545e8 Mon Sep 17 00:00:00 2001 From: wancat Date: Tue, 27 Feb 2024 12:53:44 +0800 Subject: [PATCH 02/19] fix: docker --- app/Dockerfile | 4 +--- app/package.json | 1 + app/tsconfig.json | 1 - app/tsconfig.node.json | 10 ---------- server/Dockerfile | 4 ---- 5 files changed, 2 insertions(+), 18 deletions(-) delete mode 100644 app/tsconfig.node.json diff --git a/app/Dockerfile b/app/Dockerfile index 506854c..e5e4888 100644 --- a/app/Dockerfile +++ b/app/Dockerfile @@ -20,9 +20,7 @@ COPY packages/file-graph ./packages/file-graph COPY packages/utils ./packages/utils COPY packages/constants ./packages/constants COPY app ./app -RUN yarn workspace @linux-odyssey/file-graph build -RUN yarn workspace @linux-odyssey/utils build -RUN yarn workspace @linux-odyssey/constants build +RUN yarn workspace app build:refs RUN yarn workspace app build # Production stage diff --git a/app/package.json b/app/package.json index 0e605f5..920e658 100644 --- a/app/package.json +++ b/app/package.json @@ -7,6 +7,7 @@ "dev": "vite", "dev:docker": "API_TARGET=http://backend:3000 vite", "build": "vite build", + "build:refs": "tsc --build", "preview": "vite preview" }, "dependencies": { diff --git a/app/tsconfig.json b/app/tsconfig.json index dc7801a..9a196d6 100644 --- a/app/tsconfig.json +++ b/app/tsconfig.json @@ -23,7 +23,6 @@ }, "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "src/**/*.js"], "references": [ - { "path": "./tsconfig.node.json" }, { "path": "../packages/utils" }, { "path": "../packages/constants" }, { "path": "../packages/file-graph" } diff --git a/app/tsconfig.node.json b/app/tsconfig.node.json deleted file mode 100644 index 42872c5..0000000 --- a/app/tsconfig.node.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "compilerOptions": { - "composite": true, - "skipLibCheck": true, - "module": "ESNext", - "moduleResolution": "bundler", - "allowSyntheticDefaultImports": true - }, - "include": ["vite.config.ts"] -} diff --git a/server/Dockerfile b/server/Dockerfile index 70d5145..32361c6 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -26,10 +26,6 @@ COPY server ./server COPY quests ./quests ENV NODE_ENV=production -RUN yarn workspace @linux-odyssey/file-graph build -RUN yarn workspace @linux-odyssey/utils build -RUN yarn workspace @linux-odyssey/models build -RUN yarn workspace @linux-odyssey/constants build RUN yarn workspace server build WORKDIR /app/server CMD [ "yarn", "start" ] From 6c111a4475cf87a2b73753c85eeab043eafd56ba Mon Sep 17 00:00:00 2001 From: wancat Date: Wed, 28 Feb 2024 22:17:14 +0800 Subject: [PATCH 03/19] feat: use babel to replace ts-jest (improve performance) --- babel.config.js | 6 + jest.config.ts | 1 - package.json | 5 +- yarn.lock | 928 +++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 895 insertions(+), 45 deletions(-) create mode 100644 babel.config.js diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 0000000..befbdd1 --- /dev/null +++ b/babel.config.js @@ -0,0 +1,6 @@ +module.exports = { + presets: [ + ['@babel/preset-env', { targets: { node: 'current' } }], + '@babel/preset-typescript', + ], +} diff --git a/jest.config.ts b/jest.config.ts index 32104f4..65e41ea 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -6,7 +6,6 @@ import type { Config } from 'jest' const config: Config = { - preset: 'ts-jest/presets/default-esm', // All imported modules in your tests should be mocked automatically // automock: false, diff --git a/package.json b/package.json index 3888742..e1d0906 100644 --- a/package.json +++ b/package.json @@ -28,12 +28,16 @@ "build:quests": "yarn workspace server build:quests" }, "devDependencies": { + "@babel/core": "^7.24.0", + "@babel/preset-env": "^7.24.0", + "@babel/preset-typescript": "^7.23.3", "@jest/globals": "^29.7.0", "@types/jest": "^29.5.12", "@types/node": "^20.10.4", "@typescript-eslint/eslint-plugin": "^6.14.0", "@typescript-eslint/parser": "^6.14.0", "@vue/eslint-config-prettier": "^7.1.0", + "babel-jest": "^29.7.0", "concurrently": "^8.2.2", "eslint": "^8.44.0", "eslint-config-airbnb-base": "^15.0.0", @@ -46,7 +50,6 @@ "eslint-plugin-vue": "^9.15.1", "jest": "^29.7.0", "prettier": "^3.0.0", - "ts-jest": "^29.1.1", "ts-node": "^10.9.2", "typescript": "^5.3.3" } diff --git a/yarn.lock b/yarn.lock index 26908b8..01f5d1d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -28,7 +28,7 @@ "@babel/highlight" "^7.23.4" chalk "^2.4.2" -"@babel/compat-data@^7.23.5": +"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.23.5": version "7.23.5" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.5.tgz#ffb878728bb6bdcb6f4510aa51b1be9afb8cfd98" integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== @@ -54,6 +54,27 @@ json5 "^2.2.3" semver "^6.3.1" +"@babel/core@^7.24.0": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.0.tgz#56cbda6b185ae9d9bed369816a8f4423c5f2ff1b" + integrity sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.6" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helpers" "^7.24.0" + "@babel/parser" "^7.24.0" + "@babel/template" "^7.24.0" + "@babel/traverse" "^7.24.0" + "@babel/types" "^7.24.0" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + "@babel/generator@^7.23.6", "@babel/generator@^7.7.2": version "7.23.6" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.6.tgz#9e1fca4811c77a10580d17d26b57b036133f3c2e" @@ -64,7 +85,21 @@ "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" -"@babel/helper-compilation-targets@^7.23.6": +"@babel/helper-annotate-as-pure@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" + integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz#5426b109cf3ad47b91120f8328d8ab1be8b0b956" + integrity sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw== + dependencies: + "@babel/types" "^7.22.15" + +"@babel/helper-compilation-targets@^7.22.15", "@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.23.6": version "7.23.6" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz#4d79069b16cbcf1461289eccfbbd81501ae39991" integrity sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ== @@ -75,12 +110,47 @@ lru-cache "^5.1.1" semver "^6.3.1" +"@babel/helper-create-class-features-plugin@^7.22.15", "@babel/helper-create-class-features-plugin@^7.23.6": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.0.tgz#fc7554141bdbfa2d17f7b4b80153b9b090e5d158" + integrity sha512-QAH+vfvts51BCsNZ2PhY6HAggnlS6omLLFTsIpeqZk/MmJ6cW7tgz5yRv0fMJThcr6FmbMrENh1RgrWPTYA76g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-member-expression-to-functions" "^7.23.0" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.20" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + semver "^6.3.1" + +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.15", "@babel/helper-create-regexp-features-plugin@^7.22.5": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz#5ee90093914ea09639b01c711db0d6775e558be1" + integrity sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + regexpu-core "^5.3.1" + semver "^6.3.1" + +"@babel/helper-define-polyfill-provider@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz#465805b7361f461e86c680f1de21eaf88c25901b" + integrity sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q== + dependencies: + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-plugin-utils" "^7.22.5" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + "@babel/helper-environment-visitor@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== -"@babel/helper-function-name@^7.23.0": +"@babel/helper-function-name@^7.22.5", "@babel/helper-function-name@^7.23.0": version "7.23.0" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== @@ -95,6 +165,13 @@ dependencies: "@babel/types" "^7.22.5" +"@babel/helper-member-expression-to-functions@^7.22.15", "@babel/helper-member-expression-to-functions@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz#9263e88cc5e41d39ec18c9a3e0eced59a3e7d366" + integrity sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA== + dependencies: + "@babel/types" "^7.23.0" + "@babel/helper-module-imports@^7.22.15": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" @@ -113,11 +190,41 @@ "@babel/helper-split-export-declaration" "^7.22.6" "@babel/helper-validator-identifier" "^7.22.20" +"@babel/helper-optimise-call-expression@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz#f21531a9ccbff644fdd156b4077c16ff0c3f609e" + integrity sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== +"@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.24.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz#945681931a52f15ce879fd5b86ce2dae6d3d7f2a" + integrity sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w== + +"@babel/helper-remap-async-to-generator@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz#7b68e1cb4fa964d2996fd063723fb48eca8498e0" + integrity sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-wrap-function" "^7.22.20" + +"@babel/helper-replace-supers@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz#e37d367123ca98fe455a9887734ed2e16eb7a793" + integrity sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-member-expression-to-functions" "^7.22.15" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-simple-access@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" @@ -125,6 +232,13 @@ dependencies: "@babel/types" "^7.22.5" +"@babel/helper-skip-transparent-expression-wrappers@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz#007f15240b5751c537c40e77abb4e89eeaaa8847" + integrity sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-split-export-declaration@^7.22.6": version "7.22.6" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" @@ -142,11 +256,20 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== -"@babel/helper-validator-option@^7.23.5": +"@babel/helper-validator-option@^7.22.15", "@babel/helper-validator-option@^7.23.5": version "7.23.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== +"@babel/helper-wrap-function@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz#15352b0b9bfb10fc9c76f79f6342c00e3411a569" + integrity sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw== + dependencies: + "@babel/helper-function-name" "^7.22.5" + "@babel/template" "^7.22.15" + "@babel/types" "^7.22.19" + "@babel/helpers@^7.23.9": version "7.23.9" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.9.tgz#c3e20bbe7f7a7e10cb9b178384b4affdf5995c7d" @@ -156,6 +279,15 @@ "@babel/traverse" "^7.23.9" "@babel/types" "^7.23.9" +"@babel/helpers@^7.24.0": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.0.tgz#a3dd462b41769c95db8091e49cfe019389a9409b" + integrity sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA== + dependencies: + "@babel/template" "^7.24.0" + "@babel/traverse" "^7.24.0" + "@babel/types" "^7.24.0" + "@babel/highlight@^7.23.4": version "7.23.4" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" @@ -170,6 +302,40 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.9.tgz#7b903b6149b0f8fa7ad564af646c4c38a77fc44b" integrity sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA== +"@babel/parser@^7.24.0": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.0.tgz#26a3d1ff49031c53a97d03b604375f028746a9ac" + integrity sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg== + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz#5cd1c87ba9380d0afb78469292c954fee5d2411a" + integrity sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz#f6652bb16b94f8f9c20c50941e16e9756898dc5d" + integrity sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-transform-optional-chaining" "^7.23.3" + +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.23.7": + version "7.23.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz#516462a95d10a9618f197d39ad291a9b47ae1d7b" + integrity sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": + version "7.21.0-placeholder-for-preset-env.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" + integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== + "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" @@ -184,14 +350,49 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-class-properties@^7.8.3": +"@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-syntax-import-meta@^7.8.3": +"@babel/plugin-syntax-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" + integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-export-namespace-from@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" + integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-import-assertions@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz#9c05a7f592982aff1a2768260ad84bcd3f0c77fc" + integrity sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-import-attributes@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz#992aee922cf04512461d7dae3ff6951b90a2dc06" + integrity sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-import-meta@^7.10.4", "@babel/plugin-syntax-import-meta@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== @@ -205,14 +406,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.7.2": +"@babel/plugin-syntax-jsx@^7.23.3", "@babel/plugin-syntax-jsx@^7.7.2": version "7.23.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz#8f2e4f8a9b5f9aa16067e142c1ac9cd9f810f473" integrity sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg== dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== @@ -226,7 +427,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-numeric-separator@^7.8.3": +"@babel/plugin-syntax-numeric-separator@^7.10.4", "@babel/plugin-syntax-numeric-separator@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== @@ -254,20 +455,544 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-top-level-await@^7.8.3": +"@babel/plugin-syntax-private-property-in-object@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" + integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-top-level-await@^7.14.5", "@babel/plugin-syntax-top-level-await@^7.8.3": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.7.2": +"@babel/plugin-syntax-typescript@^7.23.3", "@babel/plugin-syntax-typescript@^7.7.2": version "7.23.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz#24f460c85dbbc983cd2b9c4994178bcc01df958f" integrity sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" +"@babel/plugin-syntax-unicode-sets-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" + integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-arrow-functions@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz#94c6dcfd731af90f27a79509f9ab7fb2120fc38b" + integrity sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-async-generator-functions@^7.23.9": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.9.tgz#9adaeb66fc9634a586c5df139c6240d41ed801ce" + integrity sha512-8Q3veQEDGe14dTYuwagbRtwxQDnytyg1JFu4/HwEMETeofocrB0U0ejBJIXoeG/t2oXZ8kzCyI0ZZfbT80VFNQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.20" + "@babel/plugin-syntax-async-generators" "^7.8.4" + +"@babel/plugin-transform-async-to-generator@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz#d1f513c7a8a506d43f47df2bf25f9254b0b051fa" + integrity sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw== + dependencies: + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.20" + +"@babel/plugin-transform-block-scoped-functions@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz#fe1177d715fb569663095e04f3598525d98e8c77" + integrity sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-block-scoping@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz#b2d38589531c6c80fbe25e6b58e763622d2d3cf5" + integrity sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-class-properties@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz#35c377db11ca92a785a718b6aa4e3ed1eb65dc48" + integrity sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-class-static-block@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz#2a202c8787a8964dd11dfcedf994d36bfc844ab5" + integrity sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + +"@babel/plugin-transform-classes@^7.23.8": + version "7.23.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz#d08ae096c240347badd68cdf1b6d1624a6435d92" + integrity sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.20" + "@babel/helper-split-export-declaration" "^7.22.6" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz#652e69561fcc9d2b50ba4f7ac7f60dcf65e86474" + integrity sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/template" "^7.22.15" + +"@babel/plugin-transform-destructuring@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz#8c9ee68228b12ae3dff986e56ed1ba4f3c446311" + integrity sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-dotall-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz#3f7af6054882ede89c378d0cf889b854a993da50" + integrity sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-duplicate-keys@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz#664706ca0a5dfe8d066537f99032fc1dc8b720ce" + integrity sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-dynamic-import@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz#c7629e7254011ac3630d47d7f34ddd40ca535143" + integrity sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + +"@babel/plugin-transform-exponentiation-operator@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz#ea0d978f6b9232ba4722f3dbecdd18f450babd18" + integrity sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-export-namespace-from@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz#084c7b25e9a5c8271e987a08cf85807b80283191" + integrity sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + +"@babel/plugin-transform-for-of@^7.23.6": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz#81c37e24171b37b370ba6aaffa7ac86bcb46f94e" + integrity sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + +"@babel/plugin-transform-function-name@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz#8f424fcd862bf84cb9a1a6b42bc2f47ed630f8dc" + integrity sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw== + dependencies: + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-json-strings@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz#a871d9b6bd171976efad2e43e694c961ffa3714d" + integrity sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-json-strings" "^7.8.3" + +"@babel/plugin-transform-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz#8214665f00506ead73de157eba233e7381f3beb4" + integrity sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-logical-assignment-operators@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz#e599f82c51d55fac725f62ce55d3a0886279ecb5" + integrity sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-transform-member-expression-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz#e37b3f0502289f477ac0e776b05a833d853cabcc" + integrity sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-modules-amd@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz#e19b55436a1416829df0a1afc495deedfae17f7d" + integrity sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw== + dependencies: + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-modules-commonjs@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz#661ae831b9577e52be57dd8356b734f9700b53b4" + integrity sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA== + dependencies: + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" + +"@babel/plugin-transform-modules-systemjs@^7.23.9": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.9.tgz#105d3ed46e4a21d257f83a2f9e2ee4203ceda6be" + integrity sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw== + dependencies: + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.20" + +"@babel/plugin-transform-modules-umd@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz#5d4395fccd071dfefe6585a4411aa7d6b7d769e9" + integrity sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg== + dependencies: + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz#67fe18ee8ce02d57c855185e27e3dc959b2e991f" + integrity sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-new-target@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz#5491bb78ed6ac87e990957cea367eab781c4d980" + integrity sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-nullish-coalescing-operator@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz#45556aad123fc6e52189ea749e33ce090637346e" + integrity sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-transform-numeric-separator@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz#03d08e3691e405804ecdd19dd278a40cca531f29" + integrity sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-transform-object-rest-spread@^7.24.0": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.0.tgz#7b836ad0088fdded2420ce96d4e1d3ed78b71df1" + integrity sha512-y/yKMm7buHpFFXfxVFS4Vk1ToRJDilIa6fKRioB9Vjichv58TDGXTvqV0dN7plobAmTW5eSEGXDngE+Mm+uO+w== + dependencies: + "@babel/compat-data" "^7.23.5" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.23.3" + +"@babel/plugin-transform-object-super@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz#81fdb636dcb306dd2e4e8fd80db5b2362ed2ebcd" + integrity sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.20" + +"@babel/plugin-transform-optional-catch-binding@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz#318066de6dacce7d92fa244ae475aa8d91778017" + integrity sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-transform-optional-chaining@^7.23.3", "@babel/plugin-transform-optional-chaining@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz#6acf61203bdfc4de9d4e52e64490aeb3e52bd017" + integrity sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-transform-parameters@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz#83ef5d1baf4b1072fa6e54b2b0999a7b2527e2af" + integrity sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-private-methods@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz#b2d7a3c97e278bfe59137a978d53b2c2e038c0e4" + integrity sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-private-property-in-object@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz#3ec711d05d6608fd173d9b8de39872d8dbf68bf5" + integrity sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + +"@babel/plugin-transform-property-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz#54518f14ac4755d22b92162e4a852d308a560875" + integrity sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-regenerator@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz#141afd4a2057298602069fce7f2dc5173e6c561c" + integrity sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + regenerator-transform "^0.15.2" + +"@babel/plugin-transform-reserved-words@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz#4130dcee12bd3dd5705c587947eb715da12efac8" + integrity sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-shorthand-properties@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz#97d82a39b0e0c24f8a981568a8ed851745f59210" + integrity sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-spread@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz#41d17aacb12bde55168403c6f2d6bdca563d362c" + integrity sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + +"@babel/plugin-transform-sticky-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz#dec45588ab4a723cb579c609b294a3d1bd22ff04" + integrity sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-template-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz#5f0f028eb14e50b5d0f76be57f90045757539d07" + integrity sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-typeof-symbol@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz#9dfab97acc87495c0c449014eb9c547d8966bca4" + integrity sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-typescript@^7.23.3": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.6.tgz#aa36a94e5da8d94339ae3a4e22d40ed287feb34c" + integrity sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.23.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-typescript" "^7.23.3" + +"@babel/plugin-transform-unicode-escapes@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz#1f66d16cab01fab98d784867d24f70c1ca65b925" + integrity sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-property-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz#19e234129e5ffa7205010feec0d94c251083d7ad" + integrity sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz#26897708d8f42654ca4ce1b73e96140fbad879dc" + integrity sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-sets-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz#4fb6f0a719c2c5859d11f6b55a050cc987f3799e" + integrity sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/preset-env@^7.24.0": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.24.0.tgz#11536a7f4b977294f0bdfad780f01a8ac8e183fc" + integrity sha512-ZxPEzV9IgvGn73iK0E6VB9/95Nd7aMFpbE0l8KQFDG70cOV9IxRP7Y2FUPmlK0v6ImlLqYX50iuZ3ZTVhOF2lA== + dependencies: + "@babel/compat-data" "^7.23.5" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-validator-option" "^7.23.5" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.23.3" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.23.3" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.23.7" + "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-import-assertions" "^7.23.3" + "@babel/plugin-syntax-import-attributes" "^7.23.3" + "@babel/plugin-syntax-import-meta" "^7.10.4" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" + "@babel/plugin-transform-arrow-functions" "^7.23.3" + "@babel/plugin-transform-async-generator-functions" "^7.23.9" + "@babel/plugin-transform-async-to-generator" "^7.23.3" + "@babel/plugin-transform-block-scoped-functions" "^7.23.3" + "@babel/plugin-transform-block-scoping" "^7.23.4" + "@babel/plugin-transform-class-properties" "^7.23.3" + "@babel/plugin-transform-class-static-block" "^7.23.4" + "@babel/plugin-transform-classes" "^7.23.8" + "@babel/plugin-transform-computed-properties" "^7.23.3" + "@babel/plugin-transform-destructuring" "^7.23.3" + "@babel/plugin-transform-dotall-regex" "^7.23.3" + "@babel/plugin-transform-duplicate-keys" "^7.23.3" + "@babel/plugin-transform-dynamic-import" "^7.23.4" + "@babel/plugin-transform-exponentiation-operator" "^7.23.3" + "@babel/plugin-transform-export-namespace-from" "^7.23.4" + "@babel/plugin-transform-for-of" "^7.23.6" + "@babel/plugin-transform-function-name" "^7.23.3" + "@babel/plugin-transform-json-strings" "^7.23.4" + "@babel/plugin-transform-literals" "^7.23.3" + "@babel/plugin-transform-logical-assignment-operators" "^7.23.4" + "@babel/plugin-transform-member-expression-literals" "^7.23.3" + "@babel/plugin-transform-modules-amd" "^7.23.3" + "@babel/plugin-transform-modules-commonjs" "^7.23.3" + "@babel/plugin-transform-modules-systemjs" "^7.23.9" + "@babel/plugin-transform-modules-umd" "^7.23.3" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.22.5" + "@babel/plugin-transform-new-target" "^7.23.3" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.23.4" + "@babel/plugin-transform-numeric-separator" "^7.23.4" + "@babel/plugin-transform-object-rest-spread" "^7.24.0" + "@babel/plugin-transform-object-super" "^7.23.3" + "@babel/plugin-transform-optional-catch-binding" "^7.23.4" + "@babel/plugin-transform-optional-chaining" "^7.23.4" + "@babel/plugin-transform-parameters" "^7.23.3" + "@babel/plugin-transform-private-methods" "^7.23.3" + "@babel/plugin-transform-private-property-in-object" "^7.23.4" + "@babel/plugin-transform-property-literals" "^7.23.3" + "@babel/plugin-transform-regenerator" "^7.23.3" + "@babel/plugin-transform-reserved-words" "^7.23.3" + "@babel/plugin-transform-shorthand-properties" "^7.23.3" + "@babel/plugin-transform-spread" "^7.23.3" + "@babel/plugin-transform-sticky-regex" "^7.23.3" + "@babel/plugin-transform-template-literals" "^7.23.3" + "@babel/plugin-transform-typeof-symbol" "^7.23.3" + "@babel/plugin-transform-unicode-escapes" "^7.23.3" + "@babel/plugin-transform-unicode-property-regex" "^7.23.3" + "@babel/plugin-transform-unicode-regex" "^7.23.3" + "@babel/plugin-transform-unicode-sets-regex" "^7.23.3" + "@babel/preset-modules" "0.1.6-no-external-plugins" + babel-plugin-polyfill-corejs2 "^0.4.8" + babel-plugin-polyfill-corejs3 "^0.9.0" + babel-plugin-polyfill-regenerator "^0.5.5" + core-js-compat "^3.31.0" + semver "^6.3.1" + +"@babel/preset-modules@0.1.6-no-external-plugins": + version "0.1.6-no-external-plugins" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz#ccb88a2c49c817236861fee7826080573b8a923a" + integrity sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/preset-typescript@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz#14534b34ed5b6d435aa05f1ae1c5e7adcc01d913" + integrity sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.15" + "@babel/plugin-syntax-jsx" "^7.23.3" + "@babel/plugin-transform-modules-commonjs" "^7.23.3" + "@babel/plugin-transform-typescript" "^7.23.3" + +"@babel/regjsgen@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" + integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== + "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.6", "@babel/runtime@^7.21.0": version "7.23.9" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.9.tgz#47791a15e4603bb5f905bc0753801cf21d6345f7" @@ -275,6 +1000,13 @@ dependencies: regenerator-runtime "^0.14.0" +"@babel/runtime@^7.8.4": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.0.tgz#584c450063ffda59697021430cb47101b085951e" + integrity sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/template@^7.22.15", "@babel/template@^7.23.9", "@babel/template@^7.3.3": version "7.23.9" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.23.9.tgz#f881d0487cba2828d3259dcb9ef5005a9731011a" @@ -284,6 +1016,15 @@ "@babel/parser" "^7.23.9" "@babel/types" "^7.23.9" +"@babel/template@^7.24.0": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.0.tgz#c6a524aa93a4a05d66aaf31654258fae69d87d50" + integrity sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA== + dependencies: + "@babel/code-frame" "^7.23.5" + "@babel/parser" "^7.24.0" + "@babel/types" "^7.24.0" + "@babel/traverse@^7.23.9": version "7.23.9" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.9.tgz#2f9d6aead6b564669394c5ce0f9302bb65b9d950" @@ -300,6 +1041,22 @@ debug "^4.3.1" globals "^11.1.0" +"@babel/traverse@^7.24.0": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.0.tgz#4a408fbf364ff73135c714a2ab46a5eab2831b1e" + integrity sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw== + dependencies: + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.6" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.24.0" + "@babel/types" "^7.24.0" + debug "^4.3.1" + globals "^11.1.0" + "@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.6", "@babel/types@^7.23.9", "@babel/types@^7.3.3": version "7.23.9" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.9.tgz#1dd7b59a9a2b5c87f8b41e52770b5ecbf492e002" @@ -309,6 +1066,15 @@ "@babel/helper-validator-identifier" "^7.22.20" to-fast-properties "^2.0.0" +"@babel/types@^7.22.19", "@babel/types@^7.24.0", "@babel/types@^7.4.4": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.0.tgz#3b951f435a92e7333eba05b7566fd297960ea1bf" + integrity sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w== + dependencies: + "@babel/helper-string-parser" "^7.23.4" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + "@balena/dockerignore@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@balena/dockerignore/-/dockerignore-1.0.2.tgz#9ffe4726915251e8eb69f44ef3547e0da2c03e0d" @@ -1926,6 +2692,30 @@ babel-plugin-jest-hoist@^29.6.3: "@types/babel__core" "^7.1.14" "@types/babel__traverse" "^7.0.6" +babel-plugin-polyfill-corejs2@^0.4.8: + version "0.4.8" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.8.tgz#dbcc3c8ca758a290d47c3c6a490d59429b0d2269" + integrity sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg== + dependencies: + "@babel/compat-data" "^7.22.6" + "@babel/helper-define-polyfill-provider" "^0.5.0" + semver "^6.3.1" + +babel-plugin-polyfill-corejs3@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.9.0.tgz#9eea32349d94556c2ad3ab9b82ebb27d4bf04a81" + integrity sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.5.0" + core-js-compat "^3.34.0" + +babel-plugin-polyfill-regenerator@^0.5.5: + version "0.5.5" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.5.tgz#8b0c8fc6434239e5d7b8a9d1f832bb2b0310f06a" + integrity sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.5.0" + babel-preset-current-node-syntax@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" @@ -2068,7 +2858,7 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.22.2: +browserslist@^4.22.2, browserslist@^4.22.3: version "4.23.0" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.0.tgz#8f3acc2bbe73af7213399430890f86c63a5674ab" integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== @@ -2078,13 +2868,6 @@ browserslist@^4.22.2: node-releases "^2.0.14" update-browserslist-db "^1.0.13" -bs-logger@0.x: - version "0.2.6" - resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" - integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== - dependencies: - fast-json-stable-stringify "2.x" - bser@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" @@ -2469,6 +3252,13 @@ cookie@~0.4.1: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== +core-js-compat@^3.31.0, core-js-compat@^3.34.0: + version "3.36.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.36.0.tgz#087679119bc2fdbdefad0d45d8e5d307d45ba190" + integrity sha512-iV9Pd/PsgjNWBXeq8XRtWVSgz2tKAfhfvBs7qxYty+RlRd+OCksaWmOnc4JKrTc1cToXL1N0s3l/vwlxPtdElw== + dependencies: + browserslist "^4.22.3" + core-util-is@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -3500,7 +4290,7 @@ fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.1: merge2 "^1.3.0" micromatch "^4.0.4" -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: +fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -4665,7 +5455,7 @@ jest-snapshot@^29.7.0: pretty-format "^29.7.0" semver "^7.5.3" -jest-util@^29.0.0, jest-util@^29.7.0: +jest-util@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== @@ -4758,6 +5548,11 @@ jsesc@^2.5.1: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== + json-buffer@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" @@ -4947,6 +5742,11 @@ lodash-es@^4.17.21: resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== + lodash.includes@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" @@ -4977,11 +5777,6 @@ lodash.isstring@^4.0.1: resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== -lodash.memoize@4.x: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== - lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" @@ -5094,7 +5889,7 @@ make-dir@^4.0.0: dependencies: semver "^7.5.3" -make-error@1.x, make-error@^1.1.1: +make-error@^1.1.1: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== @@ -5995,11 +6790,30 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" +regenerate-unicode-properties@^10.1.0: + version "10.1.1" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz#6b0e05489d9076b04c436f318d9b067bba459480" + integrity sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q== + dependencies: + regenerate "^1.4.2" + +regenerate@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + regenerator-runtime@^0.14.0: version "0.14.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== +regenerator-transform@^0.15.2: + version "0.15.2" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4" + integrity sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg== + dependencies: + "@babel/runtime" "^7.8.4" + regexp.prototype.flags@^1.5.1, regexp.prototype.flags@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz#138f644a3350f981a858c44f6bb1a61ff59be334" @@ -6015,6 +6829,25 @@ regexpp@^3.0.0: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== +regexpu-core@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.3.2.tgz#11a2b06884f3527aec3e93dbbf4a3b958a95546b" + integrity sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ== + dependencies: + "@babel/regjsgen" "^0.8.0" + regenerate "^1.4.2" + regenerate-unicode-properties "^10.1.0" + regjsparser "^0.9.1" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.1.0" + +regjsparser@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709" + integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== + dependencies: + jsesc "~0.5.0" + request-progress@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-3.0.0.tgz#4ca754081c7fec63f505e4faa825aa06cd669dbe" @@ -6059,7 +6892,7 @@ resolve.exports@^2.0.0: resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== -resolve@^1.1.7, resolve@^1.10.1, resolve@^1.20.0, resolve@^1.22.2, resolve@^1.22.4: +resolve@^1.1.7, resolve@^1.10.1, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.2, resolve@^1.22.4: version "1.22.8" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== @@ -6792,20 +7625,6 @@ ts-interface-checker@^0.1.9: resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== -ts-jest@^29.1.1: - version "29.1.2" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.2.tgz#7613d8c81c43c8cb312c6904027257e814c40e09" - integrity sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g== - dependencies: - bs-logger "0.x" - fast-json-stable-stringify "2.x" - jest-util "^29.0.0" - json5 "^2.2.3" - lodash.memoize "4.x" - make-error "1.x" - semver "^7.5.3" - yargs-parser "^21.0.1" - ts-node@^10.9.2: version "10.9.2" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" @@ -6978,6 +7797,29 @@ undici-types@~5.26.4: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== +unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" + integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== + +unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" + integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== + dependencies: + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" + +unicode-match-property-value-ecmascript@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz#cb5fffdcd16a05124f5a4b0bf7c3770208acbbe0" + integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== + +unicode-property-aliases-ecmascript@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" + integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== + universalify@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" @@ -7341,7 +8183,7 @@ yaml@^2.3.1, yaml@^2.3.4: resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.4.tgz#53fc1d514be80aabf386dc6001eb29bf3b7523b2" integrity sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA== -yargs-parser@^21.0.1, yargs-parser@^21.1.1: +yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== From 6967e230d0caf3e8811569fc48bbab99e69d7057 Mon Sep 17 00:00:00 2001 From: wancat Date: Thu, 29 Feb 2024 00:33:41 +0800 Subject: [PATCH 04/19] feat: enable swc and ts-node in server dev --- server/nodemon.json | 5 +-- server/package.json | 6 ++- server/tsconfig.json | 5 ++- yarn.lock | 90 +++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 99 insertions(+), 7 deletions(-) diff --git a/server/nodemon.json b/server/nodemon.json index c61d2d2..0fdaf66 100644 --- a/server/nodemon.json +++ b/server/nodemon.json @@ -1,6 +1,5 @@ { - "watch": ["dist", "swagger.yaml", "../quests", "../packages"], + "watch": ["src", "swagger.yaml", "../quests", "../packages"], "ext": "js,ts,yaml,yml", - "exec": "node -r source-map-support/register dist/index.js", - "delay": 200 + "exec": "node --loader ts-node/esm src/index.js" } diff --git a/server/package.json b/server/package.json index 02b10c7..884d244 100644 --- a/server/package.json +++ b/server/package.json @@ -8,7 +8,7 @@ "setup": "node dist/cli/setup.js", "clean": "node dist/cli/clean.js", "build": "tsc -b", - "dev": "concurrently \"tsc -b --watch\" \"sleep 5 && nodemon\"", + "dev": "nodemon", "build:quests": "node dist/cli/build.js" }, "dependencies": { @@ -44,6 +44,8 @@ "yaml": "^2.3.1" }, "devDependencies": { + "@swc/core": "^1.4.2", + "@swc/helpers": "^0.5.6", "@types/bcrypt": "^5.0.2", "@types/dockerode": "^3.3.23", "@types/express": "^4.17.21", @@ -62,7 +64,9 @@ "concurrently": "^8.2.2", "jest": "^29.6.1", "nodemon": "^3.0.1", + "regenerator-runtime": "^0.14.1", "source-map-support": "^0.5.21", + "ts-node": "^10.9.2", "typescript": "^5.3.3" } } diff --git a/server/tsconfig.json b/server/tsconfig.json index 321fdda..6868620 100644 --- a/server/tsconfig.json +++ b/server/tsconfig.json @@ -10,5 +10,8 @@ { "path": "../packages/file-graph" }, { "path": "../packages/models" }, { "path": "../packages/utils" } - ] + ], + "ts-node": { + "swc": true + } } diff --git a/yarn.lock b/yarn.lock index 01f5d1d..e4ed895 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1679,6 +1679,92 @@ resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553" integrity sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg== +"@swc/core-darwin-arm64@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.4.2.tgz#3b5677c5b9c5a7a91d953b96cd603c94064e2835" + integrity sha512-1uSdAn1MRK5C1m/TvLZ2RDvr0zLvochgrZ2xL+lRzugLlCTlSA+Q4TWtrZaOz+vnnFVliCpw7c7qu0JouhgQIw== + +"@swc/core-darwin-x64@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.4.2.tgz#bbc8bbf420389b12541151255a50f319cc17ef96" + integrity sha512-TYD28+dCQKeuxxcy7gLJUCFLqrwDZnHtC2z7cdeGfZpbI2mbfppfTf2wUPzqZk3gEC96zHd4Yr37V3Tvzar+lQ== + +"@swc/core-linux-arm-gnueabihf@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.4.2.tgz#aa9a18f130820717df08c9dd882043fc47e8d35a" + integrity sha512-Eyqipf7ZPGj0vplKHo8JUOoU1un2sg5PjJMpEesX0k+6HKE2T8pdyeyXODN0YTFqzndSa/J43EEPXm+rHAsLFQ== + +"@swc/core-linux-arm64-gnu@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.4.2.tgz#5ef1de0ca7cc3a034aa3a1c3c1794b78e6ca207e" + integrity sha512-wZn02DH8VYPv3FC0ub4my52Rttsus/rFw+UUfzdb3tHMHXB66LqN+rR0ssIOZrH6K+VLN6qpTw9VizjyoH0BxA== + +"@swc/core-linux-arm64-musl@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.4.2.tgz#5dfd2a8c0483770a307de0ccb6019a082ff0d902" + integrity sha512-3G0D5z9hUj9bXNcwmA1eGiFTwe5rWkuL3DsoviTj73TKLpk7u64ND0XjEfO0huVv4vVu9H1jodrKb7nvln/dlw== + +"@swc/core-linux-x64-gnu@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.4.2.tgz#314aa76b7c1208e315e3156ab57b7188fb605bc2" + integrity sha512-LFxn9U8cjmYHw3jrdPNqPAkBGglKE3tCZ8rA7hYyp0BFxuo7L2ZcEnPm4RFpmSCCsExFH+LEJWuMGgWERoktvg== + +"@swc/core-linux-x64-musl@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.4.2.tgz#b2b226657f6a8d48f561cb3dbe2d414cfbafe467" + integrity sha512-dp0fAmreeVVYTUcb4u9njTPrYzKnbIH0EhH2qvC9GOYNNREUu2GezSIDgonjOXkHiTCvopG4xU7y56XtXj4VrQ== + +"@swc/core-win32-arm64-msvc@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.4.2.tgz#582f79fa328ce0f426ab8313b3d881e7315fab2f" + integrity sha512-HlVIiLMQkzthAdqMslQhDkoXJ5+AOLUSTV6fm6shFKZKqc/9cJvr4S8UveNERL9zUficA36yM3bbfo36McwnvQ== + +"@swc/core-win32-ia32-msvc@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.4.2.tgz#15c8289e1c18857f79b9b888100ab1f871bf58f6" + integrity sha512-WCF8faPGjCl4oIgugkp+kL9nl3nUATlzKXCEGFowMEmVVCFM0GsqlmGdPp1pjZoWc9tpYanoXQDnp5IvlDSLhA== + +"@swc/core-win32-x64-msvc@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.4.2.tgz#c999ca7b68124d058b40a1431cdd6f56779670d5" + integrity sha512-oV71rwiSpA5xre2C5570BhCsg1HF97SNLsZ/12xv7zayGzqr3yvFALFJN8tHKpqUdCB4FGPjoP3JFdV3i+1wUw== + +"@swc/core@^1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.4.2.tgz#310b0d5e93e47ca72f54150c8f9efcb434c39b17" + integrity sha512-vWgY07R/eqj1/a0vsRKLI9o9klGZfpLNOVEnrv4nrccxBgYPjcf22IWwAoaBJ+wpA7Q4fVjCUM8lP0m01dpxcg== + dependencies: + "@swc/counter" "^0.1.2" + "@swc/types" "^0.1.5" + optionalDependencies: + "@swc/core-darwin-arm64" "1.4.2" + "@swc/core-darwin-x64" "1.4.2" + "@swc/core-linux-arm-gnueabihf" "1.4.2" + "@swc/core-linux-arm64-gnu" "1.4.2" + "@swc/core-linux-arm64-musl" "1.4.2" + "@swc/core-linux-x64-gnu" "1.4.2" + "@swc/core-linux-x64-musl" "1.4.2" + "@swc/core-win32-arm64-msvc" "1.4.2" + "@swc/core-win32-ia32-msvc" "1.4.2" + "@swc/core-win32-x64-msvc" "1.4.2" + +"@swc/counter@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@swc/counter/-/counter-0.1.3.tgz#cc7463bd02949611c6329596fccd2b0ec782b0e9" + integrity sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ== + +"@swc/helpers@^0.5.6": + version "0.5.6" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.6.tgz#d16d8566b7aea2bef90d059757e2d77f48224160" + integrity sha512-aYX01Ke9hunpoCexYAgQucEpARGQ5w/cqHFrIR+e9gdKb1QWTsVJuTJ2ozQzIAxLyRQe/m+2RqzkyOOGiMKRQA== + dependencies: + tslib "^2.4.0" + +"@swc/types@^0.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@swc/types/-/types-0.1.5.tgz#043b731d4f56a79b4897a3de1af35e75d56bc63a" + integrity sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw== + "@testing-library/cypress@^10.0.1": version "10.0.1" resolved "https://registry.yarnpkg.com/@testing-library/cypress/-/cypress-10.0.1.tgz#15abae0edb83237316ec6d07e152b71a50b38387" @@ -6802,7 +6888,7 @@ regenerate@^1.4.2: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== -regenerator-runtime@^0.14.0: +regenerator-runtime@^0.14.0, regenerator-runtime@^0.14.1: version "0.14.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== @@ -7659,7 +7745,7 @@ tslib@2.3.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e" integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== -tslib@^2.1.0, tslib@^2.6.2: +tslib@^2.1.0, tslib@^2.4.0, tslib@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== From 3b4a808131d806a07ba02c203443184d02b37a0a Mon Sep 17 00:00:00 2001 From: wancat Date: Wed, 6 Mar 2024 23:06:52 +0800 Subject: [PATCH 05/19] feat: create pattern and command matcher --- .eslintrc.js | 2 ++ packages/game/src/command.ts | 6 ++++ packages/game/src/condition.ts | 36 +++++++++++++++++++++++ packages/game/src/matcher.ts | 5 ++++ packages/game/test/condition.test.ts | 43 ++++++++++++++++++++++++++++ 5 files changed, 92 insertions(+) create mode 100644 packages/game/src/command.ts create mode 100644 packages/game/src/condition.ts create mode 100644 packages/game/src/matcher.ts create mode 100644 packages/game/test/condition.test.ts diff --git a/.eslintrc.js b/.eslintrc.js index d177747..b323dbd 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -60,6 +60,8 @@ module.exports = { tsx: 'never', }, ], + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': 'error', }, overrides: [ { diff --git a/packages/game/src/command.ts b/packages/game/src/command.ts new file mode 100644 index 0000000..6faf783 --- /dev/null +++ b/packages/game/src/command.ts @@ -0,0 +1,6 @@ +export interface Command { + command: string + output: string + error: string + pwd: string +} diff --git a/packages/game/src/condition.ts b/packages/game/src/condition.ts new file mode 100644 index 0000000..7a050b2 --- /dev/null +++ b/packages/game/src/condition.ts @@ -0,0 +1,36 @@ +/* eslint-disable max-classes-per-file */ +import { Command } from './command' +import { Matcher } from './matcher' + +export class PatternMatcher { + protected matcher: RegExp | null + constructor(pattern?: string, args?: string) { + this.matcher = pattern ? new RegExp(pattern, args) : null + } + + test(input: string): boolean { + if (!this.matcher) { + return true + } + return this.matcher.test(input) + } +} + +export class CommandMatcher extends PatternMatcher implements Matcher { + match(command: Partial): boolean { + return !!command.command && this.test(command.command) + } +} + +export class ErrorMatcher extends PatternMatcher implements Matcher { + match(command: Partial): boolean { + if (!this.matcher) { + return command.error === '' + } + return !!command.error && this.test(command.error) + } +} + +export class Condition { + private matchers: Matcher[] = [] +} diff --git a/packages/game/src/matcher.ts b/packages/game/src/matcher.ts new file mode 100644 index 0000000..b1de51d --- /dev/null +++ b/packages/game/src/matcher.ts @@ -0,0 +1,5 @@ +import { Command } from './command' + +export interface Matcher { + match(command: Partial): boolean +} diff --git a/packages/game/test/condition.test.ts b/packages/game/test/condition.test.ts new file mode 100644 index 0000000..e6a9f6c --- /dev/null +++ b/packages/game/test/condition.test.ts @@ -0,0 +1,43 @@ +import { test, expect } from '@jest/globals' +import { PatternMatcher, CommandMatcher, ErrorMatcher } from '../src/condition' +import { Command } from '../src/command' + +test('pattern match', () => { + const matcher = new PatternMatcher('^echo start$') + + expect(matcher.test('echo start')).toBe(true) + expect(matcher.test('echo start ')).toBe(false) +}) + +test('pattern match with flag', () => { + const matcher = new PatternMatcher('^echo start$', 'i') + + expect(matcher.test('echo start')).toBe(true) + expect(matcher.test('echo Start')).toBe(true) + expect(matcher.test('echo Start ')).toBe(false) +}) + +test('empty pattern return true', () => { + const matcher = new PatternMatcher('') + expect(matcher.test('echo start')).toBe(true) +}) + +test('empty error return false', () => { + const matcher = new ErrorMatcher() + expect(matcher.match({ error: '' })).toBe(true) + expect(matcher.match({ error: 'permission denied' })).toBe(false) +}) + +test('command match', () => { + const command: Command = { + command: 'echo start', + output: 'start', + error: '', + pwd: '/home/user', + } + + const matcher = new CommandMatcher('^echo start$', 'i') + expect(matcher.match(command)).toBe(true) +}) + +test('condition match', () => {}) From 9eb08b45f4b4e3ff5dcfb4feaad8ab1be7498f00 Mon Sep 17 00:00:00 2001 From: wancat Date: Wed, 6 Mar 2024 23:28:28 +0800 Subject: [PATCH 06/19] feat: add pwdmatcher and update error matcher --- .eslintrc.js | 2 + packages/game/src/condition.ts | 37 ++++++++++++++---- packages/game/test/condition.test.ts | 57 ++++++++++++++++++++++++---- 3 files changed, 81 insertions(+), 15 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index b323dbd..c8110a1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -62,6 +62,8 @@ module.exports = { ], 'no-unused-vars': 'off', '@typescript-eslint/no-unused-vars': 'error', + 'no-useless-constructor': 'off', + '@typescript-eslint/no-useless-constructor': 'error', }, overrides: [ { diff --git a/packages/game/src/condition.ts b/packages/game/src/condition.ts index 7a050b2..b3d65f0 100644 --- a/packages/game/src/condition.ts +++ b/packages/game/src/condition.ts @@ -3,15 +3,12 @@ import { Command } from './command' import { Matcher } from './matcher' export class PatternMatcher { - protected matcher: RegExp | null - constructor(pattern?: string, args?: string) { - this.matcher = pattern ? new RegExp(pattern, args) : null + protected matcher: RegExp + constructor(pattern: string, args?: string) { + this.matcher = new RegExp(pattern, args) } test(input: string): boolean { - if (!this.matcher) { - return true - } return this.matcher.test(input) } } @@ -23,14 +20,40 @@ export class CommandMatcher extends PatternMatcher implements Matcher { } export class ErrorMatcher extends PatternMatcher implements Matcher { + constructor(private errorPattern?: string) { + super(errorPattern || '') + } + match(command: Partial): boolean { - if (!this.matcher) { + if (!this.errorPattern) { return command.error === '' } return !!command.error && this.test(command.error) } } +export class PwdMatcher implements Matcher { + constructor(private pwd: string) {} + + match(command: Partial): boolean { + return command.pwd === this.pwd + } +} + +export interface ICondition { + command?: string + output?: string + error?: string + pwd?: string +} + export class Condition { private matchers: Matcher[] = [] + + constructor({ command, output, error, pwd }: ICondition) { + if (command) this.matchers.push(new CommandMatcher(command)) + // if (output) this.matchers.push(new OutputMatcher(output)) + if (pwd) this.matchers.push(new PwdMatcher(pwd)) + this.matchers.push(new ErrorMatcher(error)) // always check unexpected error + } } diff --git a/packages/game/test/condition.test.ts b/packages/game/test/condition.test.ts index e6a9f6c..e513de6 100644 --- a/packages/game/test/condition.test.ts +++ b/packages/game/test/condition.test.ts @@ -1,5 +1,11 @@ import { test, expect } from '@jest/globals' -import { PatternMatcher, CommandMatcher, ErrorMatcher } from '../src/condition' +import { + PatternMatcher, + CommandMatcher, + ErrorMatcher, + PwdMatcher, + Condition, +} from '../src/condition' import { Command } from '../src/command' test('pattern match', () => { @@ -22,12 +28,6 @@ test('empty pattern return true', () => { expect(matcher.test('echo start')).toBe(true) }) -test('empty error return false', () => { - const matcher = new ErrorMatcher() - expect(matcher.match({ error: '' })).toBe(true) - expect(matcher.match({ error: 'permission denied' })).toBe(false) -}) - test('command match', () => { const command: Command = { command: 'echo start', @@ -40,4 +40,45 @@ test('command match', () => { expect(matcher.match(command)).toBe(true) }) -test('condition match', () => {}) +test('error matcher', () => { + const matcher = new ErrorMatcher() + expect(matcher.match({ error: '' })).toBe(true) + expect(matcher.match({ error: 'permission denied' })).toBe(false) +}) + +test('error matcher with specific error', () => { + const matcher = new ErrorMatcher('permission denied') + expect(matcher.match({ error: '' })).toBe(false) + expect(matcher.match({ error: 'file not found' })).toBe(false) + expect(matcher.match({ error: 'cannot open files: permission denied' })).toBe( + true + ) +}) + +test('pwd matcher', () => { + const matcher = new PwdMatcher('/home/user') + expect(matcher.match({ pwd: '/home/user' })).toBe(true) + expect(matcher.match({ pwd: '/home/user1' })).toBe(false) + expect(matcher.match({ pwd: '/home/user/anotherpath' })).toBe(false) + expect(matcher.match({ pwd: '/var/home/user' })).toBe(false) +}) + +// test('condition match', () => { +// const condition = new Condition({ +// command: '^echo start$', +// pwd: '/home/user', +// }) + +// expect( +// condition.match({ +// command: 'echo start', +// pwd: '/home/user', +// }) +// ).toBe(true) +// expect( +// condition.match({ +// command: 'echo start', +// pwd: '/home/user1', +// }) +// ).toBe(false) +// }) From cb26e1dcb0cc250e165faefa2461ab77489009fa Mon Sep 17 00:00:00 2001 From: wancat Date: Wed, 6 Mar 2024 23:32:23 +0800 Subject: [PATCH 07/19] feat: add output matcher --- packages/game/src/condition.ts | 6 ++++++ packages/game/test/condition.test.ts | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/packages/game/src/condition.ts b/packages/game/src/condition.ts index b3d65f0..c5febc9 100644 --- a/packages/game/src/condition.ts +++ b/packages/game/src/condition.ts @@ -40,6 +40,12 @@ export class PwdMatcher implements Matcher { } } +export class OutputMatcher extends PatternMatcher implements Matcher { + match(command: Partial): boolean { + return command.output ? this.test(command.output.trim()) : false + } +} + export interface ICondition { command?: string output?: string diff --git a/packages/game/test/condition.test.ts b/packages/game/test/condition.test.ts index e513de6..358f388 100644 --- a/packages/game/test/condition.test.ts +++ b/packages/game/test/condition.test.ts @@ -4,6 +4,7 @@ import { CommandMatcher, ErrorMatcher, PwdMatcher, + OutputMatcher, Condition, } from '../src/condition' import { Command } from '../src/command' @@ -63,6 +64,13 @@ test('pwd matcher', () => { expect(matcher.match({ pwd: '/var/home/user' })).toBe(false) }) +test('output matcher', () => { + const matcher = new OutputMatcher('^start$') + expect(matcher.match({ output: 'start' })).toBe(true) + expect(matcher.match({ output: 'start1' })).toBe(false) + expect(matcher.match({ output: 'start\n' })).toBe(true) +}) + // test('condition match', () => { // const condition = new Condition({ // command: '^echo start$', From 4f3752060da216cfa6117e273862abf2131cf81b Mon Sep 17 00:00:00 2001 From: wancat Date: Wed, 6 Mar 2024 23:54:03 +0800 Subject: [PATCH 08/19] feat: condition matcher --- .eslintrc.js | 2 ++ packages/game/src/condition.ts | 25 ++++++++++++------- packages/game/test/condition.test.ts | 36 ++++++++++++++-------------- 3 files changed, 37 insertions(+), 26 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index c8110a1..d53065a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -64,6 +64,8 @@ module.exports = { '@typescript-eslint/no-unused-vars': 'error', 'no-useless-constructor': 'off', '@typescript-eslint/no-useless-constructor': 'error', + 'no-empty-function': 'off', + '@typescript-eslint/no-empty-function': 'error', }, overrides: [ { diff --git a/packages/game/src/condition.ts b/packages/game/src/condition.ts index c5febc9..7d9c9bf 100644 --- a/packages/game/src/condition.ts +++ b/packages/game/src/condition.ts @@ -3,7 +3,7 @@ import { Command } from './command' import { Matcher } from './matcher' export class PatternMatcher { - protected matcher: RegExp + private matcher: RegExp constructor(pattern: string, args?: string) { this.matcher = new RegExp(pattern, args) } @@ -19,16 +19,19 @@ export class CommandMatcher extends PatternMatcher implements Matcher { } } -export class ErrorMatcher extends PatternMatcher implements Matcher { - constructor(private errorPattern?: string) { - super(errorPattern || '') +export class ErrorMatcher implements Matcher { + private matcher?: PatternMatcher + constructor(errorPattern?: string) { + if (errorPattern) { + this.matcher = new PatternMatcher(errorPattern) + } } match(command: Partial): boolean { - if (!this.errorPattern) { - return command.error === '' + if (!this.matcher) { + return !command.error } - return !!command.error && this.test(command.error) + return this.matcher.test(command.error || '') } } @@ -58,8 +61,14 @@ export class Condition { constructor({ command, output, error, pwd }: ICondition) { if (command) this.matchers.push(new CommandMatcher(command)) - // if (output) this.matchers.push(new OutputMatcher(output)) + if (output) this.matchers.push(new OutputMatcher(output)) if (pwd) this.matchers.push(new PwdMatcher(pwd)) this.matchers.push(new ErrorMatcher(error)) // always check unexpected error } + + match(command: Partial): boolean { + return this.matchers.every((matcher) => { + return matcher.match(command) + }) + } } diff --git a/packages/game/test/condition.test.ts b/packages/game/test/condition.test.ts index 358f388..69368eb 100644 --- a/packages/game/test/condition.test.ts +++ b/packages/game/test/condition.test.ts @@ -71,22 +71,22 @@ test('output matcher', () => { expect(matcher.match({ output: 'start\n' })).toBe(true) }) -// test('condition match', () => { -// const condition = new Condition({ -// command: '^echo start$', -// pwd: '/home/user', -// }) +test('condition match', () => { + const condition = new Condition({ + command: '^echo start$', + }) -// expect( -// condition.match({ -// command: 'echo start', -// pwd: '/home/user', -// }) -// ).toBe(true) -// expect( -// condition.match({ -// command: 'echo start', -// pwd: '/home/user1', -// }) -// ).toBe(false) -// }) + expect( + condition.match({ + command: 'echo start', + }) + ).toBe(true) + expect( + condition.match({ + command: 'echo hello', + }) + ).toBe(false) + expect( + condition.match({ command: 'echo start', error: 'permission denied' }) + ).toBe(false) +}) From 8280f7073d69e5dc4bde28c76964c1d6b35d2bc9 Mon Sep 17 00:00:00 2001 From: wancat Date: Wed, 6 Mar 2024 23:57:35 +0800 Subject: [PATCH 09/19] refactor: remove unnecessary patter matcher --- packages/game/src/condition.ts | 23 +++++++++++------------ packages/game/test/condition.test.ts | 21 --------------------- 2 files changed, 11 insertions(+), 33 deletions(-) diff --git a/packages/game/src/condition.ts b/packages/game/src/condition.ts index 7d9c9bf..9b4857d 100644 --- a/packages/game/src/condition.ts +++ b/packages/game/src/condition.ts @@ -2,28 +2,22 @@ import { Command } from './command' import { Matcher } from './matcher' -export class PatternMatcher { +export class CommandMatcher implements Matcher { private matcher: RegExp constructor(pattern: string, args?: string) { this.matcher = new RegExp(pattern, args) } - test(input: string): boolean { - return this.matcher.test(input) - } -} - -export class CommandMatcher extends PatternMatcher implements Matcher { match(command: Partial): boolean { - return !!command.command && this.test(command.command) + return !!command.command && this.matcher.test(command.command) } } export class ErrorMatcher implements Matcher { - private matcher?: PatternMatcher + private matcher?: RegExp constructor(errorPattern?: string) { if (errorPattern) { - this.matcher = new PatternMatcher(errorPattern) + this.matcher = new RegExp(errorPattern) } } @@ -43,9 +37,14 @@ export class PwdMatcher implements Matcher { } } -export class OutputMatcher extends PatternMatcher implements Matcher { +export class OutputMatcher implements Matcher { + private matcher: RegExp + constructor(pattern: string, args?: string) { + this.matcher = new RegExp(pattern, args) + } + match(command: Partial): boolean { - return command.output ? this.test(command.output.trim()) : false + return !!command.output && this.matcher.test(command.output.trim()) } } diff --git a/packages/game/test/condition.test.ts b/packages/game/test/condition.test.ts index 69368eb..53c8922 100644 --- a/packages/game/test/condition.test.ts +++ b/packages/game/test/condition.test.ts @@ -1,6 +1,5 @@ import { test, expect } from '@jest/globals' import { - PatternMatcher, CommandMatcher, ErrorMatcher, PwdMatcher, @@ -9,26 +8,6 @@ import { } from '../src/condition' import { Command } from '../src/command' -test('pattern match', () => { - const matcher = new PatternMatcher('^echo start$') - - expect(matcher.test('echo start')).toBe(true) - expect(matcher.test('echo start ')).toBe(false) -}) - -test('pattern match with flag', () => { - const matcher = new PatternMatcher('^echo start$', 'i') - - expect(matcher.test('echo start')).toBe(true) - expect(matcher.test('echo Start')).toBe(true) - expect(matcher.test('echo Start ')).toBe(false) -}) - -test('empty pattern return true', () => { - const matcher = new PatternMatcher('') - expect(matcher.test('echo start')).toBe(true) -}) - test('command match', () => { const command: Command = { command: 'echo start', From e83d91385243024955ff8f7395cca328ed63a3b5 Mon Sep 17 00:00:00 2001 From: wancat Date: Thu, 7 Mar 2024 00:25:50 +0800 Subject: [PATCH 10/19] refactor: separate matchers --- packages/game/package.json | 10 +++ packages/game/src/condition.ts | 73 ------------------- packages/game/src/condition/commandMatcher.ts | 13 ++++ packages/game/src/condition/condition.ts | 30 ++++++++ packages/game/src/condition/errorMatcher.ts | 18 +++++ packages/game/src/{ => condition}/matcher.ts | 2 +- packages/game/src/condition/outputMatcher.ts | 13 ++++ packages/game/src/condition/pwdMatcher.ts | 10 +++ packages/game/test/condition.test.ts | 29 +++----- packages/game/tsconfig.json | 8 ++ 10 files changed, 114 insertions(+), 92 deletions(-) create mode 100644 packages/game/package.json delete mode 100644 packages/game/src/condition.ts create mode 100644 packages/game/src/condition/commandMatcher.ts create mode 100644 packages/game/src/condition/condition.ts create mode 100644 packages/game/src/condition/errorMatcher.ts rename packages/game/src/{ => condition}/matcher.ts (64%) create mode 100644 packages/game/src/condition/outputMatcher.ts create mode 100644 packages/game/src/condition/pwdMatcher.ts create mode 100644 packages/game/tsconfig.json diff --git a/packages/game/package.json b/packages/game/package.json new file mode 100644 index 0000000..7e6a856 --- /dev/null +++ b/packages/game/package.json @@ -0,0 +1,10 @@ +{ + "name": "@linux-odyssey/game", + "version": "1.0.0", + "main": "dist/index.ts", + "license": "MIT", + "scripts": { + "build": "tsc -b" + }, + "dependencies": {} +} diff --git a/packages/game/src/condition.ts b/packages/game/src/condition.ts deleted file mode 100644 index 9b4857d..0000000 --- a/packages/game/src/condition.ts +++ /dev/null @@ -1,73 +0,0 @@ -/* eslint-disable max-classes-per-file */ -import { Command } from './command' -import { Matcher } from './matcher' - -export class CommandMatcher implements Matcher { - private matcher: RegExp - constructor(pattern: string, args?: string) { - this.matcher = new RegExp(pattern, args) - } - - match(command: Partial): boolean { - return !!command.command && this.matcher.test(command.command) - } -} - -export class ErrorMatcher implements Matcher { - private matcher?: RegExp - constructor(errorPattern?: string) { - if (errorPattern) { - this.matcher = new RegExp(errorPattern) - } - } - - match(command: Partial): boolean { - if (!this.matcher) { - return !command.error - } - return this.matcher.test(command.error || '') - } -} - -export class PwdMatcher implements Matcher { - constructor(private pwd: string) {} - - match(command: Partial): boolean { - return command.pwd === this.pwd - } -} - -export class OutputMatcher implements Matcher { - private matcher: RegExp - constructor(pattern: string, args?: string) { - this.matcher = new RegExp(pattern, args) - } - - match(command: Partial): boolean { - return !!command.output && this.matcher.test(command.output.trim()) - } -} - -export interface ICondition { - command?: string - output?: string - error?: string - pwd?: string -} - -export class Condition { - private matchers: Matcher[] = [] - - constructor({ command, output, error, pwd }: ICondition) { - if (command) this.matchers.push(new CommandMatcher(command)) - if (output) this.matchers.push(new OutputMatcher(output)) - if (pwd) this.matchers.push(new PwdMatcher(pwd)) - this.matchers.push(new ErrorMatcher(error)) // always check unexpected error - } - - match(command: Partial): boolean { - return this.matchers.every((matcher) => { - return matcher.match(command) - }) - } -} diff --git a/packages/game/src/condition/commandMatcher.ts b/packages/game/src/condition/commandMatcher.ts new file mode 100644 index 0000000..2d102b3 --- /dev/null +++ b/packages/game/src/condition/commandMatcher.ts @@ -0,0 +1,13 @@ +import { Command } from '../command.js' +import { Matcher } from './matcher.js' + +export class CommandMatcher implements Matcher { + private matcher: RegExp + constructor(command: string, flags?: string) { + this.matcher = new RegExp(command, flags) + } + + match(command: Partial): boolean { + return !!command.command && this.matcher.test(command.command) + } +} diff --git a/packages/game/src/condition/condition.ts b/packages/game/src/condition/condition.ts new file mode 100644 index 0000000..f65d9b8 --- /dev/null +++ b/packages/game/src/condition/condition.ts @@ -0,0 +1,30 @@ +import { Command } from '../command.js' +import { PwdMatcher } from './pwdMatcher.js' +import { CommandMatcher } from './commandMatcher.js' +import { ErrorMatcher } from './errorMatcher.js' +import { Matcher } from './matcher.js' +import { OutputMatcher } from './outputMatcher.js' + +export interface ICondition { + command?: string + output?: string + error?: string + pwd?: string +} + +export class Condition { + private matchers: Matcher[] = [] + + constructor({ command, output, error, pwd }: ICondition) { + if (command) this.matchers.push(new CommandMatcher(command)) + if (output) this.matchers.push(new OutputMatcher(output)) + if (pwd) this.matchers.push(new PwdMatcher(pwd)) + this.matchers.push(new ErrorMatcher(error)) // always check unexpected error + } + + match(command: Partial): boolean { + return this.matchers.every((matcher) => { + return matcher.match(command) + }) + } +} diff --git a/packages/game/src/condition/errorMatcher.ts b/packages/game/src/condition/errorMatcher.ts new file mode 100644 index 0000000..53898fb --- /dev/null +++ b/packages/game/src/condition/errorMatcher.ts @@ -0,0 +1,18 @@ +import { Matcher } from './matcher.js' +import { Command } from '../command.js' + +export class ErrorMatcher implements Matcher { + private matcher?: RegExp + constructor(errorPattern?: string) { + if (errorPattern) { + this.matcher = new RegExp(errorPattern) + } + } + + match(command: Partial): boolean { + if (!this.matcher) { + return !command.error + } + return this.matcher.test(command.error || '') + } +} diff --git a/packages/game/src/matcher.ts b/packages/game/src/condition/matcher.ts similarity index 64% rename from packages/game/src/matcher.ts rename to packages/game/src/condition/matcher.ts index b1de51d..29afe3f 100644 --- a/packages/game/src/matcher.ts +++ b/packages/game/src/condition/matcher.ts @@ -1,4 +1,4 @@ -import { Command } from './command' +import { Command } from '../command.js' export interface Matcher { match(command: Partial): boolean diff --git a/packages/game/src/condition/outputMatcher.ts b/packages/game/src/condition/outputMatcher.ts new file mode 100644 index 0000000..3bedb55 --- /dev/null +++ b/packages/game/src/condition/outputMatcher.ts @@ -0,0 +1,13 @@ +import { Command } from '../command.js' +import { Matcher } from './matcher.js' + +export class OutputMatcher implements Matcher { + private matcher: RegExp + constructor(pattern: string, args?: string) { + this.matcher = new RegExp(pattern, args) + } + + match(command: Partial): boolean { + return !!command.output && this.matcher.test(command.output.trim()) + } +} diff --git a/packages/game/src/condition/pwdMatcher.ts b/packages/game/src/condition/pwdMatcher.ts new file mode 100644 index 0000000..f4e276a --- /dev/null +++ b/packages/game/src/condition/pwdMatcher.ts @@ -0,0 +1,10 @@ +import { Command } from '../command.js' +import { Matcher } from './matcher.js' + +export class PwdMatcher implements Matcher { + constructor(private pwd: string) {} + + match(command: Partial): boolean { + return command.pwd === this.pwd + } +} diff --git a/packages/game/test/condition.test.ts b/packages/game/test/condition.test.ts index 53c8922..0310331 100644 --- a/packages/game/test/condition.test.ts +++ b/packages/game/test/condition.test.ts @@ -1,23 +1,16 @@ import { test, expect } from '@jest/globals' -import { - CommandMatcher, - ErrorMatcher, - PwdMatcher, - OutputMatcher, - Condition, -} from '../src/condition' -import { Command } from '../src/command' +import { Condition } from '../src/condition/condition' +import { OutputMatcher } from '../src/condition/outputMatcher' +import { PwdMatcher } from '../src/condition/pwdMatcher' +import { CommandMatcher } from '../src/condition/commandMatcher' +import { ErrorMatcher } from '../src/condition/errorMatcher.js' test('command match', () => { - const command: Command = { - command: 'echo start', - output: 'start', - error: '', - pwd: '/home/user', - } - - const matcher = new CommandMatcher('^echo start$', 'i') - expect(matcher.match(command)).toBe(true) + const matcher = new CommandMatcher('^echo start$') + expect(matcher.match({ command: 'echo start' })).toBe(true) + expect(matcher.match({ command: 'echo start1' })).toBe(false) + // Currently not supported + expect(matcher.match({ command: 'echo "start"' })).toBe(false) }) test('error matcher', () => { @@ -50,7 +43,7 @@ test('output matcher', () => { expect(matcher.match({ output: 'start\n' })).toBe(true) }) -test('condition match', () => { +test('condition match command', () => { const condition = new Condition({ command: '^echo start$', }) diff --git a/packages/game/tsconfig.json b/packages/game/tsconfig.json new file mode 100644 index 0000000..49e05ce --- /dev/null +++ b/packages/game/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["src"] +} From e5f5590a67860113bcb7faf8c88f2df834cb728b Mon Sep 17 00:00:00 2001 From: wancat Date: Thu, 7 Mar 2024 00:42:49 +0800 Subject: [PATCH 11/19] feat: add "or" and "not" matchers --- packages/game/src/condition/condition.ts | 12 +++++++++++- packages/game/src/condition/notMatcher.ts | 10 ++++++++++ packages/game/src/condition/orMatcher.ts | 10 ++++++++++ packages/game/test/condition.test.ts | 18 ++++++++++++++++++ 4 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 packages/game/src/condition/notMatcher.ts create mode 100644 packages/game/src/condition/orMatcher.ts diff --git a/packages/game/src/condition/condition.ts b/packages/game/src/condition/condition.ts index f65d9b8..6188ef3 100644 --- a/packages/game/src/condition/condition.ts +++ b/packages/game/src/condition/condition.ts @@ -1,24 +1,34 @@ +/* eslint-disable max-classes-per-file */ import { Command } from '../command.js' import { PwdMatcher } from './pwdMatcher.js' import { CommandMatcher } from './commandMatcher.js' import { ErrorMatcher } from './errorMatcher.js' import { Matcher } from './matcher.js' import { OutputMatcher } from './outputMatcher.js' +import { OrMatcher } from './orMatcher.js' +import { NotMatcher } from './notMatcher.js' export interface ICondition { command?: string output?: string error?: string pwd?: string + or?: ICondition[] + not?: ICondition } export class Condition { private matchers: Matcher[] = [] - constructor({ command, output, error, pwd }: ICondition) { + constructor({ command, output, error, pwd, or, not }: ICondition) { if (command) this.matchers.push(new CommandMatcher(command)) if (output) this.matchers.push(new OutputMatcher(output)) if (pwd) this.matchers.push(new PwdMatcher(pwd)) + if (or) { + const conditions = or.map((condition) => new Condition(condition)) + this.matchers.push(new OrMatcher(conditions)) + } + if (not) this.matchers.push(new NotMatcher(new Condition(not))) this.matchers.push(new ErrorMatcher(error)) // always check unexpected error } diff --git a/packages/game/src/condition/notMatcher.ts b/packages/game/src/condition/notMatcher.ts new file mode 100644 index 0000000..ac3ae99 --- /dev/null +++ b/packages/game/src/condition/notMatcher.ts @@ -0,0 +1,10 @@ +import { Command } from '../command.js' +import { Matcher } from './matcher.js' + +export class NotMatcher implements Matcher { + constructor(private condition: Matcher) {} + + match(command: Partial): boolean { + return !this.condition.match(command) + } +} diff --git a/packages/game/src/condition/orMatcher.ts b/packages/game/src/condition/orMatcher.ts new file mode 100644 index 0000000..1703c6c --- /dev/null +++ b/packages/game/src/condition/orMatcher.ts @@ -0,0 +1,10 @@ +import { Command } from '../command.js' +import { Matcher } from './matcher.js' + +export class OrMatcher implements Matcher { + constructor(private conditions: Matcher[]) {} + + match(command: Partial): boolean { + return this.conditions.some((condition) => condition.match(command)) + } +} diff --git a/packages/game/test/condition.test.ts b/packages/game/test/condition.test.ts index 0310331..554a0ab 100644 --- a/packages/game/test/condition.test.ts +++ b/packages/game/test/condition.test.ts @@ -62,3 +62,21 @@ test('condition match command', () => { condition.match({ command: 'echo start', error: 'permission denied' }) ).toBe(false) }) + +test('condition with OR', () => { + const condition = new Condition({ + or: [{ command: '^echo start$' }, { command: '^echo hello$' }], + }) + expect(condition.match({ command: 'echo start' })).toBe(true) + expect(condition.match({ command: 'echo hello' })).toBe(true) + expect(condition.match({ command: 'echo start1' })).toBe(false) +}) + +test('condition with NOT', () => { + const condition = new Condition({ + not: { command: '^echo start$' }, + }) + + expect(condition.match({ command: 'echo start' })).toBe(false) + expect(condition.match({ command: 'echo hello' })).toBe(true) +}) From b5e20766a35d8635b13f140144a70cab61d76f7d Mon Sep 17 00:00:00 2001 From: wancat Date: Thu, 7 Mar 2024 00:50:42 +0800 Subject: [PATCH 12/19] refactor: rename paths --- packages/game/src/command.ts | 6 ----- .../{commandMatcher.ts => CommandMatcher.ts} | 6 ++--- .../condition/{condition.ts => Condition.ts} | 27 +++++++------------ .../{errorMatcher.ts => ErrorMatcher.ts} | 6 ++--- packages/game/src/condition/Matcher.ts | 5 ++++ .../{notMatcher.ts => NotMatcher.ts} | 6 ++--- .../condition/{orMatcher.ts => OrMatcher.ts} | 6 ++--- .../{outputMatcher.ts => OutputMatcher.ts} | 6 ++--- .../{pwdMatcher.ts => PwdMatcher.ts} | 6 ++--- packages/game/src/condition/matcher.ts | 5 ---- packages/game/src/types.ts | 15 +++++++++++ packages/game/test/condition.test.ts | 10 +++---- 12 files changed, 52 insertions(+), 52 deletions(-) delete mode 100644 packages/game/src/command.ts rename packages/game/src/condition/{commandMatcher.ts => CommandMatcher.ts} (66%) rename packages/game/src/condition/{condition.ts => Condition.ts} (57%) rename packages/game/src/condition/{errorMatcher.ts => ErrorMatcher.ts} (71%) create mode 100644 packages/game/src/condition/Matcher.ts rename packages/game/src/condition/{notMatcher.ts => NotMatcher.ts} (52%) rename packages/game/src/condition/{orMatcher.ts => OrMatcher.ts} (58%) rename packages/game/src/condition/{outputMatcher.ts => OutputMatcher.ts} (66%) rename packages/game/src/condition/{pwdMatcher.ts => PwdMatcher.ts} (50%) delete mode 100644 packages/game/src/condition/matcher.ts create mode 100644 packages/game/src/types.ts diff --git a/packages/game/src/command.ts b/packages/game/src/command.ts deleted file mode 100644 index 6faf783..0000000 --- a/packages/game/src/command.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface Command { - command: string - output: string - error: string - pwd: string -} diff --git a/packages/game/src/condition/commandMatcher.ts b/packages/game/src/condition/CommandMatcher.ts similarity index 66% rename from packages/game/src/condition/commandMatcher.ts rename to packages/game/src/condition/CommandMatcher.ts index 2d102b3..1387403 100644 --- a/packages/game/src/condition/commandMatcher.ts +++ b/packages/game/src/condition/CommandMatcher.ts @@ -1,5 +1,5 @@ -import { Command } from '../command.js' -import { Matcher } from './matcher.js' +import { Command } from '../types.js' +import { Matcher } from './Matcher.js' export class CommandMatcher implements Matcher { private matcher: RegExp @@ -7,7 +7,7 @@ export class CommandMatcher implements Matcher { this.matcher = new RegExp(command, flags) } - match(command: Partial): boolean { + match(command: Command): boolean { return !!command.command && this.matcher.test(command.command) } } diff --git a/packages/game/src/condition/condition.ts b/packages/game/src/condition/Condition.ts similarity index 57% rename from packages/game/src/condition/condition.ts rename to packages/game/src/condition/Condition.ts index 6188ef3..5227413 100644 --- a/packages/game/src/condition/condition.ts +++ b/packages/game/src/condition/Condition.ts @@ -1,21 +1,12 @@ /* eslint-disable max-classes-per-file */ -import { Command } from '../command.js' -import { PwdMatcher } from './pwdMatcher.js' -import { CommandMatcher } from './commandMatcher.js' -import { ErrorMatcher } from './errorMatcher.js' -import { Matcher } from './matcher.js' -import { OutputMatcher } from './outputMatcher.js' -import { OrMatcher } from './orMatcher.js' -import { NotMatcher } from './notMatcher.js' - -export interface ICondition { - command?: string - output?: string - error?: string - pwd?: string - or?: ICondition[] - not?: ICondition -} +import { Command, ICondition } from '../types.js' +import { PwdMatcher } from './PwdMatcher.js' +import { CommandMatcher } from './CommandMatcher.js' +import { ErrorMatcher } from './ErrorMatcher.js' +import { Matcher } from './Matcher.js' +import { OutputMatcher } from './OutputMatcher.js' +import { OrMatcher } from './OrMatcher.js' +import { NotMatcher } from './NotMatcher.js' export class Condition { private matchers: Matcher[] = [] @@ -32,7 +23,7 @@ export class Condition { this.matchers.push(new ErrorMatcher(error)) // always check unexpected error } - match(command: Partial): boolean { + match(command: Command): boolean { return this.matchers.every((matcher) => { return matcher.match(command) }) diff --git a/packages/game/src/condition/errorMatcher.ts b/packages/game/src/condition/ErrorMatcher.ts similarity index 71% rename from packages/game/src/condition/errorMatcher.ts rename to packages/game/src/condition/ErrorMatcher.ts index 53898fb..b77a2a8 100644 --- a/packages/game/src/condition/errorMatcher.ts +++ b/packages/game/src/condition/ErrorMatcher.ts @@ -1,5 +1,5 @@ -import { Matcher } from './matcher.js' -import { Command } from '../command.js' +import { Matcher } from './Matcher.js' +import { Command } from '../types.js' export class ErrorMatcher implements Matcher { private matcher?: RegExp @@ -9,7 +9,7 @@ export class ErrorMatcher implements Matcher { } } - match(command: Partial): boolean { + match(command: Command): boolean { if (!this.matcher) { return !command.error } diff --git a/packages/game/src/condition/Matcher.ts b/packages/game/src/condition/Matcher.ts new file mode 100644 index 0000000..862942a --- /dev/null +++ b/packages/game/src/condition/Matcher.ts @@ -0,0 +1,5 @@ +import { Command } from '../types.js' + +export interface Matcher { + match(command: Command): boolean +} diff --git a/packages/game/src/condition/notMatcher.ts b/packages/game/src/condition/NotMatcher.ts similarity index 52% rename from packages/game/src/condition/notMatcher.ts rename to packages/game/src/condition/NotMatcher.ts index ac3ae99..f37f746 100644 --- a/packages/game/src/condition/notMatcher.ts +++ b/packages/game/src/condition/NotMatcher.ts @@ -1,10 +1,10 @@ -import { Command } from '../command.js' -import { Matcher } from './matcher.js' +import { Command } from '../types.js' +import { Matcher } from './Matcher.js' export class NotMatcher implements Matcher { constructor(private condition: Matcher) {} - match(command: Partial): boolean { + match(command: Command): boolean { return !this.condition.match(command) } } diff --git a/packages/game/src/condition/orMatcher.ts b/packages/game/src/condition/OrMatcher.ts similarity index 58% rename from packages/game/src/condition/orMatcher.ts rename to packages/game/src/condition/OrMatcher.ts index 1703c6c..eb51286 100644 --- a/packages/game/src/condition/orMatcher.ts +++ b/packages/game/src/condition/OrMatcher.ts @@ -1,10 +1,10 @@ -import { Command } from '../command.js' -import { Matcher } from './matcher.js' +import { Command } from '../types.js' +import { Matcher } from './Matcher.js' export class OrMatcher implements Matcher { constructor(private conditions: Matcher[]) {} - match(command: Partial): boolean { + match(command: Command): boolean { return this.conditions.some((condition) => condition.match(command)) } } diff --git a/packages/game/src/condition/outputMatcher.ts b/packages/game/src/condition/OutputMatcher.ts similarity index 66% rename from packages/game/src/condition/outputMatcher.ts rename to packages/game/src/condition/OutputMatcher.ts index 3bedb55..643c558 100644 --- a/packages/game/src/condition/outputMatcher.ts +++ b/packages/game/src/condition/OutputMatcher.ts @@ -1,5 +1,5 @@ -import { Command } from '../command.js' -import { Matcher } from './matcher.js' +import { Command } from '../types.js' +import { Matcher } from './Matcher.js' export class OutputMatcher implements Matcher { private matcher: RegExp @@ -7,7 +7,7 @@ export class OutputMatcher implements Matcher { this.matcher = new RegExp(pattern, args) } - match(command: Partial): boolean { + match(command: Command): boolean { return !!command.output && this.matcher.test(command.output.trim()) } } diff --git a/packages/game/src/condition/pwdMatcher.ts b/packages/game/src/condition/PwdMatcher.ts similarity index 50% rename from packages/game/src/condition/pwdMatcher.ts rename to packages/game/src/condition/PwdMatcher.ts index f4e276a..dac9c78 100644 --- a/packages/game/src/condition/pwdMatcher.ts +++ b/packages/game/src/condition/PwdMatcher.ts @@ -1,10 +1,10 @@ -import { Command } from '../command.js' -import { Matcher } from './matcher.js' +import { Command } from '../types.js' +import { Matcher } from './Matcher.js' export class PwdMatcher implements Matcher { constructor(private pwd: string) {} - match(command: Partial): boolean { + match(command: Command): boolean { return command.pwd === this.pwd } } diff --git a/packages/game/src/condition/matcher.ts b/packages/game/src/condition/matcher.ts deleted file mode 100644 index 29afe3f..0000000 --- a/packages/game/src/condition/matcher.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Command } from '../command.js' - -export interface Matcher { - match(command: Partial): boolean -} diff --git a/packages/game/src/types.ts b/packages/game/src/types.ts new file mode 100644 index 0000000..8227198 --- /dev/null +++ b/packages/game/src/types.ts @@ -0,0 +1,15 @@ +export interface Command { + command?: string + output?: string + error?: string + pwd?: string +} + +export interface ICondition { + command?: string + output?: string + error?: string + pwd?: string + or?: ICondition[] + not?: ICondition +} diff --git a/packages/game/test/condition.test.ts b/packages/game/test/condition.test.ts index 554a0ab..11dd056 100644 --- a/packages/game/test/condition.test.ts +++ b/packages/game/test/condition.test.ts @@ -1,9 +1,9 @@ import { test, expect } from '@jest/globals' -import { Condition } from '../src/condition/condition' -import { OutputMatcher } from '../src/condition/outputMatcher' -import { PwdMatcher } from '../src/condition/pwdMatcher' -import { CommandMatcher } from '../src/condition/commandMatcher' -import { ErrorMatcher } from '../src/condition/errorMatcher.js' +import { Condition } from '../src/condition/Condition' +import { OutputMatcher } from '../src/condition/OutputMatcher' +import { PwdMatcher } from '../src/condition/PwdMatcher' +import { CommandMatcher } from '../src/condition/CommandMatcher' +import { ErrorMatcher } from '../src/condition/ErrorMatcher.js' test('command match', () => { const matcher = new CommandMatcher('^echo start$') From d612b2d6af69516e1d1909972c9c94632df8510a Mon Sep 17 00:00:00 2001 From: wancat Date: Fri, 8 Mar 2024 00:13:38 +0800 Subject: [PATCH 13/19] feat: add file matcher --- .eslintrc.js | 2 + packages/game/src/condition/FileMatcher.ts | 15 ++++ packages/game/src/types.ts | 14 ++++ packages/game/test/asyncCondition.test.ts | 92 ++++++++++++++++++++++ 4 files changed, 123 insertions(+) create mode 100644 packages/game/src/condition/FileMatcher.ts create mode 100644 packages/game/test/asyncCondition.test.ts diff --git a/.eslintrc.js b/.eslintrc.js index d53065a..f1ee5a6 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -66,6 +66,8 @@ module.exports = { '@typescript-eslint/no-useless-constructor': 'error', 'no-empty-function': 'off', '@typescript-eslint/no-empty-function': 'error', + 'no-shadow': 'off', + '@typescript-eslint/no-shadow': 'error', }, overrides: [ { diff --git a/packages/game/src/condition/FileMatcher.ts b/packages/game/src/condition/FileMatcher.ts new file mode 100644 index 0000000..ac9f709 --- /dev/null +++ b/packages/game/src/condition/FileMatcher.ts @@ -0,0 +1,15 @@ +import { FileInput, IFileExistenceChecker } from '../types' + +interface FileExistenceInput extends FileInput { + exists: boolean +} + +export async function checkFiles( + checker: IFileExistenceChecker, + files: FileExistenceInput[] +) { + const existences = await Promise.all( + files.map((file) => checker.exists(file)) + ) + return existences.every((exists, index) => exists === files[index].exists) +} diff --git a/packages/game/src/types.ts b/packages/game/src/types.ts index 8227198..57724a9 100644 --- a/packages/game/src/types.ts +++ b/packages/game/src/types.ts @@ -13,3 +13,17 @@ export interface ICondition { or?: ICondition[] not?: ICondition } + +export enum FileType { + FILE = 'file', + FOLDER = 'folder', +} + +export interface FileInput { + path: string + type: FileType +} + +export interface IFileExistenceChecker { + exists(file: FileInput): Promise +} diff --git a/packages/game/test/asyncCondition.test.ts b/packages/game/test/asyncCondition.test.ts new file mode 100644 index 0000000..1a6503a --- /dev/null +++ b/packages/game/test/asyncCondition.test.ts @@ -0,0 +1,92 @@ +import { test, expect } from '@jest/globals' +import { IFileExistenceChecker, FileType, FileInput } from '../src/types.js' +import { checkFiles } from '../src/condition/FileMatcher.js' + +class MockFileChecker implements IFileExistenceChecker { + private files: FileInput[] = [ + { + path: '/home/user/hello.txt', + type: FileType.FILE, + }, + { + path: '/home/user/world.txt', + type: FileType.FILE, + }, + { + path: '/home/user/Downloads', + type: FileType.FOLDER, + }, + ] + + async exists(file: FileInput): Promise { + return this.files.some((f) => f.path === file.path && f.type === file.type) + } +} + +test('file matcher', async () => { + const checker = new MockFileChecker() + expect( + await checkFiles(checker, [ + { + path: '/home/user/hello.txt', + type: FileType.FILE, + exists: true, + }, + ]) + ).toBe(true) + expect( + await checkFiles(checker, [ + { + path: '/home/user/not-exists.txt', + type: FileType.FILE, + exists: true, + }, + ]) + ).toBe(false) + expect( + await checkFiles(checker, [ + { + path: '/home/user/not-exists.txt', + type: FileType.FILE, + exists: false, + }, + ]) + ).toBe(true) + expect( + await checkFiles(checker, [ + { + path: '/home/user/Downloads', + type: FileType.FOLDER, + exists: true, + }, + ]) + ).toBe(true) + expect( + await checkFiles(checker, [ + { + path: '/home/user/hello.txt', + type: FileType.FILE, + exists: true, + }, + { + path: '/home/user/Downloads', + type: FileType.FOLDER, + exists: true, + }, + ]) + ).toBe(true) + expect( + await checkFiles(checker, [ + { + path: '/home/user/hello.txt', + type: FileType.FILE, + exists: true, + }, + { + path: '/home/user/not-exist.txt', + type: FileType.FILE, + exists: true, + }, + ]) + ).toBe(false) +}) From 65ad72223ba291d0aa8fa19b5371ad9f68eb95b1 Mon Sep 17 00:00:00 2001 From: wancat Date: Fri, 8 Mar 2024 00:24:51 +0800 Subject: [PATCH 14/19] feat: add checkfiles into Condition --- packages/game/src/condition/Condition.ts | 18 +++++++++++++++--- packages/game/src/condition/FileMatcher.ts | 6 +----- packages/game/src/types.ts | 5 +++++ packages/game/test/asyncCondition.test.ts | 15 +++++++++++++++ 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/packages/game/src/condition/Condition.ts b/packages/game/src/condition/Condition.ts index 5227413..fc8aea4 100644 --- a/packages/game/src/condition/Condition.ts +++ b/packages/game/src/condition/Condition.ts @@ -1,5 +1,9 @@ -/* eslint-disable max-classes-per-file */ -import { Command, ICondition } from '../types.js' +import { + Command, + ICondition, + IFileExistenceChecker, + FileExistenceInput, +} from '../types.js' import { PwdMatcher } from './PwdMatcher.js' import { CommandMatcher } from './CommandMatcher.js' import { ErrorMatcher } from './ErrorMatcher.js' @@ -7,11 +11,13 @@ import { Matcher } from './Matcher.js' import { OutputMatcher } from './OutputMatcher.js' import { OrMatcher } from './OrMatcher.js' import { NotMatcher } from './NotMatcher.js' +import { checkFiles } from './FileMatcher.js' export class Condition { + private files: FileExistenceInput[] = [] private matchers: Matcher[] = [] - constructor({ command, output, error, pwd, or, not }: ICondition) { + constructor({ command, output, error, pwd, or, not, files }: ICondition) { if (command) this.matchers.push(new CommandMatcher(command)) if (output) this.matchers.push(new OutputMatcher(output)) if (pwd) this.matchers.push(new PwdMatcher(pwd)) @@ -20,6 +26,7 @@ export class Condition { this.matchers.push(new OrMatcher(conditions)) } if (not) this.matchers.push(new NotMatcher(new Condition(not))) + if (files) this.files = files this.matchers.push(new ErrorMatcher(error)) // always check unexpected error } @@ -28,4 +35,9 @@ export class Condition { return matcher.match(command) }) } + + async check(checker: IFileExistenceChecker): Promise { + if (this.matchers.length === 0) return true + return checkFiles(checker, this.files) + } } diff --git a/packages/game/src/condition/FileMatcher.ts b/packages/game/src/condition/FileMatcher.ts index ac9f709..c364e09 100644 --- a/packages/game/src/condition/FileMatcher.ts +++ b/packages/game/src/condition/FileMatcher.ts @@ -1,8 +1,4 @@ -import { FileInput, IFileExistenceChecker } from '../types' - -interface FileExistenceInput extends FileInput { - exists: boolean -} +import { FileExistenceInput, IFileExistenceChecker } from '../types' export async function checkFiles( checker: IFileExistenceChecker, diff --git a/packages/game/src/types.ts b/packages/game/src/types.ts index 57724a9..4bcbb1a 100644 --- a/packages/game/src/types.ts +++ b/packages/game/src/types.ts @@ -12,6 +12,7 @@ export interface ICondition { pwd?: string or?: ICondition[] not?: ICondition + files: FileExistenceInput[] } export enum FileType { @@ -24,6 +25,10 @@ export interface FileInput { type: FileType } +export interface FileExistenceInput extends FileInput { + exists: boolean +} + export interface IFileExistenceChecker { exists(file: FileInput): Promise } diff --git a/packages/game/test/asyncCondition.test.ts b/packages/game/test/asyncCondition.test.ts index 1a6503a..da4399d 100644 --- a/packages/game/test/asyncCondition.test.ts +++ b/packages/game/test/asyncCondition.test.ts @@ -1,6 +1,7 @@ import { test, expect } from '@jest/globals' import { IFileExistenceChecker, FileType, FileInput } from '../src/types.js' import { checkFiles } from '../src/condition/FileMatcher.js' +import { Condition } from '../src/condition/Condition.js' class MockFileChecker implements IFileExistenceChecker { private files: FileInput[] = [ @@ -90,3 +91,17 @@ test('file matcher', async () => { ]) ).toBe(false) }) + +test('condition with file matcher', async () => { + const checker = new MockFileChecker() + const condition = new Condition({ + files: [ + { + path: '/home/user/hello.txt', + type: FileType.FILE, + exists: true, + }, + ], + }) + expect(await condition.check(checker)).toBe(true) +}) From 77fe2d37b3639019fbcaf9b750652b1b7578494a Mon Sep 17 00:00:00 2001 From: wancat Date: Fri, 8 Mar 2024 00:38:49 +0800 Subject: [PATCH 15/19] feat: create stage --- packages/game/src/Stage.ts | 18 +++++++++++++ packages/game/src/condition/CommandMatcher.ts | 4 +-- packages/game/src/condition/Condition.ts | 4 +-- packages/game/src/condition/ErrorMatcher.ts | 4 +-- packages/game/src/condition/Matcher.ts | 4 +-- packages/game/src/condition/NotMatcher.ts | 4 +-- packages/game/src/condition/OrMatcher.ts | 4 +-- packages/game/src/condition/OutputMatcher.ts | 4 +-- packages/game/src/condition/PwdMatcher.ts | 4 +-- packages/game/src/types.ts | 10 ++++++-- packages/game/test/stage.test.ts | 25 +++++++++++++++++++ 11 files changed, 67 insertions(+), 18 deletions(-) create mode 100644 packages/game/src/Stage.ts create mode 100644 packages/game/test/stage.test.ts diff --git a/packages/game/src/Stage.ts b/packages/game/src/Stage.ts new file mode 100644 index 0000000..7517dc9 --- /dev/null +++ b/packages/game/src/Stage.ts @@ -0,0 +1,18 @@ +import { IStage, ICommand } from './types' +import { Condition } from './condition/Condition' + +export class Stage { + id: string + name: string + condition: Condition + + constructor({ id, name, condition }: IStage) { + this.id = id + this.name = name + this.condition = new Condition(condition) + } + + satisfies(command: ICommand): boolean { + return this.condition.match(command) + } +} diff --git a/packages/game/src/condition/CommandMatcher.ts b/packages/game/src/condition/CommandMatcher.ts index 1387403..3f71bcd 100644 --- a/packages/game/src/condition/CommandMatcher.ts +++ b/packages/game/src/condition/CommandMatcher.ts @@ -1,4 +1,4 @@ -import { Command } from '../types.js' +import { ICommand } from '../types.js' import { Matcher } from './Matcher.js' export class CommandMatcher implements Matcher { @@ -7,7 +7,7 @@ export class CommandMatcher implements Matcher { this.matcher = new RegExp(command, flags) } - match(command: Command): boolean { + match(command: ICommand): boolean { return !!command.command && this.matcher.test(command.command) } } diff --git a/packages/game/src/condition/Condition.ts b/packages/game/src/condition/Condition.ts index fc8aea4..82c6c57 100644 --- a/packages/game/src/condition/Condition.ts +++ b/packages/game/src/condition/Condition.ts @@ -1,5 +1,5 @@ import { - Command, + ICommand, ICondition, IFileExistenceChecker, FileExistenceInput, @@ -30,7 +30,7 @@ export class Condition { this.matchers.push(new ErrorMatcher(error)) // always check unexpected error } - match(command: Command): boolean { + match(command: ICommand): boolean { return this.matchers.every((matcher) => { return matcher.match(command) }) diff --git a/packages/game/src/condition/ErrorMatcher.ts b/packages/game/src/condition/ErrorMatcher.ts index b77a2a8..6fd1d15 100644 --- a/packages/game/src/condition/ErrorMatcher.ts +++ b/packages/game/src/condition/ErrorMatcher.ts @@ -1,5 +1,5 @@ import { Matcher } from './Matcher.js' -import { Command } from '../types.js' +import { ICommand } from '../types.js' export class ErrorMatcher implements Matcher { private matcher?: RegExp @@ -9,7 +9,7 @@ export class ErrorMatcher implements Matcher { } } - match(command: Command): boolean { + match(command: ICommand): boolean { if (!this.matcher) { return !command.error } diff --git a/packages/game/src/condition/Matcher.ts b/packages/game/src/condition/Matcher.ts index 862942a..0af7c33 100644 --- a/packages/game/src/condition/Matcher.ts +++ b/packages/game/src/condition/Matcher.ts @@ -1,5 +1,5 @@ -import { Command } from '../types.js' +import { ICommand } from '../types.js' export interface Matcher { - match(command: Command): boolean + match(command: ICommand): boolean } diff --git a/packages/game/src/condition/NotMatcher.ts b/packages/game/src/condition/NotMatcher.ts index f37f746..1e9a846 100644 --- a/packages/game/src/condition/NotMatcher.ts +++ b/packages/game/src/condition/NotMatcher.ts @@ -1,10 +1,10 @@ -import { Command } from '../types.js' +import { ICommand } from '../types.js' import { Matcher } from './Matcher.js' export class NotMatcher implements Matcher { constructor(private condition: Matcher) {} - match(command: Command): boolean { + match(command: ICommand): boolean { return !this.condition.match(command) } } diff --git a/packages/game/src/condition/OrMatcher.ts b/packages/game/src/condition/OrMatcher.ts index eb51286..70c2091 100644 --- a/packages/game/src/condition/OrMatcher.ts +++ b/packages/game/src/condition/OrMatcher.ts @@ -1,10 +1,10 @@ -import { Command } from '../types.js' +import { ICommand } from '../types.js' import { Matcher } from './Matcher.js' export class OrMatcher implements Matcher { constructor(private conditions: Matcher[]) {} - match(command: Command): boolean { + match(command: ICommand): boolean { return this.conditions.some((condition) => condition.match(command)) } } diff --git a/packages/game/src/condition/OutputMatcher.ts b/packages/game/src/condition/OutputMatcher.ts index 643c558..89aa9a2 100644 --- a/packages/game/src/condition/OutputMatcher.ts +++ b/packages/game/src/condition/OutputMatcher.ts @@ -1,4 +1,4 @@ -import { Command } from '../types.js' +import { ICommand } from '../types.js' import { Matcher } from './Matcher.js' export class OutputMatcher implements Matcher { @@ -7,7 +7,7 @@ export class OutputMatcher implements Matcher { this.matcher = new RegExp(pattern, args) } - match(command: Command): boolean { + match(command: ICommand): boolean { return !!command.output && this.matcher.test(command.output.trim()) } } diff --git a/packages/game/src/condition/PwdMatcher.ts b/packages/game/src/condition/PwdMatcher.ts index dac9c78..781a7c5 100644 --- a/packages/game/src/condition/PwdMatcher.ts +++ b/packages/game/src/condition/PwdMatcher.ts @@ -1,10 +1,10 @@ -import { Command } from '../types.js' +import { ICommand } from '../types.js' import { Matcher } from './Matcher.js' export class PwdMatcher implements Matcher { constructor(private pwd: string) {} - match(command: Command): boolean { + match(command: ICommand): boolean { return command.pwd === this.pwd } } diff --git a/packages/game/src/types.ts b/packages/game/src/types.ts index 4bcbb1a..52fff79 100644 --- a/packages/game/src/types.ts +++ b/packages/game/src/types.ts @@ -1,4 +1,4 @@ -export interface Command { +export interface ICommand { command?: string output?: string error?: string @@ -12,7 +12,7 @@ export interface ICondition { pwd?: string or?: ICondition[] not?: ICondition - files: FileExistenceInput[] + files?: FileExistenceInput[] } export enum FileType { @@ -32,3 +32,9 @@ export interface FileExistenceInput extends FileInput { export interface IFileExistenceChecker { exists(file: FileInput): Promise } + +export interface IStage { + id: string + name: string + condition: ICondition +} diff --git a/packages/game/test/stage.test.ts b/packages/game/test/stage.test.ts new file mode 100644 index 0000000..8fa1617 --- /dev/null +++ b/packages/game/test/stage.test.ts @@ -0,0 +1,25 @@ +import { test, expect } from '@jest/globals' +import { Stage } from '../src/Stage' + +test('check stage condition', () => { + const stage = new Stage({ + id: 'stage1', + name: 'List the files using `ls`', + condition: { + command: 'ls', + pwd: '/home/user', + }, + }) + expect( + stage.satisfies({ + command: 'ls', + pwd: '/home/user', + }) + ).toBe(true) + expect( + stage.satisfies({ + command: 'ls', + pwd: '/home/user/Downloads', + }) + ).toBe(false) +}) From 5bea2ea78c4aff40067e91b773f6c717a51e4f43 Mon Sep 17 00:00:00 2001 From: wancat Date: Fri, 8 Mar 2024 00:47:50 +0800 Subject: [PATCH 16/19] feat: add stage condition checks --- packages/game/src/Stage.ts | 9 ++-- packages/game/test/asyncCondition.test.ts | 2 +- packages/game/test/stage.test.ts | 62 +++++++++++++++++++---- 3 files changed, 60 insertions(+), 13 deletions(-) diff --git a/packages/game/src/Stage.ts b/packages/game/src/Stage.ts index 7517dc9..579bb74 100644 --- a/packages/game/src/Stage.ts +++ b/packages/game/src/Stage.ts @@ -1,4 +1,4 @@ -import { IStage, ICommand } from './types' +import { IStage, ICommand, IFileExistenceChecker } from './types' import { Condition } from './condition/Condition' export class Stage { @@ -12,7 +12,10 @@ export class Stage { this.condition = new Condition(condition) } - satisfies(command: ICommand): boolean { - return this.condition.match(command) + async satisfies( + command: ICommand, + checker: IFileExistenceChecker + ): Promise { + return this.condition.match(command) && this.condition.check(checker) } } diff --git a/packages/game/test/asyncCondition.test.ts b/packages/game/test/asyncCondition.test.ts index da4399d..8ad2630 100644 --- a/packages/game/test/asyncCondition.test.ts +++ b/packages/game/test/asyncCondition.test.ts @@ -3,7 +3,7 @@ import { IFileExistenceChecker, FileType, FileInput } from '../src/types.js' import { checkFiles } from '../src/condition/FileMatcher.js' import { Condition } from '../src/condition/Condition.js' -class MockFileChecker implements IFileExistenceChecker { +export class MockFileChecker implements IFileExistenceChecker { private files: FileInput[] = [ { path: '/home/user/hello.txt', diff --git a/packages/game/test/stage.test.ts b/packages/game/test/stage.test.ts index 8fa1617..5631e21 100644 --- a/packages/game/test/stage.test.ts +++ b/packages/game/test/stage.test.ts @@ -1,7 +1,11 @@ import { test, expect } from '@jest/globals' import { Stage } from '../src/Stage' +import { FileType } from '../src/types' +import { MockFileChecker } from './asyncCondition.test' -test('check stage condition', () => { +const checker = new MockFileChecker() + +test('check stage condition', async () => { const stage = new Stage({ id: 'stage1', name: 'List the files using `ls`', @@ -11,15 +15,55 @@ test('check stage condition', () => { }, }) expect( - stage.satisfies({ - command: 'ls', - pwd: '/home/user', - }) + await stage.satisfies( + { + command: 'ls', + pwd: '/home/user', + }, + checker + ) ).toBe(true) expect( - stage.satisfies({ - command: 'ls', - pwd: '/home/user/Downloads', - }) + await stage.satisfies( + { + command: 'ls', + pwd: '/home/user/Downloads', + }, + checker + ) ).toBe(false) }) + +test('check stage with async condition truthy', async () => { + const stage = new Stage({ + id: 'stage1', + name: 'Create file', + condition: { + files: [ + { + path: '/home/user/hello.txt', + type: FileType.FILE, + exists: true, + }, + ], + }, + }) + expect(await stage.satisfies({}, checker)).toBe(true) +}) + +test('check stage with async condition falsy', async () => { + const stage = new Stage({ + id: 'stage1', + name: 'Create file', + condition: { + files: [ + { + path: '/home/user/not-exists.txt', + type: FileType.FILE, + exists: true, + }, + ], + }, + }) + expect(await stage.satisfies({}, checker)).toBe(false) +}) From b449ea455a268049b4cc3a56d29814ced5c6fb6d Mon Sep 17 00:00:00 2001 From: wancat Date: Fri, 8 Mar 2024 01:05:26 +0800 Subject: [PATCH 17/19] feat: add Session and stage active check --- packages/game/src/Session.ts | 17 +++++++++++++++++ packages/game/src/Stage.ts | 24 ++++++++++++++++++++---- packages/game/src/types.ts | 7 ++++++- packages/game/test/stage.test.ts | 19 +++++++++++++++++++ 4 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 packages/game/src/Session.ts diff --git a/packages/game/src/Session.ts b/packages/game/src/Session.ts new file mode 100644 index 0000000..e8b5417 --- /dev/null +++ b/packages/game/src/Session.ts @@ -0,0 +1,17 @@ +import { ISession } from './types' + +export class Session implements ISession { + private completed: string[] = [] + + constructor({ completedStages }: ISession) { + this.completed = completedStages + } + + get completedStages() { + return this.completed + } + + complete(stageId: string) { + this.completed.push(stageId) + } +} diff --git a/packages/game/src/Stage.ts b/packages/game/src/Stage.ts index 579bb74..e440488 100644 --- a/packages/game/src/Stage.ts +++ b/packages/game/src/Stage.ts @@ -1,15 +1,17 @@ -import { IStage, ICommand, IFileExistenceChecker } from './types' +import { IStage, ICommand, IFileExistenceChecker, ISession } from './types' import { Condition } from './condition/Condition' export class Stage { id: string name: string - condition: Condition + private condition: Condition + private requirements: string[] - constructor({ id, name, condition }: IStage) { + constructor({ id, name, condition, requirements }: IStage) { this.id = id - this.name = name + this.name = name || '' this.condition = new Condition(condition) + this.requirements = requirements || [] } async satisfies( @@ -18,4 +20,18 @@ export class Stage { ): Promise { return this.condition.match(command) && this.condition.check(checker) } + + private checkRequirements(session: ISession): boolean { + return this.requirements.every((req) => + session.completedStages.includes(req) + ) + } + + private finished(session: ISession): boolean { + return session.completedStages.includes(this.id) + } + + active(session: ISession): boolean { + return !this.finished(session) && this.checkRequirements(session) + } } diff --git a/packages/game/src/types.ts b/packages/game/src/types.ts index 52fff79..972200f 100644 --- a/packages/game/src/types.ts +++ b/packages/game/src/types.ts @@ -35,6 +35,11 @@ export interface IFileExistenceChecker { export interface IStage { id: string - name: string + name?: string + requirements?: string[] condition: ICondition } + +export interface ISession { + completedStages: string[] +} diff --git a/packages/game/test/stage.test.ts b/packages/game/test/stage.test.ts index 5631e21..de81ade 100644 --- a/packages/game/test/stage.test.ts +++ b/packages/game/test/stage.test.ts @@ -2,6 +2,7 @@ import { test, expect } from '@jest/globals' import { Stage } from '../src/Stage' import { FileType } from '../src/types' import { MockFileChecker } from './asyncCondition.test' +import { Session } from '../src/Session' const checker = new MockFileChecker() @@ -67,3 +68,21 @@ test('check stage with async condition falsy', async () => { }) expect(await stage.satisfies({}, checker)).toBe(false) }) + +test('stage active checks', () => { + const session = new Session({ + completedStages: ['stage1'], + }) + const stage3 = new Stage({ + id: 'stage3', + requirements: ['stage1', 'stage2'], + condition: {}, + }) + expect(stage3.active(session)).toBe(false) + + session.complete('stage2') + expect(stage3.active(session)).toBe(true) + + session.complete('stage3') + expect(stage3.active(session)).toBe(false) +}) From e66598f1a76fcf44fe22ed0e4fd3f0ab3b0ddab7 Mon Sep 17 00:00:00 2001 From: Justin Lin Date: Wed, 28 Aug 2024 14:52:45 +0800 Subject: [PATCH 18/19] chore: update dependencies --- package.json | 3 +- yarn.lock | 134 +++++++++++---------------------------------------- 2 files changed, 30 insertions(+), 107 deletions(-) diff --git a/package.json b/package.json index bbd58c8..1185bbb 100644 --- a/package.json +++ b/package.json @@ -56,5 +56,6 @@ "dependencies": { "latest": "^0.2.0", "typescript-eslint": "^7.4.0" - } + }, + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" } diff --git a/yarn.lock b/yarn.lock index 4279b4b..746b92f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34,27 +34,6 @@ integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9", "@babel/core@^7.24.0": - version "7.24.0" - resolved "https://registry.npmjs.org/@babel/core/-/core-7.24.0.tgz" - integrity sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.23.5" - "@babel/generator" "^7.23.6" - "@babel/helper-compilation-targets" "^7.23.6" - "@babel/helper-module-transforms" "^7.23.3" - "@babel/helpers" "^7.24.0" - "@babel/parser" "^7.24.0" - "@babel/template" "^7.24.0" - "@babel/traverse" "^7.24.0" - "@babel/types" "^7.24.0" - convert-source-map "^2.0.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.3" - semver "^6.3.1" - -"@babel/core@^7.24.0": version "7.24.0" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.0.tgz#56cbda6b185ae9d9bed369816a8f4423c5f2ff1b" integrity sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw== @@ -198,29 +177,6 @@ "@babel/types" "^7.22.5" "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.24.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.24.0" - resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz" - integrity sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w== - -"@babel/helper-remap-async-to-generator@^7.22.20": - version "7.22.20" - resolved "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz" - integrity sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-wrap-function" "^7.22.20" - -"@babel/helper-replace-supers@^7.22.20": - version "7.22.20" - resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz" - integrity sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw== - dependencies: - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-member-expression-to-functions" "^7.22.15" - "@babel/helper-optimise-call-expression" "^7.22.5" - -"@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.24.0", "@babel/helper-plugin-utils@^7.8.3": version "7.24.0" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz#945681931a52f15ce879fd5b86ce2dae6d3d7f2a" integrity sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w== @@ -288,15 +244,6 @@ "@babel/template" "^7.22.15" "@babel/types" "^7.22.19" -"@babel/helpers@^7.24.0": - version "7.24.0" - resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.0.tgz" - integrity sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA== - dependencies: - "@babel/template" "^7.24.0" - "@babel/traverse" "^7.24.0" - "@babel/types" "^7.24.0" - "@babel/helpers@^7.24.0": version "7.24.0" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.0.tgz#a3dd462b41769c95db8091e49cfe019389a9409b" @@ -316,40 +263,6 @@ js-tokens "^4.0.0" "@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.24.0": - version "7.24.0" - resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz" - integrity sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg== - -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.23.3": - version "7.23.3" - resolved "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz" - integrity sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.23.3": - version "7.23.3" - resolved "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz" - integrity sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" - "@babel/plugin-transform-optional-chaining" "^7.23.3" - -"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.23.7": - version "7.23.7" - resolved "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz" - integrity sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw== - dependencies: - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": - version "7.21.0-placeholder-for-preset-env.2" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz" - integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== - -"@babel/parser@^7.24.0": version "7.24.0" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.0.tgz#26a3d1ff49031c53a97d03b604375f028746a9ac" integrity sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg== @@ -1073,15 +986,6 @@ globals "^11.1.0" "@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.6", "@babel/types@^7.24.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": - version "7.24.0" - resolved "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz" - integrity sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w== - dependencies: - "@babel/helper-string-parser" "^7.23.4" - "@babel/helper-validator-identifier" "^7.22.20" - to-fast-properties "^2.0.0" - -"@babel/types@^7.22.19", "@babel/types@^7.24.0", "@babel/types@^7.4.4": version "7.24.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.0.tgz#3b951f435a92e7333eba05b7566fd297960ea1bf" integrity sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w== @@ -3650,13 +3554,6 @@ cookie@0.6.0: resolved "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz" integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== -core-js-compat@^3.31.0, core-js-compat@^3.34.0: - version "3.36.0" - resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.0.tgz" - integrity sha512-iV9Pd/PsgjNWBXeq8XRtWVSgz2tKAfhfvBs7qxYty+RlRd+OCksaWmOnc4JKrTc1cToXL1N0s3l/vwlxPtdElw== - dependencies: - browserslist "^4.22.3" - core-js-compat@^3.31.0, core-js-compat@^3.34.0: version "3.36.0" resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.36.0.tgz#087679119bc2fdbdefad0d45d8e5d307d45ba190" @@ -8734,7 +8631,7 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -8752,6 +8649,15 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string-width@^5.0.1, string-width@^5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" @@ -8812,7 +8718,7 @@ stringstream@~0.0.4: resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.6.tgz#7880225b0d4ad10e30927d167a1d6f2fd3b33a72" integrity sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA== -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -8826,6 +8732,13 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1, strip-ansi@~3.0.1: dependencies: ansi-regex "^2.0.0" +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + 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" + strip-ansi@^7.0.1: version "7.1.0" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz" @@ -9678,7 +9591,7 @@ wordwrap@^1.0.0: resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz" integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -9696,6 +9609,15 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + 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" + wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz" From 19c44fbe5259d7fb52ac15b04548921e79d14587 Mon Sep 17 00:00:00 2001 From: Justin Lin Date: Thu, 10 Oct 2024 16:22:20 +0800 Subject: [PATCH 19/19] wip: game schema --- packages/game/package.json | 4 +- packages/game/src/schema/condition.ts | 0 packages/game/src/schema/index.ts | 54 ++++++++++++++++++++++++ packages/game/src/schema/requirements.ts | 0 packages/game/src/schema/stage.ts | 0 packages/game/test/condition.test.ts | 12 ++++++ yarn.lock | 2 +- 7 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 packages/game/src/schema/condition.ts create mode 100644 packages/game/src/schema/index.ts create mode 100644 packages/game/src/schema/requirements.ts create mode 100644 packages/game/src/schema/stage.ts diff --git a/packages/game/package.json b/packages/game/package.json index 7e6a856..5854459 100644 --- a/packages/game/package.json +++ b/packages/game/package.json @@ -6,5 +6,7 @@ "scripts": { "build": "tsc -b" }, - "dependencies": {} + "dependencies": { + "zod": "^3.23.8" + } } diff --git a/packages/game/src/schema/condition.ts b/packages/game/src/schema/condition.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/game/src/schema/index.ts b/packages/game/src/schema/index.ts new file mode 100644 index 0000000..f21337b --- /dev/null +++ b/packages/game/src/schema/index.ts @@ -0,0 +1,54 @@ +import { z } from 'zod' + +export const requirementsSchema = z.object({ + requirements: z.array(z.string()), +}) + +export type IRequirements = z.infer + +export const fileInputSchema = z.object({ + path: z.string(), + type: z.enum(['file', 'folder']), +}) + +export type IFileInput = z.infer + +export const fileExistenceInputSchema = fileInputSchema.extend({ + exists: z.boolean(), +}) + +export type IFileExistenceInput = z.infer + +const baseConditionSchema = z.object({ + command: z.string().optional(), + output: z.string().optional(), + error: z.string().optional(), + pwd: z.string().optional(), + files: z.array(fileExistenceInputSchema).optional(), +}) + +export type ICondition = z.infer & { + or?: ICondition[] + not?: ICondition +} + +export const conditionSchema: z.ZodType = + baseConditionSchema.extend({ + or: z.lazy(() => z.array(conditionSchema)).optional(), + not: z.lazy(() => conditionSchema).optional(), + }) + +export const responseSchema = z.object({ + type: z.enum(['narrative', 'dialogue']), + content: z.string(), +}) + +export const stageSchema = z.object({ + id: z.string().regex(/^[a-zA-Z0-9_-]+$/), + name: z.string().optional(), + requirements: z.array(z.string()), + condition: conditionSchema, + response: responseSchema, +}) + +export type IStage = z.infer diff --git a/packages/game/src/schema/requirements.ts b/packages/game/src/schema/requirements.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/game/src/schema/stage.ts b/packages/game/src/schema/stage.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/game/test/condition.test.ts b/packages/game/test/condition.test.ts index 11dd056..ad05f5c 100644 --- a/packages/game/test/condition.test.ts +++ b/packages/game/test/condition.test.ts @@ -4,6 +4,7 @@ import { OutputMatcher } from '../src/condition/OutputMatcher' import { PwdMatcher } from '../src/condition/PwdMatcher' import { CommandMatcher } from '../src/condition/CommandMatcher' import { ErrorMatcher } from '../src/condition/ErrorMatcher.js' +import { conditionSchema } from '../src/schema' test('command match', () => { const matcher = new CommandMatcher('^echo start$') @@ -80,3 +81,14 @@ test('condition with NOT', () => { expect(condition.match({ command: 'echo start' })).toBe(false) expect(condition.match({ command: 'echo hello' })).toBe(true) }) + +it('should parse condition', () => { + const condition = { + command: 'echo start', + output: 'start', + not: { + pwd: '/home/user', + }, + } + expect(conditionSchema.safeParse(condition).error).toBeUndefined() +}) diff --git a/yarn.lock b/yarn.lock index 746b92f..13fbb96 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9747,5 +9747,5 @@ yocto-queue@^0.1.0: zod@^3.23.8: version "3.23.8" - resolved "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d" integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==