@exdst-sitecore-content-sdk/astro 0.0.23 → 0.0.25
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/package.json +9 -14
- package/src/client/sitecore-astro-client.ts +0 -45
- package/src/context.ts +14 -16
- package/src/env.d.ts +1 -1
- package/src/sharedTypes/component-props.ts +0 -10
- package/src/tools/generate-map.ts +9 -21
- package/src/client/sitecore-astro-client.test.ts +0 -292
- package/src/components/AstroImage.astro.test.ts +0 -541
- package/src/components/Date.astro.test.ts +0 -197
- package/src/components/EditingScripts.astro.test.ts +0 -267
- package/src/components/ErrorBoundary.astro.test.ts +0 -252
- package/src/components/ErrorComponent.astro.test.ts +0 -31
- package/src/components/FieldMetadata.astro.test.ts +0 -40
- package/src/components/File.astro.test.ts +0 -68
- package/src/components/HiddenRendering.astro.test.ts +0 -36
- package/src/components/Image.astro.test.ts +0 -438
- package/src/components/Link.astro.test.ts +0 -261
- package/src/components/MissingComponent.astro.test.ts +0 -21
- package/src/components/Placeholder/Placeholder.astro.test.ts +0 -1088
- package/src/components/Placeholder/PlaceholderMetadata.astro.test.ts +0 -228
- package/src/components/Placeholder/PlaceholderUtils.astro.test.ts +0 -149
- package/src/components/Placeholder/placeholder-utils.test.ts +0 -309
- package/src/components/RichText.astro.test.ts +0 -205
- package/src/components/Text.astro.test.ts +0 -273
- package/src/config/define-config.test.ts +0 -526
- package/src/config-cli/define-cli-config.test.ts +0 -88
- package/src/editing/editing-config-middleware.test.ts +0 -164
- package/src/editing/editing-render-middleware.test.ts +0 -1143
- package/src/editing/render-middleware.test.ts +0 -57
- package/src/editing/utils.test.ts +0 -1212
- package/src/enhancers/WithEmptyFieldEditingComponent.astro.test.ts +0 -380
- package/src/enhancers/WithFieldMetadata.astro.test.ts +0 -113
- package/src/middleware/middleware.test.ts +0 -520
- package/src/middleware/multisite-middleware.test.ts +0 -667
- package/src/middleware/robots-middleware.test.ts +0 -129
- package/src/middleware/sitemap-middleware.test.ts +0 -184
- package/src/services/component-props-service.ts +0 -183
- package/src/tests/astro-helpers.ts +0 -61
- package/src/tests/helpers.ts +0 -46
- package/src/tests/personalizeData.ts +0 -63
- package/src/tests/test-components/CustomErrorComponent.astro +0 -3
- package/src/tests/test-components/CustomHiddenRendering.astro +0 -10
- package/src/tests/test-components/CustomMissingComponent.astro +0 -9
- package/src/tests/test-components/DownloadCallout.astro +0 -12
- package/src/tests/test-components/EmptyFieldEditingComponent.astro +0 -5
- package/src/tests/test-components/ErrorBoundaryWithError.astro +0 -10
- package/src/tests/test-components/Home.astro +0 -12
- package/src/tests/test-components/SxaRichText.astro +0 -23
- package/src/tests/test-components/SxaRichTextDefault.astro +0 -7
- package/src/tests/test-components/SxaRichTextWithTitle.astro +0 -8
- package/src/tests/test-components/TestComponent.astro +0 -9
- package/src/tests/test-components/TestComponentWithError.astro +0 -4
- package/src/tests/test-components/TestComponentWithField.astro +0 -17
- package/src/tests/test-components/TestHeader.astro +0 -8
- package/src/tests/test-components/TestLogo.astro +0 -5
- package/src/tests/test-components/TestParentWrapperComponent.astro +0 -5
- package/src/tests/test-components/TestWrapperComponent.astro +0 -5
- package/src/tests/test-components/map-components/Bar.astro +0 -0
- package/src/tests/test-components/map-components/Baz.astro +0 -0
- package/src/tests/test-components/map-components/Foo.astro +0 -0
- package/src/tests/test-components/map-components/Hero.variant.astro +0 -0
- package/src/tests/test-components/map-components/NotComponent.bsx +0 -0
- package/src/tests/test-components/map-components/Qux.astro +0 -0
- package/src/tests/test-components/map-components/folded/Folded.astro +0 -0
- package/src/tests/test-components/map-components/folded/random-file-2.docx +0 -0
- package/src/tests/test-components/map-components/random-file.txt +0 -0
- package/src/tests/test-data/metadata-data.ts +0 -86
- package/src/tests/test-data/normal-mode-data.ts +0 -466
- package/src/tests/vitest.setup.ts +0 -4
- package/src/tools/templating/components.test.ts +0 -318
- package/src/tools/templating/default-component.test.ts +0 -31
- package/src/utils/utils.test.ts +0 -48
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import * as chai from 'chai';
|
|
2
|
-
import { expect } from 'chai';
|
|
3
|
-
import sinon from 'sinon';
|
|
4
|
-
import sinonChai from 'sinon-chai';
|
|
5
|
-
import { RobotsMiddleware } from './robots-middleware';
|
|
6
|
-
import { SitecoreClient } from '@sitecore-content-sdk/content/client';
|
|
7
|
-
import { SiteInfo } from '@sitecore-content-sdk/content/site';
|
|
8
|
-
import { mockRequest } from '../tests/helpers';
|
|
9
|
-
import { constants } from '@sitecore-content-sdk/core';
|
|
10
|
-
|
|
11
|
-
const { ERROR_MESSAGES } = constants;
|
|
12
|
-
|
|
13
|
-
chai.use(sinonChai);
|
|
14
|
-
|
|
15
|
-
describe('RobotsMiddleware', () => {
|
|
16
|
-
const sandbox = sinon.createSandbox();
|
|
17
|
-
let sitecoreClientStub: sinon.SinonStubbedInstance<SitecoreClient>;
|
|
18
|
-
let middleware: RobotsMiddleware;
|
|
19
|
-
let req: Partial<Request>;
|
|
20
|
-
let siteResolverStub = {
|
|
21
|
-
getByHost: sandbox.stub(),
|
|
22
|
-
getByName: sandbox.stub(),
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const mockSiteInfo: SiteInfo = {
|
|
26
|
-
name: 'test-site',
|
|
27
|
-
hostName: 'example.com',
|
|
28
|
-
language: 'en',
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const sites = [mockSiteInfo, { name: 'test-site-two', hostName: 'localhost', language: 'da' }];
|
|
32
|
-
|
|
33
|
-
beforeEach(() => {
|
|
34
|
-
sitecoreClientStub = sandbox.createStubInstance(SitecoreClient);
|
|
35
|
-
siteResolverStub = {
|
|
36
|
-
getByHost: sandbox.stub(),
|
|
37
|
-
getByName: sandbox.stub(),
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
req = mockRequest({
|
|
41
|
-
headers: {
|
|
42
|
-
host: 'example.com',
|
|
43
|
-
},
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
middleware = new RobotsMiddleware(sitecoreClientStub as unknown as SitecoreClient, sites);
|
|
47
|
-
(middleware as any).siteResolver = siteResolverStub;
|
|
48
|
-
siteResolverStub.getByHost.callsFake((hostName) =>
|
|
49
|
-
sites.find((site) => site.hostName === hostName)
|
|
50
|
-
);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
afterEach(() => {
|
|
54
|
-
sandbox.restore();
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it('should set the content type header to text/plain', async () => {
|
|
58
|
-
sitecoreClientStub.getRobots.resolves('User-agent: *\nDisallow: /');
|
|
59
|
-
|
|
60
|
-
const res = await middleware.getHandler()(req as Request);
|
|
61
|
-
|
|
62
|
-
expect(res.headers.get('Content-Type')).to.equal('text/plain');
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('should call getRobots with the correct siteName', async () => {
|
|
66
|
-
sitecoreClientStub.getRobots.resolves('User-agent: *\nDisallow: /');
|
|
67
|
-
|
|
68
|
-
await middleware.getHandler()(req as Request);
|
|
69
|
-
|
|
70
|
-
expect(sitecoreClientStub.getRobots).to.have.been.calledWith('test-site');
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('should return 200 with robots content', async () => {
|
|
74
|
-
sitecoreClientStub.getRobots.resolves('User-agent: *\nDisallow: /');
|
|
75
|
-
|
|
76
|
-
const res = await middleware.getHandler()(req as Request);
|
|
77
|
-
|
|
78
|
-
const body = await res.text();
|
|
79
|
-
expect(res.status).to.equal(200);
|
|
80
|
-
expect(body).to.deep.equal('User-agent: *\nDisallow: /');
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it('should return 404 if getRobots returns null', async () => {
|
|
84
|
-
sitecoreClientStub.getRobots.resolves(undefined);
|
|
85
|
-
|
|
86
|
-
const res = await middleware.getHandler()(req as Request);
|
|
87
|
-
|
|
88
|
-
const body = await res.text();
|
|
89
|
-
expect(res.status).to.equal(404);
|
|
90
|
-
expect(body).to.deep.equal('User-agent: *\nDisallow: /');
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it('should return 500 if getRobots throws an error', async () => {
|
|
94
|
-
sitecoreClientStub.getRobots.rejects(new Error('Unexpected failure'));
|
|
95
|
-
|
|
96
|
-
const res = await middleware.getHandler()(req as Request);
|
|
97
|
-
|
|
98
|
-
const body = await res.text();
|
|
99
|
-
expect(res.status).to.equal(500);
|
|
100
|
-
expect(body).to.deep.equal(`Internal Server Error. ${ERROR_MESSAGES.CONTACT_SUPPORT}`);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it('should use "localhost" as fallback when host header is missing', async () => {
|
|
104
|
-
req = new Request('https://test.com'); // no host header
|
|
105
|
-
|
|
106
|
-
sitecoreClientStub.getRobots.resolves('User-agent: *\nDisallow: /');
|
|
107
|
-
|
|
108
|
-
const res = await middleware.getHandler()(req as Request);
|
|
109
|
-
|
|
110
|
-
expect(sitecoreClientStub.getRobots).to.have.been.calledWith('test-site-two');
|
|
111
|
-
|
|
112
|
-
const body = await res.text();
|
|
113
|
-
expect(res.status).to.equal(200);
|
|
114
|
-
expect(body).to.deep.equal('User-agent: *\nDisallow: /');
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
it('should use x-forwarded-host header when present', async () => {
|
|
118
|
-
req = mockRequest({
|
|
119
|
-
headers: {
|
|
120
|
-
'x-forwarded-host': 'proxy.forwarded.com',
|
|
121
|
-
host: 'localhost:3000',
|
|
122
|
-
},
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
await middleware.getHandler()(req as Request);
|
|
126
|
-
|
|
127
|
-
expect(siteResolverStub.getByHost).to.have.been.calledWith('proxy.forwarded.com');
|
|
128
|
-
});
|
|
129
|
-
});
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-unused-expressions, @typescript-eslint/no-unused-expressions */
|
|
2
|
-
import * as chai from 'chai';
|
|
3
|
-
import { expect } from 'chai';
|
|
4
|
-
import sinon from 'sinon';
|
|
5
|
-
import sinonChai from 'sinon-chai';
|
|
6
|
-
import { SitemapMiddleware } from './sitemap-middleware';
|
|
7
|
-
import { SitecoreClient } from '@sitecore-content-sdk/content/client';
|
|
8
|
-
import { constants } from '@sitecore-content-sdk/core';
|
|
9
|
-
import { mockRequest } from '../tests/helpers';
|
|
10
|
-
|
|
11
|
-
const { ERROR_MESSAGES } = constants;
|
|
12
|
-
|
|
13
|
-
chai.use(sinonChai);
|
|
14
|
-
|
|
15
|
-
describe('SitemapMiddleware', () => {
|
|
16
|
-
const sandbox = sinon.createSandbox();
|
|
17
|
-
let sitecoreClientStub: sinon.SinonStubbedInstance<SitecoreClient>;
|
|
18
|
-
let middleware: SitemapMiddleware;
|
|
19
|
-
let req: Partial<Request>;
|
|
20
|
-
let siteResolverStub = {
|
|
21
|
-
getByHost: sandbox.stub(),
|
|
22
|
-
getByName: sandbox.stub(),
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const sites = [
|
|
26
|
-
{ name: 'test-site', hostName: 'example.com', language: 'en' },
|
|
27
|
-
{ name: 'test-site-two', hostName: '*', language: 'da' },
|
|
28
|
-
];
|
|
29
|
-
|
|
30
|
-
beforeEach(() => {
|
|
31
|
-
sitecoreClientStub = sandbox.createStubInstance(SitecoreClient);
|
|
32
|
-
|
|
33
|
-
req = mockRequest({
|
|
34
|
-
headers: {
|
|
35
|
-
host: 'example.com',
|
|
36
|
-
'x-forwarded-proto': 'https',
|
|
37
|
-
},
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
siteResolverStub = {
|
|
41
|
-
getByHost: sandbox.stub(),
|
|
42
|
-
getByName: sandbox.stub(),
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
middleware = new SitemapMiddleware(sitecoreClientStub as unknown as SitecoreClient, sites);
|
|
46
|
-
(middleware as any).siteResolver = siteResolverStub;
|
|
47
|
-
siteResolverStub.getByHost.callsFake((hostName) =>
|
|
48
|
-
sites.find((site) => site.hostName === hostName)
|
|
49
|
-
);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
afterEach(() => {
|
|
53
|
-
sandbox.restore();
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
describe('getHandler', () => {
|
|
57
|
-
it('should return a handler function', () => {
|
|
58
|
-
const handler = middleware.getHandler();
|
|
59
|
-
expect(handler).to.be.a('function');
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
describe('handler', () => {
|
|
64
|
-
it('should process sitemap request without id parameter', async () => {
|
|
65
|
-
const siteName = sites[0].name;
|
|
66
|
-
const xmlContent = '<sitemapindex>...</sitemapindex>';
|
|
67
|
-
|
|
68
|
-
sitecoreClientStub.getSiteMap.resolves(xmlContent);
|
|
69
|
-
|
|
70
|
-
const res = await middleware.getHandler()(req as Request);
|
|
71
|
-
|
|
72
|
-
expect(sitecoreClientStub.getSiteMap.calledOnce).to.be.true;
|
|
73
|
-
expect(sitecoreClientStub.getSiteMap.firstCall.args[0]).to.deep.include({
|
|
74
|
-
reqHost: 'example.com',
|
|
75
|
-
reqProtocol: 'https',
|
|
76
|
-
id: '',
|
|
77
|
-
siteName: siteName,
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
expect(res.headers.get('Content-Type')).to.equal('text/xml;charset=utf-8');
|
|
81
|
-
|
|
82
|
-
const body = await res.text();
|
|
83
|
-
expect(body).to.deep.equal(xmlContent);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it('should handle sitemap request with specific id parameter', async () => {
|
|
87
|
-
const sitemapId = '1';
|
|
88
|
-
req = mockRequest({
|
|
89
|
-
url: `https://test.com/sitemap-${sitemapId}.xml`,
|
|
90
|
-
headers: {
|
|
91
|
-
host: 'example.com',
|
|
92
|
-
'x-forwarded-proto': 'https',
|
|
93
|
-
},
|
|
94
|
-
});
|
|
95
|
-
const siteName = sites[0].name;
|
|
96
|
-
const xmlContent = '<urlset>...</urlset>';
|
|
97
|
-
|
|
98
|
-
sitecoreClientStub.getSiteMap.resolves(xmlContent);
|
|
99
|
-
|
|
100
|
-
const res = await middleware.getHandler()(req as Request);
|
|
101
|
-
|
|
102
|
-
expect(sitecoreClientStub.getSiteMap.firstCall.args[0]).to.deep.include({
|
|
103
|
-
reqHost: 'example.com',
|
|
104
|
-
reqProtocol: 'https',
|
|
105
|
-
id: sitemapId,
|
|
106
|
-
siteName: siteName,
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
const body = await res.text();
|
|
110
|
-
expect(body).to.deep.equal(xmlContent);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it('should default to https protocol when x-forwarded-proto header is missing', async () => {
|
|
114
|
-
req.headers?.delete('x-forwarded-proto');
|
|
115
|
-
const siteName = sites[0].name;
|
|
116
|
-
const xmlContent = '<sitemapindex>...</sitemapindex>';
|
|
117
|
-
|
|
118
|
-
sitecoreClientStub.getSiteMap.resolves(xmlContent);
|
|
119
|
-
|
|
120
|
-
await middleware.getHandler()(req as Request);
|
|
121
|
-
|
|
122
|
-
expect(sitecoreClientStub.getSiteMap.firstCall.args[0]).to.deep.include({
|
|
123
|
-
reqHost: 'example.com',
|
|
124
|
-
reqProtocol: 'https',
|
|
125
|
-
siteName: siteName,
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it('should use x-forwarded-host header when present', async () => {
|
|
130
|
-
req = mockRequest({
|
|
131
|
-
headers: {
|
|
132
|
-
'x-forwarded-host': 'example.com',
|
|
133
|
-
host: 'localhost:3000',
|
|
134
|
-
},
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
await middleware.getHandler()(req as Request);
|
|
138
|
-
|
|
139
|
-
expect(siteResolverStub.getByHost).to.have.been.calledWith('example.com');
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
it('should use empty string when both x-forwarded-host and host headers are missing', async () => {
|
|
143
|
-
req.headers?.delete('host');
|
|
144
|
-
const xmlContent = '<sitemapindex>...</sitemapindex>';
|
|
145
|
-
|
|
146
|
-
siteResolverStub.getByHost.withArgs('').returns(sites[1]);
|
|
147
|
-
|
|
148
|
-
sitecoreClientStub.getSiteMap.resolves(xmlContent);
|
|
149
|
-
|
|
150
|
-
await middleware.getHandler()(req as Request);
|
|
151
|
-
|
|
152
|
-
expect(sitecoreClientStub.getSiteMap.firstCall.args[0]).to.deep.include({
|
|
153
|
-
reqHost: '',
|
|
154
|
-
reqProtocol: 'https',
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
it('should redirect to 404 when REDIRECT_404 error is thrown', async () => {
|
|
159
|
-
const error = new Error('REDIRECT_404');
|
|
160
|
-
|
|
161
|
-
sitecoreClientStub.getSiteMap.rejects(error);
|
|
162
|
-
|
|
163
|
-
const res = await middleware.getHandler()(req as Request);
|
|
164
|
-
|
|
165
|
-
expect(res.status).to.equal(302);
|
|
166
|
-
expect(res.body).to.equal(null);
|
|
167
|
-
|
|
168
|
-
expect(res.headers.has('Location')).to.be.true;
|
|
169
|
-
expect(res.headers.get('Location')).to.equal('/404');
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
it('should return 500 error when any other error occurs', async () => {
|
|
173
|
-
const error = new Error('Unexpected error');
|
|
174
|
-
|
|
175
|
-
sitecoreClientStub.getSiteMap.rejects(error);
|
|
176
|
-
|
|
177
|
-
const res = await middleware.getHandler()(req as Request);
|
|
178
|
-
|
|
179
|
-
const body = await res.text();
|
|
180
|
-
expect(res.status).to.equal(500);
|
|
181
|
-
expect(body).to.equal(`Internal Server Error. ${ERROR_MESSAGES.CONTACT_SUPPORT}`);
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
});
|
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
// import chalk from 'chalk';
|
|
2
|
-
import {
|
|
3
|
-
LayoutServiceData,
|
|
4
|
-
ComponentRendering,
|
|
5
|
-
PlaceholdersData,
|
|
6
|
-
} from '@sitecore-content-sdk/content/layout';
|
|
7
|
-
import {
|
|
8
|
-
AstroContentSdkComponent,
|
|
9
|
-
ComponentMap,
|
|
10
|
-
ComponentPropsCollection,
|
|
11
|
-
} from '../sharedTypes/component-props';
|
|
12
|
-
|
|
13
|
-
export type FetchComponentPropsArguments = {
|
|
14
|
-
layoutData: LayoutServiceData;
|
|
15
|
-
// context: NextContext;
|
|
16
|
-
components: ComponentMap<AstroContentSdkComponent>;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export type ComponentPropsRequest = {
|
|
20
|
-
// fetch: ComponentPropsFetchFunction;
|
|
21
|
-
layoutData: LayoutServiceData;
|
|
22
|
-
rendering: ComponentRendering;
|
|
23
|
-
// context: NextContext;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* The service for fetching component props.
|
|
28
|
-
* @public
|
|
29
|
-
*/
|
|
30
|
-
export class ComponentPropsService {
|
|
31
|
-
async fetchComponentProps(
|
|
32
|
-
params: FetchComponentPropsArguments
|
|
33
|
-
): Promise<ComponentPropsCollection> {
|
|
34
|
-
const { layoutData, components } = params;
|
|
35
|
-
const requests = await this.collectRequests({
|
|
36
|
-
placeholders: layoutData.sitecore.route?.placeholders,
|
|
37
|
-
components,
|
|
38
|
-
layoutData,
|
|
39
|
-
// context,
|
|
40
|
-
});
|
|
41
|
-
return await this.execRequests(requests);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Go through layout service data, check all renderings using displayName, which should make some side effects.
|
|
46
|
-
* Write result in requests variable
|
|
47
|
-
* @param {object} params params
|
|
48
|
-
* @param {PlaceholdersData} [params.placeholders]
|
|
49
|
-
* @param {ComponentMap} params.components
|
|
50
|
-
* @param {LayoutServiceData} params.layoutData
|
|
51
|
-
* @param {ComponentPropsRequest[]} params.requests
|
|
52
|
-
* @returns {ComponentPropsRequest[]} array of requests
|
|
53
|
-
*/
|
|
54
|
-
protected async collectRequests(params: {
|
|
55
|
-
placeholders?: PlaceholdersData;
|
|
56
|
-
components: ComponentMap<AstroContentSdkComponent>;
|
|
57
|
-
layoutData: LayoutServiceData;
|
|
58
|
-
// context: NextContext;
|
|
59
|
-
requests?: ComponentPropsRequest[];
|
|
60
|
-
}): Promise<ComponentPropsRequest[]> {
|
|
61
|
-
const { placeholders = {}, layoutData } = params;
|
|
62
|
-
|
|
63
|
-
// Will be called on first round
|
|
64
|
-
if (!params.requests) {
|
|
65
|
-
params.requests = [];
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const renderings = this.flatRenderings(placeholders);
|
|
69
|
-
|
|
70
|
-
const actions = renderings.map(async (r) => {
|
|
71
|
-
// const fetchFunc = (await this.getModule(components, r.componentName))
|
|
72
|
-
// ?.getComponentServerProps;
|
|
73
|
-
|
|
74
|
-
const fetchFunc = ''; // getModule
|
|
75
|
-
|
|
76
|
-
if (fetchFunc) {
|
|
77
|
-
params.requests &&
|
|
78
|
-
params.requests.push({
|
|
79
|
-
// fetch: fetchFunc,
|
|
80
|
-
rendering: r,
|
|
81
|
-
layoutData: layoutData,
|
|
82
|
-
// context,
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// If placeholders exist in current rendering
|
|
87
|
-
if (r.placeholders) {
|
|
88
|
-
await this.collectRequests({
|
|
89
|
-
...params,
|
|
90
|
-
placeholders: r.placeholders,
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
await Promise.all(actions);
|
|
96
|
-
|
|
97
|
-
return params.requests;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Execute request for component props
|
|
102
|
-
* @param {ComponentPropsRequest[]} requests requests
|
|
103
|
-
* @returns {Promise<ComponentPropsCollection>} requests result
|
|
104
|
-
*/
|
|
105
|
-
protected async execRequests(
|
|
106
|
-
requests: ComponentPropsRequest[]
|
|
107
|
-
): Promise<ComponentPropsCollection> {
|
|
108
|
-
const componentProps: ComponentPropsCollection = {};
|
|
109
|
-
|
|
110
|
-
const promises = requests.map((req) => {
|
|
111
|
-
const { uid } = req.rendering;
|
|
112
|
-
|
|
113
|
-
if (!uid) {
|
|
114
|
-
console.log(
|
|
115
|
-
`Component ${req.rendering.componentName} doesn't have uid, can't store data for this component`
|
|
116
|
-
);
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// return req
|
|
121
|
-
// .fetch(req.rendering, req.layoutData /*, req.context*/)
|
|
122
|
-
// .then((result) => {
|
|
123
|
-
// // Set component specific data in componentProps store
|
|
124
|
-
// componentProps[uid] = result;
|
|
125
|
-
// })
|
|
126
|
-
// .catch((error) => {
|
|
127
|
-
// const errLog = `Error during preload data for component ${
|
|
128
|
-
// req.rendering.componentName
|
|
129
|
-
// } (${uid}): ${error.message || error}`;
|
|
130
|
-
|
|
131
|
-
// console.error(chalk.red(errLog));
|
|
132
|
-
|
|
133
|
-
// componentProps[uid] = {
|
|
134
|
-
// error: error.message || errLog,
|
|
135
|
-
// componentName: req.rendering.componentName,
|
|
136
|
-
// };
|
|
137
|
-
// });
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
await Promise.all(promises);
|
|
141
|
-
|
|
142
|
-
return componentProps;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Take renderings from all placeholders and returns a flat array of renderings.
|
|
147
|
-
* @example
|
|
148
|
-
* const placeholders = {
|
|
149
|
-
* x1: [{ uid: 1 }, { uid: 2 }],
|
|
150
|
-
* x2: [{ uid: 11 }, { uid: 22 }]
|
|
151
|
-
* }
|
|
152
|
-
*
|
|
153
|
-
* flatRenderings(placeholders);
|
|
154
|
-
*
|
|
155
|
-
* RESULT: [{ uid: 1 }, { uid: 2 }, { uid: 11 }, { uid: 22 }]
|
|
156
|
-
* @param {PlaceholdersData} placeholders placeholders
|
|
157
|
-
* @returns {ComponentRendering[]} renderings
|
|
158
|
-
*/
|
|
159
|
-
protected flatRenderings(placeholders: PlaceholdersData): ComponentRendering[] {
|
|
160
|
-
const allComponentRenderings: ComponentRendering[] = [];
|
|
161
|
-
const placeholdersArr = Object.values(placeholders);
|
|
162
|
-
|
|
163
|
-
placeholdersArr.forEach((pl) => {
|
|
164
|
-
const renderings = pl as ComponentRendering[];
|
|
165
|
-
allComponentRenderings.push(...renderings);
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
return allComponentRenderings;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// private async getModule(
|
|
172
|
-
// components: ComponentMap<AstroContentSdkComponent>,
|
|
173
|
-
// componentName: string
|
|
174
|
-
// ) {
|
|
175
|
-
// const component = components.get(componentName);
|
|
176
|
-
|
|
177
|
-
// if (!component) return null;
|
|
178
|
-
|
|
179
|
-
// //const module = component.dynamicModule ? await component?.dynamicModule?.() : component;
|
|
180
|
-
// const module = component;
|
|
181
|
-
// return module as AstroContentSdkComponent;
|
|
182
|
-
// }
|
|
183
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import type { ComponentProps } from 'astro/types';
|
|
2
|
-
import {
|
|
3
|
-
experimental_AstroContainer as AstroContainer,
|
|
4
|
-
type ContainerRenderOptions,
|
|
5
|
-
} from 'astro/container';
|
|
6
|
-
import { Page } from '@sitecore-content-sdk/content/client';
|
|
7
|
-
import { ComponentMap } from '../sharedTypes/component-props';
|
|
8
|
-
import { vi } from 'vitest';
|
|
9
|
-
import { SitecoreContext } from '../context';
|
|
10
|
-
|
|
11
|
-
type AstroComponentFactory = Parameters<AstroContainer['renderToString']>[0];
|
|
12
|
-
|
|
13
|
-
type ComponentContainerRenderOptions<T extends AstroComponentFactory> = Omit<
|
|
14
|
-
ContainerRenderOptions,
|
|
15
|
-
'props'
|
|
16
|
-
> & {
|
|
17
|
-
// @ts-expect-error
|
|
18
|
-
props?: ComponentProps<T>;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Renders an Astro component to a DOM element for tests.
|
|
23
|
-
* @param {AstroComponentFactory} Component - The Astro component to render.
|
|
24
|
-
* @param {ComponentContainerRenderOptions<T>} options - Container render options, including component props.
|
|
25
|
-
* @returns A `div` whose `innerHTML` is the rendered markup (Astro attributes stripped).
|
|
26
|
-
*/
|
|
27
|
-
export async function renderAstroComponent<T extends AstroComponentFactory>(
|
|
28
|
-
Component: T,
|
|
29
|
-
options: ComponentContainerRenderOptions<T> = {}
|
|
30
|
-
) {
|
|
31
|
-
const container = await AstroContainer.create();
|
|
32
|
-
const result = await container.renderToString(Component, options);
|
|
33
|
-
|
|
34
|
-
const html = removeAstroAttributes(result);
|
|
35
|
-
|
|
36
|
-
const div = document.createElement('div');
|
|
37
|
-
div.innerHTML = html;
|
|
38
|
-
|
|
39
|
-
return div;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export const mockSitecoreContext = (page?: Page, map?: ComponentMap, api?: any) => {
|
|
43
|
-
const getMock = vi.fn();
|
|
44
|
-
|
|
45
|
-
getMock.mockReturnValue({
|
|
46
|
-
page: page,
|
|
47
|
-
componentMap: map,
|
|
48
|
-
api: api,
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
SitecoreContext.get = getMock;
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Removes Astro-specific data attributes (data-astro-*)
|
|
56
|
-
* and whitespaces between HTML tags from a given HTML string.
|
|
57
|
-
* @param {string} html - Raw HTML string from Astro rendering.
|
|
58
|
-
*/
|
|
59
|
-
const removeAstroAttributes = (html: string) => {
|
|
60
|
-
return html.replace(/\s*data-astro-[a-zA-Z0-9-]+=(\"|\').*?\1\s*/g, '').replace(/>\s+</g, '><');
|
|
61
|
-
};
|
package/src/tests/helpers.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
export type Query = {
|
|
2
|
-
[key: string]: string | string[];
|
|
3
|
-
};
|
|
4
|
-
|
|
5
|
-
const baseUrl = 'https://test.com';
|
|
6
|
-
|
|
7
|
-
export const mockRequest = ({
|
|
8
|
-
url,
|
|
9
|
-
method,
|
|
10
|
-
query,
|
|
11
|
-
headers,
|
|
12
|
-
}: {
|
|
13
|
-
url?: string;
|
|
14
|
-
method?: string;
|
|
15
|
-
query?: Query;
|
|
16
|
-
headers?: { [key: string]: string };
|
|
17
|
-
}) => {
|
|
18
|
-
const requestUrl = addQueryToUrl(url || baseUrl, query);
|
|
19
|
-
return new Request(requestUrl, {
|
|
20
|
-
method,
|
|
21
|
-
headers: headers,
|
|
22
|
-
});
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export const addQueryToUrl = (baseUrl: string, query?: Query): string => {
|
|
26
|
-
const url = new URL(baseUrl);
|
|
27
|
-
const params = new URLSearchParams();
|
|
28
|
-
|
|
29
|
-
if (query) {
|
|
30
|
-
Object.entries(query).forEach(([key, value]) => {
|
|
31
|
-
if (Array.isArray(value)) {
|
|
32
|
-
value.forEach((item) => {
|
|
33
|
-
params.append(key, item);
|
|
34
|
-
});
|
|
35
|
-
} else {
|
|
36
|
-
params.append(key, value);
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
params.forEach((value, key) => {
|
|
41
|
-
url.searchParams.append(key, value);
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return url.toString();
|
|
46
|
-
};
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
export const mountain_bike_audience = {
|
|
2
|
-
uid: '0b6d23d8-c50e-4e79-9eca-317ec43e82b0',
|
|
3
|
-
componentName: 'ContentBlock',
|
|
4
|
-
dataSource: '20679cd4-356b-4452-b507-453beeb0be39',
|
|
5
|
-
fields: {
|
|
6
|
-
content: {
|
|
7
|
-
value:
|
|
8
|
-
'<p><img src="https://edge-beta.sitecorecloud.io/ser-edge-personalization/media/CsdkNextWeb/Mountain-Bike.jpg?h=675&w=1200" style="width:1200px;height:675px;" /></p>',
|
|
9
|
-
},
|
|
10
|
-
heading: { value: 'Mountain Bike' },
|
|
11
|
-
},
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export const city_bike_audience = {
|
|
15
|
-
uid: '0b6d23d8-c50e-4e79-9eca-317ec43e82b0',
|
|
16
|
-
componentName: 'ContentBlock',
|
|
17
|
-
dataSource: '36e02581-2056-4c55-a4d5-f4b700ba1ae2',
|
|
18
|
-
fields: {
|
|
19
|
-
content: {
|
|
20
|
-
value:
|
|
21
|
-
'<p><img src="https://edge-beta.sitecorecloud.io/ser-edge-personalization/media/CsdkNextWeb/Mountain-Bike.jpg?h=675&w=1200" style="width:1200px;height:675px;" /></p>',
|
|
22
|
-
},
|
|
23
|
-
heading: { value: 'Mountain Bike' },
|
|
24
|
-
},
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export const layoutData = {
|
|
28
|
-
sitecore: {
|
|
29
|
-
context: {
|
|
30
|
-
pageEditing: false,
|
|
31
|
-
site: { name: 'CsdkNextWeb' },
|
|
32
|
-
visitorIdentificationTimestamp: 1038543,
|
|
33
|
-
language: 'en',
|
|
34
|
-
variantId: undefined,
|
|
35
|
-
},
|
|
36
|
-
route: {
|
|
37
|
-
name: 'landingpage',
|
|
38
|
-
placeholders: {
|
|
39
|
-
'content-sdk-main': [
|
|
40
|
-
{
|
|
41
|
-
uid: '0b6d23d8-c50e-4e79-9eca-317ec43e82b0',
|
|
42
|
-
componentName: 'ContentBlock',
|
|
43
|
-
dataSource: 'e020fb58-1be8-4537-aab8-67916452ecf2',
|
|
44
|
-
fields: { content: { value: '' }, heading: { value: 'Default Content' } },
|
|
45
|
-
experiences: {
|
|
46
|
-
mountain_bike_audience: mountain_bike_audience,
|
|
47
|
-
city_bike_audience: city_bike_audience,
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
],
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
export const componentWithExperiences = {
|
|
57
|
-
uid: '0b6d23d8-c50e-4e79-9eca-317ec43e82b0',
|
|
58
|
-
componentName: 'ContentBlock',
|
|
59
|
-
dataSource: '20679cd4-356b-4452-b507-453beeb0be39',
|
|
60
|
-
fields: mountain_bike_audience.fields,
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
export const componentsWithExperiencesArray = [componentWithExperiences];
|