@zap-studio/fetch 0.5.0 → 0.5.1

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @zap-studio/fetch
2
2
 
3
+ ## 0.5.1
4
+
5
+ ### Fixed
6
+
7
+ - d92f2c2: Preserve explicit `throwOnValidationError: true` overrides in `$fetch` method helpers and factory-created fetch clients.
8
+
9
+ ### Changed
10
+
11
+ - 2ea1a70: Cleaned up public option typings by removing redundant `| undefined` unions from fetch configuration types and overloads.
12
+
13
+ ### Dependencies
14
+
15
+ - Updated dependency `@zap-studio/validation` to `0.3.3`.
16
+
3
17
  ## 0.5.0
4
18
 
5
19
  ### Breaking
package/dist/index.d.mts CHANGED
@@ -52,7 +52,7 @@ declare function $fetch<TSchema extends StandardSchemaV1>(input: FetchInput, sch
52
52
  throwOnValidationError: false;
53
53
  }): Promise<StandardSchemaV1.Result<StandardSchemaV1.InferOutput<TSchema>>>;
54
54
  declare function $fetch<TSchema extends StandardSchemaV1>(input: FetchInput, schema: TSchema, options?: ExtendedRequestInit & {
55
- throwOnValidationError?: true | undefined;
55
+ throwOnValidationError?: true;
56
56
  }): Promise<StandardSchemaV1.InferOutput<TSchema>>;
57
57
  declare function $fetch(input: FetchInput, options?: ExtendedRequestInit): Promise<Response>;
