@ui5/webcomponents-tools 0.0.0-c6d8872f3 → 0.0.0-cf069fb29

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.
Files changed (75) hide show
  1. package/CHANGELOG.md +164 -1
  2. package/README.md +1 -1
  3. package/assets-meta.js +149 -0
  4. package/bin/dev.js +16 -1
  5. package/components-package/nps.js +73 -34
  6. package/components-package/postcss.themes.js +5 -2
  7. package/components-package/rollup-plugins/empty-module.js +15 -0
  8. package/components-package/rollup.js +155 -50
  9. package/components-package/wdio.js +100 -64
  10. package/components-package/wdio.sync.js +360 -0
  11. package/icons-collection/nps.js +72 -28
  12. package/lib/copy-and-watch/index.js +122 -0
  13. package/lib/copy-list/index.js +28 -0
  14. package/lib/create-icons/index.js +41 -23
  15. package/lib/create-illustrations/index.js +150 -0
  16. package/lib/create-new-component/index.js +18 -6
  17. package/lib/documentation/index.js +43 -21
  18. package/lib/documentation/templates/template.js +1 -1
  19. package/lib/esm-abs-to-rel/index.js +54 -0
  20. package/lib/generate-json-imports/i18n.js +91 -47
  21. package/lib/generate-json-imports/themes.js +61 -15
  22. package/lib/hash/config.js +10 -0
  23. package/lib/hash/generate.js +19 -0
  24. package/lib/hash/upToDate.js +31 -0
  25. package/lib/hbs2lit/index.js +2 -4
  26. package/lib/hbs2lit/src/compiler.js +8 -7
  27. package/lib/hbs2lit/src/includesReplacer.js +22 -16
  28. package/lib/hbs2lit/src/litVisitor2.js +44 -8
  29. package/lib/hbs2lit/src/svgProcessor.js +3 -3
  30. package/lib/hbs2ui5/RenderTemplates/LitRenderer.js +5 -5
  31. package/lib/hbs2ui5/index.js +26 -20
  32. package/lib/i18n/defaults.js +25 -6
  33. package/lib/i18n/toJSON.js +15 -4
  34. package/lib/jsdoc/config.json +1 -1
  35. package/lib/jsdoc/plugin.js +24 -4
  36. package/lib/jsdoc/template/publish.js +11 -2
  37. package/lib/polyfill-placeholder/index.js +5 -0
  38. package/lib/postcss-css-to-esm/index.js +31 -19
  39. package/lib/postcss-css-to-json/index.js +27 -11
  40. package/lib/postcss-new-files/index.js +36 -0
  41. package/lib/replace-global-core/index.js +20 -0
  42. package/lib/scoping/get-all-tags.js +44 -0
  43. package/lib/scoping/lint-src.js +31 -0
  44. package/lib/scoping/scope-test-pages.js +40 -0
  45. package/lib/serve/index.js +46 -0
  46. package/{components-package → lib/serve}/serve.json +0 -0
  47. package/package-lock.json +48 -0
  48. package/package.json +55 -55
  49. package/bin/init-ui5-package.js +0 -3
  50. package/lib/init-package/index.js +0 -119
  51. package/lib/init-package/resources/.eslintignore +0 -3
  52. package/lib/init-package/resources/bundle.es5.js +0 -25
  53. package/lib/init-package/resources/bundle.esm.js +0 -34
  54. package/lib/init-package/resources/config/.eslintrc.js +0 -1
  55. package/lib/init-package/resources/config/postcss.components/postcss.config.js +0 -1
  56. package/lib/init-package/resources/config/postcss.themes/postcss.config.js +0 -1
  57. package/lib/init-package/resources/config/rollup.config.js +0 -1
  58. package/lib/init-package/resources/config/wdio.conf.js +0 -1
  59. package/lib/init-package/resources/package-scripts.js +0 -11
  60. package/lib/init-package/resources/src/Assets.js +0 -6
  61. package/lib/init-package/resources/src/Demo.hbs +0 -1
  62. package/lib/init-package/resources/src/Demo.js +0 -56
  63. package/lib/init-package/resources/src/i18n/messagebundle.properties +0 -2
  64. package/lib/init-package/resources/src/i18n/messagebundle_de.properties +0 -1
  65. package/lib/init-package/resources/src/i18n/messagebundle_en.properties +0 -1
  66. package/lib/init-package/resources/src/i18n/messagebundle_es.properties +0 -1
  67. package/lib/init-package/resources/src/i18n/messagebundle_fr.properties +0 -1
  68. package/lib/init-package/resources/src/themes/Demo.css +0 -11
  69. package/lib/init-package/resources/src/themes/sap_belize/parameters-bundle.css +0 -3
  70. package/lib/init-package/resources/src/themes/sap_belize_hcb/parameters-bundle.css +0 -3
  71. package/lib/init-package/resources/src/themes/sap_belize_hcw/parameters-bundle.css +0 -3
  72. package/lib/init-package/resources/src/themes/sap_fiori_3/parameters-bundle.css +0 -3
  73. package/lib/init-package/resources/src/themes/sap_fiori_3_dark/parameters-bundle.css +0 -3
  74. package/lib/init-package/resources/test/pages/index.html +0 -51
  75. package/lib/init-package/resources/test/specs/Demo.spec.js +0 -12
