@sitecore-content-sdk/nextjs 0.1.0-beta.1
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/LICENSE.txt +202 -0
- package/README.md +10 -0
- package/dist/cjs/ComponentBuilder.js +63 -0
- package/dist/cjs/components/BYOCWrapper.js +41 -0
- package/dist/cjs/components/ComponentPropsContext.js +57 -0
- package/dist/cjs/components/FEaaSWrapper.js +43 -0
- package/dist/cjs/components/Link.js +87 -0
- package/dist/cjs/components/NextImage.js +82 -0
- package/dist/cjs/components/Placeholder.js +49 -0
- package/dist/cjs/components/RichText.js +95 -0
- package/dist/cjs/editing/constants.js +10 -0
- package/dist/cjs/editing/editing-config-middleware.js +62 -0
- package/dist/cjs/editing/editing-render-middleware.js +182 -0
- package/dist/cjs/editing/feaas-render-middleware.js +101 -0
- package/dist/cjs/editing/index.js +16 -0
- package/dist/cjs/editing/render-middleware.js +43 -0
- package/dist/cjs/graphql/index.js +7 -0
- package/dist/cjs/index.js +119 -0
- package/dist/cjs/middleware/index.js +13 -0
- package/dist/cjs/middleware/middleware.js +97 -0
- package/dist/cjs/middleware/multisite-middleware.js +93 -0
- package/dist/cjs/middleware/personalize-middleware.js +231 -0
- package/dist/cjs/middleware/redirects-middleware.js +264 -0
- package/dist/cjs/monitoring/healthcheck-middleware.js +30 -0
- package/dist/cjs/monitoring/index.js +5 -0
- package/dist/cjs/services/base-graphql-sitemap-service.js +206 -0
- package/dist/cjs/services/component-props-service.js +167 -0
- package/dist/cjs/services/graphql-sitemap-service.js +64 -0
- package/dist/cjs/services/mutisite-graphql-sitemap-service.js +81 -0
- package/dist/cjs/sharedTypes/component-props.js +2 -0
- package/dist/cjs/sharedTypes/module-factory.js +2 -0
- package/dist/cjs/site/index.js +5 -0
- package/dist/cjs/utils/index.js +11 -0
- package/dist/cjs/utils/utils.js +42 -0
- package/dist/esm/ComponentBuilder.js +59 -0
- package/dist/esm/components/BYOCWrapper.js +36 -0
- package/dist/esm/components/ComponentPropsContext.js +19 -0
- package/dist/esm/components/FEaaSWrapper.js +38 -0
- package/dist/esm/components/Link.js +48 -0
- package/dist/esm/components/NextImage.js +76 -0
- package/dist/esm/components/Placeholder.js +12 -0
- package/dist/esm/components/RichText.js +55 -0
- package/dist/esm/editing/constants.js +7 -0
- package/dist/esm/editing/editing-config-middleware.js +58 -0
- package/dist/esm/editing/editing-render-middleware.js +177 -0
- package/dist/esm/editing/feaas-render-middleware.js +97 -0
- package/dist/esm/editing/index.js +5 -0
- package/dist/esm/editing/render-middleware.js +39 -0
- package/dist/esm/graphql/index.js +1 -0
- package/dist/esm/index.js +23 -0
- package/dist/esm/middleware/index.js +5 -0
- package/dist/esm/middleware/middleware.js +93 -0
- package/dist/esm/middleware/multisite-middleware.js +89 -0
- package/dist/esm/middleware/personalize-middleware.js +227 -0
- package/dist/esm/middleware/redirects-middleware.js +257 -0
- package/dist/esm/monitoring/healthcheck-middleware.js +26 -0
- package/dist/esm/monitoring/index.js +1 -0
- package/dist/esm/services/base-graphql-sitemap-service.js +201 -0
- package/dist/esm/services/component-props-service.js +160 -0
- package/dist/esm/services/graphql-sitemap-service.js +59 -0
- package/dist/esm/services/mutisite-graphql-sitemap-service.js +77 -0
- package/dist/esm/sharedTypes/component-props.js +1 -0
- package/dist/esm/sharedTypes/module-factory.js +1 -0
- package/dist/esm/site/index.js +1 -0
- package/dist/esm/utils/index.js +3 -0
- package/dist/esm/utils/utils.js +37 -0
- package/editing.d.ts +1 -0
- package/editing.js +1 -0
- package/global.d.ts +21 -0
- package/graphql.d.ts +1 -0
- package/graphql.js +1 -0
- package/middleware.d.ts +1 -0
- package/middleware.js +1 -0
- package/monitoring.d.ts +1 -0
- package/monitoring.js +1 -0
- package/package.json +92 -0
- package/site.d.ts +1 -0
- package/site.js +1 -0
- package/types/ComponentBuilder.d.ts +59 -0
- package/types/components/BYOCWrapper.d.ts +20 -0
- package/types/components/ComponentPropsContext.d.ts +18 -0
- package/types/components/FEaaSWrapper.d.ts +22 -0
- package/types/components/Link.d.ts +10 -0
- package/types/components/NextImage.d.ts +6 -0
- package/types/components/Placeholder.d.ts +8 -0
- package/types/components/RichText.d.ts +32 -0
- package/types/editing/constants.d.ts +7 -0
- package/types/editing/editing-config-middleware.d.ts +29 -0
- package/types/editing/editing-render-middleware.d.ts +79 -0
- package/types/editing/feaas-render-middleware.d.ts +32 -0
- package/types/editing/index.d.ts +5 -0
- package/types/editing/render-middleware.d.ts +24 -0
- package/types/graphql/index.d.ts +1 -0
- package/types/index.d.ts +24 -0
- package/types/middleware/index.d.ts +5 -0
- package/types/middleware/middleware.d.ts +82 -0
- package/types/middleware/multisite-middleware.d.ts +39 -0
- package/types/middleware/personalize-middleware.d.ts +102 -0
- package/types/middleware/redirects-middleware.d.ts +57 -0
- package/types/monitoring/healthcheck-middleware.d.ts +12 -0
- package/types/monitoring/index.d.ts +1 -0
- package/types/services/base-graphql-sitemap-service.d.ts +148 -0
- package/types/services/component-props-service.d.ts +81 -0
- package/types/services/graphql-sitemap-service.d.ts +51 -0
- package/types/services/mutisite-graphql-sitemap-service.d.ts +42 -0
- package/types/sharedTypes/component-props.d.ts +26 -0
- package/types/sharedTypes/module-factory.d.ts +32 -0
- package/types/site/index.d.ts +1 -0
- package/types/utils/index.d.ts +3 -0
- package/types/utils/utils.d.ts +8 -0
- package/utils.d.ts +1 -0
- package/utils.js +1 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { debug } from '@sitecore-content-sdk/core';
|
|
11
|
+
import { getPersonalizedRewrite } from '@sitecore-content-sdk/core/personalize';
|
|
12
|
+
/** @private */
|
|
13
|
+
export const languageError = 'The list of languages cannot be empty';
|
|
14
|
+
export const siteError = 'The service needs a site name';
|
|
15
|
+
/**
|
|
16
|
+
* @param {string} siteName to inject into error text
|
|
17
|
+
* @private
|
|
18
|
+
*/
|
|
19
|
+
export function getSiteEmptyError(siteName) {
|
|
20
|
+
return `Site "${siteName}" does not exist or site item tree is missing`;
|
|
21
|
+
}
|
|
22
|
+
const languageEmptyError = 'The language must be a non-empty string';
|
|
23
|
+
/**
|
|
24
|
+
* GQL query made dynamic based whether personalization is enabled or not
|
|
25
|
+
* @param {boolean} usesPersonalize flag to detrmine which variation of a query to run
|
|
26
|
+
* @returns GraphQL query to fetch site paths with
|
|
27
|
+
*/
|
|
28
|
+
const defaultQuery = (usesPersonalize) => /* GraphQL */ `
|
|
29
|
+
query ${usesPersonalize ? 'PersonalizeSitemapQuery' : 'DefaultSitemapQuery'}(
|
|
30
|
+
$siteName: String!
|
|
31
|
+
$language: String!
|
|
32
|
+
$includedPaths: [String]
|
|
33
|
+
$excludedPaths: [String]
|
|
34
|
+
$pageSize: Int = 100
|
|
35
|
+
$after: String
|
|
36
|
+
) {
|
|
37
|
+
site {
|
|
38
|
+
siteInfo(site: $siteName) {
|
|
39
|
+
routes(
|
|
40
|
+
language: $language
|
|
41
|
+
includedPaths: $includedPaths
|
|
42
|
+
excludedPaths: $excludedPaths
|
|
43
|
+
first: $pageSize
|
|
44
|
+
after: $after
|
|
45
|
+
){
|
|
46
|
+
total
|
|
47
|
+
pageInfo {
|
|
48
|
+
endCursor
|
|
49
|
+
hasNext
|
|
50
|
+
}
|
|
51
|
+
results {
|
|
52
|
+
path: routePath
|
|
53
|
+
${usesPersonalize
|
|
54
|
+
? `
|
|
55
|
+
route {
|
|
56
|
+
personalization {
|
|
57
|
+
variantIds
|
|
58
|
+
}
|
|
59
|
+
}`
|
|
60
|
+
: ''}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
`;
|
|
67
|
+
/**
|
|
68
|
+
* Service that fetches the list of site pages using Sitecore's GraphQL API.
|
|
69
|
+
* Used to handle a single site
|
|
70
|
+
* This list is used for SSG and Export functionality.
|
|
71
|
+
* @mixes SearchQueryService<PageListQueryResult>
|
|
72
|
+
*/
|
|
73
|
+
export class BaseGraphQLSitemapService {
|
|
74
|
+
/**
|
|
75
|
+
* Creates an instance of graphQL sitemap service with the provided options
|
|
76
|
+
* @param {GraphQLSitemapServiceConfig} options instance
|
|
77
|
+
*/
|
|
78
|
+
constructor(options) {
|
|
79
|
+
this.options = options;
|
|
80
|
+
this._graphQLClient = this.getGraphQLClient();
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* GraphQL client accessible by descendant classes when needed
|
|
84
|
+
*/
|
|
85
|
+
get graphQLClient() {
|
|
86
|
+
return this._graphQLClient;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Gets the default query used for fetching the list of site pages
|
|
90
|
+
*/
|
|
91
|
+
get query() {
|
|
92
|
+
return defaultQuery(this.options.includePersonalizedRoutes);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Fetch sitemap which could be used for generation of static pages during `next export`.
|
|
96
|
+
* The `locale` parameter will be used in the item query, but since i18n is not supported,
|
|
97
|
+
* the output paths will not include a `language` property.
|
|
98
|
+
* @param {string} locale which application supports
|
|
99
|
+
* @returns an array of @see StaticPath objects
|
|
100
|
+
*/
|
|
101
|
+
fetchExportSitemap(locale) {
|
|
102
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
103
|
+
const formatPath = (path) => ({
|
|
104
|
+
params: {
|
|
105
|
+
path,
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
return this.fetchSitemap([locale], formatPath);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Fetch sitemap which could be used for generation of static pages using SSG mode
|
|
113
|
+
* @param {string[]} locales locales which application supports
|
|
114
|
+
* @returns an array of @see StaticPath objects
|
|
115
|
+
*/
|
|
116
|
+
fetchSSGSitemap(locales) {
|
|
117
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
118
|
+
const formatPath = (path, locale) => ({
|
|
119
|
+
params: {
|
|
120
|
+
path,
|
|
121
|
+
},
|
|
122
|
+
locale,
|
|
123
|
+
});
|
|
124
|
+
return this.fetchSitemap(locales, formatPath);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
getTranformedPaths(siteName, languages, formatStaticPath) {
|
|
128
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
129
|
+
const paths = new Array();
|
|
130
|
+
for (const language of languages) {
|
|
131
|
+
if (language === '') {
|
|
132
|
+
throw new RangeError(languageEmptyError);
|
|
133
|
+
}
|
|
134
|
+
debug.sitemap('fetching sitemap data for %s %s', language, siteName);
|
|
135
|
+
const results = yield this.fetchLanguageSitePaths(language, siteName);
|
|
136
|
+
const transformedPaths = yield this.transformLanguageSitePaths(results, formatStaticPath, language);
|
|
137
|
+
paths.push(...transformedPaths);
|
|
138
|
+
}
|
|
139
|
+
return paths;
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
transformLanguageSitePaths(sitePaths, formatStaticPath, language) {
|
|
143
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
144
|
+
const formatPath = (path) => formatStaticPath(path.replace(/^\/|\/$/g, '').split('/'), language);
|
|
145
|
+
const aggregatedPaths = [];
|
|
146
|
+
sitePaths.forEach((item) => {
|
|
147
|
+
var _a, _b, _c;
|
|
148
|
+
if (!item)
|
|
149
|
+
return;
|
|
150
|
+
aggregatedPaths.push(formatPath(item.path));
|
|
151
|
+
const variantIds = (_c = (_b = (_a = item.route) === null || _a === void 0 ? void 0 : _a.personalization) === null || _b === void 0 ? void 0 : _b.variantIds) === null || _c === void 0 ? void 0 : _c.filter((variantId) => !variantId.includes('_') // exclude component A/B test variants
|
|
152
|
+
);
|
|
153
|
+
if (variantIds === null || variantIds === void 0 ? void 0 : variantIds.length) {
|
|
154
|
+
aggregatedPaths.push(...variantIds.map((varId) => formatPath(getPersonalizedRewrite(item.path, [varId]))));
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
return aggregatedPaths;
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
fetchLanguageSitePaths(language, siteName) {
|
|
161
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
162
|
+
var _a, _b, _c, _d;
|
|
163
|
+
const args = {
|
|
164
|
+
siteName: siteName,
|
|
165
|
+
language: language,
|
|
166
|
+
pageSize: this.options.pageSize,
|
|
167
|
+
includedPaths: this.options.includedPaths,
|
|
168
|
+
excludedPaths: this.options.excludedPaths,
|
|
169
|
+
};
|
|
170
|
+
let results = [];
|
|
171
|
+
let hasNext = true;
|
|
172
|
+
let after = '';
|
|
173
|
+
while (hasNext) {
|
|
174
|
+
const fetchResponse = yield this.graphQLClient.request(this.query, Object.assign(Object.assign({}, args), { after }));
|
|
175
|
+
if (!((_a = fetchResponse === null || fetchResponse === void 0 ? void 0 : fetchResponse.site) === null || _a === void 0 ? void 0 : _a.siteInfo)) {
|
|
176
|
+
throw new RangeError(getSiteEmptyError(siteName));
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
results = results.concat((_b = fetchResponse.site.siteInfo.routes) === null || _b === void 0 ? void 0 : _b.results);
|
|
180
|
+
hasNext = (_c = fetchResponse.site.siteInfo.routes) === null || _c === void 0 ? void 0 : _c.pageInfo.hasNext;
|
|
181
|
+
after = (_d = fetchResponse.site.siteInfo.routes) === null || _d === void 0 ? void 0 : _d.pageInfo.endCursor;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return results;
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Gets a GraphQL client that can make requests to the API. Uses graphql-request as the default
|
|
189
|
+
* library for fetching graphql data (@see GraphQLRequestClient). Override this method if you
|
|
190
|
+
* want to use something else.
|
|
191
|
+
* @returns {GraphQLClient} implementation
|
|
192
|
+
*/
|
|
193
|
+
getGraphQLClient() {
|
|
194
|
+
if (!this.options.clientFactory) {
|
|
195
|
+
throw new Error('clientFactory needs to be provided when initializing GraphQL client.');
|
|
196
|
+
}
|
|
197
|
+
return this.options.clientFactory({
|
|
198
|
+
debugger: debug.sitemap,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import chalk from 'chalk';
|
|
11
|
+
export class ComponentPropsService {
|
|
12
|
+
/**
|
|
13
|
+
* SSR mode
|
|
14
|
+
* Fetch component props using getServerSideProps function
|
|
15
|
+
* @param {FetchComponentPropsArguments<GetServerSidePropsContext>} params fetch params
|
|
16
|
+
* @returns {Promise<ComponentPropsCollection>} props
|
|
17
|
+
*/
|
|
18
|
+
fetchServerSideComponentProps(params) {
|
|
19
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
const { moduleFactory, layoutData, context } = params;
|
|
21
|
+
const fetchFunctionFactory = (componentName) => __awaiter(this, void 0, void 0, function* () {
|
|
22
|
+
const module = yield moduleFactory(componentName);
|
|
23
|
+
return module === null || module === void 0 ? void 0 : module.getServerSideProps;
|
|
24
|
+
});
|
|
25
|
+
return this.fetchComponentProps(fetchFunctionFactory, layoutData, context);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* SSG mode
|
|
30
|
+
* Fetch component props using getStaticProps function
|
|
31
|
+
* @param {FetchComponentPropsArguments<GetStaticPropsContext>} params fetch arguments
|
|
32
|
+
* @returns {Promise<ComponentPropsCollection>} props
|
|
33
|
+
*/
|
|
34
|
+
fetchStaticComponentProps(params) {
|
|
35
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
+
const { moduleFactory, layoutData, context } = params;
|
|
37
|
+
const fetchFunctionFactory = (componentName) => __awaiter(this, void 0, void 0, function* () {
|
|
38
|
+
const module = yield moduleFactory(componentName);
|
|
39
|
+
return module === null || module === void 0 ? void 0 : module.getStaticProps;
|
|
40
|
+
});
|
|
41
|
+
return this.fetchComponentProps(fetchFunctionFactory, layoutData, context);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Traverse Layout Service data tree and call side effects on component level.
|
|
46
|
+
* Side effect function can be: getStaticProps (SSG) or getServerSideProps (SSR)
|
|
47
|
+
* @param {FetchFunctionFactory<NextContext>} fetchFunctionFactory fetch function factory
|
|
48
|
+
* @param {LayoutServiceData} layoutData layout data
|
|
49
|
+
* @param {NextContext} context next context
|
|
50
|
+
* @returns {Promise<ComponentPropsCollection>} component props
|
|
51
|
+
*/
|
|
52
|
+
fetchComponentProps(fetchFunctionFactory, layoutData, context) {
|
|
53
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
54
|
+
var _a;
|
|
55
|
+
// Array of side effect functions
|
|
56
|
+
const requests = yield this.collectRequests({
|
|
57
|
+
placeholders: (_a = layoutData.sitecore.route) === null || _a === void 0 ? void 0 : _a.placeholders,
|
|
58
|
+
fetchFunctionFactory,
|
|
59
|
+
layoutData,
|
|
60
|
+
context,
|
|
61
|
+
});
|
|
62
|
+
return yield this.execRequests(requests);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Go through layout service data, check all renderings using displayName, which should make some side effects.
|
|
67
|
+
* Write result in requests variable
|
|
68
|
+
* @param {object} params params
|
|
69
|
+
* @param {PlaceholdersData} [params.placeholders]
|
|
70
|
+
* @param {FetchFunctionFactory<NextContext>} params.fetchFunctionFactory
|
|
71
|
+
* @param {LayoutServiceData} params.layoutData
|
|
72
|
+
* @param {NextContext} params.context
|
|
73
|
+
* @param {ComponentPropsRequest<NextContext>[]} params.requests
|
|
74
|
+
* @returns {ComponentPropsRequest<NextContext>[]} array of requests
|
|
75
|
+
*/
|
|
76
|
+
collectRequests(params) {
|
|
77
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
78
|
+
const { placeholders = {}, fetchFunctionFactory, layoutData, context } = params;
|
|
79
|
+
// Will be called on first round
|
|
80
|
+
if (!params.requests) {
|
|
81
|
+
params.requests = [];
|
|
82
|
+
}
|
|
83
|
+
const renderings = this.flatRenderings(placeholders);
|
|
84
|
+
const actions = renderings.map((r) => __awaiter(this, void 0, void 0, function* () {
|
|
85
|
+
const fetchFunc = yield fetchFunctionFactory(r.componentName);
|
|
86
|
+
if (fetchFunc) {
|
|
87
|
+
params.requests &&
|
|
88
|
+
params.requests.push({
|
|
89
|
+
fetch: fetchFunc,
|
|
90
|
+
rendering: r,
|
|
91
|
+
layoutData: layoutData,
|
|
92
|
+
context,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
// If placeholders exist in current rendering
|
|
96
|
+
if (r.placeholders) {
|
|
97
|
+
yield this.collectRequests(Object.assign(Object.assign({}, params), { placeholders: r.placeholders }));
|
|
98
|
+
}
|
|
99
|
+
}));
|
|
100
|
+
yield Promise.all(actions);
|
|
101
|
+
return params.requests;
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Execute request for component props
|
|
106
|
+
* @param {ComponentPropsRequest<NextContext>[]} requests requests
|
|
107
|
+
* @returns {Promise<ComponentPropsCollection>} requests result
|
|
108
|
+
*/
|
|
109
|
+
execRequests(requests) {
|
|
110
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
111
|
+
const componentProps = {};
|
|
112
|
+
const promises = requests.map((req) => {
|
|
113
|
+
const { uid } = req.rendering;
|
|
114
|
+
if (!uid) {
|
|
115
|
+
console.log(`Component ${req.rendering.componentName} doesn't have uid, can't store data for this component`);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
return req
|
|
119
|
+
.fetch(req.rendering, req.layoutData, req.context)
|
|
120
|
+
.then((result) => {
|
|
121
|
+
// Set component specific data in componentProps store
|
|
122
|
+
componentProps[uid] = result;
|
|
123
|
+
})
|
|
124
|
+
.catch((error) => {
|
|
125
|
+
const errLog = `Error during preload data for component ${req.rendering.componentName} (${uid}): ${error.message || error}`;
|
|
126
|
+
console.error(chalk.red(errLog));
|
|
127
|
+
componentProps[uid] = {
|
|
128
|
+
error: error.message || errLog,
|
|
129
|
+
componentName: req.rendering.componentName,
|
|
130
|
+
};
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
yield Promise.all(promises);
|
|
134
|
+
return componentProps;
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Take renderings from all placeholders and returns a flat array of renderings.
|
|
139
|
+
* @example
|
|
140
|
+
* const placeholders = {
|
|
141
|
+
* x1: [{ uid: 1 }, { uid: 2 }],
|
|
142
|
+
* x2: [{ uid: 11 }, { uid: 22 }]
|
|
143
|
+
* }
|
|
144
|
+
*
|
|
145
|
+
* flatRenderings(placeholders);
|
|
146
|
+
*
|
|
147
|
+
* RESULT: [{ uid: 1 }, { uid: 2 }, { uid: 11 }, { uid: 22 }]
|
|
148
|
+
* @param {PlaceholdersData} placeholders placeholders
|
|
149
|
+
* @returns {ComponentRendering[]} renderings
|
|
150
|
+
*/
|
|
151
|
+
flatRenderings(placeholders) {
|
|
152
|
+
const allComponentRenderings = [];
|
|
153
|
+
const placeholdersArr = Object.values(placeholders);
|
|
154
|
+
placeholdersArr.forEach((pl) => {
|
|
155
|
+
const renderings = pl;
|
|
156
|
+
allComponentRenderings.push(...renderings);
|
|
157
|
+
});
|
|
158
|
+
return allComponentRenderings;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { BaseGraphQLSitemapService, } from './base-graphql-sitemap-service';
|
|
11
|
+
/** @private */
|
|
12
|
+
export const languageError = 'The list of languages cannot be empty';
|
|
13
|
+
export const siteError = 'The service needs a site name';
|
|
14
|
+
/**
|
|
15
|
+
* @param {string} siteName to inject into error text
|
|
16
|
+
* @private
|
|
17
|
+
*/
|
|
18
|
+
export function getSiteEmptyError(siteName) {
|
|
19
|
+
return `Site "${siteName}" does not exist or site item tree is missing`;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Service that fetches the list of site pages using Sitecore's GraphQL API.
|
|
23
|
+
* Used to handle a single site
|
|
24
|
+
* This list is used for SSG and Export functionality.
|
|
25
|
+
* @mixes SearchQueryService<PageListQueryResult>
|
|
26
|
+
*/
|
|
27
|
+
export class GraphQLSitemapService extends BaseGraphQLSitemapService {
|
|
28
|
+
/**
|
|
29
|
+
* Creates an instance of graphQL sitemap service with the provided options
|
|
30
|
+
* @param {GraphQLSitemapServiceConfig} options instance
|
|
31
|
+
*/
|
|
32
|
+
constructor(options) {
|
|
33
|
+
super(options);
|
|
34
|
+
this.options = options;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Fetch a flat list of all pages that belong to the specificed site and have a
|
|
38
|
+
* version in the specified language(s).
|
|
39
|
+
* @param {string[]} languages Fetch pages that have versions in this language(s).
|
|
40
|
+
* @param {Function} formatStaticPath Function for transforming the raw search results into (@see StaticPath) types.
|
|
41
|
+
* @returns list of pages
|
|
42
|
+
* @throws {RangeError} if the list of languages is empty.
|
|
43
|
+
* @throws {RangeError} if the any of the languages is an empty string.
|
|
44
|
+
*/
|
|
45
|
+
fetchSitemap(languages, formatStaticPath) {
|
|
46
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
47
|
+
const paths = new Array();
|
|
48
|
+
if (!languages.length) {
|
|
49
|
+
throw new RangeError(languageError);
|
|
50
|
+
}
|
|
51
|
+
const siteName = this.options.siteName;
|
|
52
|
+
if (!siteName) {
|
|
53
|
+
throw new RangeError(siteError);
|
|
54
|
+
}
|
|
55
|
+
paths.push(...(yield this.getTranformedPaths(siteName, languages, formatStaticPath)));
|
|
56
|
+
return [].concat(...paths);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { getSiteRewrite } from '@sitecore-content-sdk/core/site';
|
|
11
|
+
import { BaseGraphQLSitemapService, languageError, } from './base-graphql-sitemap-service';
|
|
12
|
+
export const sitesError = 'The list of sites cannot be empty';
|
|
13
|
+
/**
|
|
14
|
+
* Service that fetches the list of site pages using Sitecore's GraphQL API.
|
|
15
|
+
* Used to handle multiple sites
|
|
16
|
+
* This list is used for SSG and Export functionality.
|
|
17
|
+
* @mixes SearchQueryService<PageListQueryResult>
|
|
18
|
+
*/
|
|
19
|
+
export class MultisiteGraphQLSitemapService extends BaseGraphQLSitemapService {
|
|
20
|
+
/**
|
|
21
|
+
* Creates an instance of graphQL sitemap service with the provided options
|
|
22
|
+
* @param {MultisiteGraphQLSitemapServiceConfig} options instance
|
|
23
|
+
*/
|
|
24
|
+
constructor(options) {
|
|
25
|
+
super(options);
|
|
26
|
+
this.options = options;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Fetch a flat list of all pages that belong to all the requested sites and have a
|
|
30
|
+
* version in the specified language(s).
|
|
31
|
+
* @param {string[]} languages Fetch pages that have versions in this language(s).
|
|
32
|
+
* @param {Function} formatStaticPath Function for transforming the raw search results into (@see StaticPath) types.
|
|
33
|
+
* @returns list of pages
|
|
34
|
+
* @throws {RangeError} if the list of languages is empty.
|
|
35
|
+
* @throws {RangeError} if the any of the languages is an empty string.
|
|
36
|
+
*/
|
|
37
|
+
fetchSitemap(languages, formatStaticPath) {
|
|
38
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
39
|
+
const paths = new Array();
|
|
40
|
+
if (!languages.length) {
|
|
41
|
+
throw new RangeError(languageError);
|
|
42
|
+
}
|
|
43
|
+
// Get all sites
|
|
44
|
+
const sites = this.options.sites;
|
|
45
|
+
if (!sites || !sites.length) {
|
|
46
|
+
throw new RangeError(sitesError);
|
|
47
|
+
}
|
|
48
|
+
// Fetch paths for each site
|
|
49
|
+
for (let i = 0; i < sites.length; i++) {
|
|
50
|
+
const siteName = sites[i];
|
|
51
|
+
// Fetch paths using all locales
|
|
52
|
+
paths.push(...(yield this.getTranformedPaths(siteName, languages, formatStaticPath)));
|
|
53
|
+
}
|
|
54
|
+
return [].concat(...paths);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Fetch and return site paths for multisite implementation, with prefixes included
|
|
59
|
+
* @param {string} language path language
|
|
60
|
+
* @param {string} siteName site name
|
|
61
|
+
* @returns modified paths
|
|
62
|
+
*/
|
|
63
|
+
fetchLanguageSitePaths(language, siteName) {
|
|
64
|
+
const _super = Object.create(null, {
|
|
65
|
+
fetchLanguageSitePaths: { get: () => super.fetchLanguageSitePaths }
|
|
66
|
+
});
|
|
67
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
68
|
+
const results = yield _super.fetchLanguageSitePaths.call(this, language, siteName);
|
|
69
|
+
results.forEach((item) => {
|
|
70
|
+
if (item) {
|
|
71
|
+
item.path = getSiteRewrite(item.path, { siteName: siteName });
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
return results;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SiteResolver } from '@sitecore-content-sdk/core/site';
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { isEditorActive, resetEditorChromes } from '@sitecore-content-sdk/core/editing';
|
|
2
|
+
/**
|
|
3
|
+
* Since Sitecore editors do not support Fast Refresh:
|
|
4
|
+
* 1. Subscribe on events provided by webpack.
|
|
5
|
+
* 2. Reset editor chromes when build is finished
|
|
6
|
+
* @param {boolean} [forceReload] force page reload instead of reset chromes
|
|
7
|
+
*/
|
|
8
|
+
export const handleEditorFastRefresh = (forceReload = false) => {
|
|
9
|
+
if (process.env.NODE_ENV !== 'development' || !isEditorActive()) {
|
|
10
|
+
// Only run if development mode and editor is active
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const eventSource = new window.EventSource('/_next/webpack-hmr');
|
|
14
|
+
window.addEventListener('beforeunload', () => eventSource.close());
|
|
15
|
+
eventSource.onopen = () => console.log('[Sitecore Editor Fast Refresh Listener] Online');
|
|
16
|
+
eventSource.onmessage = (event) => {
|
|
17
|
+
if (event.data.indexOf('{') === -1)
|
|
18
|
+
return; // heartbeat
|
|
19
|
+
const payload = JSON.parse(event.data);
|
|
20
|
+
console.debug(`[Sitecore Editor Fast Refresh Listener] Saw event: ${JSON.stringify(payload)}`);
|
|
21
|
+
if (payload.action !== 'built')
|
|
22
|
+
return;
|
|
23
|
+
if (forceReload)
|
|
24
|
+
return window.location.reload();
|
|
25
|
+
setTimeout(() => {
|
|
26
|
+
console.log('[Sitecore Editor HMR Listener] Sitecore editor does not support Fast Refresh, reloading chromes...');
|
|
27
|
+
resetEditorChromes();
|
|
28
|
+
}, 500);
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
export const getJssEditingSecret = () => {
|
|
32
|
+
const secret = process.env.JSS_EDITING_SECRET;
|
|
33
|
+
if (!secret || secret.length === 0) {
|
|
34
|
+
throw new Error('The JSS_EDITING_SECRET environment variable is missing or invalid.');
|
|
35
|
+
}
|
|
36
|
+
return secret;
|
|
37
|
+
};
|
package/editing.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './types/editing/index';
|
package/editing.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./dist/cjs/editing/index');
|
package/global.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
declare module 'sync-disk-cache' {
|
|
2
|
+
export default import('sync-disk-cache').default;
|
|
3
|
+
|
|
4
|
+
export interface CacheInstance {
|
|
5
|
+
root: string;
|
|
6
|
+
set(key: string, editingData: string): string;
|
|
7
|
+
get(key: string): { value: string; isCached?: boolean };
|
|
8
|
+
remove(key: string): void;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
declare namespace NodeJS {
|
|
13
|
+
export interface Global {
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
requestAnimationFrame: (callback: () => void) => void;
|
|
16
|
+
window: Window;
|
|
17
|
+
document: Document;
|
|
18
|
+
navigator: Navigator;
|
|
19
|
+
HTMLElement: HTMLElement;
|
|
20
|
+
}
|
|
21
|
+
}
|
package/graphql.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './types/graphql/index';
|
package/graphql.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./dist/cjs/graphql/index');
|
package/middleware.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './types/middleware/index';
|
package/middleware.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./dist/cjs/middleware/index');
|
package/monitoring.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './types/monitoring/index';
|
package/monitoring.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./dist/cjs/monitoring/index');
|