rake-db 1.3.2 → 2.0.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.
Files changed (72) hide show
  1. package/.env +3 -0
  2. package/.env.local +1 -0
  3. package/README.md +1 -545
  4. package/db.ts +16 -0
  5. package/dist/index.d.ts +94 -0
  6. package/dist/index.esm.js +190 -0
  7. package/dist/index.esm.js.map +1 -0
  8. package/dist/index.js +201 -0
  9. package/dist/index.js.map +1 -0
  10. package/jest-setup.ts +3 -0
  11. package/migrations/20221009210157_first.ts +8 -0
  12. package/migrations/20221009210200_second.ts +5 -0
  13. package/package.json +55 -41
  14. package/rollup.config.js +3 -0
  15. package/src/commands/createOrDrop.test.ts +145 -0
  16. package/src/commands/createOrDrop.ts +107 -0
  17. package/src/commands/generate.test.ts +133 -0
  18. package/src/commands/generate.ts +85 -0
  19. package/src/commands/migrateOrRollback.test.ts +118 -0
  20. package/src/commands/migrateOrRollback.ts +108 -0
  21. package/src/common.test.ts +281 -0
  22. package/src/common.ts +224 -0
  23. package/src/index.ts +2 -0
  24. package/src/migration/change.ts +20 -0
  25. package/src/migration/changeTable.test.ts +417 -0
  26. package/src/migration/changeTable.ts +375 -0
  27. package/src/migration/createTable.test.ts +269 -0
  28. package/src/migration/createTable.ts +169 -0
  29. package/src/migration/migration.test.ts +341 -0
  30. package/src/migration/migration.ts +296 -0
  31. package/src/migration/migrationUtils.ts +281 -0
  32. package/src/rakeDb.ts +29 -0
  33. package/src/test-utils.ts +45 -0
  34. package/tsconfig.json +12 -0
  35. package/dist/lib/createAndDrop.d.ts +0 -2
  36. package/dist/lib/createAndDrop.js +0 -63
  37. package/dist/lib/defaults.d.ts +0 -2
  38. package/dist/lib/defaults.js +0 -5
  39. package/dist/lib/errorCodes.d.ts +0 -4
  40. package/dist/lib/errorCodes.js +0 -7
  41. package/dist/lib/generate.d.ts +0 -1
  42. package/dist/lib/generate.js +0 -99
  43. package/dist/lib/help.d.ts +0 -2
  44. package/dist/lib/help.js +0 -24
  45. package/dist/lib/init.d.ts +0 -2
  46. package/dist/lib/init.js +0 -276
  47. package/dist/lib/migrate.d.ts +0 -4
  48. package/dist/lib/migrate.js +0 -189
  49. package/dist/lib/migration.d.ts +0 -37
  50. package/dist/lib/migration.js +0 -159
  51. package/dist/lib/schema/changeTable.d.ts +0 -23
  52. package/dist/lib/schema/changeTable.js +0 -109
  53. package/dist/lib/schema/column.d.ts +0 -31
  54. package/dist/lib/schema/column.js +0 -201
  55. package/dist/lib/schema/createTable.d.ts +0 -10
  56. package/dist/lib/schema/createTable.js +0 -53
  57. package/dist/lib/schema/foreignKey.d.ts +0 -11
  58. package/dist/lib/schema/foreignKey.js +0 -53
  59. package/dist/lib/schema/index.d.ts +0 -3
  60. package/dist/lib/schema/index.js +0 -54
  61. package/dist/lib/schema/primaryKey.d.ts +0 -9
  62. package/dist/lib/schema/primaryKey.js +0 -24
  63. package/dist/lib/schema/table.d.ts +0 -43
  64. package/dist/lib/schema/table.js +0 -110
  65. package/dist/lib/schema/timestamps.d.ts +0 -3
  66. package/dist/lib/schema/timestamps.js +0 -9
  67. package/dist/lib/utils.d.ts +0 -26
  68. package/dist/lib/utils.js +0 -114
  69. package/dist/rake-db.d.ts +0 -2
  70. package/dist/rake-db.js +0 -34
  71. package/dist/types.d.ts +0 -94
  72. package/dist/types.js +0 -40
