@keq-request/exception 5.0.0-alpha.17 → 5.0.0-alpha.19

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
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.0.0-alpha.19
4
+
5
+ ### Patch Changes
6
+
7
+ - 30b0848: rename validateResponse to validateStatusCode
8
+ - keq@5.0.0-alpha.19
9
+
10
+ ## 5.0.0-alpha.18
11
+
12
+ ### Minor Changes
13
+
14
+ - 241a2ca: **Feat:** add a validateResponse middleware and plugin use to validate http response and throw standard exception
15
+
16
+ ### Patch Changes
17
+
18
+ - Updated dependencies [cbc5d17]
19
+ - keq@5.0.0-alpha.18
20
+
3
21
  ## 5.0.0-alpha.17
4
22
 
5
23
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './throw-exception.js';
2
2
  export * from './catch-exception.js';
3
+ export * from './validate-status-code.js';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAA;AACpC,cAAc,sBAAsB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAA;AACpC,cAAc,sBAAsB,CAAA;AACpC,cAAc,2BAA2B,CAAA"}
package/dist/index.js CHANGED
@@ -21,7 +21,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  catchException: () => catchException,
24
- throwException: () => throwException
24
+ throwException: () => throwException,
25
+ validateStatusCode: () => validateStatusCode
25
26
  });
26
27
  module.exports = __toCommonJS(index_exports);
27
28
 
@@ -43,4 +44,53 @@ function catchException(handler) {
43
44
  }
44
45
  };
45
46
  }
