@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.
- package/README.md +9 -0
- package/dist/@pranaysahith/decap-cms-core.js +52 -0
- package/dist/@pranaysahith/decap-cms-core.js.LICENSE.txt +141 -0
- package/dist/@pranaysahith/decap-cms-core.js.map +1 -0
- package/dist/decap-cms-core.js +47 -0
- package/dist/decap-cms-core.js.LICENSE.txt +116 -0
- package/dist/decap-cms-core.js.map +1 -0
- package/dist/esm/actions/auth.js +97 -0
- package/dist/esm/actions/collections.js +15 -0
- package/dist/esm/actions/config.js +493 -0
- package/dist/esm/actions/deploys.js +79 -0
- package/dist/esm/actions/editorialWorkflow.js +480 -0
- package/dist/esm/actions/entries.js +865 -0
- package/dist/esm/actions/media.js +147 -0
- package/dist/esm/actions/mediaLibrary.js +552 -0
- package/dist/esm/actions/notifications.js +21 -0
- package/dist/esm/actions/search.js +149 -0
- package/dist/esm/actions/status.js +74 -0
- package/dist/esm/actions/waitUntil.js +32 -0
- package/dist/esm/backend.js +1082 -0
- package/dist/esm/bootstrap.js +101 -0
- package/dist/esm/components/App/App.js +289 -0
- package/dist/esm/components/App/Header.js +172 -0
- package/dist/esm/components/App/NotFoundPage.js +19 -0
- package/dist/esm/components/Collection/Collection.js +198 -0
- package/dist/esm/components/Collection/CollectionControls.js +46 -0
- package/dist/esm/components/Collection/CollectionSearch.js +222 -0
- package/dist/esm/components/Collection/CollectionTop.js +68 -0
- package/dist/esm/components/Collection/ControlButton.js +17 -0
- package/dist/esm/components/Collection/Entries/Entries.js +73 -0
- package/dist/esm/components/Collection/Entries/EntriesCollection.js +241 -0
- package/dist/esm/components/Collection/Entries/EntriesSearch.js +113 -0
- package/dist/esm/components/Collection/Entries/EntryCard.js +177 -0
- package/dist/esm/components/Collection/Entries/EntryListing.js +143 -0
- package/dist/esm/components/Collection/FilterControl.js +33 -0
- package/dist/esm/components/Collection/FolderRenameControl.js +403 -0
- package/dist/esm/components/Collection/GroupControl.js +33 -0
- package/dist/esm/components/Collection/NestedCollection.js +308 -0
- package/dist/esm/components/Collection/Sidebar.js +91 -0
- package/dist/esm/components/Collection/SortControl.js +59 -0
- package/dist/esm/components/Collection/ViewStyleControl.js +38 -0
- package/dist/esm/components/Editor/Editor.js +466 -0
- package/dist/esm/components/Editor/EditorControlPane/EditorControl.js +395 -0
- package/dist/esm/components/Editor/EditorControlPane/EditorControlPane.js +254 -0
- package/dist/esm/components/Editor/EditorControlPane/Widget.js +374 -0
- package/dist/esm/components/Editor/EditorInterface.js +386 -0
- package/dist/esm/components/Editor/EditorPreviewPane/EditorPreview.js +47 -0
- package/dist/esm/components/Editor/EditorPreviewPane/EditorPreviewContent.js +66 -0
- package/dist/esm/components/Editor/EditorPreviewPane/EditorPreviewPane.js +288 -0
- package/dist/esm/components/Editor/EditorPreviewPane/PreviewHOC.js +27 -0
- package/dist/esm/components/Editor/EditorToolbar.js +536 -0
- package/dist/esm/components/Editor/EntryPathEditor.js +272 -0
- package/dist/esm/components/Editor/withWorkflow.js +56 -0
- package/dist/esm/components/EditorWidgets/Unknown/UnknownControl.js +18 -0
- package/dist/esm/components/EditorWidgets/Unknown/UnknownPreview.js +20 -0
- package/dist/esm/components/EditorWidgets/index.js +4 -0
- package/dist/esm/components/MediaLibrary/EmptyMessage.js +22 -0
- package/dist/esm/components/MediaLibrary/MediaLibrary.js +446 -0
- package/dist/esm/components/MediaLibrary/MediaLibraryButtons.js +93 -0
- package/dist/esm/components/MediaLibrary/MediaLibraryCard.js +99 -0
- package/dist/esm/components/MediaLibrary/MediaLibraryCardGrid.js +198 -0
- package/dist/esm/components/MediaLibrary/MediaLibraryHeader.js +32 -0
- package/dist/esm/components/MediaLibrary/MediaLibraryModal.js +156 -0
- package/dist/esm/components/MediaLibrary/MediaLibrarySearch.js +51 -0
- package/dist/esm/components/MediaLibrary/MediaLibraryTop.js +123 -0
- package/dist/esm/components/UI/DragDrop.js +67 -0
- package/dist/esm/components/UI/ErrorBoundary.js +173 -0
- package/dist/esm/components/UI/FileUploadButton.js +27 -0
- package/dist/esm/components/UI/Modal.js +104 -0
- package/dist/esm/components/UI/Notifications.js +62 -0
- package/dist/esm/components/UI/SettingsDropdown.js +107 -0
- package/dist/esm/components/UI/index.js +6 -0
- package/dist/esm/components/Workflow/Workflow.js +133 -0
- package/dist/esm/components/Workflow/WorkflowCard.js +128 -0
- package/dist/esm/components/Workflow/WorkflowList.js +204 -0
- package/dist/esm/constants/collectionTypes.js +2 -0
- package/dist/esm/constants/collectionViews.js +2 -0
- package/dist/esm/constants/commitProps.js +2 -0
- package/dist/esm/constants/configSchema.js +644 -0
- package/dist/esm/constants/fieldInference.js +57 -0
- package/dist/esm/constants/publishModes.js +18 -0
- package/dist/esm/constants/validationErrorTypes.js +6 -0
- package/dist/esm/formats/formats.js +83 -0
- package/dist/esm/formats/frontmatter.js +146 -0
- package/dist/esm/formats/helpers.js +12 -0
- package/dist/esm/formats/json.js +8 -0
- package/dist/esm/formats/toml.js +32 -0
- package/dist/esm/formats/yaml.js +51 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/integrations/index.js +28 -0
- package/dist/esm/integrations/providers/algolia/implementation.js +174 -0
- package/dist/esm/integrations/providers/assetStore/implementation.js +165 -0
- package/dist/esm/lib/consoleError.js +3 -0
- package/dist/esm/lib/formatters.js +191 -0
- package/dist/esm/lib/i18n.js +367 -0
- package/dist/esm/lib/phrases.js +6 -0
- package/dist/esm/lib/polyfill.js +8 -0
- package/dist/esm/lib/registry.js +329 -0
- package/dist/esm/lib/serializeEntryValues.js +67 -0
- package/dist/esm/lib/stega.js +142 -0
- package/dist/esm/lib/textHelper.js +9 -0
- package/dist/esm/lib/urlHelper.js +111 -0
- package/dist/esm/mediaLibrary.js +37 -0
- package/dist/esm/reducers/auth.js +27 -0
- package/dist/esm/reducers/collections.js +428 -0
- package/dist/esm/reducers/combinedReducer.js +8 -0
- package/dist/esm/reducers/config.js +29 -0
- package/dist/esm/reducers/cursors.js +31 -0
- package/dist/esm/reducers/deploys.js +45 -0
- package/dist/esm/reducers/editorialWorkflow.js +83 -0
- package/dist/esm/reducers/entries.js +568 -0
- package/dist/esm/reducers/entryDraft.js +212 -0
- package/dist/esm/reducers/globalUI.js +25 -0
- package/dist/esm/reducers/index.js +66 -0
- package/dist/esm/reducers/integrations.js +53 -0
- package/dist/esm/reducers/mediaLibrary.js +252 -0
- package/dist/esm/reducers/medias.js +68 -0
- package/dist/esm/reducers/notifications.js +23 -0
- package/dist/esm/reducers/search.js +92 -0
- package/dist/esm/reducers/status.js +30 -0
- package/dist/esm/redux/index.js +7 -0
- package/dist/esm/redux/middleware/waitUntilAction.js +48 -0
- package/dist/esm/routing/history.js +12 -0
- package/dist/esm/types/diacritics.d.js +0 -0
- package/dist/esm/types/global.d.js +1 -0
- package/dist/esm/types/immutable.js +7 -0
- package/dist/esm/types/redux.js +14 -0
- package/dist/esm/types/tomlify-j0.4.d.js +0 -0
- package/dist/esm/valueObjects/AssetProxy.js +44 -0
- package/dist/esm/valueObjects/EditorComponent.js +34 -0
- package/dist/esm/valueObjects/Entry.js +20 -0
- package/index.d.ts +618 -0
- package/package.json +106 -0
- package/src/__tests__/backend.spec.js +1161 -0
- package/src/actions/__tests__/config.spec.js +1009 -0
- package/src/actions/__tests__/editorialWorkflow.spec.js +216 -0
- package/src/actions/__tests__/entries.spec.js +596 -0
- package/src/actions/__tests__/media.spec.ts +171 -0
- package/src/actions/__tests__/mediaLibrary.spec.js +327 -0
- package/src/actions/__tests__/search.spec.js +209 -0
- package/src/actions/auth.ts +127 -0
- package/src/actions/collections.ts +18 -0
- package/src/actions/config.ts +565 -0
- package/src/actions/deploys.ts +104 -0
- package/src/actions/editorialWorkflow.ts +567 -0
- package/src/actions/entries.ts +1055 -0
- package/src/actions/media.ts +139 -0
- package/src/actions/mediaLibrary.ts +574 -0
- package/src/actions/notifications.ts +36 -0
- package/src/actions/search.ts +221 -0
- package/src/actions/status.ts +99 -0
- package/src/actions/waitUntil.ts +49 -0
- package/src/backend.ts +1400 -0
- package/src/bootstrap.js +104 -0
- package/src/components/App/App.js +286 -0
- package/src/components/App/Header.js +266 -0
- package/src/components/App/NotFoundPage.js +23 -0
- package/src/components/Collection/Collection.js +210 -0
- package/src/components/Collection/CollectionControls.js +58 -0
- package/src/components/Collection/CollectionSearch.js +243 -0
- package/src/components/Collection/CollectionTop.js +81 -0
- package/src/components/Collection/ControlButton.js +27 -0
- package/src/components/Collection/Entries/Entries.js +82 -0
- package/src/components/Collection/Entries/EntriesCollection.js +277 -0
- package/src/components/Collection/Entries/EntriesSearch.js +102 -0
- package/src/components/Collection/Entries/EntryCard.js +246 -0
- package/src/components/Collection/Entries/EntryListing.js +151 -0
- package/src/components/Collection/Entries/__tests__/EntriesCollection.spec.js +163 -0
- package/src/components/Collection/Entries/__tests__/__snapshots__/EntriesCollection.spec.js.snap +46 -0
- package/src/components/Collection/FilterControl.js +39 -0
- package/src/components/Collection/GroupControl.js +39 -0
- package/src/components/Collection/NestedCollection.js +330 -0
- package/src/components/Collection/Sidebar.js +136 -0
- package/src/components/Collection/SortControl.js +68 -0
- package/src/components/Collection/ViewStyleControl.js +50 -0
- package/src/components/Collection/__tests__/Collection.spec.js +75 -0
- package/src/components/Collection/__tests__/NestedCollection.spec.js +445 -0
- package/src/components/Collection/__tests__/Sidebar.spec.js +87 -0
- package/src/components/Collection/__tests__/__snapshots__/Collection.spec.js.snap +144 -0
- package/src/components/Collection/__tests__/__snapshots__/NestedCollection.spec.js.snap +550 -0
- package/src/components/Collection/__tests__/__snapshots__/Sidebar.spec.js.snap +312 -0
- package/src/components/Editor/Editor.js +497 -0
- package/src/components/Editor/EditorControlPane/EditorControl.js +452 -0
- package/src/components/Editor/EditorControlPane/EditorControlPane.js +269 -0
- package/src/components/Editor/EditorControlPane/Widget.js +384 -0
- package/src/components/Editor/EditorInterface.js +444 -0
- package/src/components/Editor/EditorPreviewPane/EditorPreview.js +40 -0
- package/src/components/Editor/EditorPreviewPane/EditorPreviewContent.js +74 -0
- package/src/components/Editor/EditorPreviewPane/EditorPreviewPane.js +333 -0
- package/src/components/Editor/EditorPreviewPane/PreviewHOC.js +33 -0
- package/src/components/Editor/EditorToolbar.js +691 -0
- package/src/components/Editor/__tests__/Editor.spec.js +221 -0
- package/src/components/Editor/__tests__/EditorToolbar.spec.js +120 -0
- package/src/components/Editor/__tests__/__snapshots__/Editor.spec.js.snap +45 -0
- package/src/components/Editor/__tests__/__snapshots__/EditorToolbar.spec.js.snap +4233 -0
- package/src/components/Editor/withWorkflow.js +61 -0
- package/src/components/EditorWidgets/Unknown/UnknownControl.js +17 -0
- package/src/components/EditorWidgets/Unknown/UnknownPreview.js +19 -0
- package/src/components/EditorWidgets/index.js +5 -0
- package/src/components/MediaLibrary/EmptyMessage.js +28 -0
- package/src/components/MediaLibrary/MediaLibrary.js +411 -0
- package/src/components/MediaLibrary/MediaLibraryButtons.js +136 -0
- package/src/components/MediaLibrary/MediaLibraryCard.js +128 -0
- package/src/components/MediaLibrary/MediaLibraryCardGrid.js +199 -0
- package/src/components/MediaLibrary/MediaLibraryHeader.js +48 -0
- package/src/components/MediaLibrary/MediaLibraryModal.js +200 -0
- package/src/components/MediaLibrary/MediaLibrarySearch.js +61 -0
- package/src/components/MediaLibrary/MediaLibraryTop.js +143 -0
- package/src/components/MediaLibrary/__tests__/MediaLibraryButtons.spec.js +45 -0
- package/src/components/MediaLibrary/__tests__/MediaLibraryCard.spec.js +49 -0
- package/src/components/MediaLibrary/__tests__/__snapshots__/MediaLibraryCard.spec.js.snap +264 -0
- package/src/components/UI/DragDrop.js +66 -0
- package/src/components/UI/ErrorBoundary.js +214 -0
- package/src/components/UI/FileUploadButton.js +24 -0
- package/src/components/UI/Modal.js +112 -0
- package/src/components/UI/Notifications.tsx +83 -0
- package/src/components/UI/SettingsDropdown.js +103 -0
- package/src/components/UI/__tests__/ErrorBoundary.spec.js +57 -0
- package/src/components/UI/index.js +6 -0
- package/src/components/Workflow/Workflow.js +169 -0
- package/src/components/Workflow/WorkflowCard.js +177 -0
- package/src/components/Workflow/WorkflowList.js +272 -0
- package/src/constants/__tests__/configSchema.spec.js +611 -0
- package/src/constants/collectionTypes.ts +2 -0
- package/src/constants/collectionViews.js +2 -0
- package/src/constants/commitProps.ts +2 -0
- package/src/constants/configSchema.js +441 -0
- package/src/constants/fieldInference.tsx +78 -0
- package/src/constants/publishModes.ts +22 -0
- package/src/constants/validationErrorTypes.js +6 -0
- package/src/formats/__tests__/formats.spec.js +87 -0
- package/src/formats/__tests__/frontmatter.spec.js +429 -0
- package/src/formats/__tests__/toml.spec.js +9 -0
- package/src/formats/__tests__/yaml.spec.js +162 -0
- package/src/formats/formats.ts +97 -0
- package/src/formats/frontmatter.ts +150 -0
- package/src/formats/helpers.ts +14 -0
- package/src/formats/json.ts +9 -0
- package/src/formats/toml.ts +33 -0
- package/src/formats/yaml.ts +58 -0
- package/src/index.js +8 -0
- package/src/integrations/index.js +35 -0
- package/src/integrations/providers/algolia/implementation.js +176 -0
- package/src/integrations/providers/assetStore/implementation.js +148 -0
- package/src/lib/__tests__/formatters.spec.js +751 -0
- package/src/lib/__tests__/i18n.spec.js +792 -0
- package/src/lib/__tests__/phrases.spec.js +119 -0
- package/src/lib/__tests__/registry.spec.js +261 -0
- package/src/lib/__tests__/serializeEntryValues.spec.js +22 -0
- package/src/lib/__tests__/urlHelper.spec.js +138 -0
- package/src/lib/consoleError.js +7 -0
- package/src/lib/formatters.ts +286 -0
- package/src/lib/i18n.ts +454 -0
- package/src/lib/phrases.js +8 -0
- package/src/lib/polyfill.js +9 -0
- package/src/lib/registry.js +312 -0
- package/src/lib/serializeEntryValues.js +75 -0
- package/src/lib/stega.ts +145 -0
- package/src/lib/textHelper.js +11 -0
- package/src/lib/urlHelper.ts +128 -0
- package/src/mediaLibrary.ts +51 -0
- package/src/reducers/__tests__/auth.spec.ts +38 -0
- package/src/reducers/__tests__/collections.spec.js +610 -0
- package/src/reducers/__tests__/config.spec.js +38 -0
- package/src/reducers/__tests__/entries.spec.js +694 -0
- package/src/reducers/__tests__/entryDraft.spec.js +297 -0
- package/src/reducers/__tests__/globalUI.js +43 -0
- package/src/reducers/__tests__/integrations.spec.ts +76 -0
- package/src/reducers/__tests__/mediaLibrary.spec.js +154 -0
- package/src/reducers/__tests__/medias.spec.ts +49 -0
- package/src/reducers/auth.ts +46 -0
- package/src/reducers/collections.ts +535 -0
- package/src/reducers/combinedReducer.ts +11 -0
- package/src/reducers/config.ts +38 -0
- package/src/reducers/cursors.js +36 -0
- package/src/reducers/deploys.ts +52 -0
- package/src/reducers/editorialWorkflow.ts +163 -0
- package/src/reducers/entries.ts +819 -0
- package/src/reducers/entryDraft.js +260 -0
- package/src/reducers/globalUI.ts +45 -0
- package/src/reducers/index.ts +82 -0
- package/src/reducers/integrations.ts +59 -0
- package/src/reducers/mediaLibrary.ts +296 -0
- package/src/reducers/medias.ts +66 -0
- package/src/reducers/notifications.ts +52 -0
- package/src/reducers/search.ts +111 -0
- package/src/reducers/status.ts +40 -0
- package/src/redux/index.ts +18 -0
- package/src/redux/middleware/waitUntilAction.ts +64 -0
- package/src/routing/__tests__/history.spec.ts +49 -0
- package/src/routing/history.ts +17 -0
- package/src/types/diacritics.d.ts +1 -0
- package/src/types/global.d.ts +8 -0
- package/src/types/immutable.ts +49 -0
- package/src/types/redux.ts +827 -0
- package/src/types/tomlify-j0.4.d.ts +13 -0
- package/src/valueObjects/AssetProxy.ts +48 -0
- package/src/valueObjects/EditorComponent.js +38 -0
- 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,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
|
+
}
|