prapti 0.0.3 → 0.0.4

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ![prapti](media/logo.png)
2
2
 
3
- # Prapti 🚀
3
+ # Prapti
4
4
 
5
5
  _"प्राप्ति" (Prapti) - Sanskrit for "fetch" or "obtain"_
6
6
 
@@ -18,29 +18,23 @@ const data = await response.json(); // any type
18
18
  const validatedData = UserSchema.parse(data); // manual validation
19
19
 
20
20
  // With Prapti
21
- const { fetch: safeFetch } = createPrapti(adapters.zod);
22
- const response = await safeFetch("/api/users", {
23
- responseSchema: UserSchema,
21
+ const { fetch } = prapti(zodAdapter);
22
+ const response = await fetch("/api/users", {
23
+ validate: { response: { body: UserSchema } },
24
24
  });
25
25
  const data = await response.json(); // fully typed + validated
26
26
  ```
27
27
 
28
- ## Why switch from `fetch`?
28
+ <details>
29
+ <summary>Why switch from <code>fetch</code>?</summary>
29
30
 
30
- **🎯 Stop writing `any` types**
31
- Get automatic TypeScript inference from your schemas. No more manual type assertions.
31
+ - **Stop writing `any` types** — automatic TypeScript inference from your schemas, no manual type assertions.
32
+ - **Catch API breaks at runtime** — validate responses against your schema and know immediately when APIs change.
33
+ - **Eliminate validation boilerplate** — no more `schema.parse(await response.json())` on every call.
34
+ - **Drop-in replacement** — same API as `fetch()` with optional validation. Add it only where you need it.
35
+ - **Use any validation library** — bring your own: Zod, Valibot, Yup, or a custom adapter.
32
36
 
33
- **🛡️ Catch API breaks at runtime**
34
- Validate responses against your schema. Know immediately when APIs change unexpectedly.
35
-
36
- **🔧 Eliminate validation boilerplate**
37
- No more `schema.parse(await response.json())` on every API call. It's built-in.
38
-
39
- **⚡ Drop-in replacement**
40
- Same API as `fetch()` with optional superpowers. Add validation only where you need it.
41
-
42
- **🎨 Use any validation library**
43
- Bring your own: Zod, Valibot, Yup, Joi, or build custom adapters.
37
+ </details>
44
38
 
45
39
  ## Install
46
40
 
@@ -51,7 +45,8 @@ npm install prapti zod
51
45
  ## Usage
52
46
 
53
47
  ```typescript
54
- import { createPrapti, adapters } from "prapti";
48
+ import { prapti } from "prapti";
49
+ import { zodAdapter } from "prapti/adapters/zod";
55
50
  import { z } from "zod";
56
51
 
57
52
  const UserSchema = z.object({
@@ -60,26 +55,31 @@ const UserSchema = z.object({
60
55
  email: z.string().email(),
61
56
  });
62
57
 
63
- // Create client with Zod adapter
64
- const { fetch: safeFetch } = createPrapti(adapters.zod);
58
+ const { fetch } = prapti(zodAdapter);
65
59
 
66
60
  // GET with response validation
67
- const response = await safeFetch("/api/users/1", {
68
- responseSchema: UserSchema,
61
+ const response = await fetch("/api/users/1", {
62
+ validate: { response: { body: UserSchema } },
69
63
  });
70
- const user = await response.json(); // Type: { id: number, name: string, email: string }
64
+ const user = await response.json(); // Type: { id: number; name: string; email: string }
71
65
 
72
66
  // POST with request + response validation
73
67
  const CreateUserSchema = UserSchema.omit({ id: true });
74
68
 
75
- const newUser = await safeFetch("/api/users", {
69
+ const newUser = await fetch("/api/users", {
76
70
  method: "POST",
77
71
  body: { name: "John", email: "john@example.com" },
78
- requestSchema: CreateUserSchema,
79
- responseSchema: UserSchema,
72
+ validate: {
73
+ request: { body: CreateUserSchema },
74
+ response: { body: UserSchema },
75
+ },
80
76
  });
77
+ ```
78
+
79
+ <details>
80
+ <summary>Header validation</summary>
81
81
 
82
- // With header validation
82
+ ```typescript
83
83
  const RequestHeadersSchema = z.object({
84
84
  authorization: z.string().startsWith("Bearer "),
85
85
  "content-type": z.literal("application/json"),
@@ -90,86 +90,115 @@ const ResponseHeadersSchema = z.object({
90
90
  "x-rate-limit-remaining": z.string().transform(Number).pipe(z.number()),
91
91
  });
92
92
 
93
- const response = await safeFetch("/api/users", {
93
+ const response = await fetch("/api/users", {
94
94
  headers: {
95
95
  Authorization: "Bearer token123",
96
96
  "Content-Type": "application/json",
97
97
  },
98
- requestHeadersSchema: RequestHeadersSchema,
99
- responseHeadersSchema: ResponseHeadersSchema,
98
+ validate: {
99
+ request: { headers: RequestHeadersSchema },
100
+ response: { headers: ResponseHeadersSchema },
101
+ },
100
102
  });
101
103
 
102
104
  // Get typed and validated headers
103
- const headers = response.getValidatedHeaders();
105
+ const headers = response.validatedHeaders;
104
106
  console.log(`Rate limit remaining: ${headers["x-rate-limit-remaining"]}`);
105
107
  ```
106
108
 
107
- ## API
108
-
109
- ### `Prapti(adapter)`
109
+ </details>
110
110
 
111
- Main client class. Pass a validation adapter for your schema library.
111
+ ## Adapters
112
112
 
113
- **Available adapters:**
113
+ Import only the adapter you use — unused adapters are not included in your bundle.
114
114
 
115
- - `adapters.zod` - for Zod schemas
115
+ ```typescript
116
+ import { zodAdapter } from "prapti/adapters/zod"; // Zod
117
+ import { yupAdapter } from "prapti/adapters/yup"; // Yup
118
+ import { valibotAdapter } from "prapti/adapters/valibot"; // Valibot
119
+ ```
116
120
 
117
- **Methods:**
121
+ <details>
122
+ <summary>Custom adapter</summary>
118
123
 
119
- - `fetch(url, options)` - Enhanced fetch with validation
124
+ Implement the `ValidationAdapter` interface to use any validation library:
120
125
 
121
- ### `PraptiOptions`
126
+ ```typescript
127
+ import type { ValidationAdapter } from "prapti";
122
128
 
123
- Extended fetch options with validation schemas:
129
+ const customAdapter: ValidationAdapter<MySchema> = {
130
+ parse: (schema, data) => schema.validate(data),
131
+ };
124
132
 
125
- - `requestSchema` - Schema to validate request body
126
- - `responseSchema` - Schema to validate response data
127
- - `requestHeadersSchema` - Schema to validate request headers
128
- - `responseHeadersSchema` - Schema to validate response headers
133
+ const { fetch } = prapti(customAdapter);
134
+ ```
129
135
 
130
- ### `ValidatedResponse`
136
+ </details>
131
137
 
132
- Enhanced Response with validation:
138
+ ## API
133
139
 
134
- - `json()` - Parse and validate JSON
135
- - `text()` - Parse and validate text
136
- - `blob()` - Get blob (no validation)
137
- - `arrayBuffer()` - Get buffer (no validation)
138
- - `formData()` - Parse and validate form data
139
- - `getValidatedHeaders()` - Get validated headers as typed object
140
+ <details>
141
+ <summary><code>prapti(adapter)</code></summary>
140
142
 
141
- ## Custom Adapters
143
+ Factory function. Pass a validation adapter and get back an enhanced `fetch`.
142
144
 
143
145
  ```typescript
144
- const customAdapter = {
145
- parse: <T>(schema: MySchema, data: unknown): T => {
146
- return schema.validate(data);
147
- },
148
- };
146
+ const { fetch } = prapti(zodAdapter);
147
+ ```
148
+
149
+ </details>
149
150
 
150
- const { fetch: safeFetch } = createPrapti(customAdapter);
151
+ <details>
152
+ <summary><code>PraptiOptions</code></summary>
153
+
154
+ All native `RequestInit` options plus a single `validate` block:
155
+
156
+ ```typescript
157
+ validate?: {
158
+ request?: { body?: Schema; headers?: Schema };
159
+ response?: { body?: Schema; headers?: Schema };
160
+ }
151
161
  ```
152
162
 
163
+ | Key | Description |
164
+ | --------------------------- | -------------------------------------- |
165
+ | `validate.request.body` | Validate the outgoing request body |
166
+ | `validate.request.headers` | Validate the outgoing request headers |
167
+ | `validate.response.body` | Validate the incoming response body |
168
+ | `validate.response.headers` | Validate the incoming response headers |
169
+
170
+ </details>
171
+
172
+ <details>
173
+ <summary><code>ValidatedResponse</code></summary>
174
+
175
+ Extends the native `Response` with validation support.
176
+
177
+ | Method / Property | Description |
178
+ | ------------------ | -------------------------------------------- |
179
+ | `json()` | Parse and validate JSON response body |
180
+ | `text()` | Parse text (no validation) |
181
+ | `blob()` | Get blob (no validation) |
182
+ | `arrayBuffer()` | Get buffer (no validation) |
183
+ | `formData()` | Parse and validate form data |
184
+ | `validatedHeaders` | Validated response headers as a typed object |
185
+
186
+ </details>
187
+
153
188
  ## Error Handling
154
189
 
155
190
  ```typescript
156
191
  try {
157
- const response = await safeFetch("/api/users", {
158
- responseSchema: UserSchema,
192
+ const response = await fetch("/api/users", {
193
+ validate: { response: { body: UserSchema } },
159
194
  });
160
195
  const users = await response.json();
161
196
  } catch (error) {
162
- // Validation errors from your schema library
197
+ // Validation errors thrown by your schema library
163
198
  // Network errors from fetch
164
199
  }
165
200
  ```
166
201
 
167
- ## Upcoming Features
168
-
169
- - 🔄 **Built-in adapters for Valibot, Yup, Joi, AJV**
170
- - 🎨 **Custom adapter utilities and helpers**
171
- - 🔄 **Streaming response validation**
172
-
173
202
  ## License
174
203
 
175
204
  Released under [MIT](/LICENSE) by [@kiranojhanp](https://github.com/kiranojhanp).
@@ -177,5 +206,5 @@ Released under [MIT](/LICENSE) by [@kiranojhanp](https://github.com/kiranojhanp)
177
206
  ---
178
207
 
179
208
  <div align="center">
180
- Made with ❤️ from 🇳🇵
209
+ Made with love from 🇳🇵
181
210
  </div>
@@ -0,0 +1 @@
1
+ var{defineProperty:C,getOwnPropertyNames:F,getOwnPropertyDescriptor:G}=Object,H=Object.prototype.hasOwnProperty;var D=new WeakMap,J=(x)=>{var q=D.get(x),z;if(q)return q;if(q=C({},"__esModule",{value:!0}),x&&typeof x==="object"||typeof x==="function")F(x).map((B)=>!H.call(q,B)&&C(q,B,{get:()=>x[B],enumerable:!(z=G(x,B))||z.enumerable}));return D.set(x,q),q};var K=(x,q)=>{for(var z in q)C(x,z,{get:q[z],enumerable:!0,configurable:!0,set:(B)=>q[z]=()=>B})};var M={};K(M,{valibotAdapter:()=>L});module.exports=J(M);var L={parse:(x,q)=>{let z=x["~standard"].validate(q);if(z instanceof Promise)throw new Error("Valibot async schemas are not supported. Use synchronous schemas (v.string(), v.object(), etc.) without async actions.");if("issues"in z){let B=Array.from(z.issues).map((E)=>E?.message??"Unknown issue").join("; ");throw new Error(`Valibot validation failed: ${B}`)}return z.value}};
@@ -0,0 +1,43 @@
1
+ // Generated by dts-bundle-generator v9.5.1
2
+
3
+ /**
4
+ * Validation adapter interface for different schema libraries
5
+ * Supports Zod, Valibot, Yup, Joi, and other validation libraries
6
+ */
7
+ export interface ValidationAdapter<TSchema = unknown> {
8
+ /**
9
+ * Parse and validate data against the provided schema.
10
+ * Returns `unknown`; callers derive the output type via `InferOutput<TSchema>`.
11
+ * @param schema - The validation schema
12
+ * @param data - Data to validate
13
+ * @returns Validated data (untyped — use InferOutput<TSchema> at call sites)
14
+ * @throws Validation error if data doesn't match schema
15
+ */
16
+ parse(schema: TSchema, data: unknown): unknown;
17
+ }
18
+ export type ValibotResult<O> = {
19
+ value: O;
20
+ } | {
21
+ issues: ArrayLike<unknown>;
22
+ };
23
+ export type ValibotSchema<O = unknown> = {
24
+ readonly "~standard": {
25
+ readonly version: 1;
26
+ readonly vendor: "valibot";
27
+ readonly validate: (value: unknown) => ValibotResult<O> | Promise<ValibotResult<O>>;
28
+ readonly types?: {
29
+ readonly input?: unknown;
30
+ readonly output?: O;
31
+ };
32
+ };
33
+ };
34
+ /**
35
+ * Adapter for Valibot (https://valibot.dev).
36
+ * Import directly for tree-shaking: import { valibotAdapter } from "prapti/adapters/valibot"
37
+ *
38
+ * Note: async schemas are not supported. Use synchronous schemas
39
+ * (v.string(), v.object(), etc.) without async actions.
40
+ */
41
+ export declare const valibotAdapter: ValidationAdapter<ValibotSchema>;
42
+
43
+ export {};
@@ -0,0 +1 @@
1
+ var D={parse:(x,z)=>{let q=x["~standard"].validate(z);if(q instanceof Promise)throw new Error("Valibot async schemas are not supported. Use synchronous schemas (v.string(), v.object(), etc.) without async actions.");if("issues"in q){let B=Array.from(q.issues).map((C)=>C?.message??"Unknown issue").join("; ");throw new Error(`Valibot validation failed: ${B}`)}return q.value}};export{D as valibotAdapter};
@@ -0,0 +1 @@
1
+ var{defineProperty:B,getOwnPropertyNames:D,getOwnPropertyDescriptor:E}=Object,F=Object.prototype.hasOwnProperty;var C=new WeakMap,G=(w)=>{var v=C.get(w),x;if(v)return v;if(v=B({},"__esModule",{value:!0}),w&&typeof w==="object"||typeof w==="function")D(w).map((z)=>!F.call(v,z)&&B(v,z,{get:()=>w[z],enumerable:!(x=E(w,z))||x.enumerable}));return C.set(w,v),v};var H=(w,v)=>{for(var x in v)B(w,x,{get:v[x],enumerable:!0,configurable:!0,set:(z)=>v[x]=()=>z})};var K={};H(K,{yupAdapter:()=>J});module.exports=G(K);var J={parse:(w,v)=>w.validateSync(v,{abortEarly:!1})};
@@ -0,0 +1,28 @@
1
+ // Generated by dts-bundle-generator v9.5.1
2
+
3
+ /**
4
+ * Validation adapter interface for different schema libraries
5
+ * Supports Zod, Valibot, Yup, Joi, and other validation libraries
6
+ */
7
+ export interface ValidationAdapter<TSchema = unknown> {
8
+ /**
9
+ * Parse and validate data against the provided schema.
10
+ * Returns `unknown`; callers derive the output type via `InferOutput<TSchema>`.
11
+ * @param schema - The validation schema
12
+ * @param data - Data to validate
13
+ * @returns Validated data (untyped — use InferOutput<TSchema> at call sites)
14
+ * @throws Validation error if data doesn't match schema
15
+ */
16
+ parse(schema: TSchema, data: unknown): unknown;
17
+ }
18
+ export type YupSchema<O = unknown> = {
19
+ validateSync: (data: unknown, options?: object) => O;
20
+ __outputType: O;
21
+ };
22
+ /**
23
+ * Adapter for Yup (https://github.com/jquense/yup).
24
+ * Import directly for tree-shaking: import { yupAdapter } from "prapti/adapters/yup"
25
+ */
26
+ export declare const yupAdapter: ValidationAdapter<YupSchema>;
27
+
28
+ export {};
@@ -0,0 +1 @@
1
+ var x={parse:(v,w)=>v.validateSync(w,{abortEarly:!1})};export{x as yupAdapter};
@@ -0,0 +1 @@
1
+ var{defineProperty:w,getOwnPropertyNames:B,getOwnPropertyDescriptor:C}=Object,D=Object.prototype.hasOwnProperty;var x=new WeakMap,E=(j)=>{var b=x.get(j),q;if(b)return b;if(b=w({},"__esModule",{value:!0}),j&&typeof j==="object"||typeof j==="function")B(j).map((u)=>!D.call(b,u)&&w(b,u,{get:()=>j[u],enumerable:!(q=C(j,u))||q.enumerable}));return x.set(j,b),b};var F=(j,b)=>{for(var q in b)w(j,q,{get:b[q],enumerable:!0,configurable:!0,set:(u)=>b[q]=()=>u})};var H={};F(H,{zodAdapter:()=>G});module.exports=E(H);var G={parse:(j,b)=>j.parse(b)};
@@ -0,0 +1,28 @@
1
+ // Generated by dts-bundle-generator v9.5.1
2
+
3
+ /**
4
+ * Validation adapter interface for different schema libraries
5
+ * Supports Zod, Valibot, Yup, Joi, and other validation libraries
6
+ */
7
+ export interface ValidationAdapter<TSchema = unknown> {
8
+ /**
9
+ * Parse and validate data against the provided schema.
10
+ * Returns `unknown`; callers derive the output type via `InferOutput<TSchema>`.
11
+ * @param schema - The validation schema
12
+ * @param data - Data to validate
13
+ * @returns Validated data (untyped — use InferOutput<TSchema> at call sites)
14
+ * @throws Validation error if data doesn't match schema
15
+ */
16
+ parse(schema: TSchema, data: unknown): unknown;
17
+ }
18
+ export type ZodSchema<O = unknown> = {
19
+ parse: (data: unknown) => O;
20
+ _output: O;
21
+ };
22
+ /**
23
+ * Adapter for Zod (https://zod.dev).
24
+ * Import directly for tree-shaking: import { zodAdapter } from "prapti/adapters/zod"
25
+ */
26
+ export declare const zodAdapter: ValidationAdapter<ZodSchema>;
27
+
28
+ export {};
@@ -0,0 +1 @@
1
+ var q={parse:(b,j)=>b.parse(j)};export{q as zodAdapter};
package/dist/index.cjs.js CHANGED
@@ -1 +1 @@
1
- var{defineProperty:Y,getOwnPropertyNames:x,getOwnPropertyDescriptor:q}=Object,F=Object.prototype.hasOwnProperty;var _=new WeakMap,R=(w)=>{var g=_.get(w),z;if(g)return g;if(g=Y({},"__esModule",{value:!0}),w&&typeof w==="object"||typeof w==="function")x(w).map((A)=>!F.call(g,A)&&Y(g,A,{get:()=>w[A],enumerable:!(z=q(w,A))||z.enumerable}));return _.set(w,g),g};var V=(w,g)=>{for(var z in g)Y(w,z,{get:g[z],enumerable:!0,configurable:!0,set:(A)=>g[z]=()=>A})};var B={};V(B,{createPrapti:()=>O,adapters:()=>S,ValidatedResponse:()=>W,Prapti:()=>Z});module.exports=R(B);class W extends Response{adapter;responseSchema;responseHeadersSchema;constructor(w,g,z,A){super(w.body,w);this.adapter=g;this.responseSchema=z;this.responseHeadersSchema=A;if(Object.setPrototypeOf(this,W.prototype),A)this.validateResponseHeaders()}validateResponseHeaders(){if(!this.responseHeadersSchema)return;let w={};this.headers.forEach((g,z)=>{w[z.toLowerCase()]=g}),this.adapter.parse(this.responseHeadersSchema,w)}getValidatedHeaders(){let w={};return this.headers.forEach((g,z)=>{w[z.toLowerCase()]=g}),this.responseHeadersSchema?this.adapter.parse(this.responseHeadersSchema,w):w}async json(){let w=await super.json();return this.responseSchema?this.adapter.parse(this.responseSchema,w):w}async text(){let w=await super.text();return this.responseSchema?this.adapter.parse(this.responseSchema,w):w}async blob(){return super.blob()}async arrayBuffer(){return super.arrayBuffer()}async formData(){let w=await super.formData();if(this.responseSchema){let g={};w.forEach((A,C)=>{if(g[C]!==void 0)if(Array.isArray(g[C]))g[C].push(A);else g[C]=[g[C],A];else g[C]=A});let z=this.adapter.parse(this.responseSchema,g);if(z&&typeof z==="object"){let A=new FormData;return Object.entries(z).forEach(([C,I])=>{if(Array.isArray(I))I.forEach((G)=>A.append(C,G));else A.append(C,I)}),A}}return w}async urlSearchParams(){let w=await super.text(),g=new URLSearchParams(w);if(this.responseSchema){let z={};g.forEach((C,I)=>{if(z[I]!==void 0)if(Array.isArray(z[I]))z[I].push(C);else z[I]=[z[I],C];else z[I]=C});let A=this.adapter.parse(this.responseSchema,z);if(A&&typeof A==="object"){let C=new URLSearchParams;return Object.entries(A).forEach(([I,G])=>{if(Array.isArray(G))G.forEach((U)=>C.append(I,String(U)));else C.append(I,String(G))}),C}}return g}}class Z{adapter;constructor(w){this.adapter=w}headersToObject(w){if(!w)return{};if(w instanceof Headers){let z={};return w.forEach((A,C)=>{z[C.toLowerCase()]=A}),z}if(Array.isArray(w)){let z={};return w.forEach(([A,C])=>{z[A.toLowerCase()]=String(C)}),z}let g={};return Object.entries(w).forEach(([z,A])=>{g[z.toLowerCase()]=String(A)}),g}formDataToObject(w){let g={};return w.forEach((z,A)=>{if(g[A]!==void 0)if(Array.isArray(g[A]))g[A].push(z);else g[A]=[g[A],z];else g[A]=z}),g}urlSearchParamsToObject(w){let g={};return w.forEach((z,A)=>{if(g[A]!==void 0)if(Array.isArray(g[A]))g[A].push(z);else g[A]=[g[A],z];else g[A]=z}),g}async fetch(w,g){let{requestSchema:z,responseSchema:A,requestHeadersSchema:C,responseHeadersSchema:I,body:G,headers:U,...$}=g||{},Q,T=new Headers;if(U){let K=this.headersToObject(U);if(C){let L=this.adapter.parse(C,K);if(L&&typeof L==="object")Object.entries(L).forEach(([J,M])=>{T.set(J,String(M))})}else Object.entries(K).forEach(([L,J])=>{T.set(L,J)})}if(z&&G!==void 0&&G!==null){let K;if(typeof G==="string")try{K=JSON.parse(G)}catch{K=G}else if(G instanceof FormData)K=this.formDataToObject(G);else if(G instanceof URLSearchParams)K=this.urlSearchParamsToObject(G);else K=G;let L=this.adapter.parse(z,K);if(G instanceof FormData){let J=new FormData;Object.entries(L).forEach(([M,N])=>{if(Array.isArray(N))N.forEach((X)=>J.append(M,X));else J.append(M,N)}),Q=J}else if(G instanceof URLSearchParams){let J=new URLSearchParams;Object.entries(L).forEach(([M,N])=>{if(Array.isArray(N))N.forEach((X)=>J.append(M,String(X)));else J.append(M,String(N))}),Q=J}else if(Q=JSON.stringify(L),!T.has("Content-Type"))T.set("Content-Type","application/json")}else Q=G;let E=await fetch(w,{...$,headers:T,body:Q});return new W(E,this.adapter,A,I)}}function O(w){return new Z(w)}var S={zod:{parse:(w,g)=>w.parse(g)}};
1
+ var{defineProperty:P,getOwnPropertyNames:B,getOwnPropertyDescriptor:H}=Object,D=Object.prototype.hasOwnProperty;var g=new WeakMap,R=(G)=>{var x=g.get(G),E;if(x)return x;if(x=P({},"__esModule",{value:!0}),G&&typeof G==="object"||typeof G==="function")B(G).map((T)=>!D.call(x,T)&&P(x,T,{get:()=>G[T],enumerable:!(E=H(G,T))||E.enumerable}));return g.set(G,x),x};var U=(G,x)=>{for(var E in x)P(G,E,{get:x[E],enumerable:!0,configurable:!0,set:(T)=>x[E]=()=>T})};var f={};U(f,{zodAdapter:()=>C});module.exports=R(f);var C={parse:(G,x)=>G.parse(x)};var c={};U(c,{yupAdapter:()=>Y});module.exports=R(c);var Y={parse:(G,x)=>G.validateSync(x,{abortEarly:!1})};var j={};U(j,{valibotAdapter:()=>Z});module.exports=R(j);var Z={parse:(G,x)=>{let E=G["~standard"].validate(x);if(E instanceof Promise)throw new Error("Valibot async schemas are not supported. Use synchronous schemas (v.string(), v.object(), etc.) without async actions.");if("issues"in E){let T=Array.from(E.issues).map((J)=>J?.message??"Unknown issue").join("; ");throw new Error(`Valibot validation failed: ${T}`)}return E.value}};var h={};U(h,{zodAdapter:()=>C,yupAdapter:()=>Y,valibotAdapter:()=>Z,prapti:()=>F,adapters:()=>z,ValidatedResponse:()=>I,Prapti:()=>V});module.exports=R(h);var z={zod:C,yup:Y,valibot:Z};class I extends Response{adapter;responseSchema;responseHeadersSchema;validatedHeadersCache=void 0;constructor(G,x,E,T){super(G.body,G);this.adapter=x;this.responseSchema=E;this.responseHeadersSchema=T;if(Object.setPrototypeOf(this,I.prototype),T)this.validateResponseHeaders()}validateResponseHeaders(){if(!this.responseHeadersSchema)return;let G={};this.headers.forEach((x,E)=>{G[E.toLowerCase()]=x}),this.validatedHeadersCache=this.adapter.parse(this.responseHeadersSchema,G)}get validatedHeaders(){if(this.responseHeadersSchema){if(this.validatedHeadersCache!==void 0)return this.validatedHeadersCache;let x={};return this.headers.forEach((E,T)=>{x[T.toLowerCase()]=E}),this.validatedHeadersCache=this.adapter.parse(this.responseHeadersSchema,x),this.validatedHeadersCache}let G={};return this.headers.forEach((x,E)=>{G[E.toLowerCase()]=x}),G}async json(){let G=await super.json();return this.responseSchema?this.adapter.parse(this.responseSchema,G):G}async text(){return super.text()}async blob(){return super.blob()}async arrayBuffer(){return super.arrayBuffer()}async formData(){let G=await super.formData();if(this.responseSchema){let x={};G.forEach((T,J)=>{if(x[J]!==void 0)if(Array.isArray(x[J]))x[J].push(T);else x[J]=[x[J],T];else x[J]=T});let E=this.adapter.parse(this.responseSchema,x);if(E&&typeof E==="object"){let T=new FormData;return Object.entries(E).forEach(([J,K])=>{if(Array.isArray(K))K.forEach((X)=>T.append(J,X));else T.append(J,K)}),T}else throw new Error("Schema validation result is not an object, cannot be converted to FormData")}return G}async urlSearchParams(){let G=await super.text(),x=new URLSearchParams(G);if(this.responseSchema){let E={};x.forEach((J,K)=>{if(E[K]!==void 0)if(Array.isArray(E[K]))E[K].push(J);else E[K]=[E[K],J];else E[K]=J});let T=this.adapter.parse(this.responseSchema,E);if(T&&typeof T==="object"){let J=new URLSearchParams;return Object.entries(T).forEach(([K,X])=>{if(Array.isArray(X))X.forEach((N)=>J.append(K,String(N)));else J.append(K,String(X))}),J}else throw new Error("Schema validation result is not an object, cannot be converted to URLSearchParams")}return x}}class V{adapter;constructor(G){this.adapter=G}headersToObject(G){if(!G)return{};if(G instanceof Headers){let E={};return G.forEach((T,J)=>{E[J.toLowerCase()]=T}),E}if(Array.isArray(G)){let E={};return G.forEach(([T,J])=>{E[T.toLowerCase()]=String(J)}),E}let x={};return Object.entries(G).forEach(([E,T])=>{x[E.toLowerCase()]=String(T)}),x}formDataToObject(G){let x={};return G.forEach((E,T)=>{if(x[T]!==void 0)if(Array.isArray(x[T]))x[T].push(E);else x[T]=[x[T],E];else x[T]=E}),x}urlSearchParamsToObject(G){let x={};return G.forEach((E,T)=>{if(x[T]!==void 0)if(Array.isArray(x[T]))x[T].push(E);else x[T]=[x[T],E];else x[T]=E}),x}async fetch(G,x){let{validate:E,body:T,headers:J,...K}=x||{},X=E?.request?.body,N=E?.request?.headers,O=E?.response?.body,A=E?.response?.headers,w,_=new Headers;if(J){let M=this.headersToObject(J);if(N){let Q=this.adapter.parse(N,M);if(Object.entries(M).forEach(([L,W])=>{_.set(L,W)}),Q&&typeof Q==="object")Object.entries(Q).forEach(([L,W])=>{_.set(L,String(W))})}else Object.entries(M).forEach(([Q,L])=>{_.set(Q,L)})}if(T!==void 0&&T!==null)if(X){let M;if(typeof T==="string")try{M=JSON.parse(T)}catch{M=T}else if(T instanceof FormData)M=this.formDataToObject(T);else if(T instanceof URLSearchParams)M=this.urlSearchParamsToObject(T);else M=T;let Q=this.adapter.parse(X,M);if(T instanceof FormData){let L=new FormData;Object.entries(Q).forEach(([W,$])=>{if(Array.isArray($))$.forEach((q)=>L.append(W,q));else L.append(W,$)}),w=L}else if(T instanceof URLSearchParams){let L=new URLSearchParams;Object.entries(Q).forEach(([W,$])=>{if(Array.isArray($))$.forEach((q)=>L.append(W,String(q)));else L.append(W,String($))}),w=L}else if(w=JSON.stringify(Q),!_.has("Content-Type"))_.set("Content-Type","application/json")}else if(typeof T==="object"&&T!==null&&!(T instanceof FormData)&&!(T instanceof URLSearchParams)&&!(T instanceof Blob)&&!(T instanceof ArrayBuffer)&&!ArrayBuffer.isView(T)&&!(T instanceof ReadableStream)){if(w=JSON.stringify(T),!_.has("Content-Type"))_.set("Content-Type","application/json")}else w=T;let S=await fetch(G,{...K,headers:_,body:w});return new I(S,this.adapter,O,A)}}function F(G){return new V(G)}
package/dist/index.d.ts CHANGED
@@ -1,50 +1,143 @@
1
1
  // Generated by dts-bundle-generator v9.5.1
2
2
 
3
- /**
4
- * Prapti - Type-safe HTTP client with schema validation
5
- * "प्राप्ति" (Prapti) - Sanskrit for "fetch" or "obtain"
6
- */
7
3
  /**
8
4
  * Validation adapter interface for different schema libraries
9
5
  * Supports Zod, Valibot, Yup, Joi, and other validation libraries
10
6
  */
11
7
  export interface ValidationAdapter<TSchema = unknown> {
12
8
  /**
13
- * Parse and validate data against the provided schema
9
+ * Parse and validate data against the provided schema.
10
+ * Returns `unknown`; callers derive the output type via `InferOutput<TSchema>`.
14
11
  * @param schema - The validation schema
15
12
  * @param data - Data to validate
16
- * @returns Validated and typed data
13
+ * @returns Validated data (untyped — use InferOutput<TSchema> at call sites)
17
14
  * @throws Validation error if data doesn't match schema
18
15
  */
19
- parse<T>(schema: TSchema, data: unknown): T;
16
+ parse(schema: TSchema, data: unknown): unknown;
20
17
  }
21
18
  /**
22
- * Type helper to infer output type from various schema formats
23
- * Supports multiple validation library conventions
19
+ * Type helper to infer output type from various schema formats.
20
+ *
21
+ * Convention coverage:
22
+ * - Zod: schema._output
23
+ * - Yup: schema.__outputType (via InferType)
24
+ * - Valibot: schema["~standard"].types.output (Standard Schema spec)
25
+ * - Fallback: unknown
24
26
  */
25
27
  export type InferOutput<T> = T extends {
26
28
  _output: infer U;
27
29
  } ? U : T extends {
28
- _type: infer U;
30
+ __outputType: infer U;
31
+ } ? U : T extends {
32
+ readonly "~standard": {
33
+ readonly types?: {
34
+ readonly output?: infer U;
35
+ };
36
+ };
29
37
  } ? U : T extends (...args: any[]) => infer U ? U : unknown;
30
38
  /**
31
- * Extended fetch options with optional validation schemas
39
+ * Nested validation schema options grouped by HTTP direction
40
+ */
41
+ export interface ValidateOptions<TRequestBodySchema = unknown, TResponseBodySchema = unknown, TRequestHeadersSchema = unknown, TResponseHeadersSchema = unknown> {
42
+ /** Schemas applied to the outgoing request */
43
+ request?: {
44
+ /** Schema to validate request body against */
45
+ body?: TRequestBodySchema;
46
+ /** Schema to validate request headers against */
47
+ headers?: TRequestHeadersSchema;
48
+ };
49
+ /** Schemas applied to the incoming response */
50
+ response?: {
51
+ /** Schema to validate response body against */
52
+ body?: TResponseBodySchema;
53
+ /** Schema to validate response headers against */
54
+ headers?: TResponseHeadersSchema;
55
+ };
56
+ }
57
+ /**
58
+ * Extended fetch options with optional validation schemas.
32
59
  * Maintains compatibility with native RequestInit while adding validation
60
+ * via the `validate` block.
33
61
  */
34
- export interface PraptiOptions<TRequestSchema = unknown, TResponseSchema = unknown, TRequestHeadersSchema = unknown, TResponseHeadersSchema = unknown> extends Omit<RequestInit, "body" | "headers"> {
35
- /** Request body - can be any serializable data when using requestSchema */
36
- body?: BodyInit | null | unknown;
37
- /** Request headers - can be HeadersInit or plain object when using requestHeadersSchema */
62
+ export interface PraptiOptions<TRequestBodySchema = unknown, TResponseBodySchema = unknown, TRequestHeadersSchema = unknown, TResponseHeadersSchema = unknown> extends Omit<RequestInit, "body" | "headers"> {
63
+ /** Request body accepts native BodyInit types or a plain object/array (auto-JSON-stringified) */
64
+ body?: BodyInit | null | Record<string, unknown> | unknown[];
65
+ /** Request headers - can be HeadersInit or plain object */
38
66
  headers?: HeadersInit | Record<string, unknown>;
39
- /** Schema to validate request body against */
40
- requestSchema?: TRequestSchema;
41
- /** Schema to validate response data against */
42
- responseSchema?: TResponseSchema;
43
- /** Schema to validate request headers against */
44
- requestHeadersSchema?: TRequestHeadersSchema;
45
- /** Schema to validate response headers against */
46
- responseHeadersSchema?: TResponseHeadersSchema;
67
+ /** All schema validation options, grouped by direction */
68
+ validate?: ValidateOptions<TRequestBodySchema, TResponseBodySchema, TRequestHeadersSchema, TResponseHeadersSchema>;
47
69
  }
70
+ export type ValibotResult<O> = {
71
+ value: O;
72
+ } | {
73
+ issues: ArrayLike<unknown>;
74
+ };
75
+ export type ValibotSchema<O = unknown> = {
76
+ readonly "~standard": {
77
+ readonly version: 1;
78
+ readonly vendor: "valibot";
79
+ readonly validate: (value: unknown) => ValibotResult<O> | Promise<ValibotResult<O>>;
80
+ readonly types?: {
81
+ readonly input?: unknown;
82
+ readonly output?: O;
83
+ };
84
+ };
85
+ };
86
+ /**
87
+ * Adapter for Valibot (https://valibot.dev).
88
+ * Import directly for tree-shaking: import { valibotAdapter } from "prapti/adapters/valibot"
89
+ *
90
+ * Note: async schemas are not supported. Use synchronous schemas
91
+ * (v.string(), v.object(), etc.) without async actions.
92
+ */
93
+ export declare const valibotAdapter: ValidationAdapter<ValibotSchema>;
94
+ export type YupSchema<O = unknown> = {
95
+ validateSync: (data: unknown, options?: object) => O;
96
+ __outputType: O;
97
+ };
98
+ /**
99
+ * Adapter for Yup (https://github.com/jquense/yup).
100
+ * Import directly for tree-shaking: import { yupAdapter } from "prapti/adapters/yup"
101
+ */
102
+ export declare const yupAdapter: ValidationAdapter<YupSchema>;
103
+ export type ZodSchema<O = unknown> = {
104
+ parse: (data: unknown) => O;
105
+ _output: O;
106
+ };
107
+ /**
108
+ * Adapter for Zod (https://zod.dev).
109
+ * Import directly for tree-shaking: import { zodAdapter } from "prapti/adapters/zod"
110
+ */
111
+ export declare const zodAdapter: ValidationAdapter<ZodSchema>;
112
+ export declare const adapters: {
113
+ zod: ValidationAdapter<{
114
+ parse: (data: unknown) => unknown;
115
+ _output: unknown;
116
+ }>;
117
+ yup: ValidationAdapter<{
118
+ validateSync: (data: unknown, options?: object) => unknown;
119
+ __outputType: unknown;
120
+ }>;
121
+ valibot: ValidationAdapter<{
122
+ readonly "~standard": {
123
+ readonly version: 1;
124
+ readonly vendor: "valibot";
125
+ readonly validate: (value: unknown) => ({
126
+ issues: ArrayLike<unknown>;
127
+ } | {
128
+ value: unknown;
129
+ }) | Promise<{
130
+ issues: ArrayLike<unknown>;
131
+ } | {
132
+ value: unknown;
133
+ }>;
134
+ readonly types?: {
135
+ readonly input?: unknown;
136
+ readonly output?: unknown;
137
+ } | undefined;
138
+ };
139
+ }>;
140
+ };
48
141
  /**
49
142
  * Enhanced Response class with validation-aware methods
50
143
  * Extends native Response to provide type-safe data parsing
@@ -53,6 +146,7 @@ export declare class ValidatedResponse<T = unknown, THeadersSchema = any> extend
53
146
  private adapter;
54
147
  private responseSchema?;
55
148
  private responseHeadersSchema?;
149
+ private validatedHeadersCache;
56
150
  constructor(response: Response, adapter: ValidationAdapter<any>, responseSchema?: any | undefined, responseHeadersSchema?: THeadersSchema | undefined);
57
151
  /**
58
152
  * Validate response headers against schema
@@ -60,22 +154,20 @@ export declare class ValidatedResponse<T = unknown, THeadersSchema = any> extend
60
154
  */
61
155
  private validateResponseHeaders;
62
156
  /**
63
- * Get validated headers as typed object
64
- * @returns Validated headers object if schema provided, otherwise plain object
157
+ * Get validated headers as a typed object.
158
+ * Returns the schema-validated result if a response headers schema was provided,
159
+ * otherwise returns a plain lowercase-keyed object of all response headers.
65
160
  */
66
- getValidatedHeaders<T = THeadersSchema extends {
67
- _output: infer U;
68
- } ? U : THeadersSchema extends {
69
- _type: infer U;
70
- } ? U : Record<string, string>>(): T;
161
+ get validatedHeaders(): THeadersSchema extends infer S ? InferOutput<S> : Record<string, string>;
71
162
  /**
72
163
  * Parse JSON response and validate with schema if provided
73
164
  * @returns Promise resolving to validated JSON data
74
165
  */
75
166
  json(): Promise<T>;
76
167
  /**
77
- * Parse text response and validate with schema if provided
78
- * @returns Promise resolving to validated text data
168
+ * Get raw text response - no schema validation applied.
169
+ * Text is a raw byte representation; use json() for structured validation.
170
+ * @returns Promise resolving to the raw response text
79
171
  */
80
172
  text(): Promise<string>;
81
173
  /**
@@ -135,20 +227,10 @@ export declare class Prapti<TSchema = unknown> {
135
227
  fetch<TResponseSchema extends TSchema = never, TResponseHeadersSchema extends TSchema = never>(input: RequestInfo | URL, options?: PraptiOptions<TSchema, TResponseSchema, TSchema, TResponseHeadersSchema>): Promise<ValidatedResponse<TResponseSchema extends never ? unknown : InferOutput<TResponseSchema>, TResponseHeadersSchema>>;
136
228
  }
137
229
  /**
138
- * Convenience function to create Prapti instance
230
+ * Convenience function to create a Prapti instance
139
231
  * @param adapter - Validation adapter
140
232
  * @returns New Prapti instance
141
233
  */
142
- export declare function createPrapti<TSchema>(adapter: ValidationAdapter<TSchema>): Prapti<TSchema>;
143
- /**
144
- * Pre-built adapters for popular validation libraries
145
- */
146
- export declare const adapters: {
147
- /**
148
- * Zod adapter
149
- * @returns ValidationAdapter for Zod schemas
150
- */
151
- zod: ValidationAdapter;
152
- };
234
+ export declare function prapti<TSchema>(adapter: ValidationAdapter<TSchema>): Prapti<TSchema>;
153
235
 
154
236
  export {};
package/dist/index.esm.js CHANGED
@@ -1 +1 @@
1
- class X extends Response{adapter;responseSchema;responseHeadersSchema;constructor(g,w,z,A){super(g.body,g);this.adapter=w;this.responseSchema=z;this.responseHeadersSchema=A;if(Object.setPrototypeOf(this,X.prototype),A)this.validateResponseHeaders()}validateResponseHeaders(){if(!this.responseHeadersSchema)return;let g={};this.headers.forEach((w,z)=>{g[z.toLowerCase()]=w}),this.adapter.parse(this.responseHeadersSchema,g)}getValidatedHeaders(){let g={};return this.headers.forEach((w,z)=>{g[z.toLowerCase()]=w}),this.responseHeadersSchema?this.adapter.parse(this.responseHeadersSchema,g):g}async json(){let g=await super.json();return this.responseSchema?this.adapter.parse(this.responseSchema,g):g}async text(){let g=await super.text();return this.responseSchema?this.adapter.parse(this.responseSchema,g):g}async blob(){return super.blob()}async arrayBuffer(){return super.arrayBuffer()}async formData(){let g=await super.formData();if(this.responseSchema){let w={};g.forEach((A,C)=>{if(w[C]!==void 0)if(Array.isArray(w[C]))w[C].push(A);else w[C]=[w[C],A];else w[C]=A});let z=this.adapter.parse(this.responseSchema,w);if(z&&typeof z==="object"){let A=new FormData;return Object.entries(z).forEach(([C,I])=>{if(Array.isArray(I))I.forEach((G)=>A.append(C,G));else A.append(C,I)}),A}}return g}async urlSearchParams(){let g=await super.text(),w=new URLSearchParams(g);if(this.responseSchema){let z={};w.forEach((C,I)=>{if(z[I]!==void 0)if(Array.isArray(z[I]))z[I].push(C);else z[I]=[z[I],C];else z[I]=C});let A=this.adapter.parse(this.responseSchema,z);if(A&&typeof A==="object"){let C=new URLSearchParams;return Object.entries(A).forEach(([I,G])=>{if(Array.isArray(G))G.forEach((U)=>C.append(I,String(U)));else C.append(I,String(G))}),C}}return w}}class Y{adapter;constructor(g){this.adapter=g}headersToObject(g){if(!g)return{};if(g instanceof Headers){let z={};return g.forEach((A,C)=>{z[C.toLowerCase()]=A}),z}if(Array.isArray(g)){let z={};return g.forEach(([A,C])=>{z[A.toLowerCase()]=String(C)}),z}let w={};return Object.entries(g).forEach(([z,A])=>{w[z.toLowerCase()]=String(A)}),w}formDataToObject(g){let w={};return g.forEach((z,A)=>{if(w[A]!==void 0)if(Array.isArray(w[A]))w[A].push(z);else w[A]=[w[A],z];else w[A]=z}),w}urlSearchParamsToObject(g){let w={};return g.forEach((z,A)=>{if(w[A]!==void 0)if(Array.isArray(w[A]))w[A].push(z);else w[A]=[w[A],z];else w[A]=z}),w}async fetch(g,w){let{requestSchema:z,responseSchema:A,requestHeadersSchema:C,responseHeadersSchema:I,body:G,headers:U,...Z}=w||{},Q,T=new Headers;if(U){let K=this.headersToObject(U);if(C){let L=this.adapter.parse(C,K);if(L&&typeof L==="object")Object.entries(L).forEach(([J,M])=>{T.set(J,String(M))})}else Object.entries(K).forEach(([L,J])=>{T.set(L,J)})}if(z&&G!==void 0&&G!==null){let K;if(typeof G==="string")try{K=JSON.parse(G)}catch{K=G}else if(G instanceof FormData)K=this.formDataToObject(G);else if(G instanceof URLSearchParams)K=this.urlSearchParamsToObject(G);else K=G;let L=this.adapter.parse(z,K);if(G instanceof FormData){let J=new FormData;Object.entries(L).forEach(([M,N])=>{if(Array.isArray(N))N.forEach((W)=>J.append(M,W));else J.append(M,N)}),Q=J}else if(G instanceof URLSearchParams){let J=new URLSearchParams;Object.entries(L).forEach(([M,N])=>{if(Array.isArray(N))N.forEach((W)=>J.append(M,String(W)));else J.append(M,String(N))}),Q=J}else if(Q=JSON.stringify(L),!T.has("Content-Type"))T.set("Content-Type","application/json")}else Q=G;let _=await fetch(g,{...Z,headers:T,body:Q});return new X(_,this.adapter,A,I)}}function $(g){return new Y(g)}var E={zod:{parse:(g,w)=>g.parse(w)}};export{$ as createPrapti,E as adapters,X as ValidatedResponse,Y as Prapti};
1
+ var Z={parse:(G,x)=>G.parse(x)};var I={parse:(G,x)=>G.validateSync(x,{abortEarly:!1})};var N={parse:(G,x)=>{let E=G["~standard"].validate(x);if(E instanceof Promise)throw new Error("Valibot async schemas are not supported. Use synchronous schemas (v.string(), v.object(), etc.) without async actions.");if("issues"in E){let T=Array.from(E.issues).map((J)=>J?.message??"Unknown issue").join("; ");throw new Error(`Valibot validation failed: ${T}`)}return E.value}};var g={zod:Z,yup:I,valibot:N};class C extends Response{adapter;responseSchema;responseHeadersSchema;validatedHeadersCache=void 0;constructor(G,x,E,T){super(G.body,G);this.adapter=x;this.responseSchema=E;this.responseHeadersSchema=T;if(Object.setPrototypeOf(this,C.prototype),T)this.validateResponseHeaders()}validateResponseHeaders(){if(!this.responseHeadersSchema)return;let G={};this.headers.forEach((x,E)=>{G[E.toLowerCase()]=x}),this.validatedHeadersCache=this.adapter.parse(this.responseHeadersSchema,G)}get validatedHeaders(){if(this.responseHeadersSchema){if(this.validatedHeadersCache!==void 0)return this.validatedHeadersCache;let x={};return this.headers.forEach((E,T)=>{x[T.toLowerCase()]=E}),this.validatedHeadersCache=this.adapter.parse(this.responseHeadersSchema,x),this.validatedHeadersCache}let G={};return this.headers.forEach((x,E)=>{G[E.toLowerCase()]=x}),G}async json(){let G=await super.json();return this.responseSchema?this.adapter.parse(this.responseSchema,G):G}async text(){return super.text()}async blob(){return super.blob()}async arrayBuffer(){return super.arrayBuffer()}async formData(){let G=await super.formData();if(this.responseSchema){let x={};G.forEach((T,J)=>{if(x[J]!==void 0)if(Array.isArray(x[J]))x[J].push(T);else x[J]=[x[J],T];else x[J]=T});let E=this.adapter.parse(this.responseSchema,x);if(E&&typeof E==="object"){let T=new FormData;return Object.entries(E).forEach(([J,K])=>{if(Array.isArray(K))K.forEach((X)=>T.append(J,X));else T.append(J,K)}),T}else throw new Error("Schema validation result is not an object, cannot be converted to FormData")}return G}async urlSearchParams(){let G=await super.text(),x=new URLSearchParams(G);if(this.responseSchema){let E={};x.forEach((J,K)=>{if(E[K]!==void 0)if(Array.isArray(E[K]))E[K].push(J);else E[K]=[E[K],J];else E[K]=J});let T=this.adapter.parse(this.responseSchema,E);if(T&&typeof T==="object"){let J=new URLSearchParams;return Object.entries(T).forEach(([K,X])=>{if(Array.isArray(X))X.forEach((Y)=>J.append(K,String(Y)));else J.append(K,String(X))}),J}else throw new Error("Schema validation result is not an object, cannot be converted to URLSearchParams")}return x}}class U{adapter;constructor(G){this.adapter=G}headersToObject(G){if(!G)return{};if(G instanceof Headers){let E={};return G.forEach((T,J)=>{E[J.toLowerCase()]=T}),E}if(Array.isArray(G)){let E={};return G.forEach(([T,J])=>{E[T.toLowerCase()]=String(J)}),E}let x={};return Object.entries(G).forEach(([E,T])=>{x[E.toLowerCase()]=String(T)}),x}formDataToObject(G){let x={};return G.forEach((E,T)=>{if(x[T]!==void 0)if(Array.isArray(x[T]))x[T].push(E);else x[T]=[x[T],E];else x[T]=E}),x}urlSearchParamsToObject(G){let x={};return G.forEach((E,T)=>{if(x[T]!==void 0)if(Array.isArray(x[T]))x[T].push(E);else x[T]=[x[T],E];else x[T]=E}),x}async fetch(G,x){let{validate:E,body:T,headers:J,...K}=x||{},X=E?.request?.body,Y=E?.request?.headers,V=E?.response?.body,q=E?.response?.headers,w,_=new Headers;if(J){let M=this.headersToObject(J);if(Y){let Q=this.adapter.parse(Y,M);if(Object.entries(M).forEach(([L,W])=>{_.set(L,W)}),Q&&typeof Q==="object")Object.entries(Q).forEach(([L,W])=>{_.set(L,String(W))})}else Object.entries(M).forEach(([Q,L])=>{_.set(Q,L)})}if(T!==void 0&&T!==null)if(X){let M;if(typeof T==="string")try{M=JSON.parse(T)}catch{M=T}else if(T instanceof FormData)M=this.formDataToObject(T);else if(T instanceof URLSearchParams)M=this.urlSearchParamsToObject(T);else M=T;let Q=this.adapter.parse(X,M);if(T instanceof FormData){let L=new FormData;Object.entries(Q).forEach(([W,$])=>{if(Array.isArray($))$.forEach((R)=>L.append(W,R));else L.append(W,$)}),w=L}else if(T instanceof URLSearchParams){let L=new URLSearchParams;Object.entries(Q).forEach(([W,$])=>{if(Array.isArray($))$.forEach((R)=>L.append(W,String(R)));else L.append(W,String($))}),w=L}else if(w=JSON.stringify(Q),!_.has("Content-Type"))_.set("Content-Type","application/json")}else if(typeof T==="object"&&T!==null&&!(T instanceof FormData)&&!(T instanceof URLSearchParams)&&!(T instanceof Blob)&&!(T instanceof ArrayBuffer)&&!ArrayBuffer.isView(T)&&!(T instanceof ReadableStream)){if(w=JSON.stringify(T),!_.has("Content-Type"))_.set("Content-Type","application/json")}else w=T;let P=await fetch(G,{...K,headers:_,body:w});return new C(P,this.adapter,V,q)}}function z(G){return new U(G)}export{Z as zodAdapter,I as yupAdapter,N as valibotAdapter,z as prapti,g as adapters,C as ValidatedResponse,U as Prapti};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prapti",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "Type-safe HTTP client with runtime schema validation support for Zod, Valibot, Yup, and more",
5
5
  "files": [
6
6
  "dist/*",
@@ -15,6 +15,21 @@
15
15
  "types": "./dist/index.d.ts",
16
16
  "require": "./dist/index.cjs.js",
17
17
  "import": "./dist/index.esm.js"
18
+ },
19
+ "./adapters/zod": {
20
+ "types": "./dist/adapters/zod.d.ts",
21
+ "require": "./dist/adapters/zod.cjs.js",
22
+ "import": "./dist/adapters/zod.esm.js"
23
+ },
24
+ "./adapters/yup": {
25
+ "types": "./dist/adapters/yup.d.ts",
26
+ "require": "./dist/adapters/yup.cjs.js",
27
+ "import": "./dist/adapters/yup.esm.js"
28
+ },
29
+ "./adapters/valibot": {
30
+ "types": "./dist/adapters/valibot.d.ts",
31
+ "require": "./dist/adapters/valibot.cjs.js",
32
+ "import": "./dist/adapters/valibot.esm.js"
18
33
  }
19
34
  },
20
35
  "scripts": {
@@ -50,7 +65,9 @@
50
65
  "@size-limit/preset-small-lib": "^11.2.0",
51
66
  "@types/bun": "latest",
52
67
  "bun-plugin-dts": "0.3.0",
53
- "size-limit": "^11.2.0"
68
+ "size-limit": "^11.2.0",
69
+ "valibot": "^1.2.0",
70
+ "yup": "^1.7.1"
54
71
  },
55
72
  "peerDependencies": {
56
73
  "typescript": "^5",