@@ -0,0 +1,190 @@
1
+ import { toArray, Adapter } from 'pqb';
2
+ import Enquirer from 'enquirer';
3
+ import path from 'path';
4
+ import 'fs/promises';
5
+
6
+ var __defProp = Object.defineProperty;
7
+ var __defProps = Object.defineProperties;
8
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
9
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
10
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
11
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
12
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13
+ var __spreadValues = (a, b) => {
14
+ for (var prop in b || (b = {}))
15
+ if (__hasOwnProp.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ if (__getOwnPropSymbols)
18
+ for (var prop of __getOwnPropSymbols(b)) {
19
+ if (__propIsEnum.call(b, prop))
20
+ __defNormalProp(a, prop, b[prop]);
21
+ }
22
+ return a;
23
+ };
24
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
25
+ const migrationConfigDefaults = {
26
+ migrationsPath: path.resolve(process.cwd(), "src", "migrations"),
27
+ migrationsTable: "schemaMigrations",
28
+ requireTs(path2) {
29
+ {
30
+ require("ts-node").register({ compilerOptions: { module: "CommonJS" } });
31
+ }
32
+ require(path2);
33
+ }
34
+ };
35
+ const getDatabaseAndUserFromOptions = (options) => {
36
+ if (options.connectionString) {
37
+ const url = new URL(options.connectionString);
38
+ return {
39
+ database: url.pathname.slice(1),
40
+ user: url.username
41
+ };
42
+ } else {
43
+ return {
44
+ database: options.database,
45
+ user: options.user
46
+ };
47
+ }
48
+ };
49
+ const setAdapterOptions = (options, set) => {
50
+ if (options.connectionString) {
51
+ const url = new URL(options.connectionString);
52
+ if ("database" in set) {
53
+ url.pathname = `/${set.database}`;
54
+ }
55
+ if (set.user !== void 0) {
56
+ url.username = set.user;
57
+ }
58
+ if (set.password !== void 0) {
59
+ url.password = set.password;
60
+ }
61
+ return __spreadProps(__spreadValues({}, options), { connectionString: url.toString() });
62
+ } else {
63
+ return __spreadValues(__spreadValues({}, options), set);
64
+ }
65
+ };
66
+ const askAdminCredentials = async () => {
67
+ const prompt = new Enquirer.Snippet({
68
+ message: `What are postgres admin login and password?`,
69
+ fields: [
70
+ {
71
+ name: "user",
72
+ required: true
73
+ },
74
+ {
75
+ name: "password"
76
+ }
77
+ ],
78
+ values: {
79
+ user: "postgres",
80
+ password: ""
81
+ },
82
+ template: "Admin user: {{user}}\nAdmin password: {{password}}"
83
+ });
84
+ const { values } = await prompt.run();
85
+ if (!values.password)
86
+ values.password = "";
87
+ return values;
88
+ };
89
+ const setAdminCredentialsToOptions = async (options) => {
90
+ const values = await askAdminCredentials();
91
+ return setAdapterOptions(options, values);
92
+ };
93
+ const createSchemaMigrations = async (db, config) => {
94
+ try {
95
+ await db.query(
96
+ `CREATE TABLE "${config.migrationsTable}" ( version TEXT NOT NULL )`
97
+ );
98
+ console.log("Created versions table");
99
+ } catch (err) {
100
+ if (err.code === "42P07") {
101
+ console.log("Versions table exists");
102
+ } else {
103
+ throw err;
104
+ }
105
+ }
106
+ };
107
+
108
+ const execute = async (options, sql) => {
109
+ const db = new Adapter(options);
110
+ try {
111
+ await db.query(sql);
112
+ return "ok";
113
+ } catch (error) {
114
+ const err = error;
115
+ if (err.code === "42P04" || err.code === "3D000") {
116
+ return "already";
117
+ } else if (err.code === "42501") {
118
+ return "forbidden";
119
+ } else {
120
+ return { error };
121
+ }
122
+ } finally {
123
+ await db.destroy();
124
+ }
125
+ };
126
+ const createOrDrop = async (options, adminOptions, config, args) => {
127
+ const params = getDatabaseAndUserFromOptions(options);
128
+ const result = await execute(
129
+ setAdapterOptions(adminOptions, { database: "postgres" }),
130
+ args.sql(params)
131
+ );
132
+ if (result === "ok") {
133
+ console.log(args.successMessage(params));
134
+ } else if (result === "already") {
135
+ console.log(args.alreadyMessage(params));
136
+ } else if (result === "forbidden") {
137
+ await createOrDrop(
138
+ options,
139
+ await setAdminCredentialsToOptions(options),
140
+ config,
141
+ args
142
+ );
143
+ return;
144
+ } else {
145
+ throw result.error;
146
+ }
147
+ if (!args.createVersionsTable)
148
+ return;
149
+ const db = new Adapter(options);
150
+ await createSchemaMigrations(db, config);
151
+ await db.destroy();
152
+ };
153
+ const createDb = async (arg, config) => {
154
+ for (const options of toArray(arg)) {
155
+ await createOrDrop(options, options, config, {
156
+ sql({ database, user }) {
157
+ return `CREATE DATABASE "${database}" OWNER "${user}"`;
158
+ },
159
+ successMessage({ database }) {
160
+ return `Database ${database} successfully created`;
161
+ },
162
+ alreadyMessage({ database }) {
163
+ return `Database ${database} already exists`;
164
+ },
165
+ createVersionsTable: true
166
+ });
167
+ }
168
+ };
169
+ const dropDb = async (arg) => {
170
+ for (const options of toArray(arg)) {
171
+ await createOrDrop(options, options, migrationConfigDefaults, {
172
+ sql({ database }) {
173
+ return `DROP DATABASE "${database}"`;
174
+ },
175
+ successMessage({ database }) {
176
+ return `Database ${database} was successfully dropped`;
177
+ },
178
+ alreadyMessage({ database }) {
179
+ return `Database ${database} does not exist`;
180
+ }
181
+ });
182
+ }
183
+ };
184
+
185
+ const change = (fn) => {
186
+ throw new Error("Database instance is not set");
187
+ };
188
+
189
+ export { change, createDb, dropDb };
190
+ //# sourceMappingURL=index.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.esm.js","sources":["../src/common.ts","../src/commands/createOrDrop.ts","../src/migration/change.ts"],"sourcesContent":["import { Adapter, AdapterOptions } from 'pqb';\nimport Enquirer from 'enquirer';\nimport path from 'path';\nimport { readdir } from 'fs/promises';\n\nexport type MigrationConfig = {\n migrationsPath: string;\n migrationsTable: string;\n requireTs(path: string): void;\n};\n\nconst registered = false;\n\nexport const migrationConfigDefaults = {\n migrationsPath: path.resolve(process.cwd(), 'src', 'migrations'),\n migrationsTable: 'schemaMigrations',\n requireTs(path: string) {\n if (!registered) {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n require('ts-node').register({ compilerOptions: { module: 'CommonJS' } });\n }\n require(path);\n },\n};\n\nexport const getMigrationConfigWithDefaults = (\n config: Partial<MigrationConfig>,\n) => {\n return { ...migrationConfigDefaults, ...config };\n};\n\nexport const getDatabaseAndUserFromOptions = (\n options: AdapterOptions,\n): { database: string; user: string } => {\n if (options.connectionString) {\n const url = new URL(options.connectionString);\n return {\n database: url.pathname.slice(1),\n user: url.username,\n };\n } else {\n return {\n database: options.database as string,\n user: options.user as string,\n };\n }\n};\n\nexport const setAdapterOptions = (\n options: AdapterOptions,\n set: { database?: string; user?: string; password?: string },\n): AdapterOptions => {\n if (options.connectionString) {\n const url = new URL(options.connectionString);\n\n if ('database' in set) {\n url.pathname = `/${set.database}`;\n }\n\n if (set.user !== undefined) {\n url.username = set.user;\n }\n\n if (set.password !== undefined) {\n url.password = set.password;\n }\n\n return { ...options, connectionString: url.toString() };\n } else {\n return {\n ...options,\n ...set,\n };\n }\n};\n\nconst askAdminCredentials = async (): Promise<{\n user: string;\n password: string;\n}> => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const prompt = new (Enquirer as any).Snippet({\n message: `What are postgres admin login and password?`,\n fields: [\n {\n name: 'user',\n required: true,\n },\n {\n name: 'password',\n },\n ],\n values: {\n user: 'postgres',\n password: '',\n },\n template: 'Admin user: {{user}}\\nAdmin password: {{password}}',\n });\n\n const { values } = await prompt.run();\n if (!values.password) values.password = '';\n\n return values;\n};\n\nexport const setAdminCredentialsToOptions = async (\n options: AdapterOptions,\n): Promise<AdapterOptions> => {\n const values = await askAdminCredentials();\n return setAdapterOptions(options, values);\n};\n\nexport const createSchemaMigrations = async (\n db: Adapter,\n config: MigrationConfig,\n) => {\n try {\n await db.query(\n `CREATE TABLE \"${config.migrationsTable}\" ( version TEXT NOT NULL )`,\n );\n console.log('Created versions table');\n } catch (err) {\n if ((err as Record<string, unknown>).code === '42P07') {\n console.log('Versions table exists');\n } else {\n throw err;\n }\n }\n};\n\nexport const getFirstWordAndRest = (\n input: string,\n): [string] | [string, string] => {\n const index = input.search(/(?=[A-Z])|[-_]/);\n if (index !== -1) {\n const restStart =\n input[index] === '-' || input[index] === '_' ? index + 1 : index;\n const rest = input.slice(restStart);\n return [input.slice(0, index), rest[0].toLowerCase() + rest.slice(1)];\n } else {\n return [input];\n }\n};\n\nconst getTextAfterRegExp = (\n input: string,\n regex: RegExp,\n length: number,\n): string | undefined => {\n let index = input.search(regex);\n if (index === -1) return;\n\n if (input[index] === '-' || input[index] === '_') index++;\n index += length;\n\n const start = input[index] == '-' || input[index] === '_' ? index + 1 : index;\n const text = input.slice(start);\n return text[0].toLowerCase() + text.slice(1);\n};\n\nexport const getTextAfterTo = (input: string): string | undefined => {\n return getTextAfterRegExp(input, /(To|-to|_to)[A-Z-_]/, 2);\n};\n\nexport const getTextAfterFrom = (input: string): string | undefined => {\n return getTextAfterRegExp(input, /(From|-from|_from)[A-Z-_]/, 4);\n};\n\nexport type MigrationFile = {\n path: string;\n version: string;\n};\n\nexport const getMigrationFiles = async (\n config: MigrationConfig,\n up: boolean,\n): Promise<MigrationFile[]> => {\n const { migrationsPath } = config;\n\n let files: string[];\n try {\n files = await readdir(migrationsPath);\n } catch (_) {\n return [];\n }\n\n const sort = up ? sortAsc : sortDesc;\n return sort(files).map((file) => {\n if (!file.endsWith('.ts')) {\n throw new Error(\n `Only .ts files are supported for migration, received: ${file}`,\n );\n }\n\n const timestampMatch = file.match(/^(\\d{14})\\D/);\n if (!timestampMatch) {\n throw new Error(\n `Migration file name should start with 14 digit version, received ${file}`,\n );\n }\n\n return {\n path: path.join(migrationsPath, file),\n version: timestampMatch[1],\n };\n });\n};\n\nexport const sortAsc = (arr: string[]) => arr.sort();\n\nexport const sortDesc = (arr: string[]) => arr.sort((a, b) => (a > b ? -1 : 1));\n\nexport const joinWords = (...words: string[]) => {\n return words\n .slice(1)\n .reduce(\n (acc, word) => acc + word[0].toUpperCase() + word.slice(1),\n words[0],\n );\n};\n\nexport const joinColumns = (columns: string[]) => {\n return columns.map((column) => `\"${column}\"`).join(', ');\n};\n","import { Adapter, AdapterOptions, MaybeArray, toArray } from 'pqb';\nimport {\n getDatabaseAndUserFromOptions,\n setAdminCredentialsToOptions,\n setAdapterOptions,\n createSchemaMigrations,\n MigrationConfig,\n migrationConfigDefaults,\n} from '../common';\n\nconst execute = async (\n options: AdapterOptions,\n sql: string,\n): Promise<'ok' | 'already' | 'forbidden' | { error: unknown }> => {\n const db = new Adapter(options);\n try {\n await db.query(sql);\n return 'ok';\n } catch (error) {\n const err = error as Record<string, unknown>;\n if (err.code === '42P04' || err.code === '3D000') {\n return 'already';\n } else if (err.code === '42501') {\n return 'forbidden';\n } else {\n return { error };\n }\n } finally {\n await db.destroy();\n }\n};\n\nconst createOrDrop = async (\n options: AdapterOptions,\n adminOptions: AdapterOptions,\n config: MigrationConfig,\n args: {\n sql(params: { database: string; user: string }): string;\n successMessage(params: { database: string }): string;\n alreadyMessage(params: { database: string }): string;\n createVersionsTable?: boolean;\n },\n) => {\n const params = getDatabaseAndUserFromOptions(options);\n\n const result = await execute(\n setAdapterOptions(adminOptions, { database: 'postgres' }),\n args.sql(params),\n );\n if (result === 'ok') {\n console.log(args.successMessage(params));\n } else if (result === 'already') {\n console.log(args.alreadyMessage(params));\n } else if (result === 'forbidden') {\n await createOrDrop(\n options,\n await setAdminCredentialsToOptions(options),\n config,\n args,\n );\n return;\n } else {\n throw result.error;\n }\n\n if (!args.createVersionsTable) return;\n\n const db = new Adapter(options);\n await createSchemaMigrations(db, config);\n await db.destroy();\n};\n\nexport const createDb = async (\n arg: MaybeArray<AdapterOptions>,\n config: MigrationConfig,\n) => {\n for (const options of toArray(arg)) {\n await createOrDrop(options, options, config, {\n sql({ database, user }) {\n return `CREATE DATABASE \"${database}\" OWNER \"${user}\"`;\n },\n successMessage({ database }) {\n return `Database ${database} successfully created`;\n },\n alreadyMessage({ database }) {\n return `Database ${database} already exists`;\n },\n createVersionsTable: true,\n });\n }\n};\n\nexport const dropDb = async (arg: MaybeArray<AdapterOptions>) => {\n for (const options of toArray(arg)) {\n await createOrDrop(options, options, migrationConfigDefaults, {\n sql({ database }) {\n return `DROP DATABASE \"${database}\"`;\n },\n successMessage({ database }) {\n return `Database ${database} was successfully dropped`;\n },\n alreadyMessage({ database }) {\n return `Database ${database} does not exist`;\n },\n });\n }\n};\n","import { Migration } from './migration';\n\nlet currentMigration: Migration | undefined;\nlet currentPromise: Promise<void> | undefined;\nlet currentUp = true;\n\nexport const change = (fn: (db: Migration, up: boolean) => Promise<void>) => {\n if (!currentMigration) throw new Error('Database instance is not set');\n currentPromise = fn(currentMigration, currentUp);\n};\n\nexport const setCurrentMigration = (db: Migration) => {\n currentMigration = db;\n};\n\nexport const setCurrentMigrationUp = (up: boolean) => {\n currentUp = up;\n};\n\nexport const getCurrentPromise = () => currentPromise;\n"],"names":["path"],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,201 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var pqb = require('pqb');
6
+ var Enquirer = require('enquirer');
7
+ var path = require('path');
8
+ require('fs/promises');
9
+
10
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
11
+
12
+ var Enquirer__default = /*#__PURE__*/_interopDefaultLegacy(Enquirer);
13
+ var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
14
+
15
+ var __defProp = Object.defineProperty;
16
+ var __defProps = Object.defineProperties;
17
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
18
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
19
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
20
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
21
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
22
+ var __spreadValues = (a, b) => {
23
+ for (var prop in b || (b = {}))
24
+ if (__hasOwnProp.call(b, prop))
25
+ __defNormalProp(a, prop, b[prop]);
26
+ if (__getOwnPropSymbols)
27
+ for (var prop of __getOwnPropSymbols(b)) {
28
+ if (__propIsEnum.call(b, prop))
29
+ __defNormalProp(a, prop, b[prop]);
30
+ }
31
+ return a;
32
+ };
33
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
34
+ const migrationConfigDefaults = {
35
+ migrationsPath: path__default["default"].resolve(process.cwd(), "src", "migrations"),
36
+ migrationsTable: "schemaMigrations",
37
+ requireTs(path2) {
38
+ {
39
+ require("ts-node").register({ compilerOptions: { module: "CommonJS" } });
40
+ }
41
+ require(path2);
42
+ }
43
+ };
44
+ const getDatabaseAndUserFromOptions = (options) => {
45
+ if (options.connectionString) {
46
+ const url = new URL(options.connectionString);
47
+ return {
48
+ database: url.pathname.slice(1),
49
+ user: url.username
50
+ };
51
+ } else {
52
+ return {
53
+ database: options.database,
54
+ user: options.user
55
+ };
56
+ }
57
+ };
58
+ const setAdapterOptions = (options, set) => {
59
+ if (options.connectionString) {
60
+ const url = new URL(options.connectionString);
61
+ if ("database" in set) {
62
+ url.pathname = `/${set.database}`;
63
+ }
64
+ if (set.user !== void 0) {
65
+ url.username = set.user;
66
+ }
67
+ if (set.password !== void 0) {
68
+ url.password = set.password;
69
+ }
70
+ return __spreadProps(__spreadValues({}, options), { connectionString: url.toString() });
71
+ } else {
72
+ return __spreadValues(__spreadValues({}, options), set);
73
+ }
74
+ };
75
+ const askAdminCredentials = async () => {
76
+ const prompt = new Enquirer__default["default"].Snippet({
77
+ message: `What are postgres admin login and password?`,
78
+ fields: [
79
+ {
80
+ name: "user",
81
+ required: true
82
+ },
83
+ {
84
+ name: "password"
85
+ }
86
+ ],
87
+ values: {
88
+ user: "postgres",
89
+ password: ""
90
+ },
91
+ template: "Admin user: {{user}}\nAdmin password: {{password}}"
92
+ });
93
+ const { values } = await prompt.run();
94
+ if (!values.password)
95
+ values.password = "";
96
+ return values;
97
+ };
98
+ const setAdminCredentialsToOptions = async (options) => {
99
+ const values = await askAdminCredentials();
100
+ return setAdapterOptions(options, values);
101
+ };
102
+ const createSchemaMigrations = async (db, config) => {
103
+ try {
104
+ await db.query(
105
+ `CREATE TABLE "${config.migrationsTable}" ( version TEXT NOT NULL )`
106
+ );
107
+ console.log("Created versions table");
108
+ } catch (err) {
109
+ if (err.code === "42P07") {
110
+ console.log("Versions table exists");
111
+ } else {
112
+ throw err;
113
+ }
114
+ }
115
+ };
116
+
117
+ const execute = async (options, sql) => {
118
+ const db = new pqb.Adapter(options);
119
+ try {
120
+ await db.query(sql);
121
+ return "ok";
122
+ } catch (error) {
123
+ const err = error;
124
+ if (err.code === "42P04" || err.code === "3D000") {
125
+ return "already";
126
+ } else if (err.code === "42501") {
127
+ return "forbidden";
128
+ } else {
129
+ return { error };
130
+ }
131
+ } finally {
132
+ await db.destroy();
133
+ }
134
+ };
135
+ const createOrDrop = async (options, adminOptions, config, args) => {
136
+ const params = getDatabaseAndUserFromOptions(options);
137
+ const result = await execute(
138
+ setAdapterOptions(adminOptions, { database: "postgres" }),
139
+ args.sql(params)
140
+ );
141
+ if (result === "ok") {
142
+ console.log(args.successMessage(params));
143
+ } else if (result === "already") {
144
+ console.log(args.alreadyMessage(params));
145
+ } else if (result === "forbidden") {
146
+ await createOrDrop(
147
+ options,
148
+ await setAdminCredentialsToOptions(options),
149
+ config,
150
+ args
151
+ );
152
+ return;
153
+ } else {
154
+ throw result.error;
155
+ }
156
+ if (!args.createVersionsTable)
157
+ return;
158
+ const db = new pqb.Adapter(options);
159
+ await createSchemaMigrations(db, config);
160
+ await db.destroy();
161
+ };
162
+ const createDb = async (arg, config) => {
163
+ for (const options of pqb.toArray(arg)) {
164
+ await createOrDrop(options, options, config, {
165
+ sql({ database, user }) {
166
+ return `CREATE DATABASE "${database}" OWNER "${user}"`;
167
+ },
168
+ successMessage({ database }) {
169
+ return `Database ${database} successfully created`;
170
+ },
171
+ alreadyMessage({ database }) {
172
+ return `Database ${database} already exists`;
173
+ },
174
+ createVersionsTable: true
175
+ });
176
+ }
177
+ };
178
+ const dropDb = async (arg) => {
179
+ for (const options of pqb.toArray(arg)) {
180
+ await createOrDrop(options, options, migrationConfigDefaults, {
181
+ sql({ database }) {
182
+ return `DROP DATABASE "${database}"`;
183
+ },
184
+ successMessage({ database }) {
185
+ return `Database ${database} was successfully dropped`;
186
+ },
187
+ alreadyMessage({ database }) {
188
+ return `Database ${database} does not exist`;
189
+ }
190
+ });
191
+ }
192
+ };
193
+
194
+ const change = (fn) => {
195
+ throw new Error("Database instance is not set");
196
+ };
197
+
198
+ exports.change = change;
199
+ exports.createDb = createDb;
200
+ exports.dropDb = dropDb;
201
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/common.ts","../src/commands/createOrDrop.ts","../src/migration/change.ts"],"sourcesContent":["import { Adapter, AdapterOptions } from 'pqb';\nimport Enquirer from 'enquirer';\nimport path from 'path';\nimport { readdir } from 'fs/promises';\n\nexport type MigrationConfig = {\n migrationsPath: string;\n migrationsTable: string;\n requireTs(path: string): void;\n};\n\nconst registered = false;\n\nexport const migrationConfigDefaults = {\n migrationsPath: path.resolve(process.cwd(), 'src', 'migrations'),\n migrationsTable: 'schemaMigrations',\n requireTs(path: string) {\n if (!registered) {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n require('ts-node').register({ compilerOptions: { module: 'CommonJS' } });\n }\n require(path);\n },\n};\n\nexport const getMigrationConfigWithDefaults = (\n config: Partial<MigrationConfig>,\n) => {\n return { ...migrationConfigDefaults, ...config };\n};\n\nexport const getDatabaseAndUserFromOptions = (\n options: AdapterOptions,\n): { database: string; user: string } => {\n if (options.connectionString) {\n const url = new URL(options.connectionString);\n return {\n database: url.pathname.slice(1),\n user: url.username,\n };\n } else {\n return {\n database: options.database as string,\n user: options.user as string,\n };\n }\n};\n\nexport const setAdapterOptions = (\n options: AdapterOptions,\n set: { database?: string; user?: string; password?: string },\n): AdapterOptions => {\n if (options.connectionString) {\n const url = new URL(options.connectionString);\n\n if ('database' in set) {\n url.pathname = `/${set.database}`;\n }\n\n if (set.user !== undefined) {\n url.username = set.user;\n }\n\n if (set.password !== undefined) {\n url.password = set.password;\n }\n\n return { ...options, connectionString: url.toString() };\n } else {\n return {\n ...options,\n ...set,\n };\n }\n};\n\nconst askAdminCredentials = async (): Promise<{\n user: string;\n password: string;\n}> => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const prompt = new (Enquirer as any).Snippet({\n message: `What are postgres admin login and password?`,\n fields: [\n {\n name: 'user',\n required: true,\n },\n {\n name: 'password',\n },\n ],\n values: {\n user: 'postgres',\n password: '',\n },\n template: 'Admin user: {{user}}\\nAdmin password: {{password}}',\n });\n\n const { values } = await prompt.run();\n if (!values.password) values.password = '';\n\n return values;\n};\n\nexport const setAdminCredentialsToOptions = async (\n options: AdapterOptions,\n): Promise<AdapterOptions> => {\n const values = await askAdminCredentials();\n return setAdapterOptions(options, values);\n};\n\nexport const createSchemaMigrations = async (\n db: Adapter,\n config: MigrationConfig,\n) => {\n try {\n await db.query(\n `CREATE TABLE \"${config.migrationsTable}\" ( version TEXT NOT NULL )`,\n );\n console.log('Created versions table');\n } catch (err) {\n if ((err as Record<string, unknown>).code === '42P07') {\n console.log('Versions table exists');\n } else {\n throw err;\n }\n }\n};\n\nexport const getFirstWordAndRest = (\n input: string,\n): [string] | [string, string] => {\n const index = input.search(/(?=[A-Z])|[-_]/);\n if (index !== -1) {\n const restStart =\n input[index] === '-' || input[index] === '_' ? index + 1 : index;\n const rest = input.slice(restStart);\n return [input.slice(0, index), rest[0].toLowerCase() + rest.slice(1)];\n } else {\n return [input];\n }\n};\n\nconst getTextAfterRegExp = (\n input: string,\n regex: RegExp,\n length: number,\n): string | undefined => {\n let index = input.search(regex);\n if (index === -1) return;\n\n if (input[index] === '-' || input[index] === '_') index++;\n index += length;\n\n const start = input[index] == '-' || input[index] === '_' ? index + 1 : index;\n const text = input.slice(start);\n return text[0].toLowerCase() + text.slice(1);\n};\n\nexport const getTextAfterTo = (input: string): string | undefined => {\n return getTextAfterRegExp(input, /(To|-to|_to)[A-Z-_]/, 2);\n};\n\nexport const getTextAfterFrom = (input: string): string | undefined => {\n return getTextAfterRegExp(input, /(From|-from|_from)[A-Z-_]/, 4);\n};\n\nexport type MigrationFile = {\n path: string;\n version: string;\n};\n\nexport const getMigrationFiles = async (\n config: MigrationConfig,\n up: boolean,\n): Promise<MigrationFile[]> => {\n const { migrationsPath } = config;\n\n let files: string[];\n try {\n files = await readdir(migrationsPath);\n } catch (_) {\n return [];\n }\n\n const sort = up ? sortAsc : sortDesc;\n return sort(files).map((file) => {\n if (!file.endsWith('.ts')) {\n throw new Error(\n `Only .ts files are supported for migration, received: ${file}`,\n );\n }\n\n const timestampMatch = file.match(/^(\\d{14})\\D/);\n if (!timestampMatch) {\n throw new Error(\n `Migration file name should start with 14 digit version, received ${file}`,\n );\n }\n\n return {\n path: path.join(migrationsPath, file),\n version: timestampMatch[1],\n };\n });\n};\n\nexport const sortAsc = (arr: string[]) => arr.sort();\n\nexport const sortDesc = (arr: string[]) => arr.sort((a, b) => (a > b ? -1 : 1));\n\nexport const joinWords = (...words: string[]) => {\n return words\n .slice(1)\n .reduce(\n (acc, word) => acc + word[0].toUpperCase() + word.slice(1),\n words[0],\n );\n};\n\nexport const joinColumns = (columns: string[]) => {\n return columns.map((column) => `\"${column}\"`).join(', ');\n};\n","import { Adapter, AdapterOptions, MaybeArray, toArray } from 'pqb';\nimport {\n getDatabaseAndUserFromOptions,\n setAdminCredentialsToOptions,\n setAdapterOptions,\n createSchemaMigrations,\n MigrationConfig,\n migrationConfigDefaults,\n} from '../common';\n\nconst execute = async (\n options: AdapterOptions,\n sql: string,\n): Promise<'ok' | 'already' | 'forbidden' | { error: unknown }> => {\n const db = new Adapter(options);\n try {\n await db.query(sql);\n return 'ok';\n } catch (error) {\n const err = error as Record<string, unknown>;\n if (err.code === '42P04' || err.code === '3D000') {\n return 'already';\n } else if (err.code === '42501') {\n return 'forbidden';\n } else {\n return { error };\n }\n } finally {\n await db.destroy();\n }\n};\n\nconst createOrDrop = async (\n options: AdapterOptions,\n adminOptions: AdapterOptions,\n config: MigrationConfig,\n args: {\n sql(params: { database: string; user: string }): string;\n successMessage(params: { database: string }): string;\n alreadyMessage(params: { database: string }): string;\n createVersionsTable?: boolean;\n },\n) => {\n const params = getDatabaseAndUserFromOptions(options);\n\n const result = await execute(\n setAdapterOptions(adminOptions, { database: 'postgres' }),\n args.sql(params),\n );\n if (result === 'ok') {\n console.log(args.successMessage(params));\n } else if (result === 'already') {\n console.log(args.alreadyMessage(params));\n } else if (result === 'forbidden') {\n await createOrDrop(\n options,\n await setAdminCredentialsToOptions(options),\n config,\n args,\n );\n return;\n } else {\n throw result.error;\n }\n\n if (!args.createVersionsTable) return;\n\n const db = new Adapter(options);\n await createSchemaMigrations(db, config);\n await db.destroy();\n};\n\nexport const createDb = async (\n arg: MaybeArray<AdapterOptions>,\n config: MigrationConfig,\n) => {\n for (const options of toArray(arg)) {\n await createOrDrop(options, options, config, {\n sql({ database, user }) {\n return `CREATE DATABASE \"${database}\" OWNER \"${user}\"`;\n },\n successMessage({ database }) {\n return `Database ${database} successfully created`;\n },\n alreadyMessage({ database }) {\n return `Database ${database} already exists`;\n },\n createVersionsTable: true,\n });\n }\n};\n\nexport const dropDb = async (arg: MaybeArray<AdapterOptions>) => {\n for (const options of toArray(arg)) {\n await createOrDrop(options, options, migrationConfigDefaults, {\n sql({ database }) {\n return `DROP DATABASE \"${database}\"`;\n },\n successMessage({ database }) {\n return `Database ${database} was successfully dropped`;\n },\n alreadyMessage({ database }) {\n return `Database ${database} does not exist`;\n },\n });\n }\n};\n","import { Migration } from './migration';\n\nlet currentMigration: Migration | undefined;\nlet currentPromise: Promise<void> | undefined;\nlet currentUp = true;\n\nexport const change = (fn: (db: Migration, up: boolean) => Promise<void>) => {\n if (!currentMigration) throw new Error('Database instance is not set');\n currentPromise = fn(currentMigration, currentUp);\n};\n\nexport const setCurrentMigration = (db: Migration) => {\n currentMigration = db;\n};\n\nexport const setCurrentMigrationUp = (up: boolean) => {\n currentUp = up;\n};\n\nexport const getCurrentPromise = () => currentPromise;\n"],"names":["path","Enquirer","Adapter","toArray"],"mappings":"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"}
package/jest-setup.ts ADDED
@@ -0,0 +1,3 @@
1
+ jest.mock('pqb', () => require('../pqb/src'), {
2
+ virtual: true,
3
+ });
@@ -0,0 +1,8 @@
1
+ import { change } from '../src';
2
+
3
+ change(async (db) => {
4
+ await db.createTable('first', (t) => ({
5
+ id: t.integer().primaryKey(),
6
+ name: t.text(),
7
+ }));
8
+ });
@@ -0,0 +1,5 @@
1
+ import { change } from '../src';
2
+
3
+ change(async () => {
4
+ console.log('second');
5
+ });
package/package.json CHANGED
@@ -1,53 +1,67 @@
1
1
  {
2
2
  "name": "rake-db",
3
- "version": "1.3.2",
4
- "description": "Postgresql migrations like in Ruby on Rails",
5
- "bin": {
6
- "rake-db": "dist/rake-db.js"
3
+ "version": "2.0.0",
4
+ "description": "Migrations tools for Postgresql DB",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/romeerez/porm"
8
+ },
9
+ "main": "dist/index.js",
10
+ "module": "dist/index.esm.js",
11
+ "typings": "dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "require": "./dist/index.js",
15
+ "import": "./dist/index.esm.js",
16
+ "types": "./dist/index.d.ts"
17
+ }
18
+ },
19
+ "jest": {
20
+ "setupFiles": [
21
+ "dotenv/config"
22
+ ],
23
+ "globalSetup": "../../jest-global-setup.ts",
24
+ "setupFilesAfterEnv": [
25
+ "../../jest-setup.ts",
26
+ "./jest-setup.ts"
27
+ ],
28
+ "transform": {
29
+ "^.+\\.ts$": "@swc/jest"
30
+ }
7
31
  },
