@prairielearn/migrations 2.1.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/.mocharc.cjs +3 -0
  2. package/CHANGELOG.md +25 -0
  3. package/dist/batched-migrations/batched-migration-job.js +18 -22
  4. package/dist/batched-migrations/batched-migration-job.js.map +1 -1
  5. package/dist/batched-migrations/batched-migration-runner.d.ts +2 -2
  6. package/dist/batched-migrations/batched-migration-runner.js +22 -26
  7. package/dist/batched-migrations/batched-migration-runner.js.map +1 -1
  8. package/dist/batched-migrations/batched-migration-runner.test.js +53 -78
  9. package/dist/batched-migrations/batched-migration-runner.test.js.map +1 -1
  10. package/dist/batched-migrations/batched-migration.js +30 -41
  11. package/dist/batched-migrations/batched-migration.js.map +1 -1
  12. package/dist/batched-migrations/batched-migrations-runner.d.ts +1 -1
  13. package/dist/batched-migrations/batched-migrations-runner.js +32 -67
  14. package/dist/batched-migrations/batched-migrations-runner.js.map +1 -1
  15. package/dist/batched-migrations/batched-migrations-runner.test.js +41 -69
  16. package/dist/batched-migrations/batched-migrations-runner.test.js.map +1 -1
  17. package/dist/batched-migrations/fixtures/20230406184103_successful_migration.js +2 -4
  18. package/dist/batched-migrations/fixtures/20230406184103_successful_migration.js.map +1 -1
  19. package/dist/batched-migrations/fixtures/20230406184107_failing_migration.d.ts +9 -0
  20. package/dist/batched-migrations/fixtures/20230406184107_failing_migration.js +14 -0
  21. package/dist/batched-migrations/fixtures/20230406184107_failing_migration.js.map +1 -0
  22. package/dist/batched-migrations/fixtures/20230407230446_no_rows_migration.js +2 -4
  23. package/dist/batched-migrations/fixtures/20230407230446_no_rows_migration.js.map +1 -1
  24. package/dist/batched-migrations/index.d.ts +3 -3
  25. package/dist/batched-migrations/index.js +3 -17
  26. package/dist/batched-migrations/index.js.map +1 -1
  27. package/dist/index.d.ts +2 -2
  28. package/dist/index.js +4 -22
  29. package/dist/index.js.map +1 -1
  30. package/dist/load-migrations.js +6 -16
  31. package/dist/load-migrations.js.map +1 -1
  32. package/dist/load-migrations.test.js +16 -44
  33. package/dist/load-migrations.test.js.map +1 -1
  34. package/dist/migrations/fixtures/20230407210430_insert_user.js +3 -6
  35. package/dist/migrations/fixtures/20230407210430_insert_user.js.map +1 -1
  36. package/dist/migrations/index.d.ts +1 -1
  37. package/dist/migrations/index.js +1 -5
  38. package/dist/migrations/index.js.map +1 -1
  39. package/dist/migrations/migrations.d.ts +1 -1
  40. package/dist/migrations/migrations.js +25 -57
  41. package/dist/migrations/migrations.js.map +1 -1
  42. package/dist/migrations/migrations.test.js +12 -17
  43. package/dist/migrations/migrations.test.js.map +1 -1
  44. package/package.json +14 -13
  45. package/src/batched-migrations/batched-migration-job.ts +2 -1
  46. package/src/batched-migrations/batched-migration-runner.test.ts +8 -6
  47. package/src/batched-migrations/batched-migration-runner.ts +10 -9
  48. package/src/batched-migrations/batched-migration.ts +3 -2
  49. package/src/batched-migrations/batched-migrations-runner.test.ts +15 -12
  50. package/src/batched-migrations/batched-migrations-runner.ts +7 -5
  51. package/src/batched-migrations/fixtures/20230406184103_successful_migration.ts +1 -1
  52. package/src/batched-migrations/fixtures/{20230406184107_failing_migration.js → 20230406184107_failing_migration.ts} +2 -3
  53. package/src/batched-migrations/fixtures/20230407230446_no_rows_migration.ts +1 -1
  54. package/src/batched-migrations/index.ts +7 -7
  55. package/src/index.ts +7 -7
  56. package/src/load-migrations.test.ts +6 -5
  57. package/src/migrations/index.ts +1 -1
  58. package/src/migrations/migrations.test.ts +5 -3
  59. package/src/migrations/migrations.ts +6 -5
  60. package/tsconfig.json +4 -1
