@hitachivantara/app-shell-vite-plugin 0.17.11 → 0.18.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.
Files changed (45) hide show
  1. package/README.md +22 -24
  2. package/dist/automatic-utils.d.ts +25 -2
  3. package/dist/automatic-utils.d.ts.map +1 -1
  4. package/dist/automatic-utils.js +97 -67
  5. package/dist/automatic-utils.js.map +1 -1
  6. package/dist/config-utils.d.ts +4 -11
  7. package/dist/config-utils.d.ts.map +1 -1
  8. package/dist/config-utils.js +9 -50
  9. package/dist/config-utils.js.map +1 -1
  10. package/dist/esm-externals/emotion-react.production.min.js.map +1 -1
  11. package/dist/esm-externals/react-dom.production.min.js +2 -2
  12. package/dist/esm-externals/react-dom.production.min.js.map +1 -1
  13. package/dist/esm-externals/react-router-dom.production.min.js +18 -8
  14. package/dist/esm-externals/react-router-dom.production.min.js.map +1 -1
  15. package/dist/esm-externals/react.production.min.js.map +1 -1
  16. package/dist/index.d.ts +1 -0
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js.map +1 -1
  19. package/dist/virtual-entrypoints.js +2 -2
  20. package/dist/virtual-entrypoints.js.map +1 -1
  21. package/dist/vite-configuration-processor-plugin.d.ts +4 -1
  22. package/dist/vite-configuration-processor-plugin.d.ts.map +1 -1
  23. package/dist/vite-configuration-processor-plugin.js +44 -63
  24. package/dist/vite-configuration-processor-plugin.js.map +1 -1
  25. package/dist/vite-generate-base-plugin.d.ts +1 -1
  26. package/dist/vite-generate-base-plugin.js +3 -3
  27. package/dist/vite-generate-base-plugin.js.map +1 -1
  28. package/dist/vite-generate-bash-script-plugin.js +5 -5
  29. package/dist/vite-generate-bash-script-plugin.js.map +1 -1
  30. package/dist/vite-importmap-plugin.d.ts +1 -1
  31. package/dist/vite-importmap-plugin.d.ts.map +1 -1
  32. package/dist/vite-importmap-plugin.js +8 -8
  33. package/dist/vite-importmap-plugin.js.map +1 -1
  34. package/dist/vite-metadata-plugin.d.ts +1 -1
  35. package/dist/vite-metadata-plugin.js +2 -2
  36. package/dist/vite-metadata-plugin.js.map +1 -1
  37. package/dist/vite-plugin.d.ts +10 -4
  38. package/dist/vite-plugin.d.ts.map +1 -1
  39. package/dist/vite-plugin.js +11 -21
  40. package/dist/vite-plugin.js.map +1 -1
  41. package/dist/vite-watch-config-plugin.d.ts +1 -1
  42. package/dist/vite-watch-config-plugin.d.ts.map +1 -1
  43. package/dist/vite-watch-config-plugin.js +69 -3
  44. package/dist/vite-watch-config-plugin.js.map +1 -1
  45. package/package.json +8 -7
package/README.md CHANGED
@@ -4,30 +4,28 @@ Hitachi Vantara App Shell Vite Plugin: Streamlines development and build process
4
4
 
5
5
  ## Overview
6
6
 
7
- The @hitachivantara/app-shell-vite-plugin enhances the App Shell experience by automating essential development and build tasks, such as processing configurations, creating virtual endpoints, and managing importmaps and base paths.
7
+ The `@hitachivantara/app-shell-vite-plugin` enhances the App Shell experience by automating essential development and build tasks, such as processing configurations, creating virtual endpoints, and managing importmaps and base paths.
8
8
 
9
- This plugin is responsible for the hard lifting during development time and build time.
10
- It performs the following actions:
9
+ This plugin is responsible for the hard lifting during development time and build time. It performs the following actions:
11
10
 
12
- - copy all the required js bundles to final "bundles" folders
13
- - process the `app-shell.config.json` file
14
- - create virtual endpoints to support dev mode
15
- - create virtual main.tsx and App.tsx Files: These files were there strictly for development purposes, as what ultimately matters are the ESM modules
16
- exported and consumed by others
17
- - create `importmap` and inject it into `index.html`
18
- - create <base href="..."> tag and inject it into `index.html`
11
+ - copy all the required `js` bundles to the final "bundles" folders;
12
+ - process the `app-shell.config.ts` file;
13
+ - create virtual endpoints to support dev mode;
14
+ - create virtual `main.tsx` and `App.tsx` files. These files are there strictly for development purposes, as what ultimately matters are the ESM modules exported and consumed by others;
15
+ - create `importmap` and inject it into `index.html`;
16
+ - create `<base href="...">` tag and inject it into `index.html`.
19
17
 
20
18
  ## How to use
21
19
 
22
- Install the plugin
20
+ Install the plugin:
23
21
 
24
22
  ```
25
23
  npm install -D @hitachivantara/app-shell-vite-plugin
26
24
  ```
27
25
 
28
- Add the plugin to the vite plugin list in `vite.config.js`.
26
+ Add the plugin to the vite plugin list in `vite.config.ts`.
29
27
 
30
- ```javascript
28
+ ```typescript
31
29
  // imports omitted
32
30
  import { HvAppShellVitePlugin } from "@hitachivantara/app-shell-vite-plugin";
33
31
 
