decap-cms-core 2.56.0-beta.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 (290) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +9 -0
  3. package/dist/decap-cms-core.js +47 -0
  4. package/dist/decap-cms-core.js.LICENSE.txt +109 -0
  5. package/dist/decap-cms-core.js.map +1 -0
  6. package/dist/esm/actions/auth.js +118 -0
  7. package/dist/esm/actions/collections.js +23 -0
  8. package/dist/esm/actions/config.js +482 -0
  9. package/dist/esm/actions/deploys.js +89 -0
  10. package/dist/esm/actions/editorialWorkflow.js +511 -0
  11. package/dist/esm/actions/entries.js +940 -0
  12. package/dist/esm/actions/media.js +168 -0
  13. package/dist/esm/actions/mediaLibrary.js +606 -0
  14. package/dist/esm/actions/notifications.js +32 -0
  15. package/dist/esm/actions/search.js +156 -0
  16. package/dist/esm/actions/status.js +93 -0
  17. package/dist/esm/actions/waitUntil.js +39 -0
  18. package/dist/esm/backend.js +1073 -0
  19. package/dist/esm/bootstrap.js +107 -0
  20. package/dist/esm/components/App/App.js +301 -0
  21. package/dist/esm/components/App/Header.js +162 -0
  22. package/dist/esm/components/App/NotFoundPage.js +27 -0
  23. package/dist/esm/components/Collection/Collection.js +210 -0
  24. package/dist/esm/components/Collection/CollectionControls.js +54 -0
  25. package/dist/esm/components/Collection/CollectionSearch.js +235 -0
  26. package/dist/esm/components/Collection/CollectionTop.js +77 -0
  27. package/dist/esm/components/Collection/ControlButton.js +23 -0
  28. package/dist/esm/components/Collection/Entries/Entries.js +74 -0
  29. package/dist/esm/components/Collection/Entries/EntriesCollection.js +193 -0
  30. package/dist/esm/components/Collection/Entries/EntriesSearch.js +117 -0
  31. package/dist/esm/components/Collection/Entries/EntryCard.js +134 -0
  32. package/dist/esm/components/Collection/Entries/EntryListing.js +120 -0
  33. package/dist/esm/components/Collection/FilterControl.js +41 -0
  34. package/dist/esm/components/Collection/GroupControl.js +41 -0
  35. package/dist/esm/components/Collection/NestedCollection.js +311 -0
  36. package/dist/esm/components/Collection/Sidebar.js +102 -0
  37. package/dist/esm/components/Collection/SortControl.js +67 -0
  38. package/dist/esm/components/Collection/ViewStyleControl.js +47 -0
  39. package/dist/esm/components/Editor/Editor.js +479 -0
  40. package/dist/esm/components/Editor/EditorControlPane/EditorControl.js +393 -0
  41. package/dist/esm/components/Editor/EditorControlPane/EditorControlPane.js +259 -0
  42. package/dist/esm/components/Editor/EditorControlPane/Widget.js +355 -0
  43. package/dist/esm/components/Editor/EditorInterface.js +401 -0
  44. package/dist/esm/components/Editor/EditorPreviewPane/EditorPreview.js +56 -0
  45. package/dist/esm/components/Editor/EditorPreviewPane/EditorPreviewContent.js +34 -0
  46. package/dist/esm/components/Editor/EditorPreviewPane/EditorPreviewPane.js +252 -0
  47. package/dist/esm/components/Editor/EditorPreviewPane/PreviewHOC.js +39 -0
  48. package/dist/esm/components/Editor/EditorToolbar.js +551 -0
  49. package/dist/esm/components/Editor/withWorkflow.js +64 -0
  50. package/dist/esm/components/EditorWidgets/Unknown/UnknownControl.js +26 -0
  51. package/dist/esm/components/EditorWidgets/Unknown/UnknownPreview.js +28 -0
  52. package/dist/esm/components/EditorWidgets/index.js +7 -0
  53. package/dist/esm/components/MediaLibrary/EmptyMessage.js +30 -0
  54. package/dist/esm/components/MediaLibrary/MediaLibrary.js +444 -0
  55. package/dist/esm/components/MediaLibrary/MediaLibraryButtons.js +110 -0
  56. package/dist/esm/components/MediaLibrary/MediaLibraryCard.js +108 -0
  57. package/dist/esm/components/MediaLibrary/MediaLibraryCardGrid.js +211 -0
  58. package/dist/esm/components/MediaLibrary/MediaLibraryHeader.js +40 -0
  59. package/dist/esm/components/MediaLibrary/MediaLibraryModal.js +163 -0
  60. package/dist/esm/components/MediaLibrary/MediaLibrarySearch.js +60 -0
  61. package/dist/esm/components/MediaLibrary/MediaLibraryTop.js +134 -0
  62. package/dist/esm/components/UI/DragDrop.js +84 -0
  63. package/dist/esm/components/UI/ErrorBoundary.js +184 -0
  64. package/dist/esm/components/UI/FileUploadButton.js +34 -0
  65. package/dist/esm/components/UI/Modal.js +113 -0
  66. package/dist/esm/components/UI/Notifications.js +74 -0
  67. package/dist/esm/components/UI/SettingsDropdown.js +118 -0
  68. package/dist/esm/components/UI/index.js +60 -0
  69. package/dist/esm/components/Workflow/Workflow.js +144 -0
  70. package/dist/esm/components/Workflow/WorkflowCard.js +137 -0
  71. package/dist/esm/components/Workflow/WorkflowList.js +219 -0
  72. package/dist/esm/constants/collectionTypes.js +10 -0
  73. package/dist/esm/constants/collectionViews.js +10 -0
  74. package/dist/esm/constants/commitProps.js +10 -0
  75. package/dist/esm/constants/configSchema.js +594 -0
  76. package/dist/esm/constants/fieldInference.js +67 -0
  77. package/dist/esm/constants/publishModes.js +28 -0
  78. package/dist/esm/constants/validationErrorTypes.js +13 -0
  79. package/dist/esm/formats/formats.js +82 -0
  80. package/dist/esm/formats/frontmatter.js +163 -0
  81. package/dist/esm/formats/helpers.js +18 -0
  82. package/dist/esm/formats/json.js +15 -0
  83. package/dist/esm/formats/toml.js +40 -0
  84. package/dist/esm/formats/yaml.js +63 -0
  85. package/dist/esm/index.js +20 -0
  86. package/dist/esm/integrations/index.js +37 -0
  87. package/dist/esm/integrations/providers/algolia/implementation.js +184 -0
  88. package/dist/esm/integrations/providers/assetStore/implementation.js +175 -0
  89. package/dist/esm/lib/consoleError.js +9 -0
  90. package/dist/esm/lib/formatters.js +204 -0
  91. package/dist/esm/lib/i18n.js +381 -0
  92. package/dist/esm/lib/phrases.js +13 -0
  93. package/dist/esm/lib/registry.js +322 -0
  94. package/dist/esm/lib/serializeEntryValues.js +74 -0
  95. package/dist/esm/lib/textHelper.js +15 -0
  96. package/dist/esm/lib/urlHelper.js +128 -0
  97. package/dist/esm/mediaLibrary.js +42 -0
  98. package/dist/esm/reducers/auth.js +35 -0
  99. package/dist/esm/reducers/collections.js +424 -0
  100. package/dist/esm/reducers/combinedReducer.js +19 -0
  101. package/dist/esm/reducers/config.js +42 -0
  102. package/dist/esm/reducers/cursors.js +38 -0
  103. package/dist/esm/reducers/deploys.js +53 -0
  104. package/dist/esm/reducers/editorialWorkflow.js +98 -0
  105. package/dist/esm/reducers/entries.js +591 -0
  106. package/dist/esm/reducers/entryDraft.js +184 -0
  107. package/dist/esm/reducers/globalUI.js +32 -0
  108. package/dist/esm/reducers/index.js +84 -0
  109. package/dist/esm/reducers/integrations.js +68 -0
  110. package/dist/esm/reducers/mediaLibrary.js +265 -0
  111. package/dist/esm/reducers/medias.js +76 -0
  112. package/dist/esm/reducers/notifications.js +36 -0
  113. package/dist/esm/reducers/search.js +89 -0
  114. package/dist/esm/reducers/status.js +37 -0
  115. package/dist/esm/redux/index.js +14 -0
  116. package/dist/esm/redux/middleware/waitUntilAction.js +56 -0
  117. package/dist/esm/routing/history.js +21 -0
  118. package/dist/esm/types/diacritics.d.js +1 -0
  119. package/dist/esm/types/global.d.js +5 -0
  120. package/dist/esm/types/immutable.js +5 -0
  121. package/dist/esm/types/redux.js +16 -0
  122. package/dist/esm/types/tomlify-j0.4.d.js +1 -0
  123. package/dist/esm/valueObjects/AssetProxy.js +60 -0
  124. package/dist/esm/valueObjects/EditorComponent.js +48 -0
  125. package/dist/esm/valueObjects/Entry.js +27 -0
  126. package/index.d.ts +587 -0
  127. package/package.json +102 -0
  128. package/src/__tests__/backend.spec.js +934 -0
  129. package/src/actions/__tests__/config.spec.js +1009 -0
  130. package/src/actions/__tests__/editorialWorkflow.spec.js +216 -0
  131. package/src/actions/__tests__/entries.spec.js +575 -0
  132. package/src/actions/__tests__/media.spec.ts +171 -0
  133. package/src/actions/__tests__/mediaLibrary.spec.js +327 -0
  134. package/src/actions/__tests__/search.spec.js +209 -0
  135. package/src/actions/auth.ts +127 -0
  136. package/src/actions/collections.ts +18 -0
  137. package/src/actions/config.ts +538 -0
  138. package/src/actions/deploys.ts +104 -0
  139. package/src/actions/editorialWorkflow.ts +567 -0
  140. package/src/actions/entries.ts +1041 -0
  141. package/src/actions/media.ts +139 -0
  142. package/src/actions/mediaLibrary.ts +574 -0
  143. package/src/actions/notifications.ts +36 -0
  144. package/src/actions/search.ts +194 -0
  145. package/src/actions/status.ts +99 -0
  146. package/src/actions/waitUntil.ts +49 -0
  147. package/src/backend.ts +1342 -0
  148. package/src/bootstrap.js +102 -0
  149. package/src/components/App/App.js +280 -0
  150. package/src/components/App/Header.js +236 -0
  151. package/src/components/App/NotFoundPage.js +23 -0
  152. package/src/components/Collection/Collection.js +205 -0
  153. package/src/components/Collection/CollectionControls.js +58 -0
  154. package/src/components/Collection/CollectionSearch.js +238 -0
  155. package/src/components/Collection/CollectionTop.js +81 -0
  156. package/src/components/Collection/ControlButton.js +27 -0
  157. package/src/components/Collection/Entries/Entries.js +73 -0
  158. package/src/components/Collection/Entries/EntriesCollection.js +165 -0
  159. package/src/components/Collection/Entries/EntriesSearch.js +91 -0
  160. package/src/components/Collection/Entries/EntryCard.js +167 -0
  161. package/src/components/Collection/Entries/EntryListing.js +86 -0
  162. package/src/components/Collection/Entries/__tests__/EntriesCollection.spec.js +155 -0
  163. package/src/components/Collection/Entries/__tests__/__snapshots__/EntriesCollection.spec.js.snap +49 -0
  164. package/src/components/Collection/FilterControl.js +39 -0
  165. package/src/components/Collection/GroupControl.js +39 -0
  166. package/src/components/Collection/NestedCollection.js +309 -0
  167. package/src/components/Collection/Sidebar.js +130 -0
  168. package/src/components/Collection/SortControl.js +68 -0
  169. package/src/components/Collection/ViewStyleControl.js +50 -0
  170. package/src/components/Collection/__tests__/Collection.spec.js +75 -0
  171. package/src/components/Collection/__tests__/NestedCollection.spec.js +442 -0
  172. package/src/components/Collection/__tests__/Sidebar.spec.js +87 -0
  173. package/src/components/Collection/__tests__/__snapshots__/Collection.spec.js.snap +144 -0
  174. package/src/components/Collection/__tests__/__snapshots__/NestedCollection.spec.js.snap +550 -0
  175. package/src/components/Collection/__tests__/__snapshots__/Sidebar.spec.js.snap +308 -0
  176. package/src/components/Editor/Editor.js +494 -0
  177. package/src/components/Editor/EditorControlPane/EditorControl.js +428 -0
  178. package/src/components/Editor/EditorControlPane/EditorControlPane.js +256 -0
  179. package/src/components/Editor/EditorControlPane/Widget.js +351 -0
  180. package/src/components/Editor/EditorInterface.js +434 -0
  181. package/src/components/Editor/EditorPreviewPane/EditorPreview.js +40 -0
  182. package/src/components/Editor/EditorPreviewPane/EditorPreviewContent.js +34 -0
  183. package/src/components/Editor/EditorPreviewPane/EditorPreviewPane.js +278 -0
  184. package/src/components/Editor/EditorPreviewPane/PreviewHOC.js +33 -0
  185. package/src/components/Editor/EditorToolbar.js +678 -0
  186. package/src/components/Editor/__tests__/Editor.spec.js +219 -0
  187. package/src/components/Editor/__tests__/EditorToolbar.spec.js +120 -0
  188. package/src/components/Editor/__tests__/__snapshots__/Editor.spec.js.snap +45 -0
  189. package/src/components/Editor/__tests__/__snapshots__/EditorToolbar.spec.js.snap +4020 -0
  190. package/src/components/Editor/withWorkflow.js +61 -0
  191. package/src/components/EditorWidgets/Unknown/UnknownControl.js +17 -0
  192. package/src/components/EditorWidgets/Unknown/UnknownPreview.js +19 -0
  193. package/src/components/EditorWidgets/index.js +5 -0
  194. package/src/components/MediaLibrary/EmptyMessage.js +28 -0
  195. package/src/components/MediaLibrary/MediaLibrary.js +407 -0
  196. package/src/components/MediaLibrary/MediaLibraryButtons.js +136 -0
  197. package/src/components/MediaLibrary/MediaLibraryCard.js +128 -0
  198. package/src/components/MediaLibrary/MediaLibraryCardGrid.js +199 -0
  199. package/src/components/MediaLibrary/MediaLibraryHeader.js +48 -0
  200. package/src/components/MediaLibrary/MediaLibraryModal.js +200 -0
  201. package/src/components/MediaLibrary/MediaLibrarySearch.js +61 -0
  202. package/src/components/MediaLibrary/MediaLibraryTop.js +143 -0
  203. package/src/components/MediaLibrary/__tests__/MediaLibraryButtons.spec.js +45 -0
  204. package/src/components/MediaLibrary/__tests__/MediaLibraryCard.spec.js +49 -0
  205. package/src/components/MediaLibrary/__tests__/__snapshots__/MediaLibraryCard.spec.js.snap +216 -0
  206. package/src/components/UI/DragDrop.js +66 -0
  207. package/src/components/UI/ErrorBoundary.js +209 -0
  208. package/src/components/UI/FileUploadButton.js +24 -0
  209. package/src/components/UI/Modal.js +109 -0
  210. package/src/components/UI/Notifications.tsx +83 -0
  211. package/src/components/UI/SettingsDropdown.js +103 -0
  212. package/src/components/UI/__tests__/ErrorBoundary.spec.js +57 -0
  213. package/src/components/UI/index.js +6 -0
  214. package/src/components/Workflow/Workflow.js +166 -0
  215. package/src/components/Workflow/WorkflowCard.js +177 -0
  216. package/src/components/Workflow/WorkflowList.js +269 -0
  217. package/src/constants/__tests__/configSchema.spec.js +511 -0
  218. package/src/constants/collectionTypes.ts +2 -0
  219. package/src/constants/collectionViews.js +2 -0
  220. package/src/constants/commitProps.ts +2 -0
  221. package/src/constants/configSchema.js +399 -0
  222. package/src/constants/fieldInference.tsx +78 -0
  223. package/src/constants/publishModes.ts +22 -0
  224. package/src/constants/validationErrorTypes.js +6 -0
  225. package/src/formats/__tests__/frontmatter.spec.js +429 -0
  226. package/src/formats/__tests__/toml.spec.js +9 -0
  227. package/src/formats/__tests__/yaml.spec.js +162 -0
  228. package/src/formats/formats.ts +86 -0
  229. package/src/formats/frontmatter.ts +150 -0
  230. package/src/formats/helpers.ts +14 -0
  231. package/src/formats/json.ts +9 -0
  232. package/src/formats/toml.ts +33 -0
  233. package/src/formats/yaml.ts +58 -0
  234. package/src/index.js +8 -0
  235. package/src/integrations/index.js +35 -0
  236. package/src/integrations/providers/algolia/implementation.js +176 -0
  237. package/src/integrations/providers/assetStore/implementation.js +147 -0
  238. package/src/lib/__tests__/formatters.spec.js +723 -0
  239. package/src/lib/__tests__/i18n.spec.js +792 -0
  240. package/src/lib/__tests__/phrases.spec.js +119 -0
  241. package/src/lib/__tests__/registry.spec.js +246 -0
  242. package/src/lib/__tests__/serializeEntryValues.spec.js +22 -0
  243. package/src/lib/__tests__/urlHelper.spec.js +138 -0
  244. package/src/lib/consoleError.js +7 -0
  245. package/src/lib/formatters.ts +267 -0
  246. package/src/lib/i18n.ts +427 -0
  247. package/src/lib/phrases.js +8 -0
  248. package/src/lib/registry.js +282 -0
  249. package/src/lib/serializeEntryValues.js +75 -0
  250. package/src/lib/textHelper.js +11 -0
  251. package/src/lib/urlHelper.ts +125 -0
  252. package/src/mediaLibrary.ts +51 -0
  253. package/src/reducers/__tests__/auth.spec.ts +38 -0
  254. package/src/reducers/__tests__/collections.spec.js +571 -0
  255. package/src/reducers/__tests__/config.spec.js +38 -0
  256. package/src/reducers/__tests__/entries.spec.js +694 -0
  257. package/src/reducers/__tests__/entryDraft.spec.js +198 -0
  258. package/src/reducers/__tests__/globalUI.js +43 -0
  259. package/src/reducers/__tests__/integrations.spec.ts +76 -0
  260. package/src/reducers/__tests__/mediaLibrary.spec.js +154 -0
  261. package/src/reducers/__tests__/medias.spec.ts +49 -0
  262. package/src/reducers/auth.ts +46 -0
  263. package/src/reducers/collections.ts +483 -0
  264. package/src/reducers/combinedReducer.ts +11 -0
  265. package/src/reducers/config.ts +38 -0
  266. package/src/reducers/cursors.js +36 -0
  267. package/src/reducers/deploys.ts +52 -0
  268. package/src/reducers/editorialWorkflow.ts +163 -0
  269. package/src/reducers/entries.ts +806 -0
  270. package/src/reducers/entryDraft.js +218 -0
  271. package/src/reducers/globalUI.ts +45 -0
  272. package/src/reducers/index.ts +82 -0
  273. package/src/reducers/integrations.ts +59 -0
  274. package/src/reducers/mediaLibrary.ts +296 -0
  275. package/src/reducers/medias.ts +66 -0
  276. package/src/reducers/notifications.ts +53 -0
  277. package/src/reducers/search.ts +89 -0
  278. package/src/reducers/status.ts +40 -0
  279. package/src/redux/index.ts +18 -0
  280. package/src/redux/middleware/waitUntilAction.ts +64 -0
  281. package/src/routing/__tests__/history.spec.ts +49 -0
  282. package/src/routing/history.ts +17 -0
  283. package/src/types/diacritics.d.ts +1 -0
  284. package/src/types/global.d.ts +8 -0
  285. package/src/types/immutable.ts +39 -0
  286. package/src/types/redux.ts +810 -0
  287. package/src/types/tomlify-j0.4.d.ts +13 -0
  288. package/src/valueObjects/AssetProxy.ts +48 -0
  289. package/src/valueObjects/EditorComponent.js +38 -0
  290. package/src/valueObjects/Entry.ts +63 -0
