Skip to content

Commit 423bf42

Browse files
committed
feat(docs,dgeni): add hostDirectives to directives and components
1 parent 206e4f8 commit 423bf42

9 files changed

Lines changed: 113 additions & 6 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { DaffDocsApiHostDirectiveInheritedField } from '../doc/public_api';
2+
3+
const REGEX = /(?<field>\w+)(: (?<alias>\w+))?/;
4+
5+
export const daffDocsApiParseHostDirectiveField = (field: string): DaffDocsApiHostDirectiveInheritedField => {
6+
const result = REGEX.exec(field).groups;
7+
return {
8+
field: result.field,
9+
parentField: result.alias,
10+
};
11+
};
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
const REGEX = /(directive: (?<directive>\w+))|(inputs: (?<inputs>\[.+\]))|(outputs: (?<outputs>\[.+\]))/g;
2+
3+
type Groups = Partial<{
4+
directive: string;
5+
inputs: string;
6+
outputs: string;
7+
}>;
8+
9+
export const daffDocsApiParseHostDirective = (hostDirective: string): Groups =>
10+
[...hostDirective.matchAll(REGEX)].reduce((groups, match) => {
11+
// eslint-disable-next-line guard-for-in
12+
for (const k in match.groups) {
13+
groups[k] = match.groups[k] ?? groups[k];
14+
}
15+
return groups;
16+
}, <Groups>{});
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
export * from './array-to-dict';
22
export * from './decorator.type';
3+
export * from './parse-host-directive';
4+
export * from './parse-host-directive-field';
35
export * from './ref.type';
46
export * from './role/public_api';
57
export * from './type.enum';

libs/docs-utils/src/doc/api/directive.type.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,37 @@ import {
33
DaffDocsApiClassProperty,
44
} from './class.type';
55
import { DaffDocsApiTypeProperty } from './type.type';
6-
import { DaffDocsApiRole } from '../../api/public_api';
6+
import {
7+
DaffDocsApiRef,
8+
DaffDocsApiRole,
9+
} from '../../api/public_api';
710

811
export interface DaffApiDirectiveInputDoc extends DaffDocsApiClassProperty {
912
required: boolean;
1013
}
1114

15+
export interface DaffDocsApiHostDirectiveInheritedField {
16+
/**
17+
* The name of the field on this directive.
18+
*/
19+
field: string;
20+
/**
21+
* If the field is aliased, this will be the field in the parent.
22+
*/
23+
parentField?: string;
24+
}
25+
26+
export interface DaffDocsApiHostDirective {
27+
directive: DaffDocsApiRef;
28+
inputs: Array<DaffDocsApiHostDirectiveInheritedField>;
29+
outputs: Array<DaffDocsApiHostDirectiveInheritedField>;
30+
}
31+
1232
export interface DaffApiDirective extends DaffDocsApiClass {
1333
selector: string;
1434
inputs: Array<DaffApiDirectiveInputDoc>;
1535
outputs: Array<DaffDocsApiTypeProperty>;
16-
// hostDirectives: Array
36+
hostDirectives: Array<DaffDocsApiHostDirective>;
1737
}
1838

1939
export interface DaffApiDirectiveDoc extends DaffApiDirective {

libs/docs-utils/src/doc/api/type.type.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { DaffApiDocBase } from './base.type';
99
import { DaffDocsApiFunctionParam } from './function.type';
1010
import {
1111
DaffDocsApiDecorator,
12+
DaffDocsApiRef,
1213
DaffDocsApiRole,
1314
} from '../../api/public_api';
1415
import { DaffDocsRenderedContent } from '../rendered-content.type';
@@ -19,6 +20,7 @@ export interface DaffDocsApiTypeProperty extends Pick<PropertyMemberDoc, MemberF
1920
decorators: Array<DaffDocsApiDecorator>;
2021
description: DaffDocsRenderedContent;
2122
type: DaffDocsRenderedContent;
23+
inheritedFrom?: DaffDocsApiRef;
2224
}
2325

