primitive-admin 1.1.0-alpha.3 → 1.1.0-alpha.31

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 (99) hide show
  1. package/README.md +168 -21
  2. package/assets/skill/skills/primitive-platform/SKILL.md +226 -0
  3. package/dist/bin/primitive.js +198 -15
  4. package/dist/bin/primitive.js.map +1 -1
  5. package/dist/src/commands/admins.js +107 -0
  6. package/dist/src/commands/admins.js.map +1 -1
  7. package/dist/src/commands/analytics.js +464 -55
  8. package/dist/src/commands/analytics.js.map +1 -1
  9. package/dist/src/commands/apps.js +27 -13
  10. package/dist/src/commands/apps.js.map +1 -1
  11. package/dist/src/commands/auth.js +165 -5
  12. package/dist/src/commands/auth.js.map +1 -1
  13. package/dist/src/commands/blob-buckets.js +354 -0
  14. package/dist/src/commands/blob-buckets.js.map +1 -0
  15. package/dist/src/commands/catalog.js +17 -17
  16. package/dist/src/commands/catalog.js.map +1 -1
  17. package/dist/src/commands/collection-type-configs.js +178 -0
  18. package/dist/src/commands/collection-type-configs.js.map +1 -0
  19. package/dist/src/commands/collections.js +526 -0
  20. package/dist/src/commands/collections.js.map +1 -0
  21. package/dist/src/commands/comparisons.js +6 -6
  22. package/dist/src/commands/comparisons.js.map +1 -1
  23. package/dist/src/commands/cron-triggers.js +364 -0
  24. package/dist/src/commands/cron-triggers.js.map +1 -0
  25. package/dist/src/commands/database-types.js +462 -0
  26. package/dist/src/commands/database-types.js.map +1 -0
  27. package/dist/src/commands/databases.js +1067 -58
  28. package/dist/src/commands/databases.js.map +1 -1
  29. package/dist/src/commands/documents.js +510 -2
  30. package/dist/src/commands/documents.js.map +1 -1
  31. package/dist/src/commands/email-templates.js +281 -0
  32. package/dist/src/commands/email-templates.js.map +1 -0
  33. package/dist/src/commands/env.js +260 -0
  34. package/dist/src/commands/env.js.map +1 -0
  35. package/dist/src/commands/group-type-configs.js +189 -0
  36. package/dist/src/commands/group-type-configs.js.map +1 -0
  37. package/dist/src/commands/groups.js +28 -25
  38. package/dist/src/commands/groups.js.map +1 -1
  39. package/dist/src/commands/init.js +719 -188
  40. package/dist/src/commands/init.js.map +1 -1
  41. package/dist/src/commands/integrations.js +504 -33
  42. package/dist/src/commands/integrations.js.map +1 -1
  43. package/dist/src/commands/prompts.js +17 -16
  44. package/dist/src/commands/prompts.js.map +1 -1
  45. package/dist/src/commands/rule-sets.js +366 -0
  46. package/dist/src/commands/rule-sets.js.map +1 -0
  47. package/dist/src/commands/secrets.js +108 -0
  48. package/dist/src/commands/secrets.js.map +1 -0
  49. package/dist/src/commands/skill.js +29 -0
  50. package/dist/src/commands/skill.js.map +1 -0
  51. package/dist/src/commands/sync.js +2363 -182
  52. package/dist/src/commands/sync.js.map +1 -1
  53. package/dist/src/commands/tokens.js +9 -9
  54. package/dist/src/commands/tokens.js.map +1 -1
  55. package/dist/src/commands/users.js +426 -4
  56. package/dist/src/commands/users.js.map +1 -1
  57. package/dist/src/commands/webhooks.js +386 -0
  58. package/dist/src/commands/webhooks.js.map +1 -0
  59. package/dist/src/commands/workflows.js +614 -64
  60. package/dist/src/commands/workflows.js.map +1 -1
  61. package/dist/src/lib/api-client.js +942 -83
  62. package/dist/src/lib/api-client.js.map +1 -1
  63. package/dist/src/lib/config.js +51 -53
  64. package/dist/src/lib/config.js.map +1 -1
  65. package/dist/src/lib/constants.js +3 -0
  66. package/dist/src/lib/constants.js.map +1 -0
  67. package/dist/src/lib/credentials-store.js +307 -0
  68. package/dist/src/lib/credentials-store.js.map +1 -0
  69. package/dist/src/lib/env-resolver.js +121 -0
  70. package/dist/src/lib/env-resolver.js.map +1 -0
  71. package/dist/src/lib/init-config.js +87 -0
  72. package/dist/src/lib/init-config.js.map +1 -0
  73. package/dist/src/lib/migration-nag.js +163 -0
  74. package/dist/src/lib/migration-nag.js.map +1 -0
  75. package/dist/src/lib/output.js +58 -6
  76. package/dist/src/lib/output.js.map +1 -1
  77. package/dist/src/lib/paginate.js +42 -0
  78. package/dist/src/lib/paginate.js.map +1 -0
  79. package/dist/src/lib/project-config.js +209 -0
  80. package/dist/src/lib/project-config.js.map +1 -0
  81. package/dist/src/lib/refresh-admin-credentials.js +103 -0
  82. package/dist/src/lib/refresh-admin-credentials.js.map +1 -0
  83. package/dist/src/lib/skill-installer.js +135 -0
  84. package/dist/src/lib/skill-installer.js.map +1 -0
  85. package/dist/src/lib/sync-paths.js +102 -0
  86. package/dist/src/lib/sync-paths.js.map +1 -0
  87. package/dist/src/lib/template.js +279 -18
  88. package/dist/src/lib/template.js.map +1 -1
  89. package/dist/src/lib/toml-database-config.js +384 -0
  90. package/dist/src/lib/toml-database-config.js.map +1 -0
  91. package/dist/src/lib/toml-params-validator.js +183 -0
  92. package/dist/src/lib/toml-params-validator.js.map +1 -0
  93. package/dist/src/lib/version-check.js +172 -0
  94. package/dist/src/lib/version-check.js.map +1 -0
  95. package/dist/src/lib/workflow-fragments.js +121 -0
  96. package/dist/src/lib/workflow-fragments.js.map +1 -0
  97. package/dist/src/lib/workflow-toml-validator.js +328 -0
  98. package/dist/src/lib/workflow-toml-validator.js.map +1 -0
  99. package/package.json +7 -4
