@plone/volto 19.0.0-alpha.3 → 19.0.0-alpha.4

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 (96) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/cypress/support/commands.js +5 -0
  3. package/locales/af.json +1 -1
  4. package/locales/ar.json +1 -1
  5. package/locales/bg.json +1 -1
  6. package/locales/bn.json +1 -1
  7. package/locales/ca/LC_MESSAGES/volto.po +5 -1
  8. package/locales/ca.json +1 -1
  9. package/locales/cs.json +1 -1
  10. package/locales/cy.json +1 -1
  11. package/locales/da.json +1 -1
  12. package/locales/de/LC_MESSAGES/volto.po +5 -1
  13. package/locales/de.json +1 -1
  14. package/locales/el.json +1 -1
  15. package/locales/en/LC_MESSAGES/volto.po +5 -1
  16. package/locales/en.json +1 -1
  17. package/locales/en_AU.json +1 -1
  18. package/locales/en_GB.json +1 -1
  19. package/locales/eo.json +1 -1
  20. package/locales/es/LC_MESSAGES/volto.po +5 -1
  21. package/locales/es.json +1 -1
  22. package/locales/et.json +1 -1
  23. package/locales/eu/LC_MESSAGES/volto.po +5 -1
  24. package/locales/eu.json +1 -1
  25. package/locales/fa.json +1 -1
  26. package/locales/fi/LC_MESSAGES/volto.po +5 -1
  27. package/locales/fi.json +1 -1
  28. package/locales/fr/LC_MESSAGES/volto.po +5 -1
  29. package/locales/fr.json +1 -1
  30. package/locales/fu.json +1 -1
  31. package/locales/gl.json +1 -1
  32. package/locales/he.json +1 -1
  33. package/locales/hi/LC_MESSAGES/volto.po +5 -1
  34. package/locales/hi.json +1 -1
  35. package/locales/hr.json +1 -1
  36. package/locales/hu.json +1 -1
  37. package/locales/hy.json +1 -1
  38. package/locales/id.json +1 -1
  39. package/locales/it/LC_MESSAGES/volto.po +5 -1
  40. package/locales/it.json +1 -1
  41. package/locales/ja/LC_MESSAGES/volto.po +5 -1
  42. package/locales/ja.json +1 -1
  43. package/locales/ka.json +1 -1
  44. package/locales/kn.json +1 -1
  45. package/locales/ko.json +1 -1
  46. package/locales/lt.json +1 -1
  47. package/locales/lv.json +1 -1
  48. package/locales/mi.json +1 -1
  49. package/locales/mk.json +1 -1
  50. package/locales/my.json +1 -1
  51. package/locales/nb_NO.json +1 -1
  52. package/locales/nl/LC_MESSAGES/volto.po +5 -1
  53. package/locales/nl.json +1 -1
  54. package/locales/nn.json +1 -1
  55. package/locales/pl.json +1 -1
  56. package/locales/pt/LC_MESSAGES/volto.po +5 -1
  57. package/locales/pt.json +1 -1
  58. package/locales/pt_BR/LC_MESSAGES/volto.po +5 -1
  59. package/locales/pt_BR.json +1 -1
  60. package/locales/rm.json +1 -1
  61. package/locales/ro/LC_MESSAGES/volto.po +5 -1
  62. package/locales/ro.json +1 -1
  63. package/locales/ru/LC_MESSAGES/volto.po +5 -1
  64. package/locales/ru.json +1 -1
  65. package/locales/sk.json +1 -1
  66. package/locales/sl.json +1 -1
  67. package/locales/sm.json +1 -1
  68. package/locales/sq.json +1 -1
  69. package/locales/sr.json +1 -1
  70. package/locales/sr@cyrl.json +1 -1
  71. package/locales/sr@latn.json +1 -1
  72. package/locales/sv.json +1 -1
  73. package/locales/ta.json +1 -1
  74. package/locales/te.json +1 -1
  75. package/locales/th.json +1 -1
  76. package/locales/to.json +1 -1
  77. package/locales/tr.json +1 -1
  78. package/locales/uk.json +1 -1
  79. package/locales/vi.json +1 -1
  80. package/locales/volto.pot +6 -2
  81. package/locales/zh_CN/LC_MESSAGES/volto.po +5 -1
  82. package/locales/zh_CN.json +1 -1
  83. package/locales/zh_Hant.json +1 -1
  84. package/locales/zh_Hant_HK.json +1 -1
  85. package/package.json +5 -5
  86. package/src/components/manage/Contents/ContentsItem.jsx +1 -1
  87. package/src/components/manage/UniversalLink/UniversalLink.tsx +1 -0
  88. package/src/components/manage/Widgets/RegistryImageWidget.test.jsx +1 -1
  89. package/src/components/manage/Widgets/SelectAutoComplete.jsx +29 -12
  90. package/src/config/ControlPanels.js +1 -0
  91. package/src/config/index.js +1 -1
  92. package/src/express-middleware/devproxy.js +7 -2
  93. package/src/helpers/Html/Html.jsx +9 -1
  94. package/src/helpers/Url/bulkFlattenToAppURL.test.ts +122 -0
  95. package/src/helpers/Url/bulkFlattenToAppURL.ts +24 -0
  96. package/types/helpers/Url/bulkFlattenToAppURL.d.ts +5 -0
