@tldraw/validate 3.9.0 → 3.10.0-canary.3176429f9d1b

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist-cjs/index.js CHANGED
@@ -41,7 +41,7 @@ var T = __toESM(require("./lib/validation"));
41
41
  var import_validation = require("./lib/validation");
42
42
  (0, import_utils.registerTldrawLibraryVersion)(
43
43
  "@tldraw/validate",
44
- "3.9.0",
44
+ "3.10.0-canary.3176429f9d1b",
45
45
  "cjs"
46
46
  );
47
47
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/validation.ts"],
4
- "sourcesContent": ["import {\n\tIndexKey,\n\tJsonValue,\n\tMakeUndefinedOptional,\n\tSTRUCTURED_CLONE_OBJECT_PROTOTYPE,\n\texhaustiveSwitchError,\n\tgetOwnProperty,\n\thasOwnProperty,\n\tvalidateIndexKey,\n} from '@tldraw/utils'\n\n/** @public */\nexport type ValidatorFn<T> = (value: unknown) => T\n/** @public */\nexport type ValidatorUsingKnownGoodVersionFn<In, Out = In> = (\n\tknownGoodValue: In,\n\tvalue: unknown\n) => Out\n\n/** @public */\nexport interface Validatable<T> {\n\tvalidate(value: unknown): T\n\t/**\n\t * This is a performance optimizing version of validate that can use a previous\n\t * version of the value to avoid revalidating every part of the new value if\n\t * any part of it has not changed since the last validation.\n\t *\n\t * If the value has not changed but is not referentially equal, the function\n\t * should return the previous value.\n\t * @returns\n\t */\n\tvalidateUsingKnownGoodVersion?(knownGoodValue: T, newValue: unknown): T\n}\n\nfunction formatPath(path: ReadonlyArray<number | string>): string | null {\n\tif (!path.length) {\n\t\treturn null\n\t}\n\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\n\t// N.B. We don't want id's in the path because they make grouping in Sentry tough.\n\tformattedPath = formattedPath.replace(/id = [^,]+, /, '').replace(/id = [^)]+/, '')\n\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<any>> = V extends Validatable<infer T> ? T : never\n\n/** @public */\nexport class Validator<T> implements Validatable<T> {\n\tconstructor(\n\t\treadonly validationFn: ValidatorFn<T>,\n\t\treadonly validateUsingKnownGoodVersionFn?: ValidatorUsingKnownGoodVersionFn<T>\n\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\tvalidateUsingKnownGoodVersion(knownGoodValue: T, newValue: unknown): T {\n\t\tif (Object.is(knownGoodValue, newValue)) {\n\t\t\treturn knownGoodValue as T\n\t\t}\n\n\t\tif (this.validateUsingKnownGoodVersionFn) {\n\t\t\treturn this.validateUsingKnownGoodVersionFn(knownGoodValue, newValue)\n\t\t}\n\n\t\treturn this.validate(newValue)\n\t}\n\n\t/** Checks that the passed value is of the correct type. */\n\tisValid(value: unknown): value is T {\n\t\ttry {\n\t\t\tthis.validate(value)\n\t\t\treturn true\n\t\t} catch {\n\t\t\treturn false\n\t\t}\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(\n\t\t\t(value) => {\n\t\t\t\treturn otherValidationFn(this.validate(value))\n\t\t\t},\n\n\t\t\t(knownGoodValue, newValue) => {\n\t\t\t\tconst validated = this.validateUsingKnownGoodVersion(knownGoodValue as any, newValue)\n\t\t\t\tif (Object.is(knownGoodValue, validated)) {\n\t\t\t\t\treturn knownGoodValue\n\t\t\t\t}\n\t\t\t\treturn otherValidationFn(validated)\n\t\t\t}\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(\n\t\t\t(value) => {\n\t\t\t\tconst arr = array.validate(value)\n\t\t\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\t\t\tprefixError(i, () => itemValidator.validate(arr[i]))\n\t\t\t\t}\n\t\t\t\treturn arr as T[]\n\t\t\t},\n\t\t\t(knownGoodValue, newValue) => {\n\t\t\t\tif (!itemValidator.validateUsingKnownGoodVersion) return this.validate(newValue)\n\t\t\t\tconst arr = array.validate(newValue)\n\t\t\t\tlet isDifferent = knownGoodValue.length !== arr.length\n\t\t\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\t\t\tconst item = arr[i]\n\t\t\t\t\tif (i >= knownGoodValue.length) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t\tprefixError(i, () => itemValidator.validate(item))\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\t// sneaky quick check here to avoid the prefix + validator overhead\n\t\t\t\t\tif (Object.is(knownGoodValue[i], item)) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tconst checkedItem = prefixError(i, () =>\n\t\t\t\t\t\titemValidator.validateUsingKnownGoodVersion!(knownGoodValue[i], item)\n\t\t\t\t\t)\n\t\t\t\t\tif (!Object.is(checkedItem, knownGoodValue[i])) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn isDifferent ? (newValue as T[]) : knownGoodValue\n\t\t\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(\n\t\t\t(object) => {\n\t\t\t\tif (typeof object !== 'object' || object === null) {\n\t\t\t\t\tthrow new ValidationError(`Expected object, got ${typeToString(object)}`)\n\t\t\t\t}\n\n\t\t\t\tfor (const [key, validator] of Object.entries(config)) {\n\t\t\t\t\tprefixError(key, () => {\n\t\t\t\t\t\t;(validator as Validatable<unknown>).validate(getOwnProperty(object, key))\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tif (!shouldAllowUnknownProperties) {\n\t\t\t\t\tfor (const key of Object.keys(object)) {\n\t\t\t\t\t\tif (!hasOwnProperty(config, key)) {\n\t\t\t\t\t\t\tthrow new ValidationError(`Unexpected property`, [key])\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn object as Shape\n\t\t\t},\n\t\t\t(knownGoodValue, newValue) => {\n\t\t\t\tif (typeof newValue !== 'object' || newValue === null) {\n\t\t\t\t\tthrow new ValidationError(`Expected object, got ${typeToString(newValue)}`)\n\t\t\t\t}\n\n\t\t\t\tlet isDifferent = false\n\n\t\t\t\tfor (const [key, validator] of Object.entries(config)) {\n\t\t\t\t\tconst prev = getOwnProperty(knownGoodValue, key)\n\t\t\t\t\tconst next = getOwnProperty(newValue, key)\n\t\t\t\t\t// sneaky quick check here to avoid the prefix + validator overhead\n\t\t\t\t\tif (Object.is(prev, next)) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tconst checked = prefixError(key, () => {\n\t\t\t\t\t\tconst validatable = validator as Validatable<unknown>\n\t\t\t\t\t\tif (validatable.validateUsingKnownGoodVersion) {\n\t\t\t\t\t\t\treturn validatable.validateUsingKnownGoodVersion(prev, next)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn validatable.validate(next)\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\tif (!Object.is(checked, prev)) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!shouldAllowUnknownProperties) {\n\t\t\t\t\tfor (const key of Object.keys(newValue)) {\n\t\t\t\t\t\tif (!hasOwnProperty(config, key)) {\n\t\t\t\t\t\t\tthrow new ValidationError(`Unexpected property`, [key])\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor (const key of Object.keys(knownGoodValue)) {\n\t\t\t\t\tif (!hasOwnProperty(newValue, key)) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn isDifferent ? (newValue as Shape) : knownGoodValue\n\t\t\t}\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 any 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>\n/** @public */\nexport type 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\tprivate readonly useNumberKeys: boolean\n\t) {\n\t\tsuper(\n\t\t\t(input) => {\n\t\t\t\tthis.expectObject(input)\n\n\t\t\t\tconst { matchingSchema, variant } = this.getMatchingSchemaAndVariant(input)\n\t\t\t\tif (matchingSchema === undefined) {\n\t\t\t\t\treturn this.unknownValueValidation(input, variant)\n\t\t\t\t}\n\n\t\t\t\treturn prefixError(`(${key} = ${variant})`, () => matchingSchema.validate(input))\n\t\t\t},\n\t\t\t(prevValue, newValue) => {\n\t\t\t\tthis.expectObject(newValue)\n\t\t\t\tthis.expectObject(prevValue)\n\n\t\t\t\tconst { matchingSchema, variant } = this.getMatchingSchemaAndVariant(newValue)\n\t\t\t\tif (matchingSchema === undefined) {\n\t\t\t\t\treturn this.unknownValueValidation(newValue, variant)\n\t\t\t\t}\n\n\t\t\t\tif (getOwnProperty(prevValue, key) !== getOwnProperty(newValue, key)) {\n\t\t\t\t\t// the type has changed so bail out and do a regular validation\n\t\t\t\t\treturn prefixError(`(${key} = ${variant})`, () => matchingSchema.validate(newValue))\n\t\t\t\t}\n\n\t\t\t\treturn prefixError(`(${key} = ${variant})`, () => {\n\t\t\t\t\tif (matchingSchema.validateUsingKnownGoodVersion) {\n\t\t\t\t\t\treturn matchingSchema.validateUsingKnownGoodVersion(prevValue, newValue)\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn matchingSchema.validate(newValue)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t)\n\t}\n\n\tprivate expectObject(value: unknown): asserts value is object {\n\t\tif (typeof value !== 'object' || value === null) {\n\t\t\tthrow new ValidationError(`Expected an object, got ${typeToString(value)}`, [])\n\t\t}\n\t}\n\n\tprivate getMatchingSchemaAndVariant(object: object): {\n\t\tmatchingSchema: Validatable<any> | undefined\n\t\tvariant: string\n\t} {\n\t\tconst variant = getOwnProperty(object, this.key) as string & keyof Config\n\t\tif (!this.useNumberKeys && typeof variant !== 'string') {\n\t\t\tthrow new ValidationError(\n\t\t\t\t`Expected a string for key \"${this.key}\", got ${typeToString(variant)}`\n\t\t\t)\n\t\t} else if (this.useNumberKeys && !Number.isFinite(Number(variant))) {\n\t\t\tthrow new ValidationError(`Expected a number for key \"${this.key}\", got \"${variant as any}\"`)\n\t\t}\n\n\t\tconst matchingSchema = hasOwnProperty(this.config, variant) ? this.config[variant] : undefined\n\t\treturn { matchingSchema, variant }\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, this.useNumberKeys)\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(\n\t\t\t(object) => {\n\t\t\t\tif (typeof object !== 'object' || object === null) {\n\t\t\t\t\tthrow new ValidationError(`Expected object, got ${typeToString(object)}`)\n\t\t\t\t}\n\n\t\t\t\tfor (const [key, value] of Object.entries(object)) {\n\t\t\t\t\tprefixError(key, () => {\n\t\t\t\t\t\tkeyValidator.validate(key)\n\t\t\t\t\t\tvalueValidator.validate(value)\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\treturn object as Record<Key, Value>\n\t\t\t},\n\t\t\t(knownGoodValue, newValue) => {\n\t\t\t\tif (typeof newValue !== 'object' || newValue === null) {\n\t\t\t\t\tthrow new ValidationError(`Expected object, got ${typeToString(newValue)}`)\n\t\t\t\t}\n\n\t\t\t\tlet isDifferent = false\n\n\t\t\t\tfor (const [key, value] of Object.entries(newValue)) {\n\t\t\t\t\tif (!hasOwnProperty(knownGoodValue, key)) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t\tprefixError(key, () => {\n\t\t\t\t\t\t\tkeyValidator.validate(key)\n\t\t\t\t\t\t\tvalueValidator.validate(value)\n\t\t\t\t\t\t})\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tconst prev = getOwnProperty(knownGoodValue, key)\n\t\t\t\t\tconst next = value\n\t\t\t\t\t// sneaky quick check here to avoid the prefix + validator overhead\n\t\t\t\t\tif (Object.is(prev, next)) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tconst checked = prefixError(key, () => {\n\t\t\t\t\t\tif (valueValidator.validateUsingKnownGoodVersion) {\n\t\t\t\t\t\t\treturn valueValidator.validateUsingKnownGoodVersion(prev as any, next)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn valueValidator.validate(next)\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\tif (!Object.is(checked, prev)) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor (const key of Object.keys(knownGoodValue)) {\n\t\t\t\t\tif (!hasOwnProperty(newValue, key)) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn isDifferent ? (newValue as Record<Key, Value>) : knownGoodValue\n\t\t\t}\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<MakeUndefinedOptional<Shape>> {\n\treturn new ObjectValidator(config) as any\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\t(Object.getPrototypeOf(value) === Object.prototype ||\n\t\t\tObject.getPrototypeOf(value) === null ||\n\t\t\tObject.getPrototypeOf(value) === STRUCTURED_CLONE_OBJECT_PROTOTYPE)\n\t)\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 (isPlainObject(value)) {\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: Validator<JsonValue> = new Validator<JsonValue>(\n\t(value): JsonValue => {\n\t\tif (isValidJson(value)) {\n\t\t\treturn value as JsonValue\n\t\t}\n\n\t\tthrow new ValidationError(`Expected json serializable value, got ${typeof value}`)\n\t},\n\t(knownGoodValue, newValue) => {\n\t\tif (Array.isArray(knownGoodValue) && Array.isArray(newValue)) {\n\t\t\tlet isDifferent = knownGoodValue.length !== newValue.length\n\t\t\tfor (let i = 0; i < newValue.length; i++) {\n\t\t\t\tif (i >= knownGoodValue.length) {\n\t\t\t\t\tisDifferent = true\n\t\t\t\t\tjsonValue.validate(newValue[i])\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst prev = knownGoodValue[i]\n\t\t\t\tconst next = newValue[i]\n\t\t\t\tif (Object.is(prev, next)) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst checked = jsonValue.validateUsingKnownGoodVersion!(prev, next)\n\t\t\t\tif (!Object.is(checked, prev)) {\n\t\t\t\t\tisDifferent = true\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn isDifferent ? (newValue as JsonValue) : knownGoodValue\n\t\t} else if (isPlainObject(knownGoodValue) && isPlainObject(newValue)) {\n\t\t\tlet isDifferent = false\n\t\t\tfor (const key of Object.keys(newValue)) {\n\t\t\t\tif (!hasOwnProperty(knownGoodValue, key)) {\n\t\t\t\t\tisDifferent = true\n\t\t\t\t\tjsonValue.validate(newValue[key])\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst prev = knownGoodValue[key]\n\t\t\t\tconst next = newValue[key]\n\t\t\t\tif (Object.is(prev, next)) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst checked = jsonValue.validateUsingKnownGoodVersion!(prev!, next)\n\t\t\t\tif (!Object.is(checked, prev)) {\n\t\t\t\t\tisDifferent = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const key of Object.keys(knownGoodValue)) {\n\t\t\t\tif (!hasOwnProperty(newValue, key)) {\n\t\t\t\t\tisDifferent = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn isDifferent ? (newValue as JsonValue) : knownGoodValue\n\t\t} else {\n\t\t\treturn jsonValue.validate(newValue)\n\t\t}\n\t}\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.literal('cat'), meow: T.boolean })\n * const dogValidator = T.object({ kind: T.literal('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(\n\t\tkey,\n\t\tconfig,\n\t\t(_unknownValue, unknownVariant) => {\n\t\t\tthrow new ValidationError(\n\t\t\t\t`Expected one of ${Object.keys(config)\n\t\t\t\t\t.map((key) => JSON.stringify(key))\n\t\t\t\t\t.join(' or ')}, got ${JSON.stringify(unknownVariant)}`,\n\t\t\t\t[key]\n\t\t\t)\n\t\t},\n\t\tfalse\n\t)\n}\n\n/**\n * @internal\n */\nexport function numberUnion<Key extends string, Config extends UnionValidatorConfig<Key, Config>>(\n\tkey: Key,\n\tconfig: Config\n): UnionValidator<Key, Config> {\n\treturn new UnionValidator(\n\t\tkey,\n\t\tconfig,\n\t\t(unknownValue, unknownVariant) => {\n\t\t\tthrow new ValidationError(\n\t\t\t\t`Expected one of ${Object.keys(config)\n\t\t\t\t\t.map((key) => JSON.stringify(key))\n\t\t\t\t\t.join(' or ')}, got ${JSON.stringify(unknownVariant)}`,\n\t\t\t\t[key]\n\t\t\t)\n\t\t},\n\t\ttrue\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(\n\t\t(value) => {\n\t\t\treturn prefixError(name, () => validator.validate(value))\n\t\t},\n\t\t(prevValue, newValue) => {\n\t\t\treturn prefixError(name, () => {\n\t\t\t\tif (validator.validateUsingKnownGoodVersion) {\n\t\t\t\t\treturn validator.validateUsingKnownGoodVersion(prevValue, newValue)\n\t\t\t\t} else {\n\t\t\t\t\treturn validator.validate(newValue)\n\t\t\t\t}\n\t\t\t})\n\t\t}\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(\n\t\t(value) => {\n\t\t\tif (value === undefined) return undefined\n\t\t\treturn validator.validate(value)\n\t\t},\n\t\t(knownGoodValue, newValue) => {\n\t\t\tif (knownGoodValue === undefined && newValue === undefined) return undefined\n\t\t\tif (newValue === undefined) return undefined\n\t\t\tif (validator.validateUsingKnownGoodVersion && knownGoodValue !== undefined) {\n\t\t\t\treturn validator.validateUsingKnownGoodVersion(knownGoodValue as T, newValue)\n\t\t\t}\n\t\t\treturn validator.validate(newValue)\n\t\t}\n\t)\n}\n\n/** @public */\nexport function nullable<T>(validator: Validatable<T>): Validator<T | null> {\n\treturn new Validator(\n\t\t(value) => {\n\t\t\tif (value === null) return null\n\t\t\treturn validator.validate(value)\n\t\t},\n\t\t(knownGoodValue, newValue) => {\n\t\t\tif (newValue === null) return null\n\t\t\tif (validator.validateUsingKnownGoodVersion && knownGoodValue !== null) {\n\t\t\t\treturn validator.validateUsingKnownGoodVersion(knownGoodValue as T, newValue)\n\t\t\t}\n\t\t\treturn validator.validate(newValue)\n\t\t}\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\nfunction parseUrl(str: string) {\n\ttry {\n\t\treturn new URL(str)\n\t} catch {\n\t\tif (str.startsWith('/') || str.startsWith('./')) {\n\t\t\ttry {\n\t\t\t\treturn new URL(str, 'http://example.com')\n\t\t\t} catch {\n\t\t\t\tthrow new ValidationError(`Expected a valid url, got ${JSON.stringify(str)}`)\n\t\t\t}\n\t\t}\n\t\tthrow new ValidationError(`Expected a valid url, got ${JSON.stringify(str)}`)\n\t}\n}\n\nconst validLinkProtocols = new Set(['http:', 'https:', 'mailto:'])\n\n/**\n * Validates that a value is a url safe to use as a link.\n *\n * @public\n */\nexport const linkUrl = string.check((value) => {\n\tif (value === '') return\n\tconst url = parseUrl(value)\n\n\tif (!validLinkProtocols.has(url.protocol.toLowerCase())) {\n\t\tthrow new ValidationError(\n\t\t\t`Expected a valid url, got ${JSON.stringify(value)} (invalid protocol)`\n\t\t)\n\t}\n})\n\n// N.B. asset: is a reference to the local indexedDB object store.\nconst validSrcProtocols = new Set(['http:', 'https:', 'data:', 'asset:'])\n\n/**\n * Validates that a valid is a url safe to load as an asset.\n *\n * @public\n */\nexport const srcUrl = string.check((value) => {\n\tif (value === '') return\n\tconst url = parseUrl(value)\n\n\tif (!validSrcProtocols.has(url.protocol.toLowerCase())) {\n\t\tthrow new ValidationError(\n\t\t\t`Expected a valid url, got ${JSON.stringify(value)} (invalid protocol)`\n\t\t)\n\t}\n})\n\n/**\n * Validates an http(s) url\n *\n * @public\n */\nexport const httpUrl = string.check((value) => {\n\tif (value === '') return\n\tconst url = parseUrl(value)\n\n\tif (!url.protocol.toLowerCase().match(/^https?:$/)) {\n\t\tthrow new ValidationError(\n\t\t\t`Expected a valid url, got ${JSON.stringify(value)} (invalid protocol)`\n\t\t)\n\t}\n})\n\n/**\n * Validates that a value is an IndexKey.\n * @public\n */\nexport const indexKey = string.refine<IndexKey>((key) => {\n\ttry {\n\t\tvalidateIndexKey(key)\n\t\treturn key\n\t} catch {\n\t\tthrow new ValidationError(`Expected an index key, got ${JSON.stringify(key)}`)\n\t}\n})\n\n/**\n * Validate a value against one of two types.\n *\n * @public\n */\nexport function or<T1, T2>(v1: Validatable<T1>, v2: Validatable<T2>): Validator<T1 | T2> {\n\treturn new Validator((value) => {\n\t\ttry {\n\t\t\treturn v1.validate(value)\n\t\t} catch {\n\t\t\treturn v2.validate(value)\n\t\t}\n\t})\n}\n"],
4
+ "sourcesContent": ["import {\n\tIndexKey,\n\tJsonValue,\n\tMakeUndefinedOptional,\n\tSTRUCTURED_CLONE_OBJECT_PROTOTYPE,\n\texhaustiveSwitchError,\n\tgetOwnProperty,\n\thasOwnProperty,\n\tvalidateIndexKey,\n} from '@tldraw/utils'\n\n/** @public */\nexport type ValidatorFn<T> = (value: unknown) => T\n/** @public */\nexport type ValidatorUsingKnownGoodVersionFn<In, Out = In> = (\n\tknownGoodValue: In,\n\tvalue: unknown\n) => Out\n\n/** @public */\nexport interface Validatable<T> {\n\tvalidate(value: unknown): T\n\t/**\n\t * This is a performance optimizing version of validate that can use a previous\n\t * version of the value to avoid revalidating every part of the new value if\n\t * any part of it has not changed since the last validation.\n\t *\n\t * If the value has not changed but is not referentially equal, the function\n\t * should return the previous value.\n\t * @returns\n\t */\n\tvalidateUsingKnownGoodVersion?(knownGoodValue: T, newValue: unknown): T\n}\n\nfunction formatPath(path: ReadonlyArray<number | string>): string | null {\n\tif (!path.length) {\n\t\treturn null\n\t}\n\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\n\t// N.B. We don't want id's in the path because they make grouping in Sentry tough.\n\tformattedPath = formattedPath.replace(/id = [^,]+, /, '').replace(/id = [^)]+/, '')\n\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<any>> = V extends Validatable<infer T> ? T : never\n\n/** @public */\nexport class Validator<T> implements Validatable<T> {\n\tconstructor(\n\t\treadonly validationFn: ValidatorFn<T>,\n\t\treadonly validateUsingKnownGoodVersionFn?: ValidatorUsingKnownGoodVersionFn<T>\n\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\tvalidateUsingKnownGoodVersion(knownGoodValue: T, newValue: unknown): T {\n\t\tif (Object.is(knownGoodValue, newValue)) {\n\t\t\treturn knownGoodValue as T\n\t\t}\n\n\t\tif (this.validateUsingKnownGoodVersionFn) {\n\t\t\treturn this.validateUsingKnownGoodVersionFn(knownGoodValue, newValue)\n\t\t}\n\n\t\treturn this.validate(newValue)\n\t}\n\n\t/** Checks that the passed value is of the correct type. */\n\tisValid(value: unknown): value is T {\n\t\ttry {\n\t\t\tthis.validate(value)\n\t\t\treturn true\n\t\t} catch {\n\t\t\treturn false\n\t\t}\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(\n\t\t\t(value) => {\n\t\t\t\treturn otherValidationFn(this.validate(value))\n\t\t\t},\n\n\t\t\t(knownGoodValue, newValue) => {\n\t\t\t\tconst validated = this.validateUsingKnownGoodVersion(knownGoodValue as any, newValue)\n\t\t\t\tif (Object.is(knownGoodValue, validated)) {\n\t\t\t\t\treturn knownGoodValue\n\t\t\t\t}\n\t\t\t\treturn otherValidationFn(validated)\n\t\t\t}\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(\n\t\t\t(value) => {\n\t\t\t\tconst arr = array.validate(value)\n\t\t\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\t\t\tprefixError(i, () => itemValidator.validate(arr[i]))\n\t\t\t\t}\n\t\t\t\treturn arr as T[]\n\t\t\t},\n\t\t\t(knownGoodValue, newValue) => {\n\t\t\t\tif (!itemValidator.validateUsingKnownGoodVersion) return this.validate(newValue)\n\t\t\t\tconst arr = array.validate(newValue)\n\t\t\t\tlet isDifferent = knownGoodValue.length !== arr.length\n\t\t\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\t\t\tconst item = arr[i]\n\t\t\t\t\tif (i >= knownGoodValue.length) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t\tprefixError(i, () => itemValidator.validate(item))\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\t// sneaky quick check here to avoid the prefix + validator overhead\n\t\t\t\t\tif (Object.is(knownGoodValue[i], item)) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tconst checkedItem = prefixError(i, () =>\n\t\t\t\t\t\titemValidator.validateUsingKnownGoodVersion!(knownGoodValue[i], item)\n\t\t\t\t\t)\n\t\t\t\t\tif (!Object.is(checkedItem, knownGoodValue[i])) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn isDifferent ? (newValue as T[]) : knownGoodValue\n\t\t\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(\n\t\t\t(object) => {\n\t\t\t\tif (typeof object !== 'object' || object === null) {\n\t\t\t\t\tthrow new ValidationError(`Expected object, got ${typeToString(object)}`)\n\t\t\t\t}\n\n\t\t\t\tfor (const [key, validator] of Object.entries(config)) {\n\t\t\t\t\tprefixError(key, () => {\n\t\t\t\t\t\t;(validator as Validatable<unknown>).validate(getOwnProperty(object, key))\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tif (!shouldAllowUnknownProperties) {\n\t\t\t\t\tfor (const key of Object.keys(object)) {\n\t\t\t\t\t\tif (!hasOwnProperty(config, key)) {\n\t\t\t\t\t\t\tthrow new ValidationError(`Unexpected property`, [key])\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn object as Shape\n\t\t\t},\n\t\t\t(knownGoodValue, newValue) => {\n\t\t\t\tif (typeof newValue !== 'object' || newValue === null) {\n\t\t\t\t\tthrow new ValidationError(`Expected object, got ${typeToString(newValue)}`)\n\t\t\t\t}\n\n\t\t\t\tlet isDifferent = false\n\n\t\t\t\tfor (const [key, validator] of Object.entries(config)) {\n\t\t\t\t\tconst prev = getOwnProperty(knownGoodValue, key)\n\t\t\t\t\tconst next = getOwnProperty(newValue, key)\n\t\t\t\t\t// sneaky quick check here to avoid the prefix + validator overhead\n\t\t\t\t\tif (Object.is(prev, next)) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tconst checked = prefixError(key, () => {\n\t\t\t\t\t\tconst validatable = validator as Validatable<unknown>\n\t\t\t\t\t\tif (validatable.validateUsingKnownGoodVersion) {\n\t\t\t\t\t\t\treturn validatable.validateUsingKnownGoodVersion(prev, next)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn validatable.validate(next)\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\tif (!Object.is(checked, prev)) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!shouldAllowUnknownProperties) {\n\t\t\t\t\tfor (const key of Object.keys(newValue)) {\n\t\t\t\t\t\tif (!hasOwnProperty(config, key)) {\n\t\t\t\t\t\t\tthrow new ValidationError(`Unexpected property`, [key])\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor (const key of Object.keys(knownGoodValue)) {\n\t\t\t\t\tif (!hasOwnProperty(newValue, key)) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn isDifferent ? (newValue as Shape) : knownGoodValue\n\t\t\t}\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 any 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>\n/** @public */\nexport type 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\tprivate readonly useNumberKeys: boolean\n\t) {\n\t\tsuper(\n\t\t\t(input) => {\n\t\t\t\tthis.expectObject(input)\n\n\t\t\t\tconst { matchingSchema, variant } = this.getMatchingSchemaAndVariant(input)\n\t\t\t\tif (matchingSchema === undefined) {\n\t\t\t\t\treturn this.unknownValueValidation(input, variant)\n\t\t\t\t}\n\n\t\t\t\treturn prefixError(`(${key} = ${variant})`, () => matchingSchema.validate(input))\n\t\t\t},\n\t\t\t(prevValue, newValue) => {\n\t\t\t\tthis.expectObject(newValue)\n\t\t\t\tthis.expectObject(prevValue)\n\n\t\t\t\tconst { matchingSchema, variant } = this.getMatchingSchemaAndVariant(newValue)\n\t\t\t\tif (matchingSchema === undefined) {\n\t\t\t\t\treturn this.unknownValueValidation(newValue, variant)\n\t\t\t\t}\n\n\t\t\t\tif (getOwnProperty(prevValue, key) !== getOwnProperty(newValue, key)) {\n\t\t\t\t\t// the type has changed so bail out and do a regular validation\n\t\t\t\t\treturn prefixError(`(${key} = ${variant})`, () => matchingSchema.validate(newValue))\n\t\t\t\t}\n\n\t\t\t\treturn prefixError(`(${key} = ${variant})`, () => {\n\t\t\t\t\tif (matchingSchema.validateUsingKnownGoodVersion) {\n\t\t\t\t\t\treturn matchingSchema.validateUsingKnownGoodVersion(prevValue, newValue)\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn matchingSchema.validate(newValue)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t)\n\t}\n\n\tprivate expectObject(value: unknown): asserts value is object {\n\t\tif (typeof value !== 'object' || value === null) {\n\t\t\tthrow new ValidationError(`Expected an object, got ${typeToString(value)}`, [])\n\t\t}\n\t}\n\n\tprivate getMatchingSchemaAndVariant(object: object): {\n\t\tmatchingSchema: Validatable<any> | undefined\n\t\tvariant: string\n\t} {\n\t\tconst variant = getOwnProperty(object, this.key)! as string & keyof Config\n\t\tif (!this.useNumberKeys && typeof variant !== 'string') {\n\t\t\tthrow new ValidationError(\n\t\t\t\t`Expected a string for key \"${this.key}\", got ${typeToString(variant)}`\n\t\t\t)\n\t\t} else if (this.useNumberKeys && !Number.isFinite(Number(variant))) {\n\t\t\tthrow new ValidationError(`Expected a number for key \"${this.key}\", got \"${variant as any}\"`)\n\t\t}\n\n\t\tconst matchingSchema = hasOwnProperty(this.config, variant) ? this.config[variant] : undefined\n\t\treturn { matchingSchema, variant }\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, this.useNumberKeys)\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(\n\t\t\t(object) => {\n\t\t\t\tif (typeof object !== 'object' || object === null) {\n\t\t\t\t\tthrow new ValidationError(`Expected object, got ${typeToString(object)}`)\n\t\t\t\t}\n\n\t\t\t\tfor (const [key, value] of Object.entries(object)) {\n\t\t\t\t\tprefixError(key, () => {\n\t\t\t\t\t\tkeyValidator.validate(key)\n\t\t\t\t\t\tvalueValidator.validate(value)\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\treturn object as Record<Key, Value>\n\t\t\t},\n\t\t\t(knownGoodValue, newValue) => {\n\t\t\t\tif (typeof newValue !== 'object' || newValue === null) {\n\t\t\t\t\tthrow new ValidationError(`Expected object, got ${typeToString(newValue)}`)\n\t\t\t\t}\n\n\t\t\t\tlet isDifferent = false\n\n\t\t\t\tfor (const [key, value] of Object.entries(newValue)) {\n\t\t\t\t\tif (!hasOwnProperty(knownGoodValue, key)) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t\tprefixError(key, () => {\n\t\t\t\t\t\t\tkeyValidator.validate(key)\n\t\t\t\t\t\t\tvalueValidator.validate(value)\n\t\t\t\t\t\t})\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tconst prev = getOwnProperty(knownGoodValue, key)\n\t\t\t\t\tconst next = value\n\t\t\t\t\t// sneaky quick check here to avoid the prefix + validator overhead\n\t\t\t\t\tif (Object.is(prev, next)) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tconst checked = prefixError(key, () => {\n\t\t\t\t\t\tif (valueValidator.validateUsingKnownGoodVersion) {\n\t\t\t\t\t\t\treturn valueValidator.validateUsingKnownGoodVersion(prev as any, next)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn valueValidator.validate(next)\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\tif (!Object.is(checked, prev)) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor (const key of Object.keys(knownGoodValue)) {\n\t\t\t\t\tif (!hasOwnProperty(newValue, key)) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn isDifferent ? (newValue as Record<Key, Value>) : knownGoodValue\n\t\t\t}\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<MakeUndefinedOptional<Shape>> {\n\treturn new ObjectValidator(config) as any\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\t(Object.getPrototypeOf(value) === Object.prototype ||\n\t\t\tObject.getPrototypeOf(value) === null ||\n\t\t\tObject.getPrototypeOf(value) === STRUCTURED_CLONE_OBJECT_PROTOTYPE)\n\t)\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 (isPlainObject(value)) {\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: Validator<JsonValue> = new Validator<JsonValue>(\n\t(value): JsonValue => {\n\t\tif (isValidJson(value)) {\n\t\t\treturn value as JsonValue\n\t\t}\n\n\t\tthrow new ValidationError(`Expected json serializable value, got ${typeof value}`)\n\t},\n\t(knownGoodValue, newValue) => {\n\t\tif (Array.isArray(knownGoodValue) && Array.isArray(newValue)) {\n\t\t\tlet isDifferent = knownGoodValue.length !== newValue.length\n\t\t\tfor (let i = 0; i < newValue.length; i++) {\n\t\t\t\tif (i >= knownGoodValue.length) {\n\t\t\t\t\tisDifferent = true\n\t\t\t\t\tjsonValue.validate(newValue[i])\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst prev = knownGoodValue[i]\n\t\t\t\tconst next = newValue[i]\n\t\t\t\tif (Object.is(prev, next)) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst checked = jsonValue.validateUsingKnownGoodVersion!(prev, next)\n\t\t\t\tif (!Object.is(checked, prev)) {\n\t\t\t\t\tisDifferent = true\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn isDifferent ? (newValue as JsonValue) : knownGoodValue\n\t\t} else if (isPlainObject(knownGoodValue) && isPlainObject(newValue)) {\n\t\t\tlet isDifferent = false\n\t\t\tfor (const key of Object.keys(newValue)) {\n\t\t\t\tif (!hasOwnProperty(knownGoodValue, key)) {\n\t\t\t\t\tisDifferent = true\n\t\t\t\t\tjsonValue.validate(newValue[key])\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst prev = knownGoodValue[key]\n\t\t\t\tconst next = newValue[key]\n\t\t\t\tif (Object.is(prev, next)) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst checked = jsonValue.validateUsingKnownGoodVersion!(prev!, next)\n\t\t\t\tif (!Object.is(checked, prev)) {\n\t\t\t\t\tisDifferent = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const key of Object.keys(knownGoodValue)) {\n\t\t\t\tif (!hasOwnProperty(newValue, key)) {\n\t\t\t\t\tisDifferent = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn isDifferent ? (newValue as JsonValue) : knownGoodValue\n\t\t} else {\n\t\t\treturn jsonValue.validate(newValue)\n\t\t}\n\t}\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.literal('cat'), meow: T.boolean })\n * const dogValidator = T.object({ kind: T.literal('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(\n\t\tkey,\n\t\tconfig,\n\t\t(_unknownValue, unknownVariant) => {\n\t\t\tthrow new ValidationError(\n\t\t\t\t`Expected one of ${Object.keys(config)\n\t\t\t\t\t.map((key) => JSON.stringify(key))\n\t\t\t\t\t.join(' or ')}, got ${JSON.stringify(unknownVariant)}`,\n\t\t\t\t[key]\n\t\t\t)\n\t\t},\n\t\tfalse\n\t)\n}\n\n/**\n * @internal\n */\nexport function numberUnion<Key extends string, Config extends UnionValidatorConfig<Key, Config>>(\n\tkey: Key,\n\tconfig: Config\n): UnionValidator<Key, Config> {\n\treturn new UnionValidator(\n\t\tkey,\n\t\tconfig,\n\t\t(unknownValue, unknownVariant) => {\n\t\t\tthrow new ValidationError(\n\t\t\t\t`Expected one of ${Object.keys(config)\n\t\t\t\t\t.map((key) => JSON.stringify(key))\n\t\t\t\t\t.join(' or ')}, got ${JSON.stringify(unknownVariant)}`,\n\t\t\t\t[key]\n\t\t\t)\n\t\t},\n\t\ttrue\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(\n\t\t(value) => {\n\t\t\treturn prefixError(name, () => validator.validate(value))\n\t\t},\n\t\t(prevValue, newValue) => {\n\t\t\treturn prefixError(name, () => {\n\t\t\t\tif (validator.validateUsingKnownGoodVersion) {\n\t\t\t\t\treturn validator.validateUsingKnownGoodVersion(prevValue, newValue)\n\t\t\t\t} else {\n\t\t\t\t\treturn validator.validate(newValue)\n\t\t\t\t}\n\t\t\t})\n\t\t}\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(\n\t\t(value) => {\n\t\t\tif (value === undefined) return undefined\n\t\t\treturn validator.validate(value)\n\t\t},\n\t\t(knownGoodValue, newValue) => {\n\t\t\tif (knownGoodValue === undefined && newValue === undefined) return undefined\n\t\t\tif (newValue === undefined) return undefined\n\t\t\tif (validator.validateUsingKnownGoodVersion && knownGoodValue !== undefined) {\n\t\t\t\treturn validator.validateUsingKnownGoodVersion(knownGoodValue as T, newValue)\n\t\t\t}\n\t\t\treturn validator.validate(newValue)\n\t\t}\n\t)\n}\n\n/** @public */\nexport function nullable<T>(validator: Validatable<T>): Validator<T | null> {\n\treturn new Validator(\n\t\t(value) => {\n\t\t\tif (value === null) return null\n\t\t\treturn validator.validate(value)\n\t\t},\n\t\t(knownGoodValue, newValue) => {\n\t\t\tif (newValue === null) return null\n\t\t\tif (validator.validateUsingKnownGoodVersion && knownGoodValue !== null) {\n\t\t\t\treturn validator.validateUsingKnownGoodVersion(knownGoodValue as T, newValue)\n\t\t\t}\n\t\t\treturn validator.validate(newValue)\n\t\t}\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\nfunction parseUrl(str: string) {\n\ttry {\n\t\treturn new URL(str)\n\t} catch {\n\t\tif (str.startsWith('/') || str.startsWith('./')) {\n\t\t\ttry {\n\t\t\t\treturn new URL(str, 'http://example.com')\n\t\t\t} catch {\n\t\t\t\tthrow new ValidationError(`Expected a valid url, got ${JSON.stringify(str)}`)\n\t\t\t}\n\t\t}\n\t\tthrow new ValidationError(`Expected a valid url, got ${JSON.stringify(str)}`)\n\t}\n}\n\nconst validLinkProtocols = new Set(['http:', 'https:', 'mailto:'])\n\n/**\n * Validates that a value is a url safe to use as a link.\n *\n * @public\n */\nexport const linkUrl = string.check((value) => {\n\tif (value === '') return\n\tconst url = parseUrl(value)\n\n\tif (!validLinkProtocols.has(url.protocol.toLowerCase())) {\n\t\tthrow new ValidationError(\n\t\t\t`Expected a valid url, got ${JSON.stringify(value)} (invalid protocol)`\n\t\t)\n\t}\n})\n\n// N.B. asset: is a reference to the local indexedDB object store.\nconst validSrcProtocols = new Set(['http:', 'https:', 'data:', 'asset:'])\n\n/**\n * Validates that a valid is a url safe to load as an asset.\n *\n * @public\n */\nexport const srcUrl = string.check((value) => {\n\tif (value === '') return\n\tconst url = parseUrl(value)\n\n\tif (!validSrcProtocols.has(url.protocol.toLowerCase())) {\n\t\tthrow new ValidationError(\n\t\t\t`Expected a valid url, got ${JSON.stringify(value)} (invalid protocol)`\n\t\t)\n\t}\n})\n\n/**\n * Validates an http(s) url\n *\n * @public\n */\nexport const httpUrl = string.check((value) => {\n\tif (value === '') return\n\tconst url = parseUrl(value)\n\n\tif (!url.protocol.toLowerCase().match(/^https?:$/)) {\n\t\tthrow new ValidationError(\n\t\t\t`Expected a valid url, got ${JSON.stringify(value)} (invalid protocol)`\n\t\t)\n\t}\n})\n\n/**\n * Validates that a value is an IndexKey.\n * @public\n */\nexport const indexKey = string.refine<IndexKey>((key) => {\n\ttry {\n\t\tvalidateIndexKey(key)\n\t\treturn key\n\t} catch {\n\t\tthrow new ValidationError(`Expected an index key, got ${JSON.stringify(key)}`)\n\t}\n})\n\n/**\n * Validate a value against one of two types.\n *\n * @public\n */\nexport function or<T1, T2>(v1: Validatable<T1>, v2: Validatable<T2>): Validator<T1 | T2> {\n\treturn new Validator((value) => {\n\t\ttry {\n\t\t\treturn v1.validate(value)\n\t\t} catch {\n\t\t\treturn v2.validate(value)\n\t\t}\n\t})\n}\n"],
5
5
  "mappings": "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",