@@ -0,0 +1,384 @@
1
+ /**
2
+ * Helpers for emitting `DatabaseTypeOperation` configs as native TOML.
3
+ *
4
+ * Background (issue #752): historically `sync pull` serialized
5
+ * `definition` and `params` as JSON strings stuffed into a single TOML
6
+ * field, which produced unreviewable 800-char one-liners. This module
7
+ * lets us emit them as nested TOML tables when they're representable,
8
+ * while preserving the existing file's shape so we don't generate
9
+ * surprise diffs.
10
+ *
11
+ * Three responsibilities:
12
+ * 1. `detectExistingOperationForms()` — read the raw TOML source and
13
+ * decide, per operation name, whether the file uses JSON-string
14
+ * form ("legacy") or nested-table form ("native") for each of
15
+ * `definition` and `params`. This drives form preservation on
16
+ * `sync pull`.
17
+ * 2. `canEmitNative()` — recursively check whether a JS value is
18
+ * representable as a TOML value. Returns a reason string if not.
19
+ * Mainly catches `null` and mixed-type arrays, which `@iarna/toml`
20
+ * either rejects or silently mangles.
21
+ * 3. `buildDatabaseTypeTomlData()` — builds the JS object that we
22
+ * hand to `TOML.stringify`. Per operation, decides JSON-string vs
23
+ * native based on (existing form, can-emit, override mode).
24
+ */
25
+ import * as TOML from "@iarna/toml";
26
+ /**
27
+ * Inspect the raw TOML source for a database-type file and decide which
28
+ * form each operation's `definition`/`params` currently use.
29
+ *
30
+ * Detection is intentionally simple: we walk `[[operations]]` blocks in
31
+ * source order and, for each one, look for either a `definition = '...'`
32
+ * line (legacy) or an `[operations.definition]` / `[operations.definition.X]`
33
+ * sub-header (native).
34
+ */
35
+ export function detectExistingOperationForms(rawToml) {
36
+ const lines = rawToml.split(/\r?\n/);
37
+ const operations = [];
38
+ let current = null;
39
+ // `inSubTable` flips to true the moment we descend into a sub-table of
40
+ // the current operation (e.g. `[operations.definition]` or
41
+ // `[[operations.params]]`). Once true, subsequent `name = "..."` /
42
+ // `definition = "..."` / `params = "..."` lines belong to the sub-table,
43
+ // not to the operation itself, so we must not let them overwrite the
44
+ // op-level fields (review feedback r3246634568).
45
+ let inSubTable = false;
46
+ for (const rawLine of lines) {
47
+ const line = rawLine.trim();
48
+ if (line === "[[operations]]") {
49
+ if (current)
50
+ operations.push(current);
51
+ current = { name: null, definition: null, params: null };
52
+ inSubTable = false;
53
+ continue;
54
+ }
55
+ if (!current)
56
+ continue;
57
+ // Sub-header for this op's definition or params.
58
+ if (/^\[operations\.definition(\..+)?\]/.test(line) || /^\[\[operations\.definition\..+\]\]/.test(line)) {
59
+ if (current.definition === null)
60
+ current.definition = "native";
61
+ inSubTable = true;
62
+ continue;
63
+ }
64
+ if (/^\[\[operations\.params\]\]/.test(line) || /^\[operations\.params(\..+)?\]/.test(line)) {
65
+ if (current.params === null)
66
+ current.params = "native";
67
+ inSubTable = true;
68
+ continue;
69
+ }
70
+ // A new top-level array-of-tables block ends the operation's scope
71
+ // for our purposes. We don't fully parse TOML here; we just stop
72
+ // ascribing later lines to this op.
73
+ if (/^\[\[/.test(line) && !line.startsWith("[[operations.")) {
74
+ operations.push(current);
75
+ current = null;
76
+ inSubTable = false;
77
+ continue;
78
+ }
79
+ if (/^\[/.test(line) && !line.startsWith("[operations.")) {
80
+ operations.push(current);
81
+ current = null;
82
+ inSubTable = false;
83
+ continue;
84
+ }
85
+ // Op-level fields. Skip if we've already descended into a sub-table —
86
+ // a `name = "id"` inside `[[operations.params]]` belongs to the param,
87
+ // not to the operation. Same for any other key we recognize here.
88
+ if (inSubTable)
89
+ continue;
90
+ const m = line.match(/^([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.*)$/);
91
+ if (!m)
92
+ continue;
93
+ const key = m[1];
94
+ const value = m[2];
95
+ if (key === "name") {
96
+ const nameMatch = value.match(/^["'](.+)["']\s*$/);
97
+ if (nameMatch)
98
+ current.name = nameMatch[1];
99
+ }
100
+ else if (key === "definition" && current.definition === null) {
101
+ current.definition = "legacy";
102
+ }
103
+ else if (key === "params" && current.params === null) {
104
+ current.params = "legacy";
105
+ }
106
+ }
107
+ if (current)
108
+ operations.push(current);
109
+ const definition = new Map();
110
+ const params = new Map();
111
+ for (const op of operations) {
112
+ if (!op.name)
113
+ continue;
114
+ if (op.definition)
115
+ definition.set(op.name, op.definition);
116
+ if (op.params)
117
+ params.set(op.name, op.params);
118
+ }
119
+ return { definition, params };
120
+ }
121
+ /**
122
+ * Recursively check whether a JS value can be safely serialized to TOML
123
+ * using `@iarna/toml`. Returns null if OK, a reason string otherwise.
124
+ *
125
+ * Things TOML can't represent (in `@iarna/toml`):
126
+ * - `null` (TOML has no null).
127
+ * - Arrays containing values of different "TOML types" (e.g. mixed
128
+ * string and number). Spec-wise TOML 1.0 actually allows this, but
129
+ * `@iarna/toml` is strict and throws.
130
+ * - `undefined` (different from null but equally not representable).
131
+ */
132
+ export function canEmitNative(value) {
133
+ if (value === null)
134
+ return "value is null";
135
+ if (value === undefined)
136
+ return "value is undefined";
137
+ if (Array.isArray(value)) {
138
+ if (value.length > 0) {
139
+ const types = new Set();
140
+ for (const item of value) {
141
+ if (item === null)
142
+ return "array contains null";
143
+ if (Array.isArray(item))
144
+ types.add("array");
145
+ else
146
+ types.add(typeof item);
147
+ }
148
+ if (types.size > 1) {
149
+ return `array contains mixed types (${[...types].sort().join(", ")})`;
150
+ }
151
+ }
152
+ for (const item of value) {
153
+ const sub = canEmitNative(item);
154
+ if (sub)
155
+ return sub;
156
+ }
157
+ return null;
158
+ }
159
+ if (typeof value === "object") {
160
+ for (const v of Object.values(value)) {
161
+ const sub = canEmitNative(v);
162
+ if (sub)
163
+ return sub;
164
+ }
165
+ return null;
166
+ }
167
+ // primitives: string, number, boolean.
168
+ return null;
169
+ }
170
+ /**
171
+ * Normalize a `params` value into a sorted array of
172
+ * `{ name, type, required, ... }` rows, suitable for emitting as
173
+ * `[[operations.params]]`. Accepts both shapes the wire/parser supports:
174
+ * - object form: `{ projectId: { type: "string", required: true } }`
175
+ * - array form: `[{ name: "projectId", type: "string", required: true }]`
176
+ */
177
+ export function normalizeParamsToArray(params) {
178
+ if (params == null)
179
+ return null;
180
+ if (Array.isArray(params)) {
181
+ return params
182
+ .map((p) => ({ ...p }))
183
+ .filter((p) => p && typeof p === "object");
184
+ }
185
+ if (typeof params === "object") {
186
+ return Object.entries(params).map(([name, spec]) => ({
187
+ name,
188
+ ...(spec && typeof spec === "object" ? spec : {}),
189
+ }));
190
+ }
191
+ return null;
192
+ }
193
+ /**
194
+ * Default form for a new operation (no existing form hint): native.
195
+ * That matches the issue's "new file from server → native by default"
196
+ * requirement.
197
+ */
198
+ const DEFAULT_FORM = "native";
199
+ /**
200
+ * Build the JS object to pass to `TOML.stringify` for a database-type
201
+ * config file. Per operation:
202
+ * - If the chosen form is "native" AND `definition` is TOML-emittable,
203
+ * emit `[operations.definition]` (nested table).
204
+ * - Else emit `definition = '<json string>'` and log a message.
205
+ * - Same logic independently for `params`, but the native form for
206
+ * params is `[[operations.params]]` (array-of-tables).
207
+ */
208
+ export function buildDatabaseTypeTomlData(typeConfig, operations, ruleSetIdToName, options = {}) {
209
+ const hints = options.hints;
210
+ const defaultForm = options.defaultForm ?? DEFAULT_FORM;
211
+ const log = options.logger ?? (() => { });
212
+ // Prefer the parsed-from-key-based-reference name when present
213
+ // (`_ruleSetName` is set by `parseDatabaseTypeToml` when the source TOML
214
+ // uses the modern `ruleSetName = "..."` form). This makes the
215
+ // parse → serialize cycle a no-op for the rule-set field even when the
216
+ // caller passes an empty `ruleSetIdToName` map (e.g. `sync migrate-toml`,
217
+ // review feedback r3246633010).
218
+ let ruleSetName = "";
219
+ if (typeConfig._ruleSetName) {
220
+ ruleSetName = typeConfig._ruleSetName;
221
+ }
222
+ else if (typeConfig.ruleSetId) {
223
+ ruleSetName = ruleSetIdToName.get(typeConfig.ruleSetId) || "";
224
+ }
225
+ const data = {
226
+ type: {
227
+ databaseType: typeConfig.databaseType,
228
+ ruleSetName,
229
+ },
230
+ };
231
+ if (typeConfig.metadataAccess) {
232
+ data.type.celContextAccess = typeConfig.metadataAccess;
233
+ }
234
+ if (typeConfig.defaultAccess) {
235
+ data.type.defaultAccess = typeConfig.defaultAccess;
236
+ }
237
+ if (typeConfig.autoPopulatedFields) {
238
+ data.type.autoPopulatedFields = typeConfig.autoPopulatedFields;
239
+ }
240
+ if (typeConfig.triggers) {
241
+ data.triggers = typeConfig.triggers;
242
+ }
243
+ // Issue #666: inline schema TOML. The server-side `schema` field is a raw
244
+ // TOML string of `[models.*.fields.*]` blocks. Parse + merge into the same
245
+ // TOML object so the result serializes as `[models.<Name>.fields.<field>]`
246
+ // headers (matches the round-2 plan-of-record CLI sync layout).
247
+ if (typeConfig.schema && typeof typeConfig.schema === "string") {
248
+ try {
249
+ const parsedSchema = TOML.parse(typeConfig.schema);
250
+ if (parsedSchema?.models) {
251
+ data.models = parsedSchema.models;
252
+ }
253
+ }
254
+ catch {
255
+ // If the stored TOML is malformed (operationally surprising), don't
256
+ // crash the serializer — fall through without the models block.
257
+ }
258
+ }
259
+ if (operations.length === 0)
260
+ return data;
261
+ data.operations = operations.map((op) => {
262
+ const opRow = {
263
+ name: op.name,
264
+ type: op.type,
265
+ modelName: op.modelName,
266
+ };
267
+ if (op.access) {
268
+ opRow.access = op.access;
269
+ }
270
+ // ---- definition ----
271
+ const defForm = hints?.definition.get(op.name) ?? defaultForm;
272
+ const defValue = typeof op.definition === "string"
273
+ ? safeParseJson(op.definition)
274
+ : op.definition;
275
+ let definitionEmitted = false;
276
+ if (defForm === "native" && defValue && typeof defValue === "object") {
277
+ const reason = canEmitNative(defValue);
278
+ if (reason) {
279
+ log(`Operation '${op.name}': cannot emit \`definition\` as native TOML (${reason}); falling back to JSON string for this field.`);
280
+ }
281
+ else {
282
+ opRow.definition = defValue;
283
+ definitionEmitted = true;
284
+ }
285
+ }
286
+ if (!definitionEmitted) {
287
+ opRow.definition = typeof op.definition === "object"
288
+ ? JSON.stringify(op.definition)
289
+ : op.definition;
290
+ }
291
+ // ---- params ----
292
+ if (op.params != null) {
293
+ const paramsForm = hints?.params.get(op.name) ?? defaultForm;
294
+ let paramsEmitted = false;
295
+ if (paramsForm === "native") {
296
+ const paramsParsed = typeof op.params === "string"
297
+ ? safeParseJson(op.params)
298
+ : op.params;
299
+ const paramsArray = normalizeParamsToArray(paramsParsed);
300
+ if (paramsArray && paramsArray.length > 0) {
301
+ const reason = canEmitNative(paramsArray);
302
+ if (reason) {
303
+ log(`Operation '${op.name}': cannot emit \`params\` as native TOML (${reason}); falling back to JSON string for this field.`);
304
+ }
305
+ else {
306
+ opRow.params = paramsArray;
307
+ paramsEmitted = true;
308
+ }
309
+ }
310
+ else if (paramsArray && paramsArray.length === 0) {
311
+ // Empty params: skip entirely rather than emitting an empty table.
312
+ paramsEmitted = true;
313
+ }
314
+ }
315
+ if (!paramsEmitted) {
316
+ opRow.params = typeof op.params === "object"
317
+ ? JSON.stringify(op.params)
318
+ : op.params;
319
+ }
320
+ }
321
+ return opRow;
322
+ });
323
+ return data;
324
+ }
325
+ function safeParseJson(s) {
326
+ try {
327
+ return JSON.parse(s);
328
+ }
329
+ catch {
330
+ return s;
331
+ }
332
+ }
333
+ /**
334
+ * After parsing TOML, normalize the `definition` and `params` of each
335
+ * operation row into the JS objects the server expects. Handles both
336
+ * native and legacy forms transparently. The server payload is the
337
+ * source of truth; native TOML is purely a source-control affordance.
338
+ *
339
+ * Mirrors `parseDatabaseTypeToml` in `sync.ts`, but is broken out here
340
+ * so the migrate-toml command can call it without re-implementing.
341
+ */
342
+ export function normalizeOperationFromToml(op) {
343
+ const normalized = {
344
+ name: op.name,
345
+ type: op.type,
346
+ modelName: op.modelName,
347
+ // `access` is optional — when the parent type sets `defaultAccess`,
348
+ // an operation may inherit by omitting this key. Keep null so the
349
+ // server-side controller decides whether to require it.
350
+ access: op.access ?? null,
351
+ };
352
+ if (typeof op.definition === "string") {
353
+ normalized.definition = safeParseJson(op.definition);
354
+ }
355
+ else {
356
+ // Preserve undefined-vs-set parity with the legacy parser by always
357
+ // assigning the key.
358
+ normalized.definition = op.definition;
359
+ }
360
+ if (op.params != null) {
361
+ if (typeof op.params === "string") {
362
+ normalized.params = safeParseJson(op.params);
363
+ }
364
+ else if (Array.isArray(op.params)) {
365
+ // Convert array form back into object form for the server payload.
366
+ const obj = {};
367
+ for (const row of op.params) {
368
+ if (!row || typeof row !== "object" || !row.name)
369
+ continue;
370
+ const { name, ...rest } = row;
371
+ obj[name] = rest;
372
+ }
373
+ normalized.params = obj;
374
+ }
375
+ else if (typeof op.params === "object") {
376
+ normalized.params = op.params;
377
+ }
378
+ }
379
+ else {
380
+ normalized.params = null;
381
+ }
382
+ return normalized;
383
+ }
384
+ //# sourceMappingURL=toml-database-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toml-database-config.js","sourceRoot":"","sources":["../../../src/lib/toml-database-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Validator: every `$params.X` reference inside an operation's
3
+ * `definition` must correspond to a declared param in
4
+ * `[[operations.params]]` (or the legacy JSON-string params object).
5
+ *
6
+ * Background (issue #752): a typo like `$params.proectId` used to
7
+ * silently no-op at runtime. With native TOML, we can catch these at
8
+ * `sync push` time with the file path and line number of the
9
+ * operation block where the bad reference appears.
10
+ *
11
+ * Design notes:
12
+ * - Line attribution is per-operation, not per-reference. We don't
13
+ * parse `definition` line-by-line; we just locate the
14
+ * `[[operations]]` header for the named op in the raw source and
15
+ * report that line. This is the load-bearing UX (jump to the
16
+ * offending op block); pinpointing the exact `$params.X` reference
17
+ * inside a sub-table would require swapping the TOML parser, which
18
+ * the issue explicitly leaves to implementer judgement.
19
+ * - We intentionally diverge from the server-side `collectParamRefs`
20
+ * in `database-type-operations-controller.ts:1163`. The server pushes
21
+ * the full path (e.g. `"X.Y"` for `$params.X.Y`); the CLI extracts
22
+ * only the first segment (`"X"`). Net effect: the CLI validator is
23
+ * more lenient than the server — `$params.X.Y` passes the CLI check
24
+ * when `X` alone is declared in `[[operations.params]]`, even though
25
+ * the server treats the full path as the lookup key. The server
26
+ * remains authoritative; the CLI's first-segment extraction is a
27
+ * pragmatic choice so authors can declare structured params (e.g.
28
+ * `config: { type: "object" }`) and reference sub-fields like
29
+ * `$params.config.subKey` without listing every sub-field
30
+ * individually (review feedback r3246635661).
31
+ */
32
+ /**
33
+ * Walk an arbitrary JSON-ish value and collect `$params.X` references
34
+ * found in string-valued leaves, returning only the first dotted segment
35
+ * (`"X"` for `$params.X.Y`). Intentionally more lenient than the
36
+ * server-side helper, which pushes the full path — see the module
37
+ * doc-comment for the rationale.
38
+ */
39
+ export function collectParamRefs(value) {
40
+ const refs = [];
41
+ if (typeof value === "string") {
42
+ const match = value.match(/^\$params\.(.+)$/);
43
+ if (match) {
44
+ const first = match[1].split(/[.\[]/)[0];
45
+ if (first)
46
+ refs.push(first);
47
+ }
48
+ }
49
+ else if (Array.isArray(value)) {
50
+ for (const item of value) {
51
+ refs.push(...collectParamRefs(item));
52
+ }
53
+ }
54
+ else if (value !== null && typeof value === "object") {
55
+ for (const v of Object.values(value)) {
56
+ refs.push(...collectParamRefs(v));
57
+ }
58
+ }
59
+ return refs;
60
+ }
61
+ /**
62
+ * Normalize a `params` value (object, array, or JSON string) into the
63
+ * set of declared param names.
64
+ */
65
+ export function declaredParamNames(params) {
66
+ const names = new Set();
67
+ if (params == null)
68
+ return names;
69
+ let value = params;
70
+ if (typeof value === "string") {
71
+ try {
72
+ value = JSON.parse(value);
73
+ }
74
+ catch {
75
+ return names;
76
+ }
77
+ }
78
+ if (Array.isArray(value)) {
79
+ for (const row of value) {
80
+ if (row && typeof row === "object" && typeof row.name === "string") {
81
+ names.add(row.name);
82
+ }
83
+ }
84
+ }
85
+ else if (typeof value === "object" && value !== null) {
86
+ for (const key of Object.keys(value)) {
87
+ names.add(key);
88
+ }
89
+ }
90
+ return names;
91
+ }
92
+ /**
93
+ * Find the 1-indexed line number in `rawToml` where the `[[operations]]`
94
+ * block declaring `opName` starts. Returns 0 if not found.
95
+ *
96
+ * Implementation: walk in source order, track the most recent
97
+ * `[[operations]]` header, and when we see a `name = "<opName>"` line
98
+ * before the next `[[operations]]` or top-level header, return that
99
+ * header's line.
100
+ */
101
+ export function locateOperationLine(rawToml, opName) {
102
+ const lines = rawToml.split(/\r?\n/);
103
+ let lastOpHeader = 0;
104
+ let armed = false;
105
+ for (let i = 0; i < lines.length; i++) {
106
+ const line = lines[i].trim();
107
+ if (line === "[[operations]]") {
108
+ lastOpHeader = i + 1;
109
+ armed = true;
110
+ continue;
111
+ }
112
+ if (!armed)
113
+ continue;
114
+ // Another array-of-tables / top-level table → not this op anymore.
115
+ if (line.startsWith("[[") && line !== "[[operations]]" && !line.startsWith("[[operations.")) {
116
+ armed = false;
117
+ continue;
118
+ }
119
+ if (line.startsWith("[") && !line.startsWith("[[") && !line.startsWith("[operations.")) {
120
+ armed = false;
121
+ continue;
122
+ }
123
+ const m = line.match(/^name\s*=\s*["'](.+)["']\s*$/);
124
+ if (m && m[1] === opName) {
125
+ return lastOpHeader;
126
+ }
127
+ }
128
+ return 0;
129
+ }
130
+ /**
131
+ * Validate `$params` references across every operation in a parsed
132
+ * database-type config.
133
+ *
134
+ * Errors (blocking):
135
+ * - A `$params.X` reference inside `definition` where `X` is not
136
+ * declared in `[[operations.params]]`.
137
+ *
138
+ * Warnings (soft, not blocking):
139
+ * - A param declared in `[[operations.params]]` that is not referenced
140
+ * anywhere in `definition`. Authors may be staging a deprecation.
141
+ */
142
+ export function validateOperations(opts) {
143
+ const errors = [];
144
+ const warnings = [];
145
+ for (const op of opts.operations) {
146
+ if (!op || !op.name)
147
+ continue;
148
+ const declared = declaredParamNames(op.params);
149
+ const refs = new Set(collectParamRefs(op.definition));
150
+ const line = locateOperationLine(opts.rawToml, op.name);
151
+ for (const ref of refs) {
152
+ if (!declared.has(ref)) {
153
+ errors.push({
154
+ file: opts.filePath,
155
+ line,
156
+ op: op.name,
157
+ message: `$params.${ref} not declared in [[operations.params]] for operation '${op.name}'`,
158
+ });
159
+ }
160
+ }
161
+ for (const name of declared) {
162
+ if (!refs.has(name)) {
163
+ warnings.push({
164
+ file: opts.filePath,
165
+ line,
166
+ op: op.name,
167
+ message: `param '${name}' declared but not referenced in operation '${op.name}'`,
168
+ });
169
+ }
170
+ }
171
+ }
172
+ return { errors, warnings };
173
+ }
174
+ /**
175
+ * Format a validation issue as `<file>:<line>: <message>`.
176
+ */
177
+ export function formatIssue(issue) {
178
+ if (issue.line > 0) {
179
+ return `${issue.file}:${issue.line}: ${issue.message}`;
180
+ }
181
+ return `${issue.file}: ${issue.message}`;
182
+ }
183
+ //# sourceMappingURL=toml-params-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toml-params-validator.js","sourceRoot":"","sources":["../../../src/lib/toml-params-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAcH;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAU;IACzC,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAC9C,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;YACzC,IAAI,KAAK;gBAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;SAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;SAAM,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvD,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAW;IAC5C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,IAAI,MAAM,IAAI,IAAI;QAAE,OAAO,KAAK,CAAC;IACjC,IAAI,KAAK,GAAQ,MAAM,CAAC;IACxB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;YACxB,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACnE,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;IACH,CAAC;SAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACvD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACrC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAe,EAAE,MAAc;IACjE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACrC,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;YAC9B,YAAY,GAAG,CAAC,GAAG,CAAC,CAAC;YACrB,KAAK,GAAG,IAAI,CAAC;YACb,SAAS;QACX,CAAC;QACD,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,mEAAmE;QACnE,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,KAAK,gBAAgB,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;YAC5F,KAAK,GAAG,KAAK,CAAC;YACd,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;YACvF,KAAK,GAAG,KAAK,CAAC;YACd,SAAS;QACX,CAAC;QACD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;QACrD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;YACzB,OAAO,YAAY,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAiBD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAqB;IACtD,MAAM,MAAM,GAAsB,EAAE,CAAC;IACrC,MAAM,QAAQ,GAAsB,EAAE,CAAC;IACvC,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACjC,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI;YAAE,SAAS;QAC9B,MAAM,QAAQ,GAAG,kBAAkB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;QACtD,MAAM,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;QAExD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvB,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,IAAI,CAAC,QAAQ;oBACnB,IAAI;oBACJ,EAAE,EAAE,EAAE,CAAC,IAAI;oBACX,OAAO,EAAE,WAAW,GAAG,yDAAyD,EAAE,CAAC,IAAI,GAAG;iBAC3F,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACpB,QAAQ,CAAC,IAAI,CAAC;oBACZ,IAAI,EAAE,IAAI,CAAC,QAAQ;oBACnB,IAAI;oBACJ,EAAE,EAAE,EAAE,CAAC,IAAI;oBACX,OAAO,EAAE,UAAU,IAAI,+CAA+C,EAAE,CAAC,IAAI,GAAG;iBACjF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,KAAsB;IAChD,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACnB,OAAO,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;IACzD,CAAC;IACD,OAAO,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;AAC3C,CAAC"}