keq 2.1.1 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ## [2.2.0](https://github.com/keq-request/keq/compare/v2.1.2...v2.2.0) (2024-02-04)
6
+
7
+
8
+ ### Features
9
+
10
+ * add .timeout(millisecond) ([b99009b](https://github.com/keq-request/keq/commit/b99009b6eb4a017d648a29a8b34b478dc22320ee))
11
+
12
+ ## [2.1.2](https://github.com/keq-request/keq/compare/v2.1.1...v2.1.2) (2024-01-17)
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * unable send request when parentheses exit in pathname ([24c81ff](https://github.com/keq-request/keq/commit/24c81ffdde71919163a09778aa15ae6106427d45))
18
+
5
19
  ## [2.1.1](https://github.com/keq-request/keq/compare/v2.1.0...v2.1.1) (2024-01-09)
6
20
 
7
21
 
package/README.md CHANGED
@@ -6,10 +6,12 @@
6
6
  <h1 align="center" style="text-align: center">KEQ</h1>
7
7
  <!-- title -->
8
8
 
9
- [![version](https://img.shields.io/npm/v/keq.svg?logo=npm&style=for-the-badge)](https://www.npmjs.com/package/keq)
10
- [![downloads](https://img.shields.io/npm/dm/keq.svg?logo=npm&style=for-the-badge)](https://www.npmjs.com/package/keq)
11
- [![dependencies](https://img.shields.io/librariesio/release/npm/keq?logo=npm&style=for-the-badge)](https://www.npmjs.com/package/keq)
12
- [![license](https://img.shields.io/npm/l/keq.svg?logo=github&style=for-the-badge)](https://www.npmjs.com/package/keq)
9
+ [npm]: https://www.npmjs.com/package/keq
10
+
11
+ [![version](https://img.shields.io/npm/v/keq.svg?logo=npm&style=for-the-badge)][npm]
12
+ [![downloads](https://img.shields.io/npm/dm/keq.svg?logo=npm&style=for-the-badge)][npm]
13
+ [![dependencies](https://img.shields.io/librariesio/release/npm/keq?logo=npm&style=for-the-badge)][npm]
14
+ [![license](https://img.shields.io/npm/l/keq.svg?logo=github&style=for-the-badge)][npm]
13
15
  [![Codecov](https://img.shields.io/codecov/c/gh/keq-request/keq?logo=codecov&token=PLF0DT6869&style=for-the-badge)](https://codecov.io/gh/keq-request/keq)
14
16
 
15
17
  <!-- description -->
@@ -150,24 +152,20 @@ await request
150
152
  ### Request routing parameters
151
153
 
152
154
  The `.params()` method accepts key and value, which when used for the request with routing parameters.
153
- The follwing will produce the path `/search/keq`.
154
-
155
- ```javascript
156
- import { request } from "keq";
157
-
158
- await request
159
- .get("/search/:searchKey")
160
- .params("searchKey", "keq");
161
- ```
162
-
163
- Or as a single object:
164
155
 
165
156
  ```javascript
166
157
  import { request } from "keq";
167
158
 
168
159
  await request
169
- .get("/search/:searchKey")
170
- .params({ searchKey: "keq" });
160
+ // request to /users/jack/books/kafka
161
+ .get("/users/:userName/books/{bookName}")
162
+ .params("userName", 'jack');
163
+ .params("bookName", "kafka");
164
+ // or invoke with an object
165
+ .params({
166
+ "userName": "jack",
167
+ "bookName": "kafka"
168
+ })
171
169
  ```
172
170
 
173
171
  ### JSON Request
@@ -357,6 +355,17 @@ await request
357
355
  | `fetchAPI` | Replace the defaulted `fetch` function used by `Keq`. |
358
356
 
359
357
  <!-- ###### The options with **DEPRECATED** will be removed in next major version -->
358
+
359
+ ### Timeout
360
+
361
+ Keq has built-in timeout function.
362
+
363
+ ```typescript
364
+ await request
365
+ .get("http://test.com")
366
+ // 5000 milliseconds
367
+ .timeout(5000)
368
+ ```
360
369
 
361
370
  ### Flow Control
362
371
 
@@ -403,7 +412,6 @@ request
403
412
  .followControl("serial", 'animal')
404
413
  .end()
405
414
  ```
406
-
407
415
 
408
416
  ### Middleware
409
417
 
@@ -9,6 +9,7 @@ import { proxyResponseMiddleware } from './middlewares/proxy-response-middleware
9
9
  import { retryMiddleware } from './middlewares/retry-middleware';
10
10
  import { serialFlowControlMiddleware } from './middlewares/serial-flow-control-middleware.js';
11
11
  import { KeqRouter } from './router/keq-router.js';
12
+ import { timeoutMiddleware } from './middlewares/timeout-middleware.js';
12
13
  export function createRequest(options) {
13
14
  let baseOrigin = options?.baseOrigin;
14
15
  if (isBrowser() && !baseOrigin)
@@ -16,6 +17,7 @@ export function createRequest(options) {
16
17
  const appendMiddlewares = options?.initMiddlewares ? [...options.initMiddlewares] : [
17
18
  serialFlowControlMiddleware(),
18
19
  abortFlowControlMiddleware(),
20
+ timeoutMiddleware(),
19
21
  proxyResponseMiddleware(),
20
22
  fetchArgumentsMiddleware(),
21
23
  retryMiddleware(),
@@ -70,4 +70,5 @@ export declare class Keq<T> extends Core<T> {
70
70
  credentials(mod: RequestCredentials): this;
71
71
  mode(mod: RequestMode): this;
72
72
  flowControl(mode: KeqFlowControlMode, signal?: KeqFlowControlSignal): this;
73
+ timeout(milliseconds: number): this;
73
74
  }
@@ -196,4 +196,8 @@ export class Keq extends Core {
196
196
  this.option('flowControl', flowControl);
197
197
  return this;
198
198
  }
199
+ timeout(milliseconds) {
200
+ this.option('timeout', { millisecond: milliseconds });
201
+ return this;
202
+ }
199
203
  }
@@ -1,11 +1,10 @@
1
- import { compile } from 'path-to-regexp';
2
1
  import { URL } from 'whatwg-url';
3
2
  import { Exception } from "../exception/exception";
3
+ import { compilePathnameTemplate } from "../util/compile-pathname-template.js";
4
4
  function compileUrl(obj, routeParams) {
5
5
  const url = new URL(typeof obj === 'string' ? obj : obj.href);
6
6
  try {
7
- const toPath = compile(url.pathname, { encode: encodeURIComponent });
8
- url.pathname = toPath(routeParams);
7
+ url.pathname = compilePathnameTemplate(url.pathname, routeParams);
9
8
  }
10
9
  catch (e) {
11
10
  throw new Exception(`Cannot compile the params in ${url.pathname}, Because ${e?.message}.`);
@@ -0,0 +1,2 @@
1
+ import { KeqMiddleware } from "../types/keq-middleware.js";
2
+ export declare function timeoutMiddleware(): KeqMiddleware;
@@ -0,0 +1,19 @@
1
+ export function timeoutMiddleware() {
2
+ return async (ctx, next) => {
3
+ if (!ctx.options.timeout || ctx.options.timeout.millisecond <= 0) {
4
+ await next();
5
+ return;
6
+ }
7
+ if (ctx.request.signal) {
8
+ console.warn('[keq] request signal had be set manual, abort follow control will not take effect');
9
+ await next();
10
+ return;
11
+ }
12
+ const timeoutSignal = new AbortController();
13
+ ctx.request.signal = timeoutSignal.signal;
14
+ setTimeout(() => {
15
+ timeoutSignal.abort('timeout');
16
+ }, ctx.options.timeout.millisecond);
17
+ await next();
18
+ };
19
+ }
@@ -1,6 +1,7 @@
1
1
  import { KeqFlowControl } from './keq-flow-control.js';
2
2
  import { KeqRetryDelay } from './keq-retry-delay';
3
3
  import { KeqRetryOn } from './keq-retry-on';
4
+ import { KeqTimeout } from './keq-timeout.js';
4
5
  export interface KeqBuildInOptions {
5
6
  /**
6
7
  * replace the default fetch api
@@ -29,6 +30,7 @@ export interface KeqBuildInOptions {
29
30
  pathname: string;
30
31
  };
31
32
  flowControl?: KeqFlowControl;
33
+ timeout?: KeqTimeout;
32
34
  }
33
35
  export interface KeqOptionsWithFullResponse extends KeqBuildInOptions {
34
36
  resolveWithFullResponse: true;
@@ -0,0 +1,3 @@
1
+ export interface KeqTimeout {
2
+ millisecond: number;
3
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export declare function compilePathnameTemplate(template: string, params: Record<string, string | number>): string;
@@ -0,0 +1,15 @@
1
+ export function compilePathnameTemplate(template, params) {
2
+ return template
3
+ .replace(/(^|\/)(?::([^/]+)|{([^/]+)}|%7B([^/]+)%7D)(?=$|\/)/g, (_, prefix, group1, group2, group3) => {
4
+ if (group1 && params[group1]) {
5
+ return `${prefix}${encodeURIComponent(params[group1])}`;
6
+ }
7
+ else if (group2 && params[group2]) {
8
+ return `${prefix}${encodeURIComponent(params[group2])}`;
9
+ }
10
+ else if (group3 && params[group3]) {
11
+ return `${prefix}${encodeURIComponent(params[group3])}`;
12
+ }
13
+ return _;
14
+ });
15
+ }
@@ -4,7 +4,7 @@
4
4
  if (v !== undefined) module.exports = v;
5
5
  }
6
6
  else if (typeof define === "function" && define.amd) {
7
- define(["require", "exports", "whatwg-url", "./is/is-browser", "./keq", "./middlewares/abort-flow-control-middleware.js", "./middlewares/fetch-arguments-middleware", "./middlewares/fetch-middleware", "./middlewares/proxy-response-middleware", "./middlewares/retry-middleware", "./middlewares/serial-flow-control-middleware.js", "./router/keq-router.js"], factory);
7
+ define(["require", "exports", "whatwg-url", "./is/is-browser", "./keq", "./middlewares/abort-flow-control-middleware.js", "./middlewares/fetch-arguments-middleware", "./middlewares/fetch-middleware", "./middlewares/proxy-response-middleware", "./middlewares/retry-middleware", "./middlewares/serial-flow-control-middleware.js", "./router/keq-router.js", "./middlewares/timeout-middleware.js"], factory);
8
8
  }
9
9
  })(function (require, exports) {
10
10
  "use strict";
@@ -21,6 +21,7 @@
21
21
  const retry_middleware_1 = require("./middlewares/retry-middleware");
22
22
  const serial_flow_control_middleware_js_1 = require("./middlewares/serial-flow-control-middleware.js");
23
23
  const keq_router_js_1 = require("./router/keq-router.js");
24
+ const timeout_middleware_js_1 = require("./middlewares/timeout-middleware.js");
24
25
  function createRequest(options) {
25
26
  let baseOrigin = options?.baseOrigin;
26
27
  if ((0, is_browser_1.isBrowser)() && !baseOrigin)
@@ -28,6 +29,7 @@
28
29
  const appendMiddlewares = options?.initMiddlewares ? [...options.initMiddlewares] : [
29
30
  (0, serial_flow_control_middleware_js_1.serialFlowControlMiddleware)(),
30
31
  (0, abort_flow_control_middleware_js_1.abortFlowControlMiddleware)(),
32
+ (0, timeout_middleware_js_1.timeoutMiddleware)(),
31
33
  (0, proxy_response_middleware_1.proxyResponseMiddleware)(),
32
34
  (0, fetch_arguments_middleware_1.fetchArgumentsMiddleware)(),
33
35
  (0, retry_middleware_1.retryMiddleware)(),
@@ -70,4 +70,5 @@ export declare class Keq<T> extends Core<T> {
70
70
  credentials(mod: RequestCredentials): this;
71
71
  mode(mod: RequestMode): this;
72
72
  flowControl(mode: KeqFlowControlMode, signal?: KeqFlowControlSignal): this;
73
+ timeout(milliseconds: number): this;
73
74
  }
@@ -208,6 +208,10 @@
208
208
  this.option('flowControl', flowControl);
209
209
  return this;
210
210
  }
211
+ timeout(milliseconds) {
212
+ this.option('timeout', { millisecond: milliseconds });
213
+ return this;
214
+ }
211
215
  }
212
216
  exports.Keq = Keq;
213
217
  });
@@ -4,20 +4,19 @@
4
4
  if (v !== undefined) module.exports = v;
5
5
  }
6
6
  else if (typeof define === "function" && define.amd) {
7
- define(["require", "exports", "path-to-regexp", "whatwg-url", "../exception/exception"], factory);
7
+ define(["require", "exports", "whatwg-url", "../exception/exception", "../util/compile-pathname-template.js"], factory);
8
8
  }
9
9
  })(function (require, exports) {
10
10
  "use strict";
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.fetchArgumentsMiddleware = void 0;
13
- const path_to_regexp_1 = require("path-to-regexp");
14
13
  const whatwg_url_1 = require("whatwg-url");
15
14
  const exception_1 = require("../exception/exception");
15
+ const compile_pathname_template_js_1 = require("../util/compile-pathname-template.js");
16
16
  function compileUrl(obj, routeParams) {
17
17
  const url = new whatwg_url_1.URL(typeof obj === 'string' ? obj : obj.href);
18
18
  try {
19
- const toPath = (0, path_to_regexp_1.compile)(url.pathname, { encode: encodeURIComponent });
20
- url.pathname = toPath(routeParams);
19
+ url.pathname = (0, compile_pathname_template_js_1.compilePathnameTemplate)(url.pathname, routeParams);
21
20
  }
22
21
  catch (e) {
23
22
  throw new exception_1.Exception(`Cannot compile the params in ${url.pathname}, Because ${e?.message}.`);
@@ -0,0 +1,2 @@
1
+ import { KeqMiddleware } from "../types/keq-middleware.js";
2
+ export declare function timeoutMiddleware(): KeqMiddleware;
@@ -0,0 +1,33 @@
1
+ (function (factory) {
2
+ if (typeof module === "object" && typeof module.exports === "object") {
3
+ var v = factory(require, exports);
4
+ if (v !== undefined) module.exports = v;
5
+ }
6
+ else if (typeof define === "function" && define.amd) {
7
+ define(["require", "exports"], factory);
8
+ }
9
+ })(function (require, exports) {
10
+ "use strict";
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.timeoutMiddleware = void 0;
13
+ function timeoutMiddleware() {
14
+ return async (ctx, next) => {
15
+ if (!ctx.options.timeout || ctx.options.timeout.millisecond <= 0) {
16
+ await next();
17
+ return;
18
+ }
19
+ if (ctx.request.signal) {
20
+ console.warn('[keq] request signal had be set manual, abort follow control will not take effect');
21
+ await next();
22
+ return;
23
+ }
24
+ const timeoutSignal = new AbortController();
25
+ ctx.request.signal = timeoutSignal.signal;
26
+ setTimeout(() => {
27
+ timeoutSignal.abort('timeout');
28
+ }, ctx.options.timeout.millisecond);
29
+ await next();
30
+ };
31
+ }
32
+ exports.timeoutMiddleware = timeoutMiddleware;
33
+ });
@@ -1,6 +1,7 @@
1
1
  import { KeqFlowControl } from './keq-flow-control.js';
2
2
  import { KeqRetryDelay } from './keq-retry-delay';
3
3
  import { KeqRetryOn } from './keq-retry-on';
4
+ import { KeqTimeout } from './keq-timeout.js';
4
5
  export interface KeqBuildInOptions {
5
6
  /**
6
7
  * replace the default fetch api
@@ -29,6 +30,7 @@ export interface KeqBuildInOptions {
29
30
  pathname: string;
30
31
  };
31
32
  flowControl?: KeqFlowControl;
33
+ timeout?: KeqTimeout;
32
34
  }
33
35
  export interface KeqOptionsWithFullResponse extends KeqBuildInOptions {
34
36
  resolveWithFullResponse: true;
@@ -0,0 +1,3 @@
1
+ export interface KeqTimeout {
2
+ millisecond: number;
3
+ }
@@ -0,0 +1,12 @@
1
+ (function (factory) {
2
+ if (typeof module === "object" && typeof module.exports === "object") {
3
+ var v = factory(require, exports);
4
+ if (v !== undefined) module.exports = v;
5
+ }
6
+ else if (typeof define === "function" && define.amd) {
7
+ define(["require", "exports"], factory);
8
+ }
9
+ })(function (require, exports) {
10
+ "use strict";
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ });
@@ -0,0 +1 @@
1
+ export declare function compilePathnameTemplate(template: string, params: Record<string, string | number>): string;
@@ -0,0 +1,29 @@
1
+ (function (factory) {
2
+ if (typeof module === "object" && typeof module.exports === "object") {
3
+ var v = factory(require, exports);
4
+ if (v !== undefined) module.exports = v;
5
+ }
6
+ else if (typeof define === "function" && define.amd) {
7
+ define(["require", "exports"], factory);
8
+ }
9
+ })(function (require, exports) {
10
+ "use strict";
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.compilePathnameTemplate = void 0;
13
+ function compilePathnameTemplate(template, params) {
14
+ return template
15
+ .replace(/(^|\/)(?::([^/]+)|{([^/]+)}|%7B([^/]+)%7D)(?=$|\/)/g, (_, prefix, group1, group2, group3) => {
16
+ if (group1 && params[group1]) {
17
+ return `${prefix}${encodeURIComponent(params[group1])}`;
18
+ }
19
+ else if (group2 && params[group2]) {
20
+ return `${prefix}${encodeURIComponent(params[group2])}`;
21
+ }
22
+ else if (group3 && params[group3]) {
23
+ return `${prefix}${encodeURIComponent(params[group3])}`;
24
+ }
25
+ return _;
26
+ });
27
+ }
28
+ exports.compilePathnameTemplate = compilePathnameTemplate;
29
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keq",
3
- "version": "2.1.1",
3
+ "version": "2.2.0",
4
4
  "description": "Request API write by Typescript for flexibility, readability, and a low learning curve.",
5
5
  "keywords": [
6
6
  "request",
@@ -44,7 +44,6 @@
44
44
  "fastq": "^1.16.0",
45
45
  "minimatch": "^9.0.3",
46
46
  "object.fromentries": "^2.0.7",
47
- "path-to-regexp": "^6.2.1",
48
47
  "ts-custom-error": "^3.3.1",
49
48
  "whatwg-url": "^14.0.0"
50
49
  },