@@ -43,23 +41,23 @@ export default defineConfig(({ mode }) => {
43
41
 
44
42
  ## app-shell.config
45
43
 
46
- The configuration file must be placed at the root directory of the app.
47
- The vite-plugin can process the `app-shell.config` as a json file or Typescritp file.
44
+ The configuration file must be placed at the root directory of the app and the vite-plugin can process the `app-shell.config` as a JSON or Typescript extension.
48
45
 
49
- Managing settings in TypeScript, provide more efficiency and type safety features.
50
- You can check this configuration in action [here](../../samples/default-app/app-shell.config.ts).
46
+ Managing settings in TypeScript however provides more efficiency and type safety features. You can check this configuration in action [here](../../samples/default-app/app-shell.config.ts).
51
47
 
52
- ## Automatic configuration
48
+ ## Configuration properties
53
49
 
54
- `autoViewsAndRoutes`: automatically exports views from the "src/pages" directory (or any other specified folder).
55
- This includes automatic route configuration (merges with existing ones, if any).
50
+ * `modules`: all modules that an application wants, and needs, to export so that they can be consumed by either **App Shell** or any other applications.
51
+ * `type`: controls the way application build process is executed. By using the `app` option, the build process will generate the complete set of final files ( index.html, assets, etc). Using the `bundle` option, will only create the final files for the entries defined at the `modules` property. `app` value is typically recommended for the scenarios where App Shell is used at standalone scenarios, and `bundle` for microservices environments. By default, `type` value is set to `app` at local development, but it will change to `bundle` value at CI environments (relying at the standard env property that normally available at these environments). To use `app` , value needs to be explicitly set at `vite.config` file.
56
52
 
57
- `autoDevMenu` (dev only): creates a navigation menu derived from the views.
58
- This ensures a more organized and streamlined development process.
53
+ ### Automatic features
54
+ * `autoViewsAndRoutes`: automatically exports views from the `src/pages` directory (or any other specified folder defined in the `viewsFolder` property). This includes automatic route configuration (merges with existing ones, if any). The resulting views will be added automatically to views defined at the configuration file (associated bundle will also be added to the final modules list)
55
+ * `autoMenu`: creates a navigation menu derived from the views. This ensures a more organized and streamlined development process.
59
56
 
60
- Empty Configuration Validity: With these automatic features in place, the configuration file isn't even mandatory for dev environments.
57
+ > Empty Configuration Validity: With these automatic features in place, the configuration file isn't even mandatory for dev environments.
61
58
 
62
- ## `<base href="...">` tag
59
+
60
+ ## `<base href="...">` tag
63
61
 
64
62
  The <base href="..."> tag is automatically injected at index.html file during the build process. The value of tag is the same as for the app base path. More information related to the way app base path is obtained can be checked [here](../../../docs/app-shell-utilities.md#usehvappshellbasepath).
65
63
 
@@ -1,6 +1,29 @@
1
1
  import type { HvAppShellConfig, HvAppShellViewsConfig } from "@hitachivantara/app-shell-shared";
2
+ /**
3
+ * Find all the index.tsx or index.jsx files existent at the provided path (including all the subdirectories)
4
+ * @param dir the path to search for the index.tsx or index.jsx files
5
+ */
2
6
  export declare function findIndexFiles(dir: string): string[];
3
- export declare function mapIndexFilesToRoutes(files: string[], folder: string): HvAppShellViewsConfig[];
4
- export declare function applyAutomaticViewsAndRoutes(config: HvAppShellConfig, root: string, viewsFolder: string): void;
7
+ /**
8
+ * Maps the set of files, to a set of main views config (@see HvAppShellViewsConfig) and the respective module (to be
9
+ * transformed to the final bundle)
10
+ * @param files Set of files to be mapped to a set of new virtual views
11
+ * @param folder The base folder where the files are included
12
+ * @return an array of viewConfig and their correspondent module definition
13
+ */
14
+ export declare function mapIndexFilesToRoutes(files: string[], folder: string): {
15
+ viewConfig: HvAppShellViewsConfig;
16
+ module: string;
17
+ }[];
18
+ /**
19
+ * Adds the automatically identified view (from the "viewsFolder" folder) to the AppShell configuration and calculate
20
+ * the correspondent module to be generated
21
+ * It guarantees that any new route will not overlap any manual defined route
22
+ * @param config The app Shell config file
23
+ * @param root Project root folder
24
+ * @param viewsFolder Views folder
25
+ * @return the array of modules to be created by the rollup mechanism
26
+ */
27
+ export declare function applyAutomaticViewsAndRoutes(config: HvAppShellConfig, root: string, viewsFolder: string): string[];
5
28
  export declare function applyAutomaticMenu(config: HvAppShellConfig): void;
6
29
  //# sourceMappingURL=automatic-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"automatic-utils.d.ts","sourceRoot":"","sources":["../src/automatic-utils.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,gBAAgB,EAChB,qBAAqB,EACtB,MAAM,kCAAkC,CAAC;AAI1C,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAepD;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,EAAE,EACf,MAAM,EAAE,MAAM,GACb,qBAAqB,EAAE,CAiBzB;AAED,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,QAqCpB;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,QA+C1D"}
1
+ {"version":3,"file":"automatic-utils.d.ts","sourceRoot":"","sources":["../src/automatic-utils.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,gBAAgB,EAEhB,qBAAqB,EACtB,MAAM,kCAAkC,CAAC;AAE1C;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAepD;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,EAAE,EACf,MAAM,EAAE,MAAM,GACb;IACD,UAAU,EAAE,qBAAqB,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;CAChB,EAAE,CA2BF;AAED;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,GAClB,MAAM,EAAE,CA+CV;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,QAoD1D"}
@@ -1,6 +1,9 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
- import { getMainApp } from "./config-utils.js";
3
+ /**
4
+ * Find all the index.tsx or index.jsx files existent at the provided path (including all the subdirectories)
5
+ * @param dir the path to search for the index.tsx or index.jsx files
6
+ */
4
7
  export function findIndexFiles(dir) {
5
8
  const files = [];
6
9
  fs.readdirSync(dir).forEach(file => {
@@ -9,97 +12,124 @@ export function findIndexFiles(dir) {
9
12
  if (stat.isDirectory()) {
10
13
  files.push(...findIndexFiles(filePath));
11
14
  }
12
- else if (file.match(/^index\.[tj]sx?$/)) {
15
+ else if (/^index\.[tj]sx?$/.exec(file)) {
13
16
  files.push(filePath);
14
17
  }
15
18
  });
16
19
  return files;
17
20
  }
21
+ /**
22
+ * Maps the set of files, to a set of main views config (@see HvAppShellViewsConfig) and the respective module (to be
23
+ * transformed to the final bundle)
24
+ * @param files Set of files to be mapped to a set of new virtual views
25
+ * @param folder The base folder where the files are included
26
+ * @return an array of viewConfig and their correspondent module definition
27
+ */
18
28
  export function mapIndexFilesToRoutes(files, folder) {
19
29
  const routes = [];
20
30
  files.forEach(filePath => {
21
- const bundle = filePath.substring(filePath.lastIndexOf(`/${folder.replace(/^\/|\/$/g, "")}/`) + 1, filePath.lastIndexOf("/"));
31
+ let bundle = filePath.substring(filePath.lastIndexOf(`/${folder.replace(/^\/|\/$/g, "")}/`) + 1, filePath.lastIndexOf("/"));
22
32
  const route = bundle
23
33
  .replace(new RegExp(`^${folder}`), "")
24
34
  .replace(/index\.[t|j]sx?$/, "")
25
35
  .replaceAll(/\$/g, ":")
26
36
  .toLowerCase();
27
- routes.push({ bundle, route });
37
+ // module to be added when building the application
38
+ const module = bundle;
39
+ // src needs to be replaced either with '@self' (that when built is replaced by the app id) or "immediately" with
40
+ // the app id.
41
+ bundle = bundle.replace(/^(\/?)src\//, "@self/");
42
+ bundle += ".js";
43
+ const viewConfig = { bundle, route };
44
+ routes.push({ viewConfig, module });
28
45
  });
29
46
  return routes;
30
47
  }
48
+ /**
49
+ * Adds the automatically identified view (from the "viewsFolder" folder) to the AppShell configuration and calculate
50
+ * the correspondent module to be generated
51
+ * It guarantees that any new route will not overlap any manual defined route
52
+ * @param config The app Shell config file
53
+ * @param root Project root folder
54
+ * @param viewsFolder Views folder
55
+ * @return the array of modules to be created by the rollup mechanism
56
+ */
31
57
  export function applyAutomaticViewsAndRoutes(config, root, viewsFolder) {
32
58
  const appShellConfiguration = config;
33
- let selfApp = getMainApp(appShellConfiguration);
34
59
  const folder = path.resolve(root, viewsFolder);
35
- if (fs.existsSync(folder)) {
36
- const views = mapIndexFilesToRoutes(findIndexFiles(folder), viewsFolder);
37
- if (views.length > 0) {
38
- if (selfApp == null) {
39
- selfApp = {
40
- id: "@self",
41
- baseUrl: "/"
42
- };
43
- if (appShellConfiguration.apps == null) {
44
- appShellConfiguration.apps = [];
45
- }
46
- appShellConfiguration.apps.push(selfApp);
47
- }
48
- if (selfApp.views != null && selfApp.views.length > 0) {
49
- const nowOverlappingViews = views.filter(view => {
50
- const exists = selfApp.views.some(existingView => existingView.bundle === view.bundle ||
51
- existingView.route === view.route);
52
- return !exists;
53
- });
54
- selfApp.views.push(...nowOverlappingViews);
55
- }
56
- else {
57
- selfApp.views = views;
58
- }
60
+ if (!fs.existsSync(folder)) {
61
+ return [];
62
+ }
63
+ const routes = mapIndexFilesToRoutes(findIndexFiles(folder), viewsFolder);
64
+ const views = routes.map(r => r.viewConfig);
65
+ const modules = routes.map(r => r.module);
66
+ if (routes.length === 0) {
67
+ return [];
68
+ }
69
+ if (!appShellConfiguration.mainPanel?.views ||
70
+ appShellConfiguration.mainPanel.views.length === 0) {
71
+ if (!appShellConfiguration.mainPanel) {
72
+ appShellConfiguration.mainPanel = { views: [] };
59
73
  }
74
+ appShellConfiguration.mainPanel.views = views;
75
+ return modules;
60
76
  }
77
+ const nonOverlappingRoutes = routes.filter(route => {
78
+ const exists = appShellConfiguration.mainPanel?.views?.some(existingView => existingView.bundle === route.viewConfig.bundle ||
79
+ existingView.route === route.viewConfig.route);
80
+ if (exists) {
81
+ console.info(`SKIPPED: View with bundle:[${route.viewConfig.bundle}] or route:[${route.viewConfig.route}] will not be created as their values are already used by another one.`);
82
+ }
83
+ return !exists;
84
+ });
85
+ const nonOverlappingViews = nonOverlappingRoutes.map(r => r.viewConfig);
86
+ const nonOverlappingModules = nonOverlappingRoutes.map(r => r.module);
87
+ appShellConfiguration.mainPanel.views.push(...nonOverlappingViews);
88
+ return nonOverlappingModules;
61
89
  }
62
90
  export function applyAutomaticMenu(config) {
63
91
  const appShellConfiguration = config;
64
- const selfApp = getMainApp(appShellConfiguration);
65
- if (selfApp?.views != null && selfApp.views.length > 0) {
66
- const menu = [];
67
- for (let i = 0; i !== selfApp.views.length; i += 1) {
68
- const view = selfApp.views[i];
69
- // skip dynamic routes (e.g. /list/:id))
70
- if (view.route.indexOf(":") === -1) {
71
- let currentMenu = menu;
72
- const bundleParts = view.bundle.split("/");
73
- const numberOfParts = view.route
74
- .split("/")
75
- .filter(part => part !== "").length;
76
- const srcFolderParts = bundleParts.length - numberOfParts;
77
- if (bundleParts.length > srcFolderParts) {
78
- for (let j = srcFolderParts; j !== bundleParts.length - 1; j += 1) {
79
- const part = bundleParts[j];
80
- let submenu = currentMenu.find(item => item.label === part);
81
- if (submenu == null) {
82
- submenu = {
83
- label: part,
84
- submenus: []
85
- };
86
- currentMenu.push(submenu);
87
- }
88
- currentMenu = submenu.submenus;
89
- }
90
- const label = bundleParts[bundleParts.length - 1];
91
- let menuitem = currentMenu.find(item => item.label === label);
92
- if (menuitem == null) {
93
- menuitem = {
94
- label
95
- };
96
- currentMenu.push(menuitem);
97
- }
98
- menuitem.target = view.route;
99
- }
92
+ if (!appShellConfiguration.mainPanel?.views ||
93
+ appShellConfiguration.mainPanel?.views.length === 0) {
94
+ return;
95
+ }
96
+ const menu = [];
97
+ appShellConfiguration.mainPanel?.views.forEach(view => {
98
+ // skip dynamic routes (e.g. /list/:id))
99
+ if (view.route.indexOf(":") !== -1) {
100
+ return;
101
+ }
102
+ let currentMenu = menu;
103
+ const bundleParts = view.bundle.split("/");
104
+ const numberOfParts = view.route
105
+ .split("/")
106
+ .filter(part => part !== "").length;
107
+ const srcFolderParts = bundleParts.length - numberOfParts;
108
+ if (bundleParts.length <= srcFolderParts) {
109
+ return;
110
+ }
111
+ for (let j = srcFolderParts; j < bundleParts.length - 1; j += 1) {
112
+ const part = bundleParts[j];
113
+ let submenu = currentMenu.find(item => item.label === part);
114
+ if (submenu == null) {
115
+ submenu = {
116
+ label: part,
117
+ submenus: []
118
+ };
119
+ currentMenu.push(submenu);
100
120
  }
121
+ currentMenu = submenu.submenus;
101
122
  }
102
- appShellConfiguration.menu = menu;
103
- }
123
+ const label = bundleParts[bundleParts.length - 1];
124
+ let menuitem = currentMenu.find(item => item.label === label);
125
+ if (menuitem == null) {
126
+ menuitem = {
127
+ label
128
+ };
129
+ currentMenu.push(menuitem);
130
+ }
131
+ menuitem.target = view.route;
132
+ });
133
+ appShellConfiguration.menu = menu;
104
134
  }
105
135
  //# sourceMappingURL=automatic-utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"automatic-utils.js","sourceRoot":"","sources":["../src/automatic-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\n\nimport type {\n HvAppShellConfig,\n HvAppShellViewsConfig\n} from \"@hitachivantara/app-shell-shared\";\n\nimport { getMainApp } from \"./config-utils.js\";\n\nexport function findIndexFiles(dir: string): string[] {\n const files: string[] = [];\n\n fs.readdirSync(dir).forEach(file => {\n const filePath = path.join(dir, file);\n const stat = fs.statSync(filePath);\n\n if (stat.isDirectory()) {\n files.push(...findIndexFiles(filePath));\n } else if (file.match(/^index\\.[tj]sx?$/)) {\n files.push(filePath);\n }\n });\n\n return files;\n}\n\nexport function mapIndexFilesToRoutes(\n files: string[],\n folder: string\n): HvAppShellViewsConfig[] {\n const routes: HvAppShellViewsConfig[] = [];\n\n files.forEach(filePath => {\n const bundle = filePath.substring(\n filePath.lastIndexOf(`/${folder.replace(/^\\/|\\/$/g, \"\")}/`) + 1,\n filePath.lastIndexOf(\"/\")\n );\n const route = bundle\n .replace(new RegExp(`^${folder}`), \"\")\n .replace(/index\\.[t|j]sx?$/, \"\")\n .replaceAll(/\\$/g, \":\")\n .toLowerCase();\n routes.push({ bundle, route });\n });\n\n return routes;\n}\n\nexport function applyAutomaticViewsAndRoutes(\n config: HvAppShellConfig,\n root: string,\n viewsFolder: string\n) {\n const appShellConfiguration = config;\n let selfApp = getMainApp(appShellConfiguration);\n\n const folder = path.resolve(root, viewsFolder);\n if (fs.existsSync(folder)) {\n const views = mapIndexFilesToRoutes(findIndexFiles(folder), viewsFolder);\n\n if (views.length > 0) {\n if (selfApp == null) {\n selfApp = {\n id: \"@self\",\n baseUrl: \"/\"\n };\n if (appShellConfiguration.apps == null) {\n appShellConfiguration.apps = [];\n }\n appShellConfiguration.apps.push(selfApp);\n }\n\n if (selfApp.views != null && selfApp.views.length > 0) {\n const nowOverlappingViews = views.filter(view => {\n const exists = selfApp!.views!.some(\n existingView =>\n existingView.bundle === view.bundle ||\n existingView.route === view.route\n );\n return !exists;\n });\n\n selfApp.views.push(...nowOverlappingViews);\n } else {\n selfApp.views = views;\n }\n }\n }\n}\n\nexport function applyAutomaticMenu(config: HvAppShellConfig) {\n const appShellConfiguration = config;\n const selfApp = getMainApp(appShellConfiguration);\n\n if (selfApp?.views != null && selfApp.views.length > 0) {\n const menu: HvAppShellConfig[\"menu\"] = [];\n\n for (let i = 0; i !== selfApp.views.length; i += 1) {\n const view = selfApp.views[i];\n\n // skip dynamic routes (e.g. /list/:id))\n if (view.route.indexOf(\":\") === -1) {\n let currentMenu = menu;\n const bundleParts = view.bundle.split(\"/\");\n const numberOfParts = view.route\n .split(\"/\")\n .filter(part => part !== \"\").length;\n const srcFolderParts = bundleParts.length - numberOfParts;\n if (bundleParts.length > srcFolderParts) {\n for (let j = srcFolderParts; j !== bundleParts.length - 1; j += 1) {\n const part = bundleParts[j];\n let submenu = currentMenu.find(item => item.label === part);\n if (submenu == null) {\n submenu = {\n label: part,\n submenus: []\n };\n currentMenu.push(submenu);\n }\n currentMenu = submenu.submenus!;\n }\n\n const label = bundleParts[bundleParts.length - 1];\n let menuitem = currentMenu.find(item => item.label === label);\n if (menuitem == null) {\n menuitem = {\n label\n };\n currentMenu.push(menuitem);\n }\n menuitem.target = view.route;\n }\n }\n }\n\n appShellConfiguration.menu = menu;\n }\n}\n"]}
1
+ {"version":3,"file":"automatic-utils.js","sourceRoot":"","sources":["../src/automatic-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\n\nimport type {\n HvAppShellConfig,\n HvAppShellMenuConfig,\n HvAppShellViewsConfig\n} from \"@hitachivantara/app-shell-shared\";\n\n/**\n * Find all the index.tsx or index.jsx files existent at the provided path (including all the subdirectories)\n * @param dir the path to search for the index.tsx or index.jsx files\n */\nexport function findIndexFiles(dir: string): string[] {\n const files: string[] = [];\n\n fs.readdirSync(dir).forEach(file => {\n const filePath = path.join(dir, file);\n const stat = fs.statSync(filePath);\n\n if (stat.isDirectory()) {\n files.push(...findIndexFiles(filePath));\n } else if (/^index\\.[tj]sx?$/.exec(file)) {\n files.push(filePath);\n }\n });\n\n return files;\n}\n\n/**\n * Maps the set of files, to a set of main views config (@see HvAppShellViewsConfig) and the respective module (to be\n * transformed to the final bundle)\n * @param files Set of files to be mapped to a set of new virtual views\n * @param folder The base folder where the files are included\n * @return an array of viewConfig and their correspondent module definition\n */\nexport function mapIndexFilesToRoutes(\n files: string[],\n folder: string\n): {\n viewConfig: HvAppShellViewsConfig;\n module: string;\n}[] {\n const routes: { viewConfig: HvAppShellViewsConfig; module: string }[] = [];\n\n files.forEach(filePath => {\n let bundle = filePath.substring(\n filePath.lastIndexOf(`/${folder.replace(/^\\/|\\/$/g, \"\")}/`) + 1,\n filePath.lastIndexOf(\"/\")\n );\n\n const route = bundle\n .replace(new RegExp(`^${folder}`), \"\")\n .replace(/index\\.[t|j]sx?$/, \"\")\n .replaceAll(/\\$/g, \":\")\n .toLowerCase();\n\n // module to be added when building the application\n const module = bundle;\n\n // src needs to be replaced either with '@self' (that when built is replaced by the app id) or \"immediately\" with\n // the app id.\n bundle = bundle.replace(/^(\\/?)src\\//, \"@self/\");\n bundle += \".js\";\n const viewConfig = { bundle, route };\n routes.push({ viewConfig, module });\n });\n\n return routes;\n}\n\n/**\n * Adds the automatically identified view (from the \"viewsFolder\" folder) to the AppShell configuration and calculate\n * the correspondent module to be generated\n * It guarantees that any new route will not overlap any manual defined route\n * @param config The app Shell config file\n * @param root Project root folder\n * @param viewsFolder Views folder\n * @return the array of modules to be created by the rollup mechanism\n */\nexport function applyAutomaticViewsAndRoutes(\n config: HvAppShellConfig,\n root: string,\n viewsFolder: string\n): string[] {\n const appShellConfiguration = config;\n\n const folder = path.resolve(root, viewsFolder);\n if (!fs.existsSync(folder)) {\n return [];\n }\n\n const routes = mapIndexFilesToRoutes(findIndexFiles(folder), viewsFolder);\n\n const views = routes.map(r => r.viewConfig);\n const modules = routes.map(r => r.module);\n\n if (routes.length === 0) {\n return [];\n }\n\n if (\n !appShellConfiguration.mainPanel?.views ||\n appShellConfiguration.mainPanel.views.length === 0\n ) {\n if (!appShellConfiguration.mainPanel) {\n appShellConfiguration.mainPanel = { views: [] };\n }\n appShellConfiguration.mainPanel.views = views;\n return modules;\n }\n\n const nonOverlappingRoutes = routes.filter(route => {\n const exists = appShellConfiguration.mainPanel?.views?.some(\n existingView =>\n existingView.bundle === route.viewConfig.bundle ||\n existingView.route === route.viewConfig.route\n );\n if (exists) {\n console.info(\n `SKIPPED: View with bundle:[${route.viewConfig.bundle}] or route:[${route.viewConfig.route}] will not be created as their values are already used by another one.`\n );\n }\n return !exists;\n });\n\n const nonOverlappingViews = nonOverlappingRoutes.map(r => r.viewConfig);\n const nonOverlappingModules = nonOverlappingRoutes.map(r => r.module);\n\n appShellConfiguration.mainPanel.views.push(...nonOverlappingViews);\n return nonOverlappingModules;\n}\n\nexport function applyAutomaticMenu(config: HvAppShellConfig) {\n const appShellConfiguration = config;\n\n if (\n !appShellConfiguration.mainPanel?.views ||\n appShellConfiguration.mainPanel?.views.length === 0\n ) {\n return;\n }\n\n const menu: HvAppShellMenuConfig[] = [];\n\n appShellConfiguration.mainPanel?.views.forEach(view => {\n // skip dynamic routes (e.g. /list/:id))\n if (view.route.indexOf(\":\") !== -1) {\n return;\n }\n\n let currentMenu = menu;\n const bundleParts = view.bundle.split(\"/\");\n const numberOfParts = view.route\n .split(\"/\")\n .filter(part => part !== \"\").length;\n const srcFolderParts = bundleParts.length - numberOfParts;\n if (bundleParts.length <= srcFolderParts) {\n return;\n }\n for (let j = srcFolderParts; j < bundleParts.length - 1; j += 1) {\n const part = bundleParts[j];\n let submenu = currentMenu.find(item => item.label === part);\n if (submenu == null) {\n submenu = {\n label: part,\n submenus: []\n };\n currentMenu.push(submenu);\n }\n currentMenu = submenu.submenus!;\n }\n\n const label = bundleParts[bundleParts.length - 1];\n let menuitem = currentMenu.find(item => item.label === label);\n if (menuitem == null) {\n menuitem = {\n label\n };\n currentMenu.push(menuitem);\n }\n menuitem.target = view.route;\n });\n\n appShellConfiguration.menu = menu;\n}\n"]}
@@ -1,4 +1,4 @@
1
- import type { HvAppShellAppsConfig, HvAppShellConfig } from "@hitachivantara/app-shell-shared";
1
+ import type { HvAppShellConfig } from "@hitachivantara/app-shell-shared";
2
2
  import type { AppShellVitePluginOptions } from "./vite-plugin.js";
3
3
  export interface ConfigReplacement {
4
4
  token: string;
@@ -8,11 +8,6 @@ export type AppShellConfigFunction = (pluginOptions: AppShellVitePluginOptions,
8
8
  export declare const DEFAULT_CONFIG_FILES: string[];
9
9
  export declare function findAppShellConfigFile(root: string): string | undefined;
10
10
  export declare function loadConfigFile(appShellConfigFile: string | undefined, opts: AppShellVitePluginOptions, env?: Record<string, string>): HvAppShellConfig;
11
- /**
12
- * Return the main app (identified by @self)
13
- * @param appShellConfig The App shell configuration
14
- */
15
- export declare const getMainApp: (appShellConfig: HvAppShellConfig) => HvAppShellAppsConfig | undefined;
16
11
  /**
17
12
  * Return the public path to be use by vite to launch the application.
18
13
  * Value is obtained by returning the baseUrl value of the main app {@link #getMainApp}
@@ -21,14 +16,12 @@ export declare const getMainApp: (appShellConfig: HvAppShellConfig) => HvAppShel
21
16
  export declare const getPublicPath: (appShellConfig: HvAppShellConfig) => string;
22
17
  /**
23
18
  * Returns the modules to be created by the build of the app.
24
- * The list of modules is defined by the app-shell-config.json file routes ( limited to the @self app)
25
- * The bundles will be created following the original directories structure ( having the src folder path removed)
19
+ * The list of modules is provided via parameter as one of the options used to initialize AppShellVitePlugin. {@link AppShellVitePluginOptions}
26
20
  *
27
21
  * @param root Project root directory.
28
- * @param appShellConfig The App Shell configuration.
29
- * @param selfAppName The name of the application bundle being built.
22
+ * @param modules The list of modules to be exported by the application bundle.
30
23
  */
31
- export declare function getAppModules(root: string, appShellConfig: HvAppShellConfig, selfAppName: string): {
24
+ export declare function getAppModules(root: string, modules?: string[]): {
32
25
  [key: string]: string;
33
26
  };
34
27
  //# sourceMappingURL=config-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config-utils.d.ts","sourceRoot":"","sources":["../src/config-utils.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,oBAAoB,EACpB,gBAAgB,EACjB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAalE,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,sBAAsB,GAAG,CACnC,aAAa,EAAE,yBAAyB,EACxC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KACxB,gBAAgB,CAAC;AAEtB,eAAO,MAAM,oBAAoB,UAIhC,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAUvE;AAED,wBAAgB,cAAc,CAC5B,kBAAkB,EAAE,MAAM,GAAG,SAAS,EACtC,IAAI,EAAE,yBAAyB,EAC/B,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAC/B,gBAAgB,CAgClB;AAED;;;GAGG;AACH,eAAO,MAAM,UAAU,mBACL,gBAAgB,KAC/B,oBAAoB,GAAG,SAEzB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,mBAAoB,gBAAgB,KAAG,MAWhE,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,gBAAgB,EAChC,WAAW,EAAE,MAAM;;EA4DpB"}
1
+ {"version":3,"file":"config-utils.d.ts","sourceRoot":"","sources":["../src/config-utils.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEzE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAalE,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,sBAAsB,GAAG,CACnC,aAAa,EAAE,yBAAyB,EACxC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KACxB,gBAAgB,CAAC;AAEtB,eAAO,MAAM,oBAAoB,UAIhC,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAUvE;AAED,wBAAgB,cAAc,CAC5B,kBAAkB,EAAE,MAAM,GAAG,SAAS,EACtC,IAAI,EAAE,yBAAyB,EAC/B,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAC/B,gBAAgB,CAgClB;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,mBAAoB,gBAAgB,KAAG,MAOhE,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,EAAO;;EAwBjE"}
@@ -42,24 +42,13 @@ export function loadConfigFile(appShellConfigFile, opts, env = {}) {
42
42
  }
43
43
  return loadedAppShellConfig;
44
44
  }
45
- /**
46
- * Return the main app (identified by @self)
47
- * @param appShellConfig The App shell configuration
48
- */
49
- export const getMainApp = (appShellConfig) => {
50
- return appShellConfig.apps?.filter(app => app.id === "@self")[0];
51
- };
52
45
  /**
53
46
  * Return the public path to be use by vite to launch the application.
54
47
  * Value is obtained by returning the baseUrl value of the main app {@link #getMainApp}
55
48
  * @param appShellConfig The App shell configuration
56
49
  */
57
50
  export const getPublicPath = (appShellConfig) => {
58
- const mainApp = getMainApp(appShellConfig);
59
- if (!mainApp) {
60
- return "/";
61
- }
62
- const url = mainApp.baseUrl;
51
+ const url = appShellConfig.baseUrl ?? "/";
63
52
  try {
64
53
  return new URL(url).pathname;
65
54
  }
@@ -69,54 +58,24 @@ export const getPublicPath = (appShellConfig) => {
69
58
  };
70
59
  /**
71
60
  * Returns the modules to be created by the build of the app.
72
- * The list of modules is defined by the app-shell-config.json file routes ( limited to the @self app)
73
- * The bundles will be created following the original directories structure ( having the src folder path removed)
61
+ * The list of modules is provided via parameter as one of the options used to initialize AppShellVitePlugin. {@link AppShellVitePluginOptions}
74
62
  *
75
63
  * @param root Project root directory.
76
- * @param appShellConfig The App Shell configuration.
77
- * @param selfAppName The name of the application bundle being built.
64
+ * @param modules The list of modules to be exported by the application bundle.
78
65
  */
79
- export function getAppModules(root, appShellConfig, selfAppName) {
66
+ export function getAppModules(root, modules = []) {
80
67
  const appModules = {};
81
- const selfApp = getMainApp(appShellConfig);
82
- if (selfApp != null) {
83
- const selfViews = selfApp.views?.map(view => {
84
- const bundleName = view.bundle.replace(/^src\//, "");
85
- return {
86
- ...view,
87
- bundleName
88
- };
89
- }) ?? [];
90
- selfViews.forEach(view => {
91
- appModules[view.bundleName] = path.resolve(root, view.bundle);
92
- });
93
- const selfModules = selfApp.modules?.map(module => {
94
- const bundleName = module.bundle.replace(/^src\//, "");
95
- return {
96
- ...module,
97
- bundleName
98
- };
99
- }) ?? [];
100
- selfModules.forEach(module => {
101
- appModules[module.bundleName] = path.resolve(root, module.bundle);
102
- });
103
- }
104
- const implicitThemeModules = appShellConfig?.theming?.themes?.map(theme => {
105
- if (theme.startsWith("/src/") ||
106
- theme.startsWith("@self/") ||
107
- theme.startsWith(selfAppName)) {
108
- const bundle = theme
109
- .replace(/^@self\//, "")
110
- .replace(new RegExp(`^${selfAppName}/`), "");
111
- const bundleName = bundle.replace(/^(\/?)src\//, "");
68
+ const selfModules = modules?.map(module => {
69
+ if (module.startsWith("src/")) {
70
+ const bundleName = module.replace(/^(\/?)src\//, "");
112
71
  return {
113
- bundle,
72
+ bundle: module,
114
73
  bundleName
115
74
  };
116
75
  }
117
76
  return undefined;
118
77
  }) ?? [];
119
- implicitThemeModules.forEach(module => {
78
+ selfModules.forEach(module => {
120
79
  if (module != null && appModules[module.bundleName] == null) {
121
80
  appModules[module.bundleName] = path.resolve(root, module.bundle);
122
81
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config-utils.js","sourceRoot":"","sources":["../src/config-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\n\nimport { register, createEsmHooks } from \"ts-node\";\n\nimport type {\n HvAppShellAppsConfig,\n HvAppShellConfig\n} from \"@hitachivantara/app-shell-shared\";\n\nimport type { AppShellVitePluginOptions } from \"./vite-plugin.js\";\n\nimport { require } from \"./nodeModule.js\";\n\ncreateEsmHooks(\n register({\n transpileOnly: true,\n moduleTypes: {\n \"app-shell.config.ts\": \"cjs\"\n }\n })\n);\n\nexport interface ConfigReplacement {\n token: string;\n value: string;\n}\n\nexport type AppShellConfigFunction = (\n pluginOptions: AppShellVitePluginOptions,\n env: Record<string, string>\n) => HvAppShellConfig;\n\nexport const DEFAULT_CONFIG_FILES = [\n \"app-shell.config.ts\",\n \"app-shell.config.js\",\n \"app-shell.config.json\"\n];\n\nexport function findAppShellConfigFile(root: string): string | undefined {\n const filename = DEFAULT_CONFIG_FILES.find(file =>\n fs.existsSync(path.resolve(root, file))\n );\n\n if (filename) {\n return path.resolve(root, filename);\n }\n\n return undefined;\n}\n\nexport function loadConfigFile(\n appShellConfigFile: string | undefined,\n opts: AppShellVitePluginOptions,\n env: Record<string, string> = {}\n): HvAppShellConfig {\n if (!appShellConfigFile) {\n // an empty configuration is actually valid\n // and with the automatic views option, it can even make sense\n return {};\n }\n\n if (appShellConfigFile.endsWith(\".json\")) {\n let appShellConfigRaw = fs.readFileSync(appShellConfigFile, \"utf-8\");\n\n // token replacement is only supported for json files\n opts.configReplacements?.forEach(item => {\n appShellConfigRaw = appShellConfigRaw.replaceAll(\n `@@${item.token}@@`,\n item.value\n );\n });\n\n return JSON.parse(appShellConfigRaw) as HvAppShellConfig;\n }\n\n // using require instead of import to avoid using --experimental-loader ts-node/esm\n // eslint-disable-next-line import/no-dynamic-require\n const loadedAppShellConfig = require(appShellConfigFile).default as\n | AppShellConfigFunction\n | HvAppShellConfig;\n\n if (typeof loadedAppShellConfig === \"function\") {\n return loadedAppShellConfig(opts, env);\n }\n\n return loadedAppShellConfig;\n}\n\n/**\n * Return the main app (identified by @self)\n * @param appShellConfig The App shell configuration\n */\nexport const getMainApp = (\n appShellConfig: HvAppShellConfig\n): HvAppShellAppsConfig | undefined => {\n return appShellConfig.apps?.filter(app => app.id === \"@self\")[0];\n};\n\n/**\n * Return the public path to be use by vite to launch the application.\n * Value is obtained by returning the baseUrl value of the main app {@link #getMainApp}\n * @param appShellConfig The App shell configuration\n */\nexport const getPublicPath = (appShellConfig: HvAppShellConfig): string => {\n const mainApp = getMainApp(appShellConfig);\n if (!mainApp) {\n return \"/\";\n }\n const url = mainApp.baseUrl;\n try {\n return new URL(url).pathname;\n } catch {\n return url;\n }\n};\n\n/**\n * Returns the modules to be created by the build of the app.\n * The list of modules is defined by the app-shell-config.json file routes ( limited to the @self app)\n * The bundles will be created following the original directories structure ( having the src folder path removed)\n *\n * @param root Project root directory.\n * @param appShellConfig The App Shell configuration.\n * @param selfAppName The name of the application bundle being built.\n */\nexport function getAppModules(\n root: string,\n appShellConfig: HvAppShellConfig,\n selfAppName: string\n) {\n const appModules: { [key: string]: string } = {};\n\n const selfApp = getMainApp(appShellConfig);\n if (selfApp != null) {\n const selfViews =\n selfApp.views?.map(view => {\n const bundleName = view.bundle.replace(/^src\\//, \"\");\n return {\n ...view,\n bundleName\n };\n }) ?? [];\n\n selfViews.forEach(view => {\n appModules[view.bundleName] = path.resolve(root, view.bundle);\n });\n\n const selfModules =\n selfApp.modules?.map(module => {\n const bundleName = module.bundle.replace(/^src\\//, \"\");\n return {\n ...module,\n bundleName\n };\n }) ?? [];\n\n selfModules.forEach(module => {\n appModules[module.bundleName] = path.resolve(root, module.bundle);\n });\n }\n\n const implicitThemeModules =\n appShellConfig?.theming?.themes?.map(theme => {\n if (\n theme.startsWith(\"/src/\") ||\n theme.startsWith(\"@self/\") ||\n theme.startsWith(selfAppName)\n ) {\n const bundle = theme\n .replace(/^@self\\//, \"\")\n .replace(new RegExp(`^${selfAppName}/`), \"\");\n const bundleName = bundle.replace(/^(\\/?)src\\//, \"\");\n return {\n bundle,\n bundleName\n };\n }\n\n return undefined;\n }) ?? [];\n\n implicitThemeModules.forEach(module => {\n if (module != null && appModules[module.bundleName] == null) {\n appModules[module.bundleName] = path.resolve(root, module.bundle);\n }\n });\n\n return appModules;\n}\n"]}
1
+ {"version":3,"file":"config-utils.js","sourceRoot":"","sources":["../src/config-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\n\nimport { register, createEsmHooks } from \"ts-node\";\n\nimport type { HvAppShellConfig } from \"@hitachivantara/app-shell-shared\";\n\nimport type { AppShellVitePluginOptions } from \"./vite-plugin.js\";\n\nimport { require } from \"./nodeModule.js\";\n\ncreateEsmHooks(\n register({\n transpileOnly: true,\n moduleTypes: {\n \"app-shell.config.ts\": \"cjs\"\n }\n })\n);\n\nexport interface ConfigReplacement {\n token: string;\n value: string;\n}\n\nexport type AppShellConfigFunction = (\n pluginOptions: AppShellVitePluginOptions,\n env: Record<string, string>\n) => HvAppShellConfig;\n\nexport const DEFAULT_CONFIG_FILES = [\n \"app-shell.config.ts\",\n \"app-shell.config.js\",\n \"app-shell.config.json\"\n];\n\nexport function findAppShellConfigFile(root: string): string | undefined {\n const filename = DEFAULT_CONFIG_FILES.find(file =>\n fs.existsSync(path.resolve(root, file))\n );\n\n if (filename) {\n return path.resolve(root, filename);\n }\n\n return undefined;\n}\n\nexport function loadConfigFile(\n appShellConfigFile: string | undefined,\n opts: AppShellVitePluginOptions,\n env: Record<string, string> = {}\n): HvAppShellConfig {\n if (!appShellConfigFile) {\n // an empty configuration is actually valid\n // and with the automatic views option, it can even make sense\n return {};\n }\n\n if (appShellConfigFile.endsWith(\".json\")) {\n let appShellConfigRaw = fs.readFileSync(appShellConfigFile, \"utf-8\");\n\n // token replacement is only supported for json files\n opts.configReplacements?.forEach(item => {\n appShellConfigRaw = appShellConfigRaw.replaceAll(\n `@@${item.token}@@`,\n item.value\n );\n });\n\n return JSON.parse(appShellConfigRaw) as HvAppShellConfig;\n }\n\n // using require instead of import to avoid using --experimental-loader ts-node/esm\n // eslint-disable-next-line import/no-dynamic-require\n const loadedAppShellConfig = require(appShellConfigFile).default as\n | AppShellConfigFunction\n | HvAppShellConfig;\n\n if (typeof loadedAppShellConfig === \"function\") {\n return loadedAppShellConfig(opts, env);\n }\n\n return loadedAppShellConfig;\n}\n\n/**\n * Return the public path to be use by vite to launch the application.\n * Value is obtained by returning the baseUrl value of the main app {@link #getMainApp}\n * @param appShellConfig The App shell configuration\n */\nexport const getPublicPath = (appShellConfig: HvAppShellConfig): string => {\n const url = appShellConfig.baseUrl ?? \"/\";\n try {\n return new URL(url).pathname;\n } catch {\n return url;\n }\n};\n\n/**\n * Returns the modules to be created by the build of the app.\n * The list of modules is provided via parameter as one of the options used to initialize AppShellVitePlugin. {@link AppShellVitePluginOptions}\n *\n * @param root Project root directory.\n * @param modules The list of modules to be exported by the application bundle.\n */\nexport function getAppModules(root: string, modules: string[] = []) {\n const appModules: { [key: string]: string } = {};\n\n const selfModules =\n modules?.map(module => {\n if (module.startsWith(\"src/\")) {\n const bundleName = module.replace(/^(\\/?)src\\//, \"\");\n\n return {\n bundle: module,\n bundleName\n };\n }\n\n return undefined;\n }) ?? [];\n\n selfModules.forEach(module => {\n if (module != null && appModules[module.bundleName] == null) {\n appModules[module.bundleName] = path.resolve(root, module.bundle);\n }\n });\n\n return appModules;\n}\n"]}