@suss/ir-core 0.19.0 → 0.21.0

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
@@ -5,6 +5,7 @@ import {
5
5
  ConfidenceSourceSchema,
6
6
  CorroborationSchema,
7
7
  DeployableUnitSchema,
8
+ EVERY_FIELD,
8
9
  FunctionCallSemanticsSchema,
9
10
  GraphqlOperationSemanticsSchema,
10
11
  GraphqlResolverSemanticsSchema,
@@ -16,6 +17,7 @@ import {
16
17
  SourceLocationSchema,
17
18
  StorageSemanticsSchema,
18
19
  TypeShapeSchema,
20
+ UnitInvocationSemanticsSchema,
19
21
  allBehaviors,
20
22
  behaviorOf,
21
23
  busIdentityKey,
@@ -34,9 +36,12 @@ import {
34
36
  routePathAdmits,
35
37
  semconvMappingOf,
36
38
  statesAnOrigin,
39
+ storageContainerLabel,
40
+ storageLabel,
37
41
  typeDefinitionKey,
42
+ unitIdentityKey,
38
43
  withDefinitionsInlined
39
- } from "./chunk-HSJYPBJU.js";
44
+ } from "./chunk-QHFMZPEG.js";
40
45
 
41
46
  // src/semconv.ts
42
47
  function semconvAttributes(binding) {
@@ -58,9 +63,22 @@ function semconvAttributes(binding) {
58
63
  }
59
64
 
60
65
  // src/boundaryKey.ts
66
+ function bindingIs(binding, name) {
67
+ return binding?.semantics.name === name;
68
+ }
61
69
  function boundaryKey(binding) {
62
70
  return behaviorOf(binding.semantics).identityKey(binding.semantics);
63
71
  }
72
+ function withRewrittenPaths(binding, rewrite) {
73
+ const behavior = behaviorOf(binding.semantics);
74
+ if (behavior.rewritePaths === void 0) {
75
+ return binding;
76
+ }
77
+ return {
78
+ ...binding,
79
+ semantics: behavior.rewritePaths(binding.semantics, rewrite)
80
+ };
81
+ }
64
82
  function groundedPairingKey(binding, deployedAs) {
65
83
  const behavior = behaviorOf(binding.semantics);
66
84
  const grounded = behavior.groundName?.(binding.semantics, deployedAs) ?? null;
@@ -115,6 +133,10 @@ function servesRequest(binding, method, path) {
115
133
  }
116
134
  return serves(binding.semantics, method, path);
117
135
  }
136
+ function withinScope(binding, scope) {
137
+ const within = behaviorOf(binding.semantics).withinScope;
138
+ return within === void 0 ? false : within(binding.semantics, scope);
139
+ }
118
140
 
119
141
  // src/dispatch.ts
120
142
  function dispatchByType(table, value) {
@@ -251,6 +273,57 @@ function referenceFromName(name) {
251
273
  return referenceOf(parseBoundaryName(name));
252
274
  }
253
275
 
276
+ // src/boundarySpelling.ts
277
+ function resourceNameIn(spelling) {
278
+ if (spelling.startsWith("arn:")) {
279
+ const segments2 = spelling.split(":");
280
+ return segments2[6] ?? segments2[5] ?? spelling;
281
+ }
282
+ const segments = spelling.split("/");
283
+ if (segments.length >= 4 && segments.length % 2 === 0) {
284
+ return segments[segments.length - 1] ?? spelling;
285
+ }
286
+ return spelling;
287
+ }
288
+ function spellingTokens(text) {
289
+ return text.toLowerCase().replace(/[{}]/g, " ").split(/[\s:#,()/]+/).filter((token) => token.length > 0);
290
+ }
291
+ function bindingTokens(binding) {
292
+ const tokens = new Set(spellingTokens(displayLabel(binding)));
293
+ for (const value of Object.values(binding.semantics)) {
294
+ if (typeof value === "string") {
295
+ for (const token of spellingTokens(value)) {
296
+ tokens.add(token);
297
+ }
298
+ }
299
+ }
300
+ for (const token of [...tokens]) {
301
+ for (const part of token.split(".")) {
302
+ tokens.add(part);
303
+ }
304
+ }
305
+ return tokens;
306
+ }
307
+ function namesBoundaryExactly(subject, binding) {
308
+ const wanted = new Set(spellingTokens(subject));
309
+ if (wanted.size === 0) {
310
+ return false;
311
+ }
312
+ const spelled = new Set(spellingTokens(displayLabel(binding)));
313
+ if (spelled.size !== wanted.size) {
314
+ return false;
315
+ }
316
+ return [...spelled].every((token) => wanted.has(token));
317
+ }
318
+ function namesBoundary(subject, binding) {
319
+ const wanted = spellingTokens(subject);
320
+ if (wanted.length === 0) {
321
+ return false;
322
+ }
323
+ const tokens = bindingTokens(binding);
324
+ return wanted.every((token) => tokens.has(token));
325
+ }
326
+
254
327
  // src/codeScope.ts
255
328
  function codeScopePath(raw) {
256
329
  return raw.trim().replace(/^\.\//, "").replace(/\/+$/, "");
@@ -264,26 +337,36 @@ function fileInCodeScope(file, scope) {
264
337
  return path === prefix || path.startsWith(`${prefix}/`);
265
338
  }
266
339
 
267
- // src/suppressions.ts
340
+ // src/relation.ts
268
341
  import { z } from "zod";
269
- var SuppressionSideSchema = z.object({
270
- summary: z.string().optional(),
271
- transitionId: z.string().optional()
342
+ var RelationSchema = z.enum([
343
+ "provides",
344
+ "reads",
345
+ "writes",
346
+ "invokes"
347
+ ]);
348
+ var EffectRelationSchema = RelationSchema.exclude(["provides"]);
349
+
350
+ // src/suppressions.ts
351
+ import { z as z2 } from "zod";
352
+ var SuppressionSideSchema = z2.object({
353
+ summary: z2.string().optional(),
354
+ transitionId: z2.string().optional()
272
355
  }).optional();
273
- var SuppressionRuleSchema = z.object({
356
+ var SuppressionRuleSchema = z2.object({
274
357
  /**
275
358
  * The finding kind to match, behavioural or intent. It is an open
276
359
  * string here because this package is below both IRs, and the loader
277
360
  * is what validates it against the published kind enums.
278
361
  */
279
- kind: z.string().optional(),
362
+ kind: z2.string().optional(),
280
363
  /**
281
364
  * Boundary as a human-readable key, e.g. "GET /pet/{petId}" or
282
365
  * "fn:@acme/api::getUser". REST keys are normalized via the same
283
366
  * path normalizer the checkers use, so `:id` and `{id}` compare
284
367
  * equal.
285
368
  */
286
- boundary: z.string().optional(),
369
+ boundary: z2.string().optional(),
287
370
  /**
288
371
  * Consumer-side discriminators, the narrowest useful match. These
289
372
  * mean something only for behavioural findings: a rule that
@@ -306,15 +389,15 @@ var SuppressionRuleSchema = z.object({
306
389
  * kind-only or boundary-only matches, which also silence future
307
390
  * regressions in that category.
308
391
  */
309
- scope: z.enum(["narrow", "broad"]).default("narrow"),
392
+ scope: z2.enum(["narrow", "broad"]).default("narrow"),
310
393
  /** Required human-written justification. */
311
- reason: z.string().min(1),
394
+ reason: z2.string().min(1),
312
395
  /** What to do when a finding matches. */
313
- effect: z.enum(["mark", "downgrade", "hide"]).default("mark")
396
+ effect: z2.enum(["mark", "downgrade", "hide"]).default("mark")
314
397
  }).strict();
315
- var SuppressionFileSchema = z.object({
316
- version: z.literal(1),
317
- rules: z.array(SuppressionRuleSchema)
398
+ var SuppressionFileSchema = z2.object({
399
+ version: z2.literal(1),
400
+ rules: z2.array(SuppressionRuleSchema)
318
401
  }).strict();
319
402
  function validateRule(rule) {
320
403
  if (rule.scope === "broad") {
@@ -604,6 +687,17 @@ function runtimeConfigBinding(opts) {
604
687
  recognition: opts.recognition
605
688
  };
606
689
  }
690
+ function unitInvocationBinding(opts) {
691
+ return {
692
+ transport: "invoke",
693
+ semantics: {
694
+ name: "unit-invocation",
695
+ deploymentTarget: opts.deploymentTarget,
696
+ instanceName: namedOrNull(opts.instanceName, "invoked unit")
697
+ },
698
+ recognition: opts.recognition
699
+ };
700
+ }
607
701
  function storageBinding(opts) {
608
702
  return {
609
703
  transport: opts.transport ?? opts.storageSystem,
@@ -646,11 +740,14 @@ export {
646
740
  ConfidenceSourceSchema,
647
741
  CorroborationSchema,
648
742
  DeployableUnitSchema,
743
+ EVERY_FIELD,
744
+ EffectRelationSchema,
649
745
  FunctionCallSemanticsSchema,
650
746
  GraphqlOperationSemanticsSchema,
651
747
  GraphqlResolverSemanticsSchema,
652
748
  MessageBusSemanticsSchema,
653
749
  MetricSemanticsSchema,
750
+ RelationSchema,
654
751
  RestSemanticsSchema,
655
752
  RuntimeConfigSemanticsSchema,
656
753
  SemanticsSchema,
@@ -659,7 +756,10 @@ export {
659
756
  SuppressionFileSchema,
660
757
  SuppressionRuleSchema,
661
758
  TypeShapeSchema,
759
+ UnitInvocationSemanticsSchema,
662
760
  applySuppressionsToFindings,
761
+ bindingIs,
762
+ bindingTokens,
663
763
  bodyShapesMatch,
664
764
  boundaryKey,
665
765
  boundaryLabel,
@@ -692,6 +792,8 @@ export {
692
792
  namePatternFromSub,
693
793
  namePatternKey,
694
794
  namesAgree,
795
+ namesBoundary,
796
+ namesBoundaryExactly,
695
797
  namesNothing,
696
798
  normalizePath,
697
799
  normalizeRuleBoundary,
@@ -706,6 +808,7 @@ export {
706
808
  referenceName,
707
809
  referenceOf,
708
810
  reportsUnpairedItself,
811
+ resourceNameIn,
709
812
  restBinding,
710
813
  routePathAdmits,
711
814
  ruleBoundaryMatchesKey,
@@ -713,9 +816,16 @@ export {
713
816
  semanticsAgree,
714
817
  semconvAttributes,
715
818
  servesRequest,
819
+ spellingTokens,
716
820
  statesAnOrigin,
717
821
  storageBinding,
822
+ storageContainerLabel,
823
+ storageLabel,
718
824
  typeDefinitionKey,
825
+ unitIdentityKey,
826
+ unitInvocationBinding,
719
827
  validateRule,
720
- withDefinitionsInlined
828
+ withDefinitionsInlined,
829
+ withRewrittenPaths,
830
+ withinScope
721
831
  };
@@ -155,6 +155,16 @@ declare const SemanticsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
155
155
  name: z.ZodLiteral<"metric">;
156
156
  metricSystem: z.ZodString;
157
157
  metricType: z.ZodNullable<z.ZodString>;
158
+ }, z.core.$strip>, z.ZodObject<{
159
+ deploymentTarget: z.ZodEnum<{
160
+ lambda: "lambda";
161
+ "ecs-task": "ecs-task";
162
+ container: "container";
163
+ "k8s-deployment": "k8s-deployment";
164
+ worker: "worker";
165
+ }>;
166
+ name: z.ZodLiteral<"unit-invocation">;
167
+ instanceName: z.ZodNullable<z.ZodString>;
158
168
  }, z.core.$strip>], "name">;
159
169
  type Semantics = z.infer<typeof SemanticsSchema>;
160
170
 
@@ -220,6 +230,22 @@ declare const StorageSemanticsSchema: z.ZodObject<{
220
230
  accessPath: z.ZodNullable<z.ZodString>;
221
231
  }, z.core.$strip>;
222
232
  type StorageSemantics = z.infer<typeof StorageSemanticsSchema>;
233
+ /**
234
+ * `postgresql:invoices`, `aws.dynamodb:editions#by-publication`. The
235
+ * pairing pass has no key to fall back on here, so a reader who types
236
+ * this back at `suss ask`, the pass that indexes accesses by it, and an
237
+ * intent doc that says which store a write reaches all read this one.
238
+ */
239
+ declare function storageLabel(semantics: StorageSemantics): string;
240
+ /**
241
+ * What an access writes for its columns when it asked for all of them,
242
+ * which is a query with no explicit projection. It covers every column
243
+ * rather than saying which one, so anything comparing column lists has
244
+ * to tell it apart from a list of columns.
245
+ */
246
+ declare const EVERY_FIELD = "*";
247
+ /** The store on its own, which a finding writes without the system. */
248
+ declare function storageContainerLabel(semantics: StorageSemantics): string;
223
249
 
224
250
  /**
225
251
  * @suss/ir-core schemas: primitives shared by every suss IR.
@@ -299,6 +325,10 @@ declare const SourceLocationSchema: z.ZodObject<{
299
325
  start: z.ZodNumber;
300
326
  end: z.ZodNumber;
301
327
  }, z.core.$strip>;
328
+ span: z.ZodOptional<z.ZodObject<{
329
+ start: z.ZodNumber;
330
+ end: z.ZodNumber;
331
+ }, z.core.$strip>>;
302
332
  exportName: z.ZodNullable<z.ZodString>;
303
333
  workspace: z.ZodOptional<z.ZodString>;
304
334
  }, z.core.$strip>;
@@ -362,6 +392,16 @@ declare const BoundaryBindingSchema: z.ZodObject<{
362
392
  name: z.ZodLiteral<"metric">;
363
393
  metricSystem: z.ZodString;
364
394
  metricType: z.ZodNullable<z.ZodString>;
395
+ }, z.core.$strip>, z.ZodObject<{
396
+ deploymentTarget: z.ZodEnum<{
397
+ lambda: "lambda";
398
+ "ecs-task": "ecs-task";
399
+ container: "container";
400
+ "k8s-deployment": "k8s-deployment";
401
+ worker: "worker";
402
+ }>;
403
+ name: z.ZodLiteral<"unit-invocation">;
404
+ instanceName: z.ZodNullable<z.ZodString>;
365
405
  }, z.core.$strip>], "name">;
366
406
  recognition: z.ZodString;
367
407
  }, z.core.$strip>;
@@ -451,4 +491,4 @@ declare const TypeShapeSchema: z.ZodType<TypeShape>;
451
491
  */
452
492
  declare function withDefinitionsInlined(shape: TypeShape, definitions: Record<string, TypeShape> | undefined, depth?: number, inProgress?: ReadonlySet<string>): TypeShape;
453
493
 
454
- export { BoundaryBindingSchema as B, ConfidenceInfoSchema as C, type DeployableUnit as D, type FunctionCallSemantics as F, type GraphqlOperationSemantics as G, type MessageBusSemantics as M, type RestSemantics as R, type Semantics as S, type TypeShape as T, ConfidenceLevelSchema as a, ConfidenceSourceSchema as b, CorroborationSchema as c, SourceLocationSchema as d, type MessageBusTechnology as e, DeployableUnitSchema as f, FunctionCallSemanticsSchema as g, GraphqlOperationSemanticsSchema as h, type GraphqlResolverSemantics as i, GraphqlResolverSemanticsSchema as j, MessageBusSemanticsSchema as k, RestSemanticsSchema as l, type RuntimeConfigSemantics as m, RuntimeConfigSemanticsSchema as n, SemanticsSchema as o, type StorageSemantics as p, StorageSemanticsSchema as q, TypeShapeSchema as r, ecsContainerInstanceName as s, methodsAgree as t, normalizePath as u, pathShape as v, routePathAdmits as w, typeDefinitionKey as x, withDefinitionsInlined as y };
494
+ export { withDefinitionsInlined as A, BoundaryBindingSchema as B, ConfidenceInfoSchema as C, type DeployableUnit as D, EVERY_FIELD as E, type FunctionCallSemantics as F, type GraphqlOperationSemantics as G, type MessageBusSemantics as M, type RestSemantics as R, type Semantics as S, type TypeShape as T, ConfidenceLevelSchema as a, ConfidenceSourceSchema as b, CorroborationSchema as c, SourceLocationSchema as d, type MessageBusTechnology as e, DeployableUnitSchema as f, FunctionCallSemanticsSchema as g, GraphqlOperationSemanticsSchema as h, type GraphqlResolverSemantics as i, GraphqlResolverSemanticsSchema as j, MessageBusSemanticsSchema as k, RestSemanticsSchema as l, type RuntimeConfigSemantics as m, RuntimeConfigSemanticsSchema as n, SemanticsSchema as o, type StorageSemantics as p, StorageSemanticsSchema as q, TypeShapeSchema as r, ecsContainerInstanceName as s, methodsAgree as t, normalizePath as u, pathShape as v, routePathAdmits as w, storageContainerLabel as x, storageLabel as y, typeDefinitionKey as z };
@@ -155,6 +155,16 @@ declare const SemanticsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
155
155
  name: z.ZodLiteral<"metric">;
156
156
  metricSystem: z.ZodString;
157
157
  metricType: z.ZodNullable<z.ZodString>;
158
+ }, z.core.$strip>, z.ZodObject<{
159
+ deploymentTarget: z.ZodEnum<{
160
+ lambda: "lambda";
161
+ "ecs-task": "ecs-task";
162
+ container: "container";
163
+ "k8s-deployment": "k8s-deployment";
164
+ worker: "worker";
165
+ }>;
166
+ name: z.ZodLiteral<"unit-invocation">;
167
+ instanceName: z.ZodNullable<z.ZodString>;
158
168
  }, z.core.$strip>], "name">;
159
169
  type Semantics = z.infer<typeof SemanticsSchema>;
160
170
 
@@ -220,6 +230,22 @@ declare const StorageSemanticsSchema: z.ZodObject<{
220
230
  accessPath: z.ZodNullable<z.ZodString>;
221
231
  }, z.core.$strip>;
222
232
  type StorageSemantics = z.infer<typeof StorageSemanticsSchema>;
233
+ /**
234
+ * `postgresql:invoices`, `aws.dynamodb:editions#by-publication`. The
235
+ * pairing pass has no key to fall back on here, so a reader who types
236
+ * this back at `suss ask`, the pass that indexes accesses by it, and an
237
+ * intent doc that says which store a write reaches all read this one.
238
+ */
239
+ declare function storageLabel(semantics: StorageSemantics): string;
240
+ /**
241
+ * What an access writes for its columns when it asked for all of them,
242
+ * which is a query with no explicit projection. It covers every column
243
+ * rather than saying which one, so anything comparing column lists has
244
+ * to tell it apart from a list of columns.
245
+ */
246
+ declare const EVERY_FIELD = "*";
247
+ /** The store on its own, which a finding writes without the system. */
248
+ declare function storageContainerLabel(semantics: StorageSemantics): string;
223
249
 
224
250
  /**
225
251
  * @suss/ir-core schemas: primitives shared by every suss IR.
@@ -299,6 +325,10 @@ declare const SourceLocationSchema: z.ZodObject<{
299
325
  start: z.ZodNumber;
300
326
  end: z.ZodNumber;
301
327
  }, z.core.$strip>;
328
+ span: z.ZodOptional<z.ZodObject<{
329
+ start: z.ZodNumber;
330
+ end: z.ZodNumber;
331
+ }, z.core.$strip>>;
302
332
  exportName: z.ZodNullable<z.ZodString>;
303
333
  workspace: z.ZodOptional<z.ZodString>;
304
334
  }, z.core.$strip>;
@@ -362,6 +392,16 @@ declare const BoundaryBindingSchema: z.ZodObject<{
362
392
  name: z.ZodLiteral<"metric">;
363
393
  metricSystem: z.ZodString;
364
394
  metricType: z.ZodNullable<z.ZodString>;
395
+ }, z.core.$strip>, z.ZodObject<{
396
+ deploymentTarget: z.ZodEnum<{
397
+ lambda: "lambda";
398
+ "ecs-task": "ecs-task";
399
+ container: "container";
400
+ "k8s-deployment": "k8s-deployment";
401
+ worker: "worker";
402
+ }>;
403
+ name: z.ZodLiteral<"unit-invocation">;
404
+ instanceName: z.ZodNullable<z.ZodString>;
365
405
  }, z.core.$strip>], "name">;
366
406
  recognition: z.ZodString;
367
407
  }, z.core.$strip>;
@@ -451,4 +491,4 @@ declare const TypeShapeSchema: z.ZodType<TypeShape>;
451
491
  */
452
492
  declare function withDefinitionsInlined(shape: TypeShape, definitions: Record<string, TypeShape> | undefined, depth?: number, inProgress?: ReadonlySet<string>): TypeShape;
453
493
 
454
- export { BoundaryBindingSchema as B, ConfidenceInfoSchema as C, type DeployableUnit as D, type FunctionCallSemantics as F, type GraphqlOperationSemantics as G, type MessageBusSemantics as M, type RestSemantics as R, type Semantics as S, type TypeShape as T, ConfidenceLevelSchema as a, ConfidenceSourceSchema as b, CorroborationSchema as c, SourceLocationSchema as d, type MessageBusTechnology as e, DeployableUnitSchema as f, FunctionCallSemanticsSchema as g, GraphqlOperationSemanticsSchema as h, type GraphqlResolverSemantics as i, GraphqlResolverSemanticsSchema as j, MessageBusSemanticsSchema as k, RestSemanticsSchema as l, type RuntimeConfigSemantics as m, RuntimeConfigSemanticsSchema as n, SemanticsSchema as o, type StorageSemantics as p, StorageSemanticsSchema as q, TypeShapeSchema as r, ecsContainerInstanceName as s, methodsAgree as t, normalizePath as u, pathShape as v, routePathAdmits as w, typeDefinitionKey as x, withDefinitionsInlined as y };
494
+ export { withDefinitionsInlined as A, BoundaryBindingSchema as B, ConfidenceInfoSchema as C, type DeployableUnit as D, EVERY_FIELD as E, type FunctionCallSemantics as F, type GraphqlOperationSemantics as G, type MessageBusSemantics as M, type RestSemantics as R, type Semantics as S, type TypeShape as T, ConfidenceLevelSchema as a, ConfidenceSourceSchema as b, CorroborationSchema as c, SourceLocationSchema as d, type MessageBusTechnology as e, DeployableUnitSchema as f, FunctionCallSemanticsSchema as g, GraphqlOperationSemanticsSchema as h, type GraphqlResolverSemantics as i, GraphqlResolverSemanticsSchema as j, MessageBusSemanticsSchema as k, RestSemanticsSchema as l, type RuntimeConfigSemantics as m, RuntimeConfigSemanticsSchema as n, SemanticsSchema as o, type StorageSemantics as p, StorageSemanticsSchema as q, TypeShapeSchema as r, ecsContainerInstanceName as s, methodsAgree as t, normalizePath as u, pathShape as v, routePathAdmits as w, storageContainerLabel as x, storageLabel as y, typeDefinitionKey as z };