@@ -0,0 +1,1073 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.currentBackend = exports.LocalStorageAuthStore = exports.Backend = void 0;
7
+ exports.expandSearchEntries = expandSearchEntries;
8
+ exports.extractSearchFields = extractSearchFields;
9
+ exports.mergeExpandedEntries = mergeExpandedEntries;
10
+ exports.resolveBackend = resolveBackend;
11
+ exports.slugFromCustomPath = slugFromCustomPath;
12
+ var _set2 = _interopRequireDefault(require("lodash/set"));
13
+ var _get2 = _interopRequireDefault(require("lodash/get"));
14
+ var _sortBy2 = _interopRequireDefault(require("lodash/sortBy"));
15
+ var _trim2 = _interopRequireDefault(require("lodash/trim"));
16
+ var _uniq2 = _interopRequireDefault(require("lodash/uniq"));
17
+ var _isError2 = _interopRequireDefault(require("lodash/isError"));
18
+ var _flatten2 = _interopRequireDefault(require("lodash/flatten"));
19
+ var _attempt2 = _interopRequireDefault(require("lodash/attempt"));
20
+ var _immutable = require("immutable");
21
+ var fuzzy = _interopRequireWildcard(require("fuzzy"));
22
+ var _decapCmsLibUtil = require("decap-cms-lib-util");
23
+ var _path = require("path");
24
+ var _decapCmsLibWidgets = require("decap-cms-lib-widgets");
25
+ var _formats = require("./formats/formats");
26
+ var _config = require("./reducers/config");
27
+ var _entries = require("./reducers/entries");
28
+ var _integrations = require("./reducers/integrations");
29
+ var _collections = require("./reducers/collections");
30
+ var _Entry = require("./valueObjects/Entry");
31
+ var _urlHelper = require("./lib/urlHelper");
32
+ var _registry = require("./lib/registry");
33
+ var _formatters = require("./lib/formatters");
34
+ var _publishModes = require("./constants/publishModes");
35
+ var _collectionTypes = require("./constants/collectionTypes");
36
+ var _entryDraft = require("./reducers/entryDraft");
37
+ var _i18n = require("./lib/i18n");
38
+ const _excluded = ["field"];
39
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
40
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
41
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
42
+ function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
43
+ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
44
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
45
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
46
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
47
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
48
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
49
+ const {
50
+ extractTemplateVars,
51
+ dateParsers,
52
+ expandPath
53
+ } = _decapCmsLibWidgets.stringTemplate;
54
+ function updateAssetProxies(assetProxies, config, collection, entryDraft, path) {
55
+ assetProxies.map(asset => {
56
+ // update media files path based on entry path
57
+ const oldPath = asset.path;
58
+ const newPath = (0, _entries.selectMediaFilePath)(config, collection, entryDraft.get('entry').set('path', path), oldPath, asset.field);
59
+ asset.path = newPath;
60
+ });
61
+ }
62
+ class LocalStorageAuthStore {
63
+ constructor() {
64
+ _defineProperty(this, "storageKey", 'decap-cms-user');
65
+ }
66
+ retrieve() {
67
+ const data = window.localStorage.getItem(this.storageKey);
68
+ return data && JSON.parse(data);
69
+ }
70
+ store(userData) {
71
+ window.localStorage.setItem(this.storageKey, JSON.stringify(userData));
72
+ }
73
+ logout() {
74
+ window.localStorage.removeItem(this.storageKey);
75
+ }
76
+ }
77
+ exports.LocalStorageAuthStore = LocalStorageAuthStore;
78
+ function getEntryBackupKey(collectionName, slug) {
79
+ const baseKey = 'backup';
80
+ if (!collectionName) {
81
+ return baseKey;
82
+ }
83
+ const suffix = slug ? `.${slug}` : '';
84
+ return `${baseKey}.${collectionName}${suffix}`;
85
+ }
86
+ function getEntryField(field, entry) {
87
+ const value = (0, _get2.default)(entry.data, field);
88
+ if (value) {
89
+ return String(value);
90
+ } else {
91
+ const firstFieldPart = field.split('.')[0];
92
+ if (entry[firstFieldPart]) {
93
+ // allows searching using entry.slug/entry.path etc.
94
+ return entry[firstFieldPart];
95
+ } else {
96
+ return '';
97
+ }
98
+ }
99
+ }
100
+ function extractSearchFields(searchFields) {
101
+ return entry => searchFields.reduce((acc, field) => {
102
+ const value = getEntryField(field, entry);
103
+ if (value) {
104
+ return `${acc} ${value}`;
105
+ } else {
106
+ return acc;
107
+ }
108
+ }, '');
109
+ }
110
+ function expandSearchEntries(entries, searchFields) {
111
+ // expand the entries for the purpose of the search
112
+ const expandedEntries = entries.reduce((acc, e) => {
113
+ const expandedFields = searchFields.reduce((acc, f) => {
114
+ const fields = expandPath({
115
+ data: e.data,
116
+ path: f
117
+ });
118
+ acc.push(...fields);
119
+ return acc;
120
+ }, []);
121
+ for (let i = 0; i < expandedFields.length; i++) {
122
+ acc.push(_objectSpread(_objectSpread({}, e), {}, {
123
+ field: expandedFields[i]
124
+ }));
125
+ }
126
+ return acc;
127
+ }, []);
128
+ return expandedEntries;
129
+ }
130
+ function mergeExpandedEntries(entries) {
131
+ // merge the search results by slug and only keep data that matched the search
132
+ const fields = entries.map(f => f.field);
133
+ const arrayPaths = {};
134
+ const merged = entries.reduce((acc, e) => {
135
+ if (!acc[e.slug]) {
136
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
137
+ const {
138
+ field
139
+ } = e,
140
+ rest = _objectWithoutProperties(e, _excluded);
141
+ acc[e.slug] = rest;
142
+ arrayPaths[e.slug] = (0, _immutable.Set)();
143
+ }
144
+ const nestedFields = e.field.split('.');
145
+ let value = acc[e.slug].data;
146
+ for (let i = 0; i < nestedFields.length; i++) {
147
+ value = value[nestedFields[i]];
148
+ if (Array.isArray(value)) {
149
+ const path = nestedFields.slice(0, i + 1).join('.');
150
+ arrayPaths[e.slug] = arrayPaths[e.slug].add(path);
151
+ }
152
+ }
153
+ return acc;
154
+ }, {});
155
+
156
+ // this keeps the search score sorting order designated by the order in entries
157
+ // and filters non matching items
158
+ Object.keys(merged).forEach(slug => {
159
+ const data = merged[slug].data;
160
+ for (const path of arrayPaths[slug].toArray()) {
161
+ const array = (0, _get2.default)(data, path);
162
+ const filtered = array.filter((_, index) => {
163
+ return fields.some(f => `${f}.`.startsWith(`${path}.${index}.`));
164
+ });
165
+ filtered.sort((a, b) => {
166
+ const indexOfA = array.indexOf(a);
167
+ const indexOfB = array.indexOf(b);
168
+ const pathOfA = `${path}.${indexOfA}.`;
169
+ const pathOfB = `${path}.${indexOfB}.`;
170
+ const matchingFieldIndexA = fields.findIndex(f => `${f}.`.startsWith(pathOfA));
171
+ const matchingFieldIndexB = fields.findIndex(f => `${f}.`.startsWith(pathOfB));
172
+ return matchingFieldIndexA - matchingFieldIndexB;
173
+ });
174
+ (0, _set2.default)(data, path, filtered);
175
+ }
176
+ });
177
+ return Object.values(merged);
178
+ }
179
+ function sortByScore(a, b) {
180
+ if (a.score > b.score) return -1;
181
+ if (a.score < b.score) return 1;
182
+ return 0;
183
+ }
184
+ function slugFromCustomPath(collection, customPath) {
185
+ const folderPath = collection.get('folder', '');
186
+ const entryPath = customPath.toLowerCase().replace(folderPath.toLowerCase(), '');
187
+ const slug = (0, _path.join)((0, _path.dirname)((0, _trim2.default)(entryPath, '/')), (0, _path.basename)(entryPath, (0, _path.extname)(customPath)));
188
+ return slug;
189
+ }
190
+ function prepareMetaPath(path, collection) {
191
+ if (!(0, _collections.selectHasMetaPath)(collection)) {
192
+ return path;
193
+ }
194
+ const dir = (0, _path.dirname)(path);
195
+ return dir.slice(collection.get('folder').length + 1) || '/';
196
+ }
197
+ function collectionDepth(collection) {
198
+ var _collection$get;
199
+ let depth;
200
+ depth = ((_collection$get = collection.get('nested')) === null || _collection$get === void 0 ? void 0 : _collection$get.get('depth')) || (0, _decapCmsLibUtil.getPathDepth)(collection.get('path', ''));
201
+ if ((0, _i18n.hasI18n)(collection)) {
202
+ depth = (0, _i18n.getI18nFilesDepth)(collection, depth);
203
+ }
204
+ return depth;
205
+ }
206
+ class Backend {
207
+ constructor(implementation, {
208
+ backendName,
209
+ authStore,
210
+ config
211
+ }) {
212
+ _defineProperty(this, "implementation", void 0);
213
+ _defineProperty(this, "backendName", void 0);
214
+ _defineProperty(this, "config", void 0);
215
+ _defineProperty(this, "authStore", void 0);
216
+ _defineProperty(this, "user", void 0);
217
+ _defineProperty(this, "backupSync", void 0);
218
+ _defineProperty(this, "updateUserCredentials", updatedCredentials => {
219
+ const storedUser = this.authStore.retrieve();
220
+ if (storedUser && storedUser.backendName === this.backendName) {
221
+ this.user = _objectSpread(_objectSpread({}, storedUser), updatedCredentials);
222
+ this.authStore.store(this.user);
223
+ return this.user;
224
+ }
225
+ });
226
+ _defineProperty(this, "getToken", () => this.implementation.getToken());
227
+ // We can't reliably run this on exit, so we do cleanup on load.
228
+ this.deleteAnonymousBackup();
229
+ this.config = config;
230
+ this.implementation = implementation.init(this.config, {
231
+ useWorkflow: (0, _config.selectUseWorkflow)(this.config),
232
+ updateUserCredentials: this.updateUserCredentials,
233
+ initialWorkflowStatus: _publishModes.status.first()
234
+ });
235
+ this.backendName = backendName;
236
+ this.authStore = authStore;
237
+ if (this.implementation === null) {
238
+ throw new Error('Cannot instantiate a Backend with no implementation');
239
+ }
240
+ this.backupSync = (0, _decapCmsLibUtil.asyncLock)();
241
+ }
242
+ async status() {
243
+ const attempts = 3;
244
+ let status = {
245
+ auth: {
246
+ status: true
247
+ },
248
+ api: {
249
+ status: true,
250
+ statusPage: ''
251
+ }
252
+ };
253
+ for (let i = 1; i <= attempts; i++) {
254
+ status = await this.implementation.status();
255
+ // return on first success
256
+ if (Object.values(status).every(s => s.status === true)) {
257
+ return status;
258
+ } else {
259
+ await new Promise(resolve => setTimeout(resolve, i * 1000));
260
+ }
261
+ }
262
+ return status;
263
+ }
264
+ currentUser() {
265
+ if (this.user) {
266
+ return this.user;
267
+ }
268
+ const stored = this.authStore.retrieve();
269
+ if (stored && stored.backendName === this.backendName) {
270
+ return Promise.resolve(this.implementation.restoreUser(stored)).then(user => {
271
+ this.user = _objectSpread(_objectSpread({}, user), {}, {
272
+ backendName: this.backendName
273
+ });
274
+ // return confirmed/rehydrated user object instead of stored
275
+ this.authStore.store(this.user);
276
+ return this.user;
277
+ });
278
+ }
279
+ return Promise.resolve(null);
280
+ }
281
+ isGitBackend() {
282
+ var _this$implementation$, _this$implementation;
283
+ return ((_this$implementation$ = (_this$implementation = this.implementation).isGitBackend) === null || _this$implementation$ === void 0 ? void 0 : _this$implementation$.call(_this$implementation)) || false;
284
+ }
285
+ authComponent() {
286
+ return this.implementation.authComponent();
287
+ }
288
+ authenticate(credentials) {
289
+ return this.implementation.authenticate(credentials).then(user => {
290
+ this.user = _objectSpread(_objectSpread({}, user), {}, {
291
+ backendName: this.backendName
292
+ });
293
+ if (this.authStore) {
294
+ this.authStore.store(this.user);
295
+ }
296
+ return this.user;
297
+ });
298
+ }
299
+ async logout() {
300
+ try {
301
+ await this.implementation.logout();
302
+ } catch (e) {
303
+ console.warn('Error during logout', e.message);
304
+ } finally {
305
+ this.user = null;
306
+ if (this.authStore) {
307
+ this.authStore.logout();
308
+ }
309
+ }
310
+ }
311
+ async entryExist(collection, path, slug, useWorkflow) {
312
+ const unpublishedEntry = useWorkflow && (await this.implementation.unpublishedEntry({
313
+ collection: collection.get('name'),
314
+ slug
315
+ }).catch(error => {
316
+ if (error.name === _decapCmsLibUtil.EDITORIAL_WORKFLOW_ERROR && error.notUnderEditorialWorkflow) {
317
+ return Promise.resolve(false);
318
+ }
319
+ return Promise.reject(error);
320
+ }));
321
+ if (unpublishedEntry) return unpublishedEntry;
322
+ const publishedEntry = await this.implementation.getEntry(path).then(({
323
+ data
324
+ }) => data).catch(() => {
325
+ return Promise.resolve(false);
326
+ });
327
+ return publishedEntry;
328
+ }
329
+ async generateUniqueSlug(collection, entryData, config, usedSlugs, customPath) {
330
+ const slugConfig = config.slug;
331
+ let slug;
332
+ if (customPath) {
333
+ slug = slugFromCustomPath(collection, customPath);
334
+ } else {
335
+ slug = (0, _formatters.slugFormatter)(collection, entryData, slugConfig);
336
+ }
337
+ let i = 1;
338
+ let uniqueSlug = slug;
339
+
340
+ // Check for duplicate slug in loaded entities store first before repo
341
+ while (usedSlugs.includes(uniqueSlug) || (await this.entryExist(collection, (0, _collections.selectEntryPath)(collection, uniqueSlug), uniqueSlug, (0, _config.selectUseWorkflow)(config)))) {
342
+ uniqueSlug = `${slug}${(0, _urlHelper.sanitizeChar)(' ', slugConfig)}${i++}`;
343
+ }
344
+ return uniqueSlug;
345
+ }
346
+ processEntries(loadedEntries, collection) {
347
+ const entries = loadedEntries.map(loadedEntry => (0, _Entry.createEntry)(collection.get('name'), (0, _collections.selectEntrySlug)(collection, loadedEntry.file.path), loadedEntry.file.path, {
348
+ raw: loadedEntry.data || '',
349
+ label: loadedEntry.file.label,
350
+ author: loadedEntry.file.author,
351
+ updatedOn: loadedEntry.file.updatedOn,
352
+ meta: {
353
+ path: prepareMetaPath(loadedEntry.file.path, collection)
354
+ }
355
+ }));
356
+ const formattedEntries = entries.map(this.entryWithFormat(collection));
357
+ // If this collection has a "filter" property, filter entries accordingly
358
+ const collectionFilter = collection.get('filter');
359
+ const filteredEntries = collectionFilter ? this.filterEntries({
360
+ entries: formattedEntries
361
+ }, collectionFilter) : formattedEntries;
362
+ if ((0, _i18n.hasI18n)(collection)) {
363
+ const extension = (0, _collections.selectFolderEntryExtension)(collection);
364
+ const groupedEntries = (0, _i18n.groupEntries)(collection, extension, filteredEntries);
365
+ return groupedEntries;
366
+ }
367
+ return filteredEntries;
368
+ }
369
+ async listEntries(collection) {
370
+ var _cursor$meta;
371
+ const extension = (0, _collections.selectFolderEntryExtension)(collection);
372
+ let listMethod;
373
+ const collectionType = collection.get('type');
374
+ if (collectionType === _collectionTypes.FOLDER) {
375
+ listMethod = () => {
376
+ const depth = collectionDepth(collection);
377
+ return this.implementation.entriesByFolder(collection.get('folder'), extension, depth);
378
+ };
379
+ } else if (collectionType === _collectionTypes.FILES) {
380
+ const files = collection.get('files').map(collectionFile => ({
381
+ path: collectionFile.get('file'),
382
+ label: collectionFile.get('label')
383
+ })).toArray();
384
+ listMethod = () => this.implementation.entriesByFiles(files);
385
+ } else {
386
+ throw new Error(`Unknown collection type: ${collectionType}`);
387
+ }
388
+ const loadedEntries = await listMethod();
389
+ /*
390
+ Wrap cursors so we can tell which collection the cursor is
391
+ from. This is done to prevent traverseCursor from requiring a
392
+ `collection` argument.
393
+ */
394
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
395
+ // @ts-ignore
396
+ const cursor = _decapCmsLibUtil.Cursor.create(loadedEntries[_decapCmsLibUtil.CURSOR_COMPATIBILITY_SYMBOL]).wrapData({
397
+ cursorType: 'collectionEntries',
398
+ collection
399
+ });
400
+ return {
401
+ entries: this.processEntries(loadedEntries, collection),
402
+ pagination: (_cursor$meta = cursor.meta) === null || _cursor$meta === void 0 ? void 0 : _cursor$meta.get('page'),
403
+ cursor
404
+ };
405
+ }
406
+
407
+ // The same as listEntries, except that if a cursor with the "next"
408
+ // action available is returned, it calls "next" on the cursor and
409
+ // repeats the process. Once there is no available "next" action, it
410
+ // returns all the collected entries. Used to retrieve all entries
411
+ // for local searches and queries.
412
+ async listAllEntries(collection) {
413
+ if (collection.get('folder') && this.implementation.allEntriesByFolder) {
414
+ const depth = collectionDepth(collection);
415
+ const extension = (0, _collections.selectFolderEntryExtension)(collection);
416
+ return this.implementation.allEntriesByFolder(collection.get('folder'), extension, depth).then(entries => this.processEntries(entries, collection));
417
+ }
418
+ const response = await this.listEntries(collection);
419
+ const {
420
+ entries
421
+ } = response;
422
+ let {
423
+ cursor
424
+ } = response;
425
+ while (cursor && cursor.actions.includes('next')) {
426
+ const {
427
+ entries: newEntries,
428
+ cursor: newCursor
429
+ } = await this.traverseCursor(cursor, 'next');
430
+ entries.push(...newEntries);
431
+ cursor = newCursor;
432
+ }
433
+ return entries;
434
+ }
435
+ async search(collections, searchTerm) {
436
+ // Perform a local search by requesting all entries. For each
437
+ // collection, load it, search, and call onCollectionResults with
438
+ // its results.
439
+ const errors = [];
440
+ const collectionEntriesRequests = collections.map(async collection => {
441
+ const summary = collection.get('summary', '');
442
+ const summaryFields = extractTemplateVars(summary);
443
+
444
+ // TODO: pass search fields in as an argument
445
+ let searchFields = [];
446
+ if (collection.get('type') === _collectionTypes.FILES) {
447
+ var _collection$get2;
448
+ (_collection$get2 = collection.get('files')) === null || _collection$get2 === void 0 ? void 0 : _collection$get2.forEach(f => {
449
+ const topLevelFields = f.get('fields').map(f => f.get('name')).toArray();
450
+ searchFields = [...searchFields, ...topLevelFields];
451
+ });
452
+ } else {
453
+ searchFields = [(0, _collections.selectInferedField)(collection, 'title'), (0, _collections.selectInferedField)(collection, 'shortTitle'), (0, _collections.selectInferedField)(collection, 'author'), ...summaryFields.map(elem => {
454
+ if (dateParsers[elem]) {
455
+ return (0, _collections.selectInferedField)(collection, 'date');
456
+ }
457
+ return elem;
458
+ })];
459
+ }
460
+ const filteredSearchFields = searchFields.filter(Boolean);
461
+ const collectionEntries = await this.listAllEntries(collection);
462
+ return fuzzy.filter(searchTerm, collectionEntries, {
463
+ extract: extractSearchFields((0, _uniq2.default)(filteredSearchFields))
464
+ });
465
+ }).map(p => p.catch(err => {
466
+ errors.push(err);
467
+ return [];
468
+ }));
469
+ const entries = await Promise.all(collectionEntriesRequests).then(arrays => (0, _flatten2.default)(arrays));
470
+ if (errors.length > 0) {
471
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
472
+ // @ts-ignore
473
+ throw new Error({
474
+ message: 'Errors ocurred while searching entries locally!',
475
+ errors
476
+ });
477
+ }
478
+ const hits = entries.filter(({
479
+ score
480
+ }) => score > 5).sort(sortByScore).map(f => f.original);
481
+ return {
482
+ entries: hits
483
+ };
484
+ }
485
+ async query(collection, searchFields, searchTerm, file, limit) {
486
+ let entries = await this.listAllEntries(collection);
487
+ if (file) {
488
+ entries = entries.filter(e => e.slug === file);
489
+ }
490
+ const expandedEntries = expandSearchEntries(entries, searchFields);
491
+ let hits = fuzzy.filter(searchTerm, expandedEntries, {
492
+ extract: entry => {
493
+ return getEntryField(entry.field, entry);
494
+ }
495
+ }).sort(sortByScore).map(f => f.original);
496
+ if (limit !== undefined && limit > 0) {
497
+ hits = hits.slice(0, limit);
498
+ }
499
+ const merged = mergeExpandedEntries(hits);
500
+ return {
501
+ query: searchTerm,
502
+ hits: merged
503
+ };
504
+ }
505
+ traverseCursor(cursor, action) {
506
+ const [data, unwrappedCursor] = cursor.unwrapData();
507
+ // TODO: stop assuming all cursors are for collections
508
+ const collection = data.get('collection');
509
+ return this.implementation.traverseCursor(unwrappedCursor, action).then(async ({
510
+ entries,
511
+ cursor: newCursor
512
+ }) => ({
513
+ entries: this.processEntries(entries, collection),
514
+ cursor: _decapCmsLibUtil.Cursor.create(newCursor).wrapData({
515
+ cursorType: 'collectionEntries',
516
+ collection
517
+ })
518
+ }));
519
+ }
520
+ async getLocalDraftBackup(collection, slug) {
521
+ const key = getEntryBackupKey(collection.get('name'), slug);
522
+ const backup = await _decapCmsLibUtil.localForage.getItem(key);
523
+ if (!backup || !backup.raw.trim()) {
524
+ return {};
525
+ }
526
+ const {
527
+ raw,
528
+ path
529
+ } = backup;
530
+ let {
531
+ mediaFiles = []
532
+ } = backup;
533
+ mediaFiles = mediaFiles.map(file => {
534
+ // de-serialize the file object
535
+ if (file.file) {
536
+ return _objectSpread(_objectSpread({}, file), {}, {
537
+ url: URL.createObjectURL(file.file)
538
+ });
539
+ }
540
+ return file;
541
+ });
542
+ const label = (0, _collections.selectFileEntryLabel)(collection, slug);
543
+ const formatRawData = raw => {
544
+ return this.entryWithFormat(collection)((0, _Entry.createEntry)(collection.get('name'), slug, path, {
545
+ raw,
546
+ label,
547
+ mediaFiles,
548
+ meta: {
549
+ path: prepareMetaPath(path, collection)
550
+ }
551
+ }));
552
+ };
553
+ const entry = formatRawData(raw);
554
+ if ((0, _i18n.hasI18n)(collection) && backup.i18n) {
555
+ const i18n = (0, _i18n.formatI18nBackup)(backup.i18n, formatRawData);
556
+ entry.i18n = i18n;
557
+ }
558
+ return {
559
+ entry
560
+ };
561
+ }
562
+ async persistLocalDraftBackup(entry, collection) {
563
+ try {
564
+ await this.backupSync.acquire();
565
+ const key = getEntryBackupKey(collection.get('name'), entry.get('slug'));
566
+ const raw = this.entryToRaw(collection, entry);
567
+ if (!raw.trim()) {
568
+ return;
569
+ }
570
+ const mediaFiles = await Promise.all(entry.get('mediaFiles').toJS().map(async file => {
571
+ var _file$url;
572
+ // make sure to serialize the file
573
+ if ((_file$url = file.url) !== null && _file$url !== void 0 && _file$url.startsWith('blob:')) {
574
+ const blob = await fetch(file.url).then(res => res.blob());
575
+ return _objectSpread(_objectSpread({}, file), {}, {
576
+ file: (0, _decapCmsLibUtil.blobToFileObj)(file.name, blob)
577
+ });
578
+ }
579
+ return file;
580
+ }));
581
+ let i18n;
582
+ if ((0, _i18n.hasI18n)(collection)) {
583
+ i18n = (0, _i18n.getI18nBackup)(collection, entry, entry => this.entryToRaw(collection, entry));
584
+ }
585
+ await _decapCmsLibUtil.localForage.setItem(key, _objectSpread({
586
+ raw,
587
+ path: entry.get('path'),
588
+ mediaFiles
589
+ }, i18n && {
590
+ i18n
591
+ }));
592
+ const result = await _decapCmsLibUtil.localForage.setItem(getEntryBackupKey(), raw);
593
+ return result;
594
+ } catch (e) {
595
+ console.warn('persistLocalDraftBackup', e);
596
+ } finally {
597
+ this.backupSync.release();
598
+ }
599
+ }
600
+ async deleteLocalDraftBackup(collection, slug) {
601
+ try {
602
+ await this.backupSync.acquire();
603
+ await _decapCmsLibUtil.localForage.removeItem(getEntryBackupKey(collection.get('name'), slug));
604
+ // delete new entry backup if not deleted
605
+ slug && (await _decapCmsLibUtil.localForage.removeItem(getEntryBackupKey(collection.get('name'))));
606
+ const result = await this.deleteAnonymousBackup();
607
+ return result;
608
+ } catch (e) {
609
+ console.warn('deleteLocalDraftBackup', e);
610
+ } finally {
611
+ this.backupSync.release();
612
+ }
613
+ }
614
+
615
+ // Unnamed backup for use in the global error boundary, should always be
616
+ // deleted on cms load.
617
+ deleteAnonymousBackup() {
618
+ return _decapCmsLibUtil.localForage.removeItem(getEntryBackupKey());
619
+ }
620
+ async getEntry(state, collection, slug) {
621
+ const path = (0, _collections.selectEntryPath)(collection, slug);
622
+ const label = (0, _collections.selectFileEntryLabel)(collection, slug);
623
+ const extension = (0, _collections.selectFolderEntryExtension)(collection);
624
+ const getEntryValue = async path => {
625
+ const loadedEntry = await this.implementation.getEntry(path);
626
+ let entry = (0, _Entry.createEntry)(collection.get('name'), slug, loadedEntry.file.path, {
627
+ raw: loadedEntry.data,
628
+ label,
629
+ mediaFiles: [],
630
+ meta: {
631
+ path: prepareMetaPath(loadedEntry.file.path, collection)
632
+ }
633
+ });
634
+ entry = this.entryWithFormat(collection)(entry);
635
+ entry = await this.processEntry(state, collection, entry);
636
+ return entry;
637
+ };
638
+ let entryValue;
639
+ if ((0, _i18n.hasI18n)(collection)) {
640
+ entryValue = await (0, _i18n.getI18nEntry)(collection, extension, path, slug, getEntryValue);
641
+ } else {
642
+ entryValue = await getEntryValue(path);
643
+ }
644
+ return entryValue;
645
+ }
646
+ getMedia() {
647
+ return this.implementation.getMedia();
648
+ }
649
+ getMediaFile(path) {
650
+ return this.implementation.getMediaFile(path);
651
+ }
652
+ getMediaDisplayURL(displayURL) {
653
+ if (this.implementation.getMediaDisplayURL) {
654
+ return this.implementation.getMediaDisplayURL(displayURL);
655
+ }
656
+ const err = new Error('getMediaDisplayURL is not implemented by the current backend, but the backend returned a displayURL which was not a string!');
657
+ err.displayURL = displayURL;
658
+ return Promise.reject(err);
659
+ }
660
+ entryWithFormat(collection) {
661
+ return entry => {
662
+ const format = (0, _formats.resolveFormat)(collection, entry);
663
+ if (entry && entry.raw !== undefined) {
664
+ const data = format && (0, _attempt2.default)(format.fromFile.bind(format, entry.raw)) || {};
665
+ if ((0, _isError2.default)(data)) console.error(data);
666
+ return Object.assign(entry, {
667
+ data: (0, _isError2.default)(data) ? {} : data
668
+ });
669
+ }
670
+ return format.fromFile(entry);
671
+ };
672
+ }
673
+ async processUnpublishedEntry(collection, entryData, withMediaFiles) {
674
+ const {
675
+ slug
676
+ } = entryData;
677
+ let extension;
678
+ if (collection.get('type') === _collectionTypes.FILES) {
679
+ const file = collection.get('files').find(f => (f === null || f === void 0 ? void 0 : f.get('name')) === slug);
680
+ extension = (0, _path.extname)(file.get('file'));
681
+ } else {
682
+ extension = (0, _collections.selectFolderEntryExtension)(collection);
683
+ }
684
+ const mediaFiles = [];
685
+ if (withMediaFiles) {
686
+ const nonDataFiles = entryData.diffs.filter(d => !d.path.endsWith(extension));
687
+ const files = await Promise.all(nonDataFiles.map(f => this.implementation.unpublishedEntryMediaFile(collection.get('name'), slug, f.path, f.id)));
688
+ mediaFiles.push(...files.map(f => _objectSpread(_objectSpread({}, f), {}, {
689
+ draft: true
690
+ })));
691
+ }
692
+ const dataFiles = (0, _sortBy2.default)(entryData.diffs.filter(d => d.path.endsWith(extension)), f => f.path.length);
693
+ const formatData = (data, path, newFile) => {
694
+ const entry = (0, _Entry.createEntry)(collection.get('name'), slug, path, {
695
+ raw: data,
696
+ isModification: !newFile,
697
+ label: collection && (0, _collections.selectFileEntryLabel)(collection, slug),
698
+ mediaFiles,
699
+ updatedOn: entryData.updatedAt,
700
+ author: entryData.pullRequestAuthor,
701
+ status: entryData.status,
702
+ meta: {
703
+ path: prepareMetaPath(path, collection)
704
+ }
705
+ });
706
+ const entryWithFormat = this.entryWithFormat(collection)(entry);
707
+ return entryWithFormat;
708
+ };
709
+ const readAndFormatDataFile = async dataFile => {
710
+ const data = await this.implementation.unpublishedEntryDataFile(collection.get('name'), entryData.slug, dataFile.path, dataFile.id);
711
+ const entryWithFormat = formatData(data, dataFile.path, dataFile.newFile);
712
+ return entryWithFormat;
713
+ };
714
+
715
+ // if the unpublished entry has no diffs, return the original
716
+ if (dataFiles.length <= 0) {
717
+ const loadedEntry = await this.implementation.getEntry((0, _collections.selectEntryPath)(collection, slug));
718
+ return formatData(loadedEntry.data, loadedEntry.file.path, false);
719
+ } else if ((0, _i18n.hasI18n)(collection)) {
720
+ // we need to read all locales files and not just the changes
721
+ const path = (0, _collections.selectEntryPath)(collection, slug);
722
+ const i18nFiles = (0, _i18n.getI18nDataFiles)(collection, extension, path, slug, dataFiles);
723
+ let entries = await Promise.all(i18nFiles.map(dataFile => readAndFormatDataFile(dataFile).catch(() => null)));
724
+ entries = entries.filter(Boolean);
725
+ const grouped = await (0, _i18n.groupEntries)(collection, extension, entries);
726
+ return grouped[0];
727
+ } else {
728
+ const entryWithFormat = await readAndFormatDataFile(dataFiles[0]);
729
+ return entryWithFormat;
730
+ }
731
+ }
732
+ async unpublishedEntries(collections) {
733
+ const ids = await this.implementation.unpublishedEntries();
734
+ const entries = (await Promise.all(ids.map(async id => {
735
+ const entryData = await this.implementation.unpublishedEntry({
736
+ id
737
+ });
738
+ const collectionName = entryData.collection;
739
+ const collection = collections.find(c => c.get('name') === collectionName);
740
+ if (!collection) {
741
+ console.warn(`Missing collection '${collectionName}' for unpublished entry '${id}'`);
742
+ return null;
743
+ }
744
+ const entry = await this.processUnpublishedEntry(collection, entryData, false);
745
+ return entry;
746
+ }))).filter(Boolean);
747
+ return {
748
+ pagination: 0,
749
+ entries
750
+ };
751
+ }
752
+ async processEntry(state, collection, entry) {
753
+ const integration = (0, _integrations.selectIntegration)(state.integrations, null, 'assetStore');
754
+ const mediaFolders = (0, _collections.selectMediaFolders)(state.config, collection, (0, _immutable.fromJS)(entry));
755
+ if (mediaFolders.length > 0 && !integration) {
756
+ const files = await Promise.all(mediaFolders.map(folder => this.implementation.getMedia(folder)));
757
+ entry.mediaFiles = entry.mediaFiles.concat(...files);
758
+ } else {
759
+ entry.mediaFiles = entry.mediaFiles.concat(state.mediaLibrary.get('files') || []);
760
+ }
761
+ return entry;
762
+ }
763
+ async unpublishedEntry(state, collection, slug) {
764
+ const entryData = await this.implementation.unpublishedEntry({
765
+ collection: collection.get('name'),
766
+ slug
767
+ });
768
+ let entry = await this.processUnpublishedEntry(collection, entryData, true);
769
+ entry = await this.processEntry(state, collection, entry);
770
+ return entry;
771
+ }
772
+
773
+ /**
774
+ * Creates a URL using `site_url` from the config and `preview_path` from the
775
+ * entry's collection. Does not currently make a request through the backend,
776
+ * but likely will in the future.
777
+ */
778
+ getDeploy(collection, slug, entry) {
779
+ /**
780
+ * If `site_url` is undefined or `show_preview_links` in the config is set to false, do nothing.
781
+ */
782
+
783
+ const baseUrl = this.config.site_url;
784
+ if (!baseUrl || this.config.show_preview_links === false) {
785
+ return;
786
+ }
787
+ return {
788
+ url: (0, _formatters.previewUrlFormatter)(baseUrl, collection, slug, entry, this.config.slug),
789
+ status: 'SUCCESS'
790
+ };
791
+ }
792
+
793
+ /**
794
+ * Requests a base URL from the backend for previewing a specific entry.
795
+ * Supports polling via `maxAttempts` and `interval` options, as there is
796
+ * often a delay before a preview URL is available.
797
+ */
798
+ async getDeployPreview(collection, slug, entry, {
799
+ maxAttempts = 1,
800
+ interval = 5000
801
+ } = {}) {
802
+ /**
803
+ * If the registered backend does not provide a `getDeployPreview` method, or
804
+ * `show_preview_links` in the config is set to false, do nothing.
805
+ */
806
+ if (!this.implementation.getDeployPreview || this.config.show_preview_links === false) {
807
+ return;
808
+ }
809
+
810
+ /**
811
+ * Poll for the deploy preview URL (defaults to 1 attempt, so no polling by
812
+ * default).
813
+ */
814
+ let deployPreview,
815
+ count = 0;
816
+ while (!deployPreview && count < maxAttempts) {
817
+ count++;
818
+ deployPreview = await this.implementation.getDeployPreview(collection.get('name'), slug);
819
+ if (!deployPreview) {
820
+ await new Promise(resolve => setTimeout(() => resolve(undefined), interval));
821
+ }
822
+ }
823
+
824
+ /**
825
+ * If there's no deploy preview, do nothing.
826
+ */
827
+ if (!deployPreview) {
828
+ return;
829
+ }
830
+ return {
831
+ /**
832
+ * Create a URL using the collection `preview_path`, if provided.
833
+ */
834
+ url: (0, _formatters.previewUrlFormatter)(deployPreview.url, collection, slug, entry, this.config.slug),
835
+ /**
836
+ * Always capitalize the status for consistency.
837
+ */
838
+ status: deployPreview.status ? deployPreview.status.toUpperCase() : ''
839
+ };
840
+ }
841
+ async persistEntry({
842
+ config,
843
+ collection,
844
+ entryDraft: draft,
845
+ assetProxies,
846
+ usedSlugs,
847
+ unpublished = false,
848
+ status
849
+ }) {
850
+ const modifiedData = await this.invokePreSaveEvent(draft.get('entry'));
851
+ const entryDraft = modifiedData && draft.setIn(['entry', 'data'], modifiedData) || draft;
852
+ const newEntry = entryDraft.getIn(['entry', 'newRecord']) || false;
853
+ const useWorkflow = (0, _config.selectUseWorkflow)(config);
854
+ const customPath = (0, _entryDraft.selectCustomPath)(collection, entryDraft);
855
+ let dataFile;
856
+ if (newEntry) {
857
+ if (!(0, _collections.selectAllowNewEntries)(collection)) {
858
+ throw new Error('Not allowed to create new entries in this collection');
859
+ }
860
+ const slug = await this.generateUniqueSlug(collection, entryDraft.getIn(['entry', 'data']), config, usedSlugs, customPath);
861
+ const path = customPath || (0, _collections.selectEntryPath)(collection, slug);
862
+ dataFile = {
863
+ path,
864
+ slug,
865
+ raw: this.entryToRaw(collection, entryDraft.get('entry'))
866
+ };
867
+ updateAssetProxies(assetProxies, config, collection, entryDraft, path);
868
+ } else {
869
+ const slug = entryDraft.getIn(['entry', 'slug']);
870
+ dataFile = {
871
+ path: entryDraft.getIn(['entry', 'path']),
872
+ // for workflow entries we refresh the slug on publish
873
+ slug: customPath && !useWorkflow ? slugFromCustomPath(collection, customPath) : slug,
874
+ raw: this.entryToRaw(collection, entryDraft.get('entry')),
875
+ newPath: customPath
876
+ };
877
+ }
878
+ const {
879
+ slug,
880
+ path,
881
+ newPath
882
+ } = dataFile;
883
+ let dataFiles = [dataFile];
884
+ if ((0, _i18n.hasI18n)(collection)) {
885
+ const extension = (0, _collections.selectFolderEntryExtension)(collection);
886
+ dataFiles = (0, _i18n.getI18nFiles)(collection, extension, entryDraft.get('entry'), draftData => this.entryToRaw(collection, draftData), path, slug, newPath);
887
+ }
888
+ const user = await this.currentUser();
889
+ const commitMessage = (0, _formatters.commitMessageFormatter)(newEntry ? 'create' : 'update', config, {
890
+ collection,
891
+ slug,
892
+ path,
893
+ authorLogin: user.login,
894
+ authorName: user.name
895
+ }, user.useOpenAuthoring);
896
+ const collectionName = collection.get('name');
897
+ const updatedOptions = {
898
+ unpublished,
899
+ status
900
+ };
901
+ const opts = _objectSpread({
902
+ newEntry,
903
+ commitMessage,
904
+ collectionName,
905
+ useWorkflow
906
+ }, updatedOptions);
907
+ if (!useWorkflow) {
908
+ await this.invokePrePublishEvent(entryDraft.get('entry'));
909
+ }
910
+ await this.implementation.persistEntry({
911
+ dataFiles,
912
+ assets: assetProxies
913
+ }, opts);
914
+ await this.invokePostSaveEvent(entryDraft.get('entry'));
915
+ if (!useWorkflow) {
916
+ await this.invokePostPublishEvent(entryDraft.get('entry'));
917
+ }
918
+ return slug;
919
+ }
920
+ async invokeEventWithEntry(event, entry) {
921
+ const {
922
+ login,
923
+ name
924
+ } = await this.currentUser();
925
+ return await (0, _registry.invokeEvent)({
926
+ name: event,
927
+ data: {
928
+ entry,
929
+ author: {
930
+ login,
931
+ name
932
+ }
933
+ }
934
+ });
935
+ }
936
+ async invokePrePublishEvent(entry) {
937
+ await this.invokeEventWithEntry('prePublish', entry);
938
+ }
939
+ async invokePostPublishEvent(entry) {
940
+ await this.invokeEventWithEntry('postPublish', entry);
941
+ }
942
+ async invokePreUnpublishEvent(entry) {
943
+ await this.invokeEventWithEntry('preUnpublish', entry);
944
+ }
945
+ async invokePostUnpublishEvent(entry) {
946
+ await this.invokeEventWithEntry('postUnpublish', entry);
947
+ }
948
+ async invokePreSaveEvent(entry) {
949
+ return await this.invokeEventWithEntry('preSave', entry);
950
+ }
951
+ async invokePostSaveEvent(entry) {
952
+ await this.invokeEventWithEntry('postSave', entry);
953
+ }
954
+ async persistMedia(config, file) {
955
+ const user = await this.currentUser();
956
+ const options = {
957
+ commitMessage: (0, _formatters.commitMessageFormatter)('uploadMedia', config, {
958
+ path: file.path,
959
+ authorLogin: user.login,
960
+ authorName: user.name
961
+ }, user.useOpenAuthoring)
962
+ };
963
+ return this.implementation.persistMedia(file, options);
964
+ }
965
+ async deleteEntry(state, collection, slug) {
966
+ const config = state.config;
967
+ const path = (0, _collections.selectEntryPath)(collection, slug);
968
+ const extension = (0, _collections.selectFolderEntryExtension)(collection);
969
+ if (!(0, _collections.selectAllowDeletion)(collection)) {
970
+ throw new Error('Not allowed to delete entries in this collection');
971
+ }
972
+ const user = await this.currentUser();
973
+ const commitMessage = (0, _formatters.commitMessageFormatter)('delete', config, {
974
+ collection,
975
+ slug,
976
+ path,
977
+ authorLogin: user.login,
978
+ authorName: user.name
979
+ }, user.useOpenAuthoring);
980
+ const entry = (0, _entries.selectEntry)(state.entries, collection.get('name'), slug);
981
+ await this.invokePreUnpublishEvent(entry);
982
+ let paths = [path];
983
+ if ((0, _i18n.hasI18n)(collection)) {
984
+ paths = (0, _i18n.getFilePaths)(collection, extension, path, slug);
985
+ }
986
+ await this.implementation.deleteFiles(paths, commitMessage);
987
+ await this.invokePostUnpublishEvent(entry);
988
+ }
989
+ async deleteMedia(config, path) {
990
+ const user = await this.currentUser();
991
+ const commitMessage = (0, _formatters.commitMessageFormatter)('deleteMedia', config, {
992
+ path,
993
+ authorLogin: user.login,
994
+ authorName: user.name
995
+ }, user.useOpenAuthoring);
996
+ return this.implementation.deleteFiles([path], commitMessage);
997
+ }
998
+ persistUnpublishedEntry(args) {
999
+ return this.persistEntry(_objectSpread(_objectSpread({}, args), {}, {
1000
+ unpublished: true
1001
+ }));
1002
+ }
1003
+ updateUnpublishedEntryStatus(collection, slug, newStatus) {
1004
+ return this.implementation.updateUnpublishedEntryStatus(collection, slug, newStatus);
1005
+ }
1006
+ async publishUnpublishedEntry(entry) {
1007
+ const collection = entry.get('collection');
1008
+ const slug = entry.get('slug');
1009
+ await this.invokePrePublishEvent(entry);
1010
+ await this.implementation.publishUnpublishedEntry(collection, slug);
1011
+ await this.invokePostPublishEvent(entry);
1012
+ }
1013
+ deleteUnpublishedEntry(collection, slug) {
1014
+ return this.implementation.deleteUnpublishedEntry(collection, slug);
1015
+ }
1016
+ entryToRaw(collection, entry) {
1017
+ const format = (0, _formats.resolveFormat)(collection, entry.toJS());
1018
+ const fieldsOrder = this.fieldsOrder(collection, entry);
1019
+ const fieldsComments = (0, _collections.selectFieldsComments)(collection, entry);
1020
+ return format && format.toFile(entry.get('data').toJS(), fieldsOrder, fieldsComments);
1021
+ }
1022
+ fieldsOrder(collection, entry) {
1023
+ const fields = collection.get('fields');
1024
+ if (fields) {
1025
+ return collection.get('fields').map(f => f.get('name')).toArray();
1026
+ }
1027
+ const files = collection.get('files');
1028
+ const file = (files || (0, _immutable.List)()).filter(f => f.get('name') === entry.get('slug')).get(0);
1029
+ if (file == null) {
1030
+ throw new Error(`No file found for ${entry.get('slug')} in ${collection.get('name')}`);
1031
+ }
1032
+ return file.get('fields').map(f => f.get('name')).toArray();
1033
+ }
1034
+ filterEntries(collection, filterRule) {
1035
+ return collection.entries.filter(entry => {
1036
+ const fieldValue = entry.data[filterRule.get('field')];
1037
+ if (Array.isArray(fieldValue)) {
1038
+ return fieldValue.includes(filterRule.get('value'));
1039
+ }
1040
+ return fieldValue === filterRule.get('value');
1041
+ });
1042
+ }
1043
+ }
1044
+ exports.Backend = Backend;
1045
+ function resolveBackend(config) {
1046
+ if (!config.backend.name) {
1047
+ throw new Error('No backend defined in configuration');
1048
+ }
1049
+ const {
1050
+ name
1051
+ } = config.backend;
1052
+ const authStore = new LocalStorageAuthStore();
1053
+ const backend = (0, _registry.getBackend)(name);
1054
+ if (!backend) {
1055
+ throw new Error(`Backend not found: ${name}`);
1056
+ } else {
1057
+ return new Backend(backend, {
1058
+ backendName: name,
1059
+ authStore,
1060
+ config
1061
+ });
1062
+ }
1063
+ }
1064
+ const currentBackend = function () {
1065
+ let backend;
1066
+ return config => {
1067
+ if (backend) {
1068
+ return backend;
1069
+ }
1070
+ return backend = resolveBackend(config);
1071
+ };
1072
+ }();
1073
+ exports.currentBackend = currentBackend;