@ui5/webcomponents-tools 0.0.0-f9b9eadb8 → 0.0.0-fd6264051
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 +122 -0
- package/README.md +1 -1
- package/assets-meta.js +15 -1
- package/components-package/nps.js +51 -27
- package/components-package/postcss.themes.js +5 -2
- package/components-package/rollup-plugins/empty-module.js +15 -0
- package/components-package/rollup.js +134 -40
- package/components-package/wdio.js +53 -28
- package/components-package/wdio.sync.js +360 -0
- package/icons-collection/nps.js +53 -9
- package/lib/copy-and-watch/index.js +6 -4
- package/lib/copy-list/index.js +28 -0
- package/lib/create-icons/index.js +32 -14
- package/lib/create-illustrations/index.js +150 -0
- package/lib/create-new-component/index.js +12 -4
- package/lib/documentation/index.js +42 -20
- package/lib/documentation/templates/api-properties-section.js +3 -1
- package/lib/documentation/templates/template.js +2 -1
- package/lib/esm-abs-to-rel/index.js +54 -0
- package/lib/generate-json-imports/i18n.js +56 -18
- package/lib/generate-json-imports/themes.js +44 -13
- package/lib/hash/config.js +10 -0
- package/lib/hash/generate.js +19 -0
- package/lib/hash/upToDate.js +31 -0
- package/lib/hbs2lit/src/litVisitor2.js +31 -6
- package/lib/hbs2lit/src/svgProcessor.js +3 -3
- package/lib/hbs2ui5/RenderTemplates/LitRenderer.js +4 -11
- package/lib/i18n/toJSON.js +1 -1
- package/lib/jsdoc/config.json +1 -1
- package/lib/jsdoc/plugin.js +30 -1
- package/lib/jsdoc/template/publish.js +22 -2
- package/lib/polyfill-placeholder/index.js +5 -0
- package/lib/postcss-css-to-esm/index.js +19 -16
- package/lib/postcss-css-to-json/index.js +20 -11
- package/lib/postcss-new-files/index.js +36 -0
- package/lib/replace-global-core/index.js +20 -0
- package/lib/scoping/lint-src.js +1 -1
- package/lib/scoping/missing-dependencies.js +65 -0
- package/lib/scoping/report-tags-usage.js +28 -0
- package/lib/serve/index.js +46 -0
- package/{components-package → lib/serve}/serve.json +0 -0
- package/package.json +51 -52
- package/bin/init-ui5-package.js +0 -3
- package/lib/init-package/index.js +0 -123
- package/lib/init-package/resources/.eslintignore +0 -3
- package/lib/init-package/resources/bundle.es5.js +0 -25
- package/lib/init-package/resources/bundle.esm.js +0 -34
- package/lib/init-package/resources/config/.eslintrc.js +0 -1
- package/lib/init-package/resources/config/postcss.components/postcss.config.js +0 -1
- package/lib/init-package/resources/config/postcss.themes/postcss.config.js +0 -1
- package/lib/init-package/resources/config/rollup.config.js +0 -1
- package/lib/init-package/resources/config/wdio.conf.js +0 -1
- package/lib/init-package/resources/package-scripts.js +0 -11
- package/lib/init-package/resources/src/Assets.js +0 -5
- package/lib/init-package/resources/src/MyFirstComponent.hbs +0 -1
- package/lib/init-package/resources/src/MyFirstComponent.js +0 -56
- package/lib/init-package/resources/src/i18n/messagebundle.properties +0 -2
- package/lib/init-package/resources/src/i18n/messagebundle_de.properties +0 -1
- package/lib/init-package/resources/src/i18n/messagebundle_en.properties +0 -1
- package/lib/init-package/resources/src/i18n/messagebundle_es.properties +0 -1
- package/lib/init-package/resources/src/i18n/messagebundle_fr.properties +0 -1
- package/lib/init-package/resources/src/themes/MyFirstComponent.css +0 -11
- package/lib/init-package/resources/src/themes/sap_belize/parameters-bundle.css +0 -3
- package/lib/init-package/resources/src/themes/sap_belize_hcb/parameters-bundle.css +0 -3
- package/lib/init-package/resources/src/themes/sap_belize_hcw/parameters-bundle.css +0 -3
- package/lib/init-package/resources/src/themes/sap_fiori_3/parameters-bundle.css +0 -3
- package/lib/init-package/resources/src/themes/sap_fiori_3_dark/parameters-bundle.css +0 -3
- package/lib/init-package/resources/src/themes/sap_fiori_3_hcb/parameters-bundle.css +0 -3
- package/lib/init-package/resources/src/themes/sap_fiori_3_hcw/parameters-bundle.css +0 -3
- package/lib/init-package/resources/test/pages/index.html +0 -56
- package/lib/init-package/resources/test/specs/Demo.spec.js +0 -12
@@ -2,34 +2,53 @@ const fs = require("fs");
|
|
2
2
|
const path = require("path");
|
3
3
|
const mkdirp = require("mkdirp");
|
4
4
|
|
5
|
-
const
|
6
|
-
const
|
5
|
+
const collectionName = process.argv[2] || "SAP-icons";
|
6
|
+
const collectionVersion = process.argv[3];
|
7
|
+
const srcFile = collectionVersion ? path.normalize(`src/${collectionVersion}/${collectionName}.json`) : path.normalize(`src/${collectionName}.json`);
|
8
|
+
const destDir = collectionVersion ? path.normalize(`dist/${collectionVersion}/`) : path.normalize("dist/");
|
7
9
|
|
8
10
|
mkdirp.sync(destDir);
|
9
11
|
|
10
|
-
const
|
12
|
+
const iconTemplate = (name, pathData, ltr, collection, packageName) => `import { registerIcon } from "@ui5/webcomponents-base/dist/asset-registries/Icons.js";
|
11
13
|
|
12
14
|
const name = "${name}";
|
13
15
|
const pathData = "${pathData}";
|
14
16
|
const ltr = ${ltr};
|
17
|
+
const collection = "${collection}";
|
18
|
+
const packageName = "${packageName}";
|
15
19
|
|
16
|
-
registerIcon(name, { pathData, ltr});
|
20
|
+
registerIcon(name, { pathData, ltr, collection, packageName });
|
17
21
|
|
18
22
|
export default { pathData };`;
|
19
23
|
|
20
|
-
|
24
|
+
|
25
|
+
const iconAccTemplate = (name, pathData, ltr, accData, collection, packageName) => `import { registerIcon } from "@ui5/webcomponents-base/dist/asset-registries/Icons.js";
|
21
26
|
import { ${accData.key} } from "../generated/i18n/i18n-defaults.js";
|
22
27
|
|
23
28
|
const name = "${name}";
|
24
29
|
const pathData = "${pathData}";
|
25
30
|
const ltr = ${ltr};
|
26
31
|
const accData = ${accData.key};
|
32
|
+
const collection = "${collection}";
|
33
|
+
const packageName = "${packageName}";
|
27
34
|
|
28
|
-
registerIcon(name, { pathData, ltr, accData });
|
35
|
+
registerIcon(name, { pathData, ltr, accData, collection, packageName });
|
29
36
|
|
30
37
|
export default { pathData, accData };`;
|
31
38
|
|
32
39
|
|
40
|
+
|
41
|
+
const collectionTemplate = (name) => `import { isThemeFamily } from "@ui5/webcomponents-base/dist/config/Theme.js";
|
42
|
+
import pathDataV4 from "./v5/${name}.js";
|
43
|
+
import pathDataV5 from "./v4/${name}.js";
|
44
|
+
const pathData = isThemeFamily("sap_horizon") ? pathDataV5 : pathDataV4;
|
45
|
+
export default { pathData };`;
|
46
|
+
|
47
|
+
|
48
|
+
const svgTemplate = (pathData) => `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
49
|
+
<path d="${pathData}"/>
|
50
|
+
</svg>`;
|
51
|
+
|
33
52
|
const createIcons = (file) => {
|
34
53
|
const json = JSON.parse(fs.readFileSync(file));
|
35
54
|
|
@@ -39,16 +58,15 @@ const createIcons = (file) => {
|
|
39
58
|
const ltr = !!iconData.ltr;
|
40
59
|
const acc = iconData.acc;
|
41
60
|
|
42
|
-
const content = acc ?
|
61
|
+
const content = acc ? iconAccTemplate(name, pathData, ltr, acc, json.collection, json.packageName) : iconTemplate(name, pathData, ltr, json.collection, json.packageName);
|
43
62
|
|
44
63
|
fs.writeFileSync(path.join(destDir, `${name}.js`), content);
|
45
|
-
|
64
|
+
fs.writeFileSync(path.join(destDir, `${name}.svg`), svgTemplate(pathData));
|
46
65
|
|
66
|
+
if (json.version) {
|
67
|
+
fs.writeFileSync(path.join(path.normalize("dist/"), `${name}.js`), collectionTemplate(name));
|
68
|
+
}
|
69
|
+
}
|
47
70
|
};
|
48
71
|
|
49
|
-
|
50
|
-
createIcons(path.join(srcDir, collectionFile));
|
51
|
-
});
|
52
|
-
|
53
|
-
|
54
|
-
|
72
|
+
createIcons(srcFile);
|
@@ -0,0 +1,150 @@
|
|
1
|
+
const fs = require("fs");
|
2
|
+
const path = require("path");
|
3
|
+
const mkdirp = require("mkdirp");
|
4
|
+
|
5
|
+
if (process.argv.length < 7) {
|
6
|
+
return;
|
7
|
+
}
|
8
|
+
|
9
|
+
const ORIGINAL_TEXTS = {
|
10
|
+
UnableToLoad: "UnableToLoad",
|
11
|
+
UnableToUpload: "UnableToUpload",
|
12
|
+
NoActivities: "NoActivities",
|
13
|
+
BeforeSearch: "BeforeSearch",
|
14
|
+
NoSearchResults: "NoSearchResults",
|
15
|
+
NoEntries: "NoEntries",
|
16
|
+
NoData: "NoData",
|
17
|
+
NoNotifications: "NoNotifications",
|
18
|
+
BalloonSky: "BalloonSky",
|
19
|
+
SuccessScreen: "SuccessScreen",
|
20
|
+
NoMail: "NoMail",
|
21
|
+
NoSavedItems: "NoSavedItems",
|
22
|
+
NoTasks: "NoTasks"
|
23
|
+
};
|
24
|
+
|
25
|
+
const FALLBACK_TEXTS = {
|
26
|
+
ReloadScreen: ORIGINAL_TEXTS.UnableToLoad,
|
27
|
+
Connection: ORIGINAL_TEXTS.UnableToLoad,
|
28
|
+
ErrorScreen: ORIGINAL_TEXTS.UnableToUpload,
|
29
|
+
EmptyCalendar: ORIGINAL_TEXTS.NoActivities,
|
30
|
+
SearchEarth: ORIGINAL_TEXTS.BeforeSearch,
|
31
|
+
SearchFolder: ORIGINAL_TEXTS.NoSearchResults,
|
32
|
+
EmptyList: ORIGINAL_TEXTS.NoEntries,
|
33
|
+
Tent: ORIGINAL_TEXTS.NoData,
|
34
|
+
SleepingBell: ORIGINAL_TEXTS.NoNotifications,
|
35
|
+
SimpleBalloon: ORIGINAL_TEXTS.BalloonSky,
|
36
|
+
SimpleBell: ORIGINAL_TEXTS.NoNotifications,
|
37
|
+
SimpleCalendar: ORIGINAL_TEXTS.NoActivities,
|
38
|
+
SimpleCheckMark: ORIGINAL_TEXTS.SuccessScreen,
|
39
|
+
SimpleConnection: ORIGINAL_TEXTS.UnableToLoad,
|
40
|
+
SimpleEmptyDoc: ORIGINAL_TEXTS.NoData,
|
41
|
+
SimpleEmptyList: ORIGINAL_TEXTS.NoEntries,
|
42
|
+
SimpleError: ORIGINAL_TEXTS.UnableToUpload,
|
43
|
+
SimpleMagnifier: ORIGINAL_TEXTS.BeforeSearch,
|
44
|
+
SimpleMail: ORIGINAL_TEXTS.NoMail,
|
45
|
+
SimpleNoSavedItems: ORIGINAL_TEXTS.NoSavedItems,
|
46
|
+
SimpleNotFoundMagnifier: ORIGINAL_TEXTS.NoSearchResults,
|
47
|
+
SimpleReload: ORIGINAL_TEXTS.UnableToLoad,
|
48
|
+
SimpleTask: ORIGINAL_TEXTS.NoTasks,
|
49
|
+
SuccessBalloon: ORIGINAL_TEXTS.BalloonSky,
|
50
|
+
SuccessCheckMark: ORIGINAL_TEXTS.SuccessScreen,
|
51
|
+
SuccessHighFive: ORIGINAL_TEXTS.BalloonSky
|
52
|
+
};
|
53
|
+
|
54
|
+
const srcPath = process.argv[2];
|
55
|
+
const defaultText = process.argv[3] === "true";
|
56
|
+
const illustrationsPrefix = process.argv[4];
|
57
|
+
const illustrationSet = process.argv[5];
|
58
|
+
const destPath = process.argv[6];
|
59
|
+
const fileNamePattern = new RegExp(`${illustrationsPrefix}-.+-(.+).svg`);
|
60
|
+
// collect each illustration name because each one should have Sample.js file
|
61
|
+
const fileNames = new Set();
|
62
|
+
|
63
|
+
const svgImportTemplate = svgContent => { return `export default \`${svgContent}\`;`};
|
64
|
+
const svgToJs = fileName => {
|
65
|
+
const svg = fs.readFileSync(path.join(srcPath, fileName), { encoding: "utf-8" });
|
66
|
+
const fileContent = svgImportTemplate(svg);
|
67
|
+
fileName = fileName.replace(/\.svg$/, ".js");
|
68
|
+
|
69
|
+
fs.writeFileSync(path.join(destPath, fileName), fileContent);
|
70
|
+
};
|
71
|
+
const illustrationImportTemplate = illustrationName => {
|
72
|
+
let illustrationNameForTranslation = illustrationName;
|
73
|
+
|
74
|
+
if (defaultText) {
|
75
|
+
if (FALLBACK_TEXTS[illustrationNameForTranslation]) {
|
76
|
+
illustrationNameForTranslation = FALLBACK_TEXTS[illustrationNameForTranslation];
|
77
|
+
} else if (illustrationName.indexOf("_v") !== -1) {
|
78
|
+
illustrationNameForTranslation = illustrationNameForTranslation.substr(0, illustrationNameForTranslation.indexOf('_v'));
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
const illustrationNameUpperCase = illustrationNameForTranslation.toUpperCase();
|
83
|
+
|
84
|
+
return defaultText ? `import { registerIllustration } from "@ui5/webcomponents-base/dist/asset-registries/Illustrations.js";
|
85
|
+
import dialogSvg from "./${illustrationsPrefix}-Dialog-${illustrationName}.js";
|
86
|
+
import sceneSvg from "./${illustrationsPrefix}-Scene-${illustrationName}.js";
|
87
|
+
import spotSvg from "./${illustrationsPrefix}-Spot-${illustrationName}.js";
|
88
|
+
import {
|
89
|
+
IM_TITLE_${illustrationNameUpperCase},
|
90
|
+
IM_SUBTITLE_${illustrationNameUpperCase},
|
91
|
+
} from "../generated/i18n/i18n-defaults.js";
|
92
|
+
|
93
|
+
const name = "${illustrationName}";
|
94
|
+
const set = "${illustrationSet}";
|
95
|
+
const title = IM_TITLE_${illustrationNameUpperCase};
|
96
|
+
const subtitle = IM_SUBTITLE_${illustrationNameUpperCase};
|
97
|
+
|
98
|
+
registerIllustration(name, {
|
99
|
+
dialogSvg,
|
100
|
+
sceneSvg,
|
101
|
+
spotSvg,
|
102
|
+
title,
|
103
|
+
subtitle,
|
104
|
+
set,
|
105
|
+
});
|
106
|
+
|
107
|
+
export {
|
108
|
+
dialogSvg,
|
109
|
+
sceneSvg,
|
110
|
+
spotSvg,
|
111
|
+
};` :
|
112
|
+
`import { registerIllustration } from "@ui5/webcomponents-base/dist/asset-registries/Illustrations.js";
|
113
|
+
import dialogSvg from "./${illustrationsPrefix}-Dialog-${illustrationName}.js";
|
114
|
+
import sceneSvg from "./${illustrationsPrefix}-Scene-${illustrationName}.js";
|
115
|
+
import spotSvg from "./${illustrationsPrefix}-Spot-${illustrationName}.js";
|
116
|
+
|
117
|
+
const name = "${illustrationName}";
|
118
|
+
const set = "${illustrationSet}";
|
119
|
+
|
120
|
+
registerIllustration(name, {
|
121
|
+
dialogSvg,
|
122
|
+
sceneSvg,
|
123
|
+
spotSvg,
|
124
|
+
set,
|
125
|
+
});
|
126
|
+
|
127
|
+
export {
|
128
|
+
dialogSvg,
|
129
|
+
sceneSvg,
|
130
|
+
spotSvg,
|
131
|
+
};`
|
132
|
+
};
|
133
|
+
|
134
|
+
mkdirp.sync(destPath);
|
135
|
+
|
136
|
+
const illustrationFileNames = fs.readdirSync(path.normalize(srcPath));
|
137
|
+
|
138
|
+
// convert SVG to JS imports
|
139
|
+
illustrationFileNames.forEach(illustration => {
|
140
|
+
if (fileNamePattern.test(illustration)) {
|
141
|
+
let [fileName, illustrationName] = illustration.match(fileNamePattern);
|
142
|
+
|
143
|
+
svgToJs(fileName);
|
144
|
+
fileNames.add(illustrationName);
|
145
|
+
}
|
146
|
+
});
|
147
|
+
|
148
|
+
for (let illustrationName of fileNames) {
|
149
|
+
fs.writeFileSync(path.join(destPath, `${illustrationName}.js`), illustrationImportTemplate(illustrationName));
|
150
|
+
}
|
@@ -139,8 +139,16 @@ console.log(`Successfully generated ${componentName}.js`);
|
|
139
139
|
console.log(`Successfully generated ${componentName}.css`);
|
140
140
|
console.log(`Successfully generated ${componentName}.hbs`);
|
141
141
|
|
142
|
+
const bundleLogger = fs.createWriteStream("./bundle.common.js", {
|
143
|
+
flags: "a" // appending
|
144
|
+
});
|
145
|
+
|
146
|
+
bundleLogger.write(`
|
147
|
+
// TODO: Move this line in order to keep the file sorted alphabetically
|
148
|
+
import ${componentName} from "./dist/${componentName}.js";`);
|
149
|
+
|
142
150
|
// Change the color of the output
|
143
|
-
console.warn('\x1b[33m%s\x1b[0m', `
|
144
|
-
|
145
|
-
|
146
|
-
`);
|
151
|
+
console.warn('\x1b[33m%s\x1b[0m', `
|
152
|
+
Component is imported in bundle.common.js.
|
153
|
+
Do NOT forget to sort the file in alphabeticall order.
|
154
|
+
`);
|
@@ -10,8 +10,13 @@ const Handlebars = require('handlebars/dist/handlebars.min.js');
|
|
10
10
|
const fs = require('fs');
|
11
11
|
const path = require('path');
|
12
12
|
const mkdirp = require('mkdirp');
|
13
|
+
const beautify = require("json-beautify");
|
13
14
|
|
14
|
-
|
15
|
+
|
16
|
+
const apiJSONPath = path.normalize(process.argv[2]);
|
17
|
+
const api = JSON.parse(fs.readFileSync(apiJSONPath));
|
18
|
+
|
19
|
+
fs.writeFileSync(apiJSONPath, beautify(api, null, 2, 100));
|
15
20
|
|
16
21
|
const entries = api['symbols'];
|
17
22
|
const compiledHandlebars = Handlebars.compile(template);
|
@@ -61,28 +66,40 @@ const appendCSSVarsAPI = entry => {
|
|
61
66
|
return entry;
|
62
67
|
}
|
63
68
|
|
64
|
-
const
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
let parent = getComponentByName(entry.extends) || {};
|
70
|
-
|
71
|
-
entry = appendCSSVarsAPI(entry);
|
72
|
-
parent = appendCSSVarsAPI(parent);
|
73
|
-
|
74
|
-
parent = { ...{ properties: [], events: [], slots: [], cssVariables: [] }, ...parent };
|
69
|
+
const componentHasEntityItem = (component, entity, name) => {
|
70
|
+
return component[entity].some(x => x && x.name === name);
|
71
|
+
};
|
72
|
+
const removeEmpty = arr => arr.filter(x => x);
|
75
73
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
74
|
+
const calculateAPI = component => {
|
75
|
+
if (entriesAPI.indexOf(component.basename) !== -1) {
|
76
|
+
return component;
|
77
|
+
}
|
78
|
+
const entities = ["properties", "slots", "events", "methods", "cssVariables"];
|
79
|
+
|
80
|
+
// Initialize all entities with [] if necessary, and remove undefined things, and only leave public things
|
81
|
+
entities.forEach(entity => {
|
82
|
+
component[entity] = removeEmpty(component[entity] || []).filter(x => x.visibility === "public");
|
83
|
+
});
|
84
|
+
|
85
|
+
component = appendCSSVarsAPI(component);
|
86
|
+
|
87
|
+
let parent = getComponentByName(component.extends);
|
88
|
+
if (parent) {
|
89
|
+
let parentComponent = calculateAPI(parent);
|
90
|
+
entities.forEach(entity => {
|
91
|
+
parentComponent[entity].forEach( x => {
|
92
|
+
if (!componentHasEntityItem(component, entity, x.name)) {
|
93
|
+
component[entity].push(x);
|
94
|
+
}
|
95
|
+
});
|
96
|
+
});
|
97
|
+
}
|
81
98
|
|
82
|
-
entriesAPI.push(
|
99
|
+
entriesAPI.push(component.basename);
|
83
100
|
|
84
|
-
return
|
85
|
-
}
|
101
|
+
return component;
|
102
|
+
};
|
86
103
|
|
87
104
|
const appendAdditionalEntriesAPI = entry => {
|
88
105
|
if (entry.appenddocs) {
|
@@ -107,6 +124,11 @@ const generateSamplePage = entry => {
|
|
107
124
|
} catch (err) { }
|
108
125
|
|
109
126
|
if (content) {
|
127
|
+
entry.slots.forEach(slotData => {
|
128
|
+
if (!slotData.type.startsWith("Node") && !slotData.type.startsWith("HTMLElement")) { // interface -> don't show in documentation
|
129
|
+
slotData.type = "HTMLElement" + (slotData.type.endsWith("[]") ? "[]" : "");
|
130
|
+
}
|
131
|
+
});
|
110
132
|
const APIReference = compiledHandlebars(entry).replace(/\[\]/g, " [0..n]");
|
111
133
|
const EntitySince = compiledSinceTemplate(entry).replace(/\[\]/g, " [0..n]");
|
112
134
|
|
@@ -21,7 +21,9 @@ module.exports = {
|
|
21
21
|
{{/if}}
|
22
22
|
<br>
|
23
23
|
{{#if (toKebabCase this.name)}}
|
24
|
-
|
24
|
+
{{#unless this.noattribute}}
|
25
|
+
<code>{{toKebabCase this.name}}</code>
|
26
|
+
{{/unless}}
|
25
27
|
{{/if}}
|
26
28
|
</div>
|
27
29
|
<div class="cell api-table-content-cell">{{this.type}}</div>
|
@@ -23,6 +23,7 @@ module.exports = {
|
|
23
23
|
{{> properties this}}
|
24
24
|
{{> slots this}}
|
25
25
|
{{> events this}}
|
26
|
+
{{> methods this}}
|
26
27
|
{{> cssVariables this}}
|
27
28
|
</section>
|
28
29
|
</section>
|
@@ -33,6 +34,6 @@ module.exports = {
|
|
33
34
|
<a class="separator" href="https://www.sap.com/about/legal/privacy.html" target="_blank">Privacy Policy</a>
|
34
35
|
<a href="https://www.sap.com/about/legal/impressum.html" target="_blank">Legal</a>
|
35
36
|
</div>
|
36
|
-
<img src="
|
37
|
+
<img src="../../../assets/images/sap-logo-svg.svg" alt="Sap Logo" />
|
37
38
|
</footer>`
|
38
39
|
};
|
@@ -0,0 +1,54 @@
|
|
1
|
+
const esprima = require("esprima");
|
2
|
+
const escodegen = require("escodegen");
|
3
|
+
|
4
|
+
const fs = require("fs");
|
5
|
+
const path = require("path");
|
6
|
+
const glob = require("glob");
|
7
|
+
const basePath = process.argv[2];
|
8
|
+
|
9
|
+
const convertImports = (srcPath) => {
|
10
|
+
let changed = false;
|
11
|
+
// console.log("scanning imports of", srcPath);
|
12
|
+
let code = fs.readFileSync(srcPath).toString();
|
13
|
+
const tree = esprima.parseModule(code);
|
14
|
+
const importer = srcPath.replace(basePath, "");
|
15
|
+
const importerDir = path.dirname(importer);
|
16
|
+
// console.log("-> ", importer);
|
17
|
+
tree.body.forEach(node => {
|
18
|
+
if (node.type === "ImportDeclaration") {
|
19
|
+
let importee = node.source.value;
|
20
|
+
if (importee.startsWith(".")) {
|
21
|
+
// add .js extension if missing
|
22
|
+
if (!importee.endsWith(".js")) {
|
23
|
+
node.source.value += ".js"
|
24
|
+
changed = true;
|
25
|
+
}
|
26
|
+
return;
|
27
|
+
}
|
28
|
+
let importeeDir = path.dirname(importee);
|
29
|
+
let importeeFile = path.basename(importee);
|
30
|
+
let relativePath = path.relative(importerDir, importeeDir);
|
31
|
+
if (relativePath.length === 0) {
|
32
|
+
relativePath = "."
|
33
|
+
}
|
34
|
+
if (!relativePath.startsWith(".")) {
|
35
|
+
relativePath = "./" + relativePath;
|
36
|
+
}
|
37
|
+
|
38
|
+
relativePath = relativePath.replace(/\\/g, "/"); // the browser expects unix paths
|
39
|
+
let relativeImport = `${relativePath}/${importeeFile}.js`;
|
40
|
+
// console.log(importee + " --> " + relativeImport);
|
41
|
+
node.source.value = relativeImport;
|
42
|
+
changed = true;
|
43
|
+
}
|
44
|
+
});
|
45
|
+
|
46
|
+
if (changed) {
|
47
|
+
fs.writeFileSync(srcPath, escodegen.generate(tree));
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
const fileNames = glob.sync(basePath + "**/*.js");
|
52
|
+
// console.log(fileNames);
|
53
|
+
fileNames.forEach(convertImports);
|
54
|
+
console.log("Success: Converted absolute imports to relative for files in:", basePath)
|
@@ -5,7 +5,8 @@ const mkdirp = require("mkdirp");
|
|
5
5
|
const packageName = JSON.parse(fs.readFileSync("package.json")).name;
|
6
6
|
|
7
7
|
const inputFolder = path.normalize(process.argv[2]);
|
8
|
-
const outputFile = path.normalize(`${process.argv[3]}/i18n.js`);
|
8
|
+
const outputFile = path.normalize(`${process.argv[3]}/i18n-static.js`);
|
9
|
+
const outputFileDynamic = path.normalize(`${process.argv[3]}/i18n.js`);
|
9
10
|
|
10
11
|
// All languages present in the file system
|
11
12
|
const files = fs.readdirSync(inputFolder);
|
@@ -14,22 +15,23 @@ const languages = files.map(file => {
|
|
14
15
|
return matches ? matches[1] : undefined;
|
15
16
|
}).filter(key => !!key);
|
16
17
|
|
17
|
-
let
|
18
|
+
let contentStatic, contentDynamic;
|
18
19
|
|
19
20
|
// No i18n - just import dependencies, if any
|
20
21
|
if (languages.length === 0) {
|
21
|
-
|
22
|
+
contentStatic = "";
|
23
|
+
contentDynamic = "";
|
22
24
|
// There is i18n - generate the full file
|
23
25
|
} else {
|
26
|
+
// Keys for the array
|
27
|
+
const languagesKeysString = languages.map(key => `"${key}": _${key},`).join("\n\t");
|
28
|
+
const languagesKeysStringArray = languages.map(key => `"${key}",`).join("\n\t");
|
24
29
|
|
25
|
-
//
|
26
|
-
const
|
30
|
+
// Actual imports for json assets
|
31
|
+
const assetsImportsString = languages.map(key => `import _${key} from "../assets/i18n/messagebundle_${key}.json";`).join("\n");
|
27
32
|
|
28
|
-
//
|
29
|
-
|
30
|
-
|
31
|
-
// Resulting file content
|
32
|
-
content = `import { registerI18nBundle } from "@ui5/webcomponents-base/dist/asset-registries/i18n.js";
|
33
|
+
// static imports
|
34
|
+
contentStatic = `import { registerI18nLoader } from "@ui5/webcomponents-base/dist/asset-registries/i18n.js";
|
33
35
|
|
34
36
|
${assetsImportsString}
|
35
37
|
|
@@ -37,17 +39,53 @@ const bundleMap = {
|
|
37
39
|
${languagesKeysString}
|
38
40
|
};
|
39
41
|
|
40
|
-
const
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
42
|
+
const fetchMessageBundle = async (localeId) => {
|
43
|
+
if (typeof bundleMap[localeId] === "object") {
|
44
|
+
// inlined from build
|
45
|
+
throw new Error("[i18n] Inlined JSON not supported with static imports of assets. Use dynamic imports of assets or configure JSON imports as URLs")
|
46
|
+
}
|
47
|
+
return (await fetch(bundleMap[localeId])).json()
|
46
48
|
}
|
47
49
|
|
48
|
-
|
50
|
+
const localeIds = [${languagesKeysStringArray}];
|
51
|
+
|
52
|
+
localeIds.forEach(localeId => {
|
53
|
+
registerI18nLoader("${packageName}", localeId, fetchMessageBundle);
|
54
|
+
});
|
49
55
|
`;
|
56
|
+
|
57
|
+
// Actual imports for json assets
|
58
|
+
const dynamicImportsString = languages.map(key => ` case "${key}": return (await import("../assets/i18n/messagebundle_${key}.json")).default;`).join("\n");
|
59
|
+
|
60
|
+
// Resulting file content
|
61
|
+
contentDynamic = `import { registerI18nLoader } from "@ui5/webcomponents-base/dist/asset-registries/i18n.js";
|
62
|
+
|
63
|
+
const importMessageBundle = async (localeId) => {
|
64
|
+
switch (localeId) {
|
65
|
+
${dynamicImportsString}
|
66
|
+
default: throw "unknown locale"
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
const importAndCheck = async (localeId) => {
|
71
|
+
const data = await importMessageBundle(localeId);
|
72
|
+
if (typeof data === "string" && data.endsWith(".json")) {
|
73
|
+
throw new Error(\`[i18n] Invalid bundling detected - dynamic JSON imports bundled as URLs. Switch to inlining JSON files from the build or use 'import ".../Assets-static.js"'. Check the \"Assets\" documentation for more information.\`);
|
74
|
+
}
|
75
|
+
return data;
|
76
|
+
}
|
77
|
+
|
78
|
+
const localeIds = [${languagesKeysStringArray}];
|
79
|
+
|
80
|
+
localeIds.forEach(localeId => {
|
81
|
+
registerI18nLoader("${packageName}", localeId, importAndCheck);
|
82
|
+
});
|
83
|
+
`;
|
84
|
+
|
85
|
+
|
50
86
|
}
|
51
87
|
|
88
|
+
|
52
89
|
mkdirp.sync(path.dirname(outputFile));
|
53
|
-
fs.writeFileSync(outputFile,
|
90
|
+
fs.writeFileSync(outputFile, contentStatic);
|
91
|
+
fs.writeFileSync(outputFileDynamic, contentDynamic);
|
@@ -4,39 +4,70 @@ const mkdirp = require("mkdirp");
|
|
4
4
|
const assets = require("../../assets-meta.js");
|
5
5
|
|
6
6
|
const inputFolder = path.normalize(process.argv[2]);
|
7
|
-
const outputFile = path.normalize(`${process.argv[3]}/Themes.js`);
|
7
|
+
const outputFile = path.normalize(`${process.argv[3]}/Themes-static.js`);
|
8
|
+
const outputFileDynamic = path.normalize(`${process.argv[3]}/Themes.js`);
|
8
9
|
|
9
10
|
// All supported optional themes
|
10
|
-
const
|
11
|
+
const allThemes = assets.themes.all;
|
11
12
|
|
12
13
|
// All themes present in the file system
|
13
14
|
const dirs = fs.readdirSync(inputFolder);
|
14
15
|
const themesOnFileSystem = dirs.map(dir => {
|
15
16
|
const matches = dir.match(/sap_.*$/);
|
16
17
|
return matches ? dir : undefined;
|
17
|
-
}).filter(key => !!key &&
|
18
|
+
}).filter(key => !!key && allThemes.includes(key));
|
18
19
|
|
19
20
|
const packageName = JSON.parse(fs.readFileSync("package.json")).name;
|
20
21
|
|
21
22
|
const importLines = themesOnFileSystem.map(theme => `import ${theme} from "../assets/themes/${theme}/parameters-bundle.css.json";`).join("\n");
|
22
|
-
const
|
23
|
-
const
|
23
|
+
const themeUrlsByName = "{\n" + themesOnFileSystem.join(",\n") + "\n}";
|
24
|
+
const availableThemesArray = `[${themesOnFileSystem.map(theme => `"${theme}"`).join(", ")}]`;
|
25
|
+
const dynamicImportLines = themesOnFileSystem.map(theme => `\t\tcase "${theme}": return (await import("../assets/themes/${theme}/parameters-bundle.css.json")).default;`).join("\n");
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
+
|
28
|
+
// static imports file content
|
29
|
+
const contentStatic = `import { registerThemePropertiesLoader } from "@ui5/webcomponents-base/dist/asset-registries/Themes.js";
|
27
30
|
|
28
31
|
${importLines}
|
29
32
|
|
33
|
+
const themeUrlsByName = ${themeUrlsByName};
|
30
34
|
const isInlined = obj => typeof (obj) === "object";
|
31
35
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
+
const loadThemeProperties = async (themeName) => {
|
37
|
+
if (typeof themeUrlsByName[themeName] === "object") {
|
38
|
+
// inlined from build
|
39
|
+
throw new Error("[themes] Inlined JSON not supported with static imports of assets. Use dynamic imports of assets or configure JSON imports as URLs");
|
40
|
+
}
|
41
|
+
return (await fetch(themeUrlsByName[themeName])).json();
|
42
|
+
}
|
43
|
+
|
44
|
+
${availableThemesArray}
|
45
|
+
.forEach(themeName => registerThemePropertiesLoader("${packageName}", themeName, loadThemeProperties));
|
46
|
+
`;
|
47
|
+
|
48
|
+
|
49
|
+
// dynamic imports file content
|
50
|
+
const contentDynamic = `import { registerThemePropertiesLoader } from "@ui5/webcomponents-base/dist/asset-registries/Themes.js";
|
51
|
+
|
52
|
+
const loadThemeProperties = async (themeName) => {
|
53
|
+
switch (themeName) {
|
54
|
+
${dynamicImportLines}
|
55
|
+
default: throw "unknown theme"
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
const loadAndCheck = async (themeName) => {
|
60
|
+
const data = await loadThemeProperties(themeName);
|
61
|
+
if (typeof data === "string" && data.endsWith(".json")) {
|
62
|
+
throw new Error(\`[themes] Invalid bundling detected - dynamic JSON imports bundled as URLs. Switch to inlining JSON files from the build or use 'import ".../Assets-static.js"'. Check the \"Assets\" documentation for more information.\`);
|
63
|
+
}
|
64
|
+
return data;
|
36
65
|
}
|
37
66
|
|
38
|
-
${
|
67
|
+
${availableThemesArray}
|
68
|
+
.forEach(themeName => registerThemePropertiesLoader("${packageName}", themeName, loadAndCheck));
|
39
69
|
`;
|
40
70
|
|
41
71
|
mkdirp.sync(path.dirname(outputFile));
|
42
|
-
fs.writeFileSync(outputFile,
|
72
|
+
fs.writeFileSync(outputFile, contentStatic);
|
73
|
+
fs.writeFileSync(outputFileDynamic, contentDynamic);
|
@@ -0,0 +1,19 @@
|
|
1
|
+
const fs = require("fs");
|
2
|
+
const path = require("path");
|
3
|
+
const process = require("process");
|
4
|
+
const { hashElement } = require("folder-hash");
|
5
|
+
const config = require("./config.js");
|
6
|
+
|
7
|
+
const inputDir = path.normalize(process.argv[2]);
|
8
|
+
const outputFileName = path.normalize(process.argv[3]);
|
9
|
+
|
10
|
+
const generateHash = async (inputDir, outputFileName) => {
|
11
|
+
const result = await hashElement(inputDir, config);
|
12
|
+
const hash = result.hash;
|
13
|
+
fs.writeFileSync(outputFileName, hash);
|
14
|
+
return hash;
|
15
|
+
};
|
16
|
+
|
17
|
+
generateHash(inputDir, outputFileName).then(hash => {
|
18
|
+
console.log(`Generated hash: ${hash}`);
|
19
|
+
});
|