@mvriu5/payload-ai 1.6.2 → 1.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/dist/components/action-toast/ActionToast.d.ts +1 -14
  2. package/dist/components/action-toast/ActionToast.js +1 -1
  3. package/dist/components/ai-input/AIInput.js +1 -1
  4. package/dist/components/audit-log-list/AuditLogList.d.ts +2 -3
  5. package/dist/components/diff-dialog/DiffDialog.d.ts +2 -6
  6. package/dist/components/diff-dialog/DiffDialog.js +1 -1
  7. package/dist/components/generate-field/GenerateField.js +2 -0
  8. package/dist/components/hooks/useAIChatStream.d.ts +1 -1
  9. package/dist/components/hooks/useAISettings.d.ts +1 -1
  10. package/dist/components/hooks/useAISettings.js +1 -1
  11. package/dist/components/hooks/useDocumentMentionSuggestions.js +1 -1
  12. package/dist/components/hooks/useMentions.js +1 -1
  13. package/dist/components/hooks/usePluginConfig.d.ts +6 -6
  14. package/dist/components/hooks/usePluginConfig.js +1 -1
  15. package/dist/{payload → features}/collectionPermissions.js +1 -1
  16. package/dist/{payload/textFieldGeneration.d.ts → features/content/fieldGeneration.d.ts} +4 -0
  17. package/dist/{payload/textFieldGeneration.js → features/content/fieldGeneration.js} +19 -3
  18. package/dist/{ai → features}/promptCaching.d.ts +2 -2
  19. package/dist/features/proposals/containerNormalization.d.ts +8 -0
  20. package/dist/features/proposals/containerNormalization.js +112 -0
  21. package/dist/{payload/proposalData.d.ts → features/proposals/data.d.ts} +5 -10
  22. package/dist/features/proposals/data.js +113 -0
  23. package/dist/features/proposals/fieldNormalization.d.ts +2 -0
  24. package/dist/features/proposals/fieldNormalization.js +69 -0
  25. package/dist/features/proposals/normalizationTypes.d.ts +31 -0
  26. package/dist/features/proposals/normalizationTypes.js +1 -0
  27. package/dist/features/proposals/optionInference.d.ts +13 -0
  28. package/dist/features/proposals/optionInference.js +46 -0
  29. package/dist/features/proposals/recordNormalization.d.ts +6 -0
  30. package/dist/features/proposals/recordNormalization.js +78 -0
  31. package/dist/features/proposals/relationshipNormalization.d.ts +8 -0
  32. package/dist/features/proposals/relationshipNormalization.js +71 -0
  33. package/dist/{ai/proposalRepair.d.ts → features/proposals/repair.d.ts} +1 -1
  34. package/dist/{ai/proposalSigning.d.ts → features/proposals/signing.d.ts} +2 -5
  35. package/dist/{ai/proposalSigning.js → features/proposals/signing.js} +1 -1
  36. package/dist/features/proposals/target.d.ts +52 -0
  37. package/dist/features/proposals/target.js +125 -0
  38. package/dist/features/proposals/types.d.ts +49 -0
  39. package/dist/features/proposals/types.js +1 -0
  40. package/dist/features/proposals/validation.d.ts +12 -0
  41. package/dist/features/proposals/validation.js +26 -0
  42. package/dist/features/providers/requestContext.d.ts +53 -0
  43. package/dist/features/providers/requestContext.js +90 -0
  44. package/dist/{ai/providerRuntime.d.ts → features/providers/runtime.d.ts} +1 -1
  45. package/dist/{ai/providerRuntime.js → features/providers/runtime.js} +1 -1
  46. package/dist/features/schema/context.d.ts +7 -0
  47. package/dist/features/schema/context.js +11 -0
  48. package/dist/{payload/schemaContext.d.ts → features/schema/description.d.ts} +6 -33
  49. package/dist/{payload/schemaContext.js → features/schema/description.js} +3 -207
  50. package/dist/{payload/toolFieldSelection.d.ts → features/schema/fieldSelection.d.ts} +1 -1
  51. package/dist/{payload/toolFieldSelection.js → features/schema/fieldSelection.js} +2 -2
  52. package/dist/features/schema/mentionDocuments.d.ts +15 -0
  53. package/dist/features/schema/mentionDocuments.js +50 -0
  54. package/dist/features/schema/mentions.d.ts +18 -0
  55. package/dist/features/schema/mentions.js +100 -0
  56. package/dist/{payload/normalizeData.js → features/schema/normalize.js} +1 -1
  57. package/dist/features/schema/registry.d.ts +30 -0
  58. package/dist/features/schema/registry.js +73 -0
  59. package/dist/{payload → features/schema}/toolSchemas.d.ts +1 -1
  60. package/dist/{payload → features/schema}/toolSchemas.js +1 -1
  61. package/dist/{ai → features}/sensitiveData.js +1 -1
  62. package/dist/{ai → features}/tokenUsage.d.ts +1 -2
  63. package/dist/handlers/apply/audit.d.ts +42 -0
  64. package/dist/handlers/apply/audit.js +150 -0
  65. package/dist/handlers/apply/operations.d.ts +18 -0
  66. package/dist/handlers/apply/operations.js +377 -0
  67. package/dist/handlers/apply/types.d.ts +33 -0
  68. package/dist/handlers/apply/types.js +1 -0
  69. package/dist/handlers/apply/validation.d.ts +45 -0
  70. package/dist/handlers/apply/validation.js +125 -0
  71. package/dist/handlers/applyActionHandler.d.ts +1 -6
  72. package/dist/handlers/applyActionHandler.js +13 -757
  73. package/dist/handlers/auditLogHandler.js +4 -8
  74. package/dist/handlers/chat/intent.d.ts +32 -0
  75. package/dist/handlers/chat/intent.js +155 -0
  76. package/dist/handlers/chat/prompt.d.ts +20 -0
  77. package/dist/handlers/chat/prompt.js +55 -0
  78. package/dist/handlers/chat/proposalTools.d.ts +96 -0
  79. package/dist/handlers/chat/proposalTools.js +451 -0
  80. package/dist/handlers/chat/streaming.d.ts +38 -0
  81. package/dist/handlers/chat/streaming.js +136 -0
  82. package/dist/handlers/chat/toolFactory.d.ts +79 -0
  83. package/dist/handlers/chat/toolFactory.js +156 -0
  84. package/dist/handlers/chat/types.d.ts +57 -0
  85. package/dist/handlers/chat/types.js +1 -0
  86. package/dist/handlers/chatHandler.d.ts +1 -44
  87. package/dist/handlers/chatHandler.js +186 -1162
  88. package/dist/handlers/generateFieldHandler.d.ts +3 -8
  89. package/dist/handlers/generateFieldHandler.js +71 -99
  90. package/dist/handlers/http.d.ts +17 -0
  91. package/dist/handlers/http.js +21 -0
  92. package/dist/handlers/mediaUploadHandler.js +12 -34
  93. package/dist/handlers/mentionSuggestionHandler.d.ts +1 -1
  94. package/dist/handlers/mentionSuggestionHandler.js +6 -10
  95. package/dist/handlers/proposalDiffHandler.d.ts +1 -1
  96. package/dist/handlers/proposalDiffHandler.js +72 -195
  97. package/dist/handlers/translateDocumentHandler.d.ts +3 -8
  98. package/dist/handlers/translateDocumentHandler.js +26 -82
  99. package/dist/index.d.ts +4 -30
  100. package/dist/index.js +31 -421
  101. package/dist/plugin/admin.d.ts +30 -0
  102. package/dist/plugin/admin.js +155 -0
  103. package/dist/plugin/collections.d.ts +3 -0
  104. package/dist/plugin/collections.js +169 -0
  105. package/dist/plugin/endpoints.d.ts +23 -0
  106. package/dist/plugin/endpoints.js +84 -0
  107. package/dist/plugin/options.d.ts +4 -0
  108. package/dist/plugin/options.js +13 -0
  109. package/dist/plugin/types.d.ts +28 -0
  110. package/dist/plugin/types.js +1 -0
  111. package/dist/{payload/shared.d.ts → utils/data.d.ts} +2 -12
  112. package/package.json +1 -1
  113. package/dist/payload/proposalData.js +0 -578
  114. /package/dist/{payload → features}/collectionPermissions.d.ts +0 -0
  115. /package/dist/{payload → features/content}/documentTranslation.d.ts +0 -0
  116. /package/dist/{payload → features/content}/documentTranslation.js +0 -0
  117. /package/dist/{ai → features}/promptCaching.js +0 -0
  118. /package/dist/{ai/proposalRepair.js → features/proposals/repair.js} +0 -0
  119. /package/dist/{ai/providerOptions.d.ts → features/providers/options.d.ts} +0 -0
  120. /package/dist/{ai/providerOptions.js → features/providers/options.js} +0 -0
  121. /package/dist/{payload/normalizeData.d.ts → features/schema/normalize.d.ts} +0 -0
  122. /package/dist/{ai → features}/sensitiveData.d.ts +0 -0
  123. /package/dist/{ai → features}/tokenUsage.js +0 -0
  124. /package/dist/{payload/shared.js → utils/data.js} +0 -0
  125. /package/dist/{payload → utils}/logging.d.ts +0 -0
  126. /package/dist/{payload → utils}/logging.js +0 -0
