@webiny/data-migration 0.0.0-unstable.df6d94b531 → 0.0.0-unstable.e0bfc55d5a

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.
Files changed (79) hide show
  1. package/MigrationRunner.d.ts +8 -4
  2. package/MigrationRunner.js +97 -32
  3. package/MigrationRunner.js.map +1 -1
  4. package/cli/CliMigrationRunReporter.d.ts +10 -0
  5. package/cli/CliMigrationRunReporter.js +55 -0
  6. package/cli/CliMigrationRunReporter.js.map +1 -0
  7. package/cli/InteractiveCliStatusReporter.d.ts +11 -0
  8. package/cli/InteractiveCliStatusReporter.js +74 -0
  9. package/cli/InteractiveCliStatusReporter.js.map +1 -0
  10. package/cli/LogReporter.d.ts +10 -0
  11. package/cli/LogReporter.js +43 -0
  12. package/cli/LogReporter.js.map +1 -0
  13. package/cli/LogStream.d.ts +10 -0
  14. package/cli/LogStream.js +58 -0
  15. package/cli/LogStream.js.map +1 -0
  16. package/cli/MigrationRunReporter.d.ts +4 -0
  17. package/cli/MigrationRunReporter.js +7 -0
  18. package/cli/MigrationRunReporter.js.map +1 -0
  19. package/cli/MigrationRunner.d.ts +45 -0
  20. package/cli/MigrationRunner.js +136 -0
  21. package/cli/MigrationRunner.js.map +1 -0
  22. package/cli/MigrationStatusReporter.d.ts +4 -0
  23. package/cli/MigrationStatusReporter.js +7 -0
  24. package/cli/MigrationStatusReporter.js.map +1 -0
  25. package/cli/NonInteractiveCliStatusReporter.d.ts +9 -0
  26. package/cli/NonInteractiveCliStatusReporter.js +42 -0
  27. package/cli/NonInteractiveCliStatusReporter.js.map +1 -0
  28. package/cli/VoidStatusReporter.d.ts +4 -0
  29. package/cli/VoidStatusReporter.js +14 -0
  30. package/cli/VoidStatusReporter.js.map +1 -0
  31. package/cli/getDuration.js +3 -1
  32. package/cli/getDuration.js.map +1 -1
  33. package/cli/index.d.ts +9 -2
  34. package/cli/index.js +92 -13
  35. package/cli/index.js.map +1 -1
  36. package/createPinoLogger.d.ts +4 -7
  37. package/createPinoLogger.js +7 -3
  38. package/createPinoLogger.js.map +1 -1
  39. package/createTable.d.ts +4 -4
  40. package/createTable.js +8 -4
  41. package/createTable.js.map +1 -1
  42. package/handlers/createDdbEsProjectMigration.d.ts +7 -7
  43. package/handlers/createDdbEsProjectMigration.js +23 -18
  44. package/handlers/createDdbEsProjectMigration.js.map +1 -1
  45. package/handlers/createDdbProjectMigration.d.ts +5 -5
  46. package/handlers/createDdbProjectMigration.js +21 -16
  47. package/handlers/createDdbProjectMigration.js.map +1 -1
  48. package/handlers/createPatternMatcher.d.ts +1 -1
  49. package/handlers/createPatternMatcher.js +3 -1
  50. package/handlers/createPatternMatcher.js.map +1 -1
  51. package/handlers/devVersionErrorResponse.js +3 -1
  52. package/handlers/devVersionErrorResponse.js.map +1 -1
  53. package/index.d.ts +0 -1
  54. package/index.js +3 -12
  55. package/index.js.map +1 -1
  56. package/package.json +20 -33
  57. package/repository/createStandardEntity.d.ts +50 -3
  58. package/repository/createStandardEntity.js +5 -3
  59. package/repository/createStandardEntity.js.map +1 -1
  60. package/repository/migrations.repository.d.ts +3 -3
  61. package/repository/migrations.repository.js +49 -36
  62. package/repository/migrations.repository.js.map +1 -1
  63. package/symbols.js +9 -14
  64. package/symbols.js.map +1 -1
  65. package/types.d.ts +9 -6
  66. package/types.js +2 -7
  67. package/types.js.map +1 -1
  68. package/cli/getMigrationStatus.d.ts +0 -9
  69. package/cli/getMigrationStatus.js +0 -23
  70. package/cli/getMigrationStatus.js.map +0 -1
  71. package/cli/printReport.d.ts +0 -9
  72. package/cli/printReport.js +0 -57
  73. package/cli/printReport.js.map +0 -1
  74. package/cli/runMigration.d.ts +0 -13
  75. package/cli/runMigration.js +0 -85
  76. package/cli/runMigration.js.map +0 -1
  77. package/createId.d.ts +0 -1
  78. package/createId.js +0 -14
  79. package/createId.js.map +0 -1
