@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.
Files changed (58) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/components-package/nps.js +0 -1
  3. package/lib/cem/cem.js +1 -1
  4. package/lib/cem/patch/@custom-elements-manifest/analyzer/cli.js +128 -0
  5. package/lib/cem/patch/@custom-elements-manifest/analyzer/package.json +59 -0
  6. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/browser-entrypoint.js +23 -0
  7. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/create.js +117 -0
  8. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/arrow-function.js +26 -0
  9. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/class-jsdoc.js +157 -0
  10. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/classes.js +20 -0
  11. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createArrowFunction.js +17 -0
  12. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createAttribute.js +24 -0
  13. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createClass.js +301 -0
  14. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createClassField.js +26 -0
  15. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createFunctionLike.js +73 -0
  16. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createMixin.js +33 -0
  17. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createVariable.js +22 -0
  18. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/handlers.js +338 -0
  19. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/custom-elements-define-calls.js +90 -0
  20. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/exports.js +156 -0
  21. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/function-like.js +24 -0
  22. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/mixins.js +29 -0
  23. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/reexported-wrapped-mixin-exports.js +84 -0
  24. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/variables.js +34 -0
  25. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/collect-phase/collect-imports.js +101 -0
  26. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/catalyst/catalyst.js +11 -0
  27. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/catalyst/controller.js +34 -0
  28. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/catalyst-major-2/catalyst.js +11 -0
  29. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/catalyst-major-2/controller.js +34 -0
  30. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/decorators/attr.js +53 -0
  31. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/decorators/custom-element-decorator.js +36 -0
  32. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/fast/fast.js +7 -0
  33. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/lit.js +13 -0
  34. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/member-denylist.js +21 -0
  35. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/method-denylist.js +20 -0
  36. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/property-decorator.js +94 -0
  37. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/static-properties.js +121 -0
  38. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/utils.js +66 -0
  39. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/stencil/stencil.js +129 -0
  40. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/index.js +80 -0
  41. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/link-phase/cleanup-classes.js +25 -0
  42. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/link-phase/field-denylist.js +22 -0
  43. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/link-phase/method-denylist.js +25 -0
  44. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/post-processing/apply-inheritance.js +78 -0
  45. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/post-processing/is-custom-element.js +34 -0
  46. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/post-processing/link-class-to-tagname.js +27 -0
  47. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/post-processing/remove-unexported-declarations.js +23 -0
  48. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/post-processing/resolve-initializers.js +52 -0
  49. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/ast-helpers.js +186 -0
  50. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/cli-helpers.js +164 -0
  51. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/exports.js +44 -0
  52. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/find-external-manifests.js +67 -0
  53. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/imports.js +25 -0
  54. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/index.js +71 -0
  55. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/jsdoc.js +19 -0
  56. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/manifest-helpers.js +194 -0
  57. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/mixins.js +112 -0
  58. package/package.json +3 -3
