@emoyly/problem 7.0.6 → 8.0.1

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.
Files changed (102) hide show
  1. package/README.md +1 -1
  2. package/cjs/defaults/4xx.d.ts +144 -144
  3. package/cjs/defaults/5xx.d.ts +54 -54
  4. package/cjs/defaults/aws.d.ts +8 -8
  5. package/cjs/defaults/cloudflare.d.ts +44 -44
  6. package/cjs/defaults/iis.d.ts +12 -12
  7. package/cjs/defaults/nginx.d.ts +24 -24
  8. package/cjs/defaults/others.d.ts +28 -28
  9. package/cjs/middleware/axios.js +1 -1
  10. package/cjs/middleware/base.d.ts +1 -1
  11. package/cjs/middleware/base.js +4 -4
  12. package/cjs/middleware/express.js +10 -28
  13. package/cjs/parsers/axios.js +9 -8
  14. package/cjs/parsers/jsonwebtoken.js +3 -0
  15. package/cjs/parsers/mikroorm.js +1 -0
  16. package/cjs/parsers/tsoa.js +3 -2
  17. package/cjs/parsers/zod.js +2 -1
  18. package/cjs/problem.d.ts +7 -7
  19. package/cjs/problem.js +41 -32
  20. package/cjs/tsconfig.tsbuildinfo +1 -1
  21. package/cjs/typings/codes.d.ts +2 -2
  22. package/cjs/typings/problem.d.ts +13 -2
  23. package/cjs/util/getProblems.d.ts +4 -4
  24. package/cjs/util/getProblems.js +20 -16
  25. package/cjs/util/index.d.ts +1 -1
  26. package/cjs/util/index.js +1 -1
  27. package/cjs/util/misc.d.ts +2 -2
  28. package/cjs/util/misc.js +3 -4
  29. package/cjs/util/validation.d.ts +5 -0
  30. package/cjs/util/validation.js +38 -0
  31. package/cjs/util/version.d.ts +1 -2
  32. package/cjs/util/version.js +1 -16
  33. package/esm/defaults/4xx.d.ts +144 -144
  34. package/esm/defaults/5xx.d.ts +54 -54
  35. package/esm/defaults/aws.d.ts +8 -8
  36. package/esm/defaults/cloudflare.d.ts +44 -44
  37. package/esm/defaults/iis.d.ts +12 -12
  38. package/esm/defaults/nginx.d.ts +24 -24
  39. package/esm/defaults/others.d.ts +28 -28
  40. package/esm/middleware/axios.js +1 -1
  41. package/esm/middleware/base.d.ts +1 -1
  42. package/esm/middleware/base.js +4 -4
  43. package/esm/middleware/express.js +11 -29
  44. package/esm/parsers/axios.js +9 -8
  45. package/esm/parsers/jsonwebtoken.js +3 -0
  46. package/esm/parsers/mikroorm.js +1 -0
  47. package/esm/parsers/tsoa.js +3 -2
  48. package/esm/parsers/zod.js +2 -1
  49. package/esm/problem.d.ts +7 -7
  50. package/esm/problem.js +41 -32
  51. package/esm/tsconfig.tsbuildinfo +1 -1
  52. package/esm/typings/codes.d.ts +2 -2
  53. package/esm/typings/problem.d.ts +13 -2
  54. package/esm/util/getProblems.d.ts +4 -4
  55. package/esm/util/getProblems.js +20 -16
  56. package/esm/util/index.d.ts +1 -1
  57. package/esm/util/index.js +1 -1
  58. package/esm/util/misc.d.ts +2 -2
  59. package/esm/util/misc.js +2 -3
  60. package/esm/util/validation.d.ts +5 -0
  61. package/esm/util/validation.js +33 -0
  62. package/esm/util/version.d.ts +1 -2
  63. package/esm/util/version.js +1 -15
  64. package/package.json +18 -13
  65. package/tsconfig.json +5 -1
  66. package/.editorconfig +0 -11
  67. package/.vscode/extensions.json +0 -7
  68. package/.vscode/settings.json +0 -2
  69. package/cjs/util/defaults.d.ts +0 -4
  70. package/cjs/util/defaults.js +0 -7
  71. package/esm/util/defaults.d.ts +0 -4
  72. package/esm/util/defaults.js +0 -4
  73. package/scripts/ensureCorrectVersion.js +0 -20
  74. package/src/defaults/4xx.ts +0 -149
  75. package/src/defaults/5xx.ts +0 -59
  76. package/src/defaults/aws.ts +0 -14
  77. package/src/defaults/cloudflare.ts +0 -50
  78. package/src/defaults/iis.ts +0 -19
  79. package/src/defaults/index.ts +0 -7
  80. package/src/defaults/nginx.ts +0 -34
  81. package/src/defaults/others.ts +0 -37
  82. package/src/index.ts +0 -4
  83. package/src/middleware/axios.ts +0 -28
  84. package/src/middleware/base.ts +0 -78
  85. package/src/middleware/express.ts +0 -71
  86. package/src/parsers/axios.ts +0 -60
  87. package/src/parsers/jsonwebtoken.ts +0 -107
  88. package/src/parsers/mikroorm.ts +0 -21
  89. package/src/parsers/tsoa.ts +0 -26
  90. package/src/parsers/zod.ts +0 -23
  91. package/src/problem.ts +0 -56
  92. package/src/typings/codes.ts +0 -6
  93. package/src/typings/index.ts +0 -4
  94. package/src/typings/middleware.ts +0 -14
  95. package/src/typings/parser.ts +0 -3
  96. package/src/typings/problem.ts +0 -27
  97. package/src/util/defaults.ts +0 -4
  98. package/src/util/getProblems.ts +0 -56
  99. package/src/util/index.ts +0 -4
  100. package/src/util/misc.ts +0 -21
  101. package/src/util/problemArray.ts +0 -21
  102. package/src/util/version.ts +0 -16
