@suss/ir-core 0.21.0 → 0.21.1
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/{chunk-QHFMZPEG.js → chunk-PPQWK62O.js} +201 -14
- package/dist/index.cjs +210 -154
- package/dist/index.d.cts +180 -115
- package/dist/index.d.ts +180 -115
- package/dist/index.js +33 -141
- package/dist/schemas.cjs +91 -14
- package/dist/schemas.js +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -20,19 +20,32 @@ import {
|
|
|
20
20
|
UnitInvocationSemanticsSchema,
|
|
21
21
|
allBehaviors,
|
|
22
22
|
behaviorOf,
|
|
23
|
+
boundaryNameString,
|
|
23
24
|
busIdentityKey,
|
|
24
25
|
busesAgree,
|
|
25
26
|
channelsPair,
|
|
27
|
+
dispatchByType,
|
|
26
28
|
ecsContainerInstanceName,
|
|
29
|
+
fixedTextLength,
|
|
27
30
|
fnIdentityKey,
|
|
28
31
|
formatChannel,
|
|
29
32
|
gqlIdentityKey,
|
|
33
|
+
hasNameHole,
|
|
30
34
|
methodsAgree,
|
|
31
35
|
metricIdentityKey,
|
|
36
|
+
namePatternFromSub,
|
|
37
|
+
namePatternKey,
|
|
38
|
+
namesAgree,
|
|
39
|
+
namesNothing,
|
|
32
40
|
normalizePath,
|
|
41
|
+
parseBoundaryName,
|
|
33
42
|
parseChannel,
|
|
34
43
|
pathAfterOrigin,
|
|
35
44
|
pathShape,
|
|
45
|
+
patternHole,
|
|
46
|
+
referenceFromName,
|
|
47
|
+
referenceName,
|
|
48
|
+
referenceOf,
|
|
36
49
|
routePathAdmits,
|
|
37
50
|
semconvMappingOf,
|
|
38
51
|
statesAnOrigin,
|
|
@@ -41,7 +54,7 @@ import {
|
|
|
41
54
|
typeDefinitionKey,
|
|
42
55
|
unitIdentityKey,
|
|
43
56
|
withDefinitionsInlined
|
|
44
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-PPQWK62O.js";
|
|
45
58
|
|
|
46
59
|
// src/semconv.ts
|
|
47
60
|
function semconvAttributes(binding) {
|
|
@@ -79,12 +92,16 @@ function withRewrittenPaths(binding, rewrite) {
|
|
|
79
92
|
semantics: behavior.rewritePaths(binding.semantics, rewrite)
|
|
80
93
|
};
|
|
81
94
|
}
|
|
82
|
-
function groundedPairingKey(binding,
|
|
95
|
+
function groundedPairingKey(binding, deployment) {
|
|
96
|
+
return pairingKey(groundBinding(binding, deployment));
|
|
97
|
+
}
|
|
98
|
+
function groundBinding(binding, deployment) {
|
|
83
99
|
const behavior = behaviorOf(binding.semantics);
|
|
84
|
-
const grounded = behavior.groundName?.(binding.semantics,
|
|
85
|
-
return
|
|
86
|
-
|
|
87
|
-
|
|
100
|
+
const grounded = behavior.groundName?.(binding.semantics, deployment) ?? null;
|
|
101
|
+
return grounded === null ? binding : { ...binding, semantics: grounded };
|
|
102
|
+
}
|
|
103
|
+
function nameReference(binding) {
|
|
104
|
+
return behaviorOf(binding.semantics).nameReference?.(binding.semantics) ?? null;
|
|
88
105
|
}
|
|
89
106
|
function pairingKey(binding) {
|
|
90
107
|
const behavior = behaviorOf(binding.semantics);
|
|
@@ -138,141 +155,6 @@ function withinScope(binding, scope) {
|
|
|
138
155
|
return within === void 0 ? false : within(binding.semantics, scope);
|
|
139
156
|
}
|
|
140
157
|
|
|
141
|
-
// src/dispatch.ts
|
|
142
|
-
function dispatchByType(table, value) {
|
|
143
|
-
const handler = table[value.type];
|
|
144
|
-
return handler(value);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// src/boundaryName.ts
|
|
148
|
-
var HOLE_SPLIT = /(\{[^}]*\})/;
|
|
149
|
-
var SUB_TOKEN = /\$\{([^}]*)\}/g;
|
|
150
|
-
var SUB_ESCAPE = /\$\{!/;
|
|
151
|
-
function isHole(piece) {
|
|
152
|
-
return piece.startsWith("{") && piece.endsWith("}");
|
|
153
|
-
}
|
|
154
|
-
function parseBoundaryName(name) {
|
|
155
|
-
const parts = name.split(HOLE_SPLIT).filter((piece) => piece !== "").map(
|
|
156
|
-
(piece) => isHole(piece) ? { type: "hole", label: piece.slice(1, -1) } : { type: "text", text: piece }
|
|
157
|
-
);
|
|
158
|
-
const only = parts.length === 1 ? parts[0] : void 0;
|
|
159
|
-
if (only !== void 0 && only.type === "hole") {
|
|
160
|
-
return { type: "reference", path: only.label.split(".") };
|
|
161
|
-
}
|
|
162
|
-
if (parts.some((part) => part.type === "hole")) {
|
|
163
|
-
return { type: "pattern", parts };
|
|
164
|
-
}
|
|
165
|
-
return { type: "literal", value: name };
|
|
166
|
-
}
|
|
167
|
-
var partString = {
|
|
168
|
-
text: (part) => part.text,
|
|
169
|
-
hole: (part) => patternHole(part.label)
|
|
170
|
-
};
|
|
171
|
-
var nameString = {
|
|
172
|
-
literal: (name) => name.value,
|
|
173
|
-
pattern: (name) => name.parts.map((part) => dispatchByType(partString, part)).join(""),
|
|
174
|
-
reference: (name) => patternHole(name.path.join("."))
|
|
175
|
-
};
|
|
176
|
-
function boundaryNameString(name) {
|
|
177
|
-
return dispatchByType(nameString, name);
|
|
178
|
-
}
|
|
179
|
-
function patternHole(label) {
|
|
180
|
-
return `{${label}}`;
|
|
181
|
-
}
|
|
182
|
-
function namePatternFromSub(value) {
|
|
183
|
-
if (Array.isArray(value)) {
|
|
184
|
-
return typeof value[0] === "string" ? namePatternFromSub(value[0]) : null;
|
|
185
|
-
}
|
|
186
|
-
if (typeof value !== "string") {
|
|
187
|
-
return null;
|
|
188
|
-
}
|
|
189
|
-
if (SUB_ESCAPE.test(value)) {
|
|
190
|
-
return null;
|
|
191
|
-
}
|
|
192
|
-
return value.replace(
|
|
193
|
-
SUB_TOKEN,
|
|
194
|
-
(_whole, inner) => patternHole(inner)
|
|
195
|
-
);
|
|
196
|
-
}
|
|
197
|
-
function namesNothing(name) {
|
|
198
|
-
return parseBoundaryName(name).type === "reference";
|
|
199
|
-
}
|
|
200
|
-
function hasNameHole(name) {
|
|
201
|
-
return parseBoundaryName(name).type !== "literal";
|
|
202
|
-
}
|
|
203
|
-
function namePatternKey(name) {
|
|
204
|
-
return dispatchByType(
|
|
205
|
-
{
|
|
206
|
-
literal: (parsed) => parsed.value,
|
|
207
|
-
pattern: (parsed) => boundaryNameString({
|
|
208
|
-
type: "pattern",
|
|
209
|
-
parts: parsed.parts.map(
|
|
210
|
-
(part) => part.type === "hole" ? { type: "hole", label: "" } : part
|
|
211
|
-
)
|
|
212
|
-
}),
|
|
213
|
-
reference: () => patternHole("")
|
|
214
|
-
},
|
|
215
|
-
parseBoundaryName(name)
|
|
216
|
-
);
|
|
217
|
-
}
|
|
218
|
-
function fixedTextLength(name) {
|
|
219
|
-
return dispatchByType(
|
|
220
|
-
{
|
|
221
|
-
literal: (parsed) => parsed.value.length,
|
|
222
|
-
pattern: (parsed) => parsed.parts.reduce(
|
|
223
|
-
(total, part) => total + (part.type === "text" ? part.text.length : 0),
|
|
224
|
-
0
|
|
225
|
-
),
|
|
226
|
-
reference: () => 0
|
|
227
|
-
},
|
|
228
|
-
parseBoundaryName(name)
|
|
229
|
-
);
|
|
230
|
-
}
|
|
231
|
-
function quote(text) {
|
|
232
|
-
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
233
|
-
}
|
|
234
|
-
function admits(pattern, name) {
|
|
235
|
-
const source = pattern.parts.map((part) => part.type === "hole" ? ".+" : quote(part.text)).join("");
|
|
236
|
-
return new RegExp(`^${source}$`).test(name);
|
|
237
|
-
}
|
|
238
|
-
function namesAgree(a, b) {
|
|
239
|
-
const left = parseBoundaryName(a);
|
|
240
|
-
const right = parseBoundaryName(b);
|
|
241
|
-
if (left.type === "reference" || right.type === "reference") {
|
|
242
|
-
return false;
|
|
243
|
-
}
|
|
244
|
-
if (left.type === "pattern" && right.type === "pattern") {
|
|
245
|
-
return namePatternKey(a) === namePatternKey(b);
|
|
246
|
-
}
|
|
247
|
-
if (left.type === "pattern") {
|
|
248
|
-
return admits(left, b);
|
|
249
|
-
}
|
|
250
|
-
if (right.type === "pattern") {
|
|
251
|
-
return admits(right, a);
|
|
252
|
-
}
|
|
253
|
-
return a === b;
|
|
254
|
-
}
|
|
255
|
-
function referenceName(reference) {
|
|
256
|
-
const path = [reference.root, ...reference.fields];
|
|
257
|
-
if (path.some((part) => part === "")) {
|
|
258
|
-
return null;
|
|
259
|
-
}
|
|
260
|
-
return boundaryNameString({ type: "reference", path });
|
|
261
|
-
}
|
|
262
|
-
function referenceOf(name) {
|
|
263
|
-
if (name.type !== "reference") {
|
|
264
|
-
return null;
|
|
265
|
-
}
|
|
266
|
-
const root = name.path[0];
|
|
267
|
-
if (root === void 0 || name.path.some((part) => part === "")) {
|
|
268
|
-
return null;
|
|
269
|
-
}
|
|
270
|
-
return { root, fields: name.path.slice(1) };
|
|
271
|
-
}
|
|
272
|
-
function referenceFromName(name) {
|
|
273
|
-
return referenceOf(parseBoundaryName(name));
|
|
274
|
-
}
|
|
275
|
-
|
|
276
158
|
// src/boundarySpelling.ts
|
|
277
159
|
function resourceNameIn(spelling) {
|
|
278
160
|
if (spelling.startsWith("arn:")) {
|
|
@@ -337,6 +219,13 @@ function fileInCodeScope(file, scope) {
|
|
|
337
219
|
return path === prefix || path.startsWith(`${prefix}/`);
|
|
338
220
|
}
|
|
339
221
|
|
|
222
|
+
// src/deployment.ts
|
|
223
|
+
var NOTHING_DEPLOYED = {
|
|
224
|
+
variableFor: () => null,
|
|
225
|
+
setTo: () => null,
|
|
226
|
+
pointsAt: () => null
|
|
227
|
+
};
|
|
228
|
+
|
|
340
229
|
// src/relation.ts
|
|
341
230
|
import { z } from "zod";
|
|
342
231
|
var RelationSchema = z.enum([
|
|
@@ -747,6 +636,7 @@ export {
|
|
|
747
636
|
GraphqlResolverSemanticsSchema,
|
|
748
637
|
MessageBusSemanticsSchema,
|
|
749
638
|
MetricSemanticsSchema,
|
|
639
|
+
NOTHING_DEPLOYED,
|
|
750
640
|
RelationSchema,
|
|
751
641
|
RestSemanticsSchema,
|
|
752
642
|
RuntimeConfigSemanticsSchema,
|
|
@@ -782,6 +672,7 @@ export {
|
|
|
782
672
|
gqlIdentityKey,
|
|
783
673
|
graphqlOperationBinding,
|
|
784
674
|
graphqlResolverBinding,
|
|
675
|
+
groundBinding,
|
|
785
676
|
groundedPairingKey,
|
|
786
677
|
hasNameHole,
|
|
787
678
|
isGraphqlOperationBinding,
|
|
@@ -791,6 +682,7 @@ export {
|
|
|
791
682
|
metricIdentityKey,
|
|
792
683
|
namePatternFromSub,
|
|
793
684
|
namePatternKey,
|
|
685
|
+
nameReference,
|
|
794
686
|
namesAgree,
|
|
795
687
|
namesBoundary,
|
|
796
688
|
namesBoundaryExactly,
|
package/dist/schemas.cjs
CHANGED
|
@@ -358,6 +358,44 @@ var metricSemantics = defineBoundarySemantics({
|
|
|
358
358
|
// src/semantics/rest.ts
|
|
359
359
|
var import_zod6 = require("zod");
|
|
360
360
|
|
|
361
|
+
// src/boundaryName.ts
|
|
362
|
+
var HOLE_SPLIT = /(\{[^}]*\})/;
|
|
363
|
+
function isHole(piece) {
|
|
364
|
+
return piece.startsWith("{") && piece.endsWith("}");
|
|
365
|
+
}
|
|
366
|
+
function parseBoundaryName(name) {
|
|
367
|
+
const parts = name.split(HOLE_SPLIT).filter((piece) => piece !== "").map(
|
|
368
|
+
(piece) => isHole(piece) ? { type: "hole", label: piece.slice(1, -1) } : { type: "text", text: piece }
|
|
369
|
+
);
|
|
370
|
+
const only = parts.length === 1 ? parts[0] : void 0;
|
|
371
|
+
if (only !== void 0 && only.type === "hole") {
|
|
372
|
+
return { type: "reference", path: only.label.split(".") };
|
|
373
|
+
}
|
|
374
|
+
if (parts.some((part) => part.type === "hole")) {
|
|
375
|
+
return { type: "pattern", parts };
|
|
376
|
+
}
|
|
377
|
+
return { type: "literal", value: name };
|
|
378
|
+
}
|
|
379
|
+
function patternHole(label) {
|
|
380
|
+
return `{${label}}`;
|
|
381
|
+
}
|
|
382
|
+
function namesNothing(name) {
|
|
383
|
+
return parseBoundaryName(name).type === "reference";
|
|
384
|
+
}
|
|
385
|
+
function referenceOf(name) {
|
|
386
|
+
if (name.type !== "reference") {
|
|
387
|
+
return null;
|
|
388
|
+
}
|
|
389
|
+
const root = name.path[0];
|
|
390
|
+
if (root === void 0 || name.path.some((part) => part === "")) {
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
393
|
+
return { root, fields: name.path.slice(1) };
|
|
394
|
+
}
|
|
395
|
+
function referenceFromName(name) {
|
|
396
|
+
return referenceOf(parseBoundaryName(name));
|
|
397
|
+
}
|
|
398
|
+
|
|
361
399
|
// src/urlPath.ts
|
|
362
400
|
var SCHEME_ORIGIN = /^[a-zA-Z][a-zA-Z\d+.-]*:\/\/[^/]*/;
|
|
363
401
|
var PROTOCOL_RELATIVE_ORIGIN = /^\/\/[^/]*/;
|
|
@@ -387,9 +425,9 @@ var RestSemanticsSchema = import_zod6.z.object({
|
|
|
387
425
|
declaredResponses: import_zod6.z.array(import_zod6.z.number()).optional()
|
|
388
426
|
});
|
|
389
427
|
var OPENING_HOLE = /^\{([^{}]+)\}(.*)$/;
|
|
390
|
-
function
|
|
391
|
-
const
|
|
392
|
-
return
|
|
428
|
+
function baseUrlReference(semantics) {
|
|
429
|
+
const label = OPENING_HOLE.exec(semantics.path ?? "")?.[1];
|
|
430
|
+
return label === void 0 ? null : referenceFromName(patternHole(label));
|
|
393
431
|
}
|
|
394
432
|
function normalizePath(path) {
|
|
395
433
|
let normalized = path.replace(/:([a-zA-Z_]\w*)/g, "{$1}");
|
|
@@ -523,22 +561,20 @@ var restSemantics = defineBoundarySemantics({
|
|
|
523
561
|
* route parameter, and `/orders/{id}` means every id rather than a
|
|
524
562
|
* variable somebody set.
|
|
525
563
|
*/
|
|
526
|
-
groundName(semantics,
|
|
527
|
-
|
|
564
|
+
groundName(semantics, deployment) {
|
|
565
|
+
const reference = baseUrlReference(semantics);
|
|
566
|
+
if (reference === null) {
|
|
528
567
|
return null;
|
|
529
568
|
}
|
|
530
|
-
const
|
|
531
|
-
if (opening === null) {
|
|
532
|
-
return null;
|
|
533
|
-
}
|
|
534
|
-
const [, label, rest] = opening;
|
|
535
|
-
const base = deployedAs(variableOf(label));
|
|
569
|
+
const base = deployment.setTo(reference);
|
|
536
570
|
if (base === null) {
|
|
537
571
|
return null;
|
|
538
572
|
}
|
|
573
|
+
const rest = OPENING_HOLE.exec(semantics.path ?? "")?.[2] ?? "";
|
|
539
574
|
const grounded = pathAfterOrigin(`${base}${rest}`);
|
|
540
575
|
return { ...semantics, path: grounded === "" ? "/" : grounded };
|
|
541
576
|
},
|
|
577
|
+
nameReference: baseUrlReference,
|
|
542
578
|
ruleBoundary: {
|
|
543
579
|
// "METHOD /path": one leading token, then an absolute path.
|
|
544
580
|
claims(raw) {
|
|
@@ -625,6 +661,9 @@ var StorageSemanticsSchema = import_zod9.z.object({
|
|
|
625
661
|
*/
|
|
626
662
|
accessPath: import_zod9.z.string().nullable()
|
|
627
663
|
});
|
|
664
|
+
function containerReference(semantics) {
|
|
665
|
+
return semantics.container === null ? null : referenceFromName(semantics.container);
|
|
666
|
+
}
|
|
628
667
|
var storageSemantics = defineBoundarySemantics({
|
|
629
668
|
name: "storage",
|
|
630
669
|
schema: StorageSemanticsSchema,
|
|
@@ -641,7 +680,21 @@ var storageSemantics = defineBoundarySemantics({
|
|
|
641
680
|
exchangesHttpResponses: false,
|
|
642
681
|
reportsUnpairedItself: false,
|
|
643
682
|
identityKey: () => null,
|
|
644
|
-
displayLabel: storageLabel
|
|
683
|
+
displayLabel: storageLabel,
|
|
684
|
+
/**
|
|
685
|
+
* A container the source states as a variable is whatever the
|
|
686
|
+
* deployment sets that variable to. `{SUBSCRIBERS_TABLE}` in the
|
|
687
|
+
* code and `prod-subscribers-v1` in the manifest are one table.
|
|
688
|
+
*/
|
|
689
|
+
groundName(semantics, deployment) {
|
|
690
|
+
const reference = containerReference(semantics);
|
|
691
|
+
if (reference === null) {
|
|
692
|
+
return null;
|
|
693
|
+
}
|
|
694
|
+
const name = deployment.setTo(reference);
|
|
695
|
+
return name === null ? null : { ...semantics, container: name };
|
|
696
|
+
},
|
|
697
|
+
nameReference: containerReference
|
|
645
698
|
}
|
|
646
699
|
});
|
|
647
700
|
function storageLabel(semantics) {
|
|
@@ -659,6 +712,9 @@ var UnitInvocationSemanticsSchema = DeployableUnitSchema.extend({
|
|
|
659
712
|
name: import_zod10.z.literal("unit-invocation"),
|
|
660
713
|
instanceName: DeployableUnitSchema.shape.instanceName.nullable()
|
|
661
714
|
});
|
|
715
|
+
function calleeReference(semantics) {
|
|
716
|
+
return semantics.instanceName === null ? null : referenceFromName(semantics.instanceName);
|
|
717
|
+
}
|
|
662
718
|
var unitInvocationSemantics = defineBoundarySemantics({
|
|
663
719
|
name: "unit-invocation",
|
|
664
720
|
schema: UnitInvocationSemanticsSchema,
|
|
@@ -681,8 +737,13 @@ var unitInvocationSemantics = defineBoundarySemantics({
|
|
|
681
737
|
* being reported as a problem here.
|
|
682
738
|
*/
|
|
683
739
|
reportsUnpairedItself: false,
|
|
740
|
+
/**
|
|
741
|
+
* A callee the source states only as a variable is not a name for
|
|
742
|
+
* anything until the deployment fills it in, so it keys as nothing
|
|
743
|
+
* rather than as a bucket that would agree with itself alone.
|
|
744
|
+
*/
|
|
684
745
|
identityKey(semantics) {
|
|
685
|
-
if (semantics.instanceName === null) {
|
|
746
|
+
if (semantics.instanceName === null || namesNothing(semantics.instanceName)) {
|
|
686
747
|
return null;
|
|
687
748
|
}
|
|
688
749
|
return unitIdentityKey(
|
|
@@ -698,7 +759,23 @@ var unitInvocationSemantics = defineBoundarySemantics({
|
|
|
698
759
|
semantics.deploymentTarget,
|
|
699
760
|
semantics.instanceName
|
|
700
761
|
);
|
|
701
|
-
}
|
|
762
|
+
},
|
|
763
|
+
/**
|
|
764
|
+
* A call that reads its callee's name out of the environment
|
|
765
|
+
* reaches whichever resource the template wires that variable to.
|
|
766
|
+
* The logical id is the answer rather than the deployed name,
|
|
767
|
+
* because the invoked unit's own summary is keyed by the logical
|
|
768
|
+
* id and neither side ever writes the other's string.
|
|
769
|
+
*/
|
|
770
|
+
groundName(semantics, deployment) {
|
|
771
|
+
const reference = calleeReference(semantics);
|
|
772
|
+
if (reference === null) {
|
|
773
|
+
return null;
|
|
774
|
+
}
|
|
775
|
+
const logicalId = deployment.pointsAt(reference);
|
|
776
|
+
return logicalId === null ? null : { ...semantics, instanceName: logicalId };
|
|
777
|
+
},
|
|
778
|
+
nameReference: calleeReference
|
|
702
779
|
}
|
|
703
780
|
});
|
|
704
781
|
|
package/dist/schemas.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suss/ir-core",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Shared IR primitives for suss — type shapes, boundary bindings, source locations, and confidence. Imported by both @suss/behavioral-ir and @suss/intent-ir so neither depends on the other.",
|
|
6
6
|
"keywords": [
|