@btst/stack 2.11.8 → 2.12.1

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.
Files changed (80) hide show
  1. package/dist/packages/stack/src/plugins/cms/api/plugin.cjs +14 -11
  2. package/dist/packages/stack/src/plugins/cms/api/plugin.mjs +14 -11
  3. package/dist/packages/stack/src/plugins/cms/client/components/forms/relation-field.cjs +87 -15
  4. package/dist/packages/stack/src/plugins/cms/client/components/forms/relation-field.mjs +87 -15
  5. package/dist/packages/stack/src/plugins/cms/schemas.cjs +11 -6
  6. package/dist/packages/stack/src/plugins/cms/schemas.mjs +10 -6
  7. package/dist/packages/stack/src/plugins/comments/api/query-key-defs.cjs +2 -1
  8. package/dist/packages/stack/src/plugins/comments/api/query-key-defs.mjs +2 -1
  9. package/dist/packages/stack/src/plugins/comments/client/components/comment-thread.cjs +6 -2
  10. package/dist/packages/stack/src/plugins/comments/client/components/comment-thread.mjs +6 -2
  11. package/dist/packages/stack/src/plugins/comments/client/hooks/use-comments.cjs +5 -3
  12. package/dist/packages/stack/src/plugins/comments/client/hooks/use-comments.mjs +5 -3
  13. package/dist/packages/ui/src/components/auto-form/fields/array.cjs +181 -4
  14. package/dist/packages/ui/src/components/auto-form/fields/array.mjs +184 -7
  15. package/dist/packages/ui/src/components/auto-form/index.cjs +16 -1
  16. package/dist/packages/ui/src/components/auto-form/index.mjs +17 -2
  17. package/dist/plugins/cms/api/index.cjs +2 -0
  18. package/dist/plugins/cms/api/index.d.cts +3 -2
  19. package/dist/plugins/cms/api/index.d.mts +3 -2
  20. package/dist/plugins/cms/api/index.d.ts +3 -2
  21. package/dist/plugins/cms/api/index.mjs +1 -0
  22. package/dist/plugins/cms/client/hooks/index.d.cts +1 -1
  23. package/dist/plugins/cms/client/hooks/index.d.mts +1 -1
  24. package/dist/plugins/cms/client/hooks/index.d.ts +1 -1
  25. package/dist/plugins/cms/query-keys.d.cts +398 -7
  26. package/dist/plugins/cms/query-keys.d.mts +398 -7
  27. package/dist/plugins/cms/query-keys.d.ts +398 -7
  28. package/dist/plugins/comments/api/index.d.cts +4 -4
  29. package/dist/plugins/comments/api/index.d.mts +4 -4
  30. package/dist/plugins/comments/api/index.d.ts +4 -4
  31. package/dist/plugins/comments/client/components/index.d.cts +11 -0
  32. package/dist/plugins/comments/client/components/index.d.mts +11 -0
  33. package/dist/plugins/comments/client/components/index.d.ts +11 -0
  34. package/dist/plugins/comments/client/hooks/index.d.cts +17 -1
  35. package/dist/plugins/comments/client/hooks/index.d.mts +17 -1
  36. package/dist/plugins/comments/client/hooks/index.d.ts +17 -1
  37. package/dist/plugins/comments/client/index.d.cts +9 -0
  38. package/dist/plugins/comments/client/index.d.mts +9 -0
  39. package/dist/plugins/comments/client/index.d.ts +9 -0
  40. package/dist/plugins/comments/query-keys.cjs +1 -0
  41. package/dist/plugins/comments/query-keys.d.cts +3 -2
  42. package/dist/plugins/comments/query-keys.d.mts +3 -2
  43. package/dist/plugins/comments/query-keys.d.ts +3 -2
  44. package/dist/plugins/comments/query-keys.mjs +1 -0
  45. package/dist/plugins/kanban/api/index.d.cts +1 -1
  46. package/dist/plugins/kanban/api/index.d.mts +1 -1
  47. package/dist/plugins/kanban/api/index.d.ts +1 -1
  48. package/dist/plugins/kanban/query-keys.d.cts +1 -1
  49. package/dist/plugins/kanban/query-keys.d.mts +1 -1
  50. package/dist/plugins/kanban/query-keys.d.ts +1 -1
  51. package/dist/plugins/ui-builder/index.d.cts +1 -1
  52. package/dist/plugins/ui-builder/index.d.mts +1 -1
  53. package/dist/plugins/ui-builder/index.d.ts +1 -1
  54. package/dist/shared/{stack.CJE9sAjV.d.ts → stack.Bq3kiUaM.d.ts} +1 -1
  55. package/dist/shared/{stack.C-b3Sn8j.d.cts → stack.C7KNNiJm.d.cts} +3 -1
  56. package/dist/shared/{stack.C-b3Sn8j.d.mts → stack.C7KNNiJm.d.mts} +3 -1
  57. package/dist/shared/{stack.C-b3Sn8j.d.ts → stack.C7KNNiJm.d.ts} +3 -1
  58. package/dist/shared/{stack.Dcz6636A.d.mts → stack.CCncwK6g.d.cts} +1 -1
  59. package/dist/shared/{stack.CmHRdhl8.d.cts → stack.CO1g47IS.d.mts} +1 -1
  60. package/dist/shared/{stack.B8QD11QU.d.cts → stack.DFtpFS00.d.cts} +10 -0
  61. package/dist/shared/{stack.B8QD11QU.d.mts → stack.DFtpFS00.d.mts} +10 -0
  62. package/dist/shared/{stack.B8QD11QU.d.ts → stack.DFtpFS00.d.ts} +10 -0
  63. package/package.json +1 -1
  64. package/src/plugins/cms/__tests__/schema-roundtrip.test.ts +203 -0
  65. package/src/plugins/cms/api/index.ts +1 -0
  66. package/src/plugins/cms/api/plugin.ts +33 -16
  67. package/src/plugins/cms/client/components/forms/relation-field.tsx +121 -36
  68. package/src/plugins/cms/schemas.ts +26 -6
  69. package/src/plugins/cms/types.ts +10 -0
  70. package/src/plugins/comments/api/query-key-defs.ts +5 -1
  71. package/src/plugins/comments/client/components/comment-thread.tsx +15 -0
  72. package/src/plugins/comments/client/hooks/use-comments.tsx +26 -3
  73. package/src/plugins/comments/client/overrides.ts +10 -0
  74. package/src/plugins/comments/query-keys.ts +2 -0
  75. package/dist/shared/stack.DbnCLdNF.d.mts +0 -399
  76. package/dist/shared/stack.fXlShnhv.d.ts +0 -399
  77. package/dist/shared/stack.r6HohbyX.d.cts +0 -399
  78. package/dist/shared/{stack.B6S3cgwN.d.cts → stack.CuI_-z-_.d.cts} +16 -16
  79. package/dist/shared/{stack.Bzfx-_lq.d.mts → stack.D2RVkQD8.d.mts} +16 -16
  80. package/dist/shared/{stack.j5SFLC1d.d.ts → stack.DXrOtuek.d.ts} +16 -16
