@shys/crud 1.0.1-beta.0

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.
@@ -0,0 +1,322 @@
1
+ import { resolve } from 'node:path';
2
+ import { toCamelCase, toPascalCase, toPluralKebab } from './utils.js';
3
+ import { createRenderer } from './renderer.js';
4
+ const BASE_FIELD_NAMES = ['createTime', 'updateTime', 'deleteTime'];
5
+ const JSTypeMap = {
6
+ int: 'number', integer: 'number', bigint: 'number', smallint: 'number', tinyint: 'number', mediumint: 'number',
7
+ decimal: 'number', numeric: 'number', float: 'number', double: 'number', real: 'number',
8
+ char: 'string', varchar: 'string', text: 'string', tinytext: 'string', mediumtext: 'string', longtext: 'string',
9
+ enum: 'string', set: 'string', json: 'any',
10
+ date: 'Date', datetime: 'Date', timestamp: 'Date', time: 'Date', year: 'number',
11
+ binary: 'Buffer', varbinary: 'Buffer', blob: 'Buffer',
12
+ bool: 'boolean', boolean: 'boolean', bit: 'boolean',
13
+ };
14
+ const NO_LENGTH_ORM_TYPES = /^(text|tinytext|mediumtext|longtext|blob|tinyblob|mediumblob|longblob|json)$/i;
15
+ function normalizeOrmType(type) {
16
+ return String(type).toLowerCase().replace(/\(\d+.*?\)/, '').trim() || 'varchar';
17
+ }
18
+ function fieldSupportsLength(f) {
19
+ return !NO_LENGTH_ORM_TYPES.test(normalizeOrmType(f.type));
20
+ }
21
+ function jsTypeOf(field) {
22
+ const base = JSTypeMap[field.type] || 'string';
23
+ if (field.nullable)
24
+ return `${base} | null`;
25
+ return base;
26
+ }
27
+ function createDtoTypeOf(field) {
28
+ const base = JSTypeMap[field.type] || 'string';
29
+ return `${base}${field.nullable ? ' | null' : ''}`;
30
+ }
31
+ function joiSwagType(f) {
32
+ const t = f.type;
33
+ if (t === 'int' || t === 'bigint' || t === 'smallint' || t === 'tinyint' || t === 'mediumint' || t === 'integer')
34
+ return `'integer'`;
35
+ if (t === 'decimal' || t === 'numeric' || t === 'float' || t === 'double' || t === 'real' || t === 'number')
36
+ return `'number'`;
37
+ if (t === 'datetime' || t === 'timestamp' || t === 'date')
38
+ return `'string'`;
39
+ if (t === 'bool' || t === 'boolean')
40
+ return `'boolean'`;
41
+ return `'string'`;
42
+ }
43
+ function joiRuleOf(field, opts = {}) {
44
+ const { required = false, allowNull = false } = opts;
45
+ const t = field.type;
46
+ let j;
47
+ switch (t) {
48
+ case 'int':
49
+ case 'integer':
50
+ case 'bigint':
51
+ case 'smallint':
52
+ case 'tinyint':
53
+ case 'mediumint':
54
+ j = 'Joi.number().integer()';
55
+ break;
56
+ case 'decimal':
57
+ case 'numeric':
58
+ case 'float':
59
+ case 'double':
60
+ case 'real':
61
+ j = 'Joi.number()';
62
+ break;
63
+ case 'date':
64
+ case 'datetime':
65
+ case 'timestamp':
66
+ j = 'Joi.date()';
67
+ break;
68
+ case 'bool':
69
+ case 'boolean':
70
+ j = 'Joi.boolean()';
71
+ break;
72
+ default:
73
+ j = 'Joi.string()' + (field.len ? `.max(${field.len})` : '');
74
+ }
75
+ if (allowNull)
76
+ j += '.allow(null)';
77
+ if (required)
78
+ j += '.required()';
79
+ return j;
80
+ }
81
+ function zodRuleOf(field) {
82
+ const t = field.type;
83
+ let zodBase;
84
+ if (/int|bigint|smallint|tinyint|mediumint|integer/.test(t)) {
85
+ zodBase = 'z.number().int()';
86
+ }
87
+ else if (/decimal|numeric|float|double|real/.test(t)) {
88
+ zodBase = 'z.number()';
89
+ }
90
+ else if (/date|datetime|timestamp/.test(t)) {
91
+ zodBase = 'z.date()';
92
+ }
93
+ else if (/bool|boolean/.test(t)) {
94
+ zodBase = 'z.boolean()';
95
+ }
96
+ else {
97
+ zodBase = `z.string()${field.len ? `.max(${field.len})` : ''}`;
98
+ }
99
+ return `${zodBase}.describe(${JSON.stringify(field.comment || field.camel)})`;
100
+ }
101
+ function enhanceField(f, extra = {}) {
102
+ return {
103
+ ...f,
104
+ swagType: joiSwagType(f),
105
+ jsType: jsTypeOf(f),
106
+ createDtoType: createDtoTypeOf(f),
107
+ joiRule: joiRuleOf(f, { required: false, allowNull: f.nullable }),
108
+ joiRuleRequired: joiRuleOf(f, { required: true, allowNull: f.nullable }),
109
+ zodRule: zodRuleOf(f),
110
+ ormType: normalizeOrmType(f.type),
111
+ supportsLength: fieldSupportsLength(f),
112
+ isDate: /datetime|date|timestamp/i.test(f.type),
113
+ isSensitive: /password|passwd|salt|token|secret|private_key/i.test(f.name + f.camel),
114
+ voType: /datetime|date|timestamp/i.test(f.type) ? 'string' : (JSTypeMap[f.type] || 'string'),
115
+ idx: !!extra.idx,
116
+ };
117
+ }
118
+ export function buildFiles(params) {
119
+ const { moduleName, tableName, baseSrcPath, ormInfo, fields, outputPath, templatesPath, renderer: customRenderer, onlyEntity } = params;
120
+ const renderer = customRenderer || createRenderer({ customTemplatesPath: templatesPath });
121
+ const Camel = toCamelCase(tableName);
122
+ const Pascal = toPascalCase(tableName);
123
+ const CreateName = `Create${Pascal}Dto`;
124
+ const UpdateName = `Update${Pascal}Dto`;
125
+ const ReplaceName = `Replace${Pascal}Dto`;
126
+ const QueryName = `Query${Pascal}Dto`;
127
+ const VOName = `${Pascal}VO`;
128
+ const ListVOName = `${Pascal}ListVO`;
129
+ const ServiceName = `${Pascal}Service`;
130
+ const CtrlName = `${Pascal}Controller`;
131
+ const pluralKebab = toPluralKebab(tableName);
132
+ const tagName = `${Pascal}管理`;
133
+ const desc = `${tableName} 表增删改查接口`;
134
+ const modRoot = resolve(outputPath || baseSrcPath, 'modules', moduleName);
135
+ const resultFiles = [];
136
+ const originalPkInfo = fields.find((f) => f.pk);
137
+ const hasPk = !!originalPkInfo;
138
+ const entityFields = fields.filter((f) => {
139
+ if (BASE_FIELD_NAMES.includes(f.camel))
140
+ return false;
141
+ if (f.pk)
142
+ return false;
143
+ return true;
144
+ });
145
+ const idxFields = entityFields.filter((f) => !f.pk && (String(f.name).toUpperCase() === 'COUNTRYCODE' || /_id$/.test(f.name)));
146
+ const hasDateField = entityFields.some((f) => /datetime|date|timestamp/i.test(f.type));
147
+ const enhancedEntityFields = entityFields.map((f) => enhanceField(f, { idx: idxFields.some((i) => i.name === f.name) }));
148
+ const enhancedPkInfo = originalPkInfo ? enhanceField(originalPkInfo) : null;
149
+ // Entity
150
+ resultFiles.push({
151
+ path: resolve(modRoot, `entity/${Camel}.entity.ts`),
152
+ content: renderer.render('entity', {
153
+ orm: ormInfo.orm,
154
+ ormSuffix: ormInfo.ormSuffix,
155
+ fields: enhancedEntityFields,
156
+ tableName,
157
+ Pascal,
158
+ Camel,
159
+ pkInfo: enhancedPkInfo,
160
+ hasPk,
161
+ hasDateField,
162
+ idxCount: idxFields.length,
163
+ }),
164
+ });
165
+ if (onlyEntity) {
166
+ return {
167
+ files: resultFiles,
168
+ Pascal,
169
+ pluralKebab,
170
+ Camel,
171
+ sortable: [],
172
+ filterable: [],
173
+ searchable: [],
174
+ };
175
+ }
176
+ const createFields = entityFields.filter((f) => !(f.pk && f.auto));
177
+ const writable = createFields.filter((f) => !/ctime|mtime|created_at|updated_at|create_time|update_time/i.test(f.name));
178
+ const isSensitive = (f) => /password|passwd|salt|token|secret|private_key/i.test(f.name + f.camel);
179
+ const pkCamel = originalPkInfo?.camel || '';
180
+ const sortableBase = entityFields.filter((f) => !isSensitive(f)).map((f) => f.camel);
181
+ const sortable = pkCamel && !sortableBase.includes(pkCamel)
182
+ ? [pkCamel, ...sortableBase]
183
+ : sortableBase;
184
+ const filterableBase = entityFields.filter((f) => !isSensitive(f));
185
+ const filterableArr = pkCamel && !filterableBase.some((f) => f.camel === pkCamel)
186
+ ? [originalPkInfo, ...filterableBase]
187
+ : filterableBase;
188
+ const filterable = filterableArr.map((f) => f.camel);
189
+ const searchable = filterableArr
190
+ .filter((f) => /char|varchar|text/i.test(f.type))
191
+ .map((f) => f.camel);
192
+ const enhancedCreateFields = createFields.map((f) => enhanceField(f));
193
+ const enhancedWritable = writable.map((f) => enhanceField(f));
194
+ const enhancedFilterable = filterableArr.map((f) => enhanceField(f));
195
+ // Create DTO
196
+ resultFiles.push({
197
+ path: resolve(modRoot, `dto/${Camel}/create.dto.ts`),
198
+ content: renderer.render('dto-create', {
199
+ CreateName,
200
+ Pascal,
201
+ createFields: enhancedCreateFields,
202
+ }),
203
+ });
204
+ // Update DTO
205
+ const updatePicks = enhancedWritable.map((f) => JSON.stringify(f.camel)).join(',\n ');
206
+ const updateTypeArgs = enhancedWritable.map((f) => `'${f.camel}'`).join(' | ');
207
+ resultFiles.push({
208
+ path: resolve(modRoot, `dto/${Camel}/update.dto.ts`),
209
+ content: renderer.render('dto-update', {
210
+ UpdateName,
211
+ CreateName,
212
+ writable: enhancedWritable,
213
+ picks: updatePicks,
214
+ typeArgs: updateTypeArgs || 'never',
215
+ }),
216
+ });
217
+ // Replace DTO
218
+ const replacePicks = enhancedWritable.map((f) => JSON.stringify(f.camel)).join(',\n ');
219
+ resultFiles.push({
220
+ path: resolve(modRoot, `dto/${Camel}/replace.dto.ts`),
221
+ content: renderer.render('dto-replace', {
222
+ ReplaceName,
223
+ CreateName,
224
+ writable: enhancedWritable,
225
+ picks: replacePicks,
226
+ }),
227
+ });
228
+ // Query DTO
229
+ const queryPicks = enhancedFilterable.map((f) => JSON.stringify(f.camel)).join(',\n ');
230
+ const queryTypeArgs = enhancedFilterable.map((f) => `'${f.camel}'`).join(' | ');
231
+ const sortEx = filterable[0] ? `${filterable[0]}:ASC,id:DESC` : 'id:DESC';
232
+ const filterEx = filterableArr
233
+ .slice(0, 2)
234
+ .map((f) => {
235
+ const isStr = /char|varchar|text/i.test(f.type);
236
+ return isStr ? `${f.camel}:like:a` : `${f.camel}:gte:10`;
237
+ })
238
+ .join(',');
239
+ const searchFields = searchable.join('/') || '无';
240
+ resultFiles.push({
241
+ path: resolve(modRoot, `dto/${Camel}/query.dto.ts`),
242
+ content: renderer.render('dto-query', {
243
+ QueryName,
244
+ CreateName,
245
+ filterable: enhancedFilterable,
246
+ picks: queryPicks,
247
+ typeArgs: queryTypeArgs || 'never',
248
+ sortDescription: '排序字段。标准格式:field:ASC 或 field:DESC;多字段用英文逗号分隔,或多次传 sort。示例:id:DESC、' + sortEx,
249
+ filterExample: filterEx || 'id:gte:1',
250
+ searchDescription: '搜索关键字,对可搜索字段(' + searchFields + ')模糊匹配',
251
+ }),
252
+ });
253
+ // DTO index
254
+ resultFiles.push({
255
+ path: resolve(modRoot, `dto/${Camel}/index.ts`),
256
+ content: renderer.render('dto-index', {}),
257
+ });
258
+ // Single VO
259
+ const allVoFields = [...(originalPkInfo ? [originalPkInfo] : []), ...entityFields].map((f) => enhanceField(f));
260
+ const voHasTransform = allVoFields.some((f) => f.isDate || f.isSensitive);
261
+ resultFiles.push({
262
+ path: resolve(modRoot, `vo/${Camel}/${Camel}.vo.ts`),
263
+ content: renderer.render('vo-single', {
264
+ VOName,
265
+ fields: allVoFields,
266
+ hasTransform: voHasTransform,
267
+ }),
268
+ });
269
+ // List VO
270
+ resultFiles.push({
271
+ path: resolve(modRoot, `vo/${Camel}/${Camel}List.vo.ts`),
272
+ content: renderer.render('vo-list', {
273
+ ListVOName,
274
+ VOName,
275
+ Camel,
276
+ }),
277
+ });
278
+ // VO index
279
+ resultFiles.push({
280
+ path: resolve(modRoot, `vo/${Camel}/index.ts`),
281
+ content: renderer.render('vo-index', { Camel }),
282
+ });
283
+ // Service
284
+ resultFiles.push({
285
+ path: resolve(modRoot, `service/${Camel}.service.ts`),
286
+ content: renderer.render('service', {
287
+ ServiceName,
288
+ Pascal,
289
+ Camel,
290
+ ormInfo,
291
+ }),
292
+ });
293
+ // Controller
294
+ const sArr = (arr) => arr.map((x) => JSON.stringify(x)).join(', ');
295
+ const idField = pkCamel || 'id';
296
+ const defaultSort = searchable && searchable.length
297
+ ? `[{ field: ${JSON.stringify(sortable[0] || idField)}, order: 'DESC' }]`
298
+ : `[{ field: 'id', order: 'DESC' }]`;
299
+ resultFiles.push({
300
+ path: resolve(modRoot, `controller/${Camel}.controller.ts`),
301
+ content: renderer.render('controller', {
302
+ CtrlName, Pascal, ServiceName,
303
+ CreateName, UpdateName, ReplaceName, QueryName,
304
+ VOName, ListVOName,
305
+ Camel, pluralKebab, tagName, desc,
306
+ sortable: sArr(sortable),
307
+ filterable: sArr(filterable),
308
+ searchable: sArr(searchable),
309
+ pkCamel,
310
+ idField,
311
+ defaultSort,
312
+ }),
313
+ });
314
+ // Common VO
315
+ const commonVO = resolve(outputPath || baseSrcPath, 'framework/vo/crudPage.vo.ts');
316
+ resultFiles.push({
317
+ path: commonVO,
318
+ content: renderer.render('crud-page-vo', {}),
319
+ createOnly: true,
320
+ });
321
+ return { files: resultFiles, Pascal, pluralKebab, Camel, sortable, filterable, searchable };
322
+ }
@@ -0,0 +1,8 @@
1
+ export { loadConfig, mergeConfigs } from './config.js';
2
+ export { detectOrm } from './orm.js';
3
+ export { getDbConfigFromProject, resolveDefaultDbName, getTableFieldsFromDb, templateFieldsFor, } from './db.js';
4
+ export { buildFiles } from './generator.js';
5
+ export { TemplateRenderer, createRenderer } from './renderer.js';
6
+ export type { TemplateName, TemplateRendererOptions } from './renderer.js';
7
+ export { runCli } from './cli.js';
8
+ export * from './types.js';
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export { loadConfig, mergeConfigs } from './config.js';
2
+ export { detectOrm } from './orm.js';
3
+ export { getDbConfigFromProject, resolveDefaultDbName, getTableFieldsFromDb, templateFieldsFor, } from './db.js';
4
+ export { buildFiles } from './generator.js';
5
+ export { TemplateRenderer, createRenderer } from './renderer.js';
6
+ export { runCli } from './cli.js';
7
+ export * from './types.js';
package/dist/orm.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import type { OrmInfo } from './types.js';
2
+ export declare function detectOrm(baseSrcPath: string): OrmInfo;
package/dist/orm.js ADDED
@@ -0,0 +1,57 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ export function detectOrm(baseSrcPath) {
4
+ const pkgFile = resolve(baseSrcPath, '../package.json');
5
+ const deps = {};
6
+ if (existsSync(pkgFile)) {
7
+ const raw = readFileSync(pkgFile, 'utf-8').replace(/^\uFEFF/, '');
8
+ const p = JSON.parse(raw);
9
+ for (const k of Object.keys(p.dependencies || {}))
10
+ deps[k] = p.dependencies[k];
11
+ for (const k of Object.keys(p.devDependencies || {}))
12
+ deps[k] = p.devDependencies[k];
13
+ }
14
+ if (deps['@midwayjs/typeorm'] || deps.typeorm) {
15
+ return {
16
+ orm: 'typeorm',
17
+ ormSuffix: 'entity',
18
+ serviceParent: 'TypeOrmCrudService',
19
+ importCrudOrm: `from '@midwayjs/crud/typeorm'`,
20
+ injectEntity: '@InjectEntityModel',
21
+ };
22
+ }
23
+ if (deps['@midwayjs/sequelize'] || deps.sequelize) {
24
+ return {
25
+ orm: 'sequelize',
26
+ ormSuffix: 'model',
27
+ serviceParent: 'SequelizeCrudService',
28
+ importCrudOrm: `from '@midwayjs/crud/sequelize'`,
29
+ injectEntity: '@InjectModel',
30
+ };
31
+ }
32
+ if (deps['@midwayjs/mikro'] || deps['@mikro-orm/core']) {
33
+ return {
34
+ orm: 'mikro',
35
+ ormSuffix: 'entity',
36
+ serviceParent: 'MikroCrudService',
37
+ importCrudOrm: `from '@midwayjs/crud/mikro'`,
38
+ injectEntity: '@InjectRepository',
39
+ };
40
+ }
41
+ if (deps['@midwayjs/mongoose'] || deps.mongoose) {
42
+ return {
43
+ orm: 'mongoose',
44
+ ormSuffix: 'schema',
45
+ serviceParent: 'MongooseCrudService',
46
+ importCrudOrm: `from '@midwayjs/crud/mongoose'`,
47
+ injectEntity: '@InjectModel',
48
+ };
49
+ }
50
+ return {
51
+ orm: 'typeorm',
52
+ ormSuffix: 'entity',
53
+ serviceParent: 'TypeOrmCrudService',
54
+ importCrudOrm: `from '@midwayjs/crud/typeorm'`,
55
+ injectEntity: '@InjectEntityModel',
56
+ };
57
+ }
@@ -0,0 +1,14 @@
1
+ export type TemplateName = 'entity' | 'dto-create' | 'dto-update' | 'dto-replace' | 'dto-query' | 'dto-index' | 'vo-single' | 'vo-list' | 'vo-index' | 'service' | 'controller' | 'crud-page-vo';
2
+ export interface TemplateRendererOptions {
3
+ customTemplatesPath?: string;
4
+ }
5
+ export declare class TemplateRenderer {
6
+ private env;
7
+ private customTemplatesPath?;
8
+ constructor(options?: TemplateRendererOptions);
9
+ render(templateName: TemplateName, context: Record<string, any>): string;
10
+ hasCustomTemplate(templateName: TemplateName): boolean;
11
+ getDefaultTemplatesDir(): string;
12
+ getCustomTemplatesDir(): string | undefined;
13
+ }
14
+ export declare function createRenderer(options?: TemplateRendererOptions): TemplateRenderer;
@@ -0,0 +1,62 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { resolve, dirname } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import nunjucks from 'nunjucks';
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = dirname(__filename);
7
+ const DEFAULT_TEMPLATES_DIR = resolve(__dirname, '..', 'templates');
8
+ const TEMPLATE_FILES = {
9
+ entity: 'entity.njk',
10
+ 'dto-create': 'dto-create.njk',
11
+ 'dto-update': 'dto-update.njk',
12
+ 'dto-replace': 'dto-replace.njk',
13
+ 'dto-query': 'dto-query.njk',
14
+ 'dto-index': 'dto-index.njk',
15
+ 'vo-single': 'vo-single.njk',
16
+ 'vo-list': 'vo-list.njk',
17
+ 'vo-index': 'vo-index.njk',
18
+ service: 'service.njk',
19
+ controller: 'controller.njk',
20
+ 'crud-page-vo': 'crud-page-vo.njk',
21
+ };
22
+ export class TemplateRenderer {
23
+ env;
24
+ customTemplatesPath;
25
+ constructor(options = {}) {
26
+ this.customTemplatesPath = options.customTemplatesPath;
27
+ const searchPaths = [];
28
+ if (this.customTemplatesPath && existsSync(this.customTemplatesPath)) {
29
+ searchPaths.push(this.customTemplatesPath);
30
+ }
31
+ searchPaths.push(DEFAULT_TEMPLATES_DIR);
32
+ this.env = new nunjucks.Environment(searchPaths.map((p) => new nunjucks.FileSystemLoader(p)), {
33
+ autoescape: false,
34
+ throwOnUndefined: false,
35
+ trimBlocks: false,
36
+ lstripBlocks: false,
37
+ });
38
+ this.env.addFilter('json', (value) => JSON.stringify(value));
39
+ }
40
+ render(templateName, context) {
41
+ const templateFile = TEMPLATE_FILES[templateName];
42
+ if (!templateFile) {
43
+ throw new Error(`Unknown template: ${templateName}`);
44
+ }
45
+ return this.env.render(templateFile, context);
46
+ }
47
+ hasCustomTemplate(templateName) {
48
+ if (!this.customTemplatesPath)
49
+ return false;
50
+ const templateFile = TEMPLATE_FILES[templateName];
51
+ return existsSync(resolve(this.customTemplatesPath, templateFile));
52
+ }
53
+ getDefaultTemplatesDir() {
54
+ return DEFAULT_TEMPLATES_DIR;
55
+ }
56
+ getCustomTemplatesDir() {
57
+ return this.customTemplatesPath;
58
+ }
59
+ }
60
+ export function createRenderer(options = {}) {
61
+ return new TemplateRenderer(options);
62
+ }
@@ -0,0 +1,70 @@
1
+ import type { FieldInfo, OrmInfo } from './types.js';
2
+ export declare function entityTemplate(params: {
3
+ orm: string;
4
+ ormSuffix: string;
5
+ fields: FieldInfo[];
6
+ tableName: string;
7
+ Pascal: string;
8
+ Camel: string;
9
+ originalPkInfo?: FieldInfo | null;
10
+ hasPk: boolean;
11
+ }): string;
12
+ export declare function createDtoTemplate(params: {
13
+ CreateName: string;
14
+ Pascal: string;
15
+ createFields: FieldInfo[];
16
+ }): string;
17
+ export declare function updateDtoTemplate(params: {
18
+ UpdateName: string;
19
+ CreateName: string;
20
+ writable: FieldInfo[];
21
+ Camel: string;
22
+ Pascal: string;
23
+ }): string;
24
+ export declare function replaceDtoTemplate(params: {
25
+ ReplaceName: string;
26
+ CreateName: string;
27
+ writable: FieldInfo[];
28
+ }): string;
29
+ export declare function queryDtoTemplate(params: {
30
+ QueryName: string;
31
+ CreateName: string;
32
+ filterable: FieldInfo[];
33
+ }): string;
34
+ export declare function singleVOTemplate(params: {
35
+ VOName: string;
36
+ Pascal: string;
37
+ Camel: string;
38
+ fields: FieldInfo[];
39
+ }): string;
40
+ export declare function listVOTemplate(params: {
41
+ ListVOName: string;
42
+ VOName: string;
43
+ Camel: string;
44
+ }): string;
45
+ export declare function crudPageCommonTemplate(): string;
46
+ export declare function serviceTemplate(params: {
47
+ ServiceName: string;
48
+ Pascal: string;
49
+ Camel: string;
50
+ ormInfo: OrmInfo;
51
+ }): string;
52
+ export declare function controllerTemplate(params: {
53
+ CtrlName: string;
54
+ Pascal: string;
55
+ ServiceName: string;
56
+ CreateName: string;
57
+ UpdateName: string;
58
+ ReplaceName: string;
59
+ QueryName: string;
60
+ VOName: string;
61
+ ListVOName: string;
62
+ Camel: string;
63
+ pluralKebab: string;
64
+ tagName: string;
65
+ desc: string;
66
+ sortable: string[];
67
+ filterable: string[];
68
+ searchable: string[];
69
+ pkCamel: string;
70
+ }): string;