@prairielearn/migrations 2.0.1 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @prairielearn/migrations
2
2
 
3
+ ## 2.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 2b003b4d9: Upgrade all dependencies
8
+ - Updated dependencies [2b003b4d9]
9
+ - Updated dependencies [297bbce5a]
10
+ - @prairielearn/named-locks@1.4.0
11
+ - @prairielearn/postgres@1.7.2
12
+ - @prairielearn/logger@1.0.2
13
+ - @prairielearn/error@1.0.3
14
+
3
15
  ## 2.0.1
4
16
 
5
17
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prairielearn/migrations",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "main": "./dist/index.js",
5
5
  "repository": {
6
6
  "type": "git",
@@ -16,17 +16,17 @@
16
16
  "@prairielearn/tsconfig": "^0.0.0",
17
17
  "@types/fs-extra": "^11.0.1",
18
18
  "@types/mocha": "^10.0.1",
19
- "@types/node": "^18.16.16",
19
+ "@types/node": "^18.16.19",
20
20
  "mocha": "^10.2.0",
21
21
  "ts-node": "^10.9.1",
22
- "typescript": "^5.1.3",
22
+ "typescript": "^5.1.6",
23
23
  "typescript-cp": "^0.1.8"
24
24
  },
25
25
  "dependencies": {
26
- "@prairielearn/error": "^1.0.2",
27
- "@prairielearn/logger": "^1.0.1",
28
- "@prairielearn/named-locks": "^1.3.3",
29
- "@prairielearn/postgres": "^1.7.1",
26
+ "@prairielearn/error": "^1.0.3",
27
+ "@prairielearn/logger": "^1.0.2",
28
+ "@prairielearn/named-locks": "^1.4.0",
29
+ "@prairielearn/postgres": "^1.7.2",
30
30
  "fs-extra": "^11.1.1",
31
31
  "serialize-error": "^8.1.0",
32
32
  "zod": "^3.21.4"
@@ -24,11 +24,11 @@ export type BatchedMigrationJobRow = z.infer<typeof BatchedMigrationJobRowSchema
24
24
  export async function selectRecentJobsWithStatus(
25
25
  batchedMigrationId: string,
26
26
  status: BatchedMigrationJobStatus,
27
- limit: number
27
+ limit: number,
28
28
  ): Promise<BatchedMigrationJobRow[]> {
29
29
  return queryValidatedRows(
30
30
  sql.select_recent_jobs_with_status,
31
31
  { batched_migration_id: batchedMigrationId, status, limit },
32
- BatchedMigrationJobRowSchema
32
+ BatchedMigrationJobRowSchema,
33
33
  );
34
34
  }
@@ -57,7 +57,7 @@ async function getBatchedMigration(migrationId: string) {
57
57
  return queryValidatedOneRow(
58
58
  'SELECT * FROM batched_migrations WHERE id = $id;',
59
59
  { id: migrationId },
60
- BatchedMigrationRowSchema
60
+ BatchedMigrationRowSchema,
61
61
  );
62
62
  }
63
63
 
@@ -65,7 +65,7 @@ async function getBatchedMigrationJobs(migrationId: string) {
65
65
  return queryValidatedRows(
66
66
  'SELECT * FROM batched_migration_jobs WHERE batched_migration_id = $batched_migration_id ORDER BY id ASC;',
67
67
  { batched_migration_id: migrationId },
68
- BatchedMigrationJobRowSchema
68
+ BatchedMigrationJobRowSchema,
69
69
  );
70
70
  }
71
71
 
@@ -74,7 +74,7 @@ async function resetFailedBatchedMigrationJobs(migrationId: string) {
74
74
  "UPDATE batched_migration_jobs SET status = 'pending', updated_at = CURRENT_TIMESTAMP WHERE batched_migration_id = $batched_migration_id AND status = 'failed'",
75
75
  {
76
76
  batched_migration_id: migrationId,
77
- }
77
+ },
78
78
  );
79
79
  }
80
80
 
