nanos-lint 3.3.0 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +92 -14
- package/action.yml +28 -1
- package/dist/{cli-CsIAHyRZ.js → cli-DN7ZhC9e.js} +196 -30
- package/dist/cli-DN7ZhC9e.js.map +1 -0
- package/dist/cli-dxsaVVVq.d.ts.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/package.json +1 -1
- package/dist/cli-CsIAHyRZ.js.map +0 -1
package/README.md
CHANGED
|
@@ -73,6 +73,23 @@ To pre-populate all required assets (both LuaLS binary and nanos world annotatio
|
|
|
73
73
|
npx nanos-lint warmup
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
+
Offline execution uses only local dependencies and skips all nanos-lint network requests:
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
nanos-lint warmup # provision online
|
|
80
|
+
nanos-lint check Packages/events --offline
|
|
81
|
+
npx --offline nanos-lint check Packages/events --offline
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
For `latest`, offline mode selects the highest usable cached version (numeric tag order)
|
|
85
|
+
and reports it, then tries a bundled binary or PATH. `LUALS_BIN` overrides discovery.
|
|
86
|
+
Pinned versions require a matching cache or local executable. Custom annotations
|
|
87
|
+
(`--annotations` or `NANOS_ANNOTATIONS_PATH`), bundled annotations, and valid stale
|
|
88
|
+
cached annotations work offline. `warmup --offline` verifies local assets without
|
|
89
|
+
downloading them. Missing assets fail with provisioning instructions.
|
|
90
|
+
The flag controls nanos-lint; npm/npx may access the registry before it starts. Use
|
|
91
|
+
a preinstalled executable or npm's own `--offline` with an already cached package.
|
|
92
|
+
|
|
76
93
|
---
|
|
77
94
|
|
|
78
95
|
## GitHub Actions Integration
|
|
@@ -104,20 +121,23 @@ jobs:
|
|
|
104
121
|
|
|
105
122
|
### Action Inputs
|
|
106
123
|
|
|
107
|
-
| Input
|
|
108
|
-
|
|
|
109
|
-
| `path`
|
|
110
|
-
| `paths`
|
|
111
|
-
| `dep`
|
|
112
|
-
| `checklevel`
|
|
113
|
-
| `config`
|
|
114
|
-
| `annotations`
|
|
115
|
-
| `ignore`
|
|
116
|
-
| `luals-version`
|
|
117
|
-
| `
|
|
118
|
-
| `
|
|
119
|
-
| `
|
|
120
|
-
| `
|
|
124
|
+
| Input | Description | Default |
|
|
125
|
+
| :---------------- | :------------------------------------------------------------------------------------ | :-------- |
|
|
126
|
+
| `path` | Path to workspace directory or Lua file to check | `.` |
|
|
127
|
+
| `paths` | One or more workspace target paths or Lua files to check (newline or comma-separated) | `""` |
|
|
128
|
+
| `dep` | External package dependency paths or definition files (newline or comma-separated) | `""` |
|
|
129
|
+
| `checklevel` | Minimum severity to report (`Error`, `Warning`, `Information`, `Hint`) | `Warning` |
|
|
130
|
+
| `config` | Path to a custom `.luarc.json` configuration file | `""` |
|
|
131
|
+
| `annotations` | Path to a custom `annotations.lua` file | `""` |
|
|
132
|
+
| `ignore` | Files or directories to ignore (supports glob patterns, newline or comma separated) | `""` |
|
|
133
|
+
| `luals-version` | Version of `lua-language-server` to use | `latest` |
|
|
134
|
+
| `baseline` | Accepted diagnostic baseline; only new diagnostics fail | `""` |
|
|
135
|
+
| `write-baseline` | Record current diagnostics and exit successfully | `""` |
|
|
136
|
+
| `baseline-strict` | Also fail when baseline entries disappear (requires `baseline`) | `false` |
|
|
137
|
+
| `fail-on-error` | Fail the workflow step if diagnostics are found | `true` |
|
|
138
|
+
| `log-level` | Logging level (`error`, `warn`, `info`, `debug`, `silent`) | `warn` |
|
|
139
|
+
| `realm` | Execution realm to check (`all`, `client`, `server`, `shared`) | `all` |
|
|
140
|
+
| `cache` | Whether to cache the LuaLS binary and annotations across workflow runs | `true` |
|
|
121
141
|
|
|
122
142
|
`paths` takes precedence over `path` when both are set; `path` is kept for backwards compatibility with the single-target form.
|
|
123
143
|
|
|
@@ -158,13 +178,54 @@ OPTIONS:
|
|
|
158
178
|
--format=<format> Output format: pretty, json, github (default: pretty)
|
|
159
179
|
--github Output in GitHub Actions format (shortcut for --format=github)
|
|
160
180
|
--luals-version=<ver> Version of LuaLS to use (default: latest, falling back to 3.19.1 when offline)
|
|
181
|
+
--baseline <path> Report and fail only on new diagnostics
|
|
182
|
+
--write-baseline <path> Record diagnostics and exit 0
|
|
183
|
+
--baseline-strict Also fail on stale entries (requires --baseline)
|
|
161
184
|
--no-fail Do not exit with code 1 if diagnostics are found
|
|
162
185
|
--realm <realm> Execution realm to check: all, client, server, shared (default: all)
|
|
186
|
+
--offline Use local dependencies only; never access the network
|
|
163
187
|
--no-progress Disable the interactive download, extraction and realm derivation progress display
|
|
188
|
+
-t, --template <path> (init command only) Use a custom JSONC scaffold template
|
|
164
189
|
--vendor (init command only) Vendor annotations.lua into .nanos-lint/ inside workspace
|
|
165
190
|
-f, --force (init and copy-annotations only) Overwrite existing files
|
|
166
191
|
```
|
|
167
192
|
|
|
193
|
+
### Diagnostic Baselines
|
|
194
|
+
|
|
195
|
+
Use a diagnostic baseline to accept an existing backlog and fail on new problems:
|
|
196
|
+
|
|
197
|
+
```sh
|
|
198
|
+
nanos-lint check . --write-baseline .nanos-lint/baseline.json
|
|
199
|
+
nanos-lint check . --baseline .nanos-lint/baseline.json
|
|
200
|
+
nanos-lint check . --baseline .nanos-lint/baseline.json --baseline-strict
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Recording writes all reported diagnostics in a deterministic versioned JSON file,
|
|
204
|
+
creates parent directories, and exits 0 (also with `--no-fail`). Comparison shows
|
|
205
|
+
only new diagnostics with a summary such as `12 new, 154 baselined, 166 total`.
|
|
206
|
+
JSON output retains every diagnostic and adds `baseline: true|false` plus
|
|
207
|
+
`baselineSummary` counts. GitHub annotations are emitted only for new diagnostics.
|
|
208
|
+
|
|
209
|
+
Matches use paths relative to the checked root, diagnostic code, whitespace-normalized
|
|
210
|
+
message, severity, and occurrence counts. Line changes preserve matches; additional
|
|
211
|
+
occurrences or severity changes are new problems. Removed occurrences are stale and
|
|
212
|
+
only fail with `--baseline-strict`. `--no-fail` suppresses diagnostic failure, including
|
|
213
|
+
strict staleness; invalid baseline files still fail. Missing, invalid, or incompatible
|
|
214
|
+
files require regeneration with `--write-baseline`. Recording and comparison are
|
|
215
|
+
mutually exclusive. Keep targets, realm, check level, configuration, and LuaLS version
|
|
216
|
+
consistent between runs; pin `--luals-version` to avoid diagnostic changes from upgrades.
|
|
217
|
+
Relative baseline paths are resolved from the working directory.
|
|
218
|
+
|
|
219
|
+
The GitHub Action exposes the same options as `baseline`, `write-baseline`, and
|
|
220
|
+
`baseline-strict` inputs:
|
|
221
|
+
|
|
222
|
+
```yaml
|
|
223
|
+
- uses: vugi99/nanos-lint@v3
|
|
224
|
+
with:
|
|
225
|
+
baseline: .nanos-lint/baseline.json
|
|
226
|
+
baseline-strict: "false"
|
|
227
|
+
```
|
|
228
|
+
|
|
168
229
|
### Progress Display
|
|
169
230
|
|
|
170
231
|
Downloads and extractions (`LuaLS` archive, `annotations.lua`, realm derivation) report their
|
|
@@ -251,6 +312,23 @@ npx nanos-lint copy-annotations ./types
|
|
|
251
312
|
|
|
252
313
|
`copy-annotations` refuses to overwrite an existing file unless `--force` is passed.
|
|
253
314
|
|
|
315
|
+
### Custom Init Templates
|
|
316
|
+
|
|
317
|
+
Initialize packages from a shared configuration template:
|
|
318
|
+
|
|
319
|
+
```sh
|
|
320
|
+
nanos-lint init Packages/events --template tools/team-luarc.json
|
|
321
|
+
nanos-lint init Packages/events -t tools/team-luarc.json --vendor --annotations tools/annotations.lua
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
The custom JSON/JSONC file becomes the base configuration. Relative paths in its
|
|
325
|
+
settings are interpreted relative to the target workspace, so shared templates can
|
|
326
|
+
use entries such as `nanos.deps: ["../collider"]`. Custom settings and realm mappings
|
|
327
|
+
are preserved, including `{}` to disable realms. Omitted realm mappings receive
|
|
328
|
+
the conventional Server/Client/Shared defaults. Vendoring adds its annotation
|
|
329
|
+
library, ignore and exclusion entries without discarding template entries. Existing
|
|
330
|
+
`.luarc.json` files still require `--force` to overwrite.
|
|
331
|
+
|
|
254
332
|
### Realm Mapping (`nanos.realms`)
|
|
255
333
|
|
|
256
334
|
nanos world runs two isolated Lua VMs: the server executes `Server/**` + `Shared/**`, the client executes `Client/**` + `Shared/**`. `nanos-lint` mirrors that split and lets you describe a non-standard layout in `.luarc.json`:
|
package/action.yml
CHANGED
|
@@ -34,6 +34,18 @@ inputs:
|
|
|
34
34
|
description: 'Version of LuaLS to use (or "latest")'
|
|
35
35
|
required: false
|
|
36
36
|
default: "latest"
|
|
37
|
+
baseline:
|
|
38
|
+
description: "Path to an accepted diagnostic baseline; only new diagnostics fail"
|
|
39
|
+
required: false
|
|
40
|
+
default: ""
|
|
41
|
+
write-baseline:
|
|
42
|
+
description: "Record current diagnostics to this baseline path and exit successfully"
|
|
43
|
+
required: false
|
|
44
|
+
default: ""
|
|
45
|
+
baseline-strict:
|
|
46
|
+
description: "Also fail on stale baseline entries (requires baseline)"
|
|
47
|
+
required: false
|
|
48
|
+
default: "false"
|
|
37
49
|
fail-on-error:
|
|
38
50
|
description: "Whether to fail the action step if diagnostic errors/warnings are found"
|
|
39
51
|
required: false
|
|
@@ -93,6 +105,9 @@ runs:
|
|
|
93
105
|
INPUT_CONFIG: ${{ inputs.config }}
|
|
94
106
|
INPUT_ANNOTATIONS: ${{ inputs.annotations }}
|
|
95
107
|
INPUT_LUALS_VERSION: ${{ inputs.luals-version }}
|
|
108
|
+
INPUT_BASELINE: ${{ inputs.baseline }}
|
|
109
|
+
INPUT_WRITE_BASELINE: ${{ inputs.write-baseline }}
|
|
110
|
+
INPUT_BASELINE_STRICT: ${{ inputs.baseline-strict }}
|
|
96
111
|
INPUT_FAIL_ON_ERROR: ${{ inputs.fail-on-error }}
|
|
97
112
|
INPUT_LOG_LEVEL: ${{ inputs.log-level }}
|
|
98
113
|
INPUT_REALM: ${{ inputs.realm }}
|
|
@@ -153,6 +168,18 @@ runs:
|
|
|
153
168
|
done <<< "$INPUT_IGNORE"
|
|
154
169
|
fi
|
|
155
170
|
|
|
171
|
+
if [ -n "$INPUT_BASELINE" ]; then
|
|
172
|
+
ARGS+=("--baseline=$INPUT_BASELINE")
|
|
173
|
+
fi
|
|
174
|
+
|
|
175
|
+
if [ -n "$INPUT_WRITE_BASELINE" ]; then
|
|
176
|
+
ARGS+=("--write-baseline=$INPUT_WRITE_BASELINE")
|
|
177
|
+
fi
|
|
178
|
+
|
|
179
|
+
if [ "$INPUT_BASELINE_STRICT" = "true" ]; then
|
|
180
|
+
ARGS+=("--baseline-strict")
|
|
181
|
+
fi
|
|
182
|
+
|
|
156
183
|
if [ "$INPUT_FAIL_ON_ERROR" = "false" ]; then
|
|
157
184
|
ARGS+=("--no-fail")
|
|
158
185
|
fi
|
|
@@ -172,5 +199,5 @@ runs:
|
|
|
172
199
|
else
|
|
173
200
|
# Exact version: a range could run a different release than the pinned
|
|
174
201
|
# tag. Bump together with "version" in package.json.
|
|
175
|
-
npx --yes nanos-lint@3.
|
|
202
|
+
npx --yes nanos-lint@3.4.0 "${ARGS[@]}"
|
|
176
203
|
fi
|
|
@@ -1465,21 +1465,21 @@ function initWorkspace(workspacePath, options) {
|
|
|
1465
1465
|
const targetFile = path.join(workspacePath, ".luarc.json");
|
|
1466
1466
|
if (fs.existsSync(targetFile) && !options?.force) throw new ConfigError(`.luarc.json already exists at ${targetFile}. Use --force to overwrite.`, "ERR_CONFIG_EXISTS", "Pass --force to overwrite the existing .luarc.json file.");
|
|
1467
1467
|
if (options?.annotationsPath && !options.vendor) throw new ConfigError("--annotations requires --vendor: nanos-lint init does not pin or vendor annotations.lua by default.", "ERR_ANNOTATIONS_WITHOUT_VENDOR", "Run 'nanos-lint init --vendor --annotations <path>' (or pass vendor: true), or omit the custom path to use the managed annotations cache.");
|
|
1468
|
-
const template = loadConfigFile(getDefaultTemplatePath());
|
|
1468
|
+
const template = loadConfigFile(path.resolve(options?.templatePath ?? getDefaultTemplatePath()));
|
|
1469
|
+
if (!template || typeof template !== "object" || Array.isArray(template)) throw new ConfigError("Init template must contain a configuration object.", "ERR_CONFIG_PARSE");
|
|
1470
|
+
template.nanos ??= {};
|
|
1471
|
+
template.nanos.realms ??= Object.fromEntries(DEFAULT_REALM_MAPPINGS.map(({ pattern, realm }) => [pattern, realm]));
|
|
1469
1472
|
if (options?.vendor) {
|
|
1470
1473
|
const sourceAnnotations = options.annotationsPath || getDefaultAnnotationsPath();
|
|
1471
1474
|
if (!fs.existsSync(sourceAnnotations)) throw new ConfigError(`Definitions file not found at ${sourceAnnotations}. Make sure annotations have been downloaded or pass a valid file with --annotations.`, "ERR_ANNOTATIONS_NOT_FOUND", "Run 'nanos-lint warmup' to download annotations or provide --annotations <path>.");
|
|
1472
|
-
const
|
|
1473
|
-
fs.mkdirSync(
|
|
1474
|
-
const targetAnnotations = path.join(targetNanosDir, "annotations.lua");
|
|
1475
|
+
const targetAnnotations = path.join(workspacePath, ".nanos-lint", "annotations.lua");
|
|
1476
|
+
fs.mkdirSync(path.dirname(targetAnnotations), { recursive: true });
|
|
1475
1477
|
fs.copyFileSync(sourceAnnotations, targetAnnotations);
|
|
1476
1478
|
template.workspace = template.workspace ?? {};
|
|
1477
|
-
template.workspace.library = [".nanos-lint/annotations.lua"];
|
|
1478
|
-
|
|
1479
|
-
if (!existingIgnore.includes(".nanos-lint")) template.workspace.ignoreDir = [".nanos-lint", ...existingIgnore];
|
|
1479
|
+
template.workspace.library = [.../* @__PURE__ */ new Set([...template.workspace.library ?? [], ".nanos-lint/annotations.lua"])];
|
|
1480
|
+
template.workspace.ignoreDir = [.../* @__PURE__ */ new Set([".nanos-lint", ...template.workspace.ignoreDir ?? []])];
|
|
1480
1481
|
template.files = template.files ?? {};
|
|
1481
|
-
|
|
1482
|
-
if (!existingExclude.includes(".nanos-lint/**")) template.files.exclude = [".nanos-lint/**", ...existingExclude];
|
|
1482
|
+
template.files.exclude = [.../* @__PURE__ */ new Set([".nanos-lint/**", ...template.files.exclude ?? []])];
|
|
1483
1483
|
}
|
|
1484
1484
|
fs.writeFileSync(targetFile, JSON.stringify(template, null, 2), "utf-8");
|
|
1485
1485
|
return targetFile;
|
|
@@ -7135,6 +7135,40 @@ function resolveCheckTargets(rawPaths) {
|
|
|
7135
7135
|
};
|
|
7136
7136
|
}
|
|
7137
7137
|
//#endregion
|
|
7138
|
+
//#region src/luals/offline.ts
|
|
7139
|
+
/** Validates an explicit local executable and checks a requested version against its output. */
|
|
7140
|
+
function validateOfflineBinary(binary, version) {
|
|
7141
|
+
const resolved = assertValidLuaLSBinary(binary, "offline local binary");
|
|
7142
|
+
if (version !== "latest") {
|
|
7143
|
+
if (!execFileSync(resolved, ["--version"], {
|
|
7144
|
+
encoding: "utf-8",
|
|
7145
|
+
timeout: 5e3
|
|
7146
|
+
}).split(/\s+/).some((part) => sanitizeLuaLSVersion(part) === version)) throw new LuaLSError(`Offline LuaLS binary ${resolved} does not match requested version ${version}.`, "ERR_LUALS_OFFLINE", `Run 'nanos-lint warmup --luals-version ${version}' online or set LUALS_BIN to a matching binary.`);
|
|
7147
|
+
}
|
|
7148
|
+
return resolved;
|
|
7149
|
+
}
|
|
7150
|
+
/** Resolves local LuaLS assets without changing cache entries or discovering remote releases. */
|
|
7151
|
+
function resolveOfflineLuaLS(version, cacheDir = getBaseLuaLSCacheDir()) {
|
|
7152
|
+
const requested = version === "latest" ? version : sanitizeLuaLSVersion(version);
|
|
7153
|
+
if (!requested) throw new LuaLSError(`Invalid LuaLS version: "${version}".`, "ERR_LUALS_INVALID_VERSION");
|
|
7154
|
+
if (process.env.LUALS_BIN) return validateOfflineBinary(process.env.LUALS_BIN, requested);
|
|
7155
|
+
const versions = listCachedLuaLSVersions(cacheDir).sort((a, b) => b.localeCompare(a, "en", { numeric: true }));
|
|
7156
|
+
const selected = requested === "latest" ? versions[0] : versions.find((v) => v === requested);
|
|
7157
|
+
if (selected) {
|
|
7158
|
+
logger.info(`[luals] Offline: using cached LuaLS ${selected}.`);
|
|
7159
|
+
return path.join(getCacheDir(selected, cacheDir), getPlatformInfo(selected).binaryRelativePath);
|
|
7160
|
+
}
|
|
7161
|
+
const bundled = path.join(getPackageRoot(), getPlatformInfo(FALLBACK_LUALS_VERSION).binaryRelativePath);
|
|
7162
|
+
if (fs.existsSync(bundled)) return validateOfflineBinary(bundled, requested);
|
|
7163
|
+
try {
|
|
7164
|
+
const found = execFileSync(process.platform === "win32" ? "where.exe" : "which", ["lua-language-server"], { encoding: "utf-8" }).trim().split(/\r?\n/)[0];
|
|
7165
|
+
if (found) return validateOfflineBinary(found, requested);
|
|
7166
|
+
} catch (err) {
|
|
7167
|
+
rethrowLuaLSPermissionError(err, "lua-language-server", "execute");
|
|
7168
|
+
}
|
|
7169
|
+
throw new LuaLSError(`Offline: no usable local LuaLS binary for ${requested}.`, "ERR_LUALS_OFFLINE", `Run 'nanos-lint warmup${requested === "latest" ? "" : ` --luals-version ${requested}`}' online or set LUALS_BIN to a matching local executable.`);
|
|
7170
|
+
}
|
|
7171
|
+
//#endregion
|
|
7138
7172
|
//#region src/luals/files.ts
|
|
7139
7173
|
/** Directories skipped unless the workspace config overrides `workspace.ignoreDir`. */
|
|
7140
7174
|
const DEFAULT_IGNORE_DIRS = [
|
|
@@ -7303,6 +7337,7 @@ function isOfflineError(err) {
|
|
|
7303
7337
|
}
|
|
7304
7338
|
/** Resolves the executable path of a LuaLS binary from env, bundle, cache, or network download. */
|
|
7305
7339
|
async function resolveLuaLSBinary(version = DEFAULT_LUALS_VERSION, options) {
|
|
7340
|
+
if (options?.offline) return resolveOfflineLuaLS(version, options.cacheDir);
|
|
7306
7341
|
if (process.env.LUALS_BIN) return assertValidLuaLSBinary(process.env.LUALS_BIN, "LUALS_BIN");
|
|
7307
7342
|
if (options?.reuseExisting !== false && (!version || version === "latest")) {
|
|
7308
7343
|
const defaultInfo = getPlatformInfo(FALLBACK_LUALS_VERSION);
|
|
@@ -7448,7 +7483,7 @@ async function runLuaLSCheck(targetPath, configPath, options) {
|
|
|
7448
7483
|
logger.debug(`[luals] Failed to resolve native realpath for target: ${err instanceof Error ? err.message : String(err)}`);
|
|
7449
7484
|
}
|
|
7450
7485
|
if (!fs.existsSync(absoluteTarget)) throw new LuaLSError(`Target path does not exist: ${targetPath}`, "ERR_TARGET_NOT_FOUND", "Verify that the target path exists and is accessible.");
|
|
7451
|
-
const binary = options.lualsBin ? assertValidLuaLSBinary(options.lualsBin, "--luals-bin") : await resolveLuaLSBinary(options.lualsVersion);
|
|
7486
|
+
const binary = options.lualsBin ? options.offline ? validateOfflineBinary(options.lualsBin, options.lualsVersion ?? "latest") : assertValidLuaLSBinary(options.lualsBin, "--luals-bin") : await resolveLuaLSBinary(options.lualsVersion, { offline: options.offline });
|
|
7452
7487
|
let checkDir = absoluteTarget;
|
|
7453
7488
|
let targetFileOnly = null;
|
|
7454
7489
|
if (fs.statSync(absoluteTarget).isFile()) {
|
|
@@ -7990,7 +8025,7 @@ function formatPretty(result, cwd = process.cwd(), useColor = shouldEnableColor(
|
|
|
7990
8025
|
const c = getColors(useColor);
|
|
7991
8026
|
const symCross = "✖ ";
|
|
7992
8027
|
const symCheck = "✔ ";
|
|
7993
|
-
if (result.passed) {
|
|
8028
|
+
if (result.passed && !result.baselineSummary) {
|
|
7994
8029
|
const fileStr = pluralize(result.totalFilesChecked ?? result.totalFiles, "file");
|
|
7995
8030
|
return `${c.green}${c.bold}${symCheck}Diagnosis completed, no problems found across ${fileStr}.${c.reset}`;
|
|
7996
8031
|
}
|
|
@@ -8006,6 +8041,7 @@ function formatPretty(result, cwd = process.cwd(), useColor = shouldEnableColor(
|
|
|
8006
8041
|
logger.debug(`Failed to read file snippet for ${filePath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
8007
8042
|
}
|
|
8008
8043
|
for (const d of diags) {
|
|
8044
|
+
if (d.baseline) continue;
|
|
8009
8045
|
const line = d.range.start.line + 1;
|
|
8010
8046
|
const col = d.range.start.character + 1;
|
|
8011
8047
|
const badge = formatSeverityBadge(d.severity, useColor);
|
|
@@ -8031,8 +8067,10 @@ function formatPretty(result, cwd = process.cwd(), useColor = shouldEnableColor(
|
|
|
8031
8067
|
else if (d.severity === 2) warnings++;
|
|
8032
8068
|
}
|
|
8033
8069
|
lines.push("");
|
|
8034
|
-
const
|
|
8035
|
-
|
|
8070
|
+
const counts = result.baselineSummary;
|
|
8071
|
+
const summary = counts ? `Diagnosis complete: ${counts.new} new, ${counts.baselined} baselined, ${counts.total} total (${counts.stale} stale baseline entries).` : formatProblemSummary(result.totalProblems, errors, warnings, result.totalFiles);
|
|
8072
|
+
const color = result.passed ? c.green : c.red;
|
|
8073
|
+
lines.push(`${color}${c.bold}${result.passed ? symCheck : symCross}${summary}${c.reset}`);
|
|
8036
8074
|
return lines.join("\n");
|
|
8037
8075
|
}
|
|
8038
8076
|
/** Formats check diagnostics into GitHub Actions workflow annotation commands. */
|
|
@@ -8043,6 +8081,7 @@ function formatGitHubAnnotations(result, cwd = process.cwd()) {
|
|
|
8043
8081
|
const filePath = fileUriToPath(rawUri);
|
|
8044
8082
|
const escapedFile = (path.isAbsolute(filePath) ? path.relative(cwd, filePath).replace(/\\/g, "/") : filePath.replace(/\\/g, "/")).replace(/%/g, "%25").replace(/,/g, "%2C");
|
|
8045
8083
|
for (const d of diags) {
|
|
8084
|
+
if (d.baseline) continue;
|
|
8046
8085
|
const line = d.range.start.line + 1;
|
|
8047
8086
|
const col = d.range.start.character + 1;
|
|
8048
8087
|
const endLine = d.range.end.line + 1;
|
|
@@ -11319,6 +11358,10 @@ async function resolveAnnotations(options = {}) {
|
|
|
11319
11358
|
if (fs.existsSync(bundled) && isAnnotationsValid(bundled)) return bundled;
|
|
11320
11359
|
const cacheDir = options.cacheDir ?? getAnnotationsCacheDir();
|
|
11321
11360
|
const cachedAnnotationsFile = path.join(cacheDir, ANNOTATIONS_FILENAME);
|
|
11361
|
+
if (options.offline) {
|
|
11362
|
+
if (isAnnotationsValid(cachedAnnotationsFile)) return cachedAnnotationsFile;
|
|
11363
|
+
throw new AnnotationsError(`Offline: no usable local annotations.lua at ${cachedAnnotationsFile}.`, "ERR_ANNOTATIONS_OFFLINE", "Run 'nanos-lint warmup' online or specify --annotations <path>.");
|
|
11364
|
+
}
|
|
11322
11365
|
const metadata = readAnnotationsMetadata(cacheDir);
|
|
11323
11366
|
const { dateStr } = getTodayDateString();
|
|
11324
11367
|
if (fs.existsSync(cachedAnnotationsFile) && !isAnnotationsValid(cachedAnnotationsFile)) {
|
|
@@ -11374,7 +11417,10 @@ async function copyAnnotations(targetPath = DEFAULT_COPY_TARGET, options = {}) {
|
|
|
11374
11417
|
let resolvedTarget = path.resolve(targetPath);
|
|
11375
11418
|
if (targetPath.endsWith("/") || targetPath.endsWith("\\") || fs.existsSync(resolvedTarget) && fs.statSync(resolvedTarget).isDirectory() || path.extname(resolvedTarget).toLowerCase() !== ".lua") resolvedTarget = path.join(resolvedTarget, ANNOTATIONS_FILENAME);
|
|
11376
11419
|
if (fs.existsSync(resolvedTarget) && !options.force) throw new AnnotationsError(`Target annotations file already exists: ${resolvedTarget}. Use --force to overwrite.`, "ERR_ANNOTATIONS_EXISTS", "Pass --force to overwrite the existing annotations file.");
|
|
11377
|
-
const sourcePath = options.annotationsPath ? validateCustomAnnotationsPath(options.annotationsPath, "custom") : await resolveAnnotations({
|
|
11420
|
+
const sourcePath = options.annotationsPath ? validateCustomAnnotationsPath(options.annotationsPath, "custom") : await resolveAnnotations({
|
|
11421
|
+
cacheDir: options.cacheDir,
|
|
11422
|
+
offline: options.offline
|
|
11423
|
+
});
|
|
11378
11424
|
const targetDir = path.dirname(resolvedTarget);
|
|
11379
11425
|
fs.mkdirSync(targetDir, { recursive: true });
|
|
11380
11426
|
fs.copyFileSync(sourcePath, resolvedTarget);
|
|
@@ -11480,6 +11526,106 @@ function writeOutput(message) {
|
|
|
11480
11526
|
if (logger.isOutputEnabled()) console.log(message);
|
|
11481
11527
|
}
|
|
11482
11528
|
//#endregion
|
|
11529
|
+
//#region src/baseline.ts
|
|
11530
|
+
/** Builds a line-independent diagnostic identity relative to the checked workspace root. */
|
|
11531
|
+
function entryFor(root, uri, diagnostic) {
|
|
11532
|
+
const file = fileUriToPath(uri);
|
|
11533
|
+
return {
|
|
11534
|
+
path: path.relative(root, path.isAbsolute(file) ? file : path.resolve(root, file)).replace(/\\/g, "/"),
|
|
11535
|
+
code: diagnostic.code ?? "",
|
|
11536
|
+
message: diagnostic.message.replace(/\s+/g, " ").trim(),
|
|
11537
|
+
severity: diagnostic.severity,
|
|
11538
|
+
count: 1
|
|
11539
|
+
};
|
|
11540
|
+
}
|
|
11541
|
+
/** Serializes the fields defining a diagnostic identity, excluding occurrence count. */
|
|
11542
|
+
function keyFor(entry) {
|
|
11543
|
+
return JSON.stringify([
|
|
11544
|
+
entry.path,
|
|
11545
|
+
entry.code,
|
|
11546
|
+
entry.message,
|
|
11547
|
+
entry.severity
|
|
11548
|
+
]);
|
|
11549
|
+
}
|
|
11550
|
+
/** Records sorted diagnostic identities and multiplicities without source positions. */
|
|
11551
|
+
function createBaseline(result, root) {
|
|
11552
|
+
const entries = /* @__PURE__ */ new Map();
|
|
11553
|
+
for (const [uri, diagnostics] of Object.entries(result.diagnostics)) for (const diagnostic of diagnostics) {
|
|
11554
|
+
const entry = entryFor(root, uri, diagnostic);
|
|
11555
|
+
const key = keyFor(entry);
|
|
11556
|
+
const previous = entries.get(key);
|
|
11557
|
+
if (previous) previous.count++;
|
|
11558
|
+
else entries.set(key, entry);
|
|
11559
|
+
}
|
|
11560
|
+
return {
|
|
11561
|
+
version: 1,
|
|
11562
|
+
entries: [...entries.values()].sort((a, b) => {
|
|
11563
|
+
const left = keyFor(a);
|
|
11564
|
+
const right = keyFor(b);
|
|
11565
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
11566
|
+
})
|
|
11567
|
+
};
|
|
11568
|
+
}
|
|
11569
|
+
/** Validates a persisted baseline and rejects ambiguous or incompatible entries. */
|
|
11570
|
+
function readBaseline(file) {
|
|
11571
|
+
try {
|
|
11572
|
+
const parsed = JSON.parse(fs.readFileSync(file, "utf-8"));
|
|
11573
|
+
if (parsed?.version !== 1 || !Array.isArray(parsed.entries)) throw new Error("Unsupported baseline schema (expected version 1).");
|
|
11574
|
+
const keys = /* @__PURE__ */ new Set();
|
|
11575
|
+
for (const entry of parsed.entries) {
|
|
11576
|
+
if (!entry || typeof entry.path !== "string" || !entry.path || typeof entry.code !== "string" || typeof entry.message !== "string" || !Number.isInteger(entry.severity) || entry.severity < 1 || entry.severity > 4 || !Number.isSafeInteger(entry.count) || entry.count < 1) throw new Error("Invalid baseline diagnostic entry.");
|
|
11577
|
+
const key = keyFor(entry);
|
|
11578
|
+
if (keys.has(key)) throw new Error("Duplicate baseline diagnostic entry.");
|
|
11579
|
+
keys.add(key);
|
|
11580
|
+
}
|
|
11581
|
+
return parsed;
|
|
11582
|
+
} catch (cause) {
|
|
11583
|
+
throw new ConfigError(`Cannot read diagnostic baseline ${file}: ${cause instanceof Error ? cause.message : String(cause)}`, "ERR_BASELINE_READ", "Regenerate with 'nanos-lint check <targets> --write-baseline <path>' using the same targets and options.", { cause });
|
|
11584
|
+
}
|
|
11585
|
+
}
|
|
11586
|
+
/** Atomically writes a deterministic baseline, creating its parent directory if needed. */
|
|
11587
|
+
function writeBaseline(file, result, root) {
|
|
11588
|
+
try {
|
|
11589
|
+
writeAtomicFileSync(path.resolve(file), `${JSON.stringify(createBaseline(result, root), null, 2)}\n`);
|
|
11590
|
+
} catch (cause) {
|
|
11591
|
+
throw new ConfigError(`Cannot write diagnostic baseline ${file}: ${cause instanceof Error ? cause.message : String(cause)}`, "ERR_BASELINE_WRITE", "Choose a writable baseline path.", { cause });
|
|
11592
|
+
}
|
|
11593
|
+
}
|
|
11594
|
+
/** Classifies each diagnostic against an occurrence budget and computes strict staleness. */
|
|
11595
|
+
function compareBaseline(result, baseline, root, strict = false) {
|
|
11596
|
+
const remaining = new Map(baseline.entries.map((entry) => [keyFor(entry), entry.count]));
|
|
11597
|
+
const diagnostics = {};
|
|
11598
|
+
let baselined = 0;
|
|
11599
|
+
let total = 0;
|
|
11600
|
+
for (const [uri, items] of Object.entries(result.diagnostics)) diagnostics[uri] = [...items].sort((a, b) => a.range.start.line - b.range.start.line || a.range.start.character - b.range.start.character).map((diagnostic) => {
|
|
11601
|
+
const key = keyFor(entryFor(root, uri, diagnostic));
|
|
11602
|
+
const count = remaining.get(key) ?? 0;
|
|
11603
|
+
const matched = count > 0;
|
|
11604
|
+
if (matched) {
|
|
11605
|
+
remaining.set(key, count - 1);
|
|
11606
|
+
baselined++;
|
|
11607
|
+
}
|
|
11608
|
+
total++;
|
|
11609
|
+
return {
|
|
11610
|
+
...diagnostic,
|
|
11611
|
+
baseline: matched
|
|
11612
|
+
};
|
|
11613
|
+
});
|
|
11614
|
+
const stale = [...remaining.values()].reduce((sum, count) => sum + count, 0);
|
|
11615
|
+
const newProblems = total - baselined;
|
|
11616
|
+
return {
|
|
11617
|
+
...result,
|
|
11618
|
+
diagnostics,
|
|
11619
|
+
passed: newProblems === 0 && (!strict || stale === 0),
|
|
11620
|
+
baselineSummary: {
|
|
11621
|
+
new: newProblems,
|
|
11622
|
+
baselined,
|
|
11623
|
+
total,
|
|
11624
|
+
stale
|
|
11625
|
+
}
|
|
11626
|
+
};
|
|
11627
|
+
}
|
|
11628
|
+
//#endregion
|
|
11483
11629
|
//#region src/cli-check.ts
|
|
11484
11630
|
/** Executes the check command on target paths with specified options. */
|
|
11485
11631
|
async function executeCheckCommand(targetPaths = ["."], opts, setExitCode) {
|
|
@@ -11490,7 +11636,10 @@ async function executeCheckCommand(targetPaths = ["."], opts, setExitCode) {
|
|
|
11490
11636
|
setProgressMode("off");
|
|
11491
11637
|
logger.setDiagnosticStream("stderr");
|
|
11492
11638
|
}
|
|
11639
|
+
if (opts.baseline && opts.writeBaseline || opts.baselineStrict && !opts.baseline) throw new ConfigError("Use either --baseline or --write-baseline; --baseline-strict requires --baseline.", "ERR_BASELINE_OPTIONS");
|
|
11640
|
+
const baseline = opts.baseline ? readBaseline(path.resolve(opts.baseline)) : void 0;
|
|
11493
11641
|
const checkOptions = {
|
|
11642
|
+
offline: opts.offline,
|
|
11494
11643
|
path: rootPath,
|
|
11495
11644
|
paths: canonicalTargets,
|
|
11496
11645
|
configpath: opts.config,
|
|
@@ -11505,7 +11654,10 @@ async function executeCheckCommand(targetPaths = ["."], opts, setExitCode) {
|
|
|
11505
11654
|
const resolvedConfig = path.resolve(opts.config);
|
|
11506
11655
|
if (!fs.existsSync(resolvedConfig)) throw new ConfigError(`Configuration file not found: ${resolvedConfig}`, "ERR_CONFIG_NOT_FOUND", "Verify the path passed to --config exists and is readable.");
|
|
11507
11656
|
}
|
|
11508
|
-
const annotationsPath = await resolveAnnotations({
|
|
11657
|
+
const annotationsPath = await resolveAnnotations({
|
|
11658
|
+
customPath: opts.annotations,
|
|
11659
|
+
offline: opts.offline
|
|
11660
|
+
});
|
|
11509
11661
|
const userConfig = loadUserConfig(rootPath, checkOptions.configpath);
|
|
11510
11662
|
const realmPlan = planRealmCheck({
|
|
11511
11663
|
targetPath: rootPath,
|
|
@@ -11542,6 +11694,10 @@ async function executeCheckCommand(targetPaths = ["."], opts, setExitCode) {
|
|
|
11542
11694
|
}
|
|
11543
11695
|
}
|
|
11544
11696
|
}
|
|
11697
|
+
if (opts.writeBaseline) {
|
|
11698
|
+
writeBaseline(opts.writeBaseline, result, rootPath);
|
|
11699
|
+
result = compareBaseline(result, createBaseline(result, rootPath), rootPath);
|
|
11700
|
+
} else if (baseline) result = compareBaseline(result, baseline, rootPath, opts.baselineStrict);
|
|
11545
11701
|
const output = formatReport(result, checkOptions.format, process.cwd());
|
|
11546
11702
|
if (output) writeOutput(output);
|
|
11547
11703
|
if (!result.passed && checkOptions.failOnError) setExitCode(1);
|
|
@@ -11574,7 +11730,7 @@ function createProgram(options) {
|
|
|
11574
11730
|
"info",
|
|
11575
11731
|
"debug",
|
|
11576
11732
|
"silent"
|
|
11577
|
-
]).default(DEFAULT_LOG_LEVEL)).option("--no-progress", "Disable the interactive download, extraction and realm derivation progress display").hook("preAction", (thisCommand, actionCommand) => {
|
|
11733
|
+
]).default(DEFAULT_LOG_LEVEL)).option("--offline", "Use local dependencies only; never access the network").option("--no-progress", "Disable the interactive download, extraction and realm derivation progress display").hook("preAction", (thisCommand, actionCommand) => {
|
|
11578
11734
|
const target = actionCommand || thisCommand;
|
|
11579
11735
|
const opts = target.optsWithGlobals ? target.optsWithGlobals() : target.opts();
|
|
11580
11736
|
if (opts.logLevel && isValidLogLevel(opts.logLevel)) logger.setLevel(opts.logLevel);
|
|
@@ -11592,7 +11748,7 @@ function createProgram(options) {
|
|
|
11592
11748
|
"pretty",
|
|
11593
11749
|
"json",
|
|
11594
11750
|
"github"
|
|
11595
|
-
])).option("-i, --ignore <pattern>", "Files or directories to ignore (supports glob patterns, repeatable)", collectIgnorePatterns).option("-d, --dep <path>", "Path to package dependency or Lua definition file (repeatable)", collectDeps).option("--luals-version <ver>", `Version of LuaLS to use (default: ${DEFAULT_LUALS_VERSION})`, DEFAULT_LUALS_VERSION).option("--no-fail", "Do not exit with code 1 if diagnostics are found").addOption(new Option("-l, --log-level <level>", "Logging level: error, warn, info, debug, silent").choices([
|
|
11751
|
+
])).option("-i, --ignore <pattern>", "Files or directories to ignore (supports glob patterns, repeatable)", collectIgnorePatterns).option("-d, --dep <path>", "Path to package dependency or Lua definition file (repeatable)", collectDeps).option("--luals-version <ver>", `Version of LuaLS to use (default: ${DEFAULT_LUALS_VERSION})`, DEFAULT_LUALS_VERSION).option("--baseline <path>", "Report and fail only on diagnostics absent from a saved baseline").option("--write-baseline <path>", "Record current diagnostics as a baseline and exit successfully").option("--baseline-strict", "Also fail on stale baseline entries (requires --baseline)").option("--no-fail", "Do not exit with code 1 if diagnostics are found").addOption(new Option("-l, --log-level <level>", "Logging level: error, warn, info, debug, silent").choices([
|
|
11596
11752
|
"error",
|
|
11597
11753
|
"warn",
|
|
11598
11754
|
"info",
|
|
@@ -11603,38 +11759,48 @@ function createProgram(options) {
|
|
|
11603
11759
|
"client",
|
|
11604
11760
|
"server",
|
|
11605
11761
|
"shared"
|
|
11606
|
-
]).default("all")).action(async (targetPaths = ["."], opts) => {
|
|
11762
|
+
]).default("all")).action(async (targetPaths = ["."], opts, cmd) => {
|
|
11763
|
+
opts.offline = cmd.optsWithGlobals().offline;
|
|
11607
11764
|
await executeCheckCommand(targetPaths, opts, setExitCode);
|
|
11608
11765
|
});
|
|
11609
|
-
program.command("init [path]").description("Scaffold a .luarc.json configuration in the workspace").option("-f, --force", "Overwrite existing .luarc.json configuration").option("--vendor", "Vendor annotations.lua into .nanos-lint/ inside workspace for portable standalone editor setup").option("--annotations <path>", "Path to custom annotations.lua file (requires --vendor)").action(async (targetPath = ".", opts) => {
|
|
11766
|
+
program.command("init [path]").description("Scaffold a .luarc.json configuration in the workspace").option("-t, --template <path>", "Custom JSONC .luarc.json scaffold template").option("-f, --force", "Overwrite existing .luarc.json configuration").option("--vendor", "Vendor annotations.lua into .nanos-lint/ inside workspace for portable standalone editor setup").option("--annotations <path>", "Path to custom annotations.lua file (requires --vendor)").action(async (targetPath = ".", opts, cmd) => {
|
|
11767
|
+
opts.offline = cmd.optsWithGlobals().offline;
|
|
11610
11768
|
const shouldVendor = Boolean(opts.vendor);
|
|
11611
|
-
const annotationsPath = shouldVendor ? await resolveAnnotations({
|
|
11769
|
+
const annotationsPath = shouldVendor ? await resolveAnnotations({
|
|
11770
|
+
customPath: opts.annotations,
|
|
11771
|
+
offline: opts.offline
|
|
11772
|
+
}) : opts.annotations;
|
|
11612
11773
|
writeOutput(`[init] Initialized nanos world LuaLS configuration: ${initWorkspace(path.resolve(targetPath), {
|
|
11613
11774
|
force: opts.force,
|
|
11614
11775
|
annotationsPath,
|
|
11615
|
-
vendor: shouldVendor
|
|
11776
|
+
vendor: shouldVendor,
|
|
11777
|
+
templatePath: opts.template
|
|
11616
11778
|
})}`);
|
|
11617
11779
|
setExitCode(0);
|
|
11618
11780
|
});
|
|
11619
|
-
program.command("copy-annotations [destination]").alias("export-annotations").description("Copy cached nanos world annotations.lua definitions into a target file or directory (targets not ending in .lua are treated as directories)").option("-f, --force", "Overwrite existing annotations file").option("--annotations <path>", "Path to custom annotations.lua source file").action(async (destination, opts) => {
|
|
11781
|
+
program.command("copy-annotations [destination]").alias("export-annotations").description("Copy cached nanos world annotations.lua definitions into a target file or directory (targets not ending in .lua are treated as directories)").option("-f, --force", "Overwrite existing annotations file").option("--annotations <path>", "Path to custom annotations.lua source file").action(async (destination, opts, cmd) => {
|
|
11620
11782
|
writeOutput(`[copy-annotations] Copied nanos world annotations to: ${await copyAnnotations(destination, {
|
|
11621
11783
|
force: opts.force,
|
|
11622
|
-
annotationsPath: opts.annotations
|
|
11784
|
+
annotationsPath: opts.annotations,
|
|
11785
|
+
offline: cmd.optsWithGlobals().offline
|
|
11623
11786
|
})}`);
|
|
11624
11787
|
setExitCode(0);
|
|
11625
11788
|
});
|
|
11626
|
-
program.command("warmup").alias("download").description("Pre-fetch and cache both LuaLS binary and annotations for offline execution").option("--luals-version <ver>", `Version of LuaLS to use (default: ${DEFAULT_LUALS_VERSION})`).option("--annotations <path>", "Path to custom annotations.lua file").action(async (opts) => {
|
|
11627
|
-
writeOutput(`[warmup] LuaLS binary ready: ${await resolveLuaLSBinary(opts?.lualsVersion || "latest")}`);
|
|
11628
|
-
const annotationsPath = await resolveAnnotations({
|
|
11789
|
+
program.command("warmup").alias("download").description("Pre-fetch and cache both LuaLS binary and annotations for offline execution").option("--luals-version <ver>", `Version of LuaLS to use (default: ${DEFAULT_LUALS_VERSION})`).option("--annotations <path>", "Path to custom annotations.lua file").action(async (opts, cmd) => {
|
|
11790
|
+
writeOutput(`[warmup] LuaLS binary ready: ${await resolveLuaLSBinary(opts?.lualsVersion || "latest", { offline: cmd.optsWithGlobals().offline })}`);
|
|
11791
|
+
const annotationsPath = await resolveAnnotations({
|
|
11792
|
+
customPath: opts?.annotations,
|
|
11793
|
+
offline: cmd.optsWithGlobals().offline
|
|
11794
|
+
});
|
|
11629
11795
|
const meta = readAnnotationsMetadata();
|
|
11630
11796
|
writeOutput(`[warmup] nanos world annotations ready: ${annotationsPath}${meta?.commitId && meta.commitId !== "unknown" ? ` (commit ${meta.commitId.slice(0, 7)})` : ""}`);
|
|
11631
11797
|
writeOutput("[warmup] Cache pre-warmed successfully. Ready for offline execution.");
|
|
11632
11798
|
setExitCode(0);
|
|
11633
11799
|
});
|
|
11634
|
-
program.command("download-luals [version]").description("Download and cache the LuaLS binary").option("--luals-version <ver>", `Version of LuaLS to use (default: ${DEFAULT_LUALS_VERSION})`).action(async (version, opts) => {
|
|
11800
|
+
program.command("download-luals [version]").description("Download and cache the LuaLS binary").option("--luals-version <ver>", `Version of LuaLS to use (default: ${DEFAULT_LUALS_VERSION})`).action(async (version, opts, cmd) => {
|
|
11635
11801
|
const ver = version || opts?.lualsVersion || "latest";
|
|
11636
11802
|
writeOutput(`[luals] Downloading LuaLS ${ver}...`);
|
|
11637
|
-
writeOutput(`[luals] Ready at: ${await resolveLuaLSBinary(ver)}`);
|
|
11803
|
+
writeOutput(`[luals] Ready at: ${await resolveLuaLSBinary(ver, { offline: cmd.optsWithGlobals().offline })}`);
|
|
11638
11804
|
setExitCode(0);
|
|
11639
11805
|
});
|
|
11640
11806
|
const handleCleanCache = () => {
|
|
@@ -11766,6 +11932,6 @@ if (isDirectExecution()) runCLI().then((code) => {
|
|
|
11766
11932
|
process.exit(1);
|
|
11767
11933
|
});
|
|
11768
11934
|
//#endregion
|
|
11769
|
-
export {
|
|
11935
|
+
export { findProjectRoot as $, isProgressInteractive as $t, isAnnotationsValid as A, LOG_LEVELS as An, isGzipArchive as At, shouldEnableColor as B, resolveLuaLSVersion as Bt, MAX_COMMIT_JSON_SIZE_BYTES as C, NanosLintError as Cn, MIN_DOWNLOADED_BINARY_SIZE_BYTES as Ct, getAnnotationsMetadataFilePath as D, systemPaths as Dn, inspectZipMembers as Dt, getAnnotationsCacheDir as E, getDirectorySize as En, getTarBinary as Et, formatProblemSummary as F, parseLogLevel as Fn, getPlatformInfo as Ft, resolvePackageDependencies as G, splitAnnotationsByRealm as Gt, planRealmCheck as H, ALLOWED_DOWNLOAD_DOMAINS as Ht, formatReport as I, DEFAULT_LUALS_VERSION as It, countCheckedFiles as J, SPINNER_FRAMES as Jt, resolveLuaLSBinary as K, PROGRESS_MILESTONES as Kt, formatSeverityBadge as L, FALLBACK_LUALS_VERSION as Lt, updateLastCheckedDate as M, Logger as Mn, parseTarTvSize as Mt, formatGitHubAnnotations as N, isValidLogLevel as Nn, rethrowLuaLSPermissionError as Nt, getCachedAnnotationsFilePath as O, fileUriToPath as On, isBinaryRunnable as Ot, formatPretty as P, logger as Pn, validateArchiveMembers as Pt, findCommonAncestorDirectory as Q, getProgressMode as Qt, getColors as R, fetchLatestLuaLSVersionFromGitHub as Rt, MAX_ANNOTATIONS_SIZE_BYTES as S, LuaLSError as Sn, MAX_DECOMPRESSED_SIZE_BYTES as St, MIN_ANNOTATIONS_SIZE_BYTES as T, formatBytes as Tn, escapePowerShellSingleQuote as Tt, runRealmAwareCheck as U, isAllowedDownloadUrl as Ut, collectRealmFiles as V, sanitizeLuaLSVersion as Vt, collectDeps as W, deriveRealmAnnotationFiles as Wt, computeUnrequestedExclusions as X, createSpinner as Xt, listCheckedFiles as Y, createProgressBar as Yt, filterReportByTargetPaths as Z, formatTransferSummary as Zt, downloadAndCacheAnnotations as _, stripTrailingSlashes as _n, listCachedLuaLSVersionDirs as _t, compareBaseline as a, getDefaultAnnotationsPath as an, MAX_ARCHIVE_SIZE_BYTES as at, getRawAnnotationsUrl as b, CacheError as bn, writeLuaLSMetadata as bt, writeBaseline as c, getPackageRoot as cn, limitDownloadStream as ct, copyAnnotations as d, loadUserConfig as dn, cleanupOldCachedLuaLSVersions as dt, restoreTerminal as en, getCanonicalPath as et, resolveAnnotations as f, mergeConfigs as fn, findExistingLuaLSDir as ft, RAW_ANNOTATIONS_URL as g, stripJsonComments as gn, getLuaLSMetadataPath as gt, GITHUB_COMMITS_API as h, resolveWorkspaceConfig as hn, getIsoWeek as ht, runCLI as i, buildWorkspaceConfig as in, DOWNLOAD_TIMEOUT_MS as it, readAnnotationsMetadata as j, LOG_LEVEL_PRIORITY as jn, isZipArchive as jt, getTodayDateString as k, DEFAULT_LOG_LEVEL as kn, isBinaryValid as kt, formatCacheStatusPretty as l, initWorkspace as ln, trackDownloadProgress as lt, DOCGEN_REPO as m, resolveRealmMappings as mn, getCacheDir as mt, createProgram as n, DEFAULT_REALM_MAPPINGS as nn, matchesTargetPaths as nt, createBaseline as o, getDefaultTemplatePath as on, computeFileSha256 as ot, DOCGEN_BRANCH as p, parseJsonc as pn, getBaseLuaLSCacheDir as pt, runLuaLSCheck as q, PROGRESS_THROTTLE_MS as qt, isDirectExecution as r, VALID_LUALS_DIAGNOSTIC_CODES as rn, resolveCheckTargets as rt, readBaseline as s, getDefinitionsDir as sn, downloadAndExtractLuaLS as st, collectIgnorePatterns as t, setProgressMode as tn, isFilesystemRoot as tt, getCacheStatus as u, loadConfigFile as un, LUALS_METADATA_FILENAME as ut, fetchLatestCommitId as v, writeTempConfig as vn, listCachedLuaLSVersions as vt, METADATA_FILENAME as w, cleanCache as wn, assertValidLuaLSBinary as wt, ANNOTATIONS_FILENAME as x, ConfigError as xn, MAX_ARCHIVE_MEMBER_COUNT as xt, fetchRawAnnotationsContent as y, AnnotationsError as yn, readLuaLSMetadata as yt, pluralize as z, resolveLatestLuaLSVersion as zt };
|
|
11770
11936
|
|
|
11771
|
-
//# sourceMappingURL=cli-
|
|
11937
|
+
//# sourceMappingURL=cli-DN7ZhC9e.js.map
|