deepline 0.3.97 → 0.3.99

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 (36) hide show
  1. package/dist/bundling-sources/sdk/src/client.ts +152 -5
  2. package/dist/bundling-sources/sdk/src/index.ts +17 -4
  3. package/dist/bundling-sources/sdk/src/monitor-fleets.ts +1 -0
  4. package/dist/bundling-sources/sdk/src/monitor-input-contract.ts +1 -0
  5. package/dist/bundling-sources/sdk/src/monitors.ts +8 -25
  6. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  7. package/dist/bundling-sources/shared_libs/integration-contracts/index.ts +1 -0
  8. package/dist/bundling-sources/shared_libs/integration-contracts/monitor-fleet-contract.ts +218 -16
  9. package/dist/bundling-sources/shared_libs/integration-contracts/monitor-input-contract.ts +455 -0
  10. package/dist/bundling-sources/shared_libs/monitors/fleets/plan.ts +6 -1
  11. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +2 -1
  12. package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +12 -0
  13. package/dist/bundling-sources/shared_libs/observability/scheduled-work-manual.ts +1 -0
  14. package/dist/bundling-sources/shared_libs/play-runtime/internal-bootstrap-token.ts +19 -3
  15. package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +5 -1
  16. package/dist/cli/index.js +1030 -295
  17. package/dist/cli/index.mjs +1038 -303
  18. package/dist/index.d.mts +48 -25
  19. package/dist/index.d.ts +48 -25
  20. package/dist/index.js +606 -42
  21. package/dist/index.mjs +602 -42
  22. package/dist/install-integrity.json +6 -0
  23. package/dist/monitor-fleet-contract.d.mts +44 -8
  24. package/dist/monitor-fleet-contract.d.ts +44 -8
  25. package/dist/monitor-fleet-contract.js +354 -27
  26. package/dist/monitor-fleet-contract.mjs +343 -27
  27. package/dist/monitor-input-contract.d.mts +33 -0
  28. package/dist/monitor-input-contract.d.ts +33 -0
  29. package/dist/monitor-input-contract.js +392 -0
  30. package/dist/monitor-input-contract.mjs +353 -0
  31. package/dist/plays/bundle-play-file.mjs +1 -1
  32. package/dist/release.d.mts +1 -1
  33. package/dist/release.d.ts +1 -1
  34. package/dist/release.js +1 -1
  35. package/dist/release.mjs +1 -1
  36. package/package.json +7 -1
