nanos-lint 3.0.1 → 3.1.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.
@@ -1186,10 +1186,12 @@ function mergeConfigs(base, override = {}, definitionsPath = getDefaultAnnotatio
1186
1186
  const normalizedDefPath = resolvedPath.split(path.sep).join("/");
1187
1187
  const baseLibraries = base.workspace?.library ?? [];
1188
1188
  const overrideLibraries = override.workspace?.library ?? [];
1189
+ const depLibraries = (options?.dependencyLibraries ?? []).map((p) => p.replace(/\\/g, "/"));
1189
1190
  const librarySet = /* @__PURE__ */ new Set([
1190
1191
  normalizedDefPath,
1191
1192
  ...baseLibraries,
1192
- ...overrideLibraries
1193
+ ...overrideLibraries,
1194
+ ...depLibraries
1193
1195
  ]);
1194
1196
  const baseGlobals = base.diagnostics?.globals ?? [];
1195
1197
  const overrideGlobals = override.diagnostics?.globals ?? [];
@@ -1328,7 +1330,10 @@ function buildWorkspaceConfig(workspacePath, customConfigPath, options) {
1328
1330
  }
1329
1331
  cliIgnore = expanded;
1330
1332
  }
1331
- const merged = mergeConfigs(defaultTemplate, userConfig, activeAnnotationsPath, { cliIgnore });
1333
+ const merged = mergeConfigs(defaultTemplate, userConfig, activeAnnotationsPath, {
1334
+ cliIgnore,
1335
+ dependencyLibraries: options?.dependencyLibraries
1336
+ });
1332
1337
  if (!hasCliIgnore) {
1333
1338
  const resolvedTarget = path.resolve(workspacePath);
1334
1339
  if (fs.existsSync(path.join(resolvedTarget, "main.lua")) && (fs.existsSync(path.join(resolvedTarget, "bin", "lua-language-server.exe")) || fs.existsSync(path.join(resolvedTarget, "bin", "lua-language-server")))) {
@@ -1343,6 +1348,11 @@ function buildWorkspaceConfig(workspacePath, customConfigPath, options) {
1343
1348
  ])];
1344
1349
  }
1345
1350
  }
1351
+ if (options?.unrequestedExclusions && options.unrequestedExclusions.length > 0) {
1352
+ merged.files = merged.files ?? {};
1353
+ const existingExclude = merged.files.exclude ?? [];
1354
+ merged.files.exclude = [.../* @__PURE__ */ new Set([...existingExclude, ...options.unrequestedExclusions])];
1355
+ }
1346
1356
  return merged;
1347
1357
  }
