@intentius/chant 0.124.45 → 0.124.46

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 (190) hide show
  1. package/dist/capabilities/aws.paths +148 -0
  2. package/dist/capabilities/base-mappings.json +122 -0
  3. package/dist/capabilities/catalog.d.ts +89 -0
  4. package/dist/capabilities/catalog.d.ts.map +1 -0
  5. package/dist/capabilities/catalog.js +204 -0
  6. package/dist/capabilities/language.d.ts +103 -0
  7. package/dist/capabilities/language.d.ts.map +1 -0
  8. package/dist/capabilities/language.js +335 -0
  9. package/dist/capabilities/matcher.d.ts +65 -0
  10. package/dist/capabilities/matcher.d.ts.map +1 -0
  11. package/dist/capabilities/matcher.js +299 -0
  12. package/dist/capabilities/view.d.ts +207 -0
  13. package/dist/capabilities/view.d.ts.map +1 -0
  14. package/dist/capabilities/view.js +484 -0
  15. package/dist/cli/commands/lint.d.ts.map +1 -1
  16. package/dist/cli/commands/lint.js +1 -0
  17. package/dist/cli/handlers/declared-graph.d.ts +44 -0
  18. package/dist/cli/handlers/declared-graph.d.ts.map +1 -0
  19. package/dist/cli/handlers/declared-graph.js +87 -0
  20. package/dist/cli/handlers/graph.d.ts +25 -0
  21. package/dist/cli/handlers/graph.d.ts.map +1 -1
  22. package/dist/cli/handlers/graph.js +93 -87
  23. package/dist/cli/handlers/pr-env.d.ts.map +1 -1
  24. package/dist/cli/handlers/pr-env.js +2 -1
  25. package/dist/cli/handlers/search-count.d.ts +89 -0
  26. package/dist/cli/handlers/search-count.d.ts.map +1 -0
  27. package/dist/cli/handlers/search-count.js +132 -0
  28. package/dist/cli/handlers/search.d.ts +358 -6
  29. package/dist/cli/handlers/search.d.ts.map +1 -1
  30. package/dist/cli/handlers/search.js +1065 -155
  31. package/dist/cli/main.d.ts.map +1 -1
  32. package/dist/cli/main.js +23 -3
  33. package/dist/cli/mcp/server.d.ts.map +1 -1
  34. package/dist/cli/mcp/server.js +3 -0
  35. package/dist/cli/mcp/tools/capabilities.d.ts +7 -0
  36. package/dist/cli/mcp/tools/capabilities.d.ts.map +1 -0
  37. package/dist/cli/mcp/tools/capabilities.js +27 -0
  38. package/dist/cli/mcp/workspace-tools.d.ts +3 -1
  39. package/dist/cli/mcp/workspace-tools.d.ts.map +1 -1
  40. package/dist/cli/mcp/workspace-tools.js +47 -2
  41. package/dist/cli/parse-args.d.ts.map +1 -1
  42. package/dist/cli/parse-args.js +64 -17
  43. package/dist/cli/registry.d.ts +22 -0
  44. package/dist/cli/registry.d.ts.map +1 -1
  45. package/dist/components/pr-env-ports.d.ts +29 -0
  46. package/dist/components/pr-env-ports.d.ts.map +1 -0
  47. package/dist/components/pr-env-ports.js +77 -0
  48. package/dist/components/pr-env-run.d.ts +5 -21
  49. package/dist/components/pr-env-run.d.ts.map +1 -1
  50. package/dist/components/pr-env-run.js +6 -70
  51. package/dist/components/pr-environment.d.ts +2 -1
  52. package/dist/components/pr-environment.d.ts.map +1 -1
  53. package/dist/components/pr-environment.js +1 -1
  54. package/dist/config-environments.d.ts +92 -0
  55. package/dist/config-environments.d.ts.map +1 -0
  56. package/dist/config-environments.js +102 -0
  57. package/dist/config.d.ts +24 -84
  58. package/dist/config.d.ts.map +1 -1
  59. package/dist/config.js +9 -96
  60. package/dist/graph-detail.d.ts.map +1 -1
  61. package/dist/graph-detail.js +15 -3
  62. package/dist/graph-effective.d.ts +33 -2
  63. package/dist/graph-effective.d.ts.map +1 -1
  64. package/dist/graph-effective.js +215 -68
  65. package/dist/graph-ir.d.ts +23 -0
  66. package/dist/graph-ir.d.ts.map +1 -1
  67. package/dist/graph-ir.js +130 -0
  68. package/dist/graph-sub-template.d.ts +11 -0
  69. package/dist/graph-sub-template.d.ts.map +1 -0
  70. package/dist/graph-sub-template.js +19 -0
  71. package/dist/lexicon.d.ts +9 -0
  72. package/dist/lexicon.d.ts.map +1 -1
  73. package/dist/lifecycle/observe.d.ts +28 -0
  74. package/dist/lifecycle/observe.d.ts.map +1 -1
  75. package/dist/lifecycle/observe.js +23 -1
  76. package/dist/lint/rule.d.ts +6 -0
  77. package/dist/lint/rule.d.ts.map +1 -1
  78. package/dist/live-endpoint.d.ts +1 -1
  79. package/dist/live-endpoint.d.ts.map +1 -1
  80. package/dist/live-endpoint.js +1 -1
  81. package/dist/observation.d.ts +48 -1
  82. package/dist/observation.d.ts.map +1 -1
  83. package/dist/observation.js +21 -5
  84. package/dist/op/activities/activity-contracts.d.ts +4 -4
  85. package/dist/wave-runtime.mjs +250 -249
  86. package/dist/workspace/capabilities-contract.d.ts +66 -0
  87. package/dist/workspace/capabilities-contract.d.ts.map +1 -0
  88. package/dist/workspace/capabilities-contract.js +107 -0
  89. package/dist/workspace/capabilities.schema.json +229 -0
  90. package/dist/workspace/compose-graph.d.ts +9 -0
  91. package/dist/workspace/compose-graph.d.ts.map +1 -1
  92. package/dist/workspace/compose-graph.js +3 -1
  93. package/dist/workspace/conformance/index.d.ts +1 -1
  94. package/dist/workspace/conformance/index.d.ts.map +1 -1
  95. package/dist/workspace/conformance/index.js +39 -2
  96. package/dist/workspace/graph-cache.d.ts +8 -0
  97. package/dist/workspace/graph-cache.d.ts.map +1 -1
  98. package/dist/workspace/graph-cache.js +27 -3
  99. package/dist/workspace/graph-cli.d.ts +39 -2
  100. package/dist/workspace/graph-cli.d.ts.map +1 -1
  101. package/dist/workspace/graph-cli.js +66 -24
  102. package/dist/workspace/graph.schema.json +148 -0
  103. package/dist/workspace/kind-readers.d.ts +3 -0
  104. package/dist/workspace/kind-readers.d.ts.map +1 -1
  105. package/dist/workspace/kind-readers.js +7 -1
  106. package/dist/workspace/member-commands.d.ts +10 -1
  107. package/dist/workspace/member-commands.d.ts.map +1 -1
  108. package/dist/workspace/member-commands.js +17 -1
  109. package/dist/workspace/nested-graph.d.ts +2 -0
  110. package/dist/workspace/nested-graph.d.ts.map +1 -1
  111. package/dist/workspace/nested-graph.js +32 -1
  112. package/dist/workspace/reason-codes.d.ts +10 -0
  113. package/dist/workspace/reason-codes.d.ts.map +1 -1
  114. package/dist/workspace/reason-codes.js +12 -0
  115. package/dist/workspace/search-cli.d.ts +204 -0
  116. package/dist/workspace/search-cli.d.ts.map +1 -0
  117. package/dist/workspace/search-cli.js +466 -0
  118. package/dist/workspace/search-contract.d.ts +56 -0
  119. package/dist/workspace/search-contract.d.ts.map +1 -0
  120. package/dist/workspace/search-contract.js +70 -0
  121. package/dist/workspace/search.schema.json +822 -0
  122. package/package.json +1 -1
  123. package/src/__snapshots__/okf.test.ts.snap +10 -0
  124. package/src/capabilities/aws.paths +148 -0
  125. package/src/capabilities/base-mappings.json +122 -0
  126. package/src/capabilities/catalog.ts +230 -0
  127. package/src/capabilities/language.test.ts +191 -0
  128. package/src/capabilities/language.ts +373 -0
  129. package/src/capabilities/matcher.ts +315 -0
  130. package/src/capabilities/view-compose.test.ts +76 -0
  131. package/src/capabilities/view.ts +631 -0
  132. package/src/cli/commands/lint.ts +1 -0
  133. package/src/cli/handlers/declared-graph.ts +99 -0
  134. package/src/cli/handlers/graph.test.ts +94 -3
  135. package/src/cli/handlers/graph.ts +123 -96
  136. package/src/cli/handlers/pr-env.ts +1 -2
  137. package/src/cli/handlers/search-build-roots.test.ts +144 -0
  138. package/src/cli/handlers/search-count.test.ts +191 -0
  139. package/src/cli/handlers/search-count.ts +165 -0
  140. package/src/cli/handlers/search-json.test.ts +333 -0
  141. package/src/cli/handlers/search-live.test.ts +387 -0
  142. package/src/cli/handlers/search-paths.test.ts +235 -0
  143. package/src/cli/handlers/search.ts +1312 -166
  144. package/src/cli/main.test.ts +28 -3
  145. package/src/cli/main.ts +23 -3
  146. package/src/cli/mcp/server.test.ts +3 -3
  147. package/src/cli/mcp/server.ts +3 -0
  148. package/src/cli/mcp/tools/capabilities.ts +32 -0
  149. package/src/cli/mcp/workspace-tools.e2e.test.ts +21 -1
  150. package/src/cli/mcp/workspace-tools.ts +47 -2
  151. package/src/cli/parse-args.ts +52 -13
  152. package/src/cli/registry.ts +22 -0
  153. package/src/components/pr-env-ports.ts +89 -0
  154. package/src/components/pr-env-run-bundle.test.ts +54 -0
  155. package/src/components/pr-env-run.ts +5 -76
  156. package/src/components/pr-environment.ts +2 -1
  157. package/src/config-environments.ts +133 -0
  158. package/src/config.ts +37 -124
  159. package/src/graph-detail.ts +15 -3
  160. package/src/graph-effective.ts +226 -75
  161. package/src/graph-ir.test.ts +163 -0
  162. package/src/graph-ir.ts +147 -0
  163. package/src/graph-sub-template.ts +22 -0
  164. package/src/lexicon.ts +10 -0
  165. package/src/lifecycle/observe.test.ts +27 -1
  166. package/src/lifecycle/observe.ts +43 -1
  167. package/src/lint/rule.ts +6 -0
  168. package/src/live-endpoint.ts +1 -1
  169. package/src/observation.test.ts +25 -0
  170. package/src/observation.ts +69 -5
  171. package/src/workspace/capabilities-contract.test.ts +88 -0
  172. package/src/workspace/capabilities-contract.ts +132 -0
  173. package/src/workspace/capabilities.schema.json +229 -0
  174. package/src/workspace/compose-graph.ts +10 -1
  175. package/src/workspace/conformance/conformance.e2e.test.ts +14 -1
  176. package/src/workspace/conformance/index.ts +31 -2
  177. package/src/workspace/graph-cache.ts +27 -3
  178. package/src/workspace/graph-cli.ts +96 -24
  179. package/src/workspace/graph.schema.json +148 -0
  180. package/src/workspace/kind-readers.e2e.test.ts +28 -0
  181. package/src/workspace/kind-readers.test.ts +1 -1
  182. package/src/workspace/kind-readers.ts +7 -1
  183. package/src/workspace/member-commands.ts +22 -1
  184. package/src/workspace/nested-graph.ts +32 -1
  185. package/src/workspace/reason-codes.test.ts +7 -0
  186. package/src/workspace/reason-codes.ts +12 -0
  187. package/src/workspace/search-cli.e2e.test.ts +305 -0
  188. package/src/workspace/search-cli.ts +591 -0
  189. package/src/workspace/search-contract.ts +95 -0
  190. package/src/workspace/search.schema.json +822 -0
