@noego/proper 0.0.9 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +179 -52
- package/bin/cli.js.map +1 -1
- package/bin/cli.mjs +181 -53
- package/bin/cli.mjs.map +1 -1
- package/bin/index.d.mts +104 -2
- package/bin/index.d.ts +104 -2
- package/bin/index.js +181 -52
- package/bin/index.js.map +1 -1
- package/bin/index.mjs +178 -52
- package/bin/index.mjs.map +1 -1
- package/lib/runner.js.map +1 -1
- package/lib/runner.mjs.map +1 -1
- package/package.json +5 -3
package/bin/index.mjs
CHANGED
|
@@ -40,9 +40,6 @@ var __async = (__this, __arguments, generator) => {
|
|
|
40
40
|
|
|
41
41
|
// framework/MigrationRunner.ts
|
|
42
42
|
import fs3 from "fs";
|
|
43
|
-
import mysql from "mysql2/promise";
|
|
44
|
-
import * as sqlite from "sqlite";
|
|
45
|
-
import * as sqlite3 from "sqlite3";
|
|
46
43
|
|
|
47
44
|
// framework/MigrationDirectoryReader.ts
|
|
48
45
|
import fs from "fs";
|
|
@@ -334,9 +331,10 @@ var MigrationDirectoryReader = class {
|
|
|
334
331
|
/**
|
|
335
332
|
* Resolves the appropriate file for a migration based on dialect.
|
|
336
333
|
* Priority: dialect-specific file > generic file
|
|
334
|
+
* File extensions: `.mysql.up.sql`, `.sqlite.up.sql`, `.pg.up.sql`.
|
|
337
335
|
*/
|
|
338
336
|
resolveFile(baseName, direction) {
|
|
339
|
-
const dialectExt = this.dialect === "sql" ? "mysql" :
|
|
337
|
+
const dialectExt = this.dialect === "sql" ? "mysql" : this.dialect;
|
|
340
338
|
const dialectFile = path.join(this.directory, `${baseName}.${dialectExt}.${direction}.sql`);
|
|
341
339
|
if (fs.existsSync(dialectFile)) return dialectFile;
|
|
342
340
|
const genericFile = path.join(this.directory, `${baseName}.${direction}.sql`);
|
|
@@ -347,14 +345,14 @@ var MigrationDirectoryReader = class {
|
|
|
347
345
|
* Checks if a file path is dialect-specific (contains .mysql. or .sqlite. in the name)
|
|
348
346
|
*/
|
|
349
347
|
isDialectSpecific(filePath) {
|
|
350
|
-
return /\.(mysql|sqlite)\.(up|down)\.sql$/i.test(filePath);
|
|
348
|
+
return /\.(mysql|sqlite|pg)\.(up|down)\.sql$/i.test(filePath);
|
|
351
349
|
}
|
|
352
350
|
loadMigrations(table, connection) {
|
|
353
351
|
fs.existsSync(this.directory) || fs.mkdirSync(this.directory);
|
|
354
352
|
const dir_content = fs.readdirSync(this.directory, { withFileTypes: true }).filter((file) => file.isFile()).map((file) => file.name);
|
|
355
353
|
const uniqueKeys = /* @__PURE__ */ new Set();
|
|
356
354
|
dir_content.forEach((file) => {
|
|
357
|
-
const key = file.replace(/(?:\.(mysql|sqlite))?\.(up|down)\.(sql|js)/i, "").toLowerCase();
|
|
355
|
+
const key = file.replace(/(?:\.(mysql|sqlite|pg))?\.(up|down)\.(sql|js)/i, "").toLowerCase();
|
|
358
356
|
uniqueKeys.add(key);
|
|
359
357
|
});
|
|
360
358
|
const migration_sorter = {};
|
|
@@ -426,6 +424,12 @@ var MigrationSetup = class {
|
|
|
426
424
|
up TEXT,
|
|
427
425
|
down TEXT,
|
|
428
426
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
427
|
+
)` : this.config.database === "pg" ? `CREATE TABLE IF NOT EXISTS ${tableName} (
|
|
428
|
+
id SERIAL PRIMARY KEY,
|
|
429
|
+
migration_key TEXT,
|
|
430
|
+
up TEXT,
|
|
431
|
+
down TEXT,
|
|
432
|
+
created_at TIMESTAMPTZ DEFAULT now()
|
|
429
433
|
)` : `CREATE TABLE IF NOT EXISTS ${tableName} (
|
|
430
434
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
431
435
|
migration_key VARCHAR(255),
|
|
@@ -485,31 +489,35 @@ function MySqlDialectParser(sql) {
|
|
|
485
489
|
}
|
|
486
490
|
return result;
|
|
487
491
|
}
|
|
488
|
-
function
|
|
489
|
-
const
|
|
490
|
-
let result = "";
|
|
491
|
-
let isInSqliteBlock = true;
|
|
492
|
-
const startSqliteRegex = /^\s*--\s*\[\s*sqlite\s*\]\s*$/i;
|
|
492
|
+
function markerDialectParser(names) {
|
|
493
|
+
const startRegex = new RegExp(`^\\s*--\\s*\\[\\s*(${names.join("|")})\\s*\\]\\s*$`, "i");
|
|
493
494
|
const anyDialectRegex = /^\s*--\s*\[\s*\w+\s*\]\s*$/i;
|
|
494
|
-
|
|
495
|
-
const
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
495
|
+
return function(sql) {
|
|
496
|
+
const lines = sql.split("\n");
|
|
497
|
+
let result = "";
|
|
498
|
+
let capturing = true;
|
|
499
|
+
for (const line of lines) {
|
|
500
|
+
const trimmed = line.trim();
|
|
501
|
+
if (startRegex.test(trimmed)) {
|
|
502
|
+
capturing = true;
|
|
503
|
+
result += line + "\n";
|
|
504
|
+
continue;
|
|
505
|
+
} else if (anyDialectRegex.test(trimmed)) {
|
|
506
|
+
capturing = false;
|
|
507
|
+
continue;
|
|
508
|
+
}
|
|
509
|
+
if (!capturing && line.toLowerCase().includes("create index")) {
|
|
510
|
+
capturing = true;
|
|
511
|
+
}
|
|
512
|
+
if (capturing) {
|
|
513
|
+
result += line + "\n";
|
|
514
|
+
}
|
|
509
515
|
}
|
|
510
|
-
|
|
511
|
-
|
|
516
|
+
return result;
|
|
517
|
+
};
|
|
512
518
|
}
|
|
519
|
+
var SqliteDialectParser = markerDialectParser(["sqlite"]);
|
|
520
|
+
var PgDialectParser = markerDialectParser(["pg", "postgres", "postgresql"]);
|
|
513
521
|
|
|
514
522
|
// framework/SQLRunner.ts
|
|
515
523
|
var BaseSQLRunner = class {
|
|
@@ -725,12 +733,122 @@ ${sql}
|
|
|
725
733
|
});
|
|
726
734
|
}
|
|
727
735
|
};
|
|
736
|
+
var PgRunner = class _PgRunner extends BaseSQLRunner {
|
|
737
|
+
constructor(connection) {
|
|
738
|
+
super();
|
|
739
|
+
this.connection = connection;
|
|
740
|
+
}
|
|
741
|
+
/** `?` -> `$1`, `$2`, ... outside of string literals / comments. */
|
|
742
|
+
static toPositional(sql) {
|
|
743
|
+
let out = "";
|
|
744
|
+
let n = 0;
|
|
745
|
+
let inSingle = false;
|
|
746
|
+
let inDouble = false;
|
|
747
|
+
let inLineComment = false;
|
|
748
|
+
let inBlockComment = false;
|
|
749
|
+
for (let i = 0; i < sql.length; i++) {
|
|
750
|
+
const ch = sql[i];
|
|
751
|
+
const next = sql[i + 1];
|
|
752
|
+
if (inLineComment) {
|
|
753
|
+
out += ch;
|
|
754
|
+
if (ch === "\n") inLineComment = false;
|
|
755
|
+
continue;
|
|
756
|
+
}
|
|
757
|
+
if (inBlockComment) {
|
|
758
|
+
out += ch;
|
|
759
|
+
if (ch === "*" && next === "/") {
|
|
760
|
+
out += next;
|
|
761
|
+
i++;
|
|
762
|
+
inBlockComment = false;
|
|
763
|
+
}
|
|
764
|
+
continue;
|
|
765
|
+
}
|
|
766
|
+
if (inSingle) {
|
|
767
|
+
out += ch;
|
|
768
|
+
if (ch === "'") inSingle = false;
|
|
769
|
+
continue;
|
|
770
|
+
}
|
|
771
|
+
if (inDouble) {
|
|
772
|
+
out += ch;
|
|
773
|
+
if (ch === '"') inDouble = false;
|
|
774
|
+
continue;
|
|
775
|
+
}
|
|
776
|
+
if (ch === "-" && next === "-") {
|
|
777
|
+
out += ch;
|
|
778
|
+
inLineComment = true;
|
|
779
|
+
continue;
|
|
780
|
+
}
|
|
781
|
+
if (ch === "/" && next === "*") {
|
|
782
|
+
out += ch + next;
|
|
783
|
+
i++;
|
|
784
|
+
inBlockComment = true;
|
|
785
|
+
continue;
|
|
786
|
+
}
|
|
787
|
+
if (ch === "'") {
|
|
788
|
+
out += ch;
|
|
789
|
+
inSingle = true;
|
|
790
|
+
continue;
|
|
791
|
+
}
|
|
792
|
+
if (ch === '"') {
|
|
793
|
+
out += ch;
|
|
794
|
+
inDouble = true;
|
|
795
|
+
continue;
|
|
796
|
+
}
|
|
797
|
+
if (ch === "?") {
|
|
798
|
+
out += `$${++n}`;
|
|
799
|
+
continue;
|
|
800
|
+
}
|
|
801
|
+
out += ch;
|
|
802
|
+
}
|
|
803
|
+
return out;
|
|
804
|
+
}
|
|
805
|
+
run(sql, params) {
|
|
806
|
+
return __async(this, null, function* () {
|
|
807
|
+
if (params.length > 0) {
|
|
808
|
+
return yield this.connection.query(_PgRunner.toPositional(sql), params);
|
|
809
|
+
}
|
|
810
|
+
return yield this.connection.query(sql);
|
|
811
|
+
});
|
|
812
|
+
}
|
|
813
|
+
_query(_0) {
|
|
814
|
+
return __async(this, arguments, function* (sql, params = []) {
|
|
815
|
+
const result = yield this.run(sql, params);
|
|
816
|
+
return [result.rows, result];
|
|
817
|
+
});
|
|
818
|
+
}
|
|
819
|
+
_execute(_0) {
|
|
820
|
+
return __async(this, arguments, function* (sql, params = []) {
|
|
821
|
+
var _a;
|
|
822
|
+
const result = yield this.run(sql, params);
|
|
823
|
+
return [{ changes: (_a = result.rowCount) != null ? _a : 0, lastID: void 0 }, result];
|
|
824
|
+
});
|
|
825
|
+
}
|
|
826
|
+
_end() {
|
|
827
|
+
return __async(this, null, function* () {
|
|
828
|
+
if (this.connection && typeof this.connection.end === "function") {
|
|
829
|
+
yield this.connection.end();
|
|
830
|
+
}
|
|
831
|
+
});
|
|
832
|
+
}
|
|
833
|
+
};
|
|
728
834
|
|
|
729
835
|
// framework/MigrationRunner.ts
|
|
730
836
|
function toError(error) {
|
|
731
837
|
if (error instanceof Error) return error;
|
|
732
838
|
return new Error(String(error));
|
|
733
839
|
}
|
|
840
|
+
function makeRunner(database, conn) {
|
|
841
|
+
switch (database) {
|
|
842
|
+
case "sql":
|
|
843
|
+
return new SQLRunner(conn);
|
|
844
|
+
case "sqlite":
|
|
845
|
+
return new SQLiteRunner(conn);
|
|
846
|
+
case "pg":
|
|
847
|
+
return new PgRunner(conn);
|
|
848
|
+
default:
|
|
849
|
+
throw ConfigurationError.unknownDatabaseType(database);
|
|
850
|
+
}
|
|
851
|
+
}
|
|
734
852
|
function loadMigrationConfig(configFile) {
|
|
735
853
|
const reader = new FileMigrationConfigReader(configFile);
|
|
736
854
|
return reader.loadFile();
|
|
@@ -751,6 +869,7 @@ var MigrationRunnerFactory = class _MigrationRunnerFactory {
|
|
|
751
869
|
}
|
|
752
870
|
static createConnection(config) {
|
|
753
871
|
return __async(this, null, function* () {
|
|
872
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
754
873
|
let conn = null;
|
|
755
874
|
switch (config.database) {
|
|
756
875
|
case "sql":
|
|
@@ -761,7 +880,8 @@ var MigrationRunnerFactory = class _MigrationRunnerFactory {
|
|
|
761
880
|
password: process.env.SQL_PASSWORD
|
|
762
881
|
}, config.sql);
|
|
763
882
|
try {
|
|
764
|
-
|
|
883
|
+
const mysql = yield import("mysql2/promise");
|
|
884
|
+
conn = yield ((_b = (_a = mysql.default) == null ? void 0 : _a.createConnection) != null ? _b : mysql.createConnection)(settings);
|
|
765
885
|
return conn;
|
|
766
886
|
} catch (error) {
|
|
767
887
|
throw DatabaseConnectionError.connectionFailed("sql", toError(error).message);
|
|
@@ -771,14 +891,32 @@ var MigrationRunnerFactory = class _MigrationRunnerFactory {
|
|
|
771
891
|
throw ConfigurationError.missingDatabaseConfiguration("sqlite");
|
|
772
892
|
}
|
|
773
893
|
try {
|
|
774
|
-
|
|
894
|
+
const sqlite = yield import("sqlite");
|
|
895
|
+
const sqlite3 = yield import("sqlite3");
|
|
896
|
+
conn = yield ((_d = (_c = sqlite.default) == null ? void 0 : _c.open) != null ? _d : sqlite.open)({
|
|
775
897
|
filename: config.sqlite.database,
|
|
776
|
-
driver: sqlite3.Database
|
|
898
|
+
driver: (_f = (_e = sqlite3.default) == null ? void 0 : _e.Database) != null ? _f : sqlite3.Database
|
|
777
899
|
});
|
|
778
900
|
return conn;
|
|
779
901
|
} catch (error) {
|
|
780
902
|
throw DatabaseConnectionError.connectionFailed("sqlite", toError(error).message);
|
|
781
903
|
}
|
|
904
|
+
case "pg":
|
|
905
|
+
if (!config.pg && !process.env.DATABASE_URL) {
|
|
906
|
+
throw ConfigurationError.missingDatabaseConfiguration("pg");
|
|
907
|
+
}
|
|
908
|
+
try {
|
|
909
|
+
const pgcfg = (_g = config.pg) != null ? _g : {};
|
|
910
|
+
const connectionString = (_h = pgcfg.connectionString) != null ? _h : process.env.DATABASE_URL;
|
|
911
|
+
const settings2 = connectionString ? { connectionString, ssl: pgcfg.ssl } : __spreadProps(__spreadValues({}, pgcfg), { password: (_i = pgcfg.password) != null ? _i : process.env.PG_PASSWORD });
|
|
912
|
+
const pg = yield import("pg");
|
|
913
|
+
const Client = (_k = (_j = pg.default) == null ? void 0 : _j.Client) != null ? _k : pg.Client;
|
|
914
|
+
conn = new Client(settings2);
|
|
915
|
+
yield conn.connect();
|
|
916
|
+
return conn;
|
|
917
|
+
} catch (error) {
|
|
918
|
+
throw DatabaseConnectionError.connectionFailed("pg", toError(error).message);
|
|
919
|
+
}
|
|
782
920
|
default:
|
|
783
921
|
throw ConfigurationError.unknownDatabaseType(config.database);
|
|
784
922
|
}
|
|
@@ -799,16 +937,7 @@ var MigrationRunnerFactory = class _MigrationRunnerFactory {
|
|
|
799
937
|
sqlrunner = conn;
|
|
800
938
|
driverConnection = null;
|
|
801
939
|
} else {
|
|
802
|
-
|
|
803
|
-
case "sql":
|
|
804
|
-
sqlrunner = new SQLRunner(conn);
|
|
805
|
-
break;
|
|
806
|
-
case "sqlite":
|
|
807
|
-
sqlrunner = new SQLiteRunner(conn);
|
|
808
|
-
break;
|
|
809
|
-
default:
|
|
810
|
-
throw ConfigurationError.unknownDatabaseType(config.database);
|
|
811
|
-
}
|
|
940
|
+
sqlrunner = makeRunner(config.database, conn);
|
|
812
941
|
}
|
|
813
942
|
const setup = new MigrationSetup(sqlrunner, config);
|
|
814
943
|
const read_strategy = this.getReadStategy(config);
|
|
@@ -820,17 +949,7 @@ var MigrationRunnerFactory = class _MigrationRunnerFactory {
|
|
|
820
949
|
createEmpty(config) {
|
|
821
950
|
return __async(this, null, function* () {
|
|
822
951
|
const conn = null;
|
|
823
|
-
|
|
824
|
-
switch (config.database) {
|
|
825
|
-
case "sql":
|
|
826
|
-
sqlrunner = new SQLRunner(conn);
|
|
827
|
-
break;
|
|
828
|
-
case "sqlite":
|
|
829
|
-
sqlrunner = new SQLiteRunner(conn);
|
|
830
|
-
break;
|
|
831
|
-
default:
|
|
832
|
-
throw ConfigurationError.unknownDatabaseType(config.database);
|
|
833
|
-
}
|
|
952
|
+
const sqlrunner = makeRunner(config.database, conn);
|
|
834
953
|
const setup = new MigrationSetup(sqlrunner, config);
|
|
835
954
|
const read_strategy = this.getReadStategy(config);
|
|
836
955
|
const migration_files = new MigrationDirectoryReader(config.migration_folder, read_strategy, sqlrunner, config.database);
|
|
@@ -843,6 +962,8 @@ var MigrationRunnerFactory = class _MigrationRunnerFactory {
|
|
|
843
962
|
return MySqlDialectParser;
|
|
844
963
|
case "sqlite":
|
|
845
964
|
return SqliteDialectParser;
|
|
965
|
+
case "pg":
|
|
966
|
+
return PgDialectParser;
|
|
846
967
|
default:
|
|
847
968
|
throw ConfigurationError.unknownDatabaseType(config.database);
|
|
848
969
|
}
|
|
@@ -1029,6 +1150,8 @@ var FileMigrationConfigReader = class {
|
|
|
1029
1150
|
config.database = "sql";
|
|
1030
1151
|
} else if (config.sqlite) {
|
|
1031
1152
|
config.database = "sqlite";
|
|
1153
|
+
} else if (config.pg) {
|
|
1154
|
+
config.database = "pg";
|
|
1032
1155
|
} else {
|
|
1033
1156
|
throw ConfigurationError.missingRequiredProperty("database");
|
|
1034
1157
|
}
|
|
@@ -1343,6 +1466,9 @@ function createSeedFactory(options) {
|
|
|
1343
1466
|
export {
|
|
1344
1467
|
MySQLMigrationRunner as MigrationRunner,
|
|
1345
1468
|
MigrationRunnerFactory,
|
|
1469
|
+
PgRunner,
|
|
1470
|
+
SQLRunner,
|
|
1471
|
+
SQLiteRunner,
|
|
1346
1472
|
createSeedFactory,
|
|
1347
1473
|
loadMigrationConfig,
|
|
1348
1474
|
runSeedsWithRunner
|