77 lines
1.9 KiB
TypeScript
77 lines
1.9 KiB
TypeScript
import { parceable } from "../Schema"
|
|
import SchemaItem from "../SchemaItem"
|
|
import { SchemaInfer, ValidationError, ValidationResult } from "../types"
|
|
|
|
export default class SchemaArray<Type extends SchemaItem> extends SchemaItem<Array<SchemaInfer<Type>>> {
|
|
public constructor(public readonly values: Type) { super(arguments) }
|
|
|
|
public unwrap() {
|
|
return this.values
|
|
}
|
|
|
|
/**
|
|
* transform the array so it only contains one of each elements
|
|
*/
|
|
@parceable()
|
|
public unique(): this {
|
|
this.postProcess.push((input) => input.filter((it, idx) => input.indexOf(it) === idx))
|
|
|
|
return this
|
|
}
|
|
|
|
public parse(input: unknown, options?: { fast?: boolean }): ValidationResult<Array<SchemaInfer<Type>>> {
|
|
|
|
// check errors from itself
|
|
let { valid, object, errors = [] } = super.parse(input, options)
|
|
|
|
// skip checking childs if self is not valid (maybe still try to check childs whan fast is false ?)
|
|
if (!valid) {
|
|
return {
|
|
valid,
|
|
object,
|
|
errors
|
|
} as ValidationResult<SchemaInfer<Type>>
|
|
}
|
|
|
|
const clone: Array<SchemaInfer<Type>> = []
|
|
const errs: Array<ValidationError> = []
|
|
for (let idx = 0; idx < (object as Array<Type>).length; idx++) {
|
|
const item = (object as Array<Type>)[idx]
|
|
const res = this.values.parse(item)
|
|
if (res.errors && res.errors.length > 0) {
|
|
const errors = res.errors.map((it) => ({
|
|
...it,
|
|
field: it.field ? `${idx}.${it.field}` : idx.toString()
|
|
}))
|
|
if (options?.fast) {
|
|
return {
|
|
valid: false,
|
|
object: clone as any,
|
|
errors: errors
|
|
}
|
|
}
|
|
errs.push(...errors)
|
|
} else {
|
|
clone.push(res.object)
|
|
}
|
|
}
|
|
|
|
if (errs.length > 0) {
|
|
return {
|
|
valid: false,
|
|
object: clone as any,
|
|
errors: errs
|
|
}
|
|
}
|
|
|
|
return {
|
|
valid: true,
|
|
object: clone as any
|
|
}
|
|
}
|
|
|
|
public override isOfType(input: unknown): input is Array<SchemaInfer<Type>> {
|
|
return Array.isArray(input)
|
|
}
|
|
}
|