Skip to content

chore: Updated TypeDoc workflow to generate API docs #1060

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 19, 2020
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
44 changes: 18 additions & 26 deletions docgen/content-sources/node/toc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ toc:
path: /docs/reference/admin/node/admin.app
section:
- title: "App"
path: /docs/reference/admin/node/admin.app.App
path: /docs/reference/admin/node/admin.app.App-1

- title: "admin.auth"
path: /docs/reference/admin/node/admin.auth
section:
- title: "Auth"
path: /docs/reference/admin/node/admin.auth.Auth
path: /docs/reference/admin/node/admin.auth.Auth-1
- title: "ActionCodeSettings"
path: /docs/reference/admin/node/admin.auth.ActionCodeSettings
- title: "AuthProviderConfig"
Expand All @@ -36,6 +36,8 @@ toc:
path: /docs/reference/admin/node/admin.auth.CreatePhoneMultiFactorInfoRequest
- title: "CreateRequest"
path: /docs/reference/admin/node/admin.auth.CreateRequest
- title: "EmailSignInProviderConfig"
path: /docs/reference/admin/node/admin.auth.EmailSignInProviderConfig
- title: "ListProviderConfigResults"
path: /docs/reference/admin/node/admin.auth.ListProviderConfigResults
- title: "ListTenantsResult"
Expand Down Expand Up @@ -115,25 +117,13 @@ toc:
path: /docs/reference/admin/node/admin.credential
section:
- title: "Credential"
path: /docs/reference/admin/node/admin.credential.Credential
path: /docs/reference/admin/node/admin.credential.Credential-1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry if I missed something obvious! Why do we suffix these with -1?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's the name of the auto-generated file now.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that something we want, or is it kind of forced on us?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not by choice. It was the name auto picked by typedoc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is because we have merged declarations. credential is both a module and a namespace. TypeDoc is probably not handling that well.


- title: "admin.database"
path: /docs/reference/admin/node/admin.database
section:
- title: "Database"
path: /docs/reference/admin/node/admin.database.Database
- title: "DataSnapshot"
path: /docs/reference/admin/node/admin.database.DataSnapshot
- title: "OnDisconnect"
path: /docs/reference/admin/node/admin.database.OnDisconnect
- title: "Query"
path: /docs/reference/admin/node/admin.database.Query
- title: "Reference"
path: /docs/reference/admin/node/admin.database.Reference
- title: "ServerValue"
path: /docs/reference/admin/node/admin.database.ServerValue
- title: "ThenableReference"
path: /docs/reference/admin/node/admin.database.ThenableReference
path: /docs/reference/admin/node/admin.database.Database-1

- title: "admin.firestore"
path: /docs/reference/admin/node/admin.firestore
Expand All @@ -142,7 +132,7 @@ toc:
path: /docs/reference/admin/node/admin.instanceId
section:
- title: "InstanceId"
path: /docs/reference/admin/node/admin.instanceId.InstanceId
path: /docs/reference/admin/node/admin.instanceId.InstanceId-1

- title: "admin.machineLearning"
path: /docs/reference/admin/node/admin.machineLearning
Expand All @@ -152,7 +142,7 @@ toc:
- title: "ListModelsResult"
path: /docs/reference/admin/node/admin.machineLearning.ListModelsResult
- title: "MachineLearning"
path: /docs/reference/admin/node/admin.machineLearning.MachineLearning
path: /docs/reference/admin/node/admin.machineLearning.MachineLearning-1
- title: "Model"
path: /docs/reference/admin/node/admin.machineLearning.Model
- title: "ModelOptionsBase"
Expand All @@ -167,12 +157,14 @@ toc:
- title: "admin.messaging"
path: /docs/reference/admin/node/admin.messaging
section:
- title: "BaseMessage"
path: /docs/reference/admin/node/admin.messaging.BaseMessage
- title: "TopicMessage"
path: /docs/reference/admin/node/TopicMessage
path: /docs/reference/admin/node/admin.messaging.TopicMessage
- title: "TokenMessage"
path: /docs/reference/admin/node/TokenMessage
path: /docs/reference/admin/node/admin.messaging.TokenMessage
- title: "ConditionMessage"
path: /docs/reference/admin/node/ConditionMessage
path: /docs/reference/admin/node/admin.messaging.ConditionMessage
- title: "AndroidConfig"
path: /docs/reference/admin/node/admin.messaging.AndroidConfig
- title: "AndroidFcmOptions"
Expand All @@ -184,7 +176,7 @@ toc:
- title: "LightSettings"
path: /docs/reference/admin/node/admin.messaging.LightSettings
- title: "Messaging"
path: /docs/reference/admin/node/admin.messaging.Messaging
path: /docs/reference/admin/node/admin.messaging.Messaging-1
- title: "MessagingConditionResponse"
path: /docs/reference/admin/node/admin.messaging.MessagingConditionResponse
- title: "MessagingDeviceGroupResponse"
Expand Down Expand Up @@ -248,7 +240,7 @@ toc:
- title: "IosAppMetadata"
path: /docs/reference/admin/node/admin.projectManagement.IosAppMetadata
- title: "ProjectManagement"
path: /docs/reference/admin/node/admin.projectManagement.ProjectManagement
path: /docs/reference/admin/node/admin.projectManagement.ProjectManagement-1
- title: "ShaCertificate"
path: /docs/reference/admin/node/admin.projectManagement.ShaCertificate