@@ -37,7 +37,7 @@ export class BatchedMigrationRunner {
37
37
  constructor(
38
38
  migration: BatchedMigrationRow,
39
39
  migrationImplementation: BatchedMigrationImplementation,
40
- options: BatchedMigrationRunnerOptions = {}
40
+ options: BatchedMigrationRunnerOptions = {},
41
41
  ) {
42
42
  this.options = options;
43
43
  this.migration = migration;
@@ -55,7 +55,7 @@ export class BatchedMigrationRunner {
55
55
  return queryValidatedSingleColumnOneRow(
56
56
  sql.batched_migration_has_incomplete_jobs,
57
57
  { batched_migration_id: migration.id },
58
- z.boolean()
58
+ z.boolean(),
59
59
  );
60
60
  }
61
61
 
@@ -63,7 +63,7 @@ export class BatchedMigrationRunner {
63
63
  return queryValidatedSingleColumnOneRow(
64
64
  sql.batched_migration_has_failed_jobs,
65
65
  { batched_migration_id: migration.id },
66
- z.boolean()
66
+ z.boolean(),
67
67
  );
68
68
  }
69
69
 
@@ -73,7 +73,7 @@ export class BatchedMigrationRunner {
73
73
  {
74
74
  id: migration.id,
75
75
  },
76
- BatchedMigrationStatusSchema
76
+ BatchedMigrationStatusSchema,
77
77
  );
78
78
  }
79
79
 
@@ -92,12 +92,12 @@ export class BatchedMigrationRunner {
92
92
  }
93
93
 
94
94
  private async getNextBatchBounds(
95
- migration: BatchedMigrationRow
95
+ migration: BatchedMigrationRow,
96
96
  ): Promise<null | [bigint, bigint]> {
97
97
  const lastJob = await queryValidatedZeroOrOneRow(
98
98
  sql.select_last_batched_migration_job,
99
99
  { batched_migration_id: migration.id },
100
- BatchedMigrationJobRowSchema
100
+ BatchedMigrationJobRowSchema,
101
101
  );
102
102
 
103
103
  const nextMin = lastJob ? lastJob.max_value + 1n : migration.min_value;
@@ -129,7 +129,7 @@ export class BatchedMigrationRunner {
129
129
  private async finishJob(
130
130
  job: BatchedMigrationJobRow,
131
131
  status: Extract<BatchedMigrationJobStatus, 'failed' | 'succeeded'>,
132
- data?: unknown
132
+ data?: unknown,
133
133
  ) {
134
134
  await queryAsync(sql.finish_batched_migration_job, {
135
135
  id: job.id,
@@ -140,7 +140,7 @@ export class BatchedMigrationRunner {
140
140
  }
141
141
 
142
142
  private async getOrCreateNextMigrationJob(
143
- migration: BatchedMigrationRow
143
+ migration: BatchedMigrationRow,
144
144
  ): Promise<BatchedMigrationJobRow | null> {
145
145
  const nextBatchBounds = await this.getNextBatchBounds(migration);
146
146
  if (nextBatchBounds) {
@@ -151,7 +151,7 @@ export class BatchedMigrationRunner {
151
151
  min_value: nextBatchBounds[0],
152
152
  max_value: nextBatchBounds[1],
153
153
  },
154
- BatchedMigrationJobRowSchema
154
+ BatchedMigrationJobRowSchema,
155
155
  );
156
156
  } else {
157
157
  // Pick up any old pending jobs from this migration. These will only exist if
@@ -160,14 +160,14 @@ export class BatchedMigrationRunner {
160
160
  return queryValidatedZeroOrOneRow(
161
161
  sql.select_first_pending_batched_migration_job,
162
162
  { batched_migration_id: migration.id },
163
- BatchedMigrationJobRowSchema
163
+ BatchedMigrationJobRowSchema,
164
164
  );
165
165
  }
166
166
  }
167
167
 
168
168
  private async runMigrationJob(
169
169
  migration: BatchedMigrationRow,
170
- migrationImplementation: BatchedMigrationImplementation
170
+ migrationImplementation: BatchedMigrationImplementation,
171
171
  ) {
172
172
  const nextJob = await this.getOrCreateNextMigrationJob(migration);
173
173
  if (nextJob) {
@@ -54,7 +54,7 @@ export function makeBatchedMigration<T extends BatchedMigrationImplementation>(f
54
54
  }
55
55
 
56
56
  export function validateBatchedMigrationImplementation(
57
- fns: BatchedMigrationImplementation
57
+ fns: BatchedMigrationImplementation,
58
58
  ): asserts fns is BatchedMigrationImplementation {
59
59
  if (typeof fns.getParameters !== 'function') {
60
60
  throw new Error('getParameters() must be a function');
@@ -74,12 +74,12 @@ type NewBatchedMigration = Pick<
74
74
  * project/timestamp pair, returns null, otherwise returns the inserted row.
75
75
  */
76
76
  export async function insertBatchedMigration(
77
- migration: NewBatchedMigration
77
+ migration: NewBatchedMigration,
78
78
  ): Promise<BatchedMigrationRow | null> {
79
79
  return queryValidatedZeroOrOneRow(
80
80
  sql.insert_batched_migration,
81
81
  migration,
82
- BatchedMigrationRowSchema
82
+ BatchedMigrationRowSchema,
83
83
  );
84
84
  }
85
85
 
@@ -87,40 +87,40 @@ export async function selectAllBatchedMigrations(project: string) {
87
87
  return queryValidatedRows(
88
88
  sql.select_all_batched_migrations,
89
89
  { project },
90
- BatchedMigrationRowSchema
90
+ BatchedMigrationRowSchema,
91
91
  );
92
92
  }
93
93
 
94
94
  export async function selectBatchedMigration(
95
95
  project: string,
96
- id: string
96
+ id: string,
97
97
  ): Promise<BatchedMigrationRow> {
98
98
  return queryValidatedOneRow(
99
99
  sql.select_batched_migration,
100
100
  { project, id },
101
- BatchedMigrationRowSchema
101
+ BatchedMigrationRowSchema,
102
102
  );
103
103
  }
104
104
 
105
105
  export async function selectBatchedMigrationForTimestamp(
106
106
  project: string,
107
- timestamp: string
107
+ timestamp: string,
108
108
  ): Promise<BatchedMigrationRow> {
109
109
  return queryValidatedOneRow(
110
110
  sql.select_batched_migration_for_timestamp,
111
111
  { project, timestamp },
112
- BatchedMigrationRowSchema
112
+ BatchedMigrationRowSchema,
113
113
  );
114
114
  }
115
115
 
116
116
  export async function updateBatchedMigrationStatus(
117
117
  id: string,
118
- status: BatchedMigrationStatus
118
+ status: BatchedMigrationStatus,
119
119
  ): Promise<BatchedMigrationRow> {
120
120
  return queryValidatedOneRow(
121
121
  sql.update_batched_migration_status,
122
122
  { id, status },
123
- BatchedMigrationRowSchema
123
+ BatchedMigrationRowSchema,
124
124
  );
125
125
  }
126
126
 
@@ -100,7 +100,7 @@ describe('BatchedMigrationsRunner', () => {
100
100
  runner.finalizeBatchedMigration('20230406184107_failing_migration', {
101
101
  logProgress: false,
102
102
  }),
103
- "but it is 'failed'"
103
+ "but it is 'failed'",
104
104
  );
105
105
 
106
106
  const migrations = await selectAllBatchedMigrations('test');
@@ -60,7 +60,7 @@ export class BatchedMigrationsRunner extends EventEmitter {
60
60
  if (!this.migrationFiles) {
61
61
  this.migrationFiles = await readAndValidateMigrationsFromDirectories(
62
62
  this.options.directories,
63
- EXTENSIONS
63
+ EXTENSIONS,
64
64
  );
65
65
  }
66
66
  return this.migrationFiles;
@@ -153,7 +153,7 @@ export class BatchedMigrationsRunner extends EventEmitter {
153
153
  if (migration.status === 'succeeded') return;
154
154
 
155
155
  throw new Error(
156
- `Expected batched migration with identifier ${identifier} to be marked as 'succeeded', but it is '${migration.status}'.`
156
+ `Expected batched migration with identifier ${identifier} to be marked as 'succeeded', but it is '${migration.status}'.`,
157
157
  );
158
158
  }
159
159
 
@@ -208,14 +208,14 @@ export class BatchedMigrationsRunner extends EventEmitter {
208
208
  let migration = await queryValidatedZeroOrOneRow(
209
209
  sql.select_running_migration,
210
210
  { project: this.options.project },
211
- BatchedMigrationRowSchema
211
+ BatchedMigrationRowSchema,
212
212
  );
213
213
 
214
214
  if (!migration) {
215
215
  migration = await queryValidatedZeroOrOneRow(
216
216
  sql.start_next_pending_migration,
217
217
  { project: this.options.project },
218
- BatchedMigrationRowSchema
218
+ BatchedMigrationRowSchema,
219
219
  );
220
220
  }
221
221
 
@@ -252,7 +252,7 @@ export class BatchedMigrationsRunner extends EventEmitter {
252
252
  } catch (err) {
253
253
  this.emit('error', err);
254
254
  }
255
- }
255
+ },
256
256
  );
257
257
 
258
258
  return didWork;
@@ -271,7 +271,7 @@ export class BatchedMigrationsRunner extends EventEmitter {
271
271
  let runner: BatchedMigrationsRunner | null = null;
272
272
 
273
273
  function assertRunner(
274
- runner: BatchedMigrationsRunner | null
274
+ runner: BatchedMigrationsRunner | null,
275
275
  ): asserts runner is BatchedMigrationsRunner {
276
276
  if (!runner) throw new Error('Batched migrations not initialized');
277
277
  }
@@ -320,7 +320,7 @@ export async function enqueueBatchedMigration(identifier: string) {
320
320
  */
321
321
  export async function finalizeBatchedMigration(
322
322
  identifier: string,
323
- options?: BatchedMigrationFinalizeOptions
323
+ options?: BatchedMigrationFinalizeOptions,
324
324
  ) {
325
325
  assertRunner(runner);
326
326
  await runner.finalizeBatchedMigration(identifier, options);
@@ -20,7 +20,7 @@ async function withMigrationFiles(files: string[], fn: (tmpDir: string) => Promi
20
20
  }
21
21
  await fn(tmpDir.path);
22
22
  },
23
- { unsafeCleanup: true }
23
+ { unsafeCleanup: true },
24
24
  );
25
25
  }
26
26
 
@@ -30,7 +30,7 @@ describe('load-migrations', () => {
30
30
  await withMigrationFiles(['001_testing.sql'], async (tmpDir) => {
31
31
  await assert.isRejected(
32
32
  readAndValidateMigrationsFromDirectory(tmpDir, ['.sql']),
33
- 'Invalid migration filename: 001_testing.sql'
33
+ 'Invalid migration filename: 001_testing.sql',
34
34
  );
35
35
  });
36
36
  });
@@ -41,9 +41,9 @@ describe('load-migrations', () => {
41
41
  async (tmpDir) => {
42
42
  await assert.isRejected(
43
43
  readAndValidateMigrationsFromDirectory(tmpDir, ['.sql']),
44
- 'Duplicate migration timestamp'
44
+ 'Duplicate migration timestamp',
45
45
  );
46
- }
46
+ },
47
47
  );
48
48
  });
49
49
  });
@@ -84,7 +84,7 @@ describe('load-migrations', () => {
84
84
  filename: '20220101010103_testing_3.sql',
85
85
  timestamp: '20220101010103',
86
86
  },
87
- ]
87
+ ],
88
88
  );
89
89
  });
90
90
  });
