@outfoxx/sunday 1.1.0-alpha.8 → 1.1.0-beta.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/LICENSE.txt +203 -0
- package/README.md +6 -7
- package/dist/any-type.js +13 -0
- package/dist/any-type.js.map +1 -1
- package/dist/class-type.js +13 -0
- package/dist/class-type.js.map +1 -1
- package/dist/date-time-types.js +13 -0
- package/dist/date-time-types.js.map +1 -1
- package/dist/event-parser.d.ts +1 -1
- package/dist/event-parser.js +17 -4
- package/dist/event-parser.js.map +1 -1
- package/dist/fetch-event-source.d.ts +5 -1
- package/dist/fetch-event-source.js +15 -3
- package/dist/fetch-event-source.js.map +1 -1
- package/dist/fetch-request-factory.d.ts +3 -0
- package/dist/fetch-request-factory.js +47 -9
- package/dist/fetch-request-factory.js.map +1 -1
- package/dist/fetch.js +24 -5
- package/dist/fetch.js.map +1 -1
- package/dist/header-parameters.js +13 -0
- package/dist/header-parameters.js.map +1 -1
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -1
- package/dist/logger.js +13 -0
- package/dist/logger.js.map +1 -1
- package/dist/media-type-codecs/any-text-decoder.d.ts +7 -0
- package/dist/media-type-codecs/any-text-decoder.js +29 -0
- package/dist/media-type-codecs/any-text-decoder.js.map +1 -0
- package/dist/media-type-codecs/any-text-encoder.d.ts +5 -0
- package/dist/media-type-codecs/any-text-encoder.js +23 -0
- package/dist/media-type-codecs/any-text-encoder.js.map +1 -0
- package/dist/media-type-codecs/binary-decoder.js +13 -0
- package/dist/media-type-codecs/binary-decoder.js.map +1 -1
- package/dist/media-type-codecs/binary-encoder.js +13 -0
- package/dist/media-type-codecs/binary-encoder.js.map +1 -1
- package/dist/media-type-codecs/cbor-decoder.js +13 -0
- package/dist/media-type-codecs/cbor-decoder.js.map +1 -1
- package/dist/media-type-codecs/cbor-encoder.js +13 -0
- package/dist/media-type-codecs/cbor-encoder.js.map +1 -1
- package/dist/media-type-codecs/cbor-tags.js +13 -0
- package/dist/media-type-codecs/cbor-tags.js.map +1 -1
- package/dist/media-type-codecs/json-decoder.js +13 -0
- package/dist/media-type-codecs/json-decoder.js.map +1 -1
- package/dist/media-type-codecs/json-encoder.js +13 -0
- package/dist/media-type-codecs/json-encoder.js.map +1 -1
- package/dist/media-type-codecs/media-type-decoder.js +13 -0
- package/dist/media-type-codecs/media-type-decoder.js.map +1 -1
- package/dist/media-type-codecs/media-type-decoders.js +21 -3
- package/dist/media-type-codecs/media-type-decoders.js.map +1 -1
- package/dist/media-type-codecs/media-type-encoder.js +13 -0
- package/dist/media-type-codecs/media-type-encoder.js.map +1 -1
- package/dist/media-type-codecs/media-type-encoders.js +21 -3
- package/dist/media-type-codecs/media-type-encoders.js.map +1 -1
- package/dist/media-type-codecs/www-form-url-encoder.js +56 -6
- package/dist/media-type-codecs/www-form-url-encoder.js.map +1 -1
- package/dist/media-type.d.ts +4 -2
- package/dist/media-type.js +34 -5
- package/dist/media-type.js.map +1 -1
- package/dist/problem.js +19 -2
- package/dist/problem.js.map +1 -1
- package/dist/request-factory.d.ts +6 -0
- package/dist/request-factory.js +13 -0
- package/dist/request-factory.js.map +1 -1
- package/dist/result-response.d.ts +4 -0
- package/dist/result-response.js +15 -0
- package/dist/result-response.js.map +1 -0
- package/dist/sunday-error.js +13 -0
- package/dist/sunday-error.js.map +1 -1
- package/dist/url-template.js +13 -0
- package/dist/url-template.js.map +1 -1
- package/dist/util/any.js +13 -0
- package/dist/util/any.js.map +1 -1
- 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 +13 -0
- package/dist/util/hex.js.map +1 -1
- package/dist/util/rxjs.js +14 -2
- 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.js +13 -0
- package/dist/util/temporal.js.map +1 -1
- package/package.json +33 -28
- package/src/any-type.ts +14 -0
- package/src/class-type.ts +16 -2
- package/src/date-time-types.ts +14 -0
- package/src/event-parser.ts +22 -10
- package/src/fetch-event-source.ts +39 -11
- package/src/fetch-request-factory.ts +92 -32
- package/src/fetch.ts +27 -8
- package/src/header-parameters.ts +16 -2
- package/src/index.ts +14 -0
- package/src/logger.ts +14 -0
- package/src/media-type-codecs/any-text-decoder.ts +34 -0
- package/src/media-type-codecs/any-text-encoder.ts +26 -0
- package/src/media-type-codecs/binary-decoder.ts +16 -2
- package/src/media-type-codecs/binary-encoder.ts +15 -1
- package/src/media-type-codecs/cbor-decoder.ts +30 -16
- package/src/media-type-codecs/cbor-encoder.ts +28 -14
- package/src/media-type-codecs/cbor-tags.ts +14 -0
- package/src/media-type-codecs/json-decoder.ts +31 -16
- package/src/media-type-codecs/json-encoder.ts +21 -7
- package/src/media-type-codecs/media-type-decoder.ts +16 -2
- package/src/media-type-codecs/media-type-decoders.ts +28 -8
- package/src/media-type-codecs/media-type-encoder.ts +19 -5
- package/src/media-type-codecs/media-type-encoders.ts +28 -8
- package/src/media-type-codecs/www-form-url-encoder.ts +81 -17
- package/src/media-type.ts +46 -12
- package/src/problem.ts +22 -4
- package/src/request-factory.ts +46 -7
- package/src/result-response.ts +18 -0
- package/src/sunday-error.ts +18 -4
- package/src/url-template.ts +15 -1
- package/src/util/any.ts +14 -0
- package/src/util/base64.ts +15 -1
- package/src/util/error.ts +28 -0
- package/src/util/hex.ts +14 -0
- package/src/util/rxjs.ts +18 -5
- package/src/util/stream-rxjs.ts +15 -1
- package/src/util/temporal.ts +14 -0
|
@@ -1,4 +1,19 @@
|
|
|
1
|
+
// Copyright 2020 Outfox, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
1
15
|
import { MediaType } from '../media-type';
|
|
16
|
+
import { AnyTextEncoder } from './any-text-encoder';
|
|
2
17
|
import { BinaryEncoder } from './binary-encoder';
|
|
3
18
|
import { CBOREncoder } from './cbor-encoder';
|
|
4
19
|
import { JSONEncoder } from './json-encoder';
|
|
@@ -10,7 +25,7 @@ export interface MediaTypeEncodersBuilder {
|
|
|
10
25
|
|
|
11
26
|
add(
|
|
12
27
|
mediaType: MediaType,
|
|
13
|
-
encoder: MediaTypeEncoder
|
|
28
|
+
encoder: MediaTypeEncoder,
|
|
14
29
|
): MediaTypeEncodersBuilder;
|
|
15
30
|
|
|
16
31
|
build(): MediaTypeEncoders;
|
|
@@ -21,22 +36,27 @@ export interface MediaTypeEncodersBuilderConstructor {
|
|
|
21
36
|
|
|
22
37
|
export class MediaTypeEncoders {
|
|
23
38
|
static Builder: MediaTypeEncodersBuilderConstructor = class Builder
|
|
24
|
-
implements MediaTypeEncodersBuilder
|
|
39
|
+
implements MediaTypeEncodersBuilder
|
|
40
|
+
{
|
|
25
41
|
encoders = new Map<MediaType, MediaTypeEncoder>();
|
|
26
42
|
|
|
27
43
|
add(
|
|
28
44
|
mediaType: MediaType,
|
|
29
|
-
encoder: MediaTypeEncoder
|
|
45
|
+
encoder: MediaTypeEncoder,
|
|
30
46
|
): MediaTypeEncodersBuilder {
|
|
31
47
|
this.encoders.set(mediaType, encoder);
|
|
32
48
|
return this;
|
|
33
49
|
}
|
|
34
50
|
|
|
35
51
|
addDefaults(): MediaTypeEncodersBuilder {
|
|
36
|
-
return this.add(MediaType.
|
|
37
|
-
.add(MediaType.OctetStream, BinaryEncoder.default)
|
|
52
|
+
return this.add(MediaType.OctetStream, BinaryEncoder.default)
|
|
38
53
|
.add(MediaType.WWWFormUrlEncoded, WWWFormUrlEncoder.default)
|
|
39
|
-
.add(MediaType.
|
|
54
|
+
.add(MediaType.JSON, JSONEncoder.default)
|
|
55
|
+
.add(MediaType.JSONStructured, JSONEncoder.default)
|
|
56
|
+
.add(MediaType.CBOR, CBOREncoder.default)
|
|
57
|
+
.add(MediaType.AnyText, AnyTextEncoder.default)
|
|
58
|
+
.add(MediaType.X509CACert, BinaryEncoder.default)
|
|
59
|
+
.add(MediaType.X509UserCert, BinaryEncoder.default);
|
|
40
60
|
}
|
|
41
61
|
|
|
42
62
|
build(): MediaTypeEncoders {
|
|
@@ -52,13 +72,13 @@ export class MediaTypeEncoders {
|
|
|
52
72
|
|
|
53
73
|
supports(mediaType: MediaType): boolean {
|
|
54
74
|
return Array.from(this.encoders.keys()).some((key) =>
|
|
55
|
-
key.compatible(mediaType)
|
|
75
|
+
key.compatible(mediaType),
|
|
56
76
|
);
|
|
57
77
|
}
|
|
58
78
|
|
|
59
79
|
find(mediaType: MediaType): MediaTypeEncoder {
|
|
60
80
|
const found = Array.from(this.encoders.entries()).find(([type]) =>
|
|
61
|
-
type.compatible(mediaType)
|
|
81
|
+
type.compatible(mediaType),
|
|
62
82
|
);
|
|
63
83
|
if (!found) {
|
|
64
84
|
throw Error(`Unsupported media type - ${mediaType}`);
|
|
@@ -1,4 +1,28 @@
|
|
|
1
|
-
|
|
1
|
+
// Copyright 2020 Outfox, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
DateTimeFormatter,
|
|
17
|
+
Instant,
|
|
18
|
+
LocalDate,
|
|
19
|
+
LocalDateTime,
|
|
20
|
+
LocalTime,
|
|
21
|
+
OffsetDateTime,
|
|
22
|
+
OffsetTime,
|
|
23
|
+
Temporal,
|
|
24
|
+
ZonedDateTime,
|
|
25
|
+
} from '@js-joda/core';
|
|
2
26
|
import { JsonStringifier } from '@outfoxx/jackson-js';
|
|
3
27
|
import { URLQueryParamsEncoder } from './media-type-encoder';
|
|
4
28
|
|
|
@@ -7,7 +31,7 @@ export class WWWFormUrlEncoder implements URLQueryParamsEncoder {
|
|
|
7
31
|
return new WWWFormUrlEncoder(
|
|
8
32
|
WWWFormUrlEncoder.ArrayEncoding.UNBRACKETED,
|
|
9
33
|
WWWFormUrlEncoder.BoolEncoding.LITERAL,
|
|
10
|
-
WWWFormUrlEncoder.DateEncoding.DECIMAL_SECONDS_SINCE_EPOCH
|
|
34
|
+
WWWFormUrlEncoder.DateEncoding.DECIMAL_SECONDS_SINCE_EPOCH,
|
|
11
35
|
);
|
|
12
36
|
}
|
|
13
37
|
|
|
@@ -16,7 +40,7 @@ export class WWWFormUrlEncoder implements URLQueryParamsEncoder {
|
|
|
16
40
|
private boolEncoding: WWWFormUrlEncoder.BoolEncoding,
|
|
17
41
|
private dateEncoding: WWWFormUrlEncoder.DateEncoding,
|
|
18
42
|
private json = new JsonStringifier(),
|
|
19
|
-
private encoder = new TextEncoder()
|
|
43
|
+
private encoder = new TextEncoder(),
|
|
20
44
|
) {}
|
|
21
45
|
|
|
22
46
|
encode<T = unknown>(value: T): ArrayBuffer | SharedArrayBuffer {
|
|
@@ -50,23 +74,35 @@ export class WWWFormUrlEncoder implements URLQueryParamsEncoder {
|
|
|
50
74
|
components.push(
|
|
51
75
|
...this.encodeQueryComponent(
|
|
52
76
|
encodeArrayKey(key, this.arrayEncoding),
|
|
53
|
-
item
|
|
54
|
-
)
|
|
77
|
+
item,
|
|
78
|
+
),
|
|
55
79
|
);
|
|
56
80
|
}
|
|
57
|
-
} else if (value instanceof
|
|
81
|
+
} else if (value instanceof Date) {
|
|
58
82
|
//
|
|
59
83
|
components.push(
|
|
60
84
|
encodeURIComponent(key) +
|
|
61
85
|
'=' +
|
|
62
|
-
encodeURIComponent(
|
|
86
|
+
encodeURIComponent(
|
|
87
|
+
encodeInstant(
|
|
88
|
+
Instant.ofEpochMilli(value.getTime()),
|
|
89
|
+
this.dateEncoding,
|
|
90
|
+
),
|
|
91
|
+
),
|
|
92
|
+
);
|
|
93
|
+
} else if (value instanceof Temporal) {
|
|
94
|
+
//
|
|
95
|
+
components.push(
|
|
96
|
+
encodeURIComponent(key) +
|
|
97
|
+
'=' +
|
|
98
|
+
encodeURIComponent(encodeTemporal(value, this.dateEncoding)),
|
|
63
99
|
);
|
|
64
100
|
} else if (typeof value === 'boolean') {
|
|
65
101
|
//
|
|
66
102
|
components.push(
|
|
67
103
|
encodeURIComponent(key) +
|
|
68
104
|
'=' +
|
|
69
|
-
encodeURIComponent(encodeBoolean(value, this.boolEncoding))
|
|
105
|
+
encodeURIComponent(encodeBoolean(value, this.boolEncoding)),
|
|
70
106
|
);
|
|
71
107
|
} else if (typeof value === 'object') {
|
|
72
108
|
//
|
|
@@ -74,13 +110,13 @@ export class WWWFormUrlEncoder implements URLQueryParamsEncoder {
|
|
|
74
110
|
|
|
75
111
|
for (const nestedKey of Object.keys(rec).sort()) {
|
|
76
112
|
components.push(
|
|
77
|
-
...this.encodeQueryComponent(`${key}[${nestedKey}]`, rec[nestedKey])
|
|
113
|
+
...this.encodeQueryComponent(`${key}[${nestedKey}]`, rec[nestedKey]),
|
|
78
114
|
);
|
|
79
115
|
}
|
|
80
116
|
} else {
|
|
81
117
|
//
|
|
82
118
|
components.push(
|
|
83
|
-
encodeURIComponent(key) + '=' + encodeURIComponent(`${value}`)
|
|
119
|
+
encodeURIComponent(key) + '=' + encodeURIComponent(`${value}`),
|
|
84
120
|
);
|
|
85
121
|
}
|
|
86
122
|
|
|
@@ -90,7 +126,7 @@ export class WWWFormUrlEncoder implements URLQueryParamsEncoder {
|
|
|
90
126
|
|
|
91
127
|
function encodeArrayKey(
|
|
92
128
|
key: string,
|
|
93
|
-
encoding: WWWFormUrlEncoder.ArrayEncoding
|
|
129
|
+
encoding: WWWFormUrlEncoder.ArrayEncoding,
|
|
94
130
|
): string {
|
|
95
131
|
return encoding === WWWFormUrlEncoder.ArrayEncoding.BRACKETED
|
|
96
132
|
? `${key}[]`
|
|
@@ -99,7 +135,7 @@ function encodeArrayKey(
|
|
|
99
135
|
|
|
100
136
|
function encodeBoolean(
|
|
101
137
|
value: boolean,
|
|
102
|
-
encoding: WWWFormUrlEncoder.BoolEncoding
|
|
138
|
+
encoding: WWWFormUrlEncoder.BoolEncoding,
|
|
103
139
|
): string {
|
|
104
140
|
switch (encoding) {
|
|
105
141
|
case WWWFormUrlEncoder.BoolEncoding.NUMERIC:
|
|
@@ -111,18 +147,46 @@ function encodeBoolean(
|
|
|
111
147
|
}
|
|
112
148
|
}
|
|
113
149
|
|
|
114
|
-
function
|
|
115
|
-
value:
|
|
116
|
-
encoding: WWWFormUrlEncoder.DateEncoding
|
|
150
|
+
function encodeTemporal(
|
|
151
|
+
value: Temporal,
|
|
152
|
+
encoding: WWWFormUrlEncoder.DateEncoding,
|
|
153
|
+
): string {
|
|
154
|
+
if (value instanceof Instant) {
|
|
155
|
+
return encodeInstant(value, encoding);
|
|
156
|
+
} else if (value instanceof OffsetDateTime) {
|
|
157
|
+
if (encoding == WWWFormUrlEncoder.DateEncoding.ISO8601) {
|
|
158
|
+
return value.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
|
|
159
|
+
}
|
|
160
|
+
return encodeInstant(value.toInstant(), encoding);
|
|
161
|
+
} else if (value instanceof ZonedDateTime) {
|
|
162
|
+
if (encoding == WWWFormUrlEncoder.DateEncoding.ISO8601) {
|
|
163
|
+
return value.format(DateTimeFormatter.ISO_ZONED_DATE_TIME);
|
|
164
|
+
}
|
|
165
|
+
return encodeInstant(value.toInstant(), encoding);
|
|
166
|
+
} else if (value instanceof LocalDateTime) {
|
|
167
|
+
return value.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
|
|
168
|
+
} else if (value instanceof LocalDate) {
|
|
169
|
+
return value.format(DateTimeFormatter.ISO_LOCAL_DATE);
|
|
170
|
+
} else if (value instanceof LocalTime) {
|
|
171
|
+
return value.format(DateTimeFormatter.ISO_LOCAL_TIME);
|
|
172
|
+
} else if (value instanceof OffsetTime) {
|
|
173
|
+
return value.format(DateTimeFormatter.ISO_OFFSET_TIME);
|
|
174
|
+
} else {
|
|
175
|
+
throw Error('unsupported temporal value for ');
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function encodeInstant(
|
|
180
|
+
value: Instant,
|
|
181
|
+
encoding: WWWFormUrlEncoder.DateEncoding,
|
|
117
182
|
): string {
|
|
118
|
-
value = value instanceof Date ? Instant.ofEpochMilli(value.getTime()) : value;
|
|
119
183
|
switch (encoding) {
|
|
120
184
|
case WWWFormUrlEncoder.DateEncoding.DECIMAL_SECONDS_SINCE_EPOCH:
|
|
121
185
|
return (value.epochSecond() + value.nano() / 1_000_000_000.0).toFixed(7);
|
|
122
186
|
case WWWFormUrlEncoder.DateEncoding.MILLISECONDS_SINCE_EPOCH:
|
|
123
187
|
return `${value.toEpochMilli()}`;
|
|
124
188
|
case WWWFormUrlEncoder.DateEncoding.ISO8601:
|
|
125
|
-
return
|
|
189
|
+
return DateTimeFormatter.ISO_INSTANT.format(value);
|
|
126
190
|
default:
|
|
127
191
|
throw new Error('unknown date encoding');
|
|
128
192
|
}
|
package/src/media-type.ts
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
// Copyright 2020 Outfox, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
1
15
|
export class MediaType {
|
|
2
16
|
type: MediaType.Type;
|
|
3
17
|
tree: MediaType.Tree;
|
|
@@ -21,7 +35,7 @@ export class MediaType {
|
|
|
21
35
|
obj[name.toLowerCase()] = value.toLowerCase();
|
|
22
36
|
return obj;
|
|
23
37
|
},
|
|
24
|
-
{} as Record<string, string
|
|
38
|
+
{} as Record<string, string>,
|
|
25
39
|
);
|
|
26
40
|
}
|
|
27
41
|
|
|
@@ -47,7 +61,7 @@ export class MediaType {
|
|
|
47
61
|
|
|
48
62
|
withParameter(
|
|
49
63
|
parameter: MediaType.ParameterName | string,
|
|
50
|
-
value: string
|
|
64
|
+
value: string,
|
|
51
65
|
): MediaType {
|
|
52
66
|
const parameters = Object.assign({}, this.parameters, {
|
|
53
67
|
[parameter]: value,
|
|
@@ -181,28 +195,35 @@ export namespace MediaType {
|
|
|
181
195
|
CharSet = 'charset',
|
|
182
196
|
}
|
|
183
197
|
|
|
184
|
-
export function from(value?: string | null): MediaType
|
|
198
|
+
export function from(value?: string | null): MediaType;
|
|
185
199
|
export function from(
|
|
186
200
|
value: string | null | undefined,
|
|
187
|
-
def: MediaType
|
|
201
|
+
def: MediaType,
|
|
188
202
|
): MediaType;
|
|
189
203
|
export function from(
|
|
190
204
|
value?: string | null,
|
|
191
|
-
def: MediaType | undefined = undefined
|
|
192
|
-
): MediaType
|
|
193
|
-
|
|
205
|
+
def: MediaType | undefined = undefined,
|
|
206
|
+
): MediaType {
|
|
207
|
+
const reqDef = () => {
|
|
208
|
+
if (!def) {
|
|
209
|
+
throw Error('Invalid media type');
|
|
210
|
+
}
|
|
194
211
|
return def;
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
if (!value) {
|
|
215
|
+
return reqDef();
|
|
195
216
|
}
|
|
196
217
|
|
|
197
218
|
fullRegex.lastIndex = 0;
|
|
198
219
|
const match = fullRegex.exec(value);
|
|
199
220
|
if (match?.[0] != value) {
|
|
200
|
-
return
|
|
221
|
+
return reqDef();
|
|
201
222
|
}
|
|
202
223
|
|
|
203
224
|
const type = MediaType.Type.from(match[1]?.toLowerCase());
|
|
204
225
|
if (!type) {
|
|
205
|
-
return
|
|
226
|
+
return reqDef();
|
|
206
227
|
}
|
|
207
228
|
|
|
208
229
|
const tree =
|
|
@@ -210,7 +231,7 @@ export namespace MediaType {
|
|
|
210
231
|
|
|
211
232
|
const subtype = match[3]?.toLowerCase();
|
|
212
233
|
if (!subtype) {
|
|
213
|
-
return
|
|
234
|
+
return reqDef();
|
|
214
235
|
}
|
|
215
236
|
|
|
216
237
|
const suffix = MediaType.Suffix.from(match[4]?.toLowerCase());
|
|
@@ -239,7 +260,8 @@ export namespace MediaType {
|
|
|
239
260
|
});
|
|
240
261
|
}
|
|
241
262
|
|
|
242
|
-
const fullRegex =
|
|
263
|
+
const fullRegex =
|
|
264
|
+
/^((?:[a-z]+|\*))\/(x(?:-|\\.)|(?:(?:vnd|prs|x)\.)|\*)?([a-z0-9\-.]+|\*)(?:\+([a-z]+))?( *(?:; *(?:(?:[\w.-]+) *= *(?:[\w.-]+)) *)*)$/gi;
|
|
243
265
|
const paramRegex = / *; *([\w.-]+) *= *([\w.-]+)/gi;
|
|
244
266
|
|
|
245
267
|
export const Plain = new MediaType({
|
|
@@ -320,9 +342,21 @@ export namespace MediaType {
|
|
|
320
342
|
suffix: Suffix.XML,
|
|
321
343
|
});
|
|
322
344
|
|
|
323
|
-
export const
|
|
345
|
+
export const Problem = new MediaType({
|
|
324
346
|
type: MediaType.Type.Application,
|
|
325
347
|
subtype: 'problem',
|
|
326
348
|
suffix: Suffix.JSON,
|
|
327
349
|
});
|
|
350
|
+
|
|
351
|
+
export const JsonPatch = new MediaType({
|
|
352
|
+
type: MediaType.Type.Application,
|
|
353
|
+
subtype: 'json-patch',
|
|
354
|
+
suffix: Suffix.JSON,
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
export const MergePatch = new MediaType({
|
|
358
|
+
type: MediaType.Type.Application,
|
|
359
|
+
subtype: 'merge-patch',
|
|
360
|
+
suffix: Suffix.JSON,
|
|
361
|
+
});
|
|
328
362
|
}
|
package/src/problem.ts
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
// Copyright 2020 Outfox, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
1
15
|
import { ResponseExample } from './fetch';
|
|
2
16
|
import {
|
|
3
17
|
JsonAnyGetter,
|
|
@@ -67,7 +81,7 @@ export class Problem extends Error implements Problem {
|
|
|
67
81
|
constructor(spec: ProblemSpec) {
|
|
68
82
|
super(`${spec.status.toString()} ${spec.type} - ${spec.title}`);
|
|
69
83
|
|
|
70
|
-
const src =
|
|
84
|
+
const src = spec as unknown as Record<string, unknown>;
|
|
71
85
|
|
|
72
86
|
const json = Object.assign({}, src);
|
|
73
87
|
|
|
@@ -118,7 +132,7 @@ export class Problem extends Error implements Problem {
|
|
|
118
132
|
static async fromResponse(response: Response): Promise<Problem> {
|
|
119
133
|
const [bodyExcerpt, body] = await ResponseExample.bodyExcerpt(
|
|
120
134
|
response,
|
|
121
|
-
256
|
|
135
|
+
256,
|
|
122
136
|
);
|
|
123
137
|
|
|
124
138
|
return new Problem({
|
|
@@ -129,9 +143,13 @@ export class Problem extends Error implements Problem {
|
|
|
129
143
|
url: response.url,
|
|
130
144
|
},
|
|
131
145
|
response: {
|
|
132
|
-
type: response.type,
|
|
133
146
|
headers: response.headers,
|
|
134
|
-
|
|
147
|
+
ok: response.ok,
|
|
148
|
+
redirected: response.redirected,
|
|
149
|
+
status: response.status,
|
|
150
|
+
statusText: response.statusText,
|
|
151
|
+
type: response.type,
|
|
152
|
+
url: response.url,
|
|
135
153
|
body,
|
|
136
154
|
example: ResponseExample.build(response, bodyExcerpt),
|
|
137
155
|
},
|
package/src/request-factory.ts
CHANGED
|
@@ -1,9 +1,24 @@
|
|
|
1
|
+
// Copyright 2020 Outfox, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
1
15
|
import { Observable } from 'rxjs';
|
|
2
16
|
import { AnyType } from './any-type';
|
|
3
17
|
import { ClassType, ConstructableClassType } from './class-type';
|
|
4
18
|
import { MediaType } from './media-type';
|
|
5
19
|
import { TextMediaTypeDecoder } from './media-type-codecs/media-type-decoder';
|
|
6
20
|
import { Problem } from './problem';
|
|
21
|
+
import { ResultResponse } from './result-response';
|
|
7
22
|
import { URLTemplate } from './url-template';
|
|
8
23
|
import { Logger } from './logger';
|
|
9
24
|
|
|
@@ -12,7 +27,7 @@ export interface RequestFactory {
|
|
|
12
27
|
|
|
13
28
|
registerProblem(
|
|
14
29
|
type: URL | string,
|
|
15
|
-
problemType: ConstructableClassType<Problem
|
|
30
|
+
problemType: ConstructableClassType<Problem>,
|
|
16
31
|
): void;
|
|
17
32
|
|
|
18
33
|
request(requestSpec: RequestSpec<unknown>): Observable<Request>;
|
|
@@ -21,22 +36,46 @@ export interface RequestFactory {
|
|
|
21
36
|
|
|
22
37
|
response<B>(
|
|
23
38
|
requestSpec: RequestSpec<B>,
|
|
24
|
-
dataExpected?: boolean
|
|
39
|
+
dataExpected?: boolean,
|
|
25
40
|
): Observable<Response>;
|
|
26
41
|
|
|
42
|
+
resultResponse<B, R>(
|
|
43
|
+
requestSpec: RequestSpec<B>,
|
|
44
|
+
resultType: [ClassType<R>],
|
|
45
|
+
): Observable<ResultResponse<R>>;
|
|
46
|
+
|
|
47
|
+
resultResponse<B, R>(
|
|
48
|
+
requestSpec: RequestSpec<B>,
|
|
49
|
+
resultType: [ClassType<Array<unknown>>, ClassType<R>],
|
|
50
|
+
): Observable<ResultResponse<Array<R>>>;
|
|
51
|
+
|
|
52
|
+
resultResponse<B, R>(
|
|
53
|
+
requestSpec: RequestSpec<B>,
|
|
54
|
+
resultType: [ClassType<Set<unknown>>, ClassType<R>],
|
|
55
|
+
): Observable<ResultResponse<Set<R>>>;
|
|
56
|
+
|
|
57
|
+
resultResponse<B, R>(
|
|
58
|
+
requestSpec: RequestSpec<B>,
|
|
59
|
+
resultType: AnyType,
|
|
60
|
+
): Observable<ResultResponse<R>>;
|
|
61
|
+
|
|
62
|
+
resultResponse<B>(
|
|
63
|
+
requestSpec: RequestSpec<B>,
|
|
64
|
+
): Observable<ResultResponse<void>>;
|
|
65
|
+
|
|
27
66
|
result<B, R>(
|
|
28
67
|
requestSpec: RequestSpec<B>,
|
|
29
|
-
resultType: [ClassType<R>]
|
|
68
|
+
resultType: [ClassType<R>],
|
|
30
69
|
): Observable<R>;
|
|
31
70
|
|
|
32
71
|
result<B, R>(
|
|
33
72
|
requestSpec: RequestSpec<B>,
|
|
34
|
-
resultType: [ClassType<Array<unknown>>, ClassType<R>]
|
|
73
|
+
resultType: [ClassType<Array<unknown>>, ClassType<R>],
|
|
35
74
|
): Observable<Array<R>>;
|
|
36
75
|
|
|
37
76
|
result<B, R>(
|
|
38
77
|
requestSpec: RequestSpec<B>,
|
|
39
|
-
resultType: [ClassType<Set<unknown>>, ClassType<R>]
|
|
78
|
+
resultType: [ClassType<Set<unknown>>, ClassType<R>],
|
|
40
79
|
): Observable<Set<R>>;
|
|
41
80
|
|
|
42
81
|
result<B, R>(requestSpec: RequestSpec<B>, resultType: AnyType): Observable<R>;
|
|
@@ -52,8 +91,8 @@ export interface RequestFactory {
|
|
|
52
91
|
event: string | undefined,
|
|
53
92
|
id: string | undefined,
|
|
54
93
|
data: string,
|
|
55
|
-
logger?: Logger
|
|
56
|
-
) => E | undefined
|
|
94
|
+
logger?: Logger,
|
|
95
|
+
) => E | undefined,
|
|
57
96
|
): Observable<E>;
|
|
58
97
|
}
|
|
59
98
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Copyright 2020 Outfox, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
export interface ResultResponse<R> {
|
|
16
|
+
readonly result: R;
|
|
17
|
+
readonly response: Response;
|
|
18
|
+
}
|
package/src/sunday-error.ts
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
// Copyright 2020 Outfox, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
1
15
|
import { ResponseExample } from './fetch';
|
|
2
16
|
|
|
3
17
|
export class SundayError extends Error {
|
|
@@ -9,18 +23,18 @@ export class SundayError extends Error {
|
|
|
9
23
|
public statusText: string,
|
|
10
24
|
public headers: Headers,
|
|
11
25
|
public body: unknown | undefined,
|
|
12
|
-
public responseExample: string
|
|
26
|
+
public responseExample: string,
|
|
13
27
|
) {
|
|
14
28
|
super(message);
|
|
15
29
|
}
|
|
16
30
|
|
|
17
31
|
static async fromResponse(
|
|
18
32
|
message: string,
|
|
19
|
-
response: Response
|
|
33
|
+
response: Response,
|
|
20
34
|
): Promise<SundayError> {
|
|
21
35
|
const [bodyExcerpt, body] = await ResponseExample.bodyExcerpt(
|
|
22
36
|
response,
|
|
23
|
-
256
|
|
37
|
+
256,
|
|
24
38
|
);
|
|
25
39
|
|
|
26
40
|
return new SundayError(
|
|
@@ -31,7 +45,7 @@ export class SundayError extends Error {
|
|
|
31
45
|
response.statusText,
|
|
32
46
|
response.headers,
|
|
33
47
|
body,
|
|
34
|
-
ResponseExample.build(response, bodyExcerpt)
|
|
48
|
+
ResponseExample.build(response, bodyExcerpt),
|
|
35
49
|
);
|
|
36
50
|
}
|
|
37
51
|
}
|
package/src/url-template.ts
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
|
+
// Copyright 2020 Outfox, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
1
15
|
import { URI } from 'uri-template-lite';
|
|
2
16
|
|
|
3
17
|
export class URLTemplate {
|
|
4
18
|
constructor(
|
|
5
19
|
public template: string,
|
|
6
|
-
public parameters: Record<string, unknown> = {}
|
|
20
|
+
public parameters: Record<string, unknown> = {},
|
|
7
21
|
) {}
|
|
8
22
|
|
|
9
23
|
complete(relativeTemplate: string, parameters: Record<string, unknown>): URL {
|
package/src/util/any.ts
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
// Copyright 2020 Outfox, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
1
15
|
export function unknownGet<T = unknown>(obj: unknown, key: string): T {
|
|
2
16
|
return (obj as Record<string, unknown>)?.[key] as T;
|
|
3
17
|
}
|
package/src/util/base64.ts
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
// Copyright 2020 Outfox, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
1
15
|
const chars =
|
|
2
16
|
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
3
17
|
|
|
@@ -17,7 +31,7 @@ export namespace Base64 {
|
|
|
17
31
|
export function encodeSlice(
|
|
18
32
|
buffer: ArrayBufferLike,
|
|
19
33
|
offset: number,
|
|
20
|
-
length: number
|
|
34
|
+
length: number,
|
|
21
35
|
): string {
|
|
22
36
|
const bytes = new Uint8Array(buffer, offset, length);
|
|
23
37
|
const len = bytes.length;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Copyright 2020 Outfox, Inc.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
export function isError(value: unknown): value is Error {
|
|
16
|
+
return value instanceof Error;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function errorToMessage(value: unknown, defMsg?: string): string {
|
|
20
|
+
return isError(value) ? value.message : defMsg ?? `${fmtMsg(value)}`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function fmtMsg(value: unknown): string {
|
|
24
|
+
if (value instanceof Object) {
|
|
25
|
+
return JSON.stringify(value);
|
|
26
|
+
}
|
|
27
|
+
return `${value}`;
|
|
28
|
+
}
|