@shipworthy/openapi-fetch 0.0.2 → 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,138 @@
1
+ /** Return `content` for a Response Object */
2
+ type ResponseContent<T> = T extends {
3
+ content: any;
4
+ } ? T["content"] : unknown;
5
+ /** Return type of `requestBody` for an Operation Object */
6
+ type OperationRequestBody<T> = "requestBody" extends keyof T ? T["requestBody"] : never;
7
+ /** Internal helper to get object type with only the `requestBody` property */
8
+ type PickRequestBody<T> = "requestBody" extends keyof T ? Pick<T, "requestBody"> : never;
9
+ /** Resolve to `true` if request body is optional, else `false` */
10
+ type IsOperationRequestBodyOptional<T> = RequiredKeysOf<PickRequestBody<T>> extends never ? true : false;
11
+ /** Internal helper used in OperationRequestBodyContent */
12
+ type OperationRequestBodyMediaContent<T> = IsOperationRequestBodyOptional<T> extends true ? ResponseContent<NonNullable<OperationRequestBody<T>>> | undefined : ResponseContent<OperationRequestBody<T>>;
13
+ /** Return first `content` from a Request Object Mapping, allowing any media type */
14
+ type OperationRequestBodyContent<T> = FilterKeys<OperationRequestBodyMediaContent<T>, MediaType> extends never ? FilterKeys<NonNullable<OperationRequestBodyMediaContent<T>>, MediaType> | undefined : FilterKeys<OperationRequestBodyMediaContent<T>, MediaType>;
15
+ /** Find first match of multiple keys */
16
+ type FilterKeys<Obj, Matchers> = Obj[keyof Obj & Matchers];
17
+ /** Return any `[string]/[string]` media type (important because openapi-fetch allows any content response, not just JSON-like) */
18
+ type MediaType = `${string}/${string}`;
19
+ /** Helper to get the required keys of an object. If no keys are required, will be `undefined` with strictNullChecks enabled, else `never` */
20
+ type RequiredKeysOfHelper<T> = { [K in keyof T]: {} extends Pick<T, K> ? never : K; }[keyof T];
21
+ /** Get the required keys of an object, or `never` if no keys are required */
22
+ type RequiredKeysOf<T> = RequiredKeysOfHelper<T> extends undefined ? never : RequiredKeysOfHelper<T>;
23
+ type HeadersOptions = Required<RequestInit>["headers"] | Record<string, string | number | boolean | (string | number | boolean)[] | null | undefined>;
24
+ type QuerySerializer<T> = (query: T extends {
25
+ parameters: any;
26
+ } ? NonNullable<T["parameters"]["query"]> : Record<string, unknown>) => string;
27
+ type BodySerializer<T> = (body: OperationRequestBodyContent<T>, headers?: Headers) => any;
28
+ type PathSerializer = (pathname: string, pathParams: Record<string, unknown>) => string;
29
+ type BodyType<T = unknown> = {
30
+ json: T;
31
+ text: Awaited<ReturnType<Response["text"]>>;
32
+ blob: Awaited<ReturnType<Response["blob"]>>;
33
+ arrayBuffer: Awaited<ReturnType<Response["arrayBuffer"]>>;
34
+ stream: Response["body"];
35
+ };
36
+ type ParseAs = keyof BodyType;
37
+ type MergedOptions<T = unknown> = {
38
+ baseUrl: string;
39
+ parseAs: ParseAs;
40
+ querySerializer: QuerySerializer<T>;
41
+ bodySerializer: BodySerializer<T>;
42
+ pathSerializer: PathSerializer;
43
+ fetch: typeof globalThis.fetch;
44
+ };
45
+ interface MiddlewareRequestParams {
46
+ query?: Record<string, unknown>;
47
+ header?: HeadersOptions;
48
+ path?: Record<string, unknown>;
49
+ cookie?: Record<string, unknown>;
50
+ }
51
+ interface MiddlewareRequestInput {
52
+ readonly params: MiddlewareRequestParams;
53
+ readonly body: unknown;
54
+ }
55
+ interface MiddlewareRequestInitParams {
56
+ readonly schemaPath: string;
57
+ readonly method: string;
58
+ readonly input: MiddlewareRequestInput;
59
+ /** Client, request, and parameter headers merged before serialization. */
60
+ readonly headers: Headers;
61
+ readonly id: string;
62
+ readonly options: MergedOptions;
63
+ }
64
+ interface MiddlewareResult {
65
+ readonly data?: unknown;
66
+ readonly error?: unknown;
67
+ readonly response: Response;
68
+ }
69
+ interface MiddlewareCallbackParams {
70
+ /** Current Request object */
71
+ request: Request;
72
+ /** The original OpenAPI schema path (including curly braces) */
73
+ readonly schemaPath: string;
74
+ /** OpenAPI parameters as provided from openapi-fetch */
75
+ readonly params: MiddlewareRequestParams;
76
+ /** Unique ID for this request */
77
+ readonly id: string;
78
+ /** createClient options (read-only) */
79
+ readonly options: MergedOptions;
80
+ }
81
+ interface MiddlewareResultParams extends MiddlewareCallbackParams {
82
+ /** The method requested through the client, before HTTP middleware can replace the Request. */
83
+ readonly method: string;
84
+ readonly result: MiddlewareResult;
85
+ }
86
+ type MiddlewareOnRequestInit = (options: MiddlewareRequestInitParams) => void | MiddlewareRequestInput | Promise<MiddlewareRequestInput | void>;
87
+ type MiddlewareOnRequest = (options: MiddlewareCallbackParams) => void | Request | Response | undefined | Promise<Request | Response | undefined | void>;
88
+ type MiddlewareOnResponse = (options: MiddlewareCallbackParams & {
89
+ response: Response;
90
+ }) => void | Response | undefined | Promise<Response | undefined | void>;
91
+ type MiddlewareOnError = (options: MiddlewareCallbackParams & {
92
+ error: unknown;
93
+ }) => void | Response | Error | Promise<void | Response | Error>;
94
+ type MiddlewareOnResult = (options: MiddlewareResultParams) => void | Partial<Pick<MiddlewareResult, "data" | "error">> | Promise<Partial<Pick<MiddlewareResult, "data" | "error">> | void>;
95
+ interface MiddlewareHooks {
96
+ onRequestInit?: MiddlewareOnRequestInit;
97
+ onRequest?: MiddlewareOnRequest;
98
+ onResponse?: MiddlewareOnResponse;
99
+ onError?: MiddlewareOnError;
100
+ onResult?: MiddlewareOnResult;
101
+ }
102
+ type Middleware = MiddlewareHooks & ({
103
+ onRequestInit: MiddlewareOnRequestInit;
104
+ } | {
105
+ onRequest: MiddlewareOnRequest;
106
+ } | {
107
+ onResponse: MiddlewareOnResponse;
108
+ } | {
109
+ onError: MiddlewareOnError;
110
+ } | {
111
+ onResult: MiddlewareOnResult;
112
+ });
113
+ interface CaseSchema {
114
+ readonly ref?: string;
115
+ readonly properties?: Readonly<Record<string, {
116
+ readonly name: string;
117
+ readonly schema?: CaseSchema;
118
+ }>>;
119
+ readonly declared?: readonly string[];
120
+ readonly items?: CaseSchema;
121
+ readonly prefixItems?: readonly (CaseSchema | null)[];
122
+ readonly additionalProperties?: CaseSchema;
123
+ readonly patternProperties?: Readonly<Record<string, CaseSchema | null>>;
124
+ readonly variants?: readonly CaseSchema[];
125
+ }
126
+ type CaseMediaMap = Readonly<Record<string, CaseSchema | null>>;
127
+ interface CaseOperation {
128
+ readonly parameters?: Readonly<Partial<Record<"path" | "query" | "header" | "cookie", CaseSchema>>>;
129
+ readonly requestBodies?: CaseMediaMap;
130
+ readonly responses?: Readonly<Record<string, CaseMediaMap | null>>;
131
+ }
132
+ export interface CaseMapping {
133
+ readonly schemas?: Readonly<Record<string, CaseSchema>>;
134
+ readonly operations?: Readonly<Record<string, CaseOperation>>;
135
+ }
136
+ /** Convert generated camelCase values at the openapi-fetch request and result stages. */
137
+ export declare function createCaseMappingMiddleware(mapping: CaseMapping): Middleware;
138
+ export {};
@@ -0,0 +1,138 @@
1
+ /** Return `content` for a Response Object */
2
+ type ResponseContent<T> = T extends {
3
+ content: any;
4
+ } ? T["content"] : unknown;
5
+ /** Return type of `requestBody` for an Operation Object */
6
+ type OperationRequestBody<T> = "requestBody" extends keyof T ? T["requestBody"] : never;
7
+ /** Internal helper to get object type with only the `requestBody` property */
8
+ type PickRequestBody<T> = "requestBody" extends keyof T ? Pick<T, "requestBody"> : never;
9
+ /** Resolve to `true` if request body is optional, else `false` */
10
+ type IsOperationRequestBodyOptional<T> = RequiredKeysOf<PickRequestBody<T>> extends never ? true : false;
11
+ /** Internal helper used in OperationRequestBodyContent */
12
+ type OperationRequestBodyMediaContent<T> = IsOperationRequestBodyOptional<T> extends true ? ResponseContent<NonNullable<OperationRequestBody<T>>> | undefined : ResponseContent<OperationRequestBody<T>>;
13
+ /** Return first `content` from a Request Object Mapping, allowing any media type */
14
+ type OperationRequestBodyContent<T> = FilterKeys<OperationRequestBodyMediaContent<T>, MediaType> extends never ? FilterKeys<NonNullable<OperationRequestBodyMediaContent<T>>, MediaType> | undefined : FilterKeys<OperationRequestBodyMediaContent<T>, MediaType>;
15
+ /** Find first match of multiple keys */
16
+ type FilterKeys<Obj, Matchers> = Obj[keyof Obj & Matchers];
17
+ /** Return any `[string]/[string]` media type (important because openapi-fetch allows any content response, not just JSON-like) */
18
+ type MediaType = `${string}/${string}`;
19
+ /** Helper to get the required keys of an object. If no keys are required, will be `undefined` with strictNullChecks enabled, else `never` */
20
+ type RequiredKeysOfHelper<T> = { [K in keyof T]: {} extends Pick<T, K> ? never : K; }[keyof T];
21
+ /** Get the required keys of an object, or `never` if no keys are required */
22
+ type RequiredKeysOf<T> = RequiredKeysOfHelper<T> extends undefined ? never : RequiredKeysOfHelper<T>;
23
+ type HeadersOptions = Required<RequestInit>["headers"] | Record<string, string | number | boolean | (string | number | boolean)[] | null | undefined>;
24
+ type QuerySerializer<T> = (query: T extends {
25
+ parameters: any;
26
+ } ? NonNullable<T["parameters"]["query"]> : Record<string, unknown>) => string;
27
+ type BodySerializer<T> = (body: OperationRequestBodyContent<T>, headers?: Headers) => any;
28
+ type PathSerializer = (pathname: string, pathParams: Record<string, unknown>) => string;
29
+ type BodyType<T = unknown> = {
30
+ json: T;
31
+ text: Awaited<ReturnType<Response["text"]>>;
32
+ blob: Awaited<ReturnType<Response["blob"]>>;
33
+ arrayBuffer: Awaited<ReturnType<Response["arrayBuffer"]>>;
34
+ stream: Response["body"];
35
+ };
36
+ type ParseAs = keyof BodyType;
37
+ type MergedOptions<T = unknown> = {
38
+ baseUrl: string;
39
+ parseAs: ParseAs;
40
+ querySerializer: QuerySerializer<T>;
41
+ bodySerializer: BodySerializer<T>;
42
+ pathSerializer: PathSerializer;
43
+ fetch: typeof globalThis.fetch;
44
+ };
45
+ interface MiddlewareRequestParams {
46
+ query?: Record<string, unknown>;
47
+ header?: HeadersOptions;
48
+ path?: Record<string, unknown>;
49
+ cookie?: Record<string, unknown>;
50
+ }
51
+ interface MiddlewareRequestInput {
52
+ readonly params: MiddlewareRequestParams;
53
+ readonly body: unknown;
54
+ }
55
+ interface MiddlewareRequestInitParams {
56
+ readonly schemaPath: string;
57
+ readonly method: string;
58
+ readonly input: MiddlewareRequestInput;
59
+ /** Client, request, and parameter headers merged before serialization. */
60
+ readonly headers: Headers;
61
+ readonly id: string;
62
+ readonly options: MergedOptions;
63
+ }
64
+ interface MiddlewareResult {
65
+ readonly data?: unknown;
66
+ readonly error?: unknown;
67
+ readonly response: Response;
68
+ }
69
+ interface MiddlewareCallbackParams {
70
+ /** Current Request object */
71
+ request: Request;
72
+ /** The original OpenAPI schema path (including curly braces) */
73
+ readonly schemaPath: string;
74
+ /** OpenAPI parameters as provided from openapi-fetch */
75
+ readonly params: MiddlewareRequestParams;
76
+ /** Unique ID for this request */
77
+ readonly id: string;
78
+ /** createClient options (read-only) */
79
+ readonly options: MergedOptions;
80
+ }
81
+ interface MiddlewareResultParams extends MiddlewareCallbackParams {
82
+ /** The method requested through the client, before HTTP middleware can replace the Request. */
83
+ readonly method: string;
84
+ readonly result: MiddlewareResult;
85
+ }
86
+ type MiddlewareOnRequestInit = (options: MiddlewareRequestInitParams) => void | MiddlewareRequestInput | Promise<MiddlewareRequestInput | void>;
87
+ type MiddlewareOnRequest = (options: MiddlewareCallbackParams) => void | Request | Response | undefined | Promise<Request | Response | undefined | void>;
88
+ type MiddlewareOnResponse = (options: MiddlewareCallbackParams & {
89
+ response: Response;
90
+ }) => void | Response | undefined | Promise<Response | undefined | void>;
91
+ type MiddlewareOnError = (options: MiddlewareCallbackParams & {
92
+ error: unknown;
93
+ }) => void | Response | Error | Promise<void | Response | Error>;
94
+ type MiddlewareOnResult = (options: MiddlewareResultParams) => void | Partial<Pick<MiddlewareResult, "data" | "error">> | Promise<Partial<Pick<MiddlewareResult, "data" | "error">> | void>;
95
+ interface MiddlewareHooks {
96
+ onRequestInit?: MiddlewareOnRequestInit;
97
+ onRequest?: MiddlewareOnRequest;
98
+ onResponse?: MiddlewareOnResponse;
99
+ onError?: MiddlewareOnError;
100
+ onResult?: MiddlewareOnResult;
101
+ }
102
+ type Middleware = MiddlewareHooks & ({
103
+ onRequestInit: MiddlewareOnRequestInit;
104
+ } | {
105
+ onRequest: MiddlewareOnRequest;
106
+ } | {
107
+ onResponse: MiddlewareOnResponse;
108
+ } | {
109
+ onError: MiddlewareOnError;
110
+ } | {
111
+ onResult: MiddlewareOnResult;
112
+ });
113
+ interface CaseSchema {
114
+ readonly ref?: string;
115
+ readonly properties?: Readonly<Record<string, {
116
+ readonly name: string;
117
+ readonly schema?: CaseSchema;
118
+ }>>;
119
+ readonly declared?: readonly string[];
120
+ readonly items?: CaseSchema;
121
+ readonly prefixItems?: readonly (CaseSchema | null)[];
122
+ readonly additionalProperties?: CaseSchema;
123
+ readonly patternProperties?: Readonly<Record<string, CaseSchema | null>>;
124
+ readonly variants?: readonly CaseSchema[];
125
+ }
126
+ type CaseMediaMap = Readonly<Record<string, CaseSchema | null>>;
127
+ interface CaseOperation {
128
+ readonly parameters?: Readonly<Partial<Record<"path" | "query" | "header" | "cookie", CaseSchema>>>;
129
+ readonly requestBodies?: CaseMediaMap;
130
+ readonly responses?: Readonly<Record<string, CaseMediaMap | null>>;
131
+ }
132
+ export interface CaseMapping {
133
+ readonly schemas?: Readonly<Record<string, CaseSchema>>;
134
+ readonly operations?: Readonly<Record<string, CaseOperation>>;
135
+ }
136
+ /** Convert generated camelCase values at the openapi-fetch request and result stages. */
137
+ export declare function createCaseMappingMiddleware(mapping: CaseMapping): Middleware;
138
+ export {};
@@ -0,0 +1,160 @@
1
+ // src/middleware/transform-casing.ts
2
+ function expandSchemas(schemas, mapping, visited = /* @__PURE__ */ new Set()) {
3
+ return schemas.flatMap((schema) => {
4
+ const nested = schema.variants ?? [];
5
+ if (!schema.ref || visited.has(schema.ref)) return [schema, ...expandSchemas(nested, mapping, visited)];
6
+ const referenced = mapping.schemas?.[schema.ref];
7
+ const next = new Set(visited).add(schema.ref);
8
+ return [schema, ...expandSchemas(referenced ? [referenced, ...nested] : nested, mapping, next)];
9
+ });
10
+ }
11
+ function createConverter(mapping) {
12
+ const schemaIds = /* @__PURE__ */ new WeakMap();
13
+ const plans = /* @__PURE__ */ new Map();
14
+ let nextId = 0;
15
+ function planFor(schemas, direction) {
16
+ if (schemas.length === 0) return void 0;
17
+ const key = `${direction}:${schemas.map((schema) => {
18
+ let id = schemaIds.get(schema);
19
+ if (id === void 0) {
20
+ id = ++nextId;
21
+ schemaIds.set(schema, id);
22
+ }
23
+ return id;
24
+ }).join(",")}`;
25
+ const existing = plans.get(key);
26
+ if (existing) return existing;
27
+ const expanded = expandSchemas(schemas, mapping);
28
+ const fields = /* @__PURE__ */ new Map();
29
+ for (const schema of expanded) for (const [wireName, field] of Object.entries(schema.properties ?? {})) {
30
+ const sourceName = direction === "toApi" ? field.name : wireName;
31
+ const targetName = direction === "toApi" ? wireName : field.name;
32
+ const current = fields.get(sourceName);
33
+ if (current) {
34
+ if (current.name !== targetName) throw new Error(`Conflicting case mapping for ${sourceName}`);
35
+ if (field.schema) current.schemas.push(field.schema);
36
+ } else fields.set(sourceName, {
37
+ name: targetName,
38
+ schemas: field.schema ? [field.schema] : []
39
+ });
40
+ }
41
+ const plan = {
42
+ expanded,
43
+ fields,
44
+ declared: new Set(expanded.flatMap((schema) => schema.declared ?? [])),
45
+ patterns: expanded.flatMap((schema) => Object.entries(schema.patternProperties ?? {}).map(([pattern, nested]) => ({
46
+ regex: new RegExp(pattern),
47
+ schema: nested
48
+ }))),
49
+ additional: expanded.flatMap((schema) => schema.additionalProperties ? [schema.additionalProperties] : []),
50
+ prefixLength: expanded.reduce((max, schema) => Math.max(max, schema.prefixItems?.length ?? 0), 0)
51
+ };
52
+ plans.set(key, plan);
53
+ return plan;
54
+ }
55
+ function itemPlan(plan, index, direction) {
56
+ if (index >= plan.prefixLength) {
57
+ if (plan.items === void 0) plan.items = planFor(plan.expanded.flatMap((schema) => schema.items ? [schema.items] : []), direction) ?? null;
58
+ return plan.items ?? void 0;
59
+ }
60
+ const prefixItems = plan.prefixItems ??= [];
61
+ if (prefixItems[index] === void 0) prefixItems[index] = planFor(plan.expanded.flatMap((schema) => {
62
+ const prefix = schema.prefixItems;
63
+ const item = prefix && index < prefix.length ? prefix[index] : schema.items;
64
+ return item ? [item] : [];
65
+ }), direction) ?? null;
66
+ return prefixItems[index] ?? void 0;
67
+ }
68
+ function convertWithPlan(value, plan, direction) {
69
+ if (!plan || value === null || value === void 0) return value;
70
+ if (Array.isArray(value)) return value.map((item, index) => convertWithPlan(item, itemPlan(plan, index, direction), direction));
71
+ if (typeof value !== "object") return value;
72
+ const prototype = Object.getPrototypeOf(value);
73
+ if (prototype !== Object.prototype && prototype !== null) return value;
74
+ const convertedNames = /* @__PURE__ */ new Set();
75
+ const entries = Object.entries(value).map(([name, item]) => {
76
+ const field = plan.fields.get(name);
77
+ const matched = [];
78
+ let hasPattern = false;
79
+ for (const pattern of plan.patterns) if (pattern.regex.test(name)) {
80
+ hasPattern = true;
81
+ if (pattern.schema) matched.push(pattern.schema);
82
+ }
83
+ let nested;
84
+ if (matched.length > 0) nested = planFor([...field?.schemas ?? [], ...matched], direction);
85
+ else if (field) {
86
+ if (field.nested === void 0) field.nested = planFor(field.schemas, direction) ?? null;
87
+ nested = field.nested ?? void 0;
88
+ } else if (!plan.declared.has(name) && !hasPattern) {
89
+ if (plan.additionalPlan === void 0) plan.additionalPlan = planFor(plan.additional, direction) ?? null;
90
+ nested = plan.additionalPlan ?? void 0;
91
+ }
92
+ const targetName = field?.name ?? name;
93
+ if (convertedNames.has(targetName)) throw new Error(`Conflicting case mapping for ${targetName}`);
94
+ convertedNames.add(targetName);
95
+ return [targetName, convertWithPlan(item, nested, direction)];
96
+ });
97
+ return Object.fromEntries(entries);
98
+ }
99
+ return (value, schemas, direction) => {
100
+ if (schemas.length === 0 || value === null || value === void 0) return value;
101
+ return convertWithPlan(value, planFor(schemas, direction), direction);
102
+ };
103
+ }
104
+ function isJsonMediaType(mediaType) {
105
+ return mediaType === "application/json" || mediaType.endsWith("+json");
106
+ }
107
+ function mediaSchema(media, contentType) {
108
+ if (!media) return void 0;
109
+ const type = contentType?.split(";", 1)[0]?.trim().toLowerCase();
110
+ if (type && !isJsonMediaType(type)) return void 0;
111
+ const entries = Object.entries(media).filter(([name]) => isJsonMediaType(name.toLowerCase()));
112
+ const exact = entries.find(([name]) => name.toLowerCase() === type);
113
+ if (exact) return exact[1] ?? void 0;
114
+ const json = entries.find(([name]) => name.toLowerCase() === "application/json");
115
+ if (json) return json[1] ?? void 0;
116
+ return entries.length === 1 ? entries[0]?.[1] ?? void 0 : void 0;
117
+ }
118
+ function responseMedia(operation, response) {
119
+ const responses = operation.responses;
120
+ if (!responses) return void 0;
121
+ const status = String(response.status);
122
+ const range = `${status[0]}XX`;
123
+ return mediaSchema(Object.hasOwn(responses, status) ? responses[status] : Object.hasOwn(responses, range) ? responses[range] : responses.default, response.headers.get("content-type") ?? void 0);
124
+ }
125
+ function convertRequest(input, operation, convertValue, headers) {
126
+ const parameters = operation.parameters;
127
+ const params = input.params;
128
+ const bodySchema = mediaSchema(operation.requestBodies, headers.get("content-type") ?? void 0);
129
+ return {
130
+ params: parameters ? {
131
+ ...params,
132
+ path: convertValue(params.path, parameters.path ? [parameters.path] : [], "toApi"),
133
+ query: convertValue(params.query, parameters.query ? [parameters.query] : [], "toApi"),
134
+ header: convertValue(params.header, parameters.header ? [parameters.header] : [], "toApi"),
135
+ cookie: convertValue(params.cookie, parameters.cookie ? [parameters.cookie] : [], "toApi")
136
+ } : params,
137
+ body: bodySchema && input.body !== void 0 ? convertValue(input.body, [bodySchema], "toApi") : input.body
138
+ };
139
+ }
140
+ /** Convert generated camelCase values at the openapi-fetch request and result stages. */
141
+ function createCaseMappingMiddleware(mapping) {
142
+ const convertValue = createConverter(mapping);
143
+ return {
144
+ onRequestInit({ method, schemaPath, input, headers }) {
145
+ const operation = mapping.operations?.[`${method} ${schemaPath}`];
146
+ return operation ? convertRequest(input, operation, convertValue, headers) : void 0;
147
+ },
148
+ onResult({ method, schemaPath, result, options }) {
149
+ const operation = mapping.operations?.[`${method} ${schemaPath}`];
150
+ if (!operation) return;
151
+ const schema = responseMedia(operation, result.response);
152
+ if (!schema) return;
153
+ return {
154
+ ...options.parseAs === "json" && result.data !== void 0 ? { data: convertValue(result.data, [schema], "fromApi") } : {},
155
+ ...result.error !== void 0 ? { error: convertValue(result.error, [schema], "fromApi") } : {}
156
+ };
157
+ }
158
+ };
159
+ }
160
+ export { createCaseMappingMiddleware };
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@shipworthy/openapi-fetch",
3
- "version": "0.0.2",
3
+ "version": "1.0.0",
4
4
  "files": [
5
5
  "dist"
6
6
  ],
