typedapi-client-helpers 0.1.15 → 0.2.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.
Files changed (137) hide show
  1. package/README.md +220 -490
  2. package/dist/index.cjs +274 -47
  3. package/dist/index.d.cts +79 -95
  4. package/dist/index.d.ts +79 -95
  5. package/dist/index.js +267 -47
  6. package/package.json +54 -12
  7. package/scripts/generate-api-minimal.mjs +476 -959
  8. package/scripts/openapi-generator/controller-template.mjs +246 -0
  9. package/scripts/openapi-generator/http-client-template.mjs +34 -0
  10. package/scripts/openapi-generator/index.mjs +113 -0
  11. package/scripts/openapi-generator/method-template.mjs +440 -0
  12. package/scripts/openapi-generator/names.mjs +145 -0
  13. package/scripts/openapi-generator/openapi-utils.mjs +147 -0
  14. package/scripts/openapi-generator/schema.mjs +455 -0
  15. package/bin/typedapi-generate.js +0 -3
  16. package/dist/api/generated/Import.d.ts +0 -22
  17. package/dist/api/generated/Import.d.ts.map +0 -1
  18. package/dist/api/generated/Import.js +0 -48
  19. package/dist/api/generated/Import.js.map +0 -1
  20. package/dist/api/generated/ImportRoute.d.ts +0 -30
  21. package/dist/api/generated/ImportRoute.d.ts.map +0 -1
  22. package/dist/api/generated/ImportRoute.js +0 -13
  23. package/dist/api/generated/ImportRoute.js.map +0 -1
  24. package/dist/api/generated/Order.d.ts +0 -38
  25. package/dist/api/generated/Order.d.ts.map +0 -1
  26. package/dist/api/generated/Order.js +0 -75
  27. package/dist/api/generated/Order.js.map +0 -1
  28. package/dist/api/generated/OrderRoute.d.ts +0 -83
  29. package/dist/api/generated/OrderRoute.d.ts.map +0 -1
  30. package/dist/api/generated/OrderRoute.js +0 -13
  31. package/dist/api/generated/OrderRoute.js.map +0 -1
  32. package/dist/api/generated/Product.d.ts +0 -62
  33. package/dist/api/generated/Product.d.ts.map +0 -1
  34. package/dist/api/generated/Product.js +0 -114
  35. package/dist/api/generated/Product.js.map +0 -1
  36. package/dist/api/generated/ProductRoute.d.ts +0 -140
  37. package/dist/api/generated/ProductRoute.d.ts.map +0 -1
  38. package/dist/api/generated/ProductRoute.js +0 -13
  39. package/dist/api/generated/ProductRoute.js.map +0 -1
  40. package/dist/api/generated/Report.d.ts +0 -14
  41. package/dist/api/generated/Report.d.ts.map +0 -1
  42. package/dist/api/generated/Report.js +0 -32
  43. package/dist/api/generated/Report.js.map +0 -1
  44. package/dist/api/generated/ReportRoute.d.ts +0 -23
  45. package/dist/api/generated/ReportRoute.d.ts.map +0 -1
  46. package/dist/api/generated/ReportRoute.js +0 -13
  47. package/dist/api/generated/ReportRoute.js.map +0 -1
  48. package/dist/api/generated/Supplier.d.ts +0 -46
  49. package/dist/api/generated/Supplier.d.ts.map +0 -1
  50. package/dist/api/generated/Supplier.js +0 -87
  51. package/dist/api/generated/Supplier.js.map +0 -1
  52. package/dist/api/generated/SupplierRoute.d.ts +0 -101
  53. package/dist/api/generated/SupplierRoute.d.ts.map +0 -1
  54. package/dist/api/generated/SupplierRoute.js +0 -13
  55. package/dist/api/generated/SupplierRoute.js.map +0 -1
  56. package/dist/api/generated/data-contracts.d.ts +0 -277
  57. package/dist/api/generated/data-contracts.d.ts.map +0 -1
  58. package/dist/api/generated/data-contracts.js +0 -26
  59. package/dist/api/generated/data-contracts.js.map +0 -1
  60. package/dist/api/generated/http-client.d.ts +0 -61
  61. package/dist/api/generated/http-client.d.ts.map +0 -1
  62. package/dist/api/generated/http-client.js +0 -171
  63. package/dist/api/generated/http-client.js.map +0 -1
  64. package/dist/api/index.d.ts +0 -8
  65. package/dist/api/index.d.ts.map +0 -1
  66. package/dist/api/index.js +0 -8
  67. package/dist/api/index.js.map +0 -1
  68. package/dist/api/methods/Import.api.d.ts +0 -6
  69. package/dist/api/methods/Import.api.d.ts.map +0 -1
  70. package/dist/api/methods/Import.api.js +0 -27
  71. package/dist/api/methods/Import.api.js.map +0 -1
  72. package/dist/api/methods/Order.api.d.ts +0 -29
  73. package/dist/api/methods/Order.api.d.ts.map +0 -1
  74. package/dist/api/methods/Order.api.js +0 -52
  75. package/dist/api/methods/Order.api.js.map +0 -1
  76. package/dist/api/methods/Product.api.d.ts +0 -39
  77. package/dist/api/methods/Product.api.d.ts.map +0 -1
  78. package/dist/api/methods/Product.api.js +0 -69
  79. package/dist/api/methods/Product.api.js.map +0 -1
  80. package/dist/api/methods/Report.api.d.ts +0 -6
  81. package/dist/api/methods/Report.api.d.ts.map +0 -1
  82. package/dist/api/methods/Report.api.js +0 -19
  83. package/dist/api/methods/Report.api.js.map +0 -1
  84. package/dist/api/methods/Supplier.api.d.ts +0 -35
  85. package/dist/api/methods/Supplier.api.d.ts.map +0 -1
  86. package/dist/api/methods/Supplier.api.js +0 -63
  87. package/dist/api/methods/Supplier.api.js.map +0 -1
  88. package/dist/index.d.ts.map +0 -1
  89. package/dist/index.js.map +0 -1
  90. package/dist/interfaces/ApiResult.d.ts +0 -17
  91. package/dist/interfaces/ApiResult.d.ts.map +0 -1
  92. package/dist/interfaces/ApiResult.js +0 -2
  93. package/dist/interfaces/ApiResult.js.map +0 -1
  94. package/dist/interfaces/Filter.d.ts +0 -31
  95. package/dist/interfaces/Filter.d.ts.map +0 -1
  96. package/dist/interfaces/Filter.js +0 -2
  97. package/dist/interfaces/Filter.js.map +0 -1
  98. package/dist/interfaces/SortType.d.ts +0 -7
  99. package/dist/interfaces/SortType.d.ts.map +0 -1
  100. package/dist/interfaces/SortType.js +0 -2
  101. package/dist/interfaces/SortType.js.map +0 -1
  102. package/dist/types/ApiCallOptions.d.ts +0 -9
  103. package/dist/types/ApiCallOptions.d.ts.map +0 -1
  104. package/dist/types/ApiCallOptions.js +0 -2
  105. package/dist/types/ApiCallOptions.js.map +0 -1
  106. package/dist/types/ApiMethodTypes.d.ts +0 -24
  107. package/dist/types/ApiMethodTypes.d.ts.map +0 -1
  108. package/dist/types/ApiMethodTypes.js +0 -2
  109. package/dist/types/ApiMethodTypes.js.map +0 -1
  110. package/dist/types/HttpResponse.d.ts +0 -16
  111. package/dist/types/HttpResponse.d.ts.map +0 -1
  112. package/dist/types/HttpResponse.js +0 -2
  113. package/dist/types/HttpResponse.js.map +0 -1
  114. package/dist/utils/SortTypeFromSortDirection.d.ts +0 -22
  115. package/dist/utils/SortTypeFromSortDirection.d.ts.map +0 -1
  116. package/dist/utils/SortTypeFromSortDirection.js +0 -45
  117. package/dist/utils/SortTypeFromSortDirection.js.map +0 -1
  118. package/dist/utils/buildQuery.d.ts +0 -11
  119. package/dist/utils/buildQuery.d.ts.map +0 -1
  120. package/dist/utils/buildQuery.js +0 -94
  121. package/dist/utils/buildQuery.js.map +0 -1
  122. package/dist/utils/extractArgsCallbacksAndParams.d.ts +0 -22
  123. package/dist/utils/extractArgsCallbacksAndParams.d.ts.map +0 -1
  124. package/dist/utils/extractArgsCallbacksAndParams.js +0 -44
  125. package/dist/utils/extractArgsCallbacksAndParams.js.map +0 -1
  126. package/dist/utils/extractArgsToastsAndParams.d.ts +0 -18
  127. package/dist/utils/extractArgsToastsAndParams.d.ts.map +0 -1
  128. package/dist/utils/extractArgsToastsAndParams.js +0 -40
  129. package/dist/utils/extractArgsToastsAndParams.js.map +0 -1
  130. package/dist/utils/handleApiResponse.d.ts +0 -9
  131. package/dist/utils/handleApiResponse.d.ts.map +0 -1
  132. package/dist/utils/handleApiResponse.js +0 -49
  133. package/dist/utils/handleApiResponse.js.map +0 -1
  134. package/dist/utils/toFormData.d.ts +0 -8
  135. package/dist/utils/toFormData.d.ts.map +0 -1
  136. package/dist/utils/toFormData.js +0 -68
  137. package/dist/utils/toFormData.js.map +0 -1
