@proteinjs/db 1.43.0 → 1.44.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.
Files changed (40) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/generated/index.js +1 -1
  3. package/dist/generated/index.js.map +1 -1
  4. package/dist/generated/test/index.d.ts.map +1 -1
  5. package/dist/generated/test/index.js +3 -1
  6. package/dist/generated/test/index.js.map +1 -1
  7. package/dist/src/Table.d.ts +37 -1
  8. package/dist/src/Table.d.ts.map +1 -1
  9. package/dist/src/Table.js.map +1 -1
  10. package/dist/src/source/SourceRecord.d.ts +2 -3
  11. package/dist/src/source/SourceRecord.d.ts.map +1 -1
  12. package/dist/src/source/SourceRecord.js +16 -2
  13. package/dist/src/source/SourceRecord.js.map +1 -1
  14. package/dist/src/source/SourceRecordLoader.d.ts +12 -0
  15. package/dist/src/source/SourceRecordLoader.d.ts.map +1 -1
  16. package/dist/src/source/SourceRecordLoader.js +72 -50
  17. package/dist/src/source/SourceRecordLoader.js.map +1 -1
  18. package/dist/src/tables/MigrationTable.d.ts +22 -4
  19. package/dist/src/tables/MigrationTable.d.ts.map +1 -1
  20. package/dist/src/tables/MigrationTable.js +38 -16
  21. package/dist/src/tables/MigrationTable.js.map +1 -1
  22. package/dist/test/SourceRecordLoader.test.js +151 -0
  23. package/dist/test/SourceRecordLoader.test.js.map +1 -1
  24. package/dist/test/reusable/SourceRecordSyncTests.d.ts.map +1 -1
  25. package/dist/test/reusable/SourceRecordSyncTests.js +124 -0
  26. package/dist/test/reusable/SourceRecordSyncTests.js.map +1 -1
  27. package/dist/test/util/tables/sourceRecordSyncTestTables.d.ts +17 -0
  28. package/dist/test/util/tables/sourceRecordSyncTestTables.d.ts.map +1 -1
  29. package/dist/test/util/tables/sourceRecordSyncTestTables.js +26 -1
  30. package/dist/test/util/tables/sourceRecordSyncTestTables.js.map +1 -1
  31. package/generated/index.ts +1 -1
  32. package/generated/test/index.ts +3 -1
  33. package/package.json +2 -2
  34. package/src/Table.ts +38 -1
  35. package/src/source/SourceRecord.ts +17 -4
  36. package/src/source/SourceRecordLoader.ts +30 -3
  37. package/src/tables/MigrationTable.ts +43 -16
  38. package/test/SourceRecordLoader.test.ts +90 -0
  39. package/test/reusable/SourceRecordSyncTests.ts +72 -0
  40. package/test/util/tables/sourceRecordSyncTestTables.ts +25 -0
@@ -2,6 +2,14 @@ import { Moment } from '../opt/moment';
2
2
  import { Table } from '../Table';
3
3
  import { SourceRecord } from '../source/SourceRecord';