47
+
48
+ // src/validate-status-code.ts
49
+ var import_keq = require("keq");
50
+ function validateStatusCode() {
51
+ return async (context, next) => {
52
+ await next();
53
+ const response = context.response;
54
+ if (!response) return;
55
+ const { status, statusText } = response;
56
+ if (status >= 200 && status < 300) return;
57
+ if (status >= 300 && status < 400) return;
58
+ if (status >= 400 && status < 500) {
59
+ switch (status) {
60
+ case 400:
61
+ throw new import_keq.BadRequestException(statusText);
62
+ case 401:
63
+ throw new import_keq.UnauthorizedException(statusText);
64
+ case 403:
65
+ throw new import_keq.ForbiddenException(statusText);
66
+ case 404:
67
+ throw new import_keq.NotFoundedException(statusText);
68
+ case 406:
69
+ throw new import_keq.NotAcceptableException(statusText);
70
+ case 409:
71
+ throw new import_keq.ConflictException(statusText);
72
+ case 412:
73
+ throw new import_keq.PreconditionFailedException(statusText);
74
+ case 418:
75
+ throw new import_keq.ImATeapotException(statusText);
76
+ default:
77
+ throw new import_keq.RequestException(status, statusText, false);
78
+ }
79
+ }
80
+ if (status >= 500) {
81
+ switch (status) {
82
+ case 500:
83
+ throw new import_keq.InternalServerErrorException(statusText);
84
+ case 502:
85
+ throw new import_keq.BadGatewayException(statusText);
86
+ case 503:
87
+ throw new import_keq.ServiceUnavailableException(statusText);
88
+ case 504:
89
+ throw new import_keq.GatewayTimeoutException(statusText);
90
+ default:
91
+ throw new import_keq.RequestException(status, statusText, true);
92
+ }
93
+ }
94
+ };
95
+ }
46
96
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/throw-exception.ts","../src/catch-exception.ts"],"sourcesContent":["export * from './throw-exception.js'\nexport * from './catch-exception.js'\n","import { KeqContext, KeqMiddleware } from 'keq'\nimport { Promisable } from 'type-fest'\n\n\nexport type Check = (ctx: KeqContext) => Promisable<void>\n\nexport function throwException(check: Check): KeqMiddleware {\n return async function throwException(ctx, next) {\n await next()\n\n await check(ctx)\n }\n}\n","import { KeqMiddleware } from 'keq'\nimport { Promisable } from 'type-fest'\n\n\nexport function catchException(handler: (e: unknown) => Promisable<void>): KeqMiddleware {\n return async function catchException(ctx, next) {\n try {\n await next()\n } catch (err) {\n await handler(err)\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACMO,SAAS,eAAe,OAA6B;AAC1D,SAAO,eAAeA,gBAAe,KAAK,MAAM;AAC9C,UAAM,KAAK;AAEX,UAAM,MAAM,GAAG;AAAA,EACjB;AACF;;;ACRO,SAAS,eAAe,SAA0D;AACvF,SAAO,eAAeC,gBAAe,KAAK,MAAM;AAC9C,QAAI;AACF,YAAM,KAAK;AAAA,IACb,SAAS,KAAK;AACZ,YAAM,QAAQ,GAAG;AAAA,IACnB;AAAA,EACF;AACF;","names":["throwException","catchException"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/throw-exception.ts","../src/catch-exception.ts","../src/validate-status-code.ts"],"sourcesContent":["export * from './throw-exception.js'\nexport * from './catch-exception.js'\nexport * from './validate-status-code.js'\n","import { KeqContext, KeqMiddleware } from 'keq'\nimport { Promisable } from 'type-fest'\n\n\nexport type Check = (ctx: KeqContext) => Promisable<void>\n\nexport function throwException(check: Check): KeqMiddleware {\n return async function throwException(ctx, next) {\n await next()\n\n await check(ctx)\n }\n}\n","import { KeqMiddleware } from 'keq'\nimport { Promisable } from 'type-fest'\n\n\nexport function catchException(handler: (e: unknown) => Promisable<void>): KeqMiddleware {\n return async function catchException(ctx, next) {\n try {\n await next()\n } catch (err) {\n await handler(err)\n }\n }\n}\n","import {\n BadGatewayException,\n BadRequestException,\n ConflictException,\n ForbiddenException,\n GatewayTimeoutException,\n InternalServerErrorException,\n KeqMiddleware,\n NotAcceptableException,\n NotFoundedException,\n PreconditionFailedException,\n RequestException,\n ServiceUnavailableException,\n UnauthorizedException,\n ImATeapotException,\n} from 'keq'\n\nexport function validateStatusCode(): KeqMiddleware {\n return async (context, next) => {\n await next()\n\n const response = context.response\n if (!response) return\n\n const { status, statusText } = response\n\n // 2xx success status codes - no error\n if (status >= 200 && status < 300) return\n\n // 3xx redirection status codes - no error (handled by fetch)\n if (status >= 300 && status < 400) return\n\n // 4xx client errors\n if (status >= 400 && status < 500) {\n switch (status) {\n case 400:\n throw new BadRequestException(statusText)\n case 401:\n throw new UnauthorizedException(statusText)\n case 403:\n throw new ForbiddenException(statusText)\n case 404:\n throw new NotFoundedException(statusText)\n case 406:\n throw new NotAcceptableException(statusText)\n case 409:\n throw new ConflictException(statusText)\n case 412:\n throw new PreconditionFailedException(statusText)\n case 418:\n throw new ImATeapotException(statusText)\n default:\n // Other 4xx errors, don't retry by default\n throw new RequestException(status, statusText, false)\n }\n }\n\n // 5xx server errors\n if (status >= 500) {\n switch (status) {\n case 500:\n throw new InternalServerErrorException(statusText)\n case 502:\n throw new BadGatewayException(statusText)\n case 503:\n throw new ServiceUnavailableException(statusText)\n case 504:\n throw new GatewayTimeoutException(statusText)\n default:\n // Other 5xx errors, retry by default\n throw new RequestException(status, statusText, true)\n }\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACMO,SAAS,eAAe,OAA6B;AAC1D,SAAO,eAAeA,gBAAe,KAAK,MAAM;AAC9C,UAAM,KAAK;AAEX,UAAM,MAAM,GAAG;AAAA,EACjB;AACF;;;ACRO,SAAS,eAAe,SAA0D;AACvF,SAAO,eAAeC,gBAAe,KAAK,MAAM;AAC9C,QAAI;AACF,YAAM,KAAK;AAAA,IACb,SAAS,KAAK;AACZ,YAAM,QAAQ,GAAG;AAAA,IACnB;AAAA,EACF;AACF;;;ACZA,iBAeO;AAEA,SAAS,qBAAoC;AAClD,SAAO,OAAO,SAAS,SAAS;AAC9B,UAAM,KAAK;AAEX,UAAM,WAAW,QAAQ;AACzB,QAAI,CAAC,SAAU;AAEf,UAAM,EAAE,QAAQ,WAAW,IAAI;AAG/B,QAAI,UAAU,OAAO,SAAS,IAAK;AAGnC,QAAI,UAAU,OAAO,SAAS,IAAK;AAGnC,QAAI,UAAU,OAAO,SAAS,KAAK;AACjC,cAAQ,QAAQ;AAAA,QAChB,KAAK;AACH,gBAAM,IAAI,+BAAoB,UAAU;AAAA,QAC1C,KAAK;AACH,gBAAM,IAAI,iCAAsB,UAAU;AAAA,QAC5C,KAAK;AACH,gBAAM,IAAI,8BAAmB,UAAU;AAAA,QACzC,KAAK;AACH,gBAAM,IAAI,+BAAoB,UAAU;AAAA,QAC1C,KAAK;AACH,gBAAM,IAAI,kCAAuB,UAAU;AAAA,QAC7C,KAAK;AACH,gBAAM,IAAI,6BAAkB,UAAU;AAAA,QACxC,KAAK;AACH,gBAAM,IAAI,uCAA4B,UAAU;AAAA,QAClD,KAAK;AACH,gBAAM,IAAI,8BAAmB,UAAU;AAAA,QACzC;AAEE,gBAAM,IAAI,4BAAiB,QAAQ,YAAY,KAAK;AAAA,MACtD;AAAA,IACF;AAGA,QAAI,UAAU,KAAK;AACjB,cAAQ,QAAQ;AAAA,QAChB,KAAK;AACH,gBAAM,IAAI,wCAA6B,UAAU;AAAA,QACnD,KAAK;AACH,gBAAM,IAAI,+BAAoB,UAAU;AAAA,QAC1C,KAAK;AACH,gBAAM,IAAI,uCAA4B,UAAU;AAAA,QAClD,KAAK;AACH,gBAAM,IAAI,mCAAwB,UAAU;AAAA,QAC9C;AAEE,gBAAM,IAAI,4BAAiB,QAAQ,YAAY,IAAI;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACF;","names":["throwException","catchException"]}
package/dist/index.mjs CHANGED
@@ -16,8 +16,72 @@ function catchException(handler) {
16
16
  }
17
17
  };
18
18
  }
