@proteinjs/db-driver-spanner 1.20.3 → 1.22.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 +27 -0
- package/dist/test/RunPendingMigrations.test.js +88 -10
- package/dist/test/RunPendingMigrations.test.js.map +1 -1
- package/dist/test/SourceRecordSync.test.d.ts +2 -0
- package/dist/test/SourceRecordSync.test.d.ts.map +1 -0
- package/dist/test/SourceRecordSync.test.js +65 -0
- package/dist/test/SourceRecordSync.test.js.map +1 -0
- package/package.json +5 -5
- package/test/RunPendingMigrations.test.ts +59 -3
- package/test/SourceRecordSync.test.ts +26 -0
- package/test.d.ts +2 -0
- package/test.js +10 -0
- package/tsconfig.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,33 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [1.22.0](https://github.com/proteinjs/db/compare/@proteinjs/db-driver-spanner@1.21.0...@proteinjs/db-driver-spanner@1.22.0) (2026-08-18)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* source-record sync — onSourceRemoved policies, natural-key adoption, unique-index duplicate preflight ([1345bfc](https://github.com/proteinjs/db/commit/1345bfcd2bd3f457dddacb5770bf723828d98fa9))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# [1.21.0](https://github.com/proteinjs/db/compare/@proteinjs/db-driver-spanner@1.20.3...@proteinjs/db-driver-spanner@1.21.0) (2026-08-17)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* **db-driver-spanner:** root test.js/test.d.ts shims for the ./test subpath — paths-mapped consumers resolve built dist, not sources ([d51556f](https://github.com/proteinjs/db/commit/d51556f07affcdbd80d80d19ed41d1257cc9a0cc))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Features
|
|
26
|
+
|
|
27
|
+
* **db:** retired-migration flag — the deploy series stamps source-less ledger rows and never auto-runs retired rows ([f468125](https://github.com/proteinjs/db/commit/f4681257439e2e7e031f9d7f4d90b7463cc46456))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
6
33
|
## [1.20.3](https://github.com/proteinjs/db/compare/@proteinjs/db-driver-spanner@1.20.2...@proteinjs/db-driver-spanner@1.20.3) (2026-08-15)
|
|
7
34
|
|
|
8
35
|
|
|
@@ -71,7 +71,9 @@ require("../generated/test/index");
|
|
|
71
71
|
* are reported so the Job can fail the deploy; a later series retries the failed row and
|
|
72
72
|
* finishes the tail.
|
|
73
73
|
* - HISTORY HONESTY: ledger rows whose source loader is gone (the table keeps history) are
|
|
74
|
-
* skipped and reported as unresolved, never crash the series
|
|
74
|
+
* skipped and reported as unresolved, never crash the series — and STAMPED `retired: true`.
|
|
75
|
+
* - RETIREMENT: a retired row is never auto-run, even when its source class ships again in a
|
|
76
|
+
* later build; only un-retiring it (the Migrations-page toggle) re-arms the series.
|
|
75
77
|
*
|
|
76
78
|
* All series runs execute SESSIONLESS (no test user registered) — the deploy Job has no user
|
|
77
79
|
* session, and UserAuth is fail-closed: these tests passing IS the pin that the series records
|
|
@@ -316,15 +318,15 @@ describe('MigrationRunner.runPendingMigrations (spanner)', function () {
|
|
|
316
318
|
}
|
|
317
319
|
});
|
|
318
320
|
}); }, 60000);
|
|
319
|
-
test('ledger rows without a source record are
|
|
320
|
-
var live, summary,
|
|
321
|
-
return __generator(this, function (
|
|
322
|
-
switch (
|
|
321
|
+
test('ledger rows without a source record are stamped retired — skipped, reported, never run', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
322
|
+
var live, summary, ghostRow;
|
|
323
|
+
return __generator(this, function (_a) {
|
|
324
|
+
switch (_a.label) {
|
|
323
325
|
case 0:
|
|
324
326
|
live = plantMigration('live-beside-history');
|
|
325
327
|
return [4 /*yield*/, insertLedgerRow(live, 1)];
|
|
326
328
|
case 1:
|
|
327
|
-
|
|
329
|
+
_a.sent();
|
|
328
330
|
// A row whose loader was deleted after it ran in some past release
|
|
329
331
|
// (doNotDeleteSourceRecordsFromDb keeps it in the ledger forever).
|
|
330
332
|
return [4 /*yield*/, (0, db_1.getDbAsSystem)().insert(migrationTable, {
|
|
@@ -335,17 +337,93 @@ describe('MigrationRunner.runPendingMigrations (spanner)', function () {
|
|
|
335
337
|
case 2:
|
|
336
338
|
// A row whose loader was deleted after it ran in some past release
|
|
337
339
|
// (doNotDeleteSourceRecordsFromDb keeps it in the ledger forever).
|
|
338
|
-
|
|
340
|
+
_a.sent();
|
|
339
341
|
return [4 /*yield*/, new db_1.MigrationRunner().runPendingMigrations()];
|
|
340
342
|
case 3:
|
|
341
|
-
summary =
|
|
343
|
+
summary = _a.sent();
|
|
342
344
|
expect(summary.unresolved).toEqual(['ghost-history']);
|
|
345
|
+
expect(summary.retired).toEqual([]);
|
|
343
346
|
expect(summary.applied).toEqual(['live-beside-history']);
|
|
344
347
|
expect(summary.failed).toBeUndefined();
|
|
345
|
-
_a = expect;
|
|
346
348
|
return [4 /*yield*/, (0, db_1.getDbAsSystem)().get(migrationTable, { id: 'ghost-history' })];
|
|
347
349
|
case 4:
|
|
348
|
-
|
|
350
|
+
ghostRow = _a.sent();
|
|
351
|
+
expect(ghostRow.status).toBe('proposed');
|
|
352
|
+
// The stamp: an unresolved row is retired on sight, so a returning source class can never
|
|
353
|
+
// silently re-arm it (the pin for that refusal is the next test).
|
|
354
|
+
expect(ghostRow.retired).toBe(true);
|
|
355
|
+
return [2 /*return*/];
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
}); }, 60000);
|
|
359
|
+
test('a stamped row is refused even when its source class ships again — the flag outlives the gap', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
360
|
+
var stampingRun, laterRun, row;
|
|
361
|
+
return __generator(this, function (_a) {
|
|
362
|
+
switch (_a.label) {
|
|
363
|
+
case 0:
|
|
364
|
+
// Gate run over a build where the row's loader no longer ships: the run stamps it retired.
|
|
365
|
+
return [4 /*yield*/, (0, db_1.getDbAsSystem)().insert(migrationTable, {
|
|
366
|
+
id: 'returning-loader',
|
|
367
|
+
description: 'loader missing from this build',
|
|
368
|
+
created: (0, moment_1.default)(base),
|
|
369
|
+
})];
|
|
370
|
+
case 1:
|
|
371
|
+
// Gate run over a build where the row's loader no longer ships: the run stamps it retired.
|
|
372
|
+
_a.sent();
|
|
373
|
+
return [4 /*yield*/, new db_1.MigrationRunner().runPendingMigrations()];
|
|
374
|
+
case 2:
|
|
375
|
+
stampingRun = _a.sent();
|
|
376
|
+
expect(stampingRun.unresolved).toEqual(['returning-loader']);
|
|
377
|
+
// The source class RETURNS in a later build. Its id resolving again is not consent to
|
|
378
|
+
// auto-run: the row stays excluded until a human un-retires it on the Migrations page.
|
|
379
|
+
plantMigration('returning-loader');
|
|
380
|
+
return [4 /*yield*/, new db_1.MigrationRunner().runPendingMigrations()];
|
|
381
|
+
case 3:
|
|
382
|
+
laterRun = _a.sent();
|
|
383
|
+
expect(runLog).toEqual([]);
|
|
384
|
+
expect(laterRun.retired).toEqual(['returning-loader']);
|
|
385
|
+
expect(laterRun.unresolved).toEqual([]);
|
|
386
|
+
expect(laterRun.applied).toEqual([]);
|
|
387
|
+
return [4 /*yield*/, (0, db_1.getDbAsSystem)().get(migrationTable, { id: 'returning-loader' })];
|
|
388
|
+
case 4:
|
|
389
|
+
row = _a.sent();
|
|
390
|
+
expect(row.retired).toBe(true);
|
|
391
|
+
expect(row.status).toBe('proposed');
|
|
392
|
+
return [2 /*return*/];
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
}); }, 60000);
|
|
396
|
+
test('un-retiring a retired row re-arms the series — it runs to success', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
397
|
+
var migration, refusedRun, rearmedRun, row;
|
|
398
|
+
return __generator(this, function (_a) {
|
|
399
|
+
switch (_a.label) {
|
|
400
|
+
case 0:
|
|
401
|
+
migration = plantMigration('unretired-comeback');
|
|
402
|
+
return [4 /*yield*/, (0, db_1.getDbAsSystem)().insert(migrationTable, __assign(__assign({}, migration), { retired: true, created: (0, moment_1.default)(base) }))];
|
|
403
|
+
case 1:
|
|
404
|
+
_a.sent();
|
|
405
|
+
return [4 /*yield*/, new db_1.MigrationRunner().runPendingMigrations()];
|
|
406
|
+
case 2:
|
|
407
|
+
refusedRun = _a.sent();
|
|
408
|
+
expect(runLog).toEqual([]);
|
|
409
|
+
expect(refusedRun.retired).toEqual(['unretired-comeback']);
|
|
410
|
+
// The Migrations-page Un-retire button issues exactly this write.
|
|
411
|
+
return [4 /*yield*/, (0, db_1.getDbAsSystem)().update(migrationTable, { id: 'unretired-comeback', retired: false })];
|
|
412
|
+
case 3:
|
|
413
|
+
// The Migrations-page Un-retire button issues exactly this write.
|
|
414
|
+
_a.sent();
|
|
415
|
+
return [4 /*yield*/, new db_1.MigrationRunner().runPendingMigrations()];
|
|
416
|
+
case 4:
|
|
417
|
+
rearmedRun = _a.sent();
|
|
418
|
+
expect(runLog).toEqual(['unretired-comeback']);
|
|
419
|
+
expect(rearmedRun.applied).toEqual(['unretired-comeback']);
|
|
420
|
+
expect(rearmedRun.retired).toEqual([]);
|
|
421
|
+
return [4 /*yield*/, (0, db_1.getDbAsSystem)().get(migrationTable, { id: 'unretired-comeback' })];
|
|
422
|
+
case 5:
|
|
423
|
+
row = _a.sent();
|
|
424
|
+
expect(row.status).toBe('success');
|
|
425
|
+
expect(row.output).toBe('unretired-comeback output');
|
|
426
|
+
expect(row.retired).toBe(false);
|
|
349
427
|
return [2 /*return*/];
|
|
350
428
|
}
|
|
351
429
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RunPendingMigrations.test.js","sourceRoot":"","sources":["../../test/RunPendingMigrations.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kEAA6D;AAC7D,oCAAmH;AACnH,2CAAqE;AACrE,kDAA4B;AAC5B,4DAA2D;AAC3D,gFAA+E;AAC/E,mCAAiC;AAEjC
|
|
1
|
+
{"version":3,"file":"RunPendingMigrations.test.js","sourceRoot":"","sources":["../../test/RunPendingMigrations.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SourceRecordSync.test.d.ts","sourceRoot":"","sources":["../../test/SourceRecordSync.test.ts"],"names":[],"mappings":"AAKA,OAAO,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
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;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
var test_1 = require("@proteinjs/db/test");
|
|
40
|
+
var db_driver_spanner_1 = require("@proteinjs/db-driver-spanner");
|
|
41
|
+
var getDropTestTable_1 = require("./util/getDropTestTable");
|
|
42
|
+
var SpannerEmulatorProvisioner_1 = require("./util/SpannerEmulatorProvisioner");
|
|
43
|
+
var db_transaction_context_1 = require("@proteinjs/db-transaction-context");
|
|
44
|
+
require("../generated/test/index");
|
|
45
|
+
var spannerConfig = {
|
|
46
|
+
projectId: 'proteinjs-test',
|
|
47
|
+
instanceName: 'proteinjs-test',
|
|
48
|
+
databaseName: 'test',
|
|
49
|
+
};
|
|
50
|
+
var spannerDriver = new db_driver_spanner_1.SpannerDriver(spannerConfig);
|
|
51
|
+
beforeAll(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
52
|
+
return __generator(this, function (_a) {
|
|
53
|
+
switch (_a.label) {
|
|
54
|
+
case 0: return [4 /*yield*/, SpannerEmulatorProvisioner_1.SpannerEmulatorProvisioner.ensureProvisioned(spannerConfig)];
|
|
55
|
+
case 1:
|
|
56
|
+
_a.sent();
|
|
57
|
+
return [2 /*return*/];
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}); }, 60000);
|
|
61
|
+
afterAll(function () {
|
|
62
|
+
SpannerEmulatorProvisioner_1.SpannerEmulatorProvisioner.release();
|
|
63
|
+
});
|
|
64
|
+
describe('Source record sync (mixed tables, natural-key adoption, onSourceRemoved, unique preflight)', (0, test_1.sourceRecordSyncTests)(spannerDriver, new db_transaction_context_1.TransactionContext(), (0, getDropTestTable_1.getDropTestTable)(spannerDriver)));
|
|
65
|
+
//# sourceMappingURL=SourceRecordSync.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SourceRecordSync.test.js","sourceRoot":"","sources":["../../test/SourceRecordSync.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA2D;AAC3D,kEAA6D;AAC7D,4DAA2D;AAC3D,gFAA+E;AAC/E,4EAAuE;AACvE,mCAAiC;AAEjC,IAAM,aAAa,GAAG;IACpB,SAAS,EAAE,gBAAgB;IAC3B,YAAY,EAAE,gBAAgB;IAC9B,YAAY,EAAE,MAAM;CACrB,CAAC;AACF,IAAM,aAAa,GAAG,IAAI,iCAAa,CAAC,aAAa,CAAC,CAAC;AAEvD,SAAS,CAAC;;;oBACR,qBAAM,uDAA0B,CAAC,iBAAiB,CAAC,aAAa,CAAC,EAAA;;gBAAjE,SAAiE,CAAC;;;;KACnE,EAAE,KAAK,CAAC,CAAC;AAEV,QAAQ,CAAC;IACP,uDAA0B,CAAC,OAAO,EAAE,CAAC;AACvC,CAAC,CAAC,CAAC;AAEH,QAAQ,CACN,4FAA4F,EAC5F,IAAA,4BAAqB,EAAC,aAAa,EAAE,IAAI,2CAAkB,EAAE,EAAE,IAAA,mCAAgB,EAAC,aAAa,CAAC,CAAC,CAChG,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@proteinjs/db-driver-spanner",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.22.0",
|
|
4
4
|
"main": "./dist/generated/index.js",
|
|
5
5
|
"types": "./dist/generated/index.d.ts",
|
|
6
6
|
"exports": {
|
|
@@ -42,10 +42,10 @@
|
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@google-cloud/spanner": "7.5.0",
|
|
45
|
-
"@proteinjs/db": "^1.
|
|
45
|
+
"@proteinjs/db": "^1.34.0",
|
|
46
46
|
"@proteinjs/db-query": "^1.7.0",
|
|
47
|
-
"@proteinjs/db-spanner-common": "^1.3.
|
|
48
|
-
"@proteinjs/db-transaction-context": "^0.5.
|
|
47
|
+
"@proteinjs/db-spanner-common": "^1.3.13",
|
|
48
|
+
"@proteinjs/db-transaction-context": "^0.5.13",
|
|
49
49
|
"@proteinjs/logger": "^1.0.21",
|
|
50
50
|
"@proteinjs/reflection": "^1.1.12",
|
|
51
51
|
"@proteinjs/util": "^1.6.1"
|
|
@@ -63,5 +63,5 @@
|
|
|
63
63
|
"ts-jest": "29.1.1",
|
|
64
64
|
"typescript": "5.2.2"
|
|
65
65
|
},
|
|
66
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "7a301275151aee8040fd52e15e3fe950a6863783"
|
|
67
67
|
}
|
|
@@ -20,7 +20,9 @@ import '../generated/test/index';
|
|
|
20
20
|
* are reported so the Job can fail the deploy; a later series retries the failed row and
|
|
21
21
|
* finishes the tail.
|
|
22
22
|
* - HISTORY HONESTY: ledger rows whose source loader is gone (the table keeps history) are
|
|
23
|
-
* skipped and reported as unresolved, never crash the series
|
|
23
|
+
* skipped and reported as unresolved, never crash the series — and STAMPED `retired: true`.
|
|
24
|
+
* - RETIREMENT: a retired row is never auto-run, even when its source class ships again in a
|
|
25
|
+
* later build; only un-retiring it (the Migrations-page toggle) re-arms the series.
|
|
24
26
|
*
|
|
25
27
|
* All series runs execute SESSIONLESS (no test user registered) — the deploy Job has no user
|
|
26
28
|
* session, and UserAuth is fail-closed: these tests passing IS the pin that the series records
|
|
@@ -180,7 +182,7 @@ describe('MigrationRunner.runPendingMigrations (spanner)', () => {
|
|
|
180
182
|
expect((await getDbAsSystem().get(migrationTable, { id: 'fail-c-after' })).status).toBe('success');
|
|
181
183
|
}, 60000);
|
|
182
184
|
|
|
183
|
-
test('ledger rows without a source record are
|
|
185
|
+
test('ledger rows without a source record are stamped retired — skipped, reported, never run', async () => {
|
|
184
186
|
const live = plantMigration('live-beside-history');
|
|
185
187
|
await insertLedgerRow(live, 1);
|
|
186
188
|
// A row whose loader was deleted after it ran in some past release
|
|
@@ -194,8 +196,62 @@ describe('MigrationRunner.runPendingMigrations (spanner)', () => {
|
|
|
194
196
|
const summary = await new MigrationRunner().runPendingMigrations();
|
|
195
197
|
|
|
196
198
|
expect(summary.unresolved).toEqual(['ghost-history']);
|
|
199
|
+
expect(summary.retired).toEqual([]);
|
|
197
200
|
expect(summary.applied).toEqual(['live-beside-history']);
|
|
198
201
|
expect(summary.failed).toBeUndefined();
|
|
199
|
-
|
|
202
|
+
const ghostRow = await getDbAsSystem().get(migrationTable, { id: 'ghost-history' });
|
|
203
|
+
expect(ghostRow.status).toBe('proposed');
|
|
204
|
+
// The stamp: an unresolved row is retired on sight, so a returning source class can never
|
|
205
|
+
// silently re-arm it (the pin for that refusal is the next test).
|
|
206
|
+
expect(ghostRow.retired).toBe(true);
|
|
207
|
+
}, 60000);
|
|
208
|
+
|
|
209
|
+
test('a stamped row is refused even when its source class ships again — the flag outlives the gap', async () => {
|
|
210
|
+
// Gate run over a build where the row's loader no longer ships: the run stamps it retired.
|
|
211
|
+
await getDbAsSystem().insert(migrationTable, {
|
|
212
|
+
id: 'returning-loader',
|
|
213
|
+
description: 'loader missing from this build',
|
|
214
|
+
created: moment(base),
|
|
215
|
+
} as any);
|
|
216
|
+
const stampingRun = await new MigrationRunner().runPendingMigrations();
|
|
217
|
+
expect(stampingRun.unresolved).toEqual(['returning-loader']);
|
|
218
|
+
|
|
219
|
+
// The source class RETURNS in a later build. Its id resolving again is not consent to
|
|
220
|
+
// auto-run: the row stays excluded until a human un-retires it on the Migrations page.
|
|
221
|
+
plantMigration('returning-loader');
|
|
222
|
+
const laterRun = await new MigrationRunner().runPendingMigrations();
|
|
223
|
+
|
|
224
|
+
expect(runLog).toEqual([]);
|
|
225
|
+
expect(laterRun.retired).toEqual(['returning-loader']);
|
|
226
|
+
expect(laterRun.unresolved).toEqual([]);
|
|
227
|
+
expect(laterRun.applied).toEqual([]);
|
|
228
|
+
const row = await getDbAsSystem().get(migrationTable, { id: 'returning-loader' });
|
|
229
|
+
expect(row.retired).toBe(true);
|
|
230
|
+
expect(row.status).toBe('proposed');
|
|
231
|
+
}, 60000);
|
|
232
|
+
|
|
233
|
+
test('un-retiring a retired row re-arms the series — it runs to success', async () => {
|
|
234
|
+
const migration = plantMigration('unretired-comeback');
|
|
235
|
+
await getDbAsSystem().insert(migrationTable, {
|
|
236
|
+
...migration,
|
|
237
|
+
retired: true,
|
|
238
|
+
created: moment(base),
|
|
239
|
+
} as any);
|
|
240
|
+
|
|
241
|
+
const refusedRun = await new MigrationRunner().runPendingMigrations();
|
|
242
|
+
expect(runLog).toEqual([]);
|
|
243
|
+
expect(refusedRun.retired).toEqual(['unretired-comeback']);
|
|
244
|
+
|
|
245
|
+
// The Migrations-page Un-retire button issues exactly this write.
|
|
246
|
+
await getDbAsSystem().update(migrationTable, { id: 'unretired-comeback', retired: false } as any);
|
|
247
|
+
const rearmedRun = await new MigrationRunner().runPendingMigrations();
|
|
248
|
+
|
|
249
|
+
expect(runLog).toEqual(['unretired-comeback']);
|
|
250
|
+
expect(rearmedRun.applied).toEqual(['unretired-comeback']);
|
|
251
|
+
expect(rearmedRun.retired).toEqual([]);
|
|
252
|
+
const row = await getDbAsSystem().get(migrationTable, { id: 'unretired-comeback' });
|
|
253
|
+
expect(row.status).toBe('success');
|
|
254
|
+
expect(row.output).toBe('unretired-comeback output');
|
|
255
|
+
expect(row.retired).toBe(false);
|
|
200
256
|
}, 60000);
|
|
201
257
|
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { sourceRecordSyncTests } from '@proteinjs/db/test';
|
|
2
|
+
import { SpannerDriver } from '@proteinjs/db-driver-spanner';
|
|
3
|
+
import { getDropTestTable } from './util/getDropTestTable';
|
|
4
|
+
import { SpannerEmulatorProvisioner } from './util/SpannerEmulatorProvisioner';
|
|
5
|
+
import { TransactionContext } from '@proteinjs/db-transaction-context';
|
|
6
|
+
import '../generated/test/index';
|
|
7
|
+
|
|
8
|
+
const spannerConfig = {
|
|
9
|
+
projectId: 'proteinjs-test',
|
|
10
|
+
instanceName: 'proteinjs-test',
|
|
11
|
+
databaseName: 'test',
|
|
12
|
+
};
|
|
13
|
+
const spannerDriver = new SpannerDriver(spannerConfig);
|
|
14
|
+
|
|
15
|
+
beforeAll(async () => {
|
|
16
|
+
await SpannerEmulatorProvisioner.ensureProvisioned(spannerConfig);
|
|
17
|
+
}, 60000);
|
|
18
|
+
|
|
19
|
+
afterAll(() => {
|
|
20
|
+
SpannerEmulatorProvisioner.release();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe(
|
|
24
|
+
'Source record sync (mixed tables, natural-key adoption, onSourceRemoved, unique preflight)',
|
|
25
|
+
sourceRecordSyncTests(spannerDriver, new TransactionContext(), getDropTestTable(spannerDriver))
|
|
26
|
+
);
|
package/test.d.ts
ADDED
package/test.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Node10/classic-resolution shim for the `./test` subpath (thought-common's test.js convention).
|
|
2
|
+
// Consumers compiled with `module: commonjs` + default (node10) resolution AND a
|
|
3
|
+
// `@proteinjs/*` tsconfig paths mapping resolve this subpath as a mapped FILE PATH, which
|
|
4
|
+
// bypasses the `exports`/`typesVersions` maps entirely and — in workspace-symlinked installs,
|
|
5
|
+
// where the source tree is present — lands on `test/index.ts` SOURCE. TypeScript then realpaths
|
|
6
|
+
// the sources outside the consumer's rootDir (TS6059) and `noEmitOnError` blocks the consumer's
|
|
7
|
+
// own emit (the ts-jest "Unable to process TestEnvironment.ts" cold-cache failure class,
|
|
8
|
+
// 2026-08-17). This root stub wins the mapped-path lookup before directory resolution, so every
|
|
9
|
+
// install shape resolves to the built dist instead.
|
|
10
|
+
module.exports = require('./dist/generated/test/index.js');
|