@dbml/cli 7.0.0 → 7.1.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.
@@ -1,9 +1,11 @@
1
- import path from 'path';
1
+ import childProcess from 'child_process';
2
2
  import fs from 'fs';
3
+ import path from 'path';
3
4
  import util from 'util';
4
- import childProcess from 'child_process';
5
5
  import stripAnsi from 'strip-ansi';
6
- import { scanDirNames } from './testHelpers';
6
+ import {
7
+ scanDirNames,
8
+ } from './testHelpers';
7
9
 
8
10
  const exec = util.promisify(childProcess.exec);
9
11
 
@@ -20,7 +22,9 @@ describe('@dbml/cli', () => {
20
22
  fs.mkdirSync(path.join(dirName, './out-files'));
21
23
  }
22
24
 
23
- const { stdout } = await exec(`node ${args.join(' ')}`);
25
+ const {
26
+ stdout,
27
+ } = await exec(`node ${args.join(' ')}`);
24
28
  const expectStdout = fs.readFileSync(path.join(dirName, './stdout.txt'), 'utf-8');
25
29
  const actualStdout = stripAnsi(stdout);
26
30
 
@@ -1,4 +1,6 @@
1
1
  require = require('esm')(module);
2
- const { db2dbml } = require('../src');
2
+ const {
3
+ db2dbml,
4
+ } = require('../src');
3
5
 
4
6
  db2dbml(process.argv);
@@ -1,4 +1,6 @@
1
1
  require = require('esm')(module);
2
- const { dbml2sql } = require('../src');
2
+ const {
3
+ dbml2sql,
4
+ } = require('../src');
3
5
 
4
6
  dbml2sql(process.argv);
@@ -1,4 +1,6 @@
1
1
  require = require('esm')(module);
2
- const { sql2dbml } = require('../src');
2
+ const {
3
+ sql2dbml,
4
+ } = require('../src');
3
5
 
4
6
  sql2dbml(process.argv);
package/eslint.config.ts CHANGED
@@ -4,6 +4,41 @@ import { defineConfig } from 'eslint/config';
4
4
  import stylistic from '@stylistic/eslint-plugin';
5
5
  import tseslint from 'typescript-eslint';
6
6
  import tsparser from '@typescript-eslint/parser';
7
+ import importPlugin from 'eslint-plugin-import';
8
+
9
+ const IMPORT_ORDER_RULES = {
10
+ 'import/order': ['error', {
11
+ groups: [
12
+ 'builtin',
13
+ 'external',
14
+ 'internal',
15
+ 'parent',
16
+ 'sibling',
17
+ 'index',
18
+ ],
19
+ 'newlines-between': 'never',
20
+ alphabetize: {
21
+ order: 'asc',
22
+ caseInsensitive: false,
23
+ },
24
+ }],
25
+ 'import/newline-after-import': ['error', { count: 1 }],
26
+ 'sort-imports': ['error', {
27
+ ignoreDeclarationSort: true,
28
+ ignoreCase: false,
29
+ memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'],
30
+ }],
31
+ };
32
+
33
+ const IMPORT_SETTINGS = {
34
+ 'import/resolver': {
35
+ typescript: {
36
+ alwaysTryTypes: true,
37
+ project: './tsconfig.json',
38
+ },
39
+ node: true,
40
+ },
41
+ };
7
42
 
8
43
  export default defineConfig(
9
44
  eslint.configs.recommended,
@@ -41,8 +76,18 @@ export default defineConfig(
41
76
  },
42
77
  plugins: {
43
78
  '@stylistic': stylistic,
79
+ import: importPlugin,
44
80
  },
81
+ settings: IMPORT_SETTINGS,
45
82
  rules: {
83
+ ...IMPORT_ORDER_RULES,
84
+ '@stylistic/object-curly-newline': ['error', {
85
+ ObjectExpression: { multiline: true, minProperties: 1 },
86
+ ObjectPattern: { multiline: true, minProperties: 1 },
87
+ ImportDeclaration: { multiline: true, minProperties: 1 },
88
+ ExportDeclaration: { multiline: true, minProperties: 1 },
89
+ }],
90
+ '@stylistic/object-property-newline': ['error', { allowAllPropertiesOnSameLine: false }],
46
91
  '@typescript-eslint/no-explicit-any': 'off',
47
92
  'no-use-before-define': 'off',
48
93
  'no-continue': 'off',
@@ -59,18 +104,10 @@ export default defineConfig(
59
104
  '@typescript-eslint/consistent-return': [
60
105
  'error',
61
106
  ],
62
- '@stylistic/quotes': ['error', 'single', { 'avoidEscape': true }],
107
+ '@stylistic/quotes': ['error', 'single', { avoidEscape: true }],
63
108
  '@stylistic/max-statements-per-line': 'off',
64
109
  '@stylistic/operator-linebreak': ['error', 'before', { overrides: { '=': 'after' } }],
65
110
  },
66
- settings: {
67
- 'import/resolver': {
68
- typescript: {
69
- alwaysTryTypes: true,
70
- project: 'packages/*/{ts,js}config.json',
71
- },
72
- },
73
- },
74
111
  },
75
112
  {
76
113
  files: ['**/*.test.js', '**/*.spec.js', '**/*.test.ts', '**/*.spec.ts'],
package/lib/index.js CHANGED
@@ -21,26 +21,147 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
21
21
  }) : target, mod));
22
22
  let commander = require("commander");
23
23
  commander = __toESM(commander);
