@enonic/nextjs-adapter 1.0.2 → 2.0.0-B2
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/ComponentRegistry.d.ts +1 -1
- package/ComponentRegistry.js +1 -2
- package/UrlProcessor.d.ts +4 -3
- package/UrlProcessor.js +35 -26
- package/baseMappings.js +4 -0
- package/guillotine/fetchContent.d.ts +10 -25
- package/guillotine/fetchContent.js +122 -32
- package/guillotine/getMetaData.d.ts +3 -0
- package/package.json +14 -14
- package/query/Shortcut.d.ts +1 -0
- package/query/Shortcut.js +14 -0
- package/server/index.js +63 -51
- package/utils.d.ts +61 -4
- package/utils.js +123 -26
- package/views/BaseComponent.d.ts +4 -4
- package/views/BaseContent.d.ts +2 -2
- package/views/BaseLayout.d.ts +2 -2
- package/views/BaseMacro.d.ts +2 -2
- package/views/BasePage.d.ts +2 -2
- package/views/BasePart.d.ts +2 -2
- package/views/Empty.d.ts +2 -2
- package/views/Fragment.d.ts +2 -2
- package/views/Fragment.jsx +12 -7
- package/views/MainView.d.ts +2 -2
- package/views/Region.d.ts +3 -3
- package/views/RichTextView.d.ts +2 -2
- package/views/SingleComponent.d.ts +2 -2
- package/views/StaticContent.d.ts +5 -5
- package/views/StaticContent.jsx +18 -20
- package/views/Text.d.ts +2 -2
package/server/index.js
CHANGED
|
@@ -43,7 +43,7 @@ exports.withEnonicCache = exports.PURGE_CACHE_URL = void 0;
|
|
|
43
43
|
var http_1 = require("http");
|
|
44
44
|
var cache_1 = require("./cache");
|
|
45
45
|
var path_1 = __importDefault(require("path"));
|
|
46
|
-
var
|
|
46
|
+
var hostname = process.env.HOST || '127.0.0.1';
|
|
47
47
|
var dev = process.env.NODE_ENV !== 'production';
|
|
48
48
|
var port = process.env.PORT && parseInt(process.env.PORT, 10) || (dev ? 3000 : 4242);
|
|
49
49
|
exports.PURGE_CACHE_URL = '/_/enonic/cache/purge';
|
|
@@ -61,59 +61,71 @@ exports.default = (function (next) { return __awaiter(void 0, void 0, void 0, fu
|
|
|
61
61
|
return __generator(this, function (_a) {
|
|
62
62
|
switch (_a.label) {
|
|
63
63
|
case 0:
|
|
64
|
-
nextServer = next({ dev: dev });
|
|
64
|
+
nextServer = next({ dev: dev, hostname: hostname, port: port });
|
|
65
65
|
nextHandler = nextServer.getRequestHandler();
|
|
66
|
-
return [4 /*yield*/, nextServer.prepare().then(function () {
|
|
67
|
-
var nextNodeServer
|
|
68
|
-
var
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
66
|
+
return [4 /*yield*/, nextServer.prepare().then(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
67
|
+
var nextNodeServer, opts, purgeUrl, server;
|
|
68
|
+
var _a;
|
|
69
|
+
return __generator(this, function (_b) {
|
|
70
|
+
switch (_b.label) {
|
|
71
|
+
case 0: return [4 /*yield*/, ((_a = nextServer['getServer']) === null || _a === void 0 ? void 0 : _a.call(nextServer))];
|
|
72
|
+
case 1:
|
|
73
|
+
nextNodeServer = _b.sent();
|
|
74
|
+
if (!nextNodeServer) {
|
|
75
|
+
console.error('Unable to access incremental cache, cache purge endpoint will be disabled');
|
|
76
|
+
return [2 /*return*/, nextServer];
|
|
77
|
+
}
|
|
78
|
+
opts = nextNodeServer['serverOptions'].conf;
|
|
79
|
+
purgeUrl = ((opts === null || opts === void 0 ? void 0 : opts.basePath) || '') + exports.PURGE_CACHE_URL;
|
|
80
|
+
console.info("Staring cache purge endpoint at ".concat(purgeUrl, "..."));
|
|
81
|
+
server = (0, http_1.createServer)(function (req, res) { return __awaiter(void 0, void 0, void 0, function () {
|
|
82
|
+
var parsedUrl, tokenParam, cache, pathParam;
|
|
83
|
+
return __generator(this, function (_a) {
|
|
84
|
+
switch (_a.label) {
|
|
85
|
+
case 0:
|
|
86
|
+
parsedUrl = new URL("http://".concat(hostname, ":").concat(port).concat(req.url || ''));
|
|
87
|
+
if (!(parsedUrl.pathname !== purgeUrl)) return [3 /*break*/, 2];
|
|
88
|
+
return [4 /*yield*/, nextHandler(req, res)];
|
|
89
|
+
case 1:
|
|
90
|
+
_a.sent();
|
|
91
|
+
return [3 /*break*/, 5];
|
|
92
|
+
case 2:
|
|
93
|
+
if (!dev) return [3 /*break*/, 3];
|
|
94
|
+
console.warn('\nCache clearing is not available in DEV mode.\n');
|
|
95
|
+
res.setHeader('Content-Type', 'application/json');
|
|
96
|
+
res.end(JSON.stringify({ purged: false }));
|
|
97
|
+
return [3 /*break*/, 5];
|
|
98
|
+
case 3:
|
|
99
|
+
tokenParam = parsedUrl.searchParams.get('token');
|
|
100
|
+
if (tokenParam !== process.env.ENONIC_API_TOKEN) {
|
|
101
|
+
// XP hijacks 401 to show login page, so send 407 instead
|
|
102
|
+
res.statusCode = 407;
|
|
103
|
+
res.end(JSON.stringify({ message: 'Invalid token' }));
|
|
104
|
+
return [2 /*return*/];
|
|
105
|
+
}
|
|
106
|
+
cache = nextNodeServer.getIncrementalCache({
|
|
107
|
+
requestHeaders: Object.assign({}, req.headers),
|
|
108
|
+
});
|
|
109
|
+
pathParam = parsedUrl.searchParams.get('path') || undefined;
|
|
110
|
+
return [4 /*yield*/, (0, cache_1.purgeCache)(cache, pathParam)];
|
|
111
|
+
case 4:
|
|
112
|
+
_a.sent();
|
|
113
|
+
res.setHeader('Content-Type', 'application/json');
|
|
114
|
+
res.end(JSON.stringify({ purged: true }));
|
|
115
|
+
_a.label = 5;
|
|
116
|
+
case 5: return [2 /*return*/];
|
|
117
|
+
}
|
|
98
118
|
});
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
}); }).listen(port, host, function () {
|
|
110
|
-
console.info("Server ready on ".concat(host, ":").concat(port));
|
|
111
|
-
}).on('error', function (e) {
|
|
112
|
-
console.error('Server error:', e);
|
|
113
|
-
server.close();
|
|
119
|
+
}); }).listen(port, hostname, function () {
|
|
120
|
+
console.info("Server ready on ".concat(hostname, ":").concat(port));
|
|
121
|
+
}).on('error', function (e) {
|
|
122
|
+
console.error('Server error:', e);
|
|
123
|
+
server.close();
|
|
124
|
+
});
|
|
125
|
+
return [2 /*return*/, nextServer];
|
|
126
|
+
}
|
|
114
127
|
});
|
|
115
|
-
|
|
116
|
-
})];
|
|
128
|
+
}); })];
|
|
117
129
|
case 1: return [2 /*return*/, _a.sent()];
|
|
118
130
|
}
|
|
119
131
|
});
|
package/utils.d.ts
CHANGED
|
@@ -1,15 +1,24 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
1
3
|
/** Import config values from .env, .env.development and .env.production */
|
|
2
|
-
import {
|
|
4
|
+
import { GetServerSidePropsContext } from 'next';
|
|
5
|
+
import { ParsedUrlQuery } from 'node:querystring';
|
|
6
|
+
import { IncomingHttpHeaders } from 'http';
|
|
3
7
|
export declare const IS_DEV_MODE: boolean;
|
|
8
|
+
export declare enum ENV_VARS {
|
|
9
|
+
PROJECTS = "ENONIC_PROJECTS",
|
|
10
|
+
API = "ENONIC_API",
|
|
11
|
+
API_TOKEN = "ENONIC_API_TOKEN"
|
|
12
|
+
}
|
|
4
13
|
/** Optional utility value - defining in one place the name of the target app (the app that defines the content types, the app name is therefore part of the content type strings used both in typeselector and in query introspections) */
|
|
5
14
|
export declare const APP_NAME: string;
|
|
6
15
|
/** Optional utility value - derived from APP_NAME, only with underscores instead of dots */
|
|
7
16
|
export declare const APP_NAME_UNDERSCORED: string;
|
|
8
17
|
/** Optional utility value - derived from APP_NAME, only with dashes instead of dots */
|
|
9
18
|
export declare const APP_NAME_DASHED: string;
|
|
10
|
-
export declare const SITE_KEY: string;
|
|
11
19
|
export declare const XP_BASE_URL_HEADER = "xpbaseurl";
|
|
12
20
|
export declare const RENDER_MODE_HEADER = "content-studio-mode";
|
|
21
|
+
export declare const PROJECT_ID_HEADER = "content-studio-project";
|
|
13
22
|
export declare const JSESSIONID_HEADER = "jsessionid";
|
|
14
23
|
export declare const PORTAL_COMPONENT_ATTRIBUTE = "data-portal-component-type";
|
|
15
24
|
export declare const PORTAL_REGION_ATTRIBUTE = "data-portal-region";
|
|
@@ -18,6 +27,16 @@ export declare const FRAGMENT_DEFAULT_REGION_NAME = "fragment";
|
|
|
18
27
|
export declare const PAGE_TEMPLATE_CONTENTTYPE_NAME = "portal:page-template";
|
|
19
28
|
export declare const PAGE_TEMPLATE_FOLDER = "portal:template-folder";
|
|
20
29
|
export declare const SITE_CONTENTTYPE_NAME = "portal:site";
|
|
30
|
+
export declare const LOCALE_HEADER = "locale";
|
|
31
|
+
export declare const LOCALES_HEADER = "locales";
|
|
32
|
+
export declare const DEFAULT_LOCALE_HEADER = "default-locale";
|
|
33
|
+
/** excluded contents:
|
|
34
|
+
* - folder
|
|
35
|
+
* - shortcuts (redirect can't be used in prerender)
|
|
36
|
+
* - media
|
|
37
|
+
* - paths with '/_' in them
|
|
38
|
+
*/
|
|
39
|
+
export declare const GET_STATIC_PATHS_QUERY = "query ($count: Int = 100){\n guillotine {\n query(query: \"type != 'base:folder' AND type != 'base:shortcut' AND type NOT LIKE 'media:*' AND _path NOT LIKE '*/_*'\", first: $count) {\n _name\n _path\n site {\n _name\n }\n }\n }\n}";
|
|
21
40
|
export declare enum XP_REQUEST_TYPE {
|
|
22
41
|
COMPONENT = "component",
|
|
23
42
|
TYPE = "type",
|
|
@@ -38,9 +57,48 @@ export declare enum XP_COMPONENT_TYPE {
|
|
|
38
57
|
FRAGMENT = "fragment",
|
|
39
58
|
PAGE = "page"
|
|
40
59
|
}
|
|
60
|
+
export interface ServerSideParams extends ParsedUrlQuery {
|
|
61
|
+
contentPath?: string[];
|
|
62
|
+
mode?: string;
|
|
63
|
+
}
|
|
64
|
+
export interface PreviewParams {
|
|
65
|
+
contentPath: string[];
|
|
66
|
+
headers: Record<string, string>;
|
|
67
|
+
params: Record<string, string>;
|
|
68
|
+
}
|
|
69
|
+
export type Context = GetServerSidePropsContext<ServerSideParams, PreviewParams>;
|
|
70
|
+
export type LocaleProjectConfig = {
|
|
71
|
+
project: string;
|
|
72
|
+
site: string;
|
|
73
|
+
locale: string;
|
|
74
|
+
};
|
|
75
|
+
export type LocaleProjectConfigs = {
|
|
76
|
+
default: LocaleProjectConfig;
|
|
77
|
+
[locale: string]: LocaleProjectConfig;
|
|
78
|
+
};
|
|
79
|
+
export interface MinimalContext {
|
|
80
|
+
req?: {
|
|
81
|
+
headers: IncomingHttpHeaders;
|
|
82
|
+
};
|
|
83
|
+
locale?: string;
|
|
84
|
+
defaultLocale?: string;
|
|
85
|
+
locales?: string[];
|
|
86
|
+
}
|
|
87
|
+
export interface ContentPathItem {
|
|
88
|
+
params: {
|
|
89
|
+
contentPath: string[];
|
|
90
|
+
};
|
|
91
|
+
locale?: string;
|
|
92
|
+
}
|
|
41
93
|
export declare const getRenderMode: (context?: MinimalContext) => RENDER_MODE;
|
|
94
|
+
export declare function normalizeLocale(locale: string): string | undefined;
|
|
95
|
+
export declare function getLocaleProjectConfig(context?: MinimalContext): LocaleProjectConfig;
|
|
96
|
+
export declare function getLocaleProjectConfigById(projectId?: string, useDefault?: boolean): LocaleProjectConfig;
|
|
97
|
+
export declare function getLocaleProjectConfigs(): LocaleProjectConfigs;
|
|
98
|
+
export declare function fixDoubleSlashes(str: string): string;
|
|
42
99
|
export declare function getContentApiUrl(context?: MinimalContext): string;
|
|
43
|
-
export declare function
|
|
100
|
+
export declare function addJsessionHeaders(headers?: Object, context?: MinimalContext): void;
|
|
101
|
+
export declare function addLocaleHeaders(headers?: Object, context?: Context): void;
|
|
44
102
|
export declare const getXpBaseUrl: (context?: MinimalContext) => string;
|
|
45
103
|
export declare const commonChars: (s1?: string, s2?: string) => string;
|
|
46
104
|
export declare const sanitizeGraphqlName: (text: string) => string;
|
|
@@ -49,7 +107,6 @@ declare const adapterConstants: {
|
|
|
49
107
|
APP_NAME: string;
|
|
50
108
|
APP_NAME_UNDERSCORED: string;
|
|
51
109
|
APP_NAME_DASHED: string;
|
|
52
|
-
SITE_KEY: string;
|
|
53
110
|
PORTAL_COMPONENT_ATTRIBUTE: string;
|
|
54
111
|
PORTAL_REGION_ATTRIBUTE: string;
|
|
55
112
|
};
|
package/utils.js
CHANGED
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
const mode = process.env.MODE || process.env.NEXT_PUBLIC_MODE;
|
|
2
2
|
export const IS_DEV_MODE = (mode === 'development');
|
|
3
|
+
export var ENV_VARS;
|
|
4
|
+
(function (ENV_VARS) {
|
|
5
|
+
ENV_VARS["PROJECTS"] = "ENONIC_PROJECTS";
|
|
6
|
+
ENV_VARS["API"] = "ENONIC_API";
|
|
7
|
+
ENV_VARS["API_TOKEN"] = "ENONIC_API_TOKEN";
|
|
8
|
+
})(ENV_VARS || (ENV_VARS = {}));
|
|
3
9
|
/** URL to the guillotine API */
|
|
4
|
-
const
|
|
5
|
-
|
|
10
|
+
const API_URL = (process.env.ENONIC_API || process.env.NEXT_PUBLIC_ENONIC_API);
|
|
11
|
+
/** Locales and Enonic XP projects correspondence list */
|
|
12
|
+
const PROJECTS = (process.env.ENONIC_PROJECTS || process.env.NEXT_PUBLIC_ENONIC_PROJECTS);
|
|
6
13
|
/** Optional utility value - defining in one place the name of the target app (the app that defines the content types, the app name is therefore part of the content type strings used both in typeselector and in query introspections) */
|
|
7
|
-
export const APP_NAME = (process.env.
|
|
14
|
+
export const APP_NAME = (process.env.ENONIC_APP_NAME || process.env.NEXT_PUBLIC_ENONIC_APP_NAME);
|
|
8
15
|
/** Optional utility value - derived from APP_NAME, only with underscores instead of dots */
|
|
9
16
|
export const APP_NAME_UNDERSCORED = (APP_NAME || '').replace(/\./g, '_');
|
|
10
17
|
/** Optional utility value - derived from APP_NAME, only with dashes instead of dots */
|
|
11
18
|
export const APP_NAME_DASHED = (APP_NAME || '').replace(/\./g, '-');
|
|
12
|
-
|
|
19
|
+
const PROJECT_CONFIG_REGEXP = new RegExp('^(?:([\\w-]+):)?([^\\/\\s]+)(\\/[\\w-.]+)?$', 'i');
|
|
13
20
|
// //////////////////////////////////////////////////////////////////////// Hardcode-able constants
|
|
14
21
|
// URI parameter marking that a request is for a preview for CS. MUST MATCH THE VALUE OF 'FROM_XP_PARAM' on XP side.
|
|
15
22
|
export const XP_BASE_URL_HEADER = 'xpbaseurl';
|
|
16
23
|
export const RENDER_MODE_HEADER = 'content-studio-mode';
|
|
24
|
+
export const PROJECT_ID_HEADER = 'content-studio-project';
|
|
17
25
|
export const JSESSIONID_HEADER = 'jsessionid';
|
|
18
26
|
export const PORTAL_COMPONENT_ATTRIBUTE = 'data-portal-component-type';
|
|
19
27
|
export const PORTAL_REGION_ATTRIBUTE = 'data-portal-region';
|
|
@@ -22,6 +30,26 @@ export const FRAGMENT_DEFAULT_REGION_NAME = 'fragment';
|
|
|
22
30
|
export const PAGE_TEMPLATE_CONTENTTYPE_NAME = 'portal:page-template';
|
|
23
31
|
export const PAGE_TEMPLATE_FOLDER = 'portal:template-folder';
|
|
24
32
|
export const SITE_CONTENTTYPE_NAME = 'portal:site';
|
|
33
|
+
export const LOCALE_HEADER = 'locale';
|
|
34
|
+
export const LOCALES_HEADER = 'locales';
|
|
35
|
+
export const DEFAULT_LOCALE_HEADER = 'default-locale';
|
|
36
|
+
/** excluded contents:
|
|
37
|
+
* - folder
|
|
38
|
+
* - shortcuts (redirect can't be used in prerender)
|
|
39
|
+
* - media
|
|
40
|
+
* - paths with '/_' in them
|
|
41
|
+
*/
|
|
42
|
+
export const GET_STATIC_PATHS_QUERY = `query ($count: Int = 100){
|
|
43
|
+
guillotine {
|
|
44
|
+
query(query: "type != 'base:folder' AND type != 'base:shortcut' AND type NOT LIKE 'media:*' AND _path NOT LIKE '*/_*'", first: $count) {
|
|
45
|
+
_name
|
|
46
|
+
_path
|
|
47
|
+
site {
|
|
48
|
+
_name
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}`;
|
|
25
53
|
// ------------------------------- Exports and auxillary functions derived from values above ------------------------------------
|
|
26
54
|
export var XP_REQUEST_TYPE;
|
|
27
55
|
(function (XP_REQUEST_TYPE) {
|
|
@@ -53,39 +81,109 @@ export const getRenderMode = (context) => {
|
|
|
53
81
|
const enumValue = RENDER_MODE[value === null || value === void 0 ? void 0 : value.toUpperCase()];
|
|
54
82
|
return enumValue || RENDER_MODE[process.env.RENDER_MODE] || RENDER_MODE.NEXT;
|
|
55
83
|
};
|
|
84
|
+
export function normalizeLocale(locale) {
|
|
85
|
+
return locale !== 'default' ? locale : undefined;
|
|
86
|
+
}
|
|
87
|
+
export function getLocaleProjectConfig(context) {
|
|
88
|
+
var _a;
|
|
89
|
+
const projectId = (((_a = context === null || context === void 0 ? void 0 : context.req) === null || _a === void 0 ? void 0 : _a.headers) || {})[PROJECT_ID_HEADER];
|
|
90
|
+
if (projectId) {
|
|
91
|
+
return getLocaleProjectConfigById(projectId);
|
|
92
|
+
}
|
|
93
|
+
const projectsConfig = getLocaleProjectConfigs();
|
|
94
|
+
const locale = (context === null || context === void 0 ? void 0 : context.locale) || (context === null || context === void 0 ? void 0 : context.defaultLocale);
|
|
95
|
+
let config = projectsConfig[locale];
|
|
96
|
+
if (!config) {
|
|
97
|
+
config = projectsConfig.default;
|
|
98
|
+
}
|
|
99
|
+
if (!config) {
|
|
100
|
+
throw new Error(`No config for locale "${locale}" found in "${ENV_VARS.PROJECTS}" environmental variable.
|
|
101
|
+
Format: <default-repository-name>/<site-path>,<language>:<repository-name>/<site-path>,...`);
|
|
102
|
+
}
|
|
103
|
+
return config;
|
|
104
|
+
}
|
|
105
|
+
export function getLocaleProjectConfigById(projectId, useDefault = true) {
|
|
106
|
+
const projects = getLocaleProjectConfigs();
|
|
107
|
+
if (!projectId) {
|
|
108
|
+
return useDefault ? projects.default : undefined;
|
|
109
|
+
}
|
|
110
|
+
const match = Object.values(projects).find(p => {
|
|
111
|
+
var _a;
|
|
112
|
+
return ((_a = p === null || p === void 0 ? void 0 : p.project) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === projectId.toLowerCase();
|
|
113
|
+
});
|
|
114
|
+
return match || (useDefault ? projects.default : undefined);
|
|
115
|
+
}
|
|
116
|
+
export function getLocaleProjectConfigs() {
|
|
117
|
+
const str = PROJECTS;
|
|
118
|
+
const envVarName = ENV_VARS.PROJECTS;
|
|
119
|
+
if (!(str === null || str === void 0 ? void 0 : str.length)) {
|
|
120
|
+
throw Error(`"${envVarName}" environmental variable is required.`);
|
|
121
|
+
}
|
|
122
|
+
const result = str.split(',').reduce((config, prjStr) => {
|
|
123
|
+
const matches = PROJECT_CONFIG_REGEXP.exec(prjStr === null || prjStr === void 0 ? void 0 : prjStr.trim());
|
|
124
|
+
if (!(matches === null || matches === void 0 ? void 0 : matches.length)) {
|
|
125
|
+
return config;
|
|
126
|
+
}
|
|
127
|
+
const [full, lang = 'default', project, site] = matches;
|
|
128
|
+
if (project && site) {
|
|
129
|
+
config[lang] = {
|
|
130
|
+
project,
|
|
131
|
+
site,
|
|
132
|
+
locale: lang,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
throw Error(`Wrong configuration in "${envVarName}": ${prjStr}.
|
|
137
|
+
Format: <default-repository-name>/<site-path>,<language>:<repository-name>/<site-path>,...`);
|
|
138
|
+
}
|
|
139
|
+
return config;
|
|
140
|
+
}, {
|
|
141
|
+
default: {
|
|
142
|
+
project: '',
|
|
143
|
+
site: '',
|
|
144
|
+
locale: '',
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
if (!result.default.site || !result.default.project) {
|
|
148
|
+
throw Error(`"${envVarName}" environmental variable should contain default value.
|
|
149
|
+
Format: <default-repository-name>/<site-path>,<language>:<repository-name>/<site-path>,...`);
|
|
150
|
+
}
|
|
151
|
+
return result;
|
|
152
|
+
}
|
|
153
|
+
export function fixDoubleSlashes(str) {
|
|
154
|
+
return str.replace(/(^|[^:/])\/{2,}/g, '$1/');
|
|
155
|
+
}
|
|
56
156
|
export function getContentApiUrl(context) {
|
|
57
|
-
const
|
|
58
|
-
|
|
157
|
+
const project = getLocaleProjectConfig(context).project;
|
|
158
|
+
const branch = getRenderMode(context) === RENDER_MODE.NEXT ? 'master' : 'draft';
|
|
159
|
+
return fixDoubleSlashes(`${API_URL}/${project}/${branch}`);
|
|
59
160
|
}
|
|
60
|
-
export function
|
|
161
|
+
export function addJsessionHeaders(headers = {}, context) {
|
|
61
162
|
var _a;
|
|
62
|
-
const headers = {};
|
|
63
163
|
const jsessionid = (_a = context === null || context === void 0 ? void 0 : context.req) === null || _a === void 0 ? void 0 : _a.headers[JSESSIONID_HEADER];
|
|
64
164
|
if (jsessionid) {
|
|
65
165
|
headers['Cookie'] = `${JSESSIONID_HEADER}=${jsessionid}`;
|
|
66
166
|
}
|
|
67
|
-
return headers;
|
|
68
167
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
168
|
+
export function addLocaleHeaders(headers = {}, context) {
|
|
169
|
+
const locale = context === null || context === void 0 ? void 0 : context.locale;
|
|
170
|
+
if (locale) {
|
|
171
|
+
headers[LOCALE_HEADER] = locale;
|
|
172
|
+
}
|
|
173
|
+
const locales = context === null || context === void 0 ? void 0 : context.locales;
|
|
174
|
+
if (locales) {
|
|
175
|
+
headers[LOCALES_HEADER] = JSON.stringify(locales);
|
|
176
|
+
}
|
|
177
|
+
const defaultLocale = context === null || context === void 0 ? void 0 : context.defaultLocale;
|
|
178
|
+
if (defaultLocale) {
|
|
179
|
+
headers[DEFAULT_LOCALE_HEADER] = defaultLocale;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
77
182
|
export const getXpBaseUrl = (context) => {
|
|
78
183
|
var _a;
|
|
79
|
-
const mode = getRenderMode(context);
|
|
80
|
-
const existingUrl = xpBaseUrlMap[mode];
|
|
81
|
-
if (existingUrl) {
|
|
82
|
-
return existingUrl;
|
|
83
|
-
}
|
|
84
184
|
const header = ((((_a = context === null || context === void 0 ? void 0 : context.req) === null || _a === void 0 ? void 0 : _a.headers) || {})[XP_BASE_URL_HEADER] || '');
|
|
85
185
|
// TODO: workaround for XP pattern controller mapping not picked up in edit mode
|
|
86
|
-
|
|
87
|
-
xpBaseUrlMap[mode] = resultingUrl;
|
|
88
|
-
return resultingUrl;
|
|
186
|
+
return (header || '/').replace(/\/edit\//, '/inline/');
|
|
89
187
|
};
|
|
90
188
|
export const commonChars = (s1, s2) => {
|
|
91
189
|
let result = '';
|
|
@@ -120,7 +218,6 @@ const adapterConstants = {
|
|
|
120
218
|
APP_NAME,
|
|
121
219
|
APP_NAME_UNDERSCORED,
|
|
122
220
|
APP_NAME_DASHED,
|
|
123
|
-
SITE_KEY,
|
|
124
221
|
PORTAL_COMPONENT_ATTRIBUTE,
|
|
125
222
|
PORTAL_REGION_ATTRIBUTE,
|
|
126
223
|
};
|
package/views/BaseComponent.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import { MetaData, PageComponent } from '../guillotine/getMetaData';
|
|
3
3
|
export type BaseComponentProps = {
|
|
4
4
|
component: PageComponent;
|
|
@@ -10,16 +10,16 @@ export default BaseComponent;
|
|
|
10
10
|
export declare const MissingComponent: ({ descriptor, type }: {
|
|
11
11
|
descriptor?: string;
|
|
12
12
|
type: string;
|
|
13
|
-
}) => JSX.Element;
|
|
13
|
+
}) => React.JSX.Element;
|
|
14
14
|
export declare function shouldShowMissingView(meta: MetaData): boolean;
|
|
15
15
|
export declare const ErrorComponent: ({ type, descriptor, reason }: {
|
|
16
16
|
type?: string;
|
|
17
17
|
descriptor?: string;
|
|
18
18
|
reason: string;
|
|
19
|
-
}) => JSX.Element;
|
|
19
|
+
}) => React.JSX.Element;
|
|
20
20
|
export declare function shouldShowErrorView(meta: MetaData): boolean;
|
|
21
21
|
export declare const PlaceholderComponent: ({ type, descriptor }: {
|
|
22
22
|
type?: string;
|
|
23
23
|
descriptor?: string;
|
|
24
|
-
}) => JSX.Element;
|
|
24
|
+
}) => React.JSX.Element;
|
|
25
25
|
export declare function shouldShowPlaceholderView(meta: MetaData): boolean;
|
package/views/BaseContent.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import { FetchContentResult } from '../guillotine/fetchContent';
|
|
3
|
-
declare const BaseContent: (props: FetchContentResult) => JSX.Element;
|
|
3
|
+
declare const BaseContent: (props: FetchContentResult) => React.JSX.Element;
|
|
4
4
|
export default BaseContent;
|
package/views/BaseLayout.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import { LayoutData, MetaData, RegionTree } from '../guillotine/getMetaData';
|
|
3
3
|
export interface LayoutProps {
|
|
4
4
|
layout: LayoutData;
|
|
@@ -13,5 +13,5 @@ interface BaseLayoutProps {
|
|
|
13
13
|
common?: any;
|
|
14
14
|
meta: MetaData;
|
|
15
15
|
}
|
|
16
|
-
declare const BaseLayout: (props: BaseLayoutProps) => JSX.Element;
|
|
16
|
+
declare const BaseLayout: (props: BaseLayoutProps) => React.JSX.Element;
|
|
17
17
|
export default BaseLayout;
|
package/views/BaseMacro.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import { MacroConfig, MacroData, MetaData } from '../guillotine/getMetaData';
|
|
3
3
|
export declare const MACRO_DISABLE = "system:disable";
|
|
4
4
|
export declare const MACRO_EMBED = "system:embed";
|
|
@@ -12,5 +12,5 @@ export interface MacroProps {
|
|
|
12
12
|
config: MacroConfig;
|
|
13
13
|
meta: MetaData;
|
|
14
14
|
}
|
|
15
|
-
declare const BaseMacro: (props: BaseMacroProps) => JSX.Element;
|
|
15
|
+
declare const BaseMacro: (props: BaseMacroProps) => React.JSX.Element;
|
|
16
16
|
export default BaseMacro;
|
package/views/BasePage.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import { MetaData, PageData } from '../guillotine/getMetaData';
|
|
3
3
|
export interface PageProps {
|
|
4
4
|
page: PageData;
|
|
@@ -15,5 +15,5 @@ export interface BasePageProps {
|
|
|
15
15
|
error?: string;
|
|
16
16
|
meta: MetaData;
|
|
17
17
|
}
|
|
18
|
-
declare const BasePage: (props: BasePageProps) => JSX.Element;
|
|
18
|
+
declare const BasePage: (props: BasePageProps) => React.JSX.Element;
|
|
19
19
|
export default BasePage;
|
package/views/BasePart.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import { MetaData, PartData } from '../guillotine/getMetaData';
|
|
3
3
|
export interface PartProps {
|
|
4
4
|
part: PartData;
|
|
@@ -15,5 +15,5 @@ interface BasePartProps {
|
|
|
15
15
|
error?: string;
|
|
16
16
|
meta: MetaData;
|
|
17
17
|
}
|
|
18
|
-
declare const BasePart: (props: BasePartProps) => JSX.Element;
|
|
18
|
+
declare const BasePart: (props: BasePartProps) => React.JSX.Element;
|
|
19
19
|
export default BasePart;
|
package/views/Empty.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
declare const Empty: () => JSX.Element;
|
|
1
|
+
import React from 'react';
|
|
2
|
+
declare const Empty: () => React.JSX.Element;
|
|
3
3
|
export default Empty;
|
package/views/Fragment.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import { FragmentData, MetaData, PageData } from '../guillotine/getMetaData';
|
|
3
3
|
interface FragmentProps {
|
|
4
4
|
page?: PageData;
|
|
@@ -6,5 +6,5 @@ interface FragmentProps {
|
|
|
6
6
|
common?: any;
|
|
7
7
|
meta: MetaData;
|
|
8
8
|
}
|
|
9
|
-
declare const FragmentView: (props: FragmentProps) => JSX.Element;
|
|
9
|
+
declare const FragmentView: (props: FragmentProps) => React.JSX.Element;
|
|
10
10
|
export default FragmentView;
|
package/views/Fragment.jsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import BaseComponent from './BaseComponent';
|
|
3
|
-
import { FRAGMENT_DEFAULT_REGION_NAME } from '../utils';
|
|
2
|
+
import BaseComponent, { MissingComponent, shouldShowMissingView } from './BaseComponent';
|
|
3
|
+
import { FRAGMENT_DEFAULT_REGION_NAME, XP_COMPONENT_TYPE } from '../utils';
|
|
4
4
|
const FragmentView = (props) => {
|
|
5
5
|
var _a;
|
|
6
6
|
const { component, page } = props;
|
|
@@ -13,13 +13,18 @@ const FragmentView = (props) => {
|
|
|
13
13
|
comps.push(...regionComps);
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
-
else if (component) {
|
|
16
|
+
else if (component === null || component === void 0 ? void 0 : component.fragment) {
|
|
17
17
|
// rendering a part of a page
|
|
18
18
|
comps.push(...component.fragment.components);
|
|
19
19
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
if (!comps.length && shouldShowMissingView(props.meta)) {
|
|
21
|
+
return <MissingComponent type={XP_COMPONENT_TYPE.FRAGMENT} descriptor={(page === null || page === void 0 ? void 0 : page.descriptor) || (component === null || component === void 0 ? void 0 : component.id)}/>;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
const { common, meta } = props;
|
|
25
|
+
return (<>
|
|
26
|
+
{comps.map((comp, i) => (<BaseComponent key={i} component={comp} common={common} meta={meta}/>))}
|
|
27
|
+
</>);
|
|
28
|
+
}
|
|
24
29
|
};
|
|
25
30
|
export default FragmentView;
|
package/views/MainView.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import { FetchContentResult } from '../guillotine/fetchContent';
|
|
3
|
-
declare const _MainView: (props: FetchContentResult) => JSX.Element;
|
|
3
|
+
declare const _MainView: (props: FetchContentResult) => React.JSX.Element;
|
|
4
4
|
export default _MainView;
|
package/views/Region.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import { MetaData, PageComponent, PageData } from '../guillotine/getMetaData';
|
|
3
3
|
export interface RegionProps {
|
|
4
4
|
name: string;
|
|
@@ -14,7 +14,7 @@ export interface RegionsProps {
|
|
|
14
14
|
meta: MetaData;
|
|
15
15
|
}
|
|
16
16
|
/** Single region */
|
|
17
|
-
export declare const RegionView: (props: RegionProps) => JSX.Element;
|
|
17
|
+
export declare const RegionView: (props: RegionProps) => React.JSX.Element;
|
|
18
18
|
/** Multiple regions, or only one if named in props.selected */
|
|
19
|
-
declare const RegionsView: (props: RegionsProps) => JSX.Element;
|
|
19
|
+
declare const RegionsView: (props: RegionsProps) => React.JSX.Element;
|
|
20
20
|
export default RegionsView;
|
package/views/RichTextView.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import { MetaData, RichTextData } from '../guillotine/getMetaData';
|
|
3
3
|
import { DOMNode } from 'html-react-parser';
|
|
4
4
|
export type ReplacerResult = JSX.Element | object | void | undefined | null | false;
|
|
@@ -12,5 +12,5 @@ type Props = {
|
|
|
12
12
|
customReplacer?: Replacer;
|
|
13
13
|
};
|
|
14
14
|
export declare function createReplacer(allData: RichTextData, meta: MetaData, renderMacroInEditMode?: boolean, customReplacer?: Replacer): (domNode: DOMNode) => ReplacerResult;
|
|
15
|
-
declare const RichTextView: ({ className, tag, data, meta, renderMacroInEditMode, customReplacer }: Props) => JSX.Element;
|
|
15
|
+
declare const RichTextView: ({ className, tag, data, meta, renderMacroInEditMode, customReplacer }: Props) => React.JSX.Element;
|
|
16
16
|
export default RichTextView;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Render only one component as a result of a request from XP-side .../_/component/... during edit refresh. */
|
|
2
|
-
|
|
2
|
+
import React from 'react';
|
|
3
3
|
import { FetchContentResult } from '../guillotine/fetchContent';
|
|
4
|
-
declare const SingleComponent: ({ meta, common }: FetchContentResult) => JSX.Element;
|
|
4
|
+
declare const SingleComponent: ({ meta, common }: FetchContentResult) => React.JSX.Element;
|
|
5
5
|
export default SingleComponent;
|