4
4
  export interface Migration extends SourceRecord {
5
+ /**
6
+ * The declaring loader's class name (`BackfillOnboardingStateForExistingAccounts`) — the
7
+ * ledger's human handle, leading the Migrations table. Derived by the source-record sync from
8
+ * the declaration itself ({@link MigrationTable.sourceRecordOptions} `fromDeclaration`), never
9
+ * typed into a migration's record: existing rows are backfilled by the first boot after this
10
+ * column ships and left alone from then on (a derived field is drift-compared like any other).
11
+ */
12
+ name?: string;
5
13
  description: string;
6
14
  /**
7
15
  * The explicit non-automatable class (plans/POST_RELEASE_QUEUE.md 27f): destructive
@@ -65,12 +73,21 @@ export declare class MigrationTable extends Table<Migration> {
65
73
  */
66
74
  auth: Table<Migration>['auth'];
67
75
  /**
68
- * The row scan the founder actually reads: what ran, how it went, HOW LONG it took
69
- * (duration — stamped by the runner at completion; the default pick's five-column cap
70
- * dropped it), then the declaration flags. Failure detail and timestamps stay on the
71
- * record form.
76
+ * The row scan the founder actually reads (ruled 2026-09-02): WHICH migration (name — the
77
+ * loader's class name), what it does, how the run went, WHEN it ran ("Ran at" = start_time,
78
+ * the one timestamp that answers "when did it land"), how long, when it finished, and a
79
+ * glimpse of its output (the mono JSON snippet; the record form carries the full value).
80
+ * The declaration flags and the failure detail stay on the record form. Most recent run
81
+ * first; never-run rows last — GoogleSQL orders NULL as the least value, so start_time DESC
82
+ * places rows without a run after every real timestamp; ledger order (created) breaks ties.
72
83
  */
73
84
  ui: Table<Migration>['ui'];
85
+ /**
86
+ * Declared in the order the record form reads them (within a section the form keeps schema
87
+ * order): the migration's identity and flags up top (unlabeled), then its Run — status, ran
88
+ * at, duration, end time, the full output, failure message and stack — then the System meta.
89
+ * Column order carries no DDL weight on an existing table.
90
+ */
74
91
  columns: {
75
92
  id: import("../Table").Column<string, any>;
76
93
  created: import("../Table").Column<Moment, any>;
@@ -81,6 +98,7 @@ export declare class MigrationTable extends Table<Migration> {
81
98
  } & {} & {
82
99
  retired: import("../Table").Column<boolean | undefined, any>;
83
100
  status: import("../Table").Column<"proposed" | "running" | "success" | "failure" | undefined, any>;
101
+ name: import("../Table").Column<string | undefined, any>;
84
102
  description: import("../Table").Column<string, any>;
85
103
  manual: import("../Table").Column<boolean | undefined, any>;
86
104
  preSchemaSync: import("../Table").Column<boolean | undefined, any>;
@@ -1 +1 @@
1
- {"version":3,"file":"MigrationTable.d.ts","sourceRoot":"","sources":["../../../src/tables/MigrationTable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,YAAY,EAA2B,MAAM,wBAAwB,CAAC;AAE/E,MAAM,WAAW,SAAU,SAAQ,YAAY;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,GAAG,EAAE,MAAM,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;CAChC;AAED,qBAAa,cAAe,SAAQ,KAAK,CAAC,SAAS,CAAC;IAC3C,IAAI,SAAe;IAC1B;;;;;;;;OAQG;IACI,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAGnC;IACF;;;;;OAKG;IACI,EAAE,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAI/B;IACK,OAAO;;;;;;;;;;;;;;;;;;;;;MAYX;IACI,mBAAmB,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAMjE;CACH"}
1
+ {"version":3,"file":"MigrationTable.d.ts","sourceRoot":"","sources":["../../../src/tables/MigrationTable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,YAAY,EAA2B,MAAM,wBAAwB,CAAC;AAE/E,MAAM,WAAW,SAAU,SAAQ,YAAY;IAC7C;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,GAAG,EAAE,MAAM,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;CAChC;AAED,qBAAa,cAAe,SAAQ,KAAK,CAAC,SAAS,CAAC;IAC3C,IAAI,SAAe;IAC1B;;;;;;;;OAQG;IACI,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAGnC;IACF;;;;;;;;OAQG;IACI,EAAE,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAQ/B;IACF;;;;;OAKG;IACI,OAAO;;;;;;;;;;;;;;;;;;;;;;MAeX;IACI,mBAAmB,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CASjE;CACH"}
@@ -74,34 +74,56 @@ var MigrationTable = /** @class */ (function (_super) {
74
74
  service: { query: { permission: 'dev' }, update: { permission: 'dev' }, delete: { permission: 'dev' } },
75
75
  };
76
76
  /**
77
- * The row scan the founder actually reads: what ran, how it went, HOW LONG it took
78
- * (duration — stamped by the runner at completion; the default pick's five-column cap
79
- * dropped it), then the declaration flags. Failure detail and timestamps stay on the
80
- * record form.
77
+ * The row scan the founder actually reads (ruled 2026-09-02): WHICH migration (name — the
78
+ * loader's class name), what it does, how the run went, WHEN it ran ("Ran at" = start_time,
79
+ * the one timestamp that answers "when did it land"), how long, when it finished, and a
80
+ * glimpse of its output (the mono JSON snippet; the record form carries the full value).
81
+ * The declaration flags and the failure detail stay on the record form. Most recent run
82
+ * first; never-run rows last — GoogleSQL orders NULL as the least value, so start_time DESC
83
+ * places rows without a run after every real timestamp; ledger order (created) breaks ties.
81
84
  */
82
85
  _this.ui = {
83
86
  recordTable: {
84
- columns: ['description', 'status', 'duration', 'manual', 'preSchemaSync', 'retired'],
87
+ columns: ['name', 'description', 'status', 'startTime', 'duration', 'endTime', 'output'],
88
+ sort: [
89
+ { field: 'startTime', desc: true },
90
+ { field: 'created', desc: false },
91
+ ],
85
92
  },
86
93
  };
94
+ /**
95
+ * Declared in the order the record form reads them (within a section the form keeps schema
96
+ * order): the migration's identity and flags up top (unlabeled), then its Run — status, ran
97
+ * at, duration, end time, the full output, failure message and stack — then the System meta.
98
+ * Column order carries no DDL weight on an existing table.
99
+ */
87
100
  _this.columns = (0, SourceRecord_1.withSourceRecordColumns)({
88
- description: new Columns_1.StringColumn('description', {}, 4000),
89
- manual: new Columns_1.BooleanColumn('manual'),
90
- preSchemaSync: new Columns_1.BooleanColumn('pre_schema_sync'),
91
- retired: new Columns_1.BooleanColumn('retired'),
101
+ name: new Columns_1.StringColumn('name'),
102
+ description: new Columns_1.StringColumn('description', { ui: { formGroup: 'identity' } }, 4000),
103
+ manual: new Columns_1.BooleanColumn('manual', { ui: { formGroup: 'identity' } }),
104
+ preSchemaSync: new Columns_1.BooleanColumn('pre_schema_sync', { ui: { formGroup: 'identity' } }),
105
+ retired: new Columns_1.BooleanColumn('retired', { ui: { formGroup: 'identity' } }),
92
106
  status: new Columns_1.StringColumn('status', { defaultValue: function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
93
107
  return [2 /*return*/, 'proposed'];
94
- }); }); } }),
95
- failureMessage: new Columns_1.StringColumn('failure_message', {}, 4000),
96
- failureStack: new Columns_1.StringColumn('failure_stack', {}, 'MAX'),
97
- startTime: new Columns_1.DateTimeColumn('start_time'),
98
- endTime: new Columns_1.DateTimeColumn('end_time'),
99
- duration: new Columns_1.StringColumn('duration'),
100
- output: new Columns_1.ObjectColumn('output'),
108
+ }); }); }, ui: { formGroup: 'run' } }),
109
+ startTime: new Columns_1.DateTimeColumn('start_time', { ui: { label: 'Ran at', formGroup: 'run' } }),
110
+ duration: new Columns_1.StringColumn('duration', { ui: { formGroup: 'run' } }),
111
+ endTime: new Columns_1.DateTimeColumn('end_time', { ui: { formGroup: 'run' } }),
112
+ // Opted visible: an ObjectColumn hides by default, but a run's output is exactly what the
113
+ // ledger is opened to read (snippet on the row, full JSON on the form).
114
+ output: new Columns_1.ObjectColumn('output', { ui: { hidden: false, formGroup: 'run' } }),
115
+ failureMessage: new Columns_1.StringColumn('failure_message', { ui: { formGroup: 'run' } }, 4000),
116
+ failureStack: new Columns_1.StringColumn('failure_stack', { ui: { formGroup: 'run' } }, 'MAX'),
101
117
  });
