Skip to content
This repository has been archived by the owner on Jun 15, 2024. It is now read-only.

Commit

Permalink
docs: update the api reference
Browse files Browse the repository at this point in the history
  • Loading branch information
jordimarimon committed Oct 1, 2023
1 parent d437bcb commit 41d6a08
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 44 deletions.
4 changes: 2 additions & 2 deletions packages/core/src/parse-from-glob.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import { parseFromFiles } from './parse-from-files.js';
import { globbySync } from 'globby';

/**
* Given some [glob](https://en.wikipedia.org/wiki/Glob_(programming))
* Given some [glob]{@link https://en.wikipedia.org/wiki/Glob_(programming)}
* patterns and some configurable options, reflects a simplified version
* of the TypeScript Abstract Syntax Tree.
*
* Internally [globby](https://github.com/sindresorhus/globby) handles the pattern matching.
* Internally [globby]{@link https://github.com/sindresorhus/globby} handles the pattern matching.
* Any pattern that `globby` accepts can be used.
*
* @param patterns - A string or an array of strings that represent glob patterns
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/utils/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import ts from 'typescript';
* Checks if the version of TypeScript being used is >= 4.8
*
* TypeScript introduced breaking changes in v4.8 with how to access decorators and modifiers.
* See [TypeScript 4.8 release notes](https://devblogs.microsoft.com/typescript/announcing-typescript-4-8).
* See [TypeScript 4.8 release notes]{@link https://devblogs.microsoft.com/typescript/announcing-typescript-4-8}.
*
* @returns True if the TypeScript version is >= 4.8
*/
Expand Down
7 changes: 6 additions & 1 deletion scripts/docs/build-docs.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ function build(entryPoints) {
target: 'es2022',
outdir: '_site/assets/js',
entryNames: '[name]',
external: ['node:path', 'node:fs', 'node:process'],
external: [
'node:path',
'node:fs',
'node:process',
'node:module',
],
});
}

