@pranaysahith/decap-cms-core 3.9.1

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 (299) hide show
  1. package/README.md +9 -0
  2. package/dist/@pranaysahith/decap-cms-core.js +52 -0
  3. package/dist/@pranaysahith/decap-cms-core.js.LICENSE.txt +141 -0
  4. package/dist/@pranaysahith/decap-cms-core.js.map +1 -0
  5. package/dist/decap-cms-core.js +47 -0
  6. package/dist/decap-cms-core.js.LICENSE.txt +116 -0
  7. package/dist/decap-cms-core.js.map +1 -0
  8. package/dist/esm/actions/auth.js +97 -0
  9. package/dist/esm/actions/collections.js +15 -0
  10. package/dist/esm/actions/config.js +493 -0
  11. package/dist/esm/actions/deploys.js +79 -0
  12. package/dist/esm/actions/editorialWorkflow.js +480 -0
  13. package/dist/esm/actions/entries.js +865 -0
  14. package/dist/esm/actions/media.js +147 -0
  15. package/dist/esm/actions/mediaLibrary.js +552 -0
  16. package/dist/esm/actions/notifications.js +21 -0
  17. package/dist/esm/actions/search.js +149 -0
  18. package/dist/esm/actions/status.js +74 -0
  19. package/dist/esm/actions/waitUntil.js +32 -0
  20. package/dist/esm/backend.js +1082 -0
  21. package/dist/esm/bootstrap.js +101 -0
  22. package/dist/esm/components/App/App.js +289 -0
  23. package/dist/esm/components/App/Header.js +172 -0
  24. package/dist/esm/components/App/NotFoundPage.js +19 -0
  25. package/dist/esm/components/Collection/Collection.js +198 -0
  26. package/dist/esm/components/Collection/CollectionControls.js +46 -0
  27. package/dist/esm/components/Collection/CollectionSearch.js +222 -0
  28. package/dist/esm/components/Collection/CollectionTop.js +68 -0
  29. package/dist/esm/components/Collection/ControlButton.js +17 -0
  30. package/dist/esm/components/Collection/Entries/Entries.js +73 -0
  31. package/dist/esm/components/Collection/Entries/EntriesCollection.js +241 -0
  32. package/dist/esm/components/Collection/Entries/EntriesSearch.js +113 -0
  33. package/dist/esm/components/Collection/Entries/EntryCard.js +177 -0
  34. package/dist/esm/components/Collection/Entries/EntryListing.js +143 -0
  35. package/dist/esm/components/Collection/FilterControl.js +33 -0
  36. package/dist/esm/components/Collection/FolderRenameControl.js +403 -0
  37. package/dist/esm/components/Collection/GroupControl.js +33 -0
  38. package/dist/esm/components/Collection/NestedCollection.js +308 -0
  39. package/dist/esm/components/Collection/Sidebar.js +91 -0
  40. package/dist/esm/components/Collection/SortControl.js +59 -0
  41. package/dist/esm/components/Collection/ViewStyleControl.js +38 -0
  42. package/dist/esm/components/Editor/Editor.js +466 -0
  43. package/dist/esm/components/Editor/EditorControlPane/EditorControl.js +395 -0
  44. package/dist/esm/components/Editor/EditorControlPane/EditorControlPane.js +254 -0
  45. package/dist/esm/components/Editor/EditorControlPane/Widget.js +374 -0
  46. package/dist/esm/components/Editor/EditorInterface.js +386 -0
  47. package/dist/esm/components/Editor/EditorPreviewPane/EditorPreview.js +47 -0
  48. package/dist/esm/components/Editor/EditorPreviewPane/EditorPreviewContent.js +66 -0
  49. package/dist/esm/components/Editor/EditorPreviewPane/EditorPreviewPane.js +288 -0
  50. package/dist/esm/components/Editor/EditorPreviewPane/PreviewHOC.js +27 -0
  51. package/dist/esm/components/Editor/EditorToolbar.js +536 -0
  52. package/dist/esm/components/Editor/EntryPathEditor.js +272 -0
  53. package/dist/esm/components/Editor/withWorkflow.js +56 -0
  54. package/dist/esm/components/EditorWidgets/Unknown/UnknownControl.js +18 -0
  55. package/dist/esm/components/EditorWidgets/Unknown/UnknownPreview.js +20 -0
  56. package/dist/esm/components/EditorWidgets/index.js +4 -0
  57. package/dist/esm/components/MediaLibrary/EmptyMessage.js +22 -0
  58. package/dist/esm/components/MediaLibrary/MediaLibrary.js +446 -0
  59. package/dist/esm/components/MediaLibrary/MediaLibraryButtons.js +93 -0
  60. package/dist/esm/components/MediaLibrary/MediaLibraryCard.js +99 -0
  61. package/dist/esm/components/MediaLibrary/MediaLibraryCardGrid.js +198 -0
  62. package/dist/esm/components/MediaLibrary/MediaLibraryHeader.js +32 -0
  63. package/dist/esm/components/MediaLibrary/MediaLibraryModal.js +156 -0
  64. package/dist/esm/components/MediaLibrary/MediaLibrarySearch.js +51 -0
  65. package/dist/esm/components/MediaLibrary/MediaLibraryTop.js +123 -0
  66. package/dist/esm/components/UI/DragDrop.js +67 -0
  67. package/dist/esm/components/UI/ErrorBoundary.js +173 -0
  68. package/dist/esm/components/UI/FileUploadButton.js +27 -0
  69. package/dist/esm/components/UI/Modal.js +104 -0
  70. package/dist/esm/components/UI/Notifications.js +62 -0
  71. package/dist/esm/components/UI/SettingsDropdown.js +107 -0
  72. package/dist/esm/components/UI/index.js +6 -0
  73. package/dist/esm/components/Workflow/Workflow.js +133 -0
  74. package/dist/esm/components/Workflow/WorkflowCard.js +128 -0
  75. package/dist/esm/components/Workflow/WorkflowList.js +204 -0
  76. package/dist/esm/constants/collectionTypes.js +2 -0
  77. package/dist/esm/constants/collectionViews.js +2 -0
  78. package/dist/esm/constants/commitProps.js +2 -0
  79. package/dist/esm/constants/configSchema.js +644 -0
  80. package/dist/esm/constants/fieldInference.js +57 -0
  81. package/dist/esm/constants/publishModes.js +18 -0
  82. package/dist/esm/constants/validationErrorTypes.js +6 -0
  83. package/dist/esm/formats/formats.js +83 -0
  84. package/dist/esm/formats/frontmatter.js +146 -0
  85. package/dist/esm/formats/helpers.js +12 -0
  86. package/dist/esm/formats/json.js +8 -0
  87. package/dist/esm/formats/toml.js +32 -0
  88. package/dist/esm/formats/yaml.js +51 -0
  89. package/dist/esm/index.js +7 -0
  90. package/dist/esm/integrations/index.js +28 -0
  91. package/dist/esm/integrations/providers/algolia/implementation.js +174 -0
  92. package/dist/esm/integrations/providers/assetStore/implementation.js +165 -0
  93. package/dist/esm/lib/consoleError.js +3 -0
  94. package/dist/esm/lib/formatters.js +191 -0
  95. package/dist/esm/lib/i18n.js +367 -0
  96. package/dist/esm/lib/phrases.js +6 -0
  97. package/dist/esm/lib/polyfill.js +8 -0
  98. package/dist/esm/lib/registry.js +329 -0
  99. package/dist/esm/lib/serializeEntryValues.js +67 -0
  100. package/dist/esm/lib/stega.js +142 -0
  101. package/dist/esm/lib/textHelper.js +9 -0
  102. package/dist/esm/lib/urlHelper.js +111 -0
  103. package/dist/esm/mediaLibrary.js +37 -0
  104. package/dist/esm/reducers/auth.js +27 -0
  105. package/dist/esm/reducers/collections.js +428 -0
  106. package/dist/esm/reducers/combinedReducer.js +8 -0
  107. package/dist/esm/reducers/config.js +29 -0
  108. package/dist/esm/reducers/cursors.js +31 -0
  109. package/dist/esm/reducers/deploys.js +45 -0
  110. package/dist/esm/reducers/editorialWorkflow.js +83 -0
  111. package/dist/esm/reducers/entries.js +568 -0
  112. package/dist/esm/reducers/entryDraft.js +212 -0
  113. package/dist/esm/reducers/globalUI.js +25 -0
  114. package/dist/esm/reducers/index.js +66 -0
  115. package/dist/esm/reducers/integrations.js +53 -0
  116. package/dist/esm/reducers/mediaLibrary.js +252 -0
  117. package/dist/esm/reducers/medias.js +68 -0
  118. package/dist/esm/reducers/notifications.js +23 -0
  119. package/dist/esm/reducers/search.js +92 -0
  120. package/dist/esm/reducers/status.js +30 -0
  121. package/dist/esm/redux/index.js +7 -0
  122. package/dist/esm/redux/middleware/waitUntilAction.js +48 -0
  123. package/dist/esm/routing/history.js +12 -0
  124. package/dist/esm/types/diacritics.d.js +0 -0
  125. package/dist/esm/types/global.d.js +1 -0
  126. package/dist/esm/types/immutable.js +7 -0
  127. package/dist/esm/types/redux.js +14 -0
  128. package/dist/esm/types/tomlify-j0.4.d.js +0 -0
  129. package/dist/esm/valueObjects/AssetProxy.js +44 -0
  130. package/dist/esm/valueObjects/EditorComponent.js +34 -0
  131. package/dist/esm/valueObjects/Entry.js +20 -0
  132. package/index.d.ts +618 -0
  133. package/package.json +106 -0
  134. package/src/__tests__/backend.spec.js +1161 -0
  135. package/src/actions/__tests__/config.spec.js +1009 -0
  136. package/src/actions/__tests__/editorialWorkflow.spec.js +216 -0
  137. package/src/actions/__tests__/entries.spec.js +596 -0
  138. package/src/actions/__tests__/media.spec.ts +171 -0
  139. package/src/actions/__tests__/mediaLibrary.spec.js +327 -0
  140. package/src/actions/__tests__/search.spec.js +209 -0
  141. package/src/actions/auth.ts +127 -0
  142. package/src/actions/collections.ts +18 -0
  143. package/src/actions/config.ts +565 -0
  144. package/src/actions/deploys.ts +104 -0
  145. package/src/actions/editorialWorkflow.ts +567 -0
  146. package/src/actions/entries.ts +1055 -0
  147. package/src/actions/media.ts +139 -0
  148. package/src/actions/mediaLibrary.ts +574 -0
  149. package/src/actions/notifications.ts +36 -0
  150. package/src/actions/search.ts +221 -0
  151. package/src/actions/status.ts +99 -0
  152. package/src/actions/waitUntil.ts +49 -0
  153. package/src/backend.ts +1400 -0
  154. package/src/bootstrap.js +104 -0
  155. package/src/components/App/App.js +286 -0
  156. package/src/components/App/Header.js +266 -0
  157. package/src/components/App/NotFoundPage.js +23 -0
  158. package/src/components/Collection/Collection.js +210 -0
  159. package/src/components/Collection/CollectionControls.js +58 -0
  160. package/src/components/Collection/CollectionSearch.js +243 -0
  161. package/src/components/Collection/CollectionTop.js +81 -0
  162. package/src/components/Collection/ControlButton.js +27 -0
  163. package/src/components/Collection/Entries/Entries.js +82 -0
  164. package/src/components/Collection/Entries/EntriesCollection.js +277 -0
  165. package/src/components/Collection/Entries/EntriesSearch.js +102 -0
  166. package/src/components/Collection/Entries/EntryCard.js +246 -0
  167. package/src/components/Collection/Entries/EntryListing.js +151 -0
  168. package/src/components/Collection/Entries/__tests__/EntriesCollection.spec.js +163 -0
  169. package/src/components/Collection/Entries/__tests__/__snapshots__/EntriesCollection.spec.js.snap +46 -0
  170. package/src/components/Collection/FilterControl.js +39 -0
  171. package/src/components/Collection/GroupControl.js +39 -0
  172. package/src/components/Collection/NestedCollection.js +330 -0
  173. package/src/components/Collection/Sidebar.js +136 -0
  174. package/src/components/Collection/SortControl.js +68 -0
  175. package/src/components/Collection/ViewStyleControl.js +50 -0
  176. package/src/components/Collection/__tests__/Collection.spec.js +75 -0
  177. package/src/components/Collection/__tests__/NestedCollection.spec.js +445 -0
  178. package/src/components/Collection/__tests__/Sidebar.spec.js +87 -0
  179. package/src/components/Collection/__tests__/__snapshots__/Collection.spec.js.snap +144 -0
  180. package/src/components/Collection/__tests__/__snapshots__/NestedCollection.spec.js.snap +550 -0
  181. package/src/components/Collection/__tests__/__snapshots__/Sidebar.spec.js.snap +312 -0
  182. package/src/components/Editor/Editor.js +497 -0
  183. package/src/components/Editor/EditorControlPane/EditorControl.js +452 -0
  184. package/src/components/Editor/EditorControlPane/EditorControlPane.js +269 -0
  185. package/src/components/Editor/EditorControlPane/Widget.js +384 -0
  186. package/src/components/Editor/EditorInterface.js +444 -0
  187. package/src/components/Editor/EditorPreviewPane/EditorPreview.js +40 -0
  188. package/src/components/Editor/EditorPreviewPane/EditorPreviewContent.js +74 -0
  189. package/src/components/Editor/EditorPreviewPane/EditorPreviewPane.js +333 -0
  190. package/src/components/Editor/EditorPreviewPane/PreviewHOC.js +33 -0
  191. package/src/components/Editor/EditorToolbar.js +691 -0
  192. package/src/components/Editor/__tests__/Editor.spec.js +221 -0
  193. package/src/components/Editor/__tests__/EditorToolbar.spec.js +120 -0
  194. package/src/components/Editor/__tests__/__snapshots__/Editor.spec.js.snap +45 -0
  195. package/src/components/Editor/__tests__/__snapshots__/EditorToolbar.spec.js.snap +4233 -0
  196. package/src/components/Editor/withWorkflow.js +61 -0
  197. package/src/components/EditorWidgets/Unknown/UnknownControl.js +17 -0
  198. package/src/components/EditorWidgets/Unknown/UnknownPreview.js +19 -0
  199. package/src/components/EditorWidgets/index.js +5 -0
  200. package/src/components/MediaLibrary/EmptyMessage.js +28 -0
  201. package/src/components/MediaLibrary/MediaLibrary.js +411 -0
  202. package/src/components/MediaLibrary/MediaLibraryButtons.js +136 -0
  203. package/src/components/MediaLibrary/MediaLibraryCard.js +128 -0
  204. package/src/components/MediaLibrary/MediaLibraryCardGrid.js +199 -0
  205. package/src/components/MediaLibrary/MediaLibraryHeader.js +48 -0
  206. package/src/components/MediaLibrary/MediaLibraryModal.js +200 -0
  207. package/src/components/MediaLibrary/MediaLibrarySearch.js +61 -0
  208. package/src/components/MediaLibrary/MediaLibraryTop.js +143 -0
  209. package/src/components/MediaLibrary/__tests__/MediaLibraryButtons.spec.js +45 -0
  210. package/src/components/MediaLibrary/__tests__/MediaLibraryCard.spec.js +49 -0
  211. package/src/components/MediaLibrary/__tests__/__snapshots__/MediaLibraryCard.spec.js.snap +264 -0
  212. package/src/components/UI/DragDrop.js +66 -0
  213. package/src/components/UI/ErrorBoundary.js +214 -0
  214. package/src/components/UI/FileUploadButton.js +24 -0
  215. package/src/components/UI/Modal.js +112 -0
  216. package/src/components/UI/Notifications.tsx +83 -0
  217. package/src/components/UI/SettingsDropdown.js +103 -0
  218. package/src/components/UI/__tests__/ErrorBoundary.spec.js +57 -0
  219. package/src/components/UI/index.js +6 -0
  220. package/src/components/Workflow/Workflow.js +169 -0
  221. package/src/components/Workflow/WorkflowCard.js +177 -0
  222. package/src/components/Workflow/WorkflowList.js +272 -0
  223. package/src/constants/__tests__/configSchema.spec.js +611 -0
  224. package/src/constants/collectionTypes.ts +2 -0
  225. package/src/constants/collectionViews.js +2 -0
  226. package/src/constants/commitProps.ts +2 -0
  227. package/src/constants/configSchema.js +441 -0
  228. package/src/constants/fieldInference.tsx +78 -0
  229. package/src/constants/publishModes.ts +22 -0
  230. package/src/constants/validationErrorTypes.js +6 -0
  231. package/src/formats/__tests__/formats.spec.js +87 -0
  232. package/src/formats/__tests__/frontmatter.spec.js +429 -0
  233. package/src/formats/__tests__/toml.spec.js +9 -0
  234. package/src/formats/__tests__/yaml.spec.js +162 -0
  235. package/src/formats/formats.ts +97 -0
  236. package/src/formats/frontmatter.ts +150 -0
  237. package/src/formats/helpers.ts +14 -0
  238. package/src/formats/json.ts +9 -0
  239. package/src/formats/toml.ts +33 -0
  240. package/src/formats/yaml.ts +58 -0
  241. package/src/index.js +8 -0
  242. package/src/integrations/index.js +35 -0
  243. package/src/integrations/providers/algolia/implementation.js +176 -0
  244. package/src/integrations/providers/assetStore/implementation.js +148 -0
  245. package/src/lib/__tests__/formatters.spec.js +751 -0
  246. package/src/lib/__tests__/i18n.spec.js +792 -0
  247. package/src/lib/__tests__/phrases.spec.js +119 -0
  248. package/src/lib/__tests__/registry.spec.js +261 -0
  249. package/src/lib/__tests__/serializeEntryValues.spec.js +22 -0
  250. package/src/lib/__tests__/urlHelper.spec.js +138 -0
  251. package/src/lib/consoleError.js +7 -0
  252. package/src/lib/formatters.ts +286 -0
  253. package/src/lib/i18n.ts +454 -0
  254. package/src/lib/phrases.js +8 -0
  255. package/src/lib/polyfill.js +9 -0
  256. package/src/lib/registry.js +312 -0
  257. package/src/lib/serializeEntryValues.js +75 -0
  258. package/src/lib/stega.ts +145 -0
  259. package/src/lib/textHelper.js +11 -0
  260. package/src/lib/urlHelper.ts +128 -0
  261. package/src/mediaLibrary.ts +51 -0
  262. package/src/reducers/__tests__/auth.spec.ts +38 -0
  263. package/src/reducers/__tests__/collections.spec.js +610 -0
  264. package/src/reducers/__tests__/config.spec.js +38 -0
  265. package/src/reducers/__tests__/entries.spec.js +694 -0
  266. package/src/reducers/__tests__/entryDraft.spec.js +297 -0
  267. package/src/reducers/__tests__/globalUI.js +43 -0
  268. package/src/reducers/__tests__/integrations.spec.ts +76 -0
  269. package/src/reducers/__tests__/mediaLibrary.spec.js +154 -0
  270. package/src/reducers/__tests__/medias.spec.ts +49 -0
  271. package/src/reducers/auth.ts +46 -0
  272. package/src/reducers/collections.ts +535 -0
  273. package/src/reducers/combinedReducer.ts +11 -0
  274. package/src/reducers/config.ts +38 -0
  275. package/src/reducers/cursors.js +36 -0
  276. package/src/reducers/deploys.ts +52 -0
  277. package/src/reducers/editorialWorkflow.ts +163 -0
  278. package/src/reducers/entries.ts +819 -0
  279. package/src/reducers/entryDraft.js +260 -0
  280. package/src/reducers/globalUI.ts +45 -0
  281. package/src/reducers/index.ts +82 -0
  282. package/src/reducers/integrations.ts +59 -0
  283. package/src/reducers/mediaLibrary.ts +296 -0
  284. package/src/reducers/medias.ts +66 -0
  285. package/src/reducers/notifications.ts +52 -0
  286. package/src/reducers/search.ts +111 -0
  287. package/src/reducers/status.ts +40 -0
  288. package/src/redux/index.ts +18 -0
  289. package/src/redux/middleware/waitUntilAction.ts +64 -0
  290. package/src/routing/__tests__/history.spec.ts +49 -0
  291. package/src/routing/history.ts +17 -0
  292. package/src/types/diacritics.d.ts +1 -0
  293. package/src/types/global.d.ts +8 -0
  294. package/src/types/immutable.ts +49 -0
  295. package/src/types/redux.ts +827 -0
  296. package/src/types/tomlify-j0.4.d.ts +13 -0
  297. package/src/valueObjects/AssetProxy.ts +48 -0
  298. package/src/valueObjects/EditorComponent.js +38 -0
  299. package/src/valueObjects/Entry.ts +63 -0
