@hedystia/db 2.0.6 → 2.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.
Files changed (67) hide show
  1. package/dist/cache/index.mjs +12 -0
  2. package/dist/cache/index.mjs.map +1 -0
  3. package/dist/cache/manager.mjs +156 -153
  4. package/dist/cache/manager.mjs.map +1 -1
  5. package/dist/cache/memory-store.mjs +113 -111
  6. package/dist/cache/memory-store.mjs.map +1 -1
  7. package/dist/cli/commands/migrate.cjs +78 -0
  8. package/dist/cli/commands/migrate.cjs.map +1 -0
  9. package/dist/cli/commands/migrate.mjs +83 -0
  10. package/dist/cli/commands/migrate.mjs.map +1 -0
  11. package/dist/cli/commands/migration.cjs +3 -2
  12. package/dist/cli/commands/migration.cjs.map +1 -1
  13. package/dist/cli/commands/migration.mjs +4 -3
  14. package/dist/cli/commands/migration.mjs.map +1 -1
  15. package/dist/cli.cjs +44 -5
  16. package/dist/cli.cjs.map +1 -1
  17. package/dist/cli.mjs +45 -5
  18. package/dist/cli.mjs.map +1 -1
  19. package/dist/core/database.cjs +75 -29
  20. package/dist/core/database.cjs.map +1 -1
  21. package/dist/core/database.d.cts +11 -0
  22. package/dist/core/database.d.mts +11 -0
  23. package/dist/core/database.mjs +91 -34
  24. package/dist/core/database.mjs.map +1 -1
  25. package/dist/core/repository.mjs +414 -410
  26. package/dist/core/repository.mjs.map +1 -1
  27. package/dist/drivers/driver.mjs +9 -7
  28. package/dist/drivers/driver.mjs.map +1 -1
  29. package/dist/drivers/file.mjs +315 -312
  30. package/dist/drivers/file.mjs.map +1 -1
  31. package/dist/drivers/index.mjs +15 -6
  32. package/dist/drivers/index.mjs.map +1 -1
  33. package/dist/drivers/mysql.mjs +261 -256
  34. package/dist/drivers/mysql.mjs.map +1 -1
  35. package/dist/drivers/sql-compiler.mjs +4 -1
  36. package/dist/drivers/sql-compiler.mjs.map +1 -1
  37. package/dist/drivers/sqlite.cjs +12 -1
  38. package/dist/drivers/sqlite.cjs.map +1 -1
  39. package/dist/drivers/sqlite.mjs +258 -242
  40. package/dist/drivers/sqlite.mjs.map +1 -1
  41. package/dist/errors.mjs +48 -64
  42. package/dist/errors.mjs.map +1 -1
  43. package/dist/index.mjs +21 -9
  44. package/dist/index.mjs.map +1 -1
  45. package/dist/migrations/templates.cjs +4 -3
  46. package/dist/migrations/templates.cjs.map +1 -1
  47. package/dist/migrations/templates.d.cts +3 -2
  48. package/dist/migrations/templates.d.mts +3 -2
  49. package/dist/migrations/templates.mjs +4 -3
  50. package/dist/migrations/templates.mjs.map +1 -1
  51. package/dist/schema/column.mjs +155 -157
  52. package/dist/schema/column.mjs.map +1 -1
  53. package/dist/schema/columns/index.mjs +103 -171
  54. package/dist/schema/columns/index.mjs.map +1 -1
  55. package/dist/schema/index.mjs +15 -0
  56. package/dist/schema/index.mjs.map +1 -0
  57. package/dist/schema/registry.mjs +122 -119
  58. package/dist/schema/registry.mjs.map +1 -1
  59. package/dist/schema/table.mjs +4 -1
  60. package/dist/schema/table.mjs.map +1 -1
  61. package/dist/sync/synchronizer.mjs +2 -1
  62. package/dist/sync/synchronizer.mjs.map +1 -1
  63. package/dist/utils/naming.cjs +9 -0
  64. package/dist/utils/naming.cjs.map +1 -1
  65. package/dist/utils/naming.mjs +9 -1
  66. package/dist/utils/naming.mjs.map +1 -1
  67. package/package.json +1 -1