102
118
  _this.sourceRecordOptions = {
103
119
  // The ledger outlives the migration class: run history stays when the source is deleted.
104
120
  onSourceRemoved: 'keep',
121
+ // The ledger's `name` is the declaring loader's class name — derived from the declaration
122
+ // by the sync (backfilled once onto existing rows), never typed into each migration.
123
+ fromDeclaration: function (_a) {
124
+ var name = _a.name;
125
+ return ({ name: name });
126
+ },
105
127
  ui: {
106
128
  hideColumns: true,
107
129
  },
@@ -1 +1 @@
1
- {"version":3,"file":"MigrationTable.js","sourceRoot":"","sources":["../../../src/tables/MigrationTable.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,sCAAuF;AACvF,kCAAiC;AACjC,uDAA+E;AAsD/E;IAAoC,kCAAgB;IAApD;QAAA,qEA8CC;QA7CQ,UAAI,GAAG,WAAW,CAAC;QAC1B;;;;;;;;WAQG;QACI,UAAI,GAA6B;YACtC,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE;YAClG,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE;SACxG,CAAC;QACF;;;;;WAKG;QACI,QAAE,GAA2B;YAClC,WAAW,EAAE;gBACX,OAAO,EAAE,CAAC,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAE,SAAS,CAAC;aACrF;SACF,CAAC;QACK,aAAO,GAAG,IAAA,sCAAuB,EAAY;YAClD,WAAW,EAAE,IAAI,sBAAY,CAAC,aAAa,EAAE,EAAE,EAAE,IAAI,CAAC;YACtD,MAAM,EAAE,IAAI,uBAAa,CAAC,QAAQ,CAAC;YACnC,aAAa,EAAE,IAAI,uBAAa,CAAC,iBAAiB,CAAC;YACnD,OAAO,EAAE,IAAI,uBAAa,CAAC,SAAS,CAAC;YACrC,MAAM,EAAE,IAAI,sBAAY,CAAC,QAAQ,EAAE,EAAE,YAAY,EAAE;oBAAY,sBAAA,UAAU,EAAA;yBAAA,EAAE,CAAC;YAC5E,cAAc,EAAE,IAAI,sBAAY,CAAC,iBAAiB,EAAE,EAAE,EAAE,IAAI,CAAC;YAC7D,YAAY,EAAE,IAAI,sBAAY,CAAC,eAAe,EAAE,EAAE,EAAE,KAAK,CAAC;YAC1D,SAAS,EAAE,IAAI,wBAAc,CAAC,YAAY,CAAC;YAC3C,OAAO,EAAE,IAAI,wBAAc,CAAC,UAAU,CAAC;YACvC,QAAQ,EAAE,IAAI,sBAAY,CAAC,UAAU,CAAC;YACtC,MAAM,EAAE,IAAI,sBAAY,CAAC,QAAQ,CAAC;SACnC,CAAC,CAAC;QACI,yBAAmB,GAA4C;YACpE,yFAAyF;YACzF,eAAe,EAAE,MAAM;YACvB,EAAE,EAAE;gBACF,WAAW,EAAE,IAAI;aAClB;SACF,CAAC;;IACJ,CAAC;IAAD,qBAAC;AAAD,CAAC,AA9CD,CAAoC,aAAK,GA8CxC;AA9CY,wCAAc"}
1
+ {"version":3,"file":"MigrationTable.js","sourceRoot":"","sources":["../../../src/tables/MigrationTable.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,51 @@
1
1
  "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
2
49
  Object.defineProperty(exports, "__esModule", { value: true });
3
50
  var SourceRecordLoader_1 = require("../src/source/SourceRecordLoader");
4
51
  var internals = function () { return new SourceRecordLoader_1.SourceRecordLoader(); };
@@ -118,4 +165,108 @@ describe('SourceRecordLoader.findMismatchPath', function () {
118
165
  });
119
166
  });
120
167
  });