24
+ let path = require("path");
25
+ path = __toESM(path);
26
+ let __dbml_connector = require("@dbml/connector");
24
27
  let __dbml_core = require("@dbml/core");
25
- let figures = require("figures");
26
- figures = __toESM(figures);
27
28
  let chalk = require("chalk");
28
29
  chalk = __toESM(chalk);
29
- let path = require("path");
30
- path = __toESM(path);
30
+ let figures = require("figures");
31
+ figures = __toESM(figures);
32
+ let winston = require("winston");
31
33
  let fs = require("fs");
32
34
  fs = __toESM(fs);
33
- let winston = require("winston");
34
- let __dbml_connector = require("@dbml/connector");
35
- var config_default = {
36
- mysql: { name: "MySQL" },
37
- mysqlLegacy: { name: "MySQL" },
38
- postgres: { name: "PostgreSQL" },
39
- postgresLegacy: { name: "PostgreSQL" },
40
- mssql: { name: "SQL Server" },
41
- oracle: { name: "Oracle" },
42
- snowflake: { name: "Snowflake" }
35
+ const $schema = "https://json.schemastore.org/package";
36
+ const name = "@dbml/cli";
37
+ const version = "7.1.0-alpha.0";
38
+ const description = "";
39
+ const main = "lib/index.js";
40
+ const license = "Apache-2.0";
41
+ const scripts = {
42
+ "test": "vitest run",
43
+ "test:watch": "vitest watch",
44
+ "coverage": "vitest --coverage",
45
+ "build": "rm -rf ./lib && tsc --noEmit && vite build",
46
+ "dev": "vite build --watch",
47
+ "prepublish": "npm run build",
48
+ "lint": "eslint .",
49
+ "lint:fix": "eslint --fix ."
50
+ };
51
+ const publishConfig = { "access": "public" };
52
+ const bin = {
53
+ "dbml2sql": "bin/dbml2sql.js",
54
+ "sql2dbml": "bin/sql2dbml.js",
55
+ "db2dbml": "bin/db2dbml.js"
43
56
  };
57
+ const author = "Holistics <dev@holistics.io>";
58
+ const homepage = "https://dbml.dbdiagram.io";
59
+ const repository = "https://github.com/holistics/dbml/tree/master/packages/dbml-cli";
60
+ const keywords = ["dbml", "dbml-cli"];
61
+ const dependencies = {
62
+ "@babel/cli": "^7.21.0",
63
+ "@dbml/connector": "^7.1.0-alpha.0",
64
+ "@dbml/core": "^7.1.0-alpha.0",
65
+ "@dbml/parse": "^7.1.0-alpha.0",
66
+ "bluebird": "^3.5.5",
67
+ "chalk": "^2.4.2",
68
+ "commander": "^2.20.0",
69
+ "esm": "^3.2.25",
70
+ "figures": "^3.2.0",
71
+ "lodash-es": "^4.17.15",
72
+ "pegjs-require-import": "^0.0.2",
73
+ "strip-ansi": "^5.2.0",
74
+ "winston": "^3.2.1"
75
+ };
76
+ const gitHead = "109c30cccebfcb36b793945798d40963fb24d08c";
77
+ const engines = { "node": ">=18" };
78
+ var package_default = {
79
+ $schema,
80
+ name,
81
+ version,
82
+ description: "",
83
+ main,
84
+ license,
85
+ scripts,
86
+ publishConfig,
87
+ bin,
88
+ author,
89
+ homepage,
90
+ repository,
91
+ keywords,
92
+ dependencies,
93
+ gitHead,
94
+ engines
95
+ };
96
+ var { combine, timestamp, printf } = winston.format;
97
+ var consoleFormat = printf((info) => {
98
+ const { level, message } = info;
99
+ return ` ${chalk.default.red(level.toUpperCase())}: ${message}\n
100
+ A complete log can be found in:
101
+ ${path.default.resolve(process.cwd(), "dbml-error.log")}`;
102
+ });
103
+ var fileFormat = printf((info) => {
104
+ const { timestamp: ts, stack, rootError } = info;
105
+ let logContent = `${ts}\n${stack}\n`;
106
+ if (rootError) {
107
+ logContent += "\nROOT_ERROR:";
108
+ logContent += `\n${rootError.stack}`;
109
+ if (rootError.location) logContent += `\n${JSON.stringify(rootError.location)}`;
110
+ logContent += "\n";
111
+ }
112
+ return logContent;
113
+ });
114
+ var consoleLogger = (0, winston.createLogger)({
115
+ format: combine(consoleFormat),
116
+ transports: [new winston.transports.Console({ level: "error" })]
117
+ });
118
+ var fileLogger = (0, winston.createLogger)({
119
+ format: combine(timestamp(), fileFormat),
120
+ transports: [new winston.transports.File({
121
+ filename: "dbml-error.log",
122
+ level: "error"
123
+ })]
124
+ });
125
+ var logger = {
126
+ debug(msg) {
127
+ consoleLogger.debug(msg);
128
+ },
129
+ info(msg) {
130
+ consoleLogger.info(msg);
131
+ },
132
+ warn(msg) {
133
+ consoleLogger.warn(msg);
134
+ },
135
+ error(msg) {
136
+ consoleLogger.error(msg);
137
+ fileLogger.error(msg);
138
+ }
139
+ };
140
+ var logger_default = logger;
141
+ var OutputConsolePlugin = class {
142
+ static write(content) {
143
+ console.log(content);
144
+ }
145
+ };
146
+ var outputConsolePlugin_default = OutputConsolePlugin;
147
+ var OutputFilePlugin = class {
148
+ constructor(filePath, header) {
149
+ this.filePath = filePath;
150
+ this.header = header;
151
+ this.isWrite = false;
152
+ }
153
+ start() {
154
+ fs.default.writeFileSync(this.filePath, "");
155
+ this.stream = fs.default.createWriteStream(this.filePath, { flags: "a" });
156
+ if (this.header) this.stream.write(this.header);
157
+ this.isWrite = true;
158
+ }
159
+ write(content) {
160
+ if (!this.isWrite) this.start();
161
+ this.stream.write(content);
162
+ }
163
+ };
164
+ var outputFilePlugin_default = OutputFilePlugin;
44
165
  var freeGlobal = typeof global == "object" && global && global.Object === Object && global;
45
166
  var _freeGlobal_default = freeGlobal;
46
167
  var freeSelf = typeof self == "object" && self && self.Object === Object && self;
@@ -1038,82 +1159,23 @@ function generate(inputPaths, transform, outputPlugin) {
1038
1159
  }
1039
1160
  });
