diff --git a/packages/openapi-ts/src/debug/ir.ts b/packages/openapi-ts/src/debug/ir.ts index 03bf852c1..0338666c6 100644 --- a/packages/openapi-ts/src/debug/ir.ts +++ b/packages/openapi-ts/src/debug/ir.ts @@ -72,7 +72,7 @@ const print = (ir: IR.Model, options: PrintOptions = {}) => { const operation = item[method]!; log( - `${colors.green(method.toUpperCase())} ${colors.cyan(key)} (${colors.magenta(operation.operationId)})`, + `${colors.green(method.toUpperCase())} ${colors.cyan(key)} (${colors.magenta(operation.operationId ?? operation.id)})`, base, ); diff --git a/packages/openapi-ts/src/ir/__tests__/types.test.ts b/packages/openapi-ts/src/ir/__tests__/types.test.ts new file mode 100644 index 000000000..60767f085 --- /dev/null +++ b/packages/openapi-ts/src/ir/__tests__/types.test.ts @@ -0,0 +1,59 @@ +import { describe, expect, it } from 'vitest'; + +import type { IR } from '../types'; + +describe('IR types', () => { + it('IR.Context should be properly typed (not any)', () => { + const mockContext = { + config: {} as any, + gen: {} as any, + graph: undefined, + ir: {}, + logger: {} as any, + package: {} as any, + plugins: {}, + spec: {}, + } as IR.Context; + + // If Context were 'any', TypeScript wouldn't catch type errors + // This test verifies the type is properly resolved + expect(mockContext.config).toBeDefined(); + expect(mockContext.spec).toBeDefined(); + + // TypeScript should enforce the type structure + // @ts-expect-error - nonExistentProperty should not exist on Context + expect(mockContext.nonExistentProperty).toBeUndefined(); + }); + + it('IR.ReferenceObject should be properly typed (not any)', () => { + const mockRef: IR.ReferenceObject = { + $ref: '#/components/schemas/Pet', + }; + + // Verify $ref property exists and has correct type + expect(mockRef.$ref).toBe('#/components/schemas/Pet'); + + // TypeScript should enforce the type structure + // @ts-expect-error - nonExistentProperty should not exist on ReferenceObject + expect(mockRef.nonExistentProperty).toBeUndefined(); + }); + + it('IR.Context should support generic parameter', () => { + type CustomSpec = { title: string; version: string }; + const mockContext = { + config: {} as any, + gen: {} as any, + graph: undefined, + ir: {}, + logger: {} as any, + package: {} as any, + plugins: {}, + spec: { title: 'API', version: '1.0' }, + } as IR.Context; + + // Verify the generic parameter is properly typed + const spec: CustomSpec = mockContext.spec; + expect(spec.title).toBe('API'); + expect(spec.version).toBe('1.0'); + }); +}); diff --git a/packages/openapi-ts/src/ir/types.d.ts b/packages/openapi-ts/src/ir/types.d.ts index 2a4416d98..2de84009d 100644 --- a/packages/openapi-ts/src/ir/types.d.ts +++ b/packages/openapi-ts/src/ir/types.d.ts @@ -1,12 +1,17 @@ import type { JsonSchemaDraft2020_12 } from '~/openApi/3.1.x/types/json-schema-draft-2020-12'; import type { + ReferenceObject, SecuritySchemeObject, ServerObject, } from '~/openApi/3.1.x/types/spec'; -import type { Context as IRContext } from './context'; +import type { Context } from './context'; import type { IRMediaType } from './mediaType'; +type IRContext = any> = Context; + +type IRReferenceObject = ReferenceObject; + interface IRBodyObject { mediaType: string; /** @@ -228,7 +233,7 @@ export namespace IR { export type ParametersObject = IRParametersObject; export type PathItemObject = IRPathItemObject; export type PathsObject = IRPathsObject; - export type ReferenceObject = ReferenceObject; + export type ReferenceObject = IRReferenceObject; export type RequestBodyObject = IRRequestBodyObject; export type ResponseObject = IRResponseObject; export type ResponsesObject = IRResponsesObject;