@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,51 @@
1
+ /**
2
+ * This module is currently concerned only with external media libraries
3
+ * registered via `registerMediaLibrary`.
4
+ */
5
+ import once from 'lodash/once';
6
+
7
+ import { getMediaLibrary } from './lib/registry';
8
+ import { store } from './redux';
9
+ import { configFailed } from './actions/config';
10
+ import { createMediaLibrary, insertMedia } from './actions/mediaLibrary';
11
+
12
+ import type { MediaLibraryInstance } from './types/redux';
13
+
14
+ type MediaLibraryOptions = {};
15
+
16
+ interface MediaLibrary {
17
+ init: (args: {
18
+ options: MediaLibraryOptions;
19
+ handleInsert: (url: string) => void;
20
+ }) => MediaLibraryInstance;
21
+ }
22
+
23
+ function handleInsert(url: string) {
24
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
25
+ // @ts-ignore
26
+ return store.dispatch(insertMedia(url, undefined));
27
+ }
28
+
29
+ const initializeMediaLibrary = once(async function initializeMediaLibrary(name, options) {
30
+ const lib = getMediaLibrary(name) as unknown as MediaLibrary | undefined;
31
+ if (!lib) {
32
+ const err = new Error(
33
+ `Missing external media library '${name}'. Please use 'registerMediaLibrary' to register it.`,
34
+ );
35
+ store.dispatch(configFailed(err));
36
+ } else {
37
+ const instance = await lib.init({ options, handleInsert });
38
+ store.dispatch(createMediaLibrary(instance));
39
+ }
40
+ });
41
+
42
+ store.subscribe(() => {
43
+ const state = store.getState();
44
+ if (state) {
45
+ const mediaLibraryName = state.config.media_library?.name;
46
+ if (mediaLibraryName && !state.mediaLibrary.get('externalLibrary')) {
47
+ const mediaLibraryConfig = state.config.media_library;
48
+ initializeMediaLibrary(mediaLibraryName, mediaLibraryConfig);
49
+ }
50
+ }
51
+ });
@@ -0,0 +1,38 @@
1
+ import { authenticating, authenticate, authError, logout } from '../../actions/auth';
2
+ import auth, { defaultState } from '../auth';
3
+
4
+ describe('auth', () => {
5
+ it('should handle an empty state', () => {
6
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
7
+ // @ts-ignore auth reducer doesn't accept empty action
8
+ expect(auth(undefined, {})).toEqual(defaultState);
9
+ });
10
+
11
+ it('should handle an authentication request', () => {
12
+ expect(auth(undefined, authenticating())).toEqual({
13
+ ...defaultState,
14
+ isFetching: true,
15
+ });
16
+ });
17
+
18
+ it('should handle authentication', () => {
19
+ const user = { name: 'joe', token: 'token' };
20
+ expect(auth(undefined, authenticate(user))).toEqual({
21
+ ...defaultState,
22
+ user,
23
+ });
24
+ });
25
+
26
+ it('should handle an authentication error', () => {
27
+ expect(auth(undefined, authError(new Error('Bad credentials')))).toEqual({
28
+ ...defaultState,
29
+ error: 'Error: Bad credentials',
30
+ });
31
+ });
32
+
33
+ it('should handle logout', () => {
34
+ const user = { name: 'joe', token: 'token' };
35
+ const newState = auth({ ...defaultState, user }, logout());
36
+ expect(newState.user).toBeUndefined();
37
+ });
38
+ });
@@ -0,0 +1,610 @@
1
+ import { fromJS, Map } from 'immutable';
2
+
3
+ import { configLoaded } from '../../actions/config';
4
+ import collections, {
5
+ selectAllowDeletion,
6
+ selectEntryPath,
7
+ selectEntrySlug,
8
+ selectFieldsWithMediaFolders,
9
+ selectMediaFolders,
10
+ selectEntryCollectionTitle,
11
+ getFieldsNames,
12
+ selectField,
13
+ updateFieldByKey,
14
+ selectInferredField,
15
+ } from '../collections';
16
+ import { FILES, FOLDER } from '../../constants/collectionTypes';
17
+
18
+ describe('collections', () => {
19
+ it('should handle an empty state', () => {
20
+ expect(collections(undefined, {})).toEqual(Map());
21
+ });
22
+
23
+ it('should load the collections from the config', () => {
24
+ expect(
25
+ collections(
26
+ undefined,
27
+ configLoaded({
28
+ collections: [
29
+ {
30
+ name: 'posts',
31
+ folder: '_posts',
32
+ fields: [{ name: 'title', widget: 'string' }],
33
+ },
34
+ ],
35
+ }),
36
+ ).toJS(),
37
+ ).toEqual({
38
+ posts: {
39
+ name: 'posts',
40
+ folder: '_posts',
41
+ fields: [{ name: 'title', widget: 'string' }],
42
+ },
43
+ });
44
+ });
45
+
46
+ it('should maintain config collections order', () => {
47
+ const collectionsData = new Array(1000).fill(0).map((_, index) => ({
48
+ name: `collection_${index}`,
49
+ folder: `collection_${index}`,
50
+ fields: [{ name: 'title', widget: 'string' }],
51
+ }));
52
+
53
+ const newState = collections(
54
+ undefined,
55
+ configLoaded({
56
+ collections: collectionsData,
57
+ }),
58
+ );
59
+ const keyArray = newState.keySeq().toArray();
60
+ expect(keyArray).toEqual(collectionsData.map(({ name }) => name));
61
+ });
62
+
63
+ describe('selectAllowDeletions', () => {
64
+ it('should not allow deletions for file collections', () => {
65
+ expect(
66
+ selectAllowDeletion(
67
+ fromJS({
68
+ name: 'pages',
69
+ type: FILES,
70
+ }),
71
+ ),
72
+ ).toBe(false);
73
+ });
74
+ });
75
+
76
+ describe('selectEntryPath', () => {
77
+ it('should return path', () => {
78
+ expect(
79
+ selectEntryPath(
80
+ fromJS({
81
+ type: FOLDER,
82
+ folder: 'posts',
83
+ }),
84
+ 'dir1/dir2/slug',
85
+ ),
86
+ ).toBe('posts/dir1/dir2/slug.md');
87
+ });
88
+ });
89
+
90
+ describe('selectEntrySlug', () => {
91
+ it('should return slug', () => {
92
+ expect(
93
+ selectEntrySlug(
94
+ fromJS({
95
+ type: FOLDER,
96
+ folder: 'posts',
97
+ }),
98
+ 'posts/dir1/dir2/slug.md',
99
+ ),
100
+ ).toBe('dir1/dir2/slug');
101
+ });
102
+ });
103
+
104
+ describe('selectFieldsMediaFolders', () => {
105
+ it('should return empty array for invalid collection', () => {
106
+ expect(selectFieldsWithMediaFolders(fromJS({}))).toEqual([]);
107
+ });
108
+
109
+ it('should return configs for folder collection', () => {
110
+ expect(
111
+ selectFieldsWithMediaFolders(
112
+ fromJS({
113
+ folder: 'posts',
114
+ fields: [
115
+ {
116
+ name: 'image',
117
+ media_folder: 'image_media_folder',
118
+ },
119
+ {
120
+ name: 'body',
121
+ media_folder: 'body_media_folder',
122
+ },
123
+ {
124
+ name: 'list_1',
125
+ field: {
126
+ name: 'list_1_item',
127
+ media_folder: 'list_1_item_media_folder',
128
+ },
129
+ },
130
+ {
131
+ name: 'list_2',
132
+ fields: [
133
+ {
134
+ name: 'list_2_item',
135
+ media_folder: 'list_2_item_media_folder',
136
+ },
137
+ ],
138
+ },
139
+ {
140
+ name: 'list_3',
141
+ types: [
142
+ {
143
+ name: 'list_3_type',
144
+ media_folder: 'list_3_type_media_folder',
145
+ },
146
+ ],
147
+ },
148
+ ],
149
+ }),
150
+ ),
151
+ ).toEqual([
152
+ fromJS({
153
+ name: 'image',
154
+ media_folder: 'image_media_folder',
155
+ }),
156
+ fromJS({ name: 'body', media_folder: 'body_media_folder' }),
157
+ fromJS({ name: 'list_1_item', media_folder: 'list_1_item_media_folder' }),
158
+ fromJS({
159
+ name: 'list_2_item',
160
+ media_folder: 'list_2_item_media_folder',
161
+ }),
162
+ fromJS({
163
+ name: 'list_3_type',
164
+ media_folder: 'list_3_type_media_folder',
165
+ }),
166
+ ]);
167
+ });
168
+
169
+ it('should return configs for files collection', () => {
170
+ expect(
171
+ selectFieldsWithMediaFolders(
172
+ fromJS({
173
+ files: [
174
+ {
175
+ name: 'file1',
176
+ fields: [
177
+ {
178
+ name: 'image',
179
+ media_folder: 'image_media_folder',
180
+ },
181
+ ],
182
+ },
183
+ {
184
+ name: 'file2',
185
+ fields: [
186
+ {
187
+ name: 'body',
188
+ media_folder: 'body_media_folder',
189
+ },
190
+ ],
191
+ },
192
+ {
193
+ name: 'file3',
194
+ fields: [
195
+ {
196
+ name: 'list_1',
197
+ field: {
198
+ name: 'list_1_item',
199
+ media_folder: 'list_1_item_media_folder',
200
+ },
201
+ },
202
+ ],
203
+ },
204
+ {
205
+ name: 'file4',
206
+ fields: [
207
+ {
208
+ name: 'list_2',
209
+ fields: [
210
+ {
211
+ name: 'list_2_item',
212
+ media_folder: 'list_2_item_media_folder',
213
+ },
214
+ {
215
+ name: 'list_3',
216
+ types: [
217
+ {
218
+ name: 'list_3_type',
219
+ media_folder: 'list_3_type_media_folder',
220
+ },
221
+ ],
222
+ },
223
+ ],
224
+ },
225
+ ],
226
+ },
227
+ ],
228
+ }),
229
+ 'file4',
230
+ ),
231
+ ).toEqual([
232
+ fromJS({
233
+ name: 'list_2_item',
234
+ media_folder: 'list_2_item_media_folder',
235
+ }),
236
+ fromJS({
237
+ name: 'list_3_type',
238
+ media_folder: 'list_3_type_media_folder',
239
+ }),
240
+ ]);
241
+ });
242
+ });
243
+
244
+ describe('selectMediaFolders', () => {
245
+ const slug = {
246
+ encoding: 'unicode',
247
+ clean_accents: false,
248
+ sanitize_replacement: '-',
249
+ };
250
+
251
+ const config = { slug, media_folder: '/static/img' };
252
+ it('should return fields and collection folders', () => {
253
+ expect(
254
+ selectMediaFolders(
255
+ config,
256
+ fromJS({
257
+ folder: 'posts',
258
+ media_folder: '{{media_folder}}/general/',
259
+ fields: [
260
+ {
261
+ name: 'image',
262
+ media_folder: '{{media_folder}}/customers/',
263
+ },
264
+ {
265
+ name: 'list',
266
+ types: [{ name: 'widget', media_folder: '{{media_folder}}/widgets' }],
267
+ },
268
+ ],
269
+ }),
270
+ fromJS({ slug: 'name', path: 'src/post/post1.md', data: {} }),
271
+ ),
272
+ ).toEqual([
273
+ 'static/img/general',
274
+ 'static/img/general/customers',
275
+ 'static/img/general/widgets',
276
+ ]);
277
+ });
278
+
279
+ it('should return fields, file and collection folders', () => {
280
+ expect(
281
+ selectMediaFolders(
282
+ config,
283
+ fromJS({
284
+ media_folder: '{{media_folder}}/general/',
285
+ files: [
286
+ {
287
+ name: 'name',
288
+ file: 'src/post/post1.md',
289
+ media_folder: '{{media_folder}}/customers/',
290
+ fields: [
291
+ {
292
+ name: 'image',
293
+ media_folder: '{{media_folder}}/logos/',
294
+ },
295
+ {
296
+ name: 'list',
297
+ types: [{ name: 'widget', media_folder: '{{media_folder}}/widgets' }],
298
+ },
299
+ ],
300
+ },
301
+ ],
302
+ }),
303
+ fromJS({ slug: 'name', path: 'src/post/post1.md', data: {} }),
304
+ ),
305
+ ).toEqual([
306
+ 'static/img/general',
307
+ 'static/img/general/customers',
308
+ 'static/img/general/customers/logos',
309
+ 'static/img/general/customers/widgets',
310
+ ]);
311
+ });
312
+ });
313
+
314
+ describe('getFieldsNames', () => {
315
+ it('should get flat fields names', () => {
316
+ const collection = fromJS({
317
+ fields: [{ name: 'en' }, { name: 'es' }],
318
+ });
319
+ expect(getFieldsNames(collection.get('fields').toArray())).toEqual(['en', 'es']);
320
+ });
321
+
322
+ it('should get nested fields names', () => {
323
+ const collection = fromJS({
324
+ fields: [
325
+ { name: 'en', fields: [{ name: 'title' }, { name: 'body' }] },
326
+ { name: 'es', fields: [{ name: 'title' }, { name: 'body' }] },
327
+ { name: 'it', field: { name: 'title', fields: [{ name: 'subTitle' }] } },
328
+ {
329
+ name: 'fr',
330
+ fields: [{ name: 'title', widget: 'list', types: [{ name: 'variableType' }] }],
331
+ },
332
+ ],
333
+ });
334
+ expect(getFieldsNames(collection.get('fields').toArray())).toEqual([
335
+ 'en',
336
+ 'es',
337
+ 'it',
338
+ 'fr',
339
+ 'en.title',
340
+ 'en.body',
341
+ 'es.title',
342
+ 'es.body',
343
+ 'it.title',
344
+ 'it.title.subTitle',
345
+ 'fr.title',
346
+ 'fr.title.variableType',
347
+ ]);
348
+ });
349
+ });
350
+
351
+ describe('selectField', () => {
352
+ it('should return top field by key', () => {
353
+ const collection = fromJS({
354
+ fields: [{ name: 'en' }, { name: 'es' }],
355
+ });
356
+ expect(selectField(collection, 'en')).toBe(collection.get('fields').get(0));
357
+ });
358
+
359
+ it('should return nested field by key', () => {
360
+ const collection = fromJS({
361
+ fields: [
362
+ { name: 'en', fields: [{ name: 'title' }, { name: 'body' }] },
363
+ { name: 'es', fields: [{ name: 'title' }, { name: 'body' }] },
364
+ { name: 'it', field: { name: 'title', fields: [{ name: 'subTitle' }] } },
365
+ {
366
+ name: 'fr',
367
+ fields: [{ name: 'title', widget: 'list', types: [{ name: 'variableType' }] }],
368
+ },
369
+ ],
370
+ });
371
+
372
+ expect(selectField(collection, 'en.title')).toBe(
373
+ collection.get('fields').get(0).get('fields').get(0),
374
+ );
375
+
376
+ expect(selectField(collection, 'it.title.subTitle')).toBe(
377
+ collection.get('fields').get(2).get('field').get('fields').get(0),
378
+ );
379
+
380
+ expect(selectField(collection, 'fr.title.variableType')).toBe(
381
+ collection.get('fields').get(3).get('fields').get(0).get('types').get(0),
382
+ );
383
+ });
384
+ });
385
+
386
+ describe('selectEntryCollectionTitle', () => {
387
+ const entry = fromJS({
388
+ data: { title: 'entry title', otherField: 'other field', emptyLinkTitle: '' },
389
+ });
390
+
391
+ it('should return the entry title if set', () => {
392
+ const collection = fromJS({
393
+ fields: [{ name: 'title' }, { name: 'otherField' }],
394
+ });
395
+
396
+ expect(selectEntryCollectionTitle(collection, entry)).toEqual('entry title');
397
+ });
398
+
399
+ it('should return some other inferreable title if set', () => {
400
+ const headlineEntry = fromJS({
401
+ data: { headline: 'entry headline', otherField: 'other field' },
402
+ });
403
+ const collection = fromJS({
404
+ fields: [{ name: 'headline' }, { name: 'otherField' }],
405
+ });
406
+
407
+ expect(selectEntryCollectionTitle(collection, headlineEntry)).toEqual('entry headline');
408
+ });
409
+
410
+ it('should return the identifier_field content if defined in collection', () => {
411
+ const collection = fromJS({
412
+ identifier_field: 'otherField',
413
+ fields: [{ name: 'title' }, { name: 'otherField' }],
414
+ });
415
+
416
+ expect(selectEntryCollectionTitle(collection, entry)).toEqual('other field');
417
+ });
418
+
419
+ it('should return the entry title if identifier_field content is not defined in collection', () => {
420
+ const collection = fromJS({
421
+ identifier_field: 'missingLinkTitle',
422
+ fields: [{ name: 'title' }, { name: 'otherField' }],
423
+ });
424
+
425
+ expect(selectEntryCollectionTitle(collection, entry)).toEqual('entry title');
426
+ });
427
+
428
+ it('should return the entry title if identifier_field content is empty', () => {
429
+ const collection = fromJS({
430
+ identifier_field: 'emptyLinkTitle',
431
+ fields: [{ name: 'title' }, { name: 'otherField' }, { name: 'emptyLinkTitle' }],
432
+ });
433
+
434
+ expect(selectEntryCollectionTitle(collection, entry)).toEqual('entry title');
435
+ });
436
+
437
+ it('should return the entry label of a file collection', () => {
438
+ const labelEntry = fromJS({
439
+ slug: 'entry-name',
440
+ data: { title: 'entry title', otherField: 'other field' },
441
+ });
442
+ const collection = fromJS({
443
+ type: FILES,
444
+ files: [
445
+ {
446
+ name: 'entry-name',
447
+ label: 'entry label',
448
+ },
449
+ ],
450
+ });
451
+
452
+ expect(selectEntryCollectionTitle(collection, labelEntry)).toEqual('entry label');
453
+ });
454
+
455
+ it('should return a formatted summary before everything else', () => {
456
+ const collection = fromJS({
457
+ summary: '{{title}} -- {{otherField}}',
458
+ identifier_field: 'otherField',
459
+ fields: [{ name: 'title' }, { name: 'otherField' }],
460
+ });
461
+
462
+ expect(selectEntryCollectionTitle(collection, entry)).toEqual('entry title -- other field');
463
+ });
464
+ });
465
+
466
+ describe('updateFieldByKey', () => {
467
+ it('should update field by key', () => {
468
+ const collection = fromJS({
469
+ fields: [
470
+ { name: 'title' },
471
+ { name: 'image' },
472
+ {
473
+ name: 'object',
474
+ fields: [{ name: 'title' }, { name: 'gallery', fields: [{ name: 'image' }] }],
475
+ },
476
+ { name: 'list', field: { name: 'image' } },
477
+ { name: 'body' },
478
+ { name: 'widgetList', types: [{ name: 'widget' }] },
479
+ ],
480
+ });
481
+
482
+ function updater(field) {
483
+ return field.set('default', 'default');
484
+ }
485
+
486
+ expect(updateFieldByKey(collection, 'non-existent', updater)).toBe(collection);
487
+ expect(updateFieldByKey(collection, 'title', updater)).toEqual(
488
+ fromJS({
489
+ fields: [
490
+ { name: 'title', default: 'default' },
491
+ { name: 'image' },
492
+ {
493
+ name: 'object',
494
+ fields: [{ name: 'title' }, { name: 'gallery', fields: [{ name: 'image' }] }],
495
+ },
496
+ { name: 'list', field: { name: 'image' } },
497
+ { name: 'body' },
498
+ { name: 'widgetList', types: [{ name: 'widget' }] },
499
+ ],
500
+ }),
501
+ );
502
+ expect(updateFieldByKey(collection, 'object.title', updater)).toEqual(
503
+ fromJS({
504
+ fields: [
505
+ { name: 'title' },
506
+ { name: 'image' },
507
+ {
508
+ name: 'object',
509
+ fields: [
510
+ { name: 'title', default: 'default' },
511
+ { name: 'gallery', fields: [{ name: 'image' }] },
512
+ ],
513
+ },
514
+ { name: 'list', field: { name: 'image' } },
515
+ { name: 'body' },
516
+ { name: 'widgetList', types: [{ name: 'widget' }] },
517
+ ],
518
+ }),
519
+ );
520
+
521
+ expect(updateFieldByKey(collection, 'object.gallery.image', updater)).toEqual(
522
+ fromJS({
523
+ fields: [
524
+ { name: 'title' },
525
+ { name: 'image' },
526
+ {
527
+ name: 'object',
528
+ fields: [
529
+ { name: 'title' },
530
+ { name: 'gallery', fields: [{ name: 'image', default: 'default' }] },
531
+ ],
532
+ },
533
+ { name: 'list', field: { name: 'image' } },
534
+ { name: 'body' },
535
+ { name: 'widgetList', types: [{ name: 'widget' }] },
536
+ ],
537
+ }),
538
+ );
539
+ expect(updateFieldByKey(collection, 'list.image', updater)).toEqual(
540
+ fromJS({
541
+ fields: [
542
+ { name: 'title' },
543
+ { name: 'image' },
544
+ {
545
+ name: 'object',
546
+ fields: [{ name: 'title' }, { name: 'gallery', fields: [{ name: 'image' }] }],
547
+ },
548
+ { name: 'list', field: { name: 'image', default: 'default' } },
549
+ { name: 'body' },
550
+ { name: 'widgetList', types: [{ name: 'widget' }] },
551
+ ],
552
+ }),
553
+ );
554
+
555
+ expect(updateFieldByKey(collection, 'widgetList.widget', updater)).toEqual(
556
+ fromJS({
557
+ fields: [
558
+ { name: 'title' },
559
+ { name: 'image' },
560
+ {
561
+ name: 'object',
562
+ fields: [{ name: 'title' }, { name: 'gallery', fields: [{ name: 'image' }] }],
563
+ },
564
+ { name: 'list', field: { name: 'image' } },
565
+ { name: 'body' },
566
+ { name: 'widgetList', types: [{ name: 'widget', default: 'default' }] },
567
+ ],
568
+ }),
569
+ );
570
+ });
571
+ });
572
+
573
+ describe("selectInferredField(collection, 'date')", () => {
574
+ it('should return publishDate if set', () => {
575
+ const collection = fromJS({
576
+ fields: [{ name: 'title' }, { name: 'publishDate', widget: 'datetime' }],
577
+ });
578
+
579
+ expect(selectInferredField(collection, 'date')).toEqual('publishDate');
580
+ });
581
+
582
+ it('should return publish_date if set', () => {
583
+ const collection = fromJS({
584
+ fields: [{ name: 'title' }, { name: 'publish_date', widget: 'datetime' }],
585
+ });
586
+
587
+ expect(selectInferredField(collection, 'date')).toEqual('publish_date');
588
+ });
589
+
590
+ it('should return date if set', () => {
591
+ const collection = fromJS({
592
+ fields: [{ name: 'title' }, { name: 'date', widget: 'datetime' }],
593
+ });
594
+
595
+ expect(selectInferredField(collection, 'date')).toEqual('date');
596
+ });
597
+
598
+ it('should return first date field if multiple synonyms are present', () => {
599
+ const collection = fromJS({
600
+ fields: [
601
+ { name: 'title' },
602
+ { name: 'publishDate', widget: 'datetime' },
603
+ { name: 'date', widget: 'datetime' },
604
+ ],
605
+ });
606
+
607
+ expect(selectInferredField(collection, 'date')).toEqual('publishDate');
608
+ });
609
+ });
610
+ });