@webiny/data-migration 5.39.1-beta.0 → 5.39.1
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/MigrationRunner.d.ts +2 -1
- package/MigrationRunner.js +25 -3
- package/MigrationRunner.js.map +1 -1
- package/cli/CliMigrationRunReporter.d.ts +2 -2
- package/cli/MigrationRunner.d.ts +1 -0
- package/cli/MigrationRunner.js.map +1 -1
- package/createPinoLogger.d.ts +20 -20
- package/handlers/createDdbEsProjectMigration.js +2 -1
- package/handlers/createDdbEsProjectMigration.js.map +1 -1
- package/handlers/createDdbProjectMigration.js +2 -1
- package/handlers/createDdbProjectMigration.js.map +1 -1
- package/package.json +10 -10
- package/types.d.ts +1 -0
- package/types.js.map +1 -1
package/MigrationRunner.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export declare class MigrationRunner {
|
|
|
9
9
|
private context;
|
|
10
10
|
constructor(repository: MigrationRepository, timeLimiter: ExecutionTimeLimiter, migrations: DataMigration[], logger: Logger | undefined);
|
|
11
11
|
setContext(context: Record<string, any>): void;
|
|
12
|
-
execute(projectVersion: string, isApplicable?: IsMigrationApplicable): Promise<void>;
|
|
12
|
+
execute(projectVersion: string, isApplicable?: IsMigrationApplicable, forceExecute?: boolean): Promise<void>;
|
|
13
13
|
getStatus(): Promise<MigrationStatus>;
|
|
14
14
|
private validateIds;
|
|
15
15
|
private createCheckpoint;
|
|
@@ -17,4 +17,5 @@ export declare class MigrationRunner {
|
|
|
17
17
|
private getOrCreateRunItem;
|
|
18
18
|
private setRunItem;
|
|
19
19
|
private setRunItemAndSave;
|
|
20
|
+
private printForceExecuteEnvVars;
|
|
20
21
|
}
|
package/MigrationRunner.js
CHANGED
|
@@ -18,6 +18,11 @@ const getRunItemDuration = runItem => {
|
|
|
18
18
|
}
|
|
19
19
|
return new Date(runItem.finishedOn).getTime() - new Date(runItem.startedOn).getTime();
|
|
20
20
|
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* This allows us to force-execute a migration, even if it's not in the list of the applicable migrations.
|
|
24
|
+
* Example: WEBINY_MIGRATION_FORCE_EXECUTE_5_35_0_006=true
|
|
25
|
+
*/
|
|
21
26
|
const shouldForceExecute = mig => {
|
|
22
27
|
const key = `WEBINY_MIGRATION_FORCE_EXECUTE_${mig.getId().replace(/[\.\-]/g, "_")}`;
|
|
23
28
|
return process.env[key] === "true";
|
|
@@ -38,7 +43,9 @@ class MigrationRunner {
|
|
|
38
43
|
setContext(context) {
|
|
39
44
|
this.context = context;
|
|
40
45
|
}
|
|
41
|
-
async execute(projectVersion, isApplicable
|
|
46
|
+
async execute(projectVersion, isApplicable,
|
|
47
|
+
// Force execute applicable migrations.
|
|
48
|
+
forceExecute = false) {
|
|
42
49
|
const lastRun = await this.getOrCreateRun();
|
|
43
50
|
try {
|
|
44
51
|
this.validateIds(this.migrations);
|
|
@@ -83,6 +90,10 @@ class MigrationRunner {
|
|
|
83
90
|
return mig.getId() > startingId && mig.getId() <= lastId;
|
|
84
91
|
};
|
|
85
92
|
const isMigrationApplicable = isApplicable || defaultIsApplicable;
|
|
93
|
+
this.printForceExecuteEnvVars();
|
|
94
|
+
if (forceExecute) {
|
|
95
|
+
this.logger.info(`ALL APPLICABLE MIGRATIONS WILL BE FORCE-EXECUTED! (via --force flag)`);
|
|
96
|
+
}
|
|
86
97
|
const executableMigrations = this.migrations.filter(mig => {
|
|
87
98
|
if (shouldForceExecute(mig)) {
|
|
88
99
|
return true;
|
|
@@ -115,7 +126,7 @@ class MigrationRunner {
|
|
|
115
126
|
projectVersion,
|
|
116
127
|
logger,
|
|
117
128
|
checkpoint,
|
|
118
|
-
forceExecute: shouldForceExecute(migration),
|
|
129
|
+
forceExecute: forceExecute || shouldForceExecute(migration),
|
|
119
130
|
runningOutOfTime: shouldCreateCheckpoint,
|
|
120
131
|
createCheckpoint: async data => {
|
|
121
132
|
await this.createCheckpoint(migration, data);
|
|
@@ -127,7 +138,7 @@ class MigrationRunner {
|
|
|
127
138
|
}
|
|
128
139
|
};
|
|
129
140
|
try {
|
|
130
|
-
const shouldExecute = checkpoint ||
|
|
141
|
+
const shouldExecute = checkpoint || context.forceExecute ? true : await migration.shouldExecute(context);
|
|
131
142
|
if (!shouldExecute) {
|
|
132
143
|
this.logger.info(`Skipping migration %s.`, migration.getId());
|
|
133
144
|
runItem.status = "skipped";
|
|
@@ -276,6 +287,17 @@ class MigrationRunner {
|
|
|
276
287
|
this.setRunItem(run, item);
|
|
277
288
|
await this.repository.saveRun(run);
|
|
278
289
|
}
|
|
290
|
+
printForceExecuteEnvVars() {
|
|
291
|
+
const forceKeys = Object.keys(process.env).filter(key => key.startsWith("WEBINY_MIGRATION_FORCE_EXECUTE_"));
|
|
292
|
+
if (!forceKeys.length) {
|
|
293
|
+
this.logger.info(`No migrations are enforced via WEBINY_MIGRATION_FORCE_EXECUTE environment variable.`);
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
this.logger.info(`FORCED MIGRATIONS DETECTED!`);
|
|
297
|
+
for (const key of forceKeys) {
|
|
298
|
+
this.logger.info(`${key}=${process.env[key]}`);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
279
301
|
}
|
|
280
302
|
exports.MigrationRunner = MigrationRunner;
|
|
281
303
|
(0, _ioc.makeInjectable)(MigrationRunner, [(0, _ioc.inject)(_symbols.MigrationRepositorySymbol), (0, _ioc.inject)(_symbols.ExecutionTimeLimiterSymbol), (0, _ioc.inject)(_symbols.MigrationSymbol, {
|
package/MigrationRunner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_semver","require","_ioc","_utils","_symbols","_createPinoLogger","getCurrentISOTime","Date","toISOString","getRunItemDuration","runItem","startedOn","finishedOn","getTime","shouldForceExecute","mig","key","getId","replace","process","env","MigrationNotFinished","Error","MigrationInProgress","MigrationRunner","context","constructor","repository","timeLimiter","migrations","logger","createPinoLogger","setContext","execute","projectVersion","isApplicable","lastRun","getOrCreateRun","validateIds","err","status","error","message","saveRun","latestMigration","listMigrations","limit","info","currentVersion","coerce","startingId","id","lastId","logMigration","description","reason","defaultIsApplicable","isMigrationApplicable","executableMigrations","filter","setRunItem","sort","a","b","length","shouldCreateCheckpoint","migration","getOrCreateRunItem","checkpoint","getCheckpoint","getChildLogger","forceExecute","runningOutOfTime","createCheckpoint","data","createCheckpointAndExit","shouldExecute","setRunItemAndSave","getDescription","name","stack","code","deleteCheckpoint","getStatus","getLastRun","withDescriptions","map","dataMigration","find","dm","ids","Set","endsWith","has","add","executeWithRetry","resolvedStatus","unresolvedStatus","includes","mdbid","run","existingItem","item","index","findIndex","push","slice","exports","makeInjectable","inject","MigrationRepositorySymbol","ExecutionTimeLimiterSymbol","MigrationSymbol","multi","optional","LoggerSymbol"],"sources":["MigrationRunner.ts"],"sourcesContent":["import { coerce } from \"semver\";\nimport { Logger } from \"@webiny/logger\";\nimport { inject, makeInjectable } from \"@webiny/ioc\";\nimport { executeWithRetry, mdbid } from \"@webiny/utils\";\nimport {\n MigrationRepositorySymbol,\n LoggerSymbol,\n MigrationSymbol,\n ExecutionTimeLimiterSymbol\n} from \"./symbols\";\nimport { createPinoLogger, getChildLogger } from \"./createPinoLogger\";\nimport {\n MigrationRepository,\n DataMigration,\n DataMigrationContext,\n ExecutionTimeLimiter,\n MigrationRun,\n MigrationStatus,\n MigrationRunItem\n} from \"~/types\";\n\nexport type IsMigrationApplicable = (migration: DataMigration) => boolean;\n\nconst getCurrentISOTime = () => {\n return new Date().toISOString();\n};\n\nconst getRunItemDuration = (runItem: MigrationRunItem) => {\n if (!runItem.startedOn || !runItem.finishedOn) {\n return \"N/A\";\n }\n\n return new Date(runItem.finishedOn).getTime() - new Date(runItem.startedOn).getTime();\n};\n\nconst shouldForceExecute = (mig: DataMigration) => {\n const key = `WEBINY_MIGRATION_FORCE_EXECUTE_${mig.getId().replace(/[\\.\\-]/g, \"_\")}`;\n\n return process.env[key] === \"true\";\n};\n\nclass MigrationNotFinished extends Error {}\nclass MigrationInProgress extends Error {}\n\nexport class MigrationRunner {\n private readonly logger: Logger;\n private readonly migrations: DataMigration[];\n private readonly repository: MigrationRepository;\n private readonly timeLimiter: ExecutionTimeLimiter;\n private context: Record<string, any> = {};\n\n constructor(\n repository: MigrationRepository,\n timeLimiter: ExecutionTimeLimiter,\n migrations: DataMigration[],\n logger: Logger | undefined\n ) {\n this.repository = repository;\n this.timeLimiter = timeLimiter;\n this.migrations = migrations || [];\n\n if (!logger) {\n logger = createPinoLogger();\n }\n this.logger = logger;\n }\n\n setContext(context: Record<string, any>) {\n this.context = context;\n }\n\n async execute(projectVersion: string, isApplicable?: IsMigrationApplicable) {\n const lastRun = await this.getOrCreateRun();\n\n try {\n this.validateIds(this.migrations);\n } catch (err) {\n lastRun.status = \"error\";\n lastRun.error = {\n message: err.message\n };\n await this.repository.saveRun(lastRun);\n return;\n }\n\n const [latestMigration] = await this.repository.listMigrations({ limit: 1 });\n\n this.logger.info(`Project version is %s.`, projectVersion);\n\n // Get current version, and coerce it to a valid SemVer.\n // With this, we can run migrations targeted for stable versions, released under a preid tag (e.g., `beta`).\n const currentVersion = coerce(projectVersion) + \"\";\n const startingId = latestMigration ? latestMigration.id : `${currentVersion}-000`;\n const lastId = `${currentVersion}-999`;\n\n // Create initial migration record.\n if (!latestMigration) {\n this.logger.info(\n `No migrations were ever executed. Creating initial migration record %s.`,\n startingId\n );\n await this.repository.logMigration({\n id: startingId,\n description: \"starting point for applicable migrations detection\",\n startedOn: getCurrentISOTime(),\n finishedOn: getCurrentISOTime(),\n reason: \"initial migration\"\n });\n } else {\n this.logger.info(`Latest migration ID is %s.`, latestMigration.id);\n }\n\n if (isApplicable) {\n this.logger.info(`Using custom \"isApplicable\" function.`);\n } else {\n this.logger.info(`Using migrations in the range of %s to %s.`, startingId, lastId);\n }\n\n const defaultIsApplicable: IsMigrationApplicable = mig => {\n return mig.getId() > startingId && mig.getId() <= lastId;\n };\n\n const isMigrationApplicable = isApplicable || defaultIsApplicable;\n\n const executableMigrations = this.migrations\n .filter(mig => {\n if (shouldForceExecute(mig)) {\n return true;\n }\n\n if (!isMigrationApplicable(mig)) {\n this.setRunItem(lastRun, {\n id: mig.getId(),\n status: \"not-applicable\"\n });\n\n return false;\n }\n return true;\n })\n .sort((a, b) => (a.getId() > b.getId() ? 1 : -1));\n\n this.logger.info(\n `Found %s applicable out of %s available migration(s).`,\n executableMigrations.length,\n this.migrations.length\n );\n\n // Are we're within the last 2 minutes of the execution time limit?\n const shouldCreateCheckpoint = () => {\n return this.timeLimiter() < 120000;\n };\n\n //\n for (const migration of executableMigrations) {\n const runItem = this.getOrCreateRunItem(lastRun, migration);\n const checkpoint = await this.repository.getCheckpoint(migration.getId());\n const logger = getChildLogger(this.logger, migration);\n\n if (checkpoint) {\n this.logger.info(checkpoint, `Found checkpoint ${migration.getId()}.`);\n }\n\n const context: DataMigrationContext = {\n projectVersion,\n logger,\n checkpoint,\n forceExecute: shouldForceExecute(migration),\n runningOutOfTime: shouldCreateCheckpoint,\n createCheckpoint: async (data: unknown) => {\n await this.createCheckpoint(migration, data);\n },\n createCheckpointAndExit: async (data: unknown) => {\n await this.createCheckpoint(migration, data);\n // We throw an error to break out of the migration execution completely.\n throw new MigrationNotFinished();\n }\n };\n try {\n const shouldExecute =\n checkpoint || shouldForceExecute(migration)\n ? true\n : await migration.shouldExecute(context);\n\n if (!shouldExecute) {\n this.logger.info(`Skipping migration %s.`, migration.getId());\n runItem.status = \"skipped\";\n\n await this.setRunItemAndSave(lastRun, runItem);\n\n await this.repository.logMigration({\n id: migration.getId(),\n description: migration.getDescription(),\n reason: \"skipped\"\n });\n\n continue;\n }\n\n lastRun.status = \"running\";\n runItem.status = \"running\";\n if (!runItem.startedOn) {\n runItem.startedOn = getCurrentISOTime();\n }\n await this.setRunItemAndSave(lastRun, runItem);\n this.logger.info(\n `Executing migration %s: %s`,\n migration.getId(),\n migration.getDescription()\n );\n await migration.execute(context);\n runItem.status = \"done\";\n } catch (err) {\n // If `MigrationNotFinished` was thrown, we will need to resume the migration.\n if (err instanceof MigrationNotFinished) {\n lastRun.status = \"pending\";\n runItem.status = \"pending\";\n return;\n }\n\n runItem.status = \"error\";\n lastRun.status = \"error\";\n lastRun.error = {\n name: err.name || \"Migration error\",\n message: err.message,\n stack: err.stack,\n data: err.data,\n code: err.code\n };\n this.logger.error(err, err.message);\n return;\n } finally {\n // We sum duration from the previous run with the current run.\n runItem.finishedOn = getCurrentISOTime();\n\n // Update run stats.\n await this.setRunItemAndSave(lastRun, runItem);\n\n this.logger.info(\n `Finished executing migration %s in %sms.`,\n migration.getId(),\n getRunItemDuration(runItem)\n );\n }\n\n await this.repository.logMigration({\n id: migration.getId(),\n description: migration.getDescription(),\n startedOn: runItem.startedOn,\n finishedOn: runItem.finishedOn,\n reason: \"executed\"\n });\n\n this.logger.info(`Deleting checkpoint ${migration.getId()}.`);\n await this.repository.deleteCheckpoint(migration.getId());\n }\n\n lastRun.status = \"done\";\n lastRun.finishedOn = getCurrentISOTime();\n await this.repository.saveRun(lastRun);\n\n this.logger.info(`Finished processing applicable migrations.`);\n }\n\n async getStatus(): Promise<MigrationStatus> {\n const lastRun = await this.repository.getLastRun();\n if (!lastRun) {\n throw new Error(`No migrations were ever executed!`);\n }\n\n // Since we don't store migration descriptions to DB, we need to fetch them from actual migration objects.\n const withDescriptions = lastRun.migrations.map(mig => {\n const dataMigration = this.migrations.find(dm => dm.getId() === mig.id);\n return {\n ...mig,\n description: dataMigration ? dataMigration.getDescription() : \"N/A\"\n };\n });\n\n return { ...lastRun, migrations: withDescriptions };\n }\n\n private validateIds(migrations: DataMigration[]) {\n const ids = new Set();\n for (const mig of migrations) {\n const id = mig.getId();\n if (id.endsWith(\"-000\")) {\n const error = new Error(`Migration ID must not end with \"000\": ${id}`);\n this.logger.error(error);\n throw error;\n }\n\n if (ids.has(id)) {\n const error = new Error(`Duplicate migration ID found: ${id}`);\n this.logger.error(error);\n throw error;\n }\n ids.add(id);\n }\n }\n\n private async createCheckpoint(migration: DataMigration, checkpoint: unknown) {\n this.logger.info(checkpoint, `Saving checkpoint ${migration.getId()}`);\n const execute = () => this.repository.createCheckpoint(migration.getId(), checkpoint);\n await executeWithRetry(execute);\n }\n\n private async getOrCreateRun() {\n const resolvedStatus: Array<MigrationRun[\"status\"]> = [\"done\", \"error\"];\n const unresolvedStatus: Array<MigrationRun[\"status\"]> = [\"init\", \"running\"];\n\n let lastRun = await this.repository.getLastRun();\n\n if (lastRun && unresolvedStatus.includes(lastRun.status)) {\n throw new MigrationInProgress(`Migration is already in progress (ID: ${lastRun.id})!`);\n }\n\n if (!lastRun || resolvedStatus.includes(lastRun.status)) {\n lastRun = {\n id: mdbid(),\n status: \"init\",\n startedOn: getCurrentISOTime(),\n finishedOn: \"\",\n migrations: [],\n context: this.context\n };\n\n await this.repository.saveRun(lastRun);\n }\n\n return lastRun;\n }\n\n private getOrCreateRunItem(run: MigrationRun, migration: DataMigration): MigrationRunItem {\n const existingItem = run.migrations.find(item => item.id === migration.getId());\n if (existingItem) {\n return {\n ...existingItem,\n status: \"running\"\n };\n }\n\n return {\n id: migration.getId(),\n status: \"running\"\n };\n }\n\n private setRunItem(run: MigrationRun, item: MigrationRunItem) {\n const index = run.migrations.findIndex(runItem => runItem.id === item.id);\n if (index < 0) {\n run.migrations.push(item);\n } else {\n run.migrations = [\n ...run.migrations.slice(0, index),\n item,\n ...run.migrations.slice(index + 1)\n ];\n }\n\n run.migrations = run.migrations.sort((a, b) => (a.id > b.id ? 1 : -1));\n }\n\n private async setRunItemAndSave(run: MigrationRun, item: MigrationRunItem) {\n this.setRunItem(run, item);\n await this.repository.saveRun(run);\n }\n}\n\nmakeInjectable(MigrationRunner, [\n inject(MigrationRepositorySymbol),\n inject(ExecutionTimeLimiterSymbol),\n inject(MigrationSymbol, { multi: true, optional: true }),\n inject(LoggerSymbol, { optional: true })\n]);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["_semver","require","_ioc","_utils","_symbols","_createPinoLogger","getCurrentISOTime","Date","toISOString","getRunItemDuration","runItem","startedOn","finishedOn","getTime","shouldForceExecute","mig","key","getId","replace","process","env","MigrationNotFinished","Error","MigrationInProgress","MigrationRunner","context","constructor","repository","timeLimiter","migrations","logger","createPinoLogger","setContext","execute","projectVersion","isApplicable","forceExecute","lastRun","getOrCreateRun","validateIds","err","status","error","message","saveRun","latestMigration","listMigrations","limit","info","currentVersion","coerce","startingId","id","lastId","logMigration","description","reason","defaultIsApplicable","isMigrationApplicable","printForceExecuteEnvVars","executableMigrations","filter","setRunItem","sort","a","b","length","shouldCreateCheckpoint","migration","getOrCreateRunItem","checkpoint","getCheckpoint","getChildLogger","runningOutOfTime","createCheckpoint","data","createCheckpointAndExit","shouldExecute","setRunItemAndSave","getDescription","name","stack","code","deleteCheckpoint","getStatus","getLastRun","withDescriptions","map","dataMigration","find","dm","ids","Set","endsWith","has","add","executeWithRetry","resolvedStatus","unresolvedStatus","includes","mdbid","run","existingItem","item","index","findIndex","push","slice","forceKeys","Object","keys","startsWith","exports","makeInjectable","inject","MigrationRepositorySymbol","ExecutionTimeLimiterSymbol","MigrationSymbol","multi","optional","LoggerSymbol"],"sources":["MigrationRunner.ts"],"sourcesContent":["import { coerce } from \"semver\";\nimport { Logger } from \"@webiny/logger\";\nimport { inject, makeInjectable } from \"@webiny/ioc\";\nimport { executeWithRetry, mdbid } from \"@webiny/utils\";\nimport {\n MigrationRepositorySymbol,\n LoggerSymbol,\n MigrationSymbol,\n ExecutionTimeLimiterSymbol\n} from \"./symbols\";\nimport { createPinoLogger, getChildLogger } from \"./createPinoLogger\";\nimport {\n MigrationRepository,\n DataMigration,\n DataMigrationContext,\n ExecutionTimeLimiter,\n MigrationRun,\n MigrationStatus,\n MigrationRunItem\n} from \"~/types\";\n\nexport type IsMigrationApplicable = (migration: DataMigration) => boolean;\n\nconst getCurrentISOTime = () => {\n return new Date().toISOString();\n};\n\nconst getRunItemDuration = (runItem: MigrationRunItem) => {\n if (!runItem.startedOn || !runItem.finishedOn) {\n return \"N/A\";\n }\n\n return new Date(runItem.finishedOn).getTime() - new Date(runItem.startedOn).getTime();\n};\n\n/**\n * This allows us to force-execute a migration, even if it's not in the list of the applicable migrations.\n * Example: WEBINY_MIGRATION_FORCE_EXECUTE_5_35_0_006=true\n */\nconst shouldForceExecute = (mig: DataMigration) => {\n const key = `WEBINY_MIGRATION_FORCE_EXECUTE_${mig.getId().replace(/[\\.\\-]/g, \"_\")}`;\n\n return process.env[key] === \"true\";\n};\n\nclass MigrationNotFinished extends Error {}\nclass MigrationInProgress extends Error {}\n\nexport class MigrationRunner {\n private readonly logger: Logger;\n private readonly migrations: DataMigration[];\n private readonly repository: MigrationRepository;\n private readonly timeLimiter: ExecutionTimeLimiter;\n private context: Record<string, any> = {};\n\n constructor(\n repository: MigrationRepository,\n timeLimiter: ExecutionTimeLimiter,\n migrations: DataMigration[],\n logger: Logger | undefined\n ) {\n this.repository = repository;\n this.timeLimiter = timeLimiter;\n this.migrations = migrations || [];\n\n if (!logger) {\n logger = createPinoLogger();\n }\n this.logger = logger;\n }\n\n setContext(context: Record<string, any>) {\n this.context = context;\n }\n\n async execute(\n projectVersion: string,\n isApplicable?: IsMigrationApplicable,\n // Force execute applicable migrations.\n forceExecute = false\n ) {\n const lastRun = await this.getOrCreateRun();\n\n try {\n this.validateIds(this.migrations);\n } catch (err) {\n lastRun.status = \"error\";\n lastRun.error = {\n message: err.message\n };\n await this.repository.saveRun(lastRun);\n return;\n }\n\n const [latestMigration] = await this.repository.listMigrations({ limit: 1 });\n\n this.logger.info(`Project version is %s.`, projectVersion);\n\n // Get current version, and coerce it to a valid SemVer.\n // With this, we can run migrations targeted for stable versions, released under a preid tag (e.g., `beta`).\n const currentVersion = coerce(projectVersion) + \"\";\n const startingId = latestMigration ? latestMigration.id : `${currentVersion}-000`;\n const lastId = `${currentVersion}-999`;\n\n // Create initial migration record.\n if (!latestMigration) {\n this.logger.info(\n `No migrations were ever executed. Creating initial migration record %s.`,\n startingId\n );\n await this.repository.logMigration({\n id: startingId,\n description: \"starting point for applicable migrations detection\",\n startedOn: getCurrentISOTime(),\n finishedOn: getCurrentISOTime(),\n reason: \"initial migration\"\n });\n } else {\n this.logger.info(`Latest migration ID is %s.`, latestMigration.id);\n }\n\n if (isApplicable) {\n this.logger.info(`Using custom \"isApplicable\" function.`);\n } else {\n this.logger.info(`Using migrations in the range of %s to %s.`, startingId, lastId);\n }\n\n const defaultIsApplicable: IsMigrationApplicable = mig => {\n return mig.getId() > startingId && mig.getId() <= lastId;\n };\n\n const isMigrationApplicable = isApplicable || defaultIsApplicable;\n\n this.printForceExecuteEnvVars();\n\n if (forceExecute) {\n this.logger.info(\n `ALL APPLICABLE MIGRATIONS WILL BE FORCE-EXECUTED! (via --force flag)`\n );\n }\n\n const executableMigrations = this.migrations\n .filter(mig => {\n if (shouldForceExecute(mig)) {\n return true;\n }\n\n if (!isMigrationApplicable(mig)) {\n this.setRunItem(lastRun, {\n id: mig.getId(),\n status: \"not-applicable\"\n });\n\n return false;\n }\n return true;\n })\n .sort((a, b) => (a.getId() > b.getId() ? 1 : -1));\n\n this.logger.info(\n `Found %s applicable out of %s available migration(s).`,\n executableMigrations.length,\n this.migrations.length\n );\n\n // Are we're within the last 2 minutes of the execution time limit?\n const shouldCreateCheckpoint = () => {\n return this.timeLimiter() < 120000;\n };\n\n //\n for (const migration of executableMigrations) {\n const runItem = this.getOrCreateRunItem(lastRun, migration);\n const checkpoint = await this.repository.getCheckpoint(migration.getId());\n const logger = getChildLogger(this.logger, migration);\n\n if (checkpoint) {\n this.logger.info(checkpoint, `Found checkpoint ${migration.getId()}.`);\n }\n\n const context: DataMigrationContext = {\n projectVersion,\n logger,\n checkpoint,\n forceExecute: forceExecute || shouldForceExecute(migration),\n runningOutOfTime: shouldCreateCheckpoint,\n createCheckpoint: async (data: unknown) => {\n await this.createCheckpoint(migration, data);\n },\n createCheckpointAndExit: async (data: unknown) => {\n await this.createCheckpoint(migration, data);\n // We throw an error to break out of the migration execution completely.\n throw new MigrationNotFinished();\n }\n };\n try {\n const shouldExecute =\n checkpoint || context.forceExecute\n ? true\n : await migration.shouldExecute(context);\n\n if (!shouldExecute) {\n this.logger.info(`Skipping migration %s.`, migration.getId());\n runItem.status = \"skipped\";\n\n await this.setRunItemAndSave(lastRun, runItem);\n\n await this.repository.logMigration({\n id: migration.getId(),\n description: migration.getDescription(),\n reason: \"skipped\"\n });\n\n continue;\n }\n\n lastRun.status = \"running\";\n runItem.status = \"running\";\n if (!runItem.startedOn) {\n runItem.startedOn = getCurrentISOTime();\n }\n await this.setRunItemAndSave(lastRun, runItem);\n this.logger.info(\n `Executing migration %s: %s`,\n migration.getId(),\n migration.getDescription()\n );\n await migration.execute(context);\n runItem.status = \"done\";\n } catch (err) {\n // If `MigrationNotFinished` was thrown, we will need to resume the migration.\n if (err instanceof MigrationNotFinished) {\n lastRun.status = \"pending\";\n runItem.status = \"pending\";\n return;\n }\n\n runItem.status = \"error\";\n lastRun.status = \"error\";\n lastRun.error = {\n name: err.name || \"Migration error\",\n message: err.message,\n stack: err.stack,\n data: err.data,\n code: err.code\n };\n this.logger.error(err, err.message);\n return;\n } finally {\n // We sum duration from the previous run with the current run.\n runItem.finishedOn = getCurrentISOTime();\n\n // Update run stats.\n await this.setRunItemAndSave(lastRun, runItem);\n\n this.logger.info(\n `Finished executing migration %s in %sms.`,\n migration.getId(),\n getRunItemDuration(runItem)\n );\n }\n\n await this.repository.logMigration({\n id: migration.getId(),\n description: migration.getDescription(),\n startedOn: runItem.startedOn,\n finishedOn: runItem.finishedOn,\n reason: \"executed\"\n });\n\n this.logger.info(`Deleting checkpoint ${migration.getId()}.`);\n await this.repository.deleteCheckpoint(migration.getId());\n }\n\n lastRun.status = \"done\";\n lastRun.finishedOn = getCurrentISOTime();\n await this.repository.saveRun(lastRun);\n\n this.logger.info(`Finished processing applicable migrations.`);\n }\n\n async getStatus(): Promise<MigrationStatus> {\n const lastRun = await this.repository.getLastRun();\n if (!lastRun) {\n throw new Error(`No migrations were ever executed!`);\n }\n\n // Since we don't store migration descriptions to DB, we need to fetch them from actual migration objects.\n const withDescriptions = lastRun.migrations.map(mig => {\n const dataMigration = this.migrations.find(dm => dm.getId() === mig.id);\n return {\n ...mig,\n description: dataMigration ? dataMigration.getDescription() : \"N/A\"\n };\n });\n\n return { ...lastRun, migrations: withDescriptions };\n }\n\n private validateIds(migrations: DataMigration[]) {\n const ids = new Set();\n for (const mig of migrations) {\n const id = mig.getId();\n if (id.endsWith(\"-000\")) {\n const error = new Error(`Migration ID must not end with \"000\": ${id}`);\n this.logger.error(error);\n throw error;\n }\n\n if (ids.has(id)) {\n const error = new Error(`Duplicate migration ID found: ${id}`);\n this.logger.error(error);\n throw error;\n }\n ids.add(id);\n }\n }\n\n private async createCheckpoint(migration: DataMigration, checkpoint: unknown) {\n this.logger.info(checkpoint, `Saving checkpoint ${migration.getId()}`);\n const execute = () => this.repository.createCheckpoint(migration.getId(), checkpoint);\n await executeWithRetry(execute);\n }\n\n private async getOrCreateRun() {\n const resolvedStatus: Array<MigrationRun[\"status\"]> = [\"done\", \"error\"];\n const unresolvedStatus: Array<MigrationRun[\"status\"]> = [\"init\", \"running\"];\n\n let lastRun = await this.repository.getLastRun();\n\n if (lastRun && unresolvedStatus.includes(lastRun.status)) {\n throw new MigrationInProgress(`Migration is already in progress (ID: ${lastRun.id})!`);\n }\n\n if (!lastRun || resolvedStatus.includes(lastRun.status)) {\n lastRun = {\n id: mdbid(),\n status: \"init\",\n startedOn: getCurrentISOTime(),\n finishedOn: \"\",\n migrations: [],\n context: this.context\n };\n\n await this.repository.saveRun(lastRun);\n }\n\n return lastRun;\n }\n\n private getOrCreateRunItem(run: MigrationRun, migration: DataMigration): MigrationRunItem {\n const existingItem = run.migrations.find(item => item.id === migration.getId());\n if (existingItem) {\n return {\n ...existingItem,\n status: \"running\"\n };\n }\n\n return {\n id: migration.getId(),\n status: \"running\"\n };\n }\n\n private setRunItem(run: MigrationRun, item: MigrationRunItem) {\n const index = run.migrations.findIndex(runItem => runItem.id === item.id);\n if (index < 0) {\n run.migrations.push(item);\n } else {\n run.migrations = [\n ...run.migrations.slice(0, index),\n item,\n ...run.migrations.slice(index + 1)\n ];\n }\n\n run.migrations = run.migrations.sort((a, b) => (a.id > b.id ? 1 : -1));\n }\n\n private async setRunItemAndSave(run: MigrationRun, item: MigrationRunItem) {\n this.setRunItem(run, item);\n await this.repository.saveRun(run);\n }\n\n private printForceExecuteEnvVars() {\n const forceKeys = Object.keys(process.env).filter(key =>\n key.startsWith(\"WEBINY_MIGRATION_FORCE_EXECUTE_\")\n );\n\n if (!forceKeys.length) {\n this.logger.info(\n `No migrations are enforced via WEBINY_MIGRATION_FORCE_EXECUTE environment variable.`\n );\n\n return;\n }\n\n this.logger.info(`FORCED MIGRATIONS DETECTED!`);\n for (const key of forceKeys) {\n this.logger.info(`${key}=${process.env[key]}`);\n }\n }\n}\n\nmakeInjectable(MigrationRunner, [\n inject(MigrationRepositorySymbol),\n inject(ExecutionTimeLimiterSymbol),\n inject(MigrationSymbol, { multi: true, optional: true }),\n inject(LoggerSymbol, { optional: true })\n]);\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { MigrationRunnerResult, MigrationRunReporter } from "
|
|
1
|
+
import { MigrationRunnerResult, MigrationRunReporter } from "./";
|
|
2
2
|
import { CliContext } from "@webiny/cli/types";
|
|
3
|
-
import { LogReporter } from "
|
|
3
|
+
import { LogReporter } from "./";
|
|
4
4
|
export declare class CliMigrationRunReporter implements MigrationRunReporter {
|
|
5
5
|
private context;
|
|
6
6
|
private logReporter;
|
package/cli/MigrationRunner.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_clientLambda","require","_utils","_VoidStatusReporter","MigrationRunnerResult","successBranch","errorBranch","constructor","functionName","result","getFunctionName","onSuccess","cb","push","onError","process","error","handler","data","exports","MigrationRunner","statusReporter","VoidStatusReporter","create","params","runner","lambdaClient","setStatusReporter","reporter","runMigration","payload","invokeMigration","response","Promise","resolve","setTimeout","getMigrationStatusReportInterval","getStatus","getResult","status","reportStatus","report","send","InvokeCommand","FunctionName","InvocationType","Payload","JSON","stringify","command","StatusCode","executeWithRetry","decoder","TextDecoder","parse","decode","envKey","env","parseInt","String"],"sources":["MigrationRunner.ts"],"sourcesContent":["import { InvokeCommand, LambdaClient } from \"@webiny/aws-sdk/client-lambda\";\nimport { MigrationStatusReporter } from \"~/cli/MigrationStatusReporter\";\nimport {\n MigrationEventHandlerResponse,\n MigrationInvocationErrorResponse,\n MigrationStatus,\n MigrationStatusResponse\n} from \"~/types\";\nimport { executeWithRetry } from \"@webiny/utils\";\nimport { VoidStatusReporter } from \"./VoidStatusReporter\";\n\ninterface MigrationRunnerConfig {\n lambdaClient: LambdaClient;\n functionName: string;\n statusReporter?: MigrationStatusReporter;\n}\n\ninterface MigrationPayload {\n version: string;\n pattern?: string;\n}\n\ninterface SuccessResultHandler {\n (result: MigrationStatusResponse[\"data\"]): void | Promise<void>;\n}\n\ninterface ErrorResultHandler {\n (error: MigrationInvocationErrorResponse[\"error\"]): void | Promise<void>;\n}\n\nexport class MigrationRunnerResult {\n private readonly functionName: string;\n private readonly result: MigrationStatusResponse | MigrationInvocationErrorResponse;\n private readonly successBranch: SuccessResultHandler[] = [];\n private readonly errorBranch: ErrorResultHandler[] = [];\n\n constructor(\n functionName: string,\n result: MigrationStatusResponse | MigrationInvocationErrorResponse\n ) {\n this.functionName = functionName;\n this.result = result;\n }\n\n getFunctionName() {\n return this.functionName;\n }\n\n onSuccess(cb: SuccessResultHandler) {\n this.successBranch.push(cb);\n }\n\n onError(cb: ErrorResultHandler) {\n this.errorBranch.push(cb);\n }\n\n async process(): Promise<void> {\n if (this.result.error) {\n for (const handler of this.errorBranch) {\n await handler(this.result.error);\n }\n return;\n }\n\n for (const handler of this.successBranch) {\n await handler(this.result.data);\n }\n }\n}\n\nexport class MigrationRunner {\n private readonly lambdaClient: LambdaClient;\n private readonly functionName: string;\n private statusReporter: MigrationStatusReporter = new VoidStatusReporter();\n\n public static create(params: MigrationRunnerConfig) {\n const runner = new MigrationRunner(params.lambdaClient, params.functionName);\n if (params.statusReporter) {\n runner.setStatusReporter(params.statusReporter);\n }\n return runner;\n }\n\n private constructor(lambdaClient: LambdaClient, functionName: string) {\n this.lambdaClient = lambdaClient;\n this.functionName = functionName;\n }\n\n public setStatusReporter(reporter: MigrationStatusReporter) {\n this.statusReporter = reporter;\n }\n\n async runMigration(payload: MigrationPayload): Promise<MigrationRunnerResult> {\n // Execute migration function.\n await this.invokeMigration(payload);\n\n // Poll for status and re-execute when migration is in \"pending\" state.\n let response: MigrationEventHandlerResponse;\n\n while (true) {\n await new Promise(resolve =>\n setTimeout(resolve, this.getMigrationStatusReportInterval())\n );\n\n response = await this.getStatus(payload);\n\n if (!response) {\n continue;\n }\n\n const { data, error } = response;\n\n // If we received an error, it must be an unrecoverable error, and we don't retry.\n if (error) {\n return this.getResult(response);\n }\n\n switch (data.status) {\n case \"init\":\n await this.reportStatus(data);\n continue;\n case \"pending\":\n await this.invokeMigration(payload);\n break;\n case \"running\":\n await this.reportStatus(data);\n break;\n case \"done\":\n await this.reportStatus(data);\n return this.getResult(response);\n default:\n return this.getResult(response);\n }\n }\n }\n\n private async reportStatus(data: MigrationStatus) {\n await this.statusReporter.report(data);\n }\n\n private async invokeMigration(payload: MigrationPayload) {\n const response = await this.lambdaClient.send(\n new InvokeCommand({\n FunctionName: this.functionName,\n InvocationType: \"Event\",\n Payload: JSON.stringify({ ...payload, command: \"execute\" })\n })\n );\n\n return response.StatusCode;\n }\n\n private getResult(response: MigrationStatusResponse | MigrationInvocationErrorResponse) {\n return new MigrationRunnerResult(this.functionName, response);\n }\n\n private async getStatus(payload: Record<string, any>) {\n const getStatus = () => {\n return this.lambdaClient.send(\n new InvokeCommand({\n FunctionName: this.functionName,\n InvocationType: \"RequestResponse\",\n Payload: JSON.stringify({ ...payload, command: \"status\" })\n })\n );\n };\n\n const response = await executeWithRetry(getStatus);\n\n const decoder = new TextDecoder(\"utf-8\");\n return JSON.parse(decoder.decode(response.Payload)) as MigrationEventHandlerResponse;\n }\n\n private getMigrationStatusReportInterval() {\n const envKey = \"MIGRATION_STATUS_REPORT_INTERVAL\";\n if (envKey in process.env) {\n return parseInt(String(process.env[envKey]));\n }\n return 2000;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["_clientLambda","require","_utils","_VoidStatusReporter","MigrationRunnerResult","successBranch","errorBranch","constructor","functionName","result","getFunctionName","onSuccess","cb","push","onError","process","error","handler","data","exports","MigrationRunner","statusReporter","VoidStatusReporter","create","params","runner","lambdaClient","setStatusReporter","reporter","runMigration","payload","invokeMigration","response","Promise","resolve","setTimeout","getMigrationStatusReportInterval","getStatus","getResult","status","reportStatus","report","send","InvokeCommand","FunctionName","InvocationType","Payload","JSON","stringify","command","StatusCode","executeWithRetry","decoder","TextDecoder","parse","decode","envKey","env","parseInt","String"],"sources":["MigrationRunner.ts"],"sourcesContent":["import { InvokeCommand, LambdaClient } from \"@webiny/aws-sdk/client-lambda\";\nimport { MigrationStatusReporter } from \"~/cli/MigrationStatusReporter\";\nimport {\n MigrationEventHandlerResponse,\n MigrationInvocationErrorResponse,\n MigrationStatus,\n MigrationStatusResponse\n} from \"~/types\";\nimport { executeWithRetry } from \"@webiny/utils\";\nimport { VoidStatusReporter } from \"./VoidStatusReporter\";\n\ninterface MigrationRunnerConfig {\n lambdaClient: LambdaClient;\n functionName: string;\n statusReporter?: MigrationStatusReporter;\n}\n\ninterface MigrationPayload {\n version: string;\n pattern?: string;\n force?: boolean;\n}\n\ninterface SuccessResultHandler {\n (result: MigrationStatusResponse[\"data\"]): void | Promise<void>;\n}\n\ninterface ErrorResultHandler {\n (error: MigrationInvocationErrorResponse[\"error\"]): void | Promise<void>;\n}\n\nexport class MigrationRunnerResult {\n private readonly functionName: string;\n private readonly result: MigrationStatusResponse | MigrationInvocationErrorResponse;\n private readonly successBranch: SuccessResultHandler[] = [];\n private readonly errorBranch: ErrorResultHandler[] = [];\n\n constructor(\n functionName: string,\n result: MigrationStatusResponse | MigrationInvocationErrorResponse\n ) {\n this.functionName = functionName;\n this.result = result;\n }\n\n getFunctionName() {\n return this.functionName;\n }\n\n onSuccess(cb: SuccessResultHandler) {\n this.successBranch.push(cb);\n }\n\n onError(cb: ErrorResultHandler) {\n this.errorBranch.push(cb);\n }\n\n async process(): Promise<void> {\n if (this.result.error) {\n for (const handler of this.errorBranch) {\n await handler(this.result.error);\n }\n return;\n }\n\n for (const handler of this.successBranch) {\n await handler(this.result.data);\n }\n }\n}\n\nexport class MigrationRunner {\n private readonly lambdaClient: LambdaClient;\n private readonly functionName: string;\n private statusReporter: MigrationStatusReporter = new VoidStatusReporter();\n\n public static create(params: MigrationRunnerConfig) {\n const runner = new MigrationRunner(params.lambdaClient, params.functionName);\n if (params.statusReporter) {\n runner.setStatusReporter(params.statusReporter);\n }\n return runner;\n }\n\n private constructor(lambdaClient: LambdaClient, functionName: string) {\n this.lambdaClient = lambdaClient;\n this.functionName = functionName;\n }\n\n public setStatusReporter(reporter: MigrationStatusReporter) {\n this.statusReporter = reporter;\n }\n\n async runMigration(payload: MigrationPayload): Promise<MigrationRunnerResult> {\n // Execute migration function.\n await this.invokeMigration(payload);\n\n // Poll for status and re-execute when migration is in \"pending\" state.\n let response: MigrationEventHandlerResponse;\n\n while (true) {\n await new Promise(resolve =>\n setTimeout(resolve, this.getMigrationStatusReportInterval())\n );\n\n response = await this.getStatus(payload);\n\n if (!response) {\n continue;\n }\n\n const { data, error } = response;\n\n // If we received an error, it must be an unrecoverable error, and we don't retry.\n if (error) {\n return this.getResult(response);\n }\n\n switch (data.status) {\n case \"init\":\n await this.reportStatus(data);\n continue;\n case \"pending\":\n await this.invokeMigration(payload);\n break;\n case \"running\":\n await this.reportStatus(data);\n break;\n case \"done\":\n await this.reportStatus(data);\n return this.getResult(response);\n default:\n return this.getResult(response);\n }\n }\n }\n\n private async reportStatus(data: MigrationStatus) {\n await this.statusReporter.report(data);\n }\n\n private async invokeMigration(payload: MigrationPayload) {\n const response = await this.lambdaClient.send(\n new InvokeCommand({\n FunctionName: this.functionName,\n InvocationType: \"Event\",\n Payload: JSON.stringify({ ...payload, command: \"execute\" })\n })\n );\n\n return response.StatusCode;\n }\n\n private getResult(response: MigrationStatusResponse | MigrationInvocationErrorResponse) {\n return new MigrationRunnerResult(this.functionName, response);\n }\n\n private async getStatus(payload: Record<string, any>) {\n const getStatus = () => {\n return this.lambdaClient.send(\n new InvokeCommand({\n FunctionName: this.functionName,\n InvocationType: \"RequestResponse\",\n Payload: JSON.stringify({ ...payload, command: \"status\" })\n })\n );\n };\n\n const response = await executeWithRetry(getStatus);\n\n const decoder = new TextDecoder(\"utf-8\");\n return JSON.parse(decoder.decode(response.Payload)) as MigrationEventHandlerResponse;\n }\n\n private getMigrationStatusReportInterval() {\n const envKey = \"MIGRATION_STATUS_REPORT_INTERVAL\";\n if (envKey in process.env) {\n return parseInt(String(process.env[envKey]));\n }\n return 2000;\n }\n}\n"],"mappings":"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"}
|
package/createPinoLogger.d.ts
CHANGED
|
@@ -4,10 +4,23 @@ export declare const createPinoLogger: () => Logger<{
|
|
|
4
4
|
level: string;
|
|
5
5
|
redact?: string[] | import("@webiny/logger").RedactOptions | undefined;
|
|
6
6
|
transport?: import("pino").default.TransportSingleOptions<Record<string, any>> | import("pino").default.TransportMultiOptions<Record<string, any>> | import("pino").default.TransportPipelineOptions<Record<string, any>> | undefined;
|
|
7
|
+
safe?: boolean | undefined;
|
|
7
8
|
name?: string | undefined;
|
|
8
|
-
|
|
9
|
-
[key: string]:
|
|
10
|
-
} |
|
|
9
|
+
serializers?: {
|
|
10
|
+
[key: string]: import("pino").default.SerializerFn;
|
|
11
|
+
} | undefined;
|
|
12
|
+
timestamp?: boolean | (() => string) | undefined;
|
|
13
|
+
customLevels?: {
|
|
14
|
+
[key: string]: number;
|
|
15
|
+
} | undefined;
|
|
16
|
+
useOnlyCustomLevels?: boolean | undefined;
|
|
17
|
+
mixin?: ((mergeObject: object, level: number) => object) | undefined;
|
|
18
|
+
mixinMergeStrategy?: ((mergeObject: object, mixinObject: object) => object) | undefined;
|
|
19
|
+
levelVal?: number | undefined;
|
|
20
|
+
messageKey?: string | undefined;
|
|
21
|
+
errorKey?: string | undefined;
|
|
22
|
+
nestedKey?: string | undefined;
|
|
23
|
+
enabled?: boolean | undefined;
|
|
11
24
|
browser?: {
|
|
12
25
|
asObject?: boolean | undefined;
|
|
13
26
|
write?: import("pino").default.WriteFn | ({
|
|
@@ -26,23 +39,9 @@ export declare const createPinoLogger: () => Logger<{
|
|
|
26
39
|
send: (level: import("pino").default.Level, logEvent: import("pino").default.LogEvent) => void;
|
|
27
40
|
} | undefined;
|
|
28
41
|
} | undefined;
|
|
29
|
-
|
|
30
|
-
[key: string]:
|
|
31
|
-
} | undefined;
|
|
32
|
-
useOnlyCustomLevels?: boolean | undefined;
|
|
33
|
-
levelVal?: number | undefined;
|
|
34
|
-
onChild?: (<ChildOptions extends import("pino").default.ChildLoggerOptions>(child: import("pino").default.Logger<import("pino").LoggerOptions & ChildOptions>) => void) | undefined;
|
|
35
|
-
safe?: boolean | undefined;
|
|
36
|
-
serializers?: {
|
|
37
|
-
[key: string]: import("pino").default.SerializerFn;
|
|
38
|
-
} | undefined;
|
|
39
|
-
timestamp?: boolean | (() => string) | undefined;
|
|
40
|
-
mixin?: ((mergeObject: object, level: number) => object) | undefined;
|
|
41
|
-
mixinMergeStrategy?: ((mergeObject: object, mixinObject: object) => object) | undefined;
|
|
42
|
-
messageKey?: string | undefined;
|
|
43
|
-
errorKey?: string | undefined;
|
|
44
|
-
nestedKey?: string | undefined;
|
|
45
|
-
enabled?: boolean | undefined;
|
|
42
|
+
base?: {
|
|
43
|
+
[key: string]: any;
|
|
44
|
+
} | null | undefined;
|
|
46
45
|
formatters?: {
|
|
47
46
|
level?: ((label: string, number: number) => object) | undefined;
|
|
48
47
|
bindings?: ((bindings: import("pino").default.Bindings) => object) | undefined;
|
|
@@ -54,6 +53,7 @@ export declare const createPinoLogger: () => Logger<{
|
|
|
54
53
|
} | undefined;
|
|
55
54
|
depthLimit?: number | undefined;
|
|
56
55
|
edgeLimit?: number | undefined;
|
|
56
|
+
onChild?: (<ChildOptions extends import("pino").default.ChildLoggerOptions>(child: import("pino").default.Logger<import("pino").LoggerOptions & ChildOptions>) => void) | undefined;
|
|
57
57
|
}>;
|
|
58
58
|
export declare const getChildLogger: (logger: Logger, migration: DataMigration) => import("pino").default.Logger<import("pino").LoggerOptions & {
|
|
59
59
|
msgPrefix: string;
|
|
@@ -26,6 +26,7 @@ const createDdbEsProjectMigration = ({
|
|
|
26
26
|
lambdaContext
|
|
27
27
|
}) => {
|
|
28
28
|
const projectVersion = String(payload?.version || process.env.WEBINY_VERSION);
|
|
29
|
+
const forceExecute = payload.force === true;
|
|
29
30
|
const version = (0, _semver.coerce)(projectVersion);
|
|
30
31
|
if (version?.version === "0.0.0") {
|
|
31
32
|
return (0, _devVersionErrorResponse.devVersionErrorResponse)();
|
|
@@ -63,7 +64,7 @@ const createDdbEsProjectMigration = ({
|
|
|
63
64
|
logStreamName: process.env.AWS_LAMBDA_LOG_STREAM_NAME
|
|
64
65
|
});
|
|
65
66
|
if (payload.command === "execute") {
|
|
66
|
-
await runner.execute(projectVersion, patternMatcher || isMigrationApplicable);
|
|
67
|
+
await runner.execute(projectVersion, patternMatcher || isMigrationApplicable, forceExecute);
|
|
67
68
|
return;
|
|
68
69
|
}
|
|
69
70
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_handlerAws","require","_ioc","_symbols","_MigrationRunner","_migrations","_devVersionErrorResponse","_createPatternMatcher","_semver","createDdbEsProjectMigration","migrations","elasticsearchClient","primaryTable","dynamoToEsTable","isMigrationApplicable","undefined","repository","config","createRawEventHandler","payload","lambdaContext","projectVersion","String","version","process","env","WEBINY_VERSION","semverCoerce","devVersionErrorResponse","container","createContainer","bind","PrimaryDynamoTableSymbol","toConstantValue","ElasticsearchDynamoTableSymbol","ElasticsearchClientSymbol","timeLimiter","getRemainingTimeInMillis","ExecutionTimeLimiterSymbol","MigrationRepositorySymbol","to","MigrationRepositoryImpl","forEach","migration","MigrationSymbol","patternMatcher","pattern","createPatternMatcher","runner","resolve","MigrationRunner","setContext","logGroupName","AWS_LAMBDA_LOG_GROUP_NAME","logStreamName","AWS_LAMBDA_LOG_STREAM_NAME","command","execute","data","getStatus","err","error","message","exports"],"sources":["createDdbEsProjectMigration.ts"],"sourcesContent":["import { Client as ElasticsearchClient } from \"@elastic/elasticsearch\";\nimport { Table } from \"@webiny/db-dynamodb/toolbox\";\nimport { createRawEventHandler } from \"@webiny/handler-aws\";\nimport { Constructor, createContainer } from \"@webiny/ioc\";\nimport {\n DataMigration,\n ExecutionTimeLimiter,\n MigrationEventHandlerResponse,\n MigrationEventPayload,\n MigrationRepository\n} from \"~/types\";\nimport {\n ElasticsearchClientSymbol,\n ElasticsearchDynamoTableSymbol,\n ExecutionTimeLimiterSymbol,\n MigrationRepositorySymbol,\n MigrationSymbol,\n PrimaryDynamoTableSymbol\n} from \"~/symbols\";\nimport { IsMigrationApplicable, MigrationRunner } from \"~/MigrationRunner\";\nimport { MigrationRepositoryImpl } from \"~/repository/migrations.repository\";\nimport { devVersionErrorResponse } from \"~/handlers/devVersionErrorResponse\";\nimport { createPatternMatcher } from \"~/handlers/createPatternMatcher\";\nimport { coerce as semverCoerce } from \"semver\";\n\ninterface CreateDdbEsDataMigrationConfig {\n elasticsearchClient: ElasticsearchClient;\n primaryTable: Table<string, string, string>;\n dynamoToEsTable: Table<string, string, string>;\n migrations: Constructor<DataMigration>[];\n isMigrationApplicable?: IsMigrationApplicable;\n repository?: MigrationRepository;\n timeLimiter?: ExecutionTimeLimiter;\n}\n\nexport const createDdbEsProjectMigration = ({\n migrations,\n elasticsearchClient,\n primaryTable,\n dynamoToEsTable,\n isMigrationApplicable = undefined,\n repository = undefined,\n ...config\n}: CreateDdbEsDataMigrationConfig) => {\n return createRawEventHandler<MigrationEventPayload, any, MigrationEventHandlerResponse>(\n async ({ payload, lambdaContext }) => {\n const projectVersion = String(payload?.version || process.env.WEBINY_VERSION);\n\n const version = semverCoerce(projectVersion);\n if (version?.version === \"0.0.0\") {\n return devVersionErrorResponse();\n }\n\n // COMPOSITION ROOT\n const container = createContainer();\n container.bind(PrimaryDynamoTableSymbol).toConstantValue(primaryTable);\n container.bind(ElasticsearchDynamoTableSymbol).toConstantValue(dynamoToEsTable);\n container.bind(ElasticsearchClientSymbol).toConstantValue(elasticsearchClient);\n\n const timeLimiter: ExecutionTimeLimiter =\n config.timeLimiter || lambdaContext?.getRemainingTimeInMillis || (() => 0);\n container.bind(ExecutionTimeLimiterSymbol).toConstantValue(timeLimiter);\n\n if (repository) {\n // Repository implementation provided by the user.\n container.bind(MigrationRepositorySymbol).toConstantValue(repository);\n } else {\n // Default repository implementation.\n container.bind(MigrationRepositorySymbol).to(MigrationRepositoryImpl);\n }\n\n // Bind the provided migrations.\n migrations.forEach(migration => container.bind(MigrationSymbol).to(migration));\n\n // If handler was invoked with a `pattern`, filter migrations that match the pattern only.\n let patternMatcher;\n if (payload.pattern) {\n patternMatcher = createPatternMatcher(payload.pattern);\n }\n\n // Inject dependencies and execute.\n try {\n const runner = await container.resolve(MigrationRunner);\n runner.setContext({\n logGroupName: process.env.AWS_LAMBDA_LOG_GROUP_NAME,\n logStreamName: process.env.AWS_LAMBDA_LOG_STREAM_NAME\n });\n\n if (payload.command === \"execute\") {\n await runner.execute(projectVersion
|
|
1
|
+
{"version":3,"names":["_handlerAws","require","_ioc","_symbols","_MigrationRunner","_migrations","_devVersionErrorResponse","_createPatternMatcher","_semver","createDdbEsProjectMigration","migrations","elasticsearchClient","primaryTable","dynamoToEsTable","isMigrationApplicable","undefined","repository","config","createRawEventHandler","payload","lambdaContext","projectVersion","String","version","process","env","WEBINY_VERSION","forceExecute","force","semverCoerce","devVersionErrorResponse","container","createContainer","bind","PrimaryDynamoTableSymbol","toConstantValue","ElasticsearchDynamoTableSymbol","ElasticsearchClientSymbol","timeLimiter","getRemainingTimeInMillis","ExecutionTimeLimiterSymbol","MigrationRepositorySymbol","to","MigrationRepositoryImpl","forEach","migration","MigrationSymbol","patternMatcher","pattern","createPatternMatcher","runner","resolve","MigrationRunner","setContext","logGroupName","AWS_LAMBDA_LOG_GROUP_NAME","logStreamName","AWS_LAMBDA_LOG_STREAM_NAME","command","execute","data","getStatus","err","error","message","exports"],"sources":["createDdbEsProjectMigration.ts"],"sourcesContent":["import { Client as ElasticsearchClient } from \"@elastic/elasticsearch\";\nimport { Table } from \"@webiny/db-dynamodb/toolbox\";\nimport { createRawEventHandler } from \"@webiny/handler-aws\";\nimport { Constructor, createContainer } from \"@webiny/ioc\";\nimport {\n DataMigration,\n ExecutionTimeLimiter,\n MigrationEventHandlerResponse,\n MigrationEventPayload,\n MigrationRepository\n} from \"~/types\";\nimport {\n ElasticsearchClientSymbol,\n ElasticsearchDynamoTableSymbol,\n ExecutionTimeLimiterSymbol,\n MigrationRepositorySymbol,\n MigrationSymbol,\n PrimaryDynamoTableSymbol\n} from \"~/symbols\";\nimport { IsMigrationApplicable, MigrationRunner } from \"~/MigrationRunner\";\nimport { MigrationRepositoryImpl } from \"~/repository/migrations.repository\";\nimport { devVersionErrorResponse } from \"~/handlers/devVersionErrorResponse\";\nimport { createPatternMatcher } from \"~/handlers/createPatternMatcher\";\nimport { coerce as semverCoerce } from \"semver\";\n\ninterface CreateDdbEsDataMigrationConfig {\n elasticsearchClient: ElasticsearchClient;\n primaryTable: Table<string, string, string>;\n dynamoToEsTable: Table<string, string, string>;\n migrations: Constructor<DataMigration>[];\n isMigrationApplicable?: IsMigrationApplicable;\n repository?: MigrationRepository;\n timeLimiter?: ExecutionTimeLimiter;\n}\n\nexport const createDdbEsProjectMigration = ({\n migrations,\n elasticsearchClient,\n primaryTable,\n dynamoToEsTable,\n isMigrationApplicable = undefined,\n repository = undefined,\n ...config\n}: CreateDdbEsDataMigrationConfig) => {\n return createRawEventHandler<MigrationEventPayload, any, MigrationEventHandlerResponse>(\n async ({ payload, lambdaContext }) => {\n const projectVersion = String(payload?.version || process.env.WEBINY_VERSION);\n const forceExecute = payload.force === true;\n\n const version = semverCoerce(projectVersion);\n if (version?.version === \"0.0.0\") {\n return devVersionErrorResponse();\n }\n\n // COMPOSITION ROOT\n const container = createContainer();\n container.bind(PrimaryDynamoTableSymbol).toConstantValue(primaryTable);\n container.bind(ElasticsearchDynamoTableSymbol).toConstantValue(dynamoToEsTable);\n container.bind(ElasticsearchClientSymbol).toConstantValue(elasticsearchClient);\n\n const timeLimiter: ExecutionTimeLimiter =\n config.timeLimiter || lambdaContext?.getRemainingTimeInMillis || (() => 0);\n container.bind(ExecutionTimeLimiterSymbol).toConstantValue(timeLimiter);\n\n if (repository) {\n // Repository implementation provided by the user.\n container.bind(MigrationRepositorySymbol).toConstantValue(repository);\n } else {\n // Default repository implementation.\n container.bind(MigrationRepositorySymbol).to(MigrationRepositoryImpl);\n }\n\n // Bind the provided migrations.\n migrations.forEach(migration => container.bind(MigrationSymbol).to(migration));\n\n // If handler was invoked with a `pattern`, filter migrations that match the pattern only.\n let patternMatcher;\n if (payload.pattern) {\n patternMatcher = createPatternMatcher(payload.pattern);\n }\n\n // Inject dependencies and execute.\n try {\n const runner = await container.resolve(MigrationRunner);\n runner.setContext({\n logGroupName: process.env.AWS_LAMBDA_LOG_GROUP_NAME,\n logStreamName: process.env.AWS_LAMBDA_LOG_STREAM_NAME\n });\n\n if (payload.command === \"execute\") {\n await runner.execute(\n projectVersion,\n patternMatcher || isMigrationApplicable,\n forceExecute\n );\n return;\n }\n\n return { data: await runner.getStatus() };\n } catch (err) {\n return { error: { message: err.message } };\n }\n }\n );\n};\n"],"mappings":";;;;;;AAEA,IAAAA,WAAA,GAAAC,OAAA;AACA,IAAAC,IAAA,GAAAD,OAAA;AAQA,IAAAE,QAAA,GAAAF,OAAA;AAQA,IAAAG,gBAAA,GAAAH,OAAA;AACA,IAAAI,WAAA,GAAAJ,OAAA;AACA,IAAAK,wBAAA,GAAAL,OAAA;AACA,IAAAM,qBAAA,GAAAN,OAAA;AACA,IAAAO,OAAA,GAAAP,OAAA;AAYO,MAAMQ,2BAA2B,GAAGA,CAAC;EACxCC,UAAU;EACVC,mBAAmB;EACnBC,YAAY;EACZC,eAAe;EACfC,qBAAqB,GAAGC,SAAS;EACjCC,UAAU,GAAGD,SAAS;EACtB,GAAGE;AACyB,CAAC,KAAK;EAClC,OAAO,IAAAC,iCAAqB,EACxB,OAAO;IAAEC,OAAO;IAAEC;EAAc,CAAC,KAAK;IAClC,MAAMC,cAAc,GAAGC,MAAM,CAACH,OAAO,EAAEI,OAAO,IAAIC,OAAO,CAACC,GAAG,CAACC,cAAc,CAAC;IAC7E,MAAMC,YAAY,GAAGR,OAAO,CAACS,KAAK,KAAK,IAAI;IAE3C,MAAML,OAAO,GAAG,IAAAM,cAAY,EAACR,cAAc,CAAC;IAC5C,IAAIE,OAAO,EAAEA,OAAO,KAAK,OAAO,EAAE;MAC9B,OAAO,IAAAO,gDAAuB,EAAC,CAAC;IACpC;;IAEA;IACA,MAAMC,SAAS,GAAG,IAAAC,oBAAe,EAAC,CAAC;IACnCD,SAAS,CAACE,IAAI,CAACC,iCAAwB,CAAC,CAACC,eAAe,CAACvB,YAAY,CAAC;IACtEmB,SAAS,CAACE,IAAI,CAACG,uCAA8B,CAAC,CAACD,eAAe,CAACtB,eAAe,CAAC;IAC/EkB,SAAS,CAACE,IAAI,CAACI,kCAAyB,CAAC,CAACF,eAAe,CAACxB,mBAAmB,CAAC;IAE9E,MAAM2B,WAAiC,GACnCrB,MAAM,CAACqB,WAAW,IAAIlB,aAAa,EAAEmB,wBAAwB,KAAK,MAAM,CAAC,CAAC;IAC9ER,SAAS,CAACE,IAAI,CAACO,mCAA0B,CAAC,CAACL,eAAe,CAACG,WAAW,CAAC;IAEvE,IAAItB,UAAU,EAAE;MACZ;MACAe,SAAS,CAACE,IAAI,CAACQ,kCAAyB,CAAC,CAACN,eAAe,CAACnB,UAAU,CAAC;IACzE,CAAC,MAAM;MACH;MACAe,SAAS,CAACE,IAAI,CAACQ,kCAAyB,CAAC,CAACC,EAAE,CAACC,mCAAuB,CAAC;IACzE;;IAEA;IACAjC,UAAU,CAACkC,OAAO,CAACC,SAAS,IAAId,SAAS,CAACE,IAAI,CAACa,wBAAe,CAAC,CAACJ,EAAE,CAACG,SAAS,CAAC,CAAC;;IAE9E;IACA,IAAIE,cAAc;IAClB,IAAI5B,OAAO,CAAC6B,OAAO,EAAE;MACjBD,cAAc,GAAG,IAAAE,0CAAoB,EAAC9B,OAAO,CAAC6B,OAAO,CAAC;IAC1D;;IAEA;IACA,IAAI;MACA,MAAME,MAAM,GAAG,MAAMnB,SAAS,CAACoB,OAAO,CAACC,gCAAe,CAAC;MACvDF,MAAM,CAACG,UAAU,CAAC;QACdC,YAAY,EAAE9B,OAAO,CAACC,GAAG,CAAC8B,yBAAyB;QACnDC,aAAa,EAAEhC,OAAO,CAACC,GAAG,CAACgC;MAC/B,CAAC,CAAC;MAEF,IAAItC,OAAO,CAACuC,OAAO,KAAK,SAAS,EAAE;QAC/B,MAAMR,MAAM,CAACS,OAAO,CAChBtC,cAAc,EACd0B,cAAc,IAAIjC,qBAAqB,EACvCa,YACJ,CAAC;QACD;MACJ;MAEA,OAAO;QAAEiC,IAAI,EAAE,MAAMV,MAAM,CAACW,SAAS,CAAC;MAAE,CAAC;IAC7C,CAAC,CAAC,OAAOC,GAAG,EAAE;MACV,OAAO;QAAEC,KAAK,EAAE;UAAEC,OAAO,EAAEF,GAAG,CAACE;QAAQ;MAAE,CAAC;IAC9C;EACJ,CACJ,CAAC;AACL,CAAC;AAACC,OAAA,CAAAxD,2BAAA,GAAAA,2BAAA"}
|
|
@@ -24,6 +24,7 @@ const createDdbProjectMigration = ({
|
|
|
24
24
|
lambdaContext
|
|
25
25
|
}) => {
|
|
26
26
|
const projectVersion = String(payload?.version || process.env.WEBINY_VERSION);
|
|
27
|
+
const forceExecute = payload.force === true;
|
|
27
28
|
const version = (0, _semver.coerce)(projectVersion);
|
|
28
29
|
if (version?.version === "0.0.0") {
|
|
29
30
|
return (0, _devVersionErrorResponse.devVersionErrorResponse)();
|
|
@@ -59,7 +60,7 @@ const createDdbProjectMigration = ({
|
|
|
59
60
|
logStreamName: process.env.AWS_LAMBDA_LOG_STREAM_NAME
|
|
60
61
|
});
|
|
61
62
|
if (payload.command === "execute") {
|
|
62
|
-
await runner.execute(projectVersion, patternMatcher || isMigrationApplicable);
|
|
63
|
+
await runner.execute(projectVersion, patternMatcher || isMigrationApplicable, forceExecute);
|
|
63
64
|
return;
|
|
64
65
|
}
|
|
65
66
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_handlerAws","require","_ioc","_MigrationRunner","_symbols","_migrations","_devVersionErrorResponse","_createPatternMatcher","_semver","createDdbProjectMigration","migrations","primaryTable","isMigrationApplicable","undefined","repository","config","createRawEventHandler","payload","lambdaContext","projectVersion","String","version","process","env","WEBINY_VERSION","semverCoerce","devVersionErrorResponse","container","createContainer","bind","PrimaryDynamoTableSymbol","toConstantValue","timeLimiter","getRemainingTimeInMillis","ExecutionTimeLimiterSymbol","MigrationRepositorySymbol","to","MigrationRepositoryImpl","forEach","migration","MigrationSymbol","patternMatcher","pattern","createPatternMatcher","runner","resolve","MigrationRunner","setContext","logGroupName","AWS_LAMBDA_LOG_GROUP_NAME","logStreamName","AWS_LAMBDA_LOG_STREAM_NAME","command","execute","data","getStatus","err","error","message","exports"],"sources":["createDdbProjectMigration.ts"],"sourcesContent":["import { Table } from \"@webiny/db-dynamodb/toolbox\";\nimport { createRawEventHandler } from \"@webiny/handler-aws\";\nimport { Constructor, createContainer } from \"@webiny/ioc\";\nimport { IsMigrationApplicable, MigrationRunner } from \"~/MigrationRunner\";\nimport {\n ExecutionTimeLimiterSymbol,\n MigrationRepositorySymbol,\n MigrationSymbol,\n PrimaryDynamoTableSymbol\n} from \"~/symbols\";\nimport { MigrationRepositoryImpl } from \"~/repository/migrations.repository\";\nimport { devVersionErrorResponse } from \"./devVersionErrorResponse\";\nimport { createPatternMatcher } from \"./createPatternMatcher\";\nimport {\n DataMigration,\n ExecutionTimeLimiter,\n MigrationEventHandlerResponse,\n MigrationEventPayload,\n MigrationRepository\n} from \"~/types\";\nimport { coerce as semverCoerce } from \"semver\";\n\ninterface CreateDdbDataMigrationConfig {\n migrations: Constructor<DataMigration>[];\n primaryTable: Table<string, string, string>;\n repository?: MigrationRepository;\n isMigrationApplicable?: IsMigrationApplicable;\n timeLimiter?: ExecutionTimeLimiter;\n}\n\nexport const createDdbProjectMigration = ({\n migrations,\n primaryTable,\n isMigrationApplicable = undefined,\n repository = undefined,\n ...config\n}: CreateDdbDataMigrationConfig) => {\n return createRawEventHandler<MigrationEventPayload, any, MigrationEventHandlerResponse>(\n async ({ payload, lambdaContext }) => {\n const projectVersion = String(payload?.version || process.env.WEBINY_VERSION);\n\n const version = semverCoerce(projectVersion);\n if (version?.version === \"0.0.0\") {\n return devVersionErrorResponse();\n }\n\n // COMPOSITION ROOT\n const container = createContainer();\n container.bind(PrimaryDynamoTableSymbol).toConstantValue(primaryTable);\n\n const timeLimiter: ExecutionTimeLimiter =\n config.timeLimiter || lambdaContext?.getRemainingTimeInMillis || (() => 0);\n container.bind(ExecutionTimeLimiterSymbol).toConstantValue(timeLimiter);\n\n if (repository) {\n // Repository implementation provided by the user.\n container.bind(MigrationRepositorySymbol).toConstantValue(repository);\n } else {\n // Default repository implementation.\n container.bind(MigrationRepositorySymbol).to(MigrationRepositoryImpl);\n }\n\n // Bind the provided migrations.\n migrations.forEach(migration => container.bind(MigrationSymbol).to(migration));\n\n // If handler was invoked with a `pattern`, filter migrations that match the pattern only.\n let patternMatcher;\n if (payload.pattern) {\n patternMatcher = createPatternMatcher(payload.pattern);\n }\n\n // Inject dependencies and execute.\n try {\n const runner = await container.resolve(MigrationRunner);\n runner.setContext({\n logGroupName: process.env.AWS_LAMBDA_LOG_GROUP_NAME,\n logStreamName: process.env.AWS_LAMBDA_LOG_STREAM_NAME\n });\n\n if (payload.command === \"execute\") {\n await runner.execute(projectVersion
|
|
1
|
+
{"version":3,"names":["_handlerAws","require","_ioc","_MigrationRunner","_symbols","_migrations","_devVersionErrorResponse","_createPatternMatcher","_semver","createDdbProjectMigration","migrations","primaryTable","isMigrationApplicable","undefined","repository","config","createRawEventHandler","payload","lambdaContext","projectVersion","String","version","process","env","WEBINY_VERSION","forceExecute","force","semverCoerce","devVersionErrorResponse","container","createContainer","bind","PrimaryDynamoTableSymbol","toConstantValue","timeLimiter","getRemainingTimeInMillis","ExecutionTimeLimiterSymbol","MigrationRepositorySymbol","to","MigrationRepositoryImpl","forEach","migration","MigrationSymbol","patternMatcher","pattern","createPatternMatcher","runner","resolve","MigrationRunner","setContext","logGroupName","AWS_LAMBDA_LOG_GROUP_NAME","logStreamName","AWS_LAMBDA_LOG_STREAM_NAME","command","execute","data","getStatus","err","error","message","exports"],"sources":["createDdbProjectMigration.ts"],"sourcesContent":["import { Table } from \"@webiny/db-dynamodb/toolbox\";\nimport { createRawEventHandler } from \"@webiny/handler-aws\";\nimport { Constructor, createContainer } from \"@webiny/ioc\";\nimport { IsMigrationApplicable, MigrationRunner } from \"~/MigrationRunner\";\nimport {\n ExecutionTimeLimiterSymbol,\n MigrationRepositorySymbol,\n MigrationSymbol,\n PrimaryDynamoTableSymbol\n} from \"~/symbols\";\nimport { MigrationRepositoryImpl } from \"~/repository/migrations.repository\";\nimport { devVersionErrorResponse } from \"./devVersionErrorResponse\";\nimport { createPatternMatcher } from \"./createPatternMatcher\";\nimport {\n DataMigration,\n ExecutionTimeLimiter,\n MigrationEventHandlerResponse,\n MigrationEventPayload,\n MigrationRepository\n} from \"~/types\";\nimport { coerce as semverCoerce } from \"semver\";\n\ninterface CreateDdbDataMigrationConfig {\n migrations: Constructor<DataMigration>[];\n primaryTable: Table<string, string, string>;\n repository?: MigrationRepository;\n isMigrationApplicable?: IsMigrationApplicable;\n timeLimiter?: ExecutionTimeLimiter;\n}\n\nexport const createDdbProjectMigration = ({\n migrations,\n primaryTable,\n isMigrationApplicable = undefined,\n repository = undefined,\n ...config\n}: CreateDdbDataMigrationConfig) => {\n return createRawEventHandler<MigrationEventPayload, any, MigrationEventHandlerResponse>(\n async ({ payload, lambdaContext }) => {\n const projectVersion = String(payload?.version || process.env.WEBINY_VERSION);\n const forceExecute = payload.force === true;\n\n const version = semverCoerce(projectVersion);\n if (version?.version === \"0.0.0\") {\n return devVersionErrorResponse();\n }\n\n // COMPOSITION ROOT\n const container = createContainer();\n container.bind(PrimaryDynamoTableSymbol).toConstantValue(primaryTable);\n\n const timeLimiter: ExecutionTimeLimiter =\n config.timeLimiter || lambdaContext?.getRemainingTimeInMillis || (() => 0);\n container.bind(ExecutionTimeLimiterSymbol).toConstantValue(timeLimiter);\n\n if (repository) {\n // Repository implementation provided by the user.\n container.bind(MigrationRepositorySymbol).toConstantValue(repository);\n } else {\n // Default repository implementation.\n container.bind(MigrationRepositorySymbol).to(MigrationRepositoryImpl);\n }\n\n // Bind the provided migrations.\n migrations.forEach(migration => container.bind(MigrationSymbol).to(migration));\n\n // If handler was invoked with a `pattern`, filter migrations that match the pattern only.\n let patternMatcher;\n if (payload.pattern) {\n patternMatcher = createPatternMatcher(payload.pattern);\n }\n\n // Inject dependencies and execute.\n try {\n const runner = await container.resolve(MigrationRunner);\n runner.setContext({\n logGroupName: process.env.AWS_LAMBDA_LOG_GROUP_NAME,\n logStreamName: process.env.AWS_LAMBDA_LOG_STREAM_NAME\n });\n\n if (payload.command === \"execute\") {\n await runner.execute(\n projectVersion,\n patternMatcher || isMigrationApplicable,\n forceExecute\n );\n return;\n }\n\n return {\n data: await runner.getStatus()\n };\n } catch (err) {\n return { error: { message: err.message } };\n }\n }\n );\n};\n"],"mappings":";;;;;;AACA,IAAAA,WAAA,GAAAC,OAAA;AACA,IAAAC,IAAA,GAAAD,OAAA;AACA,IAAAE,gBAAA,GAAAF,OAAA;AACA,IAAAG,QAAA,GAAAH,OAAA;AAMA,IAAAI,WAAA,GAAAJ,OAAA;AACA,IAAAK,wBAAA,GAAAL,OAAA;AACA,IAAAM,qBAAA,GAAAN,OAAA;AAQA,IAAAO,OAAA,GAAAP,OAAA;AAUO,MAAMQ,yBAAyB,GAAGA,CAAC;EACtCC,UAAU;EACVC,YAAY;EACZC,qBAAqB,GAAGC,SAAS;EACjCC,UAAU,GAAGD,SAAS;EACtB,GAAGE;AACuB,CAAC,KAAK;EAChC,OAAO,IAAAC,iCAAqB,EACxB,OAAO;IAAEC,OAAO;IAAEC;EAAc,CAAC,KAAK;IAClC,MAAMC,cAAc,GAAGC,MAAM,CAACH,OAAO,EAAEI,OAAO,IAAIC,OAAO,CAACC,GAAG,CAACC,cAAc,CAAC;IAC7E,MAAMC,YAAY,GAAGR,OAAO,CAACS,KAAK,KAAK,IAAI;IAE3C,MAAML,OAAO,GAAG,IAAAM,cAAY,EAACR,cAAc,CAAC;IAC5C,IAAIE,OAAO,EAAEA,OAAO,KAAK,OAAO,EAAE;MAC9B,OAAO,IAAAO,gDAAuB,EAAC,CAAC;IACpC;;IAEA;IACA,MAAMC,SAAS,GAAG,IAAAC,oBAAe,EAAC,CAAC;IACnCD,SAAS,CAACE,IAAI,CAACC,iCAAwB,CAAC,CAACC,eAAe,CAACtB,YAAY,CAAC;IAEtE,MAAMuB,WAAiC,GACnCnB,MAAM,CAACmB,WAAW,IAAIhB,aAAa,EAAEiB,wBAAwB,KAAK,MAAM,CAAC,CAAC;IAC9EN,SAAS,CAACE,IAAI,CAACK,mCAA0B,CAAC,CAACH,eAAe,CAACC,WAAW,CAAC;IAEvE,IAAIpB,UAAU,EAAE;MACZ;MACAe,SAAS,CAACE,IAAI,CAACM,kCAAyB,CAAC,CAACJ,eAAe,CAACnB,UAAU,CAAC;IACzE,CAAC,MAAM;MACH;MACAe,SAAS,CAACE,IAAI,CAACM,kCAAyB,CAAC,CAACC,EAAE,CAACC,mCAAuB,CAAC;IACzE;;IAEA;IACA7B,UAAU,CAAC8B,OAAO,CAACC,SAAS,IAAIZ,SAAS,CAACE,IAAI,CAACW,wBAAe,CAAC,CAACJ,EAAE,CAACG,SAAS,CAAC,CAAC;;IAE9E;IACA,IAAIE,cAAc;IAClB,IAAI1B,OAAO,CAAC2B,OAAO,EAAE;MACjBD,cAAc,GAAG,IAAAE,0CAAoB,EAAC5B,OAAO,CAAC2B,OAAO,CAAC;IAC1D;;IAEA;IACA,IAAI;MACA,MAAME,MAAM,GAAG,MAAMjB,SAAS,CAACkB,OAAO,CAACC,gCAAe,CAAC;MACvDF,MAAM,CAACG,UAAU,CAAC;QACdC,YAAY,EAAE5B,OAAO,CAACC,GAAG,CAAC4B,yBAAyB;QACnDC,aAAa,EAAE9B,OAAO,CAACC,GAAG,CAAC8B;MAC/B,CAAC,CAAC;MAEF,IAAIpC,OAAO,CAACqC,OAAO,KAAK,SAAS,EAAE;QAC/B,MAAMR,MAAM,CAACS,OAAO,CAChBpC,cAAc,EACdwB,cAAc,IAAI/B,qBAAqB,EACvCa,YACJ,CAAC;QACD;MACJ;MAEA,OAAO;QACH+B,IAAI,EAAE,MAAMV,MAAM,CAACW,SAAS,CAAC;MACjC,CAAC;IACL,CAAC,CAAC,OAAOC,GAAG,EAAE;MACV,OAAO;QAAEC,KAAK,EAAE;UAAEC,OAAO,EAAEF,GAAG,CAACE;QAAQ;MAAE,CAAC;IAC9C;EACJ,CACJ,CAAC;AACL,CAAC;AAACC,OAAA,CAAApD,yBAAA,GAAAA,yBAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webiny/data-migration",
|
|
3
|
-
"version": "5.39.1
|
|
3
|
+
"version": "5.39.1",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"types": "types.ts",
|
|
6
6
|
"license": "MIT",
|
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
"@babel/runtime": "7.22.6",
|
|
15
15
|
"@elastic/elasticsearch": "7.12.0",
|
|
16
16
|
"@types/pino": "7.0.5",
|
|
17
|
-
"@webiny/aws-sdk": "5.39.1
|
|
18
|
-
"@webiny/db-dynamodb": "5.39.1
|
|
19
|
-
"@webiny/handler-aws": "5.39.1
|
|
20
|
-
"@webiny/ioc": "5.39.1
|
|
21
|
-
"@webiny/logger": "5.39.1
|
|
22
|
-
"@webiny/utils": "5.39.1
|
|
17
|
+
"@webiny/aws-sdk": "5.39.1",
|
|
18
|
+
"@webiny/db-dynamodb": "5.39.1",
|
|
19
|
+
"@webiny/handler-aws": "5.39.1",
|
|
20
|
+
"@webiny/ioc": "5.39.1",
|
|
21
|
+
"@webiny/logger": "5.39.1",
|
|
22
|
+
"@webiny/utils": "5.39.1",
|
|
23
23
|
"center-align": "1.0.1",
|
|
24
24
|
"chalk": "4.1.2",
|
|
25
25
|
"minimatch": "5.1.6",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"@babel/preset-env": "7.22.7",
|
|
33
33
|
"@types/center-align": "1.0.0",
|
|
34
34
|
"@types/semver": "7.3.13",
|
|
35
|
-
"@webiny/cli": "5.39.1
|
|
36
|
-
"@webiny/project-utils": "5.39.1
|
|
35
|
+
"@webiny/cli": "5.39.1",
|
|
36
|
+
"@webiny/project-utils": "5.39.1",
|
|
37
37
|
"jest": "29.5.0",
|
|
38
38
|
"jest-dynalite": "3.6.1",
|
|
39
39
|
"jest-mock-console": "1.3.0",
|
|
@@ -55,5 +55,5 @@
|
|
|
55
55
|
]
|
|
56
56
|
}
|
|
57
57
|
},
|
|
58
|
-
"gitHead": "
|
|
58
|
+
"gitHead": "6fc74b45740bd4123dcf9b5890bfacee594208bf"
|
|
59
59
|
}
|
package/types.d.ts
CHANGED
|
@@ -62,6 +62,7 @@ export interface MigrationEventPayload {
|
|
|
62
62
|
command: "status" | "execute";
|
|
63
63
|
version?: string;
|
|
64
64
|
pattern?: string;
|
|
65
|
+
force?: boolean;
|
|
65
66
|
}
|
|
66
67
|
export declare type MigrationEventHandlerResponse = undefined | MigrationStatusResponse | MigrationInvocationErrorResponse;
|
|
67
68
|
export interface MigrationInvocationErrorResponse {
|
package/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import { Logger } from \"@webiny/logger\";\n\nexport type { Logger };\n\nexport interface MigrationItem {\n id: string;\n description: string;\n reason: string;\n startedOn?: string;\n finishedOn?: string;\n}\n\nexport interface MigrationRun {\n id: string;\n startedOn: string;\n finishedOn: string;\n status: \"init\" | \"running\" | \"pending\" | \"done\" | \"error\";\n migrations: MigrationRunItem[];\n context?: Record<string, any>;\n error?: {\n message: string;\n name?: string;\n code?: string;\n data?: Record<string, any>;\n stack?: string;\n };\n}\n\nexport interface MigrationRunItem {\n id: string;\n status: \"done\" | \"running\" | \"skipped\" | \"pending\" | \"not-applicable\" | \"error\";\n startedOn?: string;\n finishedOn?: string;\n}\n\nexport interface MigrationRepository {\n getLastRun(): Promise<MigrationRun | null>;\n saveRun(run: MigrationRun): Promise<void>;\n listMigrations(params?: { limit: number }): Promise<MigrationItem[]>;\n logMigration(migration: MigrationItem): Promise<void>;\n createCheckpoint(id: string, data: unknown): Promise<void>;\n getCheckpoint(id: string): Promise<unknown>;\n deleteCheckpoint(id: string): Promise<void>;\n}\n\nexport interface DataMigrationContext<TCheckpoint = any> {\n projectVersion: string;\n logger: Logger;\n checkpoint?: TCheckpoint;\n forceExecute: boolean;\n runningOutOfTime: () => boolean;\n createCheckpoint: (data: TCheckpoint) => Promise<void>;\n createCheckpointAndExit: (data: TCheckpoint) => Promise<void>;\n}\n\nexport interface DataMigration<TCheckpoint = any> {\n getId(): string;\n getDescription(): string;\n // This function should check of the migration needs to apply some changes to the system.\n // Returning `false` means \"everything is ok, mark this migration as executed\".\n shouldExecute(context: DataMigrationContext<TCheckpoint>): Promise<boolean>;\n execute(context: DataMigrationContext<TCheckpoint>): Promise<void>;\n}\n\n/**\n * Migration execution time limiter (in milliseconds).\n */\nexport type ExecutionTimeLimiter = () => number;\n\nexport interface MigrationEventPayload {\n command: \"status\" | \"execute\";\n version?: string;\n pattern?: string;\n}\n\nexport type MigrationEventHandlerResponse =\n // When migration is triggered (via `Event` invocation type), it simply gets invoked, and returns nothing.\n | undefined\n // Last migration run state.\n | MigrationStatusResponse\n // If an unhandled error is thrown, return the error object.\n | MigrationInvocationErrorResponse;\n\nexport interface MigrationInvocationErrorResponse {\n error: { message: string };\n data?: undefined;\n}\n\nexport interface MigrationStatusRunItem extends MigrationRunItem {\n description: string;\n}\n\nexport interface MigrationStatus extends MigrationRun {\n migrations: MigrationStatusRunItem[];\n}\n\nexport interface MigrationStatusResponse {\n data: MigrationStatus;\n error?: undefined;\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import { Logger } from \"@webiny/logger\";\n\nexport type { Logger };\n\nexport interface MigrationItem {\n id: string;\n description: string;\n reason: string;\n startedOn?: string;\n finishedOn?: string;\n}\n\nexport interface MigrationRun {\n id: string;\n startedOn: string;\n finishedOn: string;\n status: \"init\" | \"running\" | \"pending\" | \"done\" | \"error\";\n migrations: MigrationRunItem[];\n context?: Record<string, any>;\n error?: {\n message: string;\n name?: string;\n code?: string;\n data?: Record<string, any>;\n stack?: string;\n };\n}\n\nexport interface MigrationRunItem {\n id: string;\n status: \"done\" | \"running\" | \"skipped\" | \"pending\" | \"not-applicable\" | \"error\";\n startedOn?: string;\n finishedOn?: string;\n}\n\nexport interface MigrationRepository {\n getLastRun(): Promise<MigrationRun | null>;\n saveRun(run: MigrationRun): Promise<void>;\n listMigrations(params?: { limit: number }): Promise<MigrationItem[]>;\n logMigration(migration: MigrationItem): Promise<void>;\n createCheckpoint(id: string, data: unknown): Promise<void>;\n getCheckpoint(id: string): Promise<unknown>;\n deleteCheckpoint(id: string): Promise<void>;\n}\n\nexport interface DataMigrationContext<TCheckpoint = any> {\n projectVersion: string;\n logger: Logger;\n checkpoint?: TCheckpoint;\n forceExecute: boolean;\n runningOutOfTime: () => boolean;\n createCheckpoint: (data: TCheckpoint) => Promise<void>;\n createCheckpointAndExit: (data: TCheckpoint) => Promise<void>;\n}\n\nexport interface DataMigration<TCheckpoint = any> {\n getId(): string;\n getDescription(): string;\n // This function should check of the migration needs to apply some changes to the system.\n // Returning `false` means \"everything is ok, mark this migration as executed\".\n shouldExecute(context: DataMigrationContext<TCheckpoint>): Promise<boolean>;\n execute(context: DataMigrationContext<TCheckpoint>): Promise<void>;\n}\n\n/**\n * Migration execution time limiter (in milliseconds).\n */\nexport type ExecutionTimeLimiter = () => number;\n\nexport interface MigrationEventPayload {\n command: \"status\" | \"execute\";\n version?: string;\n pattern?: string;\n force?: boolean;\n}\n\nexport type MigrationEventHandlerResponse =\n // When migration is triggered (via `Event` invocation type), it simply gets invoked, and returns nothing.\n | undefined\n // Last migration run state.\n | MigrationStatusResponse\n // If an unhandled error is thrown, return the error object.\n | MigrationInvocationErrorResponse;\n\nexport interface MigrationInvocationErrorResponse {\n error: { message: string };\n data?: undefined;\n}\n\nexport interface MigrationStatusRunItem extends MigrationRunItem {\n description: string;\n}\n\nexport interface MigrationStatus extends MigrationRun {\n migrations: MigrationStatusRunItem[];\n}\n\nexport interface MigrationStatusResponse {\n data: MigrationStatus;\n error?: undefined;\n}\n"],"mappings":""}
|