Skip to content

Commit 6d1ea2d

Browse files
author
Stacey Gammon
committed
Review update 3 plus support for links in class interface heritage clause
1 parent eafd497 commit 6d1ea2d

File tree

9 files changed

+86
-37
lines changed

9 files changed

+86
-37
lines changed

packages/kbn-docs-utils/src/api_docs/build_api_declarations/extract_import_refs.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,11 @@ export function extractImportReferences(
6464
texts.push({
6565
pluginId: plugin.manifest.id,
6666
scope: getScopeFromPath(path, plugin, log),
67-
docId: getPluginApiDocId(plugin.manifest.id, plugin.manifest.serviceFolders, path),
67+
docId: getPluginApiDocId(plugin.manifest.id, {
68+
serviceFolders: plugin.manifest.serviceFolders,
69+
apiPath: path,
70+
directory: plugin.directory,
71+
}),
6872
section,
6973
text: name,
7074
});

packages/kbn-docs-utils/src/api_docs/build_api_declarations/get_signature.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ export function getSignature(
4949
// Need to tack on manually any type parameters or "extends/implements" section.
5050
const heritageClause = node
5151
.getHeritageClauses()
52-
.map((h) => h.getText())
52+
.map((h) => {
53+
const heritance = h.getText().indexOf('implements') > -1 ? 'implements' : 'extends';
54+
return `${heritance} ${h.getTypeNodes().map((n) => n.getType().getText())}`;
55+
})
5356
.join(' ');
5457
signature = `${node.getType().getText()}${heritageClause ? ' ' + heritageClause : ''}`;
5558
} else {

packages/kbn-docs-utils/src/api_docs/mdx/split_apis_by_folder.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ beforeAll(() => {
3838
});
3939

4040
test('foo service has all exports', () => {
41-
expect(doc?.client.length).toBe(32);
41+
expect(doc?.client.length).toBe(33);
4242
const split = splitApisByFolder(doc);
4343
expect(split.length).toBe(2);
4444

@@ -47,5 +47,5 @@ test('foo service has all exports', () => {
4747

4848
expect(fooDoc?.common.length).toBe(1);
4949
expect(fooDoc?.client.length).toBe(2);
50-
expect(mainDoc?.client.length).toBe(30);
50+
expect(mainDoc?.client.length).toBe(31);
5151
});

packages/kbn-docs-utils/src/api_docs/mdx/write_plugin_split_by_folder.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import { ToolingLog } from '@kbn/dev-utils';
10-
import { getServiceForPath, snakeToCamel } from '../utils';
10+
import { snakeToCamel } from '../utils';
1111
import { PluginApi, ApiDeclaration } from '../types';
1212
import { writePluginDoc } from './write_plugin_mdx_docs';
1313

@@ -44,7 +44,9 @@ function addSection(
4444
pluginServices: { [key: string]: PluginApi },
4545
serviceFolders: readonly string[]
4646
) {
47-
const serviceFolderName = getServiceForPath(dec.source.path);
47+
const scopeFolder = scope === 'client' ? 'public' : scope;
48+
const matchGroup = dec.source.path.match(`.*?\/${scopeFolder}\/([^\/]*?)\/`);
49+
const serviceFolderName = matchGroup ? matchGroup[1] : undefined;
4850

4951
if (serviceFolderName && serviceFolders.find((f) => f === serviceFolderName)) {
5052
const service = snakeToCamel(serviceFolderName);

packages/kbn-docs-utils/src/api_docs/tests/__fixtures__/src/plugin_a/public/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,6 @@ export enum DayOfWeek {
4040
export type MultipleDeclarationsType = TypeWithGeneric<typeof DayOfWeek>;
4141

4242
export type IRefANotExportedType = ImNotExportedFromIndex | { zed: 'hi' };
43+
export interface ImAnObject {
44+
foo: FnWithGeneric;
45+
}

packages/kbn-docs-utils/src/api_docs/tests/api_doc_suite.test.ts

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -314,23 +314,31 @@ describe('interfaces and classes', () => {
314314
expect(exampleInterface?.signature).toBeDefined();
315315
expect(exampleInterface?.type).toBe(TypeKind.InterfaceKind);
316316

317-
expect(linkCount(exampleInterface?.signature!)).toBe(1);
317+
expect(linkCount(exampleInterface?.signature!)).toBe(2);
318318

319319
// TODO: uncomment if the bug is fixed.
320320
// This is wrong, the link should be to `AnotherInterface`
321321
// Another bug, this link is not being captured.
322-
// expect(exampleInterface?.signature).toMatchInlineSnapshot(`
323-
// Array [
324-
// "",
325-
// Object {
326-
// "docId": "kibPluginAPluginApi",
327-
// "section": "def-public.ExampleInterface",
328-
// "text": "ExampleInterface",
329-
// },
330-
// " extends AnotherInterface<string>",
331-
// ]
332-
// `);
333-
// expect(typeof exampleInterface!.signature![2]).toBe('Object');
322+
expect(exampleInterface?.signature).toMatchInlineSnapshot(`
323+
Array [
324+
Object {
325+
"docId": "kibPluginAPluginApi",
326+
"pluginId": "pluginA",
327+
"scope": "public",
328+
"section": "def-public.ExampleInterface",
329+
"text": "ExampleInterface",
330+
},
331+
" extends ",
332+
Object {
333+
"docId": "kibPluginAPluginApi",
334+
"pluginId": "pluginA",
335+
"scope": "public",
336+
"section": "def-public.AnotherInterface",
337+
"text": "AnotherInterface",
338+
},
339+
"<string>",
340+
]
341+
`);
334342
});
335343

336344
it('Non arrow function on interface is exported as function type', () => {
@@ -356,10 +364,26 @@ describe('interfaces and classes', () => {
356364
"section": "def-public.CrazyClass",
357365
"text": "CrazyClass",
358366
},
359-
"<P> extends ExampleClass<WithGen<P>>",
367+
"<P> extends ",
368+
Object {
369+
"docId": "kibPluginAPluginApi",
370+
"pluginId": "pluginA",
371+
"scope": "public",
372+
"section": "def-public.ExampleClass",
373+
"text": "ExampleClass",
374+
},
375+
"<",
376+
Object {
377+
"docId": "kibPluginAPluginApi",
378+
"pluginId": "pluginA",
379+
"scope": "public",
380+
"section": "def-public.WithGen",
381+
"text": "WithGen",
382+
},
383+
"<P>>",
360384
]
361385
`);
362-
expect(clss?.signature?.length).toBe(2);
386+
expect(linkCount(clss?.signature!)).toBe(3);
363387
});
364388

365389
it('Function with generic inside interface is exported with function type', () => {

packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_a.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

packages/kbn-docs-utils/src/api_docs/utils.test.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,22 @@ it('test getPluginForPath', () => {
2727
});
2828

2929
it('test getServiceForPath', () => {
30-
expect(getServiceForPath('src/plugins/embed/public/service/file.ts')).toBe('service');
31-
expect(getServiceForPath('src/plugins/embed/public/service/subfolder/file.ts')).toBe('service');
32-
expect(getServiceForPath('src/plugins/embed/public/file.ts')).toBeUndefined();
33-
expect(getServiceForPath('src/plugins/embed/server/another_service/file.ts')).toBe(
34-
'another_service'
30+
expect(getServiceForPath('src/plugins/embed/public/service/file.ts', 'src/plugins/embed')).toBe(
31+
'service'
3532
);
36-
expect(getServiceForPath('src/plugins/embed/server/f.ts')).toBeUndefined();
33+
expect(
34+
getServiceForPath('src/plugins/embed/public/service/subfolder/file.ts', 'src/plugins/embed')
35+
).toBe('service');
36+
expect(
37+
getServiceForPath('src/plugins/embed/public/file.ts', 'src/plugins/embed')
38+
).toBeUndefined();
39+
expect(
40+
getServiceForPath('src/plugins/embed/server/another_service/file.ts', 'src/plugins/embed')
41+
).toBe('another_service');
42+
expect(
43+
getServiceForPath('src/plugins/embed/server/routes/public/foo/index.ts', 'src/plugins/embed')
44+
).toBe('routes');
45+
expect(getServiceForPath('src/plugins/embed/server/f.ts', 'src/plugins/embed')).toBeUndefined();
3746
});
3847

3948
it('test removeBrokenLinks', () => {

packages/kbn-docs-utils/src/api_docs/utils.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,11 @@ export function groupPluginApi(declarations: ApiDeclaration[]): ScopeApi {
5959
* 'src/plugin/data/server/file.ts' would return undefined.
6060
* @param path
6161
*/
62-
export function getServiceForPath(path: string): string | undefined {
63-
const publicMatchGroups = path.match(/.*\/public\/(.*?)\/.*/);
64-
const serverMatchGroups = path.match(/.*\/server\/(.*?)\/.*/);
65-
const commonMatchGroups = path.match(/.*\/common\/(.*?)\/.*/);
62+
export function getServiceForPath(path: string, pluginDirectory: string): string | undefined {
63+
const publicMatchGroups = path.match(`${pluginDirectory}/public\/([^\/]*)\/`);
64+
const serverMatchGroups = path.match(`${pluginDirectory}/server\/([^\/]*)\/`);
65+
const commonMatchGroups = path.match(`${pluginDirectory}/common\/([^\/]*)\/`);
66+
6667
if (publicMatchGroups && publicMatchGroups.length > 1) {
6768
return publicMatchGroups[1];
6869
} else if (serverMatchGroups && serverMatchGroups.length > 1) {
@@ -74,14 +75,17 @@ export function getServiceForPath(path: string): string | undefined {
7475

7576
export function getPluginApiDocId(
7677
id: string,
77-
serviceFolders?: readonly string[],
78-
apiPath?: string
78+
serviceInfo?: {
79+
serviceFolders: readonly string[];
80+
apiPath: string;
81+
directory: string;
82+
}
7983
) {
8084
let service = '';
8185
const cleanName = id.replace('.', '_');
82-
if (apiPath) {
83-
const serviceName = getServiceForPath(apiPath);
84-
const serviceFolder = serviceFolders?.find((f) => f === serviceName);
86+
if (serviceInfo) {
87+
const serviceName = getServiceForPath(serviceInfo.apiPath, serviceInfo.directory);
88+
const serviceFolder = serviceInfo.serviceFolders?.find((f) => f === serviceName);
8589

8690
if (serviceFolder) {
8791
service = snakeToCamel(serviceFolder);

0 commit comments

Comments
 (0)