swagger-ts-sdk 0.0.1 → 0.0.2

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 ADDED
@@ -0,0 +1,255 @@
1
+ # Swagger TypeScript SDK
2
+
3
+ A TypeScript SDK generated from Swagger/OpenAPI specifications, providing a type-safe way to interact with REST APIs.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install swagger-ts-sdk
9
+ # or
10
+ bun add swagger-ts-sdk
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```typescript
16
+ import { SdkClient } from "swagger-ts-sdk";
17
+ import { Api } from "./your-api-schema";
18
+
19
+ const client = new SdkClient(Api, {
20
+ baseUrl: "https://api.example.com",
21
+ });
22
+
23
+ (async () => {
24
+ const { data, error, status } = await client.greetings.greetingsList();
25
+
26
+ if (error) {
27
+ console.error("Request failed:", error);
28
+ return;
29
+ }
30
+
31
+ console.log("Success:", data);
32
+ })();
33
+ ```
34
+
35
+ ## SdkClient API
36
+
37
+ ### Constructor
38
+
39
+ ```typescript
40
+ new SdkClient<T>(ApiClass, options)
41
+ ```
42
+
43
+ #### Parameters
44
+
45
+ - `ApiClass` - The generated API class from your Swagger schema
46
+ - `options` - Configuration object with the following properties:
47
+
48
+ | Property | Type | Required | Description |
49
+ |----------|------|----------|-------------|
50
+ | `baseUrl` | `string` | Yes | The base URL for all API requests |
51
+ | `token` | `SdkToken` | No | Bearer token for authentication. Can be a static string or a function that returns the token dynamically. |
52
+ | `onRequestError` | `(error: SdkError) => void` | No | Callback triggered when a request fails |
53
+ | `timeout` | `number` | No | Request timeout in milliseconds. If set, the request will be aborted after the specified duration. |
54
+
55
+ ### Response Format
56
+
57
+ All API methods return a standardized response object:
58
+
59
+ ```typescript
60
+ {
61
+ data: T | null; // The response data on success
62
+ error: string | null; // Error message on failure
63
+ status: number | null; // HTTP status code
64
+ abort: () => void; // Function to abort the request
65
+ }
66
+ ```
67
+
68
+ ## SdkError Type
69
+
70
+ The `SdkError` type represents an error response from the API. It is passed to the `onRequestError` callback when a request fails.
71
+
72
+ ```typescript
73
+ export type SdkError<E = unknown> = {
74
+ /** Always null for error responses */
75
+ data: null;
76
+ /** The error data from the API response */
77
+ error: E;
78
+ /** HTTP status code */
79
+ status: number;
80
+ /** Whether the request was successful (always false for errors) */
81
+ ok: boolean;
82
+ /** HTTP status text */
83
+ statusText: string;
84
+ /** Response headers */
85
+ headers: Headers;
86
+ /** Optional body content */
87
+ body?: any;
88
+ };
89
+ ```
90
+
91
+ ### Importing SdkError
92
+
93
+ ```typescript
94
+ import { SdkClient, SdkError } from "swagger-ts-sdk";
95
+ ```
96
+
97
+ ## Examples
98
+
99
+ ### Basic GET Request
100
+
101
+ ```typescript
102
+ import { SdkClient } from "swagger-ts-sdk";
103
+ import { Api } from "./your-api-schema";
104
+
105
+ const client = new SdkClient(Api, {
106
+ baseUrl: "https://api.example.com",
107
+ });
108
+
109
+ // Get a list of items
110
+ const { data, error, status } = await client.items.itemsList();
111
+
112
+ if (error) {
113
+ console.error(`Error (${status}):`, error);
114
+ } else {
115
+ console.log("Items:", data);
116
+ }
117
+ ```
118
+
119
+ ### POST Request with Data
120
+
121
+ ```typescript
122
+ const { data, error, status } = await client.users.usersCreate({
123
+ body: {
124
+ name: "John Doe",
125
+ email: "john@example.com",
126
+ },
127
+ });
128
+ ```
129
+
130
+ ### Using Authentication Token
131
+
132
+ ```typescript
133
+ const client = new SdkClient(Api, {
134
+ baseUrl: "https://api.example.com",
135
+ token: "your-bearer-token",
136
+ });
137
+ ```
138
+
139
+ ### Dynamic Token (localStorage/sessionStorage)
140
+
141
+ If your token is stored in localStorage or sessionStorage and may change during the session, pass a function instead of a static string. The function will be called before each request to get the current token.
142
+
143
+ ```typescript
144
+ const client = new SdkClient(Api, {
145
+ baseUrl: "https://api.example.com",
146
+ token: () => {
147
+ // Retrieve token from localStorage/sessionStorage for each request
148
+ return localStorage.getItem("authToken");
149
+ // Or use sessionStorage:
150
+ // return sessionStorage.getItem("authToken");
151
+ },
152
+ });
153
+ ```
154
+
155
+ This is useful when:
156
+ - The token may expire and be refreshed during the session
157
+ - You want to avoid storing the token in memory
158
+ - Multiple tabs might update the token
159
+
160
+ ### Error Callback
161
+
162
+ ```typescript
163
+ const client = new SdkClient(Api, {
164
+ baseUrl: "https://api.example.com",
165
+ onRequestError: (error: SdkError) => {
166
+ console.error("Request failed!");
167
+ console.error("Status:", error.status);
168
+ console.error("Error:", error.error);
169
+ console.error("Status Text:", error.statusText);
170
+
171
+ // Send to error tracking service
172
+ // sendToSentry(error);
173
+ },
174
+ });
175
+ ```
176
+
177
+ ### Request Timeout
178
+
179
+ Set a timeout in milliseconds to automatically abort requests that take too long.
180
+
181
+ ```typescript
182
+ const client = new SdkClient(Api, {
183
+ baseUrl: "https://api.example.com",
184
+ timeout: 5000, // 5 seconds
185
+ });
186
+
187
+ // If the request takes longer than 5 seconds, it will be aborted
188
+ const { data, error, status } = await client.items.itemsList();
189
+
190
+ if (error === "Request failed" && status === 0) {
191
+ console.error("Request timed out");
192
+ }
193
+ ```
194
+
195
+ ### Abort Request
196
+
197
+ Each request returns an `abort` function that you can call to cancel the request at any time.
198
+
199
+ ```typescript
200
+ const client = new SdkClient(Api, {
201
+ baseUrl: "https://api.example.com",
202
+ });
203
+
204
+ // Make a request and get the abort function
205
+ const request = client.items.itemsList();
206
+ const { data, error, status, abort } = await request;
207
+
208
+ // Or destructured:
209
+ const { abort: cancelRequest } = await client.items.itemsList();
210
+
211
+ // Cancel the request if needed
212
+ cancelRequest();
213
+
214
+ // Or using the abort function from the response
215
+ const response = await client.users.usersList();
216
+ response.abort(); // Cancel the request
217
+ ```
218
+
219
+ **Note:** Once a request is aborted, the response will have `error: "Request aborted"` and `status: 0`.
220
+
221
+ ### Nested API Endpoints
222
+
223
+ The SDK supports nested API structures:
224
+
225
+ ```typescript
226
+ // For APIs with nested endpoints like api.auth.loginCreate
227
+ const { data, error } = await client.auth.loginCreate({
228
+ body: {
229
+ username: "user",
230
+ password: "pass",
231
+ },
232
+ });
233
+ ```
234
+
235
+ ## Type Safety
236
+
237
+ The SDK provides full type safety for:
238
+
239
+ - Request parameters
240
+ - Request body
241
+ - Response data
242
+ - Error types
243
+
244
+ ```typescript
245
+ // Full type inference
246
+ const { data, error, status } = await client.users.usersGetById("123");
247
+
248
+ // data is typed as User | null
249
+ // error is typed as string | null
250
+ // status is typed as number | null
251
+ ```
252
+
253
+ ## License
254
+
255
+ MIT
package/dist/index.d.ts CHANGED
@@ -1,11 +1,44 @@
1
+ /**
2
+ * Error type returned when an API request fails.
3
+ * Contains the error data, status code, and other response properties.
4
+ */
5
+ type SdkError<E = unknown> = {
6
+ data: null;
7
+ error: E;
8
+ status: number;
9
+ ok: boolean;
10
+ statusText: string;
11
+ headers: Headers;
12
+ body?: any;
13
+ };
14
+ /**
15
+ * Token type that can be either a static string or a function that returns the token.
16
+ * Use a function to retrieve the token dynamically from localStorage/sessionStorage
17
+ * for each request.
18
+ */
19
+ type SdkToken = string | (() => string | undefined);
1
20
  type SdkClientConstructor = new <T extends object>(ApiClass: new (config: {
2
21
  baseUrl: string;
3
22
  baseApiParams?: any;
23
+ securityWorker?: any;
24
+ customFetch?: any;
4
25
  }) => T, options: {
5
26
  baseUrl: string;
6
- /** Token to attach to every request as Bearer auth. */
7
- token?: string;
27
+ /**
28
+ * Token to attach to every request as Bearer auth.
29
+ * Can be a static string or a function that returns the token.
30
+ * Use a function to retrieve the token dynamically from localStorage/sessionStorage
31
+ * for each request.
32
+ */
33
+ token?: SdkToken;
34
+ /** Callback triggered when a request error occurs. */
35
+ onRequestError?: (error: SdkError) => void;
36
+ /**
37
+ * Request timeout in milliseconds.
38
+ * If set, the request will be aborted after the specified duration.
39
+ */
40
+ timeout?: number;
8
41
  }) => T;
