@chihqiang/sql-quicktype 0.0.1

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/dist/index.js ADDED
@@ -0,0 +1,1216 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __esm = (fn, res) => function __init() {
9
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
+ };
11
+ var __export = (target, all) => {
12
+ for (var name in all)
13
+ __defProp(target, name, { get: all[name], enumerable: true });
14
+ };
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") {
17
+ for (let key of __getOwnPropNames(from))
18
+ if (!__hasOwnProp.call(to, key) && key !== except)
19
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
+ }
21
+ return to;
22
+ };
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
24
+ // If the importer is in node compatibility mode or this is not an ESM
25
+ // file that has been converted to a CommonJS file using a Babel-
26
+ // compatible transform (i.e. "__esModule" has not been set), then set
27
+ // "default" to the CommonJS "module.exports" for node compatibility.
28
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
29
+ mod
30
+ ));
31
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
+
33
+ // src/generator/TypeScriptGenerator.ts
34
+ var TypeScriptGenerator_exports = {};
35
+ __export(TypeScriptGenerator_exports, {
36
+ TypeScriptGenerator: () => TypeScriptGenerator
37
+ });
38
+ var TypeScriptGenerator;
39
+ var init_TypeScriptGenerator = __esm({
40
+ "src/generator/TypeScriptGenerator.ts"() {
41
+ "use strict";
42
+ init_generator();
43
+ TypeScriptGenerator = class extends AGenerator {
44
+ constructor(options = { language: "typescript" }) {
45
+ super();
46
+ this.options = options;
47
+ }
48
+ /**
49
+ * 格式化字段名称(使用驼峰命名)
50
+ */
51
+ formatFieldName(name) {
52
+ return name.split("_").map((part, index) => {
53
+ if (index === 0) {
54
+ return part.toLowerCase();
55
+ }
56
+ return part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();
57
+ }).join("");
58
+ }
59
+ /**
60
+ * 生成整个数据库模式的类型定义
61
+ */
62
+ generateDatabase(database) {
63
+ let result = `// Database: ${database.name}
64
+ `;
65
+ result += `// Dialect: ${database.dialect}
66
+
67
+ `;
68
+ for (const table of database.tables) {
69
+ result += this.generateTable(table);
70
+ result += "\n";
71
+ }
72
+ return result;
73
+ }
74
+ /**
75
+ * 生成单个表的类型定义
76
+ */
77
+ generateTable(table) {
78
+ let result = `// ${table.name} \u8868\u7ED3\u6784
79
+ `;
80
+ result += `export interface ${this.formatTypeName(table.name)} {
81
+ `;
82
+ for (const column of table.columns) {
83
+ result += this.generateColumn(column);
84
+ }
85
+ result += "}\n";
86
+ return result;
87
+ }
88
+ /**
89
+ * 生成列的类型定义
90
+ */
91
+ generateColumn(column) {
92
+ const fieldName = this.formatFieldName(column.name);
93
+ const typeName = this.mapSQLType(column.type, column.name);
94
+ const optional = column.nullable ? "?" : "";
95
+ let result = ` ${fieldName}${optional}: ${typeName}`;
96
+ if (column.comment && this.options.generateComments !== false) {
97
+ result += `; // ${column.comment}`;
98
+ }
99
+ result += "\n";
100
+ return result;
101
+ }
102
+ /**
103
+ * 映射 SQL 类型到 TypeScript 类型
104
+ */
105
+ mapSQLType(type, columnName) {
106
+ switch (type.kind) {
107
+ case "int":
108
+ case "bigint":
109
+ return "number";
110
+ case "float":
111
+ case "decimal":
112
+ return "number";
113
+ case "varchar":
114
+ case "text":
115
+ return "string";
116
+ case "boolean":
117
+ return "boolean";
118
+ case "date":
119
+ case "datetime":
120
+ return "Date";
121
+ case "json":
122
+ return "unknown";
123
+ case "enum":
124
+ if (type.values && type.values.length > 0) {
125
+ const enumValues = type.values.map((v) => `'${v}'`).join(" | ");
126
+ if (columnName) {
127
+ const fieldName = this.formatFieldName(columnName);
128
+ return `${fieldName}: ${enumValues}`;
129
+ }
130
+ return enumValues;
131
+ }
132
+ return "string";
133
+ default:
134
+ return "string";
135
+ }
136
+ }
137
+ };
138
+ }
139
+ });
140
+
141
+ // src/generator/GolangGenerator.ts
142
+ var GolangGenerator_exports = {};
143
+ __export(GolangGenerator_exports, {
144
+ GolangGenerator: () => GolangGenerator
145
+ });
146
+ var GolangGenerator;
147
+ var init_GolangGenerator = __esm({
148
+ "src/generator/GolangGenerator.ts"() {
149
+ "use strict";
150
+ init_generator();
151
+ GolangGenerator = class extends AGenerator {
152
+ constructor(options = { language: "go" }) {
153
+ super();
154
+ this.options = options;
155
+ }
156
+ /**
157
+ * 生成整个数据库模式的类型定义
158
+ */
159
+ generateDatabase(database) {
160
+ let result = `// Database: ${database.name}
161
+ `;
162
+ result += `// Dialect: ${database.dialect}
163
+
164
+ `;
165
+ if (this.options.namespace) {
166
+ result += `package ${this.options.namespace}
167
+
168
+ `;
169
+ }
170
+ if (this.needsTimeImport(database)) {
171
+ result += `import "time"
172
+
173
+ `;
174
+ }
175
+ for (const table of database.tables) {
176
+ result += this.generateTable(table);
177
+ result += "\n";
178
+ }
179
+ return result;
180
+ }
181
+ /**
182
+ * 生成单个表的类型定义
183
+ */
184
+ generateTable(table) {
185
+ let result = `// ${table.name} \u8868\u7ED3\u6784
186
+ `;
187
+ result += `type ${this.formatTypeName(table.name)} struct {
188
+ `;
189
+ for (const column of table.columns) {
190
+ result += this.generateColumn(column);
191
+ }
192
+ result += "}\n";
193
+ return result;
194
+ }
195
+ /**
196
+ * 生成列的类型定义
197
+ */
198
+ generateColumn(column) {
199
+ const fieldName = this.formatFieldName(column.name);
200
+ const typeName = this.mapSQLType(column.type);
201
+ const tag = this.generateGoTag(column);
202
+ let result = ` ${fieldName} ${typeName} ${tag}`;
203
+ if (column.comment && this.options.generateComments !== false) {
204
+ result += ` // ${column.comment}`;
205
+ }
206
+ result += "\n";
207
+ return result;
208
+ }
209
+ /**
210
+ * 映射 SQL 类型到 Go 类型
211
+ */
212
+ mapSQLType(type) {
213
+ switch (type.kind) {
214
+ case "int":
215
+ return "int";
216
+ case "bigint":
217
+ return "int64";
218
+ case "float":
219
+ return "float64";
220
+ case "decimal":
221
+ return "float64";
222
+ case "varchar":
223
+ case "text":
224
+ return "string";
225
+ case "boolean":
226
+ return "bool";
227
+ case "date":
228
+ case "datetime":
229
+ return "time.Time";
230
+ case "json":
231
+ return "interface{}";
232
+ case "enum":
233
+ return "string";
234
+ default:
235
+ return "string";
236
+ }
237
+ }
238
+ /**
239
+ * 生成 Go 结构体标签
240
+ */
241
+ generateGoTag(column) {
242
+ const tags = [];
243
+ tags.push(`json:"${column.name}"`);
244
+ tags.push(`db:"${column.name}"`);
245
+ return `\`${tags.join(" ")}\``;
246
+ }
247
+ };
248
+ }
249
+ });
250
+
251
+ // src/generator/GormGenerator.ts
252
+ var GormGenerator_exports = {};
253
+ __export(GormGenerator_exports, {
254
+ GormGenerator: () => GormGenerator
255
+ });
256
+ var GormGenerator;
257
+ var init_GormGenerator = __esm({
258
+ "src/generator/GormGenerator.ts"() {
259
+ "use strict";
260
+ init_generator();
261
+ GormGenerator = class extends AGenerator {
262
+ constructor(options = { language: "gorm" }) {
263
+ super();
264
+ this.options = options;
265
+ }
266
+ /**
267
+ * 生成整个数据库模式的类型定义
268
+ */
269
+ generateDatabase(database) {
270
+ let result = `// Database: ${database.name}
271
+ `;
272
+ result += `// Dialect: ${database.dialect}
273
+
274
+ `;
275
+ if (this.options.namespace) {
276
+ result += `package ${this.options.namespace}
277
+
278
+ `;
279
+ }
280
+ if (this.needsTimeImport(database)) {
281
+ result += `import "time"
282
+
283
+ `;
284
+ }
285
+ for (const table of database.tables) {
286
+ result += this.generateTable(table);
287
+ result += "\n";
288
+ }
289
+ return result;
290
+ }
291
+ /**
292
+ * 生成单个表的类型定义
293
+ */
294
+ generateTable(table) {
295
+ let result = `// ${table.name} \u8868\u7ED3\u6784
296
+ `;
297
+ result += `type ${this.formatTypeName(table.name)} struct {
298
+ `;
299
+ for (const column of table.columns) {
300
+ result += this.generateColumn(column);
301
+ }
302
+ result += "}\n";
303
+ return result;
304
+ }
305
+ /**
306
+ * 生成列的类型定义
307
+ */
308
+ generateColumn(column) {
309
+ const fieldName = this.formatFieldName(column.name);
310
+ const typeName = this.mapSQLType(column.type);
311
+ const tag = this.generateGormTag(column);
312
+ let result = ` ${fieldName} ${typeName} ${tag}`;
313
+ if (column.comment && this.options.generateComments !== false) {
314
+ result += ` // ${column.comment}`;
315
+ }
316
+ result += "\n";
317
+ return result;
318
+ }
319
+ /**
320
+ * 映射 SQL 类型到 GORM 类型
321
+ */
322
+ mapSQLType(type) {
323
+ switch (type.kind) {
324
+ case "int":
325
+ return "int";
326
+ case "bigint":
327
+ return "int64";
328
+ case "float":
329
+ return "float64";
330
+ case "decimal":
331
+ return "float64";
332
+ case "varchar":
333
+ case "text":
334
+ return "string";
335
+ case "boolean":
336
+ return "bool";
337
+ case "date":
338
+ case "datetime":
339
+ return "time.Time";
340
+ case "json":
341
+ return "interface{}";
342
+ case "enum":
343
+ return "string";
344
+ default:
345
+ return "string";
346
+ }
347
+ }
348
+ /**
349
+ * 生成 GORM 结构体标签
350
+ */
351
+ generateGormTag(column) {
352
+ const tags = [];
353
+ tags.push(`column:${column.name}`);
354
+ let typeTag = "type:";
355
+ switch (column.type.kind) {
356
+ case "int":
357
+ typeTag += "int";
358
+ if (column.type.length) {
359
+ typeTag += `(${column.type.length})`;
360
+ }
361
+ break;
362
+ case "bigint":
363
+ typeTag += "bigint";
364
+ if (column.type.length) {
365
+ typeTag += `(${column.type.length})`;
366
+ }
367
+ break;
368
+ case "float":
369
+ typeTag += "float";
370
+ if (column.type.precision) {
371
+ typeTag += `(${column.type.precision}`;
372
+ if (column.type.scale) {
373
+ typeTag += `,${column.type.scale}`;
374
+ }
375
+ typeTag += ")";
376
+ }
377
+ break;
378
+ case "decimal":
379
+ typeTag += "decimal";
380
+ if (column.type.precision) {
381
+ typeTag += `(${column.type.precision}`;
382
+ if (column.type.scale) {
383
+ typeTag += `,${column.type.scale}`;
384
+ }
385
+ typeTag += ")";
386
+ }
387
+ break;
388
+ case "varchar":
389
+ typeTag += "varchar";
390
+ if (column.type.length) {
391
+ typeTag += `(${column.type.length})`;
392
+ }
393
+ break;
394
+ case "text":
395
+ typeTag += "text";
396
+ break;
397
+ case "boolean":
398
+ typeTag += "bool";
399
+ break;
400
+ case "date":
401
+ typeTag += "date";
402
+ break;
403
+ case "datetime":
404
+ typeTag += "datetime";
405
+ break;
406
+ case "json":
407
+ typeTag += "json";
408
+ break;
409
+ case "enum":
410
+ typeTag += "enum";
411
+ break;
412
+ default:
413
+ typeTag += "string";
414
+ }
415
+ tags.push(typeTag);
416
+ if (column.primaryKey) {
417
+ tags.push("primaryKey");
418
+ }
419
+ if (column.unique) {
420
+ tags.push("unique");
421
+ }
422
+ if (!column.nullable) {
423
+ tags.push("not null");
424
+ }
425
+ if (column.default) {
426
+ tags.push(`default:${column.default}`);
427
+ }
428
+ if (column.generated) {
429
+ tags.push("autoIncrement");
430
+ }
431
+ if (column.comment) {
432
+ tags.push(`comment:${column.comment}`);
433
+ }
434
+ return `\`gorm:"${tags.join(";")}" json:"${column.name}"\``;
435
+ }
436
+ };
437
+ }
438
+ });
439
+
440
+ // src/generator/XormGenerator.ts
441
+ var XormGenerator_exports = {};
442
+ __export(XormGenerator_exports, {
443
+ XormGenerator: () => XormGenerator
444
+ });
445
+ var XormGenerator;
446
+ var init_XormGenerator = __esm({
447
+ "src/generator/XormGenerator.ts"() {
448
+ "use strict";
449
+ init_generator();
450
+ XormGenerator = class extends AGenerator {
451
+ constructor(options = { language: "xorm" }) {
452
+ super();
453
+ this.options = options;
454
+ }
455
+ /**
456
+ * 生成整个数据库模式的类型定义
457
+ */
458
+ generateDatabase(database) {
459
+ let result = `// Database: ${database.name}
460
+ `;
461
+ result += `// Dialect: ${database.dialect}
462
+
463
+ `;
464
+ if (this.options.namespace) {
465
+ result += `package ${this.options.namespace}
466
+
467
+ `;
468
+ }
469
+ if (this.needsTimeImport(database)) {
470
+ result += `import "time"
471
+
472
+ `;
473
+ }
474
+ for (const table of database.tables) {
475
+ result += this.generateTable(table);
476
+ result += "\n";
477
+ }
478
+ return result;
479
+ }
480
+ /**
481
+ * 生成单个表的类型定义
482
+ */
483
+ generateTable(table) {
484
+ let result = `// ${table.name} \u8868\u7ED3\u6784
485
+ `;
486
+ result += `type ${this.formatTypeName(table.name)} struct {
487
+ `;
488
+ for (const column of table.columns) {
489
+ result += this.generateColumn(column);
490
+ }
491
+ result += "}\n";
492
+ return result;
493
+ }
494
+ /**
495
+ * 生成列的类型定义
496
+ */
497
+ generateColumn(column) {
498
+ const fieldName = this.formatFieldName(column.name);
499
+ const typeName = this.mapSQLType(column.type);
500
+ const tag = this.generateXormTag(column);
501
+ let result = ` ${fieldName} ${typeName} ${tag}`;
502
+ if (column.comment && this.options.generateComments !== false) {
503
+ result += ` // ${column.comment}`;
504
+ }
505
+ result += "\n";
506
+ return result;
507
+ }
508
+ /**
509
+ * 映射 SQL 类型到 XORM 类型
510
+ */
511
+ mapSQLType(type) {
512
+ switch (type.kind) {
513
+ case "int":
514
+ return "int";
515
+ case "bigint":
516
+ return "int64";
517
+ case "float":
518
+ return "float64";
519
+ case "decimal":
520
+ return "float64";
521
+ case "varchar":
522
+ case "text":
523
+ return "string";
524
+ case "boolean":
525
+ return "bool";
526
+ case "date":
527
+ case "datetime":
528
+ return "time.Time";
529
+ case "json":
530
+ return "interface{}";
531
+ case "enum":
532
+ return "string";
533
+ default:
534
+ return "string";
535
+ }
536
+ }
537
+ /**
538
+ * 生成 XORM 结构体标签
539
+ */
540
+ generateXormTag(column) {
541
+ const tags = [];
542
+ tags.push(`${column.name}`);
543
+ let typeTag = "";
544
+ switch (column.type.kind) {
545
+ case "int":
546
+ typeTag = "int";
547
+ if (column.type.length) {
548
+ typeTag += `(${column.type.length})`;
549
+ }
550
+ break;
551
+ case "bigint":
552
+ typeTag = "bigint";
553
+ if (column.type.length) {
554
+ typeTag += `(${column.type.length})`;
555
+ }
556
+ break;
557
+ case "float":
558
+ typeTag = "float";
559
+ if (column.type.precision) {
560
+ typeTag += `(${column.type.precision}`;
561
+ if (column.type.scale) {
562
+ typeTag += `,${column.type.scale}`;
563
+ }
564
+ typeTag += ")";
565
+ }
566
+ break;
567
+ case "decimal":
568
+ typeTag = "decimal";
569
+ if (column.type.precision) {
570
+ typeTag += `(${column.type.precision}`;
571
+ if (column.type.scale) {
572
+ typeTag += `,${column.type.scale}`;
573
+ }
574
+ typeTag += ")";
575
+ }
576
+ break;
577
+ case "varchar":
578
+ typeTag = "varchar";
579
+ if (column.type.length) {
580
+ typeTag += `(${column.type.length})`;
581
+ }
582
+ break;
583
+ case "text":
584
+ typeTag = "text";
585
+ break;
586
+ case "boolean":
587
+ typeTag = "bool";
588
+ break;
589
+ case "date":
590
+ typeTag = "date";
591
+ break;
592
+ case "datetime":
593
+ typeTag = "datetime";
594
+ break;
595
+ case "json":
596
+ typeTag = "json";
597
+ break;
598
+ case "enum":
599
+ typeTag = "enum";
600
+ break;
601
+ default:
602
+ typeTag = "string";
603
+ }
604
+ if (typeTag) {
605
+ tags.push(typeTag);
606
+ }
607
+ if (column.primaryKey) {
608
+ tags.push("pk");
609
+ }
610
+ if (column.unique) {
611
+ tags.push("unique");
612
+ }
613
+ if (!column.nullable) {
614
+ tags.push("notnull");
615
+ }
616
+ if (column.default) {
617
+ tags.push(`default(${column.default})`);
618
+ }
619
+ if (column.generated) {
620
+ tags.push("autoincr");
621
+ }
622
+ if (column.comment) {
623
+ tags.push(`comment(${column.comment})`);
624
+ }
625
+ return `\`xorm:"${tags.join(" ")}" json:"${column.name}"\``;
626
+ }
627
+ };
628
+ }
629
+ });
630
+
631
+ // src/generator/generator.ts
632
+ var AGenerator, GeneratorFactory;
633
+ var init_generator = __esm({
634
+ "src/generator/generator.ts"() {
635
+ "use strict";
636
+ AGenerator = class {
637
+ /**
638
+ * 格式化类型名称(如驼峰命名、帕斯卡命名等)
639
+ */
640
+ formatTypeName(name) {
641
+ return name.split("_").map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()).join("");
642
+ }
643
+ /**
644
+ * 格式化字段名称
645
+ */
646
+ formatFieldName(name) {
647
+ return name.split("_").map((part) => {
648
+ return part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();
649
+ }).join("");
650
+ }
651
+ /**
652
+ * 生成默认值
653
+ */
654
+ generateDefaultValue(column) {
655
+ if (!column.default) {
656
+ return "";
657
+ }
658
+ return column.default;
659
+ }
660
+ /**
661
+ * 检查是否需要导入 time 包
662
+ */
663
+ needsTimeImport(database) {
664
+ for (const table of database.tables) {
665
+ for (const column of table.columns) {
666
+ if (column.type.kind === "date" || column.type.kind === "datetime") {
667
+ return true;
668
+ }
669
+ }
670
+ }
671
+ return false;
672
+ }
673
+ };
674
+ GeneratorFactory = class {
675
+ /**
676
+ * 创建语言生成器实例
677
+ * @param language 目标语言
678
+ * @param options 生成器配置选项
679
+ * @returns 语言生成器实例
680
+ */
681
+ static async createGenerator(language, options = { language }) {
682
+ switch (language) {
683
+ case "typescript":
684
+ const { TypeScriptGenerator: TypeScriptGenerator2 } = await Promise.resolve().then(() => (init_TypeScriptGenerator(), TypeScriptGenerator_exports));
685
+ return new TypeScriptGenerator2(options);
686
+ case "go":
687
+ const { GolangGenerator: GolangGenerator2 } = await Promise.resolve().then(() => (init_GolangGenerator(), GolangGenerator_exports));
688
+ return new GolangGenerator2(options);
689
+ case "gorm":
690
+ const { GormGenerator: GormGenerator2 } = await Promise.resolve().then(() => (init_GormGenerator(), GormGenerator_exports));
691
+ return new GormGenerator2(options);
692
+ case "xorm":
693
+ const { XormGenerator: XormGenerator2 } = await Promise.resolve().then(() => (init_XormGenerator(), XormGenerator_exports));
694
+ return new XormGenerator2(options);
695
+ default:
696
+ throw new Error(`Unsupported language: ${language}`);
697
+ }
698
+ }
699
+ };
700
+ }
701
+ });
702
+
703
+ // src/index.ts
704
+ var index_exports = {};
705
+ __export(index_exports, {
706
+ AGenerator: () => AGenerator,
707
+ FileReader: () => FileReader,
708
+ GeneratorFactory: () => GeneratorFactory,
709
+ GolangGenerator: () => GolangGenerator,
710
+ GormGenerator: () => GormGenerator,
711
+ ReaderFactory: () => ReaderFactory,
712
+ SQLParser: () => SQLParser,
713
+ StringReader: () => StringReader,
714
+ TypeScriptGenerator: () => TypeScriptGenerator,
715
+ XormGenerator: () => XormGenerator,
716
+ generateCode: () => generateCode,
717
+ parseSQL: () => parseSQL
718
+ });
719
+ module.exports = __toCommonJS(index_exports);
720
+
721
+ // src/sql-parser.ts
722
+ var import_node_sql_parser = require("node-sql-parser");
723
+ var parserCache = /* @__PURE__ */ new Map();
724
+ function getParser(dialect) {
725
+ if (!parserCache.has(dialect)) {
726
+ parserCache.set(dialect, new import_node_sql_parser.Parser());
727
+ }
728
+ return parserCache.get(dialect);
729
+ }
730
+ function parseSQL(sql, options = { dialect: "mysql" }) {
731
+ if (!sql || typeof sql !== "string") {
732
+ throw new Error("SQL string is required and must be a string");
733
+ }
734
+ try {
735
+ const parser = getParser(options.dialect);
736
+ const processedSql = sql.trim().replace(/\s+/g, " ").replace(/;\s*;/g, ";");
737
+ const ast = parser.astify(processedSql, { database: options.dialect });
738
+ if (!ast) {
739
+ throw new Error("Failed to parse SQL: AST is null or undefined");
740
+ }
741
+ const astArray = Array.isArray(ast) ? ast : [ast];
742
+ const sqlParser = new SQLParser(options);
743
+ return sqlParser.parseDatabase(astArray);
744
+ } catch (error) {
745
+ if (error instanceof Error) {
746
+ throw new Error(
747
+ `SQL parsing error: ${error.message}
748
+ Dialect: ${options.dialect}
749
+ SQL length: ${sql.length} characters
750
+ First 200 characters: ${sql.substring(0, 200)}${sql.length > 200 ? "..." : ""}`
751
+ );
752
+ }
753
+ throw new Error(
754
+ `SQL parsing error: ${String(error)}
755
+ Dialect: ${options.dialect}
756
+ SQL length: ${sql.length} characters`
757
+ );
758
+ }
759
+ }
760
+ var SQLParser = class {
761
+ constructor(options = { dialect: "mysql" }) {
762
+ /**
763
+ * 默认类型解析器
764
+ * 提供基本的 SQL 类型到 SQLType 的映射逻辑
765
+ */
766
+ this.defaultTypeResolver = {
767
+ resolve: (def) => {
768
+ if (!def || !def.dataType) {
769
+ const textType = { kind: "text" };
770
+ return textType;
771
+ }
772
+ const dt = def.dataType.toLowerCase();
773
+ switch (dt) {
774
+ case "int":
775
+ case "integer":
776
+ case "smallint":
777
+ case "mediumint":
778
+ case "year":
779
+ const intType = {
780
+ kind: "int",
781
+ length: Array.isArray(def.length) ? def.length[0] : def.length
782
+ };
783
+ return intType;
784
+ case "bigint":
785
+ const bigIntType = {
786
+ kind: "bigint",
787
+ length: Array.isArray(def.length) ? def.length[0] : def.length
788
+ };
789
+ return bigIntType;
790
+ case "float":
791
+ case "double":
792
+ const floatType = {
793
+ kind: "float",
794
+ precision: Array.isArray(def.length) ? def.length[0] : def.length,
795
+ scale: Array.isArray(def.length) && def.length[1] ? def.length[1] : def.scale
796
+ };
797
+ return floatType;
798
+ case "decimal":
799
+ const decimalType = {
800
+ kind: "decimal",
801
+ precision: Array.isArray(def.length) ? def.length[0] : def.length,
802
+ scale: Array.isArray(def.length) && def.length[1] ? def.length[1] : def.scale
803
+ };
804
+ return decimalType;
805
+ case "varchar":
806
+ const varcharType = {
807
+ kind: "varchar",
808
+ length: Array.isArray(def.length) ? def.length[0] : def.length
809
+ };
810
+ return varcharType;
811
+ case "text":
812
+ case "longtext":
813
+ case "blob":
814
+ case "time":
815
+ const textType = { kind: "text" };
816
+ return textType;
817
+ case "boolean":
818
+ const booleanType = { kind: "boolean" };
819
+ return booleanType;
820
+ case "tinyint":
821
+ if (def.length && (Array.isArray(def.length) ? def.length[0] === 1 : def.length === 1)) {
822
+ const booleanType2 = { kind: "boolean" };
823
+ return booleanType2;
824
+ }
825
+ const tinyIntType = { kind: "int" };
826
+ return tinyIntType;
827
+ case "date":
828
+ const dateType = { kind: "date" };
829
+ return dateType;
830
+ case "datetime":
831
+ case "timestamp":
832
+ const dateTimeType = { kind: "datetime" };
833
+ return dateTimeType;
834
+ case "json":
835
+ const jsonType = { kind: "json" };
836
+ return jsonType;
837
+ case "enum":
838
+ if (def.expr && def.expr.value) {
839
+ const values = def.expr.value.map(
840
+ (v) => {
841
+ let value;
842
+ if (v.value) {
843
+ value = v.value;
844
+ } else if (v.raw) {
845
+ value = v.raw;
846
+ } else {
847
+ value = String(v);
848
+ }
849
+ return value.replace(/^['"]|['"]$/g, "");
850
+ }
851
+ );
852
+ const enumType = {
853
+ kind: "enum",
854
+ values
855
+ };
856
+ return enumType;
857
+ }
858
+ const emptyEnumType = {
859
+ kind: "enum",
860
+ values: []
861
+ };
862
+ return emptyEnumType;
863
+ /**
864
+ * 未识别类型默认降级为 text,避免解析失败
865
+ * 在严格模式下,遇到未识别的类型会抛出错误
866
+ */
867
+ default:
868
+ if (this.options.strictMode) {
869
+ throw new Error(`Unsupported SQL type: ${dt}`);
870
+ }
871
+ const defaultTextType = { kind: "text" };
872
+ return defaultTextType;
873
+ }
874
+ }
875
+ };
876
+ this.options = {
877
+ strictMode: false,
878
+ ignoreComments: false,
879
+ parseForeignKeys: true,
880
+ parseIndexes: true,
881
+ typeResolvers: [],
882
+ ...options
883
+ };
884
+ this.parser = new import_node_sql_parser.Parser();
885
+ }
886
+ /**
887
+ * 遍历 AST,提取所有 CREATE TABLE
888
+ */
889
+ parseDatabase(ast, dbName = this.options.dbName || "db") {
890
+ const db = {
891
+ name: dbName,
892
+ dialect: this.options.dialect,
893
+ tables: []
894
+ };
895
+ for (const node of ast) {
896
+ if (this.isCreateTable(node)) {
897
+ db.tables.push(this.parseTable(node));
898
+ }
899
+ }
900
+ db.tablesMap = {};
901
+ for (const table of db.tables) {
902
+ if (table.name) {
903
+ db.tablesMap[table.name] = table;
904
+ }
905
+ }
906
+ return db;
907
+ }
908
+ /**
909
+ * 类型守卫:判断是否为 CREATE TABLE 语句
910
+ */
911
+ isCreateTable(node) {
912
+ return node.type === "create" && node.keyword === "table";
913
+ }
914
+ /**
915
+ * 解析单表 AST -> TableSchema
916
+ */
917
+ parseTable(node) {
918
+ var _a, _b, _c, _d;
919
+ const tableName = (_b = (_a = node.table) == null ? void 0 : _a[0]) == null ? void 0 : _b.table;
920
+ if (!tableName) {
921
+ throw new Error("Table name is required in CREATE TABLE statement");
922
+ }
923
+ const comment = (_d = (_c = node.table_options) == null ? void 0 : _c.find(
924
+ (o) => o.keyword === "comment"
925
+ )) == null ? void 0 : _d.value;
926
+ const table = {
927
+ name: tableName,
928
+ comment: comment == null ? void 0 : comment.replace(/'/g, ""),
929
+ columns: [],
930
+ primaryKeys: [],
931
+ indexes: []
932
+ };
933
+ for (const def of node.create_definitions || []) {
934
+ try {
935
+ switch (def.resource) {
936
+ case "column":
937
+ const col = this.parseColumn(def);
938
+ table.columns.push(col);
939
+ if (col.primaryKey) {
940
+ table.primaryKeys.push(col.name);
941
+ }
942
+ break;
943
+ case "constraint":
944
+ this.parseTableConstraint(def, table);
945
+ break;
946
+ case "index":
947
+ this.parseIndex(def, table);
948
+ break;
949
+ }
950
+ } catch (error) {
951
+ throw new Error(
952
+ `Error parsing table ${tableName}: ${error instanceof Error ? error.message : String(error)}`
953
+ );
954
+ }
955
+ }
956
+ return table;
957
+ }
958
+ /**
959
+ * 解析列定义 AST -> ColumnSchema
960
+ *
961
+ * 注意:字段级 primary/unique 与表级定义会叠加
962
+ */
963
+ parseColumn(def) {
964
+ var _a, _b, _c;
965
+ const columnName = (_a = def.column) == null ? void 0 : _a.column;
966
+ if (!columnName) {
967
+ throw new Error("Column name is required in column definition");
968
+ }
969
+ if (!def.definition) {
970
+ throw new Error(`Column ${columnName} missing definition`);
971
+ }
972
+ return {
973
+ name: columnName,
974
+ /**
975
+ * 抽象 SQL 类型映射
976
+ */
977
+ type: this.mapSQLType(def.definition),
978
+ /**
979
+ * node-sql-parser 中:
980
+ * nullable 是一个对象,当它存在且 type 是 "not null" 时,表示 NOT NULL
981
+ */
982
+ nullable: !(def.nullable && def.nullable.type === "not null"),
983
+ primaryKey: !!def.primary_key,
984
+ unique: !!def.unique,
985
+ /**
986
+ * 默认值需要序列化为 SQL 字符串
987
+ */
988
+ default: def.default_val ? this.parseDefault(def.default_val) : void 0,
989
+ comment: (_c = (_b = def.comment) == null ? void 0 : _b.value) == null ? void 0 : _c.value,
990
+ unsigned: !!def.definition.unsigned,
991
+ generated: !!def.definition.generated
992
+ };
993
+ }
994
+ /**
995
+ * 解析表级 PRIMARY KEY / UNIQUE / FOREIGN KEY
996
+ */
997
+ parseTableConstraint(def, table) {
998
+ var _a, _b, _c, _d, _e, _f, _g, _h;
999
+ const type = (_a = def.constraint_type) == null ? void 0 : _a.toUpperCase();
1000
+ const columns = ((_b = def.definition) == null ? void 0 : _b.map((c) => c.column)) || [];
1001
+ if (type === "PRIMARY KEY") {
1002
+ table.primaryKeys.push(...columns);
1003
+ columns.forEach((name) => {
1004
+ const col = table.columns.find((c) => c.name === name);
1005
+ if (col) col.primaryKey = true;
1006
+ });
1007
+ return;
1008
+ }
1009
+ if ((type === "UNIQUE" || type === "UNIQUE KEY") && this.options.parseIndexes) {
1010
+ const idx = {
1011
+ name: def.index || `unique_${columns.join("_")}`,
1012
+ columns,
1013
+ unique: true
1014
+ };
1015
+ table.indexes.push(idx);
1016
+ columns.forEach((name) => {
1017
+ const col = table.columns.find((c) => c.name === name);
1018
+ if (col) col.unique = true;
1019
+ });
1020
+ }
1021
+ if (type === "FOREIGN KEY" && this.options.parseForeignKeys) {
1022
+ let referencedTable;
1023
+ let referencedColumns = [];
1024
+ if ("reference" in def && def.reference) {
1025
+ referencedTable = (_d = (_c = def.reference.table) == null ? void 0 : _c[0]) == null ? void 0 : _d.table;
1026
+ referencedColumns = ((_e = def.reference.definition) == null ? void 0 : _e.map((c) => c.column)) || [];
1027
+ } else if ("table" in def && def.table) {
1028
+ referencedTable = (_g = (_f = def.table) == null ? void 0 : _f[0]) == null ? void 0 : _g.table;
1029
+ referencedColumns = ((_h = def.definition) == null ? void 0 : _h.map((c) => c.column)) || [];
1030
+ }
1031
+ if (referencedTable && referencedColumns.length > 0) {
1032
+ if (!table.foreignKeys) {
1033
+ table.foreignKeys = [];
1034
+ }
1035
+ table.foreignKeys.push({
1036
+ name: def.index,
1037
+ columns,
1038
+ referencedTable,
1039
+ referencedColumns,
1040
+ onDelete: def.on_delete,
1041
+ onUpdate: def.on_update
1042
+ });
1043
+ }
1044
+ }
1045
+ }
1046
+ /**
1047
+ * 解析普通索引
1048
+ */
1049
+ parseIndex(def, table) {
1050
+ var _a;
1051
+ if (this.options.parseIndexes) {
1052
+ table.indexes.push({
1053
+ name: def.index,
1054
+ columns: ((_a = def.definition) == null ? void 0 : _a.map((c) => c.column)) || [],
1055
+ unique: !!def.unique,
1056
+ type: def.index_type
1057
+ });
1058
+ }
1059
+ }
1060
+ /**
1061
+ * SQL AST 类型 -> SQLType(跨方言抽象)
1062
+ */
1063
+ mapSQLType(def) {
1064
+ const allResolvers = [
1065
+ ...this.options.typeResolvers,
1066
+ this.defaultTypeResolver
1067
+ ];
1068
+ for (const resolver of allResolvers) {
1069
+ const result = resolver.resolve(def);
1070
+ if (result) {
1071
+ return result;
1072
+ }
1073
+ }
1074
+ const textType = { kind: "text" };
1075
+ return textType;
1076
+ }
1077
+ /**
1078
+ * 默认值 AST -> SQL 字符串
1079
+ *
1080
+ * 使用 sqlify 确保函数/表达式被正确序列化
1081
+ */
1082
+ parseDefault(def) {
1083
+ var _a, _b, _c, _d, _e, _f, _g;
1084
+ if (((_a = def.value) == null ? void 0 : _a.type) === "null" || def.value === null) {
1085
+ return null;
1086
+ }
1087
+ try {
1088
+ return this.parser.sqlify(def.value);
1089
+ } catch (error) {
1090
+ if (((_b = def.value) == null ? void 0 : _b.type) === "function") {
1091
+ if ((_e = (_d = (_c = def.value.name) == null ? void 0 : _c.name) == null ? void 0 : _d[0]) == null ? void 0 : _e.value) {
1092
+ return def.value.name.name[0].value;
1093
+ }
1094
+ }
1095
+ return String((_g = (_f = def.value) == null ? void 0 : _f.value) != null ? _g : def.value);
1096
+ }
1097
+ }
1098
+ };
1099
+
1100
+ // src/generator/index.ts
1101
+ init_generator();
1102
+ init_TypeScriptGenerator();
1103
+ init_GolangGenerator();
1104
+ init_GormGenerator();
1105
+ init_XormGenerator();
1106
+
1107
+ // src/utils.ts
1108
+ init_generator();
1109
+ async function generateCode(sql, options) {
1110
+ const dbSchema = parseSQL(sql, {
1111
+ dialect: options.dialect || "mysql",
1112
+ dbName: options.dbName || "my_database"
1113
+ });
1114
+ const generatorOptions = {
1115
+ language: options.language,
1116
+ namespace: options.namespace,
1117
+ generateComments: true
1118
+ };
1119
+ const generator = await GeneratorFactory.createGenerator(
1120
+ options.language,
1121
+ generatorOptions
1122
+ );
1123
+ return generator.generateDatabase(dbSchema);
1124
+ }
1125
+
1126
+ // src/reader/StringReader.ts
1127
+ var StringReader = class {
1128
+ /**
1129
+ * 构造函数
1130
+ * @param sql SQL 字符串
1131
+ */
1132
+ constructor(sql) {
1133
+ this.sql = sql;
1134
+ }
1135
+ /**
1136
+ * 读取 SQL 内容
1137
+ * @returns Promise<string> SQL 内容
1138
+ */
1139
+ async read() {
1140
+ return this.sql;
1141
+ }
1142
+ };
1143
+
1144
+ // src/reader/FileReader.ts
1145
+ var fs = __toESM(require("fs/promises"));
1146
+ var FileReader = class {
1147
+ /**
1148
+ * 构造函数
1149
+ * @param filePath SQL 文件路径
1150
+ */
1151
+ constructor(filePath) {
1152
+ this.filePath = filePath;
1153
+ }
1154
+ /**
1155
+ * 读取 SQL 内容
1156
+ * @returns Promise<string> SQL 内容
1157
+ * @throws Error 文件不存在或读取失败
1158
+ */
1159
+ async read() {
1160
+ try {
1161
+ await fs.access(this.filePath);
1162
+ const content = await fs.readFile(this.filePath, "utf-8");
1163
+ console.log(`Reading SQL from file: ${this.filePath}`);
1164
+ return content;
1165
+ } catch (error) {
1166
+ if (error instanceof Error) {
1167
+ if (error.code === "ENOENT") {
1168
+ throw new Error(`File not found: ${this.filePath}`);
1169
+ }
1170
+ throw new Error(`Failed to read file: ${error.message}`);
1171
+ }
1172
+ throw new Error("Unknown error reading file");
1173
+ }
1174
+ }
1175
+ };
1176
+
1177
+ // src/reader/ReaderFactory.ts
1178
+ var ReaderFactory = class {
1179
+ /**
1180
+ * 创建 Reader 实例
1181
+ * @param options 读取器选项
1182
+ * @returns Reader 实例
1183
+ * @throws Error 不支持的读取器类型
1184
+ */
1185
+ static createReader(options) {
1186
+ switch (options.type) {
1187
+ case "string":
1188
+ if (!options.source) {
1189
+ throw new Error("Source is required for string reader");
1190
+ }
1191
+ return new StringReader(options.source);
1192
+ case "file":
1193
+ if (!options.source) {
1194
+ throw new Error("Source is required for file reader");
1195
+ }
1196
+ return new FileReader(options.source);
1197
+ default:
1198
+ throw new Error(`Unsupported reader type: ${options.type}`);
1199
+ }
1200
+ }
1201
+ };
1202
+ // Annotate the CommonJS export names for ESM import in node:
1203
+ 0 && (module.exports = {
1204
+ AGenerator,
1205
+ FileReader,
1206
+ GeneratorFactory,
1207
+ GolangGenerator,
1208
+ GormGenerator,
1209
+ ReaderFactory,
1210
+ SQLParser,
1211
+ StringReader,
1212
+ TypeScriptGenerator,
1213
+ XormGenerator,
1214
+ generateCode,
1215
+ parseSQL
1216
+ });