[READ-ONLY] Mirror of https://github.com/bombshell-dev/tab. shell autocompletions for javascript CLIs
4

Configure Feed

Select the types of activity you want to include in your feed.

feat: finalization (#4)

authored by

Mohammad Bagher Abiyat and committed by
GitHub
(Feb 2, 2025, 1:51 PM +0330) bbef8a80 aee0186d

+4579 -2006
+12
.eslintrc.json
··· 1 + { 2 + "extends": [ 3 + "eslint:recommended", 4 + "plugin:@typescript-eslint/recommended", 5 + "prettier" 6 + ], 7 + "parser": "@typescript-eslint/parser", 8 + "plugins": ["@typescript-eslint"], 9 + "rules": { 10 + "prettier/prettier": "error" 11 + } 12 + }
+61 -38
.github/workflows/ci.yml
··· 1 - name: CLI Completion Tests 2 - 3 - on: 4 - push: 5 - branches: 6 - - main 7 - pull_request: 8 - branches: 9 - - main 10 - 11 - jobs: 12 - test: 13 - strategy: 14 - matrix: 15 - os: [ubuntu-latest, macos-latest, windows-latest] 16 - runs-on: ${{ matrix.os }} 17 - 18 - steps: 19 - - name: Checkout 20 - uses: actions/checkout@v4 21 - 22 - - name: Install pnpm 23 - uses: pnpm/action-setup@v4.0.0 24 - with: 25 - version: 8 26 - 27 - - name: Set node version to 20 28 - uses: actions/setup-node@v4 29 - with: 30 - node-version: 20 31 - registry-url: https://registry.npmjs.org/ 32 - cache: "pnpm" 33 - 34 - - name: Install deps 35 - run: pnpm install 36 - 37 - - name: Run tests 38 - run: pnpm test 1 + name: CI 2 + 3 + on: 4 + push: 5 + branches: 6 + - main 7 + pull_request: 8 + branches: 9 + - main 10 + 11 + jobs: 12 + test: 13 + name: Tests 14 + strategy: 15 + matrix: 16 + os: [ubuntu-latest, macos-latest, windows-latest] 17 + runs-on: ${{ matrix.os }} 18 + 19 + steps: 20 + - name: Checkout 21 + uses: actions/checkout@v4 22 + 23 + - name: Install pnpm 24 + uses: pnpm/action-setup@v4.0.0 25 + 26 + - name: Set node version to 20 27 + uses: actions/setup-node@v4 28 + with: 29 + node-version: 20 30 + registry-url: https://registry.npmjs.org/ 31 + cache: 'pnpm' 32 + 33 + - name: Install deps 34 + run: pnpm install 35 + 36 + - name: Run tests 37 + run: pnpm test 38 + 39 + typecheck: 40 + name: Type Check 41 + runs-on: ubuntu-latest 42 + 43 + steps: 44 + - name: Checkout 45 + uses: actions/checkout@v4 46 + 47 + - name: Install pnpm 48 + uses: pnpm/action-setup@v4.0.0 49 + 50 + - name: Set node version to 20 51 + uses: actions/setup-node@v4 52 + with: 53 + node-version: 20 54 + registry-url: https://registry.npmjs.org/ 55 + cache: pnpm 56 + 57 + - name: Install deps 58 + run: pnpm install 59 + 60 + - name: Type-check 61 + run: pnpm type-check
+27
.github/workflows/format.yml
··· 1 + name: Prettier Check 2 + 3 + on: [push, pull_request] 4 + 5 + jobs: 6 + prettier: 7 + runs-on: ubuntu-latest 8 + 9 + steps: 10 + - name: Checkout 11 + uses: actions/checkout@v4 12 + 13 + - name: Install pnpm 14 + uses: pnpm/action-setup@v4.0.0 15 + 16 + - name: Set node version to 20 17 + uses: actions/setup-node@v4 18 + with: 19 + node-version: 20 20 + registry-url: https://registry.npmjs.org/ 21 + cache: pnpm 22 + 23 + - name: Install deps 24 + run: pnpm install 25 + 26 + - name: Run Prettier Check 27 + run: npm run format:check
+25 -27
.github/workflows/pkg.pr.new.yml
··· 1 - name: pkg.pr.new 2 - on: [push, pull_request] 3 - 4 - jobs: 5 - build: 6 - runs-on: ubuntu-latest 7 - 8 - steps: 9 - - name: Checkout 10 - uses: actions/checkout@v4 11 - 12 - - name: Install pnpm 13 - uses: pnpm/action-setup@v4.0.0 14 - with: 15 - version: 8 16 - 17 - - name: Set node version to 20 18 - uses: actions/setup-node@v4 19 - with: 20 - node-version: 20 21 - registry-url: https://registry.npmjs.org/ 22 - cache: "pnpm" 23 - 24 - - name: Install deps 25 - run: pnpm install 26 - 27 - - run: pnpx pkg-pr-new publish 1 + name: pkg.pr.new 2 + on: [push, pull_request] 3 + 4 + jobs: 5 + build: 6 + runs-on: ubuntu-latest 7 + 8 + steps: 9 + - name: Checkout 10 + uses: actions/checkout@v4 11 + 12 + - name: Install pnpm 13 + uses: pnpm/action-setup@v4.0.0 14 + 15 + - name: Set node version to 20 16 + uses: actions/setup-node@v4 17 + with: 18 + node-version: 20 19 + registry-url: https://registry.npmjs.org/ 20 + cache: 'pnpm' 21 + 22 + - name: Install deps 23 + run: pnpm install 24 + 25 + - run: pnpx pkg-pr-new publish
+4
.prettierignore
··· 1 + node_modules 2 + dist 3 + build 4 + pnpm-lock.yaml
+7
.prettierrc
··· 1 + { 2 + "semi": true, 3 + "trailingComma": "es5", 4 + "singleQuote": true, 5 + "printWidth": 80, 6 + "tabWidth": 2 7 + }
+174 -16
README.md
··· 2 2 3 3 # tab 4 4 5 - - [x] zsh test in git 5 + Shell autocompletions are largely missing in the javascript cli ecosystem. This tool is an attempt to make autocompletions come out of the box for any cli tool. 6 6 7 - ```zsh 8 - source <(pnpm tsx demo.ts complete zsh) 7 + Tools like git and their autocompletion experience inspired us to build this tool and make the same ability available for any javascript cli project. Developers love hitting the tab key, hence why they prefer tabs over spaces. 9 8 10 - vite # rest of the completions 9 + ```ts 10 + import { Completion, script } from '@bombsh/tab'; 11 11 12 - pnpm tsx demo.ts complete -- --po 12 + const name = 'my-cli'; 13 + const completion = new Completion(); 14 + 15 + completion.addCommand( 16 + 'start', 17 + 'Start the application', 18 + async (previousArgs, toComplete, endsWithSpace) => { 19 + // suggestions 20 + return [ 21 + { value: 'dev', description: 'Start in development mode' }, 22 + { value: 'prod', description: 'Start in production mode' }, 23 + ]; 24 + } 25 + ); 26 + 27 + completion.addOption( 28 + 'start', 29 + '--port', 30 + 'Specify the port number', 31 + async (previousArgs, toComplete, endsWithSpace) => { 32 + return [ 33 + { value: '3000', description: 'Development port' }, 34 + { value: '8080', description: 'Production port' }, 35 + ]; 36 + } 37 + ); 38 + 39 + // a way of getting the executable path to pass to the shell autocompletion script 40 + function quoteIfNeeded(path: string) { 41 + return path.includes(' ') ? `'${path}'` : path; 42 + } 43 + const execPath = process.execPath; 44 + const processArgs = process.argv.slice(1); 45 + const quotedExecPath = quoteIfNeeded(execPath); 46 + const quotedProcessArgs = processArgs.map(quoteIfNeeded); 47 + const quotedProcessExecArgs = process.execArgv.map(quoteIfNeeded); 48 + const x = `${quotedExecPath} ${quotedProcessExecArgs.join(' ')} ${quotedProcessArgs[0]}`; 49 + 50 + if (process.argv[2] === '--') { 51 + // autocompletion logic 52 + await completion.parse(process.argv.slice(2), 'start'); // TODO: remove "start" 53 + } else { 54 + // process.argv[2] can be "zsh", "bash", "fish", "powershell" 55 + script(process.argv[2], name, x); 56 + } 13 57 ``` 14 58 15 - - [x] tests vitest (this should mostly test the completions array, e.g. logs) 16 - - [x] powershell completions generation 17 - - [x] citty support `@bomsh/tab/citty` 18 - - [] `@bombsh/tab` 59 + Now your user can run `source <(my-cli complete zsh)` and they will get completions for the `my-cli` command using the [autocompletion server](#autocompletion-server). 19 60 20 - - [] fish 21 - - [] bash 61 + ## Adapters 62 + 63 + Since we are heavy users of tools like `cac` and `citty`, we have created adapters for both of them. Ideally, tab would be integrated internally into these tools, but for now, this is a good compromise. 64 + 65 + ### `@bombsh/tab/cac` 22 66 23 67 ```ts 24 - const completion = new Completion() 25 - completion.addCommand() 26 - completion.addOption() 68 + import cac from 'cac'; 69 + import tab from '@bombsh/tab/cac'; 70 + 71 + const cli = cac('my-cli'); 72 + 73 + cli.command('dev', 'Start dev server').option('--port <port>', 'Specify port'); 74 + 75 + const completion = tab(cli); 76 + 77 + // Get the dev command completion handler 78 + const devCommandCompletion = completion.commands.get('dev'); 79 + 80 + // Get and configure the port option completion handler 81 + const portOptionCompletion = devCommandCompletion.options.get('--port'); 82 + portOptionCompletion.handler = async ( 83 + previousArgs, 84 + toComplete, 85 + endsWithSpace 86 + ) => { 87 + return [ 88 + { value: '3000', description: 'Development port' }, 89 + { value: '8080', description: 'Production port' }, 90 + ]; 91 + }; 27 92 28 - // better name 29 - completion.parse() 93 + cli.parse(); 30 94 ``` 95 + 96 + Now autocompletion will be available for any specified command and option in your cac instance. If your user writes `my-cli dev --po`, they will get suggestions for the `--port` option. Or if they write `my-cli d` they will get suggestions for the `dev` command. 97 + 98 + Suggestions are missing in the adapters since yet cac or citty do not have a way to provide suggestions (tab just came out!), we'd have to provide them manually. Mutations do not hurt in this situation. 99 + 100 + ### `@bombsh/tab/citty` 101 + 102 + ```ts 103 + import citty, { defineCommand, createMain } from 'citty'; 104 + import tab from '@bombsh/tab/citty'; 105 + 106 + const main = defineCommand({ 107 + meta: { 108 + name: 'my-cli', 109 + description: 'My CLI tool', 110 + }, 111 + }); 112 + 113 + const devCommand = defineCommand({ 114 + meta: { 115 + name: 'dev', 116 + description: 'Start dev server', 117 + }, 118 + args: { 119 + port: { type: 'string', description: 'Specify port' }, 120 + }, 121 + }); 122 + 123 + main.subCommands = { 124 + dev: devCommand, 125 + }; 126 + 127 + const completion = await tab(main); 128 + 129 + // TODO: addHandler function to export 130 + const devCommandCompletion = completion.commands.get('dev'); 131 + 132 + const portOptionCompletion = devCommandCompletion.options.get('--port'); 133 + 134 + portOptionCompletion.handler = async ( 135 + previousArgs, 136 + toComplete, 137 + endsWithSpace 138 + ) => { 139 + return [ 140 + { value: '3000', description: 'Development port' }, 141 + { value: '8080', description: 'Production port' }, 142 + ]; 143 + }; 144 + 145 + const cli = createMain(main); 146 + cli(); 147 + ``` 148 + 149 + ## Recipe 150 + 151 + `source <(my-cli complete zsh)` won't be enough since the user would have to run this command each time they spin up a new shell instance. 152 + 153 + We suggest this approach for the end user that you as a maintainer might want to push. 154 + 155 + ``` 156 + my-cli completion zsh > ~/completion-for-my-cli.zsh 157 + echo 'source ~/completion-for-my-cli.zsh' >> ~/.zshrc 158 + ``` 159 + 160 + ## Autocompletion Server 161 + 162 + By integrating tab into your cli, your cli would have a new command called `complete`. This is where all the magic happens. And the shell would contact this command to get completions. That's why we call it the autocompletion server. 163 + 164 + ```zsh 165 + my-cli complete -- --po 166 + --port Specify the port number 167 + :0 168 + ``` 169 + 170 + The autocompletion server can be a standard to identify whether a package provides autocompletions. Whether running `tool complete --` would result in an output that ends with `:{Number}` (matching the pattern `/:\d+$/`). 171 + 172 + In situations like `my-cli dev --po` you'd have autocompletions! But in the case of `pnpm my-cli dev --po` which is what most of us use, tab does not inject autocompletions for a tool like pnpm. 173 + 174 + Since pnpm already has its own autocompletion [script](https://pnpm.io/completion), this provides the opportunity to check whether a package provides autocompletions and use those autocompletions if available. 175 + 176 + This would also have users avoid injecting autocompletions in their shell config for any tool that provides its own autocompletion script, since pnpm would already support proxying the autocompletions out of the box. 177 + 178 + Other package managers like `npm` and `yarn` can decide whether to support this or not too for more universal support. 179 + 180 + ## Inspiration 181 + 182 + - git 183 + - [cobra](https://github.com/spf13/cobra/blob/main/shell_completions.go), without cobra, tab would have took 10x longer to build 184 + 185 + ## TODO 186 + 187 + - [] fish 188 + - [] bash
-2
bash.ts
··· 1 - export function generate(name: string, exec: string) { 2 - }
-304
cac.ts
··· 1 - // @bombsh/tab/cac 2 - import { CAC } from "cac"; 3 - import * as zsh from "./zsh"; 4 - import * as bash from "./bash"; 5 - import * as fish from "./fish"; 6 - import * as powershell from "./powershell"; 7 - import { 8 - flagMap, 9 - Positional, 10 - positionalMap, 11 - ShellCompDirective, 12 - } from "./shared"; 13 - 14 - function quoteIfNeeded(path: string): string { 15 - return path.includes(" ") ? `'${path}'` : path; 16 - } 17 - 18 - const execPath = process.execPath; 19 - const processArgs = process.argv.slice(1); 20 - 21 - // Apply the quoting function to each part of x 22 - // This ensures that paths like "Program Files" are quoted for PowerShell execution. 23 - const quotedExecPath = quoteIfNeeded(execPath); 24 - const quotedProcessArgs = processArgs.map(quoteIfNeeded); 25 - const quotedProcessExecArgs = process.execArgv.map(quoteIfNeeded); 26 - 27 - const x = `${quotedExecPath} ${quotedProcessExecArgs.join(" ")} ${ 28 - quotedProcessArgs[0] 29 - }`; 30 - 31 - export default function tab(instance: CAC): void { 32 - instance.command("complete [shell]").action(async (shell, extra) => { 33 - switch (shell) { 34 - case "zsh": { 35 - const script = zsh.generate(instance.name, x); 36 - console.log(script); 37 - break; 38 - } 39 - case "bash": { 40 - const script = bash.generate(instance.name, x); 41 - console.log(script); 42 - break; 43 - } 44 - case "fish": { 45 - const script = fish.generate(instance.name, x); 46 - console.log(script); 47 - break; 48 - } 49 - case "powershell": { 50 - const script = powershell.generate(instance.name, x); 51 - console.log(script); 52 - break; 53 - } 54 - default: { 55 - const args: string[] = extra["--"]; 56 - 57 - instance.showHelpOnExit = false; 58 - let directive = ShellCompDirective.ShellCompDirectiveDefault; 59 - 60 - const endsWithSpace = args[args.length - 1] === ""; 61 - if (endsWithSpace) { 62 - args.pop(); 63 - } 64 - 65 - let toComplete = args[args.length - 1] || ""; 66 - const previousArgs = args.slice(0, -1); 67 - 68 - const completions: string[] = []; 69 - 70 - instance.unsetMatchedCommand(); 71 - instance.parse([execPath, processArgs[0], ...previousArgs], { 72 - run: false, 73 - }); 74 - 75 - const command = instance.matchedCommand ?? instance.globalCommand; 76 - 77 - const options = [ 78 - ...new Set([ 79 - ...(command?.options ?? []), 80 - ...instance.globalCommand.options, 81 - ]), 82 - ]; 83 - 84 - let isCompletingFlagValue = false; 85 - let flagName = ""; 86 - let option: (typeof options)[number] | null = null; 87 - const lastArg = previousArgs[previousArgs.length - 1]; 88 - 89 - function processOption() { 90 - const matchedOption = options.find((o) => 91 - o.names.some((name) => name === flagName) 92 - ); 93 - 94 - if (matchedOption && !matchedOption.isBoolean) { 95 - isCompletingFlagValue = true; 96 - option = matchedOption; 97 - if (endsWithSpace) { 98 - toComplete = ""; 99 - } 100 - } else { 101 - isCompletingFlagValue = false; 102 - option = null; 103 - } 104 - } 105 - 106 - if (toComplete.startsWith("--")) { 107 - // Long option 108 - flagName = toComplete.slice(2); 109 - const equalsIndex = flagName.indexOf("="); 110 - if (equalsIndex !== -1 && !endsWithSpace) { 111 - // Option with '=', get the name before '=' 112 - flagName = flagName.slice(0, equalsIndex); 113 - toComplete = toComplete.slice(toComplete.indexOf("=") + 1); 114 - processOption(); 115 - } else if (!endsWithSpace) { 116 - // If not ending with space, still typing option name 117 - flagName = ""; 118 - } else { 119 - // User pressed space after typing the option name 120 - processOption(); 121 - toComplete = ""; 122 - } 123 - } else if (toComplete.startsWith("-") && toComplete.length > 1) { 124 - // Short option 125 - flagName = toComplete.slice(1); 126 - if (!endsWithSpace) { 127 - // Still typing option name 128 - flagName = ""; 129 - } else { 130 - processOption(); 131 - toComplete = ""; 132 - } 133 - } else if (lastArg?.startsWith("--") && !endsWithSpace) { 134 - flagName = lastArg.slice(2); 135 - processOption(); 136 - } else if ( 137 - lastArg?.startsWith("-") && 138 - lastArg.length > 1 && 139 - !endsWithSpace 140 - ) { 141 - flagName = lastArg.slice(2); 142 - processOption(); 143 - } 144 - 145 - if (isCompletingFlagValue) { 146 - const flagCompletionFn = flagMap.get( 147 - `${command.name} ${option?.name}` 148 - ); 149 - 150 - if (flagCompletionFn) { 151 - // Call custom completion function for the flag 152 - const comps = await flagCompletionFn(previousArgs, toComplete); 153 - completions.push( 154 - ...comps.map( 155 - (comp) => `${comp.action}\t${comp.description ?? ""}` 156 - ) 157 - ); 158 - directive = ShellCompDirective.ShellCompDirectiveNoFileComp; 159 - } else { 160 - // Default completion (e.g., file completion) 161 - directive = ShellCompDirective.ShellCompDirectiveDefault; 162 - } 163 - } else if (toComplete.startsWith("-") && !endsWithSpace) { 164 - const flag = toComplete.replace(/^-+/, ""); // Remove leading '-' 165 - 166 - // Determine options to suggest 167 - let optionsToSuggest = options.filter((o) => { 168 - const equalToDefault = 169 - "default" in o.config && 170 - instance.options[o.name] === o.config.default; 171 - return ( 172 - o.names.some((name) => name.startsWith(flag)) && 173 - !(instance.options[o.name] && !equalToDefault) 174 - ); 175 - }); 176 - 177 - const requiredOptions = optionsToSuggest.filter((o) => o.required); 178 - 179 - if (requiredOptions.length) { 180 - // Required options not yet specified 181 - optionsToSuggest = requiredOptions; 182 - } 183 - 184 - if (optionsToSuggest.length > 0) { 185 - completions.push( 186 - ...optionsToSuggest.map( 187 - (o) => `--${o.name}\t${o.description ?? ""}` 188 - ) 189 - ); 190 - } 191 - 192 - directive = ShellCompDirective.ShellCompDirectiveNoFileComp; 193 - } else { 194 - instance.parse( 195 - [execPath, processArgs[0], ...previousArgs, toComplete], 196 - { 197 - run: false, 198 - } 199 - ); 200 - const fullCommandName = args 201 - .filter((arg) => !arg.startsWith("-")) 202 - .join(" "); 203 - 204 - for (const c of instance.commands) { 205 - if (c.name === "complete") { 206 - // avoid showing completions for the completion server 207 - continue; 208 - } 209 - const fullCommandParts = fullCommandName.split(" "); 210 - const commandParts: { type: "command"; value: string }[] = c.name 211 - .split(" ") 212 - .map((part) => ({ type: "command", value: part })); 213 - const args: { 214 - type: "positional"; 215 - position: number; 216 - value: Positional; 217 - }[] = 218 - positionalMap.get(c.name)?.map((arg, i) => ({ 219 - type: "positional", 220 - position: i, 221 - value: arg, 222 - })) ?? []; 223 - const parts = [...commandParts, ...args]; 224 - 225 - for (let i = 0; i < parts.length; i++) { 226 - const fullCommandPart = fullCommandParts[i]; 227 - const part = parts[i]; 228 - 229 - if (part.type === "command") { 230 - // Command part matching 231 - if (part.value === fullCommandPart) { 232 - // Command part matches user input, continue to next part 233 - continue; 234 - } else if ( 235 - !fullCommandPart || 236 - part.value.startsWith(fullCommandPart) 237 - ) { 238 - // User is typing this command part, provide completion 239 - completions.push(`${part.value}\t${c.description ?? ""}`); 240 - } 241 - // Command part does not match, break 242 - break; 243 - } else if (part.type === "positional") { 244 - const positional = part.value; 245 - // Positional argument handling 246 - if (part.value.variadic) { 247 - const comps = await positional.completion( 248 - previousArgs, 249 - toComplete 250 - ); 251 - completions.push( 252 - ...comps.map( 253 - (comp) => `${comp.action}\t${comp.description ?? ""}` 254 - ) 255 - ); 256 - break; 257 - } 258 - if (typeof fullCommandPart !== "undefined") { 259 - // User has provided input for this positional argument 260 - if (i === fullCommandParts.length - 1 && !endsWithSpace) { 261 - // User is still typing this positional argument, provide completions 262 - const comps = await positional.completion( 263 - previousArgs, 264 - toComplete 265 - ); 266 - completions.push( 267 - ...comps.map( 268 - (comp) => `${comp.action}\t${comp.description ?? ""}` 269 - ) 270 - ); 271 - break; 272 - } else { 273 - // Positional argument is already provided, move to next 274 - previousArgs.push(fullCommandPart); 275 - continue; 276 - } 277 - } else { 278 - // User has not provided input for this positional argument 279 - const comps = await positional.completion( 280 - previousArgs, 281 - toComplete 282 - ); 283 - completions.push( 284 - ...comps.map( 285 - (comp) => `${comp.action}\t${comp.description ?? ""}` 286 - ) 287 - ); 288 - break; 289 - } 290 - } 291 - } 292 - } 293 - } 294 - 295 - // Output completions 296 - for (const comp of completions) { 297 - console.log(comp.split("\n")[0].trim()); 298 - } 299 - console.log(`:${directive}`); 300 - console.error(`Completion ended with directive: ${directive}`); 301 - } 302 - } 303 - }); 304 - }
-172
citty.ts
··· 1 - import { defineCommand } from "citty"; 2 - import * as zsh from "./zsh"; 3 - import * as bash from "./bash"; 4 - import * as fish from "./fish"; 5 - import * as powershell from "./powershell"; 6 - import { 7 - flagMap, 8 - Positional, 9 - positionalMap, 10 - ShellCompDirective, 11 - } from "./shared"; 12 - 13 - function quoteIfNeeded(path) { 14 - return path.includes(" ") ? `'${path}'` : path; 15 - } 16 - 17 - const execPath = process.execPath; 18 - const processArgs = process.argv.slice(1); 19 - const quotedExecPath = quoteIfNeeded(execPath); 20 - const quotedProcessArgs = processArgs.map(quoteIfNeeded); 21 - const quotedProcessExecArgs = process.execArgv.map(quoteIfNeeded); 22 - const x = `${quotedExecPath} ${quotedProcessExecArgs.join(" ")} ${quotedProcessArgs[0]}`; 23 - 24 - export default function tab(mainCommand) { 25 - mainCommand.subCommands["complete"] = defineCommand({ 26 - meta: { 27 - name: "complete", 28 - description: "Generate shell completion scripts", 29 - }, 30 - args: { 31 - shell: { 32 - type: "positional", 33 - required: false, 34 - description: "Specify shell type", 35 - }, 36 - }, 37 - async run(ctx) { 38 - let shell: string | undefined = ctx.args.shell; 39 - if (shell?.startsWith("--")) { 40 - shell = undefined; 41 - } 42 - 43 - const extra = ctx.args._ || []; 44 - 45 - switch (shell) { 46 - case "zsh": { 47 - const script = zsh.generate(mainCommand.meta.name, x); 48 - console.log(script); 49 - break; 50 - } 51 - case "bash": { 52 - const script = bash.generate(mainCommand.meta.name, x); 53 - console.log(script); 54 - break; 55 - } 56 - case "fish": { 57 - const script = fish.generate(mainCommand.meta.name, x); 58 - console.log(script); 59 - break; 60 - } 61 - case "powershell": { 62 - const script = powershell.generate(mainCommand.meta.name, x); 63 - console.log(script); 64 - break; 65 - } 66 - default: { 67 - const args = extra; 68 - let directive = ShellCompDirective.ShellCompDirectiveDefault; 69 - const completions: string[] = []; 70 - const endsWithSpace = args[args.length - 1] === ""; 71 - 72 - if (endsWithSpace) args.pop(); 73 - let toComplete = args[args.length - 1] || ""; 74 - const previousArgs = args.slice(0, -1); 75 - 76 - let matchedCommand = mainCommand; 77 - 78 - if (previousArgs.length > 0) { 79 - const lastPrevArg = previousArgs[previousArgs.length - 1]; 80 - if (lastPrevArg.startsWith("--")) { 81 - const flagCompletion = flagMap.get(lastPrevArg); 82 - if (flagCompletion) { 83 - const flagSuggestions = await flagCompletion(previousArgs, toComplete); 84 - completions.push( 85 - ...flagSuggestions.map( 86 - (comp) => `${comp.action}\t${comp.description ?? ""}` 87 - ) 88 - ); 89 - completions.forEach((comp) => console.log(comp)); 90 - console.log(`:${directive}`); 91 - return; 92 - } 93 - } 94 - } 95 - 96 - if (toComplete.startsWith("--")) { 97 - if (toComplete === "--") { 98 - const allFlags = [...flagMap.keys()]; 99 - const specifiedFlags = previousArgs.filter(arg => arg.startsWith('--')); 100 - const availableFlags = allFlags.filter(flag => !specifiedFlags.includes(flag)); 101 - 102 - completions.push( 103 - ...availableFlags.map( 104 - (flag) => 105 - `${flag}\t${matchedCommand.args[flag.slice(2)]?.description ?? "Option"}` 106 - ) 107 - ); 108 - } else { 109 - const flagNamePartial = toComplete.slice(2); 110 - const flagKeyPartial = `--${flagNamePartial}`; 111 - 112 - if (flagMap.has(toComplete)) { 113 - const flagCompletion = flagMap.get(toComplete); 114 - if (flagCompletion) { 115 - const flagSuggestions = await flagCompletion(previousArgs, ""); 116 - completions.push( 117 - ...flagSuggestions.map( 118 - (comp) => `${comp.action}\t${comp.description ?? ""}` 119 - ) 120 - ); 121 - } 122 - } else { 123 - const matchingFlags = [...flagMap.keys()].filter((flag) => 124 - flag.startsWith(flagKeyPartial) 125 - ); 126 - 127 - completions.push( 128 - ...matchingFlags.map( 129 - (flag) => 130 - `${flag}\t${matchedCommand.args[flag.slice(2)]?.description ?? "Option"}` 131 - ) 132 - ); 133 - } 134 - } 135 - 136 - completions.forEach((comp) => console.log(comp)); 137 - console.log(`:${directive}`); 138 - return; 139 - } 140 - 141 - if (previousArgs.length === 0) { 142 - completions.push( 143 - ...Object.keys(mainCommand.subCommands || {}) 144 - .filter((cmd) => cmd !== "complete") 145 - .map( 146 - (cmd) => 147 - `${cmd}\t${mainCommand.subCommands[cmd]?.meta.description ?? ""}` 148 - ) 149 - ); 150 - } else { 151 - const positionalCompletions = 152 - positionalMap.get(matchedCommand.meta.name) || []; 153 - for (const positional of positionalCompletions) { 154 - const suggestions = await positional.completion( 155 - previousArgs, 156 - toComplete 157 - ); 158 - completions.push( 159 - ...suggestions.map( 160 - (comp) => `${comp.action}\t${comp.description ?? ""}` 161 - ) 162 - ); 163 - } 164 - } 165 - 166 - completions.forEach((comp) => console.log(comp)); 167 - console.log(`:${directive}`); 168 - } 169 - } 170 - }, 171 - }); 172 - }
+61 -121
demo.cac.ts
··· 1 - import fs from "fs/promises"; 2 1 import cac from "cac"; 3 - import { 4 - Callback, 5 - Completion, 6 - flagMap, 7 - Positional, 8 - positionalMap, 9 - } from "./shared"; 10 - import path from "path"; 11 - import tab from "./cac"; 2 + import tab from "./src/cac"; 12 3 13 - const cli = cac("vite"); // Using 'vite' as the CLI tool name 4 + const cli = cac("vite"); 14 5 15 - // Custom converters (placeholders) 16 - function convertBase(value) { 17 - return value; 18 - } 6 + cli 7 + .option("-c, --config <file>", `Use specified config file`) 8 + .option("-m, --mode <mode>", `Set env mode`) 9 + .option("-l, --logLevel <level>", `info | warn | error | silent`); 19 10 20 - function convertHost(value) { 21 - return value; 22 - } 11 + cli 12 + .command("dev", "Start dev server") 13 + .option("--host [host]", `Specify hostname`) 14 + .option("--port <port>", `Specify port`) 15 + .action((options) => {}); 23 16 24 - // https://github.com/vitejs/vite/blob/main/packages/vite/src/node/cli.ts 25 - // Global options 26 17 cli 27 - .option("-c, --config <file>", `[string] use specified config file`) 28 - .option("--base <path>", `[string] public base path (default: /)`, { 29 - type: [convertBase], 30 - }) 31 - .option("-l, --logLevel <level>", `[string] info | warn | error | silent`) 32 - .option("--clearScreen", `[boolean] allow/disable clear screen when logging`) 33 - .option("-d, --debug [feat]", `[string | boolean] show debug logs`) 34 - .option("-f, --filter <filter>", `[string] filter debug logs`) 35 - .option("-m, --mode <mode>", `[string] set env mode`); 18 + .command("dev build", "Build project") 19 + .action((options) => {}); 36 20 37 - // Dev command 38 21 cli 39 - .command("[root]", "start dev server") // default command 40 - .alias("serve") // the command is called 'serve' in Vite's API 41 - .alias("dev") // alias to align with the script name 42 - .option("--host [host]", `[string] specify hostname`, { type: [convertHost] }) 43 - .option("--port <port>", `[number] specify port`) 44 - .option("--open [path]", `[boolean | string] open browser on startup`) 45 - .option("--cors", `[boolean] enable CORS`) 46 - .option("--strictPort", `[boolean] exit if specified port is already in use`) 47 - .option( 48 - "--force", 49 - `[boolean] force the optimizer to ignore the cache and re-bundle` 50 - ) 51 - .action((root, options) => { 52 - console.log(`Starting dev server at ${root || "."} with options:`, options); 53 - }); 54 - // Build positional completions for each command using command.args 55 - for (const c of [cli.globalCommand, ...cli.commands]) { 56 - // Handle options 57 - for (const o of [...cli.globalCommand.options, ...c.options]) { 58 - const optionKey = `${c.name} ${o.name}`; 22 + .command("lint [...files]", "Lint project") 23 + .action((files, options) => {}); 24 + 25 + const completion = await tab(cli); 26 + 27 + for (const command of completion.commands.values()) { 28 + if (command.name === 'lint') { 29 + command.handler = () => { 30 + return [ 31 + { value: 'main.ts', description: 'Main file' }, 32 + { value: 'index.ts', description: 'Index file' }, 33 + ]; 34 + }; 35 + } 59 36 60 - if (o.rawName.includes("--logLevel <level>")) { 61 - // Completion for --logLevel 62 - flagMap.set(optionKey, async (previousArgs, toComplete) => { 37 + for (const [o, config] of command.options.entries()) { 38 + if (o === '--port') { 39 + config.handler = () => { 63 40 return [ 64 - { action: "info", description: "Info level logging" }, 65 - { action: "warn", description: "Warning level logging" }, 66 - { action: "error", description: "Error level logging" }, 67 - { action: "silent", description: "No logging" }, 68 - ].filter((comp) => comp.action.startsWith(toComplete)); 69 - }); 41 + { value: '3000', description: 'Development server port' }, 42 + { value: '8080', description: 'Alternative port' }, 43 + ]; 44 + }; 70 45 } 71 - 72 - if (o.rawName.includes("--mode <mode>")) { 73 - // Completion for --mode 74 - flagMap.set(optionKey, async (previousArgs, toComplete) => { 46 + if (o === '--host') { 47 + config.handler = () => { 75 48 return [ 76 - { action: "production", description: "Production mode" }, 77 - { action: "development", description: "Development mode" }, 78 - { action: "staging", description: "Staging mode" }, 79 - ].filter((comp) => comp.action.startsWith(toComplete)); 80 - }); 49 + { value: 'localhost', description: 'Localhost' }, 50 + { value: '0.0.0.0', description: 'All interfaces' }, 51 + ]; 52 + }; 81 53 } 82 - 83 - if (o.rawName.includes("--port <port>")) { 84 - // Completion for --port 85 - flagMap.set(optionKey, async (previousArgs, toComplete) => { 54 + if (o === '--config') { 55 + config.handler = () => { 86 56 return [ 87 - { action: "3000", description: "Development server port" }, 88 - { action: "8080", description: "Alternative port" }, 89 - { action: "80", description: "HTTP port" }, 90 - { action: "443", description: "HTTPS port" }, 91 - { action: "5000", description: "Common backend port" }, 92 - ].filter((comp) => comp.action.startsWith(toComplete)); 93 - }); 57 + { value: 'vite.config.ts', description: 'Vite config file' }, 58 + { value: 'vite.config.js', description: 'Vite config file' }, 59 + ]; 60 + }; 94 61 } 95 - 96 - if (o.rawName.includes("--host [host]")) { 97 - // Completion for --host 98 - flagMap.set(optionKey, async (previousArgs, toComplete) => { 62 + if (o === '--mode') { 63 + config.handler = () => { 99 64 return [ 100 - { action: "localhost", description: "Localhost" }, 101 - { action: "0.0.0.0", description: "All interfaces" }, 102 - { action: "127.0.0.1", description: "Loopback interface" }, 103 - ].filter((comp) => comp.action.startsWith(toComplete)); 104 - }); 65 + { value: 'development', description: 'Development mode' }, 66 + { value: 'production', description: 'Production mode' }, 67 + ]; 68 + }; 105 69 } 106 - 107 - if (o.rawName.includes("--config <file>")) { 108 - // Completion for --config 109 - flagMap.set(optionKey, async (previousArgs, toComplete) => { 110 - const configFiles = ["vite.config.ts", "vite.config.js"].filter( 111 - (file) => file.startsWith(toComplete) 112 - ); 113 - return configFiles.map((file) => ({ action: file })); 114 - }); 70 + if (o === '--logLevel') { 71 + config.handler = () => { 72 + return [ 73 + { value: 'info', description: 'Info level' }, 74 + { value: 'warn', description: 'Warn level' }, 75 + { value: 'error', description: 'Error level' }, 76 + { value: 'silent', description: 'Silent level' }, 77 + ]; 78 + }; 115 79 } 116 - 117 - // Add more option completions as needed 118 - } 119 - 120 - // Handle positional arguments 121 - if (c.args && c.args.length > 0) { 122 - const positionals = c.args.map((arg) => ({ 123 - required: arg.required, 124 - variadic: arg.variadic, 125 - value: arg.value, 126 - completion: async (previousArgs, toComplete) => { 127 - if (arg.value === "root") { 128 - return [ 129 - { action: "src/", description: "💣️.sh loves vite!" }, 130 - { action: "./", description: "This one is better." }, 131 - ]; 132 - } 133 - return []; 134 - }, 135 - })); 136 - 137 - positionalMap.set(c.name, positionals); 138 80 } 139 81 } 140 - 141 - tab(cli); 142 82 143 83 cli.parse();
+126 -132
demo.citty.ts
··· 1 - import { defineCommand, createMain } from "citty"; 2 - import tab from "./citty"; 3 - import { flagMap, positionalMap } from "./shared"; 4 - 5 - const main = defineCommand({ 6 - meta: { 7 - name: "vite", 8 - description: "Vite CLI tool", 9 - }, 10 - args: { 11 - config: { type: "string", description: "Use specified config file", alias: "c" }, 12 - base: { type: "string", description: "Public base path (default: /)" }, 13 - logLevel: { type: "string", description: "info | warn | error | silent", alias: "l" }, 14 - clearScreen: { type: "boolean", description: "Allow/disable clear screen when logging" }, 15 - debug: { type: "string", description: "Show debug logs", alias: "d" }, 16 - filter: { type: "string", description: "Filter debug logs", alias: "f" }, 17 - mode: { type: "string", description: "Set env mode", alias: "m" }, 18 - }, 19 - run(ctx) { 20 - const firstArg = ctx.args._?.[0]; 21 - if (firstArg && devCommand?.run) { 22 - devCommand.run({ ...ctx, args: { ...ctx.args, root: firstArg } }); 23 - } 24 - }, 25 - }); 26 - 27 - const devCommand = defineCommand({ 28 - meta: { 29 - name: "dev", 30 - description: "Start dev server", 31 - }, 32 - args: { 33 - root: { type: "positional", description: "Root directory", default: "." }, 34 - host: { type: "string", description: "Specify hostname" }, 35 - port: { type: "string", description: "Specify port" }, 36 - open: { type: "boolean", description: "Open browser on startup" }, 37 - cors: { type: "boolean", description: "Enable CORS" }, 38 - strictPort: { type: "boolean", description: "Exit if specified port is already in use" }, 39 - force: { type: "boolean", description: "Force the optimizer to ignore the cache and re-bundle" }, 40 - }, 41 - run({ args }) { 42 - const { root, port, ...options } = args; 43 - const parsedPort = port ? parseInt(port, 10) : undefined; 44 - 45 - if (!root || root === ".") { 46 - console.log("Suggested root directories:"); 47 - console.log("- src/"); 48 - console.log("- ./"); 49 - } 50 - }, 51 - }); 52 - 53 - main.subCommands = { dev: devCommand }; 54 - 55 - for (const command of [main, ...Object.values(main.subCommands)]) { 56 - const commandName = command.meta.name; 57 - 58 - for (const [argName, argConfig] of Object.entries(command.args || {})) { 59 - const optionKey = `--${argName}`; 60 - 61 - if (argName === "port") { 62 - flagMap.set(optionKey, async (_, toComplete) => { 63 - const options = [ 64 - { action: "3000", description: "Development server port" }, 65 - { action: "8080", description: "Alternative port" }, 66 - ]; 67 - return toComplete 68 - ? options.filter(comp => comp.action.startsWith(toComplete)) 69 - : options; 70 - }); 71 - } else if (argName === "host") { 72 - flagMap.set(optionKey, async (_, toComplete) => { 73 - const options = [ 74 - { action: "localhost", description: "Localhost" }, 75 - { action: "0.0.0.0", description: "All interfaces" }, 76 - ]; 77 - return toComplete 78 - ? options.filter(comp => comp.action.startsWith(toComplete)) 79 - : options; 80 - }); 81 - } else if (argName === "config") { 82 - flagMap.set(optionKey, async (_, toComplete) => { 83 - const configFiles = ["vite.config.ts", "vite.config.js"].filter( 84 - (file) => file.startsWith(toComplete) 85 - ); 86 - return configFiles.map((file) => ({ action: file })); 87 - }); 88 - } else if (argName === "mode") { 89 - flagMap.set(optionKey, async (_, toComplete) => { 90 - const options = [ 91 - { action: "development", description: "Development mode" }, 92 - { action: "production", description: "Production mode" }, 93 - ]; 94 - return toComplete 95 - ? options.filter(comp => comp.action.startsWith(toComplete)) 96 - : options; 97 - }); 98 - } else { 99 - flagMap.set(optionKey, async (_, toComplete) => { 100 - const flag = optionKey.startsWith("--") ? optionKey.slice(2) : optionKey; 101 - if (!toComplete || optionKey.startsWith(toComplete)) { 102 - return [{ action: optionKey, description: argConfig.description }]; 103 - } 104 - return []; 105 - }); 106 - } 107 - } 108 - 109 - if (command.args) { 110 - const positionals = Object.entries(command.args) 111 - .filter(([, config]) => config.type === "positional") 112 - .map(([argName, argConfig]) => ({ 113 - value: argName, 114 - required: !!argConfig.required, 115 - completion: async (_, toComplete) => { 116 - const options = [ 117 - { action: "src/", description: "Source directory" }, 118 - { action: "./", description: "Current directory" }, 119 - ]; 120 - return toComplete 121 - ? options.filter(comp => comp.action.startsWith(toComplete)) 122 - : options; 123 - }, 124 - })); 125 - positionalMap.set(commandName, positionals); 126 - } 127 - } 128 - 129 - tab(main); 130 - 131 - const cli = createMain(main); 132 - cli(); 1 + import { defineCommand, createMain, CommandDef } from 'citty'; 2 + import tab from './src/citty'; 3 + 4 + const main = defineCommand({ 5 + meta: { 6 + name: 'vite', 7 + description: 'Vite CLI tool', 8 + }, 9 + args: { 10 + config: { 11 + type: 'string', 12 + description: 'Use specified config file', 13 + alias: 'c', 14 + }, 15 + mode: { type: 'string', description: 'Set env mode', alias: 'm' }, 16 + logLevel: { 17 + type: 'string', 18 + description: 'info | warn | error | silent', 19 + alias: 'l', 20 + }, 21 + }, 22 + run(_ctx) {}, 23 + }); 24 + 25 + const devCommand = defineCommand({ 26 + meta: { 27 + name: 'dev', 28 + description: 'Start dev server', 29 + }, 30 + args: { 31 + host: { type: 'string', description: 'Specify hostname' }, 32 + port: { type: 'string', description: 'Specify port' }, 33 + }, 34 + run(ctx) { 35 + }, 36 + }); 37 + 38 + devCommand.subCommands = { 39 + build: defineCommand({ 40 + meta: { 41 + name: 'build', 42 + description: 'Build project', 43 + }, 44 + run({ args }) {}, 45 + }), 46 + }; 47 + 48 + const lintCommand = defineCommand({ 49 + meta: { 50 + name: 'lint', 51 + description: 'Lint project', 52 + }, 53 + args: { 54 + files: { type: 'positional', description: 'Files to lint' }, 55 + }, 56 + run(ctx) { 57 + }, 58 + }); 59 + 60 + main.subCommands = { 61 + dev: devCommand, 62 + lint: lintCommand, 63 + } as Record<string, CommandDef<any>>; 64 + 65 + const completion = await tab(main); 66 + 67 + for (const command of completion.commands.values()) { 68 + 69 + if (command.name === 'lint') { 70 + command.handler = () => { 71 + return [ 72 + { value: 'main.ts', description: 'Main file' }, 73 + { value: 'index.ts', description: 'Index file' }, 74 + ]; 75 + }; 76 + } 77 + 78 + for (const [o, config] of command.options.entries()) { 79 + if (o === '--port') { 80 + config.handler = () => { 81 + return [ 82 + { value: '3000', description: 'Development server port' }, 83 + { value: '8080', description: 'Alternative port' }, 84 + ]; 85 + }; 86 + } 87 + if (o === '--host') { 88 + config.handler = () => { 89 + return [ 90 + { value: 'localhost', description: 'Localhost' }, 91 + { value: '0.0.0.0', description: 'All interfaces' }, 92 + ]; 93 + }; 94 + } 95 + if (o === '--config') { 96 + config.handler = () => { 97 + return [ 98 + { value: 'vite.config.ts', description: 'Vite config file' }, 99 + { value: 'vite.config.js', description: 'Vite config file' }, 100 + ]; 101 + }; 102 + } 103 + if (o === '--mode') { 104 + config.handler = () => { 105 + return [ 106 + { value: 'development', description: 'Development mode' }, 107 + { value: 'production', description: 'Production mode' }, 108 + ]; 109 + }; 110 + } 111 + if (o === '--logLevel') { 112 + config.handler = () => { 113 + return [ 114 + { value: 'info', description: 'Info level' }, 115 + { value: 'warn', description: 'Warn level' }, 116 + { value: 'error', description: 'Error level' }, 117 + { value: 'silent', description: 'Silent level' }, 118 + ]; 119 + }; 120 + } 121 + } 122 + } 123 + 124 + const cli = createMain(main); 125 + 126 + cli();
-2
fish.ts
··· 1 - export function generate(name: string, exec: string) { 2 - }
+11 -2
package.json
··· 5 5 "main": "index.js", 6 6 "type": "module", 7 7 "scripts": { 8 - "test": "vitest" 8 + "test": "vitest", 9 + "type-check": "tsc --noEmit", 10 + "format": "prettier --write .", 11 + "format:check": "prettier --check ." 9 12 }, 10 13 "keywords": [], 11 14 "author": "", 12 15 "license": "ISC", 13 16 "devDependencies": { 14 17 "@types/node": "^22.7.4", 18 + "@typescript-eslint/eslint-plugin": "^8.20.0", 19 + "@typescript-eslint/parser": "^8.20.0", 15 20 "cac": "^6.7.14", 16 21 "citty": "^0.1.6", 22 + "eslint-config-prettier": "^10.0.1", 23 + "eslint-plugin-prettier": "^5.2.2", 24 + "prettier": "^3.4.2", 17 25 "tsx": "^4.19.1", 18 26 "vitest": "^2.1.3" 19 27 }, 20 28 "dependencies": { 21 29 "mri": "^1.2.0" 22 - } 30 + }, 31 + "packageManager": "pnpm@9.15.0+sha512.76e2379760a4328ec4415815bcd6628dee727af3779aaa4c914e3944156c4299921a89f976381ee107d41f12cfa4b66681ca9c718f0668fa0831ed4c6d8ba56c" 23 32 }
+2396 -640
pnpm-lock.yaml
··· 1 - lockfileVersion: '6.0' 1 + lockfileVersion: '9.0' 2 2 3 3 settings: 4 4 autoInstallPeers: true 5 5 excludeLinksFromLockfile: false 6 6 7 - dependencies: 8 - mri: 9 - specifier: ^1.2.0 10 - version: 1.2.0 11 - 12 - devDependencies: 13 - '@types/node': 14 - specifier: ^22.7.4 15 - version: 22.7.5 16 - cac: 17 - specifier: ^6.7.14 18 - version: 6.7.14 19 - citty: 20 - specifier: ^0.1.6 21 - version: 0.1.6 22 - tsx: 23 - specifier: ^4.19.1 24 - version: 4.19.1 25 - vitest: 26 - specifier: ^2.1.3 27 - version: 2.1.3(@types/node@22.7.5) 7 + importers: 8 + .: 9 + dependencies: 10 + mri: 11 + specifier: ^1.2.0 12 + version: 1.2.0 13 + devDependencies: 14 + '@types/node': 15 + specifier: ^22.7.4 16 + version: 22.7.5 17 + '@typescript-eslint/eslint-plugin': 18 + specifier: ^8.20.0 19 + version: 8.20.0(@typescript-eslint/parser@8.20.0(eslint@9.18.0)(typescript@5.7.3))(eslint@9.18.0)(typescript@5.7.3) 20 + '@typescript-eslint/parser': 21 + specifier: ^8.20.0 22 + version: 8.20.0(eslint@9.18.0)(typescript@5.7.3) 23 + cac: 24 + specifier: ^6.7.14 25 + version: 6.7.14 26 + citty: 27 + specifier: ^0.1.6 28 + version: 0.1.6 29 + eslint-config-prettier: 30 + specifier: ^10.0.1 31 + version: 10.0.1(eslint@9.18.0) 32 + eslint-plugin-prettier: 33 + specifier: ^5.2.2 34 + version: 5.2.2(eslint-config-prettier@10.0.1(eslint@9.18.0))(eslint@9.18.0)(prettier@3.4.2) 35 + prettier: 36 + specifier: ^3.4.2 37 + version: 3.4.2 38 + tsx: 39 + specifier: ^4.19.1 40 + version: 4.19.1 41 + vitest: 42 + specifier: ^2.1.3 43 + version: 2.1.3(@types/node@22.7.5) 28 44 29 45 packages: 30 - 31 - /@esbuild/aix-ppc64@0.21.5: 32 - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} 33 - engines: {node: '>=12'} 46 + '@esbuild/aix-ppc64@0.21.5': 47 + resolution: 48 + { 49 + integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==, 50 + } 51 + engines: { node: '>=12' } 34 52 cpu: [ppc64] 35 53 os: [aix] 36 - requiresBuild: true 37 - dev: true 38 - optional: true 39 54 40 - /@esbuild/aix-ppc64@0.23.1: 41 - resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} 42 - engines: {node: '>=18'} 55 + '@esbuild/aix-ppc64@0.23.1': 56 + resolution: 57 + { 58 + integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==, 59 + } 60 + engines: { node: '>=18' } 43 61 cpu: [ppc64] 44 62 os: [aix] 45 - requiresBuild: true 46 - dev: true 47 - optional: true 48 63 49 - /@esbuild/android-arm64@0.21.5: 50 - resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} 51 - engines: {node: '>=12'} 64 + '@esbuild/android-arm64@0.21.5': 65 + resolution: 66 + { 67 + integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==, 68 + } 69 + engines: { node: '>=12' } 52 70 cpu: [arm64] 53 71 os: [android] 54 - requiresBuild: true 55 - dev: true 56 - optional: true 57 72 58 - /@esbuild/android-arm64@0.23.1: 59 - resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==} 60 - engines: {node: '>=18'} 73 + '@esbuild/android-arm64@0.23.1': 74 + resolution: 75 + { 76 + integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==, 77 + } 78 + engines: { node: '>=18' } 61 79 cpu: [arm64] 62 80 os: [android] 63 - requiresBuild: true 64 - dev: true 65 - optional: true 66 81 67 - /@esbuild/android-arm@0.21.5: 68 - resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} 69 - engines: {node: '>=12'} 82 + '@esbuild/android-arm@0.21.5': 83 + resolution: 84 + { 85 + integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==, 86 + } 87 + engines: { node: '>=12' } 70 88 cpu: [arm] 71 89 os: [android] 72 - requiresBuild: true 73 - dev: true 74 - optional: true 75 90 76 - /@esbuild/android-arm@0.23.1: 77 - resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==} 78 - engines: {node: '>=18'} 91 + '@esbuild/android-arm@0.23.1': 92 + resolution: 93 + { 94 + integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==, 95 + } 96 + engines: { node: '>=18' } 79 97 cpu: [arm] 80 98 os: [android] 81 - requiresBuild: true 82 - dev: true 83 - optional: true 84 99 85 - /@esbuild/android-x64@0.21.5: 86 - resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} 87 - engines: {node: '>=12'} 100 + '@esbuild/android-x64@0.21.5': 101 + resolution: 102 + { 103 + integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==, 104 + } 105 + engines: { node: '>=12' } 88 106 cpu: [x64] 89 107 os: [android] 90 - requiresBuild: true 91 - dev: true 92 - optional: true 93 108 94 - /@esbuild/android-x64@0.23.1: 95 - resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==} 96 - engines: {node: '>=18'} 109 + '@esbuild/android-x64@0.23.1': 110 + resolution: 111 + { 112 + integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==, 113 + } 114 + engines: { node: '>=18' } 97 115 cpu: [x64] 98 116 os: [android] 99 - requiresBuild: true 100 - dev: true 101 - optional: true 102 117 103 - /@esbuild/darwin-arm64@0.21.5: 104 - resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} 105 - engines: {node: '>=12'} 118 + '@esbuild/darwin-arm64@0.21.5': 119 + resolution: 120 + { 121 + integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==, 122 + } 123 + engines: { node: '>=12' } 106 124 cpu: [arm64] 107 125 os: [darwin] 108 - requiresBuild: true 109 - dev: true 110 - optional: true 111 126 112 - /@esbuild/darwin-arm64@0.23.1: 113 - resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==} 114 - engines: {node: '>=18'} 127 + '@esbuild/darwin-arm64@0.23.1': 128 + resolution: 129 + { 130 + integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==, 131 + } 132 + engines: { node: '>=18' } 115 133 cpu: [arm64] 116 134 os: [darwin] 117 - requiresBuild: true 118 - dev: true 119 - optional: true 120 135 121 - /@esbuild/darwin-x64@0.21.5: 122 - resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} 123 - engines: {node: '>=12'} 136 + '@esbuild/darwin-x64@0.21.5': 137 + resolution: 138 + { 139 + integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==, 140 + } 141 + engines: { node: '>=12' } 124 142 cpu: [x64] 125 143 os: [darwin] 126 - requiresBuild: true 127 - dev: true 128 - optional: true 129 144 130 - /@esbuild/darwin-x64@0.23.1: 131 - resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==} 132 - engines: {node: '>=18'} 145 + '@esbuild/darwin-x64@0.23.1': 146 + resolution: 147 + { 148 + integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==, 149 + } 150 + engines: { node: '>=18' } 133 151 cpu: [x64] 134 152 os: [darwin] 135 - requiresBuild: true 136 - dev: true 137 - optional: true 138 153 139 - /@esbuild/freebsd-arm64@0.21.5: 140 - resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} 141 - engines: {node: '>=12'} 154 + '@esbuild/freebsd-arm64@0.21.5': 155 + resolution: 156 + { 157 + integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==, 158 + } 159 + engines: { node: '>=12' } 142 160 cpu: [arm64] 143 161 os: [freebsd] 144 - requiresBuild: true 145 - dev: true 146 - optional: true 147 162 148 - /@esbuild/freebsd-arm64@0.23.1: 149 - resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==} 150 - engines: {node: '>=18'} 163 + '@esbuild/freebsd-arm64@0.23.1': 164 + resolution: 165 + { 166 + integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==, 167 + } 168 + engines: { node: '>=18' } 151 169 cpu: [arm64] 152 170 os: [freebsd] 153 - requiresBuild: true 154 - dev: true 155 - optional: true 156 171 157 - /@esbuild/freebsd-x64@0.21.5: 158 - resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} 159 - engines: {node: '>=12'} 172 + '@esbuild/freebsd-x64@0.21.5': 173 + resolution: 174 + { 175 + integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==, 176 + } 177 + engines: { node: '>=12' } 160 178 cpu: [x64] 161 179 os: [freebsd] 162 - requiresBuild: true 163 - dev: true 164 - optional: true 165 180 166 - /@esbuild/freebsd-x64@0.23.1: 167 - resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==} 168 - engines: {node: '>=18'} 181 + '@esbuild/freebsd-x64@0.23.1': 182 + resolution: 183 + { 184 + integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==, 185 + } 186 + engines: { node: '>=18' } 169 187 cpu: [x64] 170 188 os: [freebsd] 171 - requiresBuild: true 172 - dev: true 173 - optional: true 174 189 175 - /@esbuild/linux-arm64@0.21.5: 176 - resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} 177 - engines: {node: '>=12'} 190 + '@esbuild/linux-arm64@0.21.5': 191 + resolution: 192 + { 193 + integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==, 194 + } 195 + engines: { node: '>=12' } 178 196 cpu: [arm64] 179 197 os: [linux] 180 - requiresBuild: true 181 - dev: true 182 - optional: true 183 198 184 - /@esbuild/linux-arm64@0.23.1: 185 - resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==} 186 - engines: {node: '>=18'} 199 + '@esbuild/linux-arm64@0.23.1': 200 + resolution: 201 + { 202 + integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==, 203 + } 204 + engines: { node: '>=18' } 187 205 cpu: [arm64] 188 206 os: [linux] 189 - requiresBuild: true 190 - dev: true 191 - optional: true 192 207 193 - /@esbuild/linux-arm@0.21.5: 194 - resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} 195 - engines: {node: '>=12'} 208 + '@esbuild/linux-arm@0.21.5': 209 + resolution: 210 + { 211 + integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==, 212 + } 213 + engines: { node: '>=12' } 196 214 cpu: [arm] 197 215 os: [linux] 198 - requiresBuild: true 199 - dev: true 200 - optional: true 201 216 202 - /@esbuild/linux-arm@0.23.1: 203 - resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==} 204 - engines: {node: '>=18'} 217 + '@esbuild/linux-arm@0.23.1': 218 + resolution: 219 + { 220 + integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==, 221 + } 222 + engines: { node: '>=18' } 205 223 cpu: [arm] 206 224 os: [linux] 207 - requiresBuild: true 208 - dev: true 209 - optional: true 210 225 211 - /@esbuild/linux-ia32@0.21.5: 212 - resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} 213 - engines: {node: '>=12'} 226 + '@esbuild/linux-ia32@0.21.5': 227 + resolution: 228 + { 229 + integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==, 230 + } 231 + engines: { node: '>=12' } 214 232 cpu: [ia32] 215 233 os: [linux] 216 - requiresBuild: true 217 - dev: true 218 - optional: true 219 234 220 - /@esbuild/linux-ia32@0.23.1: 221 - resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==} 222 - engines: {node: '>=18'} 235 + '@esbuild/linux-ia32@0.23.1': 236 + resolution: 237 + { 238 + integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==, 239 + } 240 + engines: { node: '>=18' } 223 241 cpu: [ia32] 224 242 os: [linux] 225 - requiresBuild: true 226 - dev: true 227 - optional: true 228 243 229 - /@esbuild/linux-loong64@0.21.5: 230 - resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} 231 - engines: {node: '>=12'} 244 + '@esbuild/linux-loong64@0.21.5': 245 + resolution: 246 + { 247 + integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==, 248 + } 249 + engines: { node: '>=12' } 232 250 cpu: [loong64] 233 251 os: [linux] 234 - requiresBuild: true 235 - dev: true 236 - optional: true 237 252 238 - /@esbuild/linux-loong64@0.23.1: 239 - resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==} 240 - engines: {node: '>=18'} 253 + '@esbuild/linux-loong64@0.23.1': 254 + resolution: 255 + { 256 + integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==, 257 + } 258 + engines: { node: '>=18' } 241 259 cpu: [loong64] 242 260 os: [linux] 243 - requiresBuild: true 244 - dev: true 245 - optional: true 246 261 247 - /@esbuild/linux-mips64el@0.21.5: 248 - resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} 249 - engines: {node: '>=12'} 262 + '@esbuild/linux-mips64el@0.21.5': 263 + resolution: 264 + { 265 + integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==, 266 + } 267 + engines: { node: '>=12' } 250 268 cpu: [mips64el] 251 269 os: [linux] 252 - requiresBuild: true 253 - dev: true 254 - optional: true 255 270 256 - /@esbuild/linux-mips64el@0.23.1: 257 - resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==} 258 - engines: {node: '>=18'} 271 + '@esbuild/linux-mips64el@0.23.1': 272 + resolution: 273 + { 274 + integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==, 275 + } 276 + engines: { node: '>=18' } 259 277 cpu: [mips64el] 260 278 os: [linux] 261 - requiresBuild: true 262 - dev: true 263 - optional: true 264 279 265 - /@esbuild/linux-ppc64@0.21.5: 266 - resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} 267 - engines: {node: '>=12'} 280 + '@esbuild/linux-ppc64@0.21.5': 281 + resolution: 282 + { 283 + integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==, 284 + } 285 + engines: { node: '>=12' } 268 286 cpu: [ppc64] 269 287 os: [linux] 270 - requiresBuild: true 271 - dev: true 272 - optional: true 273 288 274 - /@esbuild/linux-ppc64@0.23.1: 275 - resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==} 276 - engines: {node: '>=18'} 289 + '@esbuild/linux-ppc64@0.23.1': 290 + resolution: 291 + { 292 + integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==, 293 + } 294 + engines: { node: '>=18' } 277 295 cpu: [ppc64] 278 296 os: [linux] 279 - requiresBuild: true 280 - dev: true 281 - optional: true 282 297 283 - /@esbuild/linux-riscv64@0.21.5: 284 - resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} 285 - engines: {node: '>=12'} 298 + '@esbuild/linux-riscv64@0.21.5': 299 + resolution: 300 + { 301 + integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==, 302 + } 303 + engines: { node: '>=12' } 286 304 cpu: [riscv64] 287 305 os: [linux] 288 - requiresBuild: true 289 - dev: true 290 - optional: true 291 306 292 - /@esbuild/linux-riscv64@0.23.1: 293 - resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==} 294 - engines: {node: '>=18'} 307 + '@esbuild/linux-riscv64@0.23.1': 308 + resolution: 309 + { 310 + integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==, 311 + } 312 + engines: { node: '>=18' } 295 313 cpu: [riscv64] 296 314 os: [linux] 297 - requiresBuild: true 298 - dev: true 299 - optional: true 300 315 301 - /@esbuild/linux-s390x@0.21.5: 302 - resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} 303 - engines: {node: '>=12'} 316 + '@esbuild/linux-s390x@0.21.5': 317 + resolution: 318 + { 319 + integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==, 320 + } 321 + engines: { node: '>=12' } 304 322 cpu: [s390x] 305 323 os: [linux] 306 - requiresBuild: true 307 - dev: true 308 - optional: true 309 324 310 - /@esbuild/linux-s390x@0.23.1: 311 - resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==} 312 - engines: {node: '>=18'} 325 + '@esbuild/linux-s390x@0.23.1': 326 + resolution: 327 + { 328 + integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==, 329 + } 330 + engines: { node: '>=18' } 313 331 cpu: [s390x] 314 332 os: [linux] 315 - requiresBuild: true 316 - dev: true 317 - optional: true 318 333 319 - /@esbuild/linux-x64@0.21.5: 320 - resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} 321 - engines: {node: '>=12'} 334 + '@esbuild/linux-x64@0.21.5': 335 + resolution: 336 + { 337 + integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==, 338 + } 339 + engines: { node: '>=12' } 322 340 cpu: [x64] 323 341 os: [linux] 324 - requiresBuild: true 325 - dev: true 326 - optional: true 327 342 328 - /@esbuild/linux-x64@0.23.1: 329 - resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==} 330 - engines: {node: '>=18'} 343 + '@esbuild/linux-x64@0.23.1': 344 + resolution: 345 + { 346 + integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==, 347 + } 348 + engines: { node: '>=18' } 331 349 cpu: [x64] 332 350 os: [linux] 333 - requiresBuild: true 334 - dev: true 335 - optional: true 336 351 337 - /@esbuild/netbsd-x64@0.21.5: 338 - resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} 339 - engines: {node: '>=12'} 352 + '@esbuild/netbsd-x64@0.21.5': 353 + resolution: 354 + { 355 + integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==, 356 + } 357 + engines: { node: '>=12' } 340 358 cpu: [x64] 341 359 os: [netbsd] 342 - requiresBuild: true 343 - dev: true 344 - optional: true 345 360 346 - /@esbuild/netbsd-x64@0.23.1: 347 - resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==} 348 - engines: {node: '>=18'} 361 + '@esbuild/netbsd-x64@0.23.1': 362 + resolution: 363 + { 364 + integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==, 365 + } 366 + engines: { node: '>=18' } 349 367 cpu: [x64] 350 368 os: [netbsd] 351 - requiresBuild: true 352 - dev: true 353 - optional: true 354 369 355 - /@esbuild/openbsd-arm64@0.23.1: 356 - resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==} 357 - engines: {node: '>=18'} 370 + '@esbuild/openbsd-arm64@0.23.1': 371 + resolution: 372 + { 373 + integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==, 374 + } 375 + engines: { node: '>=18' } 358 376 cpu: [arm64] 359 377 os: [openbsd] 360 - requiresBuild: true 361 - dev: true 362 - optional: true 363 378 364 - /@esbuild/openbsd-x64@0.21.5: 365 - resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} 366 - engines: {node: '>=12'} 379 + '@esbuild/openbsd-x64@0.21.5': 380 + resolution: 381 + { 382 + integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==, 383 + } 384 + engines: { node: '>=12' } 367 385 cpu: [x64] 368 386 os: [openbsd] 369 - requiresBuild: true 370 - dev: true 371 - optional: true 372 387 373 - /@esbuild/openbsd-x64@0.23.1: 374 - resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==} 375 - engines: {node: '>=18'} 388 + '@esbuild/openbsd-x64@0.23.1': 389 + resolution: 390 + { 391 + integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==, 392 + } 393 + engines: { node: '>=18' } 376 394 cpu: [x64] 377 395 os: [openbsd] 378 - requiresBuild: true 379 - dev: true 380 - optional: true 381 396 382 - /@esbuild/sunos-x64@0.21.5: 383 - resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} 384 - engines: {node: '>=12'} 397 + '@esbuild/sunos-x64@0.21.5': 398 + resolution: 399 + { 400 + integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==, 401 + } 402 + engines: { node: '>=12' } 385 403 cpu: [x64] 386 404 os: [sunos] 387 - requiresBuild: true 388 - dev: true 389 - optional: true 390 405 391 - /@esbuild/sunos-x64@0.23.1: 392 - resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==} 393 - engines: {node: '>=18'} 406 + '@esbuild/sunos-x64@0.23.1': 407 + resolution: 408 + { 409 + integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==, 410 + } 411 + engines: { node: '>=18' } 394 412 cpu: [x64] 395 413 os: [sunos] 396 - requiresBuild: true 397 - dev: true 398 - optional: true 399 414 400 - /@esbuild/win32-arm64@0.21.5: 401 - resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} 402 - engines: {node: '>=12'} 415 + '@esbuild/win32-arm64@0.21.5': 416 + resolution: 417 + { 418 + integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==, 419 + } 420 + engines: { node: '>=12' } 403 421 cpu: [arm64] 404 422 os: [win32] 405 - requiresBuild: true 406 - dev: true 407 - optional: true 408 423 409 - /@esbuild/win32-arm64@0.23.1: 410 - resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==} 411 - engines: {node: '>=18'} 424 + '@esbuild/win32-arm64@0.23.1': 425 + resolution: 426 + { 427 + integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==, 428 + } 429 + engines: { node: '>=18' } 412 430 cpu: [arm64] 413 431 os: [win32] 414 - requiresBuild: true 415 - dev: true 416 - optional: true 417 432 418 - /@esbuild/win32-ia32@0.21.5: 419 - resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} 420 - engines: {node: '>=12'} 433 + '@esbuild/win32-ia32@0.21.5': 434 + resolution: 435 + { 436 + integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==, 437 + } 438 + engines: { node: '>=12' } 421 439 cpu: [ia32] 422 440 os: [win32] 423 - requiresBuild: true 424 - dev: true 425 - optional: true 426 441 427 - /@esbuild/win32-ia32@0.23.1: 428 - resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==} 429 - engines: {node: '>=18'} 442 + '@esbuild/win32-ia32@0.23.1': 443 + resolution: 444 + { 445 + integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==, 446 + } 447 + engines: { node: '>=18' } 430 448 cpu: [ia32] 431 449 os: [win32] 432 - requiresBuild: true 433 - dev: true 434 - optional: true 435 450 436 - /@esbuild/win32-x64@0.21.5: 437 - resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} 438 - engines: {node: '>=12'} 451 + '@esbuild/win32-x64@0.21.5': 452 + resolution: 453 + { 454 + integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==, 455 + } 456 + engines: { node: '>=12' } 439 457 cpu: [x64] 440 458 os: [win32] 441 - requiresBuild: true 442 - dev: true 443 - optional: true 444 459 445 - /@esbuild/win32-x64@0.23.1: 446 - resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==} 447 - engines: {node: '>=18'} 460 + '@esbuild/win32-x64@0.23.1': 461 + resolution: 462 + { 463 + integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==, 464 + } 465 + engines: { node: '>=18' } 448 466 cpu: [x64] 449 467 os: [win32] 450 - requiresBuild: true 451 - dev: true 452 - optional: true 468 + 469 + '@eslint-community/eslint-utils@4.4.1': 470 + resolution: 471 + { 472 + integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==, 473 + } 474 + engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } 475 + peerDependencies: 476 + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 477 + 478 + '@eslint-community/regexpp@4.12.1': 479 + resolution: 480 + { 481 + integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==, 482 + } 483 + engines: { node: ^12.0.0 || ^14.0.0 || >=16.0.0 } 484 + 485 + '@eslint/config-array@0.19.1': 486 + resolution: 487 + { 488 + integrity: sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==, 489 + } 490 + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } 491 + 492 + '@eslint/core@0.10.0': 493 + resolution: 494 + { 495 + integrity: sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==, 496 + } 497 + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } 498 + 499 + '@eslint/eslintrc@3.2.0': 500 + resolution: 501 + { 502 + integrity: sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==, 503 + } 504 + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } 505 + 506 + '@eslint/js@9.18.0': 507 + resolution: 508 + { 509 + integrity: sha512-fK6L7rxcq6/z+AaQMtiFTkvbHkBLNlwyRxHpKawP0x3u9+NC6MQTnFW+AdpwC6gfHTW0051cokQgtTN2FqlxQA==, 510 + } 511 + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } 512 + 513 + '@eslint/object-schema@2.1.5': 514 + resolution: 515 + { 516 + integrity: sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==, 517 + } 518 + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } 519 + 520 + '@eslint/plugin-kit@0.2.5': 521 + resolution: 522 + { 523 + integrity: sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==, 524 + } 525 + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } 526 + 527 + '@humanfs/core@0.19.1': 528 + resolution: 529 + { 530 + integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==, 531 + } 532 + engines: { node: '>=18.18.0' } 533 + 534 + '@humanfs/node@0.16.6': 535 + resolution: 536 + { 537 + integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==, 538 + } 539 + engines: { node: '>=18.18.0' } 453 540 454 - /@jridgewell/sourcemap-codec@1.5.0: 455 - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} 456 - dev: true 541 + '@humanwhocodes/module-importer@1.0.1': 542 + resolution: 543 + { 544 + integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==, 545 + } 546 + engines: { node: '>=12.22' } 457 547 458 - /@rollup/rollup-android-arm-eabi@4.24.2: 459 - resolution: {integrity: sha512-ufoveNTKDg9t/b7nqI3lwbCG/9IJMhADBNjjz/Jn6LxIZxD7T5L8l2uO/wD99945F1Oo8FvgbbZJRguyk/BdzA==} 548 + '@humanwhocodes/retry@0.3.1': 549 + resolution: 550 + { 551 + integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==, 552 + } 553 + engines: { node: '>=18.18' } 554 + 555 + '@humanwhocodes/retry@0.4.1': 556 + resolution: 557 + { 558 + integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==, 559 + } 560 + engines: { node: '>=18.18' } 561 + 562 + '@jridgewell/sourcemap-codec@1.5.0': 563 + resolution: 564 + { 565 + integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==, 566 + } 567 + 568 + '@nodelib/fs.scandir@2.1.5': 569 + resolution: 570 + { 571 + integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==, 572 + } 573 + engines: { node: '>= 8' } 574 + 575 + '@nodelib/fs.stat@2.0.5': 576 + resolution: 577 + { 578 + integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==, 579 + } 580 + engines: { node: '>= 8' } 581 + 582 + '@nodelib/fs.walk@1.2.8': 583 + resolution: 584 + { 585 + integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==, 586 + } 587 + engines: { node: '>= 8' } 588 + 589 + '@pkgr/core@0.1.1': 590 + resolution: 591 + { 592 + integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==, 593 + } 594 + engines: { node: ^12.20.0 || ^14.18.0 || >=16.0.0 } 595 + 596 + '@rollup/rollup-android-arm-eabi@4.24.2': 597 + resolution: 598 + { 599 + integrity: sha512-ufoveNTKDg9t/b7nqI3lwbCG/9IJMhADBNjjz/Jn6LxIZxD7T5L8l2uO/wD99945F1Oo8FvgbbZJRguyk/BdzA==, 600 + } 460 601 cpu: [arm] 461 602 os: [android] 462 - requiresBuild: true 463 - dev: true 464 - optional: true 465 603 466 - /@rollup/rollup-android-arm64@4.24.2: 467 - resolution: {integrity: sha512-iZoYCiJz3Uek4NI0J06/ZxUgwAfNzqltK0MptPDO4OR0a88R4h0DSELMsflS6ibMCJ4PnLvq8f7O1d7WexUvIA==} 604 + '@rollup/rollup-android-arm64@4.24.2': 605 + resolution: 606 + { 607 + integrity: sha512-iZoYCiJz3Uek4NI0J06/ZxUgwAfNzqltK0MptPDO4OR0a88R4h0DSELMsflS6ibMCJ4PnLvq8f7O1d7WexUvIA==, 608 + } 468 609 cpu: [arm64] 469 610 os: [android] 470 - requiresBuild: true 471 - dev: true 472 - optional: true 473 611 474 - /@rollup/rollup-darwin-arm64@4.24.2: 475 - resolution: {integrity: sha512-/UhrIxobHYCBfhi5paTkUDQ0w+jckjRZDZ1kcBL132WeHZQ6+S5v9jQPVGLVrLbNUebdIRpIt00lQ+4Z7ys4Rg==} 612 + '@rollup/rollup-darwin-arm64@4.24.2': 613 + resolution: 614 + { 615 + integrity: sha512-/UhrIxobHYCBfhi5paTkUDQ0w+jckjRZDZ1kcBL132WeHZQ6+S5v9jQPVGLVrLbNUebdIRpIt00lQ+4Z7ys4Rg==, 616 + } 476 617 cpu: [arm64] 477 618 os: [darwin] 478 - requiresBuild: true 479 - dev: true 480 - optional: true 481 619 482 - /@rollup/rollup-darwin-x64@4.24.2: 483 - resolution: {integrity: sha512-1F/jrfhxJtWILusgx63WeTvGTwE4vmsT9+e/z7cZLKU8sBMddwqw3UV5ERfOV+H1FuRK3YREZ46J4Gy0aP3qDA==} 620 + '@rollup/rollup-darwin-x64@4.24.2': 621 + resolution: 622 + { 623 + integrity: sha512-1F/jrfhxJtWILusgx63WeTvGTwE4vmsT9+e/z7cZLKU8sBMddwqw3UV5ERfOV+H1FuRK3YREZ46J4Gy0aP3qDA==, 624 + } 484 625 cpu: [x64] 485 626 os: [darwin] 486 - requiresBuild: true 487 - dev: true 488 - optional: true 489 627 490 - /@rollup/rollup-freebsd-arm64@4.24.2: 491 - resolution: {integrity: sha512-1YWOpFcGuC6iGAS4EI+o3BV2/6S0H+m9kFOIlyFtp4xIX5rjSnL3AwbTBxROX0c8yWtiWM7ZI6mEPTI7VkSpZw==} 628 + '@rollup/rollup-freebsd-arm64@4.24.2': 629 + resolution: 630 + { 631 + integrity: sha512-1YWOpFcGuC6iGAS4EI+o3BV2/6S0H+m9kFOIlyFtp4xIX5rjSnL3AwbTBxROX0c8yWtiWM7ZI6mEPTI7VkSpZw==, 632 + } 492 633 cpu: [arm64] 493 634 os: [freebsd] 494 - requiresBuild: true 495 - dev: true 496 - optional: true 497 635 498 - /@rollup/rollup-freebsd-x64@4.24.2: 499 - resolution: {integrity: sha512-3qAqTewYrCdnOD9Gl9yvPoAoFAVmPJsBvleabvx4bnu1Kt6DrB2OALeRVag7BdWGWLhP1yooeMLEi6r2nYSOjg==} 636 + '@rollup/rollup-freebsd-x64@4.24.2': 637 + resolution: 638 + { 639 + integrity: sha512-3qAqTewYrCdnOD9Gl9yvPoAoFAVmPJsBvleabvx4bnu1Kt6DrB2OALeRVag7BdWGWLhP1yooeMLEi6r2nYSOjg==, 640 + } 500 641 cpu: [x64] 501 642 os: [freebsd] 502 - requiresBuild: true 503 - dev: true 504 - optional: true 505 643 506 - /@rollup/rollup-linux-arm-gnueabihf@4.24.2: 507 - resolution: {integrity: sha512-ArdGtPHjLqWkqQuoVQ6a5UC5ebdX8INPuJuJNWRe0RGa/YNhVvxeWmCTFQ7LdmNCSUzVZzxAvUznKaYx645Rig==} 644 + '@rollup/rollup-linux-arm-gnueabihf@4.24.2': 645 + resolution: 646 + { 647 + integrity: sha512-ArdGtPHjLqWkqQuoVQ6a5UC5ebdX8INPuJuJNWRe0RGa/YNhVvxeWmCTFQ7LdmNCSUzVZzxAvUznKaYx645Rig==, 648 + } 508 649 cpu: [arm] 509 650 os: [linux] 510 - requiresBuild: true 511 - dev: true 512 - optional: true 513 651 514 - /@rollup/rollup-linux-arm-musleabihf@4.24.2: 515 - resolution: {integrity: sha512-B6UHHeNnnih8xH6wRKB0mOcJGvjZTww1FV59HqJoTJ5da9LCG6R4SEBt6uPqzlawv1LoEXSS0d4fBlHNWl6iYw==} 652 + '@rollup/rollup-linux-arm-musleabihf@4.24.2': 653 + resolution: 654 + { 655 + integrity: sha512-B6UHHeNnnih8xH6wRKB0mOcJGvjZTww1FV59HqJoTJ5da9LCG6R4SEBt6uPqzlawv1LoEXSS0d4fBlHNWl6iYw==, 656 + } 516 657 cpu: [arm] 517 658 os: [linux] 518 - requiresBuild: true 519 - dev: true 520 - optional: true 521 659 522 - /@rollup/rollup-linux-arm64-gnu@4.24.2: 523 - resolution: {integrity: sha512-kr3gqzczJjSAncwOS6i7fpb4dlqcvLidqrX5hpGBIM1wtt0QEVtf4wFaAwVv8QygFU8iWUMYEoJZWuWxyua4GQ==} 660 + '@rollup/rollup-linux-arm64-gnu@4.24.2': 661 + resolution: 662 + { 663 + integrity: sha512-kr3gqzczJjSAncwOS6i7fpb4dlqcvLidqrX5hpGBIM1wtt0QEVtf4wFaAwVv8QygFU8iWUMYEoJZWuWxyua4GQ==, 664 + } 524 665 cpu: [arm64] 525 666 os: [linux] 526 - requiresBuild: true 527 - dev: true 528 - optional: true 529 667 530 - /@rollup/rollup-linux-arm64-musl@4.24.2: 531 - resolution: {integrity: sha512-TDdHLKCWgPuq9vQcmyLrhg/bgbOvIQ8rtWQK7MRxJ9nvaxKx38NvY7/Lo6cYuEnNHqf6rMqnivOIPIQt6H2AoA==} 668 + '@rollup/rollup-linux-arm64-musl@4.24.2': 669 + resolution: 670 + { 671 + integrity: sha512-TDdHLKCWgPuq9vQcmyLrhg/bgbOvIQ8rtWQK7MRxJ9nvaxKx38NvY7/Lo6cYuEnNHqf6rMqnivOIPIQt6H2AoA==, 672 + } 532 673 cpu: [arm64] 533 674 os: [linux] 534 - requiresBuild: true 535 - dev: true 536 - optional: true 537 675 538 - /@rollup/rollup-linux-powerpc64le-gnu@4.24.2: 539 - resolution: {integrity: sha512-xv9vS648T3X4AxFFZGWeB5Dou8ilsv4VVqJ0+loOIgDO20zIhYfDLkk5xoQiej2RiSQkld9ijF/fhLeonrz2mw==} 676 + '@rollup/rollup-linux-powerpc64le-gnu@4.24.2': 677 + resolution: 678 + { 679 + integrity: sha512-xv9vS648T3X4AxFFZGWeB5Dou8ilsv4VVqJ0+loOIgDO20zIhYfDLkk5xoQiej2RiSQkld9ijF/fhLeonrz2mw==, 680 + } 540 681 cpu: [ppc64] 541 682 os: [linux] 542 - requiresBuild: true 543 - dev: true 544 - optional: true 545 683 546 - /@rollup/rollup-linux-riscv64-gnu@4.24.2: 547 - resolution: {integrity: sha512-tbtXwnofRoTt223WUZYiUnbxhGAOVul/3StZ947U4A5NNjnQJV5irKMm76G0LGItWs6y+SCjUn/Q0WaMLkEskg==} 684 + '@rollup/rollup-linux-riscv64-gnu@4.24.2': 685 + resolution: 686 + { 687 + integrity: sha512-tbtXwnofRoTt223WUZYiUnbxhGAOVul/3StZ947U4A5NNjnQJV5irKMm76G0LGItWs6y+SCjUn/Q0WaMLkEskg==, 688 + } 548 689 cpu: [riscv64] 549 690 os: [linux] 550 - requiresBuild: true 551 - dev: true 552 - optional: true 553 691 554 - /@rollup/rollup-linux-s390x-gnu@4.24.2: 555 - resolution: {integrity: sha512-gc97UebApwdsSNT3q79glOSPdfwgwj5ELuiyuiMY3pEWMxeVqLGKfpDFoum4ujivzxn6veUPzkGuSYoh5deQ2Q==} 692 + '@rollup/rollup-linux-s390x-gnu@4.24.2': 693 + resolution: 694 + { 695 + integrity: sha512-gc97UebApwdsSNT3q79glOSPdfwgwj5ELuiyuiMY3pEWMxeVqLGKfpDFoum4ujivzxn6veUPzkGuSYoh5deQ2Q==, 696 + } 556 697 cpu: [s390x] 557 698 os: [linux] 558 - requiresBuild: true 559 - dev: true 560 - optional: true 561 699 562 - /@rollup/rollup-linux-x64-gnu@4.24.2: 563 - resolution: {integrity: sha512-jOG/0nXb3z+EM6SioY8RofqqmZ+9NKYvJ6QQaa9Mvd3RQxlH68/jcB/lpyVt4lCiqr04IyaC34NzhUqcXbB5FQ==} 700 + '@rollup/rollup-linux-x64-gnu@4.24.2': 701 + resolution: 702 + { 703 + integrity: sha512-jOG/0nXb3z+EM6SioY8RofqqmZ+9NKYvJ6QQaa9Mvd3RQxlH68/jcB/lpyVt4lCiqr04IyaC34NzhUqcXbB5FQ==, 704 + } 564 705 cpu: [x64] 565 706 os: [linux] 566 - requiresBuild: true 567 - dev: true 568 - optional: true 569 707 570 - /@rollup/rollup-linux-x64-musl@4.24.2: 571 - resolution: {integrity: sha512-XAo7cJec80NWx9LlZFEJQxqKOMz/lX3geWs2iNT5CHIERLFfd90f3RYLLjiCBm1IMaQ4VOX/lTC9lWfzzQm14Q==} 708 + '@rollup/rollup-linux-x64-musl@4.24.2': 709 + resolution: 710 + { 711 + integrity: sha512-XAo7cJec80NWx9LlZFEJQxqKOMz/lX3geWs2iNT5CHIERLFfd90f3RYLLjiCBm1IMaQ4VOX/lTC9lWfzzQm14Q==, 712 + } 572 713 cpu: [x64] 573 714 os: [linux] 574 - requiresBuild: true 575 - dev: true 576 - optional: true 577 715 578 - /@rollup/rollup-win32-arm64-msvc@4.24.2: 579 - resolution: {integrity: sha512-A+JAs4+EhsTjnPQvo9XY/DC0ztaws3vfqzrMNMKlwQXuniBKOIIvAAI8M0fBYiTCxQnElYu7mLk7JrhlQ+HeOw==} 716 + '@rollup/rollup-win32-arm64-msvc@4.24.2': 717 + resolution: 718 + { 719 + integrity: sha512-A+JAs4+EhsTjnPQvo9XY/DC0ztaws3vfqzrMNMKlwQXuniBKOIIvAAI8M0fBYiTCxQnElYu7mLk7JrhlQ+HeOw==, 720 + } 580 721 cpu: [arm64] 581 722 os: [win32] 582 - requiresBuild: true 583 - dev: true 584 - optional: true 585 723 586 - /@rollup/rollup-win32-ia32-msvc@4.24.2: 587 - resolution: {integrity: sha512-ZhcrakbqA1SCiJRMKSU64AZcYzlZ/9M5LaYil9QWxx9vLnkQ9Vnkve17Qn4SjlipqIIBFKjBES6Zxhnvh0EAEw==} 724 + '@rollup/rollup-win32-ia32-msvc@4.24.2': 725 + resolution: 726 + { 727 + integrity: sha512-ZhcrakbqA1SCiJRMKSU64AZcYzlZ/9M5LaYil9QWxx9vLnkQ9Vnkve17Qn4SjlipqIIBFKjBES6Zxhnvh0EAEw==, 728 + } 588 729 cpu: [ia32] 589 730 os: [win32] 590 - requiresBuild: true 591 - dev: true 592 - optional: true 593 731 594 - /@rollup/rollup-win32-x64-msvc@4.24.2: 595 - resolution: {integrity: sha512-2mLH46K1u3r6uwc95hU+OR9q/ggYMpnS7pSp83Ece1HUQgF9Nh/QwTK5rcgbFnV9j+08yBrU5sA/P0RK2MSBNA==} 732 + '@rollup/rollup-win32-x64-msvc@4.24.2': 733 + resolution: 734 + { 735 + integrity: sha512-2mLH46K1u3r6uwc95hU+OR9q/ggYMpnS7pSp83Ece1HUQgF9Nh/QwTK5rcgbFnV9j+08yBrU5sA/P0RK2MSBNA==, 736 + } 596 737 cpu: [x64] 597 738 os: [win32] 598 - requiresBuild: true 599 - dev: true 600 - optional: true 601 739 602 - /@types/estree@1.0.6: 603 - resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} 604 - dev: true 740 + '@types/estree@1.0.6': 741 + resolution: 742 + { 743 + integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==, 744 + } 605 745 606 - /@types/node@22.7.5: 607 - resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==} 608 - dependencies: 609 - undici-types: 6.19.8 610 - dev: true 746 + '@types/json-schema@7.0.15': 747 + resolution: 748 + { 749 + integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==, 750 + } 611 751 612 - /@vitest/expect@2.1.3: 613 - resolution: {integrity: sha512-SNBoPubeCJhZ48agjXruCI57DvxcsivVDdWz+SSsmjTT4QN/DfHk3zB/xKsJqMs26bLZ/pNRLnCf0j679i0uWQ==} 614 - dependencies: 615 - '@vitest/spy': 2.1.3 616 - '@vitest/utils': 2.1.3 617 - chai: 5.1.2 618 - tinyrainbow: 1.2.0 619 - dev: true 752 + '@types/node@22.7.5': 753 + resolution: 754 + { 755 + integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==, 756 + } 757 + 758 + '@typescript-eslint/eslint-plugin@8.20.0': 759 + resolution: 760 + { 761 + integrity: sha512-naduuphVw5StFfqp4Gq4WhIBE2gN1GEmMUExpJYknZJdRnc+2gDzB8Z3+5+/Kv33hPQRDGzQO/0opHE72lZZ6A==, 762 + } 763 + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } 764 + peerDependencies: 765 + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 766 + eslint: ^8.57.0 || ^9.0.0 767 + typescript: '>=4.8.4 <5.8.0' 768 + 769 + '@typescript-eslint/parser@8.20.0': 770 + resolution: 771 + { 772 + integrity: sha512-gKXG7A5HMyjDIedBi6bUrDcun8GIjnI8qOwVLiY3rx6T/sHP/19XLJOnIq/FgQvWLHja5JN/LSE7eklNBr612g==, 773 + } 774 + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } 775 + peerDependencies: 776 + eslint: ^8.57.0 || ^9.0.0 777 + typescript: '>=4.8.4 <5.8.0' 778 + 779 + '@typescript-eslint/scope-manager@8.20.0': 780 + resolution: 781 + { 782 + integrity: sha512-J7+VkpeGzhOt3FeG1+SzhiMj9NzGD/M6KoGn9f4dbz3YzK9hvbhVTmLj/HiTp9DazIzJ8B4XcM80LrR9Dm1rJw==, 783 + } 784 + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } 785 + 786 + '@typescript-eslint/type-utils@8.20.0': 787 + resolution: 788 + { 789 + integrity: sha512-bPC+j71GGvA7rVNAHAtOjbVXbLN5PkwqMvy1cwGeaxUoRQXVuKCebRoLzm+IPW/NtFFpstn1ummSIasD5t60GA==, 790 + } 791 + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } 792 + peerDependencies: 793 + eslint: ^8.57.0 || ^9.0.0 794 + typescript: '>=4.8.4 <5.8.0' 795 + 796 + '@typescript-eslint/types@8.20.0': 797 + resolution: 798 + { 799 + integrity: sha512-cqaMiY72CkP+2xZRrFt3ExRBu0WmVitN/rYPZErA80mHjHx/Svgp8yfbzkJmDoQ/whcytOPO9/IZXnOc+wigRA==, 800 + } 801 + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } 620 802 621 - /@vitest/mocker@2.1.3(@vitest/spy@2.1.3)(vite@5.4.10): 622 - resolution: {integrity: sha512-eSpdY/eJDuOvuTA3ASzCjdithHa+GIF1L4PqtEELl6Qa3XafdMLBpBlZCIUCX2J+Q6sNmjmxtosAG62fK4BlqQ==} 803 + '@typescript-eslint/typescript-estree@8.20.0': 804 + resolution: 805 + { 806 + integrity: sha512-Y7ncuy78bJqHI35NwzWol8E0X7XkRVS4K4P4TCyzWkOJih5NDvtoRDW4Ba9YJJoB2igm9yXDdYI/+fkiiAxPzA==, 807 + } 808 + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } 809 + peerDependencies: 810 + typescript: '>=4.8.4 <5.8.0' 811 + 812 + '@typescript-eslint/utils@8.20.0': 813 + resolution: 814 + { 815 + integrity: sha512-dq70RUw6UK9ei7vxc4KQtBRk7qkHZv447OUZ6RPQMQl71I3NZxQJX/f32Smr+iqWrB02pHKn2yAdHBb0KNrRMA==, 816 + } 817 + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } 818 + peerDependencies: 819 + eslint: ^8.57.0 || ^9.0.0 820 + typescript: '>=4.8.4 <5.8.0' 821 + 822 + '@typescript-eslint/visitor-keys@8.20.0': 823 + resolution: 824 + { 825 + integrity: sha512-v/BpkeeYAsPkKCkR8BDwcno0llhzWVqPOamQrAEMdpZav2Y9OVjd9dwJyBLJWwf335B5DmlifECIkZRJCaGaHA==, 826 + } 827 + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } 828 + 829 + '@vitest/expect@2.1.3': 830 + resolution: 831 + { 832 + integrity: sha512-SNBoPubeCJhZ48agjXruCI57DvxcsivVDdWz+SSsmjTT4QN/DfHk3zB/xKsJqMs26bLZ/pNRLnCf0j679i0uWQ==, 833 + } 834 + 835 + '@vitest/mocker@2.1.3': 836 + resolution: 837 + { 838 + integrity: sha512-eSpdY/eJDuOvuTA3ASzCjdithHa+GIF1L4PqtEELl6Qa3XafdMLBpBlZCIUCX2J+Q6sNmjmxtosAG62fK4BlqQ==, 839 + } 623 840 peerDependencies: 624 841 '@vitest/spy': 2.1.3 625 842 msw: ^2.3.5 ··· 629 846 optional: true 630 847 vite: 631 848 optional: true 849 + 850 + '@vitest/pretty-format@2.1.3': 851 + resolution: 852 + { 853 + integrity: sha512-XH1XdtoLZCpqV59KRbPrIhFCOO0hErxrQCMcvnQete3Vibb9UeIOX02uFPfVn3Z9ZXsq78etlfyhnkmIZSzIwQ==, 854 + } 855 + 856 + '@vitest/runner@2.1.3': 857 + resolution: 858 + { 859 + integrity: sha512-JGzpWqmFJ4fq5ZKHtVO3Xuy1iF2rHGV4d/pdzgkYHm1+gOzNZtqjvyiaDGJytRyMU54qkxpNzCx+PErzJ1/JqQ==, 860 + } 861 + 862 + '@vitest/snapshot@2.1.3': 863 + resolution: 864 + { 865 + integrity: sha512-qWC2mWc7VAXmjAkEKxrScWHWFyCQx/cmiZtuGqMi+WwqQJ2iURsVY4ZfAK6dVo6K2smKRU6l3BPwqEBvhnpQGg==, 866 + } 867 + 868 + '@vitest/spy@2.1.3': 869 + resolution: 870 + { 871 + integrity: sha512-Nb2UzbcUswzeSP7JksMDaqsI43Sj5+Kry6ry6jQJT4b5gAK+NS9NED6mDb8FlMRCX8m5guaHCDZmqYMMWRy5nQ==, 872 + } 873 + 874 + '@vitest/utils@2.1.3': 875 + resolution: 876 + { 877 + integrity: sha512-xpiVfDSg1RrYT0tX6czgerkpcKFmFOF/gCr30+Mve5V2kewCy4Prn1/NDMSRwaSmT7PRaOF83wu+bEtsY1wrvA==, 878 + } 879 + 880 + acorn-jsx@5.3.2: 881 + resolution: 882 + { 883 + integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==, 884 + } 885 + peerDependencies: 886 + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 887 + 888 + acorn@8.14.0: 889 + resolution: 890 + { 891 + integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==, 892 + } 893 + engines: { node: '>=0.4.0' } 894 + hasBin: true 895 + 896 + ajv@6.12.6: 897 + resolution: 898 + { 899 + integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==, 900 + } 901 + 902 + ansi-styles@4.3.0: 903 + resolution: 904 + { 905 + integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, 906 + } 907 + engines: { node: '>=8' } 908 + 909 + argparse@2.0.1: 910 + resolution: 911 + { 912 + integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==, 913 + } 914 + 915 + assertion-error@2.0.1: 916 + resolution: 917 + { 918 + integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==, 919 + } 920 + engines: { node: '>=12' } 921 + 922 + balanced-match@1.0.2: 923 + resolution: 924 + { 925 + integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, 926 + } 927 + 928 + brace-expansion@1.1.11: 929 + resolution: 930 + { 931 + integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==, 932 + } 933 + 934 + brace-expansion@2.0.1: 935 + resolution: 936 + { 937 + integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==, 938 + } 939 + 940 + braces@3.0.3: 941 + resolution: 942 + { 943 + integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==, 944 + } 945 + engines: { node: '>=8' } 946 + 947 + cac@6.7.14: 948 + resolution: 949 + { 950 + integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==, 951 + } 952 + engines: { node: '>=8' } 953 + 954 + callsites@3.1.0: 955 + resolution: 956 + { 957 + integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==, 958 + } 959 + engines: { node: '>=6' } 960 + 961 + chai@5.1.2: 962 + resolution: 963 + { 964 + integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==, 965 + } 966 + engines: { node: '>=12' } 967 + 968 + chalk@4.1.2: 969 + resolution: 970 + { 971 + integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, 972 + } 973 + engines: { node: '>=10' } 974 + 975 + check-error@2.1.1: 976 + resolution: 977 + { 978 + integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==, 979 + } 980 + engines: { node: '>= 16' } 981 + 982 + citty@0.1.6: 983 + resolution: 984 + { 985 + integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==, 986 + } 987 + 988 + color-convert@2.0.1: 989 + resolution: 990 + { 991 + integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, 992 + } 993 + engines: { node: '>=7.0.0' } 994 + 995 + color-name@1.1.4: 996 + resolution: 997 + { 998 + integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, 999 + } 1000 + 1001 + concat-map@0.0.1: 1002 + resolution: 1003 + { 1004 + integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==, 1005 + } 1006 + 1007 + consola@3.2.3: 1008 + resolution: 1009 + { 1010 + integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==, 1011 + } 1012 + engines: { node: ^14.18.0 || >=16.10.0 } 1013 + 1014 + cross-spawn@7.0.6: 1015 + resolution: 1016 + { 1017 + integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==, 1018 + } 1019 + engines: { node: '>= 8' } 1020 + 1021 + debug@4.3.7: 1022 + resolution: 1023 + { 1024 + integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==, 1025 + } 1026 + engines: { node: '>=6.0' } 1027 + peerDependencies: 1028 + supports-color: '*' 1029 + peerDependenciesMeta: 1030 + supports-color: 1031 + optional: true 1032 + 1033 + deep-eql@5.0.2: 1034 + resolution: 1035 + { 1036 + integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==, 1037 + } 1038 + engines: { node: '>=6' } 1039 + 1040 + deep-is@0.1.4: 1041 + resolution: 1042 + { 1043 + integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==, 1044 + } 1045 + 1046 + esbuild@0.21.5: 1047 + resolution: 1048 + { 1049 + integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==, 1050 + } 1051 + engines: { node: '>=12' } 1052 + hasBin: true 1053 + 1054 + esbuild@0.23.1: 1055 + resolution: 1056 + { 1057 + integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==, 1058 + } 1059 + engines: { node: '>=18' } 1060 + hasBin: true 1061 + 1062 + escape-string-regexp@4.0.0: 1063 + resolution: 1064 + { 1065 + integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==, 1066 + } 1067 + engines: { node: '>=10' } 1068 + 1069 + eslint-config-prettier@10.0.1: 1070 + resolution: 1071 + { 1072 + integrity: sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw==, 1073 + } 1074 + hasBin: true 1075 + peerDependencies: 1076 + eslint: '>=7.0.0' 1077 + 1078 + eslint-plugin-prettier@5.2.2: 1079 + resolution: 1080 + { 1081 + integrity: sha512-1yI3/hf35wmlq66C8yOyrujQnel+v5l1Vop5Cl2I6ylyNTT1JbuUUnV3/41PzwTzcyDp/oF0jWE3HXvcH5AQOQ==, 1082 + } 1083 + engines: { node: ^14.18.0 || >=16.0.0 } 1084 + peerDependencies: 1085 + '@types/eslint': '>=8.0.0' 1086 + eslint: '>=8.0.0' 1087 + eslint-config-prettier: '*' 1088 + prettier: '>=3.0.0' 1089 + peerDependenciesMeta: 1090 + '@types/eslint': 1091 + optional: true 1092 + eslint-config-prettier: 1093 + optional: true 1094 + 1095 + eslint-scope@8.2.0: 1096 + resolution: 1097 + { 1098 + integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==, 1099 + } 1100 + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } 1101 + 1102 + eslint-visitor-keys@3.4.3: 1103 + resolution: 1104 + { 1105 + integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==, 1106 + } 1107 + engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } 1108 + 1109 + eslint-visitor-keys@4.2.0: 1110 + resolution: 1111 + { 1112 + integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==, 1113 + } 1114 + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } 1115 + 1116 + eslint@9.18.0: 1117 + resolution: 1118 + { 1119 + integrity: sha512-+waTfRWQlSbpt3KWE+CjrPPYnbq9kfZIYUqapc0uBXyjTp8aYXZDsUH16m39Ryq3NjAVP4tjuF7KaukeqoCoaA==, 1120 + } 1121 + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } 1122 + hasBin: true 1123 + peerDependencies: 1124 + jiti: '*' 1125 + peerDependenciesMeta: 1126 + jiti: 1127 + optional: true 1128 + 1129 + espree@10.3.0: 1130 + resolution: 1131 + { 1132 + integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==, 1133 + } 1134 + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } 1135 + 1136 + esquery@1.6.0: 1137 + resolution: 1138 + { 1139 + integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==, 1140 + } 1141 + engines: { node: '>=0.10' } 1142 + 1143 + esrecurse@4.3.0: 1144 + resolution: 1145 + { 1146 + integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==, 1147 + } 1148 + engines: { node: '>=4.0' } 1149 + 1150 + estraverse@5.3.0: 1151 + resolution: 1152 + { 1153 + integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==, 1154 + } 1155 + engines: { node: '>=4.0' } 1156 + 1157 + estree-walker@3.0.3: 1158 + resolution: 1159 + { 1160 + integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==, 1161 + } 1162 + 1163 + esutils@2.0.3: 1164 + resolution: 1165 + { 1166 + integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==, 1167 + } 1168 + engines: { node: '>=0.10.0' } 1169 + 1170 + fast-deep-equal@3.1.3: 1171 + resolution: 1172 + { 1173 + integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==, 1174 + } 1175 + 1176 + fast-diff@1.3.0: 1177 + resolution: 1178 + { 1179 + integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==, 1180 + } 1181 + 1182 + fast-glob@3.3.3: 1183 + resolution: 1184 + { 1185 + integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==, 1186 + } 1187 + engines: { node: '>=8.6.0' } 1188 + 1189 + fast-json-stable-stringify@2.1.0: 1190 + resolution: 1191 + { 1192 + integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==, 1193 + } 1194 + 1195 + fast-levenshtein@2.0.6: 1196 + resolution: 1197 + { 1198 + integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==, 1199 + } 1200 + 1201 + fastq@1.18.0: 1202 + resolution: 1203 + { 1204 + integrity: sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==, 1205 + } 1206 + 1207 + file-entry-cache@8.0.0: 1208 + resolution: 1209 + { 1210 + integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==, 1211 + } 1212 + engines: { node: '>=16.0.0' } 1213 + 1214 + fill-range@7.1.1: 1215 + resolution: 1216 + { 1217 + integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==, 1218 + } 1219 + engines: { node: '>=8' } 1220 + 1221 + find-up@5.0.0: 1222 + resolution: 1223 + { 1224 + integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==, 1225 + } 1226 + engines: { node: '>=10' } 1227 + 1228 + flat-cache@4.0.1: 1229 + resolution: 1230 + { 1231 + integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==, 1232 + } 1233 + engines: { node: '>=16' } 1234 + 1235 + flatted@3.3.2: 1236 + resolution: 1237 + { 1238 + integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==, 1239 + } 1240 + 1241 + fsevents@2.3.3: 1242 + resolution: 1243 + { 1244 + integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, 1245 + } 1246 + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } 1247 + os: [darwin] 1248 + 1249 + get-tsconfig@4.8.1: 1250 + resolution: 1251 + { 1252 + integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==, 1253 + } 1254 + 1255 + glob-parent@5.1.2: 1256 + resolution: 1257 + { 1258 + integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==, 1259 + } 1260 + engines: { node: '>= 6' } 1261 + 1262 + glob-parent@6.0.2: 1263 + resolution: 1264 + { 1265 + integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==, 1266 + } 1267 + engines: { node: '>=10.13.0' } 1268 + 1269 + globals@14.0.0: 1270 + resolution: 1271 + { 1272 + integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==, 1273 + } 1274 + engines: { node: '>=18' } 1275 + 1276 + graphemer@1.4.0: 1277 + resolution: 1278 + { 1279 + integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==, 1280 + } 1281 + 1282 + has-flag@4.0.0: 1283 + resolution: 1284 + { 1285 + integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, 1286 + } 1287 + engines: { node: '>=8' } 1288 + 1289 + ignore@5.3.2: 1290 + resolution: 1291 + { 1292 + integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==, 1293 + } 1294 + engines: { node: '>= 4' } 1295 + 1296 + import-fresh@3.3.0: 1297 + resolution: 1298 + { 1299 + integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==, 1300 + } 1301 + engines: { node: '>=6' } 1302 + 1303 + imurmurhash@0.1.4: 1304 + resolution: 1305 + { 1306 + integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==, 1307 + } 1308 + engines: { node: '>=0.8.19' } 1309 + 1310 + is-extglob@2.1.1: 1311 + resolution: 1312 + { 1313 + integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==, 1314 + } 1315 + engines: { node: '>=0.10.0' } 1316 + 1317 + is-glob@4.0.3: 1318 + resolution: 1319 + { 1320 + integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==, 1321 + } 1322 + engines: { node: '>=0.10.0' } 1323 + 1324 + is-number@7.0.0: 1325 + resolution: 1326 + { 1327 + integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, 1328 + } 1329 + engines: { node: '>=0.12.0' } 1330 + 1331 + isexe@2.0.0: 1332 + resolution: 1333 + { 1334 + integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, 1335 + } 1336 + 1337 + js-yaml@4.1.0: 1338 + resolution: 1339 + { 1340 + integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==, 1341 + } 1342 + hasBin: true 1343 + 1344 + json-buffer@3.0.1: 1345 + resolution: 1346 + { 1347 + integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==, 1348 + } 1349 + 1350 + json-schema-traverse@0.4.1: 1351 + resolution: 1352 + { 1353 + integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==, 1354 + } 1355 + 1356 + json-stable-stringify-without-jsonify@1.0.1: 1357 + resolution: 1358 + { 1359 + integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==, 1360 + } 1361 + 1362 + keyv@4.5.4: 1363 + resolution: 1364 + { 1365 + integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==, 1366 + } 1367 + 1368 + levn@0.4.1: 1369 + resolution: 1370 + { 1371 + integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==, 1372 + } 1373 + engines: { node: '>= 0.8.0' } 1374 + 1375 + locate-path@6.0.0: 1376 + resolution: 1377 + { 1378 + integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==, 1379 + } 1380 + engines: { node: '>=10' } 1381 + 1382 + lodash.merge@4.6.2: 1383 + resolution: 1384 + { 1385 + integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==, 1386 + } 1387 + 1388 + loupe@3.1.2: 1389 + resolution: 1390 + { 1391 + integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==, 1392 + } 1393 + 1394 + magic-string@0.30.12: 1395 + resolution: 1396 + { 1397 + integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==, 1398 + } 1399 + 1400 + merge2@1.4.1: 1401 + resolution: 1402 + { 1403 + integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==, 1404 + } 1405 + engines: { node: '>= 8' } 1406 + 1407 + micromatch@4.0.8: 1408 + resolution: 1409 + { 1410 + integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==, 1411 + } 1412 + engines: { node: '>=8.6' } 1413 + 1414 + minimatch@3.1.2: 1415 + resolution: 1416 + { 1417 + integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==, 1418 + } 1419 + 1420 + minimatch@9.0.5: 1421 + resolution: 1422 + { 1423 + integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==, 1424 + } 1425 + engines: { node: '>=16 || 14 >=14.17' } 1426 + 1427 + mri@1.2.0: 1428 + resolution: 1429 + { 1430 + integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==, 1431 + } 1432 + engines: { node: '>=4' } 1433 + 1434 + ms@2.1.3: 1435 + resolution: 1436 + { 1437 + integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, 1438 + } 1439 + 1440 + nanoid@3.3.7: 1441 + resolution: 1442 + { 1443 + integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==, 1444 + } 1445 + engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } 1446 + hasBin: true 1447 + 1448 + natural-compare@1.4.0: 1449 + resolution: 1450 + { 1451 + integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==, 1452 + } 1453 + 1454 + optionator@0.9.4: 1455 + resolution: 1456 + { 1457 + integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==, 1458 + } 1459 + engines: { node: '>= 0.8.0' } 1460 + 1461 + p-limit@3.1.0: 1462 + resolution: 1463 + { 1464 + integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==, 1465 + } 1466 + engines: { node: '>=10' } 1467 + 1468 + p-locate@5.0.0: 1469 + resolution: 1470 + { 1471 + integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==, 1472 + } 1473 + engines: { node: '>=10' } 1474 + 1475 + parent-module@1.0.1: 1476 + resolution: 1477 + { 1478 + integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==, 1479 + } 1480 + engines: { node: '>=6' } 1481 + 1482 + path-exists@4.0.0: 1483 + resolution: 1484 + { 1485 + integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==, 1486 + } 1487 + engines: { node: '>=8' } 1488 + 1489 + path-key@3.1.1: 1490 + resolution: 1491 + { 1492 + integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, 1493 + } 1494 + engines: { node: '>=8' } 1495 + 1496 + pathe@1.1.2: 1497 + resolution: 1498 + { 1499 + integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==, 1500 + } 1501 + 1502 + pathval@2.0.0: 1503 + resolution: 1504 + { 1505 + integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==, 1506 + } 1507 + engines: { node: '>= 14.16' } 1508 + 1509 + picocolors@1.1.1: 1510 + resolution: 1511 + { 1512 + integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==, 1513 + } 1514 + 1515 + picomatch@2.3.1: 1516 + resolution: 1517 + { 1518 + integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==, 1519 + } 1520 + engines: { node: '>=8.6' } 1521 + 1522 + postcss@8.4.47: 1523 + resolution: 1524 + { 1525 + integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==, 1526 + } 1527 + engines: { node: ^10 || ^12 || >=14 } 1528 + 1529 + prelude-ls@1.2.1: 1530 + resolution: 1531 + { 1532 + integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==, 1533 + } 1534 + engines: { node: '>= 0.8.0' } 1535 + 1536 + prettier-linter-helpers@1.0.0: 1537 + resolution: 1538 + { 1539 + integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==, 1540 + } 1541 + engines: { node: '>=6.0.0' } 1542 + 1543 + prettier@3.4.2: 1544 + resolution: 1545 + { 1546 + integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==, 1547 + } 1548 + engines: { node: '>=14' } 1549 + hasBin: true 1550 + 1551 + punycode@2.3.1: 1552 + resolution: 1553 + { 1554 + integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==, 1555 + } 1556 + engines: { node: '>=6' } 1557 + 1558 + queue-microtask@1.2.3: 1559 + resolution: 1560 + { 1561 + integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==, 1562 + } 1563 + 1564 + resolve-from@4.0.0: 1565 + resolution: 1566 + { 1567 + integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==, 1568 + } 1569 + engines: { node: '>=4' } 1570 + 1571 + resolve-pkg-maps@1.0.0: 1572 + resolution: 1573 + { 1574 + integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==, 1575 + } 1576 + 1577 + reusify@1.0.4: 1578 + resolution: 1579 + { 1580 + integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==, 1581 + } 1582 + engines: { iojs: '>=1.0.0', node: '>=0.10.0' } 1583 + 1584 + rollup@4.24.2: 1585 + resolution: 1586 + { 1587 + integrity: sha512-do/DFGq5g6rdDhdpPq5qb2ecoczeK6y+2UAjdJ5trjQJj5f1AiVdLRWRc9A9/fFukfvJRgM0UXzxBIYMovm5ww==, 1588 + } 1589 + engines: { node: '>=18.0.0', npm: '>=8.0.0' } 1590 + hasBin: true 1591 + 1592 + run-parallel@1.2.0: 1593 + resolution: 1594 + { 1595 + integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==, 1596 + } 1597 + 1598 + semver@7.6.3: 1599 + resolution: 1600 + { 1601 + integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==, 1602 + } 1603 + engines: { node: '>=10' } 1604 + hasBin: true 1605 + 1606 + shebang-command@2.0.0: 1607 + resolution: 1608 + { 1609 + integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, 1610 + } 1611 + engines: { node: '>=8' } 1612 + 1613 + shebang-regex@3.0.0: 1614 + resolution: 1615 + { 1616 + integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, 1617 + } 1618 + engines: { node: '>=8' } 1619 + 1620 + siginfo@2.0.0: 1621 + resolution: 1622 + { 1623 + integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==, 1624 + } 1625 + 1626 + source-map-js@1.2.1: 1627 + resolution: 1628 + { 1629 + integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==, 1630 + } 1631 + engines: { node: '>=0.10.0' } 1632 + 1633 + stackback@0.0.2: 1634 + resolution: 1635 + { 1636 + integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==, 1637 + } 1638 + 1639 + std-env@3.7.0: 1640 + resolution: 1641 + { 1642 + integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==, 1643 + } 1644 + 1645 + strip-json-comments@3.1.1: 1646 + resolution: 1647 + { 1648 + integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==, 1649 + } 1650 + engines: { node: '>=8' } 1651 + 1652 + supports-color@7.2.0: 1653 + resolution: 1654 + { 1655 + integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, 1656 + } 1657 + engines: { node: '>=8' } 1658 + 1659 + synckit@0.9.2: 1660 + resolution: 1661 + { 1662 + integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==, 1663 + } 1664 + engines: { node: ^14.18.0 || >=16.0.0 } 1665 + 1666 + tinybench@2.9.0: 1667 + resolution: 1668 + { 1669 + integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==, 1670 + } 1671 + 1672 + tinyexec@0.3.1: 1673 + resolution: 1674 + { 1675 + integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==, 1676 + } 1677 + 1678 + tinypool@1.0.1: 1679 + resolution: 1680 + { 1681 + integrity: sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==, 1682 + } 1683 + engines: { node: ^18.0.0 || >=20.0.0 } 1684 + 1685 + tinyrainbow@1.2.0: 1686 + resolution: 1687 + { 1688 + integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==, 1689 + } 1690 + engines: { node: '>=14.0.0' } 1691 + 1692 + tinyspy@3.0.2: 1693 + resolution: 1694 + { 1695 + integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==, 1696 + } 1697 + engines: { node: '>=14.0.0' } 1698 + 1699 + to-regex-range@5.0.1: 1700 + resolution: 1701 + { 1702 + integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, 1703 + } 1704 + engines: { node: '>=8.0' } 1705 + 1706 + ts-api-utils@2.0.0: 1707 + resolution: 1708 + { 1709 + integrity: sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ==, 1710 + } 1711 + engines: { node: '>=18.12' } 1712 + peerDependencies: 1713 + typescript: '>=4.8.4' 1714 + 1715 + tslib@2.8.1: 1716 + resolution: 1717 + { 1718 + integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==, 1719 + } 1720 + 1721 + tsx@4.19.1: 1722 + resolution: 1723 + { 1724 + integrity: sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==, 1725 + } 1726 + engines: { node: '>=18.0.0' } 1727 + hasBin: true 1728 + 1729 + type-check@0.4.0: 1730 + resolution: 1731 + { 1732 + integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==, 1733 + } 1734 + engines: { node: '>= 0.8.0' } 1735 + 1736 + typescript@5.7.3: 1737 + resolution: 1738 + { 1739 + integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==, 1740 + } 1741 + engines: { node: '>=14.17' } 1742 + hasBin: true 1743 + 1744 + undici-types@6.19.8: 1745 + resolution: 1746 + { 1747 + integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==, 1748 + } 1749 + 1750 + uri-js@4.4.1: 1751 + resolution: 1752 + { 1753 + integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==, 1754 + } 1755 + 1756 + vite-node@2.1.3: 1757 + resolution: 1758 + { 1759 + integrity: sha512-I1JadzO+xYX887S39Do+paRePCKoiDrWRRjp9kkG5he0t7RXNvPAJPCQSJqbGN4uCrFFeS3Kj3sLqY8NMYBEdA==, 1760 + } 1761 + engines: { node: ^18.0.0 || >=20.0.0 } 1762 + hasBin: true 1763 + 1764 + vite@5.4.10: 1765 + resolution: 1766 + { 1767 + integrity: sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==, 1768 + } 1769 + engines: { node: ^18.0.0 || >=20.0.0 } 1770 + hasBin: true 1771 + peerDependencies: 1772 + '@types/node': ^18.0.0 || >=20.0.0 1773 + less: '*' 1774 + lightningcss: ^1.21.0 1775 + sass: '*' 1776 + sass-embedded: '*' 1777 + stylus: '*' 1778 + sugarss: '*' 1779 + terser: ^5.4.0 1780 + peerDependenciesMeta: 1781 + '@types/node': 1782 + optional: true 1783 + less: 1784 + optional: true 1785 + lightningcss: 1786 + optional: true 1787 + sass: 1788 + optional: true 1789 + sass-embedded: 1790 + optional: true 1791 + stylus: 1792 + optional: true 1793 + sugarss: 1794 + optional: true 1795 + terser: 1796 + optional: true 1797 + 1798 + vitest@2.1.3: 1799 + resolution: 1800 + { 1801 + integrity: sha512-Zrxbg/WiIvUP2uEzelDNTXmEMJXuzJ1kCpbDvaKByFA9MNeO95V+7r/3ti0qzJzrxdyuUw5VduN7k+D3VmVOSA==, 1802 + } 1803 + engines: { node: ^18.0.0 || >=20.0.0 } 1804 + hasBin: true 1805 + peerDependencies: 1806 + '@edge-runtime/vm': '*' 1807 + '@types/node': ^18.0.0 || >=20.0.0 1808 + '@vitest/browser': 2.1.3 1809 + '@vitest/ui': 2.1.3 1810 + happy-dom: '*' 1811 + jsdom: '*' 1812 + peerDependenciesMeta: 1813 + '@edge-runtime/vm': 1814 + optional: true 1815 + '@types/node': 1816 + optional: true 1817 + '@vitest/browser': 1818 + optional: true 1819 + '@vitest/ui': 1820 + optional: true 1821 + happy-dom: 1822 + optional: true 1823 + jsdom: 1824 + optional: true 1825 + 1826 + which@2.0.2: 1827 + resolution: 1828 + { 1829 + integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, 1830 + } 1831 + engines: { node: '>= 8' } 1832 + hasBin: true 1833 + 1834 + why-is-node-running@2.3.0: 1835 + resolution: 1836 + { 1837 + integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==, 1838 + } 1839 + engines: { node: '>=8' } 1840 + hasBin: true 1841 + 1842 + word-wrap@1.2.5: 1843 + resolution: 1844 + { 1845 + integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==, 1846 + } 1847 + engines: { node: '>=0.10.0' } 1848 + 1849 + yocto-queue@0.1.0: 1850 + resolution: 1851 + { 1852 + integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==, 1853 + } 1854 + engines: { node: '>=10' } 1855 + 1856 + snapshots: 1857 + '@esbuild/aix-ppc64@0.21.5': 1858 + optional: true 1859 + 1860 + '@esbuild/aix-ppc64@0.23.1': 1861 + optional: true 1862 + 1863 + '@esbuild/android-arm64@0.21.5': 1864 + optional: true 1865 + 1866 + '@esbuild/android-arm64@0.23.1': 1867 + optional: true 1868 + 1869 + '@esbuild/android-arm@0.21.5': 1870 + optional: true 1871 + 1872 + '@esbuild/android-arm@0.23.1': 1873 + optional: true 1874 + 1875 + '@esbuild/android-x64@0.21.5': 1876 + optional: true 1877 + 1878 + '@esbuild/android-x64@0.23.1': 1879 + optional: true 1880 + 1881 + '@esbuild/darwin-arm64@0.21.5': 1882 + optional: true 1883 + 1884 + '@esbuild/darwin-arm64@0.23.1': 1885 + optional: true 1886 + 1887 + '@esbuild/darwin-x64@0.21.5': 1888 + optional: true 1889 + 1890 + '@esbuild/darwin-x64@0.23.1': 1891 + optional: true 1892 + 1893 + '@esbuild/freebsd-arm64@0.21.5': 1894 + optional: true 1895 + 1896 + '@esbuild/freebsd-arm64@0.23.1': 1897 + optional: true 1898 + 1899 + '@esbuild/freebsd-x64@0.21.5': 1900 + optional: true 1901 + 1902 + '@esbuild/freebsd-x64@0.23.1': 1903 + optional: true 1904 + 1905 + '@esbuild/linux-arm64@0.21.5': 1906 + optional: true 1907 + 1908 + '@esbuild/linux-arm64@0.23.1': 1909 + optional: true 1910 + 1911 + '@esbuild/linux-arm@0.21.5': 1912 + optional: true 1913 + 1914 + '@esbuild/linux-arm@0.23.1': 1915 + optional: true 1916 + 1917 + '@esbuild/linux-ia32@0.21.5': 1918 + optional: true 1919 + 1920 + '@esbuild/linux-ia32@0.23.1': 1921 + optional: true 1922 + 1923 + '@esbuild/linux-loong64@0.21.5': 1924 + optional: true 1925 + 1926 + '@esbuild/linux-loong64@0.23.1': 1927 + optional: true 1928 + 1929 + '@esbuild/linux-mips64el@0.21.5': 1930 + optional: true 1931 + 1932 + '@esbuild/linux-mips64el@0.23.1': 1933 + optional: true 1934 + 1935 + '@esbuild/linux-ppc64@0.21.5': 1936 + optional: true 1937 + 1938 + '@esbuild/linux-ppc64@0.23.1': 1939 + optional: true 1940 + 1941 + '@esbuild/linux-riscv64@0.21.5': 1942 + optional: true 1943 + 1944 + '@esbuild/linux-riscv64@0.23.1': 1945 + optional: true 1946 + 1947 + '@esbuild/linux-s390x@0.21.5': 1948 + optional: true 1949 + 1950 + '@esbuild/linux-s390x@0.23.1': 1951 + optional: true 1952 + 1953 + '@esbuild/linux-x64@0.21.5': 1954 + optional: true 1955 + 1956 + '@esbuild/linux-x64@0.23.1': 1957 + optional: true 1958 + 1959 + '@esbuild/netbsd-x64@0.21.5': 1960 + optional: true 1961 + 1962 + '@esbuild/netbsd-x64@0.23.1': 1963 + optional: true 1964 + 1965 + '@esbuild/openbsd-arm64@0.23.1': 1966 + optional: true 1967 + 1968 + '@esbuild/openbsd-x64@0.21.5': 1969 + optional: true 1970 + 1971 + '@esbuild/openbsd-x64@0.23.1': 1972 + optional: true 1973 + 1974 + '@esbuild/sunos-x64@0.21.5': 1975 + optional: true 1976 + 1977 + '@esbuild/sunos-x64@0.23.1': 1978 + optional: true 1979 + 1980 + '@esbuild/win32-arm64@0.21.5': 1981 + optional: true 1982 + 1983 + '@esbuild/win32-arm64@0.23.1': 1984 + optional: true 1985 + 1986 + '@esbuild/win32-ia32@0.21.5': 1987 + optional: true 1988 + 1989 + '@esbuild/win32-ia32@0.23.1': 1990 + optional: true 1991 + 1992 + '@esbuild/win32-x64@0.21.5': 1993 + optional: true 1994 + 1995 + '@esbuild/win32-x64@0.23.1': 1996 + optional: true 1997 + 1998 + '@eslint-community/eslint-utils@4.4.1(eslint@9.18.0)': 1999 + dependencies: 2000 + eslint: 9.18.0 2001 + eslint-visitor-keys: 3.4.3 2002 + 2003 + '@eslint-community/regexpp@4.12.1': {} 2004 + 2005 + '@eslint/config-array@0.19.1': 2006 + dependencies: 2007 + '@eslint/object-schema': 2.1.5 2008 + debug: 4.3.7 2009 + minimatch: 3.1.2 2010 + transitivePeerDependencies: 2011 + - supports-color 2012 + 2013 + '@eslint/core@0.10.0': 2014 + dependencies: 2015 + '@types/json-schema': 7.0.15 2016 + 2017 + '@eslint/eslintrc@3.2.0': 2018 + dependencies: 2019 + ajv: 6.12.6 2020 + debug: 4.3.7 2021 + espree: 10.3.0 2022 + globals: 14.0.0 2023 + ignore: 5.3.2 2024 + import-fresh: 3.3.0 2025 + js-yaml: 4.1.0 2026 + minimatch: 3.1.2 2027 + strip-json-comments: 3.1.1 2028 + transitivePeerDependencies: 2029 + - supports-color 2030 + 2031 + '@eslint/js@9.18.0': {} 2032 + 2033 + '@eslint/object-schema@2.1.5': {} 2034 + 2035 + '@eslint/plugin-kit@0.2.5': 2036 + dependencies: 2037 + '@eslint/core': 0.10.0 2038 + levn: 0.4.1 2039 + 2040 + '@humanfs/core@0.19.1': {} 2041 + 2042 + '@humanfs/node@0.16.6': 2043 + dependencies: 2044 + '@humanfs/core': 0.19.1 2045 + '@humanwhocodes/retry': 0.3.1 2046 + 2047 + '@humanwhocodes/module-importer@1.0.1': {} 2048 + 2049 + '@humanwhocodes/retry@0.3.1': {} 2050 + 2051 + '@humanwhocodes/retry@0.4.1': {} 2052 + 2053 + '@jridgewell/sourcemap-codec@1.5.0': {} 2054 + 2055 + '@nodelib/fs.scandir@2.1.5': 2056 + dependencies: 2057 + '@nodelib/fs.stat': 2.0.5 2058 + run-parallel: 1.2.0 2059 + 2060 + '@nodelib/fs.stat@2.0.5': {} 2061 + 2062 + '@nodelib/fs.walk@1.2.8': 2063 + dependencies: 2064 + '@nodelib/fs.scandir': 2.1.5 2065 + fastq: 1.18.0 2066 + 2067 + '@pkgr/core@0.1.1': {} 2068 + 2069 + '@rollup/rollup-android-arm-eabi@4.24.2': 2070 + optional: true 2071 + 2072 + '@rollup/rollup-android-arm64@4.24.2': 2073 + optional: true 2074 + 2075 + '@rollup/rollup-darwin-arm64@4.24.2': 2076 + optional: true 2077 + 2078 + '@rollup/rollup-darwin-x64@4.24.2': 2079 + optional: true 2080 + 2081 + '@rollup/rollup-freebsd-arm64@4.24.2': 2082 + optional: true 2083 + 2084 + '@rollup/rollup-freebsd-x64@4.24.2': 2085 + optional: true 2086 + 2087 + '@rollup/rollup-linux-arm-gnueabihf@4.24.2': 2088 + optional: true 2089 + 2090 + '@rollup/rollup-linux-arm-musleabihf@4.24.2': 2091 + optional: true 2092 + 2093 + '@rollup/rollup-linux-arm64-gnu@4.24.2': 2094 + optional: true 2095 + 2096 + '@rollup/rollup-linux-arm64-musl@4.24.2': 2097 + optional: true 2098 + 2099 + '@rollup/rollup-linux-powerpc64le-gnu@4.24.2': 2100 + optional: true 2101 + 2102 + '@rollup/rollup-linux-riscv64-gnu@4.24.2': 2103 + optional: true 2104 + 2105 + '@rollup/rollup-linux-s390x-gnu@4.24.2': 2106 + optional: true 2107 + 2108 + '@rollup/rollup-linux-x64-gnu@4.24.2': 2109 + optional: true 2110 + 2111 + '@rollup/rollup-linux-x64-musl@4.24.2': 2112 + optional: true 2113 + 2114 + '@rollup/rollup-win32-arm64-msvc@4.24.2': 2115 + optional: true 2116 + 2117 + '@rollup/rollup-win32-ia32-msvc@4.24.2': 2118 + optional: true 2119 + 2120 + '@rollup/rollup-win32-x64-msvc@4.24.2': 2121 + optional: true 2122 + 2123 + '@types/estree@1.0.6': {} 2124 + 2125 + '@types/json-schema@7.0.15': {} 2126 + 2127 + '@types/node@22.7.5': 2128 + dependencies: 2129 + undici-types: 6.19.8 2130 + 2131 + '@typescript-eslint/eslint-plugin@8.20.0(@typescript-eslint/parser@8.20.0(eslint@9.18.0)(typescript@5.7.3))(eslint@9.18.0)(typescript@5.7.3)': 2132 + dependencies: 2133 + '@eslint-community/regexpp': 4.12.1 2134 + '@typescript-eslint/parser': 8.20.0(eslint@9.18.0)(typescript@5.7.3) 2135 + '@typescript-eslint/scope-manager': 8.20.0 2136 + '@typescript-eslint/type-utils': 8.20.0(eslint@9.18.0)(typescript@5.7.3) 2137 + '@typescript-eslint/utils': 8.20.0(eslint@9.18.0)(typescript@5.7.3) 2138 + '@typescript-eslint/visitor-keys': 8.20.0 2139 + eslint: 9.18.0 2140 + graphemer: 1.4.0 2141 + ignore: 5.3.2 2142 + natural-compare: 1.4.0 2143 + ts-api-utils: 2.0.0(typescript@5.7.3) 2144 + typescript: 5.7.3 2145 + transitivePeerDependencies: 2146 + - supports-color 2147 + 2148 + '@typescript-eslint/parser@8.20.0(eslint@9.18.0)(typescript@5.7.3)': 2149 + dependencies: 2150 + '@typescript-eslint/scope-manager': 8.20.0 2151 + '@typescript-eslint/types': 8.20.0 2152 + '@typescript-eslint/typescript-estree': 8.20.0(typescript@5.7.3) 2153 + '@typescript-eslint/visitor-keys': 8.20.0 2154 + debug: 4.3.7 2155 + eslint: 9.18.0 2156 + typescript: 5.7.3 2157 + transitivePeerDependencies: 2158 + - supports-color 2159 + 2160 + '@typescript-eslint/scope-manager@8.20.0': 2161 + dependencies: 2162 + '@typescript-eslint/types': 8.20.0 2163 + '@typescript-eslint/visitor-keys': 8.20.0 2164 + 2165 + '@typescript-eslint/type-utils@8.20.0(eslint@9.18.0)(typescript@5.7.3)': 2166 + dependencies: 2167 + '@typescript-eslint/typescript-estree': 8.20.0(typescript@5.7.3) 2168 + '@typescript-eslint/utils': 8.20.0(eslint@9.18.0)(typescript@5.7.3) 2169 + debug: 4.3.7 2170 + eslint: 9.18.0 2171 + ts-api-utils: 2.0.0(typescript@5.7.3) 2172 + typescript: 5.7.3 2173 + transitivePeerDependencies: 2174 + - supports-color 2175 + 2176 + '@typescript-eslint/types@8.20.0': {} 2177 + 2178 + '@typescript-eslint/typescript-estree@8.20.0(typescript@5.7.3)': 2179 + dependencies: 2180 + '@typescript-eslint/types': 8.20.0 2181 + '@typescript-eslint/visitor-keys': 8.20.0 2182 + debug: 4.3.7 2183 + fast-glob: 3.3.3 2184 + is-glob: 4.0.3 2185 + minimatch: 9.0.5 2186 + semver: 7.6.3 2187 + ts-api-utils: 2.0.0(typescript@5.7.3) 2188 + typescript: 5.7.3 2189 + transitivePeerDependencies: 2190 + - supports-color 2191 + 2192 + '@typescript-eslint/utils@8.20.0(eslint@9.18.0)(typescript@5.7.3)': 2193 + dependencies: 2194 + '@eslint-community/eslint-utils': 4.4.1(eslint@9.18.0) 2195 + '@typescript-eslint/scope-manager': 8.20.0 2196 + '@typescript-eslint/types': 8.20.0 2197 + '@typescript-eslint/typescript-estree': 8.20.0(typescript@5.7.3) 2198 + eslint: 9.18.0 2199 + typescript: 5.7.3 2200 + transitivePeerDependencies: 2201 + - supports-color 2202 + 2203 + '@typescript-eslint/visitor-keys@8.20.0': 2204 + dependencies: 2205 + '@typescript-eslint/types': 8.20.0 2206 + eslint-visitor-keys: 4.2.0 2207 + 2208 + '@vitest/expect@2.1.3': 2209 + dependencies: 2210 + '@vitest/spy': 2.1.3 2211 + '@vitest/utils': 2.1.3 2212 + chai: 5.1.2 2213 + tinyrainbow: 1.2.0 2214 + 2215 + '@vitest/mocker@2.1.3(@vitest/spy@2.1.3)(vite@5.4.10(@types/node@22.7.5))': 632 2216 dependencies: 633 2217 '@vitest/spy': 2.1.3 634 2218 estree-walker: 3.0.3 635 2219 magic-string: 0.30.12 2220 + optionalDependencies: 636 2221 vite: 5.4.10(@types/node@22.7.5) 637 - dev: true 638 2222 639 - /@vitest/pretty-format@2.1.3: 640 - resolution: {integrity: sha512-XH1XdtoLZCpqV59KRbPrIhFCOO0hErxrQCMcvnQete3Vibb9UeIOX02uFPfVn3Z9ZXsq78etlfyhnkmIZSzIwQ==} 2223 + '@vitest/pretty-format@2.1.3': 641 2224 dependencies: 642 2225 tinyrainbow: 1.2.0 643 - dev: true 644 2226 645 - /@vitest/runner@2.1.3: 646 - resolution: {integrity: sha512-JGzpWqmFJ4fq5ZKHtVO3Xuy1iF2rHGV4d/pdzgkYHm1+gOzNZtqjvyiaDGJytRyMU54qkxpNzCx+PErzJ1/JqQ==} 2227 + '@vitest/runner@2.1.3': 647 2228 dependencies: 648 2229 '@vitest/utils': 2.1.3 649 2230 pathe: 1.1.2 650 - dev: true 651 2231 652 - /@vitest/snapshot@2.1.3: 653 - resolution: {integrity: sha512-qWC2mWc7VAXmjAkEKxrScWHWFyCQx/cmiZtuGqMi+WwqQJ2iURsVY4ZfAK6dVo6K2smKRU6l3BPwqEBvhnpQGg==} 2232 + '@vitest/snapshot@2.1.3': 654 2233 dependencies: 655 2234 '@vitest/pretty-format': 2.1.3 656 2235 magic-string: 0.30.12 657 2236 pathe: 1.1.2 658 - dev: true 659 2237 660 - /@vitest/spy@2.1.3: 661 - resolution: {integrity: sha512-Nb2UzbcUswzeSP7JksMDaqsI43Sj5+Kry6ry6jQJT4b5gAK+NS9NED6mDb8FlMRCX8m5guaHCDZmqYMMWRy5nQ==} 2238 + '@vitest/spy@2.1.3': 662 2239 dependencies: 663 2240 tinyspy: 3.0.2 664 - dev: true 665 2241 666 - /@vitest/utils@2.1.3: 667 - resolution: {integrity: sha512-xpiVfDSg1RrYT0tX6czgerkpcKFmFOF/gCr30+Mve5V2kewCy4Prn1/NDMSRwaSmT7PRaOF83wu+bEtsY1wrvA==} 2242 + '@vitest/utils@2.1.3': 668 2243 dependencies: 669 2244 '@vitest/pretty-format': 2.1.3 670 2245 loupe: 3.1.2 671 2246 tinyrainbow: 1.2.0 672 - dev: true 673 2247 674 - /assertion-error@2.0.1: 675 - resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} 676 - engines: {node: '>=12'} 677 - dev: true 2248 + acorn-jsx@5.3.2(acorn@8.14.0): 2249 + dependencies: 2250 + acorn: 8.14.0 2251 + 2252 + acorn@8.14.0: {} 678 2253 679 - /cac@6.7.14: 680 - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} 681 - engines: {node: '>=8'} 682 - dev: true 2254 + ajv@6.12.6: 2255 + dependencies: 2256 + fast-deep-equal: 3.1.3 2257 + fast-json-stable-stringify: 2.1.0 2258 + json-schema-traverse: 0.4.1 2259 + uri-js: 4.4.1 683 2260 684 - /chai@5.1.2: 685 - resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} 686 - engines: {node: '>=12'} 2261 + ansi-styles@4.3.0: 2262 + dependencies: 2263 + color-convert: 2.0.1 2264 + 2265 + argparse@2.0.1: {} 2266 + 2267 + assertion-error@2.0.1: {} 2268 + 2269 + balanced-match@1.0.2: {} 2270 + 2271 + brace-expansion@1.1.11: 2272 + dependencies: 2273 + balanced-match: 1.0.2 2274 + concat-map: 0.0.1 2275 + 2276 + brace-expansion@2.0.1: 2277 + dependencies: 2278 + balanced-match: 1.0.2 2279 + 2280 + braces@3.0.3: 2281 + dependencies: 2282 + fill-range: 7.1.1 2283 + 2284 + cac@6.7.14: {} 2285 + 2286 + callsites@3.1.0: {} 2287 + 2288 + chai@5.1.2: 687 2289 dependencies: 688 2290 assertion-error: 2.0.1 689 2291 check-error: 2.1.1 690 2292 deep-eql: 5.0.2 691 2293 loupe: 3.1.2 692 2294 pathval: 2.0.0 693 - dev: true 694 2295 695 - /check-error@2.1.1: 696 - resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} 697 - engines: {node: '>= 16'} 698 - dev: true 2296 + chalk@4.1.2: 2297 + dependencies: 2298 + ansi-styles: 4.3.0 2299 + supports-color: 7.2.0 699 2300 700 - /citty@0.1.6: 701 - resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} 2301 + check-error@2.1.1: {} 2302 + 2303 + citty@0.1.6: 702 2304 dependencies: 703 2305 consola: 3.2.3 704 - dev: true 705 2306 706 - /consola@3.2.3: 707 - resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} 708 - engines: {node: ^14.18.0 || >=16.10.0} 709 - dev: true 2307 + color-convert@2.0.1: 2308 + dependencies: 2309 + color-name: 1.1.4 2310 + 2311 + color-name@1.1.4: {} 2312 + 2313 + concat-map@0.0.1: {} 2314 + 2315 + consola@3.2.3: {} 2316 + 2317 + cross-spawn@7.0.6: 2318 + dependencies: 2319 + path-key: 3.1.1 2320 + shebang-command: 2.0.0 2321 + which: 2.0.2 710 2322 711 - /debug@4.3.7: 712 - resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} 713 - engines: {node: '>=6.0'} 714 - peerDependencies: 715 - supports-color: '*' 716 - peerDependenciesMeta: 717 - supports-color: 718 - optional: true 2323 + debug@4.3.7: 719 2324 dependencies: 720 2325 ms: 2.1.3 721 - dev: true 722 2326 723 - /deep-eql@5.0.2: 724 - resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} 725 - engines: {node: '>=6'} 726 - dev: true 2327 + deep-eql@5.0.2: {} 2328 + 2329 + deep-is@0.1.4: {} 727 2330 728 - /esbuild@0.21.5: 729 - resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} 730 - engines: {node: '>=12'} 731 - hasBin: true 732 - requiresBuild: true 2331 + esbuild@0.21.5: 733 2332 optionalDependencies: 734 2333 '@esbuild/aix-ppc64': 0.21.5 735 2334 '@esbuild/android-arm': 0.21.5 ··· 754 2353 '@esbuild/win32-arm64': 0.21.5 755 2354 '@esbuild/win32-ia32': 0.21.5 756 2355 '@esbuild/win32-x64': 0.21.5 757 - dev: true 758 2356 759 - /esbuild@0.23.1: 760 - resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==} 761 - engines: {node: '>=18'} 762 - hasBin: true 763 - requiresBuild: true 2357 + esbuild@0.23.1: 764 2358 optionalDependencies: 765 2359 '@esbuild/aix-ppc64': 0.23.1 766 2360 '@esbuild/android-arm': 0.23.1 ··· 786 2380 '@esbuild/win32-arm64': 0.23.1 787 2381 '@esbuild/win32-ia32': 0.23.1 788 2382 '@esbuild/win32-x64': 0.23.1 789 - dev: true 2383 + 2384 + escape-string-regexp@4.0.0: {} 790 2385 791 - /estree-walker@3.0.3: 792 - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} 2386 + eslint-config-prettier@10.0.1(eslint@9.18.0): 2387 + dependencies: 2388 + eslint: 9.18.0 2389 + 2390 + eslint-plugin-prettier@5.2.2(eslint-config-prettier@10.0.1(eslint@9.18.0))(eslint@9.18.0)(prettier@3.4.2): 793 2391 dependencies: 2392 + eslint: 9.18.0 2393 + prettier: 3.4.2 2394 + prettier-linter-helpers: 1.0.0 2395 + synckit: 0.9.2 2396 + optionalDependencies: 2397 + eslint-config-prettier: 10.0.1(eslint@9.18.0) 2398 + 2399 + eslint-scope@8.2.0: 2400 + dependencies: 2401 + esrecurse: 4.3.0 2402 + estraverse: 5.3.0 2403 + 2404 + eslint-visitor-keys@3.4.3: {} 2405 + 2406 + eslint-visitor-keys@4.2.0: {} 2407 + 2408 + eslint@9.18.0: 2409 + dependencies: 2410 + '@eslint-community/eslint-utils': 4.4.1(eslint@9.18.0) 2411 + '@eslint-community/regexpp': 4.12.1 2412 + '@eslint/config-array': 0.19.1 2413 + '@eslint/core': 0.10.0 2414 + '@eslint/eslintrc': 3.2.0 2415 + '@eslint/js': 9.18.0 2416 + '@eslint/plugin-kit': 0.2.5 2417 + '@humanfs/node': 0.16.6 2418 + '@humanwhocodes/module-importer': 1.0.1 2419 + '@humanwhocodes/retry': 0.4.1 794 2420 '@types/estree': 1.0.6 795 - dev: true 2421 + '@types/json-schema': 7.0.15 2422 + ajv: 6.12.6 2423 + chalk: 4.1.2 2424 + cross-spawn: 7.0.6 2425 + debug: 4.3.7 2426 + escape-string-regexp: 4.0.0 2427 + eslint-scope: 8.2.0 2428 + eslint-visitor-keys: 4.2.0 2429 + espree: 10.3.0 2430 + esquery: 1.6.0 2431 + esutils: 2.0.3 2432 + fast-deep-equal: 3.1.3 2433 + file-entry-cache: 8.0.0 2434 + find-up: 5.0.0 2435 + glob-parent: 6.0.2 2436 + ignore: 5.3.2 2437 + imurmurhash: 0.1.4 2438 + is-glob: 4.0.3 2439 + json-stable-stringify-without-jsonify: 1.0.1 2440 + lodash.merge: 4.6.2 2441 + minimatch: 3.1.2 2442 + natural-compare: 1.4.0 2443 + optionator: 0.9.4 2444 + transitivePeerDependencies: 2445 + - supports-color 2446 + 2447 + espree@10.3.0: 2448 + dependencies: 2449 + acorn: 8.14.0 2450 + acorn-jsx: 5.3.2(acorn@8.14.0) 2451 + eslint-visitor-keys: 4.2.0 2452 + 2453 + esquery@1.6.0: 2454 + dependencies: 2455 + estraverse: 5.3.0 2456 + 2457 + esrecurse@4.3.0: 2458 + dependencies: 2459 + estraverse: 5.3.0 2460 + 2461 + estraverse@5.3.0: {} 2462 + 2463 + estree-walker@3.0.3: 2464 + dependencies: 2465 + '@types/estree': 1.0.6 2466 + 2467 + esutils@2.0.3: {} 2468 + 2469 + fast-deep-equal@3.1.3: {} 2470 + 2471 + fast-diff@1.3.0: {} 2472 + 2473 + fast-glob@3.3.3: 2474 + dependencies: 2475 + '@nodelib/fs.stat': 2.0.5 2476 + '@nodelib/fs.walk': 1.2.8 2477 + glob-parent: 5.1.2 2478 + merge2: 1.4.1 2479 + micromatch: 4.0.8 2480 + 2481 + fast-json-stable-stringify@2.1.0: {} 2482 + 2483 + fast-levenshtein@2.0.6: {} 2484 + 2485 + fastq@1.18.0: 2486 + dependencies: 2487 + reusify: 1.0.4 796 2488 797 - /fsevents@2.3.3: 798 - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 799 - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 800 - os: [darwin] 801 - requiresBuild: true 802 - dev: true 2489 + file-entry-cache@8.0.0: 2490 + dependencies: 2491 + flat-cache: 4.0.1 2492 + 2493 + fill-range@7.1.1: 2494 + dependencies: 2495 + to-regex-range: 5.0.1 2496 + 2497 + find-up@5.0.0: 2498 + dependencies: 2499 + locate-path: 6.0.0 2500 + path-exists: 4.0.0 2501 + 2502 + flat-cache@4.0.1: 2503 + dependencies: 2504 + flatted: 3.3.2 2505 + keyv: 4.5.4 2506 + 2507 + flatted@3.3.2: {} 2508 + 2509 + fsevents@2.3.3: 803 2510 optional: true 804 2511 805 - /get-tsconfig@4.8.1: 806 - resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} 2512 + get-tsconfig@4.8.1: 807 2513 dependencies: 808 2514 resolve-pkg-maps: 1.0.0 809 - dev: true 2515 + 2516 + glob-parent@5.1.2: 2517 + dependencies: 2518 + is-glob: 4.0.3 2519 + 2520 + glob-parent@6.0.2: 2521 + dependencies: 2522 + is-glob: 4.0.3 2523 + 2524 + globals@14.0.0: {} 2525 + 2526 + graphemer@1.4.0: {} 2527 + 2528 + has-flag@4.0.0: {} 2529 + 2530 + ignore@5.3.2: {} 2531 + 2532 + import-fresh@3.3.0: 2533 + dependencies: 2534 + parent-module: 1.0.1 2535 + resolve-from: 4.0.0 2536 + 2537 + imurmurhash@0.1.4: {} 2538 + 2539 + is-extglob@2.1.1: {} 2540 + 2541 + is-glob@4.0.3: 2542 + dependencies: 2543 + is-extglob: 2.1.1 2544 + 2545 + is-number@7.0.0: {} 2546 + 2547 + isexe@2.0.0: {} 2548 + 2549 + js-yaml@4.1.0: 2550 + dependencies: 2551 + argparse: 2.0.1 2552 + 2553 + json-buffer@3.0.1: {} 2554 + 2555 + json-schema-traverse@0.4.1: {} 810 2556 811 - /loupe@3.1.2: 812 - resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} 813 - dev: true 2557 + json-stable-stringify-without-jsonify@1.0.1: {} 2558 + 2559 + keyv@4.5.4: 2560 + dependencies: 2561 + json-buffer: 3.0.1 2562 + 2563 + levn@0.4.1: 2564 + dependencies: 2565 + prelude-ls: 1.2.1 2566 + type-check: 0.4.0 814 2567 815 - /magic-string@0.30.12: 816 - resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} 2568 + locate-path@6.0.0: 2569 + dependencies: 2570 + p-locate: 5.0.0 2571 + 2572 + lodash.merge@4.6.2: {} 2573 + 2574 + loupe@3.1.2: {} 2575 + 2576 + magic-string@0.30.12: 817 2577 dependencies: 818 2578 '@jridgewell/sourcemap-codec': 1.5.0 819 - dev: true 2579 + 2580 + merge2@1.4.1: {} 2581 + 2582 + micromatch@4.0.8: 2583 + dependencies: 2584 + braces: 3.0.3 2585 + picomatch: 2.3.1 2586 + 2587 + minimatch@3.1.2: 2588 + dependencies: 2589 + brace-expansion: 1.1.11 2590 + 2591 + minimatch@9.0.5: 2592 + dependencies: 2593 + brace-expansion: 2.0.1 2594 + 2595 + mri@1.2.0: {} 2596 + 2597 + ms@2.1.3: {} 2598 + 2599 + nanoid@3.3.7: {} 820 2600 821 - /mri@1.2.0: 822 - resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} 823 - engines: {node: '>=4'} 824 - dev: false 2601 + natural-compare@1.4.0: {} 2602 + 2603 + optionator@0.9.4: 2604 + dependencies: 2605 + deep-is: 0.1.4 2606 + fast-levenshtein: 2.0.6 2607 + levn: 0.4.1 2608 + prelude-ls: 1.2.1 2609 + type-check: 0.4.0 2610 + word-wrap: 1.2.5 2611 + 2612 + p-limit@3.1.0: 2613 + dependencies: 2614 + yocto-queue: 0.1.0 2615 + 2616 + p-locate@5.0.0: 2617 + dependencies: 2618 + p-limit: 3.1.0 2619 + 2620 + parent-module@1.0.1: 2621 + dependencies: 2622 + callsites: 3.1.0 2623 + 2624 + path-exists@4.0.0: {} 825 2625 826 - /ms@2.1.3: 827 - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 828 - dev: true 2626 + path-key@3.1.1: {} 829 2627 830 - /nanoid@3.3.7: 831 - resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} 832 - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 833 - hasBin: true 834 - dev: true 2628 + pathe@1.1.2: {} 835 2629 836 - /pathe@1.1.2: 837 - resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} 838 - dev: true 2630 + pathval@2.0.0: {} 839 2631 840 - /pathval@2.0.0: 841 - resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} 842 - engines: {node: '>= 14.16'} 843 - dev: true 2632 + picocolors@1.1.1: {} 844 2633 845 - /picocolors@1.1.1: 846 - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} 847 - dev: true 2634 + picomatch@2.3.1: {} 848 2635 849 - /postcss@8.4.47: 850 - resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} 851 - engines: {node: ^10 || ^12 || >=14} 2636 + postcss@8.4.47: 852 2637 dependencies: 853 2638 nanoid: 3.3.7 854 2639 picocolors: 1.1.1 855 2640 source-map-js: 1.2.1 856 - dev: true 2641 + 2642 + prelude-ls@1.2.1: {} 2643 + 2644 + prettier-linter-helpers@1.0.0: 2645 + dependencies: 2646 + fast-diff: 1.3.0 2647 + 2648 + prettier@3.4.2: {} 2649 + 2650 + punycode@2.3.1: {} 2651 + 2652 + queue-microtask@1.2.3: {} 2653 + 2654 + resolve-from@4.0.0: {} 2655 + 2656 + resolve-pkg-maps@1.0.0: {} 857 2657 858 - /resolve-pkg-maps@1.0.0: 859 - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} 860 - dev: true 2658 + reusify@1.0.4: {} 861 2659 862 - /rollup@4.24.2: 863 - resolution: {integrity: sha512-do/DFGq5g6rdDhdpPq5qb2ecoczeK6y+2UAjdJ5trjQJj5f1AiVdLRWRc9A9/fFukfvJRgM0UXzxBIYMovm5ww==} 864 - engines: {node: '>=18.0.0', npm: '>=8.0.0'} 865 - hasBin: true 2660 + rollup@4.24.2: 866 2661 dependencies: 867 2662 '@types/estree': 1.0.6 868 2663 optionalDependencies: ··· 885 2680 '@rollup/rollup-win32-ia32-msvc': 4.24.2 886 2681 '@rollup/rollup-win32-x64-msvc': 4.24.2 887 2682 fsevents: 2.3.3 888 - dev: true 889 2683 890 - /siginfo@2.0.0: 891 - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} 892 - dev: true 2684 + run-parallel@1.2.0: 2685 + dependencies: 2686 + queue-microtask: 1.2.3 893 2687 894 - /source-map-js@1.2.1: 895 - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} 896 - engines: {node: '>=0.10.0'} 897 - dev: true 2688 + semver@7.6.3: {} 2689 + 2690 + shebang-command@2.0.0: 2691 + dependencies: 2692 + shebang-regex: 3.0.0 2693 + 2694 + shebang-regex@3.0.0: {} 2695 + 2696 + siginfo@2.0.0: {} 2697 + 2698 + source-map-js@1.2.1: {} 2699 + 2700 + stackback@0.0.2: {} 2701 + 2702 + std-env@3.7.0: {} 2703 + 2704 + strip-json-comments@3.1.1: {} 2705 + 2706 + supports-color@7.2.0: 2707 + dependencies: 2708 + has-flag: 4.0.0 2709 + 2710 + synckit@0.9.2: 2711 + dependencies: 2712 + '@pkgr/core': 0.1.1 2713 + tslib: 2.8.1 2714 + 2715 + tinybench@2.9.0: {} 898 2716 899 - /stackback@0.0.2: 900 - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} 901 - dev: true 2717 + tinyexec@0.3.1: {} 902 2718 903 - /std-env@3.7.0: 904 - resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} 905 - dev: true 2719 + tinypool@1.0.1: {} 906 2720 907 - /tinybench@2.9.0: 908 - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} 909 - dev: true 2721 + tinyrainbow@1.2.0: {} 910 2722 911 - /tinyexec@0.3.1: 912 - resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} 913 - dev: true 2723 + tinyspy@3.0.2: {} 914 2724 915 - /tinypool@1.0.1: 916 - resolution: {integrity: sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==} 917 - engines: {node: ^18.0.0 || >=20.0.0} 918 - dev: true 2725 + to-regex-range@5.0.1: 2726 + dependencies: 2727 + is-number: 7.0.0 919 2728 920 - /tinyrainbow@1.2.0: 921 - resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} 922 - engines: {node: '>=14.0.0'} 923 - dev: true 2729 + ts-api-utils@2.0.0(typescript@5.7.3): 2730 + dependencies: 2731 + typescript: 5.7.3 924 2732 925 - /tinyspy@3.0.2: 926 - resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} 927 - engines: {node: '>=14.0.0'} 928 - dev: true 2733 + tslib@2.8.1: {} 929 2734 930 - /tsx@4.19.1: 931 - resolution: {integrity: sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==} 932 - engines: {node: '>=18.0.0'} 933 - hasBin: true 2735 + tsx@4.19.1: 934 2736 dependencies: 935 2737 esbuild: 0.23.1 936 2738 get-tsconfig: 4.8.1 937 2739 optionalDependencies: 938 2740 fsevents: 2.3.3 939 - dev: true 2741 + 2742 + type-check@0.4.0: 2743 + dependencies: 2744 + prelude-ls: 1.2.1 2745 + 2746 + typescript@5.7.3: {} 940 2747 941 - /undici-types@6.19.8: 942 - resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} 943 - dev: true 2748 + undici-types@6.19.8: {} 944 2749 945 - /vite-node@2.1.3(@types/node@22.7.5): 946 - resolution: {integrity: sha512-I1JadzO+xYX887S39Do+paRePCKoiDrWRRjp9kkG5he0t7RXNvPAJPCQSJqbGN4uCrFFeS3Kj3sLqY8NMYBEdA==} 947 - engines: {node: ^18.0.0 || >=20.0.0} 948 - hasBin: true 2750 + uri-js@4.4.1: 2751 + dependencies: 2752 + punycode: 2.3.1 2753 + 2754 + vite-node@2.1.3(@types/node@22.7.5): 949 2755 dependencies: 950 2756 cac: 6.7.14 951 2757 debug: 4.3.7 ··· 961 2767 - sugarss 962 2768 - supports-color 963 2769 - terser 964 - dev: true 965 2770 966 - /vite@5.4.10(@types/node@22.7.5): 967 - resolution: {integrity: sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==} 968 - engines: {node: ^18.0.0 || >=20.0.0} 969 - hasBin: true 970 - peerDependencies: 971 - '@types/node': ^18.0.0 || >=20.0.0 972 - less: '*' 973 - lightningcss: ^1.21.0 974 - sass: '*' 975 - sass-embedded: '*' 976 - stylus: '*' 977 - sugarss: '*' 978 - terser: ^5.4.0 979 - peerDependenciesMeta: 980 - '@types/node': 981 - optional: true 982 - less: 983 - optional: true 984 - lightningcss: 985 - optional: true 986 - sass: 987 - optional: true 988 - sass-embedded: 989 - optional: true 990 - stylus: 991 - optional: true 992 - sugarss: 993 - optional: true 994 - terser: 995 - optional: true 2771 + vite@5.4.10(@types/node@22.7.5): 996 2772 dependencies: 997 - '@types/node': 22.7.5 998 2773 esbuild: 0.21.5 999 2774 postcss: 8.4.47 1000 2775 rollup: 4.24.2 1001 2776 optionalDependencies: 2777 + '@types/node': 22.7.5 1002 2778 fsevents: 2.3.3 1003 - dev: true 1004 2779 1005 - /vitest@2.1.3(@types/node@22.7.5): 1006 - resolution: {integrity: sha512-Zrxbg/WiIvUP2uEzelDNTXmEMJXuzJ1kCpbDvaKByFA9MNeO95V+7r/3ti0qzJzrxdyuUw5VduN7k+D3VmVOSA==} 1007 - engines: {node: ^18.0.0 || >=20.0.0} 1008 - hasBin: true 1009 - peerDependencies: 1010 - '@edge-runtime/vm': '*' 1011 - '@types/node': ^18.0.0 || >=20.0.0 1012 - '@vitest/browser': 2.1.3 1013 - '@vitest/ui': 2.1.3 1014 - happy-dom: '*' 1015 - jsdom: '*' 1016 - peerDependenciesMeta: 1017 - '@edge-runtime/vm': 1018 - optional: true 1019 - '@types/node': 1020 - optional: true 1021 - '@vitest/browser': 1022 - optional: true 1023 - '@vitest/ui': 1024 - optional: true 1025 - happy-dom: 1026 - optional: true 1027 - jsdom: 1028 - optional: true 2780 + vitest@2.1.3(@types/node@22.7.5): 1029 2781 dependencies: 1030 - '@types/node': 22.7.5 1031 2782 '@vitest/expect': 2.1.3 1032 - '@vitest/mocker': 2.1.3(@vitest/spy@2.1.3)(vite@5.4.10) 2783 + '@vitest/mocker': 2.1.3(@vitest/spy@2.1.3)(vite@5.4.10(@types/node@22.7.5)) 1033 2784 '@vitest/pretty-format': 2.1.3 1034 2785 '@vitest/runner': 2.1.3 1035 2786 '@vitest/snapshot': 2.1.3 ··· 1047 2798 vite: 5.4.10(@types/node@22.7.5) 1048 2799 vite-node: 2.1.3(@types/node@22.7.5) 1049 2800 why-is-node-running: 2.3.0 2801 + optionalDependencies: 2802 + '@types/node': 22.7.5 1050 2803 transitivePeerDependencies: 1051 2804 - less 1052 2805 - lightningcss ··· 1057 2810 - sugarss 1058 2811 - supports-color 1059 2812 - terser 1060 - dev: true 2813 + 2814 + which@2.0.2: 2815 + dependencies: 2816 + isexe: 2.0.0 1061 2817 1062 - /why-is-node-running@2.3.0: 1063 - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} 1064 - engines: {node: '>=8'} 1065 - hasBin: true 2818 + why-is-node-running@2.3.0: 1066 2819 dependencies: 1067 2820 siginfo: 2.0.0 1068 2821 stackback: 0.0.2 1069 - dev: true 2822 + 2823 + word-wrap@1.2.5: {} 2824 + 2825 + yocto-queue@0.1.0: {}
+275 -275
powershell.ts src/powershell.ts
··· 1 - import { ShellCompDirective } from "./shared"; 2 - 3 - // TODO: issue with -- -- completions 4 - 5 - export function generate( 6 - name: string, 7 - exec: string, 8 - includeDesc = false 9 - ): string { 10 - // Replace '-' and ':' with '_' for variable names 11 - const nameForVar = name.replace(/[-:]/g, "_"); 12 - 13 - // Determine the completion command 14 - // const compCmd = includeDesc ? "complete" : "complete"; 15 - 16 - // Shell completion directives 17 - const ShellCompDirectiveError = ShellCompDirective.ShellCompDirectiveError; 18 - const ShellCompDirectiveNoSpace = 19 - ShellCompDirective.ShellCompDirectiveNoSpace; 20 - const ShellCompDirectiveNoFileComp = 21 - ShellCompDirective.ShellCompDirectiveNoFileComp; 22 - const ShellCompDirectiveFilterFileExt = 23 - ShellCompDirective.ShellCompDirectiveFilterFileExt; 24 - const ShellCompDirectiveFilterDirs = 25 - ShellCompDirective.ShellCompDirectiveFilterDirs; 26 - const ShellCompDirectiveKeepOrder = 27 - ShellCompDirective.ShellCompDirectiveKeepOrder; 28 - 29 - return `# powershell completion for ${name} -*- shell-script -*- 30 - 31 - [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 32 - function __${name}_debug { 33 - if ($env:BASH_COMP_DEBUG_FILE) { 34 - "$args" | Out-File -Append -FilePath "$env:BASH_COMP_DEBUG_FILE" 35 - } 36 - } 37 - 38 - filter __${name}_escapeStringWithSpecialChars { 39 - $_ -replace '\\s|#|@|\\$|;|,|''|\\{|\\}|\\(|\\)|"|\\||<|>|&','\`$&' 40 - } 41 - 42 - [scriptblock]$__${nameForVar}CompleterBlock = { 43 - param( 44 - $WordToComplete, 45 - $CommandAst, 46 - $CursorPosition 47 - ) 48 - 49 - # Get the current command line and convert into a string 50 - $Command = $CommandAst.CommandElements 51 - $Command = "$Command" 52 - 53 - __${name}_debug "" 54 - __${name}_debug "========= starting completion logic ==========" 55 - __${name}_debug "WordToComplete: $WordToComplete Command: $Command CursorPosition: $CursorPosition" 56 - 57 - # The user could have moved the cursor backwards on the command-line. 58 - # We need to trigger completion from the $CursorPosition location, so we need 59 - # to truncate the command-line ($Command) up to the $CursorPosition location. 60 - # Make sure the $Command is longer then the $CursorPosition before we truncate. 61 - # This happens because the $Command does not include the last space. 62 - if ($Command.Length -gt $CursorPosition) { 63 - $Command = $Command.Substring(0, $CursorPosition) 64 - } 65 - __${name}_debug "Truncated command: $Command" 66 - 67 - $ShellCompDirectiveError=${ShellCompDirectiveError} 68 - $ShellCompDirectiveNoSpace=${ShellCompDirectiveNoSpace} 69 - $ShellCompDirectiveNoFileComp=${ShellCompDirectiveNoFileComp} 70 - $ShellCompDirectiveFilterFileExt=${ShellCompDirectiveFilterFileExt} 71 - $ShellCompDirectiveFilterDirs=${ShellCompDirectiveFilterDirs} 72 - $ShellCompDirectiveKeepOrder=${ShellCompDirectiveKeepOrder} 73 - 74 - # Prepare the command to request completions for the program. 75 - # Split the command at the first space to separate the program and arguments. 76 - $Program, $Arguments = $Command.Split(" ", 2) 77 - 78 - $RequestComp = "& ${exec} complete -- $Arguments" 79 - __${name}_debug "RequestComp: $RequestComp" 80 - 81 - # we cannot use $WordToComplete because it 82 - # has the wrong values if the cursor was moved 83 - # so use the last argument 84 - if ($WordToComplete -ne "" ) { 85 - $WordToComplete = $Arguments.Split(" ")[-1] 86 - } 87 - __${name}_debug "New WordToComplete: $WordToComplete" 88 - 89 - 90 - # Check for flag with equal sign 91 - $IsEqualFlag = ($WordToComplete -Like "--*=*" ) 92 - if ( $IsEqualFlag ) { 93 - __${name}_debug "Completing equal sign flag" 94 - # Remove the flag part 95 - $Flag, $WordToComplete = $WordToComplete.Split("=", 2) 96 - } 97 - 98 - if ( $WordToComplete -eq "" -And ( -Not $IsEqualFlag )) { 99 - # If the last parameter is complete (there is a space following it) 100 - # We add an extra empty parameter so we can indicate this to the go method. 101 - __${name}_debug "Adding extra empty parameter" 102 - # PowerShell 7.2+ changed the way how the arguments are passed to executables, 103 - # so for pre-7.2 or when Legacy argument passing is enabled we need to use 104 - if ($PSVersionTable.PsVersion -lt [version]'7.2.0' -or 105 - ($PSVersionTable.PsVersion -lt [version]'7.3.0' -and -not [ExperimentalFeature]::IsEnabled("PSNativeCommandArgumentPassing")) -or 106 - (($PSVersionTable.PsVersion -ge [version]'7.3.0' -or [ExperimentalFeature]::IsEnabled("PSNativeCommandArgumentPassing")) -and 107 - $PSNativeCommandArgumentPassing -eq 'Legacy')) { 108 - $RequestComp="$RequestComp" + ' \`"\`"' 109 - } else { 110 - $RequestComp = "$RequestComp" + ' ""' 111 - } 112 - } 113 - 114 - __${name}_debug "Calling $RequestComp" 115 - # First disable ActiveHelp which is not supported for Powershell 116 - $env:ActiveHelp = 0 117 - 118 - # call the command store the output in $out and redirect stderr and stdout to null 119 - # $Out is an array contains each line per element 120 - Invoke-Expression -OutVariable out "$RequestComp" 2>&1 | Out-Null 121 - 122 - # get directive from last line 123 - [int]$Directive = $Out[-1].TrimStart(':') 124 - if ($Directive -eq "") { 125 - # There is no directive specified 126 - $Directive = 0 127 - } 128 - __${name}_debug "The completion directive is: $Directive" 129 - 130 - # remove directive (last element) from out 131 - $Out = $Out | Where-Object { $_ -ne $Out[-1] } 132 - __${name}_debug "The completions are: $Out" 133 - 134 - if (($Directive -band $ShellCompDirectiveError) -ne 0 ) { 135 - # Error code. No completion. 136 - __${name}_debug "Received error from custom completion go code" 137 - return 138 - } 139 - 140 - $Longest = 0 141 - [Array]$Values = $Out | ForEach-Object { 142 - # Split the output in name and description 143 - $Name, $Description = $_.Split("\`t", 2) 144 - __${name}_debug "Name: $Name Description: $Description" 145 - 146 - # Look for the longest completion so that we can format things nicely 147 - if ($Longest -lt $Name.Length) { 148 - $Longest = $Name.Length 149 - } 150 - 151 - # Set the description to a one space string if there is none set. 152 - # This is needed because the CompletionResult does not accept an empty string as argument 153 - if (-Not $Description) { 154 - $Description = " " 155 - } 156 - @{ Name = "$Name"; Description = "$Description" } 157 - } 158 - 159 - 160 - $Space = " " 161 - if (($Directive -band $ShellCompDirectiveNoSpace) -ne 0 ) { 162 - # remove the space here 163 - __${name}_debug "ShellCompDirectiveNoSpace is called" 164 - $Space = "" 165 - } 166 - 167 - if ((($Directive -band $ShellCompDirectiveFilterFileExt) -ne 0 ) -or 168 - (($Directive -band $ShellCompDirectiveFilterDirs) -ne 0 )) { 169 - __${name}_debug "ShellCompDirectiveFilterFileExt ShellCompDirectiveFilterDirs are not supported" 170 - 171 - # return here to prevent the completion of the extensions 172 - return 173 - } 174 - 175 - $Values = $Values | Where-Object { 176 - # filter the result 177 - $_.Name -like "$WordToComplete*" 178 - 179 - # Join the flag back if we have an equal sign flag 180 - if ( $IsEqualFlag ) { 181 - __${name}_debug "Join the equal sign flag back to the completion value" 182 - $_.Name = $Flag + "=" + $_.Name 183 - } 184 - } 185 - 186 - # we sort the values in ascending order by name if keep order isn't passed 187 - if (($Directive -band $ShellCompDirectiveKeepOrder) -eq 0 ) { 188 - $Values = $Values | Sort-Object -Property Name 189 - } 190 - 191 - if (($Directive -band $ShellCompDirectiveNoFileComp) -ne 0 ) { 192 - __${name}_debug "ShellCompDirectiveNoFileComp is called" 193 - 194 - if ($Values.Length -eq 0) { 195 - # Just print an empty string here so the 196 - # shell does not start to complete paths. 197 - # We cannot use CompletionResult here because 198 - # it does not accept an empty string as argument. 199 - "" 200 - return 201 - } 202 - } 203 - 204 - # Get the current mode 205 - $Mode = (Get-PSReadLineKeyHandler | Where-Object { $_.Key -eq "Tab" }).Function 206 - __${name}_debug "Mode: $Mode" 207 - 208 - $Values | ForEach-Object { 209 - 210 - # store temporary because switch will overwrite $_ 211 - $comp = $_ 212 - 213 - # PowerShell supports three different completion modes 214 - # - TabCompleteNext (default windows style - on each key press the next option is displayed) 215 - # - Complete (works like bash) 216 - # - MenuComplete (works like zsh) 217 - # You set the mode with Set-PSReadLineKeyHandler -Key Tab -Function <mode> 218 - 219 - # CompletionResult Arguments: 220 - # 1) CompletionText text to be used as the auto completion result 221 - # 2) ListItemText text to be displayed in the suggestion list 222 - # 3) ResultType type of completion result 223 - # 4) ToolTip text for the tooltip with details about the object 224 - 225 - switch ($Mode) { 226 - 227 - # bash like 228 - "Complete" { 229 - 230 - if ($Values.Length -eq 1) { 231 - __${name}_debug "Only one completion left" 232 - 233 - # insert space after value 234 - [System.Management.Automation.CompletionResult]::new($($comp.Name | __${name}_escapeStringWithSpecialChars) + $Space, "$($comp.Name)", 'ParameterValue', "$($comp.Description)") 235 - 236 - } else { 237 - # Add the proper number of spaces to align the descriptions 238 - while($comp.Name.Length -lt $Longest) { 239 - $comp.Name = $comp.Name + " " 240 - } 241 - 242 - # Check for empty description and only add parentheses if needed 243 - if ($($comp.Description) -eq " " ) { 244 - $Description = "" 245 - } else { 246 - $Description = " ($($comp.Description))" 247 - } 248 - 249 - [System.Management.Automation.CompletionResult]::new("$($comp.Name)$Description", "$($comp.Name)$Description", 'ParameterValue', "$($comp.Description)") 250 - } 251 - } 252 - 253 - # zsh like 254 - "MenuComplete" { 255 - # insert space after value 256 - # MenuComplete will automatically show the ToolTip of 257 - # the highlighted value at the bottom of the suggestions. 258 - [System.Management.Automation.CompletionResult]::new($($comp.Name | __${name}_escapeStringWithSpecialChars) + $Space, "$($comp.Name)", 'ParameterValue', "$($comp.Description)") 259 - } 260 - 261 - # TabCompleteNext and in case we get something unknown 262 - Default { 263 - # Like MenuComplete but we don't want to add a space here because 264 - # the user need to press space anyway to get the completion. 265 - # Description will not be shown because that's not possible with TabCompleteNext 266 - [System.Management.Automation.CompletionResult]::new($($comp.Name | __${name}_escapeStringWithSpecialChars), "$($comp.Name)", 'ParameterValue', "$($comp.Description)") 267 - } 268 - } 269 - 270 - } 271 - } 272 - 273 - Register-ArgumentCompleter -CommandName '${name}' -ScriptBlock $__${nameForVar}CompleterBlock 274 - `; 275 - } 1 + import { ShellCompDirective } from './'; 2 + 3 + // TODO: issue with -- -- completions 4 + 5 + export function generate( 6 + name: string, 7 + exec: string, 8 + includeDesc = false 9 + ): string { 10 + // Replace '-' and ':' with '_' for variable names 11 + const nameForVar = name.replace(/[-:]/g, '_'); 12 + 13 + // Determine the completion command 14 + // const compCmd = includeDesc ? "complete" : "complete"; 15 + 16 + // Shell completion directives 17 + const ShellCompDirectiveError = ShellCompDirective.ShellCompDirectiveError; 18 + const ShellCompDirectiveNoSpace = 19 + ShellCompDirective.ShellCompDirectiveNoSpace; 20 + const ShellCompDirectiveNoFileComp = 21 + ShellCompDirective.ShellCompDirectiveNoFileComp; 22 + const ShellCompDirectiveFilterFileExt = 23 + ShellCompDirective.ShellCompDirectiveFilterFileExt; 24 + const ShellCompDirectiveFilterDirs = 25 + ShellCompDirective.ShellCompDirectiveFilterDirs; 26 + const ShellCompDirectiveKeepOrder = 27 + ShellCompDirective.ShellCompDirectiveKeepOrder; 28 + 29 + return `# powershell completion for ${name} -*- shell-script -*- 30 + 31 + [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 32 + function __${name}_debug { 33 + if ($env:BASH_COMP_DEBUG_FILE) { 34 + "$args" | Out-File -Append -FilePath "$env:BASH_COMP_DEBUG_FILE" 35 + } 36 + } 37 + 38 + filter __${name}_escapeStringWithSpecialChars { 39 + $_ -replace '\\s|#|@|\\$|;|,|''|\\{|\\}|\\(|\\)|"|\\||<|>|&','\`$&' 40 + } 41 + 42 + [scriptblock]$__${nameForVar}CompleterBlock = { 43 + param( 44 + $WordToComplete, 45 + $CommandAst, 46 + $CursorPosition 47 + ) 48 + 49 + # Get the current command line and convert into a string 50 + $Command = $CommandAst.CommandElements 51 + $Command = "$Command" 52 + 53 + __${name}_debug "" 54 + __${name}_debug "========= starting completion logic ==========" 55 + __${name}_debug "WordToComplete: $WordToComplete Command: $Command CursorPosition: $CursorPosition" 56 + 57 + # The user could have moved the cursor backwards on the command-line. 58 + # We need to trigger completion from the $CursorPosition location, so we need 59 + # to truncate the command-line ($Command) up to the $CursorPosition location. 60 + # Make sure the $Command is longer then the $CursorPosition before we truncate. 61 + # This happens because the $Command does not include the last space. 62 + if ($Command.Length -gt $CursorPosition) { 63 + $Command = $Command.Substring(0, $CursorPosition) 64 + } 65 + __${name}_debug "Truncated command: $Command" 66 + 67 + $ShellCompDirectiveError=${ShellCompDirectiveError} 68 + $ShellCompDirectiveNoSpace=${ShellCompDirectiveNoSpace} 69 + $ShellCompDirectiveNoFileComp=${ShellCompDirectiveNoFileComp} 70 + $ShellCompDirectiveFilterFileExt=${ShellCompDirectiveFilterFileExt} 71 + $ShellCompDirectiveFilterDirs=${ShellCompDirectiveFilterDirs} 72 + $ShellCompDirectiveKeepOrder=${ShellCompDirectiveKeepOrder} 73 + 74 + # Prepare the command to request completions for the program. 75 + # Split the command at the first space to separate the program and arguments. 76 + $Program, $Arguments = $Command.Split(" ", 2) 77 + 78 + $RequestComp = "& ${exec} complete -- $Arguments" 79 + __${name}_debug "RequestComp: $RequestComp" 80 + 81 + # we cannot use $WordToComplete because it 82 + # has the wrong values if the cursor was moved 83 + # so use the last argument 84 + if ($WordToComplete -ne "" ) { 85 + $WordToComplete = $Arguments.Split(" ")[-1] 86 + } 87 + __${name}_debug "New WordToComplete: $WordToComplete" 88 + 89 + 90 + # Check for flag with equal sign 91 + $IsEqualFlag = ($WordToComplete -Like "--*=*" ) 92 + if ( $IsEqualFlag ) { 93 + __${name}_debug "Completing equal sign flag" 94 + # Remove the flag part 95 + $Flag, $WordToComplete = $WordToComplete.Split("=", 2) 96 + } 97 + 98 + if ( $WordToComplete -eq "" -And ( -Not $IsEqualFlag )) { 99 + # If the last parameter is complete (there is a space following it) 100 + # We add an extra empty parameter so we can indicate this to the go method. 101 + __${name}_debug "Adding extra empty parameter" 102 + # PowerShell 7.2+ changed the way how the arguments are passed to executables, 103 + # so for pre-7.2 or when Legacy argument passing is enabled we need to use 104 + if ($PSVersionTable.PsVersion -lt [version]'7.2.0' -or 105 + ($PSVersionTable.PsVersion -lt [version]'7.3.0' -and -not [ExperimentalFeature]::IsEnabled("PSNativeCommandArgumentPassing")) -or 106 + (($PSVersionTable.PsVersion -ge [version]'7.3.0' -or [ExperimentalFeature]::IsEnabled("PSNativeCommandArgumentPassing")) -and 107 + $PSNativeCommandArgumentPassing -eq 'Legacy')) { 108 + $RequestComp="$RequestComp" + ' \`"\`"' 109 + } else { 110 + $RequestComp = "$RequestComp" + ' ""' 111 + } 112 + } 113 + 114 + __${name}_debug "Calling $RequestComp" 115 + # First disable ActiveHelp which is not supported for Powershell 116 + $env:ActiveHelp = 0 117 + 118 + # call the command store the output in $out and redirect stderr and stdout to null 119 + # $Out is an array contains each line per element 120 + Invoke-Expression -OutVariable out "$RequestComp" 2>&1 | Out-Null 121 + 122 + # get directive from last line 123 + [int]$Directive = $Out[-1].TrimStart(':') 124 + if ($Directive -eq "") { 125 + # There is no directive specified 126 + $Directive = 0 127 + } 128 + __${name}_debug "The completion directive is: $Directive" 129 + 130 + # remove directive (last element) from out 131 + $Out = $Out | Where-Object { $_ -ne $Out[-1] } 132 + __${name}_debug "The completions are: $Out" 133 + 134 + if (($Directive -band $ShellCompDirectiveError) -ne 0 ) { 135 + # Error code. No completion. 136 + __${name}_debug "Received error from custom completion go code" 137 + return 138 + } 139 + 140 + $Longest = 0 141 + [Array]$Values = $Out | ForEach-Object { 142 + # Split the output in name and description 143 + $Name, $Description = $_.Split("\`t", 2) 144 + __${name}_debug "Name: $Name Description: $Description" 145 + 146 + # Look for the longest completion so that we can format things nicely 147 + if ($Longest -lt $Name.Length) { 148 + $Longest = $Name.Length 149 + } 150 + 151 + # Set the description to a one space string if there is none set. 152 + # This is needed because the CompletionResult does not accept an empty string as argument 153 + if (-Not $Description) { 154 + $Description = " " 155 + } 156 + @{ Name = "$Name"; Description = "$Description" } 157 + } 158 + 159 + 160 + $Space = " " 161 + if (($Directive -band $ShellCompDirectiveNoSpace) -ne 0 ) { 162 + # remove the space here 163 + __${name}_debug "ShellCompDirectiveNoSpace is called" 164 + $Space = "" 165 + } 166 + 167 + if ((($Directive -band $ShellCompDirectiveFilterFileExt) -ne 0 ) -or 168 + (($Directive -band $ShellCompDirectiveFilterDirs) -ne 0 )) { 169 + __${name}_debug "ShellCompDirectiveFilterFileExt ShellCompDirectiveFilterDirs are not supported" 170 + 171 + # return here to prevent the completion of the extensions 172 + return 173 + } 174 + 175 + $Values = $Values | Where-Object { 176 + # filter the result 177 + $_.Name -like "$WordToComplete*" 178 + 179 + # Join the flag back if we have an equal sign flag 180 + if ( $IsEqualFlag ) { 181 + __${name}_debug "Join the equal sign flag back to the completion value" 182 + $_.Name = $Flag + "=" + $_.Name 183 + } 184 + } 185 + 186 + # we sort the values in ascending order by name if keep order isn't passed 187 + if (($Directive -band $ShellCompDirectiveKeepOrder) -eq 0 ) { 188 + $Values = $Values | Sort-Object -Property Name 189 + } 190 + 191 + if (($Directive -band $ShellCompDirectiveNoFileComp) -ne 0 ) { 192 + __${name}_debug "ShellCompDirectiveNoFileComp is called" 193 + 194 + if ($Values.Length -eq 0) { 195 + # Just print an empty string here so the 196 + # shell does not start to complete paths. 197 + # We cannot use CompletionResult here because 198 + # it does not accept an empty string as argument. 199 + "" 200 + return 201 + } 202 + } 203 + 204 + # Get the current mode 205 + $Mode = (Get-PSReadLineKeyHandler | Where-Object { $_.Key -eq "Tab" }).Function 206 + __${name}_debug "Mode: $Mode" 207 + 208 + $Values | ForEach-Object { 209 + 210 + # store temporary because switch will overwrite $_ 211 + $comp = $_ 212 + 213 + # PowerShell supports three different completion modes 214 + # - TabCompleteNext (default windows style - on each key press the next option is displayed) 215 + # - Complete (works like bash) 216 + # - MenuComplete (works like zsh) 217 + # You set the mode with Set-PSReadLineKeyHandler -Key Tab -Function <mode> 218 + 219 + # CompletionResult Arguments: 220 + # 1) CompletionText text to be used as the auto completion result 221 + # 2) ListItemText text to be displayed in the suggestion list 222 + # 3) ResultType type of completion result 223 + # 4) ToolTip text for the tooltip with details about the object 224 + 225 + switch ($Mode) { 226 + 227 + # bash like 228 + "Complete" { 229 + 230 + if ($Values.Length -eq 1) { 231 + __${name}_debug "Only one completion left" 232 + 233 + # insert space after value 234 + [System.Management.Automation.CompletionResult]::new($($comp.Name | __${name}_escapeStringWithSpecialChars) + $Space, "$($comp.Name)", 'ParameterValue', "$($comp.Description)") 235 + 236 + } else { 237 + # Add the proper number of spaces to align the descriptions 238 + while($comp.Name.Length -lt $Longest) { 239 + $comp.Name = $comp.Name + " " 240 + } 241 + 242 + # Check for empty description and only add parentheses if needed 243 + if ($($comp.Description) -eq " " ) { 244 + $Description = "" 245 + } else { 246 + $Description = " ($($comp.Description))" 247 + } 248 + 249 + [System.Management.Automation.CompletionResult]::new("$($comp.Name)$Description", "$($comp.Name)$Description", 'ParameterValue', "$($comp.Description)") 250 + } 251 + } 252 + 253 + # zsh like 254 + "MenuComplete" { 255 + # insert space after value 256 + # MenuComplete will automatically show the ToolTip of 257 + # the highlighted value at the bottom of the suggestions. 258 + [System.Management.Automation.CompletionResult]::new($($comp.Name | __${name}_escapeStringWithSpecialChars) + $Space, "$($comp.Name)", 'ParameterValue', "$($comp.Description)") 259 + } 260 + 261 + # TabCompleteNext and in case we get something unknown 262 + Default { 263 + # Like MenuComplete but we don't want to add a space here because 264 + # the user need to press space anyway to get the completion. 265 + # Description will not be shown because that's not possible with TabCompleteNext 266 + [System.Management.Automation.CompletionResult]::new($($comp.Name | __${name}_escapeStringWithSpecialChars), "$($comp.Name)", 'ParameterValue', "$($comp.Description)") 267 + } 268 + } 269 + 270 + } 271 + } 272 + 273 + Register-ArgumentCompleter -CommandName '${name}' -ScriptBlock $__${nameForVar}CompleterBlock 274 + `; 275 + }
+91 -92
shadcn.cac.ts
··· 1 - import fs from "fs/promises"; 2 - import cac from "cac"; 3 - import { 4 - Callback, 5 - Completion, 6 - flagMap, 7 - Positional, 8 - positionalMap, 9 - } from "./shared"; 10 - import path from "path"; 11 - import tab from "./cac"; 1 + // import fs from "fs/promises"; 2 + // import cac from "cac"; 3 + // import { 4 + // Callback, 5 + // Completion, 6 + // flagMap, 7 + // Positional, 8 + // positionalMap, 9 + // } from "./shared"; 10 + // import path from "path"; 11 + // import tab from "./cac"; 12 12 13 - const cli = cac("shadcn"); // Using 'shadcn' as the CLI tool name 13 + // const cli = cac("shadcn"); // Using 'shadcn' as the CLI tool name 14 14 15 - // Global options 16 - cli 17 - .option("-c, --cwd [cwd]", `[string] the working directory. defaults to the current directory.`) 18 - .option("-h, --help", `display help for command`); 15 + // // Global options 16 + // cli 17 + // .option("-c, --cwd [cwd]", `[string] the working directory. defaults to the current directory.`) 18 + // .option("-h, --help", `display help for command`); 19 19 20 - // Init command 21 - cli 22 - .command("init", "initialize your project and install dependencies") 23 - .option("-d, --defaults", `[boolean] use default values i.e new-york, zinc, and css variables`, { default: false }) 24 - .option("-f, --force", `[boolean] force overwrite of existing components.json`, { default: false }) 25 - .option("-y, --yes", `[boolean] skip confirmation prompt`, { default: false }) 26 - .action((options) => { 27 - console.log(`Initializing project with options:`, options); 28 - }); 20 + // // Init command 21 + // cli 22 + // .command("init", "initialize your project and install dependencies") 23 + // .option("-d, --defaults", `[boolean] use default values i.e new-york, zinc, and css variables`, { default: false }) 24 + // .option("-f, --force", `[boolean] force overwrite of existing components.json`, { default: false }) 25 + // .option("-y, --yes", `[boolean] skip confirmation prompt`, { default: false }) 26 + // .action((options) => { 27 + // console.log(`Initializing project with options:`, options); 28 + // }); 29 29 30 - // Add command 31 - cli 32 - .command("add [...components]", "add a component to your project") 33 - .option("-y, --yes", `[boolean] skip confirmation prompt`, { default: false }) 34 - .option("-o, --overwrite", `[boolean] overwrite existing files`, { default: false }) 35 - .option("-a, --all", `[boolean] add all available components`, { default: false }) 36 - .option("-p, --path [path]", `[string] the path to add the component to`) 37 - .action((components, options) => { 38 - console.log(`Adding components:`, components, `with options:`, options); 39 - }); 30 + // // Add command 31 + // cli 32 + // .command("add [...components]", "add a component to your project") 33 + // .option("-y, --yes", `[boolean] skip confirmation prompt`, { default: false }) 34 + // .option("-o, --overwrite", `[boolean] overwrite existing files`, { default: false }) 35 + // .option("-a, --all", `[boolean] add all available components`, { default: false }) 36 + // .option("-p, --path [path]", `[string] the path to add the component to`) 37 + // .action((components, options) => { 38 + // console.log(`Adding components:`, components, `with options:`, options); 39 + // }); 40 40 41 - // Build positional completions for each command using command.args 42 - for (const c of [cli.globalCommand, ...cli.commands]) { 43 - // Handle options 44 - for (const o of [...cli.globalCommand.options, ...c.options]) { 45 - const optionKey = `${c.name} ${o.name}`; 41 + // // Build positional completions for each command using command.args 42 + // for (const c of [cli.globalCommand, ...cli.commands]) { 43 + // // Handle options 44 + // for (const o of [...cli.globalCommand.options, ...c.options]) { 45 + // const optionKey = `${c.name} ${o.name}`; 46 46 47 - if (o.rawName.includes("--cwd <cwd>")) { 48 - // Completion for --cwd (common working directories) 49 - flagMap.set(optionKey, async (previousArgs, toComplete) => { 50 - return [ 51 - { action: "./apps/www", description: "Default app directory" }, 52 - { action: "./apps/admin", description: "Admin app directory" }, 53 - ].filter((comp) => comp.action.startsWith(toComplete)); 54 - }); 55 - } 47 + // if (o.rawName.includes("--cwd <cwd>")) { 48 + // // Completion for --cwd (common working directories) 49 + // flagMap.set(optionKey, async (previousArgs, toComplete) => { 50 + // return [ 51 + // { action: "./apps/www", description: "Default app directory" }, 52 + // { action: "./apps/admin", description: "Admin app directory" }, 53 + // ].filter((comp) => comp.action.startsWith(toComplete)); 54 + // }); 55 + // } 56 56 57 - if (o.rawName.includes("--defaults")) { 58 - // Completion for --defaults (show info for default setup) 59 - flagMap.set(optionKey, async (previousArgs, toComplete) => { 60 - return [{ action: "true", description: "Use default values for setup" }]; 61 - }); 62 - } 57 + // if (o.rawName.includes("--defaults")) { 58 + // // Completion for --defaults (show info for default setup) 59 + // flagMap.set(optionKey, async (previousArgs, toComplete) => { 60 + // return [{ action: "true", description: "Use default values for setup" }]; 61 + // }); 62 + // } 63 63 64 - if (o.rawName.includes("--path <path>")) { 65 - // Completion for --path (common component paths) 66 - flagMap.set(optionKey, async (previousArgs, toComplete) => { 67 - return [ 68 - { action: "src/components", description: "Main components directory" }, 69 - { action: "src/ui", description: "UI components directory" }, 70 - ].filter((comp) => comp.action.startsWith(toComplete)); 71 - }); 72 - } 73 - } 64 + // if (o.rawName.includes("--path <path>")) { 65 + // // Completion for --path (common component paths) 66 + // flagMap.set(optionKey, async (previousArgs, toComplete) => { 67 + // return [ 68 + // { action: "src/components", description: "Main components directory" }, 69 + // { action: "src/ui", description: "UI components directory" }, 70 + // ].filter((comp) => comp.action.startsWith(toComplete)); 71 + // }); 72 + // } 73 + // } 74 74 75 - // Handle positional arguments 76 - if (c.name === "add" && c.args && c.args.length > 0) { 77 - const componentChoices = [ 78 - "accordion", "alert", "alert-dialog", "aspect-ratio", "avatar", 79 - "badge", "button", "calendar", "card", "checkbox" 80 - ]; 81 - const positionals = c.args.map((arg) => ({ 82 - required: arg.required, 83 - variadic: arg.variadic, 84 - value: arg.value, 85 - completion: async (previousArgs, toComplete) => { 86 - // if (arg.value === "root") { 87 - return componentChoices 88 - // TODO: a bug here that toComplete is equal to "add" which then makes filter not work, we should omit toComplete and add it to previous args if the endsWithSpace is true 89 - // .filter((comp) => comp.startsWith(toComplete)) 90 - .map((comp) => ({ action: comp, description: `Add ${comp} component` })); 91 - // } 92 - // return []; 93 - }, 94 - })); 75 + // // Handle positional arguments 76 + // if (c.name === "add" && c.args && c.args.length > 0) { 77 + // const componentChoices = [ 78 + // "accordion", "alert", "alert-dialog", "aspect-ratio", "avatar", 79 + // "badge", "button", "calendar", "card", "checkbox" 80 + // ]; 81 + // const positionals = c.args.map((arg) => ({ 82 + // required: arg.required, 83 + // variadic: arg.variadic, 84 + // value: arg.value, 85 + // completion: async (previousArgs, toComplete) => { 86 + // // if (arg.value === "root") { 87 + // return componentChoices 88 + // // TODO: a bug here that toComplete is equal to "add" which then makes filter not work, we should omit toComplete and add it to previous args if the endsWithSpace is true 89 + // // .filter((comp) => comp.startsWith(toComplete)) 90 + // .map((comp) => ({ action: comp, description: `Add ${comp} component` })); 91 + // // } 92 + // // return []; 93 + // }, 94 + // })); 95 95 96 - positionalMap.set(c.name, positionals); 97 - } 98 - } 96 + // positionalMap.set(c.name, positionals); 97 + // } 98 + // } 99 99 100 - // Initialize tab completion 101 - tab(cli); 100 + // // Initialize tab completion 101 + // tab(cli); 102 102 103 - cli.parse(); 104 - 103 + // cli.parse();
-75
shared.ts
··· 1 - 2 - // ShellCompRequestCmd is the name of the hidden command that is used to request 3 - // completion results from the program. It is used by the shell completion scripts. 4 - export const ShellCompRequestCmd: string = "__complete"; 5 - 6 - // ShellCompNoDescRequestCmd is the name of the hidden command that is used to request 7 - // completion results without their description. It is used by the shell completion scripts. 8 - export const ShellCompNoDescRequestCmd: string = "__completeNoDesc"; 9 - 10 - // ShellCompDirective is a bit map representing the different behaviors the shell 11 - // can be instructed to have once completions have been provided. 12 - export const ShellCompDirective = { 13 - // ShellCompDirectiveError indicates an error occurred and completions should be ignored. 14 - ShellCompDirectiveError: 1 << 0, 15 - 16 - // ShellCompDirectiveNoSpace indicates that the shell should not add a space 17 - // after the completion even if there is a single completion provided. 18 - ShellCompDirectiveNoSpace: 1 << 1, 19 - 20 - // ShellCompDirectiveNoFileComp indicates that the shell should not provide 21 - // file completion even when no completion is provided. 22 - ShellCompDirectiveNoFileComp: 1 << 2, 23 - 24 - // ShellCompDirectiveFilterFileExt indicates that the provided completions 25 - // should be used as file extension filters. 26 - // For flags, using Command.MarkFlagFilename() and Command.MarkPersistentFlagFilename() 27 - // is a shortcut to using this directive explicitly. The BashCompFilenameExt 28 - // annotation can also be used to obtain the same behavior for flags. 29 - ShellCompDirectiveFilterFileExt: 1 << 3, 30 - 31 - // ShellCompDirectiveFilterDirs indicates that only directory names should 32 - // be provided in file completion. To request directory names within another 33 - // directory, the returned completions should specify the directory within 34 - // which to search. The BashCompSubdirsInDir annotation can be used to 35 - // obtain the same behavior but only for flags. 36 - ShellCompDirectiveFilterDirs: 1 << 4, 37 - 38 - // ShellCompDirectiveKeepOrder indicates that the shell should preserve the order 39 - // in which the completions are provided. 40 - ShellCompDirectiveKeepOrder: 1 << 5, 41 - 42 - // =========================================================================== 43 - 44 - // All directives using iota (or equivalent in Go) should be above this one. 45 - // For internal use. 46 - shellCompDirectiveMaxValue: 1 << 6, 47 - 48 - // ShellCompDirectiveDefault indicates to let the shell perform its default 49 - // behavior after completions have been provided. 50 - // This one must be last to avoid messing up the iota count. 51 - ShellCompDirectiveDefault: 0, 52 - }; 53 - 54 - 55 - 56 - export type Completion = { 57 - action: string; 58 - description?: string; 59 - }; 60 - 61 - export type Callback = ( 62 - previousArgs: string[], 63 - toComplete: string, 64 - ) => Completion[] | Promise<Completion[]>; 65 - 66 - export type Positional = { 67 - required: boolean; 68 - variadic: boolean; 69 - completion: Callback; 70 - }; 71 - 72 - 73 - export const positionalMap = new Map<string, Positional[]>(); 74 - 75 - export const flagMap = new Map<string, Callback>();
+1
src/bash.ts
··· 1 + export function generate(name: string, exec: string) {}
+366
src/cac.ts
··· 1 + import * as zsh from "./zsh"; 2 + import * as bash from "./bash"; 3 + import * as fish from "./fish"; 4 + import * as powershell from "./powershell"; 5 + import type { CAC } from "cac"; 6 + import { Completion } from "./"; 7 + 8 + const execPath = process.execPath; 9 + const processArgs = process.argv.slice(1); 10 + const quotedExecPath = quoteIfNeeded(execPath); 11 + const quotedProcessArgs = processArgs.map(quoteIfNeeded); 12 + const quotedProcessExecArgs = process.execArgv.map(quoteIfNeeded); 13 + 14 + const x = `${quotedExecPath} ${quotedProcessExecArgs.join(" ")} ${quotedProcessArgs[0]}`; 15 + 16 + function quoteIfNeeded(path: string): string { 17 + return path.includes(" ") ? `'${path}'` : path; 18 + } 19 + 20 + // export default function tab(instance: CAC): void { 21 + // instance.command("complete [shell]").action(async (shell, extra) => { 22 + // switch (shell) { 23 + // case "zsh": { 24 + // const script = zsh.generate(instance.name, x); 25 + // console.log(script); 26 + // break; 27 + // } 28 + // case "bash": { 29 + // const script = bash.generate(instance.name, x); 30 + // console.log(script); 31 + // break; 32 + // } 33 + // case "fish": { 34 + // const script = fish.generate(instance.name, x); 35 + // console.log(script); 36 + // break; 37 + // } 38 + // case "powershell": { 39 + // const script = powershell.generate(instance.name, x); 40 + // console.log(script); 41 + // break; 42 + // } 43 + // default: { 44 + // const args: string[] = extra["--"]; 45 + 46 + // instance.showHelpOnExit = false; 47 + // let directive = ShellCompDirective.ShellCompDirectiveDefault; 48 + 49 + // const endsWithSpace = args[args.length - 1] === ""; 50 + // if (endsWithSpace) { 51 + // args.pop(); 52 + // } 53 + 54 + // let toComplete = args[args.length - 1] || ""; 55 + // const previousArgs = args.slice(0, -1); 56 + 57 + // const completions: string[] = []; 58 + 59 + // instance.unsetMatchedCommand(); 60 + // instance.parse([execPath, processArgs[0], ...previousArgs], { 61 + // run: false, 62 + // }); 63 + 64 + // const command = instance.matchedCommand ?? instance.globalCommand; 65 + 66 + // const options = [ 67 + // ...new Set([ 68 + // ...(command?.options ?? []), 69 + // ...instance.globalCommand.options, 70 + // ]), 71 + // ]; 72 + 73 + // let isCompletingFlagValue = false; 74 + // let flagName = ""; 75 + // let option: (typeof options)[number] | null = null; 76 + // const lastArg = previousArgs[previousArgs.length - 1]; 77 + 78 + // function processOption() { 79 + // const matchedOption = options.find((o) => 80 + // o.names.some((name) => name === flagName) 81 + // ); 82 + 83 + // if (matchedOption && !matchedOption.isBoolean) { 84 + // isCompletingFlagValue = true; 85 + // option = matchedOption; 86 + // if (endsWithSpace) { 87 + // toComplete = ""; 88 + // } 89 + // } else { 90 + // isCompletingFlagValue = false; 91 + // option = null; 92 + // } 93 + // } 94 + 95 + // if (toComplete.startsWith("--")) { 96 + // // Long option 97 + // flagName = toComplete.slice(2); 98 + // const equalsIndex = flagName.indexOf("="); 99 + // if (equalsIndex !== -1 && !endsWithSpace) { 100 + // // Option with '=', get the name before '=' 101 + // flagName = flagName.slice(0, equalsIndex); 102 + // toComplete = toComplete.slice(toComplete.indexOf("=") + 1); 103 + // processOption(); 104 + // } else if (!endsWithSpace) { 105 + // // If not ending with space, still typing option name 106 + // flagName = ""; 107 + // } else { 108 + // // User pressed space after typing the option name 109 + // processOption(); 110 + // toComplete = ""; 111 + // } 112 + // } else if (toComplete.startsWith("-") && toComplete.length > 1) { 113 + // // Short option 114 + // flagName = toComplete.slice(1); 115 + // if (!endsWithSpace) { 116 + // // Still typing option name 117 + // flagName = ""; 118 + // } else { 119 + // processOption(); 120 + // toComplete = ""; 121 + // } 122 + // } else if (lastArg?.startsWith("--") && !endsWithSpace) { 123 + // flagName = lastArg.slice(2); 124 + // processOption(); 125 + // } else if ( 126 + // lastArg?.startsWith("-") && 127 + // lastArg.length > 1 && 128 + // !endsWithSpace 129 + // ) { 130 + // flagName = lastArg.slice(2); 131 + // processOption(); 132 + // } 133 + 134 + // if (isCompletingFlagValue) { 135 + // const flagCompletionFn = flagMap.get( 136 + // `${command.name} ${option?.name}` 137 + // ); 138 + 139 + // if (flagCompletionFn) { 140 + // // Call custom completion function for the flag 141 + // const comps = await flagCompletionFn(previousArgs, toComplete); 142 + // completions.push( 143 + // ...comps.map( 144 + // (comp) => `${comp.action}\t${comp.description ?? ""}` 145 + // ) 146 + // ); 147 + // directive = ShellCompDirective.ShellCompDirectiveNoFileComp; 148 + // } else { 149 + // // Default completion (e.g., file completion) 150 + // directive = ShellCompDirective.ShellCompDirectiveDefault; 151 + // } 152 + // } else if (toComplete.startsWith("-") && !endsWithSpace) { 153 + // const flag = toComplete.replace(/^-+/, ""); // Remove leading '-' 154 + 155 + // // Determine options to suggest 156 + // let optionsToSuggest = options.filter((o) => { 157 + // const equalToDefault = 158 + // "default" in o.config && 159 + // instance.options[o.name] === o.config.default; 160 + // return ( 161 + // o.names.some((name) => name.startsWith(flag)) && 162 + // !(instance.options[o.name] && !equalToDefault) 163 + // ); 164 + // }); 165 + 166 + // const requiredOptions = optionsToSuggest.filter((o) => o.required); 167 + 168 + // if (requiredOptions.length) { 169 + // // Required options not yet specified 170 + // optionsToSuggest = requiredOptions; 171 + // } 172 + 173 + // if (optionsToSuggest.length > 0) { 174 + // completions.push( 175 + // ...optionsToSuggest.map( 176 + // (o) => `--${o.name}\t${o.description ?? ""}` 177 + // ) 178 + // ); 179 + // } 180 + 181 + // directive = ShellCompDirective.ShellCompDirectiveNoFileComp; 182 + // } else { 183 + // instance.parse( 184 + // [execPath, processArgs[0], ...previousArgs, toComplete], 185 + // { 186 + // run: false, 187 + // } 188 + // ); 189 + // const fullCommandName = args 190 + // .filter((arg) => !arg.startsWith("-")) 191 + // .join(" "); 192 + 193 + // for (const c of instance.commands) { 194 + // if (c.name === "complete") { 195 + // // avoid showing completions for the completion server 196 + // continue; 197 + // } 198 + // const fullCommandParts = fullCommandName.split(" "); 199 + // const commandParts: { type: "command"; value: string }[] = c.name 200 + // .split(" ") 201 + // .map((part) => ({ type: "command", value: part })); 202 + // const args: { 203 + // type: "positional"; 204 + // position: number; 205 + // value: Positional; 206 + // }[] = 207 + // positionalMap.get(c.name)?.map((arg, i) => ({ 208 + // type: "positional", 209 + // position: i, 210 + // value: arg, 211 + // })) ?? []; 212 + // const parts = [...commandParts, ...args]; 213 + 214 + // for (let i = 0; i < parts.length; i++) { 215 + // const fullCommandPart = fullCommandParts[i]; 216 + // const part = parts[i]; 217 + 218 + // if (part.type === "command") { 219 + // // Command part matching 220 + // if (part.value === fullCommandPart) { 221 + // // Command part matches user input, continue to next part 222 + // continue; 223 + // } else if ( 224 + // !fullCommandPart || 225 + // part.value.startsWith(fullCommandPart) 226 + // ) { 227 + // // User is typing this command part, provide completion 228 + // completions.push(`${part.value}\t${c.description ?? ""}`); 229 + // } 230 + // // Command part does not match, break 231 + // break; 232 + // } else if (part.type === "positional") { 233 + // const positional = part.value; 234 + // // Positional argument handling 235 + // if (part.value.variadic) { 236 + // const comps = await positional.completion( 237 + // previousArgs, 238 + // toComplete 239 + // ); 240 + // completions.push( 241 + // ...comps.map( 242 + // (comp) => `${comp.action}\t${comp.description ?? ""}` 243 + // ) 244 + // ); 245 + // break; 246 + // } 247 + // if (typeof fullCommandPart !== "undefined") { 248 + // // User has provided input for this positional argument 249 + // if (i === fullCommandParts.length - 1 && !endsWithSpace) { 250 + // // User is still typing this positional argument, provide completions 251 + // const comps = await positional.completion( 252 + // previousArgs, 253 + // toComplete 254 + // ); 255 + // completions.push( 256 + // ...comps.map( 257 + // (comp) => `${comp.action}\t${comp.description ?? ""}` 258 + // ) 259 + // ); 260 + // break; 261 + // } else { 262 + // // Positional argument is already provided, move to next 263 + // previousArgs.push(fullCommandPart); 264 + // continue; 265 + // } 266 + // } else { 267 + // // User has not provided input for this positional argument 268 + // const comps = await positional.completion( 269 + // previousArgs, 270 + // toComplete 271 + // ); 272 + // completions.push( 273 + // ...comps.map( 274 + // (comp) => `${comp.action}\t${comp.description ?? ""}` 275 + // ) 276 + // ); 277 + // break; 278 + // } 279 + // } 280 + // } 281 + // } 282 + // } 283 + 284 + // // Output completions 285 + // for (const comp of completions) { 286 + // console.log(comp.split("\n")[0].trim()); 287 + // } 288 + // console.log(`:${directive}`); 289 + // console.error(`Completion ended with directive: ${directive}`); 290 + // } 291 + // } 292 + // }); 293 + // } 294 + 295 + export default function tab(instance: CAC): Completion { 296 + const completion = new Completion(); 297 + 298 + // Add all commands and their options 299 + for (const cmd of [instance.globalCommand, ...instance.commands]) { 300 + if (cmd.name === 'complete') continue; // Skip completion command 301 + 302 + // Get positional args info from command usage 303 + const args = (cmd.rawName.match(/\[.*?\]|\<.*?\>/g) || []) 304 + .map(arg => arg.startsWith('[')); // true if optional (wrapped in []) 305 + 306 + // Add command to completion 307 + const commandName = completion.addCommand( 308 + cmd.name === '@@global@@' ? '' : cmd.name, 309 + cmd.description || '', 310 + args, 311 + async () => [] 312 + ); 313 + 314 + // Add command options 315 + for (const option of [...instance.globalCommand.options, ...cmd.options]) { 316 + completion.addOption( 317 + commandName, 318 + `--${option.name}`, 319 + option.description || '', 320 + async () => [] 321 + ); 322 + } 323 + } 324 + 325 + instance.command("complete [shell]").action(async (shell, extra) => { 326 + switch (shell) { 327 + case "zsh": { 328 + const script = zsh.generate(instance.name, x); 329 + console.log(script); 330 + break; 331 + } 332 + case "bash": { 333 + const script = bash.generate(instance.name, x); 334 + console.log(script); 335 + break; 336 + } 337 + case "fish": { 338 + const script = fish.generate(instance.name, x); 339 + console.log(script); 340 + break; 341 + } 342 + case "powershell": { 343 + const script = powershell.generate(instance.name, x); 344 + console.log(script); 345 + break; 346 + } 347 + default: { 348 + const args: string[] = extra["--"]; 349 + instance.showHelpOnExit = false; 350 + 351 + // Parse current command context 352 + instance.unsetMatchedCommand(); 353 + instance.parse([execPath, processArgs[0], ...args], { 354 + run: false, 355 + }); 356 + 357 + // const matchedCommand = instance.matchedCommand?.name || ''; 358 + // const potentialCommand = args.join(' ') 359 + // console.log(potentialCommand) 360 + return completion.parse(args); 361 + } 362 + } 363 + }); 364 + 365 + return completion; 366 + }
+185
src/citty.ts
··· 1 + import { ArgDef, defineCommand, parseArgs } from 'citty'; 2 + import * as zsh from './zsh'; 3 + import * as bash from './bash'; 4 + import * as fish from './fish'; 5 + import * as powershell from './powershell'; 6 + import { Completion } from '.'; 7 + import type { 8 + ArgsDef, 9 + CommandDef, 10 + PositionalArgDef, 11 + SubCommandsDef, 12 + } from 'citty'; 13 + 14 + function quoteIfNeeded(path: string) { 15 + return path.includes(' ') ? `'${path}'` : path; 16 + } 17 + 18 + const execPath = process.execPath; 19 + const processArgs = process.argv.slice(1); 20 + const quotedExecPath = quoteIfNeeded(execPath); 21 + const quotedProcessArgs = processArgs.map(quoteIfNeeded); 22 + const quotedProcessExecArgs = process.execArgv.map(quoteIfNeeded); 23 + const x = `${quotedExecPath} ${quotedProcessExecArgs.join(' ')} ${quotedProcessArgs[0]}`; 24 + 25 + function isConfigPositional<T extends ArgsDef>(config: CommandDef<T>) { 26 + return ( 27 + config.args && 28 + Object.values(config.args).some((arg) => arg.type === 'positional') 29 + ); 30 + } 31 + 32 + async function handleSubCommands<T extends ArgsDef = ArgsDef>( 33 + completion: Completion, 34 + subCommands: SubCommandsDef, 35 + parentCmd?: string 36 + ) { 37 + for (const [cmd, resolvableConfig] of Object.entries(subCommands)) { 38 + const config = await resolve(resolvableConfig); 39 + const meta = await resolve(config.meta); 40 + const subCommands = await resolve(config.subCommands); 41 + 42 + if (!meta || typeof meta?.description !== 'string') { 43 + throw new Error('Invalid meta or missing description.'); 44 + } 45 + const isPositional = isConfigPositional(config); 46 + const name = completion.addCommand( 47 + cmd, 48 + meta.description, 49 + isPositional ? [false] : [], 50 + async (previousArgs, toComplete, endsWithSpace) => { 51 + return []; 52 + }, 53 + parentCmd 54 + ); 55 + 56 + // Handle nested subcommands recursively 57 + if (subCommands) { 58 + await handleSubCommands(completion, subCommands, name); 59 + } 60 + 61 + // Handle arguments 62 + if (config.args) { 63 + for (const [argName, argConfig] of Object.entries(config.args)) { 64 + const conf = argConfig as ArgDef; 65 + if (conf.type === 'positional') { 66 + continue; 67 + } 68 + completion.addOption( 69 + name, 70 + `--${argName}`, 71 + conf.description ?? '', 72 + async (previousArgs, toComplete, endsWithSpace) => { 73 + return []; 74 + } 75 + ); 76 + } 77 + } 78 + } 79 + } 80 + 81 + export default async function tab<T extends ArgsDef = ArgsDef>( 82 + instance: CommandDef<T> 83 + ) { 84 + const completion = new Completion(); 85 + 86 + const meta = await resolve(instance.meta); 87 + 88 + if (!meta) { 89 + throw new Error('Invalid meta.'); 90 + } 91 + const name = meta.name; 92 + if (!name) { 93 + throw new Error('Invalid meta or missing name.'); 94 + } 95 + 96 + const subCommands = await resolve(instance.subCommands); 97 + if (!subCommands) { 98 + throw new Error('Invalid or missing subCommands.'); 99 + } 100 + 101 + const root = ''; 102 + const isPositional = isConfigPositional(instance); 103 + completion.addCommand( 104 + root, 105 + meta?.description ?? '', 106 + isPositional ? [false] : [], 107 + async (previousArgs, toComplete, endsWithSpace) => { 108 + return []; 109 + } 110 + ); 111 + 112 + await handleSubCommands(completion, subCommands); 113 + 114 + if (instance.args) { 115 + for (const [argName, argConfig] of Object.entries(instance.args)) { 116 + const conf = argConfig as PositionalArgDef; 117 + completion.addOption( 118 + root, 119 + `--${argName}`, 120 + conf.description ?? '', 121 + async (previousArgs, toComplete, endsWithSpace) => { 122 + return []; 123 + } 124 + ); 125 + } 126 + } 127 + 128 + const completeCommand = defineCommand({ 129 + meta: { 130 + name: 'complete', 131 + description: 'Generate shell completion scripts', 132 + }, 133 + async run(ctx) { 134 + let shell: string | undefined = ctx.rawArgs[0]; 135 + const extra = ctx.rawArgs.slice(ctx.rawArgs.indexOf('--') + 1); 136 + 137 + if (shell === '--') { 138 + shell = undefined; 139 + } 140 + 141 + switch (shell) { 142 + case 'zsh': { 143 + const script = zsh.generate(name, x); 144 + console.log(script); 145 + break; 146 + } 147 + case 'bash': { 148 + const script = bash.generate(name, x); 149 + console.log(script); 150 + break; 151 + } 152 + case 'fish': { 153 + const script = fish.generate(name, x); 154 + console.log(script); 155 + break; 156 + } 157 + case 'powershell': { 158 + const script = powershell.generate(name, x); 159 + console.log(script); 160 + break; 161 + } 162 + default: { 163 + const args = (await resolve(instance.args))!; 164 + const parsed = parseArgs(extra, args); 165 + // TODO: this is not ideal at all 166 + const matchedCommand = parsed._.join(' ').trim(); 167 + // TODO: `command lint i` does not work because `lint` and `i` are potential commands 168 + // instead the potential command should only be `lint` 169 + // and `i` is the to be completed part 170 + return completion.parse(extra, matchedCommand); 171 + } 172 + } 173 + }, 174 + }); 175 + 176 + subCommands.complete = completeCommand; 177 + 178 + return completion; 179 + } 180 + 181 + type Resolvable<T> = T | Promise<T> | (() => T) | (() => Promise<T>); 182 + 183 + async function resolve<T>(resolvable: Resolvable<T>): Promise<T> { 184 + return resolvable instanceof Function ? await resolvable() : await resolvable; 185 + }
+1
src/fish.ts
··· 1 + export function generate(name: string, exec: string) {}
+361
src/index.ts
··· 1 + import * as zsh from './zsh'; 2 + import * as bash from './bash'; 3 + import * as fish from './fish'; 4 + import * as powershell from './powershell'; 5 + 6 + // ShellCompRequestCmd is the name of the hidden command that is used to request 7 + // completion results from the program. It is used by the shell completion scripts. 8 + export const ShellCompRequestCmd: string = '__complete'; 9 + 10 + // ShellCompNoDescRequestCmd is the name of the hidden command that is used to request 11 + // completion results without their description. It is used by the shell completion scripts. 12 + export const ShellCompNoDescRequestCmd: string = '__completeNoDesc'; 13 + 14 + // ShellCompDirective is a bit map representing the different behaviors the shell 15 + // can be instructed to have once completions have been provided. 16 + export const ShellCompDirective = { 17 + // ShellCompDirectiveError indicates an error occurred and completions should be ignored. 18 + ShellCompDirectiveError: 1 << 0, 19 + 20 + // ShellCompDirectiveNoSpace indicates that the shell should not add a space 21 + // after the completion even if there is a single completion provided. 22 + ShellCompDirectiveNoSpace: 1 << 1, 23 + 24 + // ShellCompDirectiveNoFileComp indicates that the shell should not provide 25 + // file completion even when no completion is provided. 26 + ShellCompDirectiveNoFileComp: 1 << 2, 27 + 28 + // ShellCompDirectiveFilterFileExt indicates that the provided completions 29 + // should be used as file extension filters. 30 + // For flags, using Command.MarkFlagFilename() and Command.MarkPersistentFlagFilename() 31 + // is a shortcut to using this directive explicitly. The BashCompFilenameExt 32 + // annotation can also be used to obtain the same behavior for flags. 33 + ShellCompDirectiveFilterFileExt: 1 << 3, 34 + 35 + // ShellCompDirectiveFilterDirs indicates that only directory names should 36 + // be provided in file completion. To request directory names within another 37 + // directory, the returned completions should specify the directory within 38 + // which to search. The BashCompSubdirsInDir annotation can be used to 39 + // obtain the same behavior but only for flags. 40 + ShellCompDirectiveFilterDirs: 1 << 4, 41 + 42 + // ShellCompDirectiveKeepOrder indicates that the shell should preserve the order 43 + // in which the completions are provided. 44 + ShellCompDirectiveKeepOrder: 1 << 5, 45 + 46 + // =========================================================================== 47 + 48 + // All directives using iota (or equivalent in Go) should be above this one. 49 + // For internal use. 50 + shellCompDirectiveMaxValue: 1 << 6, 51 + 52 + // ShellCompDirectiveDefault indicates to let the shell perform its default 53 + // behavior after completions have been provided. 54 + // This one must be last to avoid messing up the iota count. 55 + ShellCompDirectiveDefault: 0, 56 + }; 57 + 58 + export type Positional = { 59 + required: boolean; 60 + variadic: boolean; 61 + completion: Handler; 62 + }; 63 + 64 + type Item = { 65 + description: string; 66 + value: string; 67 + }; 68 + 69 + type Handler = ( 70 + previousArgs: string[], 71 + toComplete: string, 72 + endsWithSpace: boolean 73 + ) => Item[] | Promise<Item[]>; 74 + 75 + type Option = { 76 + description: string; 77 + handler: Handler; 78 + }; 79 + 80 + type Command = { 81 + name: string; 82 + description: string; 83 + args: boolean[] 84 + handler: Handler; 85 + options: Map<string, Option>; 86 + parent?: Command; 87 + }; 88 + 89 + export class Completion { 90 + commands = new Map<string, Command>(); 91 + completions: Item[] = [] 92 + directive = ShellCompDirective.ShellCompDirectiveDefault; 93 + 94 + // vite <entry> <another> [...files] 95 + // args: [false, false, true], only the last argument can be variadic 96 + addCommand( 97 + name: string, 98 + description: string, 99 + args: boolean[], 100 + handler: Handler, 101 + parent?: string 102 + ) { 103 + const key = parent ? `${parent} ${name}` : name; 104 + this.commands.set(key, { 105 + name: key, 106 + description, 107 + args, 108 + handler, 109 + options: new Map(), 110 + parent: parent ? this.commands.get(parent)! : undefined, 111 + }); 112 + return key; 113 + } 114 + 115 + // --port 116 + addOption( 117 + command: string, 118 + option: string, 119 + description: string, 120 + handler: Handler 121 + ) { 122 + const cmd = this.commands.get(command); 123 + if (!cmd) { 124 + throw new Error(`Command ${command} not found.`); 125 + } 126 + cmd.options.set(option, { description, handler }); 127 + return option; 128 + } 129 + 130 + // TODO: this should be aware of boolean args and stuff 131 + private stripOptions(args: string[]): string[] { 132 + const parts: string[] = [] 133 + let option = false; 134 + for (const k of args) { 135 + if (k.startsWith('-')) { 136 + option = true; 137 + continue 138 + } 139 + if (option) { 140 + option = false; 141 + continue 142 + } 143 + parts.push(k) 144 + } 145 + return parts 146 + } 147 + 148 + private matchCommand(args: string[]): [Command, string[]] { 149 + args = this.stripOptions(args); 150 + let parts: string[] = []; 151 + let remaining: string[] = []; 152 + let matched: Command = this.commands.get('')! 153 + for (let i = 0; i < args.length; i++) { 154 + const k = args[i]; 155 + parts.push(k); 156 + const potential = this.commands.get(parts.join(' ')) 157 + 158 + if (potential) { 159 + matched = potential; 160 + } else { 161 + remaining = args.slice(i, args.length); 162 + break 163 + } 164 + } 165 + return [matched, remaining]; 166 + } 167 + 168 + async parse(args: string[]) { 169 + const endsWithSpace = args[args.length - 1] === ''; 170 + 171 + if (endsWithSpace) { 172 + args.pop(); 173 + } 174 + 175 + let toComplete = args[args.length - 1] || ''; 176 + const previousArgs = args.slice(0, -1); 177 + 178 + if (endsWithSpace) { 179 + previousArgs.push(toComplete); 180 + toComplete = ''; 181 + } 182 + 183 + const [matchedCommand, remaining] = this.matchCommand(previousArgs); 184 + 185 + const lastPrevArg = previousArgs[previousArgs.length - 1]; 186 + 187 + // 1. Handle flag/option completion 188 + if (this.shouldCompleteFlags(lastPrevArg, toComplete, endsWithSpace)) { 189 + await this.handleFlagCompletion( 190 + matchedCommand, 191 + previousArgs, 192 + toComplete, 193 + endsWithSpace, 194 + lastPrevArg, 195 + ); 196 + } 197 + else { 198 + // 2. Handle command/subcommand completion 199 + if (this.shouldCompleteCommands(toComplete, endsWithSpace)) { 200 + await this.handleCommandCompletion( 201 + previousArgs, 202 + toComplete, 203 + ); 204 + } 205 + // 3. Handle positional arguments 206 + if (matchedCommand && matchedCommand.args.length > 0) { 207 + await this.handlePositionalCompletion( 208 + matchedCommand, 209 + previousArgs, 210 + toComplete, 211 + endsWithSpace, 212 + ); 213 + } 214 + } 215 + this.complete(toComplete) 216 + } 217 + 218 + private complete(toComplete: string) { 219 + this.directive = ShellCompDirective.ShellCompDirectiveNoFileComp; 220 + 221 + const seen = new Set<string>(); 222 + this.completions 223 + .filter((comp) => { 224 + if (seen.has(comp.value)) return false; 225 + seen.add(comp.value); 226 + return true; 227 + }) 228 + .filter((comp) => comp.value.startsWith(toComplete)) 229 + .forEach((comp) => console.log(`${comp.value}\t${comp.description ?? ''}`)); 230 + console.log(`:${this.directive}`); 231 + } 232 + 233 + private shouldCompleteFlags(lastPrevArg: string | undefined, toComplete: string, endsWithSpace: boolean): boolean { 234 + return (lastPrevArg?.startsWith('--')) || toComplete.startsWith('--'); 235 + } 236 + 237 + private shouldCompleteCommands(toComplete: string, endsWithSpace: boolean): boolean { 238 + return !toComplete.startsWith('-'); 239 + } 240 + 241 + private async handleFlagCompletion( 242 + command: Command, 243 + previousArgs: string[], 244 + toComplete: string, 245 + endsWithSpace: boolean, 246 + lastPrevArg: string | undefined, 247 + ) { 248 + // Handle flag value completion 249 + let flagName: string | undefined; 250 + let valueToComplete = toComplete; 251 + 252 + if (toComplete.includes('=')) { 253 + // Handle --flag=value case 254 + const parts = toComplete.split('='); 255 + flagName = parts[0]; 256 + valueToComplete = parts[1] || ''; 257 + } else if (lastPrevArg?.startsWith('--')) { 258 + // Handle --flag value case 259 + flagName = lastPrevArg; 260 + } 261 + 262 + if (flagName) { 263 + const option = command.options.get(flagName); 264 + if (option) { 265 + const suggestions = await option.handler(previousArgs, valueToComplete, endsWithSpace); 266 + if (toComplete.includes('=')) { 267 + // Reconstruct the full flag=value format 268 + this.completions = suggestions.map(suggestion => ({ 269 + value: `${flagName}=${suggestion.value}`, 270 + description: suggestion.description 271 + })); 272 + } else { 273 + this.completions.push(...suggestions); 274 + } 275 + } 276 + return; 277 + } 278 + 279 + // Handle flag name completion 280 + if (toComplete.startsWith('--')) { 281 + for (const [name, option] of command.options) { 282 + if (name.startsWith(toComplete)) { 283 + this.completions.push({ 284 + value: name, 285 + description: option.description 286 + }); 287 + } 288 + } 289 + } 290 + } 291 + 292 + private async handleCommandCompletion( 293 + previousArgs: string[], 294 + toComplete: string, 295 + ) { 296 + const commandParts = [...previousArgs]; 297 + 298 + for (const k of this.commands.keys()) { 299 + if (k === '') continue; 300 + const parts = k.split(' '); 301 + let match = true; 302 + 303 + let i = 0; 304 + while (i < commandParts.length) { 305 + if (parts[i] !== commandParts[i]) { 306 + match = false; 307 + break 308 + } 309 + i++; 310 + } 311 + if (match && parts[i]?.startsWith(toComplete)) { 312 + this.completions.push({ 313 + value: parts[i], 314 + description: this.commands.get(k)!.description 315 + }); 316 + } 317 + } 318 + } 319 + 320 + private async handlePositionalCompletion( 321 + command: Command, 322 + previousArgs: string[], 323 + toComplete: string, 324 + endsWithSpace: boolean, 325 + ) { 326 + const suggestions = await command.handler(previousArgs, toComplete, endsWithSpace); 327 + this.completions.push(...suggestions); 328 + } 329 + } 330 + 331 + export function script( 332 + shell: 'zsh' | 'bash' | 'fish' | 'powershell', 333 + name: string, 334 + x: string 335 + ) { 336 + switch (shell) { 337 + case 'zsh': { 338 + const script = zsh.generate(name, x); 339 + console.log(script); 340 + break; 341 + } 342 + case 'bash': { 343 + const script = bash.generate(name, x); 344 + console.log(script); 345 + break; 346 + } 347 + case 'fish': { 348 + const script = fish.generate(name, x); 349 + console.log(script); 350 + break; 351 + } 352 + case 'powershell': { 353 + const script = powershell.generate(name, x); 354 + console.log(script); 355 + break; 356 + } 357 + default: { 358 + throw new Error(`Unsupported shell: ${shell}`); 359 + } 360 + } 361 + }
src/shared.ts

This is a binary file and will not be displayed.

+143
tests/__snapshots__/cli.test.ts.snap
··· 1 + // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 + 3 + exports[`cli completion tests for cac > cli option completion tests > should complete option for partial input '{ partial: '--p', expected: '--port' }' 1`] = ` 4 + "--port Specify port 5 + :4 6 + " 7 + `; 8 + 9 + exports[`cli completion tests for cac > cli option exclusion tests > should not suggest already specified option '{ specified: '--config', shouldNotContain: '--config' }' 1`] = ` 10 + ":4 11 + " 12 + `; 13 + 14 + exports[`cli completion tests for cac > cli option value handling > should handle unknown options with no completions 1`] = `":4"`; 15 + 16 + exports[`cli completion tests for cac > cli option value handling > should not show duplicate options 1`] = ` 17 + "--config Use specified config file 18 + --mode Set env mode 19 + --logLevel info | warn | error | silent 20 + :4 21 + " 22 + `; 23 + 24 + exports[`cli completion tests for cac > cli option value handling > should resolve config option values correctly 1`] = ` 25 + "vite.config.ts Vite config file 26 + vite.config.js Vite config file 27 + :4 28 + " 29 + `; 30 + 31 + exports[`cli completion tests for cac > cli option value handling > should resolve port value correctly 1`] = ` 32 + "--port=3000 Development server port 33 + :4 34 + " 35 + `; 36 + 37 + exports[`cli completion tests for cac > edge case completions for end with space > should keep suggesting the --port option if user typed partial but didn't end with space 1`] = ` 38 + "--port Specify port 39 + :4 40 + " 41 + `; 42 + 43 + exports[`cli completion tests for cac > edge case completions for end with space > should suggest port values if user ends with space after \`--port\` 1`] = ` 44 + "3000 Development server port 45 + 8080 Alternative port 46 + :4 47 + " 48 + `; 49 + 50 + exports[`cli completion tests for cac > edge case completions for end with space > should suggest port values if user typed \`--port=\` and hasn't typed a space or value yet 1`] = ` 51 + "--port=3000 Development server port 52 + --port=8080 Alternative port 53 + :4 54 + " 55 + `; 56 + 57 + exports[`cli completion tests for cac > positional argument completions > should complete multiple positional arguments when ending with part of the value 1`] = ` 58 + "index.ts Index file 59 + :4 60 + " 61 + `; 62 + 63 + exports[`cli completion tests for cac > positional argument completions > should complete multiple positional arguments when ending with space 1`] = ` 64 + "main.ts Main file 65 + index.ts Index file 66 + :4 67 + " 68 + `; 69 + 70 + exports[`cli completion tests for cac > positional argument completions > should complete single positional argument when ending with space 1`] = ` 71 + "main.ts Main file 72 + index.ts Index file 73 + :4 74 + " 75 + `; 76 + 77 + exports[`cli completion tests for cac > should complete cli options 1`] = ` 78 + "dev Start dev server 79 + lint Lint project 80 + :4 81 + " 82 + `; 83 + 84 + exports[`cli completion tests for citty > cli option completion tests > should complete option for partial input '{ partial: '--p', expected: '--port' }' 1`] = ` 85 + "--port Specify port 86 + :4 87 + " 88 + `; 89 + 90 + exports[`cli completion tests for citty > cli option exclusion tests > should not suggest already specified option '{ specified: '--config', shouldNotContain: '--config' }' 1`] = ` 91 + ":4 92 + " 93 + `; 94 + 95 + exports[`cli completion tests for citty > cli option value handling > should handle unknown options with no completions 1`] = `":4"`; 96 + 97 + exports[`cli completion tests for citty > cli option value handling > should not show duplicate options 1`] = ` 98 + "--config Use specified config file 99 + --mode Set env mode 100 + --logLevel info | warn | error | silent 101 + :4 102 + " 103 + `; 104 + 105 + exports[`cli completion tests for citty > cli option value handling > should resolve config option values correctly 1`] = ` 106 + "vite.config.ts Vite config file 107 + vite.config.js Vite config file 108 + :4 109 + " 110 + `; 111 + 112 + exports[`cli completion tests for citty > cli option value handling > should resolve port value correctly 1`] = ` 113 + "--port=3000 Development server port 114 + :4 115 + " 116 + `; 117 + 118 + exports[`cli completion tests for citty > edge case completions for end with space > should keep suggesting the --port option if user typed partial but didn't end with space 1`] = ` 119 + "--port Specify port 120 + :4 121 + " 122 + `; 123 + 124 + exports[`cli completion tests for citty > edge case completions for end with space > should suggest port values if user ends with space after \`--port\` 1`] = ` 125 + "3000 Development server port 126 + 8080 Alternative port 127 + :4 128 + " 129 + `; 130 + 131 + exports[`cli completion tests for citty > edge case completions for end with space > should suggest port values if user typed \`--port=\` and hasn't typed a space or value yet 1`] = ` 132 + "--port=3000 Development server port 133 + --port=8080 Alternative port 134 + :4 135 + " 136 + `; 137 + 138 + exports[`cli completion tests for citty > should complete cli options 1`] = ` 139 + "dev Start dev server 140 + lint Lint project 141 + :4 142 + " 143 + `;
+140 -106
tests/cli.test.ts
··· 1 - import { exec } from "child_process"; 2 - import { describe, it, expect, test } from "vitest"; 3 - 4 - function runCommand(command: string): Promise<string> { 5 - return new Promise((resolve, reject) => { 6 - exec(command, (error, stdout, stderr) => { 7 - if (error) { 8 - reject(stderr); 9 - } else { 10 - resolve(stdout); 11 - } 12 - }); 13 - }); 14 - } 15 - 16 - const cliTools = ["cac", "citty"]; 17 - 18 - describe.each(cliTools)("cli completion tests for %s", (cliTool) => { 19 - const commandPrefix = `pnpm tsx demo.${cliTool}.ts complete --`; 20 - 21 - // it("should complete vite commands", async () => { 22 - // const output = await runCommand(commandPrefix); 23 - // console.log(`[${cliTool}] Command Output:`, output); 24 - // expect(output).toContain("src/"); 25 - // expect(output).toContain("./"); 26 - // // expect(output).toContain('--base'); 27 - // }); 28 - 29 - it("should complete cli options", async () => { 30 - const output = await runCommand(`${commandPrefix} --`); 31 - console.log(`[${cliTool}] Command Output:`, output); 32 - expect(output).toContain("--port"); 33 - expect(output).toContain("--config"); 34 - expect(output).toContain("--base"); 35 - expect(output).toContain("--logLevel"); 36 - expect(output).toContain("--filter"); 37 - expect(output).toContain("--mode"); 38 - }); 39 - 40 - describe("cli option completion tests", () => { 41 - const optionTests = [ 42 - { partial: "--p", expected: "--port" }, 43 - ]; 44 - 45 - test.each(optionTests)( 46 - "should complete option for partial input '%s'", 47 - async ({ partial, expected }) => { 48 - const command = `${commandPrefix} ${partial}`; 49 - const output = await runCommand(command); 50 - console.log(`[${cliTool}] Complete ${partial} Output:`, output); 51 - expect(output).toContain(expected); 52 - } 53 - ); 54 - }); 55 - 56 - describe("cli option exclusion tests", () => { 57 - const alreadySpecifiedTests = [ 58 - { specified: "--port", shouldNotContain: "--port" }, 59 - ]; 60 - 61 - test.each(alreadySpecifiedTests)( 62 - "should not suggest already specified option '%s'", 63 - async ({ specified, shouldNotContain }) => { 64 - const command = `${commandPrefix} ${specified} --`; 65 - const output = await runCommand(command); 66 - console.log(`[${cliTool}] Already Specified ${specified} Output:`, output); 67 - expect(output).not.toContain(shouldNotContain); 68 - // expect(output).toContain("--base"); 69 - } 70 - ); 71 - }); 72 - 73 - describe("cli option value handling", () => { 74 - 75 - it("should resolve port value correctly", async () => { 76 - const command = `${commandPrefix} --port 3`; 77 - const output = await runCommand(command); 78 - console.log(`[${cliTool}] Port Value Output:`, output); 79 - expect(output).toContain("3000"); 80 - }); 81 - 82 - it("should handle conflicting options appropriately", async () => { 83 - const command = `${commandPrefix} --port 3000 --`; 84 - const output = await runCommand(command); 85 - console.log(`[${cliTool}] Conflicting Options Output:`, output); 86 - expect(output).not.toContain("--port"); 87 - expect(output).toContain("--config"); 88 - // expect(output).toContain("--base"); 89 - }); 90 - 91 - it("should resolve config option values correctly", async () => { 92 - const command = `${commandPrefix} --port 3000 --config vite.config`; 93 - const output = await runCommand(command); 94 - console.log(`[${cliTool}] Config Option Output:`, output); 95 - expect(output).toContain("vite.config.ts"); 96 - expect(output).toContain("vite.config.js"); 97 - }); 98 - 99 - it("should handle unknown options with no completions", async () => { 100 - const command = `${commandPrefix} --unknownoption`; 101 - const output = await runCommand(command); 102 - console.log(`[${cliTool}] No Completion Available Output:`, output); 103 - expect(output.trim()).toMatch(/^(:\d+)?$/); 104 - }); 105 - }); 106 - }); 1 + import { exec } from 'child_process'; 2 + import { describe, it, expect, test } from 'vitest'; 3 + 4 + function runCommand(command: string): Promise<string> { 5 + return new Promise((resolve, reject) => { 6 + exec(command, (error, stdout, stderr) => { 7 + if (error) { 8 + reject(stderr); 9 + } else { 10 + resolve(stdout); 11 + } 12 + }); 13 + }); 14 + } 15 + 16 + const cliTools = ['citty', 'cac']; 17 + // const cliTools = ['citty', 'cac']; 18 + 19 + describe.each(cliTools)('cli completion tests for %s', (cliTool) => { 20 + const commandPrefix = `pnpm tsx demo.${cliTool}.ts complete --`; 21 + 22 + it('should complete cli options', async () => { 23 + const output = await runCommand(`${commandPrefix}`); 24 + expect(output).toMatchSnapshot(); 25 + }); 26 + 27 + describe('cli option completion tests', () => { 28 + const optionTests = [{ partial: '--p', expected: '--port' }]; 29 + 30 + test.each(optionTests)( 31 + "should complete option for partial input '%s'", 32 + async ({ partial }) => { 33 + const command = `${commandPrefix} dev ${partial}`; 34 + const output = await runCommand(command); 35 + expect(output).toMatchSnapshot(); 36 + } 37 + ); 38 + }); 39 + 40 + describe('cli option exclusion tests', () => { 41 + const alreadySpecifiedTests = [ 42 + { specified: '--config', shouldNotContain: '--config' }, 43 + ]; 44 + 45 + test.each(alreadySpecifiedTests)( 46 + "should not suggest already specified option '%s'", 47 + async ({ specified }) => { 48 + const command = `${commandPrefix} ${specified} --`; 49 + const output = await runCommand(command); 50 + console.log(output) 51 + expect(output).toMatchSnapshot(); 52 + } 53 + ); 54 + }); 55 + 56 + describe('cli option value handling', () => { 57 + it('should resolve port value correctly', async () => { 58 + const command = `${commandPrefix} dev --port=3`; 59 + const output = await runCommand(command); 60 + expect(output).toMatchSnapshot(); 61 + }); 62 + 63 + it('should not show duplicate options', async () => { 64 + const command = `${commandPrefix} --config vite.config.js --`; 65 + const output = await runCommand(command); 66 + expect(output).toMatchSnapshot(); 67 + }); 68 + 69 + it('should resolve config option values correctly', async () => { 70 + const command = `${commandPrefix} --config vite.config`; 71 + const output = await runCommand(command); 72 + expect(output).toMatchSnapshot(); 73 + }); 74 + 75 + it('should handle unknown options with no completions', async () => { 76 + const command = `${commandPrefix} --unknownoption`; 77 + const output = await runCommand(command); 78 + expect(output.trim()).toMatchSnapshot(); 79 + }); 80 + }); 81 + 82 + describe('edge case completions for end with space', () => { 83 + //TOOD: remove this 84 + it('should suggest port values if user ends with space after `--port`', async () => { 85 + const command = `${commandPrefix} dev --port ""`; 86 + const output = await runCommand(command); 87 + expect(output).toMatchSnapshot(); 88 + }); 89 + 90 + it("should keep suggesting the --port option if user typed partial but didn't end with space", async () => { 91 + const command = `${commandPrefix} dev --po`; 92 + const output = await runCommand(command); 93 + expect(output).toMatchSnapshot(); 94 + }); 95 + 96 + it("should suggest port values if user typed `--port=` and hasn't typed a space or value yet", async () => { 97 + const command = `${commandPrefix} dev --port=`; 98 + const output = await runCommand(command); 99 + expect(output).toMatchSnapshot(); 100 + }); 101 + }); 102 + 103 + // single positional command: `lint [file]` 104 + // vite "" 105 + // -> src/ 106 + // -> ./ 107 + 108 + // vite src/ "" 109 + // -> nothing 110 + // should not suggest anything 111 + 112 + // multiple postiionals command `lint [...files]` 113 + // vite "" 114 + // -> src/ 115 + // -> ./ 116 + 117 + // vite src/ "" 118 + // -> src/ 119 + // -> ./ 120 + 121 + describe('positional argument completions', () => { 122 + it.runIf(cliTool !== 'citty')('should complete multiple positional arguments when ending with space', async () => { 123 + const command = `${commandPrefix} lint ""`; 124 + const output = await runCommand(command); 125 + expect(output).toMatchSnapshot(); 126 + }); 127 + 128 + it.runIf(cliTool !== 'citty')('should complete multiple positional arguments when ending with part of the value', async () => { 129 + const command = `${commandPrefix} lint ind`; 130 + const output = await runCommand(command); 131 + expect(output).toMatchSnapshot(); 132 + }); 133 + 134 + it.runIf(cliTool !== 'citty')('should complete single positional argument when ending with space', async () => { 135 + const command = `${commandPrefix} lint main.ts ""`; 136 + const output = await runCommand(command); 137 + expect(output).toMatchSnapshot(); 138 + }); 139 + }); 140 + });
+111
tsconfig.json
··· 1 + { 2 + "compilerOptions": { 3 + /* Visit https://aka.ms/tsconfig to read more about this file */ 4 + 5 + /* Projects */ 6 + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 9 + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 10 + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 + 13 + /* Language and Environment */ 14 + "target": "es2022" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, 15 + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 + // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ 18 + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 20 + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 22 + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 23 + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 26 + 27 + /* Modules */ 28 + "module": "es2022" /* Specify what module code is generated. */, 29 + // "rootDir": "./", /* Specify the root folder within your source files. */ 30 + "moduleResolution": "node10" /* Specify how TypeScript looks up a file from a given module specifier. */, 31 + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 35 + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 36 + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 37 + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 38 + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ 39 + // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */ 40 + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ 41 + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ 42 + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ 43 + // "noUncheckedSideEffectImports": true, /* Check side effect imports. */ 44 + // "resolveJsonModule": true, /* Enable importing .json files. */ 45 + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ 46 + // "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */ 47 + 48 + /* JavaScript Support */ 49 + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 50 + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 51 + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 52 + 53 + /* Emit */ 54 + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 55 + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 56 + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 57 + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 58 + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 59 + // "noEmit": true, /* Disable emitting files from a compilation. */ 60 + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ 61 + // "outDir": "./", /* Specify an output folder for all emitted files. */ 62 + // "removeComments": true, /* Disable emitting comments. */ 63 + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 64 + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 65 + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 66 + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 67 + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 68 + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 69 + // "newLine": "crlf", /* Set the newline character for emitting files. */ 70 + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 71 + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 72 + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 73 + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 74 + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 75 + 76 + /* Interop Constraints */ 77 + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 78 + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ 79 + // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */ 80 + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 81 + "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, 82 + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 83 + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, 84 + 85 + /* Type Checking */ 86 + "strict": true /* Enable all strict type-checking options. */, 87 + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 88 + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 89 + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 90 + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 91 + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 92 + // "strictBuiltinIteratorReturn": true, /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */ 93 + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 94 + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 95 + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 96 + "noUnusedLocals": true /* Enable error reporting when local variables aren't read. */, 97 + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 98 + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 99 + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 100 + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 101 + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 102 + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 103 + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 104 + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 105 + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 106 + 107 + /* Completeness */ 108 + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 109 + "skipLibCheck": true /* Skip type checking all .d.ts files. */ 110 + } 111 + }
+1 -2
zsh.ts src/zsh.ts
··· 1 - import { ShellCompDirective } from "./shared"; 1 + import { ShellCompDirective } from './'; 2 2 3 3 export function generate(name: string, exec: string) { 4 4 return `#compdef ${name} ··· 212 212 fi 213 213 `; 214 214 } 215 -