@gadmin2n/prisma-nest-generator 0.0.20

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.
Files changed (53) hide show
  1. package/LICENSE +177 -0
  2. package/README.md +2 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +4 -0
  5. package/dist/generator/annotations.d.ts +14 -0
  6. package/dist/generator/annotations.js +28 -0
  7. package/dist/generator/compute-model-params/compute-connect-dto-params.d.ts +7 -0
  8. package/dist/generator/compute-model-params/compute-connect-dto-params.js +14 -0
  9. package/dist/generator/compute-model-params/compute-create-dto-params.d.ts +9 -0
  10. package/dist/generator/compute-model-params/compute-create-dto-params.js +80 -0
  11. package/dist/generator/compute-model-params/compute-entity-params.d.ts +9 -0
  12. package/dist/generator/compute-model-params/compute-entity-params.js +74 -0
  13. package/dist/generator/compute-model-params/compute-update-dto-params.d.ts +9 -0
  14. package/dist/generator/compute-model-params/compute-update-dto-params.js +72 -0
  15. package/dist/generator/compute-model-params/index.d.ts +9 -0
  16. package/dist/generator/compute-model-params/index.js +22 -0
  17. package/dist/generator/field-classifiers.d.ts +14 -0
  18. package/dist/generator/field-classifiers.js +51 -0
  19. package/dist/generator/generate-connect-dto.d.ts +7 -0
  20. package/dist/generator/generate-connect-dto.js +14 -0
  21. package/dist/generator/generate-controller-spec.d.ts +8 -0
  22. package/dist/generator/generate-controller-spec.js +28 -0
  23. package/dist/generator/generate-controller.d.ts +8 -0
  24. package/dist/generator/generate-controller.js +207 -0
  25. package/dist/generator/generate-create-dto.d.ts +8 -0
  26. package/dist/generator/generate-create-dto.js +15 -0
  27. package/dist/generator/generate-entity.d.ts +7 -0
  28. package/dist/generator/generate-entity.js +16 -0
  29. package/dist/generator/generate-form-validator-class.d.ts +8 -0
  30. package/dist/generator/generate-form-validator-class.js +42 -0
  31. package/dist/generator/generate-module.d.ts +8 -0
  32. package/dist/generator/generate-module.js +18 -0
  33. package/dist/generator/generate-modules-index.d.ts +8 -0
  34. package/dist/generator/generate-modules-index.js +13 -0
  35. package/dist/generator/generate-service-spec.d.ts +8 -0
  36. package/dist/generator/generate-service-spec.js +406 -0
  37. package/dist/generator/generate-service.d.ts +8 -0
  38. package/dist/generator/generate-service.js +91 -0
  39. package/dist/generator/generate-types-dto.d.ts +7 -0
  40. package/dist/generator/generate-types-dto.js +160 -0
  41. package/dist/generator/generate-update-dto.d.ts +8 -0
  42. package/dist/generator/generate-update-dto.js +12 -0
  43. package/dist/generator/helpers.d.ts +32 -0
  44. package/dist/generator/helpers.js +167 -0
  45. package/dist/generator/index.d.ts +17 -0
  46. package/dist/generator/index.js +187 -0
  47. package/dist/generator/template-helpers.d.ts +56 -0
  48. package/dist/generator/template-helpers.js +138 -0
  49. package/dist/generator/types.d.ts +56 -0
  50. package/dist/generator/types.js +2 -0
  51. package/dist/index.d.ts +3 -0
  52. package/dist/index.js +77 -0
  53. package/package.json +71 -0
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateControllerSpec = void 0;
4
+ const case_1 = require("case");
5
+ const generateControllerSpec = ({ model, templateHelpers: t, }) => `
6
+ import { Test, TestingModule } from '@nestjs/testing';
7
+ import { ${model.name}Controller } from './${(0, case_1.camel)(model.name)}.controller';
8
+ import { ${model.name}Service } from './${(0, case_1.camel)(model.name)}.service';
9
+
10
+ describe('${model.name}Controller', () => {
11
+ let controller: ${model.name}Controller;
12
+
13
+ beforeEach(async () => {
14
+ const module: TestingModule = await Test.createTestingModule({
15
+ controllers: [${model.name}Controller],
16
+ providers: [${model.name}Service],
17
+ }).compile();
18
+
19
+ controller = module.get<${model.name}Controller>(${model.name}Controller);
20
+ });
21
+
22
+ it('should be defined', () => {
23
+ expect(controller).toBeDefined();
24
+ });
25
+ });
26
+
27
+ `;
28
+ exports.generateControllerSpec = generateControllerSpec;
@@ -0,0 +1,8 @@
1
+ import type { TemplateHelpers } from './template-helpers';
2
+ import { DMMF } from '@prisma/generator-helper';
3
+ interface GenerateControllerParam {
4
+ model: DMMF.Model;
5
+ templateHelpers: TemplateHelpers;
6
+ }
7
+ export declare const generateController: ({ model, templateHelpers: t, }: GenerateControllerParam) => string;
8
+ export {};
@@ -0,0 +1,207 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateController = void 0;
4
+ const case_1 = require("case");
5
+ const generateController = ({ model, templateHelpers: t, }) => {
6
+ const EntityName = t.entityName(model.name);
7
+ const instanceName = (0, case_1.camel)(model.name);
8
+ const CreateDto = t.createDtoName(model.name);
9
+ const UpdateDto = t.updateDtoName(model.name);
10
+ const ModelFindManyArgs = `${model.name}FindManyArgs`;
11
+ const ModelWhereSelect = `${model.name}WhereSelect`;
12
+ return `
13
+ import {
14
+ Inject,
15
+ Controller,
16
+ Get,
17
+ Post,
18
+ Req,
19
+ Body,
20
+ Patch,
21
+ Param,
22
+ Delete,
23
+ UploadedFile,
24
+ UseGuards,
25
+ UseInterceptors,
26
+ ParseIntPipe,
27
+ NotFoundException,
28
+ } from '@nestjs/common';
29
+ import {
30
+ ApiCreatedResponse,
31
+ ApiOkResponse,
32
+ ApiNotFoundResponse,
33
+ ApiTags,
34
+ } from '@nestjs/swagger';
35
+ import {
36
+ PageOptionsDto,
37
+ ApiPaginatedResponse,
38
+ diskStorage,
39
+ PageDto,
40
+ PageMetaDto,
41
+ ACGuard,
42
+ ACAttrFilter,
43
+ pick,
44
+ UserType,
45
+ } from '@gadmin2/nest-common';
46
+ import { UseRoles } from 'nest-access-control';
47
+ import { ${CreateDto} } from '../../generated/${instanceName}/dto/create-${instanceName}.dto';
48
+ import { ${UpdateDto} } from '../../generated/${instanceName}/dto/update-${instanceName}.dto';
49
+ import { ${EntityName} } from '../../generated/${instanceName}/entities/${instanceName}.entity';
50
+ import { ${ModelWhereSelect}, ${ModelFindManyArgs}, EffectedCount, UploudResponse } from '../../generated/${instanceName}/dto/${instanceName}-types.dto';
51
+ import { ${model.name}Service } from './${instanceName}.service';
52
+ import { Prisma } from '@prisma/client';
53
+ import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
54
+ import { Logger } from 'winston';
55
+
56
+ import { ConfigService } from '@nestjs/config';
57
+ import { FileInterceptor } from '@nestjs/platform-express';
58
+
59
+ @UseGuards(ACGuard)
60
+ @Controller('${instanceName}')
61
+ @ApiTags('${instanceName}')
62
+ export class ${model.name}Controller {
63
+ constructor(
64
+ private readonly ${instanceName}Service: ${model.name}Service,
65
+ private readonly config: ConfigService,
66
+ @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger,
67
+ ) {}
68
+
69
+ @Post('createOne')
70
+ @UseRoles({
71
+ resource: '${instanceName}',
72
+ action: 'create',
73
+ possession: 'any',
74
+ })
75
+ @ApiCreatedResponse({ type: ${EntityName} })
76
+ async createOne(
77
+ @Body() body: ${CreateDto},
78
+ @ACAttrFilter() acAttrFilter,
79
+ @Req() request: Request & { user: UserType },
80
+ ) {
81
+ ${model.fields.find(f => f.name === "creator") ? "body.creator = request.user.username;" : ""}
82
+ return new ${EntityName}(
83
+ await this.${instanceName}Service.createOne({data: acAttrFilter(body)}),
84
+ );
85
+ }
86
+
87
+ @Post('findMany')
88
+ @UseRoles({
89
+ resource: '${instanceName}',
90
+ action: 'read',
91
+ possession: 'any',
92
+ })
93
+ @ApiPaginatedResponse(${EntityName})
94
+ async findMany(
95
+ @Body() body: ${ModelFindManyArgs},
96
+ @ACAttrFilter() acAttrFilter,
97
+ ): Promise<PageDto<${EntityName}>> {
98
+ const { itemCount, entities } = await this.${instanceName}Service.findMany(body as Prisma.${model.name}FindManyArgs);
99
+ const { skip = 0, take = 10 } = body as Prisma.${model.name}FindManyArgs;
100
+ const pageOptionsDto: PageOptionsDto = { skip, take };
101
+ const pageMetaDto = new PageMetaDto({ itemCount, pageOptionsDto });
102
+
103
+ return new PageDto(
104
+ entities.map((item) => new ${EntityName}(acAttrFilter(item))),
105
+ pageMetaDto,
106
+ );
107
+ }
108
+
109
+ @Post('/findUnique/:id')
110
+ @UseRoles({
111
+ resource: '${instanceName}',
112
+ action: 'read',
113
+ possession: 'any',
114
+ })
115
+ @ApiOkResponse({ type: ${EntityName} })
116
+ @ApiNotFoundResponse({ description: 'Cannot found this record.' })
117
+ async findUnique(
118
+ @Param('id', ParseIntPipe) id: number,
119
+ @Body() body: ${ModelWhereSelect},
120
+ @ACAttrFilter() acAttrFilter
121
+ ) {
122
+ const item = await this.${instanceName}Service.findUnique(id, body);
123
+ if (!item) {
124
+ throw new NotFoundException();
125
+ }
126
+ return new ${EntityName}(acAttrFilter(item));
127
+ }
128
+
129
+ @Patch('updateUnique/:id')
130
+ @UseRoles({
131
+ resource: '${instanceName}',
132
+ action: 'update',
133
+ possession: 'any',
134
+ })
135
+ @ApiOkResponse({ type: ${EntityName} })
136
+ @ApiNotFoundResponse({ description: 'Cannot found this record.' })
137
+ async updateUnique(
138
+ @Param('id', ParseIntPipe) id: number,
139
+ @Body() body: ${UpdateDto},
140
+ @ACAttrFilter() acAttrFilter,
141
+ ) {
142
+ /*
143
+ const origin = (await this.${instanceName}Service.findUnique(id, {
144
+ id: true,
145
+ // 这里需要根据实际情况填写
146
+ })) as ${EntityName} | null;
147
+ if (!origin) {
148
+ throw new NotFoundException();
149
+ }
150
+ // 需要兼容从列表页change_value入口进来的情况,这里进来的是只有少量字段的数据
151
+ const newBody = {
152
+ ...origin,
153
+ ...body,
154
+ };
155
+
156
+ // 其他个性化逻辑
157
+ */
158
+
159
+ const item = await this.${instanceName}Service.updateUnique(
160
+ id,
161
+ acAttrFilter(body),
162
+ );
163
+ return new ${EntityName}(acAttrFilter(item));
164
+ }
165
+
166
+ @Delete('deleteUnique/:id')
167
+ @UseRoles({
168
+ resource: '${instanceName}',
169
+ action: 'delete',
170
+ possession: 'any',
171
+ })
172
+ @ApiOkResponse({ type: EffectedCount })
173
+ @ApiNotFoundResponse({ description: 'Cannot found this record.' })
174
+ async deleteUnique(@Param('id', ParseIntPipe) id: number) {
175
+ const res = await this.${instanceName}Service.deleteUnique(id);
176
+ if (!res.count) {
177
+ throw new NotFoundException();
178
+ }
179
+ return res;
180
+ }
181
+
182
+ @Post('upload')
183
+ @UseRoles({
184
+ resource: '${instanceName}',
185
+ action: 'create',
186
+ possession: 'any',
187
+ })
188
+ @ApiCreatedResponse({ type: UploudResponse })
189
+ @UseInterceptors(FileInterceptor('file'))
190
+ async uploadFile(@UploadedFile() file: Express.Multer.File) {
191
+ const fileName = await diskStorage(
192
+ file,
193
+ this.config.get('media')['rootDir'] + '/${instanceName}/',
194
+ );
195
+
196
+ return {
197
+ ...pick(file, ['mimetype', 'originalname', 'size']),
198
+ url: this.config.get('media')['address'] + '/${instanceName}/' + fileName,
199
+ name: fileName,
200
+ };
201
+ }
202
+
203
+ }
204
+
205
+ `;
206
+ };
207
+ exports.generateController = generateController;
@@ -0,0 +1,8 @@
1
+ import type { TemplateHelpers } from './template-helpers';
2
+ import type { CreateDtoParams } from './types';
3
+ interface GenerateCreateDtoParam extends CreateDtoParams {
4
+ exportRelationModifierClasses: boolean;
5
+ templateHelpers: TemplateHelpers;
6
+ }
7
+ export declare const generateCreateDto: ({ model, fields, imports, extraClasses, apiExtraModels, exportRelationModifierClasses, templateHelpers: t, }: GenerateCreateDtoParam) => string;
8
+ export {};
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateCreateDto = void 0;
4
+ const generateCreateDto = ({ model, fields, imports, extraClasses, apiExtraModels, exportRelationModifierClasses, templateHelpers: t, }) => `
5
+ ${t.importStatements(imports)}
6
+ import {ValidateNested, IsDefined, IsOptional, Equals, NotEquals, IsEmpty, IsNotEmpty, IsIn, IsNotIn, IsBoolean, IsDate, IsString, IsNumber, IsInt, IsArray, IsEnum, IsDivisibleBy, IsPositive, IsNegative, Min, Max, MinDate, MaxDate, IsBooleanString, IsDateString, Contains, NotContains, IsAlpha, IsAlphanumeric, IsDecimal, IsAscii, IsBase32, IsBase64, IsIBAN, IsBIC, IsByteLength, IsCreditCard, IsCurrency, IsEthereumAddress, IsBtcAddress, IsDataURI, IsEmail, IsFQDN, IsFullWidth, IsHalfWidth, IsVariableWidth, IsHexColor, IsRgbColor, IsIdentityCard, IsPassportNumber, IsPostalCode, IsHexadecimal, IsOctal, IsMACAddress, IsIP, IsPort, IsISBN, IsEAN, IsISIN, IsISO8601, IsJSON, IsJWT, IsObject, IsNotEmptyObject, IsLowercase, IsLatLong, IsLatitude, IsLongitude, IsMobilePhone, IsISO31661Alpha2, IsISO31661Alpha3, IsLocale, IsPhoneNumber, IsMongoId, IsMultibyte, IsNumberString, IsSurrogatePair, IsUrl, IsMagnetURI, IsUUID, IsFirebasePushId, IsUppercase, Length, MinLength, MaxLength, Matches, IsMilitaryTime, IsHash, IsMimeType, IsSemVer, IsISSN, IsISRC, IsRFC3339, ArrayContains, ArrayNotContains, ArrayNotEmpty, ArrayMinSize, ArrayMaxSize, ArrayUnique} from 'class-validator';
7
+
8
+ ${t.each(extraClasses, exportRelationModifierClasses ? (content) => `export ${content}` : t.echo, '\n')}
9
+
10
+ /*${t.if(apiExtraModels.length, t.apiExtraModels(apiExtraModels))}*/
11
+ export class ${t.createDtoName(model.name)} {
12
+ ${t.fieldsToDtoProps(fields, true)}
13
+ }
14
+ `;
15
+ exports.generateCreateDto = generateCreateDto;
@@ -0,0 +1,7 @@
1
+ import type { TemplateHelpers } from './template-helpers';
2
+ import type { EntityParams } from './types';
3
+ interface GenerateEntityParam extends EntityParams {
4
+ templateHelpers: TemplateHelpers;
5
+ }
6
+ export declare const generateEntity: ({ model, fields, imports, apiExtraModels, templateHelpers: t, }: GenerateEntityParam) => string;
7
+ export {};
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateEntity = void 0;
4
+ const generateEntity = ({ model, fields, imports, apiExtraModels, templateHelpers: t, }) => `
5
+ ${t.importStatements(imports)}
6
+
7
+ ${t.if(apiExtraModels.length, t.apiExtraModels(apiExtraModels))}
8
+ export class ${t.entityName(model.name)} {
9
+ ${t.fieldsToEntityProps(fields)}
10
+
11
+ constructor(partial: Partial<${t.entityName(model.name)}>) {
12
+ Object.assign(this, partial);
13
+ }
14
+ }
15
+ `;
16
+ exports.generateEntity = generateEntity;
@@ -0,0 +1,8 @@
1
+ import type { TemplateHelpers } from './template-helpers';
2
+ import type { CreateDtoParams } from './types';
3
+ interface GenerateFormValidatorClass extends CreateDtoParams {
4
+ exportRelationModifierClasses: boolean;
5
+ templateHelpers: TemplateHelpers;
6
+ }
7
+ export declare const generateFormValidatorClass: ({ model, fields, templateHelpers: t, }: GenerateFormValidatorClass) => string;
8
+ export {};
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateFormValidatorClass = void 0;
4
+ const field_classifiers_1 = require("./field-classifiers");
5
+ function isCreateAt(field) {
6
+ var _a;
7
+ return field.name === 'createdAt' || (field.hasDefaultValue && ((_a = field.default) === null || _a === void 0 ? void 0 : _a.name) === 'now');
8
+ }
9
+ const generateFormValidatorClass = ({ model, fields, templateHelpers: t, }) => {
10
+ const hasJsonField = model.fields.some((field) => field.kind === 'scalar' && field.type === 'Json');
11
+ return `
12
+ import {ValidateNested, IsDefined, IsOptional, Equals, NotEquals, IsEmpty, IsNotEmpty, IsIn, IsNotIn, IsBoolean, IsDate, IsString, IsNumber, IsInt, IsArray, IsEnum, IsDivisibleBy, IsPositive, IsNegative, Min, Max, MinDate, MaxDate, IsBooleanString, IsDateString, Contains, NotContains, IsAlpha, IsAlphanumeric, IsDecimal, IsAscii, IsBase32, IsBase64, IsIBAN, IsBIC, IsByteLength, IsCreditCard, IsCurrency, IsEthereumAddress, IsBtcAddress, IsDataURI, IsEmail, IsFQDN, IsFullWidth, IsHalfWidth, IsVariableWidth, IsHexColor, IsRgbColor, IsIdentityCard, IsPassportNumber, IsPostalCode, IsHexadecimal, IsOctal, IsMACAddress, IsIP, IsPort, IsISBN, IsEAN, IsISIN, IsISO8601, IsJSON, IsJWT, IsObject, IsNotEmptyObject, IsLowercase, IsLatLong, IsLatitude, IsLongitude, IsMobilePhone, IsISO31661Alpha2, IsISO31661Alpha3, IsLocale, IsPhoneNumber, IsMongoId, IsMultibyte, IsNumberString, IsSurrogatePair, IsUrl, IsMagnetURI, IsUUID, IsFirebasePushId, IsUppercase, Length, MinLength, MaxLength, Matches, IsMilitaryTime, IsHash, IsMimeType, IsSemVer, IsISSN, IsISRC, IsRFC3339, ArrayContains, ArrayNotContains, ArrayNotEmpty, ArrayMinSize, ArrayMaxSize, ArrayUnique} from 'class-validator';
13
+ ${hasJsonField ? "import type { Prisma } from '../../types/prisma.types';\n" : ''}
14
+ export class ${model.name}Form {
15
+ ${t.each(model.fields, (field) => {
16
+ if ('scalar' === field.kind) {
17
+ if ((0, field_classifiers_1.isIdWithDefaultValue)(field))
18
+ return "";
19
+ if ((0, field_classifiers_1.isUpdatedAt)(field))
20
+ return "";
21
+ if (isCreateAt(field))
22
+ return "";
23
+ return t.fieldToDtoProp(field);
24
+ }
25
+ else if ('enum' === field.kind) {
26
+ if (!field.isRequired) {
27
+ return `@IsOptional()\n${field.name}?: string\n`;
28
+ }
29
+ return `@IsNotEmpty()\n${field.name}: string\n`;
30
+ }
31
+ else if ('object' === field.kind) {
32
+ if (!field.isRequired) {
33
+ return `@IsOptional()\n${field.name}?: string\n`;
34
+ }
35
+ return `@IsNotEmpty()\n${field.name}: string\n`;
36
+ }
37
+ return '';
38
+ }, '\n')}
39
+ }
40
+ `;
41
+ };
42
+ exports.generateFormValidatorClass = generateFormValidatorClass;
@@ -0,0 +1,8 @@
1
+ import type { TemplateHelpers } from './template-helpers';
2
+ import { DMMF } from '@prisma/generator-helper';
3
+ interface GenerateModuleParam {
4
+ model: DMMF.Model;
5
+ templateHelpers: TemplateHelpers;
6
+ }
7
+ export declare const generateModule: ({ model, templateHelpers: t, }: GenerateModuleParam) => string;
8
+ export {};
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateModule = void 0;
4
+ const case_1 = require("case");
5
+ const generateModule = ({ model, templateHelpers: t, }) => `
6
+ import { Module } from '@nestjs/common';
7
+ import { ${model.name}Service } from './${(0, case_1.camel)(model.name)}.service';
8
+ import { ${model.name}Controller } from './${(0, case_1.camel)(model.name)}.controller';
9
+
10
+ @Module({
11
+ controllers: [${model.name}Controller],
12
+ providers: [${model.name}Service],
13
+ exports: [${model.name}Service],
14
+ })
15
+ export class ${model.name}Module {}
16
+
17
+ `;
18
+ exports.generateModule = generateModule;
@@ -0,0 +1,8 @@
1
+ import type { TemplateHelpers } from './template-helpers';
2
+ import { Model } from './types';
3
+ interface GenerateModulesIndexParam {
4
+ allModels: Model[];
5
+ templateHelpers: TemplateHelpers;
6
+ }
7
+ export declare const generateModulesIndex: ({ allModels, templateHelpers: t, }: GenerateModulesIndexParam) => string;
8
+ export {};
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateModulesIndex = void 0;
4
+ const case_1 = require("case");
5
+ const generateModulesIndex = ({ allModels, templateHelpers: t, }) => `
6
+ ${t.each(allModels, (model) => `import { ${model.name}Module } from '../modules/${(0, case_1.camel)(model.name)}/${(0, case_1.camel)(model.name)}.module';`, '\n')}
7
+
8
+ export default [
9
+ ${t.each(allModels, (model) => `${model.name}Module`, ',')}
10
+ ];
11
+
12
+ `;
13
+ exports.generateModulesIndex = generateModulesIndex;
@@ -0,0 +1,8 @@
1
+ import type { TemplateHelpers } from './template-helpers';
2
+ import { DMMF } from '@prisma/generator-helper';
3
+ interface GenerateServiceSpecParam {
4
+ model: DMMF.Model;
5
+ templateHelpers: TemplateHelpers;
6
+ }
7
+ export declare const generateServiceSpec: ({ model, templateHelpers: t, }: GenerateServiceSpecParam) => string;
8
+ export {};