@sap-ux/fiori-migration-writer 0.0.3 → 0.0.4

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.
@@ -330,9 +330,14 @@ export class ProjectAccess {
330
330
  const pomRoots = await findAllWebIDEProjectFolders(workspaceRoots);
331
331
  // find projects by manifest.json in the root
332
332
  let manifestRoots = await findProjectsByManifest(workspaceRoots);
333
- const roots = [...packageRoots, ...pomRoots];
334
- // filter projects with manifest.json at root, when the project is nested in another migratble project
335
- manifestRoots = manifestRoots.filter((manifestRoot) => !roots.some((root) => manifestRoot.startsWith(root + sep)));
333
+ // A root can be discovered by more than one strategy (e.g. a project with both package.json
334
+ // and pom.xml), so deduplicate before building folders — otherwise getReuseLibs scans the
335
+ // same folder twice and returns duplicate library entries.
336
+ const roots = [...new Set([...packageRoots, ...pomRoots])];
337
+ // filter projects with manifest.json at root, when the project is nested in another migratble project.
338
+ // Reject exact matches too: a package/pom root that also has a root-level manifest.json would
339
+ // otherwise be re-appended here, defeating the dedup above and getting scanned twice again.
340
+ manifestRoots = manifestRoots.filter((manifestRoot) => !roots.some((root) => manifestRoot === root || manifestRoot.startsWith(root + sep)));
336
341
  roots.push(...manifestRoots);
337
342
  const rootFolders = roots.map((root, index) => {
338
343
  return {
@@ -343,27 +348,57 @@ export class ProjectAccess {
343
348
  });
344
349
  // find reuse libs
345
350
  let reuseLibsRoots = (await getReuseLibs(rootFolders)).filter((lib) => lib.value.type === ReuseLibType.LIBRARY);
351
+ // Roots that are themselves reuse libraries must be emitted only as libraries, never also as
352
+ // plain projects. getReuseLibs assigns a nested library to its nearest package/pom root, so a
353
+ // freestyle app that merely embeds a library shares that libRoot — suppressing by libRoot alone
354
+ // would wrongly drop the app. A root is library-only when it is itself a discovered library root
355
+ // AND getProjectInfo does not classify it as an application (no FE version, not an SAP app).
356
+ // getProjectInfo's own type is not sufficient on its own: a library whose manifest.json lives in
357
+ // a non-standard nested source path (e.g. src/.../lib/manifest.json) is not resolved as a library
358
+ // by the default webapp lookup, so the libRoot signal is needed to catch it.
359
+ const libraryOnlyRoots = new Set();
346
360
  if (reuseLibsRoots.length) {
347
- // Process all roots in parallel
348
- const results = await Promise.all(roots.map((root) => this.getProjectInfo(root)));
349
- // Collect project roots
350
- const temp = [];
351
- results.forEach((result, index) => {
352
- if (result.projectInfo.FEVersion || result.projectInfo.isSAPApp) {
353
- temp.push(roots[index]);
361
+ const reuseLibRootPaths = new Set(reuseLibsRoots.map((lib) => lib.value.libRoot));
362
+ const appRoots = [];
363
+ // Fetch all project info in parallel for performance
364
+ const projectInfoResults = await Promise.all(roots.map((root) => this.getProjectInfo(root)));
365
+ for (let i = 0; i < roots.length; i++) {
366
+ const root = roots[i];
367
+ const result = projectInfoResults[i];
368
+ const isApp = !!(result.projectInfo.FEVersion || result.projectInfo.isSAPApp);
369
+ if (isApp) {
370
+ appRoots.push(root);
354
371
  }
355
- });
356
- // Remove reuse libs that are within project roots
357
- reuseLibsRoots = reuseLibsRoots.filter((lib) => !temp.some((tempRoot) => isSamePath(lib.value.libRoot, tempRoot)));
372
+ else if ([...reuseLibRootPaths].some((libRoot) => isSamePath(libRoot, root)) ||
373
+ result.projectInfo.type === MigrationTypes.library) {
374
+ libraryOnlyRoots.add(root);
375
+ }
376
+ }
377
+ // After classifying all roots, filter out reuse libs detected in application projects
378
+ reuseLibsRoots = reuseLibsRoots.filter((lib) => !appRoots.some((appRoot) => isSamePath(lib.value.libRoot, appRoot)));
358
379
  }
359
380
  // if workspace has multiple roots then make sure there are no similar projects
360
- const projectsUnique = [...new Set(roots)].map((root) => {
381
+ const projectsUnique = [...new Set(roots)]
382
+ .filter((root) => !libraryOnlyRoots.has(root))
383
+ .map((root) => {
361
384
  return {
362
385
  root: root,
363
386
  type: MigrationTypes.project
364
387
  };
365
388
  });
366
- const reuseLibsUnique = reuseLibsRoots.map((lib) => {
389
+ // A single library root can contain several nested manifest.json files (the library manifest
390
+ // plus per-component manifests), each of which getReuseLibs resolves back to the same libRoot.
391
+ // Emit one entry per library root so the webview does not list the same library multiple times.
392
+ const seenLibPaths = [];
393
+ const reuseLibsUnique = reuseLibsRoots
394
+ .filter((lib) => {
395
+ if (seenLibPaths.some((path) => isSamePath(path, lib.value.path))) {
396
+ return false;
397
+ }
398
+ seenLibPaths.push(lib.value.path);
399
+ return true;
400
+ })
401
+ .map((lib) => {
367
402
  return {
368
403
  root: lib.value.libRoot,
369
404
  type: MigrationTypes.library,
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%3Afiori-migration-writer"
12
12
  },
13
- "version": "0.0.3",
13
+ "version": "0.0.4",
14
14
  "license": "Apache-2.0",
15
15
  "main": "dist/index.js",
16
16
  "files": [
@@ -37,17 +37,17 @@
37
37
  "uuid": "11.1.1",
38
38
  "vscode-uri": "3.1.0",
39
39
  "yaml": "2.9.0",
40
+ "@sap-ux/adp-tooling": "1.0.65",
40
41
  "@sap-ux/axios-extension": "2.1.2",
41
42
  "@sap-ux/btp-utils": "2.0.7",
42
43
  "@sap-ux/i18n": "1.0.6",
44
+ "@sap-ux/launch-config": "1.0.25",
43
45
  "@sap-ux/nodejs-utils": "1.0.11",
44
- "@sap-ux/adp-tooling": "1.0.65",
45
46
  "@sap-ux/project-access": "2.3.1",
46
47
  "@sap-ux/store": "2.0.7",
47
48
  "@sap-ux/ui5-application-writer": "2.1.6",
48
49
  "@sap-ux/ui5-config": "1.0.10",
49
- "@sap-ux/ui5-info": "1.0.7",
50
- "@sap-ux/launch-config": "1.0.25"
50
+ "@sap-ux/ui5-info": "1.0.7"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@jest/globals": "30.4.1",