@@ -1,13 +1,15 @@
1
- import { Logger } from "pino";
2
- import { MigrationRepository, DataMigration, ExecutionTimeLimiter, MigrationStatus } from "./types";
3
- export declare type IsMigrationApplicable = (migration: DataMigration) => boolean;
1
+ import type { Logger } from "@webiny/logger";
2
+ import type { MigrationRepository, DataMigration, ExecutionTimeLimiter, MigrationStatus } from "./types";
3
+ export type IsMigrationApplicable = (migration: DataMigration) => boolean;
4
4
  export declare class MigrationRunner {
5
5
  private readonly logger;
6
6
  private readonly migrations;
7
7
  private readonly repository;
8
8
  private readonly timeLimiter;
9
+ private context;
9
10
  constructor(repository: MigrationRepository, timeLimiter: ExecutionTimeLimiter, migrations: DataMigration[], logger: Logger | undefined);
10
- execute(projectVersion: string, isApplicable?: IsMigrationApplicable): Promise<void>;
11
+ setContext(context: Record<string, any>): void;
12
+ execute(projectVersion: string, isApplicable?: IsMigrationApplicable, forceExecute?: boolean): Promise<void>;
11
13
  getStatus(): Promise<MigrationStatus>;
12
14
  private validateIds;
13
15
  private createCheckpoint;
@@ -15,4 +17,6 @@ export declare class MigrationRunner {
15
17
  private getOrCreateRunItem;
16
18
  private setRunItem;
17
19
  private setRunItemAndSave;
20
+ private printForceExecuteEnvVars;
21
+ private printSkipExecuteEnvVars;
18
22
  }
@@ -1,18 +1,14 @@
1
1
  "use strict";
2
2
 
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
3
  Object.defineProperty(exports, "__esModule", {
5
4
  value: true
6
5
  });
7
6
  exports.MigrationRunner = void 0;
8
- var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
9
- var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
7
  var _semver = require("semver");
11
8
  var _ioc = require("@webiny/ioc");
12
9
  var _utils = require("@webiny/utils");
13
10
  var _symbols = require("./symbols");
14
11
  var _createPinoLogger = require("./createPinoLogger");
15
- var _createId = require("./createId");
16
12
  const getCurrentISOTime = () => {
17
13
  return new Date().toISOString();
18
14
  };
@@ -22,14 +18,29 @@ const getRunItemDuration = runItem => {
22
18
  }
23
19
  return new Date(runItem.finishedOn).getTime() - new Date(runItem.startedOn).getTime();
24
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
+ */
26
+ const shouldForceExecute = mig => {
27
+ const key = `WEBINY_MIGRATION_FORCE_EXECUTE_${mig.getId().replace(/[\.\-]/g, "_")}`;
28
+ return process.env[key] === "true";
29
+ };
30
+
31
+ /**
32
+ * This allows us to always skip a migration.
33
+ * Example: WEBINY_MIGRATION_SKIP_5_35_0_006=true
34
+ */
35
+ const shouldSkip = mig => {
36
+ const key = `WEBINY_MIGRATION_SKIP_${mig.getId().replace(/[\.\-]/g, "_")}`;
37
+ return process.env[key] === "true";
38
+ };
25
39
  class MigrationNotFinished extends Error {}
26
40
  class MigrationInProgress extends Error {}
27
41
  class MigrationRunner {
42
+ context = {};
28
43
  constructor(repository, timeLimiter, migrations, logger) {
29
- (0, _defineProperty2.default)(this, "logger", void 0);
30
- (0, _defineProperty2.default)(this, "migrations", void 0);
31
- (0, _defineProperty2.default)(this, "repository", void 0);
32
- (0, _defineProperty2.default)(this, "timeLimiter", void 0);
33
44
  this.repository = repository;
34
45
  this.timeLimiter = timeLimiter;
35
46
  this.migrations = migrations || [];
@@ -38,7 +49,12 @@ class MigrationRunner {
38
49
  }
39
50
  this.logger = logger;
40
51
  }
41
- async execute(projectVersion, isApplicable) {
52
+ setContext(context) {
53
+ this.context = context;
54
+ }
55
+ async execute(projectVersion, isApplicable,
56
+ // Force execute applicable migrations.
57
+ forceExecute = false) {
42
58
  const lastRun = await this.getOrCreateRun();
43
59
  try {
44
60
  this.validateIds(this.migrations);
@@ -83,7 +99,22 @@ class MigrationRunner {
83
99
  return mig.getId() > startingId && mig.getId() <= lastId;
84
100
  };
85
101
  const isMigrationApplicable = isApplicable || defaultIsApplicable;
102
+ this.printForceExecuteEnvVars();
103
+ this.printSkipExecuteEnvVars();
104
+ if (forceExecute) {
105
+ this.logger.info(`ALL APPLICABLE MIGRATIONS WILL BE FORCE-EXECUTED! (via --force flag)`);
106
+ }
86
107
  const executableMigrations = this.migrations.filter(mig => {
108
+ if (shouldSkip(mig)) {
109
+ this.setRunItem(lastRun, {
110
+ id: mig.getId(),
111
+ status: "skipped"
112
+ });
113
+ return false;
114
+ }
115
+ if (shouldForceExecute(mig)) {
116
+ return true;
117
+ }
87
118
  if (!isMigrationApplicable(mig)) {
88
119
  this.setRunItem(lastRun, {
89
120
  id: mig.getId(),
@@ -99,6 +130,8 @@ class MigrationRunner {
99
130
  const shouldCreateCheckpoint = () => {
100
131
  return this.timeLimiter() < 120000;
101
132
  };
133
+
134
+ //
102
135
  for (const migration of executableMigrations) {
103
136
  const runItem = this.getOrCreateRunItem(lastRun, migration);
104
137
  const checkpoint = await this.repository.getCheckpoint(migration.getId());
@@ -110,6 +143,7 @@ class MigrationRunner {
110
143
  projectVersion,
111
144
  logger,
112
145
  checkpoint,
146
+ forceExecute: forceExecute || shouldForceExecute(migration),
113
147
  runningOutOfTime: shouldCreateCheckpoint,
114
148
  createCheckpoint: async data => {
115
149
  await this.createCheckpoint(migration, data);
@@ -120,19 +154,19 @@ class MigrationRunner {
120
154
  throw new MigrationNotFinished();
121
155
  }
122
156
  };
123
- const shouldExecute = checkpoint ? true : await migration.shouldExecute(context);
124
- if (!shouldExecute) {
125
- this.logger.info(`Skipping migration %s.`, migration.getId());
126
- runItem.status = "skipped";
127
- await this.setRunItemAndSave(lastRun, runItem);
128
- await this.repository.logMigration({
129
- id: migration.getId(),
130
- description: migration.getDescription(),
131
- reason: "skipped"
132
- });
133
- continue;
134
- }
135
157
  try {
158
+ const shouldExecute = checkpoint || context.forceExecute ? true : await migration.shouldExecute(context);
159
+ if (!shouldExecute) {
160
+ this.logger.info(`Skipping migration %s.`, migration.getId());
161
+ runItem.status = "skipped";
162
+ await this.setRunItemAndSave(lastRun, runItem);
163
+ await this.repository.logMigration({
164
+ id: migration.getId(),
165
+ description: migration.getDescription(),
166
+ reason: "skipped"
167
+ });
168
+ continue;
169
+ }
136
170
  lastRun.status = "running";
137
171
  runItem.status = "running";
138
172
  if (!runItem.startedOn) {
@@ -161,12 +195,15 @@ class MigrationRunner {
161
195
  this.logger.error(err, err.message);
162
196
  return;
163
197
  } finally {
164
- // We sum duration from the previous run with the current run.
165
198
  runItem.finishedOn = getCurrentISOTime();
166
199
 
167
200
  // Update run stats.
168
201
  await this.setRunItemAndSave(lastRun, runItem);
169
- this.logger.info(`Finished executing migration %s in %sms.`, migration.getId(), getRunItemDuration(runItem));
202
+ if (runItem.status === "pending") {
203
+ this.logger.info(`Pausing migration %s, awaiting continuation.`, migration.getId());
204
+ } else {
205
+ this.logger.info(`Finished executing migration %s in %sms.`, migration.getId(), getRunItemDuration(runItem));
206
+ }
170
207
  }
171
208
  await this.repository.logMigration({
172
209
  id: migration.getId(),
@@ -192,13 +229,15 @@ class MigrationRunner {
192
229
  // Since we don't store migration descriptions to DB, we need to fetch them from actual migration objects.
193
230
  const withDescriptions = lastRun.migrations.map(mig => {
194
231
  const dataMigration = this.migrations.find(dm => dm.getId() === mig.id);
195
- return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, mig), {}, {
232
+ return {
233
+ ...mig,
196
234
  description: dataMigration ? dataMigration.getDescription() : "N/A"
197
- });
235
+ };
198
236
  });
199
- return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, lastRun), {}, {
237
+ return {
238
+ ...lastRun,
200
239
  migrations: withDescriptions
201
- });
240
+ };
202
241
  }
203
242
  validateIds(migrations) {
204
243
  const ids = new Set();
@@ -231,11 +270,12 @@ class MigrationRunner {
231
270
  }
232
271
  if (!lastRun || resolvedStatus.includes(lastRun.status)) {
233
272
  lastRun = {
234
- id: (0, _createId.createId)(),
273
+ id: (0, _utils.mdbid)(),
235
274
  status: "init",
236
275
  startedOn: getCurrentISOTime(),
237
276
  finishedOn: "",
238
- migrations: []
277
+ migrations: [],
278
+ context: this.context
239
279
  };
240
280
  await this.repository.saveRun(lastRun);
241
281
  }
@@ -244,9 +284,10 @@ class MigrationRunner {
244
284
  getOrCreateRunItem(run, migration) {
245
285
  const existingItem = run.migrations.find(item => item.id === migration.getId());
246
286
  if (existingItem) {
247
- return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, existingItem), {}, {
287
+ return {
288
+ ...existingItem,
248
289
  status: "running"
249
- });
290
+ };
250
291
  }
251
292
  return {
252
293
  id: migration.getId(),
@@ -266,6 +307,28 @@ class MigrationRunner {
266
307
  this.setRunItem(run, item);
267
308
  await this.repository.saveRun(run);
268
309
  }
310
+ printForceExecuteEnvVars() {
311
+ const forceKeys = Object.keys(process.env).filter(key => key.startsWith("WEBINY_MIGRATION_FORCE_EXECUTE_"));
312
+ if (!forceKeys.length) {
313
+ this.logger.info(`No migrations are enforced via WEBINY_MIGRATION_FORCE_EXECUTE environment variable.`);
314
+ return;
315
+ }
316
+ this.logger.info(`FORCED MIGRATIONS DETECTED!`);
317
+ for (const key of forceKeys) {
318
+ this.logger.info(`${key}=${process.env[key]}`);
319
+ }
320
+ }
321
+ printSkipExecuteEnvVars() {
322
+ const skipKeys = Object.keys(process.env).filter(key => key.startsWith("WEBINY_MIGRATION_SKIP_"));
323
+ if (!skipKeys.length) {
324
+ this.logger.info(`No migrations are skipped via WEBINY_MIGRATION_SKIP environment variable.`);
325
+ return;
326
+ }
327
+ this.logger.info(`SKIPPED MIGRATIONS DETECTED!`);
328
+ for (const key of skipKeys) {
329
+ this.logger.info(`${key}=${process.env[key]}`);
330
+ }
331
+ }
269
332
  }
270
333
  exports.MigrationRunner = MigrationRunner;
271
334
  (0, _ioc.makeInjectable)(MigrationRunner, [(0, _ioc.inject)(_symbols.MigrationRepositorySymbol), (0, _ioc.inject)(_symbols.ExecutionTimeLimiterSymbol), (0, _ioc.inject)(_symbols.MigrationSymbol, {
@@ -273,4 +336,6 @@ exports.MigrationRunner = MigrationRunner;
273
336
  optional: true
274
337
  }), (0, _ioc.inject)(_symbols.LoggerSymbol, {
275
338
  optional: true
276
- })]);
339
+ })]);
340
+
341
+ //# sourceMappingURL=MigrationRunner.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["getCurrentISOTime","Date","toISOString","getRunItemDuration","runItem","startedOn","finishedOn","getTime","MigrationNotFinished","Error","MigrationInProgress","MigrationRunner","constructor","repository","timeLimiter","migrations","logger","createPinoLogger","execute","projectVersion","isApplicable","lastRun","getOrCreateRun","validateIds","err","status","error","message","saveRun","latestMigration","listMigrations","limit","info","currentVersion","coerce","startingId","id","lastId","logMigration","description","reason","defaultIsApplicable","mig","getId","isMigrationApplicable","executableMigrations","filter","setRunItem","sort","a","b","length","shouldCreateCheckpoint","migration","getOrCreateRunItem","checkpoint","getCheckpoint","getChildLogger","context","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","createId","run","existingItem","item","index","findIndex","push","slice","makeInjectable","inject","MigrationRepositorySymbol","ExecutionTimeLimiterSymbol","MigrationSymbol","multi","optional","LoggerSymbol"],"sources":["MigrationRunner.ts"],"sourcesContent":["import { coerce } from \"semver\";\nimport { Logger } from \"pino\";\nimport { inject, makeInjectable } from \"@webiny/ioc\";\nimport { executeWithRetry } 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\";\nimport { createId } from \"~/createId\";\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\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\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 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 (!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 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 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 const shouldExecute = checkpoint ? true : 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 try {\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: createId(),\n status: \"init\",\n startedOn: getCurrentISOTime(),\n finishedOn: \"\",\n migrations: []\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":";;;;;;;;;AAAA;AAEA;AACA;AACA;AAMA;AAUA;AAIA,MAAMA,iBAAiB,GAAG,MAAM;EAC5B,OAAO,IAAIC,IAAI,EAAE,CAACC,WAAW,EAAE;AACnC,CAAC;AAED,MAAMC,kBAAkB,GAAIC,OAAyB,IAAK;EACtD,IAAI,CAACA,OAAO,CAACC,SAAS,IAAI,CAACD,OAAO,CAACE,UAAU,EAAE;IAC3C,OAAO,KAAK;EAChB;EAEA,OAAO,IAAIL,IAAI,CAACG,OAAO,CAACE,UAAU,CAAC,CAACC,OAAO,EAAE,GAAG,IAAIN,IAAI,CAACG,OAAO,CAACC,SAAS,CAAC,CAACE,OAAO,EAAE;AACzF,CAAC;AAED,MAAMC,oBAAoB,SAASC,KAAK,CAAC;AACzC,MAAMC,mBAAmB,SAASD,KAAK,CAAC;AAEjC,MAAME,eAAe,CAAC;EAMzBC,WAAW,CACPC,UAA+B,EAC/BC,WAAiC,EACjCC,UAA2B,EAC3BC,MAA0B,EAC5B;IAAA;IAAA;IAAA;IAAA;IACE,IAAI,CAACH,UAAU,GAAGA,UAAU;IAC5B,IAAI,CAACC,WAAW,GAAGA,WAAW;IAC9B,IAAI,CAACC,UAAU,GAAGA,UAAU,IAAI,EAAE;IAElC,IAAI,CAACC,MAAM,EAAE;MACTA,MAAM,GAAG,IAAAC,kCAAgB,GAAE;IAC/B;IACA,IAAI,CAACD,MAAM,GAAGA,MAAM;EACxB;EAEA,MAAME,OAAO,CAACC,cAAsB,EAAEC,YAAoC,EAAE;IACxE,MAAMC,OAAO,GAAG,MAAM,IAAI,CAACC,cAAc,EAAE;IAE3C,IAAI;MACA,IAAI,CAACC,WAAW,CAAC,IAAI,CAACR,UAAU,CAAC;IACrC,CAAC,CAAC,OAAOS,GAAG,EAAE;MACVH,OAAO,CAACI,MAAM,GAAG,OAAO;MACxBJ,OAAO,CAACK,KAAK,GAAG;QACZC,OAAO,EAAEH,GAAG,CAACG;MACjB,CAAC;MACD,MAAM,IAAI,CAACd,UAAU,CAACe,OAAO,CAACP,OAAO,CAAC;MACtC;IACJ;IAEA,MAAM,CAACQ,eAAe,CAAC,GAAG,MAAM,IAAI,CAAChB,UAAU,CAACiB,cAAc,CAAC;MAAEC,KAAK,EAAE;IAAE,CAAC,CAAC;IAE5E,IAAI,CAACf,MAAM,CAACgB,IAAI,CAAE,wBAAuB,EAAEb,cAAc,CAAC;;IAE1D;IACA;IACA,MAAMc,cAAc,GAAG,IAAAC,cAAM,EAACf,cAAc,CAAC,GAAG,EAAE;IAClD,MAAMgB,UAAU,GAAGN,eAAe,GAAGA,eAAe,CAACO,EAAE,GAAI,GAAEH,cAAe,MAAK;IACjF,MAAMI,MAAM,GAAI,GAAEJ,cAAe,MAAK;;IAEtC;IACA,IAAI,CAACJ,eAAe,EAAE;MAClB,IAAI,CAACb,MAAM,CAACgB,IAAI,CACX,yEAAwE,EACzEG,UAAU,CACb;MACD,MAAM,IAAI,CAACtB,UAAU,CAACyB,YAAY,CAAC;QAC/BF,EAAE,EAAED,UAAU;QACdI,WAAW,EAAE,oDAAoD;QACjElC,SAAS,EAAEL,iBAAiB,EAAE;QAC9BM,UAAU,EAAEN,iBAAiB,EAAE;QAC/BwC,MAAM,EAAE;MACZ,CAAC,CAAC;IACN,CAAC,MAAM;MACH,IAAI,CAACxB,MAAM,CAACgB,IAAI,CAAE,4BAA2B,EAAEH,eAAe,CAACO,EAAE,CAAC;IACtE;IAEA,IAAIhB,YAAY,EAAE;MACd,IAAI,CAACJ,MAAM,CAACgB,IAAI,CAAE,uCAAsC,CAAC;IAC7D,CAAC,MAAM;MACH,IAAI,CAAChB,MAAM,CAACgB,IAAI,CAAE,4CAA2C,EAAEG,UAAU,EAAEE,MAAM,CAAC;IACtF;IAEA,MAAMI,mBAA0C,GAAGC,GAAG,IAAI;MACtD,OAAOA,GAAG,CAACC,KAAK,EAAE,GAAGR,UAAU,IAAIO,GAAG,CAACC,KAAK,EAAE,IAAIN,MAAM;IAC5D,CAAC;IAED,MAAMO,qBAAqB,GAAGxB,YAAY,IAAIqB,mBAAmB;IAEjE,MAAMI,oBAAoB,GAAG,IAAI,CAAC9B,UAAU,CACvC+B,MAAM,CAACJ,GAAG,IAAI;MACX,IAAI,CAACE,qBAAqB,CAACF,GAAG,CAAC,EAAE;QAC7B,IAAI,CAACK,UAAU,CAAC1B,OAAO,EAAE;UACrBe,EAAE,EAAEM,GAAG,CAACC,KAAK,EAAE;UACflB,MAAM,EAAE;QACZ,CAAC,CAAC;QAEF,OAAO,KAAK;MAChB;MACA,OAAO,IAAI;IACf,CAAC,CAAC,CACDuB,IAAI,CAAC,CAACC,CAAC,EAAEC,CAAC,KAAMD,CAAC,CAACN,KAAK,EAAE,GAAGO,CAAC,CAACP,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,CAAE,CAAC;IAErD,IAAI,CAAC3B,MAAM,CAACgB,IAAI,CACX,uDAAsD,EACvDa,oBAAoB,CAACM,MAAM,EAC3B,IAAI,CAACpC,UAAU,CAACoC,MAAM,CACzB;;IAED;IACA,MAAMC,sBAAsB,GAAG,MAAM;MACjC,OAAO,IAAI,CAACtC,WAAW,EAAE,GAAG,MAAM;IACtC,CAAC;IAED,KAAK,MAAMuC,SAAS,IAAIR,oBAAoB,EAAE;MAC1C,MAAMzC,OAAO,GAAG,IAAI,CAACkD,kBAAkB,CAACjC,OAAO,EAAEgC,SAAS,CAAC;MAC3D,MAAME,UAAU,GAAG,MAAM,IAAI,CAAC1C,UAAU,CAAC2C,aAAa,CAACH,SAAS,CAACV,KAAK,EAAE,CAAC;MACzE,MAAM3B,MAAM,GAAG,IAAAyC,gCAAc,EAAC,IAAI,CAACzC,MAAM,EAAEqC,SAAS,CAAC;MAErD,IAAIE,UAAU,EAAE;QACZ,IAAI,CAACvC,MAAM,CAACgB,IAAI,CAACuB,UAAU,EAAG,oBAAmBF,SAAS,CAACV,KAAK,EAAG,GAAE,CAAC;MAC1E;MAEA,MAAMe,OAA6B,GAAG;QAClCvC,cAAc;QACdH,MAAM;QACNuC,UAAU;QACVI,gBAAgB,EAAEP,sBAAsB;QACxCQ,gBAAgB,EAAE,MAAOC,IAAa,IAAK;UACvC,MAAM,IAAI,CAACD,gBAAgB,CAACP,SAAS,EAAEQ,IAAI,CAAC;QAChD,CAAC;QACDC,uBAAuB,EAAE,MAAOD,IAAa,IAAK;UAC9C,MAAM,IAAI,CAACD,gBAAgB,CAACP,SAAS,EAAEQ,IAAI,CAAC;UAC5C;UACA,MAAM,IAAIrD,oBAAoB,EAAE;QACpC;MACJ,CAAC;MACD,MAAMuD,aAAa,GAAGR,UAAU,GAAG,IAAI,GAAG,MAAMF,SAAS,CAACU,aAAa,CAACL,OAAO,CAAC;MAEhF,IAAI,CAACK,aAAa,EAAE;QAChB,IAAI,CAAC/C,MAAM,CAACgB,IAAI,CAAE,wBAAuB,EAAEqB,SAAS,CAACV,KAAK,EAAE,CAAC;QAC7DvC,OAAO,CAACqB,MAAM,GAAG,SAAS;QAE1B,MAAM,IAAI,CAACuC,iBAAiB,CAAC3C,OAAO,EAAEjB,OAAO,CAAC;QAE9C,MAAM,IAAI,CAACS,UAAU,CAACyB,YAAY,CAAC;UAC/BF,EAAE,EAAEiB,SAAS,CAACV,KAAK,EAAE;UACrBJ,WAAW,EAAEc,SAAS,CAACY,cAAc,EAAE;UACvCzB,MAAM,EAAE;QACZ,CAAC,CAAC;QAEF;MACJ;MAEA,IAAI;QACAnB,OAAO,CAACI,MAAM,GAAG,SAAS;QAC1BrB,OAAO,CAACqB,MAAM,GAAG,SAAS;QAC1B,IAAI,CAACrB,OAAO,CAACC,SAAS,EAAE;UACpBD,OAAO,CAACC,SAAS,GAAGL,iBAAiB,EAAE;QAC3C;QACA,MAAM,IAAI,CAACgE,iBAAiB,CAAC3C,OAAO,EAAEjB,OAAO,CAAC;QAC9C,IAAI,CAACY,MAAM,CAACgB,IAAI,CACX,4BAA2B,EAC5BqB,SAAS,CAACV,KAAK,EAAE,EACjBU,SAAS,CAACY,cAAc,EAAE,CAC7B;QACD,MAAMZ,SAAS,CAACnC,OAAO,CAACwC,OAAO,CAAC;QAChCtD,OAAO,CAACqB,MAAM,GAAG,MAAM;MAC3B,CAAC,CAAC,OAAOD,GAAG,EAAE;QACV;QACA,IAAIA,GAAG,YAAYhB,oBAAoB,EAAE;UACrCa,OAAO,CAACI,MAAM,GAAG,SAAS;UAC1BrB,OAAO,CAACqB,MAAM,GAAG,SAAS;UAC1B;QACJ;QAEArB,OAAO,CAACqB,MAAM,GAAG,OAAO;QACxBJ,OAAO,CAACI,MAAM,GAAG,OAAO;QACxBJ,OAAO,CAACK,KAAK,GAAG;UACZwC,IAAI,EAAE1C,GAAG,CAAC0C,IAAI,IAAI,iBAAiB;UACnCvC,OAAO,EAAEH,GAAG,CAACG,OAAO;UACpBwC,KAAK,EAAE3C,GAAG,CAAC2C,KAAK;UAChBN,IAAI,EAAErC,GAAG,CAACqC,IAAI;UACdO,IAAI,EAAE5C,GAAG,CAAC4C;QACd,CAAC;QACD,IAAI,CAACpD,MAAM,CAACU,KAAK,CAACF,GAAG,EAAEA,GAAG,CAACG,OAAO,CAAC;QACnC;MACJ,CAAC,SAAS;QACN;QACAvB,OAAO,CAACE,UAAU,GAAGN,iBAAiB,EAAE;;QAExC;QACA,MAAM,IAAI,CAACgE,iBAAiB,CAAC3C,OAAO,EAAEjB,OAAO,CAAC;QAE9C,IAAI,CAACY,MAAM,CAACgB,IAAI,CACX,0CAAyC,EAC1CqB,SAAS,CAACV,KAAK,EAAE,EACjBxC,kBAAkB,CAACC,OAAO,CAAC,CAC9B;MACL;MAEA,MAAM,IAAI,CAACS,UAAU,CAACyB,YAAY,CAAC;QAC/BF,EAAE,EAAEiB,SAAS,CAACV,KAAK,EAAE;QACrBJ,WAAW,EAAEc,SAAS,CAACY,cAAc,EAAE;QACvC5D,SAAS,EAAED,OAAO,CAACC,SAAS;QAC5BC,UAAU,EAAEF,OAAO,CAACE,UAAU;QAC9BkC,MAAM,EAAE;MACZ,CAAC,CAAC;MAEF,IAAI,CAACxB,MAAM,CAACgB,IAAI,CAAE,uBAAsBqB,SAAS,CAACV,KAAK,EAAG,GAAE,CAAC;MAC7D,MAAM,IAAI,CAAC9B,UAAU,CAACwD,gBAAgB,CAAChB,SAAS,CAACV,KAAK,EAAE,CAAC;IAC7D;IAEAtB,OAAO,CAACI,MAAM,GAAG,MAAM;IACvBJ,OAAO,CAACf,UAAU,GAAGN,iBAAiB,EAAE;IACxC,MAAM,IAAI,CAACa,UAAU,CAACe,OAAO,CAACP,OAAO,CAAC;IAEtC,IAAI,CAACL,MAAM,CAACgB,IAAI,CAAE,4CAA2C,CAAC;EAClE;EAEA,MAAMsC,SAAS,GAA6B;IACxC,MAAMjD,OAAO,GAAG,MAAM,IAAI,CAACR,UAAU,CAAC0D,UAAU,EAAE;IAClD,IAAI,CAAClD,OAAO,EAAE;MACV,MAAM,IAAIZ,KAAK,CAAE,mCAAkC,CAAC;IACxD;;IAEA;IACA,MAAM+D,gBAAgB,GAAGnD,OAAO,CAACN,UAAU,CAAC0D,GAAG,CAAC/B,GAAG,IAAI;MACnD,MAAMgC,aAAa,GAAG,IAAI,CAAC3D,UAAU,CAAC4D,IAAI,CAACC,EAAE,IAAIA,EAAE,CAACjC,KAAK,EAAE,KAAKD,GAAG,CAACN,EAAE,CAAC;MACvE,mEACOM,GAAG;QACNH,WAAW,EAAEmC,aAAa,GAAGA,aAAa,CAACT,cAAc,EAAE,GAAG;MAAK;IAE3E,CAAC,CAAC;IAEF,mEAAY5C,OAAO;MAAEN,UAAU,EAAEyD;IAAgB;EACrD;EAEQjD,WAAW,CAACR,UAA2B,EAAE;IAC7C,MAAM8D,GAAG,GAAG,IAAIC,GAAG,EAAE;IACrB,KAAK,MAAMpC,GAAG,IAAI3B,UAAU,EAAE;MAC1B,MAAMqB,EAAE,GAAGM,GAAG,CAACC,KAAK,EAAE;MACtB,IAAIP,EAAE,CAAC2C,QAAQ,CAAC,MAAM,CAAC,EAAE;QACrB,MAAMrD,KAAK,GAAG,IAAIjB,KAAK,CAAE,yCAAwC2B,EAAG,EAAC,CAAC;QACtE,IAAI,CAACpB,MAAM,CAACU,KAAK,CAACA,KAAK,CAAC;QACxB,MAAMA,KAAK;MACf;MAEA,IAAImD,GAAG,CAACG,GAAG,CAAC5C,EAAE,CAAC,EAAE;QACb,MAAMV,KAAK,GAAG,IAAIjB,KAAK,CAAE,iCAAgC2B,EAAG,EAAC,CAAC;QAC9D,IAAI,CAACpB,MAAM,CAACU,KAAK,CAACA,KAAK,CAAC;QACxB,MAAMA,KAAK;MACf;MACAmD,GAAG,CAACI,GAAG,CAAC7C,EAAE,CAAC;IACf;EACJ;EAEA,MAAcwB,gBAAgB,CAACP,SAAwB,EAAEE,UAAmB,EAAE;IAC1E,IAAI,CAACvC,MAAM,CAACgB,IAAI,CAACuB,UAAU,EAAG,qBAAoBF,SAAS,CAACV,KAAK,EAAG,EAAC,CAAC;IACtE,MAAMzB,OAAO,GAAG,MAAM,IAAI,CAACL,UAAU,CAAC+C,gBAAgB,CAACP,SAAS,CAACV,KAAK,EAAE,EAAEY,UAAU,CAAC;IACrF,MAAM,IAAA2B,uBAAgB,EAAChE,OAAO,CAAC;EACnC;EAEA,MAAcI,cAAc,GAAG;IAC3B,MAAM6D,cAA6C,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IACvE,MAAMC,gBAA+C,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC;IAE3E,IAAI/D,OAAO,GAAG,MAAM,IAAI,CAACR,UAAU,CAAC0D,UAAU,EAAE;IAEhD,IAAIlD,OAAO,IAAI+D,gBAAgB,CAACC,QAAQ,CAAChE,OAAO,CAACI,MAAM,CAAC,EAAE;MACtD,MAAM,IAAIf,mBAAmB,CAAE,yCAAwCW,OAAO,CAACe,EAAG,IAAG,CAAC;IAC1F;IAEA,IAAI,CAACf,OAAO,IAAI8D,cAAc,CAACE,QAAQ,CAAChE,OAAO,CAACI,MAAM,CAAC,EAAE;MACrDJ,OAAO,GAAG;QACNe,EAAE,EAAE,IAAAkD,kBAAQ,GAAE;QACd7D,MAAM,EAAE,MAAM;QACdpB,SAAS,EAAEL,iBAAiB,EAAE;QAC9BM,UAAU,EAAE,EAAE;QACdS,UAAU,EAAE;MAChB,CAAC;MAED,MAAM,IAAI,CAACF,UAAU,CAACe,OAAO,CAACP,OAAO,CAAC;IAC1C;IAEA,OAAOA,OAAO;EAClB;EAEQiC,kBAAkB,CAACiC,GAAiB,EAAElC,SAAwB,EAAoB;IACtF,MAAMmC,YAAY,GAAGD,GAAG,CAACxE,UAAU,CAAC4D,IAAI,CAACc,IAAI,IAAIA,IAAI,CAACrD,EAAE,KAAKiB,SAAS,CAACV,KAAK,EAAE,CAAC;IAC/E,IAAI6C,YAAY,EAAE;MACd,mEACOA,YAAY;QACf/D,MAAM,EAAE;MAAS;IAEzB;IAEA,OAAO;MACHW,EAAE,EAAEiB,SAAS,CAACV,KAAK,EAAE;MACrBlB,MAAM,EAAE;IACZ,CAAC;EACL;EAEQsB,UAAU,CAACwC,GAAiB,EAAEE,IAAsB,EAAE;IAC1D,MAAMC,KAAK,GAAGH,GAAG,CAACxE,UAAU,CAAC4E,SAAS,CAACvF,OAAO,IAAIA,OAAO,CAACgC,EAAE,KAAKqD,IAAI,CAACrD,EAAE,CAAC;IACzE,IAAIsD,KAAK,GAAG,CAAC,EAAE;MACXH,GAAG,CAACxE,UAAU,CAAC6E,IAAI,CAACH,IAAI,CAAC;IAC7B,CAAC,MAAM;MACHF,GAAG,CAACxE,UAAU,GAAG,CACb,GAAGwE,GAAG,CAACxE,UAAU,CAAC8E,KAAK,CAAC,CAAC,EAAEH,KAAK,CAAC,EACjCD,IAAI,EACJ,GAAGF,GAAG,CAACxE,UAAU,CAAC8E,KAAK,CAACH,KAAK,GAAG,CAAC,CAAC,CACrC;IACL;IAEAH,GAAG,CAACxE,UAAU,GAAGwE,GAAG,CAACxE,UAAU,CAACiC,IAAI,CAAC,CAACC,CAAC,EAAEC,CAAC,KAAMD,CAAC,CAACb,EAAE,GAAGc,CAAC,CAACd,EAAE,GAAG,CAAC,GAAG,CAAC,CAAE,CAAC;EAC1E;EAEA,MAAc4B,iBAAiB,CAACuB,GAAiB,EAAEE,IAAsB,EAAE;IACvE,IAAI,CAAC1C,UAAU,CAACwC,GAAG,EAAEE,IAAI,CAAC;IAC1B,MAAM,IAAI,CAAC5E,UAAU,CAACe,OAAO,CAAC2D,GAAG,CAAC;EACtC;AACJ;AAAC;AAED,IAAAO,mBAAc,EAACnF,eAAe,EAAE,CAC5B,IAAAoF,WAAM,EAACC,kCAAyB,CAAC,EACjC,IAAAD,WAAM,EAACE,mCAA0B,CAAC,EAClC,IAAAF,WAAM,EAACG,wBAAe,EAAE;EAAEC,KAAK,EAAE,IAAI;EAAEC,QAAQ,EAAE;AAAK,CAAC,CAAC,EACxD,IAAAL,WAAM,EAACM,qBAAY,EAAE;EAAED,QAAQ,EAAE;AAAK,CAAC,CAAC,CAC3C,CAAC"}
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","shouldSkip","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","printSkipExecuteEnvVars","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","skipKeys","exports","makeInjectable","inject","MigrationRepositorySymbol","ExecutionTimeLimiterSymbol","MigrationSymbol","multi","optional","LoggerSymbol"],"sources":["MigrationRunner.ts"],"sourcesContent":["import { coerce } from \"semver\";\nimport type { 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 type {\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\n/**\n * This allows us to always skip a migration.\n * Example: WEBINY_MIGRATION_SKIP_5_35_0_006=true\n */\nconst shouldSkip = (mig: DataMigration) => {\n const key = `WEBINY_MIGRATION_SKIP_${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 this.printSkipExecuteEnvVars();\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 (shouldSkip(mig)) {\n this.setRunItem(lastRun, {\n id: mig.getId(),\n status: \"skipped\"\n });\n\n return false;\n }\n\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 runItem.finishedOn = getCurrentISOTime();\n\n // Update run stats.\n await this.setRunItemAndSave(lastRun, runItem);\n\n if (runItem.status === \"pending\") {\n this.logger.info(\n `Pausing migration %s, awaiting continuation.`,\n migration.getId()\n );\n } else {\n this.logger.info(\n `Finished executing migration %s in %sms.`,\n migration.getId(),\n getRunItemDuration(runItem)\n );\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 private printSkipExecuteEnvVars() {\n const skipKeys = Object.keys(process.env).filter(key =>\n key.startsWith(\"WEBINY_MIGRATION_SKIP_\")\n );\n\n if (!skipKeys.length) {\n this.logger.info(\n `No migrations are skipped via WEBINY_MIGRATION_SKIP environment variable.`\n );\n\n return;\n }\n\n this.logger.info(`SKIPPED MIGRATIONS DETECTED!`);\n for (const key of skipKeys) {\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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","ignoreList":[]}
@@ -0,0 +1,10 @@
1
+ import type { MigrationRunnerResult, MigrationRunReporter } from "./";
2
+ import type { CliContext } from "@webiny/cli/types";
3
+ import type { LogReporter } from "./";
4
+ export declare class CliMigrationRunReporter implements MigrationRunReporter {
5
+ private context;
6
+ private logReporter;
7
+ constructor(logReporter: LogReporter, context: CliContext);
8
+ report(result: MigrationRunnerResult): Promise<void>;
9
+ private makeEven;
10
+ }
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.CliMigrationRunReporter = void 0;
8
+ var _centerAlign = _interopRequireDefault(require("center-align"));
9
+ class CliMigrationRunReporter {
10
+ constructor(logReporter, context) {
11
+ this.logReporter = logReporter;
12
+ this.context = context;
13
+ }
14
+ report(result) {
15
+ result.onSuccess(data => {
16
+ const functionName = result.getFunctionName().split(":").pop();
17
+ process.stdout.write("\n");
18
+ this.context.success(`Data migration Lambda %s executed successfully!`, functionName);
19
+ const {
20
+ migrations,
21
+ ...run
22
+ } = data;
23
+ if (!migrations.length) {
24
+ this.context.info(`No applicable migrations were found!`);
25
+ return;
26
+ }
27
+ const maxLength = Math.max(...migrations.map(mig => mig.status.length)) + 2;
28
+ this.context.info(`Migration run: %s`, run.id);
29
+ this.context.info(`Status: %s`, run.status);
30
+ this.context.info(`Started on: %s`, run.startedOn);
31
+ if (run.status === "done") {
32
+ this.context.info(`Finished on: %s`, run.finishedOn);
33
+ }
34
+ for (const migration of migrations) {
35
+ this.context.info(...[`[%s] %s: ${migration.description}`, (0, _centerAlign.default)(this.makeEven(migration.status), maxLength), migration.id]);
36
+ }
37
+ this.logReporter.printLogStreamLinks();
38
+ });
39
+ result.onError(error => {
40
+ this.context.error(error.message);
41
+ });
42
+
43
+ // Process the result!
44
+ return result.process();
45
+ }
46
+ makeEven(str) {
47
+ if (str.length % 2 > 0) {
48
+ return str + " ";
49
+ }
50
+ return str;
51
+ }
52
+ }
53
+ exports.CliMigrationRunReporter = CliMigrationRunReporter;
54
+
55
+ //# sourceMappingURL=CliMigrationRunReporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_centerAlign","_interopRequireDefault","require","CliMigrationRunReporter","constructor","logReporter","context","report","result","onSuccess","data","functionName","getFunctionName","split","pop","process","stdout","write","success","migrations","run","length","info","maxLength","Math","max","map","mig","status","id","startedOn","finishedOn","migration","description","center","makeEven","printLogStreamLinks","onError","error","message","str","exports"],"sources":["CliMigrationRunReporter.ts"],"sourcesContent":["import type { MigrationRunnerResult, MigrationRunReporter } from \"~/cli\";\nimport center from \"center-align\";\nimport type { CliContext } from \"@webiny/cli/types\";\nimport type { LogReporter } from \"~/cli\";\n\nexport class CliMigrationRunReporter implements MigrationRunReporter {\n private context: CliContext;\n private logReporter: LogReporter;\n\n constructor(logReporter: LogReporter, context: CliContext) {\n this.logReporter = logReporter;\n this.context = context;\n }\n\n report(result: MigrationRunnerResult): Promise<void> {\n result.onSuccess(data => {\n const functionName = result.getFunctionName().split(\":\").pop();\n process.stdout.write(\"\\n\");\n this.context.success(`Data migration Lambda %s executed successfully!`, functionName);\n\n const { migrations, ...run } = data;\n if (!migrations.length) {\n this.context.info(`No applicable migrations were found!`);\n return;\n }\n\n const maxLength = Math.max(...migrations.map(mig => mig.status.length)) + 2;\n this.context.info(`Migration run: %s`, run.id);\n this.context.info(`Status: %s`, run.status);\n this.context.info(`Started on: %s`, run.startedOn);\n if (run.status === \"done\") {\n this.context.info(`Finished on: %s`, run.finishedOn);\n }\n for (const migration of migrations) {\n this.context.info(\n ...[\n `[%s] %s: ${migration.description}`,\n center(this.makeEven(migration.status), maxLength),\n migration.id\n ]\n );\n }\n\n this.logReporter.printLogStreamLinks();\n });\n\n result.onError(error => {\n this.context.error(error.message);\n });\n\n // Process the result!\n return result.process();\n }\n\n private makeEven(str: string) {\n if (str.length % 2 > 0) {\n return str + \" \";\n }\n return str;\n }\n}\n"],"mappings":";;;;;;;AACA,IAAAA,YAAA,GAAAC,sBAAA,CAAAC,OAAA;AAIO,MAAMC,uBAAuB,CAAiC;EAIjEC,WAAWA,CAACC,WAAwB,EAAEC,OAAmB,EAAE;IACvD,IAAI,CAACD,WAAW,GAAGA,WAAW;IAC9B,IAAI,CAACC,OAAO,GAAGA,OAAO;EAC1B;EAEAC,MAAMA,CAACC,MAA6B,EAAiB;IACjDA,MAAM,CAACC,SAAS,CAACC,IAAI,IAAI;MACrB,MAAMC,YAAY,GAAGH,MAAM,CAACI,eAAe,CAAC,CAAC,CAACC,KAAK,CAAC,GAAG,CAAC,CAACC,GAAG,CAAC,CAAC;MAC9DC,OAAO,CAACC,MAAM,CAACC,KAAK,CAAC,IAAI,CAAC;MAC1B,IAAI,CAACX,OAAO,CAACY,OAAO,CAAC,iDAAiD,EAAEP,YAAY,CAAC;MAErF,MAAM;QAAEQ,UAAU;QAAE,GAAGC;MAAI,CAAC,GAAGV,IAAI;MACnC,IAAI,CAACS,UAAU,CAACE,MAAM,EAAE;QACpB,IAAI,CAACf,OAAO,CAACgB,IAAI,CAAC,sCAAsC,CAAC;QACzD;MACJ;MAEA,MAAMC,SAAS,GAAGC,IAAI,CAACC,GAAG,CAAC,GAAGN,UAAU,CAACO,GAAG,CAACC,GAAG,IAAIA,GAAG,CAACC,MAAM,CAACP,MAAM,CAAC,CAAC,GAAG,CAAC;MAC3E,IAAI,CAACf,OAAO,CAACgB,IAAI,CAAC,mBAAmB,EAAEF,GAAG,CAACS,EAAE,CAAC;MAC9C,IAAI,CAACvB,OAAO,CAACgB,IAAI,CAAC,YAAY,EAAEF,GAAG,CAACQ,MAAM,CAAC;MAC3C,IAAI,CAACtB,OAAO,CAACgB,IAAI,CAAC,gBAAgB,EAAEF,GAAG,CAACU,SAAS,CAAC;MAClD,IAAIV,GAAG,CAACQ,MAAM,KAAK,MAAM,EAAE;QACvB,IAAI,CAACtB,OAAO,CAACgB,IAAI,CAAC,iBAAiB,EAAEF,GAAG,CAACW,UAAU,CAAC;MACxD;MACA,KAAK,MAAMC,SAAS,IAAIb,UAAU,EAAE;QAChC,IAAI,CAACb,OAAO,CAACgB,IAAI,CACb,GAAG,CACC,YAAYU,SAAS,CAACC,WAAW,EAAE,EACnC,IAAAC,oBAAM,EAAC,IAAI,CAACC,QAAQ,CAACH,SAAS,CAACJ,MAAM,CAAC,EAAEL,SAAS,CAAC,EAClDS,SAAS,CAACH,EAAE,CAEpB,CAAC;MACL;MAEA,IAAI,CAACxB,WAAW,CAAC+B,mBAAmB,CAAC,CAAC;IAC1C,CAAC,CAAC;IAEF5B,MAAM,CAAC6B,OAAO,CAACC,KAAK,IAAI;MACpB,IAAI,CAAChC,OAAO,CAACgC,KAAK,CAACA,KAAK,CAACC,OAAO,CAAC;IACrC,CAAC,CAAC;;IAEF;IACA,OAAO/B,MAAM,CAACO,OAAO,CAAC,CAAC;EAC3B;EAEQoB,QAAQA,CAACK,GAAW,EAAE;IAC1B,IAAIA,GAAG,CAACnB,MAAM,GAAG,CAAC,GAAG,CAAC,EAAE;MACpB,OAAOmB,GAAG,GAAG,GAAG;IACpB;IACA,OAAOA,GAAG;EACd;AACJ;AAACC,OAAA,CAAAtC,uBAAA,GAAAA,uBAAA","ignoreList":[]}
@@ -0,0 +1,11 @@
1
+ import type { MigrationStatusReporter } from "./MigrationStatusReporter";
2
+ import type { MigrationStatus } from "../types";
3
+ import type { LogReporter } from "./LogReporter";
4
+ export declare class InteractiveCliStatusReporter implements MigrationStatusReporter {
5
+ private logReporter;
6
+ private firstCall;
7
+ constructor(logReporter: LogReporter);
8
+ report(migrationStatus: MigrationStatus): Promise<void>;
9
+ private clearLine;
10
+ private getDuration;
11
+ }
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.InteractiveCliStatusReporter = void 0;
8
+ var _readline = _interopRequireDefault(require("readline"));
9
+ class InteractiveCliStatusReporter {
10
+ firstCall = true;
11
+ constructor(logReporter) {
12
+ this.logReporter = logReporter;
13
+ console.log(`Using "InteractiveCliStatusReporter".`);
14
+ }
15
+ async report(migrationStatus) {
16
+ const {
17
+ status,
18
+ migrations,
19
+ context
20
+ } = migrationStatus;
21
+ this.clearLine();
22
+ const currentLogStreamName = context?.logStreamName;
23
+ if (currentLogStreamName) {
24
+ this.logReporter.initializeStream(currentLogStreamName);
25
+ if (this.firstCall) {
26
+ this.logReporter.printLogStreamLinks();
27
+ process.stdout.write(`\n---------- MIGRATION LOGS START ----------\n\n`);
28
+ }
29
+ await this.logReporter.printLogs(currentLogStreamName);
30
+ }
31
+ if (status === "running") {
32
+ const currentMigration = migrations.find(mig => mig.status === "running");
33
+ if (currentMigration) {
34
+ const duration = this.getDuration(String(currentMigration.startedOn));
35
+ process.stdout.write(`Running data migration ${currentMigration.id} (${duration})...`);
36
+ }
37
+ }
38
+ if (status === "init") {
39
+ process.stdout.write(`Checking data migrations...`);
40
+ }
41
+ if (["done", "error"].includes(status)) {
42
+ this.clearLine();
43
+ process.stdout.write(`Migration run finished, waiting for latest logs...`);
44
+
45
+ // We want to give AWS some time for the latest log events to become available.
46
+ await new Promise(resolve => {
47
+ setTimeout(resolve, 8000);
48
+ });
49
+ if (currentLogStreamName) {
50
+ this.clearLine();
51
+ await this.logReporter.printLogs(currentLogStreamName);
52
+ process.stdout.write(`\n---------- MIGRATION LOGS END ----------\n`);
53
+ }
54
+ }
55
+ this.firstCall = false;
56
+ }
57
+ clearLine() {
58
+ _readline.default.clearLine(process.stdout, 0);
59
+ _readline.default.cursorTo(process.stdout, 0);
60
+ }
61
+ getDuration(since) {
62
+ const ms = new Date().getTime() - new Date(since).getTime();
63
+ let seconds = Math.floor(ms / 1000);
64
+ let minutes = undefined;
65
+ if (seconds > 60) {
66
+ minutes = Math.floor(seconds / 60);
67
+ seconds = Math.floor(seconds % 60);
68
+ }
69
+ return minutes ? `${minutes}m ${seconds}s` : `${seconds}s`;
70
+ }
71
+ }
72
+ exports.InteractiveCliStatusReporter = InteractiveCliStatusReporter;
73
+
74
+ //# sourceMappingURL=InteractiveCliStatusReporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_readline","_interopRequireDefault","require","InteractiveCliStatusReporter","firstCall","constructor","logReporter","console","log","report","migrationStatus","status","migrations","context","clearLine","currentLogStreamName","logStreamName","initializeStream","printLogStreamLinks","process","stdout","write","printLogs","currentMigration","find","mig","duration","getDuration","String","startedOn","id","includes","Promise","resolve","setTimeout","readline","cursorTo","since","ms","Date","getTime","seconds","Math","floor","minutes","undefined","exports"],"sources":["InteractiveCliStatusReporter.ts"],"sourcesContent":["import readline from \"readline\";\nimport type { MigrationStatusReporter } from \"~/cli/MigrationStatusReporter\";\nimport type { MigrationStatus } from \"~/types\";\nimport type { LogReporter } from \"~/cli/LogReporter\";\n\nexport class InteractiveCliStatusReporter implements MigrationStatusReporter {\n private logReporter: LogReporter;\n private firstCall = true;\n\n constructor(logReporter: LogReporter) {\n this.logReporter = logReporter;\n console.log(`Using \"InteractiveCliStatusReporter\".`);\n }\n\n async report(migrationStatus: MigrationStatus) {\n const { status, migrations, context } = migrationStatus;\n this.clearLine();\n\n const currentLogStreamName = context?.logStreamName;\n if (currentLogStreamName) {\n this.logReporter.initializeStream(currentLogStreamName);\n if (this.firstCall) {\n this.logReporter.printLogStreamLinks();\n process.stdout.write(`\\n---------- MIGRATION LOGS START ----------\\n\\n`);\n }\n await this.logReporter.printLogs(currentLogStreamName);\n }\n\n if (status === \"running\") {\n const currentMigration = migrations.find(mig => mig.status === \"running\");\n if (currentMigration) {\n const duration = this.getDuration(String(currentMigration.startedOn));\n process.stdout.write(\n `Running data migration ${currentMigration.id} (${duration})...`\n );\n }\n }\n\n if (status === \"init\") {\n process.stdout.write(`Checking data migrations...`);\n }\n\n if ([\"done\", \"error\"].includes(status)) {\n this.clearLine();\n process.stdout.write(`Migration run finished, waiting for latest logs...`);\n\n // We want to give AWS some time for the latest log events to become available.\n await new Promise(resolve => {\n setTimeout(resolve, 8000);\n });\n\n if (currentLogStreamName) {\n this.clearLine();\n await this.logReporter.printLogs(currentLogStreamName);\n process.stdout.write(`\\n---------- MIGRATION LOGS END ----------\\n`);\n }\n }\n\n this.firstCall = false;\n }\n\n private clearLine() {\n readline.clearLine(process.stdout, 0);\n readline.cursorTo(process.stdout, 0);\n }\n\n private getDuration(since: string) {\n const ms = new Date().getTime() - new Date(since).getTime();\n let seconds = Math.floor(ms / 1000);\n let minutes = undefined;\n if (seconds > 60) {\n minutes = Math.floor(seconds / 60);\n seconds = Math.floor(seconds % 60);\n }\n\n return minutes ? `${minutes}m ${seconds}s` : `${seconds}s`;\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,10 @@
1
+ import { LogStream } from "./LogStream";
2
+ export declare class LogReporter {
3
+ private readonly logGroupName;
4
+ private readonly logsCreatedSince;
5
+ private readonly logStreams;
6
+ constructor(functionName: string);
7
+ printLogs(logStreamName: string): Promise<void>;
8
+ printLogStreamLinks(): void;
9
+ initializeStream(name: string): LogStream;
10
+ }
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.LogReporter = void 0;
7
+ var _LogStream = require("./LogStream");
8
+ class LogReporter {
9
+ logStreams = new Set();
10
+ constructor(functionName) {
11
+ const baseName = functionName.split(":").pop();
12
+ this.logGroupName = `/aws/lambda/${baseName}`;
13
+ this.logsCreatedSince = Date.now();
14
+ }
15
+ async printLogs(logStreamName) {
16
+ const logStream = this.initializeStream(logStreamName);
17
+ await logStream.printLogsSince(this.logsCreatedSince);
18
+ }
19
+ printLogStreamLinks() {
20
+ if (this.logStreams.size === 0) {
21
+ return;
22
+ }
23
+ const logStreams = Array.from(this.logStreams);
24
+ if (this.logStreams.size === 1) {
25
+ process.stdout.write(`\nTo view detailed logs, visit the following AWS CloudWatch log stream:\n`);
26
+ process.stdout.write(logStreams[0].getLogStreamLink());
27
+ } else {
28
+ process.stdout.write(`\nTo view detailed logs, visit the following AWS CloudWatch log streams:\n`);
29
+ for (const logStream of logStreams) {
30
+ process.stdout.write(`- ${logStream.getLogStreamLink()}`);
31
+ }
32
+ }
33
+ process.stdout.write("\n");
34
+ }
35
+ initializeStream(name) {
36
+ const logStream = _LogStream.LogStream.create(this.logGroupName, name);
37
+ this.logStreams.add(logStream);
38
+ return logStream;
39
+ }
40
+ }
41
+ exports.LogReporter = LogReporter;
42
+
43
+ //# sourceMappingURL=LogReporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_LogStream","require","LogReporter","logStreams","Set","constructor","functionName","baseName","split","pop","logGroupName","logsCreatedSince","Date","now","printLogs","logStreamName","logStream","initializeStream","printLogsSince","printLogStreamLinks","size","Array","from","process","stdout","write","getLogStreamLink","name","LogStream","create","add","exports"],"sources":["LogReporter.ts"],"sourcesContent":["import { LogStream } from \"./LogStream\";\n\nexport class LogReporter {\n private readonly logGroupName: string;\n private readonly logsCreatedSince: number;\n private readonly logStreams = new Set<LogStream>();\n\n constructor(functionName: string) {\n const baseName = functionName.split(\":\").pop();\n this.logGroupName = `/aws/lambda/${baseName}`;\n this.logsCreatedSince = Date.now();\n }\n\n public async printLogs(logStreamName: string) {\n const logStream = this.initializeStream(logStreamName);\n await logStream.printLogsSince(this.logsCreatedSince);\n }\n\n public printLogStreamLinks() {\n if (this.logStreams.size === 0) {\n return;\n }\n\n const logStreams = Array.from(this.logStreams);\n\n if (this.logStreams.size === 1) {\n process.stdout.write(\n `\\nTo view detailed logs, visit the following AWS CloudWatch log stream:\\n`\n );\n process.stdout.write(logStreams[0].getLogStreamLink());\n } else {\n process.stdout.write(\n `\\nTo view detailed logs, visit the following AWS CloudWatch log streams:\\n`\n );\n\n for (const logStream of logStreams) {\n process.stdout.write(`- ${logStream.getLogStreamLink()}`);\n }\n }\n\n process.stdout.write(\"\\n\");\n }\n\n public initializeStream(name: string) {\n const logStream = LogStream.create(this.logGroupName, name);\n this.logStreams.add(logStream);\n return logStream;\n }\n}\n"],"mappings":";;;;;;AAAA,IAAAA,UAAA,GAAAC,OAAA;AAEO,MAAMC,WAAW,CAAC;EAGJC,UAAU,GAAG,IAAIC,GAAG,CAAY,CAAC;EAElDC,WAAWA,CAACC,YAAoB,EAAE;IAC9B,MAAMC,QAAQ,GAAGD,YAAY,CAACE,KAAK,CAAC,GAAG,CAAC,CAACC,GAAG,CAAC,CAAC;IAC9C,IAAI,CAACC,YAAY,GAAG,eAAeH,QAAQ,EAAE;IAC7C,IAAI,CAACI,gBAAgB,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC;EACtC;EAEA,MAAaC,SAASA,CAACC,aAAqB,EAAE;IAC1C,MAAMC,SAAS,GAAG,IAAI,CAACC,gBAAgB,CAACF,aAAa,CAAC;IACtD,MAAMC,SAAS,CAACE,cAAc,CAAC,IAAI,CAACP,gBAAgB,CAAC;EACzD;EAEOQ,mBAAmBA,CAAA,EAAG;IACzB,IAAI,IAAI,CAAChB,UAAU,CAACiB,IAAI,KAAK,CAAC,EAAE;MAC5B;IACJ;IAEA,MAAMjB,UAAU,GAAGkB,KAAK,CAACC,IAAI,CAAC,IAAI,CAACnB,UAAU,CAAC;IAE9C,IAAI,IAAI,CAACA,UAAU,CAACiB,IAAI,KAAK,CAAC,EAAE;MAC5BG,OAAO,CAACC,MAAM,CAACC,KAAK,CAChB,2EACJ,CAAC;MACDF,OAAO,CAACC,MAAM,CAACC,KAAK,CAACtB,UAAU,CAAC,CAAC,CAAC,CAACuB,gBAAgB,CAAC,CAAC,CAAC;IAC1D,CAAC,MAAM;MACHH,OAAO,CAACC,MAAM,CAACC,KAAK,CAChB,4EACJ,CAAC;MAED,KAAK,MAAMT,SAAS,IAAIb,UAAU,EAAE;QAChCoB,OAAO,CAACC,MAAM,CAACC,KAAK,CAAC,KAAKT,SAAS,CAACU,gBAAgB,CAAC,CAAC,EAAE,CAAC;MAC7D;IACJ;IAEAH,OAAO,CAACC,MAAM,CAACC,KAAK,CAAC,IAAI,CAAC;EAC9B;EAEOR,gBAAgBA,CAACU,IAAY,EAAE;IAClC,MAAMX,SAAS,GAAGY,oBAAS,CAACC,MAAM,CAAC,IAAI,CAACnB,YAAY,EAAEiB,IAAI,CAAC;IAC3D,IAAI,CAACxB,UAAU,CAAC2B,GAAG,CAACd,SAAS,CAAC;IAC9B,OAAOA,SAAS;EACpB;AACJ;AAACe,OAAA,CAAA7B,WAAA,GAAAA,WAAA","ignoreList":[]}