Skip to content

Commit b6c184e

Browse files
committed
Fix code formatting with Prettier
1 parent 7b8b5c6 commit b6c184e

File tree

5 files changed

+101
-69
lines changed

5 files changed

+101
-69
lines changed

src/generate-class.ts

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,13 @@ function generateSingleClass(
5656
generateClassValidatorImport(sourceFile, validatorImports as Array<string>);
5757

5858
// Add Swagger imports if enabled
59-
if (config.swagger && shouldImportSwagger(model.fields as PrismaDMMF.Field[])) {
60-
const swaggerImports = getSwaggerImportsByType(model.fields as PrismaDMMF.Field[]);
59+
if (
60+
config.swagger &&
61+
shouldImportSwagger(model.fields as PrismaDMMF.Field[])
62+
) {
63+
const swaggerImports = getSwaggerImportsByType(
64+
model.fields as PrismaDMMF.Field[],
65+
);
6166
generateSwaggerImport(sourceFile, swaggerImports);
6267
}
6368
const relationImports = new Set();
@@ -105,15 +110,15 @@ function generateSeparateRelationClasses(
105110
// Separate base fields from relation fields
106111
const baseFields = model.fields.filter((field) => !field.relationName);
107112
const relationFields = model.fields.filter((field) => field.relationName);
108-
113+
109114
// Generate base class (without relations)
110115
generateBaseClass(project, config, model, baseFields);
111-
116+
112117
// Generate relation class (only relations)
113118
if (relationFields.length > 0) {
114119
generateRelationClass(project, config, model, relationFields);
115120
}
116-
121+
117122
// Generate combined class that extends base and includes relations
118123
generateCombinedClass(project, config, model, baseFields, relationFields);
119124
}
@@ -146,7 +151,9 @@ function generateBaseClass(
146151

147152
// Add Swagger imports if enabled
148153
if (config.swagger && shouldImportSwagger(fields as PrismaDMMF.Field[])) {
149-
const swaggerImports = getSwaggerImportsByType(fields as PrismaDMMF.Field[]);
154+
const swaggerImports = getSwaggerImportsByType(
155+
fields as PrismaDMMF.Field[],
156+
);
150157
generateSwaggerImport(sourceFile, swaggerImports);
151158
}
152159

@@ -160,18 +167,16 @@ function generateBaseClass(
160167
name: `${model.name}Base`,
161168
isExported: true,
162169
properties: [
163-
...fields.map<OptionalKind<PropertyDeclarationStructure>>(
164-
(field) => {
165-
return {
166-
name: field.name,
167-
type: getTSDataTypeFromFieldType(field),
168-
hasExclamationToken: field.isRequired,
169-
hasQuestionToken: !field.isRequired,
170-
trailingTrivia: '\r\n',
171-
decorators: getDecoratorsByFieldType(field, config.swagger),
172-
};
173-
},
174-
),
170+
...fields.map<OptionalKind<PropertyDeclarationStructure>>((field) => {
171+
return {
172+
name: field.name,
173+
type: getTSDataTypeFromFieldType(field),
174+
hasExclamationToken: field.isRequired,
175+
hasQuestionToken: !field.isRequired,
176+
trailingTrivia: '\r\n',
177+
decorators: getDecoratorsByFieldType(field, config.swagger),
178+
};
179+
}),
175180
],
176181
});
177182
}
@@ -199,8 +204,13 @@ function generateRelationClass(
199204
generateClassValidatorImport(sourceFile, validatorImports as Array<string>);
200205

201206
// Add Swagger imports if enabled
202-
if (config.swagger && shouldImportSwagger(relationFields as PrismaDMMF.Field[])) {
203-
const swaggerImports = getSwaggerImportsByType(relationFields as PrismaDMMF.Field[]);
207+
if (
208+
config.swagger &&
209+
shouldImportSwagger(relationFields as PrismaDMMF.Field[])
210+
) {
211+
const swaggerImports = getSwaggerImportsByType(
212+
relationFields as PrismaDMMF.Field[],
213+
);
204214
generateSwaggerImport(sourceFile, swaggerImports);
205215
}
206216

src/helpers.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,26 +68,29 @@ export const getTSDataTypeFromFieldType = (field: PrismaDMMF.Field) => {
6868
if (field.isList) {
6969
type = `${type}[]`;
7070
}
71-
71+
7272
// Add null union for optional fields to match Prisma client behavior
7373
if (!field.isRequired) {
7474
type = `${type} | null`;
7575
}
76-
76+
7777
return type;
7878
};
7979

80-
export const getDecoratorsByFieldType = (field: PrismaDMMF.Field, includeSwagger: boolean = false) => {
80+
export const getDecoratorsByFieldType = (
81+
field: PrismaDMMF.Field,
82+
includeSwagger: boolean = false,
83+
) => {
8184
const decorators: OptionalKind<DecoratorStructure>[] = [];
82-
85+
8386
// Add Swagger decorators first if enabled
8487
if (includeSwagger) {
8588
const swaggerDecorator = getSwaggerDecoratorByFieldType(field);
8689
if (swaggerDecorator) {
8790
decorators.push(swaggerDecorator);
8891
}
8992
}
90-
93+
9194
// Add class-validator decorators
9295
switch (field.type) {
9396
case 'Int':
@@ -143,7 +146,7 @@ export const getDecoratorsByFieldType = (field: PrismaDMMF.Field, includeSwagger
143146

144147
export const getSwaggerDecoratorByFieldType = (field: PrismaDMMF.Field) => {
145148
const args: string[] = [];
146-
149+
147150
// Base properties
148151
if (field.hasDefaultValue && field.default !== null) {
149152
if (typeof field.default === 'object' && 'name' in field.default) {
@@ -153,7 +156,7 @@ export const getSwaggerDecoratorByFieldType = (field: PrismaDMMF.Field) => {
153156
args.push(`example: ${JSON.stringify(field.default)}`);
154157
}
155158
}
156-
159+
157160
// Type-specific properties
158161
switch (field.type) {
159162
case 'Int':
@@ -181,22 +184,22 @@ export const getSwaggerDecoratorByFieldType = (field: PrismaDMMF.Field) => {
181184
args.push('type: "string"', 'format: "byte"');
182185
break;
183186
}
184-
187+
185188
// Array handling
186189
if (field.isList) {
187190
args.push('isArray: true');
188191
}
189-
192+
190193
// Required/optional
191194
if (!field.isRequired) {
192195
args.push('required: false');
193196
}
194-
197+
195198
// Enum handling
196199
if (field.kind === 'enum') {
197200
args.push(`enum: Object.values(${field.type})`);
198201
}
199-
202+
200203
return {
201204
name: 'ApiProperty',
202205
arguments: args.length > 0 ? [`{ ${args.join(', ')} }`] : [],

src/prisma-generator.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ export interface GeneratorConfig {
1717

1818
export async function generate(options: GeneratorOptions) {
1919
const outputDir = parseEnvValue(options.generator.output as EnvValue);
20-
20+
2121
const config: GeneratorConfig = {
2222
outputDir,
2323
swagger: options.generator.config?.swagger === 'true',
24-
separateRelationFields: options.generator.config?.separateRelationFields === 'true',
24+
separateRelationFields:
25+
options.generator.config?.separateRelationFields === 'true',
2526
};
2627
await fs.mkdir(outputDir, { recursive: true });
2728
await removeDir(outputDir, true);

tests/relation-splitting.test.ts

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ describe('Relation Splitting Generation', () => {
1010
beforeAll(async () => {
1111
// Build the generator first
1212
await execAsync('npm run build');
13-
13+
1414
// Generate models for full-features schema
1515
const schemaPath = path.resolve(__dirname, 'schemas/full-features.prisma');
1616
await execAsync(`npx prisma generate --schema="${schemaPath}"`);
@@ -19,50 +19,66 @@ describe('Relation Splitting Generation', () => {
1919
it('should generate separate base and relation classes', () => {
2020
const outputPath = path.resolve(__dirname, 'generated/full-features');
2121
const modelsDir = path.join(outputPath, 'models');
22-
22+
2323
// Check that all expected files are generated
24-
expect(() => readFileSync(path.join(modelsDir, 'UserBase.model.ts'))).not.toThrow();
25-
expect(() => readFileSync(path.join(modelsDir, 'UserRelations.model.ts'))).not.toThrow();
26-
expect(() => readFileSync(path.join(modelsDir, 'User.model.ts'))).not.toThrow();
27-
28-
expect(() => readFileSync(path.join(modelsDir, 'PostBase.model.ts'))).not.toThrow();
29-
expect(() => readFileSync(path.join(modelsDir, 'PostRelations.model.ts'))).not.toThrow();
30-
expect(() => readFileSync(path.join(modelsDir, 'Post.model.ts'))).not.toThrow();
24+
expect(() =>
25+
readFileSync(path.join(modelsDir, 'UserBase.model.ts')),
26+
).not.toThrow();
27+
expect(() =>
28+
readFileSync(path.join(modelsDir, 'UserRelations.model.ts')),
29+
).not.toThrow();
30+
expect(() =>
31+
readFileSync(path.join(modelsDir, 'User.model.ts')),
32+
).not.toThrow();
33+
34+
expect(() =>
35+
readFileSync(path.join(modelsDir, 'PostBase.model.ts')),
36+
).not.toThrow();
37+
expect(() =>
38+
readFileSync(path.join(modelsDir, 'PostRelations.model.ts')),
39+
).not.toThrow();
40+
expect(() =>
41+
readFileSync(path.join(modelsDir, 'Post.model.ts')),
42+
).not.toThrow();
3143
});
3244

3345
it('should generate UserBase with only non-relation fields', () => {
3446
const outputPath = path.resolve(__dirname, 'generated/full-features');
3547
const userBasePath = path.join(outputPath, 'models', 'UserBase.model.ts');
3648
const userBase = readFileSync(userBasePath, 'utf-8');
37-
49+
3850
// Should contain scalar fields
3951
expect(userBase).toContain('id!: number');
4052
expect(userBase).toContain('email!: string');
4153
expect(userBase).toContain('name?: string | null');
42-
54+
4355
// Should NOT contain relation fields
4456
expect(userBase).not.toContain('posts');
45-
57+
4658
// Should have both class-validator and Swagger decorators
4759
expect(userBase).toContain('@IsInt()');
4860
expect(userBase).toContain('@ApiProperty({');
4961
});
5062

5163
it('should generate UserRelations with only relation fields', () => {
5264
const outputPath = path.resolve(__dirname, 'generated/full-features');
53-
const userRelationsPath = path.join(outputPath, 'models', 'UserRelations.model.ts');
65+
const userRelationsPath = path.join(
66+
outputPath,
67+
'models',
68+
'UserRelations.model.ts',
69+
);
5470
const userRelations = readFileSync(userRelationsPath, 'utf-8');
55-
71+
5672
// Should contain relation fields
5773
expect(userRelations).toContain('posts!: Post[]');
58-
74+
5975
// Should NOT contain scalar fields
6076
expect(userRelations).not.toContain('id!: number');
6177
expect(userRelations).not.toContain('email!: string');
62-
78+
6379
// Should import related models
6480
expect(userRelations).toContain('import { Post } from "./"');
65-
81+
6682
// Should have decorators for relations
6783
expect(userRelations).toContain('@ApiProperty({ isArray: true })');
6884
});
@@ -71,16 +87,16 @@ describe('Relation Splitting Generation', () => {
7187
const outputPath = path.resolve(__dirname, 'generated/full-features');
7288
const userPath = path.join(outputPath, 'models', 'User.model.ts');
7389
const user = readFileSync(userPath, 'utf-8');
74-
90+
7591
// Should extend base class
7692
expect(user).toContain('extends UserBase');
77-
93+
7894
// Should import base class
7995
expect(user).toContain('import { UserBase } from "./UserBase.model"');
80-
96+
8197
// Should import relation types
8298
expect(user).toContain('import { Post } from "./"');
83-
99+
84100
// Should include relation properties
85101
expect(user).toContain('posts!: Post[]');
86102
});
@@ -89,13 +105,13 @@ describe('Relation Splitting Generation', () => {
89105
const outputPath = path.resolve(__dirname, 'generated/full-features');
90106
const postBasePath = path.join(outputPath, 'models', 'PostBase.model.ts');
91107
const postBase = readFileSync(postBasePath, 'utf-8');
92-
108+
93109
// Should contain all scalar fields including foreign key
94110
expect(postBase).toContain('id!: number');
95111
expect(postBase).toContain('title!: string');
96112
expect(postBase).toContain('authorId?: number | null');
97113
expect(postBase).toContain('rating!: number');
98-
114+
99115
// Should NOT contain relation fields (but should contain foreign key)
100116
expect(postBase).not.toContain('author?: User');
101117
expect(postBase).not.toContain('import { User } from "./"');
@@ -106,8 +122,8 @@ describe('Relation Splitting Generation', () => {
106122
const outputPath = path.resolve(__dirname, 'generated/full-features');
107123
const userPath = path.join(outputPath, 'models', 'User.model.ts');
108124
const user = readFileSync(userPath, 'utf-8');
109-
125+
110126
// Should be valid TypeScript
111127
expect(user).toContain('export class User extends UserBase');
112128
});
113-
});
129+
});

tests/swagger-generation.test.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ describe('Swagger Generation', () => {
1010
beforeAll(async () => {
1111
// Build the generator first
1212
await execAsync('npm run build');
13-
13+
1414
// Generate models for swagger schema
1515
const schemaPath = path.resolve(__dirname, 'schemas/swagger.prisma');
1616
await execAsync(`npx prisma generate --schema="${schemaPath}"`);
@@ -20,10 +20,12 @@ describe('Swagger Generation', () => {
2020
const outputPath = path.resolve(__dirname, 'generated/swagger');
2121
const userModelPath = path.join(outputPath, 'models', 'User.model.ts');
2222
const userModel = readFileSync(userModelPath, 'utf-8');
23-
23+
2424
// Check for Swagger imports
25-
expect(userModel).toContain('import { ApiProperty } from "@nestjs/swagger"');
26-
25+
expect(userModel).toContain(
26+
'import { ApiProperty } from "@nestjs/swagger"',
27+
);
28+
2729
// Check for ApiProperty decorators
2830
expect(userModel).toContain('@ApiProperty({');
2931
expect(userModel).toContain('type: "integer"');
@@ -36,17 +38,17 @@ describe('Swagger Generation', () => {
3638
const outputPath = path.resolve(__dirname, 'generated/swagger');
3739
const postModelPath = path.join(outputPath, 'models', 'Post.model.ts');
3840
const postModel = readFileSync(postModelPath, 'utf-8');
39-
41+
4042
// Check for DateTime format
4143
expect(postModel).toContain('format: "date-time"');
42-
44+
4345
// Check for boolean type
4446
expect(postModel).toContain('type: "boolean"');
45-
47+
4648
// Check for Float handling
4749
expect(postModel).toContain('type: "number"');
4850
expect(postModel).toContain('@IsNumber()');
49-
51+
5052
// Check for default value examples
5153
expect(postModel).toContain('example: false');
5254
expect(postModel).toContain('example: 0');
@@ -56,14 +58,14 @@ describe('Swagger Generation', () => {
5658
const outputPath = path.resolve(__dirname, 'generated/swagger');
5759
const userModelPath = path.join(outputPath, 'models', 'User.model.ts');
5860
const userModel = readFileSync(userModelPath, 'utf-8');
59-
61+
6062
// Check for class-validator decorators
6163
expect(userModel).toContain('@IsInt()');
6264
expect(userModel).toContain('@IsString()');
6365
expect(userModel).toContain('@IsDefined()');
6466
expect(userModel).toContain('@IsOptional()');
65-
67+
6668
// Check for Swagger decorators
6769
expect(userModel).toContain('@ApiProperty({');
6870
});
69-
});
71+
});

0 commit comments

Comments
 (0)