@@ -1,578 +0,0 @@
1
- import { getSafeProposalLabel, getOptionValue, isRecord } from "./shared.js";
2
- import { createLexicalText, getSchemaFields, normalizeAuthData, normalizeDataForFields } from "./normalizeData.js";
3
- const isTitleLikeField = (field, titleFieldName)=>{
4
- const normalizedName = field.name?.toLowerCase();
5
- return Boolean(field.name && (field.name === titleFieldName || normalizedName === "title" || normalizedName === "name" || normalizedName === "label" || normalizedName === "headline"));
6
- };
7
- const getFieldOptionValues = (field)=>{
8
- return (field.options || []).map((option)=>getOptionValue(option)).filter((option)=>Boolean(option));
9
- };
10
- const escapeRegExp = (value)=>value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
11
- const getFieldNameVariants = (fieldName)=>{
12
- if (!fieldName) return [];
13
- const spacedName = fieldName.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").toLowerCase();
14
- return Array.from(new Set([
15
- fieldName.toLowerCase(),
16
- spacedName
17
- ])).filter(Boolean);
18
- };
19
- const inferOptionValueFromText = ({ field, requireFieldMention = false, text })=>{
20
- const normalizedText = text?.trim().toLowerCase();
21
- if (!normalizedText) return undefined;
22
- if (requireFieldMention) {
23
- const fieldMentioned = getFieldNameVariants(field.name).some((variant)=>{
24
- const pattern = new RegExp(`\\b${escapeRegExp(variant)}\\b`, "i");
25
- return pattern.test(normalizedText);
26
- });
27
- if (!fieldMentioned) return undefined;
28
- }
29
- const optionValues = getFieldOptionValues(field).sort((left, right)=>right.length - left.length);
30
- return optionValues.find((optionValue)=>{
31
- const pattern = new RegExp(`\\b${escapeRegExp(optionValue.toLowerCase())}\\b`, "i");
32
- return pattern.test(normalizedText);
33
- });
34
- };
35
- const getDefaultFieldValue = ({ field, inferenceText, label, titleFieldName })=>{
36
- if (field.name === "_status") return "draft";
37
- if (field.type === "checkbox") return false;
38
- if (field.type === "select" || field.type === "radio") {
39
- const inferredOptionValue = inferOptionValueFromText({
40
- field,
41
- requireFieldMention: true,
42
- text: inferenceText || label
43
- });
44
- if (inferredOptionValue !== undefined) {
45
- return inferredOptionValue;
46
- }
47
- if (field.defaultValue !== undefined) {
48
- return field.defaultValue;
49
- }
50
- return getOptionValue(field.options?.[0]);
51
- }
52
- if (field.defaultValue !== undefined) return field.defaultValue;
53
- if ([
54
- "email",
55
- "text",
56
- "textarea"
57
- ].includes(field.type || "") && isTitleLikeField(field, titleFieldName)) {
58
- return getSafeProposalLabel(label);
59
- }
60
- return undefined;
61
- };
62
- const addIssue = (issues, issue)=>{
63
- issues.push(issue);
64
- };
65
- const normalizeRelationshipScalar = (value)=>{
66
- if (typeof value === "number") {
67
- if (!Number.isInteger(value) || value <= 0) return undefined;
68
- return value;
69
- }
70
- const trimmedValue = value.trim();
71
- if (!trimmedValue || /\s/.test(trimmedValue)) return undefined;
72
- if (/^\d+$/.test(trimmedValue)) {
73
- const numericValue = Number(trimmedValue);
74
- return numericValue > 0 ? numericValue : undefined;
75
- }
76
- return trimmedValue;
77
- };
78
- const normalizeRelationshipValue = ({ field, issues, path, value })=>{
79
- const allowedRelationTargets = Array.isArray(field.relationTo) ? field.relationTo.filter((item)=>typeof item === "string") : typeof field.relationTo === "string" ? [
80
- field.relationTo
81
- ] : [];
82
- const normalizeSingle = (item, itemPath)=>{
83
- if (typeof item === "number") {
84
- const normalizedValue = normalizeRelationshipScalar(item);
85
- if (normalizedValue !== undefined) {
86
- return normalizedValue;
87
- }
88
- addIssue(issues, {
89
- code: "invalid_relationship",
90
- message: "Relationship and upload fields must use a valid document ID.",
91
- path: itemPath
92
- });
93
- return undefined;
94
- }
95
- if (typeof item === "string") {
96
- const normalizedValue = normalizeRelationshipScalar(item);
97
- if (normalizedValue !== undefined) {
98
- return normalizedValue;
99
- }
100
- addIssue(issues, {
101
- code: "invalid_relationship",
102
- message: "Relationship and upload fields must use a valid document ID, not free text.",
103
- path: itemPath
104
- });
105
- return undefined;
106
- }
107
- if (!isRecord(item)) {
108
- addIssue(issues, {
109
- code: "invalid_relationship",
110
- message: "Relationship and upload fields must use a document ID or an object with id/value.",
111
- path: itemPath
112
- });
113
- return undefined;
114
- }
115
- if (typeof item.id === "string" || typeof item.id === "number") {
116
- const normalizedValue = normalizeRelationshipScalar(item.id);
117
- if (normalizedValue !== undefined) {
118
- return normalizedValue;
119
- }
120
- addIssue(issues, {
121
- code: "invalid_relationship",
122
- message: "Relationship and upload fields must use a valid document ID.",
123
- path: itemPath
124
- });
125
- return undefined;
126
- }
127
- if (typeof item.value === "string" || typeof item.value === "number") {
128
- const normalizedValue = normalizeRelationshipScalar(item.value);
129
- if (normalizedValue === undefined) {
130
- addIssue(issues, {
131
- code: "invalid_relationship",
132
- message: "Relationship and upload fields must use a valid document ID.",
133
- path: itemPath
134
- });
135
- return undefined;
136
- }
137
- if (allowedRelationTargets.length > 1) {
138
- const relationTo = typeof item.relationTo === "string" ? item.relationTo : null;
139
- if (!relationTo || !allowedRelationTargets.includes(relationTo)) {
140
- addIssue(issues, {
141
- code: "invalid_relationship",
142
- message: `Relationship must include one of: ${allowedRelationTargets.join(", ")}.`,
143
- path: itemPath
144
- });
145
- return undefined;
146
- }
147
- return {
148
- relationTo,
149
- value: normalizedValue
150
- };
151
- }
152
- return normalizedValue;
153
- }
154
- addIssue(issues, {
155
- code: "invalid_relationship",
156
- message: "Relationship and upload fields must use a document ID or an object with id/value.",
157
- path: itemPath
158
- });
159
- return undefined;
160
- };
161
- if (field.hasMany) {
162
- if (!Array.isArray(value)) {
163
- addIssue(issues, {
164
- code: "invalid_relationship",
165
- message: "Relationship field expects an array of document IDs.",
166
- path
167
- });
168
- return undefined;
169
- }
170
- const normalizedValues = value.map((item, index)=>normalizeSingle(item, `${path}.${index}`)).filter((item)=>item !== undefined);
171
- return normalizedValues;
172
- }
173
- return normalizeSingle(value, path);
174
- };
175
- const normalizeFieldValue = ({ coercedFields, enforceRequiredChildren, field, inferenceText, issues, label, mode, path, titleFieldName, value })=>{
176
- if (field.type === "group") {
177
- if (!isRecord(value)) {
178
- addIssue(issues, {
179
- code: "invalid_container",
180
- message: "Group fields must be objects.",
181
- path
182
- });
183
- return undefined;
184
- }
185
- return normalizeRecordForFields({
186
- allowSafeFallback: false,
187
- coercedFields,
188
- enforceRequiredChildren: mode === "create" || enforceRequiredChildren,
189
- fields: field.fields || [],
190
- inferenceText,
191
- issues,
192
- label,
193
- mode,
194
- path,
195
- titleFieldName,
196
- value
197
- });
198
- }
199
- if (field.type === "array") {
200
- if (!Array.isArray(value)) {
201
- addIssue(issues, {
202
- code: "invalid_array",
203
- message: "Array fields must use an array value.",
204
- path
205
- });
206
- return undefined;
207
- }
208
- const childFields = (field.fields || []).filter((childField)=>Boolean(childField.name));
209
- const itemLabelField = childFields.find((childField)=>childField.name === "label") || childFields.find((childField)=>childField.name === "title") || childFields.find((childField)=>childField.name === "name") || childFields.find((childField)=>childField.name === "value") || childFields[0];
210
- return value.map((item, index)=>{
211
- const itemPath = `${path}.${index}`;
212
- if (!isRecord(item)) {
213
- if (!itemLabelField) {
214
- addIssue(issues, {
215
- code: "invalid_array",
216
- message: "Array items must be objects for this field.",
217
- path: itemPath
218
- });
219
- return undefined;
220
- }
221
- const wrappedItem = {
222
- [itemLabelField.name]: item
223
- };
224
- return normalizeRecordForFields({
225
- allowSafeFallback: false,
226
- coercedFields,
227
- enforceRequiredChildren: true,
228
- fields: field.fields || [],
229
- inferenceText,
230
- issues,
231
- label,
232
- mode,
233
- path: itemPath,
234
- titleFieldName,
235
- value: wrappedItem
236
- });
237
- }
238
- return normalizeRecordForFields({
239
- allowSafeFallback: false,
240
- coercedFields,
241
- enforceRequiredChildren: true,
242
- fields: field.fields || [],
243
- inferenceText,
244
- issues,
245
- label,
246
- mode,
247
- path: itemPath,
248
- titleFieldName,
249
- value: item
250
- });
251
- });
252
- }
253
- if (field.type === "blocks") {
254
- if (!Array.isArray(value)) {
255
- addIssue(issues, {
256
- code: "invalid_blocks",
257
- message: "Blocks fields must use an array value.",
258
- path
259
- });
260
- return undefined;
261
- }
262
- return value.map((item, index)=>{
263
- const itemPath = `${path}.${index}`;
264
- if (!isRecord(item)) {
265
- addIssue(issues, {
266
- code: "invalid_blocks",
267
- message: "Each block entry must be an object.",
268
- path: itemPath
269
- });
270
- return undefined;
271
- }
272
- const blockType = typeof item.blockType === "string" ? item.blockType : typeof item.type === "string" ? item.type : typeof item.slug === "string" ? item.slug : null;
273
- if (!blockType) {
274
- addIssue(issues, {
275
- code: "invalid_block_type",
276
- message: "Each block entry must include blockType.",
277
- path: itemPath
278
- });
279
- return undefined;
280
- }
281
- const block = field.blocks?.find((candidate)=>candidate.slug === blockType);
282
- if (!block) {
283
- addIssue(issues, {
284
- code: "invalid_block_type",
285
- message: `Unknown block type "${blockType}".`,
286
- path: `${itemPath}.blockType`
287
- });
288
- return undefined;
289
- }
290
- const { blockType: _blockType, slug: _slug, type: _type, ...blockData } = item;
291
- const normalizedBlock = normalizeRecordForFields({
292
- allowSafeFallback: false,
293
- coercedFields,
294
- enforceRequiredChildren: true,
295
- fields: block.fields || [],
296
- inferenceText,
297
- issues,
298
- label,
299
- mode,
300
- path: itemPath,
301
- titleFieldName,
302
- value: blockData
303
- });
304
- return {
305
- ...normalizedBlock,
306
- blockType
307
- };
308
- });
309
- }
310
- if (field.type === "checkbox") {
311
- if (typeof value === "boolean") return value;
312
- if (value === "true") return true;
313
- if (value === "false") return false;
314
- addIssue(issues, {
315
- code: "invalid_checkbox",
316
- message: "Checkbox fields must use true or false.",
317
- path
318
- });
319
- return undefined;
320
- }
321
- if (field.type === "relationship" || field.type === "upload") {
322
- return normalizeRelationshipValue({
323
- field,
324
- issues,
325
- path,
326
- value
327
- });
328
- }
329
- if (field.type === "richText") return createLexicalText(value);
330
- if (field.type === "select" || field.type === "radio") {
331
- const optionValues = getFieldOptionValues(field);
332
- const stringValue = value === null ? "" : String(value);
333
- const inferredOptionValue = inferOptionValueFromText({
334
- field,
335
- requireFieldMention: true,
336
- text: inferenceText || label
337
- });
338
- if (inferredOptionValue && optionValues.includes(inferredOptionValue)) {
339
- if (stringValue !== inferredOptionValue) {
340
- coercedFields.push(path);
341
- }
342
- return inferredOptionValue;
343
- }
344
- if (stringValue && optionValues.includes(stringValue)) return stringValue;
345
- addIssue(issues, {
346
- code: "invalid_option",
347
- message: `Field must use one of: ${optionValues.join(", ")}.`,
348
- path
349
- });
350
- return undefined;
351
- }
352
- if ([
353
- "email",
354
- "text",
355
- "textarea"
356
- ].includes(field.type || "")) {
357
- return value === null ? value : String(value);
358
- }
359
- if (field.type === "date") {
360
- const date = new Date(String(value));
361
- if (Number.isNaN(date.getTime())) {
362
- addIssue(issues, {
363
- code: "invalid_date",
364
- message: "Date fields must use a valid date value.",
365
- path
366
- });
367
- return undefined;
368
- }
369
- return date.toISOString();
370
- }
371
- return value;
372
- };
373
- const normalizeRecordForFields = ({ allowSafeFallback, coercedFields, enforceRequiredChildren, fields, inferenceText, issues, label, mode, path, titleFieldName, value })=>{
374
- const normalizedData = {};
375
- const fieldsByName = new Map(fields.filter((field)=>Boolean(field.name)).map((field)=>[
376
- field.name,
377
- field
378
- ]));
379
- for (const [key, fieldValue] of Object.entries(value)){
380
- const field = fieldsByName.get(key);
381
- const fieldPath = path ? `${path}.${key}` : key;
382
- if (!field) {
383
- addIssue(issues, {
384
- code: "unknown_field",
385
- message: "Field does not exist in the schema.",
386
- path: fieldPath
387
- });
388
- continue;
389
- }
390
- const normalizedValue = normalizeFieldValue({
391
- coercedFields,
392
- enforceRequiredChildren,
393
- field,
394
- inferenceText,
395
- issues,
396
- label,
397
- mode,
398
- path: fieldPath,
399
- titleFieldName,
400
- value: fieldValue
401
- });
402
- if (normalizedValue !== undefined) {
403
- normalizedData[key] = normalizedValue;
404
- }
405
- }
406
- if (mode === "create" || enforceRequiredChildren) {
407
- for (const field of fields.filter((candidate)=>Boolean(candidate.name) && candidate.required === true)){
408
- const fieldPath = path ? `${path}.${field.name}` : field.name;
409
- if (normalizedData[field.name] === undefined) {
410
- if (allowSafeFallback) {
411
- const fallbackValue = getDefaultFieldValue({
412
- field,
413
- inferenceText,
414
- label,
415
- titleFieldName
416
- });
417
- if (fallbackValue !== undefined) {
418
- normalizedData[field.name] = fallbackValue;
419
- continue;
420
- }
421
- }
422
- addIssue(issues, {
423
- code: "missing_required_field",
424
- message: "Required field is missing.",
425
- path: fieldPath
426
- });
427
- }
428
- }
429
- }
430
- for (const field of fields.filter((candidate)=>Boolean(candidate.name))){
431
- if (normalizedData[field.name] !== undefined) continue;
432
- if (field.type !== "select" && field.type !== "radio") continue;
433
- const inferredOptionValue = inferOptionValueFromText({
434
- field,
435
- requireFieldMention: true,
436
- text: inferenceText || label
437
- });
438
- if (inferredOptionValue !== undefined) {
439
- normalizedData[field.name] = inferredOptionValue;
440
- coercedFields.push(path ? `${path}.${field.name}` : field.name);
441
- }
442
- }
443
- return normalizedData;
444
- };
445
- const prepareSingleLocaleData = ({ coercedFields, data, fields, inferenceText, issues, label, mode, titleFieldName })=>{
446
- const normalizedData = normalizeRecordForFields({
447
- allowSafeFallback: true,
448
- coercedFields,
449
- enforceRequiredChildren: false,
450
- fields,
451
- inferenceText,
452
- issues,
453
- label,
454
- mode,
455
- path: "",
456
- titleFieldName,
457
- value: data
458
- });
459
- return normalizeDataForFields(fields, normalizedData).data;
460
- };
461
- export const prepareProposalWriteData = ({ collectionConfig, data, inferenceText, label, localizedData, mode })=>{
462
- const schemaFields = getSchemaFields(collectionConfig);
463
- const titleFieldName = typeof collectionConfig?.admin?.useAsTitle === "string" ? collectionConfig.admin.useAsTitle : undefined;
464
- const issues = [];
465
- const coercedFields = [];
466
- if (localizedData) {
467
- const localeEntries = Object.entries(localizedData);
468
- if (localeEntries.length === 0) {
469
- addIssue(issues, {
470
- code: "empty_localized_data",
471
- message: "localizedData must contain at least one locale entry.",
472
- path: "localizedData"
473
- });
474
- return {
475
- coercedFields,
476
- issues,
477
- localizedData: {}
478
- };
479
- }
480
- const normalizedLocalizedData = {};
481
- for (const [locale, localeValue] of localeEntries){
482
- if (!isRecord(localeValue)) {
483
- addIssue(issues, {
484
- code: "invalid_container",
485
- message: "Each locale entry must be an object.",
486
- path: `localizedData.${locale}`
487
- });
488
- continue;
489
- }
490
- const normalizedLocaleData = prepareSingleLocaleData({
491
- coercedFields,
492
- data: localeValue,
493
- fields: schemaFields,
494
- inferenceText,
495
- issues,
496
- label,
497
- mode,
498
- titleFieldName
499
- });
500
- normalizedLocalizedData[locale] = normalizedLocaleData;
501
- }
502
- const [firstLocale] = localeEntries[0] || [];
503
- if (firstLocale) {
504
- for (const field of schemaFields.filter((candidate)=>Boolean(candidate.name))){
505
- if (!field.localized) {
506
- for (const [locale, localeValue] of Object.entries(normalizedLocalizedData)){
507
- if (locale === firstLocale) continue;
508
- if (localeValue[field.name] !== undefined) {
509
- addIssue(issues, {
510
- code: "non_localized_field_in_secondary_locale",
511
- message: "Non-localized fields may only be set in the first locale entry.",
512
- path: `localizedData.${locale}.${field.name}`
513
- });
514
- }
515
- }
516
- }
517
- }
518
- }
519
- const normalizedResult = {};
520
- for (const [locale, localeValue] of Object.entries(normalizedLocalizedData)){
521
- normalizedResult[locale] = normalizeAuthData(collectionConfig, {
522
- coercedFields: [],
523
- data: localeValue,
524
- droppedFields: []
525
- }).data;
526
- }
527
- return {
528
- coercedFields,
529
- issues,
530
- localizedData: normalizedResult
531
- };
532
- }
533
- const sourceData = data || {};
534
- const normalizedData = prepareSingleLocaleData({
535
- coercedFields,
536
- data: sourceData,
537
- fields: schemaFields,
538
- inferenceText,
539
- issues,
540
- label,
541
- mode,
542
- titleFieldName
543
- });
544
- const authNormalized = normalizeAuthData(collectionConfig, {
545
- coercedFields: [],
546
- data: normalizedData,
547
- droppedFields: []
548
- });
549
- coercedFields.push(...authNormalized.coercedFields);
550
- return {
551
- coercedFields,
552
- data: authNormalized.data,
553
- issues
554
- };
555
- };
556
- export const applyLocalizedRequiredFallbackToPreparedData = ({ fallbackSource, fields, preparedData })=>{
557
- const mergedData = {
558
- ...preparedData
559
- };
560
- for (const field of fields.filter((candidate)=>Boolean(candidate.name))){
561
- if (field.localized && field.required && mergedData[field.name] === undefined && fallbackSource[field.name] !== undefined) {
562
- mergedData[field.name] = fallbackSource[field.name];
563
- continue;
564
- }
565
- if (field.type === "group" && field.fields?.length && isRecord(fallbackSource[field.name])) {
566
- const currentValue = isRecord(mergedData[field.name]) ? mergedData[field.name] : {};
567
- const nestedValue = applyLocalizedRequiredFallbackToPreparedData({
568
- fallbackSource: fallbackSource[field.name],
569
- fields: field.fields,
570
- preparedData: currentValue
571
- });
572
- if (Object.keys(nestedValue).length > 0) {
573
- mergedData[field.name] = nestedValue;
574
- }
575
- }
576
- }
577
- return mergedData;
578
- };
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes