@hitachivantara/app-shell-vite-plugin 2.2.1 → 2.4.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/dist/automatic-utils.js +7 -3
- package/dist/locales-utils.d.ts +19 -11
- package/dist/locales-utils.js +51 -52
- package/dist/nodeModule.d.ts +1 -1
- package/dist/vite-configuration-processor-plugin.d.ts +22 -8
- package/dist/vite-configuration-processor-plugin.js +10 -11
- package/dist/vite-crossorigin-fix-plugin.js +1 -1
- package/dist/vite-dist-package-json-plugin.d.ts +5 -0
- package/dist/vite-dist-package-json-plugin.js +211 -0
- package/dist/vite-locales-plugin.d.ts +13 -3
- package/dist/vite-locales-plugin.js +71 -25
- package/dist/vite-plugin.d.ts +36 -0
- package/dist/vite-plugin.js +18 -3
- package/dist/vite-watch-config-plugin.js +2 -0
- package/package.json +7 -8
package/dist/automatic-utils.js
CHANGED
|
@@ -62,7 +62,7 @@ export function mapFolderIndexFilesToRoutes(root, viewsFolder) {
|
|
|
62
62
|
.replaceAll(/\$/g, ":")
|
|
63
63
|
.toLowerCase();
|
|
64
64
|
const viewConfig = {
|
|
65
|
-
bundle:
|
|
65
|
+
bundle: `$app/${getFinalModuleName(bundle)}.js`,
|
|
66
66
|
route,
|
|
67
67
|
};
|
|
68
68
|
routes.push({ viewConfig, module: bundle });
|
|
@@ -102,11 +102,15 @@ export function applyAutomaticViewsAndRoutes(config, selfAppName, root, viewsFol
|
|
|
102
102
|
const flattenedViews = flattenViews(appShellConfiguration.mainPanel.views);
|
|
103
103
|
const existingRoutes = flattenedViews.map((view) => view.route);
|
|
104
104
|
const existingBundles = flattenedViews.reduce((bundles, view) => {
|
|
105
|
-
if (view.bundle.startsWith("
|
|
105
|
+
if (view.bundle.startsWith("$app/")) {
|
|
106
106
|
bundles.push(view.bundle);
|
|
107
107
|
}
|
|
108
|
+
else if (view.bundle.startsWith("@self/")) {
|
|
109
|
+
// TODO(major): remove @self/ support in favour of $app/
|
|
110
|
+
bundles.push(view.bundle.replace("@self/", "$app/"));
|
|
111
|
+
}
|
|
108
112
|
else if (view.bundle.startsWith(selfAppName)) {
|
|
109
|
-
bundles.push(view.bundle.replace(selfAppName, "
|
|
113
|
+
bundles.push(view.bundle.replace(selfAppName, "$app"));
|
|
110
114
|
}
|
|
111
115
|
return bundles;
|
|
112
116
|
}, []);
|
package/dist/locales-utils.d.ts
CHANGED
|
@@ -15,16 +15,20 @@ export declare function readSupportedLocales(filePath: string): string[];
|
|
|
15
15
|
*/
|
|
16
16
|
export declare function discoverLanguageDirs(localesDir: string): string[];
|
|
17
17
|
/**
|
|
18
|
-
* Computes the
|
|
18
|
+
* Computes the effective supported-locales list.
|
|
19
19
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* manifest (alphabetical order).
|
|
20
|
+
* Discovers all language directories from both sources (upstream shell and
|
|
21
|
+
* local app). If the app provides a `supported-locales.json`, it acts as a
|
|
22
|
+
* **filter**: only locales listed there are kept. Otherwise all discovered
|
|
23
|
+
* locales are included.
|
|
25
24
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
25
|
+
* The result is always sorted alphabetically.
|
|
26
|
+
*
|
|
27
|
+
* Locales listed in the local manifest but without a matching language
|
|
28
|
+
* directory are warned about and dropped.
|
|
29
|
+
*
|
|
30
|
+
* @param shellLocalesDir - The app-shell-ui locales directory (upstream).
|
|
31
|
+
* @param appLocalesDir - The app's locales directory (downstream / local).
|
|
28
32
|
*/
|
|
29
33
|
export declare function computeSupportedLocales(shellLocalesDir: string | undefined, appLocalesDir: string | undefined): string[];
|
|
30
34
|
/**
|
|
@@ -38,7 +42,11 @@ export declare function readJsonFile(filePath: string): unknown;
|
|
|
38
42
|
* Non-JSON files are skipped (locale bundles are always JSON).
|
|
39
43
|
*
|
|
40
44
|
* `supported-locales.json` is skipped — it is handled separately after the
|
|
41
|
-
* merge so it can reflect the
|
|
42
|
-
*
|
|
45
|
+
* merge so it can reflect the computed list.
|
|
46
|
+
*
|
|
47
|
+
* When `allowedLocales` is provided, only top-level directories whose name
|
|
48
|
+
* is in the set are merged; all others are skipped. This allows the app's
|
|
49
|
+
* `supported-locales.json` to act as a filter over upstream locale dirs.
|
|
50
|
+
* Sub-directories (namespace folders) are always merged recursively.
|
|
43
51
|
*/
|
|
44
|
-
export declare function mergeDirs(src: string, dest: string): void;
|
|
52
|
+
export declare function mergeDirs(src: string, dest: string, allowedLocales?: Set<string>): void;
|
package/dist/locales-utils.js
CHANGED
|
@@ -54,53 +54,23 @@ export function discoverLanguageDirs(localesDir) {
|
|
|
54
54
|
.toSorted();
|
|
55
55
|
}
|
|
56
56
|
/**
|
|
57
|
-
* Computes the
|
|
57
|
+
* Computes the effective supported-locales list.
|
|
58
58
|
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
* manifest (alphabetical order).
|
|
59
|
+
* Discovers all language directories from both sources (upstream shell and
|
|
60
|
+
* local app). If the app provides a `supported-locales.json`, it acts as a
|
|
61
|
+
* **filter**: only locales listed there are kept. Otherwise all discovered
|
|
62
|
+
* locales are included.
|
|
64
63
|
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
64
|
+
* The result is always sorted alphabetically.
|
|
65
|
+
*
|
|
66
|
+
* Locales listed in the local manifest but without a matching language
|
|
67
|
+
* directory are warned about and dropped.
|
|
68
|
+
*
|
|
69
|
+
* @param shellLocalesDir - The app-shell-ui locales directory (upstream).
|
|
70
|
+
* @param appLocalesDir - The app's locales directory (downstream / local).
|
|
67
71
|
*/
|
|
68
72
|
export function computeSupportedLocales(shellLocalesDir, appLocalesDir) {
|
|
69
|
-
|
|
70
|
-
const result = [];
|
|
71
|
-
const addUnique = (lng) => {
|
|
72
|
-
if (!seen.has(lng)) {
|
|
73
|
-
seen.add(lng);
|
|
74
|
-
result.push(lng);
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
// 1. App manifest entries first (highest priority order)
|
|
78
|
-
if (appLocalesDir) {
|
|
79
|
-
for (const lng of readSupportedLocales(path.join(appLocalesDir, SUPPORTED_LOCALES_FILE))) {
|
|
80
|
-
addUnique(lng);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
// 2. Shell manifest entries that weren't already listed
|
|
84
|
-
if (shellLocalesDir) {
|
|
85
|
-
for (const lng of readSupportedLocales(path.join(shellLocalesDir, SUPPORTED_LOCALES_FILE))) {
|
|
86
|
-
addUnique(lng);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
// 3. Discovered language directories not in either manifest (alphabetical)
|
|
90
|
-
const discoveredDirs = [];
|
|
91
|
-
for (const dir of [shellLocalesDir, appLocalesDir]) {
|
|
92
|
-
if (dir) {
|
|
93
|
-
for (const lng of discoverLanguageDirs(dir)) {
|
|
94
|
-
if (!seen.has(lng))
|
|
95
|
-
discoveredDirs.push(lng);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
// deduplicate and sort before appending
|
|
100
|
-
for (const lng of [...new Set(discoveredDirs)].toSorted()) {
|
|
101
|
-
addUnique(lng);
|
|
102
|
-
}
|
|
103
|
-
// Validate: warn and drop manifest entries without a matching language directory
|
|
73
|
+
// Collect all language directories that actually exist on disk
|
|
104
74
|
const allDirs = new Set();
|
|
105
75
|
for (const dir of [shellLocalesDir, appLocalesDir]) {
|
|
106
76
|
if (dir) {
|
|
@@ -109,12 +79,33 @@ export function computeSupportedLocales(shellLocalesDir, appLocalesDir) {
|
|
|
109
79
|
}
|
|
110
80
|
}
|
|
111
81
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
82
|
+
// Determine if the app provides a supported-locales.json file.
|
|
83
|
+
// Physical existence of the file is what matters — even if it's empty,
|
|
84
|
+
// malformed, or contains no valid entries, it still acts as a filter
|
|
85
|
+
// (resulting in an empty effective locale list).
|
|
86
|
+
const manifestPath = appLocalesDir
|
|
87
|
+
? path.join(appLocalesDir, SUPPORTED_LOCALES_FILE)
|
|
88
|
+
: undefined;
|
|
89
|
+
const hasLocalManifest = manifestPath ? fs.existsSync(manifestPath) : false;
|
|
90
|
+
// Read the manifest entries (empty if file is missing/invalid)
|
|
91
|
+
const localManifest = manifestPath ? readSupportedLocales(manifestPath) : [];
|
|
92
|
+
// Determine the effective set of locales
|
|
93
|
+
let result;
|
|
94
|
+
if (hasLocalManifest) {
|
|
95
|
+
// Filter: only keep unique locales from the manifest that have a directory.
|
|
96
|
+
// If the manifest is empty/malformed, this correctly yields an empty list.
|
|
97
|
+
result = [...new Set(localManifest)].filter((lng) => {
|
|
98
|
+
if (allDirs.has(lng))
|
|
99
|
+
return true;
|
|
100
|
+
console.warn(`[app-shell-locales] Locale "${lng}" is listed in ${SUPPORTED_LOCALES_FILE} but has no corresponding language directory — ignoring.`);
|
|
101
|
+
return false;
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
// No local manifest → include everything discovered
|
|
106
|
+
result = [...allDirs];
|
|
107
|
+
}
|
|
108
|
+
return result.toSorted();
|
|
118
109
|
}
|
|
119
110
|
/**
|
|
120
111
|
* Parses a JSON file, wrapping parse errors with the file path for
|
|
@@ -135,15 +126,23 @@ export function readJsonFile(filePath) {
|
|
|
135
126
|
* Non-JSON files are skipped (locale bundles are always JSON).
|
|
136
127
|
*
|
|
137
128
|
* `supported-locales.json` is skipped — it is handled separately after the
|
|
138
|
-
* merge so it can reflect the
|
|
139
|
-
*
|
|
129
|
+
* merge so it can reflect the computed list.
|
|
130
|
+
*
|
|
131
|
+
* When `allowedLocales` is provided, only top-level directories whose name
|
|
132
|
+
* is in the set are merged; all others are skipped. This allows the app's
|
|
133
|
+
* `supported-locales.json` to act as a filter over upstream locale dirs.
|
|
134
|
+
* Sub-directories (namespace folders) are always merged recursively.
|
|
140
135
|
*/
|
|
141
|
-
export function mergeDirs(src, dest) {
|
|
136
|
+
export function mergeDirs(src, dest, allowedLocales) {
|
|
142
137
|
fs.mkdirSync(dest, { recursive: true });
|
|
143
138
|
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
144
139
|
const srcPath = path.join(src, entry.name);
|
|
145
140
|
const destPath = path.join(dest, entry.name);
|
|
146
141
|
if (entry.isDirectory()) {
|
|
142
|
+
// At the top level, skip locale dirs not in the allowed set
|
|
143
|
+
if (allowedLocales && !allowedLocales.has(entry.name))
|
|
144
|
+
continue;
|
|
145
|
+
// Sub-directories are always merged (no further filtering)
|
|
147
146
|
mergeDirs(srcPath, destPath);
|
|
148
147
|
}
|
|
149
148
|
else if (entry.name === SUPPORTED_LOCALES_FILE) {
|
package/dist/nodeModule.d.ts
CHANGED
|
@@ -6,4 +6,4 @@ export declare const require: NodeJS.Require;
|
|
|
6
6
|
* @param suffix to be added after the module path
|
|
7
7
|
* @returns The module path normalized
|
|
8
8
|
*/
|
|
9
|
-
export declare function resolveModule(moduleName: string, suffix?: string):
|
|
9
|
+
export declare function resolveModule(moduleName: string, suffix?: string): any;
|
|
@@ -1,16 +1,30 @@
|
|
|
1
1
|
import type { PluginOption } from "vite";
|
|
2
2
|
import type { HvAppShellConfig } from "@hitachivantara/app-shell-shared";
|
|
3
|
+
/**
|
|
4
|
+
* Options for the configuration processor plugin.
|
|
5
|
+
*/
|
|
6
|
+
export interface ProcessConfigurationOptions {
|
|
7
|
+
/** Project root directory. */
|
|
8
|
+
root: string;
|
|
9
|
+
/** The original App Shell configuration json. */
|
|
10
|
+
appShellConfig: HvAppShellConfig;
|
|
11
|
+
/** The name of the application bundle being built. */
|
|
12
|
+
selfAppName: string;
|
|
13
|
+
/** The set of modules to be created by the rollup. */
|
|
14
|
+
modules: string[];
|
|
15
|
+
/** If true, the index.html entry point will be added to the bundle. */
|
|
16
|
+
buildEntryPoint: boolean;
|
|
17
|
+
/** Flag to control if config is included at index.html. */
|
|
18
|
+
inlineConfig: boolean;
|
|
19
|
+
/** Flag to control if we are creating an empty AppShell instance. */
|
|
20
|
+
generateEmptyShell: boolean;
|
|
21
|
+
/** If true, always writes app-shell.config.json to dist for dual-use packages. */
|
|
22
|
+
experimentalNewPackageLayout: boolean;
|
|
23
|
+
}
|
|
3
24
|
/**
|
|
4
25
|
* Process configuration, executing several tasks:
|
|
5
26
|
* - Create rollup configuration to support module creation
|
|
6
27
|
* - Generates final transformed configuration json
|
|
7
28
|
* - "base" value is always "./" for build, and main app baseUrl for preview or dev
|
|
8
|
-
* @param root Project root directory.
|
|
9
|
-
* @param appShellConfig The original App Shell configuration json.
|
|
10
|
-
* @param selfAppName The name of the application bundle being built.
|
|
11
|
-
* @param buildEntryPoint If true, the index.html entry point will be added to the bundle.
|
|
12
|
-
* @param inlineConfig flag to control if config is included at index.html
|
|
13
|
-
* @param generateEmptyShell flag to control if we are creating an empty AppShell instance
|
|
14
|
-
* @param modules the set of modules to be created by the rollup
|
|
15
29
|
*/
|
|
16
|
-
export default function processConfiguration(
|
|
30
|
+
export default function processConfiguration(options: ProcessConfigurationOptions): PluginOption;
|
|
@@ -7,15 +7,9 @@ import sharedDependencies from "./shared-dependencies.js";
|
|
|
7
7
|
* - Create rollup configuration to support module creation
|
|
8
8
|
* - Generates final transformed configuration json
|
|
9
9
|
* - "base" value is always "./" for build, and main app baseUrl for preview or dev
|
|
10
|
-
* @param root Project root directory.
|
|
11
|
-
* @param appShellConfig The original App Shell configuration json.
|
|
12
|
-
* @param selfAppName The name of the application bundle being built.
|
|
13
|
-
* @param buildEntryPoint If true, the index.html entry point will be added to the bundle.
|
|
14
|
-
* @param inlineConfig flag to control if config is included at index.html
|
|
15
|
-
* @param generateEmptyShell flag to control if we are creating an empty AppShell instance
|
|
16
|
-
* @param modules the set of modules to be created by the rollup
|
|
17
10
|
*/
|
|
18
|
-
export default function processConfiguration(
|
|
11
|
+
export default function processConfiguration(options) {
|
|
12
|
+
const { root, appShellConfig, selfAppName, modules, buildEntryPoint, inlineConfig, generateEmptyShell, experimentalNewPackageLayout, } = options;
|
|
19
13
|
let finalAppShellConfig;
|
|
20
14
|
let basePath;
|
|
21
15
|
return {
|
|
@@ -58,7 +52,7 @@ export default function processConfiguration(root, appShellConfig, selfAppName,
|
|
|
58
52
|
* @param options build options
|
|
59
53
|
*/
|
|
60
54
|
async generateBundle(options) {
|
|
61
|
-
if (generateEmptyShell
|
|
55
|
+
if (generateEmptyShell) {
|
|
62
56
|
return;
|
|
63
57
|
}
|
|
64
58
|
// obtain the directory (dist) where the new config file will be placed
|
|
@@ -82,11 +76,16 @@ export default function processConfiguration(root, appShellConfig, selfAppName,
|
|
|
82
76
|
finalAppShellConfig.baseUrl = basePath;
|
|
83
77
|
}
|
|
84
78
|
finalAppShellConfig.apps = undefined;
|
|
85
|
-
// Replace all @self references using simple string replacement
|
|
79
|
+
// Replace all $app and @self (deprecated) references using simple string replacement.
|
|
86
80
|
let configString = JSON.stringify(finalAppShellConfig);
|
|
81
|
+
configString = configString.replaceAll(`"$app/`, `"${selfAppName}/`);
|
|
82
|
+
// TODO(major): remove @self/ support in favour of $app/
|
|
87
83
|
configString = configString.replaceAll(`"@self/`, `"${selfAppName}/`);
|
|
88
84
|
finalAppShellConfig = JSON.parse(configString);
|
|
89
|
-
|
|
85
|
+
// Write app-shell.config.json to dist when:
|
|
86
|
+
// - inlineConfig is false (standard flow), OR
|
|
87
|
+
// - experimentalNewPackageLayout is true (ensures dual-use: app shell or app bundle)
|
|
88
|
+
if (!inlineConfig || experimentalNewPackageLayout) {
|
|
90
89
|
fs.writeFileSync(path.resolve(targetDir, "app-shell.config.json"), JSON.stringify(finalAppShellConfig));
|
|
91
90
|
}
|
|
92
91
|
},
|
|
@@ -12,7 +12,7 @@ export function addUseCredentials(scriptSrc, html) {
|
|
|
12
12
|
}
|
|
13
13
|
function processScript(bundle, scriptSrc, html, seen = new Set()) {
|
|
14
14
|
seen.add(scriptSrc);
|
|
15
|
-
const script = bundle[scriptSrc];
|
|
15
|
+
const script = bundle?.[scriptSrc];
|
|
16
16
|
if (!script || script.type !== "chunk") {
|
|
17
17
|
return html;
|
|
18
18
|
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
4
|
+
/**
|
|
5
|
+
* Default custom export condition used internally by workspace packages
|
|
6
|
+
* to resolve TypeScript source during development.
|
|
7
|
+
*
|
|
8
|
+
* This condition must never leak into published artifacts because external
|
|
9
|
+
* consumers would not be able to resolve it.
|
|
10
|
+
*/
|
|
11
|
+
const DEFAULT_SOURCE_CONDITION = "@pentaho-apps:source";
|
|
12
|
+
/**
|
|
13
|
+
* Runtime-relevant package.json fields copied into dist output.
|
|
14
|
+
*
|
|
15
|
+
* All other fields are intentionally excluded.
|
|
16
|
+
*/
|
|
17
|
+
const INCLUDED_FIELDS = [
|
|
18
|
+
"name",
|
|
19
|
+
"version",
|
|
20
|
+
"type",
|
|
21
|
+
"license",
|
|
22
|
+
"description",
|
|
23
|
+
"dependencies",
|
|
24
|
+
"peerDependencies",
|
|
25
|
+
"peerDependenciesMeta",
|
|
26
|
+
"optionalDependencies",
|
|
27
|
+
];
|
|
28
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
29
|
+
/**
|
|
30
|
+
* Reads and parses a JSON file.
|
|
31
|
+
*
|
|
32
|
+
* Returns `undefined` if the file does not exist or cannot be parsed.
|
|
33
|
+
*/
|
|
34
|
+
function readJsonFile(filePath) {
|
|
35
|
+
try {
|
|
36
|
+
return JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Removes the build output prefix from an export path.
|
|
44
|
+
*
|
|
45
|
+
* Example:
|
|
46
|
+
* ./dist/index.js → ./index.js
|
|
47
|
+
*/
|
|
48
|
+
function stripDistPrefix(prefix, value) {
|
|
49
|
+
return value.startsWith(prefix) ? `./${value.slice(prefix.length)}` : value;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Transforms a package export target for dist/package.json.
|
|
53
|
+
*
|
|
54
|
+
* Processing rules:
|
|
55
|
+
*
|
|
56
|
+
* Strings:
|
|
57
|
+
* - Must resolve inside build.outDir
|
|
58
|
+
* - build.outDir prefix is stripped
|
|
59
|
+
*
|
|
60
|
+
* Objects:
|
|
61
|
+
* - Removes dev-only source condition
|
|
62
|
+
* - Recursively transforms nested targets
|
|
63
|
+
* - Removed if empty after transformation
|
|
64
|
+
*
|
|
65
|
+
* Arrays:
|
|
66
|
+
* - Node fallback arrays are eagerly collapsed to the first
|
|
67
|
+
* valid non-null target because import maps do not support
|
|
68
|
+
* Node conditional fallback resolution semantics.
|
|
69
|
+
*
|
|
70
|
+
* null:
|
|
71
|
+
* - Preserved as explicit export exclusion
|
|
72
|
+
*
|
|
73
|
+
* undefined:
|
|
74
|
+
* - Internal sentinel meaning "omit this entry"
|
|
75
|
+
*/
|
|
76
|
+
function transformExportTargetForDist(target, distPrefix, sourceCondition) {
|
|
77
|
+
// Explicit export exclusion must be preserved
|
|
78
|
+
if (target === null) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
// Direct export path
|
|
82
|
+
if (typeof target === "string") {
|
|
83
|
+
const stripped = stripDistPrefix(distPrefix, target);
|
|
84
|
+
// Ignore paths outside dist output
|
|
85
|
+
return stripped === target ? undefined : stripped;
|
|
86
|
+
}
|
|
87
|
+
// Fallback array
|
|
88
|
+
if (Array.isArray(target)) {
|
|
89
|
+
for (const entry of target) {
|
|
90
|
+
const resolved = transformExportTargetForDist(entry, distPrefix, sourceCondition);
|
|
91
|
+
if (resolved !== undefined && resolved !== null) {
|
|
92
|
+
return resolved;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
// Conditional exports object
|
|
98
|
+
const result = {};
|
|
99
|
+
for (const [condition, value] of Object.entries(target)) {
|
|
100
|
+
// Remove workspace-only source condition
|
|
101
|
+
if (condition === sourceCondition) {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
const transformed = transformExportTargetForDist(value, distPrefix, sourceCondition);
|
|
105
|
+
// Omitted targets disappear entirely
|
|
106
|
+
if (transformed === undefined) {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
result[condition] = transformed;
|
|
110
|
+
}
|
|
111
|
+
return Object.keys(result).length === 0 ? undefined : result;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Normalizes package exports into canonical subpath map form.
|
|
115
|
+
*
|
|
116
|
+
* Converts:
|
|
117
|
+
*
|
|
118
|
+
* "exports": "./index.js"
|
|
119
|
+
* → { ".": "./index.js" }
|
|
120
|
+
*
|
|
121
|
+
* "exports": { "import": "./index.js" }
|
|
122
|
+
* → { ".": { "import": "./index.js" } }
|
|
123
|
+
*
|
|
124
|
+
* Leaves already-normalized subpath maps untouched.
|
|
125
|
+
*/
|
|
126
|
+
function normalizeExportsToSubpathMap(exportsField) {
|
|
127
|
+
if (exportsField == null) {
|
|
128
|
+
throw new Error(`[App Shell]: package.json is missing "exports".`);
|
|
129
|
+
}
|
|
130
|
+
// Sugar form:
|
|
131
|
+
// "exports": "./index.js"
|
|
132
|
+
// "exports": ["./a.js", "./b.js"]
|
|
133
|
+
if (typeof exportsField === "string" || Array.isArray(exportsField)) {
|
|
134
|
+
return { ".": exportsField };
|
|
135
|
+
}
|
|
136
|
+
const keys = Object.keys(exportsField);
|
|
137
|
+
// Already a subpath map
|
|
138
|
+
if (keys.every((key) => key.startsWith("."))) {
|
|
139
|
+
return exportsField;
|
|
140
|
+
}
|
|
141
|
+
// Root conditional exports sugar
|
|
142
|
+
return { ".": exportsField };
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Appends standard metadata exports required at runtime.
|
|
146
|
+
*/
|
|
147
|
+
function appendStandardExports(exportsMap, outDir) {
|
|
148
|
+
exportsMap["./package.json"] = "./package.json";
|
|
149
|
+
exportsMap["./app-shell.config.json"] = "./app-shell.config.json";
|
|
150
|
+
if (fs.existsSync(path.join(outDir, "locales"))) {
|
|
151
|
+
exportsMap["./locales/*"] = "./locales/*";
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// ─── Dist package.json generation ────────────────────────────────────────────
|
|
155
|
+
/**
|
|
156
|
+
* Generates dist/package.json from the source package.
|
|
157
|
+
*
|
|
158
|
+
* The generated package:
|
|
159
|
+
* - strips dev-only export conditions
|
|
160
|
+
* - rewrites export paths relative to dist/
|
|
161
|
+
* - preserves explicit null exclusions
|
|
162
|
+
* - supports nested conditional exports
|
|
163
|
+
*/
|
|
164
|
+
function generateDistPackageJson(root, outDir, buildOutDir, sourceCondition) {
|
|
165
|
+
const pkgPath = path.join(root, "package.json");
|
|
166
|
+
const pkg = readJsonFile(pkgPath);
|
|
167
|
+
if (!pkg || !fs.existsSync(outDir)) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
const rawExports = pkg.exports;
|
|
171
|
+
const distPrefix = `./${buildOutDir}/`;
|
|
172
|
+
const transformedExports = transformExportTargetForDist(normalizeExportsToSubpathMap(rawExports), distPrefix, sourceCondition);
|
|
173
|
+
/**
|
|
174
|
+
* The entire exports tree may collapse after removing dev-only
|
|
175
|
+
* conditions and invalid dist targets.
|
|
176
|
+
*/
|
|
177
|
+
if (transformedExports === undefined) {
|
|
178
|
+
throw new Error(`[App Shell] ${pkg.name}: exports resolved to empty after transformation.`);
|
|
179
|
+
}
|
|
180
|
+
appendStandardExports(transformedExports, outDir);
|
|
181
|
+
const distPkg = {};
|
|
182
|
+
// Copy runtime-relevant fields
|
|
183
|
+
for (const field of INCLUDED_FIELDS) {
|
|
184
|
+
if (pkg[field] != null) {
|
|
185
|
+
distPkg[field] = pkg[field];
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
distPkg.exports = transformedExports;
|
|
189
|
+
fs.writeFileSync(path.join(outDir, "package.json"), JSON.stringify(distPkg, null, 2) + "\n");
|
|
190
|
+
console.info(`[App Shell] Generated ${buildOutDir}/package.json for ${pkg.name}`);
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
// ─── Plugin ──────────────────────────────────────────────────────────────────
|
|
194
|
+
/**
|
|
195
|
+
* Generates a cleaned dist/package.json during Vite builds.
|
|
196
|
+
*/
|
|
197
|
+
export default function distPackageJsonPlugin(root, sourceCondition = DEFAULT_SOURCE_CONDITION) {
|
|
198
|
+
let config;
|
|
199
|
+
return {
|
|
200
|
+
name: "app-shell:vite-dist-package-json-plugin",
|
|
201
|
+
apply: "build",
|
|
202
|
+
configResolved(resolved) {
|
|
203
|
+
config = resolved;
|
|
204
|
+
},
|
|
205
|
+
closeBundle() {
|
|
206
|
+
const packageRoot = root ?? config.root;
|
|
207
|
+
const outDir = path.resolve(packageRoot, config.build.outDir);
|
|
208
|
+
generateDistPackageJson(packageRoot, outDir, config.build.outDir, sourceCondition);
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
}
|
|
@@ -6,7 +6,17 @@ import type { PluginOption } from "vite";
|
|
|
6
6
|
*
|
|
7
7
|
* Local locale files (from the app's public/locales/) always take priority.
|
|
8
8
|
*
|
|
9
|
-
* `supported-locales.json
|
|
10
|
-
*
|
|
9
|
+
* If the app provides a `supported-locales.json`, it acts as a filter:
|
|
10
|
+
* only listed locales are included from upstream. If no local file is
|
|
11
|
+
* provided, all upstream locales are merged in.
|
|
12
|
+
*
|
|
13
|
+
* When `mergeUpstream` is false (e.g. `type: "bundle"`), the build skips
|
|
14
|
+
* upstream merging entirely but still generates `supported-locales.json`
|
|
15
|
+
* from the local locale directories, filtering by the local manifest when
|
|
16
|
+
* present. In dev mode, upstream locales are always served regardless of
|
|
17
|
+
* this flag, since the full app runs locally and needs the shell translations.
|
|
18
|
+
*
|
|
19
|
+
* @param mergeUpstream - Whether to merge upstream app-shell-ui locales.
|
|
20
|
+
* Defaults to `true` (for `type: "app"`).
|
|
11
21
|
*/
|
|
12
|
-
export default function copyAppShellLocales(): PluginOption;
|
|
22
|
+
export default function copyAppShellLocales(mergeUpstream?: boolean): PluginOption;
|
|
@@ -21,6 +21,24 @@ function resolveAppShellUiLocales() {
|
|
|
21
21
|
}
|
|
22
22
|
return undefined;
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Computes the effective set of allowed locales for a given locales directory.
|
|
26
|
+
*
|
|
27
|
+
* When a local `supported-locales.json` exists, it acts as a filter — even if
|
|
28
|
+
* it resolves to an empty list (all entries invalid), so that an invalid
|
|
29
|
+
* manifest doesn't accidentally allow everything.
|
|
30
|
+
*
|
|
31
|
+
* @returns The effective locale list (sorted, deduplicated) and the
|
|
32
|
+
* corresponding `Set` to use as a filter (or `undefined` when no local
|
|
33
|
+
* manifest exists — meaning "allow all").
|
|
34
|
+
*/
|
|
35
|
+
function resolveEffectiveLocales(shellLocalesDir, appLocalesDir) {
|
|
36
|
+
const hasLocalManifest = fs.existsSync(path.join(appLocalesDir, SUPPORTED_LOCALES_FILE));
|
|
37
|
+
const locales = computeSupportedLocales(shellLocalesDir, appLocalesDir);
|
|
38
|
+
// When a local manifest exists, always filter — even with an empty set.
|
|
39
|
+
const allowedSet = hasLocalManifest ? new Set(locales) : undefined;
|
|
40
|
+
return { locales, allowedSet };
|
|
41
|
+
}
|
|
24
42
|
/**
|
|
25
43
|
* Vite plugin that handles app-shell locale files:
|
|
26
44
|
* - In dev mode: serves merged locale files via middleware
|
|
@@ -28,10 +46,20 @@ function resolveAppShellUiLocales() {
|
|
|
28
46
|
*
|
|
29
47
|
* Local locale files (from the app's public/locales/) always take priority.
|
|
30
48
|
*
|
|
31
|
-
* `supported-locales.json
|
|
32
|
-
*
|
|
49
|
+
* If the app provides a `supported-locales.json`, it acts as a filter:
|
|
50
|
+
* only listed locales are included from upstream. If no local file is
|
|
51
|
+
* provided, all upstream locales are merged in.
|
|
52
|
+
*
|
|
53
|
+
* When `mergeUpstream` is false (e.g. `type: "bundle"`), the build skips
|
|
54
|
+
* upstream merging entirely but still generates `supported-locales.json`
|
|
55
|
+
* from the local locale directories, filtering by the local manifest when
|
|
56
|
+
* present. In dev mode, upstream locales are always served regardless of
|
|
57
|
+
* this flag, since the full app runs locally and needs the shell translations.
|
|
58
|
+
*
|
|
59
|
+
* @param mergeUpstream - Whether to merge upstream app-shell-ui locales.
|
|
60
|
+
* Defaults to `true` (for `type: "app"`).
|
|
33
61
|
*/
|
|
34
|
-
export default function copyAppShellLocales() {
|
|
62
|
+
export default function copyAppShellLocales(mergeUpstream = true) {
|
|
35
63
|
let resolvedOutDir;
|
|
36
64
|
let isBuild = false;
|
|
37
65
|
return {
|
|
@@ -42,8 +70,16 @@ export default function copyAppShellLocales() {
|
|
|
42
70
|
isBuild = config.command === "build";
|
|
43
71
|
},
|
|
44
72
|
// --- DEV MODE: serve merged locales via middleware ---
|
|
73
|
+
// In dev, always resolve upstream locales regardless of `mergeUpstream`,
|
|
74
|
+
// because the full app runs locally and needs the shell translations.
|
|
75
|
+
// The `mergeUpstream` flag only affects the build output.
|
|
45
76
|
configureServer(server) {
|
|
46
77
|
const appShellUiLocalesDir = resolveAppShellUiLocales();
|
|
78
|
+
const localLocalesDir = path.resolve(server.config.root, "public/locales");
|
|
79
|
+
// Compute the effective locale set once at server start, using the
|
|
80
|
+
// same logic as the build path. A server restart is needed when the
|
|
81
|
+
// locale directory structure or supported-locales.json changes.
|
|
82
|
+
const { locales: effectiveLocales, allowedSet } = resolveEffectiveLocales(appShellUiLocalesDir, localLocalesDir);
|
|
47
83
|
server.middlewares.use((req, res, next) => {
|
|
48
84
|
// Parse the pathname, stripping the Vite base and any query string
|
|
49
85
|
// so locale requests work under non-root base paths (e.g. /myapp/).
|
|
@@ -58,19 +94,15 @@ export default function copyAppShellLocales() {
|
|
|
58
94
|
if (!pathname.startsWith(base))
|
|
59
95
|
return next();
|
|
60
96
|
const relativePath = pathname.slice(base.length);
|
|
61
|
-
//
|
|
62
|
-
// key/value bundle, and must reflect the union of both sources plus
|
|
63
|
-
// any language directories that exist on disk.
|
|
97
|
+
// Serve the computed supported-locales.json
|
|
64
98
|
if (relativePath === `locales/${SUPPORTED_LOCALES_FILE}`) {
|
|
65
|
-
|
|
66
|
-
const merged = computeSupportedLocales(appShellUiLocalesDir, localLocalesDir);
|
|
67
|
-
if (merged.length === 0) {
|
|
99
|
+
if (effectiveLocales.length === 0) {
|
|
68
100
|
res.statusCode = 404;
|
|
69
101
|
res.end();
|
|
70
102
|
return;
|
|
71
103
|
}
|
|
72
104
|
res.setHeader("Content-Type", "application/json");
|
|
73
|
-
res.end(JSON.stringify(
|
|
105
|
+
res.end(JSON.stringify(effectiveLocales));
|
|
74
106
|
return;
|
|
75
107
|
}
|
|
76
108
|
const match = relativePath.match(/^locales\/([^/]+)\/([^/]+\.json)$/);
|
|
@@ -80,9 +112,11 @@ export default function copyAppShellLocales() {
|
|
|
80
112
|
// Guard against path traversal (e.g. `..` segments)
|
|
81
113
|
if (lng.includes("..") || nsFile.includes(".."))
|
|
82
114
|
return next();
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
115
|
+
// Filter by the effective locale set (same logic as build)
|
|
116
|
+
if (allowedSet && !allowedSet.has(lng))
|
|
117
|
+
return next();
|
|
118
|
+
const localPath = path.join(localLocalesDir, lng, nsFile);
|
|
119
|
+
if (!localPath.startsWith(localLocalesDir + path.sep))
|
|
86
120
|
return next();
|
|
87
121
|
const shellPath = appShellUiLocalesDir
|
|
88
122
|
? path.join(appShellUiLocalesDir, lng, nsFile)
|
|
@@ -118,19 +152,31 @@ export default function copyAppShellLocales() {
|
|
|
118
152
|
// guard, locale files would be written to that folder on disk.
|
|
119
153
|
if (!isBuild || !resolvedOutDir)
|
|
120
154
|
return;
|
|
121
|
-
const appShellUiLocales = resolveAppShellUiLocales();
|
|
122
|
-
if (!appShellUiLocales)
|
|
123
|
-
return;
|
|
124
155
|
const targetLocales = path.resolve(resolvedOutDir, "locales");
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
156
|
+
const appShellUiLocales = mergeUpstream
|
|
157
|
+
? resolveAppShellUiLocales()
|
|
158
|
+
: undefined;
|
|
159
|
+
if (appShellUiLocales) {
|
|
160
|
+
const { allowedSet } = resolveEffectiveLocales(appShellUiLocales, targetLocales);
|
|
161
|
+
// Recursive merge: app-shell-ui files are merged into target,
|
|
162
|
+
// with existing (local) keys taking priority in JSON files.
|
|
163
|
+
// supported-locales.json is skipped during this step.
|
|
164
|
+
// Only locale dirs in the allowed set are merged (if filtering).
|
|
165
|
+
mergeDirs(appShellUiLocales, targetLocales, allowedSet);
|
|
166
|
+
}
|
|
167
|
+
// Generate supported-locales.json from the (possibly merged) output.
|
|
168
|
+
// When no upstream is involved, this is purely based on local dirs.
|
|
169
|
+
const { locales: finalLocales } = resolveEffectiveLocales(appShellUiLocales, targetLocales);
|
|
170
|
+
// Always write/normalize the output supported-locales.json so that any
|
|
171
|
+
// stale copy from public/ (already placed into dist/ by Vite) is
|
|
172
|
+
// overwritten with the computed result. If the effective list is empty,
|
|
173
|
+
// remove the file entirely so the output doesn't ship invalid entries.
|
|
174
|
+
const manifestPath = path.join(targetLocales, SUPPORTED_LOCALES_FILE);
|
|
175
|
+
if (finalLocales.length > 0) {
|
|
176
|
+
fs.writeFileSync(manifestPath, `${JSON.stringify(finalLocales)}\n`);
|
|
177
|
+
}
|
|
178
|
+
else if (fs.existsSync(manifestPath)) {
|
|
179
|
+
fs.unlinkSync(manifestPath);
|
|
134
180
|
}
|
|
135
181
|
},
|
|
136
182
|
};
|
package/dist/vite-plugin.d.ts
CHANGED
|
@@ -97,6 +97,42 @@ export interface AppShellVitePluginOptions {
|
|
|
97
97
|
* @default false
|
|
98
98
|
*/
|
|
99
99
|
disableAppsKeyNormalization?: boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Enables the experimental new package layout feature set.
|
|
102
|
+
*
|
|
103
|
+
* When `true`, the plugin activates behaviors that are part of the
|
|
104
|
+
* new app bundle distribution/publishing package layout. Currently, this gates:
|
|
105
|
+
*
|
|
106
|
+
* - **`dist/package.json` generation** — a cleaned-up `package.json` is
|
|
107
|
+
* written to the Vite output directory after each build. The source
|
|
108
|
+
* `package.json` contains dev-time fields and conditions that do not apply
|
|
109
|
+
* to published/distributed packages; the generated manifest only includes
|
|
110
|
+
* the fields relevant to consumers.
|
|
111
|
+
* - **`dist/app-shell.config.json`** — the resolved App Shell configuration
|
|
112
|
+
* is written to the output directory so that app bundles are self-contained
|
|
113
|
+
* and can be consumed both as standalone App Shells or as bundles for
|
|
114
|
+
* another App Shell.
|
|
115
|
+
*
|
|
116
|
+
* Additional behaviors may be added under this flag in future PRs before
|
|
117
|
+
* the feature set is stabilized and the flag is removed.
|
|
118
|
+
*
|
|
119
|
+
* @default false
|
|
120
|
+
* @experimental
|
|
121
|
+
*/
|
|
122
|
+
experimentalNewPackageLayout?: boolean;
|
|
123
|
+
/**
|
|
124
|
+
* The custom exports condition used to resolve TypeScript source files during
|
|
125
|
+
* development. Only applies when `experimentalNewPackageLayout` is `true`.
|
|
126
|
+
*
|
|
127
|
+
* Workspace packages declare a scoped condition (e.g. `"@pentaho-apps:source"`)
|
|
128
|
+
* in their `exports` map that points directly at the TypeScript source. This
|
|
129
|
+
* lets consumers import the live source during development without a prior
|
|
130
|
+
* build step. The condition is stripped from `dist/package.json` so it never
|
|
131
|
+
* leaks to consumers that don't have the TypeScript sources available.
|
|
132
|
+
*
|
|
133
|
+
* @default "@pentaho-apps:source"
|
|
134
|
+
*/
|
|
135
|
+
sourceCondition?: string;
|
|
100
136
|
}
|
|
101
137
|
/**
|
|
102
138
|
* Vite plugin to support App Shell apps setup
|
package/dist/vite-plugin.js
CHANGED
|
@@ -10,6 +10,7 @@ import SHARED_DEPENDENCIES from "./shared-dependencies.js";
|
|
|
10
10
|
import getVirtualEntrypoints from "./virtual-entrypoints.js";
|
|
11
11
|
import processConfiguration from "./vite-configuration-processor-plugin.js";
|
|
12
12
|
import fixCrossOrigin from "./vite-crossorigin-fix-plugin.js";
|
|
13
|
+
import distPackageJsonPlugin from "./vite-dist-package-json-plugin.js";
|
|
13
14
|
import generateBaseTag from "./vite-generate-base-plugin.js";
|
|
14
15
|
import generateBashScript from "./vite-generate-bash-script-plugin.js";
|
|
15
16
|
import generateImportmap, { extraDependencies, } from "./vite-importmap-plugin.js";
|
|
@@ -26,7 +27,7 @@ const ViteBuildMode = {
|
|
|
26
27
|
* @param env Environment variable
|
|
27
28
|
*/
|
|
28
29
|
export async function HvAppShellVitePlugin(opts = {}, env = {}) {
|
|
29
|
-
const { root = process.cwd(), mode = ViteBuildMode.PRODUCTION, externalImportMap = false, viewsFolder = "src/pages", autoViewsAndRoutes = false, autoMenu = false, inlineConfig = opts.generateEmptyShell ?? false, generateEmptyShell = false, modules = [], disableAppsKeyNormalization = false, } = opts;
|
|
30
|
+
const { root = process.cwd(), mode = ViteBuildMode.PRODUCTION, externalImportMap = false, viewsFolder = "src/pages", autoViewsAndRoutes = false, autoMenu = false, inlineConfig = opts.generateEmptyShell ?? false, generateEmptyShell = false, modules = [], disableAppsKeyNormalization = false, experimentalNewPackageLayout = false, sourceCondition, } = opts;
|
|
30
31
|
const globalEnv = loadEnv(mode, process.cwd(), "");
|
|
31
32
|
const { type = globalEnv.CI ? "bundle" : "app" } = opts;
|
|
32
33
|
console.info(`Vite running in mode: ${mode}`);
|
|
@@ -56,6 +57,7 @@ export async function HvAppShellVitePlugin(opts = {}, env = {}) {
|
|
|
56
57
|
{
|
|
57
58
|
src: resolveModule("es-module-shims"),
|
|
58
59
|
dest: "bundles",
|
|
60
|
+
rename: { stripBase: true },
|
|
59
61
|
},
|
|
60
62
|
...(!devMode && buildEntryPoint
|
|
61
63
|
? [
|
|
@@ -70,6 +72,7 @@ export async function HvAppShellVitePlugin(opts = {}, env = {}) {
|
|
|
70
72
|
}
|
|
71
73
|
}),
|
|
72
74
|
dest: "bundles",
|
|
75
|
+
rename: { stripBase: true },
|
|
73
76
|
},
|
|
74
77
|
]
|
|
75
78
|
: []),
|
|
@@ -110,7 +113,16 @@ export async function HvAppShellVitePlugin(opts = {}, env = {}) {
|
|
|
110
113
|
buildEntryPoint &&
|
|
111
114
|
generateBaseTag(appShellConfiguration, generateEmptyShell),
|
|
112
115
|
// configure the build process based on the config file
|
|
113
|
-
processConfiguration(
|
|
116
|
+
processConfiguration({
|
|
117
|
+
root,
|
|
118
|
+
appShellConfig: appShellConfiguration,
|
|
119
|
+
selfAppName: packageJson.name,
|
|
120
|
+
modules: modules.concat(autoViewsBundles),
|
|
121
|
+
buildEntryPoint,
|
|
122
|
+
inlineConfig,
|
|
123
|
+
generateEmptyShell,
|
|
124
|
+
experimentalNewPackageLayout,
|
|
125
|
+
}),
|
|
114
126
|
// allow crossorigin="use-credentials" in the index.html
|
|
115
127
|
fixCrossOrigin(),
|
|
116
128
|
// serve the app shell config file as json and watch for changes
|
|
@@ -118,6 +130,9 @@ export async function HvAppShellVitePlugin(opts = {}, env = {}) {
|
|
|
118
130
|
// generate the shell script to replace the placeholders in the index.html
|
|
119
131
|
generateEmptyShell && generateBashScript(externalImportMap, inlineConfig),
|
|
120
132
|
// copy/merge app-shell-ui locales into dist (build) or serve via middleware (dev)
|
|
121
|
-
(buildEntryPoint
|
|
133
|
+
copyAppShellLocales(buildEntryPoint),
|
|
134
|
+
// generate dist/package.json for the build output directory
|
|
135
|
+
experimentalNewPackageLayout &&
|
|
136
|
+
distPackageJsonPlugin(root, sourceCondition),
|
|
122
137
|
];
|
|
123
138
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
const prepareConfigForDevMode = (config, selfAppName) => {
|
|
3
3
|
let configString = JSON.stringify(config);
|
|
4
|
+
configString = configString.replaceAll(`"$app/`, `"${selfAppName}/`);
|
|
5
|
+
// TODO(major): remove @self/ support in favour of $app/
|
|
4
6
|
configString = configString.replaceAll(`"@self/`, `"${selfAppName}/`);
|
|
5
7
|
return JSON.parse(configString);
|
|
6
8
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hitachivantara/app-shell-vite-plugin",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Hitachi Vantara UI Kit Team",
|
|
@@ -20,11 +20,10 @@
|
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@emotion/cache": "^11.11.0",
|
|
22
22
|
"@emotion/react": "^11.11.1",
|
|
23
|
-
"@hitachivantara/app-shell-services": "^2.0.
|
|
24
|
-
"@hitachivantara/app-shell-shared": "^2.3.
|
|
25
|
-
"@hitachivantara/app-shell-ui": "^2.3.
|
|
26
|
-
"@hitachivantara/uikit-react-
|
|
27
|
-
"@hitachivantara/uikit-react-shared": "^6.0.4",
|
|
23
|
+
"@hitachivantara/app-shell-services": "^2.0.4",
|
|
24
|
+
"@hitachivantara/app-shell-shared": "^2.3.2",
|
|
25
|
+
"@hitachivantara/app-shell-ui": "^2.3.3",
|
|
26
|
+
"@hitachivantara/uikit-react-shared": "^6.0.5",
|
|
28
27
|
"@rollup/plugin-commonjs": "^29.0.0",
|
|
29
28
|
"@rollup/plugin-json": "^6.0.0",
|
|
30
29
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
@@ -37,7 +36,7 @@
|
|
|
37
36
|
"react-dom": "^18.2.0",
|
|
38
37
|
"react-router-dom": "^6.9.0",
|
|
39
38
|
"rollup": "^4.57.1",
|
|
40
|
-
"vite-plugin-static-copy": "^
|
|
39
|
+
"vite-plugin-static-copy": "^4.1.0"
|
|
41
40
|
},
|
|
42
41
|
"peerDependencies": {
|
|
43
42
|
"vite": "^4.1.4 || ^5.0.4 || ^6.0.0 || ^7.0.0 || ^8.0.0"
|
|
@@ -59,5 +58,5 @@
|
|
|
59
58
|
},
|
|
60
59
|
"./package.json": "./package.json"
|
|
61
60
|
},
|
|
62
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "65c4f4394e8f8c7cccb58203e1c08c6832434638"
|
|
63
62
|
}
|