@ui5/webcomponents-tools 0.0.0-b132dd7b9 → 0.0.0-b3a4f8020

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 (96) hide show
  1. package/CHANGELOG.md +501 -0
  2. package/LICENSE.txt +201 -0
  3. package/README.md +7 -7
  4. package/bin/dev.js +10 -4
  5. package/bin/ui5nps.js +301 -0
  6. package/components-package/nps.js +97 -94
  7. package/components-package/wdio.js +8 -2
  8. package/icons-collection/nps.js +30 -21
  9. package/lib/amd-to-es6/index.js +17 -10
  10. package/lib/cem/cem.js +16 -0
  11. package/lib/cem/custom-elements-manifest.config.mjs +56 -4
  12. package/lib/cem/merge.mjs +220 -0
  13. package/lib/cem/patch/@custom-elements-manifest/analyzer/cli.js +128 -0
  14. package/lib/cem/patch/@custom-elements-manifest/analyzer/package.json +59 -0
  15. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/browser-entrypoint.js +23 -0
  16. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/create.js +117 -0
  17. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/arrow-function.js +26 -0
  18. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/class-jsdoc.js +157 -0
  19. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/classes.js +20 -0
  20. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createArrowFunction.js +17 -0
  21. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createAttribute.js +24 -0
  22. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createClass.js +301 -0
  23. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createClassField.js +26 -0
  24. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createFunctionLike.js +73 -0
  25. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createMixin.js +33 -0
  26. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/createVariable.js +22 -0
  27. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/creators/handlers.js +338 -0
  28. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/custom-elements-define-calls.js +90 -0
  29. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/exports.js +156 -0
  30. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/function-like.js +24 -0
  31. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/mixins.js +29 -0
  32. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/reexported-wrapped-mixin-exports.js +84 -0
  33. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/analyse-phase/variables.js +34 -0
  34. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/collect-phase/collect-imports.js +101 -0
  35. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/catalyst/catalyst.js +11 -0
  36. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/catalyst/controller.js +34 -0
  37. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/catalyst-major-2/catalyst.js +11 -0
  38. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/catalyst-major-2/controller.js +34 -0
  39. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/decorators/attr.js +53 -0
  40. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/decorators/custom-element-decorator.js +36 -0
  41. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/fast/fast.js +7 -0
  42. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/lit.js +13 -0
  43. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/member-denylist.js +21 -0
  44. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/method-denylist.js +20 -0
  45. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/property-decorator.js +94 -0
  46. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/static-properties.js +121 -0
  47. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/utils.js +66 -0
  48. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/framework-plugins/stencil/stencil.js +129 -0
  49. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/index.js +80 -0
  50. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/link-phase/cleanup-classes.js +25 -0
  51. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/link-phase/field-denylist.js +22 -0
  52. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/link-phase/method-denylist.js +25 -0
  53. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/post-processing/apply-inheritance.js +78 -0
  54. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/post-processing/is-custom-element.js +34 -0
  55. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/post-processing/link-class-to-tagname.js +27 -0
  56. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/post-processing/remove-unexported-declarations.js +23 -0
  57. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/features/post-processing/resolve-initializers.js +52 -0
  58. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/ast-helpers.js +186 -0
  59. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/cli-helpers.js +164 -0
  60. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/exports.js +44 -0
  61. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/find-external-manifests.js +67 -0
  62. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/imports.js +25 -0
  63. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/index.js +71 -0
  64. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/jsdoc.js +19 -0
  65. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/manifest-helpers.js +194 -0
  66. package/lib/cem/patch/@custom-elements-manifest/analyzer/src/utils/mixins.js +112 -0
  67. package/lib/cem/schema-internal.json +41 -1
  68. package/lib/cem/schema.json +41 -1
  69. package/lib/cem/types-internal.d.ts +32 -2
  70. package/lib/cem/types.d.ts +32 -2
  71. package/lib/cem/utils.mjs +13 -3
  72. package/lib/cem/validate.js +61 -47
  73. package/lib/chokidar/chokidar.js +28 -0
  74. package/lib/copy-and-watch/index.js +110 -97
  75. package/lib/copy-list/index.js +18 -10
  76. package/lib/create-icons/index.js +19 -15
  77. package/lib/create-illustrations/index.js +57 -29
  78. package/lib/create-new-component/index.js +5 -3
  79. package/lib/css-processors/css-processor-components.mjs +85 -60
  80. package/lib/css-processors/css-processor-themes.mjs +105 -57
  81. package/lib/css-processors/postcss-plugin.mjs +153 -0
  82. package/lib/css-processors/scope-variables.mjs +26 -1
  83. package/lib/css-processors/shared.mjs +8 -17
  84. package/lib/dev-server/dev-server.mjs +23 -11
  85. package/lib/eslint/eslint.js +44 -0
  86. package/lib/generate-js-imports/illustrations.js +55 -54
  87. package/lib/generate-json-imports/i18n.js +22 -11
  88. package/lib/generate-json-imports/themes.js +24 -12
  89. package/lib/i18n/defaults.js +14 -7
  90. package/lib/i18n/toJSON.js +40 -12
  91. package/lib/icons-hash/icons-hash.mjs +149 -0
  92. package/lib/remove-dev-mode/remove-dev-mode.mjs +38 -24
  93. package/lib/rimraf/rimraf.js +31 -0
  94. package/lib/test-runner/test-runner.js +56 -48
  95. package/lib/vite-bundler/vite-bundler.mjs +35 -0
  96. package/package.json +15 -14
