UNPKG

@hyper-fetch/core

Version:

Cache, Queue and Persist your requests no matter if you are online or offline!

105 lines 6.08 kB
import { ClientInstance } from '../client'; import { Request, RequestInstance } from '../request'; import { ExtractEndpointType, ExtractResponseType, ExtractPayloadType, ExtractQueryParamsType, ExtractLocalErrorType, ExtractHasPayloadType, ExtractHasParamsType, ExtractHasQueryParamsType, ExtractMutationContextType } from '../types'; export type RecursiveSchemaType = Record<string, // for example users / $userId / posts / $postId any>; /** * Recursively walks a schema and rebuilds every `Request` leaf with the SDK's actual client * type injected into the `Client` generic slot. Lets users omit `client` from their * `RequestModel<{...}>` declarations - the SDK fills it in from the client passed to * `createSdk(client)`. * * Non-Request leaves (primitive values, plain types) are passed through unchanged. Nested * schema objects are recursed into. Depth is guarded at 10 levels to keep the type checker * within reasonable bounds. */ export type InjectClient<T, TClient extends ClientInstance, Depth extends unknown[] = []> = Depth["length"] extends 10 ? T : T extends RequestInstance ? Request<ExtractResponseType<T>, ExtractPayloadType<T>, ExtractQueryParamsType<T>, ExtractLocalErrorType<T>, ExtractEndpointType<T> extends string ? ExtractEndpointType<T> : string, TClient, ExtractHasPayloadType<T> extends boolean ? ExtractHasPayloadType<T> : false, ExtractHasParamsType<T> extends boolean ? ExtractHasParamsType<T> : false, ExtractHasQueryParamsType<T> extends boolean ? ExtractHasQueryParamsType<T> : false, ExtractMutationContextType<T>> : T extends Record<string, any> ? { [K in keyof T]: InjectClient<T[K], TClient, [...Depth, unknown]>; } : T; /** * Per-request defaults that can be applied via SDK configuration. * These mirror the chainable setters on Request (headers, cache, retry, etc.). */ export type SdkRequestDefaults = { headers?: HeadersInit; auth?: boolean; cache?: boolean; cacheTime?: number; staleTime?: number; retry?: number; retryTime?: number; cancelable?: boolean; queued?: boolean; offline?: boolean; deduplicate?: boolean; deduplicateTime?: number | null; }; /** * Configuration value: either a static property bag or a function that receives * the request and returns a modified request (full access to every Request setter). */ export type SdkConfigurationValue = SdkRequestDefaults | ((request: RequestInstance) => RequestInstance); /** * Recursively extracts all endpoint strings from an SDK schema type. * Leaf nodes (keys starting with $) are RequestInstance — extract endpoint from those. * Other keys are nested schema segments to recurse into. */ type ExtractSdkEndpoints<T, Depth extends unknown[] = []> = Depth["length"] extends 10 ? never : { [K in keyof T]: K extends `$${string}` ? T[K] extends RequestInstance ? ExtractEndpointType<T[K]> : never : T[K] extends Record<string, any> ? ExtractSdkEndpoints<T[K], [...Depth, unknown]> : never; }[keyof T]; /** * Recursively extracts dot-path accessor keys from an SDK schema. * These mirror the SDK property chain: "users.$get", "users.$userId.$get", etc. */ type ExtractSdkPaths<T, Prefix extends string = "", Depth extends unknown[] = []> = Depth["length"] extends 10 ? never : { [K in keyof T & string]: T[K] extends RequestInstance ? `${Prefix}${K}` : T[K] extends Record<string, any> ? ExtractSdkPaths<T[K], `${Prefix}${K}.`, [...Depth, unknown]> : never; }[keyof T & string]; /** * Builds the set of valid configuration keys from an SDK schema: * - "*" (global wildcard) * - exact endpoint paths extracted from RequestInstance nodes (group keys) * - wildcard patterns like "/users/*" (group keys) * - dot-path accessor keys like "users.$get" (method-specific keys) */ type SdkConfigurationKeys<Schema extends RecursiveSchemaType> = "*" | ExtractSdkEndpoints<Schema> | `${ExtractSdkEndpoints<Schema> & string}/*` | ExtractSdkPaths<Schema>; /** * Maps endpoint paths, wildcard patterns, or dot-path accessor keys to request defaults. * Keys are validated against the SDK schema. * * Values can be: * - A plain `SdkRequestDefaults` object (shorthand for common settings) * - A function `(request) => request` for full access to every Request setter */ export type SdkConfigurationMap<Schema extends RecursiveSchemaType = RecursiveSchemaType> = Partial<Record<SdkConfigurationKeys<Schema>, SdkConfigurationValue>>; export type CreateSdkOptions<Schema extends RecursiveSchemaType = RecursiveSchemaType> = { /** @default true */ camelCaseToKebabCase?: boolean; /** @default (method) => method.toUpperCase() */ methodTransform?: (method: string) => string; /** Per-endpoint request defaults */ defaults?: SdkConfigurationMap<Schema>; }; /** * The fully-resolved SDK instance type returned by `createSdk`. * * The schema is rewritten via {@link InjectClient} so every `Request` leaf carries the * actual client type passed to `createSdk(client)` - users do not need to repeat * `client: AppClient` in every `RequestModel<{...}>` declaration. */ export type SdkInstance<Schema extends RecursiveSchemaType, TClient extends ClientInstance = ClientInstance> = InjectClient<Schema, TClient> & { /** * Apply request defaults to the SDK. Returns a new SDK instance with the configuration applied. * Use "*" to match all endpoints, or specific endpoint strings / wildcard patterns. */ $configure: (defaults: SdkConfigurationMap<Schema>) => SdkInstance<Schema, TClient>; }; export declare const createSdk: <Client extends ClientInstance, RecursiveSchema extends RecursiveSchemaType>(client: Client, options?: CreateSdkOptions<RecursiveSchema>) => SdkInstance<RecursiveSchema, Client>; /** * Type-safe factory for creating SDK configuration maps. * * @example * const config = createConfiguration<MySdkSchema>()({ "*": { retry: 3 } }) */ export declare const createConfiguration: <Schema extends RecursiveSchemaType>() => (defaults: SdkConfigurationMap<Schema>) => SdkConfigurationMap<Schema>; export {}; //# sourceMappingURL=sdk.d.ts.map