@neat.is/types 0.7.4 → 0.7.6

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.cjs CHANGED
@@ -55,6 +55,7 @@ __export(index_exports, {
55
55
  EdgeTypeSchema: () => EdgeTypeSchema,
56
56
  ErrorEventSchema: () => ErrorEventSchema,
57
57
  ExtractionCoverageSchema: () => ExtractionCoverageSchema,
58
+ FieldGuardRuleSchema: () => FieldGuardRuleSchema,
58
59
  FileNodeSchema: () => FileNodeSchema,
59
60
  FrontierNodeSchema: () => FrontierNodeSchema,
60
61
  GraphDiffResultSchema: () => GraphDiffResultSchema,
@@ -101,6 +102,7 @@ __export(index_exports, {
101
102
  SearchMatchSchema: () => SearchMatchSchema,
102
103
  SearchResponseSchema: () => SearchResponseSchema,
103
104
  SerializedGraphSchema: () => SerializedGraphSchema,
105
+ ServerActionNodeSchema: () => ServerActionNodeSchema,
104
106
  ServiceNodeSchema: () => ServiceNodeSchema,
105
107
  SingleProjectResponseSchema: () => SingleProjectResponseSchema,
106
108
  SpanAttributesSchema: () => SpanAttributesSchema,
@@ -137,11 +139,13 @@ __export(index_exports, {
137
139
  parseGrpcMethodId: () => parseGrpcMethodId,
138
140
  parseInfraId: () => parseInfraId,
139
141
  parseRouteId: () => parseRouteId,
142
+ parseServerActionId: () => parseServerActionId,
140
143
  parseServiceId: () => parseServiceId,
141
144
  parseSymbolId: () => parseSymbolId,
142
145
  parseWebsocketChannelId: () => parseWebsocketChannelId,
143
146
  passesExtractedFloor: () => passesExtractedFloor,
144
147
  routeId: () => routeId,
148
+ serverActionId: () => serverActionId,
145
149
  serviceId: () => serviceId,
146
150
  symbolId: () => symbolId,
147
151
  websocketChannelId: () => websocketChannelId
@@ -181,7 +185,17 @@ var EdgeType = {
181
185
  // fuzzy-matched. A parent that resolves to nothing (external package,
182
186
  // re-export chain, an interface, which is not a SymbolNode) emits no edge.
183
187
  INHERITS: "INHERITS",
184
- IMPLEMENTS: "IMPLEMENTS"
188
+ IMPLEMENTS: "IMPLEMENTS",
189
+ // Static foreign-key reference between two table InfraNodes (ADR-161).
190
+ // `infra:sql-table:<child> ──REFERENCES──▶ infra:sql-table:<parent>` records
191
+ // that the child table declares a foreign key into the parent — the data-axis
192
+ // sibling of INHERITS/IMPLEMENTS. Both endpoints resolve to the DATABASE table
193
+ // name via `infraId('sql-table', name)` — the same node the column/table
194
+ // extractors and OTLP already target — reproduced verbatim per ORM, so the FK
195
+ // edge lands on the fused table node rather than a code-model twin. EXTRACTED,
196
+ // minted only when the parent resolves to a real declared table without
197
+ // guessing; a computed/unresolved reference emits no edge.
198
+ REFERENCES: "REFERENCES"
185
199
  };
186
200
  var NodeType = {
187
201
  ServiceNode: "ServiceNode",
@@ -242,7 +256,22 @@ var NodeType = {
242
256
  // file (observed-first edges, one grain finer than §4 file grain). The node is
243
257
  // language-neutral; the per-language tree-sitter extractor is the adapter. See
244
258
  // docs/contracts/static-extraction.md and docs/contracts/file-awareness.md §1.
245
- SymbolNode: "SymbolNode"
259
+ SymbolNode: "SymbolNode",
260
+ // A Next.js Server Action at (service, module, exportName) granularity
261
+ // (ADR-168). A Server Action is the RPC boundary of an App Router app: the
262
+ // client posts to it, Next serialises the call to an opaque `Next-Action`
263
+ // hash, and it runs on the server. At HTTP grain the whole surface collapses
264
+ // onto one POST edge — like a GraphQL operation — so this node recovers the
265
+ // per-action topology the client actually names. It is EXTRACTED-first: the
266
+ // static extractor mints one per exported action from a `"use server"`
267
+ // directive (module-level or in-body) and the file owns it through a
268
+ // `file ──CONTAINS──▶ action` edge; a client reference to the imported action
269
+ // binding lands a `file ──CALLS──▶ action` edge, so the client→action call
270
+ // path is a real edge the reasoning core walks like any other. OBSERVED
271
+ // fusion is deferred (the `Next-Action` hash carries no action name), the
272
+ // same posture GraphQLOperationNode took before its static extractor. See
273
+ // docs/contracts/static-extraction.md and docs/contracts/file-awareness.md.
274
+ ServerActionNode: "ServerActionNode"
246
275
  };
247
276
  var NodeTypeSchema = import_zod.z.enum([
248
277
  NodeType.ServiceNode,
@@ -255,7 +284,8 @@ var NodeTypeSchema = import_zod.z.enum([
255
284
  NodeType.GraphQLOperationNode,
256
285
  NodeType.GrpcMethodNode,
257
286
  NodeType.WebSocketChannelNode,
258
- NodeType.SymbolNode
287
+ NodeType.SymbolNode,
288
+ NodeType.ServerActionNode
259
289
  ]);
260
290
 
261
291
  // src/nodes.ts
@@ -280,7 +310,8 @@ var EdgeTypeSchema = import_zod2.z.enum([
280
310
  EdgeType.CONTAINS,
281
311
  EdgeType.IMPORTS,
282
312
  EdgeType.INHERITS,
283
- EdgeType.IMPLEMENTS
313
+ EdgeType.IMPLEMENTS,
314
+ EdgeType.REFERENCES
284
315
  ]);
285
316
  var EdgeEvidenceSchema = import_zod2.z.object({
286
317
  file: import_zod2.z.string(),
@@ -425,7 +456,15 @@ var ConfigNodeSchema = import_zod3.z.object({
425
456
  var ColumnAttrSchema = import_zod3.z.object({
426
457
  name: import_zod3.z.string(),
427
458
  provenances: import_zod3.z.array(ProvenanceSchema),
428
- confidence: import_zod3.z.number().min(0).max(1)
459
+ confidence: import_zod3.z.number().min(0).max(1),
460
+ // Which SDK wrote this field, for a `firestore-collection` node (ADR-167): a
461
+ // deduped set, the write-side analog of `provenances`. `client` =
462
+ // firebase/firestore (governed by security rules), `admin` =
463
+ // firebase-admin/firestore (bypasses rules entirely). This is the seam the
464
+ // field-guard policy (ADR-169) joins on — client-written fields must be guarded
465
+ // — and is absent on a non-Firestore column. Optional growth, no version step
466
+ // (`kind` is an open string); folded by `foldSdkWrites`, never `foldColumns`.
467
+ sdkWrites: import_zod3.z.array(import_zod3.z.enum(["client", "admin"])).optional()
429
468
  });
430
469
  var InfraNodeSchema = import_zod3.z.object({
431
470
  id: import_zod3.z.string(),
@@ -438,7 +477,15 @@ var InfraNodeSchema = import_zod3.z.object({
438
477
  // Absent on a non-table InfraNode (a project node, a queue, a route). Optional
439
478
  // schema growth (ADR-031); ADR-157 stamps the snapshot version because the field
440
479
  // records a new grain the graph can now carry. See docs/contracts/schema.md.
441
- columns: import_zod3.z.array(ColumnAttrSchema).optional()
480
+ columns: import_zod3.z.array(ColumnAttrSchema).optional(),
481
+ // Guard set folded from a checked-in declared policy artifact (ADR-169): for a
482
+ // `firestore-collection` node, the fields `firestore.rules` explicitly names on
483
+ // the client write path, read by the standalone rules producer. The
484
+ // `field-guard` policy asserts every client-written column appears here. Absent
485
+ // ⇒ the collection's guard is indeterminate ⇒ the check stays silent. Optional
486
+ // growth (ADR-031); no version step — it only appears on nodes a post-ADR-169
487
+ // pass folds it onto.
488
+ guardedFields: import_zod3.z.array(import_zod3.z.string()).optional()
442
489
  });
443
490
  var FrontierNodeSchema = import_zod3.z.object({
444
491
  id: import_zod3.z.string(),
@@ -531,6 +578,17 @@ var SymbolNodeSchema = import_zod3.z.object({
531
578
  relPath: import_zod3.z.string(),
532
579
  discoveredVia: DiscoveredViaSchema.optional()
533
580
  });
581
+ var ServerActionNodeSchema = import_zod3.z.object({
582
+ id: import_zod3.z.string(),
583
+ type: import_zod3.z.literal(NodeType.ServerActionNode),
584
+ name: import_zod3.z.string(),
585
+ service: import_zod3.z.string(),
586
+ module: import_zod3.z.string(),
587
+ exportName: import_zod3.z.string(),
588
+ path: import_zod3.z.string().optional(),
589
+ line: import_zod3.z.number().int().nonnegative().optional(),
590
+ discoveredVia: DiscoveredViaSchema.optional()
591
+ });
534
592
  var GraphNodeSchema = import_zod3.z.discriminatedUnion("type", [
535
593
  ServiceNodeSchema,
536
594
  DatabaseNodeSchema,
@@ -542,7 +600,8 @@ var GraphNodeSchema = import_zod3.z.discriminatedUnion("type", [
542
600
  GraphQLOperationNodeSchema,
543
601
  GrpcMethodNodeSchema,
544
602
  WebSocketChannelNodeSchema,
545
- SymbolNodeSchema
603
+ SymbolNodeSchema,
604
+ ServerActionNodeSchema
546
605
  ]);
547
606
 
548
607
  // src/events.ts
@@ -695,6 +754,7 @@ var GRAPHQL_OP_PREFIX = "graphql:";
695
754
  var GRPC_METHOD_PREFIX = "grpc:";
696
755
  var WEBSOCKET_CHANNEL_PREFIX = "ws:";
697
756
  var SYMBOL_PREFIX = "symbol:";
757
+ var SERVER_ACTION_PREFIX = "action:";
698
758
  var ENV_UNKNOWN = "unknown";
699
759
  function serviceId(name, env) {
700
760
  if (env === void 0 || env === ENV_UNKNOWN) return `${SERVICE_PREFIX}${name}`;
@@ -842,6 +902,23 @@ function parseSymbolId(id) {
842
902
  if (qualname.length === 0) return null;
843
903
  return { service, relPath, qualname, ...disambiguator !== void 0 ? { disambiguator } : {} };
844
904
  }
905
+ function serverActionId(service, module2, exportName) {
906
+ return `${SERVER_ACTION_PREFIX}${service}:${module2}#${exportName}`;
907
+ }
908
+ function parseServerActionId(id) {
909
+ if (!id.startsWith(SERVER_ACTION_PREFIX)) return null;
910
+ const rest = id.slice(SERVER_ACTION_PREFIX.length);
911
+ const colon = rest.indexOf(":");
912
+ if (colon === -1) return null;
913
+ const service = rest.slice(0, colon);
914
+ const tail = rest.slice(colon + 1);
915
+ const hash = tail.lastIndexOf("#");
916
+ if (hash === -1) return null;
917
+ const module2 = tail.slice(0, hash);
918
+ const exportName = tail.slice(hash + 1);
919
+ if (service.length === 0 || module2.length === 0 || exportName.length === 0) return null;
920
+ return { service, module: module2, exportName };
921
+ }
845
922
  var EDGE_ARROW = "->";
846
923
  function extractedEdgeId(source, target, type) {
847
924
  return `${type}:${source}${EDGE_ARROW}${target}`;
@@ -928,12 +1005,29 @@ var BlastRadiusRuleSchema = import_zod6.z.object({
928
1005
  // default (10) when omitted.
929
1006
  depth: import_zod6.z.number().int().positive().optional()
930
1007
  });
1008
+ var FieldGuardRuleSchema = import_zod6.z.object({
1009
+ type: import_zod6.z.literal("field-guard"),
1010
+ // Node type the rule governs. InfraNode for the Firestore instance.
1011
+ nodeType: NodeTypeSchema,
1012
+ // Optional narrowing on InfraNode's free-string `kind` sub-type, so the rule
1013
+ // applies to `firestore-collection` nodes without governing every InfraNode.
1014
+ nodeKind: import_zod6.z.string().optional(),
1015
+ // Set A — the named selector the evaluator resolves into the "must be covered"
1016
+ // set. 'client-written-columns' reads ColumnAttr whose sdkWrites includes
1017
+ // 'client'. A new instance adds a value here plus a resolver branch.
1018
+ subjectSet: import_zod6.z.enum(["client-written-columns"]),
1019
+ // Set B — the covering set: the node attribute (a string[]) whose members must
1020
+ // include all of set A. 'guardedFields' for Firestore. Absent ⇒ indeterminate
1021
+ // ⇒ silent.
1022
+ guardSet: import_zod6.z.string()
1023
+ });
931
1024
  var PolicyRuleSchema = import_zod6.z.discriminatedUnion("type", [
932
1025
  StructuralRuleSchema,
933
1026
  CompatibilityRuleSchema,
934
1027
  ProvenanceRuleSchema,
935
1028
  OwnershipRuleSchema,
936
- BlastRadiusRuleSchema
1029
+ BlastRadiusRuleSchema,
1030
+ FieldGuardRuleSchema
937
1031
  ]);
938
1032
  var PolicySchema = import_zod6.z.object({
939
1033
  // Unique within the file. Duplicates fail PolicyFileSchema.parse.
@@ -992,7 +1086,7 @@ var ApplicablePolicySchema = import_zod6.z.object({
992
1086
  // from policy.onViolation or the severity default. Shown for awareness only;
993
1087
  // the soft guardrail never acts on it.
994
1088
  onViolation: PolicyActionSchema,
995
- ruleType: import_zod6.z.enum(["structural", "compatibility", "provenance", "ownership", "blast-radius"]),
1089
+ ruleType: import_zod6.z.enum(["structural", "compatibility", "provenance", "ownership", "blast-radius", "field-guard"]),
996
1090
  match: import_zod6.z.enum(["subject", "region"]),
997
1091
  // Human-readable reason the policy applies here — rides into agent context.
998
1092
  reason: import_zod6.z.string().min(1)
@@ -1011,7 +1105,7 @@ var PolicyViolationSchema = import_zod6.z.object({
1011
1105
  // Resolved at evaluation time — either the explicit policy.onViolation or
1012
1106
  // the severity-derived default per ADR-044.
1013
1107
  onViolation: PolicyActionSchema,
1014
- ruleType: import_zod6.z.enum(["structural", "compatibility", "provenance", "ownership", "blast-radius"]),
1108
+ ruleType: import_zod6.z.enum(["structural", "compatibility", "provenance", "ownership", "blast-radius", "field-guard"]),
1015
1109
  subject: import_zod6.z.object({
1016
1110
  nodeId: import_zod6.z.string().optional(),
1017
1111
  edgeId: import_zod6.z.string().optional(),
@@ -1360,6 +1454,7 @@ function passesExtractedFloor(confidence) {
1360
1454
  EdgeTypeSchema,
1361
1455
  ErrorEventSchema,
1362
1456
  ExtractionCoverageSchema,
1457
+ FieldGuardRuleSchema,
1363
1458
  FileNodeSchema,
1364
1459
  FrontierNodeSchema,
1365
1460
  GraphDiffResultSchema,
@@ -1406,6 +1501,7 @@ function passesExtractedFloor(confidence) {
1406
1501
  SearchMatchSchema,
1407
1502
  SearchResponseSchema,
1408
1503
  SerializedGraphSchema,
1504
+ ServerActionNodeSchema,
1409
1505
  ServiceNodeSchema,
1410
1506
  SingleProjectResponseSchema,
1411
1507
  SpanAttributesSchema,
@@ -1442,11 +1538,13 @@ function passesExtractedFloor(confidence) {
1442
1538
  parseGrpcMethodId,
1443
1539
  parseInfraId,
1444
1540
  parseRouteId,
1541
+ parseServerActionId,
1445
1542
  parseServiceId,
1446
1543
  parseSymbolId,
1447
1544
  parseWebsocketChannelId,
1448
1545
  passesExtractedFloor,
1449
1546
  routeId,
1547
+ serverActionId,
1450
1548
  serviceId,
1451
1549
  symbolId,
1452
1550
  websocketChannelId