@@ -1,14 +1,207 @@
1
+ // ../integration-contracts/monitor-input-contract.ts
2
+ import Handlebars from "handlebars";
3
+ function authoredMonitorFieldPath(path, field) {
4
+ const batch = /^monitors\.(\d+)$/.exec(path);
5
+ return `${batch ? `monitors[${batch[1]}]` : path}.${field}`;
6
+ }
7
+ function record(value) {
8
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
9
+ }
10
+ function json(value, path, issues) {
11
+ if (value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) {
12
+ return;
13
+ }
14
+ if (Array.isArray(value)) {
15
+ value.forEach((child, index) => json(child, `${path}.${index}`, issues));
16
+ return;
17
+ }
18
+ const object = record(value);
19
+ if (!object) {
20
+ issues.push({
21
+ severity: "error",
22
+ code: "invalid_monitor_json_value",
23
+ path,
24
+ message: "Monitor values must be JSON values."
25
+ });
26
+ return;
27
+ }
28
+ for (const [key, child] of Object.entries(object)) {
29
+ json(child, `${path}.${key}`, issues);
30
+ }
31
+ }
32
+ function monitorSpec(value, path, issues) {
33
+ const input = record(value);
34
+ if (!input) {
35
+ issues.push({
36
+ severity: "error",
37
+ code: "invalid_monitor_spec",
38
+ path,
39
+ message: "A monitor must be a JSON object."
40
+ });
41
+ return null;
42
+ }
43
+ const allowed = /* @__PURE__ */ new Set(["key", "tool", "name", "payload"]);
44
+ for (const key2 of Object.keys(input)) {
45
+ if (!allowed.has(key2)) {
46
+ if (key2 === "controls") {
47
+ issues.push({
48
+ severity: "error",
49
+ code: "CONTROLS_NOT_SUPPORTED",
50
+ path: authoredMonitorFieldPath(path, "controls"),
51
+ message: "Operational controls are managed by Deepline and cannot be authored in Batch or Fleet JSON.",
52
+ suggestion: "Remove controls. Bind downstream automation in a Play with sqlListeners."
53
+ });
54
+ continue;
55
+ }
56
+ if (key2 === "play") {
57
+ issues.push({
58
+ severity: "error",
59
+ code: "PLAY_BINDING_NOT_IN_MONITOR_SPEC",
60
+ path: authoredMonitorFieldPath(path, "play"),
61
+ message: "A monitor does not own Play bindings.",
62
+ suggestion: "Declare sqlListeners in the Play, or run: deepline plays bootstrap monitor-triggered --out on-event.play.ts"
63
+ });
64
+ continue;
65
+ }
66
+ issues.push({
67
+ severity: "error",
68
+ code: "unknown_monitor_field",
69
+ path: `${path}.${key2}`,
70
+ message: `Monitor definitions do not accept '${key2}'.`
71
+ });
72
+ }
73
+ }
74
+ const key = typeof input.key === "string" ? input.key.trim() : "";
75
+ const tool = typeof input.tool === "string" ? input.tool.trim() : "";
76
+ const name = input.name === void 0 ? void 0 : typeof input.name === "string" && input.name.trim() ? input.name.trim() : null;
77
+ const payload = record(input.payload);
78
+ if (!key) {
79
+ issues.push({
80
+ severity: "error",
81
+ code: "invalid_monitor_key",
82
+ path: `${path}.key`,
83
+ message: "Monitor key must be a non-empty string."
84
+ });
85
+ }
86
+ if (!tool) {
87
+ issues.push({
88
+ severity: "error",
89
+ code: "invalid_monitor_tool",
90
+ path: `${path}.tool`,
91
+ message: "Monitor tool must be a non-empty literal string."
92
+ });
93
+ }
94
+ if (name === null) {
95
+ issues.push({
96
+ severity: "error",
97
+ code: "invalid_monitor_name",
98
+ path: `${path}.name`,
99
+ message: "Monitor name must be a non-empty string when supplied."
100
+ });
101
+ }
102
+ if (!payload) {
103
+ issues.push({
104
+ severity: "error",
105
+ code: "invalid_monitor_payload",
106
+ path: `${path}.payload`,
107
+ message: "Monitor payload must be an object."
108
+ });
109
+ } else {
110
+ json(payload, `${path}.payload`, issues);
111
+ }
112
+ if (!key || !tool || !payload || name === null) {
113
+ return null;
114
+ }
115
+ return {
116
+ key,
117
+ tool,
118
+ ...name ? { name } : {},
119
+ payload
120
+ };
121
+ }
122
+ function issueOrder(left, right) {
123
+ return left.path.localeCompare(right.path) || left.severity.localeCompare(right.severity) || left.code.localeCompare(right.code);
124
+ }
125
+ function validateHandlebars(value, path, issues) {
126
+ if (!value.includes("{{")) return;
127
+ try {
128
+ Handlebars.parse(value);
129
+ } catch (error) {
130
+ issues.push({
131
+ severity: "error",
132
+ code: "invalid_handlebars_template",
133
+ path,
134
+ message: error instanceof Error ? error.message : "Invalid Handlebars template."
135
+ });
136
+ return;
137
+ }
138
+ const expressions = value.match(/{{[\s\S]*?}}/g) ?? [];
139
+ if (expressions.some(
140
+ (expression) => !/^{{\s*[A-Za-z_][A-Za-z0-9_]*\s*}}$/.test(expression)
141
+ )) {
142
+ issues.push({
143
+ severity: "error",
144
+ code: "unsupported_handlebars_expression",
145
+ path,
146
+ message: "Fleet templates allow only direct source-row fields such as {{domain}}; helpers, blocks, partials, paths, and prototype access are disabled."
147
+ });
148
+ }
149
+ }
150
+ function walkTemplates(value, path, issues) {
151
+ if (typeof value === "string") return validateHandlebars(value, path, issues);
152
+ if (Array.isArray(value)) {
153
+ value.forEach(
154
+ (item, index) => walkTemplates(item, `${path}.${index}`, issues)
155
+ );
156
+ return;
157
+ }
158
+ const input = record(value);
159
+ if (!input) return;
160
+ for (const [key, child] of Object.entries(input)) {
161
+ walkTemplates(child, `${path}.${key}`, issues);
162
+ }
163
+ }
164
+ function lintMonitorSpecTemplate(value, path = "monitor") {
165
+ const issues = [];
166
+ const normalized = monitorSpec(value, path, issues);
167
+ const input = record(value);
168
+ if (input && typeof input.tool === "string" && input.tool.includes("{{")) {
169
+ issues.push({
170
+ severity: "error",
171
+ code: "templated_monitor_tool",
172
+ path: `${path}.tool`,
173
+ message: "Fleet monitor tool must be literal; only key, name, and payload may be templated."
174
+ });
175
+ }
176
+ if (input) {
177
+ for (const field of ["key", "name", "payload"]) {
178
+ if (input[field] !== void 0)
179
+ walkTemplates(input[field], `${path}.${field}`, issues);
180
+ }
181
+ }
182
+ const ordered = issues.sort(issueOrder);
183
+ return ordered.some((issue) => issue.severity === "error") ? { issues: ordered } : { normalized, issues: ordered };
184
+ }
185
+
1
186
  // ../integration-contracts/monitor-fleet-contract.ts
