From 4da4827bcbcdd1ef163f635d9b29416ff272b0bb Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Mon, 27 Nov 2023 12:48:14 -0500 Subject: Add JSDoc type annotations to project (rebased) --- .eslintrc.json | 258 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 248 insertions(+), 10 deletions(-) (limited to '.eslintrc.json') diff --git a/.eslintrc.json b/.eslintrc.json index f1a79770..3200d292 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -2,15 +2,22 @@ "root": true, "extends": [ "eslint:recommended", - "plugin:jsonc/recommended-with-json" + "plugin:jsonc/recommended-with-json", + "plugin:@typescript-eslint/recommended" ], + "parser": "@typescript-eslint/parser", "parserOptions": { "ecmaVersion": 2022, "sourceType": "module", "ecmaFeatures": { "globalReturn": false, "impliedStrict": true - } + }, + "project": [ + "./jsconfig.json", + "./dev/jsconfig.json", + "./test/jsconfig.json" + ] }, "env": { "browser": true, @@ -21,7 +28,10 @@ "no-unsanitized", "header", "jsdoc", - "jsonc" + "jsonc", + "unused-imports", + "@typescript-eslint", + "@stylistic/ts" ], "ignorePatterns": [ "/ext/lib/", @@ -56,7 +66,7 @@ "no-param-reassign": "off", "no-prototype-builtins": "error", "no-shadow": [ - "error", + "off", { "builtinGlobals": false } @@ -259,23 +269,41 @@ "error", "never" ], - "jsdoc/require-jsdoc": "off", + "jsdoc/require-jsdoc": [ + "error", + { + "require": { + "ClassDeclaration": false, + "FunctionDeclaration": true, + "MethodDefinition": false + }, + "contexts": [ + "MethodDefinition[kind=constructor]>FunctionExpression>BlockStatement>ExpressionStatement>AssignmentExpression[left.object.type=ThisExpression]", + "ClassDeclaration>Classbody>PropertyDefinition", + "MethodDefinition[kind!=constructor][kind!=set]", + "MethodDefinition[kind=constructor][value.params.length>0]" + ], + "checkGetters": "no-setter", + "checkSetters": "no-getter" + } + ], + "jsdoc/require-description": "off", "jsdoc/require-param": "error", - "jsdoc/require-param-description": "error", + "jsdoc/require-param-description": "off", "jsdoc/require-param-name": "error", "jsdoc/require-param-type": "error", "jsdoc/require-property": "error", - "jsdoc/require-property-description": "error", + "jsdoc/require-property-description": "off", "jsdoc/require-property-name": "error", "jsdoc/require-property-type": "error", "jsdoc/require-returns": "error", "jsdoc/require-returns-check": "error", - "jsdoc/require-returns-description": "error", + "jsdoc/require-returns-description": "off", "jsdoc/require-returns-type": "error", "jsdoc/require-throws": "error", "jsdoc/require-yields": "error", "jsdoc/require-yields-check": "error", - "jsdoc/tag-lines": "error", + "jsdoc/tag-lines": ["error", "never", {"startLines": 0}], "jsdoc/valid-types": "error", "jsonc/indent": [ "error", @@ -321,9 +349,162 @@ { "allowAllPropertiesOnSameLine": true } - ] + ], + "@typescript-eslint/ban-ts-comment": "off", + "@typescript-eslint/ban-types": [ + "error", + { + "types": { + "object": true + }, + "extendDefaults": true + } + ], + "@typescript-eslint/consistent-type-exports": "off", + "@typescript-eslint/no-explicit-any": "error", + "@typescript-eslint/no-shadow": [ + "error", + { + "builtinGlobals": false + } + ], + "@typescript-eslint/no-this-alias": "error", + "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/no-var-requires": "off" }, "overrides": [ + { + "files": [ + "*.ts" + ], + "rules": { + "no-undef": "off", + "unused-imports/no-unused-imports": "error", + "@typescript-eslint/no-unused-vars": [ + "error", + { + "vars": "local", + "args": "after-used", + "argsIgnorePattern": "^_", + "caughtErrors": "none" + } + ], + "comma-dangle": "off", + "@typescript-eslint/comma-dangle": [ + "error", + { + "arrays": "always-multiline", + "objects": "always-multiline", + "imports": "always-multiline", + "exports": "always-multiline", + "functions": "always-multiline", + "enums": "always-multiline", + "generics": "always-multiline", + "tuples": "always-multiline" + } + ], + "@stylistic/ts/block-spacing": "off", + "@stylistic/ts/brace-style": [ + "error", + "1tbs", + { + "allowSingleLine": true + } + ], + "@stylistic/ts/comma-dangle": [ + "error", + { + "arrays": "always-multiline", + "objects": "always-multiline", + "imports": "always-multiline", + "exports": "always-multiline", + "functions": "always-multiline", + "enums": "always-multiline", + "generics": "always-multiline", + "tuples": "always-multiline" + } + ], + "@stylistic/ts/comma-spacing": [ + "error", + { + "before": false, + "after": true + } + ], + "@stylistic/ts/function-call-spacing": [ + "error", + "never" + ], + "@stylistic/ts/indent": [ + "error", + 4 + ], + "@stylistic/ts/key-spacing": [ + "error", + { + "beforeColon": false, + "afterColon": true, + "mode": "strict" + } + ], + "@stylistic/ts/keyword-spacing": [ + "error", + { + "before": true, + "after": true + } + ], + "@stylistic/ts/lines-around-comment": "off", + "@stylistic/ts/lines-between-class-members": [ + "error", + "always" + ], + "@stylistic/ts/member-delimiter-style": [ + "error", + { + "multiline": { + "delimiter": "semi", + "requireLast": true + }, + "singleline": { + "delimiter": "comma", + "requireLast": false + }, + "multilineDetection": "brackets" + } + ], + "@stylistic/ts/no-extra-parens": [ + "error", + "all" + ], + "@stylistic/ts/no-extra-semi": "error", + "@stylistic/ts/object-curly-spacing": [ + "error", + "never" + ], + "@stylistic/ts/padding-line-between-statements": "off", + "@stylistic/ts/quotes": [ + "error", + "single", + "avoid-escape" + ], + "@stylistic/ts/semi": "error", + "@stylistic/ts/space-before-blocks": [ + "error", + "always" + ], + "@stylistic/ts/space-before-function-paren": [ + "error", + { + "anonymous": "never", + "named": "never", + "asyncArrow": "always" + } + ], + "@stylistic/ts/space-infix-ops": "error", + "@stylistic/ts/type-annotation-spacing": "error" + } + }, { "files": [ "*.json" @@ -373,12 +554,67 @@ { "files": [ "ext/js/core.js", + "ext/js/core/extension-error.js", "ext/js/**/sandbox/**/*.js" ], "env": { "webextensions": false } }, + { + "files": [ + "ext/**/*.js" + ], + "excludedFiles": [ + "ext/js/core/extension-error.js" + ], + "globals": { + "ExtensionError": "readonly" + } + }, + { + "files": [ + "ext/**/*.js" + ], + "excludedFiles": [ + "ext/js/core.js", + "ext/js/core/extension-error.js", + "ext/js/accessibility/google-docs.js", + "ext/js/**/sandbox/**/*.js" + ], + "globals": { + "isObject": "readonly", + "stringReverse": "readonly", + "promiseTimeout": "readonly", + "escapeRegExp": "readonly", + "deferPromise": "readonly", + "clone": "readonly", + "deepEqual": "readonly", + "generateId": "readonly", + "promiseAnimationFrame": "readonly", + "invokeMessageHandler": "readonly", + "log": "readonly", + "DynamicProperty": "readonly", + "EventDispatcher": "readonly", + "EventListenerCollection": "readonly", + "Logger": "readonly" + } + }, + { + "files": [ + "ext/**/*.js" + ], + "excludedFiles": [ + "ext/js/core.js", + "ext/js/core/extension-error.js", + "ext/js/accessibility/google-docs.js", + "ext/js/yomitan.js", + "ext/js/**/sandbox/**/*.js" + ], + "globals": { + "yomitan": "readonly" + } + }, { "files": [ "ext/js/yomitan.js" @@ -417,6 +653,7 @@ { "files": [ "ext/js/core.js", + "ext/js/core/extension-error.js", "ext/js/yomitan.js", "ext/js/accessibility/accessibility-controller.js", "ext/js/background/backend.js", @@ -466,6 +703,7 @@ { "files": [ "ext/js/core.js", + "ext/js/core/extension-error.js", "ext/js/data/database.js", "ext/js/data/json-schema.js", "ext/js/general/cache-map.js", -- cgit v1.2.3 From 19f359af78c052c7d3083fc353d37c606444f179 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Mon, 27 Nov 2023 13:54:09 -0500 Subject: Config updates --- .eslintrc.json | 14 +- dev/jsconfig.json | 1 + package-lock.json | 761 +----------------------------------------------------- package.json | 2 +- 4 files changed, 21 insertions(+), 757 deletions(-) (limited to '.eslintrc.json') diff --git a/.eslintrc.json b/.eslintrc.json index 3200d292..640a67e2 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -61,7 +61,7 @@ "no-case-declarations": "error", "no-const-assign": "error", "no-constant-condition": "off", - "no-console": "warn", + "no-console": "off", "no-global-assign": "error", "no-param-reassign": "off", "no-prototype-builtins": "error", @@ -263,7 +263,7 @@ "jsdoc/multiline-blocks": "error", "jsdoc/no-bad-blocks": "error", "jsdoc/no-multi-asterisks": "error", - "jsdoc/no-undefined-types": 1, + "jsdoc/no-undefined-types": "error", "jsdoc/require-asterisk-prefix": "error", "jsdoc/require-hyphen-before-param-description": [ "error", @@ -762,6 +762,16 @@ "vitest/prefer-to-be": "off" }, "env": {} + }, + { + "files": [ + "dev/**/*.js", + "test/**/*.js" + ], + "rules": { + "jsdoc/require-jsdoc": "off", + "jsdoc/no-undefined-types": "off" + } } ] } diff --git a/dev/jsconfig.json b/dev/jsconfig.json index 58eba952..a012f32f 100644 --- a/dev/jsconfig.json +++ b/dev/jsconfig.json @@ -52,6 +52,7 @@ "include": [ "**/*.js", "../playwright.config.js", + "../vitest.config.js", "../ext/js/core.js", "../ext/js/core/extension-error.js", "../ext/js/data/database.js", diff --git a/package-lock.json b/package-lock.json index 1261bec9..3fb951f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,7 +50,7 @@ "license-report": "^6.5.0", "stylelint": "^15.11.0", "stylelint-config-recommended": "^13.0.0", - "typescript": "^5.2.2", + "typescript": "5.2.2", "vitest": "^0.34.6" } }, @@ -360,342 +360,6 @@ "node": ">=16" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.8.tgz", - "integrity": "sha512-31E2lxlGM1KEfivQl8Yf5aYU/mflz9g06H6S15ITUFQueMFtFjESRMoDSkvMo8thYvLBax+VKTPlpnx+sPicOA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.8.tgz", - "integrity": "sha512-B8JbS61bEunhfx8kasogFENgQfr/dIp+ggYXwTqdbMAgGDhRa3AaPpQMuQU0rNxDLECj6FhDzk1cF9WHMVwrtA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.8.tgz", - "integrity": "sha512-rdqqYfRIn4jWOp+lzQttYMa2Xar3OK9Yt2fhOhzFXqg0rVWEfSclJvZq5fZslnz6ypHvVf3CT7qyf0A5pM682A==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.8.tgz", - "integrity": "sha512-RQw9DemMbIq35Bprbboyf8SmOr4UXsRVxJ97LgB55VKKeJOOdvsIPy0nFyF2l8U+h4PtBx/1kRf0BelOYCiQcw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.8.tgz", - "integrity": "sha512-3sur80OT9YdeZwIVgERAysAbwncom7b4bCI2XKLjMfPymTud7e/oY4y+ci1XVp5TfQp/bppn7xLw1n/oSQY3/Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.8.tgz", - "integrity": "sha512-WAnPJSDattvS/XtPCTj1tPoTxERjcTpH6HsMr6ujTT+X6rylVe8ggxk8pVxzf5U1wh5sPODpawNicF5ta/9Tmw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.8.tgz", - "integrity": "sha512-ICvZyOplIjmmhjd6mxi+zxSdpPTKFfyPPQMQTK/w+8eNK6WV01AjIztJALDtwNNfFhfZLux0tZLC+U9nSyA5Zg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.8.tgz", - "integrity": "sha512-H4vmI5PYqSvosPaTJuEppU9oz1dq2A7Mr2vyg5TF9Ga+3+MGgBdGzcyBP7qK9MrwFQZlvNyJrvz6GuCaj3OukQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.8.tgz", - "integrity": "sha512-z1zMZivxDLHWnyGOctT9JP70h0beY54xDDDJt4VpTX+iwA77IFsE1vCXWmprajJGa+ZYSqkSbRQ4eyLCpCmiCQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.8.tgz", - "integrity": "sha512-1a8suQiFJmZz1khm/rDglOc8lavtzEMRo0v6WhPgxkrjcU0LkHj+TwBrALwoz/OtMExvsqbbMI0ChyelKabSvQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.8.tgz", - "integrity": "sha512-fHZWS2JJxnXt1uYJsDv9+b60WCc2RlvVAy1F76qOLtXRO+H4mjt3Tr6MJ5l7Q78X8KgCFudnTuiQRBhULUyBKQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.8.tgz", - "integrity": "sha512-Wy/z0EL5qZYLX66dVnEg9riiwls5IYnziwuju2oUiuxVc+/edvqXa04qNtbrs0Ukatg5HEzqT94Zs7J207dN5Q==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.8.tgz", - "integrity": "sha512-ETaW6245wK23YIEufhMQ3HSeHO7NgsLx8gygBVldRHKhOlD1oNeNy/P67mIh1zPn2Hr2HLieQrt6tWrVwuqrxg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.8.tgz", - "integrity": "sha512-T2DRQk55SgoleTP+DtPlMrxi/5r9AeFgkhkZ/B0ap99zmxtxdOixOMI570VjdRCs9pE4Wdkz7JYrsPvsl7eESg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.8.tgz", - "integrity": "sha512-NPxbdmmo3Bk7mbNeHmcCd7R7fptJaczPYBaELk6NcXxy7HLNyWwCyDJ/Xx+/YcNH7Im5dHdx9gZ5xIwyliQCbg==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.8.tgz", - "integrity": "sha512-lytMAVOM3b1gPypL2TRmZ5rnXl7+6IIk8uB3eLsV1JwcizuolblXRrc5ShPrO9ls/b+RTp+E6gbsuLWHWi2zGg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.8.tgz", - "integrity": "sha512-hvWVo2VsXz/8NVt1UhLzxwAfo5sioj92uo0bCfLibB0xlOmimU/DeAEsQILlBQvkhrGjamP0/el5HU76HAitGw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.8.tgz", - "integrity": "sha512-/7Y7u77rdvmGTxR83PgaSvSBJCC2L3Kb1M/+dmSIvRvQPXXCuC97QAwMugBNG0yGcbEGfFBH7ojPzAOxfGNkwQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.8.tgz", - "integrity": "sha512-9Lc4s7Oi98GqFA4HzA/W2JHIYfnXbUYgekUP/Sm4BG9sfLjyv6GKKHKKVs83SMicBF2JwAX6A1PuOLMqpD001w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.8.tgz", - "integrity": "sha512-rq6WzBGjSzihI9deW3fC2Gqiak68+b7qo5/3kmB6Gvbh/NYPA0sJhrnp7wgV4bNwjqM+R2AApXGxMO7ZoGhIJg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.8.tgz", - "integrity": "sha512-AIAbverbg5jMvJznYiGhrd3sumfwWs8572mIJL5NQjJa06P8KfCPWZQ0NwZbPQnbQi9OWSZhFVSUWjjIrn4hSw==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@esbuild/win32-x64": { "version": "0.19.8", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.8.tgz", @@ -1014,149 +678,6 @@ "node": ">=16" } }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.6.0.tgz", - "integrity": "sha512-keHkkWAe7OtdALGoutLY3utvthkGF+Y17ws9LYT8pxMBYXaCoH/8dXS2uzo6e8+sEhY7y/zi5RFo22Dy2lFpDw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.6.0.tgz", - "integrity": "sha512-y3Kt+34smKQNWilicPbBz/MXEY7QwDzMFNgwEWeYiOhUt9MTWKjHqe3EVkXwT2fR7izOvHpDWZ0o2IyD9SWX7A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.6.0.tgz", - "integrity": "sha512-oLzzxcUIHltHxOCmaXl+pkIlU+uhSxef5HfntW7RsLh1eHm+vJzjD9Oo4oUKso4YuP4PpbFJNlZjJuOrxo8dPg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.6.0.tgz", - "integrity": "sha512-+ANnmjkcOBaV25n0+M0Bere3roeVAnwlKW65qagtuAfIxXF9YxUneRyAn/RDcIdRa7QrjRNJL3jR7T43ObGe8Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.6.0.tgz", - "integrity": "sha512-tBTSIkjSVUyrekddpkAqKOosnj1Fc0ZY0rJL2bIEWPKqlEQk0paORL9pUIlt7lcGJi3LzMIlUGXvtNi1Z6MOCQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.6.0.tgz", - "integrity": "sha512-Ed8uJI3kM11de9S0j67wAV07JUNhbAqIrDYhQBrQW42jGopgheyk/cdcshgGO4fW5Wjq97COCY/BHogdGvKVNQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.6.0.tgz", - "integrity": "sha512-mZoNQ/qK4D7SSY8v6kEsAAyDgznzLLuSFCA3aBHZTmf3HP/dW4tNLTtWh9+LfyO0Z1aUn+ecpT7IQ3WtIg3ViQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.6.0.tgz", - "integrity": "sha512-rouezFHpwCqdEXsqAfNsTgSWO0FoZ5hKv5p+TGO5KFhyN/dvYXNMqMolOb8BkyKcPqjYRBeT+Z6V3aM26rPaYg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.6.0.tgz", - "integrity": "sha512-Bbm+fyn3S6u51urfj3YnqBXg5vI2jQPncRRELaucmhBVyZkbWClQ1fEsRmdnCPpQOQfkpg9gZArvtMVkOMsh1w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.6.0.tgz", - "integrity": "sha512-+MRMcyx9L2kTrTUzYmR61+XVsliMG4odFb5UmqtiT8xOfEicfYAGEuF/D1Pww1+uZkYhBqAHpvju7VN+GnC3ng==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.6.0.tgz", - "integrity": "sha512-rxfeE6K6s/Xl2HGeK6cO8SiQq3k/3BYpw7cfhW5Bk2euXNEpuzi2cc7llxx1si1QgwfjNtdRNTGqdBzGlFZGFw==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@rollup/rollup-win32-x64-msvc": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.6.0.tgz", @@ -3048,20 +2569,6 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -5762,9 +5269,9 @@ } }, "node_modules/typescript": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz", - "integrity": "sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -5949,20 +5456,6 @@ "url": "https://opencollective.com/vitest" } }, - "node_modules/vite/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, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/vitest": { "version": "0.34.6", "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.6.tgz", @@ -6520,153 +6013,6 @@ "jsdoc-type-pratt-parser": "~4.0.0" } }, - "@esbuild/android-arm": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.8.tgz", - "integrity": "sha512-31E2lxlGM1KEfivQl8Yf5aYU/mflz9g06H6S15ITUFQueMFtFjESRMoDSkvMo8thYvLBax+VKTPlpnx+sPicOA==", - "dev": true, - "optional": true - }, - "@esbuild/android-arm64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.8.tgz", - "integrity": "sha512-B8JbS61bEunhfx8kasogFENgQfr/dIp+ggYXwTqdbMAgGDhRa3AaPpQMuQU0rNxDLECj6FhDzk1cF9WHMVwrtA==", - "dev": true, - "optional": true - }, - "@esbuild/android-x64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.8.tgz", - "integrity": "sha512-rdqqYfRIn4jWOp+lzQttYMa2Xar3OK9Yt2fhOhzFXqg0rVWEfSclJvZq5fZslnz6ypHvVf3CT7qyf0A5pM682A==", - "dev": true, - "optional": true - }, - "@esbuild/darwin-arm64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.8.tgz", - "integrity": "sha512-RQw9DemMbIq35Bprbboyf8SmOr4UXsRVxJ97LgB55VKKeJOOdvsIPy0nFyF2l8U+h4PtBx/1kRf0BelOYCiQcw==", - "dev": true, - "optional": true - }, - "@esbuild/darwin-x64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.8.tgz", - "integrity": "sha512-3sur80OT9YdeZwIVgERAysAbwncom7b4bCI2XKLjMfPymTud7e/oY4y+ci1XVp5TfQp/bppn7xLw1n/oSQY3/Q==", - "dev": true, - "optional": true - }, - "@esbuild/freebsd-arm64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.8.tgz", - "integrity": "sha512-WAnPJSDattvS/XtPCTj1tPoTxERjcTpH6HsMr6ujTT+X6rylVe8ggxk8pVxzf5U1wh5sPODpawNicF5ta/9Tmw==", - "dev": true, - "optional": true - }, - "@esbuild/freebsd-x64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.8.tgz", - "integrity": "sha512-ICvZyOplIjmmhjd6mxi+zxSdpPTKFfyPPQMQTK/w+8eNK6WV01AjIztJALDtwNNfFhfZLux0tZLC+U9nSyA5Zg==", - "dev": true, - "optional": true - }, - "@esbuild/linux-arm": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.8.tgz", - "integrity": "sha512-H4vmI5PYqSvosPaTJuEppU9oz1dq2A7Mr2vyg5TF9Ga+3+MGgBdGzcyBP7qK9MrwFQZlvNyJrvz6GuCaj3OukQ==", - "dev": true, - "optional": true - }, - "@esbuild/linux-arm64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.8.tgz", - "integrity": "sha512-z1zMZivxDLHWnyGOctT9JP70h0beY54xDDDJt4VpTX+iwA77IFsE1vCXWmprajJGa+ZYSqkSbRQ4eyLCpCmiCQ==", - "dev": true, - "optional": true - }, - "@esbuild/linux-ia32": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.8.tgz", - "integrity": "sha512-1a8suQiFJmZz1khm/rDglOc8lavtzEMRo0v6WhPgxkrjcU0LkHj+TwBrALwoz/OtMExvsqbbMI0ChyelKabSvQ==", - "dev": true, - "optional": true - }, - "@esbuild/linux-loong64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.8.tgz", - "integrity": "sha512-fHZWS2JJxnXt1uYJsDv9+b60WCc2RlvVAy1F76qOLtXRO+H4mjt3Tr6MJ5l7Q78X8KgCFudnTuiQRBhULUyBKQ==", - "dev": true, - "optional": true - }, - "@esbuild/linux-mips64el": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.8.tgz", - "integrity": "sha512-Wy/z0EL5qZYLX66dVnEg9riiwls5IYnziwuju2oUiuxVc+/edvqXa04qNtbrs0Ukatg5HEzqT94Zs7J207dN5Q==", - "dev": true, - "optional": true - }, - "@esbuild/linux-ppc64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.8.tgz", - "integrity": "sha512-ETaW6245wK23YIEufhMQ3HSeHO7NgsLx8gygBVldRHKhOlD1oNeNy/P67mIh1zPn2Hr2HLieQrt6tWrVwuqrxg==", - "dev": true, - "optional": true - }, - "@esbuild/linux-riscv64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.8.tgz", - "integrity": "sha512-T2DRQk55SgoleTP+DtPlMrxi/5r9AeFgkhkZ/B0ap99zmxtxdOixOMI570VjdRCs9pE4Wdkz7JYrsPvsl7eESg==", - "dev": true, - "optional": true - }, - "@esbuild/linux-s390x": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.8.tgz", - "integrity": "sha512-NPxbdmmo3Bk7mbNeHmcCd7R7fptJaczPYBaELk6NcXxy7HLNyWwCyDJ/Xx+/YcNH7Im5dHdx9gZ5xIwyliQCbg==", - "dev": true, - "optional": true - }, - "@esbuild/linux-x64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.8.tgz", - "integrity": "sha512-lytMAVOM3b1gPypL2TRmZ5rnXl7+6IIk8uB3eLsV1JwcizuolblXRrc5ShPrO9ls/b+RTp+E6gbsuLWHWi2zGg==", - "dev": true, - "optional": true - }, - "@esbuild/netbsd-x64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.8.tgz", - "integrity": "sha512-hvWVo2VsXz/8NVt1UhLzxwAfo5sioj92uo0bCfLibB0xlOmimU/DeAEsQILlBQvkhrGjamP0/el5HU76HAitGw==", - "dev": true, - "optional": true - }, - "@esbuild/openbsd-x64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.8.tgz", - "integrity": "sha512-/7Y7u77rdvmGTxR83PgaSvSBJCC2L3Kb1M/+dmSIvRvQPXXCuC97QAwMugBNG0yGcbEGfFBH7ojPzAOxfGNkwQ==", - "dev": true, - "optional": true - }, - "@esbuild/sunos-x64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.8.tgz", - "integrity": "sha512-9Lc4s7Oi98GqFA4HzA/W2JHIYfnXbUYgekUP/Sm4BG9sfLjyv6GKKHKKVs83SMicBF2JwAX6A1PuOLMqpD001w==", - "dev": true, - "optional": true - }, - "@esbuild/win32-arm64": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.8.tgz", - "integrity": "sha512-rq6WzBGjSzihI9deW3fC2Gqiak68+b7qo5/3kmB6Gvbh/NYPA0sJhrnp7wgV4bNwjqM+R2AApXGxMO7ZoGhIJg==", - "dev": true, - "optional": true - }, - "@esbuild/win32-ia32": { - "version": "0.19.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.8.tgz", - "integrity": "sha512-AIAbverbg5jMvJznYiGhrd3sumfwWs8572mIJL5NQjJa06P8KfCPWZQ0NwZbPQnbQi9OWSZhFVSUWjjIrn4hSw==", - "dev": true, - "optional": true - }, "@esbuild/win32-x64": { "version": "0.19.8", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.8.tgz", @@ -6897,83 +6243,6 @@ "playwright": "1.40.0" } }, - "@rollup/rollup-android-arm-eabi": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.6.0.tgz", - "integrity": "sha512-keHkkWAe7OtdALGoutLY3utvthkGF+Y17ws9LYT8pxMBYXaCoH/8dXS2uzo6e8+sEhY7y/zi5RFo22Dy2lFpDw==", - "dev": true, - "optional": true - }, - "@rollup/rollup-android-arm64": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.6.0.tgz", - "integrity": "sha512-y3Kt+34smKQNWilicPbBz/MXEY7QwDzMFNgwEWeYiOhUt9MTWKjHqe3EVkXwT2fR7izOvHpDWZ0o2IyD9SWX7A==", - "dev": true, - "optional": true - }, - "@rollup/rollup-darwin-arm64": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.6.0.tgz", - "integrity": "sha512-oLzzxcUIHltHxOCmaXl+pkIlU+uhSxef5HfntW7RsLh1eHm+vJzjD9Oo4oUKso4YuP4PpbFJNlZjJuOrxo8dPg==", - "dev": true, - "optional": true - }, - "@rollup/rollup-darwin-x64": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.6.0.tgz", - "integrity": "sha512-+ANnmjkcOBaV25n0+M0Bere3roeVAnwlKW65qagtuAfIxXF9YxUneRyAn/RDcIdRa7QrjRNJL3jR7T43ObGe8Q==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.6.0.tgz", - "integrity": "sha512-tBTSIkjSVUyrekddpkAqKOosnj1Fc0ZY0rJL2bIEWPKqlEQk0paORL9pUIlt7lcGJi3LzMIlUGXvtNi1Z6MOCQ==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm64-gnu": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.6.0.tgz", - "integrity": "sha512-Ed8uJI3kM11de9S0j67wAV07JUNhbAqIrDYhQBrQW42jGopgheyk/cdcshgGO4fW5Wjq97COCY/BHogdGvKVNQ==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm64-musl": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.6.0.tgz", - "integrity": "sha512-mZoNQ/qK4D7SSY8v6kEsAAyDgznzLLuSFCA3aBHZTmf3HP/dW4tNLTtWh9+LfyO0Z1aUn+ecpT7IQ3WtIg3ViQ==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-x64-gnu": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.6.0.tgz", - "integrity": "sha512-rouezFHpwCqdEXsqAfNsTgSWO0FoZ5hKv5p+TGO5KFhyN/dvYXNMqMolOb8BkyKcPqjYRBeT+Z6V3aM26rPaYg==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-x64-musl": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.6.0.tgz", - "integrity": "sha512-Bbm+fyn3S6u51urfj3YnqBXg5vI2jQPncRRELaucmhBVyZkbWClQ1fEsRmdnCPpQOQfkpg9gZArvtMVkOMsh1w==", - "dev": true, - "optional": true - }, - "@rollup/rollup-win32-arm64-msvc": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.6.0.tgz", - "integrity": "sha512-+MRMcyx9L2kTrTUzYmR61+XVsliMG4odFb5UmqtiT8xOfEicfYAGEuF/D1Pww1+uZkYhBqAHpvju7VN+GnC3ng==", - "dev": true, - "optional": true - }, - "@rollup/rollup-win32-ia32-msvc": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.6.0.tgz", - "integrity": "sha512-rxfeE6K6s/Xl2HGeK6cO8SiQq3k/3BYpw7cfhW5Bk2euXNEpuzi2cc7llxx1si1QgwfjNtdRNTGqdBzGlFZGFw==", - "dev": true, - "optional": true - }, "@rollup/rollup-win32-x64-msvc": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.6.0.tgz", @@ -8334,13 +7603,6 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, "function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -10326,9 +9588,9 @@ "dev": true }, "typescript": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz", - "integrity": "sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true }, "ufo": { @@ -10426,15 +9688,6 @@ "fsevents": "~2.3.3", "postcss": "^8.4.31", "rollup": "^4.2.0" - }, - "dependencies": { - "fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "optional": true - } } }, "vite-node": { diff --git a/package.json b/package.json index c52c926b..bc2aebd7 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "license-report": "^6.5.0", "stylelint": "^15.11.0", "stylelint-config-recommended": "^13.0.0", - "typescript": "^5.2.2", + "typescript": "5.2.2", "vitest": "^0.34.6" }, "dependencies": { -- cgit v1.2.3 From e215656ce9b965360e540da93ebf5c381cbe4e41 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Wed, 29 Nov 2023 20:13:15 -0500 Subject: Update types --- .eslintrc.json | 1 - dev/bin/build.js | 64 ++++++++++--- dev/bin/dictionary-validate.js | 1 + dev/bin/schema-validate.js | 5 +- dev/build-libs.js | 11 ++- dev/dictionary-validate.js | 39 ++++++-- dev/generate-css-json.js | 61 +++++++++--- dev/jsconfig.json | 7 +- dev/lint/global-declarations.js | 157 ------------------------------- dev/lint/html-scripts.js | 202 ---------------------------------------- dev/manifest-util.js | 84 ++++++++++++++++- dev/schema-validate.js | 25 ++++- dev/util.js | 21 ++++- vitest.config.js | 1 + 14 files changed, 269 insertions(+), 410 deletions(-) delete mode 100644 dev/lint/global-declarations.js delete mode 100644 dev/lint/html-scripts.js (limited to '.eslintrc.json') diff --git a/.eslintrc.json b/.eslintrc.json index 640a67e2..58262714 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -765,7 +765,6 @@ }, { "files": [ - "dev/**/*.js", "test/**/*.js" ], "rules": { diff --git a/dev/bin/build.js b/dev/bin/build.js index 282f0414..c5814dd3 100644 --- a/dev/bin/build.js +++ b/dev/bin/build.js @@ -21,13 +21,22 @@ import childProcess from 'child_process'; import fs from 'fs'; import path from 'path'; import readline from 'readline'; -import {fileURLToPath} from 'url'; +import JSZip from 'jszip'; +import {fileURLToPath} from 'node:url'; import {buildLibs} from '../build-libs.js'; import {ManifestUtil} from '../manifest-util.js'; import {getAllFiles, getArgs, testMain} from '../util.js'; const dirname = path.dirname(fileURLToPath(import.meta.url)); +/** + * @param {string} directory + * @param {string[]} excludeFiles + * @param {string} outputFileName + * @param {string[]} sevenZipExes + * @param {?import('jszip').OnUpdateCallback} onUpdate + * @param {boolean} dryRun + */ async function createZip(directory, excludeFiles, outputFileName, sevenZipExes, onUpdate, dryRun) { try { fs.unlinkSync(outputFileName); @@ -57,11 +66,17 @@ async function createZip(directory, excludeFiles, outputFileName, sevenZipExes, } } } - return await createJSZip(directory, excludeFiles, outputFileName, onUpdate, dryRun); + await createJSZip(directory, excludeFiles, outputFileName, onUpdate, dryRun); } +/** + * @param {string} directory + * @param {string[]} excludeFiles + * @param {string} outputFileName + * @param {?import('jszip').OnUpdateCallback} onUpdate + * @param {boolean} dryRun + */ async function createJSZip(directory, excludeFiles, outputFileName, onUpdate, dryRun) { - const JSZip = null; const files = getAllFiles(directory); removeItemsFromArray(files, excludeFiles); const zip = new JSZip(); @@ -89,6 +104,10 @@ async function createJSZip(directory, excludeFiles, outputFileName, onUpdate, dr } } +/** + * @param {string[]} array + * @param {string[]} removeItems + */ function removeItemsFromArray(array, removeItems) { for (const item of removeItems) { const index = getIndexOfFilePath(array, item); @@ -98,6 +117,11 @@ function removeItemsFromArray(array, removeItems) { } } +/** + * @param {string[]} array + * @param {string} item + * @returns {number} + */ function getIndexOfFilePath(array, item) { const pattern = /\\/g; const separator = '/'; @@ -110,6 +134,16 @@ function getIndexOfFilePath(array, item) { return -1; } +/** + * @param {string} buildDir + * @param {string} extDir + * @param {ManifestUtil} manifestUtil + * @param {string[]} variantNames + * @param {string} manifestPath + * @param {boolean} dryRun + * @param {boolean} dryRunBuildZip + * @param {string} yomitanVersion + */ async function build(buildDir, extDir, manifestUtil, variantNames, manifestPath, dryRun, dryRunBuildZip, yomitanVersion) { const sevenZipExes = ['7za', '7z']; @@ -119,6 +153,7 @@ async function build(buildDir, extDir, manifestUtil, variantNames, manifestPath, } const dontLogOnUpdate = !process.stdout.isTTY; + /** @type {import('jszip').OnUpdateCallback} */ const onUpdate = (metadata) => { if (dontLogOnUpdate) { return; } @@ -127,7 +162,7 @@ async function build(buildDir, extDir, manifestUtil, variantNames, manifestPath, message += ` (${metadata.currentFile})`; } - readline.clearLine(process.stdout); + readline.clearLine(process.stdout, 0); readline.cursorTo(process.stdout, 0); process.stdout.write(message); }; @@ -173,6 +208,10 @@ async function build(buildDir, extDir, manifestUtil, variantNames, manifestPath, } } +/** + * @param {string} directory + * @param {string[]} files + */ function ensureFilesExist(directory, files) { for (const file of files) { assert.ok(fs.existsSync(path.join(directory, file))); @@ -180,8 +219,11 @@ function ensureFilesExist(directory, files) { } +/** + * @param {string[]} argv + */ export async function main(argv) { - const args = getArgs(argv, new Map([ + const args = getArgs(argv, new Map(/** @type {[key: string, value: (boolean|null|number|string|string[])][]} */ ([ ['all', false], ['default', false], ['manifest', null], @@ -189,11 +231,11 @@ export async function main(argv) { ['dry-run-build-zip', false], ['yomitan-version', '0.0.0.0'], [null, []] - ])); + ]))); - const dryRun = args.get('dry-run'); - const dryRunBuildZip = args.get('dry-run-build-zip'); - const yomitanVersion = args.get('yomitan-version'); + const dryRun = /** @type {boolean} */ (args.get('dry-run')); + const dryRunBuildZip = /** @type {boolean} */ (args.get('dry-run-build-zip')); + const yomitanVersion = /** @type {string} */ (args.get('yomitan-version')); const manifestUtil = new ManifestUtil(); @@ -204,11 +246,11 @@ export async function main(argv) { try { await buildLibs(); - const variantNames = ( + const variantNames = /** @type {string[]} */ (( argv.length === 0 || args.get('all') ? manifestUtil.getVariants().filter(({buildable}) => buildable !== false).map(({name}) => name) : args.get(null) - ); + )); await build(buildDir, extDir, manifestUtil, variantNames, manifestPath, dryRun, dryRunBuildZip, yomitanVersion); } finally { // Restore manifest diff --git a/dev/bin/dictionary-validate.js b/dev/bin/dictionary-validate.js index 78ad5198..0affb919 100644 --- a/dev/bin/dictionary-validate.js +++ b/dev/bin/dictionary-validate.js @@ -28,6 +28,7 @@ async function main() { return; } + /** @type {import('dev/schema-validate').ValidateMode} */ let mode = null; if (dictionaryFileNames[0] === '--ajv') { mode = 'ajv'; diff --git a/dev/bin/schema-validate.js b/dev/bin/schema-validate.js index 86cfebae..319c0d2c 100644 --- a/dev/bin/schema-validate.js +++ b/dev/bin/schema-validate.js @@ -17,8 +17,8 @@ */ import fs from 'fs'; -import performance from 'perf_hooks'; -import {createJsonSchema} from '../util.js'; +import {performance} from 'perf_hooks'; +import {createJsonSchema} from '../schema-validate.js'; function main() { const args = process.argv.slice(2); @@ -30,6 +30,7 @@ function main() { return; } + /** @type {import('dev/schema-validate').ValidateMode} */ let mode = null; if (args[0] === '--ajv') { mode = 'ajv'; diff --git a/dev/build-libs.js b/dev/build-libs.js index d33c1420..eee007f6 100644 --- a/dev/build-libs.js +++ b/dev/build-libs.js @@ -26,15 +26,18 @@ import {fileURLToPath} from 'url'; const dirname = path.dirname(fileURLToPath(import.meta.url)); const extDir = path.join(dirname, '..', 'ext'); -async function buildLib(p) { +/** + * @param {string} scriptPath + */ +async function buildLib(scriptPath) { await esbuild.build({ - entryPoints: [p], + entryPoints: [scriptPath], bundle: true, minify: false, sourcemap: true, target: 'es2020', format: 'esm', - outfile: path.join(extDir, 'lib', path.basename(p)), + outfile: path.join(extDir, 'lib', path.basename(scriptPath)), external: ['fs'], banner: { js: '// @ts-nocheck' @@ -55,7 +58,7 @@ export async function buildLibs() { const schemaDir = path.join(extDir, 'data/schemas/'); const schemaFileNames = fs.readdirSync(schemaDir); - const schemas = schemaFileNames.map((schemaFileName) => JSON.parse(fs.readFileSync(path.join(schemaDir, schemaFileName)))); + const schemas = schemaFileNames.map((schemaFileName) => JSON.parse(fs.readFileSync(path.join(schemaDir, schemaFileName), {encoding: 'utf8'}))); const ajv = new Ajv({schemas: schemas, code: {source: true, esm: true}}); const moduleCode = standaloneCode(ajv); diff --git a/dev/dictionary-validate.js b/dev/dictionary-validate.js index eb40beda..b3654e75 100644 --- a/dev/dictionary-validate.js +++ b/dev/dictionary-validate.js @@ -22,23 +22,34 @@ import path from 'path'; import {performance} from 'perf_hooks'; import {createJsonSchema} from './schema-validate.js'; +/** + * @param {string} relativeFileName + * @returns {import('dev/dictionary-validate').Schema} + */ function readSchema(relativeFileName) { const fileName = path.join(__dirname, relativeFileName); const source = fs.readFileSync(fileName, {encoding: 'utf8'}); return JSON.parse(source); } +/** + * @param {import('dev/schema-validate').ValidateMode} mode + * @param {import('jszip')} zip + * @param {string} fileNameFormat + * @param {import('dev/dictionary-validate').Schema} schema + */ async function validateDictionaryBanks(mode, zip, fileNameFormat, schema) { let jsonSchema; try { jsonSchema = createJsonSchema(mode, schema); } catch (e) { - e.message += `\n(in file ${fileNameFormat})}`; - throw e; + const e2 = e instanceof Error ? e : new Error(`${e}`); + e2.message += `\n(in file ${fileNameFormat})}`; + throw e2; } let index = 1; while (true) { - const fileName = fileNameFormat.replace(/\?/, index); + const fileName = fileNameFormat.replace(/\?/, `${index}`); const file = zip.files[fileName]; if (!file) { break; } @@ -47,14 +58,20 @@ async function validateDictionaryBanks(mode, zip, fileNameFormat, schema) { try { jsonSchema.validate(data); } catch (e) { - e.message += `\n(in file ${fileName})}`; - throw e; + const e2 = e instanceof Error ? e : new Error(`${e}`); + e2.message += `\n(in file ${fileName})}`; + throw e2; } ++index; } } +/** + * @param {import('dev/schema-validate').ValidateMode} mode + * @param {import('jszip')} archive + * @param {import('dev/dictionary-validate').Schemas} schemas + */ export async function validateDictionary(mode, archive, schemas) { const fileName = 'index.json'; const indexFile = archive.files[fileName]; @@ -69,8 +86,9 @@ export async function validateDictionary(mode, archive, schemas) { const jsonSchema = createJsonSchema(mode, schemas.index); jsonSchema.validate(index); } catch (e) { - e.message += `\n(in file ${fileName})}`; - throw e; + const e2 = e instanceof Error ? e : new Error(`${e}`); + e2.message += `\n(in file ${fileName})}`; + throw e2; } await validateDictionaryBanks(mode, archive, 'term_bank_?.json', version === 1 ? schemas.termBankV1 : schemas.termBankV3); @@ -80,6 +98,9 @@ export async function validateDictionary(mode, archive, schemas) { await validateDictionaryBanks(mode, archive, 'tag_bank_?.json', schemas.tagBankV3); } +/** + * @returns {import('dev/dictionary-validate').Schemas} + */ export function getSchemas() { return { index: readSchema('../ext/data/schemas/dictionary-index-schema.json'), @@ -93,6 +114,10 @@ export function getSchemas() { }; } +/** + * @param {import('dev/schema-validate').ValidateMode} mode + * @param {string[]} dictionaryFileNames + */ export async function testDictionaryFiles(mode, dictionaryFileNames) { const schemas = getSchemas(); diff --git a/dev/generate-css-json.js b/dev/generate-css-json.js index 914c1452..02e54530 100644 --- a/dev/generate-css-json.js +++ b/dev/generate-css-json.js @@ -16,9 +16,13 @@ * along with this program. If not, see . */ +import css from 'css'; import fs from 'fs'; import path from 'path'; +/** + * @returns {{cssFile: string, overridesCssFile: string, outputPath: string}[]} + */ export function getTargets() { return [ { @@ -34,8 +38,11 @@ export function getTargets() { ]; } -import css from 'css'; - +/** + * @param {import('css-style-applier').RawStyleData} rules + * @param {string[]} selectors + * @returns {number} + */ function indexOfRule(rules, selectors) { const jj = selectors.length; for (let i = 0, ii = rules.length; i < ii; ++i) { @@ -53,6 +60,12 @@ function indexOfRule(rules, selectors) { return -1; } +/** + * @param {import('css-style-applier').RawStyleDataStyleArray} styles + * @param {string} property + * @param {Map} removedProperties + * @returns {number} + */ function removeProperty(styles, property, removedProperties) { let removeCount = removedProperties.get(property); if (typeof removeCount !== 'undefined') { return removeCount; } @@ -69,6 +82,10 @@ function removeProperty(styles, property, removedProperties) { return removeCount; } +/** + * @param {import('css-style-applier').RawStyleData} rules + * @returns {string} + */ export function formatRulesJson(rules) { // Manually format JSON, for improved compactness // return JSON.stringify(rules, null, 4); @@ -102,27 +119,39 @@ export function formatRulesJson(rules) { return result; } +/** + * @param {string} cssFile + * @param {string} overridesCssFile + * @returns {import('css-style-applier').RawStyleData} + * @throws {Error} + */ export function generateRules(cssFile, overridesCssFile) { const content1 = fs.readFileSync(cssFile, {encoding: 'utf8'}); const content2 = fs.readFileSync(overridesCssFile, {encoding: 'utf8'}); - const stylesheet1 = css.parse(content1, {}).stylesheet; - const stylesheet2 = css.parse(content2, {}).stylesheet; + const stylesheet1 = /** @type {css.StyleRules} */ (css.parse(content1, {}).stylesheet); + const stylesheet2 = /** @type {css.StyleRules} */ (css.parse(content2, {}).stylesheet); const removePropertyPattern = /^remove-property\s+([\w\W]+)$/; const removeRulePattern = /^remove-rule$/; const propertySeparator = /\s+/; + /** @type {import('css-style-applier').RawStyleData} */ const rules = []; // Default stylesheet for (const rule of stylesheet1.rules) { if (rule.type !== 'rule') { continue; } - const {selectors, declarations} = rule; + const {selectors, declarations} = /** @type {css.Rule} */ (rule); + if (typeof selectors === 'undefined') { continue; } + /** @type {import('css-style-applier').RawStyleDataStyleArray} */ const styles = []; - for (const declaration of declarations) { - if (declaration.type !== 'declaration') { console.log(declaration); continue; } - const {property, value} = declaration; - styles.push([property, value]); + if (typeof declarations !== 'undefined') { + for (const declaration of declarations) { + if (declaration.type !== 'declaration') { console.log(declaration); continue; } + const {property, value} = /** @type {css.Declaration} */ (declaration); + if (typeof property !== 'string' || typeof value !== 'string') { continue; } + styles.push([property, value]); + } } if (styles.length > 0) { rules.push({selectors, styles}); @@ -132,7 +161,9 @@ export function generateRules(cssFile, overridesCssFile) { // Overrides for (const rule of stylesheet2.rules) { if (rule.type !== 'rule') { continue; } - const {selectors, declarations} = rule; + const {selectors, declarations} = /** @type {css.Rule} */ (rule); + if (typeof selectors === 'undefined' || typeof declarations === 'undefined') { continue; } + /** @type {Map} */ const removedProperties = new Map(); for (const declaration of declarations) { switch (declaration.type) { @@ -146,16 +177,18 @@ export function generateRules(cssFile, overridesCssFile) { entry = {selectors, styles: []}; rules.push(entry); } - const {property, value} = declaration; - removeProperty(entry.styles, property, removedProperties); - entry.styles.push([property, value]); + const {property, value} = /** @type {css.Declaration} */ (declaration); + if (typeof property === 'string' && typeof value === 'string') { + removeProperty(entry.styles, property, removedProperties); + entry.styles.push([property, value]); + } } break; case 'comment': { const index = indexOfRule(rules, selectors); if (index < 0) { throw new Error('Could not find rule with matching selectors'); } - const comment = declaration.comment.trim(); + const comment = (/** @type {css.Comment} */ (declaration).comment || '').trim(); let m; if ((m = removePropertyPattern.exec(comment)) !== null) { for (const property of m[1].split(propertySeparator)) { diff --git a/dev/jsconfig.json b/dev/jsconfig.json index 5b1c450c..e0074980 100644 --- a/dev/jsconfig.json +++ b/dev/jsconfig.json @@ -1,9 +1,9 @@ { "compilerOptions": { - "module": "ES2015", + "module": "ES2022", "target": "ES2022", "checkJs": true, - "moduleResolution": "node", + "moduleResolution": "bundler", "strict": true, "strictNullChecks": true, "noImplicitAny": true, @@ -73,6 +73,7 @@ "../types/other/globals.d.ts" ], "exclude": [ - "../node_modules" + "../node_modules", + "lib" ] } \ No newline at end of file diff --git a/dev/lint/global-declarations.js b/dev/lint/global-declarations.js deleted file mode 100644 index 648ad368..00000000 --- a/dev/lint/global-declarations.js +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2023 Yomitan Authors - * Copyright (C) 2020-2022 Yomichan Authors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -const fs = require('fs'); -const path = require('path'); -const assert = require('assert'); -const {getAllFiles} = require('../util'); - - -/** - * @param {string} string - * @returns {string} - */ -function escapeRegExp(string) { - return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); -} - -/** - * @param {string} string - * @param {RegExp} pattern - * @returns {number} - */ -function countOccurences(string, pattern) { - return (string.match(pattern) || []).length; -} - -/** - * @param {string} string - * @returns {'\r'|'\n'|'\r\n'} - */ -function getNewline(string) { - const count1 = countOccurences(string, /(?:^|[^\r])\n/g); - const count2 = countOccurences(string, /\r\n/g); - const count3 = countOccurences(string, /\r(?:[^\n]|$)/g); - if (count2 > count1) { - return (count3 > count2) ? '\r' : '\r\n'; - } else { - return (count3 > count1) ? '\r' : '\n'; - } -} - -/** - * @param {string} string - * @param {string} substring - * @returns {number} - */ -function getSubstringCount(string, substring) { - let count = 0; - const pattern = new RegExp(`\\b${escapeRegExp(substring)}\\b`, 'g'); - while (true) { - const match = pattern.exec(string); - if (match === null) { break; } - ++count; - } - return count; -} - - -/** - * @param {string} fileName - * @param {boolean} fix - * @returns {boolean} - */ -function validateGlobals(fileName, fix) { - const pattern = /\/\*\s*global\s+([\w\W]*?)\*\//g; - const trimPattern = /^[\s,*]+|[\s,*]+$/g; - const splitPattern = /[\s,*]+/; - const source = fs.readFileSync(fileName, {encoding: 'utf8'}); - let match; - let first = true; - let endIndex = 0; - let newSource = ''; - const allGlobals = []; - const newline = getNewline(source); - while ((match = pattern.exec(source)) !== null) { - if (!first) { - console.error(`Encountered more than one global declaration in ${fileName}`); - return false; - } - first = false; - - const parts = match[1].replace(trimPattern, '').split(splitPattern); - parts.sort(); - - const actual = match[0]; - const expected = `/* global${parts.map((v) => `${newline} * ${v}`).join('')}${newline} */`; - - try { - assert.strictEqual(actual, expected); - } catch (e) { - console.error(`Global declaration error encountered in ${fileName}:`); - console.error(e instanceof Error ? e.message : `${e}`); - if (!fix) { - return false; - } - } - - newSource += source.substring(0, match.index); - newSource += expected; - endIndex = match.index + match[0].length; - - allGlobals.push(...parts); - } - - newSource += source.substring(endIndex); - - // This is an approximate check to see if a global variable is unused. - // If the global appears in a comment, string, or similar, the check will pass. - let errorCount = 0; - for (const global of allGlobals) { - if (getSubstringCount(newSource, global) <= 1) { - console.error(`Global variable ${global} appears to be unused in ${fileName}`); - ++errorCount; - } - } - - if (fix) { - fs.writeFileSync(fileName, newSource, {encoding: 'utf8'}); - } - - return errorCount === 0; -} - - -/** */ -function main() { - const fix = (process.argv.length >= 2 && process.argv[2] === '--fix'); - const directory = path.resolve(__dirname, '..', '..', 'ext'); - const pattern = /\.js$/; - const ignorePattern = /^lib[\\/]/; - const fileNames = getAllFiles(directory, (f) => pattern.test(f) && !ignorePattern.test(f)); - for (const fileName of fileNames) { - if (!validateGlobals(path.join(directory, fileName), fix)) { - process.exit(-1); - return; - } - } - process.exit(0); -} - - -if (require.main === module) { main(); } diff --git a/dev/lint/html-scripts.js b/dev/lint/html-scripts.js deleted file mode 100644 index da8c2c71..00000000 --- a/dev/lint/html-scripts.js +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (C) 2023 Yomitan Authors - * Copyright (C) 2020-2022 Yomichan Authors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -const fs = require('fs'); -const path = require('path'); -const assert = require('assert'); -const {JSDOM} = require('jsdom'); -const {getAllFiles} = require('../util'); - - -/** - * @param {string} fileName - * @returns {?fs.Stats} - */ -function lstatSyncSafe(fileName) { - try { - return fs.lstatSync(fileName); - } catch (e) { - return null; - } -} - -/** - * @param {string} src - * @param {string} fileName - * @param {string} extDir - */ -function validatePath(src, fileName, extDir) { - assert.ok(typeof src === 'string', `