@payloadcms/richtext-lexical 3.0.0-beta.20 → 3.0.0-beta.22

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 (92) hide show
  1. package/dist/field/features/blocks/feature.server.d.ts.map +1 -1
  2. package/dist/field/features/blocks/feature.server.js +28 -68
  3. package/dist/field/features/blocks/feature.server.js.map +1 -1
  4. package/dist/field/features/blocks/populationPromise.d.ts.map +1 -1
  5. package/dist/field/features/blocks/populationPromise.js +0 -13
  6. package/dist/field/features/blocks/populationPromise.js.map +1 -1
  7. package/dist/field/features/blocks/validate.d.ts.map +1 -1
  8. package/dist/field/features/blocks/validate.js +2 -14
  9. package/dist/field/features/blocks/validate.js.map +1 -1
  10. package/dist/field/features/link/drawer/baseFields.d.ts +3 -3
  11. package/dist/field/features/link/drawer/baseFields.d.ts.map +1 -1
  12. package/dist/field/features/link/drawer/baseFields.js +28 -42
  13. package/dist/field/features/link/drawer/baseFields.js.map +1 -1
  14. package/dist/field/features/link/drawer/types.d.ts +4 -2
  15. package/dist/field/features/link/drawer/types.d.ts.map +1 -1
  16. package/dist/field/features/link/drawer/types.js.map +1 -1
  17. package/dist/field/features/link/feature.server.d.ts +0 -2
  18. package/dist/field/features/link/feature.server.d.ts.map +1 -1
  19. package/dist/field/features/link/feature.server.js +22 -6
  20. package/dist/field/features/link/feature.server.js.map +1 -1
  21. package/dist/field/features/link/plugins/floatingLinkEditor/LinkEditor/index.d.ts.map +1 -1
  22. package/dist/field/features/link/plugins/floatingLinkEditor/LinkEditor/index.js +38 -24
  23. package/dist/field/features/link/plugins/floatingLinkEditor/LinkEditor/index.js.map +1 -1
  24. package/dist/field/features/link/plugins/floatingLinkEditor/index.scss +9 -1
  25. package/dist/field/features/link/plugins/floatingLinkEditor/utilities.d.ts +3 -5
  26. package/dist/field/features/link/plugins/floatingLinkEditor/utilities.d.ts.map +1 -1
  27. package/dist/field/features/link/plugins/floatingLinkEditor/utilities.js +11 -29
  28. package/dist/field/features/link/plugins/floatingLinkEditor/utilities.js.map +1 -1
  29. package/dist/field/features/link/plugins/link/index.d.ts.map +1 -1
  30. package/dist/field/features/link/plugins/link/index.js +0 -6
  31. package/dist/field/features/link/plugins/link/index.js.map +1 -1
  32. package/dist/field/features/link/populationPromise.d.ts.map +1 -1
  33. package/dist/field/features/link/populationPromise.js +5 -23
  34. package/dist/field/features/link/populationPromise.js.map +1 -1
  35. package/dist/field/features/link/validate.d.ts +5 -0
  36. package/dist/field/features/link/validate.d.ts.map +1 -0
  37. package/dist/field/features/link/validate.js +32 -0
  38. package/dist/field/features/link/validate.js.map +1 -0
  39. package/dist/field/features/relationship/nodes/components/RelationshipComponent.d.ts.map +1 -1
  40. package/dist/field/features/relationship/nodes/components/RelationshipComponent.js +51 -2
  41. package/dist/field/features/relationship/nodes/components/RelationshipComponent.js.map +1 -1
  42. package/dist/field/features/types.d.ts +5 -1
  43. package/dist/field/features/types.d.ts.map +1 -1
  44. package/dist/field/features/types.js.map +1 -1
  45. package/dist/field/features/upload/feature.server.d.ts.map +1 -1
  46. package/dist/field/features/upload/feature.server.js +14 -2
  47. package/dist/field/features/upload/feature.server.js.map +1 -1
  48. package/dist/field/features/upload/populationPromise.d.ts.map +1 -1
  49. package/dist/field/features/upload/populationPromise.js +2 -12
  50. package/dist/field/features/upload/populationPromise.js.map +1 -1
  51. package/dist/field/features/upload/validate.d.ts +2 -1
  52. package/dist/field/features/upload/validate.d.ts.map +1 -1
  53. package/dist/field/features/upload/validate.js +33 -11
  54. package/dist/field/features/upload/validate.js.map +1 -1
  55. package/dist/field/lexical/LexicalEditor.js +1 -1
  56. package/dist/field/lexical/LexicalEditor.js.map +1 -1
  57. package/dist/field/lexical/config/server/default.d.ts +1 -2
  58. package/dist/field/lexical/config/server/default.d.ts.map +1 -1
  59. package/dist/field/lexical/config/server/default.js +0 -2
  60. package/dist/field/lexical/config/server/default.js.map +1 -1
  61. package/dist/field/lexical/config/server/loader.d.ts +4 -2
  62. package/dist/field/lexical/config/server/loader.d.ts.map +1 -1
  63. package/dist/field/lexical/config/server/loader.js +3 -2
  64. package/dist/field/lexical/config/server/loader.js.map +1 -1
  65. package/dist/field/lexical/config/server/sanitize.d.ts +2 -1
  66. package/dist/field/lexical/config/server/sanitize.d.ts.map +1 -1
  67. package/dist/field/lexical/config/server/sanitize.js +3 -2
  68. package/dist/field/lexical/config/server/sanitize.js.map +1 -1
  69. package/dist/field/lexical/plugins/FloatingSelectToolbar/index.d.ts.map +1 -1
  70. package/dist/field/lexical/plugins/FloatingSelectToolbar/index.js +24 -23
  71. package/dist/field/lexical/plugins/FloatingSelectToolbar/index.js.map +1 -1
  72. package/dist/field/lexical/utils/setFloatingElemPosition.d.ts +1 -1
  73. package/dist/field/lexical/utils/setFloatingElemPosition.d.ts.map +1 -1
  74. package/dist/field/lexical/utils/setFloatingElemPosition.js +15 -13
  75. package/dist/field/lexical/utils/setFloatingElemPosition.js.map +1 -1
  76. package/dist/field/lexical/utils/url.d.ts.map +1 -1
  77. package/dist/field/lexical/utils/url.js +2 -0
  78. package/dist/field/lexical/utils/url.js.map +1 -1
  79. package/dist/generateComponentMap.d.ts.map +1 -1
  80. package/dist/generateComponentMap.js +1 -10
  81. package/dist/generateComponentMap.js.map +1 -1
  82. package/dist/generateSchemaMap.d.ts.map +1 -1
  83. package/dist/generateSchemaMap.js +1 -10
  84. package/dist/generateSchemaMap.js.map +1 -1
  85. package/dist/index.d.ts +5 -5
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +241 -234
  88. package/dist/index.js.map +1 -1
  89. package/dist/types.d.ts +8 -1
  90. package/dist/types.d.ts.map +1 -1
  91. package/dist/types.js.map +1 -1
  92. package/package.json +10 -10
