@ui5/webcomponents-tools 0.0.0-e0658a650 → 0.0.0-e55c2cec6

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.
@@ -42,7 +42,7 @@ const getScripts = (options) => {
42
42
  }
43
43
 
44
44
  const scripts = {
45
- clean: 'rimraf dist && rimraf .port && nps "scope.testPages.clean"',
45
+ clean: 'rimraf jsdoc-dist && rimraf dist && rimraf .port && nps "scope.testPages.clean"',
46
46
  lint: `eslint . ${eslintConfig}`,
47
47
  lintfix: `eslint . ${eslintConfig}`,
48
48
  prepare: {
@@ -121,8 +121,8 @@ const getScripts = (options) => {
121
121
  },
122
122
  generateAPI: {
123
123
  default: "nps generateAPI.prepare generateAPI.preprocess generateAPI.jsdoc generateAPI.cleanup",
124
- prepare: `copy-and-watch "dist/**/*.js" jsdoc-dist/`,
125
- preprocess: `node "${preprocessJSDocScript}" jsdoc-dist/`,
124
+ prepare: `node "${LIB}/copy-and-watch/index.js" --silent "dist/**/*.js" jsdoc-dist/`,
125
+ preprocess: `node "${preprocessJSDocScript}" jsdoc-dist/ src`,
126
126
  jsdoc: `jsdoc -c "${LIB}/jsdoc/configTypescript.json"`,
127
127
  cleanup: "rimraf jsdoc-dist/"
128
128
  },
@@ -217,6 +217,12 @@ exports.config = {
217
217
  }, this, className);
218
218
  }, true);
219
219
 