6
6
  "names": ["object", "number", "key", "value"]
7
7
  }
@@ -9,7 +9,7 @@ import {
9
9
  } from "./lib/validation.mjs";
10
10
  registerTldrawLibraryVersion(
11
11
  "@tldraw/validate",
12
- "3.9.0",
12
+ "3.10.0-canary.3176429f9d1b",
13
13
  "esm"
14
14
  );
15
15
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/validation.ts"],
4
- "sourcesContent": ["import {\n\tIndexKey,\n\tJsonValue,\n\tMakeUndefinedOptional,\n\tSTRUCTURED_CLONE_OBJECT_PROTOTYPE,\n\texhaustiveSwitchError,\n\tgetOwnProperty,\n\thasOwnProperty,\n\tvalidateIndexKey,\n} from '@tldraw/utils'\n\n/** @public */\nexport type ValidatorFn<T> = (value: unknown) => T\n/** @public */\nexport type ValidatorUsingKnownGoodVersionFn<In, Out = In> = (\n\tknownGoodValue: In,\n\tvalue: unknown\n) => Out\n\n/** @public */\nexport interface Validatable<T> {\n\tvalidate(value: unknown): T\n\t/**\n\t * This is a performance optimizing version of validate that can use a previous\n\t * version of the value to avoid revalidating every part of the new value if\n\t * any part of it has not changed since the last validation.\n\t *\n\t * If the value has not changed but is not referentially equal, the function\n\t * should return the previous value.\n\t * @returns\n\t */\n\tvalidateUsingKnownGoodVersion?(knownGoodValue: T, newValue: unknown): T\n}\n\nfunction formatPath(path: ReadonlyArray<number | string>): string | null {\n\tif (!path.length) {\n\t\treturn null\n\t}\n\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\n\t// N.B. We don't want id's in the path because they make grouping in Sentry tough.\n\tformattedPath = formattedPath.replace(/id = [^,]+, /, '').replace(/id = [^)]+/, '')\n\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<any>> = V extends Validatable<infer T> ? T : never\n\n/** @public */\nexport class Validator<T> implements Validatable<T> {\n\tconstructor(\n\t\treadonly validationFn: ValidatorFn<T>,\n\t\treadonly validateUsingKnownGoodVersionFn?: ValidatorUsingKnownGoodVersionFn<T>\n\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\tvalidateUsingKnownGoodVersion(knownGoodValue: T, newValue: unknown): T {\n\t\tif (Object.is(knownGoodValue, newValue)) {\n\t\t\treturn knownGoodValue as T\n\t\t}\n\n\t\tif (this.validateUsingKnownGoodVersionFn) {\n\t\t\treturn this.validateUsingKnownGoodVersionFn(knownGoodValue, newValue)\n\t\t}\n\n\t\treturn this.validate(newValue)\n\t}\n\n\t/** Checks that the passed value is of the correct type. */\n\tisValid(value: unknown): value is T {\n\t\ttry {\n\t\t\tthis.validate(value)\n\t\t\treturn true\n\t\t} catch {\n\t\t\treturn false\n\t\t}\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(\n\t\t\t(value) => {\n\t\t\t\treturn otherValidationFn(this.validate(value))\n\t\t\t},\n\n\t\t\t(knownGoodValue, newValue) => {\n\t\t\t\tconst validated = this.validateUsingKnownGoodVersion(knownGoodValue as any, newValue)\n\t\t\t\tif (Object.is(knownGoodValue, validated)) {\n\t\t\t\t\treturn knownGoodValue\n\t\t\t\t}\n\t\t\t\treturn otherValidationFn(validated)\n\t\t\t}\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(\n\t\t\t(value) => {\n\t\t\t\tconst arr = array.validate(value)\n\t\t\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\t\t\tprefixError(i, () => itemValidator.validate(arr[i]))\n\t\t\t\t}\n\t\t\t\treturn arr as T[]\n\t\t\t},\n\t\t\t(knownGoodValue, newValue) => {\n\t\t\t\tif (!itemValidator.validateUsingKnownGoodVersion) return this.validate(newValue)\n\t\t\t\tconst arr = array.validate(newValue)\n\t\t\t\tlet isDifferent = knownGoodValue.length !== arr.length\n\t\t\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\t\t\tconst item = arr[i]\n\t\t\t\t\tif (i >= knownGoodValue.length) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t\tprefixError(i, () => itemValidator.validate(item))\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\t// sneaky quick check here to avoid the prefix + validator overhead\n\t\t\t\t\tif (Object.is(knownGoodValue[i], item)) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tconst checkedItem = prefixError(i, () =>\n\t\t\t\t\t\titemValidator.validateUsingKnownGoodVersion!(knownGoodValue[i], item)\n\t\t\t\t\t)\n\t\t\t\t\tif (!Object.is(checkedItem, knownGoodValue[i])) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn isDifferent ? (newValue as T[]) : knownGoodValue\n\t\t\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(\n\t\t\t(object) => {\n\t\t\t\tif (typeof object !== 'object' || object === null) {\n\t\t\t\t\tthrow new ValidationError(`Expected object, got ${typeToString(object)}`)\n\t\t\t\t}\n\n\t\t\t\tfor (const [key, validator] of Object.entries(config)) {\n\t\t\t\t\tprefixError(key, () => {\n\t\t\t\t\t\t;(validator as Validatable<unknown>).validate(getOwnProperty(object, key))\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tif (!shouldAllowUnknownProperties) {\n\t\t\t\t\tfor (const key of Object.keys(object)) {\n\t\t\t\t\t\tif (!hasOwnProperty(config, key)) {\n\t\t\t\t\t\t\tthrow new ValidationError(`Unexpected property`, [key])\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn object as Shape\n\t\t\t},\n\t\t\t(knownGoodValue, newValue) => {\n\t\t\t\tif (typeof newValue !== 'object' || newValue === null) {\n\t\t\t\t\tthrow new ValidationError(`Expected object, got ${typeToString(newValue)}`)\n\t\t\t\t}\n\n\t\t\t\tlet isDifferent = false\n\n\t\t\t\tfor (const [key, validator] of Object.entries(config)) {\n\t\t\t\t\tconst prev = getOwnProperty(knownGoodValue, key)\n\t\t\t\t\tconst next = getOwnProperty(newValue, key)\n\t\t\t\t\t// sneaky quick check here to avoid the prefix + validator overhead\n\t\t\t\t\tif (Object.is(prev, next)) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tconst checked = prefixError(key, () => {\n\t\t\t\t\t\tconst validatable = validator as Validatable<unknown>\n\t\t\t\t\t\tif (validatable.validateUsingKnownGoodVersion) {\n\t\t\t\t\t\t\treturn validatable.validateUsingKnownGoodVersion(prev, next)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn validatable.validate(next)\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\tif (!Object.is(checked, prev)) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!shouldAllowUnknownProperties) {\n\t\t\t\t\tfor (const key of Object.keys(newValue)) {\n\t\t\t\t\t\tif (!hasOwnProperty(config, key)) {\n\t\t\t\t\t\t\tthrow new ValidationError(`Unexpected property`, [key])\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor (const key of Object.keys(knownGoodValue)) {\n\t\t\t\t\tif (!hasOwnProperty(newValue, key)) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn isDifferent ? (newValue as Shape) : knownGoodValue\n\t\t\t}\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 any 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>\n/** @public */\nexport type 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\tprivate readonly useNumberKeys: boolean\n\t) {\n\t\tsuper(\n\t\t\t(input) => {\n\t\t\t\tthis.expectObject(input)\n\n\t\t\t\tconst { matchingSchema, variant } = this.getMatchingSchemaAndVariant(input)\n\t\t\t\tif (matchingSchema === undefined) {\n\t\t\t\t\treturn this.unknownValueValidation(input, variant)\n\t\t\t\t}\n\n\t\t\t\treturn prefixError(`(${key} = ${variant})`, () => matchingSchema.validate(input))\n\t\t\t},\n\t\t\t(prevValue, newValue) => {\n\t\t\t\tthis.expectObject(newValue)\n\t\t\t\tthis.expectObject(prevValue)\n\n\t\t\t\tconst { matchingSchema, variant } = this.getMatchingSchemaAndVariant(newValue)\n\t\t\t\tif (matchingSchema === undefined) {\n\t\t\t\t\treturn this.unknownValueValidation(newValue, variant)\n\t\t\t\t}\n\n\t\t\t\tif (getOwnProperty(prevValue, key) !== getOwnProperty(newValue, key)) {\n\t\t\t\t\t// the type has changed so bail out and do a regular validation\n\t\t\t\t\treturn prefixError(`(${key} = ${variant})`, () => matchingSchema.validate(newValue))\n\t\t\t\t}\n\n\t\t\t\treturn prefixError(`(${key} = ${variant})`, () => {\n\t\t\t\t\tif (matchingSchema.validateUsingKnownGoodVersion) {\n\t\t\t\t\t\treturn matchingSchema.validateUsingKnownGoodVersion(prevValue, newValue)\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn matchingSchema.validate(newValue)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t)\n\t}\n\n\tprivate expectObject(value: unknown): asserts value is object {\n\t\tif (typeof value !== 'object' || value === null) {\n\t\t\tthrow new ValidationError(`Expected an object, got ${typeToString(value)}`, [])\n\t\t}\n\t}\n\n\tprivate getMatchingSchemaAndVariant(object: object): {\n\t\tmatchingSchema: Validatable<any> | undefined\n\t\tvariant: string\n\t} {\n\t\tconst variant = getOwnProperty(object, this.key) as string & keyof Config\n\t\tif (!this.useNumberKeys && typeof variant !== 'string') {\n\t\t\tthrow new ValidationError(\n\t\t\t\t`Expected a string for key \"${this.key}\", got ${typeToString(variant)}`\n\t\t\t)\n\t\t} else if (this.useNumberKeys && !Number.isFinite(Number(variant))) {\n\t\t\tthrow new ValidationError(`Expected a number for key \"${this.key}\", got \"${variant as any}\"`)\n\t\t}\n\n\t\tconst matchingSchema = hasOwnProperty(this.config, variant) ? this.config[variant] : undefined\n\t\treturn { matchingSchema, variant }\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, this.useNumberKeys)\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(\n\t\t\t(object) => {\n\t\t\t\tif (typeof object !== 'object' || object === null) {\n\t\t\t\t\tthrow new ValidationError(`Expected object, got ${typeToString(object)}`)\n\t\t\t\t}\n\n\t\t\t\tfor (const [key, value] of Object.entries(object)) {\n\t\t\t\t\tprefixError(key, () => {\n\t\t\t\t\t\tkeyValidator.validate(key)\n\t\t\t\t\t\tvalueValidator.validate(value)\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\treturn object as Record<Key, Value>\n\t\t\t},\n\t\t\t(knownGoodValue, newValue) => {\n\t\t\t\tif (typeof newValue !== 'object' || newValue === null) {\n\t\t\t\t\tthrow new ValidationError(`Expected object, got ${typeToString(newValue)}`)\n\t\t\t\t}\n\n\t\t\t\tlet isDifferent = false\n\n\t\t\t\tfor (const [key, value] of Object.entries(newValue)) {\n\t\t\t\t\tif (!hasOwnProperty(knownGoodValue, key)) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t\tprefixError(key, () => {\n\t\t\t\t\t\t\tkeyValidator.validate(key)\n\t\t\t\t\t\t\tvalueValidator.validate(value)\n\t\t\t\t\t\t})\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tconst prev = getOwnProperty(knownGoodValue, key)\n\t\t\t\t\tconst next = value\n\t\t\t\t\t// sneaky quick check here to avoid the prefix + validator overhead\n\t\t\t\t\tif (Object.is(prev, next)) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tconst checked = prefixError(key, () => {\n\t\t\t\t\t\tif (valueValidator.validateUsingKnownGoodVersion) {\n\t\t\t\t\t\t\treturn valueValidator.validateUsingKnownGoodVersion(prev as any, next)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn valueValidator.validate(next)\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\tif (!Object.is(checked, prev)) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor (const key of Object.keys(knownGoodValue)) {\n\t\t\t\t\tif (!hasOwnProperty(newValue, key)) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn isDifferent ? (newValue as Record<Key, Value>) : knownGoodValue\n\t\t\t}\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<MakeUndefinedOptional<Shape>> {\n\treturn new ObjectValidator(config) as any\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\t(Object.getPrototypeOf(value) === Object.prototype ||\n\t\t\tObject.getPrototypeOf(value) === null ||\n\t\t\tObject.getPrototypeOf(value) === STRUCTURED_CLONE_OBJECT_PROTOTYPE)\n\t)\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 (isPlainObject(value)) {\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: Validator<JsonValue> = new Validator<JsonValue>(\n\t(value): JsonValue => {\n\t\tif (isValidJson(value)) {\n\t\t\treturn value as JsonValue\n\t\t}\n\n\t\tthrow new ValidationError(`Expected json serializable value, got ${typeof value}`)\n\t},\n\t(knownGoodValue, newValue) => {\n\t\tif (Array.isArray(knownGoodValue) && Array.isArray(newValue)) {\n\t\t\tlet isDifferent = knownGoodValue.length !== newValue.length\n\t\t\tfor (let i = 0; i < newValue.length; i++) {\n\t\t\t\tif (i >= knownGoodValue.length) {\n\t\t\t\t\tisDifferent = true\n\t\t\t\t\tjsonValue.validate(newValue[i])\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst prev = knownGoodValue[i]\n\t\t\t\tconst next = newValue[i]\n\t\t\t\tif (Object.is(prev, next)) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst checked = jsonValue.validateUsingKnownGoodVersion!(prev, next)\n\t\t\t\tif (!Object.is(checked, prev)) {\n\t\t\t\t\tisDifferent = true\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn isDifferent ? (newValue as JsonValue) : knownGoodValue\n\t\t} else if (isPlainObject(knownGoodValue) && isPlainObject(newValue)) {\n\t\t\tlet isDifferent = false\n\t\t\tfor (const key of Object.keys(newValue)) {\n\t\t\t\tif (!hasOwnProperty(knownGoodValue, key)) {\n\t\t\t\t\tisDifferent = true\n\t\t\t\t\tjsonValue.validate(newValue[key])\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst prev = knownGoodValue[key]\n\t\t\t\tconst next = newValue[key]\n\t\t\t\tif (Object.is(prev, next)) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst checked = jsonValue.validateUsingKnownGoodVersion!(prev!, next)\n\t\t\t\tif (!Object.is(checked, prev)) {\n\t\t\t\t\tisDifferent = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const key of Object.keys(knownGoodValue)) {\n\t\t\t\tif (!hasOwnProperty(newValue, key)) {\n\t\t\t\t\tisDifferent = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn isDifferent ? (newValue as JsonValue) : knownGoodValue\n\t\t} else {\n\t\t\treturn jsonValue.validate(newValue)\n\t\t}\n\t}\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.literal('cat'), meow: T.boolean })\n * const dogValidator = T.object({ kind: T.literal('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(\n\t\tkey,\n\t\tconfig,\n\t\t(_unknownValue, unknownVariant) => {\n\t\t\tthrow new ValidationError(\n\t\t\t\t`Expected one of ${Object.keys(config)\n\t\t\t\t\t.map((key) => JSON.stringify(key))\n\t\t\t\t\t.join(' or ')}, got ${JSON.stringify(unknownVariant)}`,\n\t\t\t\t[key]\n\t\t\t)\n\t\t},\n\t\tfalse\n\t)\n}\n\n/**\n * @internal\n */\nexport function numberUnion<Key extends string, Config extends UnionValidatorConfig<Key, Config>>(\n\tkey: Key,\n\tconfig: Config\n): UnionValidator<Key, Config> {\n\treturn new UnionValidator(\n\t\tkey,\n\t\tconfig,\n\t\t(unknownValue, unknownVariant) => {\n\t\t\tthrow new ValidationError(\n\t\t\t\t`Expected one of ${Object.keys(config)\n\t\t\t\t\t.map((key) => JSON.stringify(key))\n\t\t\t\t\t.join(' or ')}, got ${JSON.stringify(unknownVariant)}`,\n\t\t\t\t[key]\n\t\t\t)\n\t\t},\n\t\ttrue\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(\n\t\t(value) => {\n\t\t\treturn prefixError(name, () => validator.validate(value))\n\t\t},\n\t\t(prevValue, newValue) => {\n\t\t\treturn prefixError(name, () => {\n\t\t\t\tif (validator.validateUsingKnownGoodVersion) {\n\t\t\t\t\treturn validator.validateUsingKnownGoodVersion(prevValue, newValue)\n\t\t\t\t} else {\n\t\t\t\t\treturn validator.validate(newValue)\n\t\t\t\t}\n\t\t\t})\n\t\t}\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(\n\t\t(value) => {\n\t\t\tif (value === undefined) return undefined\n\t\t\treturn validator.validate(value)\n\t\t},\n\t\t(knownGoodValue, newValue) => {\n\t\t\tif (knownGoodValue === undefined && newValue === undefined) return undefined\n\t\t\tif (newValue === undefined) return undefined\n\t\t\tif (validator.validateUsingKnownGoodVersion && knownGoodValue !== undefined) {\n\t\t\t\treturn validator.validateUsingKnownGoodVersion(knownGoodValue as T, newValue)\n\t\t\t}\n\t\t\treturn validator.validate(newValue)\n\t\t}\n\t)\n}\n\n/** @public */\nexport function nullable<T>(validator: Validatable<T>): Validator<T | null> {\n\treturn new Validator(\n\t\t(value) => {\n\t\t\tif (value === null) return null\n\t\t\treturn validator.validate(value)\n\t\t},\n\t\t(knownGoodValue, newValue) => {\n\t\t\tif (newValue === null) return null\n\t\t\tif (validator.validateUsingKnownGoodVersion && knownGoodValue !== null) {\n\t\t\t\treturn validator.validateUsingKnownGoodVersion(knownGoodValue as T, newValue)\n\t\t\t}\n\t\t\treturn validator.validate(newValue)\n\t\t}\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\nfunction parseUrl(str: string) {\n\ttry {\n\t\treturn new URL(str)\n\t} catch {\n\t\tif (str.startsWith('/') || str.startsWith('./')) {\n\t\t\ttry {\n\t\t\t\treturn new URL(str, 'http://example.com')\n\t\t\t} catch {\n\t\t\t\tthrow new ValidationError(`Expected a valid url, got ${JSON.stringify(str)}`)\n\t\t\t}\n\t\t}\n\t\tthrow new ValidationError(`Expected a valid url, got ${JSON.stringify(str)}`)\n\t}\n}\n\nconst validLinkProtocols = new Set(['http:', 'https:', 'mailto:'])\n\n/**\n * Validates that a value is a url safe to use as a link.\n *\n * @public\n */\nexport const linkUrl = string.check((value) => {\n\tif (value === '') return\n\tconst url = parseUrl(value)\n\n\tif (!validLinkProtocols.has(url.protocol.toLowerCase())) {\n\t\tthrow new ValidationError(\n\t\t\t`Expected a valid url, got ${JSON.stringify(value)} (invalid protocol)`\n\t\t)\n\t}\n})\n\n// N.B. asset: is a reference to the local indexedDB object store.\nconst validSrcProtocols = new Set(['http:', 'https:', 'data:', 'asset:'])\n\n/**\n * Validates that a valid is a url safe to load as an asset.\n *\n * @public\n */\nexport const srcUrl = string.check((value) => {\n\tif (value === '') return\n\tconst url = parseUrl(value)\n\n\tif (!validSrcProtocols.has(url.protocol.toLowerCase())) {\n\t\tthrow new ValidationError(\n\t\t\t`Expected a valid url, got ${JSON.stringify(value)} (invalid protocol)`\n\t\t)\n\t}\n})\n\n/**\n * Validates an http(s) url\n *\n * @public\n */\nexport const httpUrl = string.check((value) => {\n\tif (value === '') return\n\tconst url = parseUrl(value)\n\n\tif (!url.protocol.toLowerCase().match(/^https?:$/)) {\n\t\tthrow new ValidationError(\n\t\t\t`Expected a valid url, got ${JSON.stringify(value)} (invalid protocol)`\n\t\t)\n\t}\n})\n\n/**\n * Validates that a value is an IndexKey.\n * @public\n */\nexport const indexKey = string.refine<IndexKey>((key) => {\n\ttry {\n\t\tvalidateIndexKey(key)\n\t\treturn key\n\t} catch {\n\t\tthrow new ValidationError(`Expected an index key, got ${JSON.stringify(key)}`)\n\t}\n})\n\n/**\n * Validate a value against one of two types.\n *\n * @public\n */\nexport function or<T1, T2>(v1: Validatable<T1>, v2: Validatable<T2>): Validator<T1 | T2> {\n\treturn new Validator((value) => {\n\t\ttry {\n\t\t\treturn v1.validate(value)\n\t\t} catch {\n\t\t\treturn v2.validate(value)\n\t\t}\n\t})\n}\n"],
4
+ "sourcesContent": ["import {\n\tIndexKey,\n\tJsonValue,\n\tMakeUndefinedOptional,\n\tSTRUCTURED_CLONE_OBJECT_PROTOTYPE,\n\texhaustiveSwitchError,\n\tgetOwnProperty,\n\thasOwnProperty,\n\tvalidateIndexKey,\n} from '@tldraw/utils'\n\n/** @public */\nexport type ValidatorFn<T> = (value: unknown) => T\n/** @public */\nexport type ValidatorUsingKnownGoodVersionFn<In, Out = In> = (\n\tknownGoodValue: In,\n\tvalue: unknown\n) => Out\n\n/** @public */\nexport interface Validatable<T> {\n\tvalidate(value: unknown): T\n\t/**\n\t * This is a performance optimizing version of validate that can use a previous\n\t * version of the value to avoid revalidating every part of the new value if\n\t * any part of it has not changed since the last validation.\n\t *\n\t * If the value has not changed but is not referentially equal, the function\n\t * should return the previous value.\n\t * @returns\n\t */\n\tvalidateUsingKnownGoodVersion?(knownGoodValue: T, newValue: unknown): T\n}\n\nfunction formatPath(path: ReadonlyArray<number | string>): string | null {\n\tif (!path.length) {\n\t\treturn null\n\t}\n\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\n\t// N.B. We don't want id's in the path because they make grouping in Sentry tough.\n\tformattedPath = formattedPath.replace(/id = [^,]+, /, '').replace(/id = [^)]+/, '')\n\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<any>> = V extends Validatable<infer T> ? T : never\n\n/** @public */\nexport class Validator<T> implements Validatable<T> {\n\tconstructor(\n\t\treadonly validationFn: ValidatorFn<T>,\n\t\treadonly validateUsingKnownGoodVersionFn?: ValidatorUsingKnownGoodVersionFn<T>\n\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\tvalidateUsingKnownGoodVersion(knownGoodValue: T, newValue: unknown): T {\n\t\tif (Object.is(knownGoodValue, newValue)) {\n\t\t\treturn knownGoodValue as T\n\t\t}\n\n\t\tif (this.validateUsingKnownGoodVersionFn) {\n\t\t\treturn this.validateUsingKnownGoodVersionFn(knownGoodValue, newValue)\n\t\t}\n\n\t\treturn this.validate(newValue)\n\t}\n\n\t/** Checks that the passed value is of the correct type. */\n\tisValid(value: unknown): value is T {\n\t\ttry {\n\t\t\tthis.validate(value)\n\t\t\treturn true\n\t\t} catch {\n\t\t\treturn false\n\t\t}\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(\n\t\t\t(value) => {\n\t\t\t\treturn otherValidationFn(this.validate(value))\n\t\t\t},\n\n\t\t\t(knownGoodValue, newValue) => {\n\t\t\t\tconst validated = this.validateUsingKnownGoodVersion(knownGoodValue as any, newValue)\n\t\t\t\tif (Object.is(knownGoodValue, validated)) {\n\t\t\t\t\treturn knownGoodValue\n\t\t\t\t}\n\t\t\t\treturn otherValidationFn(validated)\n\t\t\t}\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(\n\t\t\t(value) => {\n\t\t\t\tconst arr = array.validate(value)\n\t\t\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\t\t\tprefixError(i, () => itemValidator.validate(arr[i]))\n\t\t\t\t}\n\t\t\t\treturn arr as T[]\n\t\t\t},\n\t\t\t(knownGoodValue, newValue) => {\n\t\t\t\tif (!itemValidator.validateUsingKnownGoodVersion) return this.validate(newValue)\n\t\t\t\tconst arr = array.validate(newValue)\n\t\t\t\tlet isDifferent = knownGoodValue.length !== arr.length\n\t\t\t\tfor (let i = 0; i < arr.length; i++) {\n\t\t\t\t\tconst item = arr[i]\n\t\t\t\t\tif (i >= knownGoodValue.length) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t\tprefixError(i, () => itemValidator.validate(item))\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\t// sneaky quick check here to avoid the prefix + validator overhead\n\t\t\t\t\tif (Object.is(knownGoodValue[i], item)) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tconst checkedItem = prefixError(i, () =>\n\t\t\t\t\t\titemValidator.validateUsingKnownGoodVersion!(knownGoodValue[i], item)\n\t\t\t\t\t)\n\t\t\t\t\tif (!Object.is(checkedItem, knownGoodValue[i])) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn isDifferent ? (newValue as T[]) : knownGoodValue\n\t\t\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(\n\t\t\t(object) => {\n\t\t\t\tif (typeof object !== 'object' || object === null) {\n\t\t\t\t\tthrow new ValidationError(`Expected object, got ${typeToString(object)}`)\n\t\t\t\t}\n\n\t\t\t\tfor (const [key, validator] of Object.entries(config)) {\n\t\t\t\t\tprefixError(key, () => {\n\t\t\t\t\t\t;(validator as Validatable<unknown>).validate(getOwnProperty(object, key))\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tif (!shouldAllowUnknownProperties) {\n\t\t\t\t\tfor (const key of Object.keys(object)) {\n\t\t\t\t\t\tif (!hasOwnProperty(config, key)) {\n\t\t\t\t\t\t\tthrow new ValidationError(`Unexpected property`, [key])\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn object as Shape\n\t\t\t},\n\t\t\t(knownGoodValue, newValue) => {\n\t\t\t\tif (typeof newValue !== 'object' || newValue === null) {\n\t\t\t\t\tthrow new ValidationError(`Expected object, got ${typeToString(newValue)}`)\n\t\t\t\t}\n\n\t\t\t\tlet isDifferent = false\n\n\t\t\t\tfor (const [key, validator] of Object.entries(config)) {\n\t\t\t\t\tconst prev = getOwnProperty(knownGoodValue, key)\n\t\t\t\t\tconst next = getOwnProperty(newValue, key)\n\t\t\t\t\t// sneaky quick check here to avoid the prefix + validator overhead\n\t\t\t\t\tif (Object.is(prev, next)) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tconst checked = prefixError(key, () => {\n\t\t\t\t\t\tconst validatable = validator as Validatable<unknown>\n\t\t\t\t\t\tif (validatable.validateUsingKnownGoodVersion) {\n\t\t\t\t\t\t\treturn validatable.validateUsingKnownGoodVersion(prev, next)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn validatable.validate(next)\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\tif (!Object.is(checked, prev)) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!shouldAllowUnknownProperties) {\n\t\t\t\t\tfor (const key of Object.keys(newValue)) {\n\t\t\t\t\t\tif (!hasOwnProperty(config, key)) {\n\t\t\t\t\t\t\tthrow new ValidationError(`Unexpected property`, [key])\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor (const key of Object.keys(knownGoodValue)) {\n\t\t\t\t\tif (!hasOwnProperty(newValue, key)) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn isDifferent ? (newValue as Shape) : knownGoodValue\n\t\t\t}\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 any 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>\n/** @public */\nexport type 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\tprivate readonly useNumberKeys: boolean\n\t) {\n\t\tsuper(\n\t\t\t(input) => {\n\t\t\t\tthis.expectObject(input)\n\n\t\t\t\tconst { matchingSchema, variant } = this.getMatchingSchemaAndVariant(input)\n\t\t\t\tif (matchingSchema === undefined) {\n\t\t\t\t\treturn this.unknownValueValidation(input, variant)\n\t\t\t\t}\n\n\t\t\t\treturn prefixError(`(${key} = ${variant})`, () => matchingSchema.validate(input))\n\t\t\t},\n\t\t\t(prevValue, newValue) => {\n\t\t\t\tthis.expectObject(newValue)\n\t\t\t\tthis.expectObject(prevValue)\n\n\t\t\t\tconst { matchingSchema, variant } = this.getMatchingSchemaAndVariant(newValue)\n\t\t\t\tif (matchingSchema === undefined) {\n\t\t\t\t\treturn this.unknownValueValidation(newValue, variant)\n\t\t\t\t}\n\n\t\t\t\tif (getOwnProperty(prevValue, key) !== getOwnProperty(newValue, key)) {\n\t\t\t\t\t// the type has changed so bail out and do a regular validation\n\t\t\t\t\treturn prefixError(`(${key} = ${variant})`, () => matchingSchema.validate(newValue))\n\t\t\t\t}\n\n\t\t\t\treturn prefixError(`(${key} = ${variant})`, () => {\n\t\t\t\t\tif (matchingSchema.validateUsingKnownGoodVersion) {\n\t\t\t\t\t\treturn matchingSchema.validateUsingKnownGoodVersion(prevValue, newValue)\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn matchingSchema.validate(newValue)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t)\n\t}\n\n\tprivate expectObject(value: unknown): asserts value is object {\n\t\tif (typeof value !== 'object' || value === null) {\n\t\t\tthrow new ValidationError(`Expected an object, got ${typeToString(value)}`, [])\n\t\t}\n\t}\n\n\tprivate getMatchingSchemaAndVariant(object: object): {\n\t\tmatchingSchema: Validatable<any> | undefined\n\t\tvariant: string\n\t} {\n\t\tconst variant = getOwnProperty(object, this.key)! as string & keyof Config\n\t\tif (!this.useNumberKeys && typeof variant !== 'string') {\n\t\t\tthrow new ValidationError(\n\t\t\t\t`Expected a string for key \"${this.key}\", got ${typeToString(variant)}`\n\t\t\t)\n\t\t} else if (this.useNumberKeys && !Number.isFinite(Number(variant))) {\n\t\t\tthrow new ValidationError(`Expected a number for key \"${this.key}\", got \"${variant as any}\"`)\n\t\t}\n\n\t\tconst matchingSchema = hasOwnProperty(this.config, variant) ? this.config[variant] : undefined\n\t\treturn { matchingSchema, variant }\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, this.useNumberKeys)\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(\n\t\t\t(object) => {\n\t\t\t\tif (typeof object !== 'object' || object === null) {\n\t\t\t\t\tthrow new ValidationError(`Expected object, got ${typeToString(object)}`)\n\t\t\t\t}\n\n\t\t\t\tfor (const [key, value] of Object.entries(object)) {\n\t\t\t\t\tprefixError(key, () => {\n\t\t\t\t\t\tkeyValidator.validate(key)\n\t\t\t\t\t\tvalueValidator.validate(value)\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\treturn object as Record<Key, Value>\n\t\t\t},\n\t\t\t(knownGoodValue, newValue) => {\n\t\t\t\tif (typeof newValue !== 'object' || newValue === null) {\n\t\t\t\t\tthrow new ValidationError(`Expected object, got ${typeToString(newValue)}`)\n\t\t\t\t}\n\n\t\t\t\tlet isDifferent = false\n\n\t\t\t\tfor (const [key, value] of Object.entries(newValue)) {\n\t\t\t\t\tif (!hasOwnProperty(knownGoodValue, key)) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t\tprefixError(key, () => {\n\t\t\t\t\t\t\tkeyValidator.validate(key)\n\t\t\t\t\t\t\tvalueValidator.validate(value)\n\t\t\t\t\t\t})\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tconst prev = getOwnProperty(knownGoodValue, key)\n\t\t\t\t\tconst next = value\n\t\t\t\t\t// sneaky quick check here to avoid the prefix + validator overhead\n\t\t\t\t\tif (Object.is(prev, next)) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tconst checked = prefixError(key, () => {\n\t\t\t\t\t\tif (valueValidator.validateUsingKnownGoodVersion) {\n\t\t\t\t\t\t\treturn valueValidator.validateUsingKnownGoodVersion(prev as any, next)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn valueValidator.validate(next)\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\tif (!Object.is(checked, prev)) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor (const key of Object.keys(knownGoodValue)) {\n\t\t\t\t\tif (!hasOwnProperty(newValue, key)) {\n\t\t\t\t\t\tisDifferent = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn isDifferent ? (newValue as Record<Key, Value>) : knownGoodValue\n\t\t\t}\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<MakeUndefinedOptional<Shape>> {\n\treturn new ObjectValidator(config) as any\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\t(Object.getPrototypeOf(value) === Object.prototype ||\n\t\t\tObject.getPrototypeOf(value) === null ||\n\t\t\tObject.getPrototypeOf(value) === STRUCTURED_CLONE_OBJECT_PROTOTYPE)\n\t)\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 (isPlainObject(value)) {\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: Validator<JsonValue> = new Validator<JsonValue>(\n\t(value): JsonValue => {\n\t\tif (isValidJson(value)) {\n\t\t\treturn value as JsonValue\n\t\t}\n\n\t\tthrow new ValidationError(`Expected json serializable value, got ${typeof value}`)\n\t},\n\t(knownGoodValue, newValue) => {\n\t\tif (Array.isArray(knownGoodValue) && Array.isArray(newValue)) {\n\t\t\tlet isDifferent = knownGoodValue.length !== newValue.length\n\t\t\tfor (let i = 0; i < newValue.length; i++) {\n\t\t\t\tif (i >= knownGoodValue.length) {\n\t\t\t\t\tisDifferent = true\n\t\t\t\t\tjsonValue.validate(newValue[i])\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst prev = knownGoodValue[i]\n\t\t\t\tconst next = newValue[i]\n\t\t\t\tif (Object.is(prev, next)) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst checked = jsonValue.validateUsingKnownGoodVersion!(prev, next)\n\t\t\t\tif (!Object.is(checked, prev)) {\n\t\t\t\t\tisDifferent = true\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn isDifferent ? (newValue as JsonValue) : knownGoodValue\n\t\t} else if (isPlainObject(knownGoodValue) && isPlainObject(newValue)) {\n\t\t\tlet isDifferent = false\n\t\t\tfor (const key of Object.keys(newValue)) {\n\t\t\t\tif (!hasOwnProperty(knownGoodValue, key)) {\n\t\t\t\t\tisDifferent = true\n\t\t\t\t\tjsonValue.validate(newValue[key])\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst prev = knownGoodValue[key]\n\t\t\t\tconst next = newValue[key]\n\t\t\t\tif (Object.is(prev, next)) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst checked = jsonValue.validateUsingKnownGoodVersion!(prev!, next)\n\t\t\t\tif (!Object.is(checked, prev)) {\n\t\t\t\t\tisDifferent = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const key of Object.keys(knownGoodValue)) {\n\t\t\t\tif (!hasOwnProperty(newValue, key)) {\n\t\t\t\t\tisDifferent = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn isDifferent ? (newValue as JsonValue) : knownGoodValue\n\t\t} else {\n\t\t\treturn jsonValue.validate(newValue)\n\t\t}\n\t}\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.literal('cat'), meow: T.boolean })\n * const dogValidator = T.object({ kind: T.literal('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(\n\t\tkey,\n\t\tconfig,\n\t\t(_unknownValue, unknownVariant) => {\n\t\t\tthrow new ValidationError(\n\t\t\t\t`Expected one of ${Object.keys(config)\n\t\t\t\t\t.map((key) => JSON.stringify(key))\n\t\t\t\t\t.join(' or ')}, got ${JSON.stringify(unknownVariant)}`,\n\t\t\t\t[key]\n\t\t\t)\n\t\t},\n\t\tfalse\n\t)\n}\n\n/**\n * @internal\n */\nexport function numberUnion<Key extends string, Config extends UnionValidatorConfig<Key, Config>>(\n\tkey: Key,\n\tconfig: Config\n): UnionValidator<Key, Config> {\n\treturn new UnionValidator(\n\t\tkey,\n\t\tconfig,\n\t\t(unknownValue, unknownVariant) => {\n\t\t\tthrow new ValidationError(\n\t\t\t\t`Expected one of ${Object.keys(config)\n\t\t\t\t\t.map((key) => JSON.stringify(key))\n\t\t\t\t\t.join(' or ')}, got ${JSON.stringify(unknownVariant)}`,\n\t\t\t\t[key]\n\t\t\t)\n\t\t},\n\t\ttrue\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(\n\t\t(value) => {\n\t\t\treturn prefixError(name, () => validator.validate(value))\n\t\t},\n\t\t(prevValue, newValue) => {\n\t\t\treturn prefixError(name, () => {\n\t\t\t\tif (validator.validateUsingKnownGoodVersion) {\n\t\t\t\t\treturn validator.validateUsingKnownGoodVersion(prevValue, newValue)\n\t\t\t\t} else {\n\t\t\t\t\treturn validator.validate(newValue)\n\t\t\t\t}\n\t\t\t})\n\t\t}\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(\n\t\t(value) => {\n\t\t\tif (value === undefined) return undefined\n\t\t\treturn validator.validate(value)\n\t\t},\n\t\t(knownGoodValue, newValue) => {\n\t\t\tif (knownGoodValue === undefined && newValue === undefined) return undefined\n\t\t\tif (newValue === undefined) return undefined\n\t\t\tif (validator.validateUsingKnownGoodVersion && knownGoodValue !== undefined) {\n\t\t\t\treturn validator.validateUsingKnownGoodVersion(knownGoodValue as T, newValue)\n\t\t\t}\n\t\t\treturn validator.validate(newValue)\n\t\t}\n\t)\n}\n\n/** @public */\nexport function nullable<T>(validator: Validatable<T>): Validator<T | null> {\n\treturn new Validator(\n\t\t(value) => {\n\t\t\tif (value === null) return null\n\t\t\treturn validator.validate(value)\n\t\t},\n\t\t(knownGoodValue, newValue) => {\n\t\t\tif (newValue === null) return null\n\t\t\tif (validator.validateUsingKnownGoodVersion && knownGoodValue !== null) {\n\t\t\t\treturn validator.validateUsingKnownGoodVersion(knownGoodValue as T, newValue)\n\t\t\t}\n\t\t\treturn validator.validate(newValue)\n\t\t}\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\nfunction parseUrl(str: string) {\n\ttry {\n\t\treturn new URL(str)\n\t} catch {\n\t\tif (str.startsWith('/') || str.startsWith('./')) {\n\t\t\ttry {\n\t\t\t\treturn new URL(str, 'http://example.com')\n\t\t\t} catch {\n\t\t\t\tthrow new ValidationError(`Expected a valid url, got ${JSON.stringify(str)}`)\n\t\t\t}\n\t\t}\n\t\tthrow new ValidationError(`Expected a valid url, got ${JSON.stringify(str)}`)\n\t}\n}\n\nconst validLinkProtocols = new Set(['http:', 'https:', 'mailto:'])\n\n/**\n * Validates that a value is a url safe to use as a link.\n *\n * @public\n */\nexport const linkUrl = string.check((value) => {\n\tif (value === '') return\n\tconst url = parseUrl(value)\n\n\tif (!validLinkProtocols.has(url.protocol.toLowerCase())) {\n\t\tthrow new ValidationError(\n\t\t\t`Expected a valid url, got ${JSON.stringify(value)} (invalid protocol)`\n\t\t)\n\t}\n})\n\n// N.B. asset: is a reference to the local indexedDB object store.\nconst validSrcProtocols = new Set(['http:', 'https:', 'data:', 'asset:'])\n\n/**\n * Validates that a valid is a url safe to load as an asset.\n *\n * @public\n */\nexport const srcUrl = string.check((value) => {\n\tif (value === '') return\n\tconst url = parseUrl(value)\n\n\tif (!validSrcProtocols.has(url.protocol.toLowerCase())) {\n\t\tthrow new ValidationError(\n\t\t\t`Expected a valid url, got ${JSON.stringify(value)} (invalid protocol)`\n\t\t)\n\t}\n})\n\n/**\n * Validates an http(s) url\n *\n * @public\n */\nexport const httpUrl = string.check((value) => {\n\tif (value === '') return\n\tconst url = parseUrl(value)\n\n\tif (!url.protocol.toLowerCase().match(/^https?:$/)) {\n\t\tthrow new ValidationError(\n\t\t\t`Expected a valid url, got ${JSON.stringify(value)} (invalid protocol)`\n\t\t)\n\t}\n})\n\n/**\n * Validates that a value is an IndexKey.\n * @public\n */\nexport const indexKey = string.refine<IndexKey>((key) => {\n\ttry {\n\t\tvalidateIndexKey(key)\n\t\treturn key\n\t} catch {\n\t\tthrow new ValidationError(`Expected an index key, got ${JSON.stringify(key)}`)\n\t}\n})\n\n/**\n * Validate a value against one of two types.\n *\n * @public\n */\nexport function or<T1, T2>(v1: Validatable<T1>, v2: Validatable<T2>): Validator<T1 | T2> {\n\treturn new Validator((value) => {\n\t\ttry {\n\t\t\treturn v1.validate(value)\n\t\t} catch {\n\t\t\treturn v2.validate(value)\n\t\t}\n\t})\n}\n"],
5
5
  "mappings": "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",
