@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.
Files changed (110) hide show
  1. package/README.md +3 -3
  2. package/package.json +41 -42
  3. package/src/client/index.ts +1 -1
  4. package/src/client/sitecore-astro-client.test.ts +41 -20
  5. package/src/client/sitecore-astro-client.ts +74 -57
  6. package/src/components/AstroImage.astro +2 -2
  7. package/src/components/AstroImage.astro.test.ts +542 -0
  8. package/src/components/Date.astro +5 -1
  9. package/src/components/Date.astro.test.ts +197 -0
  10. package/src/components/DefaultEmptyFieldEditingComponentImage.astro +4 -0
  11. package/src/components/DefaultEmptyFieldEditingComponentText.astro +4 -0
  12. package/src/components/EditingScripts.astro +2 -2
  13. package/src/components/EditingScripts.astro.test.ts +267 -0
  14. package/src/components/ErrorBoundary.astro +8 -9
  15. package/src/components/ErrorBoundary.astro.test.ts +252 -0
  16. package/src/components/ErrorComponent.astro +16 -0
  17. package/src/components/ErrorComponent.astro.test.ts +31 -0
  18. package/src/components/FieldMetadata.astro +1 -1
  19. package/src/components/FieldMetadata.astro.test.ts +40 -0
  20. package/src/components/File.astro +5 -1
  21. package/src/components/File.astro.test.ts +68 -0
  22. package/src/components/HiddenRendering.astro.test.ts +36 -0
  23. package/src/components/Image.astro +18 -4
  24. package/src/components/Image.astro.test.ts +438 -0
  25. package/src/components/Link.astro +13 -1
  26. package/src/components/Link.astro.test.ts +261 -0
  27. package/src/components/MissingComponent.astro.test.ts +21 -0
  28. package/src/components/Placeholder/Placeholder.astro +18 -23
  29. package/src/components/Placeholder/Placeholder.astro.test.ts +1088 -0
  30. package/src/components/Placeholder/PlaceholderMetadata.astro +24 -18
  31. package/src/components/Placeholder/PlaceholderMetadata.astro.test.ts +228 -0
  32. package/src/components/Placeholder/PlaceholderUtils.astro +21 -40
  33. package/src/components/Placeholder/PlaceholderUtils.astro.test.ts +149 -0
  34. package/src/components/Placeholder/models.ts +26 -17
  35. package/src/components/Placeholder/placeholder-utils.test.ts +153 -6
  36. package/src/components/Placeholder/placeholder-utils.ts +33 -11
  37. package/src/components/RichText.astro +9 -1
  38. package/src/components/RichText.astro.test.ts +205 -0
  39. package/src/components/Text.astro +15 -3
  40. package/src/components/Text.astro.test.ts +273 -0
  41. package/src/config/define-config.test.ts +5 -5
  42. package/src/config/define-config.ts +22 -42
  43. package/src/config-cli/define-cli-config.test.ts +5 -12
  44. package/src/config-cli/define-cli-config.ts +4 -8
  45. package/src/context.ts +42 -11
  46. package/src/debug.ts +13 -0
  47. package/src/editing/editing-config-middleware.test.ts +5 -7
  48. package/src/editing/editing-config-middleware.ts +11 -7
  49. package/src/editing/editing-render-middleware.test.ts +366 -24
  50. package/src/editing/editing-render-middleware.ts +34 -12
  51. package/src/editing/index.ts +2 -0
  52. package/src/editing/render-middleware.test.ts +1 -1
  53. package/src/editing/render-middleware.ts +1 -1
  54. package/src/editing/types.ts +39 -0
  55. package/src/editing/utils.test.ts +364 -4
  56. package/src/editing/utils.ts +82 -24
  57. package/src/enhancers/WithEmptyFieldEditingComponent.astro +1 -1
  58. package/src/enhancers/WithEmptyFieldEditingComponent.astro.test.ts +380 -0
  59. package/src/enhancers/WithFieldMetadata.astro.test.ts +113 -0
  60. package/src/index.ts +10 -7
  61. package/src/middleware/index.ts +4 -12
  62. package/src/middleware/middleware.test.ts +13 -0
  63. package/src/middleware/middleware.ts +12 -3
  64. package/src/middleware/multisite-middleware.test.ts +45 -50
  65. package/src/middleware/multisite-middleware.ts +33 -6
  66. package/src/middleware/robots-middleware.test.ts +20 -4
  67. package/src/middleware/robots-middleware.ts +10 -3
  68. package/src/middleware/sitemap-middleware.test.ts +35 -3
  69. package/src/middleware/sitemap-middleware.ts +7 -6
  70. package/src/services/component-props-service.ts +7 -6
  71. package/src/sharedTypes/component-props.ts +15 -4
  72. package/src/site/index.ts +1 -1
  73. package/src/tests/astro-helpers.ts +61 -0
  74. package/src/tests/test-components/CustomErrorComponent.astro +3 -0
  75. package/src/tests/test-components/CustomHiddenRendering.astro +10 -0
  76. package/src/tests/test-components/CustomMissingComponent.astro +9 -0
  77. package/src/tests/test-components/DownloadCallout.astro +12 -0
  78. package/src/tests/test-components/EmptyFieldEditingComponent.astro +5 -0
  79. package/src/tests/test-components/ErrorBoundaryWithError.astro +10 -0
  80. package/src/tests/test-components/Home.astro +12 -0
  81. package/src/tests/test-components/SxaRichText.astro +23 -0
  82. package/src/tests/test-components/SxaRichTextDefault.astro +7 -0
  83. package/src/tests/test-components/SxaRichTextWithTitle.astro +8 -0
  84. package/src/tests/test-components/TestComponent.astro +9 -0
  85. package/src/tests/test-components/TestComponentWithError.astro +4 -0
  86. package/src/tests/test-components/TestComponentWithField.astro +17 -0
  87. package/src/tests/test-components/TestHeader.astro +8 -0
  88. package/src/tests/test-components/TestLogo.astro +5 -0
  89. package/src/tests/test-components/TestParentWrapperComponent.astro +5 -0
  90. package/src/tests/test-components/TestWrapperComponent.astro +5 -0
  91. package/src/tests/test-data/metadata-data.ts +86 -0
  92. package/src/tests/test-data/normal-mode-data.ts +466 -0
  93. package/src/tests/vitest.setup.ts +4 -0
  94. package/src/tools/generate-map.ts +4 -3
  95. package/src/tools/index.ts +2 -4
  96. package/src/tools/templating/components.test.ts +100 -87
  97. package/src/tools/templating/components.ts +2 -1
  98. package/src/tools/templating/default-component.ts +3 -8
  99. package/src/utils/utils.ts +20 -2
  100. /package/src/{test-data → tests}/helpers.ts +0 -0
  101. /package/src/{test-data → tests}/personalizeData.ts +0 -0
  102. /package/src/{test-data/components → tests/test-components/map-components}/Bar.astro +0 -0
  103. /package/src/{test-data/components → tests/test-components/map-components}/Baz.astro +0 -0
  104. /package/src/{test-data/components → tests/test-components/map-components}/Foo.astro +0 -0
  105. /package/src/{test-data/components → tests/test-components/map-components}/Hero.variant.astro +0 -0
  106. /package/src/{test-data/components → tests/test-components/map-components}/NotComponent.bsx +0 -0
  107. /package/src/{test-data/components → tests/test-components/map-components}/Qux.astro +0 -0
  108. /package/src/{test-data/components → tests/test-components/map-components}/folded/Folded.astro +0 -0
  109. /package/src/{test-data/components → tests/test-components/map-components}/folded/random-file-2.docx +0 -0
  110. /package/src/{test-data/components → tests/test-components/map-components}/random-file.txt +0 -0
