@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,429 @@
1
+ import {
2
+ FrontmatterInfer,
3
+ frontmatterJSON,
4
+ frontmatterTOML,
5
+ frontmatterYAML,
6
+ } from '../frontmatter';
7
+
8
+ describe('Frontmatter', () => {
9
+ describe('yaml', () => {
10
+ it('should parse YAML with --- delimiters', () => {
11
+ expect(
12
+ FrontmatterInfer.fromFile('---\ntitle: YAML\ndescription: Something longer\n---\nContent'),
13
+ ).toEqual({
14
+ title: 'YAML',
15
+ description: 'Something longer',
16
+ body: 'Content',
17
+ });
18
+ });
19
+
20
+ it('should parse YAML with --- delimiters when it is explicitly set as the format without a custom delimiter', () => {
21
+ expect(
22
+ frontmatterYAML().fromFile('---\ntitle: YAML\ndescription: Something longer\n---\nContent'),
23
+ ).toEqual({
24
+ title: 'YAML',
25
+ description: 'Something longer',
26
+ body: 'Content',
27
+ });
28
+ });
29
+
30
+ it('should parse YAML with custom delimiters when it is explicitly set as the format with a custom delimiter', () => {
31
+ expect(
32
+ frontmatterYAML('~~~').fromFile(
33
+ '~~~\ntitle: YAML\ndescription: Something longer\n~~~\nContent',
34
+ ),
35
+ ).toEqual({
36
+ title: 'YAML',
37
+ description: 'Something longer',
38
+ body: 'Content',
39
+ });
40
+ });
41
+
42
+ it('should parse YAML with custom delimiters when it is explicitly set as the format with different custom delimiters', () => {
43
+ expect(
44
+ frontmatterYAML(['~~~', '^^^']).fromFile(
45
+ '~~~\ntitle: YAML\ndescription: Something longer\n^^^\nContent',
46
+ ),
47
+ ).toEqual({
48
+ title: 'YAML',
49
+ description: 'Something longer',
50
+ body: 'Content',
51
+ });
52
+ });
53
+
54
+ it('should parse YAML with ---yaml delimiters', () => {
55
+ expect(
56
+ FrontmatterInfer.fromFile(
57
+ '---yaml\ntitle: YAML\ndescription: Something longer\n---\nContent',
58
+ ),
59
+ ).toEqual({
60
+ title: 'YAML',
61
+ description: 'Something longer',
62
+ body: 'Content',
63
+ });
64
+ });
65
+
66
+ it('should overwrite any body param in the front matter', () => {
67
+ expect(
68
+ FrontmatterInfer.fromFile('---\ntitle: The Title\nbody: Something longer\n---\nContent'),
69
+ ).toEqual({
70
+ title: 'The Title',
71
+ body: 'Content',
72
+ });
73
+ });
74
+
75
+ it('should stringify YAML with --- delimiters', () => {
76
+ expect(
77
+ FrontmatterInfer.toFile({
78
+ body: 'Some content\nOn another line',
79
+ tags: ['front matter', 'yaml'],
80
+ title: 'YAML',
81
+ }),
82
+ ).toEqual(
83
+ [
84
+ '---',
85
+ 'tags:',
86
+ ' - front matter',
87
+ ' - yaml',
88
+ 'title: YAML',
89
+ '---',
90
+ 'Some content',
91
+ 'On another line',
92
+ ].join('\n'),
93
+ );
94
+ });
95
+
96
+ it('should stringify YAML with missing body', () => {
97
+ expect(FrontmatterInfer.toFile({ tags: ['front matter', 'yaml'], title: 'YAML' })).toEqual(
98
+ ['---', 'tags:', ' - front matter', ' - yaml', 'title: YAML', '---', ''].join('\n'),
99
+ );
100
+ });
101
+
102
+ it('should stringify YAML with --- delimiters when it is explicitly set as the format without a custom delimiter', () => {
103
+ expect(
104
+ frontmatterYAML().toFile({
105
+ body: 'Some content\nOn another line',
106
+ tags: ['front matter', 'yaml'],
107
+ title: 'YAML',
108
+ }),
109
+ ).toEqual(
110
+ [
111
+ '---',
112
+ 'tags:',
113
+ ' - front matter',
114
+ ' - yaml',
115
+ 'title: YAML',
116
+ '---',
117
+ 'Some content',
118
+ 'On another line',
119
+ ].join('\n'),
120
+ );
121
+ });
122
+
123
+ it('should stringify YAML with --- delimiters when it is explicitly set as the format with a custom delimiter', () => {
124
+ expect(
125
+ frontmatterYAML('~~~').toFile({
126
+ body: 'Some content\nOn another line',
127
+ tags: ['front matter', 'yaml'],
128
+ title: 'YAML',
129
+ }),
130
+ ).toEqual(
131
+ [
132
+ '~~~',
133
+ 'tags:',
134
+ ' - front matter',
135
+ ' - yaml',
136
+ 'title: YAML',
137
+ '~~~',
138
+ 'Some content',
139
+ 'On another line',
140
+ ].join('\n'),
141
+ );
142
+ });
143
+
144
+ it('should stringify YAML with --- delimiters when it is explicitly set as the format with different custom delimiters', () => {
145
+ expect(
146
+ frontmatterYAML(['~~~', '^^^']).toFile({
147
+ body: 'Some content\nOn another line',
148
+ tags: ['front matter', 'yaml'],
149
+ title: 'YAML',
150
+ }),
151
+ ).toEqual(
152
+ [
153
+ '~~~',
154
+ 'tags:',
155
+ ' - front matter',
156
+ ' - yaml',
157
+ 'title: YAML',
158
+ '^^^',
159
+ 'Some content',
160
+ 'On another line',
161
+ ].join('\n'),
162
+ );
163
+ });
164
+
165
+ it('should trim last line break if added by grey-matter', () => {
166
+ expect(
167
+ frontmatterYAML().toFile({
168
+ body: 'noLineBreak',
169
+ }),
170
+ ).toEqual('noLineBreak');
171
+ });
172
+
173
+ it('should not trim last line break if not added by grey-matter', () => {
174
+ expect(
175
+ frontmatterYAML().toFile({
176
+ body: 'withLineBreak\n',
177
+ }),
178
+ ).toEqual('withLineBreak\n');
179
+ });
180
+
181
+ it('should keep field types', () => {
182
+ const frontmatter = frontmatterYAML();
183
+ const file = frontmatter.toFile({
184
+ number: 1,
185
+ string: 'Hello World!',
186
+ date: new Date('2020-01-01'),
187
+ array: ['1', new Date('2020-01-01')],
188
+ body: 'Content',
189
+ });
190
+ expect(frontmatter.fromFile(file)).toEqual({
191
+ number: 1,
192
+ string: 'Hello World!',
193
+ date: new Date('2020-01-01'),
194
+ array: ['1', new Date('2020-01-01')],
195
+ body: 'Content',
196
+ });
197
+ });
198
+ });
199
+
200
+ describe('toml', () => {
201
+ it('should parse TOML with +++ delimiters', () => {
202
+ expect(
203
+ FrontmatterInfer.fromFile(
204
+ '+++\ntitle = "TOML"\ndescription = "Front matter"\n+++\nContent',
205
+ ),
206
+ ).toEqual({
207
+ title: 'TOML',
208
+ description: 'Front matter',
209
+ body: 'Content',
210
+ });
211
+ });
212
+
213
+ it('should parse TOML with 0.5 style dates', () => {
214
+ expect(
215
+ FrontmatterInfer.fromFile('+++\ntitle = "TOML"\ndate = 2018-12-24\n+++\nContent'),
216
+ ).toEqual({
217
+ title: 'TOML',
218
+ date: new Date('2018-12-24T00:00:00.000Z'),
219
+ body: 'Content',
220
+ });
221
+ });
222
+
223
+ it('should parse TOML with +++ delimiters when it is explicitly set as the format without a custom delimiter', () => {
224
+ expect(
225
+ frontmatterTOML('~~~').fromFile(
226
+ '~~~\ntitle = "TOML"\ndescription = "Front matter"\n~~~\nContent',
227
+ ),
228
+ ).toEqual({
229
+ title: 'TOML',
230
+ description: 'Front matter',
231
+ body: 'Content',
232
+ });
233
+ });
234
+
235
+ it('should parse TOML with ---toml delimiters', () => {
236
+ expect(
237
+ FrontmatterInfer.fromFile(
238
+ '---toml\ntitle = "TOML"\ndescription = "Something longer"\n---\nContent',
239
+ ),
240
+ ).toEqual({
241
+ title: 'TOML',
242
+ description: 'Something longer',
243
+ body: 'Content',
244
+ });
245
+ });
246
+
247
+ it('should stringify TOML with +++ delimiters when it is explicitly set as the format without a custom delimiter', () => {
248
+ expect(
249
+ frontmatterTOML().toFile({
250
+ body: 'Some content\nOn another line',
251
+ tags: ['front matter', 'toml'],
252
+ title: 'TOML',
253
+ }),
254
+ ).toEqual(
255
+ [
256
+ '+++',
257
+ 'tags = ["front matter", "toml"]',
258
+ 'title = "TOML"',
259
+ '+++',
260
+ 'Some content',
261
+ 'On another line',
262
+ ].join('\n'),
263
+ );
264
+ });
265
+
266
+ it('should stringify TOML with +++ delimiters when it is explicitly set as the format with a custom delimiter', () => {
267
+ expect(
268
+ frontmatterTOML('~~~').toFile({
269
+ body: 'Some content\nOn another line',
270
+ tags: ['front matter', 'toml'],
271
+ title: 'TOML',
272
+ }),
273
+ ).toEqual(
274
+ [
275
+ '~~~',
276
+ 'tags = ["front matter", "toml"]',
277
+ 'title = "TOML"',
278
+ '~~~',
279
+ 'Some content',
280
+ 'On another line',
281
+ ].join('\n'),
282
+ );
283
+ });
284
+
285
+ it('should keep field types', () => {
286
+ const frontmatter = frontmatterTOML();
287
+ const file = frontmatter.toFile({
288
+ number: 1,
289
+ string: 'Hello World!',
290
+ date: new Date('2020-01-01'),
291
+ // in toml arrays must contain the same type
292
+ array: ['1', new Date('2020-01-01').toISOString()],
293
+ body: 'Content',
294
+ });
295
+ expect(frontmatter.fromFile(file)).toEqual({
296
+ number: 1,
297
+ string: 'Hello World!',
298
+ date: new Date('2020-01-01'),
299
+ array: ['1', new Date('2020-01-01').toISOString()],
300
+ body: 'Content',
301
+ });
302
+ });
303
+ });
304
+
305
+ describe('json', () => {
306
+ it('should parse JSON with { } delimiters', () => {
307
+ expect(
308
+ FrontmatterInfer.fromFile(
309
+ '{\n"title": "The Title",\n"description": "Something longer"\n}\nContent',
310
+ ),
311
+ ).toEqual({
312
+ title: 'The Title',
313
+ description: 'Something longer',
314
+ body: 'Content',
315
+ });
316
+ });
317
+
318
+ it('should parse JSON with { } delimiters when it is explicitly set as the format without a custom delimiter', () => {
319
+ expect(
320
+ frontmatterJSON().fromFile(
321
+ '{\n"title": "The Title",\n"description": "Something longer"\n}\nContent',
322
+ ),
323
+ ).toEqual({
324
+ title: 'The Title',
325
+ description: 'Something longer',
326
+ body: 'Content',
327
+ });
328
+ });
329
+
330
+ it('should parse JSON with { } delimiters when it is explicitly set as the format with a custom delimiter', () => {
331
+ expect(
332
+ frontmatterJSON('~~~').fromFile(
333
+ '~~~\n"title": "The Title",\n"description": "Something longer"\n~~~\nContent',
334
+ ),
335
+ ).toEqual({
336
+ title: 'The Title',
337
+ description: 'Something longer',
338
+ body: 'Content',
339
+ });
340
+ });
341
+
342
+ it('should parse JSON with ---json delimiters', () => {
343
+ expect(
344
+ FrontmatterInfer.fromFile(
345
+ '---json\n{\n"title": "The Title",\n"description": "Something longer"\n}\n---\nContent',
346
+ ),
347
+ ).toEqual({
348
+ title: 'The Title',
349
+ description: 'Something longer',
350
+ body: 'Content',
351
+ });
352
+ });
353
+
354
+ it('should parse JSON with { } delimiters ending with a nested object', () => {
355
+ expect(
356
+ FrontmatterInfer.fromFile(
357
+ '{\n "title": "The Title",\n "nested": {\n "inside": "Inside prop"\n }\n}\nContent',
358
+ ),
359
+ ).toEqual({
360
+ title: 'The Title',
361
+ nested: { inside: 'Inside prop' },
362
+ body: 'Content',
363
+ });
364
+ });
365
+
366
+ it('should stringify JSON with { } delimiters when it is explicitly set as the format without a custom delimiter', () => {
367
+ expect(
368
+ frontmatterJSON().toFile({
369
+ body: 'Some content\nOn another line',
370
+ tags: ['front matter', 'json'],
371
+ title: 'JSON',
372
+ }),
373
+ ).toEqual(
374
+ [
375
+ '{',
376
+ '"tags": [',
377
+ ' "front matter",',
378
+ ' "json"',
379
+ ' ],',
380
+ ' "title": "JSON"',
381
+ '}',
382
+ 'Some content',
383
+ 'On another line',
384
+ ].join('\n'),
385
+ );
386
+ });
387
+
388
+ it('should stringify JSON with { } delimiters when it is explicitly set as the format with a custom delimiter', () => {
389
+ expect(
390
+ frontmatterJSON('~~~').toFile({
391
+ body: 'Some content\nOn another line',
392
+ tags: ['front matter', 'json'],
393
+ title: 'JSON',
394
+ }),
395
+ ).toEqual(
396
+ [
397
+ '~~~',
398
+ '"tags": [',
399
+ ' "front matter",',
400
+ ' "json"',
401
+ ' ],',
402
+ ' "title": "JSON"',
403
+ '~~~',
404
+ 'Some content',
405
+ 'On another line',
406
+ ].join('\n'),
407
+ );
408
+ });
409
+
410
+ it('should keep field types', () => {
411
+ const frontmatter = frontmatterJSON();
412
+ const file = frontmatter.toFile({
413
+ number: 1,
414
+ string: 'Hello World!',
415
+ // no way to represent date in JSON
416
+ date: new Date('2020-01-01').toISOString(),
417
+ array: ['1', new Date('2020-01-01').toISOString()],
418
+ body: 'Content',
419
+ });
420
+ expect(frontmatter.fromFile(file)).toEqual({
421
+ number: 1,
422
+ string: 'Hello World!',
423
+ date: new Date('2020-01-01').toISOString(),
424
+ array: ['1', new Date('2020-01-01').toISOString()],
425
+ body: 'Content',
426
+ });
427
+ });
428
+ });
429
+ });
@@ -0,0 +1,9 @@
1
+ import tomlFormatter from '../toml';
2
+
3
+ describe('tomlFormatter', () => {
4
+ it('should output TOML integer values without decimals', () => {
5
+ expect(tomlFormatter.toFile({ testFloat: 123.456, testInteger: 789, title: 'TOML' })).toEqual(
6
+ ['testFloat = 123.456', 'testInteger = 789', 'title = "TOML"'].join('\n'),
7
+ );
8
+ });
9
+ });
@@ -0,0 +1,162 @@
1
+ import { stripIndent } from 'common-tags';
2
+
3
+ import yaml from '../yaml';
4
+
5
+ describe('yaml', () => {
6
+ describe('fromFile', () => {
7
+ test('loads valid yaml', () => {
8
+ expect(yaml.fromFile('[]')).toEqual([]);
9
+
10
+ const result = yaml.fromFile(stripIndent`
11
+ date: 2020-04-02T16:08:03.327Z
12
+ dateString: 2020-04-02
13
+ boolean: true
14
+ number: 1
15
+ `);
16
+ expect(result).toEqual({
17
+ date: new Date('2020-04-02T16:08:03.327Z'),
18
+ dateString: '2020-04-02',
19
+ boolean: true,
20
+ number: 1,
21
+ });
22
+ expect(yaml.fromFile('# Comment a\na: a\nb:\n # Comment c\n c:\n d: d\n')).toEqual({
23
+ a: 'a',
24
+ b: { c: { d: 'd' } },
25
+ });
26
+ expect(
27
+ yaml.fromFile(stripIndent`
28
+ # template comment
29
+ template: post
30
+ # title comment
31
+ title: title
32
+ # image comment
33
+ image: /media/netlify.png
34
+ # date comment
35
+ date: 2020-04-02T13:27:48.617Z
36
+ # object comment
37
+ object:
38
+ # object_title comment
39
+ object_title: object_title
40
+ # object_list comment
41
+ object_list:
42
+ - object_list_item_1: "1"
43
+ object_list_item_2: "2"
44
+ # list comment
45
+ list:
46
+ - "1"
47
+ `),
48
+ ).toEqual({
49
+ list: ['1'],
50
+ object: {
51
+ object_title: 'object_title',
52
+ object_list: [{ object_list_item_1: '1', object_list_item_2: '2' }],
53
+ },
54
+ date: new Date('2020-04-02T13:27:48.617Z'),
55
+ image: '/media/netlify.png',
56
+ title: 'title',
57
+ template: 'post',
58
+ });
59
+ });
60
+ test('does not fail on closing separator', () => {
61
+ expect(yaml.fromFile('---\n[]\n---')).toEqual([]);
62
+ });
63
+
64
+ test('parses single quoted string as string', () => {
65
+ expect(yaml.fromFile('name: y')).toEqual({ name: 'y' });
66
+ });
67
+
68
+ test('parses ISO date string as date', () => {
69
+ expect(yaml.fromFile('date: 2020-04-02T16:08:03.327Z')).toEqual({
70
+ date: new Date('2020-04-02T16:08:03.327Z'),
71
+ });
72
+ });
73
+
74
+ test('parses partial date string as string', () => {
75
+ expect(yaml.fromFile('date: 2020-06-12')).toEqual({
76
+ date: '2020-06-12',
77
+ });
78
+ expect(yaml.fromFile('date: 12-06-2012')).toEqual({
79
+ date: '12-06-2012',
80
+ });
81
+ });
82
+
83
+ test('parses partial time value as string', () => {
84
+ expect(yaml.fromFile('time: 10:05')).toEqual({
85
+ time: '10:05',
86
+ });
87
+ });
88
+ });
89
+ describe('toFile', () => {
90
+ test('outputs valid yaml', () => {
91
+ expect(yaml.toFile([])).toEqual('[]\n');
92
+ });
93
+
94
+ test('should sort keys', () => {
95
+ expect(yaml.toFile({ a: 'a', b: 'b', c: 'c', d: 'd' })).toEqual('a: a\nb: b\nc: c\nd: d\n');
96
+ expect(yaml.toFile({ a: 'a', b: 'b', c: 'c', d: 'd' }, ['d', 'b', 'a', 'c'])).toEqual(
97
+ 'd: d\nb: b\na: a\nc: c\n',
98
+ );
99
+ expect(yaml.toFile({ a: 'a', b: 'b', c: 'c', d: 'd' }, ['d', 'b', 'c'])).toEqual(
100
+ 'a: a\nd: d\nb: b\nc: c\n',
101
+ );
102
+ });
103
+
104
+ test('should add comments', () => {
105
+ expect(
106
+ yaml.toFile({ a: 'a', b: { c: { d: 'd' } } }, [], { a: 'Comment a', 'b.c': 'Comment c' }),
107
+ ).toEqual('# Comment a\na: a\nb:\n # Comment c\n c:\n d: d\n');
108
+
109
+ const expected = `# template comment
110
+ template: post
111
+ # title comment
112
+ title: title
113
+ # image comment
114
+ image: /media/netlify.png
115
+ # date comment
116
+ date: 2020-04-02T13:27:48.617Z
117
+ # object comment
118
+ object:
119
+ # object_title comment
120
+ object_title: object_title
121
+ # object_list comment
122
+ object_list:
123
+ - object_list_item_1: "1"
124
+ object_list_item_2: "2"
125
+ # list comment
126
+ list:
127
+ - "1"
128
+ `;
129
+
130
+ const result = yaml.toFile(
131
+ {
132
+ list: ['1'],
133
+ object: {
134
+ object_title: 'object_title',
135
+ object_list: [{ object_list_item_1: '1', object_list_item_2: '2' }],
136
+ },
137
+ date: new Date('2020-04-02T13:27:48.617Z'),
138
+ image: '/media/netlify.png',
139
+ title: 'title',
140
+ template: 'post',
141
+ },
142
+ ['template', 'title', 'image', 'date', 'object', 'list'],
143
+ {
144
+ list: 'list comment',
145
+ object: 'object comment',
146
+ 'object.object_title': 'object_title comment',
147
+ 'object.object_list': 'object_list comment',
148
+ date: 'date comment',
149
+ image: 'image comment',
150
+ title: 'title comment',
151
+ template: 'template comment',
152
+ },
153
+ );
154
+
155
+ expect(result).toEqual(expected);
156
+
157
+ expect(yaml.toFile({ a: 'a' }, [], { a: 'line 1\\nline 2' })).toEqual(
158
+ '# line 1\n# line 2\na: a\n',
159
+ );
160
+ });
161
+ });
162
+ });
@@ -0,0 +1,97 @@
1
+ import { List } from 'immutable';
2
+ import get from 'lodash/get';
3
+
4
+ import yamlFormatter from './yaml';
5
+ import tomlFormatter from './toml';
6
+ import jsonFormatter from './json';
7
+ import { FrontmatterInfer, frontmatterJSON, frontmatterTOML, frontmatterYAML } from './frontmatter';
8
+ import { getCustomFormatsExtensions, getCustomFormatsFormatters } from '../lib/registry';
9
+
10
+ import type { Delimiter } from './frontmatter';
11
+ import type { Collection, EntryObject, Format } from '../types/redux';
12
+ import type { EntryValue } from '../valueObjects/Entry';
13
+ import type { Formatter } from 'decap-cms-core';
14
+
15
+ export const frontmatterFormats = ['yaml-frontmatter', 'toml-frontmatter', 'json-frontmatter'];
16
+
17
+ export const formatExtensions = {
18
+ yml: 'yml',
19
+ yaml: 'yml',
20
+ toml: 'toml',
21
+ json: 'json',
22
+ frontmatter: 'md',
23
+ 'json-frontmatter': 'md',
24
+ 'toml-frontmatter': 'md',
25
+ 'yaml-frontmatter': 'md',
26
+ };
27
+
28
+ export function getFormatExtensions() {
29
+ return { ...formatExtensions, ...getCustomFormatsExtensions() };
30
+ }
31
+
32
+ export const extensionFormatters = {
33
+ yml: yamlFormatter,
34
+ yaml: yamlFormatter,
35
+ toml: tomlFormatter,
36
+ json: jsonFormatter,
37
+ md: FrontmatterInfer,
38
+ markdown: FrontmatterInfer,
39
+ html: FrontmatterInfer,
40
+ };
41
+
42
+ function formatByName(name: Format, customDelimiter?: Delimiter): Formatter {
43
+ const formatters: Record<string, Formatter> = {
44
+ yml: yamlFormatter,
45
+ yaml: yamlFormatter,
46
+ toml: tomlFormatter,
47
+ json: jsonFormatter,
48
+ frontmatter: FrontmatterInfer,
49
+ 'json-frontmatter': frontmatterJSON(customDelimiter),
50
+ 'toml-frontmatter': frontmatterTOML(customDelimiter),
51
+ 'yaml-frontmatter': frontmatterYAML(customDelimiter),
52
+ ...getCustomFormatsFormatters(),
53
+ };
54
+ if (name in formatters) {
55
+ return formatters[name];
56
+ }
57
+ throw new Error(`No formatter available with name: ${name}`);
58
+ }
59
+
60
+ function frontmatterDelimiterIsList(
61
+ frontmatterDelimiter?: Delimiter | List<string>,
62
+ ): frontmatterDelimiter is List<string> {
63
+ return List.isList(frontmatterDelimiter);
64
+ }
65
+
66
+ export function resolveFormat(collection: Collection, entry: EntryObject | EntryValue) {
67
+ // Check for custom delimiter
68
+ const frontmatter_delimiter = collection.get('frontmatter_delimiter');
69
+ const customDelimiter = frontmatterDelimiterIsList(frontmatter_delimiter)
70
+ ? (frontmatter_delimiter.toArray() as [string, string])
71
+ : frontmatter_delimiter;
72
+
73
+ // If the format is specified in the collection, use that format.
74
+ const formatSpecification = collection.get('format');
75
+ if (formatSpecification) {
76
+ return formatByName(formatSpecification, customDelimiter);
77
+ }
78
+
79
+ // If a file already exists, infer the format from its file extension.
80
+ const filePath = entry && entry.path;
81
+ if (filePath) {
82
+ const fileExtension = filePath.split('.').pop();
83
+ if (fileExtension) {
84
+ return get(extensionFormatters, fileExtension);
85
+ }
86
+ }
87
+
88
+ // If creating a new file, and an `extension` is specified in the
89
+ // collection config, infer the format from that extension.
90
+ const extension = collection.get('extension');
91
+ if (extension) {
92
+ return get(extensionFormatters, extension);
93
+ }
94
+
95
+ // If no format is specified and it cannot be inferred, return the default.
96
+ return formatByName('frontmatter', customDelimiter);
97
+ }