6
6
  "names": ["object", "number", "key", "value"]
7
7
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tldraw/validate",
3
3
  "description": "A runtime validation library by tldraw.",
4
- "version": "3.9.0",
4
+ "version": "3.10.0-canary.3176429f9d1b",
5
5
  "author": {
6
6
  "name": "tldraw Inc.",
7
7
  "email": "hello@tldraw.com"
@@ -42,7 +42,7 @@
42
42
  "lint": "yarn run -T tsx ../../internal/scripts/lint.ts"
43
43
  },
44
44
  "dependencies": {
45
- "@tldraw/utils": "3.9.0"
45
+ "@tldraw/utils": "3.10.0-canary.3176429f9d1b"
46
46
  },
47
47
  "jest": {
48
48
  "preset": "../../internal/config/jest/node/jest-preset.js",
@@ -445,7 +445,7 @@ export class UnionValidator<
445
445
  matchingSchema: Validatable<any> | undefined
446
446
  variant: string
447
447
  } {
448
- const variant = getOwnProperty(object, this.key) as string & keyof Config
448
+ const variant = getOwnProperty(object, this.key)! as string & keyof Config
449
449
  if (!this.useNumberKeys && typeof variant !== 'string') {
450
450
  throw new ValidationError(
451
451
  `Expected a string for key "${this.key}", got ${typeToString(variant)}`