import { type FieldProcessor, FieldSchema, StructureSchema } from '@ephox/boulder'; import { Arr, Fun, Obj, type Optional } from '@ephox/katamari'; import { type BehaviourState, type BehaviourStateInitialiser, NoState } from './BehaviourState'; import type { AlloyBehaviour, BehaviourConfigDetail, BehaviourConfigSpec, BehaviourRecord } from './BehaviourTypes'; export interface BehaviourConfigAndState { config: C; state: S; } export interface BehaviourSpec { config: C; state: BehaviourStateInitialiser; } export interface BehaviourData { list: Array>; data: Record Optional>>; } const generateFrom = (spec: { behaviours?: BehaviourRecord }, all: Array>): BehaviourData => { /* * This takes a basic record of configured behaviours, defaults their state * and ensures that all the behaviours were valid. Will need to document * this entire process. Let's see where this is used. */ const schema: FieldProcessor[] = Arr.map(all, (a) => // Optional here probably just due to ForeignGui listing everything it supports. Can most likely // change it to strict once I fix the other errors. FieldSchema.optionObjOf(a.name(), [ FieldSchema.required('config'), FieldSchema.defaulted('state', NoState) ]) ); type B = Record>>; const validated = StructureSchema.asRaw( 'component.behaviours', StructureSchema.objOf(schema), spec.behaviours ).fold((errInfo) => { throw new Error( StructureSchema.formatError(errInfo) + '\nComplete spec:\n' + JSON.stringify(spec, null, 2) ); }, Fun.identity); return { list: all, data: Obj.map(validated, (optBlobThunk) => { const output = optBlobThunk.map((blob) => ({ config: blob.config, state: blob.state.init(blob.config) })); return Fun.constant(output); }) }; }; const getBehaviours = (bData: BehaviourData): Array> => bData.list; const getData = (bData: BehaviourData): Record Optional>> => bData.data; export { generateFrom, getBehaviours, getData };