sonamu 0.0.39 → 0.0.41
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/api/code-converters.d.ts +1 -0
- package/dist/api/code-converters.d.ts.map +1 -1
- package/dist/api/code-converters.js +68 -1
- package/dist/api/code-converters.js.map +1 -1
- package/dist/api/decorators.d.ts +1 -0
- package/dist/api/decorators.d.ts.map +1 -1
- package/dist/api/decorators.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/smd/migrator.d.ts +34 -1
- package/dist/smd/migrator.d.ts.map +1 -1
- package/dist/smd/migrator.js +8 -6
- package/dist/smd/migrator.js.map +1 -1
- package/dist/smd/smd-manager.d.ts +1 -1
- package/dist/smd/smd-manager.d.ts.map +1 -1
- package/dist/smd/smd-manager.js.map +1 -1
- package/dist/smd/smd.d.ts +1 -1
- package/dist/smd/smd.d.ts.map +1 -1
- package/dist/smd/smd.js +27 -20
- package/dist/smd/smd.js.map +1 -1
- package/dist/syncer/syncer.d.ts +1 -1
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/syncer/syncer.js +40 -38
- package/dist/syncer/syncer.js.map +1 -1
- package/dist/types/types.d.ts +1 -0
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js.map +1 -1
- package/package.json +1 -1
- package/src/api/code-converters.ts +70 -0
- package/src/api/decorators.ts +1 -0
- package/src/index.ts +1 -0
- package/src/smd/migrator.ts +51 -12
- package/src/smd/smd-manager.ts +1 -1
- package/src/smd/smd.ts +31 -26
- package/src/syncer/syncer.ts +4 -4
- package/src/types/types.ts +1 -0
package/src/api/decorators.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ export * from "./exceptions/error-handler";
|
|
|
9
9
|
export * from "./exceptions/so-exceptions";
|
|
10
10
|
export * from "./smd/smd-manager";
|
|
11
11
|
export * from "./smd/smd-utils";
|
|
12
|
+
export * from "./smd/migrator";
|
|
12
13
|
export * from "./syncer/syncer";
|
|
13
14
|
export * from "./testing/fixture-manager";
|
|
14
15
|
export * from "./types/types";
|
package/src/smd/migrator.ts
CHANGED
|
@@ -48,6 +48,7 @@ import {
|
|
|
48
48
|
isEnumProp,
|
|
49
49
|
isIntegerProp,
|
|
50
50
|
isKnexError,
|
|
51
|
+
RelationOn,
|
|
51
52
|
} from "../types/types";
|
|
52
53
|
import { propIf } from "../utils/lodash-able";
|
|
53
54
|
import { SMDManager } from "./smd-manager";
|
|
@@ -477,20 +478,22 @@ export class Migrator {
|
|
|
477
478
|
);
|
|
478
479
|
}
|
|
479
480
|
} else {
|
|
480
|
-
const
|
|
481
|
-
[a.to, ...a.columns].join("-")
|
|
482
|
-
).map((smdForeign) => {
|
|
481
|
+
const replaceNoActionOnMySQL = (f: MigrationForeign) => {
|
|
483
482
|
// MySQL에서 RESTRICT와 NO ACTION은 동일함
|
|
484
|
-
const { onDelete, onUpdate } =
|
|
483
|
+
const { onDelete, onUpdate } = f;
|
|
485
484
|
return {
|
|
486
|
-
...
|
|
485
|
+
...f,
|
|
487
486
|
onUpdate: onUpdate === "RESTRICT" ? "NO ACTION" : onUpdate,
|
|
488
487
|
onDelete: onDelete === "RESTRICT" ? "NO ACTION" : onDelete,
|
|
489
488
|
};
|
|
490
|
-
}
|
|
489
|
+
};
|
|
490
|
+
|
|
491
|
+
const smdForeigns = sortBy(smdSet.foreigns, (a) =>
|
|
492
|
+
[a.to, ...a.columns].join("-")
|
|
493
|
+
).map((f) => replaceNoActionOnMySQL(f));
|
|
491
494
|
const dbForeigns = sortBy(dbSet.foreigns, (a) =>
|
|
492
495
|
[a.to, ...a.columns].join("-")
|
|
493
|
-
);
|
|
496
|
+
).map((f) => replaceNoActionOnMySQL(f));
|
|
494
497
|
|
|
495
498
|
if (equal(smdForeigns, dbForeigns) === false) {
|
|
496
499
|
console.dir({ smdForeigns, dbForeigns }, { depth: null });
|
|
@@ -534,7 +537,7 @@ export class Migrator {
|
|
|
534
537
|
기존 테이블 정보 읽어서 MigrationSet 형식으로 리턴
|
|
535
538
|
*/
|
|
536
539
|
async getMigrationSetFromDB(table: string): Promise<MigrationSet | null> {
|
|
537
|
-
let dbColumns:
|
|
540
|
+
let dbColumns: DBColumn[], dbIndexes: DBIndex[], dbForeigns: DBForeign[];
|
|
538
541
|
try {
|
|
539
542
|
[dbColumns, dbIndexes, dbForeigns] = await this.readTable(table);
|
|
540
543
|
} catch (e: unknown) {
|
|
@@ -554,7 +557,7 @@ export class Migrator {
|
|
|
554
557
|
...propIf(dbColumn.Default !== null, {
|
|
555
558
|
defaultTo:
|
|
556
559
|
dbColType.type === "float"
|
|
557
|
-
? parseFloat(dbColumn.Default).toString()
|
|
560
|
+
? parseFloat(dbColumn.Default ?? "0").toString()
|
|
558
561
|
: dbColumn.Default,
|
|
559
562
|
}),
|
|
560
563
|
};
|
|
@@ -592,8 +595,8 @@ export class Migrator {
|
|
|
592
595
|
return {
|
|
593
596
|
columns: [dbForeign.from],
|
|
594
597
|
to: `${dbForeign.referencesTable}.${dbForeign.referencesField}`,
|
|
595
|
-
onUpdate: dbForeign.onUpdate,
|
|
596
|
-
onDelete: dbForeign.onDelete,
|
|
598
|
+
onUpdate: dbForeign.onUpdate as RelationOn,
|
|
599
|
+
onDelete: dbForeign.onDelete as RelationOn,
|
|
597
600
|
};
|
|
598
601
|
});
|
|
599
602
|
|
|
@@ -691,7 +694,9 @@ export class Migrator {
|
|
|
691
694
|
/*
|
|
692
695
|
기존 테이블 읽어서 cols, indexes 반환
|
|
693
696
|
*/
|
|
694
|
-
async readTable(
|
|
697
|
+
async readTable(
|
|
698
|
+
tableName: string
|
|
699
|
+
): Promise<[DBColumn[], DBIndex[], DBForeign[]]> {
|
|
695
700
|
// 테이블 정보
|
|
696
701
|
try {
|
|
697
702
|
const [cols] = await this.targets.compare!.raw(
|
|
@@ -1563,3 +1568,37 @@ export class Migrator {
|
|
|
1563
1568
|
);
|
|
1564
1569
|
}
|
|
1565
1570
|
}
|
|
1571
|
+
|
|
1572
|
+
type DBColumn = {
|
|
1573
|
+
Field: string;
|
|
1574
|
+
Type: string;
|
|
1575
|
+
Null: string;
|
|
1576
|
+
Key: string;
|
|
1577
|
+
Default: string | null;
|
|
1578
|
+
Extra: string;
|
|
1579
|
+
};
|
|
1580
|
+
type DBIndex = {
|
|
1581
|
+
Table: string;
|
|
1582
|
+
Non_unique: number;
|
|
1583
|
+
Key_name: string;
|
|
1584
|
+
Seq_in_index: number;
|
|
1585
|
+
Column_name: string;
|
|
1586
|
+
Collation: string | null;
|
|
1587
|
+
Cardinality: number | null;
|
|
1588
|
+
Sub_part: number | null;
|
|
1589
|
+
Packed: string | null;
|
|
1590
|
+
Null: string;
|
|
1591
|
+
Index_type: string;
|
|
1592
|
+
Comment: string;
|
|
1593
|
+
Index_comment: string;
|
|
1594
|
+
Visible: string;
|
|
1595
|
+
Expression: string | null;
|
|
1596
|
+
};
|
|
1597
|
+
type DBForeign = {
|
|
1598
|
+
keyName: string;
|
|
1599
|
+
from: string;
|
|
1600
|
+
referencesTable: string;
|
|
1601
|
+
referencesField: string;
|
|
1602
|
+
onDelete: string;
|
|
1603
|
+
onUpdate: string;
|
|
1604
|
+
};
|
package/src/smd/smd-manager.ts
CHANGED
|
@@ -24,7 +24,7 @@ type TableSpec = {
|
|
|
24
24
|
};
|
|
25
25
|
class SMDManagerClass {
|
|
26
26
|
private SMDs: Map<string, SMD> = new Map();
|
|
27
|
-
|
|
27
|
+
public modulePaths: Map<string, string> = new Map();
|
|
28
28
|
private tableSpecs: Map<string, TableSpec> = new Map();
|
|
29
29
|
public isAutoloaded: boolean = false;
|
|
30
30
|
|
package/src/smd/smd.ts
CHANGED
|
@@ -132,7 +132,11 @@ export class SMD {
|
|
|
132
132
|
|
|
133
133
|
/*
|
|
134
134
|
*/
|
|
135
|
-
resolveSubsetQuery(
|
|
135
|
+
resolveSubsetQuery(
|
|
136
|
+
prefix: string,
|
|
137
|
+
fields: string[],
|
|
138
|
+
isAlreadyOuterJoined: boolean = false
|
|
139
|
+
): SubsetQuery {
|
|
136
140
|
// prefix 치환 (prefix는 ToOneRelation이 복수로 붙은 경우 모두 __로 변경됨)
|
|
137
141
|
prefix = prefix.replace(/\./g, "__");
|
|
138
142
|
|
|
@@ -203,9 +207,33 @@ export class SMD {
|
|
|
203
207
|
return r;
|
|
204
208
|
}
|
|
205
209
|
|
|
210
|
+
// innerOrOuter
|
|
211
|
+
const innerOrOuter = (() => {
|
|
212
|
+
if (isAlreadyOuterJoined) {
|
|
213
|
+
return "outer";
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (isOneToOneRelationProp(relation)) {
|
|
217
|
+
if (
|
|
218
|
+
relation.hasJoinColumn === true &&
|
|
219
|
+
(relation.nullable ?? false) === false
|
|
220
|
+
) {
|
|
221
|
+
return "inner";
|
|
222
|
+
} else {
|
|
223
|
+
return "outer";
|
|
224
|
+
}
|
|
225
|
+
} else {
|
|
226
|
+
if (relation.nullable) {
|
|
227
|
+
return "outer";
|
|
228
|
+
} else {
|
|
229
|
+
return "inner";
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
})();
|
|
206
233
|
const relSubsetQuery = relSMD.resolveSubsetQuery(
|
|
207
234
|
`${prefix !== "" ? prefix + "." : ""}${groupKey}`,
|
|
208
|
-
relFields
|
|
235
|
+
relFields,
|
|
236
|
+
innerOrOuter === "outer"
|
|
209
237
|
);
|
|
210
238
|
r.select = r.select.concat(relSubsetQuery.select);
|
|
211
239
|
r.virtual = r.virtual.concat(relSubsetQuery.virtual);
|
|
@@ -240,32 +268,9 @@ export class SMD {
|
|
|
240
268
|
};
|
|
241
269
|
}
|
|
242
270
|
|
|
243
|
-
const outerOrInner = (() => {
|
|
244
|
-
// 대상 컬럼이 nullable인 경우 outer, 아닌 경우 inner
|
|
245
|
-
// OneToOneRelation의 경우 joinColumn이 없는 경우 해당 relation을 찾아가 확인해야 함 (customJoin의 경우 고려하지 않음)
|
|
246
|
-
if (
|
|
247
|
-
isOneToOneRelationProp(relation) &&
|
|
248
|
-
relation.hasJoinColumn === false
|
|
249
|
-
) {
|
|
250
|
-
const oppositeRelationProp = relSMD.props.find(
|
|
251
|
-
(prop) =>
|
|
252
|
-
isOneToOneRelationProp(prop) &&
|
|
253
|
-
prop.with === this.id &&
|
|
254
|
-
prop.hasJoinColumn === true
|
|
255
|
-
);
|
|
256
|
-
if (oppositeRelationProp?.nullable === true) {
|
|
257
|
-
return "outer";
|
|
258
|
-
} else {
|
|
259
|
-
return "inner";
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
return relation.nullable === true ? "outer" : "inner";
|
|
264
|
-
})();
|
|
265
|
-
|
|
266
271
|
r.joins.push({
|
|
267
272
|
as: joinAs,
|
|
268
|
-
join:
|
|
273
|
+
join: innerOrOuter,
|
|
269
274
|
table: relSMD.table,
|
|
270
275
|
...joinClause,
|
|
271
276
|
});
|
package/src/syncer/syncer.ts
CHANGED
|
@@ -801,7 +801,7 @@ export class Syncer {
|
|
|
801
801
|
}
|
|
802
802
|
|
|
803
803
|
const rendered = template.render(options, ...extra);
|
|
804
|
-
const resolved = this.resolveRenderedTemplate(key, rendered);
|
|
804
|
+
const resolved = await this.resolveRenderedTemplate(key, rendered);
|
|
805
805
|
|
|
806
806
|
let preTemplateResolved: PathAndCode[] = [];
|
|
807
807
|
if (rendered.preTemplates) {
|
|
@@ -817,10 +817,10 @@ export class Syncer {
|
|
|
817
817
|
return [resolved, ...preTemplateResolved];
|
|
818
818
|
}
|
|
819
819
|
|
|
820
|
-
resolveRenderedTemplate(
|
|
820
|
+
async resolveRenderedTemplate(
|
|
821
821
|
key: TemplateKey,
|
|
822
822
|
result: RenderedTemplate
|
|
823
|
-
): PathAndCode {
|
|
823
|
+
): Promise<PathAndCode> {
|
|
824
824
|
const { target, path: filePath, body, importKeys, customHeaders } = result;
|
|
825
825
|
|
|
826
826
|
// import 할 대상의 대상 path 추출
|
|
@@ -873,7 +873,7 @@ export class Syncer {
|
|
|
873
873
|
const formatted =
|
|
874
874
|
key === "generated_http"
|
|
875
875
|
? [header, body].join("\n\n")
|
|
876
|
-
: prettier.format([header, body].join("\n\n"), {
|
|
876
|
+
: await prettier.format([header, body].join("\n\n"), {
|
|
877
877
|
parser: "typescript",
|
|
878
878
|
});
|
|
879
879
|
|