@ui5/webcomponents-tools 0.0.0-07d38e78e → 0.0.0-093de5dd1
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 +1030 -0
- package/LICENSE.txt +201 -0
- package/README.md +7 -10
- package/assets-meta.js +1 -5
- package/bin/dev.js +3 -2
- package/bin/ui5nps.js +274 -0
- package/components-package/eslint.js +59 -31
- package/components-package/nps.js +98 -75
- package/components-package/vite.config.js +7 -11
- package/components-package/wdio.js +12 -5
- package/icons-collection/nps.js +30 -21
- package/lib/amd-to-es6/index.js +15 -10
- package/lib/cem/cem.js +12 -0
- package/lib/cem/custom-elements-manifest.config.mjs +90 -45
- package/lib/cem/event.mjs +69 -32
- package/lib/cem/merge.mjs +220 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/cli.js +128 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/package.json +59 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/browser-entrypoint.js +23 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/create.js +117 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/arrow-function.js +26 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/class-jsdoc.js +157 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/classes.js +20 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createArrowFunction.js +17 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createAttribute.js +24 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createClass.js +301 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createClassField.js +26 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createFunctionLike.js +73 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createMixin.js +33 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createVariable.js +22 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/handlers.js +338 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/custom-elements-define-calls.js +90 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/exports.js +156 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/function-like.js +24 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/mixins.js +29 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/reexported-wrapped-mixin-exports.js +84 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/variables.js +34 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/collect-phase/collect-imports.js +101 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/catalyst/catalyst.js +11 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/catalyst/controller.js +34 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/catalyst-major-2/catalyst.js +11 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/catalyst-major-2/controller.js +34 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/decorators/attr.js +53 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/decorators/custom-element-decorator.js +36 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/fast/fast.js +7 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/lit.js +13 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/member-denylist.js +21 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/method-denylist.js +20 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/property-decorator.js +94 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/static-properties.js +121 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/utils.js +66 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/stencil/stencil.js +129 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/index.js +80 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/link-phase/cleanup-classes.js +25 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/link-phase/field-denylist.js +22 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/link-phase/method-denylist.js +25 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/post-processing/apply-inheritance.js +78 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/post-processing/is-custom-element.js +34 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/post-processing/link-class-to-tagname.js +27 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/post-processing/remove-unexported-declarations.js +23 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/post-processing/resolve-initializers.js +52 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/ast-helpers.js +186 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/cli-helpers.js +164 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/exports.js +44 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/find-external-manifests.js +67 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/imports.js +25 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/index.js +71 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/jsdoc.js +19 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/manifest-helpers.js +194 -0
- package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/mixins.js +112 -0
- 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 +61 -55
- package/lib/chokidar/chokidar.js +28 -0
- package/lib/copy-and-watch/index.js +105 -97
- package/lib/copy-list/index.js +16 -10
- package/lib/create-icons/index.js +24 -19
- package/lib/create-illustrations/index.js +49 -27
- 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 +13 -12
- package/lib/css-processors/css-processor-components.mjs +74 -59
- package/lib/css-processors/css-processor-themes.mjs +85 -62
- package/lib/css-processors/shared.mjs +5 -35
- package/lib/dev-server/{dev-server.js → dev-server.mjs} +26 -14
- package/lib/dev-server/virtual-index-html-plugin.js +24 -20
- package/lib/eslint/eslint.js +44 -0
- package/lib/generate-js-imports/illustrations.js +53 -54
- package/lib/generate-json-imports/i18n.js +56 -36
- package/lib/generate-json-imports/themes.js +27 -14
- package/lib/hbs2ui5/RenderTemplates/LitRenderer.js +12 -7
- package/lib/hbs2ui5/index.js +3 -3
- package/lib/i18n/defaults.js +15 -9
- package/lib/i18n/toJSON.js +38 -12
- package/lib/icons-hash/icons-hash.mjs +149 -0
- package/lib/remove-dev-mode/remove-dev-mode.mjs +38 -24
- package/lib/rimraf/rimraf.js +31 -0
- package/lib/scoping/get-all-tags.js +9 -2
- package/lib/test-runner/test-runner.js +56 -48
- package/lib/vite-bundler/vite-bundler.mjs +35 -0
- package/package.json +22 -19
- package/tsconfig.json +18 -0
- package/lib/css-processors/css-processor-component-styles.mjs +0 -48
- package/lib/dev-server/ssr-dom-shim-loader.js +0 -26
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UTILITIES RELATED TO GETTING INFORMATION OUT OF A MANIFEST OR DOC
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { has } from "./index.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {import('custom-elements-manifest/schema').Package} Package
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
function loopThroughDeclarations(manifest, predicate) {
|
|
12
|
+
manifest?.modules?.forEach(_module => {
|
|
13
|
+
_module?.declarations?.forEach(predicate);
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function loopThroughExports(manifest, predicate) {
|
|
18
|
+
manifest?.modules?.forEach(_module => {
|
|
19
|
+
_module?.exports?.forEach(predicate);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Loops through all modules' exports, and returns the kind provided by the users
|
|
25
|
+
*
|
|
26
|
+
* @example getKind('class');
|
|
27
|
+
* @example getKind('custom-element-definition');
|
|
28
|
+
*/
|
|
29
|
+
export function getAllExportsOfKind(manifest, kind) {
|
|
30
|
+
const result = [];
|
|
31
|
+
loopThroughExports(manifest, (_export) => {
|
|
32
|
+
if(_export.kind === kind) {
|
|
33
|
+
result.push(_export);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Loops through all modules' declarations, and returns the kind provided by the users
|
|
42
|
+
*
|
|
43
|
+
* @example getKind('class');
|
|
44
|
+
* @example getKind('custom-element-definition');
|
|
45
|
+
*/
|
|
46
|
+
export function getAllDeclarationsOfKind(manifest, kind) {
|
|
47
|
+
const result = [];
|
|
48
|
+
loopThroughDeclarations(manifest, (declaration) => {
|
|
49
|
+
if(declaration.kind === kind) {
|
|
50
|
+
result.push(declaration);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Gets the inheritance tree from a manifest given a className
|
|
58
|
+
* Returns an array of a classes mixins/superclasses all the way up the chain
|
|
59
|
+
*
|
|
60
|
+
* @param {Package[]} manifests
|
|
61
|
+
* @param {string} className
|
|
62
|
+
*/
|
|
63
|
+
export function getInheritanceTree(manifests, className) {
|
|
64
|
+
const tree = [];
|
|
65
|
+
const allClassLikes = new Map();
|
|
66
|
+
const _classes = [];
|
|
67
|
+
const _mixins = [];
|
|
68
|
+
|
|
69
|
+
manifests.forEach((cem) => {
|
|
70
|
+
_classes.push(...getAllDeclarationsOfKind(cem, 'class'));
|
|
71
|
+
_mixins.push(...getAllDeclarationsOfKind(cem, 'mixin'));
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
[..._mixins, ..._classes].forEach((klass) => {
|
|
75
|
+
allClassLikes.set(klass.name, klass);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
let klass = allClassLikes.get(className)
|
|
79
|
+
|
|
80
|
+
if(klass) {
|
|
81
|
+
tree.push(klass)
|
|
82
|
+
|
|
83
|
+
klass?.mixins?.forEach(mixin => {
|
|
84
|
+
let foundMixin = _mixins.find(m => m.name === mixin.name);
|
|
85
|
+
if(foundMixin) {
|
|
86
|
+
tree.push(foundMixin);
|
|
87
|
+
|
|
88
|
+
while(has(foundMixin?.mixins)) {
|
|
89
|
+
foundMixin?.mixins?.forEach(mixin => {
|
|
90
|
+
foundMixin = _mixins.find(m => m.name === mixin.name);
|
|
91
|
+
if(foundMixin) {
|
|
92
|
+
tree.push(foundMixin);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
while(allClassLikes.has(klass.superclass?.name)) {
|
|
100
|
+
const newKlass = allClassLikes.get(klass.superclass.name);
|
|
101
|
+
let allMixins = [];
|
|
102
|
+
if (klass?.mixins) {
|
|
103
|
+
allMixins = [...klass.mixins];
|
|
104
|
+
}
|
|
105
|
+
if (newKlass?.mixins) {
|
|
106
|
+
allMixins = [...allMixins, ...newKlass.mixins];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
allMixins.forEach(mixin => {
|
|
110
|
+
let foundMixin = _mixins.find(m => m.name === mixin.name);
|
|
111
|
+
if(foundMixin) {
|
|
112
|
+
tree.push(foundMixin);
|
|
113
|
+
|
|
114
|
+
while(has(foundMixin?.mixins)) {
|
|
115
|
+
foundMixin?.mixins?.forEach(mixin => {
|
|
116
|
+
foundMixin = _mixins.find(m => m.name === mixin.name);
|
|
117
|
+
if(foundMixin) {
|
|
118
|
+
tree.push(foundMixin);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
tree.push(newKlass);
|
|
126
|
+
klass = newKlass;
|
|
127
|
+
}
|
|
128
|
+
return tree;
|
|
129
|
+
}
|
|
130
|
+
return [];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* @param {Package[]} manifests
|
|
135
|
+
* @param {string} modulePath
|
|
136
|
+
*/
|
|
137
|
+
export function getModuleFromManifests(manifests, modulePath) {
|
|
138
|
+
let result = undefined;
|
|
139
|
+
|
|
140
|
+
manifests.forEach((cem) => {
|
|
141
|
+
cem?.modules?.forEach((_module) => {
|
|
142
|
+
if (_module.path === modulePath) {
|
|
143
|
+
result = _module;
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
return result;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* @param {Package[]} manifests
|
|
153
|
+
* @param {string} className
|
|
154
|
+
*/
|
|
155
|
+
export function getModuleForClassLike(manifests, className) {
|
|
156
|
+
let result = undefined;
|
|
157
|
+
|
|
158
|
+
manifests.forEach((cem) => {
|
|
159
|
+
cem?.modules?.forEach(_module => {
|
|
160
|
+
_module?.declarations?.forEach(declaration => {
|
|
161
|
+
if((declaration.kind === 'class' || declaration.kind === 'mixin') && declaration.name === className) {
|
|
162
|
+
result = _module.path;
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Given a manifest module, a class name, and a class member name, gets the
|
|
173
|
+
* manifest doc for the module's class' member.
|
|
174
|
+
*
|
|
175
|
+
* @param {Partial<import('custom-elements-manifest/schema').Module>} moduleDoc Manifest module
|
|
176
|
+
* @param {string} className Class to get member of
|
|
177
|
+
* @param {string} memberName Class member to get
|
|
178
|
+
* @param {boolean} isStatic Is it a static member?
|
|
179
|
+
* @return {import('custom-elements-manifest/schema').ClassMember|void} the requested class member
|
|
180
|
+
*/
|
|
181
|
+
export function getClassMemberDoc(moduleDoc, className, memberName, isStatic = false) {
|
|
182
|
+
/** @type {import('custom-elements-manifest/schema').ClassDeclaration} */
|
|
183
|
+
const classDoc = (moduleDoc.declarations.find(x => x.name === className));
|
|
184
|
+
|
|
185
|
+
if (!classDoc || !has(classDoc.members))
|
|
186
|
+
return;
|
|
187
|
+
|
|
188
|
+
const memberDoc = classDoc.members.find(x =>
|
|
189
|
+
x.name === memberName &&
|
|
190
|
+
(x.static ?? false) === isStatic
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
return memberDoc;
|
|
194
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
|
|
3
|
+
import { getReturnValue } from '../utils/ast-helpers.js';
|
|
4
|
+
|
|
5
|
+
export const isMixin = node => !!extractMixinNodes(node);
|
|
6
|
+
|
|
7
|
+
export function extractMixinNodes(node) {
|
|
8
|
+
if (ts.isVariableStatement(node) || ts.isFunctionDeclaration(node)) {
|
|
9
|
+
if (ts.isVariableStatement(node)) {
|
|
10
|
+
/**
|
|
11
|
+
* @example const MyMixin = klass => class MyMixin extends klass {}
|
|
12
|
+
* @example export const MyMixin = klass => class MyMixin extends klass {}
|
|
13
|
+
*/
|
|
14
|
+
const variableDeclaration = node.declarationList.declarations.find(declaration =>
|
|
15
|
+
ts.isVariableDeclaration(declaration),
|
|
16
|
+
);
|
|
17
|
+
if (variableDeclaration) {
|
|
18
|
+
const body = variableDeclaration?.initializer?.body;
|
|
19
|
+
if (body && ts.isClassExpression(body)) {
|
|
20
|
+
return {
|
|
21
|
+
mixinFunction: node,
|
|
22
|
+
mixinClass: body,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @example const MyMixin = klass => { return class MyMixin extends Klass{} }
|
|
28
|
+
*/
|
|
29
|
+
if (body && ts.isBlock(body)) {
|
|
30
|
+
const returnStatement = body.statements.find(statement => ts.isReturnStatement(statement));
|
|
31
|
+
|
|
32
|
+
if (returnStatement && returnStatement?.expression?.kind && ts.isClassExpression(returnStatement.expression)) {
|
|
33
|
+
return {
|
|
34
|
+
mixinFunction: variableDeclaration.initializer,
|
|
35
|
+
mixinClass: returnStatement.expression
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @example const MyMixin = klass => { class MyMixin extends klass {} return MyMixin;}
|
|
42
|
+
*/
|
|
43
|
+
if (body && ts.isBlock(body)) {
|
|
44
|
+
const classDeclaration = body.statements.find(statement => ts.isClassDeclaration(statement));
|
|
45
|
+
const returnStatement = body.statements.find(statement => ts.isReturnStatement(statement));
|
|
46
|
+
/** Avoid undefined === undefined */
|
|
47
|
+
if(!(classDeclaration && returnStatement))
|
|
48
|
+
return;
|
|
49
|
+
const classDeclarationName = classDeclaration.name?.getText?.();
|
|
50
|
+
const returnValue = getReturnValue(returnStatement)
|
|
51
|
+
/**
|
|
52
|
+
* If the classDeclaration inside the function body has the same name as whats being
|
|
53
|
+
* returned from the function, consider it a mixin
|
|
54
|
+
*/
|
|
55
|
+
if (classDeclarationName === returnValue) {
|
|
56
|
+
return {
|
|
57
|
+
mixinFunction: node,
|
|
58
|
+
mixinClass: classDeclaration
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @example function MyMixin(klass) { return class MyMixin extends Klass{} }
|
|
67
|
+
*/
|
|
68
|
+
if (ts.isFunctionDeclaration(node)) {
|
|
69
|
+
if (node.body && ts.isBlock(node.body)) {
|
|
70
|
+
|
|
71
|
+
const returnStatement = node.body.statements.find(statement => ts.isReturnStatement(statement));
|
|
72
|
+
|
|
73
|
+
if (returnStatement?.expression && ts.isClassExpression(returnStatement.expression)) {
|
|
74
|
+
return {
|
|
75
|
+
mixinFunction: node,
|
|
76
|
+
mixinClass: returnStatement.expression
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @example function MyMixin(klass) {class A extends klass {} return A;}
|
|
84
|
+
*/
|
|
85
|
+
if (ts.isFunctionDeclaration(node)) {
|
|
86
|
+
if (node.body && ts.isBlock(node.body)) {
|
|
87
|
+
const classDeclaration = node.body.statements.find(statement => ts.isClassDeclaration(statement));
|
|
88
|
+
const returnStatement = node.body.statements.find(statement => ts.isReturnStatement(statement));
|
|
89
|
+
|
|
90
|
+
/** Avoid undefined === undefined */
|
|
91
|
+
if(!(classDeclaration && returnStatement))
|
|
92
|
+
return;
|
|
93
|
+
|
|
94
|
+
const classDeclarationName = classDeclaration.name?.getText?.();
|
|
95
|
+
|
|
96
|
+
const returnValue = getReturnValue(returnStatement)
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* If the classDeclaration inside the function body has the same name as whats being
|
|
100
|
+
* returned from the function, consider it a mixin
|
|
101
|
+
*/
|
|
102
|
+
if (classDeclarationName === returnValue) {
|
|
103
|
+
return {
|
|
104
|
+
mixinFunction: node,
|
|
105
|
+
mixinClass: classDeclaration
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
@@ -46,6 +46,12 @@
|
|
|
46
46
|
"ClassDeclaration": {
|
|
47
47
|
"additionalProperties": false,
|
|
48
48
|
"properties": {
|
|
49
|
+
"_ui5experimental": {
|
|
50
|
+
"type": [
|
|
51
|
+
"string",
|
|
52
|
+
"boolean"
|
|
53
|
+
]
|
|
54
|
+
},
|
|
49
55
|
"_ui5package": {
|
|
50
56
|
"type": "string"
|
|
51
57
|
},
|
|
@@ -123,6 +129,12 @@
|
|
|
123
129
|
"EnumDeclaration": {
|
|
124
130
|
"additionalProperties": false,
|
|
125
131
|
"properties": {
|
|
132
|
+
"_ui5experimental": {
|
|
133
|
+
"type": [
|
|
134
|
+
"string",
|
|
135
|
+
"boolean"
|
|
136
|
+
]
|
|
137
|
+
},
|
|
126
138
|
"_ui5package": {
|
|
127
139
|
"type": "string"
|
|
128
140
|
},
|
|
@@ -187,6 +199,12 @@
|
|
|
187
199
|
"InterfaceDeclaration": {
|
|
188
200
|
"additionalProperties": false,
|
|
189
201
|
"properties": {
|
|
202
|
+
"_ui5experimental": {
|
|
203
|
+
"type": [
|
|
204
|
+
"string",
|
|
205
|
+
"boolean"
|
|
206
|
+
]
|
|
207
|
+
},
|
|
190
208
|
"_ui5package": {
|
|
191
209
|
"type": "string"
|
|
192
210
|
},
|
|
@@ -389,6 +407,9 @@
|
|
|
389
407
|
"CssCustomProperty": {
|
|
390
408
|
"additionalProperties": false,
|
|
391
409
|
"properties": {
|
|
410
|
+
"inheritedFrom": {
|
|
411
|
+
"$ref": "#/definitions/Reference"
|
|
412
|
+
},
|
|
392
413
|
"default": {
|
|
393
414
|
"type": "string"
|
|
394
415
|
},
|
|
@@ -425,6 +446,9 @@
|
|
|
425
446
|
"additionalProperties": false,
|
|
426
447
|
"description": "The description of a CSS Part",
|
|
427
448
|
"properties": {
|
|
449
|
+
"inheritedFrom": {
|
|
450
|
+
"$ref": "#/definitions/Reference"
|
|
451
|
+
},
|
|
428
452
|
"deprecated": {
|
|
429
453
|
"description": "Whether the CSS shadow part is deprecated.\nIf the value is a string, it's the reason for the deprecation.",
|
|
430
454
|
"type": [
|
|
@@ -453,6 +477,12 @@
|
|
|
453
477
|
"additionalProperties": false,
|
|
454
478
|
"description": "A description of a custom element class.\n\nCustom elements are JavaScript classes, so this extends from\n`ClassDeclaration` and adds custom-element-specific features like\nattributes, events, and slots.\n\nNote that `tagName` in this interface is optional. Tag names are not\nneccessarily part of a custom element class, but belong to the definition\n(often called the \"registration\") or the `customElements.define()` call.\n\nBecause classes and tag names can only be registered once, there's a\none-to-one relationship between classes and tag names. For ease of use,\nwe allow the tag name here.\n\nSome packages define and register custom elements in separate modules. In\nthese cases one `Module` should contain the `CustomElement` without a\ntagName, and another `Module` should contain the\n`CustomElementExport`.",
|
|
455
479
|
"properties": {
|
|
480
|
+
"_ui5experimental": {
|
|
481
|
+
"type": [
|
|
482
|
+
"string",
|
|
483
|
+
"boolean"
|
|
484
|
+
]
|
|
485
|
+
},
|
|
456
486
|
"_ui5package": {
|
|
457
487
|
"type": "string"
|
|
458
488
|
},
|
|
@@ -618,6 +648,12 @@
|
|
|
618
648
|
"additionalProperties": false,
|
|
619
649
|
"description": "A class mixin that also adds custom element related properties.",
|
|
620
650
|
"properties": {
|
|
651
|
+
"_ui5experimental": {
|
|
652
|
+
"type": [
|
|
653
|
+
"string",
|
|
654
|
+
"boolean"
|
|
655
|
+
]
|
|
656
|
+
},
|
|
621
657
|
"_ui5package": {
|
|
622
658
|
"type": "string"
|
|
623
659
|
},
|
|
@@ -788,6 +824,14 @@
|
|
|
788
824
|
"description": "Whether the parameter is optional. Undefined implies non-optional.",
|
|
789
825
|
"type": "boolean"
|
|
790
826
|
},
|
|
827
|
+
"_ui5Cancelable": {
|
|
828
|
+
"description": "Whether the event is cancelable or not.",
|
|
829
|
+
"type": "boolean"
|
|
830
|
+
},
|
|
831
|
+
"_ui5Bubbles": {
|
|
832
|
+
"description": "Whether the event bubbles or not.",
|
|
833
|
+
"type": "boolean"
|
|
834
|
+
},
|
|
791
835
|
"_ui5since": {
|
|
792
836
|
"description": "Marks when the field was introduced",
|
|
793
837
|
"type": "string"
|
|
@@ -827,6 +871,12 @@
|
|
|
827
871
|
"FunctionDeclaration": {
|
|
828
872
|
"additionalProperties": false,
|
|
829
873
|
"properties": {
|
|
874
|
+
"_ui5experimental": {
|
|
875
|
+
"type": [
|
|
876
|
+
"string",
|
|
877
|
+
"boolean"
|
|
878
|
+
]
|
|
879
|
+
},
|
|
830
880
|
"_ui5package": {
|
|
831
881
|
"type": "string"
|
|
832
882
|
},
|
|
@@ -1007,6 +1057,12 @@
|
|
|
1007
1057
|
"additionalProperties": false,
|
|
1008
1058
|
"description": "A description of a class mixin.\n\nMixins are functions which generate a new subclass of a given superclass.\nThis interfaces describes the class and custom element features that\nare added by the mixin. As such, it extends the CustomElement interface and\nClassLike interface.\n\nSince mixins are functions, it also extends the FunctionLike interface. This\nmeans a mixin is callable, and has parameters and a return type.\n\nThe return type is often hard or impossible to accurately describe in type\nsystems like TypeScript. It requires generics and an `extends` operator\nthat TypeScript lacks. Therefore it's recommended that the return type is\nleft empty. The most common form of a mixin function takes a single\nargument, so consumers of this interface should assume that the return type\nis the single argument subclassed by this declaration.\n\nA mixin should not have a superclass. If a mixins composes other mixins,\nthey should be listed in the `mixins` field.\n\nSee [this article]{@link https://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/}\nfor more information on the classmixin pattern in JavaScript.",
|
|
1009
1059
|
"properties": {
|
|
1060
|
+
"_ui5experimental": {
|
|
1061
|
+
"type": [
|
|
1062
|
+
"string",
|
|
1063
|
+
"boolean"
|
|
1064
|
+
]
|
|
1065
|
+
},
|
|
1010
1066
|
"_ui5package": {
|
|
1011
1067
|
"type": "string"
|
|
1012
1068
|
},
|
|
@@ -1172,6 +1228,9 @@
|
|
|
1172
1228
|
"Slot": {
|
|
1173
1229
|
"additionalProperties": false,
|
|
1174
1230
|
"properties": {
|
|
1231
|
+
"inheritedFrom": {
|
|
1232
|
+
"$ref": "#/definitions/Reference"
|
|
1233
|
+
},
|
|
1175
1234
|
"_ui5propertyName": {
|
|
1176
1235
|
"type": "string"
|
|
1177
1236
|
},
|
|
@@ -1275,6 +1334,12 @@
|
|
|
1275
1334
|
"VariableDeclaration": {
|
|
1276
1335
|
"additionalProperties": false,
|
|
1277
1336
|
"properties": {
|
|
1337
|
+
"_ui5experimental": {
|
|
1338
|
+
"type": [
|
|
1339
|
+
"string",
|
|
1340
|
+
"boolean"
|
|
1341
|
+
]
|
|
1342
|
+
},
|
|
1278
1343
|
"_ui5package": {
|
|
1279
1344
|
"type": "string"
|
|
1280
1345
|
},
|
|
@@ -319,9 +319,20 @@ export interface Event {
|
|
|
319
319
|
_ui5parameters?: Parameter[]
|
|
320
320
|
_ui5privacy?: Privacy
|
|
321
321
|
/**
|
|
322
|
-
* Whether the
|
|
322
|
+
* Whether the event is preventable.
|
|
323
|
+
*/
|
|
324
|
+
_ui5allowPreventDefault?: boolean;
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Whether the event is cancelable.
|
|
323
328
|
*/
|
|
324
|
-
|
|
329
|
+
_ui5Cancelable?: boolean;
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Whether the event is bubbles.
|
|
333
|
+
*/
|
|
334
|
+
_ui5Bubbles?: boolean;
|
|
335
|
+
|
|
325
336
|
/**
|
|
326
337
|
* Marks when the field was introduced
|
|
327
338
|
*/
|
|
@@ -484,6 +495,7 @@ export interface TypeReference extends Reference {
|
|
|
484
495
|
* The common interface of classes and mixins.
|
|
485
496
|
*/
|
|
486
497
|
export interface ClassLike {
|
|
498
|
+
_ui5experimental?: boolean | string
|
|
487
499
|
_ui5implements?: Reference[]
|
|
488
500
|
_ui5privacy?: Privacy
|
|
489
501
|
/**
|
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,
|