@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 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
- const sql = statement.replace(/--.*$/gm, "");
74
- if (isSchemaChange(sql)) {
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(sql);
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(".ts")).map((file) => file.replace(/\.ts$/, ""));
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}.ts`));
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 migrationModule = await import(filePath);
157
- if (!migrationModule.up || !migrationModule.down) {
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}.ts`;
201
+ const filename = `${compactTimestamp}_${parsedDescription}.sql`;
194
202
  const filePath = join(path, filename);
195
- const template = `// ${timestamp}
196
- // ${description}
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
- const sql = statement.replace(/--.*$/gm, "");
106
- if (isSchemaChange(sql)) {
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(sql);
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(".ts")).map((file) => file.replace(/\.ts$/, ""));
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}.ts`));
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 migrationModule = await import(filePath);
189
- if (!migrationModule.up || !migrationModule.down) {
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}.ts`;
233
+ const filename = `${compactTimestamp}_${parsedDescription}.sql`;
226
234
  const filePath = (0, import_node_path.join)(path, filename);
227
- const template = `// ${timestamp}
228
- // ${description}
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("_"))}.ts'`
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-K5WX6ESL.mjs";
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("_"))}.ts'`
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
- const sql = statement.replace(/--.*$/gm, "");
102
- if (isSchemaChange(sql)) {
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(sql);
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(".ts")).map((file) => file.replace(/\.ts$/, ""));
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}.ts`));
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 migrationModule = await import(filePath);
185
- if (!migrationModule.up || !migrationModule.down) {
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}.ts`;
229
+ const filename = `${compactTimestamp}_${parsedDescription}.sql`;
222
230
  const filePath = (0, import_node_path.join)(path, filename);
223
- const template = `// ${timestamp}
224
- // ${description}
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
@@ -4,7 +4,7 @@ import {
4
4
  init,
5
5
  status,
6
6
  up
7
- } from "./chunk-K5WX6ESL.mjs";
7
+ } from "./chunk-Z3ZLNDVO.mjs";
8
8
  export {
9
9
  create,
10
10
  down,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sebspark/spanner-migrate",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "license": "Apache-2.0",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",