1 | import { createComponentEventTypeImports, dashToPascalCase, formatToQuotedList } from './utils';
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 | export const createAngularComponentDefinition = (tagName, inputs, outputs, methods, includeImportCustomElements = false) => {
|
13 | const tagNameAsPascal = dashToPascalCase(tagName);
|
14 | const hasInputs = inputs.length > 0;
|
15 | const hasOutputs = outputs.length > 0;
|
16 | const hasMethods = methods.length > 0;
|
17 |
|
18 | const formattedInputs = formatToQuotedList(inputs);
|
19 |
|
20 | const formattedOutputs = formatToQuotedList(outputs);
|
21 |
|
22 | const formattedMethods = formatToQuotedList(methods);
|
23 | const proxyCmpOptions = [];
|
24 | if (includeImportCustomElements) {
|
25 | const defineCustomElementFn = `define${tagNameAsPascal}`;
|
26 | proxyCmpOptions.push(`\n defineCustomElementFn: ${defineCustomElementFn}`);
|
27 | }
|
28 | if (hasInputs) {
|
29 | proxyCmpOptions.push(`\n inputs: [${formattedInputs}]`);
|
30 | }
|
31 | if (hasMethods) {
|
32 | proxyCmpOptions.push(`\n methods: [${formattedMethods}]`);
|
33 | }
|
34 | |
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 | const output = `@ProxyCmp({${proxyCmpOptions.join(',')}\n})
|
42 | @Component({
|
43 | selector: '${tagName}',
|
44 | changeDetection: ChangeDetectionStrategy.OnPush,
|
45 | template: '<ng-content></ng-content>',
|
46 | // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
|
47 | inputs: [${formattedInputs}],
|
48 | })
|
49 | export class ${tagNameAsPascal} {
|
50 | protected el: HTMLElement;
|
51 | constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
52 | c.detach();
|
53 | this.el = r.nativeElement;${hasOutputs
|
54 | ? `
|
55 | proxyOutputs(this, this.el, [${formattedOutputs}]);`
|
56 | : ''}
|
57 | }
|
58 | }`;
|
59 | return output;
|
60 | };
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 | const formatOutputType = (componentClassName, event) => {
|
68 | |
69 |
|
70 |
|
71 |
|
72 |
|
73 | return Object.entries(event.complexType.references)
|
74 | .filter(([_, refObject]) => refObject.location === 'local' || refObject.location === 'import')
|
75 | .reduce((type, [src, dst]) => {
|
76 | const renamedType = `I${componentClassName}${type}`;
|
77 | return (renamedType
|
78 | .replace(new RegExp(`^${src}$`, 'g'), `${dst}`)
|
79 |
|
80 | .replace(new RegExp(`([^\\w])${src}([^\\w])`, 'g'), (v, p1, p2) => [p1, dst, p2].join('')));
|
81 | }, event.complexType.original
|
82 | .replace(/\n/g, ' ')
|
83 | .replace(/\s{2,}/g, ' ')
|
84 | .replace(/,\s*/g, ', '));
|
85 | };
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 | const createDocComment = (doc) => {
|
92 | if (doc.text.trim().length === 0 && doc.tags.length === 0) {
|
93 | return '';
|
94 | }
|
95 | return `/**
|
96 | * ${doc.text}${doc.tags.length > 0 ? ' ' : ''}${doc.tags.map((tag) => `@${tag.name} ${tag.text}`)}
|
97 | */`;
|
98 | };
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 | export const createComponentTypeDefinition = (tagNameAsPascal, events, componentCorePackage, includeImportCustomElements = false, customElementsDir) => {
|
109 | const publicEvents = events.filter((ev) => !ev.internal);
|
110 | const eventTypeImports = createComponentEventTypeImports(tagNameAsPascal, publicEvents, {
|
111 | componentCorePackage,
|
112 | includeImportCustomElements,
|
113 | customElementsDir,
|
114 | });
|
115 | const eventTypes = publicEvents.map((event) => {
|
116 | const comment = createDocComment(event.docs);
|
117 | let eventName = event.name;
|
118 | if (event.name.includes('-')) {
|
119 |
|
120 |
|
121 | eventName = `'${event.name}'`;
|
122 | }
|
123 | return `${comment.length > 0 ? ` ${comment}` : ''}
|
124 | ${eventName}: EventEmitter<CustomEvent<${formatOutputType(tagNameAsPascal, event)}>>;`;
|
125 | });
|
126 | const interfaceDeclaration = `export declare interface ${tagNameAsPascal} extends Components.${tagNameAsPascal} {`;
|
127 | const typeDefinition = (eventTypeImports.length > 0 ? `${eventTypeImports + '\n\n'}` : '') +
|
128 | `${interfaceDeclaration}${eventTypes.length === 0
|
129 | ? '}'
|
130 | : `
|
131 | ${eventTypes.join('\n')}
|
132 | }`}`;
|
133 | return typeDefinition;
|
134 | };
|