From 787b01749ca30037165c6a07eadf20a19dde97d9 Mon Sep 17 00:00:00 2001 From: yml2213 Date: Fri, 15 May 2026 17:35:50 +0800 Subject: [PATCH] feat(frontend): add P2 quality gates --- apps/frontend/.prettierignore | 4 + apps/frontend/.prettierrc.json | 6 + apps/frontend/eslint.config.js | 34 + apps/frontend/package-lock.json | 1286 ++++++++++++++++- apps/frontend/package.json | 12 +- .../src/components/admin/AdminStatusTag.vue | 78 +- .../components/tencent/TencentAuthCard.vue | 10 +- .../useTencentBrowserSessionPolling.ts | 4 +- .../useTencentBrowserSessionPresentation.ts | 6 +- .../composables/useAdminManualRedeemPage.ts | 83 +- apps/frontend/src/composables/useClaimPage.ts | 61 +- apps/frontend/src/lib/feedback.ts | 6 +- apps/frontend/src/lib/http.ts | 21 +- apps/frontend/src/router/index.ts | 3 +- .../frontend/src/services/admin/audit-logs.ts | 5 +- apps/frontend/src/services/admin/inventory.ts | 36 +- .../src/services/admin/manual-redeem.ts | 10 +- apps/frontend/src/services/admin/orders.ts | 5 +- .../src/services/admin/platform-config.ts | 151 +- apps/frontend/src/services/admin/tasks.ts | 47 +- apps/frontend/src/services/admin/users.ts | 27 +- .../src/services/admin/webhook-events.ts | 7 +- apps/frontend/src/services/tencent/session.ts | 4 +- apps/frontend/src/styles/admin-list-pages.css | 30 +- apps/frontend/src/types/tencent/session.ts | 6 +- apps/frontend/src/utils/admin-display.ts | 6 +- apps/frontend/src/utils/date-time.ts | 5 +- .../admin/audit-logs/AdminAuditLogsView.vue | 41 +- .../src/views/admin/auth/AdminLoginView.vue | 6 +- .../admin/dashboard/AdminDashboardView.vue | 9 +- .../AdminFulfillmentBindingsView.vue | 216 ++- .../AdminKuaishouCloudFulfillment.css | 6 +- .../AdminKuaishouCloudFulfillmentView.vue | 382 +++-- .../admin/inventory/AdminInventoryView.css | 208 ++- .../admin/inventory/AdminInventoryView.vue | 434 ++++-- .../src/views/admin/layout/AdminLayout.vue | 15 +- .../manual-redeem/AdminManualRedeemView.vue | 33 +- .../AdminMessageDeliveriesView.vue | 128 +- .../admin/orders/AdminOrderDetailView.vue | 52 +- .../views/admin/orders/AdminOrdersView.vue | 252 ++-- .../platform-shops/AdminPlatformShopsView.vue | 73 +- .../components/AdminPlatformAgisoSection.vue | 35 +- .../AdminPlatformCloudtentaclesSection.vue | 198 ++- .../AdminPlatformKuaishouEticketSection.vue | 219 ++- .../AdminPlatformNinetyoneSection.vue | 45 +- .../AdminPlatformNotificationSection.vue | 141 +- .../admin/platform-shops/composables/types.ts | 7 +- .../composables/useAdminAgisoPlatform.ts | 6 +- .../useAdminCloudtentaclesPlatform.ts | 151 +- .../useAdminKuaishouEticketPlatform.ts | 72 +- .../composables/useAdminNinetyonePlatform.ts | 22 +- .../useAdminNotificationPlatform.ts | 23 +- .../src/views/admin/tasks/AdminTaskDetail.css | 42 +- .../views/admin/tasks/AdminTaskDetailView.vue | 512 +++++-- .../src/views/admin/tasks/AdminTasksView.vue | 238 ++- .../src/views/admin/users/AdminUsersView.vue | 359 ++++- .../AdminWebhookEventDetailView.vue | 31 +- .../webhook-events/AdminWebhookEventsView.vue | 249 ++-- apps/frontend/src/views/claim/ClaimView.vue | 4 +- .../views/claim/KuaishouCloudClaimView.vue | 91 +- .../src/views/tx/TencentBrowserView.vue | 4 +- apps/frontend/tsconfig.json | 5 +- 62 files changed, 4907 insertions(+), 1355 deletions(-) create mode 100644 apps/frontend/.prettierignore create mode 100644 apps/frontend/.prettierrc.json create mode 100644 apps/frontend/eslint.config.js diff --git a/apps/frontend/.prettierignore b/apps/frontend/.prettierignore new file mode 100644 index 00000000..bdf2bb93 --- /dev/null +++ b/apps/frontend/.prettierignore @@ -0,0 +1,4 @@ +dist +node_modules +src/auto-imports.d.ts +src/components.d.ts diff --git a/apps/frontend/.prettierrc.json b/apps/frontend/.prettierrc.json new file mode 100644 index 00000000..3ee2d113 --- /dev/null +++ b/apps/frontend/.prettierrc.json @@ -0,0 +1,6 @@ +{ + "semi": false, + "singleQuote": true, + "printWidth": 100, + "trailingComma": "all" +} diff --git a/apps/frontend/eslint.config.js b/apps/frontend/eslint.config.js new file mode 100644 index 00000000..6c034421 --- /dev/null +++ b/apps/frontend/eslint.config.js @@ -0,0 +1,34 @@ +import js from '@eslint/js' +import prettier from 'eslint-config-prettier' +import pluginVue from 'eslint-plugin-vue' +import globals from 'globals' +import tseslint from 'typescript-eslint' + +export default tseslint.config( + { + ignores: ['dist/**', 'node_modules/**', 'src/auto-imports.d.ts', 'src/components.d.ts'], + }, + js.configs.recommended, + ...tseslint.configs.recommended, + ...pluginVue.configs['flat/recommended'], + prettier, + { + files: ['**/*.{ts,vue}'], + languageOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + globals: { + ...globals.browser, + }, + parserOptions: { + parser: tseslint.parser, + extraFileExtensions: ['.vue'], + }, + }, + rules: { + 'vue/attributes-order': 'off', + 'vue/multi-word-component-names': 'off', + 'vue/no-mutating-props': ['error', { shallowOnly: true }], + }, + }, +) diff --git a/apps/frontend/package-lock.json b/apps/frontend/package-lock.json index d198266c..24d4622e 100644 --- a/apps/frontend/package-lock.json +++ b/apps/frontend/package-lock.json @@ -16,11 +16,18 @@ "vue-router": "^4.5.1" }, "devDependencies": { + "@eslint/js": "^10.0.1", "@types/node": "^24.12.0", "@vitejs/plugin-vue": "^6.0.5", "@vue/tsconfig": "^0.9.0", + "eslint": "^10.3.0", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-vue": "^10.9.1", + "globals": "^17.6.0", + "prettier": "^3.8.3", "sass": "^1.99.0", "typescript": "~5.9.3", + "typescript-eslint": "^8.59.3", "unplugin-auto-import": "^21.0.0", "unplugin-vue-components": "^32.0.0", "vite": "^8.0.7", @@ -128,6 +135,134 @@ "tslib": "^2.4.0" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.23.5", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz", + "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^3.0.5", + "debug": "^4.3.1", + "minimatch": "^10.2.4" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.5.tgz", + "integrity": "sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/core": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", + "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/js": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", + "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "eslint": "^10.0.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/@eslint/object-schema": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz", + "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.1.tgz", + "integrity": "sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1", + "levn": "^0.4.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, "node_modules/@floating-ui/core": { "version": "1.7.5", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz", @@ -153,6 +288,72 @@ "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", "license": "MIT" }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -879,6 +1080,13 @@ "tslib": "^2.4.0" } }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -886,6 +1094,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/lodash": { "version": "4.17.24", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.24.tgz", @@ -925,6 +1140,236 @@ "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==", "license": "MIT" }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.3.tgz", + "integrity": "sha512-PwFvSKsXGShKGW6n5bZOhGHEcCZXM8HofLK9fNsEwZXzFRjoY+XT1Vsf1zgyXdwTr0ZYz1/2tkZ0DBTT9jZjhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.59.3", + "@typescript-eslint/type-utils": "8.59.3", + "@typescript-eslint/utils": "8.59.3", + "@typescript-eslint/visitor-keys": "8.59.3", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.59.3", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.3.tgz", + "integrity": "sha512-HPwA+hVkfcriajbNvTmZv4VRauibay+cWArYUYq7u7W7PmGShMxbPxLvrwDme55a6d5alG3nrYfhyJ/G28XlLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.59.3", + "@typescript-eslint/types": "8.59.3", + "@typescript-eslint/typescript-estree": "8.59.3", + "@typescript-eslint/visitor-keys": "8.59.3", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.3.tgz", + "integrity": "sha512-ECiUWa/KYRGDFUqTNehaRgzDshnJfkTABJxVemHk4ko22gcr0ukloKjWvyQ64g8YCV/UI47kN1dbmjf/GaQYng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.59.3", + "@typescript-eslint/types": "^8.59.3", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.3.tgz", + "integrity": "sha512-t2LvZnoEfzKtnPjgeEu41xw5gxq9mQVfYy4OoZ4Vlt0sk3JwxmhCca/AR7DwOiHrjWgjAj6as4AhRLKSDfvZIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.3", + "@typescript-eslint/visitor-keys": "8.59.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.3.tgz", + "integrity": "sha512-PcIJHjmaREXLgIAIzLnSY9VucEzz8FKXsRgFa1DmdGCK/5tJpW03TKJF01Q6VZd1lLdz2sIKPWaDUZN9dp//dw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.59.3.tgz", + "integrity": "sha512-g71d8QD8UaiHGvrJwyIS1hCX5r63w6Jll+4VEYhEAHXTDIqX1JgxhTAbEHtKntL9kuc4jRo7/GWw5xfCepSccQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.3", + "@typescript-eslint/typescript-estree": "8.59.3", + "@typescript-eslint/utils": "8.59.3", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.3.tgz", + "integrity": "sha512-ePFoH0g4ludssdRFqqDxQePCxU4WQyRa9+XVwjm7yLn0FKhMeoetC+qBEEI1Eyb1pGSDveTIT09Bvw2WhlGayg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.3.tgz", + "integrity": "sha512-CbRjVRAf7Lr9Kr8RopKcbY45p2VfmmHrm0ygOCYFi7oU8q19m0Fs/6iHS7kNOmwpp+ob07ZVcAqlxUod9lYdmg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.59.3", + "@typescript-eslint/tsconfig-utils": "8.59.3", + "@typescript-eslint/types": "8.59.3", + "@typescript-eslint/visitor-keys": "8.59.3", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.3.tgz", + "integrity": "sha512-JAvT14goBzRzzzZyqq3P9BLArIxTtQURUtFgQ/V7FO+eU+Gg6ES+5ymOPP1wRxXcxAYeivCk4uS3jCKWI1K8Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.59.3", + "@typescript-eslint/types": "8.59.3", + "@typescript-eslint/typescript-estree": "8.59.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.3.tgz", + "integrity": "sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.3", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@vitejs/plugin-vue": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.5.tgz", @@ -1161,6 +1606,33 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "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" + } + }, "node_modules/alien-signals": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-3.1.2.tgz", @@ -1215,6 +1687,36 @@ "proxy-from-env": "^2.1.0" } }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -1301,6 +1803,34 @@ "dev": true, "license": "MIT" }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/csstype": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", @@ -1313,6 +1843,24 @@ "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==", "license": "MIT" }, + "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/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", @@ -1322,6 +1870,13 @@ "node": ">=0.10.0" } }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1463,12 +2018,290 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.3.0.tgz", + "integrity": "sha512-XbEXaRva5cF0ZQB8w6MluHA0kZZfV2DuCMJ3ozyEOHLwDpZX2Lmm/7Pp0xdJmI0GL1W05VH5VwIFHEm1Vcw2gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.5", + "@eslint/config-helpers": "^0.5.5", + "@eslint/core": "^1.2.1", + "@eslint/plugin-kit": "^0.7.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "minimatch": "^10.2.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "10.1.8", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", + "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "funding": { + "url": "https://opencollective.com/eslint-config-prettier" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-vue": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.9.1.tgz", + "integrity": "sha512-cHB0Tf4Duvzwecwd/AqWzZvF/QszE13BhjVUpVXWCy9AeMR5GjkAjP3i85vqgLgOuTmkHR1OJ5oMeqLHtuw8zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "natural-compare": "^1.4.0", + "nth-check": "^2.1.1", + "postcss-selector-parser": "^7.1.0", + "semver": "^7.6.3", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "@stylistic/eslint-plugin": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0", + "@typescript-eslint/parser": "^7.0.0 || ^8.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "vue-eslint-parser": "^10.3.0" + }, + "peerDependenciesMeta": { + "@stylistic/eslint-plugin": { + "optional": true + }, + "@typescript-eslint/parser": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "license": "MIT" }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/exsolve": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz", @@ -1476,6 +2309,27 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", @@ -1494,6 +2348,19 @@ } } }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -1507,6 +2374,27 @@ "node": ">=8" } }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, "node_modules/follow-redirects": { "version": "1.15.11", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", @@ -1613,6 +2501,32 @@ "node": ">= 0.4" } }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "17.6.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.6.0.tgz", + "integrity": "sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -1664,6 +2578,16 @@ "node": ">= 0.4" } }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/immutable": { "version": "5.1.5", "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.5.tgz", @@ -1671,13 +2595,22 @@ "dev": true, "license": "MIT" }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "license": "MIT", - "optional": true, "engines": { "node": ">=0.10.0" } @@ -1697,7 +2630,6 @@ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "license": "MIT", - "optional": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -1705,6 +2637,13 @@ "node": ">=0.10.0" } }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, "node_modules/js-tokens": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", @@ -1712,6 +2651,51 @@ "dev": true, "license": "MIT" }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/lightningcss": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", @@ -2071,6 +3055,22 @@ "node": ">= 0.6" } }, + "node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/mlly": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz", @@ -2103,6 +3103,13 @@ "pathe": "^2.0.1" } }, + "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/muggle-string": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz", @@ -2128,6 +3135,13 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, "node_modules/node-addon-api": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", @@ -2142,6 +3156,19 @@ "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==", "license": "BSD-3-Clause" }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, "node_modules/obug": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", @@ -2153,6 +3180,24 @@ ], "license": "MIT" }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -2205,6 +3250,16 @@ "node": ">=8" } }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", @@ -2280,6 +3335,46 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", + "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/proxy-from-env": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", @@ -2289,6 +3384,16 @@ "node": ">=10" } }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/qrcode": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz", @@ -2451,12 +3556,48 @@ "dev": true, "license": "MIT" }, + "node_modules/semver": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "license": "ISC" }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -2522,6 +3663,19 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -2530,6 +3684,19 @@ "license": "0BSD", "optional": true }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", @@ -2544,6 +3711,30 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.59.3.tgz", + "integrity": "sha512-KgusgyDgG4LI8Ih/sWaCtZ06tckLAS5CvT5A4D1Q7bYVoAAyzwiZvE4BmwDHkhRVkvhRBepKeASoFzQetha7Fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.59.3", + "@typescript-eslint/parser": "8.59.3", + "@typescript-eslint/typescript-estree": "8.59.3", + "@typescript-eslint/utils": "8.59.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, "node_modules/ufo": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.3.tgz", @@ -2707,6 +3898,23 @@ "node": "^20.19.0 || >=22.12.0" } }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, "node_modules/vite": { "version": "8.0.7", "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.7.tgz", @@ -2819,6 +4027,31 @@ "integrity": "sha512-O02tnvIfOQVmnvoWwuSydwRoHjZVt8UEBR+2p4rT35p8GAy5VTlWP8o5qXfJR/GWCN0nVZoYWsVUvx2jwgdBmQ==", "license": "MIT" }, + "node_modules/vue-eslint-parser": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-10.4.0.tgz", + "integrity": "sha512-Vxi9pJdbN3ZnVGLODVtZ7y4Y2kzAAE2Cm0CZ3ZDRvydVYxZ6VrnBhLikBsRS+dpwj4Jv4UCv21PTEwF5rQ9WXg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "debug": "^4.4.0", + "eslint-scope": "^8.2.0 || ^9.0.0", + "eslint-visitor-keys": "^4.2.0 || ^5.0.0", + "espree": "^10.3.0 || ^11.0.0", + "esquery": "^1.6.0", + "semver": "^7.6.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0" + } + }, "node_modules/vue-router": { "version": "4.6.4", "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.6.4.tgz", @@ -2858,12 +4091,38 @@ "dev": true, "license": "MIT" }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/which-module": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", "license": "ISC" }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -2878,6 +4137,16 @@ "node": ">=8" } }, + "node_modules/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12" + } + }, "node_modules/y18n": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", @@ -2918,6 +4187,19 @@ "engines": { "node": ">=6" } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/apps/frontend/package.json b/apps/frontend/package.json index 81b2e182..ba58d4d3 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -7,7 +7,10 @@ "dev": "vite", "build": "vue-tsc -b && vite build", "preview": "vite preview", - "typecheck": "vue-tsc --noEmit -p tsconfig.app.json" + "typecheck": "vue-tsc --noEmit -p tsconfig.app.json", + "lint": "eslint .", + "format": "prettier --write .", + "format:check": "prettier --check ." }, "dependencies": { "@types/qrcode": "^1.5.6", @@ -18,11 +21,18 @@ "vue-router": "^4.5.1" }, "devDependencies": { + "@eslint/js": "^10.0.1", "@types/node": "^24.12.0", "@vitejs/plugin-vue": "^6.0.5", "@vue/tsconfig": "^0.9.0", + "eslint": "^10.3.0", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-vue": "^10.9.1", + "globals": "^17.6.0", + "prettier": "^3.8.3", "sass": "^1.99.0", "typescript": "~5.9.3", + "typescript-eslint": "^8.59.3", "unplugin-auto-import": "^21.0.0", "unplugin-vue-components": "^32.0.0", "vite": "^8.0.7", diff --git a/apps/frontend/src/components/admin/AdminStatusTag.vue b/apps/frontend/src/components/admin/AdminStatusTag.vue index 0b7abc63..f985d497 100644 --- a/apps/frontend/src/components/admin/AdminStatusTag.vue +++ b/apps/frontend/src/components/admin/AdminStatusTag.vue @@ -1,27 +1,79 @@ diff --git a/apps/frontend/src/components/tencent/TencentAuthCard.vue b/apps/frontend/src/components/tencent/TencentAuthCard.vue index ee707871..3d0d106b 100644 --- a/apps/frontend/src/components/tencent/TencentAuthCard.vue +++ b/apps/frontend/src/components/tencent/TencentAuthCard.vue @@ -72,7 +72,11 @@ const emit = defineEmits<{
已完成登录 @@ -93,7 +97,9 @@ const emit = defineEmits<{

- {{ props.hasSession ? props.scanInstruction : `已选择${props.loginTypeLabel},等待开始初始化` }} + {{ + props.hasSession ? props.scanInstruction : `已选择${props.loginTypeLabel},等待开始初始化` + }}

`开始初始化 ${loginTypeLabel.value} 登录`) - const scanInstruction = computed(() => `请使用${loginTypeLabel.value}扫描二维码,并在手机上确认登录`) + const scanInstruction = computed( + () => `请使用${loginTypeLabel.value}扫描二维码,并在手机上确认登录`, + ) const qrImage = computed(() => session.value?.qrImageBase64 ? `data:image/png;base64,${session.value.qrImageBase64}` : '', @@ -188,7 +190,7 @@ export function useTencentBrowserSessionPresentation(options: { const screenshotEmptyMessage = computed(() => session.value?.status === 'redeemed' ? '本次兑换可能未生成截图,或截图产物已被后端配置关闭。' - : '如本次兑换生成了结果截图,这里会展示。' + : '如本次兑换生成了结果截图,这里会展示。', ) return { diff --git a/apps/frontend/src/composables/useAdminManualRedeemPage.ts b/apps/frontend/src/composables/useAdminManualRedeemPage.ts index 2cf3848a..e2c96ee0 100644 --- a/apps/frontend/src/composables/useAdminManualRedeemPage.ts +++ b/apps/frontend/src/composables/useAdminManualRedeemPage.ts @@ -66,21 +66,31 @@ export function useAdminManualRedeemPage() { ) const hasSession = computed(() => Boolean(session.value?.sessionId)) const loginTypeLabel = computed(() => (loginType.value === 'wx' ? '微信' : 'QQ')) - const sessionNotice = computed(() => pollWarningMessage.value || session.value?.notice || task.value?.lastError || '') + const sessionNotice = computed( + () => pollWarningMessage.value || session.value?.notice || task.value?.lastError || '', + ) const qrImage = computed(() => session.value?.qrImageBase64 ? `data:image/png;base64,${session.value.qrImageBase64}` : '', ) const currentTaskId = computed(() => Number(task.value?.taskId || route.query.taskId || 0) || 0) - const reviewReady = computed(() => Boolean(session.value?.review?.capturedAt) && task.value?.status !== 'redeemed') - const resultReady = computed(() => Boolean(result.value?.screenshotReady) && task.value?.status === 'redeemed') + const reviewReady = computed( + () => Boolean(session.value?.review?.capturedAt) && task.value?.status !== 'redeemed', + ) + const resultReady = computed( + () => Boolean(result.value?.screenshotReady) && task.value?.status === 'redeemed', + ) const loginTabs = [ { value: 'qq' as const, label: 'QQ账号登录' }, { value: 'wx' as const, label: '微信账号登录' }, ] - const statusLabel = computed(() => resolveTaskStatusLabel(task.value?.status, session.value?.status)) + const statusLabel = computed(() => + resolveTaskStatusLabel(task.value?.status, session.value?.status), + ) const initButtonLabel = computed(() => `生成${loginTypeLabel.value}二维码`) - const scanInstruction = computed(() => `请让客户使用${loginTypeLabel.value}扫码,并在手机上确认登录`) + const scanInstruction = computed( + () => `请让客户使用${loginTypeLabel.value}扫码,并在手机上确认登录`, + ) const roleFacts = computed(() => [ { label: '登录昵称', @@ -120,18 +130,18 @@ export function useAdminManualRedeemPage() { ]) const canConfirmRole = computed(() => Boolean( - task.value - && task.value.status === 'claimed' - && hasSession.value - && roleReady.value - && !roleConfirmLoading.value, + task.value && + task.value.status === 'claimed' && + hasSession.value && + roleReady.value && + !roleConfirmLoading.value, ), ) const canRedeem = computed(() => Boolean( - task.value - && ['role_confirmed', 'redeeming'].includes(task.value.status) - && !redeemLoading.value, + task.value && + ['role_confirmed', 'redeeming'].includes(task.value.status) && + !redeemLoading.value, ), ) const redeemBlockedReason = computed(() => { @@ -158,13 +168,17 @@ export function useAdminManualRedeemPage() { return '' }) const redeemButtonLabel = computed(() => (redeemLoading.value ? '兑换中...' : '开始兑换')) - const screenshotEmptyTitle = computed(() => (task.value?.status === 'redeemed' ? '未获取到结果图' : '等待角色截图')) + const screenshotEmptyTitle = computed(() => + task.value?.status === 'redeemed' ? '未获取到结果图' : '等待角色截图', + ) const screenshotEmptyMessage = computed(() => task.value?.status === 'redeemed' ? '本次兑换可能未生成最终截图,或截图仍在同步中。' - : '客户登录并识别到角色后,这里会展示给客服复核的角色截图。' + : '客户登录并识别到角色后,这里会展示给客服复核的角色截图。', + ) + const canCreateTask = computed( + () => Boolean(form.proofValue.trim() && form.skuCode.trim()) && !createLoading.value, ) - const canCreateTask = computed(() => Boolean(form.proofValue.trim() && form.skuCode.trim()) && !createLoading.value) const hasActiveTask = computed(() => Boolean(task.value?.taskId)) watch(qrImage, () => { @@ -538,19 +552,20 @@ export function useAdminManualRedeemPage() { const anchor = document.createElement('a') anchor.href = screenshotUrl.value - anchor.download = task.value?.status === 'redeemed' - ? `manual-redeem-result-${task.value?.taskNo || 'task'}.png` - : `manual-redeem-review-${task.value?.taskNo || 'task'}.png` + anchor.download = + task.value?.status === 'redeemed' + ? `manual-redeem-result-${task.value?.taskNo || 'task'}.png` + : `manual-redeem-review-${task.value?.taskNo || 'task'}.png` anchor.click() return true } async function writeImageBlobToClipboard(blob: Blob, fallbackMessage: string) { if ( - typeof navigator === 'undefined' - || !navigator.clipboard - || typeof window === 'undefined' - || !('ClipboardItem' in window) + typeof navigator === 'undefined' || + !navigator.clipboard || + typeof window === 'undefined' || + !('ClipboardItem' in window) ) { throw new Error('当前浏览器不支持直接复制图片,请改用截图发送或下载') } @@ -569,7 +584,9 @@ export function useAdminManualRedeemPage() { async function loadScreenshotPreview(nextDetail = detail.value) { const taskId = Number(nextDetail?.task?.taskId || 0) - const shouldFetch = Boolean(taskId && (nextDetail?.session?.review?.capturedAt || nextDetail?.result?.screenshotReady)) + const shouldFetch = Boolean( + taskId && (nextDetail?.session?.review?.capturedAt || nextDetail?.result?.screenshotReady), + ) if (!shouldFetch) { clearScreenshotPreview() @@ -601,7 +618,9 @@ export function useAdminManualRedeemPage() { function resolveSkuName(skuCode: string) { const normalized = String(skuCode || '').trim() - const matched = suggestions.value.find((item) => String(item.skuCode || '').trim() === normalized) + const matched = suggestions.value.find( + (item) => String(item.skuCode || '').trim() === normalized, + ) return matched?.skuCode || normalized } @@ -682,7 +701,9 @@ export function useAdminManualRedeemPage() { maxWidth: '100%', })) - const qrPreviewWidth = computed(() => `${Math.min(Math.max(qrDisplayWidth.value + 120, 360), 480)}px`) + const qrPreviewWidth = computed( + () => `${Math.min(Math.max(qrDisplayWidth.value + 120, 360), 480)}px`, + ) return { form, @@ -744,7 +765,10 @@ export function useAdminManualRedeemPage() { } } -function syncLoginTypeFromDetail(detail: AdminManualRedeemDetail, fallback: TencentLoginType = DEFAULT_LOGIN_TYPE) { +function syncLoginTypeFromDetail( + detail: AdminManualRedeemDetail, + fallback: TencentLoginType = DEFAULT_LOGIN_TYPE, +) { const nextLoginType = String(detail.session?.loginType || detail.task.loginType || '').trim() if (nextLoginType === 'wx') { return 'wx' @@ -823,7 +847,10 @@ function mergeDetail(current: AdminManualRedeemDetail | null, next: AdminManualR } } -function shouldRefreshQrImage(currentSession: AdminManualRedeemDetail['session'], nextSession: AdminManualRedeemDetail['session']) { +function shouldRefreshQrImage( + currentSession: AdminManualRedeemDetail['session'], + nextSession: AdminManualRedeemDetail['session'], +) { if (!currentSession || !nextSession || !nextSession.artifacts?.hasQrImage) { return false } diff --git a/apps/frontend/src/composables/useClaimPage.ts b/apps/frontend/src/composables/useClaimPage.ts index 7082c320..ed2239c7 100644 --- a/apps/frontend/src/composables/useClaimPage.ts +++ b/apps/frontend/src/composables/useClaimPage.ts @@ -22,11 +22,7 @@ import { notifyTencentActionError } from './tencent/session-errors' const DEFAULT_LOGIN_TYPE: TencentLoginType = 'qq' const POLL_INTERVAL_MS = 2500 const POLL_FAILURE_LIMIT = 3 -const ACTIVE_TASK_STATUSES = new Set([ - 'claimed', - 'role_confirmed', - 'redeeming', -]) +const ACTIVE_TASK_STATUSES = new Set(['claimed', 'role_confirmed', 'redeeming']) export function useClaimPage(token: string) { const detailLoading = ref(true) @@ -53,7 +49,9 @@ export function useClaimPage(token: string) { const roleReady = computed(() => Boolean(activityInfo.value?.role?.ready)) const hasSession = computed(() => Boolean(session.value?.sessionId)) const loginTypeLabel = computed(() => (loginType.value === 'wx' ? '微信' : 'QQ')) - const sessionNotice = computed(() => pollWarningMessage.value || session.value?.notice || task.value?.lastError || '') + const sessionNotice = computed( + () => pollWarningMessage.value || session.value?.notice || task.value?.lastError || '', + ) const qrImage = computed(() => session.value?.qrImageBase64 ? `data:image/png;base64,${session.value.qrImageBase64}` : '', ) @@ -64,9 +62,13 @@ export function useClaimPage(token: string) { { value: 'wx' as const, label: '微信账号登录' }, ] - const statusLabel = computed(() => resolveTaskStatusLabel(task.value?.status, session.value?.status)) + const statusLabel = computed(() => + resolveTaskStatusLabel(task.value?.status, session.value?.status), + ) const initButtonLabel = computed(() => `开始初始化 ${loginTypeLabel.value} 登录`) - const scanInstruction = computed(() => `请使用${loginTypeLabel.value}扫描二维码,并在手机上确认登录`) + const scanInstruction = computed( + () => `请使用${loginTypeLabel.value}扫描二维码,并在手机上确认登录`, + ) const roleFacts = computed(() => [ { label: '登录昵称', @@ -106,21 +108,21 @@ export function useClaimPage(token: string) { ]) const canConfirmRole = computed(() => Boolean( - task.value - && !task.value.requiresSupportReview - && hasSession.value - && roleReady.value - && task.value.status === 'claimed', + task.value && + !task.value.requiresSupportReview && + hasSession.value && + roleReady.value && + task.value.status === 'claimed', ), ) const canRedeem = computed(() => Boolean( - task.value - && !task.value.requiresSupportReview - && hasSession.value - && roleConfirmed.value - && !redeemLoading.value - && (task.value.status === 'role_confirmed' || task.value.status === 'redeeming'), + task.value && + !task.value.requiresSupportReview && + hasSession.value && + roleConfirmed.value && + !redeemLoading.value && + (task.value.status === 'role_confirmed' || task.value.status === 'redeeming'), ), ) const redeemBlockedReason = computed(() => { @@ -158,14 +160,16 @@ export function useClaimPage(token: string) { return '' }) - const redeemButtonLabel = computed(() => (task.value?.requiresSupportReview ? '等待客服兑换' : '开始兑换')) + const redeemButtonLabel = computed(() => + task.value?.requiresSupportReview ? '等待客服兑换' : '开始兑换', + ) const screenshotEmptyTitle = computed(() => task.value?.status === 'redeemed' ? '本次没有可展示的截图' : '等待截图', ) const screenshotEmptyMessage = computed(() => task.value?.status === 'redeemed' ? '本次兑换可能未生成截图,或截图产物还未同步完成。' - : '领取完成后,如本次生成了结果截图,这里会展示。' + : '领取完成后,如本次生成了结果截图,这里会展示。', ) function applyLoginTypeFromDetail(nextDetail: ClaimDetailData) { @@ -183,7 +187,11 @@ export function useClaimPage(token: string) { activityInfo.value?.role?.partition || '', ].join('|'), () => { - roleConfirmed.value = Boolean(task.value?.status === 'role_confirmed' || task.value?.status === 'redeeming' || task.value?.status === 'redeemed') + roleConfirmed.value = Boolean( + task.value?.status === 'role_confirmed' || + task.value?.status === 'redeeming' || + task.value?.status === 'redeemed', + ) }, { immediate: true }, ) @@ -514,7 +522,9 @@ export function useClaimPage(token: string) { maxWidth: '100%', })) - const qrPreviewWidth = computed(() => `${Math.min(Math.max(qrDisplayWidth.value + 120, 360), 480)}px`) + const qrPreviewWidth = computed( + () => `${Math.min(Math.max(qrDisplayWidth.value + 120, 360), 480)}px`, + ) loadDetail() @@ -567,7 +577,10 @@ export function useClaimPage(token: string) { } } -function syncLoginTypeFromDetail(detail: ClaimDetailData, fallback: TencentLoginType = DEFAULT_LOGIN_TYPE) { +function syncLoginTypeFromDetail( + detail: ClaimDetailData, + fallback: TencentLoginType = DEFAULT_LOGIN_TYPE, +) { const nextLoginType = String(detail.session?.loginType || detail.task.loginType || '').trim() if (nextLoginType === 'wx') { return 'wx' diff --git a/apps/frontend/src/lib/feedback.ts b/apps/frontend/src/lib/feedback.ts index ab856002..b19cf838 100644 --- a/apps/frontend/src/lib/feedback.ts +++ b/apps/frontend/src/lib/feedback.ts @@ -44,7 +44,11 @@ export function showError(message: string, options: Partial = {} }) } -export function showConfirm(message: string, title = '确认操作', options: ElMessageBoxOptions = {}) { +export function showConfirm( + message: string, + title = '确认操作', + options: ElMessageBoxOptions = {}, +) { return ElMessageBox.confirm(message, title, { ...baseConfirmOptions, ...options, diff --git a/apps/frontend/src/lib/http.ts b/apps/frontend/src/lib/http.ts index ecac539d..ff572d83 100644 --- a/apps/frontend/src/lib/http.ts +++ b/apps/frontend/src/lib/http.ts @@ -42,7 +42,10 @@ http.interceptors.response.use( if (status === 401 && shouldClearAdminSession(errorCode)) { clearAdminSession() - if (window.location.hash.startsWith('#/admin') && !window.location.hash.startsWith('#/admin/login')) { + if ( + window.location.hash.startsWith('#/admin') && + !window.location.hash.startsWith('#/admin/login') + ) { window.location.hash = '#/admin/login' } } @@ -91,21 +94,27 @@ function shouldClearAdminSession(errorCode: string) { ].includes(errorCode) } +function request(config: Parameters>>[0]) { + return http.request, ApiEnvelope>(config) +} + export function apiGet(url: string, params?: Record) { - return http.get>(url, { params }) as unknown as Promise> + return request({ method: 'GET', url, params }) } export function apiGetBlob(url: string, params?: Record) { - return http.get(url, { + return http.request({ + method: 'GET', + url, params, responseType: 'blob', - }) as unknown as Promise + }) } export function apiPost(url: string, data?: Record) { - return http.post>(url, data) as unknown as Promise> + return request({ method: 'POST', url, data }) } export function apiDelete(url: string) { - return http.delete>(url) as unknown as Promise> + return request({ method: 'DELETE', url }) } diff --git a/apps/frontend/src/router/index.ts b/apps/frontend/src/router/index.ts index f51e7ea4..3d75e82f 100644 --- a/apps/frontend/src/router/index.ts +++ b/apps/frontend/src/router/index.ts @@ -76,7 +76,8 @@ const router = createRouter({ }, { path: 'message-deliveries', - component: () => import('@/views/admin/message-deliveries/AdminMessageDeliveriesView.vue'), + component: () => + import('@/views/admin/message-deliveries/AdminMessageDeliveriesView.vue'), }, { path: 'webhook-events', diff --git a/apps/frontend/src/services/admin/audit-logs.ts b/apps/frontend/src/services/admin/audit-logs.ts index 1c389b86..66030ebe 100644 --- a/apps/frontend/src/services/admin/audit-logs.ts +++ b/apps/frontend/src/services/admin/audit-logs.ts @@ -2,5 +2,8 @@ import { apiGet } from '@/lib/http' import type { AdminAuditLogItem, AdminPagination } from '@/types/admin' export function fetchAdminAuditLogs(params?: Record) { - return apiGet<{ items: AdminAuditLogItem[]; pagination: AdminPagination }>('/api/v1/admin/audit-logs', params) + return apiGet<{ items: AdminAuditLogItem[]; pagination: AdminPagination }>( + '/api/v1/admin/audit-logs', + params, + ) } diff --git a/apps/frontend/src/services/admin/inventory.ts b/apps/frontend/src/services/admin/inventory.ts index 272348a7..32c13c67 100644 --- a/apps/frontend/src/services/admin/inventory.ts +++ b/apps/frontend/src/services/admin/inventory.ts @@ -1,27 +1,49 @@ import { apiGet, apiPost } from '@/lib/http' -import type { AdminInventoryItemListItem, AdminInventorySkuSuggestion, AdminPagination } from '@/types/admin' +import type { + AdminInventoryItemListItem, + AdminInventorySkuSuggestion, + AdminPagination, +} from '@/types/admin' export function fetchAdminInventoryItems(params?: Record) { - return apiGet<{ items: AdminInventoryItemListItem[]; pagination: AdminPagination }>('/api/v1/admin/inventory', params) + return apiGet<{ items: AdminInventoryItemListItem[]; pagination: AdminPagination }>( + '/api/v1/admin/inventory', + params, + ) } export function fetchAdminInventorySkuSuggestions(params?: Record) { - return apiGet<{ items: AdminInventorySkuSuggestion[] }>('/api/v1/admin/inventory/sku-suggestions', params) + return apiGet<{ items: AdminInventorySkuSuggestion[] }>( + '/api/v1/admin/inventory/sku-suggestions', + params, + ) } export function importAdminInventoryItems(payload: Record) { - return apiPost<{ total: number; created: number; duplicated: number }>('/api/v1/admin/inventory/import', payload) + return apiPost<{ total: number; created: number; duplicated: number }>( + '/api/v1/admin/inventory/import', + payload, + ) } export function createAdminInventoryItem(payload: Record) { - return apiPost<{ inventoryItem: AdminInventoryItemListItem | null }>('/api/v1/admin/inventory', payload) + return apiPost<{ inventoryItem: AdminInventoryItemListItem | null }>( + '/api/v1/admin/inventory', + payload, + ) } export function releaseAdminInventoryItem(inventoryItemId: number | string) { - return apiPost<{ inventoryItem: AdminInventoryItemListItem | null }>(`/api/v1/admin/inventory/${inventoryItemId}/release`, {}) + return apiPost<{ inventoryItem: AdminInventoryItemListItem | null }>( + `/api/v1/admin/inventory/${inventoryItemId}/release`, + {}, + ) } -export function invalidateAdminInventoryItem(inventoryItemId: number | string, payload?: Record) { +export function invalidateAdminInventoryItem( + inventoryItemId: number | string, + payload?: Record, +) { return apiPost<{ inventoryItem: AdminInventoryItemListItem | null }>( `/api/v1/admin/inventory/${inventoryItemId}/invalidate`, payload || {}, diff --git a/apps/frontend/src/services/admin/manual-redeem.ts b/apps/frontend/src/services/admin/manual-redeem.ts index d99ea912..6941c52f 100644 --- a/apps/frontend/src/services/admin/manual-redeem.ts +++ b/apps/frontend/src/services/admin/manual-redeem.ts @@ -2,7 +2,10 @@ import { apiDelete, apiGet, apiPost } from '@/lib/http' import type { AdminInventorySkuSuggestion, AdminManualRedeemDetail } from '@/types/admin' export function fetchAdminManualRedeemSkuSuggestions(params?: Record) { - return apiGet<{ items: AdminInventorySkuSuggestion[] }>('/api/v1/admin/manual-redeem/sku-suggestions', params) + return apiGet<{ items: AdminInventorySkuSuggestion[] }>( + '/api/v1/admin/manual-redeem/sku-suggestions', + params, + ) } export function createAdminManualRedeemTask(payload: { @@ -30,7 +33,10 @@ export function fetchAdminManualRedeemSessionSummary(taskId: number | string) { } export function refreshAdminManualRedeemSession(taskId: number | string) { - return apiPost(`/api/v1/admin/manual-redeem/${taskId}/session/refresh`, {}) + return apiPost( + `/api/v1/admin/manual-redeem/${taskId}/session/refresh`, + {}, + ) } export function removeAdminManualRedeemSession(taskId: number | string) { diff --git a/apps/frontend/src/services/admin/orders.ts b/apps/frontend/src/services/admin/orders.ts index 92059f78..02de9ed5 100644 --- a/apps/frontend/src/services/admin/orders.ts +++ b/apps/frontend/src/services/admin/orders.ts @@ -2,7 +2,10 @@ import { apiGet } from '@/lib/http' import type { AdminOrderDetail, AdminOrderListItem, AdminPagination } from '@/types/admin' export function fetchAdminOrders(params?: Record) { - return apiGet<{ items: AdminOrderListItem[]; pagination: AdminPagination }>('/api/v1/admin/orders', params) + return apiGet<{ items: AdminOrderListItem[]; pagination: AdminPagination }>( + '/api/v1/admin/orders', + params, + ) } export function fetchAdminOrderDetail(orderId: number | string) { diff --git a/apps/frontend/src/services/admin/platform-config.ts b/apps/frontend/src/services/admin/platform-config.ts index bdbf0881..129487ec 100644 --- a/apps/frontend/src/services/admin/platform-config.ts +++ b/apps/frontend/src/services/admin/platform-config.ts @@ -59,12 +59,11 @@ export function saveAdminNotificationConfig(payload: AdminNotificationConfig) { }>('/api/v1/admin/platform-config/notifications', payload as unknown as Record) } -export function testAdminNotification(payload: { - title?: string - body?: string - url?: string -}) { - return apiPost('/api/v1/admin/platform-config/notifications/test', payload) +export function testAdminNotification(payload: { title?: string; body?: string; url?: string }) { + return apiPost( + '/api/v1/admin/platform-config/notifications/test', + payload, + ) } export function fetchAdminScheduledJobsConfig() { @@ -85,11 +84,13 @@ export function runAdminScheduledJob(jobId: string) { }>(`/api/v1/admin/platform-config/scheduled-jobs/${jobId}/run`, {}) } -export function fetchAdminNinetyoneOrders(params: { - page?: number - pageSize?: number - status?: string -} = {}) { +export function fetchAdminNinetyoneOrders( + params: { + page?: number + pageSize?: number + status?: string + } = {}, +) { const searchParams = new URLSearchParams() if (params.page) { searchParams.set('page', String(params.page)) @@ -131,7 +132,10 @@ export function saveAdminKuaishouEticketSourceConfig(payload: AdminKuaishouEtick return apiPost<{ filePath: string source: AdminKuaishouEticketSourceConfig - }>('/api/v1/admin/platform-config/kuaishou-eticket-source', payload as unknown as Record) + }>( + '/api/v1/admin/platform-config/kuaishou-eticket-source', + payload as unknown as Record, + ) } export function queryAdminKuaishouEticketDetail(payload: { @@ -140,7 +144,10 @@ export function queryAdminKuaishouEticketDetail(payload: { cookie?: string eTicketId: string }) { - return apiPost('/api/v1/admin/platform-config/kuaishou-eticket/query-detail', payload) + return apiPost( + '/api/v1/admin/platform-config/kuaishou-eticket/query-detail', + payload, + ) } export function queryAdminKuaishouEticketShopInfo(payload: { @@ -148,7 +155,10 @@ export function queryAdminKuaishouEticketShopInfo(payload: { shopId?: string cookie?: string }) { - return apiPost('/api/v1/admin/platform-config/kuaishou-eticket/query-shop-info', payload) + return apiPost( + '/api/v1/admin/platform-config/kuaishou-eticket/query-shop-info', + payload, + ) } export function consumeAdminKuaishouEticket(payload: { @@ -161,7 +171,10 @@ export function consumeAdminKuaishouEticket(payload: { num?: number storeId?: string }) { - return apiPost('/api/v1/admin/platform-config/kuaishou-eticket/consume', payload) + return apiPost( + '/api/v1/admin/platform-config/kuaishou-eticket/consume', + payload, + ) } export function fetchAdminCloudtentaclesSourceConfig() { @@ -179,7 +192,10 @@ export function saveAdminCloudtentaclesSourceConfig(payload: AdminCloudtentacles sessionFilePath: string source: AdminCloudtentaclesSourceConfig session: AdminCloudtentaclesPersistedSession - }>('/api/v1/admin/platform-config/cloudtentacles-source', payload as unknown as Record) + }>( + '/api/v1/admin/platform-config/cloudtentacles-source', + payload as unknown as Record, + ) } export function sendAdminCloudtentaclesSmsCode(payload: { @@ -189,7 +205,10 @@ export function sendAdminCloudtentaclesSmsCode(payload: { deviceId?: string deviceType?: number }) { - return apiPost('/api/v1/admin/platform-config/cloudtentacles/send-sms-code', payload) + return apiPost( + '/api/v1/admin/platform-config/cloudtentacles/send-sms-code', + payload, + ) } export function testAdminCloudtentaclesLogin(payload: { @@ -201,7 +220,10 @@ export function testAdminCloudtentaclesLogin(payload: { deviceId?: string deviceType?: number }) { - return apiPost('/api/v1/admin/platform-config/cloudtentacles/test-login', payload) + return apiPost( + '/api/v1/admin/platform-config/cloudtentacles/test-login', + payload, + ) } export function validateAdminCloudtentaclesSession(payload: { @@ -210,7 +232,10 @@ export function validateAdminCloudtentaclesSession(payload: { deviceId?: string deviceType?: number }) { - return apiPost('/api/v1/admin/platform-config/cloudtentacles/validate-session', payload) + return apiPost( + '/api/v1/admin/platform-config/cloudtentacles/validate-session', + payload, + ) } export function fetchAdminCloudtentaclesAsset(payload: { @@ -219,7 +244,10 @@ export function fetchAdminCloudtentaclesAsset(payload: { deviceId?: string deviceType?: number }) { - return apiPost>('/api/v1/admin/platform-config/cloudtentacles/asset', payload) + return apiPost>( + '/api/v1/admin/platform-config/cloudtentacles/asset', + payload, + ) } export function fetchAdminCloudtentaclesCategories(payload: { @@ -228,7 +256,10 @@ export function fetchAdminCloudtentaclesCategories(payload: { deviceId?: string deviceType?: number }) { - return apiPost>('/api/v1/admin/platform-config/cloudtentacles/categories', payload) + return apiPost>( + '/api/v1/admin/platform-config/cloudtentacles/categories', + payload, + ) } export function fetchAdminCloudtentaclesSkuList(payload: { @@ -237,7 +268,10 @@ export function fetchAdminCloudtentaclesSkuList(payload: { deviceId?: string deviceType?: number }) { - return apiPost('/api/v1/admin/platform-config/cloudtentacles/sku/list', payload) + return apiPost( + '/api/v1/admin/platform-config/cloudtentacles/sku/list', + payload, + ) } export function buyAdminCloudtentaclesSku(payload: { @@ -248,7 +282,10 @@ export function buyAdminCloudtentaclesSku(payload: { id?: number count?: number }) { - return apiPost>('/api/v1/admin/platform-config/cloudtentacles/sku/buy', payload) + return apiPost>( + '/api/v1/admin/platform-config/cloudtentacles/sku/buy', + payload, + ) } export function useAdminCloudtentaclesSku(payload: { @@ -260,7 +297,10 @@ export function useAdminCloudtentaclesSku(payload: { virtualNumberId?: number phone?: string }) { - return apiPost>('/api/v1/admin/platform-config/cloudtentacles/sku/use', payload) + return apiPost>( + '/api/v1/admin/platform-config/cloudtentacles/sku/use', + payload, + ) } export function fetchAdminCloudtentaclesKnapsack(payload: { @@ -269,7 +309,10 @@ export function fetchAdminCloudtentaclesKnapsack(payload: { deviceId?: string deviceType?: number }) { - return apiPost>('/api/v1/admin/platform-config/cloudtentacles/knapsack', payload) + return apiPost>( + '/api/v1/admin/platform-config/cloudtentacles/knapsack', + payload, + ) } export function fetchAdminCloudtentaclesVnList(payload: { @@ -279,7 +322,10 @@ export function fetchAdminCloudtentaclesVnList(payload: { deviceType?: number key?: string }) { - return apiPost>('/api/v1/admin/platform-config/cloudtentacles/vn/list', payload) + return apiPost>( + '/api/v1/admin/platform-config/cloudtentacles/vn/list', + payload, + ) } export function appointAdminCloudtentaclesVn(payload: { @@ -289,7 +335,10 @@ export function appointAdminCloudtentaclesVn(payload: { deviceType?: number key?: string }) { - return apiPost>('/api/v1/admin/platform-config/cloudtentacles/vn/appoint', payload) + return apiPost>( + '/api/v1/admin/platform-config/cloudtentacles/vn/appoint', + payload, + ) } export function generateAdminCloudtentaclesVnLoginCode(payload: { @@ -300,7 +349,10 @@ export function generateAdminCloudtentaclesVnLoginCode(payload: { key?: string id?: number }) { - return apiPost>('/api/v1/admin/platform-config/cloudtentacles/vn/generate-login-code', payload) + return apiPost>( + '/api/v1/admin/platform-config/cloudtentacles/vn/generate-login-code', + payload, + ) } export function fetchAdminCloudtentaclesVnCode(payload: { @@ -311,7 +363,10 @@ export function fetchAdminCloudtentaclesVnCode(payload: { key?: string phone?: string }) { - return apiPost>('/api/v1/admin/platform-config/cloudtentacles/vn/fetch-code', payload) + return apiPost>( + '/api/v1/admin/platform-config/cloudtentacles/vn/fetch-code', + payload, + ) } export function verifyAdminCloudtentaclesVnCode(payload: { @@ -323,7 +378,10 @@ export function verifyAdminCloudtentaclesVnCode(payload: { id?: number code?: string }) { - return apiPost>('/api/v1/admin/platform-config/cloudtentacles/vn/verify-code', payload) + return apiPost>( + '/api/v1/admin/platform-config/cloudtentacles/vn/verify-code', + payload, + ) } export function fetchAdminCloudtentaclesBindUrl(payload: { @@ -334,7 +392,10 @@ export function fetchAdminCloudtentaclesBindUrl(payload: { key?: string id?: number }) { - return apiPost>('/api/v1/admin/platform-config/cloudtentacles/vn/bind-url', payload) + return apiPost>( + '/api/v1/admin/platform-config/cloudtentacles/vn/bind-url', + payload, + ) } export function backAdminCloudtentaclesVn(payload: { @@ -345,7 +406,10 @@ export function backAdminCloudtentaclesVn(payload: { key?: string id?: number }) { - return apiPost>('/api/v1/admin/platform-config/cloudtentacles/vn/back', payload) + return apiPost>( + '/api/v1/admin/platform-config/cloudtentacles/vn/back', + payload, + ) } export function runAdminCloudtentaclesFullFlow(payload: { @@ -357,7 +421,10 @@ export function runAdminCloudtentaclesFullFlow(payload: { skuCount?: number vnKey?: string }) { - return apiPost>('/api/v1/admin/platform-config/cloudtentacles/debug/full-flow', payload) + return apiPost>( + '/api/v1/admin/platform-config/cloudtentacles/debug/full-flow', + payload, + ) } export function fetchAdminFulfillmentBindingConfigs() { @@ -374,10 +441,15 @@ export function lookupAdminFulfillmentBindingOrder(payload: { shopId: string platformOrderId: string }) { - return apiPost('/api/v1/admin/platform-config/fulfillment-bindings/lookup-order', payload) + return apiPost( + '/api/v1/admin/platform-config/fulfillment-bindings/lookup-order', + payload, + ) } -export function saveAdminFulfillmentBindingConfigs(payload: { bindings: Array> }) { +export function saveAdminFulfillmentBindingConfigs(payload: { + bindings: Array> +}) { return apiPost<{ filePath: string bindings: AdminFulfillmentBindingConfigItem[] @@ -391,9 +463,14 @@ export function fetchAdminKuaishouCloudFulfillmentConfig() { }>('/api/v1/admin/platform-config/kuaishou-cloud-fulfillment') } -export function saveAdminKuaishouCloudFulfillmentConfig(payload: AdminKuaishouCloudFulfillmentConfig) { +export function saveAdminKuaishouCloudFulfillmentConfig( + payload: AdminKuaishouCloudFulfillmentConfig, +) { return apiPost<{ filePath: string source: AdminKuaishouCloudFulfillmentConfig - }>('/api/v1/admin/platform-config/kuaishou-cloud-fulfillment', payload as unknown as Record) + }>( + '/api/v1/admin/platform-config/kuaishou-cloud-fulfillment', + payload as unknown as Record, + ) } diff --git a/apps/frontend/src/services/admin/tasks.ts b/apps/frontend/src/services/admin/tasks.ts index bc743716..4f56557a 100644 --- a/apps/frontend/src/services/admin/tasks.ts +++ b/apps/frontend/src/services/admin/tasks.ts @@ -1,8 +1,16 @@ import { apiGet, apiGetBlob, apiPost } from '@/lib/http' -import type { AdminPagination, AdminTaskActionResponse, AdminTaskDetail, AdminTaskListItem } from '@/types/admin' +import type { + AdminPagination, + AdminTaskActionResponse, + AdminTaskDetail, + AdminTaskListItem, +} from '@/types/admin' export function fetchAdminTasks(params?: Record) { - return apiGet<{ items: AdminTaskListItem[]; pagination: AdminPagination }>('/api/v1/admin/tasks', params) + return apiGet<{ items: AdminTaskListItem[]; pagination: AdminPagination }>( + '/api/v1/admin/tasks', + params, + ) } export function fetchAdminTaskDetail(taskId: number | string) { @@ -21,8 +29,14 @@ export function releaseAdminTaskInventory(taskId: number | string) { return apiPost(`/api/v1/admin/tasks/${taskId}/release-inventory`, {}) } -export function releaseAdminTaskInventoryBinding(taskId: number | string, bindingId: number | string) { - return apiPost(`/api/v1/admin/tasks/${taskId}/inventory-bindings/${bindingId}/release`, {}) +export function releaseAdminTaskInventoryBinding( + taskId: number | string, + bindingId: number | string, +) { + return apiPost( + `/api/v1/admin/tasks/${taskId}/inventory-bindings/${bindingId}/release`, + {}, + ) } export function regenerateAdminTaskClaimLink(taskId: number | string) { @@ -54,15 +68,24 @@ export function completeAdminTaskManualDispatch( deliveredCredential?: string }, ) { - return apiPost(`/api/v1/admin/tasks/${taskId}/complete-manual-dispatch`, payload) + return apiPost( + `/api/v1/admin/tasks/${taskId}/complete-manual-dispatch`, + payload, + ) } export function prepareAdminTaskKuaishouCloudFulfillment(taskId: number | string) { - return apiPost(`/api/v1/admin/tasks/${taskId}/kuaishou-cloud/prepare`, {}) + return apiPost( + `/api/v1/admin/tasks/${taskId}/kuaishou-cloud/prepare`, + {}, + ) } export function refreshAdminTaskKuaishouCloudRoleInfo(taskId: number | string) { - return apiPost(`/api/v1/admin/tasks/${taskId}/kuaishou-cloud/refresh-role-info`, {}) + return apiPost( + `/api/v1/admin/tasks/${taskId}/kuaishou-cloud/refresh-role-info`, + {}, + ) } export function dispatchAdminTaskKuaishouCloudFulfillment( @@ -71,9 +94,15 @@ export function dispatchAdminTaskKuaishouCloudFulfillment( ticketCode?: string } = {}, ) { - return apiPost(`/api/v1/admin/tasks/${taskId}/kuaishou-cloud/dispatch`, payload) + return apiPost( + `/api/v1/admin/tasks/${taskId}/kuaishou-cloud/dispatch`, + payload, + ) } export function returnNumberAdminTaskKuaishouCloudFulfillment(taskId: number | string) { - return apiPost(`/api/v1/admin/tasks/${taskId}/kuaishou-cloud/return-number`, {}) + return apiPost( + `/api/v1/admin/tasks/${taskId}/kuaishou-cloud/return-number`, + {}, + ) } diff --git a/apps/frontend/src/services/admin/users.ts b/apps/frontend/src/services/admin/users.ts index 64350520..7e66cea2 100644 --- a/apps/frontend/src/services/admin/users.ts +++ b/apps/frontend/src/services/admin/users.ts @@ -2,10 +2,18 @@ import { apiGet, apiPost } from '@/lib/http' import type { AdminPagination, AdminUserListItem } from '@/types/admin' export function fetchAdminUsers(params?: Record) { - return apiGet<{ items: AdminUserListItem[]; pagination: AdminPagination }>('/api/v1/admin/users', params) + return apiGet<{ items: AdminUserListItem[]; pagination: AdminPagination }>( + '/api/v1/admin/users', + params, + ) } -export function createAdminUser(payload: { username: string; password: string; role: string; status?: string }) { +export function createAdminUser(payload: { + username: string + password: string + role: string + status?: string +}) { return apiPost<{ user: AdminUserListItem }>('/api/v1/admin/users', payload) } @@ -17,10 +25,19 @@ export function updateAdminUserStatus(userId: number | string, payload: { status return apiPost<{ user: AdminUserListItem }>(`/api/v1/admin/users/${userId}/status`, payload) } -export function updateAdminUserInventoryGroups(userId: number | string, payload: { inventoryGroupCodes: string[] }) { - return apiPost<{ user: AdminUserListItem }>(`/api/v1/admin/users/${userId}/inventory-groups`, payload) +export function updateAdminUserInventoryGroups( + userId: number | string, + payload: { inventoryGroupCodes: string[] }, +) { + return apiPost<{ user: AdminUserListItem }>( + `/api/v1/admin/users/${userId}/inventory-groups`, + payload, + ) } export function resetAdminUserPassword(userId: number | string, payload: { password: string }) { - return apiPost<{ user: AdminUserListItem }>(`/api/v1/admin/users/${userId}/reset-password`, payload) + return apiPost<{ user: AdminUserListItem }>( + `/api/v1/admin/users/${userId}/reset-password`, + payload, + ) } diff --git a/apps/frontend/src/services/admin/webhook-events.ts b/apps/frontend/src/services/admin/webhook-events.ts index aee3111f..22f1f798 100644 --- a/apps/frontend/src/services/admin/webhook-events.ts +++ b/apps/frontend/src/services/admin/webhook-events.ts @@ -1,5 +1,10 @@ import { apiGet, apiPost } from '@/lib/http' -import type { AdminPagination, AdminWebhookEventDetail, AdminWebhookEventListItem, AdminWebhookReplayResponse } from '@/types/admin' +import type { + AdminPagination, + AdminWebhookEventDetail, + AdminWebhookEventListItem, + AdminWebhookReplayResponse, +} from '@/types/admin' export function fetchAdminWebhookEvents(params?: Record) { return apiGet<{ items: AdminWebhookEventListItem[]; pagination: AdminPagination }>( diff --git a/apps/frontend/src/services/tencent/session.ts b/apps/frontend/src/services/tencent/session.ts index 48c44086..a1864052 100644 --- a/apps/frontend/src/services/tencent/session.ts +++ b/apps/frontend/src/services/tencent/session.ts @@ -21,7 +21,9 @@ export function fetchTencentBrowserSession(sessionId: string) { } export function fetchTencentBrowserSessionSummary(sessionId: string) { - return apiGet(`/api/v1/tencent/browser/session/${sessionId}/summary`) + return apiGet( + `/api/v1/tencent/browser/session/${sessionId}/summary`, + ) } export function refreshTencentBrowserSessionPage(sessionId: string) { diff --git a/apps/frontend/src/styles/admin-list-pages.css b/apps/frontend/src/styles/admin-list-pages.css index eafbcffe..866ac4e9 100644 --- a/apps/frontend/src/styles/admin-list-pages.css +++ b/apps/frontend/src/styles/admin-list-pages.css @@ -106,11 +106,31 @@ line-height: 1; } -.summary-metric[data-tone='success'] { color: var(--color-success-dark); background: var(--color-success-light); border-color: #bbf7d0; } -.summary-metric[data-tone='danger'] { color: var(--color-danger-dark); background: var(--color-danger-light); border-color: #fecaca; } -.summary-metric[data-tone='primary'] { color: var(--color-primary-dark); background: var(--color-primary-light); border-color: #bfdbfe; } -.summary-metric[data-tone='warning'] { color: var(--color-warning-dark); background: var(--color-warning-light); border-color: #fed7aa; } -.summary-metric[data-tone='muted'] { color: var(--text-secondary); background: #f8fafc; border-color: var(--border-default); } +.summary-metric[data-tone='success'] { + color: var(--color-success-dark); + background: var(--color-success-light); + border-color: #bbf7d0; +} +.summary-metric[data-tone='danger'] { + color: var(--color-danger-dark); + background: var(--color-danger-light); + border-color: #fecaca; +} +.summary-metric[data-tone='primary'] { + color: var(--color-primary-dark); + background: var(--color-primary-light); + border-color: #bfdbfe; +} +.summary-metric[data-tone='warning'] { + color: var(--color-warning-dark); + background: var(--color-warning-light); + border-color: #fed7aa; +} +.summary-metric[data-tone='muted'] { + color: var(--text-secondary); + background: #f8fafc; + border-color: var(--border-default); +} /* ---------- 表格工具栏 ---------- */ .table-toolbar { diff --git a/apps/frontend/src/types/tencent/session.ts b/apps/frontend/src/types/tencent/session.ts index c88cc83c..908bd2f0 100644 --- a/apps/frontend/src/types/tencent/session.ts +++ b/apps/frontend/src/types/tencent/session.ts @@ -37,7 +37,9 @@ export interface TencentBrowserSessionData { artifacts: TencentBrowserSessionArtifacts } -export interface TencentBrowserSessionSummaryData - extends Omit { +export interface TencentBrowserSessionSummaryData extends Omit< + TencentBrowserSessionData, + 'qrImageBase64' +> { qrImageBase64?: string } diff --git a/apps/frontend/src/utils/admin-display.ts b/apps/frontend/src/utils/admin-display.ts index eaacff6d..5bec4e00 100644 --- a/apps/frontend/src/utils/admin-display.ts +++ b/apps/frontend/src/utils/admin-display.ts @@ -86,7 +86,7 @@ export function formatRedeemOutcomeLabel(value: string) { } export function formatRedeemResolutionStatus(value: string) { - return value === 'success' ? '已完成' : value === 'failed' ? '失败收口' : (value || '-') + return value === 'success' ? '已完成' : value === 'failed' ? '失败收口' : value || '-' } export function formatAutoDeliveryTrigger(value: string) { @@ -161,7 +161,9 @@ export function formatTaskEventPayload(payload: Record) { payload.bindUrl ? `绑定链接 ${payload.bindUrl}` : '', payload.sendType ? `发送类型 ${payload.sendType}` : '', payload.note ? `备注 ${payload.note}` : '', - payload.previousOutcome ? `切换原因 ${formatRedeemOutcomeLabel(String(payload.previousOutcome || ''))}` : '', + payload.previousOutcome + ? `切换原因 ${formatRedeemOutcomeLabel(String(payload.previousOutcome || ''))}` + : '', payload.deliveryReference ? `单号 ${payload.deliveryReference}` : '', payload.platformOrderId ? `平台单 ${payload.platformOrderId}` : '', payload.trigger ? `触发 ${formatAutoDeliveryTrigger(String(payload.trigger || ''))}` : '', diff --git a/apps/frontend/src/utils/date-time.ts b/apps/frontend/src/utils/date-time.ts index df5319f2..1567b29f 100644 --- a/apps/frontend/src/utils/date-time.ts +++ b/apps/frontend/src/utils/date-time.ts @@ -35,7 +35,10 @@ export function normalizeDateTimeValue(value: unknown): unknown { if (value && typeof value === 'object') { return Object.fromEntries( - Object.entries(value).map(([key, currentValue]) => [key, normalizeDateTimeValue(currentValue)]), + Object.entries(value).map(([key, currentValue]) => [ + key, + normalizeDateTimeValue(currentValue), + ]), ) } diff --git a/apps/frontend/src/views/admin/audit-logs/AdminAuditLogsView.vue b/apps/frontend/src/views/admin/audit-logs/AdminAuditLogsView.vue index 074b2f2b..26b5a719 100644 --- a/apps/frontend/src/views/admin/audit-logs/AdminAuditLogsView.vue +++ b/apps/frontend/src/views/admin/audit-logs/AdminAuditLogsView.vue @@ -73,18 +73,17 @@ onMounted(loadAuditLogs)