@enonic/nextjs-adapter 3.0.0-B1 → 3.0.0-B3
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/baseMappings.js +3 -2
- package/baseMappings.js.map +1 -0
- package/client.d.ts +1 -0
- package/client.js +3 -0
- package/client.js.map +1 -0
- package/common/ComponentRegistry.d.ts +34 -0
- package/{ComponentRegistry.js → common/ComponentRegistry.js} +26 -26
- package/common/ComponentRegistry.js.map +1 -0
- package/{UrlProcessor.d.ts → common/UrlProcessor.d.ts} +2 -2
- package/{UrlProcessor.js → common/UrlProcessor.js} +16 -8
- package/common/UrlProcessor.js.map +1 -0
- package/common/constants.d.ts +50 -0
- package/common/constants.js +79 -0
- package/common/constants.js.map +1 -0
- package/common/env.d.ts +11 -0
- package/common/env.js +29 -0
- package/common/env.js.map +1 -0
- package/guillotine/applyProcessors.d.ts +2 -0
- package/guillotine/applyProcessors.js +33 -0
- package/guillotine/applyProcessors.js.map +1 -0
- package/guillotine/buildComponentTree.d.ts +2 -0
- package/guillotine/buildComponentTree.js +45 -0
- package/guillotine/buildComponentTree.js.map +1 -0
- package/guillotine/buildErrorResponse.d.ts +3 -0
- package/guillotine/buildErrorResponse.js +26 -0
- package/guillotine/buildErrorResponse.js.map +1 -0
- package/guillotine/buildPage.d.ts +2 -0
- package/guillotine/buildPage.js +10 -0
- package/guillotine/buildPage.js.map +1 -0
- package/guillotine/collectComponentDescriptors.d.ts +6 -0
- package/guillotine/collectComponentDescriptors.js +43 -0
- package/guillotine/collectComponentDescriptors.js.map +1 -0
- package/guillotine/combineMultipleQueries.d.ts +2 -0
- package/guillotine/combineMultipleQueries.js +58 -0
- package/guillotine/combineMultipleQueries.js.map +1 -0
- package/guillotine/createMetaData.d.ts +17 -0
- package/guillotine/createMetaData.js +44 -0
- package/guillotine/createMetaData.js.map +1 -0
- package/guillotine/fetchContent.d.ts +2 -40
- package/guillotine/fetchContent.js +65 -676
- package/guillotine/fetchContent.js.map +1 -0
- package/guillotine/fetchContentData.d.ts +2 -0
- package/guillotine/fetchContentData.js +27 -0
- package/guillotine/fetchContentData.js.map +1 -0
- package/guillotine/fetchContentPathsForAllLocales.d.ts +2 -0
- package/guillotine/fetchContentPathsForAllLocales.js +21 -0
- package/guillotine/fetchContentPathsForAllLocales.js.map +1 -0
- package/guillotine/fetchContentPathsForLocale.d.ts +2 -0
- package/guillotine/fetchContentPathsForLocale.js +40 -0
- package/guillotine/fetchContentPathsForLocale.js.map +1 -0
- package/guillotine/fetchFromApi.d.ts +3 -0
- package/guillotine/fetchFromApi.js +67 -0
- package/guillotine/fetchFromApi.js.map +1 -0
- package/guillotine/fetchGuillotine.d.ts +3 -0
- package/guillotine/fetchGuillotine.js +57 -0
- package/guillotine/fetchGuillotine.js.map +1 -0
- package/guillotine/fetchMetaData.d.ts +2 -0
- package/guillotine/fetchMetaData.js +30 -0
- package/guillotine/fetchMetaData.js.map +1 -0
- package/guillotine/getCleanContentPathArrayOrThrow400.d.ts +2 -0
- package/guillotine/getCleanContentPathArrayOrThrow400.js +20 -0
- package/guillotine/getCleanContentPathArrayOrThrow400.js.map +1 -0
- package/guillotine/getComponentConfig.d.ts +2 -0
- package/guillotine/getComponentConfig.js +5 -0
- package/guillotine/getComponentConfig.js.map +1 -0
- package/guillotine/getContentAndComponentPaths.d.ts +1 -0
- package/guillotine/getContentAndComponentPaths.js +12 -0
- package/guillotine/getContentAndComponentPaths.js.map +1 -0
- package/guillotine/getMetaData.d.ts +0 -92
- package/guillotine/getMetaData.js +47 -109
- package/guillotine/getMetaData.js.map +1 -0
- package/guillotine/getParentRegion.d.ts +2 -0
- package/guillotine/getParentRegion.js +40 -0
- package/guillotine/getParentRegion.js.map +1 -0
- package/guillotine/getQueryAndVariables.d.ts +2 -0
- package/guillotine/getQueryAndVariables.js +32 -0
- package/guillotine/getQueryAndVariables.js.map +1 -0
- package/guillotine/metadata/configQuery.d.ts +2 -0
- package/guillotine/metadata/configQuery.js +36 -0
- package/guillotine/metadata/configQuery.js.map +1 -0
- package/guillotine/metadata/richTextQuery.d.ts +1 -0
- package/guillotine/metadata/richTextQuery.js +32 -0
- package/guillotine/metadata/richTextQuery.js.map +1 -0
- package/guillotine/parseComponentPath.d.ts +2 -0
- package/guillotine/parseComponentPath.js +22 -0
- package/guillotine/parseComponentPath.js.map +1 -0
- package/guillotine/prefixLayoutPath.d.ts +1 -0
- package/guillotine/prefixLayoutPath.js +13 -0
- package/guillotine/prefixLayoutPath.js.map +1 -0
- package/guillotine/processComponentConfig.d.ts +2 -0
- package/guillotine/processComponentConfig.js +30 -0
- package/guillotine/processComponentConfig.js.map +1 -0
- package/guillotine/restrictComponentsToPath.d.ts +2 -0
- package/guillotine/restrictComponentsToPath.js +35 -0
- package/guillotine/restrictComponentsToPath.js.map +1 -0
- package/guillotine/validateData.d.ts +2 -0
- package/guillotine/validateData.js +7 -0
- package/guillotine/validateData.js.map +1 -0
- package/guillotine/validateNotFound.d.ts +2 -0
- package/guillotine/validateNotFound.js +16 -0
- package/guillotine/validateNotFound.js.map +1 -0
- package/guillotine/validateShortcut.d.ts +2 -0
- package/guillotine/validateShortcut.js +29 -0
- package/guillotine/validateShortcut.js.map +1 -0
- package/i18n/LocaleContext.d.ts +2 -8
- package/i18n/LocaleContext.jsx +17 -13
- package/i18n/LocaleContext.jsx.map +1 -0
- package/i18n/i18n.d.ts +1 -3
- package/i18n/i18n.js +2 -1
- package/i18n/i18n.js.map +1 -0
- package/index.d.ts +14 -7
- package/index.js +14 -7
- package/index.js.map +1 -0
- package/package.json +63 -15
- package/query/Shortcut.js +1 -0
- package/query/Shortcut.js.map +1 -0
- package/server.d.ts +5 -0
- package/server.js.map +1 -0
- package/types/component.d.ts +114 -0
- package/types/component.js +2 -0
- package/types/component.js.map +1 -0
- package/types/componentProps.d.ts +104 -0
- package/types/componentProps.js +2 -0
- package/types/componentProps.js.map +1 -0
- package/types/guillotine.d.ts +342 -0
- package/types/guillotine.js +2 -0
- package/types/guillotine.js.map +1 -0
- package/types/i18n.d.ts +7 -0
- package/types/i18n.js +2 -0
- package/types/i18n.js.map +1 -0
- package/types/index.d.ts +45 -0
- package/types/index.js +3 -0
- package/types/index.js.map +1 -0
- package/types/next.d.ts +6 -0
- package/types/next.js +2 -0
- package/types/next.js.map +1 -0
- package/types/util.d.ts +3 -0
- package/types/util.js +3 -0
- package/types/util.js.map +1 -0
- package/utils/addLineNumbers.d.ts +1 -0
- package/utils/addLineNumbers.js +4 -0
- package/utils/addLineNumbers.js.map +1 -0
- package/utils/buildGuillotineRequestHeaders.d.ts +7 -0
- package/utils/buildGuillotineRequestHeaders.js +16 -0
- package/utils/buildGuillotineRequestHeaders.js.map +1 -0
- package/utils/commonChars.d.ts +1 -0
- package/utils/commonChars.js +17 -0
- package/utils/commonChars.js.map +1 -0
- package/utils/fixDoubleSlashes.d.ts +1 -0
- package/utils/fixDoubleSlashes.js +4 -0
- package/utils/fixDoubleSlashes.js.map +1 -0
- package/utils/getContentApiUrl.d.ts +2 -0
- package/utils/getContentApiUrl.js +15 -0
- package/utils/getContentApiUrl.js.map +1 -0
- package/utils/getProjectLocaleConfig.d.ts +2 -0
- package/utils/getProjectLocaleConfig.js +19 -0
- package/utils/getProjectLocaleConfig.js.map +1 -0
- package/utils/getProjectLocaleConfigById.d.ts +2 -0
- package/utils/getProjectLocaleConfigById.js +16 -0
- package/utils/getProjectLocaleConfigById.js.map +1 -0
- package/utils/getProjectLocaleConfigByLocale.d.ts +2 -0
- package/utils/getProjectLocaleConfigByLocale.js +13 -0
- package/utils/getProjectLocaleConfigByLocale.js.map +1 -0
- package/utils/getProjectLocaleConfigs.d.ts +2 -0
- package/utils/getProjectLocaleConfigs.js +30 -0
- package/utils/getProjectLocaleConfigs.js.map +1 -0
- package/utils/getProjectLocales.d.ts +1 -0
- package/utils/getProjectLocales.js +5 -0
- package/utils/getProjectLocales.js.map +1 -0
- package/utils/getRenderMode.d.ts +3 -0
- package/utils/getRenderMode.js +8 -0
- package/utils/getRenderMode.js.map +1 -0
- package/utils/getRequestLocaleInfo.d.ts +6 -0
- package/utils/getRequestLocaleInfo.js +26 -0
- package/utils/getRequestLocaleInfo.js.map +1 -0
- package/utils/getXpBaseUrl.d.ts +2 -0
- package/utils/getXpBaseUrl.js +8 -0
- package/utils/getXpBaseUrl.js.map +1 -0
- package/utils/indent.d.ts +1 -0
- package/utils/indent.js +5 -0
- package/utils/indent.js.map +1 -0
- package/utils/sanitizeGraphqlName.d.ts +1 -0
- package/utils/sanitizeGraphqlName.js +12 -0
- package/utils/sanitizeGraphqlName.js.map +1 -0
- package/views/BaseComponent.d.ts +6 -11
- package/views/BaseComponent.jsx +18 -21
- package/views/BaseComponent.jsx.map +1 -0
- package/views/BaseContent.d.ts +3 -3
- package/views/BaseContent.jsx +2 -5
- package/views/BaseContent.jsx.map +1 -0
- package/views/BaseLayout.d.ts +3 -16
- package/views/BaseLayout.jsx +3 -3
- package/views/BaseLayout.jsx.map +1 -0
- package/views/BaseMacro.d.ts +3 -13
- package/views/BaseMacro.jsx +4 -3
- package/views/BaseMacro.jsx.map +1 -0
- package/views/BasePage.d.ts +3 -18
- package/views/BasePage.jsx +3 -3
- package/views/BasePage.jsx.map +1 -0
- package/views/BasePart.d.ts +3 -18
- package/views/BasePart.jsx +3 -3
- package/views/BasePart.jsx.map +1 -0
- package/views/Empty.d.ts +2 -2
- package/views/Empty.jsx +2 -1
- package/views/Empty.jsx.map +1 -0
- package/views/Fragment.d.ts +3 -9
- package/views/Fragment.jsx +2 -2
- package/views/Fragment.jsx.map +1 -0
- package/views/MainView.d.ts +3 -3
- package/views/MainView.jsx +2 -2
- package/views/MainView.jsx.map +1 -0
- package/views/PropsView.d.ts +3 -0
- package/views/PropsView.jsx +21 -0
- package/views/PropsView.jsx.map +1 -0
- package/views/Region.d.ts +4 -17
- package/views/Region.jsx +2 -2
- package/views/Region.jsx.map +1 -0
- package/views/RichTextView.d.ts +3 -13
- package/views/RichTextView.jsx +2 -2
- package/views/RichTextView.jsx.map +1 -0
- package/views/SingleComponent.d.ts +3 -3
- package/views/SingleComponent.jsx +1 -2
- package/views/SingleComponent.jsx.map +1 -0
- package/views/StaticContent.d.ts +2 -6
- package/views/StaticContent.jsx +1 -0
- package/views/StaticContent.jsx.map +1 -0
- package/views/Text.d.ts +5 -5
- package/views/Text.jsx +1 -1
- package/views/Text.jsx.map +1 -0
- package/views/getClientHydratedHtml.d.ts +2 -0
- package/views/getClientHydratedHtml.jsx +9 -0
- package/views/getClientHydratedHtml.jsx.map +1 -0
- package/views/macros/DefaultMacro.d.ts +1 -1
- package/views/macros/DefaultMacro.jsx +1 -0
- package/views/macros/DefaultMacro.jsx.map +1 -0
- package/views/macros/DisableMacro.d.ts +1 -1
- package/views/macros/DisableMacro.jsx +1 -0
- package/views/macros/DisableMacro.jsx.map +1 -0
- package/ComponentRegistry.d.ts +0 -64
- package/utils.d.ts +0 -111
- package/utils.js +0 -255
|
@@ -7,600 +7,59 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { getMetaQuery, pageFragmentQuery } from './getMetaData';
|
|
11
|
-
import adapterConstants, { addJsessionHeaders, addLocaleHeaders, APP_NAME, APP_NAME_DASHED, FRAGMENT_CONTENTTYPE_NAME, FRAGMENT_DEFAULT_REGION_NAME, GET_STATIC_PATHS_QUERY, getContentApiUrl, getProjectLocaleConfig, getProjectLocaleConfigs, getRenderMode, getRequestLocaleInfo, getXpBaseUrl, IS_DEV_MODE, PAGE_TEMPLATE_CONTENTTYPE_NAME, PAGE_TEMPLATE_FOLDER, RENDER_MODE, sanitizeGraphqlName, XP_COMPONENT_TYPE, XP_REQUEST_TYPE, } from '../utils';
|
|
12
|
-
import { ComponentRegistry } from '../ComponentRegistry';
|
|
13
|
-
import { UrlProcessor } from '../UrlProcessor';
|
|
14
|
-
import { notFound, redirect, RedirectType } from 'next/navigation';
|
|
15
10
|
import { headers } from 'next/headers';
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
console.warn(apiUrl, e);
|
|
40
|
-
throw new Error(JSON.stringify({
|
|
41
|
-
code: 'API',
|
|
42
|
-
message: e.message,
|
|
43
|
-
}));
|
|
44
|
-
}
|
|
45
|
-
if (!res.ok) {
|
|
46
|
-
throw new Error(JSON.stringify({
|
|
47
|
-
code: res.status,
|
|
48
|
-
message: `Data fetching failed (message: '${yield res.text()}')`,
|
|
49
|
-
}));
|
|
50
|
-
}
|
|
51
|
-
let json;
|
|
52
|
-
try {
|
|
53
|
-
json = yield res.json();
|
|
54
|
-
}
|
|
55
|
-
catch (e) {
|
|
56
|
-
throw new Error(JSON.stringify({
|
|
57
|
-
code: 500,
|
|
58
|
-
message: `API call completed but with non-JSON data: ${JSON.stringify(yield res.text())}`,
|
|
59
|
-
}));
|
|
60
|
-
}
|
|
61
|
-
if (!json) {
|
|
62
|
-
throw new Error(JSON.stringify({
|
|
63
|
-
code: 500,
|
|
64
|
-
message: `API call completed but with unexpectedly empty data: ${JSON.stringify(yield res.text())}`,
|
|
65
|
-
}));
|
|
66
|
-
}
|
|
67
|
-
return json;
|
|
68
|
-
});
|
|
69
|
-
/** Guillotine-specialized fetch, using the generic fetch above */
|
|
70
|
-
export const fetchGuillotine = (contentApiUrl, body, projectConfig, headers) => __awaiter(void 0, void 0, void 0, function* () {
|
|
71
|
-
var _b;
|
|
72
|
-
if (typeof body.query !== 'string' || !body.query.trim()) {
|
|
73
|
-
return {
|
|
74
|
-
error: {
|
|
75
|
-
code: '400',
|
|
76
|
-
message: `Invalid or missing query. JSON.stringify(query) = ${JSON.stringify(body.query)}`,
|
|
77
|
-
},
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
const path = (_b = body.variables) === null || _b === void 0 ? void 0 : _b.path;
|
|
81
|
-
const pathMessage = path ? JSON.stringify(path) : '';
|
|
82
|
-
const result = yield fetchFromApi(contentApiUrl, body, projectConfig, headers)
|
|
83
|
-
.then(json => {
|
|
84
|
-
let errors = (json || {}).errors;
|
|
85
|
-
if (errors) {
|
|
86
|
-
if (!Array.isArray(errors)) {
|
|
87
|
-
errors = [errors];
|
|
88
|
-
}
|
|
89
|
-
console.error(`${errors.length} error(s) when fetching data from: ${contentApiUrl}`);
|
|
90
|
-
console.error(`headers: ${JSON.stringify(headers, null, 2)} \nvariables: ${JSON.stringify(body.variables, null, 2)}`);
|
|
91
|
-
errors.forEach(error => {
|
|
92
|
-
console.error(error);
|
|
93
|
-
});
|
|
94
|
-
return {
|
|
95
|
-
error: {
|
|
96
|
-
code: '500',
|
|
97
|
-
message: `Server responded with ${errors.length} error(s), probably from guillotine - see log.`,
|
|
98
|
-
},
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
return json.data;
|
|
102
|
-
})
|
|
103
|
-
.catch((err) => {
|
|
104
|
-
console.warn(`Client-side error when trying to fetch data ${pathMessage}`, err);
|
|
105
|
-
try {
|
|
106
|
-
return { error: JSON.parse(err.message) };
|
|
107
|
-
}
|
|
108
|
-
catch (e2) {
|
|
109
|
-
return { error: { code: 'Client-side error', message: err.message } };
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
return result;
|
|
113
|
-
});
|
|
114
|
-
// /////////////////////////////////////////////////////////////////////////////// Specific fetch wrappers:
|
|
115
|
-
const fetchMetaData = (contentApiUrl, xpContentPath, projectConfig, headers) => __awaiter(void 0, void 0, void 0, function* () {
|
|
116
|
-
var _c;
|
|
117
|
-
const body = {
|
|
118
|
-
query: getMetaQuery(pageFragmentQuery()),
|
|
119
|
-
variables: {
|
|
120
|
-
path: xpContentPath,
|
|
121
|
-
},
|
|
122
|
-
};
|
|
123
|
-
const metaResult = yield fetchGuillotine(contentApiUrl, body, projectConfig, headers);
|
|
124
|
-
if (metaResult.error) {
|
|
125
|
-
return metaResult;
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
return {
|
|
129
|
-
meta: (_c = metaResult === null || metaResult === void 0 ? void 0 : metaResult.guillotine) === null || _c === void 0 ? void 0 : _c.get,
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
const fetchContentData = (contentApiUrl, xpContentPath, projectConfig, query, variables, headers) => __awaiter(void 0, void 0, void 0, function* () {
|
|
134
|
-
const body = { query };
|
|
135
|
-
if (variables && Object.keys(variables).length > 0) {
|
|
136
|
-
body.variables = variables;
|
|
137
|
-
}
|
|
138
|
-
const contentResults = yield fetchGuillotine(contentApiUrl, body, projectConfig, headers);
|
|
139
|
-
if (contentResults.error) {
|
|
140
|
-
return contentResults;
|
|
141
|
-
}
|
|
142
|
-
else {
|
|
143
|
-
return {
|
|
144
|
-
// omit the aliases and return values
|
|
145
|
-
contents: Object.values(contentResults),
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
});
|
|
149
|
-
// /////////////////////////////////////////////////////////////////////////////// Error checking:
|
|
150
|
-
/** Checks a site-relative contentPath as a slash-delimited string or a string array, and returns a pure site-relative path string (no double slashes, starts with a slash, does not end with one). */
|
|
151
|
-
const getCleanContentPathArrayOrThrow400 = (contentPath) => {
|
|
152
|
-
if (contentPath === undefined) {
|
|
153
|
-
return '';
|
|
154
|
-
}
|
|
155
|
-
const isArray = Array.isArray(contentPath);
|
|
156
|
-
if (!isArray) {
|
|
157
|
-
if (typeof contentPath !== 'string') {
|
|
158
|
-
throw Error(JSON.stringify({
|
|
159
|
-
code: 400,
|
|
160
|
-
message: `Unexpected target content _path: contentPath must be a string or pure string array (contentPath=${JSON.stringify(contentPath)})`,
|
|
161
|
-
}));
|
|
162
|
-
}
|
|
163
|
-
return contentPath;
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
return (contentPath).join('/');
|
|
167
|
-
}
|
|
168
|
-
};
|
|
169
|
-
function parseComponentPath(contentType, path) {
|
|
170
|
-
const matches = [];
|
|
171
|
-
let match;
|
|
172
|
-
const myRegexp = /(?:(\w+)\/(\d+))+/g;
|
|
173
|
-
while ((match = myRegexp.exec(path)) !== null) {
|
|
174
|
-
matches.push({
|
|
175
|
-
region: match[1],
|
|
176
|
-
index: +match[2],
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
if (contentType === FRAGMENT_CONTENTTYPE_NAME) {
|
|
180
|
-
// there is no main region in fragment content and the root component has '/' path
|
|
181
|
-
// prepend FRAGMENT_DEFAULT_REGION_NAME to path to conform to page structure
|
|
182
|
-
matches.unshift({
|
|
183
|
-
region: FRAGMENT_DEFAULT_REGION_NAME,
|
|
184
|
-
index: 0,
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
return matches;
|
|
188
|
-
}
|
|
189
|
-
function getParentRegion(source, contentType, cmpPath, components = [], createMissing) {
|
|
190
|
-
let currentTree = source;
|
|
191
|
-
let currentRegion;
|
|
192
|
-
let parentPath = '';
|
|
193
|
-
for (let i = 0; i < cmpPath.length; i++) {
|
|
194
|
-
const pathFragment = cmpPath[i];
|
|
195
|
-
const regionName = pathFragment.region;
|
|
196
|
-
parentPath += `/${pathFragment.region}/${pathFragment.index}`;
|
|
197
|
-
currentRegion = currentTree[regionName];
|
|
198
|
-
if (!currentRegion) {
|
|
199
|
-
if (createMissing) {
|
|
200
|
-
currentRegion = {
|
|
201
|
-
name: regionName,
|
|
202
|
-
components: [],
|
|
203
|
-
};
|
|
204
|
-
currentTree[regionName] = currentRegion;
|
|
205
|
-
}
|
|
206
|
-
else {
|
|
207
|
-
throw `Region [${regionName}] was not found`;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
if (i < cmpPath.length - 1) {
|
|
211
|
-
// look for layouts inside if this is not the last path fragment
|
|
212
|
-
const layout = components.find((cmp) => {
|
|
213
|
-
return cmp.type === XP_COMPONENT_TYPE.LAYOUT && prefixLayoutPath(contentType, cmp.path) === parentPath;
|
|
214
|
-
});
|
|
215
|
-
if (!layout) {
|
|
216
|
-
throw `Layout [${parentPath}] not found among components, but needed for component [${JSON.stringify(cmpPath, null, 2)}]`;
|
|
217
|
-
}
|
|
218
|
-
if (!layout.regions) {
|
|
219
|
-
layout.regions = {};
|
|
220
|
-
}
|
|
221
|
-
currentTree = layout.regions;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
return currentRegion;
|
|
225
|
-
}
|
|
226
|
-
function prefixLayoutPath(contentType, path) {
|
|
227
|
-
if (contentType !== FRAGMENT_CONTENTTYPE_NAME) {
|
|
228
|
-
return path;
|
|
229
|
-
}
|
|
230
|
-
else {
|
|
231
|
-
// prepend FRAGMENT_DEFAULT_REGION_NAME to path to conform to page structure
|
|
232
|
-
// so that component with path '/' becomes /FRAGMENT_DEFAULT_REGION_NAME/0
|
|
233
|
-
// path /left/1 becomes /FRAGMENT_DEFAULT_REGION_NAME/0/left/1
|
|
234
|
-
return `/${FRAGMENT_DEFAULT_REGION_NAME}/0${path === '/' ? '' : path}`;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
function buildPage(contentType, comps = []) {
|
|
238
|
-
const page = {
|
|
239
|
-
type: XP_COMPONENT_TYPE.PAGE,
|
|
240
|
-
path: '/',
|
|
241
|
-
};
|
|
242
|
-
return buildComponentTree(comps, page, contentType);
|
|
243
|
-
}
|
|
244
|
-
function buildComponentTree(comps, rootComp, contentType) {
|
|
245
|
-
const rootTree = {};
|
|
246
|
-
const isFragmentType = contentType === FRAGMENT_CONTENTTYPE_NAME;
|
|
247
|
-
if (isFragmentType) {
|
|
248
|
-
rootComp.regions = rootTree;
|
|
249
|
-
}
|
|
250
|
-
(comps || []).forEach(cmp => {
|
|
251
|
-
var _a, _b, _c;
|
|
252
|
-
const cmpPath = parseComponentPath(contentType, cmp.path);
|
|
253
|
-
if (cmp.path === '/') {
|
|
254
|
-
if (cmp.type === XP_COMPONENT_TYPE.PAGE && rootComp.type === XP_COMPONENT_TYPE.PAGE) {
|
|
255
|
-
// add page values to page object
|
|
256
|
-
rootComp = Object.assign(rootComp, cmp);
|
|
257
|
-
rootComp.page.regions = rootTree;
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
260
|
-
else if (cmp.type === XP_COMPONENT_TYPE.LAYOUT && rootComp.type === XP_COMPONENT_TYPE.FRAGMENT) {
|
|
261
|
-
// when rendering fragment as part of the page with layout at root path
|
|
262
|
-
// remove other children from list as they will be included in layout
|
|
263
|
-
rootComp.fragment.fragment.components = [cmp];
|
|
264
|
-
cmp.regions = rootTree;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
if (cmp.type === XP_COMPONENT_TYPE.FRAGMENT) {
|
|
268
|
-
// build component subtree for fragment
|
|
269
|
-
cmp = buildComponentTree((_b = (_a = cmp.fragment) === null || _a === void 0 ? void 0 : _a.fragment) === null || _b === void 0 ? void 0 : _b.components, cmp, contentType);
|
|
270
|
-
}
|
|
271
|
-
const region = getParentRegion(rootTree, contentType, cmpPath, comps, true);
|
|
272
|
-
if (region) {
|
|
273
|
-
// getting the index of component from string like '/main/0/left/11'
|
|
274
|
-
const cmpIndex = (_c = cmpPath[cmpPath.length - 1]) === null || _c === void 0 ? void 0 : _c.index;
|
|
275
|
-
if (cmpIndex >= 0) {
|
|
276
|
-
region.components.splice(cmpIndex, 0, cmp);
|
|
277
|
-
}
|
|
278
|
-
else {
|
|
279
|
-
throw Error(`Could not find [${cmp.type}] component index at ${JSON.stringify(cmpPath, null, 2)}, rendering not possible.`);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
});
|
|
283
|
-
return rootComp;
|
|
284
|
-
}
|
|
285
|
-
function combineMultipleQueries(queriesWithVars) {
|
|
286
|
-
const queries = [];
|
|
287
|
-
const fragments = [];
|
|
288
|
-
const superVars = {};
|
|
289
|
-
const superParams = [];
|
|
290
|
-
queriesWithVars.forEach((componentDescriptor, index) => {
|
|
291
|
-
const queryAndVars = componentDescriptor.queryAndVariables;
|
|
292
|
-
if (!queryAndVars) {
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
295
|
-
// Extract fragments first if exist
|
|
296
|
-
let q = queryAndVars.query;
|
|
297
|
-
let match = q.match(GRAPHQL_FRAGMENTS_REGEXP);
|
|
298
|
-
if ((match === null || match === void 0 ? void 0 : match.length) === 1) {
|
|
299
|
-
// extract a fragment to put it at root level
|
|
300
|
-
fragments.push(match[0]);
|
|
301
|
-
// remove it from query because queries are going to get wrapped
|
|
302
|
-
q = q.replace(match[0], '');
|
|
303
|
-
}
|
|
304
|
-
// Extract graphql query and its params and add prefixes to exclude collisions with other queries
|
|
305
|
-
match = q.match(GUILLOTINE_QUERY_REGEXP);
|
|
306
|
-
let query = '';
|
|
307
|
-
if (match && match.length === 2) {
|
|
308
|
-
// no params, just query
|
|
309
|
-
query = match[1];
|
|
310
|
-
}
|
|
311
|
-
else if (match && match.length === 3) {
|
|
312
|
-
// both query and params are present
|
|
313
|
-
query = match[2];
|
|
314
|
-
// process args
|
|
315
|
-
const args = match[1];
|
|
316
|
-
if (args) {
|
|
317
|
-
args.split(',').forEach(originalParamString => {
|
|
318
|
-
const [originalKey, originalVal] = originalParamString.trim().split(':');
|
|
319
|
-
const [prefixedKey, prefixedVal] = [`$${ALIAS_PREFIX}${index}_${originalKey.substr(1)}`, originalVal];
|
|
320
|
-
superParams.push(`${prefixedKey}:${prefixedVal}`);
|
|
321
|
-
// also update param references in query itself !
|
|
322
|
-
// query = query.replaceAll(originalKey, prefixedKey);
|
|
323
|
-
// replaceAll is not supported in older nodejs versions
|
|
324
|
-
const origKeyPattern = new RegExp(originalKey.replace(/\$/g, '\\$'), 'g');
|
|
325
|
-
query = query.replace(origKeyPattern, prefixedKey);
|
|
326
|
-
});
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
if (query.length) {
|
|
330
|
-
queries.push(`${ALIAS_PREFIX}${index}:guillotine {${query}}`);
|
|
331
|
-
}
|
|
332
|
-
// Update variables with the same prefixes
|
|
333
|
-
Object.entries(queryAndVars.variables || {}).forEach(entry => {
|
|
334
|
-
superVars[`${ALIAS_PREFIX}${index}_${entry[0]}`] = entry[1];
|
|
335
|
-
});
|
|
336
|
-
});
|
|
337
|
-
// Compose the super query
|
|
338
|
-
const superQuery = `query ${superParams.length ? `(${superParams.join(', ')})` : ''} {
|
|
339
|
-
${queries.join('\n')}
|
|
340
|
-
}
|
|
341
|
-
${fragments.join('\n')}
|
|
342
|
-
`;
|
|
343
|
-
return {
|
|
344
|
-
query: superQuery,
|
|
345
|
-
variables: superVars,
|
|
346
|
-
};
|
|
347
|
-
}
|
|
348
|
-
function applyProcessors(componentDescriptors, contentResults, context) {
|
|
349
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
350
|
-
let dataCounter = 0;
|
|
351
|
-
const processorPromises = componentDescriptors.map((desc) => __awaiter(this, void 0, void 0, function* () {
|
|
352
|
-
var _a;
|
|
353
|
-
// we're iterating component descriptors here
|
|
354
|
-
// some of them might not have provided graphql requests
|
|
355
|
-
// but we still need to run props processor for them
|
|
356
|
-
// in case they want to fetch their data from elsewhere
|
|
357
|
-
const propsProcessor = ((_a = desc.type) === null || _a === void 0 ? void 0 : _a.processor) || NO_PROPS_PROCESSOR;
|
|
358
|
-
let data;
|
|
359
|
-
if (desc.queryAndVariables) {
|
|
360
|
-
// if there is a query then there must be a result for it
|
|
361
|
-
data = contentResults.contents[dataCounter++];
|
|
362
|
-
}
|
|
363
|
-
const config = getComponentConfig(desc.component);
|
|
364
|
-
return yield propsProcessor(data, context, config);
|
|
365
|
-
}));
|
|
366
|
-
return Promise.allSettled(processorPromises);
|
|
367
|
-
});
|
|
368
|
-
}
|
|
369
|
-
function getComponentConfig(cmp) {
|
|
370
|
-
const cmpData = cmp && cmp[cmp.type];
|
|
371
|
-
return cmpData && 'config' in cmpData ? cmpData.config : undefined;
|
|
372
|
-
}
|
|
373
|
-
function collectComponentDescriptors(components, componentRegistry, xpContentPath, context) {
|
|
374
|
-
var _a, _b;
|
|
375
|
-
const descriptors = [];
|
|
376
|
-
for (const cmp of (components || [])) {
|
|
377
|
-
processComponentConfig(APP_NAME, APP_NAME_DASHED, cmp);
|
|
378
|
-
// only look for parts
|
|
379
|
-
// look for single part if it is a single component request
|
|
380
|
-
if (XP_COMPONENT_TYPE.FRAGMENT !== cmp.type) {
|
|
381
|
-
const cmpDef = ComponentRegistry.getByComponent(cmp);
|
|
382
|
-
if (cmpDef) {
|
|
383
|
-
// const partPath = `${xpContentPath}/_component${cmp.path}`;
|
|
384
|
-
const config = getComponentConfig(cmp);
|
|
385
|
-
const queryAndVariables = getQueryAndVariables(cmp.type, xpContentPath, context, cmpDef.query, config);
|
|
386
|
-
if (queryAndVariables) {
|
|
387
|
-
descriptors.push({
|
|
388
|
-
component: cmp,
|
|
389
|
-
type: cmpDef,
|
|
390
|
-
queryAndVariables: queryAndVariables,
|
|
391
|
-
});
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
else {
|
|
396
|
-
// look for parts inside fragments
|
|
397
|
-
const fragPartDescs = collectComponentDescriptors((_b = (_a = cmp.fragment) === null || _a === void 0 ? void 0 : _a.fragment) === null || _b === void 0 ? void 0 : _b.components, componentRegistry, xpContentPath, context);
|
|
398
|
-
if (fragPartDescs.length) {
|
|
399
|
-
descriptors.push(...fragPartDescs);
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
return descriptors;
|
|
404
|
-
}
|
|
405
|
-
function processComponentConfig(myAppName, myAppNameDashed, cmp) {
|
|
406
|
-
const cmpData = cmp[cmp.type];
|
|
407
|
-
if (cmpData && 'descriptor' in cmpData && cmpData.descriptor) {
|
|
408
|
-
const [appName, cmpName] = cmpData.descriptor.split(':');
|
|
409
|
-
if (appName !== myAppName) {
|
|
410
|
-
return;
|
|
411
|
-
}
|
|
412
|
-
let config;
|
|
413
|
-
const configArray = [];
|
|
414
|
-
if ('configAsJson' in cmpData && cmpData.configAsJson && cmpData.configAsJson[myAppNameDashed]) {
|
|
415
|
-
config = cmpData.configAsJson[myAppNameDashed][cmpName];
|
|
416
|
-
if (config) {
|
|
417
|
-
configArray.push(config);
|
|
418
|
-
delete cmpData.configAsJson;
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
const sanitizedAppName = sanitizeGraphqlName(appName);
|
|
422
|
-
if ('config' in cmpData && cmpData.config && cmpData.config[sanitizedAppName]) {
|
|
423
|
-
config = cmpData.config[sanitizedAppName][sanitizeGraphqlName(cmpName)];
|
|
424
|
-
if (config) {
|
|
425
|
-
configArray.push(config);
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
if (configArray.length) {
|
|
429
|
-
cmpData.config = Object.assign({}, ...configArray);
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
function getQueryAndVariables(type, path, context, selectedQuery, config) {
|
|
434
|
-
let query, getVariables;
|
|
435
|
-
if (typeof selectedQuery === 'string' || typeof selectedQuery === 'function') {
|
|
436
|
-
query = selectedQuery;
|
|
437
|
-
}
|
|
438
|
-
else if (Array.isArray(selectedQuery)) {
|
|
439
|
-
query = selectedQuery[0];
|
|
440
|
-
getVariables = selectedQuery[1];
|
|
441
|
-
}
|
|
442
|
-
else if (typeof selectedQuery === 'object') {
|
|
443
|
-
query = selectedQuery.query;
|
|
444
|
-
getVariables = selectedQuery.variables;
|
|
445
|
-
}
|
|
446
|
-
if (getVariables && typeof getVariables !== 'function') {
|
|
447
|
-
throw Error(`getVariables for content type ${type} should be a function, not: ${typeof getVariables}`);
|
|
448
|
-
}
|
|
449
|
-
if (query && typeof query !== 'string' && typeof query !== 'function') {
|
|
450
|
-
throw Error(`Query for content type ${type} should be a string or function, not: ${typeof query}`);
|
|
451
|
-
}
|
|
452
|
-
if (typeof query === 'function') {
|
|
453
|
-
query = query(path, context, config);
|
|
454
|
-
}
|
|
455
|
-
if (query) {
|
|
456
|
-
return {
|
|
457
|
-
query,
|
|
458
|
-
variables: getVariables ? getVariables(path, context, config) : { path },
|
|
459
|
-
};
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
function createPageData(contentType, components, componentPath) {
|
|
463
|
-
let page;
|
|
464
|
-
if (components && !componentPath) {
|
|
465
|
-
page = buildPage(contentType, components);
|
|
466
|
-
}
|
|
467
|
-
else {
|
|
468
|
-
// Don't build page for single component
|
|
469
|
-
page = null;
|
|
470
|
-
}
|
|
471
|
-
return page;
|
|
472
|
-
}
|
|
473
|
-
function createMetaData(contentType, contentPath, requestType, renderMode, apiUrl, baseUrl, locale, defaultLocale, requestedComponentPath, pageCmp, components = []) {
|
|
474
|
-
var _a;
|
|
475
|
-
// .meta will be visible in final rendered inline props.
|
|
476
|
-
// Only adding some .meta attributes here on certain conditions
|
|
477
|
-
// (instead of always adding them and letting them be visible as false/undefined etc)
|
|
478
|
-
const meta = {
|
|
479
|
-
type: contentType,
|
|
480
|
-
path: contentPath,
|
|
481
|
-
requestType: requestType,
|
|
482
|
-
renderMode: renderMode,
|
|
483
|
-
canRender: false,
|
|
484
|
-
catchAll: false,
|
|
485
|
-
apiUrl,
|
|
486
|
-
baseUrl,
|
|
487
|
-
locale,
|
|
488
|
-
defaultLocale,
|
|
489
|
-
};
|
|
490
|
-
if (requestedComponentPath) {
|
|
491
|
-
meta.requestedComponent = components.find(cmp => cmp.path === requestedComponentPath);
|
|
492
|
-
}
|
|
493
|
-
const pageDesc = (_a = pageCmp === null || pageCmp === void 0 ? void 0 : pageCmp.page) === null || _a === void 0 ? void 0 : _a.descriptor;
|
|
494
|
-
const typeDef = ComponentRegistry.getContentType(contentType);
|
|
495
|
-
if ((typeDef === null || typeDef === void 0 ? void 0 : typeDef.view) && !typeDef.catchAll) {
|
|
496
|
-
meta.canRender = true;
|
|
497
|
-
}
|
|
498
|
-
else if (requestType === XP_REQUEST_TYPE.COMPONENT) {
|
|
499
|
-
// always render a single component (show missing if not implemented)
|
|
500
|
-
meta.canRender = true;
|
|
501
|
-
}
|
|
502
|
-
else if (pageDesc) {
|
|
503
|
-
// always render a page if there is a descriptor (show missing if not implemented)
|
|
504
|
-
meta.canRender = true;
|
|
505
|
-
}
|
|
506
|
-
else if (typeDef === null || typeDef === void 0 ? void 0 : typeDef.view) {
|
|
507
|
-
meta.canRender = true;
|
|
508
|
-
meta.catchAll = true;
|
|
509
|
-
}
|
|
510
|
-
return meta;
|
|
511
|
-
}
|
|
512
|
-
function buildErrorResponse(requestType, renderMode, apiUrl, baseUrl, locale, defaultLocale, contentPath) {
|
|
513
|
-
return function (code = '500', message = 'Unknown error') {
|
|
514
|
-
return {
|
|
515
|
-
error: {
|
|
516
|
-
code,
|
|
517
|
-
message,
|
|
518
|
-
},
|
|
519
|
-
page: null,
|
|
520
|
-
common: null,
|
|
521
|
-
data: null,
|
|
522
|
-
meta: {
|
|
523
|
-
type: '',
|
|
524
|
-
requestType: requestType,
|
|
525
|
-
renderMode: renderMode,
|
|
526
|
-
path: contentPath || '',
|
|
527
|
-
canRender: false,
|
|
528
|
-
catchAll: false,
|
|
529
|
-
apiUrl,
|
|
530
|
-
baseUrl,
|
|
531
|
-
locale,
|
|
532
|
-
defaultLocale,
|
|
533
|
-
},
|
|
534
|
-
};
|
|
535
|
-
};
|
|
536
|
-
}
|
|
537
|
-
function restrictComponentsToPath(contentType, components, componentPath) {
|
|
538
|
-
if (!componentPath || !(components === null || components === void 0 ? void 0 : components.length)) {
|
|
539
|
-
return components || [];
|
|
540
|
-
}
|
|
541
|
-
// filter components to the requested one only
|
|
542
|
-
const component = components.find(cmp => {
|
|
543
|
-
return cmp.path === componentPath;
|
|
544
|
-
});
|
|
545
|
-
if (!component) {
|
|
546
|
-
return [];
|
|
547
|
-
}
|
|
548
|
-
let result = [component];
|
|
549
|
-
if (component.type !== XP_COMPONENT_TYPE.LAYOUT) {
|
|
550
|
-
// remember to include all parent layouts too !
|
|
551
|
-
const cmpPath = parseComponentPath(contentType, component.path);
|
|
552
|
-
for (let i = cmpPath.length - 2; i >= 0; i--) {
|
|
553
|
-
const parentPath = cmpPath[i];
|
|
554
|
-
const parentCmp = components.find(cmp => cmp.path === `/${parentPath.region}/${parentPath.index}`);
|
|
555
|
-
if (parentCmp) {
|
|
556
|
-
result.unshift(parentCmp);
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
else {
|
|
561
|
-
// It's a layout, include child components
|
|
562
|
-
const childCmps = components.filter(cmp => cmp.path !== component.path && cmp.path.startsWith(component.path));
|
|
563
|
-
if (childCmps.length) {
|
|
564
|
-
result = result.concat(childCmps);
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
return result;
|
|
568
|
-
}
|
|
569
|
-
const COMPONENT_PATH_KEY = /\/?_\/component/; // first slash is optional for root components
|
|
570
|
-
const getContentAndComponentPaths = (requestPath) => {
|
|
571
|
-
let contentPath, componentPath;
|
|
572
|
-
if (COMPONENT_PATH_KEY.test(requestPath)) {
|
|
573
|
-
[contentPath, componentPath] = requestPath.split(COMPONENT_PATH_KEY);
|
|
574
|
-
}
|
|
575
|
-
else {
|
|
576
|
-
contentPath = requestPath;
|
|
577
|
-
}
|
|
578
|
-
return [contentPath, componentPath];
|
|
579
|
-
};
|
|
580
|
-
// ///////////////////////////// ENTRY 1 - THE BUILDER:
|
|
11
|
+
import { ComponentRegistry } from '../common/ComponentRegistry';
|
|
12
|
+
import { UrlProcessor } from '../common/UrlProcessor';
|
|
13
|
+
import { FRAGMENT_CONTENTTYPE_NAME, PAGE_TEMPLATE_CONTENTTYPE_NAME, PAGE_TEMPLATE_FOLDER, RENDER_MODE, XP_COMPONENT_TYPE, XP_REQUEST_TYPE, } from '../common/constants';
|
|
14
|
+
import { APP_NAME, APP_NAME_DASHED, IS_DEV_MODE } from '../common/env';
|
|
15
|
+
import { getContentApiUrl } from '../utils/getContentApiUrl';
|
|
16
|
+
import { getProjectLocaleConfig } from '../utils/getProjectLocaleConfig';
|
|
17
|
+
import { getRenderMode } from '../utils/getRenderMode';
|
|
18
|
+
import { getXpBaseUrl } from '../utils/getXpBaseUrl';
|
|
19
|
+
import { getRequestLocaleInfo } from '../utils/getRequestLocaleInfo';
|
|
20
|
+
import { buildGuillotineRequestHeaders } from '../utils/buildGuillotineRequestHeaders';
|
|
21
|
+
import { buildPage } from './buildPage';
|
|
22
|
+
import { fetchMetaData } from './fetchMetaData';
|
|
23
|
+
import { getCleanContentPathArrayOrThrow400 } from './getCleanContentPathArrayOrThrow400';
|
|
24
|
+
import { buildErrorResponse } from './buildErrorResponse';
|
|
25
|
+
import { getContentAndComponentPaths } from './getContentAndComponentPaths';
|
|
26
|
+
import { restrictComponentsToPath } from './restrictComponentsToPath';
|
|
27
|
+
import { processComponentConfig } from './processComponentConfig';
|
|
28
|
+
import { getQueryAndVariables } from './getQueryAndVariables';
|
|
29
|
+
import { collectComponentDescriptors } from './collectComponentDescriptors';
|
|
30
|
+
import { combineMultipleQueries } from './combineMultipleQueries';
|
|
31
|
+
import { fetchContentData } from './fetchContentData';
|
|
32
|
+
import { applyProcessors } from './applyProcessors';
|
|
33
|
+
import { createMetaData } from './createMetaData';
|
|
581
34
|
/**
|
|
582
|
-
*
|
|
583
|
-
*
|
|
584
|
-
*
|
|
35
|
+
* Default fetchContent function, built with params from imports.
|
|
36
|
+
* It runs custom content-type-specific guillotine calls against an XP guillotine endpoint, returns content data, error and some meta data
|
|
37
|
+
* Sends one query to the guillotine API and asks for content type, then uses the type to select a second query and variables, which is sent to the API and fetches content data.
|
|
38
|
+
* @param context object from Next, contains .query info
|
|
39
|
+
* @returns FetchContentResult object: {data?: T, error?: {code, message}}
|
|
585
40
|
*/
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
return
|
|
589
|
-
var _a, _b;
|
|
41
|
+
export function fetchContent(context) {
|
|
42
|
+
var _a, _b;
|
|
43
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
590
44
|
const { locale, locales, defaultLocale } = getRequestLocaleInfo(context);
|
|
591
45
|
// ideally we only want to set headers in draft mode,
|
|
592
46
|
// but draft mode token is not passed in non-static mode
|
|
593
47
|
// so try to add them whenever they are absent
|
|
594
48
|
if (!context.headers) {
|
|
49
|
+
// TODO does this break routing or dynamic server-side rendering?
|
|
50
|
+
// I guess hydration will fix it anyway?
|
|
595
51
|
const allHeaders = headers();
|
|
596
52
|
context.headers = new Headers();
|
|
597
53
|
allHeaders.forEach((value, key) => {
|
|
598
54
|
context.headers.set(key, value);
|
|
599
55
|
});
|
|
600
56
|
}
|
|
601
|
-
const outHeaders = {
|
|
602
|
-
|
|
603
|
-
|
|
57
|
+
const outHeaders = buildGuillotineRequestHeaders({
|
|
58
|
+
context,
|
|
59
|
+
defaultLocale,
|
|
60
|
+
locale,
|
|
61
|
+
locales,
|
|
62
|
+
});
|
|
604
63
|
const xpBaseUrl = getXpBaseUrl(context);
|
|
605
64
|
const contentApiUrl = getContentApiUrl(context);
|
|
606
65
|
const projectConfig = getProjectLocaleConfig(context);
|
|
@@ -630,8 +89,9 @@ const buildContentFetcher = (config) => {
|
|
|
630
89
|
else if (!type) {
|
|
631
90
|
return errorResponse('500', "Server responded with incomplete meta data: missing content 'type' attribute.");
|
|
632
91
|
}
|
|
633
|
-
else if (renderMode === RENDER_MODE.NEXT
|
|
634
|
-
|
|
92
|
+
else if (renderMode === RENDER_MODE.NEXT
|
|
93
|
+
&& !IS_DEV_MODE
|
|
94
|
+
&& (type === FRAGMENT_CONTENTTYPE_NAME ||
|
|
635
95
|
type === PAGE_TEMPLATE_CONTENTTYPE_NAME ||
|
|
636
96
|
type === PAGE_TEMPLATE_FOLDER)) {
|
|
637
97
|
return errorResponse('404', `Content type [${type}] is not accessible in ${renderMode} mode`);
|
|
@@ -647,7 +107,7 @@ const buildContentFetcher = (config) => {
|
|
|
647
107
|
// ////////////////////////////////////////////////// Content type established. Proceed to data call:
|
|
648
108
|
const allDescriptors = [];
|
|
649
109
|
// Add the content type query at all cases
|
|
650
|
-
const contentTypeDef =
|
|
110
|
+
const contentTypeDef = ComponentRegistry.getContentType(type);
|
|
651
111
|
const pageCmp = (components || []).find(cmp => cmp.type === XP_COMPONENT_TYPE.PAGE);
|
|
652
112
|
if (pageCmp) {
|
|
653
113
|
processComponentConfig(APP_NAME, APP_NAME_DASHED, pageCmp);
|
|
@@ -659,19 +119,23 @@ const buildContentFetcher = (config) => {
|
|
|
659
119
|
queryAndVariables: contentQueryAndVars,
|
|
660
120
|
});
|
|
661
121
|
}
|
|
662
|
-
const commonQueryAndVars = getQueryAndVariables(type, contentPath, context,
|
|
122
|
+
const commonQueryAndVars = getQueryAndVariables(type, contentPath, context, ComponentRegistry.getCommonQuery(), (_b = pageCmp === null || pageCmp === void 0 ? void 0 : pageCmp.page) === null || _b === void 0 ? void 0 : _b.config);
|
|
663
123
|
if (commonQueryAndVars) {
|
|
664
124
|
allDescriptors.push({
|
|
665
125
|
type: contentTypeDef,
|
|
666
126
|
queryAndVariables: commonQueryAndVars,
|
|
667
127
|
});
|
|
668
128
|
}
|
|
669
|
-
if ((components === null || components === void 0 ? void 0 : components.length) &&
|
|
129
|
+
if ((components === null || components === void 0 ? void 0 : components.length) && ComponentRegistry) {
|
|
670
130
|
for (const cmp of (components || [])) {
|
|
671
131
|
processComponentConfig(APP_NAME, APP_NAME_DASHED, cmp);
|
|
672
132
|
}
|
|
673
133
|
// Collect component queries if defined
|
|
674
|
-
const componentDescriptors = collectComponentDescriptors(
|
|
134
|
+
const componentDescriptors = collectComponentDescriptors({
|
|
135
|
+
components,
|
|
136
|
+
xpContentPath: contentPath,
|
|
137
|
+
context,
|
|
138
|
+
});
|
|
675
139
|
if (componentDescriptors.length) {
|
|
676
140
|
allDescriptors.push(...componentDescriptors);
|
|
677
141
|
}
|
|
@@ -720,8 +184,20 @@ const buildContentFetcher = (config) => {
|
|
|
720
184
|
allDescriptors[i].component.data = datum.value;
|
|
721
185
|
}
|
|
722
186
|
}
|
|
723
|
-
const page =
|
|
724
|
-
const meta = createMetaData(
|
|
187
|
+
const page = buildPage(type, components);
|
|
188
|
+
const meta = createMetaData({
|
|
189
|
+
apiUrl: contentApiUrl,
|
|
190
|
+
baseUrl: xpBaseUrl,
|
|
191
|
+
components,
|
|
192
|
+
contentPath: siteRelativeContentPath,
|
|
193
|
+
contentType: type,
|
|
194
|
+
defaultLocale,
|
|
195
|
+
locale,
|
|
196
|
+
pageCmp: page,
|
|
197
|
+
renderMode,
|
|
198
|
+
requestedComponentPath: componentPath,
|
|
199
|
+
requestType,
|
|
200
|
+
});
|
|
725
201
|
return {
|
|
726
202
|
data: contentData,
|
|
727
203
|
common,
|
|
@@ -744,92 +220,5 @@ const buildContentFetcher = (config) => {
|
|
|
744
220
|
return errorResponse(error.code, error.message);
|
|
745
221
|
}
|
|
746
222
|
});
|
|
747
|
-
};
|
|
748
|
-
// //////////////////////////// ENTRY 2: ready-to-use fetchContent function
|
|
749
|
-
/**
|
|
750
|
-
* Default fetchContent function, built with params from imports.
|
|
751
|
-
* It runs custom content-type-specific guillotine calls against an XP guillotine endpoint, returns content data, error and some meta data
|
|
752
|
-
* Sends one query to the guillotine API and asks for content type, then uses the type to select a second query and variables, which is sent to the API and fetches content data.
|
|
753
|
-
* @param contentPath string or string array: local (site-relative) path to a content available on the API (by XP _path - obtainable by running contentPath through getXpPath). Pre-split into string array, or already a slash-delimited string.
|
|
754
|
-
* @param context object from Next, contains .query info
|
|
755
|
-
* @returns FetchContentResult object: {data?: T, error?: {code, message}}
|
|
756
|
-
*/
|
|
757
|
-
export const fetchContent = buildContentFetcher(Object.assign(Object.assign({}, adapterConstants), { componentRegistry: ComponentRegistry }));
|
|
758
|
-
export function validateData(props) {
|
|
759
|
-
validateNotFound(props);
|
|
760
|
-
validateShortcut(props);
|
|
761
|
-
}
|
|
762
|
-
function validateNotFound(props) {
|
|
763
|
-
const { error } = props;
|
|
764
|
-
if (error) {
|
|
765
|
-
switch (error.code) {
|
|
766
|
-
case '404':
|
|
767
|
-
console.warn(error.code, error.message);
|
|
768
|
-
notFound();
|
|
769
|
-
break;
|
|
770
|
-
default:
|
|
771
|
-
console.error(error.code, error.message);
|
|
772
|
-
throw new Error(error.message);
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
}
|
|
776
|
-
function validateShortcut(props) {
|
|
777
|
-
var _a, _b, _c;
|
|
778
|
-
const { data, meta, error } = props;
|
|
779
|
-
const pageUrl = (_c = (_b = (_a = data === null || data === void 0 ? void 0 : data.get) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.target) === null || _c === void 0 ? void 0 : _c.pageUrl;
|
|
780
|
-
if (meta.type === 'base:shortcut' && pageUrl) {
|
|
781
|
-
if (meta.renderMode !== RENDER_MODE.NEXT) {
|
|
782
|
-
// console.debug(`Returning 404 for shortcut in ${RENDER_MODE.NEXT} mode`);
|
|
783
|
-
// do not show shortcut targets in preview/edit mode
|
|
784
|
-
console.warn(404, `Shortcuts are not available in ${RENDER_MODE.NEXT} render mode`);
|
|
785
|
-
notFound();
|
|
786
|
-
}
|
|
787
|
-
const destination = UrlProcessor.process(pageUrl, meta, true);
|
|
788
|
-
console.debug(`Redirecting shortcut content [${meta.path}] to`, destination);
|
|
789
|
-
redirect(destination, RedirectType.replace);
|
|
790
|
-
}
|
|
791
|
-
// we can not set 418 for static paths,
|
|
792
|
-
// but we can show 404 instead to be handled in CS
|
|
793
|
-
const canNotRender = meta && !meta.canRender && meta.renderMode !== RENDER_MODE.EDIT;
|
|
794
|
-
const catchAllInNextProdMode = (meta === null || meta === void 0 ? void 0 : meta.renderMode) === RENDER_MODE.NEXT && !IS_DEV_MODE && (meta === null || meta === void 0 ? void 0 : meta.catchAll);
|
|
795
|
-
const isNotFound = (error && error.code === '404') || canNotRender || catchAllInNextProdMode;
|
|
796
|
-
if (isNotFound) {
|
|
797
|
-
console.warn(404, `Can not render content at [${meta.path}]`);
|
|
798
|
-
notFound();
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
export function fetchContentPathsForAllLocales(path, query = GET_STATIC_PATHS_QUERY, countPerLocale = 999) {
|
|
802
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
803
|
-
const promises = Object.values(getProjectLocaleConfigs()).map(config => fetchContentPathsForLocale(path, config, query, countPerLocale));
|
|
804
|
-
return Promise.all(promises).then(results => {
|
|
805
|
-
return results.reduce((all, localePaths) => all.concat(localePaths), []);
|
|
806
|
-
});
|
|
807
|
-
});
|
|
808
|
-
}
|
|
809
|
-
export function fetchContentPathsForLocale(path, config, query = GET_STATIC_PATHS_QUERY, count = 999) {
|
|
810
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
811
|
-
const contentApiUrl = getContentApiUrl({
|
|
812
|
-
contentPath: path,
|
|
813
|
-
locale: config.locale,
|
|
814
|
-
});
|
|
815
|
-
const body = {
|
|
816
|
-
query,
|
|
817
|
-
variables: {
|
|
818
|
-
path,
|
|
819
|
-
count,
|
|
820
|
-
},
|
|
821
|
-
};
|
|
822
|
-
return fetchGuillotine(contentApiUrl, body, config).then((results) => {
|
|
823
|
-
return results.guillotine.queryDsl.reduce((prev, child) => {
|
|
824
|
-
var _a;
|
|
825
|
-
const regexp = new RegExp(`/${(_a = child.site) === null || _a === void 0 ? void 0 : _a._name}/?`);
|
|
826
|
-
const contentPath = child._path.replace(regexp, '');
|
|
827
|
-
prev.push({
|
|
828
|
-
contentPath: contentPath.split('/'),
|
|
829
|
-
locale: config.locale,
|
|
830
|
-
});
|
|
831
|
-
return prev;
|
|
832
|
-
}, []);
|
|
833
|
-
});
|
|
834
|
-
});
|
|
835
223
|
}
|
|
224
|
+
//# sourceMappingURL=fetchContent.js.map
|