@@ -2,53 +2,71 @@ const fs = require("fs");
2
2
  const path = require("path");
3
3
  const mkdirp = require("mkdirp");
4
4
 
5
- const srcDir = `src/icon-collections/`;
6
- const destDir = `dist/icons/`;
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
- mkdirp(destDir);
10
+ mkdirp.sync(destDir);
9
11
 
10
- const template = (name, pathData) => `import { registerIcon } from "@ui5/webcomponents-base/dist/SVGIconRegistry.js";
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}";
16
+ const ltr = ${ltr};
17
+ const collection = "${collection}";
18
+ const packageName = "${packageName}";
14
19
 
15
- registerIcon(name, { pathData });
20
+ registerIcon(name, { pathData, ltr, collection, packageName });
16
21
 
17
22
  export default { pathData };`;
18
23
 
19
- const accTemplate = (name, pathData, accData) => `import { registerIcon } from "@ui5/webcomponents-base/dist/SVGIconRegistry.js";
24
+
25
+ const iconAccTemplate = (name, pathData, ltr, accData, collection, packageName) => `import { registerIcon } from "@ui5/webcomponents-base/dist/asset-registries/Icons.js";
20
26
  import { ${accData.key} } from "../generated/i18n/i18n-defaults.js";
21
27
 
22
28
  const name = "${name}";
23
29
  const pathData = "${pathData}";
30
+ const ltr = ${ltr};
24
31
  const accData = ${accData.key};
32
+ const collection = "${collection}";
33
+ const packageName = "${packageName}";
25
34
 
26
- registerIcon(name, { pathData, accData });
35
+ registerIcon(name, { pathData, ltr, accData, collection, packageName });
27
36
 
