rake-db 2.0.7 → 2.0.9

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/.env.local CHANGED
@@ -1 +1,2 @@
1
1
  DATABASE_URL=postgres://postgres:@localhost:5432/porm
2
+ DATABASE_URL_TEST=postgres://postgres:@localhost:5432/porm_test
package/db.ts CHANGED
@@ -10,7 +10,12 @@ if (!connectionString) {
10
10
  throw new Error('DATABASE_URL is missing in .env');
11
11
  }
12
12
 
13
+ const connectionStringTest = process.env.DATABASE_URL_TEST;
14
+ if (!connectionStringTest) {
15
+ throw new Error('DATABASE_URL_TEST is missing in .env');
16
+ }
17
+
13
18
  rakeDb(
14
- { connectionString },
19
+ [{ connectionString }, { connectionString: connectionStringTest }],
15
20
  { migrationsPath: path.resolve(process.cwd(), 'migrations') },
16
21
  );
package/dist/index.d.ts CHANGED
@@ -8,11 +8,12 @@ declare type MigrationConfig = {
8
8
 
9
9
  declare const createDb: (arg: MaybeArray<AdapterOptions>, config: MigrationConfig) => Promise<void>;
10
10
  declare const dropDb: (arg: MaybeArray<AdapterOptions>) => Promise<void>;
11
+ declare const resetDb: (arg: MaybeArray<AdapterOptions>, config: MigrationConfig) => Promise<void>;
11
12
 
12
13
  declare const generate: (config: MigrationConfig, args: string[]) => Promise<void>;
13
14
 
14
- declare const migrate: (options: MaybeArray<AdapterOptions>, config: MigrationConfig, args: string[]) => Promise<void>;
15
- declare const rollback: (options: MaybeArray<AdapterOptions>, config: MigrationConfig, args: string[]) => Promise<void>;
15
+ declare const migrate: (options: MaybeArray<AdapterOptions>, config: MigrationConfig, args?: string[]) => Promise<void>;
16
+ declare const rollback: (options: MaybeArray<AdapterOptions>, config: MigrationConfig, args?: string[]) => Promise<void>;
16
17
 
17
18
  declare function add(item: ColumnType, options?: {
18
19
  dropMode?: DropMode;
@@ -119,8 +120,9 @@ declare class Migration extends TransactionAdapter {
119
120
  constraintExists(constraintName: string): Promise<boolean>;
120
121
  }
121
122
 
122
- declare const change: (fn: (db: Migration, up: boolean) => Promise<void>) => void;
123
+ declare type ChangeCallback = (db: Migration, up: boolean) => Promise<void>;
124
+ declare const change: (fn: ChangeCallback) => void;
123
125
 
124
126
  declare const rakeDb: (options: MaybeArray<AdapterOptions>, partialConfig?: Partial<MigrationConfig>, args?: string[]) => Promise<void>;
125
127
 
126
- export { ChangeTableCallback, ChangeTableOptions, ColumnComment, ColumnIndex, ColumnsShapeCallback, DropMode, ExtensionOptions, JoinTableOptions, Migration, TableOptions, change, createDb, dropDb, generate, migrate, rakeDb, rollback };
128
+ export { ChangeTableCallback, ChangeTableOptions, ColumnComment, ColumnIndex, ColumnsShapeCallback, DropMode, ExtensionOptions, JoinTableOptions, Migration, TableOptions, change, createDb, dropDb, generate, migrate, rakeDb, resetDb, rollback };
package/dist/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- import { toArray, Adapter, quote, isRaw, getRaw, getColumnTypes, columnTypes, getTableData, ColumnType, Operators, resetTableData, emptyObject, TransactionAdapter, logParamToLogObject } from 'pqb';
1
+ import { quote, isRaw, getRaw, toArray, getColumnTypes, columnTypes, getTableData, ColumnType, Operators, resetTableData, emptyObject, TransactionAdapter, logParamToLogObject, Adapter } from 'pqb';
2
2
  import Enquirer from 'enquirer';
3
3
  import path from 'path';
4
4
  import { readdir, mkdir, writeFile } from 'fs/promises';
@@ -181,156 +181,15 @@ const quoteTable = (table) => {
181
181
  }
182
182
  };
183
183
 
184
- const execute = async (options, sql) => {
185
- const db = new Adapter(options);
186
- try {
187
- await db.query(sql);
188
- return "ok";
189
- } catch (error) {
190
- const err = error;
191
- if (err.code === "42P04" || err.code === "3D000") {
192
- return "already";
193
- } else if (err.code === "42501") {
194
- return "forbidden";
195
- } else {
196
- return { error };
197
- }
198
- } finally {
199
- await db.destroy();
200
- }
201
- };
202
- const createOrDrop = async (options, adminOptions, config, args) => {
203
- const params = getDatabaseAndUserFromOptions(options);
204
- const result = await execute(
205
- setAdapterOptions(adminOptions, { database: "postgres" }),
206
- args.sql(params)
207
- );
208
- if (result === "ok") {
209
- console.log(args.successMessage(params));
210
- } else if (result === "already") {
211
- console.log(args.alreadyMessage(params));
212
- } else if (result === "forbidden") {
213
- await createOrDrop(
214
- options,
215
- await setAdminCredentialsToOptions(options),
216
- config,
217
- args
218
- );
219
- return;
220
- } else {
221
- throw result.error;
222
- }
223
- if (!args.createVersionsTable)
224
- return;
225
- const db = new Adapter(options);
226
- await createSchemaMigrations(db, config);
227
- await db.destroy();
228
- };
229
- const createDb = async (arg, config) => {
230
- for (const options of toArray(arg)) {
231
- await createOrDrop(options, options, config, {
232
- sql({ database, user }) {
233
- return `CREATE DATABASE "${database}" OWNER "${user}"`;
234
- },
235
- successMessage({ database }) {
236
- return `Database ${database} successfully created`;
237
- },
238
- alreadyMessage({ database }) {
239
- return `Database ${database} already exists`;
240
- },
241
- createVersionsTable: true
242
- });
243
- }
244
- };
245
- const dropDb = async (arg) => {
246
- for (const options of toArray(arg)) {
247
- await createOrDrop(options, options, migrationConfigDefaults, {
248
- sql({ database }) {
249
- return `DROP DATABASE "${database}"`;
250
- },
251
- successMessage({ database }) {
252
- return `Database ${database} was successfully dropped`;
253
- },
254
- alreadyMessage({ database }) {
255
- return `Database ${database} does not exist`;
256
- }
257
- });
258
- }
259
- };
260
-
261
- const generate = async (config, args) => {
262
- const name = args[0];
263
- if (!name)
264
- throw new Error("Migration name is missing");
265
- await mkdir(config.migrationsPath, { recursive: true });
266
- const filePath = path.resolve(
267
- config.migrationsPath,
268
- `${makeFileTimeStamp()}_${name}.ts`
269
- );
270
- await writeFile(filePath, makeContent(name, args.slice(1)));
271
- console.log(`Created ${filePath}`);
272
- };
273
- const makeFileTimeStamp = () => {
274
- const now = new Date();
275
- return [
276
- now.getUTCFullYear(),
277
- now.getUTCMonth() + 1,
278
- now.getUTCDate(),
279
- now.getUTCHours(),
280
- now.getUTCMinutes(),
281
- now.getUTCSeconds()
282
- ].map((value) => value < 10 ? `0${value}` : value).join("");
283
- };
284
- const makeContent = (name, args) => {
285
- let content = `import { change } from 'rake-db';
286
-
287
- change(async (db) => {`;
288
- const [first, rest] = getFirstWordAndRest(name);
289
- if (rest) {
290
- if (first === "create" || first === "drop") {
291
- content += `
292
- await db.${first === "create" ? "createTable" : "dropTable"}('${rest}', (t) => ({`;
293
- content += makeColumnsContent(args);
294
- content += "\n }));";
295
- } else if (first === "change") {
296
- content += `
297
- await db.changeTable('${rest}', (t) => ({`;
298
- content += "\n }));";
299
- } else if (first === "add" || first === "remove") {
300
- const table = first === "add" ? getTextAfterTo(rest) : getTextAfterFrom(rest);
301
- content += `
302
- await db.changeTable(${table ? `'${table}'` : "tableName"}, (t) => ({`;
303
- content += makeColumnsContent(args, first);
304
- content += "\n }));";
305
- }
306
- }
307
- return content + "\n});\n";
308
- };
309
- const makeColumnsContent = (args, method) => {
310
- let content = "";
311
- const prepend = method ? `t.${method}(` : "";
312
- const append = method ? ")" : "";
313
- for (const arg of args) {
314
- const [name, def] = arg.split(":");
315
- if (!def) {
316
- throw new Error(
317
- `Column argument should be similar to name:type, name:type.method1.method2, name:type(arg).method(arg). Example: name:varchar(20).nullable. Received: ${arg}`
318
- );
319
- }
320
- const methods = def.split(".").map((method2) => method2.endsWith(")") ? `.${method2}` : `.${method2}()`);
321
- content += `
322
- ${name}: ${prepend}t${methods.join("")}${append},`;
323
- }
324
- return content;
325
- };
326
-
327
184
  let currentMigration;
328
185
  let currentPromise;
329
186
  let currentUp = true;
187
+ let currentChangeCallback;
330
188
  const change = (fn) => {
331
189
  if (!currentMigration)
332
190
  throw new Error("Database instance is not set");
333
191
  currentPromise = fn(currentMigration, currentUp);
192
+ currentChangeCallback = fn;
334
193
  };
335
194
  const setCurrentMigration = (db) => {
336
195
  currentMigration = db;
@@ -339,6 +198,7 @@ const setCurrentMigrationUp = (up) => {
339
198
  currentUp = up;
340
199
  };
341
200
  const getCurrentPromise = () => currentPromise;
201
+ const getCurrentChangeCallback = () => currentChangeCallback;
342
202
 
343
203
  var __defProp$2 = Object.defineProperty;
344
204
  var __defProps$2 = Object.defineProperties;
@@ -1090,12 +950,19 @@ const migrateOrRollback = async (options, config, args, up) => {
1090
950
  }
1091
951
  }
1092
952
  };
953
+ const changeCache = {};
1093
954
  const processMigration = async (db, up, file, config) => {
1094
955
  await db.transaction(async (tx) => {
1095
956
  const db2 = new Migration(tx, up, config);
1096
957
  setCurrentMigration(db2);
1097
958
  setCurrentMigrationUp(up);
1098
- config.requireTs(file.path);
959
+ const callback = changeCache[file.path];
960
+ if (callback) {
961
+ change(callback);
962
+ } else {
963
+ config.requireTs(file.path);
964
+ changeCache[file.path] = getCurrentChangeCallback();
965
+ }
1099
966
  await getCurrentPromise();
1100
967
  await (up ? saveMigratedVersion : removeMigratedVersion)(
1101
968
  db2,
@@ -1130,8 +997,156 @@ const getMigratedVersionsMap = async (db, config) => {
1130
997
  throw err;
1131
998
  }
1132
999
  };
1133
- const migrate = (options, config, args) => migrateOrRollback(options, config, args, true);
1134
- const rollback = (options, config, args) => migrateOrRollback(options, config, args, false);
1000
+ const migrate = (options, config, args = []) => migrateOrRollback(options, config, args, true);
1001
+ const rollback = (options, config, args = []) => migrateOrRollback(options, config, args, false);
1002
+
1003
+ const execute = async (options, sql) => {
1004
+ const db = new Adapter(options);
1005
+ try {
1006
+ await db.query(sql);
1007
+ return "ok";
1008
+ } catch (error) {
1009
+ const err = error;
1010
+ if (err.code === "42P04" || err.code === "3D000") {
1011
+ return "already";
1012
+ } else if (err.code === "42501") {
1013
+ return "forbidden";
1014
+ } else {
1015
+ return { error };
1016
+ }
1017
+ } finally {
1018
+ await db.destroy();
1019
+ }
1020
+ };
1021
+ const createOrDrop = async (options, adminOptions, config, args) => {
1022
+ const params = getDatabaseAndUserFromOptions(options);
1023
+ const result = await execute(
1024
+ setAdapterOptions(adminOptions, { database: "postgres" }),
1025
+ args.sql(params)
1026
+ );
1027
+ if (result === "ok") {
1028
+ console.log(args.successMessage(params));
1029
+ } else if (result === "already") {
1030
+ console.log(args.alreadyMessage(params));
1031
+ } else if (result === "forbidden") {
1032
+ await createOrDrop(
1033
+ options,
1034
+ await setAdminCredentialsToOptions(options),
1035
+ config,
1036
+ args
1037
+ );
1038
+ return;
1039
+ } else {
1040
+ throw result.error;
1041
+ }
1042
+ if (!args.createVersionsTable)
1043
+ return;
1044
+ const db = new Adapter(options);
1045
+ await createSchemaMigrations(db, config);
1046
+ await db.destroy();
1047
+ };
1048
+ const createDb = async (arg, config) => {
1049
+ for (const options of toArray(arg)) {
1050
+ await createOrDrop(options, options, config, {
1051
+ sql({ database, user }) {
1052
+ return `CREATE DATABASE "${database}" OWNER "${user}"`;
1053
+ },
1054
+ successMessage({ database }) {
1055
+ return `Database ${database} successfully created`;
1056
+ },
1057
+ alreadyMessage({ database }) {
1058
+ return `Database ${database} already exists`;
1059
+ },
1060
+ createVersionsTable: true
1061
+ });
1062
+ }
1063
+ };
1064
+ const dropDb = async (arg) => {
1065
+ for (const options of toArray(arg)) {
1066
+ await createOrDrop(options, options, migrationConfigDefaults, {
1067
+ sql({ database }) {
1068
+ return `DROP DATABASE "${database}"`;
1069
+ },
1070
+ successMessage({ database }) {
1071
+ return `Database ${database} was successfully dropped`;
1072
+ },
1073
+ alreadyMessage({ database }) {
1074
+ return `Database ${database} does not exist`;
1075
+ }
1076
+ });
1077
+ }
1078
+ };
1079
+ const resetDb = async (arg, config) => {
1080
+ await dropDb(arg);
1081
+ await createDb(arg, config);
1082
+ await migrate(arg, config);
1083
+ };
1084
+
1085
+ const generate = async (config, args) => {
1086
+ const name = args[0];
1087
+ if (!name)
1088
+ throw new Error("Migration name is missing");
1089
+ await mkdir(config.migrationsPath, { recursive: true });
1090
+ const filePath = path.resolve(
1091
+ config.migrationsPath,
1092
+ `${makeFileTimeStamp()}_${name}.ts`
1093
+ );
1094
+ await writeFile(filePath, makeContent(name, args.slice(1)));
1095
+ console.log(`Created ${filePath}`);
1096
+ };
1097
+ const makeFileTimeStamp = () => {
1098
+ const now = new Date();
1099
+ return [
1100
+ now.getUTCFullYear(),
1101
+ now.getUTCMonth() + 1,
1102
+ now.getUTCDate(),
1103
+ now.getUTCHours(),
1104
+ now.getUTCMinutes(),
1105
+ now.getUTCSeconds()
1106
+ ].map((value) => value < 10 ? `0${value}` : value).join("");
1107
+ };
1108
+ const makeContent = (name, args) => {
1109
+ let content = `import { change } from 'rake-db';
1110
+
1111
+ change(async (db) => {`;
1112
+ const [first, rest] = getFirstWordAndRest(name);
1113
+ if (rest) {
1114
+ if (first === "create" || first === "drop") {
1115
+ content += `
1116
+ await db.${first === "create" ? "createTable" : "dropTable"}('${rest}', (t) => ({`;
1117
+ content += makeColumnsContent(args);
1118
+ content += "\n }));";
1119
+ } else if (first === "change") {
1120
+ content += `
1121
+ await db.changeTable('${rest}', (t) => ({`;
1122
+ content += "\n }));";
1123
+ } else if (first === "add" || first === "remove") {
1124
+ const table = first === "add" ? getTextAfterTo(rest) : getTextAfterFrom(rest);
1125
+ content += `
1126
+ await db.changeTable(${table ? `'${table}'` : "tableName"}, (t) => ({`;
1127
+ content += makeColumnsContent(args, first);
1128
+ content += "\n }));";
1129
+ }
1130
+ }
1131
+ return content + "\n});\n";
1132
+ };
1133
+ const makeColumnsContent = (args, method) => {
1134
+ let content = "";
1135
+ const prepend = method ? `t.${method}(` : "";
1136
+ const append = method ? ")" : "";
1137
+ for (const arg of args) {
1138
+ const [name, def] = arg.split(":");
1139
+ if (!def) {
1140
+ throw new Error(
1141
+ `Column argument should be similar to name:type, name:type.method1.method2, name:type(arg).method(arg). Example: name:varchar(20).nullable. Received: ${arg}`
1142
+ );
1143
+ }
1144
+ const methods = def.split(".").map((method2) => method2.endsWith(")") ? `.${method2}` : `.${method2}()`);
1145
+ content += `
1146
+ ${name}: ${prepend}t${methods.join("")}${append},`;
1147
+ }
1148
+ return content;
1149
+ };
1135
1150
 
1136
1151
  const rakeDb = async (options, partialConfig = {}, args = process.argv.slice(2)) => {
1137
1152
  const config = getMigrationConfigWithDefaults(partialConfig);
@@ -1140,6 +1155,8 @@ const rakeDb = async (options, partialConfig = {}, args = process.argv.slice(2))
1140
1155
  await createDb(options, config);
1141
1156
  } else if (command === "drop") {
1142
1157
  await dropDb(options);
1158
+ } else if (command === "reset") {
1159
+ await resetDb(options, config);
1143
1160
  } else if (command === "migrate") {
1144
1161
  await migrate(options, config, args.slice(1));
1145
1162
  } else if (command === "rollback") {
@@ -1154,9 +1171,10 @@ const printHelp = () => console.log(
1154
1171
  `Usage: rake-db [command] [arguments]
1155
1172
 
1156
1173
  Commands:
1157
- create creates databases
1158
- drop drops databases
1159
- g, generate generates migration file, see below
1174
+ create create databases
1175
+ drop drop databases
1176
+ reset drop, create and migrate databases
1177
+ g, generate generate migration file, see below
1160
1178
  migrate migrate all pending migrations
1161
1179
  rollback rollback the last migrated
1162
1180
  no or unknown command prints this message
@@ -1174,5 +1192,5 @@ Generate arguments:
1174
1192
  `
1175
1193
  );
1176
1194
 
1177
- export { Migration, change, createDb, dropDb, generate, migrate, rakeDb, rollback };
1195
+ export { Migration, change, createDb, dropDb, generate, migrate, rakeDb, resetDb, rollback };
1178
1196
  //# sourceMappingURL=index.esm.js.map