dfx-openapi
Version:
dfx-openapi is a type-safe Angular HttpClient that pulls in your OpenAPI schema. It has virtually zero runtime and is fully compatible with Http Interceptors.
68 lines (67 loc) • 5.58 kB
TypeScript
/**
* Strongly-typed OpenAPI Resource builder on top of Angular's httpResource.
*
* - Preserves dfx-openapi type inference (paths, params, body, and typed responses)
* - Reactive by design: pass a function that reads signals; when those signals change,
* the resource re-fetches.
* - Supports per-resource httpResource options via `http` field.
*/
import { HttpResourceOptions, HttpResourceRef } from '@angular/common/http';
import { Injector } from '@angular/core';
import type { FilterKeys, HttpMethod, MediaType, PathsWithMethod, RequiredKeysOf } from 'openapi-typescript-helpers';
import { HttpClientResponse } from './shared/http-client-response';
import { QuerySerializer } from './shared/query-serializer';
import { QuerySerializerOptions } from './shared/query-serializer-options';
import { RequestOptions } from './shared/request-options';
export interface OpenAPIResourceOptions {
baseUrl: string;
querySerializer?: QuerySerializer<unknown> | QuerySerializerOptions;
}
/**
* Allow per-resource httpResource options via `http` property, while preserving
* OpenAPI request options shape.
*/
type WithHttpOptions<Init, TResult, TRaw> = Init & {
http?: HttpResourceOptions<TResult, TRaw>;
};
/**
* Make the single `init` argument optionally present based on whether params/body
* are required for the specific operation. The init can be either a plain object
* or a getter function (() => object | undefined) for reactivity.
*/
type InitGetterOrValue<Init> = Init | (() => Init | undefined);
type InitParam<Init> = RequiredKeysOf<Init> extends never ? [InitGetterOrValue<Init>?] : [InitGetterOrValue<Init>];
/**
* Factory: create a typed OpenAPI Resource builder.
* Use this once per API (e.g. per `Paths`) and reuse it throughout your app.
*/
export declare function createOpenAPIResource<Paths extends Record<string, any>, Media extends MediaType = MediaType>(options: OpenAPIResourceOptions, injector?: Injector): OpenAPIResource<Paths, Media>;
/**
* OpenAPIResource returns HttpResourceRefs that refetch reactively when any
* signals used inside your init getter (path/params/body) change.
*/
export declare class OpenAPIResource<Paths extends Record<string, any>, Media extends MediaType = MediaType> {
private injector;
private readonly baseUrl;
private readonly querySerializer?;
constructor({ baseUrl, querySerializer }: OpenAPIResourceOptions, injector: Injector);
/**
* Core resource method. Prefer using the per-method helpers below.
*
* Example:
* const users = api.request('get', () => '/users', () => ({
* params: { query: { page: pageSignal() } },
* http: { defaultValue: [] }
* }));
*/
core<Method extends HttpMethod, Path extends PathsWithMethod<Paths, Method>>(method: Method, path: () => Path | undefined, ...initParam: InitParam<WithHttpOptions<RequestOptions<FilterKeys<Paths[Path], Method>>, HttpClientResponse<Paths[Path][Method], Media>, unknown>>): HttpResourceRef<HttpClientResponse<Paths[Path][Method], Media> | undefined>;
request<Method extends HttpMethod, Path extends PathsWithMethod<Paths, Method>>(method: Method, path: () => Path | undefined, ...init: InitParam<WithHttpOptions<RequestOptions<FilterKeys<Paths[Path], Method>>, HttpClientResponse<Paths[Path][Method], Media>, unknown>>): HttpResourceRef<HttpClientResponse<Paths[Path][Method], Media> | undefined>;
get<Path extends PathsWithMethod<Paths, 'get'>>(path: () => Path | undefined, ...init: InitParam<WithHttpOptions<RequestOptions<FilterKeys<Paths[Path], 'get'>>, HttpClientResponse<Paths[Path]['get'], Media>, unknown>>): HttpResourceRef<HttpClientResponse<Paths[Path]['get'], Media> | undefined>;
put<Path extends PathsWithMethod<Paths, 'put'>>(path: () => Path | undefined, ...init: InitParam<WithHttpOptions<RequestOptions<FilterKeys<Paths[Path], 'put'>>, HttpClientResponse<Paths[Path]['put'], Media>, unknown>>): HttpResourceRef<HttpClientResponse<Paths[Path]['put'], Media> | undefined>;
post<Path extends PathsWithMethod<Paths, 'post'>>(path: () => Path | undefined, ...init: InitParam<WithHttpOptions<RequestOptions<FilterKeys<Paths[Path], 'post'>>, HttpClientResponse<Paths[Path]['post'], Media>, unknown>>): HttpResourceRef<HttpClientResponse<Paths[Path]['post'], Media> | undefined>;
delete<Path extends PathsWithMethod<Paths, 'delete'>>(path: () => Path | undefined, ...init: InitParam<WithHttpOptions<RequestOptions<FilterKeys<Paths[Path], 'delete'>>, HttpClientResponse<Paths[Path]['delete'], Media>, unknown>>): HttpResourceRef<HttpClientResponse<Paths[Path]['delete'], Media> | undefined>;
options<Path extends PathsWithMethod<Paths, 'options'>>(path: () => Path | undefined, ...init: InitParam<WithHttpOptions<RequestOptions<FilterKeys<Paths[Path], 'options'>>, HttpClientResponse<Paths[Path]['options'], Media>, unknown>>): HttpResourceRef<HttpClientResponse<Paths[Path]['options'], Media> | undefined>;
head<Path extends PathsWithMethod<Paths, 'head'>>(path: () => Path | undefined, ...init: InitParam<WithHttpOptions<RequestOptions<FilterKeys<Paths[Path], 'head'>>, HttpClientResponse<Paths[Path]['head'], Media>, unknown>>): HttpResourceRef<HttpClientResponse<Paths[Path]['head'], Media> | undefined>;
patch<Path extends PathsWithMethod<Paths, 'patch'>>(path: () => Path | undefined, ...init: InitParam<WithHttpOptions<RequestOptions<FilterKeys<Paths[Path], 'patch'>>, HttpClientResponse<Paths[Path]['patch'], Media>, unknown>>): HttpResourceRef<HttpClientResponse<Paths[Path]['patch'], Media> | undefined>;
}
export {};