@@ -26,10 +26,10 @@ export interface MigrationFile {
26
26
 
27
27
  export async function readAndValidateMigrationsFromDirectory(
28
28
  dir: string,
29
- extensions: string[]
29
+ extensions: string[],
30
30
  ): Promise<MigrationFile[]> {
31
31
  const migrationFiles = (await fs.readdir(dir)).filter((m) =>
32
- extensions.some((e) => m.endsWith(e))
32
+ extensions.some((e) => m.endsWith(e)),
33
33
  );
34
34
 
35
35
  const migrations = migrationFiles.map((mf) => {
@@ -71,7 +71,7 @@ export async function readAndValidateMigrationsFromDirectory(
71
71
 
72
72
  export async function readAndValidateMigrationsFromDirectories(
73
73
  directories: string[],
74
- extensions: string[]
74
+ extensions: string[],
75
75
  ): Promise<MigrationFile[]> {
76
76
  const allMigrations: MigrationFile[] = [];
77
77
  for (const directory of directories) {
@@ -34,14 +34,14 @@ export async function init(directories: string | string[], project: string) {
34
34
  async () => {
35
35
  logger.verbose(`Acquired lock ${lockName}`);
36
36
  await initWithLock(migrationDirectories, project);
37
- }
37
+ },
38
38
  );
39
39
  logger.verbose(`Released lock ${lockName}`);
40
40
  }
41
41
 
42
42
  export function getMigrationsToExecute(
43
43
  migrationFiles: MigrationFile[],
44
- executedMigrations: { timestamp: string | null }[]
44
+ executedMigrations: { timestamp: string | null }[],
45
45
  ): MigrationFile[] {
46
46
  // If no migrations have ever been run, run them all.
47
47
  if (executedMigrations.length === 0) {
@@ -101,7 +101,7 @@ export async function initWithLock(directories: string[], project: string) {
101
101
  // This revision was the most recent commit to `master` before the
102
102
  // code handling indexes was removed.
103
103
  'You must deploy revision 1aa43c7348fa24cf636413d720d06a2fa9e38ef2 first.',
104
- ].join('\n')
104
+ ].join('\n'),
105
105
  );
106
106
  }
107
107