@padosoft/zod-to-openapi-client 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,124 @@
1
+ import { ResponseConfig, RouteConfig, ZodRequestBody } from "@asteasolutions/zod-to-openapi";
2
+ import { ConvertMaybeZod, DeepConvertMaybeZod, MergeWithDefault, Prettify } from "@padosoft/utilities";
3
+
4
+ //#region src/utilities/constants.d.ts
5
+ type HttpMethod = "get" | "put" | "post" | "delete" | "options" | "head" | "patch" | "trace";
6
+ interface ParametersNameFetchClientToSpec {
7
+ path: "params";
8
+ query: "query";
9
+ cookie: "cookies";
10
+ header: "headers";
11
+ }
12
+ type Parameters<R extends RouteConfig["request"] = RouteConfig["request"]> = keyof Omit<NonNullable<R>, "body">;
13
+ interface NoParameters extends Partial<Record<Parameters, never>> {}
14
+ type MetaKeys = keyof Pick<RouteConfig, "tags" | "operationId" | "summary" | "externalDocs" | "deprecated" | "description">;
15
+ //#endregion
16
+ //#region src/utilities/endpoint.d.ts
17
+ type ApplyEndpointCollectionConfig<Endpoint extends RouteConfig, Config extends {
18
+ path: string;
19
+ }> = Omit<Endpoint, "path"> & {
20
+ path: `${Config["path"]}${Endpoint["path"] extends "/" ? "" : Endpoint["path"]}`;
21
+ };
22
+ type EndpointTypes<T> = {
23
+ Collections: keyof T;
24
+ CollectionGraph: { [Collection in keyof T]: T[Collection] extends infer Operations ? { [Operation in keyof Operations as Operation extends "config" ? never : Operation]: Operations[Operation] extends RouteConfig ? ApplyEndpointCollectionConfig<Operations[Operation], "config" extends keyof Operations ? Operations["config"] extends {
25
+ path: string;
26
+ } ? Operations["config"] : never : never> : Operations[Operation] } : never };
27
+ };
28
+ type CollectionMap<T> = EndpointTypes<T>["CollectionGraph"][EndpointTypes<T>["Collections"]];
29
+ type Endpoints<T> = CollectionMap<T> extends infer Collection ? Collection extends object ? Collection[keyof Collection] extends infer Operation ? Operation extends RouteConfig ? Operation : never : never : never : never;
30
+ type EndpointsMethods<T> = Endpoints<T>["method"];
31
+ type EndpointsPaths<T> = Endpoints<T>["path"];
32
+ type ExtractEndpointInfo<Endpoint extends RouteConfig> = { [K in MetaKeys as K extends keyof Endpoint ? K : never]: Endpoint[K] };
33
+ //#endregion
34
+ //#region src/converter/body.d.ts
35
+ interface RequestBodyContent<Body extends ZodRequestBody> {
36
+ content: {
37
+ "application/json": NonNullable<ConvertMaybeZod<NonNullable<NonNullable<Body["content"]>["application/json"]>["schema"]>>;
38
+ };
39
+ }
40
+ interface ConvertRequestBody<T, Endpoint extends Endpoints<T>> {
41
+ requestBody?: Endpoint extends {
42
+ request?: infer Request;
43
+ } ? Request extends RouteConfig["request"] ? NonNullable<Request> extends {
44
+ body?: infer Body;
45
+ } ? Body extends ZodRequestBody ? Body["content"] extends undefined ? never : NonNullable<Body["content"]>["application/json"] extends undefined ? never : RequestBodyContent<Body> : never : never : never : never;
46
+ }
47
+ //#endregion
48
+ //#region src/converter/parameters.d.ts
49
+ interface ConvertParameters<T, Endpoint extends Endpoints<T>> {
50
+ parameters: {
51
+ path?: Record<string, unknown>;
52
+ } & (Endpoint extends {
53
+ request?: infer Request;
54
+ } ? Request extends RouteConfig["request"] ? { [Key in keyof ParametersNameFetchClientToSpec]?: NonNullable<Request>[ParametersNameFetchClientToSpec[Key]] extends infer ParameterConfig ? ConvertMaybeZod<ParameterConfig> : NoParameters } : NoParameters : NoParameters);
55
+ }
56
+ //#endregion
57
+ //#region src/converter/responses.d.ts
58
+ type InterestingResponseStatuses = 200 | "default";
59
+ type InterestingResponseFields = keyof Pick<ResponseConfig, "content" | "headers" | "description">;
60
+ interface ConvertResponses<T, Endpoint extends Endpoints<T>, TDefaultErrorResponse extends ResponseConfig = ResponseConfig> {
61
+ responses: MergeWithDefault<{ [Status in Extract<InterestingResponseStatuses, keyof Endpoint["responses"]>]: Endpoint["responses"][Status] extends infer Response ? Response extends ResponseConfig ? { [InfoField in keyof Pick<Response, InterestingResponseFields>]: Response[InfoField] extends infer ResponseInfoField ? DeepConvertMaybeZod<ResponseInfoField> : never } : never : never }, "default", TDefaultErrorResponse>;
62
+ }
63
+ //#endregion
64
+ //#region src/converter/index.d.ts
65
+ interface Converter<T, Endpoint extends Endpoints<T>, TDefaultErrorResponse extends ResponseConfig = ResponseConfig> extends ConvertRequestBody<T, Endpoint>, ConvertParameters<T, Endpoint>, ConvertResponses<T, Endpoint, TDefaultErrorResponse> {
66
+ _meta: ExtractEndpointInfo<Endpoint>;
67
+ }
68
+ //#endregion
69
+ //#region src/utilities/search.d.ts
70
+ type FindEndpointBymethod<T, M extends HttpMethod> = Extract<Endpoints<T>, {
71
+ method: M;
72
+ }>;
73
+ type FindEndpointWithoutAutocomplete<T, P extends string, M extends HttpMethod> = Extract<FindEndpointBymethod<T, M>, {
74
+ path: P;
75
+ }>;
76
+ type GetSpecEndpoint<T, M extends EndpointsMethods<T>, P extends FindEndpointBymethod<T, M>["path"]> = Extract<Endpoints<T>, {
77
+ method: M;
78
+ path: P;
79
+ }>;
80
+ type GetEndpoint<T, M extends EndpointsMethods<T>, P extends FindEndpointBymethod<T, M>["path"], TDefaultErrorResponse extends ResponseConfig = ResponseConfig> = Converter<T, Extract<Endpoints<T>, {
81
+ method: M;
82
+ path: P;
83
+ }>, TDefaultErrorResponse>;
84
+ //#endregion
85
+ //#region src/steps/convert-endpoints.d.ts
86
+ type ConvertEndpoints<T, TDefaultErrorResponse extends ResponseConfig = ResponseConfig> = { [P in Endpoints<T> as P["path"]]: { [M in HttpMethod as FindEndpointWithoutAutocomplete<T, P["path"], M> extends never ? M : never]?: never } & { [M in HttpMethod as FindEndpointWithoutAutocomplete<T, P["path"], M> extends never ? never : M]: Converter<T, FindEndpointWithoutAutocomplete<T, P["path"], M>, TDefaultErrorResponse> } };
87
+ //#endregion
88
+ //#region src/steps/setup-endpoints.d.ts
89
+ type SetupEndpoints<T, TDefaultErrorResponse extends ResponseConfig = ResponseConfig> = { [P in Endpoints<T> as P["path"]]: { [M in HttpMethod]: FindEndpointWithoutAutocomplete<T, P["path"], M> extends never ? never : Converter<T, FindEndpointWithoutAutocomplete<T, P["path"], M>, TDefaultErrorResponse> } };
90
+ //#endregion
91
+ //#region src/steps/setup-params.d.ts
92
+ type SetupParams<T> = { [Path in EndpointsPaths<T>]: {
93
+ parameters: NoParameters;
94
+ } };
95
+ //#endregion
96
+ //#region src/index.d.ts
97
+ /**
98
+ * Converts a record of zod-to-openapi route collections into a typed `Paths`
99
+ * object compatible with `openapi-fetch` and `@padosoft/openapi-client`.
100
+ *
101
+ * @typeParam TCollections - A record whose values are route collections produced
102
+ * by `@asteasolutions/zod-to-openapi`. Each collection may carry a `config`
103
+ * property with a `path` prefix (e.g. `{ path: "/v1/auth" }`).
104
+ *
105
+ * @typeParam TDefaultErrorResponse - The `ResponseConfig` shape used to fill the
106
+ * `"default"` response slot on every endpoint. Defaults to the base
107
+ * `ResponseConfig` type. Pass your own error schema to get typed error responses:
108
+ *
109
+ * @example
110
+ * ```ts
111
+ * // No custom error schema — uses base ResponseConfig
112
+ * type MyPaths = CreateClientPaths<typeof myEndpoints>;
113
+ *
114
+ * // With a custom error response type
115
+ * interface MyErrorResponse extends ResponseConfig {
116
+ * content: { "application/json": { schema: MyErrorSchema } };
117
+ * description: "Error";
118
+ * }
119
+ * type MyPaths = CreateClientPaths<typeof myEndpoints, MyErrorResponse>;
120
+ * ```
121
+ */
122
+ type CreateClientPaths<TCollections, TDefaultErrorResponse extends ResponseConfig = ResponseConfig> = Prettify<SetupParams<TCollections> & SetupEndpoints<TCollections, TDefaultErrorResponse> & ConvertEndpoints<TCollections, TDefaultErrorResponse>>;
123
+ //#endregion
124
+ export { CreateClientPaths, type Endpoints, type EndpointsMethods, type EndpointsPaths, type GetEndpoint, type GetSpecEndpoint, type HttpMethod };
package/dist/index.mjs ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@padosoft/zod-to-openapi-client",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "types": "./dist/index.d.mts",
6
+ "files": [
7
+ "dist"
8
+ ],
9
+ "publishConfig": {
10
+ "access": "public",
11
+ "registry": "https://registry.npmjs.org/"
12
+ },
13
+ "repository": {
14
+ "url": "git+https://github.com/padosoft/ts-support.git"
15
+ },
16
+ "scripts": {
17
+ "build": "tsdown",
18
+ "ts:check": "tsc --noEmit"
19
+ },
20
+ "devDependencies": {
21
+ "@padosoft/config": "workspace:^"
22
+ },
23
+ "peerDependencies": {
24
+ "@asteasolutions/zod-to-openapi": ">=7",
25
+ "@padosoft/utilities": ">=1.4.0"
26
+ },
27
+ "exports": {
28
+ ".": {
29
+ "default": "./dist/index.mjs",
30
+ "types": "./dist/index.d.mts"
31
+ },
32
+ "./package.json": "./package.json"
33
+ }
34
+ }