ESM migration: Add .js extensions for node16 moduleResolution (#257)

Migrate expressions, workflow-parser, and languageservice packages to use
proper ESM imports with .js extensions that work with node16 moduleResolution.

Changes:
- Update tsconfig.build.json in each package to use module: node16 and
  moduleResolution: node16
- Add .js extensions to all relative import paths (Option B approach)
- Fix yaml internal type imports in workflow-parser by defining local types
- Add skipLibCheck to handle @types/node compatibility issues
- Add TypeScript 5.8.3 override in root package.json
- Add ESM migration plan documentation

The languageserver package is deferred due to test hang issues that need
further investigation.

Related #154 - Upgrade moduleResolution from node to node16 or nodenext
Related #110 - Published ESM code has imports without file extensions
Related #64 - expressions: ERR_MODULE_NOT_FOUND attempting to run example
Related #146 - Can not import @actions/workflow-parser

Test results:
- expressions: 1068 tests passed
- workflow-parser: 292 tests passed
- languageservice: 452 tests passed

* docs: update ESM migration plan with findings

- Update languageserver blocker: vscode-languageserver v8.0.2 lacks ESM
  exports (not a test hang issue)
- Document that Option B (manual .js extensions) was chosen over Option A
  due to ts-jest compatibility issues
- Add workaround for yaml package internal types (LinePos, NodeBase)
- Update migration status table with accurate reason for deferral
- Add skipLibCheck note for @types/node compatibility
This commit is contained in:
eric sciple
2025-12-18 13:35:48 -06:00
committed by GitHub
parent fbdc2a5749
commit 656a821a94
186 changed files with 1136 additions and 763 deletions
+299
View File
@@ -0,0 +1,299 @@
# ESM Migration Plan: Add File Extensions to Imports
## Overview
This document outlines the plan to migrate from TypeScript's deprecated `"moduleResolution": "node"` (node10) to `"moduleResolution": "node16"` or `"nodenext"`. This change is necessary because the published ESM packages have extensionless imports that don't work correctly in modern ESM environments.
## Issues Fixed
This migration will resolve the following issues:
- **#154** - Upgrade `moduleResolution` from `node` to `node16` or `nodenext` in tsconfig
- **#110** - Published ESM code has imports without file extensions
- **#64** - expressions: ERR_MODULE_NOT_FOUND attempting to run example demo script
- **#146** - Can not import `@actions/workflow-parser`
## Problem Statement
### Current State
All packages use `"moduleResolution": "node"`:
| Package | moduleResolution | TypeScript |
|---------|------------------|------------|
| expressions | `"node"` | ^4.7.4 |
| workflow-parser | `"node"` | ^4.8.4 |
| languageservice | `"node"` | ^4.8.4 |
| languageserver | `"node"` | ^4.8.4 |
| browser-playground | `"Node16"` ✅ | ^4.9.4 |
This causes TypeScript to emit code like:
```javascript
// Published to npm - INVALID ESM
export { Expr } from "./ast"; // Missing .js extension!
```
### Why This Fails
ESM in Node.js 12+ **requires** explicit file extensions. When users try to import these packages:
```javascript
// User's code
import { Expr } from "@actions/expressions";
```
Node.js fails with:
```
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '.../node_modules/@actions/expressions/dist/ast'
```
## Migration Strategy
### Option A: TypeScript 5.7+ with `rewriteRelativeImportExtensions` (Recommended)
TypeScript 5.7 introduced a new compiler option that automatically rewrites `.ts` extensions to `.js` in output:
```jsonc
{
"compilerOptions": {
"moduleResolution": "node16", // or "nodenext"
"rewriteRelativeImportExtensions": true
}
}
```
**Source code:**
```typescript
import { Expr } from "./ast.ts";
```
**Compiled output:**
```javascript
export { Expr } from "./ast.js";
```
**Pros:**
- Source uses `.ts` extensions (matches actual files)
- Works with Deno (which requires `.ts` extensions)
- TypeScript automatically transforms to `.js`
- Modern, forward-looking approach
**Cons:**
- Requires TypeScript 5.7+
- Relatively new feature
- **BUG:** See "Known Issues" section below
### Option B: Manual `.js` Extensions
Use `.js` extensions in source TypeScript files:
```typescript
import { Expr } from "./ast.js"; // Points to .ts file, but use .js extension
```
**Pros:**
- Works with TypeScript 4.7+ (with node16 moduleResolution)
- Well-established pattern
- No post-processing needed
- Works with ts-jest without extra configuration
**Cons:**
- Confusing - `.js` files don't exist at write time
- Doesn't work with Deno out of the box
### Recommendation
**Use Option B** (manual `.js` extensions). Option A with `rewriteRelativeImportExtensions` has compatibility issues with ts-jest and requires additional workarounds.
---
## Known Issues and Workarounds (December 2025)
### 1. TypeScript Version Conflicts in Monorepo
**Problem:** The root `node_modules/typescript` was version 4.9.5 (pulled in by `ts-node` and `tsutils` dependencies), while workspace packages specified `^5.8.3`.
**Symptoms:**
- `npx tsc --version` showed 4.9.5
- `require('typescript').version` in ts-jest showed 5.8.3
- Confusing build failures
**Solution:** Add npm overrides in root `package.json`:
```json
{
"overrides": {
"typescript": "5.8.3"
}
}
```
### 2. ts-jest Compatibility with TypeScript 5.9+
**Problem:** ts-jest 29.4.6 uses `typescript.JSDocParsingMode.ParseAll` which doesn't exist in TypeScript's ES module exports.
**Error:**
```
TypeError: Cannot read properties of undefined (reading 'ParseAll')
at Object.<anonymous> (node_modules/ts-jest/dist/compiler/ts-compiler.js:43:123)
```
**Root Cause:** ts-jest accesses `typescript_1.default.JSDocParsingMode.ParseAll` but TypeScript has no default export in ESM.
**Solution:**
- Use ts-jest 29.0.3 (older version that doesn't use this API)
- OR wait for ts-jest fix
- **Stay on TypeScript 5.8.3, not 5.9+**
### 3. TypeScript `rewriteRelativeImportExtensions` Bug with .d.ts Files
**Problem:** TypeScript's `rewriteRelativeImportExtensions: true` correctly rewrites `.ts``.js` in `.js` output files, but **incorrectly keeps `.ts` extensions in `.d.ts` declaration files**.
**Example:**
- Source: `export { Expr } from "./ast.ts";`
- Output `index.js`: `export { Expr } from "./ast.js";` ✅ Correct
- Output `index.d.ts`: `export { Expr } from "./ast.ts";` ❌ Wrong (should be `.js`)
**Upstream Issue:** https://github.com/microsoft/TypeScript/issues/61037 (marked "Help Wanted", in Backlog, NOT FIXED as of Dec 2025)
**Workaround:** Post-process `.d.ts` files with a script. See `script/fix-dts-extensions.cjs`.
**Note:** Since we use Option B (manual `.js` extensions), this bug does not affect our migration.
### 4. yaml Package Internal Types Not Exported
**Problem:** The `yaml` package does not export internal types like `LinePos` and `NodeBase` that are used in `workflow-parser/src/workflows/yaml-object-reader.ts`.
**Error:**
```
error TS2305: Module '"yaml"' has no exported member 'LinePos'.
error TS2305: Module '"yaml"' has no exported member 'NodeBase'.
```
**Solution:** Define local type aliases in the file that uses them:
```typescript
// Local type definitions to replace yaml internal imports
type LinePos = { line: number; col: number };
type NodeBase = { range?: [number, number, number] };
```
### 5. languageserver Blocked by vscode-languageserver Dependency
**Problem:** The `vscode-languageserver` package (v8.0.2) does not have proper ESM exports. When using `moduleResolution: "node16"`, TypeScript requires packages to have an `exports` field in `package.json` for subpath imports to work.
**Error:**
```
src/index.ts(6,8): error TS2307: Cannot find module 'vscode-languageserver/browser' or its corresponding type declarations.
src/connection.ts(1,43): error TS2307: Cannot find module 'vscode-languageserver/node' or its corresponding type declarations.
```
**Root Cause:** The `vscode-languageserver` package.json only has `main` and `browser` fields, but no `exports` field:
```json
{
"main": "./lib/node/main.js",
"browser": {
"./lib/node/main.js": "./lib/browser/main.js"
}
// No "exports" field!
}
```
With `moduleResolution: "node16"`, TypeScript follows Node.js ESM resolution rules which require explicit `exports` for subpath imports like `vscode-languageserver/browser` and `vscode-languageserver/node`.
**Status:** Verified December 2025. Version 9.0.1 is available but ESM export support is not confirmed.
**Current Decision:** The languageserver package is **deferred** from this migration until the upstream `vscode-languageserver` package adds proper ESM exports. It will continue using the old `moduleResolution: "node"` configuration.
**Options to resolve:**
- Wait for vscode-languageserver to add ESM exports
- Try upgrading to vscode-languageserver v9.x to see if exports were added
- Use a bundler to work around the module resolution
- Fork or patch the dependency
---
## Migration Status
| Package | Tests | ESM Status |
|---------|-------|------------|
| expressions | 1068 | ✅ Migrated |
| workflow-parser | 292 | ✅ Migrated |
| languageservice | 452 | ✅ Migrated |
| languageserver | 6 files | ⏸️ Deferred (vscode-languageserver lacks ESM exports) |
---
## Required Configuration Changes
### tsconfig.build.json (each migrated package)
**Note:** We use **Option B** (manual `.js` extensions in source files) rather than `rewriteRelativeImportExtensions` because Option A caused ts-jest compatibility issues (tests would hang indefinitely).
```json
{
"compilerOptions": {
"module": "node16",
"moduleResolution": "node16",
"skipLibCheck": true,
"lib": ["ES2022"],
"target": "ES2022"
}
}
```
The `skipLibCheck: true` is needed to work around @types/node compatibility issues with TypeScript 5.x (TS2386 overload signature errors).
```
### jest.config.js (each migrated package)
```javascript
/** @type {import('ts-jest').JestConfigWithTsJest} */
export default {
preset: "ts-jest/presets/default-esm",
moduleNameMapper: {
"^(\\.{1,2}/.*)\\.js$": "$1",
"^(\\.{1,2}/.*)\\.ts$": "$1",
},
transform: {
"^.+\\.tsx?$": [
"ts-jest",
{
useESM: true,
isolatedModules: true,
},
],
},
moduleFileExtensions: ["ts", "js"],
};
```
### Root package.json
```json
{
"overrides": {
"typescript": "5.8.3"
}
}
```
### Each workspace package.json
```json
{
"devDependencies": {
"typescript": "^5.8.3",
"ts-jest": "^29.0.3"
}
}
```
---
## References
- [TypeScript moduleResolution reference](https://www.typescriptlang.org/docs/handbook/modules/reference.html)
- [TypeScript 5.7 rewriteRelativeImportExtensions](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-7.html#path-rewriting-for-relative-paths)
- [TypeScript .d.ts extension bug #61037](https://github.com/microsoft/TypeScript/issues/61037)
- [Node.js ESM mandatory extensions](https://nodejs.org/api/esm.html#mandatory-file-extensions)
- [ts-jest ESM support](https://kulshekhar.github.io/ts-jest/docs/guides/esm-support)
- [Community fork that works](https://github.com/boxbuild-io/actions-languageservices/commit/077fb2b58dfd2cca3d6e3df1fdf9e26e75db24ae)
+1 -1
View File
@@ -60,6 +60,6 @@
"prettier": "^2.8.3", "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": "^5.8.3"
} }
} }
+2 -2
View File
@@ -1,5 +1,5 @@
import {ExpressionData} from "./data"; import {ExpressionData} from "./data/index.js";
import {Token} from "./lexer"; import {Token} from "./lexer.js";
export interface ExprVisitor<R> { export interface ExprVisitor<R> {
visitLiteral(literal: Literal): R; visitLiteral(literal: Literal): R;
+8 -8
View File
@@ -1,11 +1,11 @@
import {complete, CompletionItem, trimTokenVector} from "./completion"; import {complete, CompletionItem, trimTokenVector} from "./completion.js";
import {DescriptionDictionary} from "./completion/descriptionDictionary"; import {DescriptionDictionary} from "./completion/descriptionDictionary.js";
import {BooleanData} from "./data/boolean"; import {BooleanData} from "./data/boolean.js";
import {Dictionary} from "./data/dictionary"; import {Dictionary} from "./data/dictionary.js";
import {StringData} from "./data/string"; import {StringData} from "./data/string.js";
import {wellKnownFunctions} from "./funcs"; import {wellKnownFunctions} from "./funcs.js";
import {FunctionDefinition, FunctionInfo} from "./funcs/info"; import {FunctionDefinition, FunctionInfo} from "./funcs/info.js";
import {Lexer, TokenType} from "./lexer"; import {Lexer, TokenType} from "./lexer.js";
const testContext = new Dictionary( const testContext = new Dictionary(
{ {
+8 -8
View File
@@ -1,11 +1,11 @@
import {DescriptionPair} from "./completion/descriptionDictionary"; import {DescriptionPair} from "./completion/descriptionDictionary.js";
import {Dictionary, isDictionary} from "./data/dictionary"; import {Dictionary, isDictionary} from "./data/dictionary.js";
import {ExpressionData} from "./data/expressiondata"; import {ExpressionData} from "./data/expressiondata.js";
import {Evaluator} from "./evaluator"; import {Evaluator} from "./evaluator.js";
import {wellKnownFunctions} from "./funcs"; import {wellKnownFunctions} from "./funcs.js";
import {FunctionDefinition, FunctionInfo} from "./funcs/info"; import {FunctionDefinition, FunctionInfo} from "./funcs/info.js";
import {Lexer, Token, TokenType} from "./lexer"; import {Lexer, Token, TokenType} from "./lexer.js";
import {Parser} from "./parser"; import {Parser} from "./parser.js";
export type CompletionItem = { export type CompletionItem = {
label: string; label: string;
@@ -1,5 +1,5 @@
import {StringData} from "../data"; import {StringData} from "../data/index.js";
import {DescriptionDictionary} from "./descriptionDictionary"; import {DescriptionDictionary} from "./descriptionDictionary.js";
describe("description dictionary", () => { describe("description dictionary", () => {
it("pairs contains all values", () => { it("pairs contains all values", () => {
@@ -1,5 +1,5 @@
import {Dictionary} from "../data/dictionary"; import {Dictionary} from "../data/dictionary.js";
import {ExpressionData, Kind, Pair} from "../data/expressiondata"; import {ExpressionData, Kind, Pair} from "../data/expressiondata.js";
export type DescriptionPair = Pair & {description?: string}; export type DescriptionPair = Pair & {description?: string};
+1 -1
View File
@@ -1,4 +1,4 @@
import {ExpressionData, ExpressionDataInterface, Kind, kindStr} from "./expressiondata"; import {ExpressionData, ExpressionDataInterface, Kind, kindStr} from "./expressiondata.js";
export class Array implements ExpressionDataInterface { export class Array implements ExpressionDataInterface {
private v: ExpressionData[] = []; private v: ExpressionData[] = [];
+1 -1
View File
@@ -1,4 +1,4 @@
import {ExpressionDataInterface, Kind} from "./expressiondata"; import {ExpressionDataInterface, Kind} from "./expressiondata.js";
export class BooleanData implements ExpressionDataInterface { export class BooleanData implements ExpressionDataInterface {
constructor(public readonly value: boolean) {} constructor(public readonly value: boolean) {}
+2 -2
View File
@@ -1,5 +1,5 @@
import {Dictionary} from "./dictionary"; import {Dictionary} from "./dictionary.js";
import {StringData} from "./string"; import {StringData} from "./string.js";
describe("dictionary", () => { describe("dictionary", () => {
it("pairs contains all values", () => { it("pairs contains all values", () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import {ExpressionData, ExpressionDataInterface, Kind, kindStr, Pair} from "./expressiondata"; import {ExpressionData, ExpressionDataInterface, Kind, kindStr, Pair} from "./expressiondata.js";
export class Dictionary implements ExpressionDataInterface { export class Dictionary implements ExpressionDataInterface {
private keys: string[] = []; private keys: string[] = [];
+6 -6
View File
@@ -1,9 +1,9 @@
import {Dictionary} from "./dictionary"; import {Dictionary} from "./dictionary.js";
import {Null} from "./null"; import {Null} from "./null.js";
import {Array} from "./array"; import {Array} from "./array.js";
import {StringData} from "./string"; import {StringData} from "./string.js";
import {NumberData} from "./number"; import {NumberData} from "./number.js";
import {BooleanData} from "./boolean"; import {BooleanData} from "./boolean.js";
export enum Kind { export enum Kind {
String = 0, String = 0,
+9 -9
View File
@@ -1,9 +1,9 @@
export {Array} from "./array"; export {Array} from "./array.js";
export {BooleanData} from "./boolean"; export {BooleanData} from "./boolean.js";
export {Dictionary} from "./dictionary"; export {Dictionary} from "./dictionary.js";
export {ExpressionData, Kind} from "./expressiondata"; export {ExpressionData, Kind} from "./expressiondata.js";
export {Null} from "./null"; export {Null} from "./null.js";
export {NumberData} from "./number"; export {NumberData} from "./number.js";
export {replacer} from "./replacer"; export {replacer} from "./replacer.js";
export {reviver} from "./reviver"; export {reviver} from "./reviver.js";
export {StringData} from "./string"; export {StringData} from "./string.js";
+1 -1
View File
@@ -1,4 +1,4 @@
import {ExpressionDataInterface, Kind} from "./expressiondata"; import {ExpressionDataInterface, Kind} from "./expressiondata.js";
export class Null implements ExpressionDataInterface { export class Null implements ExpressionDataInterface {
public readonly kind = Kind.Null; public readonly kind = Kind.Null;
+1 -1
View File
@@ -1,4 +1,4 @@
import {NumberData} from "./number"; import {NumberData} from "./number.js";
describe("number", () => { describe("number", () => {
it("coerces to string", () => { it("coerces to string", () => {
+1 -1
View File
@@ -1,4 +1,4 @@
import {ExpressionDataInterface, Kind} from "./expressiondata"; import {ExpressionDataInterface, Kind} from "./expressiondata.js";
export class NumberData implements ExpressionDataInterface { export class NumberData implements ExpressionDataInterface {
constructor(public readonly value: number) {} constructor(public readonly value: number) {}
+6 -6
View File
@@ -1,9 +1,9 @@
import {Array} from "./array"; import {Array} from "./array.js";
import {Dictionary} from "./dictionary"; import {Dictionary} from "./dictionary.js";
import {Null} from "./null"; import {Null} from "./null.js";
import {NumberData} from "./number"; import {NumberData} from "./number.js";
import {replacer} from "./replacer"; import {replacer} from "./replacer.js";
import {StringData} from "./string"; import {StringData} from "./string.js";
describe("replacer", () => { describe("replacer", () => {
it("null", () => { it("null", () => {
+6 -6
View File
@@ -1,9 +1,9 @@
import {Array} from "./array"; import {Array} from "./array.js";
import {BooleanData} from "./boolean"; import {BooleanData} from "./boolean.js";
import {Dictionary} from "./dictionary"; import {Dictionary} from "./dictionary.js";
import {Null} from "./null"; import {Null} from "./null.js";
import {NumberData} from "./number"; import {NumberData} from "./number.js";
import {StringData} from "./string"; import {StringData} from "./string.js";
/** /**
* Replacer can be passed to JSON.stringify to convert an ExpressionData object into plain JSON * Replacer can be passed to JSON.stringify to convert an ExpressionData object into plain JSON
+8 -8
View File
@@ -1,11 +1,11 @@
import {Array} from "./array"; import {Array} from "./array.js";
import {BooleanData} from "./boolean"; import {BooleanData} from "./boolean.js";
import {Dictionary} from "./dictionary"; import {Dictionary} from "./dictionary.js";
import {ExpressionData} from "./expressiondata"; import {ExpressionData} from "./expressiondata.js";
import {Null} from "./null"; import {Null} from "./null.js";
import {NumberData} from "./number"; import {NumberData} from "./number.js";
import {reviver} from "./reviver"; import {reviver} from "./reviver.js";
import {StringData} from "./string"; import {StringData} from "./string.js";
describe("reviver", () => { describe("reviver", () => {
const tests: { const tests: {
+7 -7
View File
@@ -1,10 +1,10 @@
import {Array as dArray} from "./array"; import {Array as dArray} from "./array.js";
import {BooleanData} from "./boolean"; import {BooleanData} from "./boolean.js";
import {Dictionary} from "./dictionary"; import {Dictionary} from "./dictionary.js";
import {ExpressionData} from "./expressiondata"; import {ExpressionData} from "./expressiondata.js";
import {Null} from "./null"; import {Null} from "./null.js";
import {NumberData} from "./number"; import {NumberData} from "./number.js";
import {StringData} from "./string"; import {StringData} from "./string.js";
/** /**
* Reviver can be passed to `JSON.parse` to convert plain JSON into an `ExpressionData` object. * Reviver can be passed to `JSON.parse` to convert plain JSON into an `ExpressionData` object.
+1 -1
View File
@@ -1,4 +1,4 @@
import {ExpressionDataInterface, Kind} from "./expressiondata"; import {ExpressionDataInterface, Kind} from "./expressiondata.js";
export class StringData implements ExpressionDataInterface { export class StringData implements ExpressionDataInterface {
constructor(public readonly value: string) {} constructor(public readonly value: string) {}
+1 -1
View File
@@ -1,4 +1,4 @@
import {Pos, Token, tokenString} from "./lexer"; import {Pos, Token, tokenString} from "./lexer.js";
export const MAX_PARSER_DEPTH = 50; export const MAX_PARSER_DEPTH = 50;
export const MAX_EXPRESSION_LENGTH = 21000; export const MAX_EXPRESSION_LENGTH = 21000;
+5 -5
View File
@@ -1,8 +1,8 @@
import * as data from "./data"; import * as data from "./data/index.js";
import {ExpressionEvaluationError} from "./errors"; import {ExpressionEvaluationError} from "./errors.js";
import {Evaluator} from "./evaluator"; import {Evaluator} from "./evaluator.js";
import {Lexer} from "./lexer"; import {Lexer} from "./lexer.js";
import {Parser} from "./parser"; import {Parser} from "./parser.js";
describe("evaluator", () => { describe("evaluator", () => {
const lexAndParse = (input: string) => { const lexAndParse = (input: string) => {
+8 -8
View File
@@ -10,14 +10,14 @@ import {
Logical, Logical,
Star, Star,
Unary Unary
} from "./ast"; } from "./ast.js";
import * as data from "./data"; import * as data from "./data/index.js";
import {FilteredArray} from "./filtered_array"; import {FilteredArray} from "./filtered_array.js";
import {wellKnownFunctions} from "./funcs"; import {wellKnownFunctions} from "./funcs.js";
import {FunctionDefinition} from "./funcs/info"; import {FunctionDefinition} from "./funcs/info.js";
import {idxHelper} from "./idxHelper"; import {idxHelper} from "./idxHelper.js";
import {TokenType} from "./lexer"; import {TokenType} from "./lexer.js";
import {equals, falsy, greaterThan, lessThan, truthy} from "./result"; import {equals, falsy, greaterThan, lessThan, truthy} from "./result.js";
export class Evaluator implements ExprVisitor<data.ExpressionData> { export class Evaluator implements ExprVisitor<data.ExpressionData> {
/** /**
+1 -1
View File
@@ -1,3 +1,3 @@
import * as data from "./data"; import * as data from "./data/index.js";
export class FilteredArray extends data.Array {} export class FilteredArray extends data.Array {}
+10 -10
View File
@@ -1,13 +1,13 @@
import {ErrorType, ExpressionError} from "./errors"; import {ErrorType, ExpressionError} from "./errors.js";
import {contains} from "./funcs/contains"; import {contains} from "./funcs/contains.js";
import {endswith} from "./funcs/endswith"; import {endswith} from "./funcs/endswith.js";
import {format} from "./funcs/format"; import {format} from "./funcs/format.js";
import {fromjson} from "./funcs/fromjson"; import {fromjson} from "./funcs/fromjson.js";
import {FunctionDefinition, FunctionInfo} from "./funcs/info"; import {FunctionDefinition, FunctionInfo} from "./funcs/info.js";
import {join} from "./funcs/join"; import {join} from "./funcs/join.js";
import {startswith} from "./funcs/startswith"; import {startswith} from "./funcs/startswith.js";
import {tojson} from "./funcs/tojson"; import {tojson} from "./funcs/tojson.js";
import {Token} from "./lexer"; import {Token} from "./lexer.js";
export type ParseContext = { export type ParseContext = {
allowUnknownKeywords: boolean; allowUnknownKeywords: boolean;
+3 -3
View File
@@ -1,6 +1,6 @@
import {BooleanData, ExpressionData, Kind} from "../data"; import {BooleanData, ExpressionData, Kind} from "../data/index.js";
import {equals} from "../result"; import {equals} from "../result.js";
import {FunctionDefinition} from "./info"; import {FunctionDefinition} from "./info.js";
export const contains: FunctionDefinition = { export const contains: FunctionDefinition = {
name: "contains", name: "contains",
+3 -3
View File
@@ -1,6 +1,6 @@
import {BooleanData, ExpressionData} from "../data"; import {BooleanData, ExpressionData} from "../data/index.js";
import {toUpperSpecial} from "../result"; import {toUpperSpecial} from "../result.js";
import {FunctionDefinition} from "./info"; import {FunctionDefinition} from "./info.js";
export const endswith: FunctionDefinition = { export const endswith: FunctionDefinition = {
name: "endsWith", name: "endsWith",
+2 -2
View File
@@ -1,5 +1,5 @@
import {Null, NumberData, StringData} from "../data"; import {Null, NumberData, StringData} from "../data/index.js";
import {format} from "./format"; import {format} from "./format.js";
describe("format", () => { describe("format", () => {
it("null", () => { it("null", () => {
+2 -2
View File
@@ -1,5 +1,5 @@
import {ExpressionData, StringData} from "../data"; import {ExpressionData, StringData} from "../data/index.js";
import {FunctionDefinition} from "./info"; import {FunctionDefinition} from "./info.js";
export const format: FunctionDefinition = { export const format: FunctionDefinition = {
name: "format", name: "format",
+4 -4
View File
@@ -1,7 +1,7 @@
import {ExpressionData} from "../data"; import {ExpressionData} from "../data/index.js";
import {reviver} from "../data/reviver"; import {reviver} from "../data/reviver.js";
import {ExpressionEvaluationError} from "../errors"; import {ExpressionEvaluationError} from "../errors.js";
import {FunctionDefinition} from "./info"; import {FunctionDefinition} from "./info.js";
export const fromjson: FunctionDefinition = { export const fromjson: FunctionDefinition = {
name: "fromJson", name: "fromJson",
+1 -1
View File
@@ -1,4 +1,4 @@
import {ExpressionData} from "../data"; import {ExpressionData} from "../data/index.js";
export interface FunctionInfo { export interface FunctionInfo {
name: string; name: string;
+2 -2
View File
@@ -1,5 +1,5 @@
import {ExpressionData, Kind, StringData} from "../data"; import {ExpressionData, Kind, StringData} from "../data/index.js";
import {FunctionDefinition} from "./info"; import {FunctionDefinition} from "./info.js";
export const join: FunctionDefinition = { export const join: FunctionDefinition = {
name: "join", name: "join",
+3 -3
View File
@@ -1,6 +1,6 @@
import {BooleanData, ExpressionData} from "../data"; import {BooleanData, ExpressionData} from "../data/index.js";
import {toUpperSpecial} from "../result"; import {toUpperSpecial} from "../result.js";
import {FunctionDefinition} from "./info"; import {FunctionDefinition} from "./info.js";
export const startswith: FunctionDefinition = { export const startswith: FunctionDefinition = {
name: "startsWith", name: "startsWith",
+3 -3
View File
@@ -1,6 +1,6 @@
import {ExpressionData, StringData} from "../data"; import {ExpressionData, StringData} from "../data/index.js";
import {replacer} from "../data/replacer"; import {replacer} from "../data/replacer.js";
import {FunctionDefinition} from "./info"; import {FunctionDefinition} from "./info.js";
export const tojson: FunctionDefinition = { export const tojson: FunctionDefinition = {
name: "toJson", name: "toJson",
+1 -1
View File
@@ -1,4 +1,4 @@
import {ExpressionData} from "./data"; import {ExpressionData} from "./data/index.js";
export class idxHelper { export class idxHelper {
public readonly str: string | undefined; public readonly str: string | undefined;
+9 -9
View File
@@ -1,9 +1,9 @@
export {Expr} from "./ast"; export {Expr} from "./ast.js";
export {complete, CompletionItem} from "./completion"; export {complete, CompletionItem} from "./completion.js";
export {DescriptionDictionary, DescriptionPair, isDescriptionDictionary} from "./completion/descriptionDictionary"; export {DescriptionDictionary, DescriptionPair, isDescriptionDictionary} from "./completion/descriptionDictionary.js";
export * as data from "./data"; export * as data from "./data/index.js";
export {ExpressionError, ExpressionEvaluationError} from "./errors"; export {ExpressionError, ExpressionEvaluationError} from "./errors.js";
export {Evaluator} from "./evaluator"; export {Evaluator} from "./evaluator.js";
export {wellKnownFunctions} from "./funcs"; export {wellKnownFunctions} from "./funcs.js";
export {Lexer, Result} from "./lexer"; export {Lexer, Result} from "./lexer.js";
export {Parser} from "./parser"; export {Parser} from "./parser.js";
+1 -1
View File
@@ -1,4 +1,4 @@
import {Lexer, Token, TokenType} from "./lexer"; import {Lexer, Token, TokenType} from "./lexer.js";
describe("lexer", () => { describe("lexer", () => {
const tests: { const tests: {
+2 -2
View File
@@ -1,5 +1,5 @@
import {StringData} from "./data"; import {StringData} from "./data/index.js";
import {MAX_EXPRESSION_LENGTH} from "./errors"; import {MAX_EXPRESSION_LENGTH} from "./errors.js";
export enum TokenType { export enum TokenType {
UNKNOWN, UNKNOWN,
+17 -6
View File
@@ -1,9 +1,20 @@
import {Binary, ContextAccess, Expr, FunctionCall, Grouping, IndexAccess, Literal, Logical, Star, Unary} from "./ast"; import {
import * as data from "./data"; Binary,
import {ErrorType, ExpressionError, MAX_PARSER_DEPTH} from "./errors"; ContextAccess,
import {ParseContext, validateFunction} from "./funcs"; Expr,
import {FunctionInfo} from "./funcs/info"; FunctionCall,
import {Token, TokenType} from "./lexer"; Grouping,
IndexAccess,
Literal,
Logical,
Star,
Unary
} from "./ast.js";
import * as data from "./data/index.js";
import {ErrorType, ExpressionError, MAX_PARSER_DEPTH} from "./errors.js";
import {ParseContext, validateFunction} from "./funcs.js";
import {FunctionInfo} from "./funcs/info.js";
import {Token, TokenType} from "./lexer.js";
export class Parser { export class Parser {
private extContexts: Map<string, boolean>; private extContexts: Map<string, boolean>;
+2 -2
View File
@@ -1,5 +1,5 @@
import {BooleanData, ExpressionData, NumberData, StringData} from "./data"; import {BooleanData, ExpressionData, NumberData, StringData} from "./data/index.js";
import {coerceTypes, toUpperSpecial} from "./result"; import {coerceTypes, toUpperSpecial} from "./result.js";
describe("coerceTypes", () => { describe("coerceTypes", () => {
const tests: { const tests: {
+1 -1
View File
@@ -1,4 +1,4 @@
import * as data from "./data"; import * as data from "./data/index.js";
export function falsy(d: data.ExpressionData): boolean { export function falsy(d: data.ExpressionData): boolean {
switch (d.kind) { switch (d.kind) {
+9 -9
View File
@@ -1,14 +1,14 @@
import * as fs from "fs"; import * as fs from "fs";
import * as path from "path"; import * as path from "path";
import {Expr} from "./ast"; import {Expr} from "./ast.js";
import * as data from "./data"; import * as data from "./data/index.js";
import {kindStr} from "./data/expressiondata"; import {kindStr} from "./data/expressiondata.js";
import {replacer} from "./data/replacer"; import {replacer} from "./data/replacer.js";
import {reviver} from "./data/reviver"; import {reviver} from "./data/reviver.js";
import {ExpressionError} from "./errors"; import {ExpressionError} from "./errors.js";
import {Evaluator} from "./evaluator"; import {Evaluator} from "./evaluator.js";
import {Lexer, Result} from "./lexer"; import {Lexer, Result} from "./lexer.js";
import {Parser} from "./parser"; import {Parser} from "./parser.js";
interface TestResult { interface TestResult {
value: data.ExpressionData; value: data.ExpressionData;
+4 -1
View File
@@ -2,9 +2,12 @@
"exclude": ["./src/**/*.test.ts"], "exclude": ["./src/**/*.test.ts"],
"extends": "./tsconfig.json", "extends": "./tsconfig.json",
"compilerOptions": { "compilerOptions": {
"module": "node16",
"moduleResolution": "node16",
"declaration": true, "declaration": true,
"declarationMap": true, "declarationMap": true,
"noEmit": false, "noEmit": false,
"outDir": "./dist" "outDir": "./dist",
"skipLibCheck": true
} }
} }
+1 -1
View File
@@ -1,4 +1,4 @@
import {actionIdentifier, parseActionReference as parse} from "./action"; import {actionIdentifier, parseActionReference as parse} from "./action.js";
describe("parseActionReference", () => { describe("parseActionReference", () => {
it("basic action", () => { it("basic action", () => {
@@ -1,13 +1,13 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */ /* eslint-disable @typescript-eslint/no-non-null-assertion */
import {data, DescriptionDictionary} from "@actions/expressions"; import {data, DescriptionDictionary} from "@actions/expressions";
import {CompletionItem, CompletionItemKind} from "vscode-languageserver-types"; import {CompletionItem, CompletionItemKind} from "vscode-languageserver-types";
import {complete, getExpressionInput} from "./complete"; import {complete, getExpressionInput} from "./complete.js";
import {ContextProviderConfig} from "./context-providers/config"; import {ContextProviderConfig} from "./context-providers/config.js";
import {registerLogger} from "./log"; import {registerLogger} from "./log.js";
import {getPositionFromCursor} from "./test-utils/cursor-position"; import {getPositionFromCursor} from "./test-utils/cursor-position.js";
import {TestLogger} from "./test-utils/logger"; import {TestLogger} from "./test-utils/logger.js";
import {testFileProvider} from "./test-utils/test-file-provider"; import {testFileProvider} from "./test-utils/test-file-provider.js";
import {clearCache} from "./utils/workflow-cache"; import {clearCache} from "./utils/workflow-cache.js";
const contextProviderConfig: ContextProviderConfig = { const contextProviderConfig: ContextProviderConfig = {
getContext: (context: string) => { getContext: (context: string) => {
@@ -1,7 +1,7 @@
import {complete} from "./complete"; import {complete} from "./complete.js";
import {TextDocument} from "vscode-languageserver-textdocument"; import {TextDocument} from "vscode-languageserver-textdocument";
import {clearCache} from "./utils/workflow-cache"; import {clearCache} from "./utils/workflow-cache.js";
import {getPositionFromCursor} from "./test-utils/cursor-position"; import {getPositionFromCursor} from "./test-utils/cursor-position.js";
beforeEach(() => { beforeEach(() => {
clearCache(); clearCache();
@@ -1,8 +1,8 @@
import {CompletionItem, MarkupContent} from "vscode-languageserver-types"; import {CompletionItem, MarkupContent} from "vscode-languageserver-types";
import {complete} from "./complete"; import {complete} from "./complete.js";
import {getPositionFromCursor} from "./test-utils/cursor-position"; import {getPositionFromCursor} from "./test-utils/cursor-position.js";
import {testFileProvider} from "./test-utils/test-file-provider"; import {testFileProvider} from "./test-utils/test-file-provider.js";
import {clearCache} from "./utils/workflow-cache"; import {clearCache} from "./utils/workflow-cache.js";
function mapResult(result: CompletionItem[]) { function mapResult(result: CompletionItem[]) {
return result.map(x => { return result.map(x => {
+6 -6
View File
@@ -1,11 +1,11 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */ /* eslint-disable @typescript-eslint/no-non-null-assertion */
import {MarkupContent, TextEdit} from "vscode-languageserver-types"; import {MarkupContent, TextEdit} from "vscode-languageserver-types";
import {complete} from "./complete"; import {complete} from "./complete.js";
import {registerLogger} from "./log"; import {registerLogger} from "./log.js";
import {getPositionFromCursor} from "./test-utils/cursor-position"; import {getPositionFromCursor} from "./test-utils/cursor-position.js";
import {TestLogger} from "./test-utils/logger"; import {TestLogger} from "./test-utils/logger.js";
import {clearCache} from "./utils/workflow-cache"; import {clearCache} from "./utils/workflow-cache.js";
import {ValueProviderConfig, ValueProviderKind} from "./value-providers/config"; import {ValueProviderConfig, ValueProviderKind} from "./value-providers/config.js";
registerLogger(new TestLogger()); registerLogger(new TestLogger());
+14 -14
View File
@@ -11,20 +11,20 @@ import {File} from "@actions/workflow-parser/workflows/file";
import {FileProvider} from "@actions/workflow-parser/workflows/file-provider"; import {FileProvider} from "@actions/workflow-parser/workflows/file-provider";
import {Position, TextDocument} from "vscode-languageserver-textdocument"; import {Position, TextDocument} from "vscode-languageserver-textdocument";
import {CompletionItem, CompletionItemKind, CompletionItemTag, Range, TextEdit} from "vscode-languageserver-types"; import {CompletionItem, CompletionItemKind, CompletionItemTag, Range, TextEdit} from "vscode-languageserver-types";
import {ContextProviderConfig} from "./context-providers/config"; import {ContextProviderConfig} from "./context-providers/config.js";
import {getContext, Mode} from "./context-providers/default"; import {getContext, Mode} from "./context-providers/default.js";
import {getWorkflowContext, WorkflowContext} from "./context/workflow-context"; import {getWorkflowContext, WorkflowContext} from "./context/workflow-context.js";
import {validatorFunctions} from "./expression-validation/functions"; import {validatorFunctions} from "./expression-validation/functions.js";
import {error} from "./log"; import {error} from "./log.js";
import {isPotentiallyExpression} from "./utils/expression-detection"; import {isPotentiallyExpression} from "./utils/expression-detection.js";
import {findToken} from "./utils/find-token"; import {findToken} from "./utils/find-token.js";
import {guessIndentation} from "./utils/indentation-guesser"; import {guessIndentation} from "./utils/indentation-guesser.js";
import {mapRange} from "./utils/range"; import {mapRange} from "./utils/range.js";
import {isPlaceholder, transform} from "./utils/transform"; import {isPlaceholder, transform} from "./utils/transform.js";
import {fetchOrConvertWorkflowTemplate, fetchOrParseWorkflow} from "./utils/workflow-cache"; import {fetchOrConvertWorkflowTemplate, fetchOrParseWorkflow} from "./utils/workflow-cache.js";
import {Value, ValueProviderConfig} from "./value-providers/config"; import {Value, ValueProviderConfig} from "./value-providers/config.js";
import {defaultValueProviders} from "./value-providers/default"; import {defaultValueProviders} from "./value-providers/default.js";
import {DefinitionValueMode, definitionValues} from "./value-providers/definition"; import {DefinitionValueMode, definitionValues} from "./value-providers/definition.js";
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
@@ -1,6 +1,6 @@
import {DescriptionDictionary} from "@actions/expressions"; import {DescriptionDictionary} from "@actions/expressions";
import {WorkflowContext} from "../context/workflow-context"; import {WorkflowContext} from "../context/workflow-context.js";
import {Mode} from "./default"; import {Mode} from "./default.js";
export type ContextProviderConfig = { export type ContextProviderConfig = {
getContext: ( getContext: (
@@ -1,6 +1,6 @@
import {DescriptionDictionary} from "@actions/expressions"; import {DescriptionDictionary} from "@actions/expressions";
import {WorkflowContext} from "../context/workflow-context"; import {WorkflowContext} from "../context/workflow-context.js";
import {getContext, Mode} from "./default"; import {getContext, Mode} from "./default.js";
describe("getContext", () => { describe("getContext", () => {
const emptyWorkflowContext: WorkflowContext = { const emptyWorkflowContext: WorkflowContext = {
@@ -1,18 +1,18 @@
import {data, DescriptionDictionary} from "@actions/expressions"; import {data, DescriptionDictionary} from "@actions/expressions";
import {Kind} from "@actions/expressions/data/expressiondata"; import {Kind} from "@actions/expressions/data/expressiondata";
import {WorkflowContext} from "../context/workflow-context"; import {WorkflowContext} from "../context/workflow-context.js";
import {ContextProviderConfig} from "./config"; import {ContextProviderConfig} from "./config.js";
import {getDescription, RootContext} from "./descriptions"; import {getDescription, RootContext} from "./descriptions.js";
import {getEnvContext} from "./env"; import {getEnvContext} from "./env.js";
import {getGithubContext} from "./github"; import {getGithubContext} from "./github.js";
import {getInputsContext} from "./inputs"; import {getInputsContext} from "./inputs.js";
import {getJobContext} from "./job"; import {getJobContext} from "./job.js";
import {getJobsContext} from "./jobs"; import {getJobsContext} from "./jobs.js";
import {getMatrixContext} from "./matrix"; import {getMatrixContext} from "./matrix.js";
import {getNeedsContext} from "./needs"; import {getNeedsContext} from "./needs.js";
import {getSecretsContext} from "./secrets"; import {getSecretsContext} from "./secrets.js";
import {getStepsContext} from "./steps"; import {getStepsContext} from "./steps.js";
import {getStrategyContext} from "./strategy"; import {getStrategyContext} from "./strategy.js";
// ContextValue is the type of the value returned by a context provider // ContextValue is the type of the value returned by a context provider
// Null indicates that the context provider doesn't have any value to provide // Null indicates that the context provider doesn't have any value to provide
+1 -1
View File
@@ -1,7 +1,7 @@
import {data, DescriptionDictionary} from "@actions/expressions"; import {data, DescriptionDictionary} from "@actions/expressions";
import {isScalar, isString} from "@actions/workflow-parser"; import {isScalar, isString} from "@actions/workflow-parser";
import {MappingToken} from "@actions/workflow-parser/templates/tokens/mapping-token"; import {MappingToken} from "@actions/workflow-parser/templates/tokens/mapping-token";
import {WorkflowContext} from "../context/workflow-context"; import {WorkflowContext} from "../context/workflow-context.js";
export function getEnvContext(workflowContext: WorkflowContext): DescriptionDictionary { export function getEnvContext(workflowContext: WorkflowContext): DescriptionDictionary {
const d = new DescriptionDictionary(); const d = new DescriptionDictionary();
@@ -1,5 +1,5 @@
import {DescriptionDictionary} from "@actions/expressions"; import {DescriptionDictionary} from "@actions/expressions";
import {getEventPayload, getSupportedEventTypes} from "./eventPayloads"; import {getEventPayload, getSupportedEventTypes} from "./eventPayloads.js";
describe("eventPayloads", () => { describe("eventPayloads", () => {
describe("getSupportedEventTypes", () => { describe("getSupportedEventTypes", () => {
@@ -1,7 +1,7 @@
import {DescriptionDictionary, isDescriptionDictionary} from "@actions/expressions/."; import {DescriptionDictionary, isDescriptionDictionary} from "@actions/expressions";
import {testGetWorkflowContext} from "../test-utils/test-workflow-context"; import {testGetWorkflowContext} from "../test-utils/test-workflow-context.js";
import {Mode} from "./default"; import {Mode} from "./default.js";
import {getGithubContext} from "./github"; import {getGithubContext} from "./github.js";
describe("github context", () => { describe("github context", () => {
it("single event", async () => { it("single event", async () => {
@@ -1,11 +1,11 @@
import {data, DescriptionDictionary, isDescriptionDictionary} from "@actions/expressions"; import {data, DescriptionDictionary, isDescriptionDictionary} from "@actions/expressions";
import {ExpressionData} from "@actions/expressions/data/expressiondata"; import {ExpressionData} from "@actions/expressions/data/expressiondata";
import {TypesFilterConfig} from "@actions/workflow-parser/model/workflow-template"; import {TypesFilterConfig} from "@actions/workflow-parser/model/workflow-template";
import {WorkflowContext} from "../context/workflow-context"; import {WorkflowContext} from "../context/workflow-context.js";
import {Mode} from "./default"; import {Mode} from "./default.js";
import {getDescription} from "./descriptions"; import {getDescription} from "./descriptions.js";
import {getEventPayload, getSupportedEventTypes} from "./events/eventPayloads"; import {getEventPayload, getSupportedEventTypes} from "./events/eventPayloads.js";
import {getInputsContext} from "./inputs"; import {getInputsContext} from "./inputs.js";
export function getGithubContext(workflowContext: WorkflowContext, mode: Mode): DescriptionDictionary { export function getGithubContext(workflowContext: WorkflowContext, mode: Mode): DescriptionDictionary {
// https://docs.github.com/en/actions/learn-github-actions/contexts#github-context // https://docs.github.com/en/actions/learn-github-actions/contexts#github-context
@@ -1,6 +1,6 @@
import {data, DescriptionDictionary} from "@actions/expressions"; import {data, DescriptionDictionary} from "@actions/expressions";
import {InputConfig} from "@actions/workflow-parser/model/workflow-template"; import {InputConfig} from "@actions/workflow-parser/model/workflow-template";
import {WorkflowContext} from "../context/workflow-context"; import {WorkflowContext} from "../context/workflow-context.js";
export function getInputsContext(workflowContext: WorkflowContext): DescriptionDictionary { export function getInputsContext(workflowContext: WorkflowContext): DescriptionDictionary {
const d = new DescriptionDictionary(); const d = new DescriptionDictionary();
+1 -1
View File
@@ -1,7 +1,7 @@
import {data, DescriptionDictionary} from "@actions/expressions"; import {data, DescriptionDictionary} from "@actions/expressions";
import {isMapping, isSequence} from "@actions/workflow-parser"; import {isMapping, isSequence} from "@actions/workflow-parser";
import {MappingToken} from "@actions/workflow-parser/templates/tokens/mapping-token"; import {MappingToken} from "@actions/workflow-parser/templates/tokens/mapping-token";
import {WorkflowContext} from "../context/workflow-context"; import {WorkflowContext} from "../context/workflow-context.js";
export function getJobContext(workflowContext: WorkflowContext): DescriptionDictionary { export function getJobContext(workflowContext: WorkflowContext): DescriptionDictionary {
// https://docs.github.com/en/actions/learn-github-actions/contexts#job-context // https://docs.github.com/en/actions/learn-github-actions/contexts#job-context
@@ -1,8 +1,8 @@
import {data, DescriptionDictionary} from "@actions/expressions"; import {data, DescriptionDictionary} from "@actions/expressions";
import {StringData} from "@actions/expressions/data/string"; import {StringData} from "@actions/expressions/data/string";
import {MappingToken} from "@actions/workflow-parser/templates/tokens/mapping-token"; import {MappingToken} from "@actions/workflow-parser/templates/tokens/mapping-token";
import {WorkflowContext} from "../context/workflow-context"; import {WorkflowContext} from "../context/workflow-context.js";
import {getDescription} from "./descriptions"; import {getDescription} from "./descriptions.js";
export function getJobsContext(workflowContext: WorkflowContext): DescriptionDictionary { export function getJobsContext(workflowContext: WorkflowContext): DescriptionDictionary {
// https://docs.github.com/en/actions/learn-github-actions/contexts#jobs-context // https://docs.github.com/en/actions/learn-github-actions/contexts#jobs-context
@@ -6,9 +6,9 @@ import {MappingToken} from "@actions/workflow-parser/templates/tokens/mapping-to
import {SequenceToken} from "@actions/workflow-parser/templates/tokens/sequence-token"; import {SequenceToken} from "@actions/workflow-parser/templates/tokens/sequence-token";
import {StringToken} from "@actions/workflow-parser/templates/tokens/string-token"; import {StringToken} from "@actions/workflow-parser/templates/tokens/string-token";
import {TemplateToken} from "@actions/workflow-parser/templates/tokens/template-token"; import {TemplateToken} from "@actions/workflow-parser/templates/tokens/template-token";
import {WorkflowContext} from "../context/workflow-context"; import {WorkflowContext} from "../context/workflow-context.js";
import {Mode} from "./default"; import {Mode} from "./default.js";
import {getMatrixContext} from "./matrix"; import {getMatrixContext} from "./matrix.js";
type MatrixMap = { type MatrixMap = {
[key: string]: Array<string> | Array<{[key: string]: string}>; [key: string]: Array<string> | Array<{[key: string]: string}>;
@@ -3,8 +3,8 @@ import {isBasicExpression, isMapping, isSequence, isString} from "@actions/workf
import {KeyValuePair} from "@actions/workflow-parser/templates/tokens/key-value-pair"; import {KeyValuePair} from "@actions/workflow-parser/templates/tokens/key-value-pair";
import {MappingToken} from "@actions/workflow-parser/templates/tokens/mapping-token"; import {MappingToken} from "@actions/workflow-parser/templates/tokens/mapping-token";
import {SequenceToken} from "@actions/workflow-parser/templates/tokens/sequence-token"; import {SequenceToken} from "@actions/workflow-parser/templates/tokens/sequence-token";
import {WorkflowContext} from "../context/workflow-context"; import {WorkflowContext} from "../context/workflow-context.js";
import {ContextValue, Mode} from "./default"; import {ContextValue, Mode} from "./default.js";
export function getMatrixContext(workflowContext: WorkflowContext, mode: Mode): ContextValue { export function getMatrixContext(workflowContext: WorkflowContext, mode: Mode): ContextValue {
// https://docs.github.com/en/actions/learn-github-actions/contexts#matrix-context // https://docs.github.com/en/actions/learn-github-actions/contexts#matrix-context
@@ -1,8 +1,8 @@
import {DescriptionDictionary} from "@actions/expressions"; import {DescriptionDictionary} from "@actions/expressions";
import {StringData} from "@actions/expressions/data/string"; import {StringData} from "@actions/expressions/data/string";
import {WorkflowContext} from "../context/workflow-context"; import {WorkflowContext} from "../context/workflow-context.js";
import {testGetWorkflowContext} from "../test-utils/test-workflow-context"; import {testGetWorkflowContext} from "../test-utils/test-workflow-context.js";
import {getNeedsContext} from "./needs"; import {getNeedsContext} from "./needs.js";
describe("needs context", () => { describe("needs context", () => {
describe("invalid workflow context", () => { describe("invalid workflow context", () => {
@@ -3,7 +3,7 @@ import {isMapping, isScalar, isString} from "@actions/workflow-parser";
import {isJob} from "@actions/workflow-parser/model/type-guards"; import {isJob} from "@actions/workflow-parser/model/type-guards";
import {WorkflowJob} from "@actions/workflow-parser/model/workflow-template"; import {WorkflowJob} from "@actions/workflow-parser/model/workflow-template";
import {TemplateToken} from "@actions/workflow-parser/templates/tokens/template-token"; import {TemplateToken} from "@actions/workflow-parser/templates/tokens/template-token";
import {WorkflowContext} from "../context/workflow-context"; import {WorkflowContext} from "../context/workflow-context.js";
export function getNeedsContext(workflowContext: WorkflowContext): DescriptionDictionary { export function getNeedsContext(workflowContext: WorkflowContext): DescriptionDictionary {
const d = new DescriptionDictionary(); const d = new DescriptionDictionary();
@@ -1,8 +1,8 @@
import {data, DescriptionDictionary} from "@actions/expressions"; import {data, DescriptionDictionary} from "@actions/expressions";
import {StringData} from "@actions/expressions/data/string"; import {StringData} from "@actions/expressions/data/string";
import {WorkflowContext} from "../context/workflow-context"; import {WorkflowContext} from "../context/workflow-context.js";
import {Mode} from "./default"; import {Mode} from "./default.js";
import {getDescription} from "./descriptions"; import {getDescription} from "./descriptions.js";
export function getSecretsContext(workflowContext: WorkflowContext, mode: Mode): DescriptionDictionary { export function getSecretsContext(workflowContext: WorkflowContext, mode: Mode): DescriptionDictionary {
const d = new DescriptionDictionary({ const d = new DescriptionDictionary({
@@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */ /* eslint-disable @typescript-eslint/no-non-null-assertion */
import {DescriptionDictionary, isDescriptionDictionary} from "@actions/expressions"; import {DescriptionDictionary, isDescriptionDictionary} from "@actions/expressions";
import {WorkflowContext} from "../context/workflow-context"; import {WorkflowContext} from "../context/workflow-context.js";
import {getStepsContext} from "./steps"; import {getStepsContext} from "./steps.js";
function createWorkflowContext(stepIds: string[], currentStepId?: string): WorkflowContext { function createWorkflowContext(stepIds: string[], currentStepId?: string): WorkflowContext {
return { return {
@@ -1,7 +1,7 @@
import {data, DescriptionDictionary} from "@actions/expressions"; import {data, DescriptionDictionary} from "@actions/expressions";
import {Step} from "@actions/workflow-parser/model/workflow-template"; import {Step} from "@actions/workflow-parser/model/workflow-template";
import {WorkflowContext} from "../context/workflow-context"; import {WorkflowContext} from "../context/workflow-context.js";
import {getDescription} from "./descriptions"; import {getDescription} from "./descriptions.js";
export function getStepsContext(workflowContext: WorkflowContext): DescriptionDictionary { export function getStepsContext(workflowContext: WorkflowContext): DescriptionDictionary {
const d = new DescriptionDictionary(); const d = new DescriptionDictionary();
@@ -5,8 +5,8 @@ import {MappingToken} from "@actions/workflow-parser/templates/tokens/mapping-to
import {NumberToken} from "@actions/workflow-parser/templates/tokens/number-token"; import {NumberToken} from "@actions/workflow-parser/templates/tokens/number-token";
import {StringToken} from "@actions/workflow-parser/templates/tokens/string-token"; import {StringToken} from "@actions/workflow-parser/templates/tokens/string-token";
import {TemplateToken} from "@actions/workflow-parser/templates/tokens/template-token"; import {TemplateToken} from "@actions/workflow-parser/templates/tokens/template-token";
import {WorkflowContext} from "../context/workflow-context"; import {WorkflowContext} from "../context/workflow-context.js";
import {getStrategyContext} from "./strategy"; import {getStrategyContext} from "./strategy.js";
function stringToToken(value: string) { function stringToToken(value: string) {
return new StringToken(undefined, undefined, value, undefined); return new StringToken(undefined, undefined, value, undefined);
@@ -1,7 +1,7 @@
import {data, DescriptionDictionary} from "@actions/expressions"; import {data, DescriptionDictionary} from "@actions/expressions";
import {isMapping, isScalar, isString} from "@actions/workflow-parser"; import {isMapping, isScalar, isString} from "@actions/workflow-parser";
import {WorkflowContext} from "../context/workflow-context"; import {WorkflowContext} from "../context/workflow-context.js";
import {scalarToData} from "../utils/scalar-to-data"; import {scalarToData} from "../utils/scalar-to-data.js";
// Default strategy values when no strategy block is defined // Default strategy values when no strategy block is defined
const DEFAULT_STRATEGY = { const DEFAULT_STRATEGY = {
@@ -1,5 +1,5 @@
import {ActionStep, RunStep} from "@actions/workflow-parser/model/workflow-template"; import {ActionStep, RunStep} from "@actions/workflow-parser/model/workflow-template";
import {testGetWorkflowContext} from "../test-utils/test-workflow-context"; import {testGetWorkflowContext} from "../test-utils/test-workflow-context.js";
describe("getWorkflowContext", () => { describe("getWorkflowContext", () => {
it("context for workflow", async () => { it("context for workflow", async () => {
@@ -1,7 +1,7 @@
import {isMapping, isString} from "@actions/workflow-parser"; import {isMapping, isString} from "@actions/workflow-parser";
import {DESCRIPTION} from "@actions/workflow-parser/templates/template-constants"; import {DESCRIPTION} from "@actions/workflow-parser/templates/template-constants";
import {WorkflowContext} from "../context/workflow-context"; import {WorkflowContext} from "../context/workflow-context.js";
import {TokenResult} from "../utils/find-token"; import {TokenResult} from "../utils/find-token.js";
export function isReusableWorkflowJobInput(tokenResult: TokenResult): boolean { export function isReusableWorkflowJobInput(tokenResult: TokenResult): boolean {
return ( return (
+3 -3
View File
@@ -1,6 +1,6 @@
import {documentLinks} from "./document-links"; import {documentLinks} from "./document-links.js";
import {createDocument} from "./test-utils/document"; import {createDocument} from "./test-utils/document.js";
import {clearCache} from "./utils/workflow-cache"; import {clearCache} from "./utils/workflow-cache.js";
beforeEach(() => { beforeEach(() => {
clearCache(); clearCache();
+3 -3
View File
@@ -5,9 +5,9 @@ import {parseFileReference} from "@actions/workflow-parser/workflows/file-refere
import {TextDocument} from "vscode-languageserver-textdocument"; import {TextDocument} from "vscode-languageserver-textdocument";
import {DocumentLink} from "vscode-languageserver-types"; import {DocumentLink} from "vscode-languageserver-types";
import * as vscodeURI from "vscode-uri"; import * as vscodeURI from "vscode-uri";
import {actionUrl, parseActionReference} from "./action"; import {actionUrl, parseActionReference} from "./action.js";
import {mapRange} from "./utils/range"; import {mapRange} from "./utils/range.js";
import {fetchOrConvertWorkflowTemplate, fetchOrParseWorkflow} from "./utils/workflow-cache"; import {fetchOrConvertWorkflowTemplate, fetchOrParseWorkflow} from "./utils/workflow-cache.js";
export async function documentLinks(document: TextDocument, workspace: string | undefined): Promise<DocumentLink[]> { export async function documentLinks(document: TextDocument, workspace: string | undefined): Promise<DocumentLink[]> {
const file: File = { const file: File = {
+6 -6
View File
@@ -1,9 +1,9 @@
import {complete} from "./complete"; import {complete} from "./complete.js";
import {hover} from "./hover"; import {hover} from "./hover.js";
import {registerLogger} from "./log"; import {registerLogger} from "./log.js";
import {getPositionFromCursor} from "./test-utils/cursor-position"; import {getPositionFromCursor} from "./test-utils/cursor-position.js";
import {TestLogger} from "./test-utils/logger"; import {TestLogger} from "./test-utils/logger.js";
import {clearCache} from "./utils/workflow-cache"; import {clearCache} from "./utils/workflow-cache.js";
registerLogger(new TestLogger()); registerLogger(new TestLogger());
@@ -1,9 +1,9 @@
import {parseWorkflow} from "@actions/workflow-parser"; import {parseWorkflow} from "@actions/workflow-parser";
import {File} from "@actions/workflow-parser/workflows/file"; import {File} from "@actions/workflow-parser/workflows/file";
import {nullTrace} from "../nulltrace"; import {nullTrace} from "../nulltrace.js";
import {getPositionFromCursor} from "../test-utils/cursor-position"; import {getPositionFromCursor} from "../test-utils/cursor-position.js";
import {findToken} from "../utils/find-token"; import {findToken} from "../utils/find-token.js";
import {ExpressionPos, mapToExpressionPos} from "./expression-pos"; import {ExpressionPos, mapToExpressionPos} from "./expression-pos.js";
describe("mapToExpressionPos", () => { describe("mapToExpressionPos", () => {
it("simple expression", () => { it("simple expression", () => {
@@ -3,8 +3,8 @@ import {ensureStatusFunction} from "@actions/workflow-parser/model/converter/if-
import {TemplateToken} from "@actions/workflow-parser/templates/tokens/template-token"; import {TemplateToken} from "@actions/workflow-parser/templates/tokens/template-token";
import {isBasicExpression, isString} from "@actions/workflow-parser/templates/tokens/type-guards"; import {isBasicExpression, isString} from "@actions/workflow-parser/templates/tokens/type-guards";
import {Position, Range as LSPRange} from "vscode-languageserver-textdocument"; import {Position, Range as LSPRange} from "vscode-languageserver-textdocument";
import {mapRange} from "../utils/range"; import {mapRange} from "../utils/range.js";
import {posWithinRange} from "./pos-range"; import {posWithinRange} from "./pos-range.js";
export type ExpressionPos = { export type ExpressionPos = {
/** The expression that includes the position */ /** The expression that includes the position */
@@ -2,13 +2,13 @@ import {data, DescriptionDictionary, Lexer, Parser} from "@actions/expressions";
import {convertWorkflowTemplate, parseWorkflow} from "@actions/workflow-parser"; import {convertWorkflowTemplate, parseWorkflow} from "@actions/workflow-parser";
import {ErrorPolicy} from "@actions/workflow-parser/model/convert"; import {ErrorPolicy} from "@actions/workflow-parser/model/convert";
import {File} from "@actions/workflow-parser/workflows/file"; import {File} from "@actions/workflow-parser/workflows/file";
import {ContextProviderConfig} from "../context-providers/config"; import {ContextProviderConfig} from "../context-providers/config.js";
import {getContext, Mode} from "../context-providers/default"; import {getContext, Mode} from "../context-providers/default.js";
import {getWorkflowContext} from "../context/workflow-context"; import {getWorkflowContext} from "../context/workflow-context.js";
import {validatorFunctions} from "../expression-validation/functions"; import {validatorFunctions} from "../expression-validation/functions.js";
import {nullTrace} from "../nulltrace"; import {nullTrace} from "../nulltrace.js";
import {getPositionFromCursor} from "../test-utils/cursor-position"; import {getPositionFromCursor} from "../test-utils/cursor-position.js";
import {HoverVisitor} from "./visitor"; import {HoverVisitor} from "./visitor.js";
const contextProviderConfig: ContextProviderConfig = { const contextProviderConfig: ContextProviderConfig = {
getContext: (context: string) => { getContext: (context: string) => {
@@ -13,7 +13,7 @@ import {
} from "@actions/expressions/ast"; } from "@actions/expressions/ast";
import {FunctionDefinition} from "@actions/expressions/funcs/info"; import {FunctionDefinition} from "@actions/expressions/funcs/info";
import {Pos, Range} from "@actions/expressions/lexer"; import {Pos, Range} from "@actions/expressions/lexer";
import {posWithinRange} from "./pos-range"; import {posWithinRange} from "./pos-range.js";
export type HoverResult = export type HoverResult =
| undefined | undefined
@@ -3,7 +3,7 @@ import {Expr, Logical} from "@actions/expressions/ast";
import {ExpressionData} from "@actions/expressions/data/expressiondata"; import {ExpressionData} from "@actions/expressions/data/expressiondata";
import {TokenType} from "@actions/expressions/lexer"; import {TokenType} from "@actions/expressions/lexer";
import {falsy, truthy} from "@actions/expressions/result"; import {falsy, truthy} from "@actions/expressions/result";
import {AccessError} from "./error-dictionary"; import {AccessError} from "./error-dictionary.js";
export type ValidationError = { export type ValidationError = {
message: string; message: string;
@@ -1,12 +1,12 @@
import {data, DescriptionDictionary} from "@actions/expressions"; import {data, DescriptionDictionary} from "@actions/expressions";
import {format} from "@actions/expressions/funcs/format"; import {format} from "@actions/expressions/funcs/format";
import {Hover} from "vscode-languageserver-types"; import {Hover} from "vscode-languageserver-types";
import {ContextProviderConfig} from "./context-providers/config"; import {ContextProviderConfig} from "./context-providers/config.js";
import {hover} from "./hover"; import {hover} from "./hover.js";
import {registerLogger} from "./log"; import {registerLogger} from "./log.js";
import {getPositionFromCursor} from "./test-utils/cursor-position"; import {getPositionFromCursor} from "./test-utils/cursor-position.js";
import {TestLogger} from "./test-utils/logger"; import {TestLogger} from "./test-utils/logger.js";
import {clearCache} from "./utils/workflow-cache"; import {clearCache} from "./utils/workflow-cache.js";
const contextProviderConfig: ContextProviderConfig = { const contextProviderConfig: ContextProviderConfig = {
getContext: (context: string) => { getContext: (context: string) => {
@@ -1,7 +1,7 @@
import {hover} from "./hover"; import {hover} from "./hover.js";
import {testHoverConfig} from "./hover.test"; import {testHoverConfig} from "./hover.test.js";
import {getPositionFromCursor} from "./test-utils/cursor-position"; import {getPositionFromCursor} from "./test-utils/cursor-position.js";
import {clearCache} from "./utils/workflow-cache"; import {clearCache} from "./utils/workflow-cache.js";
beforeEach(() => { beforeEach(() => {
clearCache(); clearCache();
+4 -4
View File
@@ -1,8 +1,8 @@
import {isString} from "@actions/workflow-parser"; import {isString} from "@actions/workflow-parser";
import {DescriptionProvider, hover, HoverConfig} from "./hover"; import {DescriptionProvider, hover, HoverConfig} from "./hover.js";
import {getPositionFromCursor} from "./test-utils/cursor-position"; import {getPositionFromCursor} from "./test-utils/cursor-position.js";
import {testFileProvider} from "./test-utils/test-file-provider"; import {testFileProvider} from "./test-utils/test-file-provider.js";
import {clearCache} from "./utils/workflow-cache"; import {clearCache} from "./utils/workflow-cache.js";
export function testHoverConfig(tokenValue: string, tokenKey: string, description?: string) { export function testHoverConfig(tokenValue: string, tokenKey: string, description?: string) {
return { return {
+12 -12
View File
@@ -9,21 +9,21 @@ import {File} from "@actions/workflow-parser/workflows/file";
import {FileProvider} from "@actions/workflow-parser/workflows/file-provider"; import {FileProvider} from "@actions/workflow-parser/workflows/file-provider";
import {Position, TextDocument} from "vscode-languageserver-textdocument"; import {Position, TextDocument} from "vscode-languageserver-textdocument";
import {Hover} from "vscode-languageserver-types"; import {Hover} from "vscode-languageserver-types";
import {ContextProviderConfig} from "./context-providers/config"; import {ContextProviderConfig} from "./context-providers/config.js";
import {getContext, Mode} from "./context-providers/default"; import {getContext, Mode} from "./context-providers/default.js";
import {getFunctionDescription} from "./context-providers/descriptions"; import {getFunctionDescription} from "./context-providers/descriptions.js";
import {getWorkflowContext, WorkflowContext} from "./context/workflow-context"; import {getWorkflowContext, WorkflowContext} from "./context/workflow-context.js";
import { import {
getReusableWorkflowInputDescription, getReusableWorkflowInputDescription,
isReusableWorkflowJobInput isReusableWorkflowJobInput
} from "./description-providers/reusable-job-inputs"; } from "./description-providers/reusable-job-inputs.js";
import {ExpressionPos, mapToExpressionPos} from "./expression-hover/expression-pos"; import {ExpressionPos, mapToExpressionPos} from "./expression-hover/expression-pos.js";
import {HoverVisitor} from "./expression-hover/visitor"; import {HoverVisitor} from "./expression-hover/visitor.js";
import {info} from "./log"; import {info} from "./log.js";
import {isPotentiallyExpression} from "./utils/expression-detection"; import {isPotentiallyExpression} from "./utils/expression-detection.js";
import {findToken} from "./utils/find-token"; import {findToken} from "./utils/find-token.js";
import {mapRange} from "./utils/range"; import {mapRange} from "./utils/range.js";
import {fetchOrConvertWorkflowTemplate, fetchOrParseWorkflow} from "./utils/workflow-cache"; import {fetchOrConvertWorkflowTemplate, fetchOrParseWorkflow} from "./utils/workflow-cache.js";
export type HoverConfig = { export type HoverConfig = {
descriptionProvider?: DescriptionProvider; descriptionProvider?: DescriptionProvider;
+7 -7
View File
@@ -1,7 +1,7 @@
export {complete} from "./complete"; export {complete} from "./complete.js";
export {ContextProviderConfig} from "./context-providers/config"; export {ContextProviderConfig} from "./context-providers/config.js";
export {documentLinks} from "./document-links"; export {documentLinks} from "./document-links.js";
export {hover} from "./hover"; export {hover} from "./hover.js";
export {Logger, LogLevel, registerLogger, setLogLevel} from "./log"; export {Logger, LogLevel, registerLogger, setLogLevel} from "./log.js";
export {validate, ValidationConfig, ActionsMetadataProvider} from "./validate"; export {validate, ValidationConfig, ActionsMetadataProvider} from "./validate.js";
export {ValueProviderConfig, ValueProviderKind} from "./value-providers/config"; export {ValueProviderConfig, ValueProviderKind} from "./value-providers/config.js";
@@ -1,5 +1,5 @@
import {clearCache} from "../utils/workflow-cache"; import {clearCache} from "../utils/workflow-cache.js";
import {getPositionFromCursor} from "./cursor-position"; import {getPositionFromCursor} from "./cursor-position.js";
beforeEach(() => { beforeEach(() => {
clearCache(); clearCache();
@@ -1,5 +1,5 @@
import {Position, TextDocument} from "vscode-languageserver-textdocument"; import {Position, TextDocument} from "vscode-languageserver-textdocument";
import {createDocument} from "./document"; import {createDocument} from "./document.js";
/** /**
* Calculates the position of the cursor and the document without that cursor * Calculates the position of the cursor and the document without that cursor
+1 -1
View File
@@ -1,4 +1,4 @@
import {Logger} from "../log"; import {Logger} from "../log.js";
export class TestLogger implements Logger { export class TestLogger implements Logger {
error(message: string): void { error(message: string): void {
@@ -1,9 +1,9 @@
import {convertWorkflowTemplate, parseWorkflow, WorkflowTemplate} from "@actions/workflow-parser"; import {convertWorkflowTemplate, parseWorkflow, WorkflowTemplate} from "@actions/workflow-parser";
import {getWorkflowContext, WorkflowContext} from "../context/workflow-context"; import {getWorkflowContext, WorkflowContext} from "../context/workflow-context.js";
import {nullTrace} from "../nulltrace"; import {nullTrace} from "../nulltrace.js";
import {findToken} from "../utils/find-token"; import {findToken} from "../utils/find-token.js";
import {getPositionFromCursor} from "./cursor-position"; import {getPositionFromCursor} from "./cursor-position.js";
import {testFileProvider} from "./test-file-provider"; import {testFileProvider} from "./test-file-provider.js";
export async function testGetWorkflowContext(input: string): Promise<WorkflowContext> { export async function testGetWorkflowContext(input: string): Promise<WorkflowContext> {
const [textDocument, pos] = getPositionFromCursor(input); const [textDocument, pos] = getPositionFromCursor(input);
+3 -3
View File
@@ -1,9 +1,9 @@
import {isScalar, parseWorkflow} from "@actions/workflow-parser"; import {isScalar, parseWorkflow} from "@actions/workflow-parser";
import {TemplateToken} from "@actions/workflow-parser/templates/tokens/template-token"; import {TemplateToken} from "@actions/workflow-parser/templates/tokens/template-token";
import {TokenType} from "@actions/workflow-parser/templates/tokens/types"; import {TokenType} from "@actions/workflow-parser/templates/tokens/types";
import {nullTrace} from "../nulltrace"; import {nullTrace} from "../nulltrace.js";
import {getPositionFromCursor} from "../test-utils/cursor-position"; import {getPositionFromCursor} from "../test-utils/cursor-position.js";
import {findToken} from "./find-token"; import {findToken} from "./find-token.js";
type testTokenInfo = [definitionKey: string | null, tokenType: TokenType, literalValue?: string]; type testTokenInfo = [definitionKey: string | null, tokenType: TokenType, literalValue?: string];
+2 -2
View File
@@ -1,5 +1,5 @@
import {getPositionFromCursor} from "../test-utils/cursor-position"; import {getPositionFromCursor} from "../test-utils/cursor-position.js";
import {transform} from "./transform"; import {transform} from "./transform.js";
describe("transform", () => { describe("transform", () => {
it("adds : at end of line", () => { it("adds : at end of line", () => {
+2 -2
View File
@@ -4,8 +4,8 @@ import {TemplateContext} from "@actions/workflow-parser/templates/template-conte
import {TemplateToken} from "@actions/workflow-parser/templates/tokens/template-token"; import {TemplateToken} from "@actions/workflow-parser/templates/tokens/template-token";
import {File} from "@actions/workflow-parser/workflows/file"; import {File} from "@actions/workflow-parser/workflows/file";
import {CompletionConfig} from "../complete"; import {CompletionConfig} from "../complete.js";
import {nullTrace} from "../nulltrace"; import {nullTrace} from "../nulltrace.js";
const parsedWorkflowCache = new Map<string, ParseWorkflowResult>(); const parsedWorkflowCache = new Map<string, ParseWorkflowResult>();
const workflowTemplateCache = new Map<string, WorkflowTemplate>(); const workflowTemplateCache = new Map<string, WorkflowTemplate>();
+3 -3
View File
@@ -4,9 +4,9 @@ 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 {parseActionReference} from "./action.js";
import {mapRange} from "./utils/range"; import {mapRange} from "./utils/range.js";
import {ValidationConfig} from "./validate"; import {ValidationConfig} from "./validate.js";
export async function validateAction( export async function validateAction(
diagnostics: Diagnostic[], diagnostics: Diagnostic[],
+7 -7
View File
@@ -1,11 +1,11 @@
import {DiagnosticSeverity} from "vscode-languageserver-types"; import {DiagnosticSeverity} from "vscode-languageserver-types";
import {ActionMetadata, ActionReference} from "./action"; import {ActionMetadata, ActionReference} from "./action.js";
import {registerLogger} from "./log"; import {registerLogger} from "./log.js";
import {createDocument} from "./test-utils/document"; import {createDocument} from "./test-utils/document.js";
import {TestLogger} from "./test-utils/logger"; import {TestLogger} from "./test-utils/logger.js";
import {validate, ValidationConfig} from "./validate"; import {validate, ValidationConfig} from "./validate.js";
import {ValueProviderKind} from "./value-providers/config"; import {ValueProviderKind} from "./value-providers/config.js";
import {clearCache} from "./utils/workflow-cache"; import {clearCache} from "./utils/workflow-cache.js";
registerLogger(new TestLogger()); registerLogger(new TestLogger());
@@ -1,7 +1,7 @@
import {DiagnosticSeverity} from "vscode-languageserver-types"; import {DiagnosticSeverity} from "vscode-languageserver-types";
import {validate} from "./validate"; import {validate} from "./validate.js";
import {createDocument} from "./test-utils/document"; import {createDocument} from "./test-utils/document.js";
import {clearCache} from "./utils/workflow-cache"; import {clearCache} from "./utils/workflow-cache.js";
beforeEach(() => { beforeEach(() => {
clearCache(); clearCache();
@@ -1,9 +1,9 @@
import {DiagnosticSeverity} from "vscode-languageserver-types"; import {DiagnosticSeverity} from "vscode-languageserver-types";
import {registerLogger} from "./log"; import {registerLogger} from "./log.js";
import {createDocument} from "./test-utils/document"; import {createDocument} from "./test-utils/document.js";
import {TestLogger} from "./test-utils/logger"; import {TestLogger} from "./test-utils/logger.js";
import {clearCache} from "./utils/workflow-cache"; import {clearCache} from "./utils/workflow-cache.js";
import {validate} from "./validate"; import {validate} from "./validate.js";
registerLogger(new TestLogger()); registerLogger(new TestLogger());
@@ -1,11 +1,11 @@
import {DescriptionDictionary} from "@actions/expressions/."; import {DescriptionDictionary} from "@actions/expressions";
import {DiagnosticSeverity} from "vscode-languageserver-types"; import {DiagnosticSeverity} from "vscode-languageserver-types";
import {ContextProviderConfig} from "./context-providers/config"; import {ContextProviderConfig} from "./context-providers/config.js";
import {registerLogger} from "./log"; import {registerLogger} from "./log.js";
import {createDocument} from "./test-utils/document"; import {createDocument} from "./test-utils/document.js";
import {TestLogger} from "./test-utils/logger"; import {TestLogger} from "./test-utils/logger.js";
import {clearCache} from "./utils/workflow-cache"; import {clearCache} from "./utils/workflow-cache.js";
import {validate, ValidationConfig} from "./validate"; import {validate, ValidationConfig} from "./validate.js";
registerLogger(new TestLogger()); registerLogger(new TestLogger());
@@ -9,9 +9,9 @@
* to fetch secrets/vars are not possible. * to fetch secrets/vars are not possible.
*/ */
import {validate} from "./validate"; import {validate} from "./validate.js";
import {createDocument} from "./test-utils/document"; import {createDocument} from "./test-utils/document.js";
import {clearCache} from "./utils/workflow-cache"; import {clearCache} from "./utils/workflow-cache.js";
beforeEach(() => { beforeEach(() => {
clearCache(); clearCache();
+5 -5
View File
@@ -1,9 +1,9 @@
import {Diagnostic, DiagnosticSeverity} from "vscode-languageserver-types"; import {Diagnostic, DiagnosticSeverity} from "vscode-languageserver-types";
import {createDocument} from "./test-utils/document"; import {createDocument} from "./test-utils/document.js";
import {validate} from "./validate"; import {validate} from "./validate.js";
import {defaultValueProviders} from "./value-providers/default"; import {defaultValueProviders} from "./value-providers/default.js";
import {clearCache} from "./utils/workflow-cache"; import {clearCache} from "./utils/workflow-cache.js";
import {ValueProviderConfig, ValueProviderKind} from "./value-providers/config"; import {ValueProviderConfig, ValueProviderKind} from "./value-providers/config.js";
beforeEach(() => { beforeEach(() => {
clearCache(); clearCache();
+14 -14
View File
@@ -13,20 +13,20 @@ import {File} from "@actions/workflow-parser/workflows/file";
import {FileProvider} from "@actions/workflow-parser/workflows/file-provider"; import {FileProvider} from "@actions/workflow-parser/workflows/file-provider";
import {TextDocument} from "vscode-languageserver-textdocument"; import {TextDocument} from "vscode-languageserver-textdocument";
import {Diagnostic, DiagnosticSeverity, URI} from "vscode-languageserver-types"; import {Diagnostic, DiagnosticSeverity, URI} from "vscode-languageserver-types";
import {ActionMetadata, ActionReference} from "./action"; import {ActionMetadata, ActionReference} from "./action.js";
import {ContextProviderConfig} from "./context-providers/config"; import {ContextProviderConfig} from "./context-providers/config.js";
import {Mode, getContext} from "./context-providers/default"; import {Mode, getContext} from "./context-providers/default.js";
import {WorkflowContext, getWorkflowContext} from "./context/workflow-context"; import {WorkflowContext, getWorkflowContext} from "./context/workflow-context.js";
import {wrapDictionary} from "./expression-validation/error-dictionary"; import {wrapDictionary} from "./expression-validation/error-dictionary.js";
import {ValidationEvaluator} from "./expression-validation/evaluator"; import {ValidationEvaluator} from "./expression-validation/evaluator.js";
import {validatorFunctions} from "./expression-validation/functions"; import {validatorFunctions} from "./expression-validation/functions.js";
import {error} from "./log"; import {error} from "./log.js";
import {findToken} from "./utils/find-token"; import {findToken} from "./utils/find-token.js";
import {mapRange} from "./utils/range"; import {mapRange} from "./utils/range.js";
import {fetchOrConvertWorkflowTemplate, fetchOrParseWorkflow} from "./utils/workflow-cache"; import {fetchOrConvertWorkflowTemplate, fetchOrParseWorkflow} from "./utils/workflow-cache.js";
import {validateAction} from "./validate-action"; import {validateAction} from "./validate-action.js";
import {ValueProviderConfig, ValueProviderKind} from "./value-providers/config"; import {ValueProviderConfig, ValueProviderKind} from "./value-providers/config.js";
import {defaultValueProviders} from "./value-providers/default"; import {defaultValueProviders} from "./value-providers/default.js";
const CRON_SCHEDULE_DOCS_URL = const CRON_SCHEDULE_DOCS_URL =
"https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions#onschedule"; "https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions#onschedule";
@@ -1,7 +1,7 @@
import {DiagnosticSeverity} from "vscode-languageserver-types"; import {DiagnosticSeverity} from "vscode-languageserver-types";
import {validate} from "./validate"; import {validate} from "./validate.js";
import {createDocument} from "./test-utils/document"; import {createDocument} from "./test-utils/document.js";
import {clearCache} from "./utils/workflow-cache"; import {clearCache} from "./utils/workflow-cache.js";
beforeEach(() => { beforeEach(() => {
clearCache(); clearCache();

Some files were not shown because too many files have changed in this diff Show More