8
- "main": "dist/rake-db.js",
9
- "files": [
10
- "dist"
11
- ],
12
- "repository": "https://github.com/romeerez/rake-db.js",
13
- "author": "Roman Kushyn",
14
- "license": "MIT",
15
32
  "keywords": [
16
- "postgres",
17
33
  "postgresql",
18
- "migrate",
34
+ "postgres",
35
+ "pg",
19
36
  "migrations",
20
- "rails"
37
+ "migration"
21
38
  ],
22
- "scripts": {
23
- "start": "tsc --watch",
24
- "build": "tsc",
25
- "prepublish": "tsc",
26
- "db": "ts-node src/rake-db.ts",
27
- "lint": "eslint --fix src",
28
- "test": "jest"
39
+ "author": "Roman Kushyn",
40
+ "license": "ISC",
41
+ "dependencies": {
42
+ "pqb": "0.0.1",
43
+ "enquirer": "^2.3.6",
44
+ "pluralize": "^8.0.0"
29
45
  },
30
46
  "devDependencies": {
31
- "@types/jest": "^25.2.1",
32
- "@types/node": "^14.0.13",
33
47
  "@types/pluralize": "^0.0.29",
34
- "@typescript-eslint/eslint-plugin": "^4.9.0",
35
- "@typescript-eslint/parser": "^4.9.0",
36
- "eslint": "^7.14.0",
37
- "eslint-config-prettier": "^6.15.0",
38
- "eslint-plugin-prettier": "^3.1.4",
39
- "jest": "^25.1.0",
40
- "prettier": "^2.2.1",
41
- "ts-jest": "^26.4.0",
42
- "typescript": "^4.0.3"
48
+ "ts-node": "^10.9.1",
49
+ "dotenv": "^16.0.3",
50
+ "rollup": "^2.79.0",
51
+ "rollup-plugin-dts": "^4.2.2",
52
+ "rollup-plugin-esbuild": "^4.10.1",
53
+ "@swc/core": "^1.2.210",
54
+ "@swc/jest": "^0.2.21",
55
+ "@types/jest": "^28.1.2",
56
+ "@types/node": "^18.0.1",
57
+ "jest": "^28.1.2",
58
+ "rimraf": "^3.0.2",
59
+ "tslib": "^2.4.0",
60
+ "typescript": "^4.7.4"
43
61
  },
44
- "dependencies": {
45
- "dotenv": "^16.0.1",
46
- "enquirer": "^2.3.6",
47
- "pg-adapter": "^1.2.5"
48
- },
49
- "peerDependencies": {
50
- "ts-node": "*",
51
- "typescript": "*"
62
+ "scripts": {
63
+ "db": "ts-node db.ts",
64
+ "test": "jest",
65
+ "build": "rimraf ./dist/ && rollup -c --rollup.config"
52
66
  }
53
- }
67
+ }
@@ -0,0 +1,3 @@
1
+ import config from '../../rollup.config';
2
+
3
+ export default config;