@ui5/webcomponents-tools 0.0.0-9261ac932 → 0.0.0-95afb1087
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 +737 -0
- package/LICENSE.txt +201 -0
- package/README.md +7 -7
- package/assets-meta.js +1 -5
- package/bin/dev.js +3 -2
- package/bin/ui5nps.js +265 -0
- package/components-package/eslint.js +29 -39
- package/components-package/nps.js +98 -75
- package/components-package/vite.config.js +7 -11
- package/components-package/wdio.js +9 -3
- 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 +58 -39
- package/lib/cem/event.mjs +51 -31
- 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 +9 -0
- package/lib/cem/utils.mjs +50 -25
- package/lib/cem/validate.js +61 -55
- package/lib/chokidar/chokidar.js +29 -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 +51 -28
- package/lib/create-new-component/{tsFileContentTemplate.js → Component.js} +11 -8
- package/lib/create-new-component/ComponentTemplate.js +12 -0
- package/lib/create-new-component/index.js +13 -10
- package/lib/css-processors/css-processor-components.mjs +75 -60
- package/lib/css-processors/css-processor-themes.mjs +101 -62
- package/lib/css-processors/scope-variables.mjs +17 -9
- package/lib/css-processors/shared.mjs +5 -35
- package/lib/dev-server/dev-server.mjs +24 -12
- 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 +20 -11
- package/lib/generate-json-imports/themes.js +20 -12
- package/lib/hbs2ui5/RenderTemplates/LitRenderer.js +8 -3
- package/lib/i18n/defaults.js +12 -7
- package/lib/i18n/toJSON.js +15 -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/test-runner/test-runner.js +56 -48
- package/lib/vite-bundler/vite-bundler.mjs +35 -0
- package/package.json +19 -22
- package/tsconfig.json +2 -0
- package/components-package/cypress/support/commands.js +0 -39
- package/components-package/cypress/support/component-index.html +0 -17
- package/components-package/cypress/support/component.d.ts +0 -23
- package/components-package/cypress/support/component.js +0 -34
- package/components-package/cypress.config.js +0 -19
- package/types/index.d.ts +0 -1
|
@@ -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
|
+
}
|
|
@@ -407,6 +407,9 @@
|
|
|
407
407
|
"CssCustomProperty": {
|
|
408
408
|
"additionalProperties": false,
|
|
409
409
|
"properties": {
|
|
410
|
+
"inheritedFrom": {
|
|
411
|
+
"$ref": "#/definitions/Reference"
|
|
412
|
+
},
|
|
410
413
|
"default": {
|
|
411
414
|
"type": "string"
|
|
412
415
|
},
|
|
@@ -443,6 +446,9 @@
|
|
|
443
446
|
"additionalProperties": false,
|
|
444
447
|
"description": "The description of a CSS Part",
|
|
445
448
|
"properties": {
|
|
449
|
+
"inheritedFrom": {
|
|
450
|
+
"$ref": "#/definitions/Reference"
|
|
451
|
+
},
|
|
446
452
|
"deprecated": {
|
|
447
453
|
"description": "Whether the CSS shadow part is deprecated.\nIf the value is a string, it's the reason for the deprecation.",
|
|
448
454
|
"type": [
|
|
@@ -1222,6 +1228,9 @@
|
|
|
1222
1228
|
"Slot": {
|
|
1223
1229
|
"additionalProperties": false,
|
|
1224
1230
|
"properties": {
|
|
1231
|
+
"inheritedFrom": {
|
|
1232
|
+
"$ref": "#/definitions/Reference"
|
|
1233
|
+
},
|
|
1225
1234
|
"_ui5propertyName": {
|
|
1226
1235
|
"type": "string"
|
|
1227
1236
|
},
|
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
|
|
@@ -30,7 +32,7 @@ const toKebabCase = str => {
|
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
const normalizeDescription = (description) => {
|
|
33
|
-
|
|
35
|
+
return typeof description === 'string' ? description.replaceAll(/^-\s+|^(\n)+|(\n)+$/g, "") : description;
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
const getTypeRefs = (ts, node, member) => {
|
|
@@ -111,10 +113,22 @@ const findPackageName = (ts, sourceFile, typeName) => {
|
|
|
111
113
|
if (currentModuleSpecifier?.text?.startsWith(".")) {
|
|
112
114
|
return packageJSON?.name;
|
|
113
115
|
} else {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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;
|
|
118
132
|
}
|
|
119
133
|
}
|
|
120
134
|
};
|
|
@@ -156,23 +170,24 @@ const findImportPath = (ts, sourceFile, typeName, modulePath) => {
|
|
|
156
170
|
?.replace("src", "dist")?.replace(".ts", ".js") || undefined
|
|
157
171
|
);
|
|
158
172
|
} else {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
173
|
+
let packageName = currentModuleSpecifier?.text?.replace(packageRegex, "") || undefined;
|
|
174
|
+
|
|
175
|
+
if (packageName?.startsWith("/")) {
|
|
176
|
+
packageName = packageName.replace("/", "");
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return packageName;
|
|
165
180
|
}
|
|
166
181
|
}
|
|
167
182
|
};
|
|
168
183
|
|
|
169
184
|
|
|
170
185
|
const isClass = text => {
|
|
171
|
-
|
|
186
|
+
return text.includes("@abstract") || text.includes("@class") || text.includes("@constructor");
|
|
172
187
|
};
|
|
173
188
|
|
|
174
189
|
const normalizeTagType = (type) => {
|
|
175
|
-
|
|
190
|
+
return type?.trim();
|
|
176
191
|
}
|
|
177
192
|
|
|
178
193
|
const packageJSON = JSON.parse(fs.readFileSync("./package.json"));
|
|
@@ -226,7 +241,7 @@ const allowedTags = {
|
|
|
226
241
|
eventParam: [...commonTags],
|
|
227
242
|
method: [...commonTags, "param", "returns", "override"],
|
|
228
243
|
class: [...commonTags, "constructor", "class", "abstract", "experimental", "implements", "extends", "slot", "csspart"],
|
|
229
|
-
enum: [...commonTags],
|
|
244
|
+
enum: [...commonTags, "experimental",],
|
|
230
245
|
enumMember: [...commonTags, "experimental",],
|
|
231
246
|
interface: [...commonTags, "experimental",],
|
|
232
247
|
};
|
|
@@ -241,19 +256,29 @@ const tagMatchCallback = (tag, tagName) => {
|
|
|
241
256
|
};
|
|
242
257
|
|
|
243
258
|
const findDecorator = (node, decoratorName) => {
|
|
244
|
-
return node?.decorators?.find(
|
|
259
|
+
return (node?.modifiers || node?.decorators)?.find(
|
|
245
260
|
(decorator) =>
|
|
246
261
|
decorator?.expression?.expression?.text === decoratorName
|
|
247
262
|
);
|
|
248
263
|
};
|
|
249
264
|
|
|
250
265
|
const findAllDecorators = (node, decoratorName) => {
|
|
251
|
-
|
|
252
|
-
node?.decorators?.filter(
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
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 [];
|
|
257
282
|
};
|
|
258
283
|
|
|
259
284
|
const hasTag = (jsDoc, tagName) => {
|
|
@@ -329,7 +354,7 @@ const validateJSDocComment = (fieldType, jsdocComment, node, moduleDoc) => {
|
|
|
329
354
|
let isValid = false
|
|
330
355
|
|
|
331
356
|
if (fieldType === "event" && tag?.tag === "param") {
|
|
332
|
-
isValid = allowedTags[fieldType]?.includes(tag.tag) && validateJSDocTag({...tag, tag: "eventparam"});
|
|
357
|
+
isValid = allowedTags[fieldType]?.includes(tag.tag) && validateJSDocTag({ ...tag, tag: "eventparam" });
|
|
333
358
|
} else {
|
|
334
359
|
isValid = allowedTags[fieldType]?.includes(tag.tag) && validateJSDocTag(tag);
|
|
335
360
|
}
|
|
@@ -358,20 +383,20 @@ const displayDocumentationErrors = () => {
|
|
|
358
383
|
[...documentationErrors.keys()].forEach(modulePath => {
|
|
359
384
|
const moduleErrors = documentationErrors.get(modulePath);
|
|
360
385
|
|
|
361
|
-
console.log(`=== ERROR: ${moduleErrors.length > 1 ? `${moduleErrors.length} problems` :
|
|
386
|
+
console.log(`=== ERROR: ${moduleErrors.length > 1 ? `${moduleErrors.length} problems` : "Problem"} found in file: ${modulePath}:`)
|
|
362
387
|
moduleErrors.forEach(moduleError => {
|
|
363
388
|
errorsCount++;
|
|
364
389
|
console.log(`\t- ${moduleError}`)
|
|
365
390
|
})
|
|
366
391
|
})
|
|
367
392
|
|
|
368
|
-
if(errorsCount) {
|
|
393
|
+
if (errorsCount) {
|
|
369
394
|
throw new Error(`Found ${errorsCount} errors in the description of the public API.`);
|
|
370
395
|
}
|
|
371
396
|
}
|
|
372
397
|
|
|
373
398
|
const formatArrays = (typeText) => {
|
|
374
|
-
|
|
399
|
+
return typeText?.replaceAll(/(\S+)\[\]/g, "Array<$1>")
|
|
375
400
|
}
|
|
376
401
|
|
|
377
402
|
export {
|
package/lib/cem/validate.js
CHANGED
|
@@ -1,70 +1,76 @@
|
|
|
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');
|
|
12
7
|
|
|
13
|
-
// Load your JSON data from the input file
|
|
14
|
-
const inputFilePath = path.join(process.cwd(), "dist/custom-elements.json"); // Update with your file path
|
|
15
|
-
const customManifest = fs.readFileSync(inputFilePath, 'utf8');
|
|
16
|
-
const inputDataInternal = JSON.parse(customManifest);
|
|
17
8
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
9
|
+
const validateFn = async () => {
|
|
10
|
+
// Load your JSON data from the input file
|
|
11
|
+
const inputFilePath = path.join(process.cwd(), "dist/custom-elements.json"); // Update with your file path
|
|
12
|
+
const customManifest = fs.readFileSync(inputFilePath, 'utf8');
|
|
13
|
+
const inputDataInternal = JSON.parse(customManifest);
|
|
14
|
+
const devMode = process.env.UI5_CEM_MODE === "dev";
|
|
22
15
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (["enum", "interface"].includes(data[i].kind)) {
|
|
28
|
-
data.splice(i, 1);
|
|
29
|
-
i--;
|
|
30
|
-
} else {
|
|
31
|
-
clearProps(data[i]);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
} else if (typeof data === "object") {
|
|
36
|
-
Object.keys(data).forEach(prop => {
|
|
37
|
-
if (prop.startsWith("_ui5")) {
|
|
38
|
-
delete data[prop];
|
|
39
|
-
} else if (typeof data[prop] === "object") {
|
|
40
|
-
clearProps(data[prop]);
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
}
|
|
16
|
+
inputDataInternal.modules.forEach(moduleDoc => {
|
|
17
|
+
moduleDoc.exports = moduleDoc.exports.
|
|
18
|
+
filter(e => moduleDoc.declarations.find(d => d.name === e.declaration.name && ["class", "function", "variable", "enum"].includes(d.kind)) || e.name === "default");
|
|
19
|
+
})
|
|
44
20
|
|
|
45
|
-
|
|
46
|
-
|
|
21
|
+
const clearProps = (data) => {
|
|
22
|
+
if (Array.isArray(data)) {
|
|
23
|
+
for (let i = 0; i < data.length; i++) {
|
|
24
|
+
if (typeof data[i] === "object") {
|
|
25
|
+
if (["enum", "interface"].includes(data[i].kind)) {
|
|
26
|
+
data.splice(i, 1);
|
|
27
|
+
i--;
|
|
28
|
+
} else {
|
|
29
|
+
clearProps(data[i]);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
} else if (typeof data === "object") {
|
|
34
|
+
Object.keys(data).forEach(prop => {
|
|
35
|
+
if (prop.startsWith("_ui5")) {
|
|
36
|
+
delete data[prop];
|
|
37
|
+
} else if (typeof data[prop] === "object") {
|
|
38
|
+
clearProps(data[prop]);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return data;
|
|
44
|
+
}
|
|
47
45
|
|
|
48
|
-
const ajv = new Ajv({ allowUnionTypes: true, allError: true })
|
|
49
|
-
let validate = ajv.compile(internalSchema)
|
|
46
|
+
const ajv = new Ajv({ allowUnionTypes: true, allError: true })
|
|
47
|
+
let validate = ajv.compile(internalSchema)
|
|
50
48
|
|
|
51
|
-
// Validate the JSON data against the schema
|
|
52
|
-
if (
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
49
|
+
// Validate the JSON data against the schema
|
|
50
|
+
if (devMode) {
|
|
51
|
+
if (validate(inputDataInternal)) {
|
|
52
|
+
console.log('Internal custom element manifest is validated successfully');
|
|
53
|
+
} else {
|
|
54
|
+
console.log(validate.errors)
|
|
55
|
+
throw new Error(`Validation of internal custom elements manifest failed: ${validate.errors}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const inputDataExternal = clearProps(JSON.parse(JSON.stringify(inputDataInternal)));
|
|
60
|
+
validate = ajv.compile(extenalSchema)
|
|
61
|
+
|
|
62
|
+
// Validate the JSON data against the schema
|
|
63
|
+
if (validate(inputDataExternal)) {
|
|
64
|
+
console.log('Custom element manifest is validated successfully');
|
|
65
|
+
fs.writeFileSync(inputFilePath, JSON.stringify(inputDataExternal, null, 2), 'utf8');
|
|
66
|
+
fs.writeFileSync(inputFilePath.replace("custom-elements", "custom-elements-internal"), JSON.stringify(inputDataInternal, null, 2), 'utf8');
|
|
67
|
+
} else if (devMode) {
|
|
68
|
+
throw new Error(`Validation of public custom elements manifest failed: ${validate.errors}`);
|
|
69
|
+
}
|
|
58
70
|
}
|
|
59
71
|
|
|
60
|
-
|
|
61
|
-
|
|
72
|
+
if (require.main === module) {
|
|
73
|
+
validateFn()
|
|
74
|
+
}
|
|
62
75
|
|
|
63
|
-
|
|
64
|
-
if (validate(inputDataExternal)) {
|
|
65
|
-
console.log('Custom element manifest is validated successfully');
|
|
66
|
-
fs.writeFileSync(inputFilePath, JSON.stringify(inputDataExternal, null, 2), 'utf8');
|
|
67
|
-
fs.writeFileSync(inputFilePath.replace("custom-elements", "custom-elements-internal"), JSON.stringify(inputDataInternal, null, 2), 'utf8');
|
|
68
|
-
} else if (argv.dev) {
|
|
69
|
-
throw new Error(`Validation of public custom elements manifest failed: ${validate.errors}`);
|
|
70
|
-
}
|
|
76
|
+
exports._ui5mainFn = validateFn;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const chokidar = require('chokidar');
|
|
2
|
+
const { exec } = require("child_process");
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
const main = async (argv) => {
|
|
6
|
+
if (argv.length < 4) {
|
|
7
|
+
console.error("Please provide a file pattern to watch and a command to execute on changes.");
|
|
8
|
+
console.error("<file-pattern> <command>");
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
console.log(argv);
|
|
12
|
+
const filePattern = argv[2];
|
|
13
|
+
const command = argv.slice(3).join(' ');
|
|
14
|
+
|
|
15
|
+
const watcher = new chokidar.FSWatcher();
|
|
16
|
+
|
|
17
|
+
watcher.add(filePattern);
|
|
18
|
+
watcher.unwatch("src/generated");
|
|
19
|
+
|
|
20
|
+
watcher.on('change', async () => {
|
|
21
|
+
exec(command);
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
if (require.main === module) {
|
|
26
|
+
main(process.argv)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
exports._ui5mainFn = main;
|