cds-plugin-ui5 0.13.2 → 0.13.3

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/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [0.13.3](https://github.com/ui5-community/ui5-ecosystem-showcase/compare/cds-plugin-ui5@0.13.2...cds-plugin-ui5@0.13.3) (2025-07-29)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **cds-plugin-ui5:** fixes issue in lazy loading feature ([#1224](https://github.com/ui5-community/ui5-ecosystem-showcase/issues/1224)) ([a65b4bc](https://github.com/ui5-community/ui5-ecosystem-showcase/commit/a65b4bc13489484d6b755f3c530bc825f5c50f24))
12
+
13
+
14
+
15
+
16
+
6
17
  ## [0.13.2](https://github.com/ui5-community/ui5-ecosystem-showcase/compare/cds-plugin-ui5@0.13.1...cds-plugin-ui5@0.13.2) (2025-07-06)
7
18
 
8
19
 
package/cds-plugin.js CHANGED
@@ -188,25 +188,20 @@ if (!skip) {
188
188
  const router = createPatchedRouter();
189
189
 
190
190
  // determine the application info and apply the UI5 middlewares (maybe lazy)
191
- const promiseApply = applyUI5Middleware(router, {
191
+ const { pages } = await applyUI5Middleware(router, {
192
192
  cwd,
193
193
  basePath: modulePath,
194
194
  ...(config[moduleId] || {}),
195
- LOG,
195
+ log: LOG,
196
196
  lazy: isLazyLoadingEnabled,
197
197
  //logPerformance: true,
198
- }).then(({ pages }) => {
199
- // append the HTML pages to the links
200
- pages.forEach((page) => {
201
- const prefix = mountPath !== "/" ? mountPath : "";
202
- links.push(`${prefix}${page}`);
203
- });
204
198
  });
205
199
 
206
- // if lazy loading is not enabled, we wait for the middlewares to be applied
207
- if (!isLazyLoadingEnabled) {
208
- await promiseApply; // wait for the middlewares to be applied
209
- }
200
+ // append the HTML pages to the links
201
+ pages.forEach((page) => {
202
+ const prefix = mountPath !== "/" ? mountPath : "";
203
+ links.push(`${prefix}${page}`);
204
+ });
210
205
 
211
206
  // register the router to the specified mount path
212
207
  app.use(mountPath, router);
@@ -1,5 +1,9 @@
1
1
  const path = require("path");
2
2
  const fs = require("fs");
3
+ const { glob } = require("glob");
4
+ const yaml = require("js-yaml");
5
+
6
+ const PAGE_GLOB_PATTERN = "**/!(*.fragment).{html,htm}";
3
7
 
4
8
  /**
5
9
  * @typedef UI5AppInfo
@@ -46,11 +50,7 @@ module.exports = async function applyUI5Middleware(router, options) {
46
50
 
47
51
  const logPerformance = options.logPerformance || false;
48
52
 
49
- const millisImport = logPerformance && Date.now();
50
- const { graphFromPackageDependencies } = await import("@ui5/project/graph");
51
- logPerformance && log.info(`[PERF] Import took ${Date.now() - millisImport}ms`);
52
-
53
- const determineConfigPath = function (configPath, configFile) {
53
+ const determineConfigPath = (configPath, configFile) => {
54
54
  // ensure that the config path is absolute
55
55
  if (!path.isAbsolute(configPath)) {
56
56
  configPath = path.resolve(options.basePath, configPath);
@@ -72,39 +72,50 @@ module.exports = async function applyUI5Middleware(router, options) {
72
72
  return undefined;
73
73
  };
74
74
 
75
- // determine the project graph from the given options
76
- const millisGraph = logPerformance && Date.now();
77
- const graph = await graphFromPackageDependencies({
78
- cwd: options.basePath,
79
- rootConfigPath: determineConfigPath(configPath, configFile),
80
- workspaceName: process.env["ui5-workspace"] || options.workspaceName || "default",
81
- workspaceConfigPath: determineConfigPath(workspaceConfigPath, workspaceConfigFile),
82
- versionOverride: options.versionOverride,
83
- cacheMode: options.cacheMode,
84
- });
85
- logPerformance && log.info(`[PERF] Graph took ${Date.now() - millisGraph}ms`);
86
-
87
- const millisRoot = logPerformance && Date.now();
88
- // detect the root project
89
- const rootProject = graph.getRoot();
90
-
91
- // create a reader for the root project
92
- const rootReader = rootProject.getReader({ style: "runtime" });
93
- logPerformance && log.info(`[PERF] Root project took ${Date.now() - millisRoot}ms`);
94
-
95
- // for Fiori elements based applications we need to invalidate the view cache
96
- // so we need to append the query parameter to the HTML files (sap-ui-xx-viewCache=false)
97
- const isFioriElementsBased = rootProject.getFrameworkDependencies().find((lib) => lib.name.startsWith("sap.fe"));
98
-
99
- // collect app pages from workspace (glob testing: https://globster.xyz/ and https://codepen.io/mrmlnc/pen/OXQjMe)
100
- // -> but exclude the HTML fragments from the list of app pages!
101
- const millisPages = logPerformance && Date.now();
102
- const pages = (await rootReader.byGlob("**/!(*.fragment).{html,htm}")).map((resource) => `${resource.getPath()}${isFioriElementsBased ? "?sap-ui-xx-viewCache=false" : ""}`);
103
- logPerformance && log.info(`[PERF] Pages took ${Date.now() - millisPages}ms`);
75
+ const loadAppInfo = async () => {
76
+ const millisImport = logPerformance && Date.now();
77
+ const { graphFromPackageDependencies } = await import("@ui5/project/graph");
78
+ logPerformance && log.info(`[PERF] Import took ${Date.now() - millisImport}ms`);
79
+
80
+ // determine the project graph from the given options
81
+ const millisGraph = logPerformance && Date.now();
82
+ const graph = await graphFromPackageDependencies({
83
+ cwd: options.basePath,
84
+ rootConfigPath: determineConfigPath(configPath, configFile),
85
+ workspaceName: process.env["ui5-workspace"] || options.workspaceName || "default",
86
+ workspaceConfigPath: determineConfigPath(workspaceConfigPath, workspaceConfigFile),
87
+ versionOverride: options.versionOverride,
88
+ cacheMode: options.cacheMode,
89
+ });
90
+ logPerformance && log.info(`[PERF] Graph took ${Date.now() - millisGraph}ms`);
91
+
92
+ const millisRoot = logPerformance && Date.now();
93
+ // detect the root project
94
+ const rootProject = graph.getRoot();
95
+
96
+ // create a reader for the root project
97
+ const rootReader = rootProject.getReader({ style: "runtime" });
98
+ logPerformance && log.info(`[PERF] Root project took ${Date.now() - millisRoot}ms`);
99
+
100
+ return { rootProject, rootReader, graph };
101
+ };
102
+
103
+ const loadPages = async ({ rootProject, rootReader }) => {
104
+ // for Fiori elements based applications we need to invalidate the view cache
105
+ // so we need to append the query parameter to the HTML files (sap-ui-xx-viewCache=false)
106
+ const isFioriElementsBased = rootProject.getFrameworkDependencies().find((lib) => lib.name.startsWith("sap.fe"));
107
+
108
+ // collect app pages from workspace (glob testing: https://globster.xyz/ and https://codepen.io/mrmlnc/pen/OXQjMe)
109
+ // -> but exclude the HTML fragments from the list of app pages!
110
+ const millisPages = logPerformance && Date.now();
111
+ const pages = (await rootReader.byGlob(PAGE_GLOB_PATTERN)).map((resource) => `${resource.getPath()}${isFioriElementsBased ? "?sap-ui-xx-viewCache=false" : ""}`);
112
+ logPerformance && log.info(`[PERF] Pages took ${Date.now() - millisPages}ms`);
113
+ return pages;
114
+ };
104
115
 
105
116
  // method to create the middleware manager and to apply the middlewares
106
117
  // to the express router provided as a parameter to this function
107
- const apply = async () => {
118
+ const apply = async ({ rootProject, rootReader, graph, pages }) => {
108
119
  // find the relevant readers for the dependencies
109
120
  const readers = [];
110
121
  await graph.traverseBreadthFirst(async function ({ project: dep }) {
@@ -148,6 +159,10 @@ module.exports = async function applyUI5Middleware(router, options) {
148
159
  });
149
160
  await middlewareManager.applyMiddleware(router);
150
161
 
162
+ // custom pages are not collectible in lazy loading mode
163
+ if (!pages) {
164
+ return;
165
+ }
151
166
  // collect app pages from middlewares implementing the getAppPages
152
167
  // which will only work if the middleware is executed synchronously
153
168
  middlewareManager.middlewareExecutionOrder?.map((name) => {
@@ -169,24 +184,55 @@ module.exports = async function applyUI5Middleware(router, options) {
169
184
  });
170
185
  };
171
186
 
187
+ const determineWebappPath = (ui5ConfigPath) => {
188
+ if (ui5ConfigPath) {
189
+ log.warn("Path to config file could not be determined. Using default webapp path to lookup HTML pages");
190
+ return "webapp";
191
+ }
192
+
193
+ /** @type {{resources: {configuration: {paths: {webapp: string}}}}[]} */
194
+ let ui5Configs;
195
+ try {
196
+ // read the ui5.yaml file to extract the configuration
197
+ const content = fs.readFileSync(ui5ConfigPath, "utf-8");
198
+ ui5Configs = yaml.loadAll(content);
199
+ } catch (err) {
200
+ if (err.name === "YAMLException") {
201
+ log.error(`Failed to read ${ui5ConfigPath}!`);
202
+ }
203
+ throw err;
204
+ }
205
+
206
+ const webappPath = ui5Configs?.[0]?.resources?.configuration?.paths?.webapp;
207
+ if (webappPath) {
208
+ log.debug(`Determined custom "webapp" path "${webappPath}"`);
209
+ }
210
+ return webappPath ?? "webapp";
211
+ };
212
+
172
213
  // install a callback in the router to apply the middlewares
173
214
  if (options.lazy) {
174
215
  let isApplied = false;
175
216
  router.use(async (req, res, next) => {
176
217
  if (!isApplied) {
177
- await apply();
218
+ const { graph, rootProject, rootReader } = await loadAppInfo();
219
+ await apply({ graph, rootProject, rootReader });
178
220
  isApplied = true;
179
221
  }
180
222
  next();
181
223
  });
224
+ const webappPath = determineWebappPath(determineConfigPath(configPath, configFile));
225
+ // collect pages via glob pattern
226
+ return {
227
+ pages: (await glob(PAGE_GLOB_PATTERN, { cwd: path.join(configPath, webappPath) })).map((p) => (!p.startsWith("/") ? `/${p}` : p)),
228
+ };
182
229
  } else {
183
- await apply();
184
- }
185
-
186
- logPerformance && log.info(`[PERF] applyUI5Middleware took ${Date.now() - millis}ms`);
230
+ const { graph, rootProject, rootReader } = await loadAppInfo();
231
+ const pages = await loadPages({ rootProject, rootReader });
232
+ await apply({ graph, rootProject, rootReader, pages });
233
+ logPerformance && log.info(`[PERF] applyUI5Middleware took ${Date.now() - millis}ms`);
187
234
 
188
- // return the UI5 application information
189
- return {
190
- pages,
191
- };
235
+ // return the UI5 application information
236
+ return { pages };
237
+ }
192
238
  };
@@ -18,7 +18,7 @@ const yaml = require("js-yaml");
18
18
  * @param {string} options.skipLocalApps skip local apps
19
19
  * @param {string} options.skipDeps skip dependencies
20
20
  * @param {string} options.log the logger (defaults to console)
21
- * @returns {Array<UI5Module>} array of UI5 module
21
+ * @returns {Promise<Array<UI5Module>>} array of UI5 module
22
22
  */
23
23
  module.exports = async function findUI5Modules({ cwd, cds, skipLocalApps, skipDeps, log = console }) {
24
24
  // extract the modules configuration from the package.json
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cds-plugin-ui5",
3
- "version": "0.13.2",
3
+ "version": "0.13.3",
4
4
  "description": "A CDS server plugin to inject the middlewares of all related UI5 tooling based projects.",
5
5
  "author": "Peter Muessig",
6
6
  "license": "Apache-2.0",
@@ -14,6 +14,7 @@
14
14
  "@ui5/fs": "^4",
15
15
  "@ui5/project": "^4",
16
16
  "@ui5/server": "^4",
17
+ "glob": "^11.0.2",
17
18
  "js-yaml": "^4.1.0",
18
19
  "node-html-parser": "^7.0.1",
19
20
  "semver": "^7.7.2"
@@ -26,5 +27,5 @@
26
27
  "@sap/cds": ">=6.8.2",
27
28
  "express": ">=4.18.2"
28
29
  },
29
- "gitHead": "4564f2dc020ee4e2dcc5a7e0ebc982d488709350"
30
+ "gitHead": "3d1a244e6e2888420c95cba9b6cfe77a20c3ef99"
30
31
  }