7
- "description": "Fast, type-safe fetch client for your OpenAPI schema. Only 6 kb (min). Works with React, Vue, Svelte, or vanilla JS.",
7
+ "description": "Fast, type-safe fetch client for your OpenAPI schema. Works with React, Vue, Svelte, or vanilla JS.",
8
8
  "keywords": [
9
9
  "api",
10
10
  "fetch",
@@ -36,6 +36,16 @@
36
36
  "default": "./dist/index.cjs"
37
37
  }
38
38
  },
39
+ "./middleware/transform-casing": {
40
+ "import": {
41
+ "types": "./dist/transform-casing.d.ts",
42
+ "default": "./dist/transform-casing.js"
43
+ },
44
+ "require": {
45
+ "types": "./dist/transform-casing.d.cts",
46
+ "default": "./dist/transform-casing.cjs"
47
+ }
48
+ },
39
49
  "./package.json": "./package.json"
40
50
  },
41
51
  "scripts": {
@@ -43,9 +53,9 @@
43
53
  "test": "vitest run"
44
54
  },
45
55
  "devDependencies": {
46
- "tsdown": "0.23.0",
56
+ "tsdown": "0.23.7",
47
57
  "typescript": "^7.0.2",
48
- "vitest": "5.0.3"
58
+ "vitest": "5.1.0"
49
59
  },
50
60
  "main": "./dist/index.cjs",
51
61
  "module": "./dist/index.js",