@evanschleret/formforgeclient 1.2.4 → 2.0.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.
Files changed (83) hide show
  1. package/README.md +10 -0
  2. package/dist/module.cjs +1 -0
  3. package/dist/module.d.cts +1 -0
  4. package/dist/module.d.mts +1 -0
  5. package/dist/module.d.ts +1 -0
  6. package/dist/module.json +1 -1
  7. package/dist/module.mjs +1 -0
  8. package/dist/runtime/api/client.js +4 -2
  9. package/dist/runtime/api/request.d.ts +1 -0
  10. package/dist/runtime/api/schema.js +4 -4
  11. package/dist/runtime/assets/formforge.css +1 -0
  12. package/dist/runtime/composables/index.d.ts +1 -1
  13. package/dist/runtime/composables/useFormForgeBuilder.d.ts +24 -2
  14. package/dist/runtime/composables/useFormForgeBuilder.js +299 -43
  15. package/dist/runtime/composables/useFormForgeForm.js +15 -5
  16. package/dist/runtime/composables/useFormForgeI18n.d.ts +245 -19
  17. package/dist/runtime/composables/useFormForgeI18n.js +245 -19
  18. package/dist/runtime/composables/useFormForgeSubmit.js +31 -9
  19. package/dist/runtime/index.d.ts +1 -0
  20. package/dist/runtime/renderers/default/FormForgeBuilder.d.vue.ts +21 -2
  21. package/dist/runtime/renderers/default/FormForgeBuilder.vue +689 -738
  22. package/dist/runtime/renderers/default/FormForgeBuilder.vue.d.ts +21 -2
  23. package/dist/runtime/renderers/default/FormForgeBuilderBlockSettingsModal.d.vue.ts +17 -0
  24. package/dist/runtime/renderers/default/FormForgeBuilderBlockSettingsModal.vue +32 -0
  25. package/dist/runtime/renderers/default/FormForgeBuilderBlockSettingsModal.vue.d.ts +17 -0
  26. package/dist/runtime/renderers/default/FormForgeRenderer.d.vue.ts +3 -4
  27. package/dist/runtime/renderers/default/FormForgeRenderer.vue +344 -294
  28. package/dist/runtime/renderers/default/FormForgeRenderer.vue.d.ts +3 -4
  29. package/dist/runtime/renderers/default/FormForgeRendererField.d.vue.ts +22 -0
  30. package/dist/runtime/renderers/default/FormForgeRendererField.vue +237 -0
  31. package/dist/runtime/renderers/default/FormForgeRendererField.vue.d.ts +22 -0
  32. package/dist/runtime/renderers/default/FormForgeRendererPage.d.vue.ts +18 -0
  33. package/dist/runtime/renderers/default/FormForgeRendererPage.vue +31 -0
  34. package/dist/runtime/renderers/default/FormForgeRendererPage.vue.d.ts +18 -0
  35. package/dist/runtime/renderers/default/FormForgeResponse.vue +4 -3
  36. package/dist/runtime/renderers/default/builder/FormForgeBuilderAddressFieldsCard.d.vue.ts +11 -0
  37. package/dist/runtime/renderers/default/builder/FormForgeBuilderAddressFieldsCard.vue +118 -0
  38. package/dist/runtime/renderers/default/builder/FormForgeBuilderAddressFieldsCard.vue.d.ts +11 -0
  39. package/dist/runtime/renderers/default/builder/FormForgeBuilderBlockCard.d.vue.ts +46 -0
  40. package/dist/runtime/renderers/default/builder/FormForgeBuilderBlockCard.vue +205 -0
  41. package/dist/runtime/renderers/default/builder/FormForgeBuilderBlockCard.vue.d.ts +46 -0
  42. package/dist/runtime/renderers/default/builder/FormForgeBuilderChoiceDisplayField.d.vue.ts +11 -0
  43. package/dist/runtime/renderers/default/builder/FormForgeBuilderChoiceDisplayField.vue +37 -0
  44. package/dist/runtime/renderers/default/builder/FormForgeBuilderChoiceDisplayField.vue.d.ts +11 -0
  45. package/dist/runtime/renderers/default/builder/FormForgeBuilderChoiceOptionsField.d.vue.ts +11 -0
  46. package/dist/runtime/renderers/default/builder/FormForgeBuilderChoiceOptionsField.vue +195 -0
  47. package/dist/runtime/renderers/default/builder/FormForgeBuilderChoiceOptionsField.vue.d.ts +11 -0
  48. package/dist/runtime/renderers/default/builder/FormForgeBuilderDescriptionField.d.vue.ts +14 -0
  49. package/dist/runtime/renderers/default/builder/FormForgeBuilderDescriptionField.vue +91 -0
  50. package/dist/runtime/renderers/default/builder/FormForgeBuilderDescriptionField.vue.d.ts +14 -0
  51. package/dist/runtime/renderers/default/builder/FormForgeBuilderLogicPanel.d.vue.ts +13 -0
  52. package/dist/runtime/renderers/default/builder/FormForgeBuilderLogicPanel.vue +387 -0
  53. package/dist/runtime/renderers/default/builder/FormForgeBuilderLogicPanel.vue.d.ts +13 -0
  54. package/dist/runtime/renderers/default/builder/FormForgeBuilderQuestionRow.d.vue.ts +44 -0
  55. package/dist/runtime/renderers/default/builder/FormForgeBuilderQuestionRow.vue +328 -0
  56. package/dist/runtime/renderers/default/builder/FormForgeBuilderQuestionRow.vue.d.ts +44 -0
  57. package/dist/runtime/renderers/default/builder/FormForgeBuilderTemporalModeField.d.vue.ts +11 -0
  58. package/dist/runtime/renderers/default/builder/FormForgeBuilderTemporalModeField.vue +47 -0
  59. package/dist/runtime/renderers/default/builder/FormForgeBuilderTemporalModeField.vue.d.ts +11 -0
  60. package/dist/runtime/renderers/default/builder/FormForgeBuilderValidationRulesSection.d.vue.ts +14 -0
  61. package/dist/runtime/renderers/default/builder/FormForgeBuilderValidationRulesSection.vue +595 -0
  62. package/dist/runtime/renderers/default/builder/FormForgeBuilderValidationRulesSection.vue.d.ts +14 -0
  63. package/dist/runtime/renderers/default/builder/builderFieldHelpers.d.ts +3 -0
  64. package/dist/runtime/renderers/default/builder/builderFieldHelpers.js +4 -0
  65. package/dist/runtime/types/index.d.ts +1 -1
  66. package/dist/runtime/types/management.d.ts +12 -0
  67. package/dist/runtime/types/schema.d.ts +72 -4
  68. package/dist/runtime/utils/defaults.d.ts +7 -0
  69. package/dist/runtime/utils/defaults.js +86 -0
  70. package/dist/runtime/utils/page-logic.d.ts +24 -0
  71. package/dist/runtime/utils/page-logic.js +351 -0
  72. package/dist/runtime/utils/rich-text.d.ts +3 -0
  73. package/dist/runtime/utils/rich-text.js +72 -0
  74. package/dist/runtime/utils/schema.d.ts +1 -1
  75. package/dist/runtime/utils/schema.js +70 -16
  76. package/dist/runtime/utils/temporal.d.ts +10 -0
  77. package/dist/runtime/utils/temporal.js +28 -0
  78. package/dist/runtime/utils/validation.d.ts +5 -0
  79. package/dist/runtime/utils/validation.js +36 -0
  80. package/dist/runtime/validation/zod.d.ts +5 -2
  81. package/dist/runtime/validation/zod.js +563 -54
  82. package/dist/types.d.mts +2 -0
  83. package/package.json +18 -14
