@emoyly/problem 5.0.8 → 7.0.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.
Files changed (169) hide show
  1. package/.editorconfig +11 -0
  2. package/.vscode/extensions.json +7 -0
  3. package/.vscode/settings.json +2 -0
  4. package/.yarn/versions/524dd037.yml +0 -0
  5. package/.yarn/versions/b57d536b.yml +0 -0
  6. package/.yarn/versions/d984e272.yml +0 -0
  7. package/README.md +1 -1
  8. package/cjs/defaults/index.d.ts +7 -0
  9. package/cjs/defaults/index.js +17 -0
  10. package/cjs/index.d.ts +4 -0
  11. package/cjs/index.js +22 -0
  12. package/{middleware → cjs/middleware}/axios.d.ts +2 -2
  13. package/cjs/middleware/axios.js +23 -0
  14. package/{middleware → cjs/middleware}/base.d.ts +13 -3
  15. package/cjs/middleware/base.js +73 -0
  16. package/{middleware → cjs/middleware}/express.d.ts +2 -2
  17. package/cjs/middleware/express.js +64 -0
  18. package/cjs/package.json +3 -0
  19. package/cjs/parsers/axios.d.ts +3 -0
  20. package/cjs/parsers/axios.js +55 -0
  21. package/cjs/parsers/jsonwebtoken.d.ts +3 -0
  22. package/{parsers → cjs/parsers}/jsonwebtoken.js +4 -4
  23. package/cjs/parsers/mikroorm.d.ts +3 -0
  24. package/{parsers → cjs/parsers}/mikroorm.js +7 -3
  25. package/cjs/parsers/tsoa.d.ts +3 -0
  26. package/{parsers → cjs/parsers}/tsoa.js +10 -4
  27. package/{problem.d.ts → cjs/problem.d.ts} +1 -1
  28. package/{problem.js → cjs/problem.js} +24 -23
  29. package/cjs/tsconfig.tsbuildinfo +1 -0
  30. package/{typings → cjs/typings}/codes.d.ts +1 -1
  31. package/cjs/typings/index.d.ts +4 -0
  32. package/{typings → cjs/typings}/index.js +4 -5
  33. package/{typings → cjs/typings}/middleware.d.ts +3 -1
  34. package/{typings → cjs/typings}/parser.d.ts +1 -1
  35. package/{util → cjs/util}/getProblems.d.ts +2 -2
  36. package/{util → cjs/util}/getProblems.js +10 -11
  37. package/{util → cjs/util}/isProblemArray.d.ts +1 -1
  38. package/{util → cjs/util}/isProblemArray.js +3 -4
  39. package/{util → cjs/util}/misc.d.ts +1 -1
  40. package/cjs/util/misc.js +19 -0
  41. package/{util → cjs/util}/version.d.ts +1 -1
  42. package/{util → cjs/util}/version.js +3 -3
  43. package/eslint.config.mjs +5 -0
  44. package/esm/defaults/4xx.d.ts +147 -0
  45. package/esm/defaults/4xx.js +148 -0
  46. package/esm/defaults/5xx.d.ts +57 -0
  47. package/esm/defaults/5xx.js +58 -0
  48. package/esm/defaults/aws.d.ts +12 -0
  49. package/esm/defaults/aws.js +13 -0
  50. package/esm/defaults/cloudflare.d.ts +47 -0
  51. package/esm/defaults/cloudflare.js +49 -0
  52. package/esm/defaults/iis.d.ts +17 -0
  53. package/esm/defaults/iis.js +18 -0
  54. package/esm/defaults/index.d.ts +7 -0
  55. package/esm/defaults/index.js +7 -0
  56. package/esm/defaults/nginx.d.ts +32 -0
  57. package/esm/defaults/nginx.js +33 -0
  58. package/esm/defaults/others.d.ts +37 -0
  59. package/esm/defaults/others.js +37 -0
  60. package/esm/index.d.ts +4 -0
  61. package/esm/index.js +4 -0
  62. package/esm/middleware/axios.d.ts +13 -0
  63. package/esm/middleware/axios.js +19 -0
  64. package/esm/middleware/base.d.ts +34 -0
  65. package/esm/middleware/base.js +69 -0
  66. package/esm/middleware/express.d.ts +19 -0
  67. package/esm/middleware/express.js +60 -0
  68. package/esm/package.json +3 -0
  69. package/esm/parsers/axios.d.ts +3 -0
  70. package/esm/parsers/axios.js +53 -0
  71. package/esm/parsers/jsonwebtoken.d.ts +3 -0
  72. package/esm/parsers/jsonwebtoken.js +94 -0
  73. package/esm/parsers/mikroorm.d.ts +3 -0
  74. package/esm/parsers/mikroorm.js +17 -0
  75. package/esm/parsers/tsoa.d.ts +3 -0
  76. package/esm/parsers/tsoa.js +21 -0
  77. package/esm/problem.d.ts +14 -0
  78. package/esm/problem.js +56 -0
  79. package/esm/tsconfig.tsbuildinfo +1 -0
  80. package/esm/typings/codes.d.ts +5 -0
  81. package/esm/typings/codes.js +1 -0
  82. package/esm/typings/index.d.ts +4 -0
  83. package/esm/typings/index.js +4 -0
  84. package/esm/typings/middleware.d.ts +11 -0
  85. package/esm/typings/middleware.js +1 -0
  86. package/esm/typings/parser.d.ts +2 -0
  87. package/esm/typings/parser.js +1 -0
  88. package/esm/typings/problem.d.ts +24 -0
  89. package/esm/typings/problem.js +11 -0
  90. package/esm/util/defaults.d.ts +4 -0
  91. package/esm/util/defaults.js +4 -0
  92. package/esm/util/getProblems.d.ts +5 -0
  93. package/esm/util/getProblems.js +40 -0
  94. package/esm/util/isProblemArray.d.ts +2 -0
  95. package/esm/util/isProblemArray.js +6 -0
  96. package/esm/util/misc.d.ts +2 -0
  97. package/esm/util/misc.js +16 -0
  98. package/esm/util/version.d.ts +3 -0
  99. package/esm/util/version.js +16 -0
  100. package/package.json +51 -28
  101. package/scripts/ensureCorrectVersion.js +8 -4
  102. package/src/defaults/4xx.ts +149 -0
  103. package/src/defaults/5xx.ts +59 -0
  104. package/src/defaults/aws.ts +14 -0
  105. package/src/defaults/cloudflare.ts +50 -0
  106. package/src/defaults/iis.ts +19 -0
  107. package/src/defaults/index.ts +7 -0
  108. package/src/defaults/nginx.ts +34 -0
  109. package/src/defaults/others.ts +37 -0
  110. package/src/index.ts +4 -0
  111. package/src/middleware/axios.ts +28 -0
  112. package/src/middleware/base.ts +90 -0
  113. package/src/middleware/express.ts +71 -0
  114. package/src/parsers/axios.ts +61 -0
  115. package/src/parsers/jsonwebtoken.ts +104 -0
  116. package/src/parsers/mikroorm.ts +21 -0
  117. package/src/parsers/tsoa.ts +25 -0
  118. package/src/problem.ts +56 -0
  119. package/src/typings/codes.ts +6 -0
  120. package/src/typings/index.ts +4 -0
  121. package/src/typings/middleware.ts +14 -0
  122. package/src/typings/parser.ts +3 -0
  123. package/src/typings/problem.ts +27 -0
  124. package/src/util/defaults.ts +4 -0
  125. package/src/util/getProblems.ts +43 -0
  126. package/src/util/isProblemArray.ts +6 -0
  127. package/src/util/misc.ts +20 -0
  128. package/src/util/version.ts +16 -0
  129. package/tsconfig.json +15 -0
  130. package/defaults/index.d.ts +0 -7
  131. package/defaults/index.js +0 -17
  132. package/index.d.ts +0 -5
  133. package/index.js +0 -39
  134. package/middleware/axios.js +0 -36
  135. package/middleware/base.js +0 -56
  136. package/middleware/express.js +0 -60
  137. package/parsers/axios.d.ts +0 -3
  138. package/parsers/axios.js +0 -41
  139. package/parsers/jsonwebtoken.d.ts +0 -3
  140. package/parsers/mikroorm.d.ts +0 -3
  141. package/parsers/tsoa.d.ts +0 -3
  142. package/tsconfig.tsbuildinfo +0 -1
  143. package/typings/events.d.ts +0 -2
  144. package/typings/events.js +0 -2
  145. package/typings/index.d.ts +0 -5
  146. package/util/events.d.ts +0 -16
  147. package/util/events.js +0 -29
  148. package/util/misc.js +0 -43
  149. /package/{defaults → cjs/defaults}/4xx.d.ts +0 -0
  150. /package/{defaults → cjs/defaults}/4xx.js +0 -0
  151. /package/{defaults → cjs/defaults}/5xx.d.ts +0 -0
  152. /package/{defaults → cjs/defaults}/5xx.js +0 -0
  153. /package/{defaults → cjs/defaults}/aws.d.ts +0 -0
  154. /package/{defaults → cjs/defaults}/aws.js +0 -0
  155. /package/{defaults → cjs/defaults}/cloudflare.d.ts +0 -0
  156. /package/{defaults → cjs/defaults}/cloudflare.js +0 -0
  157. /package/{defaults → cjs/defaults}/iis.d.ts +0 -0
  158. /package/{defaults → cjs/defaults}/iis.js +0 -0
  159. /package/{defaults → cjs/defaults}/nginx.d.ts +0 -0
  160. /package/{defaults → cjs/defaults}/nginx.js +0 -0
  161. /package/{defaults → cjs/defaults}/others.d.ts +0 -0
  162. /package/{defaults → cjs/defaults}/others.js +0 -0
  163. /package/{typings → cjs/typings}/codes.js +0 -0
  164. /package/{typings → cjs/typings}/middleware.js +0 -0
  165. /package/{typings → cjs/typings}/parser.js +0 -0
  166. /package/{typings → cjs/typings}/problem.d.ts +0 -0
  167. /package/{typings → cjs/typings}/problem.js +0 -0
  168. /package/{util → cjs/util}/defaults.d.ts +0 -0
  169. /package/{util → cjs/util}/defaults.js +0 -0
