@outfoxx/sunday 1.0.9 → 1.1.0-alpha.11
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/LICENSE.txt +203 -0
- package/README.md +35 -2
- package/dist/any-type.d.ts +2 -0
- package/dist/any-type.js +13 -0
- package/dist/any-type.js.map +1 -1
- package/dist/class-type.d.ts +2 -2
- package/dist/class-type.js +13 -0
- package/dist/class-type.js.map +1 -1
- package/dist/date-time-types.d.ts +2 -7
- package/dist/date-time-types.js +15 -4
- package/dist/date-time-types.js.map +1 -1
- package/dist/event-parser.d.ts +17 -0
- package/dist/event-parser.js +153 -0
- package/dist/event-parser.js.map +1 -0
- package/dist/fetch-event-source.d.ts +12 -10
- package/dist/fetch-event-source.js +154 -138
- package/dist/fetch-event-source.js.map +1 -1
- package/dist/fetch-request-factory.d.ts +10 -5
- package/dist/fetch-request-factory.js +100 -71
- package/dist/fetch-request-factory.js.map +1 -1
- package/dist/fetch.d.ts +7 -1
- package/dist/fetch.js +74 -8
- package/dist/fetch.js.map +1 -1
- package/dist/header-parameters.d.ts +3 -0
- package/dist/header-parameters.js +53 -0
- package/dist/header-parameters.js.map +1 -0
- package/dist/index.d.ts +12 -12
- package/dist/index.js +25 -12
- package/dist/index.js.map +1 -1
- package/dist/logger.js +13 -0
- package/dist/logger.js.map +1 -1
- package/dist/{binary-decoder.d.ts → media-type-codecs/binary-decoder.d.ts} +2 -2
- package/dist/media-type-codecs/binary-decoder.js +29 -0
- package/dist/media-type-codecs/binary-decoder.js.map +1 -0
- package/dist/{binary-encoder.d.ts → media-type-codecs/binary-encoder.d.ts} +0 -0
- package/dist/media-type-codecs/binary-encoder.js +26 -0
- package/dist/media-type-codecs/binary-encoder.js.map +1 -0
- package/dist/media-type-codecs/cbor-decoder.d.ts +39 -0
- package/dist/media-type-codecs/cbor-decoder.js +426 -0
- package/dist/media-type-codecs/cbor-decoder.js.map +1 -0
- package/dist/media-type-codecs/cbor-encoder.d.ts +43 -0
- package/dist/media-type-codecs/cbor-encoder.js +239 -0
- package/dist/media-type-codecs/cbor-encoder.js.map +1 -0
- package/dist/media-type-codecs/cbor-tags.d.ts +4 -0
- package/dist/media-type-codecs/cbor-tags.js +18 -0
- package/dist/media-type-codecs/cbor-tags.js.map +1 -0
- package/dist/media-type-codecs/json-decoder.d.ts +39 -0
- package/dist/media-type-codecs/json-decoder.js +380 -0
- package/dist/media-type-codecs/json-decoder.js.map +1 -0
- package/dist/media-type-codecs/json-encoder.d.ts +44 -0
- package/dist/media-type-codecs/json-encoder.js +276 -0
- package/dist/media-type-codecs/json-encoder.js.map +1 -0
- package/dist/media-type-codecs/media-type-decoder.d.ts +11 -0
- package/dist/media-type-codecs/media-type-decoder.js +19 -0
- package/dist/media-type-codecs/media-type-decoder.js.map +1 -0
- package/dist/{media-type-decoders.d.ts → media-type-codecs/media-type-decoders.d.ts} +5 -4
- package/dist/media-type-codecs/media-type-decoders.js +53 -0
- package/dist/media-type-codecs/media-type-decoders.js.map +1 -0
- package/dist/{media-type-encoder.d.ts → media-type-codecs/media-type-encoder.d.ts} +5 -1
- package/dist/media-type-codecs/media-type-encoder.js +24 -0
- package/dist/media-type-codecs/media-type-encoder.js.map +1 -0
- package/dist/{media-type-encoders.d.ts → media-type-codecs/media-type-encoders.d.ts} +5 -4
- package/dist/media-type-codecs/media-type-encoders.js +55 -0
- package/dist/media-type-codecs/media-type-encoders.js.map +1 -0
- package/dist/{url-encoder.d.ts → media-type-codecs/www-form-url-encoder.d.ts} +8 -8
- package/dist/{url-encoder.js → media-type-codecs/www-form-url-encoder.js} +51 -37
- package/dist/media-type-codecs/www-form-url-encoder.js.map +1 -0
- package/dist/media-type.d.ts +91 -13
- package/dist/media-type.js +286 -15
- package/dist/media-type.js.map +1 -1
- package/dist/problem.d.ts +24 -9
- package/dist/problem.js +153 -6
- package/dist/problem.js.map +1 -1
- package/dist/request-factory.d.ts +10 -10
- package/dist/request-factory.js +13 -0
- package/dist/request-factory.js.map +1 -1
- package/dist/sunday-error.d.ts +11 -0
- package/dist/sunday-error.js +31 -0
- package/dist/sunday-error.js.map +1 -0
- package/dist/url-template.js +13 -0
- package/dist/url-template.js.map +1 -1
- package/dist/util/any.d.ts +2 -0
- package/dist/util/any.js +24 -0
- package/dist/util/any.js.map +1 -0
- package/dist/util/base64.js +13 -0
- package/dist/util/base64.js.map +1 -1
- package/dist/util/error.d.ts +2 -0
- package/dist/util/error.js +26 -0
- package/dist/util/error.js.map +1 -0
- package/dist/util/hex.js +16 -2
- package/dist/util/hex.js.map +1 -1
- package/dist/util/rxjs.d.ts +3 -0
- package/dist/util/rxjs.js +22 -5
- package/dist/util/rxjs.js.map +1 -1
- package/dist/util/stream-rxjs.js +13 -0
- package/dist/util/stream-rxjs.js.map +1 -1
- package/dist/util/temporal.d.ts +2 -0
- package/dist/util/temporal.js +31 -0
- package/dist/util/temporal.js.map +1 -0
- package/package.json +29 -22
- package/src/any-type.ts +18 -0
- package/src/class-type.ts +20 -2
- package/src/date-time-types.ts +35 -8
- package/src/event-parser.ts +204 -0
- package/src/fetch-event-source.ts +163 -159
- package/src/fetch-request-factory.ts +142 -100
- package/src/fetch.ts +79 -14
- package/src/header-parameters.ts +66 -0
- package/src/index.ts +26 -12
- package/src/logger.ts +14 -0
- package/src/media-type-codecs/binary-decoder.ts +38 -0
- package/src/media-type-codecs/binary-encoder.ts +33 -0
- package/src/media-type-codecs/cbor-decoder.ts +529 -0
- package/src/media-type-codecs/cbor-encoder.ts +321 -0
- package/src/media-type-codecs/cbor-tags.ts +18 -0
- package/src/media-type-codecs/json-decoder.ts +484 -0
- package/src/media-type-codecs/json-encoder.ts +342 -0
- package/src/media-type-codecs/media-type-decoder.ts +34 -0
- package/src/media-type-codecs/media-type-decoders.ts +81 -0
- package/src/media-type-codecs/media-type-encoder.ts +45 -0
- package/src/media-type-codecs/media-type-encoders.ts +83 -0
- package/src/media-type-codecs/www-form-url-encoder.ts +193 -0
- package/src/media-type.ts +340 -22
- package/src/problem.ts +158 -12
- package/src/request-factory.ts +35 -12
- package/src/sunday-error.ts +51 -0
- package/src/url-template.ts +14 -0
- package/src/util/any.ts +24 -0
- package/src/util/base64.ts +14 -0
- package/src/util/error.ts +28 -0
- package/src/util/hex.ts +17 -2
- package/src/util/rxjs.ts +30 -5
- package/src/util/stream-rxjs.ts +14 -0
- package/src/util/temporal.ts +32 -0
- package/dist/binary-decoder.js +0 -16
- package/dist/binary-decoder.js.map +0 -1
- package/dist/binary-encoder.js +0 -13
- package/dist/binary-encoder.js.map +0 -1
- package/dist/cbor-decoder.d.ts +0 -15
- package/dist/cbor-decoder.js +0 -126
- package/dist/cbor-decoder.js.map +0 -1
- package/dist/cbor-encoder.d.ts +0 -29
- package/dist/cbor-encoder.js +0 -81
- package/dist/cbor-encoder.js.map +0 -1
- package/dist/cbor-tags.d.ts +0 -3
- package/dist/cbor-tags.js +0 -4
- package/dist/cbor-tags.js.map +0 -1
- package/dist/http-error.d.ts +0 -10
- package/dist/http-error.js +0 -45
- package/dist/http-error.js.map +0 -1
- package/dist/json-decoder.d.ts +0 -31
- package/dist/json-decoder.js +0 -139
- package/dist/json-decoder.js.map +0 -1
- package/dist/json-encoder.d.ts +0 -35
- package/dist/json-encoder.js +0 -134
- package/dist/json-encoder.js.map +0 -1
- package/dist/media-type-decoder.d.ts +0 -4
- package/dist/media-type-decoder.js +0 -2
- package/dist/media-type-decoder.js.map +0 -1
- package/dist/media-type-decoders.js +0 -40
- package/dist/media-type-decoders.js.map +0 -1
- package/dist/media-type-encoder.js +0 -6
- package/dist/media-type-encoder.js.map +0 -1
- package/dist/media-type-encoders.js +0 -42
- package/dist/media-type-encoders.js.map +0 -1
- package/dist/url-encoder.js.map +0 -1
- package/src/binary-decoder.ts +0 -24
- package/src/binary-encoder.ts +0 -19
- package/src/cbor-decoder.ts +0 -148
- package/src/cbor-encoder.ts +0 -95
- package/src/cbor-tags.ts +0 -3
- package/src/http-error.ts +0 -55
- package/src/json-decoder.ts +0 -164
- package/src/json-encoder.ts +0 -162
- package/src/media-type-decoder.ts +0 -5
- package/src/media-type-decoders.ts +0 -59
- package/src/media-type-encoder.ts +0 -16
- package/src/media-type-encoders.ts +0 -61
- package/src/url-encoder.ts +0 -173
package/src/json-decoder.ts
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import { JsonParser } from '@outfoxx/jackson-js';
|
|
2
|
-
import { CustomMapper, Deserializer } from '@outfoxx/jackson-js/dist/@types';
|
|
3
|
-
import { DateTime } from 'luxon';
|
|
4
|
-
import { AnyType } from './any-type';
|
|
5
|
-
import { MediaTypeDecoder } from './media-type-decoder';
|
|
6
|
-
import { Base64 } from './util/base64';
|
|
7
|
-
|
|
8
|
-
export class JSONDecoder implements MediaTypeDecoder {
|
|
9
|
-
static get default(): JSONDecoder {
|
|
10
|
-
return new JSONDecoder(
|
|
11
|
-
JSONDecoder.NumericDateDecoding.MILLISECONDS_SINCE_EPOCH
|
|
12
|
-
);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
private readonly customDeserializers: CustomMapper<Deserializer>[];
|
|
16
|
-
private readonly parser = new JsonParser();
|
|
17
|
-
|
|
18
|
-
constructor(readonly numericDateDecoding: JSONDecoder.NumericDateDecoding) {
|
|
19
|
-
this.customDeserializers = [
|
|
20
|
-
{
|
|
21
|
-
type: () => Date,
|
|
22
|
-
mapper: this.dateDeserializer,
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
type: () => DateTime,
|
|
26
|
-
mapper: this.dateTimeDeserializer,
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
type: () => URL,
|
|
30
|
-
mapper: this.urlDeserializer,
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
type: () => ArrayBuffer,
|
|
34
|
-
mapper: this.arrayBufferDeserializer,
|
|
35
|
-
},
|
|
36
|
-
];
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async decode<T>(response: Response, type: AnyType): Promise<T> {
|
|
40
|
-
return this.decodeJSON(await response.json(), type);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
decodeText<T>(text: string, type: AnyType): T {
|
|
44
|
-
return this.parser.parse(text, {
|
|
45
|
-
deserializers: this.customDeserializers,
|
|
46
|
-
mainCreator: () => type,
|
|
47
|
-
}) as T;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
decodeJSON<T, U>(value: T, type: AnyType): Promise<U> {
|
|
51
|
-
return this.parser.transform(value, {
|
|
52
|
-
deserializers: this.customDeserializers,
|
|
53
|
-
mainCreator: () => type,
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
private dateTimeDeserializer: Deserializer = (
|
|
58
|
-
key: string,
|
|
59
|
-
value: unknown
|
|
60
|
-
) => {
|
|
61
|
-
if (value == null) {
|
|
62
|
-
return value;
|
|
63
|
-
}
|
|
64
|
-
if (DateTime.isDateTime(value)) {
|
|
65
|
-
return value;
|
|
66
|
-
}
|
|
67
|
-
if (value instanceof Date) {
|
|
68
|
-
return DateTime.fromJSDate(value, { zone: 'UTC' });
|
|
69
|
-
}
|
|
70
|
-
if (typeof value === 'number') {
|
|
71
|
-
if (
|
|
72
|
-
this.numericDateDecoding ===
|
|
73
|
-
JSONDecoder.NumericDateDecoding.MILLISECONDS_SINCE_EPOCH
|
|
74
|
-
) {
|
|
75
|
-
return DateTime.fromMillis(value, { zone: 'UTC' });
|
|
76
|
-
} else if (
|
|
77
|
-
this.numericDateDecoding ===
|
|
78
|
-
JSONDecoder.NumericDateDecoding.SECONDS_SINCE_EPOCH
|
|
79
|
-
) {
|
|
80
|
-
return DateTime.fromSeconds(value, { zone: 'UTC' });
|
|
81
|
-
} else {
|
|
82
|
-
console.error('Unsupported date decoding format');
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
if (typeof value === 'string') {
|
|
86
|
-
return DateTime.fromISO(value, { setZone: true });
|
|
87
|
-
}
|
|
88
|
-
throw new Error(`Invalid date value for property ${key}`);
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
private dateDeserializer: Deserializer = (key: string, value: unknown) => {
|
|
92
|
-
if (value == null) {
|
|
93
|
-
return value;
|
|
94
|
-
}
|
|
95
|
-
if (value instanceof Date) {
|
|
96
|
-
return value;
|
|
97
|
-
}
|
|
98
|
-
if (typeof value === 'number') {
|
|
99
|
-
if (
|
|
100
|
-
this.numericDateDecoding ===
|
|
101
|
-
JSONDecoder.NumericDateDecoding.MILLISECONDS_SINCE_EPOCH
|
|
102
|
-
) {
|
|
103
|
-
return new Date(value);
|
|
104
|
-
} else if (
|
|
105
|
-
this.numericDateDecoding ===
|
|
106
|
-
JSONDecoder.NumericDateDecoding.SECONDS_SINCE_EPOCH
|
|
107
|
-
) {
|
|
108
|
-
return new Date(value * 1000);
|
|
109
|
-
} else {
|
|
110
|
-
console.error('Unsupported date decoding format');
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
if (typeof value === 'string') {
|
|
114
|
-
return new Date(value);
|
|
115
|
-
}
|
|
116
|
-
throw new Error(`Invalid date value for property ${key}`);
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
private urlDeserializer: Deserializer = (key: string, value: unknown) => {
|
|
120
|
-
if (value == null) {
|
|
121
|
-
return value;
|
|
122
|
-
}
|
|
123
|
-
if (value instanceof URL) {
|
|
124
|
-
return value;
|
|
125
|
-
}
|
|
126
|
-
if (typeof value === 'string') {
|
|
127
|
-
return new URL(value);
|
|
128
|
-
}
|
|
129
|
-
throw Error(`Invalid URL value for property ${key}`);
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
private arrayBufferDeserializer: Deserializer = (
|
|
133
|
-
key: string,
|
|
134
|
-
value: unknown
|
|
135
|
-
) => {
|
|
136
|
-
if (value == null) {
|
|
137
|
-
return value;
|
|
138
|
-
}
|
|
139
|
-
if (value instanceof ArrayBuffer) {
|
|
140
|
-
return value;
|
|
141
|
-
}
|
|
142
|
-
if (typeof value === 'string') {
|
|
143
|
-
return Base64.decode(value);
|
|
144
|
-
}
|
|
145
|
-
throw Error(`Invalid ArrayBuffer value for property ${key}`);
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
export namespace JSONDecoder {
|
|
150
|
-
/**
|
|
151
|
-
* Configures how numeric `Date` & `DateTime` parameters are decoded.
|
|
152
|
-
*/
|
|
153
|
-
export enum NumericDateDecoding {
|
|
154
|
-
/**
|
|
155
|
-
* Decode the `Date`/`DateTime` as a UNIX timestamp (floating point seconds since epoch).
|
|
156
|
-
*/
|
|
157
|
-
SECONDS_SINCE_EPOCH,
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Decode the `Date`/`DateTime` as UNIX millisecond timestamp (integer milliseconds since epoch).
|
|
161
|
-
*/
|
|
162
|
-
MILLISECONDS_SINCE_EPOCH,
|
|
163
|
-
}
|
|
164
|
-
}
|
package/src/json-encoder.ts
DELETED
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import { CustomMapper, Serializer } from '@outfoxx/jackson-js/dist/@types';
|
|
2
|
-
import { DateTime } from 'luxon';
|
|
3
|
-
import { MediaTypeEncoder } from './media-type-encoder';
|
|
4
|
-
import { AnyType } from './any-type';
|
|
5
|
-
import { JsonIncludeType, JsonStringifier } from '@outfoxx/jackson-js';
|
|
6
|
-
import { Base64 } from './util/base64';
|
|
7
|
-
import 'reflect-metadata';
|
|
8
|
-
|
|
9
|
-
export class JSONEncoder implements MediaTypeEncoder {
|
|
10
|
-
static get default(): JSONEncoder {
|
|
11
|
-
return new JSONEncoder(JSONEncoder.DateEncoding.ISO8601);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
private readonly customSerializers: CustomMapper<Serializer>[];
|
|
15
|
-
private stringifier = new JsonStringifier();
|
|
16
|
-
|
|
17
|
-
constructor(readonly dateEncoding: JSONEncoder.DateEncoding) {
|
|
18
|
-
this.customSerializers = [
|
|
19
|
-
{
|
|
20
|
-
type: () => Date,
|
|
21
|
-
mapper: this.dateSerializer,
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
type: () => DateTime,
|
|
25
|
-
mapper: this.dateTimeSerializer,
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
type: () => URL,
|
|
29
|
-
mapper: this.urlSerializer,
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
type: () => ArrayBuffer,
|
|
33
|
-
mapper: this.arrayBufferSerializer,
|
|
34
|
-
},
|
|
35
|
-
];
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
encode<T>(value: T, type?: AnyType, includeNulls = false): string {
|
|
39
|
-
// Use natural type when subtypes exist
|
|
40
|
-
if (
|
|
41
|
-
Reflect.hasMetadata(
|
|
42
|
-
'jackson:defaultContextGroup:JsonSubTypes',
|
|
43
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
44
|
-
(value as any).constructor ?? {}
|
|
45
|
-
)
|
|
46
|
-
) {
|
|
47
|
-
type = [Object];
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return this.stringifier.stringify(value, {
|
|
51
|
-
serializers: this.customSerializers,
|
|
52
|
-
features: {
|
|
53
|
-
serialization: {
|
|
54
|
-
DEFAULT_PROPERTY_INCLUSION: {
|
|
55
|
-
value: includeNulls
|
|
56
|
-
? JsonIncludeType.ALWAYS
|
|
57
|
-
: JsonIncludeType.NON_NULL,
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
mainCreator: () => type ?? [Object],
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
encodeJSON<T>(value: T, type?: AnyType, includeNulls = false): unknown {
|
|
66
|
-
// Use natural type when subtypes exist
|
|
67
|
-
if (
|
|
68
|
-
Reflect.hasMetadata(
|
|
69
|
-
'jackson:defaultContextGroup:JsonSubTypes',
|
|
70
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
71
|
-
(value as any).constructor ?? {}
|
|
72
|
-
)
|
|
73
|
-
) {
|
|
74
|
-
type = [Object];
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return this.stringifier.transform(value, {
|
|
78
|
-
serializers: this.customSerializers,
|
|
79
|
-
features: {
|
|
80
|
-
serialization: {
|
|
81
|
-
DEFAULT_PROPERTY_INCLUSION: {
|
|
82
|
-
value: includeNulls
|
|
83
|
-
? JsonIncludeType.ALWAYS
|
|
84
|
-
: JsonIncludeType.NON_NULL,
|
|
85
|
-
},
|
|
86
|
-
},
|
|
87
|
-
},
|
|
88
|
-
mainCreator: () => type ?? [Object],
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
private dateTimeSerializer: Serializer = (key: string, value: DateTime) => {
|
|
93
|
-
if (value == null) {
|
|
94
|
-
return null;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
switch (this.dateEncoding) {
|
|
98
|
-
case JSONEncoder.DateEncoding.ISO8601:
|
|
99
|
-
return value.toISO();
|
|
100
|
-
case JSONEncoder.DateEncoding.MILLISECONDS_SINCE_EPOCH:
|
|
101
|
-
return value.toMillis();
|
|
102
|
-
case JSONEncoder.DateEncoding.SECONDS_SINCE_EPOCH:
|
|
103
|
-
return value.toSeconds();
|
|
104
|
-
}
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
private dateSerializer: Serializer = (key: string, value: Date) => {
|
|
108
|
-
if (value == null) {
|
|
109
|
-
return null;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
switch (this.dateEncoding) {
|
|
113
|
-
case JSONEncoder.DateEncoding.ISO8601:
|
|
114
|
-
return value.toISOString();
|
|
115
|
-
case JSONEncoder.DateEncoding.MILLISECONDS_SINCE_EPOCH:
|
|
116
|
-
return value.getTime();
|
|
117
|
-
case JSONEncoder.DateEncoding.SECONDS_SINCE_EPOCH:
|
|
118
|
-
return value.getTime() / 1000;
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
private urlSerializer: Serializer = (key: string, value: URL) => {
|
|
123
|
-
if (value == null) {
|
|
124
|
-
return null;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return value.toString();
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
private arrayBufferSerializer: Serializer = (
|
|
131
|
-
key: string,
|
|
132
|
-
value: ArrayBuffer
|
|
133
|
-
) => {
|
|
134
|
-
if (value == null) {
|
|
135
|
-
return null;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return Base64.encode(value);
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
export namespace JSONEncoder {
|
|
143
|
-
/**
|
|
144
|
-
* Configures how `Date` & `DateTime` parameters are encoded.
|
|
145
|
-
*/
|
|
146
|
-
export enum DateEncoding {
|
|
147
|
-
/**
|
|
148
|
-
* Encode `Date`/`DateTime` values as a UNIX timestamp (floating point seconds since epoch).
|
|
149
|
-
*/
|
|
150
|
-
SECONDS_SINCE_EPOCH,
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Encode `Date`/`DateTime` values as UNIX millisecond timestamp (integer milliseconds since epoch).
|
|
154
|
-
*/
|
|
155
|
-
MILLISECONDS_SINCE_EPOCH,
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Encode `Date`/`DateTime` values as an ISO-8601-formatted string (in RFC 3339 format). This is the default behavior.
|
|
159
|
-
*/
|
|
160
|
-
ISO8601,
|
|
161
|
-
}
|
|
162
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { BinaryDecoder } from './binary-decoder';
|
|
2
|
-
import { CBORDecoder } from './cbor-decoder';
|
|
3
|
-
import { JSONDecoder } from './json-decoder';
|
|
4
|
-
import { MediaType } from './media-type';
|
|
5
|
-
import { MediaTypeDecoder } from './media-type-decoder';
|
|
6
|
-
|
|
7
|
-
export interface MediaTypeDecodersBuilder {
|
|
8
|
-
addDefaults(): MediaTypeDecodersBuilder;
|
|
9
|
-
|
|
10
|
-
add(mediaType: string, decoder: MediaTypeDecoder): MediaTypeDecodersBuilder;
|
|
11
|
-
|
|
12
|
-
build(): MediaTypeDecoders;
|
|
13
|
-
}
|
|
14
|
-
export interface MediaTypeDecodersBuilderConstructor {
|
|
15
|
-
new (): MediaTypeDecodersBuilder;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export class MediaTypeDecoders {
|
|
19
|
-
static Builder: MediaTypeDecodersBuilderConstructor = class Builder
|
|
20
|
-
implements MediaTypeDecodersBuilder {
|
|
21
|
-
decoders = new Map<string, MediaTypeDecoder>();
|
|
22
|
-
|
|
23
|
-
add(
|
|
24
|
-
mediaType: string,
|
|
25
|
-
decoder: MediaTypeDecoder
|
|
26
|
-
): MediaTypeDecodersBuilder {
|
|
27
|
-
this.decoders.set(mediaType, decoder);
|
|
28
|
-
return this;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
addDefaults(): MediaTypeDecodersBuilder {
|
|
32
|
-
return this.add(MediaType.JSON, JSONDecoder.default)
|
|
33
|
-
.add(MediaType.OCTET_STREAM, new BinaryDecoder())
|
|
34
|
-
.add(MediaType.CBOR, CBORDecoder.default);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
build(): MediaTypeDecoders {
|
|
38
|
-
return new MediaTypeDecoders(this.decoders);
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
static DEFAULT: MediaTypeDecoders = new MediaTypeDecoders.Builder()
|
|
43
|
-
.addDefaults()
|
|
44
|
-
.build();
|
|
45
|
-
|
|
46
|
-
constructor(private decoders: Map<string, MediaTypeDecoder>) {}
|
|
47
|
-
|
|
48
|
-
supports(mediaType: string): boolean {
|
|
49
|
-
return this.decoders.has(mediaType);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
find(mediaType: string): MediaTypeDecoder {
|
|
53
|
-
const decoder = this.decoders.get(mediaType);
|
|
54
|
-
if (!decoder) {
|
|
55
|
-
throw Error(`Unsupported media type - ${mediaType}`);
|
|
56
|
-
}
|
|
57
|
-
return decoder;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { AnyType } from './any-type';
|
|
2
|
-
|
|
3
|
-
export interface MediaTypeEncoder {
|
|
4
|
-
encode<T = unknown>(value: T, type: AnyType | undefined): BodyInit;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export interface URLQueryParamsEncoder extends MediaTypeEncoder {
|
|
8
|
-
encodeQueryString(value: Record<string, unknown>): string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function isURLQueryParamsEncoder(
|
|
12
|
-
encoder: MediaTypeEncoder | URLQueryParamsEncoder | undefined
|
|
13
|
-
): encoder is URLQueryParamsEncoder {
|
|
14
|
-
const rec = (encoder as unknown) as Record<string, unknown>;
|
|
15
|
-
return !!rec.encodeQueryString ?? false;
|
|
16
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { BinaryEncoder } from './binary-encoder';
|
|
2
|
-
import { CBOREncoder } from './cbor-encoder';
|
|
3
|
-
import { JSONEncoder } from './json-encoder';
|
|
4
|
-
import { MediaType } from './media-type';
|
|
5
|
-
import { MediaTypeEncoder } from './media-type-encoder';
|
|
6
|
-
import { URLEncoder } from './url-encoder';
|
|
7
|
-
|
|
8
|
-
export interface MediaTypeEncodersBuilder {
|
|
9
|
-
addDefaults(): MediaTypeEncodersBuilder;
|
|
10
|
-
|
|
11
|
-
add(mediaType: string, encoder: MediaTypeEncoder): MediaTypeEncodersBuilder;
|
|
12
|
-
|
|
13
|
-
build(): MediaTypeEncoders;
|
|
14
|
-
}
|
|
15
|
-
export interface MediaTypeEncodersBuilderConstructor {
|
|
16
|
-
new (): MediaTypeEncodersBuilder;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export class MediaTypeEncoders {
|
|
20
|
-
static Builder: MediaTypeEncodersBuilderConstructor = class Builder
|
|
21
|
-
implements MediaTypeEncodersBuilder {
|
|
22
|
-
encoders = new Map<string, MediaTypeEncoder>();
|
|
23
|
-
|
|
24
|
-
add(
|
|
25
|
-
mediaType: string,
|
|
26
|
-
encoder: MediaTypeEncoder
|
|
27
|
-
): MediaTypeEncodersBuilder {
|
|
28
|
-
this.encoders.set(mediaType, encoder);
|
|
29
|
-
return this;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
addDefaults(): MediaTypeEncodersBuilder {
|
|
33
|
-
return this.add(MediaType.JSON, JSONEncoder.default)
|
|
34
|
-
.add(MediaType.OCTET_STREAM, BinaryEncoder.default)
|
|
35
|
-
.add(MediaType.WWW_URL_FORM_ENCODED, URLEncoder.default)
|
|
36
|
-
.add(MediaType.CBOR, CBOREncoder.default);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
build(): MediaTypeEncoders {
|
|
40
|
-
return new MediaTypeEncoders(this.encoders);
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
static DEFAULT: MediaTypeEncoders = new MediaTypeEncoders.Builder()
|
|
45
|
-
.addDefaults()
|
|
46
|
-
.build();
|
|
47
|
-
|
|
48
|
-
constructor(private encoders: Map<string, MediaTypeEncoder>) {}
|
|
49
|
-
|
|
50
|
-
supports(mediaType: string): boolean {
|
|
51
|
-
return this.encoders.has(mediaType);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
find(mediaType: string): MediaTypeEncoder {
|
|
55
|
-
const encoder = this.encoders.get(mediaType);
|
|
56
|
-
if (!encoder) {
|
|
57
|
-
throw Error(`Unsupported media type - ${mediaType}`);
|
|
58
|
-
}
|
|
59
|
-
return encoder;
|
|
60
|
-
}
|
|
61
|
-
}
|
package/src/url-encoder.ts
DELETED
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import { URLQueryParamsEncoder } from './media-type-encoder';
|
|
2
|
-
import { DateTime } from 'luxon';
|
|
3
|
-
import { JsonStringifier } from '@outfoxx/jackson-js';
|
|
4
|
-
|
|
5
|
-
export class URLEncoder implements URLQueryParamsEncoder {
|
|
6
|
-
static get default(): URLEncoder {
|
|
7
|
-
return new URLEncoder(
|
|
8
|
-
URLEncoder.ArrayEncoding.BRACKETED,
|
|
9
|
-
URLEncoder.BoolEncoding.NUMERIC,
|
|
10
|
-
URLEncoder.DateEncoding.ISO8601
|
|
11
|
-
);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
constructor(
|
|
15
|
-
private arrayEncoding: URLEncoder.ArrayEncoding,
|
|
16
|
-
private boolEncoding: URLEncoder.BoolEncoding,
|
|
17
|
-
private dateEncoding: URLEncoder.DateEncoding,
|
|
18
|
-
private json = new JsonStringifier(),
|
|
19
|
-
private encoder = new TextEncoder()
|
|
20
|
-
) {}
|
|
21
|
-
|
|
22
|
-
encode<T = unknown>(value: T): ArrayBuffer | SharedArrayBuffer {
|
|
23
|
-
const parameters = this.json.transform(value);
|
|
24
|
-
|
|
25
|
-
return this.encoder.encode(this.encodeQueryString(parameters));
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
encodeQueryString(parameters: Record<string, unknown>): string {
|
|
29
|
-
const components: [string, string][] = [];
|
|
30
|
-
|
|
31
|
-
for (const key of Object.keys(parameters).sort()) {
|
|
32
|
-
components.push(...this.encodeQueryComponent(key, parameters[key]));
|
|
33
|
-
}
|
|
34
|
-
return components.map((e) => `${e[0]}=${e[1]}`).join('&');
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
encodeQueryComponent(key: string, value: unknown): [string, string][] {
|
|
38
|
-
const components: [string, string][] = [];
|
|
39
|
-
|
|
40
|
-
if (value === undefined) {
|
|
41
|
-
return components;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (value instanceof Array) {
|
|
45
|
-
// encode key according to `arrayEncoding`
|
|
46
|
-
for (const item of value) {
|
|
47
|
-
components.push(
|
|
48
|
-
...this.encodeQueryComponent(
|
|
49
|
-
encodeArrayKey(key, this.arrayEncoding),
|
|
50
|
-
item
|
|
51
|
-
)
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
} else if (DateTime.isDateTime(value) || value instanceof DateTime) {
|
|
55
|
-
//
|
|
56
|
-
components.push([
|
|
57
|
-
encodeURIComponent(key),
|
|
58
|
-
encodeURIComponent(encodeDate(value, this.dateEncoding)),
|
|
59
|
-
]);
|
|
60
|
-
} else if (typeof value === 'boolean') {
|
|
61
|
-
//
|
|
62
|
-
components.push([
|
|
63
|
-
encodeURIComponent(key),
|
|
64
|
-
encodeURIComponent(encodeBoolean(value, this.boolEncoding)),
|
|
65
|
-
]);
|
|
66
|
-
} else if (typeof value === 'object') {
|
|
67
|
-
//
|
|
68
|
-
const rec = (value ?? {}) as Record<string, unknown>;
|
|
69
|
-
|
|
70
|
-
for (const nestedKey of Object.keys(rec)) {
|
|
71
|
-
components.push(
|
|
72
|
-
...this.encodeQueryComponent(`${key}[${nestedKey}]`, rec[nestedKey])
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
} else {
|
|
76
|
-
//
|
|
77
|
-
components.push([
|
|
78
|
-
encodeURIComponent(key),
|
|
79
|
-
encodeURIComponent(`${value}`),
|
|
80
|
-
]);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return components;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function encodeArrayKey(
|
|
88
|
-
key: string,
|
|
89
|
-
encoding: URLEncoder.ArrayEncoding
|
|
90
|
-
): string {
|
|
91
|
-
return encoding === URLEncoder.ArrayEncoding.BRACKETED ? `${key}[]` : key;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function encodeBoolean(
|
|
95
|
-
value: boolean,
|
|
96
|
-
encoding: URLEncoder.BoolEncoding
|
|
97
|
-
): string {
|
|
98
|
-
switch (encoding) {
|
|
99
|
-
case URLEncoder.BoolEncoding.NUMERIC:
|
|
100
|
-
return value ? '1' : '0';
|
|
101
|
-
case URLEncoder.BoolEncoding.LITERAL:
|
|
102
|
-
return value ? 'true' : 'false';
|
|
103
|
-
default:
|
|
104
|
-
throw new Error('unknown boolean encoding');
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function encodeDate(
|
|
109
|
-
value: Date | DateTime,
|
|
110
|
-
encoding: URLEncoder.DateEncoding
|
|
111
|
-
): string {
|
|
112
|
-
value = value instanceof Date ? DateTime.fromJSDate(value) : value;
|
|
113
|
-
switch (encoding) {
|
|
114
|
-
case URLEncoder.DateEncoding.SECONDS_SINCE_EPOCH:
|
|
115
|
-
return `${value.toSeconds()}`;
|
|
116
|
-
case URLEncoder.DateEncoding.MILLISECONDS_SINCE_EPOCH:
|
|
117
|
-
return `${value.toMillis()}`;
|
|
118
|
-
case URLEncoder.DateEncoding.ISO8601:
|
|
119
|
-
return value.toISO();
|
|
120
|
-
default:
|
|
121
|
-
throw new Error('unknown date encoding');
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
export namespace URLEncoder {
|
|
126
|
-
/**
|
|
127
|
-
* Configures how `Array` parameters are encoded.
|
|
128
|
-
*/
|
|
129
|
-
export enum ArrayEncoding {
|
|
130
|
-
/**
|
|
131
|
-
* An empty set of square brackets is appended to the key for every value. This is the default behavior.
|
|
132
|
-
*/
|
|
133
|
-
BRACKETED,
|
|
134
|
-
/**
|
|
135
|
-
* No brackets are appended. The key is encoded as is.
|
|
136
|
-
*/
|
|
137
|
-
UNBRACKETED,
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Configures how `Bool` parameters are encoded.
|
|
142
|
-
*/
|
|
143
|
-
export enum BoolEncoding {
|
|
144
|
-
/**
|
|
145
|
-
* Encode `true` as `1` and `false` as `0`. This is the default behavior.
|
|
146
|
-
*/
|
|
147
|
-
NUMERIC,
|
|
148
|
-
/**
|
|
149
|
-
* Encode `true` and `false` as string literals.
|
|
150
|
-
*/
|
|
151
|
-
LITERAL,
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Configures how `Date` parameters are encoded.
|
|
156
|
-
*/
|
|
157
|
-
export enum DateEncoding {
|
|
158
|
-
/**
|
|
159
|
-
* Encode the `Date` as a UNIX timestamp (floating point seconds since epoch).
|
|
160
|
-
*/
|
|
161
|
-
SECONDS_SINCE_EPOCH,
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Encode the `Date` as UNIX millisecond timestamp (integer milliseconds since epoch).
|
|
165
|
-
*/
|
|
166
|
-
MILLISECONDS_SINCE_EPOCH,
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Encode the `Date` as an ISO-8601-formatted string (in RFC 3339 format). This is the default behavior.
|
|
170
|
-
*/
|
|
171
|
-
ISO8601,
|
|
172
|
-
}
|
|
173
|
-
}
|