limina 0.0.2 → 0.0.3

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.
@@ -1,4 +1,4 @@
1
- import { c as getCheckerAdapter, h as toRelativePath, l as isPathInsideDirectory, m as toPosixPath, o as collectMissingCheckerPeerDependencies, r as getActiveCheckers, s as formatMissingCheckerPeerDependencies, u as normalizeAbsolutePath } from "./dep-jgc7X0zw.js";
1
+ import { c as getCheckerAdapter, d as normalizeAbsolutePath, g as toRelativePath, h as toPosixPath, l as normalizeExtensions, o as collectMissingCheckerPeerDependencies, r as getActiveCheckers, s as formatMissingCheckerPeerDependencies, u as isPathInsideDirectory } from "./dep-DzYrmtQJ.js";
2
2
  import { builtinModules, createRequire } from "node:module";
3
3
  import { createElapsedTimer, formatErrorMessage, formatErrorMessage as formatErrorMessage$1 } from "logaria/helper";
4
4
  import { existsSync, readFileSync, statSync } from "node:fs";
@@ -11,7 +11,6 @@ import readline from "node:readline";
11
11
  import * as prompts from "@clack/prompts";
12
12
  import { mkdir, writeFile } from "node:fs/promises";
13
13
  import { parse } from "yaml";
14
- import { availableParallelism } from "node:os";
15
14
 
16
15
  //#region src/tsconfig.ts
17
16
  const dtsConfigFilePattern = /^tsconfig(?:\..+)?\.dts\.json$/u;
@@ -31,7 +30,7 @@ function escapeRegExp(value) {
31
30
  return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
32
31
  }
33
32
  function createExtensionPattern(extensions) {
34
- if (extensions.length === 0) return /$./u;
33
+ if (extensions.length === 0) return /(?!)/u;
35
34
  return new RegExp(`(?:${extensions.sort((left, right) => right.length - left.length).map(escapeRegExp).join("|")})$`, "u");
36
35
  }
37
36
  function createExtraFileExtensions(extensions) {
@@ -141,13 +140,6 @@ function collectReferencePathInfosFromConfigObject(rootDir, configPath, configOb
141
140
  references: referenceInfos
142
141
  };
143
142
  }
144
- function isNonEmptyStringArray(value) {
145
- return Array.isArray(value) && value.some((item) => typeof item === "string");
146
- }
147
- function hasOwnTypecheckInputs(configObject) {
148
- if (!Object.hasOwn(configObject, "files") && !Object.hasOwn(configObject, "include")) return true;
149
- return isNonEmptyStringArray(configObject.files) || isNonEmptyStringArray(configObject.include);
150
- }
151
143
  function isDtsConfigPath(configPath) {
152
144
  return dtsConfigFilePattern.test(path.basename(configPath));
153
145
  }
@@ -169,91 +161,6 @@ function isOrdinaryTypecheckConfigPath(configPath) {
169
161
  const fileName = path.basename(configPath);
170
162
  return tsconfigFilePattern.test(fileName) && !isReservedTypeScriptConfigFile(fileName);
171
163
  }
