@sebspark/spanner-migrate 0.1.1 → 0.2.0
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 +20 -0
- package/dist/{chunk-K5WX6ESL.mjs → chunk-Z3ZLNDVO.mjs} +33 -25
- package/dist/cli.js +33 -25
- package/dist/cli.mjs +2 -2
- package/dist/index.js +32 -24
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -48,6 +48,26 @@ Create a new migration file.
|
|
|
48
48
|
|
|
49
49
|
```zsh
|
|
50
50
|
spanner-migrate create add users table
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Result:**
|
|
54
|
+
|
|
55
|
+
Example:
|
|
56
|
+
|
|
57
|
+
`./migrations/20250120145638000_create_table_users.sql`
|
|
58
|
+
|
|
59
|
+
```sql
|
|
60
|
+
-- Created: 2025-01-20T14:56:38.000Z
|
|
61
|
+
-- Description: create table users
|
|
62
|
+
|
|
63
|
+
---- UP ----
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
---- DOWN ----
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
51
71
|
```
|
|
52
72
|
|
|
53
73
|
#### `up`
|
|
@@ -70,12 +70,11 @@ var runScript = async (db, script) => {
|
|
|
70
70
|
}
|
|
71
71
|
for (const statement of statements) {
|
|
72
72
|
console.log(`Executing statement: ${statement}`);
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
await db.updateSchema(sql);
|
|
73
|
+
if (isSchemaChange(statement)) {
|
|
74
|
+
await db.updateSchema(statement);
|
|
76
75
|
} else {
|
|
77
76
|
await db.runTransactionAsync(async (transaction) => {
|
|
78
|
-
await transaction.runUpdate(
|
|
77
|
+
await transaction.runUpdate(statement);
|
|
79
78
|
await transaction.commit();
|
|
80
79
|
});
|
|
81
80
|
}
|
|
@@ -132,12 +131,12 @@ var getAppliedMigrations = async (db) => {
|
|
|
132
131
|
};
|
|
133
132
|
|
|
134
133
|
// src/files.ts
|
|
135
|
-
import { access, mkdir, readdir, writeFile } from "node:fs/promises";
|
|
134
|
+
import { access, mkdir, readFile, readdir, writeFile } from "node:fs/promises";
|
|
136
135
|
import { join, resolve } from "node:path";
|
|
137
136
|
var getMigrationFiles = async (path) => {
|
|
138
137
|
try {
|
|
139
138
|
const files = await readdir(path);
|
|
140
|
-
const migrationFileIds = files.filter((file) => file.endsWith(".
|
|
139
|
+
const migrationFileIds = files.filter((file) => file.endsWith(".sql")).map((file) => file.replace(/\.sql$/, ""));
|
|
141
140
|
return migrationFileIds;
|
|
142
141
|
} catch (error) {
|
|
143
142
|
throw new Error(
|
|
@@ -147,31 +146,40 @@ var getMigrationFiles = async (path) => {
|
|
|
147
146
|
};
|
|
148
147
|
var getMigration = async (path, id) => {
|
|
149
148
|
try {
|
|
150
|
-
const filePath = resolve(process.cwd(), join(path, `${id}.
|
|
149
|
+
const filePath = resolve(process.cwd(), join(path, `${id}.sql`));
|
|
151
150
|
try {
|
|
152
151
|
await access(filePath);
|
|
153
152
|
} catch (err) {
|
|
154
153
|
throw new Error(`Migration file not found: ${filePath}`);
|
|
155
154
|
}
|
|
156
|
-
const
|
|
157
|
-
|
|
155
|
+
const migrationText = await readFile(filePath, "utf8");
|
|
156
|
+
const up2 = getSql(migrationText, "up");
|
|
157
|
+
const down2 = getSql(migrationText, "down");
|
|
158
|
+
const description = getDescription(migrationText);
|
|
159
|
+
if (!up2 || !down2) {
|
|
158
160
|
throw new Error(
|
|
159
161
|
`Migration file ${filePath} does not export required scripts (up, down).`
|
|
160
162
|
);
|
|
161
163
|
}
|
|
162
|
-
return {
|
|
163
|
-
id,
|
|
164
|
-
description: id.split("_").slice(1).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" "),
|
|
165
|
-
// Generate a human-readable description
|
|
166
|
-
up: migrationModule.up,
|
|
167
|
-
down: migrationModule.down
|
|
168
|
-
};
|
|
164
|
+
return { id, description, up: up2, down: down2 };
|
|
169
165
|
} catch (error) {
|
|
170
166
|
throw new Error(
|
|
171
167
|
`Failed to get migration ${id}: ${error.message}`
|
|
172
168
|
);
|
|
173
169
|
}
|
|
174
170
|
};
|
|
171
|
+
var getDescription = (text) => {
|
|
172
|
+
var _a, _b;
|
|
173
|
+
return ((_b = (_a = text == null ? void 0 : text.match(/^--\s*Description:\s*(.+)$/m)) == null ? void 0 : _a[1]) == null ? void 0 : _b.trim()) || "";
|
|
174
|
+
};
|
|
175
|
+
var getSql = (text, direction) => {
|
|
176
|
+
var _a, _b;
|
|
177
|
+
const rx = {
|
|
178
|
+
up: /---- UP ----\n([\s\S]*?)\n---- DOWN ----/,
|
|
179
|
+
down: /---- DOWN ----\n([\s\S]*)$/
|
|
180
|
+
};
|
|
181
|
+
return (_b = (_a = text == null ? void 0 : text.match(rx[direction])) == null ? void 0 : _a[1]) == null ? void 0 : _b.replace(/--.*$/gm, "").trim();
|
|
182
|
+
};
|
|
175
183
|
var getNewMigrations = (applied, files) => {
|
|
176
184
|
const sortedFiles = files.sort();
|
|
177
185
|
for (let ix = 0; ix < applied.length; ix++) {
|
|
@@ -190,18 +198,18 @@ var createMigration = async (path, description) => {
|
|
|
190
198
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
191
199
|
const compactTimestamp = timestamp.replace(/[-:.TZ]/g, "");
|
|
192
200
|
const parsedDescription = description.replace(/\s+/g, "_").toLowerCase();
|
|
193
|
-
const filename = `${compactTimestamp}_${parsedDescription}.
|
|
201
|
+
const filename = `${compactTimestamp}_${parsedDescription}.sql`;
|
|
194
202
|
const filePath = join(path, filename);
|
|
195
|
-
const template =
|
|
196
|
-
|
|
203
|
+
const template = `-- Created: ${timestamp}
|
|
204
|
+
-- Description: ${description}
|
|
205
|
+
|
|
206
|
+
---- UP ----
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
---- DOWN ----
|
|
197
211
|
|
|
198
|
-
export const up = \`
|
|
199
|
-
-- SQL for migrate up
|
|
200
|
-
\`
|
|
201
212
|
|
|
202
|
-
export const down = \`
|
|
203
|
-
-- SQL for migrate down
|
|
204
|
-
\`
|
|
205
213
|
`;
|
|
206
214
|
try {
|
|
207
215
|
await mkdir(path, { recursive: true });
|
package/dist/cli.js
CHANGED
|
@@ -102,12 +102,11 @@ var runScript = async (db, script) => {
|
|
|
102
102
|
}
|
|
103
103
|
for (const statement of statements) {
|
|
104
104
|
console.log(`Executing statement: ${statement}`);
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
await db.updateSchema(sql);
|
|
105
|
+
if (isSchemaChange(statement)) {
|
|
106
|
+
await db.updateSchema(statement);
|
|
108
107
|
} else {
|
|
109
108
|
await db.runTransactionAsync(async (transaction) => {
|
|
110
|
-
await transaction.runUpdate(
|
|
109
|
+
await transaction.runUpdate(statement);
|
|
111
110
|
await transaction.commit();
|
|
112
111
|
});
|
|
113
112
|
}
|
|
@@ -169,7 +168,7 @@ var import_node_path = require("path");
|
|
|
169
168
|
var getMigrationFiles = async (path) => {
|
|
170
169
|
try {
|
|
171
170
|
const files = await (0, import_promises.readdir)(path);
|
|
172
|
-
const migrationFileIds = files.filter((file) => file.endsWith(".
|
|
171
|
+
const migrationFileIds = files.filter((file) => file.endsWith(".sql")).map((file) => file.replace(/\.sql$/, ""));
|
|
173
172
|
return migrationFileIds;
|
|
174
173
|
} catch (error) {
|
|
175
174
|
throw new Error(
|
|
@@ -179,31 +178,40 @@ var getMigrationFiles = async (path) => {
|
|
|
179
178
|
};
|
|
180
179
|
var getMigration = async (path, id) => {
|
|
181
180
|
try {
|
|
182
|
-
const filePath = (0, import_node_path.resolve)(process.cwd(), (0, import_node_path.join)(path, `${id}.
|
|
181
|
+
const filePath = (0, import_node_path.resolve)(process.cwd(), (0, import_node_path.join)(path, `${id}.sql`));
|
|
183
182
|
try {
|
|
184
183
|
await (0, import_promises.access)(filePath);
|
|
185
184
|
} catch (err) {
|
|
186
185
|
throw new Error(`Migration file not found: ${filePath}`);
|
|
187
186
|
}
|
|
188
|
-
const
|
|
189
|
-
|
|
187
|
+
const migrationText = await (0, import_promises.readFile)(filePath, "utf8");
|
|
188
|
+
const up2 = getSql(migrationText, "up");
|
|
189
|
+
const down2 = getSql(migrationText, "down");
|
|
190
|
+
const description = getDescription(migrationText);
|
|
191
|
+
if (!up2 || !down2) {
|
|
190
192
|
throw new Error(
|
|
191
193
|
`Migration file ${filePath} does not export required scripts (up, down).`
|
|
192
194
|
);
|
|
193
195
|
}
|
|
194
|
-
return {
|
|
195
|
-
id,
|
|
196
|
-
description: id.split("_").slice(1).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" "),
|
|
197
|
-
// Generate a human-readable description
|
|
198
|
-
up: migrationModule.up,
|
|
199
|
-
down: migrationModule.down
|
|
200
|
-
};
|
|
196
|
+
return { id, description, up: up2, down: down2 };
|
|
201
197
|
} catch (error) {
|
|
202
198
|
throw new Error(
|
|
203
199
|
`Failed to get migration ${id}: ${error.message}`
|
|
204
200
|
);
|
|
205
201
|
}
|
|
206
202
|
};
|
|
203
|
+
var getDescription = (text) => {
|
|
204
|
+
var _a, _b;
|
|
205
|
+
return ((_b = (_a = text == null ? void 0 : text.match(/^--\s*Description:\s*(.+)$/m)) == null ? void 0 : _a[1]) == null ? void 0 : _b.trim()) || "";
|
|
206
|
+
};
|
|
207
|
+
var getSql = (text, direction) => {
|
|
208
|
+
var _a, _b;
|
|
209
|
+
const rx = {
|
|
210
|
+
up: /---- UP ----\n([\s\S]*?)\n---- DOWN ----/,
|
|
211
|
+
down: /---- DOWN ----\n([\s\S]*)$/
|
|
212
|
+
};
|
|
213
|
+
return (_b = (_a = text == null ? void 0 : text.match(rx[direction])) == null ? void 0 : _a[1]) == null ? void 0 : _b.replace(/--.*$/gm, "").trim();
|
|
214
|
+
};
|
|
207
215
|
var getNewMigrations = (applied, files) => {
|
|
208
216
|
const sortedFiles = files.sort();
|
|
209
217
|
for (let ix = 0; ix < applied.length; ix++) {
|
|
@@ -222,18 +230,18 @@ var createMigration = async (path, description) => {
|
|
|
222
230
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
223
231
|
const compactTimestamp = timestamp.replace(/[-:.TZ]/g, "");
|
|
224
232
|
const parsedDescription = description.replace(/\s+/g, "_").toLowerCase();
|
|
225
|
-
const filename = `${compactTimestamp}_${parsedDescription}.
|
|
233
|
+
const filename = `${compactTimestamp}_${parsedDescription}.sql`;
|
|
226
234
|
const filePath = (0, import_node_path.join)(path, filename);
|
|
227
|
-
const template =
|
|
228
|
-
|
|
235
|
+
const template = `-- Created: ${timestamp}
|
|
236
|
+
-- Description: ${description}
|
|
237
|
+
|
|
238
|
+
---- UP ----
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
---- DOWN ----
|
|
229
243
|
|
|
230
|
-
export const up = \`
|
|
231
|
-
-- SQL for migrate up
|
|
232
|
-
\`
|
|
233
244
|
|
|
234
|
-
export const down = \`
|
|
235
|
-
-- SQL for migrate down
|
|
236
|
-
\`
|
|
237
245
|
`;
|
|
238
246
|
try {
|
|
239
247
|
await (0, import_promises.mkdir)(path, { recursive: true });
|
|
@@ -356,7 +364,7 @@ async function loadConfig() {
|
|
|
356
364
|
const fullDescription = args.description.join(" ");
|
|
357
365
|
await create(config, fullDescription);
|
|
358
366
|
console.log(
|
|
359
|
-
`Migration file created: '${(0, import_node_path2.join)(config.migrationsPath, args.description.join("_"))}.
|
|
367
|
+
`Migration file created: '${(0, import_node_path2.join)(config.migrationsPath, args.description.join("_"))}.sql'`
|
|
360
368
|
);
|
|
361
369
|
}
|
|
362
370
|
).command(
|
package/dist/cli.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
init,
|
|
6
6
|
status,
|
|
7
7
|
up
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-Z3ZLNDVO.mjs";
|
|
9
9
|
|
|
10
10
|
// src/cli.ts
|
|
11
11
|
import fs from "node:fs/promises";
|
|
@@ -64,7 +64,7 @@ yargs(hideBin(process.argv)).scriptName("spanner-migrate").usage("$0 <command>")
|
|
|
64
64
|
const fullDescription = args.description.join(" ");
|
|
65
65
|
await create(config, fullDescription);
|
|
66
66
|
console.log(
|
|
67
|
-
`Migration file created: '${join(config.migrationsPath, args.description.join("_"))}.
|
|
67
|
+
`Migration file created: '${join(config.migrationsPath, args.description.join("_"))}.sql'`
|
|
68
68
|
);
|
|
69
69
|
}
|
|
70
70
|
).command(
|
package/dist/index.js
CHANGED
|
@@ -98,12 +98,11 @@ var runScript = async (db, script) => {
|
|
|
98
98
|
}
|
|
99
99
|
for (const statement of statements) {
|
|
100
100
|
console.log(`Executing statement: ${statement}`);
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
await db.updateSchema(sql);
|
|
101
|
+
if (isSchemaChange(statement)) {
|
|
102
|
+
await db.updateSchema(statement);
|
|
104
103
|
} else {
|
|
105
104
|
await db.runTransactionAsync(async (transaction) => {
|
|
106
|
-
await transaction.runUpdate(
|
|
105
|
+
await transaction.runUpdate(statement);
|
|
107
106
|
await transaction.commit();
|
|
108
107
|
});
|
|
109
108
|
}
|
|
@@ -165,7 +164,7 @@ var import_node_path = require("path");
|
|
|
165
164
|
var getMigrationFiles = async (path) => {
|
|
166
165
|
try {
|
|
167
166
|
const files = await (0, import_promises.readdir)(path);
|
|
168
|
-
const migrationFileIds = files.filter((file) => file.endsWith(".
|
|
167
|
+
const migrationFileIds = files.filter((file) => file.endsWith(".sql")).map((file) => file.replace(/\.sql$/, ""));
|
|
169
168
|
return migrationFileIds;
|
|
170
169
|
} catch (error) {
|
|
171
170
|
throw new Error(
|
|
@@ -175,31 +174,40 @@ var getMigrationFiles = async (path) => {
|
|
|
175
174
|
};
|
|
176
175
|
var getMigration = async (path, id) => {
|
|
177
176
|
try {
|
|
178
|
-
const filePath = (0, import_node_path.resolve)(process.cwd(), (0, import_node_path.join)(path, `${id}.
|
|
177
|
+
const filePath = (0, import_node_path.resolve)(process.cwd(), (0, import_node_path.join)(path, `${id}.sql`));
|
|
179
178
|
try {
|
|
180
179
|
await (0, import_promises.access)(filePath);
|
|
181
180
|
} catch (err) {
|
|
182
181
|
throw new Error(`Migration file not found: ${filePath}`);
|
|
183
182
|
}
|
|
184
|
-
const
|
|
185
|
-
|
|
183
|
+
const migrationText = await (0, import_promises.readFile)(filePath, "utf8");
|
|
184
|
+
const up2 = getSql(migrationText, "up");
|
|
185
|
+
const down2 = getSql(migrationText, "down");
|
|
186
|
+
const description = getDescription(migrationText);
|
|
187
|
+
if (!up2 || !down2) {
|
|
186
188
|
throw new Error(
|
|
187
189
|
`Migration file ${filePath} does not export required scripts (up, down).`
|
|
188
190
|
);
|
|
189
191
|
}
|
|
190
|
-
return {
|
|
191
|
-
id,
|
|
192
|
-
description: id.split("_").slice(1).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" "),
|
|
193
|
-
// Generate a human-readable description
|
|
194
|
-
up: migrationModule.up,
|
|
195
|
-
down: migrationModule.down
|
|
196
|
-
};
|
|
192
|
+
return { id, description, up: up2, down: down2 };
|
|
197
193
|
} catch (error) {
|
|
198
194
|
throw new Error(
|
|
199
195
|
`Failed to get migration ${id}: ${error.message}`
|
|
200
196
|
);
|
|
201
197
|
}
|
|
202
198
|
};
|
|
199
|
+
var getDescription = (text) => {
|
|
200
|
+
var _a, _b;
|
|
201
|
+
return ((_b = (_a = text == null ? void 0 : text.match(/^--\s*Description:\s*(.+)$/m)) == null ? void 0 : _a[1]) == null ? void 0 : _b.trim()) || "";
|
|
202
|
+
};
|
|
203
|
+
var getSql = (text, direction) => {
|
|
204
|
+
var _a, _b;
|
|
205
|
+
const rx = {
|
|
206
|
+
up: /---- UP ----\n([\s\S]*?)\n---- DOWN ----/,
|
|
207
|
+
down: /---- DOWN ----\n([\s\S]*)$/
|
|
208
|
+
};
|
|
209
|
+
return (_b = (_a = text == null ? void 0 : text.match(rx[direction])) == null ? void 0 : _a[1]) == null ? void 0 : _b.replace(/--.*$/gm, "").trim();
|
|
210
|
+
};
|
|
203
211
|
var getNewMigrations = (applied, files) => {
|
|
204
212
|
const sortedFiles = files.sort();
|
|
205
213
|
for (let ix = 0; ix < applied.length; ix++) {
|
|
@@ -218,18 +226,18 @@ var createMigration = async (path, description) => {
|
|
|
218
226
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
219
227
|
const compactTimestamp = timestamp.replace(/[-:.TZ]/g, "");
|
|
220
228
|
const parsedDescription = description.replace(/\s+/g, "_").toLowerCase();
|
|
221
|
-
const filename = `${compactTimestamp}_${parsedDescription}.
|
|
229
|
+
const filename = `${compactTimestamp}_${parsedDescription}.sql`;
|
|
222
230
|
const filePath = (0, import_node_path.join)(path, filename);
|
|
223
|
-
const template =
|
|
224
|
-
|
|
231
|
+
const template = `-- Created: ${timestamp}
|
|
232
|
+
-- Description: ${description}
|
|
233
|
+
|
|
234
|
+
---- UP ----
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
---- DOWN ----
|
|
225
239
|
|
|
226
|
-
export const up = \`
|
|
227
|
-
-- SQL for migrate up
|
|
228
|
-
\`
|
|
229
240
|
|
|
230
|
-
export const down = \`
|
|
231
|
-
-- SQL for migrate down
|
|
232
|
-
\`
|
|
233
241
|
`;
|
|
234
242
|
try {
|
|
235
243
|
await (0, import_promises.mkdir)(path, { recursive: true });
|
package/dist/index.mjs
CHANGED