@@ -0,0 +1,261 @@
1
+ import { describe, test, expect } from 'vitest';
2
+ import { renderAstroComponent } from '../tests/astro-helpers';
3
+ import Link, { LinkField } from './Link.astro';
4
+ import EmptyFieldEditingComponent from '../tests/test-components/EmptyFieldEditingComponent.astro';
5
+
6
+ describe('<Link />', () => {
7
+ test('should render nothing with missing field', async () => {
8
+ const field = null as unknown as LinkField;
9
+ const rendered = await renderAstroComponent(Link, {
10
+ props: { field: field },
11
+ });
12
+ expect(rendered.innerHTML).to.equal('');
13
+ });
14
+
15
+ test('should render nothing with missing value', async () => {
16
+ const field = {};
17
+ const rendered = await renderAstroComponent(Link, {
18
+ props: { field: field },
19
+ });
20
+ expect(rendered.innerHTML).to.equal('');
21
+ });
22
+
23
+ test('should render value with editing explicitly disabled', async () => {
24
+ const field = {
25
+ value: {
26
+ href: '/lorem',
27
+ text: 'ipsum',
28
+ },
29
+ };
30
+ const rendered = (
31
+ await renderAstroComponent(Link, {
32
+ props: { field: field, editable: false },
33
+ })
34
+ ).querySelector('a');
35
+ expect(rendered?.outerHTML).to.contain(field.value.href);
36
+ expect(rendered?.outerHTML).to.contain(field.value.text);
37
+ });
38
+
39
+ test('should render with href directly on provided field', async () => {
40
+ const field = {
41
+ href: '/lorem',
42
+ text: 'ipsum',
43
+ };
44
+ const rendered = (
45
+ await renderAstroComponent(Link, {
46
+ props: { field: field },
47
+ })
48
+ ).querySelector('a');
49
+ expect(rendered?.outerHTML).to.contain(field.href);
50
+ expect(rendered?.outerHTML).to.contain(field.text);
51
+ });
52
+
53
+ test('should not add extra hash when linktype is anchor', async () => {
54
+ const field = {
55
+ linktype: 'anchor',
56
+ href: '#anchor',
57
+ text: 'anchor link',
58
+ anchor: 'anchor',
59
+ };
60
+ const rendered = (
61
+ await renderAstroComponent(Link, {
62
+ props: { field: field },
63
+ })
64
+ ).querySelector('a');
65
+ expect(rendered?.outerHTML).to.contain(`href="${field.href}"`);
66
+ expect(rendered?.text).to.equal(field.text);
67
+ });
68
+
69
+ test('should render all value attributes', async () => {
70
+ const field = {
71
+ value: {
72
+ href: '/lorem',
73
+ anchor: 'foo',
74
+ text: 'ipsum',
75
+ class: 'my-link',
76
+ title: 'My Link',
77
+ target: '_blank',
78
+ querystring: 'foo=bar',
79
+ },
80
+ };
81
+ const rendered = (
82
+ await renderAstroComponent(Link, {
83
+ props: { field: field },
84
+ })
85
+ ).querySelector('a');
86
+ expect(rendered?.outerHTML).to.contain(
87
+ `href="${field.value.href}?${field.value.querystring}#${field.value.anchor}"`
88
+ );
89
+ expect(rendered?.outerHTML).to.contain(`class="${field.value.class}"`);
90
+ expect(rendered?.outerHTML).to.contain(`title="${field.value.title}"`);
91
+ expect(rendered?.outerHTML).to.contain(`target="${field.value.target}"`);
92
+ });
93
+
94
+ test('should render other attributes with other props provided', async () => {
95
+ const field = {
96
+ value: {
97
+ href: '/lorem',
98
+ text: 'ipsum',
99
+ },
100
+ };
101
+ const rendered = (
102
+ await renderAstroComponent(Link, {
103
+ props: { field: field, id: 'my-link', accessKey: 'a' },
104
+ })
105
+ ).querySelector('a');
106
+ expect(rendered?.outerHTML).to.contain('id="my-link"');
107
+ expect(rendered?.outerHTML).to.contain('accesskey="a"');
108
+ });
109
+
110
+ describe('edit mode', () => {
111
+ const testMetadata = {
112
+ contextItem: {
113
+ id: '{09A07660-6834-476C-B93B-584248D3003B}',
114
+ language: 'en',
115
+ revision: 'a0b36ce0a7db49418edf90eb9621e145',
116
+ version: 1,
117
+ },
118
+ fieldId: '{414061F4-FBB1-4591-BC37-BFFA67F745EB}',
119
+ fieldType: 'single-line',
120
+ rawValue: 'Test1',
121
+ };
122
+
123
+ test('should render field metadata component when metadata property is present', async () => {
124
+ const field = {
125
+ href: '/lorem',
126
+ text: 'ipsum',
127
+ metadata: testMetadata,
128
+ };
129
+
130
+ const rendered = await renderAstroComponent(Link, {
131
+ props: { field: field },
132
+ });
133
+
134
+ expect(rendered.innerHTML).to.equal(
135
+ [
136
+ `<code type="text/sitecore" chrometype="field" class="scpm" kind="open">${JSON.stringify(
137
+ testMetadata
138
+ )}</code>`,
139
+ '<a href="/lorem">ipsum</a>',
140
+ '<code type="text/sitecore" chrometype="field" class="scpm" kind="close"></code>',
141
+ ].join('')
142
+ );
143
+ });
144
+
145
+ test('should render default empty field component when field value is not present', async () => {
146
+ const field = {
147
+ value: { href: undefined },
148
+ metadata: testMetadata,
149
+ };
150
+
151
+ const rendered = await renderAstroComponent(Link, {
152
+ props: { field: field },
153
+ });
154
+
155
+ expect(rendered.innerHTML).to.equal(
156
+ [
157
+ `<code type="text/sitecore" chrometype="field" class="scpm" kind="open">${JSON.stringify(
158
+ testMetadata
159
+ )}</code>`,
160
+ '<span>[No text in field]</span>',
161
+ '<code type="text/sitecore" chrometype="field" class="scpm" kind="close"></code>',
162
+ ].join('')
163
+ );
164
+ });
165
+
166
+ test('should render default empty field component when field value href is not present', async () => {
167
+ const field = {
168
+ href: undefined,
169
+ metadata: testMetadata,
170
+ };
171
+
172
+ const rendered = await renderAstroComponent(Link, {
173
+ props: { field: field },
174
+ });
175
+
176
+ expect(rendered.innerHTML).to.equal(
177
+ [
178
+ `<code type="text/sitecore" chrometype="field" class="scpm" kind="open">${JSON.stringify(
179
+ testMetadata
180
+ )}</code>`,
181
+ '<span>[No text in field]</span>',
182
+ '<code type="text/sitecore" chrometype="field" class="scpm" kind="close"></code>',
183
+ ].join('')
184
+ );
185
+ });
186
+
187
+ test('should render custom empty field component when provided, when field value is not present', async () => {
188
+ const field = {
189
+ value: { href: undefined },
190
+ metadata: testMetadata,
191
+ };
192
+
193
+ const rendered = await renderAstroComponent(Link, {
194
+ props: {
195
+ field: field,
196
+ emptyFieldEditingComponent: EmptyFieldEditingComponent,
197
+ },
198
+ });
199
+
200
+ expect(rendered.innerHTML).to.equal(
201
+ [
202
+ `<code type="text/sitecore" chrometype="field" class="scpm" kind="open">${JSON.stringify(
203
+ testMetadata
204
+ )}</code>`,
205
+ '<span class="empty-field-value-placeholder">Custom Empty field value</span>',
206
+ '<code type="text/sitecore" chrometype="field" class="scpm" kind="close"></code>',
207
+ ].join('')
208
+ );
209
+ });
210
+
211
+ test('should render custom empty field component when provided, when field value href is not present', async () => {
212
+ const field = {
213
+ href: undefined,
214
+ metadata: testMetadata,
215
+ };
216
+
217
+ const rendered = await renderAstroComponent(Link, {
218
+ props: {
219
+ field: field,
220
+ emptyFieldEditingComponent: EmptyFieldEditingComponent,
221
+ },
222
+ });
223
+
224
+ expect(rendered.innerHTML).to.equal(
225
+ [
226
+ `<code type="text/sitecore" chrometype="field" class="scpm" kind="open">${JSON.stringify(
227
+ testMetadata
228
+ )}</code>`,
229
+ '<span class="empty-field-value-placeholder">Custom Empty field value</span>',
230
+ '<code type="text/sitecore" chrometype="field" class="scpm" kind="close"></code>',
231
+ ].join('')
232
+ );
233
+ });
234
+
235
+ test('should render nothing when field value is not present, when editing is explicitly disabled', async () => {
236
+ const field = {
237
+ value: undefined,
238
+ metadata: testMetadata,
239
+ };
240
+
241
+ const rendered = await renderAstroComponent(Link, {
242
+ props: { field: field, editable: false },
243
+ });
244
+
245
+ expect(rendered.innerHTML).to.equal('');
246
+ });
247
+
248
+ test('should render nothing when field value href is empty, when editing is explicitly disabled', async () => {
249
+ const field = {
250
+ value: { href: undefined },
251
+ metadata: testMetadata,
252
+ };
253
+
254
+ const rendered = await renderAstroComponent(Link, {
255
+ props: { field: field, editable: false },
256
+ });
257
+
258
+ expect(rendered.innerHTML).to.equal('');
259
+ });
260
+ });
261
+ });
@@ -0,0 +1,21 @@
1
+ import { describe, test, expect } from 'vitest';
2
+ import { renderAstroComponent } from '../tests/astro-helpers';
3
+ import MissingComponent from './MissingComponent.astro';
4
+
5
+ describe('<MissingComponent>', () => {
6
+ test('should accept and display custom error', async () => {
7
+ const errorMsg = 'Oops, I errored again';
8
+ const props = {
9
+ rendering: {
10
+ componentName: 'test',
11
+ },
12
+ errorOverride: errorMsg,
13
+ };
14
+
15
+ const result = await renderAstroComponent(MissingComponent, {
16
+ props: props,
17
+ });
18
+
19
+ expect(result.querySelector('div p')?.textContent).to.contain(errorMsg);
20
+ });
21
+ });
@@ -1,5 +1,5 @@
1
1
  ---
