@ui5/webcomponents-tools 2.15.0 → 2.16.0-rc.1
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 +19 -0
- package/components-package/nps.js +0 -1
- package/lib/cem/cem.js +1 -1
- 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/package.json +3 -3
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { createAttributeFromField } from '../../analyse-phase/creators/createAttribute.js';
|
|
2
|
+
import { getDefaultValuesFromConstructorVisitor } from '../../analyse-phase/creators/createClass.js';
|
|
3
|
+
import { handleJsDoc } from '../../analyse-phase/creators/handlers.js';
|
|
4
|
+
import {
|
|
5
|
+
isAlsoAttribute,
|
|
6
|
+
hasStaticKeyword,
|
|
7
|
+
getPropertiesObject,
|
|
8
|
+
getAttributeName,
|
|
9
|
+
reflects,
|
|
10
|
+
getType,
|
|
11
|
+
} from './utils.js';
|
|
12
|
+
|
|
13
|
+
import { extractMixinNodes, isMixin } from '../../../utils/mixins.js';
|
|
14
|
+
import { handleName } from '../../analyse-phase/creators/createMixin.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* STATIC-PROPERTIES
|
|
18
|
+
*
|
|
19
|
+
* Handles `static get properties()` and `static properties`
|
|
20
|
+
*/
|
|
21
|
+
export function staticPropertiesPlugin() {
|
|
22
|
+
return {
|
|
23
|
+
name: 'CORE - LIT-STATIC-PROPERTIES',
|
|
24
|
+
analyzePhase({ ts, node, moduleDoc, context }) {
|
|
25
|
+
switch (node.kind) {
|
|
26
|
+
case ts.SyntaxKind.VariableStatement:
|
|
27
|
+
case ts.SyntaxKind.FunctionDeclaration:
|
|
28
|
+
if (isMixin(node)) {
|
|
29
|
+
const { mixinFunction, mixinClass } = extractMixinNodes(node);
|
|
30
|
+
const { name } = handleName({}, mixinFunction);
|
|
31
|
+
handleStaticProperties(mixinClass, moduleDoc, context, name, ts);
|
|
32
|
+
}
|
|
33
|
+
break;
|
|
34
|
+
|
|
35
|
+
case ts.SyntaxKind.ClassDeclaration:
|
|
36
|
+
handleStaticProperties(node, moduleDoc, context, null, ts);
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function handleStaticProperties(classNode, moduleDoc, context, mixinName = null, ts) {
|
|
44
|
+
let className;
|
|
45
|
+
if (!mixinName) {
|
|
46
|
+
className = classNode?.name?.getText();
|
|
47
|
+
} else {
|
|
48
|
+
className = mixinName;
|
|
49
|
+
}
|
|
50
|
+
const currClass = moduleDoc?.declarations?.find(declaration => declaration.name === className);
|
|
51
|
+
|
|
52
|
+
classNode?.members?.forEach(member => {
|
|
53
|
+
if (hasStaticKeyword(member) && member.name.text === 'properties') {
|
|
54
|
+
const propertiesObject = getPropertiesObject(member);
|
|
55
|
+
propertiesObject?.properties?.forEach(property => {
|
|
56
|
+
if (property.kind !== ts.SyntaxKind.PropertyAssignment) return;
|
|
57
|
+
|
|
58
|
+
let classMember = {
|
|
59
|
+
kind: 'field',
|
|
60
|
+
name: property?.name?.getText() || '',
|
|
61
|
+
privacy: 'public',
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const type = getType(property);
|
|
65
|
+
if (type) {
|
|
66
|
+
classMember.type = { text: type }
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
classMember = handleJsDoc(classMember, property);
|
|
70
|
+
|
|
71
|
+
const memberIndex = currClass?.members?.findIndex(field => field.name === classMember.name);
|
|
72
|
+
if (memberIndex >= 0) {
|
|
73
|
+
classMember = { ...classMember, ...currClass.members[memberIndex] };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (isAlsoAttribute(property)) {
|
|
77
|
+
const attribute = createAttributeFromField(classMember);
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* If an attribute name is provided
|
|
81
|
+
* @example @property({attribute:'my-foo'})
|
|
82
|
+
*/
|
|
83
|
+
const attributeName = getAttributeName(property);
|
|
84
|
+
if (attributeName) {
|
|
85
|
+
attribute.name = attributeName;
|
|
86
|
+
classMember.attribute = attributeName;
|
|
87
|
+
} else {
|
|
88
|
+
classMember.attribute = classMember.name;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (reflects(property)) {
|
|
92
|
+
classMember.attribute = attribute.name;
|
|
93
|
+
classMember.reflects = true;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const attributeIndex = currClass?.attributes?.findIndex(
|
|
97
|
+
attr => attr.name === attribute.name,
|
|
98
|
+
);
|
|
99
|
+
if (attributeIndex >= 0) {
|
|
100
|
+
currClass.attributes[attributeIndex] = {
|
|
101
|
+
...currClass.attributes[attributeIndex],
|
|
102
|
+
...attribute,
|
|
103
|
+
};
|
|
104
|
+
} else {
|
|
105
|
+
currClass.attributes.push(attribute);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (memberIndex >= 0) {
|
|
110
|
+
currClass.members[memberIndex] = classMember;
|
|
111
|
+
} else {
|
|
112
|
+
currClass.members.push(classMember);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
/** Get default values */
|
|
120
|
+
getDefaultValuesFromConstructorVisitor(classNode, currClass, context);
|
|
121
|
+
}
|
package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/utils.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
|
|
3
|
+
export function isAlsoAttribute(node) {
|
|
4
|
+
let result = true;
|
|
5
|
+
(node?.initializer || node)?.properties?.forEach((property) => {
|
|
6
|
+
if (
|
|
7
|
+
property.name.text === 'attribute' &&
|
|
8
|
+
property.initializer.kind === ts.SyntaxKind.FalseKeyword
|
|
9
|
+
) {
|
|
10
|
+
result = false;
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
return result;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function reflects(node) {
|
|
17
|
+
let result = false;
|
|
18
|
+
(node?.initializer || node)?.properties?.forEach((property) => {
|
|
19
|
+
if (
|
|
20
|
+
property.name.text === 'reflect' &&
|
|
21
|
+
property.initializer.kind === ts.SyntaxKind.TrueKeyword
|
|
22
|
+
) {
|
|
23
|
+
result = true;
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function getType(node) {
|
|
30
|
+
let result = false;
|
|
31
|
+
(node?.initializer || node)?.properties?.forEach((property) => {
|
|
32
|
+
if (property.name.text === 'type') {
|
|
33
|
+
result = property.initializer.text.toLowerCase();
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function getAttributeName(node) {
|
|
40
|
+
let result = false;
|
|
41
|
+
(node?.initializer || node)?.properties?.forEach((property) => {
|
|
42
|
+
if (
|
|
43
|
+
property.name.text === 'attribute' &&
|
|
44
|
+
property.initializer.kind === ts.SyntaxKind.StringLiteral
|
|
45
|
+
) {
|
|
46
|
+
result = property.initializer.text;
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function hasPropertyDecorator(node) {
|
|
53
|
+
return node?.modifiers?.some((decorator) => {
|
|
54
|
+
return ts.isDecorator(decorator) && decorator?.expression?.expression?.getText() === 'property'
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export const hasStaticKeyword = node => node?.modifiers?.some(mod => mod.kind === ts.SyntaxKind.StaticKeyword);
|
|
59
|
+
|
|
60
|
+
export function getPropertiesObject(node) {
|
|
61
|
+
if (ts.isGetAccessor(node)) {
|
|
62
|
+
return node.body?.statements?.find(ts.isReturnStatement)?.expression;
|
|
63
|
+
} else {
|
|
64
|
+
return node.initializer;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { decorator, toKebabCase } from '../../../utils/index.js'
|
|
2
|
+
|
|
3
|
+
export function stencilPlugin() {
|
|
4
|
+
let events = [];
|
|
5
|
+
|
|
6
|
+
const METHOD_DENYLIST = ['componentWillLoad', 'componentDidLoad', 'componentShouldUpdate', 'componentWillRender', 'componentDidRender', 'componentWillUpdate', 'componentDidUpdate'];
|
|
7
|
+
|
|
8
|
+
return {
|
|
9
|
+
name: 'CORE - STENCIL',
|
|
10
|
+
// Runs for each module
|
|
11
|
+
analyzePhase({ts, node, moduleDoc}){
|
|
12
|
+
switch (node.kind) {
|
|
13
|
+
case ts.SyntaxKind.ClassDeclaration:
|
|
14
|
+
/**
|
|
15
|
+
* Add tagName to classDoc, extracted from `@Component({tag: 'foo-bar'})` decorator
|
|
16
|
+
* Add custom-element-definition to exports
|
|
17
|
+
*/
|
|
18
|
+
const componentDecorator = node?.modifiers?.find(decorator('Component'))?.expression;
|
|
19
|
+
|
|
20
|
+
const tagName = componentDecorator?.arguments?.[0]?.properties?.find(prop => {
|
|
21
|
+
return prop?.name?.getText() === 'tag'
|
|
22
|
+
})?.initializer?.text;
|
|
23
|
+
|
|
24
|
+
const className = node?.name?.getText();
|
|
25
|
+
const currClass = moduleDoc?.declarations?.find(declaration => declaration.name === className);
|
|
26
|
+
if(tagName) {
|
|
27
|
+
currClass.tagName = tagName;
|
|
28
|
+
moduleDoc.exports.push({
|
|
29
|
+
kind: "custom-element-definition",
|
|
30
|
+
name: tagName,
|
|
31
|
+
declaration: {
|
|
32
|
+
name: className,
|
|
33
|
+
module: moduleDoc.path
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Collect fields with `@Event()` decorator so we can process them in `moduleLinkPhase`
|
|
40
|
+
*/
|
|
41
|
+
const eventFields = node?.members
|
|
42
|
+
?.filter(member => member?.modifiers?.find(decorator('Event')))
|
|
43
|
+
?.map(member => {
|
|
44
|
+
const eventDecorator = member?.modifiers?.find(decorator('Event'));
|
|
45
|
+
const eventName = eventDecorator?.expression?.arguments?.[0]?.properties?.find(prop => {
|
|
46
|
+
return prop?.name?.getText() === 'eventName'
|
|
47
|
+
})?.initializer?.text;
|
|
48
|
+
|
|
49
|
+
return { field: member?.name?.getText(), as: eventName || member?.name?.getText() }
|
|
50
|
+
});
|
|
51
|
+
events = [...(eventFields || [])];
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Handle `@Prop` decorator, and store attributes to add to manifest later
|
|
55
|
+
* - if type is primitive -> create attr
|
|
56
|
+
* - if not `{ attribute: ''}` in decorator, just kebabcase the fieldname, otherwise use the value provided
|
|
57
|
+
* - if type is not primitive -> no attr
|
|
58
|
+
* - add fieldName to attr
|
|
59
|
+
*/
|
|
60
|
+
node?.members
|
|
61
|
+
?.filter(member => member?.modifiers?.find(decorator('Prop')))
|
|
62
|
+
?.forEach(property => {
|
|
63
|
+
const fieldName = property?.name?.text;
|
|
64
|
+
const attrNameFromDecorator = property?.modifiers?.[0]?.expression?.arguments?.[0]?.properties?.find(prop => prop?.name?.getText() === 'attribute')?.initializer?.text;
|
|
65
|
+
const attrName = attrNameFromDecorator || toKebabCase(property?.name?.text);
|
|
66
|
+
|
|
67
|
+
const reflects = property?.modifiers?.[0]?.expression?.arguments?.[0]?.properties?.find(prop => prop?.name?.getText() === 'reflects')?.initializer?.getText?.() === 'true';
|
|
68
|
+
const member = currClass?.members?.find(mem => mem?.name === fieldName);
|
|
69
|
+
if(reflects) {
|
|
70
|
+
member.reflects = true;
|
|
71
|
+
member.attribute = attrName;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if(!currClass.attributes) currClass.attributes = [];
|
|
75
|
+
const hasType = !!property?.type?.getText?.();
|
|
76
|
+
|
|
77
|
+
currClass.attributes.push({
|
|
78
|
+
name: attrName,
|
|
79
|
+
fieldName,
|
|
80
|
+
...(member?.default ? { default: member.default } : {}),
|
|
81
|
+
...(member?.description ? { description: member.description } : {}),
|
|
82
|
+
...(hasType ? {
|
|
83
|
+
type: { text: property?.type?.getText?.() }
|
|
84
|
+
} : {})
|
|
85
|
+
})
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
// Runs for each module, after analyzing, all information about your module should now be available
|
|
93
|
+
moduleLinkPhase({moduleDoc}){
|
|
94
|
+
/**
|
|
95
|
+
* Remove lifecycle methods
|
|
96
|
+
*/
|
|
97
|
+
const classes = moduleDoc?.declarations?.filter(declaration => declaration.kind === 'class');
|
|
98
|
+
|
|
99
|
+
classes?.forEach(klass => {
|
|
100
|
+
if(!klass?.members) return;
|
|
101
|
+
klass.members = klass?.members?.filter(member => {
|
|
102
|
+
return !METHOD_DENYLIST.includes(member.name)
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Events
|
|
108
|
+
*/
|
|
109
|
+
classes?.forEach(klass => {
|
|
110
|
+
if(!klass?.members) return;
|
|
111
|
+
const eventsAsFields = klass.members
|
|
112
|
+
?.filter(member => events.some(event => event.field === member.name))
|
|
113
|
+
?.map(member => {
|
|
114
|
+
delete member.privacy;
|
|
115
|
+
delete member.kind;
|
|
116
|
+
member.name = events.find(event => event.field === member.name).as;
|
|
117
|
+
return member;
|
|
118
|
+
}) || [];
|
|
119
|
+
|
|
120
|
+
/* Add events as eventDocs */
|
|
121
|
+
klass.events = [...(klass?.events || []), ...eventsAsFields]
|
|
122
|
+
|
|
123
|
+
/* Remove events as class fields */
|
|
124
|
+
klass.members = klass?.members?.filter(member => !events.some(event => event.field === member.name || event.as === member.name));
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COLLECT
|
|
3
|
+
*/
|
|
4
|
+
import { collectImportsPlugin } from './collect-phase/collect-imports.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* ANALYSE
|
|
8
|
+
*/
|
|
9
|
+
import { exportsPlugin } from './analyse-phase/exports.js';
|
|
10
|
+
import { customElementsDefineCallsPlugin } from './analyse-phase/custom-elements-define-calls.js';
|
|
11
|
+
import { functionLikePlugin } from './analyse-phase/function-like.js';
|
|
12
|
+
import { arrowFunctionPlugin } from './analyse-phase/arrow-function.js';
|
|
13
|
+
import { classPlugin } from './analyse-phase/classes.js';
|
|
14
|
+
import { mixinPlugin } from './analyse-phase/mixins.js';
|
|
15
|
+
import { variablePlugin } from './analyse-phase/variables.js';
|
|
16
|
+
import { classJsDocPlugin } from './analyse-phase/class-jsdoc.js';
|
|
17
|
+
import { reexportedWrappedMixinExportsPlugin } from './analyse-phase/reexported-wrapped-mixin-exports.js';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* LINK
|
|
21
|
+
*/
|
|
22
|
+
import { methodDenyListPlugin } from './link-phase/method-denylist.js';
|
|
23
|
+
import { fieldDenyListPlugin } from './link-phase/field-denylist.js';
|
|
24
|
+
import { cleanupClassesPlugin } from './link-phase/cleanup-classes.js';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* POST-PROCESSING
|
|
28
|
+
*/
|
|
29
|
+
import { removeUnexportedDeclarationsPlugin } from './post-processing/remove-unexported-declarations.js';
|
|
30
|
+
import { resolveInitializersPlugin } from './post-processing/resolve-initializers.js';
|
|
31
|
+
import { isCustomElementPlugin } from './post-processing/is-custom-element.js';
|
|
32
|
+
import { linkClassToTagnamePlugin } from './post-processing/link-class-to-tagname.js';
|
|
33
|
+
import { applyInheritancePlugin } from './post-processing/apply-inheritance.js';
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* FRAMEWORKS
|
|
37
|
+
*/
|
|
38
|
+
import { stencilPlugin } from './framework-plugins/stencil/stencil.js';
|
|
39
|
+
import { catalystPlugin } from './framework-plugins/catalyst/catalyst.js';
|
|
40
|
+
import { catalystPlugin2 } from './framework-plugins/catalyst-major-2/catalyst.js';
|
|
41
|
+
import { fastPlugin } from './framework-plugins/fast/fast.js';
|
|
42
|
+
import { litPlugin } from './framework-plugins/lit/lit.js';
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Establish the execution order of plugins
|
|
46
|
+
*/
|
|
47
|
+
export const FEATURES = [
|
|
48
|
+
/** COLLECT */
|
|
49
|
+
collectImportsPlugin(),
|
|
50
|
+
|
|
51
|
+
/** ANALYSE */
|
|
52
|
+
exportsPlugin(),
|
|
53
|
+
customElementsDefineCallsPlugin(),
|
|
54
|
+
functionLikePlugin(),
|
|
55
|
+
arrowFunctionPlugin(),
|
|
56
|
+
classPlugin(),
|
|
57
|
+
mixinPlugin(),
|
|
58
|
+
variablePlugin(),
|
|
59
|
+
reexportedWrappedMixinExportsPlugin(),
|
|
60
|
+
classJsDocPlugin(),
|
|
61
|
+
|
|
62
|
+
/** LINK */
|
|
63
|
+
methodDenyListPlugin(),
|
|
64
|
+
fieldDenyListPlugin(),
|
|
65
|
+
cleanupClassesPlugin(),
|
|
66
|
+
|
|
67
|
+
/** POST-PROCESSING */
|
|
68
|
+
resolveInitializersPlugin(),
|
|
69
|
+
linkClassToTagnamePlugin(),
|
|
70
|
+
isCustomElementPlugin(),
|
|
71
|
+
applyInheritancePlugin(),
|
|
72
|
+
removeUnexportedDeclarationsPlugin(),
|
|
73
|
+
|
|
74
|
+
/** FRAMEWORKS */
|
|
75
|
+
// litPlugin()
|
|
76
|
+
// fastPlugin()
|
|
77
|
+
// stencilPlugin()
|
|
78
|
+
// catalystPlugin()
|
|
79
|
+
// catalystPlugin2()
|
|
80
|
+
].flat();
|
package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/link-phase/cleanup-classes.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { has } from "../../utils/index.js"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CLEANUP-CLASSES
|
|
5
|
+
*
|
|
6
|
+
* Removes empty arrays from classes; e.g. if a class doesn't have any `members`,
|
|
7
|
+
* then we remove it from the class doc
|
|
8
|
+
*/
|
|
9
|
+
export function cleanupClassesPlugin() {
|
|
10
|
+
return {
|
|
11
|
+
name: 'CORE - CLEANUP-CLASSES',
|
|
12
|
+
moduleLinkPhase({moduleDoc}){
|
|
13
|
+
const classes = moduleDoc?.declarations?.filter(declaration => declaration.kind === 'class' || declaration.kind === 'mixin');
|
|
14
|
+
|
|
15
|
+
classes?.forEach(klass => {
|
|
16
|
+
['cssProperties', 'cssParts', 'slots', 'members', 'attributes', 'events', 'cssStates'].forEach(field => {
|
|
17
|
+
if(!has(klass[field])) {
|
|
18
|
+
delete klass[field];
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
},
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/link-phase/field-denylist.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FIELD-DENY-LIST
|
|
3
|
+
*
|
|
4
|
+
* Excludes fields from the manifest
|
|
5
|
+
*/
|
|
6
|
+
export function fieldDenyListPlugin() {
|
|
7
|
+
const FIELD_DENY_LIST = [
|
|
8
|
+
'observedAttributes',
|
|
9
|
+
];
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
name: 'CORE - FIELD-DENYLIST',
|
|
13
|
+
moduleLinkPhase({moduleDoc}){
|
|
14
|
+
const classes = moduleDoc?.declarations?.filter(declaration => declaration.kind === 'class' || declaration.kind === 'mixin');
|
|
15
|
+
|
|
16
|
+
classes?.forEach(klass => {
|
|
17
|
+
klass.members = klass?.members?.filter(member => !FIELD_DENY_LIST.includes(member.name));
|
|
18
|
+
});
|
|
19
|
+
},
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/link-phase/method-denylist.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* METHOD-DENY-LIST
|
|
3
|
+
*
|
|
4
|
+
* Excludes methods from the manifest
|
|
5
|
+
*/
|
|
6
|
+
export function methodDenyListPlugin() {
|
|
7
|
+
const METHOD_DENY_LIST = [
|
|
8
|
+
'connectedCallback',
|
|
9
|
+
'disconnectedCallback',
|
|
10
|
+
'attributeChangedCallback',
|
|
11
|
+
'adoptedCallback'
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
name: 'CORE - METHOD-DENYLIST',
|
|
16
|
+
moduleLinkPhase({moduleDoc}){
|
|
17
|
+
const classes = moduleDoc?.declarations?.filter(declaration => declaration.kind === 'class' || declaration.kind === 'mixin');
|
|
18
|
+
|
|
19
|
+
classes?.forEach(klass => {
|
|
20
|
+
klass.members = klass?.members?.filter(member => !METHOD_DENY_LIST.includes(member.name));
|
|
21
|
+
});
|
|
22
|
+
},
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { getAllDeclarationsOfKind, getModuleForClassLike, getModuleFromManifests, getInheritanceTree } from '../../utils/manifest-helpers.js';
|
|
2
|
+
import { resolveModuleOrPackageSpecifier } from '../../utils/index.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* APPLY-INHERITANCE-PLUGIN
|
|
6
|
+
*
|
|
7
|
+
* Applies inheritance for all classes in the manifest
|
|
8
|
+
*/
|
|
9
|
+
export function applyInheritancePlugin() {
|
|
10
|
+
return {
|
|
11
|
+
name: 'CORE - APPLY-INHERITANCE',
|
|
12
|
+
packageLinkPhase({customElementsManifest, context}){
|
|
13
|
+
const allManifests = [customElementsManifest, ...(context.thirdPartyCEMs || [])];
|
|
14
|
+
const classLikes = [];
|
|
15
|
+
|
|
16
|
+
allManifests.forEach((manifest) => {
|
|
17
|
+
const classes = getAllDeclarationsOfKind(manifest, 'class');
|
|
18
|
+
const mixins = getAllDeclarationsOfKind(manifest, 'mixin');
|
|
19
|
+
classLikes.push(...[...classes, ...mixins]);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
classLikes.forEach((customElement) => {
|
|
23
|
+
const inheritanceChain = getInheritanceTree(allManifests, customElement.name);
|
|
24
|
+
|
|
25
|
+
inheritanceChain?.forEach(klass => {
|
|
26
|
+
// ignore the current class itself
|
|
27
|
+
if (klass?.name === customElement.name) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
['slots', 'cssParts', 'cssProperties', 'attributes', 'members', 'events', 'cssStates'].forEach(type => {
|
|
32
|
+
klass?.[type]?.forEach(currItem => {
|
|
33
|
+
const containingModulePath = getModuleForClassLike(allManifests, klass.name);
|
|
34
|
+
const containingModule = getModuleFromManifests(allManifests, containingModulePath);
|
|
35
|
+
|
|
36
|
+
const newItem = { ...currItem };
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* If an attr or member is already present in the base class, but we encounter it here,
|
|
40
|
+
* it means that the base has overridden that method from the super class
|
|
41
|
+
* So we either add the data to the overridden method, or we add it to the array as a new item
|
|
42
|
+
*/
|
|
43
|
+
const existing = customElement?.[type]?.find(item => newItem.name === item.name);
|
|
44
|
+
|
|
45
|
+
if (existing) {
|
|
46
|
+
|
|
47
|
+
existing.inheritedFrom = {
|
|
48
|
+
name: klass.name,
|
|
49
|
+
...resolveModuleOrPackageSpecifier(containingModule, context, klass.name)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
customElement[type] = customElement?.[type]?.map(item => item.name === existing.name
|
|
53
|
+
? {
|
|
54
|
+
...newItem,
|
|
55
|
+
...existing,
|
|
56
|
+
// Patch: Custom patch to not merge child parent privacy/type
|
|
57
|
+
// https://github.com/open-wc/custom-elements-manifest/pull/300
|
|
58
|
+
// ...{
|
|
59
|
+
// ...(newItem.type ? { type: newItem.type } : {}),
|
|
60
|
+
// ...(newItem.privacy ? { privacy: newItem.privacy } : {})
|
|
61
|
+
// }
|
|
62
|
+
}
|
|
63
|
+
: item);
|
|
64
|
+
} else {
|
|
65
|
+
newItem.inheritedFrom = {
|
|
66
|
+
name: klass.name,
|
|
67
|
+
...resolveModuleOrPackageSpecifier(containingModule, context, klass.name)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
customElement[type] = [...(customElement[type] || []), newItem];
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const BASECLASSES = [
|
|
2
|
+
'htmlelement',
|
|
3
|
+
'litelement',
|
|
4
|
+
'fastelement'
|
|
5
|
+
];
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* ISCUSTOMELEMENT
|
|
9
|
+
*
|
|
10
|
+
* Heuristic to see whether or not a class is a custom element
|
|
11
|
+
*/
|
|
12
|
+
export function isCustomElementPlugin() {
|
|
13
|
+
return {
|
|
14
|
+
name: 'CORE - IS-CUSTOM-ELEMENT',
|
|
15
|
+
packageLinkPhase({customElementsManifest, context}) {
|
|
16
|
+
customElementsManifest?.modules?.forEach(_module => {
|
|
17
|
+
_module?.declarations?.forEach(declaration => {
|
|
18
|
+
if(declaration?.kind === 'class') {
|
|
19
|
+
/** If a class has a tagName, that means its been defined, and is a custom element */
|
|
20
|
+
if(declaration?.tagName) {
|
|
21
|
+
declaration.customElement = true;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** If a class extends from any of these, its a custom element */
|
|
25
|
+
if(BASECLASSES.includes(declaration?.superclass?.name?.toLowerCase())) {
|
|
26
|
+
declaration.customElement = true;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { getAllDeclarationsOfKind, getAllExportsOfKind } from '../../utils/manifest-helpers.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* LINK-CLASS-TO-TAGNAME
|
|
5
|
+
*
|
|
6
|
+
* Links a custom element definition to its corresponding class
|
|
7
|
+
*/
|
|
8
|
+
export function linkClassToTagnamePlugin() {
|
|
9
|
+
return {
|
|
10
|
+
name: 'CORE - LINK-CLASS-TO-TAGNAME',
|
|
11
|
+
packageLinkPhase({customElementsManifest, context}){
|
|
12
|
+
/* Get all class declarations and custom element definitions in the manifest */
|
|
13
|
+
const classes = getAllDeclarationsOfKind(customElementsManifest, 'class');
|
|
14
|
+
const definitions = getAllExportsOfKind(customElementsManifest, 'custom-element-definition');
|
|
15
|
+
|
|
16
|
+
/* Loop through all classes, and try to find their corresponding custom element definition */
|
|
17
|
+
classes?.forEach((klass) => {
|
|
18
|
+
const tagName = definitions?.find(def => def?.declaration?.name === klass?.name)?.name;
|
|
19
|
+
|
|
20
|
+
/* If there's a match, we can link the custom element definition to the class */
|
|
21
|
+
if (tagName && !klass.tagName) {
|
|
22
|
+
klass.tagName = tagName;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { has } from '../../utils/index.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* REMOVE-UNEXPORTED-DECLARATIONS
|
|
5
|
+
*
|
|
6
|
+
* If a module has declarations that are _not_ exported, that means those declarations are considered 'private' to that module, and they shouldnt be present in the manifest, so we remove them.
|
|
7
|
+
*/
|
|
8
|
+
export function removeUnexportedDeclarationsPlugin() {
|
|
9
|
+
return {
|
|
10
|
+
name: 'CORE - REMOVE-UNEXPORTED-DECLARATIONS',
|
|
11
|
+
packageLinkPhase({customElementsManifest}){
|
|
12
|
+
customElementsManifest?.modules?.forEach(mod => {
|
|
13
|
+
if(has(mod?.declarations)) {
|
|
14
|
+
mod.declarations = mod?.declarations?.filter(declaration => {
|
|
15
|
+
return mod?.exports?.some(_export => {
|
|
16
|
+
return declaration?.name === _export?.name || declaration?.name === _export?.declaration?.name;
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
}
|