@webiny/data-migration 5.37.3-beta.1 → 5.37.3

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 (59) hide show
  1. package/MigrationRunner.d.ts +2 -0
  2. package/MigrationRunner.js +18 -5
  3. package/MigrationRunner.js.map +1 -1
  4. package/cli/CliMigrationRunReporter.d.ts +10 -0
  5. package/cli/CliMigrationRunReporter.js +58 -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 +45 -0
  12. package/cli/LogReporter.js.map +1 -0
  13. package/cli/LogStream.d.ts +10 -0
  14. package/cli/LogStream.js +62 -0
  15. package/cli/LogStream.js.map +1 -0
  16. package/cli/MigrationRunReporter.d.ts +4 -0
  17. package/cli/MigrationRunReporter.js +5 -0
  18. package/cli/MigrationRunReporter.js.map +1 -0
  19. package/cli/MigrationRunner.d.ts +44 -0
  20. package/cli/MigrationRunner.js +133 -0
  21. package/cli/MigrationRunner.js.map +1 -0
  22. package/cli/MigrationStatusReporter.d.ts +4 -0
  23. package/cli/MigrationStatusReporter.js +5 -0
  24. package/cli/MigrationStatusReporter.js.map +1 -0
  25. package/cli/NonInteractiveCliStatusReporter.d.ts +9 -0
  26. package/cli/NonInteractiveCliStatusReporter.js +43 -0
  27. package/cli/NonInteractiveCliStatusReporter.js.map +1 -0
  28. package/cli/VoidStatusReporter.d.ts +4 -0
  29. package/cli/VoidStatusReporter.js +12 -0
  30. package/cli/VoidStatusReporter.js.map +1 -0
  31. package/cli/getDuration.js +1 -3
  32. package/cli/index.d.ts +8 -2
  33. package/cli/index.js +78 -14
  34. package/cli/index.js.map +1 -1
  35. package/createPinoLogger.js +1 -3
  36. package/createTable.js +1 -3
  37. package/handlers/createDdbEsProjectMigration.js +5 -3
  38. package/handlers/createDdbEsProjectMigration.js.map +1 -1
  39. package/handlers/createDdbProjectMigration.js +5 -3
  40. package/handlers/createDdbProjectMigration.js.map +1 -1
  41. package/handlers/createPatternMatcher.js +1 -3
  42. package/handlers/devVersionErrorResponse.js +1 -3
  43. package/index.js +1 -3
  44. package/package.json +9 -9
  45. package/repository/createStandardEntity.js +1 -3
  46. package/repository/migrations.repository.js +1 -3
  47. package/symbols.js +1 -3
  48. package/types.d.ts +2 -0
  49. package/types.js +1 -3
  50. package/types.js.map +1 -1
  51. package/cli/getMigrationStatus.d.ts +0 -9
  52. package/cli/getMigrationStatus.js +0 -29
  53. package/cli/getMigrationStatus.js.map +0 -1
  54. package/cli/printReport.d.ts +0 -9
  55. package/cli/printReport.js +0 -59
  56. package/cli/printReport.js.map +0 -1
  57. package/cli/runMigration.d.ts +0 -13
  58. package/cli/runMigration.js +0 -87
  59. package/cli/runMigration.js.map +0 -1
@@ -6,7 +6,9 @@ export declare class MigrationRunner {
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);
11
+ setContext(context: Record<string, any>): void;
10
12
  execute(projectVersion: string, isApplicable?: IsMigrationApplicable): Promise<void>;
11
13
  getStatus(): Promise<MigrationStatus>;
12
14
  private validateIds;
@@ -21,6 +21,10 @@ const getRunItemDuration = runItem => {
21
21
  }
22
22
  return new Date(runItem.finishedOn).getTime() - new Date(runItem.startedOn).getTime();
23
23
  };
24
+ const shouldForceExecute = mig => {
25
+ const key = `WEBINY_MIGRATION_FORCE_EXECUTE_${mig.getId().replace(/[\.\-]/g, "_")}`;
26
+ return process.env[key] === "true";
27
+ };
24
28
  class MigrationNotFinished extends Error {}
25
29
  class MigrationInProgress extends Error {}
