···11+---
22+'@hey-api/openapi-ts': patch
33+---
44+55+fix: export IR types
+2-2
packages/openapi-ts/src/generate/files.ts
···5566import { compiler } from '../compiler';
77import { type ImportExportItemObject, tsNodeToString } from '../compiler/utils';
88-import type { IRContext } from '../ir/context';
88+import type { IR } from '../ir/types';
99import { ensureValidIdentifier } from '../openApi/shared/utils/identifier';
1010import type { StringCase } from '../types/config';
1111import { stringCase } from '../utils/stringCase';
···187187 context,
188188 id,
189189 }: {
190190- context: IRContext;
190190+ context: IR.Context;
191191 id: string;
192192 }): string {
193193 const file = context.file({ id });
+2-2
packages/openapi-ts/src/generate/output.ts
···11import path from 'node:path';
2233import { compiler } from '../compiler';
44-import type { IRContext } from '../ir/context';
54import { parseIR } from '../ir/parser';
55+import type { IR } from '../ir/types';
66import type { OpenApi } from '../openApi';
77import type { Client } from '../types/client';
88import type { Files } from '../types/utils';
···106106 });
107107};
108108109109-export const generateOutput = async ({ context }: { context: IRContext }) => {
109109+export const generateOutput = async ({ context }: { context: IR.Context }) => {
110110 const outputPath = path.resolve(context.config.output.path);
111111112112 if (context.config.output.clean) {
+4-4
packages/openapi-ts/src/index.ts
···7788import { generateLegacyOutput, generateOutput } from './generate/output';
99import { ensureDirSync } from './generate/utils';
1010-import type { IRContext } from './ir/context';
1010+import type { IR } from './ir/types';
1111import { parseExperimental, parseLegacy } from './openApi';
1212import type { ClientPlugins, UserPlugins } from './plugins';
1313import { defaultPluginConfigs } from './plugins';
···444444 Performance.end('spec');
445445446446 let client: Client | undefined;
447447- let context: IRContext | undefined;
447447+ let context: IR.Context | undefined;
448448449449 Performance.start('parser');
450450 if (
···550550 defineConfig,
551551};
552552553553-export type { OpenApiV3_0_X } from './openApi/3.0.x';
554554-export type { OpenApiV3_1_X } from './openApi/3.1.x';
553553+export type { IR } from './ir/types';
554554+export type { OpenApi } from './openApi/types';
555555export type { Plugin } from './plugins/types';
556556export type { UserConfig } from './types/config';
···11import type { JsonSchemaDraft2020_12 } from '../openApi/3.1.x/types/json-schema-draft-2020-12';
22import type { SecuritySchemeObject } from '../openApi/3.1.x/types/spec';
33+import type { IRContext } from './context';
34import type { IRMediaType } from './mediaType';
44-55-export interface IR {
66- components?: IRComponentsObject;
77- paths?: IRPathsObject;
88-}
95106interface IRComponentsObject {
117 parameters?: Record<string, IRParameterObject>;
···1713 [path: `/${string}`]: IRPathItemObject;
1814}
19152020-export interface IRPathItemObject {
1616+interface IRPathItemObject {
2117 delete?: IROperationObject;
2218 get?: IROperationObject;
2319 head?: IROperationObject;
···2824 trace?: IROperationObject;
2925}
30263131-export interface IROperationObject {
2727+interface IROperationObject {
3228 body?: IRBodyObject;
3329 deprecated?: boolean;
3430 description?: string;
···4440 tags?: ReadonlyArray<string>;
4541}
46424747-export interface IRBodyObject {
4343+interface IRBodyObject {
4844 mediaType: string;
4945 /**
5046 * Does body control pagination? We handle only simple values
···5652 type?: IRMediaType;
5753}
58545959-export interface IRParametersObject {
5555+interface IRParametersObject {
6056 cookie?: Record<string, IRParameterObject>;
6157 header?: Record<string, IRParameterObject>;
6258 path?: Record<string, IRParameterObject>;
6359 query?: Record<string, IRParameterObject>;
6460}
65616666-export interface IRParameterObject
6262+interface IRParameterObject
6763 extends Pick<JsonSchemaDraft2020_12, 'deprecated' | 'description'> {
6864 /**
6965 * Determines whether the parameter value SHOULD allow reserved characters, as defined by RFC3986 `:/?#[]@!$&'()*+,;=` to be included without percent-encoding. The default value is `false`. This property SHALL be ignored if the request body media type is not `application/x-www-form-urlencoded` or `multipart/form-data`. If a value is explicitly defined, then the value of `contentType` (implicit or explicit) SHALL be ignored.
···9894 | 'spaceDelimited';
9995}
10096101101-export interface IRRequestBodyObject
9797+interface IRRequestBodyObject
10298 extends Pick<JsonSchemaDraft2020_12, 'description'> {
10399 required?: boolean;
104100 schema: IRSchemaObject;
105101}
106102107107-export interface IRResponsesObject {
103103+interface IRResponsesObject {
108104 /**
109105 * Any {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#http-status-codes HTTP status code} can be used as the property name, but only one property per code, to describe the expected response for that HTTP status code. This field MUST be enclosed in quotation marks (for example, "200") for compatibility between JSON and YAML. To define a range of response codes, this field MAY contain the uppercase wildcard character `X`. For example, `2XX` represents all response codes between `[200-299]`. Only the following range definitions are allowed: `1XX`, `2XX`, `3XX`, `4XX`, and `5XX`. If a response is defined using an explicit code, the explicit code definition takes precedence over the range definition for that code.
110106 */
···115111 default?: IRResponseObject;
116112}
117113118118-export interface IRResponseObject {
114114+interface IRResponseObject {
119115 // TODO: parser - handle headers, links, and possibly other media types?
120116 mediaType?: string;
121117 schema: IRSchemaObject;
122118}
123119124124-export interface IRSchemaObject
120120+interface IRSchemaObject
125121 extends Pick<
126122 JsonSchemaDraft2020_12,
127123 | '$ref'
···187183 | 'unknown'
188184 | 'void';
189185}
186186+187187+interface IRModel {
188188+ components?: IRComponentsObject;
189189+ paths?: IRPathsObject;
190190+}
191191+192192+export namespace IR {
193193+ export type BodyObject = IRBodyObject;
194194+ export type ComponentsObject = IRComponentsObject;
195195+ export type Context<Spec extends Record<string, any> = any> = IRContext<Spec>;
196196+ export type Model = IRModel;
197197+ export type OperationObject = IROperationObject;
198198+ export type ParameterObject = IRParameterObject;
199199+ export type ParametersObject = IRParametersObject;
200200+ export type PathItemObject = IRPathItemObject;
201201+ export type PathsObject = IRPathsObject;
202202+ export type RequestBodyObject = IRRequestBodyObject;
203203+ export type ResponseObject = IRResponseObject;
204204+ export type ResponsesObject = IRResponsesObject;
205205+ export type SchemaObject = IRSchemaObject;
206206+}
+15-21
packages/openapi-ts/src/ir/operation.ts
···11-import type { IRContext } from './context';
22-import type { IRRequestBodyObject } from './ir';
33-import {
44- type IROperationObject,
55- type IRResponseObject,
66- type IRSchemaObject,
77-} from './ir';
81import type { Pagination } from './pagination';
92import {
103 hasParametersObjectRequired,
114 parameterWithPagination,
125} from './parameter';
136import { deduplicateSchema } from './schema';
77+import type { IR } from './types';
148import { addItemsToSchema } from './utils';
1591610export const hasOperationDataRequired = (
1717- operation: IROperationObject,
1111+ operation: IR.OperationObject,
1812): boolean => {
1913 if (hasParametersObjectRequired(operation.parameters)) {
2014 return true;
···3125 context,
3226 operation,
3327}: {
3434- context: IRContext;
3535- operation: IROperationObject;
2828+ context: IR.Context;
2929+ operation: IR.OperationObject;
3630}): Pagination | undefined => {
3731 if (operation.body?.pagination) {
3832 if (typeof operation.body.pagination === 'boolean') {
···4438 }
45394640 const schema = operation.body.schema.$ref
4747- ? context.resolveIrRef<IRRequestBodyObject | IRSchemaObject>(
4141+ ? context.resolveIrRef<IR.RequestBodyObject | IR.SchemaObject>(
4842 operation.body.schema.$ref,
4943 )
5044 : operation.body.schema;
···8882 /**
8983 * A deduplicated union of all error types. Unknown types are omitted.
9084 */
9191- error?: IRSchemaObject;
8585+ error?: IR.SchemaObject;
9286 /**
9387 * An object containing a map of status codes for each error type.
9488 */
9595- errors?: IRSchemaObject;
8989+ errors?: IR.SchemaObject;
9690 /**
9791 * A deduplicated union of all response types. Unknown types are omitted.
9892 */
9999- response?: IRSchemaObject;
9393+ response?: IR.SchemaObject;
10094 /**
10195 * An object containing a map of status codes for each response type.
10296 */
103103- responses?: IRSchemaObject;
9797+ responses?: IR.SchemaObject;
10498}
10599106100export const operationResponsesMap = (
107107- operation: IROperationObject,
101101+ operation: IR.OperationObject,
108102): OperationResponsesMap => {
109103 const result: OperationResponsesMap = {};
110104···112106 return result;
113107 }
114108115115- const errors: Omit<IRSchemaObject, 'properties'> &
116116- Pick<Required<IRSchemaObject>, 'properties'> = {
109109+ const errors: Omit<IR.SchemaObject, 'properties'> &
110110+ Pick<Required<IR.SchemaObject>, 'properties'> = {
117111 properties: {},
118112 type: 'object',
119113 };
120114121121- const responses: Omit<IRSchemaObject, 'properties'> &
122122- Pick<Required<IRSchemaObject>, 'properties'> = {
115115+ const responses: Omit<IR.SchemaObject, 'properties'> &
116116+ Pick<Required<IR.SchemaObject>, 'properties'> = {
123117 properties: {},
124118 type: 'object',
125119 };
126120127121 // store default response to be evaluated last
128128- let defaultResponse: IRResponseObject | undefined;
122122+ let defaultResponse: IR.ResponseObject | undefined;
129123130124 for (const name in operation.responses) {
131125 const response = operation.responses[name]!;
+2-2
packages/openapi-ts/src/ir/pagination.ts
···11-import type { IRSchemaObject } from './ir';
11+import type { IR } from './types';
2233export const paginationKeywordsRegExp =
44 /^(after|before|cursor|offset|page|start)$/;
···66export interface Pagination {
77 in: string;
88 name: string;
99- schema: IRSchemaObject;
99+ schema: IR.SchemaObject;
1010}
+4-4
packages/openapi-ts/src/ir/parameter.ts
···11-import type { IRParameterObject, IRParametersObject } from './ir';
21import type { Pagination } from './pagination';
22+import type { IR } from './types';
3344export const hasParameterGroupObjectRequired = (
55- parameterGroup?: Record<string, IRParameterObject>,
55+ parameterGroup?: Record<string, IR.ParameterObject>,
66): boolean => {
77 for (const name in parameterGroup) {
88 if (parameterGroup[name].required) {
···1414};
15151616export const hasParametersObjectRequired = (
1717- parameters: IRParametersObject | undefined,
1717+ parameters: IR.ParametersObject | undefined,
1818): boolean => {
1919 if (!parameters) {
2020 return false;
···4040};
41414242export const parameterWithPagination = (
4343- parameters: IRParametersObject | undefined,
4343+ parameters: IR.ParametersObject | undefined,
4444): Pagination | undefined => {
4545 if (!parameters) {
4646 return;
+4-5
packages/openapi-ts/src/ir/parser.ts
···11-import type { IRContext } from './context';
22-import type { IRPathItemObject, IRPathsObject } from './ir';
11+import type { IR } from './types';
3243/**
54 * Traverse the parsed intermediate representation model and broadcast
65 * various events to listeners.
76 */
88-export const parseIR = async ({ context }: { context: IRContext }) => {
77+export const parseIR = async ({ context }: { context: IR.Context }) => {
98 await context.broadcast('before');
1091110 if (context.ir.components) {
···2928 }
30293130 for (const path in context.ir.paths) {
3232- const pathItem = context.ir.paths[path as keyof IRPathsObject];
3131+ const pathItem = context.ir.paths[path as keyof IR.PathsObject];
33323433 for (const _method in pathItem) {
3535- const method = _method as keyof IRPathItemObject;
3434+ const method = _method as keyof IR.PathItemObject;
3635 const operation = pathItem[method]!;
3736 await context.broadcast('operation', { method, operation, path });
3837 }
+3-3
packages/openapi-ts/src/ir/schema.ts
···11-import type { IRSchemaObject } from './ir';
11+import type { IR } from './types';
2233/**
44 * Ensure we don't produce redundant types, e.g. string | string.
55 */
66-export const deduplicateSchema = <T extends IRSchemaObject>({
66+export const deduplicateSchema = <T extends IR.SchemaObject>({
77 schema,
88}: {
99 schema: T;
···1212 return schema;
1313 }
14141515- const uniqueItems: Array<IRSchemaObject> = [];
1515+ const uniqueItems: Array<IR.SchemaObject> = [];
1616 const typeIds: Array<string> = [];
17171818 for (const item of schema.items) {
+4-4
packages/openapi-ts/src/ir/utils.ts
···11-import type { IRSchemaObject } from './ir';
11+import type { IR } from './types';
2233/**
44 * Simply adds `items` to the schema. Also handles setting the logical operator
···1010 mutateSchemaOneItem = false,
1111 schema,
1212}: {
1313- items: Array<IRSchemaObject>;
1414- logicalOperator?: IRSchemaObject['logicalOperator'];
1313+ items: Array<IR.SchemaObject>;
1414+ logicalOperator?: IR.SchemaObject['logicalOperator'];
1515 mutateSchemaOneItem?: boolean;
1616- schema: IRSchemaObject;
1616+ schema: IR.SchemaObject;
1717}) => {
1818 if (!items.length) {
1919 return schema;
···11-import type { IROperationObject } from '../../../ir/ir';
11+import type { IR } from '../../../ir/types';
22import type { Operation } from '../../../types/client';
33import type { Plugin } from '../../types';
44···4444 */
4545 include?: string;
4646 /**
4747- * Customise the name of methods within the service. By default, {@link IROperationObject.id} or {@link Operation.name} is used.
4747+ * Customise the name of methods within the service. By default, {@link IR.OperationObject.id} or {@link Operation.name} is used.
4848 */
4949- methodNameBuilder?: (operation: IROperationObject | Operation) => string;
4949+ methodNameBuilder?: (operation: IR.OperationObject | Operation) => string;
5050 // TODO: parser - rename operationId option to something like inferId?: boolean
5151 /**
5252 * Use operation ID to generate operation names?
···11-// import type { IROperationObject, IRSchemaObject } from '../../ir/ir';
11+// import type { IR } from '../../ir/types';
22import type { Plugin } from '../types';
3344export interface Config extends Plugin.Name<'zod'> {
···66 * Customise the Zod schema name. By default, `z{{name}}` is used,
77 * where `name` is a definition name or an operation name.
88 */
99- // nameBuilder?: (model: IROperationObject | IRSchemaObject) => string;
99+ // nameBuilder?: (model: IR.OperationObject | IR.SchemaObject) => string;
1010 /**
1111 * Name of the generated file.
1212 * @default 'zod'