@10x-media/form-builder 0.1.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,282 @@
1
+ import { t as keys } from "./keys-N5xGiUsh.js";
2
+ //#region src/translations/server.ts
3
+ /**
4
+ * Adapt a Payload request `t` (typed to core keys only) so it also accepts this
5
+ * plugin's keys. They are registered at config time and resolve at runtime; the
6
+ * cast only widens the compile-time key domain.
7
+ */
8
+ const asTranslate = (t) => t;
9
+ /**
10
+ * Adapt a Payload request `t` to the engine-facing `Translate` the submission core and field-type
11
+ * `format`/`validate` speak (any key string). Same runtime function as `asTranslate`; this widening
12
+ * accepts arbitrary keys because the engine resolves both this plugin's and a host's registered keys.
13
+ */
14
+ const asFieldTranslate = (t) => t;
15
+ /** A field `label`/`description` backed by a typed key, resolved per request. */
16
+ const labelForKey = (key) => ({ t }) => asTranslate(t)(key);
17
+ /**
18
+ * A `label`/`description` from an arbitrary key string (a field-type-supplied label, which may be a
19
+ * host-registered key or a literal; Payload's `t` returns the input unchanged when unknown). Distinct
20
+ * from `labelForKey`, which constrains to this plugin's typed keys.
21
+ */
22
+ const labelFor = (key) => ({ t }) => asTranslate(t)(key);
23
+ //#endregion
24
+ //#region src/fields/defineFormField.ts
25
+ /**
26
+ * Define a form field type once and get every facet from one object: a Payload `Field[]` for
27
+ * authoring, an isomorphic `validate`, a localized `format`, and a renderer ref. Built-ins use
28
+ * this same primitive, so custom field types are never second-class. The `value` kind drives the
29
+ * typed value threaded into `validate`/`format`; the optional second generic types the config.
30
+ */
31
+ const defineFormField = (definition) => definition;
32
+ //#endregion
33
+ //#region src/fields/builtin/calculation.ts
34
+ const calculationField = defineFormField({
35
+ type: "calculation",
36
+ label: keys.fieldTypeCalculation,
37
+ value: "number",
38
+ config: [{
39
+ name: "expression",
40
+ type: "json",
41
+ label: labelFor(keys.configExpression)
42
+ }, {
43
+ name: "calcDisplay",
44
+ type: "checkbox",
45
+ defaultValue: true,
46
+ label: labelFor(keys.configCalcDisplay)
47
+ }],
48
+ format: ({ value }) => value == null ? "" : String(value)
49
+ });
50
+ //#endregion
51
+ //#region src/fields/builtin/checkbox.ts
52
+ const checkboxField = defineFormField({
53
+ type: "checkbox",
54
+ label: keys.fieldTypeCheckbox,
55
+ value: "boolean",
56
+ format: ({ value, t }) => value ? t(keys.formatYes) : t(keys.formatNo)
57
+ });
58
+ //#endregion
59
+ //#region src/fields/builtin/consent.ts
60
+ const consentField = defineFormField({
61
+ type: "consent",
62
+ label: keys.fieldTypeConsent,
63
+ value: "boolean",
64
+ config: [
65
+ {
66
+ name: "statement",
67
+ type: "text",
68
+ label: labelFor(keys.consentConfigStatement)
69
+ },
70
+ {
71
+ name: "source",
72
+ type: "select",
73
+ defaultValue: "static",
74
+ label: labelFor(keys.consentConfigSource),
75
+ options: [{
76
+ label: labelFor(keys.consentSourceStatic),
77
+ value: "static"
78
+ }, {
79
+ label: labelFor(keys.consentSourcePageReference),
80
+ value: "pageReference"
81
+ }]
82
+ },
83
+ {
84
+ name: "sourceConfig",
85
+ type: "group",
86
+ label: labelFor(keys.consentConfigSourceConfig),
87
+ fields: [
88
+ {
89
+ name: "label",
90
+ type: "text",
91
+ label: labelFor(keys.consentConfigLabel)
92
+ },
93
+ {
94
+ name: "url",
95
+ type: "text",
96
+ label: labelFor(keys.consentConfigUrl)
97
+ },
98
+ {
99
+ name: "version",
100
+ type: "text",
101
+ label: labelFor(keys.consentConfigVersion)
102
+ },
103
+ {
104
+ name: "relationTo",
105
+ type: "text",
106
+ label: labelFor(keys.consentConfigRelationTo)
107
+ },
108
+ {
109
+ name: "docId",
110
+ type: "text",
111
+ label: labelFor(keys.consentConfigDocId)
112
+ },
113
+ {
114
+ name: "urlField",
115
+ type: "text",
116
+ defaultValue: "slug",
117
+ label: labelFor(keys.consentConfigUrlField)
118
+ },
119
+ {
120
+ name: "captureVersion",
121
+ type: "checkbox",
122
+ label: labelFor(keys.consentConfigCaptureVersion)
123
+ }
124
+ ]
125
+ },
126
+ {
127
+ name: "optional",
128
+ type: "checkbox",
129
+ label: labelFor(keys.consentConfigOptional)
130
+ }
131
+ ],
132
+ validate: ({ value, config, t }) => {
133
+ if (!(config.optional === true) && value !== true) return t(keys.validationRequired);
134
+ return true;
135
+ },
136
+ format: ({ value, t }) => t(value === true ? keys.formatYes : keys.formatNo)
137
+ });
138
+ //#endregion
139
+ //#region src/fields/builtin/email.ts
140
+ const EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
141
+ const emailField = defineFormField({
142
+ type: "email",
143
+ label: keys.fieldTypeEmail,
144
+ value: "text",
145
+ validate: ({ value, t }) => {
146
+ if (value == null || value === "") return true;
147
+ return EMAIL_PATTERN.test(value) ? true : t(keys.validationEmail);
148
+ },
149
+ format: ({ value }) => value == null ? "" : String(value)
150
+ });
151
+ //#endregion
152
+ //#region src/fields/builtin/file.ts
153
+ const isFileRef = (value) => typeof value === "object" && value !== null && "filename" in value;
154
+ /**
155
+ * The `file` field type. Its stored value is a server-captured {@link FileRef}; the client only ever submits
156
+ * the upload id, and `runSubmission` re-reads filename/mimeType/filesize from the upload doc at the trust
157
+ * boundary (see `captureFileRef`). The intrinsic validator is intentionally a no-op: MIME/size/existence are
158
+ * enforced authoritatively server-side against the stored doc, never against client metadata. `relationTo`,
159
+ * `mimeTypes`, and `maxSize` persist on the block so the capture can enforce them.
160
+ */
161
+ const fileField = defineFormField({
162
+ type: "file",
163
+ label: keys.fieldTypeFile,
164
+ value: "file",
165
+ config: [
166
+ {
167
+ name: "relationTo",
168
+ type: "text",
169
+ label: labelFor(keys.fileConfigRelationTo)
170
+ },
171
+ {
172
+ name: "mimeTypes",
173
+ type: "text",
174
+ hasMany: true,
175
+ label: labelFor(keys.fileConfigMimeTypes)
176
+ },
177
+ {
178
+ name: "maxSize",
179
+ type: "number",
180
+ label: labelFor(keys.fileConfigMaxSize)
181
+ }
182
+ ],
183
+ format: ({ value }) => isFileRef(value) ? value.filename : ""
184
+ });
185
+ //#endregion
186
+ //#region src/fields/builtin/number.ts
187
+ const numberField = defineFormField({
188
+ type: "number",
189
+ label: keys.fieldTypeNumber,
190
+ value: "number",
191
+ validate: ({ value, t }) => {
192
+ if (value == null) return true;
193
+ return Number.isFinite(value) ? true : t(keys.validationNumber);
194
+ },
195
+ format: ({ value }) => value == null ? "" : String(value)
196
+ });
197
+ //#endregion
198
+ //#region src/fields/builtin/select.ts
199
+ const selectField = defineFormField({
200
+ type: "select",
201
+ label: keys.fieldTypeSelect,
202
+ value: "text",
203
+ conditionType: "select",
204
+ config: [{
205
+ name: "options",
206
+ type: "array",
207
+ label: labelFor(keys.configOptions),
208
+ labels: {
209
+ singular: labelFor(keys.configOption),
210
+ plural: labelFor(keys.configOptions)
211
+ },
212
+ fields: [{
213
+ name: "label",
214
+ type: "text",
215
+ required: true,
216
+ label: labelFor(keys.configOptionLabel)
217
+ }, {
218
+ name: "value",
219
+ type: "text",
220
+ required: true,
221
+ label: labelFor(keys.configOptionValue)
222
+ }]
223
+ }],
224
+ validate: ({ value, config, t }) => {
225
+ if (value == null || value === "") return true;
226
+ const options = config.options ?? [];
227
+ if (options.length === 0) return true;
228
+ return options.some((option) => option.value === value) ? true : t(keys.validationSelect);
229
+ },
230
+ format: ({ value, optionLabels }) => {
231
+ if (value == null || value === "") return "";
232
+ return optionLabels?.[value] ?? String(value);
233
+ }
234
+ });
235
+ //#endregion
236
+ //#region src/fields/builtin/index.ts
237
+ const defaultFieldDefinitions = [
238
+ defineFormField({
239
+ type: "text",
240
+ label: keys.fieldTypeText,
241
+ value: "text",
242
+ format: ({ value }) => value == null ? "" : String(value)
243
+ }),
244
+ defineFormField({
245
+ type: "textarea",
246
+ label: keys.fieldTypeTextarea,
247
+ value: "text",
248
+ format: ({ value }) => value == null ? "" : String(value)
249
+ }),
250
+ emailField,
251
+ numberField,
252
+ selectField,
253
+ checkboxField,
254
+ calculationField,
255
+ consentField,
256
+ fileField
257
+ ];
258
+ //#endregion
259
+ //#region src/fields/registry.ts
260
+ const buildRegistry = (definitions) => {
261
+ const registry = /* @__PURE__ */ new Map();
262
+ for (const definition of definitions) registry.set(definition.type, definition);
263
+ return registry;
264
+ };
265
+ /**
266
+ * Resolve the active field-type registry from the built-in defaults and the plugin `fields` option.
267
+ * `false` removes a type, `true` keeps the default, an object adds a new type or replaces an existing
268
+ * one (its `type` is forced to the config key so an override cannot rename the slot).
269
+ */
270
+ const resolveFieldTypes = (defaults, config = {}) => {
271
+ const registry = buildRegistry(defaults);
272
+ for (const [type, option] of Object.entries(config)) if (option === false) registry.delete(type);
273
+ else if (option === true) {} else registry.set(type, {
274
+ ...option,
275
+ type
276
+ });
277
+ return registry;
278
+ };
279
+ //#endregion
280
+ export { asFieldTranslate as a, labelForKey as c, defineFormField as i, resolveFieldTypes as n, asTranslate as o, defaultFieldDefinitions as r, labelFor as s, buildRegistry as t };
281
+
282
+ //# sourceMappingURL=registry-CoCyhtvB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry-CoCyhtvB.js","names":[],"sources":["../src/translations/server.ts","../src/fields/defineFormField.ts","../src/fields/builtin/calculation.ts","../src/fields/builtin/checkbox.ts","../src/fields/builtin/consent.ts","../src/fields/builtin/email.ts","../src/fields/builtin/file.ts","../src/fields/builtin/number.ts","../src/fields/builtin/select.ts","../src/fields/builtin/text.ts","../src/fields/builtin/textarea.ts","../src/fields/builtin/index.ts","../src/fields/registry.ts"],"sourcesContent":["import type { LabelFunction } from 'payload'\n\nimport type { Translate as FieldTranslate } from '../fields/types'\nimport type { TranslationKey } from './keys'\n\n/** A `t`-like function narrowed to this plugin's typed keys. */\ntype Translate = (key: TranslationKey) => string\n\n/**\n * Adapt a Payload request `t` (typed to core keys only) so it also accepts this\n * plugin's keys. They are registered at config time and resolve at runtime; the\n * cast only widens the compile-time key domain.\n */\nexport const asTranslate = (t: unknown): Translate => t as Translate\n\n/**\n * Adapt a Payload request `t` to the engine-facing `Translate` the submission core and field-type\n * `format`/`validate` speak (any key string). Same runtime function as `asTranslate`; this widening\n * accepts arbitrary keys because the engine resolves both this plugin's and a host's registered keys.\n */\nexport const asFieldTranslate = (t: unknown): FieldTranslate => t as FieldTranslate\n\n/** A field `label`/`description` backed by a typed key, resolved per request. */\nexport const labelForKey =\n\t(key: TranslationKey): LabelFunction =>\n\t({ t }) =>\n\t\tasTranslate(t)(key)\n\n/**\n * A `label`/`description` from an arbitrary key string (a field-type-supplied label, which may be a\n * host-registered key or a literal; Payload's `t` returns the input unchanged when unknown). Distinct\n * from `labelForKey`, which constrains to this plugin's typed keys.\n */\nexport const labelFor =\n\t(key: string): LabelFunction =>\n\t({ t }) =>\n\t\tasTranslate(t)(key as TranslationKey)\n","import type { FormFieldConfigValues, FormFieldDefinition, FormFieldValueKind } from './types'\n\n/**\n * Define a form field type once and get every facet from one object: a Payload `Field[]` for\n * authoring, an isomorphic `validate`, a localized `format`, and a renderer ref. Built-ins use\n * this same primitive, so custom field types are never second-class. The `value` kind drives the\n * typed value threaded into `validate`/`format`; the optional second generic types the config.\n */\nexport const defineFormField = <\n\tK extends FormFieldValueKind,\n\tTConfig extends FormFieldConfigValues = FormFieldConfigValues,\n>(\n\tdefinition: FormFieldDefinition<K, TConfig>\n): FormFieldDefinition<K, TConfig> => definition\n","import { keys } from '../../translations/keys'\nimport { labelFor } from '../../translations/server'\nimport { defineFormField } from '../defineFormField'\n\nexport const calculationField = defineFormField<'number'>({\n\ttype: 'calculation',\n\tlabel: keys.fieldTypeCalculation,\n\tvalue: 'number',\n\tconfig: [\n\t\t{ name: 'expression', type: 'json', label: labelFor(keys.configExpression) },\n\t\t{\n\t\t\tname: 'calcDisplay',\n\t\t\ttype: 'checkbox',\n\t\t\tdefaultValue: true,\n\t\t\tlabel: labelFor(keys.configCalcDisplay),\n\t\t},\n\t],\n\tformat: ({ value }) => (value == null ? '' : String(value)),\n})\n","import { keys } from '../../translations/keys'\nimport { defineFormField } from '../defineFormField'\n\nexport const checkboxField = defineFormField<'boolean'>({\n\ttype: 'checkbox',\n\tlabel: keys.fieldTypeCheckbox,\n\tvalue: 'boolean',\n\tformat: ({ value, t }) => (value ? t(keys.formatYes) : t(keys.formatNo)),\n})\n","import { keys } from '../../translations/keys'\nimport { labelFor } from '../../translations/server'\nimport { defineFormField } from '../defineFormField'\n\ntype ConsentConfig = {\n\tstatement?: string\n\tsource?: string\n\tsourceConfig?: {\n\t\tlabel?: string\n\t\turl?: string\n\t\tversion?: string\n\t\trelationTo?: string\n\t\tdocId?: string\n\t\turlField?: string\n\t\tcaptureVersion?: boolean\n\t}\n\toptional?: boolean\n}\n\nexport const consentField = defineFormField<'boolean', ConsentConfig>({\n\ttype: 'consent',\n\tlabel: keys.fieldTypeConsent,\n\tvalue: 'boolean',\n\tconfig: [\n\t\t{ name: 'statement', type: 'text', label: labelFor(keys.consentConfigStatement) },\n\t\t{\n\t\t\tname: 'source',\n\t\t\ttype: 'select',\n\t\t\tdefaultValue: 'static',\n\t\t\tlabel: labelFor(keys.consentConfigSource),\n\t\t\toptions: [\n\t\t\t\t{ label: labelFor(keys.consentSourceStatic), value: 'static' },\n\t\t\t\t{ label: labelFor(keys.consentSourcePageReference), value: 'pageReference' },\n\t\t\t],\n\t\t},\n\t\t// The source params are nested so their names (label/url/...) cannot collide with the shared field config (name/label/required/...) that buildFieldBlocks prepends. The source's `resolve` receives this group object as its config.\n\t\t{\n\t\t\tname: 'sourceConfig',\n\t\t\ttype: 'group',\n\t\t\tlabel: labelFor(keys.consentConfigSourceConfig),\n\t\t\tfields: [\n\t\t\t\t{ name: 'label', type: 'text', label: labelFor(keys.consentConfigLabel) },\n\t\t\t\t{ name: 'url', type: 'text', label: labelFor(keys.consentConfigUrl) },\n\t\t\t\t{ name: 'version', type: 'text', label: labelFor(keys.consentConfigVersion) },\n\t\t\t\t{ name: 'relationTo', type: 'text', label: labelFor(keys.consentConfigRelationTo) },\n\t\t\t\t{ name: 'docId', type: 'text', label: labelFor(keys.consentConfigDocId) },\n\t\t\t\t{\n\t\t\t\t\tname: 'urlField',\n\t\t\t\t\ttype: 'text',\n\t\t\t\t\tdefaultValue: 'slug',\n\t\t\t\t\tlabel: labelFor(keys.consentConfigUrlField),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'captureVersion',\n\t\t\t\t\ttype: 'checkbox',\n\t\t\t\t\tlabel: labelFor(keys.consentConfigCaptureVersion),\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\t// Consent is required-to-submit by default (compliance); check `optional` for marketing-style opt-ins.\n\t\t{ name: 'optional', type: 'checkbox', label: labelFor(keys.consentConfigOptional) },\n\t],\n\tvalidate: ({ value, config, t }) => {\n\t\tconst optional = (config as ConsentConfig).optional === true\n\t\tif (!optional && value !== true) {\n\t\t\treturn t(keys.validationRequired)\n\t\t}\n\t\treturn true\n\t},\n\tformat: ({ value, t }) => t(value === true ? keys.formatYes : keys.formatNo),\n})\n","import { keys } from '../../translations/keys'\nimport { defineFormField } from '../defineFormField'\n\nconst EMAIL_PATTERN = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n\nexport const emailField = defineFormField<'text'>({\n\ttype: 'email',\n\tlabel: keys.fieldTypeEmail,\n\tvalue: 'text',\n\tvalidate: ({ value, t }) => {\n\t\tif (value == null || value === '') {\n\t\t\treturn true\n\t\t}\n\t\treturn EMAIL_PATTERN.test(value) ? true : t(keys.validationEmail)\n\t},\n\tformat: ({ value }) => (value == null ? '' : String(value)),\n})\n","import { keys } from '../../translations/keys'\nimport { labelFor } from '../../translations/server'\nimport type { FileRef } from '../../uploads/types'\nimport { defineFormField } from '../defineFormField'\n\ntype FileConfig = {\n\trelationTo?: string\n\tmimeTypes?: string[]\n\tmaxSize?: number\n}\n\nconst isFileRef = (value: unknown): value is FileRef =>\n\ttypeof value === 'object' && value !== null && 'filename' in value\n\n/**\n * The `file` field type. Its stored value is a server-captured {@link FileRef}; the client only ever submits\n * the upload id, and `runSubmission` re-reads filename/mimeType/filesize from the upload doc at the trust\n * boundary (see `captureFileRef`). The intrinsic validator is intentionally a no-op: MIME/size/existence are\n * enforced authoritatively server-side against the stored doc, never against client metadata. `relationTo`,\n * `mimeTypes`, and `maxSize` persist on the block so the capture can enforce them.\n */\nexport const fileField = defineFormField<'file', FileConfig>({\n\ttype: 'file',\n\tlabel: keys.fieldTypeFile,\n\tvalue: 'file',\n\tconfig: [\n\t\t{ name: 'relationTo', type: 'text', label: labelFor(keys.fileConfigRelationTo) },\n\t\t{ name: 'mimeTypes', type: 'text', hasMany: true, label: labelFor(keys.fileConfigMimeTypes) },\n\t\t{ name: 'maxSize', type: 'number', label: labelFor(keys.fileConfigMaxSize) },\n\t],\n\tformat: ({ value }) => (isFileRef(value) ? value.filename : ''),\n})\n","import { keys } from '../../translations/keys'\nimport { defineFormField } from '../defineFormField'\n\nexport const numberField = defineFormField<'number'>({\n\ttype: 'number',\n\tlabel: keys.fieldTypeNumber,\n\tvalue: 'number',\n\tvalidate: ({ value, t }) => {\n\t\tif (value == null) {\n\t\t\treturn true\n\t\t}\n\t\treturn Number.isFinite(value) ? true : t(keys.validationNumber)\n\t},\n\tformat: ({ value }) => (value == null ? '' : String(value)),\n})\n","import { keys } from '../../translations/keys'\nimport { labelFor } from '../../translations/server'\nimport { defineFormField } from '../defineFormField'\n\ntype SelectOption = { label: string; value: string }\ntype SelectConfig = { options?: SelectOption[] }\n\nexport const selectField = defineFormField<'text', SelectConfig>({\n\ttype: 'select',\n\tlabel: keys.fieldTypeSelect,\n\tvalue: 'text',\n\tconditionType: 'select',\n\tconfig: [\n\t\t{\n\t\t\tname: 'options',\n\t\t\ttype: 'array',\n\t\t\tlabel: labelFor(keys.configOptions),\n\t\t\tlabels: { singular: labelFor(keys.configOption), plural: labelFor(keys.configOptions) },\n\t\t\tfields: [\n\t\t\t\t{ name: 'label', type: 'text', required: true, label: labelFor(keys.configOptionLabel) },\n\t\t\t\t{ name: 'value', type: 'text', required: true, label: labelFor(keys.configOptionValue) },\n\t\t\t],\n\t\t},\n\t],\n\tvalidate: ({ value, config, t }) => {\n\t\tif (value == null || value === '') {\n\t\t\treturn true\n\t\t}\n\t\tconst options = config.options ?? []\n\t\tif (options.length === 0) {\n\t\t\treturn true\n\t\t}\n\t\treturn options.some((option) => option.value === value) ? true : t(keys.validationSelect)\n\t},\n\tformat: ({ value, optionLabels }) => {\n\t\tif (value == null || value === '') {\n\t\t\treturn ''\n\t\t}\n\t\treturn optionLabels?.[value] ?? String(value)\n\t},\n})\n","import { keys } from '../../translations/keys'\nimport { defineFormField } from '../defineFormField'\n\nexport const textField = defineFormField<'text'>({\n\ttype: 'text',\n\tlabel: keys.fieldTypeText,\n\tvalue: 'text',\n\tformat: ({ value }) => (value == null ? '' : String(value)),\n})\n","import { keys } from '../../translations/keys'\nimport { defineFormField } from '../defineFormField'\n\nexport const textareaField = defineFormField<'text'>({\n\ttype: 'textarea',\n\tlabel: keys.fieldTypeTextarea,\n\tvalue: 'text',\n\tformat: ({ value }) => (value == null ? '' : String(value)),\n})\n","import type { AnyFormFieldDefinition } from '../types'\nimport { calculationField } from './calculation'\nimport { checkboxField } from './checkbox'\nimport { consentField } from './consent'\nimport { emailField } from './email'\nimport { fileField } from './file'\nimport { numberField } from './number'\nimport { selectField } from './select'\nimport { textField } from './text'\nimport { textareaField } from './textarea'\n\n// Field types are authored with precise value/config generics; the registry stores them erased\n// (config is re-narrowed per matched type at execution). One cast per built-in, no `any`.\nexport const defaultFieldDefinitions: AnyFormFieldDefinition[] = [\n\ttextField as AnyFormFieldDefinition,\n\ttextareaField as AnyFormFieldDefinition,\n\temailField as AnyFormFieldDefinition,\n\tnumberField as AnyFormFieldDefinition,\n\tselectField as AnyFormFieldDefinition,\n\tcheckboxField as AnyFormFieldDefinition,\n\tcalculationField as AnyFormFieldDefinition,\n\tconsentField as AnyFormFieldDefinition,\n\tfileField as AnyFormFieldDefinition,\n]\n","import type { AnyFormFieldDefinition } from './types'\n\nexport type FieldTypeRegistry = Map<string, AnyFormFieldDefinition>\n\n/** Per-type opt-in: `false` removes a built-in, `true` keeps it, an object adds a new type or replaces one. */\nexport type FieldTypeOption = boolean | AnyFormFieldDefinition\n\nexport type FieldTypesConfig = Record<string, FieldTypeOption>\n\nexport const buildRegistry = (definitions: AnyFormFieldDefinition[]): FieldTypeRegistry => {\n\tconst registry: FieldTypeRegistry = new Map()\n\tfor (const definition of definitions) {\n\t\tregistry.set(definition.type, definition)\n\t}\n\treturn registry\n}\n\n/**\n * Resolve the active field-type registry from the built-in defaults and the plugin `fields` option.\n * `false` removes a type, `true` keeps the default, an object adds a new type or replaces an existing\n * one (its `type` is forced to the config key so an override cannot rename the slot).\n */\nexport const resolveFieldTypes = (\n\tdefaults: AnyFormFieldDefinition[],\n\tconfig: FieldTypesConfig = {}\n): FieldTypeRegistry => {\n\tconst registry = buildRegistry(defaults)\n\tfor (const [type, option] of Object.entries(config)) {\n\t\tif (option === false) {\n\t\t\tregistry.delete(type)\n\t\t} else if (option === true) {\n\t\t\t// keep the default; a no-op when no default exists for this key\n\t\t} else {\n\t\t\tregistry.set(type, { ...option, type })\n\t\t}\n\t}\n\treturn registry\n}\n"],"mappings":"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"}