172
- function collectTypecheckTargetProjectPaths(options) {
173
- const rootConfigPath = normalizeAbsolutePath(options.rootConfigPath);
174
- const reportedCycles = /* @__PURE__ */ new Set();
175
- const seen = /* @__PURE__ */ new Set();
176
- const problems = [];
177
- const projectPaths = [];
178
- const targetProjectPaths = [];
179
- const formatConfigPath = (configPath) => toRelativePath(options.rootDir, configPath);
180
- const addCycleProblem = (referencePath, stack) => {
181
- const cycleStartIndex = stack.indexOf(referencePath);
182
- const cyclePaths = cycleStartIndex === -1 ? [...stack, referencePath] : [...stack.slice(cycleStartIndex), referencePath];
183
- const cycleKey = cyclePaths.join("\0");
184
- if (reportedCycles.has(cycleKey)) return;
185
- reportedCycles.add(cycleKey);
186
- problems.push([
187
- "Circular reference in ordinary tsconfig references:",
188
- ` cycle: ${cyclePaths.map(formatConfigPath).join(" -> ")}`,
189
- " reason: ordinary tsconfig references used by limina checker typecheck must form an acyclic graph.",
190
- " fix: remove one reference from the cycle, or move shared options into extends instead of references."
191
- ].join("\n"));
192
- };
193
- const visitProject = (projectPath, stack) => {
194
- if (stack.includes(projectPath)) {
195
- addCycleProblem(projectPath, stack);
196
- return;
197
- }
198
- if (seen.has(projectPath)) return;
199
- if (!existsSync(projectPath)) {
200
- problems.push(["Ordinary tsconfig reference graph references a missing tsconfig:", ` config: ${formatConfigPath(projectPath)}`].join("\n"));
201
- return;
202
- }
203
- if (!isOrdinaryTypecheckConfigPath(projectPath)) {
204
- problems.push([
205
- "Invalid config in ordinary tsconfig reference graph:",
206
- ` config: ${formatConfigPath(projectPath)}`,
207
- " reason: ordinary tsconfig references must stay on ordinary tsconfig*.json files; tsconfig*.build.json graph aggregators and tsconfig*.dts.json declaration leaves belong to checker entries."
208
- ].join("\n"));
209
- return;
210
- }
211
- seen.add(projectPath);
212
- projectPaths.push(projectPath);
213
- const configObject = readJsonConfigFile(options.rootDir, projectPath);
214
- const referenceCollection = collectReferencePathInfosFromConfigObject(options.rootDir, projectPath, configObject);
215
- const referencePaths = referenceCollection.references.map((reference) => reference.resolvedPath);
216
- problems.push(...referenceCollection.problems);
217
- if (referencePaths.length === 0 || hasOwnTypecheckInputs(configObject)) targetProjectPaths.push(projectPath);
218
- const nextStack = [...stack, projectPath];
219
- for (const referencePath of referencePaths) {
220
- if (isBuildGraphConfigPath(referencePath) || isDtsConfigPath(referencePath)) {
221
- problems.push([
222
- "Invalid reference in ordinary tsconfig reference graph:",
223
- ` from: ${formatConfigPath(projectPath)}`,
224
- ` to: ${formatConfigPath(referencePath)}`,
225
- " reason: ordinary tsconfig references must stay on ordinary tsconfig*.json files; build graph configs and declaration leaves are checked through checker entries."
226
- ].join("\n"));
227
- continue;
228
- }
229
- if (!isOrdinaryTypecheckConfigPath(referencePath)) {
230
- problems.push([
231
- "Invalid reference in ordinary tsconfig reference graph:",
232
- ` from: ${formatConfigPath(projectPath)}`,
233
- ` to: ${formatConfigPath(referencePath)}`,
234
- " reason: referenced config must be an ordinary tsconfig*.json file."
235
- ].join("\n"));
236
- continue;
237
- }
238
- if (nextStack.includes(referencePath)) {
239
- addCycleProblem(referencePath, nextStack);
240
- continue;
241
- }
242
- visitProject(referencePath, nextStack);
243
- }
244
- };
245
- visitProject(rootConfigPath, []);
246
- if (problems.length === 0 && targetProjectPaths.length === 0) problems.push([
247
- "Ordinary tsconfig reference graph has no tsconfig targets:",
248
- ` root: ${toRelativePath(options.rootDir, rootConfigPath)}`,
249
- " reason: limina checker typecheck runs ordinary tsconfig*.json files without references, plus configs that have references and their own source inputs."
250
- ].join("\n"));
251
- return {
252
- problems,
253
- projectPaths,
254
- targetProjectPaths
255
- };
256
- }
257
164
  function collectGraphProjectRouteFromRoot(options) {
258
165
  const rootGraphConfigPath = normalizeAbsolutePath(options.rootConfigPath);
259
166
  const seen = /* @__PURE__ */ new Set();
@@ -322,7 +229,7 @@ function collectGraphProjectRoutes(config) {
322
229
  const routes = [];
323
230
  const problems = [];
324
231
  for (const checker of getActiveCheckers(config)) {
325
- if (!getCheckerAdapter(checker.preset)?.graph) continue;
232
+ if (!getCheckerAdapter(checker.preset)?.sourceGraph) continue;
326
233
  const rootConfigPath = resolveProjectConfigPath(config.rootDir, checker.entry);
327
234
  if (!existsSync(rootConfigPath)) {
328
235
  problems.push([
@@ -339,6 +246,7 @@ function collectGraphProjectRoutes(config) {
339
246
  problems.push(...routeCollection.problems);
340
247
  routes.push({
341
248
  checkerName: checker.name,
249
+ extensions: checker.extensions,
342
250
  projectPaths: routeCollection.projectPaths,
343
251
  rootConfigPath
344
252
  });
@@ -368,6 +276,7 @@ function collectCheckerEntryProjectRoutes(config) {
368
276
  problems.push(...routeCollection.problems);
369
277
  routes.push({
370
278
  checkerName: checker.name,
279
+ extensions: checker.extensions,
371
280
  projectPaths: routeCollection.projectPaths,
372
281
  rootConfigPath
373
282
  });
@@ -384,8 +293,18 @@ function collectGraphProjectRoute(config) {
384
293
  projectPaths: [...new Set(routeCollection.routes.flatMap((route) => route.projectPaths))].sort()
385
294
  };
386
295
  }
387
- function parseProjectFileNames(config, configPath, pattern = /\.(?:[cm]?tsx?|d\.[cm]?ts|json)$/u) {
388
- return parseProjectFileNamesForExtensions(config, configPath, [], pattern);
296
+ function collectSourceGraphProjectExtensions(config) {
297
+ const routeCollection = collectGraphProjectRoutes(config);
298
+ const projectExtensionsByPath = /* @__PURE__ */ new Map();
299
+ const typeScriptExtensions = getCheckerAdapter("tsc")?.defaultExtensions ?? [];
300
+ for (const route of routeCollection.routes) {
301
+ const routeExtensions = normalizeExtensions([...typeScriptExtensions, ...route.extensions]);
302
+ for (const projectPath of route.projectPaths) projectExtensionsByPath.set(projectPath, normalizeExtensions([...projectExtensionsByPath.get(projectPath) ?? [], ...routeExtensions]));
303
+ }
304
+ return {
305
+ problems: routeCollection.problems,
306
+ projectExtensionsByPath
307
+ };
389
308
  }
390
309
  function parseProjectFileNamesForExtensions(config, configPath, extensions, pattern = createExtensionPattern(extensions)) {
391
310
  const diagnostics = [];
@@ -586,6 +505,22 @@ function getDependencySections(importer) {
586
505
  importer.peerDependencies
587
506
  ].filter((section) => Boolean(section));
588
507
  }
508
+ function getPublishDependencySections(importer) {
509
+ return [
510
+ {
511
+ dependencies: importer.dependencies,
512
+ name: "dependencies"
513
+ },
514
+ {
515
+ dependencies: importer.peerDependencies,
516
+ name: "peerDependencies"
517
+ },
518
+ {
519
+ dependencies: importer.optionalDependencies,
520
+ name: "optionalDependencies"
521
+ }
522
+ ].filter((section) => Boolean(section.dependencies));
523
+ }
589
524
  function isWorkspaceDependencySpecifier(specifier) {
590
525
  return specifier.startsWith("workspace:");
591
526
  }
@@ -663,9 +598,9 @@ function readProjectLabel(config, configPath) {
663
598
  ].join("\n")
664
599
  };
665
600
  }
666
- function parseProject(config, configPath) {
601
+ function parseProject(config, configPath, extensions) {
667
602
  const diagnostics = [];
668
- const parsed = ts.getParsedCommandLineOfConfigFile(configPath, {}, {
603
+ const parsed = extensions ? ts.parseJsonConfigFileContent(readJsonConfig(config, configPath), ts.sys, path.dirname(configPath), {}, configPath, void 0, createExtraFileExtensions(extensions)) : ts.getParsedCommandLineOfConfigFile(configPath, {}, {
669
604
  ...ts.sys,
670
605
  onUnRecoverableConfigFileDiagnostic: (diagnostic) => {
671
606
  diagnostics.push(diagnostic);
@@ -682,9 +617,20 @@ function parseProject(config, configPath) {
682
617
  getNewLine: () => "\n"
683
618
  }));
684
619
  const labelInfo = readProjectLabel(config, configPath);
620
+ const projectExtensions = extensions ?? [
621
+ ".ts",
622
+ ".tsx",
623
+ ".cts",
624
+ ".mts",
625
+ ".d.ts",
626
+ ".d.cts",
627
+ ".d.mts"
628
+ ];
629
+ const filePattern = createExtensionPattern(projectExtensions);
685
630
  return {
686
631
  configPath: normalizeAbsolutePath(configPath),
687
- fileNames: parsed.fileNames.filter((fileName) => /\.(?:[cm]?tsx?|d\.[cm]?ts)$/u.test(fileName)).map(normalizeAbsolutePath),
632
+ extensions: projectExtensions,
633
+ fileNames: parsed.fileNames.filter((fileName) => filePattern.test(fileName)).map(normalizeAbsolutePath),
688
634
  label: labelInfo.label,
689
635
  labelProblem: labelInfo.labelProblem,
690
636
  options: parsed.options,
@@ -699,15 +645,27 @@ function getSourceFileKind(filePath) {
699
645
  function stringLiteralValue(node) {
700
646
  return node && ts.isStringLiteralLike(node) ? node.text : null;
701
647
  }
702
- function collectImportsFromFile(filePath) {
703
- const sourceText = readFileSync(filePath, "utf8");
704
- const sourceFile = ts.createSourceFile(filePath, sourceText, ts.ScriptTarget.Latest, true, getSourceFileKind(filePath));
648
+ function getVueCompilerSfc(rootDir) {
649
+ const requireFromRoot = createRequire(path.join(rootDir, "package.json"));
650
+ try {
651
+ return requireFromRoot("@vue/compiler-sfc");
652
+ } catch (error) {
653
+ if (error && typeof error === "object" && "code" in error && error.code === "MODULE_NOT_FOUND") throw new Error("Vue source graph support requires @vue/compiler-sfc. Fix: pnpm add -D @vue/compiler-sfc");
654
+ throw error;
655
+ }
656
+ }
657
+ function getVueBlockScriptKind(block) {
658
+ return block.lang === "tsx" || block.lang === "jsx" ? ts.ScriptKind.TSX : ts.ScriptKind.TS;
659
+ }
660
+ function collectImportsFromSourceText(options) {
661
+ const sourceFile = ts.createSourceFile(options.filePath, options.sourceText, ts.ScriptTarget.Latest, true, options.scriptKind);
705
662
  const imports = [];
663
+ const lineOffset = options.lineOffset ?? 0;
706
664
  const addImport = (specifier, node) => {
707
665
  const location = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
708
666
  imports.push({
709
- filePath,
710
- line: location.line + 1,
667
+ filePath: options.filePath,
668
+ line: lineOffset + location.line + 1,
711
669
  specifier
712
670
  });
713
671
  };
@@ -727,9 +685,37 @@ function collectImportsFromFile(filePath) {
727
685
  visit(sourceFile);
728
686
  return imports;
729
687
  }
730
- function resolveInternalImport(specifier, containingFile, options) {
688
+ function collectVueImportsFromFile(filePath, rootDir) {
689
+ const sourceText = readFileSync(filePath, "utf8");
690
+ const result = getVueCompilerSfc(rootDir).parse(sourceText, { filename: filePath });
691
+ if (result.errors.length > 0) throw new Error(`Failed to parse Vue SFC imports for ${toRelativePath(rootDir, filePath)}: ${String(result.errors[0])}`);
692
+ return [result.descriptor.script, result.descriptor.scriptSetup].filter((block) => Boolean(block && !block.src)).flatMap((block) => collectImportsFromSourceText({
693
+ filePath,
694
+ lineOffset: block.loc.start.line - 1,
695
+ scriptKind: getVueBlockScriptKind(block),
696
+ sourceText: block.content
697
+ }));
698
+ }
699
+ function collectImportsFromFile(filePath, rootDir) {
700
+ if (filePath.endsWith(".vue")) return collectVueImportsFromFile(filePath, rootDir);
701
+ return collectImportsFromSourceText({
702
+ filePath,
703
+ scriptKind: getSourceFileKind(filePath),
704
+ sourceText: readFileSync(filePath, "utf8")
705
+ });
706
+ }
707
+ function resolveInternalImport(specifier, containingFile, options, extensions = []) {
731
708
  const resolved = ts.resolveModuleName(specifier, containingFile, options, ts.sys).resolvedModule;
732
- return resolved?.resolvedFileName ? normalizeAbsolutePath(resolved.resolvedFileName) : null;
709
+ if (resolved?.resolvedFileName) return normalizeAbsolutePath(resolved.resolvedFileName);
710
+ if (!isRelativeSpecifier$1(specifier)) return null;
711
+ const resolvedSpecifierPath = path.resolve(path.dirname(containingFile), specifier);
712
+ const candidatePaths = path.extname(specifier) ? [resolvedSpecifierPath] : extensions.flatMap((extension) => [`${resolvedSpecifierPath}${extension}`, path.join(resolvedSpecifierPath, `index${extension}`)]);
713
+ for (const candidatePath of candidatePaths) {
714
+ if (!existsSync(candidatePath)) continue;
715
+ if (!statSync(candidatePath).isFile()) continue;
716
+ return normalizeAbsolutePath(candidatePath);
717
+ }
718
+ return null;
733
719
  }
734
720
  function chooseOwningProject(projectPaths) {
735
721
  return [...projectPaths].sort((left, right) => {
@@ -1437,7 +1423,7 @@ function inferProjectReferences(options) {
1437
1423
  const referencePaths = /* @__PURE__ */ new Set();
1438
1424
  for (const fileName of project.fileNames) {
1439
1425
  if (!/\.(?:[cm]?tsx?|d\.[cm]?ts)$/u.test(fileName)) continue;
1440
- for (const importRecord of collectImportsFromFile(fileName)) {
1426
+ for (const importRecord of collectImportsFromFile(fileName, options.config.rootDir)) {
1441
1427
  const resolvedFilePath = resolveImportWithTypeScript({
1442
1428
  cache: resolutionCache,
1443
1429
  host,
@@ -1622,11 +1608,14 @@ function findOwnerForFile(filePath, owners) {
1622
1608
  function isUrlOrDataOrFileSpecifier(specifier) {
1623
1609
  return specifier.startsWith("data:") || specifier.startsWith("file:") || specifier.startsWith("http:") || specifier.startsWith("https:");
1624
1610
  }
1611
+ function isVirtualModuleSpecifier(specifier) {
1612
+ return specifier.startsWith("virtual:");
1613
+ }
1625
1614
  function isPackageImportSpecifier(specifier) {
1626
1615
  return specifier.startsWith("#");
1627
1616
  }
1628
1617
  function isBarePackageSpecifier(specifier) {
1629
- return !isRelativeSpecifier$1(specifier) && !isPackageImportSpecifier(specifier) && !isUrlOrDataOrFileSpecifier(specifier) && !path.isAbsolute(specifier);
1618
+ return !isRelativeSpecifier$1(specifier) && !isPackageImportSpecifier(specifier) && !isUrlOrDataOrFileSpecifier(specifier) && !isVirtualModuleSpecifier(specifier) && !path.isAbsolute(specifier);
1630
1619
  }
1631
1620
  function isDependencyAuthorized(manifest, packageName) {
1632
1621
  return Boolean(manifest.dependencies?.[packageName] || manifest.devDependencies?.[packageName]);
@@ -1734,7 +1723,7 @@ function createSourceProjectEntries(config, projects) {
1734
1723
  return projects.filter((project) => isDtsProjectConfig(project.configPath)).map((project) => {
1735
1724
  const typecheckConfigPath = getTypecheckConfigPath(project.configPath);
1736
1725
  const fileNames = new Set(project.fileNames);
1737
- if (existsSync(typecheckConfigPath)) for (const fileName of parseProject(config, typecheckConfigPath).fileNames) fileNames.add(fileName);
1726
+ if (existsSync(typecheckConfigPath)) for (const fileName of parseProject(config, typecheckConfigPath, project.extensions).fileNames) fileNames.add(fileName);
1738
1727
  return {
1739
1728
  fileNames: [...fileNames].sort(),
1740
1729
  project
@@ -1742,8 +1731,8 @@ function createSourceProjectEntries(config, projects) {
1742
1731
  });
1743
1732
  }
1744
1733
  async function runSourceCheckInternal(config, options = {}) {
1745
- const graphRoute = collectGraphProjectRoute(config);
1746
- const projects = graphRoute.projectPaths.map((projectPath) => parseProject(config, projectPath));
1734
+ const graphRoute = collectSourceGraphProjectExtensions(config);
1735
+ const projects = [...graphRoute.projectExtensionsByPath.keys()].sort().map((projectPath) => parseProject(config, projectPath, graphRoute.projectExtensionsByPath.get(projectPath)));
1747
1736
  const sourceProjectEntries = createSourceProjectEntries(config, projects);
1748
1737
  const packages = await collectWorkspacePackages(config);
1749
1738
  const packageOwners = await collectPackageOwners(config);
@@ -1763,7 +1752,7 @@ async function runSourceCheckInternal(config, options = {}) {
1763
1752
  if (existsSync(typecheckConfigPath)) addProjectOwnerProblems({
1764
1753
  config,
1765
1754
  configPath: typecheckConfigPath,
1766
- fileNames: parseProject(config, typecheckConfigPath).fileNames,
1755
+ fileNames: parseProject(config, typecheckConfigPath, project.extensions).fileNames,
1767
1756
  owners: packageOwners,
1768
1757
  problems,
1769
1758
  role: "typecheck companion"
@@ -1772,8 +1761,8 @@ async function runSourceCheckInternal(config, options = {}) {
1772
1761
  for (const { fileNames, project } of sourceProjectEntries) for (const filePath of fileNames) {
1773
1762
  const owner = findOwnerForFile(filePath, packageOwners);
1774
1763
  if (!owner) continue;
1775
- for (const importRecord of collectImportsFromFile(filePath)) {
1776
- const resolvedFilePath = resolveInternalImport(importRecord.specifier, filePath, project.options);
1764
+ for (const importRecord of collectImportsFromFile(filePath, config.rootDir)) {
1765
+ const resolvedFilePath = resolveInternalImport(importRecord.specifier, filePath, project.options, project.extensions);
1777
1766
  if (isRelativeSpecifier$1(importRecord.specifier)) {
1778
1767
  if (!resolvedFilePath) continue;
1779
1768
  const targetOwner = findOwnerForFile(resolvedFilePath, packageOwners);
@@ -1797,7 +1786,7 @@ async function runSourceCheckInternal(config, options = {}) {
1797
1786
  });
1798
1787
  continue;
1799
1788
  }
1800
- if (isUrlOrDataOrFileSpecifier(importRecord.specifier)) continue;
1789
+ if (isUrlOrDataOrFileSpecifier(importRecord.specifier) || isVirtualModuleSpecifier(importRecord.specifier)) continue;
1801
1790
  if (!isBarePackageSpecifier(importRecord.specifier)) continue;
1802
1791
  if (isNodeBuiltinSpecifier(importRecord.specifier)) continue;
1803
1792
  const packageName = getPackageRootSpecifier(importRecord.specifier);
@@ -1846,14 +1835,9 @@ async function runSourceCheck(config, options = {}) {
1846
1835
 
1847
1836
  //#endregion
1848
1837
  //#region src/commands/typecheck.ts
1849
- function normalizeConcurrency(value) {
1850
- if (value === void 0) return Math.max(1, availableParallelism());
1851
- if (!Number.isInteger(value) || value < 1) throw new Error("Typecheck concurrency must be a positive integer.");
1852
- return value;
1853
- }
1854
1838
  function getExecutionCheckers(options) {
1855
1839
  return options.checkers.filter((checker) => {
1856
- return getCheckerAdapter(checker.preset)?.supportedExecutions.includes(options.executionKind);
1840
+ return getCheckerAdapter(checker.preset)?.execution === options.executionKind;
1857
1841
  });
1858
1842
  }
1859
1843
  function collectCheckerPeerDependencyProblems(options) {
@@ -1875,49 +1859,14 @@ function createCheckerTarget(options) {
1875
1859
  executionKind: options.executionKind
1876
1860
  };
1877
1861
  }
1878
- function collectCompanionTypecheckTargets(options) {
1879
- const entryConfigPath = resolveProjectConfigPath(options.projectRootDir, options.checker.entry);
1880
- if (!existsSync(entryConfigPath)) return {
1881
- entryConfigPath,
1882
- problems: [[
1883
- "Checker entry references a missing tsconfig:",
1884
- ` checker: ${options.checker.name}`,
1885
- ` config: ${toRelativePath(options.projectRootDir, entryConfigPath)}`
1886
- ].join("\n")],
1887
- targetProjectPaths: []
1888
- };
1889
- const routeCollection = collectGraphProjectRouteFromRoot({
1890
- rootConfigPath: entryConfigPath,
1891
- rootDir: options.projectRootDir
1892
- });
1893
- const dtsConfigPaths = routeCollection.projectPaths.filter(isDtsConfigPath);
1894
- const targetProjectPaths = [...new Set(dtsConfigPaths.map(getDtsCompanionConfigPath))].sort();
1895
- const problems = [...routeCollection.problems];
1896
- if (dtsConfigPaths.length === 0) problems.push([
1897
- "Checker entry has no declaration leaf targets:",
1898
- ` checker: ${options.checker.name}`,
1899
- ` entry: ${toRelativePath(options.projectRootDir, entryConfigPath)}`,
1900
- " reason: checker:typecheck derives targets from tsconfig*.dts.json leaves reachable from the checker entry."
1901
- ].join("\n"));
1902
- for (const configPath of targetProjectPaths) {
1903
- if (existsSync(configPath)) continue;
1904
- problems.push([
1905
- "DTS leaf companion config is missing:",
1906
- ` checker: ${options.checker.name}`,
1907
- ` expected: ${toRelativePath(options.projectRootDir, configPath)}`,
1908
- " reason: checker:typecheck runs the strict local tsconfig companion for each reachable declaration leaf."
1909
- ].join("\n"));
1910
- }
1911
- return {
1912
- entryConfigPath,
1913
- problems,
1914
- targetProjectPaths
1915
- };
1916
- }
1917
1862
  function createDefaultRunner() {
1918
1863
  return async (target) => await new Promise((resolve) => {
1919
1864
  const child = spawn(target.command, target.args, {
1920
1865
  cwd: target.cwd,
1866
+ env: {
1867
+ ...process.env,
1868
+ PATH: [path.join(target.cwd, "node_modules/.bin"), process.env.PATH].filter(Boolean).join(path.delimiter)
1869
+ },
1921
1870
  shell: process.platform === "win32",
1922
1871
  stdio: "inherit"
1923
1872
  });
@@ -1962,138 +1911,106 @@ async function runWithConcurrency(targets, concurrency, runner, options = {}) {
1962
1911
  }));
1963
1912
  return results;
1964
1913
  }
1965
- async function runCheckerTypecheckInternal(options) {
1914
+ async function runCheckerBuildInternal(options) {
1966
1915
  const cwd = path.resolve(options.cwd ?? process.cwd());
1967
1916
  const projectRootDir = normalizeAbsolutePath(options.config.rootDir);
1968
1917
  const allCheckers = getActiveCheckers(options.config);
1969
1918
  const checkers = getExecutionCheckers({
1970
1919
  checkers: allCheckers,
1971
- executionKind: "typecheck"
1920
+ executionKind: "build"
1972
1921
  });
1973
1922
  const flowDepth = options.flowDepth ?? 0;
1974
- const concurrency = normalizeConcurrency(options.concurrency);
1923
+ const rootConfigPaths = [];
1975
1924
  const problems = collectCheckerPeerDependencyProblems({
1976
1925
  checkers: allCheckers,
1977
1926
  projectRootDir,
1978
1927
  resolvePackage: options.checkerPackageResolver
1979
1928
  });
1980
- const rootConfigPaths = [];
1981
- const targetProjectPaths = [];
1982
- const targets = [];
1983
1929
  if (problems.length > 0) {
1984
1930
  options.flow?.fail("checker dependency preflight failed", { depth: flowDepth + 1 });
1985
1931
  TypecheckLogger.error(problems.join("\n\n"));
1986
1932
  return {
1987
1933
  passed: false,
1988
1934
  projectRootDir,
1989
- results: [],
1990
- rootConfigPaths,
1991
- targetProjectPaths
1935
+ rootConfigPaths
1992
1936
  };
1993
1937
  }
1994
- if (checkers.length === 0) problems.push(["No checker typecheck entries configured:", " reason: configure config.checkers.<name>.entry with a preset that supports checker:typecheck."].join("\n"));
1995
- for (const checker of checkers) {
1996
- const targetCollection = collectCompanionTypecheckTargets({
1997
- checker,
1998
- projectRootDir
1999
- });
2000
- problems.push(...targetCollection.problems);
2001
- rootConfigPaths.push(targetCollection.entryConfigPath);
2002
- targetProjectPaths.push(...targetCollection.targetProjectPaths);
2003
- targets.push(...targetCollection.targetProjectPaths.map((configPath) => createCheckerTarget({
1938
+ const targets = checkers.flatMap((checker) => {
1939
+ const configPath = resolveProjectConfigPath(projectRootDir, checker.entry);
1940
+ rootConfigPaths.push(configPath);
1941
+ return [createCheckerTarget({
2004
1942
  checker,
2005
1943
  commandOverride: options.tscCommand,
2006
1944
  configPath,
2007
- executionKind: "typecheck",
1945
+ executionKind: "build",
2008
1946
  projectRootDir
2009
- })));
2010
- }
2011
- if (problems.length > 0) {
2012
- options.flow?.fail("typecheck target discovery failed", { depth: flowDepth + 1 });
2013
- TypecheckLogger.error(problems.join("\n\n"));
2014
- return {
2015
- passed: false,
2016
- projectRootDir,
2017
- results: [],
2018
- rootConfigPaths,
2019
- targetProjectPaths
2020
- };
2021
- }
2022
- options.flow?.info(`found ${targets.length} typecheck target config(s) across ${checkers.length} checker(s); concurrency ${concurrency}`, { depth: flowDepth + 1 });
1947
+ })];
1948
+ });
1949
+ options.flow?.info(`found ${targets.length} checker build entry(s)`, { depth: flowDepth + 1 });
2023
1950
  TypecheckLogger.info([
2024
- `Running checker typechecks for ${targets.length} target config(s).`,
1951
+ `Running build checks for ${targets.length} checker entry(s).`,
2025
1952
  `CWD: ${toRelativePath(cwd, projectRootDir)}`,
2026
1953
  `Entries: ${rootConfigPaths.map((configPath) => toRelativePath(projectRootDir, configPath)).join(", ")}`
2027
1954
  ].join("\n"));
2028
- const targetFlowStates = /* @__PURE__ */ new Map();
2029
- const results = await runWithConcurrency(targets, concurrency, options.runner ?? createDefaultRunner(), {
1955
+ const targetTasks = /* @__PURE__ */ new Map();
1956
+ const failedResults = (await runWithConcurrency(targets, 1, options.runner ?? createDefaultRunner(), {
2030
1957
  onTargetResult: (target, result) => {
2031
- if (!options.flow) return;
2032
- const flowState = targetFlowStates.get(target.configPath);
2033
- if (!flowState) return;
2034
- const resultOptions = {
2035
- depth: flowDepth + 1,
2036
- elapsedTimeMs: performance.now() - flowState.startedAt
2037
- };
2038
- if (result.status === 0) options.flow.pass(flowState.label, resultOptions);
1958
+ const task = targetTasks.get(target.configPath);
1959
+ if (!task) return;
1960
+ if (result.status === 0) task.pass();
2039
1961
  else {
2040
1962
  const suffix = result.error ? formatErrorMessage$1(result.error) : `exited with code ${result.status}`;
2041
- options.flow.fail(flowState.label, {
2042
- ...resultOptions,
2043
- error: suffix
2044
- });
1963
+ task.fail(void 0, { error: suffix });
2045
1964
  }
2046
1965
  },
2047
1966
  onTargetStart: (target) => {
2048
1967
  if (!options.flow) return;
2049
- targetFlowStates.set(target.configPath, {
2050
- label: target.label ?? `checker: ${toRelativePath(projectRootDir, target.configPath)}`,
2051
- startedAt: performance.now()
2052
- });
1968
+ targetTasks.set(target.configPath, options.flow.start(target.label ?? `checker build: ${toRelativePath(projectRootDir, target.configPath)}`, {
1969
+ collapseOnSuccess: false,
1970
+ depth: flowDepth + 1
1971
+ }));
2053
1972
  }
2054
- });
2055
- const failedResults = results.filter((result) => result.status !== 0);
2056
- if (failedResults.length > 0) TypecheckLogger.error([`Typecheck failed for ${failedResults.length} config(s):`, ...failedResults.map((result) => {
1973
+ })).filter((result) => result.status !== 0);
1974
+ const passed = failedResults.length === 0;
1975
+ if (!passed) TypecheckLogger.error(["build checks failed:", ...failedResults.map((result) => {
2057
1976
  const suffix = result.error ? `: ${formatErrorMessage$1(result.error)}` : ` exited with code ${result.status}`;
2058
1977
  return ` ${toRelativePath(projectRootDir, result.configPath)}${suffix}`;
2059
1978
  })].join("\n"));
2060
- else if (!options.flow?.interactive) TypecheckLogger.success(`Checked ${targets.length} typecheck target config(s) from ${rootConfigPaths.length} checker entry(s).`);
1979
+ else if (!options.flow?.interactive) TypecheckLogger.success(`Checked ${targets.length} checker build entry(s).`);
2061
1980
  return {
2062
- passed: failedResults.length === 0,
1981
+ passed,
2063
1982
  projectRootDir,
2064
- results,
2065
- rootConfigPaths,
2066
- targetProjectPaths
1983
+ rootConfigPaths
2067
1984
  };
2068
1985
  }
2069
- async function runCheckerTypecheck(options) {
1986
+ async function runCheckerBuild(options) {
2070
1987
  if (options.clearScreen ?? true) clearCliScreen();
2071
1988
  const elapsed = createElapsedTimer();
2072
- const task = options.flow?.start("checker typecheck", { depth: options.flowDepth ?? 0 });
2073
- TypecheckLogger.info("checker typecheck started");
1989
+ const task = options.flow?.start("checker build", { depth: options.flowDepth ?? 0 });
1990
+ TypecheckLogger.info("checker build started");
2074
1991
  try {
2075
- const result = await runCheckerTypecheckInternal(options);
1992
+ const result = await runCheckerBuildInternal(options);
2076
1993
  if (result.passed) {
2077
- if (!options.flow?.interactive) TypecheckLogger.success("checker typecheck finished", elapsed());
1994
+ if (!options.flow?.interactive) TypecheckLogger.success("checker build finished", elapsed());
2078
1995
  task?.pass();
2079
1996
  } else {
2080
- TypecheckLogger.error("checker typecheck finished with failures", elapsed());
2081
- task?.fail("checker typecheck finished with failures");
1997
+ TypecheckLogger.error("checker build finished with failures", elapsed());
1998
+ task?.fail("checker build finished with failures");
2082
1999
  }
2083
2000
  return result;
2084
2001
  } catch (error) {
2085
- TypecheckLogger.error(`checker typecheck failed: ${formatErrorMessage$1(error)}`, elapsed());
2086
- task?.fail("checker typecheck failed", { error });
2002
+ TypecheckLogger.error(`checker build failed: ${formatErrorMessage$1(error)}`, elapsed());
2003
+ task?.fail("checker build failed", { error });
2087
2004
  throw error;
2088
2005
  }
2089
2006
  }
2090
- async function runCheckerBuildInternal(options) {
2007
+ async function runCheckerTypecheckInternal(options) {
2091
2008
  const cwd = path.resolve(options.cwd ?? process.cwd());
2092
2009
  const projectRootDir = normalizeAbsolutePath(options.config.rootDir);
2093
2010
  const allCheckers = getActiveCheckers(options.config);
2094
2011
  const checkers = getExecutionCheckers({
2095
2012
  checkers: allCheckers,
2096
- executionKind: "build"
2013
+ executionKind: "typecheck"
2097
2014
  });
2098
2015
  const flowDepth = options.flowDepth ?? 0;
2099
2016
  const rootConfigPaths = [];
@@ -2111,20 +2028,29 @@ async function runCheckerBuildInternal(options) {
2111
2028
  rootConfigPaths
2112
2029
  };
2113
2030
  }
2114
- const targets = checkers.flatMap((checker) => {
2031
+ const targets = checkers.map((checker) => {
2115
2032
  const configPath = resolveProjectConfigPath(projectRootDir, checker.entry);
2116
2033
  rootConfigPaths.push(configPath);
2117
- return [createCheckerTarget({
2034
+ return createCheckerTarget({
2118
2035
  checker,
2119
2036
  commandOverride: options.tscCommand,
2120
2037
  configPath,
2121
- executionKind: "build",
2038
+ executionKind: "typecheck",
2122
2039
  projectRootDir
2123
- })];
2040
+ });
2124
2041
  });
2125
- options.flow?.info(`found ${targets.length} checker build entry(s)`, { depth: flowDepth + 1 });
2042
+ if (targets.length === 0) {
2043
+ options.flow?.info("no source-only checker entries configured", { depth: flowDepth + 1 });
2044
+ if (!options.flow?.interactive) TypecheckLogger.success("No source-only checker entries configured.");
2045
+ return {
2046
+ passed: true,
2047
+ projectRootDir,
2048
+ rootConfigPaths
2049
+ };
2050
+ }
2051
+ options.flow?.info(`found ${targets.length} checker typecheck entry(s)`, { depth: flowDepth + 1 });
2126
2052
  TypecheckLogger.info([
2127
- `Running build checks for ${targets.length} checker entry(s).`,
2053
+ `Running typecheck for ${targets.length} checker entry(s).`,
2128
2054
  `CWD: ${toRelativePath(cwd, projectRootDir)}`,
2129
2055
  `Entries: ${rootConfigPaths.map((configPath) => toRelativePath(projectRootDir, configPath)).join(", ")}`
2130
2056
  ].join("\n"));
@@ -2141,42 +2067,42 @@ async function runCheckerBuildInternal(options) {
2141
2067
  },
2142
2068
  onTargetStart: (target) => {
2143
2069
  if (!options.flow) return;
2144
- targetTasks.set(target.configPath, options.flow.start(target.label ?? `checker build: ${toRelativePath(projectRootDir, target.configPath)}`, {
2070
+ targetTasks.set(target.configPath, options.flow.start(target.label ?? `checker typecheck: ${toRelativePath(projectRootDir, target.configPath)}`, {
2145
2071
  collapseOnSuccess: false,
2146
2072
  depth: flowDepth + 1
2147
2073
  }));
2148
2074
  }
2149
2075
  })).filter((result) => result.status !== 0);
2150
2076
  const passed = failedResults.length === 0;
2151
- if (!passed) TypecheckLogger.error(["build checks failed:", ...failedResults.map((result) => {
2077
+ if (!passed) TypecheckLogger.error(["typecheck checks failed:", ...failedResults.map((result) => {
2152
2078
  const suffix = result.error ? `: ${formatErrorMessage$1(result.error)}` : ` exited with code ${result.status}`;
2153
2079
  return ` ${toRelativePath(projectRootDir, result.configPath)}${suffix}`;
2154
2080
  })].join("\n"));
2155
- else if (!options.flow?.interactive) TypecheckLogger.success(`Checked ${targets.length} checker build entry(s).`);
2081
+ else if (!options.flow?.interactive) TypecheckLogger.success(`Checked ${targets.length} checker typecheck entry(s).`);
2156
2082
  return {
2157
2083
  passed,
2158
2084
  projectRootDir,
2159
2085
  rootConfigPaths
2160
2086
  };
2161
2087
  }
2162
- async function runCheckerBuild(options) {
2088
+ async function runCheckerTypecheck(options) {
2163
2089
  if (options.clearScreen ?? true) clearCliScreen();
2164
2090
  const elapsed = createElapsedTimer();
2165
- const task = options.flow?.start("checker build", { depth: options.flowDepth ?? 0 });
2166
- TypecheckLogger.info("checker build started");
2091
+ const task = options.flow?.start("checker typecheck", { depth: options.flowDepth ?? 0 });
2092
+ TypecheckLogger.info("checker typecheck started");
2167
2093
  try {
2168
- const result = await runCheckerBuildInternal(options);
2094
+ const result = await runCheckerTypecheckInternal(options);
2169
2095
  if (result.passed) {
2170
- if (!options.flow?.interactive) TypecheckLogger.success("checker build finished", elapsed());
2096
+ if (!options.flow?.interactive) TypecheckLogger.success("checker typecheck finished", elapsed());
2171
2097
  task?.pass();
2172
2098
  } else {
2173
- TypecheckLogger.error("checker build finished with failures", elapsed());
2174
- task?.fail("checker build finished with failures");
2099
+ TypecheckLogger.error("checker typecheck finished with failures", elapsed());
2100
+ task?.fail("checker typecheck finished with failures");
2175
2101
  }
2176
2102
  return result;
2177
2103
  } catch (error) {
2178
- TypecheckLogger.error(`checker build failed: ${formatErrorMessage$1(error)}`, elapsed());
2179
- task?.fail("checker build failed", { error });
2104
+ TypecheckLogger.error(`checker typecheck failed: ${formatErrorMessage$1(error)}`, elapsed());
2105
+ task?.fail("checker typecheck failed", { error });
2180
2106
  throw error;
2181
2107
  }
2182
2108
  }
@@ -2471,4 +2397,4 @@ function createLiminaFlowReporter(options = {}) {
2471
2397
  }
2472
2398
 
2473
2399
  //#endregion
2474
- export { shouldResolveThroughGraph as A, createExtensionPattern as B, formatArtifactDependencyPolicy as C, isRelativeSpecifier$1 as D, isDtsProjectConfig as E, collectCheckerEntryProjectRoutes as F, isDtsConfigPath as G, formatReferences as H, collectGraphProjectRoute as I, parseProjectFileNamesForExtensions as J, isOrdinaryTypecheckConfigPath as K, collectGraphProjectRouteFromRoot as L, collectWorkspacePackages as M, findPackageForSpecifier as N, parseProject as O, getPackageRootSpecifier as P, collectGraphProjectRoutes as R, findTargetProject as S, inferPackageProject as T, getDtsCompanionConfigPath as U, createFormatHost as V, getRawReferencePaths as W, resolveProjectConfigPath as X, readJsonConfig as Y, resolveReferencePath as Z, normalizeGraphRules as _, runSourceCheck as a, findImporterForFile as b, GraphLogger as c, ProofLogger as d, clearCliScreen as f, getDeniedRefRule as g, getDeniedDepRuleForSpecifier as h, runCheckerTypecheck as i, collectImporters as j, resolveInternalImport as k, PackageLogger as l, getDeniedDepRuleForPackage as m, createLiminaFlowReporter as n, runInit as o, formatErrorMessage$1 as p, parseProjectFileNames as q, runCheckerBuild as r, CliLogger as s, LiminaFlowReporter as t, PathsLogger as u, collectImportsFromFile as v, getTypecheckConfigPath as w, findPackageForFile as x, createFileOwnerLookup as y, collectTypecheckTargetProjectPaths as z };
2400
+ export { shouldResolveThroughGraph as A, collectGraphProjectRoutes as B, formatArtifactDependencyPolicy as C, isRelativeSpecifier$1 as D, isDtsProjectConfig as E, getPublishDependencySections as F, formatReferences as G, createExtensionPattern as H, isWorkspaceDependencySpecifier as I, isOrdinaryTypecheckConfigPath as J, getDtsCompanionConfigPath as K, collectCheckerEntryProjectRoutes as L, collectWorkspacePackages as M, findPackageForSpecifier as N, parseProject as O, getPackageRootSpecifier as P, resolveReferencePath as Q, collectGraphProjectRoute as R, findTargetProject as S, inferPackageProject as T, createExtraFileExtensions as U, collectSourceGraphProjectExtensions as V, createFormatHost as W, readJsonConfig as X, parseProjectFileNamesForExtensions as Y, resolveProjectConfigPath as Z, normalizeGraphRules as _, runSourceCheck as a, findImporterForFile as b, GraphLogger as c, ProofLogger as d, clearCliScreen as f, getDeniedRefRule as g, getDeniedDepRuleForSpecifier as h, runCheckerTypecheck as i, collectImporters as j, resolveInternalImport as k, PackageLogger as l, getDeniedDepRuleForPackage as m, createLiminaFlowReporter as n, runInit as o, formatErrorMessage$1 as p, getRawReferencePaths as q, runCheckerBuild as r, CliLogger as s, LiminaFlowReporter as t, PathsLogger as u, collectImportsFromFile as v, getTypecheckConfigPath as w, findPackageForFile as x, createFileOwnerLookup as y, collectGraphProjectRouteFromRoot as z };