@marianmeres/http-utils 1.23.0 → 2.0.2
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/README.md +261 -44
- package/dist/api.d.ts +140 -16
- package/dist/api.js +298 -0
- package/dist/error.d.ts +45 -2
- package/dist/error.js +243 -0
- package/dist/mod.d.ts +3 -0
- package/dist/mod.js +3 -0
- package/dist/status.d.ts +18 -2
- package/dist/status.js +137 -0
- package/package.json +6 -40
- package/dist/index.cjs +0 -472
- package/dist/index.d.ts +0 -3
- package/dist/index.js +0 -466
package/dist/status.js
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP status codes organized by category with convenience shortcuts.
|
|
3
|
+
* Provides comprehensive coverage of standard HTTP status codes.
|
|
4
|
+
*/
|
|
5
|
+
// prettier-ignore
|
|
6
|
+
export class HTTP_STATUS {
|
|
7
|
+
// Full database of HTTP status codes
|
|
8
|
+
// 1xx
|
|
9
|
+
static INFO = {
|
|
10
|
+
CONTINUE: { CODE: 100, TEXT: 'Continue' },
|
|
11
|
+
SWITCHING_PROTOCOLS: { CODE: 101, TEXT: 'Switching Protocols' },
|
|
12
|
+
PROCESSING: { CODE: 102, TEXT: 'Processing' },
|
|
13
|
+
EARLY_HINTS: { CODE: 103, TEXT: 'Early Hints' },
|
|
14
|
+
};
|
|
15
|
+
// 2xx
|
|
16
|
+
static SUCCESS = {
|
|
17
|
+
OK: { CODE: 200, TEXT: 'OK' },
|
|
18
|
+
CREATED: { CODE: 201, TEXT: 'Created' },
|
|
19
|
+
ACCEPTED: { CODE: 202, TEXT: 'Accepted' },
|
|
20
|
+
NON_AUTHORITATIVE_INFO: { CODE: 203, TEXT: 'Non-Authoritative Information' },
|
|
21
|
+
NO_CONTENT: { CODE: 204, TEXT: 'No Content' },
|
|
22
|
+
RESET_CONTENT: { CODE: 205, TEXT: 'Reset Content' },
|
|
23
|
+
PARTIAL_CONTENT: { CODE: 206, TEXT: 'Partial Content' },
|
|
24
|
+
MULTI_STATUS: { CODE: 207, TEXT: 'Multi-Status' },
|
|
25
|
+
ALREADY_REPORTED: { CODE: 208, TEXT: 'Already Reported' },
|
|
26
|
+
IM_USED: { CODE: 226, TEXT: 'IM Used' }, // ?
|
|
27
|
+
};
|
|
28
|
+
// 3xx
|
|
29
|
+
static REDIRECT = {
|
|
30
|
+
MULTIPLE_CHOICES: { CODE: 300, TEXT: 'Multiple Choices' },
|
|
31
|
+
MOVED_PERMANENTLY: { CODE: 301, TEXT: 'Moved Permanently' },
|
|
32
|
+
FOUND: { CODE: 302, TEXT: 'Found' },
|
|
33
|
+
SEE_OTHER: { CODE: 303, TEXT: 'See Other' },
|
|
34
|
+
NOT_MODIFIED: { CODE: 304, TEXT: 'Not Modified' },
|
|
35
|
+
TEMPORARY_REDIRECT: { CODE: 307, TEXT: 'Temporary Redirect' },
|
|
36
|
+
PERMANENT_REDIRECT: { CODE: 308, TEXT: 'Permanent Redirect' },
|
|
37
|
+
};
|
|
38
|
+
// 4xx
|
|
39
|
+
static ERROR_CLIENT = {
|
|
40
|
+
BAD_REQUEST: { CODE: 400, TEXT: 'Bad Request' },
|
|
41
|
+
UNAUTHORIZED: { CODE: 401, TEXT: 'Unauthorized' },
|
|
42
|
+
PAYMENT_REQUIRED_EXPERIMENTAL: { CODE: 402, TEXT: 'Payment Required Experimental' },
|
|
43
|
+
FORBIDDEN: { CODE: 403, TEXT: 'Forbidden' },
|
|
44
|
+
NOT_FOUND: { CODE: 404, TEXT: 'Not Found' },
|
|
45
|
+
METHOD_NOT_ALLOWED: { CODE: 405, TEXT: 'Method Not Allowed' },
|
|
46
|
+
NOT_ACCEPTABLE: { CODE: 406, TEXT: 'Not Acceptable' },
|
|
47
|
+
PROXY_AUTHENTICATION_REQUIRED: { CODE: 407, TEXT: 'Proxy Authentication Required' },
|
|
48
|
+
REQUEST_TIMEOUT: { CODE: 408, TEXT: 'Request Timeout' },
|
|
49
|
+
CONFLICT: { CODE: 409, TEXT: 'Conflict' },
|
|
50
|
+
GONE: { CODE: 410, TEXT: 'Gone' },
|
|
51
|
+
LENGTH_REQUIRED: { CODE: 411, TEXT: 'Length Required' },
|
|
52
|
+
PRECONDITION_FAILED: { CODE: 412, TEXT: 'Precondition Failed' },
|
|
53
|
+
PAYLOAD_TOO_LARGE: { CODE: 413, TEXT: 'Payload Too Large' },
|
|
54
|
+
URI_TOO_LONG: { CODE: 414, TEXT: 'URI Too Long' },
|
|
55
|
+
UNSUPPORTED_MEDIA_TYPE: { CODE: 415, TEXT: 'Unsupported Media Type' },
|
|
56
|
+
RANGE_NOT_SATISFIABLE: { CODE: 416, TEXT: 'Range Not Satisfiable' },
|
|
57
|
+
EXPECTATION_FAILED: { CODE: 417, TEXT: 'Expectation Failed' },
|
|
58
|
+
IM_A_TEAPOT: { CODE: 418, TEXT: "I'm a teapot" },
|
|
59
|
+
MISDIRECTED_REQUEST: { CODE: 421, TEXT: 'Misdirected Request' },
|
|
60
|
+
UNPROCESSABLE_CONTENT: { CODE: 422, TEXT: 'Unprocessable Content' },
|
|
61
|
+
LOCKED: { CODE: 423, TEXT: 'Locked' },
|
|
62
|
+
FAILED_DEPENDENCY: { CODE: 424, TEXT: 'Failed Dependency' },
|
|
63
|
+
TOO_EARLY_EXPERIMENTAL: { CODE: 425, TEXT: 'Too Early Experimental' },
|
|
64
|
+
UPGRADE_REQUIRED: { CODE: 426, TEXT: 'Upgrade Required' },
|
|
65
|
+
PRECONDITION_REQUIRED: { CODE: 428, TEXT: 'Precondition Required' },
|
|
66
|
+
TOO_MANY_REQUESTS: { CODE: 429, TEXT: 'Too Many Requests' },
|
|
67
|
+
REQUEST_HEADER_FIELDS_TOO_LARGE: { CODE: 431, TEXT: 'Request Header Fields Too Large' },
|
|
68
|
+
UNAVAILABLE_FOR_LEGAL_REASONS: { CODE: 451, TEXT: 'Unavailable For Legal Reasons' },
|
|
69
|
+
};
|
|
70
|
+
// 5xx
|
|
71
|
+
// prettier-ignore
|
|
72
|
+
static ERROR_SERVER = {
|
|
73
|
+
INTERNAL_SERVER_ERROR: { CODE: 500, TEXT: 'Internal Server Error' },
|
|
74
|
+
NOT_IMPLEMENTED: { CODE: 501, TEXT: 'Not Implemented' },
|
|
75
|
+
BAD_GATEWAY: { CODE: 502, TEXT: 'Bad Gateway' },
|
|
76
|
+
SERVICE_UNAVAILABLE: { CODE: 503, TEXT: 'Service Unavailable' },
|
|
77
|
+
GATEWAY_TIMEOUT: { CODE: 504, TEXT: 'Gateway Timeout' },
|
|
78
|
+
HTTP_VERSION_NOT_SUPPORTED: { CODE: 505, TEXT: 'HTTP Version Not Supported' },
|
|
79
|
+
VARIANT_ALSO_NEGOTIATES: { CODE: 506, TEXT: 'Variant Also Negotiates' },
|
|
80
|
+
INSUFFICIENT_STORAGE: { CODE: 507, TEXT: 'Insufficient Storage' },
|
|
81
|
+
LOOP_DETECTED: { CODE: 508, TEXT: 'Loop Detected' },
|
|
82
|
+
NOT_EXTENDED: { CODE: 510, TEXT: 'Not Extended' },
|
|
83
|
+
NETWORK_AUTH_REQUIRED: { CODE: 511, TEXT: 'Network Authentication Required' },
|
|
84
|
+
};
|
|
85
|
+
// Convenience shortcuts: direct access to frequently used status codes
|
|
86
|
+
// 2xx
|
|
87
|
+
static OK = HTTP_STATUS.SUCCESS.OK.CODE;
|
|
88
|
+
static CREATED = HTTP_STATUS.SUCCESS.CREATED.CODE;
|
|
89
|
+
static ACCEPTED = HTTP_STATUS.SUCCESS.ACCEPTED.CODE;
|
|
90
|
+
static NO_CONTENT = HTTP_STATUS.SUCCESS.NO_CONTENT.CODE;
|
|
91
|
+
// 3xx
|
|
92
|
+
static MULTIPLE_CHOICES = HTTP_STATUS.REDIRECT.MULTIPLE_CHOICES.CODE;
|
|
93
|
+
static FOUND = HTTP_STATUS.REDIRECT.FOUND.CODE;
|
|
94
|
+
static NOT_MODIFIED = HTTP_STATUS.REDIRECT.NOT_MODIFIED.CODE;
|
|
95
|
+
static MOVED_PERMANENTLY = HTTP_STATUS.REDIRECT.MOVED_PERMANENTLY.CODE;
|
|
96
|
+
static TEMPORARY_REDIRECT = HTTP_STATUS.REDIRECT.TEMPORARY_REDIRECT.CODE;
|
|
97
|
+
static PERMANENT_REDIRECT = HTTP_STATUS.REDIRECT.PERMANENT_REDIRECT.CODE;
|
|
98
|
+
// 4xx
|
|
99
|
+
static BAD_REQUEST = HTTP_STATUS.ERROR_CLIENT.BAD_REQUEST.CODE;
|
|
100
|
+
static UNAUTHORIZED = HTTP_STATUS.ERROR_CLIENT.UNAUTHORIZED.CODE;
|
|
101
|
+
static FORBIDDEN = HTTP_STATUS.ERROR_CLIENT.FORBIDDEN.CODE;
|
|
102
|
+
static NOT_FOUND = HTTP_STATUS.ERROR_CLIENT.NOT_FOUND.CODE;
|
|
103
|
+
static METHOD_NOT_ALLOWED = HTTP_STATUS.ERROR_CLIENT.METHOD_NOT_ALLOWED.CODE;
|
|
104
|
+
static CONFLICT = HTTP_STATUS.ERROR_CLIENT.CONFLICT.CODE;
|
|
105
|
+
static GONE = HTTP_STATUS.ERROR_CLIENT.GONE.CODE;
|
|
106
|
+
static UNPROCESSABLE_CONTENT = HTTP_STATUS.ERROR_CLIENT.UNPROCESSABLE_CONTENT.CODE;
|
|
107
|
+
static TOO_MANY_REQUESTS = HTTP_STATUS.ERROR_CLIENT.TOO_MANY_REQUESTS.CODE;
|
|
108
|
+
// 5xx
|
|
109
|
+
static INTERNAL_SERVER_ERROR = HTTP_STATUS.ERROR_SERVER.INTERNAL_SERVER_ERROR.CODE;
|
|
110
|
+
static NOT_IMPLEMENTED = HTTP_STATUS.ERROR_SERVER.NOT_IMPLEMENTED.CODE;
|
|
111
|
+
static SERVICE_UNAVAILABLE = HTTP_STATUS.ERROR_SERVER.SERVICE_UNAVAILABLE.CODE;
|
|
112
|
+
/**
|
|
113
|
+
* Finds a status code definition by its numeric code.
|
|
114
|
+
*
|
|
115
|
+
* @param code - The HTTP status code to look up (e.g., 200, 404, 500).
|
|
116
|
+
* @returns An object with CODE, TEXT, _TYPE (category), and _KEY (name), or null if not found.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```ts
|
|
120
|
+
* const status = HTTP_STATUS.findByCode(404);
|
|
121
|
+
* // { CODE: 404, TEXT: "Not Found", _TYPE: "ERROR_CLIENT", _KEY: "NOT_FOUND" }
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
static findByCode(code) {
|
|
125
|
+
const keys = [
|
|
126
|
+
'INFO', 'SUCCESS', 'REDIRECT', 'ERROR_CLIENT', 'ERROR_SERVER',
|
|
127
|
+
];
|
|
128
|
+
for (const _TYPE of keys) {
|
|
129
|
+
for (const [_KEY, data] of Object.entries(HTTP_STATUS[_TYPE])) {
|
|
130
|
+
if (data.CODE == code) {
|
|
131
|
+
return { ...data, _TYPE, _KEY };
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
}
|
package/package.json
CHANGED
|
@@ -1,50 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@marianmeres/http-utils",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Misc DRY http fetch related helpers",
|
|
3
|
+
"version": "2.0.2",
|
|
5
4
|
"type": "module",
|
|
6
|
-
"main": "
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
"import": "./dist/index.js"
|
|
11
|
-
},
|
|
12
|
-
"files": [
|
|
13
|
-
"dist"
|
|
14
|
-
],
|
|
15
|
-
"scripts": {
|
|
16
|
-
"clean": "rimraf dist/*",
|
|
17
|
-
"prettier": "prettier --write \"{src,tests}/**/*.{js,ts,json}\"",
|
|
18
|
-
"release": "release -v minor",
|
|
19
|
-
"release:patch": "release -v patch",
|
|
20
|
-
"test": "test-runner",
|
|
21
|
-
"build": "npm run clean && rollup -c",
|
|
22
|
-
"build:watch": "npm run clean && rollup -w -c"
|
|
23
|
-
},
|
|
24
|
-
"types": "./dist/index.d.ts",
|
|
5
|
+
"main": "dist/mod.js",
|
|
6
|
+
"types": "dist/mod.d.ts",
|
|
7
|
+
"author": "Marian Meres",
|
|
8
|
+
"license": "MIT",
|
|
25
9
|
"repository": {
|
|
26
10
|
"type": "git",
|
|
27
11
|
"url": "git+https://github.com/marianmeres/http-utils.git"
|
|
28
12
|
},
|
|
29
|
-
"author": "Marian Meres <marian@meres.sk>",
|
|
30
|
-
"license": "MIT",
|
|
31
13
|
"bugs": {
|
|
32
14
|
"url": "https://github.com/marianmeres/http-utils/issues"
|
|
33
|
-
},
|
|
34
|
-
"homepage": "https://github.com/marianmeres/http-utils#readme",
|
|
35
|
-
"devDependencies": {
|
|
36
|
-
"@marianmeres/clog": "^1.0.1",
|
|
37
|
-
"@marianmeres/release": "^1.1.2",
|
|
38
|
-
"@marianmeres/test-runner": "^2.0.16",
|
|
39
|
-
"@rollup/plugin-typescript": "^11.1.6",
|
|
40
|
-
"@types/node": "^22.3.0",
|
|
41
|
-
"prettier": "^3.3.3",
|
|
42
|
-
"rimraf": "^6.0.1",
|
|
43
|
-
"rollup": "^4.20.0",
|
|
44
|
-
"tslib": "^2.6.3",
|
|
45
|
-
"typescript": "^5.5.4"
|
|
46
|
-
},
|
|
47
|
-
"dependencies": {
|
|
48
|
-
"dset": "^3.1.3"
|
|
49
15
|
}
|
|
50
|
-
}
|
|
16
|
+
}
|
package/dist/index.cjs
DELETED
|
@@ -1,472 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var merge = require('dset/merge');
|
|
4
|
-
|
|
5
|
-
// prettier-ignore
|
|
6
|
-
class HTTP_STATUS {
|
|
7
|
-
// full db
|
|
8
|
-
// 1xx
|
|
9
|
-
static INFO = {
|
|
10
|
-
CONTINUE: { CODE: 100, TEXT: 'Continue' },
|
|
11
|
-
SWITCHING_PROTOCOLS: { CODE: 101, TEXT: 'Switching Protocols' },
|
|
12
|
-
PROCESSING: { CODE: 102, TEXT: 'Processing' },
|
|
13
|
-
EARLY_HINTS: { CODE: 103, TEXT: 'Early Hints' },
|
|
14
|
-
};
|
|
15
|
-
// 2xx
|
|
16
|
-
static SUCCESS = {
|
|
17
|
-
OK: { CODE: 200, TEXT: 'OK' },
|
|
18
|
-
CREATED: { CODE: 201, TEXT: 'Created' },
|
|
19
|
-
ACCEPTED: { CODE: 202, TEXT: 'Accepted' },
|
|
20
|
-
NON_AUTHORITATIVE_INFO: { CODE: 203, TEXT: 'Non-Authoritative Information' },
|
|
21
|
-
NO_CONTENT: { CODE: 204, TEXT: 'No Content' },
|
|
22
|
-
RESET_CONTENT: { CODE: 205, TEXT: 'Reset Content' },
|
|
23
|
-
PARTIAL_CONTENT: { CODE: 206, TEXT: 'Partial Content' },
|
|
24
|
-
MULTI_STATUS: { CODE: 207, TEXT: 'Multi-Status' },
|
|
25
|
-
ALREADY_REPORTED: { CODE: 208, TEXT: 'Already Reported' },
|
|
26
|
-
IM_USED: { CODE: 226, TEXT: 'IM Used' }, // ?
|
|
27
|
-
};
|
|
28
|
-
// 3xx
|
|
29
|
-
static REDIRECT = {
|
|
30
|
-
MUTLIPLE_CHOICES: { CODE: 300, TEXT: 'Multiple Choices' },
|
|
31
|
-
MOVED_PERMANENTLY: { CODE: 301, TEXT: 'Moved Permanently' },
|
|
32
|
-
FOUND: { CODE: 302, TEXT: 'Found' },
|
|
33
|
-
SEE_OTHER: { CODE: 303, TEXT: 'See Other' },
|
|
34
|
-
NOT_MODIFIED: { CODE: 304, TEXT: 'Not Modified' },
|
|
35
|
-
TEMPORARY_REDIRECT: { CODE: 307, TEXT: 'Temporary Redirect' },
|
|
36
|
-
PERMANENT_REDIRECT: { CODE: 308, TEXT: 'Permanent Redirect' },
|
|
37
|
-
};
|
|
38
|
-
// 4xx
|
|
39
|
-
static ERROR_CLIENT = {
|
|
40
|
-
BAD_REQUEST: { CODE: 400, TEXT: 'Bad Request' },
|
|
41
|
-
UNAUTHORIZED: { CODE: 401, TEXT: 'Unauthorized' },
|
|
42
|
-
PAYMENT_REQUIRED_EXPERIMENTAL: { CODE: 402, TEXT: 'Payment Required Experimental' },
|
|
43
|
-
FORBIDDEN: { CODE: 403, TEXT: 'Forbidden' },
|
|
44
|
-
NOT_FOUND: { CODE: 404, TEXT: 'Not Found' },
|
|
45
|
-
METHOD_NOT_ALLOWED: { CODE: 405, TEXT: 'Method Not Allowed' },
|
|
46
|
-
NOT_ACCEPTABLE: { CODE: 406, TEXT: 'Not Acceptable' },
|
|
47
|
-
PROXY_AUTHENTICATION_REQUIRED: { CODE: 407, TEXT: 'Proxy Authentication Required' },
|
|
48
|
-
REQUEST_TIMEOUT: { CODE: 408, TEXT: 'Request Timeout' },
|
|
49
|
-
CONFLICT: { CODE: 409, TEXT: 'Conflict' },
|
|
50
|
-
GONE: { CODE: 410, TEXT: 'Gone' },
|
|
51
|
-
LENGTH_REQUIRED: { CODE: 411, TEXT: 'Length Required' },
|
|
52
|
-
PRECONDITION_FAILED: { CODE: 412, TEXT: 'Precondition Failed' },
|
|
53
|
-
PAYLOAD_TOO_LARGE: { CODE: 413, TEXT: 'Payload Too Large' },
|
|
54
|
-
URI_TOO_LONG: { CODE: 414, TEXT: 'URI Too Long' },
|
|
55
|
-
UNSUPPORTED_MEDIA_TYPE: { CODE: 415, TEXT: 'Unsupported Media Type' },
|
|
56
|
-
RANGE_NOT_SATISFIABLE: { CODE: 416, TEXT: 'Range Not Satisfiable' },
|
|
57
|
-
EXPECTATION_FAILED: { CODE: 417, TEXT: 'Expectation Failed' },
|
|
58
|
-
IM_A_TEAPOT: { CODE: 418, TEXT: "I'm a teapot" },
|
|
59
|
-
MISDIRECTED_REQUEST: { CODE: 421, TEXT: 'Misdirected Request' },
|
|
60
|
-
UNPROCESSABLE_CONTENT: { CODE: 422, TEXT: 'Unprocessable Content' },
|
|
61
|
-
LOCKED: { CODE: 423, TEXT: 'Locked' },
|
|
62
|
-
FAILED_DEPENDENCY: { CODE: 424, TEXT: 'Failed Dependency' },
|
|
63
|
-
TOO_EARLY_EXPERIMENTAL: { CODE: 425, TEXT: 'Too Early Experimental' },
|
|
64
|
-
UPGRADE_REQUIRED: { CODE: 426, TEXT: 'Upgrade Required' },
|
|
65
|
-
PRECONDITION_REQUIRED: { CODE: 428, TEXT: 'Precondition Required' },
|
|
66
|
-
TOO_MANY_REQUESTS: { CODE: 429, TEXT: 'Too Many Requests' },
|
|
67
|
-
REQUEST_HEADER_FIELDS_TOO_LARGE: { CODE: 431, TEXT: 'Request Header Fields Too Large' },
|
|
68
|
-
UNAVAILABLE_FOR_LEGAL_REASONS: { CODE: 451, TEXT: 'Unavailable For Legal Reasons' },
|
|
69
|
-
};
|
|
70
|
-
// 5xx
|
|
71
|
-
// prettier-ignore
|
|
72
|
-
static ERROR_SERVER = {
|
|
73
|
-
INTERNAL_SERVER_ERROR: { CODE: 500, TEXT: 'Internal Server Error' },
|
|
74
|
-
NOT_IMPLEMENTED: { CODE: 501, TEXT: 'Not Implemented' },
|
|
75
|
-
BAD_GATEWAY: { CODE: 502, TEXT: 'Bad Gateway' },
|
|
76
|
-
SERVICE_UNAVAILABLE: { CODE: 503, TEXT: 'Service Unavailable' },
|
|
77
|
-
GATEWAY_TIMEOUT: { CODE: 504, TEXT: 'Gateway Timeout' },
|
|
78
|
-
HTTP_VERSION_NOT_SUPPORTED: { CODE: 505, TEXT: 'HTTP Version Not Supported' },
|
|
79
|
-
VARIANT_ALSO_NEGOTIATES: { CODE: 506, TEXT: 'Variant Also Negotiates' },
|
|
80
|
-
INSUFFICIENT_STORAGE: { CODE: 507, TEXT: 'Insufficient Storage' },
|
|
81
|
-
LOOP_DETECTED: { CODE: 508, TEXT: 'Loop Detected' },
|
|
82
|
-
NOT_EXTENDED: { CODE: 510, TEXT: 'Not Extended' },
|
|
83
|
-
NETWORK_AUTH_REQUIRED: { CODE: 511, TEXT: 'Network Authentication Required' },
|
|
84
|
-
};
|
|
85
|
-
// few hand picked direct code shortcuts
|
|
86
|
-
// 2xx
|
|
87
|
-
static OK = HTTP_STATUS.SUCCESS.OK.CODE;
|
|
88
|
-
static CREATED = HTTP_STATUS.SUCCESS.CREATED.CODE;
|
|
89
|
-
static ACCEPTED = HTTP_STATUS.SUCCESS.ACCEPTED.CODE;
|
|
90
|
-
static NO_CONTENT = HTTP_STATUS.SUCCESS.NO_CONTENT.CODE;
|
|
91
|
-
// 3xx
|
|
92
|
-
static MUTLIPLE_CHOICES = HTTP_STATUS.REDIRECT.MUTLIPLE_CHOICES.CODE;
|
|
93
|
-
static FOUND = HTTP_STATUS.REDIRECT.FOUND.CODE;
|
|
94
|
-
static NOT_MODIFIED = HTTP_STATUS.REDIRECT.NOT_MODIFIED.CODE;
|
|
95
|
-
static MOVED_PERMANENTLY = HTTP_STATUS.REDIRECT.MOVED_PERMANENTLY.CODE;
|
|
96
|
-
static TEMPORARY_REDIRECT = HTTP_STATUS.REDIRECT.TEMPORARY_REDIRECT.CODE;
|
|
97
|
-
static PERMANENT_REDIRECT = HTTP_STATUS.REDIRECT.PERMANENT_REDIRECT.CODE;
|
|
98
|
-
// 4xx
|
|
99
|
-
static BAD_REQUEST = HTTP_STATUS.ERROR_CLIENT.BAD_REQUEST.CODE;
|
|
100
|
-
static UNAUTHORIZED = HTTP_STATUS.ERROR_CLIENT.UNAUTHORIZED.CODE;
|
|
101
|
-
static FORBIDDEN = HTTP_STATUS.ERROR_CLIENT.FORBIDDEN.CODE;
|
|
102
|
-
static NOT_FOUND = HTTP_STATUS.ERROR_CLIENT.NOT_FOUND.CODE;
|
|
103
|
-
static METHOD_NOT_ALLOWED = HTTP_STATUS.ERROR_CLIENT.METHOD_NOT_ALLOWED.CODE;
|
|
104
|
-
static CONFLICT = HTTP_STATUS.ERROR_CLIENT.CONFLICT.CODE;
|
|
105
|
-
static GONE = HTTP_STATUS.ERROR_CLIENT.GONE.CODE;
|
|
106
|
-
static UNPROCESSABLE_CONTENT = HTTP_STATUS.ERROR_CLIENT.UNPROCESSABLE_CONTENT.CODE;
|
|
107
|
-
static TOO_MANY_REQUESTS = HTTP_STATUS.ERROR_CLIENT.TOO_MANY_REQUESTS.CODE;
|
|
108
|
-
// 5xx
|
|
109
|
-
static INTERNAL_SERVER_ERROR = HTTP_STATUS.ERROR_SERVER.INTERNAL_SERVER_ERROR.CODE;
|
|
110
|
-
static NOT_IMPLEMENTED = HTTP_STATUS.ERROR_SERVER.NOT_IMPLEMENTED.CODE;
|
|
111
|
-
static SERVICE_UNAVAILABLE = HTTP_STATUS.ERROR_SERVER.SERVICE_UNAVAILABLE.CODE;
|
|
112
|
-
//
|
|
113
|
-
static findByCode(code) {
|
|
114
|
-
const keys = [
|
|
115
|
-
'INFO', 'SUCCESS', 'REDIRECT', 'ERROR_CLIENT', 'ERROR_SERVER',
|
|
116
|
-
];
|
|
117
|
-
for (const _TYPE of keys) {
|
|
118
|
-
for (const [_KEY, data] of Object.entries(HTTP_STATUS[_TYPE])) {
|
|
119
|
-
if (data.CODE == code) {
|
|
120
|
-
return { ...data, _TYPE, _KEY };
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
return null;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// opinionated base for all
|
|
129
|
-
class HttpError extends Error {
|
|
130
|
-
name = 'HttpError';
|
|
131
|
-
// props simulating fetch Response
|
|
132
|
-
status = HTTP_STATUS.ERROR_SERVER.INTERNAL_SERVER_ERROR.CODE;
|
|
133
|
-
statusText = HTTP_STATUS.ERROR_SERVER.INTERNAL_SERVER_ERROR.TEXT;
|
|
134
|
-
body = null;
|
|
135
|
-
}
|
|
136
|
-
// some more specific instances of the well known ones...
|
|
137
|
-
// client
|
|
138
|
-
class BadRequest extends HttpError {
|
|
139
|
-
name = 'HttpBadRequestError';
|
|
140
|
-
status = HTTP_STATUS.ERROR_CLIENT.BAD_REQUEST.CODE;
|
|
141
|
-
statusText = HTTP_STATUS.ERROR_CLIENT.BAD_REQUEST.TEXT;
|
|
142
|
-
}
|
|
143
|
-
class Unauthorized extends HttpError {
|
|
144
|
-
name = 'HttpUnauthorizedError';
|
|
145
|
-
status = HTTP_STATUS.ERROR_CLIENT.UNAUTHORIZED.CODE;
|
|
146
|
-
statusText = HTTP_STATUS.ERROR_CLIENT.UNAUTHORIZED.TEXT;
|
|
147
|
-
}
|
|
148
|
-
class Forbidden extends HttpError {
|
|
149
|
-
name = 'HttpForbiddenError';
|
|
150
|
-
status = HTTP_STATUS.ERROR_CLIENT.FORBIDDEN.CODE;
|
|
151
|
-
statusText = HTTP_STATUS.ERROR_CLIENT.FORBIDDEN.TEXT;
|
|
152
|
-
}
|
|
153
|
-
class NotFound extends HttpError {
|
|
154
|
-
name = 'HttpNotFoundError';
|
|
155
|
-
status = HTTP_STATUS.ERROR_CLIENT.NOT_FOUND.CODE;
|
|
156
|
-
statusText = HTTP_STATUS.ERROR_CLIENT.NOT_FOUND.TEXT;
|
|
157
|
-
}
|
|
158
|
-
class MethodNotAllowed extends HttpError {
|
|
159
|
-
name = 'HttpMethodNotAllowedError';
|
|
160
|
-
status = HTTP_STATUS.ERROR_CLIENT.METHOD_NOT_ALLOWED.CODE;
|
|
161
|
-
statusText = HTTP_STATUS.ERROR_CLIENT.METHOD_NOT_ALLOWED.TEXT;
|
|
162
|
-
}
|
|
163
|
-
class RequestTimeout extends HttpError {
|
|
164
|
-
name = 'HttpRequestTimeoutError';
|
|
165
|
-
status = HTTP_STATUS.ERROR_CLIENT.REQUEST_TIMEOUT.CODE;
|
|
166
|
-
statusText = HTTP_STATUS.ERROR_CLIENT.REQUEST_TIMEOUT.TEXT;
|
|
167
|
-
}
|
|
168
|
-
class Conflict extends HttpError {
|
|
169
|
-
name = 'HttpConflictError';
|
|
170
|
-
status = HTTP_STATUS.ERROR_CLIENT.CONFLICT.CODE;
|
|
171
|
-
statusText = HTTP_STATUS.ERROR_CLIENT.CONFLICT.TEXT;
|
|
172
|
-
}
|
|
173
|
-
class Gone extends HttpError {
|
|
174
|
-
name = 'HttpGoneError';
|
|
175
|
-
status = HTTP_STATUS.ERROR_CLIENT.GONE.CODE;
|
|
176
|
-
statusText = HTTP_STATUS.ERROR_CLIENT.GONE.TEXT;
|
|
177
|
-
}
|
|
178
|
-
class LengthRequired extends HttpError {
|
|
179
|
-
name = 'HttpLengthRequiredError';
|
|
180
|
-
status = HTTP_STATUS.ERROR_CLIENT.LENGTH_REQUIRED.CODE;
|
|
181
|
-
statusText = HTTP_STATUS.ERROR_CLIENT.LENGTH_REQUIRED.TEXT;
|
|
182
|
-
}
|
|
183
|
-
class UnprocessableContent extends HttpError {
|
|
184
|
-
name = 'HttpUnprocessableContentError';
|
|
185
|
-
status = HTTP_STATUS.ERROR_CLIENT.UNPROCESSABLE_CONTENT.CODE;
|
|
186
|
-
statusText = HTTP_STATUS.ERROR_CLIENT.UNPROCESSABLE_CONTENT.TEXT;
|
|
187
|
-
}
|
|
188
|
-
class TooManyRequests extends HttpError {
|
|
189
|
-
name = 'HttpTooManyRequestsError';
|
|
190
|
-
status = HTTP_STATUS.ERROR_CLIENT.TOO_MANY_REQUESTS.CODE;
|
|
191
|
-
statusText = HTTP_STATUS.ERROR_CLIENT.TOO_MANY_REQUESTS.TEXT;
|
|
192
|
-
}
|
|
193
|
-
class ImATeapot extends HttpError {
|
|
194
|
-
name = 'HttpImATeapotError';
|
|
195
|
-
status = HTTP_STATUS.ERROR_CLIENT.IM_A_TEAPOT.CODE;
|
|
196
|
-
statusText = HTTP_STATUS.ERROR_CLIENT.IM_A_TEAPOT.TEXT;
|
|
197
|
-
}
|
|
198
|
-
// server
|
|
199
|
-
class InternalServerError extends HttpError {
|
|
200
|
-
name = 'HttpInternalServerError';
|
|
201
|
-
}
|
|
202
|
-
class NotImplemented extends HttpError {
|
|
203
|
-
name = 'HttpServiceUnavailableError';
|
|
204
|
-
status = HTTP_STATUS.ERROR_SERVER.NOT_IMPLEMENTED.CODE;
|
|
205
|
-
statusText = HTTP_STATUS.ERROR_SERVER.NOT_IMPLEMENTED.TEXT;
|
|
206
|
-
}
|
|
207
|
-
class BadGateway extends HttpError {
|
|
208
|
-
name = 'HttpBadGatewayError';
|
|
209
|
-
status = HTTP_STATUS.ERROR_SERVER.BAD_GATEWAY.CODE;
|
|
210
|
-
statusText = HTTP_STATUS.ERROR_SERVER.BAD_GATEWAY.TEXT;
|
|
211
|
-
}
|
|
212
|
-
class ServiceUnavailable extends HttpError {
|
|
213
|
-
name = 'HttpServiceUnavailableError';
|
|
214
|
-
status = HTTP_STATUS.ERROR_SERVER.SERVICE_UNAVAILABLE.CODE;
|
|
215
|
-
statusText = HTTP_STATUS.ERROR_SERVER.SERVICE_UNAVAILABLE.TEXT;
|
|
216
|
-
}
|
|
217
|
-
//
|
|
218
|
-
const HTTP_ERROR = {
|
|
219
|
-
// base
|
|
220
|
-
HttpError,
|
|
221
|
-
// client
|
|
222
|
-
BadRequest,
|
|
223
|
-
Unauthorized,
|
|
224
|
-
Forbidden,
|
|
225
|
-
NotFound,
|
|
226
|
-
MethodNotAllowed,
|
|
227
|
-
RequestTimeout,
|
|
228
|
-
Conflict,
|
|
229
|
-
Gone,
|
|
230
|
-
LengthRequired,
|
|
231
|
-
ImATeapot,
|
|
232
|
-
UnprocessableContent,
|
|
233
|
-
TooManyRequests,
|
|
234
|
-
// server
|
|
235
|
-
InternalServerError,
|
|
236
|
-
NotImplemented,
|
|
237
|
-
BadGateway,
|
|
238
|
-
ServiceUnavailable,
|
|
239
|
-
};
|
|
240
|
-
const _wellKnownCtorMap = {
|
|
241
|
-
'400': BadRequest,
|
|
242
|
-
'401': Unauthorized,
|
|
243
|
-
'403': Forbidden,
|
|
244
|
-
'404': NotFound,
|
|
245
|
-
'405': MethodNotAllowed,
|
|
246
|
-
'408': RequestTimeout,
|
|
247
|
-
'409': Conflict,
|
|
248
|
-
'410': Gone,
|
|
249
|
-
'411': LengthRequired,
|
|
250
|
-
'418': ImATeapot,
|
|
251
|
-
'422': UnprocessableContent,
|
|
252
|
-
'429': TooManyRequests,
|
|
253
|
-
//
|
|
254
|
-
'500': InternalServerError,
|
|
255
|
-
'501': NotImplemented,
|
|
256
|
-
'502': BadGateway,
|
|
257
|
-
'503': ServiceUnavailable,
|
|
258
|
-
};
|
|
259
|
-
const _maybeJsonParse = (v) => {
|
|
260
|
-
if (typeof v === 'string') {
|
|
261
|
-
try {
|
|
262
|
-
v = JSON.parse(v);
|
|
263
|
-
}
|
|
264
|
-
catch (e) { }
|
|
265
|
-
}
|
|
266
|
-
return v;
|
|
267
|
-
};
|
|
268
|
-
const createHttpError = (code, message,
|
|
269
|
-
// arbitrary content, typically http response body which threw this error
|
|
270
|
-
// (will be JSON.parse-d if the content is a valid json string)
|
|
271
|
-
body,
|
|
272
|
-
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause
|
|
273
|
-
// arbitrary details, typically response text (will be JSON.parse-d if the content is a valid json string)
|
|
274
|
-
cause) => {
|
|
275
|
-
const fallback = HTTP_STATUS.ERROR_SERVER.INTERNAL_SERVER_ERROR;
|
|
276
|
-
code = Number(code);
|
|
277
|
-
if (isNaN(code) || !(code >= 400 && code < 600))
|
|
278
|
-
code = fallback.CODE;
|
|
279
|
-
// opinionated conventions
|
|
280
|
-
body = _maybeJsonParse(body);
|
|
281
|
-
cause = _maybeJsonParse(cause);
|
|
282
|
-
// try to find the well known one, otherwise fallback to generic
|
|
283
|
-
const ctor = _wellKnownCtorMap[`${code}`] ?? HttpError;
|
|
284
|
-
//
|
|
285
|
-
const found = HTTP_STATUS.findByCode(code);
|
|
286
|
-
const statusText = found?.TEXT ?? fallback.TEXT;
|
|
287
|
-
//
|
|
288
|
-
let e = new ctor(message || statusText, { cause });
|
|
289
|
-
e.status = found?.CODE ?? fallback.CODE;
|
|
290
|
-
e.statusText = statusText;
|
|
291
|
-
e.body = body;
|
|
292
|
-
return e;
|
|
293
|
-
};
|
|
294
|
-
const getErrorMessage = (e, stripErrorPrefix = true) => {
|
|
295
|
-
if (!e)
|
|
296
|
-
return '';
|
|
297
|
-
// PROBLEM is that error may bubble from various sources which are not always under control
|
|
298
|
-
// and even if they were it still may not be trivial to keep similar structure on each error boundary...
|
|
299
|
-
// So, we'll just do what we can, it will not be perfect, but should handle most cases most of the time.
|
|
300
|
-
// Also, I'm relying on some of my own opinionated conventions as well...
|
|
301
|
-
const cause = _maybeJsonParse(e?.cause);
|
|
302
|
-
const body = _maybeJsonParse(e?.body);
|
|
303
|
-
let msg =
|
|
304
|
-
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause
|
|
305
|
-
// e.cause is the standard prop for error details, so should be considered as
|
|
306
|
-
// the most authoritative (if available)
|
|
307
|
-
// "code" and "message" are my own conventions
|
|
308
|
-
cause?.message ||
|
|
309
|
-
cause?.code ||
|
|
310
|
-
(typeof cause === 'string' ? cause : null) ||
|
|
311
|
-
// non-standard "body" is this package's HttpError prop
|
|
312
|
-
body?.error?.message ||
|
|
313
|
-
body?.message ||
|
|
314
|
-
body?.error ||
|
|
315
|
-
(typeof body === 'string' ? body : null) ||
|
|
316
|
-
// the common message from Error ctor (e.g. "Foo" if new TypeError("Foo"))
|
|
317
|
-
e?.message ||
|
|
318
|
-
// the Error class name (e.g. TypeError)
|
|
319
|
-
e?.name ||
|
|
320
|
-
// this should handle (almost) everything else (mainly if e is not an Error instance)
|
|
321
|
-
e?.toString() ||
|
|
322
|
-
// very last fallback if `toString()` was not available (or returned empty)
|
|
323
|
-
'Unknown Error';
|
|
324
|
-
// ensure we're sending string
|
|
325
|
-
msg = `${msg}`;
|
|
326
|
-
if (stripErrorPrefix) {
|
|
327
|
-
msg = msg.replace(/^[^:]*Error: /i, '');
|
|
328
|
-
}
|
|
329
|
-
return msg;
|
|
330
|
-
};
|
|
331
|
-
|
|
332
|
-
const _fetchRaw = async ({ method, path, data = null, token = null, headers = null, signal = null, credentials, }) => {
|
|
333
|
-
headers = Object.entries(headers || {}).reduce((m, [k, v]) => ({ ...m, [k.toLowerCase()]: v }), {});
|
|
334
|
-
const opts = { method, credentials, headers, signal };
|
|
335
|
-
if (data) {
|
|
336
|
-
const isObj = typeof data === 'object';
|
|
337
|
-
// multipart/form-data -- no explicit Content-Type
|
|
338
|
-
if (data instanceof FormData) {
|
|
339
|
-
opts.body = data;
|
|
340
|
-
}
|
|
341
|
-
// cover 99% use cases (may not fit all)
|
|
342
|
-
else {
|
|
343
|
-
// if not stated, assuming json
|
|
344
|
-
if (isObj || !headers['content-type']) {
|
|
345
|
-
opts.headers['content-type'] = 'application/json';
|
|
346
|
-
}
|
|
347
|
-
opts.body = JSON.stringify(data);
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
// opinionated convention
|
|
351
|
-
if (token) {
|
|
352
|
-
opts.headers['authorization'] = `Bearer ${token}`;
|
|
353
|
-
}
|
|
354
|
-
return await fetch(path, opts);
|
|
355
|
-
};
|
|
356
|
-
const _fetch = async (params, respHeaders = null, errorMessageExtractor = null, _dumpParams = false) => {
|
|
357
|
-
if (_dumpParams)
|
|
358
|
-
return params;
|
|
359
|
-
const r = await _fetchRaw(params);
|
|
360
|
-
if (params.raw)
|
|
361
|
-
return r;
|
|
362
|
-
//
|
|
363
|
-
const headers = [...r.headers.entries()].reduce((m, [k, v]) => ({ ...m, [k]: v }), {});
|
|
364
|
-
// quick-n-dirty reference to headers (so it's still accessible over this api wrap)
|
|
365
|
-
if (respHeaders) {
|
|
366
|
-
Object.assign(respHeaders, { ...headers },
|
|
367
|
-
// adding status/text under special keys
|
|
368
|
-
{ __http_status_code__: r.status, __http_status_text__: r.statusText });
|
|
369
|
-
}
|
|
370
|
-
let body = await r.text();
|
|
371
|
-
// prettier-ignore
|
|
372
|
-
try {
|
|
373
|
-
body = JSON.parse(body);
|
|
374
|
-
}
|
|
375
|
-
catch (e) { }
|
|
376
|
-
params.assert ??= true; // default is true
|
|
377
|
-
if (!r.ok && params.assert) {
|
|
378
|
-
// now we need to extract error message from an unknown response... this is obviously
|
|
379
|
-
// impossible unless we know what to expect, but we'll do some educated tries...
|
|
380
|
-
const extractor = errorMessageExtractor ?? // provided arg
|
|
381
|
-
createHttpApi.defaultErrorMessageExtractor ?? // static default
|
|
382
|
-
// educated guess fallback
|
|
383
|
-
function (_body, _response) {
|
|
384
|
-
let msg =
|
|
385
|
-
// try opinionated convention first
|
|
386
|
-
_body?.error?.message ||
|
|
387
|
-
_body?.message ||
|
|
388
|
-
_body?.error ||
|
|
389
|
-
_response?.statusText ||
|
|
390
|
-
'Unknown error';
|
|
391
|
-
if (msg.length > 255)
|
|
392
|
-
msg = `[Shortened]: ${msg.slice(0, 255)}`;
|
|
393
|
-
return msg;
|
|
394
|
-
};
|
|
395
|
-
// adding `cause` describing more details
|
|
396
|
-
throw createHttpError(r.status, extractor(body, r), body, {
|
|
397
|
-
method: params.method,
|
|
398
|
-
path: params.path,
|
|
399
|
-
response: {
|
|
400
|
-
status: r.status,
|
|
401
|
-
statusText: r.statusText,
|
|
402
|
-
headers,
|
|
403
|
-
},
|
|
404
|
-
});
|
|
405
|
-
}
|
|
406
|
-
return body;
|
|
407
|
-
};
|
|
408
|
-
function createHttpApi(base, defaults, factoryErrorMessageExtractor) {
|
|
409
|
-
const _merge = (a, b) => {
|
|
410
|
-
const wrap = { result: a };
|
|
411
|
-
merge.dset(wrap, 'result', b);
|
|
412
|
-
return wrap.result;
|
|
413
|
-
};
|
|
414
|
-
const _getDefs = async () => new Promise(async (resolve) => {
|
|
415
|
-
if (typeof defaults === 'function') {
|
|
416
|
-
resolve({ ...(await defaults()) });
|
|
417
|
-
}
|
|
418
|
-
else {
|
|
419
|
-
resolve({ ...(defaults || {}) });
|
|
420
|
-
}
|
|
421
|
-
});
|
|
422
|
-
const _buildPath = (path, base) => {
|
|
423
|
-
base = `${base || ''}`;
|
|
424
|
-
path = `${path || ''}`;
|
|
425
|
-
return /^https?:/.test(path) ? path : base + path;
|
|
426
|
-
};
|
|
427
|
-
return {
|
|
428
|
-
// GET
|
|
429
|
-
async get(path, params, respHeaders = null, errorMessageExtractor = null, _dumpParams = false) {
|
|
430
|
-
path = _buildPath(path, base);
|
|
431
|
-
return _fetch(_merge(await _getDefs(), { ...params, method: 'GET', path }), respHeaders, errorMessageExtractor ?? factoryErrorMessageExtractor, _dumpParams);
|
|
432
|
-
},
|
|
433
|
-
// POST
|
|
434
|
-
async post(path, data = null, params, respHeaders = null, errorMessageExtractor = null, _dumpParams = false) {
|
|
435
|
-
path = _buildPath(path, base);
|
|
436
|
-
return _fetch(_merge(await _getDefs(), { ...(params || {}), data, method: 'POST', path }), respHeaders, errorMessageExtractor ?? factoryErrorMessageExtractor, _dumpParams);
|
|
437
|
-
},
|
|
438
|
-
// PUT
|
|
439
|
-
async put(path, data = null, params, respHeaders = null, errorMessageExtractor = null, _dumpParams = false) {
|
|
440
|
-
path = _buildPath(path, base);
|
|
441
|
-
return _fetch(_merge(await _getDefs(), { ...(params || {}), data, method: 'PUT', path }), respHeaders, errorMessageExtractor ?? factoryErrorMessageExtractor, _dumpParams);
|
|
442
|
-
},
|
|
443
|
-
// PATCH
|
|
444
|
-
async patch(path, data = null, params, respHeaders = null, errorMessageExtractor = null, _dumpParams = false) {
|
|
445
|
-
path = _buildPath(path, base);
|
|
446
|
-
return _fetch(_merge(await _getDefs(), { ...(params || {}), data, method: 'PATCH', path }), respHeaders, errorMessageExtractor ?? factoryErrorMessageExtractor, _dumpParams);
|
|
447
|
-
},
|
|
448
|
-
// DELETE
|
|
449
|
-
// https://stackoverflow.com/questions/299628/is-an-entity-body-allowed-for-an-http-delete-request
|
|
450
|
-
async del(path, data = null, params, respHeaders = null, errorMessageExtractor = null, _dumpParams = false) {
|
|
451
|
-
path = _buildPath(path, base);
|
|
452
|
-
return _fetch(_merge(await _getDefs(), { ...(params || {}), data, method: 'DELETE', path }), respHeaders, errorMessageExtractor ?? factoryErrorMessageExtractor, _dumpParams);
|
|
453
|
-
},
|
|
454
|
-
// helper method to return api's resolved url
|
|
455
|
-
// note: cannot use URL(...) as relative would be invalid
|
|
456
|
-
url: (path) => _buildPath(path, base),
|
|
457
|
-
//
|
|
458
|
-
get base() {
|
|
459
|
-
return base;
|
|
460
|
-
},
|
|
461
|
-
set base(v) {
|
|
462
|
-
base = v;
|
|
463
|
-
},
|
|
464
|
-
};
|
|
465
|
-
}
|
|
466
|
-
createHttpApi.defaultErrorMessageExtractor = null;
|
|
467
|
-
|
|
468
|
-
exports.HTTP_ERROR = HTTP_ERROR;
|
|
469
|
-
exports.HTTP_STATUS = HTTP_STATUS;
|
|
470
|
-
exports.createHttpApi = createHttpApi;
|
|
471
|
-
exports.createHttpError = createHttpError;
|
|
472
|
-
exports.getErrorMessage = getErrorMessage;
|
package/dist/index.d.ts
DELETED