diff --git a/.github/workflows/test-pr.yaml b/.github/workflows/test-pr.yaml index 6f67d7811..d270a86c0 100644 --- a/.github/workflows/test-pr.yaml +++ b/.github/workflows/test-pr.yaml @@ -11,6 +11,16 @@ jobs: - uses: actions/checkout@v3 - uses: ./.github/workflows/setup + unit-test: + needs: build + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + - uses: ./.github/workflows/setup + + - name: Run unit tests + run: npm run test:cli + test: needs: [build] runs-on: ${{ matrix.runs-on }} diff --git a/package-lock.json b/package-lock.json index cfb560806..04f67c84e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -69,6 +69,7 @@ "tree-sitter-scala": "^0.24.0", "tree-sitter-typescript": "^0.23.2", "ts-node": "^10.9.2", + "vitest": "^3.1.4", "watch": "^1.0.2", "web-tree-sitter": "^0.26.9" }, @@ -281,640 +282,1442 @@ "node": ">=12" } }, - "node_modules/@esbuild/win32-x64": { - "version": "0.20.2", + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", "cpu": [ - "x64" + "ppc64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "win32" + "aix" ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", + "node_modules/@esbuild/android-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + "node": ">=18" } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", + "node_modules/@esbuild/android-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + "node": ">=18" } }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", + "node_modules/@esbuild/android-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=18" } }, - "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/@eslint/eslintrc/node_modules/fast-deep-equal": { - "version": "3.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { - "version": "0.4.1", - "dev": true, - "license": "MIT" - }, - "node_modules/@eslint/js": { - "version": "8.57.0", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=18" } }, - "node_modules/@glideapps/ts-necessities": { - "version": "2.2.3", - "license": "MIT" - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=10.10.0" + "node": ">=18" } }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", + "node_modules/@esbuild/linux-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", + "cpu": [ + "arm" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "node": ">=18" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", + "cpu": [ + "ia32" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "node": ">=18" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", + "cpu": [ + "loong64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=18" } }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "dev": true, - "license": "MIT" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", + "cpu": [ + "mips64el" + ], "dev": true, "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=18" } }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", + "cpu": [ + "ppc64" + ], "dev": true, "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": ">=18" } }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", + "cpu": [ + "riscv64" + ], "dev": true, "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": ">=18" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", + "cpu": [ + "s390x" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", + "node_modules/@esbuild/linux-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", + "cpu": [ + "x64" + ], + "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.0.0" + "node": ">=18" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", + "cpu": [ + "arm64" + ], + "dev": true, "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@mark.probst/typescript-json-schema": { - "version": "0.55.0", - "license": "BSD-3-Clause", - "dependencies": { - "@types/json-schema": "^7.0.9", - "@types/node": "^16.9.2", - "glob": "^7.1.7", - "path-equal": "^1.1.2", - "safe-stable-stringify": "^2.2.0", - "ts-node": "^10.9.1", - "typescript": "4.9.4", - "yargs": "^17.1.1" - }, - "bin": { - "typescript-json-schema": "bin/typescript-json-schema" + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@mark.probst/typescript-json-schema/node_modules/@types/node": { - "version": "16.18.11", - "license": "MIT" - }, - "node_modules/@mark.probst/typescript-json-schema/node_modules/typescript": { - "version": "4.9.4", - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">=4.2.0" + "node": ">=18" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">= 8" + "node": ">=18" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], "engines": { - "node": ">= 8" + "node": ">=18" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, + "optional": true, + "os": [ + "sunos" + ], "engines": { - "node": ">= 8" + "node": ">=18" } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=14" + "node": ">=18" } }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", + "cpu": [ + "ia32" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">= 6" + "node": ">=18" } }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "license": "MIT" - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "license": "MIT" + "node_modules/@esbuild/win32-x64": { + "version": "0.20.2", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "license": "MIT" + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } }, - "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "license": "MIT" + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } }, - "node_modules/@tsconfig/node18": { - "version": "1.0.1", + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } }, - "node_modules/@types/browser-or-node": { - "version": "1.3.2", + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } }, - "node_modules/@types/command-line-args": { - "version": "5.2.0", + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", "dev": true, - "license": "MIT" + "license": "Python-2.0" }, - "node_modules/@types/command-line-usage": { - "version": "5.0.4", + "node_modules/@eslint/eslintrc/node_modules/fast-deep-equal": { + "version": "3.1.3", "dev": true, "license": "MIT" }, - "node_modules/@types/glob": { - "version": "7.2.0", + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", "dev": true, "license": "MIT", "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@types/graphql": { - "version": "0.11.8", + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", "dev": true, "license": "MIT" }, - "node_modules/@types/is-url": { - "version": "1.2.32", - "resolved": "https://registry.npmjs.org/@types/is-url/-/is-url-1.2.32.tgz", - "integrity": "sha512-46VLdbWI8Sc+hPexQ6NLNR2YpoDyDZIpASHkJQ2Yr+Kf9Giw6LdCTkwOdsnHKPQeh7xTjTmSnxbE8qpxYuCiHA==", - "dev": true - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", + "node_modules/@eslint/js": { + "version": "8.57.0", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } }, - "node_modules/@types/json-schema": { - "version": "7.0.15", + "node_modules/@glideapps/ts-necessities": { + "version": "2.2.3", "license": "MIT" }, - "node_modules/@types/lodash": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz", - "integrity": "sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==", - "dev": true - }, - "node_modules/@types/minimatch": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/mocha": { - "version": "10.0.6", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "22.14.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.1.tgz", - "integrity": "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/@types/node-persist": { - "version": "3.1.8", + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@types/node": "*" + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" } }, - "node_modules/@types/pako": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/pluralize": { - "version": "0.0.30", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/readable-stream": { - "version": "4.0.10", + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "safe-buffer": "~5.1.1" + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@types/semver": { - "version": "7.5.8", + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", "dev": true, - "license": "MIT" + "license": "BSD-3-Clause" }, - "node_modules/@types/shelljs": { - "version": "0.8.15", + "node_modules/@isaacs/cliui": { + "version": "8.0.2", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "@types/glob": "~7.2.0", - "@types/node": "*" + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" } }, - "node_modules/@types/stream-chain": { - "version": "2.0.1", + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", "dev": true, "license": "MIT", - "dependencies": { - "@types/node": "*" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/@types/stream-json": { - "version": "1.7.3", + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", "dev": true, "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/stream-chain": "*" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@types/unicode-properties": { - "version": "1.3.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/urijs": { - "version": "1.19.25", - "license": "MIT" - }, - "node_modules/@types/vscode": { - "version": "1.88.0", + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", "dev": true, "license": "MIT" }, - "node_modules/@types/wordwrap": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@types/wordwrap/-/wordwrap-1.0.3.tgz", - "integrity": "sha512-jx39cOYWJxZxVOZeNHvLVoDLRUFcYtIJaurC6C0qzCovIB3GPDbMDbYvoWi9D1B2PtIE16rElQOFR4Y+8QbUgw==", - "dev": true - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", - "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/type-utils": "6.21.0", - "@typescript-eslint/utils": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": ">=12" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@typescript-eslint/parser": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", - "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4" + "ansi-regex": "^6.0.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": ">=12" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": ">=12" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", - "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/utils": "6.21.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" - }, + "license": "MIT", "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=8" } }, - "node_modules/@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", - "dev": true, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "license": "MIT", "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=6.0.0" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", - "dev": true, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "6.21.0", + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@mark.probst/typescript-json-schema": { + "version": "0.55.0", + "license": "BSD-3-Clause", + "dependencies": { + "@types/json-schema": "^7.0.9", + "@types/node": "^16.9.2", + "glob": "^7.1.7", + "path-equal": "^1.1.2", + "safe-stable-stringify": "^2.2.0", + "ts-node": "^10.9.1", + "typescript": "4.9.4", + "yargs": "^17.1.1" + }, + "bin": { + "typescript-json-schema": "bin/typescript-json-schema" + } + }, + "node_modules/@mark.probst/typescript-json-schema/node_modules/@types/node": { + "version": "16.18.11", + "license": "MIT" + }, + "node_modules/@mark.probst/typescript-json-schema/node_modules/typescript": { + "version": "4.9.4", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.2.tgz", + "integrity": "sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.2.tgz", + "integrity": "sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.2.tgz", + "integrity": "sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.2.tgz", + "integrity": "sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.2.tgz", + "integrity": "sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.2.tgz", + "integrity": "sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.2.tgz", + "integrity": "sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.2.tgz", + "integrity": "sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.2.tgz", + "integrity": "sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.2.tgz", + "integrity": "sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.2.tgz", + "integrity": "sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.2.tgz", + "integrity": "sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.2.tgz", + "integrity": "sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.2.tgz", + "integrity": "sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.2.tgz", + "integrity": "sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.2.tgz", + "integrity": "sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.2.tgz", + "integrity": "sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.2.tgz", + "integrity": "sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.2.tgz", + "integrity": "sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.2.tgz", + "integrity": "sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.2.tgz", + "integrity": "sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.2.tgz", + "integrity": "sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.2.tgz", + "integrity": "sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.2.tgz", + "integrity": "sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.2.tgz", + "integrity": "sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/@tsconfig/node18": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/browser-or-node": { + "version": "1.3.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/command-line-args": { + "version": "5.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/command-line-usage": { + "version": "5.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/graphql": { + "version": "0.11.8", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/is-url": { + "version": "1.2.32", + "resolved": "https://registry.npmjs.org/@types/is-url/-/is-url-1.2.32.tgz", + "integrity": "sha512-46VLdbWI8Sc+hPexQ6NLNR2YpoDyDZIpASHkJQ2Yr+Kf9Giw6LdCTkwOdsnHKPQeh7xTjTmSnxbE8qpxYuCiHA==", + "dev": true + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "license": "MIT" + }, + "node_modules/@types/lodash": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz", + "integrity": "sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==", + "dev": true + }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mocha": { + "version": "10.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.14.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.1.tgz", + "integrity": "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/node-persist": { + "version": "3.1.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/pako": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/pluralize": { + "version": "0.0.30", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/readable-stream": { + "version": "4.0.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/@types/semver": { + "version": "7.5.8", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/shelljs": { + "version": "0.8.15", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/glob": "~7.2.0", + "@types/node": "*" + } + }, + "node_modules/@types/stream-chain": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/stream-json": { + "version": "1.7.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/stream-chain": "*" + } + }, + "node_modules/@types/unicode-properties": { + "version": "1.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/urijs": { + "version": "1.19.25", + "license": "MIT" + }, + "node_modules/@types/vscode": { + "version": "1.88.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/wordwrap": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/wordwrap/-/wordwrap-1.0.3.tgz", + "integrity": "sha512-jx39cOYWJxZxVOZeNHvLVoDLRUFcYtIJaurC6C0qzCovIB3GPDbMDbYvoWi9D1B2PtIE16rElQOFR4Y+8QbUgw==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", + "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/type-utils": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", + "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "globby": "^11.1.0", @@ -924,163 +1727,753 @@ "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "dev": true, + "license": "ISC" + }, + "node_modules/@vitest/expect": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.7.tgz", + "integrity": "sha512-E8eBXaKibuvH2pSZErOjdVb5vF4PbKYcrnluBTYxEk1l/VhhwZg1kZQsdtjq+CsF5CFydf2Rdkz7jDHKSisi3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.7", + "@vitest/utils": "3.2.7", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.7.tgz", + "integrity": "sha512-Trr0hYO9CM3Wj6ksWHRhK9IZpIY6wTMO5u/MqXurMxT57sWBaOPEtP3Oq60ihZuh5JsiagKfz95OcxdEP6dBrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.2.7", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/mocker/node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.7.tgz", + "integrity": "sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.7.tgz", + "integrity": "sha512-sB9y4ovltoQP+WaUPwmSxO9WIg9Ig694Di5PalVPsYHklAdE027mehpWF2SQSVq+k6sFgaivbTjTJwZLSHbedA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "3.2.7", + "pathe": "^2.0.3", + "strip-literal": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.7.tgz", + "integrity": "sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.7", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot/node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/@vitest/spy": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.7.tgz", + "integrity": "sha512-Q2eQGI6d2L/hBtZ0qNuKcAGid68XK6cv1xsoaIma6PaJhHPoqcEJhYpXZ/5myCMqkNgtP6UKuBhbc0nHKnrkuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^4.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.7.tgz", + "integrity": "sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.7", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vscode/test-cli": { + "version": "0.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mocha": "^10.0.2", + "c8": "^9.1.0", + "chokidar": "^3.5.3", + "enhanced-resolve": "^5.15.0", + "glob": "^10.3.10", + "minimatch": "^9.0.3", + "mocha": "^10.2.0", + "supports-color": "^9.4.0", + "yargs": "^17.7.2" + }, + "bin": { + "vscode-test": "out/bin.mjs" + } + }, + "node_modules/@vscode/test-cli/node_modules/brace-expansion": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@vscode/test-cli/node_modules/glob": { + "version": "10.3.12", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.6", + "minimatch": "^9.0.1", + "minipass": "^7.0.4", + "path-scurry": "^1.10.2" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@vscode/test-cli/node_modules/minimatch": { + "version": "9.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@vscode/test-cli/node_modules/supports-color": { + "version": "9.4.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@vscode/test-cli/node_modules/yargs": { + "version": "17.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@vscode/test-electron": { + "version": "2.3.9", + "dev": true, + "license": "MIT", + "dependencies": { + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "jszip": "^3.10.1", + "semver": "^7.5.2" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@vscode/vsce": { + "version": "2.25.0", + "dev": true, + "license": "MIT", + "dependencies": { + "azure-devops-node-api": "^12.5.0", + "chalk": "^2.4.2", + "cheerio": "^1.0.0-rc.9", + "cockatiel": "^3.1.2", + "commander": "^6.2.1", + "form-data": "^4.0.0", + "glob": "^7.0.6", + "hosted-git-info": "^4.0.2", + "jsonc-parser": "^3.2.0", + "leven": "^3.1.0", + "markdown-it": "^12.3.2", + "mime": "^1.3.4", + "minimatch": "^3.0.3", + "parse-semver": "^1.1.1", + "read": "^1.0.7", + "semver": "^7.5.2", + "tmp": "^0.2.1", + "typed-rest-client": "^1.8.4", + "url-join": "^4.0.1", + "xml2js": "^0.5.0", + "yauzl": "^2.3.1", + "yazl": "^2.2.2" + }, + "bin": { + "vsce": "vsce" + }, + "engines": { + "node": ">= 16" + }, + "optionalDependencies": { + "keytar": "^7.7.0" + } + }, + "node_modules/@vscode/vsce/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@vscode/vsce/node_modules/commander": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/acorn": { + "version": "8.11.3", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "5.5.2", + "dev": true, + "license": "MIT", + "dependencies": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "license": "MIT" + }, + "node_modules/array-back": { + "version": "3.1.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/assertion-error": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" + "license": "MIT", + "engines": { + "node": ">=12" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "node_modules/asynckit": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", "dev": true, + "license": "MIT", "dependencies": { - "brace-expansion": "^2.0.1" + "possible-typed-array-names": "^1.0.0" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@typescript-eslint/utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", - "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "node_modules/azure-devops-node-api": { + "version": "12.5.0", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "semver": "^7.5.4" - }, + "tunnel": "0.0.6", + "typed-rest-client": "^1.8.4" + } + }, + "node_modules/balanced-match": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "dev": true, + "license": "MIT", "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": ">=8" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "node_modules/bl": { + "version": "4.1.0", "dev": true, + "license": "MIT", + "optional": true, "dependencies": { - "@typescript-eslint/types": "6.21.0", - "eslint-visitor-keys": "^3.4.1" + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/buffer": { + "version": "5.7.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.2", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">= 6" } }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", + "node_modules/boolbase": { + "version": "1.0.0", "dev": true, "license": "ISC" }, - "node_modules/@vscode/test-cli": { - "version": "0.0.6", - "dev": true, + "node_modules/brace-expansion": { + "version": "1.1.11", "license": "MIT", "dependencies": { - "@types/mocha": "^10.0.2", - "c8": "^9.1.0", - "chokidar": "^3.5.3", - "enhanced-resolve": "^5.15.0", - "glob": "^10.3.10", - "minimatch": "^9.0.3", - "mocha": "^10.2.0", - "supports-color": "^9.4.0", - "yargs": "^17.7.2" - }, - "bin": { - "vscode-test": "out/bin.mjs" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@vscode/test-cli/node_modules/brace-expansion": { - "version": "2.0.1", + "node_modules/braces": { + "version": "3.0.2", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@vscode/test-cli/node_modules/glob": { - "version": "10.3.12", + "node_modules/brfs": { + "version": "1.6.1", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.6", - "minimatch": "^9.0.1", - "minipass": "^7.0.4", - "path-scurry": "^1.10.2" + "quote-stream": "^1.0.1", + "resolve": "^1.1.5", + "static-module": "^2.2.0", + "through2": "^2.0.0" }, "bin": { - "glob": "dist/esm/bin.mjs" - }, + "brfs": "bin/cmd.js" + } + }, + "node_modules/browser-or-node": { + "version": "3.0.0", + "license": "MIT" + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "dev": true, + "license": "ISC" + }, + "node_modules/buffer": { + "version": "6.0.3", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-equal": { + "version": "0.0.1", + "dev": true, + "license": "MIT", "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=0.4.0" } }, - "node_modules/@vscode/test-cli/node_modules/minimatch": { - "version": "9.0.4", + "node_modules/buffer-from": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/c8": { + "version": "9.1.0", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "@bcoe/v8-coverage": "^0.2.3", + "@istanbuljs/schema": "^0.1.3", + "find-up": "^5.0.0", + "foreground-child": "^3.1.1", + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.1.6", + "test-exclude": "^6.0.0", + "v8-to-istanbul": "^9.0.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1" }, - "engines": { - "node": ">=16 || 14 >=14.17" + "bin": { + "c8": "bin/c8.js" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@vscode/test-cli/node_modules/supports-color": { - "version": "9.4.0", - "dev": true, - "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "node": ">=14.14.0" } }, - "node_modules/@vscode/test-cli/node_modules/yargs": { + "node_modules/c8/node_modules/yargs": { "version": "17.7.2", "dev": true, "license": "MIT", @@ -1097,479 +2490,422 @@ "node": ">=12" } }, - "node_modules/@vscode/test-electron": { - "version": "2.3.9", + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", "dev": true, "license": "MIT", - "dependencies": { - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "jszip": "^3.10.1", - "semver": "^7.5.2" - }, "engines": { - "node": ">=16" + "node": ">=8" } }, - "node_modules/@vscode/vsce": { - "version": "2.25.0", + "node_modules/call-bind": { + "version": "1.0.7", "dev": true, "license": "MIT", "dependencies": { - "azure-devops-node-api": "^12.5.0", - "chalk": "^2.4.2", - "cheerio": "^1.0.0-rc.9", - "cockatiel": "^3.1.2", - "commander": "^6.2.1", - "form-data": "^4.0.0", - "glob": "^7.0.6", - "hosted-git-info": "^4.0.2", - "jsonc-parser": "^3.2.0", - "leven": "^3.1.0", - "markdown-it": "^12.3.2", - "mime": "^1.3.4", - "minimatch": "^3.0.3", - "parse-semver": "^1.1.1", - "read": "^1.0.7", - "semver": "^7.5.2", - "tmp": "^0.2.1", - "typed-rest-client": "^1.8.4", - "url-join": "^4.0.1", - "xml2js": "^0.5.0", - "yauzl": "^2.3.1", - "yazl": "^2.2.2" - }, - "bin": { - "vsce": "vsce" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" }, "engines": { - "node": ">= 16" + "node": ">= 0.4" }, - "optionalDependencies": { - "keytar": "^7.7.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@vscode/vsce/node_modules/chalk": { - "version": "2.4.2", + "node_modules/callsites": { + "version": "3.1.0", "dev": true, "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, "engines": { - "node": ">=4" + "node": ">=6" } }, - "node_modules/@vscode/vsce/node_modules/commander": { - "version": "6.2.1", + "node_modules/camelcase": { + "version": "6.3.0", "dev": true, "license": "MIT", "engines": { - "node": ">= 6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/abort-controller": { - "version": "3.0.0", + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "dev": true, "license": "MIT", "dependencies": { - "event-target-shim": "^5.0.0" + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" }, "engines": { - "node": ">=6.5" + "node": ">=18" } }, - "node_modules/acorn": { - "version": "8.11.3", + "node_modules/chalk": { + "version": "4.1.2", "license": "MIT", - "bin": { - "acorn": "bin/acorn" + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/acorn-walk": { - "version": "8.2.0", + "node_modules/chalk-template": { + "version": "0.4.0", "license": "MIT", + "dependencies": { + "chalk": "^4.1.2" + }, "engines": { - "node": ">=0.4.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/chalk-template?sponsor=1" } }, - "node_modules/agent-base": { - "version": "6.0.2", - "dev": true, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", "license": "MIT", "dependencies": { - "debug": "4" + "color-convert": "^2.0.1" }, "engines": { - "node": ">= 6.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/ajv": { - "version": "5.5.2", - "dev": true, + "node_modules/chalk/node_modules/color-convert": { + "version": "2.0.1", "license": "MIT", "dependencies": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "dev": true, - "license": "MIT", + "color-name": "~1.1.4" + }, "engines": { - "node": ">=6" + "node": ">=7.0.0" } }, - "node_modules/ansi-regex": { - "version": "5.0.1", + "node_modules/chalk/node_modules/has-flag": { + "version": "4.0.0", "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "dev": true, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/anymatch": { - "version": "3.1.3", + "node_modules/check-error": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "license": "MIT" - }, - "node_modules/array-back": { - "version": "3.1.0", "license": "MIT", "engines": { - "node": ">=6" + "node": ">= 16" } }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "node_modules/cheerio": { + "version": "1.0.0-rc.12", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">= 6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" } }, - "node_modules/array-union": { + "node_modules/cheerio-select": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, - "engines": { - "node": ">=8" + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "dev": true, - "license": "MIT" - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", + "node_modules/chokidar": { + "version": "3.6.0", "dev": true, "license": "MIT", "dependencies": { - "possible-typed-array-names": "^1.0.0" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, "engines": { - "node": ">= 0.4" + "node": ">= 8.10.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/azure-devops-node-api": { - "version": "12.5.0", + "node_modules/chownr": { + "version": "1.1.4", "dev": true, - "license": "MIT", + "license": "ISC", + "optional": true + }, + "node_modules/cliui": { + "version": "8.0.1", + "license": "ISC", "dependencies": { - "tunnel": "0.0.6", - "typed-rest-client": "^1.8.4" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, - "node_modules/balanced-match": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/binary-extensions": { - "version": "2.3.0", + "node_modules/co": { + "version": "4.6.0", "dev": true, "license": "MIT", "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" } }, - "node_modules/bl": { - "version": "4.1.0", + "node_modules/cockatiel": { + "version": "3.1.2", "dev": true, "license": "MIT", - "optional": true, - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" + "engines": { + "node": ">=16" } }, - "node_modules/bl/node_modules/buffer": { - "version": "5.7.1", + "node_modules/collection-utils": { + "version": "1.0.1", + "license": "Apache-2.0" + }, + "node_modules/color-convert": { + "version": "1.9.3", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], "license": "MIT", - "optional": true, "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "color-name": "1.1.3" } }, - "node_modules/bl/node_modules/readable-stream": { - "version": "3.6.2", + "node_modules/color-convert/node_modules/color-name": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/color-name": { + "version": "1.1.4", + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "delayed-stream": "~1.0.0" }, "engines": { - "node": ">= 6" + "node": ">= 0.8" } }, - "node_modules/boolbase": { - "version": "1.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", + "node_modules/command-line-args": { + "version": "5.2.1", "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + }, + "engines": { + "node": ">=4.0.0" } }, - "node_modules/braces": { - "version": "3.0.2", - "dev": true, + "node_modules/command-line-usage": { + "version": "7.0.1", "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "array-back": "^6.2.2", + "chalk-template": "^0.4.0", + "table-layout": "^3.0.0", + "typical": "^7.1.1" }, "engines": { - "node": ">=8" + "node": ">=12.20.0" } }, - "node_modules/brfs": { - "version": "1.6.1", - "dev": true, + "node_modules/command-line-usage/node_modules/array-back": { + "version": "6.2.2", "license": "MIT", - "dependencies": { - "quote-stream": "^1.0.1", - "resolve": "^1.1.5", - "static-module": "^2.2.0", - "through2": "^2.0.0" - }, - "bin": { - "brfs": "bin/cmd.js" + "engines": { + "node": ">=12.17" } }, - "node_modules/browser-or-node": { - "version": "3.0.0", + "node_modules/command-line-usage/node_modules/typical": { + "version": "7.1.1", + "license": "MIT", + "engines": { + "node": ">=12.17" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", "license": "MIT" }, - "node_modules/browser-stdout": { - "version": "1.3.1", + "node_modules/concat-stream": { + "version": "1.6.2", "dev": true, - "license": "ISC" - }, - "node_modules/buffer": { - "version": "6.0.3", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } + "engines": [ + "node >= 0.8" ], "license": "MIT", "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" } }, - "node_modules/buffer-crc32": { - "version": "0.2.13", + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.8", "dev": true, "license": "MIT", - "engines": { - "node": "*" + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "node_modules/buffer-equal": { - "version": "0.0.1", + "node_modules/convert-source-map": { + "version": "2.0.0", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } + "license": "MIT" }, - "node_modules/buffer-from": { - "version": "1.1.2", - "dev": true, + "node_modules/core-util-is": { + "version": "1.0.3", "license": "MIT" }, - "node_modules/c8": { - "version": "9.1.0", - "dev": true, - "license": "ISC", + "node_modules/create-require": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/cross-fetch": { + "version": "4.0.0", + "license": "MIT", "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@istanbuljs/schema": "^0.1.3", - "find-up": "^5.0.0", - "foreground-child": "^3.1.1", - "istanbul-lib-coverage": "^3.2.0", - "istanbul-lib-report": "^3.0.1", - "istanbul-reports": "^3.1.6", - "test-exclude": "^6.0.0", - "v8-to-istanbul": "^9.0.0", - "yargs": "^17.7.2", - "yargs-parser": "^21.1.1" - }, - "bin": { - "c8": "bin/c8.js" - }, - "engines": { - "node": ">=14.14.0" + "node-fetch": "^2.6.12" } }, - "node_modules/c8/node_modules/yargs": { - "version": "17.7.2", + "node_modules/cross-spawn": { + "version": "7.0.3", "dev": true, "license": "MIT", "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": ">=12" + "node": ">= 8" } }, - "node_modules/call-bind": { - "version": "1.0.7", + "node_modules/css-select": { + "version": "5.1.0", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "dev": true, + "license": "BSD-2-Clause", "engines": { - "node": ">= 0.4" + "node": ">= 6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/fb55" } }, - "node_modules/callsites": { - "version": "3.1.0", + "node_modules/debug": { + "version": "4.3.4", "dev": true, "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, "engines": { - "node": ">=6" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/camelcase": { - "version": "6.3.0", + "node_modules/decamelize": { + "version": "4.0.0", "dev": true, "license": "MIT", "engines": { @@ -1579,258 +2915,220 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/chalk": { - "version": "4.1.2", + "node_modules/decompress-response": { + "version": "6.0.0", + "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "mimic-response": "^3.1.0" }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/chalk-template": { - "version": "0.4.0", + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, "license": "MIT", - "dependencies": { - "chalk": "^4.1.2" - }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/chalk-template?sponsor=1" + "node": ">=6" } }, - "node_modules/chalk/node_modules/ansi-styles": { - "version": "4.3.0", + "node_modules/deep-equal": { + "version": "2.2.3", + "dev": true, "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/chalk/node_modules/color-convert": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } + "node_modules/deep-equal/node_modules/isarray": { + "version": "2.0.5", + "dev": true, + "license": "MIT" }, - "node_modules/chalk/node_modules/has-flag": { - "version": "4.0.0", + "node_modules/deep-extend": { + "version": "0.6.0", + "dev": true, "license": "MIT", + "optional": true, "engines": { - "node": ">=8" + "node": ">=4.0.0" } }, - "node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } + "node_modules/deep-is": { + "version": "0.1.4", + "dev": true, + "license": "MIT" }, - "node_modules/cheerio": { - "version": "1.0.0-rc.12", + "node_modules/define-data-property": { + "version": "1.1.4", "dev": true, "license": "MIT", "dependencies": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, - "node_modules/cheerio-select": { - "version": "2.1.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/fb55" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/chokidar": { - "version": "3.6.0", + "node_modules/define-properties": { + "version": "1.2.1", "dev": true, "license": "MIT", "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" }, "engines": { - "node": ">= 8.10.0" + "node": ">= 0.4" }, "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chownr": { - "version": "1.1.4", - "dev": true, - "license": "ISC", - "optional": true - }, - "node_modules/cliui": { - "version": "8.0.1", - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/co": { - "version": "4.6.0", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/cockatiel": { - "version": "3.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/collection-utils": { - "version": "1.0.1", - "license": "Apache-2.0" - }, - "node_modules/color-convert": { - "version": "1.9.3", + "node_modules/delayed-stream": { + "version": "1.0.0", "dev": true, "license": "MIT", - "dependencies": { - "color-name": "1.1.3" + "engines": { + "node": ">=0.4.0" } }, - "node_modules/color-convert/node_modules/color-name": { - "version": "1.1.3", + "node_modules/detect-libc": { + "version": "2.0.3", "dev": true, - "license": "MIT" + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } }, - "node_modules/color-name": { - "version": "1.1.4", - "license": "MIT" + "node_modules/diff": { + "version": "4.0.2", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } }, - "node_modules/combined-stream": { - "version": "1.0.8", + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, - "license": "MIT", "dependencies": { - "delayed-stream": "~1.0.0" + "path-type": "^4.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">=8" } }, - "node_modules/command-line-args": { - "version": "5.2.1", - "license": "MIT", + "node_modules/doctrine": { + "version": "3.0.0", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "array-back": "^3.1.0", - "find-replace": "^3.0.0", - "lodash.camelcase": "^4.3.0", - "typical": "^4.0.0" + "esutils": "^2.0.2" }, "engines": { - "node": ">=4.0.0" + "node": ">=6.0.0" } }, - "node_modules/command-line-usage": { - "version": "7.0.1", + "node_modules/dom-serializer": { + "version": "2.0.0", + "dev": true, "license": "MIT", "dependencies": { - "array-back": "^6.2.2", - "chalk-template": "^0.4.0", - "table-layout": "^3.0.0", - "typical": "^7.1.1" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" }, - "engines": { - "node": ">=12.20.0" + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "node_modules/command-line-usage/node_modules/array-back": { - "version": "6.2.2", - "license": "MIT", - "engines": { - "node": ">=12.17" - } + "node_modules/domelementtype": { + "version": "2.3.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" }, - "node_modules/command-line-usage/node_modules/typical": { - "version": "7.1.1", - "license": "MIT", + "node_modules/domhandler": { + "version": "5.0.3", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, "engines": { - "node": ">=12.17" + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "license": "MIT" + "node_modules/domutils": { + "version": "3.1.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } }, - "node_modules/concat-stream": { - "version": "1.6.2", + "node_modules/duplexer2": { + "version": "0.1.4", "dev": true, - "engines": [ - "node >= 0.8" - ], - "license": "MIT", + "license": "BSD-3-Clause", "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" + "readable-stream": "^2.0.2" } }, - "node_modules/concat-stream/node_modules/readable-stream": { + "node_modules/duplexer2/node_modules/readable-stream": { "version": "2.3.8", "dev": true, "license": "MIT", @@ -1844,435 +3142,513 @@ "util-deprecate": "~1.0.1" } }, - "node_modules/convert-source-map": { - "version": "2.0.0", + "node_modules/eastasianwidth": { + "version": "0.2.0", "dev": true, "license": "MIT" }, - "node_modules/core-util-is": { - "version": "1.0.3", - "license": "MIT" - }, - "node_modules/create-require": { - "version": "1.1.1", + "node_modules/emoji-regex": { + "version": "8.0.0", "license": "MIT" }, - "node_modules/cross-fetch": { - "version": "4.0.0", + "node_modules/encoding": { + "version": "0.1.13", "license": "MIT", "dependencies": { - "node-fetch": "^2.6.12" + "iconv-lite": "^0.6.2" } }, - "node_modules/cross-spawn": { - "version": "7.0.3", + "node_modules/end-of-stream": { + "version": "1.4.4", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" + "once": "^1.4.0" } }, - "node_modules/css-select": { - "version": "5.1.0", + "node_modules/enhanced-resolve": { + "version": "5.16.0", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" }, - "funding": { - "url": "https://github.com/sponsors/fb55" + "engines": { + "node": ">=10.13.0" } }, - "node_modules/css-what": { - "version": "6.1.0", + "node_modules/entities": { + "version": "4.5.0", "dev": true, "license": "BSD-2-Clause", "engines": { - "node": ">= 6" + "node": ">=0.12" }, "funding": { - "url": "https://github.com/sponsors/fb55" + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/debug": { - "version": "4.3.4", + "node_modules/es-define-property": { + "version": "1.0.0", "dev": true, "license": "MIT", "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" + "get-intrinsic": "^1.2.4" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "4.0.0", - "dev": true, - "license": "MIT", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.4" } }, - "node_modules/decompress-response": { - "version": "6.0.0", + "node_modules/es-errors": { + "version": "1.3.0", "dev": true, "license": "MIT", - "optional": true, - "dependencies": { - "mimic-response": "^3.1.0" - }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.4" } }, - "node_modules/deep-equal": { - "version": "2.2.3", + "node_modules/es-get-iterator": { + "version": "1.1.3", "dev": true, "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.5", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.2", + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" + "stop-iteration-iterator": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/deep-equal/node_modules/isarray": { + "node_modules/es-get-iterator/node_modules/isarray": { "version": "2.0.5", "dev": true, "license": "MIT" }, - "node_modules/deep-extend": { - "version": "0.6.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", "dev": true, "license": "MIT" }, - "node_modules/define-data-property": { - "version": "1.1.4", + "node_modules/esbuild": { + "version": "0.20.2", "dev": true, + "hasInstallScript": true, "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" + "bin": { + "esbuild": "bin/esbuild" }, "engines": { - "node": ">= 0.4" + "node": ">=12" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" } }, - "node_modules/define-properties": { - "version": "1.2.1", + "node_modules/esbuild/node_modules/@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "cpu": [ + "ppc64" + ], "dev": true, "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, + "optional": true, + "os": [ + "aix" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=12" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", + "node_modules/esbuild/node_modules/@esbuild/android-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=0.4.0" + "node": ">=12" } }, - "node_modules/detect-libc": { - "version": "2.0.3", + "node_modules/esbuild/node_modules/@esbuild/android-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/diff": { - "version": "4.0.2", - "license": "BSD-3-Clause", + "node_modules/esbuild/node_modules/@esbuild/android-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=0.3.1" + "node": ">=12" } }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "node_modules/esbuild/node_modules/@esbuild/darwin-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/doctrine": { - "version": "3.0.0", + "node_modules/esbuild/node_modules/@esbuild/darwin-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=6.0.0" + "node": ">=12" } }, - "node_modules/dom-serializer": { - "version": "2.0.0", + "node_modules/esbuild/node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" } }, - "node_modules/domelementtype": { - "version": "2.3.0", + "node_modules/esbuild/node_modules/@esbuild/freebsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "cpu": [ + "x64" + ], "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } + "license": "MIT", + "optional": true, + "os": [ + "freebsd" ], - "license": "BSD-2-Clause" + "engines": { + "node": ">=12" + } }, - "node_modules/domhandler": { - "version": "5.0.3", + "node_modules/esbuild/node_modules/@esbuild/linux-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "cpu": [ + "arm" + ], "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.3.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" + "node": ">=12" } }, - "node_modules/domutils": { - "version": "3.1.0", + "node_modules/esbuild/node_modules/@esbuild/linux-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/duplexer2": { - "version": "0.1.4", + "node_modules/esbuild/node_modules/@esbuild/linux-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "cpu": [ + "ia32" + ], "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "readable-stream": "^2.0.2" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/duplexer2/node_modules/readable-stream": { - "version": "2.3.8", + "node_modules/esbuild/node_modules/@esbuild/linux-loong64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "cpu": [ + "loong64" + ], "dev": true, "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-mips64el": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", + "node_modules/esbuild/node_modules/@esbuild/linux-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "cpu": [ + "ppc64" + ], "dev": true, - "license": "MIT" - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "license": "MIT" - }, - "node_modules/encoding": { - "version": "0.1.13", "license": "MIT", - "dependencies": { - "iconv-lite": "^0.6.2" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/end-of-stream": { - "version": "1.4.4", + "node_modules/esbuild/node_modules/@esbuild/linux-riscv64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "cpu": [ + "riscv64" + ], "dev": true, "license": "MIT", "optional": true, - "dependencies": { - "once": "^1.4.0" + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/enhanced-resolve": { - "version": "5.16.0", + "node_modules/esbuild/node_modules/@esbuild/linux-s390x": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "cpu": [ + "s390x" + ], "dev": true, "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=10.13.0" + "node": ">=12" } }, - "node_modules/entities": { - "version": "4.5.0", + "node_modules/esbuild/node_modules/@esbuild/linux-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "cpu": [ + "x64" + ], "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "node": ">=12" } }, - "node_modules/es-define-property": { - "version": "1.0.0", + "node_modules/esbuild/node_modules/@esbuild/netbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">= 0.4" + "node": ">=12" } }, - "node_modules/es-errors": { - "version": "1.3.0", + "node_modules/esbuild/node_modules/@esbuild/openbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">= 0.4" + "node": ">=12" } }, - "node_modules/es-get-iterator": { - "version": "1.1.3", + "node_modules/esbuild/node_modules/@esbuild/sunos-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "is-arguments": "^1.1.1", - "is-map": "^2.0.2", - "is-set": "^2.0.2", - "is-string": "^1.0.7", - "isarray": "^2.0.5", - "stop-iteration-iterator": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" } }, - "node_modules/es-get-iterator/node_modules/isarray": { - "version": "2.0.5", + "node_modules/esbuild/node_modules/@esbuild/win32-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/esbuild": { + "node_modules/esbuild/node_modules/@esbuild/win32-ia32": { "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "cpu": [ + "ia32" + ], "dev": true, - "hasInstallScript": true, "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" } }, "node_modules/escalade": { @@ -2566,6 +3942,16 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, "node_modules/esutils": { "version": "2.0.2", "dev": true, @@ -2611,6 +3997,16 @@ "node": ">=6" } }, + "node_modules/expect-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/falafel": { "version": "2.2.5", "dev": true, @@ -2805,6 +4201,21 @@ "version": "1.0.0", "license": "ISC" }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "dev": true, @@ -3568,6 +4979,13 @@ "version": "3.7.7", "license": "BSD-3-Clause" }, + "node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true, + "license": "MIT" + }, "node_modules/json-buffer": { "version": "3.0.1", "dev": true, @@ -3714,6 +5132,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, "node_modules/lru-cache": { "version": "6.0.0", "dev": true, @@ -4112,6 +5537,25 @@ "dev": true, "license": "ISC" }, + "node_modules/nanoid": { + "version": "3.3.15", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", + "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/napi-build-utils": { "version": "1.0.2", "dev": true, @@ -4416,11 +5860,35 @@ "node": ">=8" } }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, "node_modules/pend": { "version": "1.2.0", "dev": true, "license": "MIT" }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, "node_modules/picomatch": { "version": "2.3.1", "dev": true, @@ -4447,6 +5915,35 @@ "node": ">= 0.4" } }, + "node_modules/postcss": { + "version": "8.5.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.16.tgz", + "integrity": "sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/prebuild-install": { "version": "7.1.2", "dev": true, @@ -4751,6 +6248,51 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rollup": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz", + "integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.62.2", + "@rollup/rollup-android-arm64": "4.62.2", + "@rollup/rollup-darwin-arm64": "4.62.2", + "@rollup/rollup-darwin-x64": "4.62.2", + "@rollup/rollup-freebsd-arm64": "4.62.2", + "@rollup/rollup-freebsd-x64": "4.62.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.2", + "@rollup/rollup-linux-arm-musleabihf": "4.62.2", + "@rollup/rollup-linux-arm64-gnu": "4.62.2", + "@rollup/rollup-linux-arm64-musl": "4.62.2", + "@rollup/rollup-linux-loong64-gnu": "4.62.2", + "@rollup/rollup-linux-loong64-musl": "4.62.2", + "@rollup/rollup-linux-ppc64-gnu": "4.62.2", + "@rollup/rollup-linux-ppc64-musl": "4.62.2", + "@rollup/rollup-linux-riscv64-gnu": "4.62.2", + "@rollup/rollup-linux-riscv64-musl": "4.62.2", + "@rollup/rollup-linux-s390x-gnu": "4.62.2", + "@rollup/rollup-linux-x64-gnu": "4.62.2", + "@rollup/rollup-linux-x64-musl": "4.62.2", + "@rollup/rollup-openbsd-x64": "4.62.2", + "@rollup/rollup-openharmony-arm64": "4.62.2", + "@rollup/rollup-win32-arm64-msvc": "4.62.2", + "@rollup/rollup-win32-ia32-msvc": "4.62.2", + "@rollup/rollup-win32-x64-gnu": "4.62.2", + "@rollup/rollup-win32-x64-msvc": "4.62.2", + "fsevents": "~2.3.2" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "dev": true, @@ -4908,6 +6450,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, "node_modules/signal-exit": { "version": "4.1.0", "dev": true, @@ -4982,6 +6531,23 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, "node_modules/static-eval": { "version": "2.1.1", "dev": true, @@ -5067,6 +6633,13 @@ "util-deprecate": "~1.0.1" } }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, + "license": "MIT" + }, "node_modules/stop-iteration-iterator": { "version": "1.0.0", "dev": true, @@ -5181,6 +6754,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strip-literal": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", + "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/supports-color": { "version": "5.5.0", "dev": true, @@ -5332,6 +6918,98 @@ "version": "1.0.2", "license": "MIT" }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", + "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/tmp": { "version": "0.2.3", "dev": true, @@ -6001,6 +7679,340 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/vite": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz", + "integrity": "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0 || ^0.28.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.4.1", + "es-module-lexer": "^1.7.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite-node/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/vite-node/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" + } + }, + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vitest": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.7.tgz", + "integrity": "sha512-KrxIJ62Fd89gfysR4WotlgZABiz2dqFPgqGzX7s+CwsqLFomRH7777ZcrOD6+WVAh7khPQP41A+BKbpcJFrdEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/expect": "3.2.7", + "@vitest/mocker": "3.2.7", + "@vitest/pretty-format": "^3.2.7", + "@vitest/runner": "3.2.7", + "@vitest/snapshot": "3.2.7", + "@vitest/spy": "3.2.7", + "@vitest/utils": "3.2.7", + "chai": "^5.2.0", + "debug": "^4.4.1", + "expect-type": "^1.2.1", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "picomatch": "^4.0.2", + "std-env": "^3.9.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.14", + "tinypool": "^1.1.1", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", + "vite-node": "3.2.4", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.2.7", + "@vitest/ui": "3.2.7", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/vitest/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/vitest/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/vlq": { "version": "0.2.3", "dev": true, @@ -6115,6 +8127,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/word-wrap": { "version": "1.2.5", "dev": true, @@ -6264,13 +8293,18 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "2.4.1", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", "license": "ISC", "bin": { "yaml": "bin.mjs" }, "engines": { - "node": ">= 14" + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" } }, "node_modules/yargs": { diff --git a/package.json b/package.json index 146b5c605..4337c9855 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,8 @@ "pub:vscode": "script/publish-vscode.sh", "build": "npm run clean && npm run build --workspaces --if-present && tsc", "test": "script/test", + "test:cli": "vitest run", + "test:dev": "vitest dev", "start": "script/watch", "clean": "rm -rf dist *~ packages/*/{dist,out}", "debug": "node --inspect-brk --max-old-space-size=4096 ./dist/index.js", @@ -78,6 +80,7 @@ "tree-sitter-scala": "^0.24.0", "tree-sitter-typescript": "^0.23.2", "ts-node": "^10.9.2", + "vitest": "^3.1.4", "watch": "^1.0.2", "web-tree-sitter": "^0.26.9" }, diff --git a/packages/quicktype-core/src/Inference.ts b/packages/quicktype-core/src/Inference.ts index 94bf2e829..4aa9c82dc 100644 --- a/packages/quicktype-core/src/Inference.ts +++ b/packages/quicktype-core/src/Inference.ts @@ -77,7 +77,7 @@ export const inferenceFlagsObject = { }, }; export type InferenceFlagName = keyof typeof inferenceFlagsObject; -export const inferenceFlagNames = Object.getOwnPropertyNames( +export const inferenceFlagNames = Object.keys( inferenceFlagsObject, ) as InferenceFlagName[]; export const inferenceFlags: { [F in InferenceFlagName]: InferenceFlag } = diff --git a/packages/quicktype-core/src/support/Chance.ts b/packages/quicktype-core/src/support/Chance.ts index f4c553c5f..ed88d2c8b 100644 --- a/packages/quicktype-core/src/support/Chance.ts +++ b/packages/quicktype-core/src/support/Chance.ts @@ -190,7 +190,7 @@ export class Chance { return this.integer({ min: 0, max: options.max }); } - pick(arr: T[]): T { + pick(arr: readonly T[]): T { if (arr.length === 0) { throw new RangeError("Chance: Cannot pick() from an empty array"); } diff --git a/src/CLIOptions.types.ts b/src/CLIOptions.types.ts new file mode 100644 index 000000000..3b5bf8c65 --- /dev/null +++ b/src/CLIOptions.types.ts @@ -0,0 +1,45 @@ +import type { + LanguageName, + RendererOptions, + InferenceFlagName, +} from "quicktype-core"; + +type CamelToPascal = + T extends `${infer FirstChar}${infer Rest}` + ? `${Capitalize}${Rest}` + : never; + +export type NegatedInferenceFlagName< + Input extends InferenceFlagName = InferenceFlagName, +> = `no${CamelToPascal}`; + +export interface CLIOptions + extends Partial< + Record + > { + additionalSchema: string[]; + allPropertiesOptional: boolean; + alphabetizeProperties: boolean; + buildMarkovChain?: string; + debug?: string; + graphqlIntrospect?: string; + graphqlSchema?: string; + help: boolean; + httpHeader?: string[]; + httpMethod?: string; + lang: Lang; + + noRender: boolean; + out?: string; + quiet: boolean; + + rendererOptions: RendererOptions; + + src: string[]; + srcLang: string; + srcUrls?: string; + telemetry?: "enable" | "disable"; + topLevel: string; + + version: boolean; +} diff --git a/src/GraphQLIntrospection.ts b/src/GraphQLIntrospection.ts index db2093a0a..aa59ab9f0 100644 --- a/src/GraphQLIntrospection.ts +++ b/src/GraphQLIntrospection.ts @@ -32,6 +32,7 @@ export async function introspectServer( headers[matches[1]] = matches[2]; } + // biome-ignore lint/suspicious/noImplicitAnyLet: let result; try { const response = await fetch(url, { diff --git a/src/cli.options.ts b/src/cli.options.ts new file mode 100644 index 000000000..46d94d3ea --- /dev/null +++ b/src/cli.options.ts @@ -0,0 +1,124 @@ +import { exceptionToString } from "@glideapps/ts-necessities"; +import commandLineArgs from "command-line-args"; +import _ from "lodash"; + +import { + type OptionDefinition, + type RendererOptions, + type TargetLanguage, + assert, + defaultTargetLanguages, + getTargetLanguage, + isLanguageName, + messageError, +} from "quicktype-core"; + +import { inferCLIOptions } from "./inference"; +import { + makeOptionDefinitions, + transformDefinition, +} from "./optionDefinitions"; +import type { CLIOptions } from "./CLIOptions.types"; + +// Parse the options in argv and split them into global options and renderer options, +// according to each option definition's `renderer` field. If `partial` is false this +// will throw if it encounters an unknown option. +export function parseOptions( + definitions: OptionDefinition[], + argv: string[], + partial: boolean, +): Partial { + let opts: commandLineArgs.CommandLineOptions; + try { + opts = commandLineArgs(definitions.map(transformDefinition), { + argv, + partial, + }); + } catch (e) { + assert(!partial, "Partial option parsing should not have failed"); + return messageError("DriverCLIOptionParsingFailed", { + message: exceptionToString(e), + }); + } + + for (const k of Object.keys(opts)) { + if (opts[k] === null) { + return messageError("DriverCLIOptionParsingFailed", { + message: `Missing value for command line option "${k}"`, + }); + } + } + + const options: { + [key: string]: unknown; + rendererOptions: RendererOptions; + } = { rendererOptions: {} }; + for (const optionDefinition of definitions) { + if (!(optionDefinition.name in opts)) { + continue; + } + + const optionValue = opts[optionDefinition.name] as string; + if (optionDefinition.kind !== "cli") { + ( + options.rendererOptions as Record< + typeof optionDefinition.name, + unknown + > + )[optionDefinition.name] = optionValue; + } + // Inference flags + else { + const k = _.lowerFirst( + optionDefinition.name.split("-").map(_.upperFirst).join(""), + ); + options[k] = optionValue; + } + } + + return options; +} + +export function parseCLIOptions( + argv: string[], + inputTargetLanguage?: TargetLanguage, +): CLIOptions { + if (argv.length === 0) { + return inferCLIOptions({ help: true }, inputTargetLanguage); + } + + const targetLanguages = inputTargetLanguage + ? [inputTargetLanguage] + : defaultTargetLanguages; + const optionDefinitions = makeOptionDefinitions(targetLanguages); + + // We can only fully parse the options once we know which renderer is selected, + // because there are renderer-specific options. But we only know which renderer + // is selected after we've parsed the options. Hence, we parse the options + // twice. This is the first parse to get the renderer: + const incompleteOptions = inferCLIOptions( + parseOptions(optionDefinitions, argv, true), + inputTargetLanguage, + ); + + let targetLanguage = inputTargetLanguage as TargetLanguage; + if (inputTargetLanguage === undefined) { + const languageName = isLanguageName(incompleteOptions.lang) + ? incompleteOptions.lang + : "typescript"; + targetLanguage = getTargetLanguage(languageName); + } + + const rendererOptionDefinitions = + targetLanguage.cliOptionDefinitions.actual; + // Use the global options as well as the renderer options from now on: + const allOptionDefinitions = _.concat( + optionDefinitions, + rendererOptionDefinitions, + ); + // This is the parse that counts: + return inferCLIOptions( + parseOptions(allOptionDefinitions, argv, false), + targetLanguage, + ); +} diff --git a/src/index.ts b/src/index.ts index 856542c96..566851235 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,1177 +1,27 @@ #!/usr/bin/env node + import * as fs from "node:fs"; import * as path from "node:path"; -import { exceptionToString } from "@glideapps/ts-necessities"; import chalk from "chalk"; -import { - definedMap, - // biome-ignore lint/suspicious/noShadowRestrictedNames: - hasOwnProperty, - mapFromObject, - mapMap, - withDefault, -} from "collection-utils"; -import commandLineArgs from "command-line-args"; -import getUsage from "command-line-usage"; -import * as _ from "lodash"; -import type { Readable } from "readable-stream"; -import stringToStream from "string-to-stream"; -import _wordwrap from "wordwrap"; import { - FetchingJSONSchemaStore, - InputData, IssueAnnotationData, - JSONInput, - JSONSchemaInput, - type JSONSourceData, - type LanguageName, - type OptionDefinition, - type Options, - type RendererOptions, type SerializedRenderResult, - type TargetLanguage, - assert, - assertNever, - capitalize, - defaultTargetLanguages, - defined, - getStream, - getTargetLanguage, - inferenceFlagNames, - inferenceFlags, - isLanguageName, - languageNamed, - messageAssert, - messageError, - panic, - parseJSON, quicktypeMultiFile, - readFromFileOrURL, - readableFromFileOrURL, - sourcesFromPostmanCollection, - splitIntoWords, - trainMarkovChain, } from "quicktype-core"; -import { GraphQLInput } from "quicktype-graphql-input"; -import { schemaForTypeScriptSources } from "quicktype-typescript-input"; - -import { CompressedJSONFromStream } from "./CompressedJSONFromStream"; -import { introspectServer } from "./GraphQLIntrospection"; -import type { - GraphQLTypeSource, - JSONTypeSource, - SchemaTypeSource, - TypeSource, -} from "./TypeSource"; -import { urlsFromURLGrammar } from "./URLGrammar"; - -// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires -const packageJSON = require("../package.json"); - -const wordWrap: (s: string) => string = _wordwrap(90); - -export interface CLIOptions { - // We use this to access the inference flags - // biome-ignore lint/suspicious/noExplicitAny: - [option: string]: any; - additionalSchema: string[]; - allPropertiesOptional: boolean; - alphabetizeProperties: boolean; - buildMarkovChain?: string; - debug?: string; - graphqlIntrospect?: string; - graphqlSchema?: string; - help: boolean; - httpHeader?: string[]; - httpMethod?: string; - lang: Lang; - - noRender: boolean; - out?: string; - quiet: boolean; - - rendererOptions: RendererOptions; - - src: string[]; - srcLang: string; - srcUrls?: string; - telemetry?: string; - topLevel: string; - - version: boolean; -} - -const defaultDefaultTargetLanguageName = "go"; - -async function sourceFromFileOrUrlArray( - name: string, - filesOrUrls: string[], - httpHeaders?: string[], -): Promise { - const samples = await Promise.all( - filesOrUrls.map( - async (file) => await readableFromFileOrURL(file, httpHeaders), - ), - ); - return { kind: "json", name, samples }; -} - -function typeNameFromFilename(filename: string): string { - const name = path.basename(filename); - return name.substring(0, name.lastIndexOf(".")); -} - -async function samplesFromDirectory( - dataDir: string, - httpHeaders?: string[], -): Promise { - async function readFilesOrURLsInDirectory( - d: string, - ): Promise { - const files = fs - .readdirSync(d) - .map((x) => path.join(d, x)) - .filter((x) => fs.lstatSync(x).isFile()); - // Each file is a (Name, JSON | URL) - const sourcesInDir: TypeSource[] = []; - const graphQLSources: GraphQLTypeSource[] = []; - let graphQLSchema: Readable | undefined = undefined; - let graphQLSchemaFileName: string | undefined = undefined; - for (let file of files) { - const name = typeNameFromFilename(file); - - let fileOrUrl = file; - file = file.toLowerCase(); - - // If file is a URL string, download it - if (file.endsWith(".url")) { - fileOrUrl = fs.readFileSync(file, "utf8").trim(); - } - - if (file.endsWith(".url") || file.endsWith(".json")) { - sourcesInDir.push({ - kind: "json", - name, - samples: [ - await readableFromFileOrURL(fileOrUrl, httpHeaders), - ], - }); - } else if (file.endsWith(".schema")) { - sourcesInDir.push({ - kind: "schema", - name, - uris: [fileOrUrl], - }); - } else if (file.endsWith(".gqlschema")) { - messageAssert( - graphQLSchema === undefined, - "DriverMoreThanOneGraphQLSchemaInDir", - { - dir: dataDir, - }, - ); - graphQLSchema = await readableFromFileOrURL( - fileOrUrl, - httpHeaders, - ); - graphQLSchemaFileName = fileOrUrl; - } else if (file.endsWith(".graphql")) { - graphQLSources.push({ - kind: "graphql", - name, - schema: undefined, - query: await getStream( - await readableFromFileOrURL(fileOrUrl, httpHeaders), - ), - }); - } - } - - if (graphQLSources.length > 0) { - if (graphQLSchema === undefined) { - return messageError("DriverNoGraphQLSchemaInDir", { - dir: dataDir, - }); - } - - const schema = parseJSON( - await getStream(graphQLSchema), - "GraphQL schema", - graphQLSchemaFileName, - ); - for (const source of graphQLSources) { - source.schema = schema; - sourcesInDir.push(source); - } - } - - return sourcesInDir; - } - - const contents = fs.readdirSync(dataDir).map((x) => path.join(dataDir, x)); - const directories = contents.filter((x) => fs.lstatSync(x).isDirectory()); - - let sources = await readFilesOrURLsInDirectory(dataDir); - - for (const dir of directories) { - let jsonSamples: Readable[] = []; - const schemaSources: SchemaTypeSource[] = []; - const graphQLSources: GraphQLTypeSource[] = []; - - for (const source of await readFilesOrURLsInDirectory(dir)) { - switch (source.kind) { - case "json": - jsonSamples = jsonSamples.concat(source.samples); - break; - case "schema": - schemaSources.push(source); - break; - case "graphql": - graphQLSources.push(source); - break; - default: - return assertNever(source); - } - } - - if ( - jsonSamples.length > 0 && - schemaSources.length + graphQLSources.length > 0 - ) { - return messageError("DriverCannotMixJSONWithOtherSamples", { - dir: dir, - }); - } - - // FIXME: rewrite this to be clearer - const oneUnlessEmpty = (xs: TypeSource[]): 0 | 1 => - Math.sign(xs.length) as 0 | 1; - if ( - oneUnlessEmpty(schemaSources) + oneUnlessEmpty(graphQLSources) > - 1 - ) { - return messageError("DriverCannotMixNonJSONInputs", { dir: dir }); - } - - if (jsonSamples.length > 0) { - sources.push({ - kind: "json", - name: path.basename(dir), - samples: jsonSamples, - }); - } - - sources = sources.concat(schemaSources); - sources = sources.concat(graphQLSources); - } - - return sources; -} - -function inferLang( - options: Partial, - defaultLanguage: LanguageName, -): string | LanguageName { - // Output file extension determines the language if language is undefined - if (options.out !== undefined) { - const extension = path.extname(options.out); - if (extension === "") { - return messageError("DriverNoLanguageOrExtension", {}); - } - - return extension.slice(1); - } - - return defaultLanguage; -} - -function inferTopLevel(options: Partial): string { - // Output file name determines the top-level if undefined - if (options.out !== undefined) { - const extension = path.extname(options.out); - const without = path.basename(options.out).replace(extension, ""); - return without; - } - - // Source determines the top-level if undefined - if (options.src !== undefined && options.src.length === 1) { - const src = options.src[0]; - const extension = path.extname(src); - const without = path.basename(src).replace(extension, ""); - return without; - } - - return "TopLevel"; -} - -function inferCLIOptions( - opts: Partial, - targetLanguage: TargetLanguage | undefined, -): CLIOptions { - let srcLang = opts.srcLang; - if ( - opts.graphqlSchema !== undefined || - opts.graphqlIntrospect !== undefined - ) { - messageAssert( - srcLang === undefined || srcLang === "graphql", - "DriverSourceLangMustBeGraphQL", - {}, - ); - srcLang = "graphql"; - } else if ( - opts.src !== undefined && - opts.src.length > 0 && - opts.src.every((file) => _.endsWith(file, ".ts")) - ) { - srcLang = "typescript"; - } else { - messageAssert(srcLang !== "graphql", "DriverGraphQLSchemaNeeded", {}); - srcLang = withDefault(srcLang, "json"); - } - - let language: TargetLanguage; - if (targetLanguage !== undefined) { - language = targetLanguage; - } else { - const languageName = - opts.lang ?? inferLang(opts, defaultDefaultTargetLanguageName); - - if (isLanguageName(languageName)) { - language = languageNamed(languageName); - } else { - return messageError("DriverUnknownOutputLanguage", { - lang: languageName, - }); - } - } - - const options: CLIOptions = { - src: opts.src ?? [], - srcUrls: opts.srcUrls, - srcLang: srcLang, - lang: language.name as LanguageName, - topLevel: opts.topLevel ?? inferTopLevel(opts), - noRender: !!opts.noRender, - alphabetizeProperties: !!opts.alphabetizeProperties, - allPropertiesOptional: !!opts.allPropertiesOptional, - rendererOptions: opts.rendererOptions ?? {}, - help: opts.help ?? false, - quiet: opts.quiet ?? false, - version: opts.version ?? false, - out: opts.out, - buildMarkovChain: opts.buildMarkovChain, - additionalSchema: opts.additionalSchema ?? [], - graphqlSchema: opts.graphqlSchema, - graphqlIntrospect: opts.graphqlIntrospect, - httpMethod: opts.httpMethod, - httpHeader: opts.httpHeader, - debug: opts.debug, - telemetry: opts.telemetry, - }; - for (const flagName of inferenceFlagNames) { - const cliName = negatedInferenceFlagName(flagName); - options[cliName] = !!opts[cliName]; - } - - return options; -} - -function makeLangTypeLabel(targetLanguages: readonly TargetLanguage[]): string { - assert( - targetLanguages.length > 0, - "Must have at least one target language", - ); - return targetLanguages - .map((r) => _.minBy(r.names, (s) => s.length)) - .join("|"); -} - -function negatedInferenceFlagName(name: string): string { - const prefix = "infer"; - if (name.startsWith(prefix)) { - name = name.slice(prefix.length); - } - - return "no" + capitalize(name); -} - -function dashedFromCamelCase(name: string): string { - return splitIntoWords(name) - .map((w) => w.word.toLowerCase()) - .join("-"); -} - -function makeOptionDefinitions( - targetLanguages: readonly TargetLanguage[], -): OptionDefinition[] { - const beforeLang: OptionDefinition[] = [ - { - name: "out", - alias: "o", - optionType: "string", - typeLabel: "FILE", - description: "The output file. Determines --lang and --top-level.", - kind: "cli", - }, - { - name: "top-level", - alias: "t", - optionType: "string", - typeLabel: "NAME", - description: "The name for the top level type.", - kind: "cli", - }, - ]; - const lang: OptionDefinition[] = - targetLanguages.length < 2 - ? [] - : [ - { - name: "lang", - alias: "l", - optionType: "string", - typeLabel: "LANG", - description: "The target language.", - kind: "cli", - }, - ]; - const afterLang: OptionDefinition[] = [ - { - name: "src-lang", - alias: "s", - optionType: "string", - defaultValue: undefined, - typeLabel: "SRC_LANG", - description: "The source language (default is json).", - kind: "cli", - }, - { - name: "src", - optionType: "string", - multiple: true, - typeLabel: "FILE|URL|DIRECTORY", - description: "The file, url, or data directory to type.", - kind: "cli", - defaultOption: true, - }, - { - name: "src-urls", - optionType: "string", - typeLabel: "FILE", - description: "Tracery grammar describing URLs to crawl.", - kind: "cli", - }, - ]; - const inference: OptionDefinition[] = Array.from( - mapMap(mapFromObject(inferenceFlags), (flag, name) => { - return { - name: dashedFromCamelCase(negatedInferenceFlagName(name)), - optionType: "boolean" as const, - description: flag.negationDescription + ".", - kind: "cli" as const, - }; - }).values(), - ); - const afterInference: OptionDefinition[] = [ - { - name: "graphql-schema", - optionType: "string", - typeLabel: "FILE", - description: "GraphQL introspection file.", - kind: "cli", - }, - { - name: "graphql-introspect", - optionType: "string", - typeLabel: "URL", - description: "Introspect GraphQL schema from a server.", - kind: "cli", - }, - { - name: "http-method", - optionType: "string", - typeLabel: "METHOD", - description: - "HTTP method to use for the GraphQL introspection query.", - kind: "cli", - }, - { - name: "http-header", - optionType: "string", - multiple: true, - typeLabel: "HEADER", - description: - "Header(s) to attach to all HTTP requests, including the GraphQL introspection query.", - kind: "cli", - }, - { - name: "additional-schema", - alias: "S", - optionType: "string", - multiple: true, - typeLabel: "FILE", - description: "Register the $id's of additional JSON Schema files.", - kind: "cli", - }, - { - name: "no-render", - optionType: "boolean", - description: "Don't render output.", - kind: "cli", - }, - { - name: "alphabetize-properties", - optionType: "boolean", - description: "Alphabetize order of class properties.", - kind: "cli", - }, - { - name: "all-properties-optional", - optionType: "boolean", - description: "Make all class properties optional.", - kind: "cli", - }, - { - name: "build-markov-chain", - optionType: "string", - typeLabel: "FILE", - description: "Markov chain corpus filename.", - kind: "cli", - }, - { - name: "quiet", - optionType: "boolean", - description: "Don't show issues in the generated code.", - kind: "cli", - }, - { - name: "debug", - optionType: "string", - typeLabel: "OPTIONS or all", - description: - "Comma separated debug options: print-graph, print-reconstitution, print-gather-names, print-transformations, print-schema-resolving, print-times, provenance", - kind: "cli", - }, - { - name: "telemetry", - optionType: "string", - typeLabel: "enable|disable", - description: "Enable anonymous telemetry to help improve quicktype", - kind: "cli", - }, - { - name: "help", - alias: "h", - optionType: "boolean", - description: "Get some help.", - kind: "cli", - }, - { - name: "version", - alias: "v", - optionType: "boolean", - description: "Display the version of quicktype", - kind: "cli", - }, - ]; - return beforeLang.concat(lang, afterLang, inference, afterInference); -} - -interface ColumnDefinition { - name: string; - padding?: { left: string; right: string }; - width?: number; -} - -interface TableOptions { - columns: ColumnDefinition[]; -} - -interface UsageSection { - content?: string | string[]; - header?: string; - hide?: string[]; - optionList?: OptionDefinition[]; - tableOptions?: TableOptions; -} - -const tableOptionsForOptions: TableOptions = { - columns: [ - { - name: "option", - width: 60, - }, - { - name: "description", - width: 60, - }, - ], -}; - -function makeSectionsBeforeRenderers( - targetLanguages: readonly TargetLanguage[], -): UsageSection[] { - const langDisplayNames = targetLanguages - .map((r) => r.displayName) - .join(", "); - - return [ - { - header: "Synopsis", - content: [ - `$ quicktype [${chalk.bold("--lang")} LANG] [${chalk.bold("--src-lang")} SRC_LANG] [${chalk.bold( - "--out", - )} FILE] FILE|URL ...`, - "", - ` LANG ... ${makeLangTypeLabel(targetLanguages)}`, - "", - "SRC_LANG ... json|schema|graphql|postman|typescript", - ], - }, - { - header: "Description", - content: `Given JSON sample data, quicktype outputs code for working with that data in ${langDisplayNames}.`, - }, - { - header: "Options", - optionList: makeOptionDefinitions(targetLanguages), - hide: ["no-render", "build-markov-chain"], - tableOptions: tableOptionsForOptions, - }, - ]; -} - -const sectionsAfterRenderers: UsageSection[] = [ - { - header: "Examples", - content: [ - chalk.dim("Generate C# to parse a Bitcoin API"), - "$ quicktype -o LatestBlock.cs https://blockchain.info/latestblock", - "", - chalk.dim( - "Generate Go code from a directory of samples containing:", - ), - chalk.dim( - ` - Foo.json - + Bar - - bar-sample-1.json - - bar-sample-2.json - - Baz.url`, - ), - "$ quicktype -l go samples", - "", - chalk.dim("Generate JSON Schema, then TypeScript"), - "$ quicktype -o schema.json https://blockchain.info/latestblock", - "$ quicktype -o bitcoin.ts --src-lang schema schema.json", - ], - }, - { - content: `Learn more at ${chalk.bold("quicktype.io")}`, - }, -]; - -export function parseCLIOptions( - argv: string[], - targetLanguage?: TargetLanguage, -): CLIOptions { - if (argv.length === 0) { - return inferCLIOptions({ help: true }, targetLanguage); - } - - const targetLanguages = - targetLanguage === undefined - ? defaultTargetLanguages - : [targetLanguage]; - const optionDefinitions = makeOptionDefinitions(targetLanguages); - - // We can only fully parse the options once we know which renderer is selected, - // because there are renderer-specific options. But we only know which renderer - // is selected after we've parsed the options. Hence, we parse the options - // twice. This is the first parse to get the renderer: - const incompleteOptions = inferCLIOptions( - parseOptions(optionDefinitions, argv, true), - targetLanguage, - ); - if (targetLanguage === undefined) { - const languageName = isLanguageName(incompleteOptions.lang) - ? incompleteOptions.lang - : "typescript"; - targetLanguage = getTargetLanguage(languageName); - } - - const rendererOptionDefinitions = - targetLanguage.cliOptionDefinitions.actual; - // Use the global options as well as the renderer options from now on: - const allOptionDefinitions = _.concat( - optionDefinitions, - rendererOptionDefinitions, - ); - // This is the parse that counts: - return inferCLIOptions( - parseOptions(allOptionDefinitions, argv, false), - targetLanguage, - ); -} - -// Parse the options in argv and split them into global options and renderer options, -// according to each option definition's `renderer` field. If `partial` is false this -// will throw if it encounters an unknown option. -function parseOptions( - definitions: OptionDefinition[], - argv: string[], - partial: boolean, -): Partial { - let opts: commandLineArgs.CommandLineOptions; - try { - opts = commandLineArgs( - definitions.map((def) => ({ - ...def, - type: def.optionType === "boolean" ? Boolean : String, - })), - { argv, partial }, - ); - } catch (e) { - assert(!partial, "Partial option parsing should not have failed"); - return messageError("DriverCLIOptionParsingFailed", { - message: exceptionToString(e), - }); - } - - for (const k of Object.keys(opts)) { - if (opts[k] === null) { - return messageError("DriverCLIOptionParsingFailed", { - message: `Missing value for command line option "${k}"`, - }); - } - } - - const options: { - [key: string]: unknown; - rendererOptions: RendererOptions; - } = { rendererOptions: {} }; - for (const optionDefinition of definitions) { - if (!hasOwnProperty(opts, optionDefinition.name)) { - continue; - } - - const optionValue = opts[optionDefinition.name] as string; - if (optionDefinition.kind !== "cli") { - ( - options.rendererOptions as Record< - typeof optionDefinition.name, - unknown - > - )[optionDefinition.name] = optionValue; - } else { - const k = _.lowerFirst( - optionDefinition.name.split("-").map(_.upperFirst).join(""), - ); - options[k] = optionValue; - } - } - - return options; -} - -function usage(targetLanguages: readonly TargetLanguage[]): void { - const rendererSections: UsageSection[] = []; - - for (const language of targetLanguages) { - const definitions = language.cliOptionDefinitions.display; - if (definitions.length === 0) continue; - - rendererSections.push({ - header: `Options for ${language.displayName}`, - optionList: definitions, - tableOptions: tableOptionsForOptions, - }); - } - const sections = _.concat( - makeSectionsBeforeRenderers(targetLanguages), - rendererSections, - sectionsAfterRenderers, - ); - - console.log(getUsage(sections)); -} - -// Returns an array of [name, sourceURIs] pairs. -async function getSourceURIs( - options: CLIOptions, -): Promise> { - if (options.srcUrls !== undefined) { - const json = parseJSON( - await readFromFileOrURL(options.srcUrls, options.httpHeader), - "URL grammar", - options.srcUrls, - ); - const jsonMap = urlsFromURLGrammar(json); - const topLevels = Object.getOwnPropertyNames(jsonMap); - return topLevels.map( - (name) => [name, jsonMap[name]] as [string, string[]], - ); - } - if (options.src.length === 0) { - return [[options.topLevel, ["-"]]]; - } - - return []; -} - -async function typeSourcesForURIs( - name: string, - uris: string[], - options: CLIOptions, -): Promise { - switch (options.srcLang) { - case "json": - return [ - await sourceFromFileOrUrlArray(name, uris, options.httpHeader), - ]; - case "schema": - return uris.map( - (uri) => - ({ kind: "schema", name, uris: [uri] }) as SchemaTypeSource, - ); - default: - return panic( - `typeSourceForURIs must not be called for source language ${options.srcLang}`, - ); - } -} - -async function getSources(options: CLIOptions): Promise { - const sourceURIs = await getSourceURIs(options); - const sourceArrays = await Promise.all( - sourceURIs.map( - async ([name, uris]) => - await typeSourcesForURIs(name, uris, options), - ), - ); - let sources: TypeSource[] = ([] as TypeSource[]).concat(...sourceArrays); - - const exists = options.src.filter(fs.existsSync); - const directories = exists.filter((x) => fs.lstatSync(x).isDirectory()); - - for (const dataDir of directories) { - sources = sources.concat( - await samplesFromDirectory(dataDir, options.httpHeader), - ); - } - - // Every src that's not a directory is assumed to be a file or URL - const filesOrUrls = options.src.filter((x) => !_.includes(directories, x)); - if (!_.isEmpty(filesOrUrls)) { - sources.push( - ...(await typeSourcesForURIs( - options.topLevel, - filesOrUrls, - options, - )), - ); - } - - return sources; -} - -function makeTypeScriptSource(fileNames: string[]): SchemaTypeSource { - return Object.assign( - { kind: "schema" }, - schemaForTypeScriptSources(fileNames), - ) as SchemaTypeSource; -} - -export function jsonInputForTargetLanguage( - targetLanguage: string | TargetLanguage, - languages?: TargetLanguage[], - handleJSONRefs = false, -): JSONInput { - if (typeof targetLanguage === "string") { - const languageName = isLanguageName(targetLanguage) - ? targetLanguage - : "typescript"; - targetLanguage = defined(languageNamed(languageName, languages)); - } - - const compressedJSON = new CompressedJSONFromStream( - targetLanguage.dateTimeRecognizer, - handleJSONRefs, - ); - return new JSONInput(compressedJSON); -} - -async function makeInputData( - sources: TypeSource[], - targetLanguage: TargetLanguage, - additionalSchemaAddresses: readonly string[], - handleJSONRefs: boolean, - httpHeaders?: string[], -): Promise { - const inputData = new InputData(); - - for (const source of sources) { - switch (source.kind) { - case "graphql": - await inputData.addSource( - "graphql", - source, - () => new GraphQLInput(), - ); - break; - case "json": - await inputData.addSource("json", source, () => - jsonInputForTargetLanguage( - targetLanguage, - undefined, - handleJSONRefs, - ), - ); - break; - case "schema": - await inputData.addSource( - "schema", - source, - () => - new JSONSchemaInput( - new FetchingJSONSchemaStore(httpHeaders), - [], - additionalSchemaAddresses, - ), - ); - break; - default: - return assertNever(source); - } - } - - return inputData; -} - -function stringSourceDataToStreamSourceData( - src: JSONSourceData, -): JSONSourceData { - return { - name: src.name, - description: src.description, - samples: src.samples.map( - (sample) => stringToStream(sample) as Readable, - ), - }; -} - -export async function makeQuicktypeOptions( - options: CLIOptions, - targetLanguages?: TargetLanguage[], -): Promise | undefined> { - if (options.help) { - usage(targetLanguages ?? defaultTargetLanguages); - return undefined; - } - - if (options.version) { - console.log(`quicktype version ${packageJSON.version}`); - console.log("Visit quicktype.io for more info."); - return undefined; - } - - if (options.buildMarkovChain !== undefined) { - const contents = fs.readFileSync(options.buildMarkovChain).toString(); - const lines = contents.split("\n"); - const mc = trainMarkovChain(lines, 3); - console.log(JSON.stringify(mc)); - return undefined; - } - - let sources: TypeSource[] = []; - let leadingComments: string[] | undefined = undefined; - let fixedTopLevels = false; - switch (options.srcLang) { - case "graphql": - let schemaString: string | undefined = undefined; - let wroteSchemaToFile = false; - if (options.graphqlIntrospect !== undefined) { - schemaString = await introspectServer( - options.graphqlIntrospect, - withDefault(options.httpMethod, "POST"), - withDefault(options.httpHeader, []), - ); - if (options.graphqlSchema !== undefined) { - fs.writeFileSync(options.graphqlSchema, schemaString); - wroteSchemaToFile = true; - } - } - - const numSources = options.src.length; - if (numSources !== 1) { - if (wroteSchemaToFile) { - // We're done. - return undefined; - } - - if (numSources === 0) { - if (schemaString !== undefined) { - console.log(schemaString); - return undefined; - } - - return messageError("DriverNoGraphQLQueryGiven", {}); - } - } - - const gqlSources: GraphQLTypeSource[] = []; - for (const queryFile of options.src) { - let schemaFileName: string | undefined = undefined; - if (schemaString === undefined) { - schemaFileName = defined(options.graphqlSchema); - schemaString = fs.readFileSync(schemaFileName, "utf8"); - } - - const schema = parseJSON( - schemaString, - "GraphQL schema", - schemaFileName, - ); - const query = await getStream( - await readableFromFileOrURL(queryFile, options.httpHeader), - ); - const name = - numSources === 1 - ? options.topLevel - : typeNameFromFilename(queryFile); - gqlSources.push({ kind: "graphql", name, schema, query }); - } - - sources = gqlSources; - break; - case "json": - case "schema": - sources = await getSources(options); - break; - case "typescript": - sources = [makeTypeScriptSource(options.src)]; - break; - case "postman": - for (const collectionFile of options.src) { - const collectionJSON = fs.readFileSync(collectionFile, "utf8"); - const { sources: postmanSources, description } = - sourcesFromPostmanCollection( - collectionJSON, - collectionFile, - ); - for (const src of postmanSources) { - sources.push( - Object.assign( - { kind: "json" }, - stringSourceDataToStreamSourceData(src), - ) as JSONTypeSource, - ); - } - - if (postmanSources.length > 1) { - fixedTopLevels = true; - } - - if (description !== undefined) { - leadingComments = wordWrap(description).split("\n"); - } - } - - break; - default: - return messageError("DriverUnknownSourceLanguage", { - lang: options.srcLang, - }); - } - - const components = definedMap(options.debug, (d) => d.split(",")); - const debugAll = components?.includes("all"); - let debugPrintGraph = debugAll; - let checkProvenance = debugAll; - let debugPrintReconstitution = debugAll; - let debugPrintGatherNames = debugAll; - let debugPrintTransformations = debugAll; - let debugPrintSchemaResolving = debugAll; - let debugPrintTimes = debugAll; - if (components !== undefined) { - for (let component of components) { - component = component.trim(); - if (component === "print-graph") { - debugPrintGraph = true; - } else if (component === "print-reconstitution") { - debugPrintReconstitution = true; - } else if (component === "print-gather-names") { - debugPrintGatherNames = true; - } else if (component === "print-transformations") { - debugPrintTransformations = true; - } else if (component === "print-times") { - debugPrintTimes = true; - } else if (component === "print-schema-resolving") { - debugPrintSchemaResolving = true; - } else if (component === "provenance") { - checkProvenance = true; - } else if (component !== "all") { - return messageError("DriverUnknownDebugOption", { - option: component, - }); - } - } - } - - if (!isLanguageName(options.lang)) { - return messageError("DriverUnknownOutputLanguage", { - lang: options.lang, - }); - } - - const lang = languageNamed(options.lang, targetLanguages); - - const quicktypeOptions: Partial = { - lang, - alphabetizeProperties: options.alphabetizeProperties, - allPropertiesOptional: options.allPropertiesOptional, - fixedTopLevels, - noRender: options.noRender, - rendererOptions: options.rendererOptions, - leadingComments, - outputFilename: definedMap(options.out, path.basename), - debugPrintGraph, - checkProvenance, - debugPrintReconstitution, - debugPrintGatherNames, - debugPrintTransformations, - debugPrintSchemaResolving, - debugPrintTimes, - }; - for (const flagName of inferenceFlagNames) { - const cliName = negatedInferenceFlagName(flagName); - const v = options[cliName]; - if (typeof v === "boolean") { - quicktypeOptions[flagName] = !v; - } else { - quicktypeOptions[flagName] = true; - } - } - - quicktypeOptions.inputData = await makeInputData( - sources, - lang, - options.additionalSchema, - quicktypeOptions.ignoreJsonRefs !== true, - options.httpHeader, - ); - - return quicktypeOptions; -} +import { parseCLIOptions } from "./cli.options"; +import { inferCLIOptions } from "./inference"; +import { makeQuicktypeOptions } from "./quicktype.options"; +import type { CLIOptions } from "./CLIOptions.types"; +export type { CLIOptions }; export function writeOutput( cliOptions: CLIOptions, resultsByFilename: ReadonlyMap, ): void { - let onFirst = true; + let isFirstRun = true; for (const [filename, { lines, annotations }] of resultsByFilename) { const output = lines.join("\n"); @@ -1181,7 +31,7 @@ export function writeOutput( output, ); } else { - if (!onFirst) { + if (!isFirstRun) { process.stdout.write("\n"); } @@ -1196,10 +46,13 @@ export function writeOutput( continue; } - for (const sa of annotations) { - const annotation = sa.annotation; - if (!(annotation instanceof IssueAnnotationData)) continue; - const lineNumber = sa.span.start.line; + for (const sourceAnnotation of annotations) { + const annotation = sourceAnnotation.annotation; + if (!(annotation instanceof IssueAnnotationData)) { + continue; + } + + const lineNumber = sourceAnnotation.span.start.line; const humanLineNumber = lineNumber + 1; console.error( `\nIssue in line ${humanLineNumber}: ${annotation.message}`, @@ -1207,7 +60,7 @@ export function writeOutput( console.error(`${humanLineNumber}: ${lines[lineNumber]}`); } - onFirst = false; + isFirstRun = false; } } diff --git a/src/inference.ts b/src/inference.ts new file mode 100644 index 000000000..9db3e64e9 --- /dev/null +++ b/src/inference.ts @@ -0,0 +1,128 @@ +import * as path from "node:path"; + +import { withDefault } from "collection-utils"; + +import { + type LanguageName, + type TargetLanguage, + inferenceFlagNames, + isLanguageName, + languageNamed, + messageAssert, + messageError, +} from "quicktype-core"; + +import { negatedInferenceFlagName } from "./utils"; +import type { CLIOptions } from "./CLIOptions.types"; + +const defaultTargetLanguageName = "go"; + +function inferLang( + options: Partial, + defaultLanguage: LanguageName, +): string | LanguageName { + // Output file extension determines the language if language is undefined + if (options.out !== undefined) { + const extension = path.extname(options.out); + if (extension === "") { + return messageError("DriverNoLanguageOrExtension", {}); + } + + return extension.slice(1); + } + + return defaultLanguage; +} + +function inferTopLevel(options: Partial): string { + // Output file name determines the top-level if undefined + if (options.out !== undefined) { + const extension = path.extname(options.out); + const without = path.basename(options.out).replace(extension, ""); + return without; + } + + // Source determines the top-level if undefined + if (options.src !== undefined && options.src.length === 1) { + const src = options.src[0]; + const extension = path.extname(src); + const without = path.basename(src).replace(extension, ""); + return without; + } + + return "TopLevel"; +} + +export function inferCLIOptions( + opts: Partial, + targetLanguage: TargetLanguage | undefined, +): CLIOptions { + let srcLang = opts.srcLang; + if ( + opts.graphqlSchema !== undefined || + opts.graphqlIntrospect !== undefined + ) { + messageAssert( + srcLang === undefined || srcLang === "graphql", + "DriverSourceLangMustBeGraphQL", + {}, + ); + srcLang = "graphql"; + } else if ( + opts.src !== undefined && + opts.src.length > 0 && + opts.src.every((file) => file.endsWith(".ts")) + ) { + srcLang = "typescript"; + } else { + messageAssert(srcLang !== "graphql", "DriverGraphQLSchemaNeeded", {}); + srcLang = withDefault(srcLang, "json"); + } + + let language: TargetLanguage; + if (targetLanguage !== undefined) { + language = targetLanguage; + } else { + const languageName = + opts.lang ?? inferLang(opts, defaultTargetLanguageName); + + if (isLanguageName(languageName)) { + language = languageNamed(languageName); + } else { + return messageError("DriverUnknownOutputLanguage", { + lang: languageName, + }); + } + } + + const options: CLIOptions = { + src: opts.src ?? [], + srcUrls: opts.srcUrls, + srcLang: srcLang, + lang: language.name as LanguageName, + topLevel: opts.topLevel ?? inferTopLevel(opts), + noRender: !!opts.noRender, + alphabetizeProperties: !!opts.alphabetizeProperties, + allPropertiesOptional: !!opts.allPropertiesOptional, + rendererOptions: opts.rendererOptions ?? {}, + help: opts.help ?? false, + quiet: opts.quiet ?? false, + version: opts.version ?? false, + out: opts.out, + buildMarkovChain: opts.buildMarkovChain, + additionalSchema: opts.additionalSchema ?? [], + graphqlSchema: opts.graphqlSchema, + graphqlIntrospect: opts.graphqlIntrospect, + httpMethod: opts.httpMethod, + httpHeader: opts.httpHeader, + debug: opts.debug, + telemetry: opts.telemetry, + }; + for (const flagName of inferenceFlagNames) { + const cliName = negatedInferenceFlagName(flagName); + options[cliName] = !!opts[cliName]; + options[flagName] = !opts[cliName]; + } + + return options; +} diff --git a/src/input.ts b/src/input.ts new file mode 100644 index 000000000..2570e1fd5 --- /dev/null +++ b/src/input.ts @@ -0,0 +1,86 @@ +import type { Readable } from "readable-stream"; + +import { + FetchingJSONSchemaStore, + InputData, + JSONInput, + JSONSchemaInput, + type TargetLanguage, + assertNever, + defined, + isLanguageName, + languageNamed, +} from "quicktype-core"; +import { GraphQLInput } from "quicktype-graphql-input"; + +import { CompressedJSONFromStream } from "./CompressedJSONFromStream"; +import type { TypeSource } from "./TypeSource"; + +export function jsonInputForTargetLanguage( + _targetLanguage: string | TargetLanguage, + languages?: TargetLanguage[], + handleJSONRefs = false, +): JSONInput { + let targetLanguage: TargetLanguage; + if (typeof _targetLanguage === "string") { + const languageName = isLanguageName(_targetLanguage) + ? _targetLanguage + : "typescript"; + targetLanguage = defined(languageNamed(languageName, languages)); + } else { + targetLanguage = _targetLanguage; + } + + const compressedJSON = new CompressedJSONFromStream( + targetLanguage.dateTimeRecognizer, + handleJSONRefs, + ); + return new JSONInput(compressedJSON); +} + +export async function makeInputData( + sources: TypeSource[], + targetLanguage: TargetLanguage, + additionalSchemaAddresses: readonly string[], + handleJSONRefs: boolean, + httpHeaders?: string[], +): Promise { + const inputData = new InputData(); + + for (const source of sources) { + switch (source.kind) { + case "graphql": + await inputData.addSource( + "graphql", + source, + () => new GraphQLInput(), + ); + break; + case "json": + await inputData.addSource("json", source, () => + jsonInputForTargetLanguage( + targetLanguage, + undefined, + handleJSONRefs, + ), + ); + break; + case "schema": + await inputData.addSource( + "schema", + source, + () => + new JSONSchemaInput( + new FetchingJSONSchemaStore(httpHeaders), + [], + additionalSchemaAddresses, + ), + ); + break; + default: + return assertNever(source); + } + } + + return inputData; +} diff --git a/src/optionDefinitions.ts b/src/optionDefinitions.ts new file mode 100644 index 000000000..09ffe653b --- /dev/null +++ b/src/optionDefinitions.ts @@ -0,0 +1,190 @@ +import { + type InferenceFlagName, + type OptionDefinition, + type TargetLanguage, + inferenceFlags, +} from "quicktype-core"; + +import { dashedFromCamelCase, negatedInferenceFlagName } from "./utils"; + +export function makeOptionDefinitions( + targetLanguages: readonly TargetLanguage[], +): OptionDefinition[] { + const beforeLang: OptionDefinition[] = [ + { + name: "out", + alias: "o", + optionType: "string", + typeLabel: "FILE", + description: "The output file. Determines --lang and --top-level.", + kind: "cli", + defaultOption: true, + }, + { + name: "top-level", + alias: "t", + optionType: "string", + typeLabel: "NAME", + description: "The name for the top level type.", + kind: "cli", + }, + ]; + const lang: OptionDefinition[] = + targetLanguages.length < 2 + ? [] + : [ + { + name: "lang", + alias: "l", + optionType: "string", + typeLabel: "LANG", + description: "The target language.", + kind: "cli", + }, + ]; + const afterLang: OptionDefinition[] = [ + { + name: "src-lang", + alias: "s", + optionType: "string", + defaultValue: undefined, + typeLabel: "SRC_LANG", + description: "The source language (default is json).", + kind: "cli", + }, + { + name: "src", + optionType: "string", + multiple: true, + typeLabel: "FILE|URL|DIRECTORY", + description: "The file, url, or data directory to type.", + kind: "cli", + }, + { + name: "src-urls", + optionType: "string", + typeLabel: "FILE", + description: "Tracery grammar describing URLs to crawl.", + kind: "cli", + }, + ]; + const inference: OptionDefinition[] = Object.entries(inferenceFlags).map( + ([name, flag]) => ({ + name: dashedFromCamelCase( + negatedInferenceFlagName(name as InferenceFlagName), + ), + optionType: "boolean" as const, + // biome-ignore lint/style/useTemplate: + description: flag.negationDescription + ".", + kind: "cli" as const, + }), + ); + const afterInference: OptionDefinition[] = [ + { + name: "graphql-schema", + optionType: "string", + typeLabel: "FILE", + description: "GraphQL introspection file.", + kind: "cli", + }, + { + name: "graphql-introspect", + optionType: "string", + typeLabel: "URL", + description: "Introspect GraphQL schema from a server.", + kind: "cli", + }, + { + name: "http-method", + optionType: "string", + typeLabel: "METHOD", + description: + "HTTP method to use for the GraphQL introspection query.", + kind: "cli", + }, + { + name: "http-header", + optionType: "string", + multiple: true, + typeLabel: "HEADER", + description: + "Header(s) to attach to all HTTP requests, including the GraphQL introspection query.", + kind: "cli", + }, + { + name: "additional-schema", + alias: "S", + optionType: "string", + multiple: true, + typeLabel: "FILE", + description: "Register the $id's of additional JSON Schema files.", + kind: "cli", + }, + { + name: "no-render", + optionType: "boolean", + description: "Don't render output.", + kind: "cli", + }, + { + name: "alphabetize-properties", + optionType: "boolean", + description: "Alphabetize order of class properties.", + kind: "cli", + }, + { + name: "all-properties-optional", + optionType: "boolean", + description: "Make all class properties optional.", + kind: "cli", + }, + { + name: "build-markov-chain", + optionType: "string", + typeLabel: "FILE", + description: "Markov chain corpus filename.", + kind: "cli", + }, + { + name: "quiet", + optionType: "boolean", + description: "Don't show issues in the generated code.", + kind: "cli", + }, + { + name: "debug", + optionType: "string", + typeLabel: "OPTIONS or all", + description: + "Comma separated debug options: print-graph, print-reconstitution, print-gather-names, print-transformations, print-schema-resolving, print-times, provenance", + kind: "cli", + }, + { + name: "telemetry", + optionType: "string", + typeLabel: "enable|disable", + description: "Enable anonymous telemetry to help improve quicktype", + kind: "cli", + }, + { + name: "help", + alias: "h", + optionType: "boolean", + description: "Get some help.", + kind: "cli", + }, + { + name: "version", + alias: "v", + optionType: "boolean", + description: "Display the version of quicktype", + kind: "cli", + }, + ]; + return beforeLang.concat(lang, afterLang, inference, afterInference); +} + +export const transformDefinition = (def: OptionDefinition) => ({ + ...def, + type: def.optionType === "boolean" ? Boolean : String, +}); diff --git a/src/quicktype.options.ts b/src/quicktype.options.ts new file mode 100644 index 000000000..0763b1a02 --- /dev/null +++ b/src/quicktype.options.ts @@ -0,0 +1,254 @@ +import * as fs from "node:fs"; +import * as path from "node:path"; + +import { definedMap, withDefault } from "collection-utils"; +import _wordwrap from "wordwrap"; + +import { + type Options, + type TargetLanguage, + defaultTargetLanguages, + defined, + getStream, + inferenceFlagNames, + isLanguageName, + languageNamed, + messageError, + parseJSON, + readableFromFileOrURL, + sourcesFromPostmanCollection, + trainMarkovChain, +} from "quicktype-core"; + +import { introspectServer } from "./GraphQLIntrospection"; +import type { + GraphQLTypeSource, + JSONTypeSource, + TypeSource, +} from "./TypeSource"; +import { makeInputData } from "./input"; +import { getSources, makeTypeScriptSource } from "./sources"; +import { displayUsage } from "./usage"; +import { + negatedInferenceFlagName, + stringSourceDataToStreamSourceData, + typeNameFromFilename, +} from "./utils"; +import type { CLIOptions } from "./CLIOptions.types"; + +const packageJSON = require("../package.json"); + +const wordWrap: (s: string) => string = _wordwrap(90); + +export async function makeQuicktypeOptions( + options: CLIOptions, + targetLanguages?: TargetLanguage[], +): Promise | undefined> { + if (options.help) { + displayUsage(targetLanguages ?? defaultTargetLanguages); + return; + } + + if (options.version) { + console.log(`quicktype version ${packageJSON.version}`); + console.log("Visit quicktype.io for more info."); + return; + } + + if (options.buildMarkovChain !== undefined) { + const contents = fs.readFileSync(options.buildMarkovChain).toString(); + const lines = contents.split("\n"); + const markovChain = trainMarkovChain(lines, 3); + console.log(JSON.stringify(markovChain)); + return; + } + + let sources: TypeSource[] = []; + let leadingComments: string[] | undefined = undefined; + let fixedTopLevels = false; + switch (options.srcLang) { + case "graphql": { + let schemaString: string | undefined = undefined; + let wroteSchemaToFile = false; + if (options.graphqlIntrospect !== undefined) { + schemaString = await introspectServer( + options.graphqlIntrospect, + withDefault(options.httpMethod, "POST"), + withDefault(options.httpHeader, []), + ); + if (options.graphqlSchema !== undefined) { + fs.writeFileSync(options.graphqlSchema, schemaString); + wroteSchemaToFile = true; + } + } + + const numSources = options.src.length; + if (numSources !== 1) { + if (wroteSchemaToFile) { + // We're done. + return; + } + + if (numSources === 0) { + if (schemaString !== undefined) { + console.log(schemaString); + return; + } + + return messageError("DriverNoGraphQLQueryGiven", {}); + } + } + + const graphqlSources: GraphQLTypeSource[] = []; + for (const queryFile of options.src) { + let schemaFileName: string | undefined = undefined; + if (schemaString === undefined) { + schemaFileName = defined(options.graphqlSchema); + schemaString = fs.readFileSync(schemaFileName, "utf8"); + } + + const schema = parseJSON( + schemaString, + "GraphQL schema", + schemaFileName, + ); + const query = await getStream( + await readableFromFileOrURL(queryFile, options.httpHeader), + ); + const name = + numSources === 1 + ? options.topLevel + : typeNameFromFilename(queryFile); + graphqlSources.push({ kind: "graphql", name, schema, query }); + } + + sources = graphqlSources; + break; + } + case "json": + case "schema": + sources = await getSources(options); + break; + case "typescript": + sources = [makeTypeScriptSource(options.src)]; + break; + case "postman": + for (const collectionFile of options.src) { + const collectionJson = fs.readFileSync(collectionFile, "utf8"); + const { sources: postmanSources, description } = + sourcesFromPostmanCollection( + collectionJson, + collectionFile, + ); + for (const src of postmanSources) { + sources.push( + Object.assign( + { kind: "json" }, + stringSourceDataToStreamSourceData(src), + ) as JSONTypeSource, + ); + } + + if (postmanSources.length > 1) { + fixedTopLevels = true; + } + + if (description !== undefined) { + leadingComments = wordWrap(description).split("\n"); + } + } + + break; + default: + return messageError("DriverUnknownSourceLanguage", { + lang: options.srcLang, + }); + } + + const components = definedMap(options.debug, (d) => d.split(",")); + const debugAll = components?.includes("all"); + let debugPrintGraph = debugAll; + let checkProvenance = debugAll; + let debugPrintReconstitution = debugAll; + let debugPrintGatherNames = debugAll; + let debugPrintTransformations = debugAll; + let debugPrintSchemaResolving = debugAll; + let debugPrintTimes = debugAll; + if (components !== undefined) { + for (let component of components) { + component = component.trim(); + if (component === "print-graph") { + debugPrintGraph = true; + } else if (component === "print-reconstitution") { + debugPrintReconstitution = true; + } else if (component === "print-gather-names") { + debugPrintGatherNames = true; + } else if (component === "print-transformations") { + debugPrintTransformations = true; + } else if (component === "print-times") { + debugPrintTimes = true; + } else if (component === "print-schema-resolving") { + debugPrintSchemaResolving = true; + } else if (component === "provenance") { + checkProvenance = true; + } else if (component !== "all") { + return messageError("DriverUnknownDebugOption", { + option: component, + }); + } + } + } + + if (!isLanguageName(options.lang)) { + return messageError("DriverUnknownOutputLanguage", { + lang: options.lang, + }); + } + + const lang = languageNamed(options.lang, targetLanguages); + + const quicktypeOptions: Partial = { + lang, + alphabetizeProperties: options.alphabetizeProperties, + allPropertiesOptional: options.allPropertiesOptional, + fixedTopLevels, + noRender: options.noRender, + rendererOptions: options.rendererOptions, + leadingComments, + outputFilename: definedMap(options.out, path.basename), + debugPrintGraph, + checkProvenance, + debugPrintReconstitution, + debugPrintGatherNames, + debugPrintTransformations, + debugPrintSchemaResolving, + debugPrintTimes, + }; + + for (const flagName of inferenceFlagNames) { + const cliName = negatedInferenceFlagName(flagName); + const negatedValue = options[cliName]; + const positiveValue = options[flagName]; + const value = !(positiveValue == null) + ? positiveValue + : !(negatedValue == null) + ? negatedValue + : undefined; + + if (typeof value === "boolean") { + quicktypeOptions[flagName] = !value; + } else { + quicktypeOptions[flagName] = true; + } + } + + quicktypeOptions.inputData = await makeInputData( + sources, + lang, + options.additionalSchema, + quicktypeOptions.ignoreJsonRefs !== true, + options.httpHeader, + ); + + return quicktypeOptions; +} diff --git a/src/sources.ts b/src/sources.ts new file mode 100644 index 000000000..f4adbfaf2 --- /dev/null +++ b/src/sources.ts @@ -0,0 +1,280 @@ +#!/usr/bin/env node + +import * as fs from "node:fs"; +import * as path from "node:path"; + +import * as _ from "lodash"; +import type { Readable } from "readable-stream"; +import _wordwrap from "wordwrap"; + +import { + assertNever, + getStream, + messageAssert, + messageError, + panic, + parseJSON, + readFromFileOrURL, + readableFromFileOrURL, +} from "quicktype-core"; +import { schemaForTypeScriptSources } from "quicktype-typescript-input"; + +import type { + GraphQLTypeSource, + JSONTypeSource, + SchemaTypeSource, + TypeSource, +} from "./TypeSource"; +import { urlsFromURLGrammar } from "./URLGrammar"; +import { typeNameFromFilename } from "./utils"; +import type { CLIOptions } from "./CLIOptions.types"; + +async function sourceFromFileOrUrlArray( + name: string, + filesOrUrls: string[], + httpHeaders?: string[], +): Promise { + const samples = await Promise.all( + filesOrUrls.map( + async (file) => await readableFromFileOrURL(file, httpHeaders), + ), + ); + return { kind: "json", name, samples }; +} + +async function samplesFromDirectory( + dataDir: string, + httpHeaders?: string[], +): Promise { + async function readFilesOrURLsInDirectory( + d: string, + ): Promise { + const files = fs + .readdirSync(d) + .map((x) => path.join(d, x)) + .filter((x) => fs.lstatSync(x).isFile()); + // Each file is a (Name, JSON | URL) + const sourcesInDir: TypeSource[] = []; + const graphQLSources: GraphQLTypeSource[] = []; + let graphQLSchema: Readable | undefined = undefined; + let graphQLSchemaFileName: string | undefined = undefined; + for (let file of files) { + const name = typeNameFromFilename(file); + + let fileOrUrl = file; + file = file.toLowerCase(); + + // If file is a URL string, download it + if (file.endsWith(".url")) { + fileOrUrl = fs.readFileSync(file, "utf8").trim(); + } + + if (file.endsWith(".url") || file.endsWith(".json")) { + sourcesInDir.push({ + kind: "json", + name, + samples: [ + await readableFromFileOrURL(fileOrUrl, httpHeaders), + ], + }); + } else if (file.endsWith(".schema")) { + sourcesInDir.push({ + kind: "schema", + name, + uris: [fileOrUrl], + }); + } else if (file.endsWith(".gqlschema")) { + messageAssert( + graphQLSchema === undefined, + "DriverMoreThanOneGraphQLSchemaInDir", + { + dir: dataDir, + }, + ); + graphQLSchema = await readableFromFileOrURL( + fileOrUrl, + httpHeaders, + ); + graphQLSchemaFileName = fileOrUrl; + } else if (file.endsWith(".graphql")) { + graphQLSources.push({ + kind: "graphql", + name, + schema: undefined, + query: await getStream( + await readableFromFileOrURL(fileOrUrl, httpHeaders), + ), + }); + } + } + + if (graphQLSources.length > 0) { + if (graphQLSchema === undefined) { + return messageError("DriverNoGraphQLSchemaInDir", { + dir: dataDir, + }); + } + + const schema = parseJSON( + await getStream(graphQLSchema), + "GraphQL schema", + graphQLSchemaFileName, + ); + for (const source of graphQLSources) { + source.schema = schema; + sourcesInDir.push(source); + } + } + + return sourcesInDir; + } + + const contents = fs.readdirSync(dataDir).map((x) => path.join(dataDir, x)); + const directories = contents.filter((x) => fs.lstatSync(x).isDirectory()); + + let sources = await readFilesOrURLsInDirectory(dataDir); + + for (const dir of directories) { + let jsonSamples: Readable[] = []; + const schemaSources: SchemaTypeSource[] = []; + const graphQLSources: GraphQLTypeSource[] = []; + + for (const source of await readFilesOrURLsInDirectory(dir)) { + switch (source.kind) { + case "json": + jsonSamples = jsonSamples.concat(source.samples); + break; + case "schema": + schemaSources.push(source); + break; + case "graphql": + graphQLSources.push(source); + break; + default: + return assertNever(source); + } + } + + if ( + jsonSamples.length > 0 && + schemaSources.length + graphQLSources.length > 0 + ) { + return messageError("DriverCannotMixJSONWithOtherSamples", { + dir: dir, + }); + } + + // FIXME: rewrite this to be clearer + const oneUnlessEmpty = (xs: TypeSource[]): 0 | 1 => + Math.sign(xs.length) as 0 | 1; + if ( + oneUnlessEmpty(schemaSources) + oneUnlessEmpty(graphQLSources) > + 1 + ) { + return messageError("DriverCannotMixNonJSONInputs", { dir: dir }); + } + + if (jsonSamples.length > 0) { + sources.push({ + kind: "json", + name: path.basename(dir), + samples: jsonSamples, + }); + } + + sources = sources.concat(schemaSources); + sources = sources.concat(graphQLSources); + } + + return sources; +} + +// Returns an array of [name, sourceURIs] pairs. +async function getSourceURIs( + options: CLIOptions, +): Promise> { + if (options.srcUrls !== undefined) { + const json = parseJSON( + await readFromFileOrURL(options.srcUrls, options.httpHeader), + "URL grammar", + options.srcUrls, + ); + const jsonMap = urlsFromURLGrammar(json); + const topLevels = Object.getOwnPropertyNames(jsonMap); + return topLevels.map( + (name) => [name, jsonMap[name]] as [string, string[]], + ); + } + if (options.src.length === 0) { + return [[options.topLevel, ["-"]]]; + } + + return []; +} + +async function typeSourcesForURIs( + name: string, + uris: string[], + options: CLIOptions, +): Promise { + switch (options.srcLang) { + case "json": + return [ + await sourceFromFileOrUrlArray(name, uris, options.httpHeader), + ]; + case "schema": + return uris.map( + (uri) => + ({ + kind: "schema", + name, + uris: [uri], + }) as SchemaTypeSource, + ); + default: + return panic( + `typeSourceForURIs must not be called for source language ${options.srcLang}`, + ); + } +} + +export async function getSources(options: CLIOptions): Promise { + const sourceURIs = await getSourceURIs(options); + const sourceArrays = await Promise.all( + sourceURIs.map( + async ([name, uris]) => + await typeSourcesForURIs(name, uris, options), + ), + ); + let sources: TypeSource[] = ([] as TypeSource[]).concat(...sourceArrays); + + const exists = options.src.filter(fs.existsSync); + const directories = exists.filter((x) => fs.lstatSync(x).isDirectory()); + + for (const dataDir of directories) { + sources = sources.concat( + await samplesFromDirectory(dataDir, options.httpHeader), + ); + } + + // Every src that's not a directory is assumed to be a file or URL + const filesOrUrls = options.src.filter((x) => !_.includes(directories, x)); + if (!_.isEmpty(filesOrUrls)) { + sources.push( + ...(await typeSourcesForURIs( + options.topLevel, + filesOrUrls, + options, + )), + ); + } + + return sources; +} + +export function makeTypeScriptSource(fileNames: string[]): SchemaTypeSource { + return Object.assign( + { kind: "schema" }, + schemaForTypeScriptSources(fileNames), + ) as SchemaTypeSource; +} diff --git a/src/usage.ts b/src/usage.ts new file mode 100644 index 000000000..b94d0d536 --- /dev/null +++ b/src/usage.ts @@ -0,0 +1,127 @@ +#!/usr/bin/env node + +import chalk from "chalk"; +import getUsage from "command-line-usage"; +import * as _ from "lodash"; +import _wordwrap from "wordwrap"; + +import type { OptionDefinition, TargetLanguage } from "quicktype-core"; + +import { makeOptionDefinitions } from "./optionDefinitions"; +import { makeLangTypeLabel } from "./utils"; + +interface ColumnDefinition { + name: string; + padding?: { left: string; right: string }; + width?: number; +} + +interface TableOptions { + columns: ColumnDefinition[]; +} + +interface UsageSection { + content?: string | string[]; + header?: string; + hide?: string[]; + optionList?: OptionDefinition[]; + tableOptions?: TableOptions; +} + +const tableOptionsForOptions: TableOptions = { + columns: [ + { + name: "option", + width: 60, + }, + { + name: "description", + width: 60, + }, + ], +}; + +function makeSectionsBeforeRenderers( + targetLanguages: readonly TargetLanguage[], +): UsageSection[] { + const langDisplayNames = targetLanguages + .map((r) => r.displayName) + .join(", "); + + return [ + { + header: "Synopsis", + content: [ + `$ quicktype [${chalk.bold("--lang")} LANG] [${chalk.bold("--src-lang")} SRC_LANG] [${chalk.bold( + "--out", + )} FILE] FILE|URL ...`, + "", + ` LANG ... ${makeLangTypeLabel(targetLanguages)}`, + "", + "SRC_LANG ... json|schema|graphql|postman|typescript", + ], + }, + { + header: "Description", + content: `Given JSON sample data, quicktype outputs code for working with that data in ${langDisplayNames}.`, + }, + { + header: "Options", + optionList: makeOptionDefinitions(targetLanguages), + hide: ["no-render", "build-markov-chain"], + tableOptions: tableOptionsForOptions, + }, + ]; +} + +const sectionsAfterRenderers: UsageSection[] = [ + { + header: "Examples", + content: [ + chalk.dim("Generate C# to parse a Bitcoin API"), + "$ quicktype -o LatestBlock.cs https://blockchain.info/latestblock", + "", + chalk.dim( + "Generate Go code from a directory of samples containing:", + ), + chalk.dim( + ` - Foo.json + + Bar + - bar-sample-1.json + - bar-sample-2.json + - Baz.url`, + ), + "$ quicktype -l go samples", + "", + chalk.dim("Generate JSON Schema, then TypeScript"), + "$ quicktype -o schema.json https://blockchain.info/latestblock", + "$ quicktype -o bitcoin.ts --src-lang schema schema.json", + ], + }, + { + content: `Learn more at ${chalk.bold("quicktype.io")}`, + }, +]; + +export function displayUsage(targetLanguages: readonly TargetLanguage[]): void { + const rendererSections: UsageSection[] = []; + + for (const language of targetLanguages) { + const definitions = language.cliOptionDefinitions.display; + if (definitions.length === 0) continue; + + rendererSections.push({ + header: `Options for ${language.displayName}`, + optionList: definitions, + tableOptions: tableOptionsForOptions, + }); + } + + const sections = _.concat( + makeSectionsBeforeRenderers(targetLanguages), + rendererSections, + sectionsAfterRenderers, + ); + + console.log(getUsage(sections)); +} diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 000000000..d2f4a5fde --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,61 @@ +import * as path from "node:path"; + +import * as _ from "lodash"; +import type { Readable } from "readable-stream"; +import stringToStream from "string-to-stream"; +import _wordwrap from "wordwrap"; + +import { + assert, + type InferenceFlagName, + splitIntoWords, + type JSONSourceData, + type TargetLanguage, +} from "quicktype-core"; + +import type { NegatedInferenceFlagName } from "./CLIOptions.types"; + +export function makeLangTypeLabel( + targetLanguages: readonly TargetLanguage[], +): string { + assert( + targetLanguages.length > 0, + "Must have at least one target language", + ); + return targetLanguages + .map((r) => _.minBy(r.names, (s) => s.length)) + .join("|"); +} + +export function negatedInferenceFlagName( + inputName: Input, +): NegatedInferenceFlagName { + const withoutLeadingInfer = inputName.replace(/^infer/, ""); + const asPascalCase = withoutLeadingInfer.replace(/^\w/, (x) => + x.toUpperCase(), + ); + return `no${asPascalCase}` as NegatedInferenceFlagName; +} + +export function dashedFromCamelCase(name: string): string { + return splitIntoWords(name) + .map((w) => w.word.toLowerCase()) + .join("-"); +} + +export function typeNameFromFilename(filename: string): string { + const name = path.basename(filename); + return name.substring(0, name.lastIndexOf(".")); +} + +export function stringSourceDataToStreamSourceData( + src: JSONSourceData, +): JSONSourceData { + return { + name: src.name, + description: src.description, + samples: src.samples.map( + (sample) => stringToStream(sample) as Readable, + ), + }; +} diff --git a/test/buildkite.ts b/test/buildkite.ts index e0d2ac89d..5869329bf 100644 --- a/test/buildkite.ts +++ b/test/buildkite.ts @@ -11,10 +11,8 @@ function getChangedFiles(base: string, commit: string): string[] { return diff.trim().split("\n"); } -export function affectedFixtures( - changedFiles: string[] | undefined = undefined, -): Fixture[] { - if (changedFiles === undefined) { +export function affectedFixtures(_changedFiles?: string[]): Fixture[] { + if (_changedFiles === undefined) { const { GITHUB_BASE_REF: base, GITHUB_SHA: commit } = process.env; return commit === undefined ? allFixtures @@ -22,7 +20,9 @@ export function affectedFixtures( } // We can ignore changes in Markdown files - changedFiles = _.reject(changedFiles, (file) => _.endsWith(file, ".md")); + const changedFiles = _.reject(_changedFiles, (file) => + _.endsWith(file, ".md"), + ); // All fixtures are dirty if any changed file is not included as a sourceFile of some fixture. const fileDependencies = _.flatMap( diff --git a/test/cli/options.test.ts b/test/cli/options.test.ts new file mode 100644 index 000000000..b0b7209ad --- /dev/null +++ b/test/cli/options.test.ts @@ -0,0 +1,177 @@ +import { expect, it, beforeEach } from "vitest"; + +import commandLineArgs from "command-line-args"; + +import { inferenceFlagNames, type Option } from "../../packages/quicktype-core"; +import type { EnumOption } from "../../packages/quicktype-core/dist/RendererOptions"; +import { Chance } from "../../packages/quicktype-core/src/support/Chance"; +import { all as sourceLanguages } from "../../packages/quicktype-core/dist/language/All"; + +import { parseOptions } from "../../src/cli.options"; +import { + makeOptionDefinitions, + transformDefinition, +} from "../../src/optionDefinitions"; +import { negatedInferenceFlagName } from "../../src/utils"; +import { inferCLIOptions } from "../../src/inference"; + +import * as fixtureLanguages from "../languages"; + +const optionsDefinitions = makeOptionDefinitions([]); +const chance = new Chance(0); + +let randomStrings: Record = {}; +let argv: string[] = []; + +beforeEach(() => { + randomStrings = {}; + argv = optionsDefinitions.reduce((strArr, def, i) => { + if (def.optionType === "string") { + const randomString = chance.animal(); + randomStrings[i] = randomString; + + return strArr.concat([`--${def.name}`, randomString]); + } + + return strArr.concat([`--${def.name}`]); + }, [] as string[]); +}); + +it("should call command-line-args for all generic cli options", () => { + const args = commandLineArgs(optionsDefinitions.map(transformDefinition), { + argv, + partial: true, + }); + + const expectedOutput = optionsDefinitions.reduce((acc, def, i) => { + if (def.optionType === "string") { + if (def.multiple) { + acc[def.name] = [randomStrings[i]]; + } else { + acc[def.name] = randomStrings[i]; + } + return acc; + } + + acc[def.name] = true; + return acc; + }, {}); + + expect(args).toStrictEqual(expectedOutput); +}); + +it("should process inference cli options correctly", () => { + const randomTargetLang = chance.pick(sourceLanguages); + + // throw for graphql check + const parsedOptions = parseOptions(optionsDefinitions, argv, true); + expect(() => inferCLIOptions(parsedOptions, randomTargetLang)).toThrow(); + + // pass graphql check + parsedOptions.srcLang = "graphql"; + expect(() => + inferCLIOptions(parsedOptions, randomTargetLang), + ).not.toThrow(); + + // infer ts input + parsedOptions.srcLang = undefined; + parsedOptions.graphqlIntrospect = undefined; + parsedOptions.graphqlSchema = undefined; + parsedOptions.src = parsedOptions.src?.map((str) => `${str}.ts`); + expect(inferCLIOptions(parsedOptions, randomTargetLang)).toMatchObject({ + srcLang: "typescript", + }); + + // throw on unknown target lang + expect(() => inferCLIOptions(parsedOptions, undefined)).toThrow(); + + // infer target lang + parsedOptions.lang = undefined; + parsedOptions.out = `${parsedOptions.out}.${randomTargetLang.extension}`; + + const inferredOptionsWithTargetLang = inferCLIOptions( + parsedOptions, + undefined, + ); + expect(inferredOptionsWithTargetLang).toMatchObject({ + lang: randomTargetLang.name, + }); + + // check inference flags + for (const flagName of inferenceFlagNames) { + const negatedFlagName = negatedInferenceFlagName(flagName); + + expect(inferredOptionsWithTargetLang[flagName]).toEqual( + !!parsedOptions[flagName], + ); + expect(inferredOptionsWithTargetLang[negatedFlagName]).toEqual( + !parsedOptions[flagName], + ); + } +}); + +for (const [name, fixtureLanguage] of Object.entries(fixtureLanguages)) { + const languageClass = sourceLanguages.find((lang) => + (lang.names as readonly string[]).includes(fixtureLanguage.name), + ); + + if (!languageClass) { + // it.skip(`does not have language fixture for ${fixtureLanguage.name} language`, () => {}); + continue; + } + + const fixtureRendererOptionsEntries = [ + fixtureLanguage.rendererOptions, + ...fixtureLanguage.quickTestRendererOptions, + ].flatMap((optionsObj) => Object.entries(optionsObj)); + + const dedupeKeys = {}; + const rendererOptionsArgv = fixtureRendererOptionsEntries.reduce( + (strArr, [k, v]) => { + if (k in dedupeKeys) { + return strArr; + } + + dedupeKeys[k] = true; + return strArr.concat([`--${k}`, v as string]); + }, + [] as string[], + ); + + it(`should parse rendererOptions for ${name} fixture`, () => { + const parsedOptions = parseOptions( + optionsDefinitions.concat( + languageClass.cliOptionDefinitions.actual, + ), + argv.concat(rendererOptionsArgv), + true, + ); + const options = languageClass.getOptions(); + + const isAllRendererOptionsValid = + parsedOptions.rendererOptions && + (Object.values(options) as Option[]).every( + (option) => { + const parsedValue = + parsedOptions.rendererOptions?.[option.name]; + + if (option.definition.optionType === "enum") { + try { + // biome-ignore lint/suspicious/noExplicitAny: + (option as EnumOption).getEnumValue( + parsedValue, + ); + return true; + } catch { + return false; + } + } + + // biome-ignore lint/suspicious/useValidTypeof: optionType is only 'string' | 'boolean' in this case + return option.definition.optionType === typeof parsedValue; + }, + ); + + expect(isAllRendererOptionsValid).toBeTruthy(); + }); +} diff --git a/test/cli/quicktype.options.test.ts b/test/cli/quicktype.options.test.ts new file mode 100644 index 000000000..d70057442 --- /dev/null +++ b/test/cli/quicktype.options.test.ts @@ -0,0 +1,230 @@ +/** Generated unit test */ +import { describe, expect, it, vi } from "vitest"; + +import { makeQuicktypeOptions } from "../../src/quicktype.options"; + +import * as fs from "node:fs"; +import * as usage from "../../src/usage"; +import * as sources from "../../src/sources"; +import * as graphql from "../../src/GraphQLIntrospection"; +import * as quicktypeCore from "quicktype-core"; + +vi.mock("node:fs", () => ({ + readFileSync: vi.fn(), + writeFileSync: vi.fn(), +})); +vi.mock("../../src/usage", () => ({ + displayUsage: vi.fn(), +})); +vi.mock("../../src/input", () => ({ + makeInputData: vi.fn().mockResolvedValue("inputData"), +})); +vi.mock("../../src/sources", () => ({ + getSources: vi.fn().mockResolvedValue([{ kind: "json", name: "test" }]), + makeTypeScriptSource: vi + .fn() + .mockReturnValue({ kind: "typescript", name: "ts" }), +})); +vi.mock("../../src/GraphQLIntrospection", () => ({ + introspectServer: vi.fn().mockResolvedValue('{"__schema":{}}'), +})); +vi.mock("quicktype-core", async (importOriginal) => { + const mod = await importOriginal(); + return { + // @ts-expect-error + ...mod, + parseJSON: vi.fn().mockReturnValue({}), + getStream: vi.fn().mockResolvedValue("query"), + readableFromFileOrURL: vi.fn().mockResolvedValue("stream"), + sourcesFromPostmanCollection: vi.fn().mockReturnValue({ + sources: ["postmanSrc"], + description: "desc", + }), + trainMarkovChain: vi.fn().mockReturnValue({ chain: true }), + isLanguageName: vi + .fn() + .mockImplementation( + (lang) => lang === "typescript" || lang === "json", + ), + languageNamed: vi.fn().mockReturnValue({ name: "typescript" }), + messageError: vi.fn().mockReturnValue("error"), + inferenceFlagNames: ["inferMaps", "inferEnums"], + negatedInferenceFlagName: (flag) => + `no${flag[0].toUpperCase()}${flag.slice(1)}`, + defined: vi.fn((x) => x), + defaultTargetLanguages: [], + }; +}); +vi.mock("../../src/utils", async (importOriginal) => { + const mod = await importOriginal(); + return { + // @ts-expect-error + ...mod, + stringSourceDataToStreamSourceData: vi + .fn() + .mockReturnValue({ data: "stream" }), + typeNameFromFilename: vi.fn().mockReturnValue("TypeName"), + negatedInferenceFlagName: (flag) => + `no${flag[0].toUpperCase()}${flag.slice(1)}`, + }; +}); + +describe("makeQuicktypeOptions", () => { + const baseOptions = { + lang: "typescript", + srcLang: "json", + src: ["input.json"], + rendererOptions: {}, + debug: undefined, + out: "output.ts", + help: undefined, + version: undefined, + buildMarkovChain: undefined, + graphqlIntrospect: undefined, + graphqlSchema: undefined, + httpHeader: undefined, + topLevel: undefined, + additionalSchema: undefined, + alphabetizeProperties: false, + allPropertiesOptional: false, + noRender: false, + }; + + // afterEach(() => { + // vi.clearAllMocks(); + // }); + + it("should call displayUsage and return undefined if help is set", async () => { + const options = { ...baseOptions, help: true }; + const spy = vi.spyOn(usage, "displayUsage"); + // biome-ignore lint/suspicious/noExplicitAny: + const result = await makeQuicktypeOptions(options as any); + expect(spy).toHaveBeenCalled(); + expect(result).toBeUndefined(); + }); + + it("should log version and return undefined if version is set", async () => { + const options = { ...baseOptions, version: true }; + const logSpy = vi.spyOn(console, "log").mockImplementation(() => {}); + // biome-ignore lint/suspicious/noExplicitAny: + const result = await makeQuicktypeOptions(options as any); + expect(logSpy).toHaveBeenCalled(); + expect(result).toBeUndefined(); + logSpy.mockRestore(); + }); + + it("should handle buildMarkovChain option", async () => { + const options = { ...baseOptions, buildMarkovChain: "file.txt" }; + const readSpy = vi + .spyOn(fs, "readFileSync") + // biome-ignore lint/suspicious/noExplicitAny: + .mockReturnValue("a\nb\nc" as any); + const logSpy = vi.spyOn(console, "log").mockImplementation(() => {}); + // biome-ignore lint/suspicious/noExplicitAny: + const result = await makeQuicktypeOptions(options as any); + expect(readSpy).toHaveBeenCalledWith("file.txt"); + expect(logSpy).toHaveBeenCalled(); + expect(result).toBeUndefined(); + logSpy.mockRestore(); + }); + + it("should handle JSON srcLang and call getSources", async () => { + const options = { ...baseOptions, srcLang: "json" }; + const getSourcesSpy = vi.spyOn(sources, "getSources"); + // biome-ignore lint/suspicious/noExplicitAny: + const result = await makeQuicktypeOptions(options as any); + expect(getSourcesSpy).toHaveBeenCalled(); + expect(result).toMatchObject({ + lang: { name: "typescript" }, + inputData: "inputData", + }); + }); + + it("should handle typescript srcLang and call makeTypeScriptSource", async () => { + const options = { ...baseOptions, srcLang: "typescript" }; + const makeTSSpy = vi.spyOn(sources, "makeTypeScriptSource"); + // biome-ignore lint/suspicious/noExplicitAny: + const result = await makeQuicktypeOptions(options as any); + expect(makeTSSpy).toHaveBeenCalledWith(options.src); + expect(result).toMatchObject({ + lang: { name: "typescript" }, + inputData: "inputData", + }); + }); + + it("should handle postman srcLang and call sourcesFromPostmanCollection", async () => { + const options = { + ...baseOptions, + srcLang: "postman", + src: ["collection.json"], + }; + // biome-ignore lint/suspicious/noExplicitAny: + vi.spyOn(fs, "readFileSync").mockReturnValue("{}" as any); + const spy = vi.spyOn(quicktypeCore, "sourcesFromPostmanCollection"); + // biome-ignore lint/suspicious/noExplicitAny: + const result = await makeQuicktypeOptions(options as any); + expect(spy).toHaveBeenCalled(); + expect(result).toMatchObject({ + lang: { name: "typescript" }, + leadingComments: ["desc"], + inputData: "inputData", + }); + }); + + it("should handle graphql srcLang with introspection and schema file", async () => { + const options = { + ...baseOptions, + srcLang: "graphql", + src: ["query.graphql"], + graphqlIntrospect: "http://localhost/graphql", + graphqlSchema: "schema.json", + }; + const introspectSpy = vi.spyOn(graphql, "introspectServer"); + const writeSpy = vi.spyOn(fs, "writeFileSync"); + // biome-ignore lint/suspicious/noExplicitAny: + const result = await makeQuicktypeOptions(options as any); + expect(introspectSpy).toHaveBeenCalled(); + expect(writeSpy).toHaveBeenCalledWith( + "schema.json", + expect.any(String), + ); + expect(result).toMatchObject({ + lang: { name: "typescript" }, + inputData: "inputData", + }); + }); + + it("should return error for unknown srcLang", async () => { + const options = { ...baseOptions, srcLang: "unknown" }; + // biome-ignore lint/suspicious/noExplicitAny: + const result = await makeQuicktypeOptions(options as any); + expect(result).toBe("error"); + }); + + it("should return error for unknown output language", async () => { + const options = { ...baseOptions, lang: "unknown" }; + // biome-ignore lint/suspicious/noExplicitAny: + const result = await makeQuicktypeOptions(options as any); + expect(result).toBe("error"); + }); + + it("should set debug flags from options.debug", async () => { + const options = { ...baseOptions, debug: "print-graph,provenance" }; + // biome-ignore lint/suspicious/noExplicitAny: + const result = await makeQuicktypeOptions(options as any); + expect(result?.debugPrintGraph).toBe(true); + expect(result?.checkProvenance).toBe(true); + }); + + it("should set inference flags from CLI options", async () => { + const options = { + ...baseOptions, + noInferMaps: true, + noInferEnums: false, + }; + // biome-ignore lint/suspicious/noExplicitAny: + const result = await makeQuicktypeOptions(options as any); + expect(result?.inferMaps).toBe(false); + expect(result?.inferEnums).toBe(true); + }); +}); diff --git a/test/fixtures.ts b/test/fixtures.ts index 0472762b3..07837a05d 100644 --- a/test/fixtures.ts +++ b/test/fixtures.ts @@ -103,7 +103,7 @@ function runEnvForLanguage( const newEnv = Object.assign({}, process.env); for (const option of Object.keys(additionalRendererOptions)) { - newEnv["QUICKTYPE_" + option.toUpperCase().replace("-", "_")] = ( + newEnv[`QUICKTYPE_${option.toUpperCase().replace("-", "_")}`] = ( additionalRendererOptions[ option as keyof typeof additionalRendererOptions ] as Option @@ -216,10 +216,6 @@ export abstract class Fixture { } abstract class LanguageFixture extends Fixture { - constructor(language: languages.Language) { - super(language); - } - async setup() { const setupCommand = this.language.setupCommand; if (!setupCommand || ONLY_OUTPUT) { diff --git a/test/languages.ts b/test/languages.ts index 638c3a91d..493675173 100644 --- a/test/languages.ts +++ b/test/languages.ts @@ -1,6 +1,6 @@ import type { LanguageName } from "quicktype-core"; -import * as process from "process"; +import * as process from "node:process"; // @ts-ignore import type { RendererOptions } from "../dist/quicktype-core/Run"; @@ -78,7 +78,7 @@ export interface Language { skipMiscJSON: boolean; skipSchema: string[]; rendererOptions: RendererOptions; - quickTestRendererOptions: (RendererOptions | [string, RendererOptions])[]; + quickTestRendererOptions: RendererOptions[]; sourceFiles?: string[]; } @@ -720,7 +720,7 @@ export const ElmLanguage: Language = { export const SwiftLanguage: Language = { name: "swift", base: "test/fixtures/swift", - compileCommand: `swiftc -o quicktype main.swift quicktype.swift`, + compileCommand: "swiftc -o quicktype main.swift quicktype.swift", runCommand(sample: string) { return `./quicktype "${sample}"`; }, @@ -807,7 +807,7 @@ export const SwiftLanguage: Language = { export const ObjectiveCLanguage: Language = { name: "objective-c", base: "test/fixtures/objective-c", - compileCommand: `clang -Werror -framework Foundation *.m -o test`, + compileCommand: "clang -Werror -framework Foundation *.m -o test", runCommand(sample: string) { return `cp "${sample}" sample.json && ./test sample.json`; }, diff --git a/test/lib/deepEquals.ts b/test/lib/deepEquals.ts index eaeb1209a..8b7db9e15 100644 --- a/test/lib/deepEquals.ts +++ b/test/lib/deepEquals.ts @@ -3,6 +3,7 @@ import type { Moment } from "moment"; import type { ComparisonRelaxations } from "../utils"; function pathToString(path: string[]): string { + // biome-ignore lint/style/useTemplate: return "." + path.join("."); } @@ -13,9 +14,13 @@ declare namespace Math { function tryParseMoment(s: string): [Moment | undefined, boolean] { let m = moment(s); - if (m.isValid()) return [m, false]; + if (m.isValid()) { + return [m, false]; + } m = moment(s, "HH:mm:ss.SSZ"); - if (m.isValid()) return [m, true]; + if (m.isValid()) { + return [m, true]; + } return [undefined, false]; } diff --git a/test/lib/multicore.ts b/test/lib/multicore.ts index 117f28010..d4169709e 100644 --- a/test/lib/multicore.ts +++ b/test/lib/multicore.ts @@ -1,6 +1,5 @@ -import cluster from "cluster"; -import process from "process"; -import * as _ from "lodash"; +import cluster from "node:cluster"; +import process from "node:process"; const exit = require("exit"); @@ -18,8 +17,8 @@ function randomPick(arr: T[]): T { } function guys(n: number): string { - return _.range(n) - .map((_i) => randomPick(WORKERS)) + return Array.from({ length: n }) + .map(() => randomPick(WORKERS)) .join(" "); } @@ -63,13 +62,13 @@ export async function inParallel( await map(item, i); } } else { - _.range(workers).forEach((i) => + for (let i = 0; i < workers; i++) { cluster.fork({ worker: i, // https://github.com/TypeStrong/ts-node/issues/367 TS_NODE_PROJECT: "test/tsconfig.json", - }), - ); + }); + } } } else { // Setup a worker diff --git a/test/test.ts b/test/test.ts index e3e5ddf76..2e9143946 100755 --- a/test/test.ts +++ b/test/test.ts @@ -1,11 +1,10 @@ import cluster from "node:cluster"; -import * as os from "os"; -import * as _ from "lodash"; +import * as os from "node:os"; import { inParallel } from "./lib/multicore"; import { execAsync, type Sample } from "./utils"; -import { type Fixture, allFixtures } from "./fixtures"; +import { allFixtures } from "./fixtures"; import { affectedFixtures, divideParallelJobs } from "./buildkite"; import { checkCoreImportKeepsStdoutClean } from "./check-clean-import"; import { checkJavaEnumAcronymCasing } from "./check-java-acronym-names"; @@ -51,8 +50,8 @@ async function main(sources: string[]) { const fixturesFromCmdline = process.env.FIXTURE; if (fixturesFromCmdline) { const fixtureNames = fixturesFromCmdline.split(","); - fixtures = _.filter(fixtures, (fixture) => - _.some(fixtureNames, (name) => fixture.runForName(name)), + fixtures = fixtures.filter((fixture) => + fixtureNames.some((name) => fixture.runForName(name)), ); } @@ -65,24 +64,24 @@ async function main(sources: string[]) { // Get an array of all { sample, fixtureName } objects we'll run. // We can't just put the fixture in there because these WorkItems // will be sent in a message, removing all code. - const samples = _.map(fixtures, (fixture) => ({ + const samples = fixtures.map((fixture) => ({ fixtureName: fixture.name, samples: fixture.getSamples(sources), })); - const priority = _.flatMap(samples, (x) => - _.map(x.samples.priority, (s) => ({ - fixtureName: x.fixtureName, - sample: s, + const priority = samples.flatMap((sample) => + sample.samples.priority.map((prioritySample) => ({ + fixtureName: sample.fixtureName, + sample: prioritySample, })), ); - const others = _.flatMap(samples, (x) => - _.map(x.samples.others, (s) => ({ - fixtureName: x.fixtureName, - sample: s, + const others = samples.flatMap((sample) => + sample.samples.others.map((otherSample) => ({ + fixtureName: sample.fixtureName, + sample: otherSample, })), ); - const tests = divideParallelJobs(_.concat(priority, others)); + const tests = divideParallelJobs(priority.concat(others)); await inParallel({ queue: tests, @@ -94,17 +93,20 @@ async function main(sources: string[]) { ); for (const fixture of fixtures) { - await execAsync(`rm -rf test/runs`); - await execAsync(`mkdir -p test/runs`); + await execAsync("rm -rf test/runs"); + await execAsync("mkdir -p test/runs"); await fixture.setup(); } }, map: async ({ sample, fixtureName }: WorkItem, index) => { - const fixture = _.find(fixtures, { name: fixtureName }) as Fixture; + const fixture = fixtures.find( + (fixture) => fixture.name === fixtureName, + ); + try { - await fixture.runWithSample(sample, index, tests.length); + await fixture?.runWithSample(sample, index, tests.length); } catch (e) { console.trace(e); exit(1); diff --git a/test/utils.ts b/test/utils.ts index b532a2e8f..f2196f122 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -52,19 +52,16 @@ export function callAndExpectFailure(message: string, f: () => T): void { } export function exec( - s: string, - env: NodeJS.ProcessEnv | undefined, + str: string, + env: NodeJS.ProcessEnv = process.env, printFailure = true, ): { stdout: string; code: number } { - debug(s); - if (env === undefined) { - env = process.env; - } - const result = shell.exec(s, { silent: !DEBUG, env }); + debug(str); + const result = shell.exec(str, { silent: !DEBUG, env }); if (result.code !== 0) { const failureObj = { - command: s, + command: str, code: result.code, }; if (!printFailure) {