Skip to content

Add a flag allowing api-documenter to sort functions by first param #6623

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Oct 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/popular-beans-wonder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@firebase/api-documenter': minor
---

Add an option to sort functions by first param. (--sort-functions)
19 changes: 18 additions & 1 deletion repo-scripts/api-documenter/src/cli/MarkdownAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@
import { ApiDocumenterCommandLine } from './ApiDocumenterCommandLine';
import { BaseAction } from './BaseAction';
import { MarkdownDocumenter } from '../documenters/MarkdownDocumenter';
import { CommandLineStringParameter } from '@rushstack/ts-command-line';

export class MarkdownAction extends BaseAction {
private _sortFunctions!: CommandLineStringParameter;
public constructor(parser: ApiDocumenterCommandLine) {
super({
actionName: 'markdown',
Expand All @@ -33,10 +35,24 @@ export class MarkdownAction extends BaseAction {
});
}

protected onDefineParameters(): void {
super.onDefineParameters();

this._sortFunctions = this.defineStringParameter({
parameterLongName: '--sort-functions',
argumentName: 'PRIORITY_PARAMS',
description:
`Sorts functions tables and listings by first parameter. ` +
`Provide comma-separated strings for preferred params to be ` +
`ordered first. Alphabetical otherwise.`
});
}

protected async onExecute(): Promise<void> {
// override
const { apiModel, outputFolder, addFileNameSuffix, projectName } =
this.buildApiModel();
const sortFunctions: string = this._sortFunctions.value || '';

if (!projectName) {
throw new Error('No project name provided. Use --project.');
Expand All @@ -47,7 +63,8 @@ export class MarkdownAction extends BaseAction {
documenterConfig: undefined,
outputFolder,
addFileNameSuffix,
projectName
projectName,
sortFunctions
});
markdownDocumenter.generateFiles();
}
Expand Down
95 changes: 85 additions & 10 deletions repo-scripts/api-documenter/src/documenters/MarkdownDocumenter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export interface IMarkdownDocumenterOptions {
outputFolder: string;
addFileNameSuffix: boolean;
projectName: string;
sortFunctions: string;
}

/**
Expand All @@ -108,13 +109,15 @@ export class MarkdownDocumenter {
private readonly _pluginLoader: PluginLoader;
private readonly _addFileNameSuffix: boolean;
private readonly _projectName: string;
private readonly _sortFunctions: string;

public constructor(options: IMarkdownDocumenterOptions) {
this._apiModel = options.apiModel;
this._documenterConfig = options.documenterConfig;
this._outputFolder = options.outputFolder;
this._addFileNameSuffix = options.addFileNameSuffix;
this._projectName = options.projectName;
this._sortFunctions = options.sortFunctions;
this._tsdocConfiguration = CustomDocNodes.configuration;
this._markdownEmitter = new CustomMarkdownEmitter(this._apiModel);

Expand Down Expand Up @@ -834,11 +837,13 @@ page_type: reference
headerTitles: ['Enumeration', 'Description']
});

const functionsTable: DocTable = new DocTable({
const finalFunctionsTable: DocTable = new DocTable({
configuration,
headerTitles: ['Function', 'Description']
});

const functionsRowGroup: Record<string, DocTableRow[]> = {};

const interfacesTable: DocTable = new DocTable({
configuration,
headerTitles: ['Interface', 'Description']
Expand All @@ -859,7 +864,8 @@ page_type: reference
headerTitles: ['Type Alias', 'Description']
});

const functionsDefinitions: DocNode[] = [];
const functionsDefinitionsGroup: Record<string, DocNode[]> = {};
const finalFunctionsDefinitions: DocNode[] = [];
const variablesDefinitions: DocNode[] = [];
const typeAliasDefinitions: DocNode[] = [];
const enumsDefinitions: DocNode[] = [];
Expand Down Expand Up @@ -899,10 +905,29 @@ page_type: reference
break;

case ApiItemKind.Function:
functionsTable.addRow(row);
functionsDefinitions.push(
...this._createCompleteOutputForApiItem(apiMember)
);
/**
* If this option is set, group functions by first param.
* Organize using a map where the key is the first param.
*/
if (this._sortFunctions) {
const firstParam = (apiMember as ApiParameterListMixin)
.parameters[0] || { name: '' };
if (!functionsRowGroup[firstParam.name]) {
functionsRowGroup[firstParam.name] = [];
}
if (!functionsDefinitionsGroup[firstParam.name]) {
functionsDefinitionsGroup[firstParam.name] = [];
}
functionsRowGroup[firstParam.name].push(row);
functionsDefinitionsGroup[firstParam.name].push(
...this._createCompleteOutputForApiItem(apiMember)
);
} else {
finalFunctionsTable.addRow(row);
finalFunctionsDefinitions.push(
...this._createCompleteOutputForApiItem(apiMember)
);
}
break;

case ApiItemKind.TypeAlias:
Expand All @@ -921,9 +946,59 @@ page_type: reference
}
}

