@predictorsdk/client 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/Client.d.ts +20 -0
- package/dist/Client.js +164 -7
- package/dist/api/client/requests/GetBinanceCryptoPricesRequest.d.ts +18 -0
- package/dist/api/client/requests/GetBinanceCryptoPricesRequest.js +2 -0
- package/dist/api/client/requests/GetSportsMatchingMarketsRequest.d.ts +4 -4
- package/dist/api/client/requests/index.d.ts +1 -0
- package/dist/api/errors/BadGatewayError.d.ts +6 -0
- package/dist/api/errors/BadGatewayError.js +17 -0
- package/dist/api/errors/index.d.ts +1 -0
- package/dist/api/errors/index.js +1 -0
- package/dist/api/types/CryptoPriceItem.d.ts +8 -0
- package/dist/api/types/CryptoPriceItem.js +2 -0
- package/dist/api/types/CryptoPricesResponse.d.ts +8 -0
- package/dist/api/types/CryptoPricesResponse.js +2 -0
- package/dist/api/types/ErrorResponse.d.ts +3 -1
- package/dist/api/types/PlatformMarket.d.ts +8 -16
- package/dist/api/types/PlatformMarket.js +1 -9
- package/dist/api/types/PlatformMarketPlatform.d.ts +7 -0
- package/dist/api/types/PlatformMarketPlatform.js +7 -0
- package/dist/api/types/index.d.ts +3 -0
- package/dist/api/types/index.js +3 -0
- package/dist/core/auth/BasicAuth.d.ts +2 -2
- package/dist/core/auth/BasicAuth.js +6 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +1 -0
- package/dist/core/schemas/Schema.d.ts +88 -0
- package/dist/core/schemas/Schema.js +22 -0
- package/dist/core/schemas/builders/bigint/bigint.d.ts +2 -0
- package/dist/core/schemas/builders/bigint/bigint.js +53 -0
- package/dist/core/schemas/builders/bigint/index.d.ts +1 -0
- package/dist/core/schemas/builders/bigint/index.js +1 -0
- package/dist/core/schemas/builders/date/date.d.ts +2 -0
- package/dist/core/schemas/builders/date/date.js +62 -0
- package/dist/core/schemas/builders/date/index.d.ts +1 -0
- package/dist/core/schemas/builders/date/index.js +1 -0
- package/dist/core/schemas/builders/enum/enum.d.ts +2 -0
- package/dist/core/schemas/builders/enum/enum.js +35 -0
- package/dist/core/schemas/builders/enum/index.d.ts +1 -0
- package/dist/core/schemas/builders/enum/index.js +1 -0
- package/dist/core/schemas/builders/index.d.ts +14 -0
- package/dist/core/schemas/builders/index.js +14 -0
- package/dist/core/schemas/builders/lazy/index.d.ts +3 -0
- package/dist/core/schemas/builders/lazy/index.js +2 -0
- package/dist/core/schemas/builders/lazy/lazy.d.ts +5 -0
- package/dist/core/schemas/builders/lazy/lazy.js +22 -0
- package/dist/core/schemas/builders/lazy/lazyObject.d.ts +3 -0
- package/dist/core/schemas/builders/lazy/lazyObject.js +17 -0
- package/dist/core/schemas/builders/list/index.d.ts +1 -0
- package/dist/core/schemas/builders/list/index.js +1 -0
- package/dist/core/schemas/builders/list/list.d.ts +2 -0
- package/dist/core/schemas/builders/list/list.js +49 -0
- package/dist/core/schemas/builders/literals/booleanLiteral.d.ts +2 -0
- package/dist/core/schemas/builders/literals/booleanLiteral.js +25 -0
- package/dist/core/schemas/builders/literals/index.d.ts +2 -0
- package/dist/core/schemas/builders/literals/index.js +2 -0
- package/dist/core/schemas/builders/literals/stringLiteral.d.ts +2 -0
- package/dist/core/schemas/builders/literals/stringLiteral.js +25 -0
- package/dist/core/schemas/builders/object/index.d.ts +6 -0
- package/dist/core/schemas/builders/object/index.js +3 -0
- package/dist/core/schemas/builders/object/object.d.ts +3 -0
- package/dist/core/schemas/builders/object/object.js +381 -0
- package/dist/core/schemas/builders/object/objectWithoutOptionalProperties.d.ts +6 -0
- package/dist/core/schemas/builders/object/objectWithoutOptionalProperties.js +4 -0
- package/dist/core/schemas/builders/object/property.d.ts +8 -0
- package/dist/core/schemas/builders/object/property.js +11 -0
- package/dist/core/schemas/builders/object/types.d.ts +31 -0
- package/dist/core/schemas/builders/object/types.js +1 -0
- package/dist/core/schemas/builders/object-like/getObjectLikeUtils.d.ts +9 -0
- package/dist/core/schemas/builders/object-like/getObjectLikeUtils.js +62 -0
- package/dist/core/schemas/builders/object-like/index.d.ts +2 -0
- package/dist/core/schemas/builders/object-like/index.js +1 -0
- package/dist/core/schemas/builders/object-like/types.d.ts +7 -0
- package/dist/core/schemas/builders/object-like/types.js +1 -0
- package/dist/core/schemas/builders/primitives/any.d.ts +2 -0
- package/dist/core/schemas/builders/primitives/any.js +6 -0
- package/dist/core/schemas/builders/primitives/boolean.d.ts +2 -0
- package/dist/core/schemas/builders/primitives/boolean.js +22 -0
- package/dist/core/schemas/builders/primitives/index.d.ts +6 -0
- package/dist/core/schemas/builders/primitives/index.js +6 -0
- package/dist/core/schemas/builders/primitives/never.d.ts +2 -0
- package/dist/core/schemas/builders/primitives/never.js +11 -0
- package/dist/core/schemas/builders/primitives/number.d.ts +2 -0
- package/dist/core/schemas/builders/primitives/number.js +22 -0
- package/dist/core/schemas/builders/primitives/string.d.ts +2 -0
- package/dist/core/schemas/builders/primitives/string.js +22 -0
- package/dist/core/schemas/builders/primitives/unknown.d.ts +2 -0
- package/dist/core/schemas/builders/primitives/unknown.js +3 -0
- package/dist/core/schemas/builders/record/index.d.ts +2 -0
- package/dist/core/schemas/builders/record/index.js +1 -0
- package/dist/core/schemas/builders/record/record.d.ts +4 -0
- package/dist/core/schemas/builders/record/record.js +133 -0
- package/dist/core/schemas/builders/record/types.d.ts +6 -0
- package/dist/core/schemas/builders/record/types.js +1 -0
- package/dist/core/schemas/builders/schema-utils/JsonError.d.ts +5 -0
- package/dist/core/schemas/builders/schema-utils/JsonError.js +9 -0
- package/dist/core/schemas/builders/schema-utils/ParseError.d.ts +5 -0
- package/dist/core/schemas/builders/schema-utils/ParseError.js +9 -0
- package/dist/core/schemas/builders/schema-utils/getSchemaUtils.d.ts +21 -0
- package/dist/core/schemas/builders/schema-utils/getSchemaUtils.js +150 -0
- package/dist/core/schemas/builders/schema-utils/index.d.ts +4 -0
- package/dist/core/schemas/builders/schema-utils/index.js +3 -0
- package/dist/core/schemas/builders/schema-utils/stringifyValidationErrors.d.ts +2 -0
- package/dist/core/schemas/builders/schema-utils/stringifyValidationErrors.js +6 -0
- package/dist/core/schemas/builders/set/index.d.ts +1 -0
- package/dist/core/schemas/builders/set/index.js +1 -0
- package/dist/core/schemas/builders/set/set.d.ts +2 -0
- package/dist/core/schemas/builders/set/set.js +42 -0
- package/dist/core/schemas/builders/undiscriminated-union/index.d.ts +2 -0
- package/dist/core/schemas/builders/undiscriminated-union/index.js +1 -0
- package/dist/core/schemas/builders/undiscriminated-union/types.d.ts +4 -0
- package/dist/core/schemas/builders/undiscriminated-union/types.js +1 -0
- package/dist/core/schemas/builders/undiscriminated-union/undiscriminatedUnion.d.ts +3 -0
- package/dist/core/schemas/builders/undiscriminated-union/undiscriminatedUnion.js +39 -0
- package/dist/core/schemas/builders/union/discriminant.d.ts +5 -0
- package/dist/core/schemas/builders/union/discriminant.js +6 -0
- package/dist/core/schemas/builders/union/index.d.ts +4 -0
- package/dist/core/schemas/builders/union/index.js +2 -0
- package/dist/core/schemas/builders/union/types.d.ts +13 -0
- package/dist/core/schemas/builders/union/types.js +1 -0
- package/dist/core/schemas/builders/union/union.d.ts +4 -0
- package/dist/core/schemas/builders/union/union.js +127 -0
- package/dist/core/schemas/index.d.ts +2 -0
- package/dist/core/schemas/index.js +1 -0
- package/dist/core/schemas/utils/MaybePromise.d.ts +1 -0
- package/dist/core/schemas/utils/MaybePromise.js +1 -0
- package/dist/core/schemas/utils/addQuestionMarksToNullableProperties.d.ts +7 -0
- package/dist/core/schemas/utils/addQuestionMarksToNullableProperties.js +1 -0
- package/dist/core/schemas/utils/createIdentitySchemaCreator.d.ts +2 -0
- package/dist/core/schemas/utils/createIdentitySchemaCreator.js +15 -0
- package/dist/core/schemas/utils/entries.d.ts +1 -0
- package/dist/core/schemas/utils/entries.js +3 -0
- package/dist/core/schemas/utils/filterObject.d.ts +1 -0
- package/dist/core/schemas/utils/filterObject.js +10 -0
- package/dist/core/schemas/utils/getErrorMessageForIncorrectType.d.ts +1 -0
- package/dist/core/schemas/utils/getErrorMessageForIncorrectType.js +24 -0
- package/dist/core/schemas/utils/isPlainObject.d.ts +1 -0
- package/dist/core/schemas/utils/isPlainObject.js +12 -0
- package/dist/core/schemas/utils/keys.d.ts +1 -0
- package/dist/core/schemas/utils/keys.js +3 -0
- package/dist/core/schemas/utils/maybeSkipValidation.d.ts +2 -0
- package/dist/core/schemas/utils/maybeSkipValidation.js +28 -0
- package/dist/core/schemas/utils/partition.d.ts +1 -0
- package/dist/core/schemas/utils/partition.js +12 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/serialization/index.d.ts +1 -0
- package/dist/serialization/index.js +1 -0
- package/dist/serialization/types/CryptoPriceItem.d.ts +11 -0
- package/dist/serialization/types/CryptoPriceItem.js +7 -0
- package/dist/serialization/types/CryptoPricesResponse.d.ts +12 -0
- package/dist/serialization/types/CryptoPricesResponse.js +8 -0
- package/dist/serialization/types/ErrorResponse.d.ts +11 -0
- package/dist/serialization/types/ErrorResponse.js +7 -0
- package/dist/serialization/types/PlatformMarket.d.ts +16 -0
- package/dist/serialization/types/PlatformMarket.js +12 -0
- package/dist/serialization/types/PlatformMarketPlatform.d.ts +7 -0
- package/dist/serialization/types/PlatformMarketPlatform.js +3 -0
- package/dist/serialization/types/SportsMatchingResponse.d.ts +10 -0
- package/dist/serialization/types/SportsMatchingResponse.js +6 -0
- package/dist/serialization/types/index.d.ts +6 -0
- package/dist/serialization/types/index.js +6 -0
- package/package.json +14 -3
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
import { SchemaType } from "../../Schema.js";
|
|
2
|
+
import { entries } from "../../utils/entries.js";
|
|
3
|
+
import { filterObject } from "../../utils/filterObject.js";
|
|
4
|
+
import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType.js";
|
|
5
|
+
import { isPlainObject } from "../../utils/isPlainObject.js";
|
|
6
|
+
import { keys } from "../../utils/keys.js";
|
|
7
|
+
import { maybeSkipValidation } from "../../utils/maybeSkipValidation.js";
|
|
8
|
+
import { partition } from "../../utils/partition.js";
|
|
9
|
+
import { getObjectLikeUtils } from "../object-like/index.js";
|
|
10
|
+
import { getSchemaUtils } from "../schema-utils/index.js";
|
|
11
|
+
import { isProperty } from "./property.js";
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
13
|
+
const _hasOwn = Object.prototype.hasOwnProperty;
|
|
14
|
+
export function object(schemas) {
|
|
15
|
+
// All property metadata is lazily computed on first use.
|
|
16
|
+
// This keeps schema construction free of iteration, which matters when
|
|
17
|
+
// many schemas are defined but only some are exercised at runtime.
|
|
18
|
+
// Required-key computation is also deferred because lazy() schemas may
|
|
19
|
+
// not be resolved at construction time.
|
|
20
|
+
let _rawKeyToProperty;
|
|
21
|
+
function getRawKeyToProperty() {
|
|
22
|
+
if (_rawKeyToProperty == null) {
|
|
23
|
+
_rawKeyToProperty = {};
|
|
24
|
+
for (const [parsedKey, schemaOrObjectProperty] of entries(schemas)) {
|
|
25
|
+
const rawKey = isProperty(schemaOrObjectProperty)
|
|
26
|
+
? schemaOrObjectProperty.rawKey
|
|
27
|
+
: parsedKey;
|
|
28
|
+
const valueSchema = isProperty(schemaOrObjectProperty)
|
|
29
|
+
? schemaOrObjectProperty.valueSchema
|
|
30
|
+
: schemaOrObjectProperty;
|
|
31
|
+
_rawKeyToProperty[rawKey] = {
|
|
32
|
+
rawKey,
|
|
33
|
+
parsedKey: parsedKey,
|
|
34
|
+
valueSchema,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return _rawKeyToProperty;
|
|
39
|
+
}
|
|
40
|
+
let _parseRequiredKeys;
|
|
41
|
+
let _jsonRequiredKeys;
|
|
42
|
+
let _parseRequiredKeysSet;
|
|
43
|
+
let _jsonRequiredKeysSet;
|
|
44
|
+
function getParseRequiredKeys() {
|
|
45
|
+
if (_parseRequiredKeys == null) {
|
|
46
|
+
_parseRequiredKeys = [];
|
|
47
|
+
_jsonRequiredKeys = [];
|
|
48
|
+
for (const [parsedKey, schemaOrObjectProperty] of entries(schemas)) {
|
|
49
|
+
const rawKey = isProperty(schemaOrObjectProperty)
|
|
50
|
+
? schemaOrObjectProperty.rawKey
|
|
51
|
+
: parsedKey;
|
|
52
|
+
const valueSchema = isProperty(schemaOrObjectProperty)
|
|
53
|
+
? schemaOrObjectProperty.valueSchema
|
|
54
|
+
: schemaOrObjectProperty;
|
|
55
|
+
if (isSchemaRequired(valueSchema)) {
|
|
56
|
+
_parseRequiredKeys.push(rawKey);
|
|
57
|
+
_jsonRequiredKeys.push(parsedKey);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
_parseRequiredKeysSet = new Set(_parseRequiredKeys);
|
|
61
|
+
_jsonRequiredKeysSet = new Set(_jsonRequiredKeys);
|
|
62
|
+
}
|
|
63
|
+
return _parseRequiredKeys;
|
|
64
|
+
}
|
|
65
|
+
function getJsonRequiredKeys() {
|
|
66
|
+
if (_jsonRequiredKeys == null) {
|
|
67
|
+
getParseRequiredKeys();
|
|
68
|
+
}
|
|
69
|
+
return _jsonRequiredKeys;
|
|
70
|
+
}
|
|
71
|
+
function getParseRequiredKeysSet() {
|
|
72
|
+
if (_parseRequiredKeysSet == null) {
|
|
73
|
+
getParseRequiredKeys();
|
|
74
|
+
}
|
|
75
|
+
return _parseRequiredKeysSet;
|
|
76
|
+
}
|
|
77
|
+
function getJsonRequiredKeysSet() {
|
|
78
|
+
if (_jsonRequiredKeysSet == null) {
|
|
79
|
+
getParseRequiredKeys();
|
|
80
|
+
}
|
|
81
|
+
return _jsonRequiredKeysSet;
|
|
82
|
+
}
|
|
83
|
+
const baseSchema = {
|
|
84
|
+
_getRawProperties: () => Object.entries(schemas).map(([parsedKey, propertySchema]) => isProperty(propertySchema) ? propertySchema.rawKey : parsedKey),
|
|
85
|
+
_getParsedProperties: () => keys(schemas),
|
|
86
|
+
parse: (raw, opts) => {
|
|
87
|
+
const breadcrumbsPrefix = opts?.breadcrumbsPrefix ?? [];
|
|
88
|
+
return validateAndTransformObject({
|
|
89
|
+
value: raw,
|
|
90
|
+
requiredKeys: getParseRequiredKeys(),
|
|
91
|
+
requiredKeysSet: getParseRequiredKeysSet(),
|
|
92
|
+
getProperty: (rawKey) => {
|
|
93
|
+
const property = getRawKeyToProperty()[rawKey];
|
|
94
|
+
if (property == null) {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
transformedKey: property.parsedKey,
|
|
99
|
+
transform: (propertyValue) => {
|
|
100
|
+
const childBreadcrumbs = [...breadcrumbsPrefix, rawKey];
|
|
101
|
+
return property.valueSchema.parse(propertyValue, {
|
|
102
|
+
...opts,
|
|
103
|
+
breadcrumbsPrefix: childBreadcrumbs,
|
|
104
|
+
});
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
},
|
|
108
|
+
unrecognizedObjectKeys: opts?.unrecognizedObjectKeys,
|
|
109
|
+
skipValidation: opts?.skipValidation,
|
|
110
|
+
breadcrumbsPrefix,
|
|
111
|
+
omitUndefined: opts?.omitUndefined,
|
|
112
|
+
});
|
|
113
|
+
},
|
|
114
|
+
json: (parsed, opts) => {
|
|
115
|
+
const breadcrumbsPrefix = opts?.breadcrumbsPrefix ?? [];
|
|
116
|
+
return validateAndTransformObject({
|
|
117
|
+
value: parsed,
|
|
118
|
+
requiredKeys: getJsonRequiredKeys(),
|
|
119
|
+
requiredKeysSet: getJsonRequiredKeysSet(),
|
|
120
|
+
getProperty: (parsedKey) => {
|
|
121
|
+
const property = schemas[parsedKey];
|
|
122
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
123
|
+
if (property == null) {
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
if (isProperty(property)) {
|
|
127
|
+
return {
|
|
128
|
+
transformedKey: property.rawKey,
|
|
129
|
+
transform: (propertyValue) => {
|
|
130
|
+
const childBreadcrumbs = [...breadcrumbsPrefix, parsedKey];
|
|
131
|
+
return property.valueSchema.json(propertyValue, {
|
|
132
|
+
...opts,
|
|
133
|
+
breadcrumbsPrefix: childBreadcrumbs,
|
|
134
|
+
});
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
return {
|
|
140
|
+
transformedKey: parsedKey,
|
|
141
|
+
transform: (propertyValue) => {
|
|
142
|
+
const childBreadcrumbs = [...breadcrumbsPrefix, parsedKey];
|
|
143
|
+
return property.json(propertyValue, {
|
|
144
|
+
...opts,
|
|
145
|
+
breadcrumbsPrefix: childBreadcrumbs,
|
|
146
|
+
});
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
unrecognizedObjectKeys: opts?.unrecognizedObjectKeys,
|
|
152
|
+
skipValidation: opts?.skipValidation,
|
|
153
|
+
breadcrumbsPrefix,
|
|
154
|
+
omitUndefined: opts?.omitUndefined,
|
|
155
|
+
});
|
|
156
|
+
},
|
|
157
|
+
getType: () => SchemaType.OBJECT,
|
|
158
|
+
};
|
|
159
|
+
return {
|
|
160
|
+
...maybeSkipValidation(baseSchema),
|
|
161
|
+
...getSchemaUtils(baseSchema),
|
|
162
|
+
...getObjectLikeUtils(baseSchema),
|
|
163
|
+
...getObjectUtils(baseSchema),
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
function validateAndTransformObject({ value, requiredKeys, requiredKeysSet, getProperty, unrecognizedObjectKeys = "fail", skipValidation = false, breadcrumbsPrefix = [], }) {
|
|
167
|
+
if (!isPlainObject(value)) {
|
|
168
|
+
return {
|
|
169
|
+
ok: false,
|
|
170
|
+
errors: [
|
|
171
|
+
{
|
|
172
|
+
path: breadcrumbsPrefix,
|
|
173
|
+
message: getErrorMessageForIncorrectType(value, "object"),
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
// Track which required keys have been seen.
|
|
179
|
+
// Use a counter instead of copying the Set to avoid per-call allocation.
|
|
180
|
+
let missingRequiredCount = requiredKeys.length;
|
|
181
|
+
const errors = [];
|
|
182
|
+
const transformed = {};
|
|
183
|
+
for (const preTransformedKey in value) {
|
|
184
|
+
if (!_hasOwn.call(value, preTransformedKey)) {
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
const preTransformedItemValue = value[preTransformedKey];
|
|
188
|
+
const property = getProperty(preTransformedKey);
|
|
189
|
+
if (property != null) {
|
|
190
|
+
if (missingRequiredCount > 0 && requiredKeysSet.has(preTransformedKey)) {
|
|
191
|
+
missingRequiredCount--;
|
|
192
|
+
}
|
|
193
|
+
const value = property.transform(preTransformedItemValue);
|
|
194
|
+
if (value.ok) {
|
|
195
|
+
transformed[property.transformedKey] = value.value;
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
transformed[preTransformedKey] = preTransformedItemValue;
|
|
199
|
+
errors.push(...value.errors);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
switch (unrecognizedObjectKeys) {
|
|
204
|
+
case "fail":
|
|
205
|
+
errors.push({
|
|
206
|
+
path: [...breadcrumbsPrefix, preTransformedKey],
|
|
207
|
+
message: `Unexpected key "${preTransformedKey}"`,
|
|
208
|
+
});
|
|
209
|
+
break;
|
|
210
|
+
case "strip":
|
|
211
|
+
break;
|
|
212
|
+
case "passthrough":
|
|
213
|
+
transformed[preTransformedKey] = preTransformedItemValue;
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
if (missingRequiredCount > 0) {
|
|
219
|
+
for (const key of requiredKeys) {
|
|
220
|
+
if (!(key in value)) {
|
|
221
|
+
errors.push({
|
|
222
|
+
path: breadcrumbsPrefix,
|
|
223
|
+
message: `Missing required key "${key}"`,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (errors.length === 0 || skipValidation) {
|
|
229
|
+
return {
|
|
230
|
+
ok: true,
|
|
231
|
+
value: transformed,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
return {
|
|
236
|
+
ok: false,
|
|
237
|
+
errors,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
export function getObjectUtils(schema) {
|
|
242
|
+
return {
|
|
243
|
+
extend: (extension) => {
|
|
244
|
+
const baseSchema = {
|
|
245
|
+
_getParsedProperties: () => [...schema._getParsedProperties(), ...extension._getParsedProperties()],
|
|
246
|
+
_getRawProperties: () => [...schema._getRawProperties(), ...extension._getRawProperties()],
|
|
247
|
+
parse: (raw, opts) => {
|
|
248
|
+
return validateAndTransformExtendedObject({
|
|
249
|
+
extensionKeys: extension._getRawProperties(),
|
|
250
|
+
value: raw,
|
|
251
|
+
transformBase: (rawBase) => schema.parse(rawBase, opts),
|
|
252
|
+
transformExtension: (rawExtension) => extension.parse(rawExtension, opts),
|
|
253
|
+
breadcrumbsPrefix: opts?.breadcrumbsPrefix,
|
|
254
|
+
});
|
|
255
|
+
},
|
|
256
|
+
json: (parsed, opts) => {
|
|
257
|
+
return validateAndTransformExtendedObject({
|
|
258
|
+
extensionKeys: extension._getParsedProperties(),
|
|
259
|
+
value: parsed,
|
|
260
|
+
transformBase: (parsedBase) => schema.json(parsedBase, opts),
|
|
261
|
+
transformExtension: (parsedExtension) => extension.json(parsedExtension, opts),
|
|
262
|
+
breadcrumbsPrefix: opts?.breadcrumbsPrefix,
|
|
263
|
+
});
|
|
264
|
+
},
|
|
265
|
+
getType: () => SchemaType.OBJECT,
|
|
266
|
+
};
|
|
267
|
+
return {
|
|
268
|
+
...baseSchema,
|
|
269
|
+
...getSchemaUtils(baseSchema),
|
|
270
|
+
...getObjectLikeUtils(baseSchema),
|
|
271
|
+
...getObjectUtils(baseSchema),
|
|
272
|
+
};
|
|
273
|
+
},
|
|
274
|
+
passthrough: () => {
|
|
275
|
+
const knownRawKeys = new Set(schema._getRawProperties());
|
|
276
|
+
const knownParsedKeys = new Set(schema._getParsedProperties());
|
|
277
|
+
const baseSchema = {
|
|
278
|
+
_getParsedProperties: () => schema._getParsedProperties(),
|
|
279
|
+
_getRawProperties: () => schema._getRawProperties(),
|
|
280
|
+
parse: (raw, opts) => {
|
|
281
|
+
const transformed = schema.parse(raw, { ...opts, unrecognizedObjectKeys: "passthrough" });
|
|
282
|
+
if (!transformed.ok) {
|
|
283
|
+
return transformed;
|
|
284
|
+
}
|
|
285
|
+
const extraProperties = {};
|
|
286
|
+
if (typeof raw === "object" && raw != null) {
|
|
287
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
288
|
+
if (!knownRawKeys.has(key)) {
|
|
289
|
+
extraProperties[key] = value;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
ok: true,
|
|
295
|
+
value: {
|
|
296
|
+
...extraProperties,
|
|
297
|
+
...transformed.value,
|
|
298
|
+
},
|
|
299
|
+
};
|
|
300
|
+
},
|
|
301
|
+
json: (parsed, opts) => {
|
|
302
|
+
const transformed = schema.json(parsed, { ...opts, unrecognizedObjectKeys: "passthrough" });
|
|
303
|
+
if (!transformed.ok) {
|
|
304
|
+
return transformed;
|
|
305
|
+
}
|
|
306
|
+
const extraProperties = {};
|
|
307
|
+
if (typeof parsed === "object" && parsed != null) {
|
|
308
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
309
|
+
if (!knownParsedKeys.has(key)) {
|
|
310
|
+
extraProperties[key] = value;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return {
|
|
315
|
+
ok: true,
|
|
316
|
+
value: {
|
|
317
|
+
...extraProperties,
|
|
318
|
+
...transformed.value,
|
|
319
|
+
},
|
|
320
|
+
};
|
|
321
|
+
},
|
|
322
|
+
getType: () => SchemaType.OBJECT,
|
|
323
|
+
};
|
|
324
|
+
return {
|
|
325
|
+
...baseSchema,
|
|
326
|
+
...getSchemaUtils(baseSchema),
|
|
327
|
+
...getObjectLikeUtils(baseSchema),
|
|
328
|
+
...getObjectUtils(baseSchema),
|
|
329
|
+
};
|
|
330
|
+
},
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
function validateAndTransformExtendedObject({ extensionKeys, value, transformBase, transformExtension, breadcrumbsPrefix = [], }) {
|
|
334
|
+
if (!isPlainObject(value)) {
|
|
335
|
+
return {
|
|
336
|
+
ok: false,
|
|
337
|
+
errors: [
|
|
338
|
+
{
|
|
339
|
+
path: breadcrumbsPrefix,
|
|
340
|
+
message: getErrorMessageForIncorrectType(value, "object"),
|
|
341
|
+
},
|
|
342
|
+
],
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
const extensionPropertiesSet = new Set(extensionKeys);
|
|
346
|
+
const [extensionProperties, baseProperties] = partition(keys(value), (key) => extensionPropertiesSet.has(key));
|
|
347
|
+
const transformedBase = transformBase(filterObject(value, baseProperties));
|
|
348
|
+
const transformedExtension = transformExtension(filterObject(value, extensionProperties));
|
|
349
|
+
if (transformedBase.ok && transformedExtension.ok) {
|
|
350
|
+
return {
|
|
351
|
+
ok: true,
|
|
352
|
+
value: {
|
|
353
|
+
...transformedBase.value,
|
|
354
|
+
...transformedExtension.value,
|
|
355
|
+
},
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
return {
|
|
360
|
+
ok: false,
|
|
361
|
+
errors: [
|
|
362
|
+
...(transformedBase.ok ? [] : transformedBase.errors),
|
|
363
|
+
...(transformedExtension.ok ? [] : transformedExtension.errors),
|
|
364
|
+
],
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
function isSchemaRequired(schema) {
|
|
369
|
+
return !isSchemaOptional(schema);
|
|
370
|
+
}
|
|
371
|
+
function isSchemaOptional(schema) {
|
|
372
|
+
switch (schema.getType()) {
|
|
373
|
+
case SchemaType.ANY:
|
|
374
|
+
case SchemaType.UNKNOWN:
|
|
375
|
+
case SchemaType.OPTIONAL:
|
|
376
|
+
case SchemaType.OPTIONAL_NULLABLE:
|
|
377
|
+
return true;
|
|
378
|
+
default:
|
|
379
|
+
return false;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { inferParsedPropertySchema, inferRawObjectFromPropertySchemas, ObjectSchema, PropertySchemas } from "./types.js";
|
|
2
|
+
export declare function objectWithoutOptionalProperties<ParsedKeys extends string, T extends PropertySchemas<ParsedKeys>>(schemas: T): inferObjectWithoutOptionalPropertiesSchemaFromPropertySchemas<T>;
|
|
3
|
+
export type inferObjectWithoutOptionalPropertiesSchemaFromPropertySchemas<T extends PropertySchemas<keyof T>> = ObjectSchema<inferRawObjectFromPropertySchemas<T>, inferParsedObjectWithoutOptionalPropertiesFromPropertySchemas<T>>;
|
|
4
|
+
export type inferParsedObjectWithoutOptionalPropertiesFromPropertySchemas<T extends PropertySchemas<keyof T>> = {
|
|
5
|
+
[K in keyof T]: inferParsedPropertySchema<T[K]>;
|
|
6
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Schema } from "../../Schema.js";
|
|
2
|
+
export declare function property<RawKey extends string, RawValue, ParsedValue>(rawKey: RawKey, valueSchema: Schema<RawValue, ParsedValue>): Property<RawKey, RawValue, ParsedValue>;
|
|
3
|
+
export interface Property<RawKey extends string, RawValue, ParsedValue> {
|
|
4
|
+
rawKey: RawKey;
|
|
5
|
+
valueSchema: Schema<RawValue, ParsedValue>;
|
|
6
|
+
isProperty: true;
|
|
7
|
+
}
|
|
8
|
+
export declare function isProperty<O extends Property<any, any, any>>(maybeProperty: unknown): maybeProperty is O;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function property(rawKey, valueSchema) {
|
|
2
|
+
return {
|
|
3
|
+
rawKey,
|
|
4
|
+
valueSchema,
|
|
5
|
+
isProperty: true,
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
export function isProperty(maybeProperty) {
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
10
|
+
return maybeProperty.isProperty;
|
|
11
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { BaseSchema, inferParsed, inferRaw, Schema } from "../../Schema.js";
|
|
2
|
+
import type { addQuestionMarksToNullableProperties } from "../../utils/addQuestionMarksToNullableProperties.js";
|
|
3
|
+
import type { ObjectLikeUtils } from "../object-like/index.js";
|
|
4
|
+
import type { SchemaUtils } from "../schema-utils/index.js";
|
|
5
|
+
import type { Property } from "./property.js";
|
|
6
|
+
export type ObjectSchema<Raw, Parsed> = BaseObjectSchema<Raw, Parsed> & ObjectLikeUtils<Raw, Parsed> & ObjectUtils<Raw, Parsed> & SchemaUtils<Raw, Parsed>;
|
|
7
|
+
export interface BaseObjectSchema<Raw, Parsed> extends BaseSchema<Raw, Parsed> {
|
|
8
|
+
_getRawProperties: () => (keyof Raw)[];
|
|
9
|
+
_getParsedProperties: () => (keyof Parsed)[];
|
|
10
|
+
}
|
|
11
|
+
export interface ObjectUtils<Raw, Parsed> {
|
|
12
|
+
extend: <RawExtension, ParsedExtension>(schemas: ObjectSchema<RawExtension, ParsedExtension>) => ObjectSchema<Raw & RawExtension, Parsed & ParsedExtension>;
|
|
13
|
+
passthrough: () => ObjectSchema<Raw & {
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
}, Parsed & {
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
}>;
|
|
18
|
+
}
|
|
19
|
+
export type inferRawObject<O extends ObjectSchema<any, any>> = O extends ObjectSchema<infer Raw, any> ? Raw : never;
|
|
20
|
+
export type inferParsedObject<O extends ObjectSchema<any, any>> = O extends ObjectSchema<any, infer Parsed> ? Parsed : never;
|
|
21
|
+
export type inferObjectSchemaFromPropertySchemas<T extends PropertySchemas<keyof T>> = ObjectSchema<inferRawObjectFromPropertySchemas<T>, inferParsedObjectFromPropertySchemas<T>>;
|
|
22
|
+
export type inferRawObjectFromPropertySchemas<T extends PropertySchemas<keyof T>> = addQuestionMarksToNullableProperties<{
|
|
23
|
+
[ParsedKey in keyof T as inferRawKey<ParsedKey, T[ParsedKey]>]: inferRawPropertySchema<T[ParsedKey]>;
|
|
24
|
+
}>;
|
|
25
|
+
export type inferParsedObjectFromPropertySchemas<T extends PropertySchemas<keyof T>> = addQuestionMarksToNullableProperties<{
|
|
26
|
+
[K in keyof T]: inferParsedPropertySchema<T[K]>;
|
|
27
|
+
}>;
|
|
28
|
+
export type PropertySchemas<ParsedKeys extends string | number | symbol> = Record<ParsedKeys, Property<any, any, any> | Schema<any, any>>;
|
|
29
|
+
export type inferRawPropertySchema<P extends Property<any, any, any> | Schema<any, any>> = P extends Property<any, infer Raw, any> ? Raw : P extends Schema<any, any> ? inferRaw<P> : never;
|
|
30
|
+
export type inferParsedPropertySchema<P extends Property<any, any, any> | Schema<any, any>> = P extends Property<any, any, infer Parsed> ? Parsed : P extends Schema<any, any> ? inferParsed<P> : never;
|
|
31
|
+
export type inferRawKey<ParsedKey extends string | number | symbol, P extends Property<any, any, any> | Schema<any, any>> = P extends Property<infer Raw, any, any> ? Raw : ParsedKey;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { BaseSchema } from "../../Schema.js";
|
|
2
|
+
import type { ObjectLikeSchema, ObjectLikeUtils } from "./types.js";
|
|
3
|
+
export declare function getObjectLikeUtils<Raw, Parsed>(schema: BaseSchema<Raw, Parsed>): ObjectLikeUtils<Raw, Parsed>;
|
|
4
|
+
/**
|
|
5
|
+
* object-like utils are defined in one file to resolve issues with circular imports
|
|
6
|
+
*/
|
|
7
|
+
export declare function withParsedProperties<RawObjectShape, ParsedObjectShape, Properties>(objectLike: BaseSchema<RawObjectShape, ParsedObjectShape>, properties: {
|
|
8
|
+
[K in keyof Properties]: Properties[K] | ((parsed: ParsedObjectShape) => Properties[K]);
|
|
9
|
+
}): ObjectLikeSchema<RawObjectShape, ParsedObjectShape & Properties>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { filterObject } from "../../utils/filterObject.js";
|
|
2
|
+
import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType.js";
|
|
3
|
+
import { isPlainObject } from "../../utils/isPlainObject.js";
|
|
4
|
+
import { getSchemaUtils } from "../schema-utils/index.js";
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
6
|
+
const _hasOwn = Object.prototype.hasOwnProperty;
|
|
7
|
+
export function getObjectLikeUtils(schema) {
|
|
8
|
+
return {
|
|
9
|
+
withParsedProperties: (properties) => withParsedProperties(schema, properties),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* object-like utils are defined in one file to resolve issues with circular imports
|
|
14
|
+
*/
|
|
15
|
+
export function withParsedProperties(objectLike, properties) {
|
|
16
|
+
const objectSchema = {
|
|
17
|
+
parse: (raw, opts) => {
|
|
18
|
+
const parsedObject = objectLike.parse(raw, opts);
|
|
19
|
+
if (!parsedObject.ok) {
|
|
20
|
+
return parsedObject;
|
|
21
|
+
}
|
|
22
|
+
const additionalProperties = {};
|
|
23
|
+
for (const key in properties) {
|
|
24
|
+
if (_hasOwn.call(properties, key)) {
|
|
25
|
+
const value = properties[key];
|
|
26
|
+
additionalProperties[key] =
|
|
27
|
+
typeof value === "function" ? value(parsedObject.value) : value;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
ok: true,
|
|
32
|
+
value: {
|
|
33
|
+
...parsedObject.value,
|
|
34
|
+
...additionalProperties,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
json: (parsed, opts) => {
|
|
39
|
+
if (!isPlainObject(parsed)) {
|
|
40
|
+
return {
|
|
41
|
+
ok: false,
|
|
42
|
+
errors: [
|
|
43
|
+
{
|
|
44
|
+
path: opts?.breadcrumbsPrefix ?? [],
|
|
45
|
+
message: getErrorMessageForIncorrectType(parsed, "object"),
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
// strip out added properties
|
|
51
|
+
const addedPropertyKeys = new Set(Object.keys(properties));
|
|
52
|
+
const parsedWithoutAddedProperties = filterObject(parsed, Object.keys(parsed).filter((key) => !addedPropertyKeys.has(key)));
|
|
53
|
+
return objectLike.json(parsedWithoutAddedProperties, opts);
|
|
54
|
+
},
|
|
55
|
+
getType: () => objectLike.getType(),
|
|
56
|
+
};
|
|
57
|
+
return {
|
|
58
|
+
...objectSchema,
|
|
59
|
+
...getSchemaUtils(objectSchema),
|
|
60
|
+
...getObjectLikeUtils(objectSchema),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { getObjectLikeUtils, withParsedProperties } from "./getObjectLikeUtils.js";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { BaseSchema, Schema } from "../../Schema.js";
|
|
2
|
+
export type ObjectLikeSchema<Raw, Parsed> = Schema<Raw, Parsed> & BaseSchema<Raw, Parsed> & ObjectLikeUtils<Raw, Parsed>;
|
|
3
|
+
export interface ObjectLikeUtils<Raw, Parsed> {
|
|
4
|
+
withParsedProperties: <T extends Record<string, any>>(properties: {
|
|
5
|
+
[K in keyof T]: T[K] | ((parsed: Parsed) => T[K]);
|
|
6
|
+
}) => ObjectLikeSchema<Raw, Parsed & T>;
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { SchemaType } from "../../Schema.js";
|
|
2
|
+
import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator.js";
|
|
3
|
+
import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType.js";
|
|
4
|
+
export const boolean = createIdentitySchemaCreator(SchemaType.BOOLEAN, (value, { breadcrumbsPrefix = [] } = {}) => {
|
|
5
|
+
if (typeof value === "boolean") {
|
|
6
|
+
return {
|
|
7
|
+
ok: true,
|
|
8
|
+
value,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
return {
|
|
13
|
+
ok: false,
|
|
14
|
+
errors: [
|
|
15
|
+
{
|
|
16
|
+
path: breadcrumbsPrefix,
|
|
17
|
+
message: getErrorMessageForIncorrectType(value, "boolean"),
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { SchemaType } from "../../Schema.js";
|
|
2
|
+
import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator.js";
|
|
3
|
+
export const never = createIdentitySchemaCreator(SchemaType.NEVER, (_value, { breadcrumbsPrefix = [] } = {}) => ({
|
|
4
|
+
ok: false,
|
|
5
|
+
errors: [
|
|
6
|
+
{
|
|
7
|
+
path: breadcrumbsPrefix,
|
|
8
|
+
message: "Expected never",
|
|
9
|
+
},
|
|
10
|
+
],
|
|
11
|
+
}));
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { SchemaType } from "../../Schema.js";
|
|
2
|
+
import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator.js";
|
|
3
|
+
import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType.js";
|
|
4
|
+
export const number = createIdentitySchemaCreator(SchemaType.NUMBER, (value, { breadcrumbsPrefix = [] } = {}) => {
|
|
5
|
+
if (typeof value === "number") {
|
|
6
|
+
return {
|
|
7
|
+
ok: true,
|
|
8
|
+
value,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
return {
|
|
13
|
+
ok: false,
|
|
14
|
+
errors: [
|
|
15
|
+
{
|
|
16
|
+
path: breadcrumbsPrefix,
|
|
17
|
+
message: getErrorMessageForIncorrectType(value, "number"),
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
});
|