@payloadcms/richtext-lexical 4.0.0-internal.d1cc1d3 → 4.0.0-internal.d21c039

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 (177) hide show
  1. package/dist/exports/client/Field-QKAL7KMC.js +2 -0
  2. package/dist/exports/client/Field-QKAL7KMC.js.map +7 -0
  3. package/dist/exports/client/bundled.css +1 -1
  4. package/dist/exports/client/chunk-LN6VX25I.js +2 -0
  5. package/dist/exports/client/{chunk-SSMQFWCQ.js.map → chunk-LN6VX25I.js.map} +4 -4
  6. package/dist/exports/client/index.js +26 -26
  7. package/dist/exports/client/index.js.map +4 -4
  8. package/dist/features/converters/lexicalToHtml/async/converters/heading.js +1 -1
  9. package/dist/features/converters/lexicalToHtml/async/converters/heading.js.map +1 -1
  10. package/dist/features/converters/lexicalToHtml/async/converters/list.d.ts.map +1 -1
  11. package/dist/features/converters/lexicalToHtml/async/converters/list.js +4 -3
  12. package/dist/features/converters/lexicalToHtml/async/converters/list.js.map +1 -1
  13. package/dist/features/converters/lexicalToHtml/shared/findConverterForNode.d.ts.map +1 -1
  14. package/dist/features/converters/lexicalToHtml/shared/findConverterForNode.js +3 -2
  15. package/dist/features/converters/lexicalToHtml/shared/findConverterForNode.js.map +1 -1
  16. package/dist/features/converters/lexicalToHtml/sync/converters/heading.js +1 -1
  17. package/dist/features/converters/lexicalToHtml/sync/converters/heading.js.map +1 -1
  18. package/dist/features/converters/lexicalToHtml/sync/converters/list.d.ts.map +1 -1
  19. package/dist/features/converters/lexicalToHtml/sync/converters/list.js +4 -3
  20. package/dist/features/converters/lexicalToHtml/sync/converters/list.js.map +1 -1
  21. package/dist/features/converters/lexicalToJSX/converter/converters/heading.d.ts.map +1 -1
  22. package/dist/features/converters/lexicalToJSX/converter/converters/heading.js +2 -1
  23. package/dist/features/converters/lexicalToJSX/converter/converters/heading.js.map +1 -1
  24. package/dist/features/converters/lexicalToJSX/converter/converters/list.d.ts.map +1 -1
  25. package/dist/features/converters/lexicalToJSX/converter/converters/list.js +2 -1
  26. package/dist/features/converters/lexicalToJSX/converter/converters/list.js.map +1 -1
  27. package/dist/features/heading/constants.d.ts +2 -0
  28. package/dist/features/heading/constants.d.ts.map +1 -0
  29. package/dist/features/heading/constants.js +2 -0
  30. package/dist/features/heading/constants.js.map +1 -0
  31. package/dist/features/heading/server/index.d.ts.map +1 -1
  32. package/dist/features/heading/server/index.js +5 -1
  33. package/dist/features/heading/server/index.js.map +1 -1
  34. package/dist/features/heading/server/validate.d.ts +6 -0
  35. package/dist/features/heading/server/validate.d.ts.map +1 -0
  36. package/dist/features/heading/server/validate.js +15 -0
  37. package/dist/features/heading/server/validate.js.map +1 -0
  38. package/dist/features/link/server/baseFields.d.ts.map +1 -1
  39. package/dist/features/link/server/baseFields.js +4 -5
  40. package/dist/features/link/server/baseFields.js.map +1 -1
  41. package/dist/features/lists/checklist/server/index.d.ts.map +1 -1
  42. package/dist/features/lists/checklist/server/index.js +5 -2
  43. package/dist/features/lists/checklist/server/index.js.map +1 -1
  44. package/dist/features/lists/orderedList/server/index.d.ts.map +1 -1
  45. package/dist/features/lists/orderedList/server/index.js +5 -2
  46. package/dist/features/lists/orderedList/server/index.js.map +1 -1
  47. package/dist/features/lists/shared/constants.d.ts +2 -0
  48. package/dist/features/lists/shared/constants.d.ts.map +1 -0
  49. package/dist/features/lists/shared/constants.js +2 -0
  50. package/dist/features/lists/shared/constants.js.map +1 -0
  51. package/dist/features/lists/shared/validate.d.ts +5 -0
  52. package/dist/features/lists/shared/validate.d.ts.map +1 -0
  53. package/dist/features/lists/shared/validate.js +15 -0
  54. package/dist/features/lists/shared/validate.js.map +1 -0
  55. package/dist/features/lists/unorderedList/server/index.d.ts.map +1 -1
  56. package/dist/features/lists/unorderedList/server/index.js +5 -2
  57. package/dist/features/lists/unorderedList/server/index.js.map +1 -1
  58. package/dist/features/relationship/client/index.d.ts +2 -2
  59. package/dist/features/relationship/client/index.d.ts.map +1 -1
  60. package/dist/features/relationship/client/index.js.map +1 -1
  61. package/dist/features/relationship/client/plugins/index.d.ts +2 -2
  62. package/dist/features/relationship/client/plugins/index.d.ts.map +1 -1
  63. package/dist/features/relationship/client/plugins/index.js +27 -31
  64. package/dist/features/relationship/client/plugins/index.js.map +1 -1
  65. package/dist/features/relationship/client/utils/useEnabledRelationships.d.ts +2 -4
  66. package/dist/features/relationship/client/utils/useEnabledRelationships.d.ts.map +1 -1
  67. package/dist/features/relationship/client/utils/useEnabledRelationships.js +53 -20
  68. package/dist/features/relationship/client/utils/useEnabledRelationships.js.map +1 -1
  69. package/dist/features/relationship/server/graphQLPopulationPromise.d.ts +2 -2
  70. package/dist/features/relationship/server/graphQLPopulationPromise.d.ts.map +1 -1
  71. package/dist/features/relationship/server/graphQLPopulationPromise.js +2 -2
  72. package/dist/features/relationship/server/graphQLPopulationPromise.js.map +1 -1
  73. package/dist/features/relationship/server/index.d.ts +8 -1
  74. package/dist/features/relationship/server/index.d.ts.map +1 -1
  75. package/dist/features/relationship/server/index.js +28 -11
  76. package/dist/features/relationship/server/index.js.map +1 -1
  77. package/dist/features/relationship/server/schema.d.ts +2 -2
  78. package/dist/features/relationship/server/schema.d.ts.map +1 -1
  79. package/dist/features/relationship/server/schema.js +5 -10
  80. package/dist/features/relationship/server/schema.js.map +1 -1
  81. package/dist/features/relationship/shared/filterEnabledRelationshipCollections.d.ts +1 -6
  82. package/dist/features/relationship/shared/filterEnabledRelationshipCollections.d.ts.map +1 -1
  83. package/dist/features/relationship/shared/filterEnabledRelationshipCollections.js +3 -8
  84. package/dist/features/relationship/shared/filterEnabledRelationshipCollections.js.map +1 -1
  85. package/dist/features/table/client/plugins/TableActionMenuPlugin/computeSelectionCount.d.ts +8 -0
  86. package/dist/features/table/client/plugins/TableActionMenuPlugin/computeSelectionCount.d.ts.map +1 -0
  87. package/dist/features/table/client/plugins/TableActionMenuPlugin/computeSelectionCount.js +19 -0
  88. package/dist/features/table/client/plugins/TableActionMenuPlugin/computeSelectionCount.js.map +1 -0
  89. package/dist/features/table/client/plugins/TableActionMenuPlugin/index.d.ts.map +1 -1
  90. package/dist/features/table/client/plugins/TableActionMenuPlugin/index.js +16 -43
  91. package/dist/features/table/client/plugins/TableActionMenuPlugin/index.js.map +1 -1
  92. package/dist/features/toolbars/fixed/client/Toolbar/horizontalWheelScroll.d.ts +8 -0
  93. package/dist/features/toolbars/fixed/client/Toolbar/horizontalWheelScroll.d.ts.map +1 -0
  94. package/dist/features/toolbars/fixed/client/Toolbar/horizontalWheelScroll.js +80 -0
  95. package/dist/features/toolbars/fixed/client/Toolbar/horizontalWheelScroll.js.map +1 -0
  96. package/dist/features/toolbars/fixed/client/Toolbar/index.css +79 -5
  97. package/dist/features/toolbars/fixed/client/Toolbar/index.d.ts.map +1 -1
  98. package/dist/features/toolbars/fixed/client/Toolbar/index.js +4 -1
  99. package/dist/features/toolbars/fixed/client/Toolbar/index.js.map +1 -1
  100. package/dist/features/toolbars/shared/ToolbarDropdown/index.css +12 -11
  101. package/dist/features/upload/client/index.d.ts +3 -2
  102. package/dist/features/upload/client/index.d.ts.map +1 -1
  103. package/dist/features/upload/client/index.js.map +1 -1
  104. package/dist/features/upload/client/plugin/index.d.ts.map +1 -1
  105. package/dist/features/upload/client/plugin/index.js +47 -52
  106. package/dist/features/upload/client/plugin/index.js.map +1 -1
  107. package/dist/features/upload/server/graphQLPopulationPromise.d.ts +2 -2
  108. package/dist/features/upload/server/graphQLPopulationPromise.d.ts.map +1 -1
  109. package/dist/features/upload/server/graphQLPopulationPromise.js +1 -1
  110. package/dist/features/upload/server/graphQLPopulationPromise.js.map +1 -1
  111. package/dist/features/upload/server/index.d.ts +6 -2
  112. package/dist/features/upload/server/index.d.ts.map +1 -1
  113. package/dist/features/upload/server/index.js +18 -14
  114. package/dist/features/upload/server/index.js.map +1 -1
  115. package/dist/features/upload/server/schema.d.ts +2 -2
  116. package/dist/features/upload/server/schema.d.ts.map +1 -1
  117. package/dist/features/upload/server/schema.js +4 -8
  118. package/dist/features/upload/server/schema.js.map +1 -1
  119. package/dist/features/upload/server/validate.d.ts +2 -2
  120. package/dist/features/upload/server/validate.d.ts.map +1 -1
  121. package/dist/features/upload/server/validate.js +3 -0
  122. package/dist/features/upload/server/validate.js.map +1 -1
  123. package/dist/field/Diff/converters/listitem/index.d.ts.map +1 -1
  124. package/dist/field/Diff/converters/listitem/index.js +2 -1
  125. package/dist/field/Diff/converters/listitem/index.js.map +1 -1
  126. package/dist/field/Diff/index.css +19 -22
  127. package/dist/field/Diff/index.d.ts.map +1 -1
  128. package/dist/field/Diff/index.js +1 -0
  129. package/dist/field/Diff/index.js.map +1 -1
  130. package/dist/field/RenderLexical/index.d.ts +3 -1
  131. package/dist/field/RenderLexical/index.d.ts.map +1 -1
  132. package/dist/field/RenderLexical/index.js +23 -23
  133. package/dist/field/RenderLexical/index.js.map +1 -1
  134. package/dist/field/bundled.css +1 -1
  135. package/dist/field/index.css +14 -10
  136. package/dist/i18n.d.ts.map +1 -1
  137. package/dist/i18n.js +68 -0
  138. package/dist/i18n.js.map +1 -1
  139. package/dist/index.d.ts +1 -1
  140. package/dist/index.js +1 -1
  141. package/dist/index.js.map +1 -1
  142. package/dist/lexical/LexicalEditor.css +2 -2
  143. package/dist/lexical/LexicalEditor.js.map +1 -1
  144. package/dist/lexical/plugins/InsertParagraphAtEnd/index.css +16 -23
  145. package/dist/lexical/plugins/InsertParagraphAtEnd/index.d.ts.map +1 -1
  146. package/dist/lexical/plugins/InsertParagraphAtEnd/index.js +27 -14
  147. package/dist/lexical/plugins/InsertParagraphAtEnd/index.js.map +1 -1
  148. package/dist/lexical/theme/EditorTheme.css +25 -37
  149. package/dist/lexical/ui/ContentEditable.css +1 -0
  150. package/dist/lexical/ui/icons/H3/index.d.ts.map +1 -1
  151. package/dist/lexical/ui/icons/H3/index.js +13 -6
  152. package/dist/lexical/ui/icons/H3/index.js.map +1 -1
  153. package/dist/lexical/ui/icons/H4/index.d.ts.map +1 -1
  154. package/dist/lexical/ui/icons/H4/index.js +13 -6
  155. package/dist/lexical/ui/icons/H4/index.js.map +1 -1
  156. package/dist/lexical/ui/icons/H5/index.d.ts.map +1 -1
  157. package/dist/lexical/ui/icons/H5/index.js +13 -6
  158. package/dist/lexical/ui/icons/H5/index.js.map +1 -1
  159. package/dist/lexical/ui/icons/H6/index.d.ts.map +1 -1
  160. package/dist/lexical/ui/icons/H6/index.js +13 -6
  161. package/dist/lexical/ui/icons/H6/index.js.map +1 -1
  162. package/package.json +22 -22
  163. package/dist/dependencyChecker.spec.js +0 -16
  164. package/dist/dependencyChecker.spec.js.map +0 -1
  165. package/dist/exports/client/Field-IZKDIUJY.js +0 -2
  166. package/dist/exports/client/Field-IZKDIUJY.js.map +0 -7
  167. package/dist/exports/client/chunk-SSMQFWCQ.js +0 -2
  168. package/dist/features/converters/lexicalToPlaintext/convertLexicalToPlaintext.spec.js +0 -180
  169. package/dist/features/converters/lexicalToPlaintext/convertLexicalToPlaintext.spec.js.map +0 -1
  170. package/dist/features/link/markdownTransformer.spec.js +0 -195
  171. package/dist/features/link/markdownTransformer.spec.js.map +0 -1
  172. package/dist/lexical/utils/markdown/convertFromMarkdownString.spec.js +0 -88
  173. package/dist/lexical/utils/markdown/convertFromMarkdownString.spec.js.map +0 -1
  174. package/dist/lexical/utils/url.spec.js +0 -114
  175. package/dist/lexical/utils/url.spec.js.map +0 -1
  176. package/dist/utilities/jsx/jsx.spec.js +0 -178
  177. package/dist/utilities/jsx/jsx.spec.js.map +0 -1
