@opra/common 0.22.0 → 0.23.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.
- package/browser.js +957 -1566
- package/cjs/document/api-document.js +7 -3
- package/cjs/document/data-type/api-field.js +2 -2
- package/cjs/document/data-type/complex-type.js +17 -63
- package/cjs/document/data-type/data-type.js +0 -9
- package/cjs/document/data-type/enum-type.js +2 -8
- package/cjs/document/data-type/mapped-type.js +0 -36
- package/cjs/document/data-type/simple-type.js +2 -8
- package/cjs/document/data-type/union-type.js +1 -37
- package/cjs/document/index.js +2 -0
- package/cjs/document/resource/collection.js +75 -32
- package/cjs/document/resource/singleton.js +31 -20
- package/cjs/document/resource/storage.js +6 -20
- package/cjs/document/utils/generate-codec.js +39 -0
- package/cjs/exception/http-errors/bad-request.error.js +2 -3
- package/cjs/exception/http-errors/failed-dependency.error.js +2 -3
- package/cjs/exception/http-errors/forbidden.error.js +2 -3
- package/cjs/exception/http-errors/internal-server.error.js +2 -3
- package/cjs/exception/http-errors/method-not-allowed.error.js +2 -3
- package/cjs/exception/http-errors/not-acceptable.error.js +2 -3
- package/cjs/exception/http-errors/not-found.error.js +2 -3
- package/cjs/exception/http-errors/unauthorized.error.js +2 -3
- package/cjs/exception/http-errors/unprocessable-entity.error.js +2 -2
- package/cjs/exception/opra-exception.js +48 -33
- package/cjs/exception/resource-errors/resource-not-found.error.js +2 -3
- package/cjs/exception/wrap-exception.js +16 -16
- package/cjs/helpers/index.js +1 -1
- package/cjs/helpers/is-url-string.js +14 -0
- package/cjs/helpers/object-utils.js +2 -2
- package/cjs/helpers/responsive-map.js +4 -4
- package/cjs/helpers/type-guards.js +15 -3
- package/cjs/http/index.js +2 -9
- package/cjs/http/opra-url-path.js +251 -0
- package/cjs/{url → http}/opra-url.js +53 -109
- package/cjs/i18n/i18n.js +1 -1
- package/cjs/index.js +0 -2
- package/cjs/schema/opra-schema.ns.js +1 -1
- package/cjs/schema/resource/operation.interface.js +2 -0
- package/esm/document/api-document.js +9 -5
- package/esm/document/data-type/api-field.js +2 -2
- package/esm/document/data-type/complex-type.js +13 -59
- package/esm/document/data-type/data-type.js +0 -9
- package/esm/document/data-type/enum-type.js +2 -8
- package/esm/document/data-type/mapped-type.js +0 -36
- package/esm/document/data-type/simple-type.js +2 -8
- package/esm/document/data-type/union-type.js +1 -37
- package/esm/document/index.js +2 -0
- package/esm/document/resource/collection.js +75 -32
- package/esm/document/resource/singleton.js +31 -20
- package/esm/document/resource/storage.js +6 -20
- package/esm/document/utils/generate-codec.js +33 -0
- package/esm/exception/http-errors/bad-request.error.js +2 -3
- package/esm/exception/http-errors/failed-dependency.error.js +2 -3
- package/esm/exception/http-errors/forbidden.error.js +2 -3
- package/esm/exception/http-errors/internal-server.error.js +2 -3
- package/esm/exception/http-errors/method-not-allowed.error.js +2 -3
- package/esm/exception/http-errors/not-acceptable.error.js +2 -3
- package/esm/exception/http-errors/not-found.error.js +2 -3
- package/esm/exception/http-errors/unauthorized.error.js +2 -3
- package/esm/exception/http-errors/unprocessable-entity.error.js +2 -2
- package/esm/exception/opra-exception.js +47 -32
- package/esm/exception/resource-errors/resource-not-found.error.js +2 -3
- package/esm/exception/wrap-exception.js +16 -16
- package/esm/helpers/index.js +1 -1
- package/esm/helpers/is-url-string.js +9 -0
- package/esm/helpers/object-utils.js +2 -2
- package/esm/helpers/responsive-map.js +4 -4
- package/esm/helpers/type-guards.js +11 -2
- package/esm/http/index.js +2 -9
- package/esm/http/opra-url-path.js +246 -0
- package/esm/{url → http}/opra-url.js +53 -109
- package/esm/i18n/i18n.js +2 -2
- package/esm/index.js +0 -2
- package/esm/schema/opra-schema.ns.js +1 -1
- package/esm/schema/resource/operation.interface.js +1 -0
- package/package.json +5 -5
- package/types/document/api-document.d.ts +4 -1
- package/types/document/data-type/complex-type.d.ts +7 -12
- package/types/document/data-type/data-type.d.ts +0 -6
- package/types/document/data-type/enum-type.d.ts +2 -4
- package/types/document/data-type/mapped-type.d.ts +1 -5
- package/types/document/data-type/simple-type.d.ts +2 -4
- package/types/document/data-type/union-type.d.ts +1 -5
- package/types/document/index.d.ts +2 -0
- package/types/document/interfaces/collection-resource.interface.d.ts +10 -0
- package/types/document/interfaces/singleton-resource.interface.d.ts +7 -0
- package/types/document/interfaces/storage-resource.interface.d.ts +8 -0
- package/types/document/resource/collection.d.ts +41 -35
- package/types/document/resource/resource.d.ts +1 -0
- package/types/document/resource/singleton.d.ts +24 -21
- package/types/document/resource/storage.d.ts +14 -17
- package/types/document/utils/generate-codec.d.ts +10 -0
- package/types/exception/error-issue.d.ts +2 -1
- package/types/exception/http-errors/bad-request.error.d.ts +2 -1
- package/types/exception/http-errors/failed-dependency.error.d.ts +2 -1
- package/types/exception/http-errors/forbidden.error.d.ts +2 -1
- package/types/exception/http-errors/internal-server.error.d.ts +2 -1
- package/types/exception/http-errors/method-not-allowed.error.d.ts +2 -1
- package/types/exception/http-errors/not-acceptable.error.d.ts +2 -1
- package/types/exception/http-errors/not-found.error.d.ts +2 -1
- package/types/exception/http-errors/unauthorized.error.d.ts +2 -1
- package/types/exception/http-errors/unprocessable-entity.error.d.ts +2 -1
- package/types/exception/opra-exception.d.ts +13 -8
- package/types/exception/wrap-exception.d.ts +1 -1
- package/types/helpers/index.d.ts +1 -1
- package/types/helpers/is-url-string.d.ts +2 -0
- package/types/helpers/object-utils.d.ts +1 -1
- package/types/helpers/type-guards.d.ts +3 -0
- package/types/http/index.d.ts +2 -9
- package/types/http/opra-url-path.d.ts +54 -0
- package/types/{url → http}/opra-url.d.ts +9 -13
- package/types/index.d.ts +0 -2
- package/types/schema/data-type/complex-type.interface.d.ts +1 -1
- package/types/schema/opra-schema.ns.d.ts +1 -1
- package/types/schema/resource/collection.interface.d.ts +29 -8
- package/types/schema/resource/operation.interface.d.ts +3 -0
- package/types/schema/resource/singleton.interface.d.ts +5 -5
- package/types/schema/resource/storage.interface.d.ts +42 -5
- package/cjs/helpers/is-url.js +0 -8
- package/cjs/http/codecs/boolean-codec.js +0 -24
- package/cjs/http/codecs/date-codec.js +0 -41
- package/cjs/http/codecs/filter-codec.js +0 -17
- package/cjs/http/codecs/integer-codec.js +0 -19
- package/cjs/http/codecs/number-codec.js +0 -24
- package/cjs/http/codecs/string-codec.js +0 -23
- package/cjs/http/http-params.js +0 -353
- package/cjs/http/multipart/batch-multipart.js +0 -170
- package/cjs/http/multipart/http-request-content.js +0 -17
- package/cjs/http/multipart/http-response-content.js +0 -14
- package/cjs/http/multipart/index.js +0 -2
- package/cjs/url/index.js +0 -8
- package/cjs/url/opra-url-path-component.js +0 -30
- package/cjs/url/opra-url-path.js +0 -155
- package/cjs/url/utils/decode-path-component.js +0 -41
- package/cjs/url/utils/encode-path-component.js +0 -27
- package/cjs/utils/path-utils.js +0 -24
- package/esm/helpers/is-url.js +0 -4
- package/esm/http/codecs/boolean-codec.js +0 -20
- package/esm/http/codecs/date-codec.js +0 -37
- package/esm/http/codecs/filter-codec.js +0 -13
- package/esm/http/codecs/integer-codec.js +0 -15
- package/esm/http/codecs/number-codec.js +0 -20
- package/esm/http/codecs/string-codec.js +0 -19
- package/esm/http/http-params.js +0 -348
- package/esm/http/multipart/batch-multipart.js +0 -170
- package/esm/http/multipart/http-request-content.js +0 -17
- package/esm/http/multipart/http-response-content.js +0 -14
- package/esm/http/multipart/index.js +0 -2
- package/esm/url/index.js +0 -5
- package/esm/url/opra-url-path-component.js +0 -26
- package/esm/url/opra-url-path.js +0 -151
- package/esm/url/utils/decode-path-component.js +0 -37
- package/esm/url/utils/encode-path-component.js +0 -22
- package/esm/utils/path-utils.js +0 -19
- package/types/helpers/is-url.d.ts +0 -1
- package/types/http/codecs/boolean-codec.d.ts +0 -5
- package/types/http/codecs/date-codec.d.ts +0 -16
- package/types/http/codecs/filter-codec.d.ts +0 -6
- package/types/http/codecs/integer-codec.d.ts +0 -11
- package/types/http/codecs/number-codec.d.ts +0 -14
- package/types/http/codecs/string-codec.d.ts +0 -16
- package/types/http/http-params.d.ts +0 -114
- package/types/http/interfaces/client-http-headers.interface.d.ts +0 -65
- package/types/http/interfaces/server-http-headers.interface.d.ts +0 -1
- package/types/http/multipart/batch-multipart.d.ts +0 -0
- package/types/http/multipart/http-request-content.d.ts +0 -0
- package/types/http/multipart/http-response-content.d.ts +0 -0
- package/types/http/multipart/index.d.ts +0 -0
- package/types/schema/resource/endpoint.interface.d.ts +0 -29
- package/types/url/index.d.ts +0 -5
- package/types/url/opra-url-path-component.d.ts +0 -15
- package/types/url/opra-url-path.d.ts +0 -36
- package/types/url/utils/decode-path-component.d.ts +0 -5
- package/types/url/utils/encode-path-component.d.ts +0 -1
- package/types/utils/path-utils.d.ts +0 -2
- /package/cjs/{http/interfaces/client-http-headers.interface.js → document/interfaces/collection-resource.interface.js} +0 -0
- /package/cjs/{http/interfaces/server-http-headers.interface.js → document/interfaces/singleton-resource.interface.js} +0 -0
- /package/cjs/{schema/resource/endpoint.interface.js → document/interfaces/storage-resource.interface.js} +0 -0
- /package/esm/{http/interfaces/client-http-headers.interface.js → document/interfaces/collection-resource.interface.js} +0 -0
- /package/esm/{http/interfaces/server-http-headers.interface.js → document/interfaces/singleton-resource.interface.js} +0 -0
- /package/esm/{schema/resource/endpoint.interface.js → document/interfaces/storage-resource.interface.js} +0 -0
|
@@ -11,10 +11,9 @@ export class ForbiddenError extends OpraException {
|
|
|
11
11
|
super(...arguments);
|
|
12
12
|
this.status = 403;
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
super.
|
|
14
|
+
init(issue) {
|
|
15
|
+
super.init({
|
|
16
16
|
message: translate('error:FORBIDDEN', 'You are not authorized to perform this action'),
|
|
17
|
-
severity: 'error',
|
|
18
17
|
code: 'FORBIDDEN',
|
|
19
18
|
...issue
|
|
20
19
|
});
|
|
@@ -9,10 +9,9 @@ export class InternalServerError extends OpraException {
|
|
|
9
9
|
super(...arguments);
|
|
10
10
|
this.status = 500;
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
super.
|
|
12
|
+
init(issue) {
|
|
13
|
+
super.init({
|
|
14
14
|
message: translate('error:INTERNAL_SERVER_ERROR', 'Internal server error'),
|
|
15
|
-
severity: 'error',
|
|
16
15
|
code: 'INTERNAL_SERVER_ERROR',
|
|
17
16
|
...issue
|
|
18
17
|
});
|
|
@@ -10,10 +10,9 @@ export class MethodNotAllowedError extends OpraException {
|
|
|
10
10
|
super(...arguments);
|
|
11
11
|
this.status = 405;
|
|
12
12
|
}
|
|
13
|
-
|
|
14
|
-
super.
|
|
13
|
+
init(issue) {
|
|
14
|
+
super.init({
|
|
15
15
|
message: translate('error:METHOD_NOT_ALLOWED', 'Method not allowed'),
|
|
16
|
-
severity: 'error',
|
|
17
16
|
code: 'METHOD_NOT_ALLOWED',
|
|
18
17
|
...issue
|
|
19
18
|
});
|
|
@@ -10,10 +10,9 @@ export class NotAcceptableError extends OpraException {
|
|
|
10
10
|
super(...arguments);
|
|
11
11
|
this.status = 406;
|
|
12
12
|
}
|
|
13
|
-
|
|
14
|
-
super.
|
|
13
|
+
init(issue) {
|
|
14
|
+
super.init({
|
|
15
15
|
message: translate('error:NOT_ACCEPTABLE', 'Not Acceptable'),
|
|
16
|
-
severity: 'error',
|
|
17
16
|
code: 'NOT_ACCEPTABLE',
|
|
18
17
|
...issue
|
|
19
18
|
});
|
|
@@ -13,10 +13,9 @@ export class NotFoundError extends OpraException {
|
|
|
13
13
|
super(...arguments);
|
|
14
14
|
this.status = 404;
|
|
15
15
|
}
|
|
16
|
-
|
|
17
|
-
super.
|
|
16
|
+
init(issue) {
|
|
17
|
+
super.init({
|
|
18
18
|
message: translate('error:NOT_FOUND', 'Not found'),
|
|
19
|
-
severity: 'error',
|
|
20
19
|
code: 'NOT_FOUND',
|
|
21
20
|
...issue
|
|
22
21
|
});
|
|
@@ -10,10 +10,9 @@ export class UnauthorizedError extends OpraException {
|
|
|
10
10
|
super(...arguments);
|
|
11
11
|
this.status = 401;
|
|
12
12
|
}
|
|
13
|
-
|
|
14
|
-
super.
|
|
13
|
+
init(issue) {
|
|
14
|
+
super.init({
|
|
15
15
|
message: translate('error:UNAUTHORIZED', 'You have not been authenticated to perform this action'),
|
|
16
|
-
severity: 'error',
|
|
17
16
|
code: 'UNAUTHORIZED',
|
|
18
17
|
...issue
|
|
19
18
|
});
|
|
@@ -9,8 +9,8 @@ export class UnprocessableEntityError extends OpraException {
|
|
|
9
9
|
super(...arguments);
|
|
10
10
|
this.status = 422;
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
super.
|
|
12
|
+
init(issue) {
|
|
13
|
+
super.init({
|
|
14
14
|
message: translate('error:UNPROCESSABLE_ENTITY', 'Unprocessable entity'),
|
|
15
15
|
severity: 'error',
|
|
16
16
|
code: 'UNPROCESSABLE_ENTITY',
|
|
@@ -1,52 +1,67 @@
|
|
|
1
|
+
import { omitUndefined } from '../helpers/index.js';
|
|
1
2
|
import { i18n } from '../i18n/index.js';
|
|
3
|
+
const inDevelopment = (process.env.NODE_ENV || '').startsWith('dev');
|
|
2
4
|
/**
|
|
3
5
|
* Defines the base Opra exception, which is handled by the default Exceptions Handler.
|
|
4
6
|
*/
|
|
5
7
|
export class OpraException extends Error {
|
|
6
|
-
constructor(issue,
|
|
7
|
-
super('');
|
|
8
|
+
constructor(issue, arg1, arg2) {
|
|
9
|
+
super('Unknown error');
|
|
8
10
|
this.status = 500;
|
|
9
|
-
|
|
11
|
+
let cause = arg1 && arg1 instanceof Error ? arg1 : undefined;
|
|
12
|
+
this.status = (typeof arg1 === 'number' ? arg1 : Number(arg2)) || 500;
|
|
10
13
|
if (issue instanceof Error)
|
|
11
14
|
cause = issue;
|
|
12
|
-
|
|
15
|
+
// noinspection SuspiciousTypeOfGuard
|
|
16
|
+
if (cause && cause instanceof Error) {
|
|
13
17
|
this.cause = cause;
|
|
14
18
|
if (cause.stack)
|
|
15
19
|
this.stack = cause.stack;
|
|
16
20
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
this._issue = {
|
|
25
|
-
message: 'Unknown error',
|
|
26
|
-
severity: 'error',
|
|
27
|
-
...issue,
|
|
28
|
-
};
|
|
21
|
+
if (typeof issue === 'string')
|
|
22
|
+
this.initString(issue);
|
|
23
|
+
else if (issue instanceof Error)
|
|
24
|
+
this.initError(issue);
|
|
25
|
+
else if (issue && typeof issue === 'object')
|
|
26
|
+
this.init(issue);
|
|
27
|
+
this.message = this.message || this.constructor.name;
|
|
29
28
|
}
|
|
30
29
|
setStatus(status) {
|
|
31
30
|
this.status = status;
|
|
32
31
|
return this;
|
|
33
32
|
}
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
toString() {
|
|
34
|
+
return i18n.deep(this.message);
|
|
36
35
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
36
|
+
toJSON() {
|
|
37
|
+
return omitUndefined({
|
|
38
|
+
message: this.message,
|
|
39
|
+
severity: this.severity,
|
|
40
|
+
system: this.system,
|
|
41
|
+
code: this.code,
|
|
42
|
+
details: this.details,
|
|
43
|
+
stack: inDevelopment ? this.stack?.split('\n') : undefined
|
|
44
|
+
}, true);
|
|
45
|
+
}
|
|
46
|
+
init(issue) {
|
|
47
|
+
this.message = issue.message || this.constructor.name;
|
|
48
|
+
this.severity = issue.severity || 'error';
|
|
49
|
+
this.system = issue.system;
|
|
50
|
+
this.code = issue.code;
|
|
51
|
+
this.details = issue.details;
|
|
52
|
+
}
|
|
53
|
+
initString(issue) {
|
|
54
|
+
this.message = String(issue || '') || this.constructor.name;
|
|
55
|
+
this.severity = 'error';
|
|
56
|
+
this.code = this.constructor.name;
|
|
57
|
+
}
|
|
58
|
+
initError(issue) {
|
|
59
|
+
if (typeof issue.status === 'number')
|
|
60
|
+
this.status = issue.status;
|
|
61
|
+
else if (typeof issue.getStatus === 'function')
|
|
62
|
+
this.status = issue.getStatus();
|
|
63
|
+
this.message = issue.message;
|
|
64
|
+
this.severity = issue.severity || 'error';
|
|
65
|
+
this.code = issue.code || (issue.constructor.name);
|
|
51
66
|
}
|
|
52
67
|
}
|
|
@@ -7,14 +7,13 @@ import { OpraException } from '../opra-exception.js';
|
|
|
7
7
|
export class ResourceNotFoundError extends OpraException {
|
|
8
8
|
constructor(resource, keyValue, cause) {
|
|
9
9
|
super({
|
|
10
|
-
message: translate(`error:RESOURCE_NOT_FOUND`, { resource: resource + (keyValue ? '@' + keyValue : '') }, `The resource '{{resource}}'
|
|
10
|
+
message: translate(`error:RESOURCE_NOT_FOUND`, { resource: resource + (keyValue ? '@' + keyValue : '') }, `The resource '{{resource}}' not found`),
|
|
11
11
|
severity: 'error',
|
|
12
12
|
code: 'RESOURCE_NOT_FOUND',
|
|
13
13
|
details: {
|
|
14
14
|
resource,
|
|
15
15
|
key: keyValue
|
|
16
16
|
}
|
|
17
|
-
}, cause);
|
|
18
|
-
this.status = 404;
|
|
17
|
+
}, cause, 404);
|
|
19
18
|
}
|
|
20
19
|
}
|
|
@@ -7,32 +7,32 @@ import { NotFoundError } from './http-errors/not-found.error.js';
|
|
|
7
7
|
import { UnauthorizedError } from './http-errors/unauthorized.error.js';
|
|
8
8
|
import { UnprocessableEntityError } from './http-errors/unprocessable-entity.error.js';
|
|
9
9
|
import { OpraException } from './opra-exception.js';
|
|
10
|
-
export function wrapException(
|
|
11
|
-
if (
|
|
12
|
-
return
|
|
10
|
+
export function wrapException(error) {
|
|
11
|
+
if (error instanceof OpraException)
|
|
12
|
+
return error;
|
|
13
13
|
let status = 500;
|
|
14
|
-
if (typeof
|
|
15
|
-
status =
|
|
16
|
-
else if (typeof
|
|
17
|
-
status =
|
|
14
|
+
if (typeof error.status === 'number')
|
|
15
|
+
status = error.status;
|
|
16
|
+
else if (typeof error.getStatus === 'function')
|
|
17
|
+
status = error.getStatus();
|
|
18
18
|
switch (status) {
|
|
19
19
|
case 400:
|
|
20
|
-
return new BadRequestError(
|
|
20
|
+
return new BadRequestError(error);
|
|
21
21
|
case 401:
|
|
22
|
-
return new UnauthorizedError(
|
|
22
|
+
return new UnauthorizedError(error);
|
|
23
23
|
case 403:
|
|
24
|
-
return new ForbiddenError(
|
|
24
|
+
return new ForbiddenError(error);
|
|
25
25
|
case 404:
|
|
26
|
-
return new NotFoundError(
|
|
26
|
+
return new NotFoundError(error);
|
|
27
27
|
case 405:
|
|
28
|
-
return new MethodNotAllowedError(
|
|
28
|
+
return new MethodNotAllowedError(error);
|
|
29
29
|
case 406:
|
|
30
|
-
return new NotAcceptableError(
|
|
30
|
+
return new NotAcceptableError(error);
|
|
31
31
|
case 422:
|
|
32
|
-
return new UnprocessableEntityError(
|
|
32
|
+
return new UnprocessableEntityError(error);
|
|
33
33
|
case 424:
|
|
34
|
-
return new FailedDependencyError(
|
|
34
|
+
return new FailedDependencyError(error);
|
|
35
35
|
default:
|
|
36
|
-
return new FailedDependencyError(
|
|
36
|
+
return new FailedDependencyError(error);
|
|
37
37
|
}
|
|
38
38
|
}
|
package/esm/helpers/index.js
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { URL } from 'url';
|
|
2
|
+
const URL_PATTERN = /^(https?:\/\/.)[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$/i;
|
|
3
|
+
export function isUrlString(url) {
|
|
4
|
+
return URL_PATTERN.test(url);
|
|
5
|
+
}
|
|
6
|
+
export const isAbsoluteUrl = (urlString) => {
|
|
7
|
+
return !urlString.includes('://') &&
|
|
8
|
+
(new URL(urlString, 'http://tempuri.org/')).host !== 'tempuri.org';
|
|
9
|
+
};
|
|
@@ -12,13 +12,13 @@ export function cloneObject(obj, jsonOnly) {
|
|
|
12
12
|
}
|
|
13
13
|
});
|
|
14
14
|
}
|
|
15
|
-
export function omitUndefined(obj) {
|
|
15
|
+
export function omitUndefined(obj, recursive) {
|
|
16
16
|
if (!(obj && typeof obj === 'object'))
|
|
17
17
|
return obj;
|
|
18
18
|
for (const k of Object.keys(obj)) {
|
|
19
19
|
if (obj[k] === undefined)
|
|
20
20
|
delete obj[k];
|
|
21
|
-
else if (typeof obj[k] === 'object')
|
|
21
|
+
else if (recursive && typeof obj[k] === 'object')
|
|
22
22
|
omitUndefined(obj[k]);
|
|
23
23
|
}
|
|
24
24
|
return obj;
|
|
@@ -2,10 +2,10 @@ var _a, _b, _c, _d;
|
|
|
2
2
|
function isMap(v) {
|
|
3
3
|
return v && typeof v.forEach === 'function';
|
|
4
4
|
}
|
|
5
|
-
const kKeyMap = Symbol('kKeyMap');
|
|
6
|
-
const kKeyOrder = Symbol('kKeyOrder');
|
|
7
|
-
const kWellKnownKeys = Symbol('kWellKnownKeys');
|
|
8
|
-
const kOptions = Symbol('kOptions');
|
|
5
|
+
const kKeyMap = Symbol.for('kKeyMap');
|
|
6
|
+
const kKeyOrder = Symbol.for('kKeyOrder');
|
|
7
|
+
const kWellKnownKeys = Symbol.for('kWellKnownKeys');
|
|
8
|
+
const kOptions = Symbol.for('kOptions');
|
|
9
9
|
/**
|
|
10
10
|
* A Map implementation that supports case-insensitivity and ordered keys
|
|
11
11
|
*/
|
|
@@ -11,13 +11,15 @@ export function isStream(stream) {
|
|
|
11
11
|
}
|
|
12
12
|
export function isReadable(x) {
|
|
13
13
|
return isStream(x)
|
|
14
|
-
&& x.readable !== false
|
|
15
14
|
&& typeof x._read === 'function'
|
|
16
15
|
&& typeof x._readableState === 'object';
|
|
17
16
|
}
|
|
17
|
+
export function isWritable(x) {
|
|
18
|
+
return isStream(x)
|
|
19
|
+
&& typeof x._write === 'function';
|
|
20
|
+
}
|
|
18
21
|
export function isReadableStream(x) {
|
|
19
22
|
return isStream(x)
|
|
20
|
-
&& x.readable !== false
|
|
21
23
|
&& typeof x.getReader === 'function'
|
|
22
24
|
&& typeof x.pipeThrough === 'function'
|
|
23
25
|
&& typeof x.pipeTo === 'function';
|
|
@@ -38,6 +40,13 @@ export function isFormData(x) {
|
|
|
38
40
|
}
|
|
39
41
|
export function isURL(x) {
|
|
40
42
|
return x !== null
|
|
43
|
+
&& typeof x == 'object'
|
|
41
44
|
&& typeof x.host === 'string'
|
|
42
45
|
&& typeof x.href === 'string';
|
|
43
46
|
}
|
|
47
|
+
export function isIterable(x) {
|
|
48
|
+
return Symbol.iterator in x;
|
|
49
|
+
}
|
|
50
|
+
export function isAsyncIterable(x) {
|
|
51
|
+
return Symbol.asyncIterator in x;
|
|
52
|
+
}
|
package/esm/http/index.js
CHANGED
|
@@ -1,12 +1,5 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './opra-url.js';
|
|
2
|
+
export * from './opra-url-path.js';
|
|
2
3
|
export * from './enums/http-headers-codes.enum.js';
|
|
3
4
|
export * from './enums/http-status-codes.enum.js';
|
|
4
5
|
export * from './enums/http-status-messages.js';
|
|
5
|
-
export * from './interfaces/client-http-headers.interface.js';
|
|
6
|
-
export * from './interfaces/server-http-headers.interface.js';
|
|
7
|
-
export * from './codecs/date-codec.js';
|
|
8
|
-
export * from './codecs/boolean-codec.js';
|
|
9
|
-
export * from './codecs/filter-codec.js';
|
|
10
|
-
export * from './codecs/integer-codec.js';
|
|
11
|
-
export * from './codecs/number-codec.js';
|
|
12
|
-
export * from './codecs/string-codec.js';
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
var _a;
|
|
2
|
+
import { splitString, tokenize } from 'fast-tokenizer';
|
|
3
|
+
import isPlainObject from 'putil-isplainobject';
|
|
4
|
+
const nodeInspectCustom = Symbol.for('nodejs.util.inspect.custom');
|
|
5
|
+
const kLength = Symbol.for('kLength');
|
|
6
|
+
const pathComponentRegEx = /^([^/?#:@]+)(?:@([^/?#:]*))?(?:::(.*))?$/;
|
|
7
|
+
const decimalPattern = /^[+-]?\d+(\.\d+)?$/;
|
|
8
|
+
const booleanPattern = /^true|false$/;
|
|
9
|
+
/**
|
|
10
|
+
* @class OpraURLPath
|
|
11
|
+
*/
|
|
12
|
+
export class OpraURLPath {
|
|
13
|
+
constructor(...init) {
|
|
14
|
+
this[_a] = 0;
|
|
15
|
+
this._resolve(init.filter(x => x));
|
|
16
|
+
}
|
|
17
|
+
get length() {
|
|
18
|
+
return this[kLength];
|
|
19
|
+
}
|
|
20
|
+
resolve(...items) {
|
|
21
|
+
this._resolve(items);
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
join(...items) {
|
|
25
|
+
this._resolve(items, true);
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
isRelativeTo(basePath) {
|
|
29
|
+
basePath = basePath instanceof OpraURLPath ? basePath : new OpraURLPath(basePath);
|
|
30
|
+
let i;
|
|
31
|
+
for (i = 0; i < basePath.length; i++) {
|
|
32
|
+
if (String(this[i]) !== String(basePath[i]))
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
forEach(callback) {
|
|
38
|
+
let i = 0;
|
|
39
|
+
for (const item of this.values()) {
|
|
40
|
+
callback.call(this, item, i++, this);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
values() {
|
|
44
|
+
const arr = new Array(this.length);
|
|
45
|
+
for (let i = 0; i < this.length; i++)
|
|
46
|
+
arr[i] = this[i];
|
|
47
|
+
return arr.values();
|
|
48
|
+
}
|
|
49
|
+
toString() {
|
|
50
|
+
const v = Array.from(this).join('/');
|
|
51
|
+
return v ? '/' + v : '';
|
|
52
|
+
}
|
|
53
|
+
/* istanbul ignore next */
|
|
54
|
+
[(_a = kLength, nodeInspectCustom)]() {
|
|
55
|
+
return `(UrlPath [${this.toString()}])`;
|
|
56
|
+
}
|
|
57
|
+
[Symbol.iterator]() {
|
|
58
|
+
return this.values();
|
|
59
|
+
}
|
|
60
|
+
_resolve(items, join) {
|
|
61
|
+
let paths = (Array.isArray(items) ? items : [items]).map(item => {
|
|
62
|
+
if (typeof item === 'object' && !(item instanceof OpraURLPath || item instanceof OpraURLPathComponent))
|
|
63
|
+
item = new OpraURLPathComponent(item);
|
|
64
|
+
item = String(item);
|
|
65
|
+
// Remove url parts coming after path (query, hash parts)
|
|
66
|
+
if (item.includes('?'))
|
|
67
|
+
item = splitString(item, {
|
|
68
|
+
delimiters: '?',
|
|
69
|
+
quotes: true,
|
|
70
|
+
brackets: true,
|
|
71
|
+
keepBrackets: true,
|
|
72
|
+
keepQuotes: true
|
|
73
|
+
})[0];
|
|
74
|
+
if (item.includes('#'))
|
|
75
|
+
item = splitString(item, {
|
|
76
|
+
delimiters: '#',
|
|
77
|
+
quotes: true,
|
|
78
|
+
brackets: true,
|
|
79
|
+
keepBrackets: true,
|
|
80
|
+
keepQuotes: true
|
|
81
|
+
})[0];
|
|
82
|
+
return join ? removeLeadingSeparator(item) : item;
|
|
83
|
+
});
|
|
84
|
+
const oldLength = this.length;
|
|
85
|
+
let n = 0;
|
|
86
|
+
if (!join) {
|
|
87
|
+
for (n = paths.length - 1; n >= 0; n--) {
|
|
88
|
+
if (String(items[n]).startsWith('/'))
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
if (n > 0)
|
|
92
|
+
paths = paths.slice(n);
|
|
93
|
+
}
|
|
94
|
+
const newPath = paths[0]?.startsWith('/') ? [] : Array.from(this).map(String);
|
|
95
|
+
for (let i = 0; i < paths.length; i++) {
|
|
96
|
+
const pathTokenizer = tokenize(paths[i], { delimiters: '/', quotes: true, brackets: true });
|
|
97
|
+
for (const x of pathTokenizer) {
|
|
98
|
+
if (!x)
|
|
99
|
+
continue;
|
|
100
|
+
if (x.startsWith('.')) {
|
|
101
|
+
if (x === '.')
|
|
102
|
+
continue;
|
|
103
|
+
if (x === '..') {
|
|
104
|
+
newPath.pop();
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
throw new TypeError('Invalid path string');
|
|
108
|
+
}
|
|
109
|
+
newPath.push(x);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
for (let i = 0; i < newPath.length; i++) {
|
|
113
|
+
this[i] = OpraURLPathComponent.parse(newPath[i]);
|
|
114
|
+
}
|
|
115
|
+
for (let i = newPath.length; i < oldLength; i++) {
|
|
116
|
+
delete this[i];
|
|
117
|
+
}
|
|
118
|
+
this[kLength] = newPath.length;
|
|
119
|
+
}
|
|
120
|
+
static join(...items) {
|
|
121
|
+
const instance = new OpraURLPath();
|
|
122
|
+
instance.join(...items);
|
|
123
|
+
return instance;
|
|
124
|
+
}
|
|
125
|
+
static resolve(...items) {
|
|
126
|
+
return new OpraURLPath(...items);
|
|
127
|
+
}
|
|
128
|
+
static relative(source, basePath) {
|
|
129
|
+
source = source instanceof OpraURLPath ? source : new OpraURLPath(source);
|
|
130
|
+
basePath = basePath instanceof OpraURLPath ? basePath : new OpraURLPath(basePath);
|
|
131
|
+
let i;
|
|
132
|
+
for (i = 0; i < basePath.length; i++) {
|
|
133
|
+
if (String(source[i]) !== String(basePath[i]))
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
return new OpraURLPath(Array.from(source).slice(i).join('/'));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
*
|
|
141
|
+
* @class OpraURLPathComponent
|
|
142
|
+
*/
|
|
143
|
+
class OpraURLPathComponent {
|
|
144
|
+
constructor(init) {
|
|
145
|
+
this.resource = init.resource;
|
|
146
|
+
this.key = init.key;
|
|
147
|
+
this.args = init.args;
|
|
148
|
+
this.typeCast = init.typeCast;
|
|
149
|
+
}
|
|
150
|
+
toString() {
|
|
151
|
+
let out = encodeURIComponent(this.resource).replace(/%24/, '$');
|
|
152
|
+
if (this.key) {
|
|
153
|
+
if (typeof this.key === 'object' && isPlainObject(this.key)) {
|
|
154
|
+
const arr = [];
|
|
155
|
+
for (const k of Object.keys(this.key)) {
|
|
156
|
+
let v = this.key[k];
|
|
157
|
+
if (typeof v === 'number' || typeof v === 'boolean')
|
|
158
|
+
v = String(v);
|
|
159
|
+
else
|
|
160
|
+
v = '"' + encodeURIComponent(String(v)) + '"';
|
|
161
|
+
arr.push(encodeURIComponent(k) + '=' + v);
|
|
162
|
+
}
|
|
163
|
+
out += '@' + arr.join(';');
|
|
164
|
+
}
|
|
165
|
+
else
|
|
166
|
+
out += '@' + encodeURIComponent(String(this.key));
|
|
167
|
+
}
|
|
168
|
+
if (this.args) {
|
|
169
|
+
const arr = [];
|
|
170
|
+
for (const k of Object.keys(this.args)) {
|
|
171
|
+
arr.push(encodeURIComponent(k) + '=' + encodeURIComponent(String(this.args[k])));
|
|
172
|
+
}
|
|
173
|
+
out += '(' + arr.join(';') + ')';
|
|
174
|
+
}
|
|
175
|
+
if (this.typeCast)
|
|
176
|
+
out += '::' + encodeURIComponent(this.typeCast);
|
|
177
|
+
return out;
|
|
178
|
+
}
|
|
179
|
+
/* istanbul ignore next */
|
|
180
|
+
[nodeInspectCustom]() {
|
|
181
|
+
return this.toString();
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Factory method.
|
|
185
|
+
* @param input
|
|
186
|
+
*/
|
|
187
|
+
static parse(input) {
|
|
188
|
+
const m = pathComponentRegEx.exec(input);
|
|
189
|
+
if (!m)
|
|
190
|
+
throw Object.assign(new TypeError('Invalid Opra URL'), {
|
|
191
|
+
code: 'ERR_INVALID_OPRA_URL',
|
|
192
|
+
input,
|
|
193
|
+
});
|
|
194
|
+
let key;
|
|
195
|
+
if (m[2]) {
|
|
196
|
+
const s = decodeURIComponent(m[2]);
|
|
197
|
+
const b = splitString(s, { delimiters: ';', quotes: true, escape: false, keepQuotes: true, keepBrackets: true });
|
|
198
|
+
for (const n of b) {
|
|
199
|
+
const c = splitString(n, { delimiters: '=', quotes: true, escape: false, keepQuotes: true, keepBrackets: true });
|
|
200
|
+
if ((b.length > 1 && c.length < 2) ||
|
|
201
|
+
(key &&
|
|
202
|
+
(c.length >= 2 && typeof key !== 'object') ||
|
|
203
|
+
(c.length < 2 && typeof key === 'object')))
|
|
204
|
+
throw Object.assign(new TypeError('Invalid Opra URL. name:value pair required for multiple key format'), {
|
|
205
|
+
pathComponent: input,
|
|
206
|
+
code: 'ERR_INVALID_OPRA_URL'
|
|
207
|
+
});
|
|
208
|
+
if (c.length >= 2) {
|
|
209
|
+
key = key || {};
|
|
210
|
+
const k = c.shift() || '';
|
|
211
|
+
let v = c.join('=');
|
|
212
|
+
if (decimalPattern.test(v))
|
|
213
|
+
v = Number(v);
|
|
214
|
+
else if (booleanPattern.test(v))
|
|
215
|
+
v = Boolean(v);
|
|
216
|
+
else if (v.startsWith('"') && v.endsWith('"'))
|
|
217
|
+
v = v.substring(1, v.length - 1);
|
|
218
|
+
else if (v.startsWith("'") && v.endsWith("'"))
|
|
219
|
+
v = v.substring(1, v.length - 1);
|
|
220
|
+
key[k] = v;
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
if (decimalPattern.test(c[0]))
|
|
224
|
+
key = Number(c[0]);
|
|
225
|
+
else if (booleanPattern.test(c[0]))
|
|
226
|
+
key = Boolean(c[0]);
|
|
227
|
+
else
|
|
228
|
+
key = c[0];
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return new OpraURLPathComponent({
|
|
232
|
+
resource: decodeURIComponent(m[1]),
|
|
233
|
+
key,
|
|
234
|
+
typeCast: m[3] ? decodeURIComponent(m[3]) : undefined
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
return new OpraURLPathComponent({
|
|
238
|
+
resource: decodeURIComponent(m[1]),
|
|
239
|
+
typeCast: m[3] ? decodeURIComponent(m[3]) : undefined
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
function removeLeadingSeparator(s) {
|
|
244
|
+
const m = /^\/*(.*)/.exec(s);
|
|
245
|
+
return m?.[1] || s;
|
|
246
|
+
}
|