sonamu 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/.pnp.cjs +15552 -0
- package/.pnp.loader.mjs +285 -0
- package/.vscode/extensions.json +6 -0
- package/.vscode/settings.json +9 -0
- package/.yarnrc.yml +5 -0
- package/dist/bin/cli.d.ts +2 -0
- package/dist/bin/cli.d.ts.map +1 -0
- package/dist/bin/cli.js +123 -0
- package/dist/bin/cli.js.map +1 -0
- package/dist/index.js +34 -0
- package/package.json +60 -0
- package/src/api/caster.ts +72 -0
- package/src/api/code-converters.ts +552 -0
- package/src/api/context.ts +20 -0
- package/src/api/decorators.ts +63 -0
- package/src/api/index.ts +5 -0
- package/src/api/init.ts +128 -0
- package/src/bin/cli.ts +115 -0
- package/src/database/base-model.ts +287 -0
- package/src/database/db.ts +95 -0
- package/src/database/knex-plugins/knex-on-duplicate-update.ts +41 -0
- package/src/database/upsert-builder.ts +231 -0
- package/src/exceptions/error-handler.ts +29 -0
- package/src/exceptions/so-exceptions.ts +91 -0
- package/src/index.ts +17 -0
- package/src/shared/web.shared.ts.txt +119 -0
- package/src/smd/migrator.ts +1462 -0
- package/src/smd/smd-manager.ts +141 -0
- package/src/smd/smd-utils.ts +266 -0
- package/src/smd/smd.ts +533 -0
- package/src/syncer/index.ts +1 -0
- package/src/syncer/syncer.ts +1283 -0
- package/src/templates/base-template.ts +19 -0
- package/src/templates/generated.template.ts +247 -0
- package/src/templates/generated_http.template.ts +114 -0
- package/src/templates/index.ts +1 -0
- package/src/templates/init_enums.template.ts +71 -0
- package/src/templates/init_generated.template.ts +44 -0
- package/src/templates/init_types.template.ts +38 -0
- package/src/templates/model.template.ts +168 -0
- package/src/templates/model_test.template.ts +39 -0
- package/src/templates/service.template.ts +263 -0
- package/src/templates/smd.template.ts +49 -0
- package/src/templates/view_enums_buttonset.template.ts +34 -0
- package/src/templates/view_enums_dropdown.template.ts +67 -0
- package/src/templates/view_enums_select.template.ts +60 -0
- package/src/templates/view_form.template.ts +397 -0
- package/src/templates/view_id_all_select.template.ts +34 -0
- package/src/templates/view_id_async_select.template.ts +113 -0
- package/src/templates/view_list.template.ts +652 -0
- package/src/templates/view_list_columns.template.ts +59 -0
- package/src/templates/view_search_input.template.ts +67 -0
- package/src/testing/fixture-manager.ts +271 -0
- package/src/types/types.ts +668 -0
- package/src/typings/knex.d.ts +24 -0
- package/src/utils/controller.ts +21 -0
- package/src/utils/lodash-able.ts +11 -0
- package/src/utils/model.ts +33 -0
- package/src/utils/utils.ts +28 -0
- package/tsconfig.json +47 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { glob } from "glob";
|
|
3
|
+
import { dasherize, underscore, pluralize, camelize } from "inflection";
|
|
4
|
+
import _ from "lodash";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import { SMD } from "./smd";
|
|
7
|
+
import { SMDInput } from "../types/types";
|
|
8
|
+
import { Syncer } from "../syncer/syncer";
|
|
9
|
+
|
|
10
|
+
export type SMDNamesRecord = Record<
|
|
11
|
+
| "fs"
|
|
12
|
+
| "fsPlural"
|
|
13
|
+
| "camel"
|
|
14
|
+
| "camelPlural"
|
|
15
|
+
| "capital"
|
|
16
|
+
| "capitalPlural"
|
|
17
|
+
| "upper"
|
|
18
|
+
| "constant",
|
|
19
|
+
string
|
|
20
|
+
>;
|
|
21
|
+
type TableSpec = {
|
|
22
|
+
name: string;
|
|
23
|
+
uniqueColumns: string[];
|
|
24
|
+
};
|
|
25
|
+
class SMDManagerClass {
|
|
26
|
+
private SMDs: Map<string, SMD> = new Map();
|
|
27
|
+
private modulePaths: Map<string, string> = new Map();
|
|
28
|
+
private tableSpecs: Map<string, TableSpec> = new Map();
|
|
29
|
+
public isAutoloaded: boolean = false;
|
|
30
|
+
|
|
31
|
+
// 경로 전달받아 모든 SMD 파일 로드
|
|
32
|
+
async autoload(doSilent: boolean = false) {
|
|
33
|
+
if (this.isAutoloaded) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const pathPattern = path.join(
|
|
37
|
+
Syncer.getInstance().config.appRootPath,
|
|
38
|
+
"/api/dist/application/**/*.smd.js"
|
|
39
|
+
);
|
|
40
|
+
!doSilent && console.log(chalk.yellow(`autoload ${pathPattern}`));
|
|
41
|
+
|
|
42
|
+
return new Promise((resolve) => {
|
|
43
|
+
glob(path.resolve(pathPattern!), (_err, files) => {
|
|
44
|
+
const importPaths = files.map((filePath) =>
|
|
45
|
+
path.relative(__dirname, filePath)
|
|
46
|
+
);
|
|
47
|
+
Promise.all(
|
|
48
|
+
importPaths.map(async (importPath) => {
|
|
49
|
+
const imported = await import(importPath);
|
|
50
|
+
Object.values(imported).map((smdInput) =>
|
|
51
|
+
this.register(smdInput as SMDInput<string>)
|
|
52
|
+
);
|
|
53
|
+
return imported;
|
|
54
|
+
})
|
|
55
|
+
).then(() => {
|
|
56
|
+
resolve("ok");
|
|
57
|
+
this.isAutoloaded = true;
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
register(smdInput: SMDInput<string>): void {
|
|
64
|
+
const smd = new SMD(smdInput);
|
|
65
|
+
this.SMDs.set(smdInput.id, smd);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
get(smdId: string): SMD {
|
|
69
|
+
const smd = this.SMDs.get(smdId);
|
|
70
|
+
if (smd === undefined) {
|
|
71
|
+
throw new Error(`존재하지 않는 SMD 요청 ${smdId}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return smd;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
exists(smdId: string): boolean {
|
|
78
|
+
const smd = this.SMDs.get(smdId);
|
|
79
|
+
return smd !== undefined;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
getAllIds(): string[] {
|
|
83
|
+
return Array.from(SMDManager.SMDs.keys());
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
getAllParentIds(): string[] {
|
|
87
|
+
return this.getAllIds().filter((smdId) => {
|
|
88
|
+
const smd = this.get(smdId);
|
|
89
|
+
return smd.parentId === undefined;
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
getChildrenIds(parentId: string): string[] {
|
|
94
|
+
return this.getAllIds().filter((smdId) => {
|
|
95
|
+
const smd = this.get(smdId);
|
|
96
|
+
return smd.parentId === parentId;
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
setModulePath(key: string, modulePath: string): void {
|
|
101
|
+
// console.debug(chalk.cyan(`setModulePath :: ${key} :: ${modulePath}`));
|
|
102
|
+
this.modulePaths.set(key, modulePath);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
getModulePath(key: string): string {
|
|
106
|
+
const modulePath = this.modulePaths.get(key);
|
|
107
|
+
if (modulePath === undefined) {
|
|
108
|
+
throw new Error(`존재하지 않는 모듈 패스 요청 ${key}`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return modulePath;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
setTableSpec(tableSpec: TableSpec) {
|
|
115
|
+
this.tableSpecs.set(tableSpec.name, tableSpec);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
getTableSpec(key: string): TableSpec {
|
|
119
|
+
const tableSpec = this.tableSpecs.get(key);
|
|
120
|
+
if (tableSpec === undefined) {
|
|
121
|
+
throw new Error(`존재하지 않는 테이블 스펙 요청 ${key}`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return tableSpec;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
getNamesFromId(smdId: string): SMDNamesRecord {
|
|
128
|
+
return {
|
|
129
|
+
fs: dasherize(underscore(smdId)).toLowerCase(),
|
|
130
|
+
fsPlural: dasherize(underscore(pluralize(smdId))).toLowerCase(),
|
|
131
|
+
camel: camelize(smdId, true),
|
|
132
|
+
camelPlural: pluralize(camelize(smdId, true)),
|
|
133
|
+
capital: smdId,
|
|
134
|
+
capitalPlural: pluralize(smdId),
|
|
135
|
+
upper: smdId.toUpperCase(),
|
|
136
|
+
constant: underscore(smdId).toUpperCase(),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export const SMDManager = new SMDManagerClass();
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { camelize } from "inflection";
|
|
2
|
+
import {
|
|
3
|
+
BelongsToOneRelationProp,
|
|
4
|
+
BigIntegerProp,
|
|
5
|
+
BooleanProp,
|
|
6
|
+
DateProp,
|
|
7
|
+
DateTimeProp,
|
|
8
|
+
DecimalProp,
|
|
9
|
+
DistributiveOmit,
|
|
10
|
+
DoubleProp,
|
|
11
|
+
EnumProp,
|
|
12
|
+
FloatProp,
|
|
13
|
+
HasManyRelationProp,
|
|
14
|
+
IntegerProp,
|
|
15
|
+
JsonProp,
|
|
16
|
+
ManyToManyRelationProp,
|
|
17
|
+
OneToOneRelationProp,
|
|
18
|
+
StringProp,
|
|
19
|
+
TextProp,
|
|
20
|
+
TimeProp,
|
|
21
|
+
TimestampProp,
|
|
22
|
+
UuidProp,
|
|
23
|
+
VirtualProp,
|
|
24
|
+
} from "../types/types";
|
|
25
|
+
|
|
26
|
+
export const p = {
|
|
27
|
+
integer,
|
|
28
|
+
bigInteger,
|
|
29
|
+
text,
|
|
30
|
+
string,
|
|
31
|
+
float,
|
|
32
|
+
double,
|
|
33
|
+
decimal,
|
|
34
|
+
boolean,
|
|
35
|
+
date,
|
|
36
|
+
dateTime,
|
|
37
|
+
time,
|
|
38
|
+
timestamp,
|
|
39
|
+
json,
|
|
40
|
+
uuid,
|
|
41
|
+
enums,
|
|
42
|
+
virtual,
|
|
43
|
+
relationOneToOne,
|
|
44
|
+
relationBelongsToOne,
|
|
45
|
+
relationHasMany,
|
|
46
|
+
relationManyToMany,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
function integer(
|
|
50
|
+
name: string,
|
|
51
|
+
option?: Omit<IntegerProp, "name" | "type">
|
|
52
|
+
): IntegerProp {
|
|
53
|
+
return {
|
|
54
|
+
name,
|
|
55
|
+
type: "integer",
|
|
56
|
+
...option,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function bigInteger(
|
|
60
|
+
name: string,
|
|
61
|
+
option?: Omit<BigIntegerProp, "name" | "type">
|
|
62
|
+
): BigIntegerProp {
|
|
63
|
+
return {
|
|
64
|
+
name,
|
|
65
|
+
type: "bigInteger",
|
|
66
|
+
...option,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function text(name: string, option: Omit<TextProp, "name" | "type">): TextProp {
|
|
70
|
+
return {
|
|
71
|
+
name,
|
|
72
|
+
type: "text",
|
|
73
|
+
...option,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function string(
|
|
77
|
+
name: string,
|
|
78
|
+
option: Omit<StringProp, "name" | "type">
|
|
79
|
+
): StringProp {
|
|
80
|
+
return {
|
|
81
|
+
name,
|
|
82
|
+
type: "string",
|
|
83
|
+
...option,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function float(
|
|
87
|
+
name: string,
|
|
88
|
+
option?: Omit<FloatProp, "name" | "type">
|
|
89
|
+
): FloatProp {
|
|
90
|
+
return {
|
|
91
|
+
name,
|
|
92
|
+
type: "float",
|
|
93
|
+
...option,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function double(
|
|
97
|
+
name: string,
|
|
98
|
+
option?: Omit<DoubleProp, "name" | "type">
|
|
99
|
+
): DoubleProp {
|
|
100
|
+
return {
|
|
101
|
+
name,
|
|
102
|
+
type: "double",
|
|
103
|
+
...option,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function decimal(
|
|
107
|
+
name: string,
|
|
108
|
+
option?: Omit<DecimalProp, "name" | "type">
|
|
109
|
+
): DecimalProp {
|
|
110
|
+
return {
|
|
111
|
+
name,
|
|
112
|
+
type: "decimal",
|
|
113
|
+
...option,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function boolean(
|
|
117
|
+
name: string,
|
|
118
|
+
option?: Omit<BooleanProp, "name" | "type">
|
|
119
|
+
): BooleanProp {
|
|
120
|
+
return {
|
|
121
|
+
name,
|
|
122
|
+
type: "boolean",
|
|
123
|
+
...option,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function date(
|
|
127
|
+
name: string,
|
|
128
|
+
option?: Omit<DateProp, "name" | "type"> & { now?: true }
|
|
129
|
+
): DateProp {
|
|
130
|
+
if (option?.now === true) {
|
|
131
|
+
delete option.now;
|
|
132
|
+
option.dbDefault = "CURRENT_TIMESTAMP";
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
name,
|
|
136
|
+
type: "date",
|
|
137
|
+
...option,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
function dateTime(
|
|
141
|
+
name: string,
|
|
142
|
+
option?: Omit<DateTimeProp, "name" | "type"> & { now?: true }
|
|
143
|
+
): DateTimeProp {
|
|
144
|
+
if (option?.now === true) {
|
|
145
|
+
delete option.now;
|
|
146
|
+
option.dbDefault = "CURRENT_TIMESTAMP";
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
name,
|
|
150
|
+
type: "dateTime",
|
|
151
|
+
...option,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
function time(
|
|
155
|
+
name: string,
|
|
156
|
+
option?: Omit<TimeProp, "name" | "type"> & { now?: true }
|
|
157
|
+
): TimeProp {
|
|
158
|
+
if (option?.now === true) {
|
|
159
|
+
delete option.now;
|
|
160
|
+
option.dbDefault = "CURRENT_TIMESTAMP";
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
name,
|
|
164
|
+
type: "time",
|
|
165
|
+
...option,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function timestamp(
|
|
169
|
+
name: string,
|
|
170
|
+
option?: Omit<TimestampProp, "name" | "type"> & { now?: true }
|
|
171
|
+
): TimestampProp {
|
|
172
|
+
if (option?.now === true) {
|
|
173
|
+
delete option.now;
|
|
174
|
+
option.dbDefault = "CURRENT_TIMESTAMP";
|
|
175
|
+
}
|
|
176
|
+
return {
|
|
177
|
+
name,
|
|
178
|
+
type: "timestamp",
|
|
179
|
+
...option,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
function json(name: string, option: Omit<JsonProp, "name" | "type">): JsonProp {
|
|
183
|
+
return {
|
|
184
|
+
name,
|
|
185
|
+
type: "json",
|
|
186
|
+
...option,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
function uuid(name: string, option: Omit<UuidProp, "name" | "type">): UuidProp {
|
|
190
|
+
return {
|
|
191
|
+
name,
|
|
192
|
+
type: "uuid",
|
|
193
|
+
...option,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
function enums(
|
|
197
|
+
name: string,
|
|
198
|
+
option: Omit<EnumProp, "name" | "type" | "id"> & { id?: string }
|
|
199
|
+
): EnumProp {
|
|
200
|
+
return {
|
|
201
|
+
name,
|
|
202
|
+
type: "enum",
|
|
203
|
+
id: option.id ?? `$Model${camelize(name)}`,
|
|
204
|
+
...option,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
function virtual(
|
|
208
|
+
name: string,
|
|
209
|
+
option: Omit<
|
|
210
|
+
VirtualProp,
|
|
211
|
+
"name" | "type" | "index" | "unique" | "dbDefault" | "toFilter"
|
|
212
|
+
>
|
|
213
|
+
): VirtualProp {
|
|
214
|
+
return {
|
|
215
|
+
name,
|
|
216
|
+
type: "virtual",
|
|
217
|
+
...option,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
function relationOneToOne(
|
|
221
|
+
name: string,
|
|
222
|
+
option: DistributiveOmit<
|
|
223
|
+
OneToOneRelationProp,
|
|
224
|
+
"name" | "type" | "relationType"
|
|
225
|
+
>
|
|
226
|
+
): OneToOneRelationProp {
|
|
227
|
+
return {
|
|
228
|
+
name,
|
|
229
|
+
type: "relation",
|
|
230
|
+
relationType: "OneToOne",
|
|
231
|
+
...option,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
function relationBelongsToOne(
|
|
235
|
+
name: string,
|
|
236
|
+
option: Omit<BelongsToOneRelationProp, "name" | "type" | "relationType">
|
|
237
|
+
): BelongsToOneRelationProp {
|
|
238
|
+
return {
|
|
239
|
+
name,
|
|
240
|
+
type: "relation",
|
|
241
|
+
relationType: "BelongsToOne",
|
|
242
|
+
...option,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
function relationHasMany(
|
|
246
|
+
name: string,
|
|
247
|
+
option: Omit<HasManyRelationProp, "name" | "type" | "relationType">
|
|
248
|
+
): HasManyRelationProp {
|
|
249
|
+
return {
|
|
250
|
+
name,
|
|
251
|
+
type: "relation",
|
|
252
|
+
relationType: "HasMany",
|
|
253
|
+
...option,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
function relationManyToMany(
|
|
257
|
+
name: string,
|
|
258
|
+
option: Omit<ManyToManyRelationProp, "name" | "type" | "relationType">
|
|
259
|
+
): ManyToManyRelationProp {
|
|
260
|
+
return {
|
|
261
|
+
name,
|
|
262
|
+
type: "relation",
|
|
263
|
+
relationType: "ManyToMany",
|
|
264
|
+
...option,
|
|
265
|
+
};
|
|
266
|
+
}
|