9
42
  declare const SdkClient: SdkClientConstructor;
10
43
 
11
- export { SdkClient };
44
+ export { SdkClient, type SdkError, type SdkToken };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- var g=class{constructor(o,i){let{baseUrl:u,token:e}=i,n=new o({baseUrl:u,baseApiParams:{headers:{...e&&{Authorization:`Bearer ${e}`}}}});return e&&"setSecurityData"in n&&n.setSecurityData(e),new Proxy(n,{get(l,y){let s=l[y];return typeof s=="object"&&s!==null?new Proxy(s,{get(a,c){let r=a[c];return typeof r=="function"?async(...p)=>{try{let t=await r.apply(a,p);return {data:t.data,error:null,status:t.status}}catch(t){return {data:null,error:t?.error?.message||t?.message||"Request failed",status:t?.status||null}}}:r}}):s}})}};export{g as SdkClient};
1
+ var q=class{constructor(g,T){let{baseUrl:S,token:e,onRequestError:c,timeout:l}=T,y=typeof e=="function"?e:e?()=>e:()=>{},u=new g({baseUrl:S,baseApiParams:{headers:{...e&&{Authorization:`Bearer ${y()}`}}},securityWorker:async()=>{let n=y();return n?{headers:{Authorization:`Bearer ${n}`}}:{}}}),d=typeof e=="string"?e:void 0;return d&&"setSecurityData"in u&&u.setSecurityData(d),new Proxy(u,{get(n,h){let o=n[h];return typeof o=="object"&&o!==null?new Proxy(o,{get(b,w){let i=b[w];return typeof i=="function"?function(...x){let s=new AbortController,a=s.abort.bind(s),r;l&&(r=setTimeout(()=>{s.abort();},l));let f=(async()=>{var m,k;try{let E={...x[0]||{},signal:s.signal},p=await i.apply(b,[E]);return r&&clearTimeout(r),{data:p.data,error:null,status:p.status,abort:a}}catch(t){return r&&clearTimeout(r),(t==null?void 0:t.name)==="AbortError"||(m=t==null?void 0:t.message)!=null&&m.includes("aborted")?{data:null,error:"Request aborted",status:0,abort:a}:(c&&c(t),{data:null,error:((k=t==null?void 0:t.error)==null?void 0:k.message)||(t==null?void 0:t.message)||"Request failed",status:(t==null?void 0:t.status)||null,abort:a})}})();return f.abort=a,f}:i}}):o}})}};export{q as SdkClient};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "swagger-ts-sdk",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "author": "codesordinate studio",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -8,7 +8,12 @@
8
8
  "types": "dist/index.d.ts",
9
9
  "module": "dist/index.js",
10
10
  "scripts": {
11
- "publish-package": " npm publish"
11
+ "test": "bun test",
12
+ "tsc": "tsup --watch",
13
+ "server": "bun run --watch src/example/server-test.ts",
14
+ "dev": "concurrently \"bun server\" \"bun tsc\"",
15
+ "package": "tsup",
16
+ "publish-package": "bun test && bun package && npm publish"
12
17
  },
13
18
  "repository": {
14
19
  "type": "git",
@@ -21,10 +26,15 @@
21
26
  }
22
27
  },
23
28
  "devDependencies": {
24
- "@sinclair/typebox": "^0.34.48"
29
+ "@sinclair/typebox": "^0.34.48",
30
+ "concurrently": "^9.2.1",
31
+ "swagger-typescript-api": "^13.2.18"
25
32
  },
26
33
  "files": [
27
34
  "dist",
28
35
  "README.md"
29
- ]
36
+ ],
37
+ "dependencies": {
38
+ "@codesordinatestudio/lucent": "^1.1.15"
39
+ }
30
40
  }