@telorun/analyzer 0.71.0 → 0.73.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 (139) hide show
  1. package/dist/analyzer.d.ts.map +1 -1
  2. package/dist/analyzer.js +92 -15
  3. package/dist/builtins.d.ts.map +1 -1
  4. package/dist/builtins.js +71 -97
  5. package/dist/catch-scope.d.ts +72 -0
  6. package/dist/catch-scope.d.ts.map +1 -0
  7. package/dist/catch-scope.js +102 -0
  8. package/dist/cel-scope-query.d.ts.map +1 -1
  9. package/dist/cel-scope-query.js +32 -11
  10. package/dist/cel-scope.d.ts.map +1 -1
  11. package/dist/cel-scope.js +1 -0
  12. package/dist/deprecation.d.ts +21 -0
  13. package/dist/deprecation.d.ts.map +1 -0
  14. package/dist/deprecation.js +26 -0
  15. package/dist/eval-paths.d.ts +36 -5
  16. package/dist/eval-paths.d.ts.map +1 -1
  17. package/dist/eval-paths.js +47 -6
  18. package/dist/extends-resolution.d.ts +12 -0
  19. package/dist/extends-resolution.d.ts.map +1 -1
  20. package/dist/extends-resolution.js +23 -0
  21. package/dist/index.d.ts +4 -2
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +3 -2
  24. package/dist/manifest-visitor.d.ts +17 -1
  25. package/dist/manifest-visitor.d.ts.map +1 -1
  26. package/dist/manifest-visitor.js +5 -1
  27. package/dist/migrations/report.d.ts +1 -1
  28. package/dist/migrations/report.d.ts.map +1 -1
  29. package/dist/migrations/report.js +5 -0
  30. package/dist/nearest-name.d.ts +22 -0
  31. package/dist/nearest-name.d.ts.map +1 -0
  32. package/dist/nearest-name.js +43 -0
  33. package/dist/ref-slot.d.ts +15 -0
  34. package/dist/ref-slot.d.ts.map +1 -1
  35. package/dist/ref-slot.js +7 -0
  36. package/dist/release/destinations.d.ts +59 -0
  37. package/dist/release/destinations.d.ts.map +1 -0
  38. package/dist/release/destinations.js +75 -0
  39. package/dist/release/index.d.ts +6 -2
  40. package/dist/release/index.d.ts.map +1 -1
  41. package/dist/release/index.js +3 -1
  42. package/dist/release/ledger.d.ts +20 -11
  43. package/dist/release/ledger.d.ts.map +1 -1
  44. package/dist/release/ledger.js +43 -14
  45. package/dist/release/release-plan.d.ts +3 -2
  46. package/dist/release/release-plan.d.ts.map +1 -1
  47. package/dist/release/release-plan.js +12 -19
  48. package/dist/release/workspace-config.d.ts +114 -34
  49. package/dist/release/workspace-config.d.ts.map +1 -1
  50. package/dist/release/workspace-config.js +322 -38
  51. package/dist/release/workspace-schema.d.ts +41 -0
  52. package/dist/release/workspace-schema.d.ts.map +1 -0
  53. package/dist/release/workspace-schema.js +77 -0
  54. package/dist/resolve-throws-union.d.ts +29 -1
  55. package/dist/resolve-throws-union.d.ts.map +1 -1
  56. package/dist/resolve-throws-union.js +111 -16
  57. package/dist/schema-compat.d.ts.map +1 -1
  58. package/dist/schema-compat.js +13 -1
  59. package/dist/schema-error-report.d.ts +7 -0
  60. package/dist/schema-error-report.d.ts.map +1 -1
  61. package/dist/schema-error-report.js +57 -8
  62. package/dist/schema-keywords.d.ts.map +1 -1
  63. package/dist/schema-keywords.js +3 -1
  64. package/dist/schema-walk.d.ts +27 -0
  65. package/dist/schema-walk.d.ts.map +1 -1
  66. package/dist/schema-walk.js +44 -0
  67. package/dist/telo-version.d.ts +1 -1
  68. package/dist/telo-version.js +1 -1
  69. package/dist/template-body.d.ts +10 -0
  70. package/dist/template-body.d.ts.map +1 -1
  71. package/dist/template-body.js +25 -0
  72. package/dist/types.d.ts +17 -0
  73. package/dist/types.d.ts.map +1 -1
  74. package/dist/types.js +11 -0
  75. package/dist/validate-cel-context.d.ts +23 -8
  76. package/dist/validate-cel-context.d.ts.map +1 -1
  77. package/dist/validate-cel-context.js +48 -16
  78. package/dist/validate-exports.d.ts +28 -0
  79. package/dist/validate-exports.d.ts.map +1 -0
  80. package/dist/validate-exports.js +146 -0
  81. package/dist/validate-extends.d.ts.map +1 -1
  82. package/dist/validate-extends.js +37 -1
  83. package/dist/validate-identifier-names.d.ts +2 -2
  84. package/dist/validate-identifier-names.d.ts.map +1 -1
  85. package/dist/validate-identifier-names.js +22 -7
  86. package/dist/validate-provider-coherence.d.ts +4 -8
  87. package/dist/validate-provider-coherence.d.ts.map +1 -1
  88. package/dist/validate-provider-coherence.js +12 -123
  89. package/dist/validate-ref-slots.d.ts +1 -1
  90. package/dist/validate-ref-slots.d.ts.map +1 -1
  91. package/dist/validate-ref-slots.js +34 -0
  92. package/dist/validate-references.d.ts.map +1 -1
  93. package/dist/validate-references.js +168 -63
  94. package/dist/validate-template-body.d.ts +36 -0
  95. package/dist/validate-template-body.d.ts.map +1 -0
  96. package/dist/validate-template-body.js +246 -0
  97. package/dist/validate-throws-coverage.d.ts.map +1 -1
  98. package/dist/validate-throws-coverage.js +236 -85
  99. package/package.json +3 -2
  100. package/src/analyzer.ts +118 -12
  101. package/src/builtins.ts +85 -97
  102. package/src/catch-scope.ts +157 -0
  103. package/src/cel-scope-query.ts +28 -9
  104. package/src/cel-scope.ts +1 -0
  105. package/src/deprecation.ts +36 -0
  106. package/src/eval-paths.ts +53 -6
  107. package/src/extends-resolution.ts +24 -0
  108. package/src/index.ts +9 -1
  109. package/src/manifest-visitor.ts +19 -2
  110. package/src/migrations/report.ts +5 -1
  111. package/src/nearest-name.ts +47 -0
  112. package/src/ref-slot.ts +19 -0
  113. package/src/release/destinations.ts +105 -0
  114. package/src/release/index.ts +33 -2
  115. package/src/release/ledger.ts +51 -21
  116. package/src/release/release-plan.ts +16 -26
  117. package/src/release/workspace-config.ts +483 -47
  118. package/src/release/workspace-schema.ts +99 -0
  119. package/src/resolve-throws-union.ts +139 -21
  120. package/src/schema-compat.ts +13 -0
  121. package/src/schema-error-report.ts +66 -10
  122. package/src/schema-keywords.ts +4 -1
  123. package/src/schema-walk.ts +56 -0
  124. package/src/telo-version.ts +1 -1
  125. package/src/template-body.ts +25 -0
  126. package/src/types.ts +18 -0
  127. package/src/validate-cel-context.ts +57 -16
  128. package/src/validate-exports.ts +185 -0
  129. package/src/validate-extends.ts +43 -0
  130. package/src/validate-identifier-names.ts +28 -9
  131. package/src/validate-provider-coherence.ts +17 -127
  132. package/src/validate-ref-slots.ts +41 -1
  133. package/src/validate-references.ts +174 -63
  134. package/src/validate-template-body.ts +274 -0
  135. package/src/validate-throws-coverage.ts +333 -92
  136. package/dist/validate-template-dispatch.d.ts +0 -27
  137. package/dist/validate-template-dispatch.d.ts.map +0 -1
  138. package/dist/validate-template-dispatch.js +0 -95
  139. package/src/validate-template-dispatch.ts +0 -99