168
+ /**
169
+ * Stamp hygiene on the real migration-ledger shape: `hasChanges` decides whether a boot
170
+ * rewrites a row (bumping `updated`). The ownership stamps ride the declared record, so the
171
+ * comparison must know which of them mean "the definition changed" and which are bookkeeping.
172
+ */
173
+ describe('SourceRecordLoader.hasChanges — stamp hygiene on the migration ledger', function () {
174
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
175
+ var MigrationTable = require('../src/tables/MigrationTable').MigrationTable;
176
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
177
+ var moment = require('moment');
178
+ var loader = function () { return new SourceRecordLoader_1.SourceRecordLoader(); };
179
+ var table = new MigrationTable();
180
+ /** What a build declares for a migration (the run function rides along, as it does at boot). */
181
+ var declared = function (overrides) {
182
+ if (overrides === void 0) { overrides = {}; }
183
+ return (__assign({ id: 'bee7a15c-369f-4e77-abf7-ccd5dc3ae60c', description: 'Marks every existing account onboarded', run: function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
184
+ return [2 /*return*/, undefined];
185
+ }); }); }, isLoadedFromSource: true, sourcePackage: '@n3xa/app-server', sourcePackageVersion: '1.24.0' }, overrides));
186
+ };
187
+ /** The ledger row a previous release wrote and later ran. */
188
+ var stored = function (overrides) {
189
+ if (overrides === void 0) { overrides = {}; }
190
+ return (__assign({ id: 'bee7a15c-369f-4e77-abf7-ccd5dc3ae60c', description: 'Marks every existing account onboarded', isLoadedFromSource: true, sourcePackage: '@n3xa/app-server', sourcePackageVersion: '1.23.0', status: 'success', startTime: moment('2026-08-30T10:00:00Z'), endTime: moment('2026-08-30T10:00:02Z'), duration: '2 secs', output: { rowsInserted: 12 }, created: moment('2026-08-30T09:00:00Z'), updated: moment('2026-08-30T10:00:02Z') }, overrides));
191
+ };
192
+ it('a newer package version alone is NOT a change — the every-release re-stamp', function () { return __awaiter(void 0, void 0, void 0, function () {
193
+ var _a;
194
+ return __generator(this, function (_b) {
195
+ switch (_b.label) {
196
+ case 0:
197
+ _a = expect;
198
+ return [4 /*yield*/, loader().hasChanges(table, declared(), stored())];
199
+ case 1:
200
+ _a.apply(void 0, [_b.sent()]).toBe(false);
201
+ return [2 /*return*/];
202
+ }
203
+ });
204
+ }); });
205
+ it('a row with no version stamp gets one (once)', function () { return __awaiter(void 0, void 0, void 0, function () {
206
+ var unstamped, _a;
207
+ return __generator(this, function (_b) {
208
+ switch (_b.label) {
209
+ case 0:
210
+ unstamped = stored();
211
+ delete unstamped.sourcePackageVersion;
212
+ _a = expect;
213
+ return [4 /*yield*/, loader().hasChanges(table, declared(), unstamped)];
214
+ case 1:
215
+ _a.apply(void 0, [_b.sent()]).toBe(true);
216
+ return [2 /*return*/];
217
+ }
218
+ });
219
+ }); });
220
+ it('a redefined description is still a change', function () { return __awaiter(void 0, void 0, void 0, function () {
221
+ var _a;
222
+ return __generator(this, function (_b) {
223
+ switch (_b.label) {
224
+ case 0:
225
+ _a = expect;
226
+ return [4 /*yield*/, loader().hasChanges(table, declared({ description: 'Reworded' }), stored())];
227
+ case 1:
228
+ _a.apply(void 0, [_b.sent()]).toBe(true);
229
+ return [2 /*return*/];
230
+ }
231
+ });
232
+ }); });
233
+ it('ledger-owned run state (status, times, output) never reads as drift', function () { return __awaiter(void 0, void 0, void 0, function () {
234
+ var _a;
235
+ return __generator(this, function (_b) {
236
+ switch (_b.label) {
237
+ case 0:
238
+ _a = expect;
239
+ return [4 /*yield*/, loader().hasChanges(table, declared({ sourcePackageVersion: '1.23.0' }), stored())];
240
+ case 1:
241
+ _a.apply(void 0, [_b.sent()]).toBe(false);
242
+ return [2 /*return*/];
243
+ }
244
+ });
245
+ }); });
246
+ });
247
+ describe('getSourceRecordLoaders — declaration identity', function () {
248
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
249
+ var SourceRepository = require('@proteinjs/reflection').SourceRepository;
250
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
251
+ var getSourceRecordLoaders = require('../src/source/SourceRecord').getSourceRecordLoaders;
252
+ var namedObjectCache = function () { return SourceRepository.get().namedObjectCache; };
253
+ afterEach(function () {
254
+ delete namedObjectCache()['@proteinjs/db/SourceRecordLoader'];
255
+ });
256
+ it("carries the declaration's own name (the loader class) beside its package and qualified name", function () {
257
+ namedObjectCache()['@proteinjs/db/SourceRecordLoader'] = [
258
+ {
259
+ qualifiedName: '@n3xa/app-server/BackfillOnboardingStateForExistingAccounts',
260
+ packageName: '@n3xa/app-server',
261
+ object: { table: {}, record: {} },
262
+ },
263
+ ];
264
+ var declaration = getSourceRecordLoaders()[0];
265
+ expect(declaration).toMatchObject({
266
+ source: '@n3xa/app-server',
267
+ qualifiedName: '@n3xa/app-server/BackfillOnboardingStateForExistingAccounts',
268
+ name: 'BackfillOnboardingStateForExistingAccounts',
269
+ });
270
+ });
271
+ });
121
272
  //# sourceMappingURL=SourceRecordLoader.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SourceRecordLoader.test.js","sourceRoot":"","sources":["../../test/SourceRecordLoader.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SourceRecordLoader.test.js","sourceRoot":"","sources":["../../test/SourceRecordLoader.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"SourceRecordSyncTests.d.ts","sourceRoot":"","sources":["../../../test/reusable/SourceRecordSyncTests.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,QAAQ,EAKR,KAAK,EAKN,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,eAAe,CAAC;AAsCtE;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,WACxB,QAAQ,6BACW,gCAAgC,qBACxC,MAAM,GAAG,CAAC,KAAK,QAAQ,IAAI,CAAC,eAyuBhD,CAAC"}