@@ -1,37 +1,37 @@
1
1
  export declare const otherErrors: {
2
- unknown: {
3
- status: number;
4
- title: string;
5
- type: string;
2
+ readonly unknown: {
3
+ readonly status: 500;
4
+ readonly title: "Unknown error";
5
+ readonly type: "/errors/defaults/others/unknown";
6
6
  };
7
- corsError: {
8
- status: number;
9
- title: string;
10
- type: string;
7
+ readonly corsError: {
8
+ readonly status: 401;
9
+ readonly title: "Request not allowed by CORS policy";
10
+ readonly type: "/errors/defaults/others/corsdenied";
11
11
  };
12
- problemParseError: {
13
- status: number;
14
- title: string;
15
- type: string;
12
+ readonly problemParseError: {
13
+ readonly status: 1000;
14
+ readonly title: "Could not parse problem details";
15
+ readonly type: "/errors/defaults/others/problemparseerror";
16
16
  };
17
- problemJsonError: {
18
- status: number;
19
- title: string;
20
- type: string;
17
+ readonly problemJsonError: {
18
+ readonly status: 1000;
19
+ readonly title: "Could not parse problem JSON";
20
+ readonly type: "/errors/defaults/others/problemjsonerror";
21
21
  };
22
- notAnError: {
23
- status: number;
24
- title: string;
25
- type: string;
22
+ readonly notAnError: {
23
+ readonly status: 1000;
24
+ readonly title: "Not an error";
25
+ readonly type: "/errors/defaults/others/notanerror";
26
26
  };
27
- networkError: {
28
- status: number;
29
- title: string;
30
- type: string;
27
+ readonly networkError: {
28
+ readonly status: 1000;
29
+ readonly title: "Network error";
30
+ readonly type: "/errors/defaults/others/networkerror";
31
31
  };
32
- inputValidationError: {
33
- status: number;
34
- title: string;
35
- type: string;
32
+ readonly inputValidationError: {
33
+ readonly status: 400;
34
+ readonly title: "Input failed validation";
35
+ readonly type: "/errors/defaults/others/validationerror";
36
36
  };
37
37
  };
@@ -11,7 +11,7 @@ class AxiosMiddleware extends base_js_1.MiddlewareBase {
11
11
  }, options);
12
12
  }
13
13
  interceptor = async (error) => {
14
- const problems = await this.parse(error);
14
+ const problems = this.parse(error);
15
15
  this.emit(problems);
16
16
  return Promise.reject(problems);
17
17
  };
@@ -19,7 +19,7 @@ export declare abstract class MiddlewareBase {
19
19
  /**
20
20
  * Parse input using parsers
21
21
  */
22
- parse: (input: unknown) => Promise<Problem[]>;
22
+ parse: (input: unknown) => Problem[];
23
23
  fallback: ProblemOpts;
24
24
  problemListeners: ProblemListener[];
25
25
  protected emit: (list: Problem[]) => void;
@@ -19,7 +19,7 @@ class MiddlewareBase {
19
19
  /**
20
20
  * Parse input using parsers
21
21
  */
22
- parse = async (input) => {
22
+ parse = (input) => {
23
23
  const problems = (0, getProblems_js_1.getProblems)(input, this.options.parsers);
24
24
  if (!problems || !Array.isArray(problems) || problems.length < 1) {
25
25
  if (this.enableFallback)
@@ -27,13 +27,13 @@ class MiddlewareBase {
27
27
  ...this.fallback,
28
28
  'errorObject': input,
29
29
  'stack': (typeof input === 'object' && input !== null && 'stack' in input && typeof input.stack === 'string') ? input.stack : undefined,
30
- 'middleware': this.name
30
+ 'source': `middleware:${this.name}`
31
31
  })];
32
32
  return [];
33
33
  }
34
34
  for (const p of problems) {
35
- if (!p.middleware)
36
- p.middleware = this.name;
35
+ if (!p.source)
36
+ p.source = `middleware:${this.name}`;
37
37
  }
38
38
  return problems;
39
39
  };
@@ -4,38 +4,20 @@ exports.ExpressMiddleware = void 0;
4
4
  const base_js_1 = require("./base.js");
5
5
  const problem_js_1 = require("../problem.js");
6
6
  const index_js_1 = require("../defaults/index.js");
7
- const defaults_js_1 = require("../util/defaults.js");
8
7
  class ExpressMiddleware extends base_js_1.MiddlewareBase {
9
8
  name = 'express';
10
9
  middleware = (error, req, res, next) => {
11
- this.parse(error)
12
- .then(problems => {
13
- for (const problem of problems) {
14
- if (problem.instance === defaults_js_1.defaultInstance) {
15
- problem.instance = req.originalUrl;
16
- }
10
+ const problems = this.parse(error);
11
+ for (const problem of problems) {
12
+ if (!problem.instance) {
13
+ problem.instance = req.originalUrl;
17
14
  }
18
- this.emit(problems);
19
- res
20
- .contentType('application/problem+json')
21
- .status(problems[0]?.status ?? 500)
22
- .json(problems.map(val => val.toObject()));
23
- })
24
- .catch(err => {
25
- res
26
- .contentType('application/problem+json')
27
- .status(500)
28
- .json([
29
- new problem_js_1.Problem({
30
- ...index_js_1.otherErrors.unknown,
31
- 'instance': req.originalUrl,
32
- 'status': 500,
33
- 'stack': err?.stack,
34
- 'errorObject': err,
35
- }).toObject()
36
- ]);
37
- throw err;
38
- });
15
+ }
16
+ this.emit(problems);
17
+ res
18
+ .contentType('application/problem+json')
19
+ .status(problems[0]?.status ?? 500)
20
+ .json(problems.map(val => val.toObject()));
39
21
  };
40
22
  /**
41
23
  * This function applies the middleware to your Express application. Put this at the very end of your middleware/routes.
@@ -4,13 +4,11 @@ const others_js_1 = require("../defaults/others.js");
4
4
  const problem_js_1 = require("../problem.js");
5
5
  const getProblems_js_1 = require("../util/getProblems.js");
6
6
  const misc_js_1 = require("../util/misc.js");
7
- function isAxiosError(payload) {
8
- return typeof payload === 'object' && payload !== null && 'isAxiosError' in payload && payload.isAxiosError === true;
9
- }
7
+ const axios_1 = require("axios");
10
8
  const parse = (input) => {
11
9
  if (typeof input !== 'object' || input == null)
12
10
  return [];
13
- if (!isAxiosError(input))
11
+ if (!(0, axios_1.isAxiosError)(input))
14
12
  return [];
15
13
  const request = input.request;
16
14
  if (input?.response?.data) {
@@ -19,13 +17,14 @@ const parse = (input) => {
19
17
  return problems;
20
18
  }
21
19
  if (input?.response) {
22
- const opts = (0, misc_js_1.getHttpError)(input.response.status);
20
+ const opts = (0, misc_js_1.getCodeDefaults)(input.response.status);
23
21
  if (opts)
24
22
  return [new problem_js_1.Problem({
25
23
  ...opts,
26
24
  'instance': input?.config?.url,
27
25
  'stack': input?.stack,
28
- 'errorObject': input
26
+ 'errorObject': input,
27
+ 'source': 'parser:axios'
29
28
  })];
30
29
  }
31
30
  // TODO: Fix this, this seems bad
@@ -37,7 +36,8 @@ const parse = (input) => {
37
36
  ...others_js_1.otherErrors.networkError,
38
37
  'instance': input?.config?.url,
39
38
  'stack': input?.stack,
40
- 'errorObject': input
39
+ 'errorObject': input,
40
+ 'source': 'parser:axios'
41
41
  })];
42
42
  }
43
43
  // Probably a ClientRequest
@@ -46,7 +46,8 @@ const parse = (input) => {
46
46
  ...others_js_1.otherErrors.networkError,
47
47
  'instance': input?.config?.url,
48
48
  'stack': input?.stack,
49
- 'errorObject': input
49
+ 'errorObject': input,
50
+ 'source': 'parser:axios'
50
51
  })];
51
52
  }
52
53
  }
@@ -75,6 +75,7 @@ const parse = (input) => {
75
75
  return [new problem_js_1.Problem({
76
76
  ...found.result,
77
77
  'errorObject': input,
78
+ 'source': 'parser:jsonwebtoken'
78
79
  })];
79
80
  }
80
81
  }
@@ -85,6 +86,7 @@ const parse = (input) => {
85
86
  'detail': `The JSON Web Token expired at ${input.expiredAt}`,
86
87
  'status': 400,
87
88
  'errorObject': input,
89
+ 'source': 'parser:jsonwebtoken'
88
90
  })];
89
91
  }
90
92
  else if (input instanceof jsonwebtoken_1.NotBeforeError && input.name === 'NotBeforeError') {
@@ -94,6 +96,7 @@ const parse = (input) => {
94
96
  'detail': `The JSON Web Token is not valid before ${input.date}`,
95
97
  'status': 400,
96
98
  'errorObject': input,
99
+ 'source': 'parser:jsonwebtoken'
97
100
  })];
98
101
  }
99
102
  };
@@ -13,6 +13,7 @@ const parse = (input) => {
13
13
  ..._4xx_js_1.statusCodes['404'],
14
14
  'stack': input.stack,
15
15
  'errorObject': input,
16
+ 'source': 'parser:mikroorm'
16
17
  })
17
18
  ];
18
19
  };
@@ -7,7 +7,7 @@ const parse = (input) => {
7
7
  if (!(input instanceof tsoa_1.ValidateError)) {
8
8
  return;
9
9
  }
10
- // TODO: Give actual useful responses instead of this shit
10
+ // TODO: Give actual useful responses instead of this 💩
11
11
  return [
12
12
  new problem_js_1.Problem({
13
13
  ...others_js_1.otherErrors.inputValidationError,
@@ -17,7 +17,8 @@ const parse = (input) => {
17
17
  'fields': input.fields,
18
18
  },
19
19
  'stack': input.stack,
20
- 'errorObject': input
20
+ 'errorObject': input,
21
+ 'source': 'parser:tsoa'
21
22
  })
22
23
  ];
23
24
  };
@@ -15,7 +15,8 @@ const parse = (input) => {
15
15
  'errorObject': input,
16
16
  'data': {
17
17
  'issues': input.issues
18
- }
18
+ },
19
+ 'source': 'parser:zod'
19
20
  })];
20
21
  };
21
22
  exports.default = parse;
package/cjs/problem.d.ts CHANGED
@@ -1,14 +1,14 @@
1
- import type { IProblem, ProblemOpts, JsonProblem } from './typings/problem.js';
1
+ import type { IProblem, ProblemOpts, JsonProblemOutput } from './typings/problem.js';
2
2
  export declare class Problem extends Error implements IProblem {
3
3
  type: string;
4
4
  title: string;
5
5
  status: number;
6
- detail: string;
7
- instance: string;
6
+ detail: string | undefined;
7
+ instance: string | undefined;
8
8
  errorObject?: unknown;
9
- __problemVersion: string;
9
+ readonly __problemVersion = "8.0.1";
10
10
  data: unknown;
11
- middleware?: string;
12
- constructor({ type, title, status, detail, instance, stack, errorObject, data, middleware }: ProblemOpts);
13
- toObject: () => JsonProblem;
11
+ source?: string;
12
+ constructor(opts: ProblemOpts);
13
+ toObject: () => JsonProblemOutput;
14
14
  }
package/cjs/problem.js CHANGED
@@ -1,60 +1,69 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Problem = void 0;
4
- const defaults_js_1 = require("./util/defaults.js");
4
+ const validation_js_1 = require("./util/validation.js");
5
5
  const version_js_1 = require("./util/version.js");
6
6
  class Problem extends Error {
7
- type = defaults_js_1.defaultType;
8
- title = defaults_js_1.defaultTitle;
9
- status = 500;
10
- detail = defaults_js_1.defaultDetail;
11
- instance = defaults_js_1.defaultInstance;
7
+ type;
8
+ title;
9
+ status;
10
+ detail;
11
+ instance;
12
12
  errorObject;
13
13
  __problemVersion = version_js_1.version;
14
14
  data = undefined;
15
- middleware;
16
- constructor({ type, title, status, detail, instance, stack, errorObject, data, middleware }) {
17
- super(detail ?? title ?? 'HTTP Problem Details');
18
- // TODO: Figure out why i wrote this?
15
+ source;
16
+ constructor(opts) {
17
+ const valid = (0, validation_js_1.validateBasicInput)(opts);
18
+ if (valid !== true)
19
+ throw valid;
20
+ super(opts.detail ?? opts.title ?? 'HTTP Problem Details');
21
+ // TODO: Figure out if this is still necessary
19
22
  Object.setPrototypeOf(this, new.target.prototype);
20
- this.type = type;
21
- this.title = title;
22
- this.status = status;
23
- if (detail)
24
- this.detail = detail;
25
- if (instance)
26
- this.instance = instance;
27
- if (errorObject)
28
- this.errorObject = errorObject;
29
- if (middleware)
30
- this.middleware = middleware;
31
- if (stack) {
32
- this.stack = stack;
23
+ this.type = opts.type;
24
+ this.title = opts.title;
25
+ this.status = opts.status;
26
+ if (opts.detail)
27
+ this.detail = opts.detail;
28
+ if (opts.instance)
29
+ this.instance = opts.instance;
30
+ if (opts.errorObject)
31
+ this.errorObject = opts.errorObject;
32
+ if (opts.source)
33
+ this.source = opts.source;
34
+ if (opts.stack) {
35
+ this.stack = opts.stack;
33
36
  }
34
- else if (errorObject && typeof errorObject === 'object' && 'stack' in errorObject && typeof errorObject.stack === 'string') {
35
- this.stack = errorObject.stack;
37
+ else if (opts.errorObject && typeof opts.errorObject === 'object' && 'stack' in opts.errorObject && typeof opts.errorObject.stack === 'string') {
38
+ this.stack = opts.errorObject.stack;
36
39
  }
37
40
  else {
38
41
  if (typeof Error.captureStackTrace === 'function') {
39
42
  Error.captureStackTrace(this, this.constructor);
40
43
  }
41
44
  else {
42
- this.stack = new Error(detail ?? title ?? 'HTTP Problem Details').stack;
45
+ this.stack = new Error(opts.detail ?? opts.title ?? 'HTTP Problem Details').stack;
43
46
  }
44
47
  }
45
- if (data)
46
- this.data = data;
48
+ if (opts.data)
49
+ this.data = opts.data;
47
50
  }
48
51
  toObject = () => {
49
- return {
52
+ const out = {
50
53
  'type': this.type,
51
54
  'title': this.title,
52
55
  'status': this.status,
53
- 'detail': this.detail,
54
- 'instance': this.instance,
55
56
  '__problemVersion': this.__problemVersion,
56
- 'data': this.data
57
57
  };
58
+ if (this.detail)
59
+ out.detail = this.detail;
60
+ if (this.instance)
61
+ out.instance = this.instance;
62
+ if (this.source)
63
+ out.source = this.source;
64
+ if (this.data)
65
+ out.data = this;
66
+ return out;
58
67
  };
59
68
  }
60
69
  exports.Problem = Problem;