Skip to content

Commit

Permalink
feat(PluginsConfig): add pluginConfigs to the parsed data
Browse files Browse the repository at this point in the history
Parses any `interface PluginsConfig {}` found within  `declare module '@capacitor/cli'` and adds the data to the data returned from the `parse()` API. This can be used to auto-generate docs for plugin configs.
  • Loading branch information
adamdbradley committed Feb 26, 2021
1 parent 81104d0 commit 3511c54
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 2 deletions.
63 changes: 62 additions & 1 deletion src/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type {
DocsMethodParam,
DocsJsDoc,
DocsInterfaceProperty,
DocsConfigInterface,
DocsTypeAlias,
DocsTypeAliasReference,
} from './types';
Expand All @@ -30,9 +31,17 @@ export function parse(opts: DocsParseOptions) {
const interfaces: DocsInterface[] = [];
const enums: DocsEnum[] = [];
const typeAliases: DocsTypeAlias[] = [];
const pluginConfigs: DocsInterface[] = [];

tsSourceFiles.forEach(tsSourceFile => {
parseSourceFile(tsSourceFile, typeChecker, interfaces, typeAliases, enums);
parseSourceFile(
tsSourceFile,
typeChecker,
interfaces,
typeAliases,
enums,
pluginConfigs,
);
});

return (api: string) => {
Expand All @@ -43,6 +52,7 @@ export function parse(opts: DocsParseOptions) {
interfaces: [],
enums: [],
typeAliases: [],
pluginConfigs,
};

if (apiInterface) {
Expand Down Expand Up @@ -108,11 +118,13 @@ function parseSourceFile(
interfaces: DocsInterface[],
typeAliases: DocsTypeAlias[],
enums: DocsEnum[],
pluginConfigs: DocsInterface[],
) {
const statements = tsSourceFile.statements;
const interfaceDeclarations = statements.filter(ts.isInterfaceDeclaration);
const typeAliasDeclarations = statements.filter(ts.isTypeAliasDeclaration);
const enumDeclarations = statements.filter(ts.isEnumDeclaration);
const moduleDeclarations = statements.filter(ts.isModuleDeclaration);

interfaceDeclarations.forEach(interfaceDeclaration => {
interfaces.push(getInterface(typeChecker, interfaceDeclaration));
Expand All @@ -125,6 +137,12 @@ function parseSourceFile(
typeAliasDeclarations.forEach(typeAliasDeclaration => {
typeAliases.push(getTypeAlias(typeChecker, typeAliasDeclaration));
});

moduleDeclarations
.filter(m => m?.name?.text === '@capacitor/cli')
.forEach(moduleDeclaration => {
getPluginsConfig(typeChecker, moduleDeclaration, pluginConfigs);
});
}

function getInterface(
Expand Down Expand Up @@ -338,6 +356,49 @@ function getInterfaceProperty(
return p;
}

function getPluginsConfig(
typeChecker: ts.TypeChecker,
moduleDeclaration: ts.ModuleDeclaration,
pluginConfigs: DocsConfigInterface[],
) {
const body = moduleDeclaration.body as ts.ModuleBlock;
if (!Array.isArray(body.statements)) {
return;
}

const pluginConfigInterfaces = body.statements.filter(
(s: ts.InterfaceDeclaration) =>
s?.name?.text === 'PluginsConfig' &&
Array.isArray(s?.members) &&
s.members.length > 0,
) as ts.InterfaceDeclaration[];

pluginConfigInterfaces.forEach(pluginConfigInterface => {
pluginConfigInterface.members
.filter(ts.isPropertySignature)
.filter(p => p?.type && (p?.type as ts.TypeLiteralNode).members)
.forEach(properytSignature => {
const typeLiteral = properytSignature.type as ts.TypeLiteralNode;

const nm = properytSignature.name.getText();
const i: DocsConfigInterface = {
name: nm,
slug: slugify(nm),
properties: typeLiteral.members
.filter(ts.isPropertySignature)
.map(propertySignature => {
return getInterfaceProperty(typeChecker, propertySignature);
})
.filter(p => p != null) as DocsInterfaceProperty[],
};

if (i.properties.length > 0) {
pluginConfigs.push(i);
}
});
});
}

function typeToString(
checker: ts.TypeChecker,
type: ts.Type,
Expand Down
23 changes: 23 additions & 0 deletions src/test/fixtures/definitions.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
/// <reference types="@capacitor/cli" />

declare module '@capacitor/cli' {
export interface PluginsConfig {
Haptics?: {
/**
* Configure the style.
*
* @since 1.0.0
* @default native
*/
style?: 'none' | 'native';

/**
* Configure the duration.
*
* @since 1.2.3
*/
duration?: number;
};
}
}

/**
* ## Docs from JSDoc comments!
*
Expand Down
32 changes: 31 additions & 1 deletion src/test/parse.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ describe('parse', () => {
tsconfigPath: path.join(__dirname, 'fixtures', 'tsconfig.json'),
});

const { api, interfaces, enums, typeAliases } = apiFinder('HapticsPlugin');
const { api, interfaces, enums, typeAliases, pluginConfigs } = apiFinder(
'HapticsPlugin',
);

it('api', () => {
expect(api.name).toBe(`HapticsPlugin`);
Expand Down Expand Up @@ -139,4 +141,32 @@ describe('parse', () => {
expect(t1.slug).toBe(`repeatschedule`);
expect(t1.types).toHaveLength(4);
});

it('Plugins Config', () => {
expect(pluginConfigs).toHaveLength(1);
const p = pluginConfigs.find(i => i.name === `Haptics`);

expect(p.slug).toBe(`haptics`);
expect(p.properties).toHaveLength(2);

const p0 = p.properties[0];
expect(p0.name).toBe(`style`);
expect(p0.docs).toBe(`Configure the style.`);
expect(p0.type).toBe(`'none' | 'native' | undefined`);
expect(p0.complexTypes).toHaveLength(0);
expect(p0.tags).toHaveLength(2);
expect(p0.tags[0].name).toBe(`since`);
expect(p0.tags[0].text).toBe(`1.0.0`);
expect(p0.tags[1].name).toBe(`default`);
expect(p0.tags[1].text).toBe(`native`);

const p1 = p.properties[1];
expect(p1.name).toBe(`duration`);
expect(p1.docs).toBe(`Configure the duration.`);
expect(p1.type).toBe(`number | undefined`);
expect(p1.complexTypes).toHaveLength(0);
expect(p1.tags).toHaveLength(1);
expect(p1.tags[0].name).toBe(`since`);
expect(p1.tags[0].text).toBe(`1.2.3`);
});
});
7 changes: 7 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ export interface DocsData {
interfaces: DocsInterface[];
typeAliases: DocsTypeAlias[];
enums: DocsEnum[];
pluginConfigs: DocsConfigInterface[];
}

export interface DocsConfigInterface {
name: string;
slug: string;
properties: DocsInterfaceProperty[];
}

export interface DocsInterface {
Expand Down

0 comments on commit 3511c54

Please sign in to comment.