@neat.is/core 0.5.0 → 0.5.1-dev.20260719

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.
@@ -1964,6 +1964,7 @@ function ensureFrontierNode(graph, host, ts) {
1964
1964
  }
1965
1965
  function upsertObservedEdge(graph, type, source, target, ts, isError = false, evidence) {
1966
1966
  if (!graph.hasNode(source) || !graph.hasNode(target)) return null;
1967
+ const grain = source.startsWith("file:") ? "file" : "service";
1967
1968
  const id = makeObservedEdgeId(type, source, target);
1968
1969
  if (graph.hasEdge(id)) {
1969
1970
  const existing = graph.getEdgeAttributes(id);
@@ -1980,7 +1981,9 @@ function upsertObservedEdge(graph, type, source, target, ts, isError = false, ev
1980
1981
  lastObserved: ts,
1981
1982
  callCount: newSpanCount,
1982
1983
  signal: newSignal,
1983
- confidence: confidenceForObservedSignal(newSignal)
1984
+ confidence: confidenceForObservedSignal(newSignal),
1985
+ grain
1986
+ // backfills legacy edges that predate ADR-142
1984
1987
  };
1985
1988
  graph.replaceEdgeAttributes(id, updated);
1986
1989
  return { edge: updated, created: false };
@@ -2000,6 +2003,7 @@ function upsertObservedEdge(graph, type, source, target, ts, isError = false, ev
2000
2003
  lastObserved: ts,
2001
2004
  callCount: 1,
2002
2005
  signal,
2006
+ grain,
2003
2007
  // Call-site evidence from span code.* semconv (file-awareness.md §4 + §6).
2004
2008
  // Only set when code.filepath was present on the span — never fabricated.
2005
2009
  ...evidence ? { evidence } : {}
@@ -4101,6 +4105,15 @@ async function parse4(serviceDir) {
4101
4105
  const config = parseConnectionString(urlMatch[1]);
4102
4106
  if (config) return [{ ...config, sourceFile: filePath }];
4103
4107
  }
4108
+ const urlEnvMatch = content.match(
4109
+ /(?:url|connectionString)\s*:\s*process\.env(?:\.([A-Za-z_$][\w$]*)|\[\s*['"]([^'"]+)['"]\s*\])/
4110
+ );
4111
+ if (urlEnvMatch) {
4112
+ const varName = urlEnvMatch[1] ?? urlEnvMatch[2];
4113
+ const resolved = varName ? await resolveEnvVar(serviceDir, varName) : null;
4114
+ const config = resolved ? parseConnectionString(resolved) : null;
4115
+ if (config) return [{ ...config, sourceFile: filePath }];
4116
+ }
4104
4117
  const hostMatch = content.match(/host\s*:\s*['"`]([^'"`]+)['"`]/);
4105
4118
  if (hostMatch) {
4106
4119
  const portMatch = content.match(/port\s*:\s*(\d+)/);
@@ -4153,6 +4166,15 @@ async function parse5(serviceDir) {
4153
4166
  const config = parseConnectionString(urlMatch[1]);
4154
4167
  if (config) return [{ ...config, sourceFile: filePath }];
4155
4168
  }
4169
+ const urlEnvMatch = content.match(
4170
+ /connection\s*:\s*process\.env(?:\.([A-Za-z_$][\w$]*)|\[\s*['"]([^'"]+)['"]\s*\])/
4171
+ );
4172
+ if (urlEnvMatch) {
4173
+ const varName = urlEnvMatch[1] ?? urlEnvMatch[2];
4174
+ const resolved = varName ? await resolveEnvVar(serviceDir, varName) : null;
4175
+ const config = resolved ? parseConnectionString(resolved) : null;
4176
+ if (config) return [{ ...config, sourceFile: filePath }];
4177
+ }
4156
4178
  const host = content.match(/host\s*:\s*['"`]([^'"`]+)['"`]/)?.[1];
4157
4179
  if (host) {
4158
4180
  const port = content.match(/port\s*:\s*(\d+)/)?.[1];
@@ -5724,6 +5746,16 @@ function constructorMatchesImport(name, ctx) {
5724
5746
  if (name === "createClient") return ctx.hasSupabaseJs;
5725
5747
  return ctx.hasSupabaseSsr;
5726
5748
  }
5749
+ var SUPABASE_CLIENT_ASSIGN_RE = /(?:const|let|var)\s+(\w+)\s*=\s*(?:await\s+)?(createClient|createServerClient|createBrowserClient)\s*\(/g;
5750
+ function supabaseClientVars(content, ctx) {
5751
+ const vars = /* @__PURE__ */ new Set();
5752
+ SUPABASE_CLIENT_ASSIGN_RE.lastIndex = 0;
5753
+ let m;
5754
+ while ((m = SUPABASE_CLIENT_ASSIGN_RE.exec(content)) !== null) {
5755
+ if (constructorMatchesImport(m[2], ctx)) vars.add(m[1]);
5756
+ }
5757
+ return vars;
5758
+ }
5727
5759
  function supabaseEndpointsFromFile(file, serviceDir) {
5728
5760
  const ctx = readImports2(file.content);
5729
5761
  if (!ctx.hasSupabaseJs && !ctx.hasSupabaseSsr) return [];
@@ -5756,6 +5788,34 @@ function supabaseEndpointsFromFile(file, serviceDir) {
5756
5788
  }
5757
5789
  });
5758
5790
  }
5791
+ const clientVars = supabaseClientVars(file.content, ctx);
5792
+ for (const clientVar of clientVars) {
5793
+ const accessRe = new RegExp(
5794
+ `\\b${clientVar}\\s*\\.\\s*(from|rpc)\\s*\\(\\s*['"\`]([\\w.-]+)['"\`]`,
5795
+ "g"
5796
+ );
5797
+ let am;
5798
+ while ((am = accessRe.exec(file.content)) !== null) {
5799
+ const kind = am[1] === "rpc" ? "supabase-rpc" : "supabase-table";
5800
+ const resource = am[2];
5801
+ const key = `${kind}/${resource}`;
5802
+ if (seen.has(key)) continue;
5803
+ seen.add(key);
5804
+ const line = lineOf(file.content, am[0]);
5805
+ out.push({
5806
+ infraId: infraId6(kind, resource),
5807
+ name: resource,
5808
+ kind,
5809
+ edgeType: "CALLS",
5810
+ confidenceKind: "verified-call-site",
5811
+ evidence: {
5812
+ file: path30.relative(serviceDir, file.path),
5813
+ line,
5814
+ snippet: snippet(file.content, line)
5815
+ }
5816
+ });
5817
+ }
5818
+ }
5759
5819
  return out;
5760
5820
  }
5761
5821
 
@@ -9301,4 +9361,4 @@ export {
9301
9361
  recordConnectorPoll,
9302
9362
  buildApi
9303
9363
  };
9304
- //# sourceMappingURL=chunk-QQDZSIY3.js.map
9364
+ //# sourceMappingURL=chunk-BI3XKGVG.js.map