diff --git a/.changeset/green-shoes-wish.md b/.changeset/green-shoes-wish.md new file mode 100644 index 000000000..2cd4910ec --- /dev/null +++ b/.changeset/green-shoes-wish.md @@ -0,0 +1,5 @@ +--- +"@hey-api/spec-types": minor +--- + +**feat**: initial release diff --git a/.changeset/yellow-eagles-stare.md b/.changeset/yellow-eagles-stare.md new file mode 100644 index 000000000..7a40b681f --- /dev/null +++ b/.changeset/yellow-eagles-stare.md @@ -0,0 +1,6 @@ +--- +"@hey-api/openapi-ts": patch +"@hey-api/shared": patch +--- + +**internal**: add `@hey-api/spec-types` dependency diff --git a/packages/openapi-python/package.json b/packages/openapi-python/package.json index ce1ef5c10..f78356025 100644 --- a/packages/openapi-python/package.json +++ b/packages/openapi-python/package.json @@ -63,6 +63,7 @@ "@hey-api/codegen-core": "workspace:*", "@hey-api/json-schema-ref-parser": "workspace:*", "@hey-api/shared": "workspace:*", + "@hey-api/spec-types": "workspace:*", "@hey-api/types": "workspace:*", "ansi-colors": "4.1.3", "color-support": "1.1.3", diff --git a/packages/openapi-python/src/plugins/@hey-api/sdk/examples/types.ts b/packages/openapi-python/src/plugins/@hey-api/sdk/examples/types.ts index 1b3b4c52e..ab95c49cb 100644 --- a/packages/openapi-python/src/plugins/@hey-api/sdk/examples/types.ts +++ b/packages/openapi-python/src/plugins/@hey-api/sdk/examples/types.ts @@ -1,4 +1,5 @@ -import type { FeatureToggle, IR, LinguistLanguages } from '@hey-api/shared'; +import type { FeatureToggle, IR } from '@hey-api/shared'; +import type { LinguistLanguages } from '@hey-api/spec-types'; import type { MaybeFunc } from '@hey-api/types'; import type { CallArgs, DollarPyDsl, ExampleOptions } from '../../../../py-dsl'; diff --git a/packages/openapi-ts/package.json b/packages/openapi-ts/package.json index f95c0fdd6..6cbe4182d 100644 --- a/packages/openapi-ts/package.json +++ b/packages/openapi-ts/package.json @@ -72,6 +72,7 @@ "@hey-api/codegen-core": "workspace:*", "@hey-api/json-schema-ref-parser": "workspace:*", "@hey-api/shared": "workspace:*", + "@hey-api/spec-types": "workspace:*", "@hey-api/types": "workspace:*", "ansi-colors": "4.1.3", "color-support": "1.1.3", diff --git a/packages/openapi-ts/src/plugins/@hey-api/schemas/plugin.ts b/packages/openapi-ts/src/plugins/@hey-api/schemas/plugin.ts index 87b16ccb9..985c2ed54 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/schemas/plugin.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/schemas/plugin.ts @@ -1,11 +1,6 @@ -import type { - Context, - OpenApi, - OpenApiV2_0_XTypes, - OpenApiV3_0_XTypes, - OpenApiV3_1_XTypes, -} from '@hey-api/shared'; +import type { Context, OpenApi } from '@hey-api/shared'; import { satisfies } from '@hey-api/shared'; +import type { OpenAPIV2, OpenAPIV3, OpenAPIV3_1 } from '@hey-api/spec-types'; import { $ } from '../../../ts-dsl'; import type { HeyApiSchemasPlugin } from './types'; @@ -15,10 +10,7 @@ const stripSchema = ({ schema, }: { plugin: HeyApiSchemasPlugin['Instance']; - schema: - | OpenApiV2_0_XTypes['SchemaObject'] - | OpenApiV3_0_XTypes['SchemaObject'] - | OpenApiV3_1_XTypes['SchemaObject']; + schema: OpenAPIV2.SchemaObject | OpenAPIV3.SchemaObject | OpenAPIV3_1.SchemaObject; }) => { if (plugin.config.type === 'form') { if (schema.description) { @@ -50,8 +42,8 @@ const schemaToJsonSchemaDraft_04 = ({ }: { context: Context; plugin: HeyApiSchemasPlugin['Instance']; - schema: OpenApiV2_0_XTypes['SchemaObject']; -}): OpenApiV2_0_XTypes['SchemaObject'] => { + schema: OpenAPIV2.SchemaObject; +}): OpenAPIV2.SchemaObject => { if (Array.isArray(_schema)) { return _schema.map((item) => schemaToJsonSchemaDraft_04({ @@ -59,7 +51,7 @@ const schemaToJsonSchemaDraft_04 = ({ plugin, schema: item, }), - ) as unknown as OpenApiV2_0_XTypes['SchemaObject']; + ) as unknown as OpenAPIV2.SchemaObject; } const schema = structuredClone(_schema); @@ -95,7 +87,7 @@ const schemaToJsonSchemaDraft_04 = ({ schema.items = schemaToJsonSchemaDraft_04({ context, plugin, - schema: schema.items as OpenApiV2_0_XTypes['SchemaObject'], + schema: schema.items as OpenAPIV2.SchemaObject, }); } @@ -123,8 +115,8 @@ const schemaToJsonSchemaDraft_05 = ({ }: { context: Context; plugin: HeyApiSchemasPlugin['Instance']; - schema: OpenApiV3_0_XTypes['SchemaObject'] | OpenApiV3_0_XTypes['ReferenceObject']; -}): OpenApiV3_0_XTypes['SchemaObject'] | OpenApiV3_0_XTypes['ReferenceObject'] => { + schema: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject; +}): OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject => { if (Array.isArray(_schema)) { return _schema.map((item) => schemaToJsonSchemaDraft_05({ @@ -132,7 +124,7 @@ const schemaToJsonSchemaDraft_05 = ({ plugin, schema: item, }), - ) as unknown as OpenApiV3_0_XTypes['SchemaObject'] | OpenApiV3_0_XTypes['ReferenceObject']; + ) as unknown as OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject; } const schema = structuredClone(_schema); @@ -216,8 +208,8 @@ const schemaToJsonSchema2020_12 = ({ }: { context: Context; plugin: HeyApiSchemasPlugin['Instance']; - schema: OpenApiV3_1_XTypes['SchemaObject']; -}): OpenApiV3_1_XTypes['SchemaObject'] => { + schema: OpenAPIV3_1.SchemaObject; +}): OpenAPIV3_1.SchemaObject => { if (Array.isArray(_schema)) { return _schema.map((item) => schemaToJsonSchema2020_12({ @@ -225,7 +217,7 @@ const schemaToJsonSchema2020_12 = ({ plugin, schema: item, }), - ) as unknown as OpenApiV3_1_XTypes['SchemaObject']; + ) as unknown as OpenAPIV3_1.SchemaObject; } const schema = structuredClone(_schema); @@ -319,10 +311,10 @@ const schemaName = ({ name: string; plugin: HeyApiSchemasPlugin['Instance']; schema: - | OpenApiV2_0_XTypes['SchemaObject'] - | OpenApiV3_0_XTypes['ReferenceObject'] - | OpenApiV3_0_XTypes['SchemaObject'] - | OpenApiV3_1_XTypes['SchemaObject']; + | OpenAPIV2.SchemaObject + | OpenAPIV3.ReferenceObject + | OpenAPIV3.SchemaObject + | OpenAPIV3_1.SchemaObject; }): string => { let customName = ''; diff --git a/packages/openapi-ts/src/plugins/@hey-api/schemas/types.ts b/packages/openapi-ts/src/plugins/@hey-api/schemas/types.ts index d096c1918..b4e30118a 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/schemas/types.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/schemas/types.ts @@ -1,10 +1,5 @@ -import type { - DefinePlugin, - OpenApiV2_0_XTypes, - OpenApiV3_0_XTypes, - OpenApiV3_1_XTypes, - Plugin, -} from '@hey-api/shared'; +import type { DefinePlugin, Plugin } from '@hey-api/shared'; +import type { OpenAPIV2, OpenAPIV3, OpenAPIV3_1 } from '@hey-api/spec-types'; export type UserConfig = Plugin.Name<'@hey-api/schemas'> & Plugin.Hooks & @@ -21,10 +16,10 @@ export type UserConfig = Plugin.Name<'@hey-api/schemas'> & | (( name: string, schema: - | OpenApiV2_0_XTypes['SchemaObject'] - | OpenApiV3_0_XTypes['ReferenceObject'] - | OpenApiV3_0_XTypes['SchemaObject'] - | OpenApiV3_1_XTypes['SchemaObject'], + | OpenAPIV2.SchemaObject + | OpenAPIV3.ReferenceObject + | OpenAPIV3.SchemaObject + | OpenAPIV3_1.SchemaObject, ) => string); /** * Choose schema type to generate. Select 'form' if you don't want diff --git a/packages/openapi-ts/src/plugins/@hey-api/sdk/examples/types.ts b/packages/openapi-ts/src/plugins/@hey-api/sdk/examples/types.ts index 0bbe7ed26..7cf009755 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/sdk/examples/types.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/sdk/examples/types.ts @@ -1,4 +1,5 @@ -import type { FeatureToggle, IR, LinguistLanguages } from '@hey-api/shared'; +import type { FeatureToggle, IR } from '@hey-api/shared'; +import type { LinguistLanguages } from '@hey-api/spec-types'; import type { MaybeFunc } from '@hey-api/types'; import type { CallArgs, DollarTsDsl, ExampleOptions } from '../../../../ts-dsl'; diff --git a/packages/shared/package.json b/packages/shared/package.json index ba7a93397..a622afe0b 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -42,6 +42,7 @@ "dependencies": { "@hey-api/codegen-core": "workspace:*", "@hey-api/json-schema-ref-parser": "workspace:*", + "@hey-api/spec-types": "workspace:*", "@hey-api/types": "workspace:*", "ansi-colors": "4.1.3", "cross-spawn": "7.0.6", diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts index 096883981..4cf329cf6 100644 --- a/packages/shared/src/index.ts +++ b/packages/shared/src/index.ts @@ -79,20 +79,12 @@ export type { } from './ir/types'; export { addItemsToSchema } from './ir/utils'; export { parseOpenApiSpec } from './openApi'; -export type { OpenApiV2_0_X, OpenApiV2_0_XTypes } from './openApi/2.0.x'; export { parseV2_0_X } from './openApi/2.0.x'; -export type { OpenApiV3_0_X, OpenApiV3_0_XTypes } from './openApi/3.0.x'; export { parseV3_0_X } from './openApi/3.0.x'; -export type { OpenApiV3_1_X, OpenApiV3_1_XTypes } from './openApi/3.1.x'; export { parseV3_1_X } from './openApi/3.1.x'; export type { OperationsStrategy } from './openApi/shared/locations'; export type { OperationPathStrategy, OperationStructureStrategy } from './openApi/shared/locations'; export { OperationPath, OperationStrategy } from './openApi/shared/locations'; -export type { - CodeSampleObject, - EnumExtensions, - LinguistLanguages, -} from './openApi/shared/types/openapi-spec-extensions'; export { buildGraph } from './openApi/shared/utils/graph'; export { patchOpenApiSpec } from './openApi/shared/utils/patch'; export type { diff --git a/packages/shared/src/ir/intents.ts b/packages/shared/src/ir/intents.ts index b4ce24219..8a05689d8 100644 --- a/packages/shared/src/ir/intents.ts +++ b/packages/shared/src/ir/intents.ts @@ -1,6 +1,6 @@ +import type { CodeSampleObject } from '@hey-api/spec-types'; import type { MaybePromise } from '@hey-api/types'; -import type { CodeSampleObject } from '..//openApi/shared/types'; import type { IR } from './types'; export interface ExampleIntent { diff --git a/packages/shared/src/ir/types.ts b/packages/shared/src/ir/types.ts index cb895d4b0..b4a6c150b 100644 --- a/packages/shared/src/ir/types.ts +++ b/packages/shared/src/ir/types.ts @@ -1,23 +1,9 @@ /* eslint-disable @typescript-eslint/no-namespace */ import type { Symbol } from '@hey-api/codegen-core'; +import type { JSONSchemaDraft2020_12, OpenAPIExtensions, OpenAPIV3_1 } from '@hey-api/spec-types'; -import type { JsonSchemaDraft2020_12 } from '../openApi/3.1.x/types/json-schema-draft-2020-12'; -import type { - ReferenceObject as IRReferenceObject, - SecuritySchemeObject, - ServerObject, -} from '../openApi/3.1.x/types/spec'; import type { IRMediaType } from './mediaType'; -/** - * OpenAPI Specification Extensions. - * - * See {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#specification-extensions Specification Extensions}. - */ -export interface SpecificationExtensions { - [extension: `x-${string}`]: unknown; -} - interface IRBodyObject { mediaType: string; /** @@ -36,7 +22,7 @@ interface IRComponentsObject { schemas?: Record; } -export interface IROperationObject extends SpecificationExtensions { +export interface IROperationObject extends OpenAPIExtensions { body?: IRBodyObject; deprecated?: boolean; description?: string; @@ -60,7 +46,7 @@ export interface IRParametersObject { } export interface IRParameterObject - extends Pick, SpecificationExtensions { + extends Pick, OpenAPIExtensions { /** * 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. */ @@ -102,7 +88,7 @@ interface IRPathItemObject { trace?: IROperationObject; } -interface IRRequestBodyObject extends Pick { +interface IRRequestBodyObject extends Pick { required?: boolean; schema: IRSchemaObject; } @@ -127,7 +113,7 @@ interface IRResponseObject { export interface IRSchemaObject extends Pick< - JsonSchemaDraft2020_12, + JSONSchemaDraft2020_12.Document, | '$ref' | 'const' | 'default' @@ -146,7 +132,7 @@ export interface IRSchemaObject | 'title' | 'example' >, - SpecificationExtensions { + OpenAPIExtensions { /** * If the schema is intended to be used as an object property, it can be * marked as read-only or write-only. This value controls whether the schema @@ -162,7 +148,7 @@ export interface IRSchemaObject /** * Any string value is accepted as `format`. */ - format?: JsonSchemaDraft2020_12['format'] | 'binary' | 'integer'; + format?: JSONSchemaDraft2020_12.Document['format'] | 'binary' | 'integer'; /** * If schema resolves into multiple items instead of a simple `type`, they * will be included in `items` array. @@ -219,10 +205,10 @@ export interface IRSchemaObject | 'void'; } -type IRSecurityObject = SecuritySchemeObject; +type IRSecurityObject = OpenAPIV3_1.SecuritySchemeObject; // eslint-disable-next-line @typescript-eslint/no-empty-object-type -- Interface rather than type alias avoids TS4023 errors when bundled dist is consumed by tsgo/TypeScript 7 -export interface IRServerObject extends ServerObject {} +export interface IRServerObject extends OpenAPIV3_1.ServerObject {} type IRWebhookObject = IRPathItemObject; @@ -242,7 +228,7 @@ export namespace IR { export type ParametersObject = IRParametersObject; export type PathItemObject = IRPathItemObject; export type PathsObject = IRPathsObject; - export type ReferenceObject = IRReferenceObject; + export type ReferenceObject = OpenAPIV3_1.ReferenceObject; export type RequestBodyObject = IRRequestBodyObject; export type ResponseObject = IRResponseObject; export type ResponsesObject = IRResponsesObject; diff --git a/packages/shared/src/openApi/2.0.x/index.ts b/packages/shared/src/openApi/2.0.x/index.ts index 2f22a55b7..20f6103d9 100644 --- a/packages/shared/src/openApi/2.0.x/index.ts +++ b/packages/shared/src/openApi/2.0.x/index.ts @@ -1,10 +1 @@ export { parseV2_0_X } from './parser'; -export type { OpenApiV2_0_X } from './types/spec'; - -import type { InfoObject, OperationObject, SchemaObject } from './types/spec'; - -export interface OpenApiV2_0_XTypes { - InfoObject: InfoObject; - OperationObject: OperationObject; - SchemaObject: SchemaObject; -} diff --git a/packages/shared/src/openApi/2.0.x/parser/__tests__/operation.test.ts b/packages/shared/src/openApi/2.0.x/parser/__tests__/operation.test.ts index db42f474e..9d2d90be6 100644 --- a/packages/shared/src/openApi/2.0.x/parser/__tests__/operation.test.ts +++ b/packages/shared/src/openApi/2.0.x/parser/__tests__/operation.test.ts @@ -1,5 +1,6 @@ +import type { OpenAPIV2 } from '@hey-api/spec-types'; + import type { Context } from '../../../../ir/context'; -import type { ParameterObject, SecuritySchemeObject } from '../../types/spec'; import { parsePathOperation } from '../operation'; type ParseOperationProps = Parameters[0]; @@ -48,7 +49,7 @@ describe('operation', () => { summary: 'Test Operation', }; const path = '/test'; - const securitySchemesMap = new Map([ + const securitySchemesMap = new Map([ ['apiKeyAuth', { in: 'header', name: 'Auth', type: 'apiKey' }], ['basicAuthRule', { description: 'Basic Auth', type: 'basic' }], [ @@ -107,7 +108,7 @@ describe('operation', () => { it('should parse body parameter when consumes is undefined', () => { const context = createContext(); const method = 'post'; - const bodyParam: ParameterObject = { + const bodyParam: OpenAPIV2.ParameterObject = { description: 'Request body', in: 'body', name: 'body', @@ -132,7 +133,7 @@ describe('operation', () => { summary: 'Create an item', }; const path = '/items'; - const securitySchemesMap = new Map(); + const securitySchemesMap = new Map(); const state: ParseOperationProps['state'] = { ids: new Map(), }; @@ -157,7 +158,7 @@ describe('operation', () => { it('should parse body parameter with array schema', () => { const context = createContext(); const method = 'post'; - const bodyParam: ParameterObject = { + const bodyParam: OpenAPIV2.ParameterObject = { description: 'add items', in: 'body', name: 'request', @@ -183,7 +184,7 @@ describe('operation', () => { }, }; const path = '/api/v1/items'; - const securitySchemesMap = new Map(); + const securitySchemesMap = new Map(); const state: ParseOperationProps['state'] = { ids: new Map(), }; @@ -208,7 +209,7 @@ describe('operation', () => { it('should use consumes when specified', () => { const context = createContext(); const method = 'post'; - const bodyParam: ParameterObject = { + const bodyParam: OpenAPIV2.ParameterObject = { description: 'XML body', in: 'body', name: 'body', @@ -228,7 +229,7 @@ describe('operation', () => { }, }; const path = '/items'; - const securitySchemesMap = new Map(); + const securitySchemesMap = new Map(); const state: ParseOperationProps['state'] = { ids: new Map(), }; diff --git a/packages/shared/src/openApi/2.0.x/parser/filter.ts b/packages/shared/src/openApi/2.0.x/parser/filter.ts index 39851997b..800df7c7c 100644 --- a/packages/shared/src/openApi/2.0.x/parser/filter.ts +++ b/packages/shared/src/openApi/2.0.x/parser/filter.ts @@ -1,9 +1,9 @@ import type { Logger } from '@hey-api/codegen-core'; +import type { OpenAPIV2 } from '@hey-api/spec-types'; import { createOperationKey } from '../../../ir/operation'; import { addNamespace, removeNamespace } from '../../../openApi/shared/utils/filter'; import { httpMethods } from '../../../openApi/shared/utils/operation'; -import type { OpenApiV2_0_X, OperationObject, PathItemObject, PathsObject } from '../types/spec'; /** * Replace source spec with filtered version. @@ -22,7 +22,7 @@ export const filterSpec = ({ requestBodies: Set; responses: Set; schemas: Set; - spec: OpenApiV2_0_X; + spec: OpenAPIV2.Document; }) => { const eventFilterSpec = logger.timeEvent('filter-spec'); if (spec.definitions) { @@ -49,12 +49,12 @@ export const filterSpec = ({ if (spec.paths) { for (const entry of Object.entries(spec.paths)) { - const path = entry[0] as keyof PathsObject; - const pathItem = entry[1] as PathItemObject; + const path = entry[0] as keyof OpenAPIV2.PathsObject; + const pathItem = entry[1] as OpenAPIV2.PathItemObject; for (const method of httpMethods) { // @ts-expect-error - const operation = pathItem[method] as OperationObject; + const operation = pathItem[method] as OpenAPIV2.OperationObject; if (!operation) { continue; } diff --git a/packages/shared/src/openApi/2.0.x/parser/index.ts b/packages/shared/src/openApi/2.0.x/parser/index.ts index af6705e82..2679449d8 100644 --- a/packages/shared/src/openApi/2.0.x/parser/index.ts +++ b/packages/shared/src/openApi/2.0.x/parser/index.ts @@ -1,3 +1,5 @@ +import type { OpenAPIV2 } from '@hey-api/spec-types'; + import type { Context } from '../../../ir/context'; import { buildResourceMetadata } from '../../../openApi/shared/graph/meta'; import { transformOpenApiSpec } from '../../../openApi/shared/transforms'; @@ -10,13 +12,6 @@ import { import { buildGraph } from '../../../openApi/shared/utils/graph'; import { mergeParametersObjects } from '../../../openApi/shared/utils/parameter'; import { handleValidatorResult } from '../../../openApi/shared/utils/validator'; -import type { - OpenApiV2_0_X, - OperationObject, - PathItemObject, - PathsObject, - SecuritySchemeObject, -} from '../types/spec'; import { filterSpec } from './filter'; import { parsePathOperation } from './operation'; import { parametersArrayToObject } from './parameter'; @@ -24,13 +19,10 @@ import { parseSchema } from './schema'; import { parseServers } from './server'; import { validateOpenApiSpec } from './validate'; -type PathKeys = keyof T extends infer K - ? K extends `/${string}` - ? K - : never - : never; +type PathKeys = + keyof T extends infer K ? (K extends `/${string}` ? K : never) : never; -export const parseV2_0_X = (context: Context) => { +export const parseV2_0_X = (context: Context) => { if (context.config.parser.validate_EXPERIMENTAL) { const result = validateOpenApiSpec(context.spec, context.logger); handleValidatorResult({ context, result }); @@ -59,7 +51,7 @@ export const parseV2_0_X = (context: Context) => { const state: State = { ids: new Map(), }; - const securitySchemesMap = new Map(); + const securitySchemesMap = new Map(); for (const name in context.spec.securityDefinitions) { const securitySchemeObject = context.spec.securityDefinitions[name]!; @@ -87,12 +79,12 @@ export const parseV2_0_X = (context: Context) => { const finalPathItem = pathItem.$ref ? { - ...context.resolveRef(pathItem.$ref), + ...context.resolveRef(pathItem.$ref), ...pathItem, } : pathItem; - const commonOperation: OperationObject = { + const commonOperation: OpenAPIV2.OperationObject = { consumes: context.spec.consumes, produces: context.spec.produces, responses: {}, diff --git a/packages/shared/src/openApi/2.0.x/parser/mediaType.ts b/packages/shared/src/openApi/2.0.x/parser/mediaType.ts index 22e2846c6..77fccfabf 100644 --- a/packages/shared/src/openApi/2.0.x/parser/mediaType.ts +++ b/packages/shared/src/openApi/2.0.x/parser/mediaType.ts @@ -1,14 +1,19 @@ +import type { OpenAPIV2 } from '@hey-api/spec-types'; + import type { IRMediaType } from '../../../ir/mediaType'; import { isMediaTypeFileLike, mediaTypeToIrMediaType } from '../../../ir/mediaType'; -import type { ReferenceObject, ResponseObject, SchemaObject } from '../types/spec'; interface Content { mediaType: string; - schema: SchemaObject | ReferenceObject | undefined; + schema: OpenAPIV2.SchemaObject | OpenAPIV2.ReferenceObject | undefined; type: IRMediaType | undefined; } -export const contentToSchema = ({ content }: { content: Content }): SchemaObject | undefined => { +export const contentToSchema = ({ + content, +}: { + content: Content; +}): OpenAPIV2.SchemaObject | undefined => { const { mediaType, schema } = content; if (schema && '$ref' in schema) { @@ -42,7 +47,7 @@ export const mediaTypeObjects = ({ response, }: { mimeTypes: ReadonlyArray | undefined; - response: Pick; + response: Pick; }): ReadonlyArray => { const objects: Array = []; diff --git a/packages/shared/src/openApi/2.0.x/parser/operation.ts b/packages/shared/src/openApi/2.0.x/parser/operation.ts index 3489ccd74..8a235c62b 100644 --- a/packages/shared/src/openApi/2.0.x/parser/operation.ts +++ b/packages/shared/src/openApi/2.0.x/parser/operation.ts @@ -1,22 +1,16 @@ +import type { OpenAPIV2 } from '@hey-api/spec-types'; + import type { Context } from '../../../ir/context'; import type { IR } from '../../../ir/types'; import type { State } from '../../../openApi/shared/types/state'; import { operationToId } from '../../../openApi/shared/utils/operation'; -import type { - OperationObject, - ParameterObject, - PathItemObject, - ResponseObject, - SchemaObject, - SecuritySchemeObject, -} from '../types/spec'; import { contentToSchema, mediaTypeObjects } from './mediaType'; import { paginationField } from './pagination'; import { parseExtensions, schemaToIrSchema } from './schema'; interface Operation - extends Omit, Pick { - requestBody?: OperationObject['parameters']; + extends Omit, Pick { + requestBody?: OpenAPIV2.OperationObject['parameters']; } const parseOperationJsDoc = ({ @@ -93,7 +87,7 @@ const operationToIrOperation = ({ }: Pick & { context: Context; operation: Operation; - securitySchemesMap: Map; + securitySchemesMap: Map; state: State; }): IR.OperationObject => { const irOperation = initIrOperation({ @@ -121,16 +115,17 @@ const operationToIrOperation = ({ // Check if there are any body parameters (not formData) to determine default media type const hasBodyParameter = operation.requestBody?.some((param) => { - const resolvedParam = '$ref' in param ? context.resolveRef(param.$ref) : param; + const resolvedParam = + '$ref' in param ? context.resolveRef(param.$ref) : param; return resolvedParam.in === 'body'; }); for (const requestBodyParameter of operation.requestBody ?? []) { const requestBody = '$ref' in requestBodyParameter - ? context.resolveRef(requestBodyParameter.$ref) + ? context.resolveRef(requestBodyParameter.$ref) : requestBodyParameter; - const schema: SchemaObject = + const schema: OpenAPIV2.SchemaObject = requestBody.in === 'body' ? requestBody.schema : { @@ -242,7 +237,7 @@ const operationToIrOperation = ({ const response = operation.responses[name]!; const responseObject = - '$ref' in response ? context.resolveRef(response.$ref) : response; + '$ref' in response ? context.resolveRef(response.$ref) : response; const contents = mediaTypeObjects({ // assume JSON by default mimeTypes: operation.produces ? operation.produces : ['application/json'], @@ -365,12 +360,12 @@ export const parsePathOperation = ({ }: { context: Context; method: Extract< - keyof PathItemObject, + keyof OpenAPIV2.PathItemObject, 'delete' | 'get' | 'head' | 'options' | 'patch' | 'post' | 'put' | 'trace' >; operation: Operation; path: keyof IR.PathsObject; - securitySchemesMap: Map; + securitySchemesMap: Map; state: State; }) => { if (!context.ir.paths) { diff --git a/packages/shared/src/openApi/2.0.x/parser/pagination.ts b/packages/shared/src/openApi/2.0.x/parser/pagination.ts index 616783dee..254c5fd45 100644 --- a/packages/shared/src/openApi/2.0.x/parser/pagination.ts +++ b/packages/shared/src/openApi/2.0.x/parser/pagination.ts @@ -1,11 +1,11 @@ +import type { OpenAPIV2 } from '@hey-api/spec-types'; + import type { Context } from '../../../ir/context'; import { getPaginationKeywordsRegExp } from '../../../ir/pagination'; import type { SchemaType } from '../../../openApi/shared/types/schema'; -import type { ParameterObject, ReferenceObject } from '../types/spec'; -import type { SchemaObject } from '../types/spec'; import { getSchemaType } from './schema'; -const isPaginationType = (schemaType: SchemaType | undefined): boolean => +const isPaginationType = (schemaType: SchemaType | undefined): boolean => schemaType === 'boolean' || schemaType === 'integer' || schemaType === 'number' || @@ -20,9 +20,9 @@ export const paginationField = ({ context: Context; name: string; schema: - | ParameterObject - | SchemaObject - | ReferenceObject + | OpenAPIV2.ParameterObject + | OpenAPIV2.SchemaObject + | OpenAPIV2.ReferenceObject | { in: undefined; }; @@ -33,7 +33,9 @@ export const paginationField = ({ } if ('$ref' in schema) { - const ref = context.resolveRef(schema.$ref ?? ''); + const ref = context.resolveRef( + schema.$ref ?? '', + ); if ('in' in ref && ref.in) { const refSchema = diff --git a/packages/shared/src/openApi/2.0.x/parser/parameter.ts b/packages/shared/src/openApi/2.0.x/parser/parameter.ts index 34c13ce12..9a60daef6 100644 --- a/packages/shared/src/openApi/2.0.x/parser/parameter.ts +++ b/packages/shared/src/openApi/2.0.x/parser/parameter.ts @@ -1,15 +1,11 @@ +import type { OpenAPIV2 } from '@hey-api/spec-types'; + import type { Context } from '../../../ir/context'; import type { IR } from '../../../ir/types'; -import type { - OperationObject, - ParameterObject, - ReferenceObject, - SchemaObject, -} from '../types/spec'; import { paginationField } from './pagination'; import { parseExtensions, schemaToIrSchema } from './schema'; -type Parameter = Exclude; +type Parameter = Exclude; /** * Returns default parameter `explode` based on value of `collectionFormat`. @@ -47,8 +43,8 @@ export const parametersArrayToObject = ({ parameters, }: { context: Context; - operation: OperationObject; - parameters?: ReadonlyArray; + operation: OpenAPIV2.OperationObject; + parameters?: ReadonlyArray; }): IR.ParametersObject | undefined => { if (!parameters || !Object.keys(parameters).length) { return; @@ -59,7 +55,7 @@ export const parametersArrayToObject = ({ for (const parameterOrReference of parameters) { const parameter = '$ref' in parameterOrReference - ? context.dereference(parameterOrReference) + ? context.dereference(parameterOrReference) : parameterOrReference; // push request body parameters into a separate field @@ -101,7 +97,7 @@ const parameterToIrParameter = ({ }): IR.ParameterObject => { const schema = parameter; - const finalSchema: SchemaObject = + const finalSchema: OpenAPIV2.SchemaObject = schema && '$ref' in schema ? { allOf: [ @@ -109,7 +105,7 @@ const parameterToIrParameter = ({ ...schema, $ref: schema.$ref as string, required: Array.isArray(schema.required) ? schema.required : [], - type: schema.type as SchemaObject['type'], + type: schema.type as OpenAPIV2.SchemaObject['type'], }, ], description: parameter.description, @@ -118,7 +114,7 @@ const parameterToIrParameter = ({ description: parameter.description, ...schema, required: Array.isArray(schema.required) ? schema.required : [], - type: schema.type as SchemaObject['type'], + type: schema.type as OpenAPIV2.SchemaObject['type'], }; const pagination = paginationField({ diff --git a/packages/shared/src/openApi/2.0.x/parser/schema.ts b/packages/shared/src/openApi/2.0.x/parser/schema.ts index d3f2cf55c..127220265 100644 --- a/packages/shared/src/openApi/2.0.x/parser/schema.ts +++ b/packages/shared/src/openApi/2.0.x/parser/schema.ts @@ -1,3 +1,5 @@ +import type { OpenAPIV2 } from '@hey-api/spec-types'; + import type { Context } from '../../../ir/context'; import type { IR } from '../../../ir/types'; import { addItemsToSchema } from '../../../ir/utils'; @@ -8,13 +10,12 @@ import type { } from '../../../openApi/shared/types/schema'; import { discriminatorValues } from '../../../openApi/shared/utils/discriminator'; import { isTopLevelComponent, refToName } from '../../../utils/ref'; -import type { SchemaObject } from '../types/spec'; export const getSchemaType = ({ schema, }: { - schema: SchemaObject; -}): SchemaType | undefined => { + schema: OpenAPIV2.SchemaObject; +}): SchemaType | undefined => { if (schema.type) { return schema.type; } @@ -32,7 +33,7 @@ const parseSchemaJsDoc = ({ schema, }: { irSchema: IR.SchemaObject; - schema: SchemaObject; + schema: OpenAPIV2.SchemaObject; }) => { if (schema.example) { irSchema.example = schema.example; @@ -52,7 +53,7 @@ const parseSchemaMeta = ({ schema, }: { irSchema: IR.SchemaObject; - schema: SchemaObject; + schema: OpenAPIV2.SchemaObject; }) => { if (schema.default !== undefined) { irSchema.default = schema.default; @@ -111,7 +112,7 @@ const parseArray = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: SchemaObject; + schema: OpenAPIV2.SchemaObject; state: SchemaState; }): IR.SchemaObject => { if (schema.maxItems && schema.maxItems === schema.minItems) { @@ -162,7 +163,7 @@ const parseBoolean = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: SchemaObject; + schema: OpenAPIV2.SchemaObject; state: SchemaState; }): IR.SchemaObject => { irSchema.type = 'boolean'; @@ -176,7 +177,7 @@ const parseNumber = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: SchemaWithRequired; + schema: SchemaWithRequired; state: SchemaState; }): IR.SchemaObject => { irSchema.type = schema.type; @@ -192,7 +193,7 @@ const parseObject = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: SchemaObject; + schema: OpenAPIV2.SchemaObject; state: SchemaState; }): IR.SchemaObject => { irSchema.type = 'object'; @@ -257,7 +258,7 @@ const parseString = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: SchemaObject; + schema: OpenAPIV2.SchemaObject; state: SchemaState; }): IR.SchemaObject => { irSchema.type = 'string'; @@ -273,7 +274,7 @@ export const parseExtensions = ({ source, target }: { source: object; target: ob } }; -const initIrSchema = ({ schema }: { schema: SchemaObject }): IR.SchemaObject => { +const initIrSchema = ({ schema }: { schema: OpenAPIV2.SchemaObject }): IR.SchemaObject => { const irSchema: IR.SchemaObject = {}; parseSchemaJsDoc({ @@ -295,7 +296,7 @@ const parseAllOf = ({ state, }: { context: Context; - schema: SchemaWithRequired; + schema: SchemaWithRequired; state: SchemaState; }): IR.SchemaObject => { let irSchema = initIrSchema({ schema }); @@ -332,7 +333,7 @@ const parseAllOf = ({ schemaItems.push(irCompositionSchema); if (compositionSchema.$ref) { - const ref = context.resolveRef(compositionSchema.$ref); + const ref = context.resolveRef(compositionSchema.$ref); // `$ref` should be passed from the root `parseSchema()` call if (ref.discriminator && state.$ref) { const values = discriminatorValues(state.$ref); @@ -376,7 +377,7 @@ const parseAllOf = ({ for (const compositionSchema of compositionSchemas) { // TODO: parser - this could be probably resolved more accurately const finalCompositionSchema = compositionSchema.$ref - ? context.resolveRef(compositionSchema.$ref) + ? context.resolveRef(compositionSchema.$ref) : compositionSchema; if (getSchemaType({ schema: finalCompositionSchema }) === 'object') { @@ -448,7 +449,7 @@ const parseEnum = ({ state, }: { context: Context; - schema: SchemaWithRequired; + schema: SchemaWithRequired; state: SchemaState; }): IR.SchemaObject => { let irSchema = initIrSchema({ schema }); @@ -459,7 +460,7 @@ const parseEnum = ({ for (const [index, enumValue] of schema.enum.entries()) { const typeOfEnumValue = typeof enumValue; - let enumType: SchemaType | 'null' | undefined; + let enumType: SchemaType | 'null' | undefined; if ( typeOfEnumValue === 'string' || @@ -525,7 +526,7 @@ const parseRef = ({ state, }: { context: Context; - schema: SchemaWithRequired; + schema: SchemaWithRequired; state: SchemaState; }): IR.SchemaObject => { const irSchema: IR.SchemaObject = {}; @@ -534,7 +535,7 @@ const parseRef = ({ const isComponentsRef = isTopLevelComponent(schema.$ref); if (!isComponentsRef) { if (!state.circularReferenceTracker.has(schema.$ref)) { - const refSchema = context.resolveRef(schema.$ref); + const refSchema = context.resolveRef(schema.$ref); const originalRef = state.$ref; state.$ref = schema.$ref; const irSchema = schemaToIrSchema({ @@ -557,7 +558,7 @@ const parseRef = ({ irSchema.$ref = irSchema.$ref.replace(/#\/definitions\/([^/]+)/g, '#/components/schemas/$1'); if (!state.circularReferenceTracker.has(schema.$ref)) { - const refSchema = context.resolveRef(schema.$ref); + const refSchema = context.resolveRef(schema.$ref); const originalRef = state.$ref; state.$ref = schema.$ref; schemaToIrSchema({ @@ -579,7 +580,7 @@ const parseNullableType = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: SchemaWithRequired; + schema: SchemaWithRequired; state: SchemaState; }): IR.SchemaObject => { if (!irSchema) { @@ -622,7 +623,7 @@ const parseType = ({ state, }: { context: Context; - schema: SchemaWithRequired; + schema: SchemaWithRequired; state: SchemaState; }): IR.SchemaObject => { const irSchema = initIrSchema({ schema }); @@ -666,7 +667,7 @@ const parseOneType = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: SchemaWithRequired; + schema: SchemaWithRequired; state: SchemaState; }): IR.SchemaObject => { if (!irSchema) { @@ -728,7 +729,7 @@ const parseUnknown = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: SchemaObject; + schema: OpenAPIV2.SchemaObject; }): IR.SchemaObject => { if (!irSchema) { irSchema = initIrSchema({ schema }); @@ -747,7 +748,7 @@ export const schemaToIrSchema = ({ state, }: { context: Context; - schema: SchemaObject; + schema: OpenAPIV2.SchemaObject; state: SchemaState | undefined; }): IR.SchemaObject => { if (!state) { @@ -763,7 +764,7 @@ export const schemaToIrSchema = ({ if (schema.$ref) { return parseRef({ context, - schema: schema as SchemaWithRequired, + schema: schema as SchemaWithRequired, state, }); } @@ -771,7 +772,7 @@ export const schemaToIrSchema = ({ if (schema.enum) { return parseEnum({ context, - schema: schema as SchemaWithRequired, + schema: schema as SchemaWithRequired, state, }); } @@ -779,7 +780,7 @@ export const schemaToIrSchema = ({ if (schema.allOf) { return parseAllOf({ context, - schema: schema as SchemaWithRequired, + schema: schema as SchemaWithRequired, state, }); } @@ -788,7 +789,7 @@ export const schemaToIrSchema = ({ if (schema.type || schema.properties) { return parseType({ context, - schema: schema as SchemaWithRequired, + schema: schema as SchemaWithRequired, state, }); } @@ -803,7 +804,7 @@ export const parseSchema = ({ }: { $ref: string; context: Context; - schema: SchemaObject; + schema: OpenAPIV2.SchemaObject; }) => { if (!context.ir.components) { context.ir.components = {}; diff --git a/packages/shared/src/openApi/2.0.x/parser/validate.ts b/packages/shared/src/openApi/2.0.x/parser/validate.ts index 76fa60fd1..ab5c26348 100644 --- a/packages/shared/src/openApi/2.0.x/parser/validate.ts +++ b/packages/shared/src/openApi/2.0.x/parser/validate.ts @@ -1,19 +1,19 @@ import type { Logger } from '@hey-api/codegen-core'; +import type { OpenAPIV2 } from '@hey-api/spec-types'; import { createOperationKey } from '../../../ir/operation'; import { httpMethods } from '../../../openApi/shared/utils/operation'; import type { ValidatorIssue, ValidatorResult } from '../../../openApi/shared/utils/validator'; -import type { OpenApiV2_0_X, PathItemObject, PathsObject } from '../types/spec'; -export const validateOpenApiSpec = (spec: OpenApiV2_0_X, logger: Logger): ValidatorResult => { +export const validateOpenApiSpec = (spec: OpenAPIV2.Document, logger: Logger): ValidatorResult => { const eventValidate = logger.timeEvent('validate'); const issues: Array = []; const operationIds = new Map(); if (spec.paths) { for (const entry of Object.entries(spec.paths)) { - const path = entry[0] as keyof PathsObject; - const pathItem = entry[1] as PathItemObject; + const path = entry[0] as keyof OpenAPIV2.PathsObject; + const pathItem = entry[1] as OpenAPIV2.PathItemObject; for (const method of httpMethods) { if (method === 'trace') { continue; diff --git a/packages/shared/src/openApi/3.0.x/index.ts b/packages/shared/src/openApi/3.0.x/index.ts index 3e7bcad5b..42f29f1b3 100644 --- a/packages/shared/src/openApi/3.0.x/index.ts +++ b/packages/shared/src/openApi/3.0.x/index.ts @@ -1,22 +1 @@ export { parseV3_0_X } from './parser'; -export type { OpenApiV3_0_X } from './types/spec'; - -import type { - InfoObject, - OperationObject, - ParameterObject, - ReferenceObject, - RequestBodyObject, - ResponseObject, - SchemaObject, -} from './types/spec'; - -export interface OpenApiV3_0_XTypes { - InfoObject: InfoObject; - OperationObject: OperationObject; - ParameterObject: ParameterObject; - ReferenceObject: ReferenceObject; - RequestBodyObject: RequestBodyObject; - ResponseObject: ResponseObject; - SchemaObject: SchemaObject; -} diff --git a/packages/shared/src/openApi/3.0.x/parser/__tests__/operation.test.ts b/packages/shared/src/openApi/3.0.x/parser/__tests__/operation.test.ts index 47b72ed59..d88a416e6 100644 --- a/packages/shared/src/openApi/3.0.x/parser/__tests__/operation.test.ts +++ b/packages/shared/src/openApi/3.0.x/parser/__tests__/operation.test.ts @@ -1,5 +1,6 @@ +import type { OpenAPIV3 } from '@hey-api/spec-types'; + import type { Context } from '../../../../ir/context'; -import type { SecuritySchemeObject } from '../../types/spec'; import { parsePathOperation } from '../operation'; type ParseOperationProps = Parameters[0]; @@ -38,7 +39,7 @@ describe('operation', () => { }; const path = '/test'; - const oauth2: SecuritySchemeObject = { + const oauth2: OpenAPIV3.SecuritySchemeObject = { description: 'OAuth2', flows: { password: { @@ -51,7 +52,7 @@ describe('operation', () => { }, type: 'oauth2', }; - const securitySchemesMap = new Map([ + const securitySchemesMap = new Map([ ['apiKeyAuth', { in: 'header', name: 'Auth', type: 'apiKey' }], ['basicAuthRule', { description: 'Basic Auth', scheme: 'basic', type: 'http' }], ['oauthRule', oauth2], diff --git a/packages/shared/src/openApi/3.0.x/parser/filter.ts b/packages/shared/src/openApi/3.0.x/parser/filter.ts index 5c12d5540..949280d92 100644 --- a/packages/shared/src/openApi/3.0.x/parser/filter.ts +++ b/packages/shared/src/openApi/3.0.x/parser/filter.ts @@ -1,9 +1,9 @@ import type { Logger } from '@hey-api/codegen-core'; +import type { OpenAPIV3 } from '@hey-api/spec-types'; import { createOperationKey } from '../../../ir/operation'; import { addNamespace, removeNamespace } from '../../../openApi/shared/utils/filter'; import { httpMethods } from '../../../openApi/shared/utils/operation'; -import type { OpenApiV3_0_X, PathItemObject, PathsObject } from '../types/spec'; /** * Replace source spec with filtered version. @@ -25,7 +25,7 @@ export const filterSpec = ({ requestBodies: Set; responses: Set; schemas: Set; - spec: OpenApiV3_0_X; + spec: OpenAPIV3.Document; }) => { const eventFilterSpec = logger.timeEvent('filter-spec'); if (spec.components) { @@ -120,8 +120,8 @@ export const filterSpec = ({ if (spec.paths) { for (const entry of Object.entries(spec.paths)) { - const path = entry[0] as keyof PathsObject; - const pathItem = entry[1] as PathItemObject; + const path = entry[0] as keyof OpenAPIV3.PathsObject; + const pathItem = entry[1] as OpenAPIV3.PathItemObject; for (const method of httpMethods) { const operation = pathItem[method]; diff --git a/packages/shared/src/openApi/3.0.x/parser/index.ts b/packages/shared/src/openApi/3.0.x/parser/index.ts index 582e72a02..d9d60fa4e 100644 --- a/packages/shared/src/openApi/3.0.x/parser/index.ts +++ b/packages/shared/src/openApi/3.0.x/parser/index.ts @@ -1,3 +1,5 @@ +import type { OpenAPIV3 } from '@hey-api/spec-types'; + import type { Context } from '../../../ir/context'; import { buildResourceMetadata } from '../../../openApi/shared/graph/meta'; import { transformOpenApiSpec } from '../../../openApi/shared/transforms'; @@ -10,14 +12,6 @@ import { import { buildGraph } from '../../../openApi/shared/utils/graph'; import { mergeParametersObjects } from '../../../openApi/shared/utils/parameter'; import { handleValidatorResult } from '../../../openApi/shared/utils/validator'; -import type { - OpenApiV3_0_X, - ParameterObject, - PathItemObject, - PathsObject, - RequestBodyObject, - SecuritySchemeObject, -} from '../types/spec'; import { filterSpec } from './filter'; import { parsePathOperation } from './operation'; import { parametersArrayToObject, parseParameter } from './parameter'; @@ -26,7 +20,7 @@ import { parseSchema } from './schema'; import { parseServers } from './server'; import { validateOpenApiSpec } from './validate'; -export const parseV3_0_X = (context: Context) => { +export const parseV3_0_X = (context: Context) => { if (context.config.parser.validate_EXPERIMENTAL) { const result = validateOpenApiSpec(context.spec, context.logger); handleValidatorResult({ context, result }); @@ -55,7 +49,7 @@ export const parseV3_0_X = (context: Context) => { const state: State = { ids: new Map(), }; - const securitySchemesMap = new Map(); + const securitySchemesMap = new Map(); // TODO: parser - handle more component types, old parser handles only parameters and schemas if (context.spec.components) { @@ -63,7 +57,7 @@ export const parseV3_0_X = (context: Context) => { const securityOrReference = context.spec.components.securitySchemes[name]!; const securitySchemeObject = '$ref' in securityOrReference - ? context.resolveRef(securityOrReference.$ref) + ? context.resolveRef(securityOrReference.$ref) : securityOrReference; securitySchemesMap.set(name, securitySchemeObject); } @@ -73,7 +67,7 @@ export const parseV3_0_X = (context: Context) => { const parameterOrReference = context.spec.components.parameters[name]!; const parameter = '$ref' in parameterOrReference - ? context.resolveRef(parameterOrReference.$ref) + ? context.resolveRef(parameterOrReference.$ref) : parameterOrReference; parseParameter({ @@ -88,7 +82,7 @@ export const parseV3_0_X = (context: Context) => { const requestBodyOrReference = context.spec.components.requestBodies[name]!; const requestBody = '$ref' in requestBodyOrReference - ? context.resolveRef(requestBodyOrReference.$ref) + ? context.resolveRef(requestBodyOrReference.$ref) : requestBodyOrReference; parseRequestBody({ @@ -114,11 +108,13 @@ export const parseV3_0_X = (context: Context) => { for (const path in context.spec.paths) { if (path.startsWith('x-')) continue; - const pathItem = context.spec.paths[path as keyof PathsObject]! as PathItemObject; + const pathItem = context.spec.paths[ + path as keyof OpenAPIV3.PathsObject + ]! as OpenAPIV3.PathItemObject; const finalPathItem = pathItem.$ref ? { - ...context.resolveRef(pathItem.$ref), + ...context.resolveRef(pathItem.$ref), ...pathItem, } : pathItem; diff --git a/packages/shared/src/openApi/3.0.x/parser/mediaType.ts b/packages/shared/src/openApi/3.0.x/parser/mediaType.ts index 382fe9c88..0e696ebd8 100644 --- a/packages/shared/src/openApi/3.0.x/parser/mediaType.ts +++ b/packages/shared/src/openApi/3.0.x/parser/mediaType.ts @@ -1,14 +1,19 @@ +import type { OpenAPIV3 } from '@hey-api/spec-types'; + import type { IRMediaType } from '../../../ir/mediaType'; import { isMediaTypeFileLike, mediaTypeToIrMediaType } from '../../../ir/mediaType'; -import type { MediaTypeObject, ReferenceObject, SchemaObject } from '../types/spec'; interface Content { mediaType: string; - schema: SchemaObject | ReferenceObject | undefined; + schema: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject | undefined; type: IRMediaType | undefined; } -export const contentToSchema = ({ content }: { content: Content }): SchemaObject | undefined => { +export const contentToSchema = ({ + content, +}: { + content: Content; +}): OpenAPIV3.SchemaObject | undefined => { const { mediaType, schema } = content; if (schema && '$ref' in schema) { @@ -40,7 +45,7 @@ export const contentToSchema = ({ content }: { content: Content }): SchemaObject export const mediaTypeObjects = ({ content, }: { - content: Record | undefined; + content: Record | undefined; }): ReadonlyArray => { const objects: Array = []; diff --git a/packages/shared/src/openApi/3.0.x/parser/operation.ts b/packages/shared/src/openApi/3.0.x/parser/operation.ts index 8b8ca8ffc..ef59f61d9 100644 --- a/packages/shared/src/openApi/3.0.x/parser/operation.ts +++ b/packages/shared/src/openApi/3.0.x/parser/operation.ts @@ -1,21 +1,15 @@ +import type { OpenAPIV3 } from '@hey-api/spec-types'; + import type { Context } from '../../../ir/context'; import type { IR } from '../../../ir/types'; import type { State } from '../../../openApi/shared/types/state'; import { operationToId } from '../../../openApi/shared/utils/operation'; -import type { - OperationObject, - PathItemObject, - ReferenceObject, - RequestBodyObject, - ResponseObject, - SecuritySchemeObject, -} from '../types/spec'; import { contentToSchema, mediaTypeObjects } from './mediaType'; import { paginationField } from './pagination'; import { parseExtensions, schemaToIrSchema } from './schema'; interface Operation - extends Omit, Pick {} + extends Omit, Pick {} const parseOperationJsDoc = ({ irOperation, @@ -91,7 +85,7 @@ const operationToIrOperation = ({ }: Pick & { context: Context; operation: Operation; - securitySchemesMap: Map; + securitySchemesMap: Map; state: State; }): IR.OperationObject => { const irOperation = initIrOperation({ @@ -109,7 +103,7 @@ const operationToIrOperation = ({ if (operation.requestBody) { const requestBody = '$ref' in operation.requestBody - ? context.resolveRef(operation.requestBody.$ref) + ? context.resolveRef(operation.requestBody.$ref) : operation.requestBody; const contents = mediaTypeObjects({ content: requestBody.content }); // TODO: add support for multiple content types, for now prefer JSON @@ -175,9 +169,11 @@ const operationToIrOperation = ({ irOperation.responses = {}; } - const response = operation.responses[name]! as ResponseObject | ReferenceObject; + const response = operation.responses[name]! as + | OpenAPIV3.ResponseObject + | OpenAPIV3.ReferenceObject; const responseObject = - '$ref' in response ? context.resolveRef(response.$ref) : response; + '$ref' in response ? context.resolveRef(response.$ref) : response; const contents = mediaTypeObjects({ content: responseObject.content }); // TODO: add support for multiple content types, for now prefer JSON const content = contents.find((content) => content.type === 'json') || contents[0]; @@ -242,12 +238,12 @@ export const parsePathOperation = ({ }: { context: Context; method: Extract< - keyof PathItemObject, + keyof OpenAPIV3.PathItemObject, 'delete' | 'get' | 'head' | 'options' | 'patch' | 'post' | 'put' | 'trace' >; operation: Operation; path: keyof IR.PathsObject; - securitySchemesMap: Map; + securitySchemesMap: Map; state: State; }) => { if (!context.ir.paths) { diff --git a/packages/shared/src/openApi/3.0.x/parser/pagination.ts b/packages/shared/src/openApi/3.0.x/parser/pagination.ts index 8a7b87d65..80a8c768d 100644 --- a/packages/shared/src/openApi/3.0.x/parser/pagination.ts +++ b/packages/shared/src/openApi/3.0.x/parser/pagination.ts @@ -1,12 +1,12 @@ +import type { OpenAPIV3 } from '@hey-api/spec-types'; + import type { Context } from '../../../ir/context'; import { getPaginationKeywordsRegExp } from '../../../ir/pagination'; import type { SchemaType } from '../../../openApi/shared/types/schema'; -import type { ParameterObject, ReferenceObject, RequestBodyObject } from '../types/spec'; -import type { SchemaObject } from '../types/spec'; import { mediaTypeObjects } from './mediaType'; import { getSchemaType } from './schema'; -const isPaginationType = (schemaType: SchemaType | undefined): boolean => +const isPaginationType = (schemaType: SchemaType | undefined): boolean => schemaType === 'boolean' || schemaType === 'integer' || schemaType === 'number' || @@ -20,7 +20,7 @@ export const paginationField = ({ }: { context: Context; name: string; - schema: SchemaObject | ReferenceObject; + schema: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject; }): boolean | string => { const paginationRegExp = getPaginationKeywordsRegExp(context.config.parser.pagination); if (paginationRegExp.test(name)) { @@ -28,10 +28,12 @@ export const paginationField = ({ } if ('$ref' in schema) { - const ref = context.resolveRef(schema.$ref); + const ref = context.resolveRef< + OpenAPIV3.ParameterObject | OpenAPIV3.RequestBodyObject | OpenAPIV3.SchemaObject + >(schema.$ref); if ('content' in ref || 'in' in ref) { - let refSchema: SchemaObject | ReferenceObject | undefined; + let refSchema: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject | undefined; if ('in' in ref) { refSchema = ref.schema; diff --git a/packages/shared/src/openApi/3.0.x/parser/parameter.ts b/packages/shared/src/openApi/3.0.x/parser/parameter.ts index 69059f8dc..1e3a95f6c 100644 --- a/packages/shared/src/openApi/3.0.x/parser/parameter.ts +++ b/packages/shared/src/openApi/3.0.x/parser/parameter.ts @@ -1,7 +1,8 @@ +import type { OpenAPIV3 } from '@hey-api/spec-types'; + import type { Context } from '../../../ir/context'; import type { IR } from '../../../ir/types'; import { refToName } from '../../../utils/ref'; -import type { ParameterObject, ReferenceObject, SchemaObject } from '../types/spec'; import { mediaTypeObjects } from './mediaType'; import { paginationField } from './pagination'; import { parseExtensions, schemaToIrSchema } from './schema'; @@ -9,7 +10,7 @@ import { parseExtensions, schemaToIrSchema } from './schema'; /** * Returns default parameter `allowReserved` based on value of `in`. */ -const defaultAllowReserved = (_in: ParameterObject['in']): boolean | undefined => { +const defaultAllowReserved = (_in: OpenAPIV3.ParameterObject['in']): boolean | undefined => { switch (_in) { // this keyword only applies to parameters with an `in` value of `query` case 'query': @@ -22,7 +23,7 @@ const defaultAllowReserved = (_in: ParameterObject['in']): boolean | undefined = /** * Returns default parameter `explode` based on value of `style`. */ -const defaultExplode = (style: Required['style']): boolean => { +const defaultExplode = (style: Required['style']): boolean => { switch (style) { // default value for `deepObject` is `false`, but that behavior is undefined // so we use `true` to make this work with the `client-fetch` package @@ -37,7 +38,9 @@ const defaultExplode = (style: Required['style']): boolean => { /** * Returns default parameter `style` based on value of `in`. */ -const defaultStyle = (_in: ParameterObject['in']): Required['style'] => { +const defaultStyle = ( + _in: OpenAPIV3.ParameterObject['in'], +): Required['style'] => { switch (_in) { case 'header': case 'path': @@ -53,7 +56,7 @@ export const parametersArrayToObject = ({ parameters, }: { context: Context; - parameters?: ReadonlyArray; + parameters?: ReadonlyArray; }): IR.ParametersObject | undefined => { if (!parameters || !Object.keys(parameters).length) { return; @@ -64,7 +67,7 @@ export const parametersArrayToObject = ({ for (const parameterOrReference of parameters) { const parameter = '$ref' in parameterOrReference - ? context.dereference(parameterOrReference) + ? context.dereference(parameterOrReference) : parameterOrReference; if (!parametersObject[parameter.in]) { @@ -89,7 +92,7 @@ const parameterToIrParameter = ({ }: { $ref: string; context: Context; - parameter: ParameterObject; + parameter: OpenAPIV3.ParameterObject; }): IR.ParameterObject => { // TODO: parser - fix let schema = parameter.schema; @@ -103,7 +106,7 @@ const parameterToIrParameter = ({ } } - const finalSchema: SchemaObject = + const finalSchema: OpenAPIV3.SchemaObject = schema && '$ref' in schema ? { allOf: [{ ...schema }], @@ -176,7 +179,7 @@ export const parseParameter = ({ }: { $ref: string; context: Context; - parameter: ParameterObject; + parameter: OpenAPIV3.ParameterObject; }) => { if (!context.ir.components) { context.ir.components = {}; diff --git a/packages/shared/src/openApi/3.0.x/parser/requestBody.ts b/packages/shared/src/openApi/3.0.x/parser/requestBody.ts index 60a584de7..5c1defa09 100644 --- a/packages/shared/src/openApi/3.0.x/parser/requestBody.ts +++ b/packages/shared/src/openApi/3.0.x/parser/requestBody.ts @@ -1,7 +1,8 @@ +import type { OpenAPIV3 } from '@hey-api/spec-types'; + import type { Context } from '../../../ir/context'; import type { IR } from '../../../ir/types'; import { refToName } from '../../../utils/ref'; -import type { RequestBodyObject, SchemaObject } from '../types/spec'; import { mediaTypeObjects } from './mediaType'; import { schemaToIrSchema } from './schema'; @@ -12,7 +13,7 @@ const requestBodyToIrRequestBody = ({ }: { $ref: string; context: Context; - requestBody: RequestBodyObject; + requestBody: OpenAPIV3.RequestBodyObject; }): IR.RequestBodyObject => { // TODO: parser - fix const contents = mediaTypeObjects({ content: requestBody.content }); @@ -20,7 +21,7 @@ const requestBodyToIrRequestBody = ({ const content = contents.find((content) => content.type === 'json') || contents[0]; const schema = content ? content.schema : undefined; - const finalSchema: SchemaObject = { + const finalSchema: OpenAPIV3.SchemaObject = { description: requestBody.description, ...schema, }; @@ -54,7 +55,7 @@ export const parseRequestBody = ({ }: { $ref: string; context: Context; - requestBody: RequestBodyObject; + requestBody: OpenAPIV3.RequestBodyObject; }) => { if (!context.ir.components) { context.ir.components = {}; diff --git a/packages/shared/src/openApi/3.0.x/parser/schema.ts b/packages/shared/src/openApi/3.0.x/parser/schema.ts index 3611db415..cc363caee 100644 --- a/packages/shared/src/openApi/3.0.x/parser/schema.ts +++ b/packages/shared/src/openApi/3.0.x/parser/schema.ts @@ -1,3 +1,5 @@ +import type { OpenAPIV3 } from '@hey-api/spec-types'; + import type { Context } from '../../../ir/context'; import type { IR } from '../../../ir/types'; import { addItemsToSchema } from '../../../ir/utils'; @@ -12,13 +14,12 @@ import { discriminatorValues, } from '../../../openApi/shared/utils/discriminator'; import { isTopLevelComponent, refToName } from '../../../utils/ref'; -import type { ReferenceObject, SchemaObject } from '../types/spec'; export const getSchemaType = ({ schema, }: { - schema: SchemaObject; -}): SchemaType | undefined => { + schema: OpenAPIV3.SchemaObject; +}): SchemaType | undefined => { if (schema.type) { return schema.type; } @@ -42,16 +43,17 @@ const findDiscriminatorPropertyType = ({ }: { context: Context; propertyName: string; - schemas: ReadonlyArray; + schemas: ReadonlyArray; }): DiscriminatorPropertyType => { for (const schema of schemas) { - const resolved = '$ref' in schema ? context.resolveRef(schema.$ref) : schema; + const resolved = + '$ref' in schema ? context.resolveRef(schema.$ref) : schema; // Check direct properties const property = resolved.properties?.[propertyName]; if (property) { const resolvedProperty = - '$ref' in property ? context.resolveRef(property.$ref) : property; + '$ref' in property ? context.resolveRef(property.$ref) : property; if ( resolvedProperty.type === 'boolean' || resolvedProperty.type === 'integer' || @@ -89,13 +91,13 @@ const findDiscriminatorsInSchema = ({ }: { context: Context; discriminators?: Array<{ - discriminator: NonNullable; - oneOf?: SchemaObject['oneOf']; + discriminator: NonNullable; + oneOf?: OpenAPIV3.SchemaObject['oneOf']; }>; - schema: SchemaObject; + schema: OpenAPIV3.SchemaObject; }): Array<{ - discriminator: NonNullable; - oneOf?: SchemaObject['oneOf']; + discriminator: NonNullable; + oneOf?: OpenAPIV3.SchemaObject['oneOf']; }> => { // Check if this schema has a discriminator if (schema.discriminator) { @@ -108,9 +110,9 @@ const findDiscriminatorsInSchema = ({ // If this schema is an allOf composition, recursively search in its components if (schema.allOf) { for (const compositionSchema of schema.allOf) { - let resolvedSchema: SchemaObject; + let resolvedSchema: OpenAPIV3.SchemaObject; if ('$ref' in compositionSchema) { - resolvedSchema = context.resolveRef(compositionSchema.$ref); + resolvedSchema = context.resolveRef(compositionSchema.$ref); } else { resolvedSchema = compositionSchema; } @@ -134,7 +136,7 @@ const getAllDiscriminatorValues = ({ discriminator, schemaRef, }: { - discriminator: NonNullable; + discriminator: NonNullable; schemaRef: string; }): Array => { const values: Array = []; @@ -155,7 +157,7 @@ const parseSchemaJsDoc = ({ schema, }: { irSchema: IR.SchemaObject; - schema: SchemaObject; + schema: OpenAPIV3.SchemaObject; }) => { if (schema.deprecated !== undefined) { irSchema.deprecated = schema.deprecated; @@ -179,7 +181,7 @@ const parseSchemaMeta = ({ schema, }: { irSchema: IR.SchemaObject; - schema: SchemaObject; + schema: OpenAPIV3.SchemaObject; }) => { if (schema.default !== undefined) { irSchema.default = schema.default; @@ -240,7 +242,7 @@ const parseArray = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: SchemaObject; + schema: OpenAPIV3.SchemaObject; state: SchemaState; }): IR.SchemaObject => { if (schema.maxItems && schema.maxItems === schema.minItems) { @@ -291,7 +293,7 @@ const parseBoolean = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: SchemaObject; + schema: OpenAPIV3.SchemaObject; state: SchemaState; }): IR.SchemaObject => { irSchema.type = 'boolean'; @@ -305,7 +307,7 @@ const parseNumber = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: SchemaWithRequired; + schema: SchemaWithRequired; state: SchemaState; }): IR.SchemaObject => { irSchema.type = schema.type; @@ -321,7 +323,7 @@ const parseObject = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: SchemaObject; + schema: OpenAPIV3.SchemaObject; state: SchemaState; }): IR.SchemaObject => { irSchema.type = 'object'; @@ -415,7 +417,7 @@ const parseString = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: SchemaObject; + schema: OpenAPIV3.SchemaObject; state: SchemaState; }): IR.SchemaObject => { irSchema.type = 'string'; @@ -431,7 +433,7 @@ export const parseExtensions = ({ source, target }: { source: object; target: ob } }; -const initIrSchema = ({ schema }: { schema: SchemaObject }): IR.SchemaObject => { +const initIrSchema = ({ schema }: { schema: OpenAPIV3.SchemaObject }): IR.SchemaObject => { const irSchema: IR.SchemaObject = {}; parseSchemaJsDoc({ @@ -453,7 +455,7 @@ const parseAllOf = ({ state, }: { context: Context; - schema: SchemaWithRequired; + schema: SchemaWithRequired; state: SchemaState; }): IR.SchemaObject => { let irSchema = initIrSchema({ schema }); @@ -465,7 +467,7 @@ const parseAllOf = ({ // Collect discriminator information to add after all compositions are processed type DiscriminatorInfo = { - discriminator: NonNullable; + discriminator: NonNullable; isExplicitMapping: boolean; isRequired: boolean; values: ReadonlyArray; @@ -499,7 +501,7 @@ const parseAllOf = ({ schemaItems.push(irCompositionSchema); if ('$ref' in compositionSchema) { - const ref = context.resolveRef(compositionSchema.$ref); + const ref = context.resolveRef(compositionSchema.$ref); // `$ref` should be passed from the root `parseSchema()` call if (state.$ref) { // Find all discriminators in the referenced schema, including nested allOf compositions @@ -549,7 +551,7 @@ const parseAllOf = ({ (ref.allOf && ref.allOf.some((item) => { const resolvedItem = - '$ref' in item ? context.resolveRef(item.$ref) : item; + '$ref' in item ? context.resolveRef(item.$ref) : item; return resolvedItem.required?.includes(d.discriminator.propertyName); }))), ); @@ -603,7 +605,7 @@ const parseAllOf = ({ const hasProperty = (() => { if (!item.$ref) return false; try { - const refSchema = context.resolveRef(item.$ref); + const refSchema = context.resolveRef(item.$ref); // Check if the discriminator property exists in the ref schema return ( refSchema.properties?.[discriminator.propertyName] !== undefined || @@ -611,7 +613,7 @@ const parseAllOf = ({ refSchema.allOf.some((allOfItem) => { const resolved = '$ref' in allOfItem - ? context.resolveRef(allOfItem.$ref) + ? context.resolveRef(allOfItem.$ref) : allOfItem; return resolved.properties?.[discriminator.propertyName] !== undefined; })) @@ -692,7 +694,7 @@ const parseAllOf = ({ // TODO: parser - this could be probably resolved more accurately const finalCompositionSchema = '$ref' in compositionSchema - ? context.resolveRef(compositionSchema.$ref) + ? context.resolveRef(compositionSchema.$ref) : compositionSchema; if (getSchemaType({ schema: finalCompositionSchema }) === 'object') { @@ -764,7 +766,7 @@ const parseAnyOf = ({ state, }: { context: Context; - schema: SchemaWithRequired; + schema: SchemaWithRequired; state: SchemaState; }): IR.SchemaObject => { let irSchema = initIrSchema({ schema }); @@ -855,7 +857,7 @@ const parseEnum = ({ state, }: { context: Context; - schema: SchemaWithRequired; + schema: SchemaWithRequired; state: SchemaState; }): IR.SchemaObject => { let irSchema = initIrSchema({ schema }); @@ -866,7 +868,7 @@ const parseEnum = ({ for (const [index, enumValue] of schema.enum.entries()) { const typeOfEnumValue = typeof enumValue; - let enumType: SchemaType | 'null' | undefined; + let enumType: SchemaType | 'null' | undefined; if ( typeOfEnumValue === 'string' || @@ -932,7 +934,7 @@ const parseOneOf = ({ state, }: { context: Context; - schema: SchemaWithRequired; + schema: SchemaWithRequired; state: SchemaState; }): IR.SchemaObject => { let irSchema = initIrSchema({ schema }); @@ -1035,7 +1037,7 @@ const parseRef = ({ state, }: { context: Context; - schema: ReferenceObject; + schema: OpenAPIV3.ReferenceObject; state: SchemaState; }): IR.SchemaObject => { // Inline non-component refs (e.g. #/paths/...) and deep path refs (e.g. #/components/schemas/Foo/properties/bar) @@ -1043,7 +1045,7 @@ const parseRef = ({ const isComponentsRef = isTopLevelComponent(schema.$ref); if (!isComponentsRef) { if (!state.circularReferenceTracker.has(schema.$ref)) { - const refSchema = context.resolveRef(schema.$ref); + const refSchema = context.resolveRef(schema.$ref); const originalRef = state.$ref; state.$ref = schema.$ref; const irSchema = schemaToIrSchema({ @@ -1064,7 +1066,7 @@ const parseRef = ({ irSchema.$ref = decodeURI(schema.$ref); if (!state.circularReferenceTracker.has(schema.$ref)) { - const refSchema = context.resolveRef(schema.$ref); + const refSchema = context.resolveRef(schema.$ref); const originalRef = state.$ref; state.$ref = schema.$ref; schemaToIrSchema({ @@ -1086,7 +1088,7 @@ const parseNullableType = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: SchemaWithRequired; + schema: SchemaWithRequired; state: SchemaState; }): IR.SchemaObject => { if (!irSchema) { @@ -1129,7 +1131,7 @@ const parseType = ({ state, }: { context: Context; - schema: SchemaWithRequired; + schema: SchemaWithRequired; state: SchemaState; }): IR.SchemaObject => { const irSchema = initIrSchema({ schema }); @@ -1173,7 +1175,7 @@ const parseOneType = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: SchemaWithRequired; + schema: SchemaWithRequired; state: SchemaState; }): IR.SchemaObject => { if (!irSchema) { @@ -1235,7 +1237,7 @@ const parseUnknown = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: SchemaObject; + schema: OpenAPIV3.SchemaObject; }): IR.SchemaObject => { if (!irSchema) { irSchema = initIrSchema({ schema }); @@ -1254,7 +1256,7 @@ export const schemaToIrSchema = ({ state, }: { context: Context; - schema: SchemaObject | ReferenceObject; + schema: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject; state: SchemaState | undefined; }): IR.SchemaObject => { if (!state) { @@ -1278,7 +1280,7 @@ export const schemaToIrSchema = ({ if (schema.enum) { return parseEnum({ context, - schema: schema as SchemaWithRequired, + schema: schema as SchemaWithRequired, state, }); } @@ -1286,7 +1288,7 @@ export const schemaToIrSchema = ({ if (schema.allOf) { return parseAllOf({ context, - schema: schema as SchemaWithRequired, + schema: schema as SchemaWithRequired, state, }); } @@ -1294,7 +1296,7 @@ export const schemaToIrSchema = ({ if (schema.anyOf) { return parseAnyOf({ context, - schema: schema as SchemaWithRequired, + schema: schema as SchemaWithRequired, state, }); } @@ -1302,7 +1304,7 @@ export const schemaToIrSchema = ({ if (schema.oneOf) { return parseOneOf({ context, - schema: schema as SchemaWithRequired, + schema: schema as SchemaWithRequired, state, }); } @@ -1311,7 +1313,7 @@ export const schemaToIrSchema = ({ if (schema.type || schema.properties) { return parseType({ context, - schema: schema as SchemaWithRequired, + schema: schema as SchemaWithRequired, state, }); } @@ -1326,7 +1328,7 @@ export const parseSchema = ({ }: { $ref: string; context: Context; - schema: SchemaObject | ReferenceObject; + schema: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject; }) => { if (!context.ir.components) { context.ir.components = {}; diff --git a/packages/shared/src/openApi/3.0.x/parser/validate.ts b/packages/shared/src/openApi/3.0.x/parser/validate.ts index 74ecd534b..52ee32f0c 100644 --- a/packages/shared/src/openApi/3.0.x/parser/validate.ts +++ b/packages/shared/src/openApi/3.0.x/parser/validate.ts @@ -1,19 +1,19 @@ import type { Logger } from '@hey-api/codegen-core'; +import type { OpenAPIV3 } from '@hey-api/spec-types'; import { createOperationKey } from '../../../ir/operation'; import { httpMethods } from '../../../openApi/shared/utils/operation'; import type { ValidatorIssue, ValidatorResult } from '../../../openApi/shared/utils/validator'; -import type { OpenApiV3_0_X, PathItemObject, PathsObject } from '../types/spec'; -export const validateOpenApiSpec = (spec: OpenApiV3_0_X, logger: Logger): ValidatorResult => { +export const validateOpenApiSpec = (spec: OpenAPIV3.Document, logger: Logger): ValidatorResult => { const eventValidate = logger.timeEvent('validate'); const issues: Array = []; const operationIds = new Map(); if (spec.paths) { for (const entry of Object.entries(spec.paths)) { - const path = entry[0] as keyof PathsObject; - const pathItem = entry[1] as PathItemObject; + const path = entry[0] as keyof OpenAPIV3.PathsObject; + const pathItem = entry[1] as OpenAPIV3.PathItemObject; for (const method of httpMethods) { const operation = pathItem[method]; if (!operation) { diff --git a/packages/shared/src/openApi/3.1.x/index.ts b/packages/shared/src/openApi/3.1.x/index.ts index ac9090778..f4477eb77 100644 --- a/packages/shared/src/openApi/3.1.x/index.ts +++ b/packages/shared/src/openApi/3.1.x/index.ts @@ -1,22 +1 @@ export { parseV3_1_X } from './parser'; -export type { OpenApiV3_1_X } from './types/spec'; - -import type { - InfoObject, - OperationObject, - ParameterObject, - ReferenceObject, - RequestBodyObject, - ResponseObject, - SchemaObject, -} from './types/spec'; - -export interface OpenApiV3_1_XTypes { - InfoObject: InfoObject; - OperationObject: OperationObject; - ParameterObject: ParameterObject; - ReferenceObject: ReferenceObject; - RequestBodyObject: RequestBodyObject; - ResponseObject: ResponseObject; - SchemaObject: SchemaObject; -} diff --git a/packages/shared/src/openApi/3.1.x/parser/__tests__/operation.test.ts b/packages/shared/src/openApi/3.1.x/parser/__tests__/operation.test.ts index 47b72ed59..d8515d3f0 100644 --- a/packages/shared/src/openApi/3.1.x/parser/__tests__/operation.test.ts +++ b/packages/shared/src/openApi/3.1.x/parser/__tests__/operation.test.ts @@ -1,5 +1,6 @@ +import type { OpenAPIV3_1 } from '@hey-api/spec-types'; + import type { Context } from '../../../../ir/context'; -import type { SecuritySchemeObject } from '../../types/spec'; import { parsePathOperation } from '../operation'; type ParseOperationProps = Parameters[0]; @@ -38,7 +39,7 @@ describe('operation', () => { }; const path = '/test'; - const oauth2: SecuritySchemeObject = { + const oauth2: OpenAPIV3_1.SecuritySchemeObject = { description: 'OAuth2', flows: { password: { @@ -51,7 +52,7 @@ describe('operation', () => { }, type: 'oauth2', }; - const securitySchemesMap = new Map([ + const securitySchemesMap = new Map([ ['apiKeyAuth', { in: 'header', name: 'Auth', type: 'apiKey' }], ['basicAuthRule', { description: 'Basic Auth', scheme: 'basic', type: 'http' }], ['oauthRule', oauth2], diff --git a/packages/shared/src/openApi/3.1.x/parser/filter.ts b/packages/shared/src/openApi/3.1.x/parser/filter.ts index 1bc784f20..23c2d7400 100644 --- a/packages/shared/src/openApi/3.1.x/parser/filter.ts +++ b/packages/shared/src/openApi/3.1.x/parser/filter.ts @@ -1,9 +1,9 @@ import type { Logger } from '@hey-api/codegen-core'; +import type { OpenAPIV3_1 } from '@hey-api/spec-types'; import { createOperationKey } from '../../../ir/operation'; import { addNamespace, removeNamespace } from '../../../openApi/shared/utils/filter'; import { httpMethods } from '../../../openApi/shared/utils/operation'; -import type { OpenApiV3_1_X, PathItemObject, PathsObject } from '../types/spec'; /** * Replace source spec with filtered version. @@ -25,7 +25,7 @@ export const filterSpec = ({ requestBodies: Set; responses: Set; schemas: Set; - spec: OpenApiV3_1_X; + spec: OpenAPIV3_1.Document; }) => { const eventFilterSpec = logger.timeEvent('filter-spec'); if (spec.components) { @@ -120,8 +120,8 @@ export const filterSpec = ({ if (spec.paths) { for (const entry of Object.entries(spec.paths)) { - const path = entry[0] as keyof PathsObject; - const pathItem = entry[1] as PathItemObject; + const path = entry[0] as keyof OpenAPIV3_1.PathsObject; + const pathItem = entry[1] as OpenAPIV3_1.PathItemObject; for (const method of httpMethods) { const operation = pathItem[method]; diff --git a/packages/shared/src/openApi/3.1.x/parser/index.ts b/packages/shared/src/openApi/3.1.x/parser/index.ts index c87117705..352dbc218 100644 --- a/packages/shared/src/openApi/3.1.x/parser/index.ts +++ b/packages/shared/src/openApi/3.1.x/parser/index.ts @@ -1,3 +1,5 @@ +import type { OpenAPIV3_1 } from '@hey-api/spec-types'; + import type { Context } from '../../../ir/context'; import { buildResourceMetadata } from '../../../openApi/shared/graph/meta'; import { transformOpenApiSpec } from '../../../openApi/shared/transforms'; @@ -10,14 +12,6 @@ import { import { buildGraph } from '../../../openApi/shared/utils/graph'; import { mergeParametersObjects } from '../../../openApi/shared/utils/parameter'; import { handleValidatorResult } from '../../../openApi/shared/utils/validator'; -import type { - OpenApiV3_1_X, - ParameterObject, - PathItemObject, - PathsObject, - RequestBodyObject, - SecuritySchemeObject, -} from '../types/spec'; import { filterSpec } from './filter'; import { parsePathOperation } from './operation'; import { parametersArrayToObject, parseParameter } from './parameter'; @@ -27,7 +21,7 @@ import { parseServers } from './server'; import { validateOpenApiSpec } from './validate'; import { parseWebhooks } from './webhook'; -export const parseV3_1_X = (context: Context) => { +export const parseV3_1_X = (context: Context) => { if (context.config.parser.validate_EXPERIMENTAL) { const result = validateOpenApiSpec(context.spec, context.logger); handleValidatorResult({ context, result }); @@ -56,7 +50,7 @@ export const parseV3_1_X = (context: Context) => { const state: State = { ids: new Map(), }; - const securitySchemesMap = new Map(); + const securitySchemesMap = new Map(); // TODO: parser - handle more component types, old parser handles only parameters and schemas if (context.spec.components) { @@ -64,7 +58,7 @@ export const parseV3_1_X = (context: Context) => { const securityOrReference = context.spec.components.securitySchemes[name]!; const securitySchemeObject = '$ref' in securityOrReference - ? context.resolveRef(securityOrReference.$ref) + ? context.resolveRef(securityOrReference.$ref) : securityOrReference; securitySchemesMap.set(name, securitySchemeObject); } @@ -74,7 +68,7 @@ export const parseV3_1_X = (context: Context) => { const parameterOrReference = context.spec.components.parameters[name]!; const parameter = '$ref' in parameterOrReference - ? context.resolveRef(parameterOrReference.$ref) + ? context.resolveRef(parameterOrReference.$ref) : parameterOrReference; parseParameter({ @@ -89,7 +83,7 @@ export const parseV3_1_X = (context: Context) => { const requestBodyOrReference = context.spec.components.requestBodies[name]!; const requestBody = '$ref' in requestBodyOrReference - ? context.resolveRef(requestBodyOrReference.$ref) + ? context.resolveRef(requestBodyOrReference.$ref) : requestBodyOrReference; parseRequestBody({ @@ -115,11 +109,13 @@ export const parseV3_1_X = (context: Context) => { for (const path in context.spec.paths) { if (path.startsWith('x-')) continue; - const pathItem = context.spec.paths[path as keyof PathsObject]! as PathItemObject; + const pathItem = context.spec.paths[ + path as keyof OpenAPIV3_1.PathsObject + ]! as OpenAPIV3_1.PathItemObject; const finalPathItem = pathItem.$ref ? { - ...context.resolveRef(pathItem.$ref), + ...context.resolveRef(pathItem.$ref), ...pathItem, } : pathItem; diff --git a/packages/shared/src/openApi/3.1.x/parser/mediaType.ts b/packages/shared/src/openApi/3.1.x/parser/mediaType.ts index 4725192ce..f2c218571 100644 --- a/packages/shared/src/openApi/3.1.x/parser/mediaType.ts +++ b/packages/shared/src/openApi/3.1.x/parser/mediaType.ts @@ -1,14 +1,19 @@ +import type { OpenAPIV3_1 } from '@hey-api/spec-types'; + import type { IRMediaType } from '../../../ir/mediaType'; import { isMediaTypeFileLike, mediaTypeToIrMediaType } from '../../../ir/mediaType'; -import type { MediaTypeObject, SchemaObject } from '../types/spec'; interface Content { mediaType: string; - schema: SchemaObject | undefined; + schema: OpenAPIV3_1.SchemaObject | undefined; type: IRMediaType | undefined; } -export const contentToSchema = ({ content }: { content: Content }): SchemaObject | undefined => { +export const contentToSchema = ({ + content, +}: { + content: Content; +}): OpenAPIV3_1.SchemaObject | undefined => { const { mediaType, schema } = content; if (!schema) { @@ -34,7 +39,7 @@ export const contentToSchema = ({ content }: { content: Content }): SchemaObject export const mediaTypeObjects = ({ content, }: { - content: Record | undefined; + content: Record | undefined; }): ReadonlyArray => { const objects: Array = []; diff --git a/packages/shared/src/openApi/3.1.x/parser/operation.ts b/packages/shared/src/openApi/3.1.x/parser/operation.ts index bb21fb377..924d87fda 100644 --- a/packages/shared/src/openApi/3.1.x/parser/operation.ts +++ b/packages/shared/src/openApi/3.1.x/parser/operation.ts @@ -1,21 +1,16 @@ +import type { OpenAPIV3_1 } from '@hey-api/spec-types'; + import type { Context } from '../../../ir/context'; import type { IR } from '../../../ir/types'; import type { State } from '../../../openApi/shared/types/state'; import type { httpMethods } from '../../../openApi/shared/utils/operation'; import { operationToId } from '../../../openApi/shared/utils/operation'; -import type { - OperationObject, - ReferenceObject, - RequestBodyObject, - ResponseObject, - SecuritySchemeObject, -} from '../types/spec'; import { contentToSchema, mediaTypeObjects } from './mediaType'; import { paginationField } from './pagination'; import { parseExtensions, schemaToIrSchema } from './schema'; export interface Operation - extends Omit, Pick {} + extends Omit, Pick {} const parseOperationJsDoc = ({ irOperation, @@ -91,7 +86,7 @@ const operationToIrOperation = ({ }: Pick & { context: Context; operation: Operation; - securitySchemesMap: Map; + securitySchemesMap: Map; state: State; }): IR.OperationObject => { const irOperation = initIrOperation({ @@ -109,7 +104,7 @@ const operationToIrOperation = ({ if (operation.requestBody) { const requestBody = '$ref' in operation.requestBody - ? context.resolveRef(operation.requestBody.$ref) + ? context.resolveRef(operation.requestBody.$ref) : operation.requestBody; const contents = mediaTypeObjects({ content: requestBody.content }); // TODO: add support for multiple content types, for now prefer JSON @@ -158,9 +153,11 @@ const operationToIrOperation = ({ irOperation.responses = {}; } - const response = operation.responses[name]! as ResponseObject | ReferenceObject; + const response = operation.responses[name]! as + | OpenAPIV3_1.ResponseObject + | OpenAPIV3_1.ReferenceObject; const responseObject = - '$ref' in response ? context.resolveRef(response.$ref) : response; + '$ref' in response ? context.resolveRef(response.$ref) : response; const contents = mediaTypeObjects({ content: responseObject.content }); // TODO: add support for multiple content types, for now prefer JSON const content = contents.find((content) => content.type === 'json') || contents[0]; @@ -227,7 +224,7 @@ const parseOperationObject = ({ method: (typeof httpMethods)[number]; operation: Operation; path: keyof IR.PathsObject; - securitySchemesMap: Map; + securitySchemesMap: Map; state: State; }) => { if (operation.servers) { @@ -256,7 +253,7 @@ export const parsePathOperation = ({ method: (typeof httpMethods)[number]; operation: Operation; path: keyof IR.PathsObject; - securitySchemesMap: Map; + securitySchemesMap: Map; state: State; }) => { if (!context.ir.paths) { @@ -287,7 +284,7 @@ export const parseWebhookOperation = ({ key: string; method: (typeof httpMethods)[number]; operation: Operation; - securitySchemesMap: Map; + securitySchemesMap: Map; state: State; }) => { if (!context.ir.webhooks) { diff --git a/packages/shared/src/openApi/3.1.x/parser/pagination.ts b/packages/shared/src/openApi/3.1.x/parser/pagination.ts index fa0607025..c3b08fb0e 100644 --- a/packages/shared/src/openApi/3.1.x/parser/pagination.ts +++ b/packages/shared/src/openApi/3.1.x/parser/pagination.ts @@ -1,12 +1,14 @@ +import type { OpenAPIV3_1 } from '@hey-api/spec-types'; + import type { Context } from '../../../ir/context'; import { getPaginationKeywordsRegExp } from '../../../ir/pagination'; import type { SchemaType } from '../../../openApi/shared/types/schema'; -import type { ParameterObject, RequestBodyObject } from '../types/spec'; -import type { SchemaObject } from '../types/spec'; import { mediaTypeObjects } from './mediaType'; import { getSchemaTypes } from './schema'; -const isPaginationType = (schemaTypes: ReadonlyArray>): boolean => +const isPaginationType = ( + schemaTypes: ReadonlyArray>, +): boolean => schemaTypes.includes('boolean') || schemaTypes.includes('integer') || schemaTypes.includes('number') || @@ -20,7 +22,7 @@ export const paginationField = ({ }: { context: Context; name: string; - schema: SchemaObject; + schema: OpenAPIV3_1.SchemaObject; }): boolean | string => { const paginationRegExp = getPaginationKeywordsRegExp(context.config.parser.pagination); if (paginationRegExp.test(name)) { @@ -28,10 +30,12 @@ export const paginationField = ({ } if (schema.$ref) { - const ref = context.resolveRef(schema.$ref); + const ref = context.resolveRef< + OpenAPIV3_1.ParameterObject | OpenAPIV3_1.RequestBodyObject | OpenAPIV3_1.SchemaObject + >(schema.$ref); if ('content' in ref || 'in' in ref) { - let refSchema: SchemaObject | undefined; + let refSchema: OpenAPIV3_1.SchemaObject | undefined; if ('in' in ref) { refSchema = ref.schema; diff --git a/packages/shared/src/openApi/3.1.x/parser/parameter.ts b/packages/shared/src/openApi/3.1.x/parser/parameter.ts index a37a6075e..d297e27ba 100644 --- a/packages/shared/src/openApi/3.1.x/parser/parameter.ts +++ b/packages/shared/src/openApi/3.1.x/parser/parameter.ts @@ -1,7 +1,8 @@ +import type { OpenAPIV3_1 } from '@hey-api/spec-types'; + import type { Context } from '../../../ir/context'; import type { IR } from '../../../ir/types'; import { refToName } from '../../../utils/ref'; -import type { ParameterObject, ReferenceObject, SchemaObject } from '../types/spec'; import { mediaTypeObjects } from './mediaType'; import { paginationField } from './pagination'; import { parseExtensions, schemaToIrSchema } from './schema'; @@ -9,7 +10,7 @@ import { parseExtensions, schemaToIrSchema } from './schema'; /** * Returns default parameter `allowReserved` based on value of `in`. */ -const defaultAllowReserved = (_in: ParameterObject['in']): boolean | undefined => { +const defaultAllowReserved = (_in: OpenAPIV3_1.ParameterObject['in']): boolean | undefined => { switch (_in) { // this keyword only applies to parameters with an `in` value of `query` case 'query': @@ -22,7 +23,7 @@ const defaultAllowReserved = (_in: ParameterObject['in']): boolean | undefined = /** * Returns default parameter `explode` based on value of `style`. */ -const defaultExplode = (style: Required['style']): boolean => { +const defaultExplode = (style: Required['style']): boolean => { switch (style) { // default value for `deepObject` is `false`, but that behavior is undefined // so we use `true` to make this work with the `client-fetch` package @@ -37,7 +38,9 @@ const defaultExplode = (style: Required['style']): boolean => { /** * Returns default parameter `style` based on value of `in`. */ -const defaultStyle = (_in: ParameterObject['in']): Required['style'] => { +const defaultStyle = ( + _in: OpenAPIV3_1.ParameterObject['in'], +): Required['style'] => { switch (_in) { case 'header': case 'path': @@ -53,7 +56,7 @@ export const parametersArrayToObject = ({ parameters, }: { context: Context; - parameters?: ReadonlyArray; + parameters?: ReadonlyArray; }): IR.ParametersObject | undefined => { if (!parameters || !Object.keys(parameters).length) { return; @@ -64,7 +67,7 @@ export const parametersArrayToObject = ({ for (const parameterOrReference of parameters) { const parameter = '$ref' in parameterOrReference - ? context.dereference(parameterOrReference) + ? context.dereference(parameterOrReference) : parameterOrReference; if (!parametersObject[parameter.in]) { @@ -89,7 +92,7 @@ const parameterToIrParameter = ({ }: { $ref: string; context: Context; - parameter: ParameterObject; + parameter: OpenAPIV3_1.ParameterObject; }): IR.ParameterObject => { // TODO: parser - fix let schema = parameter.schema; @@ -103,7 +106,7 @@ const parameterToIrParameter = ({ } } - const finalSchema: SchemaObject = { + const finalSchema: OpenAPIV3_1.SchemaObject = { deprecated: parameter.deprecated, description: parameter.description, ...schema, @@ -169,7 +172,7 @@ export const parseParameter = ({ }: { $ref: string; context: Context; - parameter: ParameterObject; + parameter: OpenAPIV3_1.ParameterObject; }) => { if (!context.ir.components) { context.ir.components = {}; diff --git a/packages/shared/src/openApi/3.1.x/parser/requestBody.ts b/packages/shared/src/openApi/3.1.x/parser/requestBody.ts index 60a584de7..f515fa83e 100644 --- a/packages/shared/src/openApi/3.1.x/parser/requestBody.ts +++ b/packages/shared/src/openApi/3.1.x/parser/requestBody.ts @@ -1,7 +1,8 @@ +import type { OpenAPIV3_1 } from '@hey-api/spec-types'; + import type { Context } from '../../../ir/context'; import type { IR } from '../../../ir/types'; import { refToName } from '../../../utils/ref'; -import type { RequestBodyObject, SchemaObject } from '../types/spec'; import { mediaTypeObjects } from './mediaType'; import { schemaToIrSchema } from './schema'; @@ -12,7 +13,7 @@ const requestBodyToIrRequestBody = ({ }: { $ref: string; context: Context; - requestBody: RequestBodyObject; + requestBody: OpenAPIV3_1.RequestBodyObject; }): IR.RequestBodyObject => { // TODO: parser - fix const contents = mediaTypeObjects({ content: requestBody.content }); @@ -20,7 +21,7 @@ const requestBodyToIrRequestBody = ({ const content = contents.find((content) => content.type === 'json') || contents[0]; const schema = content ? content.schema : undefined; - const finalSchema: SchemaObject = { + const finalSchema: OpenAPIV3_1.SchemaObject = { description: requestBody.description, ...schema, }; @@ -54,7 +55,7 @@ export const parseRequestBody = ({ }: { $ref: string; context: Context; - requestBody: RequestBodyObject; + requestBody: OpenAPIV3_1.RequestBodyObject; }) => { if (!context.ir.components) { context.ir.components = {}; diff --git a/packages/shared/src/openApi/3.1.x/parser/schema.ts b/packages/shared/src/openApi/3.1.x/parser/schema.ts index cb5baa305..16e605eb0 100644 --- a/packages/shared/src/openApi/3.1.x/parser/schema.ts +++ b/packages/shared/src/openApi/3.1.x/parser/schema.ts @@ -1,3 +1,5 @@ +import type { OpenAPIV3_1 } from '@hey-api/spec-types'; + import type { Context } from '../../../ir/context'; import { isMediaTypeFileLike } from '../../../ir/mediaType'; import type { IR } from '../../../ir/types'; @@ -13,13 +15,12 @@ import { discriminatorValues, } from '../../../openApi/shared/utils/discriminator'; import { isTopLevelComponent, refToName } from '../../../utils/ref'; -import type { SchemaObject } from '../types/spec'; export const getSchemaTypes = ({ schema, }: { - schema: SchemaObject; -}): ReadonlyArray> => { + schema: OpenAPIV3_1.SchemaObject; +}): ReadonlyArray> => { if (typeof schema.type === 'string') { return [schema.type]; } @@ -47,10 +48,12 @@ const findDiscriminatorPropertyType = ({ }: { context: Context; propertyName: string; - schemas: ReadonlyArray; + schemas: ReadonlyArray; }): DiscriminatorPropertyType => { for (const schema of schemas) { - const resolved = schema.$ref ? context.resolveRef(schema.$ref) : schema; + const resolved = schema.$ref + ? context.resolveRef(schema.$ref) + : schema; // Check direct properties const property = resolved.properties?.[propertyName]; @@ -59,7 +62,7 @@ const findDiscriminatorPropertyType = ({ } if (property) { const resolvedProperty = property.$ref - ? context.resolveRef(property.$ref) + ? context.resolveRef(property.$ref) : property; // Handle both single type and array of types (3.1.x supports type arrays) const propertyTypes = Array.isArray(resolvedProperty.type) @@ -102,13 +105,13 @@ const findDiscriminatorsInSchema = ({ }: { context: Context; discriminators?: Array<{ - discriminator: NonNullable; - oneOf?: SchemaObject['oneOf']; + discriminator: NonNullable; + oneOf?: OpenAPIV3_1.SchemaObject['oneOf']; }>; - schema: SchemaObject; + schema: OpenAPIV3_1.SchemaObject; }): Array<{ - discriminator: NonNullable; - oneOf?: SchemaObject['oneOf']; + discriminator: NonNullable; + oneOf?: OpenAPIV3_1.SchemaObject['oneOf']; }> => { // Check if this schema has a discriminator if (schema.discriminator) { @@ -121,9 +124,9 @@ const findDiscriminatorsInSchema = ({ // If this schema is an allOf composition, recursively search in its components if (schema.allOf) { for (const compositionSchema of schema.allOf) { - let resolvedSchema: SchemaObject; + let resolvedSchema: OpenAPIV3_1.SchemaObject; if (compositionSchema.$ref) { - resolvedSchema = context.resolveRef(compositionSchema.$ref); + resolvedSchema = context.resolveRef(compositionSchema.$ref); } else { resolvedSchema = compositionSchema; } @@ -147,7 +150,7 @@ const getAllDiscriminatorValues = ({ discriminator, schemaRef, }: { - discriminator: NonNullable; + discriminator: NonNullable; schemaRef: string; }): Array => { const values: Array = []; @@ -168,7 +171,7 @@ const parseSchemaJsDoc = ({ schema, }: { irSchema: IR.SchemaObject; - schema: SchemaObject; + schema: OpenAPIV3_1.SchemaObject; }) => { if (schema.deprecated !== undefined) { irSchema.deprecated = schema.deprecated; @@ -192,7 +195,7 @@ const parseSchemaMeta = ({ schema, }: { irSchema: IR.SchemaObject; - schema: SchemaObject; + schema: OpenAPIV3_1.SchemaObject; }) => { if (schema.const !== undefined) { irSchema.const = schema.const; @@ -282,7 +285,7 @@ const parseArray = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: SchemaObject; + schema: OpenAPIV3_1.SchemaObject; state: SchemaState; }): IR.SchemaObject => { if ( @@ -346,7 +349,7 @@ const parseBoolean = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: SchemaObject; + schema: OpenAPIV3_1.SchemaObject; }): IR.SchemaObject => { irSchema.type = 'boolean'; @@ -358,7 +361,7 @@ const parseNull = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: SchemaObject; + schema: OpenAPIV3_1.SchemaObject; }) => { irSchema.type = 'null'; @@ -371,8 +374,8 @@ const parseNumber = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: Omit & { - type: SchemaType; + schema: Omit & { + type: SchemaType; }; }): IR.SchemaObject => { irSchema.type = schema.type; @@ -388,7 +391,7 @@ const parseObject = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: SchemaObject; + schema: OpenAPIV3_1.SchemaObject; state: SchemaState; }): IR.SchemaObject => { irSchema.type = 'object'; @@ -510,7 +513,7 @@ const parseString = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: SchemaObject; + schema: OpenAPIV3_1.SchemaObject; }): IR.SchemaObject => { irSchema.type = 'string'; @@ -525,7 +528,7 @@ export const parseExtensions = ({ source, target }: { source: object; target: ob } }; -const initIrSchema = ({ schema }: { schema: SchemaObject }): IR.SchemaObject => { +const initIrSchema = ({ schema }: { schema: OpenAPIV3_1.SchemaObject }): IR.SchemaObject => { const irSchema: IR.SchemaObject = {}; parseSchemaJsDoc({ @@ -547,7 +550,7 @@ const parseAllOf = ({ state, }: { context: Context; - schema: SchemaWithRequired; + schema: SchemaWithRequired; state: SchemaState; }): IR.SchemaObject => { let irSchema = initIrSchema({ schema }); @@ -560,7 +563,7 @@ const parseAllOf = ({ // Collect discriminator information to add after all compositions are processed type DiscriminatorInfo = { - discriminator: NonNullable; + discriminator: NonNullable; isExplicitMapping: boolean; isRequired: boolean; values: ReadonlyArray; @@ -594,7 +597,7 @@ const parseAllOf = ({ schemaItems.push(irCompositionSchema); if (compositionSchema.$ref) { - const ref = context.resolveRef(compositionSchema.$ref); + const ref = context.resolveRef(compositionSchema.$ref); // `$ref` should be passed from the root `parseSchema()` call if (state.$ref) { // Find all discriminators in the referenced schema, including nested allOf compositions @@ -644,7 +647,7 @@ const parseAllOf = ({ (ref.allOf && ref.allOf.some((item) => { const resolvedItem = item.$ref - ? context.resolveRef(item.$ref) + ? context.resolveRef(item.$ref) : item; return resolvedItem.required?.includes(d.discriminator.propertyName); }))), @@ -699,14 +702,14 @@ const parseAllOf = ({ const hasProperty = (() => { if (!item.$ref) return false; try { - const refSchema = context.resolveRef(item.$ref); + const refSchema = context.resolveRef(item.$ref); // Check if the discriminator property exists in the ref schema return ( refSchema.properties?.[discriminator.propertyName] !== undefined || (refSchema.allOf && refSchema.allOf.some((allOfItem) => { const resolved = allOfItem.$ref - ? context.resolveRef(allOfItem.$ref) + ? context.resolveRef(allOfItem.$ref) : allOfItem; return resolved.properties?.[discriminator.propertyName] !== undefined; })) @@ -786,7 +789,7 @@ const parseAllOf = ({ for (const compositionSchema of compositionSchemas) { // TODO: parser - this could be probably resolved more accurately const finalCompositionSchema = compositionSchema.$ref - ? context.resolveRef(compositionSchema.$ref) + ? context.resolveRef(compositionSchema.$ref) : compositionSchema; if (getSchemaTypes({ schema: finalCompositionSchema }).includes('object')) { @@ -846,7 +849,7 @@ const parseAnyOf = ({ state, }: { context: Context; - schema: SchemaWithRequired; + schema: SchemaWithRequired; state: SchemaState; }): IR.SchemaObject => { let irSchema = initIrSchema({ schema }); @@ -938,7 +941,7 @@ const parseEnum = ({ state, }: { context: Context; - schema: SchemaWithRequired; + schema: SchemaWithRequired; state: SchemaState; }): IR.SchemaObject => { let irSchema = initIrSchema({ schema }); @@ -950,7 +953,7 @@ const parseEnum = ({ for (const [index, enumValue] of schema.enum.entries()) { const typeOfEnumValue = typeof enumValue; - let enumType: SchemaType | undefined; + let enumType: SchemaType | undefined; if ( typeOfEnumValue === 'string' || @@ -1005,7 +1008,7 @@ const parseOneOf = ({ state, }: { context: Context; - schema: SchemaWithRequired; + schema: SchemaWithRequired; state: SchemaState; }): IR.SchemaObject => { let irSchema = initIrSchema({ schema }); @@ -1109,7 +1112,7 @@ const parseRef = ({ state, }: { context: Context; - schema: SchemaWithRequired; + schema: SchemaWithRequired; state: SchemaState; }): IR.SchemaObject => { // Inline non-component refs (e.g. #/paths/...) and deep path refs (e.g. #/components/schemas/Foo/properties/bar) @@ -1117,7 +1120,7 @@ const parseRef = ({ const isComponentsRef = isTopLevelComponent(schema.$ref); if (!isComponentsRef) { if (!state.circularReferenceTracker.has(schema.$ref)) { - const refSchema = context.resolveRef(schema.$ref); + const refSchema = context.resolveRef(schema.$ref); const originalRef = state.$ref; state.$ref = schema.$ref; const irSchema = schemaToIrSchema({ @@ -1141,7 +1144,7 @@ const parseRef = ({ irRefSchema.$ref = decodeURI(schema.$ref); if (!state.circularReferenceTracker.has(schema.$ref)) { - const refSchema = context.resolveRef(schema.$ref); + const refSchema = context.resolveRef(schema.$ref); const originalRef = state.$ref; state.$ref = schema.$ref; schemaToIrSchema({ @@ -1178,8 +1181,8 @@ const parseOneType = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: Omit & { - type: SchemaType; + schema: Omit & { + type: SchemaType; }; state: SchemaState; }): IR.SchemaObject => { @@ -1242,8 +1245,8 @@ const parseManyTypes = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: Omit & { - type: ReadonlyArray>; + schema: Omit & { + type: ReadonlyArray>; }; state: SchemaState; }): IR.SchemaObject => { @@ -1295,7 +1298,7 @@ const parseType = ({ state, }: { context: Context; - schema: SchemaWithRequired; + schema: SchemaWithRequired; state: SchemaState; }): IR.SchemaObject => { const irSchema = initIrSchema({ schema }); @@ -1333,7 +1336,7 @@ const parseUnknown = ({ }: { context: Context; irSchema?: IR.SchemaObject; - schema: SchemaObject; + schema: OpenAPIV3_1.SchemaObject; }): IR.SchemaObject => { if (!irSchema) { irSchema = initIrSchema({ schema }); @@ -1352,7 +1355,7 @@ export const schemaToIrSchema = ({ state, }: { context: Context; - schema: SchemaObject; + schema: OpenAPIV3_1.SchemaObject; state: SchemaState | undefined; }): IR.SchemaObject => { if (!state) { @@ -1368,7 +1371,7 @@ export const schemaToIrSchema = ({ if (schema.$ref) { return parseRef({ context, - schema: schema as SchemaWithRequired, + schema: schema as SchemaWithRequired, state, }); } @@ -1376,7 +1379,7 @@ export const schemaToIrSchema = ({ if (schema.enum) { return parseEnum({ context, - schema: schema as SchemaWithRequired, + schema: schema as SchemaWithRequired, state, }); } @@ -1384,7 +1387,7 @@ export const schemaToIrSchema = ({ if (schema.allOf) { return parseAllOf({ context, - schema: schema as SchemaWithRequired, + schema: schema as SchemaWithRequired, state, }); } @@ -1392,7 +1395,7 @@ export const schemaToIrSchema = ({ if (schema.anyOf) { return parseAnyOf({ context, - schema: schema as SchemaWithRequired, + schema: schema as SchemaWithRequired, state, }); } @@ -1400,7 +1403,7 @@ export const schemaToIrSchema = ({ if (schema.oneOf) { return parseOneOf({ context, - schema: schema as SchemaWithRequired, + schema: schema as SchemaWithRequired, state, }); } @@ -1409,7 +1412,7 @@ export const schemaToIrSchema = ({ if (schema.type || schema.properties) { return parseType({ context, - schema: schema as SchemaWithRequired, + schema: schema as SchemaWithRequired, state, }); } @@ -1418,7 +1421,7 @@ export const schemaToIrSchema = ({ if (schema.contentMediaType && isMediaTypeFileLike({ mediaType: schema.contentMediaType })) { return parseType({ context, - schema: { ...schema, type: 'string' } as SchemaWithRequired, + schema: { ...schema, type: 'string' } as SchemaWithRequired, state, }); } @@ -1433,7 +1436,7 @@ export const parseSchema = ({ }: { $ref: string; context: Context; - schema: SchemaObject; + schema: OpenAPIV3_1.SchemaObject; }) => { if (!context.ir.components) { context.ir.components = {}; diff --git a/packages/shared/src/openApi/3.1.x/parser/validate.ts b/packages/shared/src/openApi/3.1.x/parser/validate.ts index 85f2384e5..368562f4d 100644 --- a/packages/shared/src/openApi/3.1.x/parser/validate.ts +++ b/packages/shared/src/openApi/3.1.x/parser/validate.ts @@ -1,19 +1,22 @@ import type { Logger } from '@hey-api/codegen-core'; +import type { OpenAPIV3_1 } from '@hey-api/spec-types'; import { createOperationKey } from '../../../ir/operation'; import { httpMethods } from '../../../openApi/shared/utils/operation'; import type { ValidatorIssue, ValidatorResult } from '../../../openApi/shared/utils/validator'; -import type { OpenApiV3_1_X, PathItemObject, PathsObject } from '../types/spec'; -export const validateOpenApiSpec = (spec: OpenApiV3_1_X, logger: Logger): ValidatorResult => { +export const validateOpenApiSpec = ( + spec: OpenAPIV3_1.Document, + logger: Logger, +): ValidatorResult => { const eventValidate = logger.timeEvent('validate'); const issues: Array = []; const operationIds = new Map(); if (spec.paths) { for (const entry of Object.entries(spec.paths)) { - const path = entry[0] as keyof PathsObject; - const pathItem = entry[1] as PathItemObject; + const path = entry[0] as keyof OpenAPIV3_1.PathsObject; + const pathItem = entry[1] as OpenAPIV3_1.PathItemObject; for (const method of httpMethods) { const operation = pathItem[method]; if (!operation) { diff --git a/packages/shared/src/openApi/3.1.x/parser/webhook.ts b/packages/shared/src/openApi/3.1.x/parser/webhook.ts index 486f96bc3..bbb8f270f 100644 --- a/packages/shared/src/openApi/3.1.x/parser/webhook.ts +++ b/packages/shared/src/openApi/3.1.x/parser/webhook.ts @@ -1,6 +1,7 @@ +import type { OpenAPIV3_1 } from '@hey-api/spec-types'; + import type { Context } from '../../../ir/context'; import { mergeParametersObjects } from '../../../openApi/shared/utils/parameter'; -import type { OpenApiV3_1_X, PathItemObject } from '../types/spec'; import { parseWebhookOperation } from './operation'; import { parametersArrayToObject } from './parameter'; @@ -8,7 +9,7 @@ export const parseWebhooks = ({ context, securitySchemesMap, }: Pick[0], 'securitySchemesMap'> & { - context: Context; + context: Context; }) => { const state: Parameters[0]['state'] = { ids: new Map(), @@ -20,7 +21,7 @@ export const parseWebhooks = ({ const finalWebhook = '$ref' in webhook ? { - ...context.resolveRef(webhook.$ref!), + ...context.resolveRef(webhook.$ref!), ...webhook, } : webhook; diff --git a/packages/shared/src/openApi/__tests__/index.test.ts b/packages/shared/src/openApi/__tests__/index.test.ts index 72432d8ec..4ce617d13 100644 --- a/packages/shared/src/openApi/__tests__/index.test.ts +++ b/packages/shared/src/openApi/__tests__/index.test.ts @@ -1,10 +1,11 @@ import { Logger } from '@hey-api/codegen-core'; +import type { OpenAPIV3, OpenAPIV3_1 } from '@hey-api/spec-types'; import type { AnyConfig } from '../../config/shared'; import { Context } from '../../ir/context'; import { parseOpenApiSpec } from '..'; -import { type OpenApiV3_0_X, parseV3_0_X } from '../3.0.x'; -import { type OpenApiV3_1_X, parseV3_1_X } from '../3.1.x'; +import { parseV3_0_X } from '../3.0.x'; +import { parseV3_1_X } from '../3.1.x'; vi.mock('../3.0.x', () => ({ parseV3_0_X: vi.fn(), @@ -32,7 +33,7 @@ describe('OpenAPI parser', () => { }); it('handles OpenAPI 3.0.0', () => { - const spec: OpenApiV3_0_X = { + const spec: OpenAPIV3.Document = { info: { title: '', version: '1', @@ -64,7 +65,7 @@ describe('OpenAPI parser', () => { }); it('handles OpenAPI 3.0.1', () => { - const spec: OpenApiV3_0_X = { + const spec: OpenAPIV3.Document = { info: { title: '', version: '1', @@ -96,7 +97,7 @@ describe('OpenAPI parser', () => { }); it('handles OpenAPI 3.0.2', () => { - const spec: OpenApiV3_0_X = { + const spec: OpenAPIV3.Document = { info: { title: '', version: '1', @@ -128,7 +129,7 @@ describe('OpenAPI parser', () => { }); it('handles OpenAPI 3.0.3', () => { - const spec: OpenApiV3_0_X = { + const spec: OpenAPIV3.Document = { info: { title: '', version: '1', @@ -160,7 +161,7 @@ describe('OpenAPI parser', () => { }); it('handles OpenAPI 3.0.4', () => { - const spec: OpenApiV3_0_X = { + const spec: OpenAPIV3.Document = { info: { title: '', version: '1', @@ -192,7 +193,7 @@ describe('OpenAPI parser', () => { }); it('handles OpenAPI 3.1.0', () => { - const spec: OpenApiV3_1_X = { + const spec: OpenAPIV3_1.Document = { info: { title: '', version: '1', @@ -223,7 +224,7 @@ describe('OpenAPI parser', () => { }); it('handles OpenAPI 3.1.1', () => { - const spec: OpenApiV3_1_X = { + const spec: OpenAPIV3_1.Document = { info: { title: '', version: '1', diff --git a/packages/shared/src/openApi/shared/types/index.ts b/packages/shared/src/openApi/shared/types/index.ts deleted file mode 100644 index 94ab9c3e2..000000000 --- a/packages/shared/src/openApi/shared/types/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export type { - CodeSampleObject, - EnumExtensions, - LinguistLanguages, -} from './openapi-spec-extensions'; diff --git a/packages/shared/src/openApi/shared/utils/filter.ts b/packages/shared/src/openApi/shared/utils/filter.ts index 21583de51..48f8a06df 100644 --- a/packages/shared/src/openApi/shared/utils/filter.ts +++ b/packages/shared/src/openApi/shared/utils/filter.ts @@ -1,8 +1,8 @@ import type { Logger } from '@hey-api/codegen-core'; +import type { OpenAPIV3_1 } from '@hey-api/spec-types'; import type { Parser } from '../../../config/parser/types'; import { createOperationKey } from '../../../ir/operation'; -import type { PathItemObject, PathsObject } from '../../../openApi/3.1.x/types/spec'; import type { OpenApi } from '../../../openApi/types'; import type { ResourceMetadata } from '../graph/meta'; import { httpMethods } from './operation'; @@ -109,8 +109,8 @@ const collectFiltersSetFromRegExpsOpenApiV2 = ({ }) => { if ((excludeOperations.regexps.length || includeOperations.regexps.length) && spec.paths) { for (const entry of Object.entries(spec.paths)) { - const path = entry[0] as keyof PathsObject; - const pathItem = entry[1] as PathItemObject; + const path = entry[0] as keyof OpenAPIV3_1.PathsObject; + const pathItem = entry[1] as OpenAPIV3_1.PathItemObject; for (const method of httpMethods) { const operation = pathItem[method]; if (!operation) { @@ -161,8 +161,8 @@ const collectFiltersSetFromRegExpsOpenApiV3 = ({ }) => { if ((excludeOperations.regexps.length || includeOperations.regexps.length) && spec.paths) { for (const entry of Object.entries(spec.paths)) { - const path = entry[0] as keyof PathsObject; - const pathItem = entry[1] as PathItemObject; + const path = entry[0] as keyof OpenAPIV3_1.PathsObject; + const pathItem = entry[1] as OpenAPIV3_1.PathItemObject; for (const method of httpMethods) { const operation = pathItem[method]; if (!operation) { diff --git a/packages/shared/src/openApi/types.ts b/packages/shared/src/openApi/types.ts index 1a6cb8a0b..d012366fb 100644 --- a/packages/shared/src/openApi/types.ts +++ b/packages/shared/src/openApi/types.ts @@ -1,62 +1,52 @@ /* eslint-disable @typescript-eslint/no-namespace */ -import type { OpenApiV2_0_X, OpenApiV2_0_XTypes } from './2.0.x'; -import type { OpenApiV3_0_X, OpenApiV3_0_XTypes } from './3.0.x'; -import type { OpenApiV3_1_X, OpenApiV3_1_XTypes } from './3.1.x'; +import type { OpenAPIV2, OpenAPIV3, OpenAPIV3_1 } from '@hey-api/spec-types'; export namespace OpenApi { - export type V2_0_X = OpenApiV2_0_X; + export type V2_0_X = OpenAPIV2.Document; - export type V3_0_X = OpenApiV3_0_X; + export type V3_0_X = OpenAPIV3.Document; - export type V3_1_X = OpenApiV3_1_X; + export type V3_1_X = OpenAPIV3_1.Document; } export namespace OpenApiMetaObject { - export type V2_0_X = OpenApiV2_0_XTypes['InfoObject']; + export type V2_0_X = OpenAPIV2.InfoObject; - export type V3_0_X = OpenApiV3_0_XTypes['InfoObject']; + export type V3_0_X = OpenAPIV3.InfoObject; - export type V3_1_X = OpenApiV3_1_XTypes['InfoObject']; + export type V3_1_X = OpenAPIV3_1.InfoObject; } export namespace OpenApiOperationObject { - export type V2_0_X = OpenApiV2_0_XTypes['OperationObject']; + export type V2_0_X = OpenAPIV2.OperationObject; - export type V3_0_X = OpenApiV3_0_XTypes['OperationObject']; + export type V3_0_X = OpenAPIV3.OperationObject; - export type V3_1_X = OpenApiV3_1_XTypes['OperationObject']; + export type V3_1_X = OpenAPIV3_1.OperationObject; } export namespace OpenApiParameterObject { - export type V3_0_X = - | OpenApiV3_0_XTypes['ParameterObject'] - | OpenApiV3_0_XTypes['ReferenceObject']; + export type V3_0_X = OpenAPIV3.ParameterObject | OpenAPIV3.ReferenceObject; - export type V3_1_X = - | OpenApiV3_1_XTypes['ParameterObject'] - | OpenApiV3_1_XTypes['ReferenceObject']; + export type V3_1_X = OpenAPIV3_1.ParameterObject | OpenAPIV3_1.ReferenceObject; } export namespace OpenApiRequestBodyObject { - export type V3_0_X = - | OpenApiV3_0_XTypes['RequestBodyObject'] - | OpenApiV3_0_XTypes['ReferenceObject']; + export type V3_0_X = OpenAPIV3.RequestBodyObject | OpenAPIV3.ReferenceObject; - export type V3_1_X = - | OpenApiV3_1_XTypes['RequestBodyObject'] - | OpenApiV3_1_XTypes['ReferenceObject']; + export type V3_1_X = OpenAPIV3_1.RequestBodyObject | OpenAPIV3_1.ReferenceObject; } export namespace OpenApiResponseObject { - export type V3_0_X = OpenApiV3_0_XTypes['ResponseObject'] | OpenApiV3_0_XTypes['ReferenceObject']; + export type V3_0_X = OpenAPIV3.ResponseObject | OpenAPIV3.ReferenceObject; - export type V3_1_X = OpenApiV3_1_XTypes['ResponseObject'] | OpenApiV3_1_XTypes['ReferenceObject']; + export type V3_1_X = OpenAPIV3_1.ResponseObject | OpenAPIV3_1.ReferenceObject; } export namespace OpenApiSchemaObject { - export type V2_0_X = OpenApiV2_0_XTypes['SchemaObject']; + export type V2_0_X = OpenAPIV2.SchemaObject; - export type V3_0_X = OpenApiV3_0_XTypes['SchemaObject']; + export type V3_0_X = OpenAPIV3.SchemaObject; - export type V3_1_X = OpenApiV3_1_XTypes['SchemaObject']; + export type V3_1_X = OpenAPIV3_1.SchemaObject; } diff --git a/packages/spec-types/LICENSE.md b/packages/spec-types/LICENSE.md new file mode 100644 index 000000000..6acd8004b --- /dev/null +++ b/packages/spec-types/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Hey API + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/spec-types/README.md b/packages/spec-types/README.md new file mode 100644 index 000000000..d6bd274de --- /dev/null +++ b/packages/spec-types/README.md @@ -0,0 +1,27 @@ +
+

Spec Types

+
+ +

+ + + CI status + GitHub stars + MIT License +

+ +

+ + + Issues +  â€¢  + Contribute +

+ +## About + +TypeScript definitions for OpenAPI and JSON Schema specifications with complete inline documentation. + +Part of the Hey API ecosystem. diff --git a/packages/spec-types/package.json b/packages/spec-types/package.json new file mode 100644 index 000000000..21b644bcc --- /dev/null +++ b/packages/spec-types/package.json @@ -0,0 +1,59 @@ +{ + "name": "@hey-api/spec-types", + "version": "0.0.0", + "description": "📃 TypeScript definitions for OpenAPI and JSON Schema specifications with complete inline documentation.", + "keywords": [ + "definitions", + "documentation", + "json", + "jsonschema", + "openapi", + "schema", + "spec", + "specification", + "swagger", + "types", + "typescript" + ], + "homepage": "https://heyapi.dev/", + "bugs": { + "url": "https://github.com/hey-api/openapi-ts/issues" + }, + "license": "MIT", + "author": { + "name": "Hey API", + "email": "lubos@heyapi.dev", + "url": "https://heyapi.dev" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/hey-api/openapi-ts.git" + }, + "funding": "https://github.com/sponsors/hey-api", + "files": [ + "dist", + "LICENSE.md", + "README.md" + ], + "type": "module", + "sideEffects": false, + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts" + }, + "./package.json": "./package.json" + }, + "scripts": { + "build": "tsc --build", + "dev": "tsc --build --watch", + "prepublishOnly": "pnpm build", + "typecheck": "tsgo --noEmit" + }, + "dependencies": { + "@hey-api/types": "workspace:*" + }, + "devDependencies": { + "typescript": "5.9.3" + } +} diff --git a/packages/shared/src/openApi/shared/types/openapi-spec-extensions.ts b/packages/spec-types/src/extensions/openapi.ts similarity index 83% rename from packages/shared/src/openApi/shared/types/openapi-spec-extensions.ts rename to packages/spec-types/src/extensions/openapi.ts index 6378d8a39..ac862eec1 100644 --- a/packages/shared/src/openApi/shared/types/openapi-spec-extensions.ts +++ b/packages/spec-types/src/extensions/openapi.ts @@ -56,3 +56,12 @@ export interface EnumExtensions { */ 'x-enumNames'?: ReadonlyArray; } + +/** + * OpenAPI Specification Extensions. + * + * See {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#specification-extensions Specification Extensions}. + */ +export interface OpenAPIExtensions { + [extension: `x-${string}`]: unknown; +} diff --git a/packages/spec-types/src/index.ts b/packages/spec-types/src/index.ts new file mode 100644 index 000000000..e39aa70a1 --- /dev/null +++ b/packages/spec-types/src/index.ts @@ -0,0 +1,13 @@ +export type { + CodeSampleObject, + EnumExtensions, + LinguistLanguages, + OpenAPIExtensions, +} from './extensions/openapi'; +export type * as JSONSchemaDraft4 from './json-schema/draft-4'; +export type * as JSONSchemaDraft2020_12 from './json-schema/draft-2020-12'; +export * as JSONSchema from './json-schema/union'; +export * as OpenApi from './openapi/union'; +export type * as OpenAPIV2 from './openapi/v2'; +export type * as OpenAPIV3 from './openapi/v3'; +export type * as OpenAPIV3_1 from './openapi/v3-1'; diff --git a/packages/spec-types/src/json-schema/draft-2020-12/index.ts b/packages/spec-types/src/json-schema/draft-2020-12/index.ts new file mode 100644 index 000000000..c42a27f63 --- /dev/null +++ b/packages/spec-types/src/json-schema/draft-2020-12/index.ts @@ -0,0 +1 @@ +export type * from './spec'; diff --git a/packages/shared/src/openApi/3.1.x/types/json-schema-draft-2020-12.ts b/packages/spec-types/src/json-schema/draft-2020-12/spec.ts similarity index 94% rename from packages/shared/src/openApi/3.1.x/types/json-schema-draft-2020-12.ts rename to packages/spec-types/src/json-schema/draft-2020-12/spec.ts index 5551947a9..4cd2fc6dc 100644 --- a/packages/shared/src/openApi/3.1.x/types/json-schema-draft-2020-12.ts +++ b/packages/spec-types/src/json-schema/draft-2020-12/spec.ts @@ -1,19 +1,18 @@ import type { AnyString, MaybeArray } from '@hey-api/types'; -import type { EnumExtensions } from '../../../openApi/shared/types'; -import type { SpecificationExtensions } from './spec'; -import type { OpenApiSchemaExtensions } from './spec-extensions'; +import type { EnumExtensions, OpenAPIExtensions } from '../../extensions/openapi'; +import type { OpenAPIV3_1SchemaExtensions } from '../../openapi/v3-1/extensions'; // TODO: left out some keywords related to structuring a complex schema and declaring a dialect -export interface JsonSchemaDraft2020_12 +export interface Document extends ArrayKeywords, NumberKeywords, ObjectKeywords, StringKeywords, EnumExtensions, - OpenApiSchemaExtensions, - SpecificationExtensions { + OpenAPIV3_1SchemaExtensions, + OpenAPIExtensions { /** * The `$comment` {@link https://json-schema.org/learn/glossary#keyword keyword} is strictly intended for adding comments to a schema. Its value must always be a string. Unlike the annotations `title`, `description`, and `examples`, JSON schema {@link https://json-schema.org/learn/glossary#implementation implementations} aren't allowed to attach any meaning or behavior to it whatsoever, and may even strip them at any time. Therefore, they are useful for leaving notes to future editors of a JSON schema, but should not be used to communicate to users of the schema. */ @@ -31,13 +30,13 @@ export interface JsonSchemaDraft2020_12 * * {@link https://json-schema.org/understanding-json-schema/reference/combining#allof allOf} can not be used to "extend" a schema to add more details to it in the sense of object-oriented inheritance. {@link https://json-schema.org/learn/glossary#instance Instances} must independently be valid against "all of" the schemas in the `allOf`. See the section on {@link https://json-schema.org/understanding-json-schema/reference/object#extending Extending Closed Schemas} for more information. */ - allOf?: ReadonlyArray; + allOf?: ReadonlyArray; /** * `anyOf`: (OR) Must be valid against _any_ of the subschemas * * To validate against `anyOf`, the given data must be valid against any (one or more) of the given subschemas. */ - anyOf?: ReadonlyArray; + anyOf?: ReadonlyArray; /** * The `const` keyword is used to restrict a value to a single value. */ @@ -67,7 +66,7 @@ export interface JsonSchemaDraft2020_12 /** * The `dependentSchemas` keyword conditionally applies a {@link https://json-schema.org/learn/glossary#subschema subschema} when a given property is present. This schema is applied in the same way {@link https://json-schema.org/understanding-json-schema/reference/combining#allof allOf} applies schemas. Nothing is merged or extended. Both schemas apply independently. */ - dependentSchemas?: Record; + dependentSchemas?: Record; /** * The `deprecated` keyword is a boolean that indicates that the {@link https://json-schema.org/learn/glossary#instance instance} value the keyword applies to should not be used and may be removed in the future. */ @@ -85,7 +84,7 @@ export interface JsonSchemaDraft2020_12 * * If `then` and/or `else` appear in a schema without `if`, `then` and `else` are ignored. */ - else?: JsonSchemaDraft2020_12; + else?: Document; /** * The `enum` {@link https://json-schema.org/learn/glossary#keyword keyword} is used to restrict a value to a fixed set of values. It must be an array with at least one element, where each element is unique. * @@ -113,13 +112,13 @@ export interface JsonSchemaDraft2020_12 * * If `then` and/or `else` appear in a schema without `if`, `then` and `else` are ignored. */ - if?: JsonSchemaDraft2020_12; + if?: Document; /** * `not`: (NOT) Must _not_ be valid against the given schema * * The `not` keyword declares that an instance validates if it doesn't validate against the given subschema. */ - not?: JsonSchemaDraft2020_12; + not?: Document; /** * `oneOf`: (XOR) Must be valid against _exactly one_ of the subschemas * @@ -127,7 +126,7 @@ export interface JsonSchemaDraft2020_12 * * Careful consideration should be taken when using `oneOf` entries as the nature of it requires verification of _every_ sub-schema which can lead to increased processing times. Prefer `anyOf` where possible. */ - oneOf?: ReadonlyArray; + oneOf?: ReadonlyArray; /** * The boolean keywords `readOnly` and `writeOnly` are typically used in an API context. `readOnly` indicates that a value should not be modified. It could be used to indicate that a `PUT` request that changes a value would result in a `400 Bad Request` response. `writeOnly` indicates that a value may be set, but will remain hidden. In could be used to indicate you can set a value with a `PUT` request, but it would not be included when retrieving that record with a `GET` request. */ @@ -141,7 +140,7 @@ export interface JsonSchemaDraft2020_12 * * If `then` and/or `else` appear in a schema without `if`, `then` and `else` are ignored. */ - then?: JsonSchemaDraft2020_12; + then?: Document; /** * The `title` and `description` keywords must be strings. A "title" will preferably be short, whereas a "description" will provide a more lengthy explanation about the purpose of the data described by the schema. */ @@ -156,11 +155,11 @@ export interface JsonSchemaDraft2020_12 writeOnly?: boolean; } -interface ArrayKeywords { +export interface ArrayKeywords { /** * While the `items` schema must be valid for every item in the array, the `contains` schema only needs to validate against one or more items in the array. */ - contains?: JsonSchemaDraft2020_12; + contains?: Document; /** * List validation is useful for arrays of arbitrary length where each item matches the same schema. For this kind of array, set the `items` {@link https://json-schema.org/learn/glossary#keyword keyword} to a single schema that will be used to validate all of the items in the array. * @@ -168,7 +167,7 @@ interface ArrayKeywords { * * Note that `items` doesn't "see inside" any {@link https://json-schema.org/learn/glossary#instance instances} of `allOf`, `anyOf`, or `oneOf` in the same {@link https://json-schema.org/learn/glossary#subschema subschema}. */ - items?: JsonSchemaDraft2020_12 | false; + items?: Document | false; /** * `minContains` and `maxContains` can be used with `contains` to further specify how many times a schema matches a `contains` constraint. These keywords can be any non-negative number including zero. */ @@ -188,7 +187,7 @@ interface ArrayKeywords { /** * `prefixItems` is an array, where each item is a schema that corresponds to each index of the document's array. That is, an array where the first element validates the first element of the input array, the second element validates the second element of the input array, etc. */ - prefixItems?: ReadonlyArray; + prefixItems?: ReadonlyArray; /** * The `unevaluatedItems` keyword is useful mainly when you want to add or disallow extra items to an array. * @@ -198,14 +197,14 @@ interface ArrayKeywords { * * Like with `items`, if you set `unevaluatedItems` to false, you can disallow extra items in the array. */ - unevaluatedItems?: JsonSchemaDraft2020_12 | false; + unevaluatedItems?: Document | false; /** * A schema can ensure that each of the items in an array is unique. Simply set the `uniqueItems` keyword to `true`. */ uniqueItems?: boolean; } -interface NumberKeywords { +export interface NumberKeywords { /** * Ranges of numbers are specified using a combination of the `minimum` and `maximum` keywords, (or `exclusiveMinimum` and `exclusiveMaximum` for expressing exclusive range). * @@ -272,7 +271,7 @@ interface NumberKeywords { multipleOf?: number; } -interface ObjectKeywords { +export interface ObjectKeywords { /** * The `additionalProperties` keyword is used to control the handling of extra stuff, that is, properties whose names are not listed in the `properties` keyword or match any of the regular expressions in the `patternProperties` keyword. By default any additional properties are allowed. * @@ -280,7 +279,7 @@ interface ObjectKeywords { * * It's important to note that `additionalProperties` only recognizes properties declared in the same {@link https://json-schema.org/learn/glossary#subschema subschema} as itself. So, `additionalProperties` can restrict you from "extending" a schema using {@link https://json-schema.org/understanding-json-schema/reference/combining combining} keywords such as {@link https://json-schema.org/understanding-json-schema/reference/combining#allof allOf}. */ - additionalProperties?: JsonSchemaDraft2020_12 | false; + additionalProperties?: Document | false; /** * The number of properties on an object can be restricted using the `minProperties` and `maxProperties` keywords. Each of these must be a non-negative integer. */ @@ -292,11 +291,11 @@ interface ObjectKeywords { /** * Sometimes you want to say that, given a particular kind of property name, the value should match a particular schema. That's where `patternProperties` comes in: it maps regular expressions to schemas. If a property name matches the given regular expression, the property value must validate against the corresponding schema. */ - patternProperties?: Record; + patternProperties?: Record; /** * The properties (key-value pairs) on an object are defined using the `properties` {@link https://json-schema.org/learn/glossary#keyword keyword}. The value of `properties` is an object, where each key is the name of a property and each value is a {@link https://json-schema.org/learn/glossary#schema schema} used to validate that property. Any property that doesn't match any of the property names in the `properties` keyword is ignored by this keyword. */ - properties?: Record; + properties?: Record; /** * The names of properties can be validated against a schema, irrespective of their values. This can be useful if you don't want to enforce specific properties, but you want to make sure that the names of those properties follow a specific convention. You might, for example, want to enforce that all names are valid ASCII tokens so they can be used as attributes in a particular programming language. * @@ -306,7 +305,7 @@ interface ObjectKeywords { * { "type": "string" } * ``` */ - propertyNames?: JsonSchemaDraft2020_12; + propertyNames?: Document; /** * By default, the properties defined by the `properties` keyword are not required. However, one can provide a list of required properties using the `required` keyword. * @@ -318,10 +317,10 @@ interface ObjectKeywords { * * `unevaluatedProperties` works by collecting any properties that are successfully validated when processing the schemas and using those as the allowed list of properties. This allows you to do more complex things like conditionally adding properties. */ - unevaluatedProperties?: JsonSchemaDraft2020_12 | false; + unevaluatedProperties?: Document | false; } -interface StringKeywords { +export interface StringKeywords { /** * The length of a string can be constrained using the `minLength` and `maxLength` {@link https://json-schema.org/learn/glossary#keyword keywords}. For both keywords, the value must be a non-negative number. */ @@ -336,7 +335,7 @@ interface StringKeywords { pattern?: string; } -type JsonSchemaFormats = +export type JsonSchemaFormats = | 'date' | 'date-time' | 'duration' @@ -358,4 +357,11 @@ type JsonSchemaFormats = | 'uuid' | AnyString; -type JsonSchemaTypes = 'array' | 'boolean' | 'integer' | 'null' | 'number' | 'object' | 'string'; +export type JsonSchemaTypes = + | 'array' + | 'boolean' + | 'integer' + | 'null' + | 'number' + | 'object' + | 'string'; diff --git a/packages/spec-types/src/json-schema/draft-4/index.ts b/packages/spec-types/src/json-schema/draft-4/index.ts new file mode 100644 index 000000000..c42a27f63 --- /dev/null +++ b/packages/spec-types/src/json-schema/draft-4/index.ts @@ -0,0 +1 @@ +export type * from './spec'; diff --git a/packages/shared/src/openApi/2.0.x/types/json-schema-draft-4.ts b/packages/spec-types/src/json-schema/draft-4/spec.ts similarity index 96% rename from packages/shared/src/openApi/2.0.x/types/json-schema-draft-4.ts rename to packages/spec-types/src/json-schema/draft-4/spec.ts index ac0d3ea9a..2d012391d 100644 --- a/packages/shared/src/openApi/2.0.x/types/json-schema-draft-4.ts +++ b/packages/spec-types/src/json-schema/draft-4/spec.ts @@ -1,8 +1,8 @@ import type { AnyString } from '@hey-api/types'; -import type { EnumExtensions } from '../../../openApi/shared/types'; +import type { EnumExtensions } from '../../extensions/openapi'; -export interface JsonSchemaDraft4 extends EnumExtensions { +export interface Document extends EnumExtensions { /** * A schema can reference another schema using the `$ref` keyword. The value of `$ref` is a URI-reference that is resolved against the schema's {@link https://json-schema.org/understanding-json-schema/structuring#base-uri Base URI}. When evaluating a `$ref`, an implementation uses the resolved identifier to retrieve the referenced schema and applies that schema to the {@link https://json-schema.org/learn/glossary#instance instance}. * @@ -143,6 +143,13 @@ export interface JsonSchemaDraft4 extends EnumExtensions { uniqueItems?: boolean; } -type JsonSchemaFormats = 'date-time' | 'email' | 'hostname' | 'ipv4' | 'ipv6' | 'uri' | AnyString; +export type JsonSchemaFormats = + | 'date-time' + | 'email' + | 'hostname' + | 'ipv4' + | 'ipv6' + | 'uri' + | AnyString; -type JsonSchemaTypes = 'array' | 'boolean' | 'integer' | 'number' | 'object' | 'string'; +export type JsonSchemaTypes = 'array' | 'boolean' | 'integer' | 'number' | 'object' | 'string'; diff --git a/packages/spec-types/src/json-schema/union.ts b/packages/spec-types/src/json-schema/union.ts new file mode 100644 index 000000000..0670fb058 --- /dev/null +++ b/packages/spec-types/src/json-schema/union.ts @@ -0,0 +1,7 @@ +import type { Document as JSONSchemaDraft4 } from './draft-4'; +import type { Document as JSONSchemaDraft2020_12 } from './draft-2020-12'; + +/** + * Union of all supported JSON Schema document versions. + */ +export type Document = JSONSchemaDraft4 | JSONSchemaDraft2020_12; diff --git a/packages/spec-types/src/openapi/union.ts b/packages/spec-types/src/openapi/union.ts new file mode 100644 index 000000000..f45b22a63 --- /dev/null +++ b/packages/spec-types/src/openapi/union.ts @@ -0,0 +1,8 @@ +import type { Document as OpenAPIV2 } from './v2'; +import type { Document as OpenAPIV3 } from './v3'; +import type { Document as OpenAPIV3_1 } from './v3-1'; + +/** + * Union of all supported OpenAPI document versions. + */ +export type Document = OpenAPIV2 | OpenAPIV3 | OpenAPIV3_1; diff --git a/packages/shared/src/openApi/2.0.x/types/openapi-spec-extensions.ts b/packages/spec-types/src/openapi/v2/extensions.ts similarity index 75% rename from packages/shared/src/openApi/2.0.x/types/openapi-spec-extensions.ts rename to packages/spec-types/src/openapi/v2/extensions.ts index c734de5aa..ea0936404 100644 --- a/packages/shared/src/openApi/2.0.x/types/openapi-spec-extensions.ts +++ b/packages/spec-types/src/openapi/v2/extensions.ts @@ -1,4 +1,4 @@ -export interface OpenApiV2_0_X_Nullable_Extensions { +export interface OpenAPIV2NullableExtensions { /** * OpenAPI 2.0 does not natively support null as a type, but you can use * `x-nullable` to polyfill this functionality. diff --git a/packages/spec-types/src/openapi/v2/index.ts b/packages/spec-types/src/openapi/v2/index.ts new file mode 100644 index 000000000..7c480d861 --- /dev/null +++ b/packages/spec-types/src/openapi/v2/index.ts @@ -0,0 +1,2 @@ +export type { OpenAPIV2NullableExtensions as NullableExtensions } from './extensions'; +export type * from './spec'; diff --git a/packages/shared/src/openApi/2.0.x/types/spec.ts b/packages/spec-types/src/openapi/v2/spec.ts similarity index 99% rename from packages/shared/src/openApi/2.0.x/types/spec.ts rename to packages/spec-types/src/openapi/v2/spec.ts index 637192ef4..f39c33c96 100644 --- a/packages/shared/src/openApi/2.0.x/types/spec.ts +++ b/packages/spec-types/src/openapi/v2/spec.ts @@ -1,11 +1,11 @@ -import type { CodeSampleObject, EnumExtensions } from '../../../openApi/shared/types'; -import type { JsonSchemaDraft4 } from './json-schema-draft-4'; -import type { OpenApiV2_0_X_Nullable_Extensions } from './openapi-spec-extensions'; +import type { CodeSampleObject, EnumExtensions } from '../../extensions/openapi'; +import type { Document as JSONSchemaDraft4 } from '../../json-schema/draft-4/spec'; +import type { OpenAPIV2NullableExtensions } from './extensions'; /** * This is the root document object for the API specification. It combines what previously was the Resource Listing and API Declaration (version 1.2 and earlier) together into one document. */ -export interface OpenApiV2_0_X { +export interface Document { /** * Allows extensions to the Swagger Schema. The field name MUST begin with `x-`, for example, `x-internal-id`. The value can be `null`, a primitive, an array or an object. See {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#specification-extensions Vendor Extensions} for further details. */ @@ -192,7 +192,7 @@ export interface ExternalDocumentationObject { * type: integer * ``` */ -export interface HeaderObject extends EnumExtensions, OpenApiV2_0_X_Nullable_Extensions { +export interface HeaderObject extends EnumExtensions, OpenAPIV2NullableExtensions { /** * Allows extensions to the Swagger Schema. The field name MUST begin with `x-`, for example, `x-internal-id`. The value can be `null`, a primitive, an array or an object. See {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#specification-extensions Vendor Extensions} for further details. */ @@ -378,7 +378,7 @@ export interface InfoObject { * maximum: 63 * ``` */ -export interface ItemsObject extends EnumExtensions, OpenApiV2_0_X_Nullable_Extensions { +export interface ItemsObject extends EnumExtensions, OpenAPIV2NullableExtensions { /** * Allows extensions to the Swagger Schema. The field name MUST begin with `x-`, for example, `x-internal-id`. The value can be `null`, a primitive, an array or an object. See {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#specification-extensions Vendor Extensions} for further details. */ @@ -684,7 +684,7 @@ export interface OperationObject { * ``` */ export type ParameterObject = EnumExtensions & - OpenApiV2_0_X_Nullable_Extensions & { + OpenAPIV2NullableExtensions & { /** * Allows extensions to the Swagger Schema. The field name MUST begin with `x-`, for example, `x-internal-id`. The value can be `null`, a primitive, an array or an object. See {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#specification-extensions Vendor Extensions} for further details. */ @@ -1306,7 +1306,7 @@ export interface ResponsesObject { * - packSize * ``` */ -export interface SchemaObject extends JsonSchemaDraft4, OpenApiV2_0_X_Nullable_Extensions { +export interface SchemaObject extends JSONSchemaDraft4, OpenAPIV2NullableExtensions { /** * Allows extensions to the Swagger Schema. The field name MUST begin with `x-`, for example, `x-internal-id`. The value can be `null`, a primitive, an array or an object. See {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#specification-extensions Vendor Extensions} for further details. */ diff --git a/packages/shared/src/openApi/3.1.x/types/spec-extensions.ts b/packages/spec-types/src/openapi/v3-1/extensions.ts similarity index 96% rename from packages/shared/src/openApi/3.1.x/types/spec-extensions.ts rename to packages/spec-types/src/openapi/v3-1/extensions.ts index da6c4f978..1ab47f5f7 100644 --- a/packages/shared/src/openApi/3.1.x/types/spec-extensions.ts +++ b/packages/spec-types/src/openapi/v3-1/extensions.ts @@ -1,6 +1,6 @@ import type { DiscriminatorObject, ExternalDocumentationObject, XMLObject } from './spec'; -export interface OpenApiSchemaExtensions { +export interface OpenAPIV3_1SchemaExtensions { /** * Adds support for polymorphism. The discriminator is an object name that is used to differentiate between other schemas which may satisfy the payload description. See {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#composition-and-inheritance-polymorphism Composition and Inheritance} for more details. */ diff --git a/packages/spec-types/src/openapi/v3-1/index.ts b/packages/spec-types/src/openapi/v3-1/index.ts new file mode 100644 index 000000000..dff204196 --- /dev/null +++ b/packages/spec-types/src/openapi/v3-1/index.ts @@ -0,0 +1,2 @@ +export type { OpenAPIV3_1SchemaExtensions as Extensions } from './extensions'; +export type * from './spec'; diff --git a/packages/shared/src/openApi/3.1.x/types/spec.ts b/packages/spec-types/src/openapi/v3-1/spec.ts similarity index 97% rename from packages/shared/src/openApi/3.1.x/types/spec.ts rename to packages/spec-types/src/openapi/v3-1/spec.ts index 34b1f5515..378081946 100644 --- a/packages/shared/src/openApi/3.1.x/types/spec.ts +++ b/packages/spec-types/src/openapi/v3-1/spec.ts @@ -1,21 +1,12 @@ -import type { CodeSampleObject } from '../../../openApi/shared/types'; -import type { JsonSchemaDraft2020_12 } from './json-schema-draft-2020-12'; - -/** - * OpenAPI Specification Extensions. - * - * See {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#specification-extensions Specification Extensions}. - */ -export interface SpecificationExtensions { - [extension: `x-${string}`]: unknown; -} +import type { CodeSampleObject, OpenAPIExtensions } from '../../extensions/openapi'; +import type { Document as JSONSchemaDraft2020_12 } from '../../json-schema/draft-2020-12'; /** * This is the root object of the {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#openapi-document OpenAPI document}. * * This object MAY be extended with {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#specification-extensions Specification Extensions}. */ -export interface OpenApiV3_1_X extends SpecificationExtensions { +export interface Document extends OpenAPIExtensions { /** * An element to hold various schemas for the document. */ @@ -139,7 +130,7 @@ export interface OpenApiV3_1_X extends SpecificationExtensions { * description: callback successfully processed * ``` */ -export interface CallbackObject extends SpecificationExtensions { +export interface CallbackObject extends OpenAPIExtensions { /** * A Path Item Object, or a reference to one, used to define a callback request and expected responses. A {@link https://github.com/OAI/OpenAPI-Specification/blob/main/examples/v3.0/callback-example.yaml complete example} is available. */ @@ -235,7 +226,7 @@ export interface CallbackObject extends SpecificationExtensions { * read:pets: read your pets * ``` */ -export interface ComponentsObject extends SpecificationExtensions { +export interface ComponentsObject extends OpenAPIExtensions { /** * An object to hold reusable {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#callback-object Callback Objects}. */ @@ -290,7 +281,7 @@ export interface ComponentsObject extends SpecificationExtensions { * email: support@example.com * ``` */ -export interface ContactObject extends SpecificationExtensions { +export interface ContactObject extends OpenAPIExtensions { /** * The email address of the contact person/organization. This MUST be in the form of an email address. */ @@ -431,7 +422,7 @@ export interface ContactObject extends SpecificationExtensions { * * will map to `Dog` because of the definition in the `mapping` element. */ -export interface DiscriminatorObject extends SpecificationExtensions { +export interface DiscriminatorObject extends OpenAPIExtensions { /** * An object to hold mappings between payload values and schema names or references. */ @@ -483,7 +474,7 @@ export interface DiscriminatorObject extends SpecificationExtensions { * type: integer * ``` */ -export interface EncodingObject extends SpecificationExtensions { +export interface EncodingObject extends OpenAPIExtensions { /** * Determines whether the parameter value SHOULD allow reserved characters, as defined by {@link https://tools.ietf.org/html/rfc3986#section-2.2 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 {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#encodingContentType `contentType`} (implicit or explicit) SHALL be ignored. */ @@ -579,7 +570,7 @@ export interface EncodingObject extends SpecificationExtensions { * $ref: '#/components/examples/confirmation-success' * ``` */ -export interface ExampleObject extends SpecificationExtensions { +export interface ExampleObject extends OpenAPIExtensions { /** * Long description for the example. {@link https://spec.commonmark.org/ CommonMark syntax} MAY be used for rich text representation. */ @@ -609,7 +600,7 @@ export interface ExampleObject extends SpecificationExtensions { * url: https://example.com * ``` */ -export interface ExternalDocumentationObject extends SpecificationExtensions { +export interface ExternalDocumentationObject extends OpenAPIExtensions { /** * A description of the target documentation. {@link https://spec.commonmark.org/ CommonMark syntax} MAY be used for rich text representation. */ @@ -657,7 +648,7 @@ export type HeaderObject = Omit; * version: 1.0.1 * ``` */ -export interface InfoObject extends SpecificationExtensions { +export interface InfoObject extends OpenAPIExtensions { /** * The contact information for the exposed API. */ @@ -699,7 +690,7 @@ export interface InfoObject extends SpecificationExtensions { * identifier: Apache-2.0 * ``` */ -export interface LicenseObject extends SpecificationExtensions { +export interface LicenseObject extends OpenAPIExtensions { /** * An {@link https://spdx.org/licenses/ SPDX} license expression for the API. The `identifier` field is mutually exclusive of the `url` field. */ @@ -861,7 +852,7 @@ export interface LicenseObject extends SpecificationExtensions { * * Runtime expressions preserve the type of the referenced value. Expressions can be embedded into string values by surrounding the expression with `{}` curly braces. */ -export interface LinkObject extends SpecificationExtensions { +export interface LinkObject extends OpenAPIExtensions { /** * A description of the link. {@link https://spec.commonmark.org/ CommonMark syntax} MAY be used for rich text representation. */ @@ -921,7 +912,7 @@ export interface LinkObject extends SpecificationExtensions { * $ref: "#/components/examples/frog-example" * ``` */ -export interface MediaTypeObject extends SpecificationExtensions { +export interface MediaTypeObject extends OpenAPIExtensions { /** * A map between a property name and its encoding information. The key, being the property name, MUST exist in the schema as a property. The encoding object SHALL only apply to `requestBody` objects when the media type is `multipart` or `application/x-www-form-urlencoded`. */ @@ -963,7 +954,7 @@ export interface MediaTypeObject extends SpecificationExtensions { * read:pets: read your pets * ``` */ -export interface OAuthFlowObject extends SpecificationExtensions { +export interface OAuthFlowObject extends OpenAPIExtensions { /** * **REQUIRED (`"implicit"`, `"authorizationCode"`)**. The authorization URL to be used for this flow. This MUST be in the form of a URL. The OAuth2 standard requires the use of TLS. */ @@ -987,7 +978,7 @@ export interface OAuthFlowObject extends SpecificationExtensions { * * This object MAY be extended with {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#specification-extensions Specification Extensions}. */ -export interface OAuthFlowsObject extends SpecificationExtensions { +export interface OAuthFlowsObject extends OpenAPIExtensions { /** * Configuration for the OAuth Authorization Code flow. Previously called `accessCode` in OpenAPI 2.0. */ @@ -1055,7 +1046,7 @@ export interface OAuthFlowsObject extends SpecificationExtensions { * - read:pets * ``` */ -export interface OperationObject extends SpecificationExtensions { +export interface OperationObject extends OpenAPIExtensions { /** * A map of possible out-of band callbacks related to the parent operation. The key is a unique identifier for the Callback Object. Each value in the map is a {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#callback-object Callback Object} that describes a request that may be initiated by the API provider and the expected responses. */ @@ -1207,7 +1198,7 @@ export interface OperationObject extends SpecificationExtensions { * type: number * ``` */ -export interface ParameterObject extends SpecificationExtensions { +export interface ParameterObject extends OpenAPIExtensions { /** * Sets the ability to pass empty-valued parameters. This is valid only for `query` parameters and allows sending a parameter with an empty value. Default value is `false`. If {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameterStyle `style`} is used, and if behavior is `n/a` (cannot be serialized), the value of `allowEmptyValue` SHALL be ignored. Use of this property is NOT RECOMMENDED, as it is likely to be removed in a later revision. */ @@ -1310,7 +1301,7 @@ export interface ParameterObject extends SpecificationExtensions { * style: simple * ``` */ -export interface PathItemObject extends SpecificationExtensions { +export interface PathItemObject extends OpenAPIExtensions { /** * Allows for a referenced definition of this path item. The referenced structure MUST be in the form of a {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#path-item-object Path Item Object}. In case a Path Item Object field appears both in the defined object and the referenced object, the behavior is undefined. See the rules for resolving {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#relative-references-in-uris Relative References}. */ @@ -1410,7 +1401,7 @@ export interface PathItemObject extends SpecificationExtensions { * $ref: '#/components/schemas/pet' * ``` */ -export interface PathsObject extends SpecificationExtensions { +export interface PathsObject extends OpenAPIExtensions { /** * A relative path to an individual endpoint. The field name MUST begin with a forward slash (`/`). The path is **appended** (no relative URL resolution) to the expanded URL from the {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#server-object `Server Object`}'s `url` field in order to construct the full URL. {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#path-templating Path templating} is allowed. When matching URLs, concrete (non-templated) paths would be matched before their templated counterparts. Templated paths with the same hierarchy but different templated names MUST NOT exist as they are identical. In case of ambiguous matching, it's up to the tooling to decide which one to use. */ @@ -1515,7 +1506,7 @@ export interface ReferenceObject { * type: string * ``` */ -export interface RequestBodyObject extends SpecificationExtensions { +export interface RequestBodyObject extends OpenAPIExtensions { /** * **REQUIRED**. The content of the request body. The key is a media type or {@link https://tools.ietf.org/html/rfc7231#appendix-D media type range} and the value describes it. For requests that match multiple keys, only the most specific key is applicable. e.g. text/plain overrides text/* */ @@ -1591,7 +1582,7 @@ export interface RequestBodyObject extends SpecificationExtensions { * description: object created * ``` */ -export interface ResponseObject extends SpecificationExtensions { +export interface ResponseObject extends OpenAPIExtensions { /** * A map containing descriptions of potential response payloads. The key is a media type or {@link https://datatracker.ietf.org/doc/html/rfc7231#appendix-D media type range} and the value describes it. For responses that match multiple keys, only the most specific key is applicable. e.g. text/plain overrides text/* */ @@ -1639,7 +1630,7 @@ export interface ResponseObject extends SpecificationExtensions { * $ref: '#/components/schemas/ErrorModel' * ``` */ -export interface ResponsesObject extends SpecificationExtensions { +export interface ResponsesObject extends OpenAPIExtensions { /** * 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. */ @@ -1674,7 +1665,7 @@ export interface ResponsesObject extends SpecificationExtensions { * * This object MAY be extended with {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#specification-extensions Specification Extensions}, though as noted, additional properties MAY omit the `x-` prefix within this object. */ -export type SchemaObject = JsonSchemaDraft2020_12 & SpecificationExtensions; +export type SchemaObject = JSONSchemaDraft2020_12 & OpenAPIExtensions; /** * Lists the required security schemes to execute this operation. The name used for each property MUST correspond to a security scheme declared in the {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#componentsSecuritySchemes Security Schemes} under the {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#components-object Components Object}. @@ -1761,7 +1752,7 @@ export interface SecurityRequirementObject { * read:pets: read your pets * ``` */ -export type SecuritySchemeObject = SpecificationExtensions & { +export type SecuritySchemeObject = OpenAPIExtensions & { /** * A description for security scheme. {@link https://spec.commonmark.org/ CommonMark syntax} MAY be used for rich text representation. */ @@ -1834,7 +1825,7 @@ export type SecuritySchemeObject = SpecificationExtensions & { * description: Development server * ``` */ -export interface ServerObject extends SpecificationExtensions { +export interface ServerObject extends OpenAPIExtensions { /** * An optional string describing the host designated by the URL. {@link https://spec.commonmark.org/ CommonMark syntax} MAY be used for rich text representation. */ @@ -1854,7 +1845,7 @@ export interface ServerObject extends SpecificationExtensions { * * This object MAY be extended with {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#specification-extensions Specification Extensions}. */ -export interface ServerVariableObject extends SpecificationExtensions { +export interface ServerVariableObject extends OpenAPIExtensions { /** * **REQUIRED**. The default value to use for substitution, which SHALL be sent if an alternate value is _not_ supplied. Note this behavior is different than the {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#schema-object Schema Object's} treatment of default values, because in those cases parameter values are optional. If the {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#serverVariableEnum `enum`} is defined, the value MUST exist in the enum's values. */ @@ -1880,7 +1871,7 @@ export interface ServerVariableObject extends SpecificationExtensions { * description: Pets operations * ``` */ -export interface TagObject extends SpecificationExtensions { +export interface TagObject extends OpenAPIExtensions { /** * A description for the tag. {@link https://spec.commonmark.org/ CommonMark syntax} MAY be used for rich text representation. */ @@ -2087,7 +2078,7 @@ export interface TagObject extends SpecificationExtensions { * * ``` */ -export interface XMLObject extends SpecificationExtensions { +export interface XMLObject extends OpenAPIExtensions { /** * Declares whether the property definition translates to an attribute instead of an element. Default value is `false`. */ diff --git a/packages/spec-types/src/openapi/v3/index.ts b/packages/spec-types/src/openapi/v3/index.ts new file mode 100644 index 000000000..c42a27f63 --- /dev/null +++ b/packages/spec-types/src/openapi/v3/index.ts @@ -0,0 +1 @@ +export type * from './spec'; diff --git a/packages/shared/src/openApi/3.0.x/types/spec.ts b/packages/spec-types/src/openapi/v3/spec.ts similarity index 97% rename from packages/shared/src/openApi/3.0.x/types/spec.ts rename to packages/spec-types/src/openapi/v3/spec.ts index 0062fd1bb..0c31a8d13 100644 --- a/packages/shared/src/openApi/3.0.x/types/spec.ts +++ b/packages/spec-types/src/openapi/v3/spec.ts @@ -1,22 +1,11 @@ -import type { AnyString } from '@hey-api/types'; - -import type { CodeSampleObject, EnumExtensions } from '../../../openApi/shared/types'; - -/** - * OpenAPI Specification Extensions. - * - * See {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#specification-extensions Specification Extensions}. - */ -export interface SpecificationExtensions { - [extension: `x-${string}`]: unknown; -} +import type { CodeSampleObject, EnumExtensions, OpenAPIExtensions } from '../../extensions/openapi'; /** * This is the root object of the {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#openapi-description OpenAPI Description}. * * This object MAY be extended with {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#specification-extensions Specification Extensions}. */ -export interface OpenApiV3_0_X extends SpecificationExtensions { +export interface Document extends OpenAPIExtensions { /** * An element to hold various Objects for the OpenAPI Description. */ @@ -58,7 +47,7 @@ export interface OpenApiV3_0_X extends SpecificationExtensions { * * TODO: examples */ -export interface CallbackObject extends SpecificationExtensions { +export interface CallbackObject extends OpenAPIExtensions { /** * A Path Item Object used to define a callback request and expected responses. A {@link https://learn.openapis.org/examples/v3.0/callback-example.html complete example} is available. */ @@ -74,7 +63,7 @@ export interface CallbackObject extends SpecificationExtensions { * * TODO: examples */ -export interface ComponentsObject extends SpecificationExtensions { +export interface ComponentsObject extends OpenAPIExtensions { /** * An object to hold reusable {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#callback-object Callback Objects}. */ @@ -124,7 +113,7 @@ export interface ComponentsObject extends SpecificationExtensions { * email: support@example.com * ``` */ -export interface ContactObject extends SpecificationExtensions { +export interface ContactObject extends OpenAPIExtensions { /** * The email address of the contact person/organization. This MUST be in the form of an email address. */ @@ -171,7 +160,7 @@ export interface DiscriminatorObject { * TODO: default values examples * TODO: examples */ -export interface EncodingObject extends SpecificationExtensions { +export interface EncodingObject extends OpenAPIExtensions { /** * When this is true, parameter values are serialized using reserved expansion, as defined by {@link https://datatracker.ietf.org/doc/html/rfc6570#section-3.2.3 RFC6570}, which allows {@link https://datatracker.ietf.org/doc/html/rfc3986#section-2.2 RFC3986's reserved character set}, as well as percent-encoded triples, to pass through unchanged, while still percent-encoding all other disallowed characters (including `%` outside of percent-encoded triples). Applications are still responsible for percent-encoding reserved characters that are {@link https://datatracker.ietf.org/doc/html/rfc3986#section-3.4 not allowed in the query string} (`[`, `]`, `#`), or have a special meaning in `application/x-www-form-urlencoded` (`-`, `&`, `+`); see Appendices {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#appendix-c-using-rfc6570-based-serialization C} and {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#appendix-e-percent-encoding-and-form-media-types E} for details. The default value is `false`. This field SHALL be ignored if the request body media type is not `application/x-www-form-urlencoded`. */ @@ -212,7 +201,7 @@ export interface EncodingObject extends SpecificationExtensions { * * TODO: examples */ -export interface ExampleObject extends SpecificationExtensions { +export interface ExampleObject extends OpenAPIExtensions { /** * Long description for the example. {@link https://spec.commonmark.org/ CommonMark syntax} MAY be used for rich text representation. */ @@ -243,7 +232,7 @@ export interface ExampleObject extends SpecificationExtensions { * url: https://example.com * ``` */ -export interface ExternalDocumentationObject extends SpecificationExtensions { +export interface ExternalDocumentationObject extends OpenAPIExtensions { /** * A description of the target documentation. {@link https://spec.commonmark.org/ CommonMark syntax} MAY be used for rich text representation. */ @@ -287,7 +276,7 @@ export type HeaderObject = Omit; * version: 1.0.1 * ``` */ -export interface InfoObject extends SpecificationExtensions { +export interface InfoObject extends OpenAPIExtensions { /** * The contact information for the exposed API. */ @@ -324,7 +313,7 @@ export interface InfoObject extends SpecificationExtensions { * url: https://www.apache.org/licenses/LICENSE-2.0.html * ``` */ -export interface LicenseObject extends SpecificationExtensions { +export interface LicenseObject extends OpenAPIExtensions { /** * **REQUIRED**. The license name used for the API. */ @@ -350,7 +339,7 @@ export interface LicenseObject extends SpecificationExtensions { * * TODO: examples */ -export interface LinkObject extends SpecificationExtensions { +export interface LinkObject extends OpenAPIExtensions { /** * A description of the link. {@link https://spec.commonmark.org/ CommonMark syntax} MAY be used for rich text representation. */ @@ -386,7 +375,7 @@ export interface LinkObject extends SpecificationExtensions { * * TODO: examples */ -export interface MediaTypeObject extends SpecificationExtensions { +export interface MediaTypeObject extends OpenAPIExtensions { /** * A map between a property name and its encoding information. The key, being the property name, MUST exist in the schema as a property. The `encoding` field SHALL only apply to {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#request-body-object Request Body Objects}, and only when the media type is `multipart` or `application/x-www-form-urlencoded`. If no Encoding Object is provided for a property, the behavior is determined by the default values documented for the Encoding Object. */ @@ -412,7 +401,7 @@ export interface MediaTypeObject extends SpecificationExtensions { * * TODO: examples */ -export interface OAuthFlowObject extends SpecificationExtensions { +export interface OAuthFlowObject extends OpenAPIExtensions { /** * **REQUIRED (`"implicit"`, `"authorizationCode"`)**. The authorization URL to be used for this flow. This MUST be in the form of a URL. The OAuth2 standard requires the use of TLS. */ @@ -436,7 +425,7 @@ export interface OAuthFlowObject extends SpecificationExtensions { * * This object MAY be extended with {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#specification-extensions Specification Extensions}. */ -export interface OAuthFlowsObject extends SpecificationExtensions { +export interface OAuthFlowsObject extends OpenAPIExtensions { /** * Configuration for the OAuth Authorization Code flow. Previously called `accessCode` in OpenAPI 2.0. */ @@ -462,7 +451,7 @@ export interface OAuthFlowsObject extends SpecificationExtensions { * * TODO: examples */ -export interface OperationObject extends SpecificationExtensions { +export interface OperationObject extends OpenAPIExtensions { /** * A map of possible out-of band callbacks related to the parent operation. The key is a unique identifier for the Callback Object. Each value in the map is a {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#callback-object Callback Object} that describes a request that may be initiated by the API provider and the expected responses. */ @@ -561,7 +550,7 @@ export interface OperationObject extends SpecificationExtensions { * * TODO: examples */ -export interface ParameterObject extends SpecificationExtensions { +export interface ParameterObject extends OpenAPIExtensions { /** * If `true`, clients MAY pass a zero-length string value in place of parameters that would otherwise be omitted entirely, which the server SHOULD interpret as the parameter being unused. Default value is `false`. If {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#parameter-style `style`} is used, and if {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#style-examples behavior is _n/a_ (cannot be serialized)}, the value of `allowEmptyValue` SHALL be ignored. Interactions between this field and the parameter's {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#schema-object Schema Object} are implementation-defined. This field is valid only for `query` parameters. Use of this field is NOT RECOMMENDED, and it is likely to be removed in a later revision. */ @@ -633,7 +622,7 @@ export interface ParameterObject extends SpecificationExtensions { * * TODO: examples */ -export interface PathItemObject extends SpecificationExtensions { +export interface PathItemObject extends OpenAPIExtensions { /** * Allows for a referenced definition of this path item. The value MUST be in the form of a URL, and the referenced structure MUST be in the form of a {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#path-item-object Path Item Object}. In case a Path Item Object field appears both in the defined object and the referenced object, the behavior is undefined. See the rules for resolving {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#relative-references-in-urls Relative References}. */ @@ -695,7 +684,7 @@ export interface PathItemObject extends SpecificationExtensions { * * TODO: examples */ -export interface PathsObject extends SpecificationExtensions { +export interface PathsObject extends OpenAPIExtensions { /** * A relative path to an individual endpoint. The field name MUST begin with a forward slash (`/`). The path is **appended** (no relative URL resolution) to the expanded URL from the {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#server-object Server Object}'s `url` field in order to construct the full URL. {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#path-templating Path templating} is allowed. When matching URLs, concrete (non-templated) paths would be matched before their templated counterparts. Templated paths with the same hierarchy but different templated names MUST NOT exist as they are identical. In case of ambiguous matching, it's up to the tooling to decide which one to use. */ @@ -743,7 +732,7 @@ export interface ReferenceObject { * * TODO: examples */ -export interface RequestBodyObject extends SpecificationExtensions { +export interface RequestBodyObject extends OpenAPIExtensions { /** * **REQUIRED**. The content of the request body. The key is a media type or {@link https://tools.ietf.org/html/rfc7231#appendix-D media type range} and the value describes it. For requests that match multiple keys, only the most specific key is applicable. e.g. `"text/plain"` overrides `"text/*"` */ @@ -765,7 +754,7 @@ export interface RequestBodyObject extends SpecificationExtensions { * * TODO: examples */ -export interface ResponseObject extends SpecificationExtensions { +export interface ResponseObject extends OpenAPIExtensions { /** * A map containing descriptions of potential response payloads. The key is a media type or {@link https://tools.ietf.org/html/rfc7231#appendix-D media type range} and the value describes it. For responses that match multiple keys, only the most specific key is applicable. e.g. `"text/plain"` overrides `"text/*"` */ @@ -797,7 +786,7 @@ export interface ResponseObject extends SpecificationExtensions { * * TODO: examples */ -export interface ResponsesObject extends SpecificationExtensions { +export interface ResponsesObject extends OpenAPIExtensions { /** * Any {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.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. A {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#reference-object Reference Object} can link to a response that is defined in the {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#components-responses OpenAPI Object's `components.responses`} section. 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` and `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. */ @@ -859,7 +848,7 @@ export interface ResponsesObject extends SpecificationExtensions { * * TODO: content, examples */ -export interface SchemaObject extends EnumExtensions, SpecificationExtensions { +export interface SchemaObject extends EnumExtensions, OpenAPIExtensions { /** * The value of "additionalProperties" MUST be a boolean or a schema. * @@ -1112,7 +1101,7 @@ export interface SecurityRequirementObject { * * TODO: examples */ -export type SecuritySchemeObject = SpecificationExtensions & { +export type SecuritySchemeObject = OpenAPIExtensions & { /** * A description for security scheme. {@link https://spec.commonmark.org/ CommonMark syntax} MAY be used for rich text representation. */ @@ -1175,7 +1164,7 @@ export type SecuritySchemeObject = SpecificationExtensions & { * * TODO: examples */ -export interface ServerObject extends SpecificationExtensions { +export interface ServerObject extends OpenAPIExtensions { /** * An optional string describing the host designated by the URL. {@link https://spec.commonmark.org/ CommonMark syntax} MAY be used for rich text representation. */ @@ -1195,7 +1184,7 @@ export interface ServerObject extends SpecificationExtensions { * * This object MAY be extended with {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#specification-extensions Specification Extensions}. */ -export interface ServerVariableObject extends SpecificationExtensions { +export interface ServerVariableObject extends OpenAPIExtensions { /** * **REQUIRED**. The default value to use for substitution, which SHALL be sent if an alternate value is _not_ supplied. If the {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#server-variable-enum `enum`} is defined, the value SHOULD exist in the enum's values. Note that this behavior is different from the {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#schema-object Schema Object}'s `default` keyword, which documents the receiver's behavior rather than inserting the value into the data. */ @@ -1222,7 +1211,7 @@ export interface ServerVariableObject extends SpecificationExtensions { * description: Pets operations * ``` */ -export interface TagObject extends SpecificationExtensions { +export interface TagObject extends OpenAPIExtensions { /** * A description for the tag. {@link https://spec.commonmark.org/ CommonMark syntax} MAY be used for rich text representation. */ @@ -1251,7 +1240,7 @@ export interface TagObject extends SpecificationExtensions { * * TODO: examples */ -export interface XMLObject extends SpecificationExtensions { +export interface XMLObject extends OpenAPIExtensions { /** * Declares whether the property definition translates to an attribute instead of an element. Default value is `false`. */ @@ -1287,4 +1276,4 @@ type OpenApiSchemaFormats = | 'date-time' | 'password'; -type Format = JsonSchemaFormats | OpenApiSchemaFormats | AnyString; +type Format = JsonSchemaFormats | OpenApiSchemaFormats | (string & {}); diff --git a/packages/spec-types/tsconfig.json b/packages/spec-types/tsconfig.json new file mode 100644 index 000000000..78e34cbd5 --- /dev/null +++ b/packages/spec-types/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "composite": true, + "emitDeclarationOnly": true, + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src"] +} diff --git a/packages/types/package.json b/packages/types/package.json index bae31e6f6..816a2741f 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -15,6 +15,7 @@ "dist" ], "type": "module", + "sideEffects": false, "types": "./dist/index.d.ts", "exports": { ".": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 61c1f0f96..72ef325ad 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1312,7 +1312,7 @@ importers: version: 1.8.0 nuxt: specifier: '>=3.0.0' - version: 3.14.1592(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@25.2.1)(db0@0.3.4)(encoding@0.1.13)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(less@4.4.2)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-rc.9)(rollup@3.29.5)(sass@1.97.1)(terser@5.44.1)(typescript@5.9.3)(vite@7.3.1(@types/node@25.2.1)(jiti@2.6.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vue-tsc@3.2.4(typescript@5.9.3)) + version: 3.14.1592(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@25.2.1)(db0@0.3.2)(encoding@0.1.13)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.7.0)(less@4.4.2)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-rc.9)(rollup@3.29.5)(sass@1.97.1)(terser@5.44.1)(typescript@5.9.3)(vite@7.3.1(@types/node@25.2.1)(jiti@2.6.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vue-tsc@3.2.4(typescript@5.9.3)) vue: specifier: '>=3.5.13' version: 3.5.13(typescript@5.9.3) @@ -1344,6 +1344,9 @@ importers: '@hey-api/shared': specifier: workspace:* version: link:../shared + '@hey-api/spec-types': + specifier: workspace:* + version: link:../spec-types '@hey-api/types': specifier: workspace:* version: link:../types @@ -1396,6 +1399,9 @@ importers: '@hey-api/shared': specifier: workspace:* version: link:../shared + '@hey-api/spec-types': + specifier: workspace:* + version: link:../spec-types '@hey-api/types': specifier: workspace:* version: link:../types @@ -1444,7 +1450,7 @@ importers: version: 1.14.3 nuxt: specifier: 3.14.1592 - version: 3.14.1592(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@25.2.1)(db0@0.3.2)(encoding@0.1.13)(eslint@9.39.1(jiti@2.6.1))(ioredis@5.7.0)(less@4.4.2)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-rc.9)(rollup@4.56.0)(sass@1.97.1)(terser@5.44.1)(typescript@5.9.3)(vite@5.4.19(@types/node@25.2.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1))(vue-tsc@3.2.4(typescript@5.9.3)) + version: 3.14.1592(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@25.2.1)(db0@0.3.4)(encoding@0.1.13)(eslint@9.39.1(jiti@2.6.1))(ioredis@5.9.2)(less@4.4.2)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-rc.9)(rollup@4.56.0)(sass@1.97.1)(terser@5.44.1)(typescript@5.9.3)(vite@7.3.1(@types/node@25.2.1)(jiti@2.6.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vue-tsc@3.2.4(typescript@5.9.3)) ofetch: specifier: 1.5.1 version: 1.5.1 @@ -1658,6 +1664,9 @@ importers: '@hey-api/json-schema-ref-parser': specifier: workspace:* version: link:../json-schema-ref-parser + '@hey-api/spec-types': + specifier: workspace:* + version: link:../spec-types '@hey-api/types': specifier: workspace:* version: link:../types @@ -1693,6 +1702,16 @@ importers: specifier: 2.8.2 version: 2.8.2 + packages/spec-types: + dependencies: + '@hey-api/types': + specifier: workspace:* + version: link:../types + devDependencies: + typescript: + specifier: 5.9.3 + version: 5.9.3 + packages/types: devDependencies: typescript: @@ -19804,15 +19823,6 @@ snapshots: '@nuxt/devalue@2.0.2': {} - '@nuxt/devtools-kit@1.7.0(magicast@0.3.5)(vite@5.4.19(@types/node@25.2.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1))': - dependencies: - '@nuxt/kit': 3.21.0(magicast@0.3.5) - '@nuxt/schema': 3.16.2 - execa: 7.2.0 - vite: 5.4.19(@types/node@25.2.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1) - transitivePeerDependencies: - - magicast - '@nuxt/devtools-kit@1.7.0(magicast@0.3.5)(vite@7.3.1(@types/node@25.2.1)(jiti@2.6.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@nuxt/kit': 3.21.0(magicast@0.3.5) @@ -19909,53 +19919,6 @@ snapshots: - utf-8-validate - vue - '@nuxt/devtools@1.7.0(rollup@4.56.0)(vite@5.4.19(@types/node@25.2.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1))(vue@3.5.25(typescript@5.9.3))': - dependencies: - '@antfu/utils': 0.7.10 - '@nuxt/devtools-kit': 1.7.0(magicast@0.3.5)(vite@5.4.19(@types/node@25.2.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)) - '@nuxt/devtools-wizard': 1.7.0 - '@nuxt/kit': 3.21.0(magicast@0.3.5) - '@vue/devtools-core': 7.6.8(vite@5.4.19(@types/node@25.2.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1))(vue@3.5.25(typescript@5.9.3)) - '@vue/devtools-kit': 7.6.8 - birpc: 0.2.19 - consola: 3.4.2 - cronstrue: 2.59.0 - destr: 2.0.5 - error-stack-parser-es: 0.1.5 - execa: 7.2.0 - fast-npm-meta: 0.2.2 - flatted: 3.3.3 - get-port-please: 3.2.0 - hookable: 5.5.3 - image-meta: 0.2.1 - is-installed-globally: 1.0.0 - launch-editor: 2.11.1 - local-pkg: 0.5.1 - magicast: 0.3.5 - nypm: 0.4.1 - ohash: 1.1.6 - pathe: 1.1.2 - perfect-debounce: 1.0.0 - pkg-types: 1.3.1 - rc9: 2.1.2 - scule: 1.3.0 - semver: 7.7.3 - simple-git: 3.28.0 - sirv: 3.0.2 - tinyglobby: 0.2.15 - unimport: 3.14.6(rollup@4.56.0) - vite: 5.4.19(@types/node@25.2.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1) - vite-plugin-inspect: 0.8.9(@nuxt/kit@3.21.0(magicast@0.3.5))(rollup@4.56.0)(vite@5.4.19(@types/node@25.2.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)) - vite-plugin-vue-inspector: 5.3.2(vite@5.4.19(@types/node@25.2.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)) - which: 3.0.1 - ws: 8.18.3 - transitivePeerDependencies: - - bufferutil - - rollup - - supports-color - - utf-8-validate - - vue - '@nuxt/devtools@1.7.0(rollup@4.56.0)(vite@7.3.1(@types/node@25.2.1)(jiti@2.6.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3))': dependencies: '@antfu/utils': 0.7.10 @@ -23659,18 +23622,6 @@ snapshots: dependencies: '@vue/devtools-kit': 8.0.5 - '@vue/devtools-core@7.6.8(vite@5.4.19(@types/node@25.2.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1))(vue@3.5.25(typescript@5.9.3))': - dependencies: - '@vue/devtools-kit': 7.7.7 - '@vue/devtools-shared': 7.7.7 - mitt: 3.0.1 - nanoid: 5.1.5 - pathe: 1.1.2 - vite-hot-client: 0.2.4(vite@5.4.19(@types/node@25.2.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)) - vue: 3.5.25(typescript@5.9.3) - transitivePeerDependencies: - - vite - '@vue/devtools-core@7.6.8(vite@7.3.1(@types/node@25.2.1)(jiti@2.6.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3))': dependencies: '@vue/devtools-kit': 7.7.7 @@ -25868,7 +25819,7 @@ snapshots: eslint: 9.17.0(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.17.0(jiti@2.6.1)))(eslint@9.17.0(jiti@2.6.1)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.17.0(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.17.0(jiti@2.6.1)))(eslint@9.17.0(jiti@2.6.1)))(eslint@9.17.0(jiti@2.6.1)) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.17.0(jiti@2.6.1)) eslint-plugin-react: 7.37.5(eslint@9.17.0(jiti@2.6.1)) eslint-plugin-react-hooks: 5.2.0(eslint@9.17.0(jiti@2.6.1)) @@ -25898,7 +25849,7 @@ snapshots: tinyglobby: 0.2.15 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.17.0(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.17.0(jiti@2.6.1)))(eslint@9.17.0(jiti@2.6.1)))(eslint@9.17.0(jiti@2.6.1)) transitivePeerDependencies: - supports-color @@ -25913,7 +25864,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.17.0(jiti@2.6.1)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.17.0(jiti@2.6.1)))(eslint@9.17.0(jiti@2.6.1)))(eslint@9.17.0(jiti@2.6.1)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -29006,14 +28957,14 @@ snapshots: nuxi@3.28.0: {} - nuxt@3.14.1592(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@25.2.1)(db0@0.3.2)(encoding@0.1.13)(eslint@9.39.1(jiti@2.6.1))(ioredis@5.7.0)(less@4.4.2)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-rc.9)(rollup@4.56.0)(sass@1.97.1)(terser@5.44.1)(typescript@5.9.3)(vite@5.4.19(@types/node@25.2.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1))(vue-tsc@3.2.4(typescript@5.9.3)): + nuxt@3.14.1592(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@25.2.1)(db0@0.3.2)(encoding@0.1.13)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.7.0)(less@4.4.2)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-rc.9)(rollup@3.29.5)(sass@1.97.1)(terser@5.44.1)(typescript@5.9.3)(vite@7.3.1(@types/node@25.2.1)(jiti@2.6.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vue-tsc@3.2.4(typescript@5.9.3)): dependencies: '@nuxt/devalue': 2.0.2 - '@nuxt/devtools': 1.7.0(rollup@4.56.0)(vite@5.4.19(@types/node@25.2.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1))(vue@3.5.25(typescript@5.9.3)) - '@nuxt/kit': 3.14.1592(magicast@0.3.5)(rollup@4.56.0) - '@nuxt/schema': 3.14.1592(magicast@0.3.5)(rollup@4.56.0) + '@nuxt/devtools': 1.7.0(rollup@3.29.5)(vite@7.3.1(@types/node@25.2.1)(jiti@2.6.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3)) + '@nuxt/kit': 3.14.1592(magicast@0.3.5)(rollup@3.29.5) + '@nuxt/schema': 3.14.1592(magicast@0.3.5)(rollup@3.29.5) '@nuxt/telemetry': 2.6.6(magicast@0.3.5) - '@nuxt/vite-builder': 3.14.1592(@types/node@25.2.1)(eslint@9.39.1(jiti@2.6.1))(less@4.4.2)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-rc.9)(rollup@4.56.0)(sass@1.97.1)(terser@5.44.1)(typescript@5.9.3)(vue-tsc@3.2.4(typescript@5.9.3))(vue@3.5.25(typescript@5.9.3)) + '@nuxt/vite-builder': 3.14.1592(@types/node@25.2.1)(eslint@9.39.2(jiti@2.6.1))(less@4.4.2)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-rc.9)(rollup@3.29.5)(sass@1.97.1)(terser@5.44.1)(typescript@5.9.3)(vue-tsc@3.2.4(typescript@5.9.3))(vue@3.5.25(typescript@5.9.3)) '@unhead/dom': 1.11.20 '@unhead/shared': 1.11.20 '@unhead/ssr': 1.11.20 @@ -29036,7 +28987,7 @@ snapshots: h3: 1.15.4 hookable: 5.5.3 ignore: 6.0.2 - impound: 0.2.2(rollup@4.56.0) + impound: 0.2.2(rollup@3.29.5) jiti: 2.6.1 klona: 2.0.6 knitwork: 1.3.0 @@ -29063,15 +29014,15 @@ snapshots: unctx: 2.4.1 unenv: 1.10.0 unhead: 1.11.20 - unimport: 3.14.6(rollup@4.56.0) + unimport: 3.14.6(rollup@3.29.5) unplugin: 1.16.1 - unplugin-vue-router: 0.10.9(rollup@4.56.0)(vue-router@4.5.0(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3)) + unplugin-vue-router: 0.10.9(rollup@3.29.5)(vue-router@4.5.0(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3)) unstorage: 1.17.0(@netlify/blobs@9.1.2)(db0@0.3.2)(ioredis@5.7.0) untyped: 1.5.2 vue: 3.5.25(typescript@5.9.3) vue-bundle-renderer: 2.1.2 vue-devtools-stub: 0.1.0 - vue-router: 4.5.0(vue@3.5.25(typescript@5.9.3)) + vue-router: 4.5.0(vue@3.5.13(typescript@5.9.3)) optionalDependencies: '@parcel/watcher': 2.5.1 '@types/node': 25.2.1 @@ -29248,127 +29199,6 @@ snapshots: - vue-tsc - xml2js - nuxt@3.14.1592(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@25.2.1)(db0@0.3.4)(encoding@0.1.13)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(less@4.4.2)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-rc.9)(rollup@3.29.5)(sass@1.97.1)(terser@5.44.1)(typescript@5.9.3)(vite@7.3.1(@types/node@25.2.1)(jiti@2.6.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vue-tsc@3.2.4(typescript@5.9.3)): - dependencies: - '@nuxt/devalue': 2.0.2 - '@nuxt/devtools': 1.7.0(rollup@3.29.5)(vite@7.3.1(@types/node@25.2.1)(jiti@2.6.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3)) - '@nuxt/kit': 3.14.1592(magicast@0.3.5)(rollup@3.29.5) - '@nuxt/schema': 3.14.1592(magicast@0.3.5)(rollup@3.29.5) - '@nuxt/telemetry': 2.6.6(magicast@0.3.5) - '@nuxt/vite-builder': 3.14.1592(@types/node@25.2.1)(eslint@9.39.2(jiti@2.6.1))(less@4.4.2)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-rc.9)(rollup@3.29.5)(sass@1.97.1)(terser@5.44.1)(typescript@5.9.3)(vue-tsc@3.2.4(typescript@5.9.3))(vue@3.5.25(typescript@5.9.3)) - '@unhead/dom': 1.11.20 - '@unhead/shared': 1.11.20 - '@unhead/ssr': 1.11.20 - '@unhead/vue': 1.11.20(vue@3.5.25(typescript@5.9.3)) - '@vue/shared': 3.5.25 - acorn: 8.14.0 - c12: 2.0.1(magicast@0.3.5) - chokidar: 4.0.3 - compatx: 0.1.8 - consola: 3.4.2 - cookie-es: 1.2.2 - defu: 6.1.4 - destr: 2.0.5 - devalue: 5.3.2 - errx: 0.1.0 - esbuild: 0.24.2 - escape-string-regexp: 5.0.0 - estree-walker: 3.0.3 - globby: 14.1.0 - h3: 1.15.4 - hookable: 5.5.3 - ignore: 6.0.2 - impound: 0.2.2(rollup@3.29.5) - jiti: 2.6.1 - klona: 2.0.6 - knitwork: 1.3.0 - magic-string: 0.30.21 - mlly: 1.8.0 - nanotar: 0.1.1 - nitropack: 2.12.4(@netlify/blobs@9.1.2)(encoding@0.1.13)(rolldown@1.0.0-rc.9) - nuxi: 3.28.0 - nypm: 0.3.12 - ofetch: 1.5.1 - ohash: 1.1.6 - pathe: 1.1.2 - perfect-debounce: 1.0.0 - pkg-types: 1.3.1 - radix3: 1.1.2 - scule: 1.3.0 - semver: 7.7.3 - std-env: 3.10.0 - strip-literal: 2.1.1 - tinyglobby: 0.2.10 - ufo: 1.6.1 - ultrahtml: 1.6.0 - uncrypto: 0.1.3 - unctx: 2.4.1 - unenv: 1.10.0 - unhead: 1.11.20 - unimport: 3.14.6(rollup@3.29.5) - unplugin: 1.16.1 - unplugin-vue-router: 0.10.9(rollup@3.29.5)(vue-router@4.5.0(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3)) - unstorage: 1.17.0(@netlify/blobs@9.1.2)(db0@0.3.4)(ioredis@5.9.2) - untyped: 1.5.2 - vue: 3.5.25(typescript@5.9.3) - vue-bundle-renderer: 2.1.2 - vue-devtools-stub: 0.1.0 - vue-router: 4.5.0(vue@3.5.25(typescript@5.9.3)) - optionalDependencies: - '@parcel/watcher': 2.5.1 - '@types/node': 25.2.1 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@biomejs/biome' - - '@capacitor/preferences' - - '@deno/kv' - - '@electric-sql/pglite' - - '@libsql/client' - - '@netlify/blobs' - - '@planetscale/database' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - better-sqlite3 - - bufferutil - - db0 - - drizzle-orm - - encoding - - eslint - - idb-keyval - - ioredis - - less - - lightningcss - - magicast - - meow - - mysql2 - - optionator - - rolldown - - rollup - - sass - - sass-embedded - - sqlite3 - - stylelint - - stylus - - sugarss - - supports-color - - terser - - typescript - - uploadthing - - utf-8-validate - - vite - - vls - - vti - - vue-tsc - - xml2js - nuxt@3.14.1592(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@25.2.1)(db0@0.3.4)(encoding@0.1.13)(eslint@9.39.2(jiti@2.6.1))(ioredis@5.9.2)(less@4.4.2)(magicast@0.3.5)(optionator@0.9.4)(rolldown@1.0.0-rc.9)(rollup@4.56.0)(sass@1.97.1)(terser@5.44.1)(typescript@5.9.3)(vite@7.3.1(@types/node@25.2.1)(jiti@2.6.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vue-tsc@3.2.4(typescript@5.9.3)): dependencies: '@nuxt/devalue': 2.0.2 @@ -32727,7 +32557,7 @@ snapshots: unplugin: 2.0.0-beta.1 yaml: 2.8.2 optionalDependencies: - vue-router: 4.5.0(vue@3.5.25(typescript@5.9.3)) + vue-router: 4.5.0(vue@3.5.13(typescript@5.9.3)) transitivePeerDependencies: - rollup - vue @@ -33037,10 +32867,6 @@ snapshots: vite: 7.3.1(@types/node@25.2.1)(jiti@2.6.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) vite-hot-client: 2.1.0(vite@7.3.1(@types/node@25.2.1)(jiti@2.6.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) - vite-hot-client@0.2.4(vite@5.4.19(@types/node@25.2.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)): - dependencies: - vite: 5.4.19(@types/node@25.2.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1) - vite-hot-client@0.2.4(vite@7.3.1(@types/node@25.2.1)(jiti@2.6.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)): dependencies: vite: 7.3.1(@types/node@25.2.1)(jiti@2.6.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) @@ -33172,24 +32998,6 @@ snapshots: - rollup - supports-color - vite-plugin-inspect@0.8.9(@nuxt/kit@3.21.0(magicast@0.3.5))(rollup@4.56.0)(vite@5.4.19(@types/node@25.2.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)): - dependencies: - '@antfu/utils': 0.7.10 - '@rollup/pluginutils': 5.2.0(rollup@4.56.0) - debug: 4.4.3 - error-stack-parser-es: 0.1.5 - fs-extra: 11.3.1 - open: 10.2.0 - perfect-debounce: 1.0.0 - picocolors: 1.1.1 - sirv: 3.0.2 - vite: 5.4.19(@types/node@25.2.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1) - optionalDependencies: - '@nuxt/kit': 3.21.0(magicast@0.3.5) - transitivePeerDependencies: - - rollup - - supports-color - vite-plugin-inspect@0.8.9(@nuxt/kit@3.21.0(magicast@0.3.5))(rollup@4.56.0)(vite@7.3.1(@types/node@25.2.1)(jiti@2.6.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)): dependencies: '@antfu/utils': 0.7.10 @@ -33255,21 +33063,6 @@ snapshots: - supports-color - vue - vite-plugin-vue-inspector@5.3.2(vite@5.4.19(@types/node@25.2.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)): - dependencies: - '@babel/core': 7.28.3 - '@babel/plugin-proposal-decorators': 7.28.0(@babel/core@7.28.3) - '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.3) - '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.28.3) - '@vue/babel-plugin-jsx': 1.5.0(@babel/core@7.28.3) - '@vue/compiler-dom': 3.5.25 - kolorist: 1.8.0 - magic-string: 0.30.21 - vite: 5.4.19(@types/node@25.2.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1) - transitivePeerDependencies: - - supports-color - vite-plugin-vue-inspector@5.3.2(vite@7.3.1(@types/node@24.10.10)(jiti@2.6.1)(less@4.4.2)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)): dependencies: '@babel/core': 7.28.3