Skip to content

Commit 3d17490

Browse files
authored
Merge pull request #1615 from hey-api/chore/compiler-updates
2 parents 5cd4bb2 + 8040010 commit 3d17490

File tree

16 files changed

+136
-55
lines changed

16 files changed

+136
-55
lines changed

packages/openapi-ts/src/compiler/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export const compiler = {
3838
isTsNode: utils.isTsNode,
3939
keywordTypeNode: types.createKeywordTypeNode,
4040
literalTypeNode: types.createLiteralTypeNode,
41+
mappedTypeNode: types.createMappedTypeNode,
4142
methodDeclaration: classes.createMethodDeclaration,
4243
namedImportDeclarations: module.createNamedImportDeclarations,
4344
namespaceDeclaration: types.createNamespaceDeclaration,
@@ -68,6 +69,8 @@ export const compiler = {
6869
typeIntersectionNode: typedef.createTypeIntersectionNode,
6970
typeNode: types.createTypeNode,
7071
typeOfExpression: types.createTypeOfExpression,
72+
typeOperatorNode: types.createTypeOperatorNode,
73+
typeParameterDeclaration: types.createTypeParameterDeclaration,
7174
typeParenthesizedNode: types.createTypeParenthesizedNode,
7275
typeRecordNode: typedef.createTypeRecordNode,
7376
typeReferenceNode: types.createTypeReferenceNode,

packages/openapi-ts/src/compiler/types.ts

Lines changed: 72 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -287,24 +287,84 @@ export const createKeywordTypeNode = ({
287287

288288
export const toTypeParameters = (types: FunctionTypeParameter[]) =>
289289
types.map((type) =>
290-
ts.factory.createTypeParameterDeclaration(
291-
undefined,
292-
type.name,
290+
createTypeParameterDeclaration({
293291
// TODO: support other extends values
294-
type.extends
292+
constraint: type.extends
295293
? typeof type.extends === 'string'
296294
? createKeywordTypeNode({ keyword: 'boolean' })
297295
: type.extends
298296
: undefined,
299297
// TODO: support other default types
300-
type.default !== undefined
301-
? isTsNode(type.default)
302-
? (type.default as unknown as ts.TypeNode)
303-
: ts.factory.createLiteralTypeNode(
304-
type.default ? ts.factory.createTrue() : ts.factory.createFalse(),
305-
)
306-
: undefined,
307-
),
298+
defaultType:
299+
type.default !== undefined
300+
? isTsNode(type.default)
301+
? (type.default as unknown as ts.TypeNode)
302+
: ts.factory.createLiteralTypeNode(
303+
type.default
304+
? ts.factory.createTrue()
305+
: ts.factory.createFalse(),
306+
)
307+
: undefined,
308+
name: type.name,
309+
}),
310+
);
311+
312+
export const createTypeOperatorNode = ({
313+
operator,
314+
type,
315+
}: {
316+
operator: 'keyof' | 'readonly' | 'unique';
317+
type: ts.TypeNode;
318+
}) => {
319+
const operatorKeyword =
320+
operator === 'keyof'
321+
? ts.SyntaxKind.KeyOfKeyword
322+
: operator === 'readonly'
323+
? ts.SyntaxKind.ReadonlyKeyword
324+
: ts.SyntaxKind.UniqueKeyword;
325+
return ts.factory.createTypeOperatorNode(operatorKeyword, type);
326+
};
327+
328+
export const createTypeParameterDeclaration = ({
329+
constraint,
330+
defaultType,
331+
modifiers,
332+
name,
333+
}: {
334+
constraint?: ts.TypeNode;
335+
defaultType?: ts.TypeNode;
336+
modifiers?: Array<ts.Modifier>;
337+
name: string | ts.Identifier;
338+
}) =>
339+
ts.factory.createTypeParameterDeclaration(
340+
modifiers,
341+
name,
342+
constraint,
343+
defaultType,
344+
);
345+
346+
export const createMappedTypeNode = ({
347+
members,
348+
nameType,
349+
questionToken,
350+
readonlyToken,
351+
type,
352+
typeParameter,
353+
}: {
354+
members?: ts.NodeArray<ts.TypeElement>;
355+
nameType?: ts.TypeNode;
356+
questionToken?: ts.QuestionToken | ts.PlusToken | ts.MinusToken;
357+
readonlyToken?: ts.ReadonlyKeyword | ts.PlusToken | ts.MinusToken;
358+
type?: ts.TypeNode;
359+
typeParameter: ts.TypeParameterDeclaration;
360+
}) =>
361+
ts.factory.createMappedTypeNode(
362+
readonlyToken,
363+
typeParameter,
364+
nameType,
365+
questionToken,
366+
type,
367+
members,
308368
);
309369

310370
export const createLiteralTypeNode = ({

packages/openapi-ts/src/index.ts

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,7 @@ import type {
2323
PluginNames,
2424
} from './plugins/types';
2525
import type { Client } from './types/client';
26-
import type {
27-
ClientConfig,
28-
Config,
29-
Formatters,
30-
Linters,
31-
UserConfig,
32-
} from './types/config';
26+
import type { Config, Formatters, Linters, UserConfig } from './types/config';
3327
import { CLIENTS } from './types/config';
3428
import {
3529
isLegacyClient,
@@ -103,7 +97,7 @@ const processOutput = ({ config }: { config: Config }) => {
10397
}
10498
};
10599

106-
const getClient = (userConfig: ClientConfig): Config['client'] => {
100+
const getClient = (userConfig: UserConfig): Config['client'] => {
107101
let client: Config['client'] = {
108102
bundle: false,
109103
name: '' as Config['client']['name'],
@@ -119,7 +113,7 @@ const getClient = (userConfig: ClientConfig): Config['client'] => {
119113
return client;
120114
};
121115

122-
const getInput = (userConfig: ClientConfig): Config['input'] => {
116+
const getInput = (userConfig: UserConfig): Config['input'] => {
123117
let input: Config['input'] = {
124118
path: '',
125119
};
@@ -139,7 +133,7 @@ const getInput = (userConfig: ClientConfig): Config['input'] => {
139133
return input;
140134
};
141135

142-
const getLogs = (userConfig: ClientConfig): Config['logs'] => {
136+
const getLogs = (userConfig: UserConfig): Config['logs'] => {
143137
let logs: Config['logs'] = {
144138
level: 'info',
145139
path: process.cwd(),
@@ -155,7 +149,7 @@ const getLogs = (userConfig: ClientConfig): Config['logs'] => {
155149
return logs;
156150
};
157151

158-
const getOutput = (userConfig: ClientConfig): Config['output'] => {
152+
const getOutput = (userConfig: UserConfig): Config['output'] => {
159153
let output: Config['output'] = {
160154
clean: true,
161155
format: false,
@@ -271,7 +265,7 @@ const getPluginsConfig = ({
271265
};
272266

273267
const getPlugins = (
274-
userConfig: ClientConfig,
268+
userConfig: UserConfig,
275269
): Pick<Config, 'plugins' | 'pluginOrder'> => {
276270
const userPluginsConfig: Config['plugins'] = {};
277271

@@ -438,7 +432,7 @@ const getSpec = async ({
438432
};
439433

440434
const getWatch = (
441-
userConfig: Pick<ClientConfig, 'watch'> & Pick<Config, 'input'>,
435+
userConfig: Pick<UserConfig, 'watch'> & Pick<Config, 'input'>,
442436
): Config['watch'] => {
443437
let watch: Config['watch'] = {
444438
enabled: false,
@@ -476,7 +470,7 @@ const initConfigs = async (userConfig: UserConfig): Promise<Config[]> => {
476470
name: 'openapi-ts',
477471
});
478472

479-
const userConfigs: ClientConfig[] = Array.isArray(userConfig)
473+
const userConfigs: UserConfig[] = Array.isArray(userConfig)
480474
? userConfig
481475
: Array.isArray(configFromFile)
482476
? configFromFile.map((config) => ({

packages/openapi-ts/src/plugins/@hey-api/schemas/types.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@ export interface Config extends Plugin.Name<'@hey-api/schemas'> {
2525
) => string;
2626
/**
2727
* Name of the generated file.
28+
*
2829
* @default 'schemas'
2930
*/
3031
output?: string;
3132
/**
3233
* Choose schema type to generate. Select 'form' if you don't want
3334
* descriptions to reduce bundle size and you plan to use schemas
3435
* for form validation
36+
*
3537
* @default 'json'
3638
*/
3739
type?: 'form' | 'json';

packages/openapi-ts/src/plugins/@hey-api/sdk/types.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,11 @@ export interface Config extends Plugin.Name<'@hey-api/sdk'> {
5959
*/
6060
output?: string;
6161
/**
62+
* @deprecated
63+
*
6264
* Define shape of returned value from service calls
6365
*
6466
* @default 'body'
65-
*
66-
* @deprecated
6767
*/
6868
response?: 'body' | 'response';
6969
/**

packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { irRef } from '../../../utils/ref';
77
import { stringCase } from '../../../utils/stringCase';
88
import { operationIrRef } from '../../shared/utils/ref';
99
import type { Plugin } from '../../types';
10+
import { typesId } from '../typescript/ref';
1011
import type { Config } from './types';
1112

1213
interface OperationIRRef {
@@ -460,7 +461,7 @@ export const handler: Plugin.Handler<Config> = ({ context, plugin }) => {
460461
return;
461462
}
462463

463-
const identifierResponse = context.file({ id: 'types' })!.identifier({
464+
const identifierResponse = context.file({ id: typesId })!.identifier({
464465
$ref: operationIrRef({ id: operation.id, type: 'response' }),
465466
namespace: 'type',
466467
});
@@ -486,7 +487,7 @@ export const handler: Plugin.Handler<Config> = ({ context, plugin }) => {
486487
if (nodes.length) {
487488
file.import({
488489
asType: true,
489-
module: file.relativePathToFile({ context, id: 'types' }),
490+
module: file.relativePathToFile({ context, id: typesId }),
490491
name: identifierResponse.name,
491492
});
492493
const responseTransformerNode = compiler.constVariable({

packages/openapi-ts/src/plugins/@hey-api/typescript/ref.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,15 @@ export const importIdentifierData = ({
2626
file: TypeScriptFile;
2727
operation: IR.OperationObject;
2828
}): Identifier => {
29-
const identifierData = context.file({ id: 'types' })!.identifier({
29+
const identifierData = context.file({ id: typesId })!.identifier({
3030
$ref: operationIrRef({ id: operation.id, type: 'data' }),
3131
namespace: 'type',
3232
});
3333
return refIdentifier(identifierData, (identifier) => {
3434
if (identifier.name) {
3535
file.import({
3636
asType: true,
37-
module: file.relativePathToFile({ context, id: 'types' }),
37+
module: file.relativePathToFile({ context, id: typesId }),
3838
name: identifier.name,
3939
});
4040
}
@@ -50,15 +50,15 @@ export const importIdentifierError = ({
5050
file: TypeScriptFile;
5151
operation: IR.OperationObject;
5252
}): Identifier => {
53-
const identifierError = context.file({ id: 'types' })!.identifier({
53+
const identifierError = context.file({ id: typesId })!.identifier({
5454
$ref: operationIrRef({ id: operation.id, type: 'error' }),
5555
namespace: 'type',
5656
});
5757
return refIdentifier(identifierError, (identifier) => {
5858
if (identifier.name) {
5959
file.import({
6060
asType: true,
61-
module: file.relativePathToFile({ context, id: 'types' }),
61+
module: file.relativePathToFile({ context, id: typesId }),
6262
name: identifier.name,
6363
});
6464
}
@@ -74,15 +74,15 @@ export const importIdentifierResponse = ({
7474
file: TypeScriptFile;
7575
operation: IR.OperationObject;
7676
}): Identifier => {
77-
const identifierResponse = context.file({ id: 'types' })!.identifier({
77+
const identifierResponse = context.file({ id: typesId })!.identifier({
7878
$ref: operationIrRef({ id: operation.id, type: 'response' }),
7979
namespace: 'type',
8080
});
8181
return refIdentifier(identifierResponse, (identifier) => {
8282
if (identifier.name) {
8383
file.import({
8484
asType: true,
85-
module: file.relativePathToFile({ context, id: 'types' }),
85+
module: file.relativePathToFile({ context, id: typesId }),
8686
name: identifier.name,
8787
});
8888
}

packages/openapi-ts/src/plugins/@tanstack/angular-query-experimental/types.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,26 @@ export interface Config
44
extends Plugin.Name<'@tanstack/angular-query-experimental'> {
55
/**
66
* Generate {@link https://tanstack.com/query/v5/docs/framework/angular/reference/infiniteQueryOptions `infiniteQueryOptions()`} helpers? These will be generated from GET and POST requests where a pagination parameter is detected.
7+
*
78
* @default true
89
*/
910
infiniteQueryOptions?: boolean;
1011
/**
1112
* Generate {@link https://tanstack.com/query/v5/docs/framework/angular/reference/useMutation `useMutation()`} helpers? These will be generated from DELETE, PATCH, POST, and PUT requests.
13+
*
1214
* @default true
1315
*/
1416
mutationOptions?: boolean;
1517
/**
1618
* Name of the generated file.
19+
*
1720
* @default '@tanstack/angular-query-experimental'
1821
*/
1922
output?: string;
2023
/**
2124
* Generate {@link https://tanstack.com/query/v5/docs/framework/angular/reference/queryOptions `queryOptions()`} helpers?
2225
* These will be generated from all requests.
26+
*
2327
* @default true
2428
*/
2529
queryOptions?: boolean;

packages/openapi-ts/src/plugins/@tanstack/react-query/types.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,26 @@ import type { Plugin } from '../../types';
33
export interface Config extends Plugin.Name<'@tanstack/react-query'> {
44
/**
55
* Generate {@link https://tanstack.com/query/v5/docs/framework/react/reference/infiniteQueryOptions `infiniteQueryOptions()`} helpers? These will be generated from GET and POST requests where a pagination parameter is detected.
6+
*
67
* @default true
78
*/
89
infiniteQueryOptions?: boolean;
910
/**
1011
* Generate {@link https://tanstack.com/query/v5/docs/framework/react/reference/useMutation `useMutation()`} helpers? These will be generated from DELETE, PATCH, POST, and PUT requests.
12+
*
1113
* @default true
1214
*/
1315
mutationOptions?: boolean;
1416
/**
1517
* Name of the generated file.
18+
*
1619
* @default '@tanstack/react-query'
1720
*/
1821
output?: string;
1922
/**
2023
* Generate {@link https://tanstack.com/query/v5/docs/framework/react/reference/queryOptions `queryOptions()`} helpers?
2124
* These will be generated from all requests.
25+
*
2226
* @default true
2327
*/
2428
queryOptions?: boolean;

packages/openapi-ts/src/plugins/@tanstack/solid-query/types.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,26 @@ import type { Plugin } from '../../types';
33
export interface Config extends Plugin.Name<'@tanstack/solid-query'> {
44
/**
55
* Generate `createInfiniteQuery()` helpers? These will be generated from GET and POST requests where a pagination parameter is detected.
6+
*
67
* @default true
78
*/
89
infiniteQueryOptions?: boolean;
910
/**
1011
* Generate `createMutation()` helpers? These will be generated from DELETE, PATCH, POST, and PUT requests.
12+
*
1113
* @default true
1214
*/
1315
mutationOptions?: boolean;
1416
/**
1517
* Name of the generated file.
18+
*
1619
* @default '@tanstack/solid-query'
1720
*/
1821
output?: string;
1922
/**
2023
* Generate {@link https://tanstack.com/query/v5/docs/framework/solid/reference/createQuery `createQuery()`} helpers?
2124
* These will be generated from all requests.
25+
*
2226
* @default true
2327
*/
2428
queryOptions?: boolean;

0 commit comments

Comments
 (0)