@ui5/webcomponents-tools 0.0.0-fca1107e7 → 0.0.0-fd426fe8a
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 +1078 -1
- package/README.md +2 -5
- package/assets-meta.js +1 -8
- package/components-package/eslint.js +59 -31
- package/components-package/nps.js +50 -30
- package/components-package/vite.config.js +7 -11
- package/components-package/wdio.js +415 -405
- package/icons-collection/nps.js +2 -2
- package/lib/cem/custom-elements-manifest.config.mjs +74 -45
- package/lib/cem/event.mjs +69 -32
- package/lib/cem/schema-internal.json +65 -0
- package/lib/cem/types-internal.d.ts +14 -2
- package/lib/cem/utils.mjs +69 -30
- package/lib/cem/validate.js +37 -40
- package/lib/create-icons/index.js +13 -10
- package/lib/create-illustrations/index.js +19 -1
- package/lib/create-new-component/{tsFileContentTemplate.js → Component.js} +12 -9
- package/lib/create-new-component/ComponentTemplate.js +12 -0
- package/lib/create-new-component/index.js +14 -22
- package/lib/css-processors/css-processor-components.mjs +3 -2
- package/lib/css-processors/css-processor-themes.mjs +2 -7
- package/lib/css-processors/shared.mjs +4 -24
- package/lib/dev-server/{dev-server.js → dev-server.mjs} +4 -4
- package/lib/dev-server/virtual-index-html-plugin.js +24 -20
- package/lib/generate-json-imports/i18n.js +46 -62
- package/lib/generate-json-imports/themes.js +17 -36
- package/lib/hbs2ui5/RenderTemplates/LitRenderer.js +12 -7
- package/lib/hbs2ui5/index.js +3 -3
- package/lib/i18n/defaults.js +3 -2
- package/lib/remove-dev-mode/remove-dev-mode.mjs +37 -0
- package/lib/scoping/get-all-tags.js +9 -2
- package/lib/scoping/lint-src.js +8 -7
- package/package.json +9 -8
- package/tsconfig.json +18 -0
- package/components-package/wdio.sync.js +0 -368
- package/lib/create-new-component/jsFileContentTemplate.js +0 -73
- package/lib/css-processors/css-processor-component-styles.mjs +0 -47
- package/lib/generate-custom-elements-manifest/index.js +0 -271
- package/lib/jsdoc/config.json +0 -29
- package/lib/jsdoc/configTypescript.json +0 -29
- package/lib/jsdoc/plugin.js +0 -2468
- package/lib/jsdoc/preprocess.js +0 -146
- package/lib/jsdoc/template/publish.js +0 -4120
package/lib/cem/utils.mjs
CHANGED
|
@@ -3,6 +3,8 @@ import path from "path";
|
|
|
3
3
|
|
|
4
4
|
let documentationErrors = new Map();
|
|
5
5
|
|
|
6
|
+
const packageRegex = /^((@([a-z0-9._-]+)\/)?([a-z0-9._-]+))/;
|
|
7
|
+
|
|
6
8
|
const getDeprecatedStatus = (jsdocComment) => {
|
|
7
9
|
const deprecatedTag = findTag(jsdocComment, "deprecated");
|
|
8
10
|
return deprecatedTag?.name
|
|
@@ -14,12 +16,23 @@ const getDeprecatedStatus = (jsdocComment) => {
|
|
|
14
16
|
: undefined;
|
|
15
17
|
};
|
|
16
18
|
|
|
19
|
+
const getExperimentalStatus = (jsdocComment) => {
|
|
20
|
+
const experimentalTag = findTag(jsdocComment, "experimental");
|
|
21
|
+
return experimentalTag?.name
|
|
22
|
+
? experimentalTag.description
|
|
23
|
+
? `${experimentalTag.name} ${experimentalTag.description}`
|
|
24
|
+
: experimentalTag.name
|
|
25
|
+
: experimentalTag
|
|
26
|
+
? true
|
|
27
|
+
: undefined;
|
|
28
|
+
};
|
|
29
|
+
|
|
17
30
|
const toKebabCase = str => {
|
|
18
31
|
return str.replaceAll(/[A-Z]+(?![a-z])|[A-Z]/g, ($, ofs) => (ofs ? "-" : "") + $.toLowerCase())
|
|
19
32
|
}
|
|
20
33
|
|
|
21
34
|
const normalizeDescription = (description) => {
|
|
22
|
-
|
|
35
|
+
return typeof description === 'string' ? description.replaceAll(/^-\s+|^(\n)+|(\n)+$/g, "") : description;
|
|
23
36
|
}
|
|
24
37
|
|
|
25
38
|
const getTypeRefs = (ts, node, member) => {
|
|
@@ -100,10 +113,22 @@ const findPackageName = (ts, sourceFile, typeName) => {
|
|
|
100
113
|
if (currentModuleSpecifier?.text?.startsWith(".")) {
|
|
101
114
|
return packageJSON?.name;
|
|
102
115
|
} else {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
116
|
+
// my-package/test
|
|
117
|
+
// my-package
|
|
118
|
+
// @scope/my-package
|
|
119
|
+
// my.package
|
|
120
|
+
// _mypackage
|
|
121
|
+
// mypackage-
|
|
122
|
+
// scope/my-package/test
|
|
123
|
+
// @scope/my-package/test
|
|
124
|
+
const match = currentModuleSpecifier?.text.match(packageRegex);
|
|
125
|
+
let packageName;
|
|
126
|
+
|
|
127
|
+
if (match) {
|
|
128
|
+
packageName = match[1];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return packageName || undefined;
|
|
107
132
|
}
|
|
108
133
|
}
|
|
109
134
|
};
|
|
@@ -145,23 +170,24 @@ const findImportPath = (ts, sourceFile, typeName, modulePath) => {
|
|
|
145
170
|
?.replace("src", "dist")?.replace(".ts", ".js") || undefined
|
|
146
171
|
);
|
|
147
172
|
} else {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
173
|
+
let packageName = currentModuleSpecifier?.text?.replace(packageRegex, "") || undefined;
|
|
174
|
+
|
|
175
|
+
if (packageName?.startsWith("/")) {
|
|
176
|
+
packageName = packageName.replace("/", "");
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return packageName;
|
|
154
180
|
}
|
|
155
181
|
}
|
|
156
182
|
};
|
|
157
183
|
|
|
158
184
|
|
|
159
185
|
const isClass = text => {
|
|
160
|
-
|
|
186
|
+
return text.includes("@abstract") || text.includes("@class") || text.includes("@constructor");
|
|
161
187
|
};
|
|
162
188
|
|
|
163
189
|
const normalizeTagType = (type) => {
|
|
164
|
-
|
|
190
|
+
return type?.trim();
|
|
165
191
|
}
|
|
166
192
|
|
|
167
193
|
const packageJSON = JSON.parse(fs.readFileSync("./package.json"));
|
|
@@ -211,13 +237,13 @@ const commonTags = ["public", "protected", "private", "since", "deprecated"];
|
|
|
211
237
|
const allowedTags = {
|
|
212
238
|
field: [...commonTags, "formEvents", "formProperty", "default"],
|
|
213
239
|
slot: [...commonTags, "default"],
|
|
214
|
-
event: [...commonTags, "param", "
|
|
240
|
+
event: [...commonTags, "param", "native", "allowPreventDefault"],
|
|
215
241
|
eventParam: [...commonTags],
|
|
216
242
|
method: [...commonTags, "param", "returns", "override"],
|
|
217
|
-
class: [...commonTags, "constructor", "class", "abstract", "implements", "extends", "slot", "csspart"],
|
|
218
|
-
enum: [...commonTags],
|
|
219
|
-
enumMember: [...commonTags],
|
|
220
|
-
interface: [...commonTags],
|
|
243
|
+
class: [...commonTags, "constructor", "class", "abstract", "experimental", "implements", "extends", "slot", "csspart"],
|
|
244
|
+
enum: [...commonTags, "experimental",],
|
|
245
|
+
enumMember: [...commonTags, "experimental",],
|
|
246
|
+
interface: [...commonTags, "experimental",],
|
|
221
247
|
};
|
|
222
248
|
allowedTags.getter = [...allowedTags.field, "override"]
|
|
223
249
|
|
|
@@ -230,19 +256,29 @@ const tagMatchCallback = (tag, tagName) => {
|
|
|
230
256
|
};
|
|
231
257
|
|
|
232
258
|
const findDecorator = (node, decoratorName) => {
|
|
233
|
-
return node?.decorators?.find(
|
|
259
|
+
return (node?.modifiers || node?.decorators)?.find(
|
|
234
260
|
(decorator) =>
|
|
235
261
|
decorator?.expression?.expression?.text === decoratorName
|
|
236
262
|
);
|
|
237
263
|
};
|
|
238
264
|
|
|
239
265
|
const findAllDecorators = (node, decoratorName) => {
|
|
240
|
-
|
|
241
|
-
node?.decorators?.filter(
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
266
|
+
if (typeof decoratorName === "string") {
|
|
267
|
+
return (node?.modifiers || node?.decorators)?.filter(decorator => decorator?.expression?.expression?.text === decoratorName) || [];
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (Array.isArray(decoratorName)) {
|
|
271
|
+
return (node?.modifiers || node?.decorators)?.filter(decorator => {
|
|
272
|
+
if (decorator?.expression?.expression?.text) {
|
|
273
|
+
return decoratorName.includes(decorator.expression.expression.text);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
278
|
+
) || [];
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return [];
|
|
246
282
|
};
|
|
247
283
|
|
|
248
284
|
const hasTag = (jsDoc, tagName) => {
|
|
@@ -272,7 +308,7 @@ const findAllTags = (jsDoc, tagName) => {
|
|
|
272
308
|
};
|
|
273
309
|
|
|
274
310
|
const validateJSDocTag = (tag) => {
|
|
275
|
-
const booleanTags = ["private", "protected", "public", "abstract", "
|
|
311
|
+
const booleanTags = ["private", "protected", "public", "abstract", "native", "allowPreventDefault", "formProperty", "constructor", "override"];
|
|
276
312
|
let tagName = tag.tag;
|
|
277
313
|
|
|
278
314
|
if (booleanTags.includes(tag.tag)) {
|
|
@@ -284,6 +320,8 @@ const validateJSDocTag = (tag) => {
|
|
|
284
320
|
return !tag.name && !tag.type && !tag.description;
|
|
285
321
|
case "deprecated":
|
|
286
322
|
return !tag.type;
|
|
323
|
+
case "experimental":
|
|
324
|
+
return !tag.type;
|
|
287
325
|
case "extends":
|
|
288
326
|
return !tag.type && tag.name && !tag.description;
|
|
289
327
|
case "implements":
|
|
@@ -316,7 +354,7 @@ const validateJSDocComment = (fieldType, jsdocComment, node, moduleDoc) => {
|
|
|
316
354
|
let isValid = false
|
|
317
355
|
|
|
318
356
|
if (fieldType === "event" && tag?.tag === "param") {
|
|
319
|
-
isValid = allowedTags[fieldType]?.includes(tag.tag) && validateJSDocTag({...tag, tag: "eventparam"});
|
|
357
|
+
isValid = allowedTags[fieldType]?.includes(tag.tag) && validateJSDocTag({ ...tag, tag: "eventparam" });
|
|
320
358
|
} else {
|
|
321
359
|
isValid = allowedTags[fieldType]?.includes(tag.tag) && validateJSDocTag(tag);
|
|
322
360
|
}
|
|
@@ -345,26 +383,27 @@ const displayDocumentationErrors = () => {
|
|
|
345
383
|
[...documentationErrors.keys()].forEach(modulePath => {
|
|
346
384
|
const moduleErrors = documentationErrors.get(modulePath);
|
|
347
385
|
|
|
348
|
-
console.log(`=== ERROR: ${moduleErrors.length > 1 ? `${moduleErrors.length} problems` :
|
|
386
|
+
console.log(`=== ERROR: ${moduleErrors.length > 1 ? `${moduleErrors.length} problems` : "Problem"} found in file: ${modulePath}:`)
|
|
349
387
|
moduleErrors.forEach(moduleError => {
|
|
350
388
|
errorsCount++;
|
|
351
389
|
console.log(`\t- ${moduleError}`)
|
|
352
390
|
})
|
|
353
391
|
})
|
|
354
392
|
|
|
355
|
-
if(errorsCount) {
|
|
393
|
+
if (errorsCount) {
|
|
356
394
|
throw new Error(`Found ${errorsCount} errors in the description of the public API.`);
|
|
357
395
|
}
|
|
358
396
|
}
|
|
359
397
|
|
|
360
398
|
const formatArrays = (typeText) => {
|
|
361
|
-
|
|
399
|
+
return typeText?.replaceAll(/(\S+)\[\]/g, "Array<$1>")
|
|
362
400
|
}
|
|
363
401
|
|
|
364
402
|
export {
|
|
365
403
|
getPrivacyStatus,
|
|
366
404
|
getSinceStatus,
|
|
367
405
|
getDeprecatedStatus,
|
|
406
|
+
getExperimentalStatus,
|
|
368
407
|
getType,
|
|
369
408
|
getReference,
|
|
370
409
|
validateJSDocComment,
|
package/lib/cem/validate.js
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const Ajv = require('ajv');
|
|
3
3
|
const path = require('path');
|
|
4
|
-
const yargs = require('yargs/yargs')
|
|
5
|
-
const { hideBin } = require('yargs/helpers')
|
|
6
|
-
const argv = yargs(hideBin(process.argv))
|
|
7
|
-
.argv;
|
|
8
|
-
|
|
9
4
|
// Load your JSON schema
|
|
10
5
|
const extenalSchema = require('./schema.json');
|
|
11
6
|
const internalSchema = require('./schema-internal.json');
|
|
@@ -14,47 +9,49 @@ const internalSchema = require('./schema-internal.json');
|
|
|
14
9
|
const inputFilePath = path.join(process.cwd(), "dist/custom-elements.json"); // Update with your file path
|
|
15
10
|
const customManifest = fs.readFileSync(inputFilePath, 'utf8');
|
|
16
11
|
const inputDataInternal = JSON.parse(customManifest);
|
|
12
|
+
const devMode = process.env.UI5_CEM_MODE === "dev";
|
|
17
13
|
|
|
18
14
|
inputDataInternal.modules.forEach(moduleDoc => {
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
moduleDoc.exports = moduleDoc.exports.
|
|
16
|
+
filter(e => moduleDoc.declarations.find(d => d.name === e.declaration.name && ["class", "function", "variable", "enum"].includes(d.kind)) || e.name === "default");
|
|
21
17
|
})
|
|
22
18
|
|
|
23
19
|
const clearProps = (data) => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
20
|
+
if (Array.isArray(data)) {
|
|
21
|
+
for (let i = 0; i < data.length; i++) {
|
|
22
|
+
if (typeof data[i] === "object") {
|
|
23
|
+
if (["enum", "interface"].includes(data[i].kind)) {
|
|
24
|
+
data.splice(i, 1);
|
|
25
|
+
i--;
|
|
26
|
+
} else {
|
|
27
|
+
clearProps(data[i]);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
} else if (typeof data === "object") {
|
|
32
|
+
Object.keys(data).forEach(prop => {
|
|
33
|
+
if (prop.startsWith("_ui5")) {
|
|
34
|
+
delete data[prop];
|
|
35
|
+
} else if (typeof data[prop] === "object") {
|
|
36
|
+
clearProps(data[prop]);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
44
40
|
|
|
45
|
-
|
|
41
|
+
return data;
|
|
46
42
|
}
|
|
47
43
|
|
|
48
44
|
const ajv = new Ajv({ allowUnionTypes: true, allError: true })
|
|
49
45
|
let validate = ajv.compile(internalSchema)
|
|
50
46
|
|
|
51
47
|
// Validate the JSON data against the schema
|
|
52
|
-
if (
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
48
|
+
if (devMode) {
|
|
49
|
+
if (validate(inputDataInternal)) {
|
|
50
|
+
console.log('Internal custom element manifest is validated successfully');
|
|
51
|
+
} else {
|
|
52
|
+
console.log(validate.errors)
|
|
53
|
+
throw new Error(`Validation of internal custom elements manifest failed: ${validate.errors}`);
|
|
54
|
+
}
|
|
58
55
|
}
|
|
59
56
|
|
|
60
57
|
const inputDataExternal = clearProps(JSON.parse(JSON.stringify(inputDataInternal)));
|
|
@@ -62,9 +59,9 @@ validate = ajv.compile(extenalSchema)
|
|
|
62
59
|
|
|
63
60
|
// Validate the JSON data against the schema
|
|
64
61
|
if (validate(inputDataExternal)) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
} else if (
|
|
69
|
-
|
|
70
|
-
|
|
62
|
+
console.log('Custom element manifest is validated successfully');
|
|
63
|
+
fs.writeFileSync(inputFilePath, JSON.stringify(inputDataExternal, null, 2), 'utf8');
|
|
64
|
+
fs.writeFileSync(inputFilePath.replace("custom-elements", "custom-elements-internal"), JSON.stringify(inputDataInternal, null, 2), 'utf8');
|
|
65
|
+
} else if (devMode) {
|
|
66
|
+
throw new Error(`Validation of public custom elements manifest failed: ${validate.errors}`);
|
|
67
|
+
}
|
|
@@ -21,8 +21,8 @@ export default "${collection}/${name}";
|
|
|
21
21
|
export { pathData, ltr, accData };`;
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
const iconAccTemplate = (name, pathData, ltr, accData, collection, packageName) => `import { registerIcon } from "@ui5/webcomponents-base/dist/asset-registries/Icons.js";
|
|
25
|
-
import { ${accData.key} } from "../generated/i18n/i18n-defaults.js";
|
|
24
|
+
const iconAccTemplate = (name, pathData, ltr, accData, collection, packageName, versioned) => `import { registerIcon } from "@ui5/webcomponents-base/dist/asset-registries/Icons.js";
|
|
25
|
+
import { ${accData.key} } from "${versioned ? "../" : "./"}generated/i18n/i18n-defaults.js";
|
|
26
26
|
|
|
27
27
|
const name = "${name}";
|
|
28
28
|
const pathData = "${pathData}";
|
|
@@ -38,14 +38,16 @@ export { pathData, ltr, accData };`;
|
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
const collectionTemplate = (name, versions, fullName) => `import {
|
|
41
|
+
const collectionTemplate = (name, versions, fullName) => `import { isLegacyThemeFamilyAsync } from "@ui5/webcomponents-base/dist/config/Theme.js";
|
|
42
42
|
import { pathData as pathData${versions[0]}, ltr, accData } from "./${versions[0]}/${name}.js";
|
|
43
43
|
import { pathData as pathData${versions[1]} } from "./${versions[1]}/${name}.js";
|
|
44
44
|
|
|
45
|
-
const
|
|
45
|
+
const getPathData = async() => {
|
|
46
|
+
return await isLegacyThemeFamilyAsync() ? pathDatav4 : pathDatav5;
|
|
47
|
+
};
|
|
46
48
|
|
|
47
49
|
export default "${fullName}";
|
|
48
|
-
export {
|
|
50
|
+
export { getPathData, ltr, accData };`;
|
|
49
51
|
|
|
50
52
|
|
|
51
53
|
const typeDefinitionTemplate = (name, accData, collection) => `declare const pathData: string;
|
|
@@ -56,13 +58,13 @@ declare const _default: "${collection}/${name}";
|
|
|
56
58
|
export default _default;
|
|
57
59
|
export { pathData, ltr, accData };`
|
|
58
60
|
|
|
59
|
-
const collectionTypeDefinitionTemplate = (name, accData) => `declare const
|
|
61
|
+
const collectionTypeDefinitionTemplate = (name, accData) => `declare const getPathData: () => Promise<string>;
|
|
60
62
|
declare const ltr: boolean;
|
|
61
63
|
declare const accData: ${accData ? '{ key: string; defaultText: string; }' : null}
|
|
62
64
|
declare const _default: "${name}";
|
|
63
65
|
|
|
64
66
|
export default _default;
|
|
65
|
-
export {
|
|
67
|
+
export { getPathData, ltr, accData };`
|
|
66
68
|
|
|
67
69
|
|
|
68
70
|
const svgTemplate = (pathData) => `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
|
@@ -82,8 +84,9 @@ const createIcons = async (file) => {
|
|
|
82
84
|
const acc = iconData.acc;
|
|
83
85
|
const packageName = json.packageName;
|
|
84
86
|
const collection = json.collection;
|
|
87
|
+
const versioned = json.version;
|
|
85
88
|
|
|
86
|
-
const content = acc ? iconAccTemplate(name, pathData, ltr, acc, collection, packageName) : iconTemplate(name, pathData, ltr, collection, packageName);
|
|
89
|
+
const content = acc ? iconAccTemplate(name, pathData, ltr, acc, collection, packageName, versioned) : iconTemplate(name, pathData, ltr, collection, packageName);
|
|
87
90
|
|
|
88
91
|
promises.push(fs.writeFile(path.join(destDir, `${name}.js`), content));
|
|
89
92
|
promises.push(fs.writeFile(path.join(destDir, `${name}.svg`), svgTemplate(pathData)));
|
|
@@ -91,10 +94,10 @@ const createIcons = async (file) => {
|
|
|
91
94
|
|
|
92
95
|
// For versioned icons collections, the script creates top level (unversioned) module that internally imports the versioned ones.
|
|
93
96
|
// For example, the top level "@ui5/ui5-webcomponents-icons/dist/accept.js" imports:
|
|
94
|
-
// - "@ui5/ui5-webcomponents-icons/dist/v5/accept.js"
|
|
97
|
+
// - "@ui5/ui5-webcomponents-icons/dist/v5/accept.js"
|
|
95
98
|
// - "@ui5/ui5-webcomponents-icons/dist/v4/accept.js"
|
|
96
99
|
|
|
97
|
-
if (
|
|
100
|
+
if (versioned) {
|
|
98
101
|
// The exported value from the top level (unversioned) icon module depends on whether the collection is the default,
|
|
99
102
|
// to add or not the collection name to the exported value:
|
|
100
103
|
// For the default collection (SAPIcons) we export just the icon name - "export default { 'accept' }"
|
|
@@ -20,7 +20,15 @@ const generate = async () => {
|
|
|
20
20
|
SuccessScreen: "SuccessScreen",
|
|
21
21
|
NoMail: "NoMail",
|
|
22
22
|
NoSavedItems: "NoSavedItems",
|
|
23
|
-
NoTasks: "NoTasks"
|
|
23
|
+
NoTasks: "NoTasks",
|
|
24
|
+
NoDimensionsSet: "NoDimensionsSet",
|
|
25
|
+
AddPeople: "AddPeople",
|
|
26
|
+
AddColumn: "AddColumn",
|
|
27
|
+
SortColumn: "SortColumn",
|
|
28
|
+
FilterTable: "FilterTable",
|
|
29
|
+
ResizeColumn: "ResizeColumn",
|
|
30
|
+
GroupTable: "GroupTable",
|
|
31
|
+
UploadCollection: "UploadCollection"
|
|
24
32
|
};
|
|
25
33
|
|
|
26
34
|
const FALLBACK_TEXTS = {
|
|
@@ -47,6 +55,16 @@ const generate = async () => {
|
|
|
47
55
|
SimpleNotFoundMagnifier: ORIGINAL_TEXTS.NoSearchResults,
|
|
48
56
|
SimpleReload: ORIGINAL_TEXTS.UnableToLoad,
|
|
49
57
|
SimpleTask: ORIGINAL_TEXTS.NoTasks,
|
|
58
|
+
NoChartData: ORIGINAL_TEXTS.NoDimensionsSet,
|
|
59
|
+
AddingColumns: ORIGINAL_TEXTS.AddColumn,
|
|
60
|
+
SortingColumns: ORIGINAL_TEXTS.SortColumn,
|
|
61
|
+
FilteringColumns: ORIGINAL_TEXTS.FilterTable,
|
|
62
|
+
ResizingColumns: ORIGINAL_TEXTS.ResizeColumn,
|
|
63
|
+
GroupingColumns: ORIGINAL_TEXTS.GroupTable,
|
|
64
|
+
AddPeopleToCalendar: ORIGINAL_TEXTS.AddPeople,
|
|
65
|
+
DragFilesToUpload: ORIGINAL_TEXTS.UploadCollection,
|
|
66
|
+
KeyTask: ORIGINAL_TEXTS.SuccessScreen,
|
|
67
|
+
ReceiveAppreciation: ORIGINAL_TEXTS.BalloonSky,
|
|
50
68
|
SuccessBalloon: ORIGINAL_TEXTS.BalloonSky,
|
|
51
69
|
SuccessCheckMark: ORIGINAL_TEXTS.SuccessScreen,
|
|
52
70
|
SuccessHighFive: ORIGINAL_TEXTS.BalloonSky
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
const
|
|
1
|
+
const Component = (componentName, tagName, library, packageName) => {
|
|
2
2
|
return `import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js";
|
|
3
3
|
import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js";
|
|
4
4
|
import property from "@ui5/webcomponents-base/dist/decorators/property.js";
|
|
5
5
|
import slot from "@ui5/webcomponents-base/dist/decorators/slot.js";
|
|
6
|
-
import event from "@ui5/webcomponents-base/dist/decorators/event.js";
|
|
7
|
-
import
|
|
6
|
+
import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js";
|
|
7
|
+
import jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js";
|
|
8
8
|
|
|
9
|
-
import ${componentName}Template from "
|
|
9
|
+
import ${componentName}Template from "./${componentName}Template.js";
|
|
10
10
|
|
|
11
11
|
// Styles
|
|
12
12
|
import ${componentName}Css from "./generated/themes/${componentName}.css.js";
|
|
@@ -30,10 +30,9 @@ import ${componentName}Css from "./generated/themes/${componentName}.css.js";
|
|
|
30
30
|
*/
|
|
31
31
|
@customElement({
|
|
32
32
|
tag: "${tagName}",
|
|
33
|
-
renderer:
|
|
33
|
+
renderer: jsxRenderer,
|
|
34
34
|
styles: ${componentName}Css,
|
|
35
35
|
template: ${componentName}Template,
|
|
36
|
-
dependencies: [],
|
|
37
36
|
})
|
|
38
37
|
|
|
39
38
|
/**
|
|
@@ -42,8 +41,12 @@ import ${componentName}Css from "./generated/themes/${componentName}.css.js";
|
|
|
42
41
|
*
|
|
43
42
|
* @public
|
|
44
43
|
*/
|
|
45
|
-
@event("interact"
|
|
44
|
+
@event("interact")
|
|
46
45
|
class ${componentName} extends UI5Element {
|
|
46
|
+
eventDetails!: {
|
|
47
|
+
"interact": void,
|
|
48
|
+
};
|
|
49
|
+
|
|
47
50
|
/**
|
|
48
51
|
* Defines the value of the component.
|
|
49
52
|
*
|
|
@@ -51,7 +54,7 @@ class ${componentName} extends UI5Element {
|
|
|
51
54
|
* @public
|
|
52
55
|
*/
|
|
53
56
|
@property()
|
|
54
|
-
value
|
|
57
|
+
value?: string;
|
|
55
58
|
|
|
56
59
|
/**
|
|
57
60
|
* Defines the text of the component.
|
|
@@ -68,4 +71,4 @@ export default ${componentName};
|
|
|
68
71
|
`;
|
|
69
72
|
};
|
|
70
73
|
|
|
71
|
-
module.exports =
|
|
74
|
+
module.exports = Component;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const ComponentTemplate = (componentName) => {
|
|
2
|
+
return `import type ${componentName} from "./${componentName}.js";
|
|
3
|
+
|
|
4
|
+
export default function ${componentName}Template(this: ${componentName}) {
|
|
5
|
+
return (
|
|
6
|
+
<div>Hello World!</div>
|
|
7
|
+
);
|
|
8
|
+
}
|
|
9
|
+
`;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
module.exports = ComponentTemplate;
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
const fs = require("fs");
|
|
2
|
-
const path = require("path");
|
|
3
2
|
const prompts = require("prompts");
|
|
4
|
-
const
|
|
5
|
-
const
|
|
3
|
+
const Component = require("./Component.js");
|
|
4
|
+
const ComponentTemplate= require("./ComponentTemplate.js");
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
|
-
* Hyphanates the given PascalCase string, f.e.:
|
|
9
|
-
* Foo -> "my-foo"
|
|
10
|
-
* FooBar -> "foo-bar"
|
|
7
|
+
* Hyphanates the given PascalCase string and adds prefix, f.e.:
|
|
8
|
+
* Foo -> "my-foo"
|
|
9
|
+
* FooBar -> "my-foo-bar"
|
|
11
10
|
*/
|
|
12
11
|
const hyphaneteComponentName = (componentName) => {
|
|
13
12
|
const result = componentName.replace(/([a-z])([A-Z])/g, '$1-$2' ).toLowerCase();
|
|
14
13
|
|
|
15
|
-
return
|
|
14
|
+
return `my-${result}`;
|
|
16
15
|
};
|
|
17
16
|
|
|
18
17
|
/**
|
|
@@ -58,23 +57,17 @@ const getLibraryName = packageName => {
|
|
|
58
57
|
return packageName.substr("webcomponents-".length);
|
|
59
58
|
};
|
|
60
59
|
|
|
61
|
-
const generateFiles = (componentName, tagName, library, packageName
|
|
60
|
+
const generateFiles = (componentName, tagName, library, packageName) => {
|
|
62
61
|
componentName = capitalizeFirstLetter(componentName);
|
|
63
62
|
const filePaths = {
|
|
64
|
-
"main":
|
|
65
|
-
? `./src/${componentName}.ts`
|
|
66
|
-
: `./src/${componentName}.js`,
|
|
63
|
+
"main": `./src/${componentName}.ts`,
|
|
67
64
|
"css": `./src/themes/${componentName}.css`,
|
|
68
|
-
"template": `./src/${componentName}.
|
|
65
|
+
"template": `./src/${componentName}Template.tsx`,
|
|
69
66
|
};
|
|
70
67
|
|
|
71
|
-
|
|
72
|
-
? tsFileContentTemplate(componentName, tagName, library, packageName)
|
|
73
|
-
: jsFileContentTemplate(componentName, tagName, library, packageName);
|
|
74
|
-
|
|
75
|
-
fs.writeFileSync(filePaths.main, FileContentTemplate, { flag: "wx+" });
|
|
68
|
+
fs.writeFileSync(filePaths.main, Component(componentName, tagName, library, packageName), { flag: "wx+" });
|
|
76
69
|
fs.writeFileSync(filePaths.css, "", { flag: "wx+" });
|
|
77
|
-
fs.writeFileSync(filePaths.template,
|
|
70
|
+
fs.writeFileSync(filePaths.template, ComponentTemplate(componentName), { flag: "wx+" });
|
|
78
71
|
|
|
79
72
|
console.log(`Successfully generated ${filePaths.main}`);
|
|
80
73
|
console.log(`Successfully generated ${filePaths.css}`);
|
|
@@ -82,8 +75,8 @@ const generateFiles = (componentName, tagName, library, packageName, isTypeScrip
|
|
|
82
75
|
|
|
83
76
|
// Change the color of the output
|
|
84
77
|
console.warn('\x1b[33m%s\x1b[0m', `
|
|
85
|
-
|
|
86
|
-
|
|
78
|
+
Now, import the component in "src/bundle.esm.ts" via: import "./${componentName}.js";
|
|
79
|
+
And, add it to your HTML: <${tagName}></${tagName}>.`);
|
|
87
80
|
}
|
|
88
81
|
|
|
89
82
|
// Main function
|
|
@@ -112,10 +105,9 @@ const createWebComponent = async () => {
|
|
|
112
105
|
}
|
|
113
106
|
}
|
|
114
107
|
|
|
115
|
-
const isTypeScript = fs.existsSync(path.join(process.cwd(), "tsconfig.json"));
|
|
116
108
|
const tagName = hyphaneteComponentName(componentName);
|
|
117
109
|
|
|
118
|
-
generateFiles(componentName, tagName, library, packageName
|
|
110
|
+
generateFiles(componentName, tagName, library, packageName);
|
|
119
111
|
};
|
|
120
112
|
|
|
121
113
|
createWebComponent();
|
|
@@ -22,13 +22,14 @@ let customPlugin = {
|
|
|
22
22
|
build.onEnd(result => {
|
|
23
23
|
result.outputFiles.forEach(async f => {
|
|
24
24
|
// scoping
|
|
25
|
-
|
|
25
|
+
let newText = scopeVariables(f.text, packageJSON);
|
|
26
|
+
newText = newText.replaceAll(/\\/g, "\\\\"); // Escape backslashes as they might appear in css rules
|
|
26
27
|
await mkdir(path.dirname(f.path), {recursive: true});
|
|
27
28
|
writeFile(f.path, newText);
|
|
28
29
|
|
|
29
30
|
// JS/TS
|
|
30
31
|
const jsPath = f.path.replace(/dist[\/\\]css/, "src/generated/").replace(".css", extension);
|
|
31
|
-
const jsContent = getFileContent(
|
|
32
|
+
const jsContent = getFileContent(packageJSON.name, "\`" + newText + "\`", true);
|
|
32
33
|
writeFileIfChanged(jsPath, jsContent);
|
|
33
34
|
});
|
|
34
35
|
})
|
|
@@ -42,16 +42,11 @@ let scopingPlugin = {
|
|
|
42
42
|
// JSON
|
|
43
43
|
const jsonPath = f.path.replace(/dist[\/\\]css/, "dist/generated/assets").replace(".css", ".css.json");
|
|
44
44
|
await mkdir(path.dirname(jsonPath), {recursive: true});
|
|
45
|
-
|
|
46
|
-
packageName: packageJSON.name,
|
|
47
|
-
fileName: jsonPath.substr(jsonPath.lastIndexOf("themes")),
|
|
48
|
-
content: newText,
|
|
49
|
-
};
|
|
50
|
-
writeFileIfChanged(jsonPath, JSON.stringify({_: data}));
|
|
45
|
+
writeFileIfChanged(jsonPath, JSON.stringify(newText));
|
|
51
46
|
|
|
52
47
|
// JS/TS
|
|
53
48
|
const jsPath = f.path.replace(/dist[\/\\]css/, "src/generated/").replace(".css", extension);
|
|
54
|
-
const jsContent = getFileContent(
|
|
49
|
+
const jsContent = getFileContent(packageJSON.name, "\`" + newText + "\`");
|
|
55
50
|
writeFileIfChanged(jsPath, jsContent);
|
|
56
51
|
});
|
|
57
52
|
})
|
|
@@ -42,35 +42,15 @@ const getDefaultThemeCode = packageName => {
|
|
|
42
42
|
import defaultThemeBase from "@ui5/webcomponents-theming/dist/generated/themes/${DEFAULT_THEME}/parameters-bundle.css.js";
|
|
43
43
|
import defaultTheme from "./${DEFAULT_THEME}/parameters-bundle.css.js";
|
|
44
44
|
|
|
45
|
-
registerThemePropertiesLoader("@ui5/webcomponents-theming", "${DEFAULT_THEME}", async () => defaultThemeBase);
|
|
46
|
-
registerThemePropertiesLoader("${
|
|
45
|
+
registerThemePropertiesLoader("@" + "ui5" + "/" + "webcomponents-theming", "${DEFAULT_THEME}", async () => defaultThemeBase);
|
|
46
|
+
registerThemePropertiesLoader(${ packageName.split("").map(c => `"${c}"`).join (" + ") }, "${DEFAULT_THEME}", async () => defaultTheme);
|
|
47
47
|
`;
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
-
const getFileContent = (
|
|
51
|
-
if (tsMode) {
|
|
52
|
-
return getTSContent(targetFile, packageName, css, includeDefaultTheme);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return getJSContent(targetFile, packageName, css, includeDefaultTheme);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const getTSContent = (targetFile, packageName, css, includeDefaultTheme) => {
|
|
59
|
-
const typeImport = "import type { StyleData } from \"@ui5/webcomponents-base/dist/types.js\";"
|
|
50
|
+
const getFileContent = (packageName, css, includeDefaultTheme) => {
|
|
60
51
|
const defaultTheme = includeDefaultTheme ? getDefaultThemeCode(packageName) : "";
|
|
61
|
-
|
|
62
|
-
// tabs are intentionally mixed to have proper identation in the produced file
|
|
63
|
-
return `${typeImport}
|
|
64
|
-
${defaultTheme}
|
|
65
|
-
const styleData: StyleData = {packageName:"${packageName}",fileName:"${targetFile.substr(targetFile.lastIndexOf("themes"))}",content:${css}};
|
|
66
|
-
export default styleData;
|
|
67
|
-
`;
|
|
52
|
+
return `${defaultTheme}export default ${css.trim()}`
|
|
68
53
|
}
|
|
69
54
|
|
|
70
|
-
const getJSContent = (targetFile, packageName, css, includeDefaultTheme) => {
|
|
71
|
-
const defaultTheme = includeDefaultTheme ? getDefaultThemeCode(packageName) : "";
|
|
72
|
-
|
|
73
|
-
return `${defaultTheme}export default {packageName:"${packageName}",fileName:"${targetFile.substr(targetFile.lastIndexOf("themes"))}",content:${css}}`
|
|
74
|
-
}
|
|
75
55
|
|
|
76
56
|
export { writeFileIfChanged, stripThemingBaseContent, getFileContent}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import fs from "fs/promises";
|
|
2
|
+
import { createServer } from 'vite';
|
|
3
|
+
import yargs from 'yargs';
|
|
4
|
+
import { hideBin } from 'yargs/helpers';
|
|
5
5
|
|
|
6
6
|
const argv = yargs(hideBin(process.argv))
|
|
7
7
|
.alias("c", "config")
|