/
cem-utilities.ts
147 lines (138 loc) · 4.18 KB
/
cem-utilities.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import { removeQuoteWrappers } from "../../utilities";
import type * as schema from "custom-elements-manifest";
import type { CEM, Component, ComponentWithModule } from "./types";
export const EXCLUDED_TYPES = [
"any",
"bigint",
"boolean",
"never",
"null",
"number",
"string",
"Symbol",
"undefined",
"unknown",
];
/**
* Gets the description from a CEM based on a specified source
* @param component CEM component/declaration object
* @param descriptionSrc property name of the description source
* @returns string
*/
export function getComponentDescription(
component: Component,
descriptionSrc?: string
): string {
let description =
(descriptionSrc
? (component as any)[descriptionSrc]
: component.summary || component.description
)?.replace(/\\n/g, "\n") || "";
if (component.deprecated) {
const deprecation =
typeof component.deprecated === "string"
? `@deprecated ${component.deprecated}`
: "@deprecated";
description = `${deprecation}\n\n${description}`;
}
return description;
}
/**
* Gets a list of components from a CEM object
* @param customElementsManifest CEM object
* @param exclude and array of component names to exclude
* @returns Component[]
*/
export function getComponents(
customElementsManifest: CEM,
exclude?: string[]
): ComponentWithModule[] {
return (
customElementsManifest.modules?.map(
(mod) =>
mod?.declarations
?.filter(
(dec) =>
!exclude?.includes(dec.name) && (dec.customElement || dec.tagName)
)
.map((dec) => ({ ...dec, module: mod })) || []
) || []
).flat();
}
/**
* Gets a list of public properties from a CEM component
* @param component CEM component/declaration object
* @returns an array of public properties for a given component
*/
export function getComponentProperties(component: Component) {
return component.members?.filter(
(member) =>
member.kind === "field" &&
member.privacy !== "private" &&
member.privacy !== "protected" &&
!member.static &&
!(member as schema.CustomElementField).attribute &&
!member.name.startsWith("#")
) as schema.ClassMember[];
}
/**
* This is intended for providing tooling a list of viable options for an attribute (excluding Js primitives).
* @param attr CEm attribute object
* @param typeSrc property name of the type source
* @returns list of values for a given attribute
*/
export function getAttributeValueOptions(
attr: schema.Attribute,
typeSrc: string = "type"
): string[] {
const value: string = (attr as any)[`${typeSrc}`]?.text || attr.type?.text;
return !value
? []
: (value.includes("|") ? value.split("|") : value.split(","))
.filter((type) => !EXCLUDED_TYPES.includes(type.trim()))
.map((type) => removeQuoteWrappers(type));
}
/**
* Get all public methods for a component
* @param component CEM component/declaration object
* @returns ClassMethod[]
*/
export function getComponentMethods(
component: Component
): schema.ClassMethod[] {
return component.members?.filter(
(member) =>
member.kind === "method" &&
member.privacy !== "private" &&
member.description?.length &&
!member.name.startsWith("#")
) as schema.ClassMethod[];
}
/**
* Gets a list of event names for a given component
* @param component The component you want to get the event types for
* @param excludedTypes Any types you want to exclude from the list
* @returns A string array of event types for a given component
*/
export function getCustomEventTypes(
component: Component,
excludedTypes?: string[]
) {
const types = component.events
?.map((e) => {
const eventType = e.type?.text
.replace("[]", "")
.replace(" | undefined", "");
return eventType &&
!excludedTypes?.includes(eventType) &&
!EXCLUDED_TYPES.includes(eventType) &&
!eventType.includes("<") &&
!eventType.includes(`{`) &&
!eventType.includes("'") &&
!eventType.includes(`"`)
? eventType
: undefined;
})
.filter((e) => e !== undefined && !e?.startsWith("HTML"));
return types?.length ? [...new Set(types)].join(", ") : undefined;
}