@exdst-sitecore-content-sdk/astro 0.0.16 → 0.0.19
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 +3 -3
- package/package.json +41 -42
- package/src/client/index.ts +1 -1
- package/src/client/sitecore-astro-client.test.ts +41 -20
- package/src/client/sitecore-astro-client.ts +74 -57
- package/src/components/AstroImage.astro +2 -2
- package/src/components/AstroImage.astro.test.ts +542 -0
- package/src/components/Date.astro +5 -1
- package/src/components/Date.astro.test.ts +197 -0
- package/src/components/DefaultEmptyFieldEditingComponentImage.astro +4 -0
- package/src/components/DefaultEmptyFieldEditingComponentText.astro +4 -0
- package/src/components/EditingScripts.astro +2 -2
- package/src/components/EditingScripts.astro.test.ts +267 -0
- package/src/components/ErrorBoundary.astro +8 -9
- package/src/components/ErrorBoundary.astro.test.ts +252 -0
- package/src/components/ErrorComponent.astro +16 -0
- package/src/components/ErrorComponent.astro.test.ts +31 -0
- package/src/components/FieldMetadata.astro +1 -1
- package/src/components/FieldMetadata.astro.test.ts +40 -0
- package/src/components/File.astro +5 -1
- package/src/components/File.astro.test.ts +68 -0
- package/src/components/HiddenRendering.astro.test.ts +36 -0
- package/src/components/Image.astro +18 -4
- package/src/components/Image.astro.test.ts +438 -0
- package/src/components/Link.astro +13 -1
- package/src/components/Link.astro.test.ts +261 -0
- package/src/components/MissingComponent.astro.test.ts +21 -0
- package/src/components/Placeholder/Placeholder.astro +18 -23
- package/src/components/Placeholder/Placeholder.astro.test.ts +1088 -0
- package/src/components/Placeholder/PlaceholderMetadata.astro +24 -18
- package/src/components/Placeholder/PlaceholderMetadata.astro.test.ts +228 -0
- package/src/components/Placeholder/PlaceholderUtils.astro +21 -40
- package/src/components/Placeholder/PlaceholderUtils.astro.test.ts +149 -0
- package/src/components/Placeholder/models.ts +26 -17
- package/src/components/Placeholder/placeholder-utils.test.ts +153 -6
- package/src/components/Placeholder/placeholder-utils.ts +33 -11
- package/src/components/RichText.astro +9 -1
- package/src/components/RichText.astro.test.ts +205 -0
- package/src/components/Text.astro +15 -3
- package/src/components/Text.astro.test.ts +273 -0
- package/src/config/define-config.test.ts +5 -5
- package/src/config/define-config.ts +22 -42
- package/src/config-cli/define-cli-config.test.ts +5 -12
- package/src/config-cli/define-cli-config.ts +4 -8
- package/src/context.ts +42 -11
- package/src/debug.ts +13 -0
- package/src/editing/editing-config-middleware.test.ts +5 -7
- package/src/editing/editing-config-middleware.ts +11 -7
- package/src/editing/editing-render-middleware.test.ts +366 -24
- package/src/editing/editing-render-middleware.ts +34 -12
- package/src/editing/index.ts +2 -0
- package/src/editing/render-middleware.test.ts +1 -1
- package/src/editing/render-middleware.ts +1 -1
- package/src/editing/types.ts +39 -0
- package/src/editing/utils.test.ts +364 -4
- package/src/editing/utils.ts +82 -24
- package/src/enhancers/WithEmptyFieldEditingComponent.astro +1 -1
- package/src/enhancers/WithEmptyFieldEditingComponent.astro.test.ts +380 -0
- package/src/enhancers/WithFieldMetadata.astro.test.ts +113 -0
- package/src/index.ts +10 -7
- package/src/middleware/index.ts +4 -12
- package/src/middleware/middleware.test.ts +13 -0
- package/src/middleware/middleware.ts +12 -3
- package/src/middleware/multisite-middleware.test.ts +45 -50
- package/src/middleware/multisite-middleware.ts +33 -6
- package/src/middleware/robots-middleware.test.ts +20 -4
- package/src/middleware/robots-middleware.ts +10 -3
- package/src/middleware/sitemap-middleware.test.ts +35 -3
- package/src/middleware/sitemap-middleware.ts +7 -6
- package/src/services/component-props-service.ts +7 -6
- package/src/sharedTypes/component-props.ts +15 -4
- package/src/site/index.ts +1 -1
- package/src/tests/astro-helpers.ts +61 -0
- package/src/tests/test-components/CustomErrorComponent.astro +3 -0
- package/src/tests/test-components/CustomHiddenRendering.astro +10 -0
- package/src/tests/test-components/CustomMissingComponent.astro +9 -0
- package/src/tests/test-components/DownloadCallout.astro +12 -0
- package/src/tests/test-components/EmptyFieldEditingComponent.astro +5 -0
- package/src/tests/test-components/ErrorBoundaryWithError.astro +10 -0
- package/src/tests/test-components/Home.astro +12 -0
- package/src/tests/test-components/SxaRichText.astro +23 -0
- package/src/tests/test-components/SxaRichTextDefault.astro +7 -0
- package/src/tests/test-components/SxaRichTextWithTitle.astro +8 -0
- package/src/tests/test-components/TestComponent.astro +9 -0
- package/src/tests/test-components/TestComponentWithError.astro +4 -0
- package/src/tests/test-components/TestComponentWithField.astro +17 -0
- package/src/tests/test-components/TestHeader.astro +8 -0
- package/src/tests/test-components/TestLogo.astro +5 -0
- package/src/tests/test-components/TestParentWrapperComponent.astro +5 -0
- package/src/tests/test-components/TestWrapperComponent.astro +5 -0
- package/src/tests/test-data/metadata-data.ts +86 -0
- package/src/tests/test-data/normal-mode-data.ts +466 -0
- package/src/tests/vitest.setup.ts +4 -0
- package/src/tools/generate-map.ts +4 -3
- package/src/tools/index.ts +2 -4
- package/src/tools/templating/components.test.ts +100 -87
- package/src/tools/templating/components.ts +2 -1
- package/src/tools/templating/default-component.ts +3 -8
- package/src/utils/utils.ts +20 -2
- /package/src/{test-data → tests}/helpers.ts +0 -0
- /package/src/{test-data → tests}/personalizeData.ts +0 -0
- /package/src/{test-data/components → tests/test-components/map-components}/Bar.astro +0 -0
- /package/src/{test-data/components → tests/test-components/map-components}/Baz.astro +0 -0
- /package/src/{test-data/components → tests/test-components/map-components}/Foo.astro +0 -0
- /package/src/{test-data/components → tests/test-components/map-components}/Hero.variant.astro +0 -0
- /package/src/{test-data/components → tests/test-components/map-components}/NotComponent.bsx +0 -0
- /package/src/{test-data/components → tests/test-components/map-components}/Qux.astro +0 -0
- /package/src/{test-data/components → tests/test-components/map-components}/folded/Folded.astro +0 -0
- /package/src/{test-data/components → tests/test-components/map-components}/folded/random-file-2.docx +0 -0
- /package/src/{test-data/components → tests/test-components/map-components}/random-file.txt +0 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import { describe, test, expect } from 'vitest';
|
|
2
|
+
import { renderAstroComponent } from '../tests/astro-helpers';
|
|
3
|
+
import Text, { TextField } from './Text.astro';
|
|
4
|
+
import EmptyFieldEditingComponent from '../tests/test-components/EmptyFieldEditingComponent.astro';
|
|
5
|
+
|
|
6
|
+
describe('<Text />', () => {
|
|
7
|
+
test('should render nothing with missing field', async () => {
|
|
8
|
+
const field: TextField = null!;
|
|
9
|
+
const rendered = await renderAstroComponent(Text, {
|
|
10
|
+
props: { field: field },
|
|
11
|
+
});
|
|
12
|
+
expect(rendered.innerHTML).to.equal('');
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test('should render nothing with missing field', async () => {
|
|
16
|
+
const field = {
|
|
17
|
+
value: '',
|
|
18
|
+
};
|
|
19
|
+
const rendered = await renderAstroComponent(Text, {
|
|
20
|
+
props: { field: field },
|
|
21
|
+
});
|
|
22
|
+
expect(rendered.innerHTML).to.equal('');
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('should render nothing with missing value', async () => {
|
|
26
|
+
const field = {};
|
|
27
|
+
const rendered = await renderAstroComponent(Text, {
|
|
28
|
+
props: { field: field },
|
|
29
|
+
});
|
|
30
|
+
expect(rendered.innerHTML).to.equal('');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('should render value with editing explicitly disabled', async () => {
|
|
34
|
+
const field = {
|
|
35
|
+
value: 'value',
|
|
36
|
+
};
|
|
37
|
+
const rendered = (
|
|
38
|
+
await renderAstroComponent(Text, {
|
|
39
|
+
props: { field: field, tag: 'span', editable: false },
|
|
40
|
+
})
|
|
41
|
+
).querySelector('span');
|
|
42
|
+
|
|
43
|
+
expect(rendered?.innerHTML).to.contain('value');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('should encode values with editing explicitly disabled', async () => {
|
|
47
|
+
const field = {
|
|
48
|
+
value: 'value < >',
|
|
49
|
+
};
|
|
50
|
+
const rendered = (
|
|
51
|
+
await renderAstroComponent(Text, {
|
|
52
|
+
props: { field: field, tag: 'span', editable: false },
|
|
53
|
+
})
|
|
54
|
+
).querySelector('span');
|
|
55
|
+
expect(rendered?.innerHTML).to.contain('< >');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test('should render value with just a value', async () => {
|
|
59
|
+
const field = {
|
|
60
|
+
value: 'value',
|
|
61
|
+
};
|
|
62
|
+
const rendered = (
|
|
63
|
+
await renderAstroComponent(Text, {
|
|
64
|
+
props: { field: field, tag: 'span' },
|
|
65
|
+
})
|
|
66
|
+
).querySelector('span');
|
|
67
|
+
expect(rendered?.innerHTML).to.contain('value');
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test('should render value without tag', async () => {
|
|
71
|
+
const field = {
|
|
72
|
+
value: 'value',
|
|
73
|
+
};
|
|
74
|
+
const rendered = await renderAstroComponent(Text, {
|
|
75
|
+
props: { field: field },
|
|
76
|
+
});
|
|
77
|
+
expect(rendered.innerHTML).to.equal('value');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test('should render number value', async () => {
|
|
81
|
+
const field = {
|
|
82
|
+
value: 1.23,
|
|
83
|
+
};
|
|
84
|
+
const rendered = await renderAstroComponent(Text, {
|
|
85
|
+
props: { field: field },
|
|
86
|
+
});
|
|
87
|
+
expect(rendered.innerHTML).to.equal('1.23');
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test('should render zero number value', async () => {
|
|
91
|
+
const field = {
|
|
92
|
+
value: 0,
|
|
93
|
+
};
|
|
94
|
+
const rendered = await renderAstroComponent(Text, {
|
|
95
|
+
props: { field: field },
|
|
96
|
+
});
|
|
97
|
+
expect(rendered?.innerHTML).to.equal('0');
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test('should render negative number value', async () => {
|
|
101
|
+
const field = {
|
|
102
|
+
value: -1.23,
|
|
103
|
+
};
|
|
104
|
+
const rendered = await renderAstroComponent(Text, {
|
|
105
|
+
props: { field: field },
|
|
106
|
+
});
|
|
107
|
+
expect(rendered?.innerHTML).to.equal('-1.23');
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test('should render value without tag', async () => {
|
|
111
|
+
const field = {
|
|
112
|
+
value: 'value',
|
|
113
|
+
};
|
|
114
|
+
const rendered = await renderAstroComponent(Text, {
|
|
115
|
+
props: { field: field },
|
|
116
|
+
});
|
|
117
|
+
expect(rendered?.innerHTML).to.contain('value');
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test('should render value with just a value that contains line breaks', async () => {
|
|
121
|
+
const field = {
|
|
122
|
+
value: 'xxx\n\naa\nbbb\ndd',
|
|
123
|
+
};
|
|
124
|
+
const rendered = (
|
|
125
|
+
await renderAstroComponent(Text, {
|
|
126
|
+
props: { field: field, tag: 'span' },
|
|
127
|
+
})
|
|
128
|
+
).querySelector('span');
|
|
129
|
+
expect(rendered?.innerHTML).to.contain('xxx<br><br>aa<br>bbb<br>dd');
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
test('should render value with just a value that contains only one line break', async () => {
|
|
133
|
+
const field = {
|
|
134
|
+
value: '\n',
|
|
135
|
+
};
|
|
136
|
+
const rendered = (
|
|
137
|
+
await renderAstroComponent(Text, {
|
|
138
|
+
props: { field: field, tag: 'span' },
|
|
139
|
+
})
|
|
140
|
+
).querySelector('span');
|
|
141
|
+
expect(rendered?.outerHTML).to.contain('<span><br></span>');
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test('should render embedded html as-is when encoding is disabled', async () => {
|
|
145
|
+
const field = {
|
|
146
|
+
value: '<input type="text">some crazy stuff<script code="whaaaat">uh oh</script>',
|
|
147
|
+
};
|
|
148
|
+
const rendered = (
|
|
149
|
+
await renderAstroComponent(Text, {
|
|
150
|
+
props: { field: field, encode: false },
|
|
151
|
+
})
|
|
152
|
+
).querySelector('span');
|
|
153
|
+
expect(rendered?.innerHTML).to.contain(field.value);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
test('should render tag with a tag provided', async () => {
|
|
157
|
+
const field = {
|
|
158
|
+
value: 'value',
|
|
159
|
+
};
|
|
160
|
+
const rendered = (
|
|
161
|
+
await renderAstroComponent(Text, {
|
|
162
|
+
props: { field: field, tag: 'h1' },
|
|
163
|
+
})
|
|
164
|
+
).querySelector('h1');
|
|
165
|
+
expect(rendered?.innerHTML).to.contain('value');
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
test('should render other attributes with other props provided', async () => {
|
|
169
|
+
const field = {
|
|
170
|
+
value: 'value',
|
|
171
|
+
};
|
|
172
|
+
const rendered = (
|
|
173
|
+
await renderAstroComponent(Text, {
|
|
174
|
+
props: { field: field, tag: 'h1', class: 'cssClass', id: 'lorem' },
|
|
175
|
+
})
|
|
176
|
+
).querySelector('h1');
|
|
177
|
+
expect(rendered?.outerHTML).to.contain('<h1 class="cssClass" id="lorem">');
|
|
178
|
+
expect(rendered?.outerHTML).to.contain('value');
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
describe('edit mode', () => {
|
|
182
|
+
const testMetadata = {
|
|
183
|
+
contextItem: {
|
|
184
|
+
id: '{09A07660-6834-476C-B93B-584248D3003B}',
|
|
185
|
+
language: 'en',
|
|
186
|
+
revision: 'a0b36ce0a7db49418edf90eb9621e145',
|
|
187
|
+
version: 1,
|
|
188
|
+
},
|
|
189
|
+
fieldId: '{414061F4-FBB1-4591-BC37-BFFA67F745EB}',
|
|
190
|
+
fieldType: 'single-line',
|
|
191
|
+
rawValue: 'Test1',
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
test('should render field metadata component when metadata property is present', async () => {
|
|
195
|
+
const field = {
|
|
196
|
+
value: 'value',
|
|
197
|
+
metadata: testMetadata,
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
const rendered = await renderAstroComponent(Text, {
|
|
201
|
+
props: { field: field },
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
expect(rendered.innerHTML).to.equal(
|
|
205
|
+
[
|
|
206
|
+
`<code type="text/sitecore" chrometype="field" class="scpm" kind="open">${JSON.stringify(
|
|
207
|
+
testMetadata
|
|
208
|
+
)}</code>`,
|
|
209
|
+
'<span>value</span>',
|
|
210
|
+
'<code type="text/sitecore" chrometype="field" class="scpm" kind="close"></code>',
|
|
211
|
+
].join('')
|
|
212
|
+
);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
test('should render default empty field component when field value is empty in edit mode metadata', async () => {
|
|
216
|
+
const field = {
|
|
217
|
+
value: '',
|
|
218
|
+
metadata: testMetadata,
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
const rendered = await renderAstroComponent(Text, {
|
|
222
|
+
props: { field: field },
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
expect(rendered.innerHTML).to.equal(
|
|
226
|
+
[
|
|
227
|
+
`<code type="text/sitecore" chrometype="field" class="scpm" kind="open">${JSON.stringify(
|
|
228
|
+
testMetadata
|
|
229
|
+
)}</code>`,
|
|
230
|
+
'<span>[No text in field]</span>',
|
|
231
|
+
'<code type="text/sitecore" chrometype="field" class="scpm" kind="close"></code>',
|
|
232
|
+
].join('')
|
|
233
|
+
);
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
test('should render custom empty field component when provided, when field value is empty in edit mode metadata', async () => {
|
|
237
|
+
const field = {
|
|
238
|
+
value: '',
|
|
239
|
+
metadata: testMetadata,
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
const rendered = await renderAstroComponent(Text, {
|
|
243
|
+
props: {
|
|
244
|
+
field: field,
|
|
245
|
+
emptyFieldEditingComponent: EmptyFieldEditingComponent,
|
|
246
|
+
},
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
expect(rendered.innerHTML).to.equal(
|
|
250
|
+
[
|
|
251
|
+
`<code type="text/sitecore" chrometype="field" class="scpm" kind="open">${JSON.stringify(
|
|
252
|
+
testMetadata
|
|
253
|
+
)}</code>`,
|
|
254
|
+
'<span class="empty-field-value-placeholder">Custom Empty field value</span>',
|
|
255
|
+
'<code type="text/sitecore" chrometype="field" class="scpm" kind="close"></code>',
|
|
256
|
+
].join('')
|
|
257
|
+
);
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
test('should render nothing when field value is empty, when editing is explicitly disabled in edit mode metadata ', async () => {
|
|
261
|
+
const field = {
|
|
262
|
+
value: '',
|
|
263
|
+
metadata: testMetadata,
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
const rendered = await renderAstroComponent(Text, {
|
|
267
|
+
props: { field: field, editable: false },
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
expect(rendered.innerHTML).to.equal('');
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
});
|
|
@@ -17,7 +17,7 @@ describe('defineConfig', () => {
|
|
|
17
17
|
beforeEach(() => {
|
|
18
18
|
defineConfigCoreStub = sandbox.stub();
|
|
19
19
|
defineConfigModule = proxyquire('./define-config', {
|
|
20
|
-
'@sitecore-content-sdk/
|
|
20
|
+
'@sitecore-content-sdk/content/config': {
|
|
21
21
|
defineConfig: defineConfigCoreStub,
|
|
22
22
|
},
|
|
23
23
|
});
|
|
@@ -150,10 +150,10 @@ describe('defineConfig', () => {
|
|
|
150
150
|
|
|
151
151
|
describe('config.api.edge.edgeUrl', () => {
|
|
152
152
|
describe('environment variable is not set', () => {
|
|
153
|
-
it('should default to
|
|
153
|
+
it('should default to Edge Platform URL', () => {
|
|
154
154
|
defineConfigModule.defineConfig(defaultConfig());
|
|
155
155
|
const resultConfig = defineConfigCoreStub.getCalls()[0].args[0];
|
|
156
|
-
expect(resultConfig.api?.edge?.edgeUrl).to.
|
|
156
|
+
expect(resultConfig.api?.edge?.edgeUrl).to.equal('https://edge-platform.sitecorecloud.io');
|
|
157
157
|
});
|
|
158
158
|
|
|
159
159
|
it('should use the value from the config', () => {
|
|
@@ -167,11 +167,11 @@ describe('defineConfig', () => {
|
|
|
167
167
|
});
|
|
168
168
|
describe('environment variable is set', () => {
|
|
169
169
|
before(() => {
|
|
170
|
-
process.env.
|
|
170
|
+
process.env.PUBLIC_SITECORE_EDGE_PLATFORM_HOSTNAME = 'next-public-sitecore-edgeUrl';
|
|
171
171
|
});
|
|
172
172
|
|
|
173
173
|
after(() => {
|
|
174
|
-
delete process.env.
|
|
174
|
+
delete process.env.PUBLIC_SITECORE_EDGE_PLATFORM_HOSTNAME;
|
|
175
175
|
});
|
|
176
176
|
|
|
177
177
|
it('should use the value from the config if present', () => {
|
|
@@ -3,16 +3,18 @@ import {
|
|
|
3
3
|
DeepRequired,
|
|
4
4
|
defineConfig as defineConfigCore,
|
|
5
5
|
SitecoreConfigInput as SitecoreConfigInputCore,
|
|
6
|
-
} from '@sitecore-content-sdk/
|
|
6
|
+
} from '@sitecore-content-sdk/content/config';
|
|
7
|
+
import { resolveEdgeUrl } from '@sitecore-content-sdk/core/tools';
|
|
8
|
+
|
|
9
|
+
/** Env var for Edge hostname; exposed to the browser so client code can use it. */
|
|
10
|
+
const PUBLIC_SITECORE_EDGE_PLATFORM_HOSTNAME_ENV = 'PUBLIC_SITECORE_EDGE_PLATFORM_HOSTNAME';
|
|
7
11
|
|
|
8
12
|
/**
|
|
9
13
|
* Provides default Astro initial values from env variables for SitecoreConfig
|
|
10
14
|
* @param {SitecoreConfigInput} config optional override values to be written over default config settings
|
|
11
15
|
* @returns default Astro input config
|
|
12
16
|
*/
|
|
13
|
-
export const getAstroFallbackConfig = (
|
|
14
|
-
config?: SitecoreConfigInput
|
|
15
|
-
): SitecoreConfigInput => {
|
|
17
|
+
export const getAstroFallbackConfig = (config?: SitecoreConfigInput): SitecoreConfigInput => {
|
|
16
18
|
return {
|
|
17
19
|
...config,
|
|
18
20
|
api: {
|
|
@@ -21,64 +23,40 @@ export const getAstroFallbackConfig = (
|
|
|
21
23
|
...config?.api?.edge,
|
|
22
24
|
contextId: config?.api?.edge?.contextId || '',
|
|
23
25
|
clientContextId:
|
|
24
|
-
config?.api?.edge?.clientContextId ||
|
|
25
|
-
|
|
26
|
-
process.env.
|
|
27
|
-
|
|
28
|
-
config?.api?.edge?.edgeUrl ||
|
|
29
|
-
import.meta.env?.PUBLIC_SITECORE_EDGE_URL ||
|
|
30
|
-
process.env.PUBLIC_SITECORE_EDGE_URL,
|
|
26
|
+
config?.api?.edge?.clientContextId || process.env.PUBLIC_SITECORE_EDGE_CONTEXT_ID,
|
|
27
|
+
edgeUrl: resolveEdgeUrl(
|
|
28
|
+
config?.api?.edge?.edgeUrl ?? process.env.PUBLIC_SITECORE_EDGE_PLATFORM_HOSTNAME_ENV
|
|
29
|
+
),
|
|
31
30
|
},
|
|
32
31
|
local: {
|
|
33
32
|
...config?.api?.local,
|
|
34
|
-
apiKey:
|
|
35
|
-
|
|
36
|
-
import.meta.env?.PUBLIC_SITECORE_API_KEY ||
|
|
37
|
-
process.env.PUBLIC_SITECORE_API_KEY ||
|
|
38
|
-
'',
|
|
39
|
-
apiHost:
|
|
40
|
-
config?.api?.local?.apiHost ||
|
|
41
|
-
import.meta.env?.PUBLIC_SITECORE_API_HOST ||
|
|
42
|
-
process.env.PUBLIC_SITECORE_API_HOST ||
|
|
43
|
-
'',
|
|
33
|
+
apiKey: config?.api?.local?.apiKey || process.env.PUBLIC_SITECORE_API_KEY || '',
|
|
34
|
+
apiHost: config?.api?.local?.apiHost || process.env.PUBLIC_SITECORE_API_HOST || '',
|
|
44
35
|
},
|
|
45
36
|
},
|
|
46
|
-
defaultSite:
|
|
47
|
-
|
|
48
|
-
import.meta.env?.PUBLIC_DEFAULT_SITE_NAME ||
|
|
49
|
-
process.env.PUBLIC_DEFAULT_SITE_NAME ||
|
|
50
|
-
'',
|
|
51
|
-
defaultLanguage:
|
|
52
|
-
config?.defaultLanguage ||
|
|
53
|
-
import.meta.env?.PUBLIC_DEFAULT_LANGUAGE ||
|
|
54
|
-
process.env.PUBLIC_DEFAULT_LANGUAGE ||
|
|
55
|
-
'en',
|
|
37
|
+
defaultSite: config?.defaultSite || process.env.PUBLIC_DEFAULT_SITE_NAME || '',
|
|
38
|
+
defaultLanguage: config?.defaultLanguage || process.env.PUBLIC_DEFAULT_LANGUAGE || 'en',
|
|
56
39
|
multisite: {
|
|
57
40
|
...config?.multisite,
|
|
58
41
|
useCookieResolution:
|
|
59
|
-
config?.multisite?.useCookieResolution ??
|
|
60
|
-
(() => (import.meta.env?.VERCEL_ENV || process.env.VERCEL_ENV) === 'preview'),
|
|
42
|
+
config?.multisite?.useCookieResolution ?? (() => process.env.VERCEL_ENV === 'preview'),
|
|
61
43
|
},
|
|
62
44
|
personalize: {
|
|
63
45
|
...config?.personalize,
|
|
64
|
-
scope:
|
|
65
|
-
config?.personalize?.scope ||
|
|
66
|
-
import.meta.env?.PUBLIC_PERSONALIZE_SCOPE ||
|
|
67
|
-
process.env.PUBLIC_PERSONALIZE_SCOPE,
|
|
46
|
+
scope: config?.personalize?.scope || process.env.PUBLIC_PERSONALIZE_SCOPE,
|
|
68
47
|
},
|
|
69
48
|
generateStaticPaths:
|
|
70
|
-
|
|
71
|
-
?
|
|
49
|
+
process.env.GENERATE_STATIC_PATHS !== undefined
|
|
50
|
+
? process.env.GENERATE_STATIC_PATHS.toLowerCase() === 'true'
|
|
72
51
|
: config?.generateStaticPaths ?? true,
|
|
73
52
|
sitecoreInternalEditingHostUrl:
|
|
74
|
-
config?.sitecoreInternalEditingHostUrl ||
|
|
75
|
-
import.meta.env?.SITECORE_INTERNAL_EDITING_HOST_URL ||
|
|
76
|
-
process.env.SITECORE_INTERNAL_EDITING_HOST_URL,
|
|
53
|
+
config?.sitecoreInternalEditingHostUrl || process.env.SITECORE_INTERNAL_EDITING_HOST_URL,
|
|
77
54
|
};
|
|
78
55
|
};
|
|
79
56
|
|
|
80
57
|
/**
|
|
81
58
|
* Type to be used as config input in sitecore.config
|
|
59
|
+
* @public
|
|
82
60
|
*/
|
|
83
61
|
export type SitecoreConfigInput = SitecoreConfigInputCore & {
|
|
84
62
|
/**
|
|
@@ -102,6 +80,7 @@ export type SitecoreConfigInput = SitecoreConfigInputCore & {
|
|
|
102
80
|
|
|
103
81
|
/**
|
|
104
82
|
* Final sitecore config type used at runtime Every property should be populated, either from sitecore.config or built-in fallback values
|
|
83
|
+
* @public
|
|
105
84
|
*/
|
|
106
85
|
export type SitecoreConfig = DeepRequired<SitecoreConfigInput>;
|
|
107
86
|
|
|
@@ -109,6 +88,7 @@ export type SitecoreConfig = DeepRequired<SitecoreConfigInput>;
|
|
|
109
88
|
* Accepts a SitecoreConfigInput object and returns full sitecore configuration
|
|
110
89
|
* @param {SitecoreConfigInput} config override values to be written over default config settings
|
|
111
90
|
* @returns {SitecoreConfig} full sitecore configuration to use in application
|
|
91
|
+
* @public
|
|
112
92
|
*/
|
|
113
93
|
export const defineConfig = (config?: SitecoreConfigInput): SitecoreConfig => {
|
|
114
94
|
return defineConfigCore(getAstroFallbackConfig(config)) as SitecoreConfig;
|
|
@@ -4,16 +4,13 @@ import {
|
|
|
4
4
|
SitecoreCliConfigInput,
|
|
5
5
|
SitecoreCliConfig,
|
|
6
6
|
ComponentTemplateType,
|
|
7
|
-
} from '@sitecore-content-sdk/
|
|
7
|
+
} from '@sitecore-content-sdk/content/config';
|
|
8
8
|
import chalk from 'chalk';
|
|
9
9
|
|
|
10
10
|
describe('defineCliConfig', () => {
|
|
11
11
|
const validateDefaultTemplates = (result: SitecoreCliConfig) => {
|
|
12
|
-
expect(result.scaffold.templates[0].name).to.equal(
|
|
13
|
-
|
|
14
|
-
);
|
|
15
|
-
const defaultTemplate =
|
|
16
|
-
result.scaffold.templates[0].generateTemplate('ComponentName');
|
|
12
|
+
expect(result.scaffold.templates[0].name).to.equal(ComponentTemplateType.DEFAULT);
|
|
13
|
+
const defaultTemplate = result.scaffold.templates[0].generateTemplate('ComponentName');
|
|
17
14
|
// expect(defaultTemplate).to.contain(
|
|
18
15
|
// // eslint-disable-next-line quotes
|
|
19
16
|
// `import { ComponentParams, ComponentRendering } from '@sitecore-content-sdk/nextjs';`
|
|
@@ -21,9 +18,7 @@ describe('defineCliConfig', () => {
|
|
|
21
18
|
expect(defaultTemplate).to.contain('ComponentName');
|
|
22
19
|
if (result.scaffold.templates[0].getNextSteps) {
|
|
23
20
|
const componentpath = 'src/components/ComponentName.astro';
|
|
24
|
-
expect(
|
|
25
|
-
result.scaffold.templates[0].getNextSteps(componentpath)[0]
|
|
26
|
-
).to.contain(
|
|
21
|
+
expect(result.scaffold.templates[0].getNextSteps(componentpath)[0]).to.contain(
|
|
27
22
|
`* Implement the Astro component in ${chalk.green(componentpath)}`
|
|
28
23
|
);
|
|
29
24
|
}
|
|
@@ -59,9 +54,7 @@ describe('defineCliConfig', () => {
|
|
|
59
54
|
],
|
|
60
55
|
},
|
|
61
56
|
scaffold: {
|
|
62
|
-
templates: [
|
|
63
|
-
{ name: 'existing template', generateTemplate: () => 'test' },
|
|
64
|
-
],
|
|
57
|
+
templates: [{ name: 'existing template', generateTemplate: () => 'test' }],
|
|
65
58
|
},
|
|
66
59
|
};
|
|
67
60
|
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
SitecoreCliConfig,
|
|
4
|
-
} from '@sitecore-content-sdk/core/config';
|
|
5
|
-
import { defineCliConfig as defineCliConfigCore } from '@sitecore-content-sdk/core/config-cli';
|
|
1
|
+
import { SitecoreCliConfigInput, SitecoreCliConfig } from '@sitecore-content-sdk/content/config';
|
|
2
|
+
import { defineCliConfig as defineCliConfigCore } from '@sitecore-content-sdk/content/config-cli';
|
|
6
3
|
// import { byocTemplate } from '../tools/templating/byoc-component';
|
|
7
4
|
import { defaultTemplate } from '../tools/templating/default-component';
|
|
8
5
|
import { generateMap } from '../tools/generate-map';
|
|
@@ -12,10 +9,9 @@ import { generateMap } from '../tools/generate-map';
|
|
|
12
9
|
* updated with the required default values.
|
|
13
10
|
* @param {SitecoreCliConfigInput} cliConfig the cli configuration provided by the application
|
|
14
11
|
* @returns {SitecoreCliConfig} full sitecore cli configuration to use with cli
|
|
12
|
+
* @public
|
|
15
13
|
*/
|
|
16
|
-
export const defineCliConfig = (
|
|
17
|
-
cliConfig: SitecoreCliConfigInput
|
|
18
|
-
): SitecoreCliConfig => {
|
|
14
|
+
export const defineCliConfig = (cliConfig: SitecoreCliConfigInput): SitecoreCliConfig => {
|
|
19
15
|
addDefaultScaffoldTemplates(cliConfig);
|
|
20
16
|
addDefaultComponentMapGenerator(cliConfig);
|
|
21
17
|
return defineCliConfigCore(cliConfig);
|
package/src/context.ts
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import { map } from 'nanostores';
|
|
2
2
|
import { ComponentMap } from './sharedTypes/component-props';
|
|
3
|
-
import { Page } from '@sitecore-content-sdk/
|
|
4
|
-
import { SitecoreConfig } from '@sitecore-content-sdk/
|
|
5
|
-
import { DictionaryPhrases } from '@sitecore-content-sdk/
|
|
3
|
+
import { Page } from '@sitecore-content-sdk/content/client';
|
|
4
|
+
import { SitecoreConfig } from '@sitecore-content-sdk/content/config';
|
|
5
|
+
import { DictionaryPhrases } from '@sitecore-content-sdk/content/types/i18n';
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Nanostore map holding Sitecore page, API config, component map, and dictionary for the current request or app scope.
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
7
11
|
export const SitecoreContext: any = map({});
|
|
8
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Shape of values passed when updating {@link SitecoreContext} (page, API, and optional component map).
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
9
17
|
export interface SitecoreContextProps {
|
|
10
18
|
/**
|
|
11
19
|
* The API configuration defined in the `SitecoreConfig`.
|
|
@@ -21,6 +29,10 @@ export interface SitecoreContextProps {
|
|
|
21
29
|
page: Page;
|
|
22
30
|
}
|
|
23
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Shape of values passed when updating dictionary phrases on {@link SitecoreContext}.
|
|
34
|
+
* @internal
|
|
35
|
+
*/
|
|
24
36
|
export interface SitecoreDictionarytProps {
|
|
25
37
|
/**
|
|
26
38
|
* The dictionary data.
|
|
@@ -28,22 +40,33 @@ export interface SitecoreDictionarytProps {
|
|
|
28
40
|
dictionary: DictionaryPhrases;
|
|
29
41
|
}
|
|
30
42
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
43
|
+
/**
|
|
44
|
+
* Writes page data, API config, and optional component map into {@link SitecoreContext}.
|
|
45
|
+
* @param {Page} props.page - The page data.
|
|
46
|
+
* @param {SitecoreConfig['api']} props.api - The API configuration.
|
|
47
|
+
* @param {ComponentMap} [props.componentMap] - Component map.
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
50
|
+
export const updateSitecoreContext = ({ page, api, componentMap }: SitecoreContextProps) => {
|
|
36
51
|
SitecoreContext.setKey('page', page);
|
|
37
52
|
SitecoreContext.setKey('api', api);
|
|
38
53
|
SitecoreContext.setKey('componentMap', componentMap);
|
|
39
54
|
};
|
|
40
55
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Writes dictionary phrases into {@link SitecoreContext} for {@link useDictionary}.
|
|
58
|
+
* @param {SitecoreDictionarytProps} props
|
|
59
|
+
* @param {DictionaryPhrases} props.dictionary
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
62
|
+
export const updateSitecoreDictionary = ({ dictionary }: SitecoreDictionarytProps) => {
|
|
44
63
|
SitecoreContext.setKey('dictionary', dictionary);
|
|
45
64
|
};
|
|
46
65
|
|
|
66
|
+
/**
|
|
67
|
+
* Returns the current page and API config from {@link SitecoreContext}.
|
|
68
|
+
* @public
|
|
69
|
+
*/
|
|
47
70
|
export const useSitecore = (): SitecoreContextProps => {
|
|
48
71
|
return {
|
|
49
72
|
page: SitecoreContext.get()['page'],
|
|
@@ -51,10 +74,18 @@ export const useSitecore = (): SitecoreContextProps => {
|
|
|
51
74
|
};
|
|
52
75
|
};
|
|
53
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Returns the component map from {@link SitecoreContext} for resolving rendering components.
|
|
79
|
+
* @public
|
|
80
|
+
*/
|
|
54
81
|
export const useComponentMap = (): ComponentMap => {
|
|
55
82
|
return SitecoreContext.get()['componentMap'];
|
|
56
83
|
};
|
|
57
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Returns a translator function `t(key)` that resolves keys against the dictionary on {@link SitecoreContext}, or returns the key if no dictionary is set.
|
|
87
|
+
* @public
|
|
88
|
+
*/
|
|
58
89
|
export const useDictionary = () => {
|
|
59
90
|
const t = (key: string): string => {
|
|
60
91
|
const dictionary = SitecoreContext.get()['dictionary'];
|
package/src/debug.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { debug as coreDebug } from '@sitecore-content-sdk/core';
|
|
2
|
+
import { debug as contentDebug } from '@sitecore-content-sdk/content';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Unified debug object containing all debug namespaces from referenced content-sdk packages.
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
const debug: Record<string, debug.Debugger> = {
|
|
9
|
+
...coreDebug,
|
|
10
|
+
...contentDebug,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default debug;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/* eslint-disable no-unused-expressions */
|
|
2
2
|
import { expect } from 'chai';
|
|
3
3
|
import { EditingConfigMiddleware } from './editing-config-middleware';
|
|
4
|
-
import { QUERY_PARAM_EDITING_SECRET } from '@sitecore-content-sdk/
|
|
4
|
+
import { QUERY_PARAM_EDITING_SECRET } from '@sitecore-content-sdk/content/editing';
|
|
5
5
|
import { AstroContentSdkComponent } from '../sharedTypes/component-props';
|
|
6
|
-
import { mockRequest as MockRequest, Query } from '../
|
|
6
|
+
import { mockRequest as MockRequest, Query } from '../tests/helpers';
|
|
7
7
|
|
|
8
8
|
const allowedOrigin = 'https://allowed.com';
|
|
9
9
|
|
|
@@ -116,17 +116,15 @@ describe('EditingConfigMiddleware', () => {
|
|
|
116
116
|
const res = await handler(req);
|
|
117
117
|
|
|
118
118
|
expect(res.headers.has('Access-Control-Allow-Origin')).to.be.true;
|
|
119
|
-
expect(res.headers.get('Access-Control-Allow-Origin')).to.
|
|
120
|
-
allowedOrigin
|
|
121
|
-
);
|
|
119
|
+
expect(res.headers.get('Access-Control-Allow-Origin')).to.include(allowedOrigin);
|
|
122
120
|
|
|
123
121
|
expect(res.headers.has('Access-Control-Allow-Methods')).to.be.true;
|
|
124
|
-
expect(res.headers.get('Access-Control-Allow-Methods')).to.
|
|
122
|
+
expect(res.headers.get('Access-Control-Allow-Methods')).to.include(
|
|
125
123
|
'GET, POST, OPTIONS, DELETE, PUT, PATCH'
|
|
126
124
|
);
|
|
127
125
|
|
|
128
126
|
expect(res.headers.has('Access-Control-Allow-Headers')).to.be.true;
|
|
129
|
-
expect(res.headers.get('Access-Control-Allow-Headers')).to.
|
|
127
|
+
expect(res.headers.get('Access-Control-Allow-Headers')).to.include(
|
|
130
128
|
'Content-Type, Authorization'
|
|
131
129
|
);
|
|
132
130
|
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
EDITING_ALLOWED_ORIGINS,
|
|
3
3
|
QUERY_PARAM_EDITING_SECRET,
|
|
4
|
-
} from '@sitecore-content-sdk/
|
|
5
|
-
import
|
|
6
|
-
import { Metadata } from '@sitecore-content-sdk/core/
|
|
7
|
-
import { getEnforcedCorsHeaders } from '@sitecore-content-sdk/core/
|
|
8
|
-
import { EditMode } from '@sitecore-content-sdk/
|
|
4
|
+
} from '@sitecore-content-sdk/content/editing';
|
|
5
|
+
import debug from '../debug';
|
|
6
|
+
import { Metadata } from '@sitecore-content-sdk/core/node-tools';
|
|
7
|
+
import { getEnforcedCorsHeaders } from '@sitecore-content-sdk/core/tools';
|
|
8
|
+
import { EditMode } from '@sitecore-content-sdk/content/layout';
|
|
9
9
|
import { getEditingSecret } from '../utils';
|
|
10
10
|
import { AstroContentSdkComponent, ComponentMap } from '../sharedTypes/component-props';
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* The interface for the EditingConfigMiddleware configuration.
|
|
14
|
+
* @public
|
|
15
|
+
*/
|
|
12
16
|
export type EditingConfigMiddlewareConfig = {
|
|
13
17
|
/**
|
|
14
18
|
* Components available in the application
|
|
@@ -23,6 +27,7 @@ export type EditingConfigMiddlewareConfig = {
|
|
|
23
27
|
/**
|
|
24
28
|
* Middleware / handler used in the editing config API route in xmcloud add on (e.g. '/api/editing/config')
|
|
25
29
|
* provides configuration information to determine feature compatibility on Pages side.
|
|
30
|
+
* @public
|
|
26
31
|
*/
|
|
27
32
|
export class EditingConfigMiddleware {
|
|
28
33
|
/**
|
|
@@ -39,7 +44,7 @@ export class EditingConfigMiddleware {
|
|
|
39
44
|
}
|
|
40
45
|
|
|
41
46
|
private handler = async (_req: Request): Promise<Response> => {
|
|
42
|
-
const url = new URL(_req.url
|
|
47
|
+
const url = new URL(_req.url);
|
|
43
48
|
const secret = url.searchParams.get(QUERY_PARAM_EDITING_SECRET);
|
|
44
49
|
|
|
45
50
|
const _res = new Response();
|
|
@@ -88,7 +93,6 @@ export class EditingConfigMiddleware {
|
|
|
88
93
|
if (_req.method === 'OPTIONS') {
|
|
89
94
|
debug.editing('preflight request');
|
|
90
95
|
|
|
91
|
-
// CORS headers are set by enforceCors
|
|
92
96
|
return new Response(null, {
|
|
93
97
|
status: 204,
|
|
94
98
|
headers: _res.headers,
|