@proteinjs/db 1.43.0 → 1.45.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/CHANGELOG.md +22 -0
- package/dist/generated/index.js +1 -1
- package/dist/generated/index.js.map +1 -1
- package/dist/generated/test/index.d.ts.map +1 -1
- package/dist/generated/test/index.js +3 -1
- package/dist/generated/test/index.js.map +1 -1
- package/dist/src/Table.d.ts +37 -1
- package/dist/src/Table.d.ts.map +1 -1
- package/dist/src/Table.js.map +1 -1
- package/dist/src/auth/TableAuth.d.ts +11 -1
- package/dist/src/auth/TableAuth.d.ts.map +1 -1
- package/dist/src/auth/TableAuth.js +39 -13
- package/dist/src/auth/TableAuth.js.map +1 -1
- package/dist/src/source/SourceRecord.d.ts +2 -3
- package/dist/src/source/SourceRecord.d.ts.map +1 -1
- package/dist/src/source/SourceRecord.js +16 -2
- package/dist/src/source/SourceRecord.js.map +1 -1
- package/dist/src/source/SourceRecordLoader.d.ts +12 -0
- package/dist/src/source/SourceRecordLoader.d.ts.map +1 -1
- package/dist/src/source/SourceRecordLoader.js +72 -50
- package/dist/src/source/SourceRecordLoader.js.map +1 -1
- package/dist/src/tables/MigrationTable.d.ts +22 -4
- package/dist/src/tables/MigrationTable.d.ts.map +1 -1
- package/dist/src/tables/MigrationTable.js +38 -16
- package/dist/src/tables/MigrationTable.js.map +1 -1
- package/dist/test/SourceRecordLoader.test.js +151 -0
- package/dist/test/SourceRecordLoader.test.js.map +1 -1
- package/dist/test/TableAuthIdentity.test.d.ts +2 -0
- package/dist/test/TableAuthIdentity.test.d.ts.map +1 -0
- package/dist/test/TableAuthIdentity.test.js +110 -0
- package/dist/test/TableAuthIdentity.test.js.map +1 -0
- package/dist/test/reusable/SourceRecordSyncTests.d.ts.map +1 -1
- package/dist/test/reusable/SourceRecordSyncTests.js +124 -0
- package/dist/test/reusable/SourceRecordSyncTests.js.map +1 -1
- package/dist/test/util/tables/sourceRecordSyncTestTables.d.ts +17 -0
- package/dist/test/util/tables/sourceRecordSyncTestTables.d.ts.map +1 -1
- package/dist/test/util/tables/sourceRecordSyncTestTables.js +26 -1
- package/dist/test/util/tables/sourceRecordSyncTestTables.js.map +1 -1
- package/generated/index.ts +1 -1
- package/generated/test/index.ts +3 -1
- package/package.json +2 -2
- package/src/Table.ts +38 -1
- package/src/auth/TableAuth.ts +45 -20
- package/src/source/SourceRecord.ts +17 -4
- package/src/source/SourceRecordLoader.ts +30 -3
- package/src/tables/MigrationTable.ts +43 -16
- package/test/SourceRecordLoader.test.ts +90 -0
- package/test/TableAuthIdentity.test.ts +115 -0
- package/test/reusable/SourceRecordSyncTests.ts +72 -0
- package/test/util/tables/sourceRecordSyncTestTables.ts +25 -0
|
@@ -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":"
|
|
1
|
+
{"version":3,"file":"SourceRecordLoader.test.js","sourceRoot":"","sources":["../../test/SourceRecordLoader.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uEAAsE;AAqBtE,IAAM,SAAS,GAAG,cAAM,OAAA,IAAI,uCAAkB,EAAgC,EAAtD,CAAsD,CAAC;AAE/E,QAAQ,CAAC,uCAAuC,EAAE;IAChD,EAAE,CAAC,gEAAgE,EAAE;QACnE,IAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,IAAM,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;QACrC,IAAM,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE;QAChD,IAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,IAAM,KAAK,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IACnF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE;QAC5D,IAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE;QAClD,IAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,qCAAqC,EAAE;IAC9C,QAAQ,CAAC,mBAAmB,EAAE;QAC5B,EAAE,CAAC,oCAAoC,EAAE;YACvC,IAAM,MAAM,GAAG,SAAS,EAAE,CAAC;YAC3B,IAAM,MAAM,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC;YACnE,IAAM,QAAQ,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC;YACrE,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,QAAQ,EAAE,oBAAoB,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QACrF,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0FAA0F,EAAE;YAC7F,oEAAoE;YACpE,mEAAmE;YACnE,sEAAsE;YACtE,IAAM,MAAM,GAAG,SAAS,EAAE,CAAC;YAC3B,IAAM,MAAM,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC;YACnE,IAAM,QAAQ,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;YACrE,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,QAAQ,EAAE,oBAAoB,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QACrF,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0EAA0E,EAAE;YAC7E,qEAAqE;YACrE,yEAAyE;YACzE,wEAAwE;YACxE,gDAAgD;YAChD,IAAM,MAAM,GAAG,SAAS,EAAE,CAAC;YAC3B,IAAM,MAAM,GAAG;gBACb,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,EAAE,EAAE,EAAE;aAC7E,CAAC;YACF,IAAM,QAAQ,GAAG;gBACf,WAAW,EAAE;oBACX,MAAM,EAAE;wBACN,OAAO,EAAE,EAAE;wBACX,IAAI,EAAE,OAAO;wBACb,eAAe,EAAE,EAAE;wBACnB,QAAQ,EAAE,EAAE;wBACZ,IAAI,EAAE,KAAK;wBACX,MAAM,EAAE,KAAK;qBACd;iBACF;aACF,CAAC;YACF,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,QAAQ,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACzF,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qEAAqE,EAAE;YACxE,IAAM,MAAM,GAAG,SAAS,EAAE,CAAC;YAC3B,IAAM,MAAM,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC;YACnE,IAAM,QAAQ,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;YAChD,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,QAAQ,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACzF,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kDAAkD,EAAE;YACrD,IAAM,MAAM,GAAG,SAAS,EAAE,CAAC;YAC3B,IAAM,MAAM,GAAG,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;YAC9D,IAAM,QAAQ,GAAG,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;YAChE,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,QAAQ,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACzF,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0EAA0E,EAAE;YAC7E,uEAAuE;YACvE,sEAAsE;YACtE,4DAA4D;YAC5D,IAAM,MAAM,GAAG,SAAS,EAAE,CAAC;YAC3B,IAAM,MAAM,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;YACtD,IAAM,QAAQ,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YACnC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,QAAQ,EAAE,oBAAoB,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QACrF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE;QAC3B,EAAE,CAAC,oCAAoC,EAAE;YACvC,IAAM,MAAM,GAAG,SAAS,EAAE,CAAC;YAC3B,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC5E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE;YACnD,IAAM,MAAM,GAAG,SAAS,EAAE,CAAC;YAC3B,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACzE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+BAA+B,EAAE;YAClC,IAAM,MAAM,GAAG,SAAS,EAAE,CAAC;YAC3B,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC3E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,sBAAsB,EAAE;QAC/B,EAAE,CAAC,mCAAmC,EAAE;YACtC,IAAM,MAAM,GAAG,SAAS,EAAE,CAAC;YAC3B,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC7D,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC5D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6CAA6C,EAAE;YAChD,IAAM,MAAM,GAAG,SAAS,EAAE,CAAC;YAC3B,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACnE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE;YAC5C,IAAM,MAAM,GAAG,SAAS,EAAE,CAAC;YAC3B,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,GAAG,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAClE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH;;;;GAIG;AACH,QAAQ,CAAC,uEAAuE,EAAE;IAEhF,8DAA8D;IACtD,IAAA,cAAc,GAAK,OAAO,CAAC,8BAA8B,CAAC,eAA5C,CAA6C;IACnE,8DAA8D;IAC9D,IAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjC,IAAM,MAAM,GAAG,cAAM,OAAA,IAAI,uCAAkB,EAAoC,EAA1D,CAA0D,CAAC;IAChF,IAAM,KAAK,GAAG,IAAI,cAAc,EAAE,CAAC;IAEnC,gGAAgG;IAChG,IAAM,QAAQ,GAAG,UAAC,SAAuC;QAAvC,0BAAA,EAAA,cAAuC;QAAK,OAAA,YAC5D,EAAE,EAAE,sCAAsC,EAC1C,WAAW,EAAE,wCAAwC,EACrD,GAAG,EAAE;gBAAY,sBAAA,SAAS,EAAA;qBAAA,EAC1B,kBAAkB,EAAE,IAAI,EACxB,aAAa,EAAE,kBAAkB,EACjC,oBAAoB,EAAE,QAAQ,IAC3B,SAAS,EACZ;IAR4D,CAQ5D,CAAC;IAEH,6DAA6D;IAC7D,IAAM,MAAM,GAAG,UAAC,SAAuC;QAAvC,0BAAA,EAAA,cAAuC;QAAK,OAAA,YAC1D,EAAE,EAAE,sCAAsC,EAC1C,WAAW,EAAE,wCAAwC,EACrD,kBAAkB,EAAE,IAAI,EACxB,aAAa,EAAE,kBAAkB,EACjC,oBAAoB,EAAE,QAAQ,EAC9B,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,MAAM,CAAC,sBAAsB,CAAC,EACzC,OAAO,EAAE,MAAM,CAAC,sBAAsB,CAAC,EACvC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,EAC5B,OAAO,EAAE,MAAM,CAAC,sBAAsB,CAAC,EACvC,OAAO,EAAE,MAAM,CAAC,sBAAsB,CAAC,IACpC,SAAS,EACZ;IAd0D,CAc1D,CAAC;IAEH,EAAE,CAAC,4EAA4E,EAAE;;;;;oBAC/E,KAAA,MAAM,CAAA;oBAAC,qBAAM,MAAM,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,EAAA;;oBAA7D,kBAAO,SAAsD,EAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;;;;SAC5E,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE;;;;;oBAC1C,SAAS,GAAG,MAAM,EAAE,CAAC;oBAC3B,OAAQ,SAAuC,CAAC,oBAAoB,CAAC;oBACrE,KAAA,MAAM,CAAA;oBAAC,qBAAM,MAAM,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,SAAS,CAAC,EAAA;;oBAA9D,kBAAO,SAAuD,EAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;;;;SAC5E,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE;;;;;oBAC9C,KAAA,MAAM,CAAA;oBAAC,qBAAM,MAAM,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAA;;oBAAxF,kBAAO,SAAiF,EAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;;;;SACtG,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE;;;;;oBACxE,KAAA,MAAM,CAAA;oBAAC,qBAAM,MAAM,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,oBAAoB,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAA;;oBAA/F,kBAAO,SAAwF,EAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;;;;SAC9G,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,+CAA+C,EAAE;IACxD,8DAA8D;IACtD,IAAA,gBAAgB,GAAK,OAAO,CAAC,uBAAuB,CAAC,iBAArC,CAAsC;IAC9D,8DAA8D;IACtD,IAAA,sBAAsB,GAAK,OAAO,CAAC,4BAA4B,CAAC,uBAA1C,CAA2C;IACzE,IAAM,gBAAgB,GAAG,cAAM,OAAC,gBAAgB,CAAC,GAAG,EAAU,CAAC,gBAAgB,EAAhD,CAAgD,CAAC;IAEhF,SAAS,CAAC;QACR,OAAO,gBAAgB,EAAE,CAAC,kCAAkC,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6FAA6F,EAAE;QAChG,gBAAgB,EAAE,CAAC,kCAAkC,CAAC,GAAG;YACvD;gBACE,aAAa,EAAE,6DAA6D;gBAC5E,WAAW,EAAE,kBAAkB;gBAC/B,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;aAClC;SACF,CAAC;QAEK,IAAA,WAAW,GAAI,sBAAsB,EAAW,GAArC,CAAsC;QACxD,MAAM,CAAC,WAAW,CAAC,CAAC,aAAa,CAAC;YAChC,MAAM,EAAE,kBAAkB;YAC1B,aAAa,EAAE,6DAA6D;YAC5E,IAAI,EAAE,4CAA4C;SACnD,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TableAuthIdentity.test.d.ts","sourceRoot":"","sources":["../../test/TableAuthIdentity.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __extends = (this && this.__extends) || (function () {
|
|
3
|
+
var extendStatics = function (d, b) {
|
|
4
|
+
extendStatics = Object.setPrototypeOf ||
|
|
5
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
+
return extendStatics(d, b);
|
|
8
|
+
};
|
|
9
|
+
return function (d, b) {
|
|
10
|
+
if (typeof b !== "function" && b !== null)
|
|
11
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
+
extendStatics(d, b);
|
|
13
|
+
function __() { this.constructor = d; }
|
|
14
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
+
};
|
|
16
|
+
})();
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
var user_auth_1 = require("@proteinjs/user-auth");
|
|
19
|
+
var Table_1 = require("../src/Table");
|
|
20
|
+
var Record_1 = require("../src/Record");
|
|
21
|
+
var Columns_1 = require("../src/Columns");
|
|
22
|
+
var TableAuth_1 = require("../src/auth/TableAuth");
|
|
23
|
+
var QueryOnlyTable = /** @class */ (function (_super) {
|
|
24
|
+
__extends(QueryOnlyTable, _super);
|
|
25
|
+
function QueryOnlyTable() {
|
|
26
|
+
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
27
|
+
_this.name = 'identity_query_only_test';
|
|
28
|
+
_this.auth = {
|
|
29
|
+
db: { query: 'authenticated' },
|
|
30
|
+
};
|
|
31
|
+
_this.columns = (0, Record_1.withRecordColumns)({ title: new Columns_1.StringColumn('title') });
|
|
32
|
+
return _this;
|
|
33
|
+
}
|
|
34
|
+
return QueryOnlyTable;
|
|
35
|
+
}(Table_1.Table));
|
|
36
|
+
var setUser = function (roles, email) {
|
|
37
|
+
if (email === void 0) { email = 'user@test.local'; }
|
|
38
|
+
user_auth_1.UserAuth.userRepo = { getUser: function () { return ({ email: email, roles: roles }); } };
|
|
39
|
+
};
|
|
40
|
+
var setGuest = function () {
|
|
41
|
+
user_auth_1.UserAuth.userRepo = { getUser: function () { return ({ email: 'guest', roles: [] }); } };
|
|
42
|
+
};
|
|
43
|
+
var setMapping = function (mapping) {
|
|
44
|
+
user_auth_1.UserAuth.permissionRolesMapping = { getRoles: function (permission) { return mapping[permission]; } };
|
|
45
|
+
};
|
|
46
|
+
describe('TableAuth.identityAllows', function () {
|
|
47
|
+
beforeEach(function () {
|
|
48
|
+
setMapping({ usage: ['usage'] });
|
|
49
|
+
});
|
|
50
|
+
afterEach(function () {
|
|
51
|
+
user_auth_1.UserAuth.userRepo = undefined;
|
|
52
|
+
user_auth_1.UserAuth.permissionRolesMapping = undefined;
|
|
53
|
+
});
|
|
54
|
+
test("'public' admits anyone, including a guest", function () {
|
|
55
|
+
setGuest();
|
|
56
|
+
expect(new TableAuth_1.TableAuth().identityAllows('public')).toBe(true);
|
|
57
|
+
});
|
|
58
|
+
test("'authenticated' admits a signed-in user and refuses a guest", function () {
|
|
59
|
+
setUser([]);
|
|
60
|
+
expect(new TableAuth_1.TableAuth().identityAllows('authenticated')).toBe(true);
|
|
61
|
+
setGuest();
|
|
62
|
+
expect(new TableAuth_1.TableAuth().identityAllows('authenticated')).toBe(false);
|
|
63
|
+
});
|
|
64
|
+
test('a roles list admits a holder of at least one role', function () {
|
|
65
|
+
setUser(['ops']);
|
|
66
|
+
expect(new TableAuth_1.TableAuth().identityAllows(['users', 'ops'])).toBe(true);
|
|
67
|
+
setUser(['dev']);
|
|
68
|
+
expect(new TableAuth_1.TableAuth().identityAllows(['users', 'ops'])).toBe(false);
|
|
69
|
+
});
|
|
70
|
+
test('a permission identity resolves through the consumer mapping; admin is break-glass', function () {
|
|
71
|
+
setUser(['usage']);
|
|
72
|
+
expect(new TableAuth_1.TableAuth().identityAllows({ permission: 'usage' })).toBe(true);
|
|
73
|
+
setUser(['users']);
|
|
74
|
+
expect(new TableAuth_1.TableAuth().identityAllows({ permission: 'usage' })).toBe(false);
|
|
75
|
+
setUser(['admin']);
|
|
76
|
+
expect(new TableAuth_1.TableAuth().identityAllows({ permission: 'usage' })).toBe(true);
|
|
77
|
+
});
|
|
78
|
+
test('an undeclared identity is admin-only, never open', function () {
|
|
79
|
+
setUser(['usage', 'users', 'ops']);
|
|
80
|
+
expect(new TableAuth_1.TableAuth().identityAllows(undefined)).toBe(false);
|
|
81
|
+
setUser(['admin']);
|
|
82
|
+
expect(new TableAuth_1.TableAuth().identityAllows(undefined)).toBe(true);
|
|
83
|
+
});
|
|
84
|
+
test('fails closed when no user can be resolved', function () {
|
|
85
|
+
user_auth_1.UserAuth.userRepo = {
|
|
86
|
+
getUser: function () {
|
|
87
|
+
throw new Error('no session');
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
expect(new TableAuth_1.TableAuth().identityAllows('authenticated')).toBe(false);
|
|
91
|
+
expect(new TableAuth_1.TableAuth().identityAllows({ permission: 'usage' })).toBe(false);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
describe('TableAuth operation doors keep their declared-block semantics', function () {
|
|
95
|
+
afterEach(function () {
|
|
96
|
+
user_auth_1.UserAuth.userRepo = undefined;
|
|
97
|
+
user_auth_1.UserAuth.permissionRolesMapping = undefined;
|
|
98
|
+
});
|
|
99
|
+
test('a declared operation opens to its identity', function () {
|
|
100
|
+
setUser([]);
|
|
101
|
+
expect(new TableAuth_1.TableAuth().canPerform(new QueryOnlyTable(), 'query')).toBe(true);
|
|
102
|
+
});
|
|
103
|
+
test('within a declared block an undeclared operation stays closed — admin included', function () {
|
|
104
|
+
setUser(['admin']);
|
|
105
|
+
expect(new TableAuth_1.TableAuth().canPerform(new QueryOnlyTable(), 'insert')).toBe(false);
|
|
106
|
+
setUser([]);
|
|
107
|
+
expect(new TableAuth_1.TableAuth().canPerform(new QueryOnlyTable(), 'insert')).toBe(false);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
//# sourceMappingURL=TableAuthIdentity.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TableAuthIdentity.test.js","sourceRoot":"","sources":["../../test/TableAuthIdentity.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,
|
|
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) {
|