@@ -0,0 +1,119 @@
1
+ import { getPhrases } from '../phrases';
2
+
3
+ jest.mock('../registry');
4
+
5
+ describe('defaultPhrases', () => {
6
+ it('should merge en locale with given locale', () => {
7
+ const { getLocale } = require('../registry');
8
+
9
+ const locales = {
10
+ en: {
11
+ app: {
12
+ header: {
13
+ content: 'Contents',
14
+ workflow: 'Workflow',
15
+ media: 'Media',
16
+ quickAdd: 'Quick add',
17
+ },
18
+ app: {
19
+ errorHeader: 'Error loading the CMS configuration',
20
+ configErrors: 'Config Errors',
21
+ checkConfigYml: 'Check your config.yml file.',
22
+ loadingConfig: 'Loading configuration...',
23
+ waitingBackend: 'Waiting for backend...',
24
+ },
25
+ notFoundPage: {
26
+ header: 'Not Found',
27
+ },
28
+ },
29
+ collection: {
30
+ sidebar: {
31
+ collections: 'Collections',
32
+ searchAll: 'Search all',
33
+ },
34
+ collectionTop: {
35
+ viewAs: 'View as',
36
+ newButton: 'New %{collectionLabel}',
37
+ },
38
+ entries: {
39
+ loadingEntries: 'Loading Entries',
40
+ cachingEntries: 'Caching Entries',
41
+ longerLoading: 'This might take several minutes',
42
+ },
43
+ },
44
+ },
45
+ de: {
46
+ app: {
47
+ header: {
48
+ content: 'Inhalt',
49
+ },
50
+ },
51
+ },
52
+ };
53
+
54
+ getLocale.mockImplementation(locale => locales[locale]);
55
+
56
+ expect(getPhrases('de')).toEqual({
57
+ app: {
58
+ header: {
59
+ content: 'Inhalt',
60
+ workflow: 'Workflow',
61
+ media: 'Media',
62
+ quickAdd: 'Quick add',
63
+ },
64
+ app: {
65
+ errorHeader: 'Error loading the CMS configuration',
66
+ configErrors: 'Config Errors',
67
+ checkConfigYml: 'Check your config.yml file.',
68
+ loadingConfig: 'Loading configuration...',
69
+ waitingBackend: 'Waiting for backend...',
70
+ },
71
+ notFoundPage: {
72
+ header: 'Not Found',
73
+ },
74
+ },
75
+ collection: {
76
+ sidebar: {
77
+ collections: 'Collections',
78
+ searchAll: 'Search all',
79
+ },
80
+ collectionTop: {
81
+ viewAs: 'View as',
82
+ newButton: 'New %{collectionLabel}',
83
+ },
84
+ entries: {
85
+ loadingEntries: 'Loading Entries',
86
+ cachingEntries: 'Caching Entries',
87
+ longerLoading: 'This might take several minutes',
88
+ },
89
+ },
90
+ });
91
+ });
92
+
93
+ it('should not mutate default phrases', () => {
94
+ const { getLocale } = require('../registry');
95
+
96
+ const locales = {
97
+ en: {
98
+ app: {
99
+ header: {
100
+ content: 'Contents',
101
+ },
102
+ },
103
+ },
104
+ de: {
105
+ app: {
106
+ header: {
107
+ content: 'Inhalt',
108
+ },
109
+ },
110
+ },
111
+ };
112
+
113
+ getLocale.mockImplementation(locale => locales[locale]);
114
+
115
+ const result = getPhrases('de');
116
+
117
+ expect(result === locales['en']).toBe(false);
118
+ });
119
+ });
@@ -0,0 +1,261 @@
1
+ import { fromJS } from 'immutable';
2
+
3
+ jest.spyOn(console, 'error').mockImplementation(() => {});
4
+
5
+ describe('registry', () => {
6
+ beforeEach(() => {
7
+ jest.clearAllMocks();
8
+ jest.resetModules();
9
+ });
10
+
11
+ describe('registerLocale', () => {
12
+ it('should log error when name is empty', () => {
13
+ const { registerLocale } = require('../registry');
14
+
15
+ registerLocale();
16
+ expect(console.error).toHaveBeenCalledTimes(1);
17
+ expect(console.error).toHaveBeenCalledWith(
18
+ "Locale parameters invalid. example: CMS.registerLocale('locale', phrases)",
19
+ );
20
+ });
21
+
22
+ it('should log error when phrases are undefined', () => {
23
+ const { registerLocale } = require('../registry');
24
+
25
+ registerLocale('fr');
26
+ expect(console.error).toHaveBeenCalledTimes(1);
27
+ expect(console.error).toHaveBeenCalledWith(
28
+ "Locale parameters invalid. example: CMS.registerLocale('locale', phrases)",
29
+ );
30
+ });
31
+
32
+ it('should register locale', () => {
33
+ const { registerLocale, getLocale } = require('../registry');
34
+
35
+ const phrases = {
36
+ app: {
37
+ header: {
38
+ content: 'Inhalt',
39
+ },
40
+ },
41
+ };
42
+
43
+ registerLocale('de', phrases);
44
+
45
+ expect(getLocale('de')).toBe(phrases);
46
+ });
47
+ });
48
+
49
+ describe('registerCustomFormat', () => {
50
+ it('can register a custom format', () => {
51
+ const { getCustomFormats, registerCustomFormat } = require('../registry');
52
+
53
+ expect(Object.keys(getCustomFormats())).not.toContain('querystring');
54
+
55
+ registerCustomFormat('querystring', 'qs', {
56
+ fromFile: content => Object.fromEntries(new URLSearchParams(content)),
57
+ toFile: obj => new URLSearchParams(obj).toString(),
58
+ });
59
+
60
+ expect(Object.keys(getCustomFormats())).toContain('querystring');
61
+ });
62
+ });
63
+
64
+ describe('eventHandlers', () => {
65
+ const events = [
66
+ 'prePublish',
67
+ 'postPublish',
68
+ 'preUnpublish',
69
+ 'postUnpublish',
70
+ 'preSave',
71
+ 'postSave',
72
+ ];
73
+
74
+ describe('registerEventListener', () => {
75
+ it('should throw error on invalid event', () => {
76
+ const { registerEventListener } = require('../registry');
77
+
78
+ expect(() => registerEventListener({ name: 'unknown' })).toThrow(
79
+ new Error("Invalid event name 'unknown'"),
80
+ );
81
+ });
82
+
83
+ events.forEach(name => {
84
+ it(`should register '${name}' event`, () => {
85
+ const { registerEventListener, getEventListeners } = require('../registry');
86
+
87
+ const handler = jest.fn();
88
+ registerEventListener({ name, handler });
89
+
90
+ expect(getEventListeners(name)).toEqual([{ handler, options: {} }]);
91
+ });
92
+ });
93
+ });
94
+
95
+ describe('removeEventListener', () => {
96
+ it('should throw error on invalid event', () => {
97
+ const { removeEventListener } = require('../registry');
98
+
99
+ expect(() => removeEventListener({ name: 'unknown' })).toThrow(
100
+ new Error("Invalid event name 'unknown'"),
101
+ );
102
+ });
103
+
104
+ events.forEach(name => {
105
+ it(`should remove '${name}' event by handler`, () => {
106
+ const {
107
+ registerEventListener,
108
+ getEventListeners,
109
+ removeEventListener,
110
+ } = require('../registry');
111
+
112
+ const handler1 = jest.fn();
113
+ const handler2 = jest.fn();
114
+ registerEventListener({ name, handler: handler1 });
115
+ registerEventListener({ name, handler: handler2 });
116
+
117
+ expect(getEventListeners(name)).toHaveLength(2);
118
+
119
+ removeEventListener({ name, handler: handler1 });
120
+
121
+ expect(getEventListeners(name)).toEqual([{ handler: handler2, options: {} }]);
122
+ });
123
+ });
124
+
125
+ events.forEach(name => {
126
+ it(`should remove '${name}' event by name`, () => {
127
+ const {
128
+ registerEventListener,
129
+ getEventListeners,
130
+ removeEventListener,
131
+ } = require('../registry');
132
+
133
+ const handler1 = jest.fn();
134
+ const handler2 = jest.fn();
135
+ registerEventListener({ name, handler: handler1 });
136
+ registerEventListener({ name, handler: handler2 });
137
+
138
+ expect(getEventListeners(name)).toHaveLength(2);
139
+
140
+ removeEventListener({ name });
141
+
142
+ expect(getEventListeners(name)).toHaveLength(0);
143
+ });
144
+ });
145
+ });
146
+
147
+ describe('invokeEvent', () => {
148
+ it('should throw error on invalid event', async () => {
149
+ const { invokeEvent } = require('../registry');
150
+
151
+ await expect(invokeEvent({ name: 'unknown', data: {} })).rejects.toThrow(
152
+ new Error("Invalid event name 'unknown'"),
153
+ );
154
+ });
155
+
156
+ events.forEach(name => {
157
+ it(`should invoke '${name}' event with data`, async () => {
158
+ const { registerEventListener, invokeEvent } = require('../registry');
159
+
160
+ const options = { hello: 'world' };
161
+ const handler = jest.fn();
162
+
163
+ registerEventListener({ name, handler }, options);
164
+
165
+ const data = { entry: fromJS({ data: {} }) };
166
+ await invokeEvent({ name, data });
167
+
168
+ expect(handler).toHaveBeenCalledTimes(1);
169
+ expect(handler).toHaveBeenCalledWith(data, options);
170
+ });
171
+
172
+ it(`should invoke multiple handlers on '${name}`, async () => {
173
+ const { registerEventListener, invokeEvent } = require('../registry');
174
+
175
+ const options1 = { hello: 'test1' };
176
+ const options2 = { hello: 'test2' };
177
+ const handler = jest.fn(({ entry }) => entry.get('data'));
178
+
179
+ registerEventListener({ name, handler }, options1);
180
+ registerEventListener({ name, handler }, options2);
181
+
182
+ const data = { entry: fromJS({ data: {} }) };
183
+ await invokeEvent({ name, data });
184
+
185
+ expect(handler).toHaveBeenCalledTimes(2);
186
+ expect(handler).toHaveBeenLastCalledWith(data, options2);
187
+ });
188
+
189
+ it(`should throw error when '${name}' handler throws error`, async () => {
190
+ const { registerEventListener, invokeEvent } = require('../registry');
191
+
192
+ const handler = jest.fn(() => {
193
+ throw new Error('handler failed!');
194
+ });
195
+
196
+ registerEventListener({ name, handler });
197
+ const data = { entry: fromJS({ data: {} }) };
198
+
199
+ await expect(invokeEvent({ name, data })).rejects.toThrow('handler failed!');
200
+ });
201
+ });
202
+
203
+ it(`should return an updated entry's DataMap`, async () => {
204
+ const { registerEventListener, invokeEvent } = require('../registry');
205
+
206
+ const event = 'preSave';
207
+ const options = { hello: 'world' };
208
+ const handler1 = jest.fn(({ entry }) => {
209
+ const data = entry.get('data');
210
+ return data.set('a', 'test1');
211
+ });
212
+ const handler2 = jest.fn(({ entry }) => {
213
+ const data = entry.get('data');
214
+ return data.set('c', 'test2');
215
+ });
216
+
217
+ registerEventListener({ name: event, handler: handler1 }, options);
218
+ registerEventListener({ name: event, handler: handler2 }, options);
219
+
220
+ const data = {
221
+ entry: fromJS({ data: { a: 'foo', b: 'bar' } }),
222
+ };
223
+
224
+ const dataAfterFirstHandlerExecution = {
225
+ entry: fromJS({ data: { a: 'test1', b: 'bar' } }),
226
+ };
227
+ const dataAfterSecondHandlerExecution = {
228
+ entry: fromJS({ data: { a: 'test1', b: 'bar', c: 'test2' } }),
229
+ };
230
+
231
+ const result = await invokeEvent({ name: event, data });
232
+
233
+ expect(handler1).toHaveBeenCalledWith(data, options);
234
+ expect(handler2).toHaveBeenCalledWith(dataAfterFirstHandlerExecution, options);
235
+
236
+ expect(result).toEqual(dataAfterSecondHandlerExecution.entry.get('data'));
237
+ });
238
+
239
+ it('should allow multiple events to not return a value', async () => {
240
+ const { registerEventListener, invokeEvent } = require('../registry');
241
+
242
+ const event = 'prePublish';
243
+ const options = { hello: 'world' };
244
+ const handler1 = jest.fn();
245
+ const handler2 = jest.fn();
246
+
247
+ registerEventListener({ name: event, handler: handler1 }, options);
248
+ registerEventListener({ name: event, handler: handler2 }, options);
249
+
250
+ const data = {
251
+ entry: fromJS({ data: { a: 'foo', b: 'bar' } }),
252
+ };
253
+ const result = await invokeEvent({ name: event, data });
254
+
255
+ expect(handler1).toHaveBeenCalledWith(data, options);
256
+ expect(handler2).toHaveBeenCalledWith(data, options);
257
+ expect(result).toEqual(data.entry.get('data'));
258
+ });
259
+ });
260
+ });
261
+ });
@@ -0,0 +1,22 @@
1
+ import { fromJS } from 'immutable';
2
+
3
+ import { serializeValues, deserializeValues } from '../serializeEntryValues';
4
+
5
+ const values = fromJS({ title: 'New Post', unknown: 'Unknown Field' });
6
+ const fields = fromJS([{ name: 'title', widget: 'string' }]);
7
+
8
+ describe('serializeValues', () => {
9
+ it('should retain unknown fields', () => {
10
+ expect(serializeValues(values, fields)).toEqual(
11
+ fromJS({ title: 'New Post', unknown: 'Unknown Field' }),
12
+ );
13
+ });
14
+ });
15
+
16
+ describe('deserializeValues', () => {
17
+ it('should retain unknown fields', () => {
18
+ expect(deserializeValues(values, fields)).toEqual(
19
+ fromJS({ title: 'New Post', unknown: 'Unknown Field' }),
20
+ );
21
+ });
22
+ });
@@ -0,0 +1,138 @@
1
+ import { sanitizeURI, sanitizeSlug, sanitizeChar } from '../urlHelper';
2
+
3
+ describe('sanitizeURI', () => {
4
+ // `sanitizeURI` tests from RFC 3987
5
+ it('should keep valid URI chars (letters digits _ - . ~)', () => {
6
+ expect(sanitizeURI('This, that-one_or.the~other 123!')).toEqual('Thisthat-one_or.the~other123');
7
+ });
8
+
9
+ it('should not remove accents', () => {
10
+ expect(sanitizeURI('ěščřžý')).toEqual('ěščřžý');
11
+ });
12
+
13
+ it('should keep valid non-latin chars (ucschars in RFC 3987)', () => {
14
+ expect(sanitizeURI('日本語のタイトル')).toEqual('日本語のタイトル');
15
+ });
16
+
17
+ it('should not keep valid non-latin chars (ucschars in RFC 3987) if set to ASCII mode', () => {
18
+ expect(sanitizeURI('ěščřžý日本語のタイトル', { encoding: 'ascii' })).toEqual('');
19
+ });
20
+
21
+ it('should not normalize Unicode strings', () => {
22
+ expect(sanitizeURI('\u017F\u0323\u0307')).toEqual('\u017F\u0323\u0307');
23
+ expect(sanitizeURI('\u017F\u0323\u0307')).not.toEqual('\u1E9B\u0323');
24
+ });
25
+
26
+ it('should allow a custom replacement character', () => {
27
+ expect(sanitizeURI('duck\\goose.elephant', { replacement: '-' })).toEqual(
28
+ 'duck-goose.elephant',
29
+ );
30
+ });
31
+
32
+ it('should not allow an improper replacement character', () => {
33
+ expect(() => {
34
+ sanitizeURI('I! like! dollars!', { replacement: '$' });
35
+ }).toThrow();
36
+ });
37
+
38
+ it('should not actually URI-encode the characters', () => {
39
+ expect(sanitizeURI('🎉')).toEqual('🎉');
40
+ expect(sanitizeURI('🎉')).not.toEqual('%F0%9F%8E%89');
41
+ });
42
+ });
43
+
44
+ const slugConfig = {
45
+ encoding: 'unicode',
46
+ clean_accents: false,
47
+ sanitize_replacement: '-',
48
+ };
49
+
50
+ describe('sanitizeSlug', () => {
51
+ it('throws an error for non-strings', () => {
52
+ expect(() => sanitizeSlug({})).toThrowError('The input slug must be a string.');
53
+ expect(() => sanitizeSlug([])).toThrowError('The input slug must be a string.');
54
+ expect(() => sanitizeSlug(false)).toThrowError('The input slug must be a string.');
55
+ expect(() => sanitizeSlug(null)).toThrowError('The input slug must be a string.');
56
+ expect(() => sanitizeSlug(11234)).toThrowError('The input slug must be a string.');
57
+ expect(() => sanitizeSlug(undefined)).toThrowError('The input slug must be a string.');
58
+ expect(() => sanitizeSlug(() => {})).toThrowError('The input slug must be a string.');
59
+ });
60
+
61
+ it('throws an error for non-string replacements', () => {
62
+ expect(() => sanitizeSlug('test', { sanitize_replacement: {} })).toThrowError(
63
+ '`options.replacement` must be a string.',
64
+ );
65
+ expect(() => sanitizeSlug('test', { sanitize_replacement: [] })).toThrowError(
66
+ '`options.replacement` must be a string.',
67
+ );
68
+ expect(() => sanitizeSlug('test', { sanitize_replacement: false })).toThrowError(
69
+ '`options.replacement` must be a string.',
70
+ );
71
+ expect(() => sanitizeSlug('test', { sanitize_replacement: null })).toThrowError(
72
+ '`options.replacement` must be a string.',
73
+ );
74
+ expect(() => sanitizeSlug('test', { sanitize_replacement: 11232 })).toThrowError(
75
+ '`options.replacement` must be a string.',
76
+ );
77
+ // do not test undefined for this variant since a default is set in the constructor.
78
+ //expect(() => sanitizeSlug('test', { sanitize_replacement: undefined })).toThrowError("`options.replacement` must be a string.");
79
+ expect(() => sanitizeSlug('test', { sanitize_replacement: () => {} })).toThrowError(
80
+ '`options.replacement` must be a string.',
81
+ );
82
+ });
83
+
84
+ it('should keep valid URI chars (letters digits _ - . ~)', () => {
85
+ expect(sanitizeSlug('This, that-one_or.the~other 123!', slugConfig)).toEqual(
86
+ 'This-that-one_or.the~other-123',
87
+ );
88
+ });
89
+
90
+ it('should remove accents with `clean_accents` set', () => {
91
+ expect(sanitizeSlug('ěščřžý', { ...slugConfig, clean_accents: true })).toEqual('escrzy');
92
+ });
93
+
94
+ it('should remove non-latin chars in "ascii" mode', () => {
95
+ expect(sanitizeSlug('ěščřžý日本語のタイトル', { ...slugConfig, encoding: 'ascii' })).toEqual(
96
+ '',
97
+ );
98
+ });
99
+
100
+ it('should clean accents and strip non-latin chars in "ascii" mode with `clean_accents` set', () => {
101
+ expect(
102
+ sanitizeSlug('ěščřžý日本語のタイトル', {
103
+ ...slugConfig,
104
+ encoding: 'ascii',
105
+ clean_accents: true,
106
+ }),
107
+ ).toEqual('escrzy');
108
+ });
109
+
110
+ it('removes double replacements', () => {
111
+ expect(sanitizeSlug('test--test', slugConfig)).toEqual('test-test');
112
+ expect(sanitizeSlug('test test', slugConfig)).toEqual('test-test');
113
+ });
114
+
115
+ it('removes trailing replacements', () => {
116
+ expect(sanitizeSlug('test test ', slugConfig)).toEqual('test-test');
117
+ });
118
+
119
+ it('removes leading replacements', () => {
120
+ expect(sanitizeSlug('"test" test', slugConfig)).toEqual('test-test');
121
+ });
122
+
123
+ it('uses alternate replacements', () => {
124
+ expect(sanitizeSlug('test test ', { ...slugConfig, sanitize_replacement: '_' })).toEqual(
125
+ 'test_test',
126
+ );
127
+ });
128
+ });
129
+
130
+ describe('sanitizeChar', () => {
131
+ it('should sanitize whitespace with default replacement', () => {
132
+ expect(sanitizeChar(' ', slugConfig)).toBe('-');
133
+ });
134
+
135
+ it('should sanitize whitespace with custom replacement', () => {
136
+ expect(sanitizeChar(' ', { ...slugConfig, sanitize_replacement: '_' })).toBe('_');
137
+ });
138
+ });
@@ -0,0 +1,7 @@
1
+ export default function consoleError(title, description) {
2
+ console.error(
3
+ `%c ⛔ ${title}\n` + `%c${description}\n\n`,
4
+ 'color: black; font-weight: bold; font-size: 16px; line-height: 50px;',
5
+ 'color: black;',
6
+ );
7
+ }