@@ -1,5 +1,7 @@
1
1
  import { getFormForgeStringArray, isFormForgeJsonObject, pickFormForgeDataEnvelope } from "./object.js";
2
2
  import { normalizeFormForgeCategory } from "./category.js";
3
+ import { createDefaultAddressFields, resolveDefaultFieldLabel } from "./defaults.js";
4
+ import { isTemporalFieldType, isTemporalMode, temporalModeFromFieldType } from "./temporal.js";
3
5
  const FIELD_TYPES = [
4
6
  "text",
5
7
  "textarea",
@@ -9,14 +11,14 @@ const FIELD_TYPES = [
9
11
  "select_menu",
10
12
  "radio",
11
13
  "checkbox",
14
+ "consent",
12
15
  "checkbox_group",
13
16
  "switch",
17
+ "temporal",
14
18
  "date",
15
19
  "time",
16
- "datetime",
17
- "date_range",
18
- "datetime_range",
19
- "file"
20
+ "file",
21
+ "address"
20
22
  ];
21
23
  const CONDITION_TARGET_TYPES = ["page", "field"];
22
24
  const CONDITION_ACTIONS = ["show", "hide", "skip", "require", "disable"];
@@ -62,6 +64,18 @@ function toString(value, fallback) {
62
64
  }
63
65
  return fallback;
64
66
  }