@@ -3,6 +3,8 @@
3
3
  const jsxRuntime = require('react/jsx-runtime');
4
4
  const accordion = require('../../accordion.cjs');
5
5
  const button = require('../../button.cjs');
6
+ const form = require('../../form.cjs');
7
+ const input = require('../../input.cjs');
6
8
  const separator = require('../../separator.cjs');
7
9
  const LucideIcons = require('lucide-react');
8
10
  const reactHookForm = require('react-hook-form');
@@ -26,20 +28,70 @@ function getArrayElementType(item) {
26
28
  }
27
29
  return null;
28
30
  }
31
+ function getPrimitiveDefault(itemSchema) {
32
+ const base = helpers.getBaseSchema(itemSchema);
33
+ if (!base) return "";
34
+ switch (helpers.getBaseType(base)) {
35
+ case "ZodBoolean":
36
+ return false;
37
+ case "ZodNumber":
38
+ return 0;
39
+ default:
40
+ return "";
41
+ }
42
+ }
29
43
  function AutoFormArray({
30
44
  name,
31
45
  item,
32
46
  form,
33
47
  path = [],
34
48
  fieldConfig
49
+ }) {
50
+ const itemDefType = getArrayElementType(item);
51
+ const elementBaseSchema = itemDefType ? helpers.getBaseSchema(itemDefType) : null;
52
+ const elementPrimitiveType = elementBaseSchema ? helpers.getBaseType(elementBaseSchema) : "";
53
+ const isObjectArray = !!itemDefType && elementPrimitiveType === "ZodObject";
54
+ const title = fieldConfig?.label ?? helpers.beautifyObjectName(name);
55
+ if (isObjectArray) {
56
+ return /* @__PURE__ */ jsxRuntime.jsx(
57
+ ObjectAutoFormArray,
58
+ {
59
+ name,
60
+ item,
61
+ form,
62
+ path,
63
+ fieldConfig,
64
+ itemDefType,
65
+ title
66
+ }
67
+ );
68
+ }
69
+ return /* @__PURE__ */ jsxRuntime.jsx(
70
+ PrimitiveAutoFormArray,
71
+ {
72
+ name,
73
+ item,
74
+ form,
75
+ path,
76
+ fieldConfig,
77
+ itemDefType,
78
+ title
79
+ }
80
+ );
81
+ }
82
+ function ObjectAutoFormArray({
83
+ name,
84
+ form,
85
+ path = [],
86
+ fieldConfig,
87
+ itemDefType,
88
+ title
35
89
  }) {
36
90
  const fieldPath = path.join(".");
37
91
  const { fields, append, remove } = reactHookForm.useFieldArray({
38
92
  control: form.control,
39
93
  name: fieldPath
40
94
  });
41
- const title = fieldConfig?.label ?? helpers.beautifyObjectName(name);
42
- const itemDefType = getArrayElementType(item);
43
95
  return /* @__PURE__ */ jsxRuntime.jsxs(accordion.AccordionItem, { value: name, className: "border-none", children: [
44
96
  /* @__PURE__ */ jsxRuntime.jsx(accordion.AccordionTrigger, { children: title }),
45
97
  /* @__PURE__ */ jsxRuntime.jsxs(accordion.AccordionContent, { children: [
@@ -63,11 +115,11 @@ function AutoFormArray({
63
115
  type: "button",
64
116
  className: "hover:bg-zinc-300 hover:text-black focus:ring-0 focus:ring-offset-0 focus-visible:ring-0 focus-visible:ring-offset-0 dark:bg-white dark:text-black dark:hover:bg-zinc-300 dark:hover:text-black dark:hover:ring-0 dark:hover:ring-offset-0 dark:focus-visible:ring-0 dark:focus-visible:ring-offset-0",
65
117
  onClick: () => remove(index),
66
- children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Trash, { className: "size-4 " })
118
+ children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Trash, { className: "size-4" })
67
119
  }
68
120
  ) }),
69
121
  /* @__PURE__ */ jsxRuntime.jsx(separator.Separator, {})
70
- ] }, `${key}`);
122
+ ] }, key);
71
123
  }),
