Skip to content

Commit

Permalink
Merge branch 'main' into chore/vite-rollup-recipe
Browse files Browse the repository at this point in the history
  • Loading branch information
sarah11918 authored Nov 10, 2023
2 parents 544e2b5 + 2a54003 commit 0456857
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 152 deletions.
114 changes: 77 additions & 37 deletions scripts/docgen.mjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// @ts-check

import fs from 'fs';
import jsdoc from 'jsdoc-api';
import fetch from 'node-fetch';
Expand Down Expand Up @@ -42,86 +44,97 @@ const FOOTER = ``;
export async function run() {
const sourceBranch = process.env.SOURCE_BRANCH || 'main';
const sourceRepo = process.env.SOURCE_REPO || 'withastro/astro';

let task = 'Fetch `@types/astro.ts` from ' + sourceRepo + '#' + sourceBranch;
console.time(task);

const inputBuffer =
STUB ||
(await fetch(
`https://raw.githubusercontent.com/${sourceRepo}/${sourceBranch}/packages/astro/src/%40types/astro.ts`
).then((r) => r.text()));

console.timeEnd(task);
task = 'Parse types and generate configuration reference';
console.time(task);

// Get all `@docs` JSDoc comments in the file.
const allComments = [
...inputBuffer.matchAll(/\/\*\*\s*\n([^\*]|\*[^\/])*@docs([^\*]|\*[^\/])*\*\//g),
...inputBuffer.matchAll(/\/\*\*\s*\n([^*]|\*[^/])*@docs([^*]|\*[^/])*\*\//g),
];
const allCommentsInput = allComments
.map((m) => m[0])
.filter((c) => c.includes('* @docs'))
.join('\n\n');

console.log(jsdoc);
console.log(allCommentsInput);
console.log(jsdoc.explainSync({ source: allCommentsInput }));

const allParsedComments = jsdoc
.explainSync({ source: allCommentsInput })
.filter((data) => data.tags);

let result = ``;

for (const comment of allParsedComments) {
if (comment.kind === 'heading') {
result += `## ${comment.name}\n\n`;
if (comment.description) {
result += comment.description.trim() + '\n\n';
}
continue;
}
const cliFlag = comment.tags.find((f) => f.title === 'cli');
const typerawFlag = comment.tags.find((f) => f.title === 'typeraw');
if (!comment.name) {
throw new Error(`Missing @docs JSDoc tag: @name`);
}
if (!comment.type && !typerawFlag) {
throw new Error(`Missing @docs JSDoc tag: @type or @typeraw`);
}
const typesFormatted = typerawFlag
? typerawFlag.text.replace(/\{(.*)\}/, '$1')
: comment.type.names.join(' | ');

result += [
`### ${comment.longname}`,
``,
getHeading(comment),
getDeprecatedAside(comment.deprecated),
`<p>`,
``,
[
`**Type:** \`${typesFormatted}\``,
cliFlag ? `**CLI:** \`${cliFlag.text}\`` : undefined,
comment.defaultvalue ? `**Default:** ${comment.defaultvalue}` : undefined,
comment.version ? `<Since v="${comment.version}" />` : undefined,
]
.filter((l) => l !== undefined)
.join('<br />\n'),
`</p>`,
``,
comment.description && comment.description.trim(),
getCommentProperties(comment),
comment.description?.trim() || undefined,
comment.see
? `**See Also:**\n${comment.see.map((s) => `- ${s}`.trim()).join('\n')}`
: undefined,
`\n\n`,
`\n`,
]
.filter((l) => l !== undefined)
.join('\n');
}

// Make any links to docs relative instead of absolute.
result = result.replace(/https:\/\/docs\.astro\.build\//g, '/');

console.log(result);
console.timeEnd(task);
task = 'Update configuration-reference.mdx';
console.time(task);

fs.writeFileSync(
'src/content/docs/en/reference/configuration-reference.mdx',
HEADER + result + FOOTER,
'utf8'
);

console.timeEnd(task);
}

/**
* Create a string of ### to create a Markdown heading for the given level.
* @param {number} headingLevel
*/
function h(headingLevel) {
return Array.from({ length: headingLevel }).fill('#').join('');
}

/**
* Get a Markdown heading of the correct level for this comment.
* @param {{ kind: string | undefined; longname: string }} comment
*/
function getHeading(comment) {
let headingLevel = 3;
const headingMatches = /^h(1|2|3|4|5|6)$/.exec(comment.kind || '');
if (headingMatches) {
headingLevel = parseInt(headingMatches[1]);
} else if (comment.kind === 'heading') {
headingLevel = 2;
}
return `${h(headingLevel)} ${comment.longname}\n`;
}

/**
* Get a `:::caution` block if the passed tag is deprecated.
* @param {string | undefined} tag
*/
function getDeprecatedAside(tag) {
if (!tag) return undefined;
return [
Expand All @@ -133,4 +146,31 @@ function getDeprecatedAside(tag) {
].join('\n');
}

/**
* Get block of type, CLI command, default value, and version added in for the current comment.
* @param {{ tags: { title: string; text: string }[]; kind: string; type?: { names: string [] }; defaultvalue?: string; version?: string }} comment
*/
function getCommentProperties(comment) {
const cliFlag = comment.tags.find((f) => f.title === 'cli');
const typerawFlag = comment.tags.find((f) => f.title === 'typeraw');

if (comment.kind !== 'heading' && !comment.type && !typerawFlag) {
throw new Error(`Missing @docs JSDoc tag: @type or @typeraw`);
}
const typesFormatted = typerawFlag
? typerawFlag.text.replace(/\{(.*)\}/, '$1')
: comment.type?.names.join(' | ');

const properties = [
typesFormatted ? `**Type:** \`${typesFormatted}\`` : undefined,
cliFlag ? `**CLI:** \`${cliFlag.text}\`` : undefined,
comment.defaultvalue ? `**Default:** ${comment.defaultvalue}` : undefined,
comment.version ? `<Since v="${comment.version}" />` : undefined,
]
.filter((l) => l !== undefined)
.join('<br />\n');

return properties.length ? ['<p>', '', properties, '</p>', ''].join('\n') : undefined;
}

run();
Loading

0 comments on commit 0456857

Please sign in to comment.