220
+ await browser.addCommand("hasAttribute", async function(attrName) {
221
+ return browser.executeAsync((elem, attrName, done) => {
222
+ done(elem.hasAttribute(attrName));
223
+ }, this, attrName);
224
+ }, true);
225
+
220
226
  await browser.addCommand("getStaticAreaItemClassName", async function(selector) {
221
227
  return browser.executeAsync(async (selector, done) => {
222
228
  const staticAreaItem = await document.querySelector(selector).getStaticAreaItemDomRef();
@@ -238,6 +244,7 @@ exports.config = {
238
244
  "$",
239
245
  "$$",
240
246
  "getAttribute",
247
+ "hasAttribute", // custom
241
248
  "getCSSProperty",
242
249
  "getHTML",
243
250
  "getProperty",
@@ -46,7 +46,7 @@ const getScripts = (options) => {
46
46
  clean: "rimraf dist",
47
47
  copy: copyAssetsCmd,
48
48
  build: {
49
- default: `nps clean copy build.i18n build.icons build.jsonImports`,
49
+ default: `nps clean typescript copy build.i18n build.icons build.jsonImports`,
50
50
  i18n: {
51
51
  default: "nps build.i18n.defaultsjs build.i18n.json",
52
52
  defaultsjs: `mkdirp dist/generated/i18n && node "${LIB}/i18n/defaults.js" src/i18n dist/generated/i18n`,
@@ -58,6 +58,7 @@ const getScripts = (options) => {
58
58
  },
59
59
  icons: createJSImportsCmd,
60
60
  },
61
+ typescript: "tsc",
61
62
  };
62
63
 
63
64
  return scripts;
@@ -3,7 +3,7 @@ const path = require("path");
3
3
 
4
4
  const fileList = process.argv[2];
5
5
  const dest = process.argv[3];
6
- const src = "../../node_modules/@openui5/sap.ui.core/src/";
6
+ const src = "@openui5/sap.ui.core/src/";
7
7
 
8
8
  const generate = async () => {
9
9
  const filesToCopy = (await fs.readFile(fileList)).toString();
@@ -15,7 +15,7 @@ const generate = async () => {
15
15
  const trimFile = file => file.trim();
16
16
 
17
17
  return filesToCopy.split("\n").map(trimFile).filter(shouldCopy).map(async moduleName => {
18
- const srcPath = path.join(src, moduleName);
18
+ const srcPath = require.resolve(path.join(src, moduleName), {paths: [process.cwd()]});
19
19
  const destPath = path.join(dest, moduleName);
20
20
 
21
21
  await fs.mkdir(path.dirname(destPath), { recursive: true });
@@ -13,13 +13,13 @@ import ${componentName}Css from "./generated/themes/${componentName}.css.js";
13
13
  */
14
14
  const metadata = {
15
15
  tag: "${tagName}",
16
- properties: /** @lends sap.ui.webcomponents.${library}.${componentName}.prototype */ {
16
+ properties: /** @lends sap.ui.webc.${library}.${componentName}.prototype */ {
17
17
  //
18
18
  },
19
- slots: /** @lends sap.ui.webcomponents.${library}.${componentName}.prototype */ {
19
+ slots: /** @lends sap.ui.webc.${library}.${componentName}.prototype */ {
20
20
  //
21
21
  },
22
- events: /** @lends sap.ui.webcomponents.${library}.${componentName}.prototype */ {
22
+ events: /** @lends sap.ui.webc.${library}.${componentName}.prototype */ {
23
23
  //
24
24
  },
25
25
  };
@@ -39,8 +39,8 @@ const metadata = {
39
39
  *
40
40
  * @constructor
41
41
  * @author SAP SE
42
- * @alias sap.ui.webcomponents.${library}.${componentName}
43
- * @extends sap.ui.webcomponents.base.UI5Element
42
+ * @alias sap.ui.webc.${library}.${componentName}
43
+ * @extends sap.ui.webc.base.UI5Element
44
44
  * @tagname ${tagName}
45
45
  * @public
46
46
  */
@@ -33,6 +33,7 @@ const virtualIndexPlugin = async () => {
33
33
  const folders = Object.keys(pagesPerFolder);
34
34
 
35
35
  res.statusCode = 200;
36
+ res.setHeader("Content-Type", "text/html; charset=utf-8");
36
37
  res.end(`${folders.map(folder => {
37
38
  const pages = pagesPerFolder[folder];
38
39
  return `<h1>${folder}</h1>
@@ -274,11 +274,15 @@ const generateCustomElementDeclaration = entity => {
274
274
  const generateRefenrece = (entity) => {
275
275
  let packageName;
276
276
 
277
- if (entity.name.includes("sap.ui.webcomponents.main")) {
277
+ if (!entity.name) {
278
+ throw new Error("JSDoc error: entity not found in api.json.");
279
+ }
280
+
281
+ if (entity.name.includes("sap.ui.webc.main")) {
278
282
  packageName = "@ui5/webcomponents";
279
- } else if (entity.name.includes("sap.ui.webcomponents.fiori")) {
283
+ } else if (entity.name.includes("sap.ui.webc.fiori")) {
280
284
  packageName = "@ui5/webcomponents-fiori";
281
- } else if (entity.name.includes("sap.ui.webcomponents.base")) {
285
+ } else if (entity.name.includes("sap.ui.webc.base")) {
282
286
  packageName = "@ui5/webcomponents-base";
283
287
  }
284
288
 
@@ -3,30 +3,31 @@ const path = require("path");
3
3
  const fs = require("fs/promises");
4
4
 
5
5
  const inputDir = process.argv[2];
6
+ const sourceDir = process.argv[3];
6
7
 
7
- const preprocess = async () => {
8
+ const preprocessTypes = async () => {
8
9
  try {
9
10
  const { globby } = await import("globby");
10
11
  const fileNames = await globby(inputDir + "**/types/*.js");
11
12
 
12
- return Promise.all(fileNames.map(processFile));
13
+ return Promise.all(fileNames.map(processTypeFile));
13
14
  } catch(e) {
14
- console.log("JSDoc preprocess failed: ", e);
15
+ console.log("JSDoc types preprocess failed: ", e);
15
16
  }
16
17
  };
17
18
 
18
- const processFile = async (fileName) => {
19
+ const processTypeFile = async (fileName) => {
19
20
  let fileContent = `${await fs.readFile(fileName)}`;
20
21
 
21
- const re = new RegExp(`(\\/\\*\\*[^\\/]+\\s+\\*\\/)?\\s+\\s+.*?\\["([\\w\\d]+)"\\].*?"([\\w\\d]+)";`, "gm")
22
+ const re = new RegExp(`(\\/\\*\\*\\s*\\n([^\\*]|(\\*(?!\\/)))*\\*\\/)\\s+[\\w\\d]+\\[\\"([\\w\\d]+)\\"\\]\\s*=\\s*\\"([\\w\\d]+)\\";`, "gm")
22
23
  let matches = [...fileContent.matchAll(re)];
23
24
 
24
25
  // Get all type values
25
26
  const typeData = matches.map(match => {
26
27
  return {
27
28
  comment: match[1],
28
- key: match[2],
29
- value: match[3],
29
+ key: match[4],
30
+ value: match[5],
30
31
  };
31
32
  });
32
33
  if (typeData.length === 0) {
@@ -35,7 +36,7 @@ const processFile = async (fileName) => {
35
36
 
36
37
  const typeName = path.parse(fileName).name;
37
38
 
38
- matches = fileContent.match(/^\/\*\*[^\/]+\//gm);
39
+ matches = fileContent.match(/\/\*\*\s*\n([^\*]|(\*(?!\/)))*\*\//gm);
39
40
  const comment = matches[0];
40
41
 
41
42
  const propsCode = typeData.map(item => {
@@ -55,6 +56,91 @@ const processFile = async (fileName) => {
55
56
  return fs.writeFile(fileName, fileContent);
56
57
  };
57
58
 
58
- preprocess().then(() => {
59
+ const preprocessComponents = async () => {
60
+ if (!sourceDir) {
61
+ return; // if the second param was not passed, there are no components
62
+ }
63
+
64
+ try {
65
+ const { globby } = await import("globby");
66
+ const fileNames = await globby(sourceDir + "/*.ts");
67
+
68
+ return Promise.all(fileNames.map(processComponentFile));
69
+ } catch(e) {
70
+ console.log("JSDoc components preprocess failed: ", e);
71
+ }
72
+ };
73
+
74
+ const isClass = text => {
75
+ return text.includes("@abstract") || text.includes("@class");
76
+ };
77
+
78
+ const isAnnotationComment = (comment) => {
79
+ return comment.includes("@name");
80
+ }
81
+
82
+ const processComponentFile = async (fileName) => {
83
+ // source file (src/*.ts)
84
+ let tsFileContent = `${await fs.readFile(fileName)}`;
85
+
86
+ // Skip all non-component files
87
+ if (!isClass(tsFileContent)) {
88
+ return;
89
+ }
90
+
91
+ // Gather all JSDocs from the original .ts file
92
+ const allJSDocsRegExp = new RegExp(`\\/\\*\\*(.|\\n)+?\\s+\\*\\/`, "gm");
93
+ let allJSDocs = [...tsFileContent.matchAll(allJSDocsRegExp)];
94
+ allJSDocs = allJSDocs.map(match => match[0]); // all /** ..... */ comments
95
+
96
+ // Find where the class is defined in the original file
97
+ const tsClassDefinitionRegExp = new RegExp(`^(abstract\\s)?class [\\w\\d_]+`, "gm");
98
+ let tsClassDefinitionMatch = tsFileContent.match(tsClassDefinitionRegExp);
99
+ if (!tsClassDefinitionMatch) {
100
+ return; // no class defined in this .ts file
101
+ }
102
+ const tsClassDefinition = tsClassDefinitionMatch[0];
103
+ const tsClassDefinitionIndex = tsFileContent.indexOf(tsClassDefinition);
104
+
105
+ // Gather all JSDocs that are before the class definition (except for the @class one)
106
+ const JSDocsToAppend = [];
107
+ allJSDocs.forEach(JSDoc => {
108
+ if (!isClass(JSDoc) && (tsFileContent.indexOf(JSDoc) < tsClassDefinitionIndex || isAnnotationComment(JSDoc, tsFileContent))) {
109
+ JSDocsToAppend.push(JSDoc);
110
+ }
111
+ });
112
+
113
+
114
+
115
+ // destination file (jsdoc-dist/*.js)
116
+ const destFileName = fileName.replace(sourceDir, inputDir).replace(/\.ts$/, ".js");
117
+ let jsFileContent = `${await fs.readFile(destFileName)}`;
118
+
119
+ const classDefinitionRegExp = new RegExp(`let.*? = class`, "gm");
120
+ let classDefinitionMatch = jsFileContent.match(classDefinitionRegExp);
121
+ if (!classDefinitionMatch) {
122
+ return; // not a file, generated by typescript, nothing to do here
123
+ }
124
+
125
+ const classDefinition = classDefinitionMatch[0];
126
+ const classDefinitionIndex = jsFileContent.indexOf(classDefinition); // classDefinitionIndex is the position in the file where the class is defined
127
+
128
+ // All comments before the class definition, except for the @class comment, must be removed
129
+ allJSDocs.forEach(JSDoc => {
130
+ if (!isClass(JSDoc) && jsFileContent.indexOf(JSDoc) < classDefinitionIndex) {
131
+ jsFileContent = jsFileContent.replace(JSDoc, "");
132
+ }
133
+ });
134
+
135
+ // Put all other comments at the end of the file
136
+ jsFileContent = jsFileContent + "\n\n" + JSDocsToAppend.join("\n\n");
137
+ return fs.writeFile(destFileName, jsFileContent);
138
+ };
139
+
140
+ Promise.all([
141
+ preprocessTypes(),
142
+ preprocessComponents(),
143
+ ]).then(() => {
59
144
  console.log("JSDoc preprocess ready.");
60
145
  });
146
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ui5/webcomponents-tools",
3
- "version": "0.0.0-e0658a650",
3
+ "version": "0.0.0-e55c2cec6",
4
4
  "description": "UI5 Web Components: webcomponents.tools",
5
5
  "author": "SAP SE (https://www.sap.com)",
6
6
  "license": "Apache-2.0",