@ui5/webcomponents-tools 0.0.0-47cc17a26 → 0.0.0-49bade48d
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/CHANGELOG.md +327 -1
- package/assets-meta.js +6 -4
- package/bin/dev.js +9 -4
- package/bin/ui5nps.js +44 -8
- package/components-package/eslint.js +1 -1
- package/components-package/nps.js +23 -18
- package/icons-collection/nps.js +1 -1
- package/lib/amd-to-es6/index.js +3 -1
- package/lib/cem/cem.js +4 -0
- package/lib/cem/custom-elements-manifest.config.mjs +88 -4
- package/lib/cem/merge.mjs +220 -0
- package/lib/cem/schema-internal.json +41 -1
- package/lib/cem/schema.json +41 -1
- package/lib/cem/types-internal.d.ts +32 -2
- package/lib/cem/types.d.ts +32 -2
- package/lib/cem/utils.mjs +13 -3
- package/lib/cem/validate.js +7 -2
- package/lib/chokidar/chokidar.js +28 -0
- package/lib/copy-and-watch/index.js +5 -0
- package/lib/copy-list/index.js +3 -1
- package/lib/create-icons/index.js +18 -13
- package/lib/create-illustrations/index.js +46 -4
- package/lib/css-processors/css-processor-components.mjs +14 -3
- package/lib/css-processors/css-processor-themes.mjs +148 -24
- package/lib/css-processors/merge-light-dark.mjs +131 -0
- package/lib/css-processors/postcss-plugin.mjs +153 -0
- package/lib/css-processors/scope-variables.mjs +26 -1
- package/lib/css-processors/shared.mjs +7 -6
- package/lib/eslint/eslint.js +44 -0
- package/lib/generate-js-imports/illustrations.js +3 -1
- package/lib/generate-json-imports/i18n.js +3 -1
- package/lib/generate-json-imports/themes.js +6 -2
- package/lib/i18n/defaults.js +3 -1
- package/lib/i18n/toJSON.js +28 -4
- package/lib/test-runner/test-runner.js +56 -48
- package/lib/vite-bundler/vite-bundler.mjs +35 -0
- package/package.json +2 -4
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
|
|
2
|
+
import postcss from "postcss";
|
|
3
|
+
|
|
4
|
+
const hostVariables = new Map();
|
|
5
|
+
|
|
6
|
+
const SELECTOR = ":host";
|
|
7
|
+
|
|
8
|
+
const saveVariable = (variable, value, density) => {
|
|
9
|
+
if (!hostVariables.has(variable)) {
|
|
10
|
+
hostVariables.set(variable, {});
|
|
11
|
+
}
|
|
12
|
+
hostVariables.get(variable)[density] = value;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* PostCSS plugin for handling CSS variables across density modes (cozy and compact).
|
|
17
|
+
*
|
|
18
|
+
* The plugin scans CSS for `:host` rules that define density-specific custom properties.
|
|
19
|
+
* Variables declared in a root-level `:host` rule are treated as **cozy** values, while
|
|
20
|
+
* variables declared inside `@container style(--ui5_content_density: compact)` `:host` rules
|
|
21
|
+
* are treated as **compact** values.
|
|
22
|
+
*
|
|
23
|
+
* All discovered variables are merged into a single root `:host` rule. For variables that
|
|
24
|
+
* exist in both modes, the plugin generates a value that uses CSS variable fallbacks to
|
|
25
|
+
* dynamically switch between compact and cozy values based on the active density.
|
|
26
|
+
*
|
|
27
|
+
* Variables that exist in only one mode are preserved, with appropriate fallbacks added
|
|
28
|
+
* when needed.
|
|
29
|
+
*
|
|
30
|
+
* Example input:
|
|
31
|
+
*
|
|
32
|
+
* ```css
|
|
33
|
+
* :host {
|
|
34
|
+
* --my-variable: cozy-value;
|
|
35
|
+
* --cozy-only-variable: cozy-only-value;
|
|
36
|
+
* }
|
|
37
|
+
*
|
|
38
|
+
* @container style(--ui5_content_density: compact) {
|
|
39
|
+
* :host {
|
|
40
|
+
* --my-variable: compact-value;
|
|
41
|
+
* --compact-only-variable: compact-only;
|
|
42
|
+
* }
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* Output:
|
|
47
|
+
*
|
|
48
|
+
* ```css
|
|
49
|
+
* :host {
|
|
50
|
+
* --my-variable: var(--_ui5-compact-size, compact-value) var(--_ui5-cozy-size, cozy-value);
|
|
51
|
+
* --compact-only-variable: var(--_ui5-compact-size, compact-only) var(--_ui5-cozy-size, initial);
|
|
52
|
+
* --cozy-only-variable: cozy-only-value;
|
|
53
|
+
* }
|
|
54
|
+
* ```
|
|
55
|
+
*
|
|
56
|
+
* This enables seamless runtime switching between density modes using CSS variables alone.
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
export default function postcssPlugin() {
|
|
60
|
+
return {
|
|
61
|
+
postcssPlugin: 'postcss-content-density-variables',
|
|
62
|
+
Once(root) {
|
|
63
|
+
let hasRootHost = false;
|
|
64
|
+
let hostRule;
|
|
65
|
+
|
|
66
|
+
root.walkRules((rule) => {
|
|
67
|
+
// Only process :host rules
|
|
68
|
+
if (rule.selector !== SELECTOR) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Handle root-level :host rules (cozy)
|
|
73
|
+
if (rule.parent.type === "root") {
|
|
74
|
+
if (!hasRootHost) {
|
|
75
|
+
hasRootHost = true;
|
|
76
|
+
hostRule = rule;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
rule.walkDecls((decl) => {
|
|
80
|
+
if (decl.prop.startsWith('--')) {
|
|
81
|
+
saveVariable(decl.prop, decl.value, 'cozy');
|
|
82
|
+
decl.remove();
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Handle :host rules inside @container (compact)
|
|
88
|
+
if (rule.parent.type === "atrule") {
|
|
89
|
+
if (rule.parent.params.replaceAll("\s", "") === 'style(--ui5_content_density: compact)'.replaceAll("\s", "")) {
|
|
90
|
+
rule.walkDecls((decl) => {
|
|
91
|
+
if (decl.prop.startsWith('--')) {
|
|
92
|
+
saveVariable(decl.prop, decl.value, 'compact');
|
|
93
|
+
decl.remove();
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
let current = rule;
|
|
100
|
+
// Remove up empty rules
|
|
101
|
+
while (current) {
|
|
102
|
+
if (current.nodes.length === 0) {
|
|
103
|
+
const parent = current.parent;
|
|
104
|
+
current.remove();
|
|
105
|
+
current = parent;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (current.type === "root") {
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
if (!hasRootHost) {
|
|
115
|
+
hostRule = postcss.rule({ selector: SELECTOR });
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Construct merged variable declarations depending on available modes
|
|
119
|
+
for (const [variable, variableData] of hostVariables) {
|
|
120
|
+
if (variableData.cozy && variableData.compact) {
|
|
121
|
+
hostRule.append({
|
|
122
|
+
prop: variable,
|
|
123
|
+
value: `var(--_ui5-compact-size, ${variableData.compact}) var(--_ui5-cozy-size, ${variableData.cozy})`,
|
|
124
|
+
});
|
|
125
|
+
} else if (variableData.compact) {
|
|
126
|
+
|
|
127
|
+
// Use a non-existent variable to always trigger the fallback.
|
|
128
|
+
// Because this variable is never defined, the fallback is used
|
|
129
|
+
// in all cases.
|
|
130
|
+
|
|
131
|
+
// Using `initial` as a fallback can work only for properties
|
|
132
|
+
// that treat it as an invalid value. To avoid this inconsistency,
|
|
133
|
+
// we intentionally reference an undefined variable, which is
|
|
134
|
+
// always considered invalid and undefined.
|
|
135
|
+
hostRule.append({
|
|
136
|
+
prop: variable,
|
|
137
|
+
value: `var(--_ui5-compact-size, ${variableData.compact}) var(--_ui5-cozy-size, var(--_ui5-f2d95f8))`,
|
|
138
|
+
});
|
|
139
|
+
} else {
|
|
140
|
+
hostRule.append({
|
|
141
|
+
prop: variable,
|
|
142
|
+
value: variableData.cozy,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
root.prepend(hostRule);
|
|
148
|
+
hostVariables.clear();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
postcssPlugin.postcss = true;
|
|
@@ -30,12 +30,37 @@ const getOverrideVersion = filePath => {
|
|
|
30
30
|
try {
|
|
31
31
|
overrideVersion = require(`${packageName}${path.sep}package.json`).version;
|
|
32
32
|
} catch (e) {
|
|
33
|
-
|
|
33
|
+
if (process.env.UI5_VERBOSE === "true") {
|
|
34
|
+
console.log(`Error requiring package ${packageName}: ${e.message}`);
|
|
35
|
+
}
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
return overrideVersion;
|
|
37
39
|
}
|
|
38
40
|
|
|
41
|
+
/**
|
|
42
|
+
* `packageJSON` should reference the `package.json` of the base package,
|
|
43
|
+
* as it serves as the starting point for every runtime and carries a unique version.
|
|
44
|
+
* The `getScopedVarName` function is also defined in the base package
|
|
45
|
+
* and is consumed by all other packages.
|
|
46
|
+
*
|
|
47
|
+
* Runtime (2.19.0)
|
|
48
|
+
* - base (2.19.0)
|
|
49
|
+
* - At least one of the following packages: ai / main / fiori / compat (2.19.0)
|
|
50
|
+
* - Custom package (x.x.x)
|
|
51
|
+
*
|
|
52
|
+
* It is not possible to have a runtime with the main package at version 2.19.0
|
|
53
|
+
* and the base package at a different version (e.g., 2.18.0),
|
|
54
|
+
* because the main package depends on the base package.
|
|
55
|
+
* Such a mismatch would create a new runtime.
|
|
56
|
+
*
|
|
57
|
+
* Therefore, we can safely assume that the base package version
|
|
58
|
+
* matches the runtime version and can be reliably used for scoping.
|
|
59
|
+
*
|
|
60
|
+
* It is still needed for third-party packages that have not yet migrated to the
|
|
61
|
+
* component-level variable approach.
|
|
62
|
+
*/
|
|
63
|
+
|
|
39
64
|
const scopeVariables = (cssText, packageJSON, inputFile) => {
|
|
40
65
|
const escapeVersion = version => "v" + version?.replaceAll(/[^0-9A-Za-z\-_]/g, "-");
|
|
41
66
|
const versionStr = escapeVersion(getOverrideVersion(inputFile) || packageJSON.version);
|
|
@@ -18,29 +18,30 @@ const writeFileIfChanged = async (fileName, content) => {
|
|
|
18
18
|
const oldContent = await readOldContent(fileName);
|
|
19
19
|
if (content !== oldContent) {
|
|
20
20
|
if (!oldContent) {
|
|
21
|
-
await mkdir(path.dirname(fileName), {recursive: true});
|
|
21
|
+
await mkdir(path.dirname(fileName), { recursive: true });
|
|
22
22
|
}
|
|
23
23
|
return writeFile(fileName, content);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
const DEFAULT_THEME = assets.themes.default;
|
|
28
|
+
const CSS_VARIABLES_TARGET = process.env.CSS_VARIABLES_TARGET === "host";
|
|
28
29
|
|
|
29
30
|
const getDefaultThemeCode = packageName => {
|
|
30
|
-
|
|
31
|
+
return `import { registerThemePropertiesLoader } from "@ui5/webcomponents-base/dist/asset-registries/Themes.js";
|
|
31
32
|
|
|
32
33
|
import defaultThemeBase from "@ui5/webcomponents-theming/dist/generated/themes/${DEFAULT_THEME}/parameters-bundle.css.js";
|
|
33
34
|
import defaultTheme from "./${DEFAULT_THEME}/parameters-bundle.css.js";
|
|
34
35
|
|
|
35
36
|
registerThemePropertiesLoader("@" + "ui5" + "/" + "webcomponents-theming", "${DEFAULT_THEME}", async () => defaultThemeBase);
|
|
36
|
-
registerThemePropertiesLoader(${
|
|
37
|
+
registerThemePropertiesLoader(${packageName.split("").map(c => `"${c}"`).join(" + ")}, "${DEFAULT_THEME}", async () => defaultTheme${CSS_VARIABLES_TARGET ? ', "host"' : ''});
|
|
37
38
|
`;
|
|
38
39
|
};
|
|
39
40
|
|
|
40
41
|
const getFileContent = (packageName, css, includeDefaultTheme) => {
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
const defaultTheme = includeDefaultTheme ? getDefaultThemeCode(packageName) : "";
|
|
43
|
+
return `${defaultTheme}export default ${css.trim()}`
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
|
|
46
|
-
export { writeFileIfChanged, getFileContent}
|
|
47
|
+
export { writeFileIfChanged, getFileContent }
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const { ESLint: ESLint7 } = require("eslint"); // isolated v7
|
|
3
|
+
const path = require("path");
|
|
4
|
+
|
|
5
|
+
const main = async argv => {
|
|
6
|
+
let eslintConfig;
|
|
7
|
+
if (fs.existsSync(".eslintrc.js") || fs.existsSync(".eslintrc.cjs")) {
|
|
8
|
+
// preferred way of custom configuration in root project folder
|
|
9
|
+
eslintConfig = null;
|
|
10
|
+
} else {
|
|
11
|
+
// no custom configuration - use default from tools project
|
|
12
|
+
eslintConfig = require.resolve("@ui5/webcomponents-tools/components-package/eslint.js")
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const packageDir = path.dirname(require.resolve("@ui5/webcomponents-tools/package.json"));
|
|
16
|
+
const eslint = new ESLint7({
|
|
17
|
+
overrideConfigFile: eslintConfig,
|
|
18
|
+
fix: argv.includes("--fix"),
|
|
19
|
+
resolvePluginsRelativeTo: packageDir,
|
|
20
|
+
});
|
|
21
|
+
console.log("Running ESLint v7...");
|
|
22
|
+
|
|
23
|
+
// Lint files
|
|
24
|
+
const results = await eslint.lintFiles(["."]);
|
|
25
|
+
|
|
26
|
+
// Format results
|
|
27
|
+
const formatter = await eslint.loadFormatter("stylish");
|
|
28
|
+
const resultText = formatter.format(results);
|
|
29
|
+
|
|
30
|
+
// Output results
|
|
31
|
+
console.log(resultText);
|
|
32
|
+
|
|
33
|
+
// Exit with error code if there are errors
|
|
34
|
+
const hasErrors = results.some(result => result.errorCount > 0);
|
|
35
|
+
if (hasErrors) {
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (require.main === module) {
|
|
41
|
+
main(process.argv)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
exports._ui5mainFn = main;
|
|
@@ -75,7 +75,9 @@ const generateIllustrations = async (argv) => {
|
|
|
75
75
|
await fs.mkdir(path.dirname(normalizedOutputFile), { recursive: true });
|
|
76
76
|
await fs.writeFile(normalizedOutputFile, contentDynamic);
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
if (process.env.UI5_VERBOSE === "true") {
|
|
79
|
+
console.log("Generated illustration imports.");
|
|
80
|
+
}
|
|
79
81
|
};
|
|
80
82
|
|
|
81
83
|
if (require.main === module) {
|
|
@@ -80,7 +80,9 @@ const generate = async (argv) => {
|
|
|
80
80
|
fs.writeFile(outputFileFetchMetaResolve, contentFetchMetaResolve),
|
|
81
81
|
fs.writeFile(outputFileDynamicImportJSONImport, contentDynamicImportJSONAttr),
|
|
82
82
|
]).then(() => {
|
|
83
|
-
|
|
83
|
+
if (process.env.UI5_VERBOSE === "true") {
|
|
84
|
+
console.log("Generated i18n JSON imports.");
|
|
85
|
+
}
|
|
84
86
|
});
|
|
85
87
|
}
|
|
86
88
|
|
|
@@ -5,6 +5,8 @@ const assets = require("../../assets-meta.js");
|
|
|
5
5
|
const isTypeScript = process.env.UI5_TS;
|
|
6
6
|
const ext = isTypeScript ? 'ts' : 'js';
|
|
7
7
|
|
|
8
|
+
const CSS_VARIABLES_TARGET = process.env.CSS_VARIABLES_TARGET === "host";
|
|
9
|
+
|
|
8
10
|
const generate = async (argv) => {
|
|
9
11
|
const inputFolder = path.normalize(argv[2]);
|
|
10
12
|
const outputFileDynamic = path.normalize(`${argv[3]}/Themes.${ext}`);
|
|
@@ -49,7 +51,7 @@ const loadAndCheck = async (themeName) => {
|
|
|
49
51
|
};
|
|
50
52
|
|
|
51
53
|
${availableThemesArray}
|
|
52
|
-
.forEach(themeName => registerThemePropertiesLoader(${packageName.split("").map(c => `"${c}"`).join(" + ")}, themeName, loadAndCheck));
|
|
54
|
+
.forEach(themeName => registerThemePropertiesLoader(${packageName.split("").map(c => `"${c}"`).join(" + ")}, themeName, loadAndCheck${CSS_VARIABLES_TARGET ? ', "host"' : ''}));
|
|
53
55
|
`;
|
|
54
56
|
}
|
|
55
57
|
|
|
@@ -60,7 +62,9 @@ ${availableThemesArray}
|
|
|
60
62
|
fs.writeFile(outputFileFetchMetaResolve, contentDynamic(fetchMetaResolveLines)),
|
|
61
63
|
]).
|
|
62
64
|
then(() => {
|
|
63
|
-
|
|
65
|
+
if (process.env.UI5_VERBOSE === "true") {
|
|
66
|
+
console.log("Generated themes JSON imports.");
|
|
67
|
+
}
|
|
64
68
|
})
|
|
65
69
|
};
|
|
66
70
|
|
package/lib/i18n/defaults.js
CHANGED
|
@@ -78,7 +78,9 @@ export {${textKeys.join()}};`;
|
|
|
78
78
|
await fs.writeFile(outputFile, getOutputFileContent(properties, defaultLanguageProperties));
|
|
79
79
|
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
if (process.env.UI5_VERBOSE === "true") {
|
|
82
|
+
console.log("i18n default file generated.");
|
|
83
|
+
}
|
|
82
84
|
};
|
|
83
85
|
|
|
84
86
|
if (require.main === module) {
|
package/lib/i18n/toJSON.js
CHANGED
|
@@ -14,13 +14,35 @@ const assets = require('../../assets-meta.js');
|
|
|
14
14
|
|
|
15
15
|
const allLanguages = assets.languages.all;
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* The translation system has a configuration whether to return UTF-8 sequences
|
|
19
|
+
* or the actual characters. This function inlines UTF-8 sequences to actual characters.
|
|
20
|
+
*
|
|
21
|
+
* For example, it converts "Keine Produkte erf\u00FCgbar" to "Keine Produkte verfügbar"
|
|
22
|
+
* This makes the JSON files more readable and smaller.
|
|
23
|
+
*/
|
|
24
|
+
function inlineUTF(properties) {
|
|
25
|
+
for (const key in properties) {
|
|
26
|
+
if (Object.prototype.hasOwnProperty.call(properties, key)) {
|
|
27
|
+
try {
|
|
28
|
+
// escape double quotes to avoid JSON parse error
|
|
29
|
+
const escaped = properties[key].replaceAll("\"", "\\\"");
|
|
30
|
+
properties[key] = JSON.parse(`"${escaped}"`); // utilize JSON parser to decode UTF-8 sequences
|
|
31
|
+
} catch (e) {
|
|
32
|
+
// in case of error, just keep the original string
|
|
33
|
+
console.log(`Warning: failed to inline UTF-8 for key "${key}" with value "${properties[key]}"`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return properties;
|
|
38
|
+
}
|
|
39
|
+
|
|
17
40
|
const convertToJSON = async (file, distPath) => {
|
|
18
|
-
const properties = PropertiesReader(file)._properties;
|
|
41
|
+
const properties = inlineUTF(PropertiesReader(file)._properties);
|
|
19
42
|
const filename = path.basename(file, path.extname(file));
|
|
20
43
|
const language = filename.match(/^messagebundle_(.*?)$/)[1];
|
|
21
44
|
if (!allLanguages.includes(language)) {
|
|
22
|
-
console.
|
|
23
|
-
return;
|
|
45
|
+
console.warn("Not supported language or script: ", language);
|
|
24
46
|
}
|
|
25
47
|
const outputFile = path.normalize(`${distPath}/${filename}.json`);
|
|
26
48
|
|
|
@@ -36,7 +58,9 @@ const generate = async (agrv) => {
|
|
|
36
58
|
const files = await globby(messagesBundles.replace(/\\/g, "/"));
|
|
37
59
|
return Promise.all(files.map(file => convertToJSON(file, messagesJSONDist)))
|
|
38
60
|
.then(() => {
|
|
39
|
-
|
|
61
|
+
if (process.env.UI5_VERBOSE === "true") {
|
|
62
|
+
console.log("Message bundle JSON files generated.");
|
|
63
|
+
}
|
|
40
64
|
});
|
|
41
65
|
};
|
|
42
66
|
|
|
@@ -3,69 +3,77 @@ const { readFileSync } = require("fs");
|
|
|
3
3
|
const path = require("path");
|
|
4
4
|
const fs = require("fs");
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
function testFn(outArgv) {
|
|
7
|
+
// search for dev-server port
|
|
7
8
|
// start in current folder
|
|
8
9
|
// traversing upwards in case of mono repo tests and dev-server running in root folder of repository
|
|
9
|
-
let devServerFolder = process.cwd();
|
|
10
|
-
let devServerPort;
|
|
11
|
-
while (true) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
10
|
+
let devServerFolder = process.cwd();
|
|
11
|
+
let devServerPort;
|
|
12
|
+
while (true) {
|
|
13
|
+
try {
|
|
14
|
+
devServerPort = readFileSync(path.join(devServerFolder, ".dev-server-port")).toString();
|
|
15
|
+
break; // found
|
|
16
|
+
} catch (e) {
|
|
17
|
+
// file not found
|
|
18
|
+
if (devServerFolder === path.dirname(devServerFolder)) {
|
|
19
|
+
break; // reached root folder "/"
|
|
20
|
+
}
|
|
21
|
+
devServerFolder = path.dirname(devServerFolder);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
23
24
|
|
|
24
25
|
// check if we are in a monorepo and extract path from package.json
|
|
25
|
-
let packageRepositoryPath = "";
|
|
26
|
-
const pkg = require(path.join(process.cwd(), "package.json"));
|
|
27
|
-
packageRepositoryPath = pkg.repository ? pkg.repository.directory : "";
|
|
26
|
+
let packageRepositoryPath = "";
|
|
27
|
+
const pkg = require(path.join(process.cwd(), "package.json"));
|
|
28
|
+
packageRepositoryPath = pkg.repository ? pkg.repository.directory : "";
|
|
28
29
|
|
|
29
30
|
// construct base url
|
|
30
31
|
// use devServerPort if a dev server is running, otherwise let the baseUrl in the wdio config be used
|
|
31
32
|
// if a dev server is running in the root of a mono repo, append tha package path like this
|
|
32
33
|
// http://localhost:${devServerPort}/packages/main/
|
|
33
|
-
let baseUrl = "";
|
|
34
|
-
if (devServerPort) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
34
|
+
let baseUrl = "";
|
|
35
|
+
if (devServerPort) {
|
|
36
|
+
console.log(`Found port ${devServerPort} from '${path.join(devServerFolder, ".dev-server-port")}'`);
|
|
37
|
+
const devServerInRoot = !devServerFolder.includes(packageRepositoryPath);
|
|
38
|
+
if (devServerInRoot) {
|
|
39
|
+
baseUrl = `--base-url http://localhost:${devServerPort}/${packageRepositoryPath}/`;
|
|
40
|
+
} else {
|
|
41
|
+
baseUrl = `--base-url http://localhost:${devServerPort}/`;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
43
44
|
|
|
44
|
-
if (!baseUrl) {
|
|
45
|
-
|
|
46
|
-
}
|
|
45
|
+
if (!baseUrl) {
|
|
46
|
+
console.log("No dev server running, running tests served from `dist`, make sure it is up to date");
|
|
47
|
+
}
|
|
47
48
|
|
|
48
49
|
// add single spec parameter if passed
|
|
49
|
-
let spec = "";
|
|
50
|
-
if (
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
50
|
+
let spec = "";
|
|
51
|
+
if (outArgv.length === 3) {
|
|
52
|
+
const specFile = outArgv[2];
|
|
53
|
+
spec = `--spec ${specFile}`;
|
|
54
|
+
}
|
|
54
55
|
|
|
55
56
|
// more parameters - pass them to wdio
|
|
56
|
-
let restParams = "";
|
|
57
|
-
if (
|
|
58
|
-
|
|
57
|
+
let restParams = "";
|
|
58
|
+
if (outArgv.length > 3) {
|
|
59
|
+
restParams = outArgv.slice(2).join(" ");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
let wdioConfig = "";
|
|
63
|
+
if (fs.existsSync("config/wdio.conf.cjs")) {
|
|
64
|
+
wdioConfig = "config/wdio.conf.cjs";
|
|
65
|
+
} else if (fs.existsSync("config/wdio.conf.js")) {
|
|
66
|
+
wdioConfig = "config/wdio.conf.js";
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// run wdio with calculated parameters
|
|
70
|
+
const cmd = `npx cross-env WDIO_LOG_LEVEL=error wdio ${wdioConfig} ${spec} ${baseUrl} ${restParams}`;
|
|
71
|
+
console.log(`executing: ${cmd}`);
|
|
72
|
+
child_process.execSync(cmd, {stdio: 'inherit'});
|
|
59
73
|
}
|
|
60
74
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
wdioConfig = "config/wdio.conf.cjs";
|
|
64
|
-
} else if (fs.existsSync("config/wdio.conf.js")) {
|
|
65
|
-
wdioConfig = "config/wdio.conf.js";
|
|
75
|
+
if (require.main === module) {
|
|
76
|
+
testFn(process.argv)
|
|
66
77
|
}
|
|
67
78
|
|
|
68
|
-
|
|
69
|
-
const cmd = `yarn cross-env WDIO_LOG_LEVEL=error wdio ${wdioConfig} ${spec} ${baseUrl} ${restParams}`;
|
|
70
|
-
console.log(`executing: ${cmd}`);
|
|
71
|
-
child_process.execSync(cmd, {stdio: 'inherit'});
|
|
79
|
+
exports._ui5mainFn = testFn;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { build } from 'vite';
|
|
2
|
+
import yargs from 'yargs';
|
|
3
|
+
import { hideBin } from 'yargs/helpers';
|
|
4
|
+
import { pathToFileURL } from "url";
|
|
5
|
+
|
|
6
|
+
async function start(outArgv) {
|
|
7
|
+
const argv = yargs(hideBin(outArgv))
|
|
8
|
+
.alias("c", "config")
|
|
9
|
+
.alias("mode", "mode")
|
|
10
|
+
.alias("base", "base")
|
|
11
|
+
.argv;
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
await build({
|
|
15
|
+
configFile: argv.config || undefined,
|
|
16
|
+
mode: argv.mode || undefined,
|
|
17
|
+
base: argv.base || undefined,
|
|
18
|
+
logLevel: 'info',
|
|
19
|
+
});
|
|
20
|
+
} catch (e) {
|
|
21
|
+
console.error(e)
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const filePath = process.argv[1];
|
|
27
|
+
const fileUrl = pathToFileURL(filePath).href;
|
|
28
|
+
|
|
29
|
+
if (import.meta.url === fileUrl) {
|
|
30
|
+
start(process.argv)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default {
|
|
34
|
+
_ui5mainFn: start
|
|
35
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ui5/webcomponents-tools",
|
|
3
|
-
"version": "0.0.0-
|
|
3
|
+
"version": "0.0.0-49bade48d",
|
|
4
4
|
"description": "UI5 Web Components: webcomponents.tools",
|
|
5
5
|
"author": "SAP SE (https://www.sap.com)",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -34,7 +34,6 @@
|
|
|
34
34
|
"chai": "^4.3.4",
|
|
35
35
|
"child_process": "^1.0.2",
|
|
36
36
|
"chokidar": "^3.6.0",
|
|
37
|
-
"chokidar-cli": "^3.0.0",
|
|
38
37
|
"command-line-args": "^5.1.1",
|
|
39
38
|
"comment-parser": "^1.4.0",
|
|
40
39
|
"cross-env": "^7.0.3",
|
|
@@ -54,7 +53,6 @@
|
|
|
54
53
|
"ignore": "^7.0.5",
|
|
55
54
|
"is-port-reachable": "^3.1.0",
|
|
56
55
|
"json-beautify": "^1.1.1",
|
|
57
|
-
"mkdirp": "^1.0.4",
|
|
58
56
|
"postcss": "^8.4.5",
|
|
59
57
|
"postcss-cli": "^9.1.0",
|
|
60
58
|
"postcss-selector-parser": "^6.0.10",
|
|
@@ -84,5 +82,5 @@
|
|
|
84
82
|
"esbuild": "^0.25.0",
|
|
85
83
|
"yargs": "^17.5.1"
|
|
86
84
|
},
|
|
87
|
-
"gitHead": "
|
|
85
|
+
"gitHead": "11a0183fb2973739e3549bcbc83bc249dd503784"
|
|
88
86
|
}
|