@sap-ux/adp-tooling 1.0.55 → 1.0.58

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.
@@ -1,3 +1,5 @@
1
+ import type { ReaderCollection } from '@ui5/fs';
2
+ import type { MergedAppDescriptor } from '@sap-ux/axios-extension';
1
3
  /**
2
4
  * Executes a build command in the specified project directory.
3
5
  *
@@ -9,4 +11,16 @@
9
11
  * @throws {Error} If the build process fails or if an error occurs during cleanup.
10
12
  */
11
13
  export declare function runBuild(projectPath: string, env?: NodeJS.ProcessEnv): Promise<void>;
14
+ /**
15
+ * Produces the merged manifest.json for a CF ADP project using the workspace
16
+ * and cached base app files from the last full build.
17
+ *
18
+ * Precondition: a full build must have run at least once so the base app files are
19
+ * in the local cache. Throws if the cache is empty.
20
+ *
21
+ * @param {string} projectPath - Absolute path to the project root (where ui5.yaml lives).
22
+ * @param {ReaderCollection} workspace - The UI5 project workspace (this.project in AdpPreview).
23
+ * @returns {Promise<MergedAppDescriptor['manifest']>} The merged manifest.
24
+ */
25
+ export declare function getPreviewManifest(projectPath: string, workspace: ReaderCollection): Promise<MergedAppDescriptor['manifest']>;
12
26
  //# sourceMappingURL=project-builder.d.ts.map
@@ -1,4 +1,5 @@
1
1
  import { CommandRunner } from '@sap-ux/nodejs-utils';
2
+ import { readUi5Config, extractCfBuildTask } from './helper.js';
2
3
  /**
3
4
  * Executes a build command in the specified project directory.
4
5
  *
@@ -23,4 +24,33 @@ export async function runBuild(projectPath, env) {
23
24
  throw e;
24
25
  }
25
26
  }
27
+ /**
28
+ * Produces the merged manifest.json for a CF ADP project using the workspace
29
+ * and cached base app files from the last full build.
30
+ *
31
+ * Precondition: a full build must have run at least once so the base app files are
32
+ * in the local cache. Throws if the cache is empty.
33
+ *
34
+ * @param {string} projectPath - Absolute path to the project root (where ui5.yaml lives).
35
+ * @param {ReaderCollection} workspace - The UI5 project workspace (this.project in AdpPreview).
36
+ * @returns {Promise<MergedAppDescriptor['manifest']>} The merged manifest.
37
+ */
38
+ export async function getPreviewManifest(projectPath, workspace) {
39
+ const ui5Config = await readUi5Config(projectPath, 'ui5.yaml');
40
+ const buildTask = extractCfBuildTask(ui5Config);
41
+ const { module: projectNamespace, ...configuration } = buildTask;
42
+ // Dynamic import keeps @ui5/task-adaptation out of the static module graph of adp-tooling.
43
+ // A static import would leak task-adaptation's node:child_process imports into every
44
+ // consumer's Jest test environment, breaking mocks in packages like @sap-ux/create
45
+ // that mock node:child_process without spreading the real module.
46
+ const { previewManifest } = await import('@ui5/task-adaptation');
47
+ const manifest = await previewManifest({
48
+ workspace,
49
+ options: {
50
+ configuration,
51
+ projectNamespace
52
+ }
53
+ });
54
+ return manifest;
55
+ }
26
56
  //# sourceMappingURL=project-builder.js.map
