Skip to content

Commit

Permalink
[Usage Collection] [schema] reporting + add MappedType support (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
afharo authored Sep 29, 2020
1 parent 8282dd7 commit 66866d0
Show file tree
Hide file tree
Showing 10 changed files with 1,403 additions and 9 deletions.
14 changes: 14 additions & 0 deletions packages/kbn-telemetry-tools/src/tools/serializer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,18 @@ describe('getDescriptor', () => {
'@@INDEX@@': { kind: ts.SyntaxKind.NumberKeyword, type: 'NumberKeyword' },
});
});

it('serializes MappedTypes', () => {
const usageInterface = usageInterfaces.get('MappedTypes')!;
const descriptor = getDescriptor(usageInterface, tsProgram);
expect(descriptor).toEqual({
mappedTypeWithExternallyDefinedProps: {
prop1: { kind: ts.SyntaxKind.NumberKeyword, type: 'NumberKeyword' },
prop2: { kind: ts.SyntaxKind.NumberKeyword, type: 'NumberKeyword' },
},
mappedTypeWithOneInlineProp: {
prop3: { kind: ts.SyntaxKind.NumberKeyword, type: 'NumberKeyword' },
},
});
});
});
42 changes: 40 additions & 2 deletions packages/kbn-telemetry-tools/src/tools/serializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,33 @@ export function kindToDescriptorName(kind: number) {
}
}

export function getConstraints(node: ts.Node, program: ts.Program): any {
if (ts.isTypeReferenceNode(node)) {
const typeChecker = program.getTypeChecker();
const symbol = typeChecker.getSymbolAtLocation(node.typeName);
const declaration = (symbol?.getDeclarations() || [])[0];
if (declaration) {
return getConstraints(declaration, program);
}
return getConstraints(node.typeName, program);
}

if (ts.isTypeAliasDeclaration(node)) {
return getConstraints(node.type, program);
}

if (ts.isUnionTypeNode(node)) {
const types = node.types.filter(discardNullOrUndefined);
return types.map((typeNode) => getConstraints(typeNode, program));
}

if (ts.isLiteralTypeNode(node) && ts.isLiteralExpression(node.literal)) {
return node.literal.text;
}

throw Error(`Unsupported constraint`);
}

export function getDescriptor(node: ts.Node, program: ts.Program): Descriptor | DescriptorValue {
if (ts.isMethodSignature(node) || ts.isPropertySignature(node)) {
if (node.type) {
Expand All @@ -89,8 +116,19 @@ export function getDescriptor(node: ts.Node, program: ts.Program): Descriptor |
}

// If it's defined as signature { [key: string]: OtherInterface }
if (ts.isIndexSignatureDeclaration(node) && node.type) {
return { '@@INDEX@@': getDescriptor(node.type, program) };
if ((ts.isIndexSignatureDeclaration(node) || ts.isMappedTypeNode(node)) && node.type) {
const descriptor = getDescriptor(node.type, program);

// If we know the constraints of `string` ({ [key in 'prop1' | 'prop2']: value })
const constraint = (node as ts.MappedTypeNode).typeParameter?.constraint;
if (constraint) {
const constraints = getConstraints(constraint, program);
const constraintsArray = Array.isArray(constraints) ? constraints : [constraints];
if (typeof constraintsArray[0] === 'string') {
return constraintsArray.reduce((acc, c) => ({ ...acc, [c]: descriptor }), {});
}
}
return { '@@INDEX@@': descriptor };
}

if (ts.SyntaxKind.FirstNode === node.kind) {
Expand Down
4 changes: 3 additions & 1 deletion packages/kbn-telemetry-tools/src/tools/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,9 @@ export function getVariableValue(node: ts.Node, program: ts.Program): string | R
}

throw Error(
`Unsupported Node: cannot get value of node (${node.getText()}) of kind ${node.kind}`
`Unsupported Node: cannot get value of node (${node.getText()}) of kind ${node.kind} [${
ts.SyntaxKind[node.kind]
}]`
);
}

Expand Down
11 changes: 11 additions & 0 deletions src/fixtures/telemetry_collectors/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,14 @@ export const externallyDefinedSchema: MakeSchemaFrom<{ locale: string }> = {
export type TypeAliasWithUnion = Usage & WithUnion;

export type TypeAliasWithRecord = Usage & Record<string, number>;

export type MappedTypeProps = 'prop1' | 'prop2';

export interface MappedTypes {
mappedTypeWithExternallyDefinedProps: {
[key in MappedTypeProps]: number;
};
mappedTypeWithOneInlineProp: {
[key in 'prop3']: number;
};
}
1 change: 0 additions & 1 deletion x-pack/.telemetryrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"plugins/alerts/server/usage/alerts_usage_collector.ts",
"plugins/apm/server/lib/apm_telemetry/index.ts",
"plugins/infra/server/usage/usage_collector.ts",
"plugins/reporting/server/usage/reporting_usage_collector.ts",
"plugins/maps/server/maps_telemetry/collectors/register.ts"
]
}
Loading

0 comments on commit 66866d0

Please sign in to comment.