@@ -0,0 +1,299 @@
1
+ export class CapabilityError extends Error {
2
+ }
3
+ const glob = (pattern, s) => new RegExp(`^${pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".")}$`, "i").test(s);
4
+ function equal(a, b) {
5
+ if (b === null)
6
+ return a === null || a === undefined;
7
+ if (a === b)
8
+ return true;
9
+ if (a === null || a === undefined || typeof a === "object")
10
+ return false;
11
+ return String(a) === String(b);
12
+ }
13
+ function present(a) {
14
+ return a !== undefined && a !== null && a !== false && !(Array.isArray(a) && a.length === 0);
15
+ }
16
+ const reverseHops = (hops) => [...hops].reverse();
17
+ export class CapabilityEngine {
18
+ constructor(view, rules) {
19
+ this.view = view;
20
+ this.rules = new Map();
21
+ this.sets = new Map();
22
+ this.relations = new Map();
23
+ this.busy = new Set();
24
+ this.out = new Map();
25
+ this.in = new Map();
26
+ this.byLabel = new Map();
27
+ for (const r of rules)
28
+ this.rules.set(r.name, r);
29
+ for (const e of view.edges) {
30
+ this.index(this.out, e.from, e.name, e.to, e.hops);
31
+ this.index(this.in, e.to, e.name, e.from, reverseHops(e.hops));
32
+ }
33
+ for (const n of view.nodes.values()) {
34
+ if (!this.byLabel.has(n.label))
35
+ this.byLabel.set(n.label, []);
36
+ this.byLabel.get(n.label).push(n.id);
37
+ }
38
+ for (const r of rules)
39
+ this.check(r);
40
+ }
41
+ index(ix, a, name, b, hops) {
42
+ let m = ix.get(a);
43
+ if (!m)
44
+ ix.set(a, (m = new Map()));
45
+ let l = m.get(name);
46
+ if (!l)
47
+ m.set(name, (l = []));
48
+ l.push({ to: b, hops });
49
+ }
50
+ /** Refuse a rule that names a capability that doesn't exist, or uses one in the wrong shape. */
51
+ check(r) {
52
+ const node = (n, alt) => {
53
+ for (const t of n.tests) {
54
+ if (t.kind !== "cap")
55
+ continue;
56
+ const target = this.rules.get(t.cap);
57
+ if (!target)
58
+ throw new CapabilityError(`${r.name} (line ${alt.line}): no capability "${t.cap}"`);
59
+ if (target.vars.length !== 1)
60
+ throw new CapabilityError(`${r.name} (line ${alt.line}): "@${t.cap}" is an edge, not a set; follow it with ->${t.cap}`);
61
+ }
62
+ };
63
+ for (const alt of r.alts) {
64
+ node(alt.head, alt);
65
+ for (const s of alt.steps) {
66
+ node(s.node, alt);
67
+ for (const n of s.names) {
68
+ const target = this.rules.get(n.name);
69
+ if (target && target.vars.length !== 2) {
70
+ throw new CapabilityError(`${r.name} (line ${alt.line}): "${n.name}" is a set, not an edge; test it with [@${n.name}]`);
71
+ }
72
+ }
73
+ }
74
+ }
75
+ }
76
+ has(name) {
77
+ return this.rules.has(name);
78
+ }
79
+ /** The capabilities the catalog lists: rules that carry a `## meaning`. */
80
+ publicNames() {
81
+ return [...this.rules.values()].filter((r) => r.meta.meaning !== undefined).map((r) => r.name);
82
+ }
83
+ rule(name) {
84
+ return this.rules.get(name);
85
+ }
86
+ /** Bind positional arguments to a rule's parameters. */
87
+ bind(name, positional) {
88
+ const r = this.rules.get(name);
89
+ if (!r)
90
+ throw new CapabilityError(`no capability "${name}"`);
91
+ if (positional.length > r.params.length) {
92
+ throw new CapabilityError(`${name} takes ${r.params.length === 0 ? "no arguments" : `at most ${r.params.length} (${r.params.map((p) => p.name).join(", ")})`}`);
93
+ }
94
+ const args = {};
95
+ r.params.forEach((p, i) => {
96
+ const v = positional[i];
97
+ if (v === undefined && !p.optional)
98
+ throw new CapabilityError(`${name} needs ${p.name}`);
99
+ args[p.name] = v;
100
+ });
101
+ return args;
102
+ }
103
+ key(name, args) {
104
+ return `${name}(${JSON.stringify(Object.entries(args).filter(([, v]) => v !== undefined).sort())})`;
105
+ }
106
+ /** The nodes in a set capability, with evidence. */
107
+ set(name, args = {}) {
108
+ const r = this.rules.get(name);
109
+ if (!r)
110
+ throw new CapabilityError(`no capability "${name}"`);
111
+ if (r.vars.length !== 1)
112
+ throw new CapabilityError(`"${name}" is an edge, not a set`);
113
+ const key = this.key(name, args);
114
+ const cached = this.sets.get(key);
115
+ if (cached)
116
+ return cached;
117
+ this.enter(key);
118
+ const out = new Map();
119
+ for (const alt of r.alts) {
120
+ for (const s of this.starts(alt.head)) {
121
+ this.match(alt, s, args, (env, ev) => {
122
+ const x = env[r.vars[0]] ?? s;
123
+ if (!out.has(x))
124
+ out.set(x, ev);
125
+ });
126
+ }
127
+ }
128
+ this.busy.delete(key);
129
+ this.sets.set(key, out);
130
+ return out;
131
+ }
132
+ /** The pairs in an edge capability, with evidence. */
133
+ relation(name, args = {}) {
134
+ const r = this.rules.get(name);
135
+ if (!r)
136
+ throw new CapabilityError(`no capability "${name}"`);
137
+ if (r.vars.length !== 2)
138
+ throw new CapabilityError(`"${name}" is a set, not an edge`);
139
+ const key = this.key(name, args);
140
+ const cached = this.relations.get(key);
141
+ if (cached)
142
+ return cached;
143
+ this.enter(key);
144
+ const rel = { out: new Map(), in: new Map() };
145
+ for (const alt of r.alts) {
146
+ for (const s of this.starts(alt.head)) {
147
+ this.match(alt, s, args, (env, ev, last) => {
148
+ const a = env[r.vars[0]] ?? s;
149
+ const b = env[r.vars[1]] ?? last;
150
+ if (a === b)
151
+ return;
152
+ let m = rel.out.get(a);
153
+ if (!m)
154
+ rel.out.set(a, (m = new Map()));
155
+ if (m.has(b))
156
+ return;
157
+ m.set(b, ev);
158
+ let back = rel.in.get(b);
159
+ if (!back)
160
+ rel.in.set(b, (back = new Map()));
161
+ back.set(a, ev);
162
+ });
163
+ }
164
+ }
165
+ this.busy.delete(key);
166
+ this.relations.set(key, rel);
167
+ return rel;
168
+ }
169
+ enter(key) {
170
+ if (this.busy.has(key)) {
171
+ throw new CapabilityError(`capability ${key} refers to itself through ${[...this.busy].join(" -> ")}`);
172
+ }
173
+ this.busy.add(key);
174
+ }
175
+ starts(head) {
176
+ if (!head.labels)
177
+ return [...this.view.nodes.keys()];
178
+ return head.labels.flatMap((l) => this.byLabel.get(l) ?? []);
179
+ }
180
+ resolve(v, args) {
181
+ return "lit" in v ? v.lit : args[v.param];
182
+ }
183
+ test(id, t, args, because) {
184
+ const result = (() => {
185
+ if (t.kind === "cap") {
186
+ const capArgs = this.bind(t.cap, t.args.map((v) => this.resolve(v, args)));
187
+ const ev = this.set(t.cap, capArgs).get(id);
188
+ if (ev && !t.negated)
189
+ because.push({ capability: t.cap, id, evidence: ev });
190
+ return !!ev;
191
+ }
192
+ const n = this.view.nodes.get(id);
193
+ const a = n.attrs[t.attr];
194
+ if (t.op === "present")
195
+ return present(a);
196
+ const values = t.values.map((v) => this.resolve(v, args));
197
+ // A test on a parameter nobody passed is left out, whatever else it names.
198
+ if (values.some((v) => v === undefined))
199
+ return !t.negated;
200
+ const given = values;
201
+ const each = Array.isArray(a) ? a : [a];
202
+ switch (t.op) {
203
+ case "=":
204
+ case "in":
205
+ return each.some((x) => given.some((v) => equal(x, v)));
206
+ case "!=":
207
+ return !each.some((x) => equal(x, given[0]));
208
+ case "~":
209
+ return each.some((x) => typeof x === "string" && given.some((v) => typeof v === "string" && (glob(x, v) || glob(v, x))));
210
+ default: {
211
+ const v = Number(given[0]);
212
+ return each.some((x) => {
213
+ const nx = Number(x);
214
+ if (x === null || x === undefined || Number.isNaN(nx) || Number.isNaN(v))
215
+ return false;
216
+ return t.op === "<" ? nx < v : t.op === "<=" ? nx <= v : t.op === ">" ? nx > v : nx >= v;
217
+ });
218
+ }
219
+ }
220
+ })();
221
+ return t.negated ? !result : result;
222
+ }
223
+ ok(id, s, env, args, because) {
224
+ if (s.v && env[s.v] !== undefined && env[s.v] !== id)
225
+ return false;
226
+ const n = this.view.nodes.get(id);
227
+ if (!n)
228
+ return false;
229
+ if (s.labels && !s.labels.includes(n.label))
230
+ return false;
231
+ return s.tests.every((t) => this.test(id, t, args, because));
232
+ }
233
+ hop(id, step, args) {
234
+ const out = [];
235
+ for (const n of step.names) {
236
+ if (this.rules.has(n.name)) {
237
+ const rel = this.relation(n.name, this.bind(n.name, n.args.map((v) => this.resolve(v, args))));
238
+ const m = (step.dir === "out" ? rel.out : rel.in).get(id);
239
+ if (m)
240
+ for (const [to, ev] of m)
241
+ out.push({ to, hops: step.dir === "out" ? ev.hops : reverseHops(ev.hops) });
242
+ }
243
+ else {
244
+ out.push(...((step.dir === "out" ? this.out : this.in).get(id)?.get(n.name) ?? []));
245
+ }
246
+ }
247
+ return out;
248
+ }
249
+ /** Every node within the step's depth range, by its shortest walk. */
250
+ walk(id, step, args) {
251
+ const res = [];
252
+ const seen = new Set([id]);
253
+ let frontier = [{ to: id, hops: [] }];
254
+ if (step.min === 0)
255
+ res.push(frontier[0]);
256
+ for (let d = 1; d <= step.max && frontier.length > 0; d++) {
257
+ const next = [];
258
+ for (const f of frontier) {
259
+ for (const h of this.hop(f.to, step, args)) {
260
+ if (step.max > 1) {
261
+ if (seen.has(h.to))
262
+ continue;
263
+ seen.add(h.to);
264
+ }
265
+ const p = { to: h.to, hops: [...f.hops, ...h.hops] };
266
+ next.push(p);
267
+ if (d >= step.min)
268
+ res.push(p);
269
+ }
270
+ }
271
+ frontier = next;
272
+ }
273
+ return res;
274
+ }
275
+ match(alt, start, args, emit) {
276
+ const because0 = [];
277
+ if (!this.ok(start, alt.head, {}, args, because0))
278
+ return;
279
+ const env0 = alt.head.v ? { [alt.head.v]: start } : {};
280
+ const go = (k, at, env, hops, because) => {
281
+ if (k === alt.steps.length)
282
+ return emit(env, { hops, because }, at);
283
+ const st = alt.steps[k];
284
+ if (st.negated) {
285
+ const blocked = this.walk(at, st, args).some((w) => this.ok(w.to, st.node, env, args, []));
286
+ if (!blocked)
287
+ go(k + 1, at, env, hops, because);
288
+ return;
289
+ }
290
+ for (const w of this.walk(at, st, args)) {
291
+ const b = [];
292
+ if (!this.ok(w.to, st.node, env, args, b))
293
+ continue;
294
+ go(k + 1, w.to, st.node.v ? { ...env, [st.node.v]: w.to } : env, [...hops, ...w.hops], [...because, ...b]);
295
+ }
296
+ };
297
+ go(0, start, env0, [], because0);
298
+ }
299
+ }
@@ -0,0 +1,207 @@
1
+ /**
2
+ * The lexicon-neutral view capability rules read (#4375, ruled on #4361).
3
+ *
4
+ * chant's graph IR can't serve as a rule surface as it stands: an IAM
5
+ * statement or an inline security-group rule is a property tree inside one
6
+ * node, a Terraform policy is HCL text in a string, Terraform has link
7
+ * resources where CloudFormation has a direct reference, and every Terraform
8
+ * resource is `Terraform::Resource`. So rules read this view instead:
9
+ *
10
+ * - labels (`Instance`, `Role`, `SecurityGroup`) from each lexicon's kind
11
+ * mapping, and edge names (`subnet`, `sg`) from the IR edge's `viaAttr`;
12
+ * - a node per policy statement and per inline block (an ingress rule, an
13
+ * inline route), joined to its holder by a named edge;
14
+ * - one edge per link resource (a Terraform policy attachment);
15
+ * - an edge for an ARN string that names a declared role or bucket.
16
+ *
17
+ * The mapping is data, shipped by each lexicon (`CapabilityMapping`). The
18
+ * adapter below is the code that reads it. What a lexicon can't say as data
19
+ * (reading a Terraform `jsonencode(...)` policy) it supplies as a hook.
20
+ */
21
+ import type { GraphIR } from "../graph-ir.js";
22
+ /** A path into a node's attributes: `A.B` follows objects, `A[]` spreads a list. */
23
+ export type AttrPath = string;
24
+ /** Where a neutral attribute is read from: one path, the first present of several, or every value of several. */
25
+ export type AttrSource = AttrPath | AttrPath[] | {
26
+ all: AttrPath[];
27
+ } | {
28
+ const: unknown;
29
+ };
30
+ /** A label for a kind, optionally only when the node's attributes match. */
31
+ export type LabelSpec = string | {
32
+ label: string;
33
+ when?: Record<string, unknown>;
34
+ style?: string;
35
+ set?: Record<string, unknown>;
36
+ };
37
+ /** An inline block exploded into nodes of its own. */
38
+ export interface BlockSpec {
39
+ /** The attribute holding the block or list of blocks. */
40
+ attr: AttrPath;
41
+ label: string;
42
+ /** The edge from the holder to the block; a leading `-` points it from the block to the holder. */
43
+ edge: string;
44
+ attrs?: Record<string, AttrSource>;
45
+ /** Attributes of the block that reference other nodes, and the edge name each makes from the block. */
46
+ refs?: Record<string, string>;
47
+ /** Only blocks whose attributes match. */
48
+ when?: Record<string, unknown>;
49
+ /** Recorded as the block node's `style` attribute. */
50
+ style?: string;
51
+ }
52
+ /** A link resource turned into one edge between the two nodes it links. */
53
+ export interface LinkSpec {
54
+ /** The view edge (from the link node) whose target is the new edge's source. */
55
+ from: string;
56
+ /** The view edge (from the link node) whose target is the new edge's target. */
57
+ to: string;
58
+ edge: string;
59
+ }
60
+ /** Why a lexicon can't supply a capability. */
61
+ export interface Unsupported {
62
+ code: string;
63
+ message: string;
64
+ }
65
+ /**
66
+ * A lexicon's mapping onto the view, as data (`<lexicon>/src/capabilities/mapping.json`).
67
+ * Every field is optional, so a mapping can extend another.
68
+ */
69
+ export interface CapabilityMapping {
70
+ lexicon: string;
71
+ /** How a node's type is read: its IR kind, or its Terraform resource type. */
72
+ types?: "kind" | "terraform";
73
+ /** The attribute holding the block body, when it isn't the attributes themselves. */
74
+ body?: string;
75
+ /** How references inside attribute values are spelled. */
76
+ refs?: "cloudformation" | "terraform";
77
+ labels?: Record<string, LabelSpec>;
78
+ /**
79
+ * Per label: IR `viaAttr` -> view edge name. A leading `-` reverses the
80
+ * edge. Where one attribute references several kinds (a launch template's
81
+ * `LaunchTemplateData`), the name can be given per target label.
82
+ */
83
+ edges?: Record<string, Record<string, string | Record<string, string>>>;
84
+ /** Per label: neutral attribute -> where it is read from. */
85
+ attrs?: Record<string, Record<string, AttrSource>>;
86
+ blocks?: Record<string, BlockSpec[]>;
87
+ links?: Record<string, LinkSpec>;
88
+ /** Per label: attribute path of a policy document -> its kind (`permission`, `trust`, `resource`). */
89
+ documents?: Record<string, Record<AttrPath, string>>;
90
+ /** Where tags are read from, and which tag keys give a data store its classification. */
91
+ tags?: AttrPath[];
92
+ classificationTags?: string[];
93
+ /** Capabilities this lexicon can't supply, and why. */
94
+ unsupported?: Record<string, Unsupported>;
95
+ }
96
+ /** What a lexicon supplies as code, for what its mapping can't say as data. */
97
+ export interface CapabilityAdapter {
98
+ /**
99
+ * Read a policy document held in an attribute. Return the document as a
100
+ * JSON object; a value position holding an expression comes back as a
101
+ * string with the expression in `${...}`. Undefined when it can't be read.
102
+ */
103
+ readDocument?(value: unknown): unknown;
104
+ }
105
+ /** One lexicon's contribution: its mapping (data) and its adapter (code). */
106
+ export interface CapabilityPack {
107
+ mapping: CapabilityMapping;
108
+ adapter?: CapabilityAdapter;
109
+ }
110
+ /**
111
+ * One edge of the IR a view edge stands for, in the IR's own direction:
112
+ * `from` holds the reference, `to` is what it names. #4359's `PathHop`, with
113
+ * the view edge's name.
114
+ */
115
+ export interface ViewHop {
116
+ from: string;
117
+ fromAttr?: string;
118
+ to: string;
119
+ toAttr?: string;
120
+ edge: string;
121
+ }
122
+ export interface ViewNode {
123
+ id: string;
124
+ label: string;
125
+ /** The IR node this view node is, or sits inside (a statement's holder). */
126
+ irId: string;
127
+ lexicon: string;
128
+ attrs: Record<string, unknown>;
129
+ /** What the node was read from: the resource's attributes (its block body), or the inline block. */
130
+ body?: Record<string, unknown>;
131
+ }
132
+ export interface ViewEdge {
133
+ from: string;
134
+ to: string;
135
+ name: string;
136
+ /** The IR hops this edge stands for, in walk order from `from`. */
137
+ hops: ViewHop[];
138
+ }
139
+ export interface View {
140
+ nodes: Map<string, ViewNode>;
141
+ edges: ViewEdge[];
142
+ /** Lexicons whose nodes the view read through a mapping. */
143
+ lexicons: Set<string>;
144
+ /**
145
+ * ARN strings that name a role, bucket or table by name, where this view
146
+ * declares nothing of that name (#4378). A workspace resolves them over
147
+ * every member's view: the thing may be declared in another member.
148
+ */
149
+ unresolved?: UnresolvedArn[];
150
+ }
151
+ /** An ARN a view could not resolve, kept so a composed view can (#4378). */
152
+ export interface UnresolvedArn {
153
+ /** The view node holding the reference: a statement or an inline block. */
154
+ from: string;
155
+ fromAttr: string;
156
+ /** The view edge it makes once resolved (`resource`, `principal`, or a block's ref edge). */
157
+ edge: string;
158
+ value: string;
159
+ }
160
+ /**
161
+ * Merge mappings for the same lexicon: objects merge key by key at every
162
+ * depth, lists concatenate, and anything else in a later mapping wins.
163
+ */
164
+ export declare function mergeMappings(...ms: CapabilityMapping[]): CapabilityMapping;
165
+ /** The bare name a row prints: no stack qualification, no root directory. */
166
+ export declare function displayName(id: string): string;
167
+ /**
168
+ * Build the view of an IR through the packs given. Nodes of a kind no
169
+ * mapping labels are left out, as are edges no mapping names.
170
+ */
171
+ export declare function buildView(ir: GraphIR, packs: CapabilityPack[]): View;
172
+ /** The version of the serialized view a member's `chant graph --capability-view` prints (#4378). */
173
+ export declare const VIEW_DOCUMENT_VERSION = 1;
174
+ /**
175
+ * The view as a member's `chant graph --format ir --capability-view` prints
176
+ * it (#4378): built by the member's own chant, through the mappings and
177
+ * adapters of the lexicons that member loads, so a workspace's rules read
178
+ * every member as the member's own toolchain maps it. Node bodies are left
179
+ * out: rules read labels, attributes and edges only.
180
+ */
181
+ export interface ViewDocument {
182
+ version: number;
183
+ lexicons: string[];
184
+ nodes: {
185
+ id: string;
186
+ label: string;
187
+ irId: string;
188
+ lexicon: string;
189
+ attrs: Record<string, unknown>;
190
+ }[];
191
+ edges: ViewEdge[];
192
+ unresolved: UnresolvedArn[];
193
+ }
194
+ export declare function serializeView(view: View): ViewDocument;
195
+ /** Whether a member printed a view this chant reads; anything else is treated as no view. */
196
+ export declare function isViewDocument(v: unknown): v is ViewDocument;
197
+ /** A view document with every id it holds given `prefix` (`<member>/`), as `workspace graph` composes ids. */
198
+ export declare function prefixView(doc: ViewDocument, prefix: string): ViewDocument;
199
+ /**
200
+ * Compose member views into one (#4378), the matcher's input over a
201
+ * workspace. Each member's view was mapped by its own chant; the one thing
202
+ * left to do here is resolve the ARNs a member couldn't, by name over every
203
+ * member's nodes. Where several members declare the name, the last one in
204
+ * member order wins, as within one view.
205
+ */
206
+ export declare function composeViews(docs: ViewDocument[]): View;
207
+ //# sourceMappingURL=view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../src/capabilities/view.ts"],"names":[],"mappings":"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"}