Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4efa31459b | |||
| f8ea05739d | |||
| 73dd3c33c4 | |||
| e5800c8843 | |||
| bba2a01c01 | |||
| ec52bd7358 |
+152
@@ -0,0 +1,152 @@
|
|||||||
|
# Using GitHub Actions Language Server in Neovim
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Node.js 18+
|
||||||
|
- Neovim 0.11+ with the new LSP config format
|
||||||
|
|
||||||
|
## Setup Options
|
||||||
|
|
||||||
|
### Option 1: Install from npm (Recommended)
|
||||||
|
|
||||||
|
Once published, you can install globally:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install -g @actions/languageserver
|
||||||
|
```
|
||||||
|
|
||||||
|
Then configure Neovim to use the installed binary:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
-- ~/.config/nvim/lsp/actionsls.lua
|
||||||
|
return {
|
||||||
|
cmd = { "actions-languageserver" },
|
||||||
|
filetypes = { "yaml.ghaction" }, -- GitHub Actions workflow files only
|
||||||
|
root_markers = { ".git" },
|
||||||
|
init_options = {
|
||||||
|
sessionToken = vim.fn.system("gh auth token"):gsub("%s+", ""),
|
||||||
|
logLevel = "info",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** This requires the package to be published to npm first.
|
||||||
|
|
||||||
|
### Option 2: Local Development Build
|
||||||
|
|
||||||
|
For development or if the npm package isn't published yet:
|
||||||
|
|
||||||
|
### 1. Clone and build
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/actions/languageservices.git
|
||||||
|
cd languageservices
|
||||||
|
npm install
|
||||||
|
npm run build --workspaces --if-present
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Bundle the server
|
||||||
|
|
||||||
|
The server needs to be bundled into a single file to avoid ESM module resolution issues:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd languageserver
|
||||||
|
npx esbuild src/index.ts \
|
||||||
|
--bundle \
|
||||||
|
--platform=node \
|
||||||
|
--target=node18 \
|
||||||
|
--format=cjs \
|
||||||
|
--outfile=dist/server-bundled.cjs \
|
||||||
|
--external:vscode \
|
||||||
|
--loader:.json=json
|
||||||
|
```
|
||||||
|
|
||||||
|
This creates `dist/server-bundled.cjs` (~5.6MB) that contains the entire server.
|
||||||
|
|
||||||
|
### 3. Configure Neovim
|
||||||
|
|
||||||
|
Create `~/.config/nvim/lsp/actionsls.lua`:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
return {
|
||||||
|
cmd = {
|
||||||
|
"/absolute/path/to/languageservices/languageserver/bin/actions-languageserver",
|
||||||
|
},
|
||||||
|
filetypes = { "yaml.ghaction" }, -- GitHub Actions workflow files only
|
||||||
|
root_markers = { ".git" },
|
||||||
|
init_options = {
|
||||||
|
sessionToken = vim.fn.system("gh auth token"):gsub("%s+", ""),
|
||||||
|
logLevel = "info",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Important:** Replace `/absolute/path/to/languageservices` with your actual clone path.
|
||||||
|
|
||||||
|
## Filetype Detection for GitHub Actions Workflows
|
||||||
|
|
||||||
|
To ensure the LSP only runs on GitHub Actions workflow files (not all YAML files), set up filetype detection:
|
||||||
|
|
||||||
|
**Option A:** In `~/.config/nvim/init.lua`:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
vim.api.nvim_create_autocmd({"BufRead", "BufNewFile"}, {
|
||||||
|
pattern = ".github/workflows/*.{yml,yaml}",
|
||||||
|
callback = function()
|
||||||
|
vim.bo.filetype = "yaml.ghaction"
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
**Option B:** Create `~/.config/nvim/ftdetect/ghaction.vim`:
|
||||||
|
|
||||||
|
```vim
|
||||||
|
au BufRead,BufNewFile .github/workflows/*.yml,*.yaml setfiletype yaml.ghaction
|
||||||
|
```
|
||||||
|
|
||||||
|
This sets the filetype to `yaml.ghaction` for files in `.github/workflows/`, matching the `filetypes` setting in your LSP config.
|
||||||
|
|
||||||
|
### 4. Enable the LSP in your init.lua
|
||||||
|
|
||||||
|
Add to your Neovim configuration:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
vim.lsp.enable('actionsls')
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Restart Neovim
|
||||||
|
|
||||||
|
Open any `.github/workflows/*.yml` file. The filetype detection will set it to `yaml.ghaction`, and the language server will attach automatically.
|
||||||
|
|
||||||
|
## Files Created
|
||||||
|
|
||||||
|
- `languageserver/dist/server-bundled.cjs` - Bundled server (~5.6MB)
|
||||||
|
- `languageserver/bin/actions-languageserver` - Shell wrapper script
|
||||||
|
|
||||||
|
The `dist/` directory is gitignored; you'll need to rebuild after pulling updates.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
Check if the server is running:
|
||||||
|
|
||||||
|
```vim
|
||||||
|
:lua =vim.lsp.get_clients()
|
||||||
|
```
|
||||||
|
|
||||||
|
View LSP logs:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tail -f ~/.local/state/nvim/lsp.log
|
||||||
|
```
|
||||||
|
|
||||||
|
Manually start the server to test:
|
||||||
|
|
||||||
|
```vim
|
||||||
|
:lua vim.lsp.start({name='actionsls', cmd={'/path/to/bin/actions-languageserver'}, root_dir=vim.fn.getcwd(), init_options={sessionToken='', logLevel='info'}})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- The main code change is in `languageserver/src/index.ts` to use dynamic imports, avoiding loading browser modules in Node.js
|
||||||
|
- The bundling step is necessary because TypeScript outputs ESM with bare imports that Node.js can't resolve
|
||||||
|
- Only workflow files in git repositories will activate the LSP (due to `root_markers = { ".git" }`)
|
||||||
Executable
+2
@@ -0,0 +1,2 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
import "../dist/cli.bundle.cjs";
|
||||||
@@ -32,6 +32,7 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc --build tsconfig.build.json",
|
"build": "tsc --build tsconfig.build.json",
|
||||||
|
"build:cli": "esbuild src/index.ts --bundle --platform=node --format=cjs --outfile=dist/cli.bundle.cjs",
|
||||||
"clean": "rimraf dist",
|
"clean": "rimraf dist",
|
||||||
"format": "prettier --write '**/*.ts'",
|
"format": "prettier --write '**/*.ts'",
|
||||||
"format-check": "prettier --check '**/*.ts'",
|
"format-check": "prettier --check '**/*.ts'",
|
||||||
@@ -42,6 +43,9 @@
|
|||||||
"test-watch": "NODE_OPTIONS=\"--experimental-vm-modules\" jest --watch",
|
"test-watch": "NODE_OPTIONS=\"--experimental-vm-modules\" jest --watch",
|
||||||
"watch": "tsc --build tsconfig.build.json --watch"
|
"watch": "tsc --build tsconfig.build.json --watch"
|
||||||
},
|
},
|
||||||
|
"bin": {
|
||||||
|
"actions-languageserver": "./bin/actions-languageserver"
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/languageservice": "^0.3.20",
|
"@actions/languageservice": "^0.3.20",
|
||||||
"@actions/workflow-parser": "^0.3.20",
|
"@actions/workflow-parser": "^0.3.20",
|
||||||
@@ -61,6 +65,7 @@
|
|||||||
"@types/jest": "^29.0.3",
|
"@types/jest": "^29.0.3",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.56.0",
|
"@typescript-eslint/eslint-plugin": "^5.56.0",
|
||||||
"@typescript-eslint/parser": "^5.56.0",
|
"@typescript-eslint/parser": "^5.56.0",
|
||||||
|
"esbuild": "^0.27.1",
|
||||||
"eslint": "^8.36.0",
|
"eslint": "^8.36.0",
|
||||||
"eslint-config-prettier": "^8.8.0",
|
"eslint-config-prettier": "^8.8.0",
|
||||||
"eslint-plugin-prettier": "^4.2.1",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
|
|||||||
Executable
+10
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
npx esbuild src/index.ts \
|
||||||
|
--bundle \
|
||||||
|
--platform=node \
|
||||||
|
--target=node18 \
|
||||||
|
--format=cjs \
|
||||||
|
--outfile=dist/server-bundled.cjs \
|
||||||
|
--external:vscode \
|
||||||
|
--loader:.json=json
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
import {documentLinks, hover, validate, ValidationConfig} from "@actions/languageservice";
|
import {documentLinks, getCodeActions, hover, validate, ValidationConfig} from "@actions/languageservice";
|
||||||
import {registerLogger, setLogLevel} from "@actions/languageservice/log";
|
import {registerLogger, setLogLevel} from "@actions/languageservice/log";
|
||||||
import {clearCache, clearCacheEntry} from "@actions/languageservice/utils/workflow-cache";
|
import {clearCache, clearCacheEntry} from "@actions/languageservice/utils/workflow-cache";
|
||||||
import {Octokit} from "@octokit/rest";
|
import {Octokit} from "@octokit/rest";
|
||||||
import {
|
import {
|
||||||
|
CodeAction,
|
||||||
|
CodeActionKind,
|
||||||
|
CodeActionParams,
|
||||||
CompletionItem,
|
CompletionItem,
|
||||||
Connection,
|
Connection,
|
||||||
DocumentLink,
|
DocumentLink,
|
||||||
@@ -72,6 +75,9 @@ export function initConnection(connection: Connection) {
|
|||||||
hoverProvider: true,
|
hoverProvider: true,
|
||||||
documentLinkProvider: {
|
documentLinkProvider: {
|
||||||
resolveProvider: false
|
resolveProvider: false
|
||||||
|
},
|
||||||
|
codeActionProvider: {
|
||||||
|
codeActionKinds: [CodeActionKind.QuickFix]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -158,6 +164,16 @@ export function initConnection(connection: Connection) {
|
|||||||
return documentLinks(getDocument(documents, textDocument), repoContext?.workspaceUri);
|
return documentLinks(getDocument(documents, textDocument), repoContext?.workspaceUri);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
connection.onCodeAction(async (params: CodeActionParams): Promise<CodeAction[]> => {
|
||||||
|
return timeOperation("codeAction", async () => {
|
||||||
|
return getCodeActions({
|
||||||
|
uri: params.textDocument.uri,
|
||||||
|
diagnostics: params.context.diagnostics,
|
||||||
|
only: params.context.only
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// Make the text document manager listen on the connection
|
// Make the text document manager listen on the connection
|
||||||
// for open, change and close text document events
|
// for open, change and close text document events
|
||||||
documents.listen(connection);
|
documents.listen(connection);
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import {Connection} from "vscode-languageserver";
|
import { Connection } from "vscode-languageserver";
|
||||||
import {
|
import {
|
||||||
BrowserMessageReader,
|
BrowserMessageReader,
|
||||||
BrowserMessageWriter,
|
BrowserMessageWriter,
|
||||||
createConnection as createBrowserConnection
|
createConnection as createBrowserConnection
|
||||||
} from "vscode-languageserver/browser";
|
} from "vscode-languageserver/browser";
|
||||||
import {createConnection as createNodeConnection} from "vscode-languageserver/node";
|
import { createConnection as createNodeConnection } from "vscode-languageserver/node";
|
||||||
|
|
||||||
import {initConnection} from "./connection";
|
import { initConnection } from "./connection";
|
||||||
|
|
||||||
/** Helper function determining whether we are executing with node runtime */
|
/** Helper function determining whether we are executing with node runtime */
|
||||||
function isNode(): boolean {
|
function isNode(): boolean {
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
import {CodeAction, CodeActionKind, Diagnostic} from "vscode-languageserver-types";
|
||||||
|
import {CodeActionContext, CodeActionProvider} from "./types";
|
||||||
|
import {quickfixProviders} from "./quickfix";
|
||||||
|
|
||||||
|
// Aggregate all providers by kind
|
||||||
|
const providersByKind: Map<string, CodeActionProvider[]> = new Map([
|
||||||
|
[CodeActionKind.QuickFix, quickfixProviders]
|
||||||
|
// [CodeActionKind. Refactor, refactorProviders],
|
||||||
|
// [CodeActionKind.Source, sourceProviders],
|
||||||
|
// etc
|
||||||
|
]);
|
||||||
|
|
||||||
|
export interface CodeActionConfig {
|
||||||
|
// TODO: actionsMetadataProvider, fileProvider, etc.
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CodeActionParams {
|
||||||
|
uri: string;
|
||||||
|
diagnostics: Diagnostic[];
|
||||||
|
only?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCodeActions(params: CodeActionParams, config?: CodeActionConfig): CodeAction[] {
|
||||||
|
const actions: CodeAction[] = [];
|
||||||
|
const context: CodeActionContext = {
|
||||||
|
uri: params.uri
|
||||||
|
};
|
||||||
|
|
||||||
|
// Filter to requested kinds, or use all if none specified
|
||||||
|
const requestedKinds = params.only;
|
||||||
|
const kindsToCheck = requestedKinds
|
||||||
|
? [...providersByKind.keys()].filter(kind => requestedKinds.some(requested => kind.startsWith(requested)))
|
||||||
|
: [...providersByKind.keys()];
|
||||||
|
|
||||||
|
for (const diagnostic of params.diagnostics) {
|
||||||
|
for (const kind of kindsToCheck) {
|
||||||
|
const providers = providersByKind.get(kind) ?? [];
|
||||||
|
for (const provider of providers) {
|
||||||
|
if (provider.diagnosticCodes.includes(diagnostic.code)) {
|
||||||
|
const action = provider.createCodeAction(context, diagnostic);
|
||||||
|
if (action) {
|
||||||
|
action.kind = kind;
|
||||||
|
action.diagnostics = [diagnostic];
|
||||||
|
actions.push(action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type {CodeActionContext, CodeActionProvider} from "./types";
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
import { CodeAction, TextEdit } from "vscode-languageserver-types";
|
||||||
|
import { CodeActionContext, CodeActionProvider } from "../types";
|
||||||
|
import { DiagnosticCode, MissingInputsDiagnosticData } from "../../validate-action";
|
||||||
|
|
||||||
|
export const addMissingInputsProvider: CodeActionProvider = {
|
||||||
|
diagnosticCodes: [DiagnosticCode.MissingRequiredInputs],
|
||||||
|
|
||||||
|
createCodeAction(context, diagnostic): CodeAction | undefined {
|
||||||
|
const data = diagnostic.data as MissingInputsDiagnosticData | undefined;
|
||||||
|
if (!data) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const edits = createInputEdits(data);
|
||||||
|
if (!edits) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const inputNames = data.missingInputs.map(i => i.name).join(", ");
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: `Add missing input${data.missingInputs.length > 1 ? "s" : ""}: ${inputNames}`,
|
||||||
|
edit: {
|
||||||
|
changes: {
|
||||||
|
[context.uri]: edits,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function createInputEdits(data: MissingInputsDiagnosticData): TextEdit[] | undefined {
|
||||||
|
const edits: TextEdit[] = [];
|
||||||
|
|
||||||
|
if (data.hasWithKey && data.withIndent !== undefined) {
|
||||||
|
// `with:` exists - use its indentation + 2 for inputs
|
||||||
|
const inputIndent = " ".repeat(data.withIndent + 2);
|
||||||
|
|
||||||
|
const inputLines = data.missingInputs.map(input => {
|
||||||
|
const value = input.default !== undefined ? input.default : '""';
|
||||||
|
return `${inputIndent}${input.name}: ${value}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
edits.push({
|
||||||
|
range: { start: data.insertPosition, end: data.insertPosition },
|
||||||
|
newText: inputLines.map(line => line + "\n").join(""),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// No `with:` key - `with:` at step indentation, inputs at step indentation + 2
|
||||||
|
const withIndent = " ".repeat(data.stepIndent);
|
||||||
|
const inputIndent = " ".repeat(data.stepIndent + 2);
|
||||||
|
|
||||||
|
const inputLines = data.missingInputs.map(input => {
|
||||||
|
const value = input.default !== undefined ? input.default : '""';
|
||||||
|
return `${inputIndent}${input.name}: ${value}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
const newText = [`${withIndent}with:\n`, ...inputLines.map(line => `${line}\n`)].join("");
|
||||||
|
|
||||||
|
edits.push({
|
||||||
|
range: { start: data.insertPosition, end: data.insertPosition },
|
||||||
|
newText,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return edits;
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
import {CodeActionProvider} from "../types";
|
||||||
|
import {addMissingInputsProvider} from "./add-missing-inputs";
|
||||||
|
|
||||||
|
export const quickfixProviders: CodeActionProvider[] = [addMissingInputsProvider];
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
import * as path from "path";
|
||||||
|
import {fileURLToPath} from "url";
|
||||||
|
import {loadTestCases, runTestCase} from "./runner";
|
||||||
|
import {ValidationConfig} from "../../validate";
|
||||||
|
import {ActionMetadata, ActionReference} from "../../action";
|
||||||
|
import {clearCache} from "../../utils/workflow-cache";
|
||||||
|
|
||||||
|
// ESM-compatible __dirname
|
||||||
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
|
const __dirname = path.dirname(__filename);
|
||||||
|
|
||||||
|
// Mock action metadata provider for tests
|
||||||
|
const validationConfig: ValidationConfig = {
|
||||||
|
actionsMetadataProvider: {
|
||||||
|
fetchActionMetadata: (ref: ActionReference): Promise<ActionMetadata | undefined> => {
|
||||||
|
const key = `${ref.owner}/${ref.name}@${ref.ref}`;
|
||||||
|
|
||||||
|
const metadata: Record<string, ActionMetadata> = {
|
||||||
|
"actions/cache@v1": {
|
||||||
|
name: "Cache",
|
||||||
|
description: "Cache dependencies",
|
||||||
|
inputs: {
|
||||||
|
path: {
|
||||||
|
description: "A list of files to cache",
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
key: {
|
||||||
|
description: "Cache key",
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
"restore-keys": {
|
||||||
|
description: "Restore keys",
|
||||||
|
required: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"actions/setup-node@v3": {
|
||||||
|
name: "Setup Node",
|
||||||
|
description: "Setup Node. js",
|
||||||
|
inputs: {
|
||||||
|
"node-version": {
|
||||||
|
description: "Node version",
|
||||||
|
required: true,
|
||||||
|
default: "16"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return Promise.resolve(metadata[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Point to the source testdata directory
|
||||||
|
const testdataDir = path.join(__dirname, "testdata");
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
clearCache();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("code action golden tests", () => {
|
||||||
|
const testCases = loadTestCases(testdataDir);
|
||||||
|
|
||||||
|
if (testCases.length === 0) {
|
||||||
|
it.todo("no test cases found - add . yml files to testdata/");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const testCase of testCases) {
|
||||||
|
it(testCase.name, async () => {
|
||||||
|
const result = await runTestCase(testCase, validationConfig);
|
||||||
|
|
||||||
|
if (!result.passed) {
|
||||||
|
let errorMessage = result.error || "Test failed";
|
||||||
|
|
||||||
|
if (result.expected !== undefined && result.actual !== undefined) {
|
||||||
|
errorMessage += "\n\n";
|
||||||
|
errorMessage += "=== EXPECTED (golden file) ===\n";
|
||||||
|
errorMessage += result.expected;
|
||||||
|
errorMessage += "\n\n";
|
||||||
|
errorMessage += "=== ACTUAL ===\n";
|
||||||
|
errorMessage += result.actual;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(errorMessage);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -0,0 +1,227 @@
|
|||||||
|
import * as fs from "fs";
|
||||||
|
import * as path from "path";
|
||||||
|
import { TextEdit } from "vscode-languageserver-types";
|
||||||
|
import { TextDocument } from "vscode-languageserver-textdocument";
|
||||||
|
import { validate, ValidationConfig } from "../../validate";
|
||||||
|
import { getCodeActions, CodeActionParams } from "../index";
|
||||||
|
|
||||||
|
// Marker pattern: # want "diagnostic message" fix="code-action-name"
|
||||||
|
const MARKER_PATTERN = /#\s*want\s+"([^"]+)"(?:\s+fix="([^"]+)")?/;
|
||||||
|
|
||||||
|
export interface TestCase {
|
||||||
|
name: string;
|
||||||
|
inputPath: string;
|
||||||
|
goldenPath: string;
|
||||||
|
input: string;
|
||||||
|
golden: string;
|
||||||
|
markers: Marker[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Marker {
|
||||||
|
line: number;
|
||||||
|
message: string;
|
||||||
|
fix?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TestResult {
|
||||||
|
name: string;
|
||||||
|
passed: boolean;
|
||||||
|
error?: string;
|
||||||
|
expected?: string;
|
||||||
|
actual?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse markers from input file content
|
||||||
|
*/
|
||||||
|
export function parseMarkers(content: string): Marker[] {
|
||||||
|
const lines = content.split("\n");
|
||||||
|
const markers: Marker[] = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < lines.length; i++) {
|
||||||
|
const match = lines[i].match(MARKER_PATTERN);
|
||||||
|
if (match) {
|
||||||
|
markers.push({
|
||||||
|
line: i,
|
||||||
|
message: match[1],
|
||||||
|
fix: match[2]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return markers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strip markers from content (for processing)
|
||||||
|
*/
|
||||||
|
export function stripMarkers(content: string): string {
|
||||||
|
return content
|
||||||
|
.split("\n")
|
||||||
|
.map(line => line.replace(MARKER_PATTERN, "").trimEnd())
|
||||||
|
.join("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load all test cases from a testdata directory
|
||||||
|
*/
|
||||||
|
export function loadTestCases(testdataDir: string): TestCase[] {
|
||||||
|
const testCases: TestCase[] = [];
|
||||||
|
|
||||||
|
function walkDir(dir: string) {
|
||||||
|
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
||||||
|
|
||||||
|
for (const entry of entries) {
|
||||||
|
const fullPath = path.join(dir, entry.name);
|
||||||
|
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
walkDir(fullPath);
|
||||||
|
} else if (entry.isFile() && entry.name.endsWith(".yml") && !entry.name.endsWith(". golden.yml")) {
|
||||||
|
const goldenPath = fullPath.replace(".yml", ".golden.yml");
|
||||||
|
|
||||||
|
if (fs.existsSync(goldenPath)) {
|
||||||
|
const input = fs.readFileSync(fullPath, "utf-8");
|
||||||
|
const golden = fs.readFileSync(goldenPath, "utf-8");
|
||||||
|
|
||||||
|
testCases.push({
|
||||||
|
name: path.relative(testdataDir, fullPath),
|
||||||
|
inputPath: fullPath,
|
||||||
|
goldenPath,
|
||||||
|
input,
|
||||||
|
golden,
|
||||||
|
markers: parseMarkers(input)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
walkDir(testdataDir);
|
||||||
|
return testCases;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply text edits to a document
|
||||||
|
*/
|
||||||
|
export function applyEdits(content: string, edits: TextEdit[]): string {
|
||||||
|
// Sort edits in reverse order by position to apply from bottom to top
|
||||||
|
const sortedEdits = [...edits].sort((a, b) => {
|
||||||
|
if (b.range.start.line !== a.range.start.line) {
|
||||||
|
return b.range.start.line - a.range.start.line;
|
||||||
|
}
|
||||||
|
return b.range.start.character - a.range.start.character;
|
||||||
|
});
|
||||||
|
|
||||||
|
const lines = content.split("\n");
|
||||||
|
|
||||||
|
for (const edit of sortedEdits) {
|
||||||
|
const startLine = edit.range.start.line;
|
||||||
|
const startChar = edit.range.start.character;
|
||||||
|
const endLine = edit.range.end.line;
|
||||||
|
const endChar = edit.range.end.character;
|
||||||
|
|
||||||
|
const before = lines[startLine].slice(0, startChar);
|
||||||
|
const after = lines[endLine].slice(endChar);
|
||||||
|
|
||||||
|
const newLines = edit.newText.split("\n");
|
||||||
|
newLines[0] = before + newLines[0];
|
||||||
|
newLines[newLines.length - 1] = newLines[newLines.length - 1] + after;
|
||||||
|
|
||||||
|
lines.splice(startLine, endLine - startLine + 1, ...newLines);
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines.join("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run a single test case
|
||||||
|
*/
|
||||||
|
export async function runTestCase(testCase: TestCase, validationConfig: ValidationConfig): Promise<TestResult> {
|
||||||
|
const strippedInput = stripMarkers(testCase.input);
|
||||||
|
const document = TextDocument.create("file:///test.yml", "yaml", 1, strippedInput);
|
||||||
|
|
||||||
|
// 1. Validate and get diagnostics
|
||||||
|
const diagnostics = await validate(document, validationConfig);
|
||||||
|
|
||||||
|
// 2. Verify all expected diagnostics are present
|
||||||
|
const missingDiagnostics: string[] = [];
|
||||||
|
for (const marker of testCase.markers) {
|
||||||
|
const found = diagnostics.find(d => d.range.start.line === marker.line && d.message.includes(marker.message));
|
||||||
|
console.log(found);
|
||||||
|
if (!found) {
|
||||||
|
missingDiagnostics.push(`line ${marker.line}: "${marker.message}"`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (missingDiagnostics.length > 0) {
|
||||||
|
return {
|
||||||
|
name: testCase.name,
|
||||||
|
passed: false,
|
||||||
|
error: `Missing expected diagnostics:\n ${missingDiagnostics.join(
|
||||||
|
"\n "
|
||||||
|
)}\n\nActual diagnostics:\n ${diagnostics.map(d => `line ${d.range.start.line}: "${d.message}"`).join("\n ")}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Collect all edits from all matching code actions
|
||||||
|
const allEdits: TextEdit[] = [];
|
||||||
|
|
||||||
|
for (const marker of testCase.markers) {
|
||||||
|
if (!marker.fix) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const diagnostic = diagnostics.find(d => d.range.start.line === marker.line && d.message.includes(marker.message));
|
||||||
|
|
||||||
|
if (!diagnostic) {
|
||||||
|
continue; // Already reported above
|
||||||
|
}
|
||||||
|
|
||||||
|
const params: CodeActionParams = {
|
||||||
|
uri: document.uri,
|
||||||
|
diagnostics: [diagnostic]
|
||||||
|
};
|
||||||
|
|
||||||
|
const actions = getCodeActions(params);
|
||||||
|
const matchingAction = actions.find(a => a.title.toLowerCase().includes(marker.fix!.toLowerCase()));
|
||||||
|
|
||||||
|
if (!matchingAction) {
|
||||||
|
return {
|
||||||
|
name: testCase.name,
|
||||||
|
passed: false,
|
||||||
|
error: `Code action "${marker.fix}" not found for diagnostic on line ${marker.line}.\nAvailable actions: ${actions.map(a => a.title).join(", ") || "(none)"
|
||||||
|
}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!matchingAction.edit?.changes) {
|
||||||
|
return {
|
||||||
|
name: testCase.name,
|
||||||
|
passed: false,
|
||||||
|
error: `Code action "${marker.fix}" has no edits`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const edits = matchingAction.edit.changes[document.uri] || [];
|
||||||
|
allEdits.push(...edits);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Apply all edits and compare to golden file
|
||||||
|
const actualOutput = applyEdits(strippedInput, allEdits);
|
||||||
|
const expectedOutput = testCase.golden;
|
||||||
|
|
||||||
|
if (actualOutput.trim() !== expectedOutput.trim()) {
|
||||||
|
return {
|
||||||
|
name: testCase.name,
|
||||||
|
passed: false,
|
||||||
|
error: "Output does not match golden file",
|
||||||
|
expected: expectedOutput,
|
||||||
|
actual: actualOutput
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: testCase.name,
|
||||||
|
passed: true
|
||||||
|
};
|
||||||
|
}
|
||||||
languageservice/src/code-actions/tests/testdata/quickfix/existing-with-key-without-inputs.golden.yml
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
on: push
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/cache@v1
|
||||||
|
with:
|
||||||
|
path: ""
|
||||||
|
key: ""
|
||||||
Vendored
+7
@@ -0,0 +1,7 @@
|
|||||||
|
on: push
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/cache@v1
|
||||||
|
with: # want "Missing required inputs: `path`, `key`" fix="Add missing inputs: path, key"
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
on: push
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/cache@v1
|
||||||
|
with:
|
||||||
|
restore-keys: ${{ runner.os }}-
|
||||||
|
path: ""
|
||||||
|
key: ""
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
on: push
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/cache@v1
|
||||||
|
with: # want "Missing required inputs: `path`, `key`" fix="Add missing inputs: path, key"
|
||||||
|
restore-keys: ${{ runner.os }}-
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
on: push
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/cache@v1
|
||||||
|
with:
|
||||||
|
path: ""
|
||||||
|
key: ""
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
on: push
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/cache@v1 # want "Missing required inputs: `path`, `key`" fix="Add missing inputs: path, key"
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import {CodeAction, Diagnostic} from "vscode-languageserver-types";
|
||||||
|
|
||||||
|
export interface CodeActionContext {
|
||||||
|
uri: string;
|
||||||
|
// TODO: add things like workflow template, parsed content, etc.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A provider that can produce a code action for a given diagnostic
|
||||||
|
*/
|
||||||
|
export interface CodeActionProvider {
|
||||||
|
/**
|
||||||
|
* The diagnostic codes this provider handles
|
||||||
|
*/
|
||||||
|
diagnosticCodes: (string | number | undefined)[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a code action for the diagnostic, if applicable
|
||||||
|
*/
|
||||||
|
createCodeAction(context: CodeActionContext, diagnostic: Diagnostic): CodeAction | undefined;
|
||||||
|
}
|
||||||
@@ -5,3 +5,4 @@ export {hover} from "./hover";
|
|||||||
export {Logger, LogLevel, registerLogger, setLogLevel} from "./log";
|
export {Logger, LogLevel, registerLogger, setLogLevel} from "./log";
|
||||||
export {validate, ValidationConfig, ActionsMetadataProvider} from "./validate";
|
export {validate, ValidationConfig, ActionsMetadataProvider} from "./validate";
|
||||||
export {ValueProviderConfig, ValueProviderKind} from "./value-providers/config";
|
export {ValueProviderConfig, ValueProviderKind} from "./value-providers/config";
|
||||||
|
export {getCodeActions} from "./code-actions";
|
||||||
|
|||||||
@@ -1,12 +1,30 @@
|
|||||||
import {isMapping} from "@actions/workflow-parser";
|
import { isMapping } from "@actions/workflow-parser";
|
||||||
import {isActionStep} from "@actions/workflow-parser/model/type-guards";
|
import { isActionStep } from "@actions/workflow-parser/model/type-guards";
|
||||||
import {Step} from "@actions/workflow-parser/model/workflow-template";
|
import { Step } from "@actions/workflow-parser/model/workflow-template";
|
||||||
import {ScalarToken} from "@actions/workflow-parser/templates/tokens/scalar-token";
|
import { ScalarToken } from "@actions/workflow-parser/templates/tokens/scalar-token";
|
||||||
import {TemplateToken} from "@actions/workflow-parser/templates/tokens/template-token";
|
import { TemplateToken } from "@actions/workflow-parser/templates/tokens/template-token";
|
||||||
import {Diagnostic, DiagnosticSeverity} from "vscode-languageserver-types";
|
import { Diagnostic, DiagnosticSeverity } from "vscode-languageserver-types";
|
||||||
import {parseActionReference} from "./action";
|
import { ActionReference, parseActionReference } from "./action";
|
||||||
import {mapRange} from "./utils/range";
|
import { mapRange } from "./utils/range";
|
||||||
import {ValidationConfig} from "./validate";
|
import { ValidationConfig } from "./validate";
|
||||||
|
|
||||||
|
export const DiagnosticCode = {
|
||||||
|
MissingRequiredInputs: "missing-required-inputs"
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export interface MissingInputsDiagnosticData {
|
||||||
|
action: ActionReference;
|
||||||
|
missingInputs: Array<{
|
||||||
|
name: string;
|
||||||
|
default?: string;
|
||||||
|
}>;
|
||||||
|
hasWithKey: boolean;
|
||||||
|
// Indentation of the `with:` key if present, or the step's base indentation
|
||||||
|
withIndent?: number;
|
||||||
|
stepIndent: number;
|
||||||
|
// Position where new content should be inserted
|
||||||
|
insertPosition: { line: number; character: number };
|
||||||
|
}
|
||||||
|
|
||||||
export async function validateAction(
|
export async function validateAction(
|
||||||
diagnostics: Diagnostic[],
|
diagnostics: Diagnostic[],
|
||||||
@@ -35,7 +53,7 @@ export async function validateAction(
|
|||||||
|
|
||||||
let withKey: ScalarToken | undefined;
|
let withKey: ScalarToken | undefined;
|
||||||
let withToken: TemplateToken | undefined;
|
let withToken: TemplateToken | undefined;
|
||||||
for (const {key, value} of stepToken) {
|
for (const { key, value } of stepToken) {
|
||||||
if (key.toString() === "with") {
|
if (key.toString() === "with") {
|
||||||
withKey = key;
|
withKey = key;
|
||||||
withToken = value;
|
withToken = value;
|
||||||
@@ -45,7 +63,7 @@ export async function validateAction(
|
|||||||
|
|
||||||
const stepInputs = new Map<string, ScalarToken>();
|
const stepInputs = new Map<string, ScalarToken>();
|
||||||
if (withToken && isMapping(withToken)) {
|
if (withToken && isMapping(withToken)) {
|
||||||
for (const {key} of withToken) {
|
for (const { key } of withToken) {
|
||||||
stepInputs.set(key.toString(), key);
|
stepInputs.set(key.toString(), key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,10 +101,47 @@ export async function validateAction(
|
|||||||
missingRequiredInputs.length === 1
|
missingRequiredInputs.length === 1
|
||||||
? `Missing required input \`${missingRequiredInputs[0][0]}\``
|
? `Missing required input \`${missingRequiredInputs[0][0]}\``
|
||||||
: `Missing required inputs: ${missingRequiredInputs.map(input => `\`${input[0]}\``).join(", ")}`;
|
: `Missing required inputs: ${missingRequiredInputs.map(input => `\`${input[0]}\``).join(", ")}`;
|
||||||
|
|
||||||
|
const stepIndent = stepToken.range ? stepToken.range.start.column - 1 : 0; // 0-indexed
|
||||||
|
const withIndent = withKey?.range ? withKey.range.start.column - 1 : undefined;
|
||||||
|
|
||||||
|
// Calculate insert position
|
||||||
|
// For withToken, we need to handle empty mappings specially - insert after the with: line
|
||||||
|
let insertPosition: { line: number; character: number };
|
||||||
|
if (withToken?.range) {
|
||||||
|
// Check if with: has any children by comparing start and end lines
|
||||||
|
const hasChildren = stepInputs.size > 0;
|
||||||
|
if (hasChildren) {
|
||||||
|
// Insert after the last child
|
||||||
|
insertPosition = { line: withToken.range.end.line - 1, character: 0 };
|
||||||
|
} else {
|
||||||
|
// Empty with: block - insert on the next line after with:
|
||||||
|
insertPosition = { line: withKey!.range!.end.line, character: 0 };
|
||||||
|
}
|
||||||
|
} else if (stepToken.range) {
|
||||||
|
insertPosition = { line: stepToken.range.end.line - 1, character: 0 };
|
||||||
|
} else {
|
||||||
|
insertPosition = { line: 0, character: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
const diagnosticData: MissingInputsDiagnosticData = {
|
||||||
|
action,
|
||||||
|
missingInputs: missingRequiredInputs.map(([name, input]) => ({
|
||||||
|
name,
|
||||||
|
default: input.default
|
||||||
|
})),
|
||||||
|
hasWithKey: withKey !== undefined,
|
||||||
|
withIndent,
|
||||||
|
stepIndent,
|
||||||
|
insertPosition
|
||||||
|
};
|
||||||
|
|
||||||
diagnostics.push({
|
diagnostics.push({
|
||||||
severity: DiagnosticSeverity.Error,
|
severity: DiagnosticSeverity.Error,
|
||||||
range: mapRange((withKey || stepToken).range), // Highlight the whole step if we don't have a with key
|
range: mapRange((withKey || stepToken).range), // Highlight the whole step if we don't have a with key
|
||||||
message: message
|
message: message,
|
||||||
|
code: DiagnosticCode.MissingRequiredInputs,
|
||||||
|
data: diagnosticData
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -249,7 +249,28 @@ jobs:
|
|||||||
line: 7
|
line: 7
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
severity: DiagnosticSeverity.Error
|
severity: DiagnosticSeverity.Error,
|
||||||
|
code: "missing-required-inputs",
|
||||||
|
data: {
|
||||||
|
action: {
|
||||||
|
name: "cache",
|
||||||
|
owner: "actions",
|
||||||
|
ref: "v1"
|
||||||
|
},
|
||||||
|
hasWithKey: true,
|
||||||
|
insertPosition: {
|
||||||
|
character: 0,
|
||||||
|
line: 9
|
||||||
|
},
|
||||||
|
missingInputs: [
|
||||||
|
{
|
||||||
|
default: undefined,
|
||||||
|
name: "path"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
stepIndent: 6,
|
||||||
|
withIndent: 6
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
@@ -294,7 +315,32 @@ jobs:
|
|||||||
line: 7
|
line: 7
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
severity: DiagnosticSeverity.Error
|
severity: DiagnosticSeverity.Error,
|
||||||
|
code: "missing-required-inputs",
|
||||||
|
data: {
|
||||||
|
action: {
|
||||||
|
name: "cache",
|
||||||
|
owner: "actions",
|
||||||
|
ref: "v1"
|
||||||
|
},
|
||||||
|
hasWithKey: true,
|
||||||
|
insertPosition: {
|
||||||
|
character: 0,
|
||||||
|
line: 9
|
||||||
|
},
|
||||||
|
missingInputs: [
|
||||||
|
{
|
||||||
|
default: undefined,
|
||||||
|
name: "path"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default: undefined,
|
||||||
|
name: "key"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
stepIndent: 6,
|
||||||
|
withIndent: 6
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
@@ -323,7 +369,32 @@ jobs:
|
|||||||
line: 6
|
line: 6
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
severity: DiagnosticSeverity.Error
|
severity: DiagnosticSeverity.Error,
|
||||||
|
code: "missing-required-inputs",
|
||||||
|
data: {
|
||||||
|
action: {
|
||||||
|
name: "cache",
|
||||||
|
owner: "actions",
|
||||||
|
ref: "v1"
|
||||||
|
},
|
||||||
|
hasWithKey: false,
|
||||||
|
insertPosition: {
|
||||||
|
character: 0,
|
||||||
|
line: 7
|
||||||
|
},
|
||||||
|
missingInputs: [
|
||||||
|
{
|
||||||
|
default: undefined,
|
||||||
|
name: "path"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default: undefined,
|
||||||
|
name: "key"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
stepIndent: 6,
|
||||||
|
withIndent: undefined
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|||||||
Generated
+500
-37
@@ -406,10 +406,14 @@
|
|||||||
"vscode-languageserver-textdocument": "^1.0.7",
|
"vscode-languageserver-textdocument": "^1.0.7",
|
||||||
"yaml": "^2.1.3"
|
"yaml": "^2.1.3"
|
||||||
},
|
},
|
||||||
|
"bin": {
|
||||||
|
"actions-languageserver": "bin/actions-languageserver"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^29.0.3",
|
"@types/jest": "^29.0.3",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.56.0",
|
"@typescript-eslint/eslint-plugin": "^5.56.0",
|
||||||
"@typescript-eslint/parser": "^5.56.0",
|
"@typescript-eslint/parser": "^5.56.0",
|
||||||
|
"esbuild": "^0.27.1",
|
||||||
"eslint": "^8.36.0",
|
"eslint": "^8.36.0",
|
||||||
"eslint-config-prettier": "^8.8.0",
|
"eslint-config-prettier": "^8.8.0",
|
||||||
"eslint-plugin-prettier": "^4.2.1",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
@@ -475,6 +479,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.5.tgz",
|
||||||
"integrity": "sha512-vvmsN0r7rguA+FySiCsbaTTobSftpIDIpPW81trAmsv9TGxg3YCujAxRYp/Uy8xmDgYCzzgulG62H7KYUFmeIg==",
|
"integrity": "sha512-vvmsN0r7rguA+FySiCsbaTTobSftpIDIpPW81trAmsv9TGxg3YCujAxRYp/Uy8xmDgYCzzgulG62H7KYUFmeIg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/auth-token": "^5.0.0",
|
"@octokit/auth-token": "^5.0.0",
|
||||||
"@octokit/graphql": "^8.2.2",
|
"@octokit/graphql": "^8.2.2",
|
||||||
@@ -1313,6 +1318,7 @@
|
|||||||
"version": "7.20.2",
|
"version": "7.20.2",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ampproject/remapping": "^2.1.0",
|
"@ampproject/remapping": "^2.1.0",
|
||||||
"@babel/code-frame": "^7.18.6",
|
"@babel/code-frame": "^7.18.6",
|
||||||
@@ -1890,6 +1896,448 @@
|
|||||||
"tslib": "^2.4.0"
|
"tslib": "^2.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@esbuild/aix-ppc64": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-HHB50pdsBX6k47S4u5g/CaLjqS3qwaOVE5ILsq64jyzgMhLuCuZ8rGzM9yhsAjfjkbgUPMzZEPa7DAp7yz6vuA==",
|
||||||
|
"cpu": [
|
||||||
|
"ppc64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"aix"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/android-arm": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-kFqa6/UcaTbGm/NncN9kzVOODjhZW8e+FRdSeypWe6j33gzclHtwlANs26JrupOntlcWmB0u8+8HZo8s7thHvg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"android"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/android-arm64": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-45fuKmAJpxnQWixOGCrS+ro4Uvb4Re9+UTieUY2f8AEc+t7d4AaZ6eUJ3Hva7dtrxAAWHtlEFsXFMAgNnGU9uQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"android"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/android-x64": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-LBEpOz0BsgMEeHgenf5aqmn/lLNTFXVfoWMUox8CtWWYK9X4jmQzWjoGoNb8lmAYml/tQ/Ysvm8q7szu7BoxRQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"android"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/darwin-arm64": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-veg7fL8eMSCVKL7IW4pxb54QERtedFDfY/ASrumK/SbFsXnRazxY4YykN/THYqFnFwJ0aVjiUrVG2PwcdAEqQQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/darwin-x64": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-+3ELd+nTzhfWb07Vol7EZ+5PTbJ/u74nC6iv4/lwIU99Ip5uuY6QoIf0Hn4m2HoV0qcnRivN3KSqc+FyCHjoVQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/freebsd-arm64": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-/8Rfgns4XD9XOSXlzUDepG8PX+AVWHliYlUkFI3K3GB6tqbdjYqdhcb4BKRd7C0BhZSoaCxhv8kTcBrcZWP+xg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"freebsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/freebsd-x64": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-GITpD8dK9C+r+5yRT/UKVT36h/DQLOHdwGVwwoHidlnA168oD3uxA878XloXebK4Ul3gDBBIvEdL7go9gCUFzQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"freebsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-arm": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-ieMID0JRZY/ZeCrsFQ3Y3NlHNCqIhTprJfDgSB3/lv5jJZ8FX3hqPyXWhe+gvS5ARMBJ242PM+VNz/ctNj//eA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-arm64": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-W9//kCrh/6in9rWIBdKaMtuTTzNj6jSeG/haWBADqLLa9P8O5YSRDzgD5y9QBok4AYlzS6ARHifAb75V6G670Q==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-ia32": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-VIUV4z8GD8rtSVMfAj1aXFahsi/+tcoXXNYmXgzISL+KB381vbSTNdeZHHHIYqFyXcoEhu9n5cT+05tRv13rlw==",
|
||||||
|
"cpu": [
|
||||||
|
"ia32"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-loong64": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-l4rfiiJRN7sTNI//ff65zJ9z8U+k6zcCg0LALU5iEWzY+a1mVZ8iWC1k5EsNKThZ7XCQ6YWtsZ8EWYm7r1UEsg==",
|
||||||
|
"cpu": [
|
||||||
|
"loong64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-mips64el": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-U0bEuAOLvO/DWFdygTHWY8C067FXz+UbzKgxYhXC0fDieFa0kDIra1FAhsAARRJbvEyso8aAqvPdNxzWuStBnA==",
|
||||||
|
"cpu": [
|
||||||
|
"mips64el"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-ppc64": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-NzdQ/Xwu6vPSf/GkdmRNsOfIeSGnh7muundsWItmBsVpMoNPVpM61qNzAVY3pZ1glzzAxLR40UyYM23eaDDbYQ==",
|
||||||
|
"cpu": [
|
||||||
|
"ppc64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-riscv64": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-7zlw8p3IApcsN7mFw0O1Z1PyEk6PlKMu18roImfl3iQHTnr/yAfYv6s4hXPidbDoI2Q0pW+5xeoM4eTCC0UdrQ==",
|
||||||
|
"cpu": [
|
||||||
|
"riscv64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-s390x": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-cGj5wli+G+nkVQdZo3+7FDKC25Uh4ZVwOAK6A06Hsvgr8WqBBuOy/1s+PUEd/6Je+vjfm6stX0kmib5b/O2Ykw==",
|
||||||
|
"cpu": [
|
||||||
|
"s390x"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-x64": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-z3H/HYI9MM0HTv3hQZ81f+AKb+yEoCRlUby1F80vbQ5XdzEMyY/9iNlAmhqiBKw4MJXwfgsh7ERGEOhrM1niMA==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/netbsd-arm64": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-wzC24DxAvk8Em01YmVXyjl96Mr+ecTPyOuADAvjGg+fyBpGmxmcr2E5ttf7Im8D0sXZihpxzO1isus8MdjMCXQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"netbsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/netbsd-x64": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-1YQ8ybGi2yIXswu6eNzJsrYIGFpnlzEWRl6iR5gMgmsrR0FcNoV1m9k9sc3PuP5rUBLshOZylc9nqSgymI+TYg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"netbsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/openbsd-arm64": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-5Z+DzLCrq5wmU7RDaMDe2DVXMRm2tTDvX2KU14JJVBN2CT/qov7XVix85QoJqHltpvAOZUAc3ndU56HSMWrv8g==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"openbsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/openbsd-x64": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-Q73ENzIdPF5jap4wqLtsfh8YbYSZ8Q0wnxplOlZUOyZy7B4ZKW8DXGWgTCZmF8VWD7Tciwv5F4NsRf6vYlZtqg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"openbsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/openharmony-arm64": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-ajbHrGM/XiK+sXM0JzEbJAen+0E+JMQZ2l4RR4VFwvV9JEERx+oxtgkpoKv1SevhjavK2z2ReHk32pjzktWbGg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"openharmony"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/sunos-x64": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-IPUW+y4VIjuDVn+OMzHc5FV4GubIwPnsz6ubkvN8cuhEqH81NovB53IUlrlBkPMEPxvNnf79MGBoz8rZ2iW8HA==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"sunos"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/win32-arm64": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-RIVRWiljWA6CdVu8zkWcRmGP7iRRIIwvhDKem8UMBjPql2TXM5PkDVvvrzMtj1V+WFPB4K7zkIGM7VzRtFkjdg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/win32-ia32": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-2BR5M8CPbptC1AK5JbJT1fWrHLvejwZidKx3UMSF0ecHMa+smhi16drIrCEggkgviBwLYd5nwrFLSl5Kho96RQ==",
|
||||||
|
"cpu": [
|
||||||
|
"ia32"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/win32-x64": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-d5X6RMYv6taIymSk8JBP+nxv8DQAMY6A51GPgusqLdK9wBz5wWIXy1KjTck6HnjE9hqJzJRdk+1p/t5soSbCtw==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@eslint-community/eslint-utils": {
|
"node_modules/@eslint-community/eslint-utils": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.3.0.tgz",
|
||||||
@@ -2794,22 +3242,6 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@lerna/create/node_modules/typescript": {
|
|
||||||
"version": "5.8.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
|
|
||||||
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"bin": {
|
|
||||||
"tsc": "bin/tsc",
|
|
||||||
"tsserver": "bin/tsserver"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14.17"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@lerna/create/node_modules/write-file-atomic": {
|
"node_modules/@lerna/create/node_modules/write-file-atomic": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz",
|
||||||
@@ -3723,6 +4155,7 @@
|
|||||||
"integrity": "sha512-dKYCMuPO1bmrpuogcjQ8z7ICCH3FP6WmxpwC03yjzGfZhj9fTJg6+bS1+UAplekbN2C+M61UNllGOOoAfGCrdQ==",
|
"integrity": "sha512-dKYCMuPO1bmrpuogcjQ8z7ICCH3FP6WmxpwC03yjzGfZhj9fTJg6+bS1+UAplekbN2C+M61UNllGOOoAfGCrdQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/auth-token": "^4.0.0",
|
"@octokit/auth-token": "^4.0.0",
|
||||||
"@octokit/graphql": "^7.1.0",
|
"@octokit/graphql": "^7.1.0",
|
||||||
@@ -4250,6 +4683,7 @@
|
|||||||
"integrity": "sha512-sn1OZmBxUsgxMmR8a8U5QM/Wl+tyqlH//jTqCg8daTAmhAk26L2PFhcqPLlYBhYUJMZJK276qLXlHN3a83o2cg==",
|
"integrity": "sha512-sn1OZmBxUsgxMmR8a8U5QM/Wl+tyqlH//jTqCg8daTAmhAk26L2PFhcqPLlYBhYUJMZJK276qLXlHN3a83o2cg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "5.56.0",
|
"@typescript-eslint/scope-manager": "5.56.0",
|
||||||
"@typescript-eslint/types": "5.56.0",
|
"@typescript-eslint/types": "5.56.0",
|
||||||
@@ -4488,6 +4922,7 @@
|
|||||||
"version": "8.8.1",
|
"version": "8.8.1",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"acorn": "bin/acorn"
|
"acorn": "bin/acorn"
|
||||||
},
|
},
|
||||||
@@ -4911,6 +5346,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"caniuse-lite": "^1.0.30001400",
|
"caniuse-lite": "^1.0.30001400",
|
||||||
"electron-to-chromium": "^1.4.251",
|
"electron-to-chromium": "^1.4.251",
|
||||||
@@ -5931,27 +6367,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/encoding": {
|
|
||||||
"version": "0.1.13",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"dependencies": {
|
|
||||||
"iconv-lite": "^0.6.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/encoding/node_modules/iconv-lite": {
|
|
||||||
"version": "0.6.3",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"dependencies": {
|
|
||||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/end-of-stream": {
|
"node_modules/end-of-stream": {
|
||||||
"version": "1.4.4",
|
"version": "1.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||||
@@ -6060,6 +6475,48 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/esbuild": {
|
||||||
|
"version": "0.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.1.tgz",
|
||||||
|
"integrity": "sha512-yY35KZckJJuVVPXpvjgxiCuVEJT67F6zDeVTv4rizyPrfGBUpZQsvmxnN+C371c2esD/hNMjj4tpBhuueLN7aA==",
|
||||||
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"esbuild": "bin/esbuild"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@esbuild/aix-ppc64": "0.27.1",
|
||||||
|
"@esbuild/android-arm": "0.27.1",
|
||||||
|
"@esbuild/android-arm64": "0.27.1",
|
||||||
|
"@esbuild/android-x64": "0.27.1",
|
||||||
|
"@esbuild/darwin-arm64": "0.27.1",
|
||||||
|
"@esbuild/darwin-x64": "0.27.1",
|
||||||
|
"@esbuild/freebsd-arm64": "0.27.1",
|
||||||
|
"@esbuild/freebsd-x64": "0.27.1",
|
||||||
|
"@esbuild/linux-arm": "0.27.1",
|
||||||
|
"@esbuild/linux-arm64": "0.27.1",
|
||||||
|
"@esbuild/linux-ia32": "0.27.1",
|
||||||
|
"@esbuild/linux-loong64": "0.27.1",
|
||||||
|
"@esbuild/linux-mips64el": "0.27.1",
|
||||||
|
"@esbuild/linux-ppc64": "0.27.1",
|
||||||
|
"@esbuild/linux-riscv64": "0.27.1",
|
||||||
|
"@esbuild/linux-s390x": "0.27.1",
|
||||||
|
"@esbuild/linux-x64": "0.27.1",
|
||||||
|
"@esbuild/netbsd-arm64": "0.27.1",
|
||||||
|
"@esbuild/netbsd-x64": "0.27.1",
|
||||||
|
"@esbuild/openbsd-arm64": "0.27.1",
|
||||||
|
"@esbuild/openbsd-x64": "0.27.1",
|
||||||
|
"@esbuild/openharmony-arm64": "0.27.1",
|
||||||
|
"@esbuild/sunos-x64": "0.27.1",
|
||||||
|
"@esbuild/win32-arm64": "0.27.1",
|
||||||
|
"@esbuild/win32-ia32": "0.27.1",
|
||||||
|
"@esbuild/win32-x64": "0.27.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/escalade": {
|
"node_modules/escalade": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -6080,6 +6537,7 @@
|
|||||||
"version": "7.32.0",
|
"version": "7.32.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/code-frame": "7.12.11",
|
"@babel/code-frame": "7.12.11",
|
||||||
"@eslint/eslintrc": "^0.4.3",
|
"@eslint/eslintrc": "^0.4.3",
|
||||||
@@ -7950,6 +8408,7 @@
|
|||||||
"version": "29.3.1",
|
"version": "29.3.1",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jest/core": "^29.3.1",
|
"@jest/core": "^29.3.1",
|
||||||
"@jest/types": "^29.3.1",
|
"@jest/types": "^29.3.1",
|
||||||
@@ -9024,6 +9483,7 @@
|
|||||||
"integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
|
"integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
@@ -9844,6 +10304,7 @@
|
|||||||
"version": "2.6.7",
|
"version": "2.6.7",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"whatwg-url": "^5.0.0"
|
"whatwg-url": "^5.0.0"
|
||||||
},
|
},
|
||||||
@@ -10197,6 +10658,7 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@napi-rs/wasm-runtime": "0.2.4",
|
"@napi-rs/wasm-runtime": "0.2.4",
|
||||||
"@yarnpkg/lockfile": "^1.1.0",
|
"@yarnpkg/lockfile": "^1.1.0",
|
||||||
@@ -10833,6 +11295,7 @@
|
|||||||
"version": "2.8.3",
|
"version": "2.8.3",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"prettier": "bin-prettier.js"
|
"prettier": "bin-prettier.js"
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user