72
124
  /* @__PURE__ */ jsxRuntime.jsxs(
73
125
  button.Button,
@@ -85,5 +137,130 @@ function AutoFormArray({
85
137
  ] })
86
138
  ] });
87
139
  }
140
+ function PrimitiveAutoFormArray({
141
+ name,
142
+ item,
143
+ form,
144
+ path = [],
145
+ fieldConfig,
146
+ itemDefType,
147
+ title
148
+ }) {
149
+ const fieldPath = path.join(".");
150
+ const rawValues = reactHookForm.useWatch({ control: form.control, name: fieldPath }) ?? [];
151
+ const values = Array.isArray(rawValues) ? rawValues : [];
152
+ const appendItem = () => {
153
+ const def = itemDefType ? getPrimitiveDefault(itemDefType) : "";
154
+ form.setValue(fieldPath, [...values, def], {
155
+ shouldDirty: true,
156
+ shouldValidate: false
157
+ });
158
+ };
159
+ const removeItem = (index) => {
160
+ const next = values.filter((_, i) => i !== index);
161
+ form.setValue(fieldPath, next, {
162
+ shouldDirty: true,
163
+ shouldValidate: false
164
+ });
165
+ };
166
+ return /* @__PURE__ */ jsxRuntime.jsxs(accordion.AccordionItem, { value: name, className: "border-none", children: [
167
+ /* @__PURE__ */ jsxRuntime.jsx(accordion.AccordionTrigger, { children: title }),
168
+ /* @__PURE__ */ jsxRuntime.jsxs(accordion.AccordionContent, { children: [
169
+ values.map((_, index) => {
170
+ const cellPath = `${fieldPath}.${index}`;
171
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 flex flex-col", children: [
172
+ itemDefType ? /* @__PURE__ */ jsxRuntime.jsx(
173
+ PrimitiveArrayRow,
174
+ {
175
+ form,
176
+ itemSchema: itemDefType,
177
+ cellPath
178
+ }
179
+ ) : null,
180
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "my-4 flex justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(
181
+ button.Button,
182
+ {
183
+ variant: "secondary",
184
+ size: "icon",
185
+ type: "button",
186
+ className: "hover:bg-zinc-300 hover:text-black focus:ring-0 focus:ring-offset-0 focus-visible:ring-0 focus-visible:ring-offset-0 dark:bg-white dark:text-black dark:hover:bg-zinc-300 dark:hover:text-black dark:hover:ring-0 dark:hover:ring-offset-0 dark:focus-visible:ring-0 dark:focus-visible:ring-offset-0",
187
+ onClick: () => removeItem(index),
188
+ children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Trash, { className: "size-4" })
189
+ }
190
+ ) }),
191
+ /* @__PURE__ */ jsxRuntime.jsx(separator.Separator, {})
192
+ ] }, `${fieldPath}-${index}`);
193
+ }),
194
+ /* @__PURE__ */ jsxRuntime.jsxs(
195
+ button.Button,
196
+ {
197
+ type: "button",
198
+ variant: "secondary",
199
+ onClick: appendItem,
200
+ className: "mt-4 flex items-center",
201
+ children: [
202
+ /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Plus, { className: "mr-2", size: 16 }),
203
+ "Add"
204
+ ]
205
+ }
206
+ )
207
+ ] })
208
+ ] });
209
+ }
210
+ function PrimitiveArrayRow({
211
+ form: form$1,
212
+ itemSchema,
213
+ cellPath
214
+ }) {
215
+ const baseSchema = helpers.getBaseSchema(itemSchema);
216
+ const t = baseSchema ? helpers.getBaseType(baseSchema) : "";
217
+ if (t === "ZodBoolean") {
218
+ return /* @__PURE__ */ jsxRuntime.jsx(
219
+ form.FormField,
220
+ {
221
+ control: form$1.control,
222
+ name: cellPath,
223
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(form.FormItem, { className: "flex flex-row items-center gap-2 space-y-0", children: [
224
+ /* @__PURE__ */ jsxRuntime.jsx(form.FormControl, { children: /* @__PURE__ */ jsxRuntime.jsx(
225
+ "input",
226
+ {
227
+ type: "checkbox",
228
+ "aria-label": "Toggle",
229
+ checked: Boolean(field.value),
230
+ onChange: (e) => field.onChange(e.target.checked)
231
+ }
232
+ ) }),
233
+ /* @__PURE__ */ jsxRuntime.jsx(form.FormLabel, { className: "font-normal cursor-pointer", children: field.value ? "Selected" : "Not selected" }),
234
+ /* @__PURE__ */ jsxRuntime.jsx(form.FormMessage, {})
235
+ ] })
236
+ }
237
+ );
238
+ }
239
+ const inputType = t === "ZodNumber" ? "number" : "text";
240
+ return /* @__PURE__ */ jsxRuntime.jsx(
241
+ form.FormField,
242
+ {
243
+ control: form$1.control,
244
+ name: cellPath,
245
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(form.FormItem, { className: "space-y-2", children: [
246
+ /* @__PURE__ */ jsxRuntime.jsx(form.FormLabel, { className: "sr-only", children: "Row value" }),
247
+ /* @__PURE__ */ jsxRuntime.jsx(form.FormControl, { children: /* @__PURE__ */ jsxRuntime.jsx(
248
+ input.Input,
249
+ {
250
+ type: inputType,
251
+ name: field.name,
252
+ ref: field.ref,
253
+ onBlur: field.onBlur,
254
+ value: field.value === void 0 || field.value === null ? "" : String(field.value),
255
+ onChange: (ev) => field.onChange(
256
+ inputType === "number" ? Number.isNaN(ev.target.valueAsNumber) ? void 0 : ev.target.valueAsNumber : ev.target.value
257
+ )
258
+ }
259
+ ) }),
260
+ /* @__PURE__ */ jsxRuntime.jsx(form.FormMessage, {})
261
+ ] })
262
+ }
263
+ );
264
+ }
88
265
 
