@wairon/cli 5.1.1-dev.100 → 5.1.1-dev.101

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/dist/index.js CHANGED
@@ -3828,6 +3828,7 @@ __export(src_exports, {
3828
3828
  resolveSubsystemExports: () => resolveSubsystemExports,
3829
3829
  resolveVariantGuidance: () => resolveVariantGuidance,
3830
3830
  retireSpecialists: () => retireSpecialists,
3831
+ returnTypeOf: () => returnTypeOf,
3831
3832
  rewriteReferences: () => rewriteReferences2,
3832
3833
  runWithHostedLookup: () => runWithHostedLookup,
3833
3834
  runWithProjectBinding: () => runWithProjectBinding,
@@ -9344,8 +9345,14 @@ function languageOfSourcePath(sourcePath) {
9344
9345
  function dialectOf(facts) {
9345
9346
  return facts.language ? typeDialectFor(facts.language) : null;
9346
9347
  }
9347
- function resolveImport(fromFile, specifier, knownPaths) {
9348
- if (!specifier.startsWith(".")) return void 0;
9348
+ function returnTypeOf(facts, fn) {
9349
+ return ownEntry(facts.returnTypes, fn);
9350
+ }
9351
+ function resolveImport(fromFile, specifier, knownPaths, packages) {
9352
+ if (!specifier.startsWith(".")) {
9353
+ const mapped = ownEntry(packages, specifier);
9354
+ return mapped !== void 0 && knownPaths.has(mapped) ? mapped : void 0;
9355
+ }
9349
9356
  const joined = pathKey(path9.posix.normalize(path9.posix.join(path9.posix.dirname(fromFile), specifier)));
9350
9357
  const candidates = [
9351
9358
  joined,
@@ -15754,7 +15761,7 @@ function defaultTargetConfig(type) {
15754
15761
  enabled: true
15755
15762
  };
15756
15763
  }
15757
- var WAIRON_VERSION = "5.1.1-dev.100";
15764
+ var WAIRON_VERSION = "5.1.1-dev.101";
15758
15765
  var GITHUB_REPO = "SYW-Apps/Waffle-AIron";
15759
15766
  var ARCHITECT_AGENT_ID = "agent-architect";
15760
15767
  var ARCHITECT_TEMPLATE_ID = "architect";
@@ -17666,12 +17673,12 @@ function packFiles(dir, prefix = "") {
17666
17673
  function computePackDigest(packDir) {
17667
17674
  const hash = crypto3.createHash("sha256");
17668
17675
  const abs = path16.resolve(packDir);
17669
- let isFile = false;
17676
+ let isFile2 = false;
17670
17677
  try {
17671
- isFile = fs11.statSync(abs).isFile();
17678
+ isFile2 = fs11.statSync(abs).isFile();
17672
17679
  } catch {
17673
17680
  }
17674
- const entries = isFile ? [[path16.basename(abs), abs]] : packFiles(abs).map((rel2) => [rel2, path16.join(abs, rel2)]);
17681
+ const entries = isFile2 ? [[path16.basename(abs), abs]] : packFiles(abs).map((rel2) => [rel2, path16.join(abs, rel2)]);
17675
17682
  for (const [rel2, full] of entries) {
17676
17683
  hash.update(rel2);
17677
17684
  hash.update("\0");
@@ -18355,6 +18362,7 @@ function appendUnique(map, key, value, same) {
18355
18362
  list.push(value);
18356
18363
  }
18357
18364
  function buildCodeIndex(model) {
18365
+ const packages = model.packages ?? {};
18358
18366
  const facts = /* @__PURE__ */ new Map();
18359
18367
  const paths = /* @__PURE__ */ new Set();
18360
18368
  const exactPaths = /* @__PURE__ */ new Set();
@@ -18387,7 +18395,7 @@ function buildCodeIndex(model) {
18387
18395
  const f = facts.get(from);
18388
18396
  if (f?.status !== "analyzed") continue;
18389
18397
  for (const specifier of f.reexports) {
18390
- const to = resolveImport(from, specifier, paths);
18398
+ const to = resolveImport(from, specifier, paths, packages);
18391
18399
  if (to && !out.has(to)) {
18392
18400
  out.add(to);
18393
18401
  queue.push(to);
@@ -18399,7 +18407,7 @@ function buildCodeIndex(model) {
18399
18407
  };
18400
18408
  const NO_ORIGIN = /* @__PURE__ */ new Set();
18401
18409
  const landingFrom = (scope, specifier) => {
18402
- const to = resolveImport(scope, specifier, paths);
18410
+ const to = resolveImport(scope, specifier, paths, packages);
18403
18411
  return to ? republishedFrom(to) : NO_ORIGIN;
18404
18412
  };
18405
18413
  const scopeOf2 = (site, from) => {
@@ -18429,7 +18437,7 @@ function buildCodeIndex(model) {
18429
18437
  };
18430
18438
  const possibleOriginsOf = (site, from) => {
18431
18439
  const proven = originOf2(site, from);
18432
- if (!site.field && !site.constructed && !site.via) return proven;
18440
+ if (!site.field && !site.constructed && !site.via && !site.returnedBy && !site.enclosingClass) return proven;
18433
18441
  const resolved = scopeOf2(site, from);
18434
18442
  if (!resolved) return proven;
18435
18443
  const { path: scope, facts: f } = resolved;
@@ -18442,24 +18450,59 @@ function buildCodeIndex(model) {
18442
18450
  if (site.field) for (const typeName of fieldTypesOf(f, site.field)) widenThroughType(typeName);
18443
18451
  if (site.constructed) widenThrough(site.constructed, importBindingOf(f, site.constructed)?.from);
18444
18452
  if (site.via) for (const typeName of localTypesOf(f, site.via)) widenThroughType(typeName);
18453
+ if (site.enclosingClass !== void 0 && holdsMemberBody(f, site.name, site.enclosingClass)) {
18454
+ for (const candidate of republishedFrom(scope)) out.add(candidate);
18455
+ }
18456
+ if (site.returnedBy !== void 0) {
18457
+ for (const fnFile of originOf2({ name: site.returnedBy, member: false }, scope)) {
18458
+ const at = facts.get(fnFile);
18459
+ if (at?.status !== "analyzed" || at.analysisGrade !== "exact") continue;
18460
+ const typeName = returnTypeOf(at, site.returnedBy);
18461
+ if (typeName === void 0) continue;
18462
+ const specifier = typeBindingOf(at, typeName);
18463
+ const landings = specifier !== void 0 ? landingFrom(fnFile, specifier) : declarationsAt(fnFile).has(typeName) ? republishedFrom(fnFile) : NO_ORIGIN;
18464
+ for (const candidate of landings) {
18465
+ const there = facts.get(candidate);
18466
+ if (there && holdsMemberBody(there, site.name, typeName)) out.add(candidate);
18467
+ }
18468
+ }
18469
+ }
18445
18470
  return out;
18446
18471
  };
18472
+ const holdsMemberBody = (f, name, container) => f.status === "analyzed" && f.analysisGrade === "exact" && !!f.functionBodies && Object.prototype.hasOwnProperty.call(f.functionBodies, name) && f.functionBodies[name].some((b) => b.container === container);
18447
18473
  const declarationsAt = (path49) => namesAt(declarations, pathKey(path49), (f) => /* @__PURE__ */ new Set([...f.declaredNames, ...f.exportedNames]));
18448
- const forwardsOf = (start, name) => {
18474
+ const forwardsOf = (start, name, container) => {
18449
18475
  const out = [];
18476
+ const listed = /* @__PURE__ */ new Set();
18450
18477
  const seen = /* @__PURE__ */ new Set();
18451
- const queue = [{ file: pathKey(start), name }];
18478
+ const queue = [{ file: pathKey(start), name, container }];
18452
18479
  while (queue.length) {
18453
18480
  const at = queue.shift();
18454
- const key = `${at.file}#${at.name}`;
18481
+ const key = `${at.scope ? "s" : "p"}|${at.container ?? ""}|${at.file}#${at.name}`;
18455
18482
  if (seen.has(key)) continue;
18456
18483
  seen.add(key);
18457
- out.push(at);
18458
- for (const binding of facts.get(at.file)?.reexportBindings ?? []) {
18484
+ if (!listed.has(`${at.file}#${at.name}`)) {
18485
+ listed.add(`${at.file}#${at.name}`);
18486
+ out.push({ file: at.file, name: at.name });
18487
+ }
18488
+ const f = facts.get(at.file);
18489
+ if (at.scope) {
18490
+ const binding = f ? importBindingOf(f, at.name) : void 0;
18491
+ if (!binding || binding.namespace) continue;
18492
+ const to = resolveImport(at.file, binding.from, paths, packages);
18493
+ if (to) queue.push({ file: to, name: binding.imported ?? at.name });
18494
+ continue;
18495
+ }
18496
+ for (const alias of f?.exportAliases ?? []) {
18497
+ if (alias.exported !== at.name || alias.container !== at.container) continue;
18498
+ queue.push({ file: at.file, name: alias.local, scope: true });
18499
+ }
18500
+ if (at.container !== void 0) continue;
18501
+ for (const binding of f?.reexportBindings ?? []) {
18459
18502
  const star = binding.exported === "*";
18460
18503
  if (!star && binding.exported !== at.name) continue;
18461
18504
  if (star && at.name === "default") continue;
18462
- const to = resolveImport(at.file, binding.from, paths);
18505
+ const to = resolveImport(at.file, binding.from, paths, packages);
18463
18506
  if (!to) continue;
18464
18507
  if (star && !facts.get(to)?.exportedNames.includes(at.name)) continue;
18465
18508
  queue.push({ file: to, name: star ? at.name : binding.local });
@@ -18470,6 +18513,7 @@ function buildCodeIndex(model) {
18470
18513
  return {
18471
18514
  paths,
18472
18515
  exactPaths,
18516
+ packages,
18473
18517
  factsAt: (path49) => facts.get(pathKey(path49)),
18474
18518
  declarationsAt,
18475
18519
  anchorsAt: (path49) => namesAt(anchors, pathKey(path49), (f) => /* @__PURE__ */ new Set([...f.declaredNames, ...f.exportedNames, ...f.anchoredNames])),
@@ -18523,7 +18567,7 @@ function buildImportGraph(index, universe) {
18523
18567
  const traces = /* @__PURE__ */ new Map();
18524
18568
  const resolveAll = (from, specifiers, into) => {
18525
18569
  for (const specifier of specifiers) {
18526
- const to = resolveImport(from, specifier, universe);
18570
+ const to = resolveImport(from, specifier, universe, index.packages);
18527
18571
  if (to && to !== from) into.add(to);
18528
18572
  }
18529
18573
  };
@@ -23741,13 +23785,13 @@ function invokedAs(code, site, file) {
23741
23785
  if (!site.member) {
23742
23786
  const binding = importBindingOf(facts, site.name);
23743
23787
  if (!binding || binding.namespace) return [];
23744
- const module3 = resolveImport(scope, binding.from, code.paths);
23788
+ const module3 = resolveImport(scope, binding.from, code.paths, code.packages);
23745
23789
  return module3 ? code.forwardsOf(module3, binding.imported ?? site.name) : [];
23746
23790
  }
23747
23791
  if (!site.via) return [];
23748
23792
  const receiver = importBindingOf(facts, site.via);
23749
23793
  if (!receiver?.namespace) return [];
23750
- const module2 = resolveImport(scope, receiver.from, code.paths);
23794
+ const module2 = resolveImport(scope, receiver.from, code.paths, code.packages);
23751
23795
  return module2 ? code.forwardsOf(module2, site.name) : [];
23752
23796
  }
23753
23797
  function claimsOf(implMethod) {
@@ -23769,6 +23813,8 @@ function describeSite(site) {
23769
23813
  if (site.via) return `${site.via}.${site.name}(\u2026)`;
23770
23814
  if (site.field) return `this.${site.field}.${site.name}(\u2026)`;
23771
23815
  if (site.constructed) return `new ${site.constructed}(\u2026).${site.name}(\u2026)`;
23816
+ if (site.returnedBy) return `${site.returnedBy}(\u2026).${site.name}(\u2026)`;
23817
+ if (site.enclosingClass) return `this.${site.name}(\u2026)`;
23772
23818
  return `<receiver>.${site.name}(\u2026)`;
23773
23819
  }
23774
23820
  function describeMiss(m) {
@@ -23781,7 +23827,7 @@ function describeMiss(m) {
23781
23827
  var callConformanceRule = {
23782
23828
  name: "call-conformance",
23783
23829
  judges: "code",
23784
- description: "Code\u2194spec Level 3: the CLAIMED call \u2194 realized call relation, judged both ways against the method's own source file (its sourcePath, else the implementation's), at exact analysis grade only. A method claims a call two ways and they face one check: a narrative `call` step, and an entry of the declared `calls` a narrative-less method reaches its collaborators through. They assert the same thing, and the step number is no part of the claim \u2014 this check never reads order, so it is only how a finding points at one. Forward: every claim must be realized by a call whose callee RESOLVES TO one of the target method's own source files \u2014 the target's contract name or a per-method `symbol` override, closed transitively over the named helpers the realized function calls, and resolved against every file the call CAN have reached: a `this.<field>.<method>()` receiver followed through the field's DECLARED TYPE, a `new Class(...).<method>()` receiver through the module its CLASS NAME came from, and a plain `<name>.<method>()` receiver through the type the file ANNOTATES that name with \u2014 a parameter's, or an annotated variable's, which is how a module that wires its collaborators as closures writes every one of its calls. A matching call whose origin a pure model cannot resolve is reported apart as CALL_ORIGIN_UNRESOLVED, which NAMES the shape it could not follow and asks for nothing \u2014 a coverage hole in the reader, reported for the reason CONFORMANCE_DEGRADED is: a silently degraded gate is worse than a degraded one. A finding names a landing only from the PROVEN tier so that widening what a call reached can accept a claim but never accuse one, and a target that names no file of its own falls back to name membership. Converse: a call that resolves to a modelled method of ANOTHER component in the SAME file crosses a component boundary while looking local, so the method must claim it \u2014 in a step or in `calls` (UNDECLARED_COLOCATED_CALL) \u2014 judged on the proven tier alone, and a same-file private helper is no modelled method and is never reported. A method that claims nothing at all is judged in neither direction: what it leaves unsaid is UNUSED_*'s subject. Order, arguments and conditions stay unverified, dispatch steps (runtime-table routed) are no claim about a call site, a malformed declared reference is MALFORMED_DECLARED_CALL's finding and names no target here, the conformance dial (off) skips, and weaker analysis grades never guess.",
23830
+ description: "Code\u2194spec Level 3: the CLAIMED call \u2194 realized call relation, judged both ways against the method's own source file (its sourcePath, else the implementation's), at exact analysis grade only. A method claims a call two ways and they face one check: a narrative `call` step, and an entry of the declared `calls` a narrative-less method reaches its collaborators through. They assert the same thing, and the step number is no part of the claim \u2014 this check never reads order, so it is only how a finding points at one. Forward: every claim must be realized by a call whose callee RESOLVES TO one of the target method's own source files \u2014 the target's contract name or a per-method `symbol` override, closed transitively over the named helpers the realized function calls, and resolved against every file the call CAN have reached: a `this.<field>.<method>()` receiver followed through the field's DECLARED TYPE, a `new Class(...).<method>()` receiver through the module its CLASS NAME came from, a plain `<name>.<method>()` receiver through the type the file ANNOTATES that name with \u2014 a parameter's, or an annotated variable's, which is how a module that wires its collaborators as closures writes every one of its calls \u2014 a `fn(...).<method>()` receiver through the type fn RETURNS where the code settles it, and a `this.<method>()` receiver through the class whose own method it sits in; a package specifier naming a package of this repository resolves like a relative one, and an export alias (`export { a as b }`, an adapter object property `{ b: a }`) forwards by identity like a re-export. A matching call whose origin a pure model cannot resolve is reported apart as CALL_ORIGIN_UNRESOLVED, which NAMES the shape it could not follow and asks for nothing \u2014 a coverage hole in the reader, reported for the reason CONFORMANCE_DEGRADED is: a silently degraded gate is worse than a degraded one. A finding names a landing only from the PROVEN tier so that widening what a call reached can accept a claim but never accuse one, and a target that names no file of its own falls back to name membership. Converse: a call that resolves to a modelled method of ANOTHER component in the SAME file crosses a component boundary while looking local, so the method must claim it \u2014 in a step or in `calls` (UNDECLARED_COLOCATED_CALL) \u2014 judged on the proven tier alone, and a same-file private helper is no modelled method and is never reported; a function forwarding by identity to a modelled method written in another file IS that method, so what it calls is that method's subject. A method that claims nothing at all is judged in neither direction: what it leaves unsaid is UNUSED_*'s subject. Order, arguments and conditions stay unverified, dispatch steps (runtime-table routed) are no claim about a call site, a malformed declared reference is MALFORMED_DECLARED_CALL's finding and names no target here, the conformance dial (off) skips, and weaker analysis grades never guess.",
23785
23831
  codes: [
23786
23832
  { code: "CALL_STEP_UNREALIZED", defaultSeverity: "warning", summary: "Narrative call step or declared call realized by no call that resolves to the target method's own source file \u2014 the call is absent, or it lands in another module", carryable: true },
23787
23833
  { code: "CALL_ORIGIN_UNRESOLVED", defaultSeverity: "warning", summary: "Narrative call step or declared call whose target name IS called, but only from call sites written in a shape this analysis cannot resolve to a file \u2014 the claim was not checked, and is neither proven realized nor accused", carryable: true },
@@ -23824,7 +23870,7 @@ var callConformanceRule = {
23824
23870
  if (!ctx.componentMap.has(claim.component)) continue;
23825
23871
  const target = resolveCallTarget(ctx, claim.component, claim.method);
23826
23872
  if (target.accepted.has(fnSymbol)) continue;
23827
- if (isTarget(code.forwardsOf(file, fnSymbol), target)) continue;
23873
+ if (isTarget(code.forwardsOf(file, fnSymbol, implMethod.exportedVia), target)) continue;
23828
23874
  const matching = sites.filter((s) => target.accepted.has(s.name));
23829
23875
  const ref = `${claim.component}.${claim.method}`;
23830
23876
  if (target.files.size === 0) {
@@ -23867,7 +23913,7 @@ var callConformanceRule = {
23867
23913
  ctx.addIssue(
23868
23914
  "warning",
23869
23915
  "CALL_ORIGIN_UNRESOLVED",
23870
- `Method "${implMethod.name}" in implementation "${impl.id}": ${unresolved.length} ${claimNoun(implMethod)} ARE called by name inside the function "${fnSymbol}" in "${file}", but every site calling them is written in a shape this analysis cannot resolve to a file \u2014 ${unresolved.map(describeMiss).join("; ")}. What resolves is a name bound to a module of THIS project: a bare or namespaced call through such an import binding, a \`this.<field>\` receiver whose declared type names one, a \`new Class(\u2026)\` receiver whose class does, and a receiver NAME the file annotates with a type that does. What does not: an import from a PACKAGE specifier, a receiver holding a value the module assembled, a receiver this model records no name for, and one the file annotates with nothing. This reports what was not checked, not what is wrong \u2014 the claim is neither proven realized nor accused of being missing, and no working call is asked to be rewritten to suit the reader.`,
23916
+ `Method "${implMethod.name}" in implementation "${impl.id}": ${unresolved.length} ${claimNoun(implMethod)} ARE called by name inside the function "${fnSymbol}" in "${file}", but every site calling them is written in a shape this analysis cannot resolve to a file \u2014 ${unresolved.map(describeMiss).join("; ")}. What resolves is a name bound to a module of THIS project: a bare or namespaced call through such an import binding (a package of this repository included), a \`this.<field>\` receiver whose declared type names one, a \`new Class(\u2026)\` receiver whose class does, a receiver NAME the file annotates with a type that does, a \`fn(\u2026)\` receiver whose function's return the code settles on a type with that method's body, and \`this\` inside a class's own method that has it. What does not: an import from a third-party PACKAGE, a receiver holding a value the module assembled, a receiver this model records no name for, and one the file annotates with nothing. This reports what was not checked, not what is wrong \u2014 the claim is neither proven realized nor accused of being missing, and no working call is asked to be rewritten to suit the reader.`,
23871
23917
  impl.id,
23872
23918
  entry.draftContext,
23873
23919
  void 0,
@@ -23889,7 +23935,9 @@ var callConformanceRule = {
23889
23935
  reached.set(site, owner);
23890
23936
  return owner !== void 0;
23891
23937
  };
23892
- for (const site of closedCallSites(code, file, fnSymbol, stopAtModelled, implMethod.exportedVia) ?? []) {
23938
+ const forwardsToModelled = code.forwardsOf(file, fnSymbol, implMethod.exportedVia).some((p) => p.file !== here && modelledAt.get(p.file)?.byName.has(p.name));
23939
+ const conversed = forwardsToModelled ? [] : closedCallSites(code, file, fnSymbol, stopAtModelled, implMethod.exportedVia) ?? [];
23940
+ for (const site of conversed) {
23893
23941
  const owner = reached.get(site);
23894
23942
  if (!owner || owner.component === component.id) continue;
23895
23943
  const ref = `${owner.component}.${owner.method}`;
@@ -25077,7 +25125,7 @@ var exportConformanceRule = {
25077
25125
  const facts = code.factsAt(file);
25078
25126
  if (!facts || facts.status !== "analyzed" || facts.analysisGrade !== "exact") continue;
25079
25127
  for (const binding of facts.reexportBindings ?? []) {
25080
- const target = resolveImport(file, binding.from, code.paths);
25128
+ const target = resolveImport(file, binding.from, code.paths, code.packages);
25081
25129
  const methods = target ? typeMethodsAt.get(target) : void 0;
25082
25130
  if (!methods) continue;
25083
25131
  if (binding.local === "*") {
@@ -25089,7 +25137,7 @@ var exportConformanceRule = {
25089
25137
  }
25090
25138
  const takenFrom = /* @__PURE__ */ new Map();
25091
25139
  const take = (consumer, writtenIn, specifier, names) => {
25092
- const target = resolveImport(writtenIn, specifier, code.paths);
25140
+ const target = resolveImport(writtenIn, specifier, code.paths, code.packages);
25093
25141
  if (!target) return;
25094
25142
  let byName = takenFrom.get(target);
25095
25143
  if (!byName) takenFrom.set(target, byName = /* @__PURE__ */ new Map());
@@ -26823,6 +26871,9 @@ function walkExact(ts, sourceText, fileName) {
26823
26871
  const reexports = /* @__PURE__ */ new Set();
26824
26872
  const starExports = [];
26825
26873
  const namedReexports = [];
26874
+ const exportAliases = [];
26875
+ const propertyAliases = [];
26876
+ const returnTypes = /* @__PURE__ */ new Map();
26826
26877
  const complexity = /* @__PURE__ */ new Map();
26827
26878
  const calls = /* @__PURE__ */ new Map();
26828
26879
  const bodies = /* @__PURE__ */ new Map();
@@ -26839,7 +26890,7 @@ function walkExact(ts, sourceText, fileName) {
26839
26890
  const mutableBindings = /* @__PURE__ */ new Set();
26840
26891
  const schemaConstants = /* @__PURE__ */ new Map();
26841
26892
  const derivedAliases = [];
26842
- const receiverKey = (site) => site.via ?? (site.field ? `this.${site.field}` : site.constructed ? `new ${site.constructed}` : "");
26893
+ const receiverKey = (site) => site.via ?? (site.field ? `this.${site.field}` : site.constructed ? `new ${site.constructed}` : site.returnedBy ? `${site.returnedBy}()` : site.enclosingClass ? `this:${site.enclosingClass}` : "");
26843
26894
  const siteKey = (site) => `${site.member ? "m" : "b"}:${receiverKey(site)}:${site.name}`;
26844
26895
  const addBindingNames = (name) => {
26845
26896
  if (ts.isIdentifier(name)) declared.add(name.text);
@@ -26947,6 +26998,44 @@ function walkExact(ts, sourceText, fileName) {
26947
26998
  }
26948
26999
  return void 0;
26949
27000
  };
27001
+ const enclosingClassOf = (node) => {
27002
+ let at = node.parent;
27003
+ while (at) {
27004
+ if (ts.isFunctionExpression(at) || ts.isFunctionDeclaration(at) || ts.isClassExpression(at)) return void 0;
27005
+ if ((ts.isMethodDeclaration(at) || ts.isGetAccessorDeclaration(at) || ts.isSetAccessorDeclaration(at)) && at.parent && ts.isObjectLiteralExpression(at.parent)) return void 0;
27006
+ if (ts.isClassDeclaration(at)) {
27007
+ return at.name && at.parent && ts.isSourceFile(at.parent) ? at.name.text : void 0;
27008
+ }
27009
+ at = at.parent;
27010
+ }
27011
+ return void 0;
27012
+ };
27013
+ const returnedTypeOf = (fn) => {
27014
+ const annotated = fn.type;
27015
+ if (annotated) {
27016
+ if (!ts.isTypeReferenceNode(annotated)) return void 0;
27017
+ if (ts.isIdentifier(annotated.typeName) && annotated.typeName.text === "Promise" && annotated.typeArguments?.length === 1) {
27018
+ const inner2 = annotated.typeArguments[0];
27019
+ return ts.isTypeReferenceNode(inner2) && !inner2.typeArguments ? typeReferenceName(inner2) : void 0;
27020
+ }
27021
+ return annotated.typeArguments ? void 0 : typeReferenceName(annotated);
27022
+ }
27023
+ const constructedClass = (expression) => {
27024
+ let node = expression;
27025
+ while (node && (ts.isParenthesizedExpression(node) || ts.isAsExpression(node) || ts.isSatisfiesExpression(node))) node = node.expression;
27026
+ return node && ts.isNewExpression(node) && ts.isIdentifier(node.expression) ? node.expression.text : void 0;
27027
+ };
27028
+ if (!fn.body) return void 0;
27029
+ if (!ts.isBlock(fn.body)) return constructedClass(fn.body);
27030
+ const returns = [];
27031
+ const collect = (node) => {
27032
+ if (ts.isFunctionLike(node)) return;
27033
+ if (ts.isReturnStatement(node)) returns.push(node);
27034
+ ts.forEachChild(node, collect);
27035
+ };
27036
+ ts.forEachChild(fn.body, collect);
27037
+ return returns.length === 1 ? constructedClass(returns[0].expression) : void 0;
27038
+ };
26950
27039
  const isTopLevelVariable = (decl) => ts.isVariableDeclaration(decl) && ts.isIdentifier(decl.name) && !!decl.parent && ts.isVariableDeclarationList(decl.parent) && !!decl.parent.parent && ts.isVariableStatement(decl.parent.parent) && !!decl.parent.parent.parent && ts.isSourceFile(decl.parent.parent.parent);
26951
27040
  const containerOf = (owner) => {
26952
27041
  if (!owner) return void 0;
@@ -27008,6 +27097,11 @@ function walkExact(ts, sourceText, fileName) {
27008
27097
  addSite({ name, member: true, field: receiver.name.text });
27009
27098
  } else if (ts.isNewExpression(receiver) && ts.isIdentifier(receiver.expression)) {
27010
27099
  addSite({ name, member: true, constructed: receiver.expression.text });
27100
+ } else if (ts.isCallExpression(receiver) && ts.isIdentifier(receiver.expression)) {
27101
+ addSite({ name, member: true, returnedBy: receiver.expression.text });
27102
+ } else if (receiver.kind === ts.SyntaxKind.ThisKeyword) {
27103
+ const owner = enclosingClassOf(node);
27104
+ addSite(owner !== void 0 ? { name, member: true, enclosingClass: owner } : { name, member: true });
27011
27105
  } else addSite({ name, member: true });
27012
27106
  }
27013
27107
  }
@@ -27134,6 +27228,8 @@ function walkExact(ts, sourceText, fileName) {
27134
27228
  signatures.push(declaredParameters(node));
27135
27229
  functionParams.set(fnName, signatures);
27136
27230
  if (completesLater(node)) asyncFunctions.push(fnName);
27231
+ const returned = returnedTypeOf(node) ?? null;
27232
+ returnTypes.set(fnName, returnTypes.has(fnName) && returnTypes.get(fnName) !== returned ? null : returned);
27137
27233
  const routes = collectRoutes(node);
27138
27234
  if (routes.size > 0) {
27139
27235
  const known = functionRoutes.get(fnName) ?? /* @__PURE__ */ new Map();
@@ -27170,6 +27266,23 @@ function walkExact(ts, sourceText, fileName) {
27170
27266
  if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.initializer && !schemaConstants.has(node.name.text)) {
27171
27267
  schemaConstants.set(node.name.text, node.initializer);
27172
27268
  }
27269
+ if (isTopLevelVariable(node) && node.initializer) {
27270
+ let literal = node.initializer;
27271
+ while (ts.isAsExpression(literal) || ts.isSatisfiesExpression(literal) || ts.isParenthesizedExpression(literal)) {
27272
+ literal = literal.expression;
27273
+ }
27274
+ if (ts.isObjectLiteralExpression(literal)) {
27275
+ const container = node.name.text;
27276
+ for (const property of literal.properties) {
27277
+ if (ts.isShorthandPropertyAssignment(property)) {
27278
+ propertyAliases.push({ exported: property.name.text, local: property.name.text, container });
27279
+ } else if (ts.isPropertyAssignment(property) && ts.isIdentifier(property.initializer)) {
27280
+ const key = propertyNameText(property.name);
27281
+ if (key) propertyAliases.push({ exported: key, local: property.initializer.text, container });
27282
+ }
27283
+ }
27284
+ }
27285
+ }
27173
27286
  if (ts.isFunctionDeclaration(node) || ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node) || ts.isEnumDeclaration(node) || ts.isModuleDeclaration(node)) {
27174
27287
  const name = node.name && ts.isIdentifier(node.name) ? node.name.text : void 0;
27175
27288
  if (name) {
@@ -27221,9 +27334,10 @@ function walkExact(ts, sourceText, fileName) {
27221
27334
  for (const el of node.exportClause.elements) {
27222
27335
  declared.add(el.name.text);
27223
27336
  exported.add(el.name.text);
27224
- if (spec && !node.isTypeOnly && !el.isTypeOnly) {
27225
- namedReexports.push({ exported: el.name.text, local: (el.propertyName ?? el.name).text, from: spec });
27226
- }
27337
+ if (node.isTypeOnly || el.isTypeOnly) continue;
27338
+ const local = (el.propertyName ?? el.name).text;
27339
+ if (spec) namedReexports.push({ exported: el.name.text, local, from: spec });
27340
+ else exportAliases.push({ exported: el.name.text, local });
27227
27341
  }
27228
27342
  } else if (!node.exportClause && spec) {
27229
27343
  starExports.push(spec);
@@ -27298,7 +27412,13 @@ function walkExact(ts, sourceText, fileName) {
27298
27412
  if (values && schemaConstants.has(alias.constant)) enumValues.set(alias.name, values);
27299
27413
  }
27300
27414
  const reexportOnly = sf.statements.length > 0 && sf.statements.every((st) => ts.isExportDeclaration(st) && !!st.moduleSpecifier);
27301
- return { declared, anchors, exported, imports, reexports, starExports, namedReexports, complexity, calls, bodies, importBindings, typeOnlyBindings, fieldTypes, localTypes, typeShapes, functionParams, functionRoutes, asyncFunctions, enumValues, aliasTypes, mutableBindings, reexportOnly };
27415
+ for (const alias of propertyAliases) if (exported.has(alias.container)) exportAliases.push(alias);
27416
+ return { declared, anchors, exported, imports, reexports, starExports, namedReexports, exportAliases, returnTypes, complexity, calls, bodies, importBindings, typeOnlyBindings, fieldTypes, localTypes, typeShapes, functionParams, functionRoutes, asyncFunctions, enumValues, aliasTypes, mutableBindings, reexportOnly };
27417
+ }
27418
+ var NO_PACKAGES = /* @__PURE__ */ new Map();
27419
+ function resolveModule(fromFile, specifier, packages) {
27420
+ if (!specifier.startsWith(".")) return packages.get(specifier) ?? null;
27421
+ return resolveRelativeModule(fromFile, specifier);
27302
27422
  }
27303
27423
  function resolveRelativeModule(fromFile, specifier) {
27304
27424
  if (!specifier.startsWith(".")) return null;
@@ -27321,8 +27441,8 @@ function resolveRelativeModule(fromFile, specifier) {
27321
27441
  }
27322
27442
  return null;
27323
27443
  }
27324
- function reexportTarget(ts, filePath, specifier, projectRoot, visited, exactCache) {
27325
- const target = resolveRelativeModule(filePath, specifier);
27444
+ function reexportTarget(ts, filePath, specifier, projectRoot, visited, exactCache, packages) {
27445
+ const target = resolveModule(filePath, specifier, packages);
27326
27446
  if (!target || path18.relative(projectRoot, target).startsWith("..")) return null;
27327
27447
  let targetFacts = exactCache.get(target);
27328
27448
  if (targetFacts === void 0) {
@@ -27336,7 +27456,7 @@ function reexportTarget(ts, filePath, specifier, projectRoot, visited, exactCach
27336
27456
  if (!targetFacts) return null;
27337
27457
  if (!visited.has(target)) {
27338
27458
  visited.add(target);
27339
- chaseReexports(ts, targetFacts, target, projectRoot, visited, exactCache);
27459
+ chaseReexports(ts, targetFacts, target, projectRoot, visited, exactCache, packages);
27340
27460
  }
27341
27461
  return { path: target, facts: targetFacts };
27342
27462
  }
@@ -27359,13 +27479,33 @@ function carryBody(facts, target, targetPath, local, exported, projectRoot) {
27359
27479
  }
27360
27480
  facts.bodies.set(exported, carried);
27361
27481
  }
27362
- function chaseReexports(ts, facts, filePath, projectRoot, visited, exactCache) {
27482
+ function carryAliasBody(facts, source, from, local, alias) {
27483
+ const sourceBodies = source.bodies.get(local) ?? [];
27484
+ if (!sourceBodies.length || sourceBodies.some((b) => b.nested)) return;
27485
+ const moduleScope = sourceBodies.filter((b) => b.container === void 0);
27486
+ if (!moduleScope.length) return;
27487
+ const score = source.complexity.get(local);
27488
+ if (score !== void 0) {
27489
+ facts.complexity.set(alias.exported, Math.max(facts.complexity.get(alias.exported) ?? 0, score));
27490
+ }
27491
+ const relocate2 = (site) => from !== void 0 ? { ...site, from: site.from ?? from } : site;
27492
+ const sites = facts.calls.get(alias.exported) ?? /* @__PURE__ */ new Map();
27493
+ const carried = facts.bodies.get(alias.exported) ?? [];
27494
+ for (const body of moduleScope) {
27495
+ const moved = body.sites.map(relocate2);
27496
+ for (const site of moved) sites.set(`${from ?? ""}|${alias.container ?? ""}|${JSON.stringify(site)}`, site);
27497
+ carried.push(alias.container !== void 0 ? { container: alias.container, sites: moved } : { sites: moved });
27498
+ }
27499
+ facts.calls.set(alias.exported, sites);
27500
+ facts.bodies.set(alias.exported, carried);
27501
+ }
27502
+ function chaseReexports(ts, facts, filePath, projectRoot, visited, exactCache, packages = NO_PACKAGES) {
27363
27503
  for (const re of facts.namedReexports) {
27364
- const target = reexportTarget(ts, filePath, re.from, projectRoot, visited, exactCache);
27504
+ const target = reexportTarget(ts, filePath, re.from, projectRoot, visited, exactCache, packages);
27365
27505
  if (target) carryBody(facts, target.facts, target.path, re.local, re.exported, projectRoot);
27366
27506
  }
27367
27507
  for (const spec of facts.starExports) {
27368
- const target = reexportTarget(ts, filePath, spec, projectRoot, visited, exactCache);
27508
+ const target = reexportTarget(ts, filePath, spec, projectRoot, visited, exactCache, packages);
27369
27509
  if (!target) continue;
27370
27510
  for (const name of target.facts.exported) {
27371
27511
  facts.exported.add(name);
@@ -27373,6 +27513,150 @@ function chaseReexports(ts, facts, filePath, projectRoot, visited, exactCache) {
27373
27513
  carryBody(facts, target.facts, target.path, name, name, projectRoot);
27374
27514
  }
27375
27515
  }
27516
+ for (const alias of facts.exportAliases) {
27517
+ const binding = facts.importBindings.get(alias.local);
27518
+ if (binding) {
27519
+ if (binding.namespace) continue;
27520
+ const target = reexportTarget(ts, filePath, binding.from, projectRoot, visited, exactCache, packages);
27521
+ if (!target) continue;
27522
+ const from = pathKey(path18.relative(projectRoot, target.path));
27523
+ carryAliasBody(facts, target.facts, from, binding.imported ?? alias.local, alias);
27524
+ } else if (alias.container !== void 0 || alias.local !== alias.exported) {
27525
+ carryAliasBody(facts, facts, void 0, alias.local, alias);
27526
+ }
27527
+ }
27528
+ }
27529
+ var BUILD_EXTENSIONS = [".d.mts", ".d.cts", ".d.ts", ".mjs", ".cjs", ".jsx", ".js"];
27530
+ var SOURCE_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
27531
+ var ENTRY_CONDITIONS = ["types", "import", "require", "default"];
27532
+ function isOwnFile(projectRoot, absolute) {
27533
+ const rel2 = path18.relative(projectRoot, absolute);
27534
+ if (rel2.startsWith("..") || path18.isAbsolute(rel2)) return false;
27535
+ return !pathKey(rel2).split("/").includes("node_modules");
27536
+ }
27537
+ function isFile(absolute) {
27538
+ try {
27539
+ return fs13.statSync(absolute).isFile();
27540
+ } catch {
27541
+ return false;
27542
+ }
27543
+ }
27544
+ function readJsonFile2(file, ts) {
27545
+ let text3;
27546
+ try {
27547
+ text3 = fs13.readFileSync(file, "utf8");
27548
+ } catch {
27549
+ return void 0;
27550
+ }
27551
+ try {
27552
+ return JSON.parse(text3);
27553
+ } catch {
27554
+ if (!ts) return void 0;
27555
+ const parsed = ts.parseConfigFileTextToJson(file, text3);
27556
+ return parsed.error ? void 0 : parsed.config;
27557
+ }
27558
+ }
27559
+ function conditionTargets(value) {
27560
+ if (typeof value === "string") return [value];
27561
+ if (!value || typeof value !== "object" || Array.isArray(value)) return [];
27562
+ const record = value;
27563
+ const keys = [...ENTRY_CONDITIONS.filter((k) => k in record), ...Object.keys(record).filter((k) => !ENTRY_CONDITIONS.includes(k))];
27564
+ return keys.flatMap((k) => conditionTargets(record[k]));
27565
+ }
27566
+ function packageEntries(pkg) {
27567
+ const entries = /* @__PURE__ */ new Map();
27568
+ const exportsField = pkg.exports;
27569
+ if (exportsField !== void 0 && exportsField !== null) {
27570
+ const isSubpathMap = typeof exportsField === "object" && !Array.isArray(exportsField) && Object.keys(exportsField).some((k) => k.startsWith("."));
27571
+ if (isSubpathMap) {
27572
+ for (const [subpath, value] of Object.entries(exportsField)) {
27573
+ if (!subpath.startsWith(".") || subpath.includes("*")) continue;
27574
+ const targets = conditionTargets(value);
27575
+ if (targets.length) entries.set(subpath, targets);
27576
+ }
27577
+ } else {
27578
+ const targets = conditionTargets(exportsField);
27579
+ if (targets.length) entries.set(".", targets);
27580
+ }
27581
+ return entries;
27582
+ }
27583
+ const fallbacks = ["module", "main", "types"].map((k) => pkg[k]).filter((v) => typeof v === "string");
27584
+ if (fallbacks.length) entries.set(".", fallbacks);
27585
+ return entries;
27586
+ }
27587
+ function entrySource(packageDir, target, compiler, projectRoot) {
27588
+ const absolute = path18.resolve(packageDir, target);
27589
+ if (!isOwnFile(projectRoot, absolute)) return null;
27590
+ const isDeclaration = /\.d\.[cm]?ts$/.test(absolute);
27591
+ if (!isDeclaration && languageOfSourcePath(absolute) && isFile(absolute) && !(compiler.outDir && !path18.relative(compiler.outDir, absolute).startsWith(".."))) {
27592
+ return absolute;
27593
+ }
27594
+ if (!compiler.outDir || !compiler.rootDir) return null;
27595
+ const inOut = path18.relative(compiler.outDir, absolute);
27596
+ if (inOut.startsWith("..") || path18.isAbsolute(inOut)) return null;
27597
+ const extension = BUILD_EXTENSIONS.find((ext) => inOut.endsWith(ext));
27598
+ const stem = extension ? inOut.slice(0, -extension.length) : inOut;
27599
+ for (const ext of SOURCE_EXTENSIONS) {
27600
+ const candidate = path18.join(compiler.rootDir, stem + ext);
27601
+ if (isOwnFile(projectRoot, candidate) && isFile(candidate)) return candidate;
27602
+ }
27603
+ return null;
27604
+ }
27605
+ function readLocalPackages(projectRoot) {
27606
+ const out = /* @__PURE__ */ new Map();
27607
+ const ts = resolveTypeScript(projectRoot);
27608
+ const root = readJsonFile2(path18.join(projectRoot, "package.json"), null);
27609
+ if (!root || typeof root !== "object" || Array.isArray(root)) return out;
27610
+ const rootPkg = root;
27611
+ const declared = Array.isArray(rootPkg.workspaces) ? rootPkg.workspaces : rootPkg.workspaces && typeof rootPkg.workspaces === "object" && Array.isArray(rootPkg.workspaces.packages) ? rootPkg.workspaces.packages : [];
27612
+ const dirs = [projectRoot];
27613
+ for (const entry of declared) {
27614
+ if (typeof entry !== "string") continue;
27615
+ const key = pathKey(entry).replace(/\/+$/, "");
27616
+ if (!key || path18.isAbsolute(key)) continue;
27617
+ if (key.endsWith("/*")) {
27618
+ const base = path18.resolve(projectRoot, key.slice(0, -2));
27619
+ if (base.includes("*") || !isOwnFile(projectRoot, base)) continue;
27620
+ let children;
27621
+ try {
27622
+ children = fs13.readdirSync(base, { withFileTypes: true });
27623
+ } catch {
27624
+ continue;
27625
+ }
27626
+ for (const child of children.slice().sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
27627
+ if (child.isDirectory() && child.name !== "node_modules" && !child.name.startsWith(".")) {
27628
+ dirs.push(path18.join(base, child.name));
27629
+ }
27630
+ }
27631
+ } else if (!key.includes("*")) {
27632
+ const dir = path18.resolve(projectRoot, key);
27633
+ if (isOwnFile(projectRoot, dir)) dirs.push(dir);
27634
+ }
27635
+ }
27636
+ for (const dir of dirs) {
27637
+ const pkg = dir === projectRoot ? rootPkg : readJsonFile2(path18.join(dir, "package.json"), null);
27638
+ if (!pkg || typeof pkg !== "object" || Array.isArray(pkg)) continue;
27639
+ const name = pkg.name;
27640
+ if (typeof name !== "string" || !name) continue;
27641
+ const tsconfig = readJsonFile2(path18.join(dir, "tsconfig.json"), ts);
27642
+ const options = tsconfig?.compilerOptions ?? {};
27643
+ const compiler = {
27644
+ outDir: typeof options.outDir === "string" ? path18.resolve(dir, options.outDir) : void 0,
27645
+ rootDir: typeof options.rootDir === "string" ? path18.resolve(dir, options.rootDir) : void 0
27646
+ };
27647
+ for (const [subpath, targets] of packageEntries(pkg)) {
27648
+ const specifier = subpath === "." ? name : `${name}/${subpath.replace(/^\.\//, "")}`;
27649
+ if (out.has(specifier)) continue;
27650
+ for (const target of targets) {
27651
+ const source = entrySource(dir, target, compiler, projectRoot);
27652
+ if (source) {
27653
+ out.set(specifier, source);
27654
+ break;
27655
+ }
27656
+ }
27657
+ }
27658
+ }
27659
+ return out;
27376
27660
  }
27377
27661
  function looksBinary(buffer) {
27378
27662
  const probe = buffer.subarray(0, Math.min(buffer.length, 4096));
@@ -27430,6 +27714,9 @@ function buildCodeModel(implementations, types, projectRoot, sourceRoots = [], e
27430
27714
  const seen = /* @__PURE__ */ new Set();
27431
27715
  const exactCache = /* @__PURE__ */ new Map();
27432
27716
  const rootFiles = walkDeclaredRoots(sourceRoots, exclude, projectRoot);
27717
+ const localPackages = readLocalPackages(projectRoot);
27718
+ const packages = {};
27719
+ for (const [specifier, absolute] of localPackages) packages[specifier] = pathKey(path18.relative(projectRoot, absolute));
27433
27720
  const declaredPaths = [];
27434
27721
  for (const impl of implementations) {
27435
27722
  declaredPaths.push(...implementationSourceFiles(impl));
@@ -27475,7 +27762,7 @@ function buildCodeModel(implementations, types, projectRoot, sourceRoots = [], e
27475
27762
  if (ts) {
27476
27763
  try {
27477
27764
  const facts = walkExact(ts, text3, absolute);
27478
- chaseReexports(ts, facts, absolute, projectRoot, /* @__PURE__ */ new Set([absolute]), exactCache);
27765
+ chaseReexports(ts, facts, absolute, projectRoot, /* @__PURE__ */ new Set([absolute]), exactCache, localPackages);
27479
27766
  analyzed = {
27480
27767
  analysisGrade: "exact",
27481
27768
  declaredNames: [...facts.declared],
@@ -27487,6 +27774,10 @@ function buildCodeModel(implementations, types, projectRoot, sourceRoots = [], e
27487
27774
  ...facts.namedReexports.map(({ exported, local, from }) => ({ exported, local, from })),
27488
27775
  ...facts.starExports.map((from) => ({ exported: "*", local: "*", from }))
27489
27776
  ],
27777
+ exportAliases: facts.exportAliases.map((alias) => ({ ...alias })),
27778
+ returnTypes: Object.fromEntries(
27779
+ [...facts.returnTypes].filter((entry) => entry[1] !== null)
27780
+ ),
27490
27781
  functionComplexity: Object.fromEntries(facts.complexity),
27491
27782
  functionCallSites: Object.fromEntries([...facts.calls].map(([k, v]) => [k, [...v.values()]])),
27492
27783
  functionBodies: Object.fromEntries(facts.bodies),
@@ -27516,7 +27807,7 @@ function buildCodeModel(implementations, types, projectRoot, sourceRoots = [], e
27516
27807
  }
27517
27808
  files.push({ path: sourcePath, status: "analyzed", language, ...analyzed });
27518
27809
  }
27519
- return { files, projectRoot, rootFiles };
27810
+ return { files, projectRoot, rootFiles, packages };
27520
27811
  }
27521
27812
  var IMPORT_FROM_RE = /(?:^|;)[ \t]*import\s+(?!\()([^'";]*?)\s*from\s*['"]([^'"]+)['"]/gm;
27522
27813
  var DYNAMIC_IMPORT_RE = /\{([^{}]*)\}\s*=\s*await\s+import\(\s*['"]([^'"]+)['"]\s*\)/g;
@@ -46462,6 +46753,7 @@ function loadProjectConfig3() {
46462
46753
  resolveSubsystemExports,
46463
46754
  resolveVariantGuidance,
46464
46755
  retireSpecialists,
46756
+ returnTypeOf,
46465
46757
  rewriteReferences,
46466
46758
  runWithHostedLookup,
46467
46759
  runWithProjectBinding,