@telorun/analyzer 0.65.0 → 0.67.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.
Files changed (142) hide show
  1. package/dist/analyzer.d.ts +1 -1
  2. package/dist/analyzer.d.ts.map +1 -1
  3. package/dist/analyzer.js +194 -65
  4. package/dist/builtins.d.ts.map +1 -1
  5. package/dist/builtins.js +67 -16
  6. package/dist/call-graph.d.ts.map +1 -1
  7. package/dist/call-graph.js +7 -1
  8. package/dist/cel-environment.d.ts +12 -0
  9. package/dist/cel-environment.d.ts.map +1 -1
  10. package/dist/cel-environment.js +35 -19
  11. package/dist/cel-scope.d.ts +8 -0
  12. package/dist/cel-scope.d.ts.map +1 -1
  13. package/dist/cel-scope.js +89 -11
  14. package/dist/definition-registry.d.ts +41 -0
  15. package/dist/definition-registry.d.ts.map +1 -1
  16. package/dist/definition-registry.js +76 -0
  17. package/dist/dependency-graph.d.ts.map +1 -1
  18. package/dist/dependency-graph.js +65 -0
  19. package/dist/eval-paths.d.ts +68 -0
  20. package/dist/eval-paths.d.ts.map +1 -1
  21. package/dist/eval-paths.js +138 -0
  22. package/dist/flatten-for-analyzer.d.ts +37 -1
  23. package/dist/flatten-for-analyzer.d.ts.map +1 -1
  24. package/dist/flatten-for-analyzer.js +104 -5
  25. package/dist/import-resolution-diagnostics.d.ts +1 -1
  26. package/dist/import-resolution-diagnostics.js +1 -1
  27. package/dist/index.d.ts +12 -8
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +8 -6
  30. package/dist/inline-imports.d.ts.map +1 -1
  31. package/dist/inline-imports.js +1 -0
  32. package/dist/manifest-visitor.d.ts +4 -0
  33. package/dist/manifest-visitor.d.ts.map +1 -1
  34. package/dist/manifest-visitor.js +36 -1
  35. package/dist/migrations/entries/index.d.ts.map +1 -1
  36. package/dist/migrations/entries/index.js +2 -0
  37. package/dist/migrations/entries/schema-prepare-bucket.json +27 -0
  38. package/dist/peer-binding.d.ts +232 -0
  39. package/dist/peer-binding.d.ts.map +1 -0
  40. package/dist/peer-binding.js +418 -0
  41. package/dist/precompile.d.ts.map +1 -1
  42. package/dist/precompile.js +8 -0
  43. package/dist/ref-slot.d.ts +13 -0
  44. package/dist/ref-slot.d.ts.map +1 -1
  45. package/dist/ref-slot.js +26 -0
  46. package/dist/reference-field-map.d.ts +28 -0
  47. package/dist/reference-field-map.d.ts.map +1 -1
  48. package/dist/reference-field-map.js +25 -0
  49. package/dist/referrer-rule.d.ts +17 -0
  50. package/dist/referrer-rule.d.ts.map +1 -1
  51. package/dist/referrer-rule.js +4 -1
  52. package/dist/release/index.d.ts +1 -1
  53. package/dist/release/index.js +1 -1
  54. package/dist/resolve-ref-sentinels.d.ts.map +1 -1
  55. package/dist/resolve-ref-sentinels.js +14 -1
  56. package/dist/resource-input.d.ts +75 -0
  57. package/dist/resource-input.d.ts.map +1 -0
  58. package/dist/resource-input.js +90 -0
  59. package/dist/resource-rule.d.ts +40 -27
  60. package/dist/resource-rule.d.ts.map +1 -1
  61. package/dist/resource-rule.js +61 -7
  62. package/dist/rule-condition.d.ts +11 -0
  63. package/dist/rule-condition.d.ts.map +1 -1
  64. package/dist/rule-condition.js +13 -0
  65. package/dist/schema-projection.d.ts +119 -4
  66. package/dist/schema-projection.d.ts.map +1 -1
  67. package/dist/schema-projection.js +213 -18
  68. package/dist/system-kinds.d.ts +7 -2
  69. package/dist/system-kinds.d.ts.map +1 -1
  70. package/dist/system-kinds.js +7 -2
  71. package/dist/telo-version.d.ts +1 -1
  72. package/dist/telo-version.js +1 -1
  73. package/dist/template-body.d.ts +50 -0
  74. package/dist/template-body.d.ts.map +1 -0
  75. package/dist/template-body.js +58 -0
  76. package/dist/validate-cel-context.d.ts +1 -17
  77. package/dist/validate-cel-context.d.ts.map +1 -1
  78. package/dist/validate-cel-context.js +73 -78
  79. package/dist/validate-identifier-names.d.ts.map +1 -1
  80. package/dist/validate-identifier-names.js +17 -2
  81. package/dist/validate-reference-forms.d.ts +10 -0
  82. package/dist/validate-reference-forms.d.ts.map +1 -1
  83. package/dist/validate-reference-forms.js +23 -0
  84. package/dist/validate-references.d.ts +17 -0
  85. package/dist/validate-references.d.ts.map +1 -1
  86. package/dist/validate-references.js +77 -18
  87. package/dist/validate-referrer-rules.d.ts +38 -4
  88. package/dist/validate-referrer-rules.d.ts.map +1 -1
  89. package/dist/validate-referrer-rules.js +139 -31
  90. package/dist/validate-resource-inputs.d.ts +35 -0
  91. package/dist/validate-resource-inputs.d.ts.map +1 -0
  92. package/dist/validate-resource-inputs.js +319 -0
  93. package/dist/validate-resource-rules.d.ts +11 -2
  94. package/dist/validate-resource-rules.d.ts.map +1 -1
  95. package/dist/validate-resource-rules.js +18 -12
  96. package/dist/validate-schema-projection.d.ts.map +1 -1
  97. package/dist/validate-schema-projection.js +33 -2
  98. package/dist/validate-template-dispatch.d.ts +27 -0
  99. package/dist/validate-template-dispatch.d.ts.map +1 -0
  100. package/dist/validate-template-dispatch.js +95 -0
  101. package/dist/with-synthetic-positions.d.ts +1 -1
  102. package/dist/with-synthetic-positions.js +1 -1
  103. package/package.json +3 -3
  104. package/src/analyzer.ts +236 -70
  105. package/src/builtins.ts +69 -16
  106. package/src/call-graph.ts +7 -1
  107. package/src/cel-environment.ts +48 -19
  108. package/src/cel-scope.ts +113 -19
  109. package/src/definition-registry.ts +78 -0
  110. package/src/dependency-graph.ts +66 -0
  111. package/src/eval-paths.ts +152 -0
  112. package/src/flatten-for-analyzer.ts +117 -4
  113. package/src/import-resolution-diagnostics.ts +1 -1
  114. package/src/index.ts +57 -4
  115. package/src/inline-imports.ts +1 -0
  116. package/src/manifest-visitor.ts +41 -1
  117. package/src/migrations/entries/index.ts +2 -0
  118. package/src/migrations/entries/schema-prepare-bucket.json +27 -0
  119. package/src/peer-binding.ts +641 -0
  120. package/src/precompile.ts +8 -0
  121. package/src/ref-slot.ts +36 -0
  122. package/src/reference-field-map.ts +42 -0
  123. package/src/referrer-rule.ts +20 -1
  124. package/src/release/index.ts +1 -1
  125. package/src/resolve-ref-sentinels.ts +12 -1
  126. package/src/resource-input.ts +132 -0
  127. package/src/resource-rule.ts +69 -7
  128. package/src/rule-condition.ts +15 -0
  129. package/src/schema-projection.ts +302 -20
  130. package/src/system-kinds.ts +7 -2
  131. package/src/telo-version.ts +1 -1
  132. package/src/template-body.ts +104 -0
  133. package/src/validate-cel-context.ts +73 -78
  134. package/src/validate-identifier-names.ts +18 -3
  135. package/src/validate-reference-forms.ts +22 -0
  136. package/src/validate-references.ts +85 -16
  137. package/src/validate-referrer-rules.ts +215 -28
  138. package/src/validate-resource-inputs.ts +367 -0
  139. package/src/validate-resource-rules.ts +26 -12
  140. package/src/validate-schema-projection.ts +50 -1
  141. package/src/validate-template-dispatch.ts +99 -0
  142. package/src/with-synthetic-positions.ts +1 -1
