@koine/api 2.0.0-beta.13 → 2.0.0-beta.15
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.d.ts +1 -7
- package/ApiError.js +13 -0
- package/cjs/ApiError.d.ts +5 -0
- package/cjs/ApiError.js +16 -0
- package/cjs/createApi.d.ts +2 -0
- package/cjs/createApi.js +126 -0
- package/cjs/createApiResultFail.d.ts +2 -0
- package/cjs/createApiResultFail.js +14 -0
- package/cjs/createApiResultOk.d.ts +2 -0
- package/cjs/createApiResultOk.js +15 -0
- package/cjs/createSwrApi.d.ts +15 -0
- package/cjs/createSwrApi.js +61 -0
- package/cjs/index.js +15 -0
- package/cjs/nextApiResponse.d.ts +6 -0
- package/cjs/nextApiResponse.js +15 -0
- package/cjs/nextApiResponse12.d.ts +6 -0
- package/cjs/nextApiResponse12.js +19 -0
- package/cjs/package.json +17 -0
- package/createApi.d.ts +0 -6
- package/createApi.js +122 -0
- package/createApiResultFail.js +10 -0
- package/createApiResultOk.js +11 -0
- package/createSwrApi.d.ts +2 -21
- package/createSwrApi.js +57 -0
- package/index.d.ts +6 -6
- package/index.js +6 -0
- package/nextApiResponse.d.ts +3 -2
- package/nextApiResponse.js +12 -0
- package/nextApiResponse12.js +15 -0
- package/package.json +42 -7
- package/typings.d.ts +23 -23
- package/ApiError.mjs +0 -14
- package/README.md +0 -1
- package/createApi.mjs +0 -128
- package/createApiResultFail.mjs +0 -7
- package/createApiResultOk.mjs +0 -8
- package/createSwrApi.mjs +0 -82
- package/nextApiResponse.mjs +0 -12
- package/nextApiResponse12.mjs +0 -13
- /package/{index.mjs → cjs/index.d.ts} +0 -0
package/ApiError.d.ts
CHANGED
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* Custom `ApiError` class extending `Error` to throw in failed response.
|
|
3
|
-
*
|
|
4
|
-
* @see https://eslint.org/docs/rules/no-throw-literal
|
|
5
|
-
* @see https://github.com/sindresorhus/ky/blob/main/source/errors/HTTPError.ts
|
|
6
|
-
*
|
|
7
|
-
*/
|
|
1
|
+
/// <reference types="./typings.d.ts" />
|
|
8
2
|
export declare class ApiError<TResponseFail extends Koine.Api.ResponseFail = unknown> extends Error {
|
|
9
3
|
constructor(result: Koine.Api.ResultFail<TResponseFail>);
|
|
10
4
|
}
|
package/ApiError.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { __extends } from "tslib";
|
|
2
|
+
var ApiError = (function (_super) {
|
|
3
|
+
__extends(ApiError, _super);
|
|
4
|
+
function ApiError(result) {
|
|
5
|
+
var _this = _super.call(this, "Request failed with ".concat(result.status, " ").concat(result.msg)) || this;
|
|
6
|
+
_this.name = "ApiError";
|
|
7
|
+
Object.assign(_this, result);
|
|
8
|
+
return _this;
|
|
9
|
+
}
|
|
10
|
+
return ApiError;
|
|
11
|
+
}(Error));
|
|
12
|
+
export { ApiError };
|
|
13
|
+
export default ApiError;
|
package/cjs/ApiError.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ApiError = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
var ApiError = (function (_super) {
|
|
6
|
+
tslib_1.__extends(ApiError, _super);
|
|
7
|
+
function ApiError(result) {
|
|
8
|
+
var _this = _super.call(this, "Request failed with ".concat(result.status, " ").concat(result.msg)) || this;
|
|
9
|
+
_this.name = "ApiError";
|
|
10
|
+
Object.assign(_this, result);
|
|
11
|
+
return _this;
|
|
12
|
+
}
|
|
13
|
+
return ApiError;
|
|
14
|
+
}(Error));
|
|
15
|
+
exports.ApiError = ApiError;
|
|
16
|
+
exports.default = ApiError;
|
package/cjs/createApi.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createApi = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
var buildUrlQueryString_1 = require("@koine/utils/buildUrlQueryString");
|
|
6
|
+
var errorToString_1 = require("@koine/utils/errorToString");
|
|
7
|
+
var isFullObject_1 = require("@koine/utils/isFullObject");
|
|
8
|
+
var createApi = function (apiName, baseUrl, options) {
|
|
9
|
+
var _a = options || {}, _b = _a.headers, headersBase = _b === void 0 ? {} : _b, _c = _a.request, requestBase = _c === void 0 ? {} : _c, throwErrBase = _a.throwErr, _d = _a.timeout, timeoutBase = _d === void 0 ? 10000 : _d, processReqBase = _a.processReq, processResBase = _a.processRes, processErrBase = _a.processErr;
|
|
10
|
+
return ["get", "post", "put", "patch", "delete"].reduce(function (api, method) {
|
|
11
|
+
api[method] = function (endpoint, options) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
12
|
+
var _a, _b, request, _c, headers, _d, timeout, processReq, _e, processRes, _f, processErr, _g, throwErr, _h, params, json, query, url, requestInit, transformed, transformed, key, timeoutNumber, controller, timeoutId, response, result, msg, e_1, e_2, logMsg;
|
|
13
|
+
return tslib_1.__generator(this, function (_j) {
|
|
14
|
+
switch (_j.label) {
|
|
15
|
+
case 0:
|
|
16
|
+
_a = options || {}, _b = _a.request, request = _b === void 0 ? requestBase : _b, _c = _a.headers, headers = _c === void 0 ? headersBase : _c, _d = _a.timeout, timeout = _d === void 0 ? timeoutBase : _d, processReq = _a.processReq, _e = _a.processRes, processRes = _e === void 0 ? processResBase : _e, _f = _a.processErr, processErr = _f === void 0 ? processErrBase : _f, _g = _a.throwErr, throwErr = _g === void 0 ? throwErrBase : _g;
|
|
17
|
+
_h = options || {}, params = _h.params, json = _h.json, query = _h.query;
|
|
18
|
+
url = "".concat(baseUrl, "/").concat(endpoint + "".replace(/^\/*/, ""));
|
|
19
|
+
requestInit = tslib_1.__assign(tslib_1.__assign({ method: method.toUpperCase() }, request), { headers: tslib_1.__assign({ "content-type": "application/json" }, headers) });
|
|
20
|
+
if (processReqBase) {
|
|
21
|
+
transformed = processReqBase(method, url, query, json, params, requestInit);
|
|
22
|
+
url = transformed[0];
|
|
23
|
+
query = transformed[1];
|
|
24
|
+
json = transformed[2];
|
|
25
|
+
params = transformed[3];
|
|
26
|
+
requestInit = transformed[4];
|
|
27
|
+
}
|
|
28
|
+
if (processReq) {
|
|
29
|
+
transformed = processReq(method, url, query, json, params, requestInit);
|
|
30
|
+
url = transformed[0];
|
|
31
|
+
query = transformed[1];
|
|
32
|
+
json = transformed[2];
|
|
33
|
+
params = transformed[3];
|
|
34
|
+
requestInit = transformed[4];
|
|
35
|
+
}
|
|
36
|
+
if ((0, isFullObject_1.default)(params)) {
|
|
37
|
+
for (key in params) {
|
|
38
|
+
url = url.replace("{".concat(key, "}"), params[key].toString());
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
timeoutNumber = Number(timeout);
|
|
42
|
+
if (json) {
|
|
43
|
+
requestInit.body = JSON.stringify(json);
|
|
44
|
+
}
|
|
45
|
+
if (timeoutNumber > 0) {
|
|
46
|
+
controller = new AbortController();
|
|
47
|
+
timeoutId = setTimeout(function () { return controller.abort(); }, timeoutNumber);
|
|
48
|
+
requestInit.signal = controller.signal;
|
|
49
|
+
}
|
|
50
|
+
if (query) {
|
|
51
|
+
url += (0, buildUrlQueryString_1.default)(query);
|
|
52
|
+
}
|
|
53
|
+
response = null;
|
|
54
|
+
result = null;
|
|
55
|
+
msg = "";
|
|
56
|
+
_j.label = 1;
|
|
57
|
+
case 1:
|
|
58
|
+
_j.trys.push([1, 3, , 4]);
|
|
59
|
+
return [4, fetch(url, requestInit)];
|
|
60
|
+
case 2:
|
|
61
|
+
response = _j.sent();
|
|
62
|
+
return [3, 4];
|
|
63
|
+
case 3:
|
|
64
|
+
e_1 = _j.sent();
|
|
65
|
+
msg = (0, errorToString_1.default)(e_1);
|
|
66
|
+
return [3, 4];
|
|
67
|
+
case 4:
|
|
68
|
+
if (timeoutId) {
|
|
69
|
+
clearTimeout(timeoutId);
|
|
70
|
+
}
|
|
71
|
+
if (!response) return [3, 11];
|
|
72
|
+
_j.label = 5;
|
|
73
|
+
case 5:
|
|
74
|
+
_j.trys.push([5, 10, , 11]);
|
|
75
|
+
if (!processRes) return [3, 7];
|
|
76
|
+
return [4, processRes(response, options || {})];
|
|
77
|
+
case 6:
|
|
78
|
+
result = _j.sent();
|
|
79
|
+
return [3, 9];
|
|
80
|
+
case 7: return [4, response.json()];
|
|
81
|
+
case 8:
|
|
82
|
+
result = _j.sent();
|
|
83
|
+
_j.label = 9;
|
|
84
|
+
case 9: return [3, 11];
|
|
85
|
+
case 10:
|
|
86
|
+
e_2 = _j.sent();
|
|
87
|
+
msg = (0, errorToString_1.default)(e_2);
|
|
88
|
+
return [3, 11];
|
|
89
|
+
case 11:
|
|
90
|
+
if (!(result === null)) return [3, 14];
|
|
91
|
+
if (!processErr) return [3, 13];
|
|
92
|
+
return [4, processErr(msg, options || {})];
|
|
93
|
+
case 12:
|
|
94
|
+
result = _j.sent();
|
|
95
|
+
return [3, 14];
|
|
96
|
+
case 13:
|
|
97
|
+
result = {
|
|
98
|
+
data: null,
|
|
99
|
+
msg: msg,
|
|
100
|
+
status: 100,
|
|
101
|
+
fail: true,
|
|
102
|
+
ok: false,
|
|
103
|
+
};
|
|
104
|
+
_j.label = 14;
|
|
105
|
+
case 14:
|
|
106
|
+
if (throwErr && (result === null || result === void 0 ? void 0 : result.fail)) {
|
|
107
|
+
throw result;
|
|
108
|
+
}
|
|
109
|
+
if (process.env["NODE_ENV"] !== "production") {
|
|
110
|
+
logMsg = "".concat(result === null || result === void 0 ? void 0 : result.status, ": api[").concat(apiName, "] ").concat(method.toUpperCase(), " ").concat(url);
|
|
111
|
+
if (result === null || result === void 0 ? void 0 : result.ok) {
|
|
112
|
+
console.info("\uD83D\uDFE2 ".concat(logMsg));
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
console.info("\uD83D\uDD34 ".concat(logMsg));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return [2, result];
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}); };
|
|
122
|
+
return api;
|
|
123
|
+
}, {});
|
|
124
|
+
};
|
|
125
|
+
exports.createApi = createApi;
|
|
126
|
+
exports.default = exports.createApi;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createApiResultFail = void 0;
|
|
4
|
+
var createApiResultFail = function (data, msg, status) {
|
|
5
|
+
if (data === void 0) { data = {}; }
|
|
6
|
+
return ({
|
|
7
|
+
fail: true,
|
|
8
|
+
data: data,
|
|
9
|
+
msg: msg || "",
|
|
10
|
+
status: status || 404,
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
exports.createApiResultFail = createApiResultFail;
|
|
14
|
+
exports.default = exports.createApiResultFail;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createApiResultOk = void 0;
|
|
4
|
+
var createApiResultOk = function (data, msg) {
|
|
5
|
+
if (data === void 0) { data = {}; }
|
|
6
|
+
return ({
|
|
7
|
+
ok: true,
|
|
8
|
+
fail: false,
|
|
9
|
+
data: data,
|
|
10
|
+
msg: msg || "",
|
|
11
|
+
status: 200,
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
exports.createApiResultOk = createApiResultOk;
|
|
15
|
+
exports.default = exports.createApiResultOk;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/// <reference types="./typings.d.ts" />
|
|
2
|
+
import { type BareFetcher, type SWRConfiguration, type SWRResponse } from "swr";
|
|
3
|
+
import { type SWRMutationConfiguration, type SWRMutationResponse } from "swr/mutation";
|
|
4
|
+
type SWRConfigurationExtended<Data = any, Error = any, Fn extends BareFetcher<any> = BareFetcher<any>> = SWRConfiguration<Data, Error, Fn> & {
|
|
5
|
+
when?: boolean | (() => boolean);
|
|
6
|
+
};
|
|
7
|
+
type KoineApiMethodHookSWR<THookName extends keyof Koine.Api.HooksMapsByName, TEndpoints extends Koine.Api.Endpoints> = <TEndpoint extends Koine.Api.EndpointUrl<TEndpoints>, TMethod extends Koine.Api.RequestMethod = Koine.Api.HooksMapsByName[THookName]>(endpoint: TEndpoint, options?: Koine.Api.EndpointOptions<TEndpoints, TEndpoint, TMethod>, config?: THookName extends "useGet" ? SWRConfigurationExtended<Koine.Api.EndpointResponseOk<TEndpoints, TEndpoint, TMethod>, Koine.Api.EndpointResponseFail<TEndpoints, TEndpoint, TMethod>> : SWRMutationConfiguration<Koine.Api.EndpointResponseOk<TEndpoints, TEndpoint, TMethod>, Koine.Api.EndpointResponseFail<TEndpoints, TEndpoint, TMethod>, Koine.Api.EndpointOptions<TEndpoints, TEndpoint, TMethod>, TEndpoint>) => THookName extends "useGet" ? SWRResponse<Koine.Api.EndpointResponseOk<TEndpoints, TEndpoint, TMethod>, Koine.Api.EndpointResponseFail<TEndpoints, TEndpoint, TMethod>> : SWRMutationResponse<Koine.Api.EndpointResponseOk<TEndpoints, TEndpoint, TMethod>, Koine.Api.EndpointResponseFail<TEndpoints, TEndpoint, TMethod>, Koine.Api.EndpointOptions<TEndpoints, TEndpoint, TMethod>, TEndpoint>;
|
|
8
|
+
export declare const createSwrApi: <TEndpoints extends Koine.Api.Endpoints>(apiName: string, baseUrl: string, options?: Koine.Api.ClientOptions | undefined) => Koine.Api.Client<TEndpoints> & {
|
|
9
|
+
useGet: KoineApiMethodHookSWR<"useGet", TEndpoints>;
|
|
10
|
+
usePost: KoineApiMethodHookSWR<"usePost", TEndpoints>;
|
|
11
|
+
usePut: KoineApiMethodHookSWR<"usePut", TEndpoints>;
|
|
12
|
+
usePatch: KoineApiMethodHookSWR<"usePatch", TEndpoints>;
|
|
13
|
+
useDelete: KoineApiMethodHookSWR<"useDelete", TEndpoints>;
|
|
14
|
+
};
|
|
15
|
+
export default createSwrApi;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.createSwrApi = void 0;
|
|
5
|
+
var tslib_1 = require("tslib");
|
|
6
|
+
var swr_1 = require("swr");
|
|
7
|
+
var mutation_1 = require("swr/mutation");
|
|
8
|
+
var isFunction_1 = require("@koine/utils/isFunction");
|
|
9
|
+
var createApi_1 = require("./createApi");
|
|
10
|
+
function createUseApi(api, method) {
|
|
11
|
+
return function useApi(endpoint, options, _config) {
|
|
12
|
+
var _this = this;
|
|
13
|
+
if (method === "get") {
|
|
14
|
+
var fetcher = function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
15
|
+
var data;
|
|
16
|
+
return tslib_1.__generator(this, function (_a) {
|
|
17
|
+
switch (_a.label) {
|
|
18
|
+
case 0: return [4, api[method](endpoint, tslib_1.__assign(tslib_1.__assign({}, (options || {})), { throwErr: true }))];
|
|
19
|
+
case 1:
|
|
20
|
+
data = (_a.sent()).data;
|
|
21
|
+
return [2, data];
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}); };
|
|
25
|
+
var config_1 = _config;
|
|
26
|
+
var shouldNotFetch = (config_1 === null || config_1 === void 0 ? void 0 : config_1.when) === false ||
|
|
27
|
+
((0, isFunction_1.default)(config_1 === null || config_1 === void 0 ? void 0 : config_1.when) && (config_1 === null || config_1 === void 0 ? void 0 : config_1.when()) === false);
|
|
28
|
+
return (0, swr_1.default)(shouldNotFetch ? null : options ? [endpoint, options] : [endpoint], fetcher, config_1);
|
|
29
|
+
}
|
|
30
|
+
var config = _config;
|
|
31
|
+
var sender = function (_endpoint, _options) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
32
|
+
var endpoint, options, _a, ok, data;
|
|
33
|
+
return tslib_1.__generator(this, function (_b) {
|
|
34
|
+
switch (_b.label) {
|
|
35
|
+
case 0:
|
|
36
|
+
endpoint = Array.isArray(_endpoint) ? _endpoint[0] : _endpoint;
|
|
37
|
+
options = Array.isArray(_endpoint) ? _endpoint[1] : {};
|
|
38
|
+
return [4, api[method](endpoint, tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, options), (_options.arg || {})), { throwErr: true }))];
|
|
39
|
+
case 1:
|
|
40
|
+
_a = _b.sent(), ok = _a.ok, data = _a.data;
|
|
41
|
+
return [2, ok ? data : data];
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}); };
|
|
45
|
+
return (0, mutation_1.default)(options ? [endpoint, options] : endpoint, sender, config);
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
var createSwrApi = function () {
|
|
49
|
+
var args = [];
|
|
50
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
51
|
+
args[_i] = arguments[_i];
|
|
52
|
+
}
|
|
53
|
+
var api = createApi_1.default.apply(void 0, args);
|
|
54
|
+
["get", "post", "put", "patch", "delete"].forEach(function (method) {
|
|
55
|
+
var hookName = "use".concat(method.charAt(0).toUpperCase() + method.slice(1));
|
|
56
|
+
api[hookName] = createUseApi(api, method);
|
|
57
|
+
});
|
|
58
|
+
return api;
|
|
59
|
+
};
|
|
60
|
+
exports.createSwrApi = createSwrApi;
|
|
61
|
+
exports.default = exports.createSwrApi;
|
package/cjs/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.nextApiResponse12 = exports.createSwrApi = exports.createApiResultOk = exports.createApiResultFail = exports.createApi = exports.ApiError = void 0;
|
|
4
|
+
var ApiError_1 = require("./ApiError");
|
|
5
|
+
Object.defineProperty(exports, "ApiError", { enumerable: true, get: function () { return ApiError_1.ApiError; } });
|
|
6
|
+
var createApi_1 = require("./createApi");
|
|
7
|
+
Object.defineProperty(exports, "createApi", { enumerable: true, get: function () { return createApi_1.createApi; } });
|
|
8
|
+
var createApiResultFail_1 = require("./createApiResultFail");
|
|
9
|
+
Object.defineProperty(exports, "createApiResultFail", { enumerable: true, get: function () { return createApiResultFail_1.createApiResultFail; } });
|
|
10
|
+
var createApiResultOk_1 = require("./createApiResultOk");
|
|
11
|
+
Object.defineProperty(exports, "createApiResultOk", { enumerable: true, get: function () { return createApiResultOk_1.createApiResultOk; } });
|
|
12
|
+
var createSwrApi_1 = require("./createSwrApi");
|
|
13
|
+
Object.defineProperty(exports, "createSwrApi", { enumerable: true, get: function () { return createSwrApi_1.createSwrApi; } });
|
|
14
|
+
var nextApiResponse12_1 = require("./nextApiResponse12");
|
|
15
|
+
Object.defineProperty(exports, "nextApiResponse12", { enumerable: true, get: function () { return nextApiResponse12_1.nextApiResponse12; } });
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
export declare const nextApiResponse: {
|
|
3
|
+
ok<T>(data: T, msg?: string): NextResponse<Koine.Api.ResultOk<T>>;
|
|
4
|
+
fail<T_1>(data: T_1, msg?: string, status?: number): NextResponse<Koine.Api.ResultFail<T_1>>;
|
|
5
|
+
};
|
|
6
|
+
export default nextApiResponse;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.nextApiResponse = void 0;
|
|
4
|
+
var server_1 = require("next/server");
|
|
5
|
+
var createApiResultFail_1 = require("./createApiResultFail");
|
|
6
|
+
var createApiResultOk_1 = require("./createApiResultOk");
|
|
7
|
+
exports.nextApiResponse = {
|
|
8
|
+
ok: function (data, msg) {
|
|
9
|
+
return server_1.NextResponse.json((0, createApiResultOk_1.default)(data, msg));
|
|
10
|
+
},
|
|
11
|
+
fail: function (data, msg, status) {
|
|
12
|
+
return server_1.NextResponse.json((0, createApiResultFail_1.default)(data, msg, status));
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
exports.default = exports.nextApiResponse;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.nextApiResponse12 = void 0;
|
|
4
|
+
var createApiResultFail_1 = require("./createApiResultFail");
|
|
5
|
+
var createApiResultOk_1 = require("./createApiResultOk");
|
|
6
|
+
var nextApiResponse12 = function (nextRes) {
|
|
7
|
+
return {
|
|
8
|
+
ok: function (data, msg) {
|
|
9
|
+
nextRes.status(200).json((0, createApiResultOk_1.default)(data, msg));
|
|
10
|
+
},
|
|
11
|
+
fail: function (data, msg, status) {
|
|
12
|
+
nextRes
|
|
13
|
+
.status(status || 404)
|
|
14
|
+
.json((0, createApiResultFail_1.default)(data, msg, status));
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
exports.nextApiResponse12 = nextApiResponse12;
|
|
19
|
+
exports.default = exports.nextApiResponse12;
|
package/cjs/package.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@koine/api",
|
|
3
|
+
"sideEffects": false,
|
|
4
|
+
"dependencies": {
|
|
5
|
+
"@koine/utils": "*"
|
|
6
|
+
},
|
|
7
|
+
"peerDependenciesMeta": {
|
|
8
|
+
"next": {
|
|
9
|
+
"optional": true
|
|
10
|
+
},
|
|
11
|
+
"swr": {
|
|
12
|
+
"optional": true
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"main": "./index.js",
|
|
16
|
+
"types": "./index.d.ts"
|
|
17
|
+
}
|
package/createApi.d.ts
CHANGED
|
@@ -1,8 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Create api client
|
|
3
|
-
*
|
|
4
|
-
* @param apiName Short name to use in debug logs
|
|
5
|
-
* @param baseUrl Either relativ eor absolute, it must end without trailing slash
|
|
6
|
-
*/
|
|
7
1
|
export declare const createApi: <TEndpoints extends Koine.Api.Endpoints>(apiName: string, baseUrl: string, options?: Koine.Api.ClientOptions) => Koine.Api.Client<TEndpoints>;
|
|
8
2
|
export default createApi;
|
package/createApi.js
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { __assign, __awaiter, __generator } from "tslib";
|
|
2
|
+
import buildUrlQueryString from "@koine/utils/buildUrlQueryString";
|
|
3
|
+
import errorToString from "@koine/utils/errorToString";
|
|
4
|
+
import isFullObject from "@koine/utils/isFullObject";
|
|
5
|
+
export var createApi = function (apiName, baseUrl, options) {
|
|
6
|
+
var _a = options || {}, _b = _a.headers, headersBase = _b === void 0 ? {} : _b, _c = _a.request, requestBase = _c === void 0 ? {} : _c, throwErrBase = _a.throwErr, _d = _a.timeout, timeoutBase = _d === void 0 ? 10000 : _d, processReqBase = _a.processReq, processResBase = _a.processRes, processErrBase = _a.processErr;
|
|
7
|
+
return ["get", "post", "put", "patch", "delete"].reduce(function (api, method) {
|
|
8
|
+
api[method] = function (endpoint, options) { return __awaiter(void 0, void 0, void 0, function () {
|
|
9
|
+
var _a, _b, request, _c, headers, _d, timeout, processReq, _e, processRes, _f, processErr, _g, throwErr, _h, params, json, query, url, requestInit, transformed, transformed, key, timeoutNumber, controller, timeoutId, response, result, msg, e_1, e_2, logMsg;
|
|
10
|
+
return __generator(this, function (_j) {
|
|
11
|
+
switch (_j.label) {
|
|
12
|
+
case 0:
|
|
13
|
+
_a = options || {}, _b = _a.request, request = _b === void 0 ? requestBase : _b, _c = _a.headers, headers = _c === void 0 ? headersBase : _c, _d = _a.timeout, timeout = _d === void 0 ? timeoutBase : _d, processReq = _a.processReq, _e = _a.processRes, processRes = _e === void 0 ? processResBase : _e, _f = _a.processErr, processErr = _f === void 0 ? processErrBase : _f, _g = _a.throwErr, throwErr = _g === void 0 ? throwErrBase : _g;
|
|
14
|
+
_h = options || {}, params = _h.params, json = _h.json, query = _h.query;
|
|
15
|
+
url = "".concat(baseUrl, "/").concat(endpoint + "".replace(/^\/*/, ""));
|
|
16
|
+
requestInit = __assign(__assign({ method: method.toUpperCase() }, request), { headers: __assign({ "content-type": "application/json" }, headers) });
|
|
17
|
+
if (processReqBase) {
|
|
18
|
+
transformed = processReqBase(method, url, query, json, params, requestInit);
|
|
19
|
+
url = transformed[0];
|
|
20
|
+
query = transformed[1];
|
|
21
|
+
json = transformed[2];
|
|
22
|
+
params = transformed[3];
|
|
23
|
+
requestInit = transformed[4];
|
|
24
|
+
}
|
|
25
|
+
if (processReq) {
|
|
26
|
+
transformed = processReq(method, url, query, json, params, requestInit);
|
|
27
|
+
url = transformed[0];
|
|
28
|
+
query = transformed[1];
|
|
29
|
+
json = transformed[2];
|
|
30
|
+
params = transformed[3];
|
|
31
|
+
requestInit = transformed[4];
|
|
32
|
+
}
|
|
33
|
+
if (isFullObject(params)) {
|
|
34
|
+
for (key in params) {
|
|
35
|
+
url = url.replace("{".concat(key, "}"), params[key].toString());
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
timeoutNumber = Number(timeout);
|
|
39
|
+
if (json) {
|
|
40
|
+
requestInit.body = JSON.stringify(json);
|
|
41
|
+
}
|
|
42
|
+
if (timeoutNumber > 0) {
|
|
43
|
+
controller = new AbortController();
|
|
44
|
+
timeoutId = setTimeout(function () { return controller.abort(); }, timeoutNumber);
|
|
45
|
+
requestInit.signal = controller.signal;
|
|
46
|
+
}
|
|
47
|
+
if (query) {
|
|
48
|
+
url += buildUrlQueryString(query);
|
|
49
|
+
}
|
|
50
|
+
response = null;
|
|
51
|
+
result = null;
|
|
52
|
+
msg = "";
|
|
53
|
+
_j.label = 1;
|
|
54
|
+
case 1:
|
|
55
|
+
_j.trys.push([1, 3, , 4]);
|
|
56
|
+
return [4, fetch(url, requestInit)];
|
|
57
|
+
case 2:
|
|
58
|
+
response = _j.sent();
|
|
59
|
+
return [3, 4];
|
|
60
|
+
case 3:
|
|
61
|
+
e_1 = _j.sent();
|
|
62
|
+
msg = errorToString(e_1);
|
|
63
|
+
return [3, 4];
|
|
64
|
+
case 4:
|
|
65
|
+
if (timeoutId) {
|
|
66
|
+
clearTimeout(timeoutId);
|
|
67
|
+
}
|
|
68
|
+
if (!response) return [3, 11];
|
|
69
|
+
_j.label = 5;
|
|
70
|
+
case 5:
|
|
71
|
+
_j.trys.push([5, 10, , 11]);
|
|
72
|
+
if (!processRes) return [3, 7];
|
|
73
|
+
return [4, processRes(response, options || {})];
|
|
74
|
+
case 6:
|
|
75
|
+
result = _j.sent();
|
|
76
|
+
return [3, 9];
|
|
77
|
+
case 7: return [4, response.json()];
|
|
78
|
+
case 8:
|
|
79
|
+
result = _j.sent();
|
|
80
|
+
_j.label = 9;
|
|
81
|
+
case 9: return [3, 11];
|
|
82
|
+
case 10:
|
|
83
|
+
e_2 = _j.sent();
|
|
84
|
+
msg = errorToString(e_2);
|
|
85
|
+
return [3, 11];
|
|
86
|
+
case 11:
|
|
87
|
+
if (!(result === null)) return [3, 14];
|
|
88
|
+
if (!processErr) return [3, 13];
|
|
89
|
+
return [4, processErr(msg, options || {})];
|
|
90
|
+
case 12:
|
|
91
|
+
result = _j.sent();
|
|
92
|
+
return [3, 14];
|
|
93
|
+
case 13:
|
|
94
|
+
result = {
|
|
95
|
+
data: null,
|
|
96
|
+
msg: msg,
|
|
97
|
+
status: 100,
|
|
98
|
+
fail: true,
|
|
99
|
+
ok: false,
|
|
100
|
+
};
|
|
101
|
+
_j.label = 14;
|
|
102
|
+
case 14:
|
|
103
|
+
if (throwErr && (result === null || result === void 0 ? void 0 : result.fail)) {
|
|
104
|
+
throw result;
|
|
105
|
+
}
|
|
106
|
+
if (process.env["NODE_ENV"] !== "production") {
|
|
107
|
+
logMsg = "".concat(result === null || result === void 0 ? void 0 : result.status, ": api[").concat(apiName, "] ").concat(method.toUpperCase(), " ").concat(url);
|
|
108
|
+
if (result === null || result === void 0 ? void 0 : result.ok) {
|
|
109
|
+
console.info("\uD83D\uDFE2 ".concat(logMsg));
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
console.info("\uD83D\uDD34 ".concat(logMsg));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return [2, result];
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}); };
|
|
119
|
+
return api;
|
|
120
|
+
}, {});
|
|
121
|
+
};
|
|
122
|
+
export default createApi;
|
package/createSwrApi.d.ts
CHANGED
|
@@ -1,29 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
type SWRConfiguration, type SWRResponse } from "swr";
|
|
1
|
+
/// <reference types="./typings.d.ts" />
|
|
2
|
+
import { type BareFetcher, type SWRConfiguration, type SWRResponse } from "swr";
|
|
3
3
|
import { type SWRMutationConfiguration, type SWRMutationResponse } from "swr/mutation";
|
|
4
4
|
type SWRConfigurationExtended<Data = any, Error = any, Fn extends BareFetcher<any> = BareFetcher<any>> = SWRConfiguration<Data, Error, Fn> & {
|
|
5
|
-
/**
|
|
6
|
-
* Conditional fetching as option
|
|
7
|
-
*
|
|
8
|
-
* Moving this to an option allows us to keep the endpoints typed dictionary,
|
|
9
|
-
* e.g. we can write:
|
|
10
|
-
*
|
|
11
|
-
* ```js
|
|
12
|
-
* const { data, mutate } = myApi.useGet("User/{id}",
|
|
13
|
-
* { params: { id: aVariableMaybeContainingAnId || "" }, },
|
|
14
|
-
* { when: !!aVariableMaybeContainingAnId }
|
|
15
|
-
* );
|
|
16
|
-
*
|
|
17
|
-
* // we still have typed `data`, `mutate`
|
|
18
|
-
* ```
|
|
19
|
-
* @see https://swr.vercel.app/docs/conditional-fetching
|
|
20
|
-
*/
|
|
21
5
|
when?: boolean | (() => boolean);
|
|
22
6
|
};
|
|
23
7
|
type KoineApiMethodHookSWR<THookName extends keyof Koine.Api.HooksMapsByName, TEndpoints extends Koine.Api.Endpoints> = <TEndpoint extends Koine.Api.EndpointUrl<TEndpoints>, TMethod extends Koine.Api.RequestMethod = Koine.Api.HooksMapsByName[THookName]>(endpoint: TEndpoint, options?: Koine.Api.EndpointOptions<TEndpoints, TEndpoint, TMethod>, config?: THookName extends "useGet" ? SWRConfigurationExtended<Koine.Api.EndpointResponseOk<TEndpoints, TEndpoint, TMethod>, Koine.Api.EndpointResponseFail<TEndpoints, TEndpoint, TMethod>> : SWRMutationConfiguration<Koine.Api.EndpointResponseOk<TEndpoints, TEndpoint, TMethod>, Koine.Api.EndpointResponseFail<TEndpoints, TEndpoint, TMethod>, Koine.Api.EndpointOptions<TEndpoints, TEndpoint, TMethod>, TEndpoint>) => THookName extends "useGet" ? SWRResponse<Koine.Api.EndpointResponseOk<TEndpoints, TEndpoint, TMethod>, Koine.Api.EndpointResponseFail<TEndpoints, TEndpoint, TMethod>> : SWRMutationResponse<Koine.Api.EndpointResponseOk<TEndpoints, TEndpoint, TMethod>, Koine.Api.EndpointResponseFail<TEndpoints, TEndpoint, TMethod>, Koine.Api.EndpointOptions<TEndpoints, TEndpoint, TMethod>, TEndpoint>;
|
|
24
|
-
/**
|
|
25
|
-
* It creates an api client extended with auto-generated SWR wrapper hooks
|
|
26
|
-
*/
|
|
27
8
|
export declare const createSwrApi: <TEndpoints extends Koine.Api.Endpoints>(apiName: string, baseUrl: string, options?: Koine.Api.ClientOptions | undefined) => Koine.Api.Client<TEndpoints> & {
|
|
28
9
|
useGet: KoineApiMethodHookSWR<"useGet", TEndpoints>;
|
|
29
10
|
usePost: KoineApiMethodHookSWR<"usePost", TEndpoints>;
|
package/createSwrApi.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { __assign, __awaiter, __generator } from "tslib";
|
|
3
|
+
import useSWR from "swr";
|
|
4
|
+
import useSWRMutation from "swr/mutation";
|
|
5
|
+
import isFunction from "@koine/utils/isFunction";
|
|
6
|
+
import createApi from "./createApi.js";
|
|
7
|
+
function createUseApi(api, method) {
|
|
8
|
+
return function useApi(endpoint, options, _config) {
|
|
9
|
+
var _this = this;
|
|
10
|
+
if (method === "get") {
|
|
11
|
+
var fetcher = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
12
|
+
var data;
|
|
13
|
+
return __generator(this, function (_a) {
|
|
14
|
+
switch (_a.label) {
|
|
15
|
+
case 0: return [4, api[method](endpoint, __assign(__assign({}, (options || {})), { throwErr: true }))];
|
|
16
|
+
case 1:
|
|
17
|
+
data = (_a.sent()).data;
|
|
18
|
+
return [2, data];
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}); };
|
|
22
|
+
var config_1 = _config;
|
|
23
|
+
var shouldNotFetch = (config_1 === null || config_1 === void 0 ? void 0 : config_1.when) === false ||
|
|
24
|
+
(isFunction(config_1 === null || config_1 === void 0 ? void 0 : config_1.when) && (config_1 === null || config_1 === void 0 ? void 0 : config_1.when()) === false);
|
|
25
|
+
return useSWR(shouldNotFetch ? null : options ? [endpoint, options] : [endpoint], fetcher, config_1);
|
|
26
|
+
}
|
|
27
|
+
var config = _config;
|
|
28
|
+
var sender = function (_endpoint, _options) { return __awaiter(_this, void 0, void 0, function () {
|
|
29
|
+
var endpoint, options, _a, ok, data;
|
|
30
|
+
return __generator(this, function (_b) {
|
|
31
|
+
switch (_b.label) {
|
|
32
|
+
case 0:
|
|
33
|
+
endpoint = Array.isArray(_endpoint) ? _endpoint[0] : _endpoint;
|
|
34
|
+
options = Array.isArray(_endpoint) ? _endpoint[1] : {};
|
|
35
|
+
return [4, api[method](endpoint, __assign(__assign(__assign({}, options), (_options.arg || {})), { throwErr: true }))];
|
|
36
|
+
case 1:
|
|
37
|
+
_a = _b.sent(), ok = _a.ok, data = _a.data;
|
|
38
|
+
return [2, ok ? data : data];
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}); };
|
|
42
|
+
return useSWRMutation(options ? [endpoint, options] : endpoint, sender, config);
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export var createSwrApi = function () {
|
|
46
|
+
var args = [];
|
|
47
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
48
|
+
args[_i] = arguments[_i];
|
|
49
|
+
}
|
|
50
|
+
var api = createApi.apply(void 0, args);
|
|
51
|
+
["get", "post", "put", "patch", "delete"].forEach(function (method) {
|
|
52
|
+
var hookName = "use".concat(method.charAt(0).toUpperCase() + method.slice(1));
|
|
53
|
+
api[hookName] = createUseApi(api, method);
|
|
54
|
+
});
|
|
55
|
+
return api;
|
|
56
|
+
};
|
|
57
|
+
export default createSwrApi;
|
package/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { ApiError } from "./ApiError";
|
|
2
|
-
export { createApi } from "./createApi";
|
|
3
|
-
export { createApiResultFail } from "./createApiResultFail";
|
|
4
|
-
export { createApiResultOk } from "./createApiResultOk";
|
|
5
|
-
export { createSwrApi } from "./createSwrApi";
|
|
6
|
-
export { nextApiResponse12 } from "./nextApiResponse12";
|
|
1
|
+
export { ApiError } from "./ApiError.js";
|
|
2
|
+
export { createApi } from "./createApi.js";
|
|
3
|
+
export { createApiResultFail } from "./createApiResultFail.js";
|
|
4
|
+
export { createApiResultOk } from "./createApiResultOk.js";
|
|
5
|
+
export { createSwrApi } from "./createSwrApi.js";
|
|
6
|
+
export { nextApiResponse12 } from "./nextApiResponse12.js";
|
package/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { ApiError } from "./ApiError.js";
|
|
2
|
+
export { createApi } from "./createApi.js";
|
|
3
|
+
export { createApiResultFail } from "./createApiResultFail.js";
|
|
4
|
+
export { createApiResultOk } from "./createApiResultOk.js";
|
|
5
|
+
export { createSwrApi } from "./createSwrApi.js";
|
|
6
|
+
export { nextApiResponse12 } from "./nextApiResponse12.js";
|
package/nextApiResponse.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
1
2
|
export declare const nextApiResponse: {
|
|
2
|
-
ok<T>(data: T, msg?: string):
|
|
3
|
-
fail<T_1>(data: T_1, msg?: string, status?: number):
|
|
3
|
+
ok<T>(data: T, msg?: string): NextResponse<Koine.Api.ResultOk<T>>;
|
|
4
|
+
fail<T_1>(data: T_1, msg?: string, status?: number): NextResponse<Koine.Api.ResultFail<T_1>>;
|
|
4
5
|
};
|
|
5
6
|
export default nextApiResponse;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
import createApiResultFail from "./createApiResultFail.js";
|
|
3
|
+
import createApiResultOk from "./createApiResultOk.js";
|
|
4
|
+
export var nextApiResponse = {
|
|
5
|
+
ok: function (data, msg) {
|
|
6
|
+
return NextResponse.json(createApiResultOk(data, msg));
|
|
7
|
+
},
|
|
8
|
+
fail: function (data, msg, status) {
|
|
9
|
+
return NextResponse.json(createApiResultFail(data, msg, status));
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
export default nextApiResponse;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import createApiResultFail from "./createApiResultFail.js";
|
|
2
|
+
import createApiResultOk from "./createApiResultOk.js";
|
|
3
|
+
export var nextApiResponse12 = function (nextRes) {
|
|
4
|
+
return {
|
|
5
|
+
ok: function (data, msg) {
|
|
6
|
+
nextRes.status(200).json(createApiResultOk(data, msg));
|
|
7
|
+
},
|
|
8
|
+
fail: function (data, msg, status) {
|
|
9
|
+
nextRes
|
|
10
|
+
.status(status || 404)
|
|
11
|
+
.json(createApiResultFail(data, msg, status));
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export default nextApiResponse12;
|
package/package.json
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@koine/api",
|
|
3
3
|
"sideEffects": false,
|
|
4
|
+
"dependencies": {
|
|
5
|
+
"@koine/utils": "2.0.0-beta.15"
|
|
6
|
+
},
|
|
4
7
|
"peerDependenciesMeta": {
|
|
5
8
|
"next": {
|
|
6
9
|
"optional": true
|
|
@@ -9,12 +12,44 @@
|
|
|
9
12
|
"optional": true
|
|
10
13
|
}
|
|
11
14
|
},
|
|
12
|
-
"
|
|
13
|
-
"@koine/utils": "2.0.0-beta.13"
|
|
14
|
-
},
|
|
15
|
-
"module": "./index.mjs",
|
|
16
|
-
"main": "./index.js",
|
|
15
|
+
"main": "./cjs/index.js",
|
|
17
16
|
"types": "./index.d.ts",
|
|
17
|
+
"type": "module",
|
|
18
|
+
"module": "./index.js",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"require": "./cjs/index.js",
|
|
22
|
+
"import": "./index.js"
|
|
23
|
+
},
|
|
24
|
+
"./ApiError": {
|
|
25
|
+
"require": "./cjs/ApiError.js",
|
|
26
|
+
"import": "./ApiError.js"
|
|
27
|
+
},
|
|
28
|
+
"./createApi": {
|
|
29
|
+
"require": "./cjs/createApi.js",
|
|
30
|
+
"import": "./createApi.js"
|
|
31
|
+
},
|
|
32
|
+
"./createApiResultFail": {
|
|
33
|
+
"require": "./cjs/createApiResultFail.js",
|
|
34
|
+
"import": "./createApiResultFail.js"
|
|
35
|
+
},
|
|
36
|
+
"./createApiResultOk": {
|
|
37
|
+
"require": "./cjs/createApiResultOk.js",
|
|
38
|
+
"import": "./createApiResultOk.js"
|
|
39
|
+
},
|
|
40
|
+
"./createSwrApi": {
|
|
41
|
+
"require": "./cjs/createSwrApi.js",
|
|
42
|
+
"import": "./createSwrApi.js"
|
|
43
|
+
},
|
|
44
|
+
"./nextApiResponse": {
|
|
45
|
+
"require": "./cjs/nextApiResponse.js",
|
|
46
|
+
"import": "./nextApiResponse.js"
|
|
47
|
+
},
|
|
48
|
+
"./nextApiResponse12": {
|
|
49
|
+
"require": "./cjs/nextApiResponse12.js",
|
|
50
|
+
"import": "./nextApiResponse12.js"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
18
53
|
"peerDependencies": {},
|
|
19
|
-
"version": "2.0.0-beta.
|
|
20
|
-
}
|
|
54
|
+
"version": "2.0.0-beta.15"
|
|
55
|
+
}
|
package/typings.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ type ExtractEndpointParams<T extends string> = string extends T
|
|
|
15
15
|
? { [k in Param]: string | number }
|
|
16
16
|
: never;
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
namespace Koine.Api {
|
|
19
19
|
// @see https://stackoverflow.com/a/60702896/1938970
|
|
20
20
|
// import { Exact } from "type-fest";
|
|
21
21
|
|
|
@@ -28,7 +28,7 @@ declare namespace Koine.Api {
|
|
|
28
28
|
type ClientCreator<TEndpoints extends Endpoints> = (
|
|
29
29
|
apiName: string,
|
|
30
30
|
baseUrl: string,
|
|
31
|
-
options?: ClientOptions
|
|
31
|
+
options?: ClientOptions,
|
|
32
32
|
) => Client<TEndpoints>;
|
|
33
33
|
|
|
34
34
|
type ClientOptions = {
|
|
@@ -46,7 +46,7 @@ declare namespace Koine.Api {
|
|
|
46
46
|
*
|
|
47
47
|
* @see RequestInit
|
|
48
48
|
*
|
|
49
|
-
* @default {
|
|
49
|
+
* @default {}
|
|
50
50
|
*/
|
|
51
51
|
request?: Omit<RequestInit, "body" | "headers" | "method">;
|
|
52
52
|
/**
|
|
@@ -85,7 +85,7 @@ declare namespace Koine.Api {
|
|
|
85
85
|
|
|
86
86
|
type ClientMethod<
|
|
87
87
|
TMethod extends RequestMethod,
|
|
88
|
-
TEndpoints extends Endpoints
|
|
88
|
+
TEndpoints extends Endpoints,
|
|
89
89
|
> = <
|
|
90
90
|
TEndpoint extends EndpointUrl<TEndpoints>,
|
|
91
91
|
TOptions extends EndpointOptions<TEndpoints, TEndpoint, TMethod>,
|
|
@@ -94,10 +94,10 @@ declare namespace Koine.Api {
|
|
|
94
94
|
TEndpoints,
|
|
95
95
|
TEndpoint,
|
|
96
96
|
TMethod
|
|
97
|
-
|
|
97
|
+
>,
|
|
98
98
|
>(
|
|
99
99
|
endpoint: TEndpoint,
|
|
100
|
-
options?: TOptions
|
|
100
|
+
options?: TOptions,
|
|
101
101
|
) => Promise<EndpointResult<TEndpoints, TEndpoint, TMethod>>;
|
|
102
102
|
// ) => Promise<Result<TOk, TFail>>;
|
|
103
103
|
|
|
@@ -117,7 +117,7 @@ declare namespace Koine.Api {
|
|
|
117
117
|
type EndpointOptions<
|
|
118
118
|
TEndpoints extends Endpoints,
|
|
119
119
|
TEndpoint extends EndpointUrl<TEndpoints>,
|
|
120
|
-
TMethod extends RequestMethod
|
|
120
|
+
TMethod extends RequestMethod,
|
|
121
121
|
> = RequestOptions<
|
|
122
122
|
TEndpoints,
|
|
123
123
|
TEndpoint,
|
|
@@ -129,31 +129,31 @@ declare namespace Koine.Api {
|
|
|
129
129
|
type EndpointResultOk<
|
|
130
130
|
TEndpoints extends Endpoints,
|
|
131
131
|
TEndpoint extends EndpointUrl<TEndpoints>,
|
|
132
|
-
TMethod extends RequestMethod
|
|
132
|
+
TMethod extends RequestMethod,
|
|
133
133
|
> = ResultOk<TEndpoints[TEndpoint][Uppercase<TMethod>]["ok"]>;
|
|
134
134
|
|
|
135
135
|
type EndpointResultFail<
|
|
136
136
|
TEndpoints extends Endpoints,
|
|
137
137
|
TEndpoint extends EndpointUrl<TEndpoints>,
|
|
138
|
-
TMethod extends RequestMethod
|
|
138
|
+
TMethod extends RequestMethod,
|
|
139
139
|
> = ResultFail<TEndpoints[TEndpoint][Uppercase<TMethod>]["fail"]>;
|
|
140
140
|
|
|
141
141
|
type EndpointResponseOk<
|
|
142
142
|
TEndpoints extends Endpoints,
|
|
143
143
|
TEndpoint extends EndpointUrl<TEndpoints>,
|
|
144
|
-
TMethod extends RequestMethod
|
|
144
|
+
TMethod extends RequestMethod,
|
|
145
145
|
> = TEndpoints[TEndpoint][Uppercase<TMethod>]["ok"];
|
|
146
146
|
|
|
147
147
|
type EndpointResponseFail<
|
|
148
148
|
TEndpoints extends Endpoints,
|
|
149
149
|
TEndpoint extends EndpointUrl<TEndpoints>,
|
|
150
|
-
TMethod extends RequestMethod
|
|
150
|
+
TMethod extends RequestMethod,
|
|
151
151
|
> = TEndpoints[TEndpoint][Uppercase<TMethod>]["fail"];
|
|
152
152
|
|
|
153
153
|
type EndpointResult<
|
|
154
154
|
TEndpoints extends Endpoints,
|
|
155
155
|
TEndpoint extends EndpointUrl<TEndpoints>,
|
|
156
|
-
TMethod extends RequestMethod
|
|
156
|
+
TMethod extends RequestMethod,
|
|
157
157
|
> = Result<
|
|
158
158
|
EndpointResponseOk<TEndpoints, TEndpoint, TMethod>,
|
|
159
159
|
EndpointResponseFail<TEndpoints, TEndpoint, TMethod>
|
|
@@ -240,7 +240,7 @@ declare namespace Koine.Api {
|
|
|
240
240
|
TEndpoint extends EndpointUrl<TEndpoints>,
|
|
241
241
|
TMethod extends RequestMethod,
|
|
242
242
|
TJson extends RequestJson,
|
|
243
|
-
TQuery extends RequestQuery
|
|
243
|
+
TQuery extends RequestQuery,
|
|
244
244
|
> = Omit<ClientOptions, "processReq"> & {
|
|
245
245
|
processReq?: EndpointRequestProcessor<TEndpoints, TEndpoint, TMethod>;
|
|
246
246
|
/**
|
|
@@ -273,7 +273,7 @@ declare namespace Koine.Api {
|
|
|
273
273
|
type ResponseFail = unknown;
|
|
274
274
|
|
|
275
275
|
type ResultShared<
|
|
276
|
-
T extends Record<string, unknown> = Record<string, unknown
|
|
276
|
+
T extends Record<string, unknown> = Record<string, unknown>,
|
|
277
277
|
> = T & {
|
|
278
278
|
status: _Response["status"];
|
|
279
279
|
msg: _Response["statusText"];
|
|
@@ -297,7 +297,7 @@ declare namespace Koine.Api {
|
|
|
297
297
|
|
|
298
298
|
type Result<
|
|
299
299
|
TResponseOk extends ResponseOk,
|
|
300
|
-
TResponseFail extends ResponseFail
|
|
300
|
+
TResponseFail extends ResponseFail,
|
|
301
301
|
> =
|
|
302
302
|
| {
|
|
303
303
|
status: _Response["status"];
|
|
@@ -324,13 +324,13 @@ declare namespace Koine.Api {
|
|
|
324
324
|
query: any,
|
|
325
325
|
json: any,
|
|
326
326
|
params: any,
|
|
327
|
-
requestInit: RequestInit
|
|
327
|
+
requestInit: RequestInit,
|
|
328
328
|
) => [
|
|
329
329
|
string, // url
|
|
330
330
|
RequestQuery, // query
|
|
331
331
|
RequestJson, // json
|
|
332
332
|
RequestParams, // params
|
|
333
|
-
RequestInit // requestInit
|
|
333
|
+
RequestInit, // requestInit
|
|
334
334
|
];
|
|
335
335
|
|
|
336
336
|
/**
|
|
@@ -343,20 +343,20 @@ declare namespace Koine.Api {
|
|
|
343
343
|
type EndpointRequestProcessor<
|
|
344
344
|
TEndpoints extends Endpoints,
|
|
345
345
|
TEndpoint extends EndpointUrl<TEndpoints>,
|
|
346
|
-
TMethod extends RequestMethod
|
|
346
|
+
TMethod extends RequestMethod,
|
|
347
347
|
> = (
|
|
348
348
|
method: TMethod,
|
|
349
349
|
url: string,
|
|
350
350
|
query: EndpointOptions<TEndpoints, TEndpoint, TMethod>["query"],
|
|
351
351
|
json: EndpointOptions<TEndpoints, TEndpoint, TMethod>["json"],
|
|
352
352
|
params: EndpointOptions<TEndpoints, TEndpoint, TMethod>["params"],
|
|
353
|
-
requestInit: RequestInit
|
|
353
|
+
requestInit: RequestInit,
|
|
354
354
|
) => [
|
|
355
355
|
string, // url
|
|
356
356
|
EndpointOptions<TEndpoints, TEndpoint, TMethod>["query"], // query
|
|
357
357
|
EndpointOptions<TEndpoints, TEndpoint, TMethod>["json"], // json
|
|
358
358
|
EndpointOptions<TEndpoints, TEndpoint, TMethod>["params"], // params
|
|
359
|
-
RequestInit // requestInit
|
|
359
|
+
RequestInit, // requestInit
|
|
360
360
|
];
|
|
361
361
|
|
|
362
362
|
/**
|
|
@@ -365,7 +365,7 @@ declare namespace Koine.Api {
|
|
|
365
365
|
*/
|
|
366
366
|
type ResponseProcessorRes = <TResponseOk extends ResponseOk = ResponseOk>(
|
|
367
367
|
response: _Response,
|
|
368
|
-
options: TOptions
|
|
368
|
+
options: TOptions,
|
|
369
369
|
) => Promise<Koine.Api.Result<TResponseOk>>;
|
|
370
370
|
|
|
371
371
|
/**
|
|
@@ -373,10 +373,10 @@ declare namespace Koine.Api {
|
|
|
373
373
|
* transformations to a single or all endpoint responses
|
|
374
374
|
*/
|
|
375
375
|
type ResponseProcessorErr = <
|
|
376
|
-
TResponseFail extends ResponseFailed = ResponseFailed
|
|
376
|
+
TResponseFail extends ResponseFailed = ResponseFailed,
|
|
377
377
|
>(
|
|
378
378
|
msg: string,
|
|
379
|
-
options: TOptions
|
|
379
|
+
options: TOptions,
|
|
380
380
|
) => Promise<Koine.Api.Result<TResponseFail>>;
|
|
381
381
|
|
|
382
382
|
//////////////////////////////////////////////////////////////////////////////
|
package/ApiError.mjs
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Custom `ApiError` class extending `Error` to throw in failed response.
|
|
3
|
-
*
|
|
4
|
-
* @see https://eslint.org/docs/rules/no-throw-literal
|
|
5
|
-
* @see https://github.com/sindresorhus/ky/blob/main/source/errors/HTTPError.ts
|
|
6
|
-
*
|
|
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);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
export default ApiError;
|
package/README.md
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# @koine/api
|
package/createApi.mjs
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import buildUrlQueryString from "@koine/utils/buildUrlQueryString";
|
|
2
|
-
import errorToString from "@koine/utils/errorToString";
|
|
3
|
-
import isFullObject from "@koine/utils/isFullObject";
|
|
4
|
-
/**
|
|
5
|
-
* Create api client
|
|
6
|
-
*
|
|
7
|
-
* @param apiName Short name to use in debug logs
|
|
8
|
-
* @param baseUrl Either relativ eor absolute, it must end without trailing slash
|
|
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
|
-
// @ts-expect-error FIXME: type
|
|
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}`);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
return result;
|
|
124
|
-
};
|
|
125
|
-
return api;
|
|
126
|
-
}, {});
|
|
127
|
-
};
|
|
128
|
-
export default createApi;
|
package/createApiResultFail.mjs
DELETED
package/createApiResultOk.mjs
DELETED
package/createSwrApi.mjs
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import useSWR from "swr";
|
|
3
|
-
import useSWRMutation from "swr/mutation";
|
|
4
|
-
import isFunction from "@koine/utils/isFunction";
|
|
5
|
-
import createApi from "./createApi";
|
|
6
|
-
function createUseApi(api, method) {
|
|
7
|
-
return function useApi(endpoint, options, _config) {
|
|
8
|
-
if (method === "get") {
|
|
9
|
-
// const fetcher = async (_endpoint: TEndpoint) => {
|
|
10
|
-
// try {
|
|
11
|
-
// const { ok, data } = await api[method](_endpoint, {
|
|
12
|
-
// ...(options || {}),
|
|
13
|
-
// throwErr: true,
|
|
14
|
-
// });
|
|
15
|
-
// if (ok) {
|
|
16
|
-
// return data;
|
|
17
|
-
// }
|
|
18
|
-
// throw new Error() as unknown as Koine.Api.EndpointResponseFail<TEndpoints, TEndpoint, TMethod>;
|
|
19
|
-
// } catch(e) {
|
|
20
|
-
// throw new Error() as unknown as Koine.Api.EndpointResponseFail<TEndpoints, TEndpoint, TMethod>;;
|
|
21
|
-
// }
|
|
22
|
-
// };
|
|
23
|
-
// }
|
|
24
|
-
const fetcher = async ()=>{
|
|
25
|
-
const { data } = await api[method](endpoint, {
|
|
26
|
-
...options || {},
|
|
27
|
-
throwErr: true
|
|
28
|
-
});
|
|
29
|
-
return data;
|
|
30
|
-
};
|
|
31
|
-
const config = _config;
|
|
32
|
-
const shouldNotFetch = config?.when === false || isFunction(config?.when) && config?.when() === false;
|
|
33
|
-
// <Data = any, Error = any>(key: Key, config: SWRConfigurationExtended<Data, Error, Fetcher<Data>> | undefined): SWRResponse<Data, Error>;
|
|
34
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
35
|
-
return useSWR(shouldNotFetch ? null : options ? [
|
|
36
|
-
endpoint,
|
|
37
|
-
options
|
|
38
|
-
] : [
|
|
39
|
-
endpoint
|
|
40
|
-
], fetcher, config);
|
|
41
|
-
}
|
|
42
|
-
const config = _config;
|
|
43
|
-
const sender = async (// if the first argument is an array the second tem are the base options
|
|
44
|
-
// defined when calling the usePost/Put/etc. hook, these will be overriden
|
|
45
|
-
// by the _options just here below
|
|
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
|
|
54
|
-
});
|
|
55
|
-
return ok ? data : data;
|
|
56
|
-
};
|
|
57
|
-
// config.fetcher = sender;
|
|
58
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
59
|
-
return useSWRMutation(// @ts-expect-error FIXME: I can't get it...
|
|
60
|
-
options ? [
|
|
61
|
-
endpoint,
|
|
62
|
-
options
|
|
63
|
-
] : endpoint, sender, config);
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* It creates an api client extended with auto-generated SWR wrapper hooks
|
|
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)}`;
|
|
78
|
-
api[hookName] = createUseApi(api, method);
|
|
79
|
-
});
|
|
80
|
-
return api;
|
|
81
|
-
};
|
|
82
|
-
export default createSwrApi;
|
package/nextApiResponse.mjs
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { NextResponse } from "next/server";
|
|
2
|
-
import createApiResultFail from "./createApiResultFail";
|
|
3
|
-
import createApiResultOk from "./createApiResultOk";
|
|
4
|
-
export const nextApiResponse = {
|
|
5
|
-
ok (data, msg) {
|
|
6
|
-
NextResponse.json(createApiResultOk(data, msg));
|
|
7
|
-
},
|
|
8
|
-
fail (data, msg, status) {
|
|
9
|
-
NextResponse.json(createApiResultFail(data, msg, status));
|
|
10
|
-
}
|
|
11
|
-
};
|
|
12
|
-
export default nextApiResponse;
|
package/nextApiResponse12.mjs
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import createApiResultFail from "./createApiResultFail";
|
|
2
|
-
import createApiResultOk from "./createApiResultOk";
|
|
3
|
-
export const nextApiResponse12 = (nextRes)=>{
|
|
4
|
-
return {
|
|
5
|
-
ok (data, msg) {
|
|
6
|
-
nextRes.status(200).json(createApiResultOk(data, msg));
|
|
7
|
-
},
|
|
8
|
-
fail (data, msg, status) {
|
|
9
|
-
nextRes.status(status || 404).json(createApiResultFail(data, msg, status));
|
|
10
|
-
}
|
|
11
|
-
};
|
|
12
|
-
};
|
|
13
|
-
export default nextApiResponse12;
|
|
File without changes
|