import Router from "@koa/router"; import { hasShape, predicates } from "@sealcode/ts-predicates"; import { Context } from "koa"; import { ParsedUrlQuery } from "querystring"; import { FlatTemplatable, tempstream } from "tempstream"; import { makeSlug } from "../../utils/make-slug.js"; import { FormField } from "../fields/field.js"; import { Derived } from "./derived.js"; import { FormControlContext } from "./form-control.js"; export class DerivedFrame extends Derived<{ frame_id: string; form_id: string; field_name_prefix: string; }> { constructor( public frame_name: string, fields: FormField[], public generateFrameContent: ( ctx: FormControlContext, args: ParsedUrlQuery ) => Promise, // "a" is to make it a valid DOM id public frame_id = "a" + makeSlug(frame_name) ) { super( fields, async (values, consts) => /* HTML */ ``, async (fctx) => ({ form_id: fctx.form_id, field_name_prefix: fctx.field_name_prefix, frame_id, validate: fctx.validate, }) ); } renderBackendResponseFrame(_ctx: Context, content: FlatTemplatable) { return tempstream /* HTML */ ` ${content || ""} `; } mount(router: Router) { router.get(this.frame_id, async (ctx) => { const query = ctx.query; if ( !hasShape( { field_name_prefix: predicates.string, form_id: predicates.string, validate: predicates.string, }, query ) ) { ctx.body = this.renderBackendResponseFrame( ctx, "Missing query params" ); return; } ctx.body = this.renderBackendResponseFrame( ctx, await this.generateFrameContent( new FormControlContext( ctx, { messages: [], field_messages: {}, raw_values: ctx.query, }, [], query.field_name_prefix, query.form_id, query.validate === "true" ? true : false ), ctx.query ) ); }); return; } }