@@ -1,8 +1,35 @@
1
1
  export { extractAccessChains, validateChainAgainstSchema } from "@telorun/templating";
2
2
  import { elementSchemaOf, isLiveSlot, mergeTypeSchemas, parseCanonicalTypeSchemaId, } from "@telorun/sdk";
3
3
  import { KERNEL_BUILTINS } from "./builtins.js";
4
- import { isStepSlot } from "./step-slot.js";
5
4
  import { withRefSlotsAsReadings } from "./ref-slot-reading.js";
5
+ // Where CEL is evaluated is one reader (`eval-paths.ts`), and the region half of
6
+ // it moved there so the scope walk and the `x-telo-eval` walk answer the same
7
+ // question in one place. Re-exported: this module is where every existing
8
+ // consumer imports them from.
9
+ export { extractCelRegionScopes, pathMatchesScope } from "./eval-paths.js";
10
+ /** True when a node's value is decided at load or dispatch rather than written
11
+ * — a tagged sentinel (`!cel`, `!sql`, an embed) or an already-compiled value.
12
+ * A schema position holding one declares a shape nothing static can read. */
13
+ function isDynamicNode(value) {
14
+ if (!value || typeof value !== "object")
15
+ return false;
16
+ const node = value;
17
+ return node.__tagged === true || node.__compiled !== undefined;
18
+ }
19
+ /** Replace every dynamically-valued property with an OPEN schema, so the name is
20
+ * in scope with its members unconstrained. */
21
+ function openDynamicProperties(props) {
22
+ if (!props || typeof props !== "object")
23
+ return props;
24
+ let out;
25
+ for (const [key, value] of Object.entries(props)) {
26
+ if (!isDynamicNode(value))
27
+ continue;
28
+ out ??= { ...props };
29
+ out[key] = {};
30
+ }
31
+ return out ?? props;
32
+ }
6
33
  /**
7
34
  * Resolve a type field value (string name, inline type, or raw schema) to a JSON Schema.
8
35
  * - String: look up the named type in allManifests (Type.JsonSchema resources)
@@ -229,36 +256,6 @@ function collectionBindingWithheld(schema, manifestRoot, allManifests) {
229
256
  return false;
230
257
  return isLiveSlot(resolveCollectionSchema(manifestRoot, from, allManifests));
231
258
  }
232
- /**
233
- * Returns true when a CEL expression path (from walkCelExpressions, e.g. "routes[0].inputs.q")
234
- * falls within the scope of a context (e.g. "$.routes[*].inputs").
235
- *
236
- * The scope is matched directly (no sibling sharing): a context at "$.routes[*].inputs" only
237
- * applies to expressions whose path starts with "routes[N].inputs", not to other sibling fields.
238
- */
239
- export function pathMatchesScope(exprPath, scope) {
240
- const stripped = scope.startsWith("$.") ? scope.slice(2) : scope;
241
- if (!stripped)
242
- return false;
243
- // Split on wildcard array segments; each [*] must match a concrete [N] in exprPath
244
- const parts = stripped.split("[*]");
245
- let remaining = exprPath;
246
- for (let i = 0; i < parts.length; i++) {
247
- const part = parts[i];
248
- if (!remaining.startsWith(part))
249
- return false;
250
- remaining = remaining.slice(part.length);
251
- if (i < parts.length - 1) {
252
- // Expect a concrete array index like [0], [12], ...
253
- const m = remaining.match(/^\[\d+\]/);
254
- if (!m)
255
- return false;
256
- remaining = remaining.slice(m[0].length);
257
- }
258
- }
259
- // Expression must end here or continue into a child path
260
- return remaining === "" || remaining[0] === "." || remaining[0] === "[";
261
- }
262
259
  /**
263
260
  * Resolves `x-telo-context-*` annotations in a context schema using the concrete
264
261
  * manifest item (per-scope) and the manifest root.
@@ -324,8 +321,19 @@ export function resolveContextAnnotations(schema, manifestItem, opts) {
324
321
  // to be resolved first: the standard library writes it as the inline
325
322
  // `{ kind: Type.JsonSchema, schema: … }` wrapper, so merging it verbatim
326
323
  // would type the variable as `{ kind, schema }` instead of its properties.
324
+ // The navigated node — or one of the properties in it — may itself be an
325
+ // expression: a route whose `request.schema.body` is `!cel "self.model.schema"`
326
+ // declares a body whose SHAPE is only known once the template is
327
+ // instantiated. Such a name types as OPEN rather than as nothing, and a
328
+ // wholly dynamic map leaves the whole node open. Resolving it to nothing
329
+ // reports `request.body` as undefined, which blames the reader for the
330
+ // writer's dynamism — the same posture a rule takes when a value it reads
331
+ // is dynamic: skip the judgement, never invert it.
332
+ if (isDynamicNode(navigated)) {
333
+ return { ...schema, properties: { ...(schema.properties ?? {}) }, additionalProperties: true };
334
+ }
327
335
  const asType = resolveTypeFieldToSchema(navigated, allManifests ?? []);
328
- const resolved = asType?.properties ?? navigated;
336
+ const resolved = openDynamicProperties(asType?.properties ?? navigated);
329
337
  const required = Array.isArray(asType?.required) ? asType.required : undefined;
330
338
  return {
331
339
  ...schema,
@@ -464,14 +472,40 @@ export function resolveContextAnnotations(schema, manifestItem, opts) {
464
472
  */