1040
1161
  }
1041
- function validateFilePlugin(_path) {
1042
- if (fs.default.statSync(_path).isDirectory(_path)) throw new Error("Expect input to be files");
1043
- }
1044
- var OutputConsolePlugin = class {
1045
- static write(content) {
1046
- console.log(content);
1047
- }
1048
- };
1049
- var outputConsolePlugin_default = OutputConsolePlugin;
1050
- var OutputFilePlugin = class {
1051
- constructor(filePath, header) {
1052
- this.filePath = filePath;
1053
- this.header = header;
1054
- this.isWrite = false;
1055
- }
1056
- start() {
1057
- fs.default.writeFileSync(this.filePath, "");
1058
- this.stream = fs.default.createWriteStream(this.filePath, { flags: "a" });
1059
- if (this.header) this.stream.write(this.header);
1060
- this.isWrite = true;
1061
- }
1062
- write(content) {
1063
- if (!this.isWrite) this.start();
1064
- this.stream.write(content);
1065
- }
1066
- };
1067
- var outputFilePlugin_default = OutputFilePlugin;
1068
- var { combine, timestamp, printf } = winston.format;
1069
- var consoleFormat = printf((info) => {
1070
- const { level, message } = info;
1071
- return ` ${chalk.default.red(level.toUpperCase())}: ${message}\n
1072
- A complete log can be found in:
1073
- ${path.default.resolve(process.cwd(), "dbml-error.log")}`;
1074
- });
1075
- var fileFormat = printf((info) => {
1076
- const { timestamp: timestamp$1, stack, rootError } = info;
1077
- let logContent = `${timestamp$1}\n${stack}\n`;
1078
- if (rootError) {
1079
- logContent += "\nROOT_ERROR:";
1080
- logContent += `\n${rootError.stack}`;
1081
- if (rootError.location) logContent += `\n${JSON.stringify(rootError.location)}`;
1082
- logContent += "\n";
1083
- }
1084
- return logContent;
1085
- });
1086
- var consoleLogger = (0, winston.createLogger)({
1087
- format: combine(consoleFormat),
1088
- transports: [new winston.transports.Console({ level: "error" })]
1089
- });
1090
- var fileLogger = (0, winston.createLogger)({
1091
- format: combine(timestamp(), fileFormat),
1092
- transports: [new winston.transports.File({
1093
- filename: "dbml-error.log",
1094
- level: "error"
1095
- })]
1096
- });
1097
- var logger = {
1098
- debug(msg) {
1099
- consoleLogger.debug(msg);
1100
- },
1101
- info(msg) {
1102
- consoleLogger.info(msg);
1103
- },
1104
- warn(msg) {
1105
- consoleLogger.warn(msg);
1106
- },
1107
- error(msg) {
1108
- consoleLogger.error(msg);
1109
- fileLogger.error(msg);
1110
- },
1111
- log(level, msg) {
1112
- const lvl = exports[level];
1113
- lvl(msg);
1162
+ async function connectionHandler(program$1) {
1163
+ try {
1164
+ const { connection, databaseType } = getConnectionOpt(program$1.args);
1165
+ const opts = program$1.opts();
1166
+ const schemaJson = await __dbml_connector.connector.fetchSchemaJson(connection, databaseType);
1167
+ if (!opts.outFile && !opts.outDir) {
1168
+ const res = __dbml_core.importer.generateDbml(schemaJson);
1169
+ outputConsolePlugin_default.write(res);
1170
+ } else if (opts.outFile) {
1171
+ const res = __dbml_core.importer.generateDbml(schemaJson);
1172
+ new outputFilePlugin_default(resolvePaths(opts.outFile)).write(res);
1173
+ console.log(` ${chalk.default.green(figures.default.main.tick)} Generated DBML file from database's connection: ${path.default.basename(opts.outFile)}`);
1174
+ }
1175
+ } catch (error) {
1176
+ logger_default.error(error);
1114
1177
  }
1115
- };
1116
- var logger_default = logger;
1178
+ }
1117
1179
  var DomainError = class extends Error {
1118
1180
  constructor(message, rootError = {}) {
1119
1181
  super(message);
@@ -1133,24 +1195,18 @@ var SyntaxError = class extends domainError_default {
1133
1195
  }
1134
1196
  };
1135
1197
  var syntaxError_default = SyntaxError;
1136
- async function importHandler(program$1) {
1137
- try {
1138
- const inputPaths = resolvePaths(program$1.args);
1139
- validateInputFilePaths(inputPaths, validateFilePlugin);
1140
- const opts = program$1.opts();
1141
- const format$1 = getFormatOpt(opts);
1142
- if (!opts.outFile && !opts.outDir) generate(inputPaths, (sql) => __dbml_core.importer.import(sql, format$1), outputConsolePlugin_default);
1143
- else if (opts.outFile) {
1144
- generate(inputPaths, (sql) => __dbml_core.importer.import(sql, format$1), new outputFilePlugin_default(resolvePaths(opts.outFile)));
1145
- console.log(` ${chalk.default.green(figures.default.main.tick)} Generated DBML file from SQL file (${config_default[format$1].name}): ${path.default.basename(opts.outFile)}`);
1146
- }
1147
- } catch (error) {
1148
- if ("diags" in error) {
1149
- logger_default.error(`\n ${error.diags.map((diag) => new syntaxError_default(diag.filepath, diag)).map(({ message }) => message).join("\n ")}`);
1150
- return;
1151
- }
1152
- throw error;
1153
- }
1198
+ var config = {
1199
+ mysql: { name: "MySQL" },
1200
+ mysqlLegacy: { name: "MySQL" },
1201
+ postgres: { name: "PostgreSQL" },
1202
+ postgresLegacy: { name: "PostgreSQL" },
1203
+ mssql: { name: "SQL Server" },
1204
+ oracle: { name: "Oracle" },
1205
+ snowflake: { name: "Snowflake" }
1206
+ };
1207
+ var config_default = config;
1208
+ function validateFilePlugin(_path) {
1209
+ if (fs.default.statSync(_path).isDirectory()) throw new Error("Expect input to be files");
1154
1210
  }
1155
1211
  async function exportHandler(program$1) {
1156
1212
  try {
@@ -1169,86 +1225,29 @@ async function exportHandler(program$1) {
1169
1225
  console.log(` ${chalk.default.green(figures.default.main.tick)} Generated SQL dump file (${config_default[format$1].name}): ${path.default.basename(opts.outFile)}`);
1170
1226
  }
1171
1227
  } catch (error) {
1172
- logger_default.error(`\n ${error.diags.map((diag) => new syntaxError_default(diag.filepath, diag)).map(({ message }) => message).join("\n ")}`);
1228
+ const e = error;
1229
+ logger_default.error(`\n ${e.diags.map((diag) => new syntaxError_default(diag.filepath ?? "", diag)).map(({ message }) => message).join("\n ")}`);
1173
1230
  }
1174
1231
  }
1175
- async function connectionHandler(program$1) {
1232
+ async function importHandler(program$1) {
1176
1233
  try {
1177
- const { connection, databaseType } = getConnectionOpt(program$1.args);
1234
+ const inputPaths = resolvePaths(program$1.args);
1235
+ validateInputFilePaths(inputPaths, validateFilePlugin);
1178
1236
  const opts = program$1.opts();
1179
- const schemaJson = await __dbml_connector.connector.fetchSchemaJson(connection, databaseType);
1180
- if (!opts.outFile && !opts.outDir) {
1181
- const res = __dbml_core.importer.generateDbml(schemaJson);
1182
- outputConsolePlugin_default.write(res);
1183
- } else if (opts.outFile) {
1184
- const res = __dbml_core.importer.generateDbml(schemaJson);
1185
- new outputFilePlugin_default(resolvePaths(opts.outFile)).write(res);
1186
- console.log(` ${chalk.default.green(figures.default.main.tick)} Generated DBML file from database's connection: ${path.default.basename(opts.outFile)}`);
1237
+ const format$1 = getFormatOpt(opts);
1238
+ if (!opts.outFile && !opts.outDir) generate(inputPaths, (sql) => __dbml_core.importer.import(sql, format$1), outputConsolePlugin_default);
1239
+ else if (opts.outFile) {
1240
+ generate(inputPaths, (sql) => __dbml_core.importer.import(sql, format$1), new outputFilePlugin_default(resolvePaths(opts.outFile)));
1241
+ console.log(` ${chalk.default.green(figures.default.main.tick)} Generated DBML file from SQL file (${config_default[format$1].name}): ${path.default.basename(opts.outFile)}`);
1187
1242
  }
1188
1243
  } catch (error) {
1189
- logger_default.error(error);
1244
+ if (error instanceof __dbml_core.CompilerError) {
1245
+ logger_default.error(`\n ${error.diags.map((diag) => new syntaxError_default(diag.filepath ?? "", diag)).map(({ message }) => message).join("\n ")}`);
1246
+ return;
1247
+ }
1248
+ throw error;
1190
1249
  }
1191
1250
  }
1192
- const $schema = "https://json.schemastore.org/package";
1193
- const name = "@dbml/cli";
1194
- const version = "7.0.0";
1195
- const description = "";
1196
- const main = "lib/index.js";
1197
- const license = "Apache-2.0";
1198
- const scripts = {
1199
- "test": "vitest run",
1200
- "test:watch": "vitest watch",
1201
- "coverage": "vitest --coverage",
1202
- "build": "rm -rf ./lib && tsc --noEmit && vite build",
1203
- "dev": "vite build --watch",
1204
- "prepublish": "npm run build",
1205
- "lint": "eslint .",
1206
- "lint:fix": "eslint --fix ."
1207
- };
1208
- const publishConfig = { "access": "public" };
1209
- const bin = {
1210
- "dbml2sql": "bin/dbml2sql.js",
1211
- "sql2dbml": "bin/sql2dbml.js",
1212
- "db2dbml": "bin/db2dbml.js"
1213
- };
1214
- const author = "Holistics <dev@holistics.io>";
1215
- const homepage = "https://dbml.dbdiagram.io";
1216
- const repository = "https://github.com/holistics/dbml/tree/master/packages/dbml-cli";
1217
- const keywords = ["dbml", "dbml-cli"];
1218
- const dependencies = {
1219
- "@babel/cli": "^7.21.0",
1220
- "@dbml/connector": "^7.0.0",
1221
- "@dbml/core": "^7.0.0",
1222
- "bluebird": "^3.5.5",
1223
- "chalk": "^2.4.2",
1224
- "commander": "^2.20.0",
1225
- "esm": "^3.2.25",
1226
- "figures": "^3.2.0",
1227
- "lodash-es": "^4.17.15",
1228
- "pegjs-require-import": "^0.0.2",
1229
- "strip-ansi": "^5.2.0",
1230
- "winston": "^3.2.1"
1231
- };
1232
- const gitHead = "d9579d7cf95b7cafa9f083529393f0206c0acc98";
1233
- const engines = { "node": ">=18" };
1234
- var package_default = {
1235
- $schema,
1236
- name,
1237
- version,
1238
- description: "",
1239
- main,
1240
- license,
1241
- scripts,
1242
- publishConfig,
1243
- bin,
1244
- author,
1245
- homepage,
1246
- repository,
1247
- keywords,
1248
- dependencies,
1249
- gitHead,
1250
- engines
1251
- };
1252
1251
  function showHelp(args) {
1253
1252
  if (args.length < 3) commander.default.help();
1254
1253
  }
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": "7.0.0",
4
+ "version": "7.1.0-alpha.0",
5
5
  "description": "",
6
6
  "main": "lib/index.js",
7
7
  "license": "Apache-2.0",
@@ -32,8 +32,9 @@
32
32
  ],
33
33
  "dependencies": {
34
34
  "@babel/cli": "^7.21.0",
35
- "@dbml/connector": "^7.0.0",
36
- "@dbml/core": "^7.0.0",
35
+ "@dbml/connector": "^7.1.0-alpha.0",
36
+ "@dbml/core": "^7.1.0-alpha.0",
37
+ "@dbml/parse": "^7.1.0-alpha.0",
37
38
  "bluebird": "^3.5.5",
38
39
  "chalk": "^2.4.2",
39
40
  "commander": "^2.20.0",
@@ -44,7 +45,7 @@
44
45
  "strip-ansi": "^5.2.0",
45
46
  "winston": "^3.2.1"
46
47
  },
47
- "gitHead": "d9579d7cf95b7cafa9f083529393f0206c0acc98",
48
+ "gitHead": "109c30cccebfcb36b793945798d40963fb24d08c",
48
49
  "engines": {
49
50
  "node": ">=18"
50
51
  }
@@ -1,4 +1,4 @@
1
- export default {
1
+ const config: Record<string, { name: string }> = {
2
2
  mysql: {
3
3
  name: 'MySQL',
4
4
  },
@@ -21,3 +21,5 @@ export default {
21
21
  name: 'Snowflake',
22
22
  },
23
23
  };
24
+
25
+ export default config;
@@ -1,19 +1,28 @@
1
- import { importer } from '@dbml/core';
2
- import { connector } from '@dbml/connector';
3
- import figures from 'figures';
4
- import chalk from 'chalk';
5
1
  import path from 'path';
6
2
  import {
7
- resolvePaths,
8
- getConnectionOpt,
9
- } from './utils';
3
+ connector,
4
+ } from '@dbml/connector';
5
+ import {
6
+ importer,
7
+ } from '@dbml/core';
8
+ import chalk from 'chalk';
9
+ import {
10
+ Command,
11
+ } from 'commander';
12
+ import figures from 'figures';
13
+ import logger from '../helpers/logger';
10
14
  import OutputConsolePlugin from './outputPlugins/outputConsolePlugin';
11
15
  import OutputFilePlugin from './outputPlugins/outputFilePlugin';
12
- import logger from '../helpers/logger';
16
+ import {
17
+ getConnectionOpt,
18
+ resolvePaths,
19
+ } from './utils';
13
20
 
14
- export default async function connectionHandler (program) {
21
+ export default async function connectionHandler (program: Command) {
15
22
  try {
16
- const { connection, databaseType } = getConnectionOpt(program.args);
23
+ const {
24
+ connection, databaseType,
25
+ } = getConnectionOpt(program.args);
17
26
  const opts = program.opts();
18
27
  const schemaJson = await connector.fetchSchemaJson(connection, databaseType);
19
28
 
@@ -1,27 +1,39 @@
1
- import figures from 'figures';
2
- import chalk from 'chalk';
3
1
  import path from 'path';
4
- import { exporter } from '@dbml/core';
5
2
  import {
6
- validateInputFilePaths,
7
- resolvePaths,
8
- getFormatOpt,
9
- generate,
10
- } from './utils';
11
- import { validateFilePlugin } from './validatePlugins/validatePlugins';
3
+ CompilerError, exporter,
4
+ } from '@dbml/core';
5
+ import type {
6
+ ExportFormat,
7
+ } from '@dbml/core';
8
+ import chalk from 'chalk';
9
+ import type {
10
+ Command,
11
+ } from 'commander';
12
+ import figures from 'figures';
13
+ import {
14
+ SyntaxError,
15
+ } from '../errors';
16
+ import logger from '../helpers/logger';
17
+ import config from './config';
12
18
  import OutputConsolePlugin from './outputPlugins/outputConsolePlugin';
13
19
  import OutputFilePlugin from './outputPlugins/outputFilePlugin';
14
- import config from './config';
15
- import logger from '../helpers/logger';
16
- import { SyntaxError } from '../errors';
20
+ import {
21
+ generate,
22
+ getFormatOpt,
23
+ resolvePaths,
24
+ validateInputFilePaths,
25
+ } from './utils';
26
+ import {
27
+ validateFilePlugin,
28
+ } from './validatePlugins/validatePlugins';
17
29
 
18
- export default async function exportHandler (program) {
30
+ export default async function exportHandler (program: Command) {
19
31
  try {
20
32
  const inputPaths = resolvePaths(program.args);
21
33
  validateInputFilePaths(inputPaths, validateFilePlugin);
22
34
  const opts = program.opts();
23
35
 
24
- const format = getFormatOpt(opts);
36
+ const format = getFormatOpt(opts) as ExportFormat;
25
37
 
26
38
  if (!opts.outFile && !opts.outDir) {
27
39
  generate(inputPaths, (dbml) => exporter.export(dbml, format), OutputConsolePlugin);
@@ -41,6 +53,9 @@ export default async function exportHandler (program) {
41
53
  console.log(` ${chalk.green(figures.main.tick)} Generated SQL dump file (${config[format].name}): ${path.basename(opts.outFile)}`);
42
54
  }
43
55
  } catch (error) {
44
- logger.error(`\n ${error.diags.map((diag) => new SyntaxError(diag.filepath, diag)).map(({ message }) => message).join('\n ')}`);
56
+ const e = error as CompilerError;
57
+ logger.error(`\n ${e.diags.map((diag) => new SyntaxError(diag.filepath ?? '', diag)).map(({
58
+ message,
59
+ }) => message).join('\n ')}`);
45
60
  }
46
61
  }
@@ -1,27 +1,39 @@
1
- import { importer } from '@dbml/core';
2
- import figures from 'figures';
3
- import chalk from 'chalk';
4
1
  import path from 'path';
2
+ import {
3
+ CompilerError, importer,
4
+ } from '@dbml/core';
5
+ import type {
6
+ ImportFormat,
7
+ } from '@dbml/core';
8
+ import chalk from 'chalk';
9
+ import {
10
+ Command,
11
+ } from 'commander';
12
+ import figures from 'figures';
13
+ import {
14
+ SyntaxError,
15
+ } from '../errors';
16
+ import logger from '../helpers/logger';
5
17
  import config from './config';
18
+ import OutputConsolePlugin from './outputPlugins/outputConsolePlugin';
19
+ import OutputFilePlugin from './outputPlugins/outputFilePlugin';
6
20
  import {
7
- validateInputFilePaths,
8
- resolvePaths,
9
- getFormatOpt,
10
21
  generate,
22
+ getFormatOpt,
23
+ resolvePaths,
24
+ validateInputFilePaths,
11
25
  } from './utils';
12
- import { validateFilePlugin } from './validatePlugins/validatePlugins';
13
- import OutputConsolePlugin from './outputPlugins/outputConsolePlugin';
14
- import OutputFilePlugin from './outputPlugins/outputFilePlugin';
15
- import logger from '../helpers/logger';
16
- import { SyntaxError } from '../errors';
26
+ import {
27
+ validateFilePlugin,
28
+ } from './validatePlugins/validatePlugins';
17
29
 
18
- export default async function importHandler (program) {
30
+ export default async function importHandler (program: Command) {
19
31
  try {
20
32
  const inputPaths = resolvePaths(program.args);
21
33
  validateInputFilePaths(inputPaths, validateFilePlugin);
22
34
  const opts = program.opts();
23
35
 
24
- const format = getFormatOpt(opts);
36
+ const format = getFormatOpt(opts) as ImportFormat;
25
37
 
26
38
  if (!opts.outFile && !opts.outDir) {
27
39
  generate(inputPaths, (sql) => importer.import(sql, format), OutputConsolePlugin);
@@ -31,8 +43,10 @@ export default async function importHandler (program) {
31
43
  console.log(` ${chalk.green(figures.main.tick)} Generated DBML file from SQL file (${config[format].name}): ${path.basename(opts.outFile)}`);
32
44
  }
33
45
  } catch (error) {
34
- if ('diags' in error) {
35
- logger.error(`\n ${error.diags.map((diag) => new SyntaxError(diag.filepath, diag)).map(({ message }) => message).join('\n ')}`);
46
+ if (error instanceof CompilerError) {
47
+ logger.error(`\n ${error.diags.map((diag) => new SyntaxError(diag.filepath ?? '', diag)).map(({
48
+ message,
49
+ }) => message).join('\n ')}`);
36
50
  return;
37
51
  }
38
52
  throw error;
@@ -1,14 +1,14 @@
1
1
  import program from 'commander';
2
- import importHandler from './import';
3
- import exportHandler from './export';
4
- import connectionHandler from './connector';
5
2
  import projectInfo from '../../package.json';
3
+ import connectionHandler from './connector';
4
+ import exportHandler from './export';
5
+ import importHandler from './import';
6
6
 
7
- function showHelp (args) {
7
+ function showHelp (args: string[]) {
8
8
  if (args.length < 3) program.help();
9
9
  }
10
10
 
11
- function dbml2sql (args) {
11
+ function dbml2sql (args: string[]) {
12
12
  program.version(projectInfo.version);
13
13
 
14
14
  program
@@ -26,7 +26,7 @@ function dbml2sql (args) {
26
26
  exportHandler(program);
27
27
  }
28
28
 
29
- function sql2dbml (args) {
29
+ function sql2dbml (args: string[]) {
30
30
  program.version(projectInfo.version);
31
31
 
32
32
  program
@@ -48,7 +48,7 @@ function sql2dbml (args) {
48
48
  importHandler(program);
49
49
  }
50
50
 
51
- function db2dbml (args) {
51
+ function db2dbml (args: string[]) {
52
52
  program.version(projectInfo.version);
53
53
 
54
54
  const description = `Generate DBML directly from a database
@@ -1,5 +1,5 @@
1
1
  class OutputConsolePlugin {
2
- static write (content) {
2
+ static write (content: string) {
3
3
  console.log(content);
4
4
  }
5
5
  }
@@ -1,7 +1,12 @@
1
1
  import fs from 'fs';
2
2
 
3
3
  class OutputFilePlugin {
4
- constructor (filePath, header) {
4
+ filePath: string;
5
+ header: string | undefined;
6
+ isWrite: boolean;
7
+ stream!: fs.WriteStream;
8
+
9
+ constructor (filePath: string, header?: string) {
5
10
  this.filePath = filePath;
6
11
  this.header = header;
7
12
  this.isWrite = false;
@@ -9,12 +14,14 @@ class OutputFilePlugin {
9
14
 
10
15
  start () {
11
16
  fs.writeFileSync(this.filePath, '');
12
- this.stream = fs.createWriteStream(this.filePath, { flags: 'a' });
17
+ this.stream = fs.createWriteStream(this.filePath, {
18
+ flags: 'a',
19
+ });
13
20
  if (this.header) this.stream.write(this.header);
14
21
  this.isWrite = true;
15
22
  }
16
23
 
17
- write (content) {
24
+ write (content: string) {
18
25
  if (!this.isWrite) this.start();
19
26
  this.stream.write(content);
20
27
  }
@@ -1,41 +1,57 @@
1
- import path from 'path';
2
1
  import fs from 'fs';
3
- import { CompilerError } from '@dbml/core';
4
- import { reduce } from 'lodash-es';
2
+ import path from 'path';
3
+ import {
4
+ CompilerError,
5
+ type ExportFormat,
6
+ } from '@dbml/core';
7
+ import {
8
+ reduce,
9
+ } from 'lodash-es';
10
+
11
+ interface OutputPlugin {
12
+ write(content: string): void;
13
+ }
14
+
15
+ interface ConnectionOpt {
16
+ connection: string;
17
+ databaseType: string;
18
+ }
5
19
 
6
- function resolvePaths (paths) {
20
+ function resolvePaths (paths: string): string;
21
+ function resolvePaths (paths: string[]): string[];
22
+ function resolvePaths (paths: string | string[]): string | string[] {
7
23
  if (!Array.isArray(paths)) {
8
24
  return path.resolve(process.cwd(), paths);
9
25
  }
10
26
  return paths.map((_path) => path.resolve(process.cwd(), _path));
11
27
  }
12
28
 
13
- function validateInputFilePaths (paths, validatePlugin) {
29
+ function validateInputFilePaths (paths: string[], validatePlugin: (_path: string) => void) {
14
30
  return paths.every((_path) => validatePlugin(_path));
15
31
  }
16
32
 
17
- function getFormatOpt (opts) {
33
+ function getFormatOpt (opts: Record<string, unknown>): ExportFormat {
18
34
  const formatOpts = Object.keys(opts).filter((opt) => {
19
35
  return ['postgres', 'mysql', 'mssql', 'postgresLegacy', 'mysqlLegacy', 'mssqlLegacy', 'oracle', 'snowflake'].includes(opt);
20
36
  });
21
37
 
22
- let format = 'postgres';
38
+ let format: ExportFormat = 'postgres';
23
39
  let cnt = 0;
24
40
 
25
41
  formatOpts.forEach((opt) => {
26
42
  if (opts[opt]) {
27
43
  cnt += 1;
28
44
  if (cnt > 1) throw new Error('Too many format options');
29
- format = opt;
45
+ format = opt as ExportFormat;
30
46
  }
31
47
  });
32
48
 
33
- return format;
49
+ return format as ExportFormat;
34
50
  }
35
51
 
36
- function getConnectionOpt (args) {
52
+ function getConnectionOpt (args: string[]): ConnectionOpt {
37
53
  const supportedDatabases = ['postgres', 'mysql', 'mssql', 'snowflake', 'bigquery', 'oracle'];
38
- const defaultConnectionOpt = {
54
+ const defaultConnectionOpt: ConnectionOpt = {
39
55
  connection: args[0],
40
56
  databaseType: 'unknown',
41
57
  };
@@ -61,7 +77,11 @@ function getConnectionOpt (args) {
61
77
  }, defaultConnectionOpt);
62
78
  }
63
79
 
64
- function generate (inputPaths, transform, outputPlugin) {
80
+ function generate (
81
+ inputPaths: string[],
82
+ transform: (source: string) => string,
83
+ outputPlugin: OutputPlugin,
84
+ ): void {
65
85
  inputPaths.forEach((_path) => {
66
86
  const source = fs.readFileSync(_path, 'utf-8');
67
87
  try {
@@ -70,7 +90,10 @@ function generate (inputPaths, transform, outputPlugin) {
70
90
  } catch (e) {
71
91
  if (e instanceof CompilerError) {
72
92
  throw e.map((diag) => ({
73
- ...diag, message: diag.message, filepath: path.basename(_path), stack: diag.stack,
93
+ ...diag,
94
+ message: diag.message,
95
+ filepath: path.basename(_path),
96
+ stack: diag.stack,
74
97
  }));
75
98
  }
76
99
  throw e;
@@ -1,8 +1,8 @@
1
1
  import fs from 'fs';
2
2
 
3
- function validateFilePlugin (_path) {
3
+ function validateFilePlugin (_path: string) {
4
4
  const stat = fs.statSync(_path);
5
- if (stat.isDirectory(_path)) {
5
+ if (stat.isDirectory()) {
6
6
  throw new Error('Expect input to be files');
7
7
  }
8
8
  }
@@ -1,5 +1,7 @@
1
1
  class DomainError extends Error {
2
- constructor (message, rootError = {}) {
2
+ rootError: unknown;
3
+
4
+ constructor (message: string, rootError: unknown = {}) {
3
5
  super(message);
4
6
  this.name = this.constructor.name;
5
7
  this.rootError = rootError;
@@ -1,8 +1,21 @@
1
- import { isEmpty } from 'lodash-es';
1
+ import {
2
+ isEmpty,
3
+ } from 'lodash-es';
2
4
  import DomainError from './domainError';
3
5
 
6
+ interface RootError {
7
+ location?: {
8
+ start: {
9
+ line: number;
10
+ column: number;
11
+ };
12
+ };
13
+ message?: string;
14
+ stack?: unknown;
15
+ }
16
+
4
17
  class SyntaxError extends DomainError {
5
- constructor (fileName, rootError = {}) {
18
+ constructor (fileName: string, rootError: RootError = {}) {
6
19
  let message = `You have a syntax error at "${fileName}"`;
7
20
 
8
21
  if (rootError.location) {
@@ -1,19 +1,30 @@
1
- import { createLogger, format, transports } from 'winston';
2
- import chalk from 'chalk';
3
1
  import path from 'path';
2
+ import chalk from 'chalk';
3
+ import {
4
+ createLogger, format, transports,
5
+ } from 'winston';
4
6
 
5
- const { combine, timestamp, printf } = format;
7
+ const {
8
+ combine, timestamp, printf,
9
+ } = format;
6
10
 
7
11
  const consoleFormat = printf((info) => {
8
- const { level, message } = info;
12
+ const {
13
+ level, message,
14
+ } = info;
9
15
  return ` ${chalk.red(level.toUpperCase())}: ${message}\n
10
16
  A complete log can be found in:
11
17
  ${path.resolve(process.cwd(), 'dbml-error.log')}`;
12
18
  });
13
19
 
14
20
  const fileFormat = printf((info) => {
15
- const { timestamp, stack, rootError } = info;
16
- let logContent = `${timestamp}\n${stack}\n`;
21
+ const {
22
+ timestamp: ts, stack, rootError,
23
+ } = info as unknown as { timestamp: string;
24
+ stack?: string;
25
+ rootError?: { stack?: string;
26
+ location?: unknown; }; };
27
+ let logContent = `${ts}\n${stack}\n`;
17
28
  if (rootError) {
18
29
  logContent += '\nROOT_ERROR:';
19
30
  logContent += `\n${rootError.stack}`;
@@ -30,7 +41,9 @@ const consoleLogger = createLogger({
30
41
  consoleFormat,
31
42
  ),
32
43
  transports: [
33
- new transports.Console({ level: 'error' }),
44
+ new transports.Console({
45
+ level: 'error',
46
+ }),
34
47
  ],
35
48
  });
36
49
 
@@ -40,28 +53,28 @@ const fileLogger = createLogger({
40
53
  fileFormat,
41
54
  ),
42
55
  transports: [
43
- new transports.File({ filename: 'dbml-error.log', level: 'error' }),
56
+ new transports.File({
57
+ filename: 'dbml-error.log',
58
+ level: 'error',
59
+ }),
44
60
  ],
45
61
  });
46
62
 
47
63
  const logger = {
48
- debug (msg) {
64
+ debug (msg: string) {
49
65
  consoleLogger.debug(msg);
50
66
  },
51
- info (msg) {
67
+ info (msg: string) {
52
68
  consoleLogger.info(msg);
53
69
  },
54
- warn (msg) {
70
+ warn (msg: string) {
55
71
  consoleLogger.warn(msg);
56
72
  },
57
- error (msg) {
73
+
74
+ error (msg: any) {
58
75
  consoleLogger.error(msg);
59
76
  fileLogger.error(msg);
60
77
  },
61
- log (level, msg) {
62
- const lvl = exports[level];
63
- lvl(msg);
64
- },
65
78
  };
66
79
 
67
80
  export default logger;
package/src/index.ts ADDED
@@ -0,0 +1,9 @@
1
+ import {
2
+ db2dbml, dbml2sql, sql2dbml,
3
+ } from './cli';
4
+
5
+ export {
6
+ dbml2sql,
7
+ sql2dbml,
8
+ db2dbml,
9
+ };
package/vite.config.ts CHANGED
@@ -14,7 +14,7 @@ export default defineConfig({
14
14
  outDir: 'lib',
15
15
  minify: false,
16
16
  lib: {
17
- entry: path.resolve(__dirname, 'src/index.js'),
17
+ entry: path.resolve(__dirname, 'src/index.ts'),
18
18
  fileName: 'index',
19
19
  formats: ['cjs'],
20
20
  },
package/src/index.js DELETED
@@ -1,7 +0,0 @@
1
- import { dbml2sql, sql2dbml, db2dbml } from './cli';
2
-
3
- export {
4
- dbml2sql,
5
- sql2dbml,
6
- db2dbml,
7
- };
File without changes