1348
1358
  /**
@@ -6340,6 +6350,236 @@ async function downloadAndPromoteLuaLS(resolvedVersion, info, destDir, binaryPat
6340
6350
  }
6341
6351
  }
6342
6352
  //#endregion
6353
+ //#region src/target-resolver.ts
6354
+ /** Resolves the canonical filesystem path, falling back to original path on failure. */
6355
+ function getCanonicalPath(p) {
6356
+ try {
6357
+ return fs.realpathSync.native ? fs.realpathSync.native(p) : fs.realpathSync(p);
6358
+ } catch {
6359
+ return p;
6360
+ }
6361
+ }
6362
+ /** Determines whether a path points to the root of a filesystem volume. */
6363
+ function isFilesystemRoot(dir) {
6364
+ const stripped = dir.trim();
6365
+ if (stripped === "/" || stripped === "\\" || stripped === "") return true;
6366
+ if (/^[a-zA-Z]:[\\/]?$/.test(stripped)) return true;
6367
+ const norm = path.resolve(stripped);
6368
+ if (norm === "/" || norm === "\\") return true;
6369
+ return /^[a-zA-Z]:[\\/]?$/.test(norm);
6370
+ }
6371
+ /**
6372
+ * Computes the lowest common ancestor directory for a set of paths.
6373
+ * All paths must reside on the same filesystem root or volume.
6374
+ */
6375
+ function findCommonAncestorDirectory(paths) {
6376
+ if (paths.length === 0) return path.resolve(".");
6377
+ const resolved = paths.map((p) => {
6378
+ const abs = path.resolve(p);
6379
+ try {
6380
+ if (fs.existsSync(abs)) return fs.statSync(abs).isDirectory() ? abs : path.dirname(abs);
6381
+ } catch (err) {}
6382
+ return path.dirname(abs);
6383
+ });
6384
+ if (resolved.length === 1 && resolved[0]) return resolved[0];
6385
+ const isWin = process.platform === "win32";
6386
+ const splitPaths = resolved.map((p) => path.resolve(p).split(path.sep));
6387
+ const first = splitPaths[0];
6388
+ if (!first || first.length === 0) return path.resolve(".");
6389
+ const firstRoot = first[0];
6390
+ if (!splitPaths.every((p) => {
6391
+ const rootSeg = p[0];
6392
+ if (rootSeg === void 0) return false;
6393
+ return isWin ? rootSeg.toLowerCase() === firstRoot?.toLowerCase() : rootSeg === firstRoot;
6394
+ }) || firstRoot === void 0) throw new ConfigError(`Cannot check paths across different root drives or volumes: ${paths.join(", ")}`, "ERR_MULTIPLE_ROOTS", "Ensure all checked paths are within the same workspace or project root.");
6395
+ const minLen = Math.min(...splitPaths.map((p) => p.length));
6396
+ let commonLen = 0;
6397
+ for (let i = 0; i < minLen; i++) {
6398
+ const segment = first[i];
6399
+ if (segment === void 0) break;
6400
+ if (!splitPaths.every((p) => {
6401
+ const seg = p[i];
6402
+ if (seg === void 0) return false;
6403
+ return isWin ? seg.toLowerCase() === segment.toLowerCase() : seg === segment;
6404
+ })) break;
6405
+ commonLen++;
6406
+ }
6407
+ if (commonLen === 0) throw new ConfigError(`Cannot check paths across different root drives or volumes: ${paths.join(", ")}`, "ERR_MULTIPLE_ROOTS", "Ensure all checked paths are within the same workspace or project root.");
6408
+ let commonPath = first.slice(0, commonLen).join(path.sep);
6409
+ if (!commonPath) commonPath = path.sep;
6410
+ if (isWin && /^[a-zA-Z]:$/.test(commonPath)) commonPath = `${commonPath}\\`;
6411
+ return path.resolve(commonPath);
6412
+ }
6413
+ /**
6414
+ * Searches upward from a starting directory to locate an enclosing project root
6415
+ * containing `.luarc.json`. Returns the start directory if not found.
6416
+ */
6417
+ function findProjectRoot(startDir) {
6418
+ let curr = path.resolve(startDir);
6419
+ while (true) {
6420
+ if (fs.existsSync(path.join(curr, ".luarc.json"))) return curr;
6421
+ if (fs.existsSync(path.join(curr, ".git"))) break;
6422
+ const parent = path.dirname(curr);
6423
+ if (parent === curr) break;
6424
+ curr = parent;
6425
+ }
6426
+ return startDir;
6427
+ }
6428
+ /**
6429
+ * Characters the LuaLS glob matcher treats as syntax.
6430
+ *
6431
+ * LuaLS compiles `files.exclude` with `glob.gitignore` (see its
6432
+ * `script/glob/glob.lua`), whose grammar only understands backslash escapes:
6433
+ * bracket expressions such as `[[]` are parsed as character ranges and match
6434
+ * nothing useful. Escaping is therefore done with `\`.
6435
+ */
6436
+ const GLOB_METACHARACTERS = /* @__PURE__ */ new Set([
6437
+ "*",
6438
+ "?",
6439
+ "[",
6440
+ "]",
6441
+ "{",
6442
+ "}",
6443
+ ",",
6444
+ "\\"
6445
+ ]);
6446
+ /**
6447
+ * Escapes the glob metacharacters of a single path segment so it matches literally.
6448
+ *
6449
+ * Note: `normalizePattern()` in `src/luals/files.ts` rewrites backslashes to path
6450
+ * separators when counting checked files, so these escapes only reach LuaLS. That is
6451
+ * harmless: the counted file set is filtered by the requested target paths anyway.
6452
+ */
6453
+ function escapeGlobSegment(segment) {
6454
+ let escaped = "";
6455
+ for (const char of segment) escaped += GLOB_METACHARACTERS.has(char) ? `\\${char}` : char;
6456
+ return escaped;
6457
+ }
6458
+ /** Escapes glob metacharacters in every segment of a slash-separated relative path. */
6459
+ function escapeGlobPath(relativePath) {
6460
+ return relativePath.split("/").map(escapeGlobSegment).join("/");
6461
+ }
6462
+ /**
6463
+ * Computes glob exclusion patterns for directories and files under workspace root
6464
+ * that are completely outside the requested target paths.
6465
+ */
6466
+ function computeUnrequestedExclusions(root, targetPaths) {
6467
+ const resolvedRoot = path.resolve(root);
6468
+ if (targetPaths.length === 0 || targetPaths.some((t) => t === "." || t === "" || path.resolve(resolvedRoot, t) === resolvedRoot)) return [];
6469
+ const isWin = process.platform === "win32";
6470
+ const canonicalRoot = getCanonicalPath(resolvedRoot);
6471
+ const relTargets = targetPaths.map((t) => {
6472
+ const canonical = getCanonicalPath(path.isAbsolute(t) ? t : path.resolve(canonicalRoot, t));
6473
+ const rel = path.relative(canonicalRoot, canonical).replace(/\\/g, "/");
6474
+ return isWin ? rel.toLowerCase() : rel;
6475
+ }).filter((rel) => !rel.startsWith("../") && rel !== "..");
6476
+ if (relTargets.length === 0 || relTargets.includes("") || relTargets.includes(".")) return [];
6477
+ const exclusions = [];
6478
+ /** Recursively scans directory entries to identify unrequested paths. */
6479
+ function scanDir(dir, relPrefix) {
6480
+ let entries;
6481
+ try {
6482
+ entries = fs.readdirSync(dir, { withFileTypes: true });
6483
+ } catch {
6484
+ return;
6485
+ }
6486
+ for (const entry of entries) {
6487
+ const entryRel = relPrefix ? `${relPrefix}/${entry.name}` : entry.name;
6488
+ const normEntry = isWin ? entryRel.toLowerCase() : entryRel;
6489
+ let isExactTarget = false;
6490
+ let isAncestorOfTarget = false;
6491
+ let isDescendantOfTarget = false;
6492
+ for (const target of relTargets) {
6493
+ if (normEntry === target) {
6494
+ isExactTarget = true;
6495
+ break;
6496
+ }
6497
+ if (target.startsWith(`${normEntry}/`)) {
6498
+ isAncestorOfTarget = true;
6499
+ break;
6500
+ }
6501
+ if (normEntry.startsWith(`${target}/`)) {
6502
+ isDescendantOfTarget = true;
6503
+ break;
6504
+ }
6505
+ }
6506
+ if (isExactTarget || isDescendantOfTarget) continue;
6507
+ if (isAncestorOfTarget) {
6508
+ if (entry.isDirectory()) scanDir(path.join(dir, entry.name), entryRel);
6509
+ continue;
6510
+ }
6511
+ if (entry.isDirectory()) exclusions.push(`${escapeGlobPath(entryRel)}/**`);
6512
+ else if (entry.isFile() && entry.name.toLowerCase().endsWith(".lua")) exclusions.push(escapeGlobPath(entryRel));
6513
+ }
6514
+ }
6515
+ scanDir(canonicalRoot, "");
6516
+ return exclusions;
6517
+ }
6518
+ /** Determines whether a workspace-relative file path matches any of the target paths. */
6519
+ function matchesTargetPaths(relativePath, root, targetPaths) {
6520
+ if (targetPaths.length === 0 || targetPaths.length === 1 && (targetPaths[0] === "." || targetPaths[0] === "")) return true;
6521
+ const isWin = process.platform === "win32";
6522
+ const canonicalRoot = getCanonicalPath(root);
6523
+ const normRel = isWin ? relativePath.replace(/\\/g, "/").toLowerCase() : relativePath.replace(/\\/g, "/");
6524
+ for (const rawTarget of targetPaths) {
6525
+ const fromCwd = path.resolve(rawTarget);
6526
+ const canonicalTarget = getCanonicalPath(fs.existsSync(fromCwd) ? fromCwd : path.isAbsolute(rawTarget) ? rawTarget : path.resolve(canonicalRoot, rawTarget));
6527
+ let relTarget = path.relative(canonicalRoot, canonicalTarget).replace(/\\/g, "/");
6528
+ relTarget = stripTrailingSlashes(relTarget).replace(/^\.\//, "");
6529
+ const normTarget = isWin ? relTarget.toLowerCase() : relTarget;
6530
+ if (normTarget === "" || normTarget === ".") return true;
6531
+ if (normRel === normTarget || normRel.startsWith(`${normTarget}/`)) return true;
6532
+ }
6533
+ return false;
6534
+ }
6535
+ /** Keeps only diagnostics for files that match the requested target paths. */
6536
+ function filterReportByTargetPaths(report, root, targetPaths) {
6537
+ if (targetPaths.length === 0 || targetPaths.length === 1 && (targetPaths[0] === "." || targetPaths[0] === "")) return report;
6538
+ const filtered = {};
6539
+ const canonicalRoot = getCanonicalPath(root);
6540
+ for (const [uri, diags] of Object.entries(report)) {
6541
+ const filePath = fileUriToPath(uri);
6542
+ const canonicalFile = getCanonicalPath(path.resolve(filePath));
6543
+ if (matchesTargetPaths(path.relative(canonicalRoot, canonicalFile).replace(/\\/g, "/"), canonicalRoot, targetPaths)) filtered[uri] = diags;
6544
+ }
6545
+ return filtered;
6546
+ }
6547
+ /** Validates and resolves CLI target paths into a common root directory and target list. */
6548
+ function resolveCheckTargets(rawPaths) {
6549
+ const paths = rawPaths && rawPaths.length > 0 ? rawPaths : ["."];
6550
+ const canonicalTargets = paths.map((targetPath) => {
6551
+ const resolved = path.resolve(targetPath);
6552
+ if (!fs.existsSync(resolved)) throw new LuaLSError(`Target path does not exist: ${targetPath}`, "ERR_TARGET_NOT_FOUND", "Verify that the target path exists and is accessible.");
6553
+ return getCanonicalPath(resolved);
6554
+ });
6555
+ const first = paths[0];
6556
+ if (paths.length === 1 && first) {
6557
+ const canonicalFirst = canonicalTargets[0];
6558
+ const startDir = fs.statSync(canonicalFirst).isFile() ? path.dirname(canonicalFirst) : canonicalFirst;
6559
+ const projRoot = findProjectRoot(startDir);
6560
+ if (projRoot !== startDir) {
6561
+ if (isFilesystemRoot(projRoot)) throw new ConfigError(`Cannot check targets across the root filesystem (${projRoot}): checked paths must share a common project directory.`, "ERR_ROOT_ANCESTOR", "Ensure all checked paths reside within a common project directory.");
6562
+ logger.debug(`[targets] Using discovered project root "${projRoot}" for "${first}".`);
6563
+ return {
6564
+ rootPath: projRoot,
6565
+ targetPaths: canonicalTargets
6566
+ };
6567
+ }
6568
+ return {
6569
+ rootPath: first,
6570
+ targetPaths: canonicalTargets
6571
+ };
6572
+ }
6573
+ const ancestor = findCommonAncestorDirectory(canonicalTargets);
6574
+ if (isFilesystemRoot(ancestor)) throw new ConfigError(`Cannot check targets across the root filesystem (${ancestor}): checked paths must share a common project directory.`, "ERR_ROOT_ANCESTOR", "Ensure all checked paths reside within a common project directory.");
6575
+ const rootPath = findProjectRoot(ancestor);
6576
+ if (rootPath !== ancestor) logger.debug(`[targets] Using discovered project root "${rootPath}" for "${ancestor}".`);
6577
+ return {
6578
+ rootPath,
6579
+ targetPaths: canonicalTargets
6580
+ };
6581
+ }
6582
+ //#endregion
6343
6583
  //#region src/luals/files.ts
6344
6584
  /** Directories skipped unless the workspace config overrides `workspace.ignoreDir`. */
6345
6585
  const DEFAULT_IGNORE_DIRS = [
@@ -6463,7 +6703,7 @@ function resolveTargetPath(targetPath) {
6463
6703
  * honoring `workspace.ignoreDir` and `files.exclude` (#27). Absolute paths are returned
6464
6704
  * for single-file targets, and an empty list is returned when the walk fails.
6465
6705
  */
6466
- function listCheckedFiles(targetPath, configPath) {
6706
+ function listCheckedFiles(targetPath, configPath, targetPaths) {
6467
6707
  const absPath = resolveTargetPath(targetPath);
6468
6708
  if (!absPath) return [];
6469
6709
  if (fs.statSync(absPath).isFile()) return absPath.toLowerCase().endsWith(".lua") ? [absPath] : [];
@@ -6478,7 +6718,7 @@ function listCheckedFiles(targetPath, configPath) {
6478
6718
  }
6479
6719
  const ignore = [...toIgnorePatterns(ignoreDirs), ...toIgnorePatterns(excludePatterns)];
6480
6720
  try {
6481
- return ts(LUA_FILE_PATTERN, {
6721
+ const files = ts(LUA_FILE_PATTERN, {
6482
6722
  cwd: absPath,
6483
6723
  ignore,
6484
6724
  dot: true,
@@ -6486,14 +6726,16 @@ function listCheckedFiles(targetPath, configPath) {
6486
6726
  follow: false,
6487
6727
  withFileTypes: true
6488
6728
  }).filter((entry) => entry.isFile()).map((entry) => entry.relativePosix());
6729
+ if (targetPaths && targetPaths.length > 0) return files.filter((f) => matchesTargetPaths(f, absPath, targetPaths));
6730
+ return files;
6489
6731
  } catch (err) {
6490
6732
  logger.warn(`[luals] Failed to walk ${absPath} while listing checked files: ${err instanceof Error ? err.message : String(err)}`);
6491
6733
  return [];
6492
6734
  }
6493
6735
  }
6494
6736
  /** Counts candidate Lua files within targetPath, taking workspace ignoreDir and files.exclude into account (#27). */
6495
- function countCheckedFiles(targetPath, configPath) {
6496
- return listCheckedFiles(targetPath, configPath).length;
6737
+ function countCheckedFiles(targetPath, configPath, targetPaths) {
6738
+ return listCheckedFiles(targetPath, configPath, targetPaths).length;
6497
6739
  }
6498
6740
  //#endregion
6499
6741
  //#region src/luals/runner.ts
@@ -6705,7 +6947,7 @@ async function runLuaLSCheck(targetPath, configPath, options) {
6705
6947
  const normTarget = normalizeComparable(targetFileOnly);
6706
6948
  for (const [rawUri, diags] of Object.entries(diagnostics)) if (normalizeComparable(fileUriToPath(rawUri)) === normTarget) filtered[rawUri] = diags;
6707
6949
  diagnostics = filtered;
6708
- }
6950
+ } else if (options.paths && options.paths.length > 0) diagnostics = filterReportByTargetPaths(diagnostics, checkDir, options.paths);
6709
6951
  let totalProblems = 0;
6710
6952
  let totalErrors = 0;
6711
6953
  let totalWarnings = 0;
@@ -6717,7 +6959,7 @@ async function runLuaLSCheck(targetPath, configPath, options) {
6717
6959
  else if (d.severity === 2) totalWarnings += 1;
6718
6960
  }
6719
6961
  const passed = totalProblems === 0;
6720
- const filesChecked = countCheckedFiles(targetPath, configPath);
6962
+ const filesChecked = countCheckedFiles(targetPath, configPath, options.paths);
6721
6963
  return {
6722
6964
  passed,
6723
6965
  totalProblems,
@@ -6729,6 +6971,179 @@ async function runLuaLSCheck(targetPath, configPath, options) {
6729
6971
  };
6730
6972
  }
6731
6973
  //#endregion
6974
+ //#region src/deps.ts
6975
+ /** Accumulates repeatable --dep arguments. */
6976
+ function collectDeps(val, prev) {
6977
+ const trimmed = val.trim();
6978
+ if (!trimmed) return prev ?? [];
6979
+ return (prev ?? []).concat(trimmed);
6980
+ }
6981
+ /** Normalizes a filesystem path to forward slashes for LuaLS compatibility. */
6982
+ function normalizeSlash(p) {
6983
+ return p.replace(/\\/g, "/");
6984
+ }
6985
+ /**
6986
+ * Resolves package dependencies declared in .luarc.json (nanos.deps) or via CLI (--dep),
6987
+ * resolving transitive dependencies with cycle detection and partitioning them by realm.
6988
+ */
6989
+ function resolvePackageDependencies(root, userConfig, cliDeps) {
6990
+ const visited = /* @__PURE__ */ new Set();
6991
+ const queue = [];
6992
+ if (cliDeps && cliDeps.length > 0) {
6993
+ for (const dep of cliDeps) if (typeof dep === "string" && dep.trim()) queue.push({
6994
+ rawPath: dep.trim(),
6995
+ fromDir: process.cwd()
6996
+ });
6997
+ }
6998
+ const rawConfigDeps = userConfig.nanos?.deps;
6999
+ if (rawConfigDeps !== void 0) {
7000
+ if (Array.isArray(rawConfigDeps)) for (const dep of rawConfigDeps) if (typeof dep === "string" && dep.trim()) queue.push({
7001
+ rawPath: dep.trim(),
7002
+ fromDir: root
7003
+ });
7004
+ else logger.warn(`[deps] Skipping invalid nanos.deps entry: expected a string path.`);
7005
+ else logger.warn(`[deps] Ignoring nanos.deps: expected an array of path strings.`);
7006
+ }
7007
+ const resolvedFiles = [];
7008
+ const resolvedDirs = [];
7009
+ const depConfigMap = /* @__PURE__ */ new Map();
7010
+ const isWin = process.platform === "win32";
7011
+ while (queue.length > 0) {
7012
+ const item = queue.shift();
7013
+ if (!item) continue;
7014
+ const { rawPath, fromDir } = item;
7015
+ const absPath = path.resolve(fromDir, rawPath);
7016
+ if (!fs.existsSync(absPath)) {
7017
+ logger.warn(`[deps] Dependency path not found: "${rawPath}" (skipping).`);
7018
+ continue;
7019
+ }
7020
+ let canonical;
7021
+ try {
7022
+ canonical = fs.realpathSync.native(absPath);
7023
+ } catch (err) {
7024
+ try {
7025
+ canonical = fs.realpathSync(absPath);
7026
+ } catch (innerErr) {
7027
+ canonical = absPath;
7028
+ }
7029
+ }
7030
+ const cycleKey = isWin ? canonical.toLowerCase() : canonical;
7031
+ if (visited.has(cycleKey)) continue;
7032
+ visited.add(cycleKey);
7033
+ let stat;
7034
+ try {
7035
+ stat = fs.statSync(canonical);
7036
+ } catch (err) {
7037
+ continue;
7038
+ }
7039
+ if (stat.isFile()) {
7040
+ if (canonical.toLowerCase().endsWith(".lua")) resolvedFiles.push(normalizeSlash(canonical));
7041
+ else logger.warn(`[deps] Skipping non-Lua dependency file: "${rawPath}".`);
7042
+ continue;
7043
+ }
7044
+ if (stat.isDirectory()) {
7045
+ resolvedDirs.push(canonical);
7046
+ const candidateLuarc = path.join(canonical, ".luarc.json");
7047
+ if (fs.existsSync(candidateLuarc)) try {
7048
+ const depConfig = loadUserConfig(canonical);
7049
+ depConfigMap.set(canonical, depConfig);
7050
+ const transDeps = depConfig.nanos?.deps;
7051
+ if (transDeps !== void 0) {
7052
+ if (Array.isArray(transDeps)) for (const trans of transDeps) if (typeof trans === "string" && trans.trim()) queue.push({
7053
+ rawPath: trans.trim(),
7054
+ fromDir: canonical
7055
+ });
7056
+ else logger.warn(`[deps] Skipping invalid nanos.deps entry in "${canonical}": expected a string path.`);
7057
+ else logger.warn(`[deps] Ignoring nanos.deps in "${canonical}": expected an array of path strings.`);
7058
+ }
7059
+ } catch (err) {
7060
+ logger.warn(`[deps] Failed to parse transitive dependency configuration at "${candidateLuarc}": ${err instanceof Error ? err.message : String(err)}`);
7061
+ }
7062
+ }
7063
+ }
7064
+ const serverSet = /* @__PURE__ */ new Set();
7065
+ const clientSet = /* @__PURE__ */ new Set();
7066
+ const sharedSet = /* @__PURE__ */ new Set();
7067
+ const allSet = /* @__PURE__ */ new Set();
7068
+ for (const file of resolvedFiles) {
7069
+ serverSet.add(file);
7070
+ clientSet.add(file);
7071
+ sharedSet.add(file);
7072
+ allSet.add(file);
7073
+ }
7074
+ for (const depDir of resolvedDirs) {
7075
+ const normDepDir = normalizeSlash(depDir);
7076
+ allSet.add(normDepDir);
7077
+ let depConfig = depConfigMap.get(depDir);
7078
+ if (!depConfig) try {
7079
+ depConfig = loadUserConfig(depDir);
7080
+ } catch (err) {
7081
+ depConfig = {};
7082
+ }
7083
+ const { enabled, mappings } = resolveRealmMappings(depConfig);
7084
+ if (!enabled) {
7085
+ serverSet.add(normDepDir);
7086
+ clientSet.add(normDepDir);
7087
+ sharedSet.add(normDepDir);
7088
+ continue;
7089
+ }
7090
+ const serverFolder = path.join(depDir, "Server");
7091
+ const clientFolder = path.join(depDir, "Client");
7092
+ const sharedFolder = path.join(depDir, "Shared");
7093
+ const hasServer = fs.existsSync(serverFolder);
7094
+ const hasClient = fs.existsSync(clientFolder);
7095
+ const hasShared = fs.existsSync(sharedFolder);
7096
+ if (hasServer || hasClient || hasShared) {
7097
+ if (hasServer) serverSet.add(normalizeSlash(serverFolder));
7098
+ if (hasClient) clientSet.add(normalizeSlash(clientFolder));
7099
+ if (hasShared) {
7100
+ const normShared = normalizeSlash(sharedFolder);
7101
+ serverSet.add(normShared);
7102
+ clientSet.add(normShared);
7103
+ sharedSet.add(normShared);
7104
+ }
7105
+ try {
7106
+ const entries = fs.readdirSync(depDir, { withFileTypes: true });
7107
+ for (const entry of entries) if (entry.isFile() && entry.name.toLowerCase().endsWith(".lua")) {
7108
+ const rootFile = normalizeSlash(path.join(depDir, entry.name));
7109
+ serverSet.add(rootFile);
7110
+ clientSet.add(rootFile);
7111
+ sharedSet.add(rootFile);
7112
+ }
7113
+ } catch (err) {}
7114
+ continue;
7115
+ }
7116
+ if (depConfig.nanos?.realms) {
7117
+ let matchedAnyCustom = false;
7118
+ for (const { pattern, realm } of mappings) {
7119
+ const baseFolder = pattern.replace(/\/\*\*.*$/, "").replace(/\/\*.*$/, "");
7120
+ const targetPath = path.join(depDir, baseFolder);
7121
+ if (fs.existsSync(targetPath)) {
7122
+ matchedAnyCustom = true;
7123
+ const norm = normalizeSlash(targetPath);
7124
+ if (realm === "server") serverSet.add(norm);
7125
+ else if (realm === "client") clientSet.add(norm);
7126
+ else {
7127
+ serverSet.add(norm);
7128
+ clientSet.add(norm);
7129
+ sharedSet.add(norm);
7130
+ }
7131
+ }
7132
+ }
7133
+ if (matchedAnyCustom) continue;
7134
+ }
7135
+ serverSet.add(normDepDir);
7136
+ clientSet.add(normDepDir);
7137
+ sharedSet.add(normDepDir);
7138
+ }
7139
+ return {
7140
+ server: Array.from(serverSet),
7141
+ client: Array.from(clientSet),
7142
+ shared: Array.from(sharedSet),
7143
+ all: Array.from(allSet)
7144
+ };
7145
+ }
7146
+ //#endregion
6732
7147
  //#region src/realms.ts
6733
7148
  /** Normalizes a workspace-relative path for case-insensitive comparison on Windows. */
6734
7149
  function normalizeRelative(candidate) {
@@ -6786,13 +7201,17 @@ function selectedRealms(selection) {
6786
7201
  return ["shared", selection];
6787
7202
  }
6788
7203
  /** Builds a pass config from the merged base config by swapping library and exclusions. */
6789
- function buildPassConfig(baseConfig, realm, annotationsPath, realmAnnotationPath, excludedPatterns) {
7204
+ function buildPassConfig(baseConfig, realm, annotationsPath, realmAnnotationPath, excludedPatterns, dependencyLibraries = []) {
6790
7205
  const config = JSON.parse(JSON.stringify(baseConfig));
6791
7206
  const normalizedFull = annotationsPath.replace(/\\/g, "/");
6792
7207
  const libraries = (config.workspace?.library ?? []).filter((entry) => entry.replace(/\\/g, "/") !== normalizedFull);
6793
7208
  config.workspace = {
6794
7209
  ...config.workspace ?? {},
6795
- library: [realmAnnotationPath, ...libraries]
7210
+ library: Array.from(/* @__PURE__ */ new Set([
7211
+ realmAnnotationPath,
7212
+ ...libraries,
7213
+ ...dependencyLibraries
7214
+ ]))
6796
7215
  };
6797
7216
  if (realm !== "shared" && excludedPatterns.length > 0) config.files = {
6798
7217
  ...config.files ?? {},
@@ -6814,19 +7233,25 @@ function planRealmCheck(options) {
6814
7233
  logger.debug("[realms] Realm mapping disabled; running a single standard pass.");
6815
7234
  return null;
6816
7235
  }
7236
+ const unrequestedExclusions = options.targetPaths ? computeUnrequestedExclusions(resolvedTarget, options.targetPaths) : [];
6817
7237
  const baseConfig = buildWorkspaceConfig(resolvedTarget, options.customConfigPath, {
6818
7238
  ignore: options.ignore,
6819
- annotationsPath
7239
+ annotationsPath,
7240
+ unrequestedExclusions
6820
7241
  });
6821
7242
  const tempConfigs = [];
6822
7243
  const baseConfigPath = writeTempConfig(baseConfig);
6823
7244
  tempConfigs.push(baseConfigPath);
6824
7245
  try {
6825
7246
  const realmFiles = collectRealmFiles(resolvedTarget, mappings, listCheckedFiles(resolvedTarget, baseConfigPath));
7247
+ const isTargetFile = (file) => {
7248
+ if (!options.targetPaths || options.targetPaths.length === 0) return true;
7249
+ return matchesTargetPaths(file, resolvedTarget, options.targetPaths);
7250
+ };
6826
7251
  const realmReportFiles = {
6827
- client: new Set(realmFiles.client.map(normalizeRelative)),
6828
- server: new Set(realmFiles.server.map(normalizeRelative)),
6829
- shared: new Set([...realmFiles.shared, ...realmFiles.unmatched].map(normalizeRelative))
7252
+ client: new Set(realmFiles.client.filter(isTargetFile).map(normalizeRelative)),
7253
+ server: new Set(realmFiles.server.filter(isTargetFile).map(normalizeRelative)),
7254
+ shared: new Set([...realmFiles.shared, ...realmFiles.unmatched].filter(isTargetFile).map(normalizeRelative))
6830
7255
  };
6831
7256
  const hasRealmFolders = realmFiles.client.length > 0 || realmFiles.server.length > 0 || realmFiles.shared.length > 0;
6832
7257
  if (selection === "all" && !hasRealmFolders) {
@@ -6835,14 +7260,22 @@ function planRealmCheck(options) {
6835
7260
  return null;
6836
7261
  }
6837
7262
  const wanted = selectedRealms(selection).filter((realm) => realmReportFiles[realm].size > 0);
7263
+ if (wanted.length === 0) {
7264
+ if (selection !== "all") logger.warn(`[realms] No target files match the requested realm "${selection}"; falling back to a standard check.`);
7265
+ else logger.debug("[realms] No files to report for selected realm pass; running a single standard pass.");
7266
+ for (const tempConfig of tempConfigs) removeTempConfig(tempConfig);
7267
+ return null;
7268
+ }
6838
7269
  const derived = wanted.some((realm) => realm !== "shared") ? deriveRealmAnnotationFiles(annotationsPath) : {
6839
7270
  client: annotationsPath,
6840
7271
  server: annotationsPath
6841
7272
  };
7273
+ const resolvedDeps = resolvePackageDependencies(resolvedTarget, userConfig, options.cliDeps);
6842
7274
  const passes = [];
6843
7275
  for (const realm of wanted) {
6844
7276
  const excluded = mappings.filter((mapping) => mapping.realm !== realm && mapping.realm !== "shared").map((mapping) => mapping.pattern);
6845
- const configPath = writeTempConfig(buildPassConfig(baseConfig, realm, annotationsPath, realm === "client" ? derived.client : realm === "server" ? derived.server : annotationsPath, excluded));
7277
+ const depLibraries = realm === "server" ? resolvedDeps.server : realm === "client" ? resolvedDeps.client : resolvedDeps.shared;
7278
+ const configPath = writeTempConfig(buildPassConfig(baseConfig, realm, annotationsPath, realm === "client" ? derived.client : realm === "server" ? derived.server : annotationsPath, excluded, depLibraries));
6846
7279
  tempConfigs.push(configPath);
6847
7280
  passes.push({
6848
7281
  realm,
@@ -6873,9 +7306,15 @@ function removeTempConfig(configPath) {
6873
7306
  /** Keeps only the diagnostics of files owned by the pass. */
6874
7307
  function filterReportByFiles(report, root, reportFiles) {
6875
7308
  const filtered = {};
7309
+ const canonicalRoot = getCanonicalPath(root);
6876
7310
  for (const [uri, diagnostics] of Object.entries(report)) {
6877
7311
  const filePath = fileUriToPath(uri);
6878
- const relative = normalizeRelative(path.relative(root, path.resolve(filePath)));
7312
+ const resolvedFile = path.resolve(filePath);
7313
+ let relative = normalizeRelative(path.relative(root, resolvedFile));
7314
+ if (!reportFiles.has(relative)) {
7315
+ const canonicalFile = getCanonicalPath(resolvedFile);
7316
+ relative = normalizeRelative(path.relative(canonicalRoot, canonicalFile));
7317
+ }
6879
7318
  if (reportFiles.has(relative)) filtered[uri] = diagnostics;
6880
7319
  }
6881
7320
  return filtered;
@@ -10451,7 +10890,7 @@ function createProgram(options) {
10451
10890
  writeOut: (str) => console.log(str.trimEnd()),
10452
10891
  writeErr: (str) => logger.error(str.trimEnd())
10453
10892
  });
10454
- program.command("check [path]", { isDefault: true }).description("Check a workspace or Lua file (default command)").addOption(new Option("--checklevel <level>", "Minimum diagnostic level: Error, Warning, Information, Hint").choices([
10893
+ program.command("check [paths...]", { isDefault: true }).description("Check workspace files or directories (default command)").addOption(new Option("--checklevel <level>", "Minimum diagnostic level: Error, Warning, Information, Hint").choices([
10455
10894
  "Error",
10456
10895
  "Warning",
10457
10896
  "Information",
@@ -10460,7 +10899,7 @@ function createProgram(options) {
10460
10899
  "pretty",
10461
10900
  "json",
10462
10901
  "github"
10463
- ])).option("-i, --ignore <pattern>", "Files or directories to ignore (supports glob patterns, repeatable)", collectIgnorePatterns).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([
10902
+ ])).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([
10464
10903
  "error",
10465
10904
  "warn",
10466
10905
  "info",
@@ -10471,44 +10910,54 @@ function createProgram(options) {
10471
10910
  "client",
10472
10911
  "server",
10473
10912
  "shared"
10474
- ]).default("all")).action(async (targetPath = ".", opts) => {
10913
+ ]).default("all")).action(async (targetPaths = ["."], opts) => {
10475
10914
  if (opts.logLevel && isValidLogLevel(opts.logLevel)) logger.setLevel(opts.logLevel);
10915
+ const { rootPath, targetPaths: canonicalTargets } = resolveCheckTargets(targetPaths && targetPaths.length > 0 ? targetPaths : ["."]);
10476
10916
  const format = opts.github ? "github" : opts.format || (process.env.GITHUB_ACTIONS ? "github" : "pretty");
10477
10917
  const checkOptions = {
10478
- path: targetPath,
10918
+ path: rootPath,
10919
+ paths: canonicalTargets,
10479
10920
  configpath: opts.config,
10480
10921
  checklevel: opts.checklevel,
10481
10922
  format,
10482
10923
  lualsVersion: opts.lualsVersion,
10483
10924
  failOnError: opts.fail !== false,
10484
- ignore: opts.ignore
10925
+ ignore: opts.ignore,
10926
+ deps: opts.dep
10485
10927
  };
10486
10928
  if (opts.config) {
10487
10929
  const resolvedConfig = path.resolve(opts.config);
10488
10930
  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.");
10489
10931
  }
10490
10932
  const annotationsPath = await resolveAnnotations({ customPath: opts.annotations });
10933
+ const userConfig = loadUserConfig(rootPath, checkOptions.configpath);
10491
10934
  const realmPlan = planRealmCheck({
10492
- targetPath,
10493
- userConfig: loadUserConfig(targetPath, checkOptions.configpath),
10935
+ targetPath: rootPath,
10936
+ userConfig,
10494
10937
  selection: opts.realm ?? "all",
10495
10938
  annotationsPath,
10496
10939
  customConfigPath: checkOptions.configpath,
10497
- ignore: checkOptions.ignore
10940
+ ignore: checkOptions.ignore,
10941
+ targetPaths: canonicalTargets,
10942
+ cliDeps: checkOptions.deps
10498
10943
  });
10499
10944
  let result;
10500
10945
  if (realmPlan) try {
10501
- result = await runRealmAwareCheck(realmPlan, targetPath, checkOptions);
10946
+ result = await runRealmAwareCheck(realmPlan, rootPath, checkOptions);
10502
10947
  } finally {
10503
10948
  realmPlan.cleanup();
10504
10949
  }
10505
10950
  else {
10506
- const resolved = resolveWorkspaceConfig(targetPath, checkOptions.configpath, {
10951
+ const resolvedDeps = resolvePackageDependencies(rootPath, userConfig, checkOptions.deps);
10952
+ const unrequestedExclusions = computeUnrequestedExclusions(rootPath, canonicalTargets);
10953
+ const resolved = resolveWorkspaceConfig(rootPath, checkOptions.configpath, {
10507
10954
  ignore: checkOptions.ignore,
10508
- annotationsPath
10955
+ annotationsPath,
10956
+ dependencyLibraries: resolvedDeps.all,
10957
+ unrequestedExclusions
10509
10958
  });
10510
10959
  try {
10511
- result = await runLuaLSCheck(targetPath, resolved.configPath, checkOptions);
10960
+ result = await runLuaLSCheck(rootPath, resolved.configPath, checkOptions);
10512
10961
  } finally {
10513
10962
  if (resolved.isTemp && fs.existsSync(resolved.configPath)) try {
10514
10963
  fs.unlinkSync(resolved.configPath);
@@ -10589,6 +11038,7 @@ Examples:
10589
11038
  $ npx nanos-lint check . --checklevel=Error
10590
11039
  $ npx nanos-lint check . --ignore "myfolder/hello-*.lua"
10591
11040
  $ npx nanos-lint check . --realm server
11041
+ $ npx nanos-lint check Shared/ Server/ --realm server
10592
11042
  $ npx nanos-lint init
10593
11043
  $ npx nanos-lint clean-cache
10594
11044
  `);
@@ -10668,6 +11118,6 @@ if (isDirectExecution()) runCLI().then((code) => {
10668
11118
  process.exit(1);
10669
11119
  });
10670
11120
  //#endregion
10671
- export { getBaseLuaLSCacheDir as $, getDirectorySize as $t, formatProblemSummary as A, VALID_LUALS_DIAGNOSTIC_CODES as At, runLuaLSCheck as B, parseJsonc as Bt, getCachedAnnotationsFilePath as C, fetchLatestLuaLSVersionFromGitHub as Ct, updateLastCheckedDate as D, deriveRealmAnnotationFiles as Dt, readAnnotationsMetadata as E, sanitizeLuaLSVersion as Et, shouldEnableColor as F, getPackageRoot as Ft, MAX_ARCHIVE_SIZE_BYTES as G, writeTempConfig as Gt, listCheckedFiles as H, resolveWorkspaceConfig as Ht, collectRealmFiles as I, initWorkspace as It, isAllowedDownloadUrl as J, ConfigError as Jt, computeFileSha256 as K, AnnotationsError as Kt, planRealmCheck as L, loadConfigFile as Lt, formatSeverityBadge as M, getDefaultAnnotationsPath as Mt, getColors as N, getDefaultTemplatePath as Nt, formatGitHubAnnotations as O, splitAnnotationsByRealm as Ot, pluralize as P, getDefinitionsDir as Pt, findExistingLuaLSDir as Q, formatBytes as Qt, runRealmAwareCheck as R, loadUserConfig as Rt, getAnnotationsMetadataFilePath as S, FALLBACK_LUALS_VERSION as St, isAnnotationsValid as T, resolveLuaLSVersion as Tt, ALLOWED_DOWNLOAD_DOMAINS as U, stripJsonComments as Ut, countCheckedFiles as V, resolveRealmMappings as Vt, DOWNLOAD_TIMEOUT_MS as W, stripTrailingSlashes as Wt, LUALS_METADATA_FILENAME as X, NanosLintError as Xt, limitDownloadStream as Y, LuaLSError as Yt, cleanupOldCachedLuaLSVersions as Z, cleanCache as Zt, MAX_ANNOTATIONS_SIZE_BYTES as _, isZipArchive as _t, formatCacheStatusPretty as a, Logger as an, readLuaLSMetadata as at, MIN_ANNOTATIONS_SIZE_BYTES as b, getPlatformInfo as bt, DOCGEN_BRANCH as c, parseLogLevel as cn, MAX_DECOMPRESSED_SIZE_BYTES as ct, RAW_ANNOTATIONS_URL as d, escapePowerShellSingleQuote as dt, systemPaths as en, getCacheDir as et, downloadAndCacheAnnotations as f, getTarBinary as ft, ANNOTATIONS_FILENAME as g, isGzipArchive as gt, getRawAnnotationsUrl as h, isBinaryValid as ht, runCLI as i, LOG_LEVEL_PRIORITY as in, listCachedLuaLSVersions as it, formatReport as j, buildWorkspaceConfig as jt, formatPretty as k, DEFAULT_REALM_MAPPINGS as kt, DOCGEN_REPO as l, MIN_DOWNLOADED_BINARY_SIZE_BYTES as lt, fetchRawAnnotationsContent as m, isBinaryRunnable as mt, createProgram as n, DEFAULT_LOG_LEVEL as nn, getLuaLSMetadataPath as nt, getCacheStatus as o, isValidLogLevel as on, writeLuaLSMetadata as ot, fetchLatestCommitId as p, inspectZipMembers as pt, downloadAndExtractLuaLS as q, CacheError as qt, isDirectExecution as r, LOG_LEVELS as rn, listCachedLuaLSVersionDirs as rt, resolveAnnotations as s, logger as sn, MAX_ARCHIVE_MEMBER_COUNT as st, collectIgnorePatterns as t, fileUriToPath as tn, getIsoWeek as tt, GITHUB_COMMITS_API as u, assertValidLuaLSBinary as ut, MAX_COMMIT_JSON_SIZE_BYTES as v, parseTarTvSize as vt, getTodayDateString as w, resolveLatestLuaLSVersion as wt, getAnnotationsCacheDir as x, DEFAULT_LUALS_VERSION as xt, METADATA_FILENAME as y, validateArchiveMembers as yt, resolveLuaLSBinary as z, mergeConfigs as zt };
11121
+ export { ALLOWED_DOWNLOAD_DOMAINS as $, stripJsonComments as $t, formatProblemSummary as A, getPlatformInfo as At, resolvePackageDependencies as B, VALID_LUALS_DIAGNOSTIC_CODES as Bt, getCachedAnnotationsFilePath as C, inspectZipMembers as Ct, updateLastCheckedDate as D, isZipArchive as Dt, readAnnotationsMetadata as E, isGzipArchive as Et, shouldEnableColor as F, resolveLuaLSVersion as Ft, computeUnrequestedExclusions as G, getPackageRoot as Gt, runLuaLSCheck as H, getDefaultAnnotationsPath as Ht, collectRealmFiles as I, sanitizeLuaLSVersion as It, findProjectRoot as J, loadUserConfig as Jt, filterReportByTargetPaths as K, initWorkspace as Kt, planRealmCheck as L, deriveRealmAnnotationFiles as Lt, formatSeverityBadge as M, FALLBACK_LUALS_VERSION as Mt, getColors as N, fetchLatestLuaLSVersionFromGitHub as Nt, formatGitHubAnnotations as O, parseTarTvSize as Ot, pluralize as P, resolveLatestLuaLSVersion as Pt, resolveCheckTargets as Q, resolveWorkspaceConfig as Qt, runRealmAwareCheck as R, splitAnnotationsByRealm as Rt, getAnnotationsMetadataFilePath as S, getTarBinary as St, isAnnotationsValid as T, isBinaryValid as Tt, countCheckedFiles as U, getDefaultTemplatePath as Ut, resolveLuaLSBinary as V, buildWorkspaceConfig as Vt, listCheckedFiles as W, getDefinitionsDir as Wt, isFilesystemRoot as X, parseJsonc as Xt, getCanonicalPath as Y, mergeConfigs as Yt, matchesTargetPaths as Z, resolveRealmMappings as Zt, MAX_ANNOTATIONS_SIZE_BYTES as _, logger as _n, MAX_ARCHIVE_MEMBER_COUNT as _t, formatCacheStatusPretty as a, LuaLSError as an, limitDownloadStream as at, MIN_ANNOTATIONS_SIZE_BYTES as b, assertValidLuaLSBinary as bt, DOCGEN_BRANCH as c, formatBytes as cn, findExistingLuaLSDir as ct, RAW_ANNOTATIONS_URL as d, fileUriToPath as dn, getIsoWeek as dt, stripTrailingSlashes as en, DOWNLOAD_TIMEOUT_MS as et, downloadAndCacheAnnotations as f, DEFAULT_LOG_LEVEL as fn, getLuaLSMetadataPath as ft, ANNOTATIONS_FILENAME as g, isValidLogLevel as gn, writeLuaLSMetadata as gt, getRawAnnotationsUrl as h, Logger as hn, readLuaLSMetadata as ht, runCLI as i, ConfigError as in, isAllowedDownloadUrl as it, formatReport as j, DEFAULT_LUALS_VERSION as jt, formatPretty as k, validateArchiveMembers as kt, DOCGEN_REPO as l, getDirectorySize as ln, getBaseLuaLSCacheDir as lt, fetchRawAnnotationsContent as m, LOG_LEVEL_PRIORITY as mn, listCachedLuaLSVersions as mt, createProgram as n, AnnotationsError as nn, computeFileSha256 as nt, getCacheStatus as o, NanosLintError as on, LUALS_METADATA_FILENAME as ot, fetchLatestCommitId as p, LOG_LEVELS as pn, listCachedLuaLSVersionDirs as pt, findCommonAncestorDirectory as q, loadConfigFile as qt, isDirectExecution as r, CacheError as rn, downloadAndExtractLuaLS as rt, resolveAnnotations as s, cleanCache as sn, cleanupOldCachedLuaLSVersions as st, collectIgnorePatterns as t, writeTempConfig as tn, MAX_ARCHIVE_SIZE_BYTES as tt, GITHUB_COMMITS_API as u, systemPaths as un, getCacheDir as ut, MAX_COMMIT_JSON_SIZE_BYTES as v, parseLogLevel as vn, MAX_DECOMPRESSED_SIZE_BYTES as vt, getTodayDateString as w, isBinaryRunnable as wt, getAnnotationsCacheDir as x, escapePowerShellSingleQuote as xt, METADATA_FILENAME as y, MIN_DOWNLOADED_BINARY_SIZE_BYTES as yt, collectDeps as z, DEFAULT_REALM_MAPPINGS as zt };
10672
11122
 
10673
- //# sourceMappingURL=cli-B9EpAClV.js.map
11123
+ //# sourceMappingURL=cli-Cb3wLBCr.js.map