├── .gitignore ├── tsconfig.json ├── src ├── route-type.d.ts ├── schema.json └── index.ts ├── LICENSE ├── package.json ├── README.md └── pnpm-lock.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | *.tsbuildinfo -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2016", 4 | "lib": ["ESNext"], 5 | "module": "commonjs", 6 | "moduleResolution": "node", 7 | "sourceMap": true, 8 | "composite": true, 9 | "declaration": true, 10 | "strict": true, 11 | "alwaysStrict": false, 12 | "esModuleInterop": true, 13 | "resolveJsonModule": true, 14 | "skipLibCheck": true, 15 | "noUnusedLocals": true, 16 | "baseUrl": "./", 17 | "noEmit": false, 18 | "outDir": "dist", 19 | "rootDir": "src" 20 | }, 21 | "include": ["src", "src/schema.json"] 22 | } 23 | -------------------------------------------------------------------------------- /src/route-type.d.ts: -------------------------------------------------------------------------------- 1 | import type { RouteRecordRaw } from "vue-router"; 2 | 3 | export interface CustomRouteBlock 4 | extends Partial< 5 | Omit< 6 | RouteRecordRaw, 7 | | "components" 8 | | "component" 9 | | "children" 10 | | "beforeEnter" 11 | | "name" 12 | | "redirect" 13 | | "props" 14 | > 15 | > { 16 | /** 17 | * Name for the route record. 18 | */ 19 | name?: string; 20 | /** 21 | * Where to redirect if the route is directly matched. The redirection happens 22 | * before any navigation guard and triggers a new navigation with the new 23 | * target location. 24 | */ 25 | redirect?: string; 26 | } 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Yue JIN 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "volar-plugin-vue-router", 3 | "version": "0.3.0", 4 | "description": "Volar plugin for route custom block in Vue SFC", 5 | "keywords": [ 6 | "volar", 7 | "json", 8 | "jsonschema" 9 | ], 10 | "main": "dist/index.js", 11 | "author": "Yue JIN ", 12 | "license": "MIT", 13 | "files": [ 14 | "dist/*" 15 | ], 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/kingyue737/volar-plugin-vue-router.git" 19 | }, 20 | "scripts": { 21 | "build": "tsc", 22 | "generateSchema": "ts-json-schema-generator -p \"src/route-type.d.ts\" -t \"CustomRouteBlock\" -o \"src/schema.json\" --no-type-check", 23 | "prepublishOnly": "pnpm build" 24 | }, 25 | "dependencies": { 26 | "ts-json-schema-generator": "1.2.0", 27 | "vscode-json-languageservice": "^5.3.9" 28 | }, 29 | "devDependencies": { 30 | "@types/json-schema": "^7.0.15", 31 | "@types/node": "^20.11.24", 32 | "@volar/language-service": "^2.1.0", 33 | "typescript": "^5.3.3", 34 | "vue": "3.2.47", 35 | "vue-router": "~4.1.6" 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /src/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$ref": "#/definitions/CustomRouteBlock", 3 | "$schema": "http://json-schema.org/draft-07/schema#", 4 | "definitions": { 5 | "CustomRouteBlock": { 6 | "additionalProperties": false, 7 | "properties": { 8 | "alias": { 9 | "anyOf": [ 10 | { 11 | "type": "string" 12 | }, 13 | { 14 | "items": { 15 | "type": "string" 16 | }, 17 | "type": "array" 18 | } 19 | ], 20 | "description": "Aliases for the record. Allows defining extra paths that will behave like a copy of the record. Allows having paths shorthands like `/users/:id` and `/u/:id`. All `alias` and `path` values must share the same params." 21 | }, 22 | "end": { 23 | "description": "Should the RegExp match until the end by appending a `$` to it.", 24 | "type": "boolean" 25 | }, 26 | "meta": { 27 | "$ref": "#/definitions/RouteMeta", 28 | "description": "Arbitrary data attached to the record." 29 | }, 30 | "name": { 31 | "description": "Name for the route record.", 32 | "type": "string" 33 | }, 34 | "path": { 35 | "description": "Path of the record. Should start with `/` unless the record is the child of another record.", 36 | "type": "string" 37 | }, 38 | "redirect": { 39 | "description": "Where to redirect if the route is directly matched. The redirection happens before any navigation guard and triggers a new navigation with the new target location.", 40 | "type": "string" 41 | }, 42 | "sensitive": { 43 | "description": "Makes the RegExp case-sensitive.", 44 | "type": "boolean" 45 | }, 46 | "strict": { 47 | "description": "Whether to disallow a trailing slash or not.", 48 | "type": "boolean" 49 | } 50 | }, 51 | "type": "object" 52 | }, 53 | "RouteMeta": { 54 | "additionalProperties": {}, 55 | "description": "Interface to type `meta` fields in route records.", 56 | "properties": {}, 57 | "type": "object" 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # volar-plugin-vue-router 2 | 3 | [![npm version](https://img.shields.io/npm/v/volar-plugin-vue-router)](https://www.npmjs.com/package/volar-plugin-vue-router) 4 | 5 | Volar plugin for IntelliSense in `` custom block in Vue SFC. Inspired by [built-in json plugin](https://github.com/johnsoncodehk/volar/blob/master/plugins/json/src/index.ts) of Volar. 6 | 7 |

8 | 9 |

10 | 11 | > [!WARNING] 12 | > `volar.config.js` is no longer supported since [`Vue - Official` v2](https://github.com/vuejs/language-tools/blob/master/CHANGELOG.md#refactors-1). If you want to use this plugin, please install `Vue - Official` v1.8.27. 13 | 14 | ## Usage 15 | 16 | ```sh 17 | pnpm add -D volar-plugin-vue-router 18 | # or 19 | npm i -D volar-plugin-vue-router 20 | # or 21 | yarn add -D volar-plugin-vue-router 22 | ``` 23 | 24 | `volar.config.js` 25 | 26 | ```js 27 | const route = require("volar-plugin-vue-router").default; 28 | 29 | module.exports = { 30 | // volar >= v1.7 31 | services: [route()], 32 | // volar < v1.7 33 | plugins: [route()], 34 | }; 35 | ``` 36 | 37 | ## `RouteMeta` 38 | 39 | Vue Router allows users to [type the meta field by extending the `RouteMeta`](https://router.vuejs.org/guide/advanced/meta.html#typescript). You can pass the path of source file containing `RouteMeta` type and the path of `tsconfig` to this plugin. For example: 40 | 41 | ```js 42 | const route = require("volar-plugin-vue-router").default; 43 | 44 | module.exports = { 45 | services: [ 46 | route({ path: "src/route-meta.d.ts", tsconfig: "./tsconfig.app.json" }), 47 | ], 48 | }; 49 | ``` 50 | 51 | Then this plugin will use [ts-json-schema-generator](https://github.com/vega/ts-json-schema-generator) to generate JSON Schema of `meta` and give you Intellisense of `meta` in `` custom block. 52 | 53 | For example, the type declaration below will generate the following JSON Schema for Intellisense: 54 | 55 | ```ts 56 | // route-meta.d.ts 57 | export {}; 58 | 59 | import "vue-router"; 60 | import type { Role } from "@/api/users"; 61 | 62 | declare module "vue-router" { 63 | interface RouteMeta { 64 | /** Drawer item icon */ 65 | icon?: string; 66 | /** Groups will be separated by divider line in drawer */ 67 | drawerGroup?: "admin" | "PUC"; 68 | /** Determine the order of item in drawer */ 69 | drawerIndex?: number; 70 | /** Drawer item and breadcrumb text */ 71 | title?: string; 72 | /** Authorized user groups */ 73 | roles?: Role[]; 74 | } 75 | } 76 | ``` 77 | 78 | Generated Schema: 79 | 80 | ```json 81 | { 82 | "$ref": "#/definitions/RouteMeta", 83 | "$schema": "http://json-schema.org/draft-07/schema#", 84 | "definitions": { 85 | "Role": { 86 | "enum": ["superuser", "admin", "staff"], 87 | "type": "string" 88 | }, 89 | "RouteMeta": { 90 | "additionalProperties": false, 91 | "properties": { 92 | "drawerGroup": { 93 | "description": "Groups will be separated by divider line in drawer", 94 | "enum": ["admin", "PUC"], 95 | "type": "string" 96 | }, 97 | "drawerIndex": { 98 | "description": "Determine the order of item in drawer", 99 | "type": "number" 100 | }, 101 | "icon": { 102 | "description": "Drawer item icon", 103 | "type": "string" 104 | }, 105 | "roles": { 106 | "description": "Authorized user groups", 107 | "items": { 108 | "$ref": "#/definitions/Role" 109 | }, 110 | "type": "array" 111 | }, 112 | "title": { 113 | "description": "Drawer item and breadcrumb text", 114 | "type": "string" 115 | } 116 | }, 117 | "type": "object" 118 | } 119 | } 120 | } 121 | ``` 122 | 123 | ### Refresh 124 | 125 | Once you modify your definition of `RouteMeta`, restart Volar with VSCode command palette to make it effective. 126 | 127 | ![VSCode](https://i.stack.imgur.com/jq6xW.png) 128 | 129 | ## License 130 | 131 | [MIT](http://opensource.org/licenses/MIT) 132 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import type { ServicePlugin } from "@volar/language-service"; 2 | import { 3 | type JSONDocument, 4 | type TextDocument, 5 | getLanguageService, 6 | } from "vscode-json-languageservice"; 7 | import customBlockSchema from "./schema.json"; 8 | import { createGenerator, type Config } from "ts-json-schema-generator"; 9 | 10 | type PluginConfig = Pick; 11 | 12 | // Modify of https://github.com/volarjs/services/blob/master/packages/json/src/index.ts 13 | export default (config: PluginConfig = {}): ServicePlugin => ({ 14 | // https://github.com/microsoft/vscode/blob/09850876e652688fb142e2e19fd00fd38c0bc4ba/extensions/json-language-features/server/src/jsonServer.ts#L150 15 | name: "route", 16 | triggerCharacters: ['"', ":"], 17 | create(context) { 18 | const jsonDocuments = new WeakMap(); 19 | 20 | const jsonLs = getLanguageService({}); 21 | try { 22 | const routeMetaSchema = createGenerator({ 23 | skipTypeCheck: true, 24 | type: "RouteMeta", 25 | ...config, 26 | }).createSchema("RouteMeta"); 27 | customBlockSchema.definitions = { 28 | ...customBlockSchema.definitions, 29 | ...routeMetaSchema.definitions, 30 | }; 31 | } catch (e) { 32 | console.log("[Error] volar-plugin-vue-router:"); 33 | console.log(e); 34 | } 35 | jsonLs.configure({ 36 | allowComments: false, 37 | schemas: [ 38 | { 39 | fileMatch: ["*.customBlock_route_*.json"], 40 | uri: "foo://route-custom-block.schema.json", 41 | schema: customBlockSchema, 42 | }, 43 | ], 44 | }); 45 | 46 | return { 47 | provide: { 48 | "route/jsonDocument": getJsonDocument, 49 | "route/languageService": () => jsonLs, 50 | }, 51 | 52 | provideCompletionItems(document, position) { 53 | return worker(document, async (jsonDocument) => { 54 | return await jsonLs.doComplete(document, position, jsonDocument); 55 | }); 56 | }, 57 | 58 | resolveCompletionItem(item) { 59 | return jsonLs.doResolve(item); 60 | }, 61 | 62 | provideDefinition(document, position) { 63 | return worker(document, async (jsonDocument) => { 64 | return await jsonLs.findDefinition(document, position, jsonDocument); 65 | }); 66 | }, 67 | 68 | provideDiagnostics(document) { 69 | return worker(document, async (jsonDocument) => { 70 | const documentLanguageSettings = undefined; // await getSettings(); // TODO 71 | 72 | return await jsonLs.doValidation( 73 | document, 74 | jsonDocument, 75 | documentLanguageSettings 76 | ); 77 | }); 78 | }, 79 | 80 | provideHover(document, position) { 81 | return worker(document, async (jsonDocument) => { 82 | return await jsonLs.doHover(document, position, jsonDocument); 83 | }); 84 | }, 85 | 86 | provideDocumentLinks(document) { 87 | return worker(document, async (jsonDocument) => { 88 | return await jsonLs.findLinks(document, jsonDocument); 89 | }); 90 | }, 91 | 92 | provideDocumentSymbols(document) { 93 | return worker(document, async (jsonDocument) => { 94 | return await jsonLs.findDocumentSymbols2(document, jsonDocument); 95 | }); 96 | }, 97 | 98 | provideDocumentColors(document) { 99 | return worker(document, async (jsonDocument) => { 100 | return await jsonLs.findDocumentColors(document, jsonDocument); 101 | }); 102 | }, 103 | 104 | provideColorPresentations(document, color, range) { 105 | return worker(document, async (jsonDocument) => { 106 | return await jsonLs.getColorPresentations( 107 | document, 108 | jsonDocument, 109 | color, 110 | range 111 | ); 112 | }); 113 | }, 114 | 115 | provideFoldingRanges(document) { 116 | return worker(document, async () => { 117 | return await jsonLs.getFoldingRanges(document); 118 | }); 119 | }, 120 | 121 | provideSelectionRanges(document, positions) { 122 | return worker(document, async (jsonDocument) => { 123 | return await jsonLs.getSelectionRanges( 124 | document, 125 | positions, 126 | jsonDocument 127 | ); 128 | }); 129 | }, 130 | 131 | // provideDocumentFormattingEdits(document, range, options) { 132 | // return worker(document, async () => { 133 | // const options_2 = await context.env.getConfiguration?.< 134 | // FormattingOptions & { enable: boolean } 135 | // >("json.format"); 136 | // if (!(options_2?.enable ?? true)) { 137 | // return; 138 | // } 139 | // }); 140 | // }, 141 | }; 142 | 143 | function worker( 144 | document: TextDocument, 145 | callback: (jsonDocument: JSONDocument) => T 146 | ) { 147 | const jsonDocument = getJsonDocument(document); 148 | if (!jsonDocument) return; 149 | 150 | return callback(jsonDocument); 151 | } 152 | 153 | function getJsonDocument(textDocument: TextDocument) { 154 | if ( 155 | textDocument.languageId !== "json" && 156 | textDocument.languageId !== "jsonc" 157 | ) 158 | return; 159 | 160 | const cache = jsonDocuments.get(textDocument); 161 | if (cache) { 162 | const [cacheVersion, cacheDoc] = cache; 163 | if (cacheVersion === textDocument.version) { 164 | return cacheDoc; 165 | } 166 | } 167 | 168 | const doc = jsonLs.parseJSONDocument(textDocument); 169 | jsonDocuments.set(textDocument, [textDocument.version, doc]); 170 | 171 | return doc; 172 | } 173 | }, 174 | }); 175 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '6.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | dependencies: 8 | ts-json-schema-generator: 9 | specifier: 1.2.0 10 | version: 1.2.0 11 | vscode-json-languageservice: 12 | specifier: ^5.3.9 13 | version: 5.3.9 14 | 15 | devDependencies: 16 | '@types/json-schema': 17 | specifier: ^7.0.15 18 | version: 7.0.15 19 | '@types/node': 20 | specifier: ^20.11.24 21 | version: 20.11.24 22 | '@volar/language-service': 23 | specifier: ^2.1.0 24 | version: 2.1.0 25 | typescript: 26 | specifier: ^5.3.3 27 | version: 5.3.3 28 | vue: 29 | specifier: 3.2.47 30 | version: 3.2.47 31 | vue-router: 32 | specifier: ~4.1.6 33 | version: 4.1.6(vue@3.2.47) 34 | 35 | packages: 36 | 37 | /@babel/helper-string-parser@7.23.4: 38 | resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} 39 | engines: {node: '>=6.9.0'} 40 | dev: true 41 | 42 | /@babel/helper-validator-identifier@7.22.20: 43 | resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} 44 | engines: {node: '>=6.9.0'} 45 | dev: true 46 | 47 | /@babel/parser@7.24.0: 48 | resolution: {integrity: sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==} 49 | engines: {node: '>=6.0.0'} 50 | hasBin: true 51 | dependencies: 52 | '@babel/types': 7.24.0 53 | dev: true 54 | 55 | /@babel/types@7.24.0: 56 | resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==} 57 | engines: {node: '>=6.9.0'} 58 | dependencies: 59 | '@babel/helper-string-parser': 7.23.4 60 | '@babel/helper-validator-identifier': 7.22.20 61 | to-fast-properties: 2.0.0 62 | dev: true 63 | 64 | /@types/json-schema@7.0.15: 65 | resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} 66 | 67 | /@types/node@20.11.24: 68 | resolution: {integrity: sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==} 69 | dependencies: 70 | undici-types: 5.26.5 71 | dev: true 72 | 73 | /@volar/language-core@2.1.0: 74 | resolution: {integrity: sha512-BrYEgYHx92ocpt1OUxJs2x3TAXEjpPLxsQoARb96g2GdF62xnfRQUqCNBwiU7Z3MQ/0tOAdqdHNYNmrFtx6q4A==} 75 | dependencies: 76 | '@volar/source-map': 2.1.0 77 | dev: true 78 | 79 | /@volar/language-service@2.1.0: 80 | resolution: {integrity: sha512-3BEv8acsPC+ey2Yuecm9lSZp3AT6xq5Tj71TYXoo/TglumHRIa/y0uEIvK4b9okVJo4hgBX0kj9opbgIQrNTtA==} 81 | dependencies: 82 | '@volar/language-core': 2.1.0 83 | vscode-languageserver-protocol: 3.17.5 84 | vscode-languageserver-textdocument: 1.0.11 85 | vscode-uri: 3.0.8 86 | dev: true 87 | 88 | /@volar/source-map@2.1.0: 89 | resolution: {integrity: sha512-VPyi+DTv67cvUOkUewzsOQJY3VUhjOjQxigT487z/H7tEI8ZFd5RksC5afk3JelOK+a/3Y8LRDbKmYKu1dz87g==} 90 | dependencies: 91 | muggle-string: 0.4.1 92 | dev: true 93 | 94 | /@vscode/l10n@0.0.18: 95 | resolution: {integrity: sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==} 96 | dev: false 97 | 98 | /@vue/compiler-core@3.2.47: 99 | resolution: {integrity: sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==} 100 | dependencies: 101 | '@babel/parser': 7.24.0 102 | '@vue/shared': 3.2.47 103 | estree-walker: 2.0.2 104 | source-map: 0.6.1 105 | dev: true 106 | 107 | /@vue/compiler-dom@3.2.47: 108 | resolution: {integrity: sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==} 109 | dependencies: 110 | '@vue/compiler-core': 3.2.47 111 | '@vue/shared': 3.2.47 112 | dev: true 113 | 114 | /@vue/compiler-sfc@3.2.47: 115 | resolution: {integrity: sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==} 116 | dependencies: 117 | '@babel/parser': 7.24.0 118 | '@vue/compiler-core': 3.2.47 119 | '@vue/compiler-dom': 3.2.47 120 | '@vue/compiler-ssr': 3.2.47 121 | '@vue/reactivity-transform': 3.2.47 122 | '@vue/shared': 3.2.47 123 | estree-walker: 2.0.2 124 | magic-string: 0.25.9 125 | postcss: 8.4.35 126 | source-map: 0.6.1 127 | dev: true 128 | 129 | /@vue/compiler-ssr@3.2.47: 130 | resolution: {integrity: sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==} 131 | dependencies: 132 | '@vue/compiler-dom': 3.2.47 133 | '@vue/shared': 3.2.47 134 | dev: true 135 | 136 | /@vue/devtools-api@6.6.1: 137 | resolution: {integrity: sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==} 138 | dev: true 139 | 140 | /@vue/reactivity-transform@3.2.47: 141 | resolution: {integrity: sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==} 142 | dependencies: 143 | '@babel/parser': 7.24.0 144 | '@vue/compiler-core': 3.2.47 145 | '@vue/shared': 3.2.47 146 | estree-walker: 2.0.2 147 | magic-string: 0.25.9 148 | dev: true 149 | 150 | /@vue/reactivity@3.2.47: 151 | resolution: {integrity: sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==} 152 | dependencies: 153 | '@vue/shared': 3.2.47 154 | dev: true 155 | 156 | /@vue/runtime-core@3.2.47: 157 | resolution: {integrity: sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==} 158 | dependencies: 159 | '@vue/reactivity': 3.2.47 160 | '@vue/shared': 3.2.47 161 | dev: true 162 | 163 | /@vue/runtime-dom@3.2.47: 164 | resolution: {integrity: sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==} 165 | dependencies: 166 | '@vue/runtime-core': 3.2.47 167 | '@vue/shared': 3.2.47 168 | csstype: 2.6.21 169 | dev: true 170 | 171 | /@vue/server-renderer@3.2.47(vue@3.2.47): 172 | resolution: {integrity: sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==} 173 | peerDependencies: 174 | vue: 3.2.47 175 | dependencies: 176 | '@vue/compiler-ssr': 3.2.47 177 | '@vue/shared': 3.2.47 178 | vue: 3.2.47 179 | dev: true 180 | 181 | /@vue/shared@3.2.47: 182 | resolution: {integrity: sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==} 183 | dev: true 184 | 185 | /balanced-match@1.0.2: 186 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 187 | dev: false 188 | 189 | /brace-expansion@2.0.1: 190 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} 191 | dependencies: 192 | balanced-match: 1.0.2 193 | dev: false 194 | 195 | /commander@9.5.0: 196 | resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} 197 | engines: {node: ^12.20.0 || >=14} 198 | dev: false 199 | 200 | /csstype@2.6.21: 201 | resolution: {integrity: sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==} 202 | dev: true 203 | 204 | /estree-walker@2.0.2: 205 | resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} 206 | dev: true 207 | 208 | /fs.realpath@1.0.0: 209 | resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} 210 | dev: false 211 | 212 | /glob@8.1.0: 213 | resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} 214 | engines: {node: '>=12'} 215 | dependencies: 216 | fs.realpath: 1.0.0 217 | inflight: 1.0.6 218 | inherits: 2.0.4 219 | minimatch: 5.1.6 220 | once: 1.4.0 221 | dev: false 222 | 223 | /inflight@1.0.6: 224 | resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} 225 | dependencies: 226 | once: 1.4.0 227 | wrappy: 1.0.2 228 | dev: false 229 | 230 | /inherits@2.0.4: 231 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 232 | dev: false 233 | 234 | /json5@2.2.3: 235 | resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} 236 | engines: {node: '>=6'} 237 | hasBin: true 238 | dev: false 239 | 240 | /jsonc-parser@3.2.1: 241 | resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==} 242 | dev: false 243 | 244 | /magic-string@0.25.9: 245 | resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} 246 | dependencies: 247 | sourcemap-codec: 1.4.8 248 | dev: true 249 | 250 | /minimatch@5.1.6: 251 | resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} 252 | engines: {node: '>=10'} 253 | dependencies: 254 | brace-expansion: 2.0.1 255 | dev: false 256 | 257 | /muggle-string@0.4.1: 258 | resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} 259 | dev: true 260 | 261 | /nanoid@3.3.7: 262 | resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} 263 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 264 | hasBin: true 265 | dev: true 266 | 267 | /normalize-path@3.0.0: 268 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} 269 | engines: {node: '>=0.10.0'} 270 | dev: false 271 | 272 | /once@1.4.0: 273 | resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} 274 | dependencies: 275 | wrappy: 1.0.2 276 | dev: false 277 | 278 | /picocolors@1.0.0: 279 | resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} 280 | dev: true 281 | 282 | /postcss@8.4.35: 283 | resolution: {integrity: sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==} 284 | engines: {node: ^10 || ^12 || >=14} 285 | dependencies: 286 | nanoid: 3.3.7 287 | picocolors: 1.0.0 288 | source-map-js: 1.0.2 289 | dev: true 290 | 291 | /safe-stable-stringify@2.4.3: 292 | resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} 293 | engines: {node: '>=10'} 294 | dev: false 295 | 296 | /source-map-js@1.0.2: 297 | resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} 298 | engines: {node: '>=0.10.0'} 299 | dev: true 300 | 301 | /source-map@0.6.1: 302 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} 303 | engines: {node: '>=0.10.0'} 304 | dev: true 305 | 306 | /sourcemap-codec@1.4.8: 307 | resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} 308 | deprecated: Please use @jridgewell/sourcemap-codec instead 309 | dev: true 310 | 311 | /to-fast-properties@2.0.0: 312 | resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} 313 | engines: {node: '>=4'} 314 | dev: true 315 | 316 | /ts-json-schema-generator@1.2.0: 317 | resolution: {integrity: sha512-tUMeO3ZvA12d3HHh7T/AK8W5hmUhDRNtqWRHSMN3ZRbUFt+UmV0oX8k1RK4SA+a+BKNHpmW2v06MS49e8Fi3Yg==} 318 | engines: {node: '>=10.0.0'} 319 | hasBin: true 320 | dependencies: 321 | '@types/json-schema': 7.0.15 322 | commander: 9.5.0 323 | glob: 8.1.0 324 | json5: 2.2.3 325 | normalize-path: 3.0.0 326 | safe-stable-stringify: 2.4.3 327 | typescript: 4.9.5 328 | dev: false 329 | 330 | /typescript@4.9.5: 331 | resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} 332 | engines: {node: '>=4.2.0'} 333 | hasBin: true 334 | dev: false 335 | 336 | /typescript@5.3.3: 337 | resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} 338 | engines: {node: '>=14.17'} 339 | hasBin: true 340 | dev: true 341 | 342 | /undici-types@5.26.5: 343 | resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} 344 | dev: true 345 | 346 | /vscode-json-languageservice@5.3.9: 347 | resolution: {integrity: sha512-0IcymTw0ZYX5Zcx+7KLLwTRvg0FzXUVnM1hrUH+sPhqEX0fHGg2h5UUOSp1f8ydGS7/xxzlFI3TR01yaHs6Y0Q==} 348 | dependencies: 349 | '@vscode/l10n': 0.0.18 350 | jsonc-parser: 3.2.1 351 | vscode-languageserver-textdocument: 1.0.11 352 | vscode-languageserver-types: 3.17.5 353 | vscode-uri: 3.0.8 354 | dev: false 355 | 356 | /vscode-jsonrpc@8.2.0: 357 | resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} 358 | engines: {node: '>=14.0.0'} 359 | dev: true 360 | 361 | /vscode-languageserver-protocol@3.17.5: 362 | resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} 363 | dependencies: 364 | vscode-jsonrpc: 8.2.0 365 | vscode-languageserver-types: 3.17.5 366 | dev: true 367 | 368 | /vscode-languageserver-textdocument@1.0.11: 369 | resolution: {integrity: sha512-X+8T3GoiwTVlJbicx/sIAF+yuJAqz8VvwJyoMVhwEMoEKE/fkDmrqUgDMyBECcM2A2frVZIUj5HI/ErRXCfOeA==} 370 | 371 | /vscode-languageserver-types@3.17.5: 372 | resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} 373 | 374 | /vscode-uri@3.0.8: 375 | resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} 376 | 377 | /vue-router@4.1.6(vue@3.2.47): 378 | resolution: {integrity: sha512-DYWYwsG6xNPmLq/FmZn8Ip+qrhFEzA14EI12MsMgVxvHFDYvlr4NXpVF5hrRH1wVcDP8fGi5F4rxuJSl8/r+EQ==} 379 | peerDependencies: 380 | vue: ^3.2.0 381 | dependencies: 382 | '@vue/devtools-api': 6.6.1 383 | vue: 3.2.47 384 | dev: true 385 | 386 | /vue@3.2.47: 387 | resolution: {integrity: sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==} 388 | dependencies: 389 | '@vue/compiler-dom': 3.2.47 390 | '@vue/compiler-sfc': 3.2.47 391 | '@vue/runtime-dom': 3.2.47 392 | '@vue/server-renderer': 3.2.47(vue@3.2.47) 393 | '@vue/shared': 3.2.47 394 | dev: true 395 | 396 | /wrappy@1.0.2: 397 | resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 398 | dev: false 399 | --------------------------------------------------------------------------------