@sap-ux/preview-middleware 0.23.63 → 0.23.64

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 CHANGED
@@ -29,6 +29,7 @@ When this middleware is used together with the `reload-middleware`, then the ord
29
29
  | `flp.enhancedHomePage` | `boolean` | optional | `false` | Flag for enabling enhanced FLP homepage, available only from UI5 version 1.123.0 onwards |
30
30
  | `adp.target` | --- | mandatory for adaptation projects | --- | Configuration object defining the connected back end |
31
31
  | `adp.ignoreCertErrors` | `boolean` | optional | `false` | Flag to ignore certification validation errors when working with development systems with self-signed certificates, for example |
32
+ | `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. |
32
33
  | `rta` | --- | 🚫 deprecated</br> *use `editors.rta` instead* | --- | Configuration allowing to add mount points for runtime adaptation |
33
34
  | `editors` | `array` | optional | `undefined` | List of configurations allowing to add mount points for additional editors |
34
35
  | `editors.rta` | `array` | optional | `undefined` | Configuration allowing to add mount points for runtime adaptation |
@@ -171,7 +172,31 @@ server:
171
172
  - path: /test/adaptation-editor.html
172
173
  developerMode: true
173
174
  ```
174
- When the middleware is used in an adaptation project together with a middleware proxying requests to the back end e.g. the `backend-proxy-middleware`, then it is critically important that the `preview-middleware` is handling requests before the back-end proxy because it intercepts requests to the `manifest.json` of the original application and merges it with the local variant.
175
+
176
+ ### [CF ADP Build Path Mode (Experimental)](#cf-adp-build-path-mode-experimental)
177
+ **⚠️ Experimental feature - CF ADP projects only**
178
+
179
+ For Cloud Foundry ADP projects, you can use the `cfBuildPath` option to serve built resources directly from a build output folder. This is useful for testing built applications without requiring backend connectivity.
180
+
181
+ When `cfBuildPath` is set:
182
+ - The middleware serves static files directly from the specified path (e.g., `dist` or `build/dist`)
183
+ - The manifest.json is read from the build output folder
184
+ - Static resources are served directly without backend services
185
+
186
+ **Note:** This feature is experimental and only works with CF ADP projects. The path should be relative to the project root and must contain a `manifest.json` file.
187
+
188
+ ```Yaml
189
+ server:
190
+ customMiddleware:
191
+ - name: preview-middleware
192
+ afterMiddleware: compression
193
+ configuration:
194
+ adp:
195
+ target:
196
+ url: http://sap.example
197
+ cfBuildPath: dist # Path to build output folder (experimental, CF only)
198
+ ```
199
+ When the middleware is used in an adaptation project together with a middleware proxying requests to the back end e.g. the `backend-proxy-middleware`, then it is critically important that the `preview-middleware` is handling requests before the back-end proxy because it intercepts requests to the `manifest.json` of the original application and merges it with the variant.
175
200
  ```Yaml
176
201
  - name: preview-middleware
177
202
  afterMiddleware: rcompression
@@ -1,7 +1,7 @@
1
1
  import type { ReaderCollection } from '@ui5/fs';
2
2
  import type { Editor as MemFsEditor } from 'mem-fs-editor';
3
3
  import type { Request, Router } from 'express';
4
- import type { Logger, ToolsLogger } from '@sap-ux/logger';
4
+ import type { Logger } from '@sap-ux/logger';
5
5
  import type { MiddlewareUtils } from '@ui5/server';
6
6
  import { type Manifest } from '@sap-ux/project-access';
7
7
  import { AdpPreview, type AdpPreviewConfig, type CommonChangeProperties, type OperationType, type CommonAdditionalChangeInfoProperties } from '@sap-ux/adp-tooling';
@@ -309,17 +309,26 @@ export declare class FlpSandbox {
309
309
  * @returns {Promise<void>} A promise that resolves when the route is added.
310
310
  */
311
311
  addStoreI18nKeysRoute(): Promise<void>;
312
+ /**
313
+ * Initialize the preview for an adaptation project.
314
+ *
315
+ * @param config configuration from the ui5.yaml
316
+ * @throws Error in case no manifest.appdescr_variant found
317
+ */
318
+ initAdp(config: AdpPreviewConfig): Promise<void>;
319
+ /**
320
+ * Setup common ADP middleware and handlers.
321
+ *
322
+ * @param adp AdpPreview instance
323
+ */
324
+ private setupAdpCommonHandlers;
325
+ /**
326
+ * Setup the CF build path mode for the ADP project.
327
+ *
328
+ * @param cfBuildPath path to the build output folder
329
+ * @returns the manifest
330
+ */
331
+ private setupCfBuildMode;
312
332
  }
313
- /**
314
- * Initialize the preview for an adaptation project.
315
- *
316
- * @param rootProject reference to the project
317
- * @param config configuration from the ui5.yaml
318
- * @param flp FlpSandbox instance
319
- * @param util middleware utilities provided by the UI5 CLI
320
- * @param logger logger instance
321
- * @throws Error in case no manifest.appdescr_variant found
322
- */
323
- export declare function initAdp(rootProject: ReaderCollection, config: AdpPreviewConfig, flp: FlpSandbox, util: MiddlewareUtils, logger: ToolsLogger): Promise<void>;
324
333
  export {};
325
334
  //# sourceMappingURL=flp.d.ts.map
package/dist/base/flp.js CHANGED
@@ -34,7 +34,6 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.FlpSandbox = void 0;
37
- exports.initAdp = initAdp;
38
37
  const mem_fs_1 = require("mem-fs");
39
38
  const mem_fs_editor_1 = require("mem-fs-editor");
40
39
  const ejs_1 = require("ejs");
@@ -887,6 +886,53 @@ class FlpSandbox {
887
886
  await this.storeI18nKeysHandler(req, res);
888
887
  });
889
888
  }
889
+ /**
890
+ * Initialize the preview for an adaptation project.
891
+ *
892
+ * @param config configuration from the ui5.yaml
893
+ * @throws Error in case no manifest.appdescr_variant found
894
+ */
895
+ async initAdp(config) {
896
+ const variant = await (0, adp_tooling_1.loadAppVariant)(this.project);
897
+ const adp = new adp_tooling_1.AdpPreview(config, this.project, this.utils, this.logger);
898
+ const layer = await adp.init(variant);
899
+ // CF ADP build path mode: serve built resources directly from build output
900
+ if (config.cfBuildPath) {
901
+ const manifest = this.setupCfBuildMode(config.cfBuildPath);
902
+ configureRta(this.rta, layer, variant.id, false);
903
+ await this.init(manifest, variant.reference);
904
+ this.setupAdpCommonHandlers(adp);
905
+ return;
906
+ }
907
+ configureRta(this.rta, layer, variant.id, adp.isCloudProject);
908
+ const descriptor = adp.descriptor;
909
+ const { name, manifest } = descriptor;
910
+ await this.init(manifest, name, adp.resources, adp);
911
+ this.router.use(adp.descriptor.url, adp.proxy.bind(adp));
912
+ this.setupAdpCommonHandlers(adp);
913
+ }
914
+ /**
915
+ * Setup common ADP middleware and handlers.
916
+ *
917
+ * @param adp AdpPreview instance
918
+ */
919
+ setupAdpCommonHandlers(adp) {
920
+ this.addOnChangeRequestHandler(adp.onChangeRequest.bind(adp));
921
+ this.router.use((0, express_1.json)());
922
+ adp.addApis(this.router);
923
+ }
924
+ /**
925
+ * Setup the CF build path mode for the ADP project.
926
+ *
927
+ * @param cfBuildPath path to the build output folder
928
+ * @returns the manifest
929
+ */
930
+ setupCfBuildMode(cfBuildPath) {
931
+ const manifest = (0, adp_tooling_1.readManifestFromBuildPath)(cfBuildPath);
932
+ this.router.use('/', (0, express_1.static)(cfBuildPath));
933
+ this.logger.info(`Initialized CF ADP with cfBuildPath, serving from ${cfBuildPath}`);
934
+ return manifest;
935
+ }
890
936
  }
891
937
  exports.FlpSandbox = FlpSandbox;
892
938
  /**
@@ -914,43 +960,26 @@ function serializeUi5Configuration(config) {
914
960
  return '\n' + serializeDataAttributes(config, ' ', 'data-sap-ui');
915
961
  }
916
962
  /**
917
- * Initialize the preview for an adaptation project.
963
+ * Configure RTA (Runtime Adaptation) for the FLP sandbox.
918
964
  *
919
- * @param rootProject reference to the project
920
- * @param config configuration from the ui5.yaml
921
- * @param flp FlpSandbox instance
922
- * @param util middleware utilities provided by the UI5 CLI
923
- * @param logger logger instance
924
- * @throws Error in case no manifest.appdescr_variant found
965
+ * @param rta RtaConfig instance
966
+ * @param layer UI5 flex layer
967
+ * @param variantId variant identifier
968
+ * @param isCloud whether this is a cloud project
925
969
  */
926
- async function initAdp(rootProject, config, flp, util, logger) {
927
- const appVariant = await rootProject.byPath('/manifest.appdescr_variant');
928
- if (appVariant) {
929
- const adp = new adp_tooling_1.AdpPreview(config, rootProject, util, logger);
930
- const variant = JSON.parse(await appVariant.getString());
931
- const layer = await adp.init(variant);
932
- if (flp.rta) {
933
- flp.rta.layer = layer;
934
- flp.rta.options = {
935
- ...flp.rta.options,
936
- projectId: variant.id,
937
- scenario: 'ADAPTATION_PROJECT',
938
- isCloud: adp.isCloudProject
939
- };
940
- for (const editor of flp.rta.endpoints) {
941
- editor.pluginScript ??= 'open/ux/preview/client/adp/init';
942
- }
943
- }
944
- const descriptor = adp.descriptor;
945
- const { name, manifest } = descriptor;
946
- await flp.init(manifest, name, adp.resources, adp);
947
- flp.router.use(adp.descriptor.url, adp.proxy.bind(adp));
948
- flp.addOnChangeRequestHandler(adp.onChangeRequest.bind(adp));
949
- flp.router.use((0, express_1.json)());
950
- adp.addApis(flp.router);
951
- }
952
- else {
953
- throw new Error('ADP configured but no manifest.appdescr_variant found.');
970
+ function configureRta(rta, layer, variantId, isCloud) {
971
+ if (!rta) {
972
+ return;
973
+ }
974
+ rta.layer = layer;
975
+ rta.options = {
976
+ ...rta.options,
977
+ projectId: variantId,
978
+ scenario: 'ADAPTATION_PROJECT',
979
+ isCloud
980
+ };
981
+ for (const editor of rta.endpoints) {
982
+ editor.pluginScript ??= 'open/ux/preview/client/adp/init';
954
983
  }
955
984
  }
956
985
  //# sourceMappingURL=flp.js.map
@@ -1,4 +1,4 @@
1
- export { FlpSandbox, initAdp } from './flp';
1
+ export { FlpSandbox } from './flp';
2
2
  export { generatePreviewFiles, getPreviewPaths, sanitizeRtaConfig } from './config';
3
3
  export { logRemoteUrl, isRemoteConnectionsEnabled } from './remote-url';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1,9 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isRemoteConnectionsEnabled = exports.logRemoteUrl = exports.sanitizeRtaConfig = exports.getPreviewPaths = exports.generatePreviewFiles = exports.initAdp = exports.FlpSandbox = void 0;
3
+ exports.isRemoteConnectionsEnabled = exports.logRemoteUrl = exports.sanitizeRtaConfig = exports.getPreviewPaths = exports.generatePreviewFiles = exports.FlpSandbox = void 0;
4
4
  var flp_1 = require("./flp");
5
5
  Object.defineProperty(exports, "FlpSandbox", { enumerable: true, get: function () { return flp_1.FlpSandbox; } });
6
- Object.defineProperty(exports, "initAdp", { enumerable: true, get: function () { return flp_1.initAdp; } });
7
6
  var config_1 = require("./config");
8
7
  Object.defineProperty(exports, "generatePreviewFiles", { enumerable: true, get: function () { return config_1.generatePreviewFiles; } });
9
8
  Object.defineProperty(exports, "getPreviewPaths", { enumerable: true, get: function () { return config_1.getPreviewPaths; } });
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export * from './ui5/middleware';
2
- export { FlpSandbox, initAdp, generatePreviewFiles, getPreviewPaths, sanitizeRtaConfig, logRemoteUrl, isRemoteConnectionsEnabled } from './base';
2
+ export { FlpSandbox, generatePreviewFiles, getPreviewPaths, sanitizeRtaConfig, logRemoteUrl, isRemoteConnectionsEnabled } from './base';
3
3
  export { FlpConfig, RtaConfig, TestConfig, MiddlewareConfig, DefaultFlpPath, DefaultIntent, TestConfigDefaults } from './types';
4
4
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -14,11 +14,10 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.isRemoteConnectionsEnabled = exports.logRemoteUrl = exports.sanitizeRtaConfig = exports.getPreviewPaths = exports.generatePreviewFiles = exports.initAdp = exports.FlpSandbox = void 0;
17
+ exports.isRemoteConnectionsEnabled = exports.logRemoteUrl = exports.sanitizeRtaConfig = exports.getPreviewPaths = exports.generatePreviewFiles = exports.FlpSandbox = void 0;
18
18
  __exportStar(require("./ui5/middleware"), exports);
19
19
  var base_1 = require("./base");
20
20
  Object.defineProperty(exports, "FlpSandbox", { enumerable: true, get: function () { return base_1.FlpSandbox; } });
21
- Object.defineProperty(exports, "initAdp", { enumerable: true, get: function () { return base_1.initAdp; } });
22
21
  Object.defineProperty(exports, "generatePreviewFiles", { enumerable: true, get: function () { return base_1.generatePreviewFiles; } });
23
22
  Object.defineProperty(exports, "getPreviewPaths", { enumerable: true, get: function () { return base_1.getPreviewPaths; } });
24
23
  Object.defineProperty(exports, "sanitizeRtaConfig", { enumerable: true, get: function () { return base_1.sanitizeRtaConfig; } });
@@ -22,7 +22,7 @@ async function createRouter({ resources, options, middlewareUtil }, logger) {
22
22
  // configure the FLP sandbox based on information from the manifest
23
23
  const flp = new flp_1.FlpSandbox(config, resources.rootProject, middlewareUtil, logger);
24
24
  if (config.adp) {
25
- await (0, flp_1.initAdp)(resources.rootProject, config.adp, flp, middlewareUtil, logger);
25
+ await flp.initAdp(config.adp);
26
26
  }
27
27
  else {
28
28
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
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.23.63",
12
+ "version": "0.23.64",
13
13
  "license": "Apache-2.0",
14
14
  "author": "@SAP/ux-tools-team",
15
15
  "main": "dist/index.js",
@@ -27,7 +27,7 @@
27
27
  "mem-fs-editor": "9.4.0",
28
28
  "qrcode": "1.5.4",
29
29
  "@sap/bas-sdk": "3.12.0",
30
- "@sap-ux/adp-tooling": "0.18.11",
30
+ "@sap-ux/adp-tooling": "0.18.12",
31
31
  "@sap-ux/btp-utils": "1.1.5",
32
32
  "@sap-ux/control-property-editor-sources": "npm:@sap-ux/control-property-editor@0.7.2",
33
33
  "@sap-ux/feature-toggle": "0.3.4",