import { is, predicates } from "@sealcode/ts-predicates"; import { Context } from "koa"; import { CheckboxedListInput } from "../controls/checkboxed-list-input.js"; import { FormDataValue } from "../form-types.js"; import { FieldParseResult, FormField, FormFieldValidationResponse, } from "./field.js"; export type CheckboxedListItem = { value: string; label?: string; group?: string; }; export class CheckboxedListField< Required extends boolean, Values extends string, > extends FormField< Required, Record, CheckboxedListInput > { constructor( public required: Required, public generateOptions: (ctx: Context) => Promise, public isVisible: (ctx: Context) => Promise = () => Promise.resolve(true) ) { super(required); } predicate = predicates.array(predicates.string); // TODO: this is probably wrong public async isValueValid( _: Context, value: unknown ): Promise { if (is(value, predicates.string)) { return { valid: false, message: "you need an array" }; } if (is(value, predicates.null)) { return { valid: false, message: "you need an array" }; } return { valid: true, message: "" }; } async parse( _: Context, raw_value: FormDataValue ): Promise>> { if (is(raw_value, predicates.object)) { return { parsable: true, parsed_value: Object.fromEntries( Object.entries(raw_value).filter( ([, value]) => value === "on" ) ) as Record, error: null, }; } else { return { parsed_value: null, parsable: false, error: "Expected an object", }; } } public getEmptyValue(): Record { return {}; } getControl(): CheckboxedListInput { return new CheckboxedListInput(this, { label: this.label || this.name, }); } }