decap-cms-core 3.12.0 → 3.14.0

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 (46) hide show
  1. package/dist/decap-cms-core.js +18 -18
  2. package/dist/decap-cms-core.js.map +1 -1
  3. package/dist/esm/actions/config.js +14 -1
  4. package/dist/esm/actions/entries.js +15 -4
  5. package/dist/esm/backend.js +2 -0
  6. package/dist/esm/bootstrap.js +2 -2
  7. package/dist/esm/components/App/App.js +12 -5
  8. package/dist/esm/components/App/Header.js +18 -18
  9. package/dist/esm/components/Collection/Entries/EntryCard.js +30 -15
  10. package/dist/esm/components/Collection/NestedCollection.js +20 -11
  11. package/dist/esm/components/Editor/EditorPreviewPane/EditorPreviewPane.js +22 -6
  12. package/dist/esm/components/UI/ErrorBoundary.js +2 -2
  13. package/dist/esm/components/UI/SettingsDropdown.js +25 -27
  14. package/dist/esm/constants/configSchema.js +7 -1
  15. package/dist/esm/lib/formatters.js +6 -4
  16. package/dist/esm/lib/registry.js +4 -1
  17. package/dist/esm/lib/urlHelper.js +26 -8
  18. package/dist/esm/reducers/entryDraft.js +36 -3
  19. package/index.d.ts +18 -1
  20. package/package.json +2 -2
  21. package/src/__tests__/backend.spec.js +214 -0
  22. package/src/actions/__tests__/config.spec.js +14 -0
  23. package/src/actions/__tests__/entries.spec.js +36 -1
  24. package/src/actions/config.ts +13 -1
  25. package/src/actions/entries.ts +22 -7
  26. package/src/backend.ts +2 -0
  27. package/src/components/App/App.js +22 -13
  28. package/src/components/App/Header.js +36 -11
  29. package/src/components/Collection/Entries/EntryCard.js +13 -3
  30. package/src/components/Collection/NestedCollection.js +14 -7
  31. package/src/components/Collection/__tests__/NestedCollection.spec.js +1 -1
  32. package/src/components/Collection/__tests__/__snapshots__/NestedCollection.spec.js.snap +0 -68
  33. package/src/components/Editor/EditorPreviewPane/EditorPreviewPane.js +6 -5
  34. package/src/components/Editor/__tests__/__snapshots__/EditorToolbar.spec.js.snap +104 -72
  35. package/src/components/UI/SettingsDropdown.js +36 -9
  36. package/src/constants/__tests__/configSchema.spec.js +9 -6
  37. package/src/constants/configSchema.js +3 -1
  38. package/src/lib/__tests__/formatters.spec.js +76 -4
  39. package/src/lib/__tests__/registry.spec.js +3 -3
  40. package/src/lib/__tests__/urlHelper.spec.js +7 -0
  41. package/src/lib/formatters.ts +15 -5
  42. package/src/lib/registry.js +4 -1
  43. package/src/lib/urlHelper.ts +33 -9
  44. package/src/reducers/__tests__/entryDraft.spec.js +117 -0
  45. package/src/reducers/entryDraft.js +43 -3
  46. package/src/types/redux.ts +22 -2
@@ -138,20 +138,6 @@ exports[`NestedCollection should render connected component 1`] = `
138
138
  margin-right: 4px;
139
139
  }
140
140
 
141
- .emotion-6 {
142
- position: relative;
143
- top: 2px;
144
- color: #fff;
145
- width: 0;
146
- height: 0;
147
- border: 5px solid transparent;
148
- border-radius: 2px;
149
- border-left: 6px solid currentColor;
150
- border-right: 0;
151
- color: currentColor;
152
- left: 2px;
153
- }
154
-
155
141
  <a
156
142
  class="emotion-0 emotion-1"
157
143
  data-testid="/a"
@@ -169,9 +155,6 @@ exports[`NestedCollection should render connected component 1`] = `
169
155
  >