@@ -1,44 +1,15 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
- Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.initWithLock = exports.getMigrationsToExecute = exports.init = void 0;
30
- const fs_extra_1 = __importDefault(require("fs-extra"));
31
- const path_1 = __importDefault(require("path"));
32
- const namedLocks = __importStar(require("@prairielearn/named-locks"));
33
- const logger_1 = require("@prairielearn/logger");
34
- const sqldb = __importStar(require("@prairielearn/postgres"));
35
- const error = __importStar(require("@prairielearn/error"));
36
- const load_migrations_1 = require("../load-migrations");
37
- const sql = sqldb.loadSqlEquiv(__filename);
38
- async function init(directories, project) {
1
+ import path from 'path';
2
+ import fs from 'fs-extra';
3
+ import * as error from '@prairielearn/error';
4
+ import { logger } from '@prairielearn/logger';
5
+ import * as namedLocks from '@prairielearn/named-locks';
6
+ import * as sqldb from '@prairielearn/postgres';
7
+ import { parseAnnotations, readAndValidateMigrationsFromDirectories, sortMigrationFiles, } from '../load-migrations.js';
8
+ const sql = sqldb.loadSqlEquiv(import.meta.filename);
9
+ export async function init(directories, project) {
39
10
  const migrationDirectories = Array.isArray(directories) ? directories : [directories];
40
11
  const lockName = 'migrations';
41
- logger_1.logger.verbose(`Waiting for lock ${lockName}`);
12
+ logger.verbose(`Waiting for lock ${lockName}`);
42
13
  await namedLocks.doWithLock(lockName, {
43
14
  // Migrations *might* take a long time to run, so we'll enable automatic
44
15
  // lock renewal so that our lock doesn't get killed by the Postgres
@@ -49,13 +20,12 @@ async function init(directories, project) {
49
20
  // Postgres is locking a whole table, which is unacceptable in production.
50
21
  autoRenew: true,
51
22
  }, async () => {
52
- logger_1.logger.verbose(`Acquired lock ${lockName}`);
23
+ logger.verbose(`Acquired lock ${lockName}`);
53
24
  await initWithLock(migrationDirectories, project);
54
25
  });
55
- logger_1.logger.verbose(`Released lock ${lockName}`);
26
+ logger.verbose(`Released lock ${lockName}`);
56
27
  }
57
- exports.init = init;
58
- function getMigrationsToExecute(migrationFiles, executedMigrations) {
28
+ export function getMigrationsToExecute(migrationFiles, executedMigrations) {
59
29
  // If no migrations have ever been run, run them all.
60
30
  if (executedMigrations.length === 0) {
61
31
  return migrationFiles;
@@ -63,9 +33,8 @@ function getMigrationsToExecute(migrationFiles, executedMigrations) {
63
33
  const executedMigrationTimestamps = new Set(executedMigrations.map((m) => m.timestamp));
64
34
  return migrationFiles.filter((m) => !executedMigrationTimestamps.has(m.timestamp));
65
35
  }
66
- exports.getMigrationsToExecute = getMigrationsToExecute;
67
- async function initWithLock(directories, project) {
68
- logger_1.logger.verbose('Starting DB schema migration');
36
+ export async function initWithLock(directories, project) {
37
+ logger.verbose('Starting DB schema migration');
69
38
  // Create the migrations table if needed
70
39
  await sqldb.queryAsync(sql.create_migrations_table, {});
71
40
  // Apply necessary changes to the migrations table as needed.
@@ -74,7 +43,7 @@ async function initWithLock(directories, project) {
74
43
  }
75
44
  catch (err) {
76
45
  if (err.routine === 'errorMissingColumn') {
77
- logger_1.logger.info('Altering migrations table');
46
+ logger.info('Altering migrations table');
78
47
  await sqldb.queryAsync(sql.add_projects_column, {});
79
48
  }
80
49
  else {
@@ -86,7 +55,7 @@ async function initWithLock(directories, project) {
86
55
  }
87
56
  catch (err) {
88
57
  if (err.routine === 'errorMissingColumn') {
89
- logger_1.logger.info('Altering migrations table again');
58
+ logger.info('Altering migrations table again');
90
59
  await sqldb.queryAsync(sql.add_timestamp_column, {});
91
60
  }
92
61
  else {
@@ -94,7 +63,7 @@ async function initWithLock(directories, project) {
94
63
  }
95
64
  }
96
65
  let allMigrations = await sqldb.queryAsync(sql.get_migrations, { project });
97
- const migrationFiles = await (0, load_migrations_1.readAndValidateMigrationsFromDirectories)(directories, [
66
+ const migrationFiles = await readAndValidateMigrationsFromDirectories(directories, [
98
67
  '.sql',
99
68
  '.js',
100
69
  '.ts',
@@ -116,21 +85,21 @@ async function initWithLock(directories, project) {
116
85
  // Refetch the list of migrations from the database.
117
86
  allMigrations = await sqldb.queryAsync(sql.get_migrations, { project });
118
87
  // Sort the migration files into execution order.
119
- const sortedMigrationFiles = (0, load_migrations_1.sortMigrationFiles)(migrationFiles);
88
+ const sortedMigrationFiles = sortMigrationFiles(migrationFiles);
120
89
  // Figure out which migrations have to be applied.
121
90
  const migrationsToExecute = getMigrationsToExecute(sortedMigrationFiles, allMigrations.rows);
122
91
  for (const { directory, filename, timestamp } of migrationsToExecute) {
123
92
  if (allMigrations.rows.length === 0) {
124
93
  // if we are running all the migrations then log at a lower level
125
- logger_1.logger.verbose(`Running migration ${filename}`);
94
+ logger.verbose(`Running migration ${filename}`);
126
95
  }
127
96
  else {
128
- logger_1.logger.info(`Running migration ${filename}`);
97
+ logger.info(`Running migration ${filename}`);
129
98
  }
130
- const migrationPath = path_1.default.join(directory, filename);
99
+ const migrationPath = path.join(directory, filename);
131
100
  if (filename.endsWith('.sql')) {
132
- const migrationSql = await fs_extra_1.default.readFile(migrationPath, 'utf8');
133
- const annotations = (0, load_migrations_1.parseAnnotations)(migrationSql);
101
+ const migrationSql = await fs.readFile(migrationPath, 'utf8');
102
+ const annotations = parseAnnotations(migrationSql);
134
103
  try {
135
104
  if (annotations.has('NO TRANSACTION')) {
136
105
  await sqldb.queryAsync(migrationSql, {});
@@ -147,7 +116,7 @@ async function initWithLock(directories, project) {
147
116
  }
148
117
  }
149
118
  else {
150
- const migrationModule = await Promise.resolve(`${migrationPath}`).then(s => __importStar(require(s)));
119
+ const migrationModule = await import(migrationPath);
151
120
  const implementation = migrationModule.default;
152
121
  if (typeof implementation !== 'function') {
153
122
  throw new Error(`Migration ${filename} does not export a default function`);
@@ -162,5 +131,4 @@ async function initWithLock(directories, project) {
162
131
  });
163
132
  }
164
133
  }
165
- exports.initWithLock = initWithLock;
166
134
  //# sourceMappingURL=migrations.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/migrations/migrations.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs-extra';\nimport path from 'path';\n\nimport * as namedLocks from '@prairielearn/named-locks';\nimport { logger } from '@prairielearn/logger';\nimport * as sqldb from '@prairielearn/postgres';\nimport * as error from '@prairielearn/error';\n\nimport {\n MigrationFile,\n parseAnnotations,\n readAndValidateMigrationsFromDirectories,\n sortMigrationFiles,\n} from '../load-migrations';\n\nconst sql = sqldb.loadSqlEquiv(__filename);\n\nexport async function init(directories: string | string[], project: string) {\n const migrationDirectories = Array.isArray(directories) ? directories : [directories];\n const lockName = 'migrations';\n logger.verbose(`Waiting for lock ${lockName}`);\n await namedLocks.doWithLock(\n lockName,\n {\n // Migrations *might* take a long time to run, so we'll enable automatic\n // lock renewal so that our lock doesn't get killed by the Postgres\n // idle session timeout.\n //\n // That said, we should generally try to keep migrations executing as\n // quickly as possible. A long-running migration likely means that\n // Postgres is locking a whole table, which is unacceptable in production.\n autoRenew: true,\n },\n async () => {\n logger.verbose(`Acquired lock ${lockName}`);\n await initWithLock(migrationDirectories, project);\n },\n );\n logger.verbose(`Released lock ${lockName}`);\n}\n\nexport function getMigrationsToExecute(\n migrationFiles: MigrationFile[],\n executedMigrations: { timestamp: string | null }[],\n): MigrationFile[] {\n // If no migrations have ever been run, run them all.\n if (executedMigrations.length === 0) {\n return migrationFiles;\n }\n\n const executedMigrationTimestamps = new Set(executedMigrations.map((m) => m.timestamp));\n return migrationFiles.filter((m) => !executedMigrationTimestamps.has(m.timestamp));\n}\n\nexport async function initWithLock(directories: string[], project: string) {\n logger.verbose('Starting DB schema migration');\n\n // Create the migrations table if needed\n await sqldb.queryAsync(sql.create_migrations_table, {});\n\n // Apply necessary changes to the migrations table as needed.\n try {\n await sqldb.queryAsync('SELECT project FROM migrations;', {});\n } catch (err: any) {\n if (err.routine === 'errorMissingColumn') {\n logger.info('Altering migrations table');\n await sqldb.queryAsync(sql.add_projects_column, {});\n } else {\n throw err;\n }\n }\n try {\n await sqldb.queryAsync('SELECT timestamp FROM migrations;', {});\n } catch (err: any) {\n if (err.routine === 'errorMissingColumn') {\n logger.info('Altering migrations table again');\n await sqldb.queryAsync(sql.add_timestamp_column, {});\n } else {\n throw err;\n }\n }\n\n let allMigrations = await sqldb.queryAsync(sql.get_migrations, { project });\n\n const migrationFiles = await readAndValidateMigrationsFromDirectories(directories, [\n '.sql',\n '.js',\n '.ts',\n '.mjs',\n ]);\n\n // Validation: if we not all previously-executed migrations have timestamps,\n // prompt the user to deploy an earlier version that includes both indexes\n // and timestamps.\n const migrationsMissingTimestamps = allMigrations.rows.filter((m) => !m.timestamp);\n if (migrationsMissingTimestamps.length > 0) {\n throw new Error(\n [\n 'The following migrations are missing timestamps:',\n migrationsMissingTimestamps.map((m) => ` ${m.filename}`),\n // This revision was the most recent commit to `master` before the\n // code handling indexes was removed.\n 'You must deploy revision 1aa43c7348fa24cf636413d720d06a2fa9e38ef2 first.',\n ].join('\\n'),\n );\n }\n\n // Refetch the list of migrations from the database.\n allMigrations = await sqldb.queryAsync(sql.get_migrations, { project });\n\n // Sort the migration files into execution order.\n const sortedMigrationFiles = sortMigrationFiles(migrationFiles);\n\n // Figure out which migrations have to be applied.\n const migrationsToExecute = getMigrationsToExecute(sortedMigrationFiles, allMigrations.rows);\n\n for (const { directory, filename, timestamp } of migrationsToExecute) {\n if (allMigrations.rows.length === 0) {\n // if we are running all the migrations then log at a lower level\n logger.verbose(`Running migration ${filename}`);\n } else {\n logger.info(`Running migration ${filename}`);\n }\n\n const migrationPath = path.join(directory, filename);\n if (filename.endsWith('.sql')) {\n const migrationSql = await fs.readFile(migrationPath, 'utf8');\n const annotations = parseAnnotations(migrationSql);\n try {\n if (annotations.has('NO TRANSACTION')) {\n await sqldb.queryAsync(migrationSql, {});\n } else {\n await sqldb.runInTransactionAsync(async () => {\n await sqldb.queryAsync(migrationSql, {});\n });\n }\n } catch (err) {\n error.addData(err, { sqlFile: filename });\n throw err;\n }\n } else {\n const migrationModule = await import(migrationPath);\n const implementation = migrationModule.default;\n if (typeof implementation !== 'function') {\n throw new Error(`Migration ${filename} does not export a default function`);\n }\n await implementation();\n }\n\n // Record the migration.\n await sqldb.queryAsync(sql.insert_migration, {\n filename,\n timestamp,\n project,\n });\n }\n}\n"]}
1
+ {"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/migrations/migrations.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'path';\n\nimport fs from 'fs-extra';\n\nimport * as error from '@prairielearn/error';\nimport { logger } from '@prairielearn/logger';\nimport * as namedLocks from '@prairielearn/named-locks';\nimport * as sqldb from '@prairielearn/postgres';\n\nimport {\n MigrationFile,\n parseAnnotations,\n readAndValidateMigrationsFromDirectories,\n sortMigrationFiles,\n} from '../load-migrations.js';\n\nconst sql = sqldb.loadSqlEquiv(import.meta.filename);\n\nexport async function init(directories: string | string[], project: string) {\n const migrationDirectories = Array.isArray(directories) ? directories : [directories];\n const lockName = 'migrations';\n logger.verbose(`Waiting for lock ${lockName}`);\n await namedLocks.doWithLock(\n lockName,\n {\n // Migrations *might* take a long time to run, so we'll enable automatic\n // lock renewal so that our lock doesn't get killed by the Postgres\n // idle session timeout.\n //\n // That said, we should generally try to keep migrations executing as\n // quickly as possible. A long-running migration likely means that\n // Postgres is locking a whole table, which is unacceptable in production.\n autoRenew: true,\n },\n async () => {\n logger.verbose(`Acquired lock ${lockName}`);\n await initWithLock(migrationDirectories, project);\n },\n );\n logger.verbose(`Released lock ${lockName}`);\n}\n\nexport function getMigrationsToExecute(\n migrationFiles: MigrationFile[],\n executedMigrations: { timestamp: string | null }[],\n): MigrationFile[] {\n // If no migrations have ever been run, run them all.\n if (executedMigrations.length === 0) {\n return migrationFiles;\n }\n\n const executedMigrationTimestamps = new Set(executedMigrations.map((m) => m.timestamp));\n return migrationFiles.filter((m) => !executedMigrationTimestamps.has(m.timestamp));\n}\n\nexport async function initWithLock(directories: string[], project: string) {\n logger.verbose('Starting DB schema migration');\n\n // Create the migrations table if needed\n await sqldb.queryAsync(sql.create_migrations_table, {});\n\n // Apply necessary changes to the migrations table as needed.\n try {\n await sqldb.queryAsync('SELECT project FROM migrations;', {});\n } catch (err: any) {\n if (err.routine === 'errorMissingColumn') {\n logger.info('Altering migrations table');\n await sqldb.queryAsync(sql.add_projects_column, {});\n } else {\n throw err;\n }\n }\n try {\n await sqldb.queryAsync('SELECT timestamp FROM migrations;', {});\n } catch (err: any) {\n if (err.routine === 'errorMissingColumn') {\n logger.info('Altering migrations table again');\n await sqldb.queryAsync(sql.add_timestamp_column, {});\n } else {\n throw err;\n }\n }\n\n let allMigrations = await sqldb.queryAsync(sql.get_migrations, { project });\n\n const migrationFiles = await readAndValidateMigrationsFromDirectories(directories, [\n '.sql',\n '.js',\n '.ts',\n '.mjs',\n ]);\n\n // Validation: if we not all previously-executed migrations have timestamps,\n // prompt the user to deploy an earlier version that includes both indexes\n // and timestamps.\n const migrationsMissingTimestamps = allMigrations.rows.filter((m) => !m.timestamp);\n if (migrationsMissingTimestamps.length > 0) {\n throw new Error(\n [\n 'The following migrations are missing timestamps:',\n migrationsMissingTimestamps.map((m) => ` ${m.filename}`),\n // This revision was the most recent commit to `master` before the\n // code handling indexes was removed.\n 'You must deploy revision 1aa43c7348fa24cf636413d720d06a2fa9e38ef2 first.',\n ].join('\\n'),\n );\n }\n\n // Refetch the list of migrations from the database.\n allMigrations = await sqldb.queryAsync(sql.get_migrations, { project });\n\n // Sort the migration files into execution order.\n const sortedMigrationFiles = sortMigrationFiles(migrationFiles);\n\n // Figure out which migrations have to be applied.\n const migrationsToExecute = getMigrationsToExecute(sortedMigrationFiles, allMigrations.rows);\n\n for (const { directory, filename, timestamp } of migrationsToExecute) {\n if (allMigrations.rows.length === 0) {\n // if we are running all the migrations then log at a lower level\n logger.verbose(`Running migration ${filename}`);\n } else {\n logger.info(`Running migration ${filename}`);\n }\n\n const migrationPath = path.join(directory, filename);\n if (filename.endsWith('.sql')) {\n const migrationSql = await fs.readFile(migrationPath, 'utf8');\n const annotations = parseAnnotations(migrationSql);\n try {\n if (annotations.has('NO TRANSACTION')) {\n await sqldb.queryAsync(migrationSql, {});\n } else {\n await sqldb.runInTransactionAsync(async () => {\n await sqldb.queryAsync(migrationSql, {});\n });\n }\n } catch (err) {\n error.addData(err, { sqlFile: filename });\n throw err;\n }\n } else {\n const migrationModule = await import(migrationPath);\n const implementation = migrationModule.default;\n if (typeof implementation !== 'function') {\n throw new Error(`Migration ${filename} does not export a default function`);\n }\n await implementation();\n }\n\n // Record the migration.\n await sqldb.queryAsync(sql.insert_migration, {\n filename,\n timestamp,\n project,\n });\n }\n}\n"]}
@@ -1,12 +1,7 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const chai_1 = require("chai");
7
- const node_path_1 = __importDefault(require("node:path"));
8
- const postgres_1 = require("@prairielearn/postgres");
9
- const migrations_1 = require("./migrations");
1
+ import path from 'node:path';
2
+ import { assert } from 'chai';
3
+ import { makePostgresTestUtils, queryAsync } from '@prairielearn/postgres';
4
+ import { getMigrationsToExecute, initWithLock } from './migrations.js';
10
5
  describe('migrations', () => {
11
6
  describe('getMigrationsToExecute', () => {
12
7
  it('handles the case of no executed migrations', () => {
@@ -17,7 +12,7 @@ describe('migrations', () => {
17
12
  timestamp: '20220101010101',
18
13
  },
19
14
  ];
20
- chai_1.assert.deepEqual((0, migrations_1.getMigrationsToExecute)(migrationFiles, []), migrationFiles);
15
+ assert.deepEqual(getMigrationsToExecute(migrationFiles, []), migrationFiles);
21
16
  });
22
17
  it('handles case where subset of migrations have been executed', () => {
23
18
  const migrationFiles = [
@@ -45,7 +40,7 @@ describe('migrations', () => {
45
40
  timestamp: '20220101010102',
46
41
  },
47
42
  ];
48
- chai_1.assert.deepEqual((0, migrations_1.getMigrationsToExecute)(migrationFiles, executedMigrations), [
43
+ assert.deepEqual(getMigrationsToExecute(migrationFiles, executedMigrations), [
49
44
  {
50
45
  directory: 'migrations',
51
46
  timestamp: '20220101010103',
@@ -55,7 +50,7 @@ describe('migrations', () => {
55
50
  });
56
51
  });
57
52
  describe('initWithLock', () => {
58
- const postgresTestUtils = (0, postgres_1.makePostgresTestUtils)({
53
+ const postgresTestUtils = makePostgresTestUtils({
59
54
  database: 'prairielearn_migrations',
60
55
  });
61
56
  before(async () => {
@@ -65,13 +60,13 @@ describe('migrations', () => {
65
60
  await postgresTestUtils.dropDatabase();
66
61
  });
67
62
  it('runs both SQL and JavaScript migrations', async () => {
68
- const migrationDir = node_path_1.default.join(__dirname, 'fixtures');
69
- await (0, migrations_1.initWithLock)([migrationDir], 'prairielearn_migrations');
63
+ const migrationDir = path.join(import.meta.dirname, 'fixtures');
64
+ await initWithLock([migrationDir], 'prairielearn_migrations');
70
65
  // If both migrations ran successfully, there should be a single user
71
66
  // in the database.
72
- const users = await (0, postgres_1.queryAsync)('SELECT * FROM users', {});
73
- chai_1.assert.lengthOf(users.rows, 1);
74
- chai_1.assert.equal(users.rows[0].name, 'Test User');
67
+ const users = await queryAsync('SELECT * FROM users', {});
68
+ assert.lengthOf(users.rows, 1);
69
+ assert.equal(users.rows[0].name, 'Test User');
75
70
  });
76
71
  });
77
72
  });
@@ -1 +1 @@
1
- {"version":3,"file":"migrations.test.js","sourceRoot":"","sources":["../../src/migrations/migrations.test.ts"],"names":[],"mappings":";;;;;AAAA,+BAA8B;AAC9B,0DAA6B;AAC7B,qDAA2E;AAE3E,6CAAoE;AAEpE,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACtC,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,MAAM,cAAc,GAAG;gBACrB;oBACE,SAAS,EAAE,YAAY;oBACvB,QAAQ,EAAE,iBAAiB;oBAC3B,SAAS,EAAE,gBAAgB;iBAC5B;aACF,CAAC;YACF,aAAM,CAAC,SAAS,CAAC,IAAA,mCAAsB,EAAC,cAAc,EAAE,EAAE,CAAC,EAAE,cAAc,CAAC,CAAC;QAC/E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;YACpE,MAAM,cAAc,GAAG;gBACrB;oBACE,SAAS,EAAE,YAAY;oBACvB,QAAQ,EAAE,8BAA8B;oBACxC,SAAS,EAAE,gBAAgB;iBAC5B;gBACD;oBACE,SAAS,EAAE,YAAY;oBACvB,QAAQ,EAAE,8BAA8B;oBACxC,SAAS,EAAE,gBAAgB;iBAC5B;gBACD;oBACE,SAAS,EAAE,YAAY;oBACvB,QAAQ,EAAE,8BAA8B;oBACxC,SAAS,EAAE,gBAAgB;iBAC5B;aACF,CAAC;YACF,MAAM,kBAAkB,GAAG;gBACzB;oBACE,SAAS,EAAE,gBAAgB;iBAC5B;gBACD;oBACE,SAAS,EAAE,gBAAgB;iBAC5B;aACF,CAAC;YACF,aAAM,CAAC,SAAS,CAAC,IAAA,mCAAsB,EAAC,cAAc,EAAE,kBAAkB,CAAC,EAAE;gBAC3E;oBACE,SAAS,EAAE,YAAY;oBACvB,SAAS,EAAE,gBAAgB;oBAC3B,QAAQ,EAAE,8BAA8B;iBACzC;aACF,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;QAC5B,MAAM,iBAAiB,GAAG,IAAA,gCAAqB,EAAC;YAC9C,QAAQ,EAAE,yBAAyB;SACpC,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,IAAI,EAAE;YAChB,MAAM,iBAAiB,CAAC,cAAc,EAAE,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,MAAM,iBAAiB,CAAC,YAAY,EAAE,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;YACvD,MAAM,YAAY,GAAG,mBAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;YACtD,MAAM,IAAA,yBAAY,EAAC,CAAC,YAAY,CAAC,EAAE,yBAAyB,CAAC,CAAC;YAE9D,qEAAqE;YACrE,mBAAmB;YACnB,MAAM,KAAK,GAAG,MAAM,IAAA,qBAAU,EAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;YAC1D,aAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YAC/B,aAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { assert } from 'chai';\nimport path from 'node:path';\nimport { makePostgresTestUtils, queryAsync } from '@prairielearn/postgres';\n\nimport { getMigrationsToExecute, initWithLock } from './migrations';\n\ndescribe('migrations', () => {\n describe('getMigrationsToExecute', () => {\n it('handles the case of no executed migrations', () => {\n const migrationFiles = [\n {\n directory: 'migrations',\n filename: '001_testing.sql',\n timestamp: '20220101010101',\n },\n ];\n assert.deepEqual(getMigrationsToExecute(migrationFiles, []), migrationFiles);\n });\n\n it('handles case where subset of migrations have been executed', () => {\n const migrationFiles = [\n {\n directory: 'migrations',\n filename: '20220101010101_testing_1.sql',\n timestamp: '20220101010101',\n },\n {\n directory: 'migrations',\n filename: '20220101010102_testing_2.sql',\n timestamp: '20220101010102',\n },\n {\n directory: 'migrations',\n filename: '20220101010103_testing_3.sql',\n timestamp: '20220101010103',\n },\n ];\n const executedMigrations = [\n {\n timestamp: '20220101010101',\n },\n {\n timestamp: '20220101010102',\n },\n ];\n assert.deepEqual(getMigrationsToExecute(migrationFiles, executedMigrations), [\n {\n directory: 'migrations',\n timestamp: '20220101010103',\n filename: '20220101010103_testing_3.sql',\n },\n ]);\n });\n });\n\n describe('initWithLock', () => {\n const postgresTestUtils = makePostgresTestUtils({\n database: 'prairielearn_migrations',\n });\n\n before(async () => {\n await postgresTestUtils.createDatabase();\n });\n\n after(async () => {\n await postgresTestUtils.dropDatabase();\n });\n\n it('runs both SQL and JavaScript migrations', async () => {\n const migrationDir = path.join(__dirname, 'fixtures');\n await initWithLock([migrationDir], 'prairielearn_migrations');\n\n // If both migrations ran successfully, there should be a single user\n // in the database.\n const users = await queryAsync('SELECT * FROM users', {});\n assert.lengthOf(users.rows, 1);\n assert.equal(users.rows[0].name, 'Test User');\n });\n });\n});\n"]}
1
+ {"version":3,"file":"migrations.test.js","sourceRoot":"","sources":["../../src/migrations/migrations.test.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAE9B,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAE3E,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEvE,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACtC,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,MAAM,cAAc,GAAG;gBACrB;oBACE,SAAS,EAAE,YAAY;oBACvB,QAAQ,EAAE,iBAAiB;oBAC3B,SAAS,EAAE,gBAAgB;iBAC5B;aACF,CAAC;YACF,MAAM,CAAC,SAAS,CAAC,sBAAsB,CAAC,cAAc,EAAE,EAAE,CAAC,EAAE,cAAc,CAAC,CAAC;QAC/E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;YACpE,MAAM,cAAc,GAAG;gBACrB;oBACE,SAAS,EAAE,YAAY;oBACvB,QAAQ,EAAE,8BAA8B;oBACxC,SAAS,EAAE,gBAAgB;iBAC5B;gBACD;oBACE,SAAS,EAAE,YAAY;oBACvB,QAAQ,EAAE,8BAA8B;oBACxC,SAAS,EAAE,gBAAgB;iBAC5B;gBACD;oBACE,SAAS,EAAE,YAAY;oBACvB,QAAQ,EAAE,8BAA8B;oBACxC,SAAS,EAAE,gBAAgB;iBAC5B;aACF,CAAC;YACF,MAAM,kBAAkB,GAAG;gBACzB;oBACE,SAAS,EAAE,gBAAgB;iBAC5B;gBACD;oBACE,SAAS,EAAE,gBAAgB;iBAC5B;aACF,CAAC;YACF,MAAM,CAAC,SAAS,CAAC,sBAAsB,CAAC,cAAc,EAAE,kBAAkB,CAAC,EAAE;gBAC3E;oBACE,SAAS,EAAE,YAAY;oBACvB,SAAS,EAAE,gBAAgB;oBAC3B,QAAQ,EAAE,8BAA8B;iBACzC;aACF,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;QAC5B,MAAM,iBAAiB,GAAG,qBAAqB,CAAC;YAC9C,QAAQ,EAAE,yBAAyB;SACpC,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,IAAI,EAAE;YAChB,MAAM,iBAAiB,CAAC,cAAc,EAAE,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,MAAM,iBAAiB,CAAC,YAAY,EAAE,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;YACvD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;YAChE,MAAM,YAAY,CAAC,CAAC,YAAY,CAAC,EAAE,yBAAyB,CAAC,CAAC;YAE9D,qEAAqE;YACrE,mBAAmB;YACnB,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;YAC1D,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YAC/B,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import path from 'node:path';\n\nimport { assert } from 'chai';\n\nimport { makePostgresTestUtils, queryAsync } from '@prairielearn/postgres';\n\nimport { getMigrationsToExecute, initWithLock } from './migrations.js';\n\ndescribe('migrations', () => {\n describe('getMigrationsToExecute', () => {\n it('handles the case of no executed migrations', () => {\n const migrationFiles = [\n {\n directory: 'migrations',\n filename: '001_testing.sql',\n timestamp: '20220101010101',\n },\n ];\n assert.deepEqual(getMigrationsToExecute(migrationFiles, []), migrationFiles);\n });\n\n it('handles case where subset of migrations have been executed', () => {\n const migrationFiles = [\n {\n directory: 'migrations',\n filename: '20220101010101_testing_1.sql',\n timestamp: '20220101010101',\n },\n {\n directory: 'migrations',\n filename: '20220101010102_testing_2.sql',\n timestamp: '20220101010102',\n },\n {\n directory: 'migrations',\n filename: '20220101010103_testing_3.sql',\n timestamp: '20220101010103',\n },\n ];\n const executedMigrations = [\n {\n timestamp: '20220101010101',\n },\n {\n timestamp: '20220101010102',\n },\n ];\n assert.deepEqual(getMigrationsToExecute(migrationFiles, executedMigrations), [\n {\n directory: 'migrations',\n timestamp: '20220101010103',\n filename: '20220101010103_testing_3.sql',\n },\n ]);\n });\n });\n\n describe('initWithLock', () => {\n const postgresTestUtils = makePostgresTestUtils({\n database: 'prairielearn_migrations',\n });\n\n before(async () => {\n await postgresTestUtils.createDatabase();\n });\n\n after(async () => {\n await postgresTestUtils.dropDatabase();\n });\n\n it('runs both SQL and JavaScript migrations', async () => {\n const migrationDir = path.join(import.meta.dirname, 'fixtures');\n await initWithLock([migrationDir], 'prairielearn_migrations');\n\n // If both migrations ran successfully, there should be a single user\n // in the database.\n const users = await queryAsync('SELECT * FROM users', {});\n assert.lengthOf(users.rows, 1);\n assert.equal(users.rows[0].name, 'Test User');\n });\n });\n});\n"]}
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@prairielearn/migrations",
3
- "version": "2.1.0",
3
+ "version": "3.0.1",
4
+ "type": "module",
4
5
  "main": "./dist/index.js",
5
6
  "repository": {
6
7
  "type": "git",
@@ -10,28 +11,28 @@
10
11
  "scripts": {
11
12
  "build": "tsc && tscp",
12
13
  "dev": "tsc --watch --preserveWatchOutput & tscp --watch",
13
- "test": "mocha --no-config --require tsx src/**/*.test.ts"
14
+ "test": "mocha src/**/*.test.ts"
14
15
  },
15
16
  "devDependencies": {
16
17
  "@prairielearn/tsconfig": "^0.0.0",
17
18
  "@types/fs-extra": "^11.0.4",
18
19
  "@types/mocha": "^10.0.6",
19
- "@types/node": "^20.12.2",
20
- "chai": "^4.4.1",
21
- "chai-as-promised": "^7.1.1",
20
+ "@types/node": "^20.12.11",
21
+ "chai": "^5.1.1",
22
+ "chai-as-promised": "^7.1.2",
22
23
  "mocha": "^10.4.0",
23
24
  "tmp-promise": "^3.0.3",
24
- "tsx": "^4.7.2",
25
- "typescript": "^5.4.3",
25
+ "tsx": "^4.10.2",
26
+ "typescript": "^5.4.5",
26
27
  "typescript-cp": "^0.1.9"
27
28
  },
28
29
  "dependencies": {
29
- "@prairielearn/error": "^1.2.0",
30
- "@prairielearn/logger": "^1.0.15",
31
- "@prairielearn/named-locks": "^2.0.3",
32
- "@prairielearn/postgres": "^1.9.4",
30
+ "@prairielearn/error": "^2.0.1",
31
+ "@prairielearn/logger": "^2.0.1",
32
+ "@prairielearn/named-locks": "^3.0.1",
33
+ "@prairielearn/postgres": "^2.0.1",
33
34
  "fs-extra": "^11.2.0",
34
- "serialize-error": "^8.1.0",
35
- "zod": "^3.22.4"
35
+ "serialize-error": "^11.0.3",
36
+ "zod": "^3.23.8"
36
37
  }
37
38
  }
@@ -1,7 +1,8 @@
1
1
  import { z } from 'zod';
2
+
2
3
  import { loadSqlEquiv, queryRows } from '@prairielearn/postgres';
3
4
 
4
- const sql = loadSqlEquiv(__filename);
5
+ const sql = loadSqlEquiv(import.meta.filename);
5
6
 
6
7
  export const BatchedMigrationJobStatusSchema = z.enum(['pending', 'failed', 'succeeded']);
7
8
  export type BatchedMigrationJobStatus = z.infer<typeof BatchedMigrationJobStatusSchema>;
@@ -1,17 +1,19 @@
1
1
  import { assert } from 'chai';
2
- import { makePostgresTestUtils, queryAsync, queryRow, queryRows } from '@prairielearn/postgres';
3
- import * as namedLocks from '@prairielearn/named-locks';
2
+
4
3
  import * as error from '@prairielearn/error';
4
+ import * as namedLocks from '@prairielearn/named-locks';
5
+ import { makePostgresTestUtils, queryAsync, queryRow, queryRows } from '@prairielearn/postgres';
6
+
7
+ import { SCHEMA_MIGRATIONS_PATH, init } from '../index.js';
5
8
 
9
+ import { BatchedMigrationJobRowSchema } from './batched-migration-job.js';
10
+ import { BatchedMigrationRunner } from './batched-migration-runner.js';
6
11
  import {
7
12
  BatchedMigrationRowSchema,
8
13
  insertBatchedMigration,
9
14
  makeBatchedMigration,
10
15
  updateBatchedMigrationStatus,
11
- } from './batched-migration';
12
- import { BatchedMigrationJobRowSchema } from './batched-migration-job';
13
- import { BatchedMigrationRunner } from './batched-migration-runner';
14
- import { SCHEMA_MIGRATIONS_PATH, init } from '../index';
16
+ } from './batched-migration.js';
15
17
 
16
18
  const postgresTestUtils = makePostgresTestUtils({
17
19
  database: 'prairielearn_migrations',
@@ -1,22 +1,23 @@
1
- import { loadSqlEquiv, queryAsync, queryRow, queryOptionalRow } from '@prairielearn/postgres';
2
- import { logger } from '@prairielearn/logger';
3
1
  import { serializeError } from 'serialize-error';
4
2
  import { z } from 'zod';
5
3
 
4
+ import { logger } from '@prairielearn/logger';
5
+ import { loadSqlEquiv, queryAsync, queryRow, queryOptionalRow } from '@prairielearn/postgres';
6
+
7
+ import {
8
+ BatchedMigrationJobRowSchema,
9
+ BatchedMigrationJobStatus,
10
+ BatchedMigrationJobRow,
11
+ } from './batched-migration-job.js';
6
12
  import {
7
13
  BatchedMigrationStatus,
8
14
  BatchedMigrationRow,
9
15
  updateBatchedMigrationStatus,
10
16
  BatchedMigrationStatusSchema,
11
17
  BatchedMigrationImplementation,
12
- } from './batched-migration';
13
- import {
14
- BatchedMigrationJobRowSchema,
15
- BatchedMigrationJobStatus,
16
- BatchedMigrationJobRow,
17
- } from './batched-migration-job';
18
+ } from './batched-migration.js';
18
19
 
19
- const sql = loadSqlEquiv(__filename);
20
+ const sql = loadSqlEquiv(import.meta.filename);
20
21
 
21
22
  interface BatchedMigrationRunnerOptions {
22
23
  logProgress?: boolean;
@@ -1,3 +1,5 @@
1
+ import { z } from 'zod';
2
+
1
3
  import {
2
4
  loadSqlEquiv,
3
5
  queryAsync,
@@ -5,9 +7,8 @@ import {
5
7
  queryRows,
6
8
  queryOptionalRow,
7
9
  } from '@prairielearn/postgres';
8
- import { z } from 'zod';
9
10
 
10
- const sql = loadSqlEquiv(__filename);
11
+ const sql = loadSqlEquiv(import.meta.filename);
11
12
 
12
13
  export const BatchedMigrationStatusSchema = z.enum([
13
14
  'pending',
@@ -1,14 +1,17 @@
1
- import chai, { assert } from 'chai';
2
- import chaiAsPromised from 'chai-as-promised';
3
1
  import path from 'node:path';
4
- import { makePostgresTestUtils } from '@prairielearn/postgres';
2
+
3
+ import { use as chaiUse, assert } from 'chai';
4
+ import chaiAsPromised from 'chai-as-promised';
5
+
5
6
  import * as namedLocks from '@prairielearn/named-locks';
7
+ import { makePostgresTestUtils } from '@prairielearn/postgres';
8
+
9
+ import { SCHEMA_MIGRATIONS_PATH, init } from '../index.js';
6
10
 
7
- import { SCHEMA_MIGRATIONS_PATH, init } from '../index';
8
- import { BatchedMigrationsRunner } from './batched-migrations-runner';
9
- import { selectAllBatchedMigrations } from './batched-migration';
11
+ import { selectAllBatchedMigrations } from './batched-migration.js';
12
+ import { BatchedMigrationsRunner } from './batched-migrations-runner.js';
10
13
 
11
- chai.use(chaiAsPromised);
14
+ chaiUse(chaiAsPromised);
12
15
 
13
16
  const postgresTestUtils = makePostgresTestUtils({
14
17
  database: 'prairielearn_migrations',
@@ -35,7 +38,7 @@ describe('BatchedMigrationsRunner', () => {
35
38
  it('enqueues migrations', async () => {
36
39
  const runner = new BatchedMigrationsRunner({
37
40
  project: 'test',
38
- directories: [path.join(__dirname, 'fixtures')],
41
+ directories: [path.join(import.meta.dirname, 'fixtures')],
39
42
  });
40
43
 
41
44
  await runner.enqueueBatchedMigration('20230406184103_successful_migration');
@@ -49,7 +52,7 @@ describe('BatchedMigrationsRunner', () => {
49
52
  assert.equal(migrations[0].filename, '20230406184103_successful_migration.ts');
50
53
  assert.equal(migrations[0].status, 'pending');
51
54
  assert.equal(migrations[1].timestamp, '20230406184107');
52
- assert.equal(migrations[1].filename, '20230406184107_failing_migration.js');
55
+ assert.equal(migrations[1].filename, '20230406184107_failing_migration.ts');
53
56
  assert.equal(migrations[1].status, 'pending');
54
57
  assert.equal(migrations[2].timestamp, '20230407230446');
55
58
  assert.equal(migrations[2].filename, '20230407230446_no_rows_migration.ts');
@@ -59,7 +62,7 @@ describe('BatchedMigrationsRunner', () => {
59
62
  it('safely enqueues migrations multiple times', async () => {
60
63
  const runner = new BatchedMigrationsRunner({
61
64
  project: 'test',
62
- directories: [path.join(__dirname, 'fixtures')],
65
+ directories: [path.join(import.meta.dirname, 'fixtures')],
63
66
  });
64
67
 
65
68
  await runner.enqueueBatchedMigration('20230406184103_successful_migration');
@@ -74,7 +77,7 @@ describe('BatchedMigrationsRunner', () => {
74
77
  it('finalizes a successful migration', async () => {
75
78
  const runner = new BatchedMigrationsRunner({
76
79
  project: 'test',
77
- directories: [path.join(__dirname, 'fixtures')],
80
+ directories: [path.join(import.meta.dirname, 'fixtures')],
78
81
  });
79
82
 
80
83
  await runner.enqueueBatchedMigration('20230406184103_successful_migration');
@@ -91,7 +94,7 @@ describe('BatchedMigrationsRunner', () => {
91
94
  it('finalizes a failing migration', async () => {
92
95
  const runner = new BatchedMigrationsRunner({
93
96
  project: 'test',
94
- directories: [path.join(__dirname, 'fixtures')],
97
+ directories: [path.join(import.meta.dirname, 'fixtures')],
95
98
  });
96
99
 
97
100
  await runner.enqueueBatchedMigration('20230406184107_failing_migration');
@@ -1,10 +1,13 @@
1
1
  import { EventEmitter } from 'node:events';
2
2
  import path from 'node:path';
3
3
  import { setTimeout as sleep } from 'node:timers/promises';
4
- import { loadSqlEquiv, queryOptionalRow } from '@prairielearn/postgres';
4
+
5
5
  import { doWithLock } from '@prairielearn/named-locks';
6
+ import { loadSqlEquiv, queryOptionalRow } from '@prairielearn/postgres';
7
+
8
+ import { MigrationFile, readAndValidateMigrationsFromDirectories } from '../load-migrations.js';
6
9
 
7
- import { MigrationFile, readAndValidateMigrationsFromDirectories } from '../load-migrations';
10
+ import { BatchedMigrationRunner } from './batched-migration-runner.js';
8
11
  import {
9
12
  BatchedMigrationRowSchema,
10
13
  BatchedMigrationRow,
@@ -14,10 +17,9 @@ import {
14
17
  updateBatchedMigrationStatus,
15
18
  BatchedMigrationImplementation,
16
19
  validateBatchedMigrationImplementation,
17
- } from './batched-migration';
18
- import { BatchedMigrationRunner } from './batched-migration-runner';
20
+ } from './batched-migration.js';
19
21
 
20
- const sql = loadSqlEquiv(__filename);
22
+ const sql = loadSqlEquiv(import.meta.filename);
21
23
 
22
24
  const DEFAULT_MIN_VALUE = 1n;
23
25
  const DEFAULT_BATCH_SIZE = 1_000;
@@ -1,4 +1,4 @@
1
- import { makeBatchedMigration } from '../batched-migration';
1
+ import { makeBatchedMigration } from '../batched-migration.js';
2
2
 
3
3
  export default makeBatchedMigration({
4
4
  async getParameters() {
@@ -1,7 +1,6 @@
1
- // @ts-check
2
- const { makeBatchedMigration } = require('../batched-migration');
1
+ import { makeBatchedMigration } from '../batched-migration.js';
3
2
 
4
- module.exports = makeBatchedMigration({
3
+ export default makeBatchedMigration({
5
4
  async getParameters() {
6
5
  return {
7
6
  min: 2n,
@@ -1,4 +1,4 @@
1
- import { makeBatchedMigration } from '../batched-migration';
1
+ import { makeBatchedMigration } from '../batched-migration.js';
2
2
 
3
3
  export default makeBatchedMigration({
4
4
  async getParameters() {
@@ -1,21 +1,21 @@
1
1
  export {
2
- BatchedMigrationRow,
3
- BatchedMigrationStatus,
2
+ type BatchedMigrationRow,
3
+ type BatchedMigrationStatus,
4
4
  makeBatchedMigration,
5
5
  selectAllBatchedMigrations,
6
6
  selectBatchedMigration,
7
7
  selectBatchedMigrationForTimestamp,
8
8
  retryFailedBatchedMigrationJobs,
9
- } from './batched-migration';
9
+ } from './batched-migration.js';
10
10
  export {
11
- BatchedMigrationJobRow,
12
- BatchedMigrationJobStatus,
11
+ type BatchedMigrationJobRow,
12
+ type BatchedMigrationJobStatus,
13
13
  selectRecentJobsWithStatus,
14
- } from './batched-migration-job';
14
+ } from './batched-migration-job.js';
15
15
  export {
16
16
  initBatchedMigrations,
17
17
  startBatchedMigrations,
18
18
  stopBatchedMigrations,
19
19
  enqueueBatchedMigration,
20
20
  finalizeBatchedMigration,
21
- } from './batched-migrations-runner';
21
+ } from './batched-migrations-runner.js';
package/src/index.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import path from 'path';
2
2
 
3
- export { init } from './migrations';
3
+ export { init } from './migrations/index.js';
4
4
 
5
5
  export {
6
- BatchedMigrationRow,
7
- BatchedMigrationStatus,
8
- BatchedMigrationJobRow,
9
- BatchedMigrationJobStatus,
6
+ type BatchedMigrationRow,
7
+ type BatchedMigrationStatus,
8
+ type BatchedMigrationJobRow,
9
+ type BatchedMigrationJobStatus,
10
10
  makeBatchedMigration,
11
11
  initBatchedMigrations,
12
12
  startBatchedMigrations,
@@ -18,6 +18,6 @@ export {
18
18
  selectBatchedMigrationForTimestamp,
19
19
  selectRecentJobsWithStatus,
20
20
  retryFailedBatchedMigrationJobs,
21
- } from './batched-migrations';
21
+ } from './batched-migrations/index.js';
22
22
 
23
- export const SCHEMA_MIGRATIONS_PATH = path.resolve(__dirname, '..', 'schema-migrations');
23
+ export const SCHEMA_MIGRATIONS_PATH = path.resolve(import.meta.dirname, '..', 'schema-migrations');
@@ -1,16 +1,17 @@
1
- import chai, { assert } from 'chai';
2
- import chaiAsPromised from 'chai-as-promised';
3
1
  import path from 'path';
4
- import tmp from 'tmp-promise';
2
+
3
+ import { use as chaiUse, assert } from 'chai';
4
+ import chaiAsPromised from 'chai-as-promised';
5
5
  import fs from 'fs-extra';
6
+ import tmp from 'tmp-promise';
6
7
 
7
8
  import {
8
9
  parseAnnotations,
9
10
  readAndValidateMigrationsFromDirectory,
10
11
  sortMigrationFiles,
11
- } from './load-migrations';
12
+ } from './load-migrations.js';
12
13
 
13
- chai.use(chaiAsPromised);
14
+ chaiUse(chaiAsPromised);
14
15
 
15
16
  async function withMigrationFiles(files: string[], fn: (tmpDir: string) => Promise<void>) {
16
17
  await tmp.withDir(
@@ -1 +1 @@
1
- export { init } from './migrations';
1
+ export { init } from './migrations.js';