@roostorg/db-migrator 1.0.7 → 1.0.8

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/README.md CHANGED
@@ -1,52 +1,20 @@
1
- ## Concepts/Terminology
2
-
3
- The CLI classifies scripts as "seeds" or a "migrations". The
4
- fundamental difference is that a migration runs across every environment --
5
- including production -- whereas a seed only runs in one environment. Therefore,
6
- schema changes should always be migrations. "Reference data" that are the same
7
- in every environment -- essentially, application constants that just happen to
8
- be stored in the database -- are also appropriate to add as migrations. But
9
- fixtures data for tests or other specific use cases is a seed.
10
-
11
- Critically, seed files are timestamped just like migrations, and they're run
12
- interspersed with the migrations. This approach is unconventional -- the normal
13
- approach is to have seed scripts run after all migrations have been applied --
14
- but it makes sense _given that we're writing the seeds as SQL or JS scripts that
15
- don't have access to our Sequelize model's db mappings_.
16
-
17
- Under the conventional approach, the seed scripts must be written against the
18
- latest schema (since they run after all migrations). This isn't a problem when
19
- the seed scripts are written using entity classes that the main application also
20
- uses to talk to the database, because the ORM mapping for those classes will
21
- also have updated when the migration is deployed. I.e., if we wrote our seed
22
- scripts in typescript using our sequelize models classes, then updating the
23
- model definitions to keep our classes working for our app would also keep our
24
- seed scripts working, and we might even get type errors (from Typescript) if,
25
- e.g., we removed a field from the model class that a seed script depended on.
26
-
27
- However, when seed scripts don't go though the Sequelize model classes, and
28
- instead include direct references to SQL column names etc (as ours do), then
29
- using the conventional approach of running seeds at the end means that making a
30
- schema change in a new migration can break the existing seed scripts. This is
31
- bad. It creates extra work that must be done after each new migration to keep
32
- the seed scripts working with the latest schema. More importantly, though, we
33
- might not catch for quite a while that a migration has broken one of our seed
34
- scripts, since we'd get no compile errors and since, even on deploy, only the
35
- seed scripts for the environment being deployed get run. E.g., it'd be a pain to
36
- find out three weeks after writing a migration, when we go to re-deploy demo,
37
- that we'd actually broken its seed script; then we'd have to go back, remember
38
- what we changed, and fix it.
39
-
40
- For now, we don't want to introduce the complexity of exporting/depending on our
41
- Sequelize model classes in our seed scripts, so it makes sense to ditch the
42
- conventional approach of running seeds all at the end.
43
-
44
- By instead interspersing the running of the seed scripts w/ the migrations'
45
- schema changes, each script knows exactly what the schema will look like at the
46
- time it runs, and can't be broken by future schema changes.
47
-
48
- That said, long term, it would be nice to write the seed scripts using Sequelize
49
- models and run them at the end, because that would allow us to have fewer,
50
- more-intentionally-divided seed scripts, which makes it a bit easier to see
51
- exactly what seed data we're setting up (without actually checking the db). It
52
- would also be more performant.
1
+ # Database Migrator
2
+
3
+ This package handles database schema migrations and seed data.
4
+
5
+ ## Concepts
6
+
7
+ ### Migrations vs Seeds
8
+
9
+ | Type | Purpose | When it runs |
10
+ | :---- | :---- | :---- |
11
+ | **Migration** | Schema changes (tables, columns, indexes) | All environments |
12
+ | **Seed** | Test fixtures and environment-specific data | Single environment only |
13
+
14
+ ### How Seeds Work
15
+
16
+ Seeds are timestamped and run interspersed with migrations (not after). This ensures each seed script runs against the exact schema it was written for, preventing breakage from future schema changes.
17
+
18
+ ## Usage
19
+
20
+ See `.devops/migrator/README.md` for CLI commands and setup instructions.
@@ -1,11 +1,18 @@
1
1
  import path from 'path';
2
- import { promisify } from 'util';
3
- import glob from 'glob';
2
+ import { glob } from 'node:fs/promises';
4
3
  import '@total-typescript/ts-reset/array-includes';
5
4
  import { Umzug } from 'umzug';
6
5
  import yargs from 'yargs';
7
6
  import { nameScript, scriptTypes, shouldRun } from './script-generator.js';
8
- const globAsync = promisify(glob);
7
+ async function globMigrationFiles(scriptsDirectory, supportedExtensions) {
8
+ const matchingFilePaths = [];
9
+ for await (const p of glob(`*.${supportedExtensions}`, {
10
+ cwd: scriptsDirectory,
11
+ })) {
12
+ matchingFilePaths.push(path.resolve(scriptsDirectory, p));
13
+ }
14
+ return matchingFilePaths;
15
+ }
9
16
  export function makeCli(dbs) {
10
17
  const dbNames = Object.keys(dbs);
11
18
  const dbOpt = {
@@ -154,7 +161,7 @@ export function makeCli(dbs) {
154
161
  const supportedExtensions = supportedScriptFormats.length > 1
155
162
  ? `{${supportedScriptFormats.join(',')}}`
156
163
  : `${supportedScriptFormats[0]}`;
157
- const matchingFilePaths = await globAsync(`${scriptsDirectory}/*.${supportedExtensions}`, { absolute: true });
164
+ const matchingFilePaths = await globMigrationFiles(scriptsDirectory, supportedExtensions);
158
165
  return matchingFilePaths
159
166
  .filter(shouldRun.bind(null, env, supportedScriptFormats))
160
167
  .map((unresolvedPath) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@roostorg/db-migrator",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "CLI tool for managing database migrations and seeding. Designed for modern scalable systems.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -15,20 +15,19 @@
15
15
  "files": [
16
16
  "build"
17
17
  ],
18
- "author": "",
18
+ "author": "Roostorg",
19
19
  "license": "ISC",
20
20
  "dependencies": {
21
21
  "@total-typescript/ts-reset": "^0.5.1",
22
- "@types/glob": "^7.2.0",
23
22
  "@types/umzug": "^2.3.3",
24
23
  "@types/yargs": "^17.0.24",
25
- "cassandra-driver": "^4.6.4",
26
- "glob": "^7.2.0",
24
+ "cassandra-driver": "^4.8.0",
27
25
  "sequelize": "^6.32.1",
28
26
  "umzug": "^3.0.0",
29
27
  "yargs": "^16.2.0"
30
28
  },
31
29
  "devDependencies": {
30
+ "@types/node": "^24.0.0",
32
31
  "typescript": "^5.2.2"
33
32
  },
34
33
  "publishConfig": {