@hitachivantara/app-shell-vite-plugin 0.18.7 → 0.18.8
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/dist/automatic-utils.d.ts +5 -10
- package/dist/automatic-utils.d.ts.map +1 -1
- package/dist/automatic-utils.js +23 -16
- package/dist/automatic-utils.js.map +1 -1
- package/dist/tests/automatic-utils.test.d.ts +2 -0
- package/dist/tests/automatic-utils.test.d.ts.map +1 -0
- package/dist/tests/automatic-utils.test.js +109 -0
- package/dist/tests/automatic-utils.test.js.map +1 -0
- package/package.json +2 -2
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
import type { HvAppShellConfig, HvAppShellViewsConfig } from "@hitachivantara/app-shell-shared";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
|
|
6
|
-
|
|
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
|
|
3
|
+
* Maps, through all the index files under viewsFolderPath, to a set of main views config (@see HvAppShellViewsConfig)
|
|
4
|
+
* and the respective module (to be transformed to the final bundle)
|
|
5
|
+
* @param root the absolute path to the views folder
|
|
6
|
+
* @param viewsFolder the relative base folder where the files are included
|
|
12
7
|
* @return an array of viewConfig and their correspondent module definition
|
|
13
8
|
*/
|
|
14
|
-
export declare function
|
|
9
|
+
export declare function mapFolderIndexFilesToRoutes(root: string, viewsFolder: string): {
|
|
15
10
|
viewConfig: HvAppShellViewsConfig;
|
|
16
11
|
module: string;
|
|
17
12
|
}[];
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;AAuB1C;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,GAClB;IACD,UAAU,EAAE,qBAAqB,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;CAChB,EAAE,CA0CF;AAED;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,GAClB,MAAM,EAAE,CAyCV;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,QAoD1D"}
|
package/dist/automatic-utils.js
CHANGED
|
@@ -4,7 +4,7 @@ import path from "path";
|
|
|
4
4
|
* Find all the index.tsx or index.jsx files existent at the provided path (including all the subdirectories)
|
|
5
5
|
* @param dir the path to search for the index.tsx or index.jsx files
|
|
6
6
|
*/
|
|
7
|
-
|
|
7
|
+
function findIndexFiles(dir) {
|
|
8
8
|
const files = [];
|
|
9
9
|
fs.readdirSync(dir).forEach(file => {
|
|
10
10
|
const filePath = path.join(dir, file);
|
|
@@ -19,19 +19,29 @@ export function findIndexFiles(dir) {
|
|
|
19
19
|
return files;
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
22
|
-
* Maps the
|
|
23
|
-
* transformed to the final bundle)
|
|
24
|
-
* @param
|
|
25
|
-
* @param
|
|
22
|
+
* Maps, through all the index files under viewsFolderPath, to a set of main views config (@see HvAppShellViewsConfig)
|
|
23
|
+
* and the respective module (to be transformed to the final bundle)
|
|
24
|
+
* @param root the absolute path to the views folder
|
|
25
|
+
* @param viewsFolder the relative base folder where the files are included
|
|
26
26
|
* @return an array of viewConfig and their correspondent module definition
|
|
27
27
|
*/
|
|
28
|
-
export function
|
|
28
|
+
export function mapFolderIndexFilesToRoutes(root, viewsFolder) {
|
|
29
|
+
// the regex removes any existing '/' either at the start, at the end or in both cases of the viewsFolder parameter.
|
|
30
|
+
const normalizedViewsFolder = viewsFolder.replace(/(^\/|\/$|)/g, "");
|
|
31
|
+
const viewsFolderPath = path.resolve(root, normalizedViewsFolder);
|
|
32
|
+
if (!fs.existsSync(viewsFolderPath)) {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
29
35
|
const routes = [];
|
|
30
|
-
|
|
31
|
-
|
|
36
|
+
const indexFiles = findIndexFiles(viewsFolderPath);
|
|
37
|
+
indexFiles.forEach(filePath => {
|
|
38
|
+
// required to work on Windows and also on Linux/macOS
|
|
39
|
+
const normalizedFilePath = filePath.replaceAll(path.sep, "/");
|
|
40
|
+
// fetches what is between the normalizedViewsFolder (inclusive) and the last '/' (exclusive)
|
|
41
|
+
// example: 'dummy/path/src/pages/Page1/index.tsx' and 'src/pages' returns src/pages/Page1
|
|
42
|
+
let bundle = normalizedFilePath.substring(normalizedFilePath.lastIndexOf(`/${normalizedViewsFolder}/`) + 1, normalizedFilePath.lastIndexOf("/"));
|
|
32
43
|
const route = bundle
|
|
33
|
-
.replace(new RegExp(`^${
|
|
34
|
-
.replace(/index\.[t|j]sx?$/, "")
|
|
44
|
+
.replace(new RegExp(`^${normalizedViewsFolder}`), "")
|
|
35
45
|
.replaceAll(/\$/g, ":")
|
|
36
46
|
.toLowerCase();
|
|
37
47
|
// module to be added when building the application
|
|
@@ -39,6 +49,7 @@ export function mapIndexFilesToRoutes(files, folder) {
|
|
|
39
49
|
// src needs to be replaced either with '@self' (that when built is replaced by the app id) or "immediately" with
|
|
40
50
|
// the app id.
|
|
41
51
|
bundle = bundle.replace(/^(\/?)src\//, "@self/");
|
|
52
|
+
bundle = bundle.replaceAll("$", "_");
|
|
42
53
|
bundle += ".js";
|
|
43
54
|
const viewConfig = { bundle, route };
|
|
44
55
|
routes.push({ viewConfig, module });
|
|
@@ -56,16 +67,12 @@ export function mapIndexFilesToRoutes(files, folder) {
|
|
|
56
67
|
*/
|
|
57
68
|
export function applyAutomaticViewsAndRoutes(config, root, viewsFolder) {
|
|
58
69
|
const appShellConfiguration = config;
|
|
59
|
-
const
|
|
60
|
-
if (
|
|
70
|
+
const routes = mapFolderIndexFilesToRoutes(root, viewsFolder);
|
|
71
|
+
if (routes.length === 0) {
|
|
61
72
|
return [];
|
|
62
73
|
}
|
|
63
|
-
const routes = mapIndexFilesToRoutes(findIndexFiles(folder), viewsFolder);
|
|
64
74
|
const views = routes.map(r => r.viewConfig);
|
|
65
75
|
const modules = routes.map(r => r.module);
|
|
66
|
-
if (routes.length === 0) {
|
|
67
|
-
return [];
|
|
68
|
-
}
|
|
69
76
|
if (!appShellConfiguration.mainPanel?.views ||
|
|
70
77
|
appShellConfiguration.mainPanel.views.length === 0) {
|
|
71
78
|
if (!appShellConfiguration.mainPanel) {
|
|
@@ -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 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
|
+
{"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 */\nfunction 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, through all the index files under viewsFolderPath, to a set of main views config (@see HvAppShellViewsConfig)\n * and the respective module (to be transformed to the final bundle)\n * @param root the absolute path to the views folder\n * @param viewsFolder the relative base folder where the files are included\n * @return an array of viewConfig and their correspondent module definition\n */\nexport function mapFolderIndexFilesToRoutes(\n root: string,\n viewsFolder: string\n): {\n viewConfig: HvAppShellViewsConfig;\n module: string;\n}[] {\n // the regex removes any existing '/' either at the start, at the end or in both cases of the viewsFolder parameter.\n const normalizedViewsFolder = viewsFolder.replace(/(^\\/|\\/$|)/g, \"\");\n\n const viewsFolderPath = path.resolve(root, normalizedViewsFolder);\n if (!fs.existsSync(viewsFolderPath)) {\n return [];\n }\n\n const routes: { viewConfig: HvAppShellViewsConfig; module: string }[] = [];\n const indexFiles = findIndexFiles(viewsFolderPath);\n\n indexFiles.forEach(filePath => {\n // required to work on Windows and also on Linux/macOS\n const normalizedFilePath = filePath.replaceAll(path.sep, \"/\");\n\n // fetches what is between the normalizedViewsFolder (inclusive) and the last '/' (exclusive)\n // example: 'dummy/path/src/pages/Page1/index.tsx' and 'src/pages' returns src/pages/Page1\n let bundle = normalizedFilePath.substring(\n normalizedFilePath.lastIndexOf(`/${normalizedViewsFolder}/`) + 1,\n normalizedFilePath.lastIndexOf(\"/\")\n );\n\n const route = bundle\n .replace(new RegExp(`^${normalizedViewsFolder}`), \"\")\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 = bundle.replaceAll(\"$\", \"_\");\n bundle += \".js\";\n\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 routes = mapFolderIndexFilesToRoutes(root, viewsFolder);\n if (routes.length === 0) {\n return [];\n }\n\n const views = routes.map(r => r.viewConfig);\n const modules = routes.map(r => r.module);\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"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"automatic-utils.test.d.ts","sourceRoot":"","sources":["../../src/tests/automatic-utils.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { expect } from "vitest";
|
|
2
|
+
import mock from "mock-fs";
|
|
3
|
+
import { mapFolderIndexFilesToRoutes } from "../automatic-utils";
|
|
4
|
+
describe("test automatic utils", () => {
|
|
5
|
+
describe("test `mapFolderIndexFilesToRoutes` method", () => {
|
|
6
|
+
afterEach(() => {
|
|
7
|
+
mock.restore();
|
|
8
|
+
});
|
|
9
|
+
it("should return an empty array when resolved views folder does not exist", () => {
|
|
10
|
+
const root = "/some/other/root";
|
|
11
|
+
const viewsFolder = "src/pages";
|
|
12
|
+
mock({
|
|
13
|
+
"/dummy/path/app/src/pages/Page3": {
|
|
14
|
+
"something.else": "dummy content"
|
|
15
|
+
},
|
|
16
|
+
"/dummy/path/app/src/pages/Page4": {
|
|
17
|
+
/** empty directory */
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
expect(mapFolderIndexFilesToRoutes(root, viewsFolder)).toEqual([]);
|
|
21
|
+
});
|
|
22
|
+
it("should return an empty array when there are no index files in the resolved views folder", () => {
|
|
23
|
+
const root = "/dummy/path/app";
|
|
24
|
+
const viewsFolder = "src/pages";
|
|
25
|
+
mock({
|
|
26
|
+
"/dummy/path/app/src/pages": {},
|
|
27
|
+
"/dummy/path/app/src/pages/Page3": {
|
|
28
|
+
"something.else": "dummy content"
|
|
29
|
+
},
|
|
30
|
+
"/dummy/path/app/src/pages/Page4": {
|
|
31
|
+
/** empty directory */
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
expect(mapFolderIndexFilesToRoutes(root, viewsFolder)).toEqual([]);
|
|
35
|
+
});
|
|
36
|
+
test.each([
|
|
37
|
+
["/dummy/path/app", "src/pages"],
|
|
38
|
+
["/dummy/path/app", "src/pages/"],
|
|
39
|
+
["/dummy/path/app", "/src/pages/"],
|
|
40
|
+
["/dummy/path/app", "/src/pages"]
|
|
41
|
+
])("should return all mapped main view configs and corresponding modules", (viewsFolderPath, viewsFolder) => {
|
|
42
|
+
mock({
|
|
43
|
+
"/dummy/path/app/src/pages": {},
|
|
44
|
+
"/dummy/path/app/src/pages/Page1": {
|
|
45
|
+
"index.tsx": "dummy content"
|
|
46
|
+
},
|
|
47
|
+
"/dummy/path/app/src/pages/Page2": {
|
|
48
|
+
"something.else": "dummy content"
|
|
49
|
+
},
|
|
50
|
+
"/dummy/path/app/src/pages/Page3": {
|
|
51
|
+
"index.tsx": "dummy content"
|
|
52
|
+
},
|
|
53
|
+
"/dummy/path/app/src/pages/Page4": {
|
|
54
|
+
/** empty directory */
|
|
55
|
+
},
|
|
56
|
+
"/dummy/path/app/src/pages/Page5/$id": {
|
|
57
|
+
"index.tsx": "dummy content"
|
|
58
|
+
},
|
|
59
|
+
"/dummy/path/app/src/pages/Page5/$id/Page5_1": {
|
|
60
|
+
"index.tsx": "dummy content"
|
|
61
|
+
},
|
|
62
|
+
"/dummy/path/app/src/pages/Page5/$id/Page5_1/$name": {
|
|
63
|
+
/** empty directory */
|
|
64
|
+
},
|
|
65
|
+
"/dummy/path/app/src/pages/Page5/$id/Page5_1/$name/Page5_2": {
|
|
66
|
+
"index.tsx": "dummy content"
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
expect(mapFolderIndexFilesToRoutes(viewsFolderPath, viewsFolder)).toEqual([
|
|
70
|
+
{
|
|
71
|
+
viewConfig: {
|
|
72
|
+
bundle: "@self/pages/Page1.js",
|
|
73
|
+
route: "/page1"
|
|
74
|
+
},
|
|
75
|
+
module: "src/pages/Page1"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
viewConfig: {
|
|
79
|
+
bundle: "@self/pages/Page3.js",
|
|
80
|
+
route: "/page3"
|
|
81
|
+
},
|
|
82
|
+
module: "src/pages/Page3"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
viewConfig: {
|
|
86
|
+
bundle: "@self/pages/Page5/_id/Page5_1/_name/Page5_2.js",
|
|
87
|
+
route: "/page5/:id/page5_1/:name/page5_2"
|
|
88
|
+
},
|
|
89
|
+
module: "src/pages/Page5/$id/Page5_1/$name/Page5_2"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
viewConfig: {
|
|
93
|
+
bundle: "@self/pages/Page5/_id/Page5_1.js",
|
|
94
|
+
route: "/page5/:id/page5_1"
|
|
95
|
+
},
|
|
96
|
+
module: "src/pages/Page5/$id/Page5_1"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
viewConfig: {
|
|
100
|
+
bundle: "@self/pages/Page5/_id.js",
|
|
101
|
+
route: "/page5/:id"
|
|
102
|
+
},
|
|
103
|
+
module: "src/pages/Page5/$id"
|
|
104
|
+
}
|
|
105
|
+
]);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
//# sourceMappingURL=automatic-utils.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"automatic-utils.test.js","sourceRoot":"","sources":["../../src/tests/automatic-utils.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAEjE,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,QAAQ,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACzD,SAAS,CAAC,GAAG,EAAE;YACb,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;YAChF,MAAM,IAAI,GAAG,kBAAkB,CAAC;YAChC,MAAM,WAAW,GAAG,WAAW,CAAC;YAEhC,IAAI,CAAC;gBACH,iCAAiC,EAAE;oBACjC,gBAAgB,EAAE,eAAe;iBAClC;gBACD,iCAAiC,EAAE;gBACjC,sBAAsB;iBACvB;aACF,CAAC,CAAC;YAEH,MAAM,CAAC,2BAA2B,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yFAAyF,EAAE,GAAG,EAAE;YACjG,MAAM,IAAI,GAAG,iBAAiB,CAAC;YAC/B,MAAM,WAAW,GAAG,WAAW,CAAC;YAEhC,IAAI,CAAC;gBACH,2BAA2B,EAAE,EAAE;gBAC/B,iCAAiC,EAAE;oBACjC,gBAAgB,EAAE,eAAe;iBAClC;gBACD,iCAAiC,EAAE;gBACjC,sBAAsB;iBACvB;aACF,CAAC,CAAC;YAEH,MAAM,CAAC,2BAA2B,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,CAAC;YACR,CAAC,iBAAiB,EAAE,WAAW,CAAC;YAChC,CAAC,iBAAiB,EAAE,YAAY,CAAC;YACjC,CAAC,iBAAiB,EAAE,aAAa,CAAC;YAClC,CAAC,iBAAiB,EAAE,YAAY,CAAC;SAClC,CAAC,CACA,sEAAsE,EACtE,CAAC,eAAuB,EAAE,WAAmB,EAAE,EAAE;YAC/C,IAAI,CAAC;gBACH,2BAA2B,EAAE,EAAE;gBAC/B,iCAAiC,EAAE;oBACjC,WAAW,EAAE,eAAe;iBAC7B;gBACD,iCAAiC,EAAE;oBACjC,gBAAgB,EAAE,eAAe;iBAClC;gBACD,iCAAiC,EAAE;oBACjC,WAAW,EAAE,eAAe;iBAC7B;gBACD,iCAAiC,EAAE;gBACjC,sBAAsB;iBACvB;gBACD,qCAAqC,EAAE;oBACrC,WAAW,EAAE,eAAe;iBAC7B;gBACD,6CAA6C,EAAE;oBAC7C,WAAW,EAAE,eAAe;iBAC7B;gBACD,mDAAmD,EAAE;gBACnD,sBAAsB;iBACvB;gBACD,2DAA2D,EAAE;oBAC3D,WAAW,EAAE,eAAe;iBAC7B;aACF,CAAC,CAAC;YAEH,MAAM,CACJ,2BAA2B,CAAC,eAAe,EAAE,WAAW,CAAC,CAC1D,CAAC,OAAO,CAAC;gBACR;oBACE,UAAU,EAAE;wBACV,MAAM,EAAE,sBAAsB;wBAC9B,KAAK,EAAE,QAAQ;qBAChB;oBACD,MAAM,EAAE,iBAAiB;iBAC1B;gBACD;oBACE,UAAU,EAAE;wBACV,MAAM,EAAE,sBAAsB;wBAC9B,KAAK,EAAE,QAAQ;qBAChB;oBACD,MAAM,EAAE,iBAAiB;iBAC1B;gBACD;oBACE,UAAU,EAAE;wBACV,MAAM,EAAE,gDAAgD;wBACxD,KAAK,EAAE,kCAAkC;qBAC1C;oBACD,MAAM,EAAE,2CAA2C;iBACpD;gBACD;oBACE,UAAU,EAAE;wBACV,MAAM,EAAE,kCAAkC;wBAC1C,KAAK,EAAE,oBAAoB;qBAC5B;oBACD,MAAM,EAAE,6BAA6B;iBACtC;gBACD;oBACE,UAAU,EAAE;wBACV,MAAM,EAAE,0BAA0B;wBAClC,KAAK,EAAE,YAAY;qBACpB;oBACD,MAAM,EAAE,qBAAqB;iBAC9B;aACF,CAAC,CAAC;QACL,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { expect } from \"vitest\";\nimport mock from \"mock-fs\";\nimport { mapFolderIndexFilesToRoutes } from \"../automatic-utils\";\n\ndescribe(\"test automatic utils\", () => {\n describe(\"test `mapFolderIndexFilesToRoutes` method\", () => {\n afterEach(() => {\n mock.restore();\n });\n\n it(\"should return an empty array when resolved views folder does not exist\", () => {\n const root = \"/some/other/root\";\n const viewsFolder = \"src/pages\";\n\n mock({\n \"/dummy/path/app/src/pages/Page3\": {\n \"something.else\": \"dummy content\"\n },\n \"/dummy/path/app/src/pages/Page4\": {\n /** empty directory */\n }\n });\n\n expect(mapFolderIndexFilesToRoutes(root, viewsFolder)).toEqual([]);\n });\n\n it(\"should return an empty array when there are no index files in the resolved views folder\", () => {\n const root = \"/dummy/path/app\";\n const viewsFolder = \"src/pages\";\n\n mock({\n \"/dummy/path/app/src/pages\": {},\n \"/dummy/path/app/src/pages/Page3\": {\n \"something.else\": \"dummy content\"\n },\n \"/dummy/path/app/src/pages/Page4\": {\n /** empty directory */\n }\n });\n\n expect(mapFolderIndexFilesToRoutes(root, viewsFolder)).toEqual([]);\n });\n\n test.each([\n [\"/dummy/path/app\", \"src/pages\"],\n [\"/dummy/path/app\", \"src/pages/\"],\n [\"/dummy/path/app\", \"/src/pages/\"],\n [\"/dummy/path/app\", \"/src/pages\"]\n ])(\n \"should return all mapped main view configs and corresponding modules\",\n (viewsFolderPath: string, viewsFolder: string) => {\n mock({\n \"/dummy/path/app/src/pages\": {},\n \"/dummy/path/app/src/pages/Page1\": {\n \"index.tsx\": \"dummy content\"\n },\n \"/dummy/path/app/src/pages/Page2\": {\n \"something.else\": \"dummy content\"\n },\n \"/dummy/path/app/src/pages/Page3\": {\n \"index.tsx\": \"dummy content\"\n },\n \"/dummy/path/app/src/pages/Page4\": {\n /** empty directory */\n },\n \"/dummy/path/app/src/pages/Page5/$id\": {\n \"index.tsx\": \"dummy content\"\n },\n \"/dummy/path/app/src/pages/Page5/$id/Page5_1\": {\n \"index.tsx\": \"dummy content\"\n },\n \"/dummy/path/app/src/pages/Page5/$id/Page5_1/$name\": {\n /** empty directory */\n },\n \"/dummy/path/app/src/pages/Page5/$id/Page5_1/$name/Page5_2\": {\n \"index.tsx\": \"dummy content\"\n }\n });\n\n expect(\n mapFolderIndexFilesToRoutes(viewsFolderPath, viewsFolder)\n ).toEqual([\n {\n viewConfig: {\n bundle: \"@self/pages/Page1.js\",\n route: \"/page1\"\n },\n module: \"src/pages/Page1\"\n },\n {\n viewConfig: {\n bundle: \"@self/pages/Page3.js\",\n route: \"/page3\"\n },\n module: \"src/pages/Page3\"\n },\n {\n viewConfig: {\n bundle: \"@self/pages/Page5/_id/Page5_1/_name/Page5_2.js\",\n route: \"/page5/:id/page5_1/:name/page5_2\"\n },\n module: \"src/pages/Page5/$id/Page5_1/$name/Page5_2\"\n },\n {\n viewConfig: {\n bundle: \"@self/pages/Page5/_id/Page5_1.js\",\n route: \"/page5/:id/page5_1\"\n },\n module: \"src/pages/Page5/$id/Page5_1\"\n },\n {\n viewConfig: {\n bundle: \"@self/pages/Page5/_id.js\",\n route: \"/page5/:id\"\n },\n module: \"src/pages/Page5/$id\"\n }\n ]);\n }\n );\n });\n});\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hitachivantara/app-shell-vite-plugin",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.8",
|
|
4
4
|
"description": "AppShell Vite Plugin",
|
|
5
5
|
"author": "Hitachi Vantara - Boba Fett Team",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -64,5 +64,5 @@
|
|
|
64
64
|
"peerDependencies": {
|
|
65
65
|
"vite": "^4.1.4 || ^5.0.4"
|
|
66
66
|
},
|
|
67
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "04781210ddd317d7a4c6f256d765653794e0b366"
|
|
68
68
|
}
|