@@ -1,180 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { convertLexicalToPlaintext } from './sync/index.js';
3
- function textNode(text, bold) {
4
- return {
5
- type: 'text',
6
- detail: 0,
7
- format: bold ? 1 : 0,
8
- mode: 'normal',
9
- style: '',
10
- text,
11
- version: 1
12
- };
13
- }
14
- function linebreakNode() {
15
- return {
16
- type: 'linebreak',
17
- version: 1
18
- };
19
- }
20
- function tabNode() {
21
- return {
22
- type: 'tab',
23
- detail: 0,
24
- format: 0,
25
- mode: 'normal',
26
- style: '',
27
- text: '',
28
- version: 1
29
- };
30
- }
31
- function paragraphNode(children) {
32
- return {
33
- type: 'paragraph',
34
- children,
35
- direction: 'ltr',
36
- format: '',
37
- indent: 0,
38
- textFormat: 0,
39
- version: 1
40
- };
41
- }
42
- function headingNode(children) {
43
- return {
44
- type: 'heading',
45
- children,
46
- direction: 'ltr',
47
- format: '',
48
- indent: 0,
49
- textFormat: 0,
50
- tag: 'h1',
51
- version: 1
52
- };
53
- }
54
- function listItemNode(children) {
55
- return {
56
- type: 'listitem',
57
- children,
58
- checked: false,
59
- direction: 'ltr',
60
- format: '',
61
- indent: 0,
62
- value: 0,
63
- version: 1
64
- };
65
- }
66
- function listNode(children) {
67
- return {
68
- type: 'list',
69
- children,
70
- direction: 'ltr',
71
- format: '',
72
- indent: 0,
73
- listType: 'bullet',
74
- start: 0,
75
- tag: 'ul',
76
- version: 1
77
- };
78
- }
79
- function tableNode(children) {
80
- return {
81
- type: 'table',
82
- children,
83
- direction: 'ltr',
84
- format: '',
85
- indent: 0,
86
- version: 1
87
- };
88
- }
89
- function tableRowNode(children) {
90
- return {
91
- type: 'tablerow',
92
- children,
93
- direction: 'ltr',
94
- format: '',
95
- indent: 0,
96
- version: 1
97
- };
98
- }
99
- function tableCellNode(children) {
100
- return {
101
- type: 'tablecell',
102
- children,
103
- direction: 'ltr',
104
- format: '',
105
- indent: 0,
106
- headerState: 0,
107
- version: 1
108
- };
109
- }
110
- function rootNode(nodes) {
111
- return {
112
- root: {
113
- type: 'root',
114
- children: nodes,
115
- direction: 'ltr',
116
- format: '',
117
- indent: 0,
118
- version: 1
119
- }
120
- };
121
- }
122
- describe('convertLexicalToPlaintext', () => {
123
- it('ensure paragraph with text is correctly converted', () => {
124
- const data = rootNode([paragraphNode([textNode('Basic Text')])]);
125
- const plaintext = convertLexicalToPlaintext({
126
- data
127
- });
128
- expect(plaintext).toBe('Basic Text');
129
- });
130
- it('ensure paragraph with multiple text nodes is correctly converted', () => {
131
- const data = rootNode([paragraphNode([textNode('Basic Text'), textNode(' Bold', true), textNode(' Text')])]);
132
- const plaintext = convertLexicalToPlaintext({
133
- data
134
- });
135
- expect(plaintext).toBe('Basic Text Bold Text');
136
- });
137
- it('ensure linebreaks are converted correctly', () => {
138
- const data = rootNode([paragraphNode([textNode('Basic Text'), linebreakNode(), textNode('Next Line')])]);
139
- const plaintext = convertLexicalToPlaintext({
140
- data
141
- });
142
- expect(plaintext).toBe('Basic Text\nNext Line');
143
- });
144
- it('ensure tabs are converted correctly', () => {
145
- const data = rootNode([paragraphNode([textNode('Basic Text'), tabNode(), textNode('Next Line')])]);
146
- const plaintext = convertLexicalToPlaintext({
147
- data
148
- });
149
- expect(plaintext).toBe('Basic Text\tNext Line');
150
- });
151
- it('ensure new lines are added between paragraphs', () => {
152
- const data = rootNode([paragraphNode([textNode('Basic text')]), paragraphNode([textNode('Next block-node')])]);
153
- const plaintext = convertLexicalToPlaintext({
154
- data
155
- });
156
- expect(plaintext).toBe('Basic text\n\nNext block-node');
157
- });
158
- it('ensure new lines are added between heading nodes', () => {
159
- const data = rootNode([headingNode([textNode('Basic text')]), headingNode([textNode('Next block-node')])]);
160
- const plaintext = convertLexicalToPlaintext({
161
- data
162
- });
163
- expect(plaintext).toBe('Basic text\n\nNext block-node');
164
- });
165
- it('ensure new lines are added between list items and lists', () => {
166
- const data = rootNode([listNode([listItemNode([textNode('First item')]), listItemNode([textNode('Second item')])]), listNode([listItemNode([textNode('Next list')])])]);
167
- const plaintext = convertLexicalToPlaintext({
168
- data
169
- });
170
- expect(plaintext).toBe('First item\nSecond item\n\nNext list');
171
- });
172
- it('ensure new lines are added between tables, table rows, and table cells', () => {
173
- const data = rootNode([tableNode([tableRowNode([tableCellNode([textNode('Cell 1, Row 1')]), tableCellNode([textNode('Cell 2, Row 1')])]), tableRowNode([tableCellNode([textNode('Cell 1, Row 2')]), tableCellNode([textNode('Cell 2, Row 2')])])]), tableNode([tableRowNode([tableCellNode([textNode('Cell in Table 2')])])])]);
174
- const plaintext = convertLexicalToPlaintext({
175
- data
176
- });
177
- expect(plaintext).toBe('Cell 1, Row 1 | Cell 2, Row 1\nCell 1, Row 2 | Cell 2, Row 2\n\nCell in Table 2');
178
- });
179
- });
180
- //# sourceMappingURL=convertLexicalToPlaintext.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"convertLexicalToPlaintext.spec.js","names":["describe","it","expect","convertLexicalToPlaintext","textNode","text","bold","type","detail","format","mode","style","version","linebreakNode","tabNode","paragraphNode","children","direction","indent","textFormat","headingNode","tag","listItemNode","checked","value","listNode","listType","start","tableNode","tableRowNode","tableCellNode","headerState","rootNode","nodes","root","data","plaintext","toBe"],"sources":["../../../../src/features/converters/lexicalToPlaintext/convertLexicalToPlaintext.spec.ts"],"sourcesContent":["import { describe, it, expect } from 'vitest'\nimport type {\n DefaultNodeTypes,\n DefaultTypedEditorState,\n SerializedTabNode,\n SerializedParagraphNode,\n SerializedTextNode,\n SerializedLineBreakNode,\n SerializedHeadingNode,\n SerializedListItemNode,\n SerializedListNode,\n SerializedTableRowNode,\n SerializedTableNode,\n SerializedTableCellNode,\n} from '../../../types/nodeTypes.js'\nimport { convertLexicalToPlaintext } from './sync/index.js'\n\nfunction textNode(text: string, bold?: boolean): SerializedTextNode {\n return {\n type: 'text',\n detail: 0,\n format: bold ? 1 : 0,\n mode: 'normal',\n style: '',\n text,\n version: 1,\n }\n}\n\nfunction linebreakNode(): SerializedLineBreakNode {\n return {\n type: 'linebreak',\n version: 1,\n }\n}\n\nfunction tabNode(): SerializedTabNode {\n return {\n type: 'tab',\n detail: 0,\n format: 0,\n mode: 'normal',\n style: '',\n text: '',\n version: 1,\n }\n}\n\nfunction paragraphNode(children: DefaultNodeTypes[]): SerializedParagraphNode {\n return {\n type: 'paragraph',\n children,\n direction: 'ltr',\n format: '',\n indent: 0,\n textFormat: 0,\n version: 1,\n }\n}\n\nfunction headingNode(children: DefaultNodeTypes[]): SerializedHeadingNode {\n return {\n type: 'heading',\n children,\n direction: 'ltr',\n format: '',\n indent: 0,\n textFormat: 0,\n tag: 'h1',\n version: 1,\n }\n}\n\nfunction listItemNode(children: DefaultNodeTypes[]): SerializedListItemNode {\n return {\n type: 'listitem',\n children,\n checked: false,\n direction: 'ltr',\n format: '',\n indent: 0,\n value: 0,\n version: 1,\n }\n}\n\nfunction listNode(children: DefaultNodeTypes[]): SerializedListNode {\n return {\n type: 'list',\n children,\n direction: 'ltr',\n format: '',\n indent: 0,\n listType: 'bullet',\n start: 0,\n tag: 'ul',\n version: 1,\n }\n}\n\nfunction tableNode(children: (DefaultNodeTypes | SerializedTableRowNode)[]): SerializedTableNode {\n return {\n type: 'table',\n children,\n direction: 'ltr',\n format: '',\n indent: 0,\n version: 1,\n }\n}\n\nfunction tableRowNode(\n children: (DefaultNodeTypes | SerializedTableCellNode)[],\n): SerializedTableRowNode {\n return {\n type: 'tablerow',\n children,\n direction: 'ltr',\n format: '',\n indent: 0,\n version: 1,\n }\n}\n\nfunction tableCellNode(children: DefaultNodeTypes[]): SerializedTableCellNode {\n return {\n type: 'tablecell',\n children,\n direction: 'ltr',\n format: '',\n indent: 0,\n headerState: 0,\n version: 1,\n }\n}\n\nfunction rootNode(nodes: (DefaultNodeTypes | SerializedTableNode)[]): DefaultTypedEditorState {\n return {\n root: {\n type: 'root',\n children: nodes,\n direction: 'ltr',\n format: '',\n indent: 0,\n version: 1,\n },\n }\n}\n\ndescribe('convertLexicalToPlaintext', () => {\n it('ensure paragraph with text is correctly converted', () => {\n const data: DefaultTypedEditorState = rootNode([paragraphNode([textNode('Basic Text')])])\n\n const plaintext = convertLexicalToPlaintext({\n data,\n })\n\n expect(plaintext).toBe('Basic Text')\n })\n\n it('ensure paragraph with multiple text nodes is correctly converted', () => {\n const data: DefaultTypedEditorState = rootNode([\n paragraphNode([textNode('Basic Text'), textNode(' Bold', true), textNode(' Text')]),\n ])\n\n const plaintext = convertLexicalToPlaintext({\n data,\n })\n\n expect(plaintext).toBe('Basic Text Bold Text')\n })\n\n it('ensure linebreaks are converted correctly', () => {\n const data: DefaultTypedEditorState = rootNode([\n paragraphNode([textNode('Basic Text'), linebreakNode(), textNode('Next Line')]),\n ])\n\n const plaintext = convertLexicalToPlaintext({\n data,\n })\n\n expect(plaintext).toBe('Basic Text\\nNext Line')\n })\n\n it('ensure tabs are converted correctly', () => {\n const data: DefaultTypedEditorState = rootNode([\n paragraphNode([textNode('Basic Text'), tabNode(), textNode('Next Line')]),\n ])\n\n const plaintext = convertLexicalToPlaintext({\n data,\n })\n\n expect(plaintext).toBe('Basic Text\\tNext Line')\n })\n\n it('ensure new lines are added between paragraphs', () => {\n const data: DefaultTypedEditorState = rootNode([\n paragraphNode([textNode('Basic text')]),\n paragraphNode([textNode('Next block-node')]),\n ])\n\n const plaintext = convertLexicalToPlaintext({\n data,\n })\n\n expect(plaintext).toBe('Basic text\\n\\nNext block-node')\n })\n\n it('ensure new lines are added between heading nodes', () => {\n const data: DefaultTypedEditorState = rootNode([\n headingNode([textNode('Basic text')]),\n headingNode([textNode('Next block-node')]),\n ])\n\n const plaintext = convertLexicalToPlaintext({\n data,\n })\n\n expect(plaintext).toBe('Basic text\\n\\nNext block-node')\n })\n\n it('ensure new lines are added between list items and lists', () => {\n const data: DefaultTypedEditorState = rootNode([\n listNode([listItemNode([textNode('First item')]), listItemNode([textNode('Second item')])]),\n listNode([listItemNode([textNode('Next list')])]),\n ])\n\n const plaintext = convertLexicalToPlaintext({\n data,\n })\n\n expect(plaintext).toBe('First item\\nSecond item\\n\\nNext list')\n })\n\n it('ensure new lines are added between tables, table rows, and table cells', () => {\n const data: DefaultTypedEditorState = rootNode([\n tableNode([\n tableRowNode([\n tableCellNode([textNode('Cell 1, Row 1')]),\n tableCellNode([textNode('Cell 2, Row 1')]),\n ]),\n tableRowNode([\n tableCellNode([textNode('Cell 1, Row 2')]),\n tableCellNode([textNode('Cell 2, Row 2')]),\n ]),\n ]),\n tableNode([tableRowNode([tableCellNode([textNode('Cell in Table 2')])])]),\n ])\n\n const plaintext = convertLexicalToPlaintext({\n data,\n })\n\n expect(plaintext).toBe(\n 'Cell 1, Row 1 | Cell 2, Row 1\\nCell 1, Row 2 | Cell 2, Row 2\\n\\nCell in Table 2',\n )\n })\n})\n"],"mappings":"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","ignoreList":[]}
@@ -1,195 +0,0 @@
1
- import { createHeadlessEditor } from '@lexical/headless';
2
- import { $createParagraphNode, $createTextNode, $getRoot } from 'lexical';
3
- import { describe, expect, it } from 'vitest';
4
- import { $convertToMarkdownString } from '@lexical/markdown';
5
- import { AutoLinkNode } from './nodes/AutoLinkNode.js';
6
- import { $createLinkNode, LinkNode } from './nodes/LinkNode.js';
7
- import { PAYLOAD_LINK, createPayloadLinkTransformer } from './markdownTransformer.js';
8
- function createEditor() {
9
- return createHeadlessEditor({
10
- nodes: [LinkNode, AutoLinkNode]
11
- });
12
- }
13
- function toMarkdown(setupFn, transformer = PAYLOAD_LINK) {
14
- const editor = createEditor();
15
- editor.update(setupFn, {
16
- discrete: true
17
- });
18
- let markdown = '';
19
- editor.getEditorState().read(() => {
20
- markdown = $convertToMarkdownString([transformer]);
21
- });
22
- return markdown;
23
- }
24
- describe('createPayloadLinkTransformer', () => {
25
- describe('custom links', () => {
26
- it('should export a custom link with its url', () => {
27
- const markdown = toMarkdown(() => {
28
- const link = $createLinkNode({
29
- fields: {
30
- linkType: 'custom',
31
- url: 'https://payloadcms.com',
32
- newTab: false,
33
- doc: null
34
- }
35
- });
36
- link.append($createTextNode('Payload'));
37
- $getRoot().append($createParagraphNode().append(link));
38
- });
39
- expect(markdown).toBe('[Payload](https://payloadcms.com)');
40
- });
41
- it('should export a custom link that opens in a new tab', () => {
42
- // newTab is a Payload field — markdown has no equivalent, so it is intentionally dropped
43
- const markdown = toMarkdown(() => {
44
- const link = $createLinkNode({
45
- fields: {
46
- linkType: 'custom',
47
- url: 'https://payloadcms.com',
48
- newTab: true,
49
- doc: null
50
- }
51
- });
52
- link.append($createTextNode('Payload'));
53
- $getRoot().append($createParagraphNode().append(link));
54
- });
55
- expect(markdown).toBe('[Payload](https://payloadcms.com)');
56
- });
57
- it('should produce an empty href when url is null or undefined', () => {
58
- const markdownNull = toMarkdown(() => {
59
- const link = $createLinkNode({
60
- fields: {
61
- linkType: 'custom',
62
- url: null,
63
- newTab: false,
64
- doc: null
65
- }
66
- });
67
- link.append($createTextNode('Broken'));
68
- $getRoot().append($createParagraphNode().append(link));
69
- });
70
- const markdownUndefined = toMarkdown(() => {
71
- const link = $createLinkNode({
72
- fields: {
73
- linkType: 'custom',
74
- newTab: false,
75
- doc: null
76
- }
77
- });
78
- link.append($createTextNode('Broken'));
79
- $getRoot().append($createParagraphNode().append(link));
80
- });
81
- expect(markdownNull).toBe('[Broken]()');
82
- expect(markdownUndefined).toBe('[Broken]()');
83
- });
84
- });
85
- describe('internal links', () => {
86
- it('should export an empty href when no internalDocToHref is provided', () => {
87
- const markdown = toMarkdown(() => {
88
- const link = $createLinkNode({
89
- fields: {
90
- linkType: 'internal',
91
- doc: {
92
- relationTo: 'pages',
93
- value: {
94
- id: '1',
95
- slug: 'about'
96
- }
97
- },
98
- newTab: false
99
- }
100
- });
101
- link.append($createTextNode('About'));
102
- $getRoot().append($createParagraphNode().append(link));
103
- });
104
- expect(markdown).toBe('[About]()');
105
- });
106
- it('should call internalDocToHref and use the returned url', () => {
107
- const transformer = createPayloadLinkTransformer({
108
- internalDocToHref: ({
109
- linkNode
110
- }) => {
111
- const value = linkNode.fields.doc?.value;
112
- if (value && typeof value === 'object' && 'slug' in value) {
113
- return `/${value.slug}`;
114
- }
115
- return '/';
116
- }
117
- });
118
- const markdown = toMarkdown(() => {
119
- const link = $createLinkNode({
120
- fields: {
121
- linkType: 'internal',
122
- doc: {
123
- relationTo: 'pages',
124
- value: {
125
- id: '1',
126
- slug: 'about'
127
- }
128
- },
129
- newTab: false
130
- }
131
- });
132
- link.append($createTextNode('About'));
133
- $getRoot().append($createParagraphNode().append(link));
134
- }, transformer);
135
- expect(markdown).toBe('[About](/about)');
136
- });
137
- it('should pass the full serialized link node to internalDocToHref', () => {
138
- let capturedLinkNode = null;
139
- const transformer = createPayloadLinkTransformer({
140
- internalDocToHref: ({
141
- linkNode
142
- }) => {
143
- capturedLinkNode = linkNode;
144
- return '/captured';
145
- }
146
- });
147
- toMarkdown(() => {
148
- const link = $createLinkNode({
149
- fields: {
150
- linkType: 'internal',
151
- doc: {
152
- relationTo: 'pages',
153
- value: {
154
- id: '42',
155
- title: 'Home'
156
- }
157
- },
158
- newTab: true
159
- }
160
- });
161
- link.append($createTextNode('Home'));
162
- $getRoot().append($createParagraphNode().append(link));
163
- }, transformer);
164
- expect(capturedLinkNode).not.toBeNull();
165
- expect(capturedLinkNode.fields.linkType).toBe('internal');
166
- expect(capturedLinkNode.fields.doc?.relationTo).toBe('pages');
167
- expect(capturedLinkNode.fields.doc?.value).toMatchObject({
168
- id: '42',
169
- title: 'Home'
170
- });
171
- expect(capturedLinkNode.fields.newTab).toBe(true);
172
- });
173
- });
174
- describe('PAYLOAD_LINK (static export)', () => {
175
- it('should behave identically to createPayloadLinkTransformer() with no args', () => {
176
- const setup = () => {
177
- const link = $createLinkNode({
178
- fields: {
179
- linkType: 'custom',
180
- url: 'https://example.com',
181
- newTab: false,
182
- doc: null
183
- }
184
- });
185
- link.append($createTextNode('Example'));
186
- $getRoot().append($createParagraphNode().append(link));
187
- };
188
- const fromStatic = toMarkdown(setup, PAYLOAD_LINK);
189
- const fromFactory = toMarkdown(setup, createPayloadLinkTransformer());
190
- expect(fromStatic).toBe(fromFactory);
191
- expect(fromStatic).toBe('[Example](https://example.com)');
192
- });
193
- });
194
- });
195
- //# sourceMappingURL=markdownTransformer.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"markdownTransformer.spec.js","names":["createHeadlessEditor","$createParagraphNode","$createTextNode","$getRoot","describe","expect","it","$convertToMarkdownString","AutoLinkNode","$createLinkNode","LinkNode","PAYLOAD_LINK","createPayloadLinkTransformer","createEditor","nodes","toMarkdown","setupFn","transformer","editor","update","discrete","markdown","getEditorState","read","link","fields","linkType","url","newTab","doc","append","toBe","markdownNull","markdownUndefined","relationTo","value","id","slug","internalDocToHref","linkNode","capturedLinkNode","title","not","toBeNull","toMatchObject","setup","fromStatic","fromFactory"],"sources":["../../../src/features/link/markdownTransformer.spec.ts"],"sourcesContent":["import { createHeadlessEditor } from '@lexical/headless'\nimport { $createParagraphNode, $createTextNode, $getRoot } from 'lexical'\nimport { describe, expect, it } from 'vitest'\n\nimport { $convertToMarkdownString } from '@lexical/markdown'\nimport { AutoLinkNode } from './nodes/AutoLinkNode.js'\nimport { $createLinkNode, LinkNode } from './nodes/LinkNode.js'\nimport type { SerializedLinkNode } from './server/schema.js'\nimport { PAYLOAD_LINK, createPayloadLinkTransformer } from './markdownTransformer.js'\n\nfunction createEditor() {\n return createHeadlessEditor({ nodes: [LinkNode, AutoLinkNode] })\n}\n\nfunction toMarkdown(setupFn: () => void, transformer = PAYLOAD_LINK): string {\n const editor = createEditor()\n editor.update(setupFn, { discrete: true })\n let markdown = ''\n editor.getEditorState().read(() => {\n markdown = $convertToMarkdownString([transformer])\n })\n return markdown\n}\n\ndescribe('createPayloadLinkTransformer', () => {\n describe('custom links', () => {\n it('should export a custom link with its url', () => {\n const markdown = toMarkdown(() => {\n const link = $createLinkNode({\n fields: { linkType: 'custom', url: 'https://payloadcms.com', newTab: false, doc: null },\n })\n link.append($createTextNode('Payload'))\n $getRoot().append($createParagraphNode().append(link))\n })\n\n expect(markdown).toBe('[Payload](https://payloadcms.com)')\n })\n\n it('should export a custom link that opens in a new tab', () => {\n // newTab is a Payload field — markdown has no equivalent, so it is intentionally dropped\n const markdown = toMarkdown(() => {\n const link = $createLinkNode({\n fields: { linkType: 'custom', url: 'https://payloadcms.com', newTab: true, doc: null },\n })\n link.append($createTextNode('Payload'))\n $getRoot().append($createParagraphNode().append(link))\n })\n\n expect(markdown).toBe('[Payload](https://payloadcms.com)')\n })\n\n it('should produce an empty href when url is null or undefined', () => {\n const markdownNull = toMarkdown(() => {\n const link = $createLinkNode({\n fields: { linkType: 'custom', url: null as unknown as string, newTab: false, doc: null },\n })\n link.append($createTextNode('Broken'))\n $getRoot().append($createParagraphNode().append(link))\n })\n\n const markdownUndefined = toMarkdown(() => {\n const link = $createLinkNode({\n fields: { linkType: 'custom', newTab: false, doc: null },\n })\n link.append($createTextNode('Broken'))\n $getRoot().append($createParagraphNode().append(link))\n })\n\n expect(markdownNull).toBe('[Broken]()')\n expect(markdownUndefined).toBe('[Broken]()')\n })\n })\n\n describe('internal links', () => {\n it('should export an empty href when no internalDocToHref is provided', () => {\n const markdown = toMarkdown(() => {\n const link = $createLinkNode({\n fields: {\n linkType: 'internal',\n doc: { relationTo: 'pages', value: { id: '1', slug: 'about' } },\n newTab: false,\n },\n })\n link.append($createTextNode('About'))\n $getRoot().append($createParagraphNode().append(link))\n })\n\n expect(markdown).toBe('[About]()')\n })\n\n it('should call internalDocToHref and use the returned url', () => {\n const transformer = createPayloadLinkTransformer({\n internalDocToHref: ({ linkNode }) => {\n const value = linkNode.fields.doc?.value\n if (value && typeof value === 'object' && 'slug' in value) {\n return `/${value.slug}`\n }\n return '/'\n },\n })\n\n const markdown = toMarkdown(() => {\n const link = $createLinkNode({\n fields: {\n linkType: 'internal',\n doc: { relationTo: 'pages', value: { id: '1', slug: 'about' } },\n newTab: false,\n },\n })\n link.append($createTextNode('About'))\n $getRoot().append($createParagraphNode().append(link))\n }, transformer)\n\n expect(markdown).toBe('[About](/about)')\n })\n\n it('should pass the full serialized link node to internalDocToHref', () => {\n let capturedLinkNode: SerializedLinkNode | null = null\n\n const transformer = createPayloadLinkTransformer({\n internalDocToHref: ({ linkNode }) => {\n capturedLinkNode = linkNode\n return '/captured'\n },\n })\n\n toMarkdown(() => {\n const link = $createLinkNode({\n fields: {\n linkType: 'internal',\n doc: { relationTo: 'pages', value: { id: '42', title: 'Home' } },\n newTab: true,\n },\n })\n link.append($createTextNode('Home'))\n $getRoot().append($createParagraphNode().append(link))\n }, transformer)\n\n expect(capturedLinkNode).not.toBeNull()\n expect(capturedLinkNode!.fields.linkType).toBe('internal')\n expect(capturedLinkNode!.fields.doc?.relationTo).toBe('pages')\n expect(capturedLinkNode!.fields.doc?.value).toMatchObject({ id: '42', title: 'Home' })\n expect(capturedLinkNode!.fields.newTab).toBe(true)\n })\n })\n\n describe('PAYLOAD_LINK (static export)', () => {\n it('should behave identically to createPayloadLinkTransformer() with no args', () => {\n const setup = () => {\n const link = $createLinkNode({\n fields: { linkType: 'custom', url: 'https://example.com', newTab: false, doc: null },\n })\n link.append($createTextNode('Example'))\n $getRoot().append($createParagraphNode().append(link))\n }\n\n const fromStatic = toMarkdown(setup, PAYLOAD_LINK)\n const fromFactory = toMarkdown(setup, createPayloadLinkTransformer())\n\n expect(fromStatic).toBe(fromFactory)\n expect(fromStatic).toBe('[Example](https://example.com)')\n })\n })\n})\n"],"mappings":"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","ignoreList":[]}
@@ -1,88 +0,0 @@
1
- import { createHeadlessEditor } from '@lexical/headless';
2
- import { LinkNode } from '@lexical/link';
3
- import { ListItemNode, ListNode } from '@lexical/list';
4
- import { $convertToMarkdownString } from '@lexical/markdown';
5
- import { HeadingNode, QuoteNode } from '@lexical/rich-text';
6
- import { $getRoot, $isElementNode, $isLineBreakNode } from 'lexical';
7
- import { describe, expect, it } from 'vitest';
8
- import { $convertFromMarkdownString } from './convertFromMarkdownString.js';
9
- function createEditor() {
10
- return createHeadlessEditor({
11
- nodes: [HeadingNode, QuoteNode, ListNode, ListItemNode, LinkNode]
12
- });
13
- }
14
- // Payload's editor imports markdown with shouldMergeAdjacentLines = true, so the
15
- // specs exercise that path: hard line breaks must survive even when adjacent lines
16
- // are merged, while soft wraps collapse to a single space.
17
- function importMarkdown(markdown) {
18
- const editor = createEditor();
19
- editor.update(() => $convertFromMarkdownString(markdown, undefined, undefined, false, true), {
20
- discrete: true
21
- });
22
- let result = {
23
- hasLineBreak: false,
24
- textContent: ''
25
- };
26
- editor.getEditorState().read(() => {
27
- const firstChild = $getRoot().getFirstChild();
28
- if (!$isElementNode(firstChild)) {
29
- throw new Error('Expected an element block');
30
- }
31
- result = {
32
- hasLineBreak: firstChild.getChildren().some(child => $isLineBreakNode(child)),
33
- textContent: firstChild.getTextContent()
34
- };
35
- });
36
- return result;
37
- }
38
- function roundTrip(markdown) {
39
- const editor = createEditor();
40
- editor.update(() => $convertFromMarkdownString(markdown, undefined, undefined, false, true), {
41
- discrete: true
42
- });
43
- let output = '';
44
- editor.getEditorState().read(() => {
45
- output = $convertToMarkdownString();
46
- });
47
- return output;
48
- }
49
- describe('markdown hard line break import', () => {
50
- it('should import a trailing-space hard break as a line break node with the marker stripped', () => {
51
- const {
52
- hasLineBreak,
53
- textContent
54
- } = importMarkdown(['foo ', 'bar'].join('\n'));
55
- expect(hasLineBreak).toBe(true);
56
- expect(textContent).toBe('foo\nbar');
57
- });
58
- it('should import a backslash hard break as a line break node with the marker stripped', () => {
59
- const {
60
- hasLineBreak,
61
- textContent
62
- } = importMarkdown('foo\\\nbar');
63
- expect(hasLineBreak).toBe(true);
64
- expect(textContent).toBe('foo\nbar');
65
- });
66
- });
67
- describe('markdown hard line break round trip', () => {
68
- it('should round trip a trailing-space hard break', () => {
69
- const md = ['foo ', 'bar'].join('\n');
70
- expect(roundTrip(md)).toBe(md);
71
- });
72
- it('should round trip a backslash hard break', () => {
73
- const md = 'foo\\\nbar';
74
- expect(roundTrip(md)).toBe(md);
75
- });
76
- it('should not introduce a hard break for a soft wrap', () => {
77
- expect(roundTrip(['foo', 'bar'].join('\n'))).toBe('foo bar');
78
- });
79
- it('should round trip a hard break after formatted text', () => {
80
- const md = '**foo** \nbar';
81
- expect(roundTrip(md)).toBe(md);
82
- });
83
- it('should round trip a hard break after a link', () => {
84
- const md = '[foo](https://payloadcms.com) \nbar';
85
- expect(roundTrip(md)).toBe(md);
86
- });
87
- });
88
- //# sourceMappingURL=convertFromMarkdownString.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"convertFromMarkdownString.spec.js","names":["createHeadlessEditor","LinkNode","ListItemNode","ListNode","$convertToMarkdownString","HeadingNode","QuoteNode","$getRoot","$isElementNode","$isLineBreakNode","describe","expect","it","$convertFromMarkdownString","createEditor","nodes","importMarkdown","markdown","editor","update","undefined","discrete","result","hasLineBreak","textContent","getEditorState","read","firstChild","getFirstChild","Error","getChildren","some","child","getTextContent","roundTrip","output","join","toBe","md"],"sources":["../../../../src/lexical/utils/markdown/convertFromMarkdownString.spec.ts"],"sourcesContent":["import { createHeadlessEditor } from '@lexical/headless'\nimport { LinkNode } from '@lexical/link'\nimport { ListItemNode, ListNode } from '@lexical/list'\nimport { $convertToMarkdownString } from '@lexical/markdown'\nimport { HeadingNode, QuoteNode } from '@lexical/rich-text'\nimport { $getRoot, $isElementNode, $isLineBreakNode } from 'lexical'\nimport { describe, expect, it } from 'vitest'\n\nimport { $convertFromMarkdownString } from './convertFromMarkdownString.js'\n\nfunction createEditor() {\n return createHeadlessEditor({\n nodes: [HeadingNode, QuoteNode, ListNode, ListItemNode, LinkNode],\n })\n}\n\n// Payload's editor imports markdown with shouldMergeAdjacentLines = true, so the\n// specs exercise that path: hard line breaks must survive even when adjacent lines\n// are merged, while soft wraps collapse to a single space.\nfunction importMarkdown(markdown: string): { hasLineBreak: boolean; textContent: string } {\n const editor = createEditor()\n editor.update(() => $convertFromMarkdownString(markdown, undefined, undefined, false, true), {\n discrete: true,\n })\n let result = { hasLineBreak: false, textContent: '' }\n editor.getEditorState().read(() => {\n const firstChild = $getRoot().getFirstChild()\n if (!$isElementNode(firstChild)) {\n throw new Error('Expected an element block')\n }\n result = {\n hasLineBreak: firstChild.getChildren().some((child) => $isLineBreakNode(child)),\n textContent: firstChild.getTextContent(),\n }\n })\n return result\n}\n\nfunction roundTrip(markdown: string): string {\n const editor = createEditor()\n editor.update(() => $convertFromMarkdownString(markdown, undefined, undefined, false, true), {\n discrete: true,\n })\n let output = ''\n editor.getEditorState().read(() => {\n output = $convertToMarkdownString()\n })\n return output\n}\n\ndescribe('markdown hard line break import', () => {\n it('should import a trailing-space hard break as a line break node with the marker stripped', () => {\n const { hasLineBreak, textContent } = importMarkdown(['foo ', 'bar'].join('\\n'))\n\n expect(hasLineBreak).toBe(true)\n expect(textContent).toBe('foo\\nbar')\n })\n\n it('should import a backslash hard break as a line break node with the marker stripped', () => {\n const { hasLineBreak, textContent } = importMarkdown('foo\\\\\\nbar')\n\n expect(hasLineBreak).toBe(true)\n expect(textContent).toBe('foo\\nbar')\n })\n})\n\ndescribe('markdown hard line break round trip', () => {\n it('should round trip a trailing-space hard break', () => {\n const md = ['foo ', 'bar'].join('\\n')\n expect(roundTrip(md)).toBe(md)\n })\n\n it('should round trip a backslash hard break', () => {\n const md = 'foo\\\\\\nbar'\n expect(roundTrip(md)).toBe(md)\n })\n\n it('should not introduce a hard break for a soft wrap', () => {\n expect(roundTrip(['foo', 'bar'].join('\\n'))).toBe('foo bar')\n })\n\n it('should round trip a hard break after formatted text', () => {\n const md = '**foo** \\nbar'\n expect(roundTrip(md)).toBe(md)\n })\n\n it('should round trip a hard break after a link', () => {\n const md = '[foo](https://payloadcms.com) \\nbar'\n expect(roundTrip(md)).toBe(md)\n })\n})\n"],"mappings":"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","ignoreList":[]}
@@ -1,114 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { absoluteRegExp, relativeOrAnchorRegExp, validateUrl } from './url.js';
3
- describe('Lexical URL Regex Matchers', () => {
4
- describe('relativeOrAnchorRegExp', () => {
5
- it('validation for links it should match', async () => {
6
- const shouldMatch = ['/path/to/resource', '/file-name.html', '/', '/dir/', '/path.with.dots/', '#anchor', '#section-title', '/path#fragment', '/page?id=123', '/page?id=123#section', '/search?q=test', '/?global=true'];
7
- shouldMatch.forEach(testCase => {
8
- expect(relativeOrAnchorRegExp.test(testCase)).toBe(true);
9
- });
10
- });
11
- it('validation for links it should not match', async () => {
12
- const shouldNotMatch = ['match', 'http://example.com', 'relative/path', 'file.html', 'some#fragment', '#', '/#', '/path/with spaces', '', 'ftp://example.com'];
13
- shouldNotMatch.forEach(testCase => {
14
- expect(relativeOrAnchorRegExp.test(testCase)).not.toBe(true);
15
- });
16
- });
17
- });
18
- describe('absoluteRegExp', () => {
19
- it('validation for links it should match', async () => {
20
- const shouldMatch = ['http://example.com', 'https://example.com', 'ftp://files.example.com', 'http://example.com/resource', 'https://example.com/resource?key=value', 'http://example.com/resource#anchor', 'http://www.example.com', 'https://sub.example.com/path/file', 'mailto:email@example.com', 'tel:+1234567890', 'http://user:pass@example.com', 'www.example.com', 'www.example.com/resource', 'www.example.com/resource?query=1', 'www.example.com#fragment'];
21
- shouldMatch.forEach(testCase => {
22
- expect(absoluteRegExp.test(testCase)).toBe(true);
23
- });
24
- });
25
- it('validation for links it should not match', async () => {
26
- const shouldNotMatch = ['/relative/path', '#anchor', 'example.com', '://missing.scheme', 'http://', 'http:/example.com', 'ftp://example .com', 'http://example', 'not-a-url', 'http//example.com', 'https://example.com/ spaces'];
27
- shouldNotMatch.forEach(testCase => {
28
- expect(absoluteRegExp.test(testCase)).not.toBe(true);
29
- });
30
- });
31
- });
32
- describe('validateUrl', () => {
33
- describe('absolute URLs', () => {
34
- it('should validate http and https URLs', () => {
35
- const validUrls = ['http://example.com', 'https://example.com', 'http://www.example.com', 'https://sub.example.com/path/file', 'http://example.com/resource', 'https://example.com/resource?key=value', 'http://example.com/resource#anchor'];
36
- validUrls.forEach(url => {
37
- expect(validateUrl(url)).toBe(true);
38
- });
39
- });
40
- it('should validate other protocol URLs', () => {
41
- const validUrls = ['ftp://files.example.com', 'mailto:email@example.com', 'tel:+1234567890'];
42
- validUrls.forEach(url => {
43
- expect(validateUrl(url)).toBe(true);
44
- });
45
- });
46
- it('should validate www URLs without protocol', () => {
47
- const validUrls = ['www.example.com', 'www.example.com/resource', 'www.example.com/resource?query=1', 'www.example.com#fragment'];
48
- validUrls.forEach(url => {
49
- expect(validateUrl(url)).toBe(true);
50
- });
51
- });
52
- });
53
- describe('relative URLs', () => {
54
- it('should validate relative paths', () => {
55
- const validUrls = ['/path/to/resource', '/file-name.html', '/', '/dir/', '/path.with.dots/', '/path#fragment'];
56
- validUrls.forEach(url => {
57
- expect(validateUrl(url)).toBe(true);
58
- });
59
- });
60
- });
61
- describe('anchor links', () => {
62
- it('should validate anchor links', () => {
63
- const validUrls = ['#anchor', '#section-title'];
64
- validUrls.forEach(url => {
65
- expect(validateUrl(url)).toBe(true);
66
- });
67
- });
68
- });
69
- describe('with query params', () => {
70
- it('should validate relative URLs with query parameters', () => {
71
- const validUrls = ['/page?id=123', '/search?q=test', '/products?category=electronics&sort=price', '/path?key=value&another=param', '/page?id=123&filter=active', '/?global=true'];
72
- validUrls.forEach(url => {
73
- expect(validateUrl(url)).toBe(true);
74
- });
75
- });
76
- it('should validate absolute URLs with query parameters', () => {
77
- const validUrls = ['https://example.com?id=123', 'http://example.com/page?key=value', 'www.example.com?search=query', 'https://example.com/path?a=1&b=2&c=3'];
78
- validUrls.forEach(url => {
79
- expect(validateUrl(url)).toBe(true);
80
- });
81
- });
82
- it('should validate URLs with query parameters and anchors', () => {
83
- const validUrls = ['/page?id=123#section', 'https://example.com?key=value#anchor', '/search?q=test#results'];
84
- validUrls.forEach(url => {
85
- expect(validateUrl(url)).toBe(true);
86
- });
87
- });
88
- });
89
- describe('edge cases', () => {
90
- it('should handle the default https:// case', () => {
91
- expect(validateUrl('https://')).toBe(true);
92
- });
93
- it('should return false for empty or invalid URLs', () => {
94
- const invalidUrls = ['', 'not-a-url', 'example.com', 'relative/path', 'file.html', 'some#fragment', 'http://', 'http:/example.com', 'http//example.com'];
95
- invalidUrls.forEach(url => {
96
- expect(validateUrl(url)).toBe(false);
97
- });
98
- });
99
- it('should return false for URLs with spaces', () => {
100
- const invalidUrls = ['/path/with spaces', 'http://example.com/ spaces', 'https://example.com/path with spaces'];
101
- invalidUrls.forEach(url => {
102
- expect(validateUrl(url)).toBe(false);
103
- });
104
- });
105
- it('should return false for malformed URLs', () => {
106
- const invalidUrls = ['://missing.scheme', 'ftp://example .com', 'http://example', '#', '/#'];
107
- invalidUrls.forEach(url => {
108
- expect(validateUrl(url)).toBe(false);
109
- });
110
- });
111
- });
112
- });
113
- });
114
- //# sourceMappingURL=url.spec.js.map