@smartbit4all/playwright-qa 0.1.10 → 0.1.12
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/README.md +70 -0
- package/dist/basedata/hash.d.ts +2 -0
- package/dist/basedata/hash.d.ts.map +1 -0
- package/dist/basedata/hash.js +23 -0
- package/dist/basedata/hash.js.map +1 -0
- package/dist/basedata/history.d.ts +10 -0
- package/dist/basedata/history.d.ts.map +1 -0
- package/dist/basedata/history.js +144 -0
- package/dist/basedata/history.js.map +1 -0
- package/dist/basedata/index.d.ts +6 -0
- package/dist/basedata/index.d.ts.map +1 -0
- package/dist/basedata/index.js +16 -0
- package/dist/basedata/index.js.map +1 -0
- package/dist/basedata/loader.d.ts +12 -0
- package/dist/basedata/loader.d.ts.map +1 -0
- package/dist/basedata/loader.js +230 -0
- package/dist/basedata/loader.js.map +1 -0
- package/dist/basedata/processors/basic-screen.d.ts +31 -0
- package/dist/basedata/processors/basic-screen.d.ts.map +1 -0
- package/dist/basedata/processors/basic-screen.js +128 -0
- package/dist/basedata/processors/basic-screen.js.map +1 -0
- package/dist/basedata/registry.d.ts +11 -0
- package/dist/basedata/registry.d.ts.map +1 -0
- package/dist/basedata/registry.js +50 -0
- package/dist/basedata/registry.js.map +1 -0
- package/dist/basedata/runner.d.ts +3 -0
- package/dist/basedata/runner.d.ts.map +1 -0
- package/dist/basedata/runner.js +324 -0
- package/dist/basedata/runner.js.map +1 -0
- package/dist/basedata/types.d.ts +161 -0
- package/dist/basedata/types.d.ts.map +1 -0
- package/dist/basedata/types.js +3 -0
- package/dist/basedata/types.js.map +1 -0
- package/dist/steps/debug.d.ts +15 -0
- package/dist/steps/debug.d.ts.map +1 -0
- package/dist/steps/debug.js +41 -0
- package/dist/steps/debug.js.map +1 -0
- package/dist/steps/forms.d.ts +29 -0
- package/dist/steps/forms.d.ts.map +1 -1
- package/dist/steps/forms.js +93 -0
- package/dist/steps/forms.js.map +1 -1
- package/dist/steps/grid.steps.d.ts +3 -1
- package/dist/steps/grid.steps.d.ts.map +1 -1
- package/dist/steps/grid.steps.js +52 -8
- package/dist/steps/grid.steps.js.map +1 -1
- package/dist/steps/index.d.ts +2 -1
- package/dist/steps/index.d.ts.map +1 -1
- package/dist/steps/index.js +5 -1
- package/dist/steps/index.js.map +1 -1
- package/dist/steps/locators.d.ts +17 -3
- package/dist/steps/locators.d.ts.map +1 -1
- package/dist/steps/locators.js +22 -5
- package/dist/steps/locators.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BasicScreenProcessor = void 0;
|
|
4
|
+
const forms_1 = require("../../steps/forms");
|
|
5
|
+
const locators_1 = require("../../steps/locators");
|
|
6
|
+
const dialog_steps_1 = require("../../steps/dialog.steps");
|
|
7
|
+
const grid_steps_1 = require("../../steps/grid.steps");
|
|
8
|
+
const wait_1 = require("../../steps/wait");
|
|
9
|
+
const NEW_LABELS = 'NEW_ENTRY';
|
|
10
|
+
const SAVE_LABELS = 'SAVE';
|
|
11
|
+
const DELETE_LABELS = 'Inaktiválás';
|
|
12
|
+
function anyButton(container, labels) {
|
|
13
|
+
const sel = labels.map(l => `button[data-testid="${l}"], button:has-text("${l}")`).join(', ');
|
|
14
|
+
return container.locator(sel).first();
|
|
15
|
+
}
|
|
16
|
+
async function clickFirstFound(page, labels) {
|
|
17
|
+
for (const label of labels) {
|
|
18
|
+
const item = (0, locators_1.findMenuItem)(page, label);
|
|
19
|
+
if (await item.count() > 0) {
|
|
20
|
+
await item.click();
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
throw new Error(`Menu item not found. Tried: ${labels.join(', ')}`);
|
|
25
|
+
}
|
|
26
|
+
class BasicScreenProcessor {
|
|
27
|
+
async apply(items, operation, meta, params, ctx) {
|
|
28
|
+
const { page } = ctx;
|
|
29
|
+
const keyField = meta.key ?? 'code';
|
|
30
|
+
if (params.navigationPath?.length) {
|
|
31
|
+
for (const label of params.navigationPath) {
|
|
32
|
+
await (0, locators_1.findButton)(page, label).click();
|
|
33
|
+
await (0, wait_1.waitForAngularIdle)(page);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const result = { success: 0, failed: 0, errors: [] };
|
|
37
|
+
for (const item of items) {
|
|
38
|
+
const itemKey = String(item[keyField] ?? '');
|
|
39
|
+
try {
|
|
40
|
+
await this.processItem(ctx, page, item, operation, keyField, params);
|
|
41
|
+
result.success++;
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
result.failed++;
|
|
45
|
+
result.errors.push({
|
|
46
|
+
key: itemKey,
|
|
47
|
+
error: err instanceof Error ? err.message : String(err),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
async processItem(ctx, page, item, operation, keyField, params) {
|
|
54
|
+
switch (operation) {
|
|
55
|
+
case 'insert': return this.insertItem(ctx, page, item, params);
|
|
56
|
+
case 'update': return this.updateItem(ctx, page, item, keyField, params);
|
|
57
|
+
case 'delete': return this.deleteItem(ctx, page, item, keyField, params);
|
|
58
|
+
case 'upsert': return this.upsertItem(ctx, page, item, keyField, params);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async insertItem(ctx, page, item, params) {
|
|
62
|
+
await (0, locators_1.findButton)(page, NEW_LABELS).click();
|
|
63
|
+
await (0, wait_1.waitForAngularIdle)(page);
|
|
64
|
+
const form = (0, dialog_steps_1.topDialog)(page);
|
|
65
|
+
await this.fillFields(form, item);
|
|
66
|
+
this.save(ctx, page, item);
|
|
67
|
+
}
|
|
68
|
+
async updateItem(ctx, page, item, keyField, params) {
|
|
69
|
+
await (0, grid_steps_1.selectGridRow)(page, { rowId: String(item[keyField] ?? '') }, 'Szerkesztés');
|
|
70
|
+
await (0, wait_1.waitForAngularIdle)(page);
|
|
71
|
+
const form = (0, dialog_steps_1.topDialog)(page);
|
|
72
|
+
await this.fillFields(form, item);
|
|
73
|
+
this.save(ctx, page, item);
|
|
74
|
+
}
|
|
75
|
+
async deleteItem(ctx, page, item, keyField, params) {
|
|
76
|
+
const key = String(item[keyField] ?? '');
|
|
77
|
+
await (0, grid_steps_1.selectGridRow)(page, { rowId: key }, DELETE_LABELS);
|
|
78
|
+
await (0, wait_1.waitForAngularIdle)(page);
|
|
79
|
+
}
|
|
80
|
+
async upsertItem(ctx, page, item, keyField, params) {
|
|
81
|
+
const key = String(item[keyField] ?? '');
|
|
82
|
+
let exists = true;
|
|
83
|
+
try {
|
|
84
|
+
await (0, grid_steps_1.selectGridRow)(page, { rowId: key }, 'Szerkesztés');
|
|
85
|
+
await (0, wait_1.waitForAngularIdle)(page);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// selectGridRow throws if the row cannot be located (e.g. Playwright timeout).
|
|
89
|
+
// Treat any failure here as "not found" and fall through to insert.
|
|
90
|
+
exists = false;
|
|
91
|
+
}
|
|
92
|
+
if (exists) {
|
|
93
|
+
const form = (0, dialog_steps_1.topDialog)(page);
|
|
94
|
+
await this.fillFields(form, item);
|
|
95
|
+
this.save(ctx, page, item);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
await this.insertItem(ctx, page, item, params);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Fills every field of `item` for which a widget can be found. Fields with no matching
|
|
103
|
+
* widget are skipped with a `console.warn` so the author notices without the run failing.
|
|
104
|
+
*/
|
|
105
|
+
async fillFields(form, item) {
|
|
106
|
+
for (const [key, value] of Object.entries(item)) {
|
|
107
|
+
await this.fillField(form, key, value);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Override this in a subclass to handle special per-field mapping
|
|
112
|
+
* (split one item field into multiple form fields, merge several into one,
|
|
113
|
+
* open a detail dialog for a field, etc.). Call `super.fillField(...)` for
|
|
114
|
+
* fields you do NOT need to customise.
|
|
115
|
+
*/
|
|
116
|
+
async fillField(form, key, value) {
|
|
117
|
+
if (!(await (0, forms_1.hasField)(form, key))) {
|
|
118
|
+
console.warn(`BasicScreenProcessor: no widget for field '${key}' on this screen — skipping`);
|
|
119
|
+
}
|
|
120
|
+
await (0, forms_1.setField)(form, key, value);
|
|
121
|
+
}
|
|
122
|
+
async save(ctx, page, item) {
|
|
123
|
+
await (0, locators_1.findButton)(page, SAVE_LABELS).click();
|
|
124
|
+
await (0, wait_1.waitForAngularIdle)(page);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
exports.BasicScreenProcessor = BasicScreenProcessor;
|
|
128
|
+
//# sourceMappingURL=basic-screen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"basic-screen.js","sourceRoot":"","sources":["../../../src/basedata/processors/basic-screen.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BaseDataProcessor, SessionController, TypeBundle } from './types';
|
|
2
|
+
export declare function registerProcessor(name: string, processor: BaseDataProcessor): void;
|
|
3
|
+
export declare function getProcessor(name: string): BaseDataProcessor;
|
|
4
|
+
export declare function resetProcessors(): void;
|
|
5
|
+
export declare function registerSessionController(name: string, controller: SessionController): void;
|
|
6
|
+
export declare function getSessionController(name: string): SessionController;
|
|
7
|
+
export declare function resetSessionControllers(): void;
|
|
8
|
+
export declare function registerType(name: string, bundle: TypeBundle): void;
|
|
9
|
+
export declare function getType(name: string): TypeBundle | undefined;
|
|
10
|
+
export declare function resetTypes(): void;
|
|
11
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/basedata/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAMhF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,GAAG,IAAI,CAElF;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAM5D;AAED,wBAAgB,eAAe,IAAI,IAAI,CAEtC;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,iBAAiB,GAAG,IAAI,CAE3F;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAMpE;AAED,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAEnE;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAE5D;AAED,wBAAgB,UAAU,IAAI,IAAI,CAEjC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerProcessor = registerProcessor;
|
|
4
|
+
exports.getProcessor = getProcessor;
|
|
5
|
+
exports.resetProcessors = resetProcessors;
|
|
6
|
+
exports.registerSessionController = registerSessionController;
|
|
7
|
+
exports.getSessionController = getSessionController;
|
|
8
|
+
exports.resetSessionControllers = resetSessionControllers;
|
|
9
|
+
exports.registerType = registerType;
|
|
10
|
+
exports.getType = getType;
|
|
11
|
+
exports.resetTypes = resetTypes;
|
|
12
|
+
const processors = new Map();
|
|
13
|
+
const sessionControllers = new Map();
|
|
14
|
+
const types = new Map();
|
|
15
|
+
function registerProcessor(name, processor) {
|
|
16
|
+
processors.set(name, processor);
|
|
17
|
+
}
|
|
18
|
+
function getProcessor(name) {
|
|
19
|
+
const p = processors.get(name);
|
|
20
|
+
if (!p) {
|
|
21
|
+
throw new Error(`No BaseDataProcessor registered with name '${name}'. Call registerProcessor() before runChangelog().`);
|
|
22
|
+
}
|
|
23
|
+
return p;
|
|
24
|
+
}
|
|
25
|
+
function resetProcessors() {
|
|
26
|
+
processors.clear();
|
|
27
|
+
}
|
|
28
|
+
function registerSessionController(name, controller) {
|
|
29
|
+
sessionControllers.set(name, controller);
|
|
30
|
+
}
|
|
31
|
+
function getSessionController(name) {
|
|
32
|
+
const c = sessionControllers.get(name);
|
|
33
|
+
if (!c) {
|
|
34
|
+
throw new Error(`No SessionController registered with name '${name}'. Call registerSessionController() before runChangelog().`);
|
|
35
|
+
}
|
|
36
|
+
return c;
|
|
37
|
+
}
|
|
38
|
+
function resetSessionControllers() {
|
|
39
|
+
sessionControllers.clear();
|
|
40
|
+
}
|
|
41
|
+
function registerType(name, bundle) {
|
|
42
|
+
types.set(name, bundle);
|
|
43
|
+
}
|
|
44
|
+
function getType(name) {
|
|
45
|
+
return types.get(name);
|
|
46
|
+
}
|
|
47
|
+
function resetTypes() {
|
|
48
|
+
types.clear();
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/basedata/registry.ts"],"names":[],"mappings":";;AAMA,8CAEC;AAED,oCAMC;AAED,0CAEC;AAED,8DAEC;AAED,oDAMC;AAED,0DAEC;AAED,oCAEC;AAED,0BAEC;AAED,gCAEC;AA9CD,MAAM,UAAU,GAAG,IAAI,GAAG,EAA6B,CAAC;AACxD,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAA6B,CAAC;AAChE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;AAE5C,SAAgB,iBAAiB,CAAC,IAAY,EAAE,SAA4B;IAC1E,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,SAAgB,YAAY,CAAC,IAAY;IACvC,MAAM,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,8CAA8C,IAAI,oDAAoD,CAAC,CAAC;IAC1H,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAgB,eAAe;IAC7B,UAAU,CAAC,KAAK,EAAE,CAAC;AACrB,CAAC;AAED,SAAgB,yBAAyB,CAAC,IAAY,EAAE,UAA6B;IACnF,kBAAkB,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;AAC3C,CAAC;AAED,SAAgB,oBAAoB,CAAC,IAAY;IAC/C,MAAM,CAAC,GAAG,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,8CAA8C,IAAI,4DAA4D,CAAC,CAAC;IAClI,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAgB,uBAAuB;IACrC,kBAAkB,CAAC,KAAK,EAAE,CAAC;AAC7B,CAAC;AAED,SAAgB,YAAY,CAAC,IAAY,EAAE,MAAkB;IAC3D,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC1B,CAAC;AAED,SAAgB,OAAO,CAAC,IAAY;IAClC,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC;AAED,SAAgB,UAAU;IACxB,KAAK,CAAC,KAAK,EAAE,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/basedata/runner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,mBAAmB,EACnB,kBAAkB,EAQnB,MAAM,SAAS,CAAC;AAkIjB,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CAgM7B"}
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.runChangelog = runChangelog;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const loader_1 = require("./loader");
|
|
40
|
+
const hash_1 = require("./hash");
|
|
41
|
+
const history_1 = require("./history");
|
|
42
|
+
const registry_1 = require("./registry");
|
|
43
|
+
/**
|
|
44
|
+
* Resolves the final processor + params for a tuple, consulting (in priority order):
|
|
45
|
+
* 1. explicit `changeSet.processor` / `changeSet.params`
|
|
46
|
+
* 2. enclosing manifest's `defaults.processor` / `defaults.params`
|
|
47
|
+
* 3. type registry — keyed by `changeSet.type` → `manifest.type` → `datapool.meta.entity`
|
|
48
|
+
*
|
|
49
|
+
* Params are shallow-merged: registry < manifest defaults < changeSet (later wins).
|
|
50
|
+
*/
|
|
51
|
+
function resolveProcessorAndParams(tuple, datapoolMeta) {
|
|
52
|
+
const typeName = tuple.changeSet.type ?? tuple.manifestType ?? datapoolMeta.entity;
|
|
53
|
+
const bundle = typeName ? (0, registry_1.getType)(typeName) : undefined;
|
|
54
|
+
const processor = tuple.changeSet.processor ??
|
|
55
|
+
tuple.manifestDefaults.processor ??
|
|
56
|
+
bundle?.processor;
|
|
57
|
+
if (!processor) {
|
|
58
|
+
throw new Error(`ChangeSet '${tuple.changeSet.id}' in '${tuple.manifestFile}' has no processor — ` +
|
|
59
|
+
`set changeSet.processor, manifest.defaults.processor, or register a type matching ` +
|
|
60
|
+
`'${typeName ?? '(no type or entity)'}'`);
|
|
61
|
+
}
|
|
62
|
+
const params = {
|
|
63
|
+
...(bundle?.params ?? {}),
|
|
64
|
+
...tuple.manifestDefaults.params,
|
|
65
|
+
...(tuple.changeSet.params ?? {}),
|
|
66
|
+
};
|
|
67
|
+
return { processor, params };
|
|
68
|
+
}
|
|
69
|
+
async function processChangeSet(tuple, history, options, masterBase, orderCounter, manifestCtx) {
|
|
70
|
+
const { manifestFile, sessionControllerName, changeSet, datapoolPath } = tuple;
|
|
71
|
+
const datapoolAbsPath = path.resolve(masterBase, datapoolPath);
|
|
72
|
+
const datapool = (0, loader_1.loadDatapoolFile)(datapoolAbsPath);
|
|
73
|
+
const datapoolContent = fs.readFileSync(datapoolAbsPath, 'utf-8');
|
|
74
|
+
const { processor: resolvedProcessorName, params: resolvedParams } = resolveProcessorAndParams(tuple, datapool.meta);
|
|
75
|
+
const checksum = (0, hash_1.computeChangeSetHash)(datapoolContent, resolvedProcessorName, resolvedParams, sessionControllerName ?? '');
|
|
76
|
+
const existing = (0, history_1.findHistoryEntry)(history, changeSet.id, changeSet.author, datapoolPath);
|
|
77
|
+
if (existing) {
|
|
78
|
+
// Hash check applies ONLY to successfully executed changeSets (Liquibase semantics):
|
|
79
|
+
// once a changeSet has been recorded as EXECUTED, its inputs are frozen. A FAILED
|
|
80
|
+
// entry represents work that did not commit, so the user is free to iterate on
|
|
81
|
+
// datapool/params/controller and retry — the next run uses the new hash.
|
|
82
|
+
if (existing.execType === 'EXECUTED') {
|
|
83
|
+
if (existing.checksum !== checksum) {
|
|
84
|
+
throw new Error(`Hash mismatch for executed changeSet '${changeSet.id}' by '${changeSet.author}' (file: ${datapoolPath}). ` +
|
|
85
|
+
`Recorded checksum: ${existing.checksum}, current: ${checksum}. ` +
|
|
86
|
+
`Modify the id/author to create a new changeSet, or revert the datapool/processor/params change.`);
|
|
87
|
+
}
|
|
88
|
+
return { entry: { ...existing }, outcome: 'skipped' };
|
|
89
|
+
}
|
|
90
|
+
// FAILED → fall through and re-run with the current (possibly new) hash
|
|
91
|
+
}
|
|
92
|
+
const processor = (0, registry_1.getProcessor)(resolvedProcessorName);
|
|
93
|
+
const operation = datapool.meta.operation ?? 'insert';
|
|
94
|
+
try {
|
|
95
|
+
const result = await processor.apply(datapool.items, operation, datapool.meta, resolvedParams, manifestCtx);
|
|
96
|
+
const execType = result.failed > 0 ? 'FAILED' : 'EXECUTED';
|
|
97
|
+
const entry = {
|
|
98
|
+
id: changeSet.id,
|
|
99
|
+
author: changeSet.author,
|
|
100
|
+
filename: datapoolPath,
|
|
101
|
+
manifestFile,
|
|
102
|
+
processor: resolvedProcessorName,
|
|
103
|
+
sessionController: sessionControllerName,
|
|
104
|
+
checksum,
|
|
105
|
+
dateExecuted: new Date().toISOString(),
|
|
106
|
+
orderExecuted: orderCounter.next(),
|
|
107
|
+
execType,
|
|
108
|
+
itemsTotal: datapool.items.length,
|
|
109
|
+
itemsSuccess: result.success,
|
|
110
|
+
itemsFailed: result.failed,
|
|
111
|
+
errors: result.errors,
|
|
112
|
+
};
|
|
113
|
+
return { entry, outcome: execType === 'EXECUTED' ? 'executed' : 'failed' };
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
const entry = {
|
|
117
|
+
id: changeSet.id,
|
|
118
|
+
author: changeSet.author,
|
|
119
|
+
filename: datapoolPath,
|
|
120
|
+
manifestFile,
|
|
121
|
+
processor: resolvedProcessorName,
|
|
122
|
+
sessionController: sessionControllerName,
|
|
123
|
+
checksum,
|
|
124
|
+
dateExecuted: new Date().toISOString(),
|
|
125
|
+
orderExecuted: orderCounter.next(),
|
|
126
|
+
execType: 'FAILED',
|
|
127
|
+
itemsTotal: datapool.items.length,
|
|
128
|
+
itemsSuccess: 0,
|
|
129
|
+
itemsFailed: datapool.items.length,
|
|
130
|
+
errors: [{ key: changeSet.id, error: err instanceof Error ? err.message : String(err) }],
|
|
131
|
+
};
|
|
132
|
+
return { entry, outcome: 'failed' };
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async function runChangelog(masterPath, options) {
|
|
136
|
+
const masterAbsPath = path.resolve(masterPath);
|
|
137
|
+
const masterBase = path.dirname(masterAbsPath);
|
|
138
|
+
await (0, history_1.acquireLock)(options.historyFile);
|
|
139
|
+
try {
|
|
140
|
+
const { tuples: resolved, visitedChangelogs } = (0, loader_1.resolveChangelog)(masterAbsPath, masterBase);
|
|
141
|
+
// Validate referenced session controllers exist (fail fast before any apply)
|
|
142
|
+
const distinctControllers = new Set(resolved.map(t => t.sessionControllerName).filter((n) => !!n));
|
|
143
|
+
for (const name of distinctControllers) {
|
|
144
|
+
(0, registry_1.getSessionController)(name); // throws if missing
|
|
145
|
+
}
|
|
146
|
+
const history = (0, history_1.readHistory)(options.historyFile);
|
|
147
|
+
const orderCounter = (() => {
|
|
148
|
+
let n = history.entries.length > 0 ? Math.max(...history.entries.map(e => e.orderExecuted)) + 1 : 1;
|
|
149
|
+
return { next: () => n++ };
|
|
150
|
+
})();
|
|
151
|
+
let executed = 0;
|
|
152
|
+
let skipped = 0;
|
|
153
|
+
let failed = 0;
|
|
154
|
+
const entries = [];
|
|
155
|
+
const warnings = [];
|
|
156
|
+
// Frozen-changelog check: for each visited changelog, compare against recorded fingerprint.
|
|
157
|
+
// Rules:
|
|
158
|
+
// - Master (entry-point) changelog: append-only at the end. The recorded includeList
|
|
159
|
+
// must be a prefix of the current includeList; anything else (reorder, mid-insert,
|
|
160
|
+
// removal) is an error.
|
|
161
|
+
// - Included (transitive) changelog: fully frozen once recorded. Any fingerprint
|
|
162
|
+
// difference is an error.
|
|
163
|
+
for (const visited of visitedChangelogs) {
|
|
164
|
+
const recorded = history.changelogs.find(c => c.path === visited.path);
|
|
165
|
+
if (!recorded)
|
|
166
|
+
continue;
|
|
167
|
+
if (recorded.includeFingerprint === visited.includeFingerprint)
|
|
168
|
+
continue;
|
|
169
|
+
if (visited.isMaster) {
|
|
170
|
+
const isPrefix = recorded.includeList.length <= visited.includeList.length &&
|
|
171
|
+
recorded.includeList.every((entry, i) => entry === visited.includeList[i]);
|
|
172
|
+
if (!isPrefix) {
|
|
173
|
+
throw new Error(`Master changelog '${visited.path}' was previously executed on ${recorded.lastRun}; ` +
|
|
174
|
+
`existing entries may not be reordered, removed, or replaced — only new entries appended at the end. ` +
|
|
175
|
+
`Recorded: [${recorded.includeList.join(', ')}], current: [${visited.includeList.join(', ')}].`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
throw new Error(`Included changelog '${visited.path}' was previously executed on ${recorded.lastRun} and is frozen; ` +
|
|
180
|
+
`it cannot be modified. Add new manifests under a new changelog, then include that new changelog ` +
|
|
181
|
+
`as a sibling in the master changelog.`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// Group resolved tuples by consecutive (manifestFile, manifestName). The manifest
|
|
185
|
+
// is the session boundary: two adjacent inline manifests in the same changelog file
|
|
186
|
+
// share manifestFile but have different manifestName, so they get separate groups.
|
|
187
|
+
let i = 0;
|
|
188
|
+
while (i < resolved.length) {
|
|
189
|
+
const groupManifestFile = resolved[i].manifestFile;
|
|
190
|
+
const groupManifestName = resolved[i].manifestName;
|
|
191
|
+
const group = [];
|
|
192
|
+
while (i < resolved.length &&
|
|
193
|
+
resolved[i].manifestFile === groupManifestFile &&
|
|
194
|
+
resolved[i].manifestName === groupManifestName) {
|
|
195
|
+
group.push(resolved[i]);
|
|
196
|
+
i++;
|
|
197
|
+
}
|
|
198
|
+
const sessionName = group[0].sessionControllerName;
|
|
199
|
+
const useSession = !!sessionName;
|
|
200
|
+
// Fresh per-manifest scratchpad. Spread (don't mutate) the caller's context so
|
|
201
|
+
// `manifest` is scoped to this group and isolated from sibling manifests.
|
|
202
|
+
const manifestCtx = { ...options.context, manifest: new Map() };
|
|
203
|
+
if (useSession) {
|
|
204
|
+
// Determine whether any tuple in the group needs work (not already EXECUTED with matching hash)
|
|
205
|
+
let anyPending = false;
|
|
206
|
+
for (const tuple of group) {
|
|
207
|
+
const existing = (0, history_1.findHistoryEntry)(history, tuple.changeSet.id, tuple.changeSet.author, tuple.datapoolPath);
|
|
208
|
+
if (!existing || existing.execType !== 'EXECUTED') {
|
|
209
|
+
anyPending = true;
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
const datapoolAbsPath = path.resolve(masterBase, tuple.datapoolPath);
|
|
213
|
+
const datapool = (0, loader_1.loadDatapoolFile)(datapoolAbsPath);
|
|
214
|
+
const datapoolContent = fs.readFileSync(datapoolAbsPath, 'utf-8');
|
|
215
|
+
const { processor: resolvedProcessor, params: resolvedP } = resolveProcessorAndParams(tuple, datapool.meta);
|
|
216
|
+
const expected = (0, hash_1.computeChangeSetHash)(datapoolContent, resolvedProcessor, resolvedP, tuple.sessionControllerName ?? '');
|
|
217
|
+
if (existing.checksum !== expected) {
|
|
218
|
+
anyPending = true;
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
if (!anyPending) {
|
|
223
|
+
// All tuples are already-EXECUTED-with-matching-hash; just record skips and move on
|
|
224
|
+
for (const tuple of group) {
|
|
225
|
+
const { entry, outcome } = await processChangeSet(tuple, history, options, masterBase, orderCounter, manifestCtx);
|
|
226
|
+
entries.push(entry);
|
|
227
|
+
if (outcome === 'skipped')
|
|
228
|
+
skipped++;
|
|
229
|
+
}
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
const controller = (0, registry_1.getSessionController)(sessionName);
|
|
233
|
+
await controller.start(manifestCtx);
|
|
234
|
+
let sessionFailed = false;
|
|
235
|
+
let hashMismatchError;
|
|
236
|
+
for (const tuple of group) {
|
|
237
|
+
try {
|
|
238
|
+
const { entry, outcome } = await processChangeSet(tuple, history, options, masterBase, orderCounter, manifestCtx);
|
|
239
|
+
(0, history_1.upsertHistoryEntry)(history, entry);
|
|
240
|
+
entries.push({ ...entry });
|
|
241
|
+
if (outcome === 'executed')
|
|
242
|
+
executed++;
|
|
243
|
+
else if (outcome === 'skipped')
|
|
244
|
+
skipped++;
|
|
245
|
+
else {
|
|
246
|
+
failed++;
|
|
247
|
+
sessionFailed = true;
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
catch (err) {
|
|
252
|
+
sessionFailed = true;
|
|
253
|
+
hashMismatchError = err instanceof Error ? err : new Error(String(err));
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
// Close the session before propagating any error: rollback gets a chance to run
|
|
258
|
+
// even on hash-mismatch, then history is written, then the error rethrows.
|
|
259
|
+
if (sessionFailed) {
|
|
260
|
+
try {
|
|
261
|
+
await controller.rollback(manifestCtx);
|
|
262
|
+
}
|
|
263
|
+
catch (rbErr) {
|
|
264
|
+
console.warn(`SessionController.rollback failed: ${rbErr instanceof Error ? rbErr.message : String(rbErr)}`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
await controller.commit(manifestCtx);
|
|
269
|
+
}
|
|
270
|
+
if (hashMismatchError) {
|
|
271
|
+
history.lastRun = new Date().toISOString();
|
|
272
|
+
(0, history_1.writeHistory)(options.historyFile, history);
|
|
273
|
+
throw hashMismatchError;
|
|
274
|
+
}
|
|
275
|
+
if (sessionFailed && options.stopOnFailure) {
|
|
276
|
+
history.lastRun = new Date().toISOString();
|
|
277
|
+
(0, history_1.writeHistory)(options.historyFile, history);
|
|
278
|
+
return { executed, skipped, failed, entries, warnings };
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
// No session — run tuples normally
|
|
283
|
+
for (const tuple of group) {
|
|
284
|
+
const { entry, outcome } = await processChangeSet(tuple, history, options, masterBase, orderCounter, manifestCtx);
|
|
285
|
+
(0, history_1.upsertHistoryEntry)(history, entry);
|
|
286
|
+
entries.push({ ...entry });
|
|
287
|
+
if (outcome === 'executed')
|
|
288
|
+
executed++;
|
|
289
|
+
else if (outcome === 'skipped')
|
|
290
|
+
skipped++;
|
|
291
|
+
else {
|
|
292
|
+
failed++;
|
|
293
|
+
if (options.stopOnFailure) {
|
|
294
|
+
history.lastRun = new Date().toISOString();
|
|
295
|
+
(0, history_1.writeHistory)(options.historyFile, history);
|
|
296
|
+
return { executed, skipped, failed, entries, warnings };
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
const now = new Date().toISOString();
|
|
303
|
+
// Record visited changelogs ONLY if the entire run completed without failures.
|
|
304
|
+
// This mirrors Liquibase: a failed run leaves no "frozen" marker, so the user
|
|
305
|
+
// can keep iterating on the changelog structure until everything actually runs.
|
|
306
|
+
if (failed === 0) {
|
|
307
|
+
for (const visited of visitedChangelogs) {
|
|
308
|
+
(0, history_1.upsertChangelogRecord)(history, {
|
|
309
|
+
path: visited.path,
|
|
310
|
+
lastRun: now,
|
|
311
|
+
includeList: visited.includeList,
|
|
312
|
+
includeFingerprint: visited.includeFingerprint,
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
history.lastRun = now;
|
|
317
|
+
(0, history_1.writeHistory)(options.historyFile, history);
|
|
318
|
+
return { executed, skipped, failed, entries, warnings };
|
|
319
|
+
}
|
|
320
|
+
finally {
|
|
321
|
+
(0, history_1.releaseLock)(options.historyFile);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/basedata/runner.ts"],"names":[],"mappings":"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"}
|