@sap-ux/preview-middleware 0.16.136 → 0.16.137

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.
@@ -53,9 +53,18 @@ export declare class FlpSandbox {
53
53
  * @param adp optional reference to the ADP tooling
54
54
  */
55
55
  init(manifest: Manifest, componentId?: string, resources?: Record<string, string>, adp?: AdpPreview): Promise<void>;
56
+ /**
57
+ * Get the configuration for the developer mode.
58
+ *
59
+ * @param ui5MajorVersion - the major version of UI5
60
+ * @returns the configuration for the developer mode
61
+ * @private
62
+ */
63
+ private getDeveloperModeConfig;
56
64
  /**
57
65
  * Generates the FLP sandbox for an editor.
58
66
  *
67
+ * @param req the request
59
68
  * @param rta runtime authoring configuration
60
69
  * @param editor editor configuration
61
70
  * @returns FLP sandbox html
@@ -78,6 +87,29 @@ export declare class FlpSandbox {
78
87
  * Add routes for html and scripts required for a local FLP.
79
88
  */
80
89
  private addStandardRoutes;
90
+ /**
91
+ * Read the UI5 version.
92
+ * In case of an error, the default UI5 version '1.121.0' is returned.
93
+ *
94
+ * @param protocol - the protocol that should be used to request the UI5 version ('http' or 'https')
95
+ * @param host - the host that should be used to request the UI5 version
96
+ * @param baseUrl - the base path of the request that should be added to the host
97
+ * @returns the template for the sandbox HTML file
98
+ * @private
99
+ */
100
+ private getUi5Version;
101
+ /**
102
+ * Read the sandbox template file based on the given UI5 version.
103
+ *
104
+ * @param ui5MajorVersion - the major version of UI5
105
+ * @returns the template for the sandbox HTML file
106
+ */
107
+ private getSandboxTemplate;
108
+ /**
109
+ * For UI5 version 1.71 and below, the asyncHints.requests need to be removed from the template configuration
110
+ * to load the changes in an Adaptation project.
111
+ */
112
+ private removeAsyncHintsRequests;
81
113
  /**
82
114
  * Try finding a locate-reuse-libs script in the project.
83
115
  *
package/dist/base/flp.js CHANGED
@@ -14,15 +14,6 @@ const feature_toggle_1 = require("@sap-ux/feature-toggle");
14
14
  const flex_1 = require("./flex");
15
15
  const test_1 = require("./test");
16
16
  const config_1 = require("./config");
17
- const DEVELOPER_MODE_CONFIG = new Map([
18
- // Run application in design time mode
19
- // Adds bindingString to BindingInfo objects. Required to create and read PropertyBinding changes
20
- ['xx-designMode', 'true'],
21
- // In design mode, the controller code will not be executed by default, which is not desired in our case, so we suppress the deactivation
22
- ['xx-suppressDeactivationOfControllerCode', 'true'],
23
- // Make sure that XML preprocessing results are correctly invalidated
24
- ['xx-viewCache', 'false']
25
- ]);
26
17
  const DEFAULT_LIVERELOAD_PORT = 35729;
27
18
  /**
28
19
  * Class handling preview of a sandbox FLP.
@@ -101,14 +92,46 @@ class FlpSandbox {
101
92
  this.logger.info(`Initialized for app ${id}`);
102
93
  this.logger.debug(`Configured apps: ${JSON.stringify(this.templateConfig.apps)}`);
103
94
  }
95
+ /**
96
+ * Get the configuration for the developer mode.
97
+ *
98
+ * @param ui5MajorVersion - the major version of UI5
99
+ * @returns the configuration for the developer mode
100
+ * @private
101
+ */
102
+ getDeveloperModeConfig(ui5MajorVersion) {
103
+ if (ui5MajorVersion < 2) {
104
+ return new Map([
105
+ // Run application in design time mode
106
+ // Adds bindingString to BindingInfo objects. Required to create and read PropertyBinding changes
107
+ ['xx-designMode', 'true'],
108
+ // In design mode, the controller code will not be executed by default, which is not desired in our case, so we suppress the deactivation
109
+ ['xx-suppressDeactivationOfControllerCode', 'true'],
110
+ // Make sure that XML preprocessing results are correctly invalidated
111
+ ['xx-viewCache', 'false']
112
+ ]);
113
+ }
114
+ else {
115
+ return new Map([
116
+ // Run application in design time mode
117
+ // Adds bindingString to BindingInfo objects. Required to create and read PropertyBinding changes
118
+ ['xx-design-mode', 'true'],
119
+ // In design mode, the controller code will not be executed by default, which is not desired in our case, so we suppress the deactivation
120
+ ['xx-suppress-deactivation-of-controller-code', 'true'],
121
+ // Make sure that XML preprocessing results are correctly invalidated
122
+ ['xx-view-cache', 'false']
123
+ ]);
124
+ }
125
+ }
104
126
  /**
105
127
  * Generates the FLP sandbox for an editor.
106
128
  *
129
+ * @param req the request
107
130
  * @param rta runtime authoring configuration
108
131
  * @param editor editor configuration
109
132
  * @returns FLP sandbox html
110
133
  */
111
- async generateSandboxForEditor(rta, editor) {
134
+ async generateSandboxForEditor(req, rta, editor) {
112
135
  const defaultGenerator = editor.developerMode
113
136
  ? '@sap-ux/control-property-editor'
114
137
  : '@sap-ux/preview-middleware';
@@ -128,11 +151,14 @@ class FlpSandbox {
128
151
  pluginScript: editor.pluginScript
129
152
  };
130
153
  config.features = feature_toggle_1.FeatureToggleAccess.getAllFeatureToggles();
154
+ const ui5Version = await this.getUi5Version(req.protocol, req.headers.host, req['ui5-patched-router']?.baseUrl);
131
155
  if (editor.developerMode === true) {
132
- config.ui5.bootstrapOptions = serializeUi5Configuration(DEVELOPER_MODE_CONFIG);
156
+ config.ui5.bootstrapOptions = serializeUi5Configuration(this.getDeveloperModeConfig(ui5Version.major));
157
+ }
158
+ if (ui5Version.major === 1 && ui5Version.minor <= 71) {
159
+ this.removeAsyncHintsRequests();
133
160
  }
134
- const template = (0, fs_1.readFileSync)((0, path_1.join)(__dirname, '../../templates/flp/sandbox.html'), 'utf-8');
135
- return (0, ejs_1.render)(template, config);
161
+ return (0, ejs_1.render)(this.getSandboxTemplate(ui5Version.major), config);
136
162
  }
137
163
  /**
138
164
  * Sets application dependencies in the template configuration.
@@ -198,7 +224,7 @@ class FlpSandbox {
198
224
  res.redirect(302, `${previewUrl}?${new URLSearchParams(params)}`);
199
225
  return;
200
226
  }
201
- const html = (await this.generateSandboxForEditor(rta, editor)).replace('</body>', `</body>\n<!-- livereload disabled for editor </body>-->`);
227
+ const html = (await this.generateSandboxForEditor(req, rta, editor)).replace('</body>', `</body>\n<!-- livereload disabled for editor </body>-->`);
202
228
  this.sendResponse(res, 'text/html', 200, html);
203
229
  });
204
230
  }
@@ -209,8 +235,8 @@ class FlpSandbox {
209
235
  addStandardRoutes() {
210
236
  // register static client sources
211
237
  this.router.use(config_1.PREVIEW_URL.client.path, (0, express_1.static)(config_1.PREVIEW_URL.client.local));
212
- // add route for the sandbox.html
213
- this.router.get(this.config.path, (async (_req, res, next) => {
238
+ // add route for the sandbox html
239
+ this.router.get(this.config.path, (async (req, res, next) => {
214
240
  // inform the user if a html file exists on the filesystem
215
241
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
216
242
  const file = await this.project.byPath(this.config.path);
@@ -219,12 +245,69 @@ class FlpSandbox {
219
245
  next();
220
246
  }
221
247
  else {
222
- const template = (0, fs_1.readFileSync)((0, path_1.join)(__dirname, '../../templates/flp/sandbox.html'), 'utf-8');
223
- const html = (0, ejs_1.render)(template, this.templateConfig);
248
+ const ui5Version = await this.getUi5Version(req.protocol, req.headers.host, req['ui5-patched-router']?.baseUrl);
249
+ const html = (0, ejs_1.render)(this.getSandboxTemplate(ui5Version.major), this.templateConfig);
224
250
  this.sendResponse(res, 'text/html', 200, html);
225
251
  }
226
252
  }));
227
253
  }
254
+ /**
255
+ * Read the UI5 version.
256
+ * In case of an error, the default UI5 version '1.121.0' is returned.
257
+ *
258
+ * @param protocol - the protocol that should be used to request the UI5 version ('http' or 'https')
259
+ * @param host - the host that should be used to request the UI5 version
260
+ * @param baseUrl - the base path of the request that should be added to the host
261
+ * @returns the template for the sandbox HTML file
262
+ * @private
263
+ */
264
+ async getUi5Version(protocol, host, baseUrl = '') {
265
+ let version;
266
+ if (!host) {
267
+ this.logger.error('Unable to fetch UI5 version: No host found in request header.');
268
+ }
269
+ else {
270
+ try {
271
+ const versionUrl = `${protocol}://${host}${baseUrl}/resources/sap-ui-version.json`;
272
+ const responseJson = (await fetch(versionUrl).then((res) => res.json()));
273
+ version = responseJson?.libraries?.find((lib) => lib.name === 'sap.ui.core')?.version;
274
+ }
275
+ catch (error) {
276
+ this.logger.error(error);
277
+ }
278
+ }
279
+ if (!version) {
280
+ this.logger.error('Could not get UI5 version of application. Using 1.121.0 as fallback.');
281
+ version = '1.121.0';
282
+ }
283
+ const [major, minor] = version.split('.').map((versionPart) => parseInt(versionPart, 10));
284
+ return {
285
+ major,
286
+ minor
287
+ };
288
+ }
289
+ /**
290
+ * Read the sandbox template file based on the given UI5 version.
291
+ *
292
+ * @param ui5MajorVersion - the major version of UI5
293
+ * @returns the template for the sandbox HTML file
294
+ */
295
+ getSandboxTemplate(ui5MajorVersion) {
296
+ this.logger.info(`Using sandbox template for UI5 major version ${ui5MajorVersion}.`);
297
+ return (0, fs_1.readFileSync)((0, path_1.join)(__dirname, `../../templates/flp/sandbox${ui5MajorVersion === 1 ? '' : ui5MajorVersion}.html`), 'utf-8');
298
+ }
299
+ /**
300
+ * For UI5 version 1.71 and below, the asyncHints.requests need to be removed from the template configuration
301
+ * to load the changes in an Adaptation project.
302
+ */
303
+ removeAsyncHintsRequests() {
304
+ for (const app in this.templateConfig.apps) {
305
+ const appDependencies = this.templateConfig.apps[app].applicationDependencies;
306
+ if (appDependencies?.asyncHints.requests) {
307
+ appDependencies.asyncHints.requests = [];
308
+ }
309
+ }
310
+ }
228
311
  /**
229
312
  * Try finding a locate-reuse-libs script in the project.
230
313
  *
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "bugs": {
10
10
  "url": "https://github.com/SAP/open-ux-tools/issues?q=is%3Aopen+is%3Aissue+label%3Abug+label%3Apreview-middleware"
11
11
  },
12
- "version": "0.16.136",
12
+ "version": "0.16.137",
13
13
  "license": "Apache-2.0",
14
14
  "author": "@SAP/ux-tools-team",
15
15
  "main": "dist/index.js",
@@ -46,7 +46,7 @@
46
46
  "supertest": "6.3.3",
47
47
  "@sap-ux-private/playwright": "0.1.0",
48
48
  "dotenv": "16.3.1",
49
- "@private/preview-middleware-client": "npm:@sap-ux-private/preview-middleware-client@0.11.39",
49
+ "@private/preview-middleware-client": "npm:@sap-ux-private/preview-middleware-client@0.11.40",
50
50
  "@sap-ux/axios-extension": "1.17.4",
51
51
  "@sap-ux/store": "0.9.3",
52
52
  "@sap-ux/ui5-info": "0.8.3",
@@ -44,9 +44,8 @@
44
44
  window["data-open-ux-preview-basePath"] = "<%- basePath %>";
45
45
  </script>
46
46
 
47
- <script src="<%- basePath %>/preview/client/flp/bootstrap.js" id="preview-bootstrap"></script>
48
- <script id="sap-ushell-bootstrap"></script>
49
- <!-- Bootstrap the UI5 core library. 'data-sap-ui-frameOptions="allow"'' is a NON-SECURE setting for test environments -->
47
+ <script src="<%- basePath %>/test-resources/sap/ushell/bootstrap/sandbox.js" id="sap-ushell-bootstrap"></script>
48
+ <!-- Bootstrap the UI5 core library. 'data-sap-ui-frameOptions="allow"' is a NON-SECURE setting for test environments -->
50
49
  <script id="sap-ui-bootstrap"
51
50
  src="<%- basePath %>/resources/sap-ui-core.js"
52
51
  data-sap-ui-libs="<%- ui5.libs %>"
@@ -0,0 +1,87 @@
1
+ <!DOCTYPE HTML>
2
+ <html lang="en">
3
+ <!-- Copyright (c) 2015 SAP AG, All Rights Reserved -->
4
+
5
+ <head>
6
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
7
+ <meta charset="UTF-8">
8
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
9
+ <title>Local FLP Sandbox</title>
10
+
11
+ <!-- Bootstrap the unified shell in sandbox mode for standalone usage.
12
+
13
+ The renderer is specified in the global Unified Shell configuration object "sap-ushell-config".
14
+
15
+ The fiori2 renderer will render the shell header allowing, for instance,
16
+ testing of additional application setting buttons.
17
+
18
+ The navigation target resolution service is configured in a way that the empty URL hash is
19
+ resolved to our own application.
20
+
21
+ This example uses relative path references for the SAPUI5 resources and test-resources;
22
+ it might be necessary to adapt them depending on the target runtime platform.
23
+ The sandbox platform is restricted to development or demo use cases and must NOT be used
24
+ for productive scenarios.
25
+ -->
26
+ <script type="text/javascript">
27
+ window["sap-ushell-config"] = {
28
+ defaultRenderer: "fiori2",
29
+ renderers: {
30
+ fiori2: {
31
+ componentData: {
32
+ config: {
33
+ search: "hidden",
34
+ enableSearch: false
35
+ }
36
+ }
37
+ }
38
+ },
39
+ applications: <%- JSON.stringify(apps) %>
40
+ };
41
+ </script>
42
+
43
+ <script type="text/javascript">
44
+ window["data-open-ux-preview-basePath"] = "<%- basePath %>";
45
+ </script>
46
+
47
+ <script src="<%- basePath %>/resources/sap/ushell/bootstrap/sandbox2.js" id="sap-ushell-bootstrap"></script>
48
+ <!-- Bootstrap the UI5 core library. 'data-sap-ui-frameOptions="allow"' is a NON-SECURE setting for test environments -->
49
+ <script id="sap-ui-bootstrap"
50
+ src="<%- basePath %>/resources/sap-ui-core.js"
51
+ data-sap-ui-libs="<%- ui5.libs %>"
52
+ data-sap-ui-async="true"
53
+ data-sap-ui-theme="<%- ui5.theme %>"
54
+ data-sap-ui-compat-version="edge"
55
+ data-sap-ui-language="en"
56
+ data-sap-ui-flexibility-services='<%- JSON.stringify(ui5.flex) %>'
57
+ data-sap-ui-resource-roots='<%- JSON.stringify(ui5.resources) %>'
58
+ data-sap-ui-frame-options="allow"
59
+ data-sap-ui-xx-component-preload="off"<%- ui5.bootstrapOptions %>
60
+ data-sap-ui-on-init="module:open/ux/preview/client/flp/init"<% if (locals.init) { %>
61
+ data-open-ux-preview-customInit='<%- init %>'<% } if (locals.flex) { %>
62
+ data-open-ux-preview-features='<%- JSON.stringify(features) %>'
63
+ data-open-ux-preview-flex-settings='<%- JSON.stringify(flex) %>'<% } if (locals.locateReuseLibsScript) { %>
64
+ data-open-ux-preview-libs-manifests='<%- JSON.stringify(Object.values(apps).map(app => app.url)) %>'<% } %>>
65
+ </script>
66
+
67
+ <% if (locals.flex && flex?.developerMode) { %>
68
+ <!-- Hides Rta native toolbar -->
69
+ <style>
70
+ #shell-header, .sapUiRtaToolbar {
71
+ visibility: hidden;
72
+ height: 1px;
73
+ }
74
+ .sapUshellShellCanvas {
75
+ top: 0 !important;
76
+ }
77
+ .sapUiRtaMode .sapUiShellBackgroundImage.sapUiGlobalBackgroundImageForce.sapUshellShellBG {
78
+ background-color: transparent !important;
79
+ }
80
+ </style><% } %>
81
+ </head>
82
+
83
+ <!-- UI Content -->
84
+ <body class="sapUiBody" id="content">
85
+ </body>
86
+
87
+ </html>
@@ -1,77 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-unsafe-assignment,
2
- @typescript-eslint/no-unsafe-member-access,
3
- @typescript-eslint/no-unsafe-argument,
4
- no-console */
5
-
6
- /**
7
- * Calculates the script content for accessing the right sap/ushell/bootstrap sandbox.
8
- * @param fnCallback {Function} The callback function to be executed after the bootstrap is loaded.
9
- */
10
- async function ushellBootstrap(fnCallback) {
11
- const basePath = window['data-open-ux-preview-basePath'] ?? '';
12
-
13
- let src = `${basePath}/test-resources/sap/ushell/bootstrap/sandbox.js`;
14
- try {
15
- const response = await fetch(`${basePath}/resources/sap-ui-version.json`);
16
- const json = await response.json();
17
- const version = json?.libraries?.find((lib) => lib.name === 'sap.ui.core')?.version ?? '1.121.0';
18
- const [major, minor] = version.split('.');
19
- const majorUi5Version = parseInt(major, 10);
20
- const minorUi5Version = parseInt(minor, 10);
21
- if (majorUi5Version >= 2) {
22
- src = `${basePath}/resources/sap/ushell/bootstrap/sandbox2.js`;
23
- }
24
-
25
- if (majorUi5Version === 1 && minorUi5Version < 72) {
26
- removeAsyncHintsRequests();
27
- }
28
- } catch (error) {
29
- console.warn('Failed to fetch sap-ui-version.json. Assuming it is a 1.x version.');
30
- }
31
-
32
- // eslint-disable-next-line fiori-custom/sap-no-dom-access,fiori-custom/sap-browser-api-warning
33
- const shellBootstrap = document.getElementById('sap-ushell-bootstrap');
34
- if (shellBootstrap) {
35
- shellBootstrap.onload = () => {
36
- window['sap-ui-config']['xx-bootTask'](fnCallback);
37
- };
38
- shellBootstrap.setAttribute('src', src);
39
- }
40
- }
41
-
42
- /**
43
- * For UI5 version 1.71 and below, we need to remove the asyncHints.requests
44
- * to load the changes in an Adaptation project.
45
- * This logic needs to be executed here to have a reliable check for
46
- * UI5 version and remove the asyncHints.requests before the sandbox is loaded.
47
- * The sandbox shell modifies the `window['sap-ushell-config']`.
48
- */
49
- function removeAsyncHintsRequests() {
50
- const obj = window['sap-ushell-config']['applications'];
51
-
52
- if (!obj || typeof obj !== 'object') return;
53
-
54
- const stack = [obj];
55
-
56
- while (stack.length > 0) {
57
- const current = stack.pop();
58
-
59
- if (current.asyncHints) {
60
- if (current.asyncHints.requests) {
61
- current.asyncHints.requests = [];
62
- }
63
- return;
64
- }
65
-
66
- for (const key in current) {
67
- if (typeof current[key] === 'object' && current[key] !== null) {
68
- stack.push(current[key]);
69
- }
70
- }
71
- }
72
- }
73
-
74
- // eslint-disable-next-line fiori-custom/sap-no-global-define
75
- window['sap-ui-config'] = {
76
- 'xx-bootTask': ushellBootstrap
77
- };