floppy-disk 2.9.0 → 2.10.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/index.d.ts +1 -0
- package/esm/index.js +1 -0
- package/esm/utils/fetcher.d.ts +16 -0
- package/esm/utils/fetcher.js +69 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/utils/fetcher.d.ts +16 -0
- package/lib/utils/fetcher.js +73 -0
- package/package.json +1 -1
package/esm/index.d.ts
CHANGED
package/esm/index.js
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
type FetcherOptions<TResponse = any> = {
|
|
2
|
+
url: string;
|
|
3
|
+
query?: string;
|
|
4
|
+
params?: Record<string, string | number | boolean> | null;
|
|
5
|
+
payload?: any;
|
|
6
|
+
validate?: (response: TResponse) => void | Promise<void>;
|
|
7
|
+
} & RequestInit;
|
|
8
|
+
/**
|
|
9
|
+
* Experimental fetcher - a query/mutation function creator.
|
|
10
|
+
*
|
|
11
|
+
* Can be used for REST or GraphQL.
|
|
12
|
+
*
|
|
13
|
+
* @returns A function to fetch data
|
|
14
|
+
*/
|
|
15
|
+
export declare const fetcher: <TResponse = any, TInput extends any[] = any[]>(options: FetcherOptions<TResponse> | ((...args: TInput) => FetcherOptions<TResponse>)) => (...args: TInput) => Promise<TResponse>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/* eslint-disable no-throw-literal */
|
|
2
|
+
import { getValueOrComputedValue } from '.';
|
|
3
|
+
const encodeParams = (params) => Object.entries(params)
|
|
4
|
+
.map((kv) => kv.map(encodeURIComponent).join('='))
|
|
5
|
+
.join('&');
|
|
6
|
+
/**
|
|
7
|
+
* Experimental fetcher - a query/mutation function creator.
|
|
8
|
+
*
|
|
9
|
+
* Can be used for REST or GraphQL.
|
|
10
|
+
*
|
|
11
|
+
* @returns A function to fetch data
|
|
12
|
+
*/
|
|
13
|
+
export const fetcher = (options) => async (...args) => {
|
|
14
|
+
const { url, query, params, payload, headers, validate, ...rest } = getValueOrComputedValue(options, ...args);
|
|
15
|
+
let autoOptions = {};
|
|
16
|
+
let searchParams = params;
|
|
17
|
+
if (query) {
|
|
18
|
+
// GraphQL
|
|
19
|
+
autoOptions = {
|
|
20
|
+
method: 'POST',
|
|
21
|
+
body: JSON.stringify({ query, variables: payload || args[0] }),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
else if (rest.method && rest.method.toLowerCase() !== 'get') {
|
|
25
|
+
// REST - Mutation
|
|
26
|
+
autoOptions = {
|
|
27
|
+
body: JSON.stringify(payload === undefined ? args[0] : payload),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
// REST - Query
|
|
32
|
+
if (typeof options === 'object' && params === undefined)
|
|
33
|
+
searchParams = args[0];
|
|
34
|
+
}
|
|
35
|
+
const fetchUrl = searchParams ? [url, encodeParams(searchParams)].join('?') : url;
|
|
36
|
+
const res = await fetch(fetchUrl, {
|
|
37
|
+
headers: { 'Content-Type': 'application/json', ...headers },
|
|
38
|
+
...autoOptions,
|
|
39
|
+
...rest,
|
|
40
|
+
});
|
|
41
|
+
const contentType = res.headers.get('content-type');
|
|
42
|
+
if (contentType && contentType.includes('application/json')) {
|
|
43
|
+
const resJson = await res.json().catch(() => undefined);
|
|
44
|
+
if (resJson !== undefined) {
|
|
45
|
+
if (query && resJson.errors) {
|
|
46
|
+
throw { status: res.status, statusText: res.statusText, response: resJson };
|
|
47
|
+
}
|
|
48
|
+
if (res.ok) {
|
|
49
|
+
if (validate) {
|
|
50
|
+
try {
|
|
51
|
+
await validate(resJson);
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
throw {
|
|
55
|
+
status: res.status,
|
|
56
|
+
statusText: res.statusText,
|
|
57
|
+
response: resJson,
|
|
58
|
+
validationError: err,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return resJson;
|
|
63
|
+
}
|
|
64
|
+
throw { status: res.status, statusText: res.statusText, response: resJson };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const resText = await res.text().catch(() => undefined);
|
|
68
|
+
throw { status: res.status, statusText: res.statusText, response: resText };
|
|
69
|
+
};
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -4,5 +4,6 @@ exports.hashStoreKey = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
var utils_1 = require("./utils");
|
|
6
6
|
Object.defineProperty(exports, "hashStoreKey", { enumerable: true, get: function () { return utils_1.hashStoreKey; } });
|
|
7
|
+
tslib_1.__exportStar(require("./utils/fetcher"), exports);
|
|
7
8
|
tslib_1.__exportStar(require("./vanilla"), exports);
|
|
8
9
|
tslib_1.__exportStar(require("./react"), exports);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
type FetcherOptions<TResponse = any> = {
|
|
2
|
+
url: string;
|
|
3
|
+
query?: string;
|
|
4
|
+
params?: Record<string, string | number | boolean> | null;
|
|
5
|
+
payload?: any;
|
|
6
|
+
validate?: (response: TResponse) => void | Promise<void>;
|
|
7
|
+
} & RequestInit;
|
|
8
|
+
/**
|
|
9
|
+
* Experimental fetcher - a query/mutation function creator.
|
|
10
|
+
*
|
|
11
|
+
* Can be used for REST or GraphQL.
|
|
12
|
+
*
|
|
13
|
+
* @returns A function to fetch data
|
|
14
|
+
*/
|
|
15
|
+
export declare const fetcher: <TResponse = any, TInput extends any[] = any[]>(options: FetcherOptions<TResponse> | ((...args: TInput) => FetcherOptions<TResponse>)) => (...args: TInput) => Promise<TResponse>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetcher = void 0;
|
|
4
|
+
/* eslint-disable no-throw-literal */
|
|
5
|
+
const _1 = require(".");
|
|
6
|
+
const encodeParams = (params) => Object.entries(params)
|
|
7
|
+
.map((kv) => kv.map(encodeURIComponent).join('='))
|
|
8
|
+
.join('&');
|
|
9
|
+
/**
|
|
10
|
+
* Experimental fetcher - a query/mutation function creator.
|
|
11
|
+
*
|
|
12
|
+
* Can be used for REST or GraphQL.
|
|
13
|
+
*
|
|
14
|
+
* @returns A function to fetch data
|
|
15
|
+
*/
|
|
16
|
+
const fetcher = (options) => async (...args) => {
|
|
17
|
+
const { url, query, params, payload, headers, validate, ...rest } = (0, _1.getValueOrComputedValue)(options, ...args);
|
|
18
|
+
let autoOptions = {};
|
|
19
|
+
let searchParams = params;
|
|
20
|
+
if (query) {
|
|
21
|
+
// GraphQL
|
|
22
|
+
autoOptions = {
|
|
23
|
+
method: 'POST',
|
|
24
|
+
body: JSON.stringify({ query, variables: payload || args[0] }),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
else if (rest.method && rest.method.toLowerCase() !== 'get') {
|
|
28
|
+
// REST - Mutation
|
|
29
|
+
autoOptions = {
|
|
30
|
+
body: JSON.stringify(payload === undefined ? args[0] : payload),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
// REST - Query
|
|
35
|
+
if (typeof options === 'object' && params === undefined)
|
|
36
|
+
searchParams = args[0];
|
|
37
|
+
}
|
|
38
|
+
const fetchUrl = searchParams ? [url, encodeParams(searchParams)].join('?') : url;
|
|
39
|
+
const res = await fetch(fetchUrl, {
|
|
40
|
+
headers: { 'Content-Type': 'application/json', ...headers },
|
|
41
|
+
...autoOptions,
|
|
42
|
+
...rest,
|
|
43
|
+
});
|
|
44
|
+
const contentType = res.headers.get('content-type');
|
|
45
|
+
if (contentType && contentType.includes('application/json')) {
|
|
46
|
+
const resJson = await res.json().catch(() => undefined);
|
|
47
|
+
if (resJson !== undefined) {
|
|
48
|
+
if (query && resJson.errors) {
|
|
49
|
+
throw { status: res.status, statusText: res.statusText, response: resJson };
|
|
50
|
+
}
|
|
51
|
+
if (res.ok) {
|
|
52
|
+
if (validate) {
|
|
53
|
+
try {
|
|
54
|
+
await validate(resJson);
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
throw {
|
|
58
|
+
status: res.status,
|
|
59
|
+
statusText: res.statusText,
|
|
60
|
+
response: resJson,
|
|
61
|
+
validationError: err,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return resJson;
|
|
66
|
+
}
|
|
67
|
+
throw { status: res.status, statusText: res.statusText, response: resJson };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const resText = await res.text().catch(() => undefined);
|
|
71
|
+
throw { status: res.status, statusText: res.statusText, response: resText };
|
|
72
|
+
};
|
|
73
|
+
exports.fetcher = fetcher;
|