From b622dc082221cb86847116571a27a660bb1c914d Mon Sep 17 00:00:00 2001 From: Jovi De Croock Date: Sun, 5 Jul 2026 14:36:09 +0200 Subject: [PATCH 1/6] feat: add VSCode extension contributing GraphQLSP and GraphQL grammars Adds packages/vscode-graphqlsp, a VSCode extension that: - contributes @0no-co/graphqlsp to the built-in TypeScript language features as a tsserver plugin, so projects get diagnostics, completions, hover info, and go-to-definition without installing the plugin locally - adds a TextMate grammar and language configuration for .graphql, .gql, and .graphqls files - adds an injection grammar highlighting GraphQL in gql`...` and graphql`...` tagged templates, gql(`...`)/graphql(`...`) call expressions, and untagged templates starting with #graphql - forwards graphqlsp.* editor settings to the plugin via the TS extension's configurePlugin API The plugin itself now detects being loaded as a "global" tsserver plugin without configuration and passes the language service through untouched, so the extension doesn't surface configuration errors in projects that never set up GraphQLSP. Co-Authored-By: Claude Fable 5 --- .changeset/global-plugin-dormancy.md | 5 + .gitignore | 4 + packages/graphqlsp/src/index.ts | 17 + packages/vscode-graphqlsp/.vscode/launch.json | 12 + packages/vscode-graphqlsp/.vscodeignore | 8 + packages/vscode-graphqlsp/LICENSE.md | 21 + packages/vscode-graphqlsp/README.md | 85 + .../language-configuration.json | 24 + packages/vscode-graphqlsp/package.json | 189 ++ packages/vscode-graphqlsp/scripts/package.mjs | 139 ++ packages/vscode-graphqlsp/src/extension.ts | 81 + .../syntaxes/graphql.js.tmLanguage.json | 78 + .../syntaxes/graphql.tmLanguage.json | 123 ++ packages/vscode-graphqlsp/tsconfig.json | 13 + pnpm-lock.yaml | 1841 ++++++++++++++++- pnpm-workspace.yaml | 5 + 16 files changed, 2638 insertions(+), 7 deletions(-) create mode 100644 .changeset/global-plugin-dormancy.md create mode 100644 packages/vscode-graphqlsp/.vscode/launch.json create mode 100644 packages/vscode-graphqlsp/.vscodeignore create mode 100644 packages/vscode-graphqlsp/LICENSE.md create mode 100644 packages/vscode-graphqlsp/README.md create mode 100644 packages/vscode-graphqlsp/language-configuration.json create mode 100644 packages/vscode-graphqlsp/package.json create mode 100644 packages/vscode-graphqlsp/scripts/package.mjs create mode 100644 packages/vscode-graphqlsp/src/extension.ts create mode 100644 packages/vscode-graphqlsp/syntaxes/graphql.js.tmLanguage.json create mode 100644 packages/vscode-graphqlsp/syntaxes/graphql.tmLanguage.json create mode 100644 packages/vscode-graphqlsp/tsconfig.json diff --git a/.changeset/global-plugin-dormancy.md b/.changeset/global-plugin-dormancy.md new file mode 100644 index 00000000..459326b8 --- /dev/null +++ b/.changeset/global-plugin-dormancy.md @@ -0,0 +1,5 @@ +--- +'@0no-co/graphqlsp': minor +--- + +Support being loaded as a "global" tsserver plugin, as contributed by editor extensions. When loaded globally without any `schema`/`schemas` configuration the plugin now passes the language service through untouched, instead of reporting configuration errors in projects that never set up GraphQLSP. diff --git a/.gitignore b/.gitignore index 2b55b9e2..c55649b3 100644 --- a/.gitignore +++ b/.gitignore @@ -108,3 +108,7 @@ dist packages/graphqlsp/api/* packages/graphqlsp/api + +# VSCode extension packaging +packages/vscode-graphqlsp/.staging +*.vsix diff --git a/packages/graphqlsp/src/index.ts b/packages/graphqlsp/src/index.ts index c8d09492..cec56956 100644 --- a/packages/graphqlsp/src/index.ts +++ b/packages/graphqlsp/src/index.ts @@ -55,6 +55,23 @@ function create(info: ts.server.PluginCreateInfo) { info.project.projectService.logger.info(`[GraphQLSP] ${msg}`); const config: Config = info.config; + // When an editor extension contributes GraphQLSP, tsserver loads it as a + // "global" plugin into every project — including ones that never set up + // GraphQLSP. Without any schema configuration there's nothing to do, so + // the language service is passed through untouched rather than surfacing + // "missing schema" configuration errors in unrelated projects. (tsserver + // marks the synthetic config entry of global plugins with `global: true`, + // and skips the global copy when a project's tsconfig lists the plugin + // under the same name.) + if ( + (config as { global?: boolean }).global && + config.schema === undefined && + config.schemas === undefined + ) { + logger('Loaded as a global plugin without configuration; skipping setup'); + return createBasicDecorator(info); + } + logger('config: ' + JSON.stringify(config)); logger('Setting up the GraphQL Plugin'); diff --git a/packages/vscode-graphqlsp/.vscode/launch.json b/packages/vscode-graphqlsp/.vscode/launch.json new file mode 100644 index 00000000..2906cd79 --- /dev/null +++ b/packages/vscode-graphqlsp/.vscode/launch.json @@ -0,0 +1,12 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Run Extension", + "type": "extensionHost", + "request": "launch", + "args": ["--extensionDevelopmentPath=${workspaceFolder}"], + "outFiles": ["${workspaceFolder}/dist/**/*.js"] + } + ] +} diff --git a/packages/vscode-graphqlsp/.vscodeignore b/packages/vscode-graphqlsp/.vscodeignore new file mode 100644 index 00000000..300c6834 --- /dev/null +++ b/packages/vscode-graphqlsp/.vscodeignore @@ -0,0 +1,8 @@ +src/** +scripts/** +tsconfig.json +*.tsbuildinfo +**/*.map +.staging/** +*.vsix +*.tgz diff --git a/packages/vscode-graphqlsp/LICENSE.md b/packages/vscode-graphqlsp/LICENSE.md new file mode 100644 index 00000000..c986530b --- /dev/null +++ b/packages/vscode-graphqlsp/LICENSE.md @@ -0,0 +1,21 @@ +# MIT License + +Copyright (c) 2026 0no.co + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/vscode-graphqlsp/README.md b/packages/vscode-graphqlsp/README.md new file mode 100644 index 00000000..edf825c7 --- /dev/null +++ b/packages/vscode-graphqlsp/README.md @@ -0,0 +1,85 @@ +# GraphQLSP for VSCode + +VSCode extension for [GraphQLSP](https://github.com/0no-co/GraphQLSP), bringing schema-aware +GraphQL support to TypeScript and JavaScript: + +- **TypeScript server plugin** — contributes `@0no-co/graphqlsp` to VSCode's built-in + TypeScript language features, so you get diagnostics, auto-completion, hover information, + and go-to-definition for GraphQL documents without installing the plugin per project. +- **Syntax highlighting** for `.graphql`, `.gql`, and `.graphqls` files. +- **Inline syntax highlighting** for GraphQL documents in TypeScript/JavaScript: + `` gql`...` `` and `` graphql`...` `` tagged templates, `` graphql(`...`) `` call + expressions (the [gql.tada](https://gql-tada.0no.co) style), and untagged template + literals starting with a `#graphql` comment. + +## Setup + +The recommended way to configure GraphQLSP is in your project's `tsconfig.json`, which keeps +the configuration shared with your whole team and CI: + +```jsonc +{ + "compilerOptions": { + "plugins": [ + { + "name": "@0no-co/graphqlsp", + "schema": "./schema.graphql" + } + ] + } +} +``` + +When a project lists the plugin in its `tsconfig.json`, that configuration is used as-is. +The project doesn't need `@0no-co/graphqlsp` in its own `node_modules` — tsserver falls +back to the copy bundled with this extension. (gql.tada projects using `gql.tada/ts-plugin` +keep working unchanged; that plugin resolves from the project's dependencies.) + +Alternatively — e.g. for projects whose tsconfig you don't control — the plugin can be +configured through VSCode settings: + +```jsonc +{ + "graphqlsp.schema": "./schema.graphql", + "graphqlsp.templateIsCallExpression": false +} +``` + +The settings mirror the plugin's options (`graphqlsp.schema`, `graphqlsp.schemas`, +`graphqlsp.template`, `graphqlsp.templateIsCallExpression`, +`graphqlsp.shouldCheckForColocatedFragments`, `graphqlsp.trackFieldUsage`, +`graphqlsp.clientDirectives`, `graphqlsp.tadaOutputLocation`, +`graphqlsp.tadaDisablePreprocessing`); see the +[GraphQLSP README](https://github.com/0no-co/GraphQLSP#readme) for what they do. VSCode +settings only apply to projects that _don't_ configure the plugin in their `tsconfig.json`, +and changes require a TypeScript server restart (the extension offers one when settings +change). + +Without any configuration in either place, the language service plugin stays dormant and +only the syntax highlighting is active. + +> **Note:** If you use a TypeScript version installed in your workspace, run the +> **“TypeScript: Select TypeScript Version…”** command and ensure the workspace version is +> used; the plugin is enabled for both the bundled and workspace versions. + +## Development + +```sh +pnpm install +pnpm --filter vscode-graphqlsp build +``` + +Open `packages/vscode-graphqlsp` in VSCode and press F5 (“Run Extension”) to launch an +Extension Development Host. To inspect plugin logs, run the +**“TypeScript: Open TS Server log”** command in the development host and search for +`[GraphQLSP]`. + +To build an installable `.vsix`: + +```sh +pnpm --filter vscode-graphqlsp package +``` + +This stages the extension together with an npm-installed copy of the workspace's +`@0no-co/graphqlsp` (pnpm's symlinked layout can't be packaged directly) and runs +`vsce package` on it. diff --git a/packages/vscode-graphqlsp/language-configuration.json b/packages/vscode-graphqlsp/language-configuration.json new file mode 100644 index 00000000..e5bf5db2 --- /dev/null +++ b/packages/vscode-graphqlsp/language-configuration.json @@ -0,0 +1,24 @@ +{ + "comments": { + "lineComment": "#" + }, + "brackets": [ + ["{", "}"], + ["[", "]"], + ["(", ")"] + ], + "autoClosingPairs": [ + { "open": "{", "close": "}" }, + { "open": "[", "close": "]" }, + { "open": "(", "close": ")" }, + { "open": "\"\"\"", "close": "\"\"\"", "notIn": ["string"] }, + { "open": "\"", "close": "\"", "notIn": ["string"] } + ], + "surroundingPairs": [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ["\"", "\""] + ], + "wordPattern": "[_A-Za-z][_0-9A-Za-z]*" +} diff --git a/packages/vscode-graphqlsp/package.json b/packages/vscode-graphqlsp/package.json new file mode 100644 index 00000000..31542616 --- /dev/null +++ b/packages/vscode-graphqlsp/package.json @@ -0,0 +1,189 @@ +{ + "name": "vscode-graphqlsp", + "displayName": "GraphQLSP", + "version": "0.1.0", + "private": true, + "description": "GraphQL syntax highlighting and schema-aware TypeScript support — diagnostics, auto-complete, hover information, and go-to-definition for GraphQL documents — powered by GraphQLSP.", + "publisher": "0no-co", + "author": "0no.co ", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/0no-co/GraphQLSP.git", + "directory": "packages/vscode-graphqlsp" + }, + "bugs": { + "url": "https://github.com/0no-co/GraphQLSP/issues" + }, + "homepage": "https://github.com/0no-co/GraphQLSP#readme", + "keywords": [ + "GraphQL", + "TypeScript", + "gql.tada", + "urql", + "syntax-highlighting" + ], + "categories": [ + "Programming Languages", + "Linters" + ], + "engines": { + "vscode": "^1.80.0" + }, + "main": "./dist/extension.js", + "extensionKind": [ + "workspace" + ], + "capabilities": { + "untrustedWorkspaces": { + "supported": false, + "description": "GraphQLSP runs as a TypeScript server plugin, which is disabled in untrusted workspaces." + } + }, + "activationEvents": [ + "onLanguage:javascript", + "onLanguage:javascriptreact", + "onLanguage:typescript", + "onLanguage:typescriptreact" + ], + "contributes": { + "typescriptServerPlugins": [ + { + "name": "@0no-co/graphqlsp", + "enableForWorkspaceTypeScriptVersions": true + } + ], + "languages": [ + { + "id": "graphql", + "aliases": [ + "GraphQL", + "graphql" + ], + "extensions": [ + ".graphql", + ".gql", + ".graphqls" + ], + "configuration": "./language-configuration.json" + } + ], + "grammars": [ + { + "language": "graphql", + "scopeName": "source.graphql", + "path": "./syntaxes/graphql.tmLanguage.json" + }, + { + "scopeName": "inline.graphql", + "path": "./syntaxes/graphql.js.tmLanguage.json", + "injectTo": [ + "source.js", + "source.js.jsx", + "source.jsx", + "source.ts", + "source.tsx" + ], + "embeddedLanguages": { + "meta.embedded.block.graphql": "graphql", + "meta.template.expression.ts": "typescript" + } + } + ], + "configuration": { + "title": "GraphQLSP", + "properties": { + "graphqlsp.schema": { + "type": [ + "string", + "object", + "null" + ], + "default": null, + "markdownDescription": "Path to a `.graphql` SDL file, an introspection JSON file, or the URL of a GraphQL API to introspect. May also be an object of the shape `{ \"url\": \"...\", \"headers\": { ... } }`.\n\nProjects that list `@0no-co/graphqlsp` (or `gql.tada/ts-plugin`) under `compilerOptions.plugins` in their `tsconfig.json` are configured from there instead, and these editor settings don't apply to them." + }, + "graphqlsp.schemas": { + "type": [ + "array", + "null" + ], + "default": null, + "markdownDescription": "Multi-schema configuration; an array of `{ \"name\": \"...\", \"schema\": \"...\", \"tadaOutputLocation\": \"...\" }` objects. Mutually exclusive with `#graphqlsp.schema#`." + }, + "graphqlsp.template": { + "type": [ + "string", + "null" + ], + "default": null, + "markdownDescription": "An additional template tag or function name to detect GraphQL documents by, in addition to the defaults (`gql` and `graphql`)." + }, + "graphqlsp.templateIsCallExpression": { + "type": [ + "boolean", + "null" + ], + "default": null, + "markdownDescription": "When `true`, GraphQL documents are detected in `graphql('...')` call expressions (the gql.tada style); when `false`, in tagged template literals. Defaults to `true`." + }, + "graphqlsp.shouldCheckForColocatedFragments": { + "type": [ + "boolean", + "null" + ], + "default": null, + "markdownDescription": "When enabled, GraphQLSP checks whether fragments exported from imported files are used in the current document." + }, + "graphqlsp.trackFieldUsage": { + "type": [ + "boolean", + "null" + ], + "default": null, + "markdownDescription": "When enabled, GraphQLSP warns about queried fields that are never used in the surrounding code." + }, + "graphqlsp.clientDirectives": { + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": null, + "markdownDescription": "Additional client-side directive names that shouldn't be validated against the schema." + }, + "graphqlsp.tadaOutputLocation": { + "type": [ + "string", + "null" + ], + "default": null, + "markdownDescription": "Location (file or directory) that the gql.tada introspection output is written to." + }, + "graphqlsp.tadaDisablePreprocessing": { + "type": [ + "boolean", + "null" + ], + "default": null, + "markdownDescription": "Disables preprocessing of the gql.tada introspection output." + } + } + } + }, + "scripts": { + "build": "tsc -p tsconfig.json", + "package": "pnpm build && node ./scripts/package.mjs", + "vscode:prepublish": "pnpm build" + }, + "dependencies": { + "@0no-co/graphqlsp": "workspace:*" + }, + "devDependencies": { + "@types/node": "^18.15.11", + "@types/vscode": "1.80.0", + "@vscode/vsce": "^3.3.0", + "typescript": "^5.3.3" + } +} diff --git a/packages/vscode-graphqlsp/scripts/package.mjs b/packages/vscode-graphqlsp/scripts/package.mjs new file mode 100644 index 00000000..791f0246 --- /dev/null +++ b/packages/vscode-graphqlsp/scripts/package.mjs @@ -0,0 +1,139 @@ +/* Packages the extension into a .vsix. + * + * The extension ships `@0no-co/graphqlsp` inside its `node_modules` so + * tsserver can resolve the plugin from the extension's install location + * (VSCode passes it as a plugin probe location). pnpm's symlinked + * `node_modules` layout can't be packaged by vsce directly, so this stages + * a copy of the extension, installs the workspace's graphqlsp tarball with + * npm to get a regular flat `node_modules`, and runs vsce there. */ + +import { execFileSync } from 'node:child_process'; +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const extensionRoot = path.resolve( + path.dirname(fileURLToPath(import.meta.url)), + '..' +); +const repoRoot = path.resolve(extensionRoot, '../..'); +const stagingDir = path.join(extensionRoot, '.staging'); + +const run = (command, args, cwd) => { + console.log(`> ${command} ${args.join(' ')}`); + execFileSync(command, args, { cwd, stdio: 'inherit' }); +}; + +fs.rmSync(stagingDir, { recursive: true, force: true }); +fs.mkdirSync(stagingDir, { recursive: true }); + +// Pack the workspace's graphqlsp into a tarball (this builds it through its +// prepublishOnly script) +run( + 'pnpm', + ['--filter', '@0no-co/graphqlsp', 'pack', '--pack-destination', stagingDir], + repoRoot +); +const tarball = fs.readdirSync(stagingDir).find(file => file.endsWith('.tgz')); +if (!tarball) throw new Error('pnpm pack did not produce a tarball'); + +for (const file of [ + 'dist', + 'syntaxes', + 'language-configuration.json', + 'README.md', + 'LICENSE.md', + '.vscodeignore', +]) { + fs.cpSync(path.join(extensionRoot, file), path.join(stagingDir, file), { + recursive: true, + }); +} + +const manifest = JSON.parse( + fs.readFileSync(path.join(extensionRoot, 'package.json'), 'utf8') +); +delete manifest.private; +delete manifest.scripts; +delete manifest.devDependencies; +manifest.dependencies = { '@0no-co/graphqlsp': `file:./${tarball}` }; +fs.writeFileSync( + path.join(stagingDir, 'package.json'), + JSON.stringify(manifest, null, 2) +); + +// npm rather than pnpm: it produces the plain nested node_modules layout +// that both tsserver's module resolution and vsce's file collection expect. +// --legacy-peer-deps keeps npm from installing graphqlsp's `typescript` +// peer dependency (23MB), which tsserver provides at runtime anyway +run( + 'npm', + [ + 'install', + '--omit=dev', + '--legacy-peer-deps', + '--no-audit', + '--no-fund', + '--no-package-lock', + ], + stagingDir +); + +// vsce collects dependency files via `npm list --production`, which fails +// on unmet peer dependencies; typescript is deliberately not bundled +// (tsserver provides it at runtime), so drop peer ranges from the staged +// packages to keep npm's dependency graph valid +const stripPeerDependencies = dir => { + for (const entry of fs.readdirSync(dir)) { + if (entry.startsWith('.')) continue; + if (entry.startsWith('@')) { + stripPeerDependencies(path.join(dir, entry)); + continue; + } + const manifestPath = path.join(dir, entry, 'package.json'); + if (!fs.existsSync(manifestPath)) continue; + const packageManifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')); + if (packageManifest.peerDependencies) { + delete packageManifest.peerDependencies; + delete packageManifest.peerDependenciesMeta; + fs.writeFileSync(manifestPath, JSON.stringify(packageManifest, null, 2)); + } + } +}; +stripPeerDependencies(path.join(stagingDir, 'node_modules')); +// npm's hidden lockfile takes precedence over the edited package.json +// files when npm reconstructs the tree, so it has to go too +fs.rmSync(path.join(stagingDir, 'node_modules', '.package-lock.json'), { + force: true, +}); + +// Without the lockfile npm can no longer tell that the installed copy came +// from the `file:` tarball, so point the dependency at the exact version +const installedPlugin = JSON.parse( + fs.readFileSync( + path.join( + stagingDir, + 'node_modules', + '@0no-co', + 'graphqlsp', + 'package.json' + ), + 'utf8' + ) +); +manifest.dependencies = { '@0no-co/graphqlsp': installedPlugin.version }; +fs.writeFileSync( + path.join(stagingDir, 'package.json'), + JSON.stringify(manifest, null, 2) +); + +const output = path.join( + extensionRoot, + `vscode-graphqlsp-${manifest.version}.vsix` +); +run( + path.join(extensionRoot, 'node_modules', '.bin', 'vsce'), + ['package', '--out', output], + stagingDir +); +console.log(`\nPackaged ${output}`); diff --git a/packages/vscode-graphqlsp/src/extension.ts b/packages/vscode-graphqlsp/src/extension.ts new file mode 100644 index 00000000..c9efb883 --- /dev/null +++ b/packages/vscode-graphqlsp/src/extension.ts @@ -0,0 +1,81 @@ +import * as vscode from 'vscode'; + +/** Must match the `typescriptServerPlugins` contribution in package.json. */ +const pluginName = '@0no-co/graphqlsp'; +const configurationSection = 'graphqlsp'; + +/** Settings forwarded verbatim to the tsserver plugin's configuration. */ +const pluginSettings = [ + 'schema', + 'schemas', + 'template', + 'templateIsCallExpression', + 'shouldCheckForColocatedFragments', + 'trackFieldUsage', + 'clientDirectives', + 'tadaOutputLocation', + 'tadaDisablePreprocessing', +] as const; + +interface TypeScriptLanguageFeaturesApi { + configurePlugin(pluginId: string, configuration: unknown): void; +} + +interface TypeScriptLanguageFeaturesExports { + getAPI(version: 0): TypeScriptLanguageFeaturesApi | undefined; +} + +const getPluginConfiguration = (): Record | undefined => { + const settings = vscode.workspace.getConfiguration(configurationSection); + let configuration: Record | undefined; + for (const key of pluginSettings) { + const value = settings.get(key); + if (value !== null && value !== undefined) { + (configuration || (configuration = {}))[key] = value; + } + } + return configuration; +}; + +export async function activate( + context: vscode.ExtensionContext +): Promise { + const tsExtension = + vscode.extensions.getExtension( + 'vscode.typescript-language-features' + ); + if (!tsExtension) return; + + const api = (await tsExtension.activate()).getAPI(0); + if (!api) return; + + const synchronize = () => { + const configuration = getPluginConfiguration(); + // Without any editor settings the plugin is configured through the + // project's tsconfig instead. Sending an empty configuration would + // replace tsserver's `global: true` marker on the plugin's config + // entry, which the plugin relies on to stay dormant in projects that + // never set up GraphQLSP. + if (configuration) api.configurePlugin(pluginName, configuration); + }; + + synchronize(); + + context.subscriptions.push( + vscode.workspace.onDidChangeConfiguration(async event => { + if (!event.affectsConfiguration(configurationSection)) return; + synchronize(); + // The plugin reads its configuration once per project, so changes + // only take effect after the TypeScript server restarts + const selection = await vscode.window.showInformationMessage( + 'GraphQLSP settings changed. Restart the TypeScript server to apply them?', + 'Restart TS Server' + ); + if (selection === 'Restart TS Server') { + await vscode.commands.executeCommand('typescript.restartTsServer'); + } + }) + ); +} + +export function deactivate(): void {} diff --git a/packages/vscode-graphqlsp/syntaxes/graphql.js.tmLanguage.json b/packages/vscode-graphqlsp/syntaxes/graphql.js.tmLanguage.json new file mode 100644 index 00000000..1cb6252b --- /dev/null +++ b/packages/vscode-graphqlsp/syntaxes/graphql.js.tmLanguage.json @@ -0,0 +1,78 @@ +{ + "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", + "name": "Inline GraphQL", + "scopeName": "inline.graphql", + "injectionSelector": "L:source.js -comment -string, L:source.js.jsx -comment -string, L:source.jsx -comment -string, L:source.ts -comment -string, L:source.tsx -comment -string", + "patterns": [ + { "include": "#graphql-tagged-template" }, + { "include": "#graphql-call-expression" }, + { "include": "#graphql-marked-template" } + ], + "repository": { + "graphql-tagged-template": { + "comment": "gql`...` and graphql`...` tagged template literals", + "begin": "\\b(gql|graphql)\\s*(?:<[^<>]*>)?\\s*(`)", + "beginCaptures": { + "1": { "name": "entity.name.function.tagged-template.js" }, + "2": { "name": "punctuation.definition.string.template.begin.js" } + }, + "end": "`", + "endCaptures": { + "0": { "name": "punctuation.definition.string.template.end.js" } + }, + "contentName": "meta.embedded.block.graphql", + "patterns": [{ "include": "#template-content" }] + }, + "graphql-call-expression": { + "comment": "gql(`...`) and graphql(`...`) call expressions (the gql.tada style)", + "begin": "\\b(gql|graphql)(?:\\s*\\.\\s*(persisted))?\\s*(?:<[^<>]*>)?\\s*(\\()\\s*(`)", + "beginCaptures": { + "1": { "name": "entity.name.function.js" }, + "2": { "name": "entity.name.function.js" }, + "3": { "name": "meta.brace.round.js" }, + "4": { "name": "punctuation.definition.string.template.begin.js" } + }, + "end": "`", + "endCaptures": { + "0": { "name": "punctuation.definition.string.template.end.js" } + }, + "contentName": "meta.embedded.block.graphql", + "patterns": [{ "include": "#template-content" }] + }, + "graphql-marked-template": { + "comment": "Untagged template literals whose content starts with a #graphql comment", + "begin": "(`)(?=\\s*#graphql\\b)", + "beginCaptures": { + "1": { "name": "punctuation.definition.string.template.begin.js" } + }, + "end": "`", + "endCaptures": { + "0": { "name": "punctuation.definition.string.template.end.js" } + }, + "contentName": "meta.embedded.block.graphql", + "patterns": [{ "include": "#template-content" }] + }, + "template-content": { + "patterns": [ + { "include": "#template-substitution" }, + { + "name": "constant.character.escape.js", + "match": "\\\\[`$\\\\]" + }, + { "include": "source.graphql" } + ] + }, + "template-substitution": { + "name": "meta.template.expression.ts", + "begin": "\\$\\{", + "beginCaptures": { + "0": { "name": "punctuation.definition.template-expression.begin.ts" } + }, + "end": "\\}", + "endCaptures": { + "0": { "name": "punctuation.definition.template-expression.end.ts" } + }, + "patterns": [{ "include": "source.ts#expression" }] + } + } +} diff --git a/packages/vscode-graphqlsp/syntaxes/graphql.tmLanguage.json b/packages/vscode-graphqlsp/syntaxes/graphql.tmLanguage.json new file mode 100644 index 00000000..64545275 --- /dev/null +++ b/packages/vscode-graphqlsp/syntaxes/graphql.tmLanguage.json @@ -0,0 +1,123 @@ +{ + "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", + "name": "GraphQL", + "scopeName": "source.graphql", + "fileTypes": ["graphql", "gql", "graphqls"], + "patterns": [{ "include": "#graphql" }], + "repository": { + "graphql": { + "patterns": [ + { "include": "#comment" }, + { "include": "#string-block" }, + { "include": "#string" }, + { "include": "#operation-definition" }, + { "include": "#fragment-definition" }, + { "include": "#fragment-spread" }, + { "include": "#type-system-keyword" }, + { "include": "#directive" }, + { "include": "#variable" }, + { "include": "#name-before-colon" }, + { "include": "#boolean" }, + { "include": "#null" }, + { "include": "#number" }, + { "include": "#type-name" }, + { "include": "#punctuation" } + ] + }, + "comment": { + "name": "comment.line.number-sign.graphql", + "match": "#.*" + }, + "string-block": { + "name": "string.quoted.block.graphql", + "begin": "\"\"\"", + "end": "\"\"\"", + "beginCaptures": { + "0": { "name": "punctuation.definition.string.begin.graphql" } + }, + "endCaptures": { + "0": { "name": "punctuation.definition.string.end.graphql" } + } + }, + "string": { + "name": "string.quoted.double.graphql", + "begin": "\"", + "end": "\"|(?=\\n)", + "beginCaptures": { + "0": { "name": "punctuation.definition.string.begin.graphql" } + }, + "endCaptures": { + "0": { "name": "punctuation.definition.string.end.graphql" } + }, + "patterns": [ + { + "name": "constant.character.escape.graphql", + "match": "\\\\(?:[\"\\\\/bfnrt]|u[0-9A-Fa-f]{4})" + } + ] + }, + "operation-definition": { + "match": "\\b(query|mutation|subscription)\\b\\s*([_A-Za-z][_0-9A-Za-z]*)?", + "captures": { + "1": { "name": "keyword.operation.graphql" }, + "2": { "name": "entity.name.function.operation.graphql" } + } + }, + "fragment-definition": { + "match": "\\b(fragment)\\s+([_A-Za-z][_0-9A-Za-z]*)(?:\\s+(on)\\s+([_A-Za-z][_0-9A-Za-z]*))?", + "captures": { + "1": { "name": "keyword.fragment.graphql" }, + "2": { "name": "entity.name.function.fragment.graphql" }, + "3": { "name": "keyword.on.graphql" }, + "4": { "name": "support.type.graphql" } + } + }, + "fragment-spread": { + "match": "(\\.\\.\\.)\\s*(?:\\b(on)\\s+([_A-Za-z][_0-9A-Za-z]*)|([_A-Za-z][_0-9A-Za-z]*))?", + "captures": { + "1": { "name": "keyword.operator.spread.graphql" }, + "2": { "name": "keyword.on.graphql" }, + "3": { "name": "support.type.graphql" }, + "4": { "name": "variable.fragment.graphql" } + } + }, + "type-system-keyword": { + "name": "keyword.type.graphql", + "match": "\\b(schema|scalar|type|interface|union|enum|input|directive|extend|implements|repeatable|on)\\b" + }, + "directive": { + "name": "entity.name.function.directive.graphql", + "match": "@[_A-Za-z][_0-9A-Za-z]*" + }, + "variable": { + "name": "variable.graphql", + "match": "\\$[_A-Za-z][_0-9A-Za-z]*" + }, + "name-before-colon": { + "comment": "Field aliases, argument names, input object fields, and field definitions", + "name": "variable.parameter.graphql", + "match": "\\b[_A-Za-z][_0-9A-Za-z]*(?=\\s*:)" + }, + "boolean": { + "name": "constant.language.boolean.graphql", + "match": "\\b(?:true|false)\\b" + }, + "null": { + "name": "constant.language.null.graphql", + "match": "\\bnull\\b" + }, + "number": { + "name": "constant.numeric.graphql", + "match": "(?=22.0.0'} + + '@azure/core-auth@1.11.0': + resolution: {integrity: sha512-IUZydyTUkDnYdstOW9pFOOUQlBjAepK5teihDE3x6yxsPJs/hsAaaYpeGxdxrgtOiJbBKSjKW7MDk7AEhb4LRg==} + engines: {node: '>=22.0.0'} + + '@azure/core-client@1.11.0': + resolution: {integrity: sha512-JjQWO6akOck45PH/XBrxzsQGAiKrfFl4m5iggJ0ItMIz5omRufOXWpqCPpdjKN3vKDzlSUvFjaMb7Zwf0gvAdA==} + engines: {node: '>=22.0.0'} + + '@azure/core-process@1.0.0': + resolution: {integrity: sha512-/shnJ+ooO8WPxDhPEeI/2oRQuubn16gZ6CvlbpWbEswZfzwI9tI/sMAHmF3x1LuQ9yZYXfLW3TjzGMLEC5blKg==} + engines: {node: '>=22.0.0'} + + '@azure/core-rest-pipeline@1.25.0': + resolution: {integrity: sha512-bMs8ekJLjX8wPV+9IPBges1SLPyuDtE9g5gLDWOpxzKcoOFQnpLGkbcT1tdw3FaAmDS1gnPmMmJ6y/T5B96kIA==} + engines: {node: '>=22.0.0'} + + '@azure/core-tracing@1.4.0': + resolution: {integrity: sha512-eGwxD0AtncrxeBM4tG8R55Pc3rdX1hNW2WibJAgYpCVA6E93mvvVH+LcssoVjOBrSKWS55yEIHsk0X8ctHmfOQ==} + engines: {node: '>=22.0.0'} + + '@azure/core-util@1.14.0': + resolution: {integrity: sha512-9n2pWK61veAuN0V20t9lOuoV4CFMdyAZ1ygZzvBGk/pBBJRib/PjL9PLXa/aI2CcPpyHfqVsxxqLCYl6uZlfDw==} + engines: {node: '>=22.0.0'} + + '@azure/identity@4.13.2': + resolution: {integrity: sha512-NXL2/pCJctLxgw8bvrwwgge743kEq8LBT+O1pmV0vyUwetzFPH9auP6jhkU/cgZCPPtWoewAe3ncaGCgPo07fA==} + engines: {node: '>=22.0.0'} + + '@azure/logger@1.4.0': + resolution: {integrity: sha512-rbAE25KUfjU/s3XHUdJgceoCP5dEOpMx85J04kF+QMdta73XkuG9JGHHinch+XIoKpBdqljin+KqURpJriSzLA==} + engines: {node: '>=22.0.0'} + + '@azure/msal-browser@5.19.0': + resolution: {integrity: sha512-DHe9iRcyByGJuLPkl0K31a1JjOdRY2zX38Q07mQpSbR8zOj1EIgsWfTXhSQVyyijUxlcofVy/br7qWJbrMwVXQ==} + engines: {node: '>=0.8.0'} + + '@azure/msal-common@16.13.0': + resolution: {integrity: sha512-rOAy0KUcyBbdwVJ+f3uPpthXatFLLZN+/KWAsTLzk1aB23Xl9DRmmXYwSvBFOZyXj4jUQQ5FKxxRkhAFW1fOow==} + engines: {node: '>=0.8.0'} + + '@azure/msal-node@5.6.0': + resolution: {integrity: sha512-uFY9NxrWHw8PwZx7gAX6PDn+9vdfS05+levc/kwkx77IkjfaldnQbbcQzzDIZ5Hq5Zdr6/z92oAIoRWKp6MnOA==} + engines: {node: '>=20'} + '@babel/code-frame@7.29.7': resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} engines: {node: '>=6.9.0'} @@ -1357,13 +1430,78 @@ packages: cpu: [x64] os: [win32] + '@secretlint/config-creator@10.2.2': + resolution: {integrity: sha512-BynOBe7Hn3LJjb3CqCHZjeNB09s/vgf0baBaHVw67w7gHF0d25c3ZsZ5+vv8TgwSchRdUCRrbbcq5i2B1fJ2QQ==} + engines: {node: '>=20.0.0'} + + '@secretlint/config-loader@10.2.2': + resolution: {integrity: sha512-ndjjQNgLg4DIcMJp4iaRD6xb9ijWQZVbd9694Ol2IszBIbGPPkwZHzJYKICbTBmh6AH/pLr0CiCaWdGJU7RbpQ==} + engines: {node: '>=20.0.0'} + + '@secretlint/core@10.2.2': + resolution: {integrity: sha512-6rdwBwLP9+TO3rRjMVW1tX+lQeo5gBbxl1I5F8nh8bgGtKwdlCMhMKsBWzWg1ostxx/tIG7OjZI0/BxsP8bUgw==} + engines: {node: '>=20.0.0'} + + '@secretlint/formatter@10.2.2': + resolution: {integrity: sha512-10f/eKV+8YdGKNQmoDUD1QnYL7TzhI2kzyx95vsJKbEa8akzLAR5ZrWIZ3LbcMmBLzxlSQMMccRmi05yDQ5YDA==} + engines: {node: '>=20.0.0'} + + '@secretlint/node@10.2.2': + resolution: {integrity: sha512-eZGJQgcg/3WRBwX1bRnss7RmHHK/YlP/l7zOQsrjexYt6l+JJa5YhUmHbuGXS94yW0++3YkEJp0kQGYhiw1DMQ==} + engines: {node: '>=20.0.0'} + + '@secretlint/profiler@10.2.2': + resolution: {integrity: sha512-qm9rWfkh/o8OvzMIfY8a5bCmgIniSpltbVlUVl983zDG1bUuQNd1/5lUEeWx5o/WJ99bXxS7yNI4/KIXfHexig==} + + '@secretlint/resolver@10.2.2': + resolution: {integrity: sha512-3md0cp12e+Ae5V+crPQYGd6aaO7ahw95s28OlULGyclyyUtf861UoRGS2prnUrKh7MZb23kdDOyGCYb9br5e4w==} + + '@secretlint/secretlint-formatter-sarif@10.2.2': + resolution: {integrity: sha512-ojiF9TGRKJJw308DnYBucHxkpNovDNu1XvPh7IfUp0A12gzTtxuWDqdpuVezL7/IP8Ua7mp5/VkDMN9OLp1doQ==} + + '@secretlint/secretlint-rule-no-dotenv@10.2.2': + resolution: {integrity: sha512-KJRbIShA9DVc5Va3yArtJ6QDzGjg3PRa1uYp9As4RsyKtKSSZjI64jVca57FZ8gbuk4em0/0Jq+uy6485wxIdg==} + engines: {node: '>=20.0.0'} + + '@secretlint/secretlint-rule-preset-recommend@10.2.2': + resolution: {integrity: sha512-K3jPqjva8bQndDKJqctnGfwuAxU2n9XNCPtbXVI5JvC7FnQiNg/yWlQPbMUlBXtBoBGFYp08A94m6fvtc9v+zA==} + engines: {node: '>=20.0.0'} + + '@secretlint/source-creator@10.2.2': + resolution: {integrity: sha512-h6I87xJfwfUTgQ7irWq7UTdq/Bm1RuQ/fYhA3dtTIAop5BwSFmZyrchph4WcoEvbN460BWKmk4RYSvPElIIvxw==} + engines: {node: '>=20.0.0'} + + '@secretlint/types@10.2.2': + resolution: {integrity: sha512-Nqc90v4lWCXyakD6xNyNACBJNJ0tNCwj2WNk/7ivyacYHxiITVgmLUFXTBOeCdy79iz6HtN9Y31uw/jbLrdOAg==} + engines: {node: '>=20.0.0'} + '@sindresorhus/fnv1a@3.1.0': resolution: {integrity: sha512-KV321z5m/0nuAg83W1dPLy85HpHDk7Sdi4fJbwvacWsEhAh+rZUW4ZfGcXmUIvjZg4ss2bcwNlRhJ7GBEUG08w==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + '@sindresorhus/merge-streams@2.3.0': + resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} + engines: {node: '>=18'} + '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + '@textlint/ast-node-types@15.8.0': + resolution: {integrity: sha512-5CiH9COYmovWmExQgs7763DzX6Gy9zjkjJ7JxCC95wyTcjwQn/8poNF6fv3qzRlmx8CRRde8DHr9FcgAAiPzgw==} + + '@textlint/linter-formatter@15.8.0': + resolution: {integrity: sha512-+oU3A235NATv6Lzi4xa4kJ65PuNJlIxesaO4AvDhDWA9FWm7y4XKWaoQCW1esgaQQ6dwnUiFKArQ8TcJ86mC4w==} + engines: {node: '>=20.18.0'} + + '@textlint/module-interop@15.8.0': + resolution: {integrity: sha512-rt+OR1WYGoLOY8HkA/aBPrqufF6yUUEsKEAh7XohTsT3lp9IyZFT6zOIbjul9P4FAzsmSPkcrYjVx3Bz/IUfkg==} + + '@textlint/resolver@15.8.0': + resolution: {integrity: sha512-E88tzfX3K8Jykk+38aJ9cy8RquD8ABVOPTO2rFEESq0wcg8x6/ypdAS8ZgR7OKiGqlRF0hkO/m5PbQwVfKM3VA==} + + '@textlint/types@15.8.0': + resolution: {integrity: sha512-Anhc6y5736YIsvqae0U6k0YmB2M/QVHkEeOv2aydAn/WIkdI69dCOiDbe3/+RagS3qstFTSFWJzNRA2lUjv19w==} + '@theguild/federation-composition@0.20.2': resolution: {integrity: sha512-QI4iSdrc4JvCWnMb1QbiHnEpdD33KGdiU66qfWOcM8ENebRGHkGjXDnUrVJ8F9g1dmCRMTNfn2NFGqTcDpeYXw==} engines: {node: '>=18'} @@ -1403,6 +1541,9 @@ packages: '@types/node@22.20.0': resolution: {integrity: sha512-QWlFW2wf3nTjC13/DqRnBpR4ZO36VJH/JVBkA/vcnmbTBNQIlnObqyqZE1tUR7+Ni23Lda8R1BxMfbXRpCUx5g==} + '@types/normalize-package-data@2.4.4': + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + '@types/prop-types@15.7.15': resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} @@ -1412,12 +1553,22 @@ packages: '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + '@types/sarif@2.1.7': + resolution: {integrity: sha512-kRz0VEkJqWLf1LLVN4pT1cg1Z9wAuvI6L97V3m2f5B76Tg8d413ddvLBPTEHAZJlnn4XSvu0FkZtViCQGVyrXQ==} + '@types/scheduler@0.26.0': resolution: {integrity: sha512-WFHp9YUJQ6CKshqoC37iOlHnQSmxNc795UhB26CyBBttrN9svdIrUjl/NjnNmfcwtncN0h/0PPAFWv9ovP8mLA==} + '@types/vscode@1.80.0': + resolution: {integrity: sha512-qK/CmOdS2o7ry3k6YqU4zD3R2AYlJfbwBoSbKpBoP+GpXNE+0NEgJOli4n0bm0diK5kfBnchgCEj4igQz/44Hg==} + '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@typespec/ts-http-runtime@0.3.8': + resolution: {integrity: sha512-bLMpVcWZNzq6lYOybwFwOAR1IXKcHnhUNqYeHjl1bET/qE3jFPFH+p8Wrh3rU4xwdnifPxmKNESBYnvnmc75aA==} + engines: {node: '>=22.0.0'} + '@urql/core@3.0.0': resolution: {integrity: sha512-C9nVn3+hhht8K0MEr9zLUgzoapkoX7X0crwMB72LrMqerhBjvEEuTngEFlZfALRwOzHjUNXBT9ZVgyzt6cKRhA==} peerDependencies: @@ -1458,6 +1609,59 @@ packages: '@vitest/utils@4.1.9': resolution: {integrity: sha512-A51o8ymO5PpqlWNnBP9ZHPXDIpuMtTLlGSjN7la4US+LJzoUMyhwjA5QXlm39JexgwHKW4Xjs8Z2d3dLCXOeuA==} + '@vscode/vsce-sign-alpine-arm64@2.0.6': + resolution: {integrity: sha512-wKkJBsvKF+f0GfsUuGT0tSW0kZL87QggEiqNqK6/8hvqsXvpx8OsTEc3mnE1kejkh5r+qUyQ7PtF8jZYN0mo8Q==} + cpu: [arm64] + os: [alpine] + + '@vscode/vsce-sign-alpine-x64@2.0.6': + resolution: {integrity: sha512-YoAGlmdK39vKi9jA18i4ufBbd95OqGJxRvF3n6ZbCyziwy3O+JgOpIUPxv5tjeO6gQfx29qBivQ8ZZTUF2Ba0w==} + cpu: [x64] + os: [alpine] + + '@vscode/vsce-sign-darwin-arm64@2.0.6': + resolution: {integrity: sha512-5HMHaJRIQuozm/XQIiJiA0W9uhdblwwl2ZNDSSAeXGO9YhB9MH5C4KIHOmvyjUnKy4UCuiP43VKpIxW1VWP4tQ==} + cpu: [arm64] + os: [darwin] + + '@vscode/vsce-sign-darwin-x64@2.0.6': + resolution: {integrity: sha512-25GsUbTAiNfHSuRItoQafXOIpxlYj+IXb4/qarrXu7kmbH94jlm5sdWSCKrrREs8+GsXF1b+l3OB7VJy5jsykw==} + cpu: [x64] + os: [darwin] + + '@vscode/vsce-sign-linux-arm64@2.0.6': + resolution: {integrity: sha512-cfb1qK7lygtMa4NUl2582nP7aliLYuDEVpAbXJMkDq1qE+olIw/es+C8j1LJwvcRq1I2yWGtSn3EkDp9Dq5FdA==} + cpu: [arm64] + os: [linux] + + '@vscode/vsce-sign-linux-arm@2.0.6': + resolution: {integrity: sha512-UndEc2Xlq4HsuMPnwu7420uqceXjs4yb5W8E2/UkaHBB9OWCwMd3/bRe/1eLe3D8kPpxzcaeTyXiK3RdzS/1CA==} + cpu: [arm] + os: [linux] + + '@vscode/vsce-sign-linux-x64@2.0.6': + resolution: {integrity: sha512-/olerl1A4sOqdP+hjvJ1sbQjKN07Y3DVnxO4gnbn/ahtQvFrdhUi0G1VsZXDNjfqmXw57DmPi5ASnj/8PGZhAA==} + cpu: [x64] + os: [linux] + + '@vscode/vsce-sign-win32-arm64@2.0.6': + resolution: {integrity: sha512-ivM/MiGIY0PJNZBoGtlRBM/xDpwbdlCWomUWuLmIxbi1Cxe/1nooYrEQoaHD8ojVRgzdQEUzMsRbyF5cJJgYOg==} + cpu: [arm64] + os: [win32] + + '@vscode/vsce-sign-win32-x64@2.0.6': + resolution: {integrity: sha512-mgth9Kvze+u8CruYMmhHw6Zgy3GRX2S+Ed5oSokDEK5vPEwGGKnmuXua9tmFhomeAnhgJnL4DCna3TiNuGrBTQ==} + cpu: [x64] + os: [win32] + + '@vscode/vsce-sign@2.1.0': + resolution: {integrity: sha512-9AQrqazrBgTgRSuwleLVXUrIUphY02/SFCh2TKYoLV/xifJAdblhdmEmw5gUrYSPQ3sRwNs9iyCMD14sATEE6g==} + + '@vscode/vsce@3.9.2': + resolution: {integrity: sha512-XSxMosEEDO6vLxELAHVkwmhC0qe0ijZni2jB9Rcs8kQsW4lhTDQ/wMzmwFs/buotAWSnpmUp/dRWD2ufG3UYKA==} + engines: {node: '>= 20'} + hasBin: true + '@whatwg-node/disposablestack@0.0.6': resolution: {integrity: sha512-LOtTn+JgJvX8WfBVJtF08TGrdjuFzGJc4mkP8EdDI8ADbvO7kiexYep1o8dwnt0okb0jYclCDXF13xU7Ge4zSw==} engines: {node: '>=18.0.0'} @@ -1505,6 +1709,9 @@ packages: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} + ansi-escapes@4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} @@ -1554,13 +1761,23 @@ packages: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + auto-bind@4.0.0: resolution: {integrity: sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==} engines: {node: '>=8'} + azure-devops-node-api@12.5.0: + resolution: {integrity: sha512-R5eFskGvOm3U/GzeAuxRkUsAl0hrAwGgWn6zAd2KrZmrEhWZVqLew4OOupbQlXUuojUzpGtq62SmdhJ06N88og==} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -1571,12 +1788,26 @@ packages: before-after-hook@4.0.0: resolution: {integrity: sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==} + binaryextensions@6.11.0: + resolution: {integrity: sha512-sXnYK/Ij80TO3lcqZVV2YgfKN5QjUWIRk/XSm2J/4bd/lPko3lvk0O4ZppH6m+6hB2/GTu+ptNwVFe1xh+QLQw==} + engines: {node: '>=4'} + bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + boundary@2.0.0: + resolution: {integrity: sha512-rJKn5ooC9u8q13IMCrW0RSp31pxBCHE3y9V/tp3TdWSLf8Em3p6Di4NBpfzbJge9YjjFEsD0RtFEjtvHL5VyEA==} + brace-expansion@2.0.2: resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + brace-expansion@5.0.9: + resolution: {integrity: sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==} + engines: {node: 20 || >=22} + braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} @@ -1589,12 +1820,22 @@ packages: bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + + buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + busboy@1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} @@ -1603,6 +1844,14 @@ packages: resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} engines: {node: '>=20.19.0'} + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -1624,6 +1873,10 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + change-case-all@1.0.15: resolution: {integrity: sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==} @@ -1633,6 +1886,16 @@ packages: chardet@2.2.0: resolution: {integrity: sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA==} + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + + cheerio@1.2.0: + resolution: {integrity: sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==} + engines: {node: '>=20.18.1'} + + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + cjs-module-lexer@1.4.3: resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} @@ -1672,6 +1935,10 @@ packages: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} + cockatiel@3.2.1: + resolution: {integrity: sha512-gfrHV6ZPkquExvMh9IOkKsBzNDk6sDuZ6DdBGUBkvFnTCqCxzpuq48RySgP0AnaqQkw2zynOFj9yly6T1Q2G5Q==} + engines: {node: '>=16'} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -1682,6 +1949,14 @@ packages: colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -1721,6 +1996,13 @@ packages: resolution: {integrity: sha512-Pcw1JTvZLSJH83iiGWt6fRcT+BjZlCDRVwYLbUcHzv/CRpB7r0MlSrGbIyQvVSNyGnbt7G4AXuyCiDR3POvZ1A==} engines: {node: '>=16.0.0'} + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} @@ -1746,13 +2028,37 @@ packages: supports-color: optional: true + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} + default-browser-id@5.0.1: + resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} + engines: {node: '>=18'} + + default-browser@5.5.1: + resolution: {integrity: sha512-m1pAzaJgZ/gssEqlOhJkPJp8Xly7QyW6xcrkUa2KKcDeDSEMP7X8xipU3snUcfisTQx0w1AGae+9UtJSfVnXGw==} + engines: {node: '>=18'} + defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dependency-graph@0.11.0: resolution: {integrity: sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==} engines: {node: '>= 0.6.0'} @@ -1773,6 +2079,19 @@ packages: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + dot-case@3.0.4: resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} @@ -1788,6 +2107,17 @@ packages: resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} engines: {node: '>=4'} + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + + editions@6.22.0: + resolution: {integrity: sha512-UgGlf8IW75je7HZjNDpJdCv4cGJWIi6yumFdZ0R7A8/CIhQiWUjyGLCxdHpd8bmyD1gnkfUNK0oeOXqUS2cpfQ==} + engines: {ecmascript: '>= es5', node: '>=4'} + electron-to-chromium@1.5.250: resolution: {integrity: sha512-/5UMj9IiGDMOFBnN4i7/Ry5onJrAGSbOGo3s9FEKmwobGq6xw832ccET0CE3CkkMBZ8GJSlUIesZofpyurqDXw==} @@ -1797,6 +2127,24 @@ packages: emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + encoding-sniffer@0.2.1: + resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} + environment@1.1.0: resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} engines: {node: '>=18'} @@ -1804,6 +2152,10 @@ packages: error-ex@1.3.4: resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + es-errors@1.3.0: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} @@ -1811,6 +2163,14 @@ packages: es-module-lexer@2.3.0: resolution: {integrity: sha512-KLdwQm2NvGLDkQDCGvmiQrhkd0JbMzXthwQAUgWjQuQdBLFa3eiBP5arXZyA+f8x+x7OXgud6bq2rxjGtHV2tw==} + es-object-atoms@1.1.2: + resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -1828,6 +2188,10 @@ packages: eventemitter3@5.0.4: resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + expand-template@2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} + expect-type@1.4.0: resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} engines: {node: '>=12.0.0'} @@ -1835,6 +2199,9 @@ packages: fast-decode-uri-component@1.0.1: resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} @@ -1848,6 +2215,9 @@ packages: fast-string-width@3.0.2: resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} + fast-uri@3.1.5: + resolution: {integrity: sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==} + fast-url-parser@1.1.3: resolution: {integrity: sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==} @@ -1887,10 +2257,21 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + form-data@4.0.6: + resolution: {integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==} + engines: {node: '>= 6'} + formdata-polyfill@4.0.10: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fs-extra@11.4.0: + resolution: {integrity: sha512-EQsFzMUJkCKGr1ePqlYADkIUmHW1s3ZXr5Yqy6wbGrfUCphpl2maM/kyOIRA2HpP3AaFQTZXD4ldjek+nccddA==} + engines: {node: '>=14.14'} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1911,20 +2292,46 @@ packages: resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} engines: {node: '>=18'} + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} + glob@13.0.6: + resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} + engines: {node: 18 || 20 || >=22} + globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} + globby@14.1.0: + resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==} + engines: {node: '>=18'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + gql.tada@1.11.0: resolution: {integrity: sha512-QmBB7HTPBH3fBHdAEBBbq8N/1tyq9abdINply2rSUW1FVvZJ/b/jOD8esKVHh+JEajCCtfjGl0Kx2RyvXJFNCQ==} hasBin: true peerDependencies: typescript: ^6.0.3 + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + graphql-config@5.1.5: resolution: {integrity: sha512-mG2LL1HccpU8qg5ajLROgdsBzx/o2M6kgI3uAmoaXiSH9PCUbtIyLomLqUtCFaAeG2YCFsl0M5cfQ9rKmDoMVA==} engines: {node: '>= 16.0.0'} @@ -1979,6 +2386,14 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + hasown@2.0.4: resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} engines: {node: '>= 0.4'} @@ -1986,6 +2401,17 @@ packages: header-case@2.0.4: resolution: {integrity: sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==} + hosted-git-info@4.1.0: + resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} + engines: {node: '>=10'} + + hosted-git-info@7.0.2: + resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} + engines: {node: ^16.14.0 || >=18.0.0} + + htmlparser2@10.1.0: + resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==} + http-proxy-agent@7.0.2: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} @@ -2003,6 +2429,10 @@ packages: engines: {node: '>=18'} hasBin: true + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + iconv-lite@0.7.3: resolution: {integrity: sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==} engines: {node: '>=0.10.0'} @@ -2014,6 +2444,10 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} + ignore@7.0.6: + resolution: {integrity: sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==} + engines: {node: '>= 4'} + immutable@3.7.6: resolution: {integrity: sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw==} engines: {node: '>=0.8.0'} @@ -2033,9 +2467,16 @@ packages: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} + index-to-position@1.2.0: + resolution: {integrity: sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==} + engines: {node: '>=18'} + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + inquirer@8.2.7: resolution: {integrity: sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==} engines: {node: '>=12.0.0'} @@ -2054,6 +2495,11 @@ packages: resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} engines: {node: '>= 0.4'} + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -2070,6 +2516,11 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + is-interactive@1.0.0: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} @@ -2106,11 +2557,19 @@ packages: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} + is-wsl@3.1.1: + resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} + engines: {node: '>=16'} + isomorphic-ws@5.0.0: resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} peerDependencies: ws: '*' + istextorbinary@9.5.0: + resolution: {integrity: sha512-5mbUj3SiZXCuRf9fT3ibzbSSEWiy63gFfksmGfdOzujPjW3k+z8WvIBxcJHBoQNlaZaiyB25deviif2+osLmLw==} + engines: {node: '>=4'} + jiti@1.21.7: resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} hasBin: true @@ -2132,6 +2591,10 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true + js-yaml@4.3.1: + resolution: {integrity: sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==} + hasBin: true + jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -2140,6 +2603,9 @@ packages: json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + json-to-pretty-yaml@1.2.2: resolution: {integrity: sha512-rvm6hunfCcqegwYaG5T4yKJWxc9FXFgBVrcTZ4XfSVRwa5HA/Xs+vB/Eo9treYYHCeNM0nrSUr82V/M31Urc7A==} engines: {node: '>= 0.2.0'} @@ -2155,9 +2621,29 @@ packages: jsonc-parser@3.3.1: resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + jsonfile@6.2.1: + resolution: {integrity: sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==} + + jsonwebtoken@9.0.3: + resolution: {integrity: sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==} + engines: {node: '>=12', npm: '>=6'} + + jwa@2.0.1: + resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} + + jws@4.0.1: + resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} + + keytar@7.9.0: + resolution: {integrity: sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==} + launch-editor@2.14.1: resolution: {integrity: sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==} + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + lightningcss-android-arm64@1.32.0: resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} engines: {node: '>= 12.0.0'} @@ -2235,6 +2721,9 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + linkify-it@5.0.2: + resolution: {integrity: sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==} + lint-staged@17.0.8: resolution: {integrity: sha512-B2P/d+jVW0UXOQ0MVMLrB/9ydA1P+zz6jYfdrbbEd9ur3S2rcbduFWKiUCC02Sm5hbC8nrm7y24WuYMG54HfxA==} engines: {node: '>=22.22.1'} @@ -2253,12 +2742,39 @@ packages: enquirer: optional: true + lodash.includes@4.3.0: + resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} + + lodash.isboolean@3.0.3: + resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} + + lodash.isinteger@4.0.4: + resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} + + lodash.isnumber@3.0.3: + resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} + + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + + lodash.isstring@4.0.1: + resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + + lodash.once@4.1.1: + resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + lodash.sortby@4.7.0: resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + lodash.truncate@4.4.2: + resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} @@ -2281,6 +2797,9 @@ packages: lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@11.5.1: resolution: {integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==} engines: {node: 20 || >=22} @@ -2288,6 +2807,10 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} @@ -2298,6 +2821,17 @@ packages: resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} engines: {node: '>=0.10.0'} + markdown-it@14.3.0: + resolution: {integrity: sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw==} + hasBin: true + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdurl@2.1.0: + resolution: {integrity: sha512-1+HBaOx0zi/dQWht8rNv9MYf9qqpqL/kxI0hXImU6Y547zM6Sni8BQibt7ifgMcYtQg41ao3Ivd6cnSM86inpg==} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -2315,6 +2849,19 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} @@ -2323,10 +2870,28 @@ packages: resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} engines: {node: '>=18'} + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + minimatch@10.2.6: + resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} + engines: {node: 18 || 20 || >=22} + minimatch@9.0.5: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + + mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -2338,9 +2903,19 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + napi-build-utils@2.0.0: + resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} + no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + node-abi@3.94.0: + resolution: {integrity: sha512-W5ZNO5KRPB5TkYmGVD9F6YqhsglXJzE6etpbmT+f6EQElhiX/UTG551cnsRGvLG3fyZEg9HwaDmNmj5nwJ4z9g==} + engines: {node: '>=10'} + + node-addon-api@4.3.0: + resolution: {integrity: sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==} + node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} @@ -2365,10 +2940,21 @@ packages: node-releases@2.0.27: resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + node-sarif-builder@3.4.0: + resolution: {integrity: sha512-tGnJW6OKRii9u/b2WiUViTJS+h7Apxx17qsMUjsUeNDiMMX5ZFf8F8Fcz7PAQ6omvOxHZtvDTmOYKJQwmfpjeg==} + engines: {node: '>=20'} + + normalize-package-data@6.0.2: + resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==} + engines: {node: ^16.14.0 || >=18.0.0} + normalize-path@2.1.1: resolution: {integrity: sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==} engines: {node: '>=0.10.0'} + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + nullthrows@1.1.1: resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} @@ -2376,10 +2962,17 @@ packages: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + obug@2.1.3: resolution: {integrity: sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==} engines: {node: '>=12.20.0'} + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + onetime@5.1.2: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} @@ -2388,6 +2981,10 @@ packages: resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} engines: {node: '>=18'} + open@10.2.0: + resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} + engines: {node: '>=18'} + ora@5.4.1: resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} engines: {node: '>=10'} @@ -2400,6 +2997,10 @@ packages: resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} engines: {node: '>=10'} + p-map@7.0.6: + resolution: {integrity: sha512-I4Prw6ivkd6p8PiYR1tXASOAOBzIJwu0TB7fqaX0c/8c3QAehNYmX57EijyGGGBt3c/BIowGwV03RVBtXvHEVg==} + engines: {node: '>=18'} + package-manager-detector@1.8.0: resolution: {integrity: sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==} @@ -2418,6 +3019,22 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} + parse-json@8.3.0: + resolution: {integrity: sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==} + engines: {node: '>=18'} + + parse-semver@1.1.1: + resolution: {integrity: sha512-Eg1OuNntBMH0ojvEKSrvDSnwLmvVuUOSdylH/pSCPNMIspLlweJyIWXCE+k/5hm3cj/EBUYwmWkjhBALNP4LXQ==} + + parse5-htmlparser2-tree-adapter@7.1.0: + resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} + + parse5-parser-stream@7.1.2: + resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + pascal-case@3.1.2: resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} @@ -2435,13 +3052,24 @@ packages: resolution: {integrity: sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==} engines: {node: '>=0.10.0'} + path-scurry@2.0.2: + resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} + engines: {node: 18 || 20 || >=22} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} - pathe@2.0.3: + path-type@6.0.0: + resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==} + engines: {node: '>=18'} + + pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -2453,10 +3081,23 @@ packages: resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} engines: {node: '>=12'} + pluralize@2.0.0: + resolution: {integrity: sha512-TqNZzQCD4S42De9IfnnBvILN7HAW7riLqsCyp8lgjXeysyPlX5HhqKAcJHHHb9XskE4/a+7VGC9zzx8Ls0jOAw==} + + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + postcss@8.5.16: resolution: {integrity: sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==} engines: {node: ^10 || ^12 || >=14} + prebuild-install@7.1.3: + resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} + engines: {node: '>=10'} + deprecated: No longer maintained. Please contact the author of the relevant native addon; alternatives are available. + hasBin: true + prettier@3.9.4: resolution: {integrity: sha512-yWG/o/4oJfo036EKAfK6ACAoDOfHeRHx4tuxkfBZiauURiaSmYwlpOr5LQqKtIkRD2z1PLteme2WoxEnj4tHTg==} engines: {node: '>=14'} @@ -2465,6 +3106,13 @@ packages: promise@7.3.1: resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==} + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} + + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + punycode@1.4.1: resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} @@ -2475,13 +3123,32 @@ packages: resolution: {integrity: sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==} engines: {node: '>=16.0.0'} + qs@6.15.3: + resolution: {integrity: sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==} + engines: {node: '>=0.6'} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + rc-config-loader@4.1.4: + resolution: {integrity: sha512-3GiwEzklkbXTDp52UR5nT8iXgYAx1V9ZG/kDZT7p60u2GCv2XTwQq4NzinMoMpNtXhmt3WkhYXcj6HH8HdwCEQ==} + + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + react@19.2.0: resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==} engines: {node: '>=0.10.0'} + read-pkg@9.0.1: + resolution: {integrity: sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==} + engines: {node: '>=18'} + + read@1.0.7: + resolution: {integrity: sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==} + engines: {node: '>=0.8'} + readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -2502,6 +3169,10 @@ packages: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -2553,6 +3224,10 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} + engines: {node: '>=18'} + run-async@2.4.1: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} @@ -2569,9 +3244,18 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + sax@1.6.1: + resolution: {integrity: sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==} + engines: {node: '>=11.0.0'} + scuid@1.1.0: resolution: {integrity: sha512-MuCAyrGZcTLfQoH2XoBlQ8C6bzwN88XT/0slOGz0pn8+gIP85BOAfYa44ZXQUTOwRwPU0QvgU+V+OSajl/59Xg==} + secretlint@10.2.2: + resolution: {integrity: sha512-xVpkeHV/aoWe4vP4TansF622nBEImzCY73y/0042DuJ29iKIaqgoJ8fGxre3rVSHHbxar4FdJobmTnLp9AU0eg==} + engines: {node: '>=20.0.0'} + hasBin: true + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -2599,6 +3283,22 @@ packages: resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} engines: {node: '>= 0.4'} + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.1: + resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} + engines: {node: '>= 0.4'} + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -2612,6 +3312,12 @@ packages: signedsource@1.0.0: resolution: {integrity: sha512-6+eerH9fEnNmi/hyM1DXcRK3pWdoMQtlkQ+ns0ntzunjKqp5i3sKCc80ym8Fib3iaYhdJUOPdhlJWj1tvge2Ww==} + simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + + simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -2619,6 +3325,10 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} + slice-ansi@3.0.0: resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} engines: {node: '>=8'} @@ -2653,6 +3363,18 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.23: + resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==} + sponge-case@1.0.1: resolution: {integrity: sha512-dblb9Et4DAtiZ5YSUZHLl4XhH4uK80GhAZrVXdN4O2P4gQ40Wa5UIOPUHlA/nFd2PLblBZWUioLMMAVrgpoYcA==} @@ -2696,10 +3418,21 @@ packages: resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} engines: {node: '>=12'} + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + structured-source@4.0.0: + resolution: {integrity: sha512-qGzRFNJDjFieQkl/sVOI2dUjHKRyL9dAJi2gCPGJLbJHBIkyOHxjuocpIEfbLioX+qSJpvbYdT49/YCdMznKxA==} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} + supports-hyperlinks@3.2.0: + resolution: {integrity: sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==} + engines: {node: '>=14.18'} + supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} @@ -2711,11 +3444,33 @@ packages: resolution: {integrity: sha512-c7AfkZ9udatCuAy9RSfiGPpeOKKUAUK5e1cXadLOGUjasdxqYqAK0jTNkM/FSEyJ3a5Ra27j/tw/PS0qLmaF/A==} engines: {node: '>=18'} + table@6.9.0: + resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} + engines: {node: '>=10.0.0'} + + tar-fs@2.1.5: + resolution: {integrity: sha512-OboTd8mmMhZDNPV+UjQcK9yKAatXu2aJ+r1w4im1Otd4M4fl2hwvdoXUxIYHFTHWK/3y3FarBP70v3vwmGlOxw==} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + terminal-link@4.0.0: + resolution: {integrity: sha512-lk+vH+MccxNqgVqSnkMVKx4VLJfnLjDBGzH16JVZjKE2DoxP57s6/vt6JmXV5I3jBcfGrxNrYtC+mPtU7WJztA==} + engines: {node: '>=18'} + terser@5.48.0: resolution: {integrity: sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q==} engines: {node: '>=10'} hasBin: true + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + textextensions@6.11.0: + resolution: {integrity: sha512-tXJwSr9355kFJI3lbCkPpUH5cP8/M0GGy2xLO34aZCjMXBaK3SoPnZwr/oWmo1FdCnELcs4npdCIOFtq9W3ruQ==} + engines: {node: '>=4'} + through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} @@ -2745,6 +3500,10 @@ packages: title-case@3.0.3: resolution: {integrity: sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==} + tmp@0.2.7: + resolution: {integrity: sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==} + engines: {node: '>=14.14'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -2778,6 +3537,9 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + tunnel@0.0.6: resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} @@ -2786,6 +3548,13 @@ packages: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + typed-rest-client@1.8.11: + resolution: {integrity: sha512-5UvfMpd1oelmUPRbbaVnq+rHP7ng2cE4qoQkQeAqxRL6PklkxsM0g32/HL0yfvruK6ojQ5x8EE+HF4YV6DtuCA==} + typescript@6.0.3: resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} engines: {node: '>=14.17'} @@ -2795,10 +3564,16 @@ packages: resolution: {integrity: sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug==} hasBin: true + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + unc-path-regex@0.1.2: resolution: {integrity: sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==} engines: {node: '>=0.10.0'} + underscore@1.13.8: + resolution: {integrity: sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==} + undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} @@ -2809,9 +3584,25 @@ packages: resolution: {integrity: sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==} engines: {node: '>=18.17'} + undici@7.29.0: + resolution: {integrity: sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==} + engines: {node: '>=20.18.1'} + + unicorn-magic@0.1.0: + resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} + engines: {node: '>=18'} + + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + universal-user-agent@7.0.3: resolution: {integrity: sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==} + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + unixify@1.0.0: resolution: {integrity: sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg==} engines: {node: '>=0.10.0'} @@ -2828,6 +3619,9 @@ packages: upper-case@2.0.2: resolution: {integrity: sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==} + url-join@4.0.1: + resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==} + urlpattern-polyfill@10.1.0: resolution: {integrity: sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==} @@ -2845,6 +3639,13 @@ packages: v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + + version-range@4.15.0: + resolution: {integrity: sha512-Ck0EJbAGxHwprkzFO966t4/5QkRuzh+/I1RxhLgUKKwEn+Cd8NwM60mE3AqBZg5gYODoXW0EFsQvbZjRlvdqbg==} + engines: {node: '>=4'} + vite@8.1.3: resolution: {integrity: sha512-Ds+gBRbj0lwRO2Y5hwnUBdxSwlAve9LeRyU4sNnAr0ewW0gWF0n5bgXgUzbgZ49MV9BVUAQUFYVcDUcilUExMA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2945,6 +3746,11 @@ packages: webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation + whatwg-mimetype@4.0.0: resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} engines: {node: '>=18'} @@ -2979,6 +3785,9 @@ packages: resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} engines: {node: '>=18'} + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + ws@8.18.3: resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} engines: {node: '>=10.0.0'} @@ -2991,6 +3800,18 @@ packages: utf-8-validate: optional: true + wsl-utils@0.1.0: + resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} + engines: {node: '>=18'} + + xml2js@0.5.0: + resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==} + engines: {node: '>=4.0.0'} + + xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -2998,6 +3819,9 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + yaml-ast-parser@0.0.43: resolution: {integrity: sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==} @@ -3019,6 +3843,13 @@ packages: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} + yauzl@3.4.0: + resolution: {integrity: sha512-jIH9yLR9wqr0wOS0TpBvo/g/2UgZH5qePVbjgRliiF0BYvOZyaBknKsF+x9Iht0O6sqgnB93rCICdOZFecJuDw==} + engines: {node: '>=12'} + + yazl@2.5.1: + resolution: {integrity: sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==} + yn@3.1.1: resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} engines: {node: '>=6'} @@ -3090,6 +3921,97 @@ snapshots: transitivePeerDependencies: - encoding + '@azu/format-text@1.0.2': {} + + '@azu/style-format@1.0.1': + dependencies: + '@azu/format-text': 1.0.2 + + '@azure/abort-controller@2.2.0': + dependencies: + tslib: 2.8.1 + + '@azure/core-auth@1.11.0': + dependencies: + '@azure/abort-controller': 2.2.0 + '@azure/core-util': 1.14.0 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@azure/core-client@1.11.0': + dependencies: + '@azure/abort-controller': 2.2.0 + '@azure/core-auth': 1.11.0 + '@azure/core-rest-pipeline': 1.25.0 + '@azure/core-tracing': 1.4.0 + '@azure/core-util': 1.14.0 + '@azure/logger': 1.4.0 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@azure/core-process@1.0.0': {} + + '@azure/core-rest-pipeline@1.25.0': + dependencies: + '@azure/abort-controller': 2.2.0 + '@azure/core-auth': 1.11.0 + '@azure/core-tracing': 1.4.0 + '@azure/core-util': 1.14.0 + '@azure/logger': 1.4.0 + '@typespec/ts-http-runtime': 0.3.8 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@azure/core-tracing@1.4.0': + dependencies: + tslib: 2.8.1 + + '@azure/core-util@1.14.0': + dependencies: + '@azure/abort-controller': 2.2.0 + '@typespec/ts-http-runtime': 0.3.8 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@azure/identity@4.13.2': + dependencies: + '@azure/abort-controller': 2.2.0 + '@azure/core-auth': 1.11.0 + '@azure/core-client': 1.11.0 + '@azure/core-process': 1.0.0 + '@azure/core-rest-pipeline': 1.25.0 + '@azure/core-tracing': 1.4.0 + '@azure/core-util': 1.14.0 + '@azure/logger': 1.4.0 + '@azure/msal-browser': 5.19.0 + '@azure/msal-node': 5.6.0 + open: 10.2.0 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@azure/logger@1.4.0': + dependencies: + '@typespec/ts-http-runtime': 0.3.8 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@azure/msal-browser@5.19.0': + dependencies: + '@azure/msal-common': 16.13.0 + + '@azure/msal-common@16.13.0': {} + + '@azure/msal-node@5.6.0': + dependencies: + '@azure/msal-common': 16.13.0 + jsonwebtoken: 9.0.3 + '@babel/code-frame@7.29.7': dependencies: '@babel/helper-validator-identifier': 7.29.7 @@ -4284,10 +5206,114 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.62.2': optional: true + '@secretlint/config-creator@10.2.2': + dependencies: + '@secretlint/types': 10.2.2 + + '@secretlint/config-loader@10.2.2': + dependencies: + '@secretlint/profiler': 10.2.2 + '@secretlint/resolver': 10.2.2 + '@secretlint/types': 10.2.2 + ajv: 8.20.0 + debug: 4.4.3 + rc-config-loader: 4.1.4 + transitivePeerDependencies: + - supports-color + + '@secretlint/core@10.2.2': + dependencies: + '@secretlint/profiler': 10.2.2 + '@secretlint/types': 10.2.2 + debug: 4.4.3 + structured-source: 4.0.0 + transitivePeerDependencies: + - supports-color + + '@secretlint/formatter@10.2.2': + dependencies: + '@secretlint/resolver': 10.2.2 + '@secretlint/types': 10.2.2 + '@textlint/linter-formatter': 15.8.0 + '@textlint/module-interop': 15.8.0 + '@textlint/types': 15.8.0 + chalk: 5.6.2 + debug: 4.4.3 + pluralize: 8.0.0 + strip-ansi: 7.2.0 + table: 6.9.0 + terminal-link: 4.0.0 + transitivePeerDependencies: + - supports-color + + '@secretlint/node@10.2.2': + dependencies: + '@secretlint/config-loader': 10.2.2 + '@secretlint/core': 10.2.2 + '@secretlint/formatter': 10.2.2 + '@secretlint/profiler': 10.2.2 + '@secretlint/source-creator': 10.2.2 + '@secretlint/types': 10.2.2 + debug: 4.4.3 + p-map: 7.0.6 + transitivePeerDependencies: + - supports-color + + '@secretlint/profiler@10.2.2': {} + + '@secretlint/resolver@10.2.2': {} + + '@secretlint/secretlint-formatter-sarif@10.2.2': + dependencies: + node-sarif-builder: 3.4.0 + + '@secretlint/secretlint-rule-no-dotenv@10.2.2': + dependencies: + '@secretlint/types': 10.2.2 + + '@secretlint/secretlint-rule-preset-recommend@10.2.2': {} + + '@secretlint/source-creator@10.2.2': + dependencies: + '@secretlint/types': 10.2.2 + istextorbinary: 9.5.0 + + '@secretlint/types@10.2.2': {} + '@sindresorhus/fnv1a@3.1.0': {} + '@sindresorhus/merge-streams@2.3.0': {} + '@standard-schema/spec@1.1.0': {} + '@textlint/ast-node-types@15.8.0': {} + + '@textlint/linter-formatter@15.8.0': + dependencies: + '@azu/format-text': 1.0.2 + '@azu/style-format': 1.0.1 + '@textlint/module-interop': 15.8.0 + '@textlint/resolver': 15.8.0 + '@textlint/types': 15.8.0 + debug: 4.4.3 + js-yaml: 4.3.1 + lodash: 4.18.1 + pluralize: 2.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + table: 6.9.0 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + '@textlint/module-interop@15.8.0': {} + + '@textlint/resolver@15.8.0': {} + + '@textlint/types@15.8.0': + dependencies: + '@textlint/ast-node-types': 15.8.0 + '@theguild/federation-composition@0.20.2(graphql@16.8.1)': dependencies: constant-case: 3.0.4 @@ -4330,6 +5356,8 @@ snapshots: dependencies: undici-types: 6.21.0 + '@types/normalize-package-data@2.4.4': {} + '@types/prop-types@15.7.15': {} '@types/react@18.2.45': @@ -4340,11 +5368,23 @@ snapshots: '@types/resolve@1.20.2': {} + '@types/sarif@2.1.7': {} + '@types/scheduler@0.26.0': {} + '@types/vscode@1.80.0': {} + '@types/ws@8.18.1': dependencies: - '@types/node': 18.19.130 + '@types/node': 22.20.0 + + '@typespec/ts-http-runtime@0.3.8': + dependencies: + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color '@urql/core@3.0.0(graphql@16.8.1)': dependencies: @@ -4407,6 +5447,81 @@ snapshots: convert-source-map: 2.0.0 tinyrainbow: 3.1.0 + '@vscode/vsce-sign-alpine-arm64@2.0.6': + optional: true + + '@vscode/vsce-sign-alpine-x64@2.0.6': + optional: true + + '@vscode/vsce-sign-darwin-arm64@2.0.6': + optional: true + + '@vscode/vsce-sign-darwin-x64@2.0.6': + optional: true + + '@vscode/vsce-sign-linux-arm64@2.0.6': + optional: true + + '@vscode/vsce-sign-linux-arm@2.0.6': + optional: true + + '@vscode/vsce-sign-linux-x64@2.0.6': + optional: true + + '@vscode/vsce-sign-win32-arm64@2.0.6': + optional: true + + '@vscode/vsce-sign-win32-x64@2.0.6': + optional: true + + '@vscode/vsce-sign@2.1.0': + optionalDependencies: + '@vscode/vsce-sign-alpine-arm64': 2.0.6 + '@vscode/vsce-sign-alpine-x64': 2.0.6 + '@vscode/vsce-sign-darwin-arm64': 2.0.6 + '@vscode/vsce-sign-darwin-x64': 2.0.6 + '@vscode/vsce-sign-linux-arm': 2.0.6 + '@vscode/vsce-sign-linux-arm64': 2.0.6 + '@vscode/vsce-sign-linux-x64': 2.0.6 + '@vscode/vsce-sign-win32-arm64': 2.0.6 + '@vscode/vsce-sign-win32-x64': 2.0.6 + + '@vscode/vsce@3.9.2': + dependencies: + '@azure/identity': 4.13.2 + '@secretlint/node': 10.2.2 + '@secretlint/secretlint-formatter-sarif': 10.2.2 + '@secretlint/secretlint-rule-no-dotenv': 10.2.2 + '@secretlint/secretlint-rule-preset-recommend': 10.2.2 + '@vscode/vsce-sign': 2.1.0 + azure-devops-node-api: 12.5.0 + chalk: 4.1.2 + cheerio: 1.2.0 + cockatiel: 3.2.1 + commander: 12.1.0 + form-data: 4.0.6 + glob: 13.0.6 + hosted-git-info: 4.1.0 + jsonc-parser: 3.3.1 + leven: 3.1.0 + markdown-it: 14.3.0 + mime: 1.6.0 + minimatch: 10.2.6 + parse-semver: 1.1.1 + read: 1.0.7 + secretlint: 10.2.2 + semver: 7.8.5 + tmp: 0.2.7 + typed-rest-client: 1.8.11 + url-join: 4.0.1 + xml2js: 0.5.0 + yauzl: 3.4.0 + yazl: 2.5.1 + optionalDependencies: + keytar: 7.9.0 + transitivePeerDependencies: + - supports-color + '@whatwg-node/disposablestack@0.0.6': dependencies: '@whatwg-node/promise-helpers': 1.3.2 @@ -4461,6 +5576,13 @@ snapshots: clean-stack: 2.2.0 indent-string: 4.0.0 + ajv@8.20.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.5 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + ansi-escapes@4.3.2: dependencies: type-fest: 0.21.3 @@ -4497,26 +5619,47 @@ snapshots: astral-regex@2.0.0: {} + asynckit@0.4.0: {} + auto-bind@4.0.0: {} + azure-devops-node-api@12.5.0: + dependencies: + tunnel: 0.0.6 + typed-rest-client: 1.8.11 + balanced-match@1.0.2: {} + balanced-match@4.0.4: {} + base64-js@1.5.1: {} baseline-browser-mapping@2.8.26: {} before-after-hook@4.0.0: {} + binaryextensions@6.11.0: + dependencies: + editions: 6.22.0 + bl@4.1.0: dependencies: buffer: 5.7.1 inherits: 2.0.4 readable-stream: 3.6.2 + boolbase@1.0.0: {} + + boundary@2.0.0: {} + brace-expansion@2.0.2: dependencies: balanced-match: 1.0.2 + brace-expansion@5.0.9: + dependencies: + balanced-match: 4.0.4 + braces@3.0.3: dependencies: fill-range: 7.1.1 @@ -4533,6 +5676,10 @@ snapshots: dependencies: node-int64: 0.4.0 + buffer-crc32@0.2.13: {} + + buffer-equal-constant-time@1.0.1: {} + buffer-from@1.1.2: {} buffer@5.7.1: @@ -4540,12 +5687,26 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 + bundle-name@4.1.0: + dependencies: + run-applescript: 7.1.0 + busboy@1.6.0: dependencies: streamsearch: 1.1.0 cac@7.0.0: {} + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + callsites@3.1.0: {} camel-case@4.1.2: @@ -4568,6 +5729,8 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 + chalk@5.6.2: {} + change-case-all@1.0.15: dependencies: change-case: 4.1.2 @@ -4598,6 +5761,32 @@ snapshots: chardet@2.2.0: {} + cheerio-select@2.1.0: + dependencies: + boolbase: 1.0.0 + css-select: 5.2.2 + css-what: 6.2.2 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + + cheerio@1.2.0: + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.2.2 + encoding-sniffer: 0.2.1 + htmlparser2: 10.1.0 + parse5: 7.3.0 + parse5-htmlparser2-tree-adapter: 7.1.0 + parse5-parser-stream: 7.1.2 + undici: 7.29.0 + whatwg-mimetype: 4.0.0 + + chownr@1.1.4: + optional: true + cjs-module-lexer@1.4.3: {} clean-stack@2.2.0: {} @@ -4632,6 +5821,8 @@ snapshots: clone@1.0.4: {} + cockatiel@3.2.1: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -4640,6 +5831,12 @@ snapshots: colorette@2.0.20: {} + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@12.1.0: {} + commander@2.20.3: {} common-tags@1.8.2: {} @@ -4677,6 +5874,16 @@ snapshots: dependencies: tslib: 2.8.1 + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-what@6.2.2: {} + csstype@3.1.3: {} data-uri-to-buffer@4.0.1: {} @@ -4691,13 +5898,32 @@ snapshots: dependencies: ms: 2.1.3 - deepmerge@4.3.1: {} - - defaults@1.0.4: + decompress-response@6.0.0: dependencies: - clone: 1.0.4 + mimic-response: 3.1.0 + optional: true - dependency-graph@0.11.0: {} + deep-extend@0.6.0: + optional: true + + deepmerge@4.3.1: {} + + default-browser-id@5.0.1: {} + + default-browser@5.5.1: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.1 + + defaults@1.0.4: + dependencies: + clone: 1.0.4 + + define-lazy-prop@3.0.0: {} + + delayed-stream@1.0.0: {} + + dependency-graph@0.11.0: {} detect-indent@6.1.0: {} @@ -4709,6 +5935,24 @@ snapshots: dependencies: path-type: 4.0.0 + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + dot-case@3.0.4: dependencies: no-case: 3.0.4 @@ -4720,22 +5964,65 @@ snapshots: dset@3.1.4: {} + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + ecdsa-sig-formatter@1.0.11: + dependencies: + safe-buffer: 5.2.1 + + editions@6.22.0: + dependencies: + version-range: 4.15.0 + electron-to-chromium@1.5.250: {} emoji-regex@10.6.0: {} emoji-regex@8.0.0: {} + encoding-sniffer@0.2.1: + dependencies: + iconv-lite: 0.6.3 + whatwg-encoding: 3.1.1 + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + optional: true + + entities@4.5.0: {} + + entities@6.0.1: {} + + entities@7.0.1: {} + environment@1.1.0: {} error-ex@1.3.4: dependencies: is-arrayish: 0.2.1 + es-define-property@1.0.1: {} + es-errors@1.3.0: {} es-module-lexer@2.3.0: {} + es-object-atoms@1.1.2: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.4 + escalade@3.2.0: {} escape-string-regexp@1.0.5: {} @@ -4748,10 +6035,15 @@ snapshots: eventemitter3@5.0.4: {} + expand-template@2.0.3: + optional: true + expect-type@1.4.0: {} fast-decode-uri-component@1.0.1: {} + fast-deep-equal@3.1.3: {} + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -4770,6 +6062,8 @@ snapshots: dependencies: fast-string-truncated-width: 3.0.3 + fast-uri@3.1.5: {} + fast-url-parser@1.1.3: dependencies: punycode: 1.4.1 @@ -4817,10 +6111,27 @@ snapshots: dependencies: to-regex-range: 5.0.1 + form-data@4.0.6: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.4 + mime-types: 2.1.35 + formdata-polyfill@4.0.10: dependencies: fetch-blob: 3.2.0 + fs-constants@1.0.0: + optional: true + + fs-extra@11.4.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.1 + universalify: 2.0.1 + fsevents@2.3.3: optional: true @@ -4832,10 +6143,37 @@ snapshots: get-east-asian-width@1.6.0: {} + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.4 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.2 + + github-from-package@0.0.0: + optional: true + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 + glob@13.0.6: + dependencies: + minimatch: 10.2.6 + minipass: 7.1.3 + path-scurry: 2.0.2 + globby@11.1.0: dependencies: array-union: 2.1.0 @@ -4845,6 +6183,17 @@ snapshots: merge2: 1.4.1 slash: 3.0.0 + globby@14.1.0: + dependencies: + '@sindresorhus/merge-streams': 2.3.0 + fast-glob: 3.3.3 + ignore: 7.0.6 + path-type: 6.0.0 + slash: 5.1.0 + unicorn-magic: 0.3.0 + + gopd@1.2.0: {} + gql.tada@1.11.0(graphql@16.8.1)(typescript@6.0.3): dependencies: '@0no-co/graphql.web': 1.3.2(graphql@16.8.1) @@ -4857,6 +6206,8 @@ snapshots: - '@gql.tada/vue-support' - graphql + graceful-fs@4.2.11: {} + graphql-config@5.1.5(@types/node@22.20.0)(graphql@16.8.1)(typescript@6.0.3): dependencies: '@graphql-tools/graphql-file-loader': 8.1.4(graphql@16.8.1) @@ -4911,6 +6262,12 @@ snapshots: has-flag@4.0.0: {} + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + hasown@2.0.4: dependencies: function-bind: 1.1.2 @@ -4920,6 +6277,21 @@ snapshots: capital-case: 1.0.4 tslib: 2.8.1 + hosted-git-info@4.1.0: + dependencies: + lru-cache: 6.0.0 + + hosted-git-info@7.0.2: + dependencies: + lru-cache: 10.4.3 + + htmlparser2@10.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 7.0.1 + http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.4 @@ -4938,6 +6310,10 @@ snapshots: husky@9.1.7: {} + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + iconv-lite@0.7.3: dependencies: safer-buffer: 2.1.2 @@ -4946,6 +6322,8 @@ snapshots: ignore@5.3.2: {} + ignore@7.0.6: {} + immutable@3.7.6: {} import-fresh@3.3.1: @@ -4959,8 +6337,13 @@ snapshots: indent-string@4.0.0: {} + index-to-position@1.2.0: {} + inherits@2.0.4: {} + ini@1.3.8: + optional: true + inquirer@8.2.7(@types/node@22.20.0): dependencies: '@inquirer/external-editor': 1.0.3(@types/node@22.20.0) @@ -4996,6 +6379,8 @@ snapshots: dependencies: hasown: 2.0.4 + is-docker@3.0.0: {} + is-extglob@2.1.1: {} is-fullwidth-code-point@3.0.0: {} @@ -5008,6 +6393,10 @@ snapshots: dependencies: is-extglob: 2.1.1 + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + is-interactive@1.0.0: {} is-lower-case@2.0.2: @@ -5038,10 +6427,20 @@ snapshots: is-windows@1.0.2: {} + is-wsl@3.1.1: + dependencies: + is-inside-container: 1.0.0 + isomorphic-ws@5.0.0(ws@8.18.3): dependencies: ws: 8.18.3 + istextorbinary@9.5.0: + dependencies: + binaryextensions: 6.11.0 + editions: 6.22.0 + textextensions: 6.11.0 + jiti@1.21.7: {} jiti@2.6.1: {} @@ -5056,10 +6455,16 @@ snapshots: dependencies: argparse: 2.0.1 + js-yaml@4.3.1: + dependencies: + argparse: 2.0.1 + jsesc@3.1.0: {} json-parse-even-better-errors@2.3.1: {} + json-schema-traverse@1.0.0: {} + json-to-pretty-yaml@1.2.2: dependencies: remedial: 1.0.8 @@ -5071,11 +6476,49 @@ snapshots: jsonc-parser@3.3.1: {} + jsonfile@6.2.1: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + jsonwebtoken@9.0.3: + dependencies: + jws: 4.0.1 + lodash.includes: 4.3.0 + lodash.isboolean: 3.0.3 + lodash.isinteger: 4.0.4 + lodash.isnumber: 3.0.3 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + lodash.once: 4.1.1 + ms: 2.1.3 + semver: 7.8.5 + + jwa@2.0.1: + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + + jws@4.0.1: + dependencies: + jwa: 2.0.1 + safe-buffer: 5.2.1 + + keytar@7.9.0: + dependencies: + node-addon-api: 4.3.0 + prebuild-install: 7.1.3 + optional: true + launch-editor@2.14.1: dependencies: picocolors: 1.1.1 shell-quote: 1.10.0 + leven@3.1.0: {} + lightningcss-android-arm64@1.32.0: optional: true @@ -5127,6 +6570,10 @@ snapshots: lines-and-columns@1.2.4: {} + linkify-it@5.0.2: + dependencies: + uc.micro: 2.1.0 + lint-staged@17.0.8: dependencies: listr2: 10.2.2 @@ -5155,10 +6602,28 @@ snapshots: through: 2.3.8 wrap-ansi: 7.0.0 + lodash.includes@4.3.0: {} + + lodash.isboolean@3.0.3: {} + + lodash.isinteger@4.0.4: {} + + lodash.isnumber@3.0.3: {} + + lodash.isplainobject@4.0.6: {} + + lodash.isstring@4.0.1: {} + + lodash.once@4.1.1: {} + lodash.sortby@4.7.0: {} + lodash.truncate@4.4.2: {} + lodash@4.17.21: {} + lodash@4.18.1: {} + log-symbols@4.1.0: dependencies: chalk: 4.1.2 @@ -5191,12 +6656,18 @@ snapshots: dependencies: tslib: 2.8.1 + lru-cache@10.4.3: {} + lru-cache@11.5.1: {} lru-cache@5.1.1: dependencies: yallist: 3.1.1 + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -5205,6 +6676,19 @@ snapshots: map-cache@0.2.2: {} + markdown-it@14.3.0: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.2 + mdurl: 2.1.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + + math-intrinsics@1.1.0: {} + + mdurl@2.1.0: {} + merge2@1.4.1: {} meros@1.3.2(@types/node@22.20.0): @@ -5216,25 +6700,59 @@ snapshots: braces: 3.0.3 picomatch: 2.3.2 + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime@1.6.0: {} + mimic-fn@2.1.0: {} mimic-function@5.0.1: {} + mimic-response@3.1.0: + optional: true + + minimatch@10.2.6: + dependencies: + brace-expansion: 5.0.9 + minimatch@9.0.5: dependencies: brace-expansion: 2.0.2 + minimist@1.2.8: + optional: true + + minipass@7.1.3: {} + + mkdirp-classic@0.5.3: + optional: true + ms@2.1.3: {} mute-stream@0.0.8: {} nanoid@3.3.15: {} + napi-build-utils@2.0.0: + optional: true + no-case@3.0.4: dependencies: lower-case: 2.0.2 tslib: 2.8.1 + node-abi@3.94.0: + dependencies: + semver: 7.8.5 + optional: true + + node-addon-api@4.3.0: + optional: true + node-domexception@1.0.0: {} node-fetch@2.7.0: @@ -5251,16 +6769,38 @@ snapshots: node-releases@2.0.27: {} + node-sarif-builder@3.4.0: + dependencies: + '@types/sarif': 2.1.7 + fs-extra: 11.4.0 + + normalize-package-data@6.0.2: + dependencies: + hosted-git-info: 7.0.2 + semver: 7.8.5 + validate-npm-package-license: 3.0.4 + normalize-path@2.1.1: dependencies: remove-trailing-separator: 1.1.0 + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + nullthrows@1.1.1: {} object-assign@4.1.1: {} + object-inspect@1.13.4: {} + obug@2.1.3: {} + once@1.4.0: + dependencies: + wrappy: 1.0.2 + optional: true + onetime@5.1.2: dependencies: mimic-fn: 2.1.0 @@ -5269,6 +6809,13 @@ snapshots: dependencies: mimic-function: 5.0.1 + open@10.2.0: + dependencies: + default-browser: 5.5.1 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + wsl-utils: 0.1.0 + ora@5.4.1: dependencies: bl: 4.1.0 @@ -5289,6 +6836,8 @@ snapshots: dependencies: aggregate-error: 3.1.0 + p-map@7.0.6: {} + package-manager-detector@1.8.0: {} param-case@3.0.4: @@ -5313,6 +6862,29 @@ snapshots: json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 + parse-json@8.3.0: + dependencies: + '@babel/code-frame': 7.29.7 + index-to-position: 1.2.0 + type-fest: 4.41.0 + + parse-semver@1.1.1: + dependencies: + semver: 7.8.5 + + parse5-htmlparser2-tree-adapter@7.1.0: + dependencies: + domhandler: 5.0.3 + parse5: 7.3.0 + + parse5-parser-stream@7.1.2: + dependencies: + parse5: 7.3.0 + + parse5@7.3.0: + dependencies: + entities: 6.0.1 + pascal-case@3.1.2: dependencies: no-case: 3.0.4 @@ -5331,28 +6903,65 @@ snapshots: dependencies: path-root-regex: 0.1.2 + path-scurry@2.0.2: + dependencies: + lru-cache: 11.5.1 + minipass: 7.1.3 + path-type@4.0.0: {} + path-type@6.0.0: {} + pathe@2.0.3: {} + pend@1.2.0: {} + picocolors@1.1.1: {} picomatch@2.3.2: {} picomatch@4.0.5: {} + pluralize@2.0.0: {} + + pluralize@8.0.0: {} + postcss@8.5.16: dependencies: nanoid: 3.3.15 picocolors: 1.1.1 source-map-js: 1.2.1 + prebuild-install@7.1.3: + dependencies: + detect-libc: 2.1.2 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.8 + mkdirp-classic: 0.5.3 + napi-build-utils: 2.0.0 + node-abi: 3.94.0 + pump: 3.0.4 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.5 + tunnel-agent: 0.6.0 + optional: true + prettier@3.9.4: {} promise@7.3.1: dependencies: asap: 2.0.6 + pump@3.0.4: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + optional: true + + punycode.js@2.3.1: {} + punycode@1.4.1: {} pvtsutils@1.3.6: @@ -5361,10 +6970,44 @@ snapshots: pvutils@1.1.5: {} + qs@6.15.3: + dependencies: + es-define-property: 1.0.1 + side-channel: 1.1.1 + queue-microtask@1.2.3: {} + rc-config-loader@4.1.4: + dependencies: + debug: 4.4.3 + js-yaml: 4.3.1 + json5: 2.2.3 + require-from-string: 2.0.2 + transitivePeerDependencies: + - supports-color + + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + optional: true + react@19.2.0: {} + read-pkg@9.0.1: + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 6.0.2 + parse-json: 8.3.0 + type-fest: 4.41.0 + unicorn-magic: 0.1.0 + + read@1.0.7: + dependencies: + mute-stream: 0.0.8 + readable-stream@3.6.2: dependencies: inherits: 2.0.4 @@ -5387,6 +7030,8 @@ snapshots: require-directory@2.1.1: {} + require-from-string@2.0.2: {} + resolve-from@4.0.0: {} resolve-from@5.0.0: {} @@ -5481,6 +7126,8 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.62.2 fsevents: 2.3.3 + run-applescript@7.1.0: {} + run-async@2.4.1: {} run-parallel@1.2.0: @@ -5495,8 +7142,22 @@ snapshots: safer-buffer@2.1.2: {} + sax@1.6.1: {} + scuid@1.1.0: {} + secretlint@10.2.2: + dependencies: + '@secretlint/config-creator': 10.2.2 + '@secretlint/formatter': 10.2.2 + '@secretlint/node': 10.2.2 + '@secretlint/profiler': 10.2.2 + debug: 4.4.3 + globby: 14.1.0 + read-pkg: 9.0.1 + transitivePeerDependencies: + - supports-color + semver@6.3.1: {} semver@7.8.5: {} @@ -5515,6 +7176,34 @@ snapshots: shell-quote@1.8.3: {} + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + siginfo@2.0.0: {} signal-exit@3.0.7: {} @@ -5523,10 +7212,22 @@ snapshots: signedsource@1.0.0: {} + simple-concat@1.0.1: + optional: true + + simple-get@4.0.1: + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + optional: true + sisteransi@1.0.5: {} slash@3.0.0: {} + slash@5.1.0: {} + slice-ansi@3.0.0: dependencies: ansi-styles: 4.3.0 @@ -5565,6 +7266,20 @@ snapshots: source-map@0.6.1: {} + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.23 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.23 + + spdx-license-ids@3.0.23: {} + sponge-case@1.0.1: dependencies: tslib: 2.8.1 @@ -5608,10 +7323,22 @@ snapshots: dependencies: ansi-regex: 6.2.2 + strip-json-comments@2.0.1: + optional: true + + structured-source@4.0.0: + dependencies: + boundary: 2.0.0 + supports-color@7.2.0: dependencies: has-flag: 4.0.0 + supports-hyperlinks@3.2.0: + dependencies: + has-flag: 4.0.0 + supports-color: 7.2.0 + supports-preserve-symlinks-flag@1.0.0: {} swap-case@2.0.2: @@ -5624,6 +7351,36 @@ snapshots: timeout-signal: 2.0.0 whatwg-mimetype: 4.0.0 + table@6.9.0: + dependencies: + ajv: 8.20.0 + lodash.truncate: 4.4.2 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + tar-fs@2.1.5: + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.4 + tar-stream: 2.2.0 + optional: true + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.5 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + optional: true + + terminal-link@4.0.0: + dependencies: + ansi-escapes: 7.3.0 + supports-hyperlinks: 3.2.0 + terser@5.48.0: dependencies: '@jridgewell/source-map': 0.3.11 @@ -5631,6 +7388,12 @@ snapshots: commander: 2.20.3 source-map-support: 0.5.21 + text-table@0.2.0: {} + + textextensions@6.11.0: + dependencies: + editions: 6.22.0 + through@2.3.8: {} timeout-signal@2.0.0: {} @@ -5652,6 +7415,8 @@ snapshots: dependencies: tslib: 2.8.1 + tmp@0.2.7: {} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -5684,24 +7449,49 @@ snapshots: tslib@2.8.1: {} + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.2.1 + optional: true + tunnel@0.0.6: {} type-fest@0.21.3: {} + type-fest@4.41.0: {} + + typed-rest-client@1.8.11: + dependencies: + qs: 6.15.3 + tunnel: 0.0.6 + underscore: 1.13.8 + typescript@6.0.3: {} ua-parser-js@1.0.41: {} + uc.micro@2.1.0: {} + unc-path-regex@0.1.2: {} + underscore@1.13.8: {} + undici-types@5.26.5: {} undici-types@6.21.0: {} undici@6.27.0: {} + undici@7.29.0: {} + + unicorn-magic@0.1.0: {} + + unicorn-magic@0.3.0: {} + universal-user-agent@7.0.3: {} + universalify@2.0.1: {} + unixify@1.0.0: dependencies: normalize-path: 2.1.1 @@ -5720,6 +7510,8 @@ snapshots: dependencies: tslib: 2.8.1 + url-join@4.0.1: {} + urlpattern-polyfill@10.1.0: {} urlpattern-polyfill@8.0.2: {} @@ -5736,6 +7528,13 @@ snapshots: v8-compile-cache-lib@3.0.1: {} + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + + version-range@4.15.0: {} + vite@8.1.3(@types/node@22.20.0)(jiti@2.6.1)(terser@5.48.0)(yaml@2.9.0): dependencies: lightningcss: 1.32.0 @@ -5795,6 +7594,10 @@ snapshots: webidl-conversions@3.0.1: {} + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + whatwg-mimetype@4.0.0: {} whatwg-url@5.0.0: @@ -5835,12 +7638,28 @@ snapshots: string-width: 7.2.0 strip-ansi: 7.2.0 + wrappy@1.0.2: + optional: true + ws@8.18.3: {} + wsl-utils@0.1.0: + dependencies: + is-wsl: 3.1.1 + + xml2js@0.5.0: + dependencies: + sax: 1.6.1 + xmlbuilder: 11.0.1 + + xmlbuilder@11.0.1: {} + y18n@5.0.8: {} yallist@3.1.1: {} + yallist@4.0.0: {} + yaml-ast-parser@0.0.43: {} yaml@2.8.1: {} @@ -5859,6 +7678,14 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 + yauzl@3.4.0: + dependencies: + pend: 1.2.0 + + yazl@2.5.1: + dependencies: + buffer-crc32: 0.2.13 + yn@3.1.1: {} yocto-queue@0.1.0: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 35d0b1da..99506c9e 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -3,7 +3,12 @@ packages: - 'test/e2e/**' allowBuilds: + # @vscode/vsce-sign and keytar are pulled in by @vscode/vsce; their install + # scripts only matter for marketplace publishing with signing and OS + # keychain credentials + '@vscode/vsce-sign': false esbuild: true + keytar: false minimumReleaseAgeExclude: - '@0no-co/*' From c4c56f81f37fef7c9f480256e0861bb4f1dc64fe Mon Sep 17 00:00:00 2001 From: Jovi De Croock Date: Sun, 5 Jul 2026 14:53:02 +0200 Subject: [PATCH 2/6] ci: ensure release staging ignores the VSCode extension The extension is already skipped as a private package, but this makes the exclusion explicit and robust: - list vscode-graphqlsp in the changesets ignore list, so neither changesets nor stage-packages ever considers it - skip .staging directories in the release scripts' workspace walkers; the extension's vsix staging area contains a copy of its manifest with the private flag stripped Co-Authored-By: Claude Fable 5 --- .changeset/config.json | 2 +- .github/scripts/has-unpublished-packages.mjs | 4 +++- .github/scripts/stage-packages.mjs | 5 ++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.changeset/config.json b/.changeset/config.json index efede193..ed386944 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -4,7 +4,7 @@ "commit": false, "access": "public", "baseBranch": "main", - "ignore": ["example", "fixtures"], + "ignore": ["example", "fixtures", "vscode-graphqlsp"], "updateInternalDependencies": "minor", "snapshot": { "prereleaseTemplate": "{tag}-{commit}", diff --git a/.github/scripts/has-unpublished-packages.mjs b/.github/scripts/has-unpublished-packages.mjs index ae258389..dbae2e6c 100644 --- a/.github/scripts/has-unpublished-packages.mjs +++ b/.github/scripts/has-unpublished-packages.mjs @@ -2,7 +2,9 @@ import { appendFileSync, existsSync } from 'node:fs'; import { readdir, readFile } from 'node:fs/promises'; import path from 'node:path'; -const ignoredDirectories = new Set(['.git', 'dist', 'node_modules']); +// .staging is the vsix staging area of the VSCode extension; it contains a +// copy of the extension's manifest with the `private` flag stripped +const ignoredDirectories = new Set(['.git', 'dist', 'node_modules', '.staging']); const workspaceRoot = process.cwd(); const hasWorkspaceManifest = existsSync(path.join(workspaceRoot, 'pnpm-workspace.yaml')); diff --git a/.github/scripts/stage-packages.mjs b/.github/scripts/stage-packages.mjs index 6d8c098b..e5323ffe 100644 --- a/.github/scripts/stage-packages.mjs +++ b/.github/scripts/stage-packages.mjs @@ -22,7 +22,10 @@ function packageJsonPathsFromWorkspace() { entry.name === "node_modules" || entry.name === ".pnpm" || entry.name === "dist" || - entry.name === "coverage" + entry.name === "coverage" || + // vsix staging area of the VSCode extension; it contains a copy of + // the extension's manifest with the `private` flag stripped + entry.name === ".staging" ) { continue; } From 22cd8fde1fe5d09bb827c9dc3046b189de65d889 Mon Sep 17 00:00:00 2001 From: Jovi De Croock Date: Sun, 5 Jul 2026 18:41:01 +0200 Subject: [PATCH 3/6] feat: give project config precedence over editor config in global plugin instances An editor-contributed ("global") GraphQLSP instance now resolves its configuration per project instead of blindly using editor settings, preventing conflicts between the two config sources: - defer entirely when the project already runs a local GraphQLSP instance, detected via a Symbol.for marker on the language service proxy that survives separate module copies and covers gql.tada/ts-plugin - adopt the project's tsconfig plugins entry when it exists but produced no instance (e.g. the package isn't installed locally) - fall back to editor settings passed through configurePlugin, which the extension now always tags with editorContributed - stay dormant when nothing is configured Co-Authored-By: Claude Fable 5 --- .changeset/global-plugin-dormancy.md | 2 +- packages/graphqlsp/src/index.ts | 94 ++++++++++++++++++---- packages/vscode-graphqlsp/README.md | 27 ++++--- packages/vscode-graphqlsp/src/extension.ts | 17 ++-- 4 files changed, 99 insertions(+), 41 deletions(-) diff --git a/.changeset/global-plugin-dormancy.md b/.changeset/global-plugin-dormancy.md index 459326b8..0721a3ba 100644 --- a/.changeset/global-plugin-dormancy.md +++ b/.changeset/global-plugin-dormancy.md @@ -2,4 +2,4 @@ '@0no-co/graphqlsp': minor --- -Support being loaded as a "global" tsserver plugin, as contributed by editor extensions. When loaded globally without any `schema`/`schemas` configuration the plugin now passes the language service through untouched, instead of reporting configuration errors in projects that never set up GraphQLSP. +Support being loaded as a "global" tsserver plugin, as contributed by editor extensions, with project configuration taking precedence over editor settings. An editor-contributed instance now defers to a live project-local instance (including `gql.tada/ts-plugin`, detected through a shared marker on the language service), adopts the project's tsconfig `plugins` entry when the plugin package isn't installed locally, falls back to editor settings passed through `configurePlugin`, and otherwise stays dormant instead of reporting configuration errors in projects that never set up GraphQLSP. diff --git a/packages/graphqlsp/src/index.ts b/packages/graphqlsp/src/index.ts index cec56956..3d6ad630 100644 --- a/packages/graphqlsp/src/index.ts +++ b/packages/graphqlsp/src/index.ts @@ -23,6 +23,14 @@ import { templates } from './ast/templates'; import { getPersistedCodeFixAtPosition } from './persisted'; import { canExtractFragment, getExtractFragmentEdits } from './extractFragment'; +/** Marks the language service proxies of active GraphQLSP instances. + * + * `Symbol.for` uses the shared symbol registry, so the marker survives + * multiple module copies of the plugin being loaded side by side — e.g. a + * project's own `gql.tada/ts-plugin` and a copy bundled with an editor + * extension. */ +const instanceMarker = Symbol.for('@0no-co/graphqlsp'); + function createBasicDecorator(info: ts.server.PluginCreateInfo) { const proxy: ts.LanguageService = Object.create(null); for (let k of Object.keys(info.languageService) as Array< @@ -33,6 +41,12 @@ function createBasicDecorator(info: ts.server.PluginCreateInfo) { proxy[k] = (...args: Array<{}>) => x.apply(info.languageService, args); } + // Keep the active-instance marker of a wrapped GraphQLSP proxy visible to + // any plugin instance loaded on top of this one + if ((info.languageService as any)[instanceMarker]) { + (proxy as any)[instanceMarker] = true; + } + return proxy; } @@ -48,29 +62,72 @@ interface Config { clientDirectives?: string[]; trackFieldUsage?: boolean; tadaOutputLocation?: string; + /** Set by tsserver on the synthetic config entries of "global" plugins, + * i.e. plugins contributed by editor extensions, that received no + * configuration overrides. */ + global?: boolean; + /** Set by editor extensions on the configuration they pass through + * tsserver's `configurePlugin`, which replaces the synthetic entry + * carrying `global` above. */ + editorContributed?: boolean; +} + +/** Names GraphQLSP ships under in tsconfig "plugins" entries. */ +const PLUGIN_NAMES = new Set(['@0no-co/graphqlsp', 'gql.tada/ts-plugin']); + +/** Resolves the configuration this instance should run with, or `null` to + * stay dormant. + * + * A project-local instance (configured through a tsconfig "plugins" entry) + * always runs with its entry as-is. For an editor-contributed ("global") + * instance the project's configuration wins over editor settings: + * - a live local instance already handles the project → stay dormant, + * - a tsconfig entry that produced no instance (e.g. the package isn't + * installed in the project) → adopt the entry's configuration, + * - editor settings passed through `configurePlugin` → use them, + * - no configuration anywhere → stay dormant, so unrelated projects don't + * get "missing schema" configuration errors. */ +function resolveConfig( + info: ts.server.PluginCreateInfo, + logger: Logger +): Config | null { + const config: Config = info.config; + if (!config.global && !config.editorContributed) return config; + + if ((info.languageService as any)[instanceMarker]) { + logger('The project already has a GraphQLSP instance; deferring to it'); + return null; + } + + const plugins = (info.project.getCompilerOptions().plugins || []) as Array< + ts.PluginImport & Partial + >; + const localEntry = plugins.find(entry => PLUGIN_NAMES.has(entry.name)); + if (localEntry) { + logger( + `Adopting the project's "${localEntry.name}" tsconfig configuration` + ); + return localEntry as Config; + } + + if (config.schema !== undefined || config.schemas !== undefined) { + return config; + } + + logger('Loaded as a global plugin without configuration; skipping setup'); + return null; } function create(info: ts.server.PluginCreateInfo) { const logger: Logger = (msg: string) => info.project.projectService.logger.info(`[GraphQLSP] ${msg}`); - const config: Config = info.config; - // When an editor extension contributes GraphQLSP, tsserver loads it as a - // "global" plugin into every project — including ones that never set up - // GraphQLSP. Without any schema configuration there's nothing to do, so - // the language service is passed through untouched rather than surfacing - // "missing schema" configuration errors in unrelated projects. (tsserver - // marks the synthetic config entry of global plugins with `global: true`, - // and skips the global copy when a project's tsconfig lists the plugin - // under the same name.) - if ( - (config as { global?: boolean }).global && - config.schema === undefined && - config.schemas === undefined - ) { - logger('Loaded as a global plugin without configuration; skipping setup'); - return createBasicDecorator(info); - } + const config = resolveConfig(info, logger); + if (!config) return createBasicDecorator(info); + + // Everything downstream (diagnostics, completions, schema loading) reads + // `info.config` directly, so an adopted configuration has to land there + info.config = config; logger('config: ' + JSON.stringify(config)); @@ -81,6 +138,9 @@ function create(info: ts.server.PluginCreateInfo) { } const proxy = createBasicDecorator(info); + // Marks this project as handled, keeping an editor-contributed instance + // loaded on top of this one dormant + (proxy as any)[instanceMarker] = true; const schema = loadSchema(info, logger); diff --git a/packages/vscode-graphqlsp/README.md b/packages/vscode-graphqlsp/README.md index edf825c7..79a6191e 100644 --- a/packages/vscode-graphqlsp/README.md +++ b/packages/vscode-graphqlsp/README.md @@ -8,7 +8,7 @@ GraphQL support to TypeScript and JavaScript: and go-to-definition for GraphQL documents without installing the plugin per project. - **Syntax highlighting** for `.graphql`, `.gql`, and `.graphqls` files. - **Inline syntax highlighting** for GraphQL documents in TypeScript/JavaScript: - `` gql`...` `` and `` graphql`...` `` tagged templates, `` graphql(`...`) `` call + `` gql`...` `` and `` graphql`...` `` tagged templates, ``graphql(`...`)`` call expressions (the [gql.tada](https://gql-tada.0no.co) style), and untagged template literals starting with a `#graphql` comment. @@ -23,17 +23,17 @@ the configuration shared with your whole team and CI: "plugins": [ { "name": "@0no-co/graphqlsp", - "schema": "./schema.graphql" - } - ] - } + "schema": "./schema.graphql", + }, + ], + }, } ``` -When a project lists the plugin in its `tsconfig.json`, that configuration is used as-is. -The project doesn't need `@0no-co/graphqlsp` in its own `node_modules` — tsserver falls -back to the copy bundled with this extension. (gql.tada projects using `gql.tada/ts-plugin` -keep working unchanged; that plugin resolves from the project's dependencies.) +When a project lists the plugin in its `tsconfig.json` — as `@0no-co/graphqlsp` or as +gql.tada's `gql.tada/ts-plugin` — that configuration always wins, and the project doesn't +need the plugin in its own `node_modules`: the extension defers to a running project-local +instance, and otherwise adopts the tsconfig entry's configuration using its bundled copy. Alternatively — e.g. for projects whose tsconfig you don't control — the plugin can be configured through VSCode settings: @@ -41,7 +41,7 @@ configured through VSCode settings: ```jsonc { "graphqlsp.schema": "./schema.graphql", - "graphqlsp.templateIsCallExpression": false + "graphqlsp.templateIsCallExpression": false, } ``` @@ -51,9 +51,10 @@ The settings mirror the plugin's options (`graphqlsp.schema`, `graphqlsp.schemas `graphqlsp.clientDirectives`, `graphqlsp.tadaOutputLocation`, `graphqlsp.tadaDisablePreprocessing`); see the [GraphQLSP README](https://github.com/0no-co/GraphQLSP#readme) for what they do. VSCode -settings only apply to projects that _don't_ configure the plugin in their `tsconfig.json`, -and changes require a TypeScript server restart (the extension offers one when settings -change). +settings only apply to projects that _don't_ configure the plugin in their `tsconfig.json` — +per project, the plugin uses the first of: the project's tsconfig entry, these editor +settings, or nothing (dormant). Settings changes require a TypeScript server restart (the +extension offers one when settings change). Without any configuration in either place, the language service plugin stays dormant and only the syntax highlighting is active. diff --git a/packages/vscode-graphqlsp/src/extension.ts b/packages/vscode-graphqlsp/src/extension.ts index c9efb883..0b06181d 100644 --- a/packages/vscode-graphqlsp/src/extension.ts +++ b/packages/vscode-graphqlsp/src/extension.ts @@ -25,13 +25,16 @@ interface TypeScriptLanguageFeaturesExports { getAPI(version: 0): TypeScriptLanguageFeaturesApi | undefined; } -const getPluginConfiguration = (): Record | undefined => { +const getPluginConfiguration = (): Record => { const settings = vscode.workspace.getConfiguration(configurationSection); - let configuration: Record | undefined; + // The marker tells the plugin this configuration comes from an editor + // extension, so it can give a project's own tsconfig "plugins" entry + // precedence over these settings + const configuration: Record = { editorContributed: true }; for (const key of pluginSettings) { const value = settings.get(key); if (value !== null && value !== undefined) { - (configuration || (configuration = {}))[key] = value; + configuration[key] = value; } } return configuration; @@ -50,13 +53,7 @@ export async function activate( if (!api) return; const synchronize = () => { - const configuration = getPluginConfiguration(); - // Without any editor settings the plugin is configured through the - // project's tsconfig instead. Sending an empty configuration would - // replace tsserver's `global: true` marker on the plugin's config - // entry, which the plugin relies on to stay dormant in projects that - // never set up GraphQLSP. - if (configuration) api.configurePlugin(pluginName, configuration); + api.configurePlugin(pluginName, getPluginConfiguration()); }; synchronize(); From c38008538766f9cc3a761397dddad26485c8d37c Mon Sep 17 00:00:00 2001 From: Jovi De Croock Date: Sat, 22 Aug 2026 14:24:07 +0200 Subject: [PATCH 4/6] fix: defer extension plugin to installed local versions --- packages/graphqlsp/src/config.ts | 108 +++++++++++++++++++++++++++ packages/graphqlsp/src/index.ts | 71 +----------------- test/unit/config.test.ts | 124 +++++++++++++++++++++++++++++++ 3 files changed, 234 insertions(+), 69 deletions(-) create mode 100644 packages/graphqlsp/src/config.ts create mode 100644 test/unit/config.test.ts diff --git a/packages/graphqlsp/src/config.ts b/packages/graphqlsp/src/config.ts new file mode 100644 index 00000000..11d89d60 --- /dev/null +++ b/packages/graphqlsp/src/config.ts @@ -0,0 +1,108 @@ +import type { SchemaOrigin } from '@gql.tada/internal'; + +import { ts } from './ts'; + +export interface Config { + schema: SchemaOrigin; + schemas: SchemaOrigin[]; + tadaDisablePreprocessing?: boolean; + templateIsCallExpression?: boolean; + shouldCheckForColocatedFragments?: boolean; + template?: string; + clientDirectives?: string[]; + trackFieldUsage?: boolean; + tadaOutputLocation?: string; + /** Set by tsserver on the synthetic config entries of "global" plugins, + * i.e. plugins contributed by editor extensions, that received no + * configuration overrides. */ + global?: boolean; + /** Set by editor extensions on the configuration they pass through + * tsserver's `configurePlugin`, which replaces the synthetic entry + * carrying `global` above. */ + editorContributed?: boolean; +} + +/** Names GraphQLSP ships under in tsconfig "plugins" entries. */ +const PLUGIN_NAMES = new Set(['@0no-co/graphqlsp', 'gql.tada/ts-plugin']); + +const getPackageName = (pluginName: string): string => { + const parts = pluginName.split('/'); + return pluginName.startsWith('@') ? parts.slice(0, 2).join('/') : parts[0]!; +}; + +/** Checks whether a tsconfig plugin can be resolved from the project's local + * node_modules tree without loading it. Older GraphQLSP releases don't expose + * the shared instance marker, so package presence is the only side-effect-free + * way for an editor-contributed copy to defer to them before they initialize. */ +const hasLocalPluginPackage = ( + info: ts.server.PluginCreateInfo, + pluginName: string +): boolean => { + const packageName = getPackageName(pluginName); + let directory = info.project.getCurrentDirectory(); + + while (true) { + const manifest = ts.combinePaths( + directory, + 'node_modules', + packageName, + 'package.json' + ); + if (info.project.fileExists(manifest)) return true; + + const parent = ts.getDirectoryPath(directory); + if (parent === directory) return false; + directory = parent; + } +}; + +/** Resolves the configuration this instance should run with, or `null` to + * stay dormant. + * + * A project-local instance (configured through a tsconfig "plugins" entry) + * always runs with its entry as-is. For an editor-contributed ("global") + * instance the project's configuration wins over editor settings: + * - a live local instance already handles the project → stay dormant, + * - an installed older local instance has no marker → stay dormant, + * - a tsconfig entry whose package is unavailable → adopt its configuration, + * - editor settings passed through `configurePlugin` → use them, + * - no configuration anywhere → stay dormant, so unrelated projects don't + * get "missing schema" configuration errors. */ +export function resolveConfig( + info: ts.server.PluginCreateInfo, + logger: (message: string) => void, + instanceMarker: symbol +): Config | null { + const config: Config = info.config; + if (!config.global && !config.editorContributed) return config; + + if ((info.languageService as any)[instanceMarker]) { + logger('The project already has a GraphQLSP instance; deferring to it'); + return null; + } + + const plugins = (info.project.getCompilerOptions().plugins || []) as Array< + ts.PluginImport & Partial + >; + const localEntry = plugins.find(entry => PLUGIN_NAMES.has(entry.name)); + if (localEntry) { + if (hasLocalPluginPackage(info, localEntry.name)) { + logger( + `The project has a local "${localEntry.name}" installation; deferring to it` + ); + return null; + } + + logger( + `Adopting the project's "${localEntry.name}" tsconfig configuration because its local package is unavailable` + ); + return localEntry as Config; + } + + if (config.schema !== undefined || config.schemas !== undefined) { + return config; + } + + logger('Loaded as a global plugin without configuration; skipping setup'); + return null; +} diff --git a/packages/graphqlsp/src/index.ts b/packages/graphqlsp/src/index.ts index 3d6ad630..b3887ac7 100644 --- a/packages/graphqlsp/src/index.ts +++ b/packages/graphqlsp/src/index.ts @@ -1,6 +1,5 @@ -import type { SchemaOrigin } from '@gql.tada/internal'; - import { ts, init as initTypeScript } from './ts'; +import { resolveConfig } from './config'; import { loadSchema } from './graphql/getSchema'; import { getGraphQLCompletions } from './autoComplete'; import { getGraphQLQuickInfo } from './quickInfo'; @@ -52,77 +51,11 @@ function createBasicDecorator(info: ts.server.PluginCreateInfo) { export type Logger = (msg: string) => void; -interface Config { - schema: SchemaOrigin; - schemas: SchemaOrigin[]; - tadaDisablePreprocessing?: boolean; - templateIsCallExpression?: boolean; - shouldCheckForColocatedFragments?: boolean; - template?: string; - clientDirectives?: string[]; - trackFieldUsage?: boolean; - tadaOutputLocation?: string; - /** Set by tsserver on the synthetic config entries of "global" plugins, - * i.e. plugins contributed by editor extensions, that received no - * configuration overrides. */ - global?: boolean; - /** Set by editor extensions on the configuration they pass through - * tsserver's `configurePlugin`, which replaces the synthetic entry - * carrying `global` above. */ - editorContributed?: boolean; -} - -/** Names GraphQLSP ships under in tsconfig "plugins" entries. */ -const PLUGIN_NAMES = new Set(['@0no-co/graphqlsp', 'gql.tada/ts-plugin']); - -/** Resolves the configuration this instance should run with, or `null` to - * stay dormant. - * - * A project-local instance (configured through a tsconfig "plugins" entry) - * always runs with its entry as-is. For an editor-contributed ("global") - * instance the project's configuration wins over editor settings: - * - a live local instance already handles the project → stay dormant, - * - a tsconfig entry that produced no instance (e.g. the package isn't - * installed in the project) → adopt the entry's configuration, - * - editor settings passed through `configurePlugin` → use them, - * - no configuration anywhere → stay dormant, so unrelated projects don't - * get "missing schema" configuration errors. */ -function resolveConfig( - info: ts.server.PluginCreateInfo, - logger: Logger -): Config | null { - const config: Config = info.config; - if (!config.global && !config.editorContributed) return config; - - if ((info.languageService as any)[instanceMarker]) { - logger('The project already has a GraphQLSP instance; deferring to it'); - return null; - } - - const plugins = (info.project.getCompilerOptions().plugins || []) as Array< - ts.PluginImport & Partial - >; - const localEntry = plugins.find(entry => PLUGIN_NAMES.has(entry.name)); - if (localEntry) { - logger( - `Adopting the project's "${localEntry.name}" tsconfig configuration` - ); - return localEntry as Config; - } - - if (config.schema !== undefined || config.schemas !== undefined) { - return config; - } - - logger('Loaded as a global plugin without configuration; skipping setup'); - return null; -} - function create(info: ts.server.PluginCreateInfo) { const logger: Logger = (msg: string) => info.project.projectService.logger.info(`[GraphQLSP] ${msg}`); - const config = resolveConfig(info, logger); + const config = resolveConfig(info, logger, instanceMarker); if (!config) return createBasicDecorator(info); // Everything downstream (diagnostics, completions, schema loading) reads diff --git a/test/unit/config.test.ts b/test/unit/config.test.ts new file mode 100644 index 00000000..fc9060eb --- /dev/null +++ b/test/unit/config.test.ts @@ -0,0 +1,124 @@ +import { describe, expect, it } from 'vitest'; +import ts from 'typescript/lib/tsserverlibrary'; + +import { resolveConfig } from '../../packages/graphqlsp/src/config'; +import { init } from '../../packages/graphqlsp/src/ts'; + +init({ typescript: ts }); + +const instanceMarker = Symbol.for('@0no-co/graphqlsp'); + +const createInfo = ({ + config, + plugins = [], + manifests = [], + marked = false, +}: { + config: Record; + plugins?: Array & { name: string }>; + manifests?: string[]; + marked?: boolean; +}) => { + const languageService = {} as ts.LanguageService; + if (marked) (languageService as any)[instanceMarker] = true; + + const manifestSet = new Set(manifests); + return { + languageService, + config, + project: { + getCompilerOptions: () => ({ plugins }), + getCurrentDirectory: () => '/workspace/packages/app', + fileExists: (fileName: string) => manifestSet.has(fileName), + }, + } as unknown as ts.server.PluginCreateInfo; +}; + +const resolve = (info: ts.server.PluginCreateInfo) => { + const logs: string[] = []; + const config = resolveConfig( + info, + message => logs.push(message), + instanceMarker + ); + return { config, logs }; +}; + +describe('editor-contributed plugin configuration', () => { + it('leaves project-local plugin instances active', () => { + const localConfig = { schema: './schema.graphql' }; + const { config } = resolve(createInfo({ config: localConfig })); + + expect(config).toBe(localConfig); + }); + + it('defers when a marked GraphQLSP instance is already active', () => { + const { config, logs } = resolve( + createInfo({ config: { global: true }, marked: true }) + ); + + expect(config).toBeNull(); + expect(logs).toEqual([ + 'The project already has a GraphQLSP instance; deferring to it', + ]); + }); + + it.each([ + [ + '@0no-co/graphqlsp', + '/workspace/node_modules/@0no-co/graphqlsp/package.json', + ], + ['gql.tada/ts-plugin', '/workspace/node_modules/gql.tada/package.json'], + ])('defers to an installed older local %s plugin', (name, manifest) => { + const localEntry = { name, schema: './local.graphql' }; + const { config, logs } = resolve( + createInfo({ + config: { editorContributed: true, schema: './editor.graphql' }, + plugins: [localEntry], + manifests: [manifest], + }) + ); + + expect(config).toBeNull(); + expect(logs).toEqual([ + `The project has a local "${name}" installation; deferring to it`, + ]); + }); + + it('adopts tsconfig settings when the local plugin package is unavailable', () => { + const localEntry = { + name: '@0no-co/graphqlsp', + schema: './local.graphql', + }; + const { config, logs } = resolve( + createInfo({ + config: { global: true }, + plugins: [localEntry], + }) + ); + + expect(config).toBe(localEntry); + expect(logs).toEqual([ + 'Adopting the project\'s "@0no-co/graphqlsp" tsconfig configuration because its local package is unavailable', + ]); + }); + + it('uses editor settings when no project-local plugin is configured', () => { + const editorConfig = { + editorContributed: true, + schema: './editor.graphql', + }; + const { config } = resolve(createInfo({ config: editorConfig })); + + expect(config).toBe(editorConfig); + }); + + it('stays dormant when neither project nor editor provides a schema', () => { + const { config, logs } = resolve(createInfo({ config: { global: true } })); + + expect(config).toBeNull(); + expect(logs).toEqual([ + 'Loaded as a global plugin without configuration; skipping setup', + ]); + }); +}); From 1f5f3f923439cacd3b49e9adbb033d99651d0c2a Mon Sep 17 00:00:00 2001 From: Jovi De Croock Date: Sat, 22 Aug 2026 18:09:42 +0200 Subject: [PATCH 5/6] fix(vscode): use TypeScript 6 module resolution --- packages/vscode-graphqlsp/tsconfig.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/vscode-graphqlsp/tsconfig.json b/packages/vscode-graphqlsp/tsconfig.json index 2fb78bf9..dfa66e39 100644 --- a/packages/vscode-graphqlsp/tsconfig.json +++ b/packages/vscode-graphqlsp/tsconfig.json @@ -3,8 +3,8 @@ "compilerOptions": { "target": "ES2020", "lib": ["ES2020"], - "module": "commonjs", - "moduleResolution": "node", + "module": "Node16", + "moduleResolution": "Node16", "rootDir": "src", "outDir": "dist", "sourceMap": true From 8b15398d23eef034782be5ce18a7100a60c6831c Mon Sep 17 00:00:00 2001 From: Jovi De Croock Date: Sun, 23 Aug 2026 08:11:22 +0200 Subject: [PATCH 6/6] feat(vscode): add GraphQL operations and fragments to the outline (#410) --- README.md | 1 + packages/vscode-graphqlsp/README.md | 2 + packages/vscode-graphqlsp/package.json | 3 +- packages/vscode-graphqlsp/scripts/package.mjs | 10 +- .../vscode-graphqlsp/src/documentSymbols.ts | 243 ++++++++++++++++++ packages/vscode-graphqlsp/src/extension.ts | 61 ++++- pnpm-lock.yaml | 3 + test/unit/documentSymbols.test.ts | 91 +++++++ 8 files changed, 403 insertions(+), 11 deletions(-) create mode 100644 packages/vscode-graphqlsp/src/documentSymbols.ts create mode 100644 test/unit/documentSymbols.test.ts diff --git a/README.md b/README.md index ef66a7f4..a838d849 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ auto-complete. - Find references and rename for GraphQL fragments, across your project's files - Will warn you when you are importing from a file that is exporting fragments that you're not using - An "Extract to fragment" refactor that moves selected fields into a new co-located fragment (in `graphql()` call-expression mode) +- The VS Code extension adds GraphQL operations and fragments to the Outline view and symbol navigation > Note that this plugin does not do syntax highlighting, for that you still need something like > [the VSCode/... plugin](https://marketplace.visualstudio.com/items?itemName=GraphQL.vscode-graphql-syntax) diff --git a/packages/vscode-graphqlsp/README.md b/packages/vscode-graphqlsp/README.md index 79a6191e..2ec4caf4 100644 --- a/packages/vscode-graphqlsp/README.md +++ b/packages/vscode-graphqlsp/README.md @@ -7,6 +7,8 @@ GraphQL support to TypeScript and JavaScript: TypeScript language features, so you get diagnostics, auto-completion, hover information, and go-to-definition for GraphQL documents without installing the plugin per project. - **Syntax highlighting** for `.graphql`, `.gql`, and `.graphqls` files. +- **Document symbols** for embedded GraphQL operations and fragments in the Outline view + and “Go to Symbol in Editor…” (`Cmd/Ctrl+Shift+O`). - **Inline syntax highlighting** for GraphQL documents in TypeScript/JavaScript: `` gql`...` `` and `` graphql`...` `` tagged templates, ``graphql(`...`)`` call expressions (the [gql.tada](https://gql-tada.0no.co) style), and untagged template diff --git a/packages/vscode-graphqlsp/package.json b/packages/vscode-graphqlsp/package.json index 31542616..0edf1b28 100644 --- a/packages/vscode-graphqlsp/package.json +++ b/packages/vscode-graphqlsp/package.json @@ -178,7 +178,8 @@ "vscode:prepublish": "pnpm build" }, "dependencies": { - "@0no-co/graphqlsp": "workspace:*" + "@0no-co/graphqlsp": "workspace:*", + "graphql": "^16.0.0" }, "devDependencies": { "@types/node": "^18.15.11", diff --git a/packages/vscode-graphqlsp/scripts/package.mjs b/packages/vscode-graphqlsp/scripts/package.mjs index 791f0246..4ad30cfa 100644 --- a/packages/vscode-graphqlsp/scripts/package.mjs +++ b/packages/vscode-graphqlsp/scripts/package.mjs @@ -56,7 +56,10 @@ const manifest = JSON.parse( delete manifest.private; delete manifest.scripts; delete manifest.devDependencies; -manifest.dependencies = { '@0no-co/graphqlsp': `file:./${tarball}` }; +manifest.dependencies = { + ...manifest.dependencies, + '@0no-co/graphqlsp': `file:./${tarball}`, +}; fs.writeFileSync( path.join(stagingDir, 'package.json'), JSON.stringify(manifest, null, 2) @@ -121,7 +124,10 @@ const installedPlugin = JSON.parse( 'utf8' ) ); -manifest.dependencies = { '@0no-co/graphqlsp': installedPlugin.version }; +manifest.dependencies = { + ...manifest.dependencies, + '@0no-co/graphqlsp': installedPlugin.version, +}; fs.writeFileSync( path.join(stagingDir, 'package.json'), JSON.stringify(manifest, null, 2) diff --git a/packages/vscode-graphqlsp/src/documentSymbols.ts b/packages/vscode-graphqlsp/src/documentSymbols.ts new file mode 100644 index 00000000..f2a8a770 --- /dev/null +++ b/packages/vscode-graphqlsp/src/documentSymbols.ts @@ -0,0 +1,243 @@ +import { Kind, parse } from 'graphql'; + +export interface OffsetRange { + start: number; + end: number; +} + +export interface GraphQLDocumentSymbol { + name: string; + type: 'operation' | 'fragment'; + range: OffsetRange; + selectionRange: OffsetRange; +} + +interface EmbeddedDocument { + contentStart: number; + text: string; +} + +const isIdentifierStart = (char: string | undefined): boolean => + !!char && /[A-Za-z_$]/.test(char); +const isIdentifierPart = (char: string | undefined): boolean => + !!char && /[A-Za-z0-9_$]/.test(char); + +const skipLineComment = (source: string, start: number): number => { + const end = source.indexOf('\n', start + 2); + return end === -1 ? source.length : end; +}; + +const skipBlockComment = (source: string, start: number): number => { + const end = source.indexOf('*/', start + 2); + return end === -1 ? source.length : end + 2; +}; + +const skipQuotedString = ( + source: string, + start: number, + quote: "'" | '"' +): number => { + for (let index = start + 1; index < source.length; index++) { + if (source[index] === '\\') { + index++; + } else if (source[index] === quote) { + return index + 1; + } + } + return source.length; +}; + +const skipTemplate = (source: string, start: number): number => { + for (let index = start + 1; index < source.length; index++) { + if (source[index] === '\\') { + index++; + } else if (source[index] === '`') { + return index + 1; + } else if (source[index] === '$' && source[index + 1] === '{') { + index = skipExpression(source, index + 2) - 1; + } + } + return source.length; +}; + +const skipExpression = (source: string, start: number): number => { + let depth = 1; + for (let index = start; index < source.length; index++) { + const char = source[index]; + if (char === "'" || char === '"') { + index = skipQuotedString(source, index, char) - 1; + } else if (char === '`') { + index = skipTemplate(source, index) - 1; + } else if (char === '/' && source[index + 1] === '/') { + index = skipLineComment(source, index) - 1; + } else if (char === '/' && source[index + 1] === '*') { + index = skipBlockComment(source, index) - 1; + } else if (char === '{') { + depth++; + } else if (char === '}' && --depth === 0) { + return index + 1; + } + } + return source.length; +}; + +const skipTrivia = (source: string, start: number): number => { + let index = start; + while (index < source.length) { + if (/\s/.test(source[index]!)) { + index++; + } else if (source[index] === '/' && source[index + 1] === '/') { + index = skipLineComment(source, index); + } else if (source[index] === '/' && source[index + 1] === '*') { + index = skipBlockComment(source, index); + } else { + break; + } + } + return index; +}; + +/** Replaces template interpolations with same-length whitespace so GraphQL + * locations still map directly back to the source document. */ +const maskTemplateInterpolations = (text: string): string => { + const chars = text.split(''); + for (let index = 0; index < text.length - 1; index++) { + if (text[index] === '\\') { + index++; + } else if (text[index] === '$' && text[index + 1] === '{') { + const end = skipExpression(text, index + 2); + for (let offset = index; offset < end; offset++) { + if (chars[offset] !== '\n' && chars[offset] !== '\r') + chars[offset] = ' '; + } + index = end - 1; + } + } + return chars.join(''); +}; + +const readDocumentLiteral = ( + source: string, + start: number +): { document: EmbeddedDocument; end: number } | undefined => { + const quote = source[start]; + if (quote !== "'" && quote !== '"' && quote !== '`') return undefined; + + const end = + quote === '`' + ? skipTemplate(source, start) + : skipQuotedString(source, start, quote); + if (end > source.length || source[end - 1] !== quote) return undefined; + + const raw = source.slice(start + 1, end - 1); + return { + document: { + contentStart: start + 1, + text: quote === '`' ? maskTemplateInterpolations(raw) : raw, + }, + end, + }; +}; + +/** Finds GraphQL documents embedded in calls or tagged templates without + * requiring a second TypeScript compiler in the extension host. */ +const collectEmbeddedDocuments = ( + source: string, + templateNames: ReadonlySet +): EmbeddedDocument[] => { + const documents: EmbeddedDocument[] = []; + + for (let index = 0; index < source.length;) { + const char = source[index]; + if (char === '/' && source[index + 1] === '/') { + index = skipLineComment(source, index); + continue; + } + if (char === '/' && source[index + 1] === '*') { + index = skipBlockComment(source, index); + continue; + } + if (char === "'" || char === '"') { + index = skipQuotedString(source, index, char); + continue; + } + if (char === '`') { + index = skipTemplate(source, index); + continue; + } + if (!isIdentifierStart(char)) { + index++; + continue; + } + + const identifierStart = index++; + while (isIdentifierPart(source[index])) index++; + const identifier = source.slice(identifierStart, index); + if (!templateNames.has(identifier)) continue; + + const next = skipTrivia(source, index); + if (source[next] === '`') { + const literal = readDocumentLiteral(source, next); + if (literal) documents.push(literal.document); + } else if (source[next] === '(') { + const argument = skipTrivia(source, next + 1); + const literal = readDocumentLiteral(source, argument); + if (literal) documents.push(literal.document); + } + } + + return documents; +}; + +export const getGraphQLDocumentSymbols = ( + source: string, + additionalTemplate?: string +): GraphQLDocumentSymbol[] => { + const templateNames = new Set(['gql', 'graphql']); + if (additionalTemplate) templateNames.add(additionalTemplate); + + const symbols: GraphQLDocumentSymbol[] = []; + for (const document of collectEmbeddedDocuments(source, templateNames)) { + let parsed; + try { + parsed = parse(document.text); + } catch (_error) { + continue; + } + + for (const definition of parsed.definitions) { + if (!definition.loc) continue; + + let name: string; + let type: GraphQLDocumentSymbol['type']; + if (definition.kind === Kind.OPERATION_DEFINITION) { + name = definition.name + ? `${definition.operation} ${definition.name.value}` + : `${definition.operation} (anonymous)`; + type = 'operation'; + } else if (definition.kind === Kind.FRAGMENT_DEFINITION) { + name = `fragment ${definition.name.value} on ${definition.typeCondition.name.value}`; + type = 'fragment'; + } else { + continue; + } + + const start = document.contentStart + definition.loc.start; + const end = document.contentStart + definition.loc.end; + const nameLocation = definition.name?.loc; + symbols.push({ + name, + type, + range: { start, end }, + selectionRange: nameLocation + ? { + start: document.contentStart + nameLocation.start, + end: document.contentStart + nameLocation.end, + } + : { start, end: Math.min(start + 1, end) }, + }); + } + } + + return symbols; +}; diff --git a/packages/vscode-graphqlsp/src/extension.ts b/packages/vscode-graphqlsp/src/extension.ts index 0b06181d..bd89d77e 100644 --- a/packages/vscode-graphqlsp/src/extension.ts +++ b/packages/vscode-graphqlsp/src/extension.ts @@ -1,5 +1,7 @@ import * as vscode from 'vscode'; +import { getGraphQLDocumentSymbols } from './documentSymbols'; + /** Must match the `typescriptServerPlugins` contribution in package.json. */ const pluginName = '@0no-co/graphqlsp'; const configurationSection = 'graphqlsp'; @@ -43,24 +45,67 @@ const getPluginConfiguration = (): Record => { export async function activate( context: vscode.ExtensionContext ): Promise { + const registerDocumentSymbols = () => + vscode.languages.registerDocumentSymbolProvider( + [ + { language: 'javascript' }, + { language: 'javascriptreact' }, + { language: 'typescript' }, + { language: 'typescriptreact' }, + ], + { + provideDocumentSymbols(document, token) { + if (token.isCancellationRequested) return []; + const template = vscode.workspace + .getConfiguration(configurationSection, document.uri) + .get('template'); + + return getGraphQLDocumentSymbols(document.getText(), template).map( + symbol => + new vscode.DocumentSymbol( + symbol.name, + 'GraphQL', + symbol.type === 'fragment' + ? vscode.SymbolKind.Struct + : vscode.SymbolKind.Function, + new vscode.Range( + document.positionAt(symbol.range.start), + document.positionAt(symbol.range.end) + ), + new vscode.Range( + document.positionAt(symbol.selectionRange.start), + document.positionAt(symbol.selectionRange.end) + ) + ) + ); + }, + } + ); + + let documentSymbolRegistration = registerDocumentSymbols(); + context.subscriptions.push({ + dispose: () => documentSymbolRegistration.dispose(), + }); + const tsExtension = vscode.extensions.getExtension( 'vscode.typescript-language-features' ); - if (!tsExtension) return; - - const api = (await tsExtension.activate()).getAPI(0); - if (!api) return; - - const synchronize = () => { - api.configurePlugin(pluginName, getPluginConfiguration()); - }; + const api = tsExtension + ? (await tsExtension.activate()).getAPI(0) + : undefined; + const synchronize = () => + api?.configurePlugin(pluginName, getPluginConfiguration()); synchronize(); context.subscriptions.push( vscode.workspace.onDidChangeConfiguration(async event => { if (!event.affectsConfiguration(configurationSection)) return; + documentSymbolRegistration.dispose(); + documentSymbolRegistration = registerDocumentSymbols(); + if (!api) return; + synchronize(); // The plugin reads its configuration once per project, so changes // only take effect after the TypeScript server restarts diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c6442441..ac275374 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -211,6 +211,9 @@ importers: '@0no-co/graphqlsp': specifier: workspace:* version: link:../graphqlsp + graphql: + specifier: ^16.0.0 + version: 16.8.1 devDependencies: '@types/node': specifier: ^18.15.11 diff --git a/test/unit/documentSymbols.test.ts b/test/unit/documentSymbols.test.ts new file mode 100644 index 00000000..c08d2bd3 --- /dev/null +++ b/test/unit/documentSymbols.test.ts @@ -0,0 +1,91 @@ +import { describe, expect, it } from 'vitest'; + +import { getGraphQLDocumentSymbols } from '../../packages/vscode-graphqlsp/src/documentSymbols'; + +const span = (source: string, text: string) => { + const start = source.indexOf(text); + if (start === -1) throw new Error(`Could not find ${JSON.stringify(text)}`); + return { start, end: start + text.length }; +}; + +describe('VS Code GraphQL document symbols', () => { + it('finds operations and fragments in call expressions', () => { + const source = ` + const fields = graphql(\` + fragment PokemonFields on Pokemon { + id + } + \`); + const query = graphql(\` + query Pokemons($limit: Int!) { + pokemons(limit: $limit) { id } + } + \`, [fields]); + const anonymous = graphql('query { pokemon(id: "1") { id } }'); + `; + + const symbols = getGraphQLDocumentSymbols(source); + expect(symbols.map(symbol => symbol.name)).toEqual([ + 'fragment PokemonFields on Pokemon', + 'query Pokemons', + 'query (anonymous)', + ]); + expect(symbols[0]!.selectionRange).toEqual(span(source, 'PokemonFields')); + expect(symbols[1]!.selectionRange).toEqual(span(source, 'Pokemons')); + expect(source.slice(symbols[2]!.range.start, symbols[2]!.range.end)).toBe( + 'query { pokemon(id: "1") { id } }' + ); + }); + + it('finds tagged templates and masks fragment interpolations', () => { + const source = ` + const fields = gql\`fragment Fields on Pokemon { id }\`; + const query = gql\` + query WithInterpolation { + pokemon(id: "1") { + \${fields} + name + } + } + \`; + `; + + expect( + getGraphQLDocumentSymbols(source).map(symbol => symbol.name) + ).toEqual(['fragment Fields on Pokemon', 'query WithInterpolation']); + }); + + it('supports a configured custom template name', () => { + const source = ` + const ignored = customGraphQL(\`query Custom { pokemons { id } }\`); + `; + + expect(getGraphQLDocumentSymbols(source)).toEqual([]); + expect( + getGraphQLDocumentSymbols(source, 'customGraphQL').map( + symbol => symbol.name + ) + ).toEqual(['query Custom']); + }); + + it('does not inspect comments, ordinary strings, or unrelated templates', () => { + const source = ` + // graphql(\`query Comment { pokemons { id } }\`) + const text = "gql\`query String { pokemons { id } }\`"; + const other = html\`

graphql(\`not really code\`)

\`; + `; + + expect(getGraphQLDocumentSymbols(source)).toEqual([]); + }); + + it('skips malformed GraphQL documents without affecting valid ones', () => { + const source = ` + const malformed = graphql(\`query {\`); + const valid = graphql(\`mutation Save { savePokemon { id } }\`); + `; + + expect( + getGraphQLDocumentSymbols(source).map(symbol => symbol.name) + ).toEqual(['mutation Save']); + }); +});