@contember/migrations-client 2.1.0-rc.3 → 2.2.0-alpha.10
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/dist/development/index.cjs +4 -0
- package/dist/development/index.cjs.map +1 -1
- package/dist/development/index.js +4 -0
- package/dist/development/index.js.map +1 -1
- package/dist/development/src/JsLoader.cjs.map +1 -1
- package/dist/development/src/JsLoader.js.map +1 -1
- package/dist/development/src/JsonLoader.cjs.map +1 -1
- package/dist/development/src/JsonLoader.js.map +1 -1
- package/dist/development/src/MigrationCreator.cjs +3 -3
- package/dist/development/src/MigrationCreator.cjs.map +1 -1
- package/dist/development/src/MigrationCreator.js +3 -3
- package/dist/development/src/MigrationCreator.js.map +1 -1
- package/dist/development/src/MigrationExecuteHelper.cjs +14 -5
- package/dist/development/src/MigrationExecuteHelper.cjs.map +1 -1
- package/dist/development/src/MigrationExecuteHelper.js +14 -5
- package/dist/development/src/MigrationExecuteHelper.js.map +1 -1
- package/dist/development/src/MigrationFile.cjs.map +1 -1
- package/dist/development/src/MigrationFile.js.map +1 -1
- package/dist/development/src/MigrationFilesManager.cjs +11 -11
- package/dist/development/src/MigrationFilesManager.cjs.map +1 -1
- package/dist/development/src/MigrationFilesManager.js.map +1 -1
- package/dist/development/src/MigrationParser.cjs.map +1 -1
- package/dist/development/src/MigrationParser.js.map +1 -1
- package/dist/development/src/MigrationsResolver.cjs.map +1 -1
- package/dist/development/src/MigrationsResolver.js.map +1 -1
- package/dist/development/src/SchemaStateManager.cjs +82 -0
- package/dist/development/src/SchemaStateManager.cjs.map +1 -0
- package/dist/development/src/SchemaStateManager.js +64 -0
- package/dist/development/src/SchemaStateManager.js.map +1 -0
- package/dist/development/src/SchemaVersionBuilder.cjs +28 -4
- package/dist/development/src/SchemaVersionBuilder.cjs.map +1 -1
- package/dist/development/src/SchemaVersionBuilder.js +28 -4
- package/dist/development/src/SchemaVersionBuilder.js.map +1 -1
- package/dist/development/src/SnapshotManager.cjs +46 -0
- package/dist/development/src/SnapshotManager.cjs.map +1 -0
- package/dist/development/src/SnapshotManager.js +29 -0
- package/dist/development/src/SnapshotManager.js.map +1 -0
- package/dist/development/src/SystemClient.cjs +29 -4
- package/dist/development/src/SystemClient.cjs.map +1 -1
- package/dist/development/src/SystemClient.js +29 -4
- package/dist/development/src/SystemClient.js.map +1 -1
- package/dist/development/src/migrations.cjs.map +1 -1
- package/dist/development/src/migrations.js.map +1 -1
- package/dist/production/index.cjs +4 -0
- package/dist/production/index.cjs.map +1 -1
- package/dist/production/index.js +4 -0
- package/dist/production/index.js.map +1 -1
- package/dist/production/src/JsLoader.cjs.map +1 -1
- package/dist/production/src/JsLoader.js.map +1 -1
- package/dist/production/src/JsonLoader.cjs.map +1 -1
- package/dist/production/src/JsonLoader.js.map +1 -1
- package/dist/production/src/MigrationCreator.cjs +3 -3
- package/dist/production/src/MigrationCreator.cjs.map +1 -1
- package/dist/production/src/MigrationCreator.js +3 -3
- package/dist/production/src/MigrationCreator.js.map +1 -1
- package/dist/production/src/MigrationExecuteHelper.cjs +14 -5
- package/dist/production/src/MigrationExecuteHelper.cjs.map +1 -1
- package/dist/production/src/MigrationExecuteHelper.js +14 -5
- package/dist/production/src/MigrationExecuteHelper.js.map +1 -1
- package/dist/production/src/MigrationFile.cjs.map +1 -1
- package/dist/production/src/MigrationFile.js.map +1 -1
- package/dist/production/src/MigrationFilesManager.cjs +11 -11
- package/dist/production/src/MigrationFilesManager.cjs.map +1 -1
- package/dist/production/src/MigrationFilesManager.js.map +1 -1
- package/dist/production/src/MigrationParser.cjs.map +1 -1
- package/dist/production/src/MigrationParser.js.map +1 -1
- package/dist/production/src/MigrationsResolver.cjs.map +1 -1
- package/dist/production/src/MigrationsResolver.js.map +1 -1
- package/dist/production/src/SchemaStateManager.cjs +82 -0
- package/dist/production/src/SchemaStateManager.cjs.map +1 -0
- package/dist/production/src/SchemaStateManager.js +64 -0
- package/dist/production/src/SchemaStateManager.js.map +1 -0
- package/dist/production/src/SchemaVersionBuilder.cjs +28 -4
- package/dist/production/src/SchemaVersionBuilder.cjs.map +1 -1
- package/dist/production/src/SchemaVersionBuilder.js +28 -4
- package/dist/production/src/SchemaVersionBuilder.js.map +1 -1
- package/dist/production/src/SnapshotManager.cjs +46 -0
- package/dist/production/src/SnapshotManager.cjs.map +1 -0
- package/dist/production/src/SnapshotManager.js +29 -0
- package/dist/production/src/SnapshotManager.js.map +1 -0
- package/dist/production/src/SystemClient.cjs +29 -4
- package/dist/production/src/SystemClient.cjs.map +1 -1
- package/dist/production/src/SystemClient.js +29 -4
- package/dist/production/src/SystemClient.js.map +1 -1
- package/dist/production/src/migrations.cjs.map +1 -1
- package/dist/production/src/migrations.js.map +1 -1
- package/dist/types/JsLoader.d.ts +3 -3
- package/dist/types/JsLoader.d.ts.map +1 -1
- package/dist/types/JsonLoader.d.ts +4 -4
- package/dist/types/JsonLoader.d.ts.map +1 -1
- package/dist/types/MigrationCreator.d.ts +4 -2
- package/dist/types/MigrationCreator.d.ts.map +1 -1
- package/dist/types/MigrationExecuteHelper.d.ts +6 -4
- package/dist/types/MigrationExecuteHelper.d.ts.map +1 -1
- package/dist/types/MigrationFile.d.ts +2 -2
- package/dist/types/MigrationFile.d.ts.map +1 -1
- package/dist/types/MigrationFileLoader.d.ts +1 -1
- package/dist/types/MigrationFileLoader.d.ts.map +1 -1
- package/dist/types/MigrationFilesManager.d.ts +2 -2
- package/dist/types/MigrationFilesManager.d.ts.map +1 -1
- package/dist/types/MigrationParser.d.ts +2 -2
- package/dist/types/MigrationParser.d.ts.map +1 -1
- package/dist/types/MigrationsResolver.d.ts +2 -2
- package/dist/types/MigrationsResolver.d.ts.map +1 -1
- package/dist/types/SchemaStateManager.d.ts +19 -0
- package/dist/types/SchemaStateManager.d.ts.map +1 -0
- package/dist/types/SchemaVersionBuilder.d.ts +10 -2
- package/dist/types/SchemaVersionBuilder.d.ts.map +1 -1
- package/dist/types/SnapshotManager.d.ts +31 -0
- package/dist/types/SnapshotManager.d.ts.map +1 -0
- package/dist/types/SystemClient.d.ts +11 -3
- package/dist/types/SystemClient.d.ts.map +1 -1
- package/dist/types/index.d.ts +14 -12
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/migrations.d.ts +1 -1
- package/dist/types/migrations.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
- package/src/JsLoader.ts +3 -3
- package/src/JsonLoader.ts +3 -3
- package/src/MigrationCreator.ts +8 -5
- package/src/MigrationExecuteHelper.ts +19 -8
- package/src/MigrationFile.ts +2 -2
- package/src/MigrationFileLoader.ts +1 -1
- package/src/MigrationFilesManager.ts +2 -2
- package/src/MigrationParser.ts +2 -2
- package/src/MigrationsResolver.ts +2 -2
- package/src/SchemaStateManager.ts +75 -0
- package/src/SchemaVersionBuilder.ts +35 -10
- package/src/SnapshotManager.ts +52 -0
- package/src/SystemClient.ts +41 -4
- package/src/index.ts +14 -12
- package/src/migrations.ts +1 -1
- package/tests/cases/unit/MigrationCreator.test.ts +50 -0
- package/tests/cases/unit/SchemaStateManager.test.ts +96 -0
- package/tests/cases/unit/SchemaVersionBuilder.test.ts +125 -0
- package/tests/cases/unit/SnapshotManager.test.ts +64 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const fs = require("node:fs/promises");
|
|
4
|
+
const path = require("node:path");
|
|
5
|
+
function _interopNamespaceDefault(e) {
|
|
6
|
+
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
7
|
+
if (e) {
|
|
8
|
+
for (const k in e) {
|
|
9
|
+
if (k !== "default") {
|
|
10
|
+
const d = Object.getOwnPropertyDescriptor(e, k);
|
|
11
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
get: () => e[k]
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
n.default = e;
|
|
19
|
+
return Object.freeze(n);
|
|
20
|
+
}
|
|
21
|
+
const fs__namespace = /* @__PURE__ */ _interopNamespaceDefault(fs);
|
|
22
|
+
const path__namespace = /* @__PURE__ */ _interopNamespaceDefault(path);
|
|
23
|
+
const stateFiles = ["acl", "validation", "actions", "settings"];
|
|
24
|
+
class SchemaStateManager {
|
|
25
|
+
constructor(stateDir) {
|
|
26
|
+
this.stateDir = stateDir;
|
|
27
|
+
}
|
|
28
|
+
async isStateMode() {
|
|
29
|
+
try {
|
|
30
|
+
const stat = await fs__namespace.stat(this.stateDir);
|
|
31
|
+
return stat.isDirectory();
|
|
32
|
+
} catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async readState() {
|
|
37
|
+
const state = {};
|
|
38
|
+
for (const key of stateFiles) {
|
|
39
|
+
const filePath = path__namespace.join(this.stateDir, `${key}.json`);
|
|
40
|
+
try {
|
|
41
|
+
const content = await fs__namespace.readFile(filePath, "utf8");
|
|
42
|
+
state[key] = JSON.parse(content);
|
|
43
|
+
} catch (e) {
|
|
44
|
+
throw new Error(`Failed to read schema state file ${filePath}: ${e instanceof Error ? e.message : e}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return state;
|
|
48
|
+
}
|
|
49
|
+
async writeState(state, { dryRun = false } = {}) {
|
|
50
|
+
let changed = false;
|
|
51
|
+
for (const key of stateFiles) {
|
|
52
|
+
const filePath = path__namespace.join(this.stateDir, `${key}.json`);
|
|
53
|
+
const newContent = JSON.stringify(state[key], void 0, " ") + "\n";
|
|
54
|
+
let currentContent = null;
|
|
55
|
+
try {
|
|
56
|
+
currentContent = await fs__namespace.readFile(filePath, "utf8");
|
|
57
|
+
} catch {
|
|
58
|
+
}
|
|
59
|
+
if (currentContent !== newContent) {
|
|
60
|
+
if (!dryRun) {
|
|
61
|
+
await fs__namespace.writeFile(filePath, newContent, "utf8");
|
|
62
|
+
}
|
|
63
|
+
changed = true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return changed;
|
|
67
|
+
}
|
|
68
|
+
async extractState(schema) {
|
|
69
|
+
await fs__namespace.mkdir(this.stateDir, { recursive: true });
|
|
70
|
+
await this.writeState(SchemaStateManager.schemaStateFromSchema(schema));
|
|
71
|
+
}
|
|
72
|
+
static schemaStateFromSchema(schema) {
|
|
73
|
+
return {
|
|
74
|
+
acl: schema.acl,
|
|
75
|
+
validation: schema.validation,
|
|
76
|
+
actions: schema.actions,
|
|
77
|
+
settings: schema.settings
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.SchemaStateManager = SchemaStateManager;
|
|
82
|
+
//# sourceMappingURL=SchemaStateManager.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaStateManager.cjs","sources":["../../../../packages/migrations-client/src/SchemaStateManager.ts"],"sourcesContent":["import { Acl, Actions, Schema, Settings, Validation } from '@contember/schema'\nimport * as fs from 'node:fs/promises'\nimport * as path from 'node:path'\n\nexport type SchemaState = {\n\tacl: Acl.Schema\n\tvalidation: Validation.Schema\n\tactions: Actions.Schema\n\tsettings: Settings.Schema\n}\n\nconst stateFiles = ['acl', 'validation', 'actions', 'settings'] as const\ntype StateKey = typeof stateFiles[number]\n\nexport class SchemaStateManager {\n\tconstructor(private readonly stateDir: string) {}\n\n\tasync isStateMode(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst stat = await fs.stat(this.stateDir)\n\t\t\treturn stat.isDirectory()\n\t\t} catch {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tasync readState(): Promise<SchemaState> {\n\t\tconst state: Partial<SchemaState> = {}\n\t\tfor (const key of stateFiles) {\n\t\t\tconst filePath = path.join(this.stateDir, `${key}.json`)\n\t\t\ttry {\n\t\t\t\tconst content = await fs.readFile(filePath, 'utf8')\n\t\t\t\tstate[key] = JSON.parse(content)\n\t\t\t} catch (e) {\n\t\t\t\tthrow new Error(`Failed to read schema state file ${filePath}: ${e instanceof Error ? e.message : e}`)\n\t\t\t}\n\t\t}\n\t\treturn state as SchemaState\n\t}\n\n\tasync writeState(state: SchemaState, { dryRun = false }: { dryRun?: boolean } = {}): Promise<boolean> {\n\t\tlet changed = false\n\t\tfor (const key of stateFiles) {\n\t\t\tconst filePath = path.join(this.stateDir, `${key}.json`)\n\t\t\tconst newContent = JSON.stringify(state[key], undefined, '\\t') + '\\n'\n\t\t\tlet currentContent: string | null = null\n\t\t\ttry {\n\t\t\t\tcurrentContent = await fs.readFile(filePath, 'utf8')\n\t\t\t} catch {\n\t\t\t\t// file doesn't exist yet\n\t\t\t}\n\t\t\tif (currentContent !== newContent) {\n\t\t\t\tif (!dryRun) {\n\t\t\t\t\tawait fs.writeFile(filePath, newContent, 'utf8')\n\t\t\t\t}\n\t\t\t\tchanged = true\n\t\t\t}\n\t\t}\n\t\treturn changed\n\t}\n\n\tasync extractState(schema: Schema): Promise<void> {\n\t\tawait fs.mkdir(this.stateDir, { recursive: true })\n\t\tawait this.writeState(SchemaStateManager.schemaStateFromSchema(schema))\n\t}\n\n\tstatic schemaStateFromSchema(schema: Schema): SchemaState {\n\t\treturn {\n\t\t\tacl: schema.acl,\n\t\t\tvalidation: schema.validation,\n\t\t\tactions: schema.actions,\n\t\t\tsettings: schema.settings,\n\t\t}\n\t}\n}\n"],"names":["fs","path"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAWA,MAAM,aAAa,CAAC,OAAO,cAAc,WAAW,UAAU;AAGvD,MAAM,mBAAmB;AAAA,EAC/B,YAA6B,UAAkB;AAAlB,SAAA,WAAA;AAAA,EAAmB;AAAA,EAEhD,MAAM,cAAgC;AACrC,QAAI;AACH,YAAM,OAAO,MAAMA,cAAG,KAAK,KAAK,QAAQ;AACxC,aAAO,KAAK,YAAA;AAAA,IACb,QAAQ;AACP,aAAO;AAAA,IACR;AAAA,EACD;AAAA,EAEA,MAAM,YAAkC;AACvC,UAAM,QAA8B,CAAA;AACpC,eAAW,OAAO,YAAY;AAC7B,YAAM,WAAWC,gBAAK,KAAK,KAAK,UAAU,GAAG,GAAG,OAAO;AACvD,UAAI;AACH,cAAM,UAAU,MAAMD,cAAG,SAAS,UAAU,MAAM;AAClD,cAAM,GAAG,IAAI,KAAK,MAAM,OAAO;AAAA,MAChC,SAAS,GAAG;AACX,cAAM,IAAI,MAAM,oCAAoC,QAAQ,KAAK,aAAa,QAAQ,EAAE,UAAU,CAAC,EAAE;AAAA,MACtG;AAAA,IACD;AACA,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,WAAW,OAAoB,EAAE,SAAS,MAAA,IAAgC,CAAA,GAAsB;AACrG,QAAI,UAAU;AACd,eAAW,OAAO,YAAY;AAC7B,YAAM,WAAWC,gBAAK,KAAK,KAAK,UAAU,GAAG,GAAG,OAAO;AACvD,YAAM,aAAa,KAAK,UAAU,MAAM,GAAG,GAAG,QAAW,GAAI,IAAI;AACjE,UAAI,iBAAgC;AACpC,UAAI;AACH,yBAAiB,MAAMD,cAAG,SAAS,UAAU,MAAM;AAAA,MACpD,QAAQ;AAAA,MAER;AACA,UAAI,mBAAmB,YAAY;AAClC,YAAI,CAAC,QAAQ;AACZ,gBAAMA,cAAG,UAAU,UAAU,YAAY,MAAM;AAAA,QAChD;AACA,kBAAU;AAAA,MACX;AAAA,IACD;AACA,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,aAAa,QAA+B;AACjD,UAAMA,cAAG,MAAM,KAAK,UAAU,EAAE,WAAW,MAAM;AACjD,UAAM,KAAK,WAAW,mBAAmB,sBAAsB,MAAM,CAAC;AAAA,EACvE;AAAA,EAEA,OAAO,sBAAsB,QAA6B;AACzD,WAAO;AAAA,MACN,KAAK,OAAO;AAAA,MACZ,YAAY,OAAO;AAAA,MACnB,SAAS,OAAO;AAAA,MAChB,UAAU,OAAO;AAAA,IAAA;AAAA,EAEnB;AACD;;"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
const stateFiles = ["acl", "validation", "actions", "settings"];
|
|
4
|
+
class SchemaStateManager {
|
|
5
|
+
constructor(stateDir) {
|
|
6
|
+
this.stateDir = stateDir;
|
|
7
|
+
}
|
|
8
|
+
async isStateMode() {
|
|
9
|
+
try {
|
|
10
|
+
const stat = await fs.stat(this.stateDir);
|
|
11
|
+
return stat.isDirectory();
|
|
12
|
+
} catch {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
async readState() {
|
|
17
|
+
const state = {};
|
|
18
|
+
for (const key of stateFiles) {
|
|
19
|
+
const filePath = path.join(this.stateDir, `${key}.json`);
|
|
20
|
+
try {
|
|
21
|
+
const content = await fs.readFile(filePath, "utf8");
|
|
22
|
+
state[key] = JSON.parse(content);
|
|
23
|
+
} catch (e) {
|
|
24
|
+
throw new Error(`Failed to read schema state file ${filePath}: ${e instanceof Error ? e.message : e}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return state;
|
|
28
|
+
}
|
|
29
|
+
async writeState(state, { dryRun = false } = {}) {
|
|
30
|
+
let changed = false;
|
|
31
|
+
for (const key of stateFiles) {
|
|
32
|
+
const filePath = path.join(this.stateDir, `${key}.json`);
|
|
33
|
+
const newContent = JSON.stringify(state[key], void 0, " ") + "\n";
|
|
34
|
+
let currentContent = null;
|
|
35
|
+
try {
|
|
36
|
+
currentContent = await fs.readFile(filePath, "utf8");
|
|
37
|
+
} catch {
|
|
38
|
+
}
|
|
39
|
+
if (currentContent !== newContent) {
|
|
40
|
+
if (!dryRun) {
|
|
41
|
+
await fs.writeFile(filePath, newContent, "utf8");
|
|
42
|
+
}
|
|
43
|
+
changed = true;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return changed;
|
|
47
|
+
}
|
|
48
|
+
async extractState(schema) {
|
|
49
|
+
await fs.mkdir(this.stateDir, { recursive: true });
|
|
50
|
+
await this.writeState(SchemaStateManager.schemaStateFromSchema(schema));
|
|
51
|
+
}
|
|
52
|
+
static schemaStateFromSchema(schema) {
|
|
53
|
+
return {
|
|
54
|
+
acl: schema.acl,
|
|
55
|
+
validation: schema.validation,
|
|
56
|
+
actions: schema.actions,
|
|
57
|
+
settings: schema.settings
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
export {
|
|
62
|
+
SchemaStateManager
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=SchemaStateManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaStateManager.js","sources":["../../../../packages/migrations-client/src/SchemaStateManager.ts"],"sourcesContent":["import { Acl, Actions, Schema, Settings, Validation } from '@contember/schema'\nimport * as fs from 'node:fs/promises'\nimport * as path from 'node:path'\n\nexport type SchemaState = {\n\tacl: Acl.Schema\n\tvalidation: Validation.Schema\n\tactions: Actions.Schema\n\tsettings: Settings.Schema\n}\n\nconst stateFiles = ['acl', 'validation', 'actions', 'settings'] as const\ntype StateKey = typeof stateFiles[number]\n\nexport class SchemaStateManager {\n\tconstructor(private readonly stateDir: string) {}\n\n\tasync isStateMode(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst stat = await fs.stat(this.stateDir)\n\t\t\treturn stat.isDirectory()\n\t\t} catch {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tasync readState(): Promise<SchemaState> {\n\t\tconst state: Partial<SchemaState> = {}\n\t\tfor (const key of stateFiles) {\n\t\t\tconst filePath = path.join(this.stateDir, `${key}.json`)\n\t\t\ttry {\n\t\t\t\tconst content = await fs.readFile(filePath, 'utf8')\n\t\t\t\tstate[key] = JSON.parse(content)\n\t\t\t} catch (e) {\n\t\t\t\tthrow new Error(`Failed to read schema state file ${filePath}: ${e instanceof Error ? e.message : e}`)\n\t\t\t}\n\t\t}\n\t\treturn state as SchemaState\n\t}\n\n\tasync writeState(state: SchemaState, { dryRun = false }: { dryRun?: boolean } = {}): Promise<boolean> {\n\t\tlet changed = false\n\t\tfor (const key of stateFiles) {\n\t\t\tconst filePath = path.join(this.stateDir, `${key}.json`)\n\t\t\tconst newContent = JSON.stringify(state[key], undefined, '\\t') + '\\n'\n\t\t\tlet currentContent: string | null = null\n\t\t\ttry {\n\t\t\t\tcurrentContent = await fs.readFile(filePath, 'utf8')\n\t\t\t} catch {\n\t\t\t\t// file doesn't exist yet\n\t\t\t}\n\t\t\tif (currentContent !== newContent) {\n\t\t\t\tif (!dryRun) {\n\t\t\t\t\tawait fs.writeFile(filePath, newContent, 'utf8')\n\t\t\t\t}\n\t\t\t\tchanged = true\n\t\t\t}\n\t\t}\n\t\treturn changed\n\t}\n\n\tasync extractState(schema: Schema): Promise<void> {\n\t\tawait fs.mkdir(this.stateDir, { recursive: true })\n\t\tawait this.writeState(SchemaStateManager.schemaStateFromSchema(schema))\n\t}\n\n\tstatic schemaStateFromSchema(schema: Schema): SchemaState {\n\t\treturn {\n\t\t\tacl: schema.acl,\n\t\t\tvalidation: schema.validation,\n\t\t\tactions: schema.actions,\n\t\t\tsettings: schema.settings,\n\t\t}\n\t}\n}\n"],"names":[],"mappings":";;AAWA,MAAM,aAAa,CAAC,OAAO,cAAc,WAAW,UAAU;AAGvD,MAAM,mBAAmB;AAAA,EAC/B,YAA6B,UAAkB;AAAlB,SAAA,WAAA;AAAA,EAAmB;AAAA,EAEhD,MAAM,cAAgC;AACrC,QAAI;AACH,YAAM,OAAO,MAAM,GAAG,KAAK,KAAK,QAAQ;AACxC,aAAO,KAAK,YAAA;AAAA,IACb,QAAQ;AACP,aAAO;AAAA,IACR;AAAA,EACD;AAAA,EAEA,MAAM,YAAkC;AACvC,UAAM,QAA8B,CAAA;AACpC,eAAW,OAAO,YAAY;AAC7B,YAAM,WAAW,KAAK,KAAK,KAAK,UAAU,GAAG,GAAG,OAAO;AACvD,UAAI;AACH,cAAM,UAAU,MAAM,GAAG,SAAS,UAAU,MAAM;AAClD,cAAM,GAAG,IAAI,KAAK,MAAM,OAAO;AAAA,MAChC,SAAS,GAAG;AACX,cAAM,IAAI,MAAM,oCAAoC,QAAQ,KAAK,aAAa,QAAQ,EAAE,UAAU,CAAC,EAAE;AAAA,MACtG;AAAA,IACD;AACA,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,WAAW,OAAoB,EAAE,SAAS,MAAA,IAAgC,CAAA,GAAsB;AACrG,QAAI,UAAU;AACd,eAAW,OAAO,YAAY;AAC7B,YAAM,WAAW,KAAK,KAAK,KAAK,UAAU,GAAG,GAAG,OAAO;AACvD,YAAM,aAAa,KAAK,UAAU,MAAM,GAAG,GAAG,QAAW,GAAI,IAAI;AACjE,UAAI,iBAAgC;AACpC,UAAI;AACH,yBAAiB,MAAM,GAAG,SAAS,UAAU,MAAM;AAAA,MACpD,QAAQ;AAAA,MAER;AACA,UAAI,mBAAmB,YAAY;AAClC,YAAI,CAAC,QAAQ;AACZ,gBAAM,GAAG,UAAU,UAAU,YAAY,MAAM;AAAA,QAChD;AACA,kBAAU;AAAA,MACX;AAAA,IACD;AACA,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,aAAa,QAA+B;AACjD,UAAM,GAAG,MAAM,KAAK,UAAU,EAAE,WAAW,MAAM;AACjD,UAAM,KAAK,WAAW,mBAAmB,sBAAsB,MAAM,CAAC;AAAA,EACvE;AAAA,EAEA,OAAO,sBAAsB,QAA6B;AACzD,WAAO;AAAA,MACN,KAAK,OAAO;AAAA,MACZ,YAAY,OAAO;AAAA,MACnB,SAAS,OAAO;AAAA,MAChB,UAAU,OAAO;AAAA,IAAA;AAAA,EAEnB;AACD;"}
|
|
@@ -1,22 +1,46 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const schemaUtils = require("@contember/schema-utils");
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, key + "", value);
|
|
4
7
|
class SchemaVersionBuilder {
|
|
5
|
-
constructor(migrationsResolver, schemaMigrator) {
|
|
8
|
+
constructor(migrationsResolver, schemaMigrator, schemaStateManager) {
|
|
6
9
|
this.migrationsResolver = migrationsResolver;
|
|
7
10
|
this.schemaMigrator = schemaMigrator;
|
|
11
|
+
this.schemaStateManager = schemaStateManager;
|
|
12
|
+
__publicField(this, "lastBuildUntil", null);
|
|
8
13
|
}
|
|
9
14
|
async buildSchema(targetVersion) {
|
|
10
|
-
|
|
15
|
+
let schema = await this.buildSchemaAdvanced(schemaUtils.emptySchema, (version) => !targetVersion || version <= targetVersion);
|
|
16
|
+
if (!targetVersion && await this.schemaStateManager.isStateMode()) {
|
|
17
|
+
const state = await this.schemaStateManager.readState();
|
|
18
|
+
schema = { ...schema, ...state };
|
|
19
|
+
}
|
|
20
|
+
return schema;
|
|
11
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Content migrations call this once each, with ascending versions. Continuing from the previous
|
|
24
|
+
* build keeps a run linear instead of replaying every schema migration from scratch each time.
|
|
25
|
+
*/
|
|
12
26
|
async buildSchemaUntil(targetVersion) {
|
|
13
|
-
|
|
27
|
+
const migrations = (await this.migrationsResolver.getSchemaMigrations()).filter(({ version }) => version < targetVersion);
|
|
28
|
+
const previous = this.lastBuildUntil;
|
|
29
|
+
const canContinue = previous !== null && previous.migrations.length <= migrations.length && previous.migrations.every((migration, index) => migration === migrations[index]);
|
|
30
|
+
const start = canContinue ? previous : { migrations: [], schema: schemaUtils.emptySchema };
|
|
31
|
+
const schema = this.applyMigrations(start.schema, migrations.slice(start.migrations.length));
|
|
32
|
+
this.lastBuildUntil = { migrations, schema };
|
|
33
|
+
return schema;
|
|
14
34
|
}
|
|
15
35
|
async continue(schema, previousVersion, targetVersion) {
|
|
16
36
|
return this.buildSchemaAdvanced(schema, (version) => version <= targetVersion && version > (previousVersion || ""));
|
|
17
37
|
}
|
|
18
38
|
async buildSchemaAdvanced(initialSchema, condition) {
|
|
19
|
-
|
|
39
|
+
const migrations = (await this.migrationsResolver.getSchemaMigrations()).filter(({ version }) => condition(version));
|
|
40
|
+
return this.applyMigrations(initialSchema, migrations);
|
|
41
|
+
}
|
|
42
|
+
applyMigrations(initialSchema, migrations) {
|
|
43
|
+
return migrations.reduce(
|
|
20
44
|
(schema, { modifications, formatVersion }) => this.schemaMigrator.applyModifications(schema, modifications, formatVersion),
|
|
21
45
|
initialSchema
|
|
22
46
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SchemaVersionBuilder.cjs","sources":["../../../../packages/migrations-client/src/SchemaVersionBuilder.ts"],"sourcesContent":["import { Schema } from '@contember/schema'\nimport { emptySchema } from '@contember/schema-utils'\nimport { SchemaMigrator } from '@contember/schema-migrations'\nimport { MigrationsResolver } from './MigrationsResolver'\n\nexport class SchemaVersionBuilder {\n\tconstructor(\n\t\tprivate readonly migrationsResolver: MigrationsResolver,\n\t\tprivate readonly schemaMigrator: SchemaMigrator,\n\t) {}\n\n\tasync buildSchema(targetVersion?: string): Promise<Schema> {\n\t\
|
|
1
|
+
{"version":3,"file":"SchemaVersionBuilder.cjs","sources":["../../../../packages/migrations-client/src/SchemaVersionBuilder.ts"],"sourcesContent":["import { Schema } from '@contember/schema'\nimport { emptySchema } from '@contember/schema-utils'\nimport { Migration, SchemaMigrator } from '@contember/schema-migrations'\nimport { MigrationsResolver } from './MigrationsResolver.js'\nimport { SchemaStateManager } from './SchemaStateManager.js'\n\nexport class SchemaVersionBuilder {\n\tprivate lastBuildUntil: { migrations: Migration[]; schema: Schema } | null = null\n\n\tconstructor(\n\t\tprivate readonly migrationsResolver: MigrationsResolver,\n\t\tprivate readonly schemaMigrator: SchemaMigrator,\n\t\tprivate readonly schemaStateManager: SchemaStateManager,\n\t) {}\n\n\tasync buildSchema(targetVersion?: string): Promise<Schema> {\n\t\tlet schema = await this.buildSchemaAdvanced(emptySchema, version => !targetVersion || version <= targetVersion)\n\t\tif (!targetVersion && await this.schemaStateManager.isStateMode()) {\n\t\t\tconst state = await this.schemaStateManager.readState()\n\t\t\tschema = { ...schema, ...state }\n\t\t}\n\t\treturn schema\n\t}\n\n\t/**\n\t * Content migrations call this once each, with ascending versions. Continuing from the previous\n\t * build keeps a run linear instead of replaying every schema migration from scratch each time.\n\t */\n\tasync buildSchemaUntil(targetVersion: string): Promise<Schema> {\n\t\tconst migrations = (await this.migrationsResolver.getSchemaMigrations()).filter(({ version }) => version < targetVersion)\n\t\tconst previous = this.lastBuildUntil\n\t\tconst canContinue = previous !== null\n\t\t\t&& previous.migrations.length <= migrations.length\n\t\t\t&& previous.migrations.every((migration, index) => migration === migrations[index])\n\t\tconst start = canContinue ? previous : { migrations: [], schema: emptySchema }\n\n\t\tconst schema = this.applyMigrations(start.schema, migrations.slice(start.migrations.length))\n\t\tthis.lastBuildUntil = { migrations, schema }\n\t\treturn schema\n\t}\n\n\tasync continue(schema: Schema, previousVersion: string | null, targetVersion: string): Promise<Schema> {\n\t\treturn this.buildSchemaAdvanced(schema, version => version <= targetVersion && version > (previousVersion || ''))\n\t}\n\n\tpublic async buildSchemaAdvanced(initialSchema: Schema, condition: (version: string) => boolean): Promise<Schema> {\n\t\tconst migrations = (await this.migrationsResolver.getSchemaMigrations()).filter(({ version }) => condition(version))\n\t\treturn this.applyMigrations(initialSchema, migrations)\n\t}\n\n\tprivate applyMigrations(initialSchema: Schema, migrations: Migration[]): Schema {\n\t\treturn migrations.reduce<Schema>(\n\t\t\t(schema, { modifications, formatVersion }) => this.schemaMigrator.applyModifications(schema, modifications, formatVersion),\n\t\t\tinitialSchema,\n\t\t)\n\t}\n}\n"],"names":["emptySchema"],"mappings":";;;;;;AAMO,MAAM,qBAAqB;AAAA,EAGjC,YACkB,oBACA,gBACA,oBAChB;AAHgB,SAAA,qBAAA;AACA,SAAA,iBAAA;AACA,SAAA,qBAAA;AALlB,kBAAA,MAAQ,kBAAqE,IAAA;AAAA,EAM1E;AAAA,EAEH,MAAM,YAAY,eAAyC;AAC1D,QAAI,SAAS,MAAM,KAAK,oBAAoBA,YAAAA,aAAa,CAAA,YAAW,CAAC,iBAAiB,WAAW,aAAa;AAC9G,QAAI,CAAC,iBAAiB,MAAM,KAAK,mBAAmB,eAAe;AAClE,YAAM,QAAQ,MAAM,KAAK,mBAAmB,UAAA;AAC5C,eAAS,EAAE,GAAG,QAAQ,GAAG,MAAA;AAAA,IAC1B;AACA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,iBAAiB,eAAwC;AAC9D,UAAM,cAAc,MAAM,KAAK,mBAAmB,oBAAA,GAAuB,OAAO,CAAC,EAAE,cAAc,UAAU,aAAa;AACxH,UAAM,WAAW,KAAK;AACtB,UAAM,cAAc,aAAa,QAC7B,SAAS,WAAW,UAAU,WAAW,UACzC,SAAS,WAAW,MAAM,CAAC,WAAW,UAAU,cAAc,WAAW,KAAK,CAAC;AACnF,UAAM,QAAQ,cAAc,WAAW,EAAE,YAAY,CAAA,GAAI,QAAQA,wBAAA;AAEjE,UAAM,SAAS,KAAK,gBAAgB,MAAM,QAAQ,WAAW,MAAM,MAAM,WAAW,MAAM,CAAC;AAC3F,SAAK,iBAAiB,EAAE,YAAY,OAAA;AACpC,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,SAAS,QAAgB,iBAAgC,eAAwC;AACtG,WAAO,KAAK,oBAAoB,QAAQ,CAAA,YAAW,WAAW,iBAAiB,WAAW,mBAAmB,GAAG;AAAA,EACjH;AAAA,EAEA,MAAa,oBAAoB,eAAuB,WAA0D;AACjH,UAAM,cAAc,MAAM,KAAK,mBAAmB,oBAAA,GAAuB,OAAO,CAAC,EAAE,QAAA,MAAc,UAAU,OAAO,CAAC;AACnH,WAAO,KAAK,gBAAgB,eAAe,UAAU;AAAA,EACtD;AAAA,EAEQ,gBAAgB,eAAuB,YAAiC;AAC/E,WAAO,WAAW;AAAA,MACjB,CAAC,QAAQ,EAAE,eAAe,oBAAoB,KAAK,eAAe,mBAAmB,QAAQ,eAAe,aAAa;AAAA,MACzH;AAAA,IAAA;AAAA,EAEF;AACD;;"}
|
|
@@ -1,20 +1,44 @@
|
|
|
1
1
|
import { emptySchema } from "@contember/schema-utils";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, key + "", value);
|
|
2
5
|
class SchemaVersionBuilder {
|
|
3
|
-
constructor(migrationsResolver, schemaMigrator) {
|
|
6
|
+
constructor(migrationsResolver, schemaMigrator, schemaStateManager) {
|
|
4
7
|
this.migrationsResolver = migrationsResolver;
|
|
5
8
|
this.schemaMigrator = schemaMigrator;
|
|
9
|
+
this.schemaStateManager = schemaStateManager;
|
|
10
|
+
__publicField(this, "lastBuildUntil", null);
|
|
6
11
|
}
|
|
7
12
|
async buildSchema(targetVersion) {
|
|
8
|
-
|
|
13
|
+
let schema = await this.buildSchemaAdvanced(emptySchema, (version) => !targetVersion || version <= targetVersion);
|
|
14
|
+
if (!targetVersion && await this.schemaStateManager.isStateMode()) {
|
|
15
|
+
const state = await this.schemaStateManager.readState();
|
|
16
|
+
schema = { ...schema, ...state };
|
|
17
|
+
}
|
|
18
|
+
return schema;
|
|
9
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Content migrations call this once each, with ascending versions. Continuing from the previous
|
|
22
|
+
* build keeps a run linear instead of replaying every schema migration from scratch each time.
|
|
23
|
+
*/
|
|
10
24
|
async buildSchemaUntil(targetVersion) {
|
|
11
|
-
|
|
25
|
+
const migrations = (await this.migrationsResolver.getSchemaMigrations()).filter(({ version }) => version < targetVersion);
|
|
26
|
+
const previous = this.lastBuildUntil;
|
|
27
|
+
const canContinue = previous !== null && previous.migrations.length <= migrations.length && previous.migrations.every((migration, index) => migration === migrations[index]);
|
|
28
|
+
const start = canContinue ? previous : { migrations: [], schema: emptySchema };
|
|
29
|
+
const schema = this.applyMigrations(start.schema, migrations.slice(start.migrations.length));
|
|
30
|
+
this.lastBuildUntil = { migrations, schema };
|
|
31
|
+
return schema;
|
|
12
32
|
}
|
|
13
33
|
async continue(schema, previousVersion, targetVersion) {
|
|
14
34
|
return this.buildSchemaAdvanced(schema, (version) => version <= targetVersion && version > (previousVersion || ""));
|
|
15
35
|
}
|
|
16
36
|
async buildSchemaAdvanced(initialSchema, condition) {
|
|
17
|
-
|
|
37
|
+
const migrations = (await this.migrationsResolver.getSchemaMigrations()).filter(({ version }) => condition(version));
|
|
38
|
+
return this.applyMigrations(initialSchema, migrations);
|
|
39
|
+
}
|
|
40
|
+
applyMigrations(initialSchema, migrations) {
|
|
41
|
+
return migrations.reduce(
|
|
18
42
|
(schema, { modifications, formatVersion }) => this.schemaMigrator.applyModifications(schema, modifications, formatVersion),
|
|
19
43
|
initialSchema
|
|
20
44
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SchemaVersionBuilder.js","sources":["../../../../packages/migrations-client/src/SchemaVersionBuilder.ts"],"sourcesContent":["import { Schema } from '@contember/schema'\nimport { emptySchema } from '@contember/schema-utils'\nimport { SchemaMigrator } from '@contember/schema-migrations'\nimport { MigrationsResolver } from './MigrationsResolver'\n\nexport class SchemaVersionBuilder {\n\tconstructor(\n\t\tprivate readonly migrationsResolver: MigrationsResolver,\n\t\tprivate readonly schemaMigrator: SchemaMigrator,\n\t) {}\n\n\tasync buildSchema(targetVersion?: string): Promise<Schema> {\n\t\
|
|
1
|
+
{"version":3,"file":"SchemaVersionBuilder.js","sources":["../../../../packages/migrations-client/src/SchemaVersionBuilder.ts"],"sourcesContent":["import { Schema } from '@contember/schema'\nimport { emptySchema } from '@contember/schema-utils'\nimport { Migration, SchemaMigrator } from '@contember/schema-migrations'\nimport { MigrationsResolver } from './MigrationsResolver.js'\nimport { SchemaStateManager } from './SchemaStateManager.js'\n\nexport class SchemaVersionBuilder {\n\tprivate lastBuildUntil: { migrations: Migration[]; schema: Schema } | null = null\n\n\tconstructor(\n\t\tprivate readonly migrationsResolver: MigrationsResolver,\n\t\tprivate readonly schemaMigrator: SchemaMigrator,\n\t\tprivate readonly schemaStateManager: SchemaStateManager,\n\t) {}\n\n\tasync buildSchema(targetVersion?: string): Promise<Schema> {\n\t\tlet schema = await this.buildSchemaAdvanced(emptySchema, version => !targetVersion || version <= targetVersion)\n\t\tif (!targetVersion && await this.schemaStateManager.isStateMode()) {\n\t\t\tconst state = await this.schemaStateManager.readState()\n\t\t\tschema = { ...schema, ...state }\n\t\t}\n\t\treturn schema\n\t}\n\n\t/**\n\t * Content migrations call this once each, with ascending versions. Continuing from the previous\n\t * build keeps a run linear instead of replaying every schema migration from scratch each time.\n\t */\n\tasync buildSchemaUntil(targetVersion: string): Promise<Schema> {\n\t\tconst migrations = (await this.migrationsResolver.getSchemaMigrations()).filter(({ version }) => version < targetVersion)\n\t\tconst previous = this.lastBuildUntil\n\t\tconst canContinue = previous !== null\n\t\t\t&& previous.migrations.length <= migrations.length\n\t\t\t&& previous.migrations.every((migration, index) => migration === migrations[index])\n\t\tconst start = canContinue ? previous : { migrations: [], schema: emptySchema }\n\n\t\tconst schema = this.applyMigrations(start.schema, migrations.slice(start.migrations.length))\n\t\tthis.lastBuildUntil = { migrations, schema }\n\t\treturn schema\n\t}\n\n\tasync continue(schema: Schema, previousVersion: string | null, targetVersion: string): Promise<Schema> {\n\t\treturn this.buildSchemaAdvanced(schema, version => version <= targetVersion && version > (previousVersion || ''))\n\t}\n\n\tpublic async buildSchemaAdvanced(initialSchema: Schema, condition: (version: string) => boolean): Promise<Schema> {\n\t\tconst migrations = (await this.migrationsResolver.getSchemaMigrations()).filter(({ version }) => condition(version))\n\t\treturn this.applyMigrations(initialSchema, migrations)\n\t}\n\n\tprivate applyMigrations(initialSchema: Schema, migrations: Migration[]): Schema {\n\t\treturn migrations.reduce<Schema>(\n\t\t\t(schema, { modifications, formatVersion }) => this.schemaMigrator.applyModifications(schema, modifications, formatVersion),\n\t\t\tinitialSchema,\n\t\t)\n\t}\n}\n"],"names":[],"mappings":";;;;AAMO,MAAM,qBAAqB;AAAA,EAGjC,YACkB,oBACA,gBACA,oBAChB;AAHgB,SAAA,qBAAA;AACA,SAAA,iBAAA;AACA,SAAA,qBAAA;AALlB,kBAAA,MAAQ,kBAAqE,IAAA;AAAA,EAM1E;AAAA,EAEH,MAAM,YAAY,eAAyC;AAC1D,QAAI,SAAS,MAAM,KAAK,oBAAoB,aAAa,CAAA,YAAW,CAAC,iBAAiB,WAAW,aAAa;AAC9G,QAAI,CAAC,iBAAiB,MAAM,KAAK,mBAAmB,eAAe;AAClE,YAAM,QAAQ,MAAM,KAAK,mBAAmB,UAAA;AAC5C,eAAS,EAAE,GAAG,QAAQ,GAAG,MAAA;AAAA,IAC1B;AACA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,iBAAiB,eAAwC;AAC9D,UAAM,cAAc,MAAM,KAAK,mBAAmB,oBAAA,GAAuB,OAAO,CAAC,EAAE,cAAc,UAAU,aAAa;AACxH,UAAM,WAAW,KAAK;AACtB,UAAM,cAAc,aAAa,QAC7B,SAAS,WAAW,UAAU,WAAW,UACzC,SAAS,WAAW,MAAM,CAAC,WAAW,UAAU,cAAc,WAAW,KAAK,CAAC;AACnF,UAAM,QAAQ,cAAc,WAAW,EAAE,YAAY,CAAA,GAAI,QAAQ,YAAA;AAEjE,UAAM,SAAS,KAAK,gBAAgB,MAAM,QAAQ,WAAW,MAAM,MAAM,WAAW,MAAM,CAAC;AAC3F,SAAK,iBAAiB,EAAE,YAAY,OAAA;AACpC,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,SAAS,QAAgB,iBAAgC,eAAwC;AACtG,WAAO,KAAK,oBAAoB,QAAQ,CAAA,YAAW,WAAW,iBAAiB,WAAW,mBAAmB,GAAG;AAAA,EACjH;AAAA,EAEA,MAAa,oBAAoB,eAAuB,WAA0D;AACjH,UAAM,cAAc,MAAM,KAAK,mBAAmB,oBAAA,GAAuB,OAAO,CAAC,EAAE,QAAA,MAAc,UAAU,OAAO,CAAC;AACnH,WAAO,KAAK,gBAAgB,eAAe,UAAU;AAAA,EACtD;AAAA,EAEQ,gBAAgB,eAAuB,YAAiC;AAC/E,WAAO,WAAW;AAAA,MACjB,CAAC,QAAQ,EAAE,eAAe,oBAAoB,KAAK,eAAe,mBAAmB,QAAQ,eAAe,aAAa;AAAA,MACzH;AAAA,IAAA;AAAA,EAEF;AACD;"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const fs = require("node:fs/promises");
|
|
4
|
+
function _interopNamespaceDefault(e) {
|
|
5
|
+
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
6
|
+
if (e) {
|
|
7
|
+
for (const k in e) {
|
|
8
|
+
if (k !== "default") {
|
|
9
|
+
const d = Object.getOwnPropertyDescriptor(e, k);
|
|
10
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: () => e[k]
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
n.default = e;
|
|
18
|
+
return Object.freeze(n);
|
|
19
|
+
}
|
|
20
|
+
const fs__namespace = /* @__PURE__ */ _interopNamespaceDefault(fs);
|
|
21
|
+
class SnapshotManager {
|
|
22
|
+
constructor(snapshotPath) {
|
|
23
|
+
this.snapshotPath = snapshotPath;
|
|
24
|
+
}
|
|
25
|
+
async exists() {
|
|
26
|
+
try {
|
|
27
|
+
const stat = await fs__namespace.stat(this.snapshotPath);
|
|
28
|
+
return stat.isFile();
|
|
29
|
+
} catch {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async read() {
|
|
34
|
+
try {
|
|
35
|
+
const content = await fs__namespace.readFile(this.snapshotPath, "utf8");
|
|
36
|
+
return JSON.parse(content);
|
|
37
|
+
} catch (e) {
|
|
38
|
+
throw new Error(`Failed to read snapshot file ${this.snapshotPath}: ${e instanceof Error ? e.message : e}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async write(snapshot) {
|
|
42
|
+
await fs__namespace.writeFile(this.snapshotPath, JSON.stringify(snapshot, void 0, " ") + "\n", "utf8");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.SnapshotManager = SnapshotManager;
|
|
46
|
+
//# sourceMappingURL=SnapshotManager.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SnapshotManager.cjs","sources":["../../../../packages/migrations-client/src/SnapshotManager.ts"],"sourcesContent":["import { Migration } from '@contember/schema-migrations'\nimport * as fs from 'node:fs/promises'\n\nexport type CoveredMigration = {\n\tversion: string\n\tname: string\n\ttype: 'schema' | 'content'\n\t/** schema migration checksum, or null for content migrations (mirrors the executed registry) */\n\tchecksum: string | null\n}\n\nexport type SnapshotFile = {\n\t/** last covered migration version (X) */\n\tversion: string\n\t/** whether the project used schema state mode when the snapshot was created */\n\tstateMode: boolean\n\t/** collapsed schema (empty -> X), applied in a single step */\n\tsnapshot: {\n\t\tformatVersion: number\n\t\tmodifications: Migration.Modification[]\n\t}\n\t/** migrations subsumed by the snapshot, recorded as executed without replaying them */\n\tcovers: CoveredMigration[]\n\t/** versions of content migrations within the covered range whose data is NOT reproduced */\n\tcontentMigrations: string[]\n}\n\nexport class SnapshotManager {\n\tconstructor(private readonly snapshotPath: string) {}\n\n\tasync exists(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst stat = await fs.stat(this.snapshotPath)\n\t\t\treturn stat.isFile()\n\t\t} catch {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tasync read(): Promise<SnapshotFile> {\n\t\ttry {\n\t\t\tconst content = await fs.readFile(this.snapshotPath, 'utf8')\n\t\t\treturn JSON.parse(content) as SnapshotFile\n\t\t} catch (e) {\n\t\t\tthrow new Error(`Failed to read snapshot file ${this.snapshotPath}: ${e instanceof Error ? e.message : e}`)\n\t\t}\n\t}\n\n\tasync write(snapshot: SnapshotFile): Promise<void> {\n\t\tawait fs.writeFile(this.snapshotPath, JSON.stringify(snapshot, undefined, '\\t') + '\\n', 'utf8')\n\t}\n}\n"],"names":["fs"],"mappings":";;;;;;;;;;;;;;;;;;;;AA2BO,MAAM,gBAAgB;AAAA,EAC5B,YAA6B,cAAsB;AAAtB,SAAA,eAAA;AAAA,EAAuB;AAAA,EAEpD,MAAM,SAA2B;AAChC,QAAI;AACH,YAAM,OAAO,MAAMA,cAAG,KAAK,KAAK,YAAY;AAC5C,aAAO,KAAK,OAAA;AAAA,IACb,QAAQ;AACP,aAAO;AAAA,IACR;AAAA,EACD;AAAA,EAEA,MAAM,OAA8B;AACnC,QAAI;AACH,YAAM,UAAU,MAAMA,cAAG,SAAS,KAAK,cAAc,MAAM;AAC3D,aAAO,KAAK,MAAM,OAAO;AAAA,IAC1B,SAAS,GAAG;AACX,YAAM,IAAI,MAAM,gCAAgC,KAAK,YAAY,KAAK,aAAa,QAAQ,EAAE,UAAU,CAAC,EAAE;AAAA,IAC3G;AAAA,EACD;AAAA,EAEA,MAAM,MAAM,UAAuC;AAClD,UAAMA,cAAG,UAAU,KAAK,cAAc,KAAK,UAAU,UAAU,QAAW,GAAI,IAAI,MAAM,MAAM;AAAA,EAC/F;AACD;;"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
class SnapshotManager {
|
|
3
|
+
constructor(snapshotPath) {
|
|
4
|
+
this.snapshotPath = snapshotPath;
|
|
5
|
+
}
|
|
6
|
+
async exists() {
|
|
7
|
+
try {
|
|
8
|
+
const stat = await fs.stat(this.snapshotPath);
|
|
9
|
+
return stat.isFile();
|
|
10
|
+
} catch {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
async read() {
|
|
15
|
+
try {
|
|
16
|
+
const content = await fs.readFile(this.snapshotPath, "utf8");
|
|
17
|
+
return JSON.parse(content);
|
|
18
|
+
} catch (e) {
|
|
19
|
+
throw new Error(`Failed to read snapshot file ${this.snapshotPath}: ${e instanceof Error ? e.message : e}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async write(snapshot) {
|
|
23
|
+
await fs.writeFile(this.snapshotPath, JSON.stringify(snapshot, void 0, " ") + "\n", "utf8");
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
SnapshotManager
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=SnapshotManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SnapshotManager.js","sources":["../../../../packages/migrations-client/src/SnapshotManager.ts"],"sourcesContent":["import { Migration } from '@contember/schema-migrations'\nimport * as fs from 'node:fs/promises'\n\nexport type CoveredMigration = {\n\tversion: string\n\tname: string\n\ttype: 'schema' | 'content'\n\t/** schema migration checksum, or null for content migrations (mirrors the executed registry) */\n\tchecksum: string | null\n}\n\nexport type SnapshotFile = {\n\t/** last covered migration version (X) */\n\tversion: string\n\t/** whether the project used schema state mode when the snapshot was created */\n\tstateMode: boolean\n\t/** collapsed schema (empty -> X), applied in a single step */\n\tsnapshot: {\n\t\tformatVersion: number\n\t\tmodifications: Migration.Modification[]\n\t}\n\t/** migrations subsumed by the snapshot, recorded as executed without replaying them */\n\tcovers: CoveredMigration[]\n\t/** versions of content migrations within the covered range whose data is NOT reproduced */\n\tcontentMigrations: string[]\n}\n\nexport class SnapshotManager {\n\tconstructor(private readonly snapshotPath: string) {}\n\n\tasync exists(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst stat = await fs.stat(this.snapshotPath)\n\t\t\treturn stat.isFile()\n\t\t} catch {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tasync read(): Promise<SnapshotFile> {\n\t\ttry {\n\t\t\tconst content = await fs.readFile(this.snapshotPath, 'utf8')\n\t\t\treturn JSON.parse(content) as SnapshotFile\n\t\t} catch (e) {\n\t\t\tthrow new Error(`Failed to read snapshot file ${this.snapshotPath}: ${e instanceof Error ? e.message : e}`)\n\t\t}\n\t}\n\n\tasync write(snapshot: SnapshotFile): Promise<void> {\n\t\tawait fs.writeFile(this.snapshotPath, JSON.stringify(snapshot, undefined, '\\t') + '\\n', 'utf8')\n\t}\n}\n"],"names":[],"mappings":";AA2BO,MAAM,gBAAgB;AAAA,EAC5B,YAA6B,cAAsB;AAAtB,SAAA,eAAA;AAAA,EAAuB;AAAA,EAEpD,MAAM,SAA2B;AAChC,QAAI;AACH,YAAM,OAAO,MAAM,GAAG,KAAK,KAAK,YAAY;AAC5C,aAAO,KAAK,OAAA;AAAA,IACb,QAAQ;AACP,aAAO;AAAA,IACR;AAAA,EACD;AAAA,EAEA,MAAM,OAA8B;AACnC,QAAI;AACH,YAAM,UAAU,MAAM,GAAG,SAAS,KAAK,cAAc,MAAM;AAC3D,aAAO,KAAK,MAAM,OAAO;AAAA,IAC1B,SAAS,GAAG;AACX,YAAM,IAAI,MAAM,gCAAgC,KAAK,YAAY,KAAK,aAAa,QAAQ,EAAE,UAAU,CAAC,EAAE;AAAA,IAC3G;AAAA,EACD;AAAA,EAEA,MAAM,MAAM,UAAuC;AAClD,UAAM,GAAG,UAAU,KAAK,cAAc,KAAK,UAAU,UAAU,QAAW,GAAI,IAAI,MAAM,MAAM;AAAA,EAC/F;AACD;"}
|
|
@@ -7,6 +7,7 @@ var MigrateErrorCode = /* @__PURE__ */ ((MigrateErrorCode2) => {
|
|
|
7
7
|
MigrateErrorCode2["InvalidFormat"] = "INVALID_FORMAT";
|
|
8
8
|
MigrateErrorCode2["InvalidSchema"] = "INVALID_SCHEMA";
|
|
9
9
|
MigrateErrorCode2["MigrationFailed"] = "MIGRATION_FAILED";
|
|
10
|
+
MigrateErrorCode2["ProjectNotEmpty"] = "PROJECT_NOT_EMPTY";
|
|
10
11
|
return MigrateErrorCode2;
|
|
11
12
|
})(MigrateErrorCode || {});
|
|
12
13
|
class SystemClient {
|
|
@@ -17,10 +18,10 @@ class SystemClient {
|
|
|
17
18
|
const graphqlClient$1 = new graphqlClient.GraphQlClient({ url: createSystemUrl(baseUrl, projectName), apiToken });
|
|
18
19
|
return new SystemClient(graphqlClient$1);
|
|
19
20
|
}
|
|
20
|
-
async migrate(migrations, force = false) {
|
|
21
|
+
async migrate(migrations, force = false, schemaState) {
|
|
21
22
|
const query = `
|
|
22
|
-
mutation($migrations: [Migration!]
|
|
23
|
-
migrate: ${force ? "forceMigrate" : "migrate"}(migrations: $migrations) {
|
|
23
|
+
mutation($migrations: [Migration!]!, $schemaState: SchemaStateInput) {
|
|
24
|
+
migrate: ${force ? "forceMigrate" : "migrate"}(migrations: $migrations, schemaState: $schemaState) {
|
|
24
25
|
ok
|
|
25
26
|
errors {
|
|
26
27
|
code
|
|
@@ -32,13 +33,37 @@ mutation($migrations: [Migration!]!) {
|
|
|
32
33
|
`;
|
|
33
34
|
const result = (await this.apiClient.execute(query, {
|
|
34
35
|
variables: {
|
|
35
|
-
migrations
|
|
36
|
+
migrations,
|
|
37
|
+
schemaState: schemaState ?? null
|
|
36
38
|
}
|
|
37
39
|
})).migrate;
|
|
38
40
|
if (!result.ok) {
|
|
39
41
|
throw result.errors;
|
|
40
42
|
}
|
|
41
43
|
}
|
|
44
|
+
async migrateFromSnapshot(snapshot, schemaState) {
|
|
45
|
+
const query = `
|
|
46
|
+
mutation($snapshot: SnapshotInput!, $schemaState: SchemaStateInput) {
|
|
47
|
+
migrateFromSnapshot(snapshot: $snapshot, schemaState: $schemaState) {
|
|
48
|
+
ok
|
|
49
|
+
errors {
|
|
50
|
+
code
|
|
51
|
+
migration
|
|
52
|
+
message: developerMessage
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
`;
|
|
57
|
+
const result = (await this.apiClient.execute(query, {
|
|
58
|
+
variables: {
|
|
59
|
+
snapshot,
|
|
60
|
+
schemaState: schemaState ?? null
|
|
61
|
+
}
|
|
62
|
+
})).migrateFromSnapshot;
|
|
63
|
+
if (!result.ok) {
|
|
64
|
+
throw result.errors;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
42
67
|
async migrationDelete(version) {
|
|
43
68
|
const query = `
|
|
44
69
|
mutation($version: String!) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SystemClient.cjs","sources":["../../../../packages/migrations-client/src/SystemClient.ts"],"sourcesContent":["import { GraphQlClient } from '@contember/graphql-client'\nimport { ExecutedMigration, ExecutedMigrationInfo } from './migrations'\n\nexport type MigrateError = {\n\treadonly code: MigrateErrorCode\n\treadonly migration: string\n\treadonly message: string\n}\n\nexport enum MigrateErrorCode {\n\tMustFollowLatest = 'MUST_FOLLOW_LATEST',\n\tAlreadyExecuted = 'ALREADY_EXECUTED',\n\tInvalidFormat = 'INVALID_FORMAT',\n\tInvalidSchema = 'INVALID_SCHEMA',\n\tMigrationFailed = 'MIGRATION_FAILED',\n}\n\nexport type MigrateResponse = {\n\treadonly ok: boolean\n\treadonly errors: MigrateError[]\n}\n\nexport class SystemClient {\n\tconstructor(private readonly apiClient: GraphQlClient) {}\n\n\tpublic static create(baseUrl: string, projectName: string, apiToken: string): SystemClient {\n\t\tconst graphqlClient = new GraphQlClient({ url: createSystemUrl(baseUrl, projectName), apiToken })\n\t\treturn new SystemClient(graphqlClient)\n\t}\n\n\tpublic async migrate(migrations: any[], force = false): Promise<void> {\n\t\tconst query = `\nmutation($migrations: [Migration!]
|
|
1
|
+
{"version":3,"file":"SystemClient.cjs","sources":["../../../../packages/migrations-client/src/SystemClient.ts"],"sourcesContent":["import { GraphQlClient } from '@contember/graphql-client'\nimport { ExecutedMigration, ExecutedMigrationInfo } from './migrations.js'\nimport { SchemaState } from './SchemaStateManager.js'\n\nexport type MigrateError = {\n\treadonly code: MigrateErrorCode\n\treadonly migration: string\n\treadonly message: string\n}\n\nexport enum MigrateErrorCode {\n\tMustFollowLatest = 'MUST_FOLLOW_LATEST',\n\tAlreadyExecuted = 'ALREADY_EXECUTED',\n\tInvalidFormat = 'INVALID_FORMAT',\n\tInvalidSchema = 'INVALID_SCHEMA',\n\tMigrationFailed = 'MIGRATION_FAILED',\n\tProjectNotEmpty = 'PROJECT_NOT_EMPTY',\n}\n\nexport type SnapshotInput = {\n\tformatVersion: number\n\tmodifications: unknown[]\n\tcovers: unknown[]\n}\n\nexport type MigrateResponse = {\n\treadonly ok: boolean\n\treadonly errors: MigrateError[]\n}\n\nexport class SystemClient {\n\tconstructor(private readonly apiClient: GraphQlClient) {}\n\n\tpublic static create(baseUrl: string, projectName: string, apiToken: string): SystemClient {\n\t\tconst graphqlClient = new GraphQlClient({ url: createSystemUrl(baseUrl, projectName), apiToken })\n\t\treturn new SystemClient(graphqlClient)\n\t}\n\n\tpublic async migrate(migrations: any[], force = false, schemaState?: SchemaState): Promise<void> {\n\t\tconst query = `\nmutation($migrations: [Migration!]!, $schemaState: SchemaStateInput) {\n\tmigrate: ${force ? 'forceMigrate' : 'migrate'}(migrations: $migrations, schemaState: $schemaState) {\n\t\tok\n\t\terrors {\n\t\t\tcode\n\t\t\tmigration\n\t\t\tmessage: developerMessage\n\t\t}\n\t}\n}\n`\n\t\tconst result = (\n\t\t\tawait this.apiClient.execute<{\n\t\t\t\tmigrate: { ok: boolean; errors: { code: MigrateErrorCode; migration: string; message: string }[] }\n\t\t\t}>(query, {\n\t\t\t\tvariables: {\n\t\t\t\t\tmigrations,\n\t\t\t\t\tschemaState: schemaState ?? null,\n\t\t\t\t},\n\t\t\t})\n\t\t).migrate\n\t\tif (!result.ok) {\n\t\t\tthrow result.errors\n\t\t}\n\t}\n\n\tpublic async migrateFromSnapshot(snapshot: SnapshotInput, schemaState?: SchemaState): Promise<void> {\n\t\tconst query = `\nmutation($snapshot: SnapshotInput!, $schemaState: SchemaStateInput) {\n\tmigrateFromSnapshot(snapshot: $snapshot, schemaState: $schemaState) {\n\t\tok\n\t\terrors {\n\t\t\tcode\n\t\t\tmigration\n\t\t\tmessage: developerMessage\n\t\t}\n\t}\n}\n`\n\t\tconst result = (\n\t\t\tawait this.apiClient.execute<{\n\t\t\t\tmigrateFromSnapshot: { ok: boolean; errors: { code: MigrateErrorCode; migration: string; message: string }[] }\n\t\t\t}>(query, {\n\t\t\t\tvariables: {\n\t\t\t\t\tsnapshot,\n\t\t\t\t\tschemaState: schemaState ?? null,\n\t\t\t\t},\n\t\t\t})\n\t\t).migrateFromSnapshot\n\t\tif (!result.ok) {\n\t\t\tthrow result.errors\n\t\t}\n\t}\n\n\tpublic async migrationDelete(version: string): Promise<void> {\n\t\tconst query = `\nmutation($version: String!) {\n\tmigrationDelete(migration: $version) {\n\t\tok\n\t\terror {\n\t\t\tdeveloperMessage\n\t\t}\n\t}\n}\n`\n\t\tconst result = (\n\t\t\tawait this.apiClient.execute<{\n\t\t\t\tmigrationDelete: { ok: boolean; error?: { developerMessage: string } }\n\t\t\t}>(query, {\n\t\t\t\tvariables: {\n\t\t\t\t\tversion,\n\t\t\t\t},\n\t\t\t})\n\t\t).migrationDelete\n\t\tif (!result.ok) {\n\t\t\tthrow result.error?.developerMessage\n\t\t}\n\t}\n\n\tpublic async migrationModify(version: string, modification: Partial<any>): Promise<void> {\n\t\tconst query = `\nmutation($version: String!, $modification: MigrationModification!) {\n\tmigrationModify(migration: $version, modification: $modification) {\n\t\tok\n\t\terror {\n\t\t\tdeveloperMessage\n\t\t}\n\t}\n}\n`\n\t\tconst result = (\n\t\t\tawait this.apiClient.execute<{\n\t\t\t\tmigrationModify: { ok: boolean; error?: { developerMessage: string } }\n\t\t\t}>(query, {\n\t\t\t\tvariables: {\n\t\t\t\t\tversion,\n\t\t\t\t\tmodification,\n\t\t\t\t},\n\t\t\t})\n\t\t).migrationModify\n\t\tif (!result.ok) {\n\t\t\tthrow result.error?.developerMessage\n\t\t}\n\t}\n\n\tpublic async listExecutedMigrations(): Promise<ExecutedMigrationInfo[]> {\n\t\tconst query = `query {\n\texecutedMigrations {\n\t\tname\n\t\tversion\n\t\tformatVersion\n\t\tchecksum\n\t\texecutedAt\n\t}\n}`\n\t\treturn (\n\t\t\tawait this.apiClient.execute<{\n\t\t\t\texecutedMigrations: ExecutedMigrationInfo[]\n\t\t\t}>(query, {})\n\t\t).executedMigrations.map(it => ({ ...it, executedAt: new Date(it.executedAt) }))\n\t}\n\n\tpublic async getExecutedMigration(version: string): Promise<ExecutedMigration> {\n\t\tconst query = `query($version: String!) {\n\texecutedMigrations(version: $version) {\n\t\tname\n\t\tversion\n\t\tformatVersion\n\t\tchecksum\n\t\texecutedAt\n\t\tmodifications\n\t}\n}`\n\t\treturn (\n\t\t\t(\n\t\t\t\tawait this.apiClient.execute<{\n\t\t\t\t\texecutedMigrations: ExecutedMigration[]\n\t\t\t\t}>(query, { variables: { version } })\n\t\t\t).executedMigrations.map(it => ({ ...it, executedAt: new Date(it.executedAt) }))[0] || null\n\t\t)\n\t}\n}\n\nconst createSystemUrl = (baseUrl: string, projectName: string) => {\n\tif (baseUrl.endsWith('/')) {\n\t\tbaseUrl = baseUrl.substring(0, baseUrl.length - 1)\n\t}\n\treturn baseUrl + '/system/' + projectName\n}\n"],"names":["MigrateErrorCode","graphqlClient","GraphQlClient"],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ var MigrateErrorCode = /* @__PURE__ */ ((MigrateErrorCode2) => {
|
|
|
5
5
|
MigrateErrorCode2["InvalidFormat"] = "INVALID_FORMAT";
|
|
6
6
|
MigrateErrorCode2["InvalidSchema"] = "INVALID_SCHEMA";
|
|
7
7
|
MigrateErrorCode2["MigrationFailed"] = "MIGRATION_FAILED";
|
|
8
|
+
MigrateErrorCode2["ProjectNotEmpty"] = "PROJECT_NOT_EMPTY";
|
|
8
9
|
return MigrateErrorCode2;
|
|
9
10
|
})(MigrateErrorCode || {});
|
|
10
11
|
class SystemClient {
|
|
@@ -15,10 +16,10 @@ class SystemClient {
|
|
|
15
16
|
const graphqlClient = new GraphQlClient({ url: createSystemUrl(baseUrl, projectName), apiToken });
|
|
16
17
|
return new SystemClient(graphqlClient);
|
|
17
18
|
}
|
|
18
|
-
async migrate(migrations, force = false) {
|
|
19
|
+
async migrate(migrations, force = false, schemaState) {
|
|
19
20
|
const query = `
|
|
20
|
-
mutation($migrations: [Migration!]
|
|
21
|
-
migrate: ${force ? "forceMigrate" : "migrate"}(migrations: $migrations) {
|
|
21
|
+
mutation($migrations: [Migration!]!, $schemaState: SchemaStateInput) {
|
|
22
|
+
migrate: ${force ? "forceMigrate" : "migrate"}(migrations: $migrations, schemaState: $schemaState) {
|
|
22
23
|
ok
|
|
23
24
|
errors {
|
|
24
25
|
code
|
|
@@ -30,13 +31,37 @@ mutation($migrations: [Migration!]!) {
|
|
|
30
31
|
`;
|
|
31
32
|
const result = (await this.apiClient.execute(query, {
|
|
32
33
|
variables: {
|
|
33
|
-
migrations
|
|
34
|
+
migrations,
|
|
35
|
+
schemaState: schemaState ?? null
|
|
34
36
|
}
|
|
35
37
|
})).migrate;
|
|
36
38
|
if (!result.ok) {
|
|
37
39
|
throw result.errors;
|
|
38
40
|
}
|
|
39
41
|
}
|
|
42
|
+
async migrateFromSnapshot(snapshot, schemaState) {
|
|
43
|
+
const query = `
|
|
44
|
+
mutation($snapshot: SnapshotInput!, $schemaState: SchemaStateInput) {
|
|
45
|
+
migrateFromSnapshot(snapshot: $snapshot, schemaState: $schemaState) {
|
|
46
|
+
ok
|
|
47
|
+
errors {
|
|
48
|
+
code
|
|
49
|
+
migration
|
|
50
|
+
message: developerMessage
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
`;
|
|
55
|
+
const result = (await this.apiClient.execute(query, {
|
|
56
|
+
variables: {
|
|
57
|
+
snapshot,
|
|
58
|
+
schemaState: schemaState ?? null
|
|
59
|
+
}
|
|
60
|
+
})).migrateFromSnapshot;
|
|
61
|
+
if (!result.ok) {
|
|
62
|
+
throw result.errors;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
40
65
|
async migrationDelete(version) {
|
|
41
66
|
const query = `
|
|
42
67
|
mutation($version: String!) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SystemClient.js","sources":["../../../../packages/migrations-client/src/SystemClient.ts"],"sourcesContent":["import { GraphQlClient } from '@contember/graphql-client'\nimport { ExecutedMigration, ExecutedMigrationInfo } from './migrations'\n\nexport type MigrateError = {\n\treadonly code: MigrateErrorCode\n\treadonly migration: string\n\treadonly message: string\n}\n\nexport enum MigrateErrorCode {\n\tMustFollowLatest = 'MUST_FOLLOW_LATEST',\n\tAlreadyExecuted = 'ALREADY_EXECUTED',\n\tInvalidFormat = 'INVALID_FORMAT',\n\tInvalidSchema = 'INVALID_SCHEMA',\n\tMigrationFailed = 'MIGRATION_FAILED',\n}\n\nexport type MigrateResponse = {\n\treadonly ok: boolean\n\treadonly errors: MigrateError[]\n}\n\nexport class SystemClient {\n\tconstructor(private readonly apiClient: GraphQlClient) {}\n\n\tpublic static create(baseUrl: string, projectName: string, apiToken: string): SystemClient {\n\t\tconst graphqlClient = new GraphQlClient({ url: createSystemUrl(baseUrl, projectName), apiToken })\n\t\treturn new SystemClient(graphqlClient)\n\t}\n\n\tpublic async migrate(migrations: any[], force = false): Promise<void> {\n\t\tconst query = `\nmutation($migrations: [Migration!]
|
|
1
|
+
{"version":3,"file":"SystemClient.js","sources":["../../../../packages/migrations-client/src/SystemClient.ts"],"sourcesContent":["import { GraphQlClient } from '@contember/graphql-client'\nimport { ExecutedMigration, ExecutedMigrationInfo } from './migrations.js'\nimport { SchemaState } from './SchemaStateManager.js'\n\nexport type MigrateError = {\n\treadonly code: MigrateErrorCode\n\treadonly migration: string\n\treadonly message: string\n}\n\nexport enum MigrateErrorCode {\n\tMustFollowLatest = 'MUST_FOLLOW_LATEST',\n\tAlreadyExecuted = 'ALREADY_EXECUTED',\n\tInvalidFormat = 'INVALID_FORMAT',\n\tInvalidSchema = 'INVALID_SCHEMA',\n\tMigrationFailed = 'MIGRATION_FAILED',\n\tProjectNotEmpty = 'PROJECT_NOT_EMPTY',\n}\n\nexport type SnapshotInput = {\n\tformatVersion: number\n\tmodifications: unknown[]\n\tcovers: unknown[]\n}\n\nexport type MigrateResponse = {\n\treadonly ok: boolean\n\treadonly errors: MigrateError[]\n}\n\nexport class SystemClient {\n\tconstructor(private readonly apiClient: GraphQlClient) {}\n\n\tpublic static create(baseUrl: string, projectName: string, apiToken: string): SystemClient {\n\t\tconst graphqlClient = new GraphQlClient({ url: createSystemUrl(baseUrl, projectName), apiToken })\n\t\treturn new SystemClient(graphqlClient)\n\t}\n\n\tpublic async migrate(migrations: any[], force = false, schemaState?: SchemaState): Promise<void> {\n\t\tconst query = `\nmutation($migrations: [Migration!]!, $schemaState: SchemaStateInput) {\n\tmigrate: ${force ? 'forceMigrate' : 'migrate'}(migrations: $migrations, schemaState: $schemaState) {\n\t\tok\n\t\terrors {\n\t\t\tcode\n\t\t\tmigration\n\t\t\tmessage: developerMessage\n\t\t}\n\t}\n}\n`\n\t\tconst result = (\n\t\t\tawait this.apiClient.execute<{\n\t\t\t\tmigrate: { ok: boolean; errors: { code: MigrateErrorCode; migration: string; message: string }[] }\n\t\t\t}>(query, {\n\t\t\t\tvariables: {\n\t\t\t\t\tmigrations,\n\t\t\t\t\tschemaState: schemaState ?? null,\n\t\t\t\t},\n\t\t\t})\n\t\t).migrate\n\t\tif (!result.ok) {\n\t\t\tthrow result.errors\n\t\t}\n\t}\n\n\tpublic async migrateFromSnapshot(snapshot: SnapshotInput, schemaState?: SchemaState): Promise<void> {\n\t\tconst query = `\nmutation($snapshot: SnapshotInput!, $schemaState: SchemaStateInput) {\n\tmigrateFromSnapshot(snapshot: $snapshot, schemaState: $schemaState) {\n\t\tok\n\t\terrors {\n\t\t\tcode\n\t\t\tmigration\n\t\t\tmessage: developerMessage\n\t\t}\n\t}\n}\n`\n\t\tconst result = (\n\t\t\tawait this.apiClient.execute<{\n\t\t\t\tmigrateFromSnapshot: { ok: boolean; errors: { code: MigrateErrorCode; migration: string; message: string }[] }\n\t\t\t}>(query, {\n\t\t\t\tvariables: {\n\t\t\t\t\tsnapshot,\n\t\t\t\t\tschemaState: schemaState ?? null,\n\t\t\t\t},\n\t\t\t})\n\t\t).migrateFromSnapshot\n\t\tif (!result.ok) {\n\t\t\tthrow result.errors\n\t\t}\n\t}\n\n\tpublic async migrationDelete(version: string): Promise<void> {\n\t\tconst query = `\nmutation($version: String!) {\n\tmigrationDelete(migration: $version) {\n\t\tok\n\t\terror {\n\t\t\tdeveloperMessage\n\t\t}\n\t}\n}\n`\n\t\tconst result = (\n\t\t\tawait this.apiClient.execute<{\n\t\t\t\tmigrationDelete: { ok: boolean; error?: { developerMessage: string } }\n\t\t\t}>(query, {\n\t\t\t\tvariables: {\n\t\t\t\t\tversion,\n\t\t\t\t},\n\t\t\t})\n\t\t).migrationDelete\n\t\tif (!result.ok) {\n\t\t\tthrow result.error?.developerMessage\n\t\t}\n\t}\n\n\tpublic async migrationModify(version: string, modification: Partial<any>): Promise<void> {\n\t\tconst query = `\nmutation($version: String!, $modification: MigrationModification!) {\n\tmigrationModify(migration: $version, modification: $modification) {\n\t\tok\n\t\terror {\n\t\t\tdeveloperMessage\n\t\t}\n\t}\n}\n`\n\t\tconst result = (\n\t\t\tawait this.apiClient.execute<{\n\t\t\t\tmigrationModify: { ok: boolean; error?: { developerMessage: string } }\n\t\t\t}>(query, {\n\t\t\t\tvariables: {\n\t\t\t\t\tversion,\n\t\t\t\t\tmodification,\n\t\t\t\t},\n\t\t\t})\n\t\t).migrationModify\n\t\tif (!result.ok) {\n\t\t\tthrow result.error?.developerMessage\n\t\t}\n\t}\n\n\tpublic async listExecutedMigrations(): Promise<ExecutedMigrationInfo[]> {\n\t\tconst query = `query {\n\texecutedMigrations {\n\t\tname\n\t\tversion\n\t\tformatVersion\n\t\tchecksum\n\t\texecutedAt\n\t}\n}`\n\t\treturn (\n\t\t\tawait this.apiClient.execute<{\n\t\t\t\texecutedMigrations: ExecutedMigrationInfo[]\n\t\t\t}>(query, {})\n\t\t).executedMigrations.map(it => ({ ...it, executedAt: new Date(it.executedAt) }))\n\t}\n\n\tpublic async getExecutedMigration(version: string): Promise<ExecutedMigration> {\n\t\tconst query = `query($version: String!) {\n\texecutedMigrations(version: $version) {\n\t\tname\n\t\tversion\n\t\tformatVersion\n\t\tchecksum\n\t\texecutedAt\n\t\tmodifications\n\t}\n}`\n\t\treturn (\n\t\t\t(\n\t\t\t\tawait this.apiClient.execute<{\n\t\t\t\t\texecutedMigrations: ExecutedMigration[]\n\t\t\t\t}>(query, { variables: { version } })\n\t\t\t).executedMigrations.map(it => ({ ...it, executedAt: new Date(it.executedAt) }))[0] || null\n\t\t)\n\t}\n}\n\nconst createSystemUrl = (baseUrl: string, projectName: string) => {\n\tif (baseUrl.endsWith('/')) {\n\t\tbaseUrl = baseUrl.substring(0, baseUrl.length - 1)\n\t}\n\treturn baseUrl + '/system/' + projectName\n}\n"],"names":["MigrateErrorCode"],"mappings":"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"}
|