58
58
  /**
package/dist/index.mjs CHANGED
@@ -77,11 +77,11 @@ const api = {
77
77
  function createFetch(factoryOptions = {}) {
78
78
  const defaults = {
79
79
  baseURL: factoryOptions.baseURL ?? "",
80
- headers: factoryOptions.headers,
81
- searchParams: factoryOptions.searchParams,
82
80
  throwOnFetchError: factoryOptions.throwOnFetchError ?? true,
83
81
  throwOnValidationError: factoryOptions.throwOnValidationError ?? true
84
82
  };
83
+ if (factoryOptions.headers !== void 0) defaults.headers = factoryOptions.headers;
84
+ if (factoryOptions.searchParams !== void 0) defaults.searchParams = factoryOptions.searchParams;
85
85
  async function customFetch(input, schemaOrOptions, optionsOrUndefined) {
86
86
  const [schema, options] = isStandardSchema(schemaOrOptions) ? [schemaOrOptions, optionsOrUndefined] : [void 0, schemaOrOptions];
87
87
  return await fetchInternal(input, schema, options, defaults);
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * Public entrypoint for the fetch package.\n *\n * Exposes:\n * - `$fetch` low-level typed fetch function\n * - `api` method shortcuts\n * - `createFetch` instance factory\n *\n * @module\n */\n\nimport { isStandardSchema, type StandardSchemaV1 } from \"@zap-studio/validation\";\n\nimport { GLOBAL_DEFAULTS } from \"./constants.js\";\nimport { fetchInternal } from \"./internal.js\";\nimport { createMethod } from \"./methods.js\";\nimport type {\n $Fetch,\n ApiMethods,\n ExtendedRequestInit,\n FetchDefaults,\n FetchInput,\n} from \"./types.js\";\n\n/**\n * Type-safe fetch wrapper with Standard Schema validation.\n *\n * - When `throwOnValidationError: true`: validated data of type `TSchema`\n * - When `throwOnValidationError: false`: Standard Schema Result object `{ value?, issues? }`\n * - When `throwOnFetchError: true`: throws `FetchError` on non-ok responses\n *\n * If no schema is provided, returns the raw `Response` object.\n *\n * @throws {FetchError} When `throwOnFetchError` is `true` and the response is not ok.\n * @throws {ValidationError} When a schema is provided, validation returns issues, and\n * `throwOnValidationError` is `true`.\n * @throws {TypeError} When both `body` and `json` are provided, when JSON request\n * serialization fails, when request construction fails, when headers/search params are\n * invalid, when `response.json()` cannot read the body, or when the runtime `fetch`\n * implementation rejects network-level failures as `TypeError`.\n * @throws {DOMException} When the runtime rejects an aborted request or response body read\n * as an `AbortError` DOMException.\n * @throws {SyntaxError} When a schema is provided and `response.json()` cannot parse the\n * response body.\n * @throws Any error thrown or rejected by the provided Standard Schema validator.\n *\n * @example\n * import { z } from \"zod\";\n * import { $fetch } from \"@zap-studio/fetch\";\n *\n * const UserSchema = z.object({ id: z.number(), name: z.string() });\n *\n * // Basic usage (schema validation)\n * const user = await $fetch(\"/api/users/1\", UserSchema, { headers: { \"Authorization\": \"Bearer token\" } });\n * console.log(\"Validated user:\", user);\n *\n * // Raw usage (no schema validation and typed Response object)\n * const result = await $fetch(\"/api/data\", { method: \"POST\", body: JSON.stringify({ key: \"value\" }) });\n * const json = await result.json() as ResultType;\n * console.log(\"Raw response data:\", json);\n *\n * // Usage with validation errors returned instead of thrown\n * const result = await $fetch(\"/api/users/1\", UserSchema, { throwOnValidationError: false });\n *\n * if (result.issues) {\n * console.error(\"Validation errors:\", result.issues);\n * } else {\n * console.log(\"Validated user:\", result.value);\n * }\n */\nexport async function $fetch<TSchema extends StandardSchemaV1>(\n input: FetchInput,\n schema: TSchema,\n options: ExtendedRequestInit & { throwOnValidationError: false },\n): Promise<StandardSchemaV1.Result<StandardSchemaV1.InferOutput<TSchema>>>;\n\nexport async function $fetch<TSchema extends StandardSchemaV1>(\n input: FetchInput,\n schema: TSchema,\n options?: ExtendedRequestInit & { throwOnValidationError?: true | undefined },\n): Promise<StandardSchemaV1.InferOutput<TSchema>>;\n\nexport async function $fetch(input: FetchInput, options?: ExtendedRequestInit): Promise<Response>;\n\nexport async function $fetch(\n input: FetchInput,\n schemaOrOptions?: StandardSchemaV1 | ExtendedRequestInit,\n optionsOrUndefined?: ExtendedRequestInit,\n): Promise<unknown> {\n const [schema, options] = isStandardSchema(schemaOrOptions)\n ? [schemaOrOptions, optionsOrUndefined]\n : [undefined, schemaOrOptions];\n\n return await fetchInternal(input, schema, options, GLOBAL_DEFAULTS);\n}\n\n/**\n * Convenience methods for common HTTP verbs.\n *\n * These methods always require a schema for validation.\n * For raw responses without validation, use `$fetch` directly.\n *\n * Each method has the same throw behavior as {@link $fetch}.\n *\n * @example\n * import { z } from \"zod\";\n * import { api } from \"@zap-studio/fetch\";\n *\n * const PostSchema = z.object({\n * id: z.number(),\n * title: z.string(),\n * content: z.string(),\n * });\n *\n * async function fetchPost(postId: number) {\n * const post = await api.get(`https://api.example.com/posts/${postId}`, PostSchema);\n * return post; // post is typed as { id: number; title: string; content: string; }\n * }\n */\nexport const api: ApiMethods = {\n get: createMethod($fetch, \"GET\"),\n post: createMethod($fetch, \"POST\"),\n put: createMethod($fetch, \"PUT\"),\n patch: createMethod($fetch, \"PATCH\"),\n delete: createMethod($fetch, \"DELETE\"),\n};\n\n/**\n * Creates a custom fetch instance with pre-configured defaults.\n *\n * Use this factory to create API clients with a base URL, default headers,\n * and other shared configuration. Each instance is independent.\n *\n * The returned `$fetch` and `api` methods have the same throw behavior as the\n * top-level {@link $fetch} export.\n *\n * @example\n * import { z } from \"zod\";\n * import { createFetch } from \"@zap-studio/fetch\";\n *\n * // Create a configured instance\n * const { $fetch, api } = createFetch({\n * baseURL: \"https://api.example.com\",\n * headers: { \"Authorization\": \"Bearer token\" },\n * });\n *\n * const UserSchema = z.object({ id: z.number(), name: z.string() });\n *\n * // Now use relative paths - baseURL is prepended automatically\n * const user = await api.get(\"/users/1\", UserSchema);\n *\n * // Or use $fetch directly\n * const response = await $fetch(\"/users\", UserSchema, { method: \"POST\", json: { name: \"John\" } });\n */\nexport function createFetch(factoryOptions: Partial<FetchDefaults> = {}): {\n $fetch: $Fetch;\n api: ApiMethods;\n} {\n const defaults: FetchDefaults = {\n baseURL: factoryOptions.baseURL ?? \"\",\n headers: factoryOptions.headers,\n searchParams: factoryOptions.searchParams,\n throwOnFetchError: factoryOptions.throwOnFetchError ?? true,\n throwOnValidationError: factoryOptions.throwOnValidationError ?? true,\n };\n\n async function customFetch<TSchema extends StandardSchemaV1>(\n input: FetchInput,\n schema: TSchema,\n options: ExtendedRequestInit & { throwOnValidationError: false },\n ): Promise<StandardSchemaV1.Result<StandardSchemaV1.InferOutput<TSchema>>>;\n\n async function customFetch<TSchema extends StandardSchemaV1>(\n input: FetchInput,\n schema: TSchema,\n options?: ExtendedRequestInit & {\n throwOnValidationError?: true | undefined;\n },\n ): Promise<StandardSchemaV1.InferOutput<TSchema>>;\n\n async function customFetch(input: FetchInput, options?: ExtendedRequestInit): Promise<Response>;\n\n async function customFetch(\n input: FetchInput,\n schemaOrOptions?: StandardSchemaV1 | ExtendedRequestInit,\n optionsOrUndefined?: ExtendedRequestInit,\n ): Promise<unknown> {\n const [schema, options] = isStandardSchema(schemaOrOptions)\n ? [schemaOrOptions, optionsOrUndefined]\n : [undefined, schemaOrOptions];\n\n return await fetchInternal(input, schema, options, defaults);\n }\n\n const customApi = {\n get: createMethod(customFetch, \"GET\"),\n post: createMethod(customFetch, \"POST\"),\n put: createMethod(customFetch, \"PUT\"),\n patch: createMethod(customFetch, \"PATCH\"),\n delete: createMethod(customFetch, \"DELETE\"),\n };\n\n return {\n $fetch: customFetch,\n api: customApi,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;AAoFA,eAAsB,OACpB,OACA,iBACA,oBACkB;CAClB,MAAM,CAAC,QAAQ,WAAW,iBAAiB,gBAAgB,GACvD,CAAC,iBAAiB,mBAAmB,GACrC,CAAC,KAAA,GAAW,gBAAgB;AAEhC,QAAO,MAAM,cAAc,OAAO,QAAQ,SAAS,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;AA0BrE,MAAa,MAAkB;CAC7B,KAAK,aAAa,QAAQ,MAAM;CAChC,MAAM,aAAa,QAAQ,OAAO;CAClC,KAAK,aAAa,QAAQ,MAAM;CAChC,OAAO,aAAa,QAAQ,QAAQ;CACpC,QAAQ,aAAa,QAAQ,SAAS;CACvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BD,SAAgB,YAAY,iBAAyC,EAAE,EAGrE;CACA,MAAM,WAA0B;EAC9B,SAAS,eAAe,WAAW;EACnC,SAAS,eAAe;EACxB,cAAc,eAAe;EAC7B,mBAAmB,eAAe,qBAAqB;EACvD,wBAAwB,eAAe,0BAA0B;EAClE;CAkBD,eAAe,YACb,OACA,iBACA,oBACkB;EAClB,MAAM,CAAC,QAAQ,WAAW,iBAAiB,gBAAgB,GACvD,CAAC,iBAAiB,mBAAmB,GACrC,CAAC,KAAA,GAAW,gBAAgB;AAEhC,SAAO,MAAM,cAAc,OAAO,QAAQ,SAAS,SAAS;;AAW9D,QAAO;EACL,QAAQ;EACR,KAVgB;GAChB,KAAK,aAAa,aAAa,MAAM;GACrC,MAAM,aAAa,aAAa,OAAO;GACvC,KAAK,aAAa,aAAa,MAAM;GACrC,OAAO,aAAa,aAAa,QAAQ;GACzC,QAAQ,aAAa,aAAa,SAAS;GAC5C;EAKA"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * Public entrypoint for the fetch package.\n *\n * Exposes:\n * - `$fetch` low-level typed fetch function\n * - `api` method shortcuts\n * - `createFetch` instance factory\n *\n * @module\n */\n\nimport { isStandardSchema, type StandardSchemaV1 } from \"@zap-studio/validation\";\n\nimport { GLOBAL_DEFAULTS } from \"./constants.js\";\nimport { fetchInternal } from \"./internal.js\";\nimport { createMethod } from \"./methods.js\";\nimport type {\n $Fetch,\n ApiMethods,\n ExtendedRequestInit,\n FetchDefaults,\n FetchInput,\n} from \"./types.js\";\n\n/**\n * Type-safe fetch wrapper with Standard Schema validation.\n *\n * - When `throwOnValidationError: true`: validated data of type `TSchema`\n * - When `throwOnValidationError: false`: Standard Schema Result object `{ value?, issues? }`\n * - When `throwOnFetchError: true`: throws `FetchError` on non-ok responses\n *\n * If no schema is provided, returns the raw `Response` object.\n *\n * @throws {FetchError} When `throwOnFetchError` is `true` and the response is not ok.\n * @throws {ValidationError} When a schema is provided, validation returns issues, and\n * `throwOnValidationError` is `true`.\n * @throws {TypeError} When both `body` and `json` are provided, when JSON request\n * serialization fails, when request construction fails, when headers/search params are\n * invalid, when `response.json()` cannot read the body, or when the runtime `fetch`\n * implementation rejects network-level failures as `TypeError`.\n * @throws {DOMException} When the runtime rejects an aborted request or response body read\n * as an `AbortError` DOMException.\n * @throws {SyntaxError} When a schema is provided and `response.json()` cannot parse the\n * response body.\n * @throws Any error thrown or rejected by the provided Standard Schema validator.\n *\n * @example\n * import { z } from \"zod\";\n * import { $fetch } from \"@zap-studio/fetch\";\n *\n * const UserSchema = z.object({ id: z.number(), name: z.string() });\n *\n * // Basic usage (schema validation)\n * const user = await $fetch(\"/api/users/1\", UserSchema, { headers: { \"Authorization\": \"Bearer token\" } });\n * console.log(\"Validated user:\", user);\n *\n * // Raw usage (no schema validation and typed Response object)\n * const result = await $fetch(\"/api/data\", { method: \"POST\", body: JSON.stringify({ key: \"value\" }) });\n * const json = await result.json() as ResultType;\n * console.log(\"Raw response data:\", json);\n *\n * // Usage with validation errors returned instead of thrown\n * const result = await $fetch(\"/api/users/1\", UserSchema, { throwOnValidationError: false });\n *\n * if (result.issues) {\n * console.error(\"Validation errors:\", result.issues);\n * } else {\n * console.log(\"Validated user:\", result.value);\n * }\n */\nexport async function $fetch<TSchema extends StandardSchemaV1>(\n input: FetchInput,\n schema: TSchema,\n options: ExtendedRequestInit & { throwOnValidationError: false },\n): Promise<StandardSchemaV1.Result<StandardSchemaV1.InferOutput<TSchema>>>;\n\nexport async function $fetch<TSchema extends StandardSchemaV1>(\n input: FetchInput,\n schema: TSchema,\n options?: ExtendedRequestInit & { throwOnValidationError?: true },\n): Promise<StandardSchemaV1.InferOutput<TSchema>>;\n\nexport async function $fetch(input: FetchInput, options?: ExtendedRequestInit): Promise<Response>;\n\nexport async function $fetch(\n input: FetchInput,\n schemaOrOptions?: StandardSchemaV1 | ExtendedRequestInit,\n optionsOrUndefined?: ExtendedRequestInit,\n): Promise<unknown> {\n const [schema, options] = isStandardSchema(schemaOrOptions)\n ? [schemaOrOptions, optionsOrUndefined]\n : [undefined, schemaOrOptions];\n\n return await fetchInternal(input, schema, options, GLOBAL_DEFAULTS);\n}\n\n/**\n * Convenience methods for common HTTP verbs.\n *\n * These methods always require a schema for validation.\n * For raw responses without validation, use `$fetch` directly.\n *\n * Each method has the same throw behavior as {@link $fetch}.\n *\n * @example\n * import { z } from \"zod\";\n * import { api } from \"@zap-studio/fetch\";\n *\n * const PostSchema = z.object({\n * id: z.number(),\n * title: z.string(),\n * content: z.string(),\n * });\n *\n * async function fetchPost(postId: number) {\n * const post = await api.get(`https://api.example.com/posts/${postId}`, PostSchema);\n * return post; // post is typed as { id: number; title: string; content: string; }\n * }\n */\nexport const api: ApiMethods = {\n get: createMethod($fetch, \"GET\"),\n post: createMethod($fetch, \"POST\"),\n put: createMethod($fetch, \"PUT\"),\n patch: createMethod($fetch, \"PATCH\"),\n delete: createMethod($fetch, \"DELETE\"),\n};\n\n/**\n * Creates a custom fetch instance with pre-configured defaults.\n *\n * Use this factory to create API clients with a base URL, default headers,\n * and other shared configuration. Each instance is independent.\n *\n * The returned `$fetch` and `api` methods have the same throw behavior as the\n * top-level {@link $fetch} export.\n *\n * @example\n * import { z } from \"zod\";\n * import { createFetch } from \"@zap-studio/fetch\";\n *\n * // Create a configured instance\n * const { $fetch, api } = createFetch({\n * baseURL: \"https://api.example.com\",\n * headers: { \"Authorization\": \"Bearer token\" },\n * });\n *\n * const UserSchema = z.object({ id: z.number(), name: z.string() });\n *\n * // Now use relative paths - baseURL is prepended automatically\n * const user = await api.get(\"/users/1\", UserSchema);\n *\n * // Or use $fetch directly\n * const response = await $fetch(\"/users\", UserSchema, { method: \"POST\", json: { name: \"John\" } });\n */\nexport function createFetch(factoryOptions: Partial<FetchDefaults> = {}): {\n $fetch: $Fetch;\n api: ApiMethods;\n} {\n const defaults: FetchDefaults = {\n baseURL: factoryOptions.baseURL ?? \"\",\n throwOnFetchError: factoryOptions.throwOnFetchError ?? true,\n throwOnValidationError: factoryOptions.throwOnValidationError ?? true,\n };\n\n if (factoryOptions.headers !== undefined) {\n defaults.headers = factoryOptions.headers;\n }\n\n if (factoryOptions.searchParams !== undefined) {\n defaults.searchParams = factoryOptions.searchParams;\n }\n\n async function customFetch<TSchema extends StandardSchemaV1>(\n input: FetchInput,\n schema: TSchema,\n options: ExtendedRequestInit & { throwOnValidationError: false },\n ): Promise<StandardSchemaV1.Result<StandardSchemaV1.InferOutput<TSchema>>>;\n\n async function customFetch<TSchema extends StandardSchemaV1>(\n input: FetchInput,\n schema: TSchema,\n options?: ExtendedRequestInit & {\n throwOnValidationError?: true;\n },\n ): Promise<StandardSchemaV1.InferOutput<TSchema>>;\n\n async function customFetch(input: FetchInput, options?: ExtendedRequestInit): Promise<Response>;\n\n async function customFetch(\n input: FetchInput,\n schemaOrOptions?: StandardSchemaV1 | ExtendedRequestInit,\n optionsOrUndefined?: ExtendedRequestInit,\n ): Promise<unknown> {\n const [schema, options] = isStandardSchema(schemaOrOptions)\n ? [schemaOrOptions, optionsOrUndefined]\n : [undefined, schemaOrOptions];\n\n return await fetchInternal(input, schema, options, defaults);\n }\n\n const customApi = {\n get: createMethod(customFetch, \"GET\"),\n post: createMethod(customFetch, \"POST\"),\n put: createMethod(customFetch, \"PUT\"),\n patch: createMethod(customFetch, \"PATCH\"),\n delete: createMethod(customFetch, \"DELETE\"),\n };\n\n return {\n $fetch: customFetch,\n api: customApi,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;AAoFA,eAAsB,OACpB,OACA,iBACA,oBACkB;CAClB,MAAM,CAAC,QAAQ,WAAW,iBAAiB,gBAAgB,GACvD,CAAC,iBAAiB,mBAAmB,GACrC,CAAC,KAAA,GAAW,gBAAgB;AAEhC,QAAO,MAAM,cAAc,OAAO,QAAQ,SAAS,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;AA0BrE,MAAa,MAAkB;CAC7B,KAAK,aAAa,QAAQ,MAAM;CAChC,MAAM,aAAa,QAAQ,OAAO;CAClC,KAAK,aAAa,QAAQ,MAAM;CAChC,OAAO,aAAa,QAAQ,QAAQ;CACpC,QAAQ,aAAa,QAAQ,SAAS;CACvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BD,SAAgB,YAAY,iBAAyC,EAAE,EAGrE;CACA,MAAM,WAA0B;EAC9B,SAAS,eAAe,WAAW;EACnC,mBAAmB,eAAe,qBAAqB;EACvD,wBAAwB,eAAe,0BAA0B;EAClE;AAED,KAAI,eAAe,YAAY,KAAA,EAC7B,UAAS,UAAU,eAAe;AAGpC,KAAI,eAAe,iBAAiB,KAAA,EAClC,UAAS,eAAe,eAAe;CAmBzC,eAAe,YACb,OACA,iBACA,oBACkB;EAClB,MAAM,CAAC,QAAQ,WAAW,iBAAiB,gBAAgB,GACvD,CAAC,iBAAiB,mBAAmB,GACrC,CAAC,KAAA,GAAW,gBAAgB;AAEhC,SAAO,MAAM,cAAc,OAAO,QAAQ,SAAS,SAAS;;AAW9D,QAAO;EACL,QAAQ;EACR,KAVgB;GAChB,KAAK,aAAa,aAAa,MAAM;GACrC,MAAM,aAAa,aAAa,OAAO;GACvC,KAAK,aAAa,aAAa,MAAM;GACrC,OAAO,aAAa,aAAa,QAAQ;GACzC,QAAQ,aAAa,aAAa,SAAS;GAC5C;EAKA"}
package/dist/methods.mjs CHANGED
@@ -34,10 +34,15 @@ function createMethod(fetchFn, method) {
34
34
  method,
35
35
  throwOnValidationError: false
36
36
  });
