make-service 2.0.0-next.0 → 2.1.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.
- package/README.md +9 -14
- package/dist/index.d.ts +10 -50
- package/dist/index.js +7 -67
- package/dist/index.mjs +6 -61
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ It adds a set of little features and allows you to parse responses with [zod](ht
|
|
|
11
11
|
- 🐾 Replaces URL wildcards with a **strongly-typed** object of `params`.
|
|
12
12
|
- 🧙♀️ Automatically stringifies the `body` of a request so you can give it a JSON-like structure.
|
|
13
13
|
- 🐛 Accepts a `trace` function for debugging.
|
|
14
|
-
- 🔥
|
|
14
|
+
- 🔥 It can transform responses and payloads back and forth to (e.g.) support interchangeability of casing styles (kebab-case -> camelCase -> snake_case -> kebab-case).
|
|
15
15
|
|
|
16
16
|
## Example
|
|
17
17
|
|
|
@@ -48,7 +48,7 @@ const users = await response.json(usersSchema);
|
|
|
48
48
|
- [makeFetcher](#makefetcher)
|
|
49
49
|
- [enhancedFetch](#enhancedfetch)
|
|
50
50
|
- [typedResponse](#typedresponse)
|
|
51
|
-
- [Payload
|
|
51
|
+
- [Transform the Payload](#transform-the-payload)
|
|
52
52
|
- [Other available primitives](#other-available-primitives)
|
|
53
53
|
- [addQueryToURL](#addquerytourl)
|
|
54
54
|
- [ensureStringBody](#ensurestringbody)
|
|
@@ -437,33 +437,27 @@ const text = await response.text(z.string().email())
|
|
|
437
437
|
// ^? string
|
|
438
438
|
```
|
|
439
439
|
|
|
440
|
-
#
|
|
441
|
-
The `make-service`
|
|
440
|
+
# Transform the payload
|
|
441
|
+
The combination of `make-service` and [`string-ts`](https://github.com/gustavoguichard/string-ts) libraries makes it easy to work with APIs that follow a different convention for object key's casing, so you can transform the request body before sending it or the response body after returning from the server.
|
|
442
442
|
The resulting type will be **properly typed** 🤩.
|
|
443
443
|
```ts
|
|
444
|
-
import { makeService
|
|
444
|
+
import { makeService } from 'make-service'
|
|
445
|
+
import { deepCamelKeys, deepKebabKeys } from 'string-ts'
|
|
445
446
|
|
|
446
447
|
const service = makeService("https://example.com/api")
|
|
447
448
|
const response = service.get("/users")
|
|
448
449
|
const users = await response.json(
|
|
449
450
|
z
|
|
450
451
|
.array(z.object({ "first-name": z.string(), contact: z.object({ "home-address": z.string() }) }))
|
|
451
|
-
.transform(
|
|
452
|
+
.transform(deepCamelKeys)
|
|
452
453
|
)
|
|
453
454
|
console.log(users)
|
|
454
455
|
// ^? { firstName: string, contact: { homeAddress: string } }[]
|
|
455
456
|
|
|
456
|
-
const body =
|
|
457
|
+
const body = deepKebabKeys({ firstName: "John", contact: { homeAddress: "123 Main St" } })
|
|
457
458
|
// ^? { "first-name": string, contact: { "home-address": string } }
|
|
458
459
|
service.patch("/users/:id", { body, params: { id: "1" } })
|
|
459
460
|
```
|
|
460
|
-
The available transformations are:
|
|
461
|
-
- `camelToKebab`: `"someProp" -> "some-prop"`
|
|
462
|
-
- `camelToSnake`: `"someProp" -> "some_prop"`
|
|
463
|
-
- `kebabToCamel`: `"some-prop" -> "someProp"`
|
|
464
|
-
- `kebabToSnake`: `"some-prop" -> "some_prop"`
|
|
465
|
-
- `snakeToCamel`: `"some_prop" -> "someProp"`
|
|
466
|
-
- `snakeToKebab`: `"some_prop" -> "some-prop"`
|
|
467
461
|
|
|
468
462
|
# Other available primitives
|
|
469
463
|
This little library has plenty of other useful functions that you can use to build your own services and interactions with external APIs.
|
|
@@ -589,6 +583,7 @@ The params will be **strongly-typed** which means they will be validated against
|
|
|
589
583
|
# Acknowledgements
|
|
590
584
|
This library is part of a code I've been carrying around for a while through many projects.
|
|
591
585
|
|
|
586
|
+
- [Seasoned](https://github.com/seasonedcc) - for backing my work and allowing me testing it on big codebases when I started sketching this API.
|
|
592
587
|
- [croods](https://github.com/seasonedcc/croods) by [@danielweinmann](https://github.com/danielweinmann) - a react data-layer library from pre-ReactQuery/pre-SWR era - gave me ideas and experience dealing with APIs after spending a lot of time in that codebase.
|
|
593
588
|
- [zod](https://zod.dev/) by [@colinhacks](https://github.com/colinhacks) changed my mindset about how to deal with external data.
|
|
594
589
|
- [zod-fetch](https://github.com/mattpocock/zod-fetch) by [@mattpocock](https://github.com/mattpocock) for the inspiration, when I realized I had a similar solution that could be extracted and be available for everyone to use.
|
package/dist/index.d.ts
CHANGED
|
@@ -3,9 +3,9 @@ declare const HTTP_METHODS: readonly ["GET", "POST", "PUT", "DELETE", "PATCH", "
|
|
|
3
3
|
type Schema<T> = {
|
|
4
4
|
parse: (d: unknown) => T;
|
|
5
5
|
};
|
|
6
|
-
type JSONValue = string | number | boolean | {
|
|
7
|
-
[x: string]: JSONValue;
|
|
8
|
-
} | Array<JSONValue>;
|
|
6
|
+
type JSONValue = string | number | boolean | Date | {
|
|
7
|
+
[x: string]: JSONValue | undefined | null;
|
|
8
|
+
} | Array<JSONValue | undefined | null>;
|
|
9
9
|
type SearchParams = ConstructorParameters<typeof URLSearchParams>[0];
|
|
10
10
|
type TypedResponse = Omit<Response, 'json' | 'text'> & {
|
|
11
11
|
json: TypedResponseJson;
|
|
@@ -134,51 +134,11 @@ declare function mergeHeaders(...entries: (HeadersInit | [string, undefined][] |
|
|
|
134
134
|
* @returns the url with the params replaced and with the same type as the given url
|
|
135
135
|
*/
|
|
136
136
|
declare function replaceURLParams<T extends string | URL>(url: T, params: PathParams<T>): T;
|
|
137
|
+
/**
|
|
138
|
+
* This is an enhanced version of the typeof operator to check the type of more complex values.
|
|
139
|
+
* @param t the value to be checked
|
|
140
|
+
* @returns the type of the value
|
|
141
|
+
*/
|
|
142
|
+
declare function typeOf(t: unknown): "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | "url" | "blob" | "array" | "arraybuffer" | "formdata" | "null" | "readablestream" | "urlsearchparams";
|
|
137
143
|
|
|
138
|
-
|
|
139
|
-
type SnakeToCamel<Str> = Str extends `${infer First}_${infer Rest}` ? `${First}${Capitalize<SnakeToCamel<Rest>>}` : Str;
|
|
140
|
-
type KebabToSnake<Str> = Str extends `${infer First}-${infer Rest}` ? `${First}_${KebabToSnake<Rest>}` : Str;
|
|
141
|
-
type SnakeToKebab<Str> = Str extends `${infer First}_${infer Rest}` ? `${First}-${SnakeToKebab<Rest>}` : Str;
|
|
142
|
-
type HandleFirstChar<Str> = Str extends `${infer First}${infer Rest}` ? `${Lowercase<First>}${Rest}` : Str;
|
|
143
|
-
type CamelToSnakeFn<Str> = Str extends `${infer First}${infer Rest}` ? `${First extends Capitalize<First> ? '_' : ''}${Lowercase<First>}${CamelToSnakeFn<Rest>}` : Str;
|
|
144
|
-
type CamelToSnake<Str> = CamelToSnakeFn<HandleFirstChar<Str>>;
|
|
145
|
-
type CamelToKebabFn<Str> = Str extends `${infer First}${infer Rest}` ? `${First extends Capitalize<First> ? '-' : ''}${Lowercase<First>}${CamelToKebabFn<Rest>}` : Str;
|
|
146
|
-
type CamelToKebab<Str> = CamelToKebabFn<HandleFirstChar<Str>>;
|
|
147
|
-
type DeepKebabToCamel<T> = T extends [any, ...any] ? {
|
|
148
|
-
[I in keyof T]: DeepKebabToCamel<T[I]>;
|
|
149
|
-
} : T extends (infer V)[] ? DeepKebabToCamel<V>[] : {
|
|
150
|
-
[K in keyof T as KebabToCamel<K>]: DeepKebabToCamel<T[K]>;
|
|
151
|
-
};
|
|
152
|
-
declare function kebabToCamel<T>(obj: T): DeepKebabToCamel<T>;
|
|
153
|
-
type DeepSnakeToCamel<T> = T extends [any, ...any] ? {
|
|
154
|
-
[I in keyof T]: DeepSnakeToCamel<T[I]>;
|
|
155
|
-
} : T extends (infer V)[] ? DeepSnakeToCamel<V>[] : {
|
|
156
|
-
[K in keyof T as SnakeToCamel<K>]: DeepSnakeToCamel<T[K]>;
|
|
157
|
-
};
|
|
158
|
-
declare function snakeToCamel<T>(obj: T): DeepSnakeToCamel<T>;
|
|
159
|
-
type DeepCamelToSnake<T> = T extends [any, ...any] ? {
|
|
160
|
-
[I in keyof T]: DeepCamelToSnake<T[I]>;
|
|
161
|
-
} : T extends (infer V)[] ? DeepCamelToSnake<V>[] : {
|
|
162
|
-
[K in keyof T as CamelToSnake<K>]: DeepCamelToSnake<T[K]>;
|
|
163
|
-
};
|
|
164
|
-
declare function camelToSnake<T>(obj: T): DeepCamelToSnake<T>;
|
|
165
|
-
type DeepCamelToKebab<T> = T extends [any, ...any] ? {
|
|
166
|
-
[I in keyof T]: DeepCamelToKebab<T[I]>;
|
|
167
|
-
} : T extends (infer V)[] ? DeepCamelToKebab<V>[] : {
|
|
168
|
-
[K in keyof T as CamelToKebab<K>]: DeepCamelToKebab<T[K]>;
|
|
169
|
-
};
|
|
170
|
-
declare function camelToKebab<T>(obj: T): DeepCamelToKebab<T>;
|
|
171
|
-
type DeepSnakeToKebab<T> = T extends [any, ...any] ? {
|
|
172
|
-
[I in keyof T]: DeepSnakeToKebab<T[I]>;
|
|
173
|
-
} : T extends (infer V)[] ? DeepSnakeToKebab<V>[] : {
|
|
174
|
-
[K in keyof T as SnakeToKebab<K>]: DeepSnakeToKebab<T[K]>;
|
|
175
|
-
};
|
|
176
|
-
declare function snakeToKebab<T>(obj: T): DeepSnakeToKebab<T>;
|
|
177
|
-
type DeepKebabToSnake<T> = T extends [any, ...any] ? {
|
|
178
|
-
[I in keyof T]: DeepKebabToSnake<T[I]>;
|
|
179
|
-
} : T extends (infer V)[] ? DeepKebabToSnake<V>[] : {
|
|
180
|
-
[K in keyof T as KebabToSnake<K>]: DeepKebabToSnake<T[K]>;
|
|
181
|
-
};
|
|
182
|
-
declare function kebabToSnake<T>(obj: T): DeepKebabToSnake<T>;
|
|
183
|
-
|
|
184
|
-
export { BaseOptions, CamelToKebab, CamelToSnake, DeepCamelToKebab, DeepCamelToSnake, DeepKebabToCamel, DeepKebabToSnake, DeepSnakeToCamel, DeepSnakeToKebab, EnhancedRequestInit, GetJson, GetText, HTTPMethod, JSONValue, KebabToCamel, KebabToSnake, PathParams, RequestTransformer, ResponseTransformer, Schema, SearchParams, ServiceRequestInit, SnakeToCamel, SnakeToKebab, TypedResponse, TypedResponseJson, TypedResponseText, addQueryToURL, camelToKebab, camelToSnake, enhancedFetch, ensureStringBody, kebabToCamel, kebabToSnake, makeFetcher, makeGetApiURL, makeService, mergeHeaders, replaceURLParams, snakeToCamel, snakeToKebab, typedResponse };
|
|
144
|
+
export { BaseOptions, EnhancedRequestInit, GetJson, GetText, HTTPMethod, JSONValue, PathParams, RequestTransformer, ResponseTransformer, Schema, SearchParams, ServiceRequestInit, TypedResponse, TypedResponseJson, TypedResponseText, addQueryToURL, enhancedFetch, ensureStringBody, makeFetcher, makeGetApiURL, makeService, mergeHeaders, replaceURLParams, typeOf, typedResponse };
|
package/dist/index.js
CHANGED
|
@@ -21,19 +21,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
23
|
addQueryToURL: () => addQueryToURL,
|
|
24
|
-
camelToKebab: () => camelToKebab,
|
|
25
|
-
camelToSnake: () => camelToSnake,
|
|
26
24
|
enhancedFetch: () => enhancedFetch,
|
|
27
25
|
ensureStringBody: () => ensureStringBody,
|
|
28
|
-
kebabToCamel: () => kebabToCamel,
|
|
29
|
-
kebabToSnake: () => kebabToSnake,
|
|
30
26
|
makeFetcher: () => makeFetcher,
|
|
31
27
|
makeGetApiURL: () => makeGetApiURL,
|
|
32
28
|
makeService: () => makeService,
|
|
33
29
|
mergeHeaders: () => mergeHeaders,
|
|
34
30
|
replaceURLParams: () => replaceURLParams,
|
|
35
|
-
|
|
36
|
-
snakeToKebab: () => snakeToKebab,
|
|
31
|
+
typeOf: () => typeOf,
|
|
37
32
|
typedResponse: () => typedResponse
|
|
38
33
|
});
|
|
39
34
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -60,9 +55,6 @@ var getText = (response) => async (schema) => {
|
|
|
60
55
|
const text = await response.text();
|
|
61
56
|
return schema ? schema.parse(text) : text;
|
|
62
57
|
};
|
|
63
|
-
function typeOf(t) {
|
|
64
|
-
return Object.prototype.toString.call(t).replace(/^\[object (.+)\]$/, "$1").toLowerCase();
|
|
65
|
-
}
|
|
66
58
|
|
|
67
59
|
// src/primitives.ts
|
|
68
60
|
function addQueryToURL(url, searchParams) {
|
|
@@ -73,9 +65,7 @@ function addQueryToURL(url, searchParams) {
|
|
|
73
65
|
return `${url}${separator}${new URLSearchParams(searchParams)}`;
|
|
74
66
|
}
|
|
75
67
|
if (searchParams && url instanceof URL) {
|
|
76
|
-
for (const [key, value] of
|
|
77
|
-
new URLSearchParams(searchParams)
|
|
78
|
-
)) {
|
|
68
|
+
for (const [key, value] of new URLSearchParams(searchParams).entries()) {
|
|
79
69
|
url.searchParams.set(key, value);
|
|
80
70
|
}
|
|
81
71
|
}
|
|
@@ -118,6 +108,9 @@ function replaceURLParams(url, params) {
|
|
|
118
108
|
});
|
|
119
109
|
return url instanceof URL ? new URL(urlString) : urlString;
|
|
120
110
|
}
|
|
111
|
+
function typeOf(t) {
|
|
112
|
+
return Object.prototype.toString.call(t).replace(/^\[object (.+)\]$/, "$1").toLowerCase();
|
|
113
|
+
}
|
|
121
114
|
|
|
122
115
|
// src/api.ts
|
|
123
116
|
var identity = (value) => value;
|
|
@@ -181,76 +174,23 @@ function makeService(baseURL, baseOptions) {
|
|
|
181
174
|
function appliedService(method) {
|
|
182
175
|
return async (path, requestInit = {}) => fetcher(path, { ...requestInit, method });
|
|
183
176
|
}
|
|
184
|
-
|
|
177
|
+
const service = {};
|
|
185
178
|
for (const method of HTTP_METHODS) {
|
|
186
179
|
const lowerMethod = method.toLowerCase();
|
|
187
180
|
service[lowerMethod] = appliedService(method);
|
|
188
181
|
}
|
|
189
182
|
return service;
|
|
190
183
|
}
|
|
191
|
-
|
|
192
|
-
// src/transforms.ts
|
|
193
|
-
function words(str) {
|
|
194
|
-
const matches = str.match(
|
|
195
|
-
/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g
|
|
196
|
-
);
|
|
197
|
-
return matches ? Array.from(matches) : [str];
|
|
198
|
-
}
|
|
199
|
-
function toCamelCase(str) {
|
|
200
|
-
const result = words(str).map((x) => x.slice(0, 1).toUpperCase() + x.slice(1).toLowerCase()).join("");
|
|
201
|
-
return result.slice(0, 1).toLowerCase() + result.slice(1);
|
|
202
|
-
}
|
|
203
|
-
function toKebabCase(str) {
|
|
204
|
-
return words(str).map((x) => x.toLowerCase()).join("-");
|
|
205
|
-
}
|
|
206
|
-
function toSnakeCase(str) {
|
|
207
|
-
return words(str).map((x) => x.toLowerCase()).join("_");
|
|
208
|
-
}
|
|
209
|
-
function deepTransformKeys(obj, transform) {
|
|
210
|
-
if (!["object", "array"].includes(typeOf(obj)))
|
|
211
|
-
return obj;
|
|
212
|
-
if (Array.isArray(obj)) {
|
|
213
|
-
return obj.map((x) => deepTransformKeys(x, transform));
|
|
214
|
-
}
|
|
215
|
-
const res = {};
|
|
216
|
-
for (const key in obj) {
|
|
217
|
-
res[transform(key)] = deepTransformKeys(obj[key], transform);
|
|
218
|
-
}
|
|
219
|
-
return res;
|
|
220
|
-
}
|
|
221
|
-
function kebabToCamel(obj) {
|
|
222
|
-
return deepTransformKeys(obj, toCamelCase);
|
|
223
|
-
}
|
|
224
|
-
function snakeToCamel(obj) {
|
|
225
|
-
return deepTransformKeys(obj, toCamelCase);
|
|
226
|
-
}
|
|
227
|
-
function camelToSnake(obj) {
|
|
228
|
-
return deepTransformKeys(obj, toSnakeCase);
|
|
229
|
-
}
|
|
230
|
-
function camelToKebab(obj) {
|
|
231
|
-
return deepTransformKeys(obj, toKebabCase);
|
|
232
|
-
}
|
|
233
|
-
function snakeToKebab(obj) {
|
|
234
|
-
return deepTransformKeys(obj, toKebabCase);
|
|
235
|
-
}
|
|
236
|
-
function kebabToSnake(obj) {
|
|
237
|
-
return deepTransformKeys(obj, toSnakeCase);
|
|
238
|
-
}
|
|
239
184
|
// Annotate the CommonJS export names for ESM import in node:
|
|
240
185
|
0 && (module.exports = {
|
|
241
186
|
addQueryToURL,
|
|
242
|
-
camelToKebab,
|
|
243
|
-
camelToSnake,
|
|
244
187
|
enhancedFetch,
|
|
245
188
|
ensureStringBody,
|
|
246
|
-
kebabToCamel,
|
|
247
|
-
kebabToSnake,
|
|
248
189
|
makeFetcher,
|
|
249
190
|
makeGetApiURL,
|
|
250
191
|
makeService,
|
|
251
192
|
mergeHeaders,
|
|
252
193
|
replaceURLParams,
|
|
253
|
-
|
|
254
|
-
snakeToKebab,
|
|
194
|
+
typeOf,
|
|
255
195
|
typedResponse
|
|
256
196
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -20,9 +20,6 @@ var getText = (response) => async (schema) => {
|
|
|
20
20
|
const text = await response.text();
|
|
21
21
|
return schema ? schema.parse(text) : text;
|
|
22
22
|
};
|
|
23
|
-
function typeOf(t) {
|
|
24
|
-
return Object.prototype.toString.call(t).replace(/^\[object (.+)\]$/, "$1").toLowerCase();
|
|
25
|
-
}
|
|
26
23
|
|
|
27
24
|
// src/primitives.ts
|
|
28
25
|
function addQueryToURL(url, searchParams) {
|
|
@@ -33,9 +30,7 @@ function addQueryToURL(url, searchParams) {
|
|
|
33
30
|
return `${url}${separator}${new URLSearchParams(searchParams)}`;
|
|
34
31
|
}
|
|
35
32
|
if (searchParams && url instanceof URL) {
|
|
36
|
-
for (const [key, value] of
|
|
37
|
-
new URLSearchParams(searchParams)
|
|
38
|
-
)) {
|
|
33
|
+
for (const [key, value] of new URLSearchParams(searchParams).entries()) {
|
|
39
34
|
url.searchParams.set(key, value);
|
|
40
35
|
}
|
|
41
36
|
}
|
|
@@ -78,6 +73,9 @@ function replaceURLParams(url, params) {
|
|
|
78
73
|
});
|
|
79
74
|
return url instanceof URL ? new URL(urlString) : urlString;
|
|
80
75
|
}
|
|
76
|
+
function typeOf(t) {
|
|
77
|
+
return Object.prototype.toString.call(t).replace(/^\[object (.+)\]$/, "$1").toLowerCase();
|
|
78
|
+
}
|
|
81
79
|
|
|
82
80
|
// src/api.ts
|
|
83
81
|
var identity = (value) => value;
|
|
@@ -141,75 +139,22 @@ function makeService(baseURL, baseOptions) {
|
|
|
141
139
|
function appliedService(method) {
|
|
142
140
|
return async (path, requestInit = {}) => fetcher(path, { ...requestInit, method });
|
|
143
141
|
}
|
|
144
|
-
|
|
142
|
+
const service = {};
|
|
145
143
|
for (const method of HTTP_METHODS) {
|
|
146
144
|
const lowerMethod = method.toLowerCase();
|
|
147
145
|
service[lowerMethod] = appliedService(method);
|
|
148
146
|
}
|
|
149
147
|
return service;
|
|
150
148
|
}
|
|
151
|
-
|
|
152
|
-
// src/transforms.ts
|
|
153
|
-
function words(str) {
|
|
154
|
-
const matches = str.match(
|
|
155
|
-
/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g
|
|
156
|
-
);
|
|
157
|
-
return matches ? Array.from(matches) : [str];
|
|
158
|
-
}
|
|
159
|
-
function toCamelCase(str) {
|
|
160
|
-
const result = words(str).map((x) => x.slice(0, 1).toUpperCase() + x.slice(1).toLowerCase()).join("");
|
|
161
|
-
return result.slice(0, 1).toLowerCase() + result.slice(1);
|
|
162
|
-
}
|
|
163
|
-
function toKebabCase(str) {
|
|
164
|
-
return words(str).map((x) => x.toLowerCase()).join("-");
|
|
165
|
-
}
|
|
166
|
-
function toSnakeCase(str) {
|
|
167
|
-
return words(str).map((x) => x.toLowerCase()).join("_");
|
|
168
|
-
}
|
|
169
|
-
function deepTransformKeys(obj, transform) {
|
|
170
|
-
if (!["object", "array"].includes(typeOf(obj)))
|
|
171
|
-
return obj;
|
|
172
|
-
if (Array.isArray(obj)) {
|
|
173
|
-
return obj.map((x) => deepTransformKeys(x, transform));
|
|
174
|
-
}
|
|
175
|
-
const res = {};
|
|
176
|
-
for (const key in obj) {
|
|
177
|
-
res[transform(key)] = deepTransformKeys(obj[key], transform);
|
|
178
|
-
}
|
|
179
|
-
return res;
|
|
180
|
-
}
|
|
181
|
-
function kebabToCamel(obj) {
|
|
182
|
-
return deepTransformKeys(obj, toCamelCase);
|
|
183
|
-
}
|
|
184
|
-
function snakeToCamel(obj) {
|
|
185
|
-
return deepTransformKeys(obj, toCamelCase);
|
|
186
|
-
}
|
|
187
|
-
function camelToSnake(obj) {
|
|
188
|
-
return deepTransformKeys(obj, toSnakeCase);
|
|
189
|
-
}
|
|
190
|
-
function camelToKebab(obj) {
|
|
191
|
-
return deepTransformKeys(obj, toKebabCase);
|
|
192
|
-
}
|
|
193
|
-
function snakeToKebab(obj) {
|
|
194
|
-
return deepTransformKeys(obj, toKebabCase);
|
|
195
|
-
}
|
|
196
|
-
function kebabToSnake(obj) {
|
|
197
|
-
return deepTransformKeys(obj, toSnakeCase);
|
|
198
|
-
}
|
|
199
149
|
export {
|
|
200
150
|
addQueryToURL,
|
|
201
|
-
camelToKebab,
|
|
202
|
-
camelToSnake,
|
|
203
151
|
enhancedFetch,
|
|
204
152
|
ensureStringBody,
|
|
205
|
-
kebabToCamel,
|
|
206
|
-
kebabToSnake,
|
|
207
153
|
makeFetcher,
|
|
208
154
|
makeGetApiURL,
|
|
209
155
|
makeService,
|
|
210
156
|
mergeHeaders,
|
|
211
157
|
replaceURLParams,
|
|
212
|
-
|
|
213
|
-
snakeToKebab,
|
|
158
|
+
typeOf,
|
|
214
159
|
typedResponse
|
|
215
160
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "make-service",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Some utilities to extend the 'fetch' API to better interact with external APIs.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -15,9 +15,11 @@
|
|
|
15
15
|
"test": "vitest run"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
|
+
"@typescript-eslint/eslint-plugin": "^6.3.0",
|
|
18
19
|
"eslint": "latest",
|
|
19
20
|
"jsdom": "^22.1.0",
|
|
20
21
|
"prettier": "latest",
|
|
22
|
+
"string-ts": "^0.4.1",
|
|
21
23
|
"tsup": "^6.7.0",
|
|
22
24
|
"typescript": "^5.1.3",
|
|
23
25
|
"vitest": "latest",
|