@digitalsamba/validate 2.0.0-canary.1b923c9db3e2
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/CHANGELOG.md +209 -0
- package/LICENSE +190 -0
- package/README.md +5 -0
- package/dist-cjs/index.d.ts +341 -0
- package/dist-cjs/index.js +41 -0
- package/dist-cjs/index.js.map +7 -0
- package/dist-cjs/lib/validation.js +418 -0
- package/dist-cjs/lib/validation.js.map +7 -0
- package/dist-esm/index.d.mts +341 -0
- package/dist-esm/index.mjs +17 -0
- package/dist-esm/index.mjs.map +7 -0
- package/dist-esm/lib/validation.mjs +402 -0
- package/dist-esm/lib/validation.mjs.map +7 -0
- package/package.json +66 -0
- package/src/index.ts +10 -0
- package/src/lib/validation.ts +609 -0
- package/src/test/validation.test.ts +124 -0
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
import {
|
|
2
|
+
exhaustiveSwitchError,
|
|
3
|
+
getOwnProperty,
|
|
4
|
+
hasOwnProperty
|
|
5
|
+
} from "@digitalsamba/utils";
|
|
6
|
+
function formatPath(path) {
|
|
7
|
+
if (!path.length) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
let formattedPath = "";
|
|
11
|
+
for (const item of path) {
|
|
12
|
+
if (typeof item === "number") {
|
|
13
|
+
formattedPath += `.${item}`;
|
|
14
|
+
} else if (item.startsWith("(")) {
|
|
15
|
+
if (formattedPath.endsWith(")")) {
|
|
16
|
+
formattedPath = `${formattedPath.slice(0, -1)}, ${item.slice(1)}`;
|
|
17
|
+
} else {
|
|
18
|
+
formattedPath += item;
|
|
19
|
+
}
|
|
20
|
+
} else {
|
|
21
|
+
formattedPath += `.${item}`;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (formattedPath.startsWith(".")) {
|
|
25
|
+
return formattedPath.slice(1);
|
|
26
|
+
}
|
|
27
|
+
return formattedPath;
|
|
28
|
+
}
|
|
29
|
+
class ValidationError extends Error {
|
|
30
|
+
constructor(rawMessage, path = []) {
|
|
31
|
+
const formattedPath = formatPath(path);
|
|
32
|
+
const indentedMessage = rawMessage.split("\n").map((line, i) => i === 0 ? line : ` ${line}`).join("\n");
|
|
33
|
+
super(path ? `At ${formattedPath}: ${indentedMessage}` : indentedMessage);
|
|
34
|
+
this.rawMessage = rawMessage;
|
|
35
|
+
this.path = path;
|
|
36
|
+
}
|
|
37
|
+
name = "ValidationError";
|
|
38
|
+
}
|
|
39
|
+
function prefixError(path, fn) {
|
|
40
|
+
try {
|
|
41
|
+
return fn();
|
|
42
|
+
} catch (err) {
|
|
43
|
+
if (err instanceof ValidationError) {
|
|
44
|
+
throw new ValidationError(err.rawMessage, [path, ...err.path]);
|
|
45
|
+
}
|
|
46
|
+
throw new ValidationError(err.toString(), [path]);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function typeToString(value) {
|
|
50
|
+
if (value === null)
|
|
51
|
+
return "null";
|
|
52
|
+
if (Array.isArray(value))
|
|
53
|
+
return "an array";
|
|
54
|
+
const type = typeof value;
|
|
55
|
+
switch (type) {
|
|
56
|
+
case "bigint":
|
|
57
|
+
case "boolean":
|
|
58
|
+
case "function":
|
|
59
|
+
case "number":
|
|
60
|
+
case "string":
|
|
61
|
+
case "symbol":
|
|
62
|
+
return `a ${type}`;
|
|
63
|
+
case "object":
|
|
64
|
+
return `an ${type}`;
|
|
65
|
+
case "undefined":
|
|
66
|
+
return "undefined";
|
|
67
|
+
default:
|
|
68
|
+
exhaustiveSwitchError(type);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
class Validator {
|
|
72
|
+
constructor(validationFn) {
|
|
73
|
+
this.validationFn = validationFn;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Asserts that the passed value is of the correct type and returns it. The returned value is
|
|
77
|
+
* guaranteed to be referentially equal to the passed value.
|
|
78
|
+
*/
|
|
79
|
+
validate(value) {
|
|
80
|
+
const validated = this.validationFn(value);
|
|
81
|
+
if (process.env.NODE_ENV !== "production" && !Object.is(value, validated)) {
|
|
82
|
+
throw new ValidationError("Validator functions must return the same value they were passed");
|
|
83
|
+
}
|
|
84
|
+
return validated;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Returns a new validator that also accepts null or undefined. The resulting value will always be
|
|
88
|
+
* null.
|
|
89
|
+
*/
|
|
90
|
+
nullable() {
|
|
91
|
+
return nullable(this);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Returns a new validator that also accepts null or undefined. The resulting value will always be
|
|
95
|
+
* null.
|
|
96
|
+
*/
|
|
97
|
+
optional() {
|
|
98
|
+
return optional(this);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Refine this validation to a new type. The passed-in validation function should throw an error
|
|
102
|
+
* if the value can't be converted to the new type, or return the new type otherwise.
|
|
103
|
+
*/
|
|
104
|
+
refine(otherValidationFn) {
|
|
105
|
+
return new Validator((value) => {
|
|
106
|
+
return otherValidationFn(this.validate(value));
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
check(nameOrCheckFn, checkFn) {
|
|
110
|
+
if (typeof nameOrCheckFn === "string") {
|
|
111
|
+
return this.refine((value) => {
|
|
112
|
+
prefixError(`(check ${nameOrCheckFn})`, () => checkFn(value));
|
|
113
|
+
return value;
|
|
114
|
+
});
|
|
115
|
+
} else {
|
|
116
|
+
return this.refine((value) => {
|
|
117
|
+
nameOrCheckFn(value);
|
|
118
|
+
return value;
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
class ArrayOfValidator extends Validator {
|
|
124
|
+
constructor(itemValidator) {
|
|
125
|
+
super((value) => {
|
|
126
|
+
const arr = array.validate(value);
|
|
127
|
+
for (let i = 0; i < arr.length; i++) {
|
|
128
|
+
prefixError(i, () => itemValidator.validate(arr[i]));
|
|
129
|
+
}
|
|
130
|
+
return arr;
|
|
131
|
+
});
|
|
132
|
+
this.itemValidator = itemValidator;
|
|
133
|
+
}
|
|
134
|
+
nonEmpty() {
|
|
135
|
+
return this.check((value) => {
|
|
136
|
+
if (value.length === 0) {
|
|
137
|
+
throw new ValidationError("Expected a non-empty array");
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
lengthGreaterThan1() {
|
|
142
|
+
return this.check((value) => {
|
|
143
|
+
if (value.length <= 1) {
|
|
144
|
+
throw new ValidationError("Expected an array with length greater than 1");
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
class ObjectValidator extends Validator {
|
|
150
|
+
constructor(config, shouldAllowUnknownProperties = false) {
|
|
151
|
+
super((object2) => {
|
|
152
|
+
if (typeof object2 !== "object" || object2 === null) {
|
|
153
|
+
throw new ValidationError(`Expected object, got ${typeToString(object2)}`);
|
|
154
|
+
}
|
|
155
|
+
for (const [key, validator] of Object.entries(config)) {
|
|
156
|
+
prefixError(key, () => {
|
|
157
|
+
;
|
|
158
|
+
validator.validate(getOwnProperty(object2, key));
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
if (!shouldAllowUnknownProperties) {
|
|
162
|
+
for (const key of Object.keys(object2)) {
|
|
163
|
+
if (!hasOwnProperty(config, key)) {
|
|
164
|
+
throw new ValidationError(`Unexpected property`, [key]);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return object2;
|
|
169
|
+
});
|
|
170
|
+
this.config = config;
|
|
171
|
+
this.shouldAllowUnknownProperties = shouldAllowUnknownProperties;
|
|
172
|
+
}
|
|
173
|
+
allowUnknownProperties() {
|
|
174
|
+
return new ObjectValidator(this.config, true);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Extend an object validator by adding additional properties.
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
*
|
|
181
|
+
* ```ts
|
|
182
|
+
* const animalValidator = T.object({
|
|
183
|
+
* name: T.string,
|
|
184
|
+
* })
|
|
185
|
+
* const catValidator = animalValidator.extend({
|
|
186
|
+
* meowVolume: T.number,
|
|
187
|
+
* })
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
190
|
+
extend(extension) {
|
|
191
|
+
return new ObjectValidator({ ...this.config, ...extension });
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
class UnionValidator extends Validator {
|
|
195
|
+
constructor(key, config, unknownValueValidation) {
|
|
196
|
+
super((input) => {
|
|
197
|
+
if (typeof input !== "object" || input === null) {
|
|
198
|
+
throw new ValidationError(`Expected an object, got ${typeToString(input)}`, []);
|
|
199
|
+
}
|
|
200
|
+
const variant = getOwnProperty(input, key);
|
|
201
|
+
if (typeof variant !== "string") {
|
|
202
|
+
throw new ValidationError(
|
|
203
|
+
`Expected a string for key "${key}", got ${typeToString(variant)}`
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
const matchingSchema = hasOwnProperty(config, variant) ? config[variant] : void 0;
|
|
207
|
+
if (matchingSchema === void 0) {
|
|
208
|
+
return this.unknownValueValidation(input, variant);
|
|
209
|
+
}
|
|
210
|
+
return prefixError(`(${key} = ${variant})`, () => matchingSchema.validate(input));
|
|
211
|
+
});
|
|
212
|
+
this.key = key;
|
|
213
|
+
this.config = config;
|
|
214
|
+
this.unknownValueValidation = unknownValueValidation;
|
|
215
|
+
}
|
|
216
|
+
validateUnknownVariants(unknownValueValidation) {
|
|
217
|
+
return new UnionValidator(this.key, this.config, unknownValueValidation);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
class DictValidator extends Validator {
|
|
221
|
+
constructor(keyValidator, valueValidator) {
|
|
222
|
+
super((object2) => {
|
|
223
|
+
if (typeof object2 !== "object" || object2 === null) {
|
|
224
|
+
throw new ValidationError(`Expected object, got ${typeToString(object2)}`);
|
|
225
|
+
}
|
|
226
|
+
for (const [key, value] of Object.entries(object2)) {
|
|
227
|
+
prefixError(key, () => {
|
|
228
|
+
keyValidator.validate(key);
|
|
229
|
+
valueValidator.validate(value);
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
return object2;
|
|
233
|
+
});
|
|
234
|
+
this.keyValidator = keyValidator;
|
|
235
|
+
this.valueValidator = valueValidator;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
function typeofValidator(type) {
|
|
239
|
+
return new Validator((value) => {
|
|
240
|
+
if (typeof value !== type) {
|
|
241
|
+
throw new ValidationError(`Expected ${type}, got ${typeToString(value)}`);
|
|
242
|
+
}
|
|
243
|
+
return value;
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
const unknown = new Validator((value) => value);
|
|
247
|
+
const any = new Validator((value) => value);
|
|
248
|
+
const string = typeofValidator("string");
|
|
249
|
+
const number = typeofValidator("number").check((number2) => {
|
|
250
|
+
if (Number.isNaN(number2)) {
|
|
251
|
+
throw new ValidationError("Expected a number, got NaN");
|
|
252
|
+
}
|
|
253
|
+
if (!Number.isFinite(number2)) {
|
|
254
|
+
throw new ValidationError(`Expected a finite number, got ${number2}`);
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
const positiveNumber = number.check((value) => {
|
|
258
|
+
if (value < 0)
|
|
259
|
+
throw new ValidationError(`Expected a positive number, got ${value}`);
|
|
260
|
+
});
|
|
261
|
+
const nonZeroNumber = number.check((value) => {
|
|
262
|
+
if (value <= 0)
|
|
263
|
+
throw new ValidationError(`Expected a non-zero positive number, got ${value}`);
|
|
264
|
+
});
|
|
265
|
+
const integer = number.check((value) => {
|
|
266
|
+
if (!Number.isInteger(value))
|
|
267
|
+
throw new ValidationError(`Expected an integer, got ${value}`);
|
|
268
|
+
});
|
|
269
|
+
const positiveInteger = integer.check((value) => {
|
|
270
|
+
if (value < 0)
|
|
271
|
+
throw new ValidationError(`Expected a positive integer, got ${value}`);
|
|
272
|
+
});
|
|
273
|
+
const nonZeroInteger = integer.check((value) => {
|
|
274
|
+
if (value <= 0)
|
|
275
|
+
throw new ValidationError(`Expected a non-zero positive integer, got ${value}`);
|
|
276
|
+
});
|
|
277
|
+
const boolean = typeofValidator("boolean");
|
|
278
|
+
const bigint = typeofValidator("bigint");
|
|
279
|
+
function literal(expectedValue) {
|
|
280
|
+
return new Validator((actualValue) => {
|
|
281
|
+
if (actualValue !== expectedValue) {
|
|
282
|
+
throw new ValidationError(`Expected ${expectedValue}, got ${JSON.stringify(actualValue)}`);
|
|
283
|
+
}
|
|
284
|
+
return expectedValue;
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
const array = new Validator((value) => {
|
|
288
|
+
if (!Array.isArray(value)) {
|
|
289
|
+
throw new ValidationError(`Expected an array, got ${typeToString(value)}`);
|
|
290
|
+
}
|
|
291
|
+
return value;
|
|
292
|
+
});
|
|
293
|
+
function arrayOf(itemValidator) {
|
|
294
|
+
return new ArrayOfValidator(itemValidator);
|
|
295
|
+
}
|
|
296
|
+
const unknownObject = new Validator((value) => {
|
|
297
|
+
if (typeof value !== "object" || value === null) {
|
|
298
|
+
throw new ValidationError(`Expected object, got ${typeToString(value)}`);
|
|
299
|
+
}
|
|
300
|
+
return value;
|
|
301
|
+
});
|
|
302
|
+
function object(config) {
|
|
303
|
+
return new ObjectValidator(config);
|
|
304
|
+
}
|
|
305
|
+
function isValidJson(value) {
|
|
306
|
+
if (value === null || typeof value === "number" || typeof value === "string" || typeof value === "boolean") {
|
|
307
|
+
return true;
|
|
308
|
+
}
|
|
309
|
+
if (Array.isArray(value)) {
|
|
310
|
+
return value.every(isValidJson);
|
|
311
|
+
}
|
|
312
|
+
if (typeof value === "object") {
|
|
313
|
+
return Object.values(value).every(isValidJson);
|
|
314
|
+
}
|
|
315
|
+
return false;
|
|
316
|
+
}
|
|
317
|
+
const jsonValue = new Validator((value) => {
|
|
318
|
+
if (isValidJson(value)) {
|
|
319
|
+
return value;
|
|
320
|
+
}
|
|
321
|
+
throw new ValidationError(`Expected json serializable value, got ${typeof value}`);
|
|
322
|
+
});
|
|
323
|
+
function jsonDict() {
|
|
324
|
+
return dict(string, jsonValue);
|
|
325
|
+
}
|
|
326
|
+
function dict(keyValidator, valueValidator) {
|
|
327
|
+
return new DictValidator(keyValidator, valueValidator);
|
|
328
|
+
}
|
|
329
|
+
function union(key, config) {
|
|
330
|
+
return new UnionValidator(key, config, (unknownValue, unknownVariant) => {
|
|
331
|
+
throw new ValidationError(
|
|
332
|
+
`Expected one of ${Object.keys(config).map((key2) => JSON.stringify(key2)).join(" or ")}, got ${JSON.stringify(unknownVariant)}`,
|
|
333
|
+
[key]
|
|
334
|
+
);
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
function model(name, validator) {
|
|
338
|
+
return new Validator((value) => {
|
|
339
|
+
const prefix = value && typeof value === "object" && "id" in value && typeof value.id === "string" ? `${name}(id = ${value.id})` : name;
|
|
340
|
+
return prefixError(prefix, () => validator.validate(value));
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
function setEnum(values) {
|
|
344
|
+
return new Validator((value) => {
|
|
345
|
+
if (!values.has(value)) {
|
|
346
|
+
const valuesString = Array.from(values, (value2) => JSON.stringify(value2)).join(" or ");
|
|
347
|
+
throw new ValidationError(`Expected ${valuesString}, got ${value}`);
|
|
348
|
+
}
|
|
349
|
+
return value;
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
function optional(validator) {
|
|
353
|
+
return new Validator((value) => {
|
|
354
|
+
if (value === void 0)
|
|
355
|
+
return void 0;
|
|
356
|
+
return validator.validate(value);
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
function nullable(validator) {
|
|
360
|
+
return new Validator((value) => {
|
|
361
|
+
if (value === null)
|
|
362
|
+
return null;
|
|
363
|
+
return validator.validate(value);
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
function literalEnum(...values) {
|
|
367
|
+
return setEnum(new Set(values));
|
|
368
|
+
}
|
|
369
|
+
export {
|
|
370
|
+
ArrayOfValidator,
|
|
371
|
+
DictValidator,
|
|
372
|
+
ObjectValidator,
|
|
373
|
+
UnionValidator,
|
|
374
|
+
ValidationError,
|
|
375
|
+
Validator,
|
|
376
|
+
any,
|
|
377
|
+
array,
|
|
378
|
+
arrayOf,
|
|
379
|
+
bigint,
|
|
380
|
+
boolean,
|
|
381
|
+
dict,
|
|
382
|
+
integer,
|
|
383
|
+
jsonDict,
|
|
384
|
+
jsonValue,
|
|
385
|
+
literal,
|
|
386
|
+
literalEnum,
|
|
387
|
+
model,
|
|
388
|
+
nonZeroInteger,
|
|
389
|
+
nonZeroNumber,
|
|
390
|
+
nullable,
|
|
391
|
+
number,
|
|
392
|
+
object,
|
|
393
|
+
optional,
|
|
394
|
+
positiveInteger,
|
|
395
|
+
positiveNumber,
|
|
396
|
+
setEnum,
|
|
397
|
+
string,
|
|
398
|
+
union,
|
|
399
|
+
unknown,
|
|
400
|
+
unknownObject
|
|
401
|
+
};
|
|
402
|
+
//# sourceMappingURL=validation.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/lib/validation.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n\tJsonValue,\n\texhaustiveSwitchError,\n\tgetOwnProperty,\n\thasOwnProperty,\n} from '@digitalsamba/utils'\n\n/** @public */\nexport type ValidatorFn<T> = (value: unknown) => T\n\n/** @public */\nexport type Validatable<T> = { validate: (value: unknown) => T }\n\nfunction formatPath(path: ReadonlyArray<number | string>): string | null {\n\tif (!path.length) {\n\t\treturn null\n\t}\n\tlet formattedPath = ''\n\tfor (const item of path) {\n\t\tif (typeof item === 'number') {\n\t\t\tformattedPath += `.${item}`\n\t\t} else if (item.startsWith('(')) {\n\t\t\tif (formattedPath.endsWith(')')) {\n\t\t\t\tformattedPath = `${formattedPath.slice(0, -1)}, ${item.slice(1)}`\n\t\t\t} else {\n\t\t\t\tformattedPath += item\n\t\t\t}\n\t\t} else {\n\t\t\tformattedPath += `.${item}`\n\t\t}\n\t}\n\tif (formattedPath.startsWith('.')) {\n\t\treturn formattedPath.slice(1)\n\t}\n\treturn formattedPath\n}\n\n/** @public */\nexport class ValidationError extends Error {\n\toverride name = 'ValidationError'\n\n\tconstructor(\n\t\tpublic readonly rawMessage: string,\n\t\tpublic readonly path: ReadonlyArray<number | string> = []\n\t) {\n\t\tconst formattedPath = formatPath(path)\n\t\tconst indentedMessage = rawMessage\n\t\t\t.split('\\n')\n\t\t\t.map((line, i) => (i === 0 ? line : ` ${line}`))\n\t\t\t.join('\\n')\n\t\tsuper(path ? `At ${formattedPath}: ${indentedMessage}` : indentedMessage)\n\t}\n}\n\nfunction prefixError<T>(path: string | number, fn: () => T): T {\n\ttry {\n\t\treturn fn()\n\t} catch (err) {\n\t\tif (err instanceof ValidationError) {\n\t\t\tthrow new ValidationError(err.rawMessage, [path, ...err.path])\n\t\t}\n\t\tthrow new ValidationError((err as Error).toString(), [path])\n\t}\n}\n\nfunction typeToString(value: unknown): string {\n\tif (value === null) return 'null'\n\tif (Array.isArray(value)) return 'an array'\n\tconst type = typeof value\n\tswitch (type) {\n\t\tcase 'bigint':\n\t\tcase 'boolean':\n\t\tcase 'function':\n\t\tcase 'number':\n\t\tcase 'string':\n\t\tcase 'symbol':\n\t\t\treturn `a ${type}`\n\t\tcase 'object':\n\t\t\treturn `an ${type}`\n\t\tcase 'undefined':\n\t\t\treturn 'undefined'\n\t\tdefault:\n\t\t\texhaustiveSwitchError(type)\n\t}\n}\n\n/** @public */\nexport type TypeOf<V extends Validatable<unknown>> = V extends Validatable<infer T> ? T : never\n\n/** @public */\nexport class Validator<T> implements Validatable<T> {\n\tconstructor(readonly validationFn: ValidatorFn<T>) {}\n\n\t/**\n\t * Asserts that the passed value is of the correct type and returns it. The returned value is\n\t * guaranteed to be referentially equal to the passed value.\n\t */\n\tvalidate(value: unknown): T {\n\t\tconst validated = this.validationFn(value)\n\t\tif (process.env.NODE_ENV !== 'production' && !Object.is(value, validated)) {\n\t\t\tthrow new ValidationError('Validator functions must return the same value they were passed')\n\t\t}\n\t\treturn validated\n\t}\n\n\t/**\n\t * Returns a new validator that also accepts null or undefined. The resulting value will always be\n\t * null.\n\t */\n\tnullable(): Validator<T | null> {\n\t\treturn nullable(this)\n\t}\n\n\t/**\n\t * Returns a new validator that also accepts null or undefined. The resulting value will always be\n\t * null.\n\t */\n\toptional(): Validator<T | undefined> {\n\t\treturn optional(this)\n\t}\n\n\t/**\n\t * Refine this validation to a new type. The passed-in validation function should throw an error\n\t * if the value can't be converted to the new type, or return the new type otherwise.\n\t */\n\trefine<U>(otherValidationFn: (value: T) => U): Validator<U> {\n\t\treturn new Validator((value) => {\n\t\t\treturn otherValidationFn(this.validate(value))\n\t\t})\n\t}\n\n\t/**\n\t * Refine this validation with an additional check that doesn't change the resulting value.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const numberLessThan10Validator = T.number.check((value) => {\n\t * \tif (value >= 10) {\n\t * \t\tthrow new ValidationError(`Expected number less than 10, got ${value}`)\n\t * \t}\n\t * })\n\t * ```\n\t */\n\tcheck(name: string, checkFn: (value: T) => void): Validator<T>\n\tcheck(checkFn: (value: T) => void): Validator<T>\n\tcheck(nameOrCheckFn: string | ((value: T) => void), checkFn?: (value: T) => void): Validator<T> {\n\t\tif (typeof nameOrCheckFn === 'string') {\n\t\t\treturn this.refine((value) => {\n\t\t\t\tprefixError(`(check ${nameOrCheckFn})`, () => checkFn!(value))\n\t\t\t\treturn value\n\t\t\t})\n\t\t} else {\n\t\t\treturn this.refine((value) => {\n\t\t\t\tnameOrCheckFn(value)\n\t\t\t\treturn value\n\t\t\t})\n\t\t}\n\t}\n}\n\n/** @public */\nexport class ArrayOfValidator<T> extends Validator<T[]> {\n\tconstructor(readonly itemValidator: Validatable<T>) {\n\t\tsuper((value) => {\n\t\t\tconst arr = array.validate(value)\n\t\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\t\tprefixError(i, () => itemValidator.validate(arr[i]))\n\t\t\t}\n\t\t\treturn arr as T[]\n\t\t})\n\t}\n\n\tnonEmpty() {\n\t\treturn this.check((value) => {\n\t\t\tif (value.length === 0) {\n\t\t\t\tthrow new ValidationError('Expected a non-empty array')\n\t\t\t}\n\t\t})\n\t}\n\n\tlengthGreaterThan1() {\n\t\treturn this.check((value) => {\n\t\t\tif (value.length <= 1) {\n\t\t\t\tthrow new ValidationError('Expected an array with length greater than 1')\n\t\t\t}\n\t\t})\n\t}\n}\n\n/** @public */\nexport class ObjectValidator<Shape extends object> extends Validator<Shape> {\n\tconstructor(\n\t\tpublic readonly config: {\n\t\t\treadonly [K in keyof Shape]: Validatable<Shape[K]>\n\t\t},\n\t\tprivate readonly shouldAllowUnknownProperties = false\n\t) {\n\t\tsuper((object) => {\n\t\t\tif (typeof object !== 'object' || object === null) {\n\t\t\t\tthrow new ValidationError(`Expected object, got ${typeToString(object)}`)\n\t\t\t}\n\n\t\t\tfor (const [key, validator] of Object.entries(config)) {\n\t\t\t\tprefixError(key, () => {\n\t\t\t\t\t;(validator as Validator<unknown>).validate(getOwnProperty(object, key))\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tif (!shouldAllowUnknownProperties) {\n\t\t\t\tfor (const key of Object.keys(object)) {\n\t\t\t\t\tif (!hasOwnProperty(config, key)) {\n\t\t\t\t\t\tthrow new ValidationError(`Unexpected property`, [key])\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn object as Shape\n\t\t})\n\t}\n\n\tallowUnknownProperties() {\n\t\treturn new ObjectValidator(this.config, true)\n\t}\n\n\t/**\n\t * Extend an object validator by adding additional properties.\n\t *\n\t * @example\n\t *\n\t * ```ts\n\t * const animalValidator = T.object({\n\t * \tname: T.string,\n\t * })\n\t * const catValidator = animalValidator.extend({\n\t * \tmeowVolume: T.number,\n\t * })\n\t * ```\n\t */\n\textend<Extension extends Record<string, unknown>>(extension: {\n\t\treadonly [K in keyof Extension]: Validatable<Extension[K]>\n\t}): ObjectValidator<Shape & Extension> {\n\t\treturn new ObjectValidator({ ...this.config, ...extension }) as ObjectValidator<\n\t\t\tShape & Extension\n\t\t>\n\t}\n}\n\n// pass this into itself e.g. Config extends UnionObjectSchemaConfig<Key, Config>\ntype UnionValidatorConfig<Key extends string, Config> = {\n\treadonly [Variant in keyof Config]: Validatable<any> & {\n\t\tvalidate: (input: any) => { readonly [K in Key]: Variant }\n\t}\n}\n/** @public */\nexport class UnionValidator<\n\tKey extends string,\n\tConfig extends UnionValidatorConfig<Key, Config>,\n\tUnknownValue = never\n> extends Validator<TypeOf<Config[keyof Config]> | UnknownValue> {\n\tconstructor(\n\t\tprivate readonly key: Key,\n\t\tprivate readonly config: Config,\n\t\tprivate readonly unknownValueValidation: (value: object, variant: string) => UnknownValue\n\t) {\n\t\tsuper((input) => {\n\t\t\tif (typeof input !== 'object' || input === null) {\n\t\t\t\tthrow new ValidationError(`Expected an object, got ${typeToString(input)}`, [])\n\t\t\t}\n\n\t\t\tconst variant = getOwnProperty(input, key) as keyof Config | undefined\n\t\t\tif (typeof variant !== 'string') {\n\t\t\t\tthrow new ValidationError(\n\t\t\t\t\t`Expected a string for key \"${key}\", got ${typeToString(variant)}`\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst matchingSchema = hasOwnProperty(config, variant) ? config[variant] : undefined\n\t\t\tif (matchingSchema === undefined) {\n\t\t\t\treturn this.unknownValueValidation(input, variant)\n\t\t\t}\n\n\t\t\treturn prefixError(`(${key} = ${variant})`, () => matchingSchema.validate(input))\n\t\t})\n\t}\n\n\tvalidateUnknownVariants<Unknown>(\n\t\tunknownValueValidation: (value: object, variant: string) => Unknown\n\t): UnionValidator<Key, Config, Unknown> {\n\t\treturn new UnionValidator(this.key, this.config, unknownValueValidation)\n\t}\n}\n\n/** @public */\nexport class DictValidator<Key extends string, Value> extends Validator<Record<Key, Value>> {\n\tconstructor(\n\t\tpublic readonly keyValidator: Validatable<Key>,\n\t\tpublic readonly valueValidator: Validatable<Value>\n\t) {\n\t\tsuper((object) => {\n\t\t\tif (typeof object !== 'object' || object === null) {\n\t\t\t\tthrow new ValidationError(`Expected object, got ${typeToString(object)}`)\n\t\t\t}\n\n\t\t\tfor (const [key, value] of Object.entries(object)) {\n\t\t\t\tprefixError(key, () => {\n\t\t\t\t\tkeyValidator.validate(key)\n\t\t\t\t\tvalueValidator.validate(value)\n\t\t\t\t})\n\t\t\t}\n\n\t\t\treturn object as Record<Key, Value>\n\t\t})\n\t}\n}\n\nfunction typeofValidator<T>(type: string): Validator<T> {\n\treturn new Validator((value) => {\n\t\tif (typeof value !== type) {\n\t\t\tthrow new ValidationError(`Expected ${type}, got ${typeToString(value)}`)\n\t\t}\n\t\treturn value as T\n\t})\n}\n\n/**\n * Validation that accepts any value. Useful as a starting point for building your own custom\n * validations.\n *\n * @public\n */\nexport const unknown = new Validator((value) => value)\n/**\n * Validation that accepts any value. Generally this should be avoided, but you can use it as an\n * escape hatch if you want to work without validations for e.g. a prototype.\n *\n * @public\n */\nexport const any = new Validator((value): any => value)\n\n/**\n * Validates that a value is a string.\n *\n * @public\n */\nexport const string = typeofValidator<string>('string')\n\n/**\n * Validates that a value is a finite non-NaN number.\n *\n * @public\n */\nexport const number = typeofValidator<number>('number').check((number) => {\n\tif (Number.isNaN(number)) {\n\t\tthrow new ValidationError('Expected a number, got NaN')\n\t}\n\tif (!Number.isFinite(number)) {\n\t\tthrow new ValidationError(`Expected a finite number, got ${number}`)\n\t}\n})\n/**\n * Fails if value \\< 0\n *\n * @public\n */\nexport const positiveNumber = number.check((value) => {\n\tif (value < 0) throw new ValidationError(`Expected a positive number, got ${value}`)\n})\n/**\n * Fails if value \\<= 0\n *\n * @public\n */\nexport const nonZeroNumber = number.check((value) => {\n\tif (value <= 0) throw new ValidationError(`Expected a non-zero positive number, got ${value}`)\n})\n/**\n * Fails if number is not an integer\n *\n * @public\n */\nexport const integer = number.check((value) => {\n\tif (!Number.isInteger(value)) throw new ValidationError(`Expected an integer, got ${value}`)\n})\n/**\n * Fails if value \\< 0 and is not an integer\n *\n * @public\n */\nexport const positiveInteger = integer.check((value) => {\n\tif (value < 0) throw new ValidationError(`Expected a positive integer, got ${value}`)\n})\n/**\n * Fails if value \\<= 0 and is not an integer\n *\n * @public\n */\nexport const nonZeroInteger = integer.check((value) => {\n\tif (value <= 0) throw new ValidationError(`Expected a non-zero positive integer, got ${value}`)\n})\n\n/**\n * Validates that a value is boolean.\n *\n * @public\n */\nexport const boolean = typeofValidator<boolean>('boolean')\n/**\n * Validates that a value is a bigint.\n *\n * @public\n */\nexport const bigint = typeofValidator<bigint>('bigint')\n/**\n * Validates that a value matches another that was passed in.\n *\n * @example\n *\n * ```ts\n * const trueValidator = T.literal(true)\n * ```\n *\n * @public\n */\nexport function literal<T extends string | number | boolean>(expectedValue: T): Validator<T> {\n\treturn new Validator((actualValue) => {\n\t\tif (actualValue !== expectedValue) {\n\t\t\tthrow new ValidationError(`Expected ${expectedValue}, got ${JSON.stringify(actualValue)}`)\n\t\t}\n\t\treturn expectedValue\n\t})\n}\n\n/**\n * Validates that a value is an array. To check the contents of the array, use T.arrayOf.\n *\n * @public\n */\nexport const array = new Validator<unknown[]>((value) => {\n\tif (!Array.isArray(value)) {\n\t\tthrow new ValidationError(`Expected an array, got ${typeToString(value)}`)\n\t}\n\treturn value\n})\n\n/**\n * Validates that a value is an array whose contents matches the passed-in validator.\n *\n * @public\n */\nexport function arrayOf<T>(itemValidator: Validatable<T>): ArrayOfValidator<T> {\n\treturn new ArrayOfValidator(itemValidator)\n}\n\n/** @public */\nexport const unknownObject = new Validator<Record<string, unknown>>((value) => {\n\tif (typeof value !== 'object' || value === null) {\n\t\tthrow new ValidationError(`Expected object, got ${typeToString(value)}`)\n\t}\n\treturn value as Record<string, unknown>\n})\n\n/**\n * Validate an object has a particular shape.\n *\n * @public\n */\nexport function object<Shape extends object>(config: {\n\treadonly [K in keyof Shape]: Validatable<Shape[K]>\n}): ObjectValidator<Shape> {\n\treturn new ObjectValidator(config)\n}\n\nfunction isValidJson(value: any): value is JsonValue {\n\tif (\n\t\tvalue === null ||\n\t\ttypeof value === 'number' ||\n\t\ttypeof value === 'string' ||\n\t\ttypeof value === 'boolean'\n\t) {\n\t\treturn true\n\t}\n\n\tif (Array.isArray(value)) {\n\t\treturn value.every(isValidJson)\n\t}\n\n\tif (typeof value === 'object') {\n\t\treturn Object.values(value).every(isValidJson)\n\t}\n\n\treturn false\n}\n\n/**\n * Validate that a value is valid JSON.\n *\n * @public\n */\nexport const jsonValue = new Validator<JsonValue>((value): JsonValue => {\n\tif (isValidJson(value)) {\n\t\treturn value as JsonValue\n\t}\n\n\tthrow new ValidationError(`Expected json serializable value, got ${typeof value}`)\n})\n\n/**\n * Validate an object has a particular shape.\n *\n * @public\n */\nexport function jsonDict(): DictValidator<string, JsonValue> {\n\treturn dict(string, jsonValue)\n}\n\n/**\n * Validation that an option is a dict with particular keys and values.\n *\n * @public\n */\nexport function dict<Key extends string, Value>(\n\tkeyValidator: Validatable<Key>,\n\tvalueValidator: Validatable<Value>\n): DictValidator<Key, Value> {\n\treturn new DictValidator(keyValidator, valueValidator)\n}\n\n/**\n * Validate a union of several object types. Each object must have a property matching `key` which\n * should be a unique string.\n *\n * @example\n *\n * ```ts\n * const catValidator = T.object({ kind: T.value('cat'), meow: T.boolean })\n * const dogValidator = T.object({ kind: T.value('dog'), bark: T.boolean })\n * const animalValidator = T.union('kind', { cat: catValidator, dog: dogValidator })\n * ```\n *\n * @public\n */\nexport function union<Key extends string, Config extends UnionValidatorConfig<Key, Config>>(\n\tkey: Key,\n\tconfig: Config\n): UnionValidator<Key, Config> {\n\treturn new UnionValidator(key, config, (unknownValue, unknownVariant) => {\n\t\tthrow new ValidationError(\n\t\t\t`Expected one of ${Object.keys(config)\n\t\t\t\t.map((key) => JSON.stringify(key))\n\t\t\t\t.join(' or ')}, got ${JSON.stringify(unknownVariant)}`,\n\t\t\t[key]\n\t\t)\n\t})\n}\n\n/**\n * A named object with an ID. Errors will be reported as being part of the object with the given\n * name.\n *\n * @public\n */\nexport function model<T extends { readonly id: string }>(\n\tname: string,\n\tvalidator: Validatable<T>\n): Validator<T> {\n\treturn new Validator((value) => {\n\t\tconst prefix =\n\t\t\tvalue && typeof value === 'object' && 'id' in value && typeof value.id === 'string'\n\t\t\t\t? `${name}(id = ${value.id})`\n\t\t\t\t: name\n\n\t\treturn prefixError(prefix, () => validator.validate(value))\n\t})\n}\n\n/** @public */\nexport function setEnum<T>(values: ReadonlySet<T>): Validator<T> {\n\treturn new Validator((value) => {\n\t\tif (!values.has(value as T)) {\n\t\t\tconst valuesString = Array.from(values, (value) => JSON.stringify(value)).join(' or ')\n\t\t\tthrow new ValidationError(`Expected ${valuesString}, got ${value}`)\n\t\t}\n\t\treturn value as T\n\t})\n}\n\n/** @public */\nexport function optional<T>(validator: Validatable<T>): Validator<T | undefined> {\n\treturn new Validator((value) => {\n\t\tif (value === undefined) return undefined\n\t\treturn validator.validate(value)\n\t})\n}\n\n/** @public */\nexport function nullable<T>(validator: Validatable<T>): Validator<T | null> {\n\treturn new Validator((value) => {\n\t\tif (value === null) return null\n\t\treturn validator.validate(value)\n\t})\n}\n\n/** @public */\nexport function literalEnum<const Values extends readonly unknown[]>(\n\t...values: Values\n): Validator<Values[number]> {\n\treturn setEnum(new Set(values))\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["object", "number", "key", "value"]
|
|
7
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@digitalsamba/validate",
|
|
3
|
+
"description": "A runtime validation library by tldraw.",
|
|
4
|
+
"version": "2.0.0-canary.1b923c9db3e2",
|
|
5
|
+
"packageManager": "yarn@3.5.0",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "tldraw GB Ltd."
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://tldraw.dev",
|
|
10
|
+
"license": "Apache-2.0",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/tldraw/tldraw"
|
|
14
|
+
},
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/tldraw/tldraw/issues"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"tldraw",
|
|
20
|
+
"drawing",
|
|
21
|
+
"app",
|
|
22
|
+
"development",
|
|
23
|
+
"whiteboard",
|
|
24
|
+
"canvas",
|
|
25
|
+
"infinite"
|
|
26
|
+
],
|
|
27
|
+
"main": "dist-cjs/index.js",
|
|
28
|
+
"files": [
|
|
29
|
+
"dist-esm",
|
|
30
|
+
"dist-cjs",
|
|
31
|
+
"src"
|
|
32
|
+
],
|
|
33
|
+
"scripts": {
|
|
34
|
+
"test": "lazy inherit",
|
|
35
|
+
"test-coverage": "lazy inherit",
|
|
36
|
+
"build": "yarn run -T tsx ../../scripts/build-package.ts",
|
|
37
|
+
"build-api": "yarn run -T tsx ../../scripts/build-api.ts",
|
|
38
|
+
"prepack": "yarn run -T tsx ../../scripts/prepack.ts",
|
|
39
|
+
"postpack": "../../scripts/postpack.sh",
|
|
40
|
+
"pack-tarball": "yarn pack",
|
|
41
|
+
"lint": "yarn run -T tsx ../../scripts/lint.ts"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@digitalsamba/utils": "2.0.0-canary.1b923c9db3e2"
|
|
45
|
+
},
|
|
46
|
+
"jest": {
|
|
47
|
+
"preset": "config/jest/node",
|
|
48
|
+
"setupFiles": [
|
|
49
|
+
"raf/polyfill"
|
|
50
|
+
],
|
|
51
|
+
"moduleNameMapper": {
|
|
52
|
+
"^~(.*)": "<rootDir>/src/$1"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"lazyrepo": "0.0.0-alpha.27"
|
|
57
|
+
},
|
|
58
|
+
"module": "dist-esm/index.mjs",
|
|
59
|
+
"source": "src/index.ts",
|
|
60
|
+
"exports": {
|
|
61
|
+
".": {
|
|
62
|
+
"import": "./dist-esm/index.mjs",
|
|
63
|
+
"require": "./dist-cjs/index.js"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|