-
-
Notifications
You must be signed in to change notification settings - Fork 102
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
1,702 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@hey-api/openapi-ts': minor | ||
--- | ||
|
||
feat: add fastify-openapi-glue plugin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import type { DefineConfig, PluginConfig } from '../types'; | ||
import { handler } from './plugin'; | ||
import type { Config } from './types'; | ||
|
||
export const defaultConfig: PluginConfig<Config> = { | ||
_handler: handler, | ||
_handlerLegacy: () => {}, | ||
name: 'fastify', | ||
output: 'fastify', | ||
}; | ||
|
||
/** | ||
* Type helper for the Fastify plugin, returns {@link PluginConfig} object | ||
*/ | ||
export const defineConfig: DefineConfig<Config> = (config) => ({ | ||
...defaultConfig, | ||
...config, | ||
}); | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export { defaultConfig, defineConfig } from './config'; | ||
export type { Config } from './types'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
import type ts from 'typescript'; | ||
|
||
import { compiler, type Property } from '../../compiler'; | ||
import type { IRContext } from '../../ir/context'; | ||
import type { | ||
IROperationObject, | ||
IRParameterObject, | ||
IRPathItemObject, | ||
IRPathsObject, | ||
} from '../../ir/ir'; | ||
import { irParametersToIrSchema } from '../../ir/schema'; | ||
import type { PluginHandler } from '../types'; | ||
import { | ||
componentsToType, | ||
schemaToType, | ||
type SchemaToTypeOptions, | ||
} from '../utils/types'; | ||
import type { Config } from './types'; | ||
|
||
const FILE_ID = 'fastify'; | ||
const ROUTE_HANDLER_NAME = 'RouteHandler'; | ||
const OPERATIONS_IDENTIFIER = 'FastifyRouteHandlers'; | ||
const ROUTE_PROPERTY_NAME = { | ||
BODY: 'Body', | ||
HEADER: 'Headers', | ||
PATH: 'Params', | ||
QUERY: 'Querystring', | ||
RESPONSE: 'Reply', | ||
}; | ||
|
||
const parameterToProperty = ({ | ||
options, | ||
parameter, | ||
name, | ||
}: { | ||
name: string; | ||
options: SchemaToTypeOptions; | ||
parameter: Record<string, IRParameterObject>; | ||
}): Property => { | ||
const schema = irParametersToIrSchema({ | ||
parameters: parameter, | ||
}); | ||
return { | ||
isRequired: !!schema.required, | ||
name, | ||
type: schemaToType({ options, schema }), | ||
}; | ||
}; | ||
|
||
const operationToProperty = ({ | ||
operation, | ||
options, | ||
}: { | ||
operation: IROperationObject; | ||
options: SchemaToTypeOptions; | ||
}): Property => { | ||
const operationProperties: Array<Property> = []; | ||
|
||
if (operation.body) { | ||
operationProperties.push({ | ||
isRequired: operation.body.required, | ||
name: ROUTE_PROPERTY_NAME.BODY, | ||
type: schemaToType({ | ||
options, | ||
schema: operation.body.schema, | ||
}), | ||
}); | ||
} | ||
|
||
if (operation.parameters) { | ||
if (operation.parameters.header) { | ||
operationProperties.push( | ||
parameterToProperty({ | ||
name: ROUTE_PROPERTY_NAME.HEADER, | ||
options, | ||
parameter: operation.parameters.header, | ||
}), | ||
); | ||
} | ||
|
||
if (operation.parameters.query) { | ||
operationProperties.push( | ||
parameterToProperty({ | ||
name: ROUTE_PROPERTY_NAME.QUERY, | ||
options, | ||
parameter: operation.parameters.query, | ||
}), | ||
); | ||
} | ||
|
||
if (operation.parameters.path) { | ||
operationProperties.push( | ||
parameterToProperty({ | ||
name: ROUTE_PROPERTY_NAME.PATH, | ||
options, | ||
parameter: operation.parameters.path, | ||
}), | ||
); | ||
} | ||
} | ||
|
||
if (operation.responses) { | ||
const responseProperties: Array<Property> = []; | ||
for (const code in operation.responses) { | ||
const response = operation.responses[code]; | ||
responseProperties.push({ | ||
name: code, | ||
type: schemaToType({ | ||
options, | ||
schema: response?.schema ?? {}, | ||
}), | ||
}); | ||
} | ||
operationProperties.push({ | ||
name: ROUTE_PROPERTY_NAME.RESPONSE, | ||
type: compiler.typeInterfaceNode({ | ||
properties: responseProperties, | ||
useLegacyResolution: false, | ||
}), | ||
}); | ||
} | ||
|
||
const operationType = compiler.typeInterfaceNode({ | ||
properties: operationProperties, | ||
useLegacyResolution: false, | ||
}); | ||
const property: Property = { | ||
name: operation.id, | ||
type: compiler.typeNode(ROUTE_HANDLER_NAME, [operationType]), | ||
}; | ||
return property; | ||
}; | ||
|
||
const pathsToType = ({ | ||
context, | ||
options, | ||
}: { | ||
context: IRContext; | ||
options: SchemaToTypeOptions; | ||
}): ts.Node => { | ||
const operationsProperties = []; | ||
for (const path in context.ir.paths) { | ||
const pathItem = context.ir.paths[path as keyof IRPathsObject]; | ||
for (const method in pathItem) { | ||
const operation = pathItem[method as keyof IRPathItemObject]; | ||
if (operation) { | ||
const operationProperty = operationToProperty({ operation, options }); | ||
operationsProperties.push(operationProperty); | ||
} | ||
} | ||
} | ||
|
||
const identifier = context.file({ id: FILE_ID })!.identifier({ | ||
$ref: OPERATIONS_IDENTIFIER, | ||
create: true, | ||
namespace: 'type', | ||
}); | ||
const paths = compiler.typeAliasDeclaration({ | ||
exportType: true, | ||
name: identifier.name || '', | ||
type: compiler.typeInterfaceNode({ | ||
properties: operationsProperties, | ||
useLegacyResolution: false, | ||
}), | ||
}); | ||
return paths; | ||
}; | ||
|
||
export const handler: PluginHandler<Config> = ({ context, plugin }) => { | ||
const file = context.createFile({ id: FILE_ID, path: plugin.output }); | ||
const options: SchemaToTypeOptions = { file }; | ||
file.import({ asType: true, module: 'fastify', name: ROUTE_HANDLER_NAME }); | ||
componentsToType({ | ||
context, | ||
options, | ||
}); | ||
file.add(pathsToType({ context, options })); | ||
}; | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import type { PluginName } from '../types'; | ||
|
||
export interface Config extends PluginName<'fastify'> { | ||
/** | ||
* Name of the generated file. | ||
* @default 'fastify' | ||
*/ | ||
output?: string; | ||
} | ||
|
||
export interface UserConfig extends Omit<Config, 'output'> {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.