19
+
20
+ // src/validate-status-code.ts
21
+ import {
22
+ BadGatewayException,
23
+ BadRequestException,
24
+ ConflictException,
25
+ ForbiddenException,
26
+ GatewayTimeoutException,
27
+ InternalServerErrorException,
28
+ NotAcceptableException,
29
+ NotFoundedException,
30
+ PreconditionFailedException,
31
+ RequestException,
32
+ ServiceUnavailableException,
33
+ UnauthorizedException,
34
+ ImATeapotException
35
+ } from "keq";
36
+ function validateStatusCode() {
37
+ return async (context, next) => {
38
+ await next();
39
+ const response = context.response;
40
+ if (!response) return;
41
+ const { status, statusText } = response;
42
+ if (status >= 200 && status < 300) return;
43
+ if (status >= 300 && status < 400) return;
44
+ if (status >= 400 && status < 500) {
45
+ switch (status) {
46
+ case 400:
47
+ throw new BadRequestException(statusText);
48
+ case 401:
49
+ throw new UnauthorizedException(statusText);
50
+ case 403:
51
+ throw new ForbiddenException(statusText);
52
+ case 404:
53
+ throw new NotFoundedException(statusText);
54
+ case 406:
55
+ throw new NotAcceptableException(statusText);
56
+ case 409:
57
+ throw new ConflictException(statusText);
58
+ case 412:
59
+ throw new PreconditionFailedException(statusText);
60
+ case 418:
61
+ throw new ImATeapotException(statusText);
62
+ default:
63
+ throw new RequestException(status, statusText, false);
64
+ }
65
+ }
66
+ if (status >= 500) {
67
+ switch (status) {
68
+ case 500:
69
+ throw new InternalServerErrorException(statusText);
70
+ case 502:
71
+ throw new BadGatewayException(statusText);
72
+ case 503:
73
+ throw new ServiceUnavailableException(statusText);
74
+ case 504:
75
+ throw new GatewayTimeoutException(statusText);
76
+ default:
77
+ throw new RequestException(status, statusText, true);
78
+ }
79
+ }
80
+ };
81
+ }
19
82
  export {
20
83
  catchException,
21
- throwException
84
+ throwException,
85
+ validateStatusCode
22
86
  };