@@ -0,0 +1,104 @@
1
+ import { Problem } from '../problem.js'
2
+ import type { Parser } from '../typings/parser.js'
3
+ import { JsonWebTokenError, NotBeforeError, TokenExpiredError } from 'jsonwebtoken'
4
+ import type { ProblemOpts } from '../typings/problem.js'
5
+
6
+ interface ErrorMap {
7
+ 'search': string | RegExp,
8
+ 'result': ProblemOpts,
9
+ }
10
+
11
+ const errorMap: ErrorMap[] = [
12
+ {
13
+ 'search': 'invalid token',
14
+ 'result': {
15
+ 'type': '/errors/jsonwebtoken/invalidtoken',
16
+ 'status': 400,
17
+ 'title': 'Invalid JSON Web Token',
18
+ }
19
+ },
20
+ {
21
+ 'search': 'jwt malformed',
22
+ 'result': {
23
+ 'type': '/errors/jsonwebtoken/malformed',
24
+ 'status': 400,
25
+ 'title': 'Malformed JSON Web Token',
26
+ }
27
+ },
28
+ {
29
+ 'search': 'jwt signature is required',
30
+ 'result': {
31
+ 'type': '/errors/jsonwebtoken/signaturerequired',
32
+ 'status': 400,
33
+ 'title': 'JSON Web Token is missing, but required',
34
+ }
35
+ },
36
+ {
37
+ 'search': 'invalid signature',
38
+ 'result': {
39
+ 'type': '/errors/jsonwebtoken/invalidsignature',
40
+ 'status': 400,
41
+ 'title': 'The JSON Web Token signature is invalid',
42
+ }
43
+ },
44
+ {
45
+ 'search': /^(jwt audience invalid\. expected:)/,
46
+ 'result': {
47
+ 'type': '/errors/jsonwebtoken/invalidaud',
48
+ 'status': 400,
49
+ 'title': 'The JSON Web Token audience is invalid',
50
+ }
51
+ },
52
+ {
53
+ 'search': /^(jwt issuer invalid\. expected:)/,
54
+ 'result': {
55
+ 'type': '/errors/jsonwebtoken/invalidiss',
56
+ 'status': 400,
57
+ 'title': 'The JSON Web Token issuer is invalid',
58
+ }
59
+ },
60
+ {
61
+ 'search': /^(jwt id invalid\. expected:)/,
62
+ 'result': {
63
+ 'type': '/errors/jsonwebtoken/invalidid',
64
+ 'status': 400,
65
+ 'title': 'The JSON Web Token id is invalid',
66
+ }
67
+ },
68
+ {
69
+ 'search': /^(jwt subject invalid\. expected:)/,
70
+ 'result': {
71
+ 'type': '/errors/jsonwebtoken/invalidsubject',
72
+ 'status': 400,
73
+ 'title': 'The JSON Web Token subject is invalid',
74
+ }
75
+ }
76
+ ]
77
+
78
+ const parse: Parser = (input) => {
79
+ if (input instanceof JsonWebTokenError && input.name === 'JsonWebTokenError') {
80
+ const found = errorMap.find(val => typeof val.search === 'string' ? val.search === input.message : val.search.test(input.message))
81
+
82
+ if (found) {
83
+ return [new Problem(found.result)]
84
+ }
85
+ } else if (input instanceof TokenExpiredError && input.name === 'TokenExpiredError') {
86
+ return [new Problem({
87
+ 'title': 'The JSON Web Token has expired',
88
+ 'type': '/errors/jsonwebtoken/tokenexpired',
89
+ 'detail': `The JSON Web Token expired at ${input.expiredAt}`,
90
+ 'status': 400,
91
+ })]
92
+ } else if (input instanceof NotBeforeError && input.name === 'NotBeforeError') {
93
+ return [new Problem({
94
+ 'title': 'The JSON Web Token is not valid yet',
95
+ 'type': '/errors/jsonwebtoken/notbefore',
96
+ 'detail': `The JSON Web Token is not valid before ${input.date}`,
97
+ 'status': 400,
98
+ })]
99
+ }
100
+
101
+ return []
102
+ }
103
+
104
+ export default parse
@@ -0,0 +1,21 @@
1
+ import { Problem } from '../problem.js'
2
+ import { statusCodes } from '../defaults/4xx.js'
3
+ import type { Parser } from '../typings/parser.js'
4
+ import { NotFoundError } from '@mikro-orm/core'
5
+
6
+ // TODO: Make this less bad
7
+ const parse: Parser = (input) => {
8
+ if (!(input instanceof NotFoundError)) {
9
+ return []
10
+ }
11
+
12
+ return [
13
+ new Problem({
14
+ ...statusCodes['404'],
15
+ 'stack': input.stack,
16
+ 'errorObject': input,
17
+ })
18
+ ]
19
+ }
20
+
21
+ export default parse
@@ -0,0 +1,25 @@
1
+ import { ValidateError } from 'tsoa'
2
+ import { Problem } from '../problem.js'
3
+ import { otherErrors } from '../defaults/others.js'
4
+ import type { Parser } from '../typings/parser.js'
5
+
6
+ const parse: Parser = (input) => {
7
+ if (!(input instanceof ValidateError)) {
8
+ return []
9
+ }
10
+
11
+ // TODO: Give actual useful responses instead of this shit
12
+ return [
13
+ new Problem({
14
+ ...otherErrors.inputValidationError,
15
+ 'detail': input.message,
16
+ 'status': input.status,
17
+ 'data': {
18
+ 'fields': input.fields,
19
+ },
20
+ 'stack': input.stack,
21
+ })
22
+ ]
23
+ }
24
+
25
+ export default parse
package/src/problem.ts ADDED
@@ -0,0 +1,56 @@
1
+ import type { IProblem, ProblemOpts, JsonProblem } from './typings/problem.js'
2
+ import { defaultDetail, defaultInstance, defaultTitle, defaultType } from './util/defaults.js'
3
+ import { version } from './util/version.js'
4
+
5
+ export class Problem extends Error implements IProblem {
6
+ public type = defaultType
7
+ public title = defaultTitle
8
+ public status = 500
9
+ public detail = defaultDetail
10
+ public instance = defaultInstance
11
+ public errorObject?: unknown
12
+ public __problemVersion = version
13
+ public data: unknown = undefined
14
+ public middleware?: string
15
+
16
+ constructor({ type, title, status, detail, instance, stack, errorObject, data, middleware }: ProblemOpts) {
17
+ super(detail ?? title ?? 'HTTP Problem Details')
18
+ // TODO: Figure out why i wrote this?
19
+ Object.setPrototypeOf(this, new.target.prototype)
20
+
21
+ this.type = type
22
+ this.title = title
23
+ this.status = status
24
+
25
+ if (detail) this.detail = detail
26
+ if (instance) this.instance = instance
27
+ if (errorObject) this.errorObject = errorObject
28
+ if (middleware) this.middleware = middleware
29
+
30
+ if (stack) {
31
+ this.stack = stack
32
+ } else if (errorObject && typeof errorObject === 'object' && 'stack' in errorObject && typeof errorObject.stack === 'string') {
33
+ this.stack = errorObject.stack
34
+ } else {
35
+ if (typeof Error.captureStackTrace === 'function') {
36
+ Error.captureStackTrace(this, this.constructor)
37
+ } else {
38
+ this.stack = new Error(detail ?? title ?? 'HTTP Problem Details').stack
39
+ }
40
+ }
41
+
42
+ if (data) this.data = data
43
+ }
44
+
45
+ public toObject = (): JsonProblem => {
46
+ return {
47
+ 'type': this.type,
48
+ 'title': this.title,
49
+ 'status': this.status,
50
+ 'detail': this.detail,
51
+ 'instance': this.instance,
52
+ '__problemVersion': this.__problemVersion,
53
+ 'data': this.data
54
+ }
55
+ }
56
+ }
@@ -0,0 +1,6 @@
1
+ import type { ProblemOpts } from './problem.js'
2
+
3
+ export interface Codes {
4
+ [key: number]: ProblemOpts | undefined
5
+ [key: string]: ProblemOpts | undefined
6
+ }
@@ -0,0 +1,4 @@
1
+ export * from './middleware.js'
2
+ export * from './parser.js'
3
+ export * from './problem.js'
4
+ export * from './codes.js'
@@ -0,0 +1,14 @@
1
+ import type { Problem } from '../problem.js'
2
+ import type { Parser } from './parser.js'
3
+
4
+ export interface MiddlewareOptions {
5
+ /**
6
+ * A list of parsers to be used by the middleware.
7
+ * Parsers are run in the order they sit in the array
8
+ */
9
+ parsers: Parser[]
10
+ }
11
+
12
+ export type PartialMiddlewareOptions = Partial<MiddlewareOptions>
13
+
14
+ export type ProblemListener = (problems: Problem[]) => void
@@ -0,0 +1,3 @@
1
+ import type { Problem } from '../problem.js'
2
+
3
+ export type Parser = (input: unknown) => Problem[]
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @param {string} type - A URI refrence that identifies the problem type.
3
+ * @param {string} title - A short, human-readable summary of the problem
4
+ * type. It SHOULD NOT change from occurrence to occurrence of the problem
5
+ * @param {number} status - The HTTP status code
6
+ * @param {string} detail - A human-readable explanation specific to this
7
+ occurrence of the problem.
8
+ * @property {string} instance - A URI reference that identifies the specific
9
+ occurrence of the problem
10
+ **/
11
+
12
+ export interface IProblem {
13
+ type: string
14
+ title: string
15
+ status: number
16
+ detail?: string
17
+ instance?: string
18
+ stack?: string
19
+ errorObject?: unknown
20
+ __problemVersion: string
21
+ data?: unknown
22
+ middleware?: string
23
+ }
24
+
25
+ export type JsonProblem = Omit<IProblem, 'stack' | 'errorObject' | 'middleware'>
26
+
27
+ export type ProblemOpts = Omit<IProblem, '__problemVersion'>
@@ -0,0 +1,4 @@
1
+ export const defaultType = '/errors/default/unknown'
2
+ export const defaultTitle = 'Unknown error'
3
+ export const defaultDetail = 'No extended details are available'
4
+ export const defaultInstance = '/unknown'
@@ -0,0 +1,43 @@
1
+ import { Problem } from '../problem.js'
2
+ import type { JsonProblem } from '../typings/problem.js'
3
+ import { isProblemArray } from './isProblemArray.js'
4
+ import { isCompatibleVersion } from './version.js'
5
+
6
+ const strings = ['title', 'type', 'instance', 'detail', '__problemVersion']
7
+ export function isJsonProblem(input: unknown): input is JsonProblem {
8
+ if (input === null) return false
9
+ if (typeof input !== 'object') return false
10
+
11
+ if (!strings.every(val => val in input && typeof input[val as keyof typeof input] === 'string')) return false
12
+ if (!isCompatibleVersion(('__problemVersion' in input && typeof input['__problemVersion'] === 'string') ? input['__problemVersion'] : '')) return false
13
+
14
+ if (!('status' in input) || typeof input.status !== 'number') return false
15
+
16
+ return true
17
+ }
18
+
19
+ export function createFromJson({ title, type, instance, detail, status, data }: JsonProblem): Problem {
20
+ return new Problem({ title, type, instance, detail, status, data })
21
+ }
22
+
23
+ export function getProblems(input: unknown): Problem[] | void {
24
+ if (typeof input === 'string') {
25
+ try {
26
+ const p = JSON.parse(input)
27
+ input = p
28
+ } catch (err) { /**/ }
29
+ }
30
+
31
+ if (input instanceof Problem) return [input]
32
+ if (isProblemArray(input)) return input
33
+
34
+ if (Array.isArray(input) && input.every(val => isJsonProblem(val))) {
35
+ const _input = input as JsonProblem[]
36
+
37
+ return _input.map(val => createFromJson(val))
38
+ }
39
+
40
+ if (isJsonProblem(input)) {
41
+ return [createFromJson(input)]
42
+ }
43
+ }
@@ -0,0 +1,6 @@
1
+ import { Problem } from '../problem.js'
2
+
3
+ export function isProblemArray(input: unknown): input is Problem[] {
4
+ if (!Array.isArray(input)) return false
5
+ return input.every(val => val instanceof Problem)
6
+ }
@@ -0,0 +1,20 @@
1
+ import * as allCodes from '../defaults/index.js'
2
+ import { ProblemOpts, Codes } from '../typings/index.js'
3
+
4
+ export function getHttpError(statusCode: number | string): ProblemOpts | undefined {
5
+ for (const key in allCodes) {
6
+ // This ensures all codes are written correctly as well, so that's a bonus
7
+ const codeObject: Codes = allCodes[key as keyof typeof allCodes]
8
+
9
+ if (typeof statusCode === 'string') {
10
+ const conv = Number(statusCode)
11
+ if (!isNaN(conv)) statusCode = conv
12
+ }
13
+
14
+ const code = codeObject[statusCode]
15
+
16
+ if (!code) return
17
+
18
+ return code
19
+ }
20
+ }
@@ -0,0 +1,16 @@
1
+ export const version = '7.0.0'
2
+ export const major = Number(version.split('.')[0])
3
+
4
+ export function isCompatibleVersion(inputVersion: string) {
5
+ // TODO: Remove this
6
+ if (inputVersion === 'lua-dev') return true
7
+
8
+ const parts = inputVersion.split('.')
9
+ const inputMajor = Number(parts[0])
10
+
11
+ if (parts.length !== 3) return false
12
+ if (isNaN(inputMajor)) return false
13
+ if (inputMajor !== major) return false
14
+
15
+ return true
16
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "extends": "./node_modules/@emoyly/devutils/tsconfig-base.json",
3
+ "compilerOptions": {
4
+ "outDir": "./esm",
5
+ "esModuleInterop": false,
6
+ "lib": [
7
+ "DOM",
8
+ "ES2022"
9
+ ]
10
+ },
11
+ "exclude": [
12
+ "./esm/",
13
+ "./cjs/"
14
+ ]
15
+ }
@@ -1,7 +0,0 @@
1
- export { statusCodes as codes4xx } from '../defaults/4xx';
2
- export { statusCodes as codes5xx } from '../defaults/5xx';
3
- export { statusCodes as codesAws } from '../defaults/aws';
4
- export { statusCodes as codesCloudflare } from '../defaults/cloudflare';
5
- export { statusCodes as codesIis } from '../defaults/iis';
6
- export { statusCodes as codesNginx } from '../defaults/nginx';
7
- export { otherErrors } from '../defaults/others';
package/defaults/index.js DELETED
@@ -1,17 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.otherErrors = exports.codesNginx = exports.codesIis = exports.codesCloudflare = exports.codesAws = exports.codes5xx = exports.codes4xx = void 0;
4
- var _4xx_1 = require("../defaults/4xx");
5
- Object.defineProperty(exports, "codes4xx", { enumerable: true, get: function () { return _4xx_1.statusCodes; } });
6
- var _5xx_1 = require("../defaults/5xx");
7
- Object.defineProperty(exports, "codes5xx", { enumerable: true, get: function () { return _5xx_1.statusCodes; } });
8
- var aws_1 = require("../defaults/aws");
9
- Object.defineProperty(exports, "codesAws", { enumerable: true, get: function () { return aws_1.statusCodes; } });
10
- var cloudflare_1 = require("../defaults/cloudflare");
11
- Object.defineProperty(exports, "codesCloudflare", { enumerable: true, get: function () { return cloudflare_1.statusCodes; } });
12
- var iis_1 = require("../defaults/iis");
13
- Object.defineProperty(exports, "codesIis", { enumerable: true, get: function () { return iis_1.statusCodes; } });
14
- var nginx_1 = require("../defaults/nginx");
15
- Object.defineProperty(exports, "codesNginx", { enumerable: true, get: function () { return nginx_1.statusCodes; } });
16
- var others_1 = require("../defaults/others");
17
- Object.defineProperty(exports, "otherErrors", { enumerable: true, get: function () { return others_1.otherErrors; } });
package/index.d.ts DELETED
@@ -1,5 +0,0 @@
1
- export { Problem } from './problem';
2
- export * as defaults from './defaults';
3
- export { default as events } from './util/events';
4
- export * from './typings';
5
- export * from './util/isProblemArray';
package/index.js DELETED
@@ -1,39 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
26
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
27
- };
28
- var __importDefault = (this && this.__importDefault) || function (mod) {
29
- return (mod && mod.__esModule) ? mod : { "default": mod };
30
- };
31
- Object.defineProperty(exports, "__esModule", { value: true });
32
- exports.events = exports.defaults = exports.Problem = void 0;
33
- var problem_1 = require("./problem");
34
- Object.defineProperty(exports, "Problem", { enumerable: true, get: function () { return problem_1.Problem; } });
35
- exports.defaults = __importStar(require("./defaults"));
36
- var events_1 = require("./util/events");
37
- Object.defineProperty(exports, "events", { enumerable: true, get: function () { return __importDefault(events_1).default; } });
38
- __exportStar(require("./typings"), exports);
39
- __exportStar(require("./util/isProblemArray"), exports);
@@ -1,36 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.AxiosMiddleware = void 0;
16
- const base_1 = require("./base");
17
- const axios_1 = __importDefault(require("../parsers/axios"));
18
- const events_1 = __importDefault(require("../util/events"));
19
- class AxiosMiddleware extends base_1.MiddlewareBase {
20
- constructor(options) {
21
- super({
22
- 'parsers': [axios_1.default]
23
- }, options);
24
- this.name = 'axios';
25
- this.interceptor = (error) => __awaiter(this, void 0, void 0, function* () {
26
- const problems = yield this.parse(error);
27
- events_1.default.emit(problems);
28
- return Promise.reject(problems);
29
- });
30
- /**
31
- * @example instance.interceptors.response.use(...middleware.use())
32
- */
33
- this.use = () => [undefined, this.interceptor];
34
- }
35
- }
36
- exports.AxiosMiddleware = AxiosMiddleware;
@@ -1,56 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.MiddlewareBase = void 0;
13
- const defaults_1 = require("../defaults");
14
- const problem_1 = require("../problem");
15
- const getProblems_1 = require("../util/getProblems");
16
- /**
17
- * Middleware collects errors from somewhere, transforms them into something recognizable by a parser, and then passes them to the parsers, and then returns an array of Problems to whatever is using the middleware
18
- */
19
- class MiddlewareBase {
20
- constructor(defaultOptions, options) {
21
- /**
22
- * When nothing is returned from the parsers, just throw in a default "fallback" Problem object, so that a Problem is still actually returned/emitted
23
- */
24
- this.enableFallback = true;
25
- /**
26
- * Parse input using parsers
27
- */
28
- this.parse = (input) => __awaiter(this, void 0, void 0, function* () {
29
- const problems = [];
30
- const prob = (0, getProblems_1.getProblems)(input);
31
- if (!prob) {
32
- for (const parse of this.options.parsers) {
33
- const resp = parse(input);
34
- if (!resp.length)
35
- continue;
36
- problems.push(...resp);
37
- break;
38
- }
39
- if (!problems.length && this.enableFallback) {
40
- problems.push(new problem_1.Problem(Object.assign(Object.assign({}, this.fallback), { 'errorObject': input, 'stack': (typeof input === 'object' && input !== null && 'stack' in input && typeof input.stack === 'string') ? input.stack : undefined })));
41
- }
42
- }
43
- else {
44
- problems.push(...prob);
45
- }
46
- for (const p of problems) {
47
- if (!p.middleware)
48
- p.middleware = this.name;
49
- }
50
- return problems;
51
- });
52
- this.fallback = defaults_1.otherErrors.unknown;
53
- this.options = Object.assign(Object.assign({}, defaultOptions), options);
54
- }
55
- }
56
- exports.MiddlewareBase = MiddlewareBase;
@@ -1,60 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ExpressMiddleware = void 0;
7
- const base_1 = require("./base");
8
- const problem_1 = require("../problem");
9
- const defaults_1 = require("../defaults");
10
- const events_1 = __importDefault(require("../util/events"));
11
- const defaults_2 = require("../util/defaults");
12
- class ExpressMiddleware extends base_1.MiddlewareBase {
13
- constructor(options) {
14
- super({
15
- 'parsers': []
16
- }, options);
17
- this.name = 'express';
18
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
19
- this.middleware = (error, req, res, next) => {
20
- this.parse(error)
21
- .then(problems => {
22
- var _a, _b;
23
- for (const problem of problems) {
24
- if (problem.instance === defaults_2.defaultInstance) {
25
- problem.instance = req.originalUrl;
26
- }
27
- }
28
- events_1.default.emit(problems);
29
- res
30
- .contentType('application/problem+json')
31
- .status((_b = (_a = problems[0]) === null || _a === void 0 ? void 0 : _a.status) !== null && _b !== void 0 ? _b : 500)
32
- .json(problems.map(val => val.toObject()));
33
- })
34
- .catch(err => {
35
- res
36
- .contentType('application/problem+json')
37
- .status(500)
38
- .json([
39
- new problem_1.Problem(Object.assign(Object.assign({}, defaults_1.otherErrors.unknown), { 'instance': req.originalUrl, 'status': 500, 'stack': err === null || err === void 0 ? void 0 : err.stack, 'errorObject': err })).toObject()
40
- ]);
41
- throw err;
42
- });
43
- };
44
- /**
45
- * This function applies the middleware to your Express application. Put this at the very end of your middleware/routes.
46
- * If you want to also handle 404 errors, check out the notFound middleware function.
47
- * @example app.use(middleware.use())
48
- */
49
- this.use = () => this.middleware;
50
- /**
51
- * Put this right before the middleware.use() to catch all 404 errors and respond with a Problem instead of the default Express response
52
- * @example app.use(middleware.notFound)
53
- */
54
- this.notFound = (req, res, next) => {
55
- const error = new problem_1.Problem(Object.assign(Object.assign({}, defaults_1.codes4xx[404]), { 'instance': req.originalUrl, 'detail': `No API endpoints exist on ${req.url} for request method ${req.method}` }));
56
- return next(error);
57
- };
58
- }
59
- }
60
- exports.ExpressMiddleware = ExpressMiddleware;
@@ -1,3 +0,0 @@
1
- import type { Parser } from '../typings/parser';
2
- declare const parse: Parser;
3
- export default parse;
package/parsers/axios.js DELETED
@@ -1,41 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const others_1 = require("../defaults/others");
4
- const problem_1 = require("../problem");
5
- const getProblems_1 = require("../util/getProblems");
6
- const misc_1 = require("../util/misc");
7
- function isAxiosError(payload) {
8
- return typeof payload === 'object' && payload !== null && 'isAxiosError' in payload && payload.isAxiosError === true;
9
- }
10
- const parse = (input) => {
11
- var _a, _b, _c, _d, _e;
12
- if (typeof input !== 'object' || input == null)
13
- return [];
14
- if (!isAxiosError(input))
15
- return [];
16
- const request = input.request;
17
- if ((_a = input === null || input === void 0 ? void 0 : input.response) === null || _a === void 0 ? void 0 : _a.data) {
18
- const problems = (0, getProblems_1.getProblems)((_b = input === null || input === void 0 ? void 0 : input.response) === null || _b === void 0 ? void 0 : _b.data);
19
- if (problems === null || problems === void 0 ? void 0 : problems.length)
20
- return problems;
21
- }
22
- if (input === null || input === void 0 ? void 0 : input.response) {
23
- const opts = (0, misc_1.getHttpError)(input.response.status);
24
- if (opts)
25
- return [new problem_1.Problem(Object.assign(Object.assign({}, opts), { 'instance': (_c = input === null || input === void 0 ? void 0 : input.config) === null || _c === void 0 ? void 0 : _c.url, 'stack': input === null || input === void 0 ? void 0 : input.stack, 'errorObject': input }))];
26
- }
27
- // TODO: Fix this, this seems bad
28
- if (request) {
29
- const isNode = typeof process !== 'undefined' && process.versions && process.versions.node;
30
- const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
31
- if (isBrowser && request instanceof XMLHttpRequest) {
32
- return [new problem_1.Problem(Object.assign(Object.assign({}, others_1.otherErrors.networkError), { 'instance': (_d = input === null || input === void 0 ? void 0 : input.config) === null || _d === void 0 ? void 0 : _d.url, 'stack': input === null || input === void 0 ? void 0 : input.stack, 'errorObject': input }))];
33
- }
34
- // Probably a ClientRequest
35
- if (isNode && 'pipe' in request && 'destroy' in request) {
36
- return [new problem_1.Problem(Object.assign(Object.assign({}, others_1.otherErrors.networkError), { 'instance': (_e = input === null || input === void 0 ? void 0 : input.config) === null || _e === void 0 ? void 0 : _e.url, 'stack': input === null || input === void 0 ? void 0 : input.stack, 'errorObject': input }))];
37
- }
38
- }
39
- return [];
40
- };
41
- exports.default = parse;