465
473
  export function getManifestItem(exprPath, scope, manifest) {
466
474
  const stripped = scope.startsWith("$.") ? scope.slice(2) : scope;
467
- const wildcardIdx = stripped.indexOf("[*]");
468
- if (wildcardIdx === -1)
469
- return manifest;
470
- const arrayProp = stripped.slice(0, wildcardIdx); // e.g. "routes"
471
- const m = exprPath.match(new RegExp(`^${arrayProp}\\[(\\d+)\\]`));
472
- if (!m)
475
+ const parts = stripped.split("[*]");
476
+ if (parts.length === 1)
473
477
  return manifest;
474
- return manifest[arrayProp]?.[Number(m[1])] ?? manifest;
478
+ // Resolve each `[*]` against the concrete index the expression path carries at
479
+ // the same position, accumulating up to the LAST wildcard: that node is the
480
+ // per-scope item (`routes[2]`), which is what `x-telo-context-from` navigates
481
+ // from. Built by walking the pattern rather than by a regex over the scope —
482
+ // a scope is a path, not a pattern, and its own `[4]` segments are regex
483
+ // character classes, which is what silently made every nested scope resolve
484
+ // to the whole document instead of the item.
485
+ let remaining = exprPath;
486
+ let concrete = "";
487
+ for (let i = 0; i < parts.length - 1; i++) {
488
+ const part = parts[i];
489
+ if (!remaining.startsWith(part))
490
+ return manifest;
491
+ remaining = remaining.slice(part.length);
492
+ const index = remaining.match(/^\[(\d+)\]/);
493
+ if (!index)
494
+ return manifest;
495
+ remaining = remaining.slice(index[0].length);
496
+ concrete += `${part}${index[0]}`;
497
+ }
498
+ return navigateConcretePath(manifest, concrete) ?? manifest;
499
+ }
500
+ /** Walk a concrete dotted path with `[N]` indices (`resources[4].routes[2]`). */
501
+ function navigateConcretePath(root, path) {
502
+ let cur = root;
503
+ for (const segment of path.match(/[^.[\]]+/g) ?? []) {
504
+ if (cur === null || typeof cur !== "object")
505
+ return undefined;
506
+ cur = cur[segment];
507
+ }
508
+ return cur;
475
509
  }