Expand Down
96 changes: 56 additions & 40 deletions scripts/docs/generate-api-reference.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DeclarationKind, DocTagName, is, parseFromGlob } from '@ts-ast-parser/core';
import { DeclarationKind, is, parseFromGlob } from '@ts-ast-parser/core';
import MarkdownIt from 'markdown-it';
import Handlebars from 'handlebars';
import * as path from 'node:path';
Expand All @@ -14,8 +14,27 @@ const md = new MarkdownIt({

// Handlebars Helpers
Handlebars.registerHelper('firstLetter', str => str[0].toUpperCase());
Handlebars.registerHelper('markdownToHTML', str => {
let html = md.render(str);
Handlebars.registerHelper('markdownToHTML', commentPart => {
const parts = Array.isArray(commentPart)
? commentPart
: typeof commentPart === 'string'
? [{kind: 'text', text: commentPart}]
: [commentPart];

const markdown = [];
for (const part of parts) {
let partMd = '';

if (part.kind === 'text') {
partMd = part.text;
} else {
partMd = `[${part.targetText || part.target}](${part.target})`;
}

markdown.push(partMd);
}

let html = md.render(markdown.join(' '));
html = html.replaceAll(/<a/g, '<a class="prose" target="_blank"');
html = html.replaceAll(/<code/g, '<code class="code"');
html = html.replaceAll(/<ul/g, '<ul class="disc"');
Expand All @@ -30,10 +49,6 @@ Handlebars.registerHelper('typeWithReference', type => {
return new Handlebars.SafeString(`<code class="code code-accent">${text}</code>`);
});

// Obtain the reflected modules
const {project} = await parseFromGlob('packages/core/src/**/*.ts');
const reflectedModules = project?.getModules() ?? [];

// Handlebars templates
const { pathname: cwd } = new URL('../..', import.meta.url);
const templatesDir = path.join(cwd, 'scripts', 'docs');
Expand All @@ -52,47 +67,51 @@ const templateVariable = Handlebars.compile(templateVariableFile, { noEscape: tr
const templateTypeAliasFile = fs.readFileSync(path.join(templatesDir, 'type-alias.hbs'), 'utf8');
const templateTypeAlias = Handlebars.compile(templateTypeAliasFile, { noEscape: true });

// Here we will store the data for the templates
const models = [];
const utils = [];
const nodes = [];
const types = [];
const parsers = [];

// Clear the directories
clearDir('models');
clearDir('utils');
clearDir('nodes');
clearDir('types');
clearDir('parsers');

// Obtain the reflected modules
const indexPath = path.join('packages', 'core', 'src', 'index.ts');
const {project} = await parseFromGlob('packages/core/src/**/*.ts');
const reflectedModules = project?.getModules() ?? [];
const indexModule = reflectedModules.find(mod => mod.getSourcePath() === indexPath);

if (!indexModule) {
console.error("Couldn't found the index file of the package.");
process.exit(1);
}

const publicFiles = indexModule
// The modules that are explicitly exported in the entry point of the package
const publicModules = indexModule
.getExports()
.filter(exp => is.ReExportNode(exp))
.map(exp => {
const modulePath = exp.getModule().replace(/'/g, '');
// Modern ESM imports include the ".js" extension
const modulePath = exp.getModule().replace(/'/g, '').replace('.js', '.ts');
return path.join('packages', 'core', 'src', modulePath);
});

// Here we will store the data for the templates
const models = [];
const utils = [];
const nodes = [];
const types = [];
const parsers = [];

// Clear the directories
clearDir('models');
clearDir('utils');
clearDir('nodes');
clearDir('types');
clearDir('parsers');

// Loop through each reflected module and create the data for the templates
for (const module of reflectedModules) {
const modulePath = module.getSourcePath();

if (!publicFiles.includes(modulePath.replace('.ts', '.js'))) {
if (!publicModules.includes(modulePath)) {
continue;
}

const segments = modulePath.split(path.sep);
const declarations = module.getDeclarations();

const fileBaseName = segments[segments.length - 1].replace('.ts', '');
const category = segments[segments.length - 2];
const normalizedCategory = category === 'src'
Expand Down Expand Up @@ -190,7 +209,7 @@ function createInterface(inter, category, filePath) {
name: inter.getName(),
path: filePath,
line: inter.getLine(),
description: jsDoc.getTag(DocTagName.description)?.serialize() ?? '',
description: jsDoc.getTag('description')?.text ?? '',
properties: inter.getProperties().map(p => createPropertyContext(p, filePath)),
methods: inter.getMethods().map(m => createFunctionContext(m, filePath)),
};
Expand All @@ -207,7 +226,7 @@ function createClass(clazz, category, filePath) {
name: clazz.getName(),
path: filePath,
line: clazz.getLine(),
description: jsDoc.getTag(DocTagName.description)?.serialize() ?? '',
description: jsDoc.getTag('description')?.text ?? '',
methods: clazz.getMethods().map(m => createFunctionContext(m, filePath)),
};

Expand All @@ -223,11 +242,11 @@ function createEnum(enumerable, category, filePath) {
name: enumerable.getName(),
path: filePath,
line: enumerable.getLine(),
description: jsDoc.getTag(DocTagName.description)?.serialize() ?? '',
description: jsDoc.getTag('description')?.text ?? '',
members: enumerable.getMembers().map(member => ({
name: member.getName(),
value: member.getValue(),
description: member.getJSDoc().getTag(DocTagName.description)?.serialize() ?? '',
description: member.getJSDoc().getTag('description')?.text ?? '',
})),
};

Expand All @@ -244,7 +263,7 @@ function createVariable(variable, category, filePath) {
name: variable.getName(),
path: filePath,
line: variable.getLine(),
description: jsDoc.getTag(DocTagName.description)?.serialize() ?? '',
description: jsDoc.getTag('description')?.text ?? '',
value: variable.getValue(),
};

Expand All @@ -260,7 +279,7 @@ function createTypeAlias(typeAlias, category, filePath) {
name: typeAlias.getName(),
path: filePath,
line: typeAlias.getLine(),
description: jsDoc.getTag(DocTagName.description)?.serialize() ?? '',
description: jsDoc.getTag('description')?.text ?? '',
value: typeAlias.getValue().getText(),
};

Expand All @@ -274,7 +293,7 @@ function createFunctionContext(func, filePath) {
const signature = func.getSignatures()[0];
const funcJsDoc = func.isArrowFunctionOrFunctionExpression() ? func.getJSDoc() : signature.getJSDoc();
const returnType = signature.getReturnType();
const returnTypeDescription = funcJsDoc.getTag(DocTagName.returns)?.serialize() ?? '';
const returnTypeDescription = funcJsDoc.getTag('returns')?.text ?? '';
const typeParameters = signature.getTypeParameters().map(t => {
return {
name: t.getName(),
Expand All @@ -284,10 +303,7 @@ function createFunctionContext(func, filePath) {
});
const parameters = signature.getParameters().map(p => ({
name: p.getName(),
description: funcJsDoc
.getAllTags(DocTagName.param)
?.find(t => t.getName() === p.getName())
?.getDescription() ?? '',
description: funcJsDoc.getAllTags('param')?.find(t => t.name === p.getName())?.text ?? '',
type: {text: p.getType().getText()},
default: p.getDefault(),
}));
Expand All @@ -309,8 +325,8 @@ function createFunctionContext(func, filePath) {
name: func.getName(),
path: filePath,
line: signature.getLine(),
description: funcJsDoc.getTag(DocTagName.description)?.serialize() ?? '',
see: funcJsDoc.getAllTags(DocTagName.see),
description: funcJsDoc.getTag('description')?.text ?? '',
see: funcJsDoc.getAllTags('see'),
signature: `${func.getName()}${typeParametersJoined}(${parametersStringify}): ${returnType.getText()}`,
parameters,
typeParameters,
Expand All @@ -326,8 +342,8 @@ function createPropertyContext(property, filePath) {
name: property.getName(),
path: filePath,
line: property.getLine(),
description: property.getJSDoc().getTag(DocTagName.description)?.serialize() ?? '',
see: property.getJSDoc().getAllTags(DocTagName.see),
description: property.getJSDoc().getTag('description')?.text ?? '',
see: property.getJSDoc().getAllTags('see'),
type: {
text: property.getType().getText(),
},
Expand Down

0 comments on commit 41d6a08

Please sign in to comment.