@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,83 @@
|
|
|
1
|
+
import { List } from 'immutable';
|
|
2
|
+
import get from 'lodash/get';
|
|
3
|
+
import yamlFormatter from './yaml';
|
|
4
|
+
import tomlFormatter from './toml';
|
|
5
|
+
import jsonFormatter from './json';
|
|
6
|
+
import { FrontmatterInfer, frontmatterJSON, frontmatterTOML, frontmatterYAML } from './frontmatter';
|
|
7
|
+
import { getCustomFormatsExtensions, getCustomFormatsFormatters } from '../lib/registry';
|
|
8
|
+
export const frontmatterFormats = ['yaml-frontmatter', 'toml-frontmatter', 'json-frontmatter'];
|
|
9
|
+
export const formatExtensions = {
|
|
10
|
+
yml: 'yml',
|
|
11
|
+
yaml: 'yml',
|
|
12
|
+
toml: 'toml',
|
|
13
|
+
json: 'json',
|
|
14
|
+
frontmatter: 'md',
|
|
15
|
+
'json-frontmatter': 'md',
|
|
16
|
+
'toml-frontmatter': 'md',
|
|
17
|
+
'yaml-frontmatter': 'md'
|
|
18
|
+
};
|
|
19
|
+
export function getFormatExtensions() {
|
|
20
|
+
return {
|
|
21
|
+
...formatExtensions,
|
|
22
|
+
...getCustomFormatsExtensions()
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export const extensionFormatters = {
|
|
26
|
+
yml: yamlFormatter,
|
|
27
|
+
yaml: yamlFormatter,
|
|
28
|
+
toml: tomlFormatter,
|
|
29
|
+
json: jsonFormatter,
|
|
30
|
+
md: FrontmatterInfer,
|
|
31
|
+
markdown: FrontmatterInfer,
|
|
32
|
+
html: FrontmatterInfer
|
|
33
|
+
};
|
|
34
|
+
function formatByName(name, customDelimiter) {
|
|
35
|
+
const formatters = {
|
|
36
|
+
yml: yamlFormatter,
|
|
37
|
+
yaml: yamlFormatter,
|
|
38
|
+
toml: tomlFormatter,
|
|
39
|
+
json: jsonFormatter,
|
|
40
|
+
frontmatter: FrontmatterInfer,
|
|
41
|
+
'json-frontmatter': frontmatterJSON(customDelimiter),
|
|
42
|
+
'toml-frontmatter': frontmatterTOML(customDelimiter),
|
|
43
|
+
'yaml-frontmatter': frontmatterYAML(customDelimiter),
|
|
44
|
+
...getCustomFormatsFormatters()
|
|
45
|
+
};
|
|
46
|
+
if (name in formatters) {
|
|
47
|
+
return formatters[name];
|
|
48
|
+
}
|
|
49
|
+
throw new Error(`No formatter available with name: ${name}`);
|
|
50
|
+
}
|
|
51
|
+
function frontmatterDelimiterIsList(frontmatterDelimiter) {
|
|
52
|
+
return List.isList(frontmatterDelimiter);
|
|
53
|
+
}
|
|
54
|
+
export function resolveFormat(collection, entry) {
|
|
55
|
+
// Check for custom delimiter
|
|
56
|
+
const frontmatter_delimiter = collection.get('frontmatter_delimiter');
|
|
57
|
+
const customDelimiter = frontmatterDelimiterIsList(frontmatter_delimiter) ? frontmatter_delimiter.toArray() : frontmatter_delimiter;
|
|
58
|
+
|
|
59
|
+
// If the format is specified in the collection, use that format.
|
|
60
|
+
const formatSpecification = collection.get('format');
|
|
61
|
+
if (formatSpecification) {
|
|
62
|
+
return formatByName(formatSpecification, customDelimiter);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// If a file already exists, infer the format from its file extension.
|
|
66
|
+
const filePath = entry && entry.path;
|
|
67
|
+
if (filePath) {
|
|
68
|
+
const fileExtension = filePath.split('.').pop();
|
|
69
|
+
if (fileExtension) {
|
|
70
|
+
return get(extensionFormatters, fileExtension);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// If creating a new file, and an `extension` is specified in the
|
|
75
|
+
// collection config, infer the format from that extension.
|
|
76
|
+
const extension = collection.get('extension');
|
|
77
|
+
if (extension) {
|
|
78
|
+
return get(extensionFormatters, extension);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// If no format is specified and it cannot be inferred, return the default.
|
|
82
|
+
return formatByName('frontmatter', customDelimiter);
|
|
83
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import matter from 'gray-matter';
|
|
2
|
+
import tomlFormatter from './toml';
|
|
3
|
+
import yamlFormatter from './yaml';
|
|
4
|
+
import jsonFormatter from './json';
|
|
5
|
+
const Languages = {
|
|
6
|
+
YAML: 'yaml',
|
|
7
|
+
TOML: 'toml',
|
|
8
|
+
JSON: 'json'
|
|
9
|
+
};
|
|
10
|
+
const parsers = {
|
|
11
|
+
toml: {
|
|
12
|
+
parse: input => tomlFormatter.fromFile(input),
|
|
13
|
+
stringify: (metadata, opts) => {
|
|
14
|
+
const {
|
|
15
|
+
sortedKeys
|
|
16
|
+
} = opts || {};
|
|
17
|
+
return tomlFormatter.toFile(metadata, sortedKeys);
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
json: {
|
|
21
|
+
parse: input => {
|
|
22
|
+
let JSONinput = input.trim();
|
|
23
|
+
// Fix JSON if leading and trailing brackets were trimmed.
|
|
24
|
+
if (JSONinput.slice(0, 1) !== '{') {
|
|
25
|
+
JSONinput = '{' + JSONinput + '}';
|
|
26
|
+
}
|
|
27
|
+
return jsonFormatter.fromFile(JSONinput);
|
|
28
|
+
},
|
|
29
|
+
stringify: metadata => {
|
|
30
|
+
let JSONoutput = jsonFormatter.toFile(metadata).trim();
|
|
31
|
+
// Trim leading and trailing brackets.
|
|
32
|
+
if (JSONoutput.slice(0, 1) === '{' && JSONoutput.slice(-1) === '}') {
|
|
33
|
+
JSONoutput = JSONoutput.slice(1, -1);
|
|
34
|
+
}
|
|
35
|
+
return JSONoutput;
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
yaml: {
|
|
39
|
+
parse: input => yamlFormatter.fromFile(input),
|
|
40
|
+
stringify: (metadata, opts) => {
|
|
41
|
+
const {
|
|
42
|
+
sortedKeys,
|
|
43
|
+
comments
|
|
44
|
+
} = opts || {};
|
|
45
|
+
return yamlFormatter.toFile(metadata, sortedKeys, comments);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
function inferFrontmatterFormat(str) {
|
|
50
|
+
const lineEnd = str.indexOf('\n');
|
|
51
|
+
const firstLine = str.slice(0, lineEnd !== -1 ? lineEnd : 0).trim();
|
|
52
|
+
if (firstLine.length > 3 && firstLine.slice(0, 3) === '---') {
|
|
53
|
+
// No need to infer, `gray-matter` will handle things like `---toml` for us.
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
switch (firstLine) {
|
|
57
|
+
case '---':
|
|
58
|
+
return getFormatOpts(Languages.YAML);
|
|
59
|
+
case '+++':
|
|
60
|
+
return getFormatOpts(Languages.TOML);
|
|
61
|
+
case '{':
|
|
62
|
+
return getFormatOpts(Languages.JSON);
|
|
63
|
+
default:
|
|
64
|
+
console.warn('Unrecognized front-matter format.');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
export function getFormatOpts(format, customDelimiter) {
|
|
68
|
+
if (!format) {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
const formats = {
|
|
72
|
+
yaml: {
|
|
73
|
+
language: Languages.YAML,
|
|
74
|
+
delimiters: '---'
|
|
75
|
+
},
|
|
76
|
+
toml: {
|
|
77
|
+
language: Languages.TOML,
|
|
78
|
+
delimiters: '+++'
|
|
79
|
+
},
|
|
80
|
+
json: {
|
|
81
|
+
language: Languages.JSON,
|
|
82
|
+
delimiters: ['{', '}']
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const {
|
|
86
|
+
language,
|
|
87
|
+
delimiters
|
|
88
|
+
} = formats[format];
|
|
89
|
+
return {
|
|
90
|
+
language,
|
|
91
|
+
delimiters: customDelimiter || delimiters
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
export class FrontmatterFormatter {
|
|
95
|
+
constructor(format, customDelimiter) {
|
|
96
|
+
this.format = getFormatOpts(format, customDelimiter);
|
|
97
|
+
}
|
|
98
|
+
fromFile(content) {
|
|
99
|
+
const format = this.format || inferFrontmatterFormat(content);
|
|
100
|
+
const result = matter(content, {
|
|
101
|
+
engines: parsers,
|
|
102
|
+
...format
|
|
103
|
+
});
|
|
104
|
+
// in the absent of a body when serializing an entry we use an empty one
|
|
105
|
+
// when calling `toFile`, so we don't want to add it when parsing.
|
|
106
|
+
return {
|
|
107
|
+
...result.data,
|
|
108
|
+
...(result.content.trim() && {
|
|
109
|
+
body: result.content
|
|
110
|
+
})
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
toFile(data, sortedKeys, comments) {
|
|
114
|
+
const {
|
|
115
|
+
body = '',
|
|
116
|
+
...meta
|
|
117
|
+
} = data;
|
|
118
|
+
|
|
119
|
+
// Stringify to YAML if the format was not set
|
|
120
|
+
const format = this.format || getFormatOpts(Languages.YAML);
|
|
121
|
+
|
|
122
|
+
// gray-matter always adds a line break at the end which trips our
|
|
123
|
+
// change detection logic
|
|
124
|
+
// https://github.com/jonschlinkert/gray-matter/issues/96
|
|
125
|
+
const trimLastLineBreak = body.slice(-1) !== '\n';
|
|
126
|
+
const file = matter.stringify(body, meta, {
|
|
127
|
+
engines: parsers,
|
|
128
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
129
|
+
// @ts-ignore `sortedKeys` is not recognized by gray-matter, so it gets passed through to the parser
|
|
130
|
+
sortedKeys,
|
|
131
|
+
comments,
|
|
132
|
+
...format
|
|
133
|
+
});
|
|
134
|
+
return trimLastLineBreak && file.slice(-1) === '\n' ? file.slice(0, -1) : file;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
export const FrontmatterInfer = new FrontmatterFormatter();
|
|
138
|
+
export function frontmatterYAML(customDelimiter) {
|
|
139
|
+
return new FrontmatterFormatter(Languages.YAML, customDelimiter);
|
|
140
|
+
}
|
|
141
|
+
export function frontmatterTOML(customDelimiter) {
|
|
142
|
+
return new FrontmatterFormatter(Languages.TOML, customDelimiter);
|
|
143
|
+
}
|
|
144
|
+
export function frontmatterJSON(customDelimiter) {
|
|
145
|
+
return new FrontmatterFormatter(Languages.JSON, customDelimiter);
|
|
146
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function sortKeys(sortedKeys,
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3
|
+
selector = a => a) {
|
|
4
|
+
return (a, b) => {
|
|
5
|
+
const idxA = sortedKeys.indexOf(selector(a));
|
|
6
|
+
const idxB = sortedKeys.indexOf(selector(b));
|
|
7
|
+
if (idxA === -1 || idxB === -1) return 0;
|
|
8
|
+
if (idxA > idxB) return 1;
|
|
9
|
+
if (idxA < idxB) return -1;
|
|
10
|
+
return 0;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import parseToml from '@iarna/toml/parse-string';
|
|
2
|
+
import tomlify from 'tomlify-j0.4';
|
|
3
|
+
import dayjs from 'dayjs';
|
|
4
|
+
import AssetProxy from '../valueObjects/AssetProxy';
|
|
5
|
+
import { sortKeys } from './helpers';
|
|
6
|
+
function outputReplacer(_key, value) {
|
|
7
|
+
if (dayjs.isDayjs(value)) {
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
9
|
+
// @ts-ignore
|
|
10
|
+
return value.format(value._f);
|
|
11
|
+
}
|
|
12
|
+
if (value instanceof AssetProxy) {
|
|
13
|
+
return `${value.path}`;
|
|
14
|
+
}
|
|
15
|
+
if (typeof value === 'number' && Number.isInteger(value)) {
|
|
16
|
+
// Return the string representation of integers so tomlify won't render with tenths (".0")
|
|
17
|
+
return value.toString();
|
|
18
|
+
}
|
|
19
|
+
// Return `false` to use default (`undefined` would delete key).
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
export default {
|
|
23
|
+
fromFile(content) {
|
|
24
|
+
return parseToml(content);
|
|
25
|
+
},
|
|
26
|
+
toFile(data, sortedKeys = []) {
|
|
27
|
+
return tomlify.toToml(data, {
|
|
28
|
+
replace: outputReplacer,
|
|
29
|
+
sort: sortKeys(sortedKeys)
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import yaml from 'yaml';
|
|
2
|
+
import { sortKeys } from './helpers';
|
|
3
|
+
function addComments(items, comments, prefix = '') {
|
|
4
|
+
items.forEach(item => {
|
|
5
|
+
if (item.key !== undefined) {
|
|
6
|
+
const itemKey = item.key.toString();
|
|
7
|
+
const key = prefix ? `${prefix}.${itemKey}` : itemKey;
|
|
8
|
+
if (comments[key]) {
|
|
9
|
+
const value = comments[key].split('\\n').join('\n ');
|
|
10
|
+
item.commentBefore = ` ${value}`;
|
|
11
|
+
}
|
|
12
|
+
if (Array.isArray(item.value?.items)) {
|
|
13
|
+
addComments(item.value.items, comments, key);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
const timestampTag = {
|
|
19
|
+
identify: value => value instanceof Date,
|
|
20
|
+
default: true,
|
|
21
|
+
tag: '!timestamp',
|
|
22
|
+
test: RegExp('^' + '([0-9]{4})-([0-9]{2})-([0-9]{2})' +
|
|
23
|
+
// YYYY-MM-DD
|
|
24
|
+
'T' +
|
|
25
|
+
// T
|
|
26
|
+
'([0-9]{2}):([0-9]{2}):([0-9]{2}(\\.[0-9]+)?)' +
|
|
27
|
+
// HH:MM:SS(.ss)?
|
|
28
|
+
'Z' +
|
|
29
|
+
// Z
|
|
30
|
+
'$'),
|
|
31
|
+
resolve: str => new Date(str),
|
|
32
|
+
stringify: value => value.toISOString()
|
|
33
|
+
};
|
|
34
|
+
export default {
|
|
35
|
+
fromFile(content) {
|
|
36
|
+
if (content && content.trim().endsWith('---')) {
|
|
37
|
+
content = content.trim().slice(0, -3);
|
|
38
|
+
}
|
|
39
|
+
return yaml.parse(content, {
|
|
40
|
+
customTags: [timestampTag]
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
toFile(data, sortedKeys = [], comments = {}) {
|
|
44
|
+
const contents = yaml.createNode(data);
|
|
45
|
+
addComments(contents.items, comments);
|
|
46
|
+
contents.items.sort(sortKeys(sortedKeys, item => item.key?.toString()));
|
|
47
|
+
const doc = new yaml.Document();
|
|
48
|
+
doc.contents = contents;
|
|
49
|
+
return doc.toString();
|
|
50
|
+
}
|
|
51
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Map } from 'immutable';
|
|
2
|
+
import Algolia from './providers/algolia/implementation';
|
|
3
|
+
import AssetStore from './providers/assetStore/implementation';
|
|
4
|
+
export function resolveIntegrations(integrationsConfig, getToken) {
|
|
5
|
+
let integrationInstances = Map({});
|
|
6
|
+
integrationsConfig.get('providers').forEach((providerData, providerName) => {
|
|
7
|
+
switch (providerName) {
|
|
8
|
+
case 'algolia':
|
|
9
|
+
integrationInstances = integrationInstances.set('algolia', new Algolia(providerData));
|
|
10
|
+
break;
|
|
11
|
+
case 'assetStore':
|
|
12
|
+
integrationInstances = integrationInstances.set('assetStore', new AssetStore(providerData, getToken));
|
|
13
|
+
break;
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
return integrationInstances;
|
|
17
|
+
}
|
|
18
|
+
export const getIntegrationProvider = function () {
|
|
19
|
+
let integrations = null;
|
|
20
|
+
return (integrationsConfig, getToken, provider) => {
|
|
21
|
+
if (integrations) {
|
|
22
|
+
return integrations.get(provider);
|
|
23
|
+
} else {
|
|
24
|
+
integrations = resolveIntegrations(integrationsConfig, getToken);
|
|
25
|
+
return integrations.get(provider);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}();
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import flatten from 'lodash/flatten';
|
|
2
|
+
import { unsentRequest } from 'decap-cms-lib-util';
|
|
3
|
+
import { createEntry } from '../../../valueObjects/Entry';
|
|
4
|
+
import { selectEntrySlug } from '../../../reducers/collections';
|
|
5
|
+
const {
|
|
6
|
+
fetchWithTimeout: fetch
|
|
7
|
+
} = unsentRequest;
|
|
8
|
+
function getSlug(path) {
|
|
9
|
+
return path.split('/').pop().replace(/\.[^.]+$/, '');
|
|
10
|
+
}
|
|
11
|
+
export default class Algolia {
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.config = config;
|
|
14
|
+
if (config.get('applicationID') == null || config.get('apiKey') == null) {
|
|
15
|
+
throw 'The Algolia search integration needs the credentials (applicationID and apiKey) in the integration configuration.';
|
|
16
|
+
}
|
|
17
|
+
this.applicationID = config.get('applicationID');
|
|
18
|
+
this.apiKey = config.get('apiKey');
|
|
19
|
+
const prefix = config.get('indexPrefix');
|
|
20
|
+
this.indexPrefix = prefix ? `${prefix}-` : '';
|
|
21
|
+
this.searchURL = `https://${this.applicationID}-dsn.algolia.net/1`;
|
|
22
|
+
this.entriesCache = {
|
|
23
|
+
collection: null,
|
|
24
|
+
page: null,
|
|
25
|
+
entries: []
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
requestHeaders(headers = {}) {
|
|
29
|
+
return {
|
|
30
|
+
'X-Algolia-API-Key': this.apiKey,
|
|
31
|
+
'X-Algolia-Application-Id': this.applicationID,
|
|
32
|
+
'Content-Type': 'application/json',
|
|
33
|
+
...headers
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
parseJsonResponse(response) {
|
|
37
|
+
return response.json().then(json => {
|
|
38
|
+
if (!response.ok) {
|
|
39
|
+
return Promise.reject(json);
|
|
40
|
+
}
|
|
41
|
+
return json;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
urlFor(path, options) {
|
|
45
|
+
const params = [];
|
|
46
|
+
if (options.params) {
|
|
47
|
+
for (const key in options.params) {
|
|
48
|
+
params.push(`${key}=${encodeURIComponent(options.params[key])}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (params.length) {
|
|
52
|
+
path += `?${params.join('&')}`;
|
|
53
|
+
}
|
|
54
|
+
return path;
|
|
55
|
+
}
|
|
56
|
+
request(path, options = {}) {
|
|
57
|
+
const headers = this.requestHeaders(options.headers || {});
|
|
58
|
+
const url = this.urlFor(path, options);
|
|
59
|
+
return fetch(url, {
|
|
60
|
+
...options,
|
|
61
|
+
headers
|
|
62
|
+
}).then(response => {
|
|
63
|
+
const contentType = response.headers.get('Content-Type');
|
|
64
|
+
if (contentType && contentType.match(/json/)) {
|
|
65
|
+
return this.parseJsonResponse(response);
|
|
66
|
+
}
|
|
67
|
+
return response.text();
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
search(collections, searchTerm, page) {
|
|
71
|
+
const searchCollections = collections.map(collection => ({
|
|
72
|
+
indexName: `${this.indexPrefix}${collection}`,
|
|
73
|
+
params: `query=${searchTerm}&page=${page}`
|
|
74
|
+
}));
|
|
75
|
+
return this.request(`${this.searchURL}/indexes/*/queries`, {
|
|
76
|
+
method: 'POST',
|
|
77
|
+
body: JSON.stringify({
|
|
78
|
+
requests: searchCollections
|
|
79
|
+
})
|
|
80
|
+
}).then(response => {
|
|
81
|
+
const entries = response.results.map((result, index) => result.hits.map(hit => {
|
|
82
|
+
const slug = getSlug(hit.path);
|
|
83
|
+
return createEntry(collections[index], slug, hit.path, {
|
|
84
|
+
data: hit.data,
|
|
85
|
+
partial: true
|
|
86
|
+
});
|
|
87
|
+
}));
|
|
88
|
+
return {
|
|
89
|
+
entries: flatten(entries),
|
|
90
|
+
pagination: page
|
|
91
|
+
};
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
searchBy(field, collection, query) {
|
|
95
|
+
return this.request(`${this.searchURL}/indexes/${this.indexPrefix}${collection}`, {
|
|
96
|
+
params: {
|
|
97
|
+
restrictSearchableAttributes: field,
|
|
98
|
+
query
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
listEntries(collection, page) {
|
|
103
|
+
if (this.entriesCache.collection === collection && this.entriesCache.page === page) {
|
|
104
|
+
return Promise.resolve({
|
|
105
|
+
page: this.entriesCache.page,
|
|
106
|
+
entries: this.entriesCache.entries
|
|
107
|
+
});
|
|
108
|
+
} else {
|
|
109
|
+
return this.request(`${this.searchURL}/indexes/${this.indexPrefix}${collection.get('name')}`, {
|
|
110
|
+
params: {
|
|
111
|
+
page
|
|
112
|
+
}
|
|
113
|
+
}).then(response => {
|
|
114
|
+
const entries = response.hits.map(hit => {
|
|
115
|
+
const slug = selectEntrySlug(collection, hit.path);
|
|
116
|
+
return createEntry(collection.get('name'), slug, hit.path, {
|
|
117
|
+
data: hit.data,
|
|
118
|
+
partial: true
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
this.entriesCache = {
|
|
122
|
+
collection,
|
|
123
|
+
pagination: response.page,
|
|
124
|
+
entries
|
|
125
|
+
};
|
|
126
|
+
return {
|
|
127
|
+
entries,
|
|
128
|
+
pagination: response.page
|
|
129
|
+
};
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
async listAllEntries(collection) {
|
|
134
|
+
const params = {
|
|
135
|
+
hitsPerPage: 1000
|
|
136
|
+
};
|
|
137
|
+
let response = await this.request(`${this.searchURL}/indexes/${this.indexPrefix}${collection.get('name')}`, {
|
|
138
|
+
params
|
|
139
|
+
});
|
|
140
|
+
let {
|
|
141
|
+
nbPages = 0,
|
|
142
|
+
hits,
|
|
143
|
+
page
|
|
144
|
+
} = response;
|
|
145
|
+
page = page + 1;
|
|
146
|
+
while (page < nbPages) {
|
|
147
|
+
response = await this.request(`${this.searchURL}/indexes/${this.indexPrefix}${collection.get('name')}`, {
|
|
148
|
+
params: {
|
|
149
|
+
...params,
|
|
150
|
+
page
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
hits = [...hits, ...response.hits];
|
|
154
|
+
page = page + 1;
|
|
155
|
+
}
|
|
156
|
+
const entries = hits.map(hit => {
|
|
157
|
+
const slug = selectEntrySlug(collection, hit.path);
|
|
158
|
+
return createEntry(collection.get('name'), slug, hit.path, {
|
|
159
|
+
data: hit.data,
|
|
160
|
+
partial: true
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
return entries;
|
|
164
|
+
}
|
|
165
|
+
getEntry(collection, slug) {
|
|
166
|
+
return this.searchBy('slug', collection.get('name'), slug).then(response => {
|
|
167
|
+
const entry = response.hits.filter(hit => hit.slug === slug)[0];
|
|
168
|
+
return createEntry(collection.get('name'), slug, entry.path, {
|
|
169
|
+
data: entry.data,
|
|
170
|
+
partial: true
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|