@dreamtree-org/graphify 1.1.2 → 1.1.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,7 +1,7 @@
1
1
  import {
2
2
  affectedBy,
3
3
  testsForNode
4
- } from "./chunk-YT7B6DOD.js";
4
+ } from "./chunk-ZK3TA6FW.js";
5
5
  import {
6
6
  escapeHtml,
7
7
  sanitizeLabel,
@@ -1609,13 +1609,11 @@ async function extractTypeScript(filePath, displayPath) {
1609
1609
  });
1610
1610
  }
1611
1611
  function importTargetId(binding, property) {
1612
- if (!binding.ref.external) {
1613
- if (binding.kind === "named" && binding.importedName) {
1614
- return entityId(binding.ref.id, binding.importedName);
1615
- }
1616
- if (binding.kind === "namespace" && property) {
1617
- return entityId(binding.ref.id, property);
1618
- }
1612
+ if (binding.kind === "named" && binding.importedName) {
1613
+ return entityId(binding.ref.id, binding.importedName);
1614
+ }
1615
+ if (binding.kind === "namespace" && property) {
1616
+ return entityId(binding.ref.id, property);
1619
1617
  }
1620
1618
  return binding.ref.id;
1621
1619
  }
@@ -1653,24 +1651,35 @@ async function extractTypeScript(filePath, displayPath) {
1653
1651
  }
1654
1652
  }
1655
1653
  }
