@suss/ir-core 0.33.0 → 0.34.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/README.md +30 -30
- package/dist/{chunk-N564FH5U.js → chunk-WOXA5GBL.js} +251 -208
- package/dist/index.cjs +335 -248
- package/dist/index.d.cts +399 -355
- package/dist/index.d.ts +399 -355
- package/dist/index.js +68 -26
- package/dist/{schemas-CIns0fqF.d.cts → schemas-CghZNwSE.d.cts} +88 -81
- package/dist/{schemas-CIns0fqF.d.ts → schemas-CghZNwSE.d.ts} +88 -81
- package/dist/schemas.cjs +248 -208
- package/dist/schemas.d.cts +1 -1
- package/dist/schemas.d.ts +1 -1
- package/dist/schemas.js +1 -1
- package/package.json +2 -2
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// src/schemas.ts
|
|
2
|
-
import { z as
|
|
2
|
+
import { z as z13 } from "zod";
|
|
3
3
|
|
|
4
4
|
// src/semantics/registry.ts
|
|
5
|
-
import { z as
|
|
5
|
+
import { z as z12 } from "zod";
|
|
6
6
|
|
|
7
7
|
// src/semantics/functionCall.ts
|
|
8
8
|
import { z } from "zod";
|
|
@@ -23,6 +23,9 @@ function unitIdentityKey(deploymentTarget, instanceName) {
|
|
|
23
23
|
function metricIdentityKey(metricSystem, metricType) {
|
|
24
24
|
return `metric:${metricSystem} ${metricType}`;
|
|
25
25
|
}
|
|
26
|
+
function ioIdentityKey(target) {
|
|
27
|
+
return `io:${target}`;
|
|
28
|
+
}
|
|
26
29
|
|
|
27
30
|
// src/semantics/definition.ts
|
|
28
31
|
function defineBoundarySemantics(definition) {
|
|
@@ -33,10 +36,11 @@ function defineBoundarySemantics(definition) {
|
|
|
33
36
|
var FunctionCallSemanticsSchema = z.object({
|
|
34
37
|
name: z.literal("function-call"),
|
|
35
38
|
/**
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* module path
|
|
39
|
-
*
|
|
39
|
+
* Where the function lives inside this repository. It is either the
|
|
40
|
+
* name of a module the project lists in `suss.json`, such as
|
|
41
|
+
* `"billing"`, or a module path, such as the file a server action is
|
|
42
|
+
* written in. A name has no separator in it and a path always does.
|
|
43
|
+
* Packs that don't do cross-module pairing can leave it unset.
|
|
40
44
|
*/
|
|
41
45
|
module: z.string().optional(),
|
|
42
46
|
/** Named export within the module, when applicable. */
|
|
@@ -61,35 +65,38 @@ var FunctionCallSemanticsSchema = z.object({
|
|
|
61
65
|
*/
|
|
62
66
|
exportPath: z.array(z.string()).optional()
|
|
63
67
|
});
|
|
68
|
+
function isModuleName(module) {
|
|
69
|
+
return !module.includes("/") && !module.includes("\\");
|
|
70
|
+
}
|
|
64
71
|
var functionCallSemantics = defineBoundarySemantics({
|
|
65
72
|
name: "function-call",
|
|
66
73
|
schema: FunctionCallSemanticsSchema,
|
|
67
|
-
// A call
|
|
68
|
-
//
|
|
74
|
+
// A call inside the process does not produce a span, and the
|
|
75
|
+
// conventions have no attributes for it.
|
|
69
76
|
semconv: {},
|
|
70
77
|
behavior: {
|
|
71
|
-
/** A call returns a value,
|
|
78
|
+
/** A call returns a value, with no status. */
|
|
72
79
|
exchangesHttpResponses: false,
|
|
73
80
|
leavesTheProcess: false,
|
|
74
81
|
reportsUnpairedItself: false,
|
|
75
82
|
/**
|
|
76
|
-
* In-repo units
|
|
77
|
-
*
|
|
78
|
-
*
|
|
83
|
+
* In-repo units such as components have no key on purpose. They
|
|
84
|
+
* pair through call edges instead of the keyed pass, so a missing
|
|
85
|
+
* key does not make them unreachable.
|
|
79
86
|
*/
|
|
80
87
|
canPair: () => true,
|
|
81
|
-
/**
|
|
82
|
-
* `"fn:<package>::<exportPath>"` when both are set, and
|
|
83
|
-
* `"fn:<module>::<exportName>"` for an in-repo unit that states its
|
|
84
|
-
* module, the way a server action does. Components and bare
|
|
85
|
-
* handlers state neither and have no key at all.
|
|
86
|
-
*/
|
|
87
88
|
rewritePaths(semantics, rewrite) {
|
|
88
|
-
if (semantics.module === void 0) {
|
|
89
|
+
if (semantics.module === void 0 || isModuleName(semantics.module)) {
|
|
89
90
|
return semantics;
|
|
90
91
|
}
|
|
91
92
|
return { ...semantics, module: rewrite(semantics.module) };
|
|
92
93
|
},
|
|
94
|
+
/**
|
|
95
|
+
* `"fn:<package>::<exportPath>"` when both are set, and
|
|
96
|
+
* `"fn:<module>::<exportName>"` for an in-repo unit that gives its
|
|
97
|
+
* module, as a server action does. Components and plain handlers
|
|
98
|
+
* give neither and have no key.
|
|
99
|
+
*/
|
|
93
100
|
identityKey(semantics) {
|
|
94
101
|
if (semantics.package !== void 0 && semantics.exportPath !== void 0 && semantics.exportPath.length > 0) {
|
|
95
102
|
return fnIdentityKey(semantics.package, semantics.exportPath);
|
|
@@ -120,15 +127,15 @@ var graphqlOperationSemantics = defineBoundarySemantics({
|
|
|
120
127
|
behavior: {
|
|
121
128
|
/**
|
|
122
129
|
* An operation gets a data-and-errors document back, which the
|
|
123
|
-
* GraphQL contract checker reads. Status codes
|
|
130
|
+
* GraphQL contract checker reads. Status codes do not apply.
|
|
124
131
|
*/
|
|
125
132
|
exchangesHttpResponses: false,
|
|
126
133
|
leavesTheProcess: true,
|
|
127
134
|
reportsUnpairedItself: false,
|
|
128
135
|
identityKey: () => null,
|
|
129
|
-
/**
|
|
136
|
+
/** No key on purpose. The dedicated pass pairs an operation by its document. */
|
|
130
137
|
canPair: () => true,
|
|
131
|
-
/**
|
|
138
|
+
/** `query GetUser`. Only for display, since the contract checker does the pairing. */
|
|
132
139
|
displayLabel(semantics) {
|
|
133
140
|
return `${semantics.operationType} ${semantics.operationName ?? "<anonymous>"}`;
|
|
134
141
|
}
|
|
@@ -151,14 +158,14 @@ var GraphqlResolverSemanticsSchema = z3.object({
|
|
|
151
158
|
var graphqlResolverSemantics = defineBoundarySemantics({
|
|
152
159
|
name: "graphql-resolver",
|
|
153
160
|
schema: GraphqlResolverSemanticsSchema,
|
|
154
|
-
// The conventions
|
|
155
|
-
// resolver the server ran for one field of it.
|
|
161
|
+
// The conventions describe the operation a client sent. They have no
|
|
162
|
+
// attribute for the resolver the server ran for one field of it.
|
|
156
163
|
semconv: {},
|
|
157
164
|
behavior: {
|
|
158
|
-
/** A resolver returns a field value,
|
|
165
|
+
/** A resolver returns a field value, with no status. */
|
|
159
166
|
exchangesHttpResponses: false,
|
|
160
|
-
// A
|
|
161
|
-
// server calls
|
|
167
|
+
// A resolver runs because a client outside the process sent a query,
|
|
168
|
+
// even though the server calls it in its own process.
|
|
162
169
|
leavesTheProcess: true,
|
|
163
170
|
reportsUnpairedItself: false,
|
|
164
171
|
/**
|
|
@@ -175,8 +182,32 @@ var graphqlResolverSemantics = defineBoundarySemantics({
|
|
|
175
182
|
}
|
|
176
183
|
});
|
|
177
184
|
|
|
178
|
-
// src/semantics/
|
|
185
|
+
// src/semantics/io.ts
|
|
179
186
|
import { z as z4 } from "zod";
|
|
187
|
+
var IoSemanticsSchema = z4.object({
|
|
188
|
+
name: z4.literal("io"),
|
|
189
|
+
/** The stream, such as `stdout` or `stderr`. Null when the source does not say which. */
|
|
190
|
+
target: z4.string().nullable()
|
|
191
|
+
});
|
|
192
|
+
var ioSemantics = defineBoundarySemantics({
|
|
193
|
+
name: "io",
|
|
194
|
+
schema: IoSemanticsSchema,
|
|
195
|
+
// The semantic conventions have no attribute for a process's own streams.
|
|
196
|
+
semconv: {},
|
|
197
|
+
behavior: {
|
|
198
|
+
exchangesHttpResponses: false,
|
|
199
|
+
leavesTheProcess: true,
|
|
200
|
+
reportsUnpairedItself: false,
|
|
201
|
+
identityKey(semantics) {
|
|
202
|
+
return semantics.target === null ? null : ioIdentityKey(semantics.target);
|
|
203
|
+
},
|
|
204
|
+
// Nothing declares the reading side, so a write has nothing to meet.
|
|
205
|
+
canPair: () => false
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
// src/semantics/messageBus.ts
|
|
210
|
+
import { z as z5 } from "zod";
|
|
180
211
|
|
|
181
212
|
// src/channel.ts
|
|
182
213
|
function parseChannel(channel) {
|
|
@@ -202,12 +233,11 @@ function channelsPair(a, b) {
|
|
|
202
233
|
}
|
|
203
234
|
|
|
204
235
|
// src/semantics/messageBus.ts
|
|
205
|
-
var MessageBusSemanticsSchema =
|
|
206
|
-
name:
|
|
207
|
-
messageBus:
|
|
208
|
-
// The conventions
|
|
209
|
-
// underscore and one with a dot
|
|
210
|
-
// not a typo.
|
|
236
|
+
var MessageBusSemanticsSchema = z5.object({
|
|
237
|
+
name: z5.literal("message-bus"),
|
|
238
|
+
messageBus: z5.enum([
|
|
239
|
+
// The conventions write these two AWS buses differently, one with an
|
|
240
|
+
// underscore and one with a dot. Both are as the conventions give them.
|
|
211
241
|
"aws_sqs",
|
|
212
242
|
"aws.sns",
|
|
213
243
|
"s3",
|
|
@@ -226,12 +256,13 @@ var MessageBusSemanticsSchema = z4.object({
|
|
|
226
256
|
"cloudflare-tail"
|
|
227
257
|
]),
|
|
228
258
|
/**
|
|
229
|
-
*
|
|
230
|
-
* a subject pattern, or `bus#detailType`. Null when this
|
|
231
|
-
* not say which channel, as with a send whose queue the
|
|
232
|
-
*
|
|
259
|
+
* A stable channel identifier: a CloudFormation logical id, a queue or
|
|
260
|
+
* topic name, a subject pattern, or `bus#detailType`. Null when this
|
|
261
|
+
* source does not say which channel, as with a send whose queue the
|
|
262
|
+
* code picks at run time, or a receive whose queue is set in the
|
|
263
|
+
* event-source mapping.
|
|
233
264
|
*/
|
|
234
|
-
channel:
|
|
265
|
+
channel: z5.string().min(1).nullable()
|
|
235
266
|
});
|
|
236
267
|
var messageBusSemantics = defineBoundarySemantics({
|
|
237
268
|
name: "message-bus",
|
|
@@ -245,25 +276,26 @@ var messageBusSemantics = defineBoundarySemantics({
|
|
|
245
276
|
exchangesHttpResponses: false,
|
|
246
277
|
leavesTheProcess: true,
|
|
247
278
|
/**
|
|
248
|
-
* `checkMessageBus`
|
|
249
|
-
*
|
|
279
|
+
* `checkMessageBus` reports every channel, unused ones included, so
|
|
280
|
+
* the generic unmatched list leaves them out.
|
|
250
281
|
*/
|
|
251
282
|
reportsUnpairedItself: true,
|
|
252
283
|
/**
|
|
253
|
-
* A channel
|
|
254
|
-
*
|
|
255
|
-
* channel
|
|
284
|
+
* A channel that is null here can still pair. The dedicated pass
|
|
285
|
+
* follows environment variable chains before comparing, so a
|
|
286
|
+
* consumer whose channel is set at run time meets the template that
|
|
287
|
+
* declares it.
|
|
256
288
|
*/
|
|
257
289
|
canPair: () => true,
|
|
258
290
|
/**
|
|
259
291
|
* `"bus:<messageBus> <subject>"`, or null when the channel is null
|
|
260
292
|
* or its subject is empty.
|
|
261
293
|
*
|
|
262
|
-
* The key has the subject
|
|
263
|
-
*
|
|
294
|
+
* The key has the subject and leaves out the bus, so a template
|
|
295
|
+
* writing `default#order.placed` and a handler writing
|
|
264
296
|
* `order.placed` land in one bucket, where `sidesAgree` compares the
|
|
265
|
-
* buses.
|
|
266
|
-
*
|
|
297
|
+
* buses. Keying on the bus would separate a side that cannot know
|
|
298
|
+
* its bus from the side that can.
|
|
267
299
|
*
|
|
268
300
|
* The bus technology stays in, because a queue and an event router
|
|
269
301
|
* are different destinations even with the same subject. Case stays
|
|
@@ -286,9 +318,9 @@ var messageBusSemantics = defineBoundarySemantics({
|
|
|
286
318
|
return channelsPair(a.channel, b.channel);
|
|
287
319
|
},
|
|
288
320
|
/**
|
|
289
|
-
* The whole channel, bus included,
|
|
290
|
-
*
|
|
291
|
-
*
|
|
321
|
+
* The whole channel, bus included, where the identity key has only
|
|
322
|
+
* the subject. A reader looking at unmatched channels needs to see
|
|
323
|
+
* which bus each one was on.
|
|
292
324
|
*/
|
|
293
325
|
displayLabel(semantics) {
|
|
294
326
|
if (semantics.channel === null) {
|
|
@@ -300,25 +332,25 @@ var messageBusSemantics = defineBoundarySemantics({
|
|
|
300
332
|
});
|
|
301
333
|
|
|
302
334
|
// src/semantics/metric.ts
|
|
303
|
-
import { z as
|
|
304
|
-
var MetricSemanticsSchema =
|
|
305
|
-
name:
|
|
306
|
-
/**
|
|
307
|
-
metricSystem:
|
|
335
|
+
import { z as z6 } from "zod";
|
|
336
|
+
var MetricSemanticsSchema = z6.object({
|
|
337
|
+
name: z6.literal("metric"),
|
|
338
|
+
/** The system the series is stored in, such as `cloud-monitoring` or `cloudwatch`. */
|
|
339
|
+
metricSystem: z6.string(),
|
|
308
340
|
/**
|
|
309
|
-
* The type string the system
|
|
310
|
-
* both sides
|
|
311
|
-
*
|
|
312
|
-
*
|
|
313
|
-
*
|
|
341
|
+
* The type string the system uses for the metric, written the same
|
|
342
|
+
* way on both sides. Null when the reader could not work the string
|
|
343
|
+
* out, as with a query it could not parse. A null type pairs with
|
|
344
|
+
* nothing, so it cannot pair with an unrelated metric that happens to
|
|
345
|
+
* share its source text.
|
|
314
346
|
*/
|
|
315
|
-
metricType:
|
|
347
|
+
metricType: z6.string().nullable()
|
|
316
348
|
});
|
|
317
349
|
var metricSemantics = defineBoundarySemantics({
|
|
318
350
|
name: "metric",
|
|
319
351
|
schema: MetricSemanticsSchema,
|
|
320
|
-
// OpenTelemetry
|
|
321
|
-
// attribute for the system
|
|
352
|
+
// OpenTelemetry identifies a metric by its instrument name. It has no
|
|
353
|
+
// attribute for the metric's system or its type string.
|
|
322
354
|
semconv: {},
|
|
323
355
|
behavior: {
|
|
324
356
|
exchangesHttpResponses: false,
|
|
@@ -334,7 +366,7 @@ var metricSemantics = defineBoundarySemantics({
|
|
|
334
366
|
});
|
|
335
367
|
|
|
336
368
|
// src/semantics/rest.ts
|
|
337
|
-
import { z as
|
|
369
|
+
import { z as z7 } from "zod";
|
|
338
370
|
|
|
339
371
|
// src/dispatch.ts
|
|
340
372
|
function dispatchByType(table, value) {
|
|
@@ -681,23 +713,23 @@ function compareRanks(a, b) {
|
|
|
681
713
|
}
|
|
682
714
|
|
|
683
715
|
// src/semantics/rest.ts
|
|
684
|
-
var RestSemanticsSchema =
|
|
685
|
-
name:
|
|
716
|
+
var RestSemanticsSchema = z7.object({
|
|
717
|
+
name: z7.literal("rest"),
|
|
686
718
|
/**
|
|
687
719
|
* Uppercase HTTP method ("GET", "POST", …), `"*"` for a handler that
|
|
688
720
|
* responds to every method, or null when this source does not say
|
|
689
721
|
* which method.
|
|
690
722
|
*/
|
|
691
|
-
method:
|
|
723
|
+
method: z7.string().min(1).nullable(),
|
|
692
724
|
/** Normalized route path ("/users/{id}"), or null when this source does not give one. */
|
|
693
|
-
path:
|
|
725
|
+
path: z7.string().min(1).nullable(),
|
|
694
726
|
/**
|
|
695
|
-
* Status codes the producing source explicitly
|
|
696
|
-
* responses
|
|
697
|
-
*
|
|
698
|
-
* metadata. Absent
|
|
727
|
+
* Status codes the producing source declared explicitly, such as
|
|
728
|
+
* OpenAPI responses or CloudFormation MethodResponses. They are kept
|
|
729
|
+
* here so the pairing layer can see them without unwrapping any
|
|
730
|
+
* metadata. Absent or empty for an inferred source.
|
|
699
731
|
*/
|
|
700
|
-
declaredResponses:
|
|
732
|
+
declaredResponses: z7.array(z7.number()).optional()
|
|
701
733
|
});
|
|
702
734
|
var OPENING_HOLE = /^\{([^{}]+)\}(.*)$/;
|
|
703
735
|
function baseUrlReference(semantics) {
|
|
@@ -754,16 +786,15 @@ var restSemantics = defineBoundarySemantics({
|
|
|
754
786
|
return `${semantics.method.toUpperCase()} ${normalizePath(semantics.path)}`;
|
|
755
787
|
},
|
|
756
788
|
/**
|
|
757
|
-
* The bucket has only the path
|
|
758
|
-
*
|
|
759
|
-
*
|
|
760
|
-
* sees and a suppression targets ("GET /users", "* /users")
|
|
761
|
-
* this key groups what a reader still tells apart.
|
|
789
|
+
* The bucket has only the path, so a `"*"` route lands with the
|
|
790
|
+
* consumers that each give a method, and `methodsAgree` compares the
|
|
791
|
+
* methods inside the bucket. The identity key is still what a reader
|
|
792
|
+
* sees and what a suppression targets ("GET /users", "* /users").
|
|
762
793
|
*
|
|
763
|
-
*
|
|
764
|
-
* `{userId}` where the Express route that serves it
|
|
765
|
-
* both match the same requests
|
|
766
|
-
* boundaries that never
|
|
794
|
+
* Parameter names are dropped too. A hand-written spec writes
|
|
795
|
+
* `{userId}` where the Express route that serves it writes `:id`,
|
|
796
|
+
* and both match the same requests. Pairing on the name would leave
|
|
797
|
+
* two boundaries that never meet.
|
|
767
798
|
*/
|
|
768
799
|
pairingKey(semantics) {
|
|
769
800
|
if (semantics.method === null || semantics.path === null) {
|
|
@@ -784,9 +815,9 @@ var restSemantics = defineBoundarySemantics({
|
|
|
784
815
|
return semantics.path === null ? [] : pathSpecificity(normalizePath(semantics.path));
|
|
785
816
|
},
|
|
786
817
|
/**
|
|
787
|
-
*
|
|
788
|
-
*
|
|
789
|
-
*
|
|
818
|
+
* The identity key, with a missing half still readable: `ANY` when
|
|
819
|
+
* the source gave no method, and `?` when it gave no path. Null when
|
|
820
|
+
* both are missing, since then there is nothing to show.
|
|
790
821
|
*/
|
|
791
822
|
displayLabel(semantics) {
|
|
792
823
|
if (semantics.method === null && semantics.path === null) {
|
|
@@ -797,11 +828,11 @@ var restSemantics = defineBoundarySemantics({
|
|
|
797
828
|
return `${method} ${path}`;
|
|
798
829
|
},
|
|
799
830
|
/**
|
|
800
|
-
*
|
|
801
|
-
*
|
|
802
|
-
*
|
|
803
|
-
*
|
|
804
|
-
*
|
|
831
|
+
* With both halves present, the method goes through `methodsAgree`
|
|
832
|
+
* (so a `"*"` route matches every method) and the path through
|
|
833
|
+
* `routePathAdmits`. A route missing either half might still handle
|
|
834
|
+
* the request, and this declaration cannot settle that, so the
|
|
835
|
+
* result is `"unknown"`.
|
|
805
836
|
*/
|
|
806
837
|
servesRequest(semantics, method, path) {
|
|
807
838
|
if (semantics.method === null || semantics.path === null) {
|
|
@@ -814,8 +845,8 @@ var restSemantics = defineBoundarySemantics({
|
|
|
814
845
|
},
|
|
815
846
|
/**
|
|
816
847
|
* A route the registration pattern admits is inside it. A route
|
|
817
|
-
*
|
|
818
|
-
*
|
|
848
|
+
* without a path counts as outside, because nothing shows that the
|
|
849
|
+
* pattern covers it.
|
|
819
850
|
*/
|
|
820
851
|
withinScope(semantics, scope) {
|
|
821
852
|
return semantics.path !== null && routePathAdmits(scope, semantics.path);
|
|
@@ -824,16 +855,12 @@ var restSemantics = defineBoundarySemantics({
|
|
|
824
855
|
* A call whose base URL the deployment fills in, resolved to the
|
|
825
856
|
* path it reaches.
|
|
826
857
|
*
|
|
827
|
-
* The source cannot settle this on its own,
|
|
828
|
-
*
|
|
829
|
-
*
|
|
830
|
-
*
|
|
831
|
-
*
|
|
832
|
-
*
|
|
833
|
-
*
|
|
834
|
-
* Only a hole at the front is a base URL. A hole further along is a
|
|
835
|
-
* route parameter, and `/orders/{id}` means every id rather than a
|
|
836
|
-
* variable somebody set.
|
|
858
|
+
* The source cannot settle this on its own, so the adapter leaves
|
|
859
|
+
* the hole in. `API_BASE` could be `http://backend.internal`, and
|
|
860
|
+
* then the path is `/orders`. It could equally be `/api/v2`, and
|
|
861
|
+
* then the path is `/api/v2/orders`. Filling in the deployed value
|
|
862
|
+
* and reading the path back out gets the right one either way.
|
|
863
|
+
* `baseUrlReference` finds the hole that is the base URL.
|
|
837
864
|
*/
|
|
838
865
|
groundName(semantics, deployment) {
|
|
839
866
|
const reference = baseUrlReference(semantics);
|
|
@@ -850,7 +877,7 @@ var restSemantics = defineBoundarySemantics({
|
|
|
850
877
|
},
|
|
851
878
|
nameReference: baseUrlReference,
|
|
852
879
|
ruleBoundary: {
|
|
853
|
-
// "METHOD /path": one
|
|
880
|
+
// "METHOD /path": one token, a space, then an absolute path.
|
|
854
881
|
claims(raw) {
|
|
855
882
|
return /^\S+ +\//.test(raw.trim());
|
|
856
883
|
},
|
|
@@ -865,12 +892,12 @@ var restSemantics = defineBoundarySemantics({
|
|
|
865
892
|
});
|
|
866
893
|
|
|
867
894
|
// src/semantics/runtimeConfig.ts
|
|
868
|
-
import { z as
|
|
895
|
+
import { z as z9 } from "zod";
|
|
869
896
|
|
|
870
897
|
// src/deployableUnit.ts
|
|
871
|
-
import { z as
|
|
872
|
-
var DeployableUnitSchema =
|
|
873
|
-
deploymentTarget:
|
|
898
|
+
import { z as z8 } from "zod";
|
|
899
|
+
var DeployableUnitSchema = z8.object({
|
|
900
|
+
deploymentTarget: z8.enum([
|
|
874
901
|
"lambda",
|
|
875
902
|
"ecs-task",
|
|
876
903
|
"container",
|
|
@@ -879,7 +906,7 @@ var DeployableUnitSchema = z7.object({
|
|
|
879
906
|
]),
|
|
880
907
|
// An empty name would agree with every other empty name, so a unit
|
|
881
908
|
// with no name has to leave the field off instead.
|
|
882
|
-
instanceName:
|
|
909
|
+
instanceName: z8.string().min(1)
|
|
883
910
|
});
|
|
884
911
|
function ecsContainerInstanceName(taskDefinitionLogicalId, containerName) {
|
|
885
912
|
return `${taskDefinitionLogicalId}/${containerName}`;
|
|
@@ -890,14 +917,14 @@ var RuntimeConfigSemanticsSchema = DeployableUnitSchema.partial({
|
|
|
890
917
|
deploymentTarget: true,
|
|
891
918
|
instanceName: true
|
|
892
919
|
}).extend({
|
|
893
|
-
name:
|
|
920
|
+
name: z9.literal("runtime-config")
|
|
894
921
|
});
|
|
895
922
|
var runtimeConfigSemantics = defineBoundarySemantics({
|
|
896
923
|
name: "runtime-config",
|
|
897
924
|
schema: RuntimeConfigSemanticsSchema,
|
|
898
|
-
// service.name and cloud.resource_id
|
|
899
|
-
// instanceName is the
|
|
900
|
-
//
|
|
925
|
+
// service.name and cloud.resource_id identify the same deployable, but
|
|
926
|
+
// instanceName is the template's logical id, a different string from
|
|
927
|
+
// both.
|
|
901
928
|
semconv: {},
|
|
902
929
|
behavior: {
|
|
903
930
|
/** A process reads its config at startup, and nothing replies. */
|
|
@@ -906,46 +933,53 @@ var runtimeConfigSemantics = defineBoundarySemantics({
|
|
|
906
933
|
// comes from outside the code.
|
|
907
934
|
leavesTheProcess: true,
|
|
908
935
|
reportsUnpairedItself: false,
|
|
909
|
-
identityKey: () => null
|
|
936
|
+
identityKey: () => null,
|
|
937
|
+
// A reader sees which deployable's environment this is. Code that
|
|
938
|
+
// reads a variable does not say which deployable runs it, so a read
|
|
939
|
+
// has no name.
|
|
940
|
+
displayLabel(semantics) {
|
|
941
|
+
const instance = semantics.instanceName;
|
|
942
|
+
return instance === void 0 ? null : `runtime-config:${instance}`;
|
|
943
|
+
}
|
|
910
944
|
}
|
|
911
945
|
});
|
|
912
946
|
|
|
913
947
|
// src/semantics/storage.ts
|
|
914
|
-
import { z as
|
|
915
|
-
var StorageSemanticsSchema =
|
|
916
|
-
name:
|
|
948
|
+
import { z as z10 } from "zod";
|
|
949
|
+
var StorageSemanticsSchema = z10.object({
|
|
950
|
+
name: z10.literal("storage"),
|
|
917
951
|
/**
|
|
918
|
-
*
|
|
919
|
-
*
|
|
920
|
-
*
|
|
921
|
-
* containers can share a name,
|
|
922
|
-
*
|
|
923
|
-
*
|
|
952
|
+
* The storage system: an OpenTelemetry value such as `postgresql` or
|
|
953
|
+
* `aws.dynamodb`, or suss's own word for one the conventions do not
|
|
954
|
+
* cover, such as `s3`. Null when the reader could not work out which
|
|
955
|
+
* system the source uses. Two products' containers can share a name,
|
|
956
|
+
* and this field keeps them apart. The pairing pass decides how to
|
|
957
|
+
* treat a null.
|
|
924
958
|
*/
|
|
925
|
-
storageSystem:
|
|
959
|
+
storageSystem: z10.string().nullable(),
|
|
926
960
|
/**
|
|
927
961
|
* The ORM, schema, or deployment scope. A single-database setup uses
|
|
928
962
|
* `"default"`, and a monorepo with several schemas gives each one its
|
|
929
963
|
* own value.
|
|
930
964
|
*/
|
|
931
|
-
scope:
|
|
965
|
+
scope: z10.string(),
|
|
932
966
|
/**
|
|
933
|
-
* The table, bucket, collection
|
|
934
|
-
*
|
|
935
|
-
*
|
|
936
|
-
*
|
|
937
|
-
*
|
|
938
|
-
*
|
|
967
|
+
* The table, bucket, collection or index, as the source declares it.
|
|
968
|
+
* Null when the reader could not work out the container, and a null
|
|
969
|
+
* container pairs with nothing, so it cannot match by accident of
|
|
970
|
+
* shared source text. The string uses the boundary-name syntax (a
|
|
971
|
+
* literal, a pattern with `{}` holes, or a reference), and only
|
|
972
|
+
* `parseBoundaryName` should read it.
|
|
939
973
|
*/
|
|
940
|
-
container:
|
|
974
|
+
container: z10.string().nullable(),
|
|
941
975
|
/**
|
|
942
|
-
* A secondary way into the container, a DynamoDB global
|
|
943
|
-
* index or an Elasticsearch alias, each with its own key
|
|
944
|
-
* Null means the container's
|
|
976
|
+
* A secondary way into the container, such as a DynamoDB global
|
|
977
|
+
* secondary index or an Elasticsearch alias, each with its own key
|
|
978
|
+
* fields. Null means the container's primary key. A query through an
|
|
945
979
|
* index and a query through the table are different accesses, so
|
|
946
980
|
* they pair separately.
|
|
947
981
|
*/
|
|
948
|
-
accessPath:
|
|
982
|
+
accessPath: z10.string().nullable()
|
|
949
983
|
});
|
|
950
984
|
function containerReference(semantics) {
|
|
951
985
|
return semantics.container === null ? null : referenceFromName(semantics.container);
|
|
@@ -955,21 +989,21 @@ var storageSemantics = defineBoundarySemantics({
|
|
|
955
989
|
schema: StorageSemanticsSchema,
|
|
956
990
|
semconv: {
|
|
957
991
|
storageSystem: { name: "db.system.name" },
|
|
958
|
-
// "default"
|
|
992
|
+
// suss writes "default" when the source did not say which database.
|
|
959
993
|
scope: { name: "db.namespace", placeholderValues: ["default"] },
|
|
960
994
|
container: { name: "db.collection.name" }
|
|
961
|
-
//
|
|
962
|
-
//
|
|
995
|
+
// The conventions have no attribute for a secondary index, so
|
|
996
|
+
// accessPath is left out.
|
|
963
997
|
},
|
|
964
998
|
behavior: {
|
|
965
|
-
/** A query returns rows or items,
|
|
999
|
+
/** A query returns rows or items, with no status. */
|
|
966
1000
|
exchangesHttpResponses: false,
|
|
967
1001
|
leavesTheProcess: true,
|
|
968
1002
|
reportsUnpairedItself: false,
|
|
969
1003
|
identityKey: () => null,
|
|
970
1004
|
displayLabel: storageLabel,
|
|
971
1005
|
/**
|
|
972
|
-
* A container the source
|
|
1006
|
+
* A container the source gives as a variable is whatever the
|
|
973
1007
|
* deployment sets that variable to. `{SUBSCRIBERS_TABLE}` in the
|
|
974
1008
|
* code and `prod-subscribers-v1` in the manifest are one table.
|
|
975
1009
|
*/
|
|
@@ -999,9 +1033,9 @@ function storageContainerLabel(semantics) {
|
|
|
999
1033
|
}
|
|
1000
1034
|
|
|
1001
1035
|
// src/semantics/unitInvocation.ts
|
|
1002
|
-
import { z as
|
|
1036
|
+
import { z as z11 } from "zod";
|
|
1003
1037
|
var UnitInvocationSemanticsSchema = DeployableUnitSchema.extend({
|
|
1004
|
-
name:
|
|
1038
|
+
name: z11.literal("unit-invocation"),
|
|
1005
1039
|
instanceName: DeployableUnitSchema.shape.instanceName.nullable()
|
|
1006
1040
|
});
|
|
1007
1041
|
function calleeReference(semantics) {
|
|
@@ -1031,9 +1065,9 @@ var unitInvocationSemantics = defineBoundarySemantics({
|
|
|
1031
1065
|
*/
|
|
1032
1066
|
reportsUnpairedItself: false,
|
|
1033
1067
|
/**
|
|
1034
|
-
* A callee the source
|
|
1035
|
-
*
|
|
1036
|
-
*
|
|
1068
|
+
* A callee the source gives only as a variable has no name until the
|
|
1069
|
+
* deployment fills it in. It gets no key, since a key built from the
|
|
1070
|
+
* variable would pair only with itself.
|
|
1037
1071
|
*/
|
|
1038
1072
|
identityKey(semantics) {
|
|
1039
1073
|
if (semantics.instanceName === null || namesNothing(semantics.instanceName)) {
|
|
@@ -1054,11 +1088,10 @@ var unitInvocationSemantics = defineBoundarySemantics({
|
|
|
1054
1088
|
);
|
|
1055
1089
|
},
|
|
1056
1090
|
/**
|
|
1057
|
-
* A call that reads its callee's name
|
|
1058
|
-
*
|
|
1059
|
-
*
|
|
1060
|
-
*
|
|
1061
|
-
* id and neither side ever writes the other's string.
|
|
1091
|
+
* A call that reads its callee's name from the environment reaches
|
|
1092
|
+
* whichever resource the template wires that variable to. The name
|
|
1093
|
+
* is grounded to the logical id and not the deployed name, because
|
|
1094
|
+
* the invoked unit's own summary is keyed by the logical id.
|
|
1062
1095
|
*/
|
|
1063
1096
|
groundName(semantics, deployment) {
|
|
1064
1097
|
const reference = calleeReference(semantics);
|
|
@@ -1073,7 +1106,7 @@ var unitInvocationSemantics = defineBoundarySemantics({
|
|
|
1073
1106
|
});
|
|
1074
1107
|
|
|
1075
1108
|
// src/semantics/registry.ts
|
|
1076
|
-
var SemanticsSchema =
|
|
1109
|
+
var SemanticsSchema = z12.discriminatedUnion("name", [
|
|
1077
1110
|
restSemantics.schema,
|
|
1078
1111
|
functionCallSemantics.schema,
|
|
1079
1112
|
graphqlResolverSemantics.schema,
|
|
@@ -1082,7 +1115,8 @@ var SemanticsSchema = z11.discriminatedUnion("name", [
|
|
|
1082
1115
|
storageSemantics.schema,
|
|
1083
1116
|
messageBusSemantics.schema,
|
|
1084
1117
|
metricSemantics.schema,
|
|
1085
|
-
unitInvocationSemantics.schema
|
|
1118
|
+
unitInvocationSemantics.schema,
|
|
1119
|
+
ioSemantics.schema
|
|
1086
1120
|
]);
|
|
1087
1121
|
var DEFINITIONS = [
|
|
1088
1122
|
restSemantics,
|
|
@@ -1093,7 +1127,8 @@ var DEFINITIONS = [
|
|
|
1093
1127
|
storageSemantics,
|
|
1094
1128
|
messageBusSemantics,
|
|
1095
1129
|
metricSemantics,
|
|
1096
|
-
unitInvocationSemantics
|
|
1130
|
+
unitInvocationSemantics,
|
|
1131
|
+
ioSemantics
|
|
1097
1132
|
];
|
|
1098
1133
|
var BY_NAME = new Map(
|
|
1099
1134
|
DEFINITIONS.map((d) => [d.name, d])
|
|
@@ -1116,90 +1151,95 @@ function allBehaviors() {
|
|
|
1116
1151
|
}
|
|
1117
1152
|
|
|
1118
1153
|
// src/schemas.ts
|
|
1119
|
-
var ConfidenceSourceSchema =
|
|
1154
|
+
var ConfidenceSourceSchema = z13.enum([
|
|
1120
1155
|
"inferred_static",
|
|
1121
1156
|
"inferred_ai",
|
|
1122
1157
|
"declared",
|
|
1123
1158
|
"derived"
|
|
1124
1159
|
]);
|
|
1125
|
-
var ConfidenceLevelSchema =
|
|
1126
|
-
var CorroborationSchema =
|
|
1127
|
-
outcome:
|
|
1160
|
+
var ConfidenceLevelSchema = z13.enum(["high", "medium", "low"]);
|
|
1161
|
+
var CorroborationSchema = z13.object({
|
|
1162
|
+
outcome: z13.enum(["observed", "refuted", "untested"]),
|
|
1128
1163
|
/** Executions that produced a verdict for this claim. */
|
|
1129
|
-
runs:
|
|
1164
|
+
runs: z13.number(),
|
|
1130
1165
|
/** Present when refuted: the input and observation that disagreed. */
|
|
1131
|
-
counterexample:
|
|
1166
|
+
counterexample: z13.unknown().optional(),
|
|
1132
1167
|
/** Present when untested: why no verdict was reachable. */
|
|
1133
|
-
reason:
|
|
1168
|
+
reason: z13.string().optional()
|
|
1134
1169
|
});
|
|
1135
|
-
var ConfidenceInfoSchema =
|
|
1170
|
+
var ConfidenceInfoSchema = z13.object({
|
|
1136
1171
|
source: ConfidenceSourceSchema,
|
|
1137
1172
|
level: ConfidenceLevelSchema,
|
|
1138
1173
|
corroboration: CorroborationSchema.optional()
|
|
1139
1174
|
});
|
|
1140
|
-
var SourceLocationSchema =
|
|
1141
|
-
file:
|
|
1175
|
+
var SourceLocationSchema = z13.object({
|
|
1176
|
+
file: z13.string(),
|
|
1142
1177
|
/** Line numbers, for a person reading the summary or an editor link. */
|
|
1143
|
-
range:
|
|
1178
|
+
range: z13.object({ start: z13.number(), end: z13.number() }),
|
|
1144
1179
|
/**
|
|
1145
|
-
* Character offsets of the unit in its file. Identity and joins
|
|
1146
|
-
*
|
|
1147
|
-
*
|
|
1148
|
-
*
|
|
1149
|
-
* contract artifact's say.
|
|
1180
|
+
* Character offsets of the unit in its file. Identity and joins use
|
|
1181
|
+
* these, because two functions can share a line but never an offset
|
|
1182
|
+
* range. `range` gives the same place in lines. Absent on a summary
|
|
1183
|
+
* with no source position, such as one read from a contract.
|
|
1150
1184
|
*/
|
|
1151
|
-
span:
|
|
1152
|
-
exportName:
|
|
1185
|
+
span: z13.object({ start: z13.number(), end: z13.number() }).optional(),
|
|
1186
|
+
exportName: z13.string().nullable(),
|
|
1153
1187
|
/**
|
|
1154
|
-
* The project the extract
|
|
1155
|
-
*
|
|
1188
|
+
* The project the extract ran on, by the name the project gives
|
|
1189
|
+
* itself.
|
|
1156
1190
|
*
|
|
1157
1191
|
* Paths are relative to wherever the extract ran, so two services in
|
|
1158
|
-
* one repository both report `src/handlers.ts`, and merging their
|
|
1159
|
-
* summaries
|
|
1160
|
-
*
|
|
1192
|
+
* one repository can both report `src/handlers.ts`, and merging their
|
|
1193
|
+
* summaries would mix them up. This field tells them apart, and a
|
|
1194
|
+
* reader groups by it.
|
|
1195
|
+
*/
|
|
1196
|
+
workspace: z13.string().optional(),
|
|
1197
|
+
/**
|
|
1198
|
+
* The module of the application the unit belongs to, by the name the
|
|
1199
|
+
* project's `suss.json` gives it. Set only when the project lists its
|
|
1200
|
+
* modules, and then on every unit whose file is under a module's root.
|
|
1161
1201
|
*/
|
|
1162
|
-
|
|
1202
|
+
module: z13.string().optional()
|
|
1163
1203
|
});
|
|
1164
|
-
var BoundaryBindingSchema =
|
|
1165
|
-
transport:
|
|
1204
|
+
var BoundaryBindingSchema = z13.object({
|
|
1205
|
+
transport: z13.string(),
|
|
1166
1206
|
semantics: SemanticsSchema,
|
|
1167
|
-
recognition:
|
|
1207
|
+
recognition: z13.string()
|
|
1168
1208
|
});
|
|
1169
1209
|
function typeDefinitionKey(ref) {
|
|
1170
1210
|
return ref.def ?? null;
|
|
1171
1211
|
}
|
|
1172
|
-
var TypeShapeSchema =
|
|
1173
|
-
() =>
|
|
1174
|
-
|
|
1175
|
-
type:
|
|
1176
|
-
properties:
|
|
1177
|
-
spreads:
|
|
1212
|
+
var TypeShapeSchema = z13.lazy(
|
|
1213
|
+
() => z13.discriminatedUnion("type", [
|
|
1214
|
+
z13.object({
|
|
1215
|
+
type: z13.literal("record"),
|
|
1216
|
+
properties: z13.record(z13.string(), TypeShapeSchema),
|
|
1217
|
+
spreads: z13.array(z13.object({ sourceText: z13.string() })).optional()
|
|
1178
1218
|
}),
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
type:
|
|
1183
|
-
value:
|
|
1184
|
-
raw:
|
|
1219
|
+
z13.object({ type: z13.literal("dictionary"), values: TypeShapeSchema }),
|
|
1220
|
+
z13.object({ type: z13.literal("array"), items: TypeShapeSchema }),
|
|
1221
|
+
z13.object({
|
|
1222
|
+
type: z13.literal("literal"),
|
|
1223
|
+
value: z13.union([z13.string(), z13.number(), z13.boolean()]),
|
|
1224
|
+
raw: z13.string().optional()
|
|
1185
1225
|
}),
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
type:
|
|
1194
|
-
variants:
|
|
1226
|
+
z13.object({ type: z13.literal("text") }),
|
|
1227
|
+
z13.object({ type: z13.literal("integer") }),
|
|
1228
|
+
z13.object({ type: z13.literal("number") }),
|
|
1229
|
+
z13.object({ type: z13.literal("boolean") }),
|
|
1230
|
+
z13.object({ type: z13.literal("null") }),
|
|
1231
|
+
z13.object({ type: z13.literal("undefined") }),
|
|
1232
|
+
z13.object({
|
|
1233
|
+
type: z13.literal("union"),
|
|
1234
|
+
variants: z13.array(TypeShapeSchema)
|
|
1195
1235
|
}),
|
|
1196
|
-
|
|
1197
|
-
type:
|
|
1198
|
-
name:
|
|
1199
|
-
from:
|
|
1200
|
-
def:
|
|
1236
|
+
z13.object({
|
|
1237
|
+
type: z13.literal("ref"),
|
|
1238
|
+
name: z13.string(),
|
|
1239
|
+
from: z13.string().optional(),
|
|
1240
|
+
def: z13.string().optional()
|
|
1201
1241
|
}),
|
|
1202
|
-
|
|
1242
|
+
z13.object({ type: z13.literal("unknown") })
|
|
1203
1243
|
])
|
|
1204
1244
|
);
|
|
1205
1245
|
var MAX_DEFINITION_DEPTH = 6;
|
|
@@ -1250,8 +1290,11 @@ export {
|
|
|
1250
1290
|
busIdentityKey,
|
|
1251
1291
|
unitIdentityKey,
|
|
1252
1292
|
metricIdentityKey,
|
|
1293
|
+
ioIdentityKey,
|
|
1253
1294
|
FunctionCallSemanticsSchema,
|
|
1295
|
+
isModuleName,
|
|
1254
1296
|
GraphqlResolverSemanticsSchema,
|
|
1297
|
+
IoSemanticsSchema,
|
|
1255
1298
|
parseChannel,
|
|
1256
1299
|
formatChannel,
|
|
1257
1300
|
busesAgree,
|