2
187
  var MONITOR_FLEET_MAX_MEMBERS = 1e3;
3
188
  var MONITOR_FLEET_FRONTIER_MAX_ROWS = 1e4;
4
- var MONITOR_FLEET_AUTHORING_CONTRACT_EDITION = 1;
189
+ var MONITOR_FLEET_AUTHORING_CONTRACT_EDITION = 2;
5
190
  var SUPPORTED_MONITOR_FLEET_AUTHORING_CONTRACT_EDITIONS = [
6
- MONITOR_FLEET_AUTHORING_CONTRACT_EDITION
191
+ 1,
192
+ 2
7
193
  ];
8
194
  var MONITOR_FLEET_AUTHORING_CONTRACT_CHANGELOG = [
9
195
  {
10
196
  edition: 1,
11
- changed: "Initial Fleet JSON contract: bounded sticky table membership, one daily sync, and a seven-day removal grace.",
197
+ changed: "Initial Fleet JSON contract: bounded sticky table membership, source refresh, and a seven-day removal grace.",
198
+ compatibilityOwner: "Monitors Runtime",
199
+ newWritesEnd: null,
200
+ readerRemoval: null
201
+ },
202
+ {
203
+ edition: 2,
204
+ changed: "Canonical table-backed Fleet envelope with one Handlebars MonitorSpec template.",
12
205
  compatibilityOwner: "Monitors Runtime",
13
206
  newWritesEnd: null,
14
207
  readerRemoval: null
@@ -20,11 +213,11 @@ var MONITOR_FLEET_DOCUMENTATION = {
20
213
  authoredFields: {
21
214
  id: "Stable lowercase fleet id used by sync, get, and deactivate.",
22
215
  source: "Customer DB table, unique row key, and optional equality filters that select candidate rows.",
23
- member: "Ordinary monitor tool, stable key template, and payload evaluated for each selected source row.",
216
+ monitor: "One Batch-compatible MonitorSpec. Direct Handlebars source-row fields such as {{domain}} are rendered for each selected row.",
24
217
  selection: "Deterministic ranking and an active-member limit between 1 and 1,000."
25
218
  },
26
219
  fixedPolicy: {
27
- cadence: "daily",
220
+ cadence: "60s fair bounded source refresh",
28
221
  membership: "sticky",
29
222
  removalGrace: "7d",
30
223
  onRemoved: "deactivate",
@@ -32,9 +225,10 @@ var MONITOR_FLEET_DOCUMENTATION = {
32
225
  billing: "No Fleet fee, permit, or renewal. Dry-run reports ordinary monitor lifecycle charges due now."
33
226
  },
34
227
  stickyMembership: "Ranking fills vacancies but never replaces a current member merely because another row ranks higher.",
35
- columnExpression: 'Use { "$fleet": "column", "name": "column_name" } in a member key or payload to read a value from each source row.'
228
+ templating: "Use direct Handlebars fields such as {{domain}} in monitor key, name, or payload. Helpers, blocks, partials, paths, and prototype access are disabled.",
229
+ legacyCompatibility: 'Edition 1 member/$fleet files remain readable with a lint warning; new files should use version: 2, kind: "fleet", and monitor.'
36
230
  };
37
- function record(value) {
231
+ function record2(value) {
38
232
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
39
233
  }
40
234
  function identifier(value) {
@@ -59,7 +253,7 @@ function jsonValue(value, path, issues) {
59
253
  value.forEach((item, index) => jsonValue(item, `${path}.${index}`, issues));
60
254
  return;
61
255
  }
62
- const input = record(value);
256
+ const input = record2(value);
63
257
  if (!input) {
64
258
  issues.push({
65
259
  path,
@@ -85,7 +279,7 @@ function defineMonitorFleet(definition) {
85
279
  return definition;
86
280
  }
87
281
  function validateExpression(value, path, issues) {
88
- const input = record(value);
282
+ const input = record2(value);
89
283
  if (!input || input.$fleet !== "column" || !identifier(input.name)) {
90
284
  issues.push({
91
285
  path,
@@ -103,7 +297,7 @@ function walkPayload(value, path, issues) {
103
297
  );
104
298
  return;
105
299
  }
106
- const input = record(value);
300
+ const input = record2(value);
107
301
  if (!input) return;
108
302
  if ("$fleet" in input) {
109
303
  validateExpression(input, path, issues);
@@ -113,9 +307,9 @@ function walkPayload(value, path, issues) {
113
307
  walkPayload(item, `${path}.${key}`, issues);
114
308
  }
115
309
  }
116
- function validateMonitorFleetDefinition(value) {
310
+ function validateMonitorFleetDefinitionV1(value) {
117
311
  const issues = [];
118
- const input = record(value);
312
+ const input = record2(value);
119
313
  if (!input) {
120
314
  return {
121
315
  valid: false,
@@ -136,7 +330,7 @@ function validateMonitorFleetDefinition(value) {
136
330
  message: "Fleet id must be lowercase kebab-case."
137
331
  });
138
332
  }
139
- const source = record(input.source);
333
+ const source = record2(input.source);
140
334
  exactKeys(
141
335
  source,
142
336
  ["kind", "schema", "table", "key", "where"],
@@ -157,7 +351,7 @@ function validateMonitorFleetDefinition(value) {
157
351
  message: "Source schema and table must be SQL identifiers."
158
352
  });
159
353
  }
160
- const sourceKey = record(source?.key);
354
+ const sourceKey = record2(source?.key);
161
355
  exactKeys(sourceKey, ["column", "type"], "source.key", issues);
162
356
  if (!sourceKey || !identifier(sourceKey.column) || !["text", "uuid", "int4", "int8"].includes(String(sourceKey.type))) {
163
357
  issues.push({
@@ -167,7 +361,7 @@ function validateMonitorFleetDefinition(value) {
167
361
  });
168
362
  }
169
363
  if (source?.where !== void 0) {
170
- const where = record(source.where);
364
+ const where = record2(source.where);
171
365
  if (!where) {
172
366
  issues.push({
173
367
  path: "source.where",
@@ -193,9 +387,9 @@ function validateMonitorFleetDefinition(value) {
193
387
  }
194
388
  }
195
389
  }
196
- const member = record(input.member);
390
+ const member = record2(input.member);
197
391
  exactKeys(member, ["tool", "key", "payload"], "member", issues);
198
- const key = record(member?.key);
392
+ const key = record2(member?.key);
199
393
  if (!member || typeof member.tool !== "string" || !member.tool.trim()) {
200
394
  issues.push({
201
395
  path: "member.tool",
@@ -216,7 +410,7 @@ function validateMonitorFleetDefinition(value) {
216
410
  validateExpression(part, `member.key.parts.${index}`, issues);
217
411
  }
218
412
  if (sourceKey && !key.parts.some(
219
- (part) => record(part)?.$fleet === "column" && record(part)?.name === sourceKey.column
413
+ (part) => record2(part)?.$fleet === "column" && record2(part)?.name === sourceKey.column
220
414
  )) {
221
415
  issues.push({
222
416
  path: "member.key.parts",
@@ -235,7 +429,7 @@ function validateMonitorFleetDefinition(value) {
235
429
  jsonValue(member.payload, "member.payload", issues);
236
430
  }
237
431
  walkPayload(member?.payload, "member.payload", issues);
238
- const selection = record(input.selection);
432
+ const selection = record2(input.selection);
239
433
  exactKeys(selection, ["limit", "orderBy", "membership"], "selection", issues);
240
434
  if (!selection || !Number.isSafeInteger(selection.limit) || Number(selection.limit) < 1 || Number(selection.limit) > MONITOR_FLEET_MAX_MEMBERS) {
241
435
  issues.push({
@@ -261,7 +455,7 @@ function validateMonitorFleetDefinition(value) {
261
455
  } else {
262
456
  const orderColumns = /* @__PURE__ */ new Set();
263
457
  for (const [index, order] of orderBy.entries()) {
264
- const item = record(order);
458
+ const item = record2(order);
265
459
  exactKeys(
266
460
  item,
267
461
  ["column", "direction"],
@@ -284,7 +478,7 @@ function validateMonitorFleetDefinition(value) {
284
478
  orderColumns.add(item.column);
285
479
  }
286
480
  }
287
- if (sourceKey && record(orderBy.at(-1))?.column !== sourceKey.column) {
481
+ if (sourceKey && record2(orderBy.at(-1))?.column !== sourceKey.column) {
288
482
  issues.push({
289
483
  path: "selection.orderBy",
290
484
  code: "fleet_order_missing_key",
@@ -303,9 +497,104 @@ function validateMonitorFleetDefinition(value) {
303
497
  }
304
498
  return issues.length === 0 ? { valid: true, definition: value, issues } : { valid: false, issues };
305
499
  }
306
- function admitMonitorFleetAuthoringContract(value, edition = MONITOR_FLEET_AUTHORING_CONTRACT_EDITION) {
500
+ function v2Issue(issue) {
501
+ return { path: issue.path, code: issue.code, message: issue.message };
502
+ }
503
+ function validateMonitorFleetDefinitionV2(value) {
504
+ const issues = [];
505
+ const input = record2(value);
506
+ if (!input) {
507
+ return {
508
+ valid: false,
509
+ issues: [
510
+ {
511
+ path: "",
512
+ code: "invalid_fleet",
513
+ message: "Fleet must be an object."
514
+ }
515
+ ]
516
+ };
517
+ }
518
+ exactKeys(
519
+ input,
520
+ ["version", "kind", "id", "source", "monitor", "selection"],
521
+ "",
522
+ issues
523
+ );
524
+ if (input.version !== 2) {
525
+ issues.push({
526
+ path: "version",
527
+ code: "unsupported_fleet_version",
528
+ message: "Canonical Fleet input version must be 2."
529
+ });
530
+ }
531
+ if (input.kind !== "fleet") {
532
+ issues.push({
533
+ path: "kind",
534
+ code: "invalid_fleet_kind",
535
+ message: 'Canonical Fleet input kind must be "fleet".'
536
+ });
537
+ }
538
+ const source = record2(input.source);
539
+ const sourceKey = record2(source?.key);
540
+ const legacyShape = {
541
+ id: input.id,
542
+ source: input.source,
543
+ member: {
544
+ tool: record2(input.monitor)?.tool,
545
+ key: {
546
+ $fleet: "template",
547
+ parts: [
548
+ "fleet-",
549
+ {
550
+ $fleet: "column",
551
+ name: typeof sourceKey?.column === "string" ? sourceKey.column : "invalid_source_key"
552
+ }
553
+ ]
554
+ },
555
+ payload: record2(input.monitor)?.payload
556
+ },
557
+ selection: input.selection
558
+ };
559
+ const legacyCheck = validateMonitorFleetDefinitionV1(legacyShape);
560
+ for (const issue of legacyCheck.issues) {
561
+ issues.push({
562
+ ...issue,
563
+ path: issue.path.replace(/^member\./, "monitor.")
564
+ });
565
+ }
566
+ const monitorInput = record2(input.monitor);
567
+ const monitorKey = monitorInput?.key;
568
+ const monitor = lintMonitorSpecTemplate(input.monitor);
569
+ issues.push(...monitor.issues.map(v2Issue));
570
+ if (typeof monitorKey === "string" && typeof sourceKey?.column === "string" && !monitorKey.includes(`{{${sourceKey.column}}}`)) {
571
+ issues.push({
572
+ path: "monitor.key",
573
+ code: "fleet_key_missing_source_key",
574
+ message: "Monitor key must include the source key as a direct Handlebars expression."
575
+ });
576
+ }
577
+ return issues.length === 0 && monitor.normalized ? {
578
+ valid: true,
579
+ definition: {
580
+ version: 2,
581
+ kind: "fleet",
582
+ id: String(input.id),
583
+ source: input.source,
584
+ monitor: monitor.normalized,
585
+ selection: input.selection
586
+ },
587
+ issues
588
+ } : { valid: false, issues };
589
+ }
590
+ function validateMonitorFleetDefinition(value) {
591
+ const input = record2(value);
592
+ return input?.version === 2 || input?.kind === "fleet" ? validateMonitorFleetDefinitionV2(value) : validateMonitorFleetDefinitionV1(value);
593
+ }
594
+ function admitMonitorFleetAuthoringContract(value, edition) {
595
+ const detectedEdition = edition ?? (record2(value)?.version === 2 || record2(value)?.kind === "fleet" ? 2 : 1);
307
596
  if (!SUPPORTED_MONITOR_FLEET_AUTHORING_CONTRACT_EDITIONS.includes(
308
- edition
597
+ detectedEdition
309
598
  )) {
310
599
  return {
311
600
  valid: false,
@@ -313,16 +602,16 @@ function admitMonitorFleetAuthoringContract(value, edition = MONITOR_FLEET_AUTHO
313
602
  {
314
603
  path: "authoring_contract_edition",
315
604
  code: "unsupported_fleet_authoring_contract_edition",
316
- message: `Monitor Fleet authoring contract edition ${edition} is not supported.`
605
+ message: `Monitor Fleet authoring contract edition ${detectedEdition} is not supported.`
317
606
  }
318
607
  ]
319
608
  };
320
609
  }
321
- const result = validateMonitorFleetDefinition(value);
610
+ const result = detectedEdition === 2 ? validateMonitorFleetDefinitionV2(value) : validateMonitorFleetDefinitionV1(value);
322
611
  return result.valid && result.definition ? {
323
612
  valid: true,
324
613
  contract: {
325
- edition,
614
+ edition: detectedEdition,
326
615
  // JSON cloning prevents later caller mutation from changing the
327
616
  // admitted snapshot.
328
617
  definition: JSON.parse(
@@ -332,10 +621,36 @@ function admitMonitorFleetAuthoringContract(value, edition = MONITOR_FLEET_AUTHO
332
621
  issues: []
333
622
  } : { valid: false, issues: result.issues };
334
623
  }
624
+ function lintMonitorFleetInput(value) {
625
+ const input = record2(value);
626
+ const legacy = input?.member !== void 0;
627
+ const admitted = admitMonitorFleetAuthoringContract(value);
628
+ const issues = admitted.issues.map((issue) => ({
629
+ ...issue,
630
+ severity: "error"
631
+ }));
632
+ if (legacy) {
633
+ issues.push({
634
+ severity: "warning",
635
+ code: "deprecated_fleet_member",
636
+ path: "member",
637
+ message: "Legacy Fleet member syntax remains supported."
638
+ });
639
+ if (JSON.stringify(input).includes('"$fleet"')) {
640
+ issues.push({
641
+ severity: "warning",
642
+ code: "deprecated_fleet_expression",
643
+ path: "member",
644
+ message: "Legacy $fleet expressions remain supported; use direct Handlebars fields in monitor instead."
645
+ });
646
+ }
647
+ }
648
+ return admitted.valid && admitted.contract ? { normalized: admitted.contract.definition, issues } : { issues };
649
+ }
335
650
  function evaluateMonitorFleetValue(value, row) {
336
651
  if (Array.isArray(value))
337
652
  return value.map((item) => evaluateMonitorFleetValue(item, row));
338
- const input = record(value);
653
+ const input = record2(value);
339
654
  if (!input) return value;
340
655
  if (input.$fleet === "column") return row[String(input.name)];
341
656
  if (input.$fleet === "template" && Array.isArray(input.parts)) {
@@ -363,5 +678,6 @@ export {
363
678
  evaluateMonitorFleetValue,
364
679
  fleetColumn,
365
680
  fleetKey,
681
+ lintMonitorFleetInput,
366
682
  validateMonitorFleetDefinition
367
683
  };
@@ -0,0 +1,33 @@
1
+ /// <reference path="./text-imports.d.ts" />
2
+ type MonitorInputIssue = {
3
+ severity: 'error' | 'warning' | 'info';
4
+ code: string;
5
+ path: string;
6
+ message: string;
7
+ suggestion?: string;
8
+ };
9
+ type MonitorSpec = {
10
+ key: string;
11
+ tool: string;
12
+ name?: string;
13
+ payload: Record<string, unknown>;
14
+ };
15
+ type BatchMonitorInput = {
16
+ version: 1;
17
+ kind: 'batch';
18
+ monitors: MonitorSpec[];
19
+ };
20
+ declare function lintMonitorBatchInput(value: unknown): {
21
+ normalized?: BatchMonitorInput;
22
+ issues: MonitorInputIssue[];
23
+ };
24
+ declare function lintMonitorSpecTemplate(value: unknown, path?: string): {
25
+ normalized?: MonitorSpec;
26
+ issues: MonitorInputIssue[];
27
+ };
28
+ declare function renderMonitorSpecTemplate(template: MonitorSpec, row: Record<string, unknown>): {
29
+ spec?: MonitorSpec;
30
+ issues: MonitorInputIssue[];
31
+ };
32
+
33
+ export { type BatchMonitorInput, type MonitorInputIssue, type MonitorSpec, lintMonitorBatchInput, lintMonitorSpecTemplate, renderMonitorSpecTemplate };
@@ -0,0 +1,33 @@
1
+ /// <reference path="./text-imports.d.ts" />
2
+ type MonitorInputIssue = {
3
+ severity: 'error' | 'warning' | 'info';
4
+ code: string;
5
+ path: string;
6
+ message: string;
7
+ suggestion?: string;
8
+ };
9
+ type MonitorSpec = {
10
+ key: string;
11
+ tool: string;
12
+ name?: string;
13
+ payload: Record<string, unknown>;
14
+ };
15
+ type BatchMonitorInput = {
16
+ version: 1;
17
+ kind: 'batch';
18
+ monitors: MonitorSpec[];
19
+ };
20
+ declare function lintMonitorBatchInput(value: unknown): {
21
+ normalized?: BatchMonitorInput;
22
+ issues: MonitorInputIssue[];
23
+ };
24
+ declare function lintMonitorSpecTemplate(value: unknown, path?: string): {
25
+ normalized?: MonitorSpec;
26
+ issues: MonitorInputIssue[];
27
+ };
28
+ declare function renderMonitorSpecTemplate(template: MonitorSpec, row: Record<string, unknown>): {
29
+ spec?: MonitorSpec;
30
+ issues: MonitorInputIssue[];
31
+ };
32
+
33
+ export { type BatchMonitorInput, type MonitorInputIssue, type MonitorSpec, lintMonitorBatchInput, lintMonitorSpecTemplate, renderMonitorSpecTemplate };