2426
export interface DaffDocsApiTypeMethod extends Pick<MethodMemberDoc, MemberFields | 'typeParameters'> {

tools/dgeni/src/transforms/daffodil-api-package/processors/add-source.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,9 @@ const interfaceBlock = (doc: DaffApiType): string => {
125125
const classBlock = (doc: ClassExportDoc & DaffDocsApiClass): string => {
126126
const decorators = doc.decorators?.length > 0
127127
? doc.decorators.reduce((acc, decorator) =>
128-
`${acc}@${decorator.name}()\n`
128+
decorator.name === 'Component' && (<any>decorator.argumentInfo[0]).hostDirectives?.length > 0
129+
? `${acc}@${decorator.name}({\n${tab()}hostDirectives: [${(<any>decorator.argumentInfo[0]).hostDirectives.reduce((acc_, hd) => `${acc_}\n${indent(hd, 2)},`, '')}\n${tab()}]\n})\n`
130+
: `${acc}@${decorator.name}()\n`
129131
, '')
130132
: '';
131133
const parents = doc.extendsClauses.length > 0

tools/dgeni/src/transforms/daffodil-api-package/processors/role.ts

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type { ConstExportDoc } from 'dgeni-packages/typescript/api-doc-types/Con
55
import type { FunctionExportDoc } from 'dgeni-packages/typescript/api-doc-types/FunctionExportDoc';
66
import { MethodMemberDoc } from 'dgeni-packages/typescript/api-doc-types/MethodMemberDoc';
77
import { PropertyMemberDoc } from 'dgeni-packages/typescript/api-doc-types/PropertyMemberDoc';
8+
import { createRef } from 'tools/dgeni/src/utils/create-ref';
89
import { TypeFlags } from 'typescript';
910

1011
import {
@@ -27,6 +28,9 @@ import {
2728
DaffDocsApiTypeProperty,
2829
daffDocsGetRoleFromTsDoc,
2930
DaffDocsTsDocument,
31+
daffDocsApiParseHostDirective,
32+
daffDocsApiParseHostDirectiveField,
33+
DaffDocsApiHostDirective,
3034
} from '@daffodil/docs-utils';
3135

3236
import { InlineTagProcessor } from './inline-tag-processor';
@@ -229,6 +233,7 @@ export class RoleProcessor implements FilterableProcessor {
229233
readonly directiveSerialize = serializeFactory<DaffApiDirective>(
230234
[
231235
'selector',
236+
'hostDirectives',
232237
],
233238
{
234239
inputs: arraySerializer(this.inputSerialize),
@@ -242,6 +247,7 @@ export class RoleProcessor implements FilterableProcessor {
242247
constructor(
243248
private markdown: MarkdownCodeProcessor,
244249
private inlineTagProcessor: InlineTagProcessor,
250+
private aliasMap,
245251
) {}
246252

247253
$process(docs: Array<Document>): Array<Document> {
@@ -309,9 +315,44 @@ export class RoleProcessor implements FilterableProcessor {
309315
directive(doc: SerializableDoc & DaffApiDirective & ClassExportDoc): SerializableDoc & DaffApiDirective {
310316
this.klass(<any>doc);
311317
doc.serializer = this.directiveSerialize;
318+
const directiveArg: any = doc.decorators[0].argumentInfo[0];
312319
doc.inputs = [];
313320
doc.outputs = [];
314-
doc.selector = doc.decorators[0].argumentInfo[0][0];
321+
doc.selector = directiveArg.selector;
322+
doc.hostDirectives = (<Array<string>>directiveArg.hostDirectives)
323+
?.map(daffDocsApiParseHostDirective)
324+
.map<DaffDocsApiHostDirective>(({ directive, inputs, outputs }) => ({
325+
directive: createRef(directive),
326+
inputs: inputs ? JSON.parse(inputs.replaceAll('\'', '\"')).map(daffDocsApiParseHostDirectiveField) : [],
327+
outputs: outputs ? JSON.parse(outputs.replaceAll('\'', '\"')).map(daffDocsApiParseHostDirectiveField) : [],
328+
})) || [];
329+
doc.hostDirectives.forEach((hostDirective) => {
330+
const directiveDoc = this.aliasMap.getDocs(hostDirective.directive.label)[0];
331+
if (directiveDoc) {
332+
hostDirective.inputs.forEach((input) => {
333+
const parentInput = directiveDoc.members.find((member) => member.name === input.parentField || input.field);
334+
if (parentInput) {
335+
doc.inputs.push({
336+
...parentInput,
337+
name: input.field,
338+
required: !parentInput.isOptional,
339+
inheritedFrom: hostDirective.directive,
340+
});
341+
}
342+
});
343+
hostDirective.outputs.forEach((output) => {
344+
const parentOutput = directiveDoc.members.find((member) => member.name === output.parentField || output.field);
345+
if (parentOutput) {
346+
doc.outputs.push({
347+
...parentOutput,
348+
name: output.field,
349+
required: !parentOutput.isOptional,
350+
inheritedFrom: hostDirective.directive,
351+
});
352+
}
353+
});
354+
}
355+
});
315356
// TODO: support signals
316357
doc.props = doc.props.reduce((acc, prop) => {
317358
if (prop.decorators?.find(({ name }) => name === 'Input')) {
@@ -443,5 +484,5 @@ export class RoleProcessor implements FilterableProcessor {
443484

444485
export const ROLE_PROVIDER = <const>[
445486
ROLE_PROCESSOR_NAME,
446-
(markdown: MarkdownCodeProcessor, inlineTagProcessorForRealz: InlineTagProcessor) => new RoleProcessor(markdown, inlineTagProcessorForRealz),
487+
(markdown: MarkdownCodeProcessor, inlineTagProcessorForRealz: InlineTagProcessor, aliasMap) => new RoleProcessor(markdown, inlineTagProcessorForRealz, aliasMap),
447488
];
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { DaffDocsApiRef } from '@daffodil/docs-utils';
2+
3+
import { absolutifyPaths } from '../processors/absolutify-paths';
4+
import { CollectLinkableSymbolsProcessor } from '../processors/collect-linkable-symbols';
5+
6+
export const createRef = (text: string): DaffDocsApiRef =>
7+
CollectLinkableSymbolsProcessor.symbols.has(text)
8+
? {
9+
label: text,
10+
path: absolutifyPaths(CollectLinkableSymbolsProcessor.symbols.get(text)),
11+
}
12+
: undefined;

tools/dgeni/tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
"jasmine",
1010
"node"
1111
],
12-
"esModuleInterop": true
12+
"esModuleInterop": true,
13+
"downlevelIteration": true
1314
},
1415
"include": [
1516
"**/*.ts"

0 commit comments

Comments
 (0)