feat: add type definitions (FormDefinition, FormField, settings)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e9e87d52b1
commit
b6f7d0db64
1 changed files with 93 additions and 0 deletions
93
src/types.ts
Normal file
93
src/types.ts
Normal file
|
|
@ -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<T extends Record<string, unknown>>(
|
||||||
|
target: T,
|
||||||
|
source: Partial<T>,
|
||||||
|
): 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<string, unknown>,
|
||||||
|
srcVal as Record<string, unknown>,
|
||||||
|
) as T[keyof T];
|
||||||
|
} else if (srcVal !== undefined) {
|
||||||
|
result[key] = srcVal as T[keyof T];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue