sonamu 0.0.19 → 0.0.21
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/bin/cli.js +9 -0
- package/dist/bin/cli.js.map +1 -1
- package/dist/database/base-model.d.ts.map +1 -1
- package/dist/database/base-model.js +14 -1
- package/dist/database/base-model.js.map +1 -1
- package/dist/smd/migrator.d.ts +2 -0
- package/dist/smd/migrator.d.ts.map +1 -1
- package/dist/smd/migrator.js +88 -69
- package/dist/smd/migrator.js.map +1 -1
- package/dist/smd/smd-utils.d.ts +7 -1
- package/dist/smd/smd-utils.d.ts.map +1 -1
- package/dist/smd/smd-utils.js +18 -1
- package/dist/smd/smd-utils.js.map +1 -1
- package/dist/smd/smd.d.ts +3 -2
- package/dist/smd/smd.d.ts.map +1 -1
- package/dist/smd/smd.js +7 -17
- package/dist/smd/smd.js.map +1 -1
- package/dist/templates/model_test.template.js +1 -1
- package/dist/templates/smd.template.d.ts.map +1 -1
- package/dist/templates/smd.template.js +5 -1
- package/dist/templates/smd.template.js.map +1 -1
- package/dist/templates/view_id_async_select.template.d.ts.map +1 -1
- package/dist/templates/view_id_async_select.template.js +7 -0
- package/dist/templates/view_id_async_select.template.js.map +1 -1
- package/dist/types/types.d.ts +6 -3
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js.map +1 -1
- package/package.json +1 -1
- package/src/bin/cli.ts +9 -0
- package/src/database/base-model.ts +13 -1
- package/src/smd/migrator.ts +110 -76
- package/src/smd/smd-utils.ts +21 -0
- package/src/smd/smd.ts +19 -17
- package/src/templates/model_test.template.ts +1 -1
- package/src/templates/smd.template.ts +5 -1
- package/src/templates/view_id_async_select.template.ts +7 -0
- package/src/types/types.ts +7 -3
package/src/smd/migrator.ts
CHANGED
|
@@ -124,6 +124,18 @@ export class Migrator {
|
|
|
124
124
|
await this.cleanUpDist(true);
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
+
async check(): Promise<void> {
|
|
128
|
+
const codes = await this.compareMigrations();
|
|
129
|
+
if (codes.length === 0) {
|
|
130
|
+
console.log(chalk.green("\n현재 모두 싱크된 상태입니다."));
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// 현재 생성된 코드 표기
|
|
135
|
+
console.table(codes, ["type", "title"]);
|
|
136
|
+
console.log(codes[0]);
|
|
137
|
+
}
|
|
138
|
+
|
|
127
139
|
async run(): Promise<void> {
|
|
128
140
|
// pending 마이그레이션 확인
|
|
129
141
|
const [, pendingList] = await this.targets.pending.migrate.list();
|
|
@@ -439,10 +451,10 @@ export class Migrator {
|
|
|
439
451
|
console.debug({ smdCreatedAt, dbCreatedAt });
|
|
440
452
|
*/
|
|
441
453
|
|
|
442
|
-
const smdIndexes = sortBy(smdSet.indexes, (a
|
|
454
|
+
const smdIndexes = sortBy(smdSet.indexes, (a) =>
|
|
443
455
|
(a as MigrationIndex).columns.join("-")
|
|
444
456
|
);
|
|
445
|
-
const dbIndexes = sortBy(dbSet.indexes, (a
|
|
457
|
+
const dbIndexes = sortBy(dbSet.indexes, (a) =>
|
|
446
458
|
(a as MigrationIndex).columns.join("-")
|
|
447
459
|
);
|
|
448
460
|
|
|
@@ -473,6 +485,11 @@ export class Migrator {
|
|
|
473
485
|
// TODO FK alter
|
|
474
486
|
console.log(chalk.red(`FK 다름! ${smdSet.table}`));
|
|
475
487
|
// console.dir({ smdForeigns, dbForeigns }, { depth: null });
|
|
488
|
+
return this.generateAlterCode_Foreigns(
|
|
489
|
+
smdSet.table,
|
|
490
|
+
smdForeigns,
|
|
491
|
+
dbForeigns
|
|
492
|
+
);
|
|
476
493
|
}
|
|
477
494
|
}
|
|
478
495
|
return null;
|
|
@@ -550,9 +567,6 @@ export class Migrator {
|
|
|
550
567
|
columns: currentIndexes.map(
|
|
551
568
|
(currentIndex) => currentIndex.Column_name
|
|
552
569
|
),
|
|
553
|
-
...propIf(currentIndexes.length > 1, {
|
|
554
|
-
name: keyName,
|
|
555
|
-
}),
|
|
556
570
|
};
|
|
557
571
|
}
|
|
558
572
|
);
|
|
@@ -742,66 +756,6 @@ export class Migrator {
|
|
|
742
756
|
r.columns.push(column);
|
|
743
757
|
}
|
|
744
758
|
|
|
745
|
-
// 일반 컬럼 + ToOne 케이스 컬럼
|
|
746
|
-
if (
|
|
747
|
-
!isRelationProp(prop) ||
|
|
748
|
-
isBelongsToOneRelationProp(prop) ||
|
|
749
|
-
(isOneToOneRelationProp(prop) && prop.hasJoinColumn)
|
|
750
|
-
) {
|
|
751
|
-
const propName = !isRelationProp(prop)
|
|
752
|
-
? prop.name
|
|
753
|
-
: `${prop.name}_id`;
|
|
754
|
-
|
|
755
|
-
// index 처리
|
|
756
|
-
if (prop.index !== undefined) {
|
|
757
|
-
if (prop.index !== true) {
|
|
758
|
-
prop.index.map((indexName) => {
|
|
759
|
-
const namedOne = r.indexes.find(
|
|
760
|
-
(_index) => _index.name === indexName
|
|
761
|
-
);
|
|
762
|
-
if (namedOne) {
|
|
763
|
-
namedOne.columns.push(propName);
|
|
764
|
-
} else {
|
|
765
|
-
r.indexes.push({
|
|
766
|
-
type: "index",
|
|
767
|
-
columns: [propName],
|
|
768
|
-
name: indexName,
|
|
769
|
-
});
|
|
770
|
-
}
|
|
771
|
-
});
|
|
772
|
-
} else {
|
|
773
|
-
r.indexes.push({
|
|
774
|
-
type: "index",
|
|
775
|
-
columns: [propName],
|
|
776
|
-
});
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
// unique 처리
|
|
780
|
-
if (prop.unique !== undefined) {
|
|
781
|
-
if (prop.unique !== true) {
|
|
782
|
-
prop.unique.map((indexName) => {
|
|
783
|
-
const namedOne = r.indexes.find(
|
|
784
|
-
(_index) => _index.name === indexName
|
|
785
|
-
);
|
|
786
|
-
if (namedOne) {
|
|
787
|
-
namedOne.columns.push(propName);
|
|
788
|
-
} else {
|
|
789
|
-
r.indexes.push({
|
|
790
|
-
type: "unique",
|
|
791
|
-
columns: [propName],
|
|
792
|
-
name: indexName,
|
|
793
|
-
});
|
|
794
|
-
}
|
|
795
|
-
});
|
|
796
|
-
} else {
|
|
797
|
-
r.indexes.push({
|
|
798
|
-
type: "unique",
|
|
799
|
-
columns: [propName],
|
|
800
|
-
});
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
|
|
805
759
|
if (isManyToManyRelationProp(prop)) {
|
|
806
760
|
// ManyToMany 케이스
|
|
807
761
|
const relMd = SMDManager.get(prop.with);
|
|
@@ -888,6 +842,9 @@ export class Migrator {
|
|
|
888
842
|
}
|
|
889
843
|
);
|
|
890
844
|
|
|
845
|
+
// indexes
|
|
846
|
+
migrationSet.indexes = smd.indexes;
|
|
847
|
+
|
|
891
848
|
// uuid
|
|
892
849
|
migrationSet.columns = migrationSet.columns.concat({
|
|
893
850
|
name: "uuid",
|
|
@@ -949,15 +906,11 @@ export class Migrator {
|
|
|
949
906
|
}
|
|
950
907
|
const lines = uniq(
|
|
951
908
|
indexes.reduce((r, index) => {
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
.map((col) => `'${col}'`)
|
|
958
|
-
.join(",")}], '${index.name}')`
|
|
959
|
-
);
|
|
960
|
-
}
|
|
909
|
+
r.push(
|
|
910
|
+
`table.${index.type}([${index.columns
|
|
911
|
+
.map((col) => `'${col}'`)
|
|
912
|
+
.join(",")}])`
|
|
913
|
+
);
|
|
961
914
|
return r;
|
|
962
915
|
}, [] as string[])
|
|
963
916
|
);
|
|
@@ -1362,10 +1315,10 @@ export class Migrator {
|
|
|
1362
1315
|
};
|
|
1363
1316
|
const extraIndexes = {
|
|
1364
1317
|
db: differenceBy(dbIndexes, smdIndexes, (col) =>
|
|
1365
|
-
[col.type, col.
|
|
1318
|
+
[col.type, col.columns.join("-")].join("//")
|
|
1366
1319
|
),
|
|
1367
1320
|
smd: differenceBy(smdIndexes, dbIndexes, (col) =>
|
|
1368
|
-
[col.type, col.
|
|
1321
|
+
[col.type, col.columns.join("-")].join("//")
|
|
1369
1322
|
),
|
|
1370
1323
|
};
|
|
1371
1324
|
if (extraIndexes.smd.length > 0) {
|
|
@@ -1439,6 +1392,87 @@ export class Migrator {
|
|
|
1439
1392
|
return linesTo;
|
|
1440
1393
|
}
|
|
1441
1394
|
|
|
1395
|
+
generateAlterCode_Foreigns(
|
|
1396
|
+
table: string,
|
|
1397
|
+
smdForeigns: MigrationForeign[],
|
|
1398
|
+
dbForeigns: MigrationForeign[]
|
|
1399
|
+
): GenMigrationCode[] {
|
|
1400
|
+
// console.log({ smdForeigns, dbForeigns });
|
|
1401
|
+
|
|
1402
|
+
const getKey = (mf: MigrationForeign): string => {
|
|
1403
|
+
return [mf.columns.join("-"), mf.to].join("///");
|
|
1404
|
+
};
|
|
1405
|
+
const fkTo = smdForeigns.reduce(
|
|
1406
|
+
(result, smdF) => {
|
|
1407
|
+
const matchingDbF = dbForeigns.find(
|
|
1408
|
+
(dbF) => getKey(smdF) === getKey(dbF)
|
|
1409
|
+
);
|
|
1410
|
+
if (!matchingDbF) {
|
|
1411
|
+
result.add.push(smdF);
|
|
1412
|
+
return result;
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1415
|
+
if (equal(smdF, matchingDbF) === false) {
|
|
1416
|
+
result.alterSrc.push(matchingDbF);
|
|
1417
|
+
result.alterDst.push(smdF);
|
|
1418
|
+
return result;
|
|
1419
|
+
}
|
|
1420
|
+
return result;
|
|
1421
|
+
},
|
|
1422
|
+
{
|
|
1423
|
+
add: [] as MigrationForeign[],
|
|
1424
|
+
alterSrc: [] as MigrationForeign[],
|
|
1425
|
+
alterDst: [] as MigrationForeign[],
|
|
1426
|
+
}
|
|
1427
|
+
);
|
|
1428
|
+
|
|
1429
|
+
const linesTo = {
|
|
1430
|
+
add: this.genForeignDefinitions(table, fkTo.add),
|
|
1431
|
+
alterSrc: this.genForeignDefinitions(table, fkTo.alterSrc),
|
|
1432
|
+
alterDst: this.genForeignDefinitions(table, fkTo.alterDst),
|
|
1433
|
+
};
|
|
1434
|
+
|
|
1435
|
+
const lines: string[] = [
|
|
1436
|
+
'import { Knex } from "knex";',
|
|
1437
|
+
"",
|
|
1438
|
+
"export async function up(knex: Knex): Promise<void> {",
|
|
1439
|
+
`return knex.schema.alterTable("${table}", (table) => {`,
|
|
1440
|
+
...linesTo.add.up,
|
|
1441
|
+
...linesTo.alterSrc.down,
|
|
1442
|
+
...linesTo.alterDst.up,
|
|
1443
|
+
"})",
|
|
1444
|
+
"}",
|
|
1445
|
+
"",
|
|
1446
|
+
"export async function down(knex: Knex): Promise<void> {",
|
|
1447
|
+
`return knex.schema.alterTable("${table}", (table) => {`,
|
|
1448
|
+
...linesTo.add.down,
|
|
1449
|
+
...linesTo.alterDst.down,
|
|
1450
|
+
...linesTo.alterSrc.up,
|
|
1451
|
+
"})",
|
|
1452
|
+
"}",
|
|
1453
|
+
];
|
|
1454
|
+
|
|
1455
|
+
const formatted = prettier.format(lines.join("\n"), {
|
|
1456
|
+
parser: "typescript",
|
|
1457
|
+
});
|
|
1458
|
+
|
|
1459
|
+
const title = [
|
|
1460
|
+
"alter",
|
|
1461
|
+
table,
|
|
1462
|
+
"foreigns",
|
|
1463
|
+
// TODO 바뀌는 부분
|
|
1464
|
+
].join("_");
|
|
1465
|
+
|
|
1466
|
+
return [
|
|
1467
|
+
{
|
|
1468
|
+
table,
|
|
1469
|
+
title,
|
|
1470
|
+
formatted,
|
|
1471
|
+
type: "normal",
|
|
1472
|
+
},
|
|
1473
|
+
];
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1442
1476
|
async destroy(): Promise<void> {
|
|
1443
1477
|
await Promise.all(
|
|
1444
1478
|
this.targets.apply.map((db) => {
|
package/src/smd/smd-utils.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
JsonProp,
|
|
16
16
|
ManyToManyRelationProp,
|
|
17
17
|
OneToOneRelationProp,
|
|
18
|
+
SMDIndex,
|
|
18
19
|
StringProp,
|
|
19
20
|
TextProp,
|
|
20
21
|
TimeProp,
|
|
@@ -22,6 +23,7 @@ import {
|
|
|
22
23
|
UuidProp,
|
|
23
24
|
VirtualProp,
|
|
24
25
|
} from "../types/types";
|
|
26
|
+
import { asArray } from "../utils/model";
|
|
25
27
|
|
|
26
28
|
export const p = {
|
|
27
29
|
integer,
|
|
@@ -264,3 +266,22 @@ function relationManyToMany(
|
|
|
264
266
|
...option,
|
|
265
267
|
};
|
|
266
268
|
}
|
|
269
|
+
|
|
270
|
+
export const i = {
|
|
271
|
+
index,
|
|
272
|
+
unique,
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
function index(columns: string | string[]): SMDIndex {
|
|
276
|
+
return {
|
|
277
|
+
type: "index",
|
|
278
|
+
columns: asArray(columns),
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function unique(columns: string | string[]): SMDIndex {
|
|
283
|
+
return {
|
|
284
|
+
type: "unique",
|
|
285
|
+
columns: asArray(columns),
|
|
286
|
+
};
|
|
287
|
+
}
|
package/src/smd/smd.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
SMDPropNode,
|
|
16
16
|
isEnumProp,
|
|
17
17
|
StringProp,
|
|
18
|
+
SMDIndex,
|
|
18
19
|
} from "../types/types";
|
|
19
20
|
import inflection from "inflection";
|
|
20
21
|
import path from "path";
|
|
@@ -39,6 +40,7 @@ export class SMD {
|
|
|
39
40
|
relations: {
|
|
40
41
|
[key: string]: RelationProp;
|
|
41
42
|
};
|
|
43
|
+
indexes: SMDIndex[];
|
|
42
44
|
subsets: {
|
|
43
45
|
[key: string]: string[];
|
|
44
46
|
};
|
|
@@ -52,7 +54,15 @@ export class SMD {
|
|
|
52
54
|
[name: string]: EnumsLabelKo<string>;
|
|
53
55
|
} = {};
|
|
54
56
|
|
|
55
|
-
constructor({
|
|
57
|
+
constructor({
|
|
58
|
+
id,
|
|
59
|
+
parentId,
|
|
60
|
+
table,
|
|
61
|
+
title,
|
|
62
|
+
props,
|
|
63
|
+
indexes,
|
|
64
|
+
subsets,
|
|
65
|
+
}: SMDInput<any>) {
|
|
56
66
|
// id
|
|
57
67
|
this.id = id;
|
|
58
68
|
this.parentId = parentId;
|
|
@@ -91,6 +101,9 @@ export class SMD {
|
|
|
91
101
|
this.relations = {};
|
|
92
102
|
}
|
|
93
103
|
|
|
104
|
+
// indexes
|
|
105
|
+
this.indexes = indexes ?? [];
|
|
106
|
+
|
|
94
107
|
// subsets
|
|
95
108
|
this.subsets = subsets ?? {};
|
|
96
109
|
|
|
@@ -514,22 +527,11 @@ export class SMD {
|
|
|
514
527
|
|
|
515
528
|
registerTableSpecs(): void {
|
|
516
529
|
const uniqueColumns = uniq(
|
|
517
|
-
this.
|
|
518
|
-
.
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
: prop.name;
|
|
523
|
-
if (prop.unique === true) {
|
|
524
|
-
return propColumn;
|
|
525
|
-
} else if (prop.unique && Array.isArray(prop.unique)) {
|
|
526
|
-
return propColumn;
|
|
527
|
-
} else {
|
|
528
|
-
return null;
|
|
529
|
-
}
|
|
530
|
-
})
|
|
531
|
-
.filter((prop) => prop !== null)
|
|
532
|
-
) as string[];
|
|
530
|
+
this.indexes
|
|
531
|
+
.filter((idx) => idx.type === "unique")
|
|
532
|
+
.map((idx) => idx.columns)
|
|
533
|
+
.flat()
|
|
534
|
+
);
|
|
533
535
|
|
|
534
536
|
SMDManager.setTableSpec({
|
|
535
537
|
name: this.table,
|
|
@@ -21,7 +21,7 @@ export class Template__model_test extends Template {
|
|
|
21
21
|
...this.getTargetAndPath(names),
|
|
22
22
|
body: `
|
|
23
23
|
import { describe, test, expect } from "vitest";
|
|
24
|
-
import { bootstrap } from '../../testing/
|
|
24
|
+
import { bootstrap } from '../../testing/bootstrap';
|
|
25
25
|
|
|
26
26
|
bootstrap([]);
|
|
27
27
|
describe.skip("${smdId}ModelTest", () => {
|
|
@@ -21,7 +21,7 @@ export class Template__smd extends Template {
|
|
|
21
21
|
return {
|
|
22
22
|
...this.getTargetAndPath(names),
|
|
23
23
|
body: `
|
|
24
|
-
import { p, SMDInput } from "sonamu";
|
|
24
|
+
import { p, i, SMDInput } from "sonamu";
|
|
25
25
|
import { ${smdId}FieldExpr } from "./${names.fs}.generated";
|
|
26
26
|
|
|
27
27
|
/*
|
|
@@ -37,6 +37,10 @@ export const ${names.camel}SmdInput: SMDInput<${smdId}FieldExpr> = {
|
|
|
37
37
|
now: true,
|
|
38
38
|
}),
|
|
39
39
|
],
|
|
40
|
+
indexes: [
|
|
41
|
+
i.index('created_at'),
|
|
42
|
+
//
|
|
43
|
+
],
|
|
40
44
|
subsets: {
|
|
41
45
|
A: [ 'id', 'created_at' ]
|
|
42
46
|
}
|
|
@@ -83,6 +83,13 @@ export function ${names.capital}IdAsyncSelect<T extends ${
|
|
|
83
83
|
);
|
|
84
84
|
}, [${names.camelPlural}]);
|
|
85
85
|
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
setListParams({
|
|
88
|
+
...listParams,
|
|
89
|
+
...baseListParams,
|
|
90
|
+
});
|
|
91
|
+
}, [baseListParams]);
|
|
92
|
+
|
|
86
93
|
const handleSearchChange = (
|
|
87
94
|
e: SyntheticEvent<HTMLElement, Event>,
|
|
88
95
|
data: DropdownOnSearchChangeData,
|
package/src/types/types.ts
CHANGED
|
@@ -122,8 +122,6 @@ type _RelationProp = {
|
|
|
122
122
|
name: string;
|
|
123
123
|
with: string;
|
|
124
124
|
nullable?: boolean;
|
|
125
|
-
index?: true | string[];
|
|
126
|
-
unique?: true | string[];
|
|
127
125
|
toFilter?: true;
|
|
128
126
|
};
|
|
129
127
|
export type OneToOneRelationProp = _RelationProp & {
|
|
@@ -180,12 +178,19 @@ export type SMDProp =
|
|
|
180
178
|
| VirtualProp
|
|
181
179
|
| RelationProp;
|
|
182
180
|
|
|
181
|
+
export type SMDIndex = {
|
|
182
|
+
type: "index" | "unique";
|
|
183
|
+
columns: string[];
|
|
184
|
+
name?: string;
|
|
185
|
+
};
|
|
186
|
+
|
|
183
187
|
export type SMDInput<T extends string> = {
|
|
184
188
|
id: string;
|
|
185
189
|
parentId?: string;
|
|
186
190
|
table?: string;
|
|
187
191
|
title?: string;
|
|
188
192
|
props?: SMDProp[];
|
|
193
|
+
indexes?: SMDIndex[];
|
|
189
194
|
subsets?: {
|
|
190
195
|
[subset: string]: T[];
|
|
191
196
|
};
|
|
@@ -352,7 +357,6 @@ export type MigrationColumn = {
|
|
|
352
357
|
export type MigrationIndex = {
|
|
353
358
|
columns: string[];
|
|
354
359
|
type: "unique" | "index";
|
|
355
|
-
name?: string;
|
|
356
360
|
};
|
|
357
361
|
export type MigrationForeign = {
|
|
358
362
|
columns: string[];
|