23
87
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/throw-exception.ts","../src/catch-exception.ts"],"sourcesContent":["import { KeqContext, KeqMiddleware } from 'keq'\nimport { Promisable } from 'type-fest'\n\n\nexport type Check = (ctx: KeqContext) => Promisable<void>\n\nexport function throwException(check: Check): KeqMiddleware {\n return async function throwException(ctx, next) {\n await next()\n\n await check(ctx)\n }\n}\n","import { KeqMiddleware } from 'keq'\nimport { Promisable } from 'type-fest'\n\n\nexport function catchException(handler: (e: unknown) => Promisable<void>): KeqMiddleware {\n return async function catchException(ctx, next) {\n try {\n await next()\n } catch (err) {\n await handler(err)\n }\n }\n}\n"],"mappings":";AAMO,SAAS,eAAe,OAA6B;AAC1D,SAAO,eAAeA,gBAAe,KAAK,MAAM;AAC9C,UAAM,KAAK;AAEX,UAAM,MAAM,GAAG;AAAA,EACjB;AACF;;;ACRO,SAAS,eAAe,SAA0D;AACvF,SAAO,eAAeC,gBAAe,KAAK,MAAM;AAC9C,QAAI;AACF,YAAM,KAAK;AAAA,IACb,SAAS,KAAK;AACZ,YAAM,QAAQ,GAAG;AAAA,IACnB;AAAA,EACF;AACF;","names":["throwException","catchException"]}
1
+ {"version":3,"sources":["../src/throw-exception.ts","../src/catch-exception.ts","../src/validate-status-code.ts"],"sourcesContent":["import { KeqContext, KeqMiddleware } from 'keq'\nimport { Promisable } from 'type-fest'\n\n\nexport type Check = (ctx: KeqContext) => Promisable<void>\n\nexport function throwException(check: Check): KeqMiddleware {\n return async function throwException(ctx, next) {\n await next()\n\n await check(ctx)\n }\n}\n","import { KeqMiddleware } from 'keq'\nimport { Promisable } from 'type-fest'\n\n\nexport function catchException(handler: (e: unknown) => Promisable<void>): KeqMiddleware {\n return async function catchException(ctx, next) {\n try {\n await next()\n } catch (err) {\n await handler(err)\n }\n }\n}\n","import {\n BadGatewayException,\n BadRequestException,\n ConflictException,\n ForbiddenException,\n GatewayTimeoutException,\n InternalServerErrorException,\n KeqMiddleware,\n NotAcceptableException,\n NotFoundedException,\n PreconditionFailedException,\n RequestException,\n ServiceUnavailableException,\n UnauthorizedException,\n ImATeapotException,\n} from 'keq'\n\nexport function validateStatusCode(): KeqMiddleware {\n return async (context, next) => {\n await next()\n\n const response = context.response\n if (!response) return\n\n const { status, statusText } = response\n\n // 2xx success status codes - no error\n if (status >= 200 && status < 300) return\n\n // 3xx redirection status codes - no error (handled by fetch)\n if (status >= 300 && status < 400) return\n\n // 4xx client errors\n if (status >= 400 && status < 500) {\n switch (status) {\n case 400:\n throw new BadRequestException(statusText)\n case 401:\n throw new UnauthorizedException(statusText)\n case 403:\n throw new ForbiddenException(statusText)\n case 404:\n throw new NotFoundedException(statusText)\n case 406:\n throw new NotAcceptableException(statusText)\n case 409:\n throw new ConflictException(statusText)\n case 412:\n throw new PreconditionFailedException(statusText)\n case 418:\n throw new ImATeapotException(statusText)\n default:\n // Other 4xx errors, don't retry by default\n throw new RequestException(status, statusText, false)\n }\n }\n\n // 5xx server errors\n if (status >= 500) {\n switch (status) {\n case 500:\n throw new InternalServerErrorException(statusText)\n case 502:\n throw new BadGatewayException(statusText)\n case 503:\n throw new ServiceUnavailableException(statusText)\n case 504:\n throw new GatewayTimeoutException(statusText)\n default:\n // Other 5xx errors, retry by default\n throw new RequestException(status, statusText, true)\n }\n }\n }\n}\n"],"mappings":";AAMO,SAAS,eAAe,OAA6B;AAC1D,SAAO,eAAeA,gBAAe,KAAK,MAAM;AAC9C,UAAM,KAAK;AAEX,UAAM,MAAM,GAAG;AAAA,EACjB;AACF;;;ACRO,SAAS,eAAe,SAA0D;AACvF,SAAO,eAAeC,gBAAe,KAAK,MAAM;AAC9C,QAAI;AACF,YAAM,KAAK;AAAA,IACb,SAAS,KAAK;AACZ,YAAM,QAAQ,GAAG;AAAA,IACnB;AAAA,EACF;AACF;;;ACZA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEA,SAAS,qBAAoC;AAClD,SAAO,OAAO,SAAS,SAAS;AAC9B,UAAM,KAAK;AAEX,UAAM,WAAW,QAAQ;AACzB,QAAI,CAAC,SAAU;AAEf,UAAM,EAAE,QAAQ,WAAW,IAAI;AAG/B,QAAI,UAAU,OAAO,SAAS,IAAK;AAGnC,QAAI,UAAU,OAAO,SAAS,IAAK;AAGnC,QAAI,UAAU,OAAO,SAAS,KAAK;AACjC,cAAQ,QAAQ;AAAA,QAChB,KAAK;AACH,gBAAM,IAAI,oBAAoB,UAAU;AAAA,QAC1C,KAAK;AACH,gBAAM,IAAI,sBAAsB,UAAU;AAAA,QAC5C,KAAK;AACH,gBAAM,IAAI,mBAAmB,UAAU;AAAA,QACzC,KAAK;AACH,gBAAM,IAAI,oBAAoB,UAAU;AAAA,QAC1C,KAAK;AACH,gBAAM,IAAI,uBAAuB,UAAU;AAAA,QAC7C,KAAK;AACH,gBAAM,IAAI,kBAAkB,UAAU;AAAA,QACxC,KAAK;AACH,gBAAM,IAAI,4BAA4B,UAAU;AAAA,QAClD,KAAK;AACH,gBAAM,IAAI,mBAAmB,UAAU;AAAA,QACzC;AAEE,gBAAM,IAAI,iBAAiB,QAAQ,YAAY,KAAK;AAAA,MACtD;AAAA,IACF;AAGA,QAAI,UAAU,KAAK;AACjB,cAAQ,QAAQ;AAAA,QAChB,KAAK;AACH,gBAAM,IAAI,6BAA6B,UAAU;AAAA,QACnD,KAAK;AACH,gBAAM,IAAI,oBAAoB,UAAU;AAAA,QAC1C,KAAK;AACH,gBAAM,IAAI,4BAA4B,UAAU;AAAA,QAClD,KAAK;AACH,gBAAM,IAAI,wBAAwB,UAAU;AAAA,QAC9C;AAEE,gBAAM,IAAI,iBAAiB,QAAQ,YAAY,IAAI;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACF;","names":["throwException","catchException"]}
@@ -0,0 +1,12 @@
1
+ import { Plugin, Compiler } from '@keq-request/cli';
2
+
3
+ interface Options {
4
+ modules?: string[];
5
+ }
6
+ declare class ValidateStatusCodePlugin implements Plugin {
7
+ private options;
8
+ constructor(options?: Options);
9
+ apply(compiler: Compiler): void;
10
+ }
11
+
12
+ export { ValidateStatusCodePlugin };
@@ -0,0 +1,12 @@
1
+ import { Plugin, Compiler } from '@keq-request/cli';
2
+
3
+ interface Options {
4
+ modules?: string[];
5
+ }
6
+ declare class ValidateStatusCodePlugin implements Plugin {
7
+ private options;
8
+ constructor(options?: Options);
9
+ apply(compiler: Compiler): void;
10
+ }
11
+
12
+ export { ValidateStatusCodePlugin };
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // plugins/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ ValidateStatusCodePlugin: () => ValidateStatusCodePlugin
24
+ });
25
+ module.exports = __toCommonJS(index_exports);
26
+
27
+ // plugins/validate-response.ts
28
+ var import_cli = require("@keq-request/cli");
29
+ var ValidateStatusCodePlugin = class _ValidateStatusCodePlugin {
30
+ constructor(options = {}) {
31
+ this.options = options;
32
+ }
33
+ apply(compiler) {
34
+ if (this.options.modules && this.options.modules.length === 0) return;
35
+ compiler.hooks.afterShaking.tap(_ValidateStatusCodePlugin.name, () => {
36
+ if (!compiler.context.shaken) return;
37
+ const documents = compiler.context.shaken.documents;
38
+ compiler.context.shaken.documents = documents.map((document) => {
39
+ if (this.options.modules && !this.options.modules.includes(document.module.name)) {
40
+ return document;
41
+ }
42
+ const spec = document.specification;
43
+ if (!spec.paths || typeof spec.paths !== "object" || spec.paths === null) return document;
44
+ const paths = Object.fromEntries(
45
+ Object.entries(spec.paths).map(([path, pathItem]) => {
46
+ if (!pathItem || typeof pathItem !== "object" || pathItem === null) return [path, pathItem];
47
+ return [
48
+ path,
49
+ Object.fromEntries(
50
+ Object.entries(pathItem).map(([method, operation]) => {
51
+ if (!operation || typeof operation !== "object" || operation === null) return [method, operation];
52
+ const responses = operation.responses;
53
+ if (!responses) return [method, operation];
54
+ return [
55
+ method,
56
+ {
57
+ ...operation,
58
+ responses: Object.fromEntries(
59
+ Object.entries(responses).filter(([statusCode]) => parseInt(statusCode, 10) < 400)
60
+ )
61
+ }
62
+ ];
63
+ })
64
+ )
65
+ ];
66
+ })
67
+ );
68
+ return new import_cli.ApiDocumentV3_1({ ...spec, paths }, document.module);
69
+ });
70
+ });
71
+ compiler.hooks.afterCompileKeqRequest.tap(_ValidateStatusCodePlugin.name, (artifact) => {
72
+ artifact.addDependence("@keq-request/exception", ["validateResponse"]);
73
+ if (!this.options.modules) {
74
+ artifact.anchor.prepend("file:end", "request.use(validateResponse())\n");
75
+ } else {
76
+ artifact.anchor.prepend(
77
+ "file:end",
78
+ [
79
+ "request",
80
+ " .useRouter()",
81
+ ...this.options.modules.map((moduleName) => ` .module(${JSON.stringify(moduleName)}, validateResponse())`),
82
+ ""
83
+ ].join("\n")
84
+ );
85
+ }
86
+ return artifact;
87
+ });
88
+ }
89
+ };
90
+ // Annotate the CommonJS export names for ESM import in node:
91
+ 0 && (module.exports = {
92
+ ValidateStatusCodePlugin
93
+ });
@@ -0,0 +1,66 @@
1
+ // plugins/validate-response.ts
2
+ import { ApiDocumentV3_1 } from "@keq-request/cli";
3
+ var ValidateStatusCodePlugin = class _ValidateStatusCodePlugin {
4
+ constructor(options = {}) {
5
+ this.options = options;
6
+ }
7
+ apply(compiler) {
8
+ if (this.options.modules && this.options.modules.length === 0) return;
9
+ compiler.hooks.afterShaking.tap(_ValidateStatusCodePlugin.name, () => {
10
+ if (!compiler.context.shaken) return;
11
+ const documents = compiler.context.shaken.documents;
12
+ compiler.context.shaken.documents = documents.map((document) => {
13
+ if (this.options.modules && !this.options.modules.includes(document.module.name)) {
14
+ return document;
15
+ }
16
+ const spec = document.specification;
17
+ if (!spec.paths || typeof spec.paths !== "object" || spec.paths === null) return document;
18
+ const paths = Object.fromEntries(
19
+ Object.entries(spec.paths).map(([path, pathItem]) => {
20
+ if (!pathItem || typeof pathItem !== "object" || pathItem === null) return [path, pathItem];
21
+ return [
22
+ path,
23
+ Object.fromEntries(
24
+ Object.entries(pathItem).map(([method, operation]) => {
25
+ if (!operation || typeof operation !== "object" || operation === null) return [method, operation];
26
+ const responses = operation.responses;
27
+ if (!responses) return [method, operation];
28
+ return [
29
+ method,
30
+ {
31
+ ...operation,
32
+ responses: Object.fromEntries(
33
+ Object.entries(responses).filter(([statusCode]) => parseInt(statusCode, 10) < 400)
34
+ )
35
+ }
36
+ ];
37
+ })
38
+ )
39
+ ];
40
+ })
41
+ );
42
+ return new ApiDocumentV3_1({ ...spec, paths }, document.module);
43
+ });
44
+ });
45
+ compiler.hooks.afterCompileKeqRequest.tap(_ValidateStatusCodePlugin.name, (artifact) => {
46
+ artifact.addDependence("@keq-request/exception", ["validateResponse"]);
47
+ if (!this.options.modules) {
48
+ artifact.anchor.prepend("file:end", "request.use(validateResponse())\n");
49
+ } else {
50
+ artifact.anchor.prepend(
51
+ "file:end",
52
+ [
53
+ "request",
54
+ " .useRouter()",
55
+ ...this.options.modules.map((moduleName) => ` .module(${JSON.stringify(moduleName)}, validateResponse())`),
56
+ ""
57
+ ].join("\n")
58
+ );
59
+ }
60
+ return artifact;
61
+ });
62
+ }
63
+ };
64
+ export {
65
+ ValidateStatusCodePlugin
66
+ };
@@ -0,0 +1,3 @@
1
+ import { KeqMiddleware } from 'keq';
2
+ export declare function validateStatusCode(): KeqMiddleware;
3
+ //# sourceMappingURL=validate-status-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-status-code.d.ts","sourceRoot":"","sources":["../src/validate-status-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,aAAa,EAQd,MAAM,KAAK,CAAA;AAEZ,wBAAgB,kBAAkB,IAAI,aAAa,CAyDlD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@keq-request/exception",
3
- "version": "5.0.0-alpha.17",
3
+ "version": "5.0.0-alpha.19",
4
4
  "description": "Request exception for keq",