@@ -0,0 +1,78 @@
1
+ require("../../constants.cjs");
2
+ const require_database = require("../../core/database.cjs");
3
+ let path = require("path");
4
+ let url = require("url");
5
+ //#region src/cli/commands/migrate.ts
6
+ async function loadModules(dir) {
7
+ const fs = await import("fs");
8
+ const path$1 = await import("path");
9
+ const absDir = (0, path.resolve)(dir);
10
+ if (!fs.existsSync(absDir)) return {};
11
+ const files = fs.readdirSync(absDir).filter((f) => /\.(ts|js|mjs|cjs)$/.test(f));
12
+ const modules = {};
13
+ for (const file of files) {
14
+ const mod = await import((0, url.pathToFileURL)(path$1.join(absDir, file)).href);
15
+ const key = path$1.basename(file, path$1.extname(file));
16
+ if (mod.default) modules[key] = mod.default;
17
+ for (const [k, v] of Object.entries(mod)) if (k !== "default") modules[k] = v;
18
+ }
19
+ return modules;
20
+ }
21
+ function parseConnection(connStr) {
22
+ if (connStr.endsWith(".db") || connStr.endsWith(".sqlite") || connStr.endsWith(".sqlite3")) return { filename: connStr };
23
+ try {
24
+ return JSON.parse(connStr);
25
+ } catch {
26
+ return { filename: connStr };
27
+ }
28
+ }
29
+ async function createDbInstance(options) {
30
+ const migrationsPath = options.migrationsPath ?? "src/database/migrations";
31
+ const schemasPath = options.schemasPath ?? "src/database/schemas";
32
+ const dbType = options.database ?? "sqlite";
33
+ const migrations = await loadModules(migrationsPath);
34
+ const db = require_database.database({
35
+ schemas: await loadModules(schemasPath),
36
+ migrations,
37
+ database: dbType,
38
+ connection: options.connection ? parseConnection(options.connection) : { filename: "./database.db" },
39
+ cache: false,
40
+ runMigrations: false
41
+ });
42
+ await db.initialize();
43
+ return db;
44
+ }
45
+ /**
46
+ * Run pending migrations
47
+ */
48
+ async function migrateUp(options) {
49
+ const db = await createDbInstance(options);
50
+ try {
51
+ await db.migrateUp();
52
+ console.log("Migrations applied successfully");
53
+ } finally {
54
+ await db.close();
55
+ }
56
+ }
57
+ /**
58
+ * Rollback migrations
59
+ */
60
+ async function migrateDown(options) {
61
+ const db = await createDbInstance(options);
62
+ try {
63
+ const steps = options.steps ?? 1;
64
+ const rolledBack = await db.migrateDown(steps);
65
+ if (rolledBack.length === 0) console.log("No migrations to rollback");
66
+ else {
67
+ for (const name of rolledBack) console.log(` Rolled back: ${name}`);
68
+ console.log(`Rolled back ${rolledBack.length} migration(s)`);
69
+ }
70
+ } finally {
71
+ await db.close();
72
+ }
73
+ }
74
+ //#endregion
75
+ exports.migrateDown = migrateDown;
76
+ exports.migrateUp = migrateUp;
77
+
78
+ //# sourceMappingURL=migrate.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.cjs","names":["path","database"],"sources":["../../../src/cli/commands/migrate.ts"],"sourcesContent":["import { resolve } from \"path\";\nimport { pathToFileURL } from \"url\";\nimport { DEFAULT_MIGRATIONS_PATH, DEFAULT_SCHEMAS_PATH } from \"../../constants\";\nimport { database } from \"../../core/database\";\n\ninterface MigrateOptions {\n config?: string;\n migrationsPath?: string;\n schemasPath?: string;\n database?: string;\n connection?: string;\n steps?: number;\n}\n\nasync function loadModules(dir: string): Promise<Record<string, unknown>> {\n const fs = await import(\"fs\");\n const path = await import(\"path\");\n\n const absDir = resolve(dir);\n if (!fs.existsSync(absDir)) {\n return {};\n }\n\n const files = fs.readdirSync(absDir).filter((f: string) => /\\.(ts|js|mjs|cjs)$/.test(f));\n const modules: Record<string, unknown> = {};\n\n for (const file of files) {\n const filePath = path.join(absDir, file);\n const fileUrl = pathToFileURL(filePath).href;\n const mod = await import(fileUrl);\n const key = path.basename(file, path.extname(file));\n if (mod.default) {\n modules[key] = mod.default;\n }\n for (const [k, v] of Object.entries(mod)) {\n if (k !== \"default\") {\n modules[k] = v;\n }\n }\n }\n\n return modules;\n}\n\nfunction parseConnection(connStr: string): Record<string, unknown> {\n if (connStr.endsWith(\".db\") || connStr.endsWith(\".sqlite\") || connStr.endsWith(\".sqlite3\")) {\n return { filename: connStr };\n }\n try {\n return JSON.parse(connStr);\n } catch {\n return { filename: connStr };\n }\n}\n\nasync function createDbInstance(options: MigrateOptions) {\n const migrationsPath = options.migrationsPath ?? DEFAULT_MIGRATIONS_PATH;\n const schemasPath = options.schemasPath ?? DEFAULT_SCHEMAS_PATH;\n const dbType = options.database ?? \"sqlite\";\n\n const migrations = await loadModules(migrationsPath);\n const schemas = await loadModules(schemasPath);\n\n const connection = options.connection\n ? parseConnection(options.connection)\n : { filename: \"./database.db\" };\n\n const db = database({\n schemas,\n migrations,\n database: dbType as any,\n connection: connection as any,\n cache: false,\n runMigrations: false,\n });\n\n await db.initialize();\n return db;\n}\n\n/**\n * Run pending migrations\n */\nexport async function migrateUp(options: MigrateOptions): Promise<void> {\n const db = await createDbInstance(options);\n try {\n await db.migrateUp();\n console.log(\"Migrations applied successfully\");\n } finally {\n await db.close();\n }\n}\n\n/**\n * Rollback migrations\n */\nexport async function migrateDown(options: MigrateOptions): Promise<void> {\n const db = await createDbInstance(options);\n try {\n const steps = options.steps ?? 1;\n const rolledBack = await db.migrateDown(steps);\n if (rolledBack.length === 0) {\n console.log(\"No migrations to rollback\");\n } else {\n for (const name of rolledBack) {\n console.log(` Rolled back: ${name}`);\n }\n console.log(`Rolled back ${rolledBack.length} migration(s)`);\n }\n } finally {\n await db.close();\n }\n}\n"],"mappings":";;;;;AAcA,eAAe,YAAY,KAA+C;CACxE,MAAM,KAAK,MAAM,OAAO;CACxB,MAAMA,SAAO,MAAM,OAAO;CAE1B,MAAM,UAAA,GAAA,KAAA,SAAiB,IAAI;AAC3B,KAAI,CAAC,GAAG,WAAW,OAAO,CACxB,QAAO,EAAE;CAGX,MAAM,QAAQ,GAAG,YAAY,OAAO,CAAC,QAAQ,MAAc,qBAAqB,KAAK,EAAE,CAAC;CACxF,MAAM,UAAmC,EAAE;AAE3C,MAAK,MAAM,QAAQ,OAAO;EAGxB,MAAM,MAAM,MAAM,QAAA,GAAA,IAAA,eAFDA,OAAK,KAAK,QAAQ,KAAK,CACD,CAAC;EAExC,MAAM,MAAMA,OAAK,SAAS,MAAMA,OAAK,QAAQ,KAAK,CAAC;AACnD,MAAI,IAAI,QACN,SAAQ,OAAO,IAAI;AAErB,OAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,IAAI,CACtC,KAAI,MAAM,UACR,SAAQ,KAAK;;AAKnB,QAAO;;AAGT,SAAS,gBAAgB,SAA0C;AACjE,KAAI,QAAQ,SAAS,MAAM,IAAI,QAAQ,SAAS,UAAU,IAAI,QAAQ,SAAS,WAAW,CACxF,QAAO,EAAE,UAAU,SAAS;AAE9B,KAAI;AACF,SAAO,KAAK,MAAM,QAAQ;SACpB;AACN,SAAO,EAAE,UAAU,SAAS;;;AAIhC,eAAe,iBAAiB,SAAyB;CACvD,MAAM,iBAAiB,QAAQ,kBAAA;CAC/B,MAAM,cAAc,QAAQ,eAAA;CAC5B,MAAM,SAAS,QAAQ,YAAY;CAEnC,MAAM,aAAa,MAAM,YAAY,eAAe;CAOpD,MAAM,KAAKC,iBAAAA,SAAS;EAClB,SAPc,MAAM,YAAY,YAAY;EAQ5C;EACA,UAAU;EACV,YARiB,QAAQ,aACvB,gBAAgB,QAAQ,WAAW,GACnC,EAAE,UAAU,iBAAiB;EAO/B,OAAO;EACP,eAAe;EAChB,CAAC;AAEF,OAAM,GAAG,YAAY;AACrB,QAAO;;;;;AAMT,eAAsB,UAAU,SAAwC;CACtE,MAAM,KAAK,MAAM,iBAAiB,QAAQ;AAC1C,KAAI;AACF,QAAM,GAAG,WAAW;AACpB,UAAQ,IAAI,kCAAkC;WACtC;AACR,QAAM,GAAG,OAAO;;;;;;AAOpB,eAAsB,YAAY,SAAwC;CACxE,MAAM,KAAK,MAAM,iBAAiB,QAAQ;AAC1C,KAAI;EACF,MAAM,QAAQ,QAAQ,SAAS;EAC/B,MAAM,aAAa,MAAM,GAAG,YAAY,MAAM;AAC9C,MAAI,WAAW,WAAW,EACxB,SAAQ,IAAI,4BAA4B;OACnC;AACL,QAAK,MAAM,QAAQ,WACjB,SAAQ,IAAI,kBAAkB,OAAO;AAEvC,WAAQ,IAAI,eAAe,WAAW,OAAO,eAAe;;WAEtD;AACR,QAAM,GAAG,OAAO"}
@@ -0,0 +1,83 @@
1
+ import { __esmMin } from "../../_virtual/_rolldown/runtime.mjs";
2
+ import { init_constants } from "../../constants.mjs";
3
+ import { database, init_database } from "../../core/database.mjs";
4
+ import { resolve } from "path";
5
+ import { pathToFileURL } from "url";
6
+ //#region src/cli/commands/migrate.ts
7
+ async function loadModules(dir) {
8
+ const fs = await import("fs");
9
+ const path = await import("path");
10
+ const absDir = resolve(dir);
11
+ if (!fs.existsSync(absDir)) return {};
12
+ const files = fs.readdirSync(absDir).filter((f) => /\.(ts|js|mjs|cjs)$/.test(f));
13
+ const modules = {};
14
+ for (const file of files) {
15
+ const mod = await import(pathToFileURL(path.join(absDir, file)).href);
16
+ const key = path.basename(file, path.extname(file));
17
+ if (mod.default) modules[key] = mod.default;
18
+ for (const [k, v] of Object.entries(mod)) if (k !== "default") modules[k] = v;
19
+ }
20
+ return modules;
21
+ }
22
+ function parseConnection(connStr) {
23
+ if (connStr.endsWith(".db") || connStr.endsWith(".sqlite") || connStr.endsWith(".sqlite3")) return { filename: connStr };
24
+ try {
25
+ return JSON.parse(connStr);
26
+ } catch {
27
+ return { filename: connStr };
28
+ }
29
+ }
30
+ async function createDbInstance(options) {
31
+ const migrationsPath = options.migrationsPath ?? "src/database/migrations";
32
+ const schemasPath = options.schemasPath ?? "src/database/schemas";
33
+ const dbType = options.database ?? "sqlite";
34
+ const migrations = await loadModules(migrationsPath);
35
+ const db = database({
36
+ schemas: await loadModules(schemasPath),
37
+ migrations,
38
+ database: dbType,
39
+ connection: options.connection ? parseConnection(options.connection) : { filename: "./database.db" },
40
+ cache: false,
41
+ runMigrations: false
42
+ });
43
+ await db.initialize();
44
+ return db;
45
+ }
46
+ /**
47
+ * Run pending migrations
48
+ */
49
+ async function migrateUp(options) {
50
+ const db = await createDbInstance(options);
51
+ try {
52
+ await db.migrateUp();
53
+ console.log("Migrations applied successfully");
54
+ } finally {
55
+ await db.close();
56
+ }
57
+ }
58
+ /**
59
+ * Rollback migrations
60
+ */
61
+ async function migrateDown(options) {
62
+ const db = await createDbInstance(options);
63
+ try {
64
+ const steps = options.steps ?? 1;
65
+ const rolledBack = await db.migrateDown(steps);
66
+ if (rolledBack.length === 0) console.log("No migrations to rollback");
67
+ else {
68
+ for (const name of rolledBack) console.log(` Rolled back: ${name}`);
69
+ console.log(`Rolled back ${rolledBack.length} migration(s)`);
70
+ }
71
+ } finally {
72
+ await db.close();
73
+ }
74
+ }
75
+ var init_migrate = __esmMin((() => {
76
+ init_constants();
77
+ init_database();
78
+ }));
79
+ //#endregion
80
+ init_migrate();
81
+ export { init_migrate, migrateDown, migrateUp };
82
+
83
+ //# sourceMappingURL=migrate.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.mjs","names":[],"sources":["../../../src/cli/commands/migrate.ts"],"sourcesContent":["import { resolve } from \"path\";\nimport { pathToFileURL } from \"url\";\nimport { DEFAULT_MIGRATIONS_PATH, DEFAULT_SCHEMAS_PATH } from \"../../constants\";\nimport { database } from \"../../core/database\";\n\ninterface MigrateOptions {\n config?: string;\n migrationsPath?: string;\n schemasPath?: string;\n database?: string;\n connection?: string;\n steps?: number;\n}\n\nasync function loadModules(dir: string): Promise<Record<string, unknown>> {\n const fs = await import(\"fs\");\n const path = await import(\"path\");\n\n const absDir = resolve(dir);\n if (!fs.existsSync(absDir)) {\n return {};\n }\n\n const files = fs.readdirSync(absDir).filter((f: string) => /\\.(ts|js|mjs|cjs)$/.test(f));\n const modules: Record<string, unknown> = {};\n\n for (const file of files) {\n const filePath = path.join(absDir, file);\n const fileUrl = pathToFileURL(filePath).href;\n const mod = await import(fileUrl);\n const key = path.basename(file, path.extname(file));\n if (mod.default) {\n modules[key] = mod.default;\n }\n for (const [k, v] of Object.entries(mod)) {\n if (k !== \"default\") {\n modules[k] = v;\n }\n }\n }\n\n return modules;\n}\n\nfunction parseConnection(connStr: string): Record<string, unknown> {\n if (connStr.endsWith(\".db\") || connStr.endsWith(\".sqlite\") || connStr.endsWith(\".sqlite3\")) {\n return { filename: connStr };\n }\n try {\n return JSON.parse(connStr);\n } catch {\n return { filename: connStr };\n }\n}\n\nasync function createDbInstance(options: MigrateOptions) {\n const migrationsPath = options.migrationsPath ?? DEFAULT_MIGRATIONS_PATH;\n const schemasPath = options.schemasPath ?? DEFAULT_SCHEMAS_PATH;\n const dbType = options.database ?? \"sqlite\";\n\n const migrations = await loadModules(migrationsPath);\n const schemas = await loadModules(schemasPath);\n\n const connection = options.connection\n ? parseConnection(options.connection)\n : { filename: \"./database.db\" };\n\n const db = database({\n schemas,\n migrations,\n database: dbType as any,\n connection: connection as any,\n cache: false,\n runMigrations: false,\n });\n\n await db.initialize();\n return db;\n}\n\n/**\n * Run pending migrations\n */\nexport async function migrateUp(options: MigrateOptions): Promise<void> {\n const db = await createDbInstance(options);\n try {\n await db.migrateUp();\n console.log(\"Migrations applied successfully\");\n } finally {\n await db.close();\n }\n}\n\n/**\n * Rollback migrations\n */\nexport async function migrateDown(options: MigrateOptions): Promise<void> {\n const db = await createDbInstance(options);\n try {\n const steps = options.steps ?? 1;\n const rolledBack = await db.migrateDown(steps);\n if (rolledBack.length === 0) {\n console.log(\"No migrations to rollback\");\n } else {\n for (const name of rolledBack) {\n console.log(` Rolled back: ${name}`);\n }\n console.log(`Rolled back ${rolledBack.length} migration(s)`);\n }\n } finally {\n await db.close();\n }\n}\n"],"mappings":";;;;;;AAcA,eAAe,YAAY,KAA+C;CACxE,MAAM,KAAK,MAAM,OAAO;CACxB,MAAM,OAAO,MAAM,OAAO;CAE1B,MAAM,SAAS,QAAQ,IAAI;AAC3B,KAAI,CAAC,GAAG,WAAW,OAAO,CACxB,QAAO,EAAE;CAGX,MAAM,QAAQ,GAAG,YAAY,OAAO,CAAC,QAAQ,MAAc,qBAAqB,KAAK,EAAE,CAAC;CACxF,MAAM,UAAmC,EAAE;AAE3C,MAAK,MAAM,QAAQ,OAAO;EAGxB,MAAM,MAAM,MAAM,OADF,cADC,KAAK,KAAK,QAAQ,KAAK,CACD,CAAC;EAExC,MAAM,MAAM,KAAK,SAAS,MAAM,KAAK,QAAQ,KAAK,CAAC;AACnD,MAAI,IAAI,QACN,SAAQ,OAAO,IAAI;AAErB,OAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,IAAI,CACtC,KAAI,MAAM,UACR,SAAQ,KAAK;;AAKnB,QAAO;;AAGT,SAAS,gBAAgB,SAA0C;AACjE,KAAI,QAAQ,SAAS,MAAM,IAAI,QAAQ,SAAS,UAAU,IAAI,QAAQ,SAAS,WAAW,CACxF,QAAO,EAAE,UAAU,SAAS;AAE9B,KAAI;AACF,SAAO,KAAK,MAAM,QAAQ;SACpB;AACN,SAAO,EAAE,UAAU,SAAS;;;AAIhC,eAAe,iBAAiB,SAAyB;CACvD,MAAM,iBAAiB,QAAQ,kBAAA;CAC/B,MAAM,cAAc,QAAQ,eAAA;CAC5B,MAAM,SAAS,QAAQ,YAAY;CAEnC,MAAM,aAAa,MAAM,YAAY,eAAe;CAOpD,MAAM,KAAK,SAAS;EAClB,SAPc,MAAM,YAAY,YAAY;EAQ5C;EACA,UAAU;EACV,YARiB,QAAQ,aACvB,gBAAgB,QAAQ,WAAW,GACnC,EAAE,UAAU,iBAAiB;EAO/B,OAAO;EACP,eAAe;EAChB,CAAC;AAEF,OAAM,GAAG,YAAY;AACrB,QAAO;;;;;AAMT,eAAsB,UAAU,SAAwC;CACtE,MAAM,KAAK,MAAM,iBAAiB,QAAQ;AAC1C,KAAI;AACF,QAAM,GAAG,WAAW;AACpB,UAAQ,IAAI,kCAAkC;WACtC;AACR,QAAM,GAAG,OAAO;;;;;;AAOpB,eAAsB,YAAY,SAAwC;CACxE,MAAM,KAAK,MAAM,iBAAiB,QAAQ;AAC1C,KAAI;EACF,MAAM,QAAQ,QAAQ,SAAS;EAC/B,MAAM,aAAa,MAAM,GAAG,YAAY,MAAM;AAC9C,MAAI,WAAW,WAAW,EACxB,SAAQ,IAAI,4BAA4B;OACnC;AACL,QAAK,MAAM,QAAQ,WACjB,SAAQ,IAAI,kBAAkB,OAAO;AAEvC,WAAQ,IAAI,eAAe,WAAW,OAAO,eAAe;;WAEtD;AACR,QAAM,GAAG,OAAO;;;;iBA5G4D;gBACjC"}
@@ -8,13 +8,14 @@ let path = require("path");
8
8
  * Create a new migration file
