Merge branch 'main' into joshmgross/workflow_call-validation
This commit is contained in:
@@ -12,14 +12,15 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Use Node.js 16.x
|
- name: Use Node.js 16.15
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16.x
|
node-version: 16.15
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
registry-url: 'https://npm.pkg.github.com'
|
registry-url: 'https://npm.pkg.github.com'
|
||||||
- run: npm ci
|
- run: npm ci
|
||||||
env:
|
env:
|
||||||
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
- run: npm run format-check -ws
|
||||||
- run: npm run build -ws
|
- run: npm run build -ws
|
||||||
- run: npm test -ws
|
- run: npm test -ws
|
||||||
|
|||||||
@@ -3,3 +3,4 @@ dist
|
|||||||
*.md
|
*.md
|
||||||
*.js
|
*.js
|
||||||
*.json
|
*.json
|
||||||
|
*.d.ts
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@github/actions-expressions",
|
"name": "@github/actions-expressions",
|
||||||
"version": "0.1.100",
|
"version": "0.1.109",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"source": "./src/index.ts",
|
"source": "./src/index.ts",
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
"watch": "tsc --build tsconfig.build.json --watch"
|
"watch": "tsc --build tsconfig.build.json --watch"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 16"
|
"node": ">= 16.15"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist/**/*"
|
"dist/**/*"
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^29.0.3",
|
"@types/jest": "^29.0.3",
|
||||||
"jest": "^29.0.3",
|
"jest": "^29.0.3",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.8.3",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"ts-jest": "^29.0.3",
|
"ts-jest": "^29.0.3",
|
||||||
"typescript": "^4.7.4"
|
"typescript": "^4.7.4"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@github/actions-languageserver",
|
"name": "@github/actions-languageserver",
|
||||||
"version": "0.1.100",
|
"version": "0.1.109",
|
||||||
"description": "Language server for GitHub Actions",
|
"description": "Language server for GitHub Actions",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -38,15 +38,15 @@
|
|||||||
"watch": "tsc --build tsconfig.build.json --watch"
|
"watch": "tsc --build tsconfig.build.json --watch"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@github/actions-languageservice": "^0.1.100",
|
"@github/actions-languageservice": "^0.1.109",
|
||||||
"@github/actions-workflow-parser": "^0.1.100",
|
"@github/actions-workflow-parser": "^0.1.109",
|
||||||
"@octokit/rest": "^19.0.5",
|
"@octokit/rest": "^19.0.7",
|
||||||
"vscode-languageserver": "^8.0.2",
|
"vscode-languageserver": "^8.0.2",
|
||||||
"vscode-languageserver-textdocument": "^1.0.7",
|
"vscode-languageserver-textdocument": "^1.0.7",
|
||||||
"yaml": "^2.1.3"
|
"yaml": "^2.1.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 16"
|
"node": ">= 16.15"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist/**/*"
|
"dist/**/*"
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
"@types/jest": "^29.0.3",
|
"@types/jest": "^29.0.3",
|
||||||
"fetch-mock": "^9.11.0",
|
"fetch-mock": "^9.11.0",
|
||||||
"jest": "^29.0.3",
|
"jest": "^29.0.3",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.8.3",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"ts-jest": "^29.0.3",
|
"ts-jest": "^29.0.3",
|
||||||
"typescript": "^4.8.4"
|
"typescript": "^4.8.4"
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import {Octokit} from "@octokit/rest";
|
||||||
|
|
||||||
|
export function getClient(token: string, userAgent?: string): Octokit {
|
||||||
|
return new Octokit({
|
||||||
|
auth: token,
|
||||||
|
userAgent: userAgent || `GitHub Actions Language Server`
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -16,19 +16,20 @@ import {
|
|||||||
TextDocumentSyncKind
|
TextDocumentSyncKind
|
||||||
} from "vscode-languageserver";
|
} from "vscode-languageserver";
|
||||||
import {TextDocument} from "vscode-languageserver-textdocument";
|
import {TextDocument} from "vscode-languageserver-textdocument";
|
||||||
|
import {getClient} from "./client";
|
||||||
|
import {Commands} from "./commands";
|
||||||
import {contextProviders} from "./context-providers";
|
import {contextProviders} from "./context-providers";
|
||||||
|
import {descriptionProvider} from "./description-provider";
|
||||||
import {InitializationOptions, RepositoryContext} from "./initializationOptions";
|
import {InitializationOptions, RepositoryContext} from "./initializationOptions";
|
||||||
import {onCompletion} from "./on-completion";
|
import {onCompletion} from "./on-completion";
|
||||||
import {TTLCache} from "./utils/cache";
|
import {TTLCache} from "./utils/cache";
|
||||||
import {valueProviders} from "./value-providers";
|
import {valueProviders} from "./value-providers";
|
||||||
import {getActionInputs} from "./value-providers/action-inputs";
|
import {getActionInputs} from "./value-providers/action-inputs";
|
||||||
import {Commands} from "./commands";
|
|
||||||
import {descriptionProvider} from "./description-provider";
|
|
||||||
|
|
||||||
export function initConnection(connection: Connection) {
|
export function initConnection(connection: Connection) {
|
||||||
const documents: TextDocuments<TextDocument> = new TextDocuments(TextDocument);
|
const documents: TextDocuments<TextDocument> = new TextDocuments(TextDocument);
|
||||||
|
|
||||||
let sessionToken: string | undefined;
|
let client: Octokit | undefined;
|
||||||
let repos: RepositoryContext[] = [];
|
let repos: RepositoryContext[] = [];
|
||||||
const cache = new TTLCache();
|
const cache = new TTLCache();
|
||||||
|
|
||||||
@@ -49,7 +50,11 @@ export function initConnection(connection: Connection) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const options: InitializationOptions = params.initializationOptions;
|
const options: InitializationOptions = params.initializationOptions;
|
||||||
sessionToken = options.sessionToken;
|
|
||||||
|
if (options.sessionToken) {
|
||||||
|
client = getClient(options.sessionToken, options.userAgent);
|
||||||
|
}
|
||||||
|
|
||||||
if (options.repos) {
|
if (options.repos) {
|
||||||
repos = options.repos;
|
repos = options.repos;
|
||||||
}
|
}
|
||||||
@@ -93,15 +98,13 @@ export function initConnection(connection: Connection) {
|
|||||||
const repoContext = repos.find(repo => textDocument.uri.startsWith(repo.workspaceUri));
|
const repoContext = repos.find(repo => textDocument.uri.startsWith(repo.workspaceUri));
|
||||||
|
|
||||||
const config: ValidationConfig = {
|
const config: ValidationConfig = {
|
||||||
valueProviderConfig: valueProviders(sessionToken, repoContext, cache),
|
valueProviderConfig: valueProviders(client, repoContext, cache),
|
||||||
contextProviderConfig: contextProviders(sessionToken, repoContext, cache),
|
contextProviderConfig: contextProviders(client, repoContext, cache),
|
||||||
getActionInputs: async action => {
|
getActionInputs: async action => {
|
||||||
if (sessionToken) {
|
if (client) {
|
||||||
const octokit = new Octokit({
|
return await getActionInputs(client, cache, action);
|
||||||
auth: sessionToken
|
|
||||||
});
|
|
||||||
return await getActionInputs(octokit, cache, action);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -114,7 +117,7 @@ export function initConnection(connection: Connection) {
|
|||||||
return await onCompletion(
|
return await onCompletion(
|
||||||
position,
|
position,
|
||||||
documents.get(textDocument.uri)!,
|
documents.get(textDocument.uri)!,
|
||||||
sessionToken,
|
client,
|
||||||
repos.find(repo => textDocument.uri.startsWith(repo.workspaceUri)),
|
repos.find(repo => textDocument.uri.startsWith(repo.workspaceUri)),
|
||||||
cache
|
cache
|
||||||
);
|
);
|
||||||
@@ -122,7 +125,7 @@ export function initConnection(connection: Connection) {
|
|||||||
|
|
||||||
connection.onHover(async ({position, textDocument}: HoverParams): Promise<Hover | null> => {
|
connection.onHover(async ({position, textDocument}: HoverParams): Promise<Hover | null> => {
|
||||||
return hover(documents.get(textDocument.uri)!, position, {
|
return hover(documents.get(textDocument.uri)!, position, {
|
||||||
descriptionProvider: descriptionProvider(sessionToken, cache)
|
descriptionProvider: descriptionProvider(client, cache)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -9,18 +9,14 @@ import {RepositoryContext} from "./initializationOptions";
|
|||||||
import {TTLCache} from "./utils/cache";
|
import {TTLCache} from "./utils/cache";
|
||||||
|
|
||||||
export function contextProviders(
|
export function contextProviders(
|
||||||
sessionToken: string | undefined,
|
client: Octokit | undefined,
|
||||||
repo: RepositoryContext | undefined,
|
repo: RepositoryContext | undefined,
|
||||||
cache: TTLCache
|
cache: TTLCache
|
||||||
): ContextProviderConfig {
|
): ContextProviderConfig {
|
||||||
if (!repo || !sessionToken) {
|
if (!repo || !client) {
|
||||||
return {getContext: (_: string) => Promise.resolve(undefined)};
|
return {getContext: (_: string) => Promise.resolve(undefined)};
|
||||||
}
|
}
|
||||||
|
|
||||||
const octokit = new Octokit({
|
|
||||||
auth: sessionToken
|
|
||||||
});
|
|
||||||
|
|
||||||
const getContext = async (
|
const getContext = async (
|
||||||
name: string,
|
name: string,
|
||||||
defaultContext: DescriptionDictionary | undefined,
|
defaultContext: DescriptionDictionary | undefined,
|
||||||
@@ -28,11 +24,11 @@ export function contextProviders(
|
|||||||
) => {
|
) => {
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case "secrets":
|
case "secrets":
|
||||||
return await getSecrets(workflowContext, octokit, cache, repo, defaultContext);
|
return await getSecrets(workflowContext, client, cache, repo, defaultContext);
|
||||||
case "vars":
|
case "vars":
|
||||||
return await getVariables(workflowContext, octokit, cache, repo, defaultContext);
|
return await getVariables(workflowContext, client, cache, repo, defaultContext);
|
||||||
case "steps":
|
case "steps":
|
||||||
return await getStepsContext(octokit, cache, defaultContext, workflowContext);
|
return await getStepsContext(client, cache, defaultContext, workflowContext);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,15 @@ export async function getSecrets(
|
|||||||
}
|
}
|
||||||
>();
|
>();
|
||||||
|
|
||||||
|
secrets.orgSecrets.forEach(secret =>
|
||||||
|
secretsMap.set(secret.value.toLowerCase(), {
|
||||||
|
key: secret.value,
|
||||||
|
value: new data.StringData("***"),
|
||||||
|
description: "Organization secret"
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
// Override org secrets with repo secrets
|
||||||
secrets.repoSecrets.forEach(secret =>
|
secrets.repoSecrets.forEach(secret =>
|
||||||
secretsMap.set(secret.value.toLowerCase(), {
|
secretsMap.set(secret.value.toLowerCase(), {
|
||||||
key: secret.value,
|
key: secret.value,
|
||||||
@@ -76,6 +85,7 @@ async function getRemoteSecrets(
|
|||||||
): Promise<{
|
): Promise<{
|
||||||
repoSecrets: StringData[];
|
repoSecrets: StringData[];
|
||||||
environmentSecrets: StringData[];
|
environmentSecrets: StringData[];
|
||||||
|
orgSecrets: StringData[];
|
||||||
}> {
|
}> {
|
||||||
return {
|
return {
|
||||||
repoSecrets: await cache.get(`${repo.owner}/${repo.name}/secrets`, undefined, () =>
|
repoSecrets: await cache.get(`${repo.owner}/${repo.name}/secrets`, undefined, () =>
|
||||||
@@ -86,18 +96,22 @@ async function getRemoteSecrets(
|
|||||||
(await cache.get(`${repo.owner}/${repo.name}/secrets/environment/${environmentName}`, undefined, () =>
|
(await cache.get(`${repo.owner}/${repo.name}/secrets/environment/${environmentName}`, undefined, () =>
|
||||||
fetchEnvironmentSecrets(octokit, repo.id, environmentName)
|
fetchEnvironmentSecrets(octokit, repo.id, environmentName)
|
||||||
))) ||
|
))) ||
|
||||||
[]
|
[],
|
||||||
|
orgSecrets: await cache.get(`${repo.owner}/secrets`, undefined, () => fetchOrganizationSecrets(octokit, repo))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchSecrets(octokit: Octokit, owner: string, name: string): Promise<StringData[]> {
|
async function fetchSecrets(octokit: Octokit, owner: string, name: string): Promise<StringData[]> {
|
||||||
try {
|
try {
|
||||||
const response = await octokit.actions.listRepoSecrets({
|
return await octokit.paginate(
|
||||||
owner,
|
octokit.actions.listRepoSecrets,
|
||||||
repo: name
|
{
|
||||||
});
|
owner,
|
||||||
|
repo: name,
|
||||||
return response.data.secrets.map(secret => new StringData(secret.name));
|
per_page: 100
|
||||||
|
},
|
||||||
|
response => response.data.map(secret => new StringData(secret.name))
|
||||||
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("Failure to retrieve secrets: ", e);
|
console.log("Failure to retrieve secrets: ", e);
|
||||||
}
|
}
|
||||||
@@ -111,15 +125,37 @@ async function fetchEnvironmentSecrets(
|
|||||||
environmentName: string
|
environmentName: string
|
||||||
): Promise<StringData[]> {
|
): Promise<StringData[]> {
|
||||||
try {
|
try {
|
||||||
const response = await octokit.actions.listEnvironmentSecrets({
|
return await octokit.paginate(
|
||||||
repository_id: repositoryId,
|
octokit.actions.listEnvironmentSecrets,
|
||||||
environment_name: environmentName
|
{
|
||||||
});
|
repository_id: repositoryId,
|
||||||
|
environment_name: environmentName,
|
||||||
return response.data.secrets.map(secret => new StringData(secret.name));
|
per_page: 100
|
||||||
|
},
|
||||||
|
response => response.data.map(secret => new StringData(secret.name))
|
||||||
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("Failure to retrieve environment secrets: ", e);
|
console.log("Failure to retrieve environment secrets: ", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fetchOrganizationSecrets(octokit: Octokit, repo: RepositoryContext): Promise<StringData[]> {
|
||||||
|
if (!repo.organizationOwned) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const secrets: {name: string}[] = await octokit.paginate("GET /repos/{owner}/{repo}/actions/organization-secrets", {
|
||||||
|
owner: repo.owner,
|
||||||
|
repo: repo.name,
|
||||||
|
per_page: 100
|
||||||
|
});
|
||||||
|
return secrets.map(secret => new StringData(secret.name));
|
||||||
|
} catch (e) {
|
||||||
|
console.log("Failure to retrieve organization secrets: ", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|||||||
@@ -42,6 +42,15 @@ export async function getVariables(
|
|||||||
}
|
}
|
||||||
>();
|
>();
|
||||||
|
|
||||||
|
variables.organizationVariables.forEach(variable =>
|
||||||
|
variablesMap.set(variable.key.toLowerCase(), {
|
||||||
|
key: variable.key,
|
||||||
|
value: new data.StringData(variable.value.coerceString()),
|
||||||
|
description: `${variable.value.coerceString()} - Organization variable`
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
// Override org variables with repo variables
|
||||||
variables.repoVariables.forEach(variable =>
|
variables.repoVariables.forEach(variable =>
|
||||||
variablesMap.set(variable.key.toLowerCase(), {
|
variablesMap.set(variable.key.toLowerCase(), {
|
||||||
key: variable.key,
|
key: variable.key,
|
||||||
@@ -77,6 +86,7 @@ export async function getRemoteVariables(
|
|||||||
): Promise<{
|
): Promise<{
|
||||||
repoVariables: Pair[];
|
repoVariables: Pair[];
|
||||||
environmentVariables: Pair[];
|
environmentVariables: Pair[];
|
||||||
|
organizationVariables: Pair[];
|
||||||
}> {
|
}> {
|
||||||
// Repo variables
|
// Repo variables
|
||||||
return {
|
return {
|
||||||
@@ -88,25 +98,27 @@ export async function getRemoteVariables(
|
|||||||
(await cache.get(`${repo.owner}/${repo.name}/vars/environment/${environmentName}`, undefined, () =>
|
(await cache.get(`${repo.owner}/${repo.name}/vars/environment/${environmentName}`, undefined, () =>
|
||||||
fetchEnvironmentVariables(octokit, repo.id, environmentName)
|
fetchEnvironmentVariables(octokit, repo.id, environmentName)
|
||||||
))) ||
|
))) ||
|
||||||
[]
|
[],
|
||||||
|
organizationVariables: await cache.get(`${repo.owner}/vars`, undefined, () =>
|
||||||
|
fetchOrganizationVariables(octokit, repo)
|
||||||
|
)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchVariables(octokit: Octokit, owner: string, name: string): Promise<Pair[]> {
|
async function fetchVariables(octokit: Octokit, owner: string, name: string): Promise<Pair[]> {
|
||||||
try {
|
try {
|
||||||
const response = (await octokit.paginate("GET /repos/{owner}/{repo}/actions/variables{?per_page}", {
|
return await octokit.paginate(
|
||||||
owner: owner,
|
octokit.actions.listRepoVariables,
|
||||||
repo: name
|
{
|
||||||
})) as {
|
owner: owner,
|
||||||
name: string;
|
repo: name,
|
||||||
value: string;
|
per_page: 100
|
||||||
created_at: string;
|
},
|
||||||
updated_at: string;
|
response =>
|
||||||
}[];
|
response.data.map(variable => {
|
||||||
|
return {key: variable.name, value: new StringData(variable.value)};
|
||||||
return response.map(variable => {
|
})
|
||||||
return {key: variable.name, value: new StringData(variable.value)};
|
);
|
||||||
});
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("Failure to retrieve variables: ", e);
|
console.log("Failure to retrieve variables: ", e);
|
||||||
}
|
}
|
||||||
@@ -120,25 +132,45 @@ async function fetchEnvironmentVariables(
|
|||||||
environmentName: string
|
environmentName: string
|
||||||
): Promise<Pair[]> {
|
): Promise<Pair[]> {
|
||||||
try {
|
try {
|
||||||
const response = (await octokit.paginate(
|
return await octokit.paginate(
|
||||||
"GET /repositories/{repository_id}/environments/{environment_name}/variables{?per_page}",
|
octokit.actions.listEnvironmentVariables,
|
||||||
{
|
{
|
||||||
repository_id: repositoryId,
|
repository_id: repositoryId,
|
||||||
environment_name: environmentName
|
environment_name: environmentName,
|
||||||
}
|
per_page: 100
|
||||||
)) as {
|
},
|
||||||
name: string;
|
response =>
|
||||||
value: string;
|
response.data.map(variable => {
|
||||||
created_at: string;
|
return {key: variable.name, value: new StringData(variable.value)};
|
||||||
updated_at: string;
|
})
|
||||||
}[];
|
);
|
||||||
|
|
||||||
return response.map(variable => {
|
|
||||||
return {key: variable.name, value: new StringData(variable.value)};
|
|
||||||
});
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("Failure to retrieve environment variables: ", e);
|
console.log("Failure to retrieve environment variables: ", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fetchOrganizationVariables(octokit: Octokit, repo: RepositoryContext): Promise<Pair[]> {
|
||||||
|
if (!repo.organizationOwned) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const variables: {name: string; value: string}[] = await octokit.paginate(
|
||||||
|
"GET /repos/{owner}/{repo}/actions/organization-variables",
|
||||||
|
{
|
||||||
|
owner: repo.owner,
|
||||||
|
repo: repo.name,
|
||||||
|
per_page: 100
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return variables.map(variable => {
|
||||||
|
return {key: variable.name, value: new StringData(variable.value)};
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.log("Failure to retrieve organization variables: ", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,22 +1,17 @@
|
|||||||
import {DescriptionProvider} from "@github/actions-languageservice/hover";
|
import {DescriptionProvider} from "@github/actions-languageservice/hover";
|
||||||
import {Octokit} from "@octokit/rest";
|
import {Octokit} from "@octokit/rest";
|
||||||
import {TTLCache} from "./utils/cache";
|
|
||||||
import {getActionInputDescription} from "./description-providers/action-input";
|
import {getActionInputDescription} from "./description-providers/action-input";
|
||||||
|
import {TTLCache} from "./utils/cache";
|
||||||
|
|
||||||
export function descriptionProvider(sessionToken: string | undefined, cache: TTLCache): DescriptionProvider {
|
export function descriptionProvider(client: Octokit | undefined, cache: TTLCache): DescriptionProvider {
|
||||||
const octokit =
|
|
||||||
sessionToken &&
|
|
||||||
new Octokit({
|
|
||||||
auth: sessionToken
|
|
||||||
});
|
|
||||||
|
|
||||||
const getDescription: DescriptionProvider["getDescription"] = async (context, token, path) => {
|
const getDescription: DescriptionProvider["getDescription"] = async (context, token, path) => {
|
||||||
if (!octokit) {
|
if (!client) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const parent = path[path.length - 1];
|
const parent = path[path.length - 1];
|
||||||
if (context.step && parent.definition?.key === "step-with") {
|
if (context.step && parent.definition?.key === "step-with") {
|
||||||
return await getActionInputDescription(octokit, cache, context.step, token);
|
return await getActionInputDescription(client, cache, context.step, token);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,11 @@ export interface InitializationOptions {
|
|||||||
*/
|
*/
|
||||||
sessionToken?: string;
|
sessionToken?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional user agent to use when making calls to github.com
|
||||||
|
*/
|
||||||
|
userAgent?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of repositories that the language server should be aware of
|
* List of repositories that the language server should be aware of
|
||||||
*/
|
*/
|
||||||
@@ -31,6 +36,11 @@ export interface RepositoryContext {
|
|||||||
*/
|
*/
|
||||||
owner: string;
|
owner: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if the repository is owned by an organization
|
||||||
|
*/
|
||||||
|
organizationOwned: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Repository name
|
* Repository name
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import {complete} from "@github/actions-languageservice/complete";
|
import {complete} from "@github/actions-languageservice/complete";
|
||||||
|
import {Octokit} from "@octokit/rest";
|
||||||
import {CompletionItem, Position} from "vscode-languageserver";
|
import {CompletionItem, Position} from "vscode-languageserver";
|
||||||
import {TextDocument} from "vscode-languageserver-textdocument";
|
import {TextDocument} from "vscode-languageserver-textdocument";
|
||||||
import {contextProviders} from "./context-providers";
|
import {contextProviders} from "./context-providers";
|
||||||
@@ -9,14 +10,14 @@ import {valueProviders} from "./value-providers";
|
|||||||
export async function onCompletion(
|
export async function onCompletion(
|
||||||
position: Position,
|
position: Position,
|
||||||
document: TextDocument,
|
document: TextDocument,
|
||||||
sessionToken: string | undefined,
|
client: Octokit | undefined,
|
||||||
repoContext: RepositoryContext | undefined,
|
repoContext: RepositoryContext | undefined,
|
||||||
cache: TTLCache
|
cache: TTLCache
|
||||||
): Promise<CompletionItem[]> {
|
): Promise<CompletionItem[]> {
|
||||||
return await complete(
|
return await complete(
|
||||||
document,
|
document,
|
||||||
position,
|
position,
|
||||||
repoContext && valueProviders(sessionToken, repoContext, cache),
|
repoContext && valueProviders(client, repoContext, cache),
|
||||||
repoContext && contextProviders(sessionToken, repoContext, cache)
|
repoContext && contextProviders(client, repoContext, cache)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,34 +9,30 @@ import {getEnvironments} from "./value-providers/job-environment";
|
|||||||
import {getRunnerLabels} from "./value-providers/runs-on";
|
import {getRunnerLabels} from "./value-providers/runs-on";
|
||||||
|
|
||||||
export function valueProviders(
|
export function valueProviders(
|
||||||
sessionToken: string | undefined,
|
client: Octokit | undefined,
|
||||||
repo: RepositoryContext | undefined,
|
repo: RepositoryContext | undefined,
|
||||||
cache: TTLCache
|
cache: TTLCache
|
||||||
): ValueProviderConfig {
|
): ValueProviderConfig {
|
||||||
if (!repo || !sessionToken) {
|
if (!repo || !client) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const octokit = new Octokit({
|
|
||||||
auth: sessionToken
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"job-environment": {
|
"job-environment": {
|
||||||
kind: ValueProviderKind.AllowedValues,
|
kind: ValueProviderKind.AllowedValues,
|
||||||
get: (_: WorkflowContext) => getEnvironments(octokit, cache, repo.owner, repo.name)
|
get: (_: WorkflowContext) => getEnvironments(client, cache, repo.owner, repo.name)
|
||||||
},
|
},
|
||||||
"job-environment-name": {
|
"job-environment-name": {
|
||||||
kind: ValueProviderKind.AllowedValues,
|
kind: ValueProviderKind.AllowedValues,
|
||||||
get: (_: WorkflowContext) => getEnvironments(octokit, cache, repo.owner, repo.name)
|
get: (_: WorkflowContext) => getEnvironments(client, cache, repo.owner, repo.name)
|
||||||
},
|
},
|
||||||
"runs-on": {
|
"runs-on": {
|
||||||
kind: ValueProviderKind.SuggestedValues,
|
kind: ValueProviderKind.SuggestedValues,
|
||||||
get: (_: WorkflowContext) => getRunnerLabels(octokit, cache, repo.owner, repo.name)
|
get: (_: WorkflowContext) => getRunnerLabels(client, cache, repo.owner, repo.name)
|
||||||
},
|
},
|
||||||
"step-with": {
|
"step-with": {
|
||||||
kind: ValueProviderKind.AllowedValues,
|
kind: ValueProviderKind.AllowedValues,
|
||||||
get: (context: WorkflowContext) => getActionInputValues(octokit, cache, context)
|
get: (context: WorkflowContext) => getActionInputValues(client, cache, context)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import {Value} from "@github/actions-languageservice/value-providers/config";
|
|||||||
import {Octokit} from "@octokit/rest";
|
import {Octokit} from "@octokit/rest";
|
||||||
import {TTLCache} from "../utils/cache";
|
import {TTLCache} from "../utils/cache";
|
||||||
|
|
||||||
|
// Limitation: getRunnerLabels returns default hosted labels and labels for repository self-hosted runners.
|
||||||
|
// It doesn't return labels for organization runners visible to the repository.
|
||||||
export async function getRunnerLabels(client: Octokit, cache: TTLCache, owner: string, name: string): Promise<Value[]> {
|
export async function getRunnerLabels(client: Octokit, cache: TTLCache, owner: string, name: string): Promise<Value[]> {
|
||||||
const defaultLabels = [
|
const defaultLabels = [
|
||||||
"ubuntu-latest",
|
"ubuntu-latest",
|
||||||
@@ -33,14 +35,17 @@ export async function getRunnerLabels(client: Octokit, cache: TTLCache, owner: s
|
|||||||
async function fetchRunnerLabels(client: Octokit, owner: string, name: string): Promise<Set<string>> {
|
async function fetchRunnerLabels(client: Octokit, owner: string, name: string): Promise<Set<string>> {
|
||||||
const labels = new Set<string>();
|
const labels = new Set<string>();
|
||||||
try {
|
try {
|
||||||
const response = await client.actions.listSelfHostedRunnersForRepo({
|
const itor = client.paginate.iterator(client.actions.listSelfHostedRunnersForRepo, {
|
||||||
owner,
|
owner,
|
||||||
repo: name
|
repo: name,
|
||||||
|
per_page: 100
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const runner of response.data.runners) {
|
for await (const response of itor) {
|
||||||
for (const label of runner.labels) {
|
for (const runner of response.data) {
|
||||||
labels.add(label.name);
|
for (const label of runner.labels) {
|
||||||
|
labels.add(label.name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -8,7 +8,8 @@
|
|||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"lib": ["es6", "webworker"]
|
"lib": ["es6", "webworker"],
|
||||||
|
"resolveJsonModule": true
|
||||||
},
|
},
|
||||||
"watchOptions": {
|
"watchOptions": {
|
||||||
"watchFile": "useFsEvents",
|
"watchFile": "useFsEvents",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@github/actions-languageservice",
|
"name": "@github/actions-languageservice",
|
||||||
"version": "0.1.100",
|
"version": "0.1.109",
|
||||||
"description": "Language service for GitHub Actions",
|
"description": "Language service for GitHub Actions",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -38,14 +38,14 @@
|
|||||||
"watch": "tsc --build tsconfig.build.json --watch"
|
"watch": "tsc --build tsconfig.build.json --watch"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@github/actions-expressions": "^0.1.100",
|
"@github/actions-expressions": "^0.1.109",
|
||||||
"@github/actions-workflow-parser": "^0.1.100",
|
"@github/actions-workflow-parser": "^0.1.109",
|
||||||
"vscode-languageserver-textdocument": "^1.0.7",
|
"vscode-languageserver-textdocument": "^1.0.7",
|
||||||
"vscode-languageserver-types": "^3.17.2",
|
"vscode-languageserver-types": "^3.17.2",
|
||||||
"yaml": "^2.1.1"
|
"yaml": "^2.1.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 16"
|
"node": ">= 16.15"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist/**/*"
|
"dist/**/*"
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^29.0.3",
|
"@types/jest": "^29.0.3",
|
||||||
"jest": "^29.0.3",
|
"jest": "^29.0.3",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.8.3",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"ts-jest": "^29.0.3",
|
"ts-jest": "^29.0.3",
|
||||||
"typescript": "^4.8.4"
|
"typescript": "^4.8.4"
|
||||||
|
|||||||
@@ -255,6 +255,13 @@ jobs:
|
|||||||
expect(result.map(x => x.label)).toEqual(["event"]);
|
expect(result.map(x => x.label)).toEqual(["event"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("auto-complete partial", async () => {
|
||||||
|
const input = "run-name: ${{ github.ev| }}";
|
||||||
|
const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig);
|
||||||
|
|
||||||
|
expect(result.map(x => x.label)).toEqual(["event"]);
|
||||||
|
});
|
||||||
|
|
||||||
it("using default context provider", async () => {
|
it("using default context provider", async () => {
|
||||||
const input =
|
const input =
|
||||||
"on: push\njobs:\n build:\n runs-on: ubuntu-latest\n environment:\n url: ${{ runner.| }}\n steps:\n - run: echo";
|
"on: push\njobs:\n build:\n runs-on: ubuntu-latest\n environment:\n url: ${{ runner.| }}\n steps:\n - run: echo";
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
import {complete as completeExpression} from "@github/actions-expressions";
|
import {DescriptionDictionary, complete as completeExpression} from "@github/actions-expressions";
|
||||||
import {CompletionItem as ExpressionCompletionItem} from "@github/actions-expressions/completion";
|
import {CompletionItem as ExpressionCompletionItem} from "@github/actions-expressions/completion";
|
||||||
import {convertWorkflowTemplate, isSequence, isString, parseWorkflow} from "@github/actions-workflow-parser";
|
import {
|
||||||
|
convertWorkflowTemplate,
|
||||||
|
isBasicExpression,
|
||||||
|
isSequence,
|
||||||
|
isString,
|
||||||
|
parseWorkflow
|
||||||
|
} from "@github/actions-workflow-parser";
|
||||||
import {ErrorPolicy} from "@github/actions-workflow-parser/model/convert";
|
import {ErrorPolicy} from "@github/actions-workflow-parser/model/convert";
|
||||||
import {DefinitionType} from "@github/actions-workflow-parser/templates/schema/definition-type";
|
import {DefinitionType} from "@github/actions-workflow-parser/templates/schema/definition-type";
|
||||||
import {StringDefinition} from "@github/actions-workflow-parser/templates/schema/string-definition";
|
import {StringDefinition} from "@github/actions-workflow-parser/templates/schema/string-definition";
|
||||||
@@ -24,6 +30,7 @@ import {transform} from "./utils/transform";
|
|||||||
import {Value, ValueProviderConfig} from "./value-providers/config";
|
import {Value, ValueProviderConfig} from "./value-providers/config";
|
||||||
import {defaultValueProviders} from "./value-providers/default";
|
import {defaultValueProviders} from "./value-providers/default";
|
||||||
import {definitionValues} from "./value-providers/definition";
|
import {definitionValues} from "./value-providers/definition";
|
||||||
|
import {TokenRange} from "@github/actions-workflow-parser/templates/tokens/token-range";
|
||||||
|
|
||||||
export function getExpressionInput(input: string, pos: number): string {
|
export function getExpressionInput(input: string, pos: number): string {
|
||||||
// Find start marker around the cursor position
|
// Find start marker around the cursor position
|
||||||
@@ -71,37 +78,14 @@ export async function complete(
|
|||||||
// If we are inside an expression, take a different code-path. The workflow parser does not correctly create
|
// If we are inside an expression, take a different code-path. The workflow parser does not correctly create
|
||||||
// expression nodes for invalid expressions and during editing expressions are invalid most of the time.
|
// expression nodes for invalid expressions and during editing expressions are invalid most of the time.
|
||||||
if (token) {
|
if (token) {
|
||||||
const isExpression =
|
const isStringExpressionToken = isStringExpression(token);
|
||||||
token.definition?.definitionType === DefinitionType.String && (token.definition as StringDefinition).isExpression;
|
const isBasicExpressionToken = isBasicExpression(token) && token.isExpression;
|
||||||
const containsExpression = isString(token) && token.value.indexOf(OPEN_EXPRESSION) >= 0;
|
|
||||||
if (isString(token) && (isExpression || containsExpression)) {
|
|
||||||
const currentInput = token.source || token.value;
|
|
||||||
|
|
||||||
// Transform the overall position into a node relative position
|
|
||||||
let relCharPos: number = 0;
|
|
||||||
const range = mapRange(token.range!);
|
|
||||||
if (range.start.line !== range.end.line) {
|
|
||||||
const lines = currentInput.split("\n");
|
|
||||||
const lineDiff = newPos.line - range.start.line - 1;
|
|
||||||
const linesBeforeCusor = lines.slice(0, lineDiff);
|
|
||||||
relCharPos = linesBeforeCusor.join("\n").length + newPos.character + 1;
|
|
||||||
} else {
|
|
||||||
relCharPos = newPos.character - range.start.character;
|
|
||||||
}
|
|
||||||
|
|
||||||
const expressionInput = (getExpressionInput(currentInput, relCharPos) || "").trim();
|
|
||||||
|
|
||||||
|
if (isStringExpressionToken || isBasicExpressionToken) {
|
||||||
const allowedContext = token.definitionInfo?.allowedContext || [];
|
const allowedContext = token.definitionInfo?.allowedContext || [];
|
||||||
const context = await getContext(allowedContext, contextProviderConfig, workflowContext, Mode.Completion);
|
const context = await getContext(allowedContext, contextProviderConfig, workflowContext, Mode.Completion);
|
||||||
|
|
||||||
try {
|
return getExpressionCompletionItems(token, context, newPos);
|
||||||
return completeExpression(expressionInput, context, [], validatorFunctions).map(item =>
|
|
||||||
mapExpressionCompletionItem(item, currentInput[relCharPos])
|
|
||||||
);
|
|
||||||
} catch (e: any) {
|
|
||||||
error(`Error while completing expression: '${e?.message || "<no details>"}'`);
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,6 +200,35 @@ export function getExistingValues(token: TemplateToken | null, parent: TemplateT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getExpressionCompletionItems(
|
||||||
|
token: TemplateToken,
|
||||||
|
context: DescriptionDictionary,
|
||||||
|
pos: Position
|
||||||
|
): CompletionItem[] {
|
||||||
|
let expressionInput = "";
|
||||||
|
let currentInput = "";
|
||||||
|
let relCharPos: number = 0;
|
||||||
|
|
||||||
|
if (isBasicExpression(token)) {
|
||||||
|
expressionInput = currentInput = token.expression;
|
||||||
|
relCharPos = getRelCharPos(token.range!, expressionInput, pos);
|
||||||
|
} else {
|
||||||
|
const stringToken = token.assertString("Expected string token for expression completion");
|
||||||
|
currentInput = stringToken.source || stringToken.value;
|
||||||
|
relCharPos = getRelCharPos(stringToken.range!, currentInput, pos);
|
||||||
|
expressionInput = (getExpressionInput(currentInput, relCharPos) || "").trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return completeExpression(expressionInput, context, [], validatorFunctions).map(item =>
|
||||||
|
mapExpressionCompletionItem(item, currentInput[relCharPos])
|
||||||
|
);
|
||||||
|
} catch (e: any) {
|
||||||
|
error(`Error while completing expression: '${e?.message || "<no details>"}'`);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function filterAndSortCompletionOptions(options: Value[], existingValues?: Set<string>) {
|
function filterAndSortCompletionOptions(options: Value[], existingValues?: Set<string>) {
|
||||||
options = options.filter(x => !existingValues?.has(x.label));
|
options = options.filter(x => !existingValues?.has(x.label));
|
||||||
options.sort((a, b) => a.label.localeCompare(b.label));
|
options.sort((a, b) => a.label.localeCompare(b.label));
|
||||||
@@ -239,3 +252,23 @@ function mapExpressionCompletionItem(item: ExpressionCompletionItem, charAfterPo
|
|||||||
kind: item.function ? CompletionItemKind.Function : CompletionItemKind.Variable
|
kind: item.function ? CompletionItemKind.Function : CompletionItemKind.Variable
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getRelCharPos(tokenRange: TokenRange, currentInput: string, pos: Position): number {
|
||||||
|
// Transform the overall position into a node relative position
|
||||||
|
const range = mapRange(tokenRange);
|
||||||
|
if (range.start.line !== range.end.line) {
|
||||||
|
const lines = currentInput.split("\n");
|
||||||
|
const lineDiff = pos.line - range.start.line - 1;
|
||||||
|
const linesBeforeCusor = lines.slice(0, lineDiff);
|
||||||
|
return linesBeforeCusor.join("\n").length + pos.character + 1;
|
||||||
|
} else {
|
||||||
|
return pos.character - range.start.character;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isStringExpression(token: TemplateToken): boolean {
|
||||||
|
const isExpression =
|
||||||
|
token.definition?.definitionType === DefinitionType.String && (token.definition as StringDefinition).isExpression;
|
||||||
|
const containsExpression = isString(token) && token.value.indexOf(OPEN_EXPRESSION) >= 0;
|
||||||
|
return isExpression || containsExpression;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import descriptions from "./descriptions.json";
|
import descriptions from "./descriptions.json" assert {type: "json"};
|
||||||
|
|
||||||
export const RootContext = "root";
|
export const RootContext = "root";
|
||||||
|
|
||||||
|
|||||||
@@ -1,55 +1,55 @@
|
|||||||
import check_run from "./check_run.json";
|
import check_run from "./check_run.json" assert {type: "json"};
|
||||||
import check_suite from "./check_suite.json";
|
import check_suite from "./check_suite.json" assert {type: "json"};
|
||||||
import commit_comment from "./commit_comment.json";
|
import commit_comment from "./commit_comment.json" assert {type: "json"};
|
||||||
import content_reference from "./content_reference.json";
|
import content_reference from "./content_reference.json" assert {type: "json"};
|
||||||
import create from "./create.json";
|
import create from "./create.json" assert {type: "json"};
|
||||||
import deletePayload from "./delete.json";
|
import deletePayload from "./delete.json" assert {type: "json"};
|
||||||
import deploy_key from "./deploy_key.json";
|
import deploy_key from "./deploy_key.json" assert {type: "json"};
|
||||||
import deployment from "./deployment.json";
|
import deployment from "./deployment.json" assert {type: "json"};
|
||||||
import deployment_status from "./deployment_status.json";
|
import deployment_status from "./deployment_status.json" assert {type: "json"};
|
||||||
import fork from "./fork.json";
|
import fork from "./fork.json" assert {type: "json"};
|
||||||
import github_app_authorization from "./github_app_authorization.json";
|
import github_app_authorization from "./github_app_authorization.json" assert {type: "json"};
|
||||||
import gollum from "./gollum.json";
|
import gollum from "./gollum.json" assert {type: "json"};
|
||||||
import installation from "./installation.json";
|
import installation from "./installation.json" assert {type: "json"};
|
||||||
import installation_repositories from "./installation_repositories.json";
|
import installation_repositories from "./installation_repositories.json" assert {type: "json"};
|
||||||
import issue_comment from "./issue_comment.json";
|
import issue_comment from "./issue_comment.json" assert {type: "json"};
|
||||||
import issues from "./issues.json";
|
import issues from "./issues.json" assert {type: "json"};
|
||||||
import label from "./label.json";
|
import label from "./label.json" assert {type: "json"};
|
||||||
import marketplace_purchase from "./marketplace_purchase.json";
|
import marketplace_purchase from "./marketplace_purchase.json" assert {type: "json"};
|
||||||
import member from "./member.json";
|
import member from "./member.json" assert {type: "json"};
|
||||||
import membership from "./membership.json";
|
import membership from "./membership.json" assert {type: "json"};
|
||||||
import merge_group from "./merge_group.json";
|
import merge_group from "./merge_group.json" assert {type: "json"};
|
||||||
import meta from "./meta.json";
|
import meta from "./meta.json" assert {type: "json"};
|
||||||
import milestone from "./milestone.json";
|
import milestone from "./milestone.json" assert {type: "json"};
|
||||||
import org_block from "./org_block.json";
|
import org_block from "./org_block.json" assert {type: "json"};
|
||||||
import organization from "./organization.json";
|
import organization from "./organization.json" assert {type: "json"};
|
||||||
import packagePayload from "./package_payload.json";
|
import packagePayload from "./package_payload.json" assert {type: "json"};
|
||||||
import page_build from "./page_build.json";
|
import page_build from "./page_build.json" assert {type: "json"};
|
||||||
import ping from "./ping.json";
|
import ping from "./ping.json" assert {type: "json"};
|
||||||
import project from "./project.json";
|
import project from "./project.json" assert {type: "json"};
|
||||||
import project_card from "./project_card.json";
|
import project_card from "./project_card.json" assert {type: "json"};
|
||||||
import project_column from "./project_column.json";
|
import project_column from "./project_column.json" assert {type: "json"};
|
||||||
import publicPayload from "./public.json";
|
import publicPayload from "./public.json" assert {type: "json"};
|
||||||
import pull_request from "./pull_request.json";
|
import pull_request from "./pull_request.json" assert {type: "json"};
|
||||||
import pull_request_review from "./pull_request_review.json";
|
import pull_request_review from "./pull_request_review.json" assert {type: "json"};
|
||||||
import pull_request_review_comment from "./pull_request_review_comment.json";
|
import pull_request_review_comment from "./pull_request_review_comment.json" assert {type: "json"};
|
||||||
import push from "./push.json";
|
import push from "./push.json" assert {type: "json"};
|
||||||
import release from "./release.json";
|
import release from "./release.json" assert {type: "json"};
|
||||||
import repository from "./repository.json";
|
import repository from "./repository.json" assert {type: "json"};
|
||||||
import repository_dispatch from "./repository_dispatch.json";
|
import repository_dispatch from "./repository_dispatch.json" assert {type: "json"};
|
||||||
import repository_import from "./repository_import.json";
|
import repository_import from "./repository_import.json" assert {type: "json"};
|
||||||
import repository_vulnerability_alert from "./repository_vulnerability_alert.json";
|
import repository_vulnerability_alert from "./repository_vulnerability_alert.json" assert {type: "json"};
|
||||||
import schedule from "./schedule.json";
|
import schedule from "./schedule.json" assert {type: "json"};
|
||||||
import security_advisory from "./security_advisory.json";
|
import security_advisory from "./security_advisory.json" assert {type: "json"};
|
||||||
import sponsorship from "./sponsorship.json";
|
import sponsorship from "./sponsorship.json" assert {type: "json"};
|
||||||
import star from "./star.json";
|
import star from "./star.json" assert {type: "json"};
|
||||||
import status from "./status.json";
|
import status from "./status.json" assert {type: "json"};
|
||||||
import team from "./team.json";
|
import team from "./team.json" assert {type: "json"};
|
||||||
import team_add from "./team_add.json";
|
import team_add from "./team_add.json" assert {type: "json"};
|
||||||
import watch from "./watch.json";
|
import watch from "./watch.json" assert {type: "json"};
|
||||||
import workflow_call from "./workflow_call.json";
|
import workflow_call from "./workflow_call.json" assert {type: "json"};
|
||||||
import workflow_dispatch from "./workflow_dispatch.json";
|
import workflow_dispatch from "./workflow_dispatch.json" assert {type: "json"};
|
||||||
import workflow_run from "./workflow_run.json";
|
import workflow_run from "./workflow_run.json" assert {type: "json"};
|
||||||
|
|
||||||
export const eventPayloads: {[key: string]: Object} = {
|
export const eventPayloads: {[key: string]: Object} = {
|
||||||
check_run,
|
check_run,
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ function testHoverConfig(tokenValue: string, tokenKey: string, description?: str
|
|||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
} satisfies DescriptionProvider
|
} satisfies DescriptionProvider
|
||||||
} satisfies HoverConfig
|
} satisfies HoverConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("hover", () => {
|
describe("hover", () => {
|
||||||
@@ -146,7 +146,8 @@ jobs:
|
|||||||
expect(result).not.toBeUndefined();
|
expect(result).not.toBeUndefined();
|
||||||
|
|
||||||
// The `ref` is a `string` definition and inherits the context from `step-with`
|
// The `ref` is a `string` definition and inherits the context from `step-with`
|
||||||
const expected = "**Context:** github, inputs, vars, needs, strategy, matrix, secrets, steps, job, runner, env, hashFiles(1,255)"
|
const expected =
|
||||||
|
"**Context:** github, inputs, vars, needs, strategy, matrix, secrets, steps, job, runner, env, hashFiles(1,255)";
|
||||||
expect(result?.contents).toEqual(expected);
|
expect(result?.contents).toEqual(expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -164,11 +165,15 @@ jobs:
|
|||||||
ref|: main
|
ref|: main
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const result = await hover(...getPositionFromCursor(input), testHoverConfig("ref", "string", "The branch, tag or SHA to checkout."));
|
const result = await hover(
|
||||||
|
...getPositionFromCursor(input),
|
||||||
|
testHoverConfig("ref", "string", "The branch, tag or SHA to checkout.")
|
||||||
|
);
|
||||||
expect(result).not.toBeUndefined();
|
expect(result).not.toBeUndefined();
|
||||||
|
|
||||||
const expected = "The branch, tag or SHA to checkout.\n\n" +
|
const expected =
|
||||||
"**Context:** github, inputs, vars, needs, strategy, matrix, secrets, steps, job, runner, env, hashFiles(1,255)"
|
"The branch, tag or SHA to checkout.\n\n" +
|
||||||
|
"**Context:** github, inputs, vars, needs, strategy, matrix, secrets, steps, job, runner, env, hashFiles(1,255)";
|
||||||
expect(result?.contents).toEqual(expected);
|
expect(result?.contents).toEqual(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -184,6 +189,8 @@ jobs:
|
|||||||
|
|
||||||
const result = await hover(...getPositionFromCursor(input), testHoverConfig("uses", "non-empty-string", undefined));
|
const result = await hover(...getPositionFromCursor(input), testHoverConfig("uses", "non-empty-string", undefined));
|
||||||
expect(result).not.toBeUndefined();
|
expect(result).not.toBeUndefined();
|
||||||
expect(result?.contents).toEqual("Selects an action to run as part of a step in your job. An action is a reusable unit of code. You can use an action defined in the same repository as the workflow, a public repository, or in a published Docker container image.");
|
expect(result?.contents).toEqual(
|
||||||
|
"Selects an action to run as part of a step in your job. An action is a reusable unit of code. You can use an action defined in the same repository as the workflow, a public repository, or in a published Docker container image."
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export async function hover(document: TextDocument, position: Position, config?:
|
|||||||
info(`Calculating hover for token with definition ${token.definition.key}`);
|
info(`Calculating hover for token with definition ${token.definition.key}`);
|
||||||
|
|
||||||
if (tokenResult.parent && isCronMappingValue(tokenResult)) {
|
if (tokenResult.parent && isCronMappingValue(tokenResult)) {
|
||||||
const tokenValue = (token as StringToken).value
|
const tokenValue = (token as StringToken).value;
|
||||||
let description = getCronDescription(tokenValue);
|
let description = getCronDescription(tokenValue);
|
||||||
if (description) {
|
if (description) {
|
||||||
return {
|
return {
|
||||||
@@ -82,7 +82,9 @@ async function getDescription(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isCronMappingValue(tokenResult: TokenResult): boolean {
|
function isCronMappingValue(tokenResult: TokenResult): boolean {
|
||||||
return tokenResult.parent?.definition?.key === "cron-mapping" &&
|
return (
|
||||||
|
tokenResult.parent?.definition?.key === "cron-mapping" &&
|
||||||
isString(tokenResult.token!) &&
|
isString(tokenResult.token!) &&
|
||||||
tokenResult.token.value !== "cron"
|
tokenResult.token.value !== "cron"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,13 +141,16 @@ function posInToken(pos: Position, token: TemplateToken): boolean {
|
|||||||
const tokenChar = pos.character + 1;
|
const tokenChar = pos.character + 1;
|
||||||
|
|
||||||
// Check lines
|
// Check lines
|
||||||
if (r.start[0] > tokenLine || tokenLine > r.end[0]) {
|
if (r.start.line > tokenLine || tokenLine > r.end.line) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Position is within the token lines. Check character/column if pos line matches
|
// Position is within the token lines. Check character/column if pos line matches
|
||||||
// start or end
|
// start or end
|
||||||
if ((r.start[0] === tokenLine && tokenChar < r.start[1]) || (r.end[0] === tokenLine && tokenChar > r.end[1])) {
|
if (
|
||||||
|
(r.start.line === tokenLine && tokenChar < r.start.column) ||
|
||||||
|
(r.end.line === tokenLine && tokenChar > r.end.column)
|
||||||
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,14 +166,14 @@ function onSameLine(pos: Position, key: TemplateToken, value: TemplateToken): bo
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value.range.start[0] !== value.range.end[0]) {
|
if (value.range.start.line !== value.range.end.line) {
|
||||||
// Token occupies multiple lines, can't be an empty node
|
// Token occupies multiple lines, can't be an empty node
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TokenRange is one-based, Position is zero-based
|
// TokenRange is one-based, Position is zero-based
|
||||||
const posLine = pos.line + 1;
|
const posLine = pos.line + 1;
|
||||||
if (posLine != value.range.start[0]) {
|
if (posLine != value.range.start.line) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export function mapRange(range: TokenRange | undefined): Range {
|
|||||||
|
|
||||||
export function mapPosition(position: TokenPosition): Position {
|
export function mapPosition(position: TokenPosition): Position {
|
||||||
return {
|
return {
|
||||||
line: position[0] - 1,
|
line: position.line - 1,
|
||||||
character: position[1] - 1
|
character: position.column - 1
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,21 +73,7 @@ jobs:
|
|||||||
{valueProviderConfig: defaultValueProviders}
|
{valueProviderConfig: defaultValueProviders}
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(result.length).toBe(1);
|
expect(result.length).toBe(0);
|
||||||
expect(result[0]).toEqual({
|
|
||||||
message: "Value 'does-not-exist' might not be valid",
|
|
||||||
severity: DiagnosticSeverity.Warning,
|
|
||||||
range: {
|
|
||||||
end: {
|
|
||||||
character: 27,
|
|
||||||
line: 3
|
|
||||||
},
|
|
||||||
start: {
|
|
||||||
character: 13,
|
|
||||||
line: 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} as Diagnostic);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("value in sequence not returned by value provider", async () => {
|
it("value in sequence not returned by value provider", async () => {
|
||||||
@@ -106,21 +92,7 @@ jobs:
|
|||||||
{valueProviderConfig: defaultValueProviders}
|
{valueProviderConfig: defaultValueProviders}
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(result.length).toBe(1);
|
expect(result.length).toBe(0);
|
||||||
expect(result[0]).toEqual({
|
|
||||||
message: "Value 'does-not-exist' might not be valid",
|
|
||||||
severity: DiagnosticSeverity.Warning,
|
|
||||||
range: {
|
|
||||||
end: {
|
|
||||||
character: 20,
|
|
||||||
line: 5
|
|
||||||
},
|
|
||||||
start: {
|
|
||||||
character: 6,
|
|
||||||
line: 5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} as Diagnostic);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("single value not returned by allowed value provider", async () => {
|
it("single value not returned by allowed value provider", async () => {
|
||||||
|
|||||||
@@ -150,13 +150,7 @@ function invalidValue(diagnostics: Diagnostic[], token: StringToken, kind: Value
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ValueProviderKind.SuggestedValues:
|
// no messages for SuggestedValues
|
||||||
diagnostics.push({
|
|
||||||
message: `Value '${token.value}' might not be valid`,
|
|
||||||
severity: DiagnosticSeverity.Warning,
|
|
||||||
range: mapRange(token.range)
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,8 +162,8 @@ function getProviderContext(
|
|||||||
): WorkflowContext {
|
): WorkflowContext {
|
||||||
const {parent, path} = findToken(
|
const {parent, path} = findToken(
|
||||||
{
|
{
|
||||||
line: token.range!.start[0] - 1,
|
line: token.range!.start.line - 1,
|
||||||
character: token.range!.start[1] - 1
|
character: token.range!.start.column - 1
|
||||||
},
|
},
|
||||||
root
|
root
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@github/actions-workflow-parser",
|
"name": "@github/actions-workflow-parser",
|
||||||
"version": "0.1.100",
|
"version": "0.1.109",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"source": "./src/index.ts",
|
"source": "./src/index.ts",
|
||||||
@@ -40,12 +40,12 @@
|
|||||||
"watch": "tsc --build tsconfig.build.json --watch"
|
"watch": "tsc --build tsconfig.build.json --watch"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@github/actions-expressions": "^0.1.100",
|
"@github/actions-expressions": "^0.1.109",
|
||||||
"cronstrue": "^2.21.0",
|
"cronstrue": "^2.21.0",
|
||||||
"yaml": "^2.0.0-8"
|
"yaml": "^2.0.0-8"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 16"
|
"node": ">= 16.15"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist/**/*"
|
"dist/**/*"
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
"@typescript-eslint/parser": "^5.40.0",
|
"@typescript-eslint/parser": "^5.40.0",
|
||||||
"eslint": "7.32.0",
|
"eslint": "7.32.0",
|
||||||
"jest": "^29.0.3",
|
"jest": "^29.0.3",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.8.3",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"ts-jest": "^29.0.3",
|
"ts-jest": "^29.0.3",
|
||||||
"typescript": "^4.8.4"
|
"typescript": "^4.8.4"
|
||||||
|
|||||||
@@ -85,15 +85,15 @@ jobs:
|
|||||||
[
|
[
|
||||||
"${{ github.event_name }}",
|
"${{ github.event_name }}",
|
||||||
{
|
{
|
||||||
start: [7, 16],
|
start: {line: 7, column: 16},
|
||||||
end: [7, 40]
|
end: {line: 7, column: 40}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"${{ github.ref }}",
|
"${{ github.ref }}",
|
||||||
{
|
{
|
||||||
start: [8, 24],
|
start: {line: 8, column: 24},
|
||||||
end: [8, 41]
|
end: {line: 8, column: 41}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
@@ -160,16 +160,16 @@ jobs:
|
|||||||
{
|
{
|
||||||
prefix: "test.yaml (Line: 6, Col: 14)",
|
prefix: "test.yaml (Line: 6, Col: 14)",
|
||||||
range: {
|
range: {
|
||||||
start: [7, 16],
|
start: {line: 7, column: 16},
|
||||||
end: [7, 40]
|
end: {line: 7, column: 40}
|
||||||
},
|
},
|
||||||
rawMessage: "Unrecognized function: 'fromJSON2'"
|
rawMessage: "Unrecognized function: 'fromJSON2'"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
prefix: "test.yaml (Line: 6, Col: 14)",
|
prefix: "test.yaml (Line: 6, Col: 14)",
|
||||||
range: {
|
range: {
|
||||||
start: [8, 24],
|
start: {line: 8, column: 24},
|
||||||
end: [8, 51]
|
end: {line: 8, column: 51}
|
||||||
},
|
},
|
||||||
rawMessage: "Unrecognized function: 'toJSON2'"
|
rawMessage: "Unrecognized function: 'toJSON2'"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ describe("parseWorkflow", () => {
|
|||||||
|
|
||||||
expect(result.context.errors.getErrors()).toEqual([
|
expect(result.context.errors.getErrors()).toEqual([
|
||||||
new TemplateValidationError("Required property is missing: runs-on", "test.yaml (Line: 4, Col: 5)", undefined, {
|
new TemplateValidationError("Required property is missing: runs-on", "test.yaml (Line: 4, Col: 5)", undefined, {
|
||||||
start: [4, 5],
|
start: {line: 4, column: 5},
|
||||||
end: [5, 24]
|
end: {line: 5, column: 24}
|
||||||
})
|
})
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
@@ -62,8 +62,8 @@ jobs:
|
|||||||
"test.yaml (Line: 6, Col: 13)",
|
"test.yaml (Line: 6, Col: 13)",
|
||||||
undefined,
|
undefined,
|
||||||
{
|
{
|
||||||
start: [6, 13],
|
start: {line: 6, column: 13},
|
||||||
end: [6, 37]
|
end: {line: 6, column: 37}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -455,7 +455,7 @@ class TemplateReader {
|
|||||||
// Doesn't contain "${{"
|
// Doesn't contain "${{"
|
||||||
// Check if value should still be evaluated as an expression
|
// Check if value should still be evaluated as an expression
|
||||||
if (definitionInfo.definition instanceof StringDefinition && definitionInfo.definition.isExpression) {
|
if (definitionInfo.definition instanceof StringDefinition && definitionInfo.definition.isExpression) {
|
||||||
const expression = this.parseIntoExpressionToken(token.range!, raw, allowedContext, token);
|
const expression = this.parseIntoExpressionToken(token.range!, raw, allowedContext, token, definitionInfo);
|
||||||
if (expression) {
|
if (expression) {
|
||||||
return expression;
|
return expression;
|
||||||
}
|
}
|
||||||
@@ -500,11 +500,11 @@ class TemplateReader {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let tr = token.range!;
|
let tr = token.range!;
|
||||||
if (tr.start[0] === tr.end[0]) {
|
if (tr.start.line === tr.end.line) {
|
||||||
// If it's a single line expression, adjust the range to only cover the sub-expression
|
// If it's a single line expression, adjust the range to only cover the sub-expression
|
||||||
tr = {
|
tr = {
|
||||||
start: [tr.start[0], tr.start[1] + startExpression],
|
start: {line: tr.start.line, column: tr.start.column + startExpression},
|
||||||
end: [tr.end[0], tr.start[1] + endExpression + 1]
|
end: {line: tr.end.line, column: tr.start.column + endExpression + 1}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
// Adjust the range to only cover the expression for multi-line strings
|
// Adjust the range to only cover the expression for multi-line strings
|
||||||
@@ -515,12 +515,12 @@ class TemplateReader {
|
|||||||
const adjustedEnd = endExpression - beginningOfLine + 1;
|
const adjustedEnd = endExpression - beginningOfLine + 1;
|
||||||
|
|
||||||
tr = {
|
tr = {
|
||||||
start: [tr.start[0] + adjustedStartLine, adjustedStart],
|
start: {line: tr.start.line + adjustedStartLine, column: adjustedStart},
|
||||||
end: [tr.start[0] + adjustedStartLine, adjustedEnd]
|
end: {line: tr.start.line + adjustedStartLine, column: adjustedEnd}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const expression = this.parseIntoExpressionToken(tr, rawExpression, allowedContext, token);
|
const expression = this.parseIntoExpressionToken(tr, rawExpression, allowedContext, token, definitionInfo);
|
||||||
|
|
||||||
if (!expression) {
|
if (!expression) {
|
||||||
// Record that we've hit an error but continue to validate any other expressions
|
// Record that we've hit an error but continue to validate any other expressions
|
||||||
@@ -615,9 +615,10 @@ class TemplateReader {
|
|||||||
tr: TokenRange,
|
tr: TokenRange,
|
||||||
rawExpression: string,
|
rawExpression: string,
|
||||||
allowedContext: string[],
|
allowedContext: string[],
|
||||||
token: TemplateToken
|
token: TemplateToken,
|
||||||
|
definitionInfo: DefinitionInfo | undefined
|
||||||
): ExpressionToken | undefined {
|
): ExpressionToken | undefined {
|
||||||
const parseExpressionResult = this.parseExpression(tr, rawExpression, allowedContext, token.definitionInfo);
|
const parseExpressionResult = this.parseExpression(tr, rawExpression, allowedContext, definitionInfo);
|
||||||
|
|
||||||
// Check for error
|
// Check for error
|
||||||
if (parseExpressionResult.error) {
|
if (parseExpressionResult.error) {
|
||||||
|
|||||||
@@ -42,11 +42,11 @@ export abstract class TemplateToken {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public get line(): number | undefined {
|
public get line(): number | undefined {
|
||||||
return this.range?.start[0];
|
return this.range?.start.line;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get col(): number | undefined {
|
public get col(): number | undefined {
|
||||||
return this.range?.start[1];
|
return this.range?.start.column;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get definition(): Definition | undefined {
|
public get definition(): Definition | undefined {
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
export type Position = [line: number, character: number];
|
/** Represents the position within a template object */
|
||||||
|
export type Position = {
|
||||||
|
/** The one-based line value */
|
||||||
|
line: number;
|
||||||
|
/** The one-based column value */
|
||||||
|
column: number;
|
||||||
|
};
|
||||||
|
|
||||||
export type TokenRange = {
|
export type TokenRange = {
|
||||||
start: Position;
|
start: Position;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import {JSONObjectReader} from "../templates/json-object-reader";
|
import {JSONObjectReader} from "../templates/json-object-reader";
|
||||||
import {TemplateSchema} from "../templates/schema";
|
import {TemplateSchema} from "../templates/schema";
|
||||||
import WorkflowSchema from "../workflow-v1.0.json";
|
import WorkflowSchema from "../workflow-v1.0.json" assert {type: "json"};
|
||||||
|
|
||||||
let schema: TemplateSchema;
|
let schema: TemplateSchema;
|
||||||
|
|
||||||
|
|||||||
@@ -74,8 +74,8 @@ it("YAML errors include range information", () => {
|
|||||||
|
|
||||||
const error = context.errors.getErrors()[0];
|
const error = context.errors.getErrors()[0];
|
||||||
expect(error.range).toEqual({
|
expect(error.range).toEqual({
|
||||||
start: [7, 38],
|
start: {line: 7, column: 38},
|
||||||
end: [7, 63]
|
end: {line: 7, column: 63}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -89,8 +89,8 @@ export class YamlObjectReader implements ObjectReader {
|
|||||||
const elp = this.lineCounter.linePos(endPos);
|
const elp = this.lineCounter.linePos(endPos);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
start: [slp.line, slp.col],
|
start: {line: slp.line, column: slp.col},
|
||||||
end: [elp.line, elp.col]
|
end: {line: elp.line, column: elp.col}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,7 +216,7 @@ function rangeFromLinePos(linePos: [LinePos] | [LinePos, LinePos] | undefined):
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TokenRange and linePos are both 1-based
|
// TokenRange and linePos are both 1-based
|
||||||
const start: Position = [linePos[0].line, linePos[0].col];
|
const start: Position = {line: linePos[0].line, column: linePos[0].col};
|
||||||
const end: Position = linePos.length == 2 ? [linePos[1].line, linePos[1].col] : start;
|
const end: Position = linePos.length == 2 ? {line: linePos[1].line, column: linePos[1].col} : start;
|
||||||
return {start, end};
|
return {start, end};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "browser-playground",
|
"name": "browser-playground",
|
||||||
"version": "0.1.100",
|
"version": "0.1.109",
|
||||||
"description": "",
|
"description": "",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@github/actions-languageserver": "^0.1.100",
|
"@github/actions-languageserver": "^0.1.109",
|
||||||
"monaco-editor-webpack-plugin": "^7.0.1",
|
"monaco-editor-webpack-plugin": "^7.0.1",
|
||||||
"monaco-editor-workers": "^0.34.2",
|
"monaco-editor-workers": "^0.34.2",
|
||||||
"monaco-languageclient": "^4.0.3",
|
"monaco-languageclient": "^4.0.3",
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
|
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
|
||||||
"useWorkspaces": true,
|
"useWorkspaces": true,
|
||||||
"version": "0.1.100"
|
"version": "0.1.109"
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+119
-63
@@ -18,28 +18,28 @@
|
|||||||
},
|
},
|
||||||
"actions-expressions": {
|
"actions-expressions": {
|
||||||
"name": "@github/actions-expressions",
|
"name": "@github/actions-expressions",
|
||||||
"version": "0.1.100",
|
"version": "0.1.109",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^29.0.3",
|
"@types/jest": "^29.0.3",
|
||||||
"jest": "^29.0.3",
|
"jest": "^29.0.3",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.8.3",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"ts-jest": "^29.0.3",
|
"ts-jest": "^29.0.3",
|
||||||
"typescript": "^4.7.4"
|
"typescript": "^4.7.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 16"
|
"node": ">= 16.15"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"actions-languageserver": {
|
"actions-languageserver": {
|
||||||
"name": "@github/actions-languageserver",
|
"name": "@github/actions-languageserver",
|
||||||
"version": "0.1.100",
|
"version": "0.1.109",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@github/actions-languageservice": "^0.1.100",
|
"@github/actions-languageservice": "^0.1.109",
|
||||||
"@github/actions-workflow-parser": "^0.1.100",
|
"@github/actions-workflow-parser": "^0.1.109",
|
||||||
"@octokit/rest": "^19.0.5",
|
"@octokit/rest": "^19.0.7",
|
||||||
"vscode-languageserver": "^8.0.2",
|
"vscode-languageserver": "^8.0.2",
|
||||||
"vscode-languageserver-textdocument": "^1.0.7",
|
"vscode-languageserver-textdocument": "^1.0.7",
|
||||||
"yaml": "^2.1.3"
|
"yaml": "^2.1.3"
|
||||||
@@ -48,22 +48,22 @@
|
|||||||
"@types/jest": "^29.0.3",
|
"@types/jest": "^29.0.3",
|
||||||
"fetch-mock": "^9.11.0",
|
"fetch-mock": "^9.11.0",
|
||||||
"jest": "^29.0.3",
|
"jest": "^29.0.3",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.8.3",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"ts-jest": "^29.0.3",
|
"ts-jest": "^29.0.3",
|
||||||
"typescript": "^4.8.4"
|
"typescript": "^4.8.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 16"
|
"node": ">= 16.15"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"actions-languageservice": {
|
"actions-languageservice": {
|
||||||
"name": "@github/actions-languageservice",
|
"name": "@github/actions-languageservice",
|
||||||
"version": "0.1.100",
|
"version": "0.1.109",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@github/actions-expressions": "^0.1.100",
|
"@github/actions-expressions": "^0.1.109",
|
||||||
"@github/actions-workflow-parser": "^0.1.100",
|
"@github/actions-workflow-parser": "^0.1.109",
|
||||||
"vscode-languageserver-textdocument": "^1.0.7",
|
"vscode-languageserver-textdocument": "^1.0.7",
|
||||||
"vscode-languageserver-types": "^3.17.2",
|
"vscode-languageserver-types": "^3.17.2",
|
||||||
"yaml": "^2.1.1"
|
"yaml": "^2.1.1"
|
||||||
@@ -71,21 +71,21 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^29.0.3",
|
"@types/jest": "^29.0.3",
|
||||||
"jest": "^29.0.3",
|
"jest": "^29.0.3",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.8.3",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"ts-jest": "^29.0.3",
|
"ts-jest": "^29.0.3",
|
||||||
"typescript": "^4.8.4"
|
"typescript": "^4.8.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 16"
|
"node": ">= 16.15"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"actions-workflow-parser": {
|
"actions-workflow-parser": {
|
||||||
"name": "@github/actions-workflow-parser",
|
"name": "@github/actions-workflow-parser",
|
||||||
"version": "0.1.100",
|
"version": "0.1.109",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@github/actions-expressions": "^0.1.100",
|
"@github/actions-expressions": "^0.1.109",
|
||||||
"cronstrue": "^2.21.0",
|
"cronstrue": "^2.21.0",
|
||||||
"yaml": "^2.0.0-8"
|
"yaml": "^2.0.0-8"
|
||||||
},
|
},
|
||||||
@@ -95,20 +95,20 @@
|
|||||||
"@typescript-eslint/parser": "^5.40.0",
|
"@typescript-eslint/parser": "^5.40.0",
|
||||||
"eslint": "7.32.0",
|
"eslint": "7.32.0",
|
||||||
"jest": "^29.0.3",
|
"jest": "^29.0.3",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.8.3",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"ts-jest": "^29.0.3",
|
"ts-jest": "^29.0.3",
|
||||||
"typescript": "^4.8.4"
|
"typescript": "^4.8.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 16"
|
"node": ">= 16.15"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"browser-playground": {
|
"browser-playground": {
|
||||||
"version": "0.1.100",
|
"version": "0.1.109",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@github/actions-languageserver": "^0.1.100",
|
"@github/actions-languageserver": "^0.1.109",
|
||||||
"monaco-editor-webpack-plugin": "^7.0.1",
|
"monaco-editor-webpack-plugin": "^7.0.1",
|
||||||
"monaco-editor-workers": "^0.34.2",
|
"monaco-editor-workers": "^0.34.2",
|
||||||
"monaco-languageclient": "^4.0.3",
|
"monaco-languageclient": "^4.0.3",
|
||||||
@@ -2904,11 +2904,11 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/plugin-paginate-rest": {
|
"node_modules/@octokit/plugin-paginate-rest": {
|
||||||
"version": "5.0.1",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.0.0.tgz",
|
||||||
"integrity": "sha512-7A+rEkS70pH36Z6JivSlR7Zqepz3KVucEFVDnSrgHXzG7WLAzYwcHZbKdfTXHwuTHbkT1vKvz7dHl1+HNf6Qyw==",
|
"integrity": "sha512-Sq5VU1PfT6/JyuXPyt04KZNVsFOSBaYOAq2QRZUwzVlI10KFvcbUo8lR258AAQL1Et60b0WuVik+zOWKLuDZxw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/types": "^8.0.0"
|
"@octokit/types": "^9.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 14"
|
"node": ">= 14"
|
||||||
@@ -2917,6 +2917,19 @@
|
|||||||
"@octokit/core": ">=4"
|
"@octokit/core": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": {
|
||||||
|
"version": "16.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
|
||||||
|
"integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": {
|
||||||
|
"version": "9.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
|
||||||
|
"integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/openapi-types": "^16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@octokit/plugin-request-log": {
|
"node_modules/@octokit/plugin-request-log": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
|
||||||
@@ -2926,11 +2939,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/plugin-rest-endpoint-methods": {
|
"node_modules/@octokit/plugin-rest-endpoint-methods": {
|
||||||
"version": "6.7.0",
|
"version": "7.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-6.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.0.1.tgz",
|
||||||
"integrity": "sha512-orxQ0fAHA7IpYhG2flD2AygztPlGYNAdlzYz8yrD8NDgelPfOYoRPROfEyIe035PlxvbYrgkfUZIhSBKju/Cvw==",
|
"integrity": "sha512-pnCaLwZBudK5xCdrR823xHGNgqOzRnJ/mpC/76YPpNP7DybdsJtP7mdOwh+wYZxK5jqeQuhu59ogMI4NRlBUvA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/types": "^8.0.0",
|
"@octokit/types": "^9.0.0",
|
||||||
"deprecation": "^2.3.1"
|
"deprecation": "^2.3.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -2940,6 +2953,19 @@
|
|||||||
"@octokit/core": ">=3"
|
"@octokit/core": ">=3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": {
|
||||||
|
"version": "16.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
|
||||||
|
"integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": {
|
||||||
|
"version": "9.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
|
||||||
|
"integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/openapi-types": "^16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@octokit/request": {
|
"node_modules/@octokit/request": {
|
||||||
"version": "6.2.2",
|
"version": "6.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.2.tgz",
|
||||||
@@ -2970,14 +2996,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@octokit/rest": {
|
"node_modules/@octokit/rest": {
|
||||||
"version": "19.0.5",
|
"version": "19.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.7.tgz",
|
||||||
"integrity": "sha512-+4qdrUFq2lk7Va+Qff3ofREQWGBeoTKNqlJO+FGjFP35ZahP+nBenhZiGdu8USSgmq4Ky3IJ/i4u0xbLqHaeow==",
|
"integrity": "sha512-HRtSfjrWmWVNp2uAkEpQnuGMJsu/+dBr47dRc5QVgsCbnIc1+GFEaoKBWkYG+zjrsHpSqcAElMio+n10c0b5JA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/core": "^4.1.0",
|
"@octokit/core": "^4.1.0",
|
||||||
"@octokit/plugin-paginate-rest": "^5.0.0",
|
"@octokit/plugin-paginate-rest": "^6.0.0",
|
||||||
"@octokit/plugin-request-log": "^1.0.4",
|
"@octokit/plugin-request-log": "^1.0.4",
|
||||||
"@octokit/plugin-rest-endpoint-methods": "^6.7.0"
|
"@octokit/plugin-rest-endpoint-methods": "^7.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 14"
|
"node": ">= 14"
|
||||||
@@ -10998,9 +11024,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/prettier": {
|
"node_modules/prettier": {
|
||||||
"version": "2.7.1",
|
"version": "2.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz",
|
||||||
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
|
"integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"prettier": "bin-prettier.js"
|
"prettier": "bin-prettier.js"
|
||||||
@@ -14535,7 +14561,7 @@
|
|||||||
"requires": {
|
"requires": {
|
||||||
"@types/jest": "^29.0.3",
|
"@types/jest": "^29.0.3",
|
||||||
"jest": "^29.0.3",
|
"jest": "^29.0.3",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.8.3",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"ts-jest": "^29.0.3",
|
"ts-jest": "^29.0.3",
|
||||||
"typescript": "^4.7.4"
|
"typescript": "^4.7.4"
|
||||||
@@ -14544,13 +14570,13 @@
|
|||||||
"@github/actions-languageserver": {
|
"@github/actions-languageserver": {
|
||||||
"version": "file:actions-languageserver",
|
"version": "file:actions-languageserver",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@github/actions-languageservice": "^0.1.100",
|
"@github/actions-languageservice": "^0.1.109",
|
||||||
"@github/actions-workflow-parser": "^0.1.100",
|
"@github/actions-workflow-parser": "^0.1.109",
|
||||||
"@octokit/rest": "^19.0.5",
|
"@octokit/rest": "^19.0.7",
|
||||||
"@types/jest": "^29.0.3",
|
"@types/jest": "^29.0.3",
|
||||||
"fetch-mock": "^9.11.0",
|
"fetch-mock": "^9.11.0",
|
||||||
"jest": "^29.0.3",
|
"jest": "^29.0.3",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.8.3",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"ts-jest": "^29.0.3",
|
"ts-jest": "^29.0.3",
|
||||||
"typescript": "^4.8.4",
|
"typescript": "^4.8.4",
|
||||||
@@ -14562,11 +14588,11 @@
|
|||||||
"@github/actions-languageservice": {
|
"@github/actions-languageservice": {
|
||||||
"version": "file:actions-languageservice",
|
"version": "file:actions-languageservice",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@github/actions-expressions": "^0.1.100",
|
"@github/actions-expressions": "^0.1.109",
|
||||||
"@github/actions-workflow-parser": "^0.1.100",
|
"@github/actions-workflow-parser": "^0.1.109",
|
||||||
"@types/jest": "^29.0.3",
|
"@types/jest": "^29.0.3",
|
||||||
"jest": "^29.0.3",
|
"jest": "^29.0.3",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.8.3",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"ts-jest": "^29.0.3",
|
"ts-jest": "^29.0.3",
|
||||||
"typescript": "^4.8.4",
|
"typescript": "^4.8.4",
|
||||||
@@ -14578,14 +14604,14 @@
|
|||||||
"@github/actions-workflow-parser": {
|
"@github/actions-workflow-parser": {
|
||||||
"version": "file:actions-workflow-parser",
|
"version": "file:actions-workflow-parser",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@github/actions-expressions": "^0.1.100",
|
"@github/actions-expressions": "^0.1.109",
|
||||||
"@types/jest": "^29.0.3",
|
"@types/jest": "^29.0.3",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.40.0",
|
"@typescript-eslint/eslint-plugin": "^5.40.0",
|
||||||
"@typescript-eslint/parser": "^5.40.0",
|
"@typescript-eslint/parser": "^5.40.0",
|
||||||
"cronstrue": "^2.21.0",
|
"cronstrue": "^2.21.0",
|
||||||
"eslint": "7.32.0",
|
"eslint": "7.32.0",
|
||||||
"jest": "^29.0.3",
|
"jest": "^29.0.3",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.8.3",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"ts-jest": "^29.0.3",
|
"ts-jest": "^29.0.3",
|
||||||
"typescript": "^4.8.4",
|
"typescript": "^4.8.4",
|
||||||
@@ -16280,11 +16306,26 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@octokit/plugin-paginate-rest": {
|
"@octokit/plugin-paginate-rest": {
|
||||||
"version": "5.0.1",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.0.0.tgz",
|
||||||
"integrity": "sha512-7A+rEkS70pH36Z6JivSlR7Zqepz3KVucEFVDnSrgHXzG7WLAzYwcHZbKdfTXHwuTHbkT1vKvz7dHl1+HNf6Qyw==",
|
"integrity": "sha512-Sq5VU1PfT6/JyuXPyt04KZNVsFOSBaYOAq2QRZUwzVlI10KFvcbUo8lR258AAQL1Et60b0WuVik+zOWKLuDZxw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@octokit/types": "^8.0.0"
|
"@octokit/types": "^9.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/openapi-types": {
|
||||||
|
"version": "16.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
|
||||||
|
"integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
|
||||||
|
},
|
||||||
|
"@octokit/types": {
|
||||||
|
"version": "9.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
|
||||||
|
"integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
|
||||||
|
"requires": {
|
||||||
|
"@octokit/openapi-types": "^16.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@octokit/plugin-request-log": {
|
"@octokit/plugin-request-log": {
|
||||||
@@ -16294,12 +16335,27 @@
|
|||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"@octokit/plugin-rest-endpoint-methods": {
|
"@octokit/plugin-rest-endpoint-methods": {
|
||||||
"version": "6.7.0",
|
"version": "7.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-6.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.0.1.tgz",
|
||||||
"integrity": "sha512-orxQ0fAHA7IpYhG2flD2AygztPlGYNAdlzYz8yrD8NDgelPfOYoRPROfEyIe035PlxvbYrgkfUZIhSBKju/Cvw==",
|
"integrity": "sha512-pnCaLwZBudK5xCdrR823xHGNgqOzRnJ/mpC/76YPpNP7DybdsJtP7mdOwh+wYZxK5jqeQuhu59ogMI4NRlBUvA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@octokit/types": "^8.0.0",
|
"@octokit/types": "^9.0.0",
|
||||||
"deprecation": "^2.3.1"
|
"deprecation": "^2.3.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/openapi-types": {
|
||||||
|
"version": "16.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
|
||||||
|
"integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
|
||||||
|
},
|
||||||
|
"@octokit/types": {
|
||||||
|
"version": "9.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
|
||||||
|
"integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
|
||||||
|
"requires": {
|
||||||
|
"@octokit/openapi-types": "^16.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@octokit/request": {
|
"@octokit/request": {
|
||||||
@@ -16326,14 +16382,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@octokit/rest": {
|
"@octokit/rest": {
|
||||||
"version": "19.0.5",
|
"version": "19.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.7.tgz",
|
||||||
"integrity": "sha512-+4qdrUFq2lk7Va+Qff3ofREQWGBeoTKNqlJO+FGjFP35ZahP+nBenhZiGdu8USSgmq4Ky3IJ/i4u0xbLqHaeow==",
|
"integrity": "sha512-HRtSfjrWmWVNp2uAkEpQnuGMJsu/+dBr47dRc5QVgsCbnIc1+GFEaoKBWkYG+zjrsHpSqcAElMio+n10c0b5JA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@octokit/core": "^4.1.0",
|
"@octokit/core": "^4.1.0",
|
||||||
"@octokit/plugin-paginate-rest": "^5.0.0",
|
"@octokit/plugin-paginate-rest": "^6.0.0",
|
||||||
"@octokit/plugin-request-log": "^1.0.4",
|
"@octokit/plugin-request-log": "^1.0.4",
|
||||||
"@octokit/plugin-rest-endpoint-methods": "^6.7.0"
|
"@octokit/plugin-rest-endpoint-methods": "^7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@octokit/types": {
|
"@octokit/types": {
|
||||||
@@ -17506,7 +17562,7 @@
|
|||||||
"browser-playground": {
|
"browser-playground": {
|
||||||
"version": "file:browser-playground",
|
"version": "file:browser-playground",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@github/actions-languageserver": "^0.1.100",
|
"@github/actions-languageserver": "^0.1.109",
|
||||||
"css-loader": "^6.7.2",
|
"css-loader": "^6.7.2",
|
||||||
"monaco-editor-webpack-plugin": "^7.0.1",
|
"monaco-editor-webpack-plugin": "^7.0.1",
|
||||||
"monaco-editor-workers": "^0.34.2",
|
"monaco-editor-workers": "^0.34.2",
|
||||||
@@ -22508,9 +22564,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"prettier": {
|
"prettier": {
|
||||||
"version": "2.7.1",
|
"version": "2.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz",
|
||||||
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
|
"integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"pretty-format": {
|
"pretty-format": {
|
||||||
|
|||||||
Reference in New Issue
Block a user