@topogram/cli 0.3.64 → 0.3.65

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 (245) hide show
  1. package/package.json +1 -1
  2. package/src/adoption/plan/index.js +703 -0
  3. package/src/adoption/plan.js +12 -703
  4. package/src/agent-ops/query-builders/auth.js +375 -0
  5. package/src/agent-ops/query-builders/change-risk/change-plan.js +123 -0
  6. package/src/agent-ops/query-builders/change-risk/import-plan.js +49 -0
  7. package/src/agent-ops/query-builders/change-risk/maintained.js +286 -0
  8. package/src/agent-ops/query-builders/change-risk/review-packets.js +123 -0
  9. package/src/agent-ops/query-builders/change-risk/risk.js +189 -0
  10. package/src/agent-ops/query-builders/change-risk.js +25 -0
  11. package/src/agent-ops/query-builders/common.js +149 -0
  12. package/src/agent-ops/query-builders/maintained-risk.js +539 -0
  13. package/src/agent-ops/query-builders/maintained-shared.js +120 -0
  14. package/src/agent-ops/query-builders/multi-agent.js +547 -0
  15. package/src/agent-ops/query-builders/projection-impacts.js +514 -0
  16. package/src/agent-ops/query-builders/work-packets.js +417 -0
  17. package/src/agent-ops/query-builders/workflow-context-shared.js +300 -0
  18. package/src/agent-ops/query-builders/workflow-context.js +398 -0
  19. package/src/agent-ops/query-builders/workflow-presets-core.js +676 -0
  20. package/src/agent-ops/query-builders/workflow-presets.js +341 -0
  21. package/src/agent-ops/query-builders.d.ts +26 -26
  22. package/src/agent-ops/query-builders.js +42 -5021
  23. package/src/catalog/constants.js +10 -0
  24. package/src/catalog/copy.js +60 -0
  25. package/src/catalog/diagnostics.js +15 -0
  26. package/src/catalog/entries.js +42 -0
  27. package/src/catalog/files.js +67 -0
  28. package/src/catalog/provenance.js +122 -0
  29. package/src/catalog/source.js +150 -0
  30. package/src/catalog/validation.js +252 -0
  31. package/src/catalog.d.ts +2 -0
  32. package/src/catalog.js +18 -746
  33. package/src/cli/commands/catalog/check.js +31 -0
  34. package/src/cli/commands/catalog/copy.js +59 -0
  35. package/src/cli/commands/catalog/doctor.js +248 -0
  36. package/src/cli/commands/catalog/help.js +21 -0
  37. package/src/cli/commands/catalog/list.js +52 -0
  38. package/src/cli/commands/catalog/runner.js +92 -0
  39. package/src/cli/commands/catalog/shared.js +17 -0
  40. package/src/cli/commands/catalog/show.js +134 -0
  41. package/src/cli/commands/catalog.js +30 -615
  42. package/src/cli/commands/generator-policy/package-info.js +162 -0
  43. package/src/cli/commands/generator-policy/payloads.js +372 -0
  44. package/src/cli/commands/generator-policy/printers.js +159 -0
  45. package/src/cli/commands/generator-policy/runner.js +81 -0
  46. package/src/cli/commands/generator-policy/shared.js +39 -0
  47. package/src/cli/commands/generator-policy.js +15 -783
  48. package/src/cli/commands/import/adopt.js +170 -0
  49. package/src/cli/commands/import/check.js +91 -0
  50. package/src/cli/commands/import/diff.js +84 -0
  51. package/src/cli/commands/import/help.js +47 -0
  52. package/src/cli/commands/import/paths.js +277 -0
  53. package/src/cli/commands/import/plan.js +284 -0
  54. package/src/cli/commands/import/refresh.js +470 -0
  55. package/src/cli/commands/import/status-history.js +196 -0
  56. package/src/cli/commands/import/workspace.js +230 -0
  57. package/src/cli/commands/import.js +33 -1732
  58. package/src/cli/commands/package/constants.js +17 -0
  59. package/src/cli/commands/package/doctor.js +240 -0
  60. package/src/cli/commands/package/help.js +27 -0
  61. package/src/cli/commands/package/lockfile.js +135 -0
  62. package/src/cli/commands/package/npm.js +97 -0
  63. package/src/cli/commands/package/reporting.js +35 -0
  64. package/src/cli/commands/package/runner.js +33 -0
  65. package/src/cli/commands/package/shared.js +9 -0
  66. package/src/cli/commands/package/update-cli.js +252 -0
  67. package/src/cli/commands/package/versions.js +35 -0
  68. package/src/cli/commands/package.js +29 -813
  69. package/src/cli/commands/query/change-plan.js +68 -0
  70. package/src/cli/commands/query/definitions.js +202 -0
  71. package/src/cli/commands/query/import-adopt.js +121 -0
  72. package/src/cli/commands/query/runner/artifacts.js +102 -0
  73. package/src/cli/commands/query/runner/boundaries.js +211 -0
  74. package/src/cli/commands/query/runner/change.js +182 -0
  75. package/src/cli/commands/query/runner/import-adopt.js +111 -0
  76. package/src/cli/commands/query/runner/index.js +31 -0
  77. package/src/cli/commands/query/runner/output.js +12 -0
  78. package/src/cli/commands/query/runner/workflow.js +241 -0
  79. package/src/cli/commands/query/runner.js +3 -0
  80. package/src/cli/commands/query/workflow-context.js +5 -0
  81. package/src/cli/commands/query/workspace.js +274 -0
  82. package/src/cli/commands/query.js +9 -1300
  83. package/src/cli/commands/template/baseline.js +100 -0
  84. package/src/cli/commands/template/check.js +466 -0
  85. package/src/cli/commands/template/constants.js +8 -0
  86. package/src/cli/commands/template/diagnostics.js +26 -0
  87. package/src/cli/commands/template/help.js +28 -0
  88. package/src/cli/commands/template/lifecycle.js +404 -0
  89. package/src/cli/commands/template/list-show.js +287 -0
  90. package/src/cli/commands/template/policy.js +422 -0
  91. package/src/cli/commands/template/shared.js +127 -0
  92. package/src/cli/commands/template/updates.js +352 -0
  93. package/src/cli/commands/template.js +41 -2143
  94. package/src/generator/api/contracts.js +497 -0
  95. package/src/generator/api/metadata.js +221 -0
  96. package/src/generator/api/openapi.js +559 -0
  97. package/src/generator/api/schema.js +124 -0
  98. package/src/generator/api/types.d.ts +98 -0
  99. package/src/generator/api.js +3 -1195
  100. package/src/generator/context/shared/domain-sdlc.js +282 -0
  101. package/src/generator/context/shared/maintained-boundary.js +665 -0
  102. package/src/generator/context/shared/metrics.js +85 -0
  103. package/src/generator/context/shared/primitives.js +64 -0
  104. package/src/generator/context/shared/relationships.js +453 -0
  105. package/src/generator/context/shared/summaries.js +263 -0
  106. package/src/generator/context/shared/types.d.ts +207 -0
  107. package/src/generator/context/shared.d.ts +42 -0
  108. package/src/generator/context/shared.js +80 -1390
  109. package/src/generator/context/slice/core.js +397 -0
  110. package/src/generator/context/slice/sdlc.js +417 -0
  111. package/src/generator/context/slice/ui-packets.js +183 -0
  112. package/src/generator/context/slice.js +2 -859
  113. package/src/generator/registry/index.js +507 -0
  114. package/src/generator/registry.js +18 -504
  115. package/src/generator/runtime/environment/index.js +666 -0
  116. package/src/generator/runtime/environment.js +4 -666
  117. package/src/generator/runtime/runtime-check/index.js +554 -0
  118. package/src/generator/runtime/runtime-check.js +4 -554
  119. package/src/generator/runtime/shared/index.js +572 -0
  120. package/src/generator/runtime/shared.js +19 -570
  121. package/src/generator/shared.d.ts +2 -0
  122. package/src/generator/surfaces/shared.d.ts +3 -0
  123. package/src/generator/widget-conformance/behavior-report.js +258 -0
  124. package/src/generator/widget-conformance/checks.js +371 -0
  125. package/src/generator/widget-conformance/projection-context.js +200 -0
  126. package/src/generator/widget-conformance/report.js +166 -0
  127. package/src/generator/widget-conformance/types.d.ts +121 -0
  128. package/src/generator/widget-conformance.js +3 -824
  129. package/src/import/core/context.d.ts +3 -0
  130. package/src/import/core/contracts.d.ts +1 -0
  131. package/src/import/core/registry.d.ts +4 -0
  132. package/src/import/core/runner/candidates.js +217 -0
  133. package/src/import/core/runner/options.js +22 -0
  134. package/src/import/core/runner/reports.js +50 -0
  135. package/src/import/core/runner/run.js +79 -0
  136. package/src/import/core/runner/tracks.js +150 -0
  137. package/src/import/core/runner/ui-drafts.js +337 -0
  138. package/src/import/core/runner.js +3 -698
  139. package/src/import/core/shared/api-routes.js +221 -0
  140. package/src/import/core/shared/candidates.js +97 -0
  141. package/src/import/core/shared/files.js +177 -0
  142. package/src/import/core/shared/next-app.js +389 -0
  143. package/src/import/core/shared/types.d.ts +51 -0
  144. package/src/import/core/shared/ui-routes.js +230 -0
  145. package/src/import/core/shared.js +60 -861
  146. package/src/new-project/constants.js +128 -0
  147. package/src/new-project/create.js +83 -0
  148. package/src/new-project/json.js +28 -0
  149. package/src/new-project/metadata.js +96 -0
  150. package/src/new-project/package-spec.js +161 -0
  151. package/src/new-project/project-files.js +348 -0
  152. package/src/new-project/template-policy.js +269 -0
  153. package/src/new-project/template-resolution.js +368 -0
  154. package/src/new-project/template-snapshots.js +430 -0
  155. package/src/new-project/template-updates.js +512 -0
  156. package/src/new-project/types.d.ts +83 -0
  157. package/src/new-project.js +6 -2277
  158. package/src/parser.d.ts +87 -1
  159. package/src/parser.js +118 -0
  160. package/src/policy/review-boundaries.d.ts +15 -0
  161. package/src/project-config/index.js +564 -0
  162. package/src/project-config.js +19 -561
  163. package/src/resolver/enrich/acceptance-criterion.js +2 -0
  164. package/src/resolver/enrich/bug.js +2 -0
  165. package/src/resolver/enrich/pitch.js +2 -0
  166. package/src/resolver/enrich/requirement.js +2 -0
  167. package/src/resolver/enrich/task.js +2 -0
  168. package/src/resolver/index.js +19 -2089
  169. package/src/resolver/normalize.js +384 -1
  170. package/src/resolver/plans.js +168 -0
  171. package/src/resolver/projections-api.js +494 -0
  172. package/src/resolver/projections-db.js +133 -0
  173. package/src/resolver/projections-ui.js +317 -0
  174. package/src/resolver/shapes.js +251 -0
  175. package/src/resolver/shared.js +278 -0
  176. package/src/resolver/widgets.js +132 -0
  177. package/src/template-trust/constants.js +62 -0
  178. package/src/template-trust/content.js +258 -0
  179. package/src/template-trust/diff.js +92 -0
  180. package/src/template-trust/policy.js +61 -0
  181. package/src/template-trust/record.js +90 -0
  182. package/src/template-trust/status.js +182 -0
  183. package/src/template-trust.js +24 -687
  184. package/src/text-helpers.d.ts +1 -0
  185. package/src/topogram-types.d.ts +69 -0
  186. package/src/validator/common.js +488 -0
  187. package/src/validator/data-model.js +237 -0
  188. package/src/validator/docs.js +167 -0
  189. package/src/validator/expressions.js +146 -1
  190. package/src/validator/index.d.ts +23 -0
  191. package/src/validator/index.js +32 -3585
  192. package/src/validator/kinds.d.ts +41 -0
  193. package/src/validator/kinds.js +2 -0
  194. package/src/validator/model-helpers.js +46 -0
  195. package/src/validator/per-kind/acceptance-criterion.js +5 -0
  196. package/src/validator/per-kind/bug.js +6 -0
  197. package/src/validator/per-kind/domain.js +15 -2
  198. package/src/validator/per-kind/pitch.js +7 -0
  199. package/src/validator/per-kind/requirement.js +5 -0
  200. package/src/validator/per-kind/task.js +7 -0
  201. package/src/validator/per-kind/widget.js +14 -0
  202. package/src/validator/projections/api-http-async.js +410 -0
  203. package/src/validator/projections/api-http-authz.js +88 -0
  204. package/src/validator/projections/api-http-core.js +205 -0
  205. package/src/validator/projections/api-http-policies.js +339 -0
  206. package/src/validator/projections/api-http-responses.js +233 -0
  207. package/src/validator/projections/api-http.js +44 -0
  208. package/src/validator/projections/db.js +353 -0
  209. package/src/validator/projections/generator-defaults.js +45 -0
  210. package/src/validator/projections/helpers.js +87 -0
  211. package/src/validator/projections/ui-helpers.js +214 -0
  212. package/src/validator/projections/ui-navigation.js +344 -0
  213. package/src/validator/projections/ui-structure.js +364 -0
  214. package/src/validator/projections/ui-widgets.js +493 -0
  215. package/src/validator/projections/ui.js +46 -0
  216. package/src/validator/registry.js +48 -1
  217. package/src/validator/utils.d.ts +20 -0
  218. package/src/validator/utils.js +115 -12
  219. package/src/widget-behavior.d.ts +1 -0
  220. package/src/workflows/import-app/api/collect.js +221 -0
  221. package/src/workflows/import-app/api/openapi.js +257 -0
  222. package/src/workflows/import-app/api/routes.js +327 -0
  223. package/src/workflows/import-app/api/sources.js +22 -0
  224. package/src/workflows/import-app/api.js +2 -797
  225. package/src/workflows/reconcile/adoption-plan/build.js +208 -0
  226. package/src/workflows/reconcile/adoption-plan/dependencies.js +75 -0
  227. package/src/workflows/reconcile/adoption-plan/outputs.js +143 -0
  228. package/src/workflows/reconcile/adoption-plan/paths.js +58 -0
  229. package/src/workflows/reconcile/adoption-plan/projection-patches.js +177 -0
  230. package/src/workflows/reconcile/adoption-plan/reasons.js +107 -0
  231. package/src/workflows/reconcile/adoption-plan.js +30 -740
  232. package/src/workflows/reconcile/auth/closures.js +115 -0
  233. package/src/workflows/reconcile/auth/formatters.js +142 -0
  234. package/src/workflows/reconcile/auth/inference.js +330 -0
  235. package/src/workflows/reconcile/auth/roles.js +122 -0
  236. package/src/workflows/reconcile/auth.js +35 -690
  237. package/src/workflows/reconcile/bundle-core/index.js +600 -0
  238. package/src/workflows/reconcile/bundle-core.js +12 -598
  239. package/src/workflows/reconcile/canonical-surface.js +1 -1
  240. package/src/workflows/reconcile/impacts/adoption-plan.js +192 -0
  241. package/src/workflows/reconcile/impacts/indexes.js +101 -0
  242. package/src/workflows/reconcile/impacts/patches.js +252 -0
  243. package/src/workflows/reconcile/impacts/reports.js +80 -0
  244. package/src/workflows/reconcile/impacts.js +14 -623
  245. package/src/workspace-docs.d.ts +29 -0
