@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
package/CHANGELOG.md CHANGED
@@ -3,6 +3,25 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [2.16.0-rc.1](https://github.com/UI5/webcomponents/compare/v2.16.0-rc.0...v2.16.0-rc.1) (2025-10-16)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * apply @custom-elements-manifest/analyzer patch ([#12441](https://github.com/UI5/webcomponents/issues/12441)) ([a9ec6e2](https://github.com/UI5/webcomponents/commit/a9ec6e217bb59dbffb0db79c6008cecf77bc0649))
12
+
13
+
14
+
15
+
16
+
17
+ # [2.16.0-rc.0](https://github.com/UI5/webcomponents/compare/v2.15.0...v2.16.0-rc.0) (2025-10-09)
18
+
19
+ **Note:** Version bump only for package @ui5/webcomponents-tools
20
+
21
+
22
+
23
+
24
+
6
25
  # [2.15.0](https://github.com/UI5/webcomponents/compare/v2.15.0-rc.3...v2.15.0) (2025-10-03)
7
26
 
8
27
  **Note:** Version bump only for package @ui5/webcomponents-tools
@@ -80,7 +80,6 @@ const getScripts = (options) => {
80
80
  UI5_CEM_MODE: options.dev,
81
81
  UI5_TS: `${tsOption}`,
82
82
  CYPRESS_COVERAGE: !!(options.internal?.cypress_code_coverage),
83
- CYPRESS_UI5_ACC: !!(options.internal?.cypress_acc_tests),
84
83
  },
85
84
  clean: {
86
85
  "default": "ui5nps clean.generated clean.dist scope.testPages.clean",
package/lib/cem/cem.js CHANGED
@@ -1,4 +1,4 @@
1
- const cemCLI = require("@custom-elements-manifest/analyzer/cli")
1
+ const cemCLI = require("./patch/@custom-elements-manifest/analyzer/cli.js")
2
2
 
3
3
  const main = async argv => {
4
4
  const patchedArgv = argv.slice(2);
@@ -0,0 +1,128 @@
1
+ #!/usr/bin/env node
2
+
3
+ import ts from 'typescript';
4
+ import path from 'path';
5
+ // Patch: Custom patch to not merge child parent privacy/type
6
+ // https://github.com/open-wc/custom-elements-manifest/pull/300
7
+ import { globby } from 'globby';
8
+ import fs from 'fs';
9
+ import commandLineArgs from 'command-line-args';
10
+ import chokidar from 'chokidar';
11
+ import debounce from 'debounce';
12
+
13
+ import { create } from './src/create.js';
14
+ import {
15
+ getUserConfig,
16
+ getCliConfig,
17
+ addFrameworkPlugins,
18
+ addCustomElementsPropertyToPackageJson,
19
+ mergeGlobsAndExcludes,
20
+ timestamp,
21
+ DEFAULTS,
22
+ MENU,
23
+ } from './src/utils/cli-helpers.js';
24
+ import { findExternalManifests } from './src/utils/find-external-manifests.js';
25
+
26
+ /**
27
+ * @param {{argv:string[]; cwd: string; noWrite:boolean}} [opts]
28
+ */
29
+ export async function cli({ argv = process.argv, cwd = process.cwd(), noWrite } = {}) {
30
+ const mainDefinitions = [{ name: 'command', defaultOption: true }];
31
+ const mainOptions = commandLineArgs(mainDefinitions, { stopAtFirstUnknown: true, argv });
32
+ const cliArgs = mainOptions._unknown || [];
33
+
34
+ if (mainOptions.command === 'analyze') {
35
+ const { config: configPath, ...cliConfig } = getCliConfig(cliArgs);
36
+ const userConfig = await getUserConfig(configPath, cwd);
37
+
38
+ /**
39
+ * Merged config options
40
+ * Command line options override userConfig options
41
+ */
42
+ const mergedOptions = { ...DEFAULTS, ...userConfig, ...cliConfig };
43
+ const merged = mergeGlobsAndExcludes(DEFAULTS, userConfig, cliConfig);
44
+ async function run() {
45
+ const globs = await globby(merged, { cwd });
46
+ const modules = userConfig?.overrideModuleCreation
47
+ ? userConfig.overrideModuleCreation({ ts, globs })
48
+ : globs.map((glob) => {
49
+ const fullPath = path.resolve(cwd, glob);
50
+ const source = fs.readFileSync(fullPath).toString();
51
+
52
+ return ts.createSourceFile(glob, source, ts.ScriptTarget.ES2015, true);
53
+ });
54
+
55
+ let thirdPartyCEMs = [];
56
+ if (mergedOptions?.dependencies) {
57
+ try {
58
+ const fullPathGlobs = globs.map(glob => path.resolve(cwd, glob));
59
+ thirdPartyCEMs = await findExternalManifests(fullPathGlobs, {basePath: cwd});
60
+ } catch (e) {
61
+ if (mergedOptions.dev) console.log(`Failed to add third party CEMs. \n\n${e.stack}`);
62
+ }
63
+ }
64
+
65
+ let plugins = await addFrameworkPlugins(mergedOptions);
66
+ plugins = [...plugins, ...(userConfig?.plugins || [])];
67
+
68
+ const context = { dev: mergedOptions.dev, thirdPartyCEMs };
69
+
70
+ /**
71
+ * Create the manifest
72
+ */
73
+ const customElementsManifest = create({modules, plugins, context});
74
+
75
+ if (mergedOptions.dev) {
76
+ console.log(JSON.stringify(customElementsManifest, null, 2));
77
+ }
78
+
79
+ if(!noWrite) {
80
+ const outdir = path.join(cwd, mergedOptions.outdir);
81
+ if (!fs.existsSync(outdir)) {
82
+ fs.mkdirSync(outdir, { recursive: true });
83
+ }
84
+ fs.writeFileSync(
85
+ path.join(outdir, 'custom-elements.json'),
86
+ `${JSON.stringify(customElementsManifest, null, 2)}\n`,
87
+ );
88
+ }
89
+
90
+ if (!mergedOptions.quiet) {
91
+ console.log(`[${timestamp()}] @custom-elements-manifest/analyzer: Created new manifest.`);
92
+ }
93
+
94
+ return customElementsManifest;
95
+ }
96
+ /** The manifest that will be returned for programmatic calls of cli */
97
+ const manifest = await run();
98
+
99
+ /**
100
+ * Watch mode
101
+ */
102
+ if (mergedOptions.watch) {
103
+ const fileWatcher = chokidar.watch(merged);
104
+
105
+ const onChange = debounce(run, 100);
106
+
107
+ fileWatcher.addListener('add', onChange);
108
+ fileWatcher.addListener('change', onChange);
109
+ fileWatcher.addListener('unlink', onChange);
110
+ }
111
+
112
+ try {
113
+ if (mergedOptions.packagejson) {
114
+ addCustomElementsPropertyToPackageJson(mergedOptions.outdir);
115
+ }
116
+ } catch {
117
+ console.log(
118
+ `Could not add 'customElements' property to ${cwd}${
119
+ path.sep
120
+ }package.json. \nAdding this property helps tooling locate your Custom Elements Manifest. Please consider adding it yourself, or file an issue if you think this is a bug.\nhttps://www.github.com/open-wc/custom-elements-manifest`,
121
+ );
122
+ }
123
+
124
+ return manifest;
125
+ } else {
126
+ console.log(MENU);
127
+ }
128
+ }
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@custom-elements-manifest/analyzer",
3
+ "version": "0.10.10",
4
+ "description": "",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "types": "index.d.ts",
8
+ "bin": {
9
+ "custom-elements-manifest": "./cem.js",
10
+ "cem": "./cem.js"
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/open-wc/custom-elements-manifest.git",
15
+ "directory": "packages/analyzer"
16
+ },
17
+ "author": "open-wc",
18
+ "homepage": "https://github.com/open-wc/custom-elements-manifest",
19
+ "bugs": {
20
+ "url": "https://github.com/open-wc/custom-elements-manifest"
21
+ },
22
+ "main": "index.js",
23
+ "scripts": {
24
+ "prepublishOnly": "npm test && npm run build:browser",
25
+ "start": "nodemon --ignore './custom-elements.json' cem.js analyze --dev --fast",
26
+ "test": "asdgf",
27
+ "build:browser": "esbuild src/browser-entrypoint.js --bundle --format=esm --outfile=browser/index.js",
28
+ "test:watch": "watchexec -w src -w test npm test",
29
+ "update-fixtures": "node scripts/update-version.js --version 1.0.0"
30
+ },
31
+ "keywords": [
32
+ "custom-elements",
33
+ "custom-elements-json",
34
+ "custom-elements-manifest",
35
+ "customelements",
36
+ "webcomponents",
37
+ "customelementsjson",
38
+ "customelementsmanifest"
39
+ ],
40
+ "dependencies": {
41
+ "@custom-elements-manifest/find-dependencies": "^0.0.6",
42
+ "@github/catalyst": "^1.6.0",
43
+ "@web/config-loader": "0.1.3",
44
+ "chokidar": "3.5.2",
45
+ "command-line-args": "5.1.2",
46
+ "comment-parser": "1.2.4",
47
+ "custom-elements-manifest": "1.0.0",
48
+ "debounce": "1.2.1",
49
+ "globby": "11.0.4",
50
+ "typescript": "~5.4.2"
51
+ },
52
+ "devDependencies": {},
53
+ "contributors": [
54
+ "Pascal Schilp <pascalschilp@gmail.com>",
55
+ "Benny Powers <web@bennypowers.com>",
56
+ "Matias Huhta <huhta.matias@gmail.com>"
57
+ ],
58
+ "customElements": "custom-elements.json"
59
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * This file is the entrypoint for rollup to correctly bundle the analyzer for the browser.
3
+ * Do not use directly, but import from ./browser/index.js
4
+ */
5
+
6
+ import ts from 'typescript';
7
+
8
+ import { create } from './create.js';
9
+ import { catalystPlugin } from './features/framework-plugins/catalyst/catalyst.js';
10
+ import { catalystPlugin2 } from './features/framework-plugins/catalyst-major-2/catalyst.js';
11
+ import { stencilPlugin } from './features/framework-plugins/stencil/stencil.js';
12
+ import { litPlugin } from './features/framework-plugins/lit/lit.js';
13
+ import { fastPlugin } from './features/framework-plugins/fast/fast.js';
14
+
15
+ export {
16
+ ts,
17
+ create,
18
+ catalystPlugin,
19
+ catalystPlugin2,
20
+ stencilPlugin,
21
+ litPlugin,
22
+ fastPlugin
23
+ };
@@ -0,0 +1,117 @@
1
+ import ts from 'typescript';
2
+ import { FEATURES } from './features/index.js';
3
+ import { withErrorHandling } from './utils/index.js';
4
+
5
+ /**
6
+ * CORE
7
+ *
8
+ * This function is the core of the analyzer. It takes an array of ts sourceFiles, and creates a
9
+ * custom elements manifest.
10
+ */
11
+ export function create({modules, plugins = [], context = {dev:false}}) {
12
+ const customElementsManifest = {
13
+ schemaVersion: '1.0.0',
14
+ readme: '',
15
+ modules: [],
16
+ };
17
+
18
+ const { dev } = context;
19
+
20
+ const mergedPlugins = [
21
+ ...FEATURES,
22
+ ...plugins,
23
+ ];
24
+
25
+ if(dev) console.log('[INITIALIZE PLUGINS]');
26
+ mergedPlugins.forEach(({name, initialize}) => {
27
+ withErrorHandling(name, () => {
28
+ initialize?.({ts, customElementsManifest, context});
29
+ });
30
+ });
31
+
32
+ modules.forEach(currModule => {
33
+ if(dev) console.log('[COLLECT PHASE]: ', currModule.fileName);
34
+ /**
35
+ * COLLECT PHASE
36
+ * First pass through all modules. Can be used to gather imports, exports, types, default values,
37
+ * which you may need to know the existence of in a later phase.
38
+ */
39
+ collect(currModule, context, mergedPlugins);
40
+ });
41
+
42
+ modules.forEach(currModule => {
43
+ if(dev) console.log('[ANALYZE PHASE]: ', currModule.fileName);
44
+ const moduleDoc = {
45
+ kind: "javascript-module",
46
+ path: currModule.fileName,
47
+ declarations: [],
48
+ exports: []
49
+ };
50
+
51
+ /**
52
+ * ANALYZE PHASE
53
+ * Go through the AST of every separate module, and gather as much as information as we can
54
+ * This includes a modules imports, which are not specified in custom-elements.json, but are
55
+ * required for the LINK PHASE, and deleted when processed
56
+ */
57
+ analyze(currModule, moduleDoc, context, mergedPlugins);
58
+ customElementsManifest.modules.push(moduleDoc);
59
+
60
+ if(dev) console.log('[MODULE LINK PHASE]: ', currModule.fileName);
61
+ /**
62
+ * LINK PHASE
63
+ * All information for a module has been gathered, now we can link information together. Like:
64
+ * - Finding a CustomElement's tagname by finding its customElements.define() call (or 'export')
65
+ * - Applying inheritance to classes (adding `inheritedFrom` properties/attrs/events/methods)
66
+ */
67
+ mergedPlugins.forEach(({name, moduleLinkPhase}) => {
68
+ withErrorHandling(name, () => {
69
+ moduleLinkPhase?.({ts, moduleDoc, context});
70
+ });
71
+ });
72
+ });
73
+
74
+ if(dev) console.log('[PACKAGE LINK PHASE]');
75
+ /**
76
+ * PACKAGE LINK PHASE
77
+ * All modules have now been parsed, we can now link information from across modules together
78
+ * - Link classes to their definitions etc
79
+ * - Match tagNames for classDocs
80
+ * - Apply inheritance
81
+ */
82
+ mergedPlugins.forEach(({name, packageLinkPhase}) => {
83
+ withErrorHandling(name, () => {
84
+ packageLinkPhase?.({customElementsManifest, context});
85
+ });
86
+ });
87
+
88
+ return customElementsManifest;
89
+ }
90
+
91
+ function collect(source, context, mergedPlugins) {
92
+ visitNode(source);
93
+
94
+ function visitNode(node) {
95
+ mergedPlugins.forEach(({name, collectPhase}) => {
96
+ withErrorHandling(name, () => {
97
+ collectPhase?.({ts, node, context});
98
+ });
99
+ });
100
+
101
+ ts.forEachChild(node, visitNode);
102
+ }
103
+ }
104
+
105
+ function analyze(source, moduleDoc, context, mergedPlugins) {
106
+ visitNode(source);
107
+
108
+ function visitNode(node) {
109
+ mergedPlugins.forEach(({name, analyzePhase}) => {
110
+ withErrorHandling(name, () => {
111
+ analyzePhase?.({ts, node, moduleDoc, context});
112
+ });
113
+ });
114
+
115
+ ts.forEachChild(node, visitNode);
116
+ }
117
+ }
@@ -0,0 +1,26 @@
1
+ import { hasInitializer } from '../../utils/ast-helpers.js';
2
+ import { isMixin } from '../../utils/mixins.js';
3
+ import { createArrowFunction } from './creators/createArrowFunction.js';
4
+
5
+
6
+ /**
7
+ * arrowFunctionPlugin
8
+ *
9
+ * handles arrow functions
10
+ */
11
+ export function arrowFunctionPlugin() {
12
+ return {
13
+ name: 'CORE - ARROW-FUNCTION',
14
+ analyzePhase({ts, node, moduleDoc}){
15
+ switch(node.kind) {
16
+ case ts.SyntaxKind.VariableStatement:
17
+ if(!isMixin(node) && hasInitializer(node)) {
18
+ const functionLike = createArrowFunction(node);
19
+ moduleDoc.declarations.push(functionLike);
20
+ }
21
+ break;
22
+ }
23
+ }
24
+ }
25
+ }
26
+
@@ -0,0 +1,157 @@
1
+ import { parse } from 'comment-parser';
2
+ import { handleJsDocType, normalizeDescription } from '../../utils/jsdoc.js';
3
+ import { has, safe } from '../../utils/index.js';
4
+
5
+ /**
6
+ * CLASS-JSDOC
7
+ *
8
+ * Deals with any JSDoc above a class
9
+ */
10
+ export function classJsDocPlugin() {
11
+ return {
12
+ name: 'CORE - CLASS-JSDOC',
13
+ analyzePhase({ts, node, moduleDoc}){
14
+ switch (node.kind) {
15
+ case ts.SyntaxKind.ClassDeclaration:
16
+ const className = node?.name?.getText();
17
+ const classDoc = moduleDoc?.declarations?.find(declaration => declaration.name === className);
18
+
19
+ /**
20
+ * Because we use a bunch of 'non-standard' JSDoc annotations, TS doesn't recognize most of them.
21
+ * Instead we use `comment-parser` to parse the JSDoc.
22
+ *
23
+ * Loops through each JSDoc (yes, there can be multiple) above a class, and parses every JSDoc annotation
24
+ *
25
+ * Checks to see if the item is already in the classDoc, and if so merge and overwrite (JSDoc takes precedence)
26
+ */
27
+ node?.jsDoc?.forEach(jsDoc => {
28
+ const parsed = parse(jsDoc?.getFullText());
29
+ parsed?.forEach(parsedJsDoc => {
30
+
31
+ /**
32
+ * If any of the tags is a `@typedef`, we ignore it; this JSDoc comment may be above a class,
33
+ * it probably doesnt _belong_ to the class, but something else in the file
34
+ */
35
+ if(parsedJsDoc?.tags?.some(tag => tag?.tag === 'typedef')) return;
36
+
37
+ parsedJsDoc?.tags?.forEach(jsDoc => {
38
+ switch(jsDoc.tag) {
39
+ case 'attr':
40
+ case 'attribute':
41
+ const attributeAlreadyExists = classDoc?.attributes?.find(attr => attr.name === jsDoc.name);
42
+ let attributeDoc = attributeAlreadyExists || {};
43
+ attributeDoc = handleClassJsDoc(attributeDoc, jsDoc);
44
+ if(!attributeAlreadyExists) {
45
+ classDoc.attributes.push(attributeDoc);
46
+ }
47
+ break;
48
+ case 'prop':
49
+ case 'property':
50
+ const fieldAlreadyExists = classDoc?.members?.find(member => member.name === jsDoc.name);
51
+ let fieldDoc = fieldAlreadyExists || {};
52
+ fieldDoc = handleClassJsDoc(fieldDoc, jsDoc);
53
+ fieldDoc.kind = 'field';
54
+ if(!fieldAlreadyExists) {
55
+ classDoc.members.push(fieldDoc);
56
+ }
57
+ break;
58
+ case 'fires':
59
+ case 'event':
60
+ const eventAlreadyExists = classDoc?.events?.find(event => event.name === jsDoc.name);
61
+ let eventDoc = eventAlreadyExists || {};
62
+ eventDoc = handleClassJsDoc(eventDoc, jsDoc);
63
+ delete eventDoc.privacy;
64
+ if(!eventAlreadyExists) {
65
+ classDoc.events.push(eventDoc);
66
+ }
67
+ break;
68
+ case 'csspart':
69
+ case 'part':
70
+ let cssPartDoc = {};
71
+ cssPartDoc = handleClassJsDoc(cssPartDoc, jsDoc);
72
+ classDoc.cssParts.push(cssPartDoc);
73
+ break;
74
+ case 'cssprop':
75
+ case 'cssproperty':
76
+ let cssPropertyDoc = {};
77
+ cssPropertyDoc = handleClassJsDoc(cssPropertyDoc, jsDoc);
78
+ classDoc.cssProperties.push(cssPropertyDoc);
79
+ break;
80
+ case 'slot':
81
+ let slotDoc = {};
82
+ slotDoc = handleClassJsDoc(slotDoc, jsDoc);
83
+ classDoc.slots.push(slotDoc);
84
+ break;
85
+ case 'tag':
86
+ case 'tagname':
87
+ case 'element':
88
+ case 'customElement':
89
+ case 'customelement':
90
+ classDoc.tagName = jsDoc?.name || '';
91
+ classDoc.customElement = true;
92
+ break;
93
+ case 'cssState':
94
+ case 'cssstate':
95
+ let statePropertyDoc = {};
96
+ statePropertyDoc = handleClassJsDoc(statePropertyDoc, jsDoc);
97
+ classDoc.cssStates.push(statePropertyDoc);
98
+ break;
99
+ case 'deprecated':
100
+ classDoc.deprecated = jsDoc?.name ? `${jsDoc.name} ${jsDoc?.description}`.trim() : "true";
101
+ break;
102
+ }
103
+ })
104
+ });
105
+
106
+ /**
107
+ * Description
108
+ */
109
+ if(jsDoc?.comment) {
110
+ if(has(jsDoc?.comment)) {
111
+ classDoc.description = jsDoc.comment.map(com => `${safe(() => com?.name?.getText()) ?? ''}${com.text}`).join('');
112
+ } else {
113
+ classDoc.description = normalizeDescription(jsDoc.comment);
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Comment-parse doesn't handle annotations with only a description correctly, for example:
119
+ * @summary foo bar
120
+ * will output only 'bar' as the description.
121
+ *
122
+ * Instead, we use TS for this JSDoc annotation.
123
+ */
124
+ jsDoc?.tags?.forEach(tag => {
125
+ switch(safe(() => tag?.tagName?.getText())) {
126
+ case 'summary':
127
+ classDoc.summary = tag?.comment;
128
+ break;
129
+ }
130
+ });
131
+ });
132
+
133
+ break;
134
+ }
135
+ }
136
+ }
137
+ }
138
+
139
+ function handleClassJsDoc(doc, tag) {
140
+ if(tag?.type) {
141
+ doc.type = { text: handleJsDocType(tag.type) }
142
+ }
143
+
144
+ if(tag?.description) {
145
+ doc.description = normalizeDescription(tag.description);
146
+ }
147
+
148
+ if(tag?.name) {
149
+ doc.name = tag.name === '-' ? '' : tag.name;
150
+ }
151
+
152
+ if(tag?.default) {
153
+ doc.default = tag.default;
154
+ }
155
+
156
+ return doc;
157
+ }
@@ -0,0 +1,20 @@
1
+ import { createClass } from './creators/createClass.js';
2
+
3
+ /**
4
+ * classPlugin
5
+ *
6
+ * handles classes
7
+ */
8
+ export function classPlugin() {
9
+ return {
10
+ name: 'CORE - CLASSES',
11
+ analyzePhase({ts, node, moduleDoc, context}){
12
+ switch(node.kind) {
13
+ case ts.SyntaxKind.ClassDeclaration:
14
+ const klass = createClass(node, moduleDoc, context);
15
+ moduleDoc.declarations.push(klass);
16
+ break;
17
+ }
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,17 @@
1
+ import ts from 'typescript';
2
+ import { handleParametersAndReturnType } from './createFunctionLike.js';
3
+ import { handleJsDoc } from './handlers.js';
4
+
5
+ export function createArrowFunction(node) {
6
+ const arrowFunction = node?.declarationList?.declarations?.find(declaration => ts.SyntaxKind.ArrowFunction === declaration?.initializer?.kind);
7
+
8
+ let functionLikeTemplate = {
9
+ kind: 'function',
10
+ name: arrowFunction?.name?.getText() || '',
11
+ };
12
+
13
+ functionLikeTemplate = handleParametersAndReturnType(functionLikeTemplate, arrowFunction?.initializer);
14
+ functionLikeTemplate = handleJsDoc(functionLikeTemplate, node);
15
+
16
+ return functionLikeTemplate;
17
+ }
@@ -0,0 +1,24 @@
1
+ export function createAttribute(node) {
2
+ const attributeTemplate = {
3
+ name: node?.text || ''
4
+ }
5
+ return attributeTemplate;
6
+ }
7
+
8
+ export function createAttributeFromField(field) {
9
+ const attribute = {
10
+ ...field,
11
+ fieldName: field.name
12
+ }
13
+
14
+ /**
15
+ * Delete the following properties because they don't exist on a attributeDoc
16
+ */
17
+ delete attribute.kind;
18
+ delete attribute.static;
19
+ delete attribute.privacy;
20
+ delete attribute.reflects;
21
+ delete attribute.resolveInitializer;
22
+
23
+ return attribute;
24
+ }