@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
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
|
@@ -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
|
+
|
package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/class-jsdoc.js
ADDED
|
@@ -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
|
+
}
|
package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/classes.js
ADDED
|
@@ -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
|
+
}
|