@netlisian/softconfig 0.1.4 → 0.1.5

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.
@@ -52,6 +52,8 @@ import {
52
52
  var getRootProps = (appState) => appState.data.root.props;
53
53
 
54
54
  // src/puck/lib/builder/root-config.tsx
55
+ import { useEffect } from "react";
56
+ import equal2 from "react-fast-compare";
55
57
  import {
56
58
  createUsePuck,
57
59
  walkTree
@@ -59,59 +61,352 @@ import {
59
61
 
60
62
  // src/puck/lib/get-field-settings.tsx
61
63
  import { AutoField } from "@measured/puck";
64
+
65
+ // src/puck/lib/get-settings-by-path.ts
66
+ function getFieldSettingsByPath(fieldSettings, path) {
67
+ return path.split(".").reduce((o, key) => o ? o[key] : void 0, fieldSettings);
68
+ }
69
+
70
+ // src/puck/lib/array-field-utils.ts
71
+ var primitiveFieldTypes = /* @__PURE__ */ new Set([
72
+ "text",
73
+ "textarea",
74
+ "number",
75
+ "select",
76
+ "radio",
77
+ "reference"
78
+ ]);
79
+ var isPrimitiveValue = (value) => ["string", "number", "boolean"].includes(typeof value);
80
+ var getFallbackValueForField = (type) => {
81
+ switch (type) {
82
+ case "number":
83
+ return 0;
84
+ case "array":
85
+ return [];
86
+ case "object":
87
+ return {};
88
+ default:
89
+ return "";
90
+ }
91
+ };
92
+ var resolveExpressionSummary = (item, index, expression) => {
93
+ if (!expression) return "";
94
+ let isValid = true;
95
+ const result = expression.replace(/\{([^}]+)\}/g, (_match, token) => {
96
+ if (token === "index") {
97
+ return String(index);
98
+ }
99
+ if (token.startsWith("item.")) {
100
+ const value = getFieldSettingsByPath(item, token.slice(5));
101
+ if (isPrimitiveValue(value)) {
102
+ return String(value);
103
+ }
104
+ }
105
+ isValid = false;
106
+ return "";
107
+ });
108
+ return isValid ? result : "";
109
+ };
110
+ var isPrimitiveFieldType = (type) => primitiveFieldTypes.has(type);
111
+ var buildArrayDefaultItemProps = (subFields = [], subFieldSettings = {}) => {
112
+ if (!subFields.length) return void 0;
113
+ const item = {};
114
+ let hasValue = false;
115
+ subFields.forEach((subField) => {
116
+ const settings = subFieldSettings[subField.name];
117
+ if (settings && Object.prototype.hasOwnProperty.call(settings, "defaultValue") && settings.defaultValue !== void 0) {
118
+ item[subField.name] = settings.defaultValue;
119
+ hasValue = true;
120
+ return;
121
+ }
122
+ item[subField.name] = getFallbackValueForField(subField.type);
123
+ hasValue = true;
124
+ });
125
+ return hasValue ? item : void 0;
126
+ };
127
+ var buildArrayDefaultValue = (subFields = [], subFieldSettings = {}) => {
128
+ const item = buildArrayDefaultItemProps(subFields, subFieldSettings);
129
+ return item ? [item] : [];
130
+ };
131
+ var getArrayItemSummary = (item, index = 0, settings) => {
132
+ if ((settings == null ? void 0 : settings.summary) === "field" && settings.summaryField) {
133
+ const value = getFieldSettingsByPath(item, settings.summaryField);
134
+ if (isPrimitiveValue(value) && String(value).length > 0) {
135
+ return String(value);
136
+ }
137
+ return `Item ${(index || 0) + 1}`;
138
+ }
139
+ if ((settings == null ? void 0 : settings.summary) === "expression") {
140
+ const summary = resolveExpressionSummary(
141
+ item,
142
+ index,
143
+ settings.summaryExpression
144
+ );
145
+ return summary || `Item ${(index || 0) + 1}`;
146
+ }
147
+ return `Item ${(index || 0) + 1}`;
148
+ };
149
+ var isArrayMappingPath = (path) => {
150
+ return typeof path === "string" && /^[^.]+\[\]\.[^.]+$/.test(path);
151
+ };
152
+ var getArrayBasePath = (arrayPath) => {
153
+ if (!isArrayMappingPath(arrayPath)) return null;
154
+ const match = arrayPath.match(/^([^.]+)\[\]\./);
155
+ return match ? match[1] : null;
156
+ };
157
+ var getArrayItemSubPath = (arrayPath) => {
158
+ if (!isArrayMappingPath(arrayPath)) return null;
159
+ const match = arrayPath.match(/\[\]\.(.+)$/);
160
+ return match ? match[1] : null;
161
+ };
162
+
163
+ // src/puck/lib/custom-fields.ts
164
+ var builtInSoftFieldTypes = /* @__PURE__ */ new Set([
165
+ "text",
166
+ "textarea",
167
+ "number",
168
+ "select",
169
+ "radio",
170
+ "array",
171
+ "object",
172
+ "reference"
173
+ ]);
174
+ var warnedMessages = /* @__PURE__ */ new Set();
175
+ var warnOnce = (message) => {
176
+ if (warnedMessages.has(message)) {
177
+ return;
178
+ }
179
+ warnedMessages.add(message);
180
+ console.warn(message);
181
+ };
182
+ var isBuiltInSoftFieldType = (fieldType) => {
183
+ return builtInSoftFieldTypes.has(fieldType);
184
+ };
185
+ var resolveCustomFieldDefinition = (fieldType, customFields) => {
186
+ if (isBuiltInSoftFieldType(fieldType)) {
187
+ return void 0;
188
+ }
189
+ return customFields == null ? void 0 : customFields[fieldType];
190
+ };
191
+ var resolveCustomFieldReturnType = (fieldType, customFields) => {
192
+ const customField = resolveCustomFieldDefinition(fieldType, customFields);
193
+ if (!customField) {
194
+ return null;
195
+ }
196
+ if (!customField.returnType) {
197
+ warnOnce(
198
+ `[soft-config] Custom field "${fieldType}" is missing a required returnType and will be skipped from mapping options.`
199
+ );
200
+ return null;
201
+ }
202
+ return customField.returnType;
203
+ };
204
+ var resolveCustomFieldSchema = (fieldType, customFields) => {
205
+ const customField = resolveCustomFieldDefinition(fieldType, customFields);
206
+ if (!customField) {
207
+ return null;
208
+ }
209
+ const returnType = resolveCustomFieldReturnType(fieldType, customFields);
210
+ if (!returnType) {
211
+ return null;
212
+ }
213
+ if (returnType !== "array" && returnType !== "object") {
214
+ return null;
215
+ }
216
+ const subFields = customField.subFields || [];
217
+ if (!subFields.length) {
218
+ warnOnce(
219
+ `[soft-config] Custom field "${fieldType}" returns ${returnType} but does not define subFields. It will be skipped from mapping options.`
220
+ );
221
+ return null;
222
+ }
223
+ return {
224
+ subFields,
225
+ subFieldSettings: customField.subFieldSettings || {}
226
+ };
227
+ };
228
+ var getCustomFieldTypeOptions = (customFields) => {
229
+ if (!customFields) {
230
+ return [];
231
+ }
232
+ return Object.entries(customFields).filter(([fieldType]) => !isBuiltInSoftFieldType(fieldType)).map(([fieldType, definition]) => ({
233
+ label: typeof definition.field.label === "string" && definition.field.label ? definition.field.label : fieldType,
234
+ value: fieldType
235
+ }));
236
+ };
237
+ var mapCustomReturnTypeToMappingType = (returnType) => {
238
+ switch (returnType) {
239
+ case "string":
240
+ return "textarea";
241
+ case "number":
242
+ return "number";
243
+ case "boolean":
244
+ return "select";
245
+ case "array":
246
+ return "array";
247
+ case "object":
248
+ return "object";
249
+ default:
250
+ return "textarea";
251
+ }
252
+ };
253
+
254
+ // src/puck/lib/get-field-settings.tsx
62
255
  import { jsx } from "react/jsx-runtime";
63
- var getFieldSettings = (_fields, _fieldSettings, deep) => {
256
+ var buildPuckField = (field, fieldSettings, customFields) => {
257
+ const customFieldDefinition = resolveCustomFieldDefinition(
258
+ field.type,
259
+ customFields
260
+ );
261
+ const customReturnType = resolveCustomFieldReturnType(field.type, customFields);
262
+ if (customFieldDefinition && customReturnType) {
263
+ return __spreadProps(__spreadValues({}, customFieldDefinition.field), {
264
+ type: "custom",
265
+ label: customFieldDefinition.field.label || field.name
266
+ });
267
+ }
268
+ const resolvedType = field.type;
269
+ switch (resolvedType) {
270
+ case "text":
271
+ case "textarea":
272
+ return { type: resolvedType, label: field.name };
273
+ case "number":
274
+ return {
275
+ type: resolvedType,
276
+ label: field.name,
277
+ min: fieldSettings == null ? void 0 : fieldSettings.min,
278
+ max: fieldSettings == null ? void 0 : fieldSettings.max,
279
+ step: fieldSettings == null ? void 0 : fieldSettings.step
280
+ };
281
+ case "select":
282
+ case "radio":
283
+ return {
284
+ type: resolvedType,
285
+ label: field.name,
286
+ options: (fieldSettings == null ? void 0 : fieldSettings.options) || []
287
+ };
288
+ case "array": {
289
+ const subFields = (fieldSettings == null ? void 0 : fieldSettings.subFields) || [];
290
+ const subFieldSettings = (fieldSettings == null ? void 0 : fieldSettings.subFieldSettings) || {};
291
+ return {
292
+ type: "array",
293
+ label: field.name,
294
+ min: fieldSettings == null ? void 0 : fieldSettings.min,
295
+ max: fieldSettings == null ? void 0 : fieldSettings.max,
296
+ arrayFields: buildDefaultEditorFields(
297
+ subFields,
298
+ subFieldSettings,
299
+ customFields
300
+ ),
301
+ defaultItemProps: buildArrayDefaultItemProps(subFields, subFieldSettings),
302
+ getItemSummary(item, index) {
303
+ return getArrayItemSummary(item, index, fieldSettings);
304
+ }
305
+ };
306
+ }
307
+ case "object":
308
+ return {
309
+ type: "object",
310
+ label: field.name,
311
+ objectFields: buildDefaultEditorFields(
312
+ (fieldSettings == null ? void 0 : fieldSettings.subFields) || [],
313
+ (fieldSettings == null ? void 0 : fieldSettings.subFieldSettings) || {},
314
+ customFields
315
+ )
316
+ };
317
+ default:
318
+ return { type: "text", label: field.name };
319
+ }
320
+ };
321
+ var buildDefaultEditorFields = (fields = [], fieldSettings = {}, customFields) => {
322
+ return fields.reduce((acc, field) => {
323
+ acc[field.name] = buildPuckField(
324
+ field,
325
+ fieldSettings[field.name],
326
+ customFields
327
+ );
328
+ return acc;
329
+ }, {});
330
+ };
331
+ var getFieldSettings = (_fields, _fieldSettings, customFields, deep) => {
332
+ const customTypeOptions = getCustomFieldTypeOptions(customFields);
64
333
  return (_fields || []).reduce((fields, field) => {
65
334
  const fieldSettings = {
66
335
  // placeholder: { type: "text", label: "Placeholder" },
67
336
  };
68
337
  const currentFieldSettings = _fieldSettings == null ? void 0 : _fieldSettings[field.name];
69
- switch (field.type) {
338
+ const customFieldDefinition = resolveCustomFieldDefinition(
339
+ field.type,
340
+ customFields
341
+ );
342
+ const customReturnType = resolveCustomFieldReturnType(
343
+ field.type,
344
+ customFields
345
+ );
346
+ const resolvedType = field.type;
347
+ const customSchema = resolveCustomFieldSchema(field.type, customFields);
348
+ const resolvedSubFields = (customSchema == null ? void 0 : customSchema.subFields) || (currentFieldSettings == null ? void 0 : currentFieldSettings.subFields) || [];
349
+ const resolvedSubFieldSettings = (customSchema == null ? void 0 : customSchema.subFieldSettings) || (currentFieldSettings == null ? void 0 : currentFieldSettings.subFieldSettings) || {};
350
+ const customDefaultValueField = customFieldDefinition && customReturnType ? __spreadProps(__spreadValues({}, customFieldDefinition.field), {
351
+ type: "custom",
352
+ label: customFieldDefinition.field.label || "Default Value"
353
+ }) : null;
354
+ if (customDefaultValueField) {
355
+ fieldSettings.defaultValue = customDefaultValueField;
356
+ }
357
+ switch (resolvedType) {
70
358
  case "text":
71
359
  case "textarea":
72
- fieldSettings.defaultValue = {
73
- type: field.type,
74
- label: "Default Value"
75
- };
360
+ if (!customDefaultValueField) {
361
+ fieldSettings.defaultValue = {
362
+ type: resolvedType,
363
+ label: "Default Value"
364
+ };
365
+ }
76
366
  break;
77
367
  case "number":
78
- fieldSettings.defaultValue = {
79
- type: field.type,
80
- label: "Default Value"
81
- };
368
+ if (!customDefaultValueField) {
369
+ fieldSettings.defaultValue = {
370
+ type: resolvedType,
371
+ label: "Default Value"
372
+ };
373
+ }
82
374
  fieldSettings.min = {
83
- type: field.type,
375
+ type: resolvedType,
84
376
  label: "Minimum Value"
85
377
  };
86
378
  fieldSettings.max = {
87
- type: field.type,
379
+ type: resolvedType,
88
380
  label: "Maximum Value"
89
381
  };
90
382
  fieldSettings.step = {
91
- type: field.type,
383
+ type: resolvedType,
92
384
  label: "Step Size"
93
385
  };
94
386
  break;
95
387
  case "radio":
96
- case "select":
97
- fieldSettings.defaultValue = {
98
- type: "custom",
99
- label: "Default Value",
100
- render: ({ value, onChange, id }) => /* @__PURE__ */ jsx(
101
- AutoField,
102
- {
103
- field: {
104
- type: field.type,
105
- label: "Default Value",
106
- options: (currentFieldSettings == null ? void 0 : currentFieldSettings.options) || []
107
- },
108
- value,
109
- onChange,
110
- readOnly: false,
111
- id
112
- }
113
- )
114
- };
388
+ case "select": {
389
+ const selectOptions = (currentFieldSettings == null ? void 0 : currentFieldSettings.options) || [];
390
+ if (!customDefaultValueField) {
391
+ fieldSettings.defaultValue = {
392
+ type: "custom",
393
+ label: "Default Value",
394
+ render: ({ value, onChange, id }) => /* @__PURE__ */ jsx(
395
+ AutoField,
396
+ {
397
+ field: {
398
+ type: resolvedType,
399
+ label: "Default Value",
400
+ options: selectOptions
401
+ },
402
+ value,
403
+ onChange,
404
+ readOnly: false,
405
+ id
406
+ }
407
+ )
408
+ };
409
+ }
115
410
  fieldSettings.options = {
116
411
  type: "array",
117
412
  label: "Options",
@@ -131,21 +426,8 @@ var getFieldSettings = (_fields, _fieldSettings, deep) => {
131
426
  }
132
427
  };
133
428
  break;
429
+ }
134
430
  case "array":
135
- fieldSettings.summary = {
136
- type: "select",
137
- label: "Summary Field",
138
- options: [
139
- {
140
- label: "Default Numbering",
141
- value: ""
142
- },
143
- ...((currentFieldSettings == null ? void 0 : currentFieldSettings.subFields) || []).map((f) => ({
144
- label: f.name,
145
- value: f.name
146
- }))
147
- ]
148
- };
149
431
  case "object":
150
432
  fieldSettings.subFields = {
151
433
  type: "array",
@@ -174,7 +456,8 @@ var getFieldSettings = (_fields, _fieldSettings, deep) => {
174
456
  {
175
457
  label: "Radio",
176
458
  value: "radio"
177
- }
459
+ },
460
+ ...customTypeOptions
178
461
  ] : [
179
462
  {
180
463
  label: "Text",
@@ -203,7 +486,8 @@ var getFieldSettings = (_fields, _fieldSettings, deep) => {
203
486
  {
204
487
  label: "Reference",
205
488
  value: "reference"
206
- }
489
+ },
490
+ ...customTypeOptions
207
491
  ]
208
492
  }
209
493
  },
@@ -215,44 +499,99 @@ var getFieldSettings = (_fields, _fieldSettings, deep) => {
215
499
  fieldSettings.subFieldSettings = {
216
500
  type: "object",
217
501
  label: "Sub Field Settings",
218
- objectFields: (currentFieldSettings == null ? void 0 : currentFieldSettings.subFields) ? getFieldSettings(
219
- currentFieldSettings.subFields,
220
- currentFieldSettings.subFieldSettings,
502
+ objectFields: resolvedSubFields ? getFieldSettings(
503
+ resolvedSubFields,
504
+ resolvedSubFieldSettings,
505
+ customFields,
221
506
  true
222
507
  ) : {}
223
508
  };
509
+ if (resolvedType === "array") {
510
+ if (!customDefaultValueField) {
511
+ fieldSettings.defaultValue = {
512
+ type: "array",
513
+ label: "Default Items",
514
+ arrayFields: buildDefaultEditorFields(
515
+ resolvedSubFields,
516
+ resolvedSubFieldSettings,
517
+ customFields
518
+ ),
519
+ defaultItemProps: buildArrayDefaultItemProps(
520
+ resolvedSubFields,
521
+ resolvedSubFieldSettings
522
+ ),
523
+ getItemSummary(item, index) {
524
+ return getArrayItemSummary(item, index, currentFieldSettings);
525
+ }
526
+ };
527
+ }
528
+ fieldSettings.min = {
529
+ type: "number",
530
+ label: "Minimum Items"
531
+ };
532
+ fieldSettings.max = {
533
+ type: "number",
534
+ label: "Maximum Items"
535
+ };
536
+ fieldSettings.summary = {
537
+ type: "select",
538
+ label: "Summary",
539
+ options: [
540
+ {
541
+ label: "Default Numbering / Count",
542
+ value: "count"
543
+ },
544
+ {
545
+ label: "Field",
546
+ value: "field"
547
+ },
548
+ {
549
+ label: "Expression",
550
+ value: "expression"
551
+ }
552
+ ]
553
+ };
554
+ if ((currentFieldSettings == null ? void 0 : currentFieldSettings.summary) === "field") {
555
+ fieldSettings.summaryField = {
556
+ type: "select",
557
+ label: "Summary Field",
558
+ options: [
559
+ {
560
+ label: "Select a field",
561
+ value: ""
562
+ },
563
+ ...resolvedSubFields.filter((subField) => isPrimitiveFieldType(subField.type)).map((subField) => ({
564
+ label: subField.name,
565
+ value: subField.name
566
+ }))
567
+ ]
568
+ };
569
+ }
570
+ if ((currentFieldSettings == null ? void 0 : currentFieldSettings.summary) === "expression") {
571
+ fieldSettings.summaryExpression = {
572
+ type: "text",
573
+ label: "Summary Expression"
574
+ };
575
+ }
576
+ }
224
577
  break;
225
578
  }
579
+ const overriddenFieldSettings = (customFieldDefinition == null ? void 0 : customFieldDefinition.fieldSettingsOverride) ? customFieldDefinition.fieldSettingsOverride({
580
+ fieldName: field.name,
581
+ fieldType: field.type,
582
+ fieldSettings: currentFieldSettings,
583
+ originalFieldSettings: fieldSettings
584
+ }) : fieldSettings;
226
585
  fields[field.name] = {
227
586
  type: "object",
228
587
  label: field.name,
229
- objectFields: fieldSettings
588
+ objectFields: overriddenFieldSettings
230
589
  };
231
590
  return fields;
232
591
  }, {});
233
592
  };
234
593
  var get_field_settings_default = getFieldSettings;
235
594
 
236
- // src/puck/lib/get-settings-by-path.ts
237
- function getFieldSettingsByPath(fieldSettings, path) {
238
- return path.split(".").reduce((o, key) => o ? o[key] : void 0, fieldSettings);
239
- }
240
-
241
- // src/puck/lib/set-prop-by-path.ts
242
- function setPropertyByPath(props, path, value) {
243
- const parts = path.split(".");
244
- const last = parts.pop();
245
- let cur = props;
246
- for (const p of parts) {
247
- if (typeof cur[p] !== "object" || cur[p] === null) cur[p] = {};
248
- cur = cur[p];
249
- }
250
- cur[last] = value;
251
- }
252
-
253
- // src/puck/lib/builder/root-config.tsx
254
- import { useEffect } from "react";
255
-
256
595
  // src/puck/context/useStore.ts
257
596
  import { createContext, useContext } from "react";
258
597
  import { useStore } from "zustand";
@@ -273,224 +612,356 @@ var createUseSoftConfig = () => {
273
612
  };
274
613
  var useSoftConfig = createUseSoftConfig();
275
614
 
276
- // src/puck/lib/builder/root-config.tsx
277
- import { useDebounce } from "use-debounce";
278
- import { Fragment, jsx as jsx2 } from "react/jsx-runtime";
279
- var useCustomPuck = createUsePuck();
280
- var breakVersion = (version) => {
281
- const [major, minor, patch] = version.split(".").map((v) => parseInt(v));
282
- return [major, minor, patch];
283
- };
284
- var updateVersion = (version, increment) => {
285
- let [major, minor, patch] = breakVersion(version);
286
- if (increment === "major") {
287
- major += 1;
288
- minor = 0;
289
- patch = 0;
290
- } else if (increment === "minor") {
291
- minor += 1;
292
- patch = 0;
293
- } else {
294
- patch += 1;
615
+ // src/puck/lib/apply-mapping.ts
616
+ import equal from "react-fast-compare";
617
+
618
+ // src/puck/lib/set-prop-by-path.ts
619
+ function setPropertyByPath(props, path, value) {
620
+ const parts = path.split(".");
621
+ const last = parts.pop();
622
+ let cur = props;
623
+ for (const p of parts) {
624
+ if (typeof cur[p] !== "object" || cur[p] === null) cur[p] = {};
625
+ cur = cur[p];
626
+ }
627
+ cur[last] = value;
628
+ }
629
+
630
+ // src/puck/lib/apply-mapping.ts
631
+ var resolveValueByPath = (source, path) => {
632
+ if (!path) return source;
633
+ const segments = path.split(".");
634
+ const resolveSegments = (current, index) => {
635
+ if (current === null || current === void 0) return void 0;
636
+ if (index >= segments.length) return current;
637
+ const segment = segments[index];
638
+ if (segment.endsWith("[]")) {
639
+ const arrayKey = segment.slice(0, -2);
640
+ const arraySource = arrayKey ? current == null ? void 0 : current[arrayKey] : current;
641
+ const resolvedArray = Array.isArray(arraySource) ? arraySource : Array.isArray(arraySource == null ? void 0 : arraySource.defaultValue) ? arraySource.defaultValue : void 0;
642
+ if (!resolvedArray) return void 0;
643
+ if (index === segments.length - 1) return resolvedArray;
644
+ return resolvedArray.map((item) => resolveSegments(item, index + 1));
645
+ }
646
+ return resolveSegments(current[segment], index + 1);
647
+ };
648
+ return resolveSegments(source, 0);
649
+ };
650
+ var resolveFieldSettingEntryByPath = (settings, path) => {
651
+ if (!path) return void 0;
652
+ const segments = path.split(".");
653
+ let currentSettings = settings;
654
+ let currentEntry;
655
+ for (const segmentWithArraySuffix of segments) {
656
+ const segment = segmentWithArraySuffix.endsWith("[]") ? segmentWithArraySuffix.slice(0, -2) : segmentWithArraySuffix;
657
+ if (!currentSettings || typeof currentSettings !== "object") {
658
+ return void 0;
659
+ }
660
+ currentEntry = currentSettings[segment];
661
+ if (currentEntry === void 0) {
662
+ return void 0;
663
+ }
664
+ currentSettings = currentEntry == null ? void 0 : currentEntry.subFieldSettings;
295
665
  }
296
- return `${major}.${minor}.${patch}`;
666
+ return currentEntry;
297
667
  };
298
- var builderRootConfig = (config, overrides, editingComponent, showVersionFields = true) => ({
299
- fields: __spreadValues({
300
- _name: overrides.name || {
301
- type: "text",
302
- label: "Soft Component Name"
303
- },
304
- _category: overrides.categories || {
305
- type: "select",
306
- label: "Category",
307
- options: [
308
- ...Object.keys(config.categories || {}).map((cat) => {
309
- var _a;
310
- return {
311
- label: ((_a = config.categories) == null ? void 0 : _a[cat].title) || cat,
312
- value: cat
313
- };
314
- }) || [],
315
- {
316
- label: Object.keys(config.categories || {}).length ? "Other" : "Uncategorized",
317
- value: void 0
668
+ function applyMapping(props, fieldSettings, map, resolveInput = "fieldSettings", options) {
669
+ var _a, _b, _c;
670
+ const newProps = __spreadValues({}, props);
671
+ const sourceProps = (_a = options == null ? void 0 : options.sourceProps) != null ? _a : props;
672
+ const mappedArrayPaths = /* @__PURE__ */ new Set();
673
+ let changed = false;
674
+ const changedArrayBases = /* @__PURE__ */ new Set();
675
+ for (const entry of map) {
676
+ const { from, to, transform } = entry;
677
+ if (!from || !to) continue;
678
+ const fromPaths = Array.isArray(from) ? from : [from];
679
+ const toPaths = Array.isArray(to) ? to : [to];
680
+ const hasInvalidPair = fromPaths.some((fp, idx) => {
681
+ const tp = toPaths[idx] || toPaths[0];
682
+ if (typeof fp !== "string" || typeof tp !== "string") return false;
683
+ return isArrayMappingPath(fp) && !isArrayMappingPath(tp);
684
+ });
685
+ if (hasInvalidPair) continue;
686
+ const inputValues = fromPaths.map((f) => {
687
+ if (resolveInput === "propsFirst") {
688
+ const propVal = resolveValueByPath(sourceProps, f);
689
+ if (propVal !== void 0) return propVal;
690
+ const setting = resolveValueByPath(fieldSettings, f);
691
+ if (setting && Object.prototype.hasOwnProperty.call(setting, "defaultValue")) {
692
+ return setting.defaultValue;
318
693
  }
319
- ]
320
- },
321
- _fields: {
322
- type: "array",
323
- label: "Fields",
324
- defaultItemProps: {
325
- name: "New Field",
326
- type: "text"
327
- },
328
- getItemSummary(item, index) {
329
- return item.name || `Field ${(index || 0) + 1}`;
330
- },
331
- arrayFields: {
332
- name: { type: "text", label: "Name" },
333
- type: {
334
- type: "select",
335
- label: "Type",
336
- options: [
337
- { label: "Text", value: "text" },
338
- { label: "Textarea", value: "textarea" },
339
- { label: "Number", value: "number" },
340
- { label: "Select", value: "select" },
341
- { label: "Radio", value: "radio" },
342
- { label: "Array", value: "array" },
343
- { label: "Object", value: "object" }
344
- // { label: "Reference", value: "reference" },
345
- ]
694
+ return propVal;
695
+ }
696
+ const directValue = resolveValueByPath(fieldSettings, f);
697
+ if (directValue !== void 0) {
698
+ return directValue;
699
+ }
700
+ return resolveFieldSettingEntryByPath(fieldSettings, f);
701
+ });
702
+ const resolvedInputs = inputValues.map(
703
+ (v) => resolveInput === "fieldSettings" ? v == null ? void 0 : v.defaultValue : v
704
+ );
705
+ let result = transform ? transform(resolvedInputs, newProps) : inputValues[0];
706
+ if (resolveInput === "fieldSettings" && !transform && result !== void 0 && typeof result === "object" && result !== null && "defaultValue" in result) {
707
+ result = result.defaultValue;
708
+ }
709
+ const isSingleArrayTarget = toPaths.length === 1 && typeof toPaths[0] === "string" && isArrayMappingPath(toPaths[0]);
710
+ if (isSingleArrayTarget) {
711
+ const toPath = toPaths[0];
712
+ const arrayBase = getArrayBasePath(toPath);
713
+ const subProp = getArrayItemSubPath(toPath) || "";
714
+ if (!arrayBase) continue;
715
+ const defaultArray = Array.isArray((_b = options == null ? void 0 : options.arrayDefaults) == null ? void 0 : _b[arrayBase]) ? (_c = options == null ? void 0 : options.arrayDefaults) == null ? void 0 : _c[arrayBase] : [];
716
+ const currentArrayAtPath = resolveValueByPath(newProps, arrayBase);
717
+ const currentArray = Array.isArray(currentArrayAtPath) ? currentArrayAtPath : [];
718
+ const isFromArrayPath = typeof fromPaths[0] === "string" && isArrayMappingPath(fromPaths[0]);
719
+ const sourceArray = isFromArrayPath ? Array.isArray(result) ? result : result !== void 0 ? [result] : [] : Array.isArray(result) ? result : defaultArray.map(() => result);
720
+ let defaults = entry.unmappedArrayItemDefaultValues || entry.defaultOverrides || {};
721
+ if (typeof defaults === "string") {
722
+ try {
723
+ defaults = JSON.parse(defaults);
724
+ } catch (e) {
725
+ defaults = {};
346
726
  }
347
727
  }
728
+ const targetLength = sourceArray.length;
729
+ const constructed = Array.from({ length: targetLength }).map((_, idx) => {
730
+ const mappedValue = sourceArray[idx];
731
+ const defaultItem = defaultArray[idx] && typeof defaultArray[idx] === "object" ? defaultArray[idx] : {};
732
+ const currentItem = currentArray[idx] && typeof currentArray[idx] === "object" ? currentArray[idx] : {};
733
+ const item = __spreadValues(__spreadValues(__spreadValues({}, defaultItem), defaults), currentItem);
734
+ if (subProp && mappedValue !== void 0) {
735
+ setPropertyByPath(item, subProp, mappedValue);
736
+ }
737
+ return item;
738
+ });
739
+ const originalArray = resolveValueByPath(newProps, arrayBase);
740
+ if (!equal(originalArray, constructed)) {
741
+ setPropertyByPath(newProps, arrayBase, constructed);
742
+ changedArrayBases.add(arrayBase);
743
+ }
744
+ mappedArrayPaths.add(arrayBase);
745
+ } else if (toPaths.length === 1 && Array.isArray(result) && toPaths[0].includes("array")) {
746
+ const toPath = toPaths[0];
747
+ const original = resolveValueByPath(newProps, toPath);
748
+ if (!equal(original, result)) {
749
+ setPropertyByPath(newProps, toPath, result);
750
+ changed = true;
751
+ }
752
+ } else if (Array.isArray(result) && toPaths.length > 1) {
753
+ result.forEach((val, idx) => {
754
+ if (toPaths[idx]) {
755
+ const orig = resolveValueByPath(newProps, toPaths[idx]);
756
+ if (!equal(orig, val)) {
757
+ setPropertyByPath(newProps, toPaths[idx], val);
758
+ changed = true;
759
+ }
760
+ }
761
+ });
762
+ } else if (toPaths[0]) {
763
+ const finalValue = result;
764
+ const originalValue = resolveValueByPath(newProps, toPaths[0]);
765
+ if (!equal(originalValue, finalValue)) {
766
+ setPropertyByPath(newProps, toPaths[0], finalValue);
767
+ changed = true;
768
+ }
348
769
  }
349
- }, overrides.additionalRootFields || {}),
350
- resolveFields({ props: data }, { fields, changed }) {
351
- var _a, _b;
352
- if (!(data == null ? void 0 : data._fields) || changed._fields || changed._fieldSettings)
353
- if ((_a = data == null ? void 0 : data._fields) == null ? void 0 : _a.length)
354
- fields._fieldSettings = {
355
- type: "object",
356
- label: "Field Settings",
357
- objectFields: get_field_settings_default(
358
- data._fields || [],
359
- data._fieldSettings || {}
360
- )
361
- };
362
- else delete fields._fieldSettings;
363
- if (showVersionFields && ((_b = data == null ? void 0 : data._versions) == null ? void 0 : _b.length)) {
364
- const latestVersion = data._versions[data._versions.length - 1] || "1.0.0";
365
- delete fields._version;
366
- fields._version = {
770
+ }
771
+ const hasNetArrayChanges = Array.from(changedArrayBases).some(
772
+ (arrayBase) => !equal(resolveValueByPath(props, arrayBase), resolveValueByPath(newProps, arrayBase))
773
+ );
774
+ return { newProps, mappedArrayPaths, changed: changed || hasNetArrayChanges };
775
+ }
776
+
777
+ // src/puck/lib/builder/root-config.tsx
778
+ import { Fragment, jsx as jsx2 } from "react/jsx-runtime";
779
+ var useCustomPuck = createUsePuck();
780
+ var getSerializableProps = (props) => {
781
+ const cleanProps = {
782
+ id: props.id
783
+ };
784
+ for (const key in props) {
785
+ const value = props[key];
786
+ if (["children", "puck", "editMode"].includes(key)) continue;
787
+ if (value && typeof value === "object" && value.$$typeof) continue;
788
+ if (typeof value === "function") continue;
789
+ cleanProps[key] = value;
790
+ }
791
+ return cleanProps;
792
+ };
793
+ var builderRootConfig = (config, overrides, editingComponent, showVersionFields = true, customFields) => {
794
+ const customTypeOptions = getCustomFieldTypeOptions(customFields);
795
+ return {
796
+ fields: __spreadValues({
797
+ _name: overrides.name || {
798
+ type: "text",
799
+ label: "Soft Component Name"
800
+ },
801
+ _category: overrides.categories || {
367
802
  type: "select",
368
- label: "Version",
803
+ label: "Category",
369
804
  options: [
370
- ...data._versions.map((v) => ({ label: v, value: v })),
371
- {
372
- label: `${updateVersion(latestVersion, "patch")} (Patch)`,
373
- value: updateVersion(latestVersion, "patch")
374
- },
375
- {
376
- label: `${updateVersion(latestVersion, "minor")} (Minor)`,
377
- value: updateVersion(latestVersion, "minor")
378
- },
805
+ ...Object.keys(config.categories || {}).map((cat) => {
806
+ var _a;
807
+ return {
808
+ label: ((_a = config.categories) == null ? void 0 : _a[cat].title) || cat,
809
+ value: cat
810
+ };
811
+ }) || [],
379
812
  {
380
- label: `${updateVersion(latestVersion, "major")} (Major)`,
381
- value: updateVersion(latestVersion, "major")
813
+ label: Object.keys(config.categories || {}).length ? "Other" : "Uncategorized",
814
+ value: void 0
382
815
  }
383
816
  ]
384
- };
385
- } else {
386
- delete fields._version;
387
- }
388
- return fields;
389
- },
390
- resolveData: (props, params) => {
391
- if (overrides.resolveRootData) {
392
- return overrides.resolveRootData(props, params, { editingComponent });
393
- }
394
- let result = {
395
- props,
396
- readOnly: void 0
397
- };
398
- return result;
399
- },
400
- render: (props) => {
401
- const fieldSettings = props == null ? void 0 : props._fieldSettings;
402
- const data = useCustomPuck((s) => s.appState.data);
403
- const dispatch = useCustomPuck((s) => s.dispatch);
404
- const getSelectorForId = useCustomPuck((s) => s.getSelectorForId);
405
- const setVersion = useSoftConfig((s) => s.builder.setVersion);
406
- const state = useSoftConfig((s) => s.state);
407
- const [debouncedFieldSettings] = useDebounce(fieldSettings, 500);
408
- useEffect(() => {
409
- if (!debouncedFieldSettings || Object.keys(debouncedFieldSettings).length === 0) return;
410
- walkTree(
411
- data,
412
- {
413
- components: config.components
817
+ },
818
+ _fields: {
819
+ type: "array",
820
+ label: "Fields",
821
+ defaultItemProps: {
822
+ name: "New Field",
823
+ type: "text"
414
824
  },
415
- (content) => content.map((child) => {
416
- var _a;
417
- const map = ((_a = child.props) == null ? void 0 : _a._map) || [];
418
- if (map.length) {
419
- map.forEach(({ from, to, transform }) => {
420
- if (!from || !to) return;
421
- const fromPaths = Array.isArray(from) ? from : [from];
422
- const toPaths = Array.isArray(to) ? to : [to];
423
- const inputValues = fromPaths.map(
424
- (f) => getFieldSettingsByPath(props._fieldSettings || {}, f)
425
- );
426
- let value = transform ? transform(
427
- inputValues.map((v) => v == null ? void 0 : v.defaultValue),
428
- child.props
429
- ) : inputValues[0];
430
- if (Array.isArray(value)) {
431
- value.forEach((val, i) => {
432
- if (toPaths[i]) {
433
- const originalValue = getFieldSettingsByPath(
434
- child.props,
435
- toPaths[i]
436
- );
437
- if (originalValue !== val) {
438
- const itemSelector = getSelectorForId(child.props.id);
439
- if (!itemSelector) return;
440
- setPropertyByPath(child.props, toPaths[i], val);
441
- dispatch({
442
- type: "replace",
443
- data: child,
444
- destinationIndex: itemSelector == null ? void 0 : itemSelector.index,
445
- destinationZone: itemSelector == null ? void 0 : itemSelector.zone
446
- });
447
- }
448
- }
449
- });
450
- } else if (toPaths[0]) {
451
- const setting = getFieldSettingsByPath(
452
- debouncedFieldSettings,
453
- fromPaths.length === 1 ? fromPaths[0] : fromPaths.join(".")
454
- );
455
- const defaultValue = setting == null ? void 0 : setting.defaultValue;
456
- const originalValue = getFieldSettingsByPath(
457
- child.props,
458
- toPaths[0]
459
- );
460
- const finalValue = transform !== void 0 && value !== void 0 ? value : defaultValue !== void 0 ? defaultValue : value;
461
- if (originalValue !== finalValue) {
462
- const itemSelector = getSelectorForId(child.props.id);
463
- if (!itemSelector) return;
464
- setPropertyByPath(child.props, toPaths[0], finalValue);
465
- dispatch({
466
- type: "replace",
467
- data: child,
468
- destinationIndex: itemSelector == null ? void 0 : itemSelector.index,
469
- destinationZone: itemSelector == null ? void 0 : itemSelector.zone
470
- });
471
- }
472
- }
473
- });
825
+ getItemSummary(item, index) {
826
+ return item.name || `Field ${(index || 0) + 1}`;
827
+ },
828
+ arrayFields: {
829
+ name: { type: "text", label: "Name" },
830
+ type: {
831
+ type: "select",
832
+ label: "Type",
833
+ options: [
834
+ { label: "Text", value: "text" },
835
+ { label: "Textarea", value: "textarea" },
836
+ { label: "Number", value: "number" },
837
+ { label: "Select", value: "select" },
838
+ { label: "Radio", value: "radio" },
839
+ { label: "Array", value: "array" },
840
+ { label: "Object", value: "object" },
841
+ // { label: "Reference", value: "reference" },
842
+ ...customTypeOptions
843
+ ]
474
844
  }
475
- return child;
476
- })
477
- );
478
- }, [debouncedFieldSettings, data, dispatch, getSelectorForId, props._fieldSettings]);
479
- useEffect(() => {
480
- var _a;
481
- if (state !== "remodeling") return;
482
- if (!(props == null ? void 0 : props._version) || !(props == null ? void 0 : props._name)) return;
483
- const currentVersion = props == null ? void 0 : props._version;
484
- if (((_a = props._versions) == null ? void 0 : _a.includes(currentVersion)) && props._versions.length > 1) {
485
- setVersion(props._name, currentVersion, props, dispatch);
845
+ }
486
846
  }
487
- }, [props == null ? void 0 : props._version]);
488
- return /* @__PURE__ */ jsx2(Fragment, { children: props.children });
489
- }
490
- });
847
+ }, overrides.additionalRootFields || {}),
848
+ resolveFields({ props: data }, { fields, changed }) {
849
+ const newFields = __spreadValues({}, fields);
850
+ const rootFields = Array.isArray(
851
+ data == null ? void 0 : data._fields
852
+ ) ? (data == null ? void 0 : data._fields) || [] : [];
853
+ const rootFieldSettings = (data == null ? void 0 : data._fieldSettings) || {};
854
+ if (changed._fields || changed._fieldSettings) {
855
+ if (rootFields.length) {
856
+ newFields._fieldSettings = {
857
+ type: "object",
858
+ label: "Field Settings",
859
+ objectFields: get_field_settings_default(
860
+ rootFields,
861
+ rootFieldSettings,
862
+ customFields
863
+ )
864
+ };
865
+ } else {
866
+ delete newFields._fieldSettings;
867
+ }
868
+ }
869
+ return newFields;
870
+ },
871
+ // resolveData: (props, params) => {
872
+ // if (overrides.resolveRootData) {
873
+ // return overrides.resolveRootData(props, params, { editingComponent });
874
+ // }
875
+ // const result: {
876
+ // props: RootData<AsFieldProps<WithChildren<BuilderRootConfig>>>;
877
+ // readOnly: Readonly<Record<string, boolean>> | undefined;
878
+ // } = {
879
+ // props,
880
+ // readOnly: undefined,
881
+ // };
882
+ // return result;
883
+ // },
884
+ render: (props) => {
885
+ const fieldSettings = props == null ? void 0 : props._fieldSettings;
886
+ const data = useCustomPuck((s) => s.appState.data);
887
+ const dispatch = useCustomPuck((s) => s.dispatch);
888
+ const getSelectorForId = useCustomPuck((s) => s.getSelectorForId);
889
+ const setVersion = useSoftConfig((s) => s.builder.setVersion);
890
+ const state = useSoftConfig((s) => s.state);
891
+ useEffect(() => {
892
+ if (!fieldSettings || Object.keys(fieldSettings).length === 0) return;
893
+ const replacements = [];
894
+ walkTree(
895
+ {
896
+ content: (data == null ? void 0 : data.content) || [],
897
+ root: (data == null ? void 0 : data.root) || {}
898
+ },
899
+ {
900
+ components: config.components
901
+ },
902
+ (content) => content.map((child) => {
903
+ var _a;
904
+ const map = ((_a = child.props) == null ? void 0 : _a._map) || [];
905
+ if (!map.length) return child;
906
+ const cleanProps = getSerializableProps(child.props);
907
+ const { newProps, changed } = applyMapping(
908
+ cleanProps,
909
+ fieldSettings,
910
+ map,
911
+ "fieldSettings"
912
+ );
913
+ if (!changed || equal2(cleanProps, newProps)) return child;
914
+ replacements.push({
915
+ id: child.props.id,
916
+ data: __spreadProps(__spreadValues({}, child), { props: newProps })
917
+ });
918
+ return child;
919
+ })
920
+ );
921
+ if (!replacements.length) return;
922
+ replacements.forEach((replacement) => {
923
+ const itemSelector = getSelectorForId(replacement.id);
924
+ if (!itemSelector) return;
925
+ dispatch({
926
+ type: "replace",
927
+ data: replacement.data,
928
+ destinationIndex: itemSelector.index,
929
+ destinationZone: itemSelector.zone
930
+ });
931
+ });
932
+ }, [fieldSettings, data, dispatch, getSelectorForId]);
933
+ useEffect(() => {
934
+ var _a;
935
+ if (state !== "remodeling" || !(props == null ? void 0 : props._version) || !(props == null ? void 0 : props._name)) return;
936
+ const currentVersion = props._version;
937
+ if (((_a = props._versions) == null ? void 0 : _a.includes(currentVersion)) && props._versions.length > 1) {
938
+ setVersion(props._name, currentVersion, props, dispatch);
939
+ }
940
+ }, [props == null ? void 0 : props._version]);
941
+ return /* @__PURE__ */ jsx2(Fragment, { children: props.children });
942
+ }
943
+ };
944
+ };
491
945
 
492
946
  // src/puck/lib/builder/generate-field-options.ts
493
- function generateFieldOptions(fields, selectedFields, prefix = "") {
947
+ var hasArrayMappingPath = (value) => value.includes("[]");
948
+ var isBareArrayPath = (value) => !hasArrayMappingPath(value) && !value.includes(".");
949
+ function filterToOptionsForFrom(fromPath, toOptions) {
950
+ if (!fromPath) return toOptions;
951
+ const fromHasArrayMapping = hasArrayMappingPath(fromPath);
952
+ const fromIsBareArray = isBareArrayPath(fromPath);
953
+ return toOptions.filter((option) => {
954
+ const optionHasArrayMapping = hasArrayMappingPath(option.value);
955
+ if (fromHasArrayMapping) {
956
+ return optionHasArrayMapping;
957
+ }
958
+ if (fromIsBareArray) {
959
+ return isBareArrayPath(option.value);
960
+ }
961
+ return !optionHasArrayMapping;
962
+ });
963
+ }
964
+ function generateFieldOptions(fields, prefix = "") {
494
965
  const opts = [];
495
966
  function recurse(current, prefix2) {
496
967
  Object.entries(current).forEach(([key, fld]) => {
@@ -498,36 +969,68 @@ function generateFieldOptions(fields, selectedFields, prefix = "") {
498
969
  if (key === "_map") return;
499
970
  if (key === "_slotEnabled") return;
500
971
  const path = prefix2 ? `${prefix2}.${key}` : key;
501
- if (selectedFields.includes(path)) {
502
- return;
503
- }
504
- opts.push({ label: path, value: path, type: fld.type });
505
972
  if (fld.type === "object" && fld.objectFields) {
506
973
  recurse(fld.objectFields, path);
507
- }
508
- if (fld.type === "array" && fld.arrayFields) {
509
- recurse(fld.arrayFields, path);
974
+ } else if (fld.type === "array" && fld.arrayFields) {
975
+ recurse(
976
+ fld.arrayFields,
977
+ path + "[]"
978
+ );
979
+ } else {
980
+ opts.push({ label: path, value: path, type: fld.type });
510
981
  }
511
982
  });
512
983
  }
513
984
  recurse(fields, prefix);
514
985
  return opts;
515
986
  }
516
- function generateDynamicFieldOptions(_fields, _fieldSettings, prefix = "") {
987
+ function generateDynamicFieldOptions(_fields, _fieldSettings, customFields, prefix = "") {
517
988
  const opts = [];
518
- if (!_fields || !_fieldSettings) return opts;
989
+ if (!_fields) return opts;
519
990
  function recurse(fields, fieldSettings, currentPrefix) {
520
991
  fields.forEach((field) => {
521
992
  var _a;
522
993
  const settings = fieldSettings[field.name];
994
+ const customReturnType = resolveCustomFieldReturnType(
995
+ field.type,
996
+ customFields
997
+ );
523
998
  const path = currentPrefix ? `${currentPrefix}.${field.name}` : field.name;
524
- opts.push({ label: path, value: path, type: field.type });
999
+ if (customReturnType) {
1000
+ if (customReturnType === "array" || customReturnType === "object") {
1001
+ const customSchema = resolveCustomFieldSchema(field.type, customFields);
1002
+ if (!customSchema) {
1003
+ return;
1004
+ }
1005
+ recurse(
1006
+ customSchema.subFields,
1007
+ customSchema.subFieldSettings,
1008
+ path + (customReturnType === "array" ? "[]" : "")
1009
+ );
1010
+ return;
1011
+ }
1012
+ opts.push({
1013
+ label: path,
1014
+ value: path,
1015
+ type: mapCustomReturnTypeToMappingType(customReturnType)
1016
+ });
1017
+ return;
1018
+ }
1019
+ if (!isBuiltInSoftFieldType(field.type)) {
1020
+ return;
1021
+ }
525
1022
  if ((_a = settings == null ? void 0 : settings.subFields) == null ? void 0 : _a.length) {
526
- recurse(settings.subFields, settings.subFieldSettings || {}, path);
1023
+ recurse(
1024
+ settings.subFields,
1025
+ settings.subFieldSettings || {},
1026
+ path + (field.type === "array" ? "[]" : "")
1027
+ );
1028
+ } else if (field.type !== "array" && field.type !== "object") {
1029
+ opts.push({ label: path, value: path, type: field.type });
527
1030
  }
528
1031
  });
529
1032
  }
530
- recurse(_fields, _fieldSettings, prefix);
1033
+ recurse(_fields, _fieldSettings || {}, prefix);
531
1034
  return opts;
532
1035
  }
533
1036
 
@@ -619,8 +1122,14 @@ var ErrorBoundary = class extends Component {
619
1122
 
620
1123
  // src/puck/lib/builder/builder-config.tsx
621
1124
  import { jsx as jsx4 } from "react/jsx-runtime";
622
- var builderConfig = (config, overrides, editingComponent, showVersionFields = true, dependents) => ({
623
- root: builderRootConfig(config, overrides, editingComponent, showVersionFields),
1125
+ var builderConfig = (config, overrides, editingComponent, showVersionFields = true, dependents, customFields) => ({
1126
+ root: builderRootConfig(
1127
+ config,
1128
+ overrides,
1129
+ editingComponent,
1130
+ showVersionFields,
1131
+ customFields
1132
+ ),
624
1133
  components: Object.entries(__spreadValues({}, config.components)).reduce(
625
1134
  (acc, [name, component]) => {
626
1135
  const tempComponent = __spreadProps(__spreadValues({}, component), {
@@ -629,6 +1138,7 @@ var builderConfig = (config, overrides, editingComponent, showVersionFields = tr
629
1138
  },
630
1139
  resolveFields(data, params) {
631
1140
  return __async(this, null, function* () {
1141
+ var _a2;
632
1142
  let fields = {};
633
1143
  if (!fields._slot) {
634
1144
  const slotFields = Object.entries(params.fields).filter(
@@ -649,8 +1159,8 @@ var builderConfig = (config, overrides, editingComponent, showVersionFields = tr
649
1159
  { label: "Select a slot", value: "" },
650
1160
  ...slotFields.filter(
651
1161
  ([fieldName, field]) => {
652
- var _a2;
653
- return field.type === "slot" && !(((_a2 = data.props) == null ? void 0 : _a2._slot) || []).some(
1162
+ var _a3;
1163
+ return field.type === "slot" && !(((_a3 = data.props) == null ? void 0 : _a3._slot) || []).some(
654
1164
  (s) => s.slot === fieldName
655
1165
  );
656
1166
  }
@@ -669,17 +1179,21 @@ var builderConfig = (config, overrides, editingComponent, showVersionFields = tr
669
1179
  };
670
1180
  }
671
1181
  const defaultFields = component.resolveFields ? yield component.resolveFields(data, params) : component.fields || {};
672
- if (!fields._map) {
1182
+ if (!fields._map || params.changed._map) {
673
1183
  const rootProps = getRootProps(params.appState);
674
1184
  const fromOptions = generateDynamicFieldOptions(
675
1185
  (rootProps == null ? void 0 : rootProps._fields) || [],
676
- (rootProps == null ? void 0 : rootProps._fieldSettings) || {}
1186
+ (rootProps == null ? void 0 : rootProps._fieldSettings) || {},
1187
+ customFields
677
1188
  );
678
- const toOptions = generateFieldOptions(defaultFields, []);
1189
+ const toOptionsFields = component.resolveFields && ((_a2 = data.props) == null ? void 0 : _a2._map) ? yield component.resolveFields(
1190
+ __spreadProps(__spreadValues({}, data), { props: __spreadProps(__spreadValues({}, data.props), { _map: void 0 }) }),
1191
+ params
1192
+ ) : defaultFields;
1193
+ const toOptions = generateFieldOptions(toOptionsFields);
679
1194
  fields._map = overrides.map ? {
680
1195
  type: "custom",
681
1196
  render: ({ value, onChange, id }) => {
682
- const toOptions2 = generateFieldOptions(defaultFields, []);
683
1197
  const rootProps2 = getRootProps(params.appState);
684
1198
  return overrides.map({
685
1199
  rootProps: rootProps2,
@@ -688,13 +1202,39 @@ var builderConfig = (config, overrides, editingComponent, showVersionFields = tr
688
1202
  id,
689
1203
  props: data.props || {},
690
1204
  fromOptions,
691
- toOptions: toOptions2
1205
+ toOptions
1206
+ });
1207
+ }
1208
+ } : (() => {
1209
+ var _a3;
1210
+ const mapEntries = ((_a3 = data.props) == null ? void 0 : _a3._map) || [];
1211
+ const toPaths = mapEntries.flatMap(
1212
+ (entry) => Array.isArray(entry.to) ? entry.to : entry.to ? [entry.to] : []
1213
+ );
1214
+ const toPath = toPaths.find(
1215
+ (path) => typeof path === "string" && isArrayMappingPath(path)
1216
+ );
1217
+ const arrayBaseName = toPath ? getArrayBasePath(toPath) : null;
1218
+ const targetArrayField = arrayBaseName ? defaultFields[arrayBaseName] : null;
1219
+ const mappedSubProps = /* @__PURE__ */ new Set();
1220
+ if (arrayBaseName) {
1221
+ toPaths.forEach((path) => {
1222
+ if (typeof path !== "string") return;
1223
+ if (getArrayBasePath(path) !== arrayBaseName) return;
1224
+ const subProp = getArrayItemSubPath(path);
1225
+ if (subProp) mappedSubProps.add(subProp);
692
1226
  });
693
1227
  }
694
- } : {
695
- type: "array",
696
- label: "Dynamic Field Map",
697
- arrayFields: {
1228
+ const defaultValueFields = {};
1229
+ if (targetArrayField && targetArrayField.type === "array" && targetArrayField.arrayFields) {
1230
+ const arrayFields = targetArrayField.arrayFields;
1231
+ Object.entries(arrayFields).forEach(([key, fld]) => {
1232
+ if (mappedSubProps.has(key)) return;
1233
+ if (fld.type === "array" || fld.type === "object" || fld.type === "slot") return;
1234
+ defaultValueFields[key] = __spreadProps(__spreadValues({}, fld), { label: fld.label || key });
1235
+ });
1236
+ }
1237
+ const baseArrayFields = {
698
1238
  from: {
699
1239
  type: "select",
700
1240
  label: "From",
@@ -717,47 +1257,57 @@ var builderConfig = (config, overrides, editingComponent, showVersionFields = tr
717
1257
  }))
718
1258
  ]
719
1259
  }
1260
+ };
1261
+ if (arrayBaseName && Object.keys(defaultValueFields).length > 0) {
1262
+ baseArrayFields.unmappedArrayItemDefaultValues = {
1263
+ type: "object",
1264
+ label: "Default Item Values",
1265
+ objectFields: defaultValueFields
1266
+ };
720
1267
  }
721
- };
1268
+ return {
1269
+ type: "array",
1270
+ label: "Dynamic Field Map",
1271
+ arrayFields: baseArrayFields
1272
+ };
1273
+ })();
722
1274
  }
723
1275
  fields = __spreadValues(__spreadValues({}, fields), defaultFields);
724
1276
  return fields;
725
1277
  });
726
1278
  },
727
1279
  resolveData: ({ props }, { lastData }) => {
728
- var _a2;
729
- const _map = props._map || [];
1280
+ const _map = (props._map || []).map((item) => {
1281
+ const newItem = __spreadValues({}, item);
1282
+ if (typeof newItem.unmappedArrayItemDefaultValues === "string") {
1283
+ try {
1284
+ newItem.unmappedArrayItemDefaultValues = JSON.parse(
1285
+ newItem.unmappedArrayItemDefaultValues
1286
+ );
1287
+ } catch (e) {
1288
+ newItem.unmappedArrayItemDefaultValues = {};
1289
+ }
1290
+ } else if (!newItem.unmappedArrayItemDefaultValues) {
1291
+ newItem.unmappedArrayItemDefaultValues = {};
1292
+ }
1293
+ return newItem;
1294
+ });
730
1295
  const readOnlyFields = _map.flatMap((item) => item.to);
1296
+ const readOnlyArrayBases = readOnlyFields.filter((field) => typeof field === "string").map(getArrayBasePath).filter((base) => base !== null);
731
1297
  if (_map.length) {
732
1298
  return {
733
- props,
734
- readOnly: readOnlyFields.reduce(
1299
+ props: __spreadProps(__spreadValues({}, props), { _map }),
1300
+ readOnly: [
1301
+ ...readOnlyFields.map((f) => String(f)),
1302
+ ...readOnlyArrayBases
1303
+ ].reduce(
735
1304
  (acc2, field) => __spreadProps(__spreadValues({}, acc2), { [field]: true }),
736
1305
  {}
737
1306
  )
738
1307
  };
739
1308
  }
740
- const prevMap = (_a2 = lastData == null ? void 0 : lastData.props) == null ? void 0 : _a2._map;
741
- if (prevMap && prevMap.length === 1) {
742
- const lastField = prevMap[0].to;
743
- if (typeof lastField === "string") {
744
- return {
745
- props,
746
- readOnly: { [lastField]: false }
747
- };
748
- }
749
- if (Array.isArray(lastField)) {
750
- return {
751
- props,
752
- readOnly: lastField.reduce(
753
- (acc2, field) => __spreadProps(__spreadValues({}, acc2), { [String(field)]: false }),
754
- {}
755
- )
756
- };
757
- }
758
- }
759
1309
  return {
760
- props,
1310
+ props: __spreadProps(__spreadValues({}, props), { _map }),
761
1311
  readOnly: {}
762
1312
  };
763
1313
  },
@@ -773,6 +1323,9 @@ var builderConfig = (config, overrides, editingComponent, showVersionFields = tr
773
1323
  categories: config.categories || {}
774
1324
  });
775
1325
 
1326
+ // src/puck/lib/soft-component-constants.ts
1327
+ var TECHNICAL_KEYS = /* @__PURE__ */ new Set(["_map", "_slot", "id", "_version"]);
1328
+
776
1329
  // src/puck/lib/strip-id.ts
777
1330
  var stripIdFromProps = (components, allowedTypes) => {
778
1331
  return components.map((component) => sanitizeComponent(component, allowedTypes));
@@ -796,7 +1349,7 @@ var sanitizeComponent = (component, allowedTypes) => {
796
1349
  var getSubComponents = (content, componentConfigs, fieldSettings, slots) => {
797
1350
  if (!content || !Array.isArray(content)) return [];
798
1351
  return content.map((componentProps) => {
799
- var _a, _b, _c;
1352
+ var _a, _b, _c, _d;
800
1353
  const componentConfig = componentConfigs[componentProps.type];
801
1354
  const enabledSlotNames = new Set(
802
1355
  (((_a = componentProps.props) == null ? void 0 : _a._slot) || []).map((s) => s.slot)
@@ -817,7 +1370,27 @@ var getSubComponents = (content, componentConfigs, fieldSettings, slots) => {
817
1370
  },
818
1371
  {}
819
1372
  ) || {};
820
- const fixedProps = __spreadValues(__spreadValues({}, componentConfig == null ? void 0 : componentConfig.defaultProps), componentProps.props);
1373
+ const map = ((_b = componentProps.props) == null ? void 0 : _b._map) || [];
1374
+ const mappedPaths = /* @__PURE__ */ new Set();
1375
+ map.forEach((item) => {
1376
+ const to = Array.isArray(item.to) ? item.to : [item.to];
1377
+ to.forEach((path) => {
1378
+ if (path) {
1379
+ if (isArrayMappingPath(path)) {
1380
+ const basePath = getArrayBasePath(path);
1381
+ if (basePath) mappedPaths.add(basePath);
1382
+ } else {
1383
+ mappedPaths.add(path);
1384
+ }
1385
+ }
1386
+ });
1387
+ });
1388
+ const fixedProps = Object.entries(__spreadValues(__spreadValues({}, componentConfig == null ? void 0 : componentConfig.defaultProps), componentProps.props)).reduce((acc, [key, value]) => {
1389
+ if (!TECHNICAL_KEYS.has(key) && !mappedPaths.has(key)) {
1390
+ acc[key] = value;
1391
+ }
1392
+ return acc;
1393
+ }, {});
821
1394
  (componentProps.props._slot || []).forEach(
822
1395
  (s) => {
823
1396
  var _a2;
@@ -831,19 +1404,34 @@ var getSubComponents = (content, componentConfigs, fieldSettings, slots) => {
831
1404
  }
832
1405
  );
833
1406
  const subComponent = {
834
- map: ((_b = componentProps.props) == null ? void 0 : _b._map) || [],
1407
+ map: ((_c = componentProps.props) == null ? void 0 : _c._map) || [],
835
1408
  fixedProps,
836
1409
  type: componentProps.type,
837
1410
  components,
838
- enabledSlots: ((_c = componentProps.props) == null ? void 0 : _c._slot) || []
1411
+ enabledSlots: ((_d = componentProps.props) == null ? void 0 : _d._slot) || []
839
1412
  };
840
1413
  return subComponent;
841
1414
  });
842
1415
  };
843
- var softFieldsToPuckFields = (fields, fieldSettings) => {
1416
+ var softFieldsToPuckFields = (fields, fieldSettings, customFields) => {
844
1417
  return (fields == null ? void 0 : fields.reduce(
845
1418
  (acc, field) => {
846
- var _a, _b, _c, _d, _e, _f, _g, _h;
1419
+ var _a, _b, _c, _d, _e, _f;
1420
+ const customFieldDefinition = resolveCustomFieldDefinition(
1421
+ field.type,
1422
+ customFields
1423
+ );
1424
+ const customReturnType = resolveCustomFieldReturnType(
1425
+ field.type,
1426
+ customFields
1427
+ );
1428
+ if (customFieldDefinition && customReturnType) {
1429
+ acc[field.name] = __spreadProps(__spreadValues({}, customFieldDefinition.field), {
1430
+ type: "custom",
1431
+ label: customFieldDefinition.field.label || field.name
1432
+ });
1433
+ return acc;
1434
+ }
847
1435
  switch (field.type) {
848
1436
  case "text":
849
1437
  case "textarea":
@@ -868,13 +1456,24 @@ var softFieldsToPuckFields = (fields, fieldSettings) => {
868
1456
  break;
869
1457
  // TODO: Default item props
870
1458
  case "array":
1459
+ const currentArraySettings = (fieldSettings == null ? void 0 : fieldSettings[field.name]) || {};
871
1460
  acc[field.name] = {
872
1461
  type: field.type,
873
1462
  label: field.name,
1463
+ min: currentArraySettings.min,
1464
+ max: currentArraySettings.max,
874
1465
  arrayFields: softFieldsToPuckFields(
875
- ((_e = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _e.subFields) || [],
876
- ((_f = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _f.subFieldSettings) || {}
877
- )
1466
+ currentArraySettings.subFields || [],
1467
+ currentArraySettings.subFieldSettings || {},
1468
+ customFields
1469
+ ),
1470
+ defaultItemProps: buildArrayDefaultItemProps(
1471
+ currentArraySettings.subFields,
1472
+ currentArraySettings.subFieldSettings
1473
+ ),
1474
+ getItemSummary(item, index) {
1475
+ return getArrayItemSummary(item, index, currentArraySettings);
1476
+ }
878
1477
  };
879
1478
  break;
880
1479
  // TODO: Needs testing to see if it works
@@ -883,8 +1482,9 @@ var softFieldsToPuckFields = (fields, fieldSettings) => {
883
1482
  type: field.type,
884
1483
  label: field.name,
885
1484
  objectFields: softFieldsToPuckFields(
886
- ((_g = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _g.subFields) || [],
887
- ((_h = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _h.subFieldSettings) || {}
1485
+ ((_e = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _e.subFields) || [],
1486
+ ((_f = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _f.subFieldSettings) || {},
1487
+ customFields
888
1488
  )
889
1489
  };
890
1490
  break;
@@ -896,11 +1496,34 @@ var softFieldsToPuckFields = (fields, fieldSettings) => {
896
1496
  {}
897
1497
  )) || {};
898
1498
  };
899
- var softComponentFromAppState = (appState, configComponents, editedItem, metadata) => {
1499
+ var softComponentFromAppState = (appState, configComponents, editedItem, metadata, customFields) => {
900
1500
  var _a;
901
1501
  const rootProps = ((_a = appState.data.root) == null ? void 0 : _a.props) || {};
902
1502
  const fields = rootProps._fields || [];
903
1503
  const field_settings = rootProps._fieldSettings || {};
1504
+ const normalizedFieldSettings = __spreadValues({}, field_settings);
1505
+ (fields || []).forEach((field) => {
1506
+ const customFieldDefinition = resolveCustomFieldDefinition(
1507
+ field.type,
1508
+ customFields
1509
+ );
1510
+ const customReturnType = resolveCustomFieldReturnType(
1511
+ field.type,
1512
+ customFields
1513
+ );
1514
+ if (!customFieldDefinition || !customReturnType) {
1515
+ return;
1516
+ }
1517
+ const schema = resolveCustomFieldSchema(field.type, customFields);
1518
+ const existingSettings = normalizedFieldSettings[field.name] || {};
1519
+ normalizedFieldSettings[field.name] = __spreadValues(__spreadProps(__spreadValues({}, existingSettings), {
1520
+ customFieldType: field.type,
1521
+ customFieldReturnType: customReturnType
1522
+ }), schema ? {
1523
+ subFields: schema.subFields,
1524
+ subFieldSettings: schema.subFieldSettings
1525
+ } : {});
1526
+ });
904
1527
  const builtInRootProps = /* @__PURE__ */ new Set([
905
1528
  "_name",
906
1529
  "_category",
@@ -920,12 +1543,22 @@ var softComponentFromAppState = (appState, configComponents, editedItem, metadat
920
1543
  const components = getSubComponents(
921
1544
  [editedItem],
922
1545
  configComponents,
923
- field_settings,
1546
+ normalizedFieldSettings,
924
1547
  slots
925
1548
  );
926
- const defaultProps = __spreadValues(__spreadValues({}, Object.keys(field_settings).reduce(
1549
+ const defaultProps = __spreadValues(__spreadValues({}, Object.keys(normalizedFieldSettings).reduce(
927
1550
  (acc, field) => {
928
- acc[field] = field_settings[field].defaultValue;
1551
+ var _a2;
1552
+ const fieldDefinition = (fields || []).find((item) => item.name === field);
1553
+ const customFieldReturnType = (_a2 = normalizedFieldSettings[field]) == null ? void 0 : _a2.customFieldReturnType;
1554
+ if ((fieldDefinition == null ? void 0 : fieldDefinition.type) === "array" || customFieldReturnType === "array") {
1555
+ acc[field] = normalizedFieldSettings[field].defaultValue !== void 0 ? normalizedFieldSettings[field].defaultValue : buildArrayDefaultValue(
1556
+ normalizedFieldSettings[field].subFields,
1557
+ normalizedFieldSettings[field].subFieldSettings
1558
+ );
1559
+ return acc;
1560
+ }
1561
+ acc[field] = normalizedFieldSettings[field].defaultValue;
929
1562
  return acc;
930
1563
  },
931
1564
  {}
@@ -934,11 +1567,11 @@ var softComponentFromAppState = (appState, configComponents, editedItem, metadat
934
1567
  {
935
1568
  name: metadata.name,
936
1569
  category: metadata.category,
937
- fields: __spreadValues(__spreadValues({}, softFieldsToPuckFields(fields, field_settings)), Object.keys(slots).reduce((acc, slot) => {
1570
+ fields: __spreadValues(__spreadValues({}, softFieldsToPuckFields(fields, normalizedFieldSettings, customFields)), Object.keys(slots).reduce((acc, slot) => {
938
1571
  acc[slot] = { type: "slot", label: slot };
939
1572
  return acc;
940
1573
  }, {})),
941
- fieldSettings: field_settings,
1574
+ fieldSettings: normalizedFieldSettings,
942
1575
  defaultProps,
943
1576
  rootProps: customRootProps,
944
1577
  components,
@@ -964,23 +1597,55 @@ var createComponentKeyFromName = (displayName, overrides, context) => {
964
1597
  return key.trim();
965
1598
  };
966
1599
  var getComponentNameFromKey = (key, overrides) => {
967
- if (overrides.componentKeyToName) {
1600
+ if (overrides == null ? void 0 : overrides.componentKeyToName) {
968
1601
  return overrides.componentKeyToName(key);
969
1602
  }
970
1603
  return key;
971
1604
  };
972
1605
 
973
1606
  // src/puck/lib/soft-component-to-appstate.ts
974
- var puckFieldsToSoftFields = (fields, slots) => {
1607
+ var mergeFieldSettings = (generated = {}, persisted = {}) => {
1608
+ return Object.entries(persisted).reduce((acc, [fieldName, value]) => {
1609
+ const current = acc[fieldName] || {};
1610
+ acc[fieldName] = __spreadProps(__spreadValues(__spreadValues({}, current), value), {
1611
+ subFieldSettings: current.subFieldSettings || (value == null ? void 0 : value.subFieldSettings) ? mergeFieldSettings(
1612
+ current.subFieldSettings || {},
1613
+ (value == null ? void 0 : value.subFieldSettings) || {}
1614
+ ) : void 0
1615
+ });
1616
+ return acc;
1617
+ }, __spreadValues({}, generated));
1618
+ };
1619
+ var puckFieldsToSoftFields = (fields, slots, persistedFieldSettings = {}, customFields) => {
975
1620
  const softFields = [];
976
1621
  const fieldSettings = {};
977
1622
  Object.entries(fields).forEach(([fieldName, field]) => {
1623
+ var _a;
1624
+ const persistedSettings = persistedFieldSettings == null ? void 0 : persistedFieldSettings[fieldName];
1625
+ const fieldWithMeta = field;
1626
+ const customFieldType = fieldWithMeta.customFieldType || (persistedSettings == null ? void 0 : persistedSettings.customFieldType);
1627
+ const customFieldReturnType = fieldWithMeta.customFieldReturnType || (persistedSettings == null ? void 0 : persistedSettings.customFieldReturnType) || (customFieldType ? (_a = customFields == null ? void 0 : customFields[customFieldType]) == null ? void 0 : _a.returnType : void 0);
978
1628
  if (slots.has(fieldName)) {
979
1629
  return;
980
1630
  }
981
1631
  if (fieldName === "_version") {
982
1632
  return;
983
1633
  }
1634
+ if (field.type === "custom" && customFieldType) {
1635
+ softFields.push({ name: fieldName, type: customFieldType });
1636
+ const customSchema = resolveCustomFieldSchema(customFieldType, customFields);
1637
+ fieldSettings[fieldName] = __spreadValues(__spreadProps(__spreadValues({}, persistedSettings || {}), {
1638
+ customFieldType,
1639
+ customFieldReturnType
1640
+ }), customSchema ? {
1641
+ subFields: customSchema.subFields,
1642
+ subFieldSettings: customSchema.subFieldSettings
1643
+ } : {});
1644
+ if (!Object.prototype.hasOwnProperty.call(fieldSettings[fieldName], "defaultValue")) {
1645
+ fieldSettings[fieldName].defaultValue = void 0;
1646
+ }
1647
+ return;
1648
+ }
984
1649
  switch (field.type) {
985
1650
  case "text":
986
1651
  case "textarea":
@@ -998,67 +1663,81 @@ var puckFieldsToSoftFields = (fields, slots) => {
998
1663
  case "radio":
999
1664
  softFields.push({ name: fieldName, type: field.type });
1000
1665
  fieldSettings[fieldName] = {
1001
- options: field.options || []
1666
+ options: field.options ? [...field.options] : []
1002
1667
  };
1003
1668
  break;
1004
1669
  case "array":
1005
1670
  softFields.push({ name: fieldName, type: "array" });
1006
1671
  const arrayFieldsResult = puckFieldsToSoftFields(
1007
1672
  field.arrayFields || {},
1008
- /* @__PURE__ */ new Set()
1673
+ /* @__PURE__ */ new Set(),
1674
+ persistedSettings == null ? void 0 : persistedSettings.subFieldSettings,
1675
+ customFields
1009
1676
  );
1010
- fieldSettings[fieldName] = {
1677
+ fieldSettings[fieldName] = __spreadProps(__spreadValues({}, persistedSettings || {}), {
1011
1678
  subFields: arrayFieldsResult.fields,
1012
1679
  subFieldSettings: arrayFieldsResult.fieldSettings
1013
- };
1680
+ });
1014
1681
  break;
1015
1682
  case "object":
1016
1683
  softFields.push({ name: fieldName, type: "object" });
1017
1684
  const objectFieldsResult = puckFieldsToSoftFields(
1018
1685
  field.objectFields || {},
1019
- /* @__PURE__ */ new Set()
1686
+ /* @__PURE__ */ new Set(),
1687
+ persistedSettings == null ? void 0 : persistedSettings.subFieldSettings,
1688
+ customFields
1020
1689
  );
1021
- fieldSettings[fieldName] = {
1690
+ fieldSettings[fieldName] = __spreadProps(__spreadValues({}, persistedSettings || {}), {
1022
1691
  subFields: objectFieldsResult.fields,
1023
1692
  subFieldSettings: objectFieldsResult.fieldSettings
1024
- };
1693
+ });
1025
1694
  break;
1026
1695
  default:
1027
1696
  softFields.push({ name: fieldName, type: "text" });
1028
1697
  }
1029
- if (fieldSettings[fieldName]) {
1030
- fieldSettings[fieldName].defaultValue = void 0;
1031
- } else {
1032
- fieldSettings[fieldName] = { defaultValue: void 0 };
1033
- }
1698
+ fieldSettings[fieldName] = __spreadProps(__spreadValues({}, fieldSettings[fieldName] || persistedSettings || {}), {
1699
+ defaultValue: Object.prototype.hasOwnProperty.call(
1700
+ fieldSettings[fieldName] || persistedSettings || {},
1701
+ "defaultValue"
1702
+ ) ? (fieldSettings[fieldName] || persistedSettings || {}).defaultValue : void 0
1703
+ });
1034
1704
  });
1035
1705
  return { fields: softFields, fieldSettings };
1036
1706
  };
1037
1707
  var reconstructComponents = (subComponents, componentConfigs, softComponentProps) => {
1038
1708
  return subComponents.map((subComponent) => {
1039
- var _a;
1040
- const props = __spreadValues({}, subComponent.fixedProps);
1041
- (_a = subComponent.map) == null ? void 0 : _a.forEach((mapItem, i) => {
1042
- var _a2;
1043
- const { from, to, transform } = mapItem || {};
1044
- const fromPaths = Array.isArray(from) ? from : from ? [from] : [];
1045
- const toPaths = Array.isArray(to) ? to : to ? [to] : [];
1046
- const inputs = fromPaths.map(
1047
- (path) => getFieldSettingsByPath(softComponentProps || {}, path)
1048
- );
1049
- const runner = transform;
1050
- const result = runner ? runner(inputs, softComponentProps) : inputs[0];
1051
- if (Array.isArray(result)) {
1052
- result.forEach((val, idx) => {
1053
- if (toPaths[idx]) setPropertyByPath(props, toPaths[idx], val);
1709
+ const componentConfig = componentConfigs[subComponent.type];
1710
+ const props = __spreadProps(__spreadValues({}, subComponent.fixedProps), {
1711
+ _map: subComponent.map
1712
+ });
1713
+ const arrayDefaults = (subComponent.map || []).reduce(
1714
+ (acc, mapEntry) => {
1715
+ const toPaths = Array.isArray(mapEntry.to) ? mapEntry.to : [mapEntry.to];
1716
+ toPaths.forEach((path) => {
1717
+ var _a;
1718
+ if (typeof path !== "string" || !isArrayMappingPath(path)) return;
1719
+ const arrayBase = getArrayBasePath(path);
1720
+ if (!arrayBase || acc[arrayBase]) return;
1721
+ const defaultValue = (_a = componentConfig == null ? void 0 : componentConfig.defaultProps) == null ? void 0 : _a[arrayBase];
1722
+ if (Array.isArray(defaultValue)) acc[arrayBase] = defaultValue;
1054
1723
  });
1055
- } else {
1056
- toPaths.forEach((toPath) => setPropertyByPath(props, toPath, result));
1057
- }
1058
- if (transform && ((_a2 = props._map) == null ? void 0 : _a2[i])) {
1059
- props._map[i].transform = transform;
1724
+ return acc;
1725
+ },
1726
+ {}
1727
+ );
1728
+ const sourceProps = __spreadValues(__spreadValues(__spreadValues({}, (componentConfig == null ? void 0 : componentConfig.defaultProps) || {}), softComponentProps), props);
1729
+ const { newProps } = applyMapping(
1730
+ props,
1731
+ {},
1732
+ // fieldSettings not needed for "propsFirst" mode as it resolves from propsFirst
1733
+ subComponent.map || [],
1734
+ "propsFirst",
1735
+ {
1736
+ sourceProps,
1737
+ arrayDefaults
1060
1738
  }
1061
- });
1739
+ );
1740
+ Object.assign(props, newProps);
1062
1741
  if (subComponent.enabledSlots.length > 0) {
1063
1742
  props._slot = subComponent.enabledSlots;
1064
1743
  subComponent.enabledSlots.forEach(({ slot, name }) => {
@@ -1088,16 +1767,33 @@ var reconstructComponents = (subComponents, componentConfigs, softComponentProps
1088
1767
  return componentData;
1089
1768
  });
1090
1769
  };
1091
- var softComponentToAppState = (softComponent, componentName, version, versions, componentProps, componentConfigs, overrides, displayName, category) => {
1770
+ var softComponentToAppState = (softComponent, componentName, version, versions, componentProps, componentConfigs, overrides, displayName, category, customFields) => {
1092
1771
  const slots = new Set(Object.keys(softComponent.slots));
1093
1772
  const { fields, fieldSettings } = puckFieldsToSoftFields(
1094
1773
  softComponent.fields,
1095
- slots
1774
+ slots,
1775
+ softComponent.fieldSettings,
1776
+ customFields
1096
1777
  );
1778
+ const mergedFieldSettings = mergeFieldSettings(
1779
+ fieldSettings,
1780
+ softComponent.fieldSettings || {}
1781
+ ) || {};
1097
1782
  Object.entries(softComponent.defaultProps).forEach(([key, value]) => {
1098
- if (fieldSettings && fieldSettings[key] && !slots.has(key)) {
1099
- fieldSettings[key].defaultValue = value;
1783
+ if (mergedFieldSettings && mergedFieldSettings[key] && !slots.has(key)) {
1784
+ mergedFieldSettings[key].defaultValue = value;
1785
+ }
1786
+ });
1787
+ (fields || []).forEach((field) => {
1788
+ if (field.type !== "array" || slots.has(field.name)) return;
1789
+ const settings = mergedFieldSettings[field.name] || {};
1790
+ if (settings.defaultValue === void 0) {
1791
+ settings.defaultValue = buildArrayDefaultValue(
1792
+ settings.subFields,
1793
+ settings.subFieldSettings
1794
+ );
1100
1795
  }
1796
+ mergedFieldSettings[field.name] = settings;
1101
1797
  });
1102
1798
  let rootProps = __spreadValues({
1103
1799
  _name: displayName || getComponentNameFromKey(componentName, overrides),
@@ -1105,7 +1801,7 @@ var softComponentToAppState = (softComponent, componentName, version, versions,
1105
1801
  _version: version,
1106
1802
  _versions: versions,
1107
1803
  _fields: fields,
1108
- _fieldSettings: fieldSettings
1804
+ _fieldSettings: mergedFieldSettings
1109
1805
  }, softComponent.rootProps || {});
1110
1806
  if (overrides.onRemodel) {
1111
1807
  rootProps = __spreadValues(__spreadValues({}, rootProps), overrides.onRemodel(componentName));
@@ -1131,12 +1827,12 @@ var rootZone = "default-zone";
1131
1827
  var rootDroppableId = `${rootAreaId}:${rootZone}`;
1132
1828
 
1133
1829
  // src/puck/components/soft-render/index.tsx
1134
- import React2, { useMemo, memo } from "react";
1135
- import equal from "react-fast-compare";
1830
+ import React3, { useMemo, memo } from "react";
1831
+ import equal3 from "react-fast-compare";
1136
1832
  import { Fragment as Fragment2, jsx as jsx5 } from "react/jsx-runtime";
1137
1833
  function isPlainObject(val) {
1138
1834
  if (typeof val !== "object" || val === null) return false;
1139
- if (React2.isValidElement(val)) return false;
1835
+ if (React3.isValidElement(val)) return false;
1140
1836
  if ("$$typeof" in val) return false;
1141
1837
  const proto = Object.getPrototypeOf(val);
1142
1838
  return proto === Object.prototype || proto === null;
@@ -1171,28 +1867,19 @@ var SubComponentRenderer = memo(
1171
1867
  if (!componentConfig) return {};
1172
1868
  const clonedProps = cloneData(subComponent.fixedProps || {});
1173
1869
  if ((_a = subComponent.map) == null ? void 0 : _a.length) {
1174
- subComponent.map.forEach((mapItem) => {
1175
- const { from, to, transform } = mapItem || {};
1176
- const fromPaths = Array.isArray(from) ? from : from ? [from] : [];
1177
- const toPaths = Array.isArray(to) ? to : to ? [to] : [];
1178
- const inputValues = fromPaths.map((f) => {
1179
- const propValue = getFieldSettingsByPath(props, f);
1180
- if (propValue !== void 0) return propValue;
1181
- const setting = getFieldSettingsByPath(softComponentFieldSettings || {}, f);
1182
- if (setting && Object.prototype.hasOwnProperty.call(setting, "defaultValue")) {
1183
- return setting.defaultValue;
1184
- }
1185
- return propValue;
1186
- });
1187
- const result = transform ? transform(inputValues, props) : inputValues[0];
1188
- if (Array.isArray(result)) {
1189
- result.forEach(
1190
- (val, i) => toPaths[i] && setPropertyByPath(clonedProps, toPaths[i], val)
1191
- );
1192
- } else if (toPaths[0]) {
1193
- setPropertyByPath(clonedProps, toPaths[0], result);
1870
+ const mergedInput = __spreadValues(__spreadValues({}, clonedProps), props);
1871
+ const { newProps } = applyMapping(
1872
+ mergedInput,
1873
+ softComponentFieldSettings || {},
1874
+ subComponent.map,
1875
+ "propsFirst"
1876
+ );
1877
+ const parentKeys = new Set(Object.keys(props));
1878
+ for (const [key, value] of Object.entries(newProps)) {
1879
+ if (!parentKeys.has(key) || key in clonedProps) {
1880
+ clonedProps[key] = value;
1194
1881
  }
1195
- });
1882
+ }
1196
1883
  }
1197
1884
  Object.entries(componentConfig.fields || {}).forEach(
1198
1885
  ([slotKey, field]) => {
@@ -1253,7 +1940,7 @@ var SubComponentRenderer = memo(
1253
1940
  // and on props (the primary driver of field-mapping changes).
1254
1941
  // configComponents and softComponentFields are treated as stable config
1255
1942
  // references — reference equality is intentional and fast here.
1256
- (prev, next) => prev.depth === next.depth && prev.index === next.index && prev.configComponents === next.configComponents && prev.softComponentFields === next.softComponentFields && equal(prev.props, next.props) && equal(prev.subComponent, next.subComponent) && equal(prev.softComponentFieldSettings, next.softComponentFieldSettings)
1943
+ (prev, next) => prev.depth === next.depth && prev.index === next.index && prev.configComponents === next.configComponents && prev.softComponentFields === next.softComponentFields && equal3(prev.props, next.props) && equal3(prev.subComponent, next.subComponent) && equal3(prev.softComponentFieldSettings, next.softComponentFieldSettings)
1257
1944
  );
1258
1945
  SubComponentRenderer.displayName = "SubComponentRenderer";
1259
1946
  var SoftRender = memo(
@@ -1287,13 +1974,32 @@ var SoftRender = memo(
1287
1974
  // configComponents / softComponentFields: reference equality (stable config).
1288
1975
  // softComponentFieldSettings: deep equality (may carry dynamic defaults).
1289
1976
  // props / softSubComponent: deep equality (primary render drivers).
1290
- (prev, next) => prev.configComponents === next.configComponents && prev.softComponentFields === next.softComponentFields && equal(prev.props, next.props) && equal(prev.softSubComponent, next.softSubComponent) && equal(prev.softComponentFieldSettings, next.softComponentFieldSettings)
1977
+ (prev, next) => prev.configComponents === next.configComponents && prev.softComponentFields === next.softComponentFields && equal3(prev.props, next.props) && equal3(prev.softSubComponent, next.softSubComponent) && equal3(prev.softComponentFieldSettings, next.softComponentFieldSettings)
1291
1978
  );
1292
1979
  SoftRender.displayName = "SoftRender";
1293
1980
 
1294
1981
  // src/puck/lib/create-versioned-component-config.tsx
1295
1982
  import { jsx as jsx6 } from "react/jsx-runtime";
1296
- var createVersionedComponentConfig = (componentName, displayName, version, allVersions, config, softComponents, defaultProps, showVersioning = true) => {
1983
+ var hydrateCustomField = (fieldName, field, fieldSettings, customFields) => {
1984
+ var _a;
1985
+ if (field.type !== "custom") {
1986
+ return field;
1987
+ }
1988
+ const fieldWithMeta = field;
1989
+ const customFieldType = fieldWithMeta.customFieldType || ((_a = fieldSettings == null ? void 0 : fieldSettings[fieldName]) == null ? void 0 : _a.customFieldType);
1990
+ if (!customFieldType) {
1991
+ return field;
1992
+ }
1993
+ const customField = customFields == null ? void 0 : customFields[customFieldType];
1994
+ if (!customField) {
1995
+ return field;
1996
+ }
1997
+ return __spreadProps(__spreadValues(__spreadValues({}, field), customField.field), {
1998
+ type: "custom",
1999
+ label: field.label || customField.field.label || fieldName
2000
+ });
2001
+ };
2002
+ var createVersionedComponentConfig = (componentName, displayName, version, allVersions, config, softComponents, defaultProps, showVersioning = true, customFields) => {
1297
2003
  var _a, _b;
1298
2004
  const softConfig = config;
1299
2005
  return {
@@ -1321,7 +2027,12 @@ var createVersionedComponentConfig = (componentName, displayName, version, allVe
1321
2027
  };
1322
2028
  }
1323
2029
  Object.entries((versionedComponent == null ? void 0 : versionedComponent.fields) || {}).filter(([, field]) => field.type !== "slot").forEach(([key, field]) => {
1324
- fields[key] = field;
2030
+ fields[key] = hydrateCustomField(
2031
+ key,
2032
+ field,
2033
+ versionedComponent == null ? void 0 : versionedComponent.fieldSettings,
2034
+ customFields
2035
+ );
1325
2036
  });
1326
2037
  return fields;
1327
2038
  },
@@ -1348,21 +2059,16 @@ var subComponentDecomposer = (componentRootData, softSubComponent) => {
1348
2059
  var _a;
1349
2060
  const resolvedProps = __spreadValues({}, softSubComponent.fixedProps);
1350
2061
  (_a = softSubComponent.map) == null ? void 0 : _a.forEach((mapItem) => {
1351
- const { from, to, transform } = mapItem || {};
1352
- const fromPaths = Array.isArray(from) ? from : from ? [from] : [];
1353
- const toPaths = Array.isArray(to) ? to : to ? [to] : [];
1354
- const inputs = fromPaths.map(
1355
- (path) => getFieldSettingsByPath(componentRootData.props || {}, path)
2062
+ const { newProps } = applyMapping(
2063
+ resolvedProps,
2064
+ {},
2065
+ [mapItem],
2066
+ "propsFirst",
2067
+ {
2068
+ sourceProps: componentRootData.props || {}
2069
+ }
1356
2070
  );
1357
- const runner = transform;
1358
- const result = runner ? runner(inputs, componentRootData.props) : inputs[0];
1359
- if (Array.isArray(result)) {
1360
- result.forEach((val, idx) => {
1361
- if (toPaths[idx]) setPropertyByPath(resolvedProps, toPaths[idx], val);
1362
- });
1363
- } else if (toPaths[0]) {
1364
- setPropertyByPath(resolvedProps, toPaths[0], result);
1365
- }
2071
+ Object.assign(resolvedProps, newProps);
1366
2072
  });
1367
2073
  softSubComponent.enabledSlots.forEach(({ slot, name }) => {
1368
2074
  var _a2, _b;
@@ -1385,9 +2091,22 @@ var subComponentDecomposer = (componentRootData, softSubComponent) => {
1385
2091
  return accItem;
1386
2092
  };
1387
2093
 
2094
+ // src/puck/lib/builder/resolve-soft-component-data.ts
2095
+ var resolveSoftComponentData = (props, _fieldSettings = {}) => {
2096
+ const map = props._map;
2097
+ if (!(map == null ? void 0 : map.length)) return __spreadValues({}, props);
2098
+ const { newProps } = applyMapping(
2099
+ props,
2100
+ _fieldSettings,
2101
+ map,
2102
+ "propsFirst"
2103
+ );
2104
+ return newProps;
2105
+ };
2106
+
1388
2107
  // src/puck/lib/decompose-soft-component.ts
1389
- function decomposeSoftComponent(componentData, softComponents) {
1390
- var _a, _b;
2108
+ function decomposeSoftComponent(componentData, softComponents, fieldSettings) {
2109
+ var _a, _b, _c, _d;
1391
2110
  if (!(componentData == null ? void 0 : componentData.type) || !(componentData == null ? void 0 : componentData.props.id)) {
1392
2111
  throw new Error("Component data must have type and id to decompose.");
1393
2112
  }
@@ -1398,9 +2117,19 @@ function decomposeSoftComponent(componentData, softComponents) {
1398
2117
  `Soft component "${componentData.type}" version "${version}" not found.`
1399
2118
  );
1400
2119
  }
2120
+ let resolvedComponentData = componentData;
2121
+ if (fieldSettings && ((_d = (_c = componentData.props) == null ? void 0 : _c._map) == null ? void 0 : _d.length)) {
2122
+ const resolvedProps = resolveSoftComponentData(
2123
+ componentData.props,
2124
+ fieldSettings
2125
+ );
2126
+ resolvedComponentData = __spreadProps(__spreadValues({}, componentData), {
2127
+ props: resolvedProps
2128
+ });
2129
+ }
1401
2130
  const decomposedComponentData = softComponent.components.map(
1402
2131
  (softSubComponent) => {
1403
- return subComponentDecomposer(componentData, softSubComponent);
2132
+ return subComponentDecomposer(resolvedComponentData, softSubComponent);
1404
2133
  }
1405
2134
  );
1406
2135
  return decomposedComponentData;
@@ -1470,7 +2199,14 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1470
2199
  });
1471
2200
  const config = __spreadValues({}, get().softConfig);
1472
2201
  const overrides = get().overrides;
1473
- const buildConfig = builderConfig(config, overrides, void 0, get().showVersionFields);
2202
+ const buildConfig = builderConfig(
2203
+ config,
2204
+ overrides,
2205
+ void 0,
2206
+ get().showVersionFields,
2207
+ void 0,
2208
+ get().customFields
2209
+ );
1474
2210
  const editableIds = /* @__PURE__ */ new Set([selectedItem.props.id]);
1475
2211
  const initialContent = [__spreadValues({}, selectedItem)];
1476
2212
  walkTree3(
@@ -1544,12 +2280,20 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1544
2280
  get().softConfig.components,
1545
2281
  get().overrides,
1546
2282
  (softComponentMeta == null ? void 0 : softComponentMeta.name) || softComponentName,
1547
- softComponentMeta == null ? void 0 : softComponentMeta.category
2283
+ softComponentMeta == null ? void 0 : softComponentMeta.category,
2284
+ get().customFields
1548
2285
  );
1549
2286
  const config = __spreadValues({}, get().softConfig);
1550
2287
  const overrides = get().overrides;
1551
2288
  const dependents = get().dependencyGraph.get(softComponentName) || /* @__PURE__ */ new Set();
1552
- const buildConfig = builderConfig(config, overrides, softComponentName, get().showVersionFields, dependents);
2289
+ const buildConfig = builderConfig(
2290
+ config,
2291
+ overrides,
2292
+ softComponentName,
2293
+ get().showVersionFields,
2294
+ dependents,
2295
+ get().customFields
2296
+ );
1553
2297
  const editableIds = /* @__PURE__ */ new Set([]);
1554
2298
  const decomposedComponents = get().builder.decompose(selectedItem);
1555
2299
  walkTree3(
@@ -1776,7 +2520,8 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1776
2520
  {
1777
2521
  name: displayName,
1778
2522
  category
1779
- }
2523
+ },
2524
+ get().customFields
1780
2525
  );
1781
2526
  const existingComponent = get().softComponents[componentName];
1782
2527
  const allVersions = Object.keys((existingComponent == null ? void 0 : existingComponent.versions) || {});
@@ -1795,7 +2540,8 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1795
2540
  })
1796
2541
  }),
1797
2542
  softComponent.defaultProps,
1798
- get().showVersionFields
2543
+ get().showVersionFields,
2544
+ get().customFields
1799
2545
  );
1800
2546
  get().setSoftComponent(componentName, version, softComponent);
1801
2547
  return [newSoftComponentConfig, version];
@@ -1849,7 +2595,8 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1849
2595
  get().softConfig.components,
1850
2596
  get().overrides,
1851
2597
  (softComponentMeta == null ? void 0 : softComponentMeta.name) || componentName,
1852
- softComponentMeta == null ? void 0 : softComponentMeta.category
2598
+ softComponentMeta == null ? void 0 : softComponentMeta.category,
2599
+ get().customFields
1853
2600
  );
1854
2601
  puckDispatch({
1855
2602
  type: "setData",
@@ -1996,7 +2743,7 @@ function topologicalSort(softComponents, hardComponentNames) {
1996
2743
  }
1997
2744
  return sorted;
1998
2745
  }
1999
- function buildInitialSoftComponents(hardConfig, softComponents, overrides, showVersioning = false) {
2746
+ function buildInitialSoftComponents(hardConfig, softComponents, overrides, showVersioning = false, customFields) {
2000
2747
  var _a, _b;
2001
2748
  if (!softComponents || Object.keys(softComponents).length === 0) {
2002
2749
  return {};
@@ -2032,7 +2779,8 @@ function buildInitialSoftComponents(hardConfig, softComponents, overrides, showV
2032
2779
  // Pass the accumulating config
2033
2780
  hydratedSoftComponents,
2034
2781
  versionedComponent.defaultProps,
2035
- showVersioning
2782
+ showVersioning,
2783
+ customFields
2036
2784
  );
2037
2785
  componentConfigs[name] = newSoftComponentConfig;
2038
2786
  buildingConfig.components[name] = newSoftComponentConfig;
@@ -2060,7 +2808,8 @@ function buildInitialSoftComponents(hardConfig, softComponents, overrides, showV
2060
2808
  hardConfig,
2061
2809
  hydratedSoftComponents,
2062
2810
  versionedComponent.defaultProps,
2063
- showVersioning
2811
+ showVersioning,
2812
+ customFields
2064
2813
  );
2065
2814
  componentConfigs[name] = newSoftComponentConfig;
2066
2815
  }
@@ -2126,9 +2875,9 @@ var clearEditVisibility = (doc) => {
2126
2875
  // src/puck/store/index.tsx
2127
2876
  var createSoftConfigStore = (hardConfig = {
2128
2877
  components: {}
2129
- }, softComponents = {}, overrides = {}, onActions, showVersionFields = true) => {
2878
+ }, softComponents = {}, overrides = {}, onActions, showVersionFields = true, customFields = {}) => {
2130
2879
  const normalizedSoftComponents = Object.fromEntries(
2131
- Object.entries(softComponents || {}).map(([key, value]) => [
2880
+ Object.entries(softComponents || {}).filter(([key]) => !hardConfig.components || !hardConfig.components[key]).map(([key, value]) => [
2132
2881
  key,
2133
2882
  __spreadProps(__spreadValues({}, value), {
2134
2883
  name: value.name || key
@@ -2149,6 +2898,7 @@ var createSoftConfigStore = (hardConfig = {
2149
2898
  state: "ready",
2150
2899
  originalHistory: [],
2151
2900
  overrides,
2901
+ customFields,
2152
2902
  onActions,
2153
2903
  iframeDocRef,
2154
2904
  showVersionFields,
@@ -2190,11 +2940,17 @@ var createSoftConfigStore = (hardConfig = {
2190
2940
  components: __spreadValues(__spreadValues({}, hardConfig.components), buildInitialSoftComponents(
2191
2941
  hardConfig,
2192
2942
  hydratedSoftComponents,
2193
- overrides
2943
+ overrides,
2944
+ showVersionFields,
2945
+ customFields
2194
2946
  )),
2195
2947
  categories: __spreadValues({}, hardConfig.categories || {})
2196
2948
  }),
2197
2949
  setSoftComponent: (name, version, component) => {
2950
+ if (hardConfig.components && hardConfig.components[name]) {
2951
+ console.warn(`Cannot set soft component "${name}" because it conflicts with a base hardConfig component.`);
2952
+ return;
2953
+ }
2198
2954
  const existing = get().softComponents[name];
2199
2955
  set((state) => {
2200
2956
  var _a, _b;
@@ -2217,6 +2973,9 @@ var createSoftConfigStore = (hardConfig = {
2217
2973
  const nextSoftComponents = __spreadValues({}, state.softComponents);
2218
2974
  const nextConfigComponents = __spreadValues({}, state.softConfig.components);
2219
2975
  Object.entries(incomingComponents).forEach(([name, data]) => {
2976
+ if (hardConfig.components && hardConfig.components[name]) {
2977
+ return;
2978
+ }
2220
2979
  const existing = nextSoftComponents[name];
2221
2980
  const finalComponentData = existing ? __spreadProps(__spreadValues(__spreadValues({}, existing), data), {
2222
2981
  name: data.name || existing.name || name,
@@ -2235,7 +2994,8 @@ var createSoftConfigStore = (hardConfig = {
2235
2994
  state.softConfig,
2236
2995
  nextSoftComponents,
2237
2996
  activeVersionData.defaultProps,
2238
- state.showVersionFields
2997
+ state.showVersionFields,
2998
+ state.customFields
2239
2999
  );
2240
3000
  }
2241
3001
  });
@@ -2266,7 +3026,8 @@ var createSoftConfigStore = (hardConfig = {
2266
3026
  softConfig,
2267
3027
  hydratedComponents,
2268
3028
  activeVersionData.defaultProps,
2269
- get().showVersionFields
3029
+ get().showVersionFields,
3030
+ get().customFields
2270
3031
  );
2271
3032
  }
2272
3033
  });
@@ -2297,7 +3058,8 @@ var createSoftConfigStore = (hardConfig = {
2297
3058
  get().softConfig,
2298
3059
  get().softComponents,
2299
3060
  softComponent.defaultProps,
2300
- get().showVersionFields
3061
+ get().showVersionFields,
3062
+ get().customFields
2301
3063
  );
2302
3064
  set((state) => ({
2303
3065
  softConfig: __spreadProps(__spreadValues({}, state.softConfig), {
@@ -2434,7 +3196,8 @@ var createSoftConfigStore = (hardConfig = {
2434
3196
  config,
2435
3197
  softComponents2,
2436
3198
  versionedComponent.defaultProps,
2437
- state.showVersionFields
3199
+ state.showVersionFields,
3200
+ state.customFields
2438
3201
  );
2439
3202
  config.components[dependentName] = newConfig;
2440
3203
  }
@@ -2452,14 +3215,29 @@ var SoftConfigProvider = ({
2452
3215
  children,
2453
3216
  hardConfig,
2454
3217
  softComponents,
3218
+ customFields,
2455
3219
  overrides,
2456
3220
  value,
2457
3221
  onActions,
2458
3222
  useVersioning = false
2459
3223
  }) => {
2460
3224
  const store = value != null ? value : useMemo2(
2461
- () => createSoftConfigStore(hardConfig, softComponents, overrides, onActions, useVersioning),
2462
- [hardConfig, softComponents, overrides, onActions, useVersioning]
3225
+ () => createSoftConfigStore(
3226
+ hardConfig,
3227
+ softComponents,
3228
+ overrides,
3229
+ onActions,
3230
+ useVersioning,
3231
+ customFields
3232
+ ),
3233
+ [
3234
+ hardConfig,
3235
+ softComponents,
3236
+ overrides,
3237
+ onActions,
3238
+ useVersioning,
3239
+ customFields
3240
+ ]
2463
3241
  );
2464
3242
  const [softConfig, setSoftConfig] = useState(
2465
3243
  () => store.getState().softConfig
@@ -3055,7 +3833,7 @@ var getClassName3 = get_class_name_factory_default("ActionBar", ActionBar_module
3055
3833
  var usePuck2 = createUsePuck11();
3056
3834
  var ActionBarOverride = (props) => {
3057
3835
  var _a, _b;
3058
- const { handleBuild } = useBuild("Custom Name");
3836
+ const { handleBuild } = useBuild(props.label ? props.label + " Soft Component" : "New Soft Component");
3059
3837
  const { handleRemodel } = useRemodel();
3060
3838
  const { handleDecompose } = useDecompose();
3061
3839
  const overrides = useSoftConfig((s) => s.overrides);
@@ -3087,10 +3865,17 @@ var ActionBarOverride = (props) => {
3087
3865
  const selectedId = (_a = selectedItem == null ? void 0 : selectedItem.props) == null ? void 0 : _a.id;
3088
3866
  const parentId = (_b = itemSelector == null ? void 0 : itemSelector.zone) == null ? void 0 : _b.split(":")[0];
3089
3867
  const isEditable = Boolean(selectedId && (editableIds.has(selectedId) || parentId && editableIds.has(parentId)));
3868
+ const displayName = useMemo3(() => {
3869
+ var _a2;
3870
+ if (isSoftComponent2) {
3871
+ return ((_a2 = softComponents[key]) == null ? void 0 : _a2.name) || getComponentNameFromKey(key, overrides);
3872
+ }
3873
+ return props.label || "";
3874
+ }, [isSoftComponent2, key, props.label, overrides, softComponents]);
3090
3875
  return /* @__PURE__ */ jsx9("div", { className: getClassName3(), children: /* @__PURE__ */ jsxs3(ActionBar, { children: [
3091
3876
  /* @__PURE__ */ jsxs3(ActionBar.Group, { children: [
3092
3877
  props.parentAction,
3093
- /* @__PURE__ */ jsx9(ActionBar.Label, { label: props.label })
3878
+ /* @__PURE__ */ jsx9(ActionBar.Label, { label: displayName })
3094
3879
  ] }),
3095
3880
  /* @__PURE__ */ jsxs3(ActionBar.Group, { children: [
3096
3881
  status === "ready" ? isSoftComponent2 ? /* @__PURE__ */ jsxs3(Fragment4, { children: [
@@ -3215,7 +4000,7 @@ var getClassName5 = get_class_name_factory_default("DrawerItem", DrawerItem_modu
3215
4000
  var usePuck3 = createUsePuck12();
3216
4001
  var DrawerItem = (props) => {
3217
4002
  const componentMeta = useSoftConfig((s) => s.softComponents[props.name]);
3218
- const displayName = (componentMeta == null ? void 0 : componentMeta.name) || props.name;
4003
+ const displayName = props.label || (componentMeta == null ? void 0 : componentMeta.name) || props.name;
3219
4004
  const softComponents = new Set(
3220
4005
  Object.keys(useSoftConfig((s) => s.softComponents, shallow2))
3221
4006
  );
@@ -3311,6 +4096,7 @@ var DrawerItem = (props) => {
3311
4096
  onMouseEnter: () => setIsHovering(true),
3312
4097
  onMouseLeave: () => setIsHovering(false),
3313
4098
  children: [
4099
+ props.label,
3314
4100
  /* @__PURE__ */ jsxs4("div", { className: getClassName5("content"), children: [
3315
4101
  /* @__PURE__ */ jsx11("div", { className: getClassName5("name"), children: displayName }),
3316
4102
  useVersioning && /* @__PURE__ */ jsxs4("div", { className: getClassName5("version"), children: [
@@ -3487,6 +4273,10 @@ var Drawer = (_props) => {
3487
4273
  })
3488
4274
  );
3489
4275
  const allKeys = Object.keys(config.components);
4276
+ const labels = Object.entries(config.components).reduce((acc, [key, comp]) => {
4277
+ acc[key] = comp.label || key;
4278
+ return acc;
4279
+ }, {});
3490
4280
  const otherKeys = allKeys.filter((k) => !categorised.has(k));
3491
4281
  const categoryEntries = Object.entries(categories).filter(
3492
4282
  ([, cat]) => cat.visible !== false
@@ -3505,6 +4295,7 @@ var Drawer = (_props) => {
3505
4295
  PuckDrawer.Item,
3506
4296
  {
3507
4297
  name: key,
4298
+ label: labels[key],
3508
4299
  isDragDisabled: !getPermissions({ type: key }).insert,
3509
4300
  children: DrawerItem
3510
4301
  },
@@ -3589,9 +4380,6 @@ function extractDependencies2(softComponents, componentName, version) {
3589
4380
  return dependencies;
3590
4381
  }
3591
4382
  function reverseTopologicalSort(softComponents, hardComponentNames) {
3592
- const sorted = [];
3593
- const visiting = /* @__PURE__ */ new Set();
3594
- const visited = /* @__PURE__ */ new Set();
3595
4383
  const dependencyGraph = /* @__PURE__ */ new Map();
3596
4384
  const dependents = /* @__PURE__ */ new Map();
3597
4385
  for (const [componentName, component] of Object.entries(softComponents)) {
@@ -3639,7 +4427,7 @@ function reverseTopologicalSort(softComponents, hardComponentNames) {
3639
4427
  const sortedByDepth = [...depths.entries()].sort(([, depthA], [, depthB]) => depthB - depthA).map(([name]) => name);
3640
4428
  return sortedByDepth;
3641
4429
  }
3642
- function dissolveComponentRecursively(componentData, softComponents, hardComponentNames, depth = 0) {
4430
+ function dissolveComponentRecursively(componentData, softComponents, hardComponentNames, depth = 0, fieldSettings) {
3643
4431
  const MAX_DEPTH = 50;
3644
4432
  if (depth > MAX_DEPTH) {
3645
4433
  console.error(
@@ -3649,11 +4437,11 @@ function dissolveComponentRecursively(componentData, softComponents, hardCompone
3649
4437
  }
3650
4438
  const componentType = componentData.type;
3651
4439
  if (!isSoftComponent(componentType, softComponents)) {
3652
- return [dissolveComponentSlots(componentData, softComponents, hardComponentNames, depth)];
4440
+ return [dissolveComponentSlots(componentData, softComponents, hardComponentNames, depth, fieldSettings)];
3653
4441
  }
3654
4442
  let decomposed;
3655
4443
  try {
3656
- decomposed = decomposeSoftComponent(componentData, softComponents);
4444
+ decomposed = decomposeSoftComponent(componentData, softComponents, fieldSettings);
3657
4445
  } catch (error) {
3658
4446
  console.warn(
3659
4447
  `Failed to decompose soft component "${componentType}":`,
@@ -3667,13 +4455,14 @@ function dissolveComponentRecursively(componentData, softComponents, hardCompone
3667
4455
  component,
3668
4456
  softComponents,
3669
4457
  hardComponentNames,
3670
- depth + 1
4458
+ depth + 1,
4459
+ fieldSettings
3671
4460
  );
3672
4461
  fullyDissolved.push(...dissolved);
3673
4462
  }
3674
4463
  return fullyDissolved;
3675
4464
  }
3676
- function dissolveComponentSlots(componentData, softComponents, hardComponentNames, depth) {
4465
+ function dissolveComponentSlots(componentData, softComponents, hardComponentNames, depth, fieldSettings) {
3677
4466
  const newProps = __spreadValues({}, componentData.props);
3678
4467
  Object.entries(newProps).forEach(([key, value]) => {
3679
4468
  var _a;
@@ -3683,7 +4472,8 @@ function dissolveComponentSlots(componentData, softComponents, hardComponentName
3683
4472
  slotComponent,
3684
4473
  softComponents,
3685
4474
  hardComponentNames,
3686
- depth
4475
+ depth,
4476
+ fieldSettings
3687
4477
  )
3688
4478
  );
3689
4479
  }
@@ -3693,22 +4483,23 @@ function dissolveComponentSlots(componentData, softComponents, hardComponentName
3693
4483
  });
3694
4484
  }
3695
4485
  function dissolveAllSoftComponents(data, softComponents, config) {
4486
+ var _a;
3696
4487
  const hardComponentNames = new Set(
3697
4488
  Object.keys(config.components || {}).filter(
3698
4489
  (name) => !isSoftComponent(name, softComponents)
3699
4490
  )
3700
4491
  );
3701
- const dissolutionOrder = reverseTopologicalSort(
3702
- softComponents,
3703
- hardComponentNames
3704
- );
4492
+ reverseTopologicalSort(softComponents, hardComponentNames);
4493
+ const rootParams = ((_a = data.root) == null ? void 0 : _a.props) || {};
4494
+ const fieldSettings = __spreadValues(__spreadValues({}, rootParams._fieldSettings || {}), rootParams);
3705
4495
  const dissolveComponents = (components) => {
3706
4496
  return components.flatMap((componentData) => {
3707
4497
  return dissolveComponentRecursively(
3708
4498
  componentData,
3709
4499
  softComponents,
3710
4500
  hardComponentNames,
3711
- 0
4501
+ 0,
4502
+ fieldSettings
3712
4503
  );
3713
4504
  });
3714
4505
  };
@@ -3774,12 +4565,18 @@ export {
3774
4565
  Header,
3775
4566
  Modal,
3776
4567
  SoftConfigProvider,
4568
+ applyMapping,
3777
4569
  confirm,
3778
4570
  createActionCallback,
3779
4571
  createSoftConfigStore,
3780
4572
  createUseSoftConfig,
4573
+ filterToOptionsForFrom,
4574
+ getArrayBasePath,
4575
+ getArrayItemSubPath,
4576
+ isArrayMappingPath,
3781
4577
  notify,
3782
4578
  resolveSoftConfig,
4579
+ resolveValueByPath,
3783
4580
  setConfirmHandler,
3784
4581
  setNotificationHandler,
3785
4582
  useBuild,