2
- import { ComponentRendering } from '@sitecore-content-sdk/core/layout';
2
+ import { ComponentRendering } from '@sitecore-content-sdk/content/layout';
3
3
  import ErrorBoundary from '../ErrorBoundary.astro';
4
4
  import PlaceholderMetadata from './PlaceholderMetadata.astro';
5
5
  import { useSitecore } from '../../context';
@@ -7,26 +7,21 @@ import RenderWrapper from '../RenderWrapper.astro';
7
7
  import EmptyPlaceholder from './EmptyPlaceholder.astro';
8
8
  import { PlaceholderProps } from './models';
9
9
  import { getPlaceholderRenderings } from './placeholder-utils';
10
- import { getComponentsForRenderingData } from './PlaceholderUtils.astro';
10
+ import { getPlaceholderComponents } from './PlaceholderUtils.astro';
11
11
 
12
12
  const props = Astro.props as PlaceholderProps;
13
13
 
14
14
  const { page } = useSitecore();
15
- const childProps: PlaceholderProps = { ...props, page };
16
15
 
17
- delete childProps.componentMap;
18
-
19
- const renderingData = childProps.rendering;
20
-
21
- const placeholderData = getPlaceholderRenderings(
22
- renderingData,
23
- childProps.name,
24
- childProps.page.mode.isEditing
16
+ const placeholderRenderings = getPlaceholderRenderings(
17
+ props.rendering,
18
+ props.name,
19
+ page.mode.isEditing
25
20
  );
26
21
 
27
- const isEmpty = !placeholderData.length;
22
+ const isEmpty = !placeholderRenderings.length;
28
23
 
29
- const components = getComponentsForRenderingData(placeholderData, childProps);
24
+ const components = getPlaceholderComponents(props, placeholderRenderings);
30
25
  ---
31
26
 
32
27
  {
@@ -34,30 +29,30 @@ const components = getComponentsForRenderingData(placeholderData, childProps);
34
29
  <RenderWrapper
35
30
  wrapper={
36
31
  isEmpty
37
- ? childProps.page.mode.isEditing && EmptyPlaceholder
38
- : childProps.render
32
+ ? page.mode.isEditing && EmptyPlaceholder
33
+ : props.render
39
34
  }
40
35
  >
41
36
  <ErrorBoundary>
42
- <RenderWrapper wrapper={isEmpty && childProps.renderEmpty}>
37
+ <RenderWrapper wrapper={isEmpty && props.renderEmpty}>
43
38
  {
44
39
  // Conditional rendering based on editing mode
45
- childProps.page.mode.isEditing ? (
40
+ page.mode.isEditing ? (
46
41
  <PlaceholderMetadata
47
- placeholderName={childProps.name}
48
- rendering={childProps.rendering as ComponentRendering}
42
+ placeholderName={props.name}
43
+ rendering={props.rendering as ComponentRendering}
49
44
  >
50
45
  {components.map((component) => {
51
46
  const Component = component.component.component;
52
47
 
53
48
  return (
54
- <RenderWrapper wrapper={childProps.renderEach}>
49
+ <RenderWrapper wrapper={props.renderEach}>
55
50
  <PlaceholderMetadata
56
51
  rendering={component.rendering as ComponentRendering}
57
52
  >
58
53
  {!component.component.isEmpty && (
59
54
  <ErrorBoundary
60
- errorComponent={childProps.errorComponent}
55
+ errorComponent={props.errorComponent}
61
56
  {...component.props}
62
57
  >
63
58
  <Component {...component.props} />
@@ -78,11 +73,11 @@ const components = getComponentsForRenderingData(placeholderData, childProps);
78
73
  return (
79
74
  <RenderWrapper
80
75
  wrapper={
81
- isEmpty ? childProps.renderEmpty : childProps.renderEach
76
+ isEmpty ? props.renderEmpty : props.renderEach
82
77
  }
83
78
  >
84
79
  <ErrorBoundary
85
- errorComponent={childProps.errorComponent}
80
+ errorComponent={props.errorComponent}
86
81
  {...component.props}
87
82
  >
88
83
  <Component {...component.props} />