@ui5/webcomponents-tools 0.0.0-037d08c67
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 +2474 -0
- package/LICENSE.txt +201 -0
- package/README.md +21 -0
- package/assets-meta.js +154 -0
- package/bin/create-ui5-element.js +3 -0
- package/bin/dev.js +22 -0
- package/bin/ui5nps.js +301 -0
- package/components-package/eslint.js +195 -0
- package/components-package/nps.js +177 -0
- package/components-package/postcss.components.js +1 -0
- package/components-package/postcss.themes.js +1 -0
- package/components-package/vite.config.js +9 -0
- package/components-package/wdio.js +421 -0
- package/icons-collection/nps.js +80 -0
- package/lib/amd-to-es6/index.js +109 -0
- package/lib/amd-to-es6/no-remaining-require.js +33 -0
- package/lib/cem/cem.js +16 -0
- package/lib/cem/custom-elements-manifest.config.mjs +575 -0
- package/lib/cem/event.mjs +168 -0
- 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/lib/cem/schema-internal.json +1422 -0
- package/lib/cem/schema.json +1098 -0
- package/lib/cem/types-internal.d.ts +808 -0
- package/lib/cem/types.d.ts +736 -0
- package/lib/cem/utils.mjs +429 -0
- package/lib/cem/validate.js +81 -0
- package/lib/chokidar/chokidar.js +28 -0
- package/lib/copy-and-watch/index.js +158 -0
- package/lib/copy-list/index.js +36 -0
- package/lib/create-icons/index.js +131 -0
- package/lib/create-illustrations/index.js +210 -0
- package/lib/create-new-component/Component.js +74 -0
- package/lib/create-new-component/ComponentTemplate.js +12 -0
- package/lib/create-new-component/index.js +115 -0
- package/lib/css-processors/css-processor-components.mjs +101 -0
- package/lib/css-processors/css-processor-themes.mjs +121 -0
- package/lib/css-processors/postcss-plugin.mjs +153 -0
- package/lib/css-processors/scope-variables.mjs +51 -0
- package/lib/css-processors/shared.mjs +47 -0
- package/lib/dev-server/custom-hot-update-plugin.js +39 -0
- package/lib/dev-server/dev-server.mjs +78 -0
- package/lib/dev-server/virtual-index-html-plugin.js +56 -0
- package/lib/eslint/eslint.js +44 -0
- package/lib/generate-js-imports/illustrations.js +87 -0
- package/lib/generate-json-imports/i18n.js +93 -0
- package/lib/generate-json-imports/themes.js +75 -0
- package/lib/hbs2lit/index.js +3 -0
- package/lib/hbs2lit/src/compiler.js +60 -0
- package/lib/hbs2lit/src/extendedAttributeMapping.js +12 -0
- package/lib/hbs2lit/src/includesReplacer.js +31 -0
- package/lib/hbs2lit/src/litVisitor2.js +278 -0
- package/lib/hbs2lit/src/partials2.js +51 -0
- package/lib/hbs2lit/src/partialsVisitor.js +187 -0
- package/lib/hbs2lit/src/svgProcessor.js +76 -0
- package/lib/hbs2ui5/RenderTemplates/LitRenderer.js +45 -0
- package/lib/hbs2ui5/index.js +119 -0
- package/lib/i18n/defaults.js +90 -0
- package/lib/i18n/toJSON.js +71 -0
- package/lib/icons-hash/icons-hash.mjs +149 -0
- package/lib/postcss-combine-duplicated-selectors/index.js +185 -0
- package/lib/remove-dev-mode/remove-dev-mode.mjs +51 -0
- package/lib/rimraf/rimraf.js +31 -0
- package/lib/scoping/get-all-tags.js +44 -0
- package/lib/scoping/lint-src.js +32 -0
- package/lib/scoping/missing-dependencies.js +65 -0
- package/lib/scoping/report-tags-usage.js +28 -0
- package/lib/scoping/scope-test-pages.js +41 -0
- package/lib/test-runner/test-runner.js +79 -0
- package/lib/vite-bundler/vite-bundler.mjs +35 -0
- package/package.json +86 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { parse } from "comment-parser";
|
|
2
|
+
import {
|
|
3
|
+
getPrivacyStatus,
|
|
4
|
+
getDeprecatedStatus,
|
|
5
|
+
getSinceStatus,
|
|
6
|
+
getType,
|
|
7
|
+
getTypeRefs,
|
|
8
|
+
validateJSDocComment,
|
|
9
|
+
hasTag,
|
|
10
|
+
findTag,
|
|
11
|
+
findAllTags,
|
|
12
|
+
getReference,
|
|
13
|
+
normalizeDescription,
|
|
14
|
+
normalizeTagType,
|
|
15
|
+
logDocumentationError
|
|
16
|
+
} from "./utils.mjs";
|
|
17
|
+
|
|
18
|
+
const jsDocRegExp = /\/\*\*(.|\n)+?\s+\*\//;
|
|
19
|
+
const ASTFalseKeywordCode = 94;
|
|
20
|
+
|
|
21
|
+
const getParams = (ts, eventDetails, commentParams, classNode, moduleDoc) => {
|
|
22
|
+
return commentParams?.map(commentParam => {
|
|
23
|
+
const { typeName, name } = getType(normalizeTagType(commentParam?.type));
|
|
24
|
+
let type;
|
|
25
|
+
|
|
26
|
+
if (typeName) {
|
|
27
|
+
type = { text: typeName };
|
|
28
|
+
|
|
29
|
+
let typeRefs = name?.split("|")
|
|
30
|
+
?.map(e => getReference(ts, e.trim(), classNode, moduleDoc.path))
|
|
31
|
+
.filter(Boolean);
|
|
32
|
+
|
|
33
|
+
if (typeRefs?.length) {
|
|
34
|
+
type.references = typeRefs;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
type,
|
|
40
|
+
name: commentParam?.name,
|
|
41
|
+
_ui5privacy: "public",
|
|
42
|
+
description: normalizeDescription(commentParam?.description),
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
function processEvent(ts, event, classNode, moduleDoc) {
|
|
48
|
+
const name = event?.expression?.arguments?.[0]?.text;
|
|
49
|
+
const result = {
|
|
50
|
+
name,
|
|
51
|
+
_ui5privacy: "private",
|
|
52
|
+
type: { text: "CustomEvent" }
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const comment = event.getFullText?.().match(jsDocRegExp)?.[0];
|
|
56
|
+
|
|
57
|
+
if (!comment) {
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const eventParsedComment = parse(comment, { spacing: 'preserve' })[0];
|
|
62
|
+
|
|
63
|
+
validateJSDocComment("event", eventParsedComment, name, moduleDoc);
|
|
64
|
+
|
|
65
|
+
const deprecatedTag = findTag(eventParsedComment, "deprecated");
|
|
66
|
+
const privacy = findTag(eventParsedComment, ["public", "private", "protected"])?.tag || "private";
|
|
67
|
+
const sinceTag = findTag(eventParsedComment, "since");
|
|
68
|
+
const commentParams = findAllTags(eventParsedComment, "param");
|
|
69
|
+
const description = normalizeDescription(eventParsedComment?.description);
|
|
70
|
+
const native = hasTag(eventParsedComment, "native");
|
|
71
|
+
const eventArgs = event?.expression?.arguments;
|
|
72
|
+
let eventBubbles;
|
|
73
|
+
let eventCancelable;
|
|
74
|
+
let eventDetails;
|
|
75
|
+
|
|
76
|
+
eventArgs && eventArgs.forEach(arg => {
|
|
77
|
+
arg.properties?.forEach(prop => {
|
|
78
|
+
if (prop.name?.text === "bubbles") {
|
|
79
|
+
eventBubbles = prop.initializer.kind === ASTFalseKeywordCode ? false : true;
|
|
80
|
+
} else if (prop.name?.text === "cancelable") {
|
|
81
|
+
eventCancelable = prop.initializer.kind === ASTFalseKeywordCode ? false : true;
|
|
82
|
+
} else if (prop.name?.text === "detail") {
|
|
83
|
+
eventDetails = prop.initializer?.properties;
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
result.description = description;
|
|
89
|
+
result._ui5Cancelable = eventCancelable !== undefined ? eventCancelable : false;
|
|
90
|
+
result._ui5allowPreventDefault = result._ui5Cancelable;
|
|
91
|
+
result._ui5Bubbles = eventBubbles !== undefined ? eventBubbles : false;
|
|
92
|
+
|
|
93
|
+
if (native) {
|
|
94
|
+
result.type = { text: "Event" };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (privacy) {
|
|
98
|
+
result._ui5privacy = privacy;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (deprecatedTag?.name) {
|
|
102
|
+
result.deprecated = deprecatedTag.description
|
|
103
|
+
? `${deprecatedTag.name} ${deprecatedTag.description}`
|
|
104
|
+
: deprecatedTag.name;
|
|
105
|
+
} else if (deprecatedTag) {
|
|
106
|
+
result.deprecated = true;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (sinceTag?.name) {
|
|
110
|
+
result._ui5since = sinceTag?.description
|
|
111
|
+
? `${sinceTag.name} ${sinceTag.description}`
|
|
112
|
+
: sinceTag.name;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const eventDetailType = classNode.members?.find(member => {
|
|
116
|
+
return ts.isPropertyDeclaration(member) && member.name.text === "eventDetails"
|
|
117
|
+
})?.type;
|
|
118
|
+
const eventDetailRef = eventDetailType?.members?.find(member => member.name.text === name) || eventDetailType?.types?.[eventDetailType?.types?.length - 1]?.members?.find(member => member.name.text === name);
|
|
119
|
+
const hasGeneric = !!event?.expression?.typeArguments
|
|
120
|
+
|
|
121
|
+
if (commentParams.length) {
|
|
122
|
+
if (eventDetailRef && hasGeneric) {
|
|
123
|
+
logDocumentationError(moduleDoc.path, `Event details for event '${name}' has to be defined either with generic or with eventDetails.`)
|
|
124
|
+
} else if (eventDetails) {
|
|
125
|
+
if (hasGeneric) {
|
|
126
|
+
const typesText = event?.expression?.typeArguments.map(type => type.typeName?.text).filter(Boolean).join(" | ");
|
|
127
|
+
const typeRefs = (getTypeRefs(ts, event.expression)
|
|
128
|
+
?.map(e => getReference(ts, e, event, moduleDoc.path)).filter(Boolean)) || [];
|
|
129
|
+
|
|
130
|
+
result.type = { text: `CustomEvent<${typesText}>` };
|
|
131
|
+
|
|
132
|
+
if (typeRefs.length) {
|
|
133
|
+
result.type.references = typeRefs;
|
|
134
|
+
}
|
|
135
|
+
} else if (eventDetailRef) {
|
|
136
|
+
const typesText = eventDetailRef?.type?.typeName?.text;
|
|
137
|
+
const typeRefs = (getTypeRefs(ts, eventDetailRef)
|
|
138
|
+
?.map(e => getReference(ts, e, event, moduleDoc.path)).filter(Boolean)) || [];
|
|
139
|
+
|
|
140
|
+
result.type = { text: `CustomEvent<${typesText}>` };
|
|
141
|
+
|
|
142
|
+
if (typeRefs.length) {
|
|
143
|
+
result.type.references = typeRefs;
|
|
144
|
+
}
|
|
145
|
+
} else {
|
|
146
|
+
logDocumentationError(moduleDoc.path, `Event details for event '${name}' must be described using generics. Add type via generics to the decorator: @event<TypeForDetails>("${name}", {details}).`)
|
|
147
|
+
}
|
|
148
|
+
} else if (eventDetailRef) {
|
|
149
|
+
const typesText = eventDetailRef?.type?.typeName?.text;
|
|
150
|
+
const typeRefs = (getTypeRefs(ts, eventDetailRef)
|
|
151
|
+
?.map(e => getReference(ts, e, event, moduleDoc.path)).filter(Boolean)) || [];
|
|
152
|
+
|
|
153
|
+
result.type = { text: `CustomEvent<${typesText}>` };
|
|
154
|
+
|
|
155
|
+
if (typeRefs.length) {
|
|
156
|
+
result.type.references = typeRefs;
|
|
157
|
+
}
|
|
158
|
+
} else {
|
|
159
|
+
logDocumentationError(moduleDoc.path, `Event details for event '${name}' must be described.`)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
result._ui5parameters = getParams(ts, eventDetails, commentParams, classNode, moduleDoc);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return result;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export default processEvent;
|
|
@@ -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
|
+
}
|