@koine/api 1.0.49 → 1.0.52

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/core/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { __assign, __awaiter, __extends, __generator } from "tslib";
2
- import { buildUrlQueryString } from "@koine/utils";
2
+ import { buildUrlQueryString, isFullObject } from "@koine/utils";
3
3
  /**
4
4
  * Custom `ApiError` class extending `Error` to throw in failed response.
5
5
  *
@@ -25,24 +25,24 @@ export { ApiError };
25
25
  * @param baseUrl Either relativ eor absolute, it must end without trailing slash
26
26
  */
27
27
  export var createApi = function (apiName, baseUrl, options) {
28
- var _a = options || {}, transformRequestBase = _a.transformRequest, transformResponseBase = _a.transformResponse, _b = _a.request, requestBase = _b === void 0 ? {
28
+ var _a = options || {}, _b = _a.headers, headersBase = _b === void 0 ? {} : _b, _c = _a.request, requestBase = _c === void 0 ? {
29
29
  credentials: "include",
30
30
  referrerPolicy: "no-referrer",
31
31
  // mode: "cors",
32
32
  // redirect: "follow",
33
33
  // cache: "no-cache",
34
- } : _b, shouldThrowBase = _a.shouldThrow;
34
+ } : _c, shouldThrowBase = _a.shouldThrow, _d = _a.timeout, timeoutBase = _d === void 0 ? 10000 : _d, transformRequestBase = _a.transformRequest, transformResponseBase = _a.transformResponse;
35
35
  return ["get", "post", "put", "patch", "delete"].reduce(function (api, method) {
36
36
  api[method] = function (endpoint, options) { return __awaiter(void 0, void 0, void 0, function () {
37
- var _a, json, path, params, _b, request, _c, headers, _d, timeout, _e, transformRequest, _f, transformResponse, _g, shouldThrow, requestInit, key, timeoutNumber, controller, timeoutId, url, response, e_1, result, e_2, msg;
37
+ var _a, params, json, query, _b, request, _c, headers, _d, timeout, _e, transformRequest, _f, transformResponse, _g, shouldThrow, requestInit, key, timeoutNumber, controller, timeoutId, url, response, e_1, result, e_2, msg;
38
38
  return __generator(this, function (_h) {
39
39
  switch (_h.label) {
40
40
  case 0:
41
- _a = options || {}, json = _a.json, path = _a.path, params = _a.params, _b = _a.request, request = _b === void 0 ? requestBase : _b, _c = _a.headers, headers = _c === void 0 ? {} : _c, _d = _a.timeout, timeout = _d === void 0 ? 10000 : _d, _e = _a.transformRequest, transformRequest = _e === void 0 ? transformRequestBase : _e, _f = _a.transformResponse, transformResponse = _f === void 0 ? transformResponseBase : _f, _g = _a.shouldThrow, shouldThrow = _g === void 0 ? shouldThrowBase : _g;
41
+ _a = options || {}, params = _a.params, json = _a.json, query = _a.query, _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, _e = _a.transformRequest, transformRequest = _e === void 0 ? transformRequestBase : _e, _f = _a.transformResponse, transformResponse = _f === void 0 ? transformResponseBase : _f, _g = _a.shouldThrow, shouldThrow = _g === void 0 ? shouldThrowBase : _g;
42
42
  requestInit = __assign(__assign({ method: method.toUpperCase() }, request), { headers: __assign({ "content-type": "application/json" }, headers) });
43
- if (path && Object.keys(path).length) {
44
- for (key in path) {
45
- endpoint = endpoint.replace("{".concat(key, "}"), path[key].toString());
43
+ if (isFullObject(params)) {
44
+ for (key in params) {
45
+ endpoint = endpoint.replace("{".concat(key, "}"), params[key].toString());
46
46
  }
47
47
  }
48
48
  timeoutNumber = Number(timeout);
@@ -58,10 +58,9 @@ export var createApi = function (apiName, baseUrl, options) {
58
58
  if (transformRequest) {
59
59
  requestInit = transformRequest(requestInit);
60
60
  }
61
- if (params) {
61
+ if (query) {
62
62
  // FIXME: ts-expect-error this assertion is not the best, but nevermind for now
63
- // url += buildUrlQueryString(params as unknown as Koine.Api.RequestParams);
64
- url += buildUrlQueryString(params);
63
+ url += buildUrlQueryString(query);
65
64
  }
66
65
  if (!shouldThrow) return [3 /*break*/, 5];
67
66
  _h.label = 1;
@@ -123,10 +122,10 @@ export var createApi = function (apiName, baseUrl, options) {
123
122
  if (process.env["NODE_ENV"] !== "production") {
124
123
  msg = "".concat(result.status, ": api[").concat(apiName, "] ").concat(method.toUpperCase(), " ").concat(url);
125
124
  if (result.ok) {
126
- console.log("[@koine] \uD83D\uDFE2 ".concat(msg));
125
+ console.log("\uD83D\uDFE2 ".concat(msg));
127
126
  }
128
127
  else {
129
- console.log("[@koine] \uD83D\uDD34 ".concat(msg));
128
+ console.log("\uD83D\uDD34 ".concat(msg));
130
129
  }
131
130
  }
132
131
  return [2 /*return*/, result];
@@ -28,24 +28,24 @@ exports.ApiError = ApiError;
28
28
  * @param baseUrl Either relativ eor absolute, it must end without trailing slash
29
29
  */
30
30
  var createApi = function (apiName, baseUrl, options) {
31
- var _a = options || {}, transformRequestBase = _a.transformRequest, transformResponseBase = _a.transformResponse, _b = _a.request, requestBase = _b === void 0 ? {
31
+ var _a = options || {}, _b = _a.headers, headersBase = _b === void 0 ? {} : _b, _c = _a.request, requestBase = _c === void 0 ? {
32
32
  credentials: "include",
33
33
  referrerPolicy: "no-referrer",
34
34
  // mode: "cors",
35
35
  // redirect: "follow",
36
36
  // cache: "no-cache",
37
- } : _b, shouldThrowBase = _a.shouldThrow;
37
+ } : _c, shouldThrowBase = _a.shouldThrow, _d = _a.timeout, timeoutBase = _d === void 0 ? 10000 : _d, transformRequestBase = _a.transformRequest, transformResponseBase = _a.transformResponse;
38
38
  return ["get", "post", "put", "patch", "delete"].reduce(function (api, method) {
39
39
  api[method] = function (endpoint, options) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
40
- var _a, json, path, params, _b, request, _c, headers, _d, timeout, _e, transformRequest, _f, transformResponse, _g, shouldThrow, requestInit, key, timeoutNumber, controller, timeoutId, url, response, e_1, result, e_2, msg;
40
+ var _a, params, json, query, _b, request, _c, headers, _d, timeout, _e, transformRequest, _f, transformResponse, _g, shouldThrow, requestInit, key, timeoutNumber, controller, timeoutId, url, response, e_1, result, e_2, msg;
41
41
  return tslib_1.__generator(this, function (_h) {
42
42
  switch (_h.label) {
43
43
  case 0:
44
- _a = options || {}, json = _a.json, path = _a.path, params = _a.params, _b = _a.request, request = _b === void 0 ? requestBase : _b, _c = _a.headers, headers = _c === void 0 ? {} : _c, _d = _a.timeout, timeout = _d === void 0 ? 10000 : _d, _e = _a.transformRequest, transformRequest = _e === void 0 ? transformRequestBase : _e, _f = _a.transformResponse, transformResponse = _f === void 0 ? transformResponseBase : _f, _g = _a.shouldThrow, shouldThrow = _g === void 0 ? shouldThrowBase : _g;
44
+ _a = options || {}, params = _a.params, json = _a.json, query = _a.query, _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, _e = _a.transformRequest, transformRequest = _e === void 0 ? transformRequestBase : _e, _f = _a.transformResponse, transformResponse = _f === void 0 ? transformResponseBase : _f, _g = _a.shouldThrow, shouldThrow = _g === void 0 ? shouldThrowBase : _g;
45
45
  requestInit = tslib_1.__assign(tslib_1.__assign({ method: method.toUpperCase() }, request), { headers: tslib_1.__assign({ "content-type": "application/json" }, headers) });
46
- if (path && Object.keys(path).length) {
47
- for (key in path) {
48
- endpoint = endpoint.replace("{".concat(key, "}"), path[key].toString());
46
+ if ((0, utils_1.isFullObject)(params)) {
47
+ for (key in params) {
48
+ endpoint = endpoint.replace("{".concat(key, "}"), params[key].toString());
49
49
  }
50
50
  }
51
51
  timeoutNumber = Number(timeout);
@@ -61,10 +61,9 @@ var createApi = function (apiName, baseUrl, options) {
61
61
  if (transformRequest) {
62
62
  requestInit = transformRequest(requestInit);
63
63
  }
64
- if (params) {
64
+ if (query) {
65
65
  // FIXME: ts-expect-error this assertion is not the best, but nevermind for now
66
- // url += buildUrlQueryString(params as unknown as Koine.Api.RequestParams);
67
- url += (0, utils_1.buildUrlQueryString)(params);
66
+ url += (0, utils_1.buildUrlQueryString)(query);
68
67
  }
69
68
  if (!shouldThrow) return [3 /*break*/, 5];
70
69
  _h.label = 1;
@@ -126,10 +125,10 @@ var createApi = function (apiName, baseUrl, options) {
126
125
  if (process.env["NODE_ENV"] !== "production") {
127
126
  msg = "".concat(result.status, ": api[").concat(apiName, "] ").concat(method.toUpperCase(), " ").concat(url);
128
127
  if (result.ok) {
129
- console.log("[@koine] \uD83D\uDFE2 ".concat(msg));
128
+ console.log("\uD83D\uDFE2 ".concat(msg));
130
129
  }
131
130
  else {
132
- console.log("[@koine] \uD83D\uDD34 ".concat(msg));
131
+ console.log("\uD83D\uDD34 ".concat(msg));
133
132
  }
134
133
  }
135
134
  return [2 /*return*/, result];
package/node/swr/index.js CHANGED
@@ -46,7 +46,7 @@ function createUseApi(api, method) {
46
46
  // defined when calling the usePost/Put/etc. hook, these will be overriden
47
47
  // by the _options just here below
48
48
  _endpoint,
49
- // these are the options arriving when calling `trigger({ json, params, etc... })
49
+ // these are the options arriving when calling `trigger({ json, query, etc... })
50
50
  _options) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
51
51
  var endpoint, options, _a, ok, data;
52
52
  return tslib_1.__generator(this, function (_b) {
package/package.json CHANGED
@@ -5,12 +5,12 @@
5
5
  "typings": "./index.d.ts",
6
6
  "dependencies": {},
7
7
  "peerDependencies": {
8
- "@koine/utils": "1.0.49",
8
+ "@koine/utils": "1.0.52",
9
9
  "next": "^12.2.0",
10
10
  "swr": "^2.0.0-beta.6",
11
11
  "tslib": "^2.4.0"
12
12
  },
13
- "version": "1.0.49",
13
+ "version": "1.0.52",
14
14
  "module": "./index.js",
15
15
  "types": "./index.d.ts"
16
16
  }
package/swr/index.js CHANGED
@@ -43,7 +43,7 @@ function createUseApi(api, method) {
43
43
  // defined when calling the usePost/Put/etc. hook, these will be overriden
44
44
  // by the _options just here below
45
45
  _endpoint,
46
- // these are the options arriving when calling `trigger({ json, params, etc... })
46
+ // these are the options arriving when calling `trigger({ json, query, etc... })
47
47
  _options) { return __awaiter(_this, void 0, void 0, function () {
48
48
  var endpoint, options, _a, ok, data;
49
49
  return __generator(this, function (_b) {
package/typings.d.ts CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  type _Response = Response;
4
4
 
5
+ /**
6
+ * @borrows [awesome-template-literal-types](https://github.com/ghoullier/awesome-template-literal-types#router-params-parsing)
7
+ */
8
+ type ExtractEndpointParams<T extends string> = string extends T
9
+ ? Record<string, string>
10
+ : // eslint-disable-next-line @typescript-eslint/no-unused-vars
11
+ T extends `${infer _Start}{${infer Param}}${infer Rest}`
12
+ ? { [k in Param | keyof ExtractEndpointParams<Rest>]: string | number }
13
+ : // eslint-disable-next-line @typescript-eslint/no-unused-vars
14
+ T extends `${infer _Start}{${infer Param}}`
15
+ ? { [k in Param]: string | number }
16
+ : never;
17
+
5
18
  declare namespace Koine.Api {
6
19
  // @see https://stackoverflow.com/a/60702896/1938970
7
20
  // import { Exact } from "type-fest";
@@ -19,6 +32,15 @@ declare namespace Koine.Api {
19
32
  ) => Client<TEndpoints>;
20
33
 
21
34
  type ClientOptions = {
35
+ /**
36
+ * Headers will be merged with
37
+ * ```
38
+ * { "content-type": "application/json" }
39
+ * ```
40
+ *
41
+ * @default {}
42
+ */
43
+ headers?: RequestInit["headers"];
22
44
  /**
23
45
  * Basic request options to supply to `fetch`
24
46
  *
@@ -27,9 +49,30 @@ declare namespace Koine.Api {
27
49
  * @default { credentials: "include", referrerPolicy: "no-referrer" }
28
50
  */
29
51
  request?: Omit<RequestInit, "body" | "headers" | "method">;
52
+ /**
53
+ * Flag to throw error with try/catch
54
+ *
55
+ * @default false
56
+ */
57
+ shouldThrow?: boolean;
58
+ /**
59
+ * Timeout in `ms`, if `falsy` there is no timeout
60
+ *
61
+ * @default 10000
62
+ */
63
+ timeout?: number | false | null;
64
+ /**
65
+ * Transform request before actual http call
66
+ *
67
+ * @default undefined
68
+ */
30
69
  transformRequest?: RequestTransformer;
70
+ /**
71
+ * Transform response just after http response
72
+ *
73
+ * @default undefined
74
+ */
31
75
  transformResponse?: ResponseTransformer;
32
- shouldThrow?: boolean;
33
76
  };
34
77
 
35
78
  type ClientMethod<
@@ -38,12 +81,8 @@ declare namespace Koine.Api {
38
81
  > = <
39
82
  TEndpoint extends EndpointUrl<TEndpoints>,
40
83
  TOptions extends EndpointRequestOptions<TEndpoints, TEndpoint, TMethod>,
41
- TSuccesfull extends Koine.Api.DataSuccesfull = Koine.Api.EndpointResponseOk<
42
- TEndpoints,
43
- TEndpoint,
44
- TMethod
45
- >,
46
- TFailed extends Koine.Api.DataFailed = Koine.Api.EndpointResponseFail<
84
+ TOk extends ResponseOk = EndpointResponseOk<TEndpoints, TEndpoint, TMethod>,
85
+ TFail extends ResponseFail = EndpointResponseFail<
47
86
  TEndpoints,
48
87
  TEndpoint,
49
88
  TMethod
@@ -51,8 +90,8 @@ declare namespace Koine.Api {
51
90
  >(
52
91
  endpoint: TEndpoint,
53
92
  options?: TOptions
54
- // ) => Promise<EndpointResponse<TEndpoints, TEndpoint, TMethod>>;
55
- ) => Promise<Result<TSuccesfull, TFailed>>;
93
+ ) => Promise<EndpointResponse<TEndpoints, TEndpoint, TMethod>>;
94
+ // ) => Promise<Result<TOk, TFail>>;
56
95
 
57
96
  /**
58
97
  * The `api` interface generated by `createApi`
@@ -74,7 +113,8 @@ declare namespace Koine.Api {
74
113
  > = RequestOptions<
75
114
  TMethod,
76
115
  TEndpoints[TEndpoint][Uppercase<TMethod>]["json"],
77
- TEndpoints[TEndpoint][Uppercase<TMethod>]["params"]
116
+ TEndpoints[TEndpoint][Uppercase<TMethod>]["query"],
117
+ TEndpoint
78
118
  >;
79
119
 
80
120
  type EndpointResultOk<
@@ -155,7 +195,7 @@ declare namespace Koine.Api {
155
195
  /**
156
196
  * The parameters to encode in the URL of the request
157
197
  */
158
- params?: RequestParams;
198
+ query?: RequestQuery;
159
199
  /**
160
200
  * The JSON response data returned by the request in case of success
161
201
  */
@@ -175,66 +215,40 @@ declare namespace Koine.Api {
175
215
 
176
216
  type RequestJson = undefined | null | Record<string | number, unknown>;
177
217
 
178
- type RequestParams = undefined | null | Record<string | number, unknown>;
218
+ type RequestQuery = undefined | null | Record<string | number, unknown>;
179
219
 
180
220
  /**
181
- * Shared request options (for every request method)
221
+ * Request options
182
222
  *
183
- * Client options can be overriden here at request level.
223
+ * `ClientOptions` can be overriden here at the single request level.
184
224
  */
185
- type RequestOptionsShared = ClientOptions & {
186
- /**
187
- * Headers will be merged with
188
- * ```
189
- * { "content-type": "application/json" }
190
- * ```
191
- */
192
- headers?: RequestInit["headers"];
225
+ type RequestOptions<
226
+ TMethod extends RequestMethod,
227
+ TJson extends RequestJson = RequestJson,
228
+ TQuery extends RequestQuery = RequestQuery,
229
+ TEndpoint extends EndpointUrl<TEndpoints> = ""
230
+ > = ClientOptions & {
193
231
  /**
194
- * Timeout in `ms`, if `falsy` there is no timeout
232
+ * A dictionary to dynamically interpolate endpoint url params, e.g.:
195
233
  *
196
- * @default 10000
234
+ * ```js
235
+ * myapi.get("user/{id}", { path: { id: "12" }})
236
+ * ```
237
+ * results in a call to the endpoint `"user/12"`
197
238
  */
198
- timeout?: number | false | null;
239
+ params?: ExtractEndpointParams<TEndpoint>;
199
240
  /**
200
- * Basic request options to supply to `fetch`
201
- *
202
- * @see RequestInit
203
- *
204
- * @default { credentials: "include", referrerPolicy: "no-referrer" }
241
+ * Query parameters will be serialized into a string and appended to the URL
205
242
  */
206
- request?: Omit<RequestInit, "body" | "headers" | "method">;
207
- /**
208
- * A dictionary to dynamically interpolate endpoint url values, e.g.:
209
- *
210
- * ```
211
- * "user/{id}" endpoint with { path: { id: "12" }} results in a call
212
- * to the endpoint "user/12"
213
- * ```
214
- */
215
- path?: Record<string, string | number>;
216
- };
217
-
218
- /**
219
- * Request options
220
- *
221
- * Client options can be overriden here at request level.
222
- */
223
- type RequestOptions<
224
- TMethod extends RequestMethod,
225
- TJson extends Record<string, unknown> = {},
226
- TParams extends RequestParams = {}
227
- > = RequestOptionsShared &
228
- ([TMethod] extends ["get"]
243
+ query?: TQuery;
244
+ } & ([TMethod] extends ["get"]
229
245
  ? {
230
246
  /**
231
247
  * JSON request body
248
+ *
249
+ * FIXME: this should be `undefined` here but it breaks
232
250
  */
233
251
  json?: TJson;
234
- /**
235
- * Params will be serialized into a string and appended to the URL
236
- */
237
- params?: TParams;
238
252
  }
239
253
  : {
240
254
  /**
@@ -243,10 +257,6 @@ declare namespace Koine.Api {
243
257
  * @default {}
244
258
  */
245
259
  json?: TJson;
246
- /**
247
- * Params will be serialized into a string and appended to the URL
248
- */
249
- params?: TParams;
250
260
  });
251
261
 
252
262
  type RequestMethod = "get" | "post" | "put" | "patch" | "delete";