@sap-ux/preview-middleware 1.1.3 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -29
- package/dist/base/config.d.ts +55 -2
- package/dist/base/config.js +158 -26
- package/dist/base/flp.d.ts +24 -0
- package/dist/base/flp.js +116 -18
- package/dist/client/adp/api-handler.js +5 -1
- package/dist/client/adp/api-handler.ts +11 -4
- package/dist/client/adp/controllers/ControllerExtension.controller.js +95 -35
- package/dist/client/adp/controllers/ControllerExtension.controller.ts +121 -42
- package/dist/client/adp/extend-controller.ts +1 -0
- package/dist/client/adp/quick-actions/common/add-controller-to-page.js +2 -2
- package/dist/client/adp/quick-actions/common/add-controller-to-page.ts +2 -2
- package/dist/client/adp/quick-actions/fe-v4/create-page-action.js +3 -2
- package/dist/client/adp/quick-actions/fe-v4/create-page-action.ts +3 -2
- package/dist/client/adp/quick-actions/fe-v4/create-table-action-config-change.js +3 -2
- package/dist/client/adp/quick-actions/fe-v4/create-table-action-config-change.ts +3 -2
- package/dist/client/adp/ui/ControllerExtension.fragment.xml +33 -6
- package/dist/client/adp/utils.js +73 -5
- package/dist/client/adp/utils.ts +84 -5
- package/dist/client/flp/WorkspaceConnector.js +7 -5
- package/dist/client/flp/WorkspaceConnector.ts +7 -5
- package/dist/client/flp/common.js +293 -1
- package/dist/client/flp/common.ts +344 -1
- package/dist/client/flp/sandbox1Init.js +187 -0
- package/dist/client/flp/sandbox1Init.ts +174 -0
- package/dist/client/flp/sandbox2AfterInit.js +66 -0
- package/dist/client/flp/sandbox2AfterInit.ts +63 -0
- package/dist/client/flp/sandbox2BeforeInit.js +67 -0
- package/dist/client/flp/sandbox2BeforeInit.ts +60 -0
- package/dist/client/messagebundle.properties +3 -0
- package/dist/types/index.d.ts +21 -0
- package/package.json +3 -3
- package/templates/flp/cdm.ejs +1 -1
- package/templates/flp/sandbox.ejs +1 -1
- package/templates/flp/sandbox2.ejs +12 -44
- package/dist/client/flp/init.js +0 -465
- package/dist/client/flp/init.ts +0 -498
package/README.md
CHANGED
|
@@ -15,36 +15,38 @@ When this middleware is used together with the `reload-middleware`, then the ord
|
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
## [Configuration Options](#configuration-options)
|
|
18
|
-
| Option
|
|
19
|
-
|
|
20
|
-
| `flp`
|
|
21
|
-
| `flp.path`
|
|
22
|
-
| `flp.init`
|
|
23
|
-
| `flp.intent`
|
|
24
|
-
| `flp.intent.object`
|
|
25
|
-
| `flp.intent.action`
|
|
26
|
-
| `flp.apps`
|
|
27
|
-
| `flp.libs`
|
|
28
|
-
| `flp.theme`
|
|
29
|
-
| `flp.enhancedHomePage`
|
|
30
|
-
| `
|
|
31
|
-
| `
|
|
32
|
-
| `adp.
|
|
33
|
-
| `
|
|
34
|
-
| `
|
|
35
|
-
| `
|
|
36
|
-
| `editors
|
|
37
|
-
| `editors.rta
|
|
38
|
-
| `editors.
|
|
39
|
-
| `editors.
|
|
40
|
-
| `
|
|
41
|
-
| `
|
|
18
|
+
| Option | Value Type | Requirement Type | Default Value | Description |
|
|
19
|
+
|------------------------------|------------|------------------------------------------------|---------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
20
|
+
| `flp` | --- | optional | --- | Configuration object for the local SAP Fiori launchpad |
|
|
21
|
+
| `flp.path` | `string` | optional | `/test/flp.html` | The mount point of the local SAP Fiori launchpad. In case no file is found at the given path, a virtual endpoint will be instantiated. |
|
|
22
|
+
| `flp.init` | `string` | optional | `undefined` | UI5 module/script to be executed after the standard initialization |
|
|
23
|
+
| `flp.intent` | --- | optional | --- | Intent object to be used for the application |
|
|
24
|
+
| `flp.intent.object` | `string` | optional | `app` | Name of the semantic object |
|
|
25
|
+
| `flp.intent.action` | `string` | optional | `preview` | Name of the action |
|
|
26
|
+
| `flp.apps` | `array` | optional | `undefined` | Additional local apps that are available in the local SAP Fiori launchpad |
|
|
27
|
+
| `flp.libs` | `boolean` | optional | `false` | Flag to add a generic script fetching the paths of used libraries not available in UI5. To disable it, set it to `false`. If not set, then the project is checked for a `load-reuse-libs` script and, if available, the libraries are fetched as well |
|
|
28
|
+
| `flp.theme` | `string` | optional | `(calculated)` | Name of the UI5 theme to be used (default is `sap_horizon` or the first entry in the sap.ui.supportedThemes list provided in the manifest.json file if `sap_horizon` is not contained in the list) |
|
|
29
|
+
| `flp.enhancedHomePage` | `boolean` | optional | `false` | Flag for enabling enhanced FLP homepage, available only from UI5 version 1.123.0 onwards |
|
|
30
|
+
| `flp.useNewSandbox` | `boolean` | optional | `false` | Set to `true` to opt in to the new FLP Sandbox instead of using the classic sandbox. Only has an effect when the UI5 version qualifies (>= 1.151 or legacy-free) |
|
|
31
|
+
| `flp.navigateToApp` | `boolean` | optional | `false` | Only applies when the new FLP Sandbox is active. Set to `true` to navigate directly to the app on startup instead of showing the FLP home screen first. |
|
|
32
|
+
| `adp.target` | --- | mandatory for adaptation projects | --- | Configuration object defining the connected back end |
|
|
33
|
+
| `adp.ignoreCertErrors` | `boolean` | optional | `false` | Flag to ignore certification validation errors when working with development systems with self-signed certificates, for example |
|
|
34
|
+
| `adp.cfBuildPath` | `string` | optional (experimental, CF only) | `undefined` | **Experimental**: For CF ADP projects only. Path to build output folder (e.g., `dist`) to serve built resources directly. When set, the middleware serves static files from this path and reads manifest.json from it. |
|
|
35
|
+
| `rta` | --- | 🚫 deprecated</br> *use `editors.rta` instead* | --- | Configuration allowing to add mount points for runtime adaptation |
|
|
36
|
+
| `editors` | `array` | optional | `undefined` | List of configurations allowing to add mount points for additional editors |
|
|
37
|
+
| `editors.rta` | `array` | optional | `undefined` | Configuration allowing to add mount points for runtime adaptation |
|
|
38
|
+
| `editors.rta.layer` | `string` | optional | `(calculated)` | Property for defining the runtime adaptation layer for changes (default is `CUSTOMER_BASE` or read from the project for adaptation projects) |
|
|
39
|
+
| `editors.rta.endpoints` | `array` | optional | `undefined` | List of mount points for editing |
|
|
40
|
+
| `editors.cardGenerator` | --- | optional | `undefined` | Configuration object that enables card generation for an application. The generated cards are only available when the application is deployed to an ABAP-based SAP Fiori launchpad, such as SAP Fiori launchpad in SAP S/4HANA Cloud Public Edition. Available only from UI5 version 1.149.0 onwards for CAP node apps and from UI5 version 1.121.0 onwards for ABAP backends |
|
|
41
|
+
| `editors.cardGenerator.path` | `string` | optional | `test/flpGeneratorSandbox.html` | The mount point of the local SAP Fiori launchpad which will be considered for card generation. |
|
|
42
|
+
| `test` | `array` | optional | `undefined` | List of configurations for automated testing. |
|
|
43
|
+
| `debug` | `boolean` | optional | `false` | Enables the debug output |
|
|
42
44
|
|
|
43
45
|
### [`flp.apps`](#configuration-option-flpapps)
|
|
44
46
|
Array of additional application configurations:
|
|
45
47
|
|
|
46
48
|
| Option | Value Type | Requirement Type | Default Value | Description |
|
|
47
|
-
|
|
49
|
+
|--------------------------|------------|------------------|----------------|-------------------------------------------------------------------------------------------------------------|
|
|
48
50
|
| `target` | `string` | mandatory | `undefined` | Target path of the additional application |
|
|
49
51
|
| `local` or `componentId` | `string` | mandatory | `undefined` | Either a local path to a folder containing the application or the `componentId` of a remote app is required |
|
|
50
52
|
| `intent` | --- | optional | --- | Intent object to be used for the application |
|
|
@@ -53,15 +55,15 @@ Array of additional application configurations:
|
|
|
53
55
|
|
|
54
56
|
### [`adp.target`](#configuration-option-adptarget)
|
|
55
57
|
| Option | Value Type | Requirement Type | Default Value | Description |
|
|
56
|
-
|
|
58
|
+
|---------------|------------|-----------------------|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
57
59
|
| `url` | `string` | mandatory (local) | `undefined` | Mandatory URL pointing to the back-end system. *Not required if destination is provided and the proxy is running SAP Business Application Studio |
|
|
58
60
|
| `destination` | `string` | mandatory (if no URL) | `undefined` | Required if the back-end system is available as destination in SAP Business Application Studio. |
|
|
59
|
-
| `client` | `string` | optional | `undefined`
|
|
61
|
+
| `client` | `string` | optional | `undefined` | Parameter for the SAP client |
|
|
60
62
|
| `scp` | `boolean` | optional | `false` | Flag to execute the required OAuth routine for the ABAP environment on SAP BTP |
|
|
61
63
|
|
|
62
64
|
### [`editors`](#configuration-option-editors)
|
|
63
|
-
| Option | Value Type | Requirement Type | Default Value | Description
|
|
64
|
-
|
|
65
|
+
| Option | Value Type | Requirement Type | Default Value | Description |
|
|
66
|
+
|-------------------------------|------------|------------------|---------------|-----------------------------------------------------------------------------------------------|
|
|
65
67
|
| `rta.endpoints.path` | `string` | mandatory | `undefined` | The mount point to be used for the editor. |
|
|
66
68
|
| `rta.endpoints.developerMode` | `boolean` | optional | `false` | Flag to enable the runtime adaptation developer mode (only supported for adaptation projects) |
|
|
67
69
|
|
package/dist/base/config.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ToolsLogger, type Logger } from '@sap-ux/logger';
|
|
2
|
-
import type { App, DefaultFlpPath, DefaultIntent, FlpConfig, Intent, CompleteTestConfig, MiddlewareConfig, RtaConfig, TestConfig } from '../types/index.js';
|
|
2
|
+
import type { App, DefaultFlpPath, DefaultIntent, FlpConfig, Intent, CompleteTestConfig, MiddlewareConfig, RtaConfig, TestConfig, Ui5Version } from '../types/index.js';
|
|
3
3
|
import { type Manifest, type UI5FlexLayer } from '@sap-ux/project-access';
|
|
4
4
|
import { type Editor } from 'mem-fs-editor';
|
|
5
5
|
import type { MergedAppDescriptor } from '@sap-ux/axios-extension';
|
|
@@ -8,6 +8,19 @@ export interface CustomConnector {
|
|
|
8
8
|
writeConnector: string;
|
|
9
9
|
custom: boolean;
|
|
10
10
|
}
|
|
11
|
+
export interface SandboxAppConfig {
|
|
12
|
+
tiles: {
|
|
13
|
+
semanticObject: string;
|
|
14
|
+
action: string;
|
|
15
|
+
rootPath: string;
|
|
16
|
+
}[];
|
|
17
|
+
rootIntent?: string;
|
|
18
|
+
beforeFlpStart: string;
|
|
19
|
+
afterFlpStart: string;
|
|
20
|
+
restricted: {
|
|
21
|
+
flexibilityServices: (CustomConnector | FlexConnector)[];
|
|
22
|
+
};
|
|
23
|
+
}
|
|
11
24
|
export interface FlexConnector {
|
|
12
25
|
connector: string;
|
|
13
26
|
layers: string[];
|
|
@@ -39,11 +52,31 @@ export interface TemplateConfig {
|
|
|
39
52
|
applicationDependencies?: MergedAppDescriptor;
|
|
40
53
|
}>;
|
|
41
54
|
ui5: {
|
|
55
|
+
/**
|
|
56
|
+
* Comma-separated list of UI5 libraries to preload.
|
|
57
|
+
*
|
|
58
|
+
* @remarks Not rendered in sandbox2.ejs — the Sandbox 2.0 bootstrap manages its own library loading.
|
|
59
|
+
*/
|
|
42
60
|
libs: string;
|
|
43
61
|
theme: string;
|
|
62
|
+
/**
|
|
63
|
+
* Flexibility service connector configuration.
|
|
64
|
+
*
|
|
65
|
+
* @remarks Rendered in sandbox.ejs as `data-sap-ui-flexibilityServices` for sandbox 1.
|
|
66
|
+
* Not used by sandbox 2 — `generateSandboxAppConfig` calls `getFlexSettings()` independently
|
|
67
|
+
* to populate `restricted.flexibilityServices` in the fioriSandboxAppConfig.json endpoint.
|
|
68
|
+
*/
|
|
44
69
|
flex: (CustomConnector | FlexConnector)[];
|
|
45
70
|
bootstrapOptions: string;
|
|
46
71
|
resources: Record<string, string>;
|
|
72
|
+
/**
|
|
73
|
+
* Major version of the UI5 framework being used.
|
|
74
|
+
*
|
|
75
|
+
* @remarks Mutated per request in flpGetHandler based on the resolved UI5 version.
|
|
76
|
+
* Used by sandbox2.ejs to conditionally include SandboxBootTask.js (major 1) or
|
|
77
|
+
* data-sap-ui-boot-manifest (major 2).
|
|
78
|
+
*/
|
|
79
|
+
versionMajor: number;
|
|
47
80
|
};
|
|
48
81
|
init?: string;
|
|
49
82
|
flexSettings?: {
|
|
@@ -158,9 +191,11 @@ export declare function remapResourcesForPath(config: TemplateConfig, newPagePat
|
|
|
158
191
|
* @param manifest application manifest
|
|
159
192
|
* @param resources additional resources
|
|
160
193
|
* @param isAdp whether this is an adaptation project
|
|
194
|
+
* @param isCap whether this is a CAP project
|
|
195
|
+
* @param logger optional logger instance
|
|
161
196
|
* @returns configuration object for the sandbox.html template
|
|
162
197
|
*/
|
|
163
|
-
export declare function createFlpTemplateConfig(config: FlpConfig, manifest: Partial<Manifest>, resources?: Record<string, string>, isAdp?: boolean): TemplateConfig;
|
|
198
|
+
export declare function createFlpTemplateConfig(config: FlpConfig, manifest: Partial<Manifest>, resources?: Record<string, string>, isAdp?: boolean, isCap?: boolean, logger?: Logger): TemplateConfig;
|
|
164
199
|
/**
|
|
165
200
|
* Creates the configuration object for the test template.
|
|
166
201
|
*
|
|
@@ -170,6 +205,17 @@ export declare function createFlpTemplateConfig(config: FlpConfig, manifest: Par
|
|
|
170
205
|
* @returns configuration object for the test template
|
|
171
206
|
*/
|
|
172
207
|
export declare function createTestTemplateConfig(config: CompleteTestConfig, id: string, theme: string): TestTemplateConfig;
|
|
208
|
+
/**
|
|
209
|
+
* Generates the fioriSandboxAppConfig.json content for Sandbox 2.0.
|
|
210
|
+
*
|
|
211
|
+
* @param templateConfig the current template configuration containing apps
|
|
212
|
+
* @param flpConfig the FLP configuration containing the intent
|
|
213
|
+
* @param isAdp whether this is an adaptation project - LocalStorageConnector is omitted for ADP
|
|
214
|
+
* @param isCap whether this is a CAP project
|
|
215
|
+
* @param logger optional logger instance
|
|
216
|
+
* @returns the sandbox app config object
|
|
217
|
+
*/
|
|
218
|
+
export declare function generateSandboxAppConfig(templateConfig: TemplateConfig, flpConfig: FlpConfig, isAdp?: boolean, isCap?: boolean, logger?: Logger): SandboxAppConfig;
|
|
173
219
|
/**
|
|
174
220
|
* Returns the preview paths.
|
|
175
221
|
*
|
|
@@ -178,6 +224,13 @@ export declare function createTestTemplateConfig(config: CompleteTestConfig, id:
|
|
|
178
224
|
* @returns an array of preview paths
|
|
179
225
|
*/
|
|
180
226
|
export declare function getPreviewPaths(config: MiddlewareConfig, logger?: ToolsLogger): PreviewUrls[];
|
|
227
|
+
/**
|
|
228
|
+
* Returns true if the given UI5 version qualifies for the new FLP Sandbox (2.0).
|
|
229
|
+
*
|
|
230
|
+
* @param ui5Version - the UI5 version to check
|
|
231
|
+
* @returns true if the version qualifies for the new sandbox
|
|
232
|
+
*/
|
|
233
|
+
export declare function qualifiesForNewSandbox(ui5Version: Ui5Version): boolean;
|
|
181
234
|
/**
|
|
182
235
|
* Generates the preview files.
|
|
183
236
|
*
|
package/dist/base/config.js
CHANGED
|
@@ -2,7 +2,7 @@ import { ToolsLogger } from '@sap-ux/logger';
|
|
|
2
2
|
import { render } from 'ejs';
|
|
3
3
|
import { dirname, join, posix, resolve } from 'node:path';
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
|
-
import { createProjectAccess, getWebappPath } from '@sap-ux/project-access';
|
|
5
|
+
import { createProjectAccess, getWebappPath, getMinimumUI5Version, getProjectType } from '@sap-ux/project-access';
|
|
6
6
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
7
|
import { extractDoubleCurlyBracketsKey } from '@sap-ux/i18n';
|
|
8
8
|
import { readFileSync } from 'node:fs';
|
|
@@ -111,7 +111,9 @@ export function getFlpConfigWithDefaults(config = {}) {
|
|
|
111
111
|
libs: config.libs,
|
|
112
112
|
theme: config.theme,
|
|
113
113
|
init: config.init,
|
|
114
|
-
enhancedHomePage: config.enhancedHomePage === true
|
|
114
|
+
enhancedHomePage: config.enhancedHomePage === true,
|
|
115
|
+
useNewSandbox: config.useNewSandbox === true,
|
|
116
|
+
navigateToApp: config.navigateToApp === true
|
|
115
117
|
};
|
|
116
118
|
if (!flpConfig.path.startsWith('/')) {
|
|
117
119
|
flpConfig.path = `/${flpConfig.path}`;
|
|
@@ -165,20 +167,32 @@ export function sanitizeRtaConfig(deprecatedRtaConfig, logger) {
|
|
|
165
167
|
* Retrieves the configuration settings for UI5 flexibility services.
|
|
166
168
|
*
|
|
167
169
|
* @param isAdp whether this is an adaptation project - LocalStorageConnector is omitted for ADP
|
|
170
|
+
* @param isCap whether this is a CAP project - LrepConnector is omitted for CAP
|
|
171
|
+
* @param logger optional logger instance
|
|
168
172
|
* @returns An array of flexibility service configurations, each specifying a connector
|
|
169
173
|
* and its options, such as the layers it applies to and its service URL, if applicable.
|
|
170
174
|
*/
|
|
171
|
-
function getFlexSettings(isAdp = false) {
|
|
175
|
+
function getFlexSettings(isAdp = false, isCap = false, logger) {
|
|
172
176
|
const localConnectorPath = 'open/ux/preview/client/flp/WorkspaceConnector';
|
|
177
|
+
if (isCap) {
|
|
178
|
+
logger?.debug(`The ABAP connector is not being used because this is a CAP project.`);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
logger?.debug(`The ABAP connector is being used.`);
|
|
182
|
+
}
|
|
173
183
|
const connectors = [
|
|
174
|
-
{ connector: 'LrepConnector', layers: [], url: '/sap/bc/lrep' },
|
|
184
|
+
...(!isCap ? [{ connector: 'LrepConnector', layers: [], url: '/sap/bc/lrep' }] : []),
|
|
175
185
|
{
|
|
176
186
|
applyConnector: localConnectorPath,
|
|
177
187
|
writeConnector: localConnectorPath,
|
|
178
188
|
custom: true
|
|
179
189
|
}
|
|
180
190
|
];
|
|
181
|
-
if (
|
|
191
|
+
if (isAdp) {
|
|
192
|
+
logger?.debug(`The local storage connector is not being used because this is an ADP project.`);
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
logger?.debug(`The local storage connector is being used.`);
|
|
182
196
|
connectors.push({ connector: 'LocalStorageConnector', layers: ['CUSTOMER', 'USER'] });
|
|
183
197
|
}
|
|
184
198
|
return connectors;
|
|
@@ -284,10 +298,12 @@ export function remapResourcesForPath(config, newPagePath, appId) {
|
|
|
284
298
|
* @param manifest application manifest
|
|
285
299
|
* @param resources additional resources
|
|
286
300
|
* @param isAdp whether this is an adaptation project
|
|
301
|
+
* @param isCap whether this is a CAP project
|
|
302
|
+
* @param logger optional logger instance
|
|
287
303
|
* @returns configuration object for the sandbox.html template
|
|
288
304
|
*/
|
|
289
|
-
export function createFlpTemplateConfig(config, manifest, resources = {}, isAdp = false) {
|
|
290
|
-
const flex = getFlexSettings(isAdp);
|
|
305
|
+
export function createFlpTemplateConfig(config, manifest, resources = {}, isAdp = false, isCap = false, logger) {
|
|
306
|
+
const flex = getFlexSettings(isAdp, isCap, logger);
|
|
291
307
|
const supportedThemes = manifest['sap.ui5']?.supportedThemes ?? [DEFAULT_THEME];
|
|
292
308
|
const ui5Theme = config.theme ?? (supportedThemes.includes(DEFAULT_THEME) ? DEFAULT_THEME : supportedThemes[0]);
|
|
293
309
|
const id = manifest['sap.app']?.id ?? '';
|
|
@@ -311,7 +327,8 @@ export function createFlpTemplateConfig(config, manifest, resources = {}, isAdp
|
|
|
311
327
|
...resources,
|
|
312
328
|
[PREVIEW_URL.client.ns]: PREVIEW_URL.client.getUrl(basePath)
|
|
313
329
|
},
|
|
314
|
-
bootstrapOptions: ''
|
|
330
|
+
bootstrapOptions: '',
|
|
331
|
+
versionMajor: 1
|
|
315
332
|
},
|
|
316
333
|
locateReuseLibsScript: config.libs,
|
|
317
334
|
enhancedHomePage: config.enhancedHomePage,
|
|
@@ -335,6 +352,52 @@ export function createTestTemplateConfig(config, id, theme) {
|
|
|
335
352
|
theme
|
|
336
353
|
};
|
|
337
354
|
}
|
|
355
|
+
/**
|
|
356
|
+
* Generates the fioriSandboxAppConfig.json content for Sandbox 2.0.
|
|
357
|
+
*
|
|
358
|
+
* @param templateConfig the current template configuration containing apps
|
|
359
|
+
* @param flpConfig the FLP configuration containing the intent
|
|
360
|
+
* @param isAdp whether this is an adaptation project - LocalStorageConnector is omitted for ADP
|
|
361
|
+
* @param isCap whether this is a CAP project
|
|
362
|
+
* @param logger optional logger instance
|
|
363
|
+
* @returns the sandbox app config object
|
|
364
|
+
*/
|
|
365
|
+
export function generateSandboxAppConfig(templateConfig, flpConfig, isAdp = false, isCap = false, logger) {
|
|
366
|
+
// Build a url→intent map: primary app + additional apps with explicit intent
|
|
367
|
+
const intentByUrl = new Map();
|
|
368
|
+
intentByUrl.set(templateConfig.apps[`${flpConfig.intent.object}-${flpConfig.intent.action}`]?.url ?? '', flpConfig.intent);
|
|
369
|
+
for (const app of flpConfig.apps) {
|
|
370
|
+
if (app.intent) {
|
|
371
|
+
intentByUrl.set(app.target, app.intent);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
const tiles = Object.entries(templateConfig.apps).map(([appName, app]) => {
|
|
375
|
+
const rootPath = app.url.endsWith('/') ? app.url : `${app.url}/`;
|
|
376
|
+
const knownIntent = intentByUrl.get(app.url);
|
|
377
|
+
if (knownIntent) {
|
|
378
|
+
return { semanticObject: knownIntent.object, action: knownIntent.action, rootPath };
|
|
379
|
+
}
|
|
380
|
+
// Fallback for additional apps without explicit intent: appName is built by getAppName() as
|
|
381
|
+
// "<semanticObject>-<action>" where the fallback action is hardcoded to 'preview' (no dashes).
|
|
382
|
+
// lastIndexOf('-') is therefore safe — the last dash is always the object/action separator.
|
|
383
|
+
// If the fallback action ever contained a dash (e.g. 'my-preview'), this split would be wrong.
|
|
384
|
+
const dashIndex = appName.lastIndexOf('-');
|
|
385
|
+
const semanticObject = dashIndex === -1 ? appName : appName.substring(0, dashIndex);
|
|
386
|
+
const action = dashIndex === -1 ? '' : appName.substring(dashIndex + 1);
|
|
387
|
+
return { semanticObject, action, rootPath };
|
|
388
|
+
});
|
|
389
|
+
return {
|
|
390
|
+
tiles,
|
|
391
|
+
...(flpConfig.navigateToApp && {
|
|
392
|
+
rootIntent: `${flpConfig.intent.object}-${flpConfig.intent.action}`
|
|
393
|
+
}),
|
|
394
|
+
beforeFlpStart: 'module:open/ux/preview/client/flp/sandbox2BeforeInit',
|
|
395
|
+
afterFlpStart: 'module:open/ux/preview/client/flp/sandbox2AfterInit',
|
|
396
|
+
restricted: {
|
|
397
|
+
flexibilityServices: getFlexSettings(isAdp, isCap, logger)
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
}
|
|
338
401
|
/**
|
|
339
402
|
* Returns the preview paths.
|
|
340
403
|
*
|
|
@@ -399,6 +462,83 @@ function generateTestRunners(configs, manifest, fs, webappPath, flpTemplConfig)
|
|
|
399
462
|
}
|
|
400
463
|
}
|
|
401
464
|
}
|
|
465
|
+
/**
|
|
466
|
+
* Generates the sandbox 2 HTML file and the companion fioriSandboxAppConfig.json.
|
|
467
|
+
* Also sets versionMajor on the template config based on the manifest minUI5Version.
|
|
468
|
+
*
|
|
469
|
+
* @param flpPath - absolute path of the FLP HTML file to write
|
|
470
|
+
* @param flpTemplConfig - the template configuration (mutated: versionMajor is set)
|
|
471
|
+
* @param flpConfig - the resolved FLP configuration
|
|
472
|
+
* @param manifest - the app manifest (must contain a valid minUI5Version)
|
|
473
|
+
* @param isAdp - whether this is an adaptation project
|
|
474
|
+
* @param isCap - whether this is a CAP project
|
|
475
|
+
* @param logger - optional logger instance
|
|
476
|
+
* @param fs - file system editor
|
|
477
|
+
*/
|
|
478
|
+
function generateSandbox2Files(flpPath, flpTemplConfig, flpConfig, manifest, isAdp, isCap, logger, fs) {
|
|
479
|
+
const [major] = getMinimumUI5Version(manifest).split('.').map(Number);
|
|
480
|
+
flpTemplConfig.ui5.versionMajor = major;
|
|
481
|
+
fs.write(join(dirname(flpPath), 'fioriSandboxAppConfig.json'), JSON.stringify(generateSandboxAppConfig(flpTemplConfig, flpConfig, isAdp, isCap, logger), null, 4));
|
|
482
|
+
fs.write(flpPath, render(readFileSync(join(TEMPLATE_PATH, 'flp/sandbox2.ejs'), 'utf-8'), flpTemplConfig));
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Returns true if sandbox 2 should be used for static file generation.
|
|
486
|
+
* Requires: useNewSandbox opted in, no legacy fioriSandboxConfig.json, enhancedHomePage not set, and manifest minUI5Version >= 1.150.
|
|
487
|
+
*
|
|
488
|
+
* @param manifest - the app manifest, if available
|
|
489
|
+
* @param flpConfig - the resolved FLP configuration
|
|
490
|
+
* @param basePath - path to the application root
|
|
491
|
+
* @param fs - file system editor
|
|
492
|
+
* @returns true if sandbox 2 files should be generated
|
|
493
|
+
*/
|
|
494
|
+
function shouldUseSandbox2(manifest, flpConfig, basePath, fs) {
|
|
495
|
+
if (flpConfig.useNewSandbox !== true || flpConfig.enhancedHomePage || !manifest) {
|
|
496
|
+
return false;
|
|
497
|
+
}
|
|
498
|
+
if (fs.exists(join(basePath, 'appconfig/fioriSandboxConfig.json'))) {
|
|
499
|
+
return false;
|
|
500
|
+
}
|
|
501
|
+
const minVersion = getMinimumUI5Version(manifest);
|
|
502
|
+
if (!minVersion) {
|
|
503
|
+
return false;
|
|
504
|
+
}
|
|
505
|
+
const [major, minor] = minVersion.split('.').map(Number);
|
|
506
|
+
return qualifiesForNewSandbox({ major, minor, patch: 0, isCdn: false });
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Returns true if the given UI5 version qualifies for the new FLP Sandbox (2.0).
|
|
510
|
+
*
|
|
511
|
+
* @param ui5Version - the UI5 version to check
|
|
512
|
+
* @returns true if the version qualifies for the new sandbox
|
|
513
|
+
*/
|
|
514
|
+
export function qualifiesForNewSandbox(ui5Version) {
|
|
515
|
+
return (ui5Version.major > 1 ||
|
|
516
|
+
ui5Version.label?.includes('legacy-free') === true ||
|
|
517
|
+
(ui5Version.major === 1 && ui5Version.minor >= 151));
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Adds additional apps from flpConfig.apps to the template configuration.
|
|
521
|
+
*
|
|
522
|
+
* @param flpConfig - the resolved FLP configuration
|
|
523
|
+
* @param basePath - path to the application root
|
|
524
|
+
* @param flpTemplConfig - the template configuration to extend
|
|
525
|
+
* @param fs - file system editor
|
|
526
|
+
* @param logger - logger instance
|
|
527
|
+
*/
|
|
528
|
+
async function addAdditionalApps(flpConfig, basePath, flpTemplConfig, fs, logger) {
|
|
529
|
+
for (const app of flpConfig.apps) {
|
|
530
|
+
if (app.local) {
|
|
531
|
+
const appPath = await getWebappPath(join(basePath, app.local), fs);
|
|
532
|
+
if (fs.exists(join(appPath, 'manifest.json'))) {
|
|
533
|
+
const appManifest = (await fs.readJSON(join(appPath, 'manifest.json')));
|
|
534
|
+
await addApp(flpTemplConfig, appManifest, app, logger);
|
|
535
|
+
}
|
|
536
|
+
else {
|
|
537
|
+
logger.warn(`Could not add route for ${app}`);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
}
|
|
402
542
|
/**
|
|
403
543
|
* Generates the preview files.
|
|
404
544
|
*
|
|
@@ -413,9 +553,8 @@ export async function generatePreviewFiles(basePath, config, fs, logger = new To
|
|
|
413
553
|
sanitizeConfig(config, logger);
|
|
414
554
|
// create file system if not provided
|
|
415
555
|
fs ??= create(createStorage());
|
|
416
|
-
// generate FLP configuration
|
|
417
|
-
const flpTemplate = readFileSync(join(TEMPLATE_PATH, 'flp/sandbox.ejs'), 'utf-8');
|
|
418
556
|
const flpConfig = getFlpConfigWithDefaults(config.flp);
|
|
557
|
+
const isCap = (await getProjectType(basePath)) !== 'EDMXBackend';
|
|
419
558
|
const webappPath = await getWebappPath(basePath, fs);
|
|
420
559
|
let manifest;
|
|
421
560
|
if (fs.exists(join(webappPath, 'manifest.json'))) {
|
|
@@ -424,7 +563,7 @@ export async function generatePreviewFiles(basePath, config, fs, logger = new To
|
|
|
424
563
|
let flpTemplConfig;
|
|
425
564
|
let flpPath;
|
|
426
565
|
if (manifest) {
|
|
427
|
-
flpTemplConfig = createFlpTemplateConfig(flpConfig, manifest);
|
|
566
|
+
flpTemplConfig = createFlpTemplateConfig(flpConfig, manifest, {}, false, isCap, logger);
|
|
428
567
|
flpPath = join(webappPath, flpConfig.path);
|
|
429
568
|
await addApp(flpTemplConfig, manifest, {
|
|
430
569
|
target: flpTemplConfig.basePath,
|
|
@@ -434,24 +573,17 @@ export async function generatePreviewFiles(basePath, config, fs, logger = new To
|
|
|
434
573
|
generateTestRunners(config.test, manifest, fs, webappPath, flpTemplConfig);
|
|
435
574
|
}
|
|
436
575
|
else {
|
|
437
|
-
flpTemplConfig = createFlpTemplateConfig(flpConfig, {});
|
|
576
|
+
flpTemplConfig = createFlpTemplateConfig(flpConfig, {}, {}, false, isCap, logger);
|
|
438
577
|
flpPath = join(basePath, flpConfig.path);
|
|
439
578
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
}
|
|
448
|
-
else {
|
|
449
|
-
logger.warn(`Could not add route for ${app}`);
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
}
|
|
579
|
+
await addAdditionalApps(flpConfig, basePath, flpTemplConfig, fs, logger);
|
|
580
|
+
if (shouldUseSandbox2(manifest, flpConfig, basePath, fs)) {
|
|
581
|
+
// manifest is guaranteed non-undefined here: shouldUseSandbox2 returns false when manifest is undefined
|
|
582
|
+
generateSandbox2Files(flpPath, flpTemplConfig, flpConfig, manifest, config.adp !== undefined, isCap, logger, fs);
|
|
583
|
+
}
|
|
584
|
+
else {
|
|
585
|
+
fs.write(flpPath, render(readFileSync(join(TEMPLATE_PATH, 'flp/sandbox.ejs'), 'utf-8'), flpTemplConfig));
|
|
453
586
|
}
|
|
454
|
-
fs.write(flpPath, render(flpTemplate, flpTemplConfig));
|
|
455
587
|
return fs;
|
|
456
588
|
}
|
|
457
589
|
//# sourceMappingURL=config.js.map
|
package/dist/base/flp.d.ts
CHANGED
|
@@ -78,6 +78,7 @@ export declare class FlpSandbox {
|
|
|
78
78
|
* Also deletes the ABAP connector in case of a CAP project.
|
|
79
79
|
* Deletes all connectors if UI5 version is < 1.84 and served from npmjs.
|
|
80
80
|
*
|
|
81
|
+
* @param config - the template config to mutate (must be a per-request clone, not the shared this.templateConfig)
|
|
81
82
|
* @param ui5VersionMajor - the major version of UI5
|
|
82
83
|
* @param ui5VersionMinor - the minor version of UI5
|
|
83
84
|
* @param isCDN - whether the UI5 sources are served from CDN
|
|
@@ -136,6 +137,17 @@ export declare class FlpSandbox {
|
|
|
136
137
|
* @private
|
|
137
138
|
*/
|
|
138
139
|
private flpGetHandler;
|
|
140
|
+
/**
|
|
141
|
+
* Handler for GET requests to fioriSandboxAppConfig.json (Sandbox 2.0).
|
|
142
|
+
* Serves a virtual config, optionally merged with a user-provided file.
|
|
143
|
+
* If a real HTML file exists at the FLP path, no virtual config is served.
|
|
144
|
+
*
|
|
145
|
+
* @param req incoming request
|
|
146
|
+
* @param res server response
|
|
147
|
+
* @param next next middleware function
|
|
148
|
+
* @param configJsonPath project-relative path to fioriSandboxAppConfig.json
|
|
149
|
+
*/
|
|
150
|
+
private sandboxAppConfigGetHandler;
|
|
139
151
|
/**
|
|
140
152
|
* Add routes for html and scripts required for a local FLP.
|
|
141
153
|
*/
|
|
@@ -172,6 +184,7 @@ export declare class FlpSandbox {
|
|
|
172
184
|
private getUi5Version;
|
|
173
185
|
/**
|
|
174
186
|
* Read the sandbox template file based on the given UI5 version.
|
|
187
|
+
* Also checks for a legacy 'appconfig/fioriSandboxConfig.json' and falls back to Sandbox 1 if found.
|
|
175
188
|
*
|
|
176
189
|
* @param ui5Version - the UI5 version
|
|
177
190
|
* @returns the template for the sandbox HTML file
|
|
@@ -182,6 +195,17 @@ export declare class FlpSandbox {
|
|
|
182
195
|
* to load the changes in an Adaptation project.
|
|
183
196
|
*/
|
|
184
197
|
private removeAsyncHintsRequests;
|
|
198
|
+
/**
|
|
199
|
+
* Checks if a legacy 'appconfig/fioriSandboxConfig.json' file is present when using the new FLP Sandbox.
|
|
200
|
+
* If found, warns the user to migrate and returns true so the caller can fall back to the classic Sandbox
|
|
201
|
+
* for this request.
|
|
202
|
+
*
|
|
203
|
+
* @param ui5Version - the resolved UI5 version
|
|
204
|
+
* @param baseUrl - the base URL of the current request
|
|
205
|
+
* @returns true if the legacy file is present and sandbox 2 should be suppressed
|
|
206
|
+
* @private
|
|
207
|
+
*/
|
|
208
|
+
private hasLegacySandboxConfig;
|
|
185
209
|
/**
|
|
186
210
|
* For UI5 versions below 1.120, flexExtensionPointEnabled must be removed from the application
|
|
187
211
|
* dependencies manifest. Older UI5 versions cannot handle this property at bootstrap time.
|