26
30
  class MigrationRunner {
@@ -29,6 +33,7 @@ class MigrationRunner {
29
33
  (0, _defineProperty2.default)(this, "migrations", void 0);
30
34
  (0, _defineProperty2.default)(this, "repository", void 0);
31
35
  (0, _defineProperty2.default)(this, "timeLimiter", void 0);
36
+ (0, _defineProperty2.default)(this, "context", {});
32
37
  this.repository = repository;
33
38
  this.timeLimiter = timeLimiter;
34
39
  this.migrations = migrations || [];
@@ -37,6 +42,9 @@ class MigrationRunner {
37
42
  }
38
43
  this.logger = logger;
39
44
  }
45
+ setContext(context) {
46
+ this.context = context;
47
+ }
40
48
  async execute(projectVersion, isApplicable) {
41
49
  const lastRun = await this.getOrCreateRun();
42
50
  try {
@@ -83,6 +91,9 @@ class MigrationRunner {
83
91
  };
84
92
  const isMigrationApplicable = isApplicable || defaultIsApplicable;
85
93
  const executableMigrations = this.migrations.filter(mig => {
94
+ if (shouldForceExecute(mig)) {
95
+ return true;
96
+ }
86
97
  if (!isMigrationApplicable(mig)) {
87
98
  this.setRunItem(lastRun, {
88
99
  id: mig.getId(),
@@ -98,6 +109,8 @@ class MigrationRunner {
98
109
  const shouldCreateCheckpoint = () => {
99
110
  return this.timeLimiter() < 120000;
100
111
  };
112
+
113
+ //
101
114
  for (const migration of executableMigrations) {
102
115
  const runItem = this.getOrCreateRunItem(lastRun, migration);
103
116
  const checkpoint = await this.repository.getCheckpoint(migration.getId());
@@ -109,6 +122,7 @@ class MigrationRunner {
109
122
  projectVersion,
110
123
  logger,
111
124
  checkpoint,
125
+ forceExecute: shouldForceExecute(migration),
112
126
  runningOutOfTime: shouldCreateCheckpoint,
113
127
  createCheckpoint: async data => {
114
128
  await this.createCheckpoint(migration, data);
@@ -120,7 +134,7 @@ class MigrationRunner {
120
134
  }
121
135
  };
122
136
  try {
123
- const shouldExecute = checkpoint ? true : await migration.shouldExecute(context);
137
+ const shouldExecute = checkpoint || shouldForceExecute(migration) ? true : await migration.shouldExecute(context);
124
138
  if (!shouldExecute) {
125
139
  this.logger.info(`Skipping migration %s.`, migration.getId());
126
140
  runItem.status = "skipped";
@@ -234,7 +248,8 @@ class MigrationRunner {
234
248
  status: "init",
235
249
  startedOn: getCurrentISOTime(),
236
250
  finishedOn: "",
237
- migrations: []
251
+ migrations: [],
252
+ context: this.context
238
253
  };
239
254
  await this.repository.saveRun(lastRun);
240
255
  }
@@ -272,6 +287,4 @@ exports.MigrationRunner = MigrationRunner;
272
287
  optional: true
273
288
  }), (0, _ioc.inject)(_symbols.LoggerSymbol, {
274
289
  optional: true
275
- })]);
276
-
277
- //# sourceMappingURL=MigrationRunner.js.map
290
+ })]);
@@ -1 +1 @@
1
- {"version":3,"names":["_semver","require","_ioc","_utils","_symbols","_createPinoLogger","getCurrentISOTime","Date","toISOString","getRunItemDuration","runItem","startedOn","finishedOn","getTime","MigrationNotFinished","Error","MigrationInProgress","MigrationRunner","constructor","repository","timeLimiter","migrations","logger","_defineProperty2","default","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","_objectSpread2","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\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 try {\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 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 };\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","constructor","repository","timeLimiter","migrations","logger","_defineProperty2","default","createPinoLogger","setContext","context","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","_objectSpread2","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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"}
@@ -0,0 +1,10 @@
1
+ import { MigrationRunnerResult, MigrationRunReporter } from ".";
2
+ import { CliContext } from "@webiny/cli/types";
3
+ import { 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,58 @@
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 _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
9
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
+ var _centerAlign = _interopRequireDefault(require("center-align"));
11
+ const _excluded = ["migrations"];
12
+ class CliMigrationRunReporter {
13
+ constructor(logReporter, context) {
14
+ (0, _defineProperty2.default)(this, "context", void 0);
15
+ (0, _defineProperty2.default)(this, "logReporter", void 0);
16
+ this.logReporter = logReporter;
17
+ this.context = context;
18
+ }
19
+ report(result) {
20
+ result.onSuccess(data => {
21
+ const functionName = result.getFunctionName().split(":").pop();
22
+ process.stdout.write("\n");
23
+ this.context.success(`Data migration Lambda %s executed successfully!`, functionName);
24
+ const {
25
+ migrations
26
+ } = data,
27
+ run = (0, _objectWithoutProperties2.default)(data, _excluded);
28
+ if (!migrations.length) {
29
+ this.context.info(`No applicable migrations were found!`);
30
+ return;
31
+ }
32
+ const maxLength = Math.max(...migrations.map(mig => mig.status.length)) + 2;
33
+ this.context.info(`Migration run: %s`, run.id);
34
+ this.context.info(`Status: %s`, run.status);
35
+ this.context.info(`Started on: %s`, run.startedOn);
36
+ if (run.status === "done") {
37
+ this.context.info(`Finished on: %s`, run.finishedOn);
38
+ }
39
+ for (const migration of migrations) {
40
+ this.context.info(...[`[%s] %s: ${migration.description}`, (0, _centerAlign.default)(this.makeEven(migration.status), maxLength), migration.id]);
41
+ }
42
+ this.logReporter.printLogStreamLinks();
43
+ });
44
+ result.onError(error => {
45
+ this.context.error(error.message);
46
+ });
47
+
48
+ // Process the result!
49
+ return result.process();
50
+ }
51
+ makeEven(str) {
52
+ if (str.length % 2 > 0) {
53
+ return str + " ";
54
+ }
55
+ return str;
56
+ }
57
+ }
58
+ exports.CliMigrationRunReporter = CliMigrationRunReporter;
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_centerAlign","_interopRequireDefault","require","_excluded","CliMigrationRunReporter","constructor","logReporter","context","_defineProperty2","default","report","result","onSuccess","data","functionName","getFunctionName","split","pop","process","stdout","write","success","migrations","run","_objectWithoutProperties2","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 { MigrationRunnerResult, MigrationRunReporter } from \"~/cli\";\nimport center from \"center-align\";\nimport { CliContext } from \"@webiny/cli/types\";\nimport { 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;AAAkC,MAAAC,SAAA;AAI3B,MAAMC,uBAAuB,CAAiC;EAIjEC,WAAWA,CAACC,WAAwB,EAAEC,OAAmB,EAAE;IAAA,IAAAC,gBAAA,CAAAC,OAAA;IAAA,IAAAD,gBAAA,CAAAC,OAAA;IACvD,IAAI,CAACH,WAAW,GAAGA,WAAW;IAC9B,IAAI,CAACC,OAAO,GAAGA,OAAO;EAC1B;EAEAG,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,CAACb,OAAO,CAACc,OAAO,CAAE,iDAAgD,EAAEP,YAAY,CAAC;MAErF,MAAM;UAAEQ;QAAmB,CAAC,GAAGT,IAAI;QAAZU,GAAG,OAAAC,yBAAA,CAAAf,OAAA,EAAKI,IAAI,EAAAV,SAAA;MACnC,IAAI,CAACmB,UAAU,CAACG,MAAM,EAAE;QACpB,IAAI,CAAClB,OAAO,CAACmB,IAAI,CAAE,sCAAqC,CAAC;QACzD;MACJ;MAEA,MAAMC,SAAS,GAAGC,IAAI,CAACC,GAAG,CAAC,GAAGP,UAAU,CAACQ,GAAG,CAACC,GAAG,IAAIA,GAAG,CAACC,MAAM,CAACP,MAAM,CAAC,CAAC,GAAG,CAAC;MAC3E,IAAI,CAAClB,OAAO,CAACmB,IAAI,CAAE,mBAAkB,EAAEH,GAAG,CAACU,EAAE,CAAC;MAC9C,IAAI,CAAC1B,OAAO,CAACmB,IAAI,CAAE,YAAW,EAAEH,GAAG,CAACS,MAAM,CAAC;MAC3C,IAAI,CAACzB,OAAO,CAACmB,IAAI,CAAE,gBAAe,EAAEH,GAAG,CAACW,SAAS,CAAC;MAClD,IAAIX,GAAG,CAACS,MAAM,KAAK,MAAM,EAAE;QACvB,IAAI,CAACzB,OAAO,CAACmB,IAAI,CAAE,iBAAgB,EAAEH,GAAG,CAACY,UAAU,CAAC;MACxD;MACA,KAAK,MAAMC,SAAS,IAAId,UAAU,EAAE;QAChC,IAAI,CAACf,OAAO,CAACmB,IAAI,CACb,GAAG,CACE,YAAWU,SAAS,CAACC,WAAY,EAAC,EACnC,IAAAC,oBAAM,EAAC,IAAI,CAACC,QAAQ,CAACH,SAAS,CAACJ,MAAM,CAAC,EAAEL,SAAS,CAAC,EAClDS,SAAS,CAACH,EAAE,CAEpB,CAAC;MACL;MAEA,IAAI,CAAC3B,WAAW,CAACkC,mBAAmB,CAAC,CAAC;IAC1C,CAAC,CAAC;IAEF7B,MAAM,CAAC8B,OAAO,CAACC,KAAK,IAAI;MACpB,IAAI,CAACnC,OAAO,CAACmC,KAAK,CAACA,KAAK,CAACC,OAAO,CAAC;IACrC,CAAC,CAAC;;IAEF;IACA,OAAOhC,MAAM,CAACO,OAAO,CAAC,CAAC;EAC3B;EAEQqB,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,CAAAzC,uBAAA,GAAAA,uBAAA"}
@@ -0,0 +1,11 @@
1
+ import { MigrationStatusReporter } from "./MigrationStatusReporter";
2
+ import { MigrationStatus } from "../types";
3
+ import { 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 _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _readline = _interopRequireDefault(require("readline"));
10
+ class InteractiveCliStatusReporter {
11
+ constructor(logReporter) {
12
+ (0, _defineProperty2.default)(this, "logReporter", void 0);
13
+ (0, _defineProperty2.default)(this, "firstCall", true);
14
+ this.logReporter = logReporter;
15
+ console.log(`Using "InteractiveCliStatusReporter".`);
16
+ }
17
+ async report(migrationStatus) {
18
+ const {
19
+ status,
20
+ migrations,
21
+ context
22
+ } = migrationStatus;
23
+ this.clearLine();
24
+ const currentLogStreamName = context === null || context === void 0 ? void 0 : context.logStreamName;
25
+ if (currentLogStreamName) {
26
+ this.logReporter.initializeStream(currentLogStreamName);
27
+ if (this.firstCall) {
28
+ this.logReporter.printLogStreamLinks();
29
+ process.stdout.write(`\n---------- MIGRATION LOGS START ----------\n\n`);
30
+ }
31
+ await this.logReporter.printLogs(currentLogStreamName);
32
+ }
33
+ if (status === "running") {
34
+ const currentMigration = migrations.find(mig => mig.status === "running");
35
+ if (currentMigration) {
36
+ const duration = this.getDuration(String(currentMigration.startedOn));
37
+ process.stdout.write(`Running data migration ${currentMigration.id} (${duration})...`);
38
+ }
39
+ }
40
+ if (status === "init") {
41
+ process.stdout.write(`Checking data migrations...`);
42
+ }
43
+ if (["done", "error"].includes(status)) {
44
+ this.clearLine();
45
+ process.stdout.write(`Migration run finished, waiting for latest logs...`);
46
+
47
+ // We want to give AWS some time for the latest log events to become available.
48
+ await new Promise(resolve => {
49
+ setTimeout(resolve, 8000);
50
+ });
51
+ if (currentLogStreamName) {
52
+ this.clearLine();
53
+ await this.logReporter.printLogs(currentLogStreamName);
54
+ process.stdout.write(`\n---------- MIGRATION LOGS END ----------\n`);
55
+ }
56
+ }
57
+ this.firstCall = false;
58
+ }
59
+ clearLine() {
60
+ _readline.default.clearLine(process.stdout, 0);
61
+ _readline.default.cursorTo(process.stdout, 0);
62
+ }
63
+ getDuration(since) {
64
+ const ms = new Date().getTime() - new Date(since).getTime();
65
+ let seconds = Math.floor(ms / 1000);
66
+ let minutes = undefined;
67
+ if (seconds > 60) {
68
+ minutes = Math.floor(seconds / 60);
69
+ seconds = Math.floor(seconds % 60);
70
+ }
71
+ return minutes ? `${minutes}m ${seconds}s` : `${seconds}s`;
72
+ }
73
+ }
74
+ exports.InteractiveCliStatusReporter = InteractiveCliStatusReporter;
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_readline","_interopRequireDefault","require","InteractiveCliStatusReporter","constructor","logReporter","_defineProperty2","default","console","log","report","migrationStatus","status","migrations","context","clearLine","currentLogStreamName","logStreamName","initializeStream","firstCall","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 { MigrationStatusReporter } from \"~/cli/MigrationStatusReporter\";\nimport { MigrationStatus } from \"~/types\";\nimport { 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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"}
@@ -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,45 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.LogReporter = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _LogStream = require("./LogStream");
10
+ class LogReporter {
11
+ constructor(functionName) {
12
+ (0, _defineProperty2.default)(this, "logGroupName", void 0);
13
+ (0, _defineProperty2.default)(this, "logsCreatedSince", void 0);
14
+ (0, _defineProperty2.default)(this, "logStreams", new Set());
15
+ const baseName = functionName.split(":").pop();
16
+ this.logGroupName = `/aws/lambda/${baseName}`;
17
+ this.logsCreatedSince = Date.now();
18
+ }
19
+ async printLogs(logStreamName) {
20
+ const logStream = this.initializeStream(logStreamName);
21
+ await logStream.printLogsSince(this.logsCreatedSince);
22
+ }
23
+ printLogStreamLinks() {
24
+ if (this.logStreams.size === 0) {
25
+ return;
26
+ }
27
+ const logStreams = Array.from(this.logStreams);
28
+ if (this.logStreams.size === 1) {
29
+ process.stdout.write(`\nTo view detailed logs, visit the following AWS CloudWatch log stream:\n`);
30
+ process.stdout.write(logStreams[0].getLogStreamLink());
31
+ } else {
32
+ process.stdout.write(`\nTo view detailed logs, visit the following AWS CloudWatch log streams:\n`);
33
+ for (const logStream of logStreams) {
34
+ process.stdout.write(`- ${logStream.getLogStreamLink()}`);
35
+ }
36
+ }
37
+ process.stdout.write("\n");
38
+ }
39
+ initializeStream(name) {
40
+ const logStream = _LogStream.LogStream.create(this.logGroupName, name);
41
+ this.logStreams.add(logStream);
42
+ return logStream;
43
+ }
44
+ }
45
+ exports.LogReporter = LogReporter;
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_LogStream","require","LogReporter","constructor","functionName","_defineProperty2","default","Set","baseName","split","pop","logGroupName","logsCreatedSince","Date","now","printLogs","logStreamName","logStream","initializeStream","printLogsSince","printLogStreamLinks","logStreams","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;EAKrBC,WAAWA,CAACC,YAAoB,EAAE;IAAA,IAAAC,gBAAA,CAAAC,OAAA;IAAA,IAAAD,gBAAA,CAAAC,OAAA;IAAA,IAAAD,gBAAA,CAAAC,OAAA,sBAFJ,IAAIC,GAAG,CAAY,CAAC;IAG9C,MAAMC,QAAQ,GAAGJ,YAAY,CAACK,KAAK,CAAC,GAAG,CAAC,CAACC,GAAG,CAAC,CAAC;IAC9C,IAAI,CAACC,YAAY,GAAI,eAAcH,QAAS,EAAC;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,CAACC,UAAU,CAACC,IAAI,KAAK,CAAC,EAAE;MAC5B;IACJ;IAEA,MAAMD,UAAU,GAAGE,KAAK,CAACC,IAAI,CAAC,IAAI,CAACH,UAAU,CAAC;IAE9C,IAAI,IAAI,CAACA,UAAU,CAACC,IAAI,KAAK,CAAC,EAAE;MAC5BG,OAAO,CAACC,MAAM,CAACC,KAAK,CACf,2EACL,CAAC;MACDF,OAAO,CAACC,MAAM,CAACC,KAAK,CAACN,UAAU,CAAC,CAAC,CAAC,CAACO,gBAAgB,CAAC,CAAC,CAAC;IAC1D,CAAC,MAAM;MACHH,OAAO,CAACC,MAAM,CAACC,KAAK,CACf,4EACL,CAAC;MAED,KAAK,MAAMV,SAAS,IAAII,UAAU,EAAE;QAChCI,OAAO,CAACC,MAAM,CAACC,KAAK,CAAE,KAAIV,SAAS,CAACW,gBAAgB,CAAC,CAAE,EAAC,CAAC;MAC7D;IACJ;IAEAH,OAAO,CAACC,MAAM,CAACC,KAAK,CAAC,IAAI,CAAC;EAC9B;EAEOT,gBAAgBA,CAACW,IAAY,EAAE;IAClC,MAAMZ,SAAS,GAAGa,oBAAS,CAACC,MAAM,CAAC,IAAI,CAACpB,YAAY,EAAEkB,IAAI,CAAC;IAC3D,IAAI,CAACR,UAAU,CAACW,GAAG,CAACf,SAAS,CAAC;IAC9B,OAAOA,SAAS;EACpB;AACJ;AAACgB,OAAA,CAAA/B,WAAA,GAAAA,WAAA"}
@@ -0,0 +1,10 @@
1
+ export declare class LogStream {
2
+ private readonly logGroupName;
3
+ private readonly logStreamName;
4
+ private readonly cloudWatchLogs;
5
+ private nextPage;
6
+ private constructor();
7
+ getLogStreamLink(): string;
8
+ printLogsSince(startTime: number): Promise<void>;
9
+ static create(logGroupName: string, logStreamName: string): LogStream;
10
+ }
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.LogStream = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _cloudwatchlogs = _interopRequireDefault(require("aws-sdk/clients/cloudwatchlogs"));
10
+ const cache = new Map();
11
+ class LogStream {
12
+ constructor(logGroupName, logStreamName) {
13
+ (0, _defineProperty2.default)(this, "logGroupName", void 0);
14
+ (0, _defineProperty2.default)(this, "logStreamName", void 0);
15
+ (0, _defineProperty2.default)(this, "cloudWatchLogs", void 0);
16
+ (0, _defineProperty2.default)(this, "nextPage", void 0);
17
+ this.logGroupName = logGroupName;
18
+ this.logStreamName = logStreamName;
19
+ this.cloudWatchLogs = new _cloudwatchlogs.default();
20
+ }
21
+ getLogStreamLink() {
22
+ const replacements = [[/\$/g, "$2524"], [/\//g, "$252F"], [/\[/g, "$255B"], [/]/g, "$255D"]];
23
+ const replacer = (value, replacement) => {
24
+ return value.replace(replacement[0], replacement[1]);
25
+ };
26
+ return [`https://${process.env.AWS_REGION}.console.aws.amazon.com/cloudwatch/home?region=${process.env.AWS_REGION}#logsV2:log-groups/log-group/`, replacements.reduce(replacer, this.logGroupName), "/log-events/", replacements.reduce(replacer, this.logStreamName)].join("");
27
+ }
28
+ async printLogsSince(startTime) {
29
+ const params = {
30
+ logStreamName: this.logStreamName,
31
+ logGroupName: this.logGroupName,
32
+ nextToken: this.nextPage,
33
+ startFromHead: true,
34
+ startTime,
35
+ unmask: true
36
+ };
37
+ try {
38
+ const {
39
+ events,
40
+ nextForwardToken
41
+ } = await this.cloudWatchLogs.getLogEvents(params).promise();
42
+ this.nextPage = nextForwardToken;
43
+ if (events) {
44
+ events.forEach(event => {
45
+ process.stdout.write(String(event.message));
46
+ });
47
+ }
48
+ } catch (err) {
49
+ console.log(`Couldn't fetch logs: ${err.message}`);
50
+ }
51
+ }
52
+ static create(logGroupName, logStreamName) {
53
+ const cacheId = `${logGroupName}:${logStreamName}`;
54
+ if (cache.has(cacheId)) {
55
+ return cache.get(cacheId);
56
+ }
57
+ const logStream = new LogStream(logGroupName, logStreamName);
58
+ cache.set(cacheId, logStream);
59
+ return logStream;
60
+ }
61
+ }
62
+ exports.LogStream = LogStream;
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_cloudwatchlogs","_interopRequireDefault","require","cache","Map","LogStream","constructor","logGroupName","logStreamName","_defineProperty2","default","cloudWatchLogs","CloudWatchLogs","getLogStreamLink","replacements","replacer","value","replacement","replace","process","env","AWS_REGION","reduce","join","printLogsSince","startTime","params","nextToken","nextPage","startFromHead","unmask","events","nextForwardToken","getLogEvents","promise","forEach","event","stdout","write","String","message","err","console","log","create","cacheId","has","get","logStream","set","exports"],"sources":["LogStream.ts"],"sourcesContent":["import CloudWatchLogs from \"aws-sdk/clients/cloudwatchlogs\";\n\nconst cache = new Map<string, LogStream>();\n\nexport class LogStream {\n private readonly logGroupName: string;\n private readonly logStreamName: string;\n private readonly cloudWatchLogs: CloudWatchLogs;\n private nextPage: string | undefined;\n\n private constructor(logGroupName: string, logStreamName: string) {\n this.logGroupName = logGroupName;\n this.logStreamName = logStreamName;\n this.cloudWatchLogs = new CloudWatchLogs();\n }\n\n getLogStreamLink() {\n const replacements = [\n [/\\$/g, \"$2524\"],\n [/\\//g, \"$252F\"],\n [/\\[/g, \"$255B\"],\n [/]/g, \"$255D\"]\n ];\n\n const replacer = (value: string, replacement: (string | RegExp)[]) => {\n return value.replace(replacement[0], replacement[1] as string);\n };\n\n return [\n `https://${process.env.AWS_REGION}.console.aws.amazon.com/cloudwatch/home?region=${process.env.AWS_REGION}#logsV2:log-groups/log-group/`,\n replacements.reduce(replacer, this.logGroupName),\n \"/log-events/\",\n replacements.reduce(replacer, this.logStreamName)\n ].join(\"\");\n }\n\n async printLogsSince(startTime: number): Promise<void> {\n const params: CloudWatchLogs.Types.GetLogEventsRequest = {\n logStreamName: this.logStreamName,\n logGroupName: this.logGroupName,\n nextToken: this.nextPage,\n startFromHead: true,\n startTime,\n unmask: true\n };\n\n try {\n const { events, nextForwardToken } = await this.cloudWatchLogs\n .getLogEvents(params)\n .promise();\n\n this.nextPage = nextForwardToken;\n\n if (events) {\n events.forEach(event => {\n process.stdout.write(String(event.message));\n });\n }\n } catch (err) {\n console.log(`Couldn't fetch logs: ${err.message}`);\n }\n }\n\n public static create(logGroupName: string, logStreamName: string) {\n const cacheId = `${logGroupName}:${logStreamName}`;\n\n if (cache.has(cacheId)) {\n return cache.get(cacheId) as LogStream;\n }\n\n const logStream = new LogStream(logGroupName, logStreamName);\n cache.set(cacheId, logStream);\n\n return logStream;\n }\n}\n"],"mappings":";;;;;;;;AAAA,IAAAA,eAAA,GAAAC,sBAAA,CAAAC,OAAA;AAEA,MAAMC,KAAK,GAAG,IAAIC,GAAG,CAAoB,CAAC;AAEnC,MAAMC,SAAS,CAAC;EAMXC,WAAWA,CAACC,YAAoB,EAAEC,aAAqB,EAAE;IAAA,IAAAC,gBAAA,CAAAC,OAAA;IAAA,IAAAD,gBAAA,CAAAC,OAAA;IAAA,IAAAD,gBAAA,CAAAC,OAAA;IAAA,IAAAD,gBAAA,CAAAC,OAAA;IAC7D,IAAI,CAACH,YAAY,GAAGA,YAAY;IAChC,IAAI,CAACC,aAAa,GAAGA,aAAa;IAClC,IAAI,CAACG,cAAc,GAAG,IAAIC,uBAAc,CAAC,CAAC;EAC9C;EAEAC,gBAAgBA,CAAA,EAAG;IACf,MAAMC,YAAY,GAAG,CACjB,CAAC,KAAK,EAAE,OAAO,CAAC,EAChB,CAAC,KAAK,EAAE,OAAO,CAAC,EAChB,CAAC,KAAK,EAAE,OAAO,CAAC,EAChB,CAAC,IAAI,EAAE,OAAO,CAAC,CAClB;IAED,MAAMC,QAAQ,GAAGA,CAACC,KAAa,EAAEC,WAAgC,KAAK;MAClE,OAAOD,KAAK,CAACE,OAAO,CAACD,WAAW,CAAC,CAAC,CAAC,EAAEA,WAAW,CAAC,CAAC,CAAW,CAAC;IAClE,CAAC;IAED,OAAO,CACF,WAAUE,OAAO,CAACC,GAAG,CAACC,UAAW,kDAAiDF,OAAO,CAACC,GAAG,CAACC,UAAW,+BAA8B,EACxIP,YAAY,CAACQ,MAAM,CAACP,QAAQ,EAAE,IAAI,CAACR,YAAY,CAAC,EAChD,cAAc,EACdO,YAAY,CAACQ,MAAM,CAACP,QAAQ,EAAE,IAAI,CAACP,aAAa,CAAC,CACpD,CAACe,IAAI,CAAC,EAAE,CAAC;EACd;EAEA,MAAMC,cAAcA,CAACC,SAAiB,EAAiB;IACnD,MAAMC,MAAgD,GAAG;MACrDlB,aAAa,EAAE,IAAI,CAACA,aAAa;MACjCD,YAAY,EAAE,IAAI,CAACA,YAAY;MAC/BoB,SAAS,EAAE,IAAI,CAACC,QAAQ;MACxBC,aAAa,EAAE,IAAI;MACnBJ,SAAS;MACTK,MAAM,EAAE;IACZ,CAAC;IAED,IAAI;MACA,MAAM;QAAEC,MAAM;QAAEC;MAAiB,CAAC,GAAG,MAAM,IAAI,CAACrB,cAAc,CACzDsB,YAAY,CAACP,MAAM,CAAC,CACpBQ,OAAO,CAAC,CAAC;MAEd,IAAI,CAACN,QAAQ,GAAGI,gBAAgB;MAEhC,IAAID,MAAM,EAAE;QACRA,MAAM,CAACI,OAAO,CAACC,KAAK,IAAI;UACpBjB,OAAO,CAACkB,MAAM,CAACC,KAAK,CAACC,MAAM,CAACH,KAAK,CAACI,OAAO,CAAC,CAAC;QAC/C,CAAC,CAAC;MACN;IACJ,CAAC,CAAC,OAAOC,GAAG,EAAE;MACVC,OAAO,CAACC,GAAG,CAAE,wBAAuBF,GAAG,CAACD,OAAQ,EAAC,CAAC;IACtD;EACJ;EAEA,OAAcI,MAAMA,CAACrC,YAAoB,EAAEC,aAAqB,EAAE;IAC9D,MAAMqC,OAAO,GAAI,GAAEtC,YAAa,IAAGC,aAAc,EAAC;IAElD,IAAIL,KAAK,CAAC2C,GAAG,CAACD,OAAO,CAAC,EAAE;MACpB,OAAO1C,KAAK,CAAC4C,GAAG,CAACF,OAAO,CAAC;IAC7B;IAEA,MAAMG,SAAS,GAAG,IAAI3C,SAAS,CAACE,YAAY,EAAEC,aAAa,CAAC;IAC5DL,KAAK,CAAC8C,GAAG,CAACJ,OAAO,EAAEG,SAAS,CAAC;IAE7B,OAAOA,SAAS;EACpB;AACJ;AAACE,OAAA,CAAA7C,SAAA,GAAAA,SAAA"}
@@ -0,0 +1,4 @@
1
+ import { MigrationRunnerResult } from "./MigrationRunner";
2
+ export interface MigrationRunReporter {
3
+ report(result: MigrationRunnerResult): void | Promise<void>;
4
+ }
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["MigrationRunReporter.ts"],"sourcesContent":["import { MigrationRunnerResult } from \"~/cli/MigrationRunner\";\n\nexport interface MigrationRunReporter {\n report(result: MigrationRunnerResult): void | Promise<void>;\n}\n"],"mappings":""}
@@ -0,0 +1,44 @@
1
+ import LambdaClient from "aws-sdk/clients/lambda";
2
+ import { MigrationStatusReporter } from "./MigrationStatusReporter";
3
+ import { MigrationInvocationErrorResponse, MigrationStatusResponse } from "../types";
4
+ interface MigrationRunnerConfig {
5
+ lambdaClient: LambdaClient;
6
+ functionName: string;
7
+ statusReporter?: MigrationStatusReporter;
8
+ }
9
+ interface MigrationPayload {
10
+ version: string;
11
+ pattern?: string;
12
+ }
13
+ interface SuccessResultHandler {
14
+ (result: MigrationStatusResponse["data"]): void | Promise<void>;
15
+ }
16
+ interface ErrorResultHandler {
17
+ (error: MigrationInvocationErrorResponse["error"]): void | Promise<void>;
18
+ }
19
+ export declare class MigrationRunnerResult {
20
+ private readonly functionName;
21
+ private readonly result;
22
+ private readonly successBranch;
23
+ private readonly errorBranch;
24
+ constructor(functionName: string, result: MigrationStatusResponse | MigrationInvocationErrorResponse);
25
+ getFunctionName(): string;
26
+ onSuccess(cb: SuccessResultHandler): void;
27
+ onError(cb: ErrorResultHandler): void;
28
+ process(): Promise<void>;
29
+ }
30
+ export declare class MigrationRunner {
31
+ private readonly lambdaClient;
32
+ private readonly functionName;
33
+ private statusReporter;
34
+ static create(params: MigrationRunnerConfig): MigrationRunner;
35
+ private constructor();
36
+ setStatusReporter(reporter: MigrationStatusReporter): void;
37
+ runMigration(payload: MigrationPayload): Promise<MigrationRunnerResult>;
38
+ private reportStatus;
39
+ private invokeMigration;
40
+ private getResult;
41
+ private getStatus;
42
+ private getMigrationStatusReportInterval;
43
+ }
44
+ export {};