9
9
  * @param {string} name - Migration name
10
10
  * @param {string} [path] - Output directory
11
+ * @param {boolean} [noId] - Omit timestamp from variable name and migration id
11
12
  */
12
- function createMigration(name, path$1) {
13
+ function createMigration(name, path$1, noId) {
13
14
  const dir = path$1 ?? "src/database/migrations";
14
15
  require_fs.ensureDir(dir);
15
16
  const timestamp = require_naming.generateTimestamp();
16
17
  const filePath = (0, path.join)(dir, `${timestamp}_${name}.ts`);
17
- require_fs.writeFileSafe(filePath, require_templates.generateMigrationTemplate(`${timestamp}_${name}`));
18
+ require_fs.writeFileSafe(filePath, require_templates.generateMigrationTemplate(noId ? name : `${timestamp}_${name}`, noId ? require_naming.toCamelCase(name) : `${require_naming.toCamelCase(name)}${timestamp}`));
18
19
  console.log(`Created migration: ${filePath}`);
19
20
  }
20
21
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"migration.cjs","names":["path","generateTimestamp","generateMigrationTemplate"],"sources":["../../../src/cli/commands/migration.ts"],"sourcesContent":["import { join } from \"path\";\nimport { DEFAULT_MIGRATIONS_PATH } from \"../../constants\";\nimport { generateMigrationTemplate } from \"../../migrations\";\nimport { ensureDir, writeFileSafe } from \"../../utils\";\nimport { generateTimestamp } from \"../../utils/naming\";\n\n/**\n * Create a new migration file\n * @param {string} name - Migration name\n * @param {string} [path] - Output directory\n */\nexport function createMigration(name: string, path?: string): void {\n const dir = path ?? DEFAULT_MIGRATIONS_PATH;\n ensureDir(dir);\n\n const timestamp = generateTimestamp();\n const fileName = `${timestamp}_${name}.ts`;\n const filePath = join(dir, fileName);\n const migrationId = `${timestamp}_${name}`;\n const content = generateMigrationTemplate(migrationId);\n\n writeFileSafe(filePath, content);\n console.log(`Created migration: ${filePath}`);\n}\n"],"mappings":";;;;;;;;;;;AAWA,SAAgB,gBAAgB,MAAc,QAAqB;CACjE,MAAM,MAAMA,UAAAA;AACZ,YAAA,UAAU,IAAI;CAEd,MAAM,YAAYC,eAAAA,mBAAmB;CAErC,MAAM,YAAA,GAAA,KAAA,MAAgB,KADL,GAAG,UAAU,GAAG,KAAK,KACF;AAIpC,YAAA,cAAc,UAFEC,kBAAAA,0BADI,GAAG,UAAU,GAAG,OACkB,CAEtB;AAChC,SAAQ,IAAI,sBAAsB,WAAW"}
1
+ {"version":3,"file":"migration.cjs","names":["path","generateTimestamp","generateMigrationTemplate","toCamelCase"],"sources":["../../../src/cli/commands/migration.ts"],"sourcesContent":["import { join } from \"path\";\nimport { DEFAULT_MIGRATIONS_PATH } from \"../../constants\";\nimport { generateMigrationTemplate } from \"../../migrations\";\nimport { ensureDir, writeFileSafe } from \"../../utils\";\nimport { generateTimestamp, toCamelCase } from \"../../utils/naming\";\n\n/**\n * Create a new migration file\n * @param {string} name - Migration name\n * @param {string} [path] - Output directory\n * @param {boolean} [noId] - Omit timestamp from variable name and migration id\n */\nexport function createMigration(name: string, path?: string, noId?: boolean): void {\n const dir = path ?? DEFAULT_MIGRATIONS_PATH;\n ensureDir(dir);\n\n const timestamp = generateTimestamp();\n const fileName = `${timestamp}_${name}.ts`;\n const filePath = join(dir, fileName);\n const migrationId = noId ? name : `${timestamp}_${name}`;\n const varName = noId ? toCamelCase(name) : `${toCamelCase(name)}${timestamp}`;\n const content = generateMigrationTemplate(migrationId, varName);\n\n writeFileSafe(filePath, content);\n console.log(`Created migration: ${filePath}`);\n}\n"],"mappings":";;;;;;;;;;;;AAYA,SAAgB,gBAAgB,MAAc,QAAe,MAAsB;CACjF,MAAM,MAAMA,UAAAA;AACZ,YAAA,UAAU,IAAI;CAEd,MAAM,YAAYC,eAAAA,mBAAmB;CAErC,MAAM,YAAA,GAAA,KAAA,MAAgB,KADL,GAAG,UAAU,GAAG,KAAK,KACF;AAKpC,YAAA,cAAc,UAFEC,kBAAAA,0BAFI,OAAO,OAAO,GAAG,UAAU,GAAG,QAClC,OAAOC,eAAAA,YAAY,KAAK,GAAG,GAAGA,eAAAA,YAAY,KAAK,GAAG,YACH,CAE/B;AAChC,SAAQ,IAAI,sBAAsB,WAAW"}
@@ -1,7 +1,7 @@
1
1
  import { __esmMin } from "../../_virtual/_rolldown/runtime.mjs";