476
510
  function navigatePath(obj, segments) {
477
511
  let cur = obj;
@@ -496,45 +530,6 @@ export function extractContextsFromSchema(schema, path = "$") {
496
530
  const all = collectContexts(schema, path);
497
531
  return all.sort((a, b) => b.scope.length - a.scope.length);
498
532
  }
499
- /** Schema keys that declare a CEL-bearing region: a field carrying any of these
500
- * is evaluated at runtime, so a `!cel` inside it (or a descendant) is live. A
501
- * STEP BODY is one too, and says so through the grammar its items point at
502
- * rather than through a key — {@link isStepSlot} reads either spelling. */
503
- const CEL_REGION_KEYS = [
504
- "x-telo-context",
505
- "x-telo-step-context",
506
- "x-telo-error-context",
507
- ];
508
- /**
509
- * Walk a JSON Schema tree and collect the JSONPath scopes of every field that
510
- * declares a CEL-bearing region (`x-telo-context` / `x-telo-step-context` /
511
- * `x-telo-error-context`). Used — alongside `x-telo-eval` paths — to decide
512
- * whether a `!cel` expression sits in a slot the runtime actually evaluates.
513
- * Scopes use the same `$.a.b[*]` form as `extractContextsFromSchema`, matched
514
- * against expression paths with `pathMatchesScope`.
515
- */
516
- export function extractCelRegionScopes(schema, path = "$") {
517
- if (!schema || typeof schema !== "object")
518
- return [];
519
- const out = [];
520
- if (CEL_REGION_KEYS.some((k) => schema[k]) || isStepSlot(schema))
521
- out.push(path);
522
- if (schema.properties) {
523
- for (const [key, value] of Object.entries(schema.properties)) {
524
- out.push(...extractCelRegionScopes(value, `${path}.${key}`));
525
- }
526
- }
527
- if (schema.items && typeof schema.items === "object") {
528
- out.push(...extractCelRegionScopes(schema.items, `${path}[*]`));
529
- }
530
- for (const key of ["oneOf", "anyOf", "allOf"]) {
531
- if (Array.isArray(schema[key])) {
532
- for (const subschema of schema[key])
533
- out.push(...extractCelRegionScopes(subschema, path));
534
- }
535
- }
536
- return out;
537
- }
538
533
  function collectContexts(schema, path) {
539
534
  if (!schema || typeof schema !== "object")
540
535
  return [];
@@ -1 +1 @@
1
- {"version":3,"file":"validate-identifier-names.d.ts","sourceRoot":"","sources":["../src/validate-identifier-names.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAOnE,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIrD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,aAAa,EACtB,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EACxB,KAAK,EAAE,SAAS,GACf,kBAAkB,EAAE,CAgEtB"}
1
+ {"version":3,"file":"validate-identifier-names.d.ts","sourceRoot":"","sources":["../src/validate-identifier-names.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAQnE,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIrD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE,aAAa,EACtB,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EACxB,KAAK,EAAE,SAAS,GACf,kBAAkB,EAAE,CAwEtB"}
@@ -1,4 +1,5 @@
1
1
  import { TYPE_LEVEL_DOC_KINDS, checkName, } from "./identifier-name.js";
2
+ import { isInjectedDeclaration } from "./resource-input.js";
2
3
  const SOURCE = "telo-analyzer";
3
4
  /**
4
5
  * Every author-written name in one pass — resource instances, kinds, modules,
@@ -36,6 +37,11 @@ export function validateIdentifierNames(manifests, registry, aliases, rootModule
36
37
  // would blame them for a spelling this pass's own pipeline chose.
37
38
  if (metadata?.xTeloOrigin)
38
39
  continue;
40
+ // A kind-only stand-in for a `resources:` entry carries the name the author
41
+ // wrote in that block, and the block's own keys are checked below — on the
42
+ // module doc, where the name is written and a squiggle can land.
43
+ if (isInjectedDeclaration(manifest))
44
+ continue;
39
45
  const ownModule = metadata?.module;
40
46
  if (ownModule && !rootModules.has(ownModule))
41
47
  continue;
@@ -53,7 +59,10 @@ export function validateIdentifierNames(manifests, registry, aliases, rootModule
53
59
  // keys are the imported library's declarations, so a violation there is
54
60
  // the library author's, reported when their module is analyzed as a root.
55
61
  if (manifest.kind === "Telo.Application" || manifest.kind === "Telo.Library") {
56
- for (const field of ["variables", "secrets", "ports"]) {
62
+ // `resources:` joins them: a library's resource inputs are named in the
63
+ // same identifier space (`!ref connection`, `resources.connection`) and
64
+ // break the same way.
65
+ for (const field of ["variables", "secrets", "ports", "resources"]) {
57
66
  const block = manifest[field];
58
67
  if (!block || typeof block !== "object" || Array.isArray(block))
59
68
  continue;
@@ -125,7 +134,13 @@ function surfaceFor(kind) {
125
134
  }
126
135
  }
127
136
  function singular(field) {
128
- return field === "variables" ? "variable" : field === "secrets" ? "secret" : "port";
137
+ return field === "variables"
138
+ ? "variable"
139
+ : field === "secrets"
140
+ ? "secret"
141
+ : field === "ports"
142
+ ? "port"
143
+ : "resource input";
129
144
  }
130
145
  function push(out, violation, at) {
131
146
  if (!violation)
@@ -23,6 +23,16 @@ import { type AnalysisDiagnostic } from "./types.js";
23
23
  * Rejected, each with an actionable diagnostic pointing at `!ref`:
24
24
  * - the object form `{ kind, name }` (the old reference object), and
25
25
  * - a bare string (the old name / dotted-FQN reference).
26
+ *
27
+ * **A value-or-reference union slot is the one exception**, and it is decided by
28
+ * the value rather than by a new spelling: where the reference constraint is a
29
+ * *branch* of a union (`type:` on a column, holding either a storage class or a
30
+ * `!ref` to a declared enum), a SCALAR is a value and is left to that branch,
31
+ * while an object is still checked for the removed `{kind, name}` form unless a
32
+ * branch describes it. The rule guards a REMOVED spelling — a bare string is
33
+ * simply not a reference in Telo — so admitting one takes nothing away: what it
34
+ * costs is the answer when an author meant a reference and wrote a bare name,
35
+ * which against a closed branch AJV reports as an unknown value.
26
36
  */
27
37
  export declare function validateReferenceForms(resources: ResourceManifest[], registry: DefinitionRegistry, aliases?: AliasResolver, aliasesByModule?: Map<string, AliasResolver>): AnalysisDiagnostic[];
28
38
  //# sourceMappingURL=validate-reference-forms.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate-reference-forms.d.ts","sourceRoot":"","sources":["../src/validate-reference-forms.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAGnE,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIzE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,CAAC,EAAE,aAAa,EACvB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GAC3C,kBAAkB,EAAE,CA+DtB"}
1
+ {"version":3,"file":"validate-reference-forms.d.ts","sourceRoot":"","sources":["../src/validate-reference-forms.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAInE,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,CAAC,EAAE,aAAa,EACvB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GAC3C,kBAAkB,EAAE,CA0EtB"}
@@ -1,5 +1,6 @@
1
1
  import { isTaggedSentinel } from "@telorun/templating";
2
2
  import { visitManifest } from "./manifest-visitor.js";
3
+ import { satisfiesValueBranch } from "./reference-field-map.js";
3
4
  import { REF_VALIDATION_SKIP_KINDS as SYSTEM_KINDS } from "./system-kinds.js";
4
5
  import { DiagnosticSeverity } from "./types.js";
5
6
  const SOURCE = "telo-analyzer";
@@ -24,6 +25,16 @@ const SOURCE = "telo-analyzer";
24
25
  * Rejected, each with an actionable diagnostic pointing at `!ref`:
25
26
  * - the object form `{ kind, name }` (the old reference object), and
26
27
  * - a bare string (the old name / dotted-FQN reference).
28
+ *
29
+ * **A value-or-reference union slot is the one exception**, and it is decided by
30
+ * the value rather than by a new spelling: where the reference constraint is a
31
+ * *branch* of a union (`type:` on a column, holding either a storage class or a
32
+ * `!ref` to a declared enum), a SCALAR is a value and is left to that branch,
33
+ * while an object is still checked for the removed `{kind, name}` form unless a
34
+ * branch describes it. The rule guards a REMOVED spelling — a bare string is
35
+ * simply not a reference in Telo — so admitting one takes nothing away: what it
36
+ * costs is the answer when an author meant a reference and wrote a bare name,
37
+ * which against a closed branch AJV reports as an unknown value.
27
38
  */
28
39
  export function validateReferenceForms(resources, registry, aliases, aliasesByModule) {
29
40
  if (!aliases)
@@ -37,6 +48,18 @@ export function validateReferenceForms(resources, registry, aliases, aliasesByMo
37
48
  // `!ref` and `!cel`/`${{ }}` sentinels are the supported shapes.
38
49
  if (isTaggedSentinel(value))
39
50
  return;
51
+ // A SCALAR at a slot whose union has a value branch is a value, and the
52
+ // value branch is what judges it. Reporting a mistyped storage class as
53
+ // a malformed reference — "write it as '!ref txt'" — instructs the author
54
+ // to convert a typo into a reference, and AJV has already said what the
55
+ // value must be one of. The object form below is not ambiguous the same
56
+ // way: `{kind, name}` is the removed reference object, so it is still
57
+ // reported unless a branch genuinely describes that shape.
58
+ const hasValueBranch = (e.entry.valueBranches?.length ?? 0) > 0;
59
+ if (hasValueBranch && typeof value !== "object")
60
+ return;
61
+ if (satisfiesValueBranch(value, e.entry.valueBranches, registry))
62
+ return;
40
63
  const r = e.source;
41
64
  const resourceLabel = `${r.kind}/${r.metadata.name}`;
42
65
  const resourceData = { kind: r.kind, name: r.metadata.name };
@@ -1,5 +1,22 @@
1
1
  import type { ResourceManifest } from "@telorun/sdk";
2
2
  import { type AnalysisDiagnostic, type AnalysisContext } from "./types.js";
3
+ import type { DefinitionRegistry } from "./definition-registry.js";
4
+ /**
5
+ * Liskov substitutability at a kind constraint: is `resolved` (a canonical
6
+ * `<module>.<Kind>`) accepted where `targetKind` is required?
7
+ *
8
+ * THE one implementation — `checkKind` below builds a MESSAGE from it and adds
9
+ * nothing to the rule, so a resource input's injection site and an ordinary ref
10
+ * slot cannot come to disagree about what satisfies a constraint.
11
+ *
12
+ * A value satisfies the slot when it transitively extends the target kind, or —
13
+ * for a CONCRETE target — IS that kind; `getByExtends` is the same transitive
14
+ * subtype index for both, and an abstract is satisfied only by an implementer,
15
+ * never by the abstract itself (which is non-instantiable). Accepts a constraint
16
+ * that resolves to nothing, and an abstract with no loaded implementations:
17
+ * partial context, where a rejection would be a guess.
18
+ */
19
+ export declare function kindSatisfies(resolved: string, targetKind: string, registry: DefinitionRegistry): boolean;
3
20
  /**
4
21
  * Phase 3 — Reference validation.
5
22
  *
@@ -1 +1 @@
1
- {"version":3,"file":"validate-references.d.ts","sourceRoot":"","sources":["../src/validate-references.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAOrD,OAAO,EAAsB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAuD/F;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,EAAE,eAAe,GACvB,kBAAkB,EAAE,CAogBtB"}
1
+ {"version":3,"file":"validate-references.d.ts","sourceRoot":"","sources":["../src/validate-references.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAarD,OAAO,EAAsB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAE/F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAInE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,kBAAkB,GAC3B,OAAO,CAwBT;AA8DD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,EAAE,eAAe,GACvB,kBAAkB,EAAE,CA2gBtB"}
@@ -1,19 +1,73 @@
1
1
  import { isRefSentinel } from "@telorun/templating";
2
2
  import { visitManifest } from "./manifest-visitor.js";
3
- import { isInlineResource, resolveFieldEntries, resolveFieldValues } from "./reference-field-map.js";
3
+ import { isInlineResource, resolveFieldEntries, resolveFieldValues, satisfiesValueBranch, } from "./reference-field-map.js";
4
4
  import { navigateJsonPointer, substituteCelFields } from "./schema-compat.js";
5
5
  import { REF_VALIDATION_SKIP_KINDS as SYSTEM_KINDS } from "./system-kinds.js";
6
6
  import { resolveTypeFieldToSchema } from "./validate-cel-context.js";
7
7
  import { DiagnosticSeverity } from "./types.js";
8
8
  const SOURCE = "telo-analyzer";
9
9
  /**
10
- * Checks whether `kind` satisfies the ref constraint in `entry`.
11
- * Returns an empty array when valid, or mismatch error strings when not.
12
- * Returns an empty array immediately when the ref identity is not registered
13
- * (partial contextskip check rather than false-positive).
10
+ * Liskov substitutability at a kind constraint: is `resolved` (a canonical
11
+ * `<module>.<Kind>`) accepted where `targetKind` is required?
12
+ *
13
+ * THE one implementation `checkKind` below builds a MESSAGE from it and adds
14
+ * nothing to the rule, so a resource input's injection site and an ordinary ref
15
+ * slot cannot come to disagree about what satisfies a constraint.
16
+ *
17
+ * A value satisfies the slot when it transitively extends the target kind, or —
18
+ * for a CONCRETE target — IS that kind; `getByExtends` is the same transitive
19
+ * subtype index for both, and an abstract is satisfied only by an implementer,
20
+ * never by the abstract itself (which is non-instantiable). Accepts a constraint
21
+ * that resolves to nothing, and an abstract with no loaded implementations:
22
+ * partial context, where a rejection would be a guess.
14
23
  */
24
+ export function kindSatisfies(resolved, targetKind, registry) {
25
+ const canonical = registry.resolveRef(targetKind) ?? targetKind;
26
+ const targetDef = registry.resolve(canonical);
27
+ if (!targetDef)
28
+ return true;
29
+ if (targetDef.kind !== "Telo.Abstract" && resolved === canonical)
30
+ return true;
31
+ const subtypes = registry.getByExtends(canonical);
32
+ if (subtypes.some((d) => `${d.metadata.module}.${d.metadata.name}` === resolved))
33
+ return true;
34
+ // Leniency is about the CANDIDATE, not about the population, and it is the
35
+ // same question for an abstract target and a concrete one. Accepting whenever
36
+ // no subtype happened to be loaded silenced the check exactly where it was
37
+ // needed: an app whose imports declare no `Telo.Runnable` is an app whose boot
38
+ // targets are all wrong, and every one of them passed.
39
+ //
40
+ // An UNREGISTERED candidate is not partial context, and the distinction is
41
+ // load-bearing: a kind nobody declared is an unknown kind or an unimported
42
+ // alias prefix (`NotAnAlias.Script`), which is precisely what this check
43
+ // exists to report. Only a kind that IS declared, whose ancestry reaches
44
+ // something this analysis never saw, is undecidable — there the missing hop is
45
+ // where the target it appears not to reach could have been declared.
46
+ // A candidate the registry never saw cannot be judged on what it implements —
47
+ // the analysis simply does not hold it. Whether its NAME is resolvable is a
48
+ // different question, asked of the alias scope by the caller.
49
+ if (!registry.resolve(resolved))
50
+ return true;
51
+ return !registry.ancestryResolved(resolved);
52
+ }
53
+ /** {@link kindSatisfies} at every kind a slot accepts, rendered as messages.
54
+ * The acceptance rule is not restated here — only what to say when it fails,
55
+ * which needs the slot's alternatives and the target's flavour. */
15
56
  function checkKind(kind, entry, registry, aliases) {
16
57
  const resolved = aliases.resolveKind(kind) ?? kind;
58
+ // A qualified kind whose prefix names no import in this scope is a bad NAME
59
+ // rather than a bad type — `{kind: NotAnAlias.Script}` where only `Lib` is
60
+ // imported — and this check is the only place it surfaces, so it is never
61
+ // waved through as partial context. Asked of the resolver, which reports
62
+ // `unknown` for exactly that case: a kind reached through a DECLARED alias
63
+ // resolves (`ok`) even when the target's definitions are not loaded, and a
64
+ // gated one says so separately.
65
+ const unknownAlias = kind.includes(".") &&
66
+ aliases.resolveKindResult(kind).status === "unknown" &&
67
+ // …and the registry does not hold it under the name as written either. A
68
+ // manifest may carry a canonical `<module>.<Kind>`, which no alias resolves
69
+ // and which is nonetheless perfectly identified.
70
+ registry.resolve(resolved) === undefined;
17
71
  const errors = [];
18
72
  for (const refStr of entry.refs) {
19
73
  const targetKind = registry.resolveRef(refStr);
@@ -22,20 +76,11 @@ function checkKind(kind, entry, registry, aliases) {
22
76
  const targetDef = registry.resolve(targetKind);
23
77
  if (!targetDef)
24
78
  return [];
25
- // Liskov substitutability: a value satisfies the slot when it transitively
26
- // extends the target kind, or — for a CONCRETE target — IS that kind.
27
- // `getByExtends` is the same transitive subtype index for abstract and
28
- // concrete targets alike; an abstract is satisfied only by an implementer,
29
- // never by the abstract kind itself (which is non-instantiable).
30
- if (targetDef.kind !== "Telo.Abstract" && resolved === targetKind)
79
+ if (!unknownAlias && kindSatisfies(resolved, targetKind, registry))
31
80
  return [];
32
81
  const subtypes = registry.getByExtends(targetKind);
33
82
  const subtypeKinds = new Set(subtypes.map((d) => `${d.metadata.module}.${d.metadata.name}`));
34
- if (subtypeKinds.has(resolved))
35
- return [];
36
83
  if (targetDef.kind === "Telo.Abstract") {
37
- if (subtypes.length === 0)
38
- return []; // partial context — no implementations loaded yet
39
84
  // Suggest only what an author can actually wire: with abstract-extends-
40
85
  // abstract real (Telo.Executable over Invocable/Runnable), the transitive
41
86
  // subtype list contains abstracts, which are non-instantiable and would
@@ -43,8 +88,15 @@ function checkKind(kind, entry, registry, aliases) {
43
88
  const concrete = subtypes
44
89
  .filter((d) => d.kind !== "Telo.Abstract")
45
90
  .map((d) => `${d.metadata.module}.${d.metadata.name}`);
46
- const options = (concrete.length > 0 ? concrete : [...subtypeKinds]).join(", ");
47
- errors.push(`'${kind}' does not implement '${targetKind}' (known implementations: ${options})`);
91
+ const options = concrete.length > 0 ? concrete : [...subtypeKinds];
92
+ // With nothing loaded that implements the target there is no list to
93
+ // offer, so the message says what this kind IS instead — which is the
94
+ // half the author can act on ("it declares 'Telo.Invocable'" points
95
+ // straight at a boot target that should have been an invoke step).
96
+ const declared = registry.resolve(resolved)?.capability;
97
+ errors.push(options.length > 0
98
+ ? `'${kind}' does not implement '${targetKind}' (known implementations: ${options.join(", ")})`
99
+ : `'${kind}' does not implement '${targetKind}'${declared ? ` — it declares '${declared}'` : ""}`);
48
100
  }
49
101
  else {
50
102
  const options = subtypeKinds.size > 0 ? ` or a subtype (${[...subtypeKinds].join(", ")})` : "";
@@ -91,7 +143,7 @@ export function validateReferences(resources, context) {
91
143
  // Group manifests by name to detect collisions. Two subtleties:
92
144
  //
93
145
  // 1. Some analyzer hosts emit the SAME physical document twice through
94
- // their pipeline — e.g. the telo-editor's `toAnalysisManifests` walks
146
+ // their pipeline — e.g. telo studio's `toAnalysisManifests` walks
95
147
  // each workspace module's documents independently, and a file
96
148
  // reachable from two angles (entry module + `include:` partial)
97
149
  // shows up twice. The fingerprint includes `sourceLine` so identical
@@ -278,6 +330,13 @@ export function validateReferences(resources, context) {
278
330
  if (typeof val !== "object")
279
331
  return;
280
332
  const refVal = val;
333
+ // A value the slot's own union describes is a value, not a reference —
334
+ // the same narrowing `validateReferenceForms` applies, through the same
335
+ // function, because it has to be applied here too: an OBJECT-shaped value
336
+ // branch would otherwise reach the structural check below and be reported
337
+ // as a reference missing 'kind' and 'name'.
338
+ if (satisfiesValueBranch(val, entry.valueBranches, registry))
339
+ return;
281
340
  // Skip inline resources — Phase 2 normalization hasn't run yet.
282
341
  if (isInlineResource(refVal))
283
342
  return;
@@ -24,6 +24,8 @@
24
24
  */
25
25
  import type { ResourceManifest } from "@telorun/sdk";
26
26
  import { type ReferrerRule } from "./referrer-rule.js";
27
+ import type { PeerBinder, PeerBindingFailure, PeersTarget } from "./peer-binding.js";
28
+ import { type DynamicLeaf } from "./resource-rule.js";
27
29
  export interface ReferrerRuleIssue {
28
30
  code: "REFERRER_RULE_INVALID";
29
31
  manifest: ResourceManifest;
@@ -48,7 +50,12 @@ export type ReferrerRuleFinding = {
48
50
  kind: "skipped";
49
51
  rule: ReferrerRule;
50
52
  referrer: Referrer;
51
- dynamicAt: string;
53
+ dynamic: DynamicLeaf;
54
+ } | {
55
+ kind: "unbound";
56
+ rule: ReferrerRule;
57
+ referrer: Referrer;
58
+ failure: PeerBindingFailure;
52
59
  } | {
53
60
  kind: "failed";
54
61
  rule: ReferrerRule;
@@ -60,6 +67,28 @@ export type ReferrerRuleFinding = {
60
67
  referrer: Referrer;
61
68
  elapsedMs: number;
62
69
  };
70
+ /** What a peer rule needs beyond the referrers themselves: the binder that
71
+ * resolves a referrer's collection into declarations. Absent for a host that
72
+ * cannot resolve one — a rule declaring `peers:` then reports as unbound rather
73
+ * than running with the binding missing, which would evaluate a condition
74
+ * against names that are simply not there.
75
+ *
76
+ * ONE binder per analysis, because it caches each referrer's resolved
77
+ * collection and both the evaluation and the exercised check ask for it. */
78
+ export interface ReferrerRuleContext {
79
+ readonly peerBinder?: PeerBinder;
80
+ }
81
+ /** What a `peers:` pointer names in the referrer kind it is filtered to. Defined
82
+ * with the binding vocabulary; re-exported here because this is the surface
83
+ * that consumes it. The caller resolves it — only it holds the definition
84
+ * registry, and only after every kind is registered, since a rule may name a
85
+ * kind declared later in the same file. */
86
+ export type { PeersTarget };
87
+ export interface ReferrerRuleDeclarationContext {
88
+ /** Resolves a rule's `peers:` against its `referrer:` kind. Omit to skip the
89
+ * check — the safe direction for a host with no registry. */
90
+ readonly peersTarget?: (referrerKind: string, pointer: string) => PeersTarget;
91
+ }
63
92
  /**
64
93
  * Report every way a kind's referrer-rule declarations are malformed. Runs on
65
94
  * the `Telo.Definition` / `Telo.Abstract` doc, so a defect lands on the line the
@@ -69,7 +98,7 @@ export type ReferrerRuleFinding = {
69
98
  * declaring module's scope by `resolveSchemaRefKinds`, the only pass holding
70
99
  * that scope, and a name resolving to nothing is reported from there.
71
100
  */
72
- export declare function validateReferrerRuleDeclarations(manifest: ResourceManifest): ReferrerRuleIssue[];
101
+ export declare function validateReferrerRuleDeclarations(manifest: ResourceManifest, context?: ReferrerRuleDeclarationContext): ReferrerRuleIssue[];
73
102
  /**
74
103
  * Run a kind's referrer rules against every resource that references one of its
75
104
  * resources.
@@ -79,16 +108,21 @@ export declare function validateReferrerRuleDeclarations(manifest: ResourceManif
79
108
  * manifest identity, since a name alone is module-scoped — because the condition
80
109
  * reads the two manifests and nothing about the site, so a second site could only
81
110
  * produce the identical verdict at a different path.
111
+ *
112
+ * **A rule declaring `peers:` is the exception, and evaluates once per ENTRY.**
113
+ * That is a deliberate departure from judge-once rather than an inconsistency: a
114
+ * rule that binds `entry` is about the entry, so a resource listed twice has two
115
+ * entries to answer for, and the two sites can genuinely disagree.
82
116
  */
83
117
  export declare function evaluateReferrerRules(manifest: ResourceManifest, definitionSchema: unknown, referrers: readonly Referrer[],
84
118
  /** Whether a referrer of `kind` satisfies a rule's `referrer:` filter —
85
119
  * Liskov-substitutable, so a child of the named kind matches. Supplied by the
86
120
  * caller, which holds the definition registry. */
87
- kindMatches: (filter: string, kind: string) => boolean): ReferrerRuleFinding[];
121
+ kindMatches: (filter: string, kind: string) => boolean, context?: ReferrerRuleContext): ReferrerRuleFinding[];
88
122
  /** Whether a rule found any referrer to judge — the input to the never-exercised
89
123
  * report, which is how a mistyped `referrer:` filter would otherwise disable a
90
124
  * check in silence. */
91
- export declare function referrerRuleExercised(rule: ReferrerRule, referrers: readonly Referrer[], kindMatches: (filter: string, kind: string) => boolean): boolean;
125
+ export declare function referrerRuleExercised(rule: ReferrerRule, referrers: readonly Referrer[], kindMatches: (filter: string, kind: string) => boolean, context?: ReferrerRuleContext): boolean;
92
126
  /** Where a referrer-rule finding is reported, and how loudly. Plain data, so the
93
127
  * caller pushes it exactly as it does for the resource-rule reports. */
94
128
  export interface ReferrerRuleDiagnostic {
@@ -1 +1 @@
1
- {"version":3,"file":"validate-referrer-rules.d.ts","sourceRoot":"","sources":["../src/validate-referrer-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAIL,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAC;AAI5B,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,uBAAuB,CAAC;IAC9B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,+EAA+E;AAC/E,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,kFAAkF;IAClF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,0CAA0C;AAC1C,MAAM,MAAM,mBAAmB,GAC3B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC9E;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAC9E;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC3E;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAMvF;;;;;;;;GAQG;AACH,wBAAgB,gCAAgC,CAAC,QAAQ,EAAE,gBAAgB,GAAG,iBAAiB,EAAE,CA2EhG;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,gBAAgB,EAC1B,gBAAgB,EAAE,OAAO,EACzB,SAAS,EAAE,SAAS,QAAQ,EAAE;AAC9B;;mDAEmD;AACnD,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,GACrD,mBAAmB,EAAE,CAmEvB;AAED;;wBAEwB;AACxB,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,YAAY,EAClB,SAAS,EAAE,SAAS,QAAQ,EAAE,EAC9B,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,GACrD,OAAO,CAIT;AAED;yEACyE;AACzE,MAAM,WAAW,sBAAsB;IACrC,IAAI,EACA,wBAAwB,GACxB,uBAAuB,GACvB,uBAAuB,GACvB,2BAA2B,CAAC;IAChC,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,aAAa,CAAC;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB;oEACgE;IAChE,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAKD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,gBAAgB,GAAG,SAAS,EACxC,QAAQ,EAAE,SAAS,mBAAmB,EAAE;AACxC,0EAA0E;AAC1E,iBAAiB,EAAE,OAAO,GACzB,sBAAsB,EAAE,CAmE1B;AAED;;kDAEkD;AAClD,wBAAgB,6BAA6B,CAC3C,UAAU,EAAE,gBAAgB,EAC5B,IAAI,EAAE,YAAY,GACjB,sBAAsB,CAexB"}
1
+ {"version":3,"file":"validate-referrer-rules.d.ts","sourceRoot":"","sources":["../src/validate-referrer-rules.ts"],"names":[],"mappings":"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"}