package/README.md CHANGED
@@ -1,490 +1,220 @@
1
- # typedapi-client-helpers
2
-
3
- `typedapi-client-helpers` generates a typed TypeScript API client from an OpenAPI/Swagger document and adds reusable helper types and functions for API results, callbacks, filtering, sorting, request parameters, and multipart uploads.
4
-
5
- The package is intended for frontend projects that want a generated API client while still keeping generated files inside their own source tree.
6
-
7
- ## Installation
8
-
9
- ```bash
10
- npm install typedapi-client-helpers
11
- ```
12
-
13
- ## Basic usage
14
-
15
- Add a generator script to your project:
16
-
17
- ```json
18
- {
19
- "scripts": {
20
- "generate:api": "typedapi-generate"
21
- }
22
- }
23
- ```
24
-
25
- Run the generator:
26
-
27
- ```bash
28
- npm run generate:api
29
- ```
30
-
31
- By default, the generator reads the Swagger document from `https://localhost:7000/swagger/v1/swagger.json` and writes the generated API client to `src/api`.
32
-
33
- You can also run the command directly:
34
-
35
- ```bash
36
- npx typedapi-generate
37
- ```
38
-
39
- ## Configuration
40
-
41
- Configuration can be supplied in the `config` section of your `package.json`, with environment variables, or with npm command-line arguments.
42
-
43
- ### Package configuration
44
-
45
- ```json
46
- {
47
- "config": {
48
- "swaggerUrl": "https://localhost:7000/swagger/v1/swagger.json",
49
- "swaggerFile": "swagger/openapi.json",
50
- "apiOutput": "src/api",
51
- "typedApiUseTypeOnlyImports": true,
52
- "typedApiUseFilterFormValues": false,
53
- "typedApiDefaultFunctionsPath": "src/defaultApiFunctions",
54
- "typedApiDefaultSuccessHandler": "handleGoodResult",
55
- "typedApiDefaultErrorHandler": "handleErrors"
56
- }
57
- }
58
- ```
59
-
60
- `swaggerFile` takes precedence over `swaggerUrl` when both are configured.
61
-
62
- ### Configuration options
63
-
64
- | Option | Default | Description |
65
- | ------------------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
66
- | `swaggerUrl` | `https://localhost:7000/swagger/v1/swagger.json` | URL of the OpenAPI/Swagger document. |
67
- | `swaggerFile` | none | Local path to an OpenAPI/Swagger document. When set, this is used instead of `swaggerUrl`. |
68
- | `apiOutput` | `src/api` | Directory where the generated API files are written. |
69
- | `typedApiUseTypeOnlyImports` | `false` | Generates `import type` statements for imports that are only used as types. |
70
- | `typedApiUseFilterFormValues` | `false` | Generates paginated methods that accept `FilterFormValues[]`, page values, and sort values instead of a prebuilt query object. |
71
- | `typedApiDefaultFunctionsPath` | `defaultApiFunctions` | Import path used by generated method files for shared success and error handlers. |
72
- | `typedApiDefaultSuccessHandler` | `handleGoodResult` | Name of the default success handler function imported into generated methods. |
73
- | `typedApiDefaultErrorHandler` | `handleErrors` | Name of the default error handler function imported into generated methods. |
74
-
75
- ### Environment variables
76
-
77
- | Environment variable | Description |
78
- | ----------------------------------- | -------------------------------------------------- |
79
- | `SWAGGER_URL` | URL of the OpenAPI/Swagger document. |
80
- | `SWAGGER_FILE` | Local path to an OpenAPI/Swagger document. |
81
- | `API_OUTPUT` | Directory where generated API files are written. |
82
- | `TYPED_API_USE_TYPE_ONLY_IMPORTS` | Enables type-only imports when set to `true`. |
83
- | `TYPED_API_USE_FILTER_FORM_VALUES` | Enables filter-form based paginated methods. |
84
- | `TYPED_API_DEFAULT_FUNCTIONS_PATH` | Path to the shared default callback handler file. |
85
- | `TYPED_API_DEFAULT_SUCCESS_HANDLER` | Export name of the shared default success handler. |
86
- | `TYPED_API_DEFAULT_ERROR_HANDLER` | Export name of the shared default error handler. |
87
-
88
- Example:
89
-
90
- ```bash
91
- SWAGGER_URL=https://localhost:7000/swagger/v1/swagger.json npm run generate:api
92
- ```
93
-
94
- ### Command-line npm config
95
-
96
- ```bash
97
- npm run generate:api --swagger-url=https://localhost:7000/swagger/v1/swagger.json
98
- npm run generate:api --swagger-file=swagger/openapi.json
99
- npm run generate:api --api-output=src/api
100
- npm run generate:api --typed-api-use-filter-form-values=true
101
- ```
102
-
103
- ## Generated structure
104
-
105
- Running the generator creates a structure similar to this:
106
-
107
- ```text
108
- src/
109
- └── api/
110
- ├── generated/
111
- │ ├── data-contracts.ts
112
- │ ├── http-client.ts
113
- │ ├── Product.ts
114
- │ └── Supplier.ts
115
- ├── methods/
116
- │ ├── Product.api.ts
117
- │ └── Supplier.api.ts
118
- └── index.ts
119
- ```
120
-
121
- | Folder or file | Description |
122
- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------- |
123
- | `generated/` | Raw client, models, and HTTP client generated by `swagger-typescript-api`. Route type files are removed after generation. |
124
- | `methods/` | Typed wrapper methods generated by this package. These call the raw generated client and return `ApiResult<T>`. |
125
- | `index.ts` | Barrel file that exports generated contracts, HTTP client types, and wrapper methods. |
126
- | `defaultApiFunctions.ts` | Optional shared success and error handlers created when the configured default handler file does not exist. |
127
-
128
- ## Calling generated methods
129
-
130
- Generated wrapper methods return `ApiResult<T>`.
131
-
132
- ```ts
133
- import { getSuppliers } from "./api";
134
-
135
- const result = await getSuppliers({
136
- pageNumber: 1,
137
- pageSize: 25,
138
- });
139
-
140
- if (result.ok) {
141
- console.log(result.response);
142
- } else {
143
- console.error(result.status, result.error);
144
- }
145
- ```
146
-
147
- Checking `result.ok` narrows the result automatically.
148
-
149
- ## Generated method argument order
150
-
151
- Generated wrappers preserve the original generated API arguments and then add an optional method options object.
152
-
153
- For query methods:
154
-
155
- ```ts
156
- await getSuppliers(query, {
157
- onSuccess,
158
- onError,
159
- params,
160
- });
161
- ```
162
-
163
- For query methods without a query object, pass `undefined` as the first argument when you want to provide options:
164
-
165
- ```ts
166
- await exportPartners(undefined, {
167
- onError: handleError,
168
- });
169
- ```
170
-
171
- For non-query methods:
172
-
173
- ```ts
174
- await updateSupplier(id, body, {
175
- onSuccess,
176
- onError,
177
- params,
178
- });
179
- ```
180
-
181
- For multipart/form-data methods:
182
-
183
- ```ts
184
- await uploadSupplierLogo(data, {
185
- onSuccess,
186
- onError,
187
- params,
188
- });
189
- ```
190
-
191
- For filter-form paginated methods when `typedApiUseFilterFormValues` is enabled:
192
-
193
- ```ts
194
- await getSuppliers(filters, page, pageSize, sortBy, sortDirection, {
195
- onSuccess,
196
- onError,
197
- params,
198
- });
199
- ```
200
-
201
- The `params` property is forwarded to the generated HTTP client and can contain values such as headers or other request options.
202
-
203
- Every generated wrapper method gets its own options type. The type name is based on the method name.
204
-
205
- ```ts
206
- export type GetSuppliersOptions = {
207
- onSuccess?: ApiSuccessHandler<GetSuppliersResponse>;
208
- onError?: ApiErrorHandler<GetSuppliersError>;
209
- params?: RequestParams;
210
- };
211
- ```
212
-
213
- Examples of generated option type names:
214
-
215
- ```ts
216
- GetSuppliersOptions;
217
- CreateSupplierOptions;
218
- UpdateSupplierOptions;
219
- ExportPartnersOptions;
220
- ```
221
-
222
- This makes it possible to pass only `onError` without also passing `onSuccess`.
223
-
224
- ```ts
225
- await getSuppliers(undefined, {
226
- onError: handleError,
227
- });
228
- ```
229
-
230
- ## Success and error callbacks
231
-
232
- Callbacks receive the full result object, not just the raw response or error.
233
-
234
- ```ts
235
- import type { ApiErrorResult, ApiSuccessResult } from "typedapi-client-helpers";
236
- import { getSuppliers, type SupplierListResponse } from "./api";
237
-
238
- function onSuccess(result: ApiSuccessResult<SupplierListResponse>) {
239
- console.log(result.status, result.response);
240
- }
241
-
242
- function onError(result: ApiErrorResult<SupplierListResponse>) {
243
- console.error(result.status, result.error);
244
- }
245
-
246
- await getSuppliers(
247
- { pageNumber: 1, pageSize: 25 },
248
- {
249
- onSuccess,
250
- onError,
251
- },
252
- );
253
- ```
254
-
255
- The generated method still returns `ApiResult<T>` after callbacks run.
256
-
257
- You can also pass only one callback.
258
-
259
- ```ts
260
- await getSuppliers(
261
- { pageNumber: 1, pageSize: 25 },
262
- {
263
- onError,
264
- },
265
- );
266
- ```
267
-
268
- When default handlers are configured, generated methods use them when no method-specific callback is supplied.
269
-
270
- ```ts
271
- await getSuppliers(
272
- { pageNumber: 1, pageSize: 25 },
273
- {
274
- onSuccess: customSuccessHandler,
275
- },
276
- );
277
- ```
278
-
279
- In this example, the custom success handler is used for success results, and the configured default error handler is still used for error results.
280
-
281
- ## Custom request parameters
282
-
283
- The method options object can contain request parameters supported by the generated HTTP client.
284
-
285
- ```ts
286
- const result = await getSuppliers(
287
- { pageNumber: 1, pageSize: 25 },
288
- {
289
- params: {
290
- headers: {
291
- Authorization: `Bearer ${token}`,
292
- },
293
- },
294
- },
295
- );
296
- ```
297
-
298
- Request parameters can also be combined with callbacks.
299
-
300
- ```ts
301
- const result = await getSuppliers(
302
- { pageNumber: 1, pageSize: 25 },
303
- {
304
- onError: handleError,
305
- params: {
306
- headers: {
307
- Authorization: `Bearer ${token}`,
308
- },
309
- },
310
- },
311
- );
312
- ```
313
-
314
- ## Query methods without required filters
315
-
316
- Some generated API methods require a query object at the raw generated client level, even when all query properties are optional.
317
-
318
- The wrapper methods allow the query argument to be omitted. Internally, they pass an empty object to the raw generated method.
319
-
320
- ```ts
321
- await exportPartners();
322
- ```
323
-
324
- is handled like:
325
-
326
- ```ts
327
- await exportPartners({});
328
- ```
329
-
330
- When you want to pass options but no query, pass `undefined` as the first argument.
331
-
332
- ```ts
333
- await exportPartners(undefined, {
334
- onError: handleError,
335
- });
336
- ```
337
-
338
- ## Filter-form generation
339
-
340
- Set `typedApiUseFilterFormValues` to `true` to generate paginated methods that accept filter form values.
341
-
342
- ```json
343
- {
344
- "config": {
345
- "typedApiUseFilterFormValues": true
346
- }
347
- }
348
- ```
349
-
350
- Example:
351
-
352
- ```ts
353
- import type { FilterFormValues } from "typedapi-client-helpers";
354
- import { getSuppliers, type GetSuppliersQuery } from "./api";
355
-
356
- const filters: FilterFormValues<GetSuppliersQuery>[] = [
357
- {
358
- name: "Supplier name",
359
- filterName: "name",
360
- type: "string",
361
- value: "Example",
362
- isAList: false,
363
- },
364
- ];
365
-
366
- const result = await getSuppliers(filters, 1, 25, "name", "Ascending");
367
- ```
368
-
369
- You can also pass method options as the final argument.
370
-
371
- ```ts
372
- const result = await getSuppliers(filters, 1, 25, "name", "Ascending", {
373
- onError: handleError,
374
- params: {
375
- headers: {
376
- Authorization: `Bearer ${token}`,
377
- },
378
- },
379
- });
380
- ```
381
-
382
- Empty filter values are ignored by `buildQuery`.
383
-
384
- ## Multipart uploads
385
-
386
- Generated methods that need multipart bodies can use `toFormData` internally. You can also use it directly:
387
-
388
- ```ts
389
- import { toFormData } from "typedapi-client-helpers";
390
-
391
- const body = toFormData({
392
- name: "Manual",
393
- file,
394
- tags: ["docs", "public"],
395
- });
396
- ```
397
-
398
- Arrays are appended as repeated fields, files keep their filename, primitives become strings, and nested objects are JSON-stringified.
399
-
400
- ## Public API reference
401
-
402
- ### Result types
403
-
404
- | Export | Description |
405
- | --------------------- | --------------------------------------------------------------------------------------------------------------- |
406
- | `ApiResult<T>` | Discriminated union returned by generated wrapper methods. Contains either a success branch or an error branch. |
407
- | `ApiSuccessResult<T>` | Success-only branch of `ApiResult<T>`. Useful for success callbacks and helper functions. |
408
- | `ApiErrorResult<T>` | Error-only branch of `ApiResult<T>`. Useful for error callbacks and helper functions. |
409
-
410
- ### Filter and sort types
411
-
412
- | Export | Description |
413
- | -------------------------- | ------------------------------------------------------------------------------------------- |
414
- | `FilterType` | Union of supported filter input types used by generated filter-form methods. |
415
- | `OptionValue` | Option object with a display `name` and submitted `value`. |
416
- | `FilterFormValues<TQuery>` | Configuration object for one filter field mapped to a query property. |
417
- | `SortType` | UI sort state: Default, Neutral, Ascending, or Descending. |
418
- | `SortDirection` | Sort direction value accepted by generated query objects. Supports string or number values. |
419
- | `ApiSortDirection` | Sort direction values accepted by the generated API: Default, Ascending, or Descending. |
420
- | `sortTypes` | Constant list of all supported UI sort states. |
421
-
422
- ### Callback and method types
423
-
424
- | Export | Description |
425
- | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
426
- | `ApiSuccessHandler<TResponse>` | Callback type for successful API results. |
427
- | `ApiErrorHandler<TResponse>` | Callback type for failed API results. |
428
- | `ApiMethodCallbacks<TResponse>` | Object shape containing optional `onSuccess`, `onError`, and `params` properties. |
429
- | Generated method options, such as `GetSuppliersOptions` | Per-method options object generated for wrapper methods. Contains optional `onSuccess`, `onError`, and `params`. |
430
- | `ExtractResponse<T>` | Extracts the response body type from a generated method promise. |
431
- | `ExtractError<T>` | Extracts the error body type from a generated method promise. |
432
- | `UnwrapArray<T>` | Extracts the item type from an array, otherwise keeps the original type. |
433
- | `ExtractDataIfPaginated<T>` | Extracts the item type from a `{ data?: T[] }` paginated response. |
434
- | `SortableKeys<T>` | Produces keys that can be used as sortable fields for a response type. |
435
- | `WithoutRequestParams<T>` | Removes a trailing optional `RequestParams` argument from a generated method argument tuple. |
436
-
437
- ### HTTP types
438
-
439
- | Export | Description |
440
- | ---------------------- | ------------------------------------------------------------------- |
441
- | `HttpResponse<D, E>` | Extended fetch `Response` with typed `data` and `error` properties. |
442
- | `RuntimeRequestParams` | Runtime request options object forwarded to generated API methods. |
443
-
444
- ### Utility functions
445
-
446
- | Export | Description |
447
- | ---------------------------------- | ---------------------------------------------------------------------------------------------------- |
448
- | `buildQuery<TQuery, TSortModel>()` | Builds a query object from filter form values, page values, and sort values. |
449
- | `extractArgsCallbacksAndParams()` | Backwards-compatible helper for older generated files that used positional callbacks. |
450
- | `extractArgsToastsAndParams()` | Backwards-compatible extractor for wrapper arguments with success/error handlers and request params. |
451
- | `handleApiResponse()` | Executes a generated API call and converts the response or thrown error into `ApiResult<T>`. |
452
- | `HandleApiResponseOptions<T>` | Options object for passing success and error callbacks to `handleApiResponse`. |
453
- | `getSortTypeFromSortDirection()` | Converts an API sort direction into a UI `SortType`. |
454
- | `getSortDirectionFromSortType()` | Converts a UI `SortType` into an API sort direction. |
455
- | `toFormData()` | Converts an object payload into `FormData`. |
456
-
457
- ### Default callback functions
458
-
459
- | Export | Description |
460
- | ----------------------- | ------------------------------------------------------------------------------------------------------ |
461
- | `handleGoodResult<T>()` | Default success handler template created for generated projects. It can be customized by the consumer. |
462
- | `handleErrors<T>()` | Default error handler template created for generated projects. It can be customized by the consumer. |
463
-
464
- ## Folder documentation
465
-
466
- Additional README files are included in these folders:
467
-
468
- | File | Description |
469
- | -------------------------- | ----------------------------------------------------------- |
470
- | `src/interfaces/README.md` | Documents exported interfaces and result/filter/sort types. |
471
- | `src/types/README.md` | Documents helper types used by generated wrapper methods. |
472
- | `src/utils/README.md` | Documents runtime helper functions. |
473
-
474
- ## Build the package
475
-
476
- ```bash
477
- npm run build
478
- ```
479
-
480
- ## Generate an API client while developing this package
481
-
482
- ```bash
483
- npm run generate:api
484
- ```
485
-
486
- ## Notes
487
-
488
- Generated files inside `src/api` and `dist/api` depend on the Swagger document used during generation. Their exact method names and model names will change when the OpenAPI document changes.
489
-
490
- Generated route type files ending in `Route.ts` are removed from the generated output.
1
+ # typedapi-client-helpers
2
+
3
+ `typedapi-client-helpers` generates a typed TypeScript fetch client from an OpenAPI/Swagger document and adds reusable helper types and functions for API results, callbacks, filtering, sorting, request parameters, and multipart uploads.
4
+
5
+ The package is intended for frontend projects that want a generated API client while still keeping generated files inside their own source tree.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install typedapi-client-helpers
11
+ ```
12
+
13
+ ## Basic usage
14
+
15
+ Add a generator script to your project:
16
+
17
+ ```json
18
+ {
19
+ "scripts": {
20
+ "generate:api": "typedapi-generate"
21
+ }
22
+ }
23
+ ```
24
+
25
+ Run the generator:
26
+
27
+ ```bash
28
+ npm run generate:api
29
+ ```
30
+
31
+ By default, the generator first looks for a local `swagger/swagger.json` file in the project where the command is run. If that file is not available, it tries `https://localhost:7000/swagger/v1/swagger.json` and stores a validated backup copy inside this package for later runs.
32
+
33
+ You can also run the command directly:
34
+
35
+ ```bash
36
+ npx typedapi-generate
37
+ ```
38
+
39
+ ## Configuration
40
+
41
+ Configuration can be supplied in the `config` section of your `package.json`, with environment variables, or with npm command-line arguments.
42
+
43
+ Configuration is resolved in this order:
44
+
45
+ 1. environment variables;
46
+ 2. npm command-line config values;
47
+ 3. the consuming project's `package.json` config;
48
+ 4. this package's default config values;
49
+ 5. built-in fallbacks.
50
+
51
+ ### Package configuration
52
+
53
+ ```json
54
+ {
55
+ "config": {
56
+ "swaggerUrl": "https://localhost:7000/swagger/v1/swagger.json",
57
+ "swaggerFile": "swagger/openapi.json",
58
+ "typedApiSwaggerBackupFile": "swagger/swagger.backup.json",
59
+ "apiOutput": "src/api",
60
+ "typedApiCleanOutput": true,
61
+ "typedApiModuleNameFirstTag": true,
62
+ "typedApiUseTypeOnlyImports": true,
63
+ "typedApiDefaultFunctionsPath": "src/defaultApiFunctions",
64
+ "typedApiDefaultSuccessHandler": "handleGoodResult",
65
+ "typedApiDefaultErrorHandler": "handleErrors",
66
+ "typedApiDefaultResponseAsSuccess": false,
67
+ "typedApiGenerateUnionEnums": false,
68
+ "typedApiEnumNamesAsValues": false,
69
+ "typedApiBaseUrl": "https://localhost:7000"
70
+ }
71
+ }
72
+ ```
73
+
74
+ `swaggerFile` takes precedence over `swaggerUrl` when both are configured.
75
+
76
+ ### OpenAPI input and backup behavior
77
+
78
+ The generator resolves the OpenAPI/Swagger input as follows:
79
+
80
+ 1. If `swaggerFile` is configured and the file exists, that file is used and copied to the backup file.
81
+ 2. If `swaggerFile` is configured but missing, the generator uses the backup file when it exists. If no backup exists, generation fails.
82
+ 3. If `swaggerUrl` is configured, the generator downloads it, validates that the response is JSON, writes it to the backup file, and generates from that backup copy.
83
+ 4. If `swaggerUrl` is configured but unavailable, the generator uses the backup file when it exists. If no backup exists, generation fails.
84
+ 5. If neither `swaggerFile` nor `swaggerUrl` is configured, the generator tries `swagger/swagger.json` in the current project.
85
+ 6. If no local default file exists, the generator tries `https://localhost:7000/swagger/v1/swagger.json` and falls back to the backup file if the URL is unavailable.
86
+
87
+ The backup prevents a temporary unavailable Swagger endpoint from breaking generation when a valid backup was created earlier.
88
+
89
+ The backup file is always package-owned: `swagger/swagger.backup.json` inside `typedapi-client-helpers`. Consumers do not need to add or configure a backup file in their own project.
90
+
91
+ ### Configuration options
92
+
93
+ | Option | Default | Description |
94
+ | ---------------------------------- | ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------- |
95
+ | `swaggerUrl` | `https://localhost:7000/swagger/v1/swagger.json` | URL of the OpenAPI/Swagger document. Used when no configured or default local file is available. |
96
+ | `swaggerFile` | none | Local path to an OpenAPI/Swagger document. When set, this is used before `swaggerUrl`. |
97
+ | `apiOutput` | `src/api` | Directory where the generated API files are written. |
98
+ | `typedApiCleanOutput` | `true` | Cleans generated API output before writing the new files. |
99
+ | `typedApiModuleNameFirstTag` | `true` | Groups operations by their first OpenAPI tag, creating one controller file per tag. |
100
+ | `typedApiUseTypeOnlyImports` | `true` | Generates `import type` statements for imports that are only used as types. Set to `false` for normal imports. |
101
+ | `typedApiDefaultFunctionsPath` | `src/defaultApiFunctions` | Path to the project file that exports the shared default API success and error handlers. Created when missing. |
102
+ | `typedApiDefaultSuccessHandler` | `handleGoodResult` | Export name of the default success handler imported into generated method files. |
103
+ | `typedApiDefaultErrorHandler` | `handleErrors` | Export name of the default error handler imported into generated method files. |
104
+ | `typedApiDefaultResponseAsSuccess` | `false` | Uses the OpenAPI `default` response as a success response when no 2xx response is available. |
105
+ | `typedApiGenerateUnionEnums` | `false` | Generates enum schemas as string-literal union types instead of `as const` enum-like objects. |
106
+ | `typedApiEnumNamesAsValues` | `false` | When OpenAPI uses `x-enumNames`, uses those names as enum/union values instead of only as object keys. |
107
+ | `typedApiBaseUrl` | first OpenAPI server URL | Overrides the generated HTTP client's default `baseUrl`. |
108
+
109
+ ### Environment variables
110
+
111
+ | Environment variable | Description |
112
+ | --------------------------------------- | ------------------------------------------------------------ |
113
+ | `SWAGGER_URL` | URL of the OpenAPI/Swagger document. |
114
+ | `SWAGGER_FILE` | Local path to an OpenAPI/Swagger document. |
115
+ | `API_OUTPUT` | Directory where generated API files are written. |
116
+ | `TYPED_API_CLEAN_OUTPUT` | Cleans generated API output when set to `true`. |
117
+ | `TYPED_API_MODULE_NAME_FIRST_TAG` | Groups operations by first OpenAPI tag when set to `true`. |
118
+ | `TYPED_API_USE_TYPE_ONLY_IMPORTS` | Enables type-only imports when set to `true`. |
119
+ | `TYPED_API_DEFAULT_FUNCTIONS_PATH` | Path to the shared default handler file. |
120
+ | `TYPED_API_DEFAULT_SUCCESS_HANDLER` | Export name of the default success handler. |
121
+ | `TYPED_API_DEFAULT_ERROR_HANDLER` | Export name of the default error handler. |
122
+ | `TYPED_API_DEFAULT_RESPONSE_AS_SUCCESS` | Allows the OpenAPI `default` response to be used as success. |
123
+ | `TYPED_API_GENERATE_UNION_ENUMS` | Generates enum schemas as union types when set to `true`. |
124
+ | `TYPED_API_ENUM_NAMES_AS_VALUES` | Generates enum-like literal values when set to `true`. |
125
+ | `TYPED_API_BASE_URL` | Overrides the generated HTTP client's default base URL. |
126
+
127
+ Example:
128
+
129
+ ```bash
130
+ SWAGGER_URL=https://localhost:7000/swagger/v1/swagger.json npm run generate:api
131
+ ```
132
+
133
+ ### Command-line npm config
134
+
135
+ ```bash
136
+ npm run generate:api --swagger-url=https://localhost:7000/swagger/v1/swagger.json
137
+ npm run generate:api --swagger-file=swagger/openapi.json
138
+ npm run generate:api --typed-api-swagger-backup-file=swagger/swagger.backup.json
139
+ npm run generate:api --api-output=src/api
140
+ npm run generate:api --typed-api-use-type-only-imports=true
141
+ npm run generate:api --typed-api-module-name-first-tag=true
142
+ npm run generate:api --typed-api-generate-union-enums=true
143
+ ```
144
+
145
+ ## Generated structure
146
+
147
+ Running the generator creates a structure similar to this:
148
+
149
+ ```text
150
+ src/
151
+ └── api/
152
+ ├── generated/
153
+ │ ├── data-contracts.ts
154
+ │ └── http-client.ts
155
+ ├── methods/
156
+ │ ├── Product.api.ts
157
+ │ └── Supplier.api.ts
158
+ └── index.ts
159
+ ```
160
+
161
+ | Folder or file | Description |
162
+ | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
163
+ | `generated/data-contracts.ts` | TypeScript models, request parameter types, const enum-like objects, and multipart payload interfaces generated from the OpenAPI schema. |
164
+ | `generated/http-client.ts` | Function-based fetch client with request params, security worker support, custom fetch support, cancellation tokens, and content formatting. It does not generate a class. |
165
+ | `methods/*.api.ts` | One generated file per controller/tag. These files export plain functions such as `getProducts`, `createProduct`, and `uploadProductFiles`; there are no generated controller classes. |
166
+ | `index.ts` | Barrel file that exports contracts, HTTP client utilities, and callable methods. |
167
+
168
+ The generated `generated/` folder, `methods/` folder, old `controllers/` folder, and `index.ts` are cleaned each time the generator runs.
169
+
170
+ The `generated/` and `methods/` folders are cleaned and recreated each time the generator runs.
171
+
172
+ ## Calling generated methods
173
+
174
+ Generated method files export plain functions that can be called directly. The wrapper return type stays `ApiResult<T>`, so existing UI code can keep using `result.ok`, `result.status`, `result.response`, and `result.error`.
175
+
176
+ ```ts
177
+ import {
178
+ getProducts,
179
+ getProductById,
180
+ updateProduct,
181
+ } from "./api/methods/Product.api";
182
+
183
+ const products = await getProducts([], 1, 25);
184
+ const product = await getProductById({ id: "..." });
185
+ await updateProduct(
186
+ { id: "..." },
187
+ { name: "Updated", sku: "SKU-1", price: 10, stock: 5, active: true },
188
+ );
189
+ ```
190
+
191
+ The generated method signatures stay close to the existing callable wrappers:
192
+
193
+ ```ts
194
+ getProducts(filters?, page?, pageSize?, sortBy?, sortDirection?, options?);
195
+ getProductById({ id }, options?);
196
+ updateProduct({ id }, data, options?);
197
+ uploadProductFile(data, options?);
198
+ ```
199
+
200
+ `options.params` is the generated `RequestParams` type and is forwarded directly to the fetch client.
201
+
202
+ ### Default success and error handlers
203
+
204
+ Generated method files import default handlers from `typedApiDefaultFunctionsPath` when that file exports the configured handler names. With the package defaults, the generator uses `src/defaultApiFunctions.ts` and creates it automatically when it is missing.
205
+
206
+ ```ts
207
+ export function handleGoodResult<T>(
208
+ response: ApiSuccessResult<T>,
209
+ ): void | Promise<void> {
210
+ // default success behavior
211
+ }
212
+
213
+ export function handleErrors<T>(
214
+ error: ApiErrorResult<T>,
215
+ ): void | Promise<void> {
216
+ // default error behavior
217
+ }
218
+ ```
219
+
220
+ You can override the path or export names from the consuming project's `package.json` without changing generated method signatures.