if (functionsTable.rows.length > 0) {
/**
* Sort the functions groups by first param. If priority params were
* provided to --sort-functions, will put them first in the order
* given.
*/
if (this._sortFunctions) {
let priorityParams: string[] = [];
if (this._sortFunctions.includes(',')) {
priorityParams = this._sortFunctions.split(',');
} else {
priorityParams = [this._sortFunctions];
}
const sortedFunctionsFirstParamKeys = Object.keys(functionsRowGroup).sort(
(a, b) => {
if (priorityParams.includes(a) && priorityParams.includes(b)) {
return priorityParams.indexOf(a) - priorityParams.indexOf(b);
} else if (priorityParams.includes(a)) {
return -1;
} else if (priorityParams.includes(b)) {
return 1;
}
return a.localeCompare(b);
}
);

for (const paramKey of sortedFunctionsFirstParamKeys) {
// Header for each group of functions grouped by first param.
// Doesn't make sense if there's only one group.
const headerText = paramKey ? `function(${paramKey}...)` : 'function()';
const formattedHeaderText = `<strong>${headerText}</strong>`;
if (sortedFunctionsFirstParamKeys.length > 1) {
finalFunctionsTable.addRow(
new DocTableRow({ configuration }, [
new DocTableCell({ configuration }, [
new DocParagraph({ configuration }, [
new DocPlainText({ configuration, text: formattedHeaderText })
])
])
])
);
}
for (const functionsRow of functionsRowGroup[paramKey]) {
finalFunctionsTable.addRow(functionsRow);
}
for (const functionDefinition of functionsDefinitionsGroup[paramKey]) {
finalFunctionsDefinitions.push(functionDefinition);
}
}
}

if (finalFunctionsTable.rows.length > 0) {
output.push(new DocHeading({ configuration, title: 'Functions' }));
output.push(functionsTable);
output.push(finalFunctionsTable);
}

if (classesTable.rows.length > 0) {
Expand Down Expand Up @@ -956,8 +1031,8 @@ page_type: reference
output.push(typeAliasesTable);
}

if (functionsDefinitions.length > 0) {
output.push(...functionsDefinitions);
if (finalFunctionsDefinitions.length > 0) {
output.push(...finalFunctionsDefinitions);
}

if (variablesDefinitions.length > 0) {
Expand Down
22 changes: 21 additions & 1 deletion scripts/docgen/docgen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,24 @@ https://github.com/firebase/firebase-js-sdk
const tmpDir = `${projectRoot}/temp`;
const EXCLUDED_PACKAGES = ['app-compat', 'util', 'rules-unit-testing'];

/**
* When ordering functions, will prioritize these first params at
* the top, in order.
*/
const PREFERRED_PARAMS = [
'app',
'analyticsInstance',
'appCheckInstance',
'db',
'firestore',
'functionsInstance',
'installations',
'messaging',
'performance',
'remoteConfig',
'storage'
];

yargs
.command(
'$0',
Expand Down Expand Up @@ -181,7 +199,9 @@ async function generateDocs(
'--output',
outputFolder,
'--project',
'js'
'js',
'--sort-functions',
PREFERRED_PARAMS.join(',')
],
{ stdio: 'inherit' }
);
Expand Down