28
37
  export default { pathData, accData };`;
29
38
 
30
39
 
40
+
41
+ const collectionTemplate = (name) => `import { isTheme } 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 = isTheme("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
+
31
52
  const createIcons = (file) => {
32
53
  const json = JSON.parse(fs.readFileSync(file));
54
+
33
55
  for (let name in json.data) {
34
- let content;
35
- const pathData = json.data[name];
36
- const accData = json.accData[name];
37
-
38
- if (accData) {
39
- content = accTemplate(name, pathData, accData);
40
- } else {
41
- content = template(name, pathData);
42
- }
56
+ const iconData = json.data[name];
57
+ const pathData = iconData.path;
58
+ const ltr = !!iconData.ltr;
59
+ const acc = iconData.acc;
60
+
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
- fs.readdirSync(srcDir).forEach(collectionFile => {
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
+ }
@@ -61,8 +61,12 @@ class ${componentName} extends UI5Element {
61
61
  return ${componentName}Template;
62
62
  }
63
63
 
64
- static async define(...params) {
65
- super.define(...params);
64
+ static get dependencies() {
65
+ return [];
66
+ }
67
+
68
+ static async onDefine() {
69
+
66
70
  }
67
71
  }
68
72
 
@@ -135,8 +139,16 @@ console.log(`Successfully generated ${componentName}.js`);
135
139
  console.log(`Successfully generated ${componentName}.css`);
136
140
  console.log(`Successfully generated ${componentName}.hbs`);
137
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
+
138
150
  // Change the color of the output
139
- console.warn('\x1b[33m%s\x1b[0m', `
140
- Please import the generated component in bundle.esm.js:
141
- import ${componentName} from "./dist/${componentName}.js";
142
- `);
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
- const api = JSON.parse(fs.readFileSync(path.normalize(process.argv[2])));
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);
@@ -52,7 +57,7 @@ Handlebars.registerPartial('events', eventsTemplate);
52
57
  Handlebars.registerPartial('methods', methodsTemplate);
53
58
  Handlebars.registerPartial('cssVariables', cssVariablesTemplate);
54
59
 
55
- mkdirp(`dist/test-resources/api`);
60
+ mkdirp.sync(`dist/test-resources/api`);
56
61
 
57
62
  let entriesAPI = [];
58
63
 
@@ -61,28 +66,40 @@ const appendCSSVarsAPI = entry => {
61
66
  return entry;
62
67
  }
63
68
 
64
- const calculateAPI = entry => {
65
- if (entriesAPI.indexOf(entry.basename) !== -1) {
66
- return entry;
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
- // extend component documentation
77
- entry.properties = [...(entry.properties || []), ...(parent.properties || [])];
78
- entry.events = [...(entry.events || []), ...(parent.events || [])];
79
- entry.slots = [...(entry.slots || []), ...(parent.slots || [])];
80
- entry.cssVariables = [...(entry.cssVariables || []), ...(parent.cssVariables || [])];
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(entry.basename);
99
+ entriesAPI.push(component.basename);
83
100
 
84
- return entry;
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
 
@@ -33,6 +33,6 @@ module.exports = {
33
33
  <a class="separator" href="https://www.sap.com/about/legal/privacy.html" target="_blank">Privacy Policy</a>
34
34
  <a href="https://www.sap.com/about/legal/impressum.html" target="_blank">Legal</a>
35
35
  </div>
36
- <img src="../../../../../../assets/images/sap-logo-svg.svg" alt="Sap Logo" />
36
+ <img src="../../../assets/images/sap-logo-svg.svg" alt="Sap Logo" />
37
37
  </footer>`
38
38
  };
@@ -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)
@@ -1,47 +1,91 @@
1
- const fs = require("fs");
2
-
3
- const packageName = JSON.parse(fs.readFileSync("package.json")).name;
4
-
5
- // All languages present in the file system
6
- const files = fs.readdirSync("dist/generated/assets/i18n/");
7
- const languages = files.map(file => {
8
- const matches = file.match(/messagebundle_(.+?).json$/);
9
- return matches ? matches[1] : undefined;
10
- }).filter(key => !!key);
11
-
12
- let content;
13
-
14
- // No i18n - just import dependencies, if any
15
- if (languages.length === 0) {
16
- content = ``;
17
- // There is i18n - generate the full file
18
- } else {
19
-
20
- // Keys for the array
21
- const languagesKeysString = languages.map(key => `${key},`).join("\n\t");
22
-
23
- // Actual imports for json assets
24
- const assetsImportsString = languages.map(key => `import ${key} from "../assets/i18n/messagebundle_${key}.json";`).join("\n");
25
-
26
- // Resulting file content
27
- content = `import { registerI18nBundle } from "@ui5/webcomponents-base/dist/asset-registries/i18n.js";
28
-
29
- ${assetsImportsString}
30
-
31
- const bundleMap = {
32
- ${languagesKeysString}
33
- };
34
-
35
- const allEntriesInlined = Object.entries(bundleMap).every(([_key, value]) => typeof (value) === "object");
36
-
37
- if (allEntriesInlined) {
38
- console.warn(\`Inefficient bundling detected: consider bundling i18n imports as URLs instead of inlining them.
39
- See rollup-plugin-url or webpack file-loader for more information.
40
- Suggested pattern: "assets\\\\\\/.*\\\\\\.json"\`);
41
- }
42
-
43
- registerI18nBundle("${packageName}", bundleMap);
44
- `;
45
- }
46
-
47
- fs.writeFileSync("dist/generated/json-imports/i18n.js", content);
1
+ const fs = require("fs");
2
+ const path = require('path');
3
+ const mkdirp = require("mkdirp");
4
+
5
+ const packageName = JSON.parse(fs.readFileSync("package.json")).name;
6
+
7
+ const inputFolder = path.normalize(process.argv[2]);
8
+ const outputFile = path.normalize(`${process.argv[3]}/i18n-static.js`);
9
+ const outputFileDynamic = path.normalize(`${process.argv[3]}/i18n.js`);
10
+
11
+ // All languages present in the file system
12
+ const files = fs.readdirSync(inputFolder);
13
+ const languages = files.map(file => {
14
+ const matches = file.match(/messagebundle_(.+?).json$/);
15
+ return matches ? matches[1] : undefined;
16
+ }).filter(key => !!key);
17
+
18
+ let contentStatic, contentDynamic;
19
+
20
+ // No i18n - just import dependencies, if any
21
+ if (languages.length === 0) {
22
+ contentStatic = "";
23
+ contentDynamic = "";
24
+ // There is i18n - generate the full file
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");
29
+
30
+ // Actual imports for json assets
31
+ const assetsImportsString = languages.map(key => `import _${key} from "../assets/i18n/messagebundle_${key}.json";`).join("\n");
32
+
33
+ // static imports
34
+ contentStatic = `import { registerI18nLoader } from "@ui5/webcomponents-base/dist/asset-registries/i18n.js";
35
+
36
+ ${assetsImportsString}
37
+
38
+ const bundleMap = {
39
+ ${languagesKeysString}
40
+ };
41
+
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()
48
+ }
49
+
50
+ const localeIds = [${languagesKeysStringArray}];
51
+
52
+ localeIds.forEach(localeId => {
53
+ registerI18nLoader("${packageName}", localeId, fetchMessageBundle);
54
+ });
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
+
86
+ }
87
+
88
+
89
+ mkdirp.sync(path.dirname(outputFile));
90
+ fs.writeFileSync(outputFile, contentStatic);
91
+ fs.writeFileSync(outputFileDynamic, contentDynamic);
@@ -1,27 +1,73 @@
1
1
  const fs = require("fs");
2
+ const path = require('path');
3
+ const mkdirp = require("mkdirp");
4
+ const assets = require("../../assets-meta.js");
5
+
6
+ const inputFolder = path.normalize(process.argv[2]);
7
+ const outputFile = path.normalize(`${process.argv[3]}/Themes-static.js`);
8
+ const outputFileDynamic = path.normalize(`${process.argv[3]}/Themes.js`);
9
+
10
+ // All supported optional themes
11
+ const allThemes = assets.themes.all;
12
+
13
+ // All themes present in the file system
14
+ const dirs = fs.readdirSync(inputFolder);
15
+ const themesOnFileSystem = dirs.map(dir => {
16
+ const matches = dir.match(/sap_.*$/);
17
+ return matches ? dir : undefined;
18
+ }).filter(key => !!key && allThemes.includes(key));
2
19
 
3
20
  const packageName = JSON.parse(fs.readFileSync("package.json")).name;
4
21
 
5
- // Resulting file content
6
- const content = `import { registerThemeProperties } from "@ui5/webcomponents-base/dist/asset-registries/Themes.js";
22
+ const importLines = themesOnFileSystem.map(theme => `import ${theme} from "../assets/themes/${theme}/parameters-bundle.css.json";`).join("\n");
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");
26
+
7
27
 
8
- import fiori3Dark from "../assets/themes/sap_fiori_3_dark/parameters-bundle.css.json";
9
- import belize from "../assets/themes/sap_belize/parameters-bundle.css.json";
10
- import belizeHcb from "../assets/themes/sap_belize_hcb/parameters-bundle.css.json";
11
- import belizeHcw from "../assets/themes/sap_belize_hcw/parameters-bundle.css.json";
28
+ // static imports file content
29
+ const contentStatic = `import { registerThemePropertiesLoader } from "@ui5/webcomponents-base/dist/asset-registries/Themes.js";
12
30
 
31
+ ${importLines}
32
+
33
+ const themeUrlsByName = ${themeUrlsByName};
13
34
  const isInlined = obj => typeof (obj) === "object";
14
35
 
15
- if (isInlined(fiori3Dark) || isInlined(belize) || isInlined(belizeHcb)) {
16
- console.warn(\`Inefficient bundling detected: consider bundling theme properties imports as URLs instead of inlining them.
17
- See rollup-plugin-url or webpack file-loader for more information.
18
- Suggested pattern: "assets\\\\\\/.*\\\\\\.json"\`);
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;
19
65
  }
20
66
 
21
- registerThemeProperties("${packageName}", "sap_fiori_3_dark", fiori3Dark);
22
- registerThemeProperties("${packageName}", "sap_belize", belize);
23
- registerThemeProperties("${packageName}", "sap_belize_hcb", belizeHcb);
24
- registerThemeProperties("${packageName}", "sap_belize_hcw", belizeHcw);
67
+ ${availableThemesArray}
68
+ .forEach(themeName => registerThemePropertiesLoader("${packageName}", themeName, loadAndCheck));
25
69
  `;
26
70
 
27
- fs.writeFileSync("dist/generated/json-imports/Themes.js", content);
71
+ mkdirp.sync(path.dirname(outputFile));
72
+ fs.writeFileSync(outputFile, contentStatic);
73
+ fs.writeFileSync(outputFileDynamic, contentDynamic);