@@ -1 +1 @@
1
- {"version":3,"file":"feature.server.d.ts","sourceRoot":"","sources":["../../../../src/field/features/blocks/feature.server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAqB,+BAA+B,EAAE,MAAM,eAAe,CAAA;AAY9F,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,aAAa,CAAA;AAChE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AASnE,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG;IACjD,MAAM,EAAE,+BAA+B,EAAE,CAAA;CAC1C,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,YAAY,EAAE,CAAA;CACvB,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,6BAA6B,CACvD,kBAAkB,EAClB,wBAAwB,CA+MzB,CAAA"}
1
+ {"version":3,"file":"feature.server.d.ts","sourceRoot":"","sources":["../../../../src/field/features/blocks/feature.server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAqB,+BAA+B,EAAE,MAAM,eAAe,CAAA;AAM9F,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,aAAa,CAAA;AAChE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAQnE,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG;IACjD,MAAM,EAAE,+BAA+B,EAAE,CAAA;CAC1C,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,YAAY,EAAE,CAAA;CACvB,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,6BAA6B,CACvD,kBAAkB,EAClB,wBAAwB,CAsKzB,CAAA"}
@@ -1,42 +1,40 @@
1
1
  import { traverseFields } from '@payloadcms/next/utilities';
2
2
  import { baseBlockFields, sanitizeFields } from 'payload/config';
3
3
  import { fieldsToJSONSchema, formatLabels } from 'payload/utilities';
4
- import { cloneDeep } from '../../lexical/utils/cloneDeep.js';
5
4
  import { createNode } from '../typeUtilities.js';
6
5
  import { BlocksFeatureClientComponent } from './feature.client.js';
7
6
  import { BlockNode } from './nodes/BlocksNode.js';
8
7
  import { blockPopulationPromiseHOC } from './populationPromise.js';
9
8
  import { blockValidationHOC } from './validate.js';
10
9
  export const BlocksFeature = (props)=>{
11
- // Sanitization taken from payload/src/fields/config/sanitize.ts
12
- if (props?.blocks?.length) {
13
- props.blocks = props.blocks.map((block)=>{
14
- const blockCopy = cloneDeep(block);
15
- return {
16
- ...blockCopy,
17
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
18
- fields: blockCopy.fields.concat(baseBlockFields),
19
- labels: !blockCopy.labels ? formatLabels(blockCopy.slug) : blockCopy.labels
20
- };
21
- });
22
- // unSanitizedBlock.fields are sanitized in the React component and not here.
23
- // That's because we do not have access to the payload config here.
24
- }
25
- // Build clientProps
26
- const clientProps = {
27
- reducedBlocks: []
28
- };
29
- for (const block of props.blocks){
30
- clientProps.reducedBlocks.push({
31
- slug: block.slug,
32
- fieldMap: [],
33
- imageAltText: block.imageAltText,
34
- imageURL: block.imageURL,
35
- labels: block.labels
36
- });
37
- }
38
10
  return {
39
- feature: ()=>{
11
+ feature: async ({ config: _config })=>{
12
+ if (props?.blocks?.length) {
13
+ const validRelationships = _config.collections.map((c)=>c.slug) || [];
14
+ for (const block of props.blocks){
15
+ block.fields = block.fields.concat(baseBlockFields);
16
+ block.labels = !block.labels ? formatLabels(block.slug) : block.labels;
17
+ block.fields = await sanitizeFields({
18
+ config: _config,
19
+ fields: block.fields,
20
+ requireFieldLevelRichTextEditor: true,
21
+ validRelationships
22
+ });
23
+ }
24
+ }
25
+ // Build clientProps
26
+ const clientProps = {
27
+ reducedBlocks: []
28
+ };
29
+ for (const block of props.blocks){
30
+ clientProps.reducedBlocks.push({
31
+ slug: block.slug,
32
+ fieldMap: [],
33
+ imageAltText: block.imageAltText,
34
+ imageURL: block.imageURL,
35
+ labels: block.labels
36
+ });
37
+ }
40
38
  return {
41
39
  ClientComponent: BlocksFeatureClientComponent,
42
40
  clientFeatureProps: clientProps,
@@ -64,24 +62,10 @@ export const BlocksFeature = (props)=>{
64
62
  if (!props?.blocks?.length) {
65
63
  return currentSchema;
66
64
  }
67
- // sanitize blocks
68
- const validRelationships = config.collections.map((c)=>c.slug) || [];
69
- const sanitizedBlocks = props.blocks.map((block)=>{
70
- const blockCopy = cloneDeep(block);
71
- return {
72
- ...blockCopy,
73
- fields: sanitizeFields({
74
- config,
75
- fields: blockCopy.fields,
76
- requireFieldLevelRichTextEditor: true,
77
- validRelationships
78
- })
79
- };
80
- });
81
65
  const blocksField = {
82
66
  name: field?.name + '_lexical_blocks',
83
67
  type: 'blocks',
84
- blocks: sanitizedBlocks
68
+ blocks: props.blocks
85
69
  };
86
70
  // This is only done so that interfaceNameDefinitions sets those block's interfaceNames.
87
71
  // we don't actually use the JSON Schema itself in the generated types yet.
@@ -103,19 +87,6 @@ export const BlocksFeature = (props)=>{
103
87
  props.blocks.find((block) => block.slug === blockType),
104
88
  )
105
89
 
106
- // sanitize blocks
107
- const validRelationships = req.payload.config.collections.map((c) => c.slug) || []
108
-
109
- const sanitizedBlock = {
110
- ...block,
111
- fields: sanitizeFields({
112
- config: req.payload.config,
113
- fields: block.fields,
114
- requireFieldLevelRichTextEditor: true,
115
- validRelationships,
116
- }),
117
- }
118
-
119
90
 
120
91
  await beforeChangeTraverseFields({
121
92
  id: null,
@@ -147,18 +118,7 @@ export const BlocksFeature = (props)=>{
147
118
  props.blocks.find((block) => block.slug === blockType),
148
119
  )
149
120
 
150
- // sanitize blocks
151
- const validRelationships = req.payload.config.collections.map((c) => c.slug) || []
152
121
 
153
- const sanitizedBlock = {
154
- ...block,
155
- fields: sanitizeFields({
156
- config: req.payload.config,
157
- fields: block.fields,
158
- requireFieldLevelRichTextEditor: true,
159
- validRelationships,
160
- }),
161
- }
162
122
 
163
123
  await beforeValidateTraverseFields({
164
124
  id: null,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/field/features/blocks/feature.server.ts"],"sourcesContent":["import type { Block, BlockField, Field, FieldWithRichTextRequiredEditor } from 'payload/types'\n\nimport { traverseFields } from '@payloadcms/next/utilities'\nimport { baseBlockFields, sanitizeFields } from 'payload/config'\nimport {\n beforeChangeTraverseFields,\n beforeValidateTraverseFields,\n deepCopyObject,\n fieldsToJSONSchema,\n formatLabels,\n} from 'payload/utilities'\n\nimport type { FeatureProviderProviderServer } from '../types.js'\nimport type { BlocksFeatureClientProps } from './feature.client.js'\n\nimport { cloneDeep } from '../../lexical/utils/cloneDeep.js'\nimport { createNode } from '../typeUtilities.js'\nimport { BlocksFeatureClientComponent } from './feature.client.js'\nimport { BlockNode } from './nodes/BlocksNode.js'\nimport { blockPopulationPromiseHOC } from './populationPromise.js'\nimport { blockValidationHOC } from './validate.js'\n\nexport type LexicalBlock = Omit<Block, 'fields'> & {\n fields: FieldWithRichTextRequiredEditor[]\n}\n\nexport type BlocksFeatureProps = {\n blocks: LexicalBlock[]\n}\n\nexport const BlocksFeature: FeatureProviderProviderServer<\n BlocksFeatureProps,\n BlocksFeatureClientProps\n> = (props) => {\n // Sanitization taken from payload/src/fields/config/sanitize.ts\n\n if (props?.blocks?.length) {\n props.blocks = props.blocks.map((block) => {\n const blockCopy = cloneDeep(block)\n\n return {\n ...blockCopy,\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n fields: blockCopy.fields.concat(baseBlockFields as FieldWithRichTextRequiredEditor[]),\n labels: !blockCopy.labels ? formatLabels(blockCopy.slug) : blockCopy.labels,\n }\n })\n // unSanitizedBlock.fields are sanitized in the React component and not here.\n // That's because we do not have access to the payload config here.\n }\n\n // Build clientProps\n const clientProps: BlocksFeatureClientProps = {\n reducedBlocks: [],\n }\n for (const block of props.blocks) {\n clientProps.reducedBlocks.push({\n slug: block.slug,\n fieldMap: [],\n imageAltText: block.imageAltText,\n imageURL: block.imageURL,\n labels: block.labels,\n })\n }\n\n return {\n feature: () => {\n return {\n ClientComponent: BlocksFeatureClientComponent,\n clientFeatureProps: clientProps,\n generateSchemaMap: ({ config, i18n, props }) => {\n const validRelationships = config.collections.map((c) => c.slug) || []\n\n /**\n * Add sub-fields to the schemaMap. E.g. if you have an array field as part of the block, and it runs addRow, it will request these\n * sub-fields from the component map. Thus, we need to put them in the component map here.\n */\n const schemaMap = new Map<string, Field[]>()\n\n for (const block of props.blocks) {\n schemaMap.set(block.slug, block.fields || [])\n\n traverseFields({\n config,\n fields: block.fields,\n i18n,\n schemaMap,\n schemaPath: block.slug,\n validRelationships,\n })\n }\n\n return schemaMap\n },\n generatedTypes: {\n modifyOutputSchema: ({\n collectionIDFieldTypes,\n config,\n currentSchema,\n field,\n interfaceNameDefinitions,\n }) => {\n if (!props?.blocks?.length) {\n return currentSchema\n }\n\n // sanitize blocks\n const validRelationships = config.collections.map((c) => c.slug) || []\n\n const sanitizedBlocks = props.blocks.map((block) => {\n const blockCopy = cloneDeep(block)\n return {\n ...blockCopy,\n fields: sanitizeFields({\n config,\n fields: blockCopy.fields,\n requireFieldLevelRichTextEditor: true,\n validRelationships,\n }),\n }\n })\n\n const blocksField: BlockField = {\n name: field?.name + '_lexical_blocks',\n type: 'blocks',\n blocks: sanitizedBlocks,\n }\n // This is only done so that interfaceNameDefinitions sets those block's interfaceNames.\n // we don't actually use the JSON Schema itself in the generated types yet.\n fieldsToJSONSchema(\n collectionIDFieldTypes,\n [blocksField],\n interfaceNameDefinitions,\n config,\n )\n\n return currentSchema\n },\n },\n nodes: [\n createNode({\n /* // TODO: Implement these hooks once docWithLocales / originalSiblingDoc => node matching has been figured out\n hooks: {\n beforeChange: [\n async ({ context, findMany, node, operation, overrideAccess, req }) => {\n const blockType = node.fields.blockType\n\n const block = deepCopyObject(\n props.blocks.find((block) => block.slug === blockType),\n )\n\n // sanitize blocks\n const validRelationships = req.payload.config.collections.map((c) => c.slug) || []\n\n const sanitizedBlock = {\n ...block,\n fields: sanitizeFields({\n config: req.payload.config,\n fields: block.fields,\n requireFieldLevelRichTextEditor: true,\n validRelationships,\n }),\n }\n\n\n await beforeChangeTraverseFields({\n id: null,\n collection: null,\n context,\n data: node.fields,\n doc: node.fields,\n fields: sanitizedBlock.fields,\n global: null,\n mergeLocaleActions: [],\n operation:\n operation === 'create' || operation === 'update' ? operation : 'update',\n overrideAccess,\n path: '',\n req,\n siblingData: node.fields,\n siblingDoc: node.fields,\n })\n\n\n return node\n },\n ],\n beforeValidate: [\n async ({ context, findMany, node, operation, overrideAccess, req }) => {\n const blockType = node.fields.blockType\n\n const block = deepCopyObject(\n props.blocks.find((block) => block.slug === blockType),\n )\n\n // sanitize blocks\n const validRelationships = req.payload.config.collections.map((c) => c.slug) || []\n\n const sanitizedBlock = {\n ...block,\n fields: sanitizeFields({\n config: req.payload.config,\n fields: block.fields,\n requireFieldLevelRichTextEditor: true,\n validRelationships,\n }),\n }\n\n await beforeValidateTraverseFields({\n id: null,\n collection: null,\n context,\n data: node.fields,\n doc: node.fields,\n fields: sanitizedBlock.fields,\n global: null,\n operation:\n operation === 'create' || operation === 'update' ? operation : 'update',\n overrideAccess,\n req,\n siblingData: node.fields,\n siblingDoc: node.fields,\n })\n\n return node\n },\n ],\n },*/\n node: BlockNode,\n populationPromises: [blockPopulationPromiseHOC(props)],\n validations: [blockValidationHOC(props)],\n }),\n ],\n serverFeatureProps: props,\n }\n },\n key: 'blocks',\n serverFeatureProps: props,\n }\n}\n"],"names":["traverseFields","baseBlockFields","sanitizeFields","fieldsToJSONSchema","formatLabels","cloneDeep","createNode","BlocksFeatureClientComponent","BlockNode","blockPopulationPromiseHOC","blockValidationHOC","BlocksFeature","props","blocks","length","map","block","blockCopy","fields","concat","labels","slug","clientProps","reducedBlocks","push","fieldMap","imageAltText","imageURL","feature","ClientComponent","clientFeatureProps","generateSchemaMap","config","i18n","validRelationships","collections","c","schemaMap","Map","set","schemaPath","generatedTypes","modifyOutputSchema","collectionIDFieldTypes","currentSchema","field","interfaceNameDefinitions","sanitizedBlocks","requireFieldLevelRichTextEditor","blocksField","name","type","nodes","node","populationPromises","validations","serverFeatureProps","key"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAEA,SAASA,cAAc,QAAQ,6BAA4B;AAC3D,SAASC,eAAe,EAAEC,cAAc,QAAQ,iBAAgB;AAChE,SAIEC,kBAAkB,EAClBC,YAAY,QACP,oBAAmB;AAK1B,SAASC,SAAS,QAAQ,mCAAkC;AAC5D,SAASC,UAAU,QAAQ,sBAAqB;AAChD,SAASC,4BAA4B,QAAQ,sBAAqB;AAClE,SAASC,SAAS,QAAQ,wBAAuB;AACjD,SAASC,yBAAyB,QAAQ,yBAAwB;AAClE,SAASC,kBAAkB,QAAQ,gBAAe;AAUlD,OAAO,MAAMC,gBAGT,CAACC;IACH,gEAAgE;IAEhE,IAAIA,OAAOC,QAAQC,QAAQ;QACzBF,MAAMC,MAAM,GAAGD,MAAMC,MAAM,CAACE,GAAG,CAAC,CAACC;YAC/B,MAAMC,YAAYZ,UAAUW;YAE5B,OAAO;gBACL,GAAGC,SAAS;gBACZ,4EAA4E;gBAC5EC,QAAQD,UAAUC,MAAM,CAACC,MAAM,CAAClB;gBAChCmB,QAAQ,CAACH,UAAUG,MAAM,GAAGhB,aAAaa,UAAUI,IAAI,IAAIJ,UAAUG,MAAM;YAC7E;QACF;IACA,8EAA8E;IAC9E,mEAAmE;IACrE;IAEA,oBAAoB;IACpB,MAAME,cAAwC;QAC5CC,eAAe,EAAE;IACnB;IACA,KAAK,MAAMP,SAASJ,MAAMC,MAAM,CAAE;QAChCS,YAAYC,aAAa,CAACC,IAAI,CAAC;YAC7BH,MAAML,MAAMK,IAAI;YAChBI,UAAU,EAAE;YACZC,cAAcV,MAAMU,YAAY;YAChCC,UAAUX,MAAMW,QAAQ;YACxBP,QAAQJ,MAAMI,MAAM;QACtB;IACF;IAEA,OAAO;QACLQ,SAAS;YACP,OAAO;gBACLC,iBAAiBtB;gBACjBuB,oBAAoBR;gBACpBS,mBAAmB,CAAC,EAAEC,MAAM,EAAEC,IAAI,EAAErB,KAAK,EAAE;oBACzC,MAAMsB,qBAAqBF,OAAOG,WAAW,CAACpB,GAAG,CAAC,CAACqB,IAAMA,EAAEf,IAAI,KAAK,EAAE;oBAEtE;;;WAGC,GACD,MAAMgB,YAAY,IAAIC;oBAEtB,KAAK,MAAMtB,SAASJ,MAAMC,MAAM,CAAE;wBAChCwB,UAAUE,GAAG,CAACvB,MAAMK,IAAI,EAAEL,MAAME,MAAM,IAAI,EAAE;wBAE5ClB,eAAe;4BACbgC;4BACAd,QAAQF,MAAME,MAAM;4BACpBe;4BACAI;4BACAG,YAAYxB,MAAMK,IAAI;4BACtBa;wBACF;oBACF;oBAEA,OAAOG;gBACT;gBACAI,gBAAgB;oBACdC,oBAAoB,CAAC,EACnBC,sBAAsB,EACtBX,MAAM,EACNY,aAAa,EACbC,KAAK,EACLC,wBAAwB,EACzB;wBACC,IAAI,CAAClC,OAAOC,QAAQC,QAAQ;4BAC1B,OAAO8B;wBACT;wBAEA,kBAAkB;wBAClB,MAAMV,qBAAqBF,OAAOG,WAAW,CAACpB,GAAG,CAAC,CAACqB,IAAMA,EAAEf,IAAI,KAAK,EAAE;wBAEtE,MAAM0B,kBAAkBnC,MAAMC,MAAM,CAACE,GAAG,CAAC,CAACC;4BACxC,MAAMC,YAAYZ,UAAUW;4BAC5B,OAAO;gCACL,GAAGC,SAAS;gCACZC,QAAQhB,eAAe;oCACrB8B;oCACAd,QAAQD,UAAUC,MAAM;oCACxB8B,iCAAiC;oCACjCd;gCACF;4BACF;wBACF;wBAEA,MAAMe,cAA0B;4BAC9BC,MAAML,OAAOK,OAAO;4BACpBC,MAAM;4BACNtC,QAAQkC;wBACV;wBACA,wFAAwF;wBACxF,2EAA2E;wBAC3E5C,mBACEwC,wBACA;4BAACM;yBAAY,EACbH,0BACAd;wBAGF,OAAOY;oBACT;gBACF;gBACAQ,OAAO;oBACL9C,WAAW;wBACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAsFE,GACF+C,MAAM7C;wBACN8C,oBAAoB;4BAAC7C,0BAA0BG;yBAAO;wBACtD2C,aAAa;4BAAC7C,mBAAmBE;yBAAO;oBAC1C;iBACD;gBACD4C,oBAAoB5C;YACtB;QACF;QACA6C,KAAK;QACLD,oBAAoB5C;IACtB;AACF,EAAC"}
1
+ {"version":3,"sources":["../../../../src/field/features/blocks/feature.server.ts"],"sourcesContent":["import type { Config } from 'payload/config'\nimport type { Block, BlockField, Field, FieldWithRichTextRequiredEditor } from 'payload/types'\n\nimport { traverseFields } from '@payloadcms/next/utilities'\nimport { baseBlockFields, sanitizeFields } from 'payload/config'\nimport { fieldsToJSONSchema, formatLabels } from 'payload/utilities'\n\nimport type { FeatureProviderProviderServer } from '../types.js'\nimport type { BlocksFeatureClientProps } from './feature.client.js'\n\nimport { createNode } from '../typeUtilities.js'\nimport { BlocksFeatureClientComponent } from './feature.client.js'\nimport { BlockNode } from './nodes/BlocksNode.js'\nimport { blockPopulationPromiseHOC } from './populationPromise.js'\nimport { blockValidationHOC } from './validate.js'\n\nexport type LexicalBlock = Omit<Block, 'fields'> & {\n fields: FieldWithRichTextRequiredEditor[]\n}\n\nexport type BlocksFeatureProps = {\n blocks: LexicalBlock[]\n}\n\nexport const BlocksFeature: FeatureProviderProviderServer<\n BlocksFeatureProps,\n BlocksFeatureClientProps\n> = (props) => {\n return {\n feature: async ({ config: _config }) => {\n if (props?.blocks?.length) {\n const validRelationships = _config.collections.map((c) => c.slug) || []\n\n for (const block of props.blocks) {\n block.fields = block.fields.concat(baseBlockFields as FieldWithRichTextRequiredEditor[])\n block.labels = !block.labels ? formatLabels(block.slug) : block.labels\n\n block.fields = (await sanitizeFields({\n config: _config as unknown as Config,\n fields: block.fields,\n requireFieldLevelRichTextEditor: true,\n validRelationships,\n })) as FieldWithRichTextRequiredEditor[]\n }\n }\n\n // Build clientProps\n const clientProps: BlocksFeatureClientProps = {\n reducedBlocks: [],\n }\n for (const block of props.blocks) {\n clientProps.reducedBlocks.push({\n slug: block.slug,\n fieldMap: [],\n imageAltText: block.imageAltText,\n imageURL: block.imageURL,\n labels: block.labels,\n })\n }\n\n return {\n ClientComponent: BlocksFeatureClientComponent,\n clientFeatureProps: clientProps,\n generateSchemaMap: ({ config, i18n, props }) => {\n const validRelationships = config.collections.map((c) => c.slug) || []\n\n /**\n * Add sub-fields to the schemaMap. E.g. if you have an array field as part of the block, and it runs addRow, it will request these\n * sub-fields from the component map. Thus, we need to put them in the component map here.\n */\n const schemaMap = new Map<string, Field[]>()\n\n for (const block of props.blocks) {\n schemaMap.set(block.slug, block.fields || [])\n\n traverseFields({\n config,\n fields: block.fields,\n i18n,\n schemaMap,\n schemaPath: block.slug,\n validRelationships,\n })\n }\n\n return schemaMap\n },\n generatedTypes: {\n modifyOutputSchema: ({\n collectionIDFieldTypes,\n config,\n currentSchema,\n field,\n interfaceNameDefinitions,\n }) => {\n if (!props?.blocks?.length) {\n return currentSchema\n }\n\n const blocksField: BlockField = {\n name: field?.name + '_lexical_blocks',\n type: 'blocks',\n blocks: props.blocks,\n }\n // This is only done so that interfaceNameDefinitions sets those block's interfaceNames.\n // we don't actually use the JSON Schema itself in the generated types yet.\n fieldsToJSONSchema(\n collectionIDFieldTypes,\n [blocksField],\n interfaceNameDefinitions,\n config,\n )\n\n return currentSchema\n },\n },\n nodes: [\n createNode({\n /* // TODO: Implement these hooks once docWithLocales / originalSiblingDoc => node matching has been figured out\n hooks: {\n beforeChange: [\n async ({ context, findMany, node, operation, overrideAccess, req }) => {\n const blockType = node.fields.blockType\n\n const block = deepCopyObject(\n props.blocks.find((block) => block.slug === blockType),\n )\n\n\n await beforeChangeTraverseFields({\n id: null,\n collection: null,\n context,\n data: node.fields,\n doc: node.fields,\n fields: sanitizedBlock.fields,\n global: null,\n mergeLocaleActions: [],\n operation:\n operation === 'create' || operation === 'update' ? operation : 'update',\n overrideAccess,\n path: '',\n req,\n siblingData: node.fields,\n siblingDoc: node.fields,\n })\n\n\n return node\n },\n ],\n beforeValidate: [\n async ({ context, findMany, node, operation, overrideAccess, req }) => {\n const blockType = node.fields.blockType\n\n const block = deepCopyObject(\n props.blocks.find((block) => block.slug === blockType),\n )\n\n\n\n await beforeValidateTraverseFields({\n id: null,\n collection: null,\n context,\n data: node.fields,\n doc: node.fields,\n fields: sanitizedBlock.fields,\n global: null,\n operation:\n operation === 'create' || operation === 'update' ? operation : 'update',\n overrideAccess,\n req,\n siblingData: node.fields,\n siblingDoc: node.fields,\n })\n\n return node\n },\n ],\n },*/\n node: BlockNode,\n populationPromises: [blockPopulationPromiseHOC(props)],\n validations: [blockValidationHOC(props)],\n }),\n ],\n serverFeatureProps: props,\n }\n },\n key: 'blocks',\n serverFeatureProps: props,\n }\n}\n"],"names":["traverseFields","baseBlockFields","sanitizeFields","fieldsToJSONSchema","formatLabels","createNode","BlocksFeatureClientComponent","BlockNode","blockPopulationPromiseHOC","blockValidationHOC","BlocksFeature","props","feature","config","_config","blocks","length","validRelationships","collections","map","c","slug","block","fields","concat","labels","requireFieldLevelRichTextEditor","clientProps","reducedBlocks","push","fieldMap","imageAltText","imageURL","ClientComponent","clientFeatureProps","generateSchemaMap","i18n","schemaMap","Map","set","schemaPath","generatedTypes","modifyOutputSchema","collectionIDFieldTypes","currentSchema","field","interfaceNameDefinitions","blocksField","name","type","nodes","node","populationPromises","validations","serverFeatureProps","key"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"populationPromise.d.ts","sourceRoot":"","sources":["../../../../src/field/features/blocks/populationPromise.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAC7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAIhE,eAAO,MAAM,yBAAyB,UAC7B,kBAAkB,KACxB,kBAAkB,mBAAmB,CAyDvC,CAAA"}
1
+ {"version":3,"file":"populationPromise.d.ts","sourceRoot":"","sources":["../../../../src/field/features/blocks/populationPromise.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAC7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAIhE,eAAO,MAAM,yBAAyB,UAC7B,kBAAkB,KACxB,kBAAkB,mBAAmB,CA4CvC,CAAA"}
@@ -1,20 +1,7 @@
1
- import { sanitizeFields } from 'payload/config';
2
1
  import { recurseNestedFields } from '../../../populate/recurseNestedFields.js';
3
2
  export const blockPopulationPromiseHOC = (props)=>{
4
3
  const blockPopulationPromise = ({ context, currentDepth, depth, editorPopulationPromises, fieldPromises, findMany, flattenLocales, node, overrideAccess, populationPromises, req, showHiddenFields, siblingDoc })=>{
5
- const blocks = props.blocks;
6
4
  const blockFieldData = node.fields;
7
- // Sanitize block's fields here. This is done here and not in the feature, because the payload config is available here
8
- const payloadConfig = req.payload.config;
9
- const validRelationships = payloadConfig.collections.map((c)=>c.slug) || [];
10
- blocks.forEach((block)=>{
11
- block.fields = sanitizeFields({
12
- config: payloadConfig,
13
- fields: block.fields,
14
- requireFieldLevelRichTextEditor: true,
15
- validRelationships
16
- });
17
- });
18
5
  // find block used in this node
19
6
  const block = props.blocks.find((block)=>block.slug === blockFieldData.blockType);
20
7
  if (!block || !block?.fields?.length || !blockFieldData) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/field/features/blocks/populationPromise.ts"],"sourcesContent":["import type { Block } from 'payload/types'\n\nimport { sanitizeFields } from 'payload/config'\n\nimport type { PopulationPromise } from '../types.js'\nimport type { BlocksFeatureProps } from './feature.server.js'\nimport type { SerializedBlockNode } from './nodes/BlocksNode.js'\n\nimport { recurseNestedFields } from '../../../populate/recurseNestedFields.js'\n\nexport const blockPopulationPromiseHOC = (\n props: BlocksFeatureProps,\n): PopulationPromise<SerializedBlockNode> => {\n const blockPopulationPromise: PopulationPromise<SerializedBlockNode> = ({\n context,\n currentDepth,\n depth,\n editorPopulationPromises,\n fieldPromises,\n findMany,\n flattenLocales,\n node,\n overrideAccess,\n populationPromises,\n req,\n showHiddenFields,\n siblingDoc,\n }) => {\n const blocks: Block[] = props.blocks\n const blockFieldData = node.fields\n\n // Sanitize block's fields here. This is done here and not in the feature, because the payload config is available here\n const payloadConfig = req.payload.config\n const validRelationships = payloadConfig.collections.map((c) => c.slug) || []\n blocks.forEach((block) => {\n block.fields = sanitizeFields({\n config: payloadConfig,\n fields: block.fields,\n requireFieldLevelRichTextEditor: true,\n validRelationships,\n })\n })\n\n // find block used in this node\n const block = props.blocks.find((block) => block.slug === blockFieldData.blockType)\n if (!block || !block?.fields?.length || !blockFieldData) {\n return\n }\n\n recurseNestedFields({\n context,\n currentDepth,\n data: blockFieldData,\n depth,\n editorPopulationPromises,\n fieldPromises,\n fields: block.fields,\n findMany,\n flattenLocales,\n overrideAccess,\n populationPromises,\n req,\n showHiddenFields,\n // The afterReadPromise gets its data from looking for field.name inside the siblingDoc. Thus, here we cannot pass the whole document's siblingDoc, but only the siblingDoc (sibling fields) of the current field.\n siblingDoc: blockFieldData,\n })\n }\n\n return blockPopulationPromise\n}\n"],"names":["sanitizeFields","recurseNestedFields","blockPopulationPromiseHOC","props","blockPopulationPromise","context","currentDepth","depth","editorPopulationPromises","fieldPromises","findMany","flattenLocales","node","overrideAccess","populationPromises","req","showHiddenFields","siblingDoc","blocks","blockFieldData","fields","payloadConfig","payload","config","validRelationships","collections","map","c","slug","forEach","block","requireFieldLevelRichTextEditor","find","blockType","length","data"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAEA,SAASA,cAAc,QAAQ,iBAAgB;AAM/C,SAASC,mBAAmB,QAAQ,2CAA0C;AAE9E,OAAO,MAAMC,4BAA4B,CACvCC;IAEA,MAAMC,yBAAiE,CAAC,EACtEC,OAAO,EACPC,YAAY,EACZC,KAAK,EACLC,wBAAwB,EACxBC,aAAa,EACbC,QAAQ,EACRC,cAAc,EACdC,IAAI,EACJC,cAAc,EACdC,kBAAkB,EAClBC,GAAG,EACHC,gBAAgB,EAChBC,UAAU,EACX;QACC,MAAMC,SAAkBf,MAAMe,MAAM;QACpC,MAAMC,iBAAiBP,KAAKQ,MAAM;QAElC,uHAAuH;QACvH,MAAMC,gBAAgBN,IAAIO,OAAO,CAACC,MAAM;QACxC,MAAMC,qBAAqBH,cAAcI,WAAW,CAACC,GAAG,CAAC,CAACC,IAAMA,EAAEC,IAAI,KAAK,EAAE;QAC7EV,OAAOW,OAAO,CAAC,CAACC;YACdA,MAAMV,MAAM,GAAGpB,eAAe;gBAC5BuB,QAAQF;gBACRD,QAAQU,MAAMV,MAAM;gBACpBW,iCAAiC;gBACjCP;YACF;QACF;QAEA,+BAA+B;QAC/B,MAAMM,QAAQ3B,MAAMe,MAAM,CAACc,IAAI,CAAC,CAACF,QAAUA,MAAMF,IAAI,KAAKT,eAAec,SAAS;QAClF,IAAI,CAACH,SAAS,CAACA,OAAOV,QAAQc,UAAU,CAACf,gBAAgB;YACvD;QACF;QAEAlB,oBAAoB;YAClBI;YACAC;YACA6B,MAAMhB;YACNZ;YACAC;YACAC;YACAW,QAAQU,MAAMV,MAAM;YACpBV;YACAC;YACAE;YACAC;YACAC;YACAC;YACA,kNAAkN;YAClNC,YAAYE;QACd;IACF;IAEA,OAAOf;AACT,EAAC"}
1
+ {"version":3,"sources":["../../../../src/field/features/blocks/populationPromise.ts"],"sourcesContent":["import type { PopulationPromise } from '../types.js'\nimport type { BlocksFeatureProps } from './feature.server.js'\nimport type { SerializedBlockNode } from './nodes/BlocksNode.js'\n\nimport { recurseNestedFields } from '../../../populate/recurseNestedFields.js'\n\nexport const blockPopulationPromiseHOC = (\n props: BlocksFeatureProps,\n): PopulationPromise<SerializedBlockNode> => {\n const blockPopulationPromise: PopulationPromise<SerializedBlockNode> = ({\n context,\n currentDepth,\n depth,\n editorPopulationPromises,\n fieldPromises,\n findMany,\n flattenLocales,\n node,\n overrideAccess,\n populationPromises,\n req,\n showHiddenFields,\n siblingDoc,\n }) => {\n const blockFieldData = node.fields\n\n // find block used in this node\n const block = props.blocks.find((block) => block.slug === blockFieldData.blockType)\n if (!block || !block?.fields?.length || !blockFieldData) {\n return\n }\n\n recurseNestedFields({\n context,\n currentDepth,\n data: blockFieldData,\n depth,\n editorPopulationPromises,\n fieldPromises,\n fields: block.fields,\n findMany,\n flattenLocales,\n overrideAccess,\n populationPromises,\n req,\n showHiddenFields,\n // The afterReadPromise gets its data from looking for field.name inside the siblingDoc. Thus, here we cannot pass the whole document's siblingDoc, but only the siblingDoc (sibling fields) of the current field.\n siblingDoc: blockFieldData,\n })\n }\n\n return blockPopulationPromise\n}\n"],"names":["recurseNestedFields","blockPopulationPromiseHOC","props","blockPopulationPromise","context","currentDepth","depth","editorPopulationPromises","fieldPromises","findMany","flattenLocales","node","overrideAccess","populationPromises","req","showHiddenFields","siblingDoc","blockFieldData","fields","block","blocks","find","slug","blockType","length","data"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAIA,SAASA,mBAAmB,QAAQ,2CAA0C;AAE9E,OAAO,MAAMC,4BAA4B,CACvCC;IAEA,MAAMC,yBAAiE,CAAC,EACtEC,OAAO,EACPC,YAAY,EACZC,KAAK,EACLC,wBAAwB,EACxBC,aAAa,EACbC,QAAQ,EACRC,cAAc,EACdC,IAAI,EACJC,cAAc,EACdC,kBAAkB,EAClBC,GAAG,EACHC,gBAAgB,EAChBC,UAAU,EACX;QACC,MAAMC,iBAAiBN,KAAKO,MAAM;QAElC,+BAA+B;QAC/B,MAAMC,QAAQjB,MAAMkB,MAAM,CAACC,IAAI,CAAC,CAACF,QAAUA,MAAMG,IAAI,KAAKL,eAAeM,SAAS;QAClF,IAAI,CAACJ,SAAS,CAACA,OAAOD,QAAQM,UAAU,CAACP,gBAAgB;YACvD;QACF;QAEAjB,oBAAoB;YAClBI;YACAC;YACAoB,MAAMR;YACNX;YACAC;YACAC;YACAU,QAAQC,MAAMD,MAAM;YACpBT;YACAC;YACAE;YACAC;YACAC;YACAC;YACA,kNAAkN;YAClNC,YAAYC;QACd;IACF;IAEA,OAAOd;AACT,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../../src/field/features/blocks/validate.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAC7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAEhE,eAAO,MAAM,kBAAkB,UACtB,kBAAkB,KACxB,eAAe,mBAAmB,CA+DpC,CAAA"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../../src/field/features/blocks/validate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAC7D,OAAO,KAAK,EAAe,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAE7E,eAAO,MAAM,kBAAkB,UACtB,kBAAkB,KACxB,eAAe,mBAAmB,CA2CpC,CAAA"}
@@ -1,20 +1,8 @@
1
1
  import { buildStateFromSchema } from '@payloadcms/ui/forms/buildStateFromSchema';
2
- import { sanitizeFields } from 'payload/config';
3
2
  export const blockValidationHOC = (props)=>{
4
3
  return async ({ node, validation })=>{
5
- const blockFieldData = node.fields;
6
- const blocks = props.blocks;
7
- const { options: { id, operation, preferences, req, req: { payload: { config } } } } = validation;
8
- // Sanitize block's fields here. This is done here and not in the feature, because the payload config is available here
9
- const validRelationships = config.collections.map((c)=>c.slug) || [];
10
- blocks.forEach((block)=>{
11
- block.fields = sanitizeFields({
12
- config,
13
- fields: block.fields,
14
- requireFieldLevelRichTextEditor: true,
15
- validRelationships
16
- });
17
- });
4
+ const blockFieldData = node.fields ?? {};
5
+ const { options: { id, operation, preferences, req } } = validation;
18
6
  // find block
19
7
  const block = props.blocks.find((block)=>block.slug === blockFieldData.blockType);
20
8
  // validate block
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/field/features/blocks/validate.ts"],"sourcesContent":["import type { Block } from 'payload/types'\n\nimport { buildStateFromSchema } from '@payloadcms/ui/forms/buildStateFromSchema'\nimport { sanitizeFields } from 'payload/config'\n\nimport type { NodeValidation } from '../types.js'\nimport type { BlocksFeatureProps } from './feature.server.js'\nimport type { SerializedBlockNode } from './nodes/BlocksNode.js'\n\nexport const blockValidationHOC = (\n props: BlocksFeatureProps,\n): NodeValidation<SerializedBlockNode> => {\n return async ({ node, validation }) => {\n const blockFieldData = node.fields\n const blocks: Block[] = props.blocks\n\n const {\n options: {\n id,\n operation,\n preferences,\n req,\n req: {\n payload: { config },\n },\n },\n } = validation\n\n // Sanitize block's fields here. This is done here and not in the feature, because the payload config is available here\n const validRelationships = config.collections.map((c) => c.slug) || []\n blocks.forEach((block) => {\n block.fields = sanitizeFields({\n config,\n fields: block.fields,\n requireFieldLevelRichTextEditor: true,\n validRelationships,\n })\n })\n\n // find block\n const block = props.blocks.find((block) => block.slug === blockFieldData.blockType)\n\n // validate block\n if (!block) {\n return 'Block not found'\n }\n\n /**\n * Run buildStateFromSchema as that properly validates block and block sub-fields\n */\n\n const result = await buildStateFromSchema({\n id,\n data: blockFieldData,\n fieldSchema: block.fields,\n operation: operation === 'create' || operation === 'update' ? operation : 'update',\n preferences,\n req,\n siblingData: blockFieldData,\n })\n\n let errorPaths = []\n for (const fieldKey in result) {\n if (result[fieldKey].errorPaths) {\n errorPaths = errorPaths.concat(result[fieldKey].errorPaths)\n }\n }\n\n if (errorPaths.length) {\n return 'Block validation failed: ' + errorPaths.join(', ')\n }\n\n return true\n }\n}\n"],"names":["buildStateFromSchema","sanitizeFields","blockValidationHOC","props","node","validation","blockFieldData","fields","blocks","options","id","operation","preferences","req","payload","config","validRelationships","collections","map","c","slug","forEach","block","requireFieldLevelRichTextEditor","find","blockType","result","data","fieldSchema","siblingData","errorPaths","fieldKey","concat","length","join"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAEA,SAASA,oBAAoB,QAAQ,4CAA2C;AAChF,SAASC,cAAc,QAAQ,iBAAgB;AAM/C,OAAO,MAAMC,qBAAqB,CAChCC;IAEA,OAAO,OAAO,EAAEC,IAAI,EAAEC,UAAU,EAAE;QAChC,MAAMC,iBAAiBF,KAAKG,MAAM;QAClC,MAAMC,SAAkBL,MAAMK,MAAM;QAEpC,MAAM,EACJC,SAAS,EACPC,EAAE,EACFC,SAAS,EACTC,WAAW,EACXC,GAAG,EACHA,KAAK,EACHC,SAAS,EAAEC,MAAM,EAAE,EACpB,EACF,EACF,GAAGV;QAEJ,uHAAuH;QACvH,MAAMW,qBAAqBD,OAAOE,WAAW,CAACC,GAAG,CAAC,CAACC,IAAMA,EAAEC,IAAI,KAAK,EAAE;QACtEZ,OAAOa,OAAO,CAAC,CAACC;YACdA,MAAMf,MAAM,GAAGN,eAAe;gBAC5Bc;gBACAR,QAAQe,MAAMf,MAAM;gBACpBgB,iCAAiC;gBACjCP;YACF;QACF;QAEA,aAAa;QACb,MAAMM,QAAQnB,MAAMK,MAAM,CAACgB,IAAI,CAAC,CAACF,QAAUA,MAAMF,IAAI,KAAKd,eAAemB,SAAS;QAElF,iBAAiB;QACjB,IAAI,CAACH,OAAO;YACV,OAAO;QACT;QAEA;;KAEC,GAED,MAAMI,SAAS,MAAM1B,qBAAqB;YACxCU;YACAiB,MAAMrB;YACNsB,aAAaN,MAAMf,MAAM;YACzBI,WAAWA,cAAc,YAAYA,cAAc,WAAWA,YAAY;YAC1EC;YACAC;YACAgB,aAAavB;QACf;QAEA,IAAIwB,aAAa,EAAE;QACnB,IAAK,MAAMC,YAAYL,OAAQ;YAC7B,IAAIA,MAAM,CAACK,SAAS,CAACD,UAAU,EAAE;gBAC/BA,aAAaA,WAAWE,MAAM,CAACN,MAAM,CAACK,SAAS,CAACD,UAAU;YAC5D;QACF;QAEA,IAAIA,WAAWG,MAAM,EAAE;YACrB,OAAO,8BAA8BH,WAAWI,IAAI,CAAC;QACvD;QAEA,OAAO;IACT;AACF,EAAC"}
1
+ {"version":3,"sources":["../../../../src/field/features/blocks/validate.ts"],"sourcesContent":["import { buildStateFromSchema } from '@payloadcms/ui/forms/buildStateFromSchema'\n\nimport type { NodeValidation } from '../types.js'\nimport type { BlocksFeatureProps } from './feature.server.js'\nimport type { BlockFields, SerializedBlockNode } from './nodes/BlocksNode.js'\n\nexport const blockValidationHOC = (\n props: BlocksFeatureProps,\n): NodeValidation<SerializedBlockNode> => {\n return async ({ node, validation }) => {\n const blockFieldData = node.fields ?? ({} as BlockFields)\n\n const {\n options: { id, operation, preferences, req },\n } = validation\n\n // find block\n const block = props.blocks.find((block) => block.slug === blockFieldData.blockType)\n\n // validate block\n if (!block) {\n return 'Block not found'\n }\n\n /**\n * Run buildStateFromSchema as that properly validates block and block sub-fields\n */\n\n const result = await buildStateFromSchema({\n id,\n data: blockFieldData,\n fieldSchema: block.fields,\n operation: operation === 'create' || operation === 'update' ? operation : 'update',\n preferences,\n req,\n siblingData: blockFieldData,\n })\n\n let errorPaths = []\n for (const fieldKey in result) {\n if (result[fieldKey].errorPaths) {\n errorPaths = errorPaths.concat(result[fieldKey].errorPaths)\n }\n }\n\n if (errorPaths.length) {\n return 'Block validation failed: ' + errorPaths.join(', ')\n }\n\n return true\n }\n}\n"],"names":["buildStateFromSchema","blockValidationHOC","props","node","validation","blockFieldData","fields","options","id","operation","preferences","req","block","blocks","find","slug","blockType","result","data","fieldSchema","siblingData","errorPaths","fieldKey","concat","length","join"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,oBAAoB,QAAQ,4CAA2C;AAMhF,OAAO,MAAMC,qBAAqB,CAChCC;IAEA,OAAO,OAAO,EAAEC,IAAI,EAAEC,UAAU,EAAE;QAChC,MAAMC,iBAAiBF,KAAKG,MAAM,IAAK,CAAC;QAExC,MAAM,EACJC,SAAS,EAAEC,EAAE,EAAEC,SAAS,EAAEC,WAAW,EAAEC,GAAG,EAAE,EAC7C,GAAGP;QAEJ,aAAa;QACb,MAAMQ,QAAQV,MAAMW,MAAM,CAACC,IAAI,CAAC,CAACF,QAAUA,MAAMG,IAAI,KAAKV,eAAeW,SAAS;QAElF,iBAAiB;QACjB,IAAI,CAACJ,OAAO;YACV,OAAO;QACT;QAEA;;KAEC,GAED,MAAMK,SAAS,MAAMjB,qBAAqB;YACxCQ;YACAU,MAAMb;YACNc,aAAaP,MAAMN,MAAM;YACzBG,WAAWA,cAAc,YAAYA,cAAc,WAAWA,YAAY;YAC1EC;YACAC;YACAS,aAAaf;QACf;QAEA,IAAIgB,aAAa,EAAE;QACnB,IAAK,MAAMC,YAAYL,OAAQ;YAC7B,IAAIA,MAAM,CAACK,SAAS,CAACD,UAAU,EAAE;gBAC/BA,aAAaA,WAAWE,MAAM,CAACN,MAAM,CAACK,SAAS,CAACD,UAAU;YAC5D;QACF;QAEA,IAAIA,WAAWG,MAAM,EAAE;YACrB,OAAO,8BAA8BH,WAAWI,IAAI,CAAC;QACvD;QAEA,OAAO;IACT;AACF,EAAC"}
@@ -1,4 +1,4 @@
1
- import type { Config } from 'payload/config';
2
- import type { Field } from 'payload/types';
3
- export declare const getBaseFields: (config: Config, enabledCollections: false | string[], disabledCollections: false | string[]) => Field[];
1
+ import type { SanitizedConfig } from 'payload/config';
2
+ import type { FieldWithRichTextRequiredEditor } from 'payload/types';
3
+ export declare const getBaseFields: (config: SanitizedConfig, enabledCollections: false | string[], disabledCollections: false | string[]) => FieldWithRichTextRequiredEditor[];
4
4
  //# sourceMappingURL=baseFields.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"baseFields.d.ts","sourceRoot":"","sources":["../../../../../src/field/features/link/drawer/baseFields.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,KAAK,EAAE,KAAK,EAAyB,MAAM,eAAe,CAAA;AAIjE,eAAO,MAAM,aAAa,WAChB,MAAM,sBACM,KAAK,GAAG,MAAM,EAAE,uBACf,KAAK,GAAG,MAAM,EAAE,KACpC,KAAK,EAmHP,CAAA"}
1
+ {"version":3,"file":"baseFields.d.ts","sourceRoot":"","sources":["../../../../../src/field/features/link/drawer/baseFields.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AACrD,OAAO,KAAK,EAAS,+BAA+B,EAAyB,MAAM,eAAe,CAAA;AAIlG,eAAO,MAAM,aAAa,WAChB,eAAe,sBACH,KAAK,GAAG,MAAM,EAAE,uBACf,KAAK,GAAG,MAAM,EAAE,KACpC,+BAA+B,EAqGjC,CAAA"}
@@ -24,61 +24,47 @@ export const getBaseFields = (config, enabledCollections, disabledCollections)=>
24
24
  required: true
25
25
  },
26
26
  {
27
- name: 'fields',
28
- type: 'group',
27
+ name: 'linkType',
28
+ type: 'radio',
29
29
  admin: {
30
- style: {
31
- borderBottom: 0,
32
- borderTop: 0,
33
- margin: 0,
34
- padding: 0
35
- }
30
+ description: ({ t })=>t('fields:chooseBetweenCustomTextOrDocument')
36
31
  },
37
- fields: [
38
- {
39
- name: 'linkType',
40
- type: 'radio',
41
- admin: {
42
- description: ({ t })=>t('fields:chooseBetweenCustomTextOrDocument')
43
- },
44
- defaultValue: 'custom',
45
- label: ({ t })=>t('fields:linkType'),
46
- options: [
47
- {
48
- label: ({ t })=>t('fields:customURL'),
49
- value: 'custom'
50
- }
51
- ],
52
- required: true
53
- },
32
+ defaultValue: 'custom',
33
+ label: ({ t })=>t('fields:linkType'),
34
+ options: [
54
35
  {
55
- name: 'url',
56
- type: 'text',
57
- label: ({ t })=>t('fields:enterURL'),
58
- required: true,
59
- validate: (value)=>{
60
- if (!validateUrl(value)) {
61
- return 'Invalid URL';
62
- }
63
- }
36
+ label: ({ t })=>t('fields:customURL'),
37
+ value: 'custom'
38
+ }
39
+ ],
40
+ required: true
41
+ },
42
+ {
43
+ name: 'url',
44
+ type: 'text',
45
+ label: ({ t })=>t('fields:enterURL'),
46
+ required: true,
47
+ validate: (value)=>{
48
+ if (!validateUrl(value)) {
49
+ return 'Invalid URL';
64
50
  }
65
- ]
51
+ }
66
52
  }
67
53
  ];
68
54
  // Only display internal link-specific fields / options / conditions if there are enabled relations
69
55
  if (enabledRelations?.length) {
70
- baseFields[1].fields[0].options.push({
56
+ baseFields[1].options.push({
71
57
  label: ({ t })=>t('fields:internalLink'),
72
58
  value: 'internal'
73
59
  });
74
- baseFields[1].fields[1].admin = {
75
- condition: ({ fields })=>fields?.linkType !== 'internal'
60
+ baseFields[2].admin = {
61
+ condition: ({ linkType })=>linkType !== 'internal'
76
62
  };
77
- baseFields[1].fields.push({
63
+ baseFields.push({
78
64
  name: 'doc',
79
65
  admin: {
80
- condition: ({ fields })=>{
81
- return fields?.linkType === 'internal';
66
+ condition: ({ linkType })=>{
67
+ return linkType === 'internal';
82
68
  }
83
69
  },
84
70
  // when admin.hidden is a function we need to dynamically call hidden with the user to know if the collection should be shown
@@ -96,7 +82,7 @@ export const getBaseFields = (config, enabledCollections, disabledCollections)=>
96
82
  required: true
97
83
  });
98
84
  }
99
- baseFields[1].fields.push({
85
+ baseFields.push({
100
86
  name: 'newTab',
101
87
  type: 'checkbox',
102
88
  label: ({ t })=>t('fields:openInNewTab')
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/field/features/link/drawer/baseFields.ts"],"sourcesContent":["import type { User } from 'payload/auth'\nimport type { Config } from 'payload/config'\nimport type { Field, RadioField, TextField } from 'payload/types'\n\nimport { validateUrl } from '../../../lexical/utils/url.js'\n\nexport const getBaseFields = (\n config: Config,\n enabledCollections: false | string[],\n disabledCollections: false | string[],\n): Field[] => {\n let enabledRelations: string[]\n\n /**\n * Figure out which relations should be enabled (enabledRelations) based on a collection's admin.enableRichTextLink property,\n * or the Link Feature's enabledCollections and disabledCollections properties which override it.\n */\n if (enabledCollections) {\n enabledRelations = enabledCollections\n } else if (disabledCollections) {\n enabledRelations = config.collections\n .filter(({ slug }) => !disabledCollections.includes(slug))\n .map(({ slug }) => slug)\n } else {\n enabledRelations = config.collections\n .filter(({ admin: { enableRichTextLink, hidden } }) => {\n if (typeof hidden !== 'function' && hidden) {\n return false\n }\n return enableRichTextLink\n })\n .map(({ slug }) => slug)\n }\n\n const baseFields = [\n {\n name: 'text',\n type: 'text',\n label: ({ t }) => t('fields:textToDisplay'),\n required: true,\n },\n {\n name: 'fields',\n type: 'group',\n admin: {\n style: {\n borderBottom: 0,\n borderTop: 0,\n margin: 0,\n padding: 0,\n },\n },\n fields: [\n {\n name: 'linkType',\n type: 'radio',\n admin: {\n description: ({ t }) => t('fields:chooseBetweenCustomTextOrDocument'),\n },\n defaultValue: 'custom',\n label: ({ t }) => t('fields:linkType'),\n options: [\n {\n label: ({ t }) => t('fields:customURL'),\n value: 'custom',\n },\n ],\n required: true,\n },\n {\n name: 'url',\n type: 'text',\n label: ({ t }) => t('fields:enterURL'),\n required: true,\n validate: (value: string) => {\n if (!validateUrl(value)) {\n return 'Invalid URL'\n }\n },\n },\n ] as Field[],\n },\n ]\n\n // Only display internal link-specific fields / options / conditions if there are enabled relations\n if (enabledRelations?.length) {\n ;(baseFields[1].fields[0] as RadioField).options.push({\n label: ({ t }) => t('fields:internalLink'),\n value: 'internal',\n })\n ;(baseFields[1].fields[1] as TextField).admin = {\n condition: ({ fields }) => fields?.linkType !== 'internal',\n }\n\n baseFields[1].fields.push({\n name: 'doc',\n admin: {\n condition: ({ fields }) => {\n return fields?.linkType === 'internal'\n },\n },\n // when admin.hidden is a function we need to dynamically call hidden with the user to know if the collection should be shown\n type: 'relationship',\n filterOptions:\n !enabledCollections && !disabledCollections\n ? ({ relationTo, user }) => {\n const hidden = config.collections.find(({ slug }) => slug === relationTo).admin.hidden\n if (typeof hidden === 'function' && hidden({ user } as { user: User })) {\n return false\n }\n }\n : null,\n label: ({ t }) => t('fields:chooseDocumentToLink'),\n relationTo: enabledRelations,\n required: true,\n })\n }\n\n baseFields[1].fields.push({\n name: 'newTab',\n type: 'checkbox',\n label: ({ t }) => t('fields:openInNewTab'),\n })\n\n return baseFields as Field[]\n}\n"],"names":["validateUrl","getBaseFields","config","enabledCollections","disabledCollections","enabledRelations","collections","filter","slug","includes","map","admin","enableRichTextLink","hidden","baseFields","name","type","label","t","required","style","borderBottom","borderTop","margin","padding","fields","description","defaultValue","options","value","validate","length","push","condition","linkType","filterOptions","relationTo","user","find"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/field/features/link/drawer/baseFields.ts"],"sourcesContent":["import type { User } from 'payload/auth'\nimport type { SanitizedConfig } from 'payload/config'\nimport type { Field, FieldWithRichTextRequiredEditor, RadioField, TextField } from 'payload/types'\n\nimport { validateUrl } from '../../../lexical/utils/url.js'\n\nexport const getBaseFields = (\n config: SanitizedConfig,\n enabledCollections: false | string[],\n disabledCollections: false | string[],\n): FieldWithRichTextRequiredEditor[] => {\n let enabledRelations: string[]\n\n /**\n * Figure out which relations should be enabled (enabledRelations) based on a collection's admin.enableRichTextLink property,\n * or the Link Feature's enabledCollections and disabledCollections properties which override it.\n */\n if (enabledCollections) {\n enabledRelations = enabledCollections\n } else if (disabledCollections) {\n enabledRelations = config.collections\n .filter(({ slug }) => !disabledCollections.includes(slug))\n .map(({ slug }) => slug)\n } else {\n enabledRelations = config.collections\n .filter(({ admin: { enableRichTextLink, hidden } }) => {\n if (typeof hidden !== 'function' && hidden) {\n return false\n }\n return enableRichTextLink\n })\n .map(({ slug }) => slug)\n }\n\n const baseFields: Field[] = [\n {\n name: 'text',\n type: 'text',\n label: ({ t }) => t('fields:textToDisplay'),\n required: true,\n },\n {\n name: 'linkType',\n type: 'radio',\n admin: {\n description: ({ t }) => t('fields:chooseBetweenCustomTextOrDocument'),\n },\n defaultValue: 'custom',\n label: ({ t }) => t('fields:linkType'),\n options: [\n {\n label: ({ t }) => t('fields:customURL'),\n value: 'custom',\n },\n ],\n required: true,\n } as RadioField,\n {\n name: 'url',\n type: 'text',\n label: ({ t }) => t('fields:enterURL'),\n required: true,\n validate: (value: string) => {\n if (!validateUrl(value)) {\n return 'Invalid URL'\n }\n },\n },\n ]\n\n // Only display internal link-specific fields / options / conditions if there are enabled relations\n if (enabledRelations?.length) {\n ;(baseFields[1] as RadioField).options.push({\n label: ({ t }) => t('fields:internalLink'),\n value: 'internal',\n })\n ;(baseFields[2] as TextField).admin = {\n condition: ({ linkType }) => linkType !== 'internal',\n }\n\n baseFields.push({\n name: 'doc',\n admin: {\n condition: ({ linkType }) => {\n return linkType === 'internal'\n },\n },\n // when admin.hidden is a function we need to dynamically call hidden with the user to know if the collection should be shown\n type: 'relationship',\n filterOptions:\n !enabledCollections && !disabledCollections\n ? ({ relationTo, user }) => {\n const hidden = config.collections.find(({ slug }) => slug === relationTo).admin.hidden\n if (typeof hidden === 'function' && hidden({ user } as { user: User })) {\n return false\n }\n }\n : null,\n label: ({ t }) => t('fields:chooseDocumentToLink'),\n relationTo: enabledRelations,\n required: true,\n })\n }\n\n baseFields.push({\n name: 'newTab',\n type: 'checkbox',\n label: ({ t }) => t('fields:openInNewTab'),\n })\n\n return baseFields as FieldWithRichTextRequiredEditor[]\n}\n"],"names":["validateUrl","getBaseFields","config","enabledCollections","disabledCollections","enabledRelations","collections","filter","slug","includes","map","admin","enableRichTextLink","hidden","baseFields","name","type","label","t","required","description","defaultValue","options","value","validate","length","push","condition","linkType","filterOptions","relationTo","user","find"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAIA,SAASA,WAAW,QAAQ,gCAA+B;AAE3D,OAAO,MAAMC,gBAAgB,CAC3BC,QACAC,oBACAC;IAEA,IAAIC;IAEJ;;;GAGC,GACD,IAAIF,oBAAoB;QACtBE,mBAAmBF;IACrB,OAAO,IAAIC,qBAAqB;QAC9BC,mBAAmBH,OAAOI,WAAW,CAClCC,MAAM,CAAC,CAAC,EAAEC,IAAI,EAAE,GAAK,CAACJ,oBAAoBK,QAAQ,CAACD,OACnDE,GAAG,CAAC,CAAC,EAAEF,IAAI,EAAE,GAAKA;IACvB,OAAO;QACLH,mBAAmBH,OAAOI,WAAW,CAClCC,MAAM,CAAC,CAAC,EAAEI,OAAO,EAAEC,kBAAkB,EAAEC,MAAM,EAAE,EAAE;YAChD,IAAI,OAAOA,WAAW,cAAcA,QAAQ;gBAC1C,OAAO;YACT;YACA,OAAOD;QACT,GACCF,GAAG,CAAC,CAAC,EAAEF,IAAI,EAAE,GAAKA;IACvB;IAEA,MAAMM,aAAsB;QAC1B;YACEC,MAAM;YACNC,MAAM;YACNC,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE;YACpBC,UAAU;QACZ;QACA;YACEJ,MAAM;YACNC,MAAM;YACNL,OAAO;gBACLS,aAAa,CAAC,EAAEF,CAAC,EAAE,GAAKA,EAAE;YAC5B;YACAG,cAAc;YACdJ,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE;YACpBI,SAAS;gBACP;oBACEL,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE;oBACpBK,OAAO;gBACT;aACD;YACDJ,UAAU;QACZ;QACA;YACEJ,MAAM;YACNC,MAAM;YACNC,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE;YACpBC,UAAU;YACVK,UAAU,CAACD;gBACT,IAAI,CAACvB,YAAYuB,QAAQ;oBACvB,OAAO;gBACT;YACF;QACF;KACD;IAED,mGAAmG;IACnG,IAAIlB,kBAAkBoB,QAAQ;QAC1BX,UAAU,CAAC,EAAE,CAAgBQ,OAAO,CAACI,IAAI,CAAC;YAC1CT,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE;YACpBK,OAAO;QACT;QACET,UAAU,CAAC,EAAE,CAAeH,KAAK,GAAG;YACpCgB,WAAW,CAAC,EAAEC,QAAQ,EAAE,GAAKA,aAAa;QAC5C;QAEAd,WAAWY,IAAI,CAAC;YACdX,MAAM;YACNJ,OAAO;gBACLgB,WAAW,CAAC,EAAEC,QAAQ,EAAE;oBACtB,OAAOA,aAAa;gBACtB;YACF;YACA,6HAA6H;YAC7HZ,MAAM;YACNa,eACE,CAAC1B,sBAAsB,CAACC,sBACpB,CAAC,EAAE0B,UAAU,EAAEC,IAAI,EAAE;gBACnB,MAAMlB,SAASX,OAAOI,WAAW,CAAC0B,IAAI,CAAC,CAAC,EAAExB,IAAI,EAAE,GAAKA,SAASsB,YAAYnB,KAAK,CAACE,MAAM;gBACtF,IAAI,OAAOA,WAAW,cAAcA,OAAO;oBAAEkB;gBAAK,IAAsB;oBACtE,OAAO;gBACT;YACF,IACA;YACNd,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE;YACpBY,YAAYzB;YACZc,UAAU;QACZ;IACF;IAEAL,WAAWY,IAAI,CAAC;QACdX,MAAM;QACNC,MAAM;QACNC,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE;IACtB;IAEA,OAAOJ;AACT,EAAC"}
@@ -1,8 +1,10 @@
1
1
  import type { FormState } from 'payload/types';
2
- import type { LinkPayload } from '../plugins/floatingLinkEditor/types.js';
2
+ import type { LinkFields } from '../nodes/types.js';
3
3
  export interface Props {
4
4
  drawerSlug: string;
5
5
  handleModalSubmit: (fields: FormState, data: Record<string, unknown>) => void;
6
- stateData?: LinkPayload;
6
+ stateData?: LinkFields & {
7
+ text: string;
8
+ };
7
9
  }
8
10
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/field/features/link/drawer/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAE9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAA;AAEzE,MAAM,WAAW,KAAK;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,iBAAiB,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAA;IAC7E,SAAS,CAAC,EAAE,WAAW,CAAA;CACxB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/field/features/link/drawer/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAE9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAEnD,MAAM,WAAW,KAAK;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,iBAAiB,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAA;IAC7E,SAAS,CAAC,EAAE,UAAU,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAC1C"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/field/features/link/drawer/types.ts"],"sourcesContent":["import type { FormState } from 'payload/types'\n\nimport type { LinkPayload } from '../plugins/floatingLinkEditor/types.js'\n\nexport interface Props {\n drawerSlug: string\n handleModalSubmit: (fields: FormState, data: Record<string, unknown>) => void\n stateData?: LinkPayload\n}\n"],"names":[],"rangeMappings":"","mappings":"AAIA,WAIC"}
1
+ {"version":3,"sources":["../../../../../src/field/features/link/drawer/types.ts"],"sourcesContent":["import type { FormState } from 'payload/types'\n\nimport type { LinkFields } from '../nodes/types.js'\n\nexport interface Props {\n drawerSlug: string\n handleModalSubmit: (fields: FormState, data: Record<string, unknown>) => void\n stateData?: LinkFields & { text: string }\n}\n"],"names":[],"rangeMappings":"","mappings":"AAIA,WAIC"}
@@ -1,4 +1,3 @@
1
- import type { I18n } from '@payloadcms/translations';
2
1
  import type { SanitizedConfig } from 'payload/config';
3
2
  import type { FieldWithRichTextRequiredEditor } from 'payload/types';
4
3
  import type { FeatureProviderProviderServer } from '../types.js';
@@ -26,7 +25,6 @@ export type LinkFeatureServerProps = ExclusiveLinkCollectionsProps & {
26
25
  fields?: ((args: {
27
26
  config: SanitizedConfig;
28
27
  defaultFields: FieldWithRichTextRequiredEditor[];
29
- i18n: I18n;
30
28
  }) => FieldWithRichTextRequiredEditor[]) | FieldWithRichTextRequiredEditor[];
31
29
  };
32
30
  export declare const LinkFeature: FeatureProviderProviderServer<LinkFeatureServerProps, ClientProps>;
@@ -1 +1 @@
1
- {"version":3,"file":"feature.server.d.ts","sourceRoot":"","sources":["../../../../src/field/features/link/feature.server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAA;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AACrD,OAAO,KAAK,EAAS,+BAA+B,EAAE,MAAM,eAAe,CAAA;AAK3E,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,aAAa,CAAA;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAUtD,MAAM,MAAM,6BAA6B,GACrC;IACE;;;QAGI;IACJ,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAA;IAG9B,kBAAkB,CAAC,EAAE,KAAK,CAAA;CAC3B,GACD;IAEE,mBAAmB,CAAC,EAAE,KAAK,CAAA;IAE3B;;;QAGI;IACJ,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;CAC9B,CAAA;AAEL,MAAM,MAAM,sBAAsB,GAAG,6BAA6B,GAAG;IACnE;;;OAGG;IACH,MAAM,CAAC,EACH,CAAC,CAAC,IAAI,EAAE;QACN,MAAM,EAAE,eAAe,CAAA;QACvB,aAAa,EAAE,+BAA+B,EAAE,CAAA;QAChD,IAAI,EAAE,IAAI,CAAA;KACX,KAAK,+BAA+B,EAAE,CAAC,GACxC,+BAA+B,EAAE,CAAA;CACtC,CAAA;AAED,eAAO,MAAM,WAAW,EAAE,6BAA6B,CAAC,sBAAsB,EAAE,WAAW,CA4H1F,CAAA"}
1
+ {"version":3,"file":"feature.server.d.ts","sourceRoot":"","sources":["../../../../src/field/features/link/feature.server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAC7D,OAAO,KAAK,EAAS,+BAA+B,EAAE,MAAM,eAAe,CAAA;AAM3E,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,aAAa,CAAA;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAWtD,MAAM,MAAM,6BAA6B,GACrC;IACE;;;QAGI;IACJ,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAA;IAG9B,kBAAkB,CAAC,EAAE,KAAK,CAAA;CAC3B,GACD;IAEE,mBAAmB,CAAC,EAAE,KAAK,CAAA;IAE3B;;;QAGI;IACJ,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;CAC9B,CAAA;AAEL,MAAM,MAAM,sBAAsB,GAAG,6BAA6B,GAAG;IACnE;;;OAGG;IACH,MAAM,CAAC,EACH,CAAC,CAAC,IAAI,EAAE;QACN,MAAM,EAAE,eAAe,CAAA;QACvB,aAAa,EAAE,+BAA+B,EAAE,CAAA;KACjD,KAAK,+BAA+B,EAAE,CAAC,GACxC,+BAA+B,EAAE,CAAA;CACtC,CAAA;AAED,eAAO,MAAM,WAAW,EAAE,6BAA6B,CAAC,sBAAsB,EAAE,WAAW,CAmI1F,CAAA"}
@@ -1,4 +1,5 @@
1
1
  import { traverseFields } from '@payloadcms/next/utilities';
2
+ import { sanitizeFields } from 'payload/config';
2
3
  import { deepCopyObject } from 'payload/utilities';
3
4
  import { convertLexicalNodesToHTML } from '../converters/html/converter/index.js';
4
5
  import { createNode } from '../typeUtilities.js';
@@ -7,29 +8,38 @@ import { AutoLinkNode } from './nodes/AutoLinkNode.js';
7
8
  import { LinkNode } from './nodes/LinkNode.js';
8
9
  import { transformExtraFields } from './plugins/floatingLinkEditor/utilities.js';
9
10
  import { linkPopulationPromiseHOC } from './populationPromise.js';
11
+ import { linkValidation } from './validate.js';
10
12
  export const LinkFeature = (props)=>{
11
13
  if (!props) {
12
14
  props = {};
13
15
  }
14
16
  return {
15
- feature: ()=>{
17
+ feature: async ({ config: _config })=>{
18
+ const validRelationships = _config.collections.map((c)=>c.slug) || [];
19
+ const _transformedFields = transformExtraFields(deepCopyObject(props.fields), _config, props.enabledCollections, props.disabledCollections);
20
+ const sanitizedFields = await sanitizeFields({
21
+ config: _config,
22
+ fields: _transformedFields,
23
+ requireFieldLevelRichTextEditor: true,
24
+ validRelationships
25
+ });
26
+ props.fields = sanitizedFields;
16
27
  return {
17
28
  ClientComponent: LinkFeatureClientComponent,
18
29
  clientFeatureProps: {
19
30
  disabledCollections: props.disabledCollections,
20
31
  enabledCollections: props.enabledCollections
21
32
  },
22
- generateSchemaMap: ({ config, i18n, props })=>{
23
- const transformedFields = transformExtraFields(deepCopyObject(props.fields), config, i18n, props.enabledCollections, props.disabledCollections);
24
- if (!transformedFields || !Array.isArray(transformedFields) || transformedFields.length === 0) {
33
+ generateSchemaMap: ({ config, i18n })=>{
34
+ if (!sanitizedFields || !Array.isArray(sanitizedFields) || sanitizedFields.length === 0) {
25
35
  return null;
26
36
  }
27
37
  const schemaMap = new Map();
28
38
  const validRelationships = config.collections.map((c)=>c.slug) || [];
29
- schemaMap.set('fields', transformedFields);
39
+ schemaMap.set('fields', sanitizedFields);
30
40
  traverseFields({
31
41
  config,
32
- fields: transformedFields,
42
+ fields: sanitizedFields,
33
43
  i18n,
34
44
  schemaMap,
35
45
  schemaPath: 'fields',
@@ -73,6 +83,9 @@ export const LinkFeature = (props)=>{
73
83
  node: AutoLinkNode,
74
84
  populationPromises: [
75
85
  linkPopulationPromiseHOC(props)
86
+ ],
87
+ validations: [
88
+ linkValidation(props)
76
89
  ]
77
90
  }),
78
91
  createNode({
@@ -100,6 +113,9 @@ export const LinkFeature = (props)=>{
100
113
  node: LinkNode,
101
114
  populationPromises: [
102
115
  linkPopulationPromiseHOC(props)
116
+ ],
117
+ validations: [
118
+ linkValidation(props)
103
119
  ]
104
120
  })
105
121
  ],