@payloadcms/richtext-lexical 3.0.0-beta.45 → 3.0.0-beta.47

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 (129) hide show
  1. package/dist/field/features/blocks/component/BlockContent.d.ts.map +1 -1
  2. package/dist/field/features/blocks/component/BlockContent.js +12 -9
  3. package/dist/field/features/blocks/component/BlockContent.js.map +1 -1
  4. package/dist/field/features/blocks/component/index.d.ts +0 -1
  5. package/dist/field/features/blocks/component/index.d.ts.map +1 -1
  6. package/dist/field/features/blocks/component/index.js +3 -6
  7. package/dist/field/features/blocks/component/index.js.map +1 -1
  8. package/dist/field/features/blocks/feature.server.d.ts.map +1 -1
  9. package/dist/field/features/blocks/feature.server.js +11 -65
  10. package/dist/field/features/blocks/feature.server.js.map +1 -1
  11. package/dist/field/features/blocks/{populationPromise.d.ts → graphQLPopulationPromise.d.ts} +1 -1
  12. package/dist/field/features/blocks/graphQLPopulationPromise.d.ts.map +1 -0
  13. package/dist/field/features/blocks/{populationPromise.js → graphQLPopulationPromise.js} +6 -7
  14. package/dist/field/features/blocks/graphQLPopulationPromise.js.map +1 -0
  15. package/dist/field/features/link/drawer/baseFields.d.ts +2 -2
  16. package/dist/field/features/link/drawer/baseFields.d.ts.map +1 -1
  17. package/dist/field/features/link/drawer/baseFields.js.map +1 -1
  18. package/dist/field/features/link/feature.server.d.ts +3 -3
  19. package/dist/field/features/link/feature.server.d.ts.map +1 -1
  20. package/dist/field/features/link/feature.server.js +16 -15
  21. package/dist/field/features/link/feature.server.js.map +1 -1
  22. package/dist/field/features/link/{populationPromise.d.ts → graphQLPopulationPromise.d.ts} +1 -1
  23. package/dist/field/features/link/graphQLPopulationPromise.d.ts.map +1 -0
  24. package/dist/field/features/link/{populationPromise.js → graphQLPopulationPromise.js} +4 -4
  25. package/dist/field/features/link/graphQLPopulationPromise.js.map +1 -0
  26. package/dist/field/features/link/nodes/AutoLinkNode.js +2 -0
  27. package/dist/field/features/link/nodes/AutoLinkNode.js.map +1 -1
  28. package/dist/field/features/link/nodes/LinkNode.d.ts +7 -6
  29. package/dist/field/features/link/nodes/LinkNode.d.ts.map +1 -1
  30. package/dist/field/features/link/nodes/LinkNode.js +23 -5
  31. package/dist/field/features/link/nodes/LinkNode.js.map +1 -1
  32. package/dist/field/features/link/nodes/types.d.ts +2 -1
  33. package/dist/field/features/link/nodes/types.d.ts.map +1 -1
  34. package/dist/field/features/link/nodes/types.js.map +1 -1
  35. package/dist/field/features/link/plugins/floatingLinkEditor/LinkEditor/index.d.ts.map +1 -1
  36. package/dist/field/features/link/plugins/floatingLinkEditor/LinkEditor/index.js +1 -0
  37. package/dist/field/features/link/plugins/floatingLinkEditor/LinkEditor/index.js.map +1 -1
  38. package/dist/field/features/link/plugins/floatingLinkEditor/utilities.d.ts +2 -2
  39. package/dist/field/features/link/plugins/floatingLinkEditor/utilities.d.ts.map +1 -1
  40. package/dist/field/features/link/plugins/floatingLinkEditor/utilities.js.map +1 -1
  41. package/dist/field/features/link/plugins/link/index.js +2 -2
  42. package/dist/field/features/link/plugins/link/index.js.map +1 -1
  43. package/dist/field/features/link/validate.d.ts +2 -1
  44. package/dist/field/features/link/validate.d.ts.map +1 -1
  45. package/dist/field/features/link/validate.js +5 -9
  46. package/dist/field/features/link/validate.js.map +1 -1
  47. package/dist/field/features/relationship/feature.server.d.ts.map +1 -1
  48. package/dist/field/features/relationship/feature.server.js +35 -4
  49. package/dist/field/features/relationship/feature.server.js.map +1 -1
  50. package/dist/field/features/relationship/{populationPromise.d.ts → graphQLPopulationPromise.d.ts} +1 -1
  51. package/dist/field/features/relationship/graphQLPopulationPromise.d.ts.map +1 -0
  52. package/dist/field/features/relationship/{populationPromise.js → graphQLPopulationPromise.js} +3 -4
  53. package/dist/field/features/relationship/graphQLPopulationPromise.js.map +1 -0
  54. package/dist/field/features/types.d.ts +114 -31
  55. package/dist/field/features/types.d.ts.map +1 -1
  56. package/dist/field/features/types.js.map +1 -1
  57. package/dist/field/features/upload/drawer/index.d.ts.map +1 -1
  58. package/dist/field/features/upload/drawer/index.js +0 -1
  59. package/dist/field/features/upload/drawer/index.js.map +1 -1
  60. package/dist/field/features/upload/feature.server.d.ts.map +1 -1
  61. package/dist/field/features/upload/feature.server.js +50 -3
  62. package/dist/field/features/upload/feature.server.js.map +1 -1
  63. package/dist/field/features/upload/{populationPromise.d.ts → graphQLPopulationPromise.d.ts} +1 -1
  64. package/dist/field/features/upload/graphQLPopulationPromise.d.ts.map +1 -0
  65. package/dist/field/features/upload/graphQLPopulationPromise.js +52 -0
  66. package/dist/field/features/upload/graphQLPopulationPromise.js.map +1 -0
  67. package/dist/field/features/upload/nodes/UploadNode.d.ts +3 -2
  68. package/dist/field/features/upload/nodes/UploadNode.d.ts.map +1 -1
  69. package/dist/field/features/upload/nodes/UploadNode.js +11 -2
  70. package/dist/field/features/upload/nodes/UploadNode.js.map +1 -1
  71. package/dist/field/features/upload/plugin/index.d.ts +1 -1
  72. package/dist/field/features/upload/plugin/index.d.ts.map +1 -1
  73. package/dist/field/features/upload/plugin/index.js +1 -0
  74. package/dist/field/features/upload/plugin/index.js.map +1 -1
  75. package/dist/field/lexical/config/server/loader.d.ts.map +1 -1
  76. package/dist/field/lexical/config/server/loader.js.map +1 -1
  77. package/dist/field/lexical/config/server/sanitize.d.ts.map +1 -1
  78. package/dist/field/lexical/config/server/sanitize.js +11 -7
  79. package/dist/field/lexical/config/server/sanitize.js.map +1 -1
  80. package/dist/field/lexical/nodes/index.d.ts +1 -2
  81. package/dist/field/lexical/nodes/index.d.ts.map +1 -1
  82. package/dist/field/lexical/nodes/index.js.map +1 -1
  83. package/dist/field/lexical/utils/nodeFormat.d.ts +1 -2
  84. package/dist/field/lexical/utils/nodeFormat.d.ts.map +1 -1
  85. package/dist/field/lexical/utils/nodeFormat.js +1 -1
  86. package/dist/field/lexical/utils/nodeFormat.js.map +1 -1
  87. package/dist/index.d.ts +2 -2
  88. package/dist/index.d.ts.map +1 -1
  89. package/dist/index.js +416 -119
  90. package/dist/index.js.map +1 -1
  91. package/dist/populateGraphQL/defaultValue.d.ts.map +1 -0
  92. package/dist/populateGraphQL/defaultValue.js.map +1 -0
  93. package/dist/populateGraphQL/populate.d.ts +17 -0
  94. package/dist/populateGraphQL/populate.d.ts.map +1 -0
  95. package/dist/{populate → populateGraphQL}/populate.js +6 -1
  96. package/dist/populateGraphQL/populate.js.map +1 -0
  97. package/dist/{populate → populateGraphQL}/populateLexicalPopulationPromises.d.ts +1 -1
  98. package/dist/populateGraphQL/populateLexicalPopulationPromises.d.ts.map +1 -0
  99. package/dist/{populate → populateGraphQL}/populateLexicalPopulationPromises.js +2 -1
  100. package/dist/populateGraphQL/populateLexicalPopulationPromises.js.map +1 -0
  101. package/dist/{populate/recurseNestedFields.d.ts → populateGraphQL/recursivelyPopulateFieldsForGraphQL.d.ts} +2 -2
  102. package/dist/populateGraphQL/recursivelyPopulateFieldsForGraphQL.d.ts.map +1 -0
  103. package/dist/{populate/recurseNestedFields.js → populateGraphQL/recursivelyPopulateFieldsForGraphQL.js} +6 -3
  104. package/dist/populateGraphQL/recursivelyPopulateFieldsForGraphQL.js.map +1 -0
  105. package/dist/recurseNodeTree.d.ts +9 -0
  106. package/dist/recurseNodeTree.d.ts.map +1 -0
  107. package/dist/recurseNodeTree.js +27 -0
  108. package/dist/recurseNodeTree.js.map +1 -0
  109. package/package.json +9 -9
  110. package/dist/field/features/blocks/populationPromise.d.ts.map +0 -1
  111. package/dist/field/features/blocks/populationPromise.js.map +0 -1
  112. package/dist/field/features/link/populationPromise.d.ts.map +0 -1
  113. package/dist/field/features/link/populationPromise.js.map +0 -1
  114. package/dist/field/features/relationship/populationPromise.d.ts.map +0 -1
  115. package/dist/field/features/relationship/populationPromise.js.map +0 -1
  116. package/dist/field/features/upload/populationPromise.d.ts.map +0 -1
  117. package/dist/field/features/upload/populationPromise.js +0 -52
  118. package/dist/field/features/upload/populationPromise.js.map +0 -1
  119. package/dist/populate/defaultValue.d.ts.map +0 -1
  120. package/dist/populate/defaultValue.js.map +0 -1
  121. package/dist/populate/populate.d.ts +0 -22
  122. package/dist/populate/populate.d.ts.map +0 -1
  123. package/dist/populate/populate.js.map +0 -1
  124. package/dist/populate/populateLexicalPopulationPromises.d.ts.map +0 -1
  125. package/dist/populate/populateLexicalPopulationPromises.js.map +0 -1
  126. package/dist/populate/recurseNestedFields.d.ts.map +0 -1
  127. package/dist/populate/recurseNestedFields.js.map +0 -1
  128. /package/dist/{populate → populateGraphQL}/defaultValue.d.ts +0 -0
  129. /package/dist/{populate → populateGraphQL}/defaultValue.js +0 -0
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { withMergedProps } from '@payloadcms/ui/elements/withMergedProps';
2
- import { withNullableJSONSchemaType } from 'payload/utilities';
2
+ import { afterChangeTraverseFields, afterReadTraverseFields, beforeChangeTraverseFields, beforeValidateTraverseFields, withNullableJSONSchemaType } from 'payload/utilities';
3
3
  import { RichTextCell } from './cell/index.js';
