@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/cli/index.js CHANGED
@@ -65,7 +65,7 @@ var init_defaults = __esm({
65
65
  copilot: ".github/prompts",
66
66
  codex: ".codex/agents"
67
67
  };
68
- WAIRON_VERSION = "5.1.1-dev.100";
68
+ WAIRON_VERSION = "5.1.1-dev.101";
69
69
  GITHUB_REPO = "SYW-Apps/Waffle-AIron";
70
70
  SUPPORTED_ALIASES = ["wai"];
71
71
  SCAN_EXCLUDE_DIRS = /* @__PURE__ */ new Set([
@@ -5725,8 +5725,14 @@ function languageOfSourcePath(sourcePath) {
5725
5725
  function dialectOf(facts) {
5726
5726
  return facts.language ? typeDialectFor(facts.language) : null;
5727
5727
  }
5728
- function resolveImport(fromFile, specifier, knownPaths) {
5729
- if (!specifier.startsWith(".")) return void 0;
5728
+ function returnTypeOf(facts, fn) {
5729
+ return ownEntry(facts.returnTypes, fn);
5730
+ }
5731
+ function resolveImport(fromFile, specifier, knownPaths, packages) {
5732
+ if (!specifier.startsWith(".")) {
5733
+ const mapped = ownEntry(packages, specifier);
5734
+ return mapped !== void 0 && knownPaths.has(mapped) ? mapped : void 0;
5735
+ }
5730
5736
  const joined = pathKey(path10.posix.normalize(path10.posix.join(path10.posix.dirname(fromFile), specifier)));
5731
5737
  const candidates = [
5732
5738
  joined,
@@ -14185,12 +14191,12 @@ function packFiles(dir, prefix = "") {
14185
14191
  function computePackDigest(packDir) {
14186
14192
  const hash = crypto3.createHash("sha256");
14187
14193
  const abs = path16.resolve(packDir);
14188
- let isFile = false;
14194
+ let isFile2 = false;
14189
14195
  try {
14190
- isFile = fs11.statSync(abs).isFile();
14196
+ isFile2 = fs11.statSync(abs).isFile();
14191
14197
  } catch {
14192
14198
  }
14193
- const entries = isFile ? [[path16.basename(abs), abs]] : packFiles(abs).map((rel2) => [rel2, path16.join(abs, rel2)]);
14199
+ const entries = isFile2 ? [[path16.basename(abs), abs]] : packFiles(abs).map((rel2) => [rel2, path16.join(abs, rel2)]);
14194
14200
  for (const [rel2, full] of entries) {
14195
14201
  hash.update(rel2);
14196
14202
  hash.update("\0");
@@ -14911,6 +14917,7 @@ function appendUnique(map, key, value, same) {
14911
14917
  list2.push(value);
14912
14918
  }
14913
14919
  function buildCodeIndex(model) {
14920
+ const packages = model.packages ?? {};
14914
14921
  const facts = /* @__PURE__ */ new Map();
14915
14922
  const paths = /* @__PURE__ */ new Set();
14916
14923
  const exactPaths = /* @__PURE__ */ new Set();
@@ -14943,7 +14950,7 @@ function buildCodeIndex(model) {
14943
14950
  const f = facts.get(from);
14944
14951
  if (f?.status !== "analyzed") continue;
14945
14952
  for (const specifier of f.reexports) {
14946
- const to = resolveImport(from, specifier, paths);
14953
+ const to = resolveImport(from, specifier, paths, packages);
14947
14954
  if (to && !out.has(to)) {
14948
14955
  out.add(to);
14949
14956
  queue.push(to);
@@ -14955,7 +14962,7 @@ function buildCodeIndex(model) {
14955
14962
  };
14956
14963
  const NO_ORIGIN = /* @__PURE__ */ new Set();
14957
14964
  const landingFrom = (scope, specifier) => {
14958
- const to = resolveImport(scope, specifier, paths);
14965
+ const to = resolveImport(scope, specifier, paths, packages);
14959
14966
  return to ? republishedFrom(to) : NO_ORIGIN;
14960
14967
  };
14961
14968
  const scopeOf3 = (site, from) => {
@@ -14985,7 +14992,7 @@ function buildCodeIndex(model) {
14985
14992
  };
14986
14993
  const possibleOriginsOf = (site, from) => {
14987
14994
  const proven = originOf2(site, from);
14988
- if (!site.field && !site.constructed && !site.via) return proven;
14995
+ if (!site.field && !site.constructed && !site.via && !site.returnedBy && !site.enclosingClass) return proven;
14989
14996
  const resolved = scopeOf3(site, from);
14990
14997
  if (!resolved) return proven;
14991
14998
  const { path: scope, facts: f } = resolved;
@@ -14998,24 +15005,59 @@ function buildCodeIndex(model) {
14998
15005
  if (site.field) for (const typeName of fieldTypesOf(f, site.field)) widenThroughType(typeName);
14999
15006
  if (site.constructed) widenThrough(site.constructed, importBindingOf(f, site.constructed)?.from);
15000
15007
  if (site.via) for (const typeName of localTypesOf(f, site.via)) widenThroughType(typeName);
15008
+ if (site.enclosingClass !== void 0 && holdsMemberBody(f, site.name, site.enclosingClass)) {
15009
+ for (const candidate of republishedFrom(scope)) out.add(candidate);
15010
+ }
15011
+ if (site.returnedBy !== void 0) {
15012
+ for (const fnFile of originOf2({ name: site.returnedBy, member: false }, scope)) {
15013
+ const at = facts.get(fnFile);
15014
+ if (at?.status !== "analyzed" || at.analysisGrade !== "exact") continue;
15015
+ const typeName = returnTypeOf(at, site.returnedBy);
15016
+ if (typeName === void 0) continue;
15017
+ const specifier = typeBindingOf(at, typeName);
15018
+ const landings = specifier !== void 0 ? landingFrom(fnFile, specifier) : declarationsAt(fnFile).has(typeName) ? republishedFrom(fnFile) : NO_ORIGIN;
15019
+ for (const candidate of landings) {
15020
+ const there = facts.get(candidate);
15021
+ if (there && holdsMemberBody(there, site.name, typeName)) out.add(candidate);
15022
+ }
15023
+ }
15024
+ }
15001
15025
  return out;
15002
15026
  };
15027
+ 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);
15003
15028
  const declarationsAt = (path93) => namesAt(declarations, pathKey(path93), (f) => /* @__PURE__ */ new Set([...f.declaredNames, ...f.exportedNames]));
15004
- const forwardsOf = (start2, name) => {
15029
+ const forwardsOf = (start2, name, container) => {
15005
15030
  const out = [];
15031
+ const listed = /* @__PURE__ */ new Set();
15006
15032
  const seen = /* @__PURE__ */ new Set();
15007
- const queue = [{ file: pathKey(start2), name }];
15033
+ const queue = [{ file: pathKey(start2), name, container }];
15008
15034
  while (queue.length) {
15009
15035
  const at = queue.shift();
15010
- const key = `${at.file}#${at.name}`;
15036
+ const key = `${at.scope ? "s" : "p"}|${at.container ?? ""}|${at.file}#${at.name}`;
15011
15037
  if (seen.has(key)) continue;
15012
15038
  seen.add(key);
15013
- out.push(at);
15014
- for (const binding of facts.get(at.file)?.reexportBindings ?? []) {
15039
+ if (!listed.has(`${at.file}#${at.name}`)) {
15040
+ listed.add(`${at.file}#${at.name}`);
15041
+ out.push({ file: at.file, name: at.name });
15042
+ }
15043
+ const f = facts.get(at.file);
15044
+ if (at.scope) {
15045
+ const binding = f ? importBindingOf(f, at.name) : void 0;
15046
+ if (!binding || binding.namespace) continue;
15047
+ const to = resolveImport(at.file, binding.from, paths, packages);
15048
+ if (to) queue.push({ file: to, name: binding.imported ?? at.name });
15049
+ continue;
15050
+ }
15051
+ for (const alias of f?.exportAliases ?? []) {
15052
+ if (alias.exported !== at.name || alias.container !== at.container) continue;
15053
+ queue.push({ file: at.file, name: alias.local, scope: true });
15054
+ }
15055
+ if (at.container !== void 0) continue;
15056
+ for (const binding of f?.reexportBindings ?? []) {
15015
15057
  const star = binding.exported === "*";
15016
15058
  if (!star && binding.exported !== at.name) continue;
15017
15059
  if (star && at.name === "default") continue;
15018
- const to = resolveImport(at.file, binding.from, paths);
15060
+ const to = resolveImport(at.file, binding.from, paths, packages);
15019
15061
  if (!to) continue;
15020
15062
  if (star && !facts.get(to)?.exportedNames.includes(at.name)) continue;
15021
15063
  queue.push({ file: to, name: star ? at.name : binding.local });
@@ -15026,6 +15068,7 @@ function buildCodeIndex(model) {
15026
15068
  return {
15027
15069
  paths,
15028
15070
  exactPaths,
15071
+ packages,
15029
15072
  factsAt: (path93) => facts.get(pathKey(path93)),
15030
15073
  declarationsAt,
15031
15074
  anchorsAt: (path93) => namesAt(anchors, pathKey(path93), (f) => /* @__PURE__ */ new Set([...f.declaredNames, ...f.exportedNames, ...f.anchoredNames])),
@@ -15079,7 +15122,7 @@ function buildImportGraph(index, universe) {
15079
15122
  const traces = /* @__PURE__ */ new Map();
15080
15123
  const resolveAll = (from, specifiers, into) => {
15081
15124
  for (const specifier of specifiers) {
15082
- const to = resolveImport(from, specifier, universe);
15125
+ const to = resolveImport(from, specifier, universe, index.packages);
15083
15126
  if (to && to !== from) into.add(to);
15084
15127
  }
15085
15128
  };
@@ -20918,13 +20961,13 @@ function invokedAs(code, site, file) {
20918
20961
  if (!site.member) {
20919
20962
  const binding = importBindingOf(facts, site.name);
20920
20963
  if (!binding || binding.namespace) return [];
20921
- const module3 = resolveImport(scope, binding.from, code.paths);
20964
+ const module3 = resolveImport(scope, binding.from, code.paths, code.packages);
20922
20965
  return module3 ? code.forwardsOf(module3, binding.imported ?? site.name) : [];
20923
20966
  }
20924
20967
  if (!site.via) return [];
20925
20968
  const receiver = importBindingOf(facts, site.via);
20926
20969
  if (!receiver?.namespace) return [];
20927
- const module2 = resolveImport(scope, receiver.from, code.paths);
20970
+ const module2 = resolveImport(scope, receiver.from, code.paths, code.packages);
20928
20971
  return module2 ? code.forwardsOf(module2, site.name) : [];
20929
20972
  }
20930
20973
  function claimsOf(implMethod) {
@@ -20944,6 +20987,8 @@ function describeSite(site) {
20944
20987
  if (site.via) return `${site.via}.${site.name}(\u2026)`;
20945
20988
  if (site.field) return `this.${site.field}.${site.name}(\u2026)`;
20946
20989
  if (site.constructed) return `new ${site.constructed}(\u2026).${site.name}(\u2026)`;
20990
+ if (site.returnedBy) return `${site.returnedBy}(\u2026).${site.name}(\u2026)`;
20991
+ if (site.enclosingClass) return `this.${site.name}(\u2026)`;
20947
20992
  return `<receiver>.${site.name}(\u2026)`;
20948
20993
  }
20949
20994
  function describeMiss(m) {
@@ -20964,7 +21009,7 @@ var init_call_conformance = __esm({
20964
21009
  callConformanceRule = {
20965
21010
  name: "call-conformance",
20966
21011
  judges: "code",
20967
- 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.",
21012
+ 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.",
20968
21013
  codes: [
20969
21014
  { 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 },
20970
21015
  { 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 },
@@ -21007,7 +21052,7 @@ var init_call_conformance = __esm({
21007
21052
  if (!ctx.componentMap.has(claim.component)) continue;
21008
21053
  const target = resolveCallTarget(ctx, claim.component, claim.method);
21009
21054
  if (target.accepted.has(fnSymbol)) continue;
21010
- if (isTarget(code.forwardsOf(file, fnSymbol), target)) continue;
21055
+ if (isTarget(code.forwardsOf(file, fnSymbol, implMethod.exportedVia), target)) continue;
21011
21056
  const matching = sites.filter((s) => target.accepted.has(s.name));
21012
21057
  const ref = `${claim.component}.${claim.method}`;
21013
21058
  if (target.files.size === 0) {
@@ -21050,7 +21095,7 @@ var init_call_conformance = __esm({
21050
21095
  ctx.addIssue(
21051
21096
  "warning",
21052
21097
  "CALL_ORIGIN_UNRESOLVED",
21053
- `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.`,
21098
+ `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.`,
21054
21099
  impl.id,
21055
21100
  entry.draftContext,
21056
21101
  void 0,
@@ -21072,7 +21117,9 @@ var init_call_conformance = __esm({
21072
21117
  reached.set(site, owner);
21073
21118
  return owner !== void 0;
21074
21119
  };
21075
- for (const site of closedCallSites(code, file, fnSymbol, stopAtModelled, implMethod.exportedVia) ?? []) {
21120
+ const forwardsToModelled = code.forwardsOf(file, fnSymbol, implMethod.exportedVia).some((p) => p.file !== here && modelledAt.get(p.file)?.byName.has(p.name));
21121
+ const conversed = forwardsToModelled ? [] : closedCallSites(code, file, fnSymbol, stopAtModelled, implMethod.exportedVia) ?? [];
21122
+ for (const site of conversed) {
21076
21123
  const owner = reached.get(site);
21077
21124
  if (!owner || owner.component === component.id) continue;
21078
21125
  const ref = `${owner.component}.${owner.method}`;
@@ -22363,7 +22410,7 @@ var init_export_conformance = __esm({
22363
22410
  const facts = code.factsAt(file);
22364
22411
  if (!facts || facts.status !== "analyzed" || facts.analysisGrade !== "exact") continue;
22365
22412
  for (const binding of facts.reexportBindings ?? []) {
22366
- const target = resolveImport(file, binding.from, code.paths);
22413
+ const target = resolveImport(file, binding.from, code.paths, code.packages);
22367
22414
  const methods = target ? typeMethodsAt.get(target) : void 0;
22368
22415
  if (!methods) continue;
22369
22416
  if (binding.local === "*") {
@@ -22375,7 +22422,7 @@ var init_export_conformance = __esm({
22375
22422
  }
22376
22423
  const takenFrom = /* @__PURE__ */ new Map();
22377
22424
  const take = (consumer, writtenIn, specifier, names) => {
22378
- const target = resolveImport(writtenIn, specifier, code.paths);
22425
+ const target = resolveImport(writtenIn, specifier, code.paths, code.packages);
22379
22426
  if (!target) return;
22380
22427
  let byName = takenFrom.get(target);
22381
22428
  if (!byName) takenFrom.set(target, byName = /* @__PURE__ */ new Map());
@@ -24203,6 +24250,9 @@ function walkExact(ts, sourceText, fileName) {
24203
24250
  const reexports = /* @__PURE__ */ new Set();
24204
24251
  const starExports = [];
24205
24252
  const namedReexports = [];
24253
+ const exportAliases = [];
24254
+ const propertyAliases = [];
24255
+ const returnTypes = /* @__PURE__ */ new Map();
24206
24256
  const complexity = /* @__PURE__ */ new Map();
24207
24257
  const calls = /* @__PURE__ */ new Map();
24208
24258
  const bodies = /* @__PURE__ */ new Map();
@@ -24219,7 +24269,7 @@ function walkExact(ts, sourceText, fileName) {
24219
24269
  const mutableBindings = /* @__PURE__ */ new Set();
24220
24270
  const schemaConstants = /* @__PURE__ */ new Map();
24221
24271
  const derivedAliases = [];
24222
- const receiverKey = (site) => site.via ?? (site.field ? `this.${site.field}` : site.constructed ? `new ${site.constructed}` : "");
24272
+ const receiverKey = (site) => site.via ?? (site.field ? `this.${site.field}` : site.constructed ? `new ${site.constructed}` : site.returnedBy ? `${site.returnedBy}()` : site.enclosingClass ? `this:${site.enclosingClass}` : "");
24223
24273
  const siteKey = (site) => `${site.member ? "m" : "b"}:${receiverKey(site)}:${site.name}`;
24224
24274
  const addBindingNames = (name) => {
24225
24275
  if (ts.isIdentifier(name)) declared.add(name.text);
@@ -24327,6 +24377,44 @@ function walkExact(ts, sourceText, fileName) {
24327
24377
  }
24328
24378
  return void 0;
24329
24379
  };
24380
+ const enclosingClassOf = (node) => {
24381
+ let at = node.parent;
24382
+ while (at) {
24383
+ if (ts.isFunctionExpression(at) || ts.isFunctionDeclaration(at) || ts.isClassExpression(at)) return void 0;
24384
+ if ((ts.isMethodDeclaration(at) || ts.isGetAccessorDeclaration(at) || ts.isSetAccessorDeclaration(at)) && at.parent && ts.isObjectLiteralExpression(at.parent)) return void 0;
24385
+ if (ts.isClassDeclaration(at)) {
24386
+ return at.name && at.parent && ts.isSourceFile(at.parent) ? at.name.text : void 0;
24387
+ }
24388
+ at = at.parent;
24389
+ }
24390
+ return void 0;
24391
+ };
24392
+ const returnedTypeOf = (fn) => {
24393
+ const annotated = fn.type;
24394
+ if (annotated) {
24395
+ if (!ts.isTypeReferenceNode(annotated)) return void 0;
24396
+ if (ts.isIdentifier(annotated.typeName) && annotated.typeName.text === "Promise" && annotated.typeArguments?.length === 1) {
24397
+ const inner2 = annotated.typeArguments[0];
24398
+ return ts.isTypeReferenceNode(inner2) && !inner2.typeArguments ? typeReferenceName(inner2) : void 0;
24399
+ }
24400
+ return annotated.typeArguments ? void 0 : typeReferenceName(annotated);
24401
+ }
24402
+ const constructedClass = (expression) => {
24403
+ let node = expression;
24404
+ while (node && (ts.isParenthesizedExpression(node) || ts.isAsExpression(node) || ts.isSatisfiesExpression(node))) node = node.expression;
24405
+ return node && ts.isNewExpression(node) && ts.isIdentifier(node.expression) ? node.expression.text : void 0;
24406
+ };
24407
+ if (!fn.body) return void 0;
24408
+ if (!ts.isBlock(fn.body)) return constructedClass(fn.body);
24409
+ const returns = [];
24410
+ const collect2 = (node) => {
24411
+ if (ts.isFunctionLike(node)) return;
24412
+ if (ts.isReturnStatement(node)) returns.push(node);
24413
+ ts.forEachChild(node, collect2);
24414
+ };
24415
+ ts.forEachChild(fn.body, collect2);
24416
+ return returns.length === 1 ? constructedClass(returns[0].expression) : void 0;
24417
+ };
24330
24418
  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);
24331
24419
  const containerOf = (owner) => {
24332
24420
  if (!owner) return void 0;
@@ -24388,6 +24476,11 @@ function walkExact(ts, sourceText, fileName) {
24388
24476
  addSite({ name, member: true, field: receiver.name.text });
24389
24477
  } else if (ts.isNewExpression(receiver) && ts.isIdentifier(receiver.expression)) {
24390
24478
  addSite({ name, member: true, constructed: receiver.expression.text });
24479
+ } else if (ts.isCallExpression(receiver) && ts.isIdentifier(receiver.expression)) {
24480
+ addSite({ name, member: true, returnedBy: receiver.expression.text });
24481
+ } else if (receiver.kind === ts.SyntaxKind.ThisKeyword) {
24482
+ const owner = enclosingClassOf(node);
24483
+ addSite(owner !== void 0 ? { name, member: true, enclosingClass: owner } : { name, member: true });
24391
24484
  } else addSite({ name, member: true });
24392
24485
  }
24393
24486
  }
@@ -24514,6 +24607,8 @@ function walkExact(ts, sourceText, fileName) {
24514
24607
  signatures.push(declaredParameters(node));
24515
24608
  functionParams.set(fnName, signatures);
24516
24609
  if (completesLater(node)) asyncFunctions.push(fnName);
24610
+ const returned = returnedTypeOf(node) ?? null;
24611
+ returnTypes.set(fnName, returnTypes.has(fnName) && returnTypes.get(fnName) !== returned ? null : returned);
24517
24612
  const routes = collectRoutes(node);
24518
24613
  if (routes.size > 0) {
24519
24614
  const known = functionRoutes.get(fnName) ?? /* @__PURE__ */ new Map();
@@ -24550,6 +24645,23 @@ function walkExact(ts, sourceText, fileName) {
24550
24645
  if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.initializer && !schemaConstants.has(node.name.text)) {
24551
24646
  schemaConstants.set(node.name.text, node.initializer);
24552
24647
  }
24648
+ if (isTopLevelVariable(node) && node.initializer) {
24649
+ let literal = node.initializer;
24650
+ while (ts.isAsExpression(literal) || ts.isSatisfiesExpression(literal) || ts.isParenthesizedExpression(literal)) {
24651
+ literal = literal.expression;
24652
+ }
24653
+ if (ts.isObjectLiteralExpression(literal)) {
24654
+ const container = node.name.text;
24655
+ for (const property of literal.properties) {
24656
+ if (ts.isShorthandPropertyAssignment(property)) {
24657
+ propertyAliases.push({ exported: property.name.text, local: property.name.text, container });
24658
+ } else if (ts.isPropertyAssignment(property) && ts.isIdentifier(property.initializer)) {
24659
+ const key = propertyNameText(property.name);
24660
+ if (key) propertyAliases.push({ exported: key, local: property.initializer.text, container });
24661
+ }
24662
+ }
24663
+ }
24664
+ }
24553
24665
  if (ts.isFunctionDeclaration(node) || ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node) || ts.isEnumDeclaration(node) || ts.isModuleDeclaration(node)) {
24554
24666
  const name = node.name && ts.isIdentifier(node.name) ? node.name.text : void 0;
24555
24667
  if (name) {
@@ -24601,9 +24713,10 @@ function walkExact(ts, sourceText, fileName) {
24601
24713
  for (const el of node.exportClause.elements) {
24602
24714
  declared.add(el.name.text);
24603
24715
  exported.add(el.name.text);
24604
- if (spec && !node.isTypeOnly && !el.isTypeOnly) {
24605
- namedReexports.push({ exported: el.name.text, local: (el.propertyName ?? el.name).text, from: spec });
24606
- }
24716
+ if (node.isTypeOnly || el.isTypeOnly) continue;
24717
+ const local = (el.propertyName ?? el.name).text;
24718
+ if (spec) namedReexports.push({ exported: el.name.text, local, from: spec });
24719
+ else exportAliases.push({ exported: el.name.text, local });
24607
24720
  }
24608
24721
  } else if (!node.exportClause && spec) {
24609
24722
  starExports.push(spec);
@@ -24678,7 +24791,12 @@ function walkExact(ts, sourceText, fileName) {
24678
24791
  if (values && schemaConstants.has(alias.constant)) enumValues.set(alias.name, values);
24679
24792
  }
24680
24793
  const reexportOnly = sf.statements.length > 0 && sf.statements.every((st) => ts.isExportDeclaration(st) && !!st.moduleSpecifier);
24681
- return { declared, anchors, exported, imports, reexports, starExports, namedReexports, complexity, calls, bodies, importBindings, typeOnlyBindings, fieldTypes, localTypes, typeShapes, functionParams, functionRoutes, asyncFunctions, enumValues, aliasTypes, mutableBindings, reexportOnly };
24794
+ for (const alias of propertyAliases) if (exported.has(alias.container)) exportAliases.push(alias);
24795
+ 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 };
24796
+ }
24797
+ function resolveModule(fromFile, specifier, packages) {
24798
+ if (!specifier.startsWith(".")) return packages.get(specifier) ?? null;
24799
+ return resolveRelativeModule(fromFile, specifier);
24682
24800
  }
24683
24801
  function resolveRelativeModule(fromFile, specifier) {
24684
24802
  if (!specifier.startsWith(".")) return null;
@@ -24701,8 +24819,8 @@ function resolveRelativeModule(fromFile, specifier) {
24701
24819
  }
24702
24820
  return null;
24703
24821
  }
24704
- function reexportTarget(ts, filePath, specifier, projectRoot2, visited, exactCache) {
24705
- const target = resolveRelativeModule(filePath, specifier);
24822
+ function reexportTarget(ts, filePath, specifier, projectRoot2, visited, exactCache, packages) {
24823
+ const target = resolveModule(filePath, specifier, packages);
24706
24824
  if (!target || path18.relative(projectRoot2, target).startsWith("..")) return null;
24707
24825
  let targetFacts = exactCache.get(target);
24708
24826
  if (targetFacts === void 0) {
@@ -24716,7 +24834,7 @@ function reexportTarget(ts, filePath, specifier, projectRoot2, visited, exactCac
24716
24834
  if (!targetFacts) return null;
24717
24835
  if (!visited.has(target)) {
24718
24836
  visited.add(target);
24719
- chaseReexports(ts, targetFacts, target, projectRoot2, visited, exactCache);
24837
+ chaseReexports(ts, targetFacts, target, projectRoot2, visited, exactCache, packages);
24720
24838
  }
24721
24839
  return { path: target, facts: targetFacts };
24722
24840
  }
@@ -24739,13 +24857,33 @@ function carryBody(facts, target, targetPath, local, exported, projectRoot2) {
24739
24857
  }
24740
24858
  facts.bodies.set(exported, carried);
24741
24859
  }
24742
- function chaseReexports(ts, facts, filePath, projectRoot2, visited, exactCache) {
24860
+ function carryAliasBody(facts, source, from, local, alias) {
24861
+ const sourceBodies = source.bodies.get(local) ?? [];
24862
+ if (!sourceBodies.length || sourceBodies.some((b) => b.nested)) return;
24863
+ const moduleScope = sourceBodies.filter((b) => b.container === void 0);
24864
+ if (!moduleScope.length) return;
24865
+ const score = source.complexity.get(local);
24866
+ if (score !== void 0) {
24867
+ facts.complexity.set(alias.exported, Math.max(facts.complexity.get(alias.exported) ?? 0, score));
24868
+ }
24869
+ const relocate2 = (site) => from !== void 0 ? { ...site, from: site.from ?? from } : site;
24870
+ const sites = facts.calls.get(alias.exported) ?? /* @__PURE__ */ new Map();
24871
+ const carried = facts.bodies.get(alias.exported) ?? [];
24872
+ for (const body of moduleScope) {
24873
+ const moved = body.sites.map(relocate2);
24874
+ for (const site of moved) sites.set(`${from ?? ""}|${alias.container ?? ""}|${JSON.stringify(site)}`, site);
24875
+ carried.push(alias.container !== void 0 ? { container: alias.container, sites: moved } : { sites: moved });
24876
+ }
24877
+ facts.calls.set(alias.exported, sites);
24878
+ facts.bodies.set(alias.exported, carried);
24879
+ }
24880
+ function chaseReexports(ts, facts, filePath, projectRoot2, visited, exactCache, packages = NO_PACKAGES) {
24743
24881
  for (const re of facts.namedReexports) {
24744
- const target = reexportTarget(ts, filePath, re.from, projectRoot2, visited, exactCache);
24882
+ const target = reexportTarget(ts, filePath, re.from, projectRoot2, visited, exactCache, packages);
24745
24883
  if (target) carryBody(facts, target.facts, target.path, re.local, re.exported, projectRoot2);
24746
24884
  }
24747
24885
  for (const spec of facts.starExports) {
24748
- const target = reexportTarget(ts, filePath, spec, projectRoot2, visited, exactCache);
24886
+ const target = reexportTarget(ts, filePath, spec, projectRoot2, visited, exactCache, packages);
24749
24887
  if (!target) continue;
24750
24888
  for (const name of target.facts.exported) {
24751
24889
  facts.exported.add(name);
@@ -24753,6 +24891,147 @@ function chaseReexports(ts, facts, filePath, projectRoot2, visited, exactCache)
24753
24891
  carryBody(facts, target.facts, target.path, name, name, projectRoot2);
24754
24892
  }
24755
24893
  }
24894
+ for (const alias of facts.exportAliases) {
24895
+ const binding = facts.importBindings.get(alias.local);
24896
+ if (binding) {
24897
+ if (binding.namespace) continue;
24898
+ const target = reexportTarget(ts, filePath, binding.from, projectRoot2, visited, exactCache, packages);
24899
+ if (!target) continue;
24900
+ const from = pathKey(path18.relative(projectRoot2, target.path));
24901
+ carryAliasBody(facts, target.facts, from, binding.imported ?? alias.local, alias);
24902
+ } else if (alias.container !== void 0 || alias.local !== alias.exported) {
24903
+ carryAliasBody(facts, facts, void 0, alias.local, alias);
24904
+ }
24905
+ }
24906
+ }
24907
+ function isOwnFile(projectRoot2, absolute) {
24908
+ const rel2 = path18.relative(projectRoot2, absolute);
24909
+ if (rel2.startsWith("..") || path18.isAbsolute(rel2)) return false;
24910
+ return !pathKey(rel2).split("/").includes("node_modules");
24911
+ }
24912
+ function isFile(absolute) {
24913
+ try {
24914
+ return fs13.statSync(absolute).isFile();
24915
+ } catch {
24916
+ return false;
24917
+ }
24918
+ }
24919
+ function readJsonFile(file, ts) {
24920
+ let text3;
24921
+ try {
24922
+ text3 = fs13.readFileSync(file, "utf8");
24923
+ } catch {
24924
+ return void 0;
24925
+ }
24926
+ try {
24927
+ return JSON.parse(text3);
24928
+ } catch {
24929
+ if (!ts) return void 0;
24930
+ const parsed = ts.parseConfigFileTextToJson(file, text3);
24931
+ return parsed.error ? void 0 : parsed.config;
24932
+ }
24933
+ }
24934
+ function conditionTargets(value) {
24935
+ if (typeof value === "string") return [value];
24936
+ if (!value || typeof value !== "object" || Array.isArray(value)) return [];
24937
+ const record2 = value;
24938
+ const keys = [...ENTRY_CONDITIONS.filter((k) => k in record2), ...Object.keys(record2).filter((k) => !ENTRY_CONDITIONS.includes(k))];
24939
+ return keys.flatMap((k) => conditionTargets(record2[k]));
24940
+ }
24941
+ function packageEntries(pkg) {
24942
+ const entries = /* @__PURE__ */ new Map();
24943
+ const exportsField = pkg.exports;
24944
+ if (exportsField !== void 0 && exportsField !== null) {
24945
+ const isSubpathMap = typeof exportsField === "object" && !Array.isArray(exportsField) && Object.keys(exportsField).some((k) => k.startsWith("."));
24946
+ if (isSubpathMap) {
24947
+ for (const [subpath, value] of Object.entries(exportsField)) {
24948
+ if (!subpath.startsWith(".") || subpath.includes("*")) continue;
24949
+ const targets = conditionTargets(value);
24950
+ if (targets.length) entries.set(subpath, targets);
24951
+ }
24952
+ } else {
24953
+ const targets = conditionTargets(exportsField);
24954
+ if (targets.length) entries.set(".", targets);
24955
+ }
24956
+ return entries;
24957
+ }
24958
+ const fallbacks = ["module", "main", "types"].map((k) => pkg[k]).filter((v) => typeof v === "string");
24959
+ if (fallbacks.length) entries.set(".", fallbacks);
24960
+ return entries;
24961
+ }
24962
+ function entrySource(packageDir, target, compiler, projectRoot2) {
24963
+ const absolute = path18.resolve(packageDir, target);
24964
+ if (!isOwnFile(projectRoot2, absolute)) return null;
24965
+ const isDeclaration = /\.d\.[cm]?ts$/.test(absolute);
24966
+ if (!isDeclaration && languageOfSourcePath(absolute) && isFile(absolute) && !(compiler.outDir && !path18.relative(compiler.outDir, absolute).startsWith(".."))) {
24967
+ return absolute;
24968
+ }
24969
+ if (!compiler.outDir || !compiler.rootDir) return null;
24970
+ const inOut = path18.relative(compiler.outDir, absolute);
24971
+ if (inOut.startsWith("..") || path18.isAbsolute(inOut)) return null;
24972
+ const extension = BUILD_EXTENSIONS.find((ext) => inOut.endsWith(ext));
24973
+ const stem2 = extension ? inOut.slice(0, -extension.length) : inOut;
24974
+ for (const ext of SOURCE_EXTENSIONS) {
24975
+ const candidate = path18.join(compiler.rootDir, stem2 + ext);
24976
+ if (isOwnFile(projectRoot2, candidate) && isFile(candidate)) return candidate;
24977
+ }
24978
+ return null;
24979
+ }
24980
+ function readLocalPackages(projectRoot2) {
24981
+ const out = /* @__PURE__ */ new Map();
24982
+ const ts = resolveTypeScript(projectRoot2);
24983
+ const root = readJsonFile(path18.join(projectRoot2, "package.json"), null);
24984
+ if (!root || typeof root !== "object" || Array.isArray(root)) return out;
24985
+ const rootPkg = root;
24986
+ const declared = Array.isArray(rootPkg.workspaces) ? rootPkg.workspaces : rootPkg.workspaces && typeof rootPkg.workspaces === "object" && Array.isArray(rootPkg.workspaces.packages) ? rootPkg.workspaces.packages : [];
24987
+ const dirs = [projectRoot2];
24988
+ for (const entry of declared) {
24989
+ if (typeof entry !== "string") continue;
24990
+ const key = pathKey(entry).replace(/\/+$/, "");
24991
+ if (!key || path18.isAbsolute(key)) continue;
24992
+ if (key.endsWith("/*")) {
24993
+ const base = path18.resolve(projectRoot2, key.slice(0, -2));
24994
+ if (base.includes("*") || !isOwnFile(projectRoot2, base)) continue;
24995
+ let children;
24996
+ try {
24997
+ children = fs13.readdirSync(base, { withFileTypes: true });
24998
+ } catch {
24999
+ continue;
25000
+ }
25001
+ for (const child of children.slice().sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
25002
+ if (child.isDirectory() && child.name !== "node_modules" && !child.name.startsWith(".")) {
25003
+ dirs.push(path18.join(base, child.name));
25004
+ }
25005
+ }
25006
+ } else if (!key.includes("*")) {
25007
+ const dir = path18.resolve(projectRoot2, key);
25008
+ if (isOwnFile(projectRoot2, dir)) dirs.push(dir);
25009
+ }
25010
+ }
25011
+ for (const dir of dirs) {
25012
+ const pkg = dir === projectRoot2 ? rootPkg : readJsonFile(path18.join(dir, "package.json"), null);
25013
+ if (!pkg || typeof pkg !== "object" || Array.isArray(pkg)) continue;
25014
+ const name = pkg.name;
25015
+ if (typeof name !== "string" || !name) continue;
25016
+ const tsconfig = readJsonFile(path18.join(dir, "tsconfig.json"), ts);
25017
+ const options = tsconfig?.compilerOptions ?? {};
25018
+ const compiler = {
25019
+ outDir: typeof options.outDir === "string" ? path18.resolve(dir, options.outDir) : void 0,
25020
+ rootDir: typeof options.rootDir === "string" ? path18.resolve(dir, options.rootDir) : void 0
25021
+ };
25022
+ for (const [subpath, targets] of packageEntries(pkg)) {
25023
+ const specifier = subpath === "." ? name : `${name}/${subpath.replace(/^\.\//, "")}`;
25024
+ if (out.has(specifier)) continue;
25025
+ for (const target of targets) {
25026
+ const source = entrySource(dir, target, compiler, projectRoot2);
25027
+ if (source) {
25028
+ out.set(specifier, source);
25029
+ break;
25030
+ }
25031
+ }
25032
+ }
25033
+ }
25034
+ return out;
24756
25035
  }
24757
25036
  function looksBinary(buffer) {
24758
25037
  const probe2 = buffer.subarray(0, Math.min(buffer.length, 4096));
@@ -24810,6 +25089,9 @@ function buildCodeModel(implementations, types, projectRoot2, sourceRoots = [],
24810
25089
  const seen = /* @__PURE__ */ new Set();
24811
25090
  const exactCache = /* @__PURE__ */ new Map();
24812
25091
  const rootFiles = walkDeclaredRoots(sourceRoots, exclude, projectRoot2);
25092
+ const localPackages = readLocalPackages(projectRoot2);
25093
+ const packages = {};
25094
+ for (const [specifier, absolute] of localPackages) packages[specifier] = pathKey(path18.relative(projectRoot2, absolute));
24813
25095
  const declaredPaths = [];
24814
25096
  for (const impl of implementations) {
24815
25097
  declaredPaths.push(...implementationSourceFiles(impl));
@@ -24855,7 +25137,7 @@ function buildCodeModel(implementations, types, projectRoot2, sourceRoots = [],
24855
25137
  if (ts) {
24856
25138
  try {
24857
25139
  const facts = walkExact(ts, text3, absolute);
24858
- chaseReexports(ts, facts, absolute, projectRoot2, /* @__PURE__ */ new Set([absolute]), exactCache);
25140
+ chaseReexports(ts, facts, absolute, projectRoot2, /* @__PURE__ */ new Set([absolute]), exactCache, localPackages);
24859
25141
  analyzed = {
24860
25142
  analysisGrade: "exact",
24861
25143
  declaredNames: [...facts.declared],
@@ -24867,6 +25149,10 @@ function buildCodeModel(implementations, types, projectRoot2, sourceRoots = [],
24867
25149
  ...facts.namedReexports.map(({ exported, local, from }) => ({ exported, local, from })),
24868
25150
  ...facts.starExports.map((from) => ({ exported: "*", local: "*", from }))
24869
25151
  ],
25152
+ exportAliases: facts.exportAliases.map((alias) => ({ ...alias })),
25153
+ returnTypes: Object.fromEntries(
25154
+ [...facts.returnTypes].filter((entry) => entry[1] !== null)
25155
+ ),
24870
25156
  functionComplexity: Object.fromEntries(facts.complexity),
24871
25157
  functionCallSites: Object.fromEntries([...facts.calls].map(([k, v]) => [k, [...v.values()]])),
24872
25158
  functionBodies: Object.fromEntries(facts.bodies),
@@ -24896,7 +25182,7 @@ function buildCodeModel(implementations, types, projectRoot2, sourceRoots = [],
24896
25182
  }
24897
25183
  files.push({ path: sourcePath, status: "analyzed", language, ...analyzed });
24898
25184
  }
24899
- return { files, projectRoot: projectRoot2, rootFiles };
25185
+ return { files, projectRoot: projectRoot2, rootFiles, packages };
24900
25186
  }
24901
25187
  function clauseBindings(clause, specifier) {
24902
25188
  const out = [];
@@ -25032,7 +25318,7 @@ function findTestsReferencing(methods, projectRoot2, testRoots) {
25032
25318
  }
25033
25319
  return found;
25034
25320
  }
25035
- var fs13, path18, import_module2, C_FAMILY_COMMENTS, NAMED_IMPORT_BINDINGS_RE, JS_PATTERNS, LANGUAGE_PATTERNS, PATTERN_ANALYSIS_MAX_BYTES, IDENTIFIER_RE, STRING_RE, tsResolutionCache, TS_RESOLUTION_RETRY_MS, IMPORT_FROM_RE, DYNAMIC_IMPORT_RE, IDENTIFIER_ONLY_RE, NAMED_REEXPORT_RE, STAR_REEXPORT_RE;
25321
+ var fs13, path18, import_module2, C_FAMILY_COMMENTS, NAMED_IMPORT_BINDINGS_RE, JS_PATTERNS, LANGUAGE_PATTERNS, PATTERN_ANALYSIS_MAX_BYTES, IDENTIFIER_RE, STRING_RE, tsResolutionCache, TS_RESOLUTION_RETRY_MS, NO_PACKAGES, BUILD_EXTENSIONS, SOURCE_EXTENSIONS, ENTRY_CONDITIONS, IMPORT_FROM_RE, DYNAMIC_IMPORT_RE, IDENTIFIER_ONLY_RE, NAMED_REEXPORT_RE, STAR_REEXPORT_RE;
25036
25322
  var init_source_analysis = __esm({
25037
25323
  "src/core/source-analysis.ts"() {
25038
25324
  "use strict";
@@ -25141,6 +25427,10 @@ var init_source_analysis = __esm({
25141
25427
  STRING_RE = /'([^'\\\n]*(?:\\.[^'\\\n]*)*)'|"([^"\\\n]*(?:\\.[^"\\\n]*)*)"|`([^`\\]*(?:\\.[^`\\]*)*)`/g;
25142
25428
  tsResolutionCache = /* @__PURE__ */ new Map();
25143
25429
  TS_RESOLUTION_RETRY_MS = 3e4;
25430
+ NO_PACKAGES = /* @__PURE__ */ new Map();
25431
+ BUILD_EXTENSIONS = [".d.mts", ".d.cts", ".d.ts", ".mjs", ".cjs", ".jsx", ".js"];
25432
+ SOURCE_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
25433
+ ENTRY_CONDITIONS = ["types", "import", "require", "default"];
25144
25434
  IMPORT_FROM_RE = /(?:^|;)[ \t]*import\s+(?!\()([^'";]*?)\s*from\s*['"]([^'"]+)['"]/gm;
25145
25435
  DYNAMIC_IMPORT_RE = /\{([^{}]*)\}\s*=\s*await\s+import\(\s*['"]([^'"]+)['"]\s*\)/g;
25146
25436
  IDENTIFIER_ONLY_RE = /^[A-Za-z_$][\w$]*$/;