@@ -0,0 +1,494 @@
1
+ import { blockEntries, getFieldValue } from "../validator.js";
2
+ import { normalizeSequence, tokenValue } from "./shared.js";
3
+
4
+ export function parseProjectionHttpBlock(statement, registry) {
5
+ return blockEntries(getFieldValue(statement, "endpoints")).map((entry) => {
6
+ const capabilityId = tokenValue(entry.items[0]);
7
+ const directives = {};
8
+
9
+ for (let i = 1; i < entry.items.length; i += 2) {
10
+ const key = tokenValue(entry.items[i]);
11
+ const value = tokenValue(entry.items[i + 1]);
12
+ if (key && value != null) {
13
+ directives[key] = value;
14
+ }
15
+ }
16
+
17
+ return {
18
+ type: "http_realization",
19
+ capability: capabilityId
20
+ ? {
21
+ id: capabilityId,
22
+ kind: registry.get(capabilityId)?.kind || null
23
+ }
24
+ : null,
25
+ method: directives.method || null,
26
+ path: directives.path || null,
27
+ success: directives.success ? Number.parseInt(directives.success, 10) : null,
28
+ auth: directives.auth || null,
29
+ request: directives.request || null,
30
+ raw: normalizeSequence(entry.items),
31
+ loc: entry.loc
32
+ };
33
+ });
34
+ }
35
+
36
+ export function parseProjectionHttpErrorsBlock(statement, registry) {
37
+ return blockEntries(getFieldValue(statement, "error_responses")).map((entry) => ({
38
+ type: "http_error_mapping",
39
+ capability: tokenValue(entry.items[0])
40
+ ? {
41
+ id: tokenValue(entry.items[0]),
42
+ kind: registry.get(tokenValue(entry.items[0]))?.kind || null
43
+ }
44
+ : null,
45
+ code: tokenValue(entry.items[1]),
46
+ status: tokenValue(entry.items[2]) ? Number.parseInt(tokenValue(entry.items[2]), 10) : null,
47
+ raw: normalizeSequence(entry.items),
48
+ loc: entry.loc
49
+ }));
50
+ }
51
+
52
+ export function parseProjectionHttpFieldsBlock(statement, registry) {
53
+ return blockEntries(getFieldValue(statement, "wire_fields")).map((entry) => ({
54
+ type: "http_field_binding",
55
+ capability: tokenValue(entry.items[0])
56
+ ? {
57
+ id: tokenValue(entry.items[0]),
58
+ kind: registry.get(tokenValue(entry.items[0]))?.kind || null
59
+ }
60
+ : null,
61
+ direction: tokenValue(entry.items[1]),
62
+ field: tokenValue(entry.items[2]),
63
+ location: tokenValue(entry.items[4]),
64
+ wireName: tokenValue(entry.items[5]) === "as" ? tokenValue(entry.items[6]) : null,
65
+ raw: normalizeSequence(entry.items),
66
+ loc: entry.loc
67
+ }));
68
+ }
69
+
70
+ export function parseProjectionHttpResponsesBlock(statement, registry) {
71
+ return blockEntries(getFieldValue(statement, "responses")).map((entry) => {
72
+ const capabilityId = tokenValue(entry.items[0]);
73
+ const directives = parseProjectionHttpResponseDirectives(entry.items.slice(1));
74
+
75
+ return {
76
+ type: "http_response_realization",
77
+ capability: capabilityId
78
+ ? {
79
+ id: capabilityId,
80
+ kind: registry.get(capabilityId)?.kind || null
81
+ }
82
+ : null,
83
+ mode: directives.mode || null,
84
+ item: directives.item
85
+ ? {
86
+ id: directives.item,
87
+ kind: registry.get(directives.item)?.kind || null
88
+ }
89
+ : null,
90
+ cursor: directives.cursor || null,
91
+ limit: directives.limit
92
+ ? {
93
+ field: directives.limit.field,
94
+ defaultValue: directives.limit.defaultValue ? Number.parseInt(directives.limit.defaultValue, 10) : null,
95
+ maxValue: directives.limit.maxValue ? Number.parseInt(directives.limit.maxValue, 10) : null
96
+ }
97
+ : null,
98
+ sort: directives.sort
99
+ ? {
100
+ field: directives.sort.field,
101
+ direction: directives.sort.direction
102
+ }
103
+ : null,
104
+ total: directives.total
105
+ ? {
106
+ included: directives.total.included === "true"
107
+ }
108
+ : null,
109
+ raw: normalizeSequence(entry.items),
110
+ loc: entry.loc
111
+ };
112
+ });
113
+ }
114
+
115
+ export function parseProjectionHttpPreconditionsBlock(statement, registry) {
116
+ return blockEntries(getFieldValue(statement, "preconditions")).map((entry) => {
117
+ const capabilityId = tokenValue(entry.items[0]);
118
+ const directives = {};
119
+
120
+ for (let i = 1; i < entry.items.length; i += 2) {
121
+ const key = tokenValue(entry.items[i]);
122
+ const value = tokenValue(entry.items[i + 1]);
123
+ if (key && value != null) {
124
+ directives[key] = value;
125
+ }
126
+ }
127
+
128
+ return {
129
+ type: "http_precondition",
130
+ capability: capabilityId
131
+ ? {
132
+ id: capabilityId,
133
+ kind: registry.get(capabilityId)?.kind || null
134
+ }
135
+ : null,
136
+ header: directives.header || null,
137
+ required: directives.required === "true",
138
+ error: directives.error ? Number.parseInt(directives.error, 10) : null,
139
+ source: directives.source || null,
140
+ code: directives.code || null,
141
+ raw: normalizeSequence(entry.items),
142
+ loc: entry.loc
143
+ };
144
+ });
145
+ }
146
+
147
+ export function parseProjectionHttpIdempotencyBlock(statement, registry) {
148
+ return blockEntries(getFieldValue(statement, "idempotency")).map((entry) => {
149
+ const capabilityId = tokenValue(entry.items[0]);
150
+ const directives = {};
151
+
152
+ for (let i = 1; i < entry.items.length; i += 2) {
153
+ const key = tokenValue(entry.items[i]);
154
+ const value = tokenValue(entry.items[i + 1]);
155
+ if (key && value != null) {
156
+ directives[key] = value;
157
+ }
158
+ }
159
+
160
+ return {
161
+ type: "idempotency",
162
+ capability: capabilityId
163
+ ? {
164
+ id: capabilityId,
165
+ kind: registry.get(capabilityId)?.kind || null
166
+ }
167
+ : null,
168
+ header: directives.header || null,
169
+ required: directives.required === "true",
170
+ error: directives.error ? Number.parseInt(directives.error, 10) : null,
171
+ code: directives.code || null,
172
+ raw: normalizeSequence(entry.items),
173
+ loc: entry.loc
174
+ };
175
+ });
176
+ }
177
+
178
+ export function parseProjectionHttpCacheBlock(statement, registry) {
179
+ return blockEntries(getFieldValue(statement, "cache")).map((entry) => {
180
+ const capabilityId = tokenValue(entry.items[0]);
181
+ const directives = {};
182
+
183
+ for (let i = 1; i < entry.items.length; i += 2) {
184
+ const key = tokenValue(entry.items[i]);
185
+ const value = tokenValue(entry.items[i + 1]);
186
+ if (key && value != null) {
187
+ directives[key] = value;
188
+ }
189
+ }
190
+
191
+ return {
192
+ type: "cache",
193
+ capability: capabilityId
194
+ ? {
195
+ id: capabilityId,
196
+ kind: registry.get(capabilityId)?.kind || null
197
+ }
198
+ : null,
199
+ responseHeader: directives.response_header || null,
200
+ requestHeader: directives.request_header || null,
201
+ required: directives.required === "true",
202
+ notModified: directives.not_modified ? Number.parseInt(directives.not_modified, 10) : null,
203
+ source: directives.source || null,
204
+ code: directives.code || null,
205
+ raw: normalizeSequence(entry.items),
206
+ loc: entry.loc
207
+ };
208
+ });
209
+ }
210
+
211
+ export function parseProjectionHttpDeleteBlock(statement, registry) {
212
+ return blockEntries(getFieldValue(statement, "delete_semantics")).map((entry) => {
213
+ const capabilityId = tokenValue(entry.items[0]);
214
+ const directives = {};
215
+
216
+ for (let i = 1; i < entry.items.length; i += 2) {
217
+ const key = tokenValue(entry.items[i]);
218
+ const value = tokenValue(entry.items[i + 1]);
219
+ if (key && value != null) {
220
+ directives[key] = value;
221
+ }
222
+ }
223
+
224
+ return {
225
+ type: "delete_semantics",
226
+ capability: capabilityId
227
+ ? {
228
+ id: capabilityId,
229
+ kind: registry.get(capabilityId)?.kind || null
230
+ }
231
+ : null,
232
+ mode: directives.mode || null,
233
+ field: directives.field || null,
234
+ value: directives.value || null,
235
+ response: directives.response || null,
236
+ raw: normalizeSequence(entry.items),
237
+ loc: entry.loc
238
+ };
239
+ });
240
+ }
241
+
242
+ export function parseProjectionHttpAsyncBlock(statement, registry) {
243
+ return blockEntries(getFieldValue(statement, "async_jobs")).map((entry) => {
244
+ const capabilityId = tokenValue(entry.items[0]);
245
+ const directives = {};
246
+
247
+ for (let i = 1; i < entry.items.length; i += 2) {
248
+ const key = tokenValue(entry.items[i]);
249
+ const value = tokenValue(entry.items[i + 1]);
250
+ if (key && value != null) {
251
+ directives[key] = value;
252
+ }
253
+ }
254
+
255
+ return {
256
+ type: "async_jobs",
257
+ capability: capabilityId
258
+ ? {
259
+ id: capabilityId,
260
+ kind: registry.get(capabilityId)?.kind || null
261
+ }
262
+ : null,
263
+ mode: directives.mode || null,
264
+ accepted: directives.accepted ? Number.parseInt(directives.accepted, 10) : null,
265
+ locationHeader: directives.location_header || null,
266
+ retryAfterHeader: directives.retry_after_header || null,
267
+ statusPath: directives.status_path || null,
268
+ statusCapability: directives.status_capability
269
+ ? {
270
+ id: directives.status_capability,
271
+ kind: registry.get(directives.status_capability)?.kind || null
272
+ }
273
+ : null,
274
+ job: directives.job
275
+ ? {
276
+ id: directives.job,
277
+ kind: registry.get(directives.job)?.kind || null
278
+ }
279
+ : null,
280
+ raw: normalizeSequence(entry.items),
281
+ loc: entry.loc
282
+ };
283
+ });
284
+ }
285
+
286
+ export function parseProjectionHttpStatusBlock(statement, registry) {
287
+ return blockEntries(getFieldValue(statement, "async_status")).map((entry) => {
288
+ const capabilityId = tokenValue(entry.items[0]);
289
+ const directives = {};
290
+
291
+ for (let i = 1; i < entry.items.length; i += 2) {
292
+ const key = tokenValue(entry.items[i]);
293
+ const value = tokenValue(entry.items[i + 1]);
294
+ if (key && value != null) {
295
+ directives[key] = value;
296
+ }
297
+ }
298
+
299
+ return {
300
+ type: "async_status",
301
+ capability: capabilityId
302
+ ? {
303
+ id: capabilityId,
304
+ kind: registry.get(capabilityId)?.kind || null
305
+ }
306
+ : null,
307
+ asyncFor: directives.async_for
308
+ ? {
309
+ id: directives.async_for,
310
+ kind: registry.get(directives.async_for)?.kind || null
311
+ }
312
+ : null,
313
+ stateField: directives.state_field || null,
314
+ completed: directives.completed || null,
315
+ failed: directives.failed || null,
316
+ expired: directives.expired || null,
317
+ downloadCapability: directives.download_capability
318
+ ? {
319
+ id: directives.download_capability,
320
+ kind: registry.get(directives.download_capability)?.kind || null
321
+ }
322
+ : null,
323
+ downloadField: directives.download_field || null,
324
+ errorField: directives.error_field || null,
325
+ raw: normalizeSequence(entry.items),
326
+ loc: entry.loc
327
+ };
328
+ });
329
+ }
330
+
331
+ export function parseProjectionHttpDownloadBlock(statement, registry) {
332
+ return blockEntries(getFieldValue(statement, "downloads")).map((entry) => {
333
+ const capabilityId = tokenValue(entry.items[0]);
334
+ const directives = {};
335
+
336
+ for (let i = 1; i < entry.items.length; i += 2) {
337
+ const key = tokenValue(entry.items[i]);
338
+ const value = tokenValue(entry.items[i + 1]);
339
+ if (key && value != null) {
340
+ directives[key] = value;
341
+ }
342
+ }
343
+
344
+ return {
345
+ type: "downloads",
346
+ capability: capabilityId
347
+ ? {
348
+ id: capabilityId,
349
+ kind: registry.get(capabilityId)?.kind || null
350
+ }
351
+ : null,
352
+ asyncFor: directives.async_for
353
+ ? {
354
+ id: directives.async_for,
355
+ kind: registry.get(directives.async_for)?.kind || null
356
+ }
357
+ : null,
358
+ media: directives.media || null,
359
+ filename: directives.filename || null,
360
+ disposition: directives.disposition || null,
361
+ raw: normalizeSequence(entry.items),
362
+ loc: entry.loc
363
+ };
364
+ });
365
+ }
366
+
367
+ export function parseProjectionHttpAuthzBlock(statement, registry) {
368
+ return blockEntries(getFieldValue(statement, "authorization")).map((entry) => {
369
+ const capabilityId = tokenValue(entry.items[0]);
370
+ const directives = {};
371
+
372
+ for (let i = 1; i < entry.items.length; i += 2) {
373
+ const key = tokenValue(entry.items[i]);
374
+ const value = tokenValue(entry.items[i + 1]);
375
+ if (key && value != null) {
376
+ directives[key] = value;
377
+ }
378
+ }
379
+
380
+ return {
381
+ type: "authorization",
382
+ capability: capabilityId
383
+ ? {
384
+ id: capabilityId,
385
+ kind: registry.get(capabilityId)?.kind || null
386
+ }
387
+ : null,
388
+ role: directives.role || null,
389
+ permission: directives.permission || null,
390
+ claim: directives.claim || null,
391
+ claimValue: directives.claim_value || null,
392
+ ownership: directives.ownership || null,
393
+ ownershipField: directives.ownership_field || null,
394
+ raw: normalizeSequence(entry.items),
395
+ loc: entry.loc
396
+ };
397
+ });
398
+ }
399
+
400
+ export function parseProjectionHttpCallbacksBlock(statement, registry) {
401
+ return blockEntries(getFieldValue(statement, "callbacks")).map((entry) => {
402
+ const capabilityId = tokenValue(entry.items[0]);
403
+ const directives = {};
404
+
405
+ for (let i = 1; i < entry.items.length; i += 2) {
406
+ const key = tokenValue(entry.items[i]);
407
+ const value = tokenValue(entry.items[i + 1]);
408
+ if (key && value != null) {
409
+ directives[key] = value;
410
+ }
411
+ }
412
+
413
+ return {
414
+ type: "http_callback",
415
+ capability: capabilityId
416
+ ? {
417
+ id: capabilityId,
418
+ kind: registry.get(capabilityId)?.kind || null
419
+ }
420
+ : null,
421
+ event: directives.event || null,
422
+ targetField: directives.target_field || null,
423
+ method: directives.method || null,
424
+ payload: directives.payload
425
+ ? {
426
+ id: directives.payload,
427
+ kind: registry.get(directives.payload)?.kind || null
428
+ }
429
+ : null,
430
+ success: directives.success ? Number.parseInt(directives.success, 10) : null,
431
+ raw: normalizeSequence(entry.items),
432
+ loc: entry.loc
433
+ };
434
+ });
435
+ }
436
+
437
+ export function parseProjectionHttpResponseDirectives(tokens) {
438
+ const directives = {
439
+ mode: null,
440
+ item: null,
441
+ cursor: null,
442
+ limit: null,
443
+ sort: null,
444
+ total: null
445
+ };
446
+
447
+ for (let i = 0; i < tokens.length; i += 1) {
448
+ const token = tokenValue(tokens[i]);
449
+ if (token === "mode") {
450
+ directives.mode = tokenValue(tokens[i + 1]);
451
+ i += 1;
452
+ continue;
453
+ }
454
+ if (token === "item") {
455
+ directives.item = tokenValue(tokens[i + 1]);
456
+ i += 1;
457
+ continue;
458
+ }
459
+ if (token === "cursor") {
460
+ directives.cursor = {
461
+ requestAfter: tokenValue(tokens[i + 1]) === "request_after" ? tokenValue(tokens[i + 2]) : null,
462
+ responseNext: tokenValue(tokens[i + 3]) === "response_next" ? tokenValue(tokens[i + 4]) : null,
463
+ responsePrev: tokenValue(tokens[i + 5]) === "response_prev" ? tokenValue(tokens[i + 6]) : null
464
+ };
465
+ i += directives.cursor.responsePrev ? 6 : 4;
466
+ continue;
467
+ }
468
+ if (token === "limit") {
469
+ directives.limit = {
470
+ field: tokenValue(tokens[i + 1]) === "field" ? tokenValue(tokens[i + 2]) : null,
471
+ defaultValue: tokenValue(tokens[i + 3]) === "default" ? tokenValue(tokens[i + 4]) : null,
472
+ maxValue: tokenValue(tokens[i + 5]) === "max" ? tokenValue(tokens[i + 6]) : null
473
+ };
474
+ i += 6;
475
+ continue;
476
+ }
477
+ if (token === "sort") {
478
+ directives.sort = {
479
+ field: tokenValue(tokens[i + 1]) === "by" ? tokenValue(tokens[i + 2]) : null,
480
+ direction: tokenValue(tokens[i + 3]) === "direction" ? tokenValue(tokens[i + 4]) : null
481
+ };
482
+ i += 4;
483
+ continue;
484
+ }
485
+ if (token === "total") {
486
+ directives.total = {
487
+ included: tokenValue(tokens[i + 1]) === "included" ? tokenValue(tokens[i + 2]) : null
488
+ };
489
+ i += 2;
490
+ }
491
+ }
492
+
493
+ return directives;
494
+ }
@@ -0,0 +1,133 @@
1
+ import { blockEntries, getFieldValue } from "../validator.js";
2
+ import { normalizeSequence, tokenValue } from "./shared.js";
3
+
4
+ export function parseProjectionGeneratorDefaultsBlock(statement) {
5
+ return blockEntries(getFieldValue(statement, "generator_defaults")).map((entry) => ({
6
+ type: "generator_default",
7
+ key: tokenValue(entry.items[0]),
8
+ value: tokenValue(entry.items[1]) || null,
9
+ raw: normalizeSequence(entry.items),
10
+ loc: entry.loc
11
+ }));
12
+ }
13
+
14
+ export function parseProjectionDbTablesBlock(statement, registry) {
15
+ return blockEntries(getFieldValue(statement, "tables")).map((entry) => ({
16
+ type: "db_table_mapping",
17
+ entity: tokenValue(entry.items[0])
18
+ ? {
19
+ id: tokenValue(entry.items[0]),
20
+ kind: registry.get(tokenValue(entry.items[0]))?.kind || null
21
+ }
22
+ : null,
23
+ table: tokenValue(entry.items[2]) || null,
24
+ raw: normalizeSequence(entry.items),
25
+ loc: entry.loc
26
+ }));
27
+ }
28
+
29
+ export function parseProjectionDbColumnsBlock(statement, registry) {
30
+ return blockEntries(getFieldValue(statement, "columns")).map((entry) => ({
31
+ type: "db_column_mapping",
32
+ entity: tokenValue(entry.items[0])
33
+ ? {
34
+ id: tokenValue(entry.items[0]),
35
+ kind: registry.get(tokenValue(entry.items[0]))?.kind || null
36
+ }
37
+ : null,
38
+ field: tokenValue(entry.items[2]) || null,
39
+ column: tokenValue(entry.items[4]) || null,
40
+ raw: normalizeSequence(entry.items),
41
+ loc: entry.loc
42
+ }));
43
+ }
44
+
45
+ export function parseProjectionDbKeysBlock(statement, registry) {
46
+ return blockEntries(getFieldValue(statement, "keys")).map((entry) => ({
47
+ type: "db_key",
48
+ entity: tokenValue(entry.items[0])
49
+ ? {
50
+ id: tokenValue(entry.items[0]),
51
+ kind: registry.get(tokenValue(entry.items[0]))?.kind || null
52
+ }
53
+ : null,
54
+ keyType: tokenValue(entry.items[1]) || null,
55
+ fields: entry.items[2]?.type === "list" ? entry.items[2].items.map((item) => item.value) : [],
56
+ raw: normalizeSequence(entry.items),
57
+ loc: entry.loc
58
+ }));
59
+ }
60
+
61
+ export function parseProjectionDbIndexesBlock(statement, registry) {
62
+ return blockEntries(getFieldValue(statement, "indexes")).map((entry) => ({
63
+ type: "db_index",
64
+ entity: tokenValue(entry.items[0])
65
+ ? {
66
+ id: tokenValue(entry.items[0]),
67
+ kind: registry.get(tokenValue(entry.items[0]))?.kind || null
68
+ }
69
+ : null,
70
+ indexType: tokenValue(entry.items[1]) || null,
71
+ fields: entry.items[2]?.type === "list" ? entry.items[2].items.map((item) => item.value) : [],
72
+ raw: normalizeSequence(entry.items),
73
+ loc: entry.loc
74
+ }));
75
+ }
76
+
77
+ export function parseProjectionDbRelationsBlock(statement, registry) {
78
+ return blockEntries(getFieldValue(statement, "relations")).map((entry) => {
79
+ const targetRef = tokenValue(entry.items[4]) || null;
80
+ const [targetEntityId, targetField] = (targetRef || "").split(".");
81
+ return {
82
+ type: "db_relation",
83
+ entity: tokenValue(entry.items[0])
84
+ ? {
85
+ id: tokenValue(entry.items[0]),
86
+ kind: registry.get(tokenValue(entry.items[0]))?.kind || null
87
+ }
88
+ : null,
89
+ relationType: tokenValue(entry.items[1]) || null,
90
+ field: tokenValue(entry.items[2]) || null,
91
+ target: targetEntityId
92
+ ? {
93
+ id: targetEntityId,
94
+ kind: registry.get(targetEntityId)?.kind || null,
95
+ field: targetField || null
96
+ }
97
+ : null,
98
+ onDelete: tokenValue(entry.items[6]) || null,
99
+ raw: normalizeSequence(entry.items),
100
+ loc: entry.loc
101
+ };
102
+ });
103
+ }
104
+
105
+ export function parseProjectionDbLifecycleBlock(statement, registry) {
106
+ return blockEntries(getFieldValue(statement, "lifecycle")).map((entry) => {
107
+ const directives = {};
108
+ for (let i = 2; i < entry.items.length; i += 2) {
109
+ const key = tokenValue(entry.items[i]);
110
+ const value = tokenValue(entry.items[i + 1]);
111
+ if (key && value != null) {
112
+ directives[key] = value;
113
+ }
114
+ }
115
+
116
+ return {
117
+ type: "lifecycle",
118
+ entity: tokenValue(entry.items[0])
119
+ ? {
120
+ id: tokenValue(entry.items[0]),
121
+ kind: registry.get(tokenValue(entry.items[0]))?.kind || null
122
+ }
123
+ : null,
124
+ lifecycleType: tokenValue(entry.items[1]) || null,
125
+ field: directives.field || null,
126
+ value: directives.value || null,
127
+ createdAt: directives.created_at || null,
128
+ updatedAt: directives.updated_at || null,
129
+ raw: normalizeSequence(entry.items),
130
+ loc: entry.loc
131
+ };
132
+ });
133
+ }