2
2
  import { init_constants } from "../../constants.mjs";
3
3
  import { ensureDir, writeFileSafe } from "../../utils/fs.mjs";
4
- import { generateTimestamp, init_naming } from "../../utils/naming.mjs";
4
+ import { generateTimestamp, init_naming, toCamelCase } from "../../utils/naming.mjs";
5
5
  import { init_utils } from "../../utils/index.mjs";
6
6
  import { generateMigrationTemplate } from "../../migrations/templates.mjs";
7
7
  import { init_migrations } from "../../migrations/index.mjs";
@@ -11,13 +11,14 @@ import { join } from "path";
11
11
  * Create a new migration file
12
12
  * @param {string} name - Migration name
13
13
  * @param {string} [path] - Output directory
14
+ * @param {boolean} [noId] - Omit timestamp from variable name and migration id
14
15
  */
15
- function createMigration(name, path) {
16
+ function createMigration(name, path, noId) {
16
17
  const dir = path ?? "src/database/migrations";
17
18
  ensureDir(dir);
18
19
  const timestamp = generateTimestamp();
19
20
  const filePath = join(dir, `${timestamp}_${name}.ts`);
20
- writeFileSafe(filePath, generateMigrationTemplate(`${timestamp}_${name}`));
21
+ writeFileSafe(filePath, generateMigrationTemplate(noId ? name : `${timestamp}_${name}`, noId ? toCamelCase(name) : `${toCamelCase(name)}${timestamp}`));
21
22
  console.log(`Created migration: ${filePath}`);
22
23
  }
23
24
  var init_migration = __esmMin((() => {
@@ -1 +1 @@
1
- {"version":3,"file":"migration.mjs","names":[],"sources":["../../../src/cli/commands/migration.ts"],"sourcesContent":["import { join } from \"path\";\nimport { DEFAULT_MIGRATIONS_PATH } from \"../../constants\";\nimport { generateMigrationTemplate } from \"../../migrations\";\nimport { ensureDir, writeFileSafe } from \"../../utils\";\nimport { generateTimestamp } from \"../../utils/naming\";\n\n/**\n * Create a new migration file\n * @param {string} name - Migration name\n * @param {string} [path] - Output directory\n */\nexport function createMigration(name: string, path?: string): void {\n const dir = path ?? DEFAULT_MIGRATIONS_PATH;\n ensureDir(dir);\n\n const timestamp = generateTimestamp();\n const fileName = `${timestamp}_${name}.ts`;\n const filePath = join(dir, fileName);\n const migrationId = `${timestamp}_${name}`;\n const content = generateMigrationTemplate(migrationId);\n\n writeFileSafe(filePath, content);\n console.log(`Created migration: ${filePath}`);\n}\n"],"mappings":";;;;;;;;;;;;;;AAWA,SAAgB,gBAAgB,MAAc,MAAqB;CACjE,MAAM,MAAM,QAAA;AACZ,WAAU,IAAI;CAEd,MAAM,YAAY,mBAAmB;CAErC,MAAM,WAAW,KAAK,KADL,GAAG,UAAU,GAAG,KAAK,KACF;AAIpC,eAAc,UAFE,0BADI,GAAG,UAAU,GAAG,OACkB,CAEtB;AAChC,SAAQ,IAAI,sBAAsB,WAAW;;;iBArBW;kBACG;aACN;cACA"}
1
+ {"version":3,"file":"migration.mjs","names":[],"sources":["../../../src/cli/commands/migration.ts"],"sourcesContent":["import { join } from \"path\";\nimport { DEFAULT_MIGRATIONS_PATH } from \"../../constants\";\nimport { generateMigrationTemplate } from \"../../migrations\";\nimport { ensureDir, writeFileSafe } from \"../../utils\";\nimport { generateTimestamp, toCamelCase } from \"../../utils/naming\";\n\n/**\n * Create a new migration file\n * @param {string} name - Migration name\n * @param {string} [path] - Output directory\n * @param {boolean} [noId] - Omit timestamp from variable name and migration id\n */\nexport function createMigration(name: string, path?: string, noId?: boolean): void {\n const dir = path ?? DEFAULT_MIGRATIONS_PATH;\n ensureDir(dir);\n\n const timestamp = generateTimestamp();\n const fileName = `${timestamp}_${name}.ts`;\n const filePath = join(dir, fileName);\n const migrationId = noId ? name : `${timestamp}_${name}`;\n const varName = noId ? toCamelCase(name) : `${toCamelCase(name)}${timestamp}`;\n const content = generateMigrationTemplate(migrationId, varName);\n\n writeFileSafe(filePath, content);\n console.log(`Created migration: ${filePath}`);\n}\n"],"mappings":";;;;;;;;;;;;;;;AAYA,SAAgB,gBAAgB,MAAc,MAAe,MAAsB;CACjF,MAAM,MAAM,QAAA;AACZ,WAAU,IAAI;CAEd,MAAM,YAAY,mBAAmB;CAErC,MAAM,WAAW,KAAK,KADL,GAAG,UAAU,GAAG,KAAK,KACF;AAKpC,eAAc,UAFE,0BAFI,OAAO,OAAO,GAAG,UAAU,GAAG,QAClC,OAAO,YAAY,KAAK,GAAG,GAAG,YAAY,KAAK,GAAG,YACH,CAE/B;AAChC,SAAQ,IAAI,sBAAsB,WAAW;;;iBAvBW;kBACG;aACN;cACa"}
package/dist/cli.cjs CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env bun
2
+ const require_migrate = require("./cli/commands/migrate.cjs");
2
3
  const require_migration = require("./cli/commands/migration.cjs");
3
4
  const require_schema = require("./cli/commands/schema.cjs");
4
5
  //#region src/cli.ts
@@ -12,16 +13,28 @@ function getFlag(flag) {
12
13
  function getName() {
13
14
  return getFlag("--name") ?? args[2];
14
15
  }
16
+ function hasFlag(flag) {
17
+ return args.includes(flag);
18
+ }
19
+ function getMigrateOptions() {
20
+ return {
21
+ migrationsPath: getFlag("--migrations"),
22
+ schemasPath: getFlag("--schemas"),
23
+ database: getFlag("--database"),
24
+ connection: getFlag("--connection"),
25
+ steps: getFlag("--steps") ? Number(getFlag("--steps")) : void 0
26
+ };
27
+ }
15
28
  switch (command) {
16
29
  case "migration":
17
30
  if ((subCommand === "create" ? "create" : "create") === "create") {
18
31
  const name = subCommand === "create" ? getName() : subCommand;
19
32
  if (!name) {
20
- console.log("Usage: @hedystia/db migration create <name> [--path <path>]");
21
- console.log(" @hedystia/db migration <name> [--path <path>]");
33
+ console.log("Usage: @hedystia/db migration create <name> [--path <path>] [--no-id]");
34
+ console.log(" @hedystia/db migration <name> [--path <path>] [--no-id]");
22
35
  process.exit(1);
23
36
  }
24
- require_migration.createMigration(name, getFlag("--path"));
37
+ require_migration.createMigration(name, getFlag("--path"), hasFlag("--no-id"));
25
38
  }
26
39
  break;
27
40
  case "schema":
@@ -35,14 +48,40 @@ switch (command) {
35
48
  require_schema.createSchema(name, getFlag("--path"));
36
49
  }
37
50
  break;
51
+ case "migrate": {
52
+ const options = getMigrateOptions();
53
+ if (subCommand === "up") require_migrate.migrateUp(options).catch((err) => {
54
+ console.error("Migration failed:", err.message);
55
+ process.exit(1);
56
+ });
57
+ else if (subCommand === "down") require_migrate.migrateDown(options).catch((err) => {
58
+ console.error("Rollback failed:", err.message);
59
+ process.exit(1);
60
+ });
61
+ else {
62
+ console.log("Usage: @hedystia/db migrate up [options]");
63
+ console.log(" @hedystia/db migrate down [options]");
64
+ console.log("");
65
+ console.log("Options:");
66
+ console.log(" --migrations <path> Path to migrations directory");
67
+ console.log(" --schemas <path> Path to schemas directory");
68
+ console.log(" --database <type> Database type (sqlite, mysql, mariadb)");
69
+ console.log(" --connection <config> Connection string or JSON config");
70
+ console.log(" --steps <n> Number of migrations to rollback (down only, default: 1)");
71
+ process.exit(1);
72
+ }
73
+ break;
74
+ }
38
75
  default:
39
76
  console.log("@hedystia/db CLI");
40
77
  console.log("");
41
78
  console.log("Commands:");
42
- console.log(" migration create <name> [--path <path>] Create a new migration file");
43
- console.log(" migration <name> [--path <path>] Create a new migration file (shorthand)");
79
+ console.log(" migration create <name> [--path <path>] [--no-id] Create a new migration file");
80
+ console.log(" migration <name> [--path <path>] [--no-id] Create a new migration file (shorthand)");
44
81
  console.log(" schema create <name> [--path <path>] Create a new schema file");
45
82
  console.log(" schema <name> [--path <path>] Create a new schema file (shorthand)");
83
+ console.log(" migrate up [options] Run pending migrations");
84
+ console.log(" migrate down [options] Rollback migrations");
46
85
  break;
47
86
  }
48
87
  //#endregion
package/dist/cli.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.cjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env bun\nimport { createMigration } from \"./cli/commands/migration\";\nimport { createSchema } from \"./cli/commands/schema\";\n\nconst args = process.argv.slice(2);\nconst command = args[0];\nconst subCommand = args[1];\n\nfunction getFlag(flag: string): string | undefined {\n const index = args.indexOf(flag);\n if (index !== -1 && args[index + 1]) {\n return args[index + 1];\n }\n return undefined;\n}\n\nfunction getName(): string | undefined {\n return getFlag(\"--name\") ?? args[2];\n}\n\nswitch (command) {\n case \"migration\": {\n const action = subCommand === \"create\" ? \"create\" : \"create\";\n if (action === \"create\") {\n const name = subCommand === \"create\" ? getName() : subCommand;\n if (!name) {\n console.log(\"Usage: @hedystia/db migration create <name> [--path <path>]\");\n console.log(\" @hedystia/db migration <name> [--path <path>]\");\n process.exit(1);\n }\n createMigration(name, getFlag(\"--path\"));\n }\n break;\n }\n case \"schema\": {\n const action = subCommand === \"create\" ? \"create\" : \"create\";\n if (action === \"create\") {\n const name = subCommand === \"create\" ? getName() : subCommand;\n if (!name) {\n console.log(\"Usage: @hedystia/db schema create <name> [--path <path>]\");\n console.log(\" @hedystia/db schema <name> [--path <path>]\");\n process.exit(1);\n }\n createSchema(name, getFlag(\"--path\"));\n }\n break;\n }\n default: {\n console.log(\"@hedystia/db CLI\");\n console.log(\"\");\n console.log(\"Commands:\");\n console.log(\" migration create <name> [--path <path>] Create a new migration file\");\n console.log(\" migration <name> [--path <path>] Create a new migration file (shorthand)\");\n console.log(\" schema create <name> [--path <path>] Create a new schema file\");\n console.log(\" schema <name> [--path <path>] Create a new schema file (shorthand)\");\n break;\n }\n}\n"],"mappings":";;;;AAIA,MAAM,OAAO,QAAQ,KAAK,MAAM,EAAE;AAClC,MAAM,UAAU,KAAK;AACrB,MAAM,aAAa,KAAK;AAExB,SAAS,QAAQ,MAAkC;CACjD,MAAM,QAAQ,KAAK,QAAQ,KAAK;AAChC,KAAI,UAAU,MAAM,KAAK,QAAQ,GAC/B,QAAO,KAAK,QAAQ;;AAKxB,SAAS,UAA8B;AACrC,QAAO,QAAQ,SAAS,IAAI,KAAK;;AAGnC,QAAQ,SAAR;CACE,KAAK;AAEH,OADe,eAAe,WAAW,WAAW,cACrC,UAAU;GACvB,MAAM,OAAO,eAAe,WAAW,SAAS,GAAG;AACnD,OAAI,CAAC,MAAM;AACT,YAAQ,IAAI,8DAA8D;AAC1E,YAAQ,IAAI,uDAAuD;AACnE,YAAQ,KAAK,EAAE;;AAEjB,qBAAA,gBAAgB,MAAM,QAAQ,SAAS,CAAC;;AAE1C;CAEF,KAAK;AAEH,OADe,eAAe,WAAW,WAAW,cACrC,UAAU;GACvB,MAAM,OAAO,eAAe,WAAW,SAAS,GAAG;AACnD,OAAI,CAAC,MAAM;AACT,YAAQ,IAAI,2DAA2D;AACvE,YAAQ,IAAI,oDAAoD;AAChE,YAAQ,KAAK,EAAE;;AAEjB,kBAAA,aAAa,MAAM,QAAQ,SAAS,CAAC;;AAEvC;CAEF;AACE,UAAQ,IAAI,mBAAmB;AAC/B,UAAQ,IAAI,GAAG;AACf,UAAQ,IAAI,YAAY;AACxB,UAAQ,IAAI,yEAAyE;AACrF,UAAQ,IAAI,qFAAqF;AACjG,UAAQ,IAAI,sEAAsE;AAClF,UAAQ,IAAI,kFAAkF;AAC9F"}
1
+ {"version":3,"file":"cli.cjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env bun\nimport { migrateDown, migrateUp } from \"./cli/commands/migrate\";\nimport { createMigration } from \"./cli/commands/migration\";\nimport { createSchema } from \"./cli/commands/schema\";\n\nconst args = process.argv.slice(2);\nconst command = args[0];\nconst subCommand = args[1];\n\nfunction getFlag(flag: string): string | undefined {\n const index = args.indexOf(flag);\n if (index !== -1 && args[index + 1]) {\n return args[index + 1];\n }\n return undefined;\n}\n\nfunction getName(): string | undefined {\n return getFlag(\"--name\") ?? args[2];\n}\n\nfunction hasFlag(flag: string): boolean {\n return args.includes(flag);\n}\n\nfunction getMigrateOptions() {\n return {\n migrationsPath: getFlag(\"--migrations\"),\n schemasPath: getFlag(\"--schemas\"),\n database: getFlag(\"--database\"),\n connection: getFlag(\"--connection\"),\n steps: getFlag(\"--steps\") ? Number(getFlag(\"--steps\")) : undefined,\n };\n}\n\nswitch (command) {\n case \"migration\": {\n const action = subCommand === \"create\" ? \"create\" : \"create\";\n if (action === \"create\") {\n const name = subCommand === \"create\" ? getName() : subCommand;\n if (!name) {\n console.log(\"Usage: @hedystia/db migration create <name> [--path <path>] [--no-id]\");\n console.log(\" @hedystia/db migration <name> [--path <path>] [--no-id]\");\n process.exit(1);\n }\n createMigration(name, getFlag(\"--path\"), hasFlag(\"--no-id\"));\n }\n break;\n }\n case \"schema\": {\n const action = subCommand === \"create\" ? \"create\" : \"create\";\n if (action === \"create\") {\n const name = subCommand === \"create\" ? getName() : subCommand;\n if (!name) {\n console.log(\"Usage: @hedystia/db schema create <name> [--path <path>]\");\n console.log(\" @hedystia/db schema <name> [--path <path>]\");\n process.exit(1);\n }\n createSchema(name, getFlag(\"--path\"));\n }\n break;\n }\n case \"migrate\": {\n const options = getMigrateOptions();\n if (subCommand === \"up\") {\n migrateUp(options).catch((err) => {\n console.error(\"Migration failed:\", err.message);\n process.exit(1);\n });\n } else if (subCommand === \"down\") {\n migrateDown(options).catch((err) => {\n console.error(\"Rollback failed:\", err.message);\n process.exit(1);\n });\n } else {\n console.log(\"Usage: @hedystia/db migrate up [options]\");\n console.log(\" @hedystia/db migrate down [options]\");\n console.log(\"\");\n console.log(\"Options:\");\n console.log(\" --migrations <path> Path to migrations directory\");\n console.log(\" --schemas <path> Path to schemas directory\");\n console.log(\" --database <type> Database type (sqlite, mysql, mariadb)\");\n console.log(\" --connection <config> Connection string or JSON config\");\n console.log(\n \" --steps <n> Number of migrations to rollback (down only, default: 1)\",\n );\n process.exit(1);\n }\n break;\n }\n default: {\n console.log(\"@hedystia/db CLI\");\n console.log(\"\");\n console.log(\"Commands:\");\n console.log(\n \" migration create <name> [--path <path>] [--no-id] Create a new migration file\",\n );\n console.log(\n \" migration <name> [--path <path>] [--no-id] Create a new migration file (shorthand)\",\n );\n console.log(\" schema create <name> [--path <path>] Create a new schema file\");\n console.log(\" schema <name> [--path <path>] Create a new schema file (shorthand)\");\n console.log(\" migrate up [options] Run pending migrations\");\n console.log(\" migrate down [options] Rollback migrations\");\n break;\n }\n}\n"],"mappings":";;;;;AAKA,MAAM,OAAO,QAAQ,KAAK,MAAM,EAAE;AAClC,MAAM,UAAU,KAAK;AACrB,MAAM,aAAa,KAAK;AAExB,SAAS,QAAQ,MAAkC;CACjD,MAAM,QAAQ,KAAK,QAAQ,KAAK;AAChC,KAAI,UAAU,MAAM,KAAK,QAAQ,GAC/B,QAAO,KAAK,QAAQ;;AAKxB,SAAS,UAA8B;AACrC,QAAO,QAAQ,SAAS,IAAI,KAAK;;AAGnC,SAAS,QAAQ,MAAuB;AACtC,QAAO,KAAK,SAAS,KAAK;;AAG5B,SAAS,oBAAoB;AAC3B,QAAO;EACL,gBAAgB,QAAQ,eAAe;EACvC,aAAa,QAAQ,YAAY;EACjC,UAAU,QAAQ,aAAa;EAC/B,YAAY,QAAQ,eAAe;EACnC,OAAO,QAAQ,UAAU,GAAG,OAAO,QAAQ,UAAU,CAAC,GAAG,KAAA;EAC1D;;AAGH,QAAQ,SAAR;CACE,KAAK;AAEH,OADe,eAAe,WAAW,WAAW,cACrC,UAAU;GACvB,MAAM,OAAO,eAAe,WAAW,SAAS,GAAG;AACnD,OAAI,CAAC,MAAM;AACT,YAAQ,IAAI,wEAAwE;AACpF,YAAQ,IAAI,iEAAiE;AAC7E,YAAQ,KAAK,EAAE;;AAEjB,qBAAA,gBAAgB,MAAM,QAAQ,SAAS,EAAE,QAAQ,UAAU,CAAC;;AAE9D;CAEF,KAAK;AAEH,OADe,eAAe,WAAW,WAAW,cACrC,UAAU;GACvB,MAAM,OAAO,eAAe,WAAW,SAAS,GAAG;AACnD,OAAI,CAAC,MAAM;AACT,YAAQ,IAAI,2DAA2D;AACvE,YAAQ,IAAI,oDAAoD;AAChE,YAAQ,KAAK,EAAE;;AAEjB,kBAAA,aAAa,MAAM,QAAQ,SAAS,CAAC;;AAEvC;CAEF,KAAK,WAAW;EACd,MAAM,UAAU,mBAAmB;AACnC,MAAI,eAAe,KACjB,iBAAA,UAAU,QAAQ,CAAC,OAAO,QAAQ;AAChC,WAAQ,MAAM,qBAAqB,IAAI,QAAQ;AAC/C,WAAQ,KAAK,EAAE;IACf;WACO,eAAe,OACxB,iBAAA,YAAY,QAAQ,CAAC,OAAO,QAAQ;AAClC,WAAQ,MAAM,oBAAoB,IAAI,QAAQ;AAC9C,WAAQ,KAAK,EAAE;IACf;OACG;AACL,WAAQ,IAAI,2CAA2C;AACvD,WAAQ,IAAI,6CAA6C;AACzD,WAAQ,IAAI,GAAG;AACf,WAAQ,IAAI,WAAW;AACvB,WAAQ,IAAI,wDAAwD;AACpE,WAAQ,IAAI,qDAAqD;AACjE,WAAQ,IAAI,kEAAkE;AAC9E,WAAQ,IAAI,4DAA4D;AACxE,WAAQ,IACN,oFACD;AACD,WAAQ,KAAK,EAAE;;AAEjB;;CAEF;AACE,UAAQ,IAAI,mBAAmB;AAC/B,UAAQ,IAAI,GAAG;AACf,UAAQ,IAAI,YAAY;AACxB,UAAQ,IACN,mFACD;AACD,UAAQ,IACN,+FACD;AACD,UAAQ,IAAI,sEAAsE;AAClF,UAAQ,IAAI,kFAAkF;AAC9F,UAAQ,IAAI,oEAAoE;AAChF,UAAQ,IAAI,iEAAiE;AAC7E"}
package/dist/cli.mjs CHANGED
@@ -1,9 +1,11 @@
1
1
  #!/usr/bin/env bun
2
2
  import { __commonJSMin } from "./_virtual/_rolldown/runtime.mjs";
3
+ import { init_migrate, migrateDown, migrateUp } from "./cli/commands/migrate.mjs";
3
4
  import { createMigration, init_migration } from "./cli/commands/migration.mjs";
4
5
  import { createSchema, init_schema } from "./cli/commands/schema.mjs";
5
6
  //#region src/cli.ts
6
7
  var require_cli = /* @__PURE__ */ __commonJSMin((() => {
8
+ init_migrate();
7
9
  init_migration();
8
10
  init_schema();
9
11
  const args = process.argv.slice(2);
@@ -16,16 +18,28 @@ var require_cli = /* @__PURE__ */ __commonJSMin((() => {
16
18
  function getName() {
17
19
  return getFlag("--name") ?? args[2];
18
20
  }
21
+ function hasFlag(flag) {
22
+ return args.includes(flag);
23
+ }
24
+ function getMigrateOptions() {
25
+ return {
26
+ migrationsPath: getFlag("--migrations"),
27
+ schemasPath: getFlag("--schemas"),
28
+ database: getFlag("--database"),
29
+ connection: getFlag("--connection"),
30
+ steps: getFlag("--steps") ? Number(getFlag("--steps")) : void 0
31
+ };
32
+ }
19
33
  switch (command) {
20
34
  case "migration":
21
35
  if ((subCommand === "create" ? "create" : "create") === "create") {
22
36
  const name = subCommand === "create" ? getName() : subCommand;
23
37
  if (!name) {
24
- console.log("Usage: @hedystia/db migration create <name> [--path <path>]");
25
- console.log(" @hedystia/db migration <name> [--path <path>]");
38
+ console.log("Usage: @hedystia/db migration create <name> [--path <path>] [--no-id]");
39
+ console.log(" @hedystia/db migration <name> [--path <path>] [--no-id]");
26
40
  process.exit(1);
27
41
  }
28
- createMigration(name, getFlag("--path"));
42
+ createMigration(name, getFlag("--path"), hasFlag("--no-id"));
29
43
  }
30
44
  break;
31
45
  case "schema":
@@ -39,14 +53,40 @@ var require_cli = /* @__PURE__ */ __commonJSMin((() => {
39
53
  createSchema(name, getFlag("--path"));
40
54
  }
41
55
  break;
56
+ case "migrate": {
57
+ const options = getMigrateOptions();
58
+ if (subCommand === "up") migrateUp(options).catch((err) => {
59
+ console.error("Migration failed:", err.message);
60
+ process.exit(1);
61
+ });
62
+ else if (subCommand === "down") migrateDown(options).catch((err) => {
63
+ console.error("Rollback failed:", err.message);
64
+ process.exit(1);
65
+ });
66
+ else {
67
+ console.log("Usage: @hedystia/db migrate up [options]");
68
+ console.log(" @hedystia/db migrate down [options]");
69
+ console.log("");
70
+ console.log("Options:");
71
+ console.log(" --migrations <path> Path to migrations directory");
72
+ console.log(" --schemas <path> Path to schemas directory");
73
+ console.log(" --database <type> Database type (sqlite, mysql, mariadb)");
74
+ console.log(" --connection <config> Connection string or JSON config");
75
+ console.log(" --steps <n> Number of migrations to rollback (down only, default: 1)");
76
+ process.exit(1);
77
+ }
78
+ break;
79
+ }
42
80
  default:
43
81
  console.log("@hedystia/db CLI");
44
82
  console.log("");
45
83
  console.log("Commands:");
46
- console.log(" migration create <name> [--path <path>] Create a new migration file");
47
- console.log(" migration <name> [--path <path>] Create a new migration file (shorthand)");
84
+ console.log(" migration create <name> [--path <path>] [--no-id] Create a new migration file");
85
+ console.log(" migration <name> [--path <path>] [--no-id] Create a new migration file (shorthand)");
48
86
  console.log(" schema create <name> [--path <path>] Create a new schema file");
49
87
  console.log(" schema <name> [--path <path>] Create a new schema file (shorthand)");
88
+ console.log(" migrate up [options] Run pending migrations");
89
+ console.log(" migrate down [options] Rollback migrations");
50
90
  break;
51
91
  }
52
92
  }));
package/dist/cli.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env bun\nimport { createMigration } from \"./cli/commands/migration\";\nimport { createSchema } from \"./cli/commands/schema\";\n\nconst args = process.argv.slice(2);\nconst command = args[0];\nconst subCommand = args[1];\n\nfunction getFlag(flag: string): string | undefined {\n const index = args.indexOf(flag);\n if (index !== -1 && args[index + 1]) {\n return args[index + 1];\n }\n return undefined;\n}\n\nfunction getName(): string | undefined {\n return getFlag(\"--name\") ?? args[2];\n}\n\nswitch (command) {\n case \"migration\": {\n const action = subCommand === \"create\" ? \"create\" : \"create\";\n if (action === \"create\") {\n const name = subCommand === \"create\" ? getName() : subCommand;\n if (!name) {\n console.log(\"Usage: @hedystia/db migration create <name> [--path <path>]\");\n console.log(\" @hedystia/db migration <name> [--path <path>]\");\n process.exit(1);\n }\n createMigration(name, getFlag(\"--path\"));\n }\n break;\n }\n case \"schema\": {\n const action = subCommand === \"create\" ? \"create\" : \"create\";\n if (action === \"create\") {\n const name = subCommand === \"create\" ? getName() : subCommand;\n if (!name) {\n console.log(\"Usage: @hedystia/db schema create <name> [--path <path>]\");\n console.log(\" @hedystia/db schema <name> [--path <path>]\");\n process.exit(1);\n }\n createSchema(name, getFlag(\"--path\"));\n }\n break;\n }\n default: {\n console.log(\"@hedystia/db CLI\");\n console.log(\"\");\n console.log(\"Commands:\");\n console.log(\" migration create <name> [--path <path>] Create a new migration file\");\n console.log(\" migration <name> [--path <path>] Create a new migration file (shorthand)\");\n console.log(\" schema create <name> [--path <path>] Create a new schema file\");\n console.log(\" schema <name> [--path <path>] Create a new schema file (shorthand)\");\n break;\n }\n}\n"],"mappings":";;;;;;iBAC2D;cACN;CAErD,MAAM,OAAO,QAAQ,KAAK,MAAM,EAAE;CAClC,MAAM,UAAU,KAAK;CACrB,MAAM,aAAa,KAAK;CAExB,SAAS,QAAQ,MAAkC;EACjD,MAAM,QAAQ,KAAK,QAAQ,KAAK;AAChC,MAAI,UAAU,MAAM,KAAK,QAAQ,GAC/B,QAAO,KAAK,QAAQ;;CAKxB,SAAS,UAA8B;AACrC,SAAO,QAAQ,SAAS,IAAI,KAAK;;AAGnC,SAAQ,SAAR;EACE,KAAK;AAEH,QADe,eAAe,WAAW,WAAW,cACrC,UAAU;IACvB,MAAM,OAAO,eAAe,WAAW,SAAS,GAAG;AACnD,QAAI,CAAC,MAAM;AACT,aAAQ,IAAI,8DAA8D;AAC1E,aAAQ,IAAI,uDAAuD;AACnE,aAAQ,KAAK,EAAE;;AAEjB,oBAAgB,MAAM,QAAQ,SAAS,CAAC;;AAE1C;EAEF,KAAK;AAEH,QADe,eAAe,WAAW,WAAW,cACrC,UAAU;IACvB,MAAM,OAAO,eAAe,WAAW,SAAS,GAAG;AACnD,QAAI,CAAC,MAAM;AACT,aAAQ,IAAI,2DAA2D;AACvE,aAAQ,IAAI,oDAAoD;AAChE,aAAQ,KAAK,EAAE;;AAEjB,iBAAa,MAAM,QAAQ,SAAS,CAAC;;AAEvC;EAEF;AACE,WAAQ,IAAI,mBAAmB;AAC/B,WAAQ,IAAI,GAAG;AACf,WAAQ,IAAI,YAAY;AACxB,WAAQ,IAAI,yEAAyE;AACrF,WAAQ,IAAI,qFAAqF;AACjG,WAAQ,IAAI,sEAAsE;AAClF,WAAQ,IAAI,kFAAkF;AAC9F"}
1
+ {"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env bun\nimport { migrateDown, migrateUp } from \"./cli/commands/migrate\";\nimport { createMigration } from \"./cli/commands/migration\";\nimport { createSchema } from \"./cli/commands/schema\";\n\nconst args = process.argv.slice(2);\nconst command = args[0];\nconst subCommand = args[1];\n\nfunction getFlag(flag: string): string | undefined {\n const index = args.indexOf(flag);\n if (index !== -1 && args[index + 1]) {\n return args[index + 1];\n }\n return undefined;\n}\n\nfunction getName(): string | undefined {\n return getFlag(\"--name\") ?? args[2];\n}\n\nfunction hasFlag(flag: string): boolean {\n return args.includes(flag);\n}\n\nfunction getMigrateOptions() {\n return {\n migrationsPath: getFlag(\"--migrations\"),\n schemasPath: getFlag(\"--schemas\"),\n database: getFlag(\"--database\"),\n connection: getFlag(\"--connection\"),\n steps: getFlag(\"--steps\") ? Number(getFlag(\"--steps\")) : undefined,\n };\n}\n\nswitch (command) {\n case \"migration\": {\n const action = subCommand === \"create\" ? \"create\" : \"create\";\n if (action === \"create\") {\n const name = subCommand === \"create\" ? getName() : subCommand;\n if (!name) {\n console.log(\"Usage: @hedystia/db migration create <name> [--path <path>] [--no-id]\");\n console.log(\" @hedystia/db migration <name> [--path <path>] [--no-id]\");\n process.exit(1);\n }\n createMigration(name, getFlag(\"--path\"), hasFlag(\"--no-id\"));\n }\n break;\n }\n case \"schema\": {\n const action = subCommand === \"create\" ? \"create\" : \"create\";\n if (action === \"create\") {\n const name = subCommand === \"create\" ? getName() : subCommand;\n if (!name) {\n console.log(\"Usage: @hedystia/db schema create <name> [--path <path>]\");\n console.log(\" @hedystia/db schema <name> [--path <path>]\");\n process.exit(1);\n }\n createSchema(name, getFlag(\"--path\"));\n }\n break;\n }\n case \"migrate\": {\n const options = getMigrateOptions();\n if (subCommand === \"up\") {\n migrateUp(options).catch((err) => {\n console.error(\"Migration failed:\", err.message);\n process.exit(1);\n });\n } else if (subCommand === \"down\") {\n migrateDown(options).catch((err) => {\n console.error(\"Rollback failed:\", err.message);\n process.exit(1);\n });\n } else {\n console.log(\"Usage: @hedystia/db migrate up [options]\");\n console.log(\" @hedystia/db migrate down [options]\");\n console.log(\"\");\n console.log(\"Options:\");\n console.log(\" --migrations <path> Path to migrations directory\");\n console.log(\" --schemas <path> Path to schemas directory\");\n console.log(\" --database <type> Database type (sqlite, mysql, mariadb)\");\n console.log(\" --connection <config> Connection string or JSON config\");\n console.log(\n \" --steps <n> Number of migrations to rollback (down only, default: 1)\",\n );\n process.exit(1);\n }\n break;\n }\n default: {\n console.log(\"@hedystia/db CLI\");\n console.log(\"\");\n console.log(\"Commands:\");\n console.log(\n \" migration create <name> [--path <path>] [--no-id] Create a new migration file\",\n );\n console.log(\n \" migration <name> [--path <path>] [--no-id] Create a new migration file (shorthand)\",\n );\n console.log(\" schema create <name> [--path <path>] Create a new schema file\");\n console.log(\" schema <name> [--path <path>] Create a new schema file (shorthand)\");\n console.log(\" migrate up [options] Run pending migrations\");\n console.log(\" migrate down [options] Rollback migrations\");\n break;\n }\n}\n"],"mappings":";;;;;;;eACgE;iBACL;cACN;CAErD,MAAM,OAAO,QAAQ,KAAK,MAAM,EAAE;CAClC,MAAM,UAAU,KAAK;CACrB,MAAM,aAAa,KAAK;CAExB,SAAS,QAAQ,MAAkC;EACjD,MAAM,QAAQ,KAAK,QAAQ,KAAK;AAChC,MAAI,UAAU,MAAM,KAAK,QAAQ,GAC/B,QAAO,KAAK,QAAQ;;CAKxB,SAAS,UAA8B;AACrC,SAAO,QAAQ,SAAS,IAAI,KAAK;;CAGnC,SAAS,QAAQ,MAAuB;AACtC,SAAO,KAAK,SAAS,KAAK;;CAG5B,SAAS,oBAAoB;AAC3B,SAAO;GACL,gBAAgB,QAAQ,eAAe;GACvC,aAAa,QAAQ,YAAY;GACjC,UAAU,QAAQ,aAAa;GAC/B,YAAY,QAAQ,eAAe;GACnC,OAAO,QAAQ,UAAU,GAAG,OAAO,QAAQ,UAAU,CAAC,GAAG,KAAA;GAC1D;;AAGH,SAAQ,SAAR;EACE,KAAK;AAEH,QADe,eAAe,WAAW,WAAW,cACrC,UAAU;IACvB,MAAM,OAAO,eAAe,WAAW,SAAS,GAAG;AACnD,QAAI,CAAC,MAAM;AACT,aAAQ,IAAI,wEAAwE;AACpF,aAAQ,IAAI,iEAAiE;AAC7E,aAAQ,KAAK,EAAE;;AAEjB,oBAAgB,MAAM,QAAQ,SAAS,EAAE,QAAQ,UAAU,CAAC;;AAE9D;EAEF,KAAK;AAEH,QADe,eAAe,WAAW,WAAW,cACrC,UAAU;IACvB,MAAM,OAAO,eAAe,WAAW,SAAS,GAAG;AACnD,QAAI,CAAC,MAAM;AACT,aAAQ,IAAI,2DAA2D;AACvE,aAAQ,IAAI,oDAAoD;AAChE,aAAQ,KAAK,EAAE;;AAEjB,iBAAa,MAAM,QAAQ,SAAS,CAAC;;AAEvC;EAEF,KAAK,WAAW;GACd,MAAM,UAAU,mBAAmB;AACnC,OAAI,eAAe,KACjB,WAAU,QAAQ,CAAC,OAAO,QAAQ;AAChC,YAAQ,MAAM,qBAAqB,IAAI,QAAQ;AAC/C,YAAQ,KAAK,EAAE;KACf;YACO,eAAe,OACxB,aAAY,QAAQ,CAAC,OAAO,QAAQ;AAClC,YAAQ,MAAM,oBAAoB,IAAI,QAAQ;AAC9C,YAAQ,KAAK,EAAE;KACf;QACG;AACL,YAAQ,IAAI,2CAA2C;AACvD,YAAQ,IAAI,6CAA6C;AACzD,YAAQ,IAAI,GAAG;AACf,YAAQ,IAAI,WAAW;AACvB,YAAQ,IAAI,wDAAwD;AACpE,YAAQ,IAAI,qDAAqD;AACjE,YAAQ,IAAI,kEAAkE;AAC9E,YAAQ,IAAI,4DAA4D;AACxE,YAAQ,IACN,oFACD;AACD,YAAQ,KAAK,EAAE;;AAEjB;;EAEF;AACE,WAAQ,IAAI,mBAAmB;AAC/B,WAAQ,IAAI,GAAG;AACf,WAAQ,IAAI,YAAY;AACxB,WAAQ,IACN,mFACD;AACD,WAAQ,IACN,+FACD;AACD,WAAQ,IAAI,sEAAsE;AAClF,WAAQ,IAAI,kFAAkF;AAC9F,WAAQ,IAAI,oEAAoE;AAChF,WAAQ,IAAI,iEAAiE;AAC7E"}
@@ -22,7 +22,13 @@ function database(config) {
22
22
  const schemas = normalizeSchemas(config.schemas);
23
23
  const registry = new require_registry.SchemaRegistry();
24
24
  registry.register(schemas);
25
- const connectionConfig = Array.isArray(config.connection) ? config.connection[0] : config.connection;
25
+ const dbName = typeof config.database === "string" ? config.database : config.database.name;
26
+ let connectionConfig;
27
+ if (Array.isArray(config.connection)) if (dbName === "sqlite") connectionConfig = config.connection.find((c) => "filename" in c) ?? config.connection[0];
28
+ else if (dbName === "mysql" || dbName === "mariadb") connectionConfig = config.connection.find((c) => "host" in c) ?? config.connection[0];
29
+ else if (dbName === "file") connectionConfig = config.connection.find((c) => "directory" in c) ?? config.connection[0];
30
+ else connectionConfig = config.connection[0];
31
+ else connectionConfig = config.connection;
26
32
  if (!connectionConfig) throw new require_errors.DatabaseError("Connection config is required");
27
33
  const driver = require_index.createDriver(config.database, connectionConfig);
28
34
  const cache = new require_manager.CacheManager(config.cache);
@@ -81,6 +87,18 @@ function database(config) {
81
87
  transaction: async (fn) => {
82
88
  await ensureInitialized();
83
89
  return driver.transaction(fn);
90
+ },
91
+ migrateUp: async () => {
92
+ await ensureInitialized();
93
+ if (config.migrations) {
94
+ const migrations = normalizeMigrations(config.migrations);
95
+ if (migrations.length > 0) await runMigrations(driver, registry, migrations);
96
+ }
97
+ },
98
+ migrateDown: async (steps = 1) => {
99
+ await ensureInitialized();
100
+ if (config.migrations) return rollbackMigrations(driver, registry, normalizeMigrations(config.migrations), steps);
101
+ return [];
84
102
  }
85
103
  };
86
104
  for (const schema of schemas) {
@@ -97,8 +115,8 @@ function database(config) {
97
115
  }
98
116
  return instance;
99
117
  }
100
- async function runMigrations(driver, registry, migrations) {
101
- const migrationsTableMeta = {
118
+ function getMigrationsTableMeta() {
119
+ return {
102
120
  name: require_constants.MIGRATIONS_TABLE,
103
121
  columns: [
104
122
  {
@@ -131,39 +149,67 @@ async function runMigrations(driver, registry, migrations) {
131
149
  }
132
150
  ]
133
151
  };
134
- if (!await driver.tableExists("__hedystia_migrations")) await driver.createTable(migrationsTableMeta);
152
+ }
153
+ function createMigrationContext(driver, registry) {
154
+ return {
155
+ schema: {
156
+ createTable: async (tableDef) => {
157
+ const meta = registry.getTable(tableDef.__name) ?? {
158
+ name: tableDef.__name,
159
+ columns: [...tableDef.__columns]
160
+ };
161
+ await driver.createTable(meta);
162
+ },
163
+ dropTable: async (name) => {
164
+ await driver.dropTable(name);
165
+ },
166
+ addColumn: async (table, _name, column) => {
167
+ await driver.addColumn(table, column);
168
+ },
169
+ dropColumn: async (table, name) => {
170
+ await driver.dropColumn(table, name);
171
+ },
172
+ renameColumn: async (table, oldName, newName) => {
173
+ await driver.renameColumn(table, oldName, newName);
174
+ },
175
+ addIndex: async () => {},
176
+ dropIndex: async () => {}
177
+ },
178
+ sql: async (query, params) => {
179
+ return driver.execute(query, params);
180
+ }
181
+ };
182
+ }
183
+ async function ensureMigrationsTable(driver) {
184
+ if (!await driver.tableExists("__hedystia_migrations")) await driver.createTable(getMigrationsTableMeta());
185
+ }
186
+ async function runMigrations(driver, registry, migrations) {
187
+ await ensureMigrationsTable(driver);
135
188
  const executed = await driver.query(`SELECT name FROM \`${require_constants.MIGRATIONS_TABLE}\``);
136
189
  const executedNames = new Set(executed.map((r) => r.name));
190
+ const ctx = createMigrationContext(driver, registry);
137
191
  for (const migration of migrations) {
138
192
  if (executedNames.has(migration.name)) continue;
139
- await migration.up({
140
- schema: {
141
- createTable: async (tableDef) => {
142
- const meta = registry.getTable(tableDef.__name);
143
- if (meta) await driver.createTable(meta);
144
- },
145
- dropTable: async (name) => {
146
- await driver.dropTable(name);
147
- },
148
- addColumn: async (table, _name, column) => {
149
- await driver.addColumn(table, column);
150
- },
151
- dropColumn: async (table, name) => {
152
- await driver.dropColumn(table, name);
153
- },
154
- renameColumn: async (table, oldName, newName) => {
155
- await driver.renameColumn(table, oldName, newName);
156
- },
157
- addIndex: async () => {},
158
- dropIndex: async () => {}
159
- },
160
- sql: async (query, params) => {
161
- return driver.execute(query, params);
162
- }
163
- });
193
+ await migration.up(ctx);
164
194
  await driver.execute(`INSERT INTO \`${require_constants.MIGRATIONS_TABLE}\` (\`name\`, \`executed_at\`) VALUES (?, ?)`, [migration.name, /* @__PURE__ */ new Date()]);
165
195
  }
166
196
  }
197
+ async function rollbackMigrations(driver, registry, migrations, steps = 1) {
198
+ await ensureMigrationsTable(driver);
199
+ const executedNames = (await driver.query(`SELECT name FROM \`${require_constants.MIGRATIONS_TABLE}\` ORDER BY id DESC`)).map((r) => r.name);
200
+ const ctx = createMigrationContext(driver, registry);
201
+ const migrationMap = new Map(migrations.map((m) => [m.name, m]));
202
+ const rolledBack = [];
203
+ const toRollback = executedNames.slice(0, steps);
204
+ for (const name of toRollback) {
205
+ const migration = migrationMap.get(name);
206
+ if (!migration) continue;
207
+ await migration.down(ctx);
208
+ await driver.execute(`DELETE FROM \`${require_constants.MIGRATIONS_TABLE}\` WHERE \`name\` = ?`, [name]);
209
+ rolledBack.push(name);
210
+ }
211
+ return rolledBack;
212
+ }
167
213
  //#endregion
168
214
  exports.database = database;
169
215