Expand All @@ -264,19 +256,19 @@ toc:
- title: "RulesetMetadataList"
path: /docs/reference/admin/node/admin.securityRules.RulesetMetadataList
- title: "SecurityRules"
path: /docs/reference/admin/node/admin.securityRules.SecurityRules
path: /docs/reference/admin/node/admin.securityRules.SecurityRules-1

- title: "admin.storage"
path: /docs/reference/admin/node/admin.storage
section:
- title: "Storage"
path: /docs/reference/admin/node/admin.storage.Storage
path: /docs/reference/admin/node/admin.storage.Storage-1

- title: "admin.remoteConfig"
path: /docs/reference/admin/node/admin.remoteConfig
section:
- title: "RemoteConfig"
path: /docs/reference/admin/node/admin.remoteConfig.RemoteConfig
path: /docs/reference/admin/node/admin.remoteConfig.RemoteConfig-1
- title: "RemoteConfigTemplate"
path: /docs/reference/admin/node/admin.remoteConfig.RemoteConfigTemplate
- title: "RemoteConfigParameter"
Expand Down
86 changes: 75 additions & 11 deletions docgen/generate-docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,16 @@ const yaml = require('js-yaml');

const repoPath = path.resolve(`${__dirname}/..`);

const defaultSources = [
`${repoPath}/lib/firebase-namespace.d.ts`,
`${repoPath}/lib/firebase-namespace-api.d.ts`,
`${repoPath}/lib/**/*.d.ts`,
];

// Command-line options.
const { source: sourceFile } = yargs
.option('source', {
default: `${repoPath}/src/*.d.ts`,
default: defaultSources.join(' '),
describe: 'Typescript source file(s)',
type: 'string'
})
Expand All @@ -51,6 +57,17 @@ const firestoreHeader = `<section class="tsd-panel-group tsd-member-group ">
<ul>`;
const firestoreFooter = '\n </ul>\n</section>\n';

const databaseExcludes = ['enableLogging'];
const databaseHtmlPath = `${docPath}/admin.database.html`;
const databaseHeader = `<section class="tsd-panel-group tsd-member-group ">
<h2>Type aliases</h2>
<div class="tsd-panel">
<p>Following types are defined in the <code>@firebase/database</code> package
and re-exported from this namespace for convenience.</p>
</div>
<ul>`;
const databaseFooter = '\n </ul>\n</section>\n';

