Skip to content

Commit

Permalink
feat apilinks.json generator
Browse files Browse the repository at this point in the history
Closes #152

Signed-off-by: flakey5 <73616808+flakey5@users.noreply.github.com>
  • Loading branch information
flakey5 committed Nov 29, 2024
1 parent db50bb6 commit 96355ad
Show file tree
Hide file tree
Showing 15 changed files with 645 additions and 11 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ Options:
-o, --output <path> Specify the relative or absolute output directory
-v, --version <semver> Specify the target version of Node.js, semver compliant (default: "v22.6.0")
-c, --changelog <url> Specify the path (file: or https://) to the CHANGELOG.md file (default: "https://raw.githubusercontent.com/nodejs/node/HEAD/CHANGELOG.md")
-t, --target [mode...] Set the processing target modes (choices: "json-simple", "legacy-html", "legacy-html-all", "man-page", "legacy-json", "legacy-json-all")
-t, --target [mode...] Set the processing target modes (choices: "json-simple", "legacy-html", "legacy-html-all", "man-page", "legacy-json", "legacy-json-all", "api-links")
-h, --help display help for command
```
14 changes: 11 additions & 3 deletions bin/cli.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,22 @@ program
*/
const { input, output, target = [], version, changelog } = program.opts();

const { loadFiles } = createLoader();
const { parseApiDocs } = createParser();
const { loadFiles, loadJsFiles } = createLoader();
const { parseApiDocs, parseJsSources } = createParser();

const apiDocFiles = loadFiles(input);

const parsedApiDocs = await parseApiDocs(apiDocFiles);

const { runGenerators } = createGenerator(parsedApiDocs);
const sourceFiles = loadJsFiles(
parsedApiDocs
.map(apiDoc => apiDoc.source_link_local)
.filter(path => path !== undefined && path.endsWith('.js'))
);

const parsedJsFiles = await parseJsSources(sourceFiles);

const { runGenerators } = createGenerator(parsedApiDocs, parsedJsFiles);

// Retrieves Node.js release metadata from a given Node.js version and CHANGELOG.md file
const { getAllMajors } = createNodeReleases(changelog);
Expand Down
7 changes: 4 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"prettier": "3.3.3"
},
"dependencies": {
"acorn": "^8.14.0",
"commander": "^12.1.0",
"github-slugger": "^2.0.0",
"glob": "^11.0.0",
Expand Down
8 changes: 6 additions & 2 deletions src/generators.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,20 @@ import availableGenerators from './generators/index.mjs';
* the final generators in the chain.
*
* @param {ApiDocMetadataEntry} input The parsed API doc metadata entries
* @param {Array<import('acorn').Program>} parsedJsFiles
*/
const createGenerator = input => {
const createGenerator = (input, parsedJsFiles) => {
/**
* We store all the registered generators to be processed
* within a Record, so we can access their results at any time whenever needed
* (we store the Promises of the generator outputs)
*
* @type {{ [K in keyof AllGenerators]: ReturnType<AllGenerators[K]['generate']> }}
*/
const cachedGenerators = { ast: Promise.resolve(input) };
const cachedGenerators = {
ast: Promise.resolve(input),
'ast-js': Promise.resolve(parsedJsFiles),
};

/**
* Runs the Generator engine with the provided top-level input and the given generator options
Expand Down
95 changes: 95 additions & 0 deletions src/generators/api-links/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
'use strict';

import { basename, dirname, join } from 'node:path';
import { writeFile } from 'node:fs/promises';
import { getGitRepository, getGitTag } from '../../utils/git.mjs';
import { extractExports } from './utils/extractExports.mjs';
import { findDefinitions } from './utils/findDefinitions.mjs';

/**
* This generator is responsible for mapping publicly accessible functions in
* Node.js to their source locations in the Node.js repository.
*
* This is a top-level generator. It takes in the raw AST tree of the JavaScript
* source files. It outputs a `apilinks.json` file into the specified output
* directory.
*
* @typedef {Array<JsProgram>} Input
*
* @type {import('../types.d.ts').GeneratorMetadata<Input, Record<string, string>>}
*/
export default {
name: 'api-links',

version: '1.0.0',

description:
'Creates a mapping of publicly accessible functions to their source locations in the Node.js repository.',

dependsOn: 'ast-js',

/**
* Generates the `apilinks.json` file.
*
* @param {Input} input
* @param {Partial<GeneratorOptions>} options
*/
async generate(input, { output }) {
/**
* @type {Record<string, string>}
*/
const definitions = {};

/**
* @type {string}
*/
let baseGithubLink;

input.forEach(program => {
/**
* Mapping of definitions to their line number
* @type {Record<string, number>}
* @example { 'someclass.foo', 10 }
*/
const nameToLineNumberMap = {};

const programBasename = basename(program.path, '.js');

const exports = extractExports(
program,
programBasename,
nameToLineNumberMap
);

findDefinitions(program, programBasename, nameToLineNumberMap, exports);

if (!baseGithubLink) {
const directory = dirname(program.path);

const repository = getGitRepository(directory);

const tag = getGitTag(directory);

baseGithubLink = `https://github.com/${repository}/blob/${tag}`;
}

const githubLink =
`${baseGithubLink}/lib/${programBasename}.js`.replaceAll('\\', '/');

Object.keys(nameToLineNumberMap).forEach(key => {
const lineNumber = nameToLineNumberMap[key];

definitions[key] = `${githubLink}#L${lineNumber}`;
});
});

if (output) {
await writeFile(
join(output, 'apilinks.json'),
JSON.stringify(definitions)
);
}

return definitions;
},
};
4 changes: 4 additions & 0 deletions src/generators/api-links/types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface ProgramExports {
ctors: Array<string>;
identifiers: Array<string>;
}
Loading

0 comments on commit 96355ad

Please sign in to comment.