Skip to content

Commit 5ee8c97

Browse files
committed
refactor: fastify plugin use dsl
1 parent 595ae0e commit 5ee8c97

File tree

5 files changed

+90
-111
lines changed

5 files changed

+90
-111
lines changed

packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/plugins/fastify/default/fastify.gen.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ export type RouteHandlers = {
4141
Reply: DummyBResponses;
4242
}>;
4343
callWithDuplicateResponses: RouteHandler<{
44-
Reply: Omit<CallWithDuplicateResponsesErrors, 'default'> & CallWithDuplicateResponsesResponses;
44+
Reply: Omit<CallWithDuplicateResponsesErrors, "default"> & CallWithDuplicateResponsesResponses;
4545
}>;
4646
callWithResponses: RouteHandler<{
47-
Reply: Omit<CallWithResponsesErrors, 'default'> & CallWithResponsesResponses;
47+
Reply: Omit<CallWithResponsesErrors, "default"> & CallWithResponsesResponses;
4848
}>;
4949
collectionFormat: RouteHandler<{
5050
Querystring: CollectionFormatData['query'];

packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/plugins/fastify/default/fastify.gen.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type { ApiVVersionODataControllerCountResponses, CallToTestOrderOfParamsD
77
export type RouteHandlers = {
88
import: RouteHandler<{
99
Body: ImportData['body'];
10-
Reply: Omit<ImportResponses, 'default'>;
10+
Reply: Omit<ImportResponses, "default">;
1111
}>;
1212
apiVVersionODataControllerCount: RouteHandler<{
1313
Reply: ApiVVersionODataControllerCountResponses;
@@ -43,16 +43,16 @@ export type RouteHandlers = {
4343
Querystring?: GetCallWithOptionalParamData['query'];
4444
}>;
4545
postCallWithOptionalParam: RouteHandler<{
46-
Body: PostCallWithOptionalParamData['body'];
46+
Body?: PostCallWithOptionalParamData['body'];
4747
Querystring: PostCallWithOptionalParamData['query'];
4848
Reply: PostCallWithOptionalParamResponses;
4949
}>;
5050
postApiVbyApiVersionRequestBody: RouteHandler<{
51-
Body: PostApiVbyApiVersionRequestBodyData['body'];
51+
Body?: PostApiVbyApiVersionRequestBodyData['body'];
5252
Querystring?: PostApiVbyApiVersionRequestBodyData['query'];
5353
}>;
5454
postApiVbyApiVersionFormData: RouteHandler<{
55-
Body: PostApiVbyApiVersionFormDataData['body'];
55+
Body?: PostApiVbyApiVersionFormDataData['body'];
5656
Querystring?: PostApiVbyApiVersionFormDataData['query'];
5757
}>;
5858
callWithDefaultParameters: RouteHandler<{
@@ -77,10 +77,10 @@ export type RouteHandlers = {
7777
Reply: DummyBResponses;
7878
}>;
7979
callWithDuplicateResponses: RouteHandler<{
80-
Reply: Omit<CallWithDuplicateResponsesErrors, 'default'> & CallWithDuplicateResponsesResponses;
80+
Reply: Omit<CallWithDuplicateResponsesErrors, "default"> & CallWithDuplicateResponsesResponses;
8181
}>;
8282
callWithResponses: RouteHandler<{
83-
Reply: Omit<CallWithResponsesErrors, 'default'> & CallWithResponsesResponses;
83+
Reply: Omit<CallWithResponsesErrors, "default"> & CallWithResponsesResponses;
8484
}>;
8585
collectionFormat: RouteHandler<{
8686
Querystring: CollectionFormatData['query'];
@@ -107,10 +107,10 @@ export type RouteHandlers = {
107107
Reply: MultipartResponseResponses;
108108
}>;
109109
multipartRequest: RouteHandler<{
110-
Body: MultipartRequestData['body'];
110+
Body?: MultipartRequestData['body'];
111111
}>;
112112
complexParams: RouteHandler<{
113-
Body: ComplexParamsData['body'];
113+
Body?: ComplexParamsData['body'];
114114
Params: ComplexParamsData['path'];
115115
Reply: ComplexParamsResponses;
116116
}>;

packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/plugins/fastify/default/fastify.gen.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type { ApiVVersionODataControllerCountResponses, CallToTestOrderOfParamsD
77
export type RouteHandlers = {
88
import: RouteHandler<{
99
Body: ImportData['body'];
10-
Reply: Omit<ImportResponses, 'default'>;
10+
Reply: Omit<ImportResponses, "default">;
1111
}>;
1212
apiVVersionODataControllerCount: RouteHandler<{
1313
Reply: ApiVVersionODataControllerCountResponses;
@@ -43,16 +43,16 @@ export type RouteHandlers = {
4343
Querystring?: GetCallWithOptionalParamData['query'];
4444
}>;
4545
postCallWithOptionalParam: RouteHandler<{
46-
Body: PostCallWithOptionalParamData['body'];
46+
Body?: PostCallWithOptionalParamData['body'];
4747
Querystring: PostCallWithOptionalParamData['query'];
4848
Reply: PostCallWithOptionalParamResponses;
4949
}>;
5050
postApiVbyApiVersionRequestBody: RouteHandler<{
51-
Body: PostApiVbyApiVersionRequestBodyData['body'];
51+
Body?: PostApiVbyApiVersionRequestBodyData['body'];
5252
Querystring?: PostApiVbyApiVersionRequestBodyData['query'];
5353
}>;
5454
postApiVbyApiVersionFormData: RouteHandler<{
55-
Body: PostApiVbyApiVersionFormDataData['body'];
55+
Body?: PostApiVbyApiVersionFormDataData['body'];
5656
Querystring?: PostApiVbyApiVersionFormDataData['query'];
5757
}>;
5858
callWithDefaultParameters: RouteHandler<{
@@ -77,10 +77,10 @@ export type RouteHandlers = {
7777
Reply: DummyBResponses;
7878
}>;
7979
callWithDuplicateResponses: RouteHandler<{
80-
Reply: Omit<CallWithDuplicateResponsesErrors, 'default'> & CallWithDuplicateResponsesResponses;
80+
Reply: Omit<CallWithDuplicateResponsesErrors, "default"> & CallWithDuplicateResponsesResponses;
8181
}>;
8282
callWithResponses: RouteHandler<{
83-
Reply: Omit<CallWithResponsesErrors, 'default'> & CallWithResponsesResponses;
83+
Reply: Omit<CallWithResponsesErrors, "default"> & CallWithResponsesResponses;
8484
}>;
8585
collectionFormat: RouteHandler<{
8686
Querystring: CollectionFormatData['query'];
@@ -107,10 +107,10 @@ export type RouteHandlers = {
107107
Reply: MultipartResponseResponses;
108108
}>;
109109
multipartRequest: RouteHandler<{
110-
Body: MultipartRequestData['body'];
110+
Body?: MultipartRequestData['body'];
111111
}>;
112112
complexParams: RouteHandler<{
113-
Body: ComplexParamsData['body'];
113+
Body?: ComplexParamsData['body'];
114114
Params: ComplexParamsData['path'];
115115
Reply: ComplexParamsResponses;
116116
}>;
Lines changed: 56 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
import type ts from 'typescript';
2-
31
import { operationResponsesMap } from '~/ir/operation';
42
import { hasParameterGroupObjectRequired } from '~/ir/parameter';
53
import type { IR } from '~/ir/types';
6-
import { type Property, tsc } from '~/tsc';
4+
import { $ } from '~/ts-dsl';
75

86
import type { FastifyPlugin } from './types';
97

@@ -13,8 +11,8 @@ const operationToRouteHandler = ({
1311
}: {
1412
operation: IR.OperationObject;
1513
plugin: FastifyPlugin['Instance'];
16-
}): Property | undefined => {
17-
const properties: Array<Property> = [];
14+
}) => {
15+
const type = $.type.object();
1816

1917
const symbolDataType = plugin.querySymbol({
2018
category: 'type',
@@ -25,49 +23,49 @@ const operationToRouteHandler = ({
2523
});
2624
if (symbolDataType) {
2725
if (operation.body) {
28-
properties.push({
29-
isRequired: operation.body.required,
30-
name: 'Body',
31-
type: `${symbolDataType.placeholder}['body']`,
32-
});
26+
type.prop('Body', (p) =>
27+
p
28+
.optional(!operation.body!.required)
29+
.type(`${symbolDataType.placeholder}['body']`),
30+
);
3331
}
3432

3533
if (operation.parameters) {
3634
if (operation.parameters.header) {
37-
properties.push({
38-
isRequired: hasParameterGroupObjectRequired(
39-
operation.parameters.header,
40-
),
41-
name: 'Headers',
42-
type: `${symbolDataType.placeholder}['headers']`,
43-
});
35+
type.prop('Headers', (p) =>
36+
p
37+
.optional(
38+
!hasParameterGroupObjectRequired(operation.parameters!.header),
39+
)
40+
.type(`${symbolDataType.placeholder}['headers']`),
41+
);
4442
}
4543

4644
if (operation.parameters.path) {
47-
properties.push({
48-
isRequired: hasParameterGroupObjectRequired(
49-
operation.parameters.path,
50-
),
51-
name: 'Params',
52-
type: `${symbolDataType.placeholder}['path']`,
53-
});
45+
type.prop('Params', (p) =>
46+
p
47+
.optional(
48+
!hasParameterGroupObjectRequired(operation.parameters!.path),
49+
)
50+
.type(`${symbolDataType.placeholder}['path']`),
51+
);
5452
}
5553

5654
if (operation.parameters.query) {
57-
properties.push({
58-
isRequired: hasParameterGroupObjectRequired(
59-
operation.parameters.query,
60-
),
61-
name: 'Querystring',
62-
type: `${symbolDataType.placeholder}['query']`,
63-
});
55+
type.prop('Querystring', (p) =>
56+
p
57+
.optional(
58+
!hasParameterGroupObjectRequired(operation.parameters!.query),
59+
)
60+
.type(`${symbolDataType.placeholder}['query']`),
61+
);
6462
}
6563
}
6664
}
6765

6866
const { errors, responses } = operationResponsesMap(operation);
6967

70-
let errorsTypeReference: ts.TypeReferenceNode | undefined = undefined;
68+
let errorsTypeReference: ReturnType<typeof $.type> | undefined;
7169
const symbolErrorType = plugin.querySymbol({
7270
category: 'type',
7371
resource: 'operation',
@@ -79,25 +77,19 @@ const operationToRouteHandler = ({
7977
if (keys.length) {
8078
const hasDefaultResponse = keys.includes('default');
8179
if (!hasDefaultResponse) {
82-
errorsTypeReference = tsc.typeReferenceNode({
83-
typeName: symbolErrorType.placeholder,
84-
});
80+
errorsTypeReference = $.type(symbolErrorType.placeholder);
8581
} else if (keys.length > 1) {
86-
const errorsType = tsc.typeReferenceNode({
87-
typeName: symbolErrorType.placeholder,
88-
});
89-
const defaultType = tsc.literalTypeNode({
90-
literal: tsc.stringLiteral({ text: 'default' }),
91-
});
92-
errorsTypeReference = tsc.typeReferenceNode({
93-
typeArguments: [errorsType, defaultType],
94-
typeName: 'Omit',
95-
});
82+
errorsTypeReference = $.type('Omit', (t) =>
83+
t.generics(
84+
$.type(symbolErrorType.placeholder),
85+
$.type.literal('default'),
86+
),
87+
);
9688
}
9789
}
9890
}
9991

100-
let responsesTypeReference: ts.TypeReferenceNode | undefined = undefined;
92+
let responsesTypeReference: ReturnType<typeof $.type> | undefined = undefined;
10193
const symbolResponseType = plugin.querySymbol({
10294
category: 'type',
10395
resource: 'operation',
@@ -109,37 +101,26 @@ const operationToRouteHandler = ({
109101
if (keys.length) {
110102
const hasDefaultResponse = keys.includes('default');
111103
if (!hasDefaultResponse) {
112-
responsesTypeReference = tsc.typeReferenceNode({
113-
typeName: symbolResponseType.placeholder,
114-
});
104+
responsesTypeReference = $.type(symbolResponseType.placeholder);
115105
} else if (keys.length > 1) {
116-
const responsesType = tsc.typeReferenceNode({
117-
typeName: symbolResponseType.placeholder,
118-
});
119-
const defaultType = tsc.literalTypeNode({
120-
literal: tsc.stringLiteral({ text: 'default' }),
121-
});
122-
responsesTypeReference = tsc.typeReferenceNode({
123-
typeArguments: [responsesType, defaultType],
124-
typeName: 'Omit',
125-
});
106+
responsesTypeReference = $.type('Omit', (t) =>
107+
t.generics(
108+
$.type(symbolResponseType.placeholder),
109+
$.type.literal('default'),
110+
),
111+
);
126112
}
127113
}
128114
}
129115

130116
const replyTypes = [errorsTypeReference, responsesTypeReference].filter(
131-
Boolean,
117+
(t): t is ReturnType<typeof $.type> => t !== undefined,
132118
);
133119
if (replyTypes.length) {
134-
properties.push({
135-
name: 'Reply',
136-
type: tsc.typeIntersectionNode({
137-
types: replyTypes,
138-
}),
139-
});
120+
type.prop('Reply', (p) => p.type($.type.and(...replyTypes)));
140121
}
141122

142-
if (!properties.length) {
123+
if (type.isEmpty) {
143124
return;
144125
}
145126

@@ -148,19 +129,10 @@ const operationToRouteHandler = ({
148129
resource: 'route-handler',
149130
tool: 'fastify',
150131
});
151-
const routeHandler: Property = {
132+
return {
152133
name: operation.id,
153-
type: tsc.typeReferenceNode({
154-
typeArguments: [
155-
tsc.typeInterfaceNode({
156-
properties,
157-
useLegacyResolution: false,
158-
}),
159-
],
160-
typeName: symbolRouteHandler.placeholder,
161-
}),
134+
type: $.type(symbolRouteHandler.placeholder, (t) => t.generic(type)),
162135
};
163-
return routeHandler;
164136
};
165137

166138
export const handler: FastifyPlugin['Handler'] = ({ plugin }) => {
@@ -181,28 +153,24 @@ export const handler: FastifyPlugin['Handler'] = ({ plugin }) => {
181153
name: 'RouteHandlers',
182154
});
183155

184-
const routeHandlers: Array<Property> = [];
156+
const type = $.type.object();
185157

186158
plugin.forEach(
187159
'operation',
188160
({ operation }) => {
189161
const routeHandler = operationToRouteHandler({ operation, plugin });
190162
if (routeHandler) {
191-
routeHandlers.push(routeHandler);
163+
type.prop(routeHandler.name, (p) => p.type(routeHandler.type));
192164
}
193165
},
194166
{
195167
order: 'declarations',
196168
},
197169
);
198170

199-
const node = tsc.typeAliasDeclaration({
200-
exportType: symbolRouteHandlers.exported,
201-
name: symbolRouteHandlers.placeholder,
202-
type: tsc.typeInterfaceNode({
203-
properties: routeHandlers,
204-
useLegacyResolution: false,
205-
}),
206-
});
171+
const node = $.type
172+
.alias(symbolRouteHandlers.placeholder)
173+
.export(symbolRouteHandlers.exported)
174+
.type(type);
207175
plugin.setSymbolValue(symbolRouteHandlers, node);
208176
};

0 commit comments

Comments
 (0)