@dbml/cli 7.1.1 → 8.0.0-alpha.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/__tests__/db2dbml/mssql/dbml-error.log +330 -0
- package/__tests__/db2dbml/mysql/dbml-error.log +429 -0
- package/__tests__/db2dbml/oracle/dbml-error.log +462 -0
- package/__tests__/db2dbml/postgres/dbml-error.log +231 -0
- package/__tests__/dbml2sql/filename --mysql --out-file/dbml-error.log +0 -0
- package/__tests__/dbml2sql/filename --mysql --out-file/out-files/schema.sql +65 -0
- package/__tests__/dbml2sql/filename --mysql stdout/dbml-error.log +0 -0
- package/__tests__/dbml2sql/filename --oracle --out-file/dbml-error.log +0 -0
- package/__tests__/dbml2sql/filename --oracle --out-file/out-files/schema.sql +61 -0
- package/__tests__/dbml2sql/filename --oracle stdout/dbml-error.log +0 -0
- package/__tests__/dbml2sql/filename --out-file/dbml-error.log +0 -0
- package/__tests__/dbml2sql/filename --out-file/out-files/schema.sql +77 -0
- package/__tests__/dbml2sql/filename --postgres --out-file/dbml-error.log +0 -0
- package/__tests__/dbml2sql/filename --postgres --out-file/out-files/schema.sql +77 -0
- package/__tests__/dbml2sql/filename --postgres stdout/dbml-error.log +0 -0
- package/__tests__/dbml2sql/filename stdout/dbml-error.log +0 -0
- package/__tests__/dbml2sql/filenames --mysql --out-file/dbml-error.log +0 -0
- package/__tests__/dbml2sql/filenames --mysql --out-file/out-files/schema.sql +172 -0
- package/__tests__/dbml2sql/filenames --mysql stdout/dbml-error.log +0 -0
- package/__tests__/dbml2sql/filenames --oracle --out-file/dbml-error.log +0 -0
- package/__tests__/dbml2sql/filenames --oracle --out-file/out-files/schema.sql +172 -0
- package/__tests__/dbml2sql/filenames --oracle stdout/dbml-error.log +0 -0
- package/__tests__/dbml2sql/filenames --out-file/dbml-error.log +0 -0
- package/__tests__/dbml2sql/filenames --out-file/out-files/schema.sql +172 -0
- package/__tests__/dbml2sql/filenames --postgres --out-file/dbml-error.log +0 -0
- package/__tests__/dbml2sql/filenames --postgres --out-file/out-files/schema.sql +172 -0
- package/__tests__/dbml2sql/filenames --postgres stdout/dbml-error.log +0 -0
- package/__tests__/dbml2sql/filenames stdout/dbml-error.log +0 -0
- package/__tests__/dbml2sql/multifile complex stdout/dbml-error.log +0 -0
- package/__tests__/dbml2sql/multifile complex stdout/in-files/auth.dbml +4 -0
- package/__tests__/dbml2sql/multifile complex stdout/in-files/catalog.dbml +10 -0
- package/__tests__/dbml2sql/multifile complex stdout/in-files/enums.dbml +5 -0
- package/__tests__/dbml2sql/multifile complex stdout/in-files/main.dbml +15 -0
- package/__tests__/dbml2sql/multifile complex stdout/options.json +3 -0
- package/__tests__/dbml2sql/multifile complex stdout/stdout.txt +32 -0
- package/__tests__/dbml2sql/multiple_schema_mssql/dbml-error.log +30 -0
- package/__tests__/dbml2sql/multiple_schema_mssql/out-files/multiple_schema.out.sql +62 -0
- package/__tests__/dbml2sql/multiple_schema_mysql/dbml-error.log +30 -0
- package/__tests__/dbml2sql/multiple_schema_mysql/out-files/multiple_schema.out.sql +50 -0
- package/__tests__/dbml2sql/multiple_schema_oracle/dbml-error.log +0 -0
- package/__tests__/dbml2sql/multiple_schema_oracle/out-files/multiple_schema.out.sql +88 -0
- package/__tests__/dbml2sql/multiple_schema_pg/dbml-error.log +30 -0
- package/__tests__/dbml2sql/multiple_schema_pg/out-files/multiple_schema.out.sql +67 -0
- package/__tests__/dbml2sql/syntax-error/dbml-error.log +102 -0
- package/__tests__/sql2dbml/custom-error-alter-table-column-not-found --oracle/dbml-error.log +108 -0
- package/__tests__/sql2dbml/custom-error-alter-table-table-not-found --oracle/dbml-error.log +108 -0
- package/__tests__/sql2dbml/custom-error-column-comment-column-not-found --oracle/dbml-error.log +108 -0
- package/__tests__/sql2dbml/custom-error-column-comment-table-not-found --oracle/dbml-error.log +108 -0
- package/__tests__/sql2dbml/custom-error-create-index-table-not-found --oracle/dbml-error.log +108 -0
- package/__tests__/sql2dbml/custom-error-table-comment-table-not-found --oracle/dbml-error.log +108 -0
- package/__tests__/sql2dbml/filename --mssql --out-file/dbml-error.log +0 -0
- package/__tests__/sql2dbml/filename --mssql --out-file/out-files/schema.dbml +25 -0
- package/__tests__/sql2dbml/filename --mysql --out-file/dbml-error.log +0 -0
- package/__tests__/sql2dbml/filename --mysql --out-file/out-files/schema.dbml +74 -0
- package/__tests__/sql2dbml/filename --mysql stdout/dbml-error.log +0 -0
- package/__tests__/sql2dbml/filename --oracle --out-file/dbml-error.log +0 -0
- package/__tests__/sql2dbml/filename --oracle --out-file/out-files/schema.dbml +83 -0
- package/__tests__/sql2dbml/filename --out-file/dbml-error.log +0 -0
- package/__tests__/sql2dbml/filename --out-file/out-files/schema.dbml +74 -0
- package/__tests__/sql2dbml/filename --postgres --out-file/dbml-error.log +0 -0
- package/__tests__/sql2dbml/filename --postgres --out-file/out-files/schema.dbml +74 -0
- package/__tests__/sql2dbml/filename --postgres stdout/dbml-error.log +0 -0
- package/__tests__/sql2dbml/filename --snowflake stdout/dbml-error.log +0 -0
- package/__tests__/sql2dbml/filename stdout/dbml-error.log +0 -0
- package/__tests__/sql2dbml/filenames --mysql --out-file/dbml-error.log +0 -0
- package/__tests__/sql2dbml/filenames --mysql --out-file/out-files/schema.dbml +170 -0
- package/__tests__/sql2dbml/filenames --mysql stdout/dbml-error.log +0 -0
- package/__tests__/sql2dbml/filenames --out-file/dbml-error.log +0 -0
- package/__tests__/sql2dbml/filenames --out-file/out-files/schema.dbml +170 -0
- package/__tests__/sql2dbml/filenames --postgres --out-file/dbml-error.log +0 -0
- package/__tests__/sql2dbml/filenames --postgres --out-file/out-files/schema.dbml +170 -0
- package/__tests__/sql2dbml/filenames --postgres stdout/dbml-error.log +0 -0
- package/__tests__/sql2dbml/filenames stdout/dbml-error.log +0 -0
- package/__tests__/sql2dbml/multiple_schema_mssql/dbml-error.log +0 -0
- package/__tests__/sql2dbml/multiple_schema_mssql/out-files/multiple_schema.out.dbml +58 -0
- package/__tests__/sql2dbml/multiple_schema_mysql/dbml-error.log +0 -0
- package/__tests__/sql2dbml/multiple_schema_mysql/out-files/multiple_schema.out.dbml +136 -0
- package/__tests__/sql2dbml/multiple_schema_pg/dbml-error.log +0 -0
- package/__tests__/sql2dbml/multiple_schema_pg/out-files/multiple_schema.out.dbml +101 -0
- package/__tests__/sql2dbml/syntax-error/dbml-error.log +102 -0
- package/__tests__/sql2dbml/syntax-error-duplicate-endpoints --mssql/dbml-error.log +99 -0
- package/__tests__/sql2dbml/syntax-error-duplicate-endpoints --mysql/dbml-error.log +99 -0
- package/dbml-error.log +3 -0
- package/lib/index.js +129 -42
- package/package.json +5 -5
- package/src/NodeProjectLayout.ts +125 -0
- package/src/cli/export.ts +59 -35
- package/vite.config.ts +1 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
2026-04-11T10:16:02.804Z
|
|
2
|
+
undefined
|
|
3
|
+
|
|
4
|
+
2026-04-11T10:19:47.074Z
|
|
5
|
+
undefined
|
|
6
|
+
|
|
7
|
+
2026-04-11T10:53:31.236Z
|
|
8
|
+
undefined
|
|
9
|
+
|
|
10
|
+
2026-04-11T10:55:59.352Z
|
|
11
|
+
undefined
|
|
12
|
+
|
|
13
|
+
2026-04-11T11:14:08.082Z
|
|
14
|
+
undefined
|
|
15
|
+
|
|
16
|
+
2026-04-11T15:33:24.319Z
|
|
17
|
+
undefined
|
|
18
|
+
|
|
19
|
+
2026-04-17T08:28:12.644Z
|
|
20
|
+
undefined
|
|
21
|
+
|
|
22
|
+
2026-04-17T08:30:04.522Z
|
|
23
|
+
undefined
|
|
24
|
+
|
|
25
|
+
2026-04-21T10:03:46.911Z
|
|
26
|
+
undefined
|
|
27
|
+
|
|
28
|
+
2026-04-25T14:23:24.290Z
|
|
29
|
+
undefined
|
|
30
|
+
|
|
31
|
+
2026-04-25T14:24:44.457Z
|
|
32
|
+
undefined
|
|
33
|
+
|
|
34
|
+
2026-04-25T14:26:03.853Z
|
|
35
|
+
undefined
|
|
36
|
+
|
|
37
|
+
2026-04-25T14:27:23.238Z
|
|
38
|
+
undefined
|
|
39
|
+
|
|
40
|
+
2026-04-25T14:28:44.260Z
|
|
41
|
+
undefined
|
|
42
|
+
|
|
43
|
+
2026-04-25T14:39:04.973Z
|
|
44
|
+
undefined
|
|
45
|
+
|
|
46
|
+
2026-04-25T14:42:09.694Z
|
|
47
|
+
undefined
|
|
48
|
+
|
|
49
|
+
2026-04-25T14:46:18.763Z
|
|
50
|
+
undefined
|
|
51
|
+
|
|
52
|
+
2026-04-25T14:49:45.147Z
|
|
53
|
+
undefined
|
|
54
|
+
|
|
55
|
+
2026-04-25T14:52:17.585Z
|
|
56
|
+
undefined
|
|
57
|
+
|
|
58
|
+
2026-04-25T14:54:06.309Z
|
|
59
|
+
undefined
|
|
60
|
+
|
|
61
|
+
2026-04-25T14:55:33.033Z
|
|
62
|
+
undefined
|
|
63
|
+
|
|
64
|
+
2026-04-25T14:57:29.835Z
|
|
65
|
+
undefined
|
|
66
|
+
|
|
67
|
+
2026-04-25T14:59:18.940Z
|
|
68
|
+
undefined
|
|
69
|
+
|
|
70
|
+
2026-04-25T15:18:52.479Z
|
|
71
|
+
undefined
|
|
72
|
+
|
|
73
|
+
2026-04-25T15:45:10.950Z
|
|
74
|
+
undefined
|
|
75
|
+
|
|
76
|
+
2026-04-30T02:24:16.181Z
|
|
77
|
+
undefined
|
|
78
|
+
|
|
79
|
+
2026-04-30T02:27:03.580Z
|
|
80
|
+
undefined
|
|
81
|
+
|
|
82
|
+
2026-05-03T12:50:13.032Z
|
|
83
|
+
undefined
|
|
84
|
+
|
|
85
|
+
2026-05-03T12:55:31.060Z
|
|
86
|
+
undefined
|
|
87
|
+
|
|
88
|
+
2026-05-03T13:24:02.658Z
|
|
89
|
+
undefined
|
|
90
|
+
|
|
91
|
+
2026-05-04T15:14:09.165Z
|
|
92
|
+
undefined
|
|
93
|
+
|
|
94
|
+
2026-05-04T17:05:56.541Z
|
|
95
|
+
undefined
|
|
96
|
+
|
|
97
|
+
2026-05-04T17:07:08.426Z
|
|
98
|
+
undefined
|
|
99
|
+
|
package/dbml-error.log
ADDED
package/lib/index.js
CHANGED
|
@@ -32,9 +32,11 @@ figures = __toESM(figures);
|
|
|
32
32
|
let winston = require("winston");
|
|
33
33
|
let fs = require("fs");
|
|
34
34
|
fs = __toESM(fs);
|
|
35
|
+
let __dbml_parse = require("@dbml/parse");
|
|
36
|
+
let node_fs = require("node:fs");
|
|
35
37
|
const $schema = "https://json.schemastore.org/package";
|
|
36
38
|
const name = "@dbml/cli";
|
|
37
|
-
const version = "
|
|
39
|
+
const version = "8.0.0-alpha.0";
|
|
38
40
|
const description = "";
|
|
39
41
|
const main = "lib/index.js";
|
|
40
42
|
const license = "Apache-2.0";
|
|
@@ -60,9 +62,9 @@ const repository = "https://github.com/holistics/dbml/tree/master/packages/dbml-
|
|
|
60
62
|
const keywords = ["dbml", "dbml-cli"];
|
|
61
63
|
const dependencies = {
|
|
62
64
|
"@babel/cli": "^7.21.0",
|
|
63
|
-
"@dbml/connector": "^
|
|
64
|
-
"@dbml/core": "^
|
|
65
|
-
"@dbml/parse": "^
|
|
65
|
+
"@dbml/connector": "^8.0.0-alpha.0",
|
|
66
|
+
"@dbml/core": "^8.0.0-alpha.0",
|
|
67
|
+
"@dbml/parse": "^8.0.0-alpha.0",
|
|
66
68
|
"bluebird": "^3.5.5",
|
|
67
69
|
"chalk": "^2.4.2",
|
|
68
70
|
"commander": "^2.20.0",
|
|
@@ -73,7 +75,7 @@ const dependencies = {
|
|
|
73
75
|
"strip-ansi": "^5.2.0",
|
|
74
76
|
"winston": "^3.2.1"
|
|
75
77
|
};
|
|
76
|
-
const gitHead = "
|
|
78
|
+
const gitHead = "4b99e7eab601b7d53e268d5d80048ee035614a79";
|
|
77
79
|
const engines = { "node": ">=18" };
|
|
78
80
|
var package_default = {
|
|
79
81
|
$schema,
|
|
@@ -510,8 +512,8 @@ ListCache.prototype.get = _listCacheGet_default;
|
|
|
510
512
|
ListCache.prototype.has = _listCacheHas_default;
|
|
511
513
|
ListCache.prototype.set = _listCacheSet_default;
|
|
512
514
|
var _ListCache_default = ListCache;
|
|
513
|
-
var Map = _getNative_default(_root_default, "Map");
|
|
514
|
-
var _Map_default = Map;
|
|
515
|
+
var Map$1 = _getNative_default(_root_default, "Map");
|
|
516
|
+
var _Map_default = Map$1;
|
|
515
517
|
function mapCacheClear() {
|
|
516
518
|
this.size = 0;
|
|
517
519
|
this.__data__ = {
|
|
@@ -724,8 +726,8 @@ var DataView = _getNative_default(_root_default, "DataView");
|
|
|
724
726
|
var _DataView_default = DataView;
|
|
725
727
|
var Promise$1 = _getNative_default(_root_default, "Promise");
|
|
726
728
|
var _Promise_default = Promise$1;
|
|
727
|
-
var Set = _getNative_default(_root_default, "Set");
|
|
728
|
-
var _Set_default = Set;
|
|
729
|
+
var Set$1 = _getNative_default(_root_default, "Set");
|
|
730
|
+
var _Set_default = Set$1;
|
|
729
731
|
var mapTag$2 = "[object Map]", objectTag$1 = "[object Object]", promiseTag = "[object Promise]", setTag$2 = "[object Set]", weakMapTag = "[object WeakMap]";
|
|
730
732
|
var dataViewTag$1 = "[object DataView]";
|
|
731
733
|
var dataViewCtorString = _toSource_default(_DataView_default), mapCtorString = _toSource_default(_Map_default), promiseCtorString = _toSource_default(_Promise_default), setCtorString = _toSource_default(_Set_default), weakMapCtorString = _toSource_default(_WeakMap_default);
|
|
@@ -1176,25 +1178,76 @@ async function connectionHandler(program$1) {
|
|
|
1176
1178
|
logger_default.error(error);
|
|
1177
1179
|
}
|
|
1178
1180
|
}
|
|
1179
|
-
var
|
|
1180
|
-
constructor(
|
|
1181
|
-
|
|
1182
|
-
this.
|
|
1183
|
-
this.rootError = rootError;
|
|
1184
|
-
Error.captureStackTrace(this, this.constructor);
|
|
1181
|
+
var NodeProjectLayout = class NodeProjectLayout {
|
|
1182
|
+
constructor(entryPoints) {
|
|
1183
|
+
this.overlay = /* @__PURE__ */ new Map();
|
|
1184
|
+
this.entryPoints = [...entryPoints];
|
|
1185
1185
|
}
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
if (
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1186
|
+
setSource(filePath, content) {
|
|
1187
|
+
this.overlay.set(filePath.absolute, content);
|
|
1188
|
+
}
|
|
1189
|
+
getSource(filePath) {
|
|
1190
|
+
const absolutePath = filePath.absolute;
|
|
1191
|
+
if (this.overlay.has(absolutePath)) return this.overlay.get(absolutePath) ?? void 0;
|
|
1192
|
+
try {
|
|
1193
|
+
return (0, node_fs.readFileSync)(absolutePath, "utf-8");
|
|
1194
|
+
} catch {
|
|
1195
|
+
return;
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
deleteSource(filePath) {
|
|
1199
|
+
this.overlay.set(filePath.absolute, null);
|
|
1200
|
+
}
|
|
1201
|
+
clearSource() {
|
|
1202
|
+
this.overlay.clear();
|
|
1203
|
+
this.entryPoints = [];
|
|
1204
|
+
}
|
|
1205
|
+
exists(filePath) {
|
|
1206
|
+
return this.isFile(filePath) || this.isDirectory(filePath);
|
|
1207
|
+
}
|
|
1208
|
+
isFile(filePath) {
|
|
1209
|
+
const absolutePath = filePath.absolute;
|
|
1210
|
+
if (this.overlay.has(absolutePath)) return this.overlay.get(absolutePath) !== null;
|
|
1211
|
+
try {
|
|
1212
|
+
return (0, node_fs.statSync)(absolutePath).isFile();
|
|
1213
|
+
} catch {
|
|
1214
|
+
return false;
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
isDirectory(filePath) {
|
|
1218
|
+
const absolutePath = filePath.absolute;
|
|
1219
|
+
try {
|
|
1220
|
+
if ((0, node_fs.statSync)(absolutePath).isDirectory()) return true;
|
|
1221
|
+
} catch {}
|
|
1222
|
+
for (const [overlayPath, content] of this.overlay) {
|
|
1223
|
+
if (content === null) continue;
|
|
1224
|
+
if (overlayPath.startsWith(absolutePath)) return true;
|
|
1225
|
+
}
|
|
1226
|
+
return false;
|
|
1227
|
+
}
|
|
1228
|
+
listDirectory(dirPath) {
|
|
1229
|
+
const basePath = dirPath?.absolute ?? "/";
|
|
1230
|
+
const results = /* @__PURE__ */ new Set();
|
|
1231
|
+
try {
|
|
1232
|
+
for (const entry of (0, node_fs.readdirSync)(basePath)) results.add(basePath + entry);
|
|
1233
|
+
} catch {}
|
|
1234
|
+
for (const [abs, content] of this.overlay) {
|
|
1235
|
+
if (content === null) continue;
|
|
1236
|
+
if (!abs.startsWith(basePath)) continue;
|
|
1237
|
+
if (!abs.slice(basePath.length).includes("/")) results.add(abs);
|
|
1238
|
+
}
|
|
1239
|
+
for (const [overlayPath, content] of this.overlay) if (content === null) results.delete(overlayPath);
|
|
1240
|
+
return [...results].sort().map(__dbml_parse.Filepath.from);
|
|
1241
|
+
}
|
|
1242
|
+
getEntryPoints() {
|
|
1243
|
+
return this.entryPoints.filter((fp) => this.exists(fp));
|
|
1244
|
+
}
|
|
1245
|
+
clone() {
|
|
1246
|
+
const copy = new NodeProjectLayout([...this.entryPoints]);
|
|
1247
|
+
for (const [overlayPath, content] of this.overlay) copy.overlay.set(overlayPath, content);
|
|
1248
|
+
return copy;
|
|
1195
1249
|
}
|
|
1196
1250
|
};
|
|
1197
|
-
var syntaxError_default = SyntaxError;
|
|
1198
1251
|
var config = {
|
|
1199
1252
|
mysql: { name: "MySQL" },
|
|
1200
1253
|
mysqlLegacy: { name: "MySQL" },
|
|
@@ -1209,26 +1262,60 @@ function validateFilePlugin(_path) {
|
|
|
1209
1262
|
if (fs.default.statSync(_path).isDirectory()) throw new Error("Expect input to be files");
|
|
1210
1263
|
}
|
|
1211
1264
|
async function exportHandler(program$1) {
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1265
|
+
const inputPaths = resolvePaths(program$1.args);
|
|
1266
|
+
validateInputFilePaths(inputPaths, validateFilePlugin);
|
|
1267
|
+
const opts = program$1.opts();
|
|
1268
|
+
const format$1 = getFormatOpt(opts);
|
|
1269
|
+
const entryPoints = inputPaths.map((p) => new __dbml_parse.Filepath(p));
|
|
1270
|
+
const compiler = new __dbml_parse.Compiler();
|
|
1271
|
+
compiler.layout = new NodeProjectLayout(entryPoints);
|
|
1272
|
+
const outputPlugin = opts.outFile ? new outputFilePlugin_default(resolvePaths(opts.outFile), [
|
|
1273
|
+
"-- SQL dump generated using DBML (dbml.dbdiagram.io)\n",
|
|
1274
|
+
`-- Database: ${config_default[format$1].name}\n`,
|
|
1275
|
+
`-- Generated at: ${(/* @__PURE__ */ new Date()).toISOString()}\n\n`
|
|
1276
|
+
].join("")) : outputConsolePlugin_default;
|
|
1277
|
+
let hasErrors = false;
|
|
1278
|
+
for (const filepath of entryPoints) {
|
|
1279
|
+
const result = compiler.interpretFile(filepath);
|
|
1280
|
+
const errors = result.getErrors();
|
|
1281
|
+
if (errors.length > 0) {
|
|
1282
|
+
hasErrors = true;
|
|
1283
|
+
const isMultifile = compiler.reachableFiles(filepath).length > 1;
|
|
1284
|
+
logger_default.error(`\n ${errors.map((e) => {
|
|
1285
|
+
const pos = e.nodeOrToken.startPos;
|
|
1286
|
+
const line = pos.line + 1;
|
|
1287
|
+
const col = pos.column + 1;
|
|
1288
|
+
if (isMultifile) return `${e.filepath.basename}(${line},${col}): ${e.message}`;
|
|
1289
|
+
return `You have a syntax error at "${e.filepath.basename}" line ${line} column ${col}. ${e.message}`;
|
|
1290
|
+
}).join("\n ")}`);
|
|
1291
|
+
continue;
|
|
1226
1292
|
}
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1293
|
+
const db = result.getValue();
|
|
1294
|
+
if (!db) continue;
|
|
1295
|
+
const sql = __dbml_core.ModelExporter.export(__dbml_core.Parser.parseJSONToDatabase(db), format$1);
|
|
1296
|
+
outputPlugin.write(sql);
|
|
1230
1297
|
}
|
|
1298
|
+
if (!hasErrors && opts.outFile) console.log(` ${chalk.default.green(figures.default.main.tick)} Generated SQL dump file (${config_default[format$1].name}): ${path.default.basename(opts.outFile)}`);
|
|
1231
1299
|
}
|
|
1300
|
+
var DomainError = class extends Error {
|
|
1301
|
+
constructor(message, rootError = {}) {
|
|
1302
|
+
super(message);
|
|
1303
|
+
this.name = this.constructor.name;
|
|
1304
|
+
this.rootError = rootError;
|
|
1305
|
+
Error.captureStackTrace(this, this.constructor);
|
|
1306
|
+
}
|
|
1307
|
+
};
|
|
1308
|
+
var domainError_default = DomainError;
|
|
1309
|
+
var SyntaxError = class extends domainError_default {
|
|
1310
|
+
constructor(fileName, rootError = {}) {
|
|
1311
|
+
let message = `You have a syntax error at "${fileName}"`;
|
|
1312
|
+
if (rootError.location) message += ` line ${rootError.location.start.line} column ${rootError.location.start.column}`;
|
|
1313
|
+
message += ".";
|
|
1314
|
+
if (!isEmpty_default(rootError)) message += ` ${rootError.message}`;
|
|
1315
|
+
super(message, rootError);
|
|
1316
|
+
}
|
|
1317
|
+
};
|
|
1318
|
+
var syntaxError_default = SyntaxError;
|
|
1232
1319
|
async function importHandler(program$1) {
|
|
1233
1320
|
try {
|
|
1234
1321
|
const inputPaths = resolvePaths(program$1.args);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package",
|
|
3
3
|
"name": "@dbml/cli",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "8.0.0-alpha.0",
|
|
5
5
|
"description": "",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"license": "Apache-2.0",
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@babel/cli": "^7.21.0",
|
|
35
|
-
"@dbml/connector": "^
|
|
36
|
-
"@dbml/core": "^
|
|
37
|
-
"@dbml/parse": "^
|
|
35
|
+
"@dbml/connector": "^8.0.0-alpha.0",
|
|
36
|
+
"@dbml/core": "^8.0.0-alpha.0",
|
|
37
|
+
"@dbml/parse": "^8.0.0-alpha.0",
|
|
38
38
|
"bluebird": "^3.5.5",
|
|
39
39
|
"chalk": "^2.4.2",
|
|
40
40
|
"commander": "^2.20.0",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"strip-ansi": "^5.2.0",
|
|
46
46
|
"winston": "^3.2.1"
|
|
47
47
|
},
|
|
48
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "4b99e7eab601b7d53e268d5d80048ee035614a79",
|
|
49
49
|
"engines": {
|
|
50
50
|
"node": ">=18"
|
|
51
51
|
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import {
|
|
2
|
+
existsSync, readFileSync, readdirSync, statSync,
|
|
3
|
+
} from 'node:fs';
|
|
4
|
+
import {
|
|
5
|
+
type DbmlProjectLayout, Filepath,
|
|
6
|
+
} from '@dbml/parse';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A DbmlProjectLayout backed by the Node.js filesystem.
|
|
10
|
+
* Reads source files on demand from disk; setSource/deleteSource maintain an
|
|
11
|
+
* in-memory overlay (e.g. for unsaved edits) without touching the real FS.
|
|
12
|
+
*/
|
|
13
|
+
export class NodeProjectLayout implements DbmlProjectLayout {
|
|
14
|
+
// Overlay is an overriding map of file absolute paths to file content
|
|
15
|
+
// `null`: The file is deleted
|
|
16
|
+
private overlay = new Map<string, string | null>();
|
|
17
|
+
private entryPoints: Filepath[];
|
|
18
|
+
|
|
19
|
+
constructor (entryPoints: Filepath[]) {
|
|
20
|
+
this.entryPoints = [...entryPoints];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
setSource (filePath: Filepath, content: string): void {
|
|
24
|
+
this.overlay.set(filePath.absolute, content);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
getSource (filePath: Filepath): string | undefined {
|
|
28
|
+
const absolutePath = filePath.absolute;
|
|
29
|
+
|
|
30
|
+
// If overlay already has the file,
|
|
31
|
+
// return its content
|
|
32
|
+
if (this.overlay.has(absolutePath)) {
|
|
33
|
+
const value = this.overlay.get(absolutePath);
|
|
34
|
+
return value ?? undefined; // null (deleted) -> undefined
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
return readFileSync(absolutePath, 'utf-8');
|
|
38
|
+
} catch {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
deleteSource (filePath: Filepath): void {
|
|
44
|
+
this.overlay.set(filePath.absolute, null);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
clearSource (): void {
|
|
48
|
+
this.overlay.clear();
|
|
49
|
+
this.entryPoints = [];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
exists (filePath: Filepath): boolean {
|
|
53
|
+
return this.isFile(filePath) || this.isDirectory(filePath);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
isFile (filePath: Filepath): boolean {
|
|
57
|
+
const absolutePath = filePath.absolute;
|
|
58
|
+
|
|
59
|
+
if (this.overlay.has(absolutePath)) return this.overlay.get(absolutePath) !== null;
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
// `statSync` (not lstatSync) so symlinks resolve to their target, matching
|
|
63
|
+
// how node reads the file on disk.
|
|
64
|
+
return statSync(absolutePath).isFile();
|
|
65
|
+
} catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
isDirectory (filePath: Filepath): boolean {
|
|
71
|
+
const absolutePath = filePath.absolute;
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
// Exist in filesystem
|
|
75
|
+
if (statSync(absolutePath).isDirectory()) return true;
|
|
76
|
+
} catch {
|
|
77
|
+
// fall through: the path may exist only in the overlay
|
|
78
|
+
}
|
|
79
|
+
for (const [overlayPath, content] of this.overlay) {
|
|
80
|
+
if (content === null) continue;
|
|
81
|
+
if (overlayPath.startsWith(absolutePath)) return true;
|
|
82
|
+
}
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
listDirectory (dirPath?: Filepath): Filepath[] {
|
|
87
|
+
const basePath = dirPath?.absolute ?? '/';
|
|
88
|
+
const results = new Set<string>();
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
// Filesystem entries
|
|
92
|
+
for (const entry of readdirSync(basePath)) {
|
|
93
|
+
results.add(basePath + entry);
|
|
94
|
+
}
|
|
95
|
+
} catch {
|
|
96
|
+
// Not a readable directory - ignore
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Overlay additions: non-deleted files directly under base
|
|
100
|
+
for (const [abs, content] of this.overlay) {
|
|
101
|
+
if (content === null) continue;
|
|
102
|
+
if (!abs.startsWith(basePath)) continue;
|
|
103
|
+
if (!abs.slice(basePath.length).includes('/')) results.add(abs);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Remove overlay-deleted paths
|
|
107
|
+
for (const [overlayPath, content] of this.overlay) {
|
|
108
|
+
if (content === null) results.delete(overlayPath);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return [...results].sort().map(Filepath.from);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
getEntryPoints (): Filepath[] {
|
|
115
|
+
return this.entryPoints.filter((fp) => this.exists(fp));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
clone (): NodeProjectLayout {
|
|
119
|
+
const copy = new NodeProjectLayout([...this.entryPoints]);
|
|
120
|
+
for (const [overlayPath, content] of this.overlay) {
|
|
121
|
+
copy.overlay.set(overlayPath, content);
|
|
122
|
+
}
|
|
123
|
+
return copy;
|
|
124
|
+
}
|
|
125
|
+
}
|
package/src/cli/export.ts
CHANGED
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
} from '@dbml/core';
|
|
5
|
-
import type {
|
|
6
|
-
ExportFormat,
|
|
3
|
+
ModelExporter, Parser,
|
|
7
4
|
} from '@dbml/core';
|
|
5
|
+
import {
|
|
6
|
+
Compiler, Filepath,
|
|
7
|
+
} from '@dbml/parse';
|
|
8
8
|
import chalk from 'chalk';
|
|
9
9
|
import type {
|
|
10
10
|
Command,
|
|
11
11
|
} from 'commander';
|
|
12
12
|
import figures from 'figures';
|
|
13
13
|
import {
|
|
14
|
-
|
|
15
|
-
} from '../
|
|
14
|
+
NodeProjectLayout,
|
|
15
|
+
} from '../NodeProjectLayout';
|
|
16
16
|
import logger from '../helpers/logger';
|
|
17
17
|
import config from './config';
|
|
18
18
|
import OutputConsolePlugin from './outputPlugins/outputConsolePlugin';
|
|
19
19
|
import OutputFilePlugin from './outputPlugins/outputFilePlugin';
|
|
20
20
|
import {
|
|
21
|
-
generate,
|
|
22
21
|
getFormatOpt,
|
|
23
22
|
resolvePaths,
|
|
24
23
|
validateInputFilePaths,
|
|
@@ -27,35 +26,60 @@ import {
|
|
|
27
26
|
validateFilePlugin,
|
|
28
27
|
} from './validatePlugins/validatePlugins';
|
|
29
28
|
|
|
30
|
-
export default async function exportHandler (program: Command) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
29
|
+
export default async function exportHandler (program: Command): Promise<void> {
|
|
30
|
+
const inputPaths = resolvePaths(program.args);
|
|
31
|
+
validateInputFilePaths(inputPaths, validateFilePlugin);
|
|
32
|
+
const opts = program.opts();
|
|
33
|
+
const format = getFormatOpt(opts);
|
|
34
|
+
|
|
35
|
+
const entryPoints = inputPaths.map((p: string) => new Filepath(p));
|
|
36
|
+
const compiler = new Compiler();
|
|
37
|
+
compiler.layout = new NodeProjectLayout(entryPoints);
|
|
38
|
+
|
|
39
|
+
const outputPlugin = opts.outFile
|
|
40
|
+
? new OutputFilePlugin(
|
|
41
|
+
resolvePaths(opts.outFile as string),
|
|
42
|
+
[
|
|
43
|
+
'-- SQL dump generated using DBML (dbml.dbdiagram.io)\n',
|
|
44
|
+
`-- Database: ${(config as any)[format].name}\n`,
|
|
45
|
+
`-- Generated at: ${new Date().toISOString()}\n\n`,
|
|
46
|
+
].join(''),
|
|
47
|
+
)
|
|
48
|
+
: OutputConsolePlugin;
|
|
49
|
+
|
|
50
|
+
let hasErrors = false;
|
|
52
51
|
|
|
53
|
-
|
|
52
|
+
for (const filepath of entryPoints) {
|
|
53
|
+
const result = compiler.interpretFile(filepath);
|
|
54
|
+
const errors = result.getErrors();
|
|
55
|
+
|
|
56
|
+
if (errors.length > 0) {
|
|
57
|
+
hasErrors = true;
|
|
58
|
+
const isMultifile = compiler.reachableFiles(filepath).length > 1;
|
|
59
|
+
logger.error(
|
|
60
|
+
`\n ${errors
|
|
61
|
+
.map((e) => {
|
|
62
|
+
const pos = e.nodeOrToken.startPos;
|
|
63
|
+
const line = pos.line + 1;
|
|
64
|
+
const col = pos.column + 1;
|
|
65
|
+
if (isMultifile) {
|
|
66
|
+
return `${e.filepath.basename}(${line},${col}): ${e.message}`;
|
|
67
|
+
}
|
|
68
|
+
return `You have a syntax error at "${e.filepath.basename}" line ${line} column ${col}. ${e.message}`;
|
|
69
|
+
})
|
|
70
|
+
.join('\n ')}`,
|
|
71
|
+
);
|
|
72
|
+
continue;
|
|
54
73
|
}
|
|
55
|
-
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
74
|
+
|
|
75
|
+
const db = result.getValue();
|
|
76
|
+
if (!db) continue;
|
|
77
|
+
|
|
78
|
+
const sql = ModelExporter.export(Parser.parseJSONToDatabase(db as any), format);
|
|
79
|
+
outputPlugin.write(sql);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!hasErrors && opts.outFile) {
|
|
83
|
+
console.log(` ${chalk.green(figures.main.tick)} Generated SQL dump file (${(config as any)[format].name}): ${path.basename(opts.outFile)}`);
|
|
60
84
|
}
|
|
61
85
|
}
|