[fix] allow loading files (#3517)
I messed up the schema validator for loading files. ### Change Type <!-- ❗ Please select a 'Scope' label ❗️ --> - [x] `sdk` — Changes the tldraw SDK - [ ] `dotcom` — Changes the tldraw.com web app - [ ] `docs` — Changes to the documentation, examples, or templates. - [ ] `vs code` — Changes to the vscode plugin - [ ] `internal` — Does not affect user-facing stuff <!-- ❗ Please select a 'Type' label ❗️ --> - [x] `bugfix` — Bug fix - [ ] `feature` — New feature - [ ] `improvement` — Improving existing features - [ ] `chore` — Updating dependencies, other boring stuff - [ ] `galaxy brain` — Architectural changes - [ ] `tests` — Changes to any test code - [ ] `tools` — Changes to infrastructure, CI, internal scripts, debugging tools, etc. - [ ] `dunno` — I don't know
This commit is contained in:
parent
f70fd2729d
commit
625f4abc3b
4 changed files with 80 additions and 14 deletions
|
@ -62,7 +62,7 @@ const schemaV2 = T.object<SerializedSchemaV2>({
|
|||
|
||||
const tldrawFileValidator: T.Validator<TldrawFile> = T.object({
|
||||
tldrawFileFormatVersion: T.nonZeroInteger,
|
||||
schema: T.union('schemaVersion', {
|
||||
schema: T.numberUnion('schemaVersion', {
|
||||
1: schemaV1,
|
||||
2: schemaV2,
|
||||
}),
|
||||
|
|
|
@ -83,6 +83,9 @@ function nullable<T>(validator: Validatable<T>): Validator<null | T>;
|
|||
// @public
|
||||
const number: Validator<number>;
|
||||
|
||||
// @internal (undocumented)
|
||||
function numberUnion<Key extends string, Config extends UnionValidatorConfig<Key, Config>>(key: Key, config: Config): UnionValidator<Key, Config>;
|
||||
|
||||
// @public
|
||||
function object<Shape extends object>(config: {
|
||||
readonly [K in keyof Shape]: Validatable<Shape[K]>;
|
||||
|
@ -134,6 +137,7 @@ declare namespace T {
|
|||
jsonDict,
|
||||
dict,
|
||||
union,
|
||||
numberUnion,
|
||||
model,
|
||||
setEnum,
|
||||
optional,
|
||||
|
@ -178,7 +182,7 @@ function union<Key extends string, Config extends UnionValidatorConfig<Key, Conf
|
|||
|
||||
// @public (undocumented)
|
||||
export class UnionValidator<Key extends string, Config extends UnionValidatorConfig<Key, Config>, UnknownValue = never> extends Validator<TypeOf<Config[keyof Config]> | UnknownValue> {
|
||||
constructor(key: Key, config: Config, unknownValueValidation: (value: object, variant: string) => UnknownValue);
|
||||
constructor(key: Key, config: Config, unknownValueValidation: (value: object, variant: string) => UnknownValue, useNumberKeys: boolean);
|
||||
// (undocumented)
|
||||
validateUnknownVariants<Unknown>(unknownValueValidation: (value: object, variant: string) => Unknown): UnionValidator<Key, Config, Unknown>;
|
||||
}
|
||||
|
|
|
@ -3027,6 +3027,14 @@
|
|||
"kind": "Content",
|
||||
"text": "(value: object, variant: string) => UnknownValue"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", useNumberKeys: "
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "boolean"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ");"
|
||||
|
@ -3059,6 +3067,14 @@
|
|||
"endIndex": 6
|
||||
},
|
||||
"isOptional": false
|
||||
},
|
||||
{
|
||||
"parameterName": "useNumberKeys",
|
||||
"parameterTypeTokenRange": {
|
||||
"startIndex": 7,
|
||||
"endIndex": 8
|
||||
},
|
||||
"isOptional": false
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -4260,6 +4276,14 @@
|
|||
"kind": "Content",
|
||||
"text": "(value: object, variant: string) => UnknownValue"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", useNumberKeys: "
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "boolean"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ");"
|
||||
|
@ -4292,6 +4316,14 @@
|
|||
"endIndex": 6
|
||||
},
|
||||
"isOptional": false
|
||||
},
|
||||
{
|
||||
"parameterName": "useNumberKeys",
|
||||
"parameterTypeTokenRange": {
|
||||
"startIndex": 7,
|
||||
"endIndex": 8
|
||||
},
|
||||
"isOptional": false
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -394,7 +394,8 @@ export class UnionValidator<
|
|||
constructor(
|
||||
private readonly key: Key,
|
||||
private readonly config: Config,
|
||||
private readonly unknownValueValidation: (value: object, variant: string) => UnknownValue
|
||||
private readonly unknownValueValidation: (value: object, variant: string) => UnknownValue,
|
||||
private readonly useNumberKeys: boolean
|
||||
) {
|
||||
super(
|
||||
(input) => {
|
||||
|
@ -442,11 +443,13 @@ export class UnionValidator<
|
|||
matchingSchema: Validatable<any> | undefined
|
||||
variant: string
|
||||
} {
|
||||
const variant = getOwnProperty(object, this.key) as keyof Config | undefined
|
||||
if (typeof variant !== 'string') {
|
||||
const variant = getOwnProperty(object, this.key) as string & keyof Config
|
||||
if (!this.useNumberKeys && typeof variant !== 'string') {
|
||||
throw new ValidationError(
|
||||
`Expected a string for key "${this.key}", got ${typeToString(variant)}`
|
||||
)
|
||||
} else if (this.useNumberKeys && !Number.isFinite(Number(variant))) {
|
||||
throw new ValidationError(`Expected a number for key "${this.key}", got "${variant as any}"`)
|
||||
}
|
||||
|
||||
const matchingSchema = hasOwnProperty(this.config, variant) ? this.config[variant] : undefined
|
||||
|
@ -456,7 +459,7 @@ export class UnionValidator<
|
|||
validateUnknownVariants<Unknown>(
|
||||
unknownValueValidation: (value: object, variant: string) => Unknown
|
||||
): UnionValidator<Key, Config, Unknown> {
|
||||
return new UnionValidator(this.key, this.config, unknownValueValidation)
|
||||
return new UnionValidator(this.key, this.config, unknownValueValidation, this.useNumberKeys)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -829,14 +832,41 @@ export function union<Key extends string, Config extends UnionValidatorConfig<Ke
|
|||
key: Key,
|
||||
config: Config
|
||||
): UnionValidator<Key, Config> {
|
||||
return new UnionValidator(key, config, (unknownValue, unknownVariant) => {
|
||||
throw new ValidationError(
|
||||
`Expected one of ${Object.keys(config)
|
||||
.map((key) => JSON.stringify(key))
|
||||
.join(' or ')}, got ${JSON.stringify(unknownVariant)}`,
|
||||
[key]
|
||||
)
|
||||
})
|
||||
return new UnionValidator(
|
||||
key,
|
||||
config,
|
||||
(unknownValue, unknownVariant) => {
|
||||
throw new ValidationError(
|
||||
`Expected one of ${Object.keys(config)
|
||||
.map((key) => JSON.stringify(key))
|
||||
.join(' or ')}, got ${JSON.stringify(unknownVariant)}`,
|
||||
[key]
|
||||
)
|
||||
},
|
||||
false
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function numberUnion<Key extends string, Config extends UnionValidatorConfig<Key, Config>>(
|
||||
key: Key,
|
||||
config: Config
|
||||
): UnionValidator<Key, Config> {
|
||||
return new UnionValidator(
|
||||
key,
|
||||
config,
|
||||
(unknownValue, unknownVariant) => {
|
||||
throw new ValidationError(
|
||||
`Expected one of ${Object.keys(config)
|
||||
.map((key) => JSON.stringify(key))
|
||||
.join(' or ')}, got ${JSON.stringify(unknownVariant)}`,
|
||||
[key]
|
||||
)
|
||||
},
|
||||
true
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue