@koine/api 2.0.0-beta.2 → 2.0.0-beta.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/ApiError.js +25 -16
- package/ApiError.mjs +6 -12
- package/createApi.js +136 -142
- package/createApi.mjs +115 -131
- package/createSwrApi.d.ts +2 -1
- package/createSwrApi.js +65 -57
- package/createSwrApi.mjs +42 -47
- package/index.js +27 -10
- package/nextApiResponse.js +19 -5
- package/nextApiResponse.mjs +1 -1
- package/package.json +14 -11
package/ApiError.js
CHANGED
|
@@ -1,23 +1,32 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ApiError = void 0;
|
|
4
|
-
var tslib_1 = require("tslib");
|
|
5
1
|
/**
|
|
6
2
|
* Custom `ApiError` class extending `Error` to throw in failed response.
|
|
7
3
|
*
|
|
8
4
|
* @see https://eslint.org/docs/rules/no-throw-literal
|
|
9
5
|
* @see https://github.com/sindresorhus/ky/blob/main/source/errors/HTTPError.ts
|
|
10
6
|
*
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
7
|
+
*/ "use strict";
|
|
8
|
+
Object.defineProperty(exports, "__esModule", {
|
|
9
|
+
value: true
|
|
10
|
+
});
|
|
11
|
+
function _export(target, all) {
|
|
12
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: all[name]
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
_export(exports, {
|
|
18
|
+
ApiError: function() {
|
|
19
|
+
return ApiError;
|
|
20
|
+
},
|
|
21
|
+
default: function() {
|
|
22
|
+
return _default;
|
|
19
23
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
});
|
|
25
|
+
let ApiError = class ApiError extends Error {
|
|
26
|
+
constructor(result){
|
|
27
|
+
super(`Request failed with ${result.status} ${result.msg}`);
|
|
28
|
+
this.name = "ApiError";
|
|
29
|
+
Object.assign(this, result);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const _default = ApiError;
|
package/ApiError.mjs
CHANGED
|
@@ -1,20 +1,14 @@
|
|
|
1
|
-
import { __extends } from "tslib";
|
|
2
1
|
/**
|
|
3
2
|
* Custom `ApiError` class extending `Error` to throw in failed response.
|
|
4
3
|
*
|
|
5
4
|
* @see https://eslint.org/docs/rules/no-throw-literal
|
|
6
5
|
* @see https://github.com/sindresorhus/ky/blob/main/source/errors/HTTPError.ts
|
|
7
6
|
*
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
_this.name = "ApiError";
|
|
14
|
-
Object.assign(_this, result);
|
|
15
|
-
return _this;
|
|
7
|
+
*/ export class ApiError extends Error {
|
|
8
|
+
constructor(result){
|
|
9
|
+
super(`Request failed with ${result.status} ${result.msg}`);
|
|
10
|
+
this.name = "ApiError";
|
|
11
|
+
Object.assign(this, result);
|
|
16
12
|
}
|
|
17
|
-
|
|
18
|
-
}(Error));
|
|
19
|
-
export { ApiError };
|
|
13
|
+
}
|
|
20
14
|
export default ApiError;
|
package/createApi.js
CHANGED
|
@@ -1,148 +1,142 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
var
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: all[name]
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
createApi: function() {
|
|
13
|
+
return createApi;
|
|
14
|
+
},
|
|
15
|
+
default: function() {
|
|
16
|
+
return _default;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
|
|
20
|
+
const _buildUrlQueryString = /*#__PURE__*/ _interop_require_default._(require("@koine/utils/buildUrlQueryString"));
|
|
21
|
+
const _errorToString = /*#__PURE__*/ _interop_require_default._(require("@koine/utils/errorToString"));
|
|
22
|
+
const _isFullObject = /*#__PURE__*/ _interop_require_default._(require("@koine/utils/isFullObject"));
|
|
23
|
+
const createApi = (apiName, baseUrl, options)=>{
|
|
24
|
+
const { headers: headersBase = {}, request: requestBase = {
|
|
25
|
+
referrerPolicy: "no-referrer"
|
|
26
|
+
}, throwErr: throwErrBase, timeout: timeoutBase = 10000, processReq: processReqBase, processRes: processResBase, processErr: processErrBase } = options || {};
|
|
27
|
+
return [
|
|
28
|
+
"get",
|
|
29
|
+
"post",
|
|
30
|
+
"put",
|
|
31
|
+
"patch",
|
|
32
|
+
"delete"
|
|
33
|
+
].reduce((api, method)=>{
|
|
23
34
|
// @ts-expect-error FIXME: type
|
|
24
|
-
api[method] =
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
transformed = processReqBase(method, url, query, json, params, requestInit);
|
|
35
|
-
url = transformed[0];
|
|
36
|
-
query = transformed[1];
|
|
37
|
-
json = transformed[2];
|
|
38
|
-
params = transformed[3];
|
|
39
|
-
requestInit = transformed[4];
|
|
40
|
-
}
|
|
41
|
-
if (processReq) {
|
|
42
|
-
transformed = processReq(method, url, query, json, params, requestInit);
|
|
43
|
-
url = transformed[0];
|
|
44
|
-
query = transformed[1];
|
|
45
|
-
json = transformed[2];
|
|
46
|
-
params = transformed[3];
|
|
47
|
-
requestInit = transformed[4];
|
|
48
|
-
}
|
|
49
|
-
if ((0, isFullObject_1.default)(params)) {
|
|
50
|
-
for (key in params) {
|
|
51
|
-
url = url.replace("{".concat(key, "}"), params[key].toString());
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
timeoutNumber = Number(timeout);
|
|
55
|
-
if (json) {
|
|
56
|
-
requestInit.body = JSON.stringify(json);
|
|
57
|
-
}
|
|
58
|
-
if (timeoutNumber > 0) {
|
|
59
|
-
controller = new AbortController();
|
|
60
|
-
timeoutId = setTimeout(function () { return controller.abort(); }, timeoutNumber);
|
|
61
|
-
requestInit.signal = controller.signal;
|
|
62
|
-
}
|
|
63
|
-
if (query) {
|
|
64
|
-
// FIXME: ts-expect-error this assertion is not the best, but nevermind for now
|
|
65
|
-
url += (0, buildUrlQueryString_1.default)(query);
|
|
66
|
-
}
|
|
67
|
-
response = null;
|
|
68
|
-
result = null;
|
|
69
|
-
msg = "";
|
|
70
|
-
_j.label = 1;
|
|
71
|
-
case 1:
|
|
72
|
-
_j.trys.push([1, 3, , 4]);
|
|
73
|
-
return [4 /*yield*/, fetch(url, requestInit)];
|
|
74
|
-
case 2:
|
|
75
|
-
response = _j.sent();
|
|
76
|
-
return [3 /*break*/, 4];
|
|
77
|
-
case 3:
|
|
78
|
-
e_1 = _j.sent();
|
|
79
|
-
msg = (0, errorToString_1.default)(e_1);
|
|
80
|
-
return [3 /*break*/, 4];
|
|
81
|
-
case 4:
|
|
82
|
-
if (timeoutId) {
|
|
83
|
-
clearTimeout(timeoutId);
|
|
84
|
-
}
|
|
85
|
-
if (!response) return [3 /*break*/, 11];
|
|
86
|
-
_j.label = 5;
|
|
87
|
-
case 5:
|
|
88
|
-
_j.trys.push([5, 10, , 11]);
|
|
89
|
-
if (!processRes) return [3 /*break*/, 7];
|
|
90
|
-
return [4 /*yield*/, processRes(response, options || {})];
|
|
91
|
-
case 6:
|
|
92
|
-
result = _j.sent();
|
|
93
|
-
return [3 /*break*/, 9];
|
|
94
|
-
case 7: return [4 /*yield*/, response.json()];
|
|
95
|
-
case 8:
|
|
96
|
-
result = _j.sent();
|
|
97
|
-
_j.label = 9;
|
|
98
|
-
case 9: return [3 /*break*/, 11];
|
|
99
|
-
case 10:
|
|
100
|
-
e_2 = _j.sent();
|
|
101
|
-
msg = (0, errorToString_1.default)(e_2);
|
|
102
|
-
return [3 /*break*/, 11];
|
|
103
|
-
case 11:
|
|
104
|
-
if (!(result === null)) return [3 /*break*/, 14];
|
|
105
|
-
if (!processErr) return [3 /*break*/, 13];
|
|
106
|
-
return [4 /*yield*/, processErr(msg, options || {})];
|
|
107
|
-
case 12:
|
|
108
|
-
result = _j.sent();
|
|
109
|
-
return [3 /*break*/, 14];
|
|
110
|
-
case 13:
|
|
111
|
-
// this error should only happen on network errors or wrong API urls
|
|
112
|
-
// there is no specific HTTP error for this, we can consider these
|
|
113
|
-
// two statuses though:
|
|
114
|
-
// - [100 Continue](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/100)
|
|
115
|
-
// - [501 Not Implemented](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/501)
|
|
116
|
-
result = {
|
|
117
|
-
data: null,
|
|
118
|
-
msg: msg,
|
|
119
|
-
status: 100,
|
|
120
|
-
fail: true,
|
|
121
|
-
ok: false,
|
|
122
|
-
};
|
|
123
|
-
_j.label = 14;
|
|
124
|
-
case 14:
|
|
125
|
-
if (throwErr && (result === null || result === void 0 ? void 0 : result.fail)) {
|
|
126
|
-
// throw new ApiError<Failed>(result);
|
|
127
|
-
// I prefer to throw an object literal despite what eslint says
|
|
128
|
-
// eslint-disable-next-line no-throw-literal
|
|
129
|
-
throw result;
|
|
130
|
-
}
|
|
131
|
-
if (process.env["NODE_ENV"] !== "production") {
|
|
132
|
-
logMsg = "".concat(result === null || result === void 0 ? void 0 : result.status, ": api[").concat(apiName, "] ").concat(method.toUpperCase(), " ").concat(url);
|
|
133
|
-
if (result === null || result === void 0 ? void 0 : result.ok) {
|
|
134
|
-
console.info("\uD83D\uDFE2 ".concat(logMsg));
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
console.info("\uD83D\uDD34 ".concat(logMsg));
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
return [2 /*return*/, result];
|
|
35
|
+
api[method] = async (endpoint, options)=>{
|
|
36
|
+
const { request = requestBase, headers = headersBase, timeout = timeoutBase, processReq, processRes = processResBase, processErr = processErrBase, throwErr = throwErrBase } = options || {};
|
|
37
|
+
let { params, json, query } = options || {};
|
|
38
|
+
let url = `${baseUrl}/${endpoint + "".replace(/^\/*/, "")}`;
|
|
39
|
+
let requestInit = {
|
|
40
|
+
method: method.toUpperCase(),
|
|
41
|
+
...request,
|
|
42
|
+
headers: {
|
|
43
|
+
"content-type": "application/json",
|
|
44
|
+
...headers
|
|
141
45
|
}
|
|
142
|
-
}
|
|
143
|
-
|
|
46
|
+
};
|
|
47
|
+
if (processReqBase) {
|
|
48
|
+
const transformed = processReqBase(method, url, query, json, params, requestInit);
|
|
49
|
+
url = transformed[0];
|
|
50
|
+
query = transformed[1];
|
|
51
|
+
json = transformed[2];
|
|
52
|
+
params = transformed[3];
|
|
53
|
+
requestInit = transformed[4];
|
|
54
|
+
}
|
|
55
|
+
if (processReq) {
|
|
56
|
+
const transformed = processReq(method, url, query, json, params, requestInit);
|
|
57
|
+
url = transformed[0];
|
|
58
|
+
query = transformed[1];
|
|
59
|
+
json = transformed[2];
|
|
60
|
+
params = transformed[3];
|
|
61
|
+
requestInit = transformed[4];
|
|
62
|
+
}
|
|
63
|
+
if ((0, _isFullObject.default)(params)) {
|
|
64
|
+
for(const key in params){
|
|
65
|
+
url = url.replace(`{${key}}`, params[key].toString());
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const timeoutNumber = Number(timeout);
|
|
69
|
+
let controller;
|
|
70
|
+
let timeoutId;
|
|
71
|
+
if (json) {
|
|
72
|
+
requestInit.body = JSON.stringify(json);
|
|
73
|
+
}
|
|
74
|
+
if (timeoutNumber > 0) {
|
|
75
|
+
controller = new AbortController();
|
|
76
|
+
timeoutId = setTimeout(()=>controller.abort(), timeoutNumber);
|
|
77
|
+
requestInit.signal = controller.signal;
|
|
78
|
+
}
|
|
79
|
+
if (query) {
|
|
80
|
+
// FIXME: ts-expect-error this assertion is not the best, but nevermind for now
|
|
81
|
+
url += (0, _buildUrlQueryString.default)(query);
|
|
82
|
+
}
|
|
83
|
+
let response = null;
|
|
84
|
+
let result = null;
|
|
85
|
+
let msg = "";
|
|
86
|
+
try {
|
|
87
|
+
response = await fetch(url, requestInit);
|
|
88
|
+
} catch (e) {
|
|
89
|
+
msg = (0, _errorToString.default)(e);
|
|
90
|
+
}
|
|
91
|
+
if (timeoutId) {
|
|
92
|
+
clearTimeout(timeoutId);
|
|
93
|
+
}
|
|
94
|
+
if (response) {
|
|
95
|
+
try {
|
|
96
|
+
if (processRes) {
|
|
97
|
+
result = await processRes(response, options || {});
|
|
98
|
+
} else {
|
|
99
|
+
result = await response.json();
|
|
100
|
+
}
|
|
101
|
+
} catch (e) {
|
|
102
|
+
msg = (0, _errorToString.default)(e);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (result === null) {
|
|
106
|
+
if (processErr) {
|
|
107
|
+
result = await processErr(msg, options || {});
|
|
108
|
+
} else {
|
|
109
|
+
// this error should only happen on network errors or wrong API urls
|
|
110
|
+
// there is no specific HTTP error for this, we can consider these
|
|
111
|
+
// two statuses though:
|
|
112
|
+
// - [100 Continue](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/100)
|
|
113
|
+
// - [501 Not Implemented](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/501)
|
|
114
|
+
result = {
|
|
115
|
+
data: null,
|
|
116
|
+
msg,
|
|
117
|
+
status: 100,
|
|
118
|
+
fail: true,
|
|
119
|
+
ok: false
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (throwErr && result?.fail) {
|
|
124
|
+
// throw new ApiError<Failed>(result);
|
|
125
|
+
// I prefer to throw an object literal despite what eslint says
|
|
126
|
+
// eslint-disable-next-line no-throw-literal
|
|
127
|
+
throw result;
|
|
128
|
+
}
|
|
129
|
+
if (process.env["NODE_ENV"] !== "production") {
|
|
130
|
+
const logMsg = `${result?.status}: api[${apiName}] ${method.toUpperCase()} ${url}`;
|
|
131
|
+
if (result?.ok) {
|
|
132
|
+
console.info(`🟢 ${logMsg}`);
|
|
133
|
+
} else {
|
|
134
|
+
console.info(`🔴 ${logMsg}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return result;
|
|
138
|
+
};
|
|
144
139
|
return api;
|
|
145
140
|
}, {});
|
|
146
141
|
};
|
|
147
|
-
|
|
148
|
-
exports.default = exports.createApi;
|
|
142
|
+
const _default = createApi;
|
package/createApi.mjs
CHANGED
|
@@ -1,143 +1,127 @@
|
|
|
1
|
-
import { __assign, __awaiter, __generator } from "tslib";
|
|
2
1
|
import buildUrlQueryString from "@koine/utils/buildUrlQueryString";
|
|
3
|
-
import isFullObject from "@koine/utils/isFullObject";
|
|
4
2
|
import errorToString from "@koine/utils/errorToString";
|
|
3
|
+
import isFullObject from "@koine/utils/isFullObject";
|
|
5
4
|
/**
|
|
6
5
|
* Create api client
|
|
7
6
|
*
|
|
8
7
|
* @param apiName Short name to use in debug logs
|
|
9
8
|
* @param baseUrl Either relativ eor absolute, it must end without trailing slash
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
9
|
+
*/ export const createApi = (apiName, baseUrl, options)=>{
|
|
10
|
+
const { headers: headersBase = {}, request: requestBase = {
|
|
11
|
+
referrerPolicy: "no-referrer"
|
|
12
|
+
}, throwErr: throwErrBase, timeout: timeoutBase = 10000, processReq: processReqBase, processRes: processResBase, processErr: processErrBase } = options || {};
|
|
13
|
+
return [
|
|
14
|
+
"get",
|
|
15
|
+
"post",
|
|
16
|
+
"put",
|
|
17
|
+
"patch",
|
|
18
|
+
"delete"
|
|
19
|
+
].reduce((api, method)=>{
|
|
20
20
|
// @ts-expect-error FIXME: type
|
|
21
|
-
api[method] =
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
case 14:
|
|
122
|
-
if (throwErr && (result === null || result === void 0 ? void 0 : result.fail)) {
|
|
123
|
-
// throw new ApiError<Failed>(result);
|
|
124
|
-
// I prefer to throw an object literal despite what eslint says
|
|
125
|
-
// eslint-disable-next-line no-throw-literal
|
|
126
|
-
throw result;
|
|
127
|
-
}
|
|
128
|
-
if (process.env["NODE_ENV"] !== "production") {
|
|
129
|
-
logMsg = "".concat(result === null || result === void 0 ? void 0 : result.status, ": api[").concat(apiName, "] ").concat(method.toUpperCase(), " ").concat(url);
|
|
130
|
-
if (result === null || result === void 0 ? void 0 : result.ok) {
|
|
131
|
-
console.info("\uD83D\uDFE2 ".concat(logMsg));
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
console.info("\uD83D\uDD34 ".concat(logMsg));
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
return [2 /*return*/, result];
|
|
21
|
+
api[method] = async (endpoint, options)=>{
|
|
22
|
+
const { request = requestBase, headers = headersBase, timeout = timeoutBase, processReq, processRes = processResBase, processErr = processErrBase, throwErr = throwErrBase } = options || {};
|
|
23
|
+
let { params, json, query } = options || {};
|
|
24
|
+
let url = `${baseUrl}/${endpoint + "".replace(/^\/*/, "")}`;
|
|
25
|
+
let requestInit = {
|
|
26
|
+
method: method.toUpperCase(),
|
|
27
|
+
...request,
|
|
28
|
+
headers: {
|
|
29
|
+
"content-type": "application/json",
|
|
30
|
+
...headers
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
if (processReqBase) {
|
|
34
|
+
const transformed = processReqBase(method, url, query, json, params, requestInit);
|
|
35
|
+
url = transformed[0];
|
|
36
|
+
query = transformed[1];
|
|
37
|
+
json = transformed[2];
|
|
38
|
+
params = transformed[3];
|
|
39
|
+
requestInit = transformed[4];
|
|
40
|
+
}
|
|
41
|
+
if (processReq) {
|
|
42
|
+
const transformed = processReq(method, url, query, json, params, requestInit);
|
|
43
|
+
url = transformed[0];
|
|
44
|
+
query = transformed[1];
|
|
45
|
+
json = transformed[2];
|
|
46
|
+
params = transformed[3];
|
|
47
|
+
requestInit = transformed[4];
|
|
48
|
+
}
|
|
49
|
+
if (isFullObject(params)) {
|
|
50
|
+
for(const key in params){
|
|
51
|
+
url = url.replace(`{${key}}`, params[key].toString());
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const timeoutNumber = Number(timeout);
|
|
55
|
+
let controller;
|
|
56
|
+
let timeoutId;
|
|
57
|
+
if (json) {
|
|
58
|
+
requestInit.body = JSON.stringify(json);
|
|
59
|
+
}
|
|
60
|
+
if (timeoutNumber > 0) {
|
|
61
|
+
controller = new AbortController();
|
|
62
|
+
timeoutId = setTimeout(()=>controller.abort(), timeoutNumber);
|
|
63
|
+
requestInit.signal = controller.signal;
|
|
64
|
+
}
|
|
65
|
+
if (query) {
|
|
66
|
+
// FIXME: ts-expect-error this assertion is not the best, but nevermind for now
|
|
67
|
+
url += buildUrlQueryString(query);
|
|
68
|
+
}
|
|
69
|
+
let response = null;
|
|
70
|
+
let result = null;
|
|
71
|
+
let msg = "";
|
|
72
|
+
try {
|
|
73
|
+
response = await fetch(url, requestInit);
|
|
74
|
+
} catch (e) {
|
|
75
|
+
msg = errorToString(e);
|
|
76
|
+
}
|
|
77
|
+
if (timeoutId) {
|
|
78
|
+
clearTimeout(timeoutId);
|
|
79
|
+
}
|
|
80
|
+
if (response) {
|
|
81
|
+
try {
|
|
82
|
+
if (processRes) {
|
|
83
|
+
result = await processRes(response, options || {});
|
|
84
|
+
} else {
|
|
85
|
+
result = await response.json();
|
|
86
|
+
}
|
|
87
|
+
} catch (e) {
|
|
88
|
+
msg = errorToString(e);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (result === null) {
|
|
92
|
+
if (processErr) {
|
|
93
|
+
result = await processErr(msg, options || {});
|
|
94
|
+
} else {
|
|
95
|
+
// this error should only happen on network errors or wrong API urls
|
|
96
|
+
// there is no specific HTTP error for this, we can consider these
|
|
97
|
+
// two statuses though:
|
|
98
|
+
// - [100 Continue](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/100)
|
|
99
|
+
// - [501 Not Implemented](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/501)
|
|
100
|
+
result = {
|
|
101
|
+
data: null,
|
|
102
|
+
msg,
|
|
103
|
+
status: 100,
|
|
104
|
+
fail: true,
|
|
105
|
+
ok: false
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (throwErr && result?.fail) {
|
|
110
|
+
// throw new ApiError<Failed>(result);
|
|
111
|
+
// I prefer to throw an object literal despite what eslint says
|
|
112
|
+
// eslint-disable-next-line no-throw-literal
|
|
113
|
+
throw result;
|
|
114
|
+
}
|
|
115
|
+
if (process.env["NODE_ENV"] !== "production") {
|
|
116
|
+
const logMsg = `${result?.status}: api[${apiName}] ${method.toUpperCase()} ${url}`;
|
|
117
|
+
if (result?.ok) {
|
|
118
|
+
console.info(`🟢 ${logMsg}`);
|
|
119
|
+
} else {
|
|
120
|
+
console.info(`🔴 ${logMsg}`);
|
|
138
121
|
}
|
|
139
|
-
}
|
|
140
|
-
|
|
122
|
+
}
|
|
123
|
+
return result;
|
|
124
|
+
};
|
|
141
125
|
return api;
|
|
142
126
|
}, {});
|
|
143
127
|
};
|
package/createSwrApi.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type BareFetcher, // type Fetcher,
|
|
2
|
+
type SWRConfiguration, type SWRResponse } from "swr";
|
|
2
3
|
import { type SWRMutationConfiguration, type SWRMutationResponse } from "swr/mutation";
|
|
3
4
|
type SWRConfigurationExtended<Data = any, Error = any, Fn extends BareFetcher<any> = BareFetcher<any>> = SWRConfiguration<Data, Error, Fn> & {
|
|
4
5
|
/**
|
package/createSwrApi.js
CHANGED
|
@@ -1,15 +1,29 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
"use client";
|
|
3
|
-
|
|
4
|
-
exports
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
var
|
|
9
|
-
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
function _export(target, all) {
|
|
7
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: all[name]
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
_export(exports, {
|
|
13
|
+
createSwrApi: function() {
|
|
14
|
+
return createSwrApi;
|
|
15
|
+
},
|
|
16
|
+
default: function() {
|
|
17
|
+
return _default;
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
|
|
21
|
+
const _swr = /*#__PURE__*/ _interop_require_default._(require("swr"));
|
|
22
|
+
const _mutation = /*#__PURE__*/ _interop_require_default._(require("swr/mutation"));
|
|
23
|
+
const _isFunction = /*#__PURE__*/ _interop_require_default._(require("@koine/utils/isFunction"));
|
|
24
|
+
const _createApi = /*#__PURE__*/ _interop_require_default._(require("./createApi"));
|
|
10
25
|
function createUseApi(api, method) {
|
|
11
26
|
return function useApi(endpoint, options, _config) {
|
|
12
|
-
var _this = this;
|
|
13
27
|
if (method === "get") {
|
|
14
28
|
// const fetcher = async (_endpoint: TEndpoint) => {
|
|
15
29
|
// try {
|
|
@@ -26,66 +40,60 @@ function createUseApi(api, method) {
|
|
|
26
40
|
// }
|
|
27
41
|
// };
|
|
28
42
|
// }
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
case 0: return [4 /*yield*/, api[method](endpoint, tslib_1.__assign(tslib_1.__assign({}, (options || {})), { throwErr: true }))];
|
|
34
|
-
case 1:
|
|
35
|
-
data = (_a.sent()).data;
|
|
36
|
-
return [2 /*return*/, data];
|
|
37
|
-
}
|
|
43
|
+
const fetcher = async ()=>{
|
|
44
|
+
const { data } = await api[method](endpoint, {
|
|
45
|
+
...options || {},
|
|
46
|
+
throwErr: true
|
|
38
47
|
});
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
48
|
+
return data;
|
|
49
|
+
};
|
|
50
|
+
const config = _config;
|
|
51
|
+
const shouldNotFetch = config?.when === false || (0, _isFunction.default)(config?.when) && config?.when() === false;
|
|
43
52
|
// <Data = any, Error = any>(key: Key, config: SWRConfigurationExtended<Data, Error, Fetcher<Data>> | undefined): SWRResponse<Data, Error>;
|
|
44
53
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
45
|
-
return (0,
|
|
54
|
+
return (0, _swr.default)(shouldNotFetch ? null : options ? [
|
|
55
|
+
endpoint,
|
|
56
|
+
options
|
|
57
|
+
] : [
|
|
58
|
+
endpoint
|
|
59
|
+
], fetcher, config);
|
|
46
60
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
// if the first argument is an array the second tem are the base options
|
|
61
|
+
const config = _config;
|
|
62
|
+
const sender = async (// if the first argument is an array the second tem are the base options
|
|
50
63
|
// defined when calling the usePost/Put/etc. hook, these will be overriden
|
|
51
64
|
// by the _options just here below
|
|
52
|
-
_endpoint,
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
options = Array.isArray(_endpoint) ? _endpoint[1] : {};
|
|
61
|
-
return [4 /*yield*/, api[method](endpoint, tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, options), (_options.arg || {})), { throwErr: true }))];
|
|
62
|
-
case 1:
|
|
63
|
-
_a = _b.sent(), ok = _a.ok, data = _a.data;
|
|
64
|
-
return [2 /*return*/, ok ? data : data];
|
|
65
|
-
}
|
|
65
|
+
_endpoint, // these are the options arriving when calling `trigger({ json, query, etc... })
|
|
66
|
+
_options)=>{
|
|
67
|
+
const endpoint = Array.isArray(_endpoint) ? _endpoint[0] : _endpoint;
|
|
68
|
+
const options = Array.isArray(_endpoint) ? _endpoint[1] : {};
|
|
69
|
+
const { ok, data } = await api[method](endpoint, {
|
|
70
|
+
...options,
|
|
71
|
+
..._options.arg || {},
|
|
72
|
+
throwErr: true
|
|
66
73
|
});
|
|
67
|
-
|
|
74
|
+
return ok ? data : data;
|
|
75
|
+
};
|
|
68
76
|
// config.fetcher = sender;
|
|
69
77
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
70
|
-
return (0,
|
|
71
|
-
|
|
72
|
-
|
|
78
|
+
return (0, _mutation.default)(// @ts-expect-error FIXME: I can't get it...
|
|
79
|
+
options ? [
|
|
80
|
+
endpoint,
|
|
81
|
+
options
|
|
82
|
+
] : endpoint, sender, config);
|
|
73
83
|
};
|
|
74
84
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
var hookName = "use".concat(method.charAt(0).toUpperCase() + method.slice(1));
|
|
85
|
+
const createSwrApi = (...args)=>{
|
|
86
|
+
const api = (0, _createApi.default)(...args);
|
|
87
|
+
[
|
|
88
|
+
"get",
|
|
89
|
+
"post",
|
|
90
|
+
"put",
|
|
91
|
+
"patch",
|
|
92
|
+
"delete"
|
|
93
|
+
].forEach((method)=>{
|
|
94
|
+
const hookName = `use${method.charAt(0).toUpperCase() + method.slice(1)}`;
|
|
86
95
|
api[hookName] = createUseApi(api, method);
|
|
87
96
|
});
|
|
88
97
|
return api;
|
|
89
98
|
};
|
|
90
|
-
|
|
91
|
-
exports.default = exports.createSwrApi;
|
|
99
|
+
const _default = createSwrApi;
|
package/createSwrApi.mjs
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { __assign, __awaiter, __generator } from "tslib";
|
|
3
|
-
import isFunction from "@koine/utils/isFunction";
|
|
4
2
|
import useSWR from "swr";
|
|
5
3
|
import useSWRMutation from "swr/mutation";
|
|
4
|
+
import isFunction from "@koine/utils/isFunction";
|
|
6
5
|
import createApi from "./createApi";
|
|
7
6
|
function createUseApi(api, method) {
|
|
8
7
|
return function useApi(endpoint, options, _config) {
|
|
9
|
-
var _this = this;
|
|
10
8
|
if (method === "get") {
|
|
11
9
|
// const fetcher = async (_endpoint: TEndpoint) => {
|
|
12
10
|
// try {
|
|
@@ -23,63 +21,60 @@ function createUseApi(api, method) {
|
|
|
23
21
|
// }
|
|
24
22
|
// };
|
|
25
23
|
// }
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
case 0: return [4 /*yield*/, api[method](endpoint, __assign(__assign({}, (options || {})), { throwErr: true }))];
|
|
31
|
-
case 1:
|
|
32
|
-
data = (_a.sent()).data;
|
|
33
|
-
return [2 /*return*/, data];
|
|
34
|
-
}
|
|
24
|
+
const fetcher = async ()=>{
|
|
25
|
+
const { data } = await api[method](endpoint, {
|
|
26
|
+
...options || {},
|
|
27
|
+
throwErr: true
|
|
35
28
|
});
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
29
|
+
return data;
|
|
30
|
+
};
|
|
31
|
+
const config = _config;
|
|
32
|
+
const shouldNotFetch = config?.when === false || isFunction(config?.when) && config?.when() === false;
|
|
40
33
|
// <Data = any, Error = any>(key: Key, config: SWRConfigurationExtended<Data, Error, Fetcher<Data>> | undefined): SWRResponse<Data, Error>;
|
|
41
34
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
42
|
-
return useSWR(shouldNotFetch ? null : options ? [
|
|
35
|
+
return useSWR(shouldNotFetch ? null : options ? [
|
|
36
|
+
endpoint,
|
|
37
|
+
options
|
|
38
|
+
] : [
|
|
39
|
+
endpoint
|
|
40
|
+
], fetcher, config);
|
|
43
41
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
// if the first argument is an array the second tem are the base options
|
|
42
|
+
const config = _config;
|
|
43
|
+
const sender = async (// if the first argument is an array the second tem are the base options
|
|
47
44
|
// defined when calling the usePost/Put/etc. hook, these will be overriden
|
|
48
45
|
// by the _options just here below
|
|
49
|
-
_endpoint,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
options = Array.isArray(_endpoint) ? _endpoint[1] : {};
|
|
58
|
-
return [4 /*yield*/, api[method](endpoint, __assign(__assign(__assign({}, options), (_options.arg || {})), { throwErr: true }))];
|
|
59
|
-
case 1:
|
|
60
|
-
_a = _b.sent(), ok = _a.ok, data = _a.data;
|
|
61
|
-
return [2 /*return*/, ok ? data : data];
|
|
62
|
-
}
|
|
46
|
+
_endpoint, // these are the options arriving when calling `trigger({ json, query, etc... })
|
|
47
|
+
_options)=>{
|
|
48
|
+
const endpoint = Array.isArray(_endpoint) ? _endpoint[0] : _endpoint;
|
|
49
|
+
const options = Array.isArray(_endpoint) ? _endpoint[1] : {};
|
|
50
|
+
const { ok, data } = await api[method](endpoint, {
|
|
51
|
+
...options,
|
|
52
|
+
..._options.arg || {},
|
|
53
|
+
throwErr: true
|
|
63
54
|
});
|
|
64
|
-
|
|
55
|
+
return ok ? data : data;
|
|
56
|
+
};
|
|
65
57
|
// config.fetcher = sender;
|
|
66
58
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
67
|
-
return useSWRMutation(
|
|
68
|
-
|
|
69
|
-
|
|
59
|
+
return useSWRMutation(// @ts-expect-error FIXME: I can't get it...
|
|
60
|
+
options ? [
|
|
61
|
+
endpoint,
|
|
62
|
+
options
|
|
63
|
+
] : endpoint, sender, config);
|
|
70
64
|
};
|
|
71
65
|
}
|
|
72
66
|
/**
|
|
73
67
|
* It creates an api client extended with auto-generated SWR wrapper hooks
|
|
74
|
-
*/
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
68
|
+
*/ export const createSwrApi = (...args)=>{
|
|
69
|
+
const api = createApi(...args);
|
|
70
|
+
[
|
|
71
|
+
"get",
|
|
72
|
+
"post",
|
|
73
|
+
"put",
|
|
74
|
+
"patch",
|
|
75
|
+
"delete"
|
|
76
|
+
].forEach((method)=>{
|
|
77
|
+
const hookName = `use${method.charAt(0).toUpperCase() + method.slice(1)}`;
|
|
83
78
|
api[hookName] = createUseApi(api, method);
|
|
84
79
|
});
|
|
85
80
|
return api;
|
package/index.js
CHANGED
|
@@ -1,11 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
var
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: all[name]
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
ApiError: function() {
|
|
13
|
+
return _ApiError.ApiError;
|
|
14
|
+
},
|
|
15
|
+
createApi: function() {
|
|
16
|
+
return _createApi.createApi;
|
|
17
|
+
},
|
|
18
|
+
createSwrApi: function() {
|
|
19
|
+
return _createSwrApi.createSwrApi;
|
|
20
|
+
},
|
|
21
|
+
nextApiResponse: function() {
|
|
22
|
+
return _nextApiResponse.nextApiResponse;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
const _ApiError = require("./ApiError");
|
|
26
|
+
const _createApi = require("./createApi");
|
|
27
|
+
const _createSwrApi = require("./createSwrApi");
|
|
28
|
+
const _nextApiResponse = require("./nextApiResponse");
|
package/nextApiResponse.js
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: all[name]
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
nextApiResponse: function() {
|
|
13
|
+
return nextApiResponse;
|
|
14
|
+
},
|
|
15
|
+
default: function() {
|
|
16
|
+
return _default;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
const nextApiResponse = (nextRes, result)=>{
|
|
5
20
|
// nextRes.status(result.status).json(result.data || result.msg);
|
|
6
21
|
nextRes.status(result.status).json(result);
|
|
7
22
|
};
|
|
8
|
-
|
|
9
|
-
exports.default = exports.nextApiResponse;
|
|
23
|
+
const _default = nextApiResponse;
|
package/nextApiResponse.mjs
CHANGED
package/package.json
CHANGED
|
@@ -7,18 +7,21 @@
|
|
|
7
7
|
}
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"clsx": "1.2.1",
|
|
11
|
-
"next": "^13.4.
|
|
12
|
-
"swr": "^2.
|
|
10
|
+
"clsx": "^1.2.1",
|
|
11
|
+
"next": "^13.4.7",
|
|
12
|
+
"swr": "^2.2.0",
|
|
13
13
|
"ts-debounce": "^4.0.0",
|
|
14
|
-
"type-fest": "^3.
|
|
15
|
-
},
|
|
16
|
-
"peerDependencies": {
|
|
17
|
-
"@koine/utils": "2.0.0-beta.2",
|
|
18
|
-
"tslib": "2.5.3"
|
|
14
|
+
"type-fest": "^3.12.0"
|
|
19
15
|
},
|
|
16
|
+
"peerDependencies": {},
|
|
17
|
+
"module": "./index.mjs",
|
|
20
18
|
"main": "./index.js",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"import": "./index.js",
|
|
22
|
+
"require": "./index.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
21
25
|
"types": "./index.d.ts",
|
|
22
|
-
"version": "2.0.0-beta.
|
|
23
|
-
|
|
24
|
-
}
|
|
26
|
+
"version": "2.0.0-beta.4"
|
|
27
|
+
}
|