@flightdev/forms 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,181 @@
1
+ /**
2
+ * @flightdev/forms - Agnostic Full-Stack Form Handling
3
+ *
4
+ * Flight provides form primitives, you choose the validator.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { createForm } from '@flightdev/forms';
9
+ * import { zod } from '@flightdev/forms/zod';
10
+ * import { z } from 'zod';
11
+ *
12
+ * const contactForm = createForm({
13
+ * validator: zod(z.object({
14
+ * email: z.string().email(),
15
+ * message: z.string().min(10),
16
+ * })),
17
+ * action: async (data) => {
18
+ * await sendEmail(data.email, data.message);
19
+ * return { success: true };
20
+ * },
21
+ * });
22
+ * ```
23
+ */
24
+ /** Validation error for a single field */
25
+ interface FieldError {
26
+ /** Field path (e.g., 'email', 'address.street') */
27
+ path: string;
28
+ /** Error message */
29
+ message: string;
30
+ /** Error code (e.g., 'invalid_type', 'too_small') */
31
+ code?: string;
32
+ }
33
+ /** Result of validation */
34
+ interface ValidationResult<T> {
35
+ /** Whether validation passed */
36
+ success: boolean;
37
+ /** Validated and transformed data (if success) */
38
+ data?: T;
39
+ /** Validation errors (if not success) */
40
+ errors?: FieldError[];
41
+ }
42
+ /** Form submission result */
43
+ interface FormResult<T = unknown> {
44
+ /** Whether the action succeeded */
45
+ success: boolean;
46
+ /** Returned data from the action */
47
+ data?: T;
48
+ /** Error message if failed */
49
+ error?: string;
50
+ /** Field-specific errors */
51
+ fieldErrors?: FieldError[];
52
+ }
53
+ /** Form state during submission */
54
+ interface FormState<T = unknown> {
55
+ /** Whether form is currently submitting */
56
+ pending: boolean;
57
+ /** Last submission result */
58
+ result?: FormResult<T>;
59
+ /** Current form data */
60
+ data?: Partial<T>;
61
+ /** Current validation errors */
62
+ errors: Record<string, string>;
63
+ /** Fields that have been touched */
64
+ touched: Set<string>;
65
+ /** Whether form has been modified */
66
+ dirty: boolean;
67
+ }
68
+ /**
69
+ * Validation Adapter Interface
70
+ *
71
+ * Implement this to create a custom validator adapter.
72
+ * Flight provides Zod, Yup, and Valibot adapters.
73
+ */
74
+ interface ValidationAdapter<TInput = unknown, TOutput = TInput> {
75
+ /** Adapter name for debugging */
76
+ readonly name: string;
77
+ /**
78
+ * Validate input data
79
+ *
80
+ * @param data - Raw input data to validate
81
+ * @returns Validation result with either typed data or errors
82
+ */
83
+ validate(data: unknown): ValidationResult<TOutput>;
84
+ /**
85
+ * Async validate (for schemas with async refinements)
86
+ */
87
+ validateAsync(data: unknown): Promise<ValidationResult<TOutput>>;
88
+ /**
89
+ * Get the inferred output type (for TypeScript)
90
+ * This is used for type inference only.
91
+ */
92
+ readonly _output: TOutput;
93
+ }
94
+ /** Validation adapter factory type */
95
+ type ValidationAdapterFactory<TSchema, TOutput> = (schema: TSchema) => ValidationAdapter<unknown, TOutput>;
96
+ /** Form action function type */
97
+ type FormAction<TInput, TResult = unknown> = (data: TInput, context?: FormActionContext) => Promise<FormResult<TResult>>;
98
+ /** Context passed to form actions */
99
+ interface FormActionContext {
100
+ /** Original request (server-side) */
101
+ request?: Request;
102
+ /** Form data (for file uploads) */
103
+ formData?: FormData;
104
+ }
105
+ /** Form definition options */
106
+ interface FormOptions<TValidator extends ValidationAdapter<unknown, unknown>, TResult = unknown> {
107
+ /** Validation adapter with schema */
108
+ validator: TValidator;
109
+ /** Server action to execute on submit */
110
+ action: FormAction<TValidator['_output'], TResult>;
111
+ /** Enable CSRF protection */
112
+ csrf?: boolean;
113
+ /** Form ID (for multiple forms on same page) */
114
+ id?: string;
115
+ /** Redirect URL on success */
116
+ redirectOnSuccess?: string;
117
+ /** Enable progressive enhancement */
118
+ progressive?: boolean;
119
+ }
120
+ /** Form instance */
121
+ interface FormDefinition<TInput, TResult = unknown> {
122
+ /** Form ID */
123
+ readonly id: string;
124
+ /** Validate data */
125
+ validate(data: unknown): ValidationResult<TInput>;
126
+ /** Validate data async */
127
+ validateAsync(data: unknown): Promise<ValidationResult<TInput>>;
128
+ /** Execute the form action (server-side) */
129
+ execute(data: unknown, context?: FormActionContext): Promise<FormResult<TResult>>;
130
+ /** Parse FormData to object */
131
+ parseFormData(formData: FormData): Record<string, unknown>;
132
+ /** Handle form submission (server-side) */
133
+ handleSubmit(request: Request): Promise<FormResult<TResult>>;
134
+ }
135
+ /**
136
+ * Create a form definition
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * import { createForm } from '@flightdev/forms';
141
+ * import { zod } from '@flightdev/forms/zod';
142
+ * import { z } from 'zod';
143
+ *
144
+ * const loginForm = createForm({
145
+ * validator: zod(z.object({
146
+ * email: z.string().email(),
147
+ * password: z.string().min(8),
148
+ * })),
149
+ * action: async (data) => {
150
+ * const user = await authenticate(data.email, data.password);
151
+ * if (user) {
152
+ * return { success: true, data: { userId: user.id } };
153
+ * }
154
+ * return {
155
+ * success: false,
156
+ * error: 'Invalid credentials',
157
+ * fieldErrors: [{ path: 'email', message: 'Invalid email or password' }],
158
+ * };
159
+ * },
160
+ * });
161
+ * ```
162
+ */
163
+ declare function createForm<TValidator extends ValidationAdapter<unknown, unknown>, TResult = unknown>(options: FormOptions<TValidator, TResult>): FormDefinition<TValidator['_output'], TResult>;
164
+ /**
165
+ * Create initial form state
166
+ */
167
+ declare function createFormState<T>(): FormState<T>;
168
+ /**
169
+ * Convert field errors array to errors object
170
+ */
171
+ declare function errorsToObject(errors: FieldError[]): Record<string, string>;
172
+ /**
173
+ * Get error for a specific field
174
+ */
175
+ declare function getFieldError(errors: FieldError[], path: string): string | undefined;
176
+ /**
177
+ * Check if form has any errors
178
+ */
179
+ declare function hasErrors(state: FormState<unknown>): boolean;
180
+
181
+ export { type FieldError, type FormAction, type FormActionContext, type FormDefinition, type FormOptions, type FormResult, type FormState, type ValidationAdapter, type ValidationAdapterFactory, type ValidationResult, createForm, createFormState, errorsToObject, getFieldError, hasErrors };
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { createForm, createFormState, errorsToObject, getFieldError, hasErrors } from './chunk-5LLYBEXV.js';
2
+ import './chunk-DGUM43GV.js';
3
+ //# sourceMappingURL=index.js.map
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
package/package.json ADDED
@@ -0,0 +1,102 @@
1
+ {
2
+ "name": "@flightdev/forms",
3
+ "version": "0.0.2",
4
+ "description": "Agnostic full-stack form handling for Flight Framework. Choose your validator: Zod, Yup, Valibot, or custom.",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/index.js"
10
+ },
11
+ "./zod": {
12
+ "types": "./dist/adapters/zod.d.ts",
13
+ "import": "./dist/adapters/zod.js"
14
+ },
15
+ "./yup": {
16
+ "types": "./dist/adapters/yup.d.ts",
17
+ "import": "./dist/adapters/yup.js"
18
+ },
19
+ "./valibot": {
20
+ "types": "./dist/adapters/valibot.d.ts",
21
+ "import": "./dist/adapters/valibot.js"
22
+ },
23
+ "./react": {
24
+ "types": "./dist/frameworks/react.d.ts",
25
+ "import": "./dist/frameworks/react.js"
26
+ },
27
+ "./vue": {
28
+ "types": "./dist/frameworks/vue.d.ts",
29
+ "import": "./dist/frameworks/vue.js"
30
+ },
31
+ "./svelte": {
32
+ "types": "./dist/frameworks/svelte.d.ts",
33
+ "import": "./dist/frameworks/svelte.js"
34
+ },
35
+ "./solid": {
36
+ "types": "./dist/frameworks/solid.d.ts",
37
+ "import": "./dist/frameworks/solid.js"
38
+ }
39
+ },
40
+ "main": "./dist/index.js",
41
+ "types": "./dist/index.d.ts",
42
+ "files": [
43
+ "dist"
44
+ ],
45
+ "dependencies": {},
46
+ "peerDependencies": {
47
+ "zod": ">=3.0.0",
48
+ "yup": ">=1.0.0",
49
+ "valibot": ">=0.30.0",
50
+ "react": ">=18.0.0",
51
+ "vue": ">=3.0.0",
52
+ "svelte": ">=4.0.0",
53
+ "solid-js": ">=1.0.0"
54
+ },
55
+ "peerDependenciesMeta": {
56
+ "zod": {
57
+ "optional": true
58
+ },
59
+ "yup": {
60
+ "optional": true
61
+ },
62
+ "valibot": {
63
+ "optional": true
64
+ },
65
+ "react": {
66
+ "optional": true
67
+ },
68
+ "vue": {
69
+ "optional": true
70
+ },
71
+ "svelte": {
72
+ "optional": true
73
+ },
74
+ "solid-js": {
75
+ "optional": true
76
+ }
77
+ },
78
+ "devDependencies": {
79
+ "@types/node": "^22.0.0",
80
+ "tsup": "^8.0.0",
81
+ "typescript": "^5.7.0",
82
+ "vitest": "^2.0.0"
83
+ },
84
+ "keywords": [
85
+ "flight",
86
+ "forms",
87
+ "validation",
88
+ "zod",
89
+ "yup",
90
+ "valibot",
91
+ "progressive-enhancement"
92
+ ],
93
+ "author": "Flight Contributors",
94
+ "license": "MIT",
95
+ "scripts": {
96
+ "build": "tsup",
97
+ "dev": "tsup --watch",
98
+ "test": "vitest run",
99
+ "test:watch": "vitest",
100
+ "typecheck": "tsc --noEmit"
101
+ }
102
+ }