@aerokit/sdk 14.54.0 → 14.55.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aerokit/sdk",
3
- "version": "14.54.0",
3
+ "version": "14.55.0",
4
4
  "description": "Unified TypeScript SDK for modern cloud platforms.",
5
5
  "scripts": {
6
6
  "clean": "rm -rf dist",
@@ -51,18 +51,39 @@ export function sampleRecord(entity) {
51
51
  for (const set of entity.exactlyOne ?? []) {
52
52
  for (const name of set.slice(1)) delete record[name];
53
53
  }
54
- // a compare check relates two of the record's own fields, and the sample values above are
55
- // per-type constants - so two dates come out EQUAL and a strict comparison (gt/lt/ne) would be
56
- // rejected with 400. Derive the left operand from the right, by the smallest step that satisfies
57
- // the declared operator (equality satisfies ge/le/eq).
54
+ // a compare check relates the record's own field to a second value - another of its fields, or a
55
+ // literal - and the sample values above are per-type constants, so two dates come out EQUAL and a
56
+ // strict comparison (gt/lt/ne) would be rejected with 400, just as a sample quantity of 7 fails a
57
+ // `le 5`. Derive the left operand from whichever right-hand side the check names, by the smallest
58
+ // step that satisfies the declared operator (equality satisfies ge/le/eq).
58
59
  for (const check of entity.compare ?? []) {
59
- if (!(check.field in record) || record[check.than] == null) continue;
60
+ if (!(check.field in record)) continue;
60
61
  const type = (entity.fields ?? []).find((f) => f.name === check.field)?.type;
61
- record[check.field] = shifted(record[check.than], type, STEPS[check.op] ?? 0);
62
+ const right = 'than' in check ? record[check.than] : literalValue(check.value, type);
63
+ if (right == null) continue;
64
+ record[check.field] = shifted(right, type, STEPS[check.op] ?? 0);
62
65
  }
63
66
  return record;
64
67
  }
65
68
 
69
+ // The right-hand side of a compare check declared as a literal. A moment (CURRENT_DATE /
70
+ // CURRENT_TIMESTAMP / NOW) resolves against the runner's own clock, in the field's shape; a moment
71
+ // carrying an offset is left alone - the sample record keeps its constant and the check is simply
72
+ // not steered, which is safe for the ge/le/eq that a stale sample still satisfies.
73
+ function literalValue(value, type) {
74
+ if (typeof value !== 'string') return value;
75
+ const now = new Date();
76
+ switch (value.trim()) {
77
+ case 'CURRENT_DATE':
78
+ return type === 'date' ? now.toISOString().slice(0, 10) : now.toISOString().replace(/\.\d{3}Z$/, 'Z');
79
+ case 'CURRENT_TIMESTAMP':
80
+ case 'NOW':
81
+ return now.toISOString().replace(/\.\d{3}Z$/, 'Z');
82
+ default:
83
+ return /^(CURRENT_DATE|CURRENT_TIMESTAMP|NOW)[+-]/.test(value.trim()) ? null : value;
84
+ }
85
+ }
86
+
66
87
  // How far the left operand of a compare check has to move off the right one to satisfy it.
67
88
  const STEPS = { ge: 0, le: 0, eq: 0, gt: 1, ne: 1, lt: -1 };
68
89