@@ -96,6 +96,17 @@ export declare class AdpPreview {
96
96
  * The descriptor is refreshed only if the global flag is set to true.
97
97
  */
98
98
  sync(): Promise<void>;
99
+ /**
100
+ * Sync the merged descriptor and send its manifest.json as the response.
101
+ *
102
+ * Rewrites `ui5://<namespace>/` to absolute paths in the manifest so that
103
+ * FLP Sandbox 2.0's CDM does not map enhanceWith bundleUrls to the backend.
104
+ * Uses descriptorVariantId (from manifest.appdescr_variant) — the manifest's ui5:// URLs
105
+ * are built from the variant id, whereas mergedDescriptor.name is the base app reference.
106
+ *
107
+ * @param res outgoing response object
108
+ */
109
+ private sendManifest;
99
110
  /**
100
111
  * Proxy for the merged application manifest.json and blocking of preload files.
101
112
  *
@@ -104,6 +115,14 @@ export declare class AdpPreview {
104
115
  * @param next next middleware that is to be called if the request cannot be handled
105
116
  */
106
117
  proxy(req: Request, res: Response, next: NextFunction): Promise<void>;
118
+ /**
119
+ * CF build mode proxy that intercepts manifest.json requests and delegates everything else to the next middleware.
120
+ *
121
+ * @param req incoming request
122
+ * @param res outgoing response object
123
+ * @param next next middleware that is to be called if the request cannot be handled
124
+ */
125
+ cfProxy(req: Request, res: Response, next: NextFunction): Promise<void>;
107
126
  /**
108
127
  * Add additional APIs to the router that are required for adaptation projects only.
109
128
  *
@@ -4,7 +4,8 @@ import RoutesHandler from './routes-handler.js';
4
4
  import OvpRoutesHandler from './ovp-routes-handler.js';
5
5
  import { addAnnotationFile, addXmlFragment, isAddAnnotationChange, isAddXMLChange, isCodeExtChange, addControllerExtension, moduleNameContentMap, tryFixChange, isV4DescriptorChange } from './change-handler.js';
6
6
  import { addCustomFragment } from './descriptor-change-handler.js';
7
- import { getExistingAdpProjectType } from '../base/helper.js';
7
+ import { getExistingAdpProjectType, readManifestFromBuildPath } from '../base/helper.js';
8
+ import { getPreviewManifest } from '../base/project-builder.js';
8
9
  import path from 'node:path';
9
10
  export var ApiRoutes;
10
11
  (function (ApiRoutes) {
@@ -118,11 +119,12 @@ export class AdpPreview {
118
119
  * @returns {Promise<UI5FlexLayer>} The UI5 flex layer for which editing is enabled.
119
120
  */
120
121
  async init(descriptorVariant) {
121
- if ('cfBuildPath' in this.config) {
122
+ if (this.isCloudFoundry) {
122
123
  return this.initCfBuildMode(descriptorVariant);
123
124
  }
125
+ const config = this.config;
124
126
  this.descriptorVariantId = descriptorVariant.id;
125
- this.provider = await createAbapServiceProvider(this.config.target, { ignoreCertErrors: this.config.ignoreCertErrors }, true, this.logger);
127
+ this.provider = await createAbapServiceProvider(config.target, { ignoreCertErrors: config.ignoreCertErrors }, true, this.logger);
126
128
  this.routesHandler = new RoutesHandler(this.project, this.util, this.provider, this.logger);
127
129
  this.ovpRoutesHandler = new OvpRoutesHandler(this.provider, this.logger);
128
130
  this.lrep = this.provider.getLayeredRepository();
@@ -142,6 +144,14 @@ export class AdpPreview {
142
144
  this.descriptorVariantId = descriptorVariant.id;
143
145
  this.projectTypeValue = undefined;
144
146
  this.routesHandler = new RoutesHandler(this.project, this.util, {}, this.logger);
147
+ const config = this.config;
148
+ const manifest = readManifestFromBuildPath(config.cfBuildPath);
149
+ this.mergedDescriptor = {
150
+ name: descriptorVariant.id,
151
+ url: '/',
152
+ manifest,
153
+ asyncHints: { libs: [], components: [] }
154
+ };
145
155
  return descriptorVariant.layer;
146
156
  }
147
157
  /**
@@ -149,10 +159,12 @@ export class AdpPreview {
149
159
  * The descriptor is refreshed only if the global flag is set to true.
150
160
  */
151
161
  async sync() {
152
- if ('cfBuildPath' in this.config) {
162
+ if (!global.__SAP_UX_MANIFEST_SYNC_REQUIRED__ && this.mergedDescriptor) {
153
163
  return;
154
164
  }
155
- if (!global.__SAP_UX_MANIFEST_SYNC_REQUIRED__ && this.mergedDescriptor) {
165
+ if (this.isCloudFoundry) {
166
+ this.mergedDescriptor.manifest = await getPreviewManifest(this.util.getProject().getRootPath(), this.project);
167
+ global.__SAP_UX_MANIFEST_SYNC_REQUIRED__ = false;
156
168
  return;
157
169
  }
158
170
  if (!this.lrep || !this.descriptorVariantId) {
@@ -167,6 +179,23 @@ export class AdpPreview {
167
179
  this.mergedDescriptor = (await this.lrep.mergeAppDescriptorVariant(buffer, '//'))[this.descriptorVariantId];
168
180
  global.__SAP_UX_MANIFEST_SYNC_REQUIRED__ = false;
169
181
  }
182
+ /**
183
+ * Sync the merged descriptor and send its manifest.json as the response.
184
+ *
185
+ * Rewrites `ui5://<namespace>/` to absolute paths in the manifest so that
186
+ * FLP Sandbox 2.0's CDM does not map enhanceWith bundleUrls to the backend.
187
+ * Uses descriptorVariantId (from manifest.appdescr_variant) — the manifest's ui5:// URLs
188
+ * are built from the variant id, whereas mergedDescriptor.name is the base app reference.
189
+ *
190
+ * @param res outgoing response object
191
+ */
192
+ async sendManifest(res) {
193
+ await this.sync();
194
+ res.status(200);
195
+ const ui5Prefix = `ui5://${(this.descriptorVariantId ?? this.mergedDescriptor.name).replaceAll('.', '/')}/`;
196
+ const manifest = JSON.stringify(this.descriptor.manifest, undefined, 2).replaceAll(ui5Prefix, '/');
197
+ res.send(manifest);
198
+ }
170
199
  /**
171
200
  * Proxy for the merged application manifest.json and blocking of preload files.
172
201
  *
@@ -176,15 +205,7 @@ export class AdpPreview {
176
205
  */
177
206
  async proxy(req, res, next) {
178
207
  if (req.path === '/manifest.json') {
179
- await this.sync();
180
- res.status(200);
181
- // Rewrite ui5://<namespace>/ to absolute paths in the manifest so that
182
- // FLP Sandbox 2.0's CDM does not map enhanceWith bundleUrls to the backend.
183
- // Use descriptorVariantId (from manifest.appdescr_variant) — the manifest's ui5:// URLs
184
- // are built from the variant id, whereas mergedDescriptor.name is the base app reference.
185
- const ui5Prefix = `ui5://${(this.descriptorVariantId ?? this.mergedDescriptor.name).replaceAll('.', '/')}/`;
186
- const manifest = JSON.stringify(this.descriptor.manifest, undefined, 2).replaceAll(ui5Prefix, '/');
187
- res.send(manifest);
208
+ await this.sendManifest(res);
188
209
  }
189
210
  else if (req.path === '/Component-preload.js') {
190
211
  res.status(404).send();
@@ -210,6 +231,21 @@ export class AdpPreview {
210
231
  }
211
232
  }
212
233
  }
234
+ /**
235
+ * CF build mode proxy that intercepts manifest.json requests and delegates everything else to the next middleware.
236
+ *
237
+ * @param req incoming request
238
+ * @param res outgoing response object
239
+ * @param next next middleware that is to be called if the request cannot be handled
240
+ */
241
+ async cfProxy(req, res, next) {
242
+ if (req.path === '/manifest.json') {
243
+ await this.sendManifest(res);
244
+ }
245
+ else {
246
+ next();
247
+ }
248
+ }
213
249
  /**
214
250
  * Add additional APIs to the router that are required for adaptation projects only.
215
251
  *
package/dist/types.d.ts CHANGED
@@ -896,6 +896,7 @@ export interface UI5YamlCustomTaskConfiguration {
896
896
  appHostId: string;
897
897
  appName: string;
898
898
  appVersion: string;
899
+ module: string;
899
900
  moduleName: string;
900
901
  org: string;
901
902
  space: string;
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "bugs": {
11
11
  "url": "https://github.com/SAP/open-ux-tools/issues?q=is%3Aopen+is%3Aissue+label%3Abug+label%3Aadp-tooling"
12
12
  },
13
- "version": "1.0.55",
13
+ "version": "1.0.58",
14
14
  "license": "Apache-2.0",
15
15
  "author": "@SAP/ux-tools-team",
16
16
  "main": "dist/index.js",
@@ -37,15 +37,16 @@
37
37
  "prompts": "2.4.2",
38
38
  "sanitize-filename": "1.6.4",
39
39
  "uuid": "11.1.1",
40
+ "@ui5/task-adaptation": "1.6.8",
40
41
  "@sap-ux/axios-extension": "2.1.0",
41
42
  "@sap-ux/btp-utils": "2.0.6",
42
- "@sap-ux/i18n": "1.0.3",
43
- "@sap-ux/inquirer-common": "1.0.42",
43
+ "@sap-ux/i18n": "1.0.4",
44
+ "@sap-ux/inquirer-common": "1.0.44",
44
45
  "@sap-ux/logger": "1.0.3",
45
46
  "@sap-ux/nodejs-utils": "1.0.10",
46
- "@sap-ux/odata-service-writer": "1.0.22",
47
- "@sap-ux/project-access": "2.2.0",
48
- "@sap-ux/project-input-validator": "1.0.19",
47
+ "@sap-ux/odata-service-writer": "1.0.23",
48
+ "@sap-ux/project-access": "2.2.1",
49
+ "@sap-ux/project-input-validator": "1.0.20",
49
50
  "@sap-ux/store": "2.0.7",
50
51
  "@sap-ux/system-access": "1.0.14",
51
52
  "@sap-ux/ui5-config": "1.0.9",