@btst/stack 1.5.2 → 1.6.0
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.
- package/dist/node_modules/.pnpm/@dnd-kit_accessibility@3.1.1_react@19.2.0/node_modules/@dnd-kit/accessibility/dist/accessibility.esm.cjs +68 -0
- package/dist/node_modules/.pnpm/@dnd-kit_accessibility@3.1.1_react@19.2.0/node_modules/@dnd-kit/accessibility/dist/accessibility.esm.mjs +60 -0
- package/dist/node_modules/.pnpm/@dnd-kit_core@6.3.1_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/@dnd-kit/core/dist/core.esm.cjs +3937 -0
- package/dist/node_modules/.pnpm/@dnd-kit_core@6.3.1_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/@dnd-kit/core/dist/core.esm.mjs +3907 -0
- package/dist/node_modules/.pnpm/@dnd-kit_modifiers@9.0.0_@dnd-kit_core@6.3.1_react-dom@19.2.0_react@19.2.0__react@19.2.0__react@19.2.0/node_modules/@dnd-kit/modifiers/dist/modifiers.esm.cjs +30 -0
- package/dist/node_modules/.pnpm/@dnd-kit_modifiers@9.0.0_@dnd-kit_core@6.3.1_react-dom@19.2.0_react@19.2.0__react@19.2.0__react@19.2.0/node_modules/@dnd-kit/modifiers/dist/modifiers.esm.mjs +28 -0
- package/dist/node_modules/.pnpm/@dnd-kit_sortable@10.0.0_@dnd-kit_core@6.3.1_react-dom@19.2.0_react@19.2.0__react@19.2.0__react@19.2.0/node_modules/@dnd-kit/sortable/dist/sortable.esm.cjs +675 -0
- package/dist/node_modules/.pnpm/@dnd-kit_sortable@10.0.0_@dnd-kit_core@6.3.1_react-dom@19.2.0_react@19.2.0__react@19.2.0__react@19.2.0/node_modules/@dnd-kit/sortable/dist/sortable.esm.mjs +661 -0
- package/dist/node_modules/.pnpm/@dnd-kit_utilities@3.2.2_react@19.2.0/node_modules/@dnd-kit/utilities/dist/utilities.esm.cjs +358 -0
- package/dist/node_modules/.pnpm/@dnd-kit_utilities@3.2.2_react@19.2.0/node_modules/@dnd-kit/utilities/dist/utilities.esm.mjs +332 -0
- package/dist/node_modules/.pnpm/@radix-ui_react-tabs@1.1.13_@types_react-dom@19.2.3_@types_react@19.2.6__@types_react@1_865f042350eb43f3338b0fffb33f6246/node_modules/@radix-ui/react-tabs/dist/index.cjs +211 -0
- package/dist/node_modules/.pnpm/@radix-ui_react-tabs@1.1.13_@types_react-dom@19.2.3_@types_react@19.2.6__@types_react@1_865f042350eb43f3338b0fffb33f6246/node_modules/@radix-ui/react-tabs/dist/index.mjs +188 -0
- package/dist/packages/better-stack/src/plugins/cms/api/plugin.cjs +3 -2
- package/dist/packages/better-stack/src/plugins/cms/api/plugin.mjs +3 -2
- package/dist/packages/better-stack/src/plugins/cms/client/components/forms/content-form.cjs +15 -15
- package/dist/packages/better-stack/src/plugins/cms/client/components/forms/content-form.mjs +16 -16
- package/dist/packages/better-stack/src/plugins/form-builder/api/plugin.cjs +588 -0
- package/dist/packages/better-stack/src/plugins/form-builder/api/plugin.mjs +586 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/forms/form-renderer.cjs +131 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/forms/form-renderer.mjs +129 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/loading/form-builder-skeleton.cjs +32 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/loading/form-builder-skeleton.mjs +30 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/loading/form-list-skeleton.cjs +21 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/loading/form-list-skeleton.mjs +19 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/loading/submissions-skeleton.cjs +34 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/loading/submissions-skeleton.mjs +32 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/404-page.cjs +20 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/404-page.mjs +18 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/form-builder-page.cjs +19 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/form-builder-page.internal.cjs +186 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/form-builder-page.internal.mjs +184 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/form-builder-page.mjs +17 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/form-list-page.cjs +19 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/form-list-page.internal.cjs +165 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/form-list-page.internal.mjs +163 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/form-list-page.mjs +17 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/submissions-page.cjs +19 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/submissions-page.internal.cjs +177 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/submissions-page.internal.mjs +175 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/pages/submissions-page.mjs +17 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/shared/default-error.cjs +17 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/shared/default-error.mjs +15 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/shared/empty-state.cjs +16 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/shared/empty-state.mjs +14 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/shared/page-wrapper.cjs +27 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/shared/page-wrapper.mjs +25 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/shared/pagination.cjs +39 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/components/shared/pagination.mjs +37 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/hooks/form-builder-hooks.cjs +551 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/hooks/form-builder-hooks.mjs +537 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/localization/form-builder-common.cjs +36 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/localization/form-builder-common.mjs +34 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/localization/form-builder-editor.cjs +19 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/localization/form-builder-editor.mjs +17 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/localization/form-builder-list.cjs +21 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/localization/form-builder-list.mjs +19 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/localization/form-builder-submissions.cjs +19 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/localization/form-builder-submissions.mjs +17 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/localization/form-builder-toasts.cjs +14 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/localization/form-builder-toasts.mjs +12 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/localization/index.cjs +17 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/localization/index.mjs +15 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/plugin.cjs +278 -0
- package/dist/packages/better-stack/src/plugins/form-builder/client/plugin.mjs +276 -0
- package/dist/packages/better-stack/src/plugins/form-builder/db.cjs +99 -0
- package/dist/packages/better-stack/src/plugins/form-builder/db.mjs +97 -0
- package/dist/packages/better-stack/src/plugins/form-builder/schemas.cjs +82 -0
- package/dist/packages/better-stack/src/plugins/form-builder/schemas.mjs +74 -0
- package/dist/packages/better-stack/src/plugins/form-builder/utils.cjs +37 -0
- package/dist/packages/better-stack/src/plugins/form-builder/utils.mjs +29 -0
- package/dist/packages/ui/src/components/auto-form/index.cjs +2 -12
- package/dist/packages/ui/src/components/auto-form/index.mjs +2 -9
- package/dist/packages/ui/src/components/auto-form/stepped-auto-form.cjs +377 -0
- package/dist/packages/ui/src/components/auto-form/stepped-auto-form.mjs +368 -0
- package/dist/packages/ui/src/components/auto-form/utils.cjs +1 -56
- package/dist/packages/ui/src/components/auto-form/utils.mjs +2 -56
- package/dist/packages/ui/src/components/form-builder/canvas.cjs +111 -0
- package/dist/packages/ui/src/components/form-builder/canvas.mjs +109 -0
- package/dist/packages/ui/src/components/form-builder/components/index.cjs +570 -0
- package/dist/packages/ui/src/components/form-builder/components/index.mjs +553 -0
- package/dist/packages/ui/src/components/form-builder/edit-field-dialog.cjs +131 -0
- package/dist/packages/ui/src/components/form-builder/edit-field-dialog.mjs +129 -0
- package/dist/packages/ui/src/components/form-builder/form-preview.cjs +73 -0
- package/dist/packages/ui/src/components/form-builder/form-preview.mjs +71 -0
- package/dist/packages/ui/src/components/form-builder/index.cjs +353 -0
- package/dist/packages/ui/src/components/form-builder/index.mjs +344 -0
- package/dist/packages/ui/src/components/form-builder/nested-field-editor-dialog.cjs +263 -0
- package/dist/packages/ui/src/components/form-builder/nested-field-editor-dialog.mjs +261 -0
- package/dist/packages/ui/src/components/form-builder/palette.cjs +52 -0
- package/dist/packages/ui/src/components/form-builder/palette.mjs +49 -0
- package/dist/packages/ui/src/components/form-builder/schema-utils.cjs +120 -0
- package/dist/packages/ui/src/components/form-builder/schema-utils.mjs +114 -0
- package/dist/packages/ui/src/components/form-builder/sortable-field.cjs +151 -0
- package/dist/packages/ui/src/components/form-builder/sortable-field.mjs +148 -0
- package/dist/packages/ui/src/components/form-builder/step-tabs.cjs +180 -0
- package/dist/packages/ui/src/components/form-builder/step-tabs.mjs +178 -0
- package/dist/packages/ui/src/components/form-builder/types.cjs +7 -0
- package/dist/packages/ui/src/components/form-builder/types.mjs +5 -0
- package/dist/packages/ui/src/components/form-builder/validation-schemas.cjs +67 -0
- package/dist/packages/ui/src/components/form-builder/validation-schemas.mjs +56 -0
- package/dist/packages/ui/src/components/tabs.cjs +70 -0
- package/dist/packages/ui/src/components/tabs.mjs +65 -0
- package/dist/packages/ui/src/lib/schema-converter.cjs +130 -0
- package/dist/packages/ui/src/lib/schema-converter.mjs +124 -0
- package/dist/plugins/blog/api/index.d.cts +1 -1
- package/dist/plugins/blog/api/index.d.mts +1 -1
- package/dist/plugins/blog/api/index.d.ts +1 -1
- package/dist/plugins/blog/client/hooks/index.d.cts +2 -2
- package/dist/plugins/blog/client/hooks/index.d.mts +2 -2
- package/dist/plugins/blog/client/hooks/index.d.ts +2 -2
- package/dist/plugins/blog/client/index.d.cts +1 -1
- package/dist/plugins/blog/client/index.d.mts +1 -1
- package/dist/plugins/blog/client/index.d.ts +1 -1
- package/dist/plugins/blog/query-keys.d.cts +2 -2
- package/dist/plugins/blog/query-keys.d.mts +2 -2
- package/dist/plugins/blog/query-keys.d.ts +2 -2
- package/dist/plugins/cms/client/index.cjs +6 -0
- package/dist/plugins/cms/client/index.d.cts +6 -113
- package/dist/plugins/cms/client/index.d.mts +6 -113
- package/dist/plugins/cms/client/index.d.ts +6 -113
- package/dist/plugins/cms/client/index.mjs +1 -0
- package/dist/plugins/form-builder/api/index.cjs +7 -0
- package/dist/plugins/form-builder/api/index.d.cts +141 -0
- package/dist/plugins/form-builder/api/index.d.mts +141 -0
- package/dist/plugins/form-builder/api/index.d.ts +141 -0
- package/dist/plugins/form-builder/api/index.mjs +1 -0
- package/dist/plugins/form-builder/client/components/index.cjs +29 -0
- package/dist/plugins/form-builder/client/components/index.d.cts +93 -0
- package/dist/plugins/form-builder/client/components/index.d.mts +93 -0
- package/dist/plugins/form-builder/client/components/index.d.ts +93 -0
- package/dist/plugins/form-builder/client/components/index.mjs +18 -0
- package/dist/plugins/form-builder/client/hooks/index.cjs +19 -0
- package/dist/plugins/form-builder/client/hooks/index.d.cts +154 -0
- package/dist/plugins/form-builder/client/hooks/index.d.mts +154 -0
- package/dist/plugins/form-builder/client/hooks/index.d.ts +154 -0
- package/dist/plugins/form-builder/client/hooks/index.mjs +1 -0
- package/dist/plugins/form-builder/client/index.cjs +13 -0
- package/dist/plugins/form-builder/client/index.d.cts +381 -0
- package/dist/plugins/form-builder/client/index.d.mts +381 -0
- package/dist/plugins/form-builder/client/index.d.ts +381 -0
- package/dist/plugins/form-builder/client/index.mjs +2 -0
- package/dist/plugins/form-builder/client.css +3 -0
- package/dist/plugins/form-builder/query-keys.cjs +143 -0
- package/dist/plugins/form-builder/query-keys.d.cts +74 -0
- package/dist/plugins/form-builder/query-keys.d.mts +74 -0
- package/dist/plugins/form-builder/query-keys.d.ts +74 -0
- package/dist/plugins/form-builder/query-keys.mjs +141 -0
- package/dist/plugins/form-builder/style.css +19 -0
- package/dist/shared/stack.AX5nZ6A3.d.cts +86 -0
- package/dist/shared/stack.AX5nZ6A3.d.mts +86 -0
- package/dist/shared/stack.AX5nZ6A3.d.ts +86 -0
- package/dist/shared/stack.BIh2AXaW.d.cts +123 -0
- package/dist/shared/stack.BIh2AXaW.d.mts +123 -0
- package/dist/shared/stack.BIh2AXaW.d.ts +123 -0
- package/dist/shared/stack.DzH_wcvr.d.cts +195 -0
- package/dist/shared/stack.DzH_wcvr.d.mts +195 -0
- package/dist/shared/stack.DzH_wcvr.d.ts +195 -0
- package/package.json +54 -1
- package/src/plugins/cms/api/plugin.ts +9 -4
- package/src/plugins/cms/client/components/forms/content-form.tsx +23 -25
- package/src/plugins/cms/client/index.ts +11 -0
- package/src/plugins/form-builder/api/index.ts +1 -0
- package/src/plugins/form-builder/api/plugin.ts +776 -0
- package/src/plugins/form-builder/client/components/forms/form-renderer.tsx +253 -0
- package/src/plugins/form-builder/client/components/index.tsx +24 -0
- package/src/plugins/form-builder/client/components/loading/form-builder-skeleton.tsx +42 -0
- package/src/plugins/form-builder/client/components/loading/form-list-skeleton.tsx +25 -0
- package/src/plugins/form-builder/client/components/loading/index.tsx +3 -0
- package/src/plugins/form-builder/client/components/loading/submissions-skeleton.tsx +40 -0
- package/src/plugins/form-builder/client/components/pages/404-page.tsx +28 -0
- package/src/plugins/form-builder/client/components/pages/form-builder-page.internal.tsx +253 -0
- package/src/plugins/form-builder/client/components/pages/form-builder-page.tsx +26 -0
- package/src/plugins/form-builder/client/components/pages/form-list-page.internal.tsx +231 -0
- package/src/plugins/form-builder/client/components/pages/form-list-page.tsx +22 -0
- package/src/plugins/form-builder/client/components/pages/submissions-page.internal.tsx +268 -0
- package/src/plugins/form-builder/client/components/pages/submissions-page.tsx +26 -0
- package/src/plugins/form-builder/client/components/shared/default-error.tsx +30 -0
- package/src/plugins/form-builder/client/components/shared/empty-state.tsx +26 -0
- package/src/plugins/form-builder/client/components/shared/page-wrapper.tsx +32 -0
- package/src/plugins/form-builder/client/components/shared/pagination.tsx +52 -0
- package/src/plugins/form-builder/client/hooks/form-builder-hooks.tsx +799 -0
- package/src/plugins/form-builder/client/hooks/index.tsx +1 -0
- package/src/plugins/form-builder/client/index.ts +22 -0
- package/src/plugins/form-builder/client/localization/form-builder-common.ts +36 -0
- package/src/plugins/form-builder/client/localization/form-builder-editor.ts +18 -0
- package/src/plugins/form-builder/client/localization/form-builder-list.ts +17 -0
- package/src/plugins/form-builder/client/localization/form-builder-submissions.ts +17 -0
- package/src/plugins/form-builder/client/localization/form-builder-toasts.ts +10 -0
- package/src/plugins/form-builder/client/localization/index.ts +15 -0
- package/src/plugins/form-builder/client/overrides.ts +146 -0
- package/src/plugins/form-builder/client/plugin.tsx +488 -0
- package/src/plugins/form-builder/client.css +3 -0
- package/src/plugins/form-builder/db.ts +99 -0
- package/src/plugins/form-builder/query-keys.ts +198 -0
- package/src/plugins/form-builder/schemas.ts +122 -0
- package/src/plugins/form-builder/style.css +19 -0
- package/src/plugins/form-builder/types.ts +317 -0
- package/src/plugins/form-builder/utils.ts +63 -0
- package/dist/shared/{stack.DLhzx1-D.d.cts → stack.CcI4sYJP.d.cts} +1 -1
- package/dist/shared/{stack.DLhzx1-D.d.mts → stack.CcI4sYJP.d.mts} +1 -1
- package/dist/shared/{stack.DLhzx1-D.d.ts → stack.CcI4sYJP.d.ts} +1 -1
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Form Builder Plugin Types
|
|
3
|
+
*
|
|
4
|
+
* Key distinction from CMS Plugin:
|
|
5
|
+
* - CMS uses developer-defined Zod schemas in code
|
|
6
|
+
* - Form Builder allows non-technical admins to build forms via drag-and-drop UI
|
|
7
|
+
* - Forms are serialized to/from JSON Schema for storage
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Form stored in the database
|
|
11
|
+
*/
|
|
12
|
+
type Form = {
|
|
13
|
+
id: string;
|
|
14
|
+
/** Display name for the form */
|
|
15
|
+
name: string;
|
|
16
|
+
/** URL-friendly slug - unique identifier for public access */
|
|
17
|
+
slug: string;
|
|
18
|
+
/** Optional description for admin UI */
|
|
19
|
+
description?: string;
|
|
20
|
+
/** JSON Schema stored as string (includes steps, fieldType, stepGroup, etc.) */
|
|
21
|
+
schema: string;
|
|
22
|
+
/** Optional custom success message after submission */
|
|
23
|
+
successMessage?: string;
|
|
24
|
+
/** Optional redirect URL after submission */
|
|
25
|
+
redirectUrl?: string;
|
|
26
|
+
/** Form status: active, inactive, archived */
|
|
27
|
+
status: "active" | "inactive" | "archived";
|
|
28
|
+
/** User who created the form */
|
|
29
|
+
createdBy?: string;
|
|
30
|
+
createdAt: Date;
|
|
31
|
+
updatedAt: Date;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Form submission stored in the database
|
|
35
|
+
*/
|
|
36
|
+
type FormSubmission = {
|
|
37
|
+
id: string;
|
|
38
|
+
/** Reference to the form */
|
|
39
|
+
formId: string;
|
|
40
|
+
/** Submitted data as JSON string */
|
|
41
|
+
data: string;
|
|
42
|
+
/** Submission timestamp */
|
|
43
|
+
submittedAt: Date;
|
|
44
|
+
/** Optional user ID if authenticated */
|
|
45
|
+
submittedBy?: string;
|
|
46
|
+
/** Client IP address for rate limiting and spam protection */
|
|
47
|
+
ipAddress?: string;
|
|
48
|
+
/** User agent for analytics */
|
|
49
|
+
userAgent?: string;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Serialized form for API responses (dates as strings)
|
|
53
|
+
*/
|
|
54
|
+
interface SerializedForm extends Omit<Form, "createdAt" | "updatedAt" | "status"> {
|
|
55
|
+
status: string;
|
|
56
|
+
createdAt: string;
|
|
57
|
+
updatedAt: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Serialized form submission for API responses (dates as strings)
|
|
61
|
+
*/
|
|
62
|
+
interface SerializedFormSubmission extends Omit<FormSubmission, "submittedAt"> {
|
|
63
|
+
submittedAt: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Serialized form submission with parsed data
|
|
67
|
+
*/
|
|
68
|
+
interface SerializedFormSubmissionWithData<TData = Record<string, unknown>> extends SerializedFormSubmission {
|
|
69
|
+
/** Parsed data object (JSON.parse of data field) */
|
|
70
|
+
parsedData: TData;
|
|
71
|
+
/** Joined form */
|
|
72
|
+
form?: SerializedForm;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Paginated list response for forms
|
|
76
|
+
*/
|
|
77
|
+
interface PaginatedForms {
|
|
78
|
+
items: SerializedForm[];
|
|
79
|
+
total: number;
|
|
80
|
+
limit: number;
|
|
81
|
+
offset: number;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Paginated list response for form submissions
|
|
85
|
+
*/
|
|
86
|
+
interface PaginatedFormSubmissions<TData = Record<string, unknown>> {
|
|
87
|
+
items: SerializedFormSubmissionWithData<TData>[];
|
|
88
|
+
total: number;
|
|
89
|
+
limit: number;
|
|
90
|
+
offset: number;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Context passed to all backend hooks
|
|
94
|
+
*/
|
|
95
|
+
interface FormBuilderHookContext {
|
|
96
|
+
/** User ID if authenticated */
|
|
97
|
+
userId?: string;
|
|
98
|
+
/** Request headers */
|
|
99
|
+
headers?: Headers;
|
|
100
|
+
/** Client IP address (for rate limiting) */
|
|
101
|
+
ipAddress?: string;
|
|
102
|
+
/** User agent string */
|
|
103
|
+
userAgent?: string;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Context for submission-specific hooks
|
|
107
|
+
*/
|
|
108
|
+
interface SubmissionHookContext extends FormBuilderHookContext {
|
|
109
|
+
/** Form slug being submitted */
|
|
110
|
+
formSlug: string;
|
|
111
|
+
/** Form ID */
|
|
112
|
+
formId: string;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Input data for creating a form
|
|
116
|
+
*/
|
|
117
|
+
interface FormInput {
|
|
118
|
+
name: string;
|
|
119
|
+
slug: string;
|
|
120
|
+
description?: string;
|
|
121
|
+
schema: string;
|
|
122
|
+
successMessage?: string;
|
|
123
|
+
redirectUrl?: string;
|
|
124
|
+
status?: "active" | "inactive" | "archived";
|
|
125
|
+
createdBy?: string;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Input data for updating a form
|
|
129
|
+
*/
|
|
130
|
+
interface FormUpdate {
|
|
131
|
+
name?: string;
|
|
132
|
+
slug?: string;
|
|
133
|
+
description?: string;
|
|
134
|
+
schema?: string;
|
|
135
|
+
successMessage?: string;
|
|
136
|
+
redirectUrl?: string;
|
|
137
|
+
status?: "active" | "inactive" | "archived";
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Backend hooks for Form Builder plugin
|
|
141
|
+
*
|
|
142
|
+
* All CRUD hooks receive ipAddress and headers for auth/rate limiting.
|
|
143
|
+
* Return false from onBefore* hooks to reject the operation (throws 403).
|
|
144
|
+
*/
|
|
145
|
+
interface FormBuilderBackendHooks {
|
|
146
|
+
/** Called before listing forms. Return false to deny access (403). */
|
|
147
|
+
onBeforeListForms?: (ctx: FormBuilderHookContext) => Promise<boolean> | boolean;
|
|
148
|
+
/** Called before creating a form. Return false to deny, or modified data. */
|
|
149
|
+
onBeforeFormCreated?: (data: FormInput, ctx: FormBuilderHookContext) => Promise<FormInput | false> | FormInput | false;
|
|
150
|
+
/** Called after a form is created */
|
|
151
|
+
onAfterFormCreated?: (form: SerializedForm, ctx: FormBuilderHookContext) => Promise<void> | void;
|
|
152
|
+
/** Called before getting a form by ID or slug. Return false to deny access. */
|
|
153
|
+
onBeforeGetForm?: (idOrSlug: string, ctx: FormBuilderHookContext) => Promise<boolean> | boolean;
|
|
154
|
+
/** Called before updating a form. Return false to deny, or modified data. */
|
|
155
|
+
onBeforeFormUpdated?: (id: string, data: FormUpdate, ctx: FormBuilderHookContext) => Promise<FormUpdate | false> | FormUpdate | false;
|
|
156
|
+
/** Called after a form is updated */
|
|
157
|
+
onAfterFormUpdated?: (form: SerializedForm, ctx: FormBuilderHookContext) => Promise<void> | void;
|
|
158
|
+
/** Called before deleting a form. Return false to deny. */
|
|
159
|
+
onBeforeFormDeleted?: (id: string, ctx: FormBuilderHookContext) => Promise<boolean> | boolean;
|
|
160
|
+
/** Called after a form is deleted */
|
|
161
|
+
onAfterFormDeleted?: (id: string, ctx: FormBuilderHookContext) => Promise<void> | void;
|
|
162
|
+
/**
|
|
163
|
+
* Called before processing a form submission.
|
|
164
|
+
* Use for: spam protection, rate limiting, data validation/enrichment.
|
|
165
|
+
*
|
|
166
|
+
* @returns false to reject submission (400), or modified data to continue
|
|
167
|
+
*/
|
|
168
|
+
onBeforeSubmission?: (formSlug: string, data: Record<string, unknown>, ctx: SubmissionHookContext) => Promise<Record<string, unknown> | false> | Record<string, unknown> | false;
|
|
169
|
+
/**
|
|
170
|
+
* Called after a submission is saved.
|
|
171
|
+
* Use for: sending emails, storing in CRM, triggering workflows.
|
|
172
|
+
*/
|
|
173
|
+
onAfterSubmission?: (submission: SerializedFormSubmission, form: SerializedForm, ctx: SubmissionHookContext) => Promise<void> | void;
|
|
174
|
+
/** Called when a submission fails */
|
|
175
|
+
onSubmissionError?: (error: Error, formSlug: string, data: Record<string, unknown>, ctx: SubmissionHookContext) => Promise<void> | void;
|
|
176
|
+
/** Called before listing submissions. Return false to deny access (403). */
|
|
177
|
+
onBeforeListSubmissions?: (formId: string, ctx: FormBuilderHookContext) => Promise<boolean> | boolean;
|
|
178
|
+
/** Called before getting a submission. Return false to deny access. */
|
|
179
|
+
onBeforeGetSubmission?: (submissionId: string, ctx: FormBuilderHookContext) => Promise<boolean> | boolean;
|
|
180
|
+
/** Called before deleting a submission. Return false to deny. */
|
|
181
|
+
onBeforeSubmissionDeleted?: (submissionId: string, ctx: FormBuilderHookContext) => Promise<boolean> | boolean;
|
|
182
|
+
/** Called after a submission is deleted */
|
|
183
|
+
onAfterSubmissionDeleted?: (submissionId: string, ctx: FormBuilderHookContext) => Promise<void> | void;
|
|
184
|
+
/** Called on any error */
|
|
185
|
+
onError?: (error: Error, operation: "list" | "get" | "create" | "update" | "delete" | "submit" | "listSubmissions" | "getSubmission" | "deleteSubmission", ctx: FormBuilderHookContext) => Promise<void> | void;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Configuration for the Form Builder backend plugin
|
|
189
|
+
*/
|
|
190
|
+
interface FormBuilderBackendConfig {
|
|
191
|
+
/** Optional hooks for customizing behavior */
|
|
192
|
+
hooks?: FormBuilderBackendHooks;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export type { FormBuilderBackendConfig as F, PaginatedForms as P, SerializedForm as S, SerializedFormSubmission as a, SerializedFormSubmissionWithData as b, PaginatedFormSubmissions as c };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@btst/stack",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "A composable, plugin-based library for building full-stack applications.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -206,6 +206,47 @@
|
|
|
206
206
|
}
|
|
207
207
|
},
|
|
208
208
|
"./plugins/cms/css": "./dist/plugins/cms/style.css",
|
|
209
|
+
"./plugins/form-builder/api": {
|
|
210
|
+
"import": {
|
|
211
|
+
"types": "./dist/plugins/form-builder/api/index.d.ts",
|
|
212
|
+
"default": "./dist/plugins/form-builder/api/index.mjs"
|
|
213
|
+
},
|
|
214
|
+
"require": {
|
|
215
|
+
"types": "./dist/plugins/form-builder/api/index.d.cts",
|
|
216
|
+
"default": "./dist/plugins/form-builder/api/index.cjs"
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
"./plugins/form-builder/client": {
|
|
220
|
+
"import": {
|
|
221
|
+
"types": "./dist/plugins/form-builder/client/index.d.ts",
|
|
222
|
+
"default": "./dist/plugins/form-builder/client/index.mjs"
|
|
223
|
+
},
|
|
224
|
+
"require": {
|
|
225
|
+
"types": "./dist/plugins/form-builder/client/index.d.cts",
|
|
226
|
+
"default": "./dist/plugins/form-builder/client/index.cjs"
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
"./plugins/form-builder/client/components": {
|
|
230
|
+
"import": {
|
|
231
|
+
"types": "./dist/plugins/form-builder/client/components/index.d.ts",
|
|
232
|
+
"default": "./dist/plugins/form-builder/client/components/index.mjs"
|
|
233
|
+
},
|
|
234
|
+
"require": {
|
|
235
|
+
"types": "./dist/plugins/form-builder/client/components/index.d.cts",
|
|
236
|
+
"default": "./dist/plugins/form-builder/client/components/index.cjs"
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
"./plugins/form-builder/client/hooks": {
|
|
240
|
+
"import": {
|
|
241
|
+
"types": "./dist/plugins/form-builder/client/hooks/index.d.ts",
|
|
242
|
+
"default": "./dist/plugins/form-builder/client/hooks/index.mjs"
|
|
243
|
+
},
|
|
244
|
+
"require": {
|
|
245
|
+
"types": "./dist/plugins/form-builder/client/hooks/index.d.cts",
|
|
246
|
+
"default": "./dist/plugins/form-builder/client/hooks/index.cjs"
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
"./plugins/form-builder/css": "./dist/plugins/form-builder/style.css",
|
|
209
250
|
"./dist/*": "./dist/*",
|
|
210
251
|
"./ui/css": "./dist/ui/components.css",
|
|
211
252
|
"./package.json": "./package.json"
|
|
@@ -259,6 +300,18 @@
|
|
|
259
300
|
],
|
|
260
301
|
"plugins/cms/client/hooks": [
|
|
261
302
|
"./dist/plugins/cms/client/hooks/index.d.ts"
|
|
303
|
+
],
|
|
304
|
+
"plugins/form-builder/api": [
|
|
305
|
+
"./dist/plugins/form-builder/api/index.d.ts"
|
|
306
|
+
],
|
|
307
|
+
"plugins/form-builder/client": [
|
|
308
|
+
"./dist/plugins/form-builder/client/index.d.ts"
|
|
309
|
+
],
|
|
310
|
+
"plugins/form-builder/client/components": [
|
|
311
|
+
"./dist/plugins/form-builder/client/components/index.d.ts"
|
|
312
|
+
],
|
|
313
|
+
"plugins/form-builder/client/hooks": [
|
|
314
|
+
"./dist/plugins/form-builder/client/hooks/index.d.ts"
|
|
262
315
|
]
|
|
263
316
|
}
|
|
264
317
|
},
|
|
@@ -2,6 +2,10 @@ import type { Adapter } from "@btst/db";
|
|
|
2
2
|
import { defineBackendPlugin } from "@btst/stack/plugins/api";
|
|
3
3
|
import { createEndpoint } from "@btst/stack/plugins/api";
|
|
4
4
|
import { z } from "zod";
|
|
5
|
+
import {
|
|
6
|
+
zodToFormSchema,
|
|
7
|
+
formSchemaToZod,
|
|
8
|
+
} from "@workspace/ui/lib/schema-converter";
|
|
5
9
|
import { cmsSchema as dbSchema } from "../db";
|
|
6
10
|
import type {
|
|
7
11
|
ContentType,
|
|
@@ -124,8 +128,9 @@ async function syncContentTypes(
|
|
|
124
128
|
config: CMSBackendConfig,
|
|
125
129
|
): Promise<void> {
|
|
126
130
|
for (const ct of config.contentTypes) {
|
|
127
|
-
// Convert Zod schema to JSON Schema
|
|
128
|
-
|
|
131
|
+
// Convert Zod schema to JSON Schema using zodToFormSchema
|
|
132
|
+
// This properly handles dates, date constraints, and steps metadata
|
|
133
|
+
const jsonSchema = JSON.stringify(zodToFormSchema(ct.schema));
|
|
129
134
|
|
|
130
135
|
const existing = await adapter.findOne<ContentType>({
|
|
131
136
|
model: "contentType",
|
|
@@ -184,11 +189,11 @@ async function syncContentTypes(
|
|
|
184
189
|
|
|
185
190
|
/**
|
|
186
191
|
* Get Zod schema for a content type from its JSON Schema
|
|
187
|
-
* Uses
|
|
192
|
+
* Uses formSchemaToZod to properly handle dates, date constraints, and steps metadata
|
|
188
193
|
*/
|
|
189
194
|
function getContentTypeZodSchema(contentType: ContentType): z.ZodTypeAny {
|
|
190
195
|
const jsonSchema = JSON.parse(contentType.jsonSchema);
|
|
191
|
-
return
|
|
196
|
+
return formSchemaToZod(jsonSchema);
|
|
192
197
|
}
|
|
193
198
|
|
|
194
199
|
/**
|
|
@@ -3,15 +3,13 @@
|
|
|
3
3
|
import { useState, useMemo, useEffect } from "react";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
import { toast } from "sonner";
|
|
6
|
-
import
|
|
6
|
+
import { SteppedAutoForm } from "@workspace/ui/components/auto-form/stepped-auto-form";
|
|
7
7
|
import type {
|
|
8
8
|
FieldConfig,
|
|
9
9
|
AutoFormInputComponentProps,
|
|
10
10
|
} from "@workspace/ui/components/auto-form/types";
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
fromJSONSchemaWithDates,
|
|
14
|
-
} from "@workspace/ui/components/auto-form/utils";
|
|
11
|
+
import { buildFieldConfigFromJsonSchema as buildFieldConfigBase } from "@workspace/ui/components/auto-form/utils";
|
|
12
|
+
import { formSchemaToZod } from "@workspace/ui/lib/schema-converter";
|
|
15
13
|
import { Input } from "@workspace/ui/components/input";
|
|
16
14
|
import { Label } from "@workspace/ui/components/label";
|
|
17
15
|
import { Badge } from "@workspace/ui/components/badge";
|
|
@@ -168,11 +166,11 @@ export function ContentForm({
|
|
|
168
166
|
}
|
|
169
167
|
}, [contentType.jsonSchema]);
|
|
170
168
|
|
|
171
|
-
// Convert JSON Schema to Zod schema using
|
|
169
|
+
// Convert JSON Schema to Zod schema using formSchemaToZod utility
|
|
172
170
|
// This properly handles date fields (format: "date-time") and min/max date constraints
|
|
173
171
|
const zodSchema = useMemo(() => {
|
|
174
172
|
try {
|
|
175
|
-
return
|
|
173
|
+
return formSchemaToZod(jsonSchema);
|
|
176
174
|
} catch {
|
|
177
175
|
return z.object({});
|
|
178
176
|
}
|
|
@@ -264,30 +262,30 @@ export function ContentForm({
|
|
|
264
262
|
</div>
|
|
265
263
|
|
|
266
264
|
{/* Dynamic form from Zod schema */}
|
|
267
|
-
|
|
265
|
+
{/* Uses SteppedAutoForm which automatically handles both single-step and multi-step content types */}
|
|
266
|
+
<SteppedAutoForm
|
|
268
267
|
formSchema={zodSchema as z.ZodObject<any, any>}
|
|
269
268
|
values={formData as any}
|
|
270
269
|
onValuesChange={handleValuesChange as any}
|
|
271
270
|
onSubmit={handleSubmit as any}
|
|
272
271
|
fieldConfig={fieldConfig as any}
|
|
272
|
+
isSubmitting={isSubmitting}
|
|
273
|
+
submitButtonText={
|
|
274
|
+
isSubmitting
|
|
275
|
+
? localization.CMS_STATUS_SAVING
|
|
276
|
+
: localization.CMS_BUTTON_SAVE
|
|
277
|
+
}
|
|
273
278
|
>
|
|
274
|
-
|
|
275
|
-
<
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
className="px-4 py-2 text-sm text-muted-foreground hover:text-foreground"
|
|
285
|
-
>
|
|
286
|
-
{localization.CMS_BUTTON_CANCEL}
|
|
287
|
-
</button>
|
|
288
|
-
)}
|
|
289
|
-
</div>
|
|
290
|
-
</AutoForm>
|
|
279
|
+
{onCancel && (
|
|
280
|
+
<button
|
|
281
|
+
type="button"
|
|
282
|
+
onClick={onCancel}
|
|
283
|
+
className="px-4 py-2 text-sm text-muted-foreground hover:text-foreground"
|
|
284
|
+
>
|
|
285
|
+
{localization.CMS_BUTTON_CANCEL}
|
|
286
|
+
</button>
|
|
287
|
+
)}
|
|
288
|
+
</SteppedAutoForm>
|
|
291
289
|
</div>
|
|
292
290
|
);
|
|
293
291
|
}
|
|
@@ -6,6 +6,17 @@ export type { CMSLocalization } from "./localization";
|
|
|
6
6
|
// Re-export AutoFormInputComponentProps for custom field components
|
|
7
7
|
export type { AutoFormInputComponentProps } from "@workspace/ui/components/auto-form/types";
|
|
8
8
|
|
|
9
|
+
// Re-export schema converter utilities
|
|
10
|
+
export {
|
|
11
|
+
zodToFormSchema,
|
|
12
|
+
formSchemaToZod,
|
|
13
|
+
hasSteps,
|
|
14
|
+
getSteps,
|
|
15
|
+
getStepGroupMap,
|
|
16
|
+
type FormStep,
|
|
17
|
+
type FormSchemaMetadata,
|
|
18
|
+
} from "@workspace/ui/lib/schema-converter";
|
|
19
|
+
|
|
9
20
|
// Export CMSFileUpload for consumers to use or extend
|
|
10
21
|
export {
|
|
11
22
|
CMSFileUpload,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { formBuilderBackendPlugin, type FormBuilderApiRouter } from "./plugin";
|