@shys/crud 1.0.1-beta.6 → 1.0.1-beta.8
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/cli.js +60 -50
- package/dist/config.js +2 -0
- package/dist/generator.d.ts +2 -1
- package/dist/generator.js +74 -16
- package/dist/types.d.ts +18 -0
- package/package.json +1 -1
- package/templates/controller.njk +65 -65
- package/templates/dto-index.njk +4 -4
- package/templates/dto-query.njk +17 -17
- package/templates/entity.njk +19 -9
- package/templates/service.njk +20 -20
package/dist/cli.js
CHANGED
|
@@ -16,56 +16,56 @@ const warn = (t) => console.log(`${chalk.yellow('!')} ${t}`);
|
|
|
16
16
|
const err = (t) => console.log(`${chalk.red('✘')} ${t}`);
|
|
17
17
|
const info = (t) => console.log(`${chalk.cyan('ℹ')} ${t}`);
|
|
18
18
|
function printHelp() {
|
|
19
|
-
console.log(`shys-crud CLI — MidwayJS v4 模块化 CRUD 代码生成器
|
|
20
|
-
|
|
21
|
-
用法:
|
|
22
|
-
shys-crud --module <moduleName> --table <tableName> [选项]
|
|
23
|
-
npx @shys/crud --module <moduleName> --table <tableName> [选项]
|
|
24
|
-
|
|
25
|
-
参数:
|
|
26
|
-
-m, --module 模块名(如 home/order/goods)
|
|
27
|
-
-t, --table 表名(如 sys_dept/city/order_info)
|
|
28
|
-
-s, --src src 根路径(默认 ./src 或从配置文件读取)
|
|
29
|
-
-o, --output 生成文件输出路径(默认与 --src 相同)
|
|
30
|
-
--templates-path 自定义模板目录路径
|
|
31
|
-
|
|
32
|
-
选项:
|
|
33
|
-
-f, --force 强制覆盖已存在的文件
|
|
34
|
-
-n, --dry-run 模拟运行,不实际写入文件
|
|
35
|
-
-c, --compile 生成完后自动执行 mwtsc --cleanOutDir
|
|
36
|
-
--only-entity 仅生成 entity 文件,不生成 DTO/VO/Service/Controller
|
|
37
|
-
--no-db 不尝试连库,使用模板字段模式
|
|
38
|
-
--db-host 数据库 host
|
|
39
|
-
--db-port 数据库端口(默认 3306)
|
|
40
|
-
--db-user 数据库用户名
|
|
41
|
-
--db-pass 数据库密码
|
|
42
|
-
--db-name 数据库名
|
|
43
|
-
-h, --help 显示帮助信息
|
|
44
|
-
|
|
45
|
-
配置文件支持(按优先级从高到低):
|
|
46
|
-
--src 指向的目录或 cwd 下查找:
|
|
47
|
-
- crud.config.ts / crud.config.js / crud.config.mjs / crud.config.cjs
|
|
48
|
-
- .crudrc / .crudrc.json / .crudrc.yaml / .crudrc.yml / .crudrc.js
|
|
49
|
-
- .config/crudrc / .config/crudrc.json
|
|
50
|
-
- package.json 中的 "crud" 字段
|
|
51
|
-
|
|
52
|
-
配置文件示例(crud.config.ts):
|
|
53
|
-
export default {
|
|
54
|
-
baseSrcPath: './src',
|
|
55
|
-
outputPath: './src',
|
|
56
|
-
db: {
|
|
57
|
-
host: '127.0.0.1',
|
|
58
|
-
port: 3306,
|
|
59
|
-
user: 'root',
|
|
60
|
-
password: '',
|
|
61
|
-
database: 'mydb',
|
|
62
|
-
},
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
示例:
|
|
66
|
-
shys-crud --module home --table sys_dept
|
|
67
|
-
shys-crud --module order --table order_info --force
|
|
68
|
-
shys-crud -m home -t city -s ./packages/webtest/src --db-name world
|
|
19
|
+
console.log(`shys-crud CLI — MidwayJS v4 模块化 CRUD 代码生成器
|
|
20
|
+
|
|
21
|
+
用法:
|
|
22
|
+
shys-crud --module <moduleName> --table <tableName> [选项]
|
|
23
|
+
npx @shys/crud --module <moduleName> --table <tableName> [选项]
|
|
24
|
+
|
|
25
|
+
参数:
|
|
26
|
+
-m, --module 模块名(如 home/order/goods)
|
|
27
|
+
-t, --table 表名(如 sys_dept/city/order_info)
|
|
28
|
+
-s, --src src 根路径(默认 ./src 或从配置文件读取)
|
|
29
|
+
-o, --output 生成文件输出路径(默认与 --src 相同)
|
|
30
|
+
--templates-path 自定义模板目录路径
|
|
31
|
+
|
|
32
|
+
选项:
|
|
33
|
+
-f, --force 强制覆盖已存在的文件
|
|
34
|
+
-n, --dry-run 模拟运行,不实际写入文件
|
|
35
|
+
-c, --compile 生成完后自动执行 mwtsc --cleanOutDir
|
|
36
|
+
--only-entity 仅生成 entity 文件,不生成 DTO/VO/Service/Controller
|
|
37
|
+
--no-db 不尝试连库,使用模板字段模式
|
|
38
|
+
--db-host 数据库 host
|
|
39
|
+
--db-port 数据库端口(默认 3306)
|
|
40
|
+
--db-user 数据库用户名
|
|
41
|
+
--db-pass 数据库密码
|
|
42
|
+
--db-name 数据库名
|
|
43
|
+
-h, --help 显示帮助信息
|
|
44
|
+
|
|
45
|
+
配置文件支持(按优先级从高到低):
|
|
46
|
+
--src 指向的目录或 cwd 下查找:
|
|
47
|
+
- crud.config.ts / crud.config.js / crud.config.mjs / crud.config.cjs
|
|
48
|
+
- .crudrc / .crudrc.json / .crudrc.yaml / .crudrc.yml / .crudrc.js
|
|
49
|
+
- .config/crudrc / .config/crudrc.json
|
|
50
|
+
- package.json 中的 "crud" 字段
|
|
51
|
+
|
|
52
|
+
配置文件示例(crud.config.ts):
|
|
53
|
+
export default {
|
|
54
|
+
baseSrcPath: './src',
|
|
55
|
+
outputPath: './src',
|
|
56
|
+
db: {
|
|
57
|
+
host: '127.0.0.1',
|
|
58
|
+
port: 3306,
|
|
59
|
+
user: 'root',
|
|
60
|
+
password: '',
|
|
61
|
+
database: 'mydb',
|
|
62
|
+
},
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
示例:
|
|
66
|
+
shys-crud --module home --table sys_dept
|
|
67
|
+
shys-crud --module order --table order_info --force
|
|
68
|
+
shys-crud -m home -t city -s ./packages/webtest/src --db-name world
|
|
69
69
|
`);
|
|
70
70
|
}
|
|
71
71
|
function parseArgs(argv) {
|
|
@@ -153,6 +153,15 @@ async function askIfMissing(cli, config) {
|
|
|
153
153
|
if (!cli.onlyEntity && config.onlyEntity) {
|
|
154
154
|
cli.onlyEntity = true;
|
|
155
155
|
}
|
|
156
|
+
if (!cli.hooks && config.hooks) {
|
|
157
|
+
cli.hooks = config.hooks;
|
|
158
|
+
}
|
|
159
|
+
if (!cli.baseFieldNames && config.baseFieldNames) {
|
|
160
|
+
cli.baseFieldNames = config.baseFieldNames;
|
|
161
|
+
}
|
|
162
|
+
if (!cli.excludeWritableFields && config.excludeWritableFields) {
|
|
163
|
+
cli.excludeWritableFields = config.excludeWritableFields;
|
|
164
|
+
}
|
|
156
165
|
}
|
|
157
166
|
finally {
|
|
158
167
|
rl.close();
|
|
@@ -279,6 +288,7 @@ export async function runCli(argv = process.argv.slice(2)) {
|
|
|
279
288
|
onlyEntity: cli.onlyEntity,
|
|
280
289
|
baseFieldNames: cli.baseFieldNames,
|
|
281
290
|
excludeWritableFields: cli.excludeWritableFields,
|
|
291
|
+
hooks: cli.hooks,
|
|
282
292
|
});
|
|
283
293
|
console.log(`\n${chalk.cyan(`生成清单(${built.files.length})`)}`);
|
|
284
294
|
const stats = writeAll(built.files, { force: !!cli.force, dryRun: !!cli.dryRun });
|
package/dist/config.js
CHANGED
|
@@ -111,6 +111,8 @@ export function mergeConfigs(...configs) {
|
|
|
111
111
|
result.baseFieldNames = config.baseFieldNames;
|
|
112
112
|
if (config.excludeWritableFields !== undefined)
|
|
113
113
|
result.excludeWritableFields = config.excludeWritableFields;
|
|
114
|
+
if (config.hooks !== undefined)
|
|
115
|
+
result.hooks = { ...(result.hooks || {}), ...config.hooks };
|
|
114
116
|
if (config.db) {
|
|
115
117
|
result.db = { ...(result.db || {}), ...config.db };
|
|
116
118
|
}
|
package/dist/generator.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FieldInfo, OrmInfo } from './types.js';
|
|
1
|
+
import type { CrudHooks, FieldInfo, OrmInfo } from './types.js';
|
|
2
2
|
import { TemplateRenderer } from './renderer.js';
|
|
3
3
|
export interface BuildResult {
|
|
4
4
|
files: Array<{
|
|
@@ -25,5 +25,6 @@ export interface BuildFilesParams {
|
|
|
25
25
|
onlyEntity?: boolean;
|
|
26
26
|
baseFieldNames?: string[];
|
|
27
27
|
excludeWritableFields?: string[];
|
|
28
|
+
hooks?: CrudHooks;
|
|
28
29
|
}
|
|
29
30
|
export declare function buildFiles(params: BuildFilesParams): BuildResult;
|
package/dist/generator.js
CHANGED
|
@@ -166,13 +166,44 @@ function enhanceField(f, extra = {}) {
|
|
|
166
166
|
};
|
|
167
167
|
}
|
|
168
168
|
export function buildFiles(params) {
|
|
169
|
-
const { moduleName, tableName, baseSrcPath, ormInfo, fields, outputPath, templatesPath, renderer: customRenderer, onlyEntity, baseFieldNames, excludeWritableFields, } = params;
|
|
169
|
+
const { moduleName, tableName: rawTableName, baseSrcPath, ormInfo, fields: rawFields, outputPath, templatesPath, renderer: customRenderer, onlyEntity, baseFieldNames, excludeWritableFields, hooks, } = params;
|
|
170
|
+
const tableName = hooks?.customTableName
|
|
171
|
+
? hooks.customTableName(rawTableName)
|
|
172
|
+
: rawTableName;
|
|
173
|
+
let fields = rawFields;
|
|
174
|
+
if (hooks?.customFields) {
|
|
175
|
+
fields = hooks.customFields(fields);
|
|
176
|
+
}
|
|
177
|
+
if (hooks?.customField || hooks?.customFieldName) {
|
|
178
|
+
fields = fields
|
|
179
|
+
.map((f) => {
|
|
180
|
+
let field = { ...f };
|
|
181
|
+
if (hooks?.customFieldName) {
|
|
182
|
+
const newName = hooks.customFieldName(field.name);
|
|
183
|
+
if (newName !== field.name) {
|
|
184
|
+
field.name = newName;
|
|
185
|
+
field.camel = toCamelCase(newName);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (hooks?.customField) {
|
|
189
|
+
const result = hooks.customField(field);
|
|
190
|
+
if (result === null)
|
|
191
|
+
return null;
|
|
192
|
+
field = { ...field, ...result };
|
|
193
|
+
}
|
|
194
|
+
return field;
|
|
195
|
+
})
|
|
196
|
+
.filter(Boolean);
|
|
197
|
+
}
|
|
170
198
|
const renderer = customRenderer || createRenderer({ customTemplatesPath: templatesPath });
|
|
171
199
|
const finalBaseFieldNames = baseFieldNames ?? DEFAULT_BASE_FIELD_NAMES;
|
|
172
200
|
const finalExcludeWritable = excludeWritableFields ?? DEFAULT_EXCLUDE_WRITABLE_FIELDS;
|
|
173
201
|
const excludeWritableRegex = new RegExp(finalExcludeWritable.map(s => `^${s}$`).join('|'), 'i');
|
|
174
202
|
const Camel = toCamelCase(tableName);
|
|
175
|
-
const
|
|
203
|
+
const rawPascal = toPascalCase(tableName);
|
|
204
|
+
const Pascal = hooks?.customEntityName
|
|
205
|
+
? hooks.customEntityName(rawPascal)
|
|
206
|
+
: rawPascal;
|
|
176
207
|
const CreateName = `Create${Pascal}Dto`;
|
|
177
208
|
const UpdateName = `Update${Pascal}Dto`;
|
|
178
209
|
const ReplaceName = `Replace${Pascal}Dto`;
|
|
@@ -186,8 +217,10 @@ export function buildFiles(params) {
|
|
|
186
217
|
const desc = `${tableName} 表增删改查接口`;
|
|
187
218
|
const modRoot = resolve(outputPath || baseSrcPath, 'modules', moduleName);
|
|
188
219
|
const resultFiles = [];
|
|
189
|
-
const
|
|
190
|
-
const
|
|
220
|
+
const pkFields = fields.filter(f => f.pk);
|
|
221
|
+
const originalPkInfo = pkFields[0] || null;
|
|
222
|
+
const hasPk = pkFields.length > 0;
|
|
223
|
+
const autoPkFields = pkFields.filter(f => f.auto);
|
|
191
224
|
const entityFields = fields.filter(f => {
|
|
192
225
|
if (finalBaseFieldNames.includes(f.camel))
|
|
193
226
|
return false;
|
|
@@ -200,6 +233,7 @@ export function buildFiles(params) {
|
|
|
200
233
|
const hasDateField = entityFields.some(f => /datetime|date|timestamp/i.test(f.type));
|
|
201
234
|
const enhancedEntityFields = entityFields.map(f => enhanceField(f, { idx: idxFields.some(i => i.name === f.name) }));
|
|
202
235
|
const enhancedPkInfo = originalPkInfo ? enhanceField(originalPkInfo) : null;
|
|
236
|
+
const enhancedPkInfos = pkFields.map(f => enhanceField(f));
|
|
203
237
|
// Entity
|
|
204
238
|
resultFiles.push({
|
|
205
239
|
path: resolve(modRoot, `entity/${Camel}.entity.ts`),
|
|
@@ -211,6 +245,7 @@ export function buildFiles(params) {
|
|
|
211
245
|
Pascal,
|
|
212
246
|
Camel,
|
|
213
247
|
pkInfo: enhancedPkInfo,
|
|
248
|
+
pkInfos: enhancedPkInfos,
|
|
214
249
|
hasPk,
|
|
215
250
|
hasDateField,
|
|
216
251
|
idxCount: idxFields.length,
|
|
@@ -227,24 +262,44 @@ export function buildFiles(params) {
|
|
|
227
262
|
searchable: [],
|
|
228
263
|
};
|
|
229
264
|
}
|
|
230
|
-
const createFields =
|
|
265
|
+
const createFields = fields.filter(f => {
|
|
266
|
+
if (finalBaseFieldNames.includes(f.camel))
|
|
267
|
+
return false;
|
|
268
|
+
if (f.pk && f.auto)
|
|
269
|
+
return false;
|
|
270
|
+
return true;
|
|
271
|
+
});
|
|
231
272
|
const writable = createFields.filter(f => !excludeWritableRegex.test(f.name));
|
|
232
273
|
const isSensitive = (f) => /password|passwd|salt|token|secret|private_key/i.test(f.name + f.camel);
|
|
233
274
|
const pkCamel = originalPkInfo?.camel || '';
|
|
234
|
-
const
|
|
275
|
+
const pkCamels = pkFields.map(f => f.camel);
|
|
276
|
+
const sortableBase = [...entityFields, ...pkFields]
|
|
235
277
|
.filter(f => !isSensitive(f))
|
|
236
278
|
.map(f => f.camel);
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
? [originalPkInfo, ...filterableBase]
|
|
243
|
-
: filterableBase;
|
|
244
|
-
const filterable = filterableArr.map(f => f.camel);
|
|
245
|
-
const searchable = filterableArr
|
|
279
|
+
let sortable = [...new Set([...pkCamels, ...sortableBase])];
|
|
280
|
+
const filterableBase = [...entityFields, ...pkFields].filter(f => !isSensitive(f));
|
|
281
|
+
let filterableArr = [...new Map([...pkFields, ...filterableBase].map(f => [f.camel, f])).values()];
|
|
282
|
+
let filterable = filterableArr.map(f => f.camel);
|
|
283
|
+
let searchable = filterableArr
|
|
246
284
|
.filter(f => /char|varchar|text/i.test(f.type))
|
|
247
285
|
.map(f => f.camel);
|
|
286
|
+
if (hooks?.queryFields) {
|
|
287
|
+
const hookResult = hooks.queryFields(tableName, fields, Pascal, {
|
|
288
|
+
sortable,
|
|
289
|
+
filterable,
|
|
290
|
+
searchable,
|
|
291
|
+
});
|
|
292
|
+
if (hookResult) {
|
|
293
|
+
if (hookResult.sortable !== undefined)
|
|
294
|
+
sortable = hookResult.sortable;
|
|
295
|
+
if (hookResult.filterable !== undefined) {
|
|
296
|
+
filterable = hookResult.filterable;
|
|
297
|
+
filterableArr = fields.filter(f => filterable.includes(f.camel));
|
|
298
|
+
}
|
|
299
|
+
if (hookResult.searchable !== undefined)
|
|
300
|
+
searchable = hookResult.searchable;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
248
303
|
const enhancedCreateFields = createFields.map(f => enhanceField(f));
|
|
249
304
|
const enhancedWritable = writable.map(f => enhanceField(f));
|
|
250
305
|
const enhancedFilterable = filterableArr.map(f => enhanceField(f));
|
|
@@ -325,7 +380,7 @@ export function buildFiles(params) {
|
|
|
325
380
|
});
|
|
326
381
|
// Single VO
|
|
327
382
|
const allVoFields = [
|
|
328
|
-
...
|
|
383
|
+
...pkFields,
|
|
329
384
|
...entityFields,
|
|
330
385
|
].map(f => enhanceField(f));
|
|
331
386
|
const voHasTransform = allVoFields.some(f => f.isDate || f.isSensitive);
|
|
@@ -366,6 +421,7 @@ export function buildFiles(params) {
|
|
|
366
421
|
// Controller
|
|
367
422
|
const sArr = (arr) => arr.map(x => JSON.stringify(x)).join(', ');
|
|
368
423
|
const idField = pkCamel || 'id';
|
|
424
|
+
const idFields = pkCamels.length ? pkCamels : ['id'];
|
|
369
425
|
const defaultSort = searchable && searchable.length
|
|
370
426
|
? `[{ field: ${JSON.stringify(sortable[0] || idField)}, order: 'DESC' }]`
|
|
371
427
|
: `[{ field: 'id', order: 'DESC' }]`;
|
|
@@ -389,7 +445,9 @@ export function buildFiles(params) {
|
|
|
389
445
|
filterable: sArr(filterable),
|
|
390
446
|
searchable: sArr(searchable),
|
|
391
447
|
pkCamel,
|
|
448
|
+
pkCamels,
|
|
392
449
|
idField,
|
|
450
|
+
idFields,
|
|
393
451
|
defaultSort,
|
|
394
452
|
}),
|
|
395
453
|
});
|
package/dist/types.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ export interface CrudConfig {
|
|
|
20
20
|
onlyEntity?: boolean;
|
|
21
21
|
baseFieldNames?: string[];
|
|
22
22
|
excludeWritableFields?: string[];
|
|
23
|
+
hooks?: CrudHooks;
|
|
23
24
|
}
|
|
24
25
|
export interface CliOptions extends CrudConfig {
|
|
25
26
|
help?: boolean;
|
|
@@ -36,6 +37,23 @@ export interface FieldInfo {
|
|
|
36
37
|
defaultVal: any;
|
|
37
38
|
comment: string;
|
|
38
39
|
}
|
|
40
|
+
export interface QueryFieldsResult {
|
|
41
|
+
sortable?: string[];
|
|
42
|
+
filterable?: string[];
|
|
43
|
+
searchable?: string[];
|
|
44
|
+
}
|
|
45
|
+
export interface CrudHooks {
|
|
46
|
+
customEntityName?: (tableName: string) => string;
|
|
47
|
+
customFieldName?: (fieldName: string) => string;
|
|
48
|
+
customField?: (field: FieldInfo) => FieldInfo | null;
|
|
49
|
+
customFields?: (fields: FieldInfo[]) => FieldInfo[];
|
|
50
|
+
customTableName?: (tableName: string) => string;
|
|
51
|
+
queryFields?: (tableName: string, fields: FieldInfo[], pascal: string, defaultQuery: {
|
|
52
|
+
sortable: string[];
|
|
53
|
+
filterable: string[];
|
|
54
|
+
searchable: string[];
|
|
55
|
+
}) => QueryFieldsResult | void;
|
|
56
|
+
}
|
|
39
57
|
export interface OrmInfo {
|
|
40
58
|
orm: string;
|
|
41
59
|
ormSuffix: string;
|
package/package.json
CHANGED
package/templates/controller.njk
CHANGED
|
@@ -1,65 +1,65 @@
|
|
|
1
|
-
import { Inject } from '@midwayjs/core';
|
|
2
|
-
import { YSController, CrudPiped } from '@shys/core';
|
|
3
|
-
import { {{ Pascal }} } from '../entity/{{ Camel }}.entity';
|
|
4
|
-
import { {{ ServiceName }} } from '../service/{{ Camel }}.service';
|
|
5
|
-
import {
|
|
6
|
-
{{ CreateName }},
|
|
7
|
-
{{ UpdateName }},
|
|
8
|
-
{{ ReplaceName }},
|
|
9
|
-
{{ QueryName }},
|
|
10
|
-
} from '../dto/{{ Camel }}';
|
|
11
|
-
import { {{ VOName }}, {{ ListVOName }} } from '../vo/{{ Camel }}';
|
|
12
|
-
|
|
13
|
-
@YSController({
|
|
14
|
-
tagName: {{ tagName | json }},
|
|
15
|
-
description: {{ desc | json }},
|
|
16
|
-
})
|
|
17
|
-
@CrudPiped({
|
|
18
|
-
model: {{ Pascal }},
|
|
19
|
-
service: {{ ServiceName }},
|
|
20
|
-
id: {{ idField | json }},
|
|
21
|
-
dto: {
|
|
22
|
-
create: {{ CreateName }},
|
|
23
|
-
update: {{ UpdateName }},
|
|
24
|
-
replace: {{ ReplaceName }},
|
|
25
|
-
query: {{ QueryName }},
|
|
26
|
-
},
|
|
27
|
-
serialize: {
|
|
28
|
-
get: {{ VOName }},
|
|
29
|
-
list: {{ ListVOName }},
|
|
30
|
-
create: {{ VOName }},
|
|
31
|
-
update: {{ VOName }},
|
|
32
|
-
},
|
|
33
|
-
routes: {
|
|
34
|
-
only: ['list', 'detail', 'create', 'update', 'replace', 'delete'],
|
|
35
|
-
},
|
|
36
|
-
query: {
|
|
37
|
-
maxLimit: 100,
|
|
38
|
-
defaultLimit: 10,
|
|
39
|
-
sortable: [{{ sortable }}],
|
|
40
|
-
filterable: [{{ filterable }}],
|
|
41
|
-
searchable: [{{ searchable }}],
|
|
42
|
-
defaultSort: {{ defaultSort }},
|
|
43
|
-
},
|
|
44
|
-
piped: {
|
|
45
|
-
create: {
|
|
46
|
-
enabled: true,
|
|
47
|
-
stages: ['deserialize', 'sanitize', 'mapFields', 'transform', 'validate'],
|
|
48
|
-
validate: { enabled: true, errorStatus: 422 },
|
|
49
|
-
},
|
|
50
|
-
update: {
|
|
51
|
-
enabled: true,
|
|
52
|
-
stages: ['deserialize', 'sanitize', 'mapFields', 'transform', 'validate'],
|
|
53
|
-
validate: { enabled: true, errorStatus: 422 },
|
|
54
|
-
},
|
|
55
|
-
replace: {
|
|
56
|
-
enabled: true,
|
|
57
|
-
stages: ['deserialize', 'sanitize', 'mapFields', 'transform', 'validate'],
|
|
58
|
-
validate: { enabled: true, errorStatus: 422 },
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
})
|
|
62
|
-
export class {{ CtrlName }} {
|
|
63
|
-
@Inject()
|
|
64
|
-
crudService: {{ ServiceName }};
|
|
65
|
-
}
|
|
1
|
+
import { Inject } from '@midwayjs/core';
|
|
2
|
+
import { YSController, CrudPiped } from '@shys/core';
|
|
3
|
+
import { {{ Pascal }} } from '../entity/{{ Camel }}.entity';
|
|
4
|
+
import { {{ ServiceName }} } from '../service/{{ Camel }}.service';
|
|
5
|
+
import {
|
|
6
|
+
{{ CreateName }},
|
|
7
|
+
{{ UpdateName }},
|
|
8
|
+
{{ ReplaceName }},
|
|
9
|
+
{{ QueryName }},
|
|
10
|
+
} from '../dto/{{ Camel }}';
|
|
11
|
+
import { {{ VOName }}, {{ ListVOName }} } from '../vo/{{ Camel }}';
|
|
12
|
+
|
|
13
|
+
@YSController({
|
|
14
|
+
tagName: {{ tagName | json }},
|
|
15
|
+
description: {{ desc | json }},
|
|
16
|
+
})
|
|
17
|
+
@CrudPiped({
|
|
18
|
+
model: {{ Pascal }},
|
|
19
|
+
service: {{ ServiceName }},
|
|
20
|
+
id: {{ idField | json }},
|
|
21
|
+
dto: {
|
|
22
|
+
create: {{ CreateName }},
|
|
23
|
+
update: {{ UpdateName }},
|
|
24
|
+
replace: {{ ReplaceName }},
|
|
25
|
+
query: {{ QueryName }},
|
|
26
|
+
},
|
|
27
|
+
serialize: {
|
|
28
|
+
get: {{ VOName }},
|
|
29
|
+
list: {{ ListVOName }},
|
|
30
|
+
create: {{ VOName }},
|
|
31
|
+
update: {{ VOName }},
|
|
32
|
+
},
|
|
33
|
+
routes: {
|
|
34
|
+
only: ['list', 'detail', 'create', 'update', 'replace', 'delete'],
|
|
35
|
+
},
|
|
36
|
+
query: {
|
|
37
|
+
maxLimit: 100,
|
|
38
|
+
defaultLimit: 10,
|
|
39
|
+
sortable: [{{ sortable }}],
|
|
40
|
+
filterable: [{{ filterable }}],
|
|
41
|
+
searchable: [{{ searchable }}],
|
|
42
|
+
defaultSort: {{ defaultSort }},
|
|
43
|
+
},
|
|
44
|
+
piped: {
|
|
45
|
+
create: {
|
|
46
|
+
enabled: true,
|
|
47
|
+
stages: ['deserialize', 'sanitize', 'mapFields', 'transform', 'validate'],
|
|
48
|
+
validate: { enabled: true, errorStatus: 422 },
|
|
49
|
+
},
|
|
50
|
+
update: {
|
|
51
|
+
enabled: true,
|
|
52
|
+
stages: ['deserialize', 'sanitize', 'mapFields', 'transform', 'validate'],
|
|
53
|
+
validate: { enabled: true, errorStatus: 422 },
|
|
54
|
+
},
|
|
55
|
+
replace: {
|
|
56
|
+
enabled: true,
|
|
57
|
+
stages: ['deserialize', 'sanitize', 'mapFields', 'transform', 'validate'],
|
|
58
|
+
validate: { enabled: true, errorStatus: 422 },
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
})
|
|
62
|
+
export class {{ CtrlName }} {
|
|
63
|
+
@Inject()
|
|
64
|
+
crudService: {{ ServiceName }};
|
|
65
|
+
}
|
package/templates/dto-index.njk
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from './create.dto';
|
|
2
|
-
export * from './update.dto';
|
|
3
|
-
export * from './replace.dto';
|
|
4
|
-
export * from './query.dto';
|
|
1
|
+
export * from './create.dto';
|
|
2
|
+
export * from './update.dto';
|
|
3
|
+
export * from './replace.dto';
|
|
4
|
+
export * from './query.dto';
|
package/templates/dto-query.njk
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { ApiPropertyOptional } from '@midwayjs/swagger';
|
|
2
|
-
import { Rule } from '@midwayjs/validation';
|
|
3
|
-
import * as Joi from 'joi';
|
|
4
|
-
import { CrudBaseQueryDto } from '../../../../framework/dto/base.query.dto';
|
|
5
|
-
|
|
6
|
-
export class {{ QueryName }} extends CrudBaseQueryDto {
|
|
7
|
-
{% for f in filterable -%}
|
|
8
|
-
@ApiPropertyOptional({
|
|
9
|
-
type: {{ f.swagType | json }},
|
|
10
|
-
{% if f.len %} maxLength: {{ f.len }},
|
|
11
|
-
{% endif %} description: {{ (f.comment or f.camel) | json }},
|
|
12
|
-
})
|
|
13
|
-
@Rule({{ f.joiRule }}.optional())
|
|
14
|
-
{{ f.camel }}?: {{ f.jsType }};
|
|
15
|
-
|
|
16
|
-
{% endfor -%}
|
|
17
|
-
}
|
|
1
|
+
import { ApiPropertyOptional } from '@midwayjs/swagger';
|
|
2
|
+
import { Rule } from '@midwayjs/validation';
|
|
3
|
+
import * as Joi from 'joi';
|
|
4
|
+
import { CrudBaseQueryDto } from '../../../../framework/dto/base.query.dto';
|
|
5
|
+
|
|
6
|
+
export class {{ QueryName }} extends CrudBaseQueryDto {
|
|
7
|
+
{% for f in filterable -%}
|
|
8
|
+
@ApiPropertyOptional({
|
|
9
|
+
type: {{ f.swagType | json }},
|
|
10
|
+
{% if f.len %} maxLength: {{ f.len }},
|
|
11
|
+
{% endif %} description: {{ (f.comment or f.camel) | json }},
|
|
12
|
+
})
|
|
13
|
+
@Rule({{ f.joiRule }}.optional())
|
|
14
|
+
{{ f.camel }}?: {{ f.jsType }};
|
|
15
|
+
|
|
16
|
+
{% endfor -%}
|
|
17
|
+
}
|
package/templates/entity.njk
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
// {{ orm }} Entity 模板占位(TypeORM 是当前唯一完整生成的 ORM)
|
|
3
3
|
export class {{ Pascal }} {}
|
|
4
4
|
{%- else -%}
|
|
5
|
-
|
|
5
|
+
{% set hasAutoPk = pkInfos | selectattr('auto') | list | length > 0 -%}
|
|
6
|
+
{% set hasNonAutoPk = pkInfos | rejectattr('auto') | list | length > 0 -%}
|
|
7
|
+
import { Entity, Column{% if hasPk and hasAutoPk %}, PrimaryGeneratedColumn{% endif %}{% if hasPk and hasNonAutoPk %}, PrimaryColumn{% endif %}{% if idxCount %}, Index{% endif %} } from 'typeorm';
|
|
6
8
|
import { Expose{% if hasDateField %}, Transform{% endif %} } from 'class-transformer';
|
|
7
9
|
import { ApiProperty, ApiPropertyOptional } from '@midwayjs/swagger';
|
|
8
10
|
import { Rule } from '@midwayjs/validation';
|
|
@@ -13,21 +15,29 @@ import { BaseEntity } from '../../../framework/entity/base.entity';
|
|
|
13
15
|
comment: {{ (tableName + ' 表') | json }},
|
|
14
16
|
})
|
|
15
17
|
export class {{ Pascal }} extends BaseEntity {
|
|
16
|
-
{%
|
|
18
|
+
{% for pk in pkInfos -%}
|
|
19
|
+
{% if pk.auto -%}
|
|
17
20
|
@PrimaryGeneratedColumn({
|
|
18
|
-
type: {{
|
|
19
|
-
name: {{
|
|
20
|
-
comment: {{ (
|
|
21
|
+
type: {{ pk.type | json }},
|
|
22
|
+
name: {{ pk.name | json }},
|
|
23
|
+
comment: {{ (pk.comment or '主键') | json }},
|
|
21
24
|
})
|
|
25
|
+
{% else -%}
|
|
26
|
+
@PrimaryColumn({
|
|
27
|
+
type: {{ pk.type | json }},
|
|
28
|
+
name: {{ pk.name | json }},
|
|
29
|
+
comment: {{ (pk.comment or '主键') | json }},
|
|
30
|
+
})
|
|
31
|
+
{% endif -%}
|
|
22
32
|
@ApiProperty({
|
|
23
33
|
type: 'integer',
|
|
24
|
-
description: {{ (
|
|
34
|
+
description: {{ (pk.comment or '主键ID') | json }},
|
|
25
35
|
})
|
|
26
36
|
@Expose()
|
|
27
|
-
@Rule(Joi.number().integer().label({{ (
|
|
28
|
-
{{
|
|
37
|
+
@Rule(Joi.number().integer().label({{ (pk.comment or '主键ID') | json }}).required())
|
|
38
|
+
{{ pk.camel }}: number;
|
|
29
39
|
|
|
30
|
-
{%
|
|
40
|
+
{% endfor -%}
|
|
31
41
|
{% for f in fields -%}
|
|
32
42
|
{% if f.idx -%} @Index()
|
|
33
43
|
{% endif -%} @Column({
|
package/templates/service.njk
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
{% if ormInfo.orm === 'typeorm' -%}
|
|
2
|
-
import { Provide, Scope, ScopeEnum } from '@midwayjs/core';
|
|
3
|
-
import { InjectEntityModel } from '@midwayjs/typeorm';
|
|
4
|
-
import { Repository } from 'typeorm';
|
|
5
|
-
import {
|
|
6
|
-
import { {{ Pascal }} } from '../entity/{{ Camel }}.entity';
|
|
7
|
-
|
|
8
|
-
@Provide()
|
|
9
|
-
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
|
10
|
-
export class {{ ServiceName }} extends
|
|
11
|
-
@InjectEntityModel({{ Pascal }})
|
|
12
|
-
repo: Repository<{{ Pascal }}>;
|
|
13
|
-
}
|
|
14
|
-
{%- else -%}
|
|
15
|
-
// {{ ormInfo.orm }} Service 模板(请按项目注入方式调整)
|
|
16
|
-
import { Provide } from '@midwayjs/core';
|
|
17
|
-
|
|
18
|
-
@Provide()
|
|
19
|
-
export class {{ ServiceName }} {}
|
|
20
|
-
{%- endif %}
|
|
1
|
+
{% if ormInfo.orm === 'typeorm' -%}
|
|
2
|
+
import { Provide, Scope, ScopeEnum } from '@midwayjs/core';
|
|
3
|
+
import { InjectEntityModel } from '@midwayjs/typeorm';
|
|
4
|
+
import { Repository } from 'typeorm';
|
|
5
|
+
import { BaseTypeOrmCrudService } from '@shys/core';
|
|
6
|
+
import { {{ Pascal }} } from '../entity/{{ Camel }}.entity';
|
|
7
|
+
|
|
8
|
+
@Provide()
|
|
9
|
+
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
|
10
|
+
export class {{ ServiceName }} extends BaseTypeOrmCrudService<{{ Pascal }}> {
|
|
11
|
+
@InjectEntityModel({{ Pascal }})
|
|
12
|
+
repo: Repository<{{ Pascal }}>;
|
|
13
|
+
}
|
|
14
|
+
{%- else -%}
|
|
15
|
+
// {{ ormInfo.orm }} Service 模板(请按项目注入方式调整)
|
|
16
|
+
import { Provide } from '@midwayjs/core';
|
|
17
|
+
|
|
18
|
+
@Provide()
|
|
19
|
+
export class {{ ServiceName }} {}
|
|
20
|
+
{%- endif %}
|