5
5
  "keywords": [
6
6
  "keq",
@@ -26,17 +26,27 @@
26
26
  "types": "./dist/index.d.ts",
27
27
  "require": "./dist/index.js",
28
28
  "import": "./dist/index.mjs"
29
+ },
30
+ "./plugins": {
31
+ "types": "./dist/plugins/index.d.ts",
32
+ "require": "./dist/plugins/index.js",
33
+ "import": "./dist/plugins/index.mjs"
29
34
  }
30
35
  },
31
36
  "dependencies": {
32
- "type-fest": "^5.2.0"
37
+ "type-fest": "^5.3.0"
33
38
  },
34
39
  "devDependencies": {
35
- "@types/node": "^20.19.24",
36
- "keq": "5.0.0-alpha.17"
40
+ "@scalar/openapi-types": "^0.5.2",
41
+ "@types/node": "^20.19.25",
42
+ "@keq-request/cli": "5.0.0-alpha.19",
43
+ "keq": "5.0.0-alpha.19"
37
44
  },
38
45
  "peerDependencies": {
39
- "keq": "^5.0.0-alpha.17"
46
+ "keq": "^5.0.0-alpha.19"
47
+ },
48
+ "optionalDependencies": {
49
+ "@keq-request/cli": "5.0.0-alpha.19"
40
50
  },
