@rsdk/common 5.7.0-next.6 → 6.0.0-next.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/dist/functions/obj-normalization.d.ts +37 -7
- package/dist/functions/obj-normalization.js +50 -8
- package/dist/functions/obj-normalization.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/parsers/array/array.parser.d.ts +11 -0
- package/dist/parsers/array/array.parser.js +34 -0
- package/dist/parsers/array/array.parser.js.map +1 -0
- package/dist/parsers/array/index.d.ts +1 -0
- package/dist/parsers/array/index.js +18 -0
- package/dist/parsers/array/index.js.map +1 -0
- package/dist/parsers/boolean/bool.parser.d.ts +6 -0
- package/dist/parsers/boolean/bool.parser.js +21 -0
- package/dist/parsers/boolean/bool.parser.js.map +1 -0
- package/dist/parsers/boolean/index.d.ts +1 -0
- package/dist/parsers/boolean/index.js +18 -0
- package/dist/parsers/boolean/index.js.map +1 -0
- package/dist/parsers/enum/enum.parser.d.ts +9 -0
- package/dist/parsers/enum/enum.parser.js +26 -0
- package/dist/parsers/enum/enum.parser.js.map +1 -0
- package/dist/parsers/enum/index.d.ts +1 -0
- package/dist/parsers/enum/index.js +18 -0
- package/dist/parsers/enum/index.js.map +1 -0
- package/dist/parsers/index.d.ts +11 -0
- package/dist/parsers/index.js +28 -0
- package/dist/parsers/index.js.map +1 -0
- package/dist/parsers/int/index.d.ts +1 -0
- package/dist/parsers/int/index.js +18 -0
- package/dist/parsers/int/index.js.map +1 -0
- package/dist/parsers/int/int.parser.d.ts +6 -0
- package/dist/parsers/int/int.parser.js +21 -0
- package/dist/parsers/int/int.parser.js.map +1 -0
- package/dist/parsers/json/index.d.ts +1 -0
- package/dist/parsers/json/index.js +18 -0
- package/dist/parsers/json/index.js.map +1 -0
- package/dist/parsers/json/json.parser.d.ts +6 -0
- package/dist/parsers/json/json.parser.js +16 -0
- package/dist/parsers/json/json.parser.js.map +1 -0
- package/dist/parsers/number/index.d.ts +1 -0
- package/dist/parsers/number/index.js +18 -0
- package/dist/parsers/number/index.js.map +1 -0
- package/dist/parsers/number/number.parser.d.ts +6 -0
- package/dist/parsers/number/number.parser.js +24 -0
- package/dist/parsers/number/number.parser.js.map +1 -0
- package/dist/parsers/parser.interface.d.ts +20 -0
- package/dist/parsers/parser.interface.js +3 -0
- package/dist/parsers/parser.interface.js.map +1 -0
- package/dist/parsers/size/index.d.ts +1 -0
- package/dist/parsers/size/index.js +18 -0
- package/dist/parsers/size/index.js.map +1 -0
- package/dist/parsers/size/size.parser.d.ts +7 -0
- package/dist/parsers/size/size.parser.js +23 -0
- package/dist/parsers/size/size.parser.js.map +1 -0
- package/dist/parsers/string/index.d.ts +1 -0
- package/dist/parsers/string/index.js +18 -0
- package/dist/parsers/string/index.js.map +1 -0
- package/dist/parsers/string/string.parser.d.ts +8 -0
- package/dist/parsers/string/string.parser.js +25 -0
- package/dist/parsers/string/string.parser.js.map +1 -0
- package/dist/parsers/timespan/index.d.ts +1 -0
- package/dist/parsers/timespan/index.js +18 -0
- package/dist/parsers/timespan/index.js.map +1 -0
- package/dist/parsers/timespan/timespan.parser.d.ts +7 -0
- package/dist/parsers/timespan/timespan.parser.js +23 -0
- package/dist/parsers/timespan/timespan.parser.js.map +1 -0
- package/dist/parsers/url/errors.d.ts +6 -0
- package/dist/parsers/url/errors.js +24 -0
- package/dist/parsers/url/errors.js.map +1 -0
- package/dist/parsers/url/index.d.ts +1 -0
- package/dist/parsers/url/index.js +18 -0
- package/dist/parsers/url/index.js.map +1 -0
- package/dist/parsers/url/url.parser.d.ts +9 -0
- package/dist/parsers/url/url.parser.js +38 -0
- package/dist/parsers/url/url.parser.js.map +1 -0
- package/dist/types/assert.class.d.ts +2 -0
- package/dist/types/assert.class.js +12 -0
- package/dist/types/assert.class.js.map +1 -1
- package/package.json +4 -4
- package/src/functions/obj-normalization.spec.ts +102 -0
- package/src/functions/obj-normalization.ts +53 -8
- package/src/index.ts +1 -0
- package/src/parsers/array/array.parser.ts +34 -0
- package/src/parsers/array/index.ts +1 -0
- package/src/parsers/boolean/bool.parser.ts +20 -0
- package/src/parsers/boolean/bool.spec.ts +4 -0
- package/src/parsers/boolean/index.ts +1 -0
- package/src/parsers/enum/enum.parser.ts +24 -0
- package/src/parsers/enum/enum.spec.ts +5 -0
- package/src/parsers/enum/index.ts +1 -0
- package/src/parsers/index.ts +11 -0
- package/src/parsers/int/index.ts +1 -0
- package/src/parsers/int/int.parser.ts +20 -0
- package/src/parsers/int/int.spec.ts +5 -0
- package/src/parsers/json/index.ts +1 -0
- package/src/parsers/json/json.parser.ts +15 -0
- package/src/parsers/number/index.ts +1 -0
- package/src/parsers/number/number.parser.ts +23 -0
- package/src/parsers/number/number.spec.ts +5 -0
- package/src/parsers/parser.interface.ts +22 -0
- package/src/parsers/size/index.ts +1 -0
- package/src/parsers/size/size.parser.ts +23 -0
- package/src/parsers/size/size.spec.ts +4 -0
- package/src/parsers/string/index.ts +1 -0
- package/src/parsers/string/string.parser.ts +24 -0
- package/src/parsers/string/string.spec.ts +10 -0
- package/src/parsers/timespan/index.ts +1 -0
- package/src/parsers/timespan/timespan.parser.ts +23 -0
- package/src/parsers/timespan/timespan.spec.ts +5 -0
- package/src/parsers/url/errors.ts +19 -0
- package/src/parsers/url/index.ts +1 -0
- package/src/parsers/url/url.parser.ts +43 -0
- package/src/types/assert.class.ts +16 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Convert } from '../../convert';
|
|
2
|
+
import type { EnumLike, EnumValue } from '../../enums';
|
|
3
|
+
import { Enum } from '../../enums';
|
|
4
|
+
import { text } from '../../strings';
|
|
5
|
+
import type { PropertyParser } from '../parser.interface';
|
|
6
|
+
|
|
7
|
+
export class EnumParser<E extends EnumValue> implements PropertyParser<E> {
|
|
8
|
+
constructor(private readonly enumeration: EnumLike) {}
|
|
9
|
+
|
|
10
|
+
type(): string {
|
|
11
|
+
return `string|number(enum_value)`;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
description(): string {
|
|
15
|
+
return text`
|
|
16
|
+
Extracts strings or numbers and ensures it is one of:
|
|
17
|
+
${Enum.values(this.enumeration).join(', ')}
|
|
18
|
+
`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
parse(value: unknown): E {
|
|
22
|
+
return Convert.enum<E>(value, this.enumeration);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './enum.parser';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from './boolean';
|
|
2
|
+
export * from './enum';
|
|
3
|
+
export * from './int';
|
|
4
|
+
export * from './number';
|
|
5
|
+
export * from './size';
|
|
6
|
+
export * from './string';
|
|
7
|
+
export * from './timespan';
|
|
8
|
+
export * from './url';
|
|
9
|
+
export * from './array';
|
|
10
|
+
export * from './json';
|
|
11
|
+
export * from './parser.interface';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './int.parser';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Convert } from '../../convert';
|
|
2
|
+
import { text } from '../../strings';
|
|
3
|
+
import type { PropertyParser } from '../parser.interface';
|
|
4
|
+
|
|
5
|
+
export class IntParser implements PropertyParser<number> {
|
|
6
|
+
type(): string {
|
|
7
|
+
return 'number(int)';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
description(): string {
|
|
11
|
+
return text`
|
|
12
|
+
Extracts valid integer (uses parseInt under the hood).
|
|
13
|
+
Floating point numbers, NaN, Infinity will be rejected.
|
|
14
|
+
`;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
parse(value: unknown): number {
|
|
18
|
+
return Convert.int(value);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './json.parser';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { PropertyParser } from '../parser.interface';
|
|
2
|
+
|
|
3
|
+
export class JsonParser implements PropertyParser<Record<string, any>> {
|
|
4
|
+
description(): string {
|
|
5
|
+
return 'parse string as json';
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
parse(value: string): Record<string, any> {
|
|
9
|
+
return JSON.parse(value);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
type(): string {
|
|
13
|
+
return 'json';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './number.parser';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Convert } from '../../convert';
|
|
2
|
+
import { text } from '../../strings';
|
|
3
|
+
import type { PropertyParser } from '../parser.interface';
|
|
4
|
+
|
|
5
|
+
export class NumberParser implements PropertyParser<number> {
|
|
6
|
+
type(): string {
|
|
7
|
+
return 'number';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
description(): string {
|
|
11
|
+
return text`
|
|
12
|
+
Extracts numeric value (uses parseFloat under the hood).
|
|
13
|
+
NaN and Infinity will be rejected.
|
|
14
|
+
|
|
15
|
+
NOTE: Use correct decimal delimiter according to locale. See
|
|
16
|
+
https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Intl
|
|
17
|
+
`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
parse(value: unknown): number {
|
|
21
|
+
return Convert.number(value);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Implement this interface to create more parsers.
|
|
3
|
+
* For example: email, BigInt, guid etc.
|
|
4
|
+
*
|
|
5
|
+
* NOTE: In other modules it is more common to define metadata
|
|
6
|
+
* via decorators. But this case is a bit different.
|
|
7
|
+
*
|
|
8
|
+
* 1. Parser implementations can have constructors with parameters
|
|
9
|
+
* which will affect it's behaviour. It's will be nice to have it
|
|
10
|
+
* in metadata, and decorators won't provide this.
|
|
11
|
+
*
|
|
12
|
+
* 2. Metadata will be extracted via type() and description() methods
|
|
13
|
+
* mostly during decorator factories (such as @Property()) code is
|
|
14
|
+
* executed. Thus output **can** be used in autodoc
|
|
15
|
+
*/
|
|
16
|
+
export interface PropertyParser<T = any> {
|
|
17
|
+
type(): string;
|
|
18
|
+
|
|
19
|
+
description(): string;
|
|
20
|
+
|
|
21
|
+
parse(value: unknown): T;
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './size.parser';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Size, SIZE_STRING_PATTERN } from '../../size';
|
|
2
|
+
import { text } from '../../strings';
|
|
3
|
+
import { Assert } from '../../types';
|
|
4
|
+
import type { PropertyParser } from '../parser.interface';
|
|
5
|
+
|
|
6
|
+
export class SizeParser implements PropertyParser<Size> {
|
|
7
|
+
type(): string {
|
|
8
|
+
return 'Timespan';
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
description(): string {
|
|
12
|
+
return text`
|
|
13
|
+
Parses string in size format into Timespan instance.
|
|
14
|
+
Format is: ${SIZE_STRING_PATTERN}. For example: 8b, 10kb, 2gb.
|
|
15
|
+
`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
parse(value: unknown): Size {
|
|
19
|
+
Assert.isString(value);
|
|
20
|
+
|
|
21
|
+
return Size.parse(value);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './string.parser';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Assert } from '../../types';
|
|
2
|
+
import type { PropertyParser } from '../parser.interface';
|
|
3
|
+
|
|
4
|
+
export class StringParser implements PropertyParser<string> {
|
|
5
|
+
constructor(private readonly pattern?: RegExp) {}
|
|
6
|
+
|
|
7
|
+
type(): string {
|
|
8
|
+
return 'string';
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
description(): string {
|
|
12
|
+
return 'Extract arbitrary string.';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
parse(value: unknown): string {
|
|
16
|
+
Assert.isString(value);
|
|
17
|
+
|
|
18
|
+
if (this.pattern) {
|
|
19
|
+
Assert.isTrue(this.pattern.test(value));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { StringParser } from './string.parser';
|
|
2
|
+
|
|
3
|
+
describe('StringMatcher', () => {
|
|
4
|
+
it('match', () => {
|
|
5
|
+
const parser = new StringParser(/^[a-z]+$/);
|
|
6
|
+
|
|
7
|
+
expect(parser.parse('abcd')).toBe('abcd');
|
|
8
|
+
expect(() => parser.parse('1234')).toThrow();
|
|
9
|
+
});
|
|
10
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './timespan.parser';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { text } from '../../strings';
|
|
2
|
+
import { Timespan, TIMESPAN_STRING_PATTERN } from '../../time';
|
|
3
|
+
import { Assert } from '../../types';
|
|
4
|
+
import type { PropertyParser } from '../parser.interface';
|
|
5
|
+
|
|
6
|
+
export class TimespanParser implements PropertyParser<Timespan> {
|
|
7
|
+
type(): string {
|
|
8
|
+
return 'Timespan';
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
description(): string {
|
|
12
|
+
return text`
|
|
13
|
+
Parses string in timespan format into Timespan instance.
|
|
14
|
+
Format is: ${TIMESPAN_STRING_PATTERN}. For example: 1s, 2h, 4d.
|
|
15
|
+
`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
parse(value: unknown): Timespan {
|
|
19
|
+
Assert.isString(value);
|
|
20
|
+
|
|
21
|
+
return Timespan.parse(value);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export class InvalidUrl extends Error {
|
|
2
|
+
constructor(str: string, cause: unknown) {
|
|
3
|
+
super(`Invalid url string: <${str}>`);
|
|
4
|
+
this.name = 'InvalidUrl';
|
|
5
|
+
this.cause = cause;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class InvalidProtocol extends Error {
|
|
10
|
+
constructor(expectedProtocols: string[], protocol: string, url: URL) {
|
|
11
|
+
super(`Invalid protocol: <${protocol}>, expected: ${expectedProtocols}`);
|
|
12
|
+
this.name = 'InvalidProtocol';
|
|
13
|
+
this.cause = {
|
|
14
|
+
protocol,
|
|
15
|
+
url,
|
|
16
|
+
expected: expectedProtocols,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './url.parser';
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Assert } from '../../types';
|
|
2
|
+
import type { PropertyParser } from '../parser.interface';
|
|
3
|
+
|
|
4
|
+
import { InvalidProtocol, InvalidUrl } from './errors';
|
|
5
|
+
|
|
6
|
+
export class UrlParser implements PropertyParser<URL> {
|
|
7
|
+
private readonly protocols: string[];
|
|
8
|
+
|
|
9
|
+
constructor(...protocols: string[]) {
|
|
10
|
+
this.protocols = protocols;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type(): string {
|
|
14
|
+
return 'URL';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
description(): string {
|
|
18
|
+
return 'Parses string into instance of URL';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
parse(value: unknown): URL {
|
|
22
|
+
Assert.isString(value);
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
const url = new URL(value);
|
|
26
|
+
|
|
27
|
+
this.assertProtocol(url);
|
|
28
|
+
return url;
|
|
29
|
+
} catch (error) {
|
|
30
|
+
throw new InvalidUrl(value, error);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private assertProtocol(url: URL): void {
|
|
35
|
+
if (this.protocols.length === 0) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (!this.protocols.includes(url.protocol)) {
|
|
40
|
+
throw new InvalidProtocol(this.protocols, url.protocol, url);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -15,6 +15,22 @@ export class Assert {
|
|
|
15
15
|
throw new Error(`<${x}> is not a number.`);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
static isBoolean(x: unknown): asserts x is boolean {
|
|
19
|
+
if (typeof x === 'boolean') {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
throw new Error(`<${x}> is not a boolean.`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
static isTrue(x: unknown): asserts x is true {
|
|
27
|
+
if (x === true) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
throw new Error(`<${x}> is not true.`);
|
|
32
|
+
}
|
|
33
|
+
|
|
18
34
|
static isError(x: unknown): asserts x is Error {
|
|
19
35
|
if (x instanceof Error) {
|
|
20
36
|
return;
|