From b6f7d0db644054f4bf96e09813433da3dc611d86 Mon Sep 17 00:00:00 2001 From: tolvitty Date: Fri, 13 Feb 2026 13:12:39 +0100 Subject: [PATCH] feat: add type definitions (FormDefinition, FormField, settings) Co-Authored-By: Claude Opus 4.6 --- src/types.ts | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/types.ts diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..6754459 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,93 @@ +// --------------------------------------------------------------------------- +// Field Types +// --------------------------------------------------------------------------- + +export type FieldType = + | 'text' + | 'textarea' + | 'number' + | 'toggle' + | 'date' + | 'dropdown' + | 'tags' + | 'note-link' + | 'folder-picker' + | 'rating'; + +export interface FormField { + id: string; + label: string; + type: FieldType; + required: boolean; + defaultValue?: string | number | boolean | string[]; + placeholder?: string; + /** For dropdown: list of options. For tags: suggested tags. */ + options?: string[]; + /** For note-link: restrict to files in this folder. */ + folder?: string; +} + +// --------------------------------------------------------------------------- +// Form Definition +// --------------------------------------------------------------------------- + +export interface FormDefinition { + id: string; + name: string; + icon: string; + mode: 'create' | 'update'; + + // mode: "create" only + targetFolder?: string; + fileNameTemplate?: string; + bodyTemplate?: string; + + // mode: "update" only + targetFile?: 'active' | 'prompt'; + + fields: FormField[]; +} + +// --------------------------------------------------------------------------- +// Settings +// --------------------------------------------------------------------------- + +export interface FormfireSettings { + forms: FormDefinition[]; +} + +export const DEFAULT_SETTINGS: FormfireSettings = { + forms: [], +}; + +// --------------------------------------------------------------------------- +// Utilities +// --------------------------------------------------------------------------- + +/** Recursively merge source into target. Arrays are replaced, not merged. */ +export function deepMerge>( + target: T, + source: Partial, +): T { + const result = { ...target }; + for (const key of Object.keys(source) as (keyof T)[]) { + const srcVal = source[key]; + const tgtVal = target[key]; + if ( + srcVal !== null && + typeof srcVal === 'object' && + !Array.isArray(srcVal) && + tgtVal !== null && + typeof tgtVal === 'object' && + !Array.isArray(tgtVal) + ) { + result[key] = deepMerge( + tgtVal as Record, + srcVal as Record, + ) as T[keyof T]; + } else if (srcVal !== undefined) { + result[key] = srcVal as T[keyof T]; + } + } + return result; +}