@@ -1,95 +0,0 @@
1
- import { isRefSentinel } from "@telorun/templating";
2
- import { distance } from "./levenshtein.js";
3
- import { DiagnosticSeverity } from "./types.js";
4
- const SOURCE = "telo-analyzer";
5
- /** The four slots a `Telo.Definition` names its dispatch target in. Each takes
6
- * the same grammar; which one is legal for a given capability is
7
- * `validate-provider-coherence`'s question, not this one's. */
8
- const DISPATCH_FIELDS = ["invoke", "run", "provide", "mount"];
9
- /**
10
- * A `!ref` at a definition's dispatch slot must name a sibling `resources:`
11
- * entry.
12
- *
13
- * `!ref` is the one spelling an author — and the editor's rename, completion and
14
- * go-to-definition — expects to be RESOLVED. But a `Telo.Definition` is in both
15
- * `REF_VALIDATION_SKIP_KINDS` and `REF_RESOLUTION_SKIP_KINDS`, and the dispatch
16
- * slots carry no `x-telo-ref` (the accepted targets are the definition's own
17
- * template-internal entries, not resources of any module), so no reference pass
18
- * reaches them. Introducing the tag at a slot nothing resolves would be worse
19
- * than the string form it replaces: a typo that used to be an obvious runtime
20
- * miss becomes a typo in a construct that advertises static resolution.
21
- *
22
- * Decidable only when every sibling name is LITERAL. A template routinely names
23
- * its entries with CEL (`name: !cel "self.name + '-query'"`), and an expression
24
- * could expand to the referenced name — so one dynamic sibling switches the
25
- * check off for that definition rather than inventing a miss.
26
- *
27
- * Entry-module-scoped, like every other declaration check: a published
28
- * dependency's template body is not the consumer's to fix.
29
- *
30
- * Browser-safe.
31
- */
32
- export function validateTemplateDispatch(manifests, rootModules) {
33
- const out = [];
34
- for (const m of manifests) {
35
- if (m.kind !== "Telo.Definition")
36
- continue;
37
- const meta = m.metadata;
38
- const name = meta?.name;
39
- if (!name)
40
- continue;
41
- if (meta?.module && !rootModules.has(meta.module))
42
- continue;
43
- const bodies = m.resources;
44
- if (!Array.isArray(bodies))
45
- continue;
46
- const siblings = [];
47
- let anyDynamic = false;
48
- for (const entry of bodies) {
49
- const entryName = entry?.metadata?.name;
50
- if (typeof entryName === "string" && !entryName.includes("${{"))
51
- siblings.push(entryName);
52
- else if (entryName !== undefined)
53
- anyDynamic = true;
54
- }
55
- if (anyDynamic)
56
- continue;
57
- for (const field of DISPATCH_FIELDS) {
58
- const value = m[field];
59
- if (!isRefSentinel(value))
60
- continue;
61
- const source = value.source;
62
- const target = source.startsWith("Self.") ? source.slice("Self.".length) : source;
63
- if (siblings.includes(target))
64
- continue;
65
- const suggestion = nearest(target, siblings);
66
- out.push({
67
- severity: DiagnosticSeverity.Error,
68
- code: "TEMPLATE_DISPATCH_UNKNOWN",
69
- source: SOURCE,
70
- message: `${m.kind}/${name}: '${field}: !ref ${source}' names no entry in 'resources:'. ` +
71
- `Available: ${siblings.join(", ") || "(none)"}.` +
72
- (suggestion ? ` Did you mean '${suggestion}'?` : ""),
73
- data: {
74
- resource: { kind: m.kind, name },
75
- filePath: meta?.source,
76
- path: field,
77
- ...(suggestion ? { fix: { replacement: suggestion } } : {}),
78
- },
79
- });
80
- }
81
- }
82
- return out;
83
- }
84
- /** The closest sibling name, when one is close enough to be a typo rather than a
85
- * different name. */
86
- function nearest(target, candidates) {
87
- let best;
88
- for (const candidate of candidates) {
89
- const d = distance(target, candidate);
90
- if (!best || d < best.d)
91
- best = { name: candidate, d };
92
- }
93
- const limit = Math.max(1, Math.floor(target.length / 3));
94
- return best && best.d <= limit ? best.name : undefined;
95
- }
@@ -1,99 +0,0 @@
1
- import type { ResourceManifest } from "@telorun/sdk";
2
- import { isRefSentinel } from "@telorun/templating";
3
- import { distance } from "./levenshtein.js";
4
- import { DiagnosticSeverity, type AnalysisDiagnostic } from "./types.js";
5
-
6
- const SOURCE = "telo-analyzer";
7
-
8
- /** The four slots a `Telo.Definition` names its dispatch target in. Each takes
9
- * the same grammar; which one is legal for a given capability is
10
- * `validate-provider-coherence`'s question, not this one's. */
11
- const DISPATCH_FIELDS = ["invoke", "run", "provide", "mount"] as const;
12
-
13
- /**
14
- * A `!ref` at a definition's dispatch slot must name a sibling `resources:`
15
- * entry.
16
- *
17
- * `!ref` is the one spelling an author — and the editor's rename, completion and
18
- * go-to-definition — expects to be RESOLVED. But a `Telo.Definition` is in both
19
- * `REF_VALIDATION_SKIP_KINDS` and `REF_RESOLUTION_SKIP_KINDS`, and the dispatch
20
- * slots carry no `x-telo-ref` (the accepted targets are the definition's own
21
- * template-internal entries, not resources of any module), so no reference pass
22
- * reaches them. Introducing the tag at a slot nothing resolves would be worse
23
- * than the string form it replaces: a typo that used to be an obvious runtime
24
- * miss becomes a typo in a construct that advertises static resolution.
25
- *
26
- * Decidable only when every sibling name is LITERAL. A template routinely names
27
- * its entries with CEL (`name: !cel "self.name + '-query'"`), and an expression
28
- * could expand to the referenced name — so one dynamic sibling switches the
29
- * check off for that definition rather than inventing a miss.
30
- *
31
- * Entry-module-scoped, like every other declaration check: a published
32
- * dependency's template body is not the consumer's to fix.
33
- *
34
- * Browser-safe.
35
- */
36
- export function validateTemplateDispatch(
37
- manifests: ResourceManifest[],
38
- rootModules: ReadonlySet<string>,
39
- ): AnalysisDiagnostic[] {
40
- const out: AnalysisDiagnostic[] = [];
41
-
42
- for (const m of manifests) {
43
- if (m.kind !== "Telo.Definition") continue;
44
- const meta = m.metadata as { name?: string; module?: string; source?: string } | undefined;
45
- const name = meta?.name;
46
- if (!name) continue;
47
- if (meta?.module && !rootModules.has(meta.module)) continue;
48
-
49
- const bodies = (m as Record<string, unknown>).resources;
50
- if (!Array.isArray(bodies)) continue;
51
-
52
- const siblings: string[] = [];
53
- let anyDynamic = false;
54
- for (const entry of bodies) {
55
- const entryName = (entry as { metadata?: { name?: unknown } } | undefined)?.metadata?.name;
56
- if (typeof entryName === "string" && !entryName.includes("${{")) siblings.push(entryName);
57
- else if (entryName !== undefined) anyDynamic = true;
58
- }
59
- if (anyDynamic) continue;
60
-
61
- for (const field of DISPATCH_FIELDS) {
62
- const value = (m as Record<string, unknown>)[field];
63
- if (!isRefSentinel(value)) continue;
64
- const source = value.source;
65
- const target = source.startsWith("Self.") ? source.slice("Self.".length) : source;
66
- if (siblings.includes(target)) continue;
67
- const suggestion = nearest(target, siblings);
68
- out.push({
69
- severity: DiagnosticSeverity.Error,
70
- code: "TEMPLATE_DISPATCH_UNKNOWN",
71
- source: SOURCE,
72
- message:
73
- `${m.kind}/${name}: '${field}: !ref ${source}' names no entry in 'resources:'. ` +
74
- `Available: ${siblings.join(", ") || "(none)"}.` +
75
- (suggestion ? ` Did you mean '${suggestion}'?` : ""),
76
- data: {
77
- resource: { kind: m.kind, name },
78
- filePath: meta?.source,
79
- path: field,
80
- ...(suggestion ? { fix: { replacement: suggestion } } : {}),
81
- },
82
- });
83
- }
84
- }
85
-
86
- return out;
87
- }
88
-
89
- /** The closest sibling name, when one is close enough to be a typo rather than a
90
- * different name. */
91
- function nearest(target: string, candidates: readonly string[]): string | undefined {
92
- let best: { name: string; d: number } | undefined;
93
- for (const candidate of candidates) {
94
- const d = distance(target, candidate);
95
- if (!best || d < best.d) best = { name: candidate, d };
96
- }
97
- const limit = Math.max(1, Math.floor(target.length / 3));
98
- return best && best.d <= limit ? best.name : undefined;
99
- }