1
+ {"version":3,"file":"SourceRecordSyncTests.d.ts","sourceRoot":"","sources":["../../../test/reusable/SourceRecordSyncTests.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,QAAQ,EAKR,KAAK,EAKN,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,eAAe,CAAC;AAsCtE;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,WACxB,QAAQ,6BACW,gCAAgC,qBACxC,MAAM,GAAG,CAAC,KAAK,QAAQ,IAAI,CAAC,eAizBhD,CAAC"}
@@ -226,6 +226,9 @@ var sourceRecordSyncTests = function (driver, transactionContextFactory, dropTab
226
226
  _a.sent();
227
227
  return [4 /*yield*/, db.delete(sourceRecordSyncTestTables_1.sourceRecordSyncTestTables.InheritedStamp, {})];
228
228
  case 3:
229
+ _a.sent();
230
+ return [4 /*yield*/, db.delete(sourceRecordSyncTestTables_1.sourceRecordSyncTestTables.SyncDerivedName, {})];
231
+ case 4:
229
232
  _a.sent();
230
233
  RecordingMachineAccountWatcher.updates = [];
231
234
  return [2 /*return*/];
@@ -1246,6 +1249,127 @@ var sourceRecordSyncTests = function (driver, transactionContextFactory, dropTab
1246
1249
  });
1247
1250
  }); });