@@ -141,7 +141,7 @@ let config = {
141
141
  serverConfig,
142
142
  storeExtenders: [],
143
143
  showTags: true,
144
- showRelatedItems: false,
144
+ showRelatedItems: true,
145
145
  controlpanels: [],
146
146
  controlPanelsIcons,
147
147
  filterControlPanels,
@@ -10,8 +10,13 @@ import querystring from 'querystring';
10
10
  import { parse as parseUrl } from 'url';
11
11
 
12
12
  const filter = function (pathname, req) {
13
- // This is the proxy to the API in case the accept header is 'application/json'
14
- return config.settings.devProxyToApiPath && pathname.startsWith('/++api++');
13
+ // Check if pathname is defined, there are some corner cases that pathname is null
14
+ if (pathname) {
15
+ // This is the proxy to the API in case the accept header is 'application/json'
16
+ return config.settings.devProxyToApiPath && pathname.startsWith('/++api++');
17
+ } else {
18
+ return false;
19
+ }
15
20
  };
16
21
 
17
22
  let _env = null;
@@ -11,6 +11,7 @@ import join from 'lodash/join';
11
11
  import BodyClass from '@plone/volto/helpers/BodyClass/BodyClass';
12
12
  import { runtimeConfig } from '@plone/volto/runtime_config';
13
13
  import config from '@plone/volto/registry';
14
+ import { bulkFlattenToAppURL } from '../Url/bulkFlattenToAppURL';
14
15
 
15
16
  const CRITICAL_CSS_TEMPLATE = `function alter() {
16
17
  document.querySelectorAll("head link[rel='prefetch']").forEach(function(el) { el.rel = 'stylesheet'});
@@ -189,7 +190,14 @@ class Html extends Component {
189
190
  <script
190
191
  dangerouslySetInnerHTML={{
191
192
  __html: `window.__data=${serialize(
192
- loadReducers(store.getState()),
193
+ loadReducers({
194
+ ...store.getState(),
195
+ // Flatten the content URLs in initial request in SSR
196
+ // it normalizes the URLs in case the INTERNAL_API_PATH is set
197
+ // and prevents unwanted leaks of INTERNAL_API_PATH in the client
198
+ // (only in the first request)
199
+ content: bulkFlattenToAppURL(store.getState().content),
200
+ }),
193
201
  )};`,
194
202
  }}
195
203
  charSet="UTF-8"
@@ -0,0 +1,122 @@
1
+ import { describe, it, expect, afterEach } from 'vitest';
2
+ import config from '@plone/registry';
3
+ import { bulkFlattenToAppURL } from './bulkFlattenToAppURL';
4
+
5
+ const API_PATH = 'http://example.com/api';
6
+ const INTERNAL_API_PATH = 'http://backend/api';
7
+
8
+ describe('bulkFlattenToAppURL', () => {
9
+ afterEach(() => {
10
+ config.settings = {};
11
+ });
12
+
13
+ it('should flatten URLs correctly with API_PATH', () => {
14
+ config.settings.apiPath = API_PATH;
15
+
16
+ const input = {
17
+ '@id': `${API_PATH}/path/to/resource`,
18
+ anotherField: `${API_PATH}/another/path`,
19
+ nested: {
20
+ '@id': `${API_PATH}/nested/resource`,
21
+ anotherNestedField: `${API_PATH}/nested/another/path`,
22
+ },
23
+ arrayField: [
24
+ {
25
+ '@id': `${API_PATH}/array/resource/1`,
26
+ anotherArrayField: `${API_PATH}/array/another/path/1`,
27
+ },
28
+ {
29
+ '@id': `${API_PATH}/array/resource/2`,
30
+ anotherArrayField: `${API_PATH}/array/another/path/2`,
31
+ },
32
+ ],
33
+ stringField: 'This is a string',
34
+ numberField: 42,
35
+ booleanField: true,
36
+ nullField: null,
37
+ undefinedField: undefined,
38
+ };
39
+
40
+ const expectedOutput = {
41
+ '@id': '/path/to/resource',
42
+ anotherField: '/another/path',
43
+ nested: {
44
+ '@id': '/nested/resource',
45
+ anotherNestedField: '/nested/another/path',
46
+ },
47
+ arrayField: [
48
+ {
49
+ '@id': '/array/resource/1',
50
+ anotherArrayField: '/array/another/path/1',
51
+ },
52
+ {
53
+ '@id': '/array/resource/2',
54
+ anotherArrayField: '/array/another/path/2',
55
+ },
56
+ ],
57
+ stringField: 'This is a string',
58
+ numberField: 42,
59
+ booleanField: true,
60
+ nullField: null,
61
+ undefinedField: undefined,
62
+ };
63
+
64
+ const result = bulkFlattenToAppURL(input as any);
65
+ expect(result).toEqual(expectedOutput);
66
+ });
67
+
68
+ it('should flatten URLs correctly with INTERNAL_API_PATH', () => {
69
+ config.settings.internalApiPath = INTERNAL_API_PATH;
70
+
71
+ const input = {
72
+ '@id': `${INTERNAL_API_PATH}/path/to/resource`,
73
+ anotherField: `${INTERNAL_API_PATH}/another/path`,
74
+ nested: {
75
+ '@id': `${INTERNAL_API_PATH}/nested/resource`,
76
+ anotherNestedField: `${INTERNAL_API_PATH}/nested/another/path`,
77
+ },
78
+ arrayField: [
79
+ {
80
+ '@id': `${INTERNAL_API_PATH}/array/resource/1`,
81
+ anotherArrayField: `${INTERNAL_API_PATH}/array/another/path/1`,
82
+ },
83
+ {
84
+ '@id': `${INTERNAL_API_PATH}/array/resource/2`,
85
+ anotherArrayField: `${INTERNAL_API_PATH}/array/another/path/2`,
86
+ },
87
+ ],
88
+ stringField: 'This is a string',
89
+ numberField: 42,
90
+ booleanField: true,
91
+ nullField: null,
92
+ undefinedField: undefined,
93
+ };
94
+
95
+ const expectedOutput = {
96
+ '@id': '/path/to/resource',
97
+ anotherField: '/another/path',
98
+ nested: {
99
+ '@id': '/nested/resource',
100
+ anotherNestedField: '/nested/another/path',
101
+ },
102
+ arrayField: [
103
+ {
104
+ '@id': '/array/resource/1',
105
+ anotherArrayField: '/array/another/path/1',
106
+ },
107
+ {
108
+ '@id': '/array/resource/2',
109
+ anotherArrayField: '/array/another/path/2',
110
+ },
111
+ ],
112
+ stringField: 'This is a string',
113
+ numberField: 42,
114
+ booleanField: true,
115
+ nullField: null,
116
+ undefinedField: undefined,
117
+ };
118
+
119
+ const result = bulkFlattenToAppURL(input as any);
120
+ expect(result).toEqual(expectedOutput);
121
+ });
122
+ });
@@ -0,0 +1,24 @@
1
+ import config from '@plone/registry';
2
+
3
+ /**
4
+ * The definitive flattenToAppURL function
5
+ * Flattens all the URLs in the response to the current app URL (or internalApiPath if set).
6
+ */
7
+ export function bulkFlattenToAppURL<T>(data: T) {
8
+ // Convert data to string to perform replacements
9
+ let stringData = JSON.stringify(data);
10
+
11
+ // Replace all occurrences of backend URLs
12
+ stringData = stringData.replaceAll(`${config.settings.apiPath}/`, '/');
13
+ stringData = stringData.replaceAll(config.settings.apiPath, '/');
14
+ if (config.settings.internalApiPath) {
15
+ stringData = stringData.replaceAll(
16
+ `${config.settings.internalApiPath}/`,
17
+ '/',
18
+ );
19
+ stringData = stringData.replaceAll(config.settings.internalApiPath, '/');
20
+ }
21
+
22
+ // Parse back to object
23
+ return JSON.parse(stringData) as T;
24
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * The definitive flattenToAppURL function
3
+ * Flattens all the URLs in the response to the current app URL (or internalApiPath if set).
4
+ */
5
+ export declare function bulkFlattenToAppURL<T>(data: T): T;