37
- return fetchFn(input, schemaOrOptions, {
38
- ...optionsOrUndefined,
37
+ const { throwOnValidationError, ...restOptions } = optionsOrUndefined ?? {};
38
+ if (throwOnValidationError === true) return fetchFn(input, schemaOrOptions, {
39
+ ...restOptions,
39
40
  method,
40
- throwOnValidationError: optionsOrUndefined?.throwOnValidationError
41
+ throwOnValidationError: true
42
+ });
43
+ return fetchFn(input, schemaOrOptions, {
44
+ ...restOptions,
45
+ method
41
46
  });
42
47
  }
43
48
  return fetchFn(input, {
@@ -1 +1 @@
1
- {"version":3,"file":"methods.mjs","names":[],"sources":["../src/methods.ts"],"sourcesContent":["/**\n * Method helper factories used to build verb-specific fetch functions.\n *\n * @module\n */\n\nimport { isStandardSchema, type StandardSchemaV1 } from \"@zap-studio/validation\";\n\nimport type { $Fetch, ExtendedRequestInit, FetchInput } from \"./types.js\";\n\n/**\n * Creates an HTTP method helper bound to a fetch function.\n *\n * The returned function mirrors `$Fetch` overloads but forces the provided\n * HTTP method (`GET`, `POST`, etc.) into request options.\n *\n * @param fetchFn - Fetch function to wrap.\n * @param method - HTTP method to enforce.\n * @returns Method-bound fetch function.\n * @throws Any error thrown or rejected by `fetchFn` when the returned method-bound\n * fetch function is called.\n *\n * @example\n * const get = createMethod($fetch, \"GET\");\n * const user = await get(\"/users/1\", UserSchema);\n */\nexport function createMethod<TFetch extends $Fetch>(fetchFn: TFetch, method: string): $Fetch {\n function methodFetch<TSchema extends StandardSchemaV1>(\n input: FetchInput,\n schema: TSchema,\n options: ExtendedRequestInit & {\n throwOnValidationError: false;\n },\n ): Promise<StandardSchemaV1.Result<StandardSchemaV1.InferOutput<TSchema>>>;\n\n function methodFetch<TSchema extends StandardSchemaV1>(\n input: FetchInput,\n schema: TSchema,\n options?: ExtendedRequestInit & {\n throwOnValidationError?: true | undefined;\n },\n ): Promise<StandardSchemaV1.InferOutput<TSchema>>;\n\n function methodFetch(input: FetchInput, options?: ExtendedRequestInit): Promise<Response>;\n\n /**\n * Method-bound `$Fetch` implementation.\n *\n * Resolves schema/option overloads and injects the configured HTTP method.\n */\n function methodFetch(\n input: FetchInput,\n schemaOrOptions?: StandardSchemaV1 | ExtendedRequestInit,\n optionsOrUndefined?: ExtendedRequestInit,\n ): Promise<unknown> {\n if (isStandardSchema(schemaOrOptions)) {\n if (optionsOrUndefined?.throwOnValidationError === false) {\n return fetchFn(input, schemaOrOptions, {\n ...optionsOrUndefined,\n method,\n throwOnValidationError: false,\n });\n }\n\n return fetchFn(input, schemaOrOptions, {\n ...optionsOrUndefined,\n method,\n throwOnValidationError: optionsOrUndefined?.throwOnValidationError,\n });\n }\n\n return fetchFn(input, {\n ...schemaOrOptions,\n method,\n });\n }\n\n return methodFetch;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA0BA,SAAgB,aAAoC,SAAiB,QAAwB;;;;;;CAwB3F,SAAS,YACP,OACA,iBACA,oBACkB;AAClB,MAAI,iBAAiB,gBAAgB,EAAE;AACrC,OAAI,oBAAoB,2BAA2B,MACjD,QAAO,QAAQ,OAAO,iBAAiB;IACrC,GAAG;IACH;IACA,wBAAwB;IACzB,CAAC;AAGJ,UAAO,QAAQ,OAAO,iBAAiB;IACrC,GAAG;IACH;IACA,wBAAwB,oBAAoB;IAC7C,CAAC;;AAGJ,SAAO,QAAQ,OAAO;GACpB,GAAG;GACH;GACD,CAAC;;AAGJ,QAAO"}
1
+ {"version":3,"file":"methods.mjs","names":[],"sources":["../src/methods.ts"],"sourcesContent":["/**\n * Method helper factories used to build verb-specific fetch functions.\n *\n * @module\n */\n\nimport { isStandardSchema, type StandardSchemaV1 } from \"@zap-studio/validation\";\n\nimport type { $Fetch, ExtendedRequestInit, FetchInput } from \"./types.js\";\n\n/**\n * Creates an HTTP method helper bound to a fetch function.\n *\n * The returned function mirrors `$Fetch` overloads but forces the provided\n * HTTP method (`GET`, `POST`, etc.) into request options.\n *\n * @param fetchFn - Fetch function to wrap.\n * @param method - HTTP method to enforce.\n * @returns Method-bound fetch function.\n * @throws Any error thrown or rejected by `fetchFn` when the returned method-bound\n * fetch function is called.\n *\n * @example\n * const get = createMethod($fetch, \"GET\");\n * const user = await get(\"/users/1\", UserSchema);\n */\nexport function createMethod<TFetch extends $Fetch>(fetchFn: TFetch, method: string): $Fetch {\n function methodFetch<TSchema extends StandardSchemaV1>(\n input: FetchInput,\n schema: TSchema,\n options: ExtendedRequestInit & {\n throwOnValidationError: false;\n },\n ): Promise<StandardSchemaV1.Result<StandardSchemaV1.InferOutput<TSchema>>>;\n\n function methodFetch<TSchema extends StandardSchemaV1>(\n input: FetchInput,\n schema: TSchema,\n options?: ExtendedRequestInit & {\n throwOnValidationError?: true;\n },\n ): Promise<StandardSchemaV1.InferOutput<TSchema>>;\n\n function methodFetch(input: FetchInput, options?: ExtendedRequestInit): Promise<Response>;\n\n /**\n * Method-bound `$Fetch` implementation.\n *\n * Resolves schema/option overloads and injects the configured HTTP method.\n */\n function methodFetch(\n input: FetchInput,\n schemaOrOptions?: StandardSchemaV1 | ExtendedRequestInit,\n optionsOrUndefined?: ExtendedRequestInit,\n ): Promise<unknown> {\n if (isStandardSchema(schemaOrOptions)) {\n if (optionsOrUndefined?.throwOnValidationError === false) {\n return fetchFn(input, schemaOrOptions, {\n ...optionsOrUndefined,\n method,\n throwOnValidationError: false,\n });\n }\n\n const { throwOnValidationError, ...restOptions } = optionsOrUndefined ?? {};\n\n if (throwOnValidationError === true) {\n return fetchFn(input, schemaOrOptions, {\n ...restOptions,\n method,\n throwOnValidationError: true,\n });\n }\n\n return fetchFn(input, schemaOrOptions, {\n ...restOptions,\n method,\n });\n }\n\n return fetchFn(input, {\n ...schemaOrOptions,\n method,\n });\n }\n\n return methodFetch;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA0BA,SAAgB,aAAoC,SAAiB,QAAwB;;;;;;CAwB3F,SAAS,YACP,OACA,iBACA,oBACkB;AAClB,MAAI,iBAAiB,gBAAgB,EAAE;AACrC,OAAI,oBAAoB,2BAA2B,MACjD,QAAO,QAAQ,OAAO,iBAAiB;IACrC,GAAG;IACH;IACA,wBAAwB;IACzB,CAAC;GAGJ,MAAM,EAAE,wBAAwB,GAAG,gBAAgB,sBAAsB,EAAE;AAE3E,OAAI,2BAA2B,KAC7B,QAAO,QAAQ,OAAO,iBAAiB;IACrC,GAAG;IACH;IACA,wBAAwB;IACzB,CAAC;AAGJ,UAAO,QAAQ,OAAO,iBAAiB;IACrC,GAAG;IACH;IACD,CAAC;;AAGJ,SAAO,QAAQ,OAAO;GACpB,GAAG;GACH;GACD,CAAC;;AAGJ,QAAO"}
package/dist/types.d.mts CHANGED
@@ -19,17 +19,17 @@ type CustomRequestInit = {
19
19
  * Per-request query/search params
20
20
  * @default undefined
21
21
  */
22
- searchParams?: URLSearchParamsInput | undefined;
22
+ searchParams?: URLSearchParamsInput;
23
23
  /**
24
24
  * Whether to throw a FetchError on HTTP errors (non-2xx responses)
25
25
  * @default true
26
26
  */
27
- throwOnFetchError?: boolean | undefined;
27
+ throwOnFetchError?: boolean;
28
28
  /**
29
29
  * Whether to throw a ValidationError on validation errors
30
30
  * @default true
31
31
  */
32
- throwOnValidationError?: boolean | undefined;
32
+ throwOnValidationError?: boolean;
33
33
  };
34
34
  /**
35
35
  * Extended RequestInit type to include custom fetch options
@@ -62,12 +62,12 @@ interface FetchDefaults {
62
62
  * Default headers to include in all requests (can be overridden per request)
63
63
  * @default undefined
64
64
  */
65
- headers?: HeadersInit | undefined;
65
+ headers?: HeadersInit;
66
66
  /**
67
67
  * Default query/search params applied to every request (can be overridden per request)
68
68
  * @default undefined
69
69
  */
70
- searchParams?: URLSearchParamsInput | undefined;
70
+ searchParams?: URLSearchParamsInput;
71
71
  /**
72
72
  * Whether to throw a `FetchError` on HTTP errors (non-2xx responses)
73
73
  * @default true
@@ -118,7 +118,7 @@ interface $Fetch {
118
118
  * @throws Any error thrown or rejected by the provided Standard Schema validator.
119
119
  */
120
120
  <TSchema extends StandardSchemaV1>(input: FetchInput, schema: TSchema, options?: ExtendedRequestInit & {
121
- throwOnValidationError?: true | undefined;
121
+ throwOnValidationError?: true;
122
122
  }): Promise<StandardSchemaV1.InferOutput<TSchema>>;
123
123
  /**
124
124
  * Fetch without schema validation
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zap-studio/fetch",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "private": false,
5
5
  "description": "A type-safe fetch wrapper for HTTP requests with runtime schema validation.",
6
6
  "keywords": [
@@ -52,7 +52,7 @@
52
52
  "access": "public"
53
53
  },
54
54
  "dependencies": {
55
- "@zap-studio/validation": "0.3.2"
55
+ "@zap-studio/validation": "0.3.3"
56
56
  },
57
57
  "devDependencies": {
58
58
  "arktype": "^2.2.0",