4
4
  import { RichTextField } from './field/index.js';
5
5
  import { defaultEditorConfig, defaultEditorFeatures } from './field/lexical/config/server/default.js';
@@ -9,7 +9,8 @@ import { cloneDeep } from './field/lexical/utils/cloneDeep.js';
9
9
  import { getGenerateComponentMap } from './generateComponentMap.js';
10
10
  import { getGenerateSchemaMap } from './generateSchemaMap.js';
11
11
  import { i18n } from './i18n.js';
12
- import { populateLexicalPopulationPromises } from './populate/populateLexicalPopulationPromises.js';
12
+ import { populateLexicalPopulationPromises } from './populateGraphQL/populateLexicalPopulationPromises.js';
13
+ import { recurseNodeTree } from './recurseNodeTree.js';
13
14
  import { richTextValidateHOC } from './validate/index.js';
14
15
  let defaultSanitizedServerEditorConfig = null;
15
16
  export function lexicalEditor(props) {
@@ -85,104 +86,421 @@ export function lexicalEditor(props) {
85
86
  generateSchemaMap: getGenerateSchemaMap({
86
87
  resolvedFeatureMap
87
88
  }),
88
- i18n: featureI18n,
89
- /* hooks: {
90
- afterChange: finalSanitizedEditorConfig.features.hooks.afterChange,
91
- afterRead: finalSanitizedEditorConfig.features.hooks.afterRead,
92
- beforeChange: finalSanitizedEditorConfig.features.hooks.beforeChange,
93
- beforeDuplicate: finalSanitizedEditorConfig.features.hooks.beforeDuplicate,
94
- beforeValidate: finalSanitizedEditorConfig.features.hooks.beforeValidate,
95
- },*/ /* // TODO: Figure out docWithLocales / originalSiblingDoc => node matching. Can't use indexes, as the order of nodes could technically change between hooks.
96
- hooks: {
97
- afterChange: [
98
- async ({ context, findMany, operation, overrideAccess, req, value }) => {
99
- await recurseNodesAsync({
100
- callback: async (node) => {
101
- const afterChangeHooks = finalSanitizedEditorConfig.features.hooks.afterChange
102
- if (afterChangeHooks?.has(node.type)) {
103
- for (const hook of afterChangeHooks.get(node.type)) {
104
- node = await hook({ context, findMany, node, operation, overrideAccess, req })
105
- }
106
- }
107
- },
108
- nodes: (value as SerializedEditorState)?.root?.children ?? [],
109
- })
110
-
111
- return value
112
- },
113
- ],
114
- afterRead: [
115
- async ({ context, findMany, operation, overrideAccess, req, value }) => {
116
- await recurseNodesAsync({
117
- callback: async (node) => {
118
- const afterReadHooks = finalSanitizedEditorConfig.features.hooks.afterRead
119
- if (afterReadHooks?.has(node.type)) {
120
- for (const hook of afterReadHooks.get(node.type)) {
121
- node = await hook({ context, findMany, node, operation, overrideAccess, req })
122
- }
123
- }
124
- },
125
- nodes: (value as SerializedEditorState)?.root?.children ?? [],
126
- })
127
-
128
- return value
129
- },
130
- ],
131
- beforeChange: [
132
- async ({ context, findMany, operation, overrideAccess, req, value }) => {
133
- await recurseNodesAsync({
134
- callback: async (node) => {
135
- const beforeChangeHooks = finalSanitizedEditorConfig.features.hooks.beforeChange
136
- if (beforeChangeHooks?.has(node.type)) {
137
- for (const hook of beforeChangeHooks.get(node.type)) {
138
- node = await hook({ context, findMany, node, operation, overrideAccess, req })
139
- }
140
- }
141
- },
142
- nodes: (value as SerializedEditorState)?.root?.children ?? [],
143
- })
144
-
145
- return value
146
- },
147
- ],
148
- beforeDuplicate: [
149
- async ({ context, findMany, operation, overrideAccess, req, value }) => {
150
- await recurseNodesAsync({
151
- callback: async (node) => {
152
- const beforeDuplicateHooks = finalSanitizedEditorConfig.features.hooks.beforeDuplicate
153
- if (beforeDuplicateHooks?.has(node.type)) {
154
- for (const hook of beforeDuplicateHooks.get(node.type)) {
155
- node = await hook({ context, findMany, node, operation, overrideAccess, req })
156
- }
89
+ graphQLPopulationPromises ({ context, currentDepth, depth, draft, field, fieldPromises, findMany, flattenLocales, overrideAccess, populationPromises, req, showHiddenFields, siblingDoc }) {
90
+ // check if there are any features with nodes which have populationPromises for this field
91
+ if (finalSanitizedEditorConfig?.features?.graphQLPopulationPromises?.size) {
92
+ populateLexicalPopulationPromises({
93
+ context,
94
+ currentDepth: currentDepth ?? 0,
95
+ depth,
96
+ draft,
97
+ editorPopulationPromises: finalSanitizedEditorConfig.features.graphQLPopulationPromises,
98
+ field,
99
+ fieldPromises,
100
+ findMany,
101
+ flattenLocales,
102
+ overrideAccess,
103
+ populationPromises,
104
+ req,
105
+ showHiddenFields,
106
+ siblingDoc
107
+ });
157
108
  }
158
- },
159
- nodes: (value as SerializedEditorState)?.root?.children ?? [],
160
- })
161
-
162
- return value
163
- },
164
- ],
165
- beforeValidate: [
166
- async ({ context, findMany, operation, overrideAccess, req, value }) => {
167
- await recurseNodesAsync({
168
- callback: async (node) => {
169
- const beforeValidateHooks = finalSanitizedEditorConfig.features.hooks.beforeValidate
170
- if (beforeValidateHooks?.has(node.type)) {
171
- for (const hook of beforeValidateHooks.get(node.type)) {
109
+ },
110
+ hooks: {
111
+ afterChange: [
112
+ async ({ collection, context: _context, global, operation, path, req, schemaPath, value })=>{
113
+ if (!finalSanitizedEditorConfig.features.hooks.afterChange.size && !finalSanitizedEditorConfig.features.getSubFields.size) {
114
+ return value;
115
+ }
116
+ const context = _context;
117
+ const nodeIDMap = {};
118
+ /**
119
+ * Get the originalNodeIDMap from the beforeValidate hook, which is always run before this hook.
120
+ */ const originalNodeIDMap = context?.internal?.richText?.[path.join('.')]?.originalNodeIDMap;
121
+ if (!originalNodeIDMap || !Object.keys(originalNodeIDMap).length || !value) {
122
+ return value;
123
+ }
124
+ recurseNodeTree({
125
+ nodeIDMap,
126
+ nodes: value?.root?.children ?? []
127
+ });
128
+ // eslint-disable-next-line prefer-const
129
+ for (let [id, node] of Object.entries(nodeIDMap)){
130
+ const afterChangeHooks = finalSanitizedEditorConfig.features.hooks.afterChange;
131
+ if (afterChangeHooks?.has(node.type)) {
132
+ for (const hook of afterChangeHooks.get(node.type)){
133
+ if (!originalNodeIDMap[id]) {
134
+ console.warn('(afterChange) No original node found for node with id', id, 'node:', node, 'path', path.join('.'));
135
+ continue;
136
+ }
137
+ node = await hook({
138
+ context,
139
+ node,
140
+ operation,
141
+ originalNode: originalNodeIDMap[id],
142
+ parentRichTextFieldPath: path,
143
+ parentRichTextFieldSchemaPath: schemaPath,
144
+ req
145
+ });
146
+ }
147
+ }
148
+ const subFieldFn = finalSanitizedEditorConfig.features.getSubFields.get(node.type);
149
+ const subFieldDataFn = finalSanitizedEditorConfig.features.getSubFieldsData.get(node.type);
150
+ if (subFieldFn) {
151
+ const subFields = subFieldFn({
152
+ node,
153
+ req
154
+ });
155
+ const data = subFieldDataFn({
156
+ node,
157
+ req
158
+ });
159
+ const originalData = subFieldDataFn({
160
+ node: originalNodeIDMap[id],
161
+ req
162
+ });
163
+ if (subFields?.length) {
164
+ await afterChangeTraverseFields({
165
+ collection,
166
+ context,
167
+ data: originalData,
168
+ doc: data,
169
+ fields: subFields,
170
+ global,
171
+ operation,
172
+ path,
173
+ previousDoc: data,
174
+ previousSiblingDoc: {
175
+ ...data
176
+ },
177
+ req,
178
+ schemaPath,
179
+ siblingData: originalData || {},
180
+ siblingDoc: {
181
+ ...data
182
+ }
183
+ });
184
+ }
185
+ }
186
+ }
187
+ return value;
188
+ }
189
+ ],
190
+ afterRead: [
172
191
  /**
173
- * We cannot pass the originalNode here, as there is no way to map one node to a previous one, as a previous originalNode might be in a different position
174
- */ /*
175
- node = await hook({ context, findMany, node, operation, overrideAccess, req })
176
- }
177
- }
192
+ * afterRead hooks do not receive the originalNode. Thus, they can run on all nodes, not just nodes with an ID.
193
+ */ async ({ collection, context: context, currentDepth, depth, draft, fallbackLocale, fieldPromises, findMany, flattenLocales, global, locale, overrideAccess, path, populationPromises, req, schemaPath, showHiddenFields, triggerAccessControl, triggerHooks, value })=>{
194
+ if (!finalSanitizedEditorConfig.features.hooks.afterRead.size && !finalSanitizedEditorConfig.features.getSubFields.size) {
195
+ return value;
196
+ }
197
+ const flattenedNodes = [];
198
+ recurseNodeTree({
199
+ flattenedNodes,
200
+ nodes: value?.root?.children ?? []
201
+ });
202
+ for (let node of flattenedNodes){
203
+ const afterReadHooks = finalSanitizedEditorConfig.features.hooks.afterRead;
204
+ if (afterReadHooks?.has(node.type)) {
205
+ for (const hook of afterReadHooks.get(node.type)){
206
+ node = await hook({
207
+ context,
208
+ currentDepth,
209
+ depth,
210
+ draft,
211
+ fallbackLocale,
212
+ fieldPromises,
213
+ findMany,
214
+ flattenLocales,
215
+ locale,
216
+ node,
217
+ overrideAccess,
218
+ parentRichTextFieldPath: path,
219
+ parentRichTextFieldSchemaPath: schemaPath,
220
+ populationPromises,
221
+ req,
222
+ showHiddenFields,
223
+ triggerAccessControl,
224
+ triggerHooks
225
+ });
226
+ }
227
+ }
228
+ const subFieldFn = finalSanitizedEditorConfig.features.getSubFields.get(node.type);
229
+ const subFieldDataFn = finalSanitizedEditorConfig.features.getSubFieldsData.get(node.type);
230
+ if (subFieldFn) {
231
+ const subFields = subFieldFn({
232
+ node,
233
+ req
234
+ });
235
+ const data = subFieldDataFn({
236
+ node,
237
+ req
238
+ });
239
+ if (subFields?.length) {
240
+ afterReadTraverseFields({
241
+ collection,
242
+ context,
243
+ currentDepth,
244
+ depth,
245
+ doc: data,
246
+ draft,
247
+ fallbackLocale,
248
+ fieldPromises,
249
+ fields: subFields,
250
+ findMany,
251
+ flattenLocales,
252
+ global,
253
+ locale,
254
+ overrideAccess,
255
+ path,
256
+ populationPromises,
257
+ req,
258
+ schemaPath,
259
+ showHiddenFields,
260
+ siblingDoc: data,
261
+ triggerAccessControl,
262
+ triggerHooks
263
+ });
264
+ }
265
+ }
266
+ }
267
+ return value;
268
+ }
269
+ ],
270
+ beforeChange: [
271
+ async ({ collection, context: _context, duplicate, errors, field, global, mergeLocaleActions, operation, path, req, schemaPath, siblingData, siblingDocWithLocales, skipValidation, value })=>{
272
+ if (!finalSanitizedEditorConfig.features.hooks.beforeChange.size && !finalSanitizedEditorConfig.features.getSubFields.size) {
273
+ return value;
274
+ }
275
+ const context = _context;
276
+ const nodeIDMap = {};
277
+ /**
278
+ * Get the originalNodeIDMap from the beforeValidate hook, which is always run before this hook.
279
+ */ const originalNodeIDMap = context?.internal?.richText?.[path.join('.')]?.originalNodeIDMap;
280
+ if (!originalNodeIDMap || !Object.keys(originalNodeIDMap).length || !value) {
281
+ return value;
282
+ }
283
+ const originalNodeWithLocalesIDMap = {};
284
+ recurseNodeTree({
285
+ nodeIDMap,
286
+ nodes: value?.root?.children ?? []
287
+ });
288
+ if (siblingDocWithLocales?.[field.name]) {
289
+ recurseNodeTree({
290
+ nodeIDMap: originalNodeWithLocalesIDMap,
291
+ nodes: siblingDocWithLocales[field.name]?.root?.children ?? []
292
+ });
293
+ }
294
+ // eslint-disable-next-line prefer-const
295
+ for (let [id, node] of Object.entries(nodeIDMap)){
296
+ const beforeChangeHooks = finalSanitizedEditorConfig.features.hooks.beforeChange;
297
+ if (beforeChangeHooks?.has(node.type)) {
298
+ for (const hook of beforeChangeHooks.get(node.type)){
299
+ if (!originalNodeIDMap[id]) {
300
+ console.warn('(beforeChange) No original node found for node with id', id, 'node:', node, 'path', path.join('.'));
301
+ continue;
302
+ }
303
+ node = await hook({
304
+ context,
305
+ duplicate,
306
+ errors,
307
+ mergeLocaleActions,
308
+ node,
309
+ operation,
310
+ originalNode: originalNodeIDMap[id],
311
+ originalNodeWithLocales: originalNodeWithLocalesIDMap[id],
312
+ parentRichTextFieldPath: path,
313
+ parentRichTextFieldSchemaPath: schemaPath,
314
+ req,
315
+ skipValidation
316
+ });
317
+ }
318
+ }
319
+ const subFieldFn = finalSanitizedEditorConfig.features.getSubFields.get(node.type);
320
+ const subFieldDataFn = finalSanitizedEditorConfig.features.getSubFieldsData.get(node.type);
321
+ if (subFieldFn) {
322
+ const subFields = subFieldFn({
323
+ node,
324
+ req
325
+ });
326
+ const data = subFieldDataFn({
327
+ node,
328
+ req
329
+ });
330
+ const originalData = subFieldDataFn({
331
+ node: originalNodeIDMap[id],
332
+ req
333
+ });
334
+ const originalDataWithLocales = subFieldDataFn({
335
+ node: originalNodeWithLocalesIDMap[id],
336
+ req
337
+ });
338
+ if (subFields?.length) {
339
+ await beforeChangeTraverseFields({
340
+ id,
341
+ collection,
342
+ context,
343
+ data,
344
+ doc: originalData,
345
+ docWithLocales: originalDataWithLocales ?? {},
346
+ duplicate,
347
+ errors,
348
+ fields: subFields,
349
+ global,
350
+ mergeLocaleActions,
351
+ operation,
352
+ path,
353
+ req,
354
+ schemaPath,
355
+ siblingData: data,
356
+ siblingDoc: originalData,
357
+ siblingDocWithLocales: originalDataWithLocales ?? {},
358
+ skipValidation
359
+ });
360
+ }
361
+ }
362
+ }
363
+ /**
364
+ * within the beforeChange hook, id's may be re-generated.
365
+ * Example:
366
+ * 1. Seed data contains IDs for block feature blocks.
367
+ * 2. Those are used in beforeValidate
368
+ * 3. in beforeChange, those IDs are regenerated, because you cannot provide IDs during document creation. See baseIDField beforeChange hook for reasoning
369
+ * 4. Thus, in order for all post-beforeChange hooks to receive the correct ID, we need to update the originalNodeIDMap with the new ID's, by regenerating the nodeIDMap.
370
+ * The reason this is not generated for every hook, is to save on performance. We know we only really have to generate it in beforeValidate, which is the first hook,
371
+ * and in beforeChange, which is where modifications to the provided IDs can occur.
372
+ */ const newOriginalNodeIDMap = {};
373
+ const previousValue = siblingData[field.name];
374
+ recurseNodeTree({
375
+ nodeIDMap: newOriginalNodeIDMap,
376
+ nodes: previousValue?.root?.children ?? []
377
+ });
378
+ if (!context.internal) {
379
+ // Add to context, for other hooks to use
380
+ context.internal = {};
381
+ }
382
+ if (!context.internal.richText) {
383
+ context.internal.richText = {};
384
+ }
385
+ context.internal.richText[path.join('.')] = {
386
+ originalNodeIDMap: newOriginalNodeIDMap
387
+ };
388
+ return value;
389
+ }
390
+ ],
391
+ beforeValidate: [
392
+ async ({ collection, context, global, operation, overrideAccess, path, previousValue, req, schemaPath, value })=>{
393
+ // return value if there are NO hooks
394
+ if (!finalSanitizedEditorConfig.features.hooks.beforeValidate.size && !finalSanitizedEditorConfig.features.hooks.afterChange.size && !finalSanitizedEditorConfig.features.hooks.beforeChange.size && !finalSanitizedEditorConfig.features.getSubFields.size) {
395
+ return value;
396
+ }
397
+ /**
398
+ * beforeValidate is the first field hook which runs. This is where we can create the node map, which can then be used in the other hooks.
399
+ *
400
+ */ /**
401
+ * flattenedNodes contains all nodes in the editor, in the order they appear in the editor. They will be used for the following hooks:
402
+ * - afterRead
403
+ *
404
+ * The other hooks require nodes to have IDs, which is why those are ran only from the nodeIDMap. They require IDs because they have both doc/siblingDoc and data/siblingData, and
405
+ * thus require a reliable way to match new node data to old node data. Given that node positions can change in between hooks, this is only reliably possible for nodes which are saved with
406
+ * an ID.
407
+ */ //const flattenedNodes: SerializedLexicalNode[] = []
408
+ /**
409
+ * Only nodes with id's (so, nodes with hooks added to them) will be added to the nodeIDMap. They will be used for the following hooks:
410
+ * - afterChange
411
+ * - beforeChange
412
+ * - beforeValidate
413
+ * - beforeDuplicate
414
+ *
415
+ * Other hooks are handled by the flattenedNodes. All nodes in the nodeIDMap are part of flattenedNodes.
416
+ */ const originalNodeIDMap = {};
417
+ recurseNodeTree({
418
+ nodeIDMap: originalNodeIDMap,
419
+ nodes: previousValue?.root?.children ?? []
420
+ });
421
+ if (!context.internal) {
422
+ // Add to context, for other hooks to use
423
+ context.internal = {};
424
+ }
425
+ if (!context.internal.richText) {
426
+ context.internal.richText = {};
427
+ }
428
+ context.internal.richText[path.join('.')] = {
429
+ originalNodeIDMap
430
+ };
431
+ /**
432
+ * Now that the maps for all hooks are set up, we can run the validate hook
433
+ */ if (!finalSanitizedEditorConfig.features.hooks.beforeValidate.size) {
434
+ return value;
435
+ }
436
+ const nodeIDMap = {};
437
+ recurseNodeTree({
438
+ //flattenedNodes,
439
+ nodeIDMap,
440
+ nodes: value?.root?.children ?? []
441
+ });
442
+ // eslint-disable-next-line prefer-const
443
+ for (let [id, node] of Object.entries(nodeIDMap)){
444
+ const beforeValidateHooks = finalSanitizedEditorConfig.features.hooks.beforeValidate;
445
+ if (beforeValidateHooks?.has(node.type)) {
446
+ for (const hook of beforeValidateHooks.get(node.type)){
447
+ if (!originalNodeIDMap[id]) {
448
+ console.warn('(beforeValidate) No original node found for node with id', id, 'node:', node, 'path', path.join('.'));
449
+ continue;
450
+ }
451
+ node = await hook({
452
+ context,
453
+ node,
454
+ operation,
455
+ originalNode: originalNodeIDMap[id],
456
+ overrideAccess,
457
+ parentRichTextFieldPath: path,
458
+ parentRichTextFieldSchemaPath: schemaPath,
459
+ req
460
+ });
461
+ }
462
+ }
463
+ const subFieldFn = finalSanitizedEditorConfig.features.getSubFields.get(node.type);
464
+ const subFieldDataFn = finalSanitizedEditorConfig.features.getSubFieldsData.get(node.type);
465
+ if (subFieldFn) {
466
+ const subFields = subFieldFn({
467
+ node,
468
+ req
469
+ });
470
+ const data = subFieldDataFn({
471
+ node,
472
+ req
473
+ });
474
+ const originalData = subFieldDataFn({
475
+ node: originalNodeIDMap[id],
476
+ req
477
+ });
478
+ if (subFields?.length) {
479
+ await beforeValidateTraverseFields({
480
+ id,
481
+ collection,
482
+ context,
483
+ data,
484
+ doc: originalData,
485
+ fields: subFields,
486
+ global,
487
+ operation,
488
+ overrideAccess,
489
+ path,
490
+ req,
491
+ schemaPath,
492
+ siblingData: data,
493
+ siblingDoc: originalData
494
+ });
495
+ }
496
+ }
497
+ }
498
+ return value;
499
+ }
500
+ ]
178
501
  },