@@ -0,0 +1,220 @@
1
+ import { pathToFileURL } from "url";
2
+ import path from "path";
3
+ import { createRequire } from 'module';
4
+ import { readFile, writeFile } from "fs/promises";
5
+
6
+ const require = createRequire(import.meta.url);
7
+
8
+ const UI5_BASE_CLASS = "UI5Element";
9
+
10
+ const main = async (argv) => {
11
+ let customElementsPath = null;
12
+ const CACHED_CEMS = new Map();
13
+ const DECLARATION_PACKAGE = new WeakMap();
14
+ const DECLARATION_MODULE = new WeakMap();
15
+
16
+ function removeInheritedFrom(obj) {
17
+ if (obj === null || typeof obj !== 'object') {
18
+ return obj;
19
+ }
20
+
21
+ if (Array.isArray(obj)) {
22
+ return obj.map(item => removeInheritedFrom(item));
23
+ }
24
+
25
+ const result = {};
26
+ for (const [key, value] of Object.entries(obj)) {
27
+ if (key === 'inheritedFrom') {
28
+ continue;
29
+ }
30
+ result[key] = removeInheritedFrom(value);
31
+ }
32
+ return result;
33
+ }
34
+
35
+ async function readPackageJson(filePath) {
36
+ try {
37
+ return JSON.parse(await readFile(filePath, "utf-8"));
38
+ } catch (error) {
39
+ throw new Error(`Failed to read package.json at ${filePath}: ${error.message}`);
40
+ }
41
+ }
42
+
43
+ async function loadPackageJson(depName) {
44
+ try {
45
+ // First try the standard require method (works when exports includes package.json)
46
+ const pkg = require(`${depName}/package.json`);
47
+ const pkgPath = require.resolve(`${depName}/package.json`);
48
+ return { path: path.dirname(pkgPath), pkg };
49
+ } catch (e) {
50
+ // If that fails, resolve the package path and read package.json directly
51
+ try {
52
+ const packagePath = require.resolve(depName);
53
+ let currentDir = path.dirname(packagePath);
54
+
55
+ // Navigate up to find package.json (the resolved path might be deep in dist/ or similar)
56
+ while (currentDir !== path.parse(currentDir).root) {
57
+ try {
58
+ const pkgPath = path.join(currentDir, 'package.json');
59
+ const content = await readFile(pkgPath, 'utf-8');
60
+ const pkg = JSON.parse(content);
61
+
62
+ // Verify this is the correct package.json by checking the name
63
+ if (pkg.name === depName) {
64
+ return { path: currentDir, pkg };
65
+ }
66
+ } catch {
67
+ // Continue searching up the directory tree
68
+ }
69
+ currentDir = path.dirname(currentDir);
70
+ }
71
+ } catch (resolveError) {
72
+ // console.warn(`Could not resolve ${depName}:`, resolveError.message);
73
+ }
74
+ return null;
75
+ }
76
+ }
77
+
78
+ async function collectThirdPartyCem() {
79
+ const packageJSONPath = path.resolve(process.cwd(), "package.json");
80
+ const packageJSON = await readPackageJson(packageJSONPath);
81
+
82
+ const dependencyKeys = Object.keys(packageJSON).filter(key => key.toLowerCase().includes("dependencies"));
83
+ const dependencies = dependencyKeys.flatMap(key => Object.keys(packageJSON[key]));
84
+
85
+ const thirdPartCEM = (await Promise.all(dependencies.map(async dep => {
86
+ const result = await loadPackageJson(dep);
87
+ if (!result?.pkg?.customElements) return null;
88
+
89
+ return {
90
+ path: result.path,
91
+ name: dep,
92
+ cem: result.pkg.customElements
93
+ };
94
+ }))).filter(Boolean);
95
+
96
+ await Promise.all(thirdPartCEM.map(async dep => {
97
+ const cemPath = path.resolve(dep.path, dep.cem);
98
+ try {
99
+ const cemContent = JSON.parse(await readFile(cemPath, "utf-8"));
100
+ CACHED_CEMS.set(dep.name, cemContent);
101
+ } catch (error) {
102
+ console.warn(`Failed to read CEM for ${dep.name} from ${cemPath}: ${error.message}`);
103
+ }
104
+ }));
105
+ }
106
+
107
+ async function readCurrentCEM() {
108
+ const packageJSONPath = path.resolve(process.cwd(), "package.json");
109
+ const packageJSON = await readPackageJson(packageJSONPath);
110
+
111
+ if (!packageJSON?.customElements) {
112
+ return null;
113
+ }
114
+
115
+ customElementsPath = packageJSON.customElements;
116
+ const cemPath = path.resolve(process.cwd(), customElementsPath);
117
+
118
+ try {
119
+ const cemContent = JSON.parse(await readFile(cemPath, "utf-8"));
120
+ CACHED_CEMS.set(packageJSON.name, cemContent);
121
+ return cemContent;
122
+ } catch (error) {
123
+ throw new Error(`Failed to read CEM from ${cemPath}: ${error.message}`);
124
+ }
125
+ }
126
+
127
+ async function resolveReference(ref) {
128
+ const pkg = CACHED_CEMS.get(ref.package);
129
+
130
+ if (!pkg) {
131
+ return null;
132
+ }
133
+
134
+ const mod = (pkg.modules || []).find(m => m.path === ref.module);
135
+
136
+ if (!mod) {
137
+ return null;
138
+ }
139
+
140
+ const declaration = (mod.declarations || []).find(d => d.name === ref.name);
141
+
142
+ if (!declaration) {
143
+ return null;
144
+ }
145
+
146
+ DECLARATION_PACKAGE.set(declaration, ref.package);
147
+ DECLARATION_MODULE.set(declaration, ref.module);
148
+
149
+ return resolveDeclaration(declaration);
150
+ }
151
+
152
+ async function resolveDeclaration(declaration) {
153
+ if (!declaration.superclass || declaration.superclass.name === UI5_BASE_CLASS) {
154
+ return [declaration];
155
+ }
156
+
157
+ const superclassDeclarations = await resolveReference(declaration.superclass);
158
+ return [declaration, superclassDeclarations].flat().filter(Boolean);
159
+ }
160
+
161
+ const merge = async () => {
162
+ const currentCEM = await readCurrentCEM();
163
+ if (!currentCEM) {
164
+ throw new Error("No custom elements manifest found in current project");
165
+ }
166
+
167
+ await collectThirdPartyCem();
168
+
169
+ const modules = currentCEM.modules || [];
170
+
171
+ for (const mod of modules) {
172
+ const declarations = (mod.declarations || []).filter(d => d.kind === "class");
173
+
174
+ for (const declaration of declarations) {
175
+ const declarationHierarchy = await resolveDeclaration(declaration);
176
+ const allKeys = declarationHierarchy.flatMap(dec => Object.keys(dec));
177
+ const uniqueKeys = [...new Set(allKeys)];
178
+ const arrayKeys = uniqueKeys
179
+ .filter(key => !key.startsWith("_ui5"))
180
+ .filter(key => declarationHierarchy.some(dec => Array.isArray(dec[key])));
181
+
182
+ for (const key of arrayKeys) {
183
+ const allItems = declarationHierarchy.flatMap(dec => dec[key] || []);
184
+
185
+ // Remove duplicates based on name property
186
+ const seen = new Set();
187
+ declaration[key] = allItems.filter(item => {
188
+ if (!item.name) return true;
189
+ if (seen.has(item.name)) return false;
190
+ seen.add(item.name);
191
+ return true;
192
+ });
193
+ }
194
+ }
195
+ }
196
+
197
+ const cleanedCEM = removeInheritedFrom(currentCEM);
198
+ const outputPath = path.resolve(process.cwd(), customElementsPath);
199
+
200
+ try {
201
+ await writeFile(outputPath, JSON.stringify(cleanedCEM, null, 2), "utf-8");
202
+ console.log(`Successfully merged CEM to ${outputPath}`);
203
+ } catch (error) {
204
+ throw new Error(`Failed to write merged CEM to ${outputPath}: ${error.message}`);
205
+ }
206
+ };
207
+
208
+ await merge();
209
+ }
210
+
211
+ const filePath = process.argv[1];
212
+ const fileUrl = pathToFileURL(filePath).href;
213
+
214
+ if (import.meta.url === fileUrl) {
215
+ main(process.argv)
216
+ }
217
+
218
+ export default {
219
+ _ui5mainFn: main
220
+ }
@@ -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
+