41
51
  "scripts": {
42
52
  "build": "tsup",
@@ -0,0 +1 @@
1
+ export * from './validate-response.js'
@@ -0,0 +1,87 @@
1
+ import { ApiDocumentV3_1, Artifact, Compiler, Plugin } from '@keq-request/cli'
2
+ import type { OpenAPIV3_1 } from '@scalar/openapi-types'
3
+
4
+
5
+ interface Options {
6
+ modules?: string[]
7
+ }
8
+
9
+ export class ValidateStatusCodePlugin implements Plugin {
10
+ constructor(private options: Options = {}) {}
11
+
12
+ apply(compiler: Compiler): void {
13
+ if (this.options.modules && this.options.modules.length === 0) return
14
+
15
+ // remove 4xx and 5xx responses from OpenAPI documents
16
+ compiler.hooks.afterShaking.tap(ValidateStatusCodePlugin.name, () => {
17
+ if (!compiler.context.shaken) return
18
+
19
+ const documents = compiler.context.shaken.documents
20
+
21
+ compiler.context.shaken.documents = documents.map((document: ApiDocumentV3_1): ApiDocumentV3_1 => {
22
+ if (this.options.modules && !this.options.modules.includes(document.module.name)) {
23
+ return document
24
+ }
25
+
26
+ const spec: OpenAPIV3_1.Document = document.specification
27
+
28
+ if (!spec.paths || typeof spec.paths !== 'object' || spec.paths === null) return document
29
+
30
+ const paths = Object.fromEntries(
31
+ Object.entries(spec.paths)
32
+ .map(([path, pathItem]) => {
33
+ if (!pathItem || typeof pathItem !== 'object' || pathItem === null) return [path, pathItem]
34
+
35
+ return [
36
+ path,
37
+ Object.fromEntries(
38
+ Object.entries(pathItem)
39
+ .map(([method, operation]) => {
40
+ if (!operation || typeof operation !== 'object' || operation === null) return [method, operation]
41
+
42
+ const responses = operation.responses
43
+ if (!responses) return [method, operation]
44
+
45
+ return [
46
+ method,
47
+ {
48
+ ...operation,
49
+
50
+ responses: Object.fromEntries(
51
+ Object.entries(responses)
52
+ .filter(([statusCode]) => parseInt(statusCode, 10) < 400),
53
+ ),
54
+ },
55
+ ]
56
+ }),
57
+ ),
58
+ ]
59
+ }),
60
+ )
61
+
62
+ return new ApiDocumentV3_1({ ...spec, paths }, document.module)
63
+ })
64
+ })
65
+
66
+ // inject validateResponse middleware into generated code
67
+ compiler.hooks.afterCompileKeqRequest.tap(ValidateStatusCodePlugin.name, (artifact: Artifact) => {
68
+ artifact.addDependence('@keq-request/exception', ['validateResponse'])
69
+
70
+ if (!this.options.modules) {
71
+ artifact.anchor.prepend('file:end', 'request.use(validateResponse())\n')
72
+ } else {
73
+ artifact.anchor.prepend(
74
+ 'file:end',
75
+ [
76
+ 'request',
77
+ ' .useRouter()',
78
+ ...this.options.modules.map((moduleName) => ` .module(${JSON.stringify(moduleName)}, validateResponse())`),
79
+ '',
80
+ ].join('\n'),
81
+ )
82
+ }
83
+
84
+ return artifact
85
+ })
86
+ }
87
+ }