/**
* Strips path prefix and returns only filename.
* @param {string} path
Expand Down Expand Up @@ -99,7 +116,7 @@ function fixLinks(file) {
.replace(/(modules|interfaces|classes|enums)\//g, '');
let caseFixedLinks = flattenedLinks;
for (const lower in lowerToUpperLookup) {
const re = new RegExp(lower, 'g');
const re = new RegExp('\\b' + lower, 'g');
caseFixedLinks = caseFixedLinks.replace(re, lowerToUpperLookup[lower]);
}
return fs.writeFile(file, caseFixedLinks);
Expand All @@ -119,7 +136,7 @@ function generateTempHomeMdFile(tocRaw, homeRaw) {
const { toc } = yaml.safeLoad(tocRaw);
let tocPageLines = [homeRaw, '# API Reference'];
toc.forEach(group => {
tocPageLines.push(`\n## [${group.title}](${stripPath(group.path)})`);
tocPageLines.push(`\n## [${group.title}](${stripPath(group.path)}.html)`);
const section = group.section || [];
section.forEach(item => {
tocPageLines.push(`- [${item.title}](${stripPath(item.path)}.html)`);
Expand Down Expand Up @@ -150,13 +167,13 @@ function checkForMissingFilesAndFixFilenameCase() {
// Preferred filename for devsite should be capitalized and taken from
// toc.yaml.
const tocFilePath = `${docPath}/${filename}.html`;
// Generated filename from Typedoc will be lowercase.
const generatedFilePath = `${docPath}/${filename.toLowerCase()}.html`;
// Generated filename from Typedoc will be lowercase and won't have the admin prefix.
const generatedFilePath = `${docPath}/${filename.toLowerCase().replace('admin.', '')}.html`;
return fs.exists(generatedFilePath).then(exists => {
if (exists) {
// Store in a lookup table for link fixing.
lowerToUpperLookup[
`${filename.toLowerCase()}.html`
`${filename.toLowerCase().replace('admin.', '')}.html`
] = `${filename}.html`;
return fs.rename(generatedFilePath, tocFilePath);
} else {
Expand All @@ -167,6 +184,7 @@ function checkForMissingFilesAndFixFilenameCase() {
}
});
});

return Promise.all(fileCheckPromises).then(() => filenames);
}

Expand Down Expand Up @@ -253,15 +271,16 @@ function fixAllLinks(htmlFiles) {
* Updates the auto-generated Firestore API references page, by appending
* the specified HTML content block.
*
* @param {string} htmlPath Path of the HTML file to update.
* @param {string} contentBlock The HTML content block to be added to the Firestore docs.
*/
function updateFirestoreHtml(contentBlock) {
const dom = new jsdom.JSDOM(fs.readFileSync(firestoreHtmlPath));
function updateHtml(htmlPath, contentBlock) {
const dom = new jsdom.JSDOM(fs.readFileSync(htmlPath));
const contentNode = dom.window.document.body.querySelector('.col-12');

const newSection = new jsdom.JSDOM(contentBlock);
contentNode.appendChild(newSection.window.document.body.firstChild);
fs.writeFileSync(firestoreHtmlPath, dom.window.document.documentElement.outerHTML);
fs.writeFileSync(htmlPath, dom.window.document.documentElement.outerHTML);
}

/**
Expand All @@ -272,7 +291,7 @@ function updateFirestoreHtml(contentBlock) {
*/
function addFirestoreTypeAliases() {
return new Promise((resolve, reject) => {
const fileStream = fs.createReadStream(`${repoPath}/src/index.d.ts`);
const fileStream = fs.createReadStream(`${repoPath}/lib/firestore/index.d.ts`);
fileStream.on('error', (err) => {
reject(err);
});
Expand All @@ -297,7 +316,49 @@ function addFirestoreTypeAliases() {
lineReader.on('close', () => {
try {
contentBlock += firestoreFooter;
updateFirestoreHtml(contentBlock);
updateHtml(firestoreHtmlPath, contentBlock);
resolve();
} catch (err) {
reject(err);
}
});
});
}

/**
* Adds RTDB type aliases to the auto-generated API docs. These are the
* types that are imported from the @firebase/database package, and
* then re-exported from the admin.database namespace. Typedoc currently
* does not handle these correctly, so we need this solution instead.
*/
function addDatabaseTypeAliases() {
return new Promise((resolve, reject) => {
const fileStream = fs.createReadStream(`${repoPath}/lib/database/index.d.ts`);
fileStream.on('error', (err) => {
reject(err);
});
const lineReader = readline.createInterface({
input: fileStream,
});

let contentBlock = databaseHeader;
lineReader.on('line', (line) => {
line = line.trim();
if (line.startsWith('export import') && line.indexOf('rtdb.') >= 0) {
const typeName = line.split(' ')[2];
if (databaseExcludes.indexOf(typeName) === -1) {
contentBlock += `
<li>
<a href="/docs/reference/js/firebase.database.${typeName}.html">${typeName}</a>
</li>`;
}
}
});

lineReader.on('close', () => {
try {
contentBlock += databaseFooter;
updateHtml(databaseHtmlPath, contentBlock);
resolve();
} catch (err) {
reject(err);
Expand Down Expand Up @@ -349,6 +410,8 @@ Promise.all([
moveFilesToRoot('enums'),
]);
})
// Rename the globals file to be the top-level admin doc.
.then(() => fs.rename(`${docPath}/globals.html`, `${docPath}/admin.html`))
// Check for files listed in TOC that are missing and warn if so.
// Not blocking.
.then(checkForMissingFilesAndFixFilenameCase)
Expand All @@ -366,6 +429,7 @@ Promise.all([
// Add local variable include line to index.html (to access current SDK
// version number).
.then(addFirestoreTypeAliases)
.then(addDatabaseTypeAliases)
.then(() => {
fs.readFile(`${docPath}/index.html`, 'utf8').then(data => {
// String to include devsite local variables.
Expand Down
Loading