import { Project, ScriptTarget, ModuleKind } from 'ts-morph'; import { ParameterType, XML, ExternalDocs, Info, Path, BodyParameter, QueryParameter, Security, Tag } from 'swagger-schema-official'; /** * An operation parameter. OpenAPI 3.x carries the type in `schema`; * Swagger 2.0 puts `type`/`format` directly on the parameter — consumers * must handle both (or use the normalized model, which precomputes them). */ interface Parameter { name: string; in: "query" | "path" | "header" | "cookie"; required?: boolean; schema?: SwaggerDefinition; type?: string; format?: string; description?: string; } /** * One operation of the spec, flattened to (path, method). Raw-ish view — * generators consume its precomputed extension NormalizedOperation instead. */ interface PathInfo { path: string; method: string; operationId?: string; summary?: string; description?: string; tags?: string[]; parameters?: Parameter[]; requestBody?: RequestBody; responses?: Record; } /** * Operation request body, keyed by content type — the OpenAPI 3.x shape. * Swagger 2.0 `in: "body"` parameters are NOT yet lifted into this shape; * 2.0 operations currently generate without a body parameter. */ interface RequestBody { required?: boolean; content?: Record; } /** * A single response entry, keyed by content type — the OpenAPI 3.x shape. * A Swagger 2.0 response's direct `schema` is NOT yet mapped into `content`; * 2.0 responses currently type as `any`. */ interface SwaggerResponse { description?: string; content?: Record; } /** OpenAPI 3.x security scheme (subset of the spec's fields). */ interface OpenApiSecurityScheme { type?: "apiKey" | "http" | "oauth2" | "openIdConnect"; description?: string; name?: string; in?: "query" | "header" | "cookie"; scheme?: string; bearerFormat?: string; flows?: Record; openIdConnectUrl?: string; } /** * A JSON-Schema-ish definition as it appears in the spec, shared by * Swagger 2.0 and OpenAPI 3.x (3.0's `nullable` and 3.1's type arrays * both flow through `type`/`nullable`). May contain unresolved `$ref`s. */ interface SwaggerDefinition { type?: ParameterType | undefined; format?: string | undefined; title?: string | undefined; description?: string | undefined; default?: unknown; multipleOf?: number | undefined; maximum?: number | undefined; exclusiveMaximum?: boolean | undefined; minimum?: number | undefined; exclusiveMinimum?: boolean | undefined; maxLength?: number | undefined; minLength?: number | undefined; pattern?: string | undefined; maxItems?: number | undefined; minItems?: number | undefined; uniqueItems?: boolean | undefined; maxProperties?: number | undefined; minProperties?: number | undefined; enum?: Array | undefined; /** OpenAPI 3.1 (JSON Schema); normalizeSchema folds it into a single-value `enum`. */ const?: unknown; items?: SwaggerDefinition | SwaggerDefinition[] | undefined; $ref?: string | undefined; allOf?: SwaggerDefinition[] | undefined; additionalProperties?: SwaggerDefinition | boolean | undefined; properties?: { [propertyName: string]: SwaggerDefinition; } | undefined; discriminator?: string | undefined; readOnly?: boolean | undefined; nullable?: boolean | undefined; xml?: XML | undefined; externalDocs?: ExternalDocs | undefined; example?: unknown; required?: string[] | undefined; oneOf?: SwaggerDefinition[]; anyOf?: SwaggerDefinition[]; } /** * The raw parsed spec document. Exactly one of `swagger` ("2.x") or * `openapi` ("3.x") identifies the version; everything version-specific * is resolved once by normalizeSpec. */ interface SwaggerSpec { openapi: string; swagger: string; info: Info; externalDocs?: ExternalDocs | undefined; host?: string | undefined; basePath?: string | undefined; schemes?: string[] | undefined; consumes?: string[] | undefined; produces?: string[] | undefined; paths: { [pathName: string]: Path; }; definitions?: { [definitionsName: string]: SwaggerDefinition; } | undefined; parameters?: { [parameterName: string]: BodyParameter | QueryParameter; } | undefined; responses?: { [responseName: string]: SwaggerResponse; } | undefined; security?: Array<{ [securityDefinitionName: string]: string[]; }> | undefined; securityDefinitions?: { [securityDefinitionName: string]: Security; } | undefined; tags?: Tag[] | undefined; components?: { schemas?: Record; securitySchemes?: Record; }; } type ResponseKind = "json" | "blob" | "arraybuffer" | "text"; /** * A spec operation with everything the generators need precomputed once at * normalization time. Generators must not re-derive any of these fields or * resolve $refs during emission — that is exactly the duplication this model * exists to remove. */ interface NormalizedOperation extends PathInfo { /** parameters with in === "path" */ pathParams: Parameter[]; /** parameters with in === "query" */ queryParams: Parameter[]; hasBody: boolean; isMultipart: boolean; /** urlencoded body without a JSON alternative */ isUrlEncoded: boolean; /** ref-resolved multipart body schema (set only when isMultipart) */ formDataSchema?: SwaggerDefinition; /** field names of formDataSchema's properties */ formDataFields: string[]; /** ref-resolved urlencoded body schema (set only when isUrlEncoded) */ urlEncodedSchema?: SwaggerDefinition; /** field names of urlEncodedSchema's properties */ urlEncodedFields: string[]; /** derived from the first success response (200/201/202/204/206) */ responseType: ResponseKind; /** * Accept header value derived from the same success response: its content * types that agree with responseType (unset when none are declared). */ acceptHeader?: string; } /** Detected spec flavor and its literal version string (e.g. openapi "3.0.3"). */ interface SpecVersion { type: "swagger" | "openapi"; version: string; } /** * Version-free view of a parsed spec: Swagger 2.0 vs OpenAPI 3.x differences * are resolved once at normalization time. Generators consume this instead of * touching the raw SwaggerSpec. */ interface NormalizedSpec { version: SpecVersion | null; /** 2.0 `definitions` or 3.x `components.schemas`, whichever the spec has */ definitions: Record; operations: NormalizedOperation[]; /** Lookup for "#/definitions/X" and "#/components/schemas/X" style refs */ resolveReference(ref: string): SwaggerDefinition | undefined; } /** * Everything a plugin generator receives from the orchestrator. * * Plugins consume the version-free NormalizedSpec — never the raw spec or the * SwaggerParser — and emit through the shared ts-morph Project so the * orchestrator can track written files. */ interface PluginGeneratorContext { /** Version-free spec model; $refs resolved, per-operation fields precomputed. */ spec: NormalizedSpec; /** Shared ts-morph project all generators emit through. */ project: Project; /** Full user-facing config; plugins should read only the slice they need. */ config: GeneratorConfig; /** Sink for non-fatal diagnostics — plugins must never log directly. */ onWarning?: (message: string) => void; } /** * Constructor contract for plugin generator classes (what GeneratorConfig.plugins accepts). */ interface IPluginGeneratorClass { new (context: PluginGeneratorContext): IPluginGenerator; } /** * Interface for generator instances */ interface IPluginGenerator { /** * Generate code files under the given output root. */ generate(outputRoot: string): Promise; } /** * Prefix/suffix decoration for one category of generated identifiers. * A prefix is prepended verbatim and must be a valid identifier start. * For services/resources the suffix replaces the default * "Service"/"Resource" (an empty string drops it); for models it is * plainly appended (models have no default suffix). */ interface NameDecoration { prefix?: string; suffix?: string; } /** * Identifier decoration for generated classes/types. File names are * unaffected; model decoration applies to schema-derived types only * (request-params interfaces and zod schemas keep their operation-derived * names). */ interface NamingOptions { services?: NameDecoration; resources?: NameDecoration; models?: NameDecoration; } /** * The user-facing configuration (config file or programmatic call). * Validated at the boundary by validateGeneratorConfig, which throws * ConfigValidationError listing every problem at once — see * https://ng-openapi.dev for full option documentation. */ interface GeneratorConfig { /** Path or http(s) URL of the OpenAPI 3.x / Swagger 2.x spec (.json/.yaml/.yml). */ input: string; /** Output directory; created if missing. */ output: string; /** Distinguishes tokens/providers when several clients coexist in one app. */ clientName?: string; /** Custom acceptance check run on the parsed spec; returning false aborts generation. */ validateInput?: (spec: SwaggerSpec) => boolean; options: { /** How date/date-time formats are typed in generated models. */ dateType: "string" | "Date"; /** Emit TS enums or literal-union types for spec enums. */ enumStyle: "enum" | "union"; validation?: { /** Adds a `parse` hook to RequestOptions for response validation. */ response?: boolean; }; /** Set false to generate models only. Default: true. */ generateServices?: boolean; /** Read enum member names from JSON-encoded descriptions (see EnumValueObject). */ generateEnumBasedOnDescription?: boolean; /** Default headers added to every request when not already present. */ customHeaders?: Record; /** * Send an Accept header derived from each operation's response content * types (caller-supplied and customHeaders values win). Default: true. */ emitAcceptHeader?: boolean; /** Pin the Angular responseType per response content type. */ responseTypeMapping?: { [contentType: string]: "json" | "blob" | "arraybuffer" | "text"; }; /** Derive method names from operationIds; throws when an operation has none. */ customizeMethodName?: (operationId: string) => string; /** Collapse each method's parameters into a single request object. */ useSingleRequestParameter?: boolean; /** * Class decorator emitted on generated services/resources. `"service"` * emits Angular 22+'s `@Service()` (pre-release; shorthand for exactly * `@Injectable({ providedIn: "root" })`) — generated code will not * compile on Angular ≤ 21. Default: `"injectable"`. */ serviceDecorator?: "injectable" | "service"; /** Prefix/suffix decoration of generated service/resource/model identifiers. */ naming?: NamingOptions; /** * Layout of the generated model declarations. `"single"` (default) * keeps every type in `models/index.ts`; `"per-type"` writes one file * per schema (kebab-case of the raw schema name) plus * `models/request-options.ts`, with `models/index.ts` as a barrel. */ modelFileStructure?: "single" | "per-type"; }; /** Overrides for the ts-morph compiler settings used during generation. */ compilerOptions?: { declaration?: boolean; target?: ScriptTarget; module?: ModuleKind; strict?: boolean; }; /** Plugin generator classes, run after core generation (see PluginGeneratorContext). */ plugins?: IPluginGeneratorClass[]; } declare class HttpResourceGenerator implements IPluginGenerator { private project; private spec; private config; private methodGenerator; private indexGenerator; private readonly onWarning?; constructor(context: PluginGeneratorContext); generate(outputRoot: string): Promise; private groupPathsByController; private generateServiceFile; private addServiceClass; } export { HttpResourceGenerator as HttpResourcePlugin };