@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,367 @@
1
+ import { Map, List } from 'immutable';
2
+ import set from 'lodash/set';
3
+ import groupBy from 'lodash/groupBy';
4
+ import escapeRegExp from 'lodash/escapeRegExp';
5
+ import { selectEntrySlug } from '../reducers/collections';
6
+ export const I18N = 'i18n';
7
+ export let I18N_STRUCTURE = /*#__PURE__*/function (I18N_STRUCTURE) {
8
+ I18N_STRUCTURE["MULTIPLE_FOLDERS"] = "multiple_folders";
9
+ I18N_STRUCTURE["MULTIPLE_FILES"] = "multiple_files";
10
+ I18N_STRUCTURE["SINGLE_FILE"] = "single_file";
11
+ return I18N_STRUCTURE;
12
+ }({});
13
+ export let I18N_FIELD = /*#__PURE__*/function (I18N_FIELD) {
14
+ I18N_FIELD["TRANSLATE"] = "translate";
15
+ I18N_FIELD["DUPLICATE"] = "duplicate";
16
+ I18N_FIELD["NONE"] = "none";
17
+ return I18N_FIELD;
18
+ }({});
19
+ export function hasI18n(collection) {
20
+ return collection.has(I18N);
21
+ }
22
+ export function getI18nInfo(collection) {
23
+ if (!hasI18n(collection)) {
24
+ return {};
25
+ }
26
+ const {
27
+ structure,
28
+ locales,
29
+ default_locale: defaultLocale
30
+ } = collection.get(I18N).toJS();
31
+ return {
32
+ structure,
33
+ locales,
34
+ defaultLocale
35
+ };
36
+ }
37
+ export function getI18nFilesDepth(collection, depth) {
38
+ const {
39
+ structure
40
+ } = getI18nInfo(collection);
41
+ if (structure === I18N_STRUCTURE.MULTIPLE_FOLDERS) {
42
+ return depth + 1;
43
+ }
44
+ return depth;
45
+ }
46
+ export function isFieldTranslatable(field, locale, defaultLocale) {
47
+ const isTranslatable = locale !== defaultLocale && field.get(I18N) === I18N_FIELD.TRANSLATE;
48
+ return isTranslatable;
49
+ }
50
+ export function isFieldDuplicate(field, locale, defaultLocale) {
51
+ const isDuplicate = locale !== defaultLocale && field.get(I18N) === I18N_FIELD.DUPLICATE;
52
+ return isDuplicate;
53
+ }
54
+ export function isFieldHidden(field, locale, defaultLocale) {
55
+ const isHidden = locale !== defaultLocale && field.get(I18N) === I18N_FIELD.NONE;
56
+ return isHidden;
57
+ }
58
+ export function getLocaleDataPath(locale) {
59
+ return [I18N, locale, 'data'];
60
+ }
61
+ export function getDataPath(locale, defaultLocale) {
62
+ const dataPath = locale !== defaultLocale ? getLocaleDataPath(locale) : ['data'];
63
+ return dataPath;
64
+ }
65
+ export function getFilePath(structure, extension, path, slug, locale) {
66
+ switch (structure) {
67
+ case I18N_STRUCTURE.MULTIPLE_FOLDERS:
68
+ return path.replace(`/${slug}`, `/${locale}/${slug}`);
69
+ case I18N_STRUCTURE.MULTIPLE_FILES:
70
+ return path.replace(new RegExp(`${escapeRegExp(extension)}$`), `${locale}.${extension}`);
71
+ case I18N_STRUCTURE.SINGLE_FILE:
72
+ default:
73
+ return path;
74
+ }
75
+ }
76
+ export function getLocaleFromPath(structure, extension, path) {
77
+ switch (structure) {
78
+ case I18N_STRUCTURE.MULTIPLE_FOLDERS:
79
+ {
80
+ const parts = path.split('/');
81
+ // filename
82
+ parts.pop();
83
+ // locale
84
+ return parts.pop();
85
+ }
86
+ case I18N_STRUCTURE.MULTIPLE_FILES:
87
+ {
88
+ const parts = path.slice(0, -`.${extension}`.length);
89
+ return parts.split('.').pop();
90
+ }
91
+ case I18N_STRUCTURE.SINGLE_FILE:
92
+ default:
93
+ return '';
94
+ }
95
+ }
96
+ export function getFilePaths(collection, extension, path, slug) {
97
+ const {
98
+ structure,
99
+ locales
100
+ } = getI18nInfo(collection);
101
+ if (structure === I18N_STRUCTURE.SINGLE_FILE) {
102
+ return [path];
103
+ }
104
+ const paths = locales.map(locale => getFilePath(structure, extension, path, slug, locale));
105
+ return paths;
106
+ }
107
+ export function normalizeFilePath(structure, path, locale) {
108
+ switch (structure) {
109
+ case I18N_STRUCTURE.MULTIPLE_FOLDERS:
110
+ return path.replace(`${locale}/`, '');
111
+ case I18N_STRUCTURE.MULTIPLE_FILES:
112
+ return path.replace(`.${locale}`, '');
113
+ case I18N_STRUCTURE.SINGLE_FILE:
114
+ default:
115
+ return path;
116
+ }
117
+ }
118
+ export function getI18nFiles(collection, extension, entryDraft, entryToRaw, path, slug, newPath) {
119
+ const {
120
+ structure,
121
+ defaultLocale,
122
+ locales
123
+ } = getI18nInfo(collection);
124
+ if (structure === I18N_STRUCTURE.SINGLE_FILE) {
125
+ const data = locales.reduce((map, locale) => {
126
+ const dataPath = getDataPath(locale, defaultLocale);
127
+ return map.set(locale, entryDraft.getIn(dataPath));
128
+ }, Map({}));
129
+ const draft = entryDraft.set('data', data);
130
+ return [{
131
+ path: getFilePath(structure, extension, path, slug, locales[0]),
132
+ slug,
133
+ raw: entryToRaw(draft),
134
+ ...(newPath && {
135
+ newPath: getFilePath(structure, extension, newPath, slug, locales[0])
136
+ })
137
+ }];
138
+ }
139
+ const dataFiles = locales.map(locale => {
140
+ const dataPath = getDataPath(locale, defaultLocale);
141
+ const draft = entryDraft.set('data', entryDraft.getIn(dataPath));
142
+ return {
143
+ path: getFilePath(structure, extension, path, slug, locale),
144
+ slug,
145
+ raw: draft.get('data') ? entryToRaw(draft) : '',
146
+ ...(newPath && {
147
+ newPath: getFilePath(structure, extension, newPath, slug, locale)
148
+ })
149
+ };
150
+ }).filter(dataFile => dataFile.raw);
151
+ return dataFiles;
152
+ }
153
+ export function getI18nBackup(collection, entry, entryToRaw) {
154
+ const {
155
+ locales,
156
+ defaultLocale
157
+ } = getI18nInfo(collection);
158
+ const i18nBackup = locales.filter(l => l !== defaultLocale).reduce((acc, locale) => {
159
+ const dataPath = getDataPath(locale, defaultLocale);
160
+ const data = entry.getIn(dataPath);
161
+ if (!data) {
162
+ return acc;
163
+ }
164
+ const draft = entry.set('data', data);
165
+ return {
166
+ ...acc,
167
+ [locale]: {
168
+ raw: entryToRaw(draft)
169
+ }
170
+ };
171
+ }, {});
172
+ return i18nBackup;
173
+ }
174
+ export function formatI18nBackup(i18nBackup, formatRawData) {
175
+ const i18n = Object.entries(i18nBackup).reduce((acc, [locale, {
176
+ raw
177
+ }]) => {
178
+ const entry = formatRawData(raw);
179
+ return {
180
+ ...acc,
181
+ [locale]: {
182
+ data: entry.data
183
+ }
184
+ };
185
+ }, {});
186
+ return i18n;
187
+ }
188
+ function applyDefaultI18nValues(collection, value, defaultLocaleValue) {
189
+ if (collection.get('fields') === undefined) {
190
+ return;
191
+ }
192
+ collection.get('fields').forEach(field => {
193
+ if (field && field.get(I18N) === I18N_FIELD.DUPLICATE) {
194
+ const data = value.data[field.get('name')];
195
+ if (!data) {
196
+ value.data[field.get('name')] = defaultLocaleValue.data[field.get('name')];
197
+ }
198
+ }
199
+ });
200
+ }
201
+ function mergeValues(collection, structure, defaultLocale, values) {
202
+ let defaultEntry = values.find(e => e.locale === defaultLocale);
203
+ if (!defaultEntry) {
204
+ defaultEntry = values[0];
205
+ console.warn(`Could not locale entry for default locale '${defaultLocale}'`);
206
+ }
207
+ const i18n = values.filter(e => e.locale !== defaultEntry.locale).reduce((acc, {
208
+ locale,
209
+ value
210
+ }) => {
211
+ const dataPath = getLocaleDataPath(locale);
212
+ if (defaultEntry) {
213
+ applyDefaultI18nValues(collection, value, defaultEntry.value);
214
+ }
215
+ return set(acc, dataPath, value.data);
216
+ }, {});
217
+ const path = normalizeFilePath(structure, defaultEntry.value.path, defaultLocale);
218
+ const slug = selectEntrySlug(collection, path);
219
+ const entryValue = {
220
+ ...defaultEntry.value,
221
+ raw: '',
222
+ ...i18n,
223
+ path,
224
+ slug
225
+ };
226
+ return entryValue;
227
+ }
228
+ function mergeSingleFileValue(entryValue, defaultLocale, locales) {
229
+ const data = entryValue.data[defaultLocale] || {};
230
+ const i18n = locales.filter(l => l !== defaultLocale).map(l => ({
231
+ locale: l,
232
+ value: entryValue.data[l]
233
+ })).filter(e => e.value).reduce((acc, e) => {
234
+ return {
235
+ ...acc,
236
+ [e.locale]: {
237
+ data: e.value
238
+ }
239
+ };
240
+ }, {});
241
+ return {
242
+ ...entryValue,
243
+ data,
244
+ i18n,
245
+ raw: ''
246
+ };
247
+ }
248
+ export async function getI18nEntry(collection, extension, path, slug, getEntryValue) {
249
+ const {
250
+ structure,
251
+ locales,
252
+ defaultLocale
253
+ } = getI18nInfo(collection);
254
+ let entryValue;
255
+ if (structure === I18N_STRUCTURE.SINGLE_FILE) {
256
+ entryValue = mergeSingleFileValue(await getEntryValue(path), defaultLocale, locales);
257
+ } else {
258
+ const entryValues = await Promise.all(locales.map(async locale => {
259
+ const entryPath = getFilePath(structure, extension, path, slug, locale);
260
+ const value = await getEntryValue(entryPath).catch(() => null);
261
+ return {
262
+ value,
263
+ locale
264
+ };
265
+ }));
266
+ const nonNullValues = entryValues.filter(e => e.value !== null);
267
+ entryValue = mergeValues(collection, structure, defaultLocale, nonNullValues);
268
+ }
269
+ return entryValue;
270
+ }
271
+ export function groupEntries(collection, extension, entries) {
272
+ const {
273
+ structure,
274
+ defaultLocale,
275
+ locales
276
+ } = getI18nInfo(collection);
277
+ if (structure === I18N_STRUCTURE.SINGLE_FILE) {
278
+ return entries.map(e => mergeSingleFileValue(e, defaultLocale, locales));
279
+ }
280
+ const grouped = groupBy(entries.map(e => ({
281
+ locale: getLocaleFromPath(structure, extension, e.path),
282
+ value: e
283
+ })), ({
284
+ locale,
285
+ value: e
286
+ }) => {
287
+ return normalizeFilePath(structure, e.path, locale);
288
+ });
289
+ const groupedEntries = Object.values(grouped).reduce((acc, values) => {
290
+ const entryValue = mergeValues(collection, structure, defaultLocale, values);
291
+ return [...acc, entryValue];
292
+ }, []);
293
+ return groupedEntries;
294
+ }
295
+ export function getI18nDataFiles(collection, extension, path, slug, diffFiles) {
296
+ const {
297
+ structure
298
+ } = getI18nInfo(collection);
299
+ if (structure === I18N_STRUCTURE.SINGLE_FILE) {
300
+ return diffFiles;
301
+ }
302
+ const paths = getFilePaths(collection, extension, path, slug);
303
+ const dataFiles = paths.reduce((acc, path) => {
304
+ const dataFile = diffFiles.find(file => file.path === path);
305
+ if (dataFile) {
306
+ return [...acc, dataFile];
307
+ } else {
308
+ return [...acc, {
309
+ path,
310
+ id: '',
311
+ newFile: false
312
+ }];
313
+ }
314
+ }, []);
315
+ return dataFiles;
316
+ }
317
+
318
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
319
+ export function duplicateDefaultI18nFields(collection, dataFields) {
320
+ const {
321
+ locales,
322
+ defaultLocale
323
+ } = getI18nInfo(collection);
324
+ const i18nFields = Object.fromEntries(locales.filter(locale => locale !== defaultLocale).map(locale => [locale, {
325
+ data: dataFields
326
+ }]));
327
+ return i18nFields;
328
+ }
329
+ export function duplicateI18nFields(entryDraft, field, locales, defaultLocale, fieldPath = [field.get('name')]) {
330
+ const value = entryDraft.getIn(['entry', 'data', ...fieldPath]);
331
+ if (field.get(I18N) === I18N_FIELD.DUPLICATE) {
332
+ locales.filter(l => l !== defaultLocale).forEach(l => {
333
+ entryDraft = entryDraft.setIn(['entry', ...getDataPath(l, defaultLocale), ...fieldPath], value);
334
+ });
335
+ }
336
+ if (field.has('field') && !List.isList(value)) {
337
+ const fields = [field.get('field')];
338
+ fields.forEach(field => {
339
+ entryDraft = duplicateI18nFields(entryDraft, field, locales, defaultLocale, [...fieldPath, field.get('name')]);
340
+ });
341
+ } else if (field.has('fields') && !List.isList(value)) {
342
+ const fields = field.get('fields').toArray();
343
+ fields.forEach(field => {
344
+ entryDraft = duplicateI18nFields(entryDraft, field, locales, defaultLocale, [...fieldPath, field.get('name')]);
345
+ });
346
+ }
347
+ return entryDraft;
348
+ }
349
+ export function getPreviewEntry(entry, locale, defaultLocale) {
350
+ if (locale === defaultLocale) {
351
+ return entry;
352
+ }
353
+ return entry.set('data', entry.getIn([I18N, locale, 'data']));
354
+ }
355
+ export function serializeI18n(collection, entry,
356
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
357
+ serializeValues) {
358
+ const {
359
+ locales,
360
+ defaultLocale
361
+ } = getI18nInfo(collection);
362
+ locales.filter(locale => locale !== defaultLocale).forEach(locale => {
363
+ const dataPath = getLocaleDataPath(locale);
364
+ entry = entry.setIn(dataPath, serializeValues(entry.getIn(dataPath)));
365
+ });
366
+ return entry;
367
+ }
@@ -0,0 +1,6 @@
1
+ import merge from 'lodash/merge';
2
+ import { getLocale } from './registry';
3
+ export function getPhrases(locale) {
4
+ const phrases = merge({}, getLocale('en'), getLocale(locale));
5
+ return phrases;
6
+ }
@@ -0,0 +1,8 @@
1
+ import { Buffer } from 'buffer';
2
+ if (typeof window !== 'undefined') {
3
+ // Polyfill global for packages like @iarna/toml
4
+ window.global = window;
5
+
6
+ // Polyfill Buffer for packages like gray-matter
7
+ window.Buffer = Buffer;
8
+ }
@@ -0,0 +1,329 @@
1
+ import { Map } from 'immutable';
2
+ import { produce } from 'immer';
3
+ import { oneLine } from 'common-tags';
4
+ import EditorComponent from '../valueObjects/EditorComponent';
5
+ const allowedEvents = ['prePublish', 'postPublish', 'preUnpublish', 'postUnpublish', 'preSave', 'postSave'];
6
+ const eventHandlers = {};
7
+ allowedEvents.forEach(e => {
8
+ eventHandlers[e] = [];
9
+ });
10
+
11
+ /**
12
+ * Global Registry Object
13
+ */
14
+ const registry = {
15
+ backends: {},
16
+ templates: {},
17
+ previewStyles: [],
18
+ widgets: {},
19
+ editorComponents: Map(),
20
+ remarkPlugins: [],
21
+ widgetValueSerializers: {},
22
+ mediaLibraries: [],
23
+ locales: {},
24
+ eventHandlers,
25
+ formats: {}
26
+ };
27
+ export default {
28
+ registerPreviewStyle,
29
+ getPreviewStyles,
30
+ registerPreviewTemplate,
31
+ getPreviewTemplate,
32
+ registerWidget,
33
+ getWidget,
34
+ getWidgets,
35
+ resolveWidget,
36
+ registerEditorComponent,
37
+ getEditorComponents,
38
+ registerRemarkPlugin,
39
+ getRemarkPlugins,
40
+ registerWidgetValueSerializer,
41
+ getWidgetValueSerializer,
42
+ registerBackend,
43
+ getBackend,
44
+ registerMediaLibrary,
45
+ getMediaLibrary,
46
+ registerLocale,
47
+ getLocale,
48
+ registerEventListener,
49
+ removeEventListener,
50
+ getEventListeners,
51
+ invokeEvent,
52
+ registerCustomFormat,
53
+ getCustomFormats,
54
+ getCustomFormatsExtensions,
55
+ getCustomFormatsFormatters
56
+ };
57
+
58
+ /**
59
+ * Preview Styles
60
+ *
61
+ * Valid options:
62
+ * - raw {boolean} if `true`, `style` value is expected to be a CSS string
63
+ */
64
+ export function registerPreviewStyle(style, opts) {
65
+ registry.previewStyles.push({
66
+ ...opts,
67
+ value: style
68
+ });
69
+ }
70
+ export function getPreviewStyles() {
71
+ return registry.previewStyles;
72
+ }
73
+
74
+ /**
75
+ * Preview Templates
76
+ */
77
+ export function registerPreviewTemplate(name, component) {
78
+ registry.templates[name] = component;
79
+ }
80
+ export function getPreviewTemplate(name) {
81
+ return registry.templates[name];
82
+ }
83
+
84
+ /**
85
+ * Editor Widgets
86
+ */
87
+ export function registerWidget(name, control, preview, schema = {}) {
88
+ if (Array.isArray(name)) {
89
+ name.forEach(widget => {
90
+ if (typeof widget !== 'object') {
91
+ console.error(`Cannot register widget: ${widget}`);
92
+ } else {
93
+ registerWidget(widget);
94
+ }
95
+ });
96
+ } else if (typeof name === 'string') {
97
+ // A registered widget control can be reused by a new widget, allowing
98
+ // multiple copies with different previews.
99
+ const newControl = typeof control === 'string' ? registry.widgets[control].control : control;
100
+ registry.widgets[name] = {
101
+ control: newControl,
102
+ preview,
103
+ schema
104
+ };
105
+ } else if (typeof name === 'object') {
106
+ const {
107
+ name: widgetName,
108
+ controlComponent: control,
109
+ previewComponent: preview,
110
+ schema = {},
111
+ allowMapValue,
112
+ globalStyles,
113
+ ...options
114
+ } = name;
115
+ if (registry.widgets[widgetName]) {
116
+ console.warn(oneLine`
117
+ Multiple widgets registered with name "${widgetName}". Only the last widget registered with
118
+ this name will be used.
119
+ `);
120
+ }
121
+ if (!control) {
122
+ throw Error(`Widget "${widgetName}" registered without \`controlComponent\`.`);
123
+ }
124
+ registry.widgets[widgetName] = {
125
+ control,
126
+ preview,
127
+ schema,
128
+ globalStyles,
129
+ allowMapValue,
130
+ ...options
131
+ };
132
+ } else {
133
+ console.error('`registerWidget` failed, called with incorrect arguments.');
134
+ }
135
+ }
136
+ export function getWidget(name) {
137
+ return registry.widgets[name];
138
+ }
139
+ export function getWidgets() {
140
+ return produce(Object.entries(registry.widgets), draft => {
141
+ return draft.map(([key, value]) => ({
142
+ name: key,
143
+ ...value
144
+ }));
145
+ });
146
+ }
147
+ export function resolveWidget(name) {
148
+ return getWidget(name || 'string') || getWidget('unknown');
149
+ }
150
+
151
+ /**
152
+ * Markdown Editor Custom Components
153
+ */
154
+ export function registerEditorComponent(component) {
155
+ const plugin = EditorComponent(component);
156
+ if (plugin.type === 'code-block') {
157
+ const codeBlock = registry.editorComponents.find(c => c.type === 'code-block');
158
+ if (codeBlock) {
159
+ console.warn(oneLine`
160
+ Only one editor component of type "code-block" may be registered. Previously registered code
161
+ block component(s) will be overwritten.
162
+ `);
163
+ registry.editorComponents = registry.editorComponents.delete(codeBlock.id);
164
+ }
165
+ }
166
+ registry.editorComponents = registry.editorComponents.set(plugin.id, plugin);
167
+ }
168
+ export function getEditorComponents() {
169
+ return registry.editorComponents;
170
+ }
171
+
172
+ /**
173
+ * Remark plugins
174
+ */
175
+ /** @typedef {import('unified').Pluggable} RemarkPlugin */
176
+ /** @type {(plugin: RemarkPlugin) => void} */
177
+ export function registerRemarkPlugin(plugin) {
178
+ registry.remarkPlugins.push(plugin);
179
+ }
180
+ /** @type {() => Array<RemarkPlugin>} */
181
+ export function getRemarkPlugins() {
182
+ return registry.remarkPlugins;
183
+ }
184
+
185
+ /**
186
+ * Widget Serializers
187
+ */
188
+ export function registerWidgetValueSerializer(widgetName, serializer) {
189
+ registry.widgetValueSerializers[widgetName] = serializer;
190
+ }
191
+ export function getWidgetValueSerializer(widgetName) {
192
+ return registry.widgetValueSerializers[widgetName];
193
+ }
194
+
195
+ /**
196
+ * Backend API
197
+ */
198
+ export function registerBackend(name, BackendClass) {
199
+ if (!name || !BackendClass) {
200
+ console.error("Backend parameters invalid. example: CMS.registerBackend('myBackend', BackendClass)");
201
+ } else if (registry.backends[name]) {
202
+ console.error(`Backend [${name}] already registered. Please choose a different name.`);
203
+ } else {
204
+ registry.backends[name] = {
205
+ init: (...args) => new BackendClass(...args)
206
+ };
207
+ }
208
+ }
209
+ export function getBackend(name) {
210
+ return registry.backends[name];
211
+ }
212
+
213
+ /**
214
+ * Media Libraries
215
+ */
216
+ export function registerMediaLibrary(mediaLibrary, options) {
217
+ if (registry.mediaLibraries.find(ml => mediaLibrary.name === ml.name)) {
218
+ throw new Error(`A media library named ${mediaLibrary.name} has already been registered.`);
219
+ }
220
+ registry.mediaLibraries.push({
221
+ ...mediaLibrary,
222
+ options
223
+ });
224
+ }
225
+ export function getMediaLibrary(name) {
226
+ return registry.mediaLibraries.find(ml => ml.name === name);
227
+ }
228
+ function validateEventName(name) {
229
+ if (!allowedEvents.includes(name)) {
230
+ throw new Error(`Invalid event name '${name}'`);
231
+ }
232
+ }
233
+ export function getEventListeners(name) {
234
+ validateEventName(name);
235
+ return [...registry.eventHandlers[name]];
236
+ }
237
+ export function registerEventListener({
238
+ name,
239
+ handler
240
+ }, options = {}) {
241
+ validateEventName(name);
242
+ registry.eventHandlers[name].push({
243
+ handler,
244
+ options
245
+ });
246
+ }
247
+ export async function invokeEvent({
248
+ name,
249
+ data
250
+ }) {
251
+ validateEventName(name);
252
+ const handlers = registry.eventHandlers[name];
253
+ let _data = {
254
+ ...data
255
+ };
256
+ for (const {
257
+ handler,
258
+ options
259
+ } of handlers) {
260
+ const result = await handler(_data, options);
261
+ if (result !== undefined) {
262
+ const entry = _data.entry.set('data', result);
263
+ _data = {
264
+ ...data,
265
+ entry
266
+ };
267
+ }
268
+ }
269
+ return _data.entry.get('data');
270
+ }
271
+ export function removeEventListener({
272
+ name,
273
+ handler
274
+ }) {
275
+ validateEventName(name);
276
+ if (handler) {
277
+ registry.eventHandlers[name] = registry.eventHandlers[name].filter(item => item.handler !== handler);
278
+ } else {
279
+ registry.eventHandlers[name] = [];
280
+ }
281
+ }
282
+
283
+ /**
284
+ * Locales
285
+ */
286
+ export function registerLocale(locale, phrases) {
287
+ if (!locale || !phrases) {
288
+ console.error("Locale parameters invalid. example: CMS.registerLocale('locale', phrases)");
289
+ } else {
290
+ registry.locales[locale] = phrases;
291
+ }
292
+ }
293
+ export function getLocale(locale) {
294
+ return registry.locales[locale];
295
+ }
296
+ export function registerCustomFormat(name, extension, formatter) {
297
+ registry.formats[name] = {
298
+ extension,
299
+ formatter
300
+ };
301
+ }
302
+ export function getCustomFormats() {
303
+ return registry.formats;
304
+ }
305
+ export function getCustomFormatsExtensions() {
306
+ return Object.entries(registry.formats).reduce(function (acc, [name, {
307
+ extension
308
+ }]) {
309
+ return {
310
+ ...acc,
311
+ [name]: extension
312
+ };
313
+ }, {});
314
+ }
315
+
316
+ /** @type {() => Record<string, unknown>} */
317
+ export function getCustomFormatsFormatters() {
318
+ return Object.entries(registry.formats).reduce(function (acc, [name, {
319
+ formatter
320
+ }]) {
321
+ return {
322
+ ...acc,
323
+ [name]: formatter
324
+ };
325
+ }, {});
326
+ }
327
+ export function getFormatter(name) {
328
+ return registry.formats[name]?.formatter;
329
+ }