@hitachivantara/app-shell-vite-plugin 0.17.11 → 0.18.0
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 +22 -24
- package/dist/automatic-utils.d.ts +25 -2
- package/dist/automatic-utils.d.ts.map +1 -1
- package/dist/automatic-utils.js +97 -67
- package/dist/automatic-utils.js.map +1 -1
- package/dist/config-utils.d.ts +4 -11
- package/dist/config-utils.d.ts.map +1 -1
- package/dist/config-utils.js +9 -50
- package/dist/config-utils.js.map +1 -1
- package/dist/esm-externals/emotion-react.production.min.js.map +1 -1
- package/dist/esm-externals/react-dom.production.min.js +2 -2
- package/dist/esm-externals/react-dom.production.min.js.map +1 -1
- package/dist/esm-externals/react-router-dom.production.min.js +18 -8
- package/dist/esm-externals/react-router-dom.production.min.js.map +1 -1
- package/dist/esm-externals/react.production.min.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/virtual-entrypoints.js +2 -2
- package/dist/virtual-entrypoints.js.map +1 -1
- package/dist/vite-configuration-processor-plugin.d.ts +4 -1
- package/dist/vite-configuration-processor-plugin.d.ts.map +1 -1
- package/dist/vite-configuration-processor-plugin.js +44 -63
- package/dist/vite-configuration-processor-plugin.js.map +1 -1
- package/dist/vite-generate-base-plugin.d.ts +1 -1
- package/dist/vite-generate-base-plugin.js +3 -3
- package/dist/vite-generate-base-plugin.js.map +1 -1
- package/dist/vite-generate-bash-script-plugin.js +5 -5
- package/dist/vite-generate-bash-script-plugin.js.map +1 -1
- package/dist/vite-importmap-plugin.d.ts +1 -1
- package/dist/vite-importmap-plugin.d.ts.map +1 -1
- package/dist/vite-importmap-plugin.js +8 -8
- package/dist/vite-importmap-plugin.js.map +1 -1
- package/dist/vite-metadata-plugin.d.ts +1 -1
- package/dist/vite-metadata-plugin.js +2 -2
- package/dist/vite-metadata-plugin.js.map +1 -1
- package/dist/vite-plugin.d.ts +10 -4
- package/dist/vite-plugin.d.ts.map +1 -1
- package/dist/vite-plugin.js +11 -21
- package/dist/vite-plugin.js.map +1 -1
- package/dist/vite-watch-config-plugin.d.ts +1 -1
- package/dist/vite-watch-config-plugin.d.ts.map +1 -1
- package/dist/vite-watch-config-plugin.js +69 -3
- package/dist/vite-watch-config-plugin.js.map +1 -1
- 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
|
|
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.
|
|
14
|
-
- create virtual endpoints to support dev mode
|
|
15
|
-
- create virtual main.tsx and App.tsx
|
|
16
|
-
|
|
17
|
-
- create
|
|
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.
|
|
26
|
+
Add the plugin to the vite plugin list in `vite.config.ts`.
|
|
29
27
|
|
|
30
|
-
```
|
|
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
|
|
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
|
-
##
|
|
48
|
+
## Configuration properties
|
|
53
49
|
|
|
54
|
-
`
|
|
55
|
-
|
|
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
|
-
|
|
58
|
-
This
|
|
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
|
-
|
|
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
|
-
|
|
4
|
-
|
|
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,
|
|
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"}
|
package/dist/automatic-utils.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
|
-
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
-
|
|
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"]}
|
package/dist/config-utils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
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
|
|
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
|
|
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,
|
|
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,
|
|
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"}
|
package/dist/config-utils.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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,
|
|
66
|
+
export function getAppModules(root, modules = []) {
|
|
80
67
|
const appModules = {};
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
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
|
-
|
|
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
|
}
|
package/dist/config-utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-utils.js","sourceRoot":"","sources":["../src/config-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;
|
|
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"]}
|