Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec7109a487 | ||
|
|
929faacbc4 | ||
|
|
f964e5a42d | ||
|
|
1d7389f3e8 |
@@ -0,0 +1,167 @@
|
||||
name: Publish Action Release
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
action-directory:
|
||||
required: true
|
||||
type: string
|
||||
description: 'Path to the action directory (e.g., github-actions/bundle-script)'
|
||||
package-json-path:
|
||||
required: true
|
||||
type: string
|
||||
description: 'Path to package.json relative to repo root'
|
||||
action-name:
|
||||
required: true
|
||||
type: string
|
||||
description: 'Name of the action for display purposes'
|
||||
prefix:
|
||||
required: true
|
||||
type: string
|
||||
description: 'Prefix for version tags (e.g., bundle-script will create tags like bundle-script/v1.0.0)'
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
derive_release:
|
||||
name: Derive release metadata
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ steps.derive.outputs.version }}
|
||||
release_tag: ${{ steps.derive.outputs.release_tag }}
|
||||
rolling_minor_tag: ${{ steps.derive.outputs.rolling_minor_tag }}
|
||||
rolling_major_tag: ${{ steps.derive.outputs.rolling_major_tag }}
|
||||
bump_kind: ${{ steps.derive.outputs.bump_kind }}
|
||||
should_publish: ${{ steps.derive.outputs.should_publish }}
|
||||
latest_release_tag: ${{ steps.derive.outputs.latest_release_tag }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Derive version and tags
|
||||
id: derive
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
version=$(node -p "require('./${{ inputs.package-json-path }}').version")
|
||||
if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
echo "${{ inputs.action-name }}/package.json version must be semver X.Y.Z, got: $version" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
IFS='.' read -r major minor patch <<< "$version"
|
||||
release_tag="${{ inputs.prefix }}/v${version}"
|
||||
rolling_minor_tag="${{ inputs.prefix }}/v${major}.${minor}"
|
||||
rolling_major_tag="${{ inputs.prefix }}/v${major}"
|
||||
|
||||
latest_release_tag=$(git tag --list '${{ inputs.prefix }}/v*.*.*' --sort=-version:refname | head -n 1)
|
||||
|
||||
bump_kind="initial"
|
||||
should_publish="true"
|
||||
|
||||
if [[ -n "$latest_release_tag" ]]; then
|
||||
latest_version=${latest_release_tag#${{ inputs.prefix }}/v}
|
||||
|
||||
if [[ "$version" == "$latest_version" ]]; then
|
||||
should_publish="false"
|
||||
bump_kind="duplicate"
|
||||
else
|
||||
IFS='.' read -r latest_major latest_minor latest_patch <<< "$latest_version"
|
||||
|
||||
if (( major < latest_major )) || \
|
||||
(( major == latest_major && minor < latest_minor )) || \
|
||||
(( major == latest_major && minor == latest_minor && patch < latest_patch )); then
|
||||
echo "${{ inputs.action-name }}/package.json version $version must be greater than latest published $latest_version" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if (( major > latest_major )); then
|
||||
bump_kind="major"
|
||||
elif (( minor > latest_minor )); then
|
||||
bump_kind="minor"
|
||||
elif (( patch > latest_patch )); then
|
||||
bump_kind="patch"
|
||||
else
|
||||
echo "Unable to derive release kind from $latest_version -> $version" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "version=$version" >> "$GITHUB_OUTPUT"
|
||||
echo "release_tag=$release_tag" >> "$GITHUB_OUTPUT"
|
||||
echo "rolling_minor_tag=$rolling_minor_tag" >> "$GITHUB_OUTPUT"
|
||||
echo "rolling_major_tag=$rolling_major_tag" >> "$GITHUB_OUTPUT"
|
||||
echo "bump_kind=$bump_kind" >> "$GITHUB_OUTPUT"
|
||||
echo "should_publish=$should_publish" >> "$GITHUB_OUTPUT"
|
||||
echo "latest_release_tag=$latest_release_tag" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Summarize release plan
|
||||
shell: bash
|
||||
run: |
|
||||
{
|
||||
echo "## ${{ inputs.action-name }} release plan"
|
||||
echo ""
|
||||
echo "- Version: ${{ steps.derive.outputs.version }}"
|
||||
echo "- Release tag: ${{ steps.derive.outputs.release_tag }}"
|
||||
echo "- Rolling minor tag: ${{ steps.derive.outputs.rolling_minor_tag }}"
|
||||
echo "- Rolling major tag: ${{ steps.derive.outputs.rolling_major_tag }}"
|
||||
echo "- Bump kind: ${{ steps.derive.outputs.bump_kind }}"
|
||||
echo "- Latest published tag: ${{ steps.derive.outputs.latest_release_tag || 'none' }}"
|
||||
echo "- Will publish: ${{ steps.derive.outputs.should_publish }}"
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
publish_tags:
|
||||
name: Publish tags
|
||||
runs-on: ubuntu-latest
|
||||
needs: derive_release
|
||||
if: ${{ needs.derive_release.outputs.should_publish == 'true' }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Create immutable release tag
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
release_tag='${{ needs.derive_release.outputs.release_tag }}'
|
||||
|
||||
if git rev-parse "$release_tag" >/dev/null 2>&1; then
|
||||
echo "Release tag $release_tag already exists" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git tag "$release_tag" "$GITHUB_SHA"
|
||||
|
||||
- name: Update rolling tags
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
git tag -f '${{ needs.derive_release.outputs.rolling_minor_tag }}' "$GITHUB_SHA"
|
||||
git tag -f '${{ needs.derive_release.outputs.rolling_major_tag }}' "$GITHUB_SHA"
|
||||
|
||||
- name: Push release tags
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
git push origin '${{ needs.derive_release.outputs.release_tag }}'
|
||||
git push origin '${{ needs.derive_release.outputs.rolling_minor_tag }}' --force
|
||||
git push origin '${{ needs.derive_release.outputs.rolling_major_tag }}' --force
|
||||
|
||||
- name: Summarize published tags
|
||||
shell: bash
|
||||
run: |
|
||||
{
|
||||
echo "## Published ${{ inputs.action-name }} tags"
|
||||
echo ""
|
||||
echo "- Immutable: ${{ needs.derive_release.outputs.release_tag }}"
|
||||
echo "- Rolling minor: ${{ needs.derive_release.outputs.rolling_minor_tag }}"
|
||||
echo "- Rolling major: ${{ needs.derive_release.outputs.rolling_major_tag }}"
|
||||
echo "- Bump kind: ${{ needs.derive_release.outputs.bump_kind }}"
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
@@ -0,0 +1,20 @@
|
||||
name: Publish Bundle Script Action
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- github-actions/bundle-script/package.json
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
publish_action:
|
||||
uses: ./.github/workflows/_publish-action-release.yml
|
||||
with:
|
||||
action-directory: github-actions/bundle-script
|
||||
package-json-path: github-actions/bundle-script/package.json
|
||||
action-name: Bundle Script
|
||||
prefix: bundle-script
|
||||
@@ -0,0 +1,20 @@
|
||||
name: Publish Install Lua Addon Action
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- github-actions/install-lua-addon/package.json
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
publish_action:
|
||||
uses: ./.github/workflows/_publish-action-release.yml
|
||||
with:
|
||||
action-directory: github-actions/install-lua-addon
|
||||
package-json-path: github-actions/install-lua-addon/package.json
|
||||
action-name: Install Lua Addon
|
||||
prefix: install-lua-addon
|
||||
Vendored
+1
@@ -19,6 +19,7 @@
|
||||
"label": "watch",
|
||||
"type": "npm",
|
||||
"script": "watch",
|
||||
"dependsOn": "compile",
|
||||
"isBackground": true,
|
||||
"presentation": {
|
||||
"reveal": "never"
|
||||
|
||||
@@ -22,8 +22,9 @@ Get the extension here: https://marketplace.visualstudio.com/items?itemName=dutc
|
||||
### Features:
|
||||
|
||||
- [x] Compile the mission script just like in the VS Code extension, but in a Github Action.
|
||||
- [x] Install Lua addons and type definitions for scripting linter support on agents
|
||||
|
||||
### Usage:
|
||||
### Compile Script:
|
||||
|
||||
```yaml
|
||||
|
||||
@@ -47,3 +48,18 @@ jobs:
|
||||
|
||||
|
||||
```
|
||||
|
||||
### Add Lua Types
|
||||
|
||||
```yaml
|
||||
name: Install Lua Addons
|
||||
on: [push]
|
||||
jobs:
|
||||
install-lua-addons:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dutchie031/DcsMissionScriptingTools/github-actions/install-lua-addon@action/v1
|
||||
with:
|
||||
destination-path: 'lua-addons'
|
||||
```
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "dutchies-dcs-scripting-tools",
|
||||
"displayName": "Dutchies Dcs Scripting Tools",
|
||||
"description": "Scripting tools to create DCS script and frameworks easier",
|
||||
"version": "0.0.5",
|
||||
"version": "0.1.0",
|
||||
"author": {
|
||||
"name": "dutchie031",
|
||||
"email": "54616262+dutchie031@users.noreply.github.com"
|
||||
@@ -15,7 +15,7 @@
|
||||
"publisher": "dutchie031",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"vscode": "1.108.1"
|
||||
"vscode": "^1.108.1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -3,37 +3,52 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { ScriptCompiler, ScriptCompilerOptions, CompilationError, ICompilationLogger } from 'dcs-script-compiler';
|
||||
import { Logger } from './logger';
|
||||
import * as luaAddonsManager from './lua-addons-manager';
|
||||
|
||||
const luaWorkSpaceSettingKey = "Lua.workspace";
|
||||
const librarySettingsKey = "library";
|
||||
const diagnosticCollection = vscode.languages.createDiagnosticCollection('lua-transpiler');
|
||||
|
||||
let pluginPath : string | undefined;
|
||||
|
||||
const logger = new Logger();
|
||||
|
||||
const extensionName = 'dutchies-dcs-scripting-tools';
|
||||
const publisherName = 'dutchie031';
|
||||
const extensionSettingsFilter = `@ext:${publisherName}.${extensionName}`;
|
||||
|
||||
// State tracking for addon updates
|
||||
let extensionPath: string | undefined;
|
||||
let workspaceRoot: string | undefined;
|
||||
let currentExtensionVersion: string | undefined;
|
||||
let installedAddonPaths: Map<string, string> = new Map();
|
||||
let isUpdatingAddons = false;
|
||||
|
||||
//TODO:
|
||||
// - ENABLE/DISABLE with settings instead of commands (or both)
|
||||
|
||||
// This method is called when your extension is activated
|
||||
// Your extension is activated the very first time the command is executed
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
export async function activate(context: vscode.ExtensionContext) {
|
||||
|
||||
pluginPath = context.asAbsolutePath('lua-addons');
|
||||
extensionPath = context.extensionPath;
|
||||
workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
|
||||
|
||||
// Initialize extension version
|
||||
try {
|
||||
currentExtensionVersion = await luaAddonsManager.getExtensionVersion(extensionPath);
|
||||
logger.debug(`Extension version: ${currentExtensionVersion}`);
|
||||
} catch (err) {
|
||||
logger.error(`Failed to determine extension version: ${err instanceof Error ? err.message : String(err)}`);
|
||||
}
|
||||
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('dutchies-dcs-scripting-tools.enable', async () => {
|
||||
enableIntellisense();
|
||||
await enableIntellisense();
|
||||
})
|
||||
);
|
||||
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('dutchies-dcs-scripting-tools.disable', async () => {
|
||||
disableIntellisense();
|
||||
await disableIntellisense();
|
||||
})
|
||||
);
|
||||
|
||||
@@ -71,20 +86,28 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
const config = vscode.workspace.getConfiguration(extensionName);
|
||||
const dcsTypesEnabled = config.get<boolean>('dcsTypes') || false;
|
||||
if (dcsTypesEnabled) {
|
||||
addPluginPathToSettings();
|
||||
await updateLuaAddons();
|
||||
} else {
|
||||
removePluginPathFromSettings();
|
||||
await disableIntellisense();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Check and update lua-addons on activation if dcsTypes is enabled
|
||||
await checkAndUpdateAddonsOnStartup();
|
||||
|
||||
logger.info('Dutchies DCS Scripting Tools extension activated');
|
||||
}
|
||||
|
||||
// This method is called when your extension is deactivated
|
||||
export function deactivate()
|
||||
export async function deactivate()
|
||||
{
|
||||
removePluginPathFromSettings();
|
||||
// Clean up addon paths from settings on deactivation
|
||||
try {
|
||||
await removeVersionedPluginPathsFromSettings();
|
||||
} catch (err) {
|
||||
logger.error(`Error cleaning up on deactivation: ${err instanceof Error ? err.message : String(err)}`);
|
||||
}
|
||||
logger.info('Dutchies DCS Scripting Tools extension deactivated');
|
||||
}
|
||||
|
||||
@@ -162,11 +185,11 @@ async function enableIntellisense() {
|
||||
config.update("dcsTypes", true, vscode.ConfigurationTarget.Workspace);
|
||||
}
|
||||
|
||||
addPluginPathToSettings();
|
||||
await updateLuaAddons();
|
||||
await vscode.commands.executeCommand(
|
||||
"lua.startServer"
|
||||
);
|
||||
vscode.window.showInformationMessage('Dutchies DCS Scripting Tools enabled.');
|
||||
vscode.window.showInformationMessage(`DCS-Types installed. Version ${currentExtensionVersion}.`);
|
||||
}
|
||||
|
||||
async function disableIntellisense() {
|
||||
@@ -175,32 +198,252 @@ async function disableIntellisense() {
|
||||
config.update("dcsTypes", false, vscode.ConfigurationTarget.Workspace);
|
||||
}
|
||||
|
||||
removePluginPathFromSettings();
|
||||
await removeVersionedPluginPathsFromSettings();
|
||||
|
||||
// Clean up all addon versions from workspace
|
||||
if (workspaceRoot) {
|
||||
try {
|
||||
const discoveredAddons = await luaAddonsManager.discoverLuaAddons(extensionPath || '');
|
||||
for (const addonName of discoveredAddons.keys()) {
|
||||
await luaAddonsManager.deleteAllVersionsOfAddon(workspaceRoot, addonName);
|
||||
logger.debug(`Deleted all versions of ${addonName} from workspace.`);
|
||||
}
|
||||
} catch (err) {
|
||||
logger.error(`Failed to clean up addons: ${err instanceof Error ? err.message : String(err)}`);
|
||||
}
|
||||
}
|
||||
|
||||
await vscode.commands.executeCommand(
|
||||
"lua.startServer"
|
||||
);
|
||||
vscode.window.showInformationMessage('Dutchies DCS Scripting Tools disabled.');
|
||||
}
|
||||
|
||||
function addPluginPathToSettings() {
|
||||
if (pluginPath) {
|
||||
const luaSettings = vscode.workspace.getConfiguration(luaWorkSpaceSettingKey);
|
||||
const librarySettings = luaSettings.get<string[]>(librarySettingsKey) || [];
|
||||
if (!librarySettings.includes(pluginPath)) {
|
||||
librarySettings.push(pluginPath);
|
||||
luaSettings.update(librarySettingsKey, librarySettings, vscode.ConfigurationTarget.Workspace);
|
||||
/**
|
||||
* Updates lua-addons by copying them from the extension bundle to the workspace
|
||||
* with versioned naming, cleaning old versions, and updating Lua settings
|
||||
*/
|
||||
async function updateLuaAddons(): Promise<void> {
|
||||
// Prevent concurrent update operations
|
||||
if (isUpdatingAddons) {
|
||||
logger.debug('Addon update already in progress, skipping.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!extensionPath || !workspaceRoot || !currentExtensionVersion) {
|
||||
logger.warn('Cannot update addons: extension path, workspace root, or version not available.');
|
||||
return;
|
||||
}
|
||||
|
||||
isUpdatingAddons = true;
|
||||
|
||||
try {
|
||||
logger.info('Starting lua-addons update...');
|
||||
|
||||
// Discover bundled addons
|
||||
const discoveredAddons = await luaAddonsManager.discoverLuaAddons(extensionPath);
|
||||
|
||||
if (discoveredAddons.size === 0) {
|
||||
logger.info('No lua-addons found in extension bundle.');
|
||||
isUpdatingAddons = false;
|
||||
return;
|
||||
}
|
||||
|
||||
logger.debug(`Discovered ${discoveredAddons.size} lua-addon(s): ${Array.from(discoveredAddons.keys()).join(', ')}`);
|
||||
|
||||
// Copy addons with versioned names
|
||||
const copiedAddons = await luaAddonsManager.copyLuaAddons(
|
||||
extensionPath,
|
||||
workspaceRoot,
|
||||
currentExtensionVersion,
|
||||
discoveredAddons
|
||||
);
|
||||
|
||||
// Store paths for settings management
|
||||
installedAddonPaths = copiedAddons;
|
||||
logger.debug(`Copied ${copiedAddons.size} addon(s) to workspace.`);
|
||||
|
||||
// Clean up old versions
|
||||
for (const addonName of discoveredAddons.keys()) {
|
||||
await luaAddonsManager.deleteOldVersions(workspaceRoot, addonName, currentExtensionVersion);
|
||||
logger.debug(`Cleaned old versions of ${addonName}.`);
|
||||
}
|
||||
|
||||
// Update Lua settings with new paths
|
||||
await addVersionedPluginPathsToSettings(copiedAddons);
|
||||
|
||||
logger.info(`Lua-addons update completed successfully (version ${currentExtensionVersion}).`);
|
||||
|
||||
} catch (err) {
|
||||
const errorMsg = err instanceof Error ? err.message : String(err);
|
||||
logger.error(`Failed to update lua-addons: ${errorMsg}`);
|
||||
vscode.window.showErrorMessage(`Failed to update Dcs Lua Types: ${errorMsg}`);
|
||||
} finally {
|
||||
isUpdatingAddons = false;
|
||||
}
|
||||
}
|
||||
|
||||
function removePluginPathFromSettings() {
|
||||
if (pluginPath) {
|
||||
const luaSettings = vscode.workspace.getConfiguration(luaWorkSpaceSettingKey);
|
||||
const librarySettings = luaSettings.get<string[]>(librarySettingsKey) || [];
|
||||
const libIndex = librarySettings.indexOf(pluginPath);
|
||||
if (libIndex !== -1) {
|
||||
librarySettings.splice(libIndex, 1);
|
||||
luaSettings.update(librarySettingsKey, librarySettings, vscode.ConfigurationTarget.Workspace);
|
||||
/**
|
||||
* Checks on extension startup if lua-addons need to be updated
|
||||
* Runs only if dcsTypes is enabled in the workspace
|
||||
*/
|
||||
async function checkAndUpdateAddonsOnStartup(): Promise<void> {
|
||||
if (!extensionPath || !workspaceRoot || !currentExtensionVersion) {
|
||||
logger.debug('Skipping addon version check on startup: missing initialization data.');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const config = vscode.workspace.getConfiguration(extensionName);
|
||||
const dcsTypesEnabled = config.get<boolean>('dcsTypes') || false;
|
||||
|
||||
if (!dcsTypesEnabled) {
|
||||
logger.debug('dcsTypes not enabled, skipping addon check on startup.');
|
||||
return;
|
||||
}
|
||||
|
||||
logger.debug('Checking lua-addons versions on startup...');
|
||||
|
||||
// Get installed addons
|
||||
const installedAddons = await luaAddonsManager.getInstalledAddons(workspaceRoot);
|
||||
const discoveredAddons = await luaAddonsManager.discoverLuaAddons(extensionPath);
|
||||
|
||||
// Check each discovered addon
|
||||
let updateNeeded = false;
|
||||
for (const addonName of discoveredAddons.keys()) {
|
||||
const installed = installedAddons.get(addonName);
|
||||
const installedVersion = installed?.version;
|
||||
|
||||
if (luaAddonsManager.requiresUpdate(installedVersion, currentExtensionVersion)) {
|
||||
logger.info(
|
||||
`Version mismatch for ${addonName}: installed=${installedVersion || 'none'}, current=${currentExtensionVersion}`
|
||||
);
|
||||
updateNeeded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (updateNeeded) {
|
||||
logger.info('Lua-addons update needed, prompting user...');
|
||||
const userChoice = await vscode.window.showInformationMessage(
|
||||
'DCS-Types are not up to date with the current extension version. Do you want to update them?',
|
||||
{ modal: false },
|
||||
'Update'
|
||||
);
|
||||
|
||||
if (userChoice === 'Update') {
|
||||
await updateLuaAddons();
|
||||
vscode.window.showInformationMessage(`DCS-Types updated to version ${currentExtensionVersion}.`);
|
||||
} else {
|
||||
logger.info('User declined DCS-Types update.');
|
||||
}
|
||||
} else {
|
||||
logger.debug('Lua-addons versions are current, no update needed.');
|
||||
// Ensure paths are in settings even if no update needed
|
||||
const pathsMap = new Map<string, string>();
|
||||
for (const [name, info] of installedAddons.entries()) {
|
||||
pathsMap.set(name, info.path);
|
||||
}
|
||||
installedAddonPaths = pathsMap;
|
||||
await addVersionedPluginPathsToSettings(installedAddonPaths);
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
logger.error(
|
||||
`Error checking lua-addons on startup: ${err instanceof Error ? err.message : String(err)}`
|
||||
);
|
||||
// Don't fail activation if check fails; user can manually enable/disable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an absolute path to a workspace-relative path using ${workspaceFolder}
|
||||
*/
|
||||
function convertToWorkspaceFolderPath(absolutePath: string): string {
|
||||
if (!workspaceRoot) {
|
||||
return absolutePath;
|
||||
}
|
||||
// Normalize paths for comparison (handle both forward and back slashes)
|
||||
const normalizedAbsolute = absolutePath.replace(/\\/g, '/');
|
||||
const normalizedWorkspace = workspaceRoot.replace(/\\/g, '/');
|
||||
|
||||
if (normalizedAbsolute.startsWith(normalizedWorkspace)) {
|
||||
const relativePath = normalizedAbsolute.substring(normalizedWorkspace.length);
|
||||
// Remove leading slash if present
|
||||
const cleanPath = relativePath.startsWith('/') ? relativePath.substring(1) : relativePath;
|
||||
return `\${workspaceFolder}/${cleanPath}`;
|
||||
}
|
||||
return absolutePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds versioned addon paths to the Lua workspace library settings
|
||||
* @param addonPaths - Map of addon name to installed path
|
||||
*/
|
||||
async function addVersionedPluginPathsToSettings(addonPaths?: Map<string, string>): Promise<void> {
|
||||
const pathsToAdd = addonPaths || installedAddonPaths;
|
||||
|
||||
if (pathsToAdd.size === 0) {
|
||||
logger.debug('No addon paths to add to settings.');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const luaSettings = vscode.workspace.getConfiguration(luaWorkSpaceSettingKey);
|
||||
let librarySettings = luaSettings.get<string[]>(librarySettingsKey) || [];
|
||||
|
||||
// Add each addon path if not already present
|
||||
for (const addonPath of pathsToAdd.values()) {
|
||||
const workspaceFolderPath = convertToWorkspaceFolderPath(addonPath);
|
||||
if (!librarySettings.includes(workspaceFolderPath)) {
|
||||
librarySettings.push(workspaceFolderPath);
|
||||
logger.debug(`Added addon path to settings: ${workspaceFolderPath}`);
|
||||
}
|
||||
}
|
||||
|
||||
await luaSettings.update(librarySettingsKey, librarySettings, vscode.ConfigurationTarget.Workspace);
|
||||
} catch (err) {
|
||||
logger.error(`Failed to add addon paths to settings: ${err instanceof Error ? err.message : String(err)}`);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all addon paths from the Lua workspace library settings
|
||||
*/
|
||||
async function removeVersionedPluginPathsFromSettings(): Promise<void> {
|
||||
try {
|
||||
const luaSettings = vscode.workspace.getConfiguration(luaWorkSpaceSettingKey);
|
||||
let librarySettings = luaSettings.get<string[]>(librarySettingsKey) || [];
|
||||
|
||||
if (workspaceRoot) {
|
||||
// Get all installed addons to know what paths to remove
|
||||
const installedAddons = await luaAddonsManager.getInstalledAddons(workspaceRoot);
|
||||
|
||||
for (const addonInfo of installedAddons.values()) {
|
||||
// Try both absolute and workspace-relative paths for compatibility
|
||||
const absolutePath = addonInfo.path;
|
||||
const relativePath = convertToWorkspaceFolderPath(absolutePath);
|
||||
|
||||
// Remove absolute path if present
|
||||
let index = librarySettings.indexOf(absolutePath);
|
||||
if (index !== -1) {
|
||||
librarySettings.splice(index, 1);
|
||||
logger.debug(`Removed addon path from settings: ${absolutePath}`);
|
||||
}
|
||||
|
||||
// Remove relative path if present
|
||||
index = librarySettings.indexOf(relativePath);
|
||||
if (index !== -1) {
|
||||
librarySettings.splice(index, 1);
|
||||
logger.debug(`Removed addon path from settings: ${relativePath}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await luaSettings.update(librarySettingsKey, librarySettings, vscode.ConfigurationTarget.Workspace);
|
||||
} catch (err) {
|
||||
logger.error(`Failed to remove addon paths from settings: ${err instanceof Error ? err.message : String(err)}`);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,14 @@ export class Logger {
|
||||
this.outputChannel.appendLine(`[${new Date().toISOString()}][ERROR] ${message}`);
|
||||
}
|
||||
|
||||
debug(message: string) {
|
||||
this.outputChannel.appendLine(`[${new Date().toISOString()}][DEBUG] ${message}`);
|
||||
}
|
||||
|
||||
warn(message: string) {
|
||||
this.outputChannel.appendLine(`[${new Date().toISOString()}][WARN] ${message}`);
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.outputChannel.clear();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,354 @@
|
||||
import * as fs from 'fs/promises';
|
||||
import * as path from 'path';
|
||||
import { existsSync } from 'fs';
|
||||
|
||||
/**
|
||||
* Manages lua-addons: discovery, versioning, copying, and cleanup.
|
||||
* All operations assume semver versioning (X.Y.Z format).
|
||||
* Addon folder names follow the pattern: `<addon-name>.<version>` (e.g., dcs-types.0.0.5)
|
||||
*/
|
||||
|
||||
interface LuaAddonInfo {
|
||||
name: string;
|
||||
sourceDir: string;
|
||||
version: string;
|
||||
}
|
||||
|
||||
interface InstalledAddonInfo {
|
||||
name: string;
|
||||
version: string;
|
||||
path: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the extension's version from package.json
|
||||
* @param extensionRoot - Absolute path to the extension root directory
|
||||
* @returns The semantic version string (e.g., "0.0.5")
|
||||
* @throws Error if package.json cannot be read or version is not found
|
||||
*/
|
||||
export async function getExtensionVersion(extensionRoot: string): Promise<string> {
|
||||
try {
|
||||
const packageJsonPath = path.join(extensionRoot, 'package.json');
|
||||
const content = await fs.readFile(packageJsonPath, 'utf-8');
|
||||
const packageJson = JSON.parse(content);
|
||||
|
||||
const version = packageJson.version as string | undefined;
|
||||
if (!version) {
|
||||
throw new Error('Version field not found in package.json');
|
||||
}
|
||||
|
||||
return version;
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`Failed to read extension version: ${err instanceof Error ? err.message : String(err)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Discovers all lua-addons in the bundled lua-addons directory
|
||||
* @param extensionPath - Absolute path to the extension installation directory
|
||||
* @returns Map of addon name to source directory path
|
||||
* @throws Error if lua-addons directory cannot be read
|
||||
*/
|
||||
export async function discoverLuaAddons(extensionPath: string): Promise<Map<string, string>> {
|
||||
const luaAddonsDir = path.join(extensionPath, 'lua-addons');
|
||||
const addons = new Map<string, string>();
|
||||
|
||||
try {
|
||||
// Check if lua-addons directory exists
|
||||
if (!existsSync(luaAddonsDir)) {
|
||||
return addons; // Empty map if no lua-addons
|
||||
}
|
||||
|
||||
const entries = await fs.readdir(luaAddonsDir, { withFileTypes: true });
|
||||
|
||||
for (const entry of entries) {
|
||||
if (entry.isDirectory()) {
|
||||
const addonName = entry.name;
|
||||
const addonPath = path.join(luaAddonsDir, addonName);
|
||||
addons.set(addonName, addonPath);
|
||||
}
|
||||
}
|
||||
|
||||
return addons;
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`Failed to discover lua-addons: ${err instanceof Error ? err.message : String(err)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the workspace lua-addons directory path (.vscode/lua-addons)
|
||||
* @param workspaceRoot - Absolute path to the workspace root
|
||||
* @returns Absolute path to .vscode/lua-addons
|
||||
*/
|
||||
export function getWorkspaceLuaAddonsDir(workspaceRoot: string): string {
|
||||
return path.join(workspaceRoot, '.vscode', 'lua-addons');
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses installed addon versions from the workspace lua-addons directory
|
||||
* Expects folder names in format: `<addon-name>.<version>` (e.g., dcs-types.0.0.5)
|
||||
* @param workspaceRoot - Absolute path to the workspace root
|
||||
* @returns Map of addon name to version string; returns empty map if directory doesn't exist
|
||||
* @throws Error if directory cannot be read
|
||||
*/
|
||||
export async function getInstalledVersions(
|
||||
workspaceRoot: string
|
||||
): Promise<Map<string, InstalledAddonInfo>> {
|
||||
const luaAddonsDir = getWorkspaceLuaAddonsDir(workspaceRoot);
|
||||
const installed = new Map<string, InstalledAddonInfo>();
|
||||
|
||||
try {
|
||||
// Return empty map if directory doesn't exist yet
|
||||
if (!existsSync(luaAddonsDir)) {
|
||||
return installed;
|
||||
}
|
||||
|
||||
const entries = await fs.readdir(luaAddonsDir, { withFileTypes: true });
|
||||
|
||||
for (const entry of entries) {
|
||||
if (entry.isDirectory()) {
|
||||
const folderName = entry.name;
|
||||
const parsed = parseAddonFolderName(folderName);
|
||||
|
||||
if (parsed) {
|
||||
installed.set(parsed.name, {
|
||||
name: parsed.name,
|
||||
version: parsed.version,
|
||||
path: path.join(luaAddonsDir, folderName)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return installed;
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`Failed to read installed versions: ${err instanceof Error ? err.message : String(err)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies lua-addons from the extension bundle to the workspace with versioned folder names
|
||||
* @param extensionPath - Absolute path to the extension installation directory
|
||||
* @param workspaceRoot - Absolute path to the workspace root
|
||||
* @param extensionVersion - The current extension version string
|
||||
* @param addonsToCopy - Map of addon name to source directory (from discoverLuaAddons)
|
||||
* @returns Map of addon name to installed path in workspace
|
||||
* @throws Error if copy fails or directory creation fails
|
||||
*/
|
||||
export async function copyLuaAddons(
|
||||
extensionPath: string,
|
||||
workspaceRoot: string,
|
||||
extensionVersion: string,
|
||||
addonsToCopy: Map<string, string>
|
||||
): Promise<Map<string, string>> {
|
||||
const luaAddonsDir = getWorkspaceLuaAddonsDir(workspaceRoot);
|
||||
const results = new Map<string, string>();
|
||||
|
||||
try {
|
||||
// Ensure .vscode directory exists
|
||||
const vscodeDir = path.join(workspaceRoot, '.vscode');
|
||||
await ensureDirectoryExists(vscodeDir);
|
||||
|
||||
// Ensure lua-addons directory exists
|
||||
await ensureDirectoryExists(luaAddonsDir);
|
||||
|
||||
// Copy each addon
|
||||
for (const [addonName, sourceDir] of addonsToCopy) {
|
||||
const versionedFolderName = `${addonName}.${extensionVersion}`;
|
||||
const destDir = path.join(luaAddonsDir, versionedFolderName);
|
||||
|
||||
// Remove destination if it already exists (shouldn't happen, but be safe)
|
||||
if (existsSync(destDir)) {
|
||||
await fs.rm(destDir, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
// Copy the addon
|
||||
await copyDirectory(sourceDir, destDir);
|
||||
results.set(addonName, destDir);
|
||||
}
|
||||
|
||||
return results;
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`Failed to copy lua-addons: ${err instanceof Error ? err.message : String(err)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all old versions of a specific addon
|
||||
* @param workspaceRoot - Absolute path to the workspace root
|
||||
* @param addonName - Name of the addon (e.g., "dcs-types")
|
||||
* @param currentVersion - Version to keep (e.g., "0.0.5")
|
||||
* @throws Error if directory operations fail
|
||||
*/
|
||||
export async function deleteOldVersions(
|
||||
workspaceRoot: string,
|
||||
addonName: string,
|
||||
currentVersion: string
|
||||
): Promise<void> {
|
||||
const luaAddonsDir = getWorkspaceLuaAddonsDir(workspaceRoot);
|
||||
|
||||
try {
|
||||
// Return silently if directory doesn't exist
|
||||
if (!existsSync(luaAddonsDir)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const entries = await fs.readdir(luaAddonsDir, { withFileTypes: true });
|
||||
|
||||
for (const entry of entries) {
|
||||
if (entry.isDirectory()) {
|
||||
const parsed = parseAddonFolderName(entry.name);
|
||||
|
||||
// Delete if it's an old version of this addon
|
||||
if (parsed && parsed.name === addonName && parsed.version !== currentVersion) {
|
||||
const oldPath = path.join(luaAddonsDir, entry.name);
|
||||
await fs.rm(oldPath, { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`Failed to delete old versions of ${addonName}: ${
|
||||
err instanceof Error ? err.message : String(err)
|
||||
}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an addon needs to be updated (version mismatch)
|
||||
* @param installedVersion - Currently installed version or undefined if not installed
|
||||
* @param currentExtensionVersion - Current extension version to compare against
|
||||
* @returns true if no version is installed or version doesn't match
|
||||
*/
|
||||
export function requiresUpdate(
|
||||
installedVersion: string | undefined,
|
||||
currentExtensionVersion: string
|
||||
): boolean {
|
||||
return !installedVersion || installedVersion !== currentExtensionVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all versioned addon folders for a specific addon name
|
||||
* @param workspaceRoot - Absolute path to the workspace root
|
||||
* @param addonName - Name of the addon to clean up completely
|
||||
* @throws Error if directory operations fail
|
||||
*/
|
||||
export async function deleteAllVersionsOfAddon(
|
||||
workspaceRoot: string,
|
||||
addonName: string
|
||||
): Promise<void> {
|
||||
const luaAddonsDir = getWorkspaceLuaAddonsDir(workspaceRoot);
|
||||
|
||||
try {
|
||||
// Return silently if directory doesn't exist
|
||||
if (!existsSync(luaAddonsDir)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const entries = await fs.readdir(luaAddonsDir, { withFileTypes: true });
|
||||
|
||||
for (const entry of entries) {
|
||||
if (entry.isDirectory()) {
|
||||
const parsed = parseAddonFolderName(entry.name);
|
||||
|
||||
// Delete all versions of this addon
|
||||
if (parsed && parsed.name === addonName) {
|
||||
const addonPath = path.join(luaAddonsDir, entry.name);
|
||||
await fs.rm(addonPath, { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`Failed to delete all versions of ${addonName}: ${
|
||||
err instanceof Error ? err.message : String(err)
|
||||
}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the currently installed addon info for all addons
|
||||
* @param workspaceRoot - Absolute path to the workspace root
|
||||
* @returns Map of addon name to its latest installed version info
|
||||
*/
|
||||
export async function getInstalledAddons(
|
||||
workspaceRoot: string
|
||||
): Promise<Map<string, InstalledAddonInfo>> {
|
||||
return getInstalledVersions(workspaceRoot);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Private Helper Functions
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Parses an addon folder name in format `<name>.<version>`
|
||||
* @param folderName - The folder name to parse
|
||||
* @returns Object with name and version, or null if format doesn't match
|
||||
*/
|
||||
function parseAddonFolderName(
|
||||
folderName: string
|
||||
): { name: string; version: string } | null {
|
||||
// Split only on the last dot to handle addon names with dots (unlikely, but safe)
|
||||
const lastDotIndex = folderName.lastIndexOf('.');
|
||||
if (lastDotIndex === -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const name = folderName.substring(0, lastDotIndex);
|
||||
const version = folderName.substring(lastDotIndex + 1);
|
||||
|
||||
// Validate semver format (basic check)
|
||||
if (!/^\d+\.\d+\.\d+/.test(version)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return { name, version };
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures a directory exists, creating it if necessary
|
||||
* @param dirPath - Absolute path to the directory
|
||||
*/
|
||||
async function ensureDirectoryExists(dirPath: string): Promise<void> {
|
||||
try {
|
||||
await fs.mkdir(dirPath, { recursive: true });
|
||||
} catch (err) {
|
||||
// Ignore EEXIST errors
|
||||
if ((err as NodeJS.ErrnoException).code !== 'EEXIST') {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively copies a directory and its contents
|
||||
* @param srcDir - Source directory path
|
||||
* @param destDir - Destination directory path
|
||||
*/
|
||||
async function copyDirectory(srcDir: string, destDir: string): Promise<void> {
|
||||
await ensureDirectoryExists(destDir);
|
||||
|
||||
const entries = await fs.readdir(srcDir, { withFileTypes: true });
|
||||
|
||||
for (const entry of entries) {
|
||||
const srcPath = path.join(srcDir, entry.name);
|
||||
const destPath = path.join(destDir, entry.name);
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
await copyDirectory(srcPath, destPath);
|
||||
} else {
|
||||
await fs.copyFile(srcPath, destPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,310 @@
|
||||
import * as assert from 'assert';
|
||||
import * as fs from 'fs/promises';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
import { existsSync } from 'fs';
|
||||
import * as luaAddonsManager from '../lua-addons-manager';
|
||||
|
||||
/**
|
||||
* Integration tests for lua-addons-manager
|
||||
* Uses temporary directories to avoid polluting the file system
|
||||
*/
|
||||
|
||||
suite('lua-addons-manager', () => {
|
||||
let tempDir: string;
|
||||
|
||||
suiteSetup(async () => {
|
||||
tempDir = path.join(os.tmpdir(), `dcs-test-${Date.now()}-${Math.random()}`);
|
||||
});
|
||||
|
||||
suiteTeardown(async () => {
|
||||
if (existsSync(tempDir)) {
|
||||
await fs.rm(tempDir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
suite('getExtensionVersion', () => {
|
||||
test('should read version from package.json', async () => {
|
||||
const testDir = path.join(tempDir, 'getExtensionVersion-1');
|
||||
await fs.mkdir(testDir, { recursive: true });
|
||||
const packageJson = path.join(testDir, 'package.json');
|
||||
await fs.writeFile(packageJson, JSON.stringify({ version: '1.2.3' }));
|
||||
|
||||
const version = await luaAddonsManager.getExtensionVersion(testDir);
|
||||
|
||||
assert.strictEqual(version, '1.2.3');
|
||||
});
|
||||
|
||||
test('should throw error if package.json not found', async () => {
|
||||
const testDir = path.join(tempDir, 'getExtensionVersion-2');
|
||||
await fs.mkdir(testDir, { recursive: true });
|
||||
|
||||
await assert.rejects(
|
||||
() => luaAddonsManager.getExtensionVersion(testDir),
|
||||
/Failed to read extension version/
|
||||
);
|
||||
});
|
||||
|
||||
test('should throw error if version field missing', async () => {
|
||||
const testDir = path.join(tempDir, 'getExtensionVersion-3');
|
||||
await fs.mkdir(testDir, { recursive: true });
|
||||
const packageJson = path.join(testDir, 'package.json');
|
||||
await fs.writeFile(packageJson, JSON.stringify({ name: 'test' }));
|
||||
|
||||
await assert.rejects(
|
||||
() => luaAddonsManager.getExtensionVersion(testDir),
|
||||
/Version field not found/
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
suite('discoverLuaAddons', () => {
|
||||
test('should discover lua-addons directories', async () => {
|
||||
const testDir = path.join(tempDir, 'discoverLuaAddons-1');
|
||||
const luaAddonsDir = path.join(testDir, 'lua-addons');
|
||||
await fs.mkdir(path.join(luaAddonsDir, 'addon1'), { recursive: true });
|
||||
await fs.mkdir(path.join(luaAddonsDir, 'addon2'), { recursive: true });
|
||||
|
||||
const addons = await luaAddonsManager.discoverLuaAddons(testDir);
|
||||
|
||||
assert.strictEqual(addons.size, 2);
|
||||
assert.strictEqual(addons.has('addon1'), true);
|
||||
assert.strictEqual(addons.has('addon2'), true);
|
||||
});
|
||||
|
||||
test('should return empty map if lua-addons directory does not exist', async () => {
|
||||
const testDir = path.join(tempDir, 'discoverLuaAddons-2');
|
||||
await fs.mkdir(testDir, { recursive: true });
|
||||
|
||||
const addons = await luaAddonsManager.discoverLuaAddons(testDir);
|
||||
|
||||
assert.strictEqual(addons.size, 0);
|
||||
});
|
||||
|
||||
test('should ignore non-directory entries', async () => {
|
||||
const testDir = path.join(tempDir, 'discoverLuaAddons-3');
|
||||
const luaAddonsDir = path.join(testDir, 'lua-addons');
|
||||
await fs.mkdir(luaAddonsDir, { recursive: true });
|
||||
await fs.mkdir(path.join(luaAddonsDir, 'addon1'), { recursive: true });
|
||||
await fs.writeFile(path.join(luaAddonsDir, 'file.txt'), 'test');
|
||||
|
||||
const addons = await luaAddonsManager.discoverLuaAddons(testDir);
|
||||
|
||||
assert.strictEqual(addons.size, 1);
|
||||
assert.strictEqual(addons.has('addon1'), true);
|
||||
});
|
||||
});
|
||||
|
||||
suite('getWorkspaceLuaAddonsDir', () => {
|
||||
test('should return correct .vscode/lua-addons path', () => {
|
||||
const workspaceRoot = '/path/to/workspace';
|
||||
const result = luaAddonsManager.getWorkspaceLuaAddonsDir(workspaceRoot);
|
||||
|
||||
assert.strictEqual(result, path.join(workspaceRoot, '.vscode', 'lua-addons'));
|
||||
});
|
||||
});
|
||||
|
||||
suite('getInstalledVersions', () => {
|
||||
test('should parse installed addon versions from folder names', async () => {
|
||||
const testDir = path.join(tempDir, 'getInstalledVersions-1');
|
||||
const luaAddonsDir = path.join(testDir, '.vscode', 'lua-addons');
|
||||
await fs.mkdir(path.join(luaAddonsDir, 'dcs-types.0.0.5'), { recursive: true });
|
||||
await fs.mkdir(path.join(luaAddonsDir, 'mission-utils.1.2.3'), { recursive: true });
|
||||
|
||||
const installed = await luaAddonsManager.getInstalledVersions(testDir);
|
||||
|
||||
assert.strictEqual(installed.size, 2);
|
||||
assert.strictEqual(installed.has('dcs-types'), true);
|
||||
assert.strictEqual(installed.has('mission-utils'), true);
|
||||
assert.strictEqual(installed.get('dcs-types')?.version, '0.0.5');
|
||||
assert.strictEqual(installed.get('mission-utils')?.version, '1.2.3');
|
||||
});
|
||||
|
||||
test('should return empty map if directory does not exist', async () => {
|
||||
const testDir = path.join(tempDir, 'getInstalledVersions-2');
|
||||
await fs.mkdir(testDir, { recursive: true });
|
||||
|
||||
const installed = await luaAddonsManager.getInstalledVersions(testDir);
|
||||
|
||||
assert.strictEqual(installed.size, 0);
|
||||
});
|
||||
|
||||
test('should ignore folders with invalid version format', async () => {
|
||||
const testDir = path.join(tempDir, 'getInstalledVersions-3');
|
||||
const luaAddonsDir = path.join(testDir, '.vscode', 'lua-addons');
|
||||
await fs.mkdir(path.join(luaAddonsDir, 'dcs-types.0.0.5'), { recursive: true });
|
||||
await fs.mkdir(path.join(luaAddonsDir, 'invalid-addon'), { recursive: true });
|
||||
await fs.mkdir(path.join(luaAddonsDir, 'bad-format.v1'), { recursive: true });
|
||||
|
||||
const installed = await luaAddonsManager.getInstalledVersions(testDir);
|
||||
|
||||
assert.strictEqual(installed.size, 1);
|
||||
assert.strictEqual(installed.has('dcs-types'), true);
|
||||
assert.strictEqual(installed.has('invalid-addon'), false);
|
||||
assert.strictEqual(installed.has('bad-format'), false);
|
||||
});
|
||||
});
|
||||
|
||||
suite('copyLuaAddons', () => {
|
||||
test('should copy addons with versioned folder names', async () => {
|
||||
const testDir = path.join(tempDir, 'copyLuaAddons-1');
|
||||
const sourceAddon1 = path.join(testDir, 'source-addons', 'addon1');
|
||||
await fs.mkdir(sourceAddon1, { recursive: true });
|
||||
await fs.writeFile(path.join(sourceAddon1, 'file1.lua'), 'content1');
|
||||
|
||||
const addonsToCopy = new Map<string, string>([
|
||||
['addon1', sourceAddon1]
|
||||
]);
|
||||
|
||||
const result = await luaAddonsManager.copyLuaAddons(
|
||||
testDir,
|
||||
testDir,
|
||||
'1.0.0',
|
||||
addonsToCopy
|
||||
);
|
||||
|
||||
assert.strictEqual(result.size, 1);
|
||||
const copiedPath = result.get('addon1');
|
||||
assert.strictEqual(copiedPath !== undefined, true);
|
||||
if (copiedPath) {
|
||||
assert.strictEqual(copiedPath.includes('addon1.1.0.0'), true);
|
||||
assert.strictEqual(existsSync(path.join(copiedPath, 'file1.lua')), true);
|
||||
}
|
||||
});
|
||||
|
||||
test('should create .vscode directory if it does not exist', async () => {
|
||||
const testDir = path.join(tempDir, 'copyLuaAddons-2');
|
||||
const sourceAddon = path.join(testDir, 'source', 'addon1');
|
||||
await fs.mkdir(sourceAddon, { recursive: true });
|
||||
|
||||
const addonsToCopy = new Map<string, string>([
|
||||
['addon1', sourceAddon]
|
||||
]);
|
||||
|
||||
await luaAddonsManager.copyLuaAddons(
|
||||
testDir,
|
||||
testDir,
|
||||
'1.0.0',
|
||||
addonsToCopy
|
||||
);
|
||||
|
||||
const vscodeDir = path.join(testDir, '.vscode');
|
||||
assert.strictEqual(existsSync(vscodeDir), true);
|
||||
});
|
||||
|
||||
test('should copy nested directories recursively', async () => {
|
||||
const testDir = path.join(tempDir, 'copyLuaAddons-3');
|
||||
const sourceAddon = path.join(testDir, 'source', 'addon1');
|
||||
await fs.mkdir(path.join(sourceAddon, 'subdir'), { recursive: true });
|
||||
await fs.writeFile(path.join(sourceAddon, 'file.lua'), 'root');
|
||||
await fs.writeFile(path.join(sourceAddon, 'subdir', 'file.lua'), 'nested');
|
||||
|
||||
const addonsToCopy = new Map<string, string>([
|
||||
['addon1', sourceAddon]
|
||||
]);
|
||||
|
||||
const result = await luaAddonsManager.copyLuaAddons(
|
||||
testDir,
|
||||
testDir,
|
||||
'1.0.0',
|
||||
addonsToCopy
|
||||
);
|
||||
|
||||
const copiedPath = result.get('addon1')!;
|
||||
assert.strictEqual(existsSync(path.join(copiedPath, 'file.lua')), true);
|
||||
assert.strictEqual(existsSync(path.join(copiedPath, 'subdir', 'file.lua')), true);
|
||||
});
|
||||
});
|
||||
|
||||
suite('deleteOldVersions', () => {
|
||||
test('should delete old versions of an addon', async () => {
|
||||
const testDir = path.join(tempDir, 'deleteOldVersions-1');
|
||||
const luaAddonsDir = path.join(testDir, '.vscode', 'lua-addons');
|
||||
await fs.mkdir(path.join(luaAddonsDir, 'addon1.0.0.1'), { recursive: true });
|
||||
await fs.mkdir(path.join(luaAddonsDir, 'addon1.0.0.2'), { recursive: true });
|
||||
await fs.mkdir(path.join(luaAddonsDir, 'addon1.0.0.3'), { recursive: true });
|
||||
|
||||
await luaAddonsManager.deleteOldVersions(testDir, 'addon1', '0.0.3');
|
||||
|
||||
const remaining = await fs.readdir(luaAddonsDir);
|
||||
assert.deepStrictEqual(remaining.sort(), ['addon1.0.0.3']);
|
||||
});
|
||||
|
||||
test('should not delete other addons', async () => {
|
||||
const testDir = path.join(tempDir, 'deleteOldVersions-2');
|
||||
const luaAddonsDir = path.join(testDir, '.vscode', 'lua-addons');
|
||||
await fs.mkdir(path.join(luaAddonsDir, 'addon1.0.0.1'), { recursive: true });
|
||||
await fs.mkdir(path.join(luaAddonsDir, 'addon1.0.0.2'), { recursive: true });
|
||||
await fs.mkdir(path.join(luaAddonsDir, 'addon2.0.0.1'), { recursive: true });
|
||||
|
||||
await luaAddonsManager.deleteOldVersions(testDir, 'addon1', '0.0.2');
|
||||
|
||||
const remaining = await fs.readdir(luaAddonsDir);
|
||||
assert.strictEqual(remaining.includes('addon1.0.0.2'), true);
|
||||
assert.strictEqual(remaining.includes('addon2.0.0.1'), true);
|
||||
assert.strictEqual(remaining.includes('addon1.0.0.1'), false);
|
||||
});
|
||||
|
||||
test('should handle missing directory gracefully', async () => {
|
||||
const testDir = path.join(tempDir, 'deleteOldVersions-3');
|
||||
await fs.mkdir(testDir, { recursive: true });
|
||||
|
||||
// Should not throw
|
||||
await luaAddonsManager.deleteOldVersions(testDir, 'addon1', '0.0.1');
|
||||
});
|
||||
});
|
||||
|
||||
suite('deleteAllVersionsOfAddon', () => {
|
||||
test('should delete all versions of an addon', async () => {
|
||||
const testDir = path.join(tempDir, 'deleteAllVersionsOfAddon-1');
|
||||
const luaAddonsDir = path.join(testDir, '.vscode', 'lua-addons');
|
||||
await fs.mkdir(path.join(luaAddonsDir, 'addon1.0.0.1'), { recursive: true });
|
||||
await fs.mkdir(path.join(luaAddonsDir, 'addon1.0.0.2'), { recursive: true });
|
||||
await fs.mkdir(path.join(luaAddonsDir, 'addon2.0.0.1'), { recursive: true });
|
||||
|
||||
await luaAddonsManager.deleteAllVersionsOfAddon(testDir, 'addon1');
|
||||
|
||||
const remaining = await fs.readdir(luaAddonsDir);
|
||||
assert.deepStrictEqual(remaining.sort(), ['addon2.0.0.1']);
|
||||
});
|
||||
});
|
||||
|
||||
suite('requiresUpdate', () => {
|
||||
test('should return true if no version installed', () => {
|
||||
const result = luaAddonsManager.requiresUpdate(undefined, '1.0.0');
|
||||
|
||||
assert.strictEqual(result, true);
|
||||
});
|
||||
|
||||
test('should return true if versions do not match', () => {
|
||||
const result = luaAddonsManager.requiresUpdate('1.0.0', '1.0.1');
|
||||
|
||||
assert.strictEqual(result, true);
|
||||
});
|
||||
|
||||
test('should return false if versions match', () => {
|
||||
const result = luaAddonsManager.requiresUpdate('1.0.0', '1.0.0');
|
||||
|
||||
assert.strictEqual(result, false);
|
||||
});
|
||||
});
|
||||
|
||||
suite('getInstalledAddons', () => {
|
||||
test('should return installed addon information', async () => {
|
||||
const testDir = path.join(tempDir, 'getInstalledAddons-1');
|
||||
const luaAddonsDir = path.join(testDir, '.vscode', 'lua-addons');
|
||||
await fs.mkdir(path.join(luaAddonsDir, 'dcs-types.0.0.5'), { recursive: true });
|
||||
|
||||
const installed = await luaAddonsManager.getInstalledAddons(testDir);
|
||||
|
||||
assert.strictEqual(installed.size, 1);
|
||||
const addonInfo = installed.get('dcs-types');
|
||||
assert.strictEqual(addonInfo !== undefined, true);
|
||||
if (addonInfo) {
|
||||
assert.strictEqual(addonInfo.name, 'dcs-types');
|
||||
assert.strictEqual(addonInfo.version, '0.0.5');
|
||||
assert.strictEqual(addonInfo.path.includes('dcs-types.0.0.5'), true);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
Generated
-789
@@ -1,789 +0,0 @@
|
||||
{
|
||||
"name": "gh-scripting-compiler",
|
||||
"version": "0.0.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "gh-scripting-compiler",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.27.2",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/core": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.11.1.tgz",
|
||||
"integrity": "sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/exec": "^1.1.1",
|
||||
"@actions/http-client": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/exec": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz",
|
||||
"integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/io": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/http-client": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.3.tgz",
|
||||
"integrity": "sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tunnel": "^0.0.6",
|
||||
"undici": "^5.25.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/io": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz",
|
||||
"integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@cspotcode/source-map-support": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/trace-mapping": "0.3.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz",
|
||||
"integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"aix"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz",
|
||||
"integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz",
|
||||
"integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-x64": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz",
|
||||
"integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz",
|
||||
"integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz",
|
||||
"integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz",
|
||||
"integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz",
|
||||
"integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz",
|
||||
"integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz",
|
||||
"integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz",
|
||||
"integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz",
|
||||
"integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz",
|
||||
"integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz",
|
||||
"integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz",
|
||||
"integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz",
|
||||
"integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz",
|
||||
"integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-arm64": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz",
|
||||
"integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz",
|
||||
"integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-arm64": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz",
|
||||
"integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz",
|
||||
"integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openharmony-arm64": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz",
|
||||
"integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openharmony"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz",
|
||||
"integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz",
|
||||
"integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz",
|
||||
"integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz",
|
||||
"integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@fastify/busboy": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz",
|
||||
"integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/resolve-uri": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
||||
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
|
||||
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
|
||||
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "^3.0.3",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tsconfig/node10": {
|
||||
"version": "1.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz",
|
||||
"integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@tsconfig/node12": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
|
||||
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@tsconfig/node14": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
||||
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@tsconfig/node16": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
|
||||
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "25.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.2.tgz",
|
||||
"integrity": "sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~7.18.0"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.16.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
|
||||
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn-walk": {
|
||||
"version": "8.3.5",
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz",
|
||||
"integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"acorn": "^8.11.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/arg": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/create-require": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/diff": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz",
|
||||
"integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.27.7",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz",
|
||||
"integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/aix-ppc64": "0.27.7",
|
||||
"@esbuild/android-arm": "0.27.7",
|
||||
"@esbuild/android-arm64": "0.27.7",
|
||||
"@esbuild/android-x64": "0.27.7",
|
||||
"@esbuild/darwin-arm64": "0.27.7",
|
||||
"@esbuild/darwin-x64": "0.27.7",
|
||||
"@esbuild/freebsd-arm64": "0.27.7",
|
||||
"@esbuild/freebsd-x64": "0.27.7",
|
||||
"@esbuild/linux-arm": "0.27.7",
|
||||
"@esbuild/linux-arm64": "0.27.7",
|
||||
"@esbuild/linux-ia32": "0.27.7",
|
||||
"@esbuild/linux-loong64": "0.27.7",
|
||||
"@esbuild/linux-mips64el": "0.27.7",
|
||||
"@esbuild/linux-ppc64": "0.27.7",
|
||||
"@esbuild/linux-riscv64": "0.27.7",
|
||||
"@esbuild/linux-s390x": "0.27.7",
|
||||
"@esbuild/linux-x64": "0.27.7",
|
||||
"@esbuild/netbsd-arm64": "0.27.7",
|
||||
"@esbuild/netbsd-x64": "0.27.7",
|
||||
"@esbuild/openbsd-arm64": "0.27.7",
|
||||
"@esbuild/openbsd-x64": "0.27.7",
|
||||
"@esbuild/openharmony-arm64": "0.27.7",
|
||||
"@esbuild/sunos-x64": "0.27.7",
|
||||
"@esbuild/win32-arm64": "0.27.7",
|
||||
"@esbuild/win32-ia32": "0.27.7",
|
||||
"@esbuild/win32-x64": "0.27.7"
|
||||
}
|
||||
},
|
||||
"node_modules/make-error": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/ts-node": {
|
||||
"version": "10.9.2",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
|
||||
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@cspotcode/source-map-support": "^0.8.0",
|
||||
"@tsconfig/node10": "^1.0.7",
|
||||
"@tsconfig/node12": "^1.0.7",
|
||||
"@tsconfig/node14": "^1.0.0",
|
||||
"@tsconfig/node16": "^1.0.2",
|
||||
"acorn": "^8.4.1",
|
||||
"acorn-walk": "^8.1.1",
|
||||
"arg": "^4.1.0",
|
||||
"create-require": "^1.1.0",
|
||||
"diff": "^4.0.1",
|
||||
"make-error": "^1.1.1",
|
||||
"v8-compile-cache-lib": "^3.0.1",
|
||||
"yn": "3.1.1"
|
||||
},
|
||||
"bin": {
|
||||
"ts-node": "dist/bin.js",
|
||||
"ts-node-cwd": "dist/bin-cwd.js",
|
||||
"ts-node-esm": "dist/bin-esm.js",
|
||||
"ts-node-script": "dist/bin-script.js",
|
||||
"ts-node-transpile-only": "dist/bin-transpile.js",
|
||||
"ts-script": "dist/bin-script-deprecated.js"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@swc/core": ">=1.2.50",
|
||||
"@swc/wasm": ">=1.2.50",
|
||||
"@types/node": "*",
|
||||
"typescript": ">=2.7"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@swc/core": {
|
||||
"optional": true
|
||||
},
|
||||
"@swc/wasm": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/tunnel": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
||||
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.9.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "5.29.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz",
|
||||
"integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fastify/busboy": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "7.18.2",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
|
||||
"integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/v8-compile-cache-lib": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/yn": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gh-scripting-compiler",
|
||||
"version": "0.0.1",
|
||||
"version": "1.0.0",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "node esbuild.js",
|
||||
@@ -8,12 +8,12 @@
|
||||
"package": "node esbuild.js --production"
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.0"
|
||||
"@actions/core": "3.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.0.0",
|
||||
"esbuild": "^0.27.2"
|
||||
"typescript": "7.0.2",
|
||||
"esbuild": "0.28.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
name: 'Install Lua Addon'
|
||||
description: 'Installs DCS Lua addons and type definitions for scripting.'
|
||||
inputs:
|
||||
destination-path:
|
||||
description: 'The destination path in the repository where lua-addons should be installed.'
|
||||
required: true
|
||||
default: 'lua-addons'
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Copy lua-addons
|
||||
run: |
|
||||
cp -r ../dutchies-dcs-scripting-tools/lua-addons ./lua-addons
|
||||
shell: bash
|
||||
working-directory: ${{ github.action_path }}
|
||||
|
||||
- name: Build action
|
||||
run: |
|
||||
npm ci
|
||||
npm run build
|
||||
shell: bash
|
||||
working-directory: ${{ github.action_path }}
|
||||
|
||||
- name: Install lua-addons
|
||||
run: node ${{ github.action_path }}/dist/index.js
|
||||
shell: bash
|
||||
working-directory: ${{ github.workspace }}
|
||||
env:
|
||||
INPUT_DESTINATION-PATH: ${{ inputs.destination-path }}
|
||||
@@ -0,0 +1,32 @@
|
||||
const esbuild = require("esbuild");
|
||||
|
||||
const production = process.argv.includes('--production');
|
||||
const watch = process.argv.includes('--watch');
|
||||
|
||||
async function main() {
|
||||
const ctx = await esbuild.context({
|
||||
entryPoints: [
|
||||
'src/index.ts'
|
||||
],
|
||||
bundle: true,
|
||||
format: 'cjs',
|
||||
minify: production,
|
||||
sourcemap: !production,
|
||||
sourcesContent: false,
|
||||
platform: 'node',
|
||||
outfile: 'dist/index.js',
|
||||
external: ['@actions/core'],
|
||||
logLevel: 'silent',
|
||||
});
|
||||
if (watch) {
|
||||
await ctx.watch();
|
||||
} else {
|
||||
await ctx.rebuild();
|
||||
await ctx.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(e => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
||||
+1145
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "gh-lua-addon-installer",
|
||||
"version": "1.0.0",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "node esbuild.js",
|
||||
"watch": "node esbuild.js --watch",
|
||||
"package": "node esbuild.js --production"
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/core": "1.10.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "7.0.2",
|
||||
"esbuild": "0.28.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
import * as core from '@actions/core';
|
||||
import * as fs from 'fs/promises';
|
||||
import * as path from 'path';
|
||||
import { existsSync } from 'fs';
|
||||
|
||||
async function copyDirectory(src: string, dest: string): Promise<void> {
|
||||
await fs.mkdir(dest, { recursive: true });
|
||||
const entries = await fs.readdir(src, { withFileTypes: true });
|
||||
|
||||
for (const entry of entries) {
|
||||
const srcPath = path.join(src, entry.name);
|
||||
const destPath = path.join(dest, entry.name);
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
await copyDirectory(srcPath, destPath);
|
||||
} else {
|
||||
await fs.copyFile(srcPath, destPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
const destinationPath = core.getInput('destination-path');
|
||||
if (!destinationPath) {
|
||||
core.setFailed('Destination path is required.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Reference lua-addons relative to the dist directory
|
||||
// __dirname is dist/, so lua-addons is one level up
|
||||
const bundledAddonsDir = path.resolve(__dirname, '../lua-addons');
|
||||
|
||||
// Verify bundled addons directory exists
|
||||
if (!existsSync(bundledAddonsDir)) {
|
||||
core.setFailed(`Lua-addons directory not found at: ${bundledAddonsDir}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the workspace root and resolve destination path
|
||||
const workspaceRoot = process.env.GITHUB_WORKSPACE || process.cwd();
|
||||
const absoluteDestinationPath = path.join(workspaceRoot, destinationPath);
|
||||
|
||||
core.info(`Copying lua-addons to: ${absoluteDestinationPath}`);
|
||||
|
||||
// Create destination directory if it doesn't exist
|
||||
await fs.mkdir(absoluteDestinationPath, { recursive: true });
|
||||
|
||||
// Copy all bundled addons to the destination
|
||||
const addons = await fs.readdir(bundledAddonsDir, { withFileTypes: true });
|
||||
for (const addon of addons) {
|
||||
if (addon.isDirectory()) {
|
||||
const sourceAddonDir = path.join(bundledAddonsDir, addon.name);
|
||||
const destAddonDir = path.join(absoluteDestinationPath, addon.name);
|
||||
|
||||
core.info(`Installing addon: ${addon.name}`);
|
||||
await copyDirectory(sourceAddonDir, destAddonDir);
|
||||
core.info(`✓ ${addon.name} installed`);
|
||||
}
|
||||
}
|
||||
|
||||
core.info('Lua addons installation completed successfully.');
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
core.setFailed(error.message);
|
||||
} else {
|
||||
core.setFailed('An unknown error occurred');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "commonjs",
|
||||
"types": ["node"],
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
]
|
||||
}
|
||||
Generated
+29
-15
@@ -11,7 +11,7 @@
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^10.0.10",
|
||||
"@types/node": "22.x",
|
||||
"@types/node": "^22.20.2",
|
||||
"@types/vscode": "^1.108.1",
|
||||
"@vscode/test-cli": "^0.0.12",
|
||||
"@vscode/test-electron": "^2.5.2",
|
||||
@@ -47,7 +47,7 @@
|
||||
"typescript-eslint": "8.70.0"
|
||||
},
|
||||
"engines": {
|
||||
"vscode": "1.108.1"
|
||||
"vscode": "^1.108.1"
|
||||
}
|
||||
},
|
||||
"dutchies-dcs-scripting-tools/node_modules/@eslint/config-array": {
|
||||
@@ -1220,29 +1220,43 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@humanfs/core": {
|
||||
"version": "0.19.1",
|
||||
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
|
||||
"integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
|
||||
"version": "0.19.2",
|
||||
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz",
|
||||
"integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@humanfs/types": "^0.15.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.18.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@humanfs/node": {
|
||||
"version": "0.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz",
|
||||
"integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==",
|
||||
"version": "0.16.8",
|
||||
"resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz",
|
||||
"integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@humanfs/core": "^0.19.1",
|
||||
"@humanfs/core": "^0.19.2",
|
||||
"@humanfs/types": "^0.15.0",
|
||||
"@humanwhocodes/retry": "^0.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.18.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@humanfs/types": {
|
||||
"version": "0.15.0",
|
||||
"resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz",
|
||||
"integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=18.18.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/module-importer": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
|
||||
@@ -1374,9 +1388,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.19.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.17.tgz",
|
||||
"integrity": "sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==",
|
||||
"version": "22.20.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.2.tgz",
|
||||
"integrity": "sha512-xlvWf4Vs9n1PEVYwP1n4vvG07M6y8WgvJ2t0vbrWTmijsIHp1cS+uJ2kMIRdY3nHZK0nCYKrPeD171+SzF4/zw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -3964,9 +3978,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz",
|
||||
"integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==",
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz",
|
||||
"integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^10.0.10",
|
||||
"@types/node": "22.x",
|
||||
"@types/node": "^22.20.2",
|
||||
"@types/vscode": "^1.108.1",
|
||||
"@vscode/test-cli": "^0.0.12",
|
||||
"@vscode/test-electron": "^2.5.2",
|
||||
|
||||
Reference in New Issue
Block a user