@@ -0,0 +1,338 @@
1
+ import ts from 'typescript';
2
+ import { parse } from 'comment-parser';
3
+
4
+ import { has, resolveModuleOrPackageSpecifier, safe } from '../../../utils/index.js';
5
+ import { handleJsDocType, normalizeDescription } from '../../../utils/jsdoc.js';
6
+ import { isWellKnownType } from '../../../utils/ast-helpers.js';
7
+
8
+ /**
9
+ * @example static foo;
10
+ * @example public foo;
11
+ * @example private foo;
12
+ * @example protected foo;
13
+ */
14
+ export function handleModifiers(doc, node) {
15
+ node?.modifiers?.forEach(modifier => {
16
+ if(modifier?.kind === ts.SyntaxKind.StaticKeyword) {
17
+ doc.static = true;
18
+ }
19
+
20
+ if (modifier?.kind === ts.SyntaxKind.ReadonlyKeyword) {
21
+ doc.readonly = true;
22
+ }
23
+
24
+ switch (modifier.kind) {
25
+ case ts.SyntaxKind.PublicKeyword:
26
+ doc.privacy = 'public';
27
+ break;
28
+ case ts.SyntaxKind.PrivateKeyword:
29
+ doc.privacy = 'private';
30
+ break;
31
+ case ts.SyntaxKind.ProtectedKeyword:
32
+ doc.privacy = 'protected';
33
+ break;
34
+ }
35
+ });
36
+
37
+ if (node.name?.text?.startsWith('#')) {
38
+ doc.privacy = 'private';
39
+ }
40
+
41
+ return doc;
42
+ }
43
+
44
+ /**
45
+ * Handles JsDoc
46
+ */
47
+ export function handleJsDoc(doc, node) {
48
+ node?.jsDoc?.forEach(jsDocComment => {
49
+ if(jsDocComment?.comment) {
50
+ if(has(jsDocComment?.comment)) {
51
+ doc.description = jsDocComment.comment.map(com => `${safe(() => com?.name?.getText()) ?? ''}${com.text}`).join('');
52
+ } else {
53
+ doc.description = normalizeDescription(jsDocComment.comment);
54
+ }
55
+ }
56
+
57
+ jsDocComment?.tags?.forEach(tag => {
58
+ /** @readonly */
59
+ if(tag.kind === ts.SyntaxKind.JSDocReadonlyTag) {
60
+ doc.readonly = true;
61
+ }
62
+
63
+ /** @param */
64
+ if(tag.kind === ts.SyntaxKind.JSDocParameterTag) {
65
+ const parameter = doc?.parameters?.find(parameter => parameter.name === tag.name.text);
66
+ const parameterAlreadyExists = !!parameter;
67
+ const parameterTemplate = parameter || {};
68
+
69
+ if(tag?.comment) {
70
+ parameterTemplate.description = normalizeDescription(tag.comment);
71
+ }
72
+
73
+ if(tag?.name) {
74
+ parameterTemplate.name = tag.name.getText();
75
+ }
76
+
77
+ /**
78
+ * If its bracketed, that means its optional
79
+ * @example [foo]
80
+ */
81
+ if(tag?.isBracketed) {
82
+ parameterTemplate.optional = true;
83
+ }
84
+
85
+ if(tag?.typeExpression) {
86
+ parameterTemplate.type = {
87
+ text: handleJsDocType(tag.typeExpression.type.getText())
88
+ }
89
+ }
90
+
91
+ if(!parameterAlreadyExists) {
92
+ doc.parameters = [...(doc?.parameters || []), parameterTemplate];
93
+ }
94
+ }
95
+
96
+ /** @returns */
97
+ if(tag.kind === ts.SyntaxKind.JSDocReturnTag) {
98
+ doc.return = {
99
+ type: {
100
+ text: handleJsDocType(tag?.typeExpression?.type?.getText())
101
+ }
102
+ }
103
+ }
104
+
105
+ /** @type */
106
+ if(tag.kind === ts.SyntaxKind.JSDocTypeTag) {
107
+ if(tag?.comment) {
108
+ doc.description = normalizeDescription(tag.comment);
109
+ }
110
+
111
+ doc.type = {
112
+ text: handleJsDocType(tag.typeExpression.type.getText())
113
+ }
114
+ }
115
+
116
+ /** @reflect */
117
+ if(safe(() => tag?.tagName?.getText()) === 'reflect' && doc?.kind === 'field') {
118
+ doc.reflects = true;
119
+ }
120
+
121
+ /** @summary */
122
+ if(safe(() => tag?.tagName?.getText()) === 'summary') {
123
+ doc.summary = tag.comment;
124
+ }
125
+
126
+ /** @deprecated */
127
+ if(safe(() => tag?.tagName?.getText()) === 'deprecated') {
128
+ doc.deprecated = tag.comment || "true";
129
+ }
130
+
131
+ /** @default */
132
+ if (safe(() => tag?.tagName?.getText()) === 'default' && doc?.kind === 'field') {
133
+ doc.default ??= tag.comment;
134
+ }
135
+
136
+ /**
137
+ * Overwrite privacy
138
+ * @public
139
+ * @private
140
+ * @protected
141
+ */
142
+ switch(tag.kind) {
143
+ case ts.SyntaxKind.JSDocPublicTag:
144
+ doc.privacy = 'public';
145
+ break;
146
+ case ts.SyntaxKind.JSDocPrivateTag:
147
+ doc.privacy = 'private';
148
+ break;
149
+ case ts.SyntaxKind.JSDocProtectedTag:
150
+ doc.privacy = 'protected';
151
+ break;
152
+ }
153
+ });
154
+ });
155
+
156
+ return doc;
157
+ }
158
+
159
+
160
+
161
+ /**
162
+ * Creates a mixin for inside a classDoc
163
+ */
164
+ export function createClassDeclarationMixin(name, moduleDoc, context) {
165
+ const mixin = {
166
+ name,
167
+ ...resolveModuleOrPackageSpecifier(moduleDoc, context, name)
168
+ };
169
+ return mixin;
170
+ }
171
+
172
+ /**
173
+ * Handles mixins and superclass
174
+ */
175
+ export function handleHeritage(classTemplate, moduleDoc, context, node) {
176
+ node?.heritageClauses?.forEach((clause) => {
177
+ /* Ignoring `ImplementsKeyword` for now, future revisions may retrieve docs per-field for the implemented methods. */
178
+ if (clause.token !== ts.SyntaxKind.ExtendsKeyword) return;
179
+
180
+ clause?.types?.forEach((type) => {
181
+ const mixins = [];
182
+ let node = type.expression;
183
+ let superClass;
184
+
185
+ /* gather mixin calls */
186
+ if (ts.isCallExpression(node)) {
187
+ const mixinName = node.expression.getText();
188
+ mixins.push(createClassDeclarationMixin(mixinName, moduleDoc, context))
189
+ while (ts.isCallExpression(node.arguments[0])) {
190
+ node = node.arguments[0];
191
+ const mixinName = node.expression.getText();
192
+ mixins.push(createClassDeclarationMixin(mixinName, moduleDoc, context));
193
+ }
194
+ superClass = node.arguments[0].text;
195
+ } else {
196
+ superClass = node.text;
197
+ }
198
+
199
+ if (has(mixins)) {
200
+ classTemplate.mixins = mixins;
201
+ }
202
+
203
+ classTemplate.superclass = {
204
+ name: superClass,
205
+ ...resolveModuleOrPackageSpecifier(moduleDoc, context, superClass)
206
+ };
207
+
208
+ if(superClass === 'HTMLElement') {
209
+ delete classTemplate.superclass.module;
210
+ }
211
+ });
212
+ });
213
+
214
+ return classTemplate;
215
+ }
216
+
217
+ /**
218
+ * Handles fields that have an @attr jsdoc annotation and gets the attribute name (if specified) and the description
219
+ * @example @attr my-attr this is the attr description
220
+ */
221
+ export function handleAttrJsDoc(node, doc) {
222
+ node?.jsDoc?.forEach(jsDoc => {
223
+ const docs = parse(jsDoc?.getFullText())?.find(doc => doc?.tags?.some(({tag}) => ["attribute", "attr"].includes(tag)));
224
+ const attrTag = docs?.tags?.find(({tag}) => ["attribute", "attr"].includes(tag));
225
+
226
+ if(attrTag?.name) {
227
+ doc.name = attrTag.name;
228
+ }
229
+
230
+ if(attrTag?.description) {
231
+ doc.description = normalizeDescription(attrTag.description);
232
+ }
233
+ });
234
+
235
+ return doc;
236
+ }
237
+
238
+ export function handleTypeInference(doc, node) {
239
+ const n = node?.initializer || node;
240
+ switch(n?.kind) {
241
+ case ts.SyntaxKind.TrueKeyword:
242
+ case ts.SyntaxKind.FalseKeyword:
243
+ doc.type = { text: "boolean" }
244
+ break;
245
+ case ts.SyntaxKind.StringLiteral:
246
+ doc.type = { text: "string" }
247
+ break;
248
+ case ts.SyntaxKind.PrefixUnaryExpression:
249
+ doc.type = n?.operator === ts.SyntaxKind.ExclamationToken ? { text: "boolean" } : { text: "number" };
250
+ break;
251
+ case ts.SyntaxKind.NumericLiteral:
252
+ doc.type = { text: "number" }
253
+ break;
254
+ case ts.SyntaxKind.NullKeyword:
255
+ doc.type = { text: "null" }
256
+ break;
257
+ case ts.SyntaxKind.ArrayLiteralExpression:
258
+ doc.type = { text: "array" }
259
+ break;
260
+ case ts.SyntaxKind.ObjectLiteralExpression:
261
+ doc.type = { text: "object" }
262
+ break;
263
+ }
264
+ return doc;
265
+ }
266
+
267
+ /**
268
+ * For `as const` and namespace/enum types
269
+ * @example class A { b = 'b' as const }
270
+ * @example class A { b = B.b }
271
+ */
272
+ export function handleWellKnownTypes(doc, node) {
273
+ if (!!node.initializer?.expression) {
274
+ const text = node?.initializer?.expression?.getText();
275
+ if (isWellKnownType(node)) {
276
+ doc.type = { text };
277
+ }
278
+ }
279
+ return doc;
280
+ }
281
+
282
+ export function handleDefaultValue(doc, node, expression) {
283
+ /**
284
+ * In case of a class field node?.initializer
285
+ * In case of a property assignment in constructor node?.expression?.right
286
+ */
287
+ const initializer = node?.initializer || expression?.right;
288
+
289
+ /** Ignore the following */
290
+ if(initializer?.kind === ts.SyntaxKind.BinaryExpression) return doc;
291
+ if(initializer?.kind === ts.SyntaxKind.ConditionalExpression) return doc;
292
+ if(initializer?.kind === ts.SyntaxKind.PropertyAccessExpression) return doc;
293
+ if(initializer?.kind === ts.SyntaxKind.CallExpression) return doc;
294
+ if(initializer?.kind === ts.SyntaxKind.ArrowFunction) return doc;
295
+
296
+ let defaultValue;
297
+ /**
298
+ * Check if value has `as const`
299
+ * @example const foo = 'foo' as const;
300
+ */
301
+ if(initializer?.kind === ts.SyntaxKind.AsExpression) {
302
+ defaultValue = initializer?.expression?.getText()
303
+ } else {
304
+ defaultValue = initializer?.getText()
305
+ }
306
+
307
+ if(defaultValue) {
308
+ doc.default = defaultValue.replace(/\s+/g, ' ').trim();
309
+ }
310
+ return doc;
311
+ }
312
+
313
+ /**
314
+ * Add TS type
315
+ * @example class Foo { bar: string = ''; }
316
+ */
317
+ export function handleExplicitType(doc, node) {
318
+ if(node.type) {
319
+ doc.type = { text: node.type.getText() }
320
+
321
+ if(node?.questionToken) {
322
+ doc.type.text += ' | undefined';
323
+ }
324
+ }
325
+
326
+ return doc;
327
+ }
328
+
329
+ /**
330
+ * if is private field
331
+ * @example class Foo { #bar = ''; }
332
+ */
333
+ export function handlePrivateMember(doc, node) {
334
+ if (ts.isPrivateIdentifier(node.name)) {
335
+ doc.privacy = 'private';
336
+ }
337
+ return doc;
338
+ }
@@ -0,0 +1,90 @@
1
+ import { getDeclarationInFile, hasIgnoreJSDoc, isCustomElementsDefineCall } from '../../utils/ast-helpers.js';
2
+ import { resolveModuleOrPackageSpecifier } from '../../utils/index.js';
3
+ import { createClass } from './creators/createClass.js';
4
+
5
+ /**
6
+ * CUSTOM-ELEMENTS-DEFINE-CALLS
7
+ *
8
+ * Analyzes calls for:
9
+ * @example customElements.define()
10
+ * @example window.customElements.define()
11
+ */
12
+ export function customElementsDefineCallsPlugin() {
13
+ let counter;
14
+ return {
15
+ name: 'CORE - CUSTOM-ELEMENTS-DEFINE-CALLS',
16
+ analyzePhase({ts, node, moduleDoc, context}){
17
+ if(node?.kind === ts.SyntaxKind.SourceFile) {
18
+ counter = 0;
19
+ }
20
+
21
+ if (hasIgnoreJSDoc(node))
22
+ return;
23
+
24
+ /**
25
+ * @example customElements.define('my-el', MyEl);
26
+ * @example window.customElements.define('my-el', MyEl);
27
+ */
28
+ if(isCustomElementsDefineCall(node)) {
29
+ const classArg = node.parent.arguments[1];
30
+ let isAnonymousClass = classArg?.kind === ts.SyntaxKind.ClassExpression;
31
+ let isUnnamed = classArg?.name === undefined;
32
+
33
+ if(isAnonymousClass) {
34
+ const klass = createClass(classArg, moduleDoc, context);
35
+
36
+ if(isUnnamed) {
37
+ klass.name = `anonymous_${counter}`;
38
+ }
39
+ moduleDoc.declarations.push(klass);
40
+ }
41
+
42
+ let elementClass;
43
+
44
+ /**
45
+ * @example customElements.define('m-e', class extends HTMLElement{})
46
+ * ^
47
+ */
48
+ if(isUnnamed) {
49
+ elementClass = `anonymous_${counter}`;
50
+ counter = counter + 1;
51
+ }
52
+
53
+ /**
54
+ * @example customElements.define('m-e', MyElement)
55
+ * ^^^^^^^^^
56
+ */
57
+ if(node?.parent?.arguments?.[1]?.text) {
58
+ elementClass = node.parent.arguments[1].text;
59
+ }
60
+
61
+ /**
62
+ * @example customElements.define('m-e', class MyElement extends HTMLElement{})
63
+ * ^^^^^^^^^
64
+ */
65
+ if(classArg?.name) {
66
+ elementClass = classArg?.name?.getText();
67
+ }
68
+
69
+ const elementTag = node.parent.arguments[0].text;
70
+
71
+ const klass = getDeclarationInFile(elementClass, node?.getSourceFile());
72
+
73
+ if (hasIgnoreJSDoc(klass))
74
+ return;
75
+
76
+ const definitionDoc = {
77
+ kind: 'custom-element-definition',
78
+ name: elementTag,
79
+ declaration: {
80
+ name: elementClass,
81
+ ...resolveModuleOrPackageSpecifier(moduleDoc, context, elementClass)
82
+ },
83
+ };
84
+
85
+ moduleDoc.exports = [...(moduleDoc.exports || []), definitionDoc];
86
+ }
87
+ }
88
+ }
89
+ }
90
+
@@ -0,0 +1,156 @@
1
+ import { getDeclarationInFile, hasIgnoreJSDoc } from '../../utils/ast-helpers.js';
2
+ import {
3
+ hasExportModifier,
4
+ hasDefaultModifier,
5
+ hasNamedExports,
6
+ isReexport,
7
+ } from '../../utils/exports.js';
8
+ import { isBareModuleSpecifier } from '../../utils/index.js';
9
+
10
+ /**
11
+ * EXPORTS
12
+ *
13
+ * Analyzes a modules exports and adds them to the moduleDoc
14
+ */
15
+ export function exportsPlugin() {
16
+ return {
17
+ name: 'CORE - EXPORTS',
18
+ analyzePhase({ts, node, moduleDoc}){
19
+ if(hasIgnoreJSDoc(node)) return;
20
+
21
+ /**
22
+ * @example export const foo = '';
23
+ */
24
+ if(hasExportModifier(node) && ts.isVariableStatement(node)) {
25
+ node?.declarationList?.declarations?.forEach(declaration => {
26
+ const _export = {
27
+ kind: 'js',
28
+ name: declaration.name.getText(),
29
+ declaration: {
30
+ name: declaration.name.getText(),
31
+ module: moduleDoc.path,
32
+ },
33
+ };
34
+
35
+ moduleDoc.exports = [...(moduleDoc.exports || []), _export];
36
+ });
37
+ }
38
+
39
+ /**
40
+ * @example export default var1;
41
+ */
42
+ if (node.kind === ts.SyntaxKind.ExportAssignment) {
43
+ const _export = {
44
+ kind: 'js',
45
+ name: 'default',
46
+ declaration: {
47
+ name: node.expression.text,
48
+ module: moduleDoc.path,
49
+ },
50
+ };
51
+ moduleDoc.exports = [...(moduleDoc.exports || []), _export];
52
+ }
53
+
54
+ if (node.kind === ts.SyntaxKind.ExportDeclaration) {
55
+
56
+ /**
57
+ * @example export { var1, var2 };
58
+ */
59
+ if (hasNamedExports(node) && !isReexport(node)) {
60
+ node.exportClause?.elements?.forEach((element) => {
61
+ if (hasIgnoreJSDoc(element) || hasIgnoreJSDoc(getDeclarationInFile(element, node.getSourceFile())))
62
+ return;
63
+
64
+ const _export = {
65
+ kind: 'js',
66
+ name: element.name.getText(),
67
+ declaration: {
68
+ name: element.propertyName?.getText() || element.name.getText(),
69
+ module: moduleDoc.path,
70
+ },
71
+ };
72
+
73
+ moduleDoc.exports = [...(moduleDoc.exports || []), _export];
74
+ });
75
+ }
76
+
77
+ /**
78
+ * @example export * from 'foo';
79
+ * @example export * from './my-module.js';
80
+ */
81
+ if (isReexport(node) && !hasNamedExports(node)) {
82
+ const _export = {
83
+ kind: 'js',
84
+ name: '*',
85
+ declaration: {
86
+ name: '*',
87
+ package: node.moduleSpecifier.getText().replace(/'/g, ''),
88
+ },
89
+ };
90
+ moduleDoc.exports = [...(moduleDoc.exports || []), _export];
91
+ }
92
+
93
+ /**
94
+ * @example export { var1, var2 } from 'foo';
95
+ * @example export { var1, var2 } from './my-module.js';
96
+ */
97
+ if (isReexport(node) && hasNamedExports(node)) {
98
+ node.exportClause?.elements?.forEach((element) => {
99
+ const _export = {
100
+ kind: 'js',
101
+ name: element.name.getText(),
102
+ declaration: {
103
+ name: element.propertyName?.getText() || element.name.getText(),
104
+ },
105
+ };
106
+
107
+ if (isBareModuleSpecifier(node.moduleSpecifier.getText())) {
108
+ _export.declaration.package = node.moduleSpecifier.getText().replace(/'/g, '');
109
+ } else {
110
+ _export.declaration.module = node.moduleSpecifier.getText().replace(/'/g, '');
111
+ }
112
+
113
+ moduleDoc.exports = [...(moduleDoc.exports || []), _export];
114
+ });
115
+ }
116
+ }
117
+
118
+ /**
119
+ * @example export function foo() {}
120
+ */
121
+ if (node.kind === ts.SyntaxKind.FunctionDeclaration) {
122
+ if (hasExportModifier(node)) {
123
+ const isDefault = hasDefaultModifier(node);
124
+ const _export = {
125
+ kind: 'js',
126
+ name: isDefault ? 'default' : node.name?.getText() || '',
127
+ declaration: {
128
+ name: node.name?.getText() || '',
129
+ module: moduleDoc.path,
130
+ },
131
+ };
132
+
133
+ moduleDoc.exports = [...(moduleDoc.exports || []), _export];
134
+ }
135
+ }
136
+
137
+ /**
138
+ * @example export class Class1 {}
139
+ */
140
+ if (node.kind === ts.SyntaxKind.ClassDeclaration) {
141
+ if (hasExportModifier(node)) {
142
+ const isDefault = hasDefaultModifier(node);
143
+ const _export = {
144
+ kind: 'js',
145
+ name: isDefault ? 'default' : node?.name?.text || '',
146
+ declaration: {
147
+ name: node?.name?.text || '',
148
+ module: moduleDoc.path,
149
+ },
150
+ };
151
+ moduleDoc.exports = [...(moduleDoc.exports || []), _export];
152
+ }
153
+ }
154
+ }
155
+ }
156
+ }
@@ -0,0 +1,24 @@
1
+ import { createFunctionLike } from './creators/createFunctionLike.js';
2
+ import { isMixin } from '../../utils/mixins.js';
3
+
4
+ /**
5
+ * functionLikePlugin
6
+ *
7
+ * handles functionLikes such as class methods and functions
8
+ * does NOT handle arrow functions
9
+ */
10
+ export function functionLikePlugin() {
11
+ return {
12
+ name: 'CORE - FUNCTION-LIKE',
13
+ analyzePhase({ts, node, moduleDoc}){
14
+ switch(node.kind) {
15
+ case ts.SyntaxKind.FunctionDeclaration:
16
+ if(!isMixin(node)) {
17
+ const functionLike = createFunctionLike(node);
18
+ moduleDoc.declarations.push(functionLike);
19
+ }
20
+ break;
21
+ }
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,29 @@
1
+ import { extractMixinNodes, isMixin } from '../../utils/mixins.js';
2
+ import { createMixin } from './creators/createMixin.js';
3
+
4
+ /**
5
+ * mixinPlugin
6
+ *
7
+ * handles mixins
8
+ */
9
+ export function mixinPlugin() {
10
+ return {
11
+ name: 'CORE - MIXINS',
12
+ analyzePhase({ts, node, moduleDoc, context}){
13
+ switch(node.kind) {
14
+ case ts.SyntaxKind.VariableStatement:
15
+ case ts.SyntaxKind.FunctionDeclaration:
16
+ /**
17
+ * Try to extract mixin nodes, if its a mixin
18
+ */
19
+ if(isMixin(node)) {
20
+ const { mixinFunction, mixinClass } = extractMixinNodes(node);
21
+ let mixin = createMixin(mixinFunction, mixinClass, moduleDoc, context);
22
+ moduleDoc.declarations.push(mixin);
23
+ }
24
+ break;
25
+ }
26
+ }
27
+ }
28
+ }
29
+