1654
+ function unwrapExpression(node) {
1655
+ let current = node;
1656
+ while (current.type === "as_expression" || current.type === "satisfies_expression" || current.type === "non_null_expression" || current.type === "parenthesized_expression") {
1657
+ const inner = namedChildren(current)[0];
1658
+ if (!inner) break;
1659
+ current = inner;
1660
+ }
1661
+ return current;
1662
+ }
1656
1663
  function handleTopLevelVariableFunctions(node) {
1664
+ const isExported = node.parent?.type === "export_statement";
1657
1665
  for (const declarator of namedChildren(node)) {
1658
1666
  if (declarator.type !== "variable_declarator") continue;
1659
1667
  const value = declarator.childForFieldName("value");
1660
1668
  if (!value) continue;
1661
- if (value.type === "arrow_function" || value.type === "function_expression") {
1669
+ const core = unwrapExpression(value);
1670
+ if (core.type === "arrow_function" || core.type === "function_expression") {
1662
1671
  const name = declarator.childForFieldName("name")?.text;
1663
1672
  if (!name) continue;
1664
1673
  const id = entityId(sourceFile, name);
1665
1674
  builder.addNode({ id, label: `function ${name}`, sourceFile, sourceLocation: lineOf(declarator) });
1666
1675
  builder.addEdge({ source: fileId, target: id, relation: "contains", confidence: "EXTRACTED" });
1667
1676
  nameIndex.set(name, id);
1668
- functionNodeMap.set(value.id, id);
1677
+ functionNodeMap.set(core.id, id);
1669
1678
  continue;
1670
1679
  }
1671
- if (value.type === "call_expression") {
1672
- const callee = value.childForFieldName("function");
1673
- const specifier = callee?.type === "identifier" && callee.text === "require" ? firstStringArgument(value) : null;
1680
+ if (core.type === "call_expression") {
1681
+ const callee = core.childForFieldName("function");
1682
+ const specifier = callee?.type === "identifier" && callee.text === "require" ? firstStringArgument(core) : null;
1674
1683
  if (specifier) {
1675
1684
  const nameNode = declarator.childForFieldName("name");
1676
1685
  if (nameNode) {
@@ -1678,6 +1687,21 @@ async function extractTypeScript(filePath, displayPath) {
1678
1687
  addModuleNode(ref);
1679
1688
  registerRequireBinding(nameNode, ref);
1680
1689
  }
1690
+ continue;
1691
+ }
1692
+ }
1693
+ if (isExported) {
1694
+ const name = declarator.childForFieldName("name")?.text;
1695
+ if (!name) continue;
1696
+ const id = entityId(sourceFile, name);
1697
+ builder.addNode({ id, label: `const ${name}`, sourceFile, sourceLocation: lineOf(declarator) });
1698
+ builder.addEdge({ source: fileId, target: id, relation: "contains", confidence: "EXTRACTED" });
1699
+ nameIndex.set(name, id);
1700
+ if (core.type === "identifier") {
1701
+ const aliased = nameIndex.get(core.text);
1702
+ if (aliased !== void 0 && aliased !== id) {
1703
+ builder.addEdge({ source: id, target: aliased, relation: "references", confidence: "EXTRACTED" });
1704
+ }
1681
1705
  }
1682
1706
  }
1683
1707
  }
@@ -2077,13 +2101,12 @@ function candidatePaths(guessed) {
2077
2101
  }
2078
2102
  return candidates.filter((c) => c !== guessed);
2079
2103
  }
2080
- function uniqueMatch(guessed, candidates, realIds) {
2104
+ function uniqueMatch(candidates, real) {
2081
2105
  const matches = /* @__PURE__ */ new Set();
2082
2106
  for (const candidate of candidates) {
2083
- if (realIds.has(candidate)) matches.add(candidate);
2107
+ if (real.has(candidate)) matches.add(candidate);
2084
2108
  }
2085
- if (matches.size !== 1) return null;
2086
- return [...matches][0];
2109
+ return matches.size === 1 ? [...matches][0] : null;
2087
2110
  }
2088
2111
  function resolveCrossFileReferences(extractions, options = {}) {
2089
2112
  const selfNames = options.selfNames ?? [];
@@ -2104,20 +2127,24 @@ function resolveCrossFileReferences(extractions, options = {}) {
2104
2127
  }
2105
2128
  }
2106
2129
  const remap = /* @__PURE__ */ new Map();
2107
- const resolveId = (id) => {
2108
- if (id.startsWith("module:") && selfNames.length > 0) {
2109
- const cachedSelf = remap.get(id);
2110
- if (cachedSelf !== void 0) return cachedSelf;
2111
- const candidates = selfImportCandidates(id.slice("module:".length), selfNames);
2112
- if (candidates !== null) {
2113
- const resolved2 = uniqueMatch(id, candidates, realFiles);
2114
- if (resolved2 !== null) {
2115
- remap.set(id, resolved2);
2116
- return resolved2;
2130
+ let resolvedEndpoints = 0;
2131
+ const applyRemap = (resolveId) => {
2132
+ for (const extraction of extractions) {
2133
+ for (const edge of extraction.edges) {
2134
+ const source = resolveId(edge.source);
2135
+ if (source !== null) {
2136
+ edge.source = source;
2137
+ resolvedEndpoints++;
2138
+ }
2139
+ const target = resolveId(edge.target);
2140
+ if (target !== null) {
2141
+ edge.target = target;
2142
+ resolvedEndpoints++;
2117
2143
  }
2118
2144
  }
2119
- return null;
2120
2145
  }
2146
+ };
2147
+ const resolvePathId = (id) => {
2121
2148
  if (isOpaque(id)) return null;
2122
2149
  const cached = remap.get(id);
2123
2150
  if (cached !== void 0) return cached;
@@ -2127,30 +2154,77 @@ function resolveCrossFileReferences(extractions, options = {}) {
2127
2154
  if (realIds.has(id)) return null;
2128
2155
  const guessedPath = id.slice(0, sep2);
2129
2156
  const name = id.slice(sep2);
2130
- const candidates = candidatePaths(guessedPath).map((p) => `${p}${name}`);
2131
- resolved = uniqueMatch(id, candidates, realIds);
2157
+ resolved = uniqueMatch(candidatePaths(guessedPath).map((p) => `${p}${name}`), realIds);
2132
2158
  } else {
2133
2159
  if (realFiles.has(id)) return null;
2134
- resolved = uniqueMatch(id, candidatePaths(id), realFiles);
2160
+ resolved = uniqueMatch(candidatePaths(id), realFiles);
2135
2161
  }
2136
2162
  if (resolved !== null) remap.set(id, resolved);
2137
2163
  return resolved;
2138
2164
  };
2139
- let resolvedEndpoints = 0;
2165
+ applyRemap(resolvePathId);
2166
+ const namedAlias = /* @__PURE__ */ new Map();
2167
+ const starTargets = /* @__PURE__ */ new Map();
2140
2168
  for (const extraction of extractions) {
2141
2169
  for (const edge of extraction.edges) {
2142
- const source = resolveId(edge.source);
2143
- if (source !== null) {
2144
- edge.source = source;
2145
- resolvedEndpoints++;
2146
- }
2147
- const target = resolveId(edge.target);
2148
- if (target !== null) {
2149
- edge.target = target;
2150
- resolvedEndpoints++;
2170
+ if (edge.relation !== "re_exports" || !realFiles.has(edge.source)) continue;
2171
+ const sep2 = edge.target.lastIndexOf("::");
2172
+ if (sep2 > 0 && realIds.has(edge.target)) {
2173
+ namedAlias.set(`${edge.source}|${edge.target.slice(sep2 + 2)}`, edge.target);
2174
+ } else if (sep2 < 0 && realFiles.has(edge.target)) {
2175
+ const targets = starTargets.get(edge.source) ?? [];
2176
+ targets.push(edge.target);
2177
+ starTargets.set(edge.source, targets);
2151
2178
  }
2152
2179
  }
2153
2180
  }
2181
+ const throughBarrel = (file, name) => {
2182
+ const direct = `${file}::${name}`;
2183
+ if (realIds.has(direct)) return direct;
2184
+ const aliased = namedAlias.get(`${file}|${name}`);
2185
+ if (aliased !== void 0) return aliased;
2186
+ const viaStar = (starTargets.get(file) ?? []).map((sf) => `${sf}::${name}`).filter((id) => realIds.has(id));
2187
+ return viaStar.length === 1 ? viaStar[0] : null;
2188
+ };
2189
+ const resolveBarrelId = (id) => {
2190
+ const cached = remap.get(id);
2191
+ if (cached !== void 0) return cached;
2192
+ if (id.startsWith("module:")) {
2193
+ const spec = id.slice("module:".length);
2194
+ const sep3 = spec.indexOf("::");
2195
+ const moduleSpec = sep3 > 0 ? spec.slice(0, sep3) : spec;
2196
+ const name = sep3 > 0 ? spec.slice(sep3 + 2) : null;
2197
+ const candidates = selfImportCandidates(moduleSpec, selfNames);
2198
+ if (candidates === null) {
2199
+ if (name === null) return null;
2200
+ remap.set(id, `module:${moduleSpec}`);
2201
+ return `module:${moduleSpec}`;
2202
+ }
2203
+ const file = uniqueMatch(candidates, realFiles);
2204
+ let resolved = null;
2205
+ if (file !== null) {
2206
+ resolved = name !== null ? throughBarrel(file, name) ?? file : file;
2207
+ } else if (name !== null) {
2208
+ resolved = `module:${moduleSpec}`;
2209
+ }
2210
+ if (resolved !== null) remap.set(id, resolved);
2211
+ return resolved;
2212
+ }
2213
+ const sep2 = id.indexOf("::");
2214
+ if (sep2 > 0 && !realIds.has(id)) {
2215
+ const guessedPath = id.slice(0, sep2);
2216
+ const name = id.slice(sep2 + 2);
2217
+ const files = [guessedPath, ...candidatePaths(guessedPath)].filter((f) => realFiles.has(f));
2218
+ const resolvedSet = new Set(files.map((f) => throughBarrel(f, name)).filter((r) => r !== null));
2219
+ if (resolvedSet.size === 1) {
2220
+ const resolved = [...resolvedSet][0];
2221
+ remap.set(id, resolved);
2222
+ return resolved;
2223
+ }
2224
+ }
2225
+ return null;
2226
+ };
2227
+ applyRemap(resolveBarrelId);
2154
2228
  let droppedPlaceholders = 0;
2155
2229
  for (const extraction of extractions) {
2156
2230
  const before = extraction.nodes.length;
@@ -3046,4 +3120,4 @@ export {
3046
3120
  validateRules,
3047
3121
  checkRules
3048
3122
  };
3049
- //# sourceMappingURL=chunk-PXVI2L45.js.map
3123
+ //# sourceMappingURL=chunk-NS5HB65S.js.map