1248
1251
  });
1252
+ describe('stamp hygiene: an unchanged declaration is never rewritten', function () {
1253
+ var versioned = function (displayName) { return ({
1254
+ table: defaultPolicyTable,
1255
+ record: { id: 'v-1', email: 'v1@test.local', displayName: displayName },
1256
+ }); };
1257
+ test('a version bump alone re-stamps nothing: the next release leaves unchanged rows (and their updated stamp) alone', function () { return __awaiter(void 0, void 0, void 0, function () {
1258
+ var db, stamped, summary, idle, redefined, rewritten;
1259
+ return __generator(this, function (_a) {
1260
+ switch (_a.label) {
1261
+ case 0:
1262
+ db = (0, db_1.getDbAsSystem)();
1263
+ return [4 /*yield*/, bootAsSource('@test/pkg-a', [versioned('same')], '1.23.0')];
1264
+ case 1:
1265
+ _a.sent();
1266
+ return [4 /*yield*/, db.get(defaultPolicyTable, { id: 'v-1' })];
1267
+ case 2:
1268
+ stamped = _a.sent();
1269
+ expect(stamped.sourcePackageVersion).toBe('1.23.0');
1270
+ return [4 /*yield*/, bootAsSource('@test/pkg-a', [versioned('same')], '1.24.0')];
1271
+ case 3:
1272
+ summary = _a.sent();
1273
+ expect(summary[defaultPolicyTable.name]).toMatchObject({ updates: 0, unchanged: 1 });
1274
+ return [4 /*yield*/, db.get(defaultPolicyTable, { id: 'v-1' })];
1275
+ case 4:
1276
+ idle = _a.sent();
1277
+ expect(idle.updated.valueOf()).toBe(stamped.updated.valueOf());
1278
+ // The stamp records the version that last WROTE the row's definition.
1279
+ expect(idle.sourcePackageVersion).toBe('1.23.0');
1280
+ return [4 /*yield*/, bootAsSource('@test/pkg-a', [versioned('changed')], '1.24.0')];
1281
+ case 5:
1282
+ redefined = _a.sent();
1283
+ expect(redefined[defaultPolicyTable.name].updates).toBe(1);
1284
+ return [4 /*yield*/, db.get(defaultPolicyTable, { id: 'v-1' })];
1285
+ case 6:
1286
+ rewritten = _a.sent();
1287
+ expect(rewritten).toMatchObject({ displayName: 'changed', sourcePackageVersion: '1.24.0' });
1288
+ return [2 /*return*/];
1289
+ }
1290
+ });
1291
+ }); });
1292
+ test('a row with no version stamp is stamped exactly once', function () { return __awaiter(void 0, void 0, void 0, function () {
1293
+ var db, _a, first, _b, second;
1294
+ return __generator(this, function (_c) {
1295
+ switch (_c.label) {
1296
+ case 0:
1297
+ db = (0, db_1.getDbAsSystem)();
1298
+ // Written before versions existed (or by a build that could not resolve its version).
1299
+ return [4 /*yield*/, bootAsSource('@test/pkg-a', [versioned('same')])];
1300
+ case 1:
1301
+ // Written before versions existed (or by a build that could not resolve its version).
1302
+ _c.sent();
1303
+ _a = expect;
1304
+ return [4 /*yield*/, db.get(defaultPolicyTable, { id: 'v-1' })];
1305
+ case 2:
1306
+ _a.apply(void 0, [(_c.sent()).sourcePackageVersion]).toBeFalsy();
1307
+ return [4 /*yield*/, bootAsSource('@test/pkg-a', [versioned('same')], '2.0.0')];
1308
+ case 3:
1309
+ first = _c.sent();
1310
+ expect(first[defaultPolicyTable.name].updates).toBe(1);
1311
+ _b = expect;
1312
+ return [4 /*yield*/, db.get(defaultPolicyTable, { id: 'v-1' })];
1313
+ case 4:
1314
+ _b.apply(void 0, [(_c.sent()).sourcePackageVersion]).toBe('2.0.0');
1315
+ return [4 /*yield*/, bootAsSource('@test/pkg-a', [versioned('same')], '2.0.0')];
1316
+ case 5:
1317
+ second = _c.sent();
1318
+ expect(second[defaultPolicyTable.name]).toMatchObject({ updates: 0, unchanged: 1 });
1319
+ return [2 /*return*/];
1320
+ }
1321
+ });
1322
+ }); });
1323
+ test('fromDeclaration: derived fields land on insert, backfill existing rows exactly once, and never re-stamp', function () { return __awaiter(void 0, void 0, void 0, function () {
1324
+ var db, derivedTable, declaration, _a, backfill, backfilled, idle, _b, _c;
1325
+ return __generator(this, function (_d) {
1326
+ switch (_d.label) {
1327
+ case 0:
1328
+ db = (0, db_1.getDbAsSystem)();
1329
+ derivedTable = sourceRecordSyncTestTables_1.sourceRecordSyncTestTables.SyncDerivedName;
1330
+ declaration = { table: derivedTable, record: { id: 'd-1', email: 'd1@test.local' } };
1331
+ return [4 /*yield*/, boot([declaration])];
1332
+ case 1:
1333
+ _d.sent();
1334
+ _a = expect;
1335
+ return [4 /*yield*/, db.get(derivedTable, { id: 'd-1' })];
1336
+ case 2:
1337
+ _a.apply(void 0, [_d.sent()]).toMatchObject({ name: 'SeededLoader0' });
1338
+ // A row written before the derived field existed: backfilled ONCE by the next boot…
1339
+ return [4 /*yield*/, db.update(derivedTable, { id: 'd-1', name: null })];
1340
+ case 3:
1341
+ // A row written before the derived field existed: backfilled ONCE by the next boot…
1342
+ _d.sent();
1343
+ return [4 /*yield*/, boot([declaration])];
1344
+ case 4:
1345
+ backfill = _d.sent();
1346
+ expect(backfill[derivedTable.name].updates).toBe(1);
1347
+ return [4 /*yield*/, db.get(derivedTable, { id: 'd-1' })];
1348
+ case 5:
1349
+ backfilled = _d.sent();
1350
+ expect(backfilled.name).toBe('SeededLoader0');
1351
+ return [4 /*yield*/, boot([declaration])];
1352
+ case 6:
1353
+ idle = _d.sent();
1354
+ expect(idle[derivedTable.name]).toMatchObject({ updates: 0, unchanged: 1 });
1355
+ _b = expect;
1356
+ return [4 /*yield*/, db.get(derivedTable, { id: 'd-1' })];
1357
+ case 7:
1358
+ _b.apply(void 0, [(_d.sent()).updated.valueOf()]).toBe(backfilled.updated.valueOf());
1359
+ // The derivation owns the field: a value typed into the record does not survive it.
1360
+ return [4 /*yield*/, boot([{ table: derivedTable, record: { id: 'd-1', email: 'd1@test.local', name: 'typed-by-hand' } }])];
1361
+ case 8:
1362
+ // The derivation owns the field: a value typed into the record does not survive it.
1363
+ _d.sent();
1364
+ _c = expect;
1365
+ return [4 /*yield*/, db.get(derivedTable, { id: 'd-1' })];
1366
+ case 9:
1367
+ _c.apply(void 0, [(_d.sent()).name]).toBe('SeededLoader0');
1368
+ return [2 /*return*/];
1369
+ }
1370
+ });
1371
+ }); });
1372
+ });
1249
1373
  test('a natural key without a unique guarantee fails boot loudly', function () { return __awaiter(void 0, void 0, void 0, function () {
1250
1374
  var MisdeclaredNaturalKeyTable;
1251
1375
  return __generator(this, function (_a) {