67
+ function toNumber(value, fallback) {
68
+ if (typeof value === "number" && Number.isFinite(value)) {
69
+ return value;
70
+ }
71
+ if (typeof value === "string") {
72
+ const parsed = Number.parseInt(value, 10);
73
+ if (!Number.isNaN(parsed)) {
74
+ return parsed;
75
+ }
76
+ }
77
+ return fallback;
78
+ }
65
79
  function toNullableString(value) {
66
80
  if (typeof value === "string" || value === null) {
67
81
  return value;
@@ -74,6 +88,10 @@ function toNumberOrStringOrNull(value) {
74
88
  }
75
89
  return void 0;
76
90
  }
91
+ function toPositiveNumber(value) {
92
+ const numericValue = toNumber(value, 0);
93
+ return numericValue > 0 ? numericValue : void 0;
94
+ }
77
95
  function normalizeOption(option) {
78
96
  if (typeof option === "string" || typeof option === "number" || typeof option === "boolean" || option === null) {
79
97
  return option;
@@ -102,9 +120,31 @@ function normalizeOptions(value) {
102
120
  }
103
121
  return options;
104
122
  }
105
- function normalizeField(field, index, fallbackPageKey) {
123
+ function normalizeAddressFields(value, locale) {
124
+ if (!Array.isArray(value)) {
125
+ return void 0;
126
+ }
127
+ const defaults = createDefaultAddressFields(locale);
128
+ const normalized = [];
129
+ for (const [index, addressField] of value.entries()) {
130
+ if (!isFormForgeJsonObject(addressField)) {
131
+ continue;
132
+ }
133
+ const hasLabel = Object.prototype.hasOwnProperty.call(addressField, "label") && (typeof addressField.label === "string" || addressField.label === null);
134
+ const key = typeof addressField.key === "string" && addressField.key.trim() !== "" ? addressField.key : defaults[index]?.key ?? defaults[0].key;
135
+ const label = hasLabel ? typeof addressField.label === "string" ? addressField.label.trim() : "" : defaults[index]?.label ?? key;
136
+ normalized.push({
137
+ key,
138
+ label,
139
+ visible: addressField.visible !== false,
140
+ required: addressField.required === true
141
+ });
142
+ }
143
+ return normalized.length > 0 ? normalized : void 0;
144
+ }
145
+ function normalizeField(field, index, fallbackPageKey, locale) {
106
146
  const rawType = toString(field.type, "text");
107
- const fieldType = isFieldType(rawType) ? rawType : "text";
147
+ const fieldType = isTemporalFieldType(rawType) ? "temporal" : isFieldType(rawType) ? rawType : "text";
108
148
  const name = toString(field.name, `field_${index}`);
109
149
  const fieldKey = toString(field.field_key, `${name}_${index}`);
110
150
  const pageKey = toString(field.page_key, fallbackPageKey);
@@ -131,8 +171,16 @@ function normalizeField(field, index, fallbackPageKey) {
131
171
  multiple: toBoolean(field.multiple, false),
132
172
  disabled: toBoolean(field.disabled, false),
133
173
  readonly: toBoolean(field.readonly, false),
134
- options: normalizeOptions(field.options)
174
+ options: normalizeOptions(field.options),
175
+ address_fields: normalizeAddressFields(field.address_fields, locale),
176
+ display: field.display === "list" || field.display === "menu" ? field.display : void 0,
177
+ temporal_mode: fieldType === "temporal" ? isTemporalMode(field.temporal_mode) ? field.temporal_mode : temporalModeFromFieldType(rawType) : void 0,
178
+ hour_cycle: fieldType === "temporal" && (isTemporalMode(field.temporal_mode) ? field.temporal_mode : temporalModeFromFieldType(rawType)) === "time" ? field.hour_cycle === 12 ? 12 : 24 : void 0,
179
+ consent_label: typeof field.consent_label === "string" ? field.consent_label : void 0
135
180
  };
181
+ if (normalizedField.type === "temporal" && (typeof normalizedField.label !== "string" || normalizedField.label.trim() === "")) {
182
+ normalizedField.label = resolveDefaultFieldLabel("temporal", locale, normalizedField.temporal_mode);
183
+ }
136
184
  if (fieldType === "file") {
137
185
  const accept = getFormForgeStringArray(field.accept);
138
186
  const maxSize = typeof field.max_size === "number" || field.max_size === null ? field.max_size : void 0;
@@ -150,7 +198,7 @@ function normalizeField(field, index, fallbackPageKey) {
150
198
  }
151
199
  return normalizedField;
152
200
  }
153
- function normalizeFieldsList(value, fallbackPageKey, indexOffset = 0) {
201
+ function normalizeFieldsList(value, fallbackPageKey, indexOffset = 0, locale) {
154
202
  if (!Array.isArray(value)) {
155
203
  return [];
156
204
  }
@@ -159,11 +207,11 @@ function normalizeFieldsList(value, fallbackPageKey, indexOffset = 0) {
159
207
  if (!isFormForgeJsonObject(item)) {
160
208
  continue;
161
209
  }
162
- fields.push(normalizeField(item, indexOffset + index, fallbackPageKey));
210
+ fields.push(normalizeField(item, indexOffset + index, fallbackPageKey, locale));
163
211
  }
164
212
  return fields;
165
213
  }
166
- function normalizePageFieldsFromSections(value, pageKey, indexOffset) {
214
+ function normalizePageFieldsFromSections(value, pageKey, indexOffset, locale) {
167
215
  if (!Array.isArray(value)) {
168
216
  return [];
169
217
  }
@@ -172,12 +220,12 @@ function normalizePageFieldsFromSections(value, pageKey, indexOffset) {
172
220
  if (!isFormForgeJsonObject(sectionValue)) {
173
221
  continue;
174
222
  }
175
- const sectionFields = normalizeFieldsList(sectionValue.fields, pageKey, indexOffset + fields.length);
223
+ const sectionFields = normalizeFieldsList(sectionValue.fields, pageKey, indexOffset + fields.length, locale);
176
224
  fields.push(...sectionFields);
177
225
  }
178
226
  return fields;
179
227
  }
180
- function normalizePages(value) {
228
+ function normalizePages(value, locale) {
181
229
  if (!Array.isArray(value)) {
182
230
  return {
183
231
  pages: [],
@@ -193,7 +241,7 @@ function normalizePages(value) {
193
241
  const pageKey = toString(pageValue.page_key, `page_${pageIndex + 1}`);
194
242
  const pageMetaValue = pageValue.meta;
195
243
  const pageMeta = isFormForgeJsonObject(pageMetaValue) ? pageMetaValue : {};
196
- const pageFields = Array.isArray(pageValue.fields) ? normalizeFieldsList(pageValue.fields, pageKey, fields.length) : normalizePageFieldsFromSections(pageValue.sections, pageKey, fields.length);
244
+ const pageFields = Array.isArray(pageValue.fields) ? normalizeFieldsList(pageValue.fields, pageKey, fields.length, locale) : normalizePageFieldsFromSections(pageValue.sections, pageKey, fields.length, locale);
197
245
  fields.push(...pageFields);
198
246
  pages.push({
199
247
  page_key: pageKey,
@@ -281,10 +329,10 @@ function normalizeDraftSettings(value) {
281
329
  enabled: toBoolean(value.enabled, false)
282
330
  };
283
331
  }
284
- export function normalizeFormForgeSchema(payload) {
332
+ export function normalizeFormForgeSchema(payload, locale) {
285
333
  const data = pickFormForgeDataEnvelope(payload);
286
- const rootFields = normalizeFieldsList(data.fields, "page_1");
287
- const normalizedPages = normalizePages(data.pages);
334
+ const rootFields = normalizeFieldsList(data.fields, "page_1", 0, locale);
335
+ const normalizedPages = normalizePages(data.pages, locale);
288
336
  const fields = normalizedPages.fields.length > 0 ? normalizedPages.fields : rootFields;
289
337
  const pages = normalizedPages.pages.length > 0 ? normalizedPages.pages : buildPagesFromFlatFields(fields);
290
338
  const apiValue = data.api;
@@ -295,10 +343,16 @@ export function normalizeFormForgeSchema(payload) {
295
343
  return {
296
344
  key: toString(data.key, ""),
297
345
  version: toString(data.version, ""),
346
+ schema_version: toNumber(data.schema_version, 1),
298
347
  title: toString(data.title, ""),
348
+ publish_at: toNullableString(data.publish_at),
349
+ pause_at: toNullableString(data.pause_at),
350
+ response_limit: toPositiveNumber(data.response_limit),
351
+ submission_code_required: typeof data.submission_code_required === "boolean" ? data.submission_code_required : void 0,
299
352
  category: typeof data.category === "string" || data.category === null ? data.category : void 0,
300
353
  category_item: categoryItem ?? void 0,
301
354
  is_published: toBoolean(data.is_published, false),
355
+ public_url: toNullableString(data.public_url),
302
356
  fields,
303
357
  pages,
304
358
  conditions: normalizeConditions(data.conditions),
@@ -0,0 +1,10 @@
1
+ import type { FormForgeFieldSchema, FormForgeTemporalMode } from '../types/index.js';
2
+ declare const LEGACY_TEMPORAL_TYPES: Record<'date' | 'time', FormForgeTemporalMode>;
3
+ export declare function isTemporalMode(value: unknown): value is FormForgeTemporalMode;
4
+ export declare function isLegacyTemporalFieldType(value: string): value is keyof typeof LEGACY_TEMPORAL_TYPES;
5
+ export declare function isTemporalFieldType(value: string): boolean;
6
+ export declare function temporalModeFromFieldType(value: string): FormForgeTemporalMode;
7
+ export declare function resolveTemporalMode(field: Pick<FormForgeFieldSchema, 'type' | 'temporal_mode'>): FormForgeTemporalMode;
8
+ export declare function isTemporalDateMode(mode: FormForgeTemporalMode): boolean;
9
+ export {};
10
+ //# sourceMappingURL=temporal.d.ts.map
@@ -0,0 +1,28 @@
1
+ const LEGACY_TEMPORAL_TYPES = {
2
+ date: "date",
3
+ time: "time"
4
+ };
5
+ export function isTemporalMode(value) {
6
+ return value === "date" || value === "time";
7
+ }
8
+ export function isLegacyTemporalFieldType(value) {
9
+ return value === "date" || value === "time";
10
+ }
11
+ export function isTemporalFieldType(value) {
12
+ return value === "temporal" || isLegacyTemporalFieldType(value);
13
+ }
14
+ export function temporalModeFromFieldType(value) {
15
+ if (isLegacyTemporalFieldType(value)) {
16
+ return LEGACY_TEMPORAL_TYPES[value];
17
+ }
18
+ return "date";
19
+ }
20
+ export function resolveTemporalMode(field) {
21
+ if (field.type === "temporal" && isTemporalMode(field.temporal_mode)) {
22
+ return field.temporal_mode;
23
+ }
24
+ return temporalModeFromFieldType(field.type);
25
+ }
26
+ export function isTemporalDateMode(mode) {
27
+ return mode === "date";
28
+ }
@@ -0,0 +1,5 @@
1
+ import type { FormForgeFieldValidationConfig, FormForgeFieldValidationOperator } from '../types/index.js';
2
+ export type FormForgeValidationMode = 'text' | 'address' | 'temporal';
3
+ export declare function normalizeFormForgeValidationOperator(operator: FormForgeFieldValidationOperator, mode: FormForgeValidationMode): FormForgeFieldValidationOperator;
4
+ export declare function normalizeFormForgeValidationConfig(config: FormForgeFieldValidationConfig, mode: FormForgeValidationMode): FormForgeFieldValidationConfig;
5
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1,36 @@
1
+ const TEXT_TO_TEMPORAL_OPERATOR_MAP = {
2
+ min: "after",
3
+ max: "before"
4
+ };
5
+ const TEMPORAL_TO_TEXT_OPERATOR_MAP = {
6
+ after: "min",
7
+ before: "max",
8
+ between: "min",
9
+ not_between: "max"
10
+ };
11
+ export function normalizeFormForgeValidationOperator(operator, mode) {
12
+ if (mode === "temporal") {
13
+ return TEXT_TO_TEMPORAL_OPERATOR_MAP[operator] ?? operator;
14
+ }
15
+ return TEMPORAL_TO_TEXT_OPERATOR_MAP[operator] ?? operator;
16
+ }
17
+ export function normalizeFormForgeValidationConfig(config, mode) {
18
+ let mutated = false;
19
+ const nextRules = config.rules.map((rule) => {
20
+ const operator = normalizeFormForgeValidationOperator(rule.operator, mode);
21
+ if (operator !== rule.operator) {
22
+ mutated = true;
23
+ }
24
+ return operator === rule.operator ? rule : {
25
+ ...rule,
26
+ operator
27
+ };
28
+ });
29
+ if (!mutated) {
30
+ return config;
31
+ }
32
+ return {
33
+ ...config,
34
+ rules: nextRules
35
+ };
36
+ }
@@ -1,6 +1,9 @@
1
1
  import { z } from 'zod';
2
2
  import type { FormForgeFormSchema, FormForgeSubmissionPayload } from '../types/index.js';
3
- export declare function createFormForgeZodSchema(form: FormForgeFormSchema): z.ZodTypeAny;
3
+ export interface FormForgeZodValidationOptions {
4
+ locale?: string;
5
+ }
6
+ export declare function createFormForgeZodSchema(form: FormForgeFormSchema, options?: FormForgeZodValidationOptions): z.ZodTypeAny;
4
7
  export declare function mapFormForgeZodIssues(error: z.ZodError): Record<string, string[]>;
5
- export declare function validateFormForgePayload(schema: z.ZodTypeAny, payload: FormForgeSubmissionPayload): Record<string, string[]>;
8
+ export declare function validateFormForgePayload(schema: z.ZodTypeAny, payload: FormForgeSubmissionPayload, options?: FormForgeZodValidationOptions): Record<string, string[]>;
6
9
  //# sourceMappingURL=zod.d.ts.map