170
156
  File 1
171
157
  </div>
172
- <div
173
- class="emotion-6 emotion-7"
174
- />
175
158
  </div>
176
159
  </a>
177
160
  .emotion-0 {
@@ -224,20 +207,6 @@ exports[`NestedCollection should render connected component 1`] = `
224
207
  margin-right: 4px;
225
208
  }
226
209
 
227
- .emotion-6 {
228
- position: relative;
229
- top: 2px;
230
- color: #fff;
231
- width: 0;
232
- height: 0;
233
- border: 5px solid transparent;
234
- border-radius: 2px;
235
- border-left: 6px solid currentColor;
236
- border-right: 0;
237
- color: currentColor;
238
- left: 2px;
239
- }
240
-
241
210
  <a
242
211
  class="emotion-0 emotion-1"
243
212
  data-testid="/b"
@@ -255,9 +224,6 @@ exports[`NestedCollection should render connected component 1`] = `
255
224
  >
256
225
  File 2
257
226
  </div>
258
- <div
259
- class="emotion-6 emotion-7"
260
- />
261
227
  </div>
262
228
  </a>
263
229
  </DocumentFragment>
@@ -401,20 +367,6 @@ exports[`NestedCollection should render correctly with nested entries 1`] = `
401
367
  margin-right: 4px;
402
368
  }
403
369
 
404
- .emotion-6 {
405
- position: relative;
406
- top: 2px;
407
- color: #fff;
408
- width: 0;
409
- height: 0;
410
- border: 5px solid transparent;
411
- border-radius: 2px;
412
- border-left: 6px solid currentColor;
413
- border-right: 0;
414
- color: currentColor;
415
- left: 2px;
416
- }
417
-
418
370
  <a
419
371
  class="emotion-0 emotion-1"
420
372
  data-testid="/a"
@@ -432,9 +384,6 @@ exports[`NestedCollection should render correctly with nested entries 1`] = `
432
384
  >
433
385
  File 1
434
386
  </div>
435
- <div
436
- class="emotion-6 emotion-7"
437
- />
438
387
  </div>
439
388
  </a>
440
389
  .emotion-0 {
@@ -487,20 +436,6 @@ exports[`NestedCollection should render correctly with nested entries 1`] = `
487
436
  margin-right: 4px;
488
437
  }
489
438
 
490
- .emotion-6 {
491
- position: relative;
492
- top: 2px;
493
- color: #fff;
494
- width: 0;
495
- height: 0;
496
- border: 5px solid transparent;
497
- border-radius: 2px;
498
- border-left: 6px solid currentColor;
499
- border-right: 0;
500
- color: currentColor;
501
- left: 2px;
502
- }
503
-
504
439
  <a
505
440
  class="emotion-0 emotion-1"
506
441
  data-testid="/b"
@@ -518,9 +453,6 @@ exports[`NestedCollection should render correctly with nested entries 1`] = `
518
453
  >
519
454
  File 2
520
455
  </div>
521
- <div
522
- class="emotion-6 emotion-7"
523
- />
524
456
  </div>
525
457
  </a>
526
458
  </DocumentFragment>
@@ -224,17 +224,18 @@ export class PreviewPane extends React.Component {
224
224
  * This function exists entirely to expose collections from outside of this entry
225
225
  *
226
226
  */
227
- getCollection = async (collectionName, slug) => {
227
+ getCollection = async (collectionName, slugToLoad) => {
228
228
  const { state } = this.props;
229
229
  const selectedCollection = state.collections.get(collectionName);
230
230
 
231
- if (typeof slug === 'undefined') {
231
+ if (typeof slugToLoad === 'undefined') {
232
232
  const entries = await getAllEntries(state, selectedCollection);
233
- return entries.map(entry => Map().set('data', entry.data));
233
+
234
+ return entries.map(({ data, slug, path }) => Map({ data, slug, path }));
234
235
  }
235
236
 
236
- const entry = await tryLoadEntry(state, selectedCollection, slug);
237
- return Map().set('data', entry.data);
237
+ const { data, slug, path } = await tryLoadEntry(state, selectedCollection, slugToLoad);
238
+ return Map({ data, slug, path });
238
239
  };
239
240
 
240
241
  render() {
@@ -106,6 +106,7 @@ exports[`EditorToolbar should render normal save button 1`] = `
106
106
  -moz-user-select: none;
107
107
  -ms-user-select: none;
108
108
  user-select: none;
109
+ touch-action: manipulation;
109
110
  margin: 0 10px;
110
111
  }
111
112
 
@@ -127,6 +128,7 @@ exports[`EditorToolbar should render normal save button 1`] = `
127
128
  padding-left: 20px;
128
129
  padding-right: 40px;
129
130
  position: relative;
131
+ white-space: nowrap;
130
132
  overflow: hidden;
131
133
  white-space: nowrap;
132
134
  text-overflow: ellipsis;
@@ -245,15 +247,17 @@ exports[`EditorToolbar should render normal save button 1`] = `
245
247
  <div
246
248
  class="emotion-14 emotion-15 emotion-16"
247
249
  >
248
- <span
249
- aria-expanded="false"
250
- aria-haspopup="true"
251
- class="emotion-17 emotion-18"
252
- role="button"
253
- tabindex="0"
254
- >
255
- editor.editorToolbar.publish
256
- </span>
250
+ <div>
251
+ <span
252
+ aria-expanded="false"
253
+ aria-haspopup="true"
254
+ class="emotion-17 emotion-18"
255
+ role="button"
256
+ tabindex="0"
257
+ >
258
+ editor.editorToolbar.publish
259
+ </span>
260
+ </div>
257
261
  </div>
258
262
  </div>
259
263
  <div>
@@ -383,6 +387,7 @@ exports[`EditorToolbar should render normal save button 2`] = `
383
387
  -moz-user-select: none;
384
388
  -ms-user-select: none;
385
389
  user-select: none;
390
+ touch-action: manipulation;
386
391
  margin: 0 10px;
387
392
  }
388
393
 
@@ -404,6 +409,7 @@ exports[`EditorToolbar should render normal save button 2`] = `
404
409
  padding-left: 20px;
405
410
  padding-right: 40px;
406
411
  position: relative;
412
+ white-space: nowrap;
407
413
  overflow: hidden;
408
414
  white-space: nowrap;
409
415
  text-overflow: ellipsis;
@@ -522,15 +528,17 @@ exports[`EditorToolbar should render normal save button 2`] = `
522
528
  <div
523
529
  class="emotion-14 emotion-15 emotion-16"
524
530
  >
525
- <span
526
- aria-expanded="false"
527
- aria-haspopup="true"
528
- class="emotion-17 emotion-18"
529
- role="button"
530
- tabindex="0"
531
- >
532
- editor.editorToolbar.publish
533
- </span>
531
+ <div>
532
+ <span
533
+ aria-expanded="false"
534
+ aria-haspopup="true"
535
+ class="emotion-17 emotion-18"
536
+ role="button"
537
+ tabindex="0"
538
+ >
539
+ editor.editorToolbar.publish
540
+ </span>
541
+ </div>
534
542
  </div>
535
543
  </div>
536
544
  <div>
@@ -927,6 +935,7 @@ exports[`EditorToolbar should render with status=draft,useOpenAuthoring=false 1`
927
935
  -moz-user-select: none;
928
936
  -ms-user-select: none;
929
937
  user-select: none;
938
+ touch-action: manipulation;
930
939
  margin: 0 10px;
931
940
  }
932
941
 
@@ -948,6 +957,7 @@ exports[`EditorToolbar should render with status=draft,useOpenAuthoring=false 1`
948
957
  padding-left: 20px;
949
958
  padding-right: 40px;
950
959
  position: relative;
960
+ white-space: nowrap;
951
961
  overflow: hidden;
952
962
  white-space: nowrap;
953
963
  text-overflow: ellipsis;
@@ -1072,15 +1082,17 @@ exports[`EditorToolbar should render with status=draft,useOpenAuthoring=false 1`
1072
1082
  <div
1073
1083
  class="emotion-16 emotion-17 emotion-18"
1074
1084
  >
1075
- <span
1076
- aria-expanded="false"
1077
- aria-haspopup="true"
1078
- class="emotion-19 emotion-20"
1079
- role="button"
1080
- tabindex="0"
1081
- >
1082
- editor.editorToolbar.status
1083
- </span>
1085
+ <div>
1086
+ <span
1087
+ aria-expanded="false"
1088
+ aria-haspopup="true"
1089
+ class="emotion-19 emotion-20"
1090
+ role="button"
1091
+ tabindex="0"
1092
+ >
1093
+ editor.editorToolbar.status
1094
+ </span>
1095
+ </div>
1084
1096
  </div>
1085
1097
  <button
1086
1098
  class="emotion-21 emotion-22"
@@ -1238,6 +1250,7 @@ exports[`EditorToolbar should render with status=draft,useOpenAuthoring=true 1`]
1238
1250
  -moz-user-select: none;
1239
1251
  -ms-user-select: none;
1240
1252
  user-select: none;
1253
+ touch-action: manipulation;
1241
1254
  margin: 0 10px;
1242
1255
  }
1243
1256
 
@@ -1259,6 +1272,7 @@ exports[`EditorToolbar should render with status=draft,useOpenAuthoring=true 1`]
1259
1272
  padding-left: 20px;
1260
1273
  padding-right: 40px;
1261
1274
  position: relative;
1275
+ white-space: nowrap;
1262
1276
  overflow: hidden;
1263
1277
  white-space: nowrap;
1264
1278
  text-overflow: ellipsis;
@@ -1417,15 +1431,17 @@ exports[`EditorToolbar should render with status=draft,useOpenAuthoring=true 1`]
1417
1431
  <div
1418
1432
  class="emotion-16 emotion-17 emotion-18"
1419
1433
  >
1420
- <span
1421
- aria-expanded="false"
1422
- aria-haspopup="true"
1423
- class="emotion-19 emotion-20"
1424
- role="button"
1425
- tabindex="0"
1426
- >
1427
- editor.editorToolbar.status
1428
- </span>
1434
+ <div>
1435
+ <span
1436
+ aria-expanded="false"
1437
+ aria-haspopup="true"
1438
+ class="emotion-19 emotion-20"
1439
+ role="button"
1440
+ tabindex="0"
1441
+ >
1442
+ editor.editorToolbar.status
1443
+ </span>
1444
+ </div>
1429
1445
  </div>
1430
1446
  <div
1431
1447
  class="emotion-21 emotion-22"
@@ -1610,6 +1626,7 @@ exports[`EditorToolbar should render with status=pending_publish,useOpenAuthorin
1610
1626
  -moz-user-select: none;
1611
1627
  -ms-user-select: none;
1612
1628
  user-select: none;
1629
+ touch-action: manipulation;
1613
1630
  margin: 0 10px;
1614
1631
  }
1615
1632
 
@@ -1631,6 +1648,7 @@ exports[`EditorToolbar should render with status=pending_publish,useOpenAuthorin
1631
1648
  padding-left: 20px;
1632
1649
  padding-right: 40px;
1633
1650
  position: relative;
1651
+ white-space: nowrap;
1634
1652
  overflow: hidden;
1635
1653
  white-space: nowrap;
1636
1654
  text-overflow: ellipsis;
@@ -1755,15 +1773,17 @@ exports[`EditorToolbar should render with status=pending_publish,useOpenAuthorin
1755
1773
  <div
1756
1774
  class="emotion-16 emotion-17 emotion-18"
1757
1775
  >
1758
- <span
1759
- aria-expanded="false"
1760
- aria-haspopup="true"
1761
- class="emotion-19 emotion-20"
1762
- role="button"
1763
- tabindex="0"
1764
- >
1765
- editor.editorToolbar.status
1766
- </span>
1776
+ <div>
1777
+ <span
1778
+ aria-expanded="false"
1779
+ aria-haspopup="true"
1780
+ class="emotion-19 emotion-20"
1781
+ role="button"
1782
+ tabindex="0"
1783
+ >
1784
+ editor.editorToolbar.status
1785
+ </span>
1786
+ </div>
1767
1787
  </div>
1768
1788
  <button
1769
1789
  class="emotion-21 emotion-22"
@@ -1921,6 +1941,7 @@ exports[`EditorToolbar should render with status=pending_publish,useOpenAuthorin
1921
1941
  -moz-user-select: none;
1922
1942
  -ms-user-select: none;
1923
1943
  user-select: none;
1944
+ touch-action: manipulation;
1924
1945
  margin: 0 10px;
1925
1946
  }
1926
1947
 
@@ -1942,6 +1963,7 @@ exports[`EditorToolbar should render with status=pending_publish,useOpenAuthorin
1942
1963
  padding-left: 20px;
1943
1964
  padding-right: 40px;
1944
1965
  position: relative;
1966
+ white-space: nowrap;
1945
1967
  overflow: hidden;
1946
1968
  white-space: nowrap;
1947
1969
  text-overflow: ellipsis;
@@ -2082,15 +2104,17 @@ exports[`EditorToolbar should render with status=pending_publish,useOpenAuthorin
2082
2104
  <div
2083
2105
  class="emotion-16 emotion-17 emotion-18"
2084
2106
  >
2085
- <span
2086
- aria-expanded="false"
2087
- aria-haspopup="true"
2088
- class="emotion-19 emotion-20"
2089
- role="button"
2090
- tabindex="0"
2091
- >
2092
- editor.editorToolbar.status
2093
- </span>
2107
+ <div>
2108
+ <span
2109
+ aria-expanded="false"
2110
+ aria-haspopup="true"
2111
+ class="emotion-19 emotion-20"
2112
+ role="button"
2113
+ tabindex="0"
2114
+ >
2115
+ editor.editorToolbar.status
2116
+ </span>
2117
+ </div>
2094
2118
  </div>
2095
2119
  <div
2096
2120
  class="emotion-21 emotion-22"
@@ -2270,6 +2294,7 @@ exports[`EditorToolbar should render with status=pending_review,useOpenAuthoring
2270
2294
  -moz-user-select: none;
2271
2295
  -ms-user-select: none;
2272
2296
  user-select: none;
2297
+ touch-action: manipulation;
2273
2298
  margin: 0 10px;
2274
2299
  }
2275
2300
 
@@ -2291,6 +2316,7 @@ exports[`EditorToolbar should render with status=pending_review,useOpenAuthoring
2291
2316
  padding-left: 20px;
2292
2317
  padding-right: 40px;
2293
2318
  position: relative;
2319
+ white-space: nowrap;
2294
2320
  overflow: hidden;
2295
2321
  white-space: nowrap;
2296
2322
  text-overflow: ellipsis;
@@ -2415,15 +2441,17 @@ exports[`EditorToolbar should render with status=pending_review,useOpenAuthoring
2415
2441
  <div
2416
2442
  class="emotion-16 emotion-17 emotion-18"
2417
2443
  >
2418
- <span
2419
- aria-expanded="false"
2420
- aria-haspopup="true"
2421
- class="emotion-19 emotion-20"
2422
- role="button"
2423
- tabindex="0"
2424
- >
2425
- editor.editorToolbar.status
2426
- </span>
2444
+ <div>
2445
+ <span
2446
+ aria-expanded="false"
2447
+ aria-haspopup="true"
2448
+ class="emotion-19 emotion-20"
2449
+ role="button"
2450
+ tabindex="0"
2451
+ >
2452
+ editor.editorToolbar.status
2453
+ </span>
2454
+ </div>
2427
2455
  </div>
2428
2456
  <button
2429
2457
  class="emotion-21 emotion-22"
@@ -2581,6 +2609,7 @@ exports[`EditorToolbar should render with status=pending_review,useOpenAuthoring
2581
2609
  -moz-user-select: none;
2582
2610
  -ms-user-select: none;
2583
2611
  user-select: none;
2612
+ touch-action: manipulation;
2584
2613
  margin: 0 10px;
2585
2614
  }
2586
2615
 
@@ -2602,6 +2631,7 @@ exports[`EditorToolbar should render with status=pending_review,useOpenAuthoring
2602
2631
  padding-left: 20px;
2603
2632
  padding-right: 40px;
2604
2633
  position: relative;
2634
+ white-space: nowrap;
2605
2635
  overflow: hidden;
2606
2636
  white-space: nowrap;
2607
2637
  text-overflow: ellipsis;
@@ -2760,15 +2790,17 @@ exports[`EditorToolbar should render with status=pending_review,useOpenAuthoring
2760
2790
  <div
2761
2791
  class="emotion-16 emotion-17 emotion-18"
2762
2792
  >
2763
- <span
2764
- aria-expanded="false"
2765
- aria-haspopup="true"
2766
- class="emotion-19 emotion-20"
2767
- role="button"
2768
- tabindex="0"
2769
- >
2770
- editor.editorToolbar.status
2771
- </span>
2793
+ <div>
2794
+ <span
2795
+ aria-expanded="false"
2796
+ aria-haspopup="true"
2797
+ class="emotion-19 emotion-20"
2798
+ role="button"
2799
+ tabindex="0"
2800
+ >
2801
+ editor.editorToolbar.status
2802
+ </span>
2803
+ </div>
2772
2804
  </div>
2773
2805
  <div
2774
2806
  class="emotion-21 emotion-22"
@@ -3,7 +3,14 @@ import PropTypes from 'prop-types';
3
3
  import { css } from '@emotion/react';
4
4
  import styled from '@emotion/styled';
5
5
  import { translate } from 'react-polyglot';
6
- import { Icon, Dropdown, DropdownItem, DropdownButton, colors } from 'decap-cms-ui-default';
6
+ import {
7
+ Icon,
8
+ Dropdown,
9
+ DropdownItem,
10
+ DropdownButton,
11
+ colors,
12
+ shadows,
13
+ } from 'decap-cms-ui-default';
7
14
 
8
15
  import { stripProtocol } from '../../lib/urlHelper';
9
16
 
@@ -33,18 +40,32 @@ const AvatarPlaceholderIcon = styled(Icon)`
33
40
  background-color: ${colors.textFieldBorder};
34
41
  `;
35
42
 
36
- const AppHeaderSiteLink = styled.a`
43
+ const AppHeaderLink = css`
37
44
  font-size: 14px;
38
45
  font-weight: 400;
39
- color: #7b8290;
46
+ color: ${colors.text};
40
47
  padding: 10px 16px;
48
+ overflow: hidden;
49
+ text-overflow: ellipsis;
50
+ white-space: nowrap;
41
51
  `;
42
52
 
53
+ const AppHeaderSiteLink = styled.a(AppHeaderLink);
54
+
43
55
  const AppHeaderTestRepoIndicator = styled.a`
44
- font-size: 14px;
45
- font-weight: 400;
46
- color: #7b8290;
47
- padding: 10px 16px;
56
+ ${AppHeaderLink};
57
+
58
+ @media (max-width: 399px) {
59
+ position: absolute;
60
+ top: 0;
61
+ left: 50%;
62
+ transform: translateX(-50%);
63
+ font-size: 12px;
64
+ background-color: ${colors.background};
65
+ padding: 4px 12px;
66
+ border-radius: 0 0 4px 4px;
67
+ ${shadows.drop}
68
+ }
48
69
  `;
49
70
 
50
71
  function Avatar({ imageUrl }) {
@@ -59,9 +80,15 @@ Avatar.propTypes = {
59
80
  imageUrl: PropTypes.string,
60
81
  };
61
82
 
83
+ const SettingsWrapper = styled.div`
84
+ display: flex;
85
+ align-items: center;
86
+ min-width: 0;
87
+ `;
88
+
62
89
  function SettingsDropdown({ displayUrl, isTestRepo, imageUrl, onLogoutClick, t }) {
63
90
  return (
64
- <React.Fragment>
91
+ <SettingsWrapper>
65
92
  {isTestRepo && (
66
93
  <AppHeaderTestRepoIndicator
67
94
  href="https://www.decapcms.org/docs/test-backend"
@@ -88,7 +115,7 @@ function SettingsDropdown({ displayUrl, isTestRepo, imageUrl, onLogoutClick, t }
88
115
  >
89
116
  <DropdownItem label={t('ui.settingsDropdown.logOut')} onClick={onLogoutClick} />
90
117
  </Dropdown>
91
- </React.Fragment>
118
+ </SettingsWrapper>
92
119
  );
93
120
  }
94
121
 
@@ -477,22 +477,25 @@ describe('config', () => {
477
477
  merge({}, validConfig, { collections: [{ meta: { path: { label: 'Label' } } }] }),
478
478
  );
479
479
  }).toThrowError("'collections[0].meta.path' must have required property 'widget'");
480
+ });
481
+
482
+ it('should allow collection meta to have a path configuration with index_file', () => {
480
483
  expect(() => {
481
484
  validateConfig(
482
485
  merge({}, validConfig, {
483
- collections: [{ meta: { path: { label: 'Label', widget: 'widget' } } }],
486
+ collections: [
487
+ { meta: { path: { label: 'Path', widget: 'string', index_file: 'index' } } },
488
+ ],
484
489
  }),
485
490
  );
486
- }).toThrowError("'collections[0].meta.path' must have required property 'index_file'");
491
+ }).not.toThrow();
487
492
  });
488
493
 
489
- it('should allow collection meta to have a path configuration', () => {
494
+ it('should allow collection meta to have a path configuration without index_file', () => {
490
495
  expect(() => {
491
496
  validateConfig(
492
497
  merge({}, validConfig, {
493
- collections: [
494
- { meta: { path: { label: 'Path', widget: 'string', index_file: 'index' } } },
495
- ],
498
+ collections: [{ meta: { path: { label: 'Path', widget: 'string' } } }],
496
499
  }),
497
500
  );
498
501
  }).not.toThrow();
@@ -224,6 +224,7 @@ function getConfigSchema() {
224
224
  file: { type: 'string' },
225
225
  preview_path: { type: 'string' },
226
226
  preview_path_date_field: { type: 'string' },
227
+ preview_path_preserve_slashes: { type: 'boolean' },
227
228
  fields: fieldsConfig(),
228
229
  },
229
230
  required: ['name', 'label', 'file', 'fields'],
@@ -236,6 +237,7 @@ function getConfigSchema() {
236
237
  path: { type: 'string' },
237
238
  preview_path: { type: 'string' },
238
239
  preview_path_date_field: { type: 'string' },
240
+ preview_path_preserve_slashes: { type: 'boolean' },
239
241
  create: { type: 'boolean' },
240
242
  publish: { type: 'boolean' },
241
243
  hide: { type: 'boolean' },
@@ -303,7 +305,7 @@ function getConfigSchema() {
303
305
  widget: { type: 'string' },
304
306
  index_file: { type: 'string' },
305
307
  },
306
- required: ['label', 'widget', 'index_file'],
308
+ required: ['label', 'widget'],
307
309
  },
308
310
  },
309
311
  additionalProperties: false,