179
- nodes: (value as SerializedEditorState)?.root?.children ?? [],
180
- })
181
-
182
- return value
183
- },
184
- ],
185
- },*/ outputSchema: ({ collectionIDFieldTypes, config, field, interfaceNameDefinitions, isRequired })=>{
502
+ i18n: featureI18n,
503
+ outputSchema: ({ collectionIDFieldTypes, config, field, interfaceNameDefinitions, isRequired })=>{
186
504
  let outputSchema = {
187
505
  // This schema matches the SerializedEditorState type so far, that it's possible to cast SerializedEditorState to this schema without any errors.
188
506
  // In the future, we should
@@ -274,27 +592,6 @@ export function lexicalEditor(props) {
274
592
  }
275
593
  return outputSchema;
276
594
  },
277
- populationPromises ({ context, currentDepth, depth, draft, field, fieldPromises, findMany, flattenLocales, overrideAccess, populationPromises, req, showHiddenFields, siblingDoc }) {
278
- // check if there are any features with nodes which have populationPromises for this field
279
- if (finalSanitizedEditorConfig?.features?.populationPromises?.size) {
280
- populateLexicalPopulationPromises({
281
- context,
282
- currentDepth,
283
- depth,
284
- draft,
285
- editorPopulationPromises: finalSanitizedEditorConfig.features.populationPromises,
286
- field,
287
- fieldPromises,
288
- findMany,
289
- flattenLocales,
290
- overrideAccess,
291
- populationPromises,
292
- req,
293
- showHiddenFields,
294
- siblingDoc
295
- });
296
- }
297
- },
298
595
  validate: richTextValidateHOC({
299
596
  editorConfig: finalSanitizedEditorConfig
300
597
  })
@@ -378,6 +675,6 @@ export { setFloatingElemPosition } from './field/lexical/utils/setFloatingElemPo
378
675
  export { setFloatingElemPositionForLinkEditor } from './field/lexical/utils/setFloatingElemPositionForLinkEditor.js';
379
676
  export { addSwipeDownListener, addSwipeLeftListener, addSwipeRightListener, addSwipeUpListener } from './field/lexical/utils/swipe.js';
380
677
  export { sanitizeUrl, validateUrl } from './field/lexical/utils/url.js';
381
- export { defaultRichTextValue } from './populate/defaultValue.js';
678
+ export { defaultRichTextValue } from './populateGraphQL/defaultValue.js';
382
679
 
383
680
  //# sourceMappingURL=index.js.map