89
266
  module.exports = AutoFormArray;
@@ -1,10 +1,12 @@
1
- import { jsxs, jsx } from 'react/jsx-runtime';
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import { AccordionItem, AccordionTrigger, AccordionContent } from '../../accordion.mjs';
3
3
  import { Button } from '../../button.mjs';
4
+ import { FormField, FormItem, FormControl, FormLabel, FormMessage } from '../../form.mjs';
5
+ import { Input } from '../../input.mjs';
4
6
  import { Separator } from '../../separator.mjs';
5
7
  import { Trash, Plus } from 'lucide-react';
6
- import { useFieldArray } from 'react-hook-form';
7
- import { beautifyObjectName } from '../helpers.mjs';
8
+ import { useFieldArray, useWatch } from 'react-hook-form';
9
+ import { getBaseSchema, getBaseType, beautifyObjectName } from '../helpers.mjs';
8
10
  import AutoFormObject from './object.mjs';
9
11
 
10
12
  function getDefType(schema) {
@@ -24,20 +26,70 @@ function getArrayElementType(item) {
24
26
  }
25
27
  return null;
26
28
  }
29
+ function getPrimitiveDefault(itemSchema) {
30
+ const base = getBaseSchema(itemSchema);
31
+ if (!base) return "";
32
+ switch (getBaseType(base)) {
33
+ case "ZodBoolean":
34
+ return false;
35
+ case "ZodNumber":
36
+ return 0;
37
+ default:
38
+ return "";
39
+ }
40
+ }
27
41
  function AutoFormArray({
28
42
  name,
29
43
  item,
30
44
  form,
31
45
  path = [],
32
46
  fieldConfig
47
+ }) {
48
+ const itemDefType = getArrayElementType(item);
49
+ const elementBaseSchema = itemDefType ? getBaseSchema(itemDefType) : null;
50
+ const elementPrimitiveType = elementBaseSchema ? getBaseType(elementBaseSchema) : "";
51
+ const isObjectArray = !!itemDefType && elementPrimitiveType === "ZodObject";
52
+ const title = fieldConfig?.label ?? beautifyObjectName(name);
53
+ if (isObjectArray) {
54
+ return /* @__PURE__ */ jsx(
55
+ ObjectAutoFormArray,
56
+ {
57
+ name,
58
+ item,
59
+ form,
60
+ path,
61
+ fieldConfig,
62
+ itemDefType,
63
+ title
64
+ }
65
+ );
66
+ }
67
+ return /* @__PURE__ */ jsx(
68
+ PrimitiveAutoFormArray,
69
+ {
70
+ name,
71
+ item,
72
+ form,
73
+ path,
74
+ fieldConfig,
75
+ itemDefType,
76
+ title
77
+ }
78
+ );
79
+ }
80
+ function ObjectAutoFormArray({
81
+ name,
82
+ form,
83
+ path = [],
84
+ fieldConfig,
85
+ itemDefType,
86
+ title
33
87
  }) {
34
88
  const fieldPath = path.join(".");
35
89
  const { fields, append, remove } = useFieldArray({
36
90
  control: form.control,
37
91
  name: fieldPath
38
92
  });
39
- const title = fieldConfig?.label ?? beautifyObjectName(name);
40
- const itemDefType = getArrayElementType(item);
41
93
  return /* @__PURE__ */ jsxs(AccordionItem, { value: name, className: "border-none", children: [
42
94
  /* @__PURE__ */ jsx(AccordionTrigger, { children: title }),
43
95
  /* @__PURE__ */ jsxs(AccordionContent, { children: [
@@ -61,11 +113,11 @@ function AutoFormArray({
61
113
  type: "button",
62
114
  className: "hover:bg-zinc-300 hover:text-black focus:ring-0 focus:ring-offset-0 focus-visible:ring-0 focus-visible:ring-offset-0 dark:bg-white dark:text-black dark:hover:bg-zinc-300 dark:hover:text-black dark:hover:ring-0 dark:hover:ring-offset-0 dark:focus-visible:ring-0 dark:focus-visible:ring-offset-0",
63
115
  onClick: () => remove(index),
64
- children: /* @__PURE__ */ jsx(Trash, { className: "size-4 " })
116
+ children: /* @__PURE__ */ jsx(Trash, { className: "size-4" })
65
117
  }
66
118
  ) }),
67
119
  /* @__PURE__ */ jsx(Separator, {})
68
- ] }, `${key}`);
120
+ ] }, key);
69
121
  }),
70
122
  /* @__PURE__ */ jsxs(
71
123
  Button,
@@ -83,5 +135,130 @@ function AutoFormArray({
83
135
  ] })
84
136
  ] });
85
137
  }
138
+ function PrimitiveAutoFormArray({
139
+ name,
140
+ item,
141
+ form,
142
+ path = [],
143
+ fieldConfig,
144
+ itemDefType,
145
+ title
146
+ }) {
147
+ const fieldPath = path.join(".");
148
+ const rawValues = useWatch({ control: form.control, name: fieldPath }) ?? [];
149
+ const values = Array.isArray(rawValues) ? rawValues : [];
150
+ const appendItem = () => {
151
+ const def = itemDefType ? getPrimitiveDefault(itemDefType) : "";
152
+ form.setValue(fieldPath, [...values, def], {
153
+ shouldDirty: true,
154
+ shouldValidate: false
155
+ });
156
+ };
157
+ const removeItem = (index) => {
158
+ const next = values.filter((_, i) => i !== index);
159
+ form.setValue(fieldPath, next, {
160
+ shouldDirty: true,
161
+ shouldValidate: false
162
+ });
163
+ };
164
+ return /* @__PURE__ */ jsxs(AccordionItem, { value: name, className: "border-none", children: [
165
+ /* @__PURE__ */ jsx(AccordionTrigger, { children: title }),
166
+ /* @__PURE__ */ jsxs(AccordionContent, { children: [
167
+ values.map((_, index) => {
168
+ const cellPath = `${fieldPath}.${index}`;
169
+ return /* @__PURE__ */ jsxs("div", { className: "mt-4 flex flex-col", children: [
170
+ itemDefType ? /* @__PURE__ */ jsx(
171
+ PrimitiveArrayRow,
172
+ {
173
+ form,
174
+ itemSchema: itemDefType,
175
+ cellPath
176
+ }
177
+ ) : null,
178
+ /* @__PURE__ */ jsx("div", { className: "my-4 flex justify-end", children: /* @__PURE__ */ jsx(
179
+ Button,
180
+ {
181
+ variant: "secondary",
182
+ size: "icon",
183
+ type: "button",
184
+ className: "hover:bg-zinc-300 hover:text-black focus:ring-0 focus:ring-offset-0 focus-visible:ring-0 focus-visible:ring-offset-0 dark:bg-white dark:text-black dark:hover:bg-zinc-300 dark:hover:text-black dark:hover:ring-0 dark:hover:ring-offset-0 dark:focus-visible:ring-0 dark:focus-visible:ring-offset-0",
185
+ onClick: () => removeItem(index),
186
+ children: /* @__PURE__ */ jsx(Trash, { className: "size-4" })
187
+ }
188
+ ) }),
189
+ /* @__PURE__ */ jsx(Separator, {})
190
+ ] }, `${fieldPath}-${index}`);
191
+ }),
192
+ /* @__PURE__ */ jsxs(
193
+ Button,
194
+ {
195
+ type: "button",
196
+ variant: "secondary",
197
+ onClick: appendItem,
198
+ className: "mt-4 flex items-center",
199
+ children: [
200
+ /* @__PURE__ */ jsx(Plus, { className: "mr-2", size: 16 }),
201
+ "Add"
202
+ ]
203
+ }
204
+ )
205
+ ] })
206
+ ] });
207
+ }
208
+ function PrimitiveArrayRow({
209
+ form,
210
+ itemSchema,
211
+ cellPath
212
+ }) {
213
+ const baseSchema = getBaseSchema(itemSchema);
214
+ const t = baseSchema ? getBaseType(baseSchema) : "";
215
+ if (t === "ZodBoolean") {
216
+ return /* @__PURE__ */ jsx(
217
+ FormField,
218
+ {
219
+ control: form.control,
220
+ name: cellPath,
221
+ render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, { className: "flex flex-row items-center gap-2 space-y-0", children: [
222
+ /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
223
+ "input",
224
+ {
225
+ type: "checkbox",
226
+ "aria-label": "Toggle",
227
+ checked: Boolean(field.value),
228
+ onChange: (e) => field.onChange(e.target.checked)
229
+ }
230
+ ) }),
231
+ /* @__PURE__ */ jsx(FormLabel, { className: "font-normal cursor-pointer", children: field.value ? "Selected" : "Not selected" }),
232
+ /* @__PURE__ */ jsx(FormMessage, {})
233
+ ] })
234
+ }
235
+ );
236
+ }
237
+ const inputType = t === "ZodNumber" ? "number" : "text";
238
+ return /* @__PURE__ */ jsx(
239
+ FormField,
240
+ {
241
+ control: form.control,
242
+ name: cellPath,
243
+ render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, { className: "space-y-2", children: [
244
+ /* @__PURE__ */ jsx(FormLabel, { className: "sr-only", children: "Row value" }),
245
+ /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
246
+ Input,
247
+ {
248
+ type: inputType,
249
+ name: field.name,
250
+ ref: field.ref,
251
+ onBlur: field.onBlur,
252
+ value: field.value === void 0 || field.value === null ? "" : String(field.value),
253
+ onChange: (ev) => field.onChange(
254
+ inputType === "number" ? Number.isNaN(ev.target.valueAsNumber) ? void 0 : ev.target.valueAsNumber : ev.target.value
255
+ )
256
+ }
257
+ ) }),
258
+ /* @__PURE__ */ jsx(FormMessage, {})
259
+ ] })
260
+ }
261
+ );
262
+ }
86
263
 
87
264
  export { AutoFormArray as default };
@@ -43,10 +43,17 @@ function AutoForm({
43
43
  defaultValues: defaultValues ?? void 0,
44
44
  values: valuesProp
45
45
  });
46
+ const [schemaSubmitError, setSchemaSubmitError] = React.useState(null);
46
47
  function onSubmit(values) {
48
+ setSchemaSubmitError(null);
47
49
  const parsedValues = formSchema.safeParse(values);
48
50
  if (parsedValues.success) {
49
51
  onSubmitProp?.(parsedValues.data, form$1);
52
+ } else {
53
+ const message = parsedValues.error.issues.map(
54
+ (issue) => `${issue.path.length ? `${issue.path.join(".")}: ` : ""}${issue.message}`
55
+ ).join(" \xB7 ");
56
+ setSchemaSubmitError(message);
50
57
  }
51
58
  }
52
59
  React__default.useEffect(() => {
@@ -64,7 +71,7 @@ function AutoForm({
64
71
  "form",
65
72
  {
66
73
  onSubmit: (e) => {
67
- form$1.handleSubmit(onSubmit)(e);
74
+ form$1.handleSubmit(onSubmit, () => setSchemaSubmitError(null))(e);
68
75
  },
69
76
  className: utils.cn("space-y-5", className),
70
77
  children: [
@@ -77,6 +84,14 @@ function AutoForm({
77
84
  fieldConfig
78
85
  }
79
86
  ),
87
+ schemaSubmitError ? /* @__PURE__ */ jsxRuntime.jsx(
88
+ "div",
89
+ {
90
+ role: "alert",
91
+ className: "rounded-md border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive",
92
+ children: schemaSubmitError
93
+ }
94
+ ) : null,
80
95
  renderChildren
81
96
  ]
82
97
  }
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from 'react/jsx-runtime';
3
3
  import { Form } from '../form.mjs';
4
- import React__default from 'react';
4
+ import React__default, { useState } from 'react';
5
5
  import { useForm } from 'react-hook-form';
6
6
  import { Button } from '../button.mjs';
7
7
  import { cn } from '../../lib/utils.mjs';
@@ -35,10 +35,17 @@ function AutoForm({
35
35
  defaultValues: defaultValues ?? void 0,
36
36
  values: valuesProp
37
37
  });
38
+ const [schemaSubmitError, setSchemaSubmitError] = useState(null);
38
39
  function onSubmit(values) {
40
+ setSchemaSubmitError(null);
39
41
  const parsedValues = formSchema.safeParse(values);
40
42
  if (parsedValues.success) {
41
43
  onSubmitProp?.(parsedValues.data, form);
44
+ } else {
45
+ const message = parsedValues.error.issues.map(
46
+ (issue) => `${issue.path.length ? `${issue.path.join(".")}: ` : ""}${issue.message}`
47
+ ).join(" \xB7 ");
48
+ setSchemaSubmitError(message);
42
49
  }
43
50
  }
44
51
  React__default.useEffect(() => {
@@ -56,7 +63,7 @@ function AutoForm({
56
63
  "form",
57
64
  {
58
65
  onSubmit: (e) => {
59
- form.handleSubmit(onSubmit)(e);
66
+ form.handleSubmit(onSubmit, () => setSchemaSubmitError(null))(e);
60
67
  },
61
68
  className: cn("space-y-5", className),
62
69
  children: [
@@ -69,6 +76,14 @@ function AutoForm({
69
76
  fieldConfig
70
77
  }
71
78
  ),
79
+ schemaSubmitError ? /* @__PURE__ */ jsx(
80
+ "div",
81
+ {
82
+ role: "alert",
83
+ className: "rounded-md border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive",
84
+ children: schemaSubmitError
85
+ }
86
+ ) : null,
72
87
  renderChildren
73
88
  ]
74
89
  }
@@ -4,6 +4,7 @@ const plugin = require('../../../packages/stack/src/plugins/cms/api/plugin.cjs')
4
4
  const getters = require('../../../packages/stack/src/plugins/cms/api/getters.cjs');
5
5
  const mutations = require('../../../packages/stack/src/plugins/cms/api/mutations.cjs');
6
6
  const queryKeyDefs = require('../../../packages/stack/src/plugins/cms/api/query-key-defs.cjs');
7
+ const plugins_cms_queryKeys = require('../query-keys.cjs');
7
8
 
8
9
 
9
10
 
@@ -17,3 +18,4 @@ exports.serializeContentItemWithType = getters.serializeContentItemWithType;
17
18
  exports.serializeContentType = getters.serializeContentType;
18
19
  exports.createCMSContentItem = mutations.createCMSContentItem;
19
20
  exports.CMS_QUERY_KEYS = queryKeyDefs.CMS_QUERY_KEYS;
21
+ exports.createCMSQueryKeys = plugins_cms_queryKeys.createCMSQueryKeys;
@@ -1,7 +1,8 @@
1
- export { C as CMSApiRouter, b as CMSRouteKey, m as CMS_QUERY_KEYS, k as CreateCMSContentItemInput, l as CreateCMSContentItemOptions, c as cmsBackendPlugin, j as createCMSContentItem, d as getAllContentItems, g as getAllContentTypes, f as getContentItemById, e as getContentItemBySlug, h as serializeContentItem, i as serializeContentItemWithType, s as serializeContentType } from '../../../shared/stack.r6HohbyX.cjs';
1
+ export { C as CMSApiRouter, a as CMSRouteKey, l as CMS_QUERY_KEYS, j as CreateCMSContentItemInput, k as CreateCMSContentItemOptions, c as cmsBackendPlugin, i as createCMSContentItem, createCMSQueryKeys, b as getAllContentItems, g as getAllContentTypes, e as getContentItemById, d as getContentItemBySlug, f as serializeContentItem, h as serializeContentItemWithType, s as serializeContentType } from '../query-keys.cjs';
2
2
  import '@btst/stack/plugins/api';
3
- import '../../../shared/stack.B8QD11QU.cjs';
3
+ import '../../../shared/stack.DFtpFS00.cjs';
4
4
  import 'zod';
5
5
  import 'better-call';
6
6
  import '@btst/db';
7
7
  import '@tanstack/react-query';
8
+ import '@btst/stack/plugins/client';
@@ -1,7 +1,8 @@
1
- export { C as CMSApiRouter, b as CMSRouteKey, m as CMS_QUERY_KEYS, k as CreateCMSContentItemInput, l as CreateCMSContentItemOptions, c as cmsBackendPlugin, j as createCMSContentItem, d as getAllContentItems, g as getAllContentTypes, f as getContentItemById, e as getContentItemBySlug, h as serializeContentItem, i as serializeContentItemWithType, s as serializeContentType } from '../../../shared/stack.DbnCLdNF.mjs';
1
+ export { C as CMSApiRouter, a as CMSRouteKey, l as CMS_QUERY_KEYS, j as CreateCMSContentItemInput, k as CreateCMSContentItemOptions, c as cmsBackendPlugin, i as createCMSContentItem, createCMSQueryKeys, b as getAllContentItems, g as getAllContentTypes, e as getContentItemById, d as getContentItemBySlug, f as serializeContentItem, h as serializeContentItemWithType, s as serializeContentType } from '../query-keys.mjs';
2
2
  import '@btst/stack/plugins/api';
3
- import '../../../shared/stack.B8QD11QU.mjs';
3
+ import '../../../shared/stack.DFtpFS00.mjs';
4
4
  import 'zod';
5
5
  import 'better-call';
6
6
  import '@btst/db';
7
7
  import '@tanstack/react-query';
8
+ import '@btst/stack/plugins/client';
@@ -1,7 +1,8 @@
1
- export { C as CMSApiRouter, b as CMSRouteKey, m as CMS_QUERY_KEYS, k as CreateCMSContentItemInput, l as CreateCMSContentItemOptions, c as cmsBackendPlugin, j as createCMSContentItem, d as getAllContentItems, g as getAllContentTypes, f as getContentItemById, e as getContentItemBySlug, h as serializeContentItem, i as serializeContentItemWithType, s as serializeContentType } from '../../../shared/stack.fXlShnhv.js';
1
+ export { C as CMSApiRouter, a as CMSRouteKey, l as CMS_QUERY_KEYS, j as CreateCMSContentItemInput, k as CreateCMSContentItemOptions, c as cmsBackendPlugin, i as createCMSContentItem, createCMSQueryKeys, b as getAllContentItems, g as getAllContentTypes, e as getContentItemById, d as getContentItemBySlug, f as serializeContentItem, h as serializeContentItemWithType, s as serializeContentType } from '../query-keys.js';
2
2
  import '@btst/stack/plugins/api';
3
- import '../../../shared/stack.B8QD11QU.js';
3
+ import '../../../shared/stack.DFtpFS00.js';
4
4
  import 'zod';
5
5
  import 'better-call';
6
6
  import '@btst/db';
7
7
  import '@tanstack/react-query';
8
+ import '@btst/stack/plugins/client';
@@ -2,3 +2,4 @@ export { cmsBackendPlugin } from '../../../packages/stack/src/plugins/cms/api/pl
2
2
  export { getAllContentItems, getAllContentTypes, getContentItemById, getContentItemBySlug, serializeContentItem, serializeContentItemWithType, serializeContentType } from '../../../packages/stack/src/plugins/cms/api/getters.mjs';
3
3
  export { createCMSContentItem } from '../../../packages/stack/src/plugins/cms/api/mutations.mjs';
4
4
  export { CMS_QUERY_KEYS } from '../../../packages/stack/src/plugins/cms/api/query-key-defs.mjs';
5
+ export { createCMSQueryKeys } from '../query-keys.mjs';
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { S as SerializedContentType, a as SerializedContentItemWithType } from '../../../../shared/stack.B8QD11QU.cjs';
2
+ import { S as SerializedContentType, a as SerializedContentItemWithType } from '../../../../shared/stack.DFtpFS00.cjs';
3
3
  import 'zod';
4
4
 
5
5
  interface UseContentTypesResult {
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { S as SerializedContentType, a as SerializedContentItemWithType } from '../../../../shared/stack.B8QD11QU.mjs';
2
+ import { S as SerializedContentType, a as SerializedContentItemWithType } from '../../../../shared/stack.DFtpFS00.mjs';
3
3
  import 'zod';
4
4
 
5
5
  interface UseContentTypesResult {
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { S as SerializedContentType, a as SerializedContentItemWithType } from '../../../../shared/stack.B8QD11QU.js';
2
+ import { S as SerializedContentType, a as SerializedContentItemWithType } from '../../../../shared/stack.DFtpFS00.js';
3
3
  import 'zod';
4
4
 
5
5
  interface UseContentTypesResult {