mirror of
https://gitee.com/antv/g6.git
synced 2024-12-06 05:38:47 +08:00
7cc8278fc1
* feat: generate edge api docs * feat: generate node,combo style props docs * refactor: doc pipeline * docs: remove reference index.md
161 lines
5.2 KiB
TypeScript
161 lines
5.2 KiB
TypeScript
/**
|
|
* @file Using API Extractor to generate API Document Model files
|
|
*/
|
|
import { getPackages } from '@manypkg/get-packages';
|
|
import type { ExtractorResult, IConfigFile } from '@microsoft/api-extractor';
|
|
import { Extractor, ExtractorConfig } from '@microsoft/api-extractor';
|
|
import { EnumMemberOrder } from '@microsoft/api-extractor-model';
|
|
import { FileSystem } from '@rushstack/node-core-library';
|
|
import { execSync } from 'child_process';
|
|
import * as path from 'path';
|
|
|
|
/**
|
|
* Get a path relative to the base directory of this project. If called with no
|
|
* arguments it will return the base directory.
|
|
* @param paths - the paths to join
|
|
* @returns the resolved path
|
|
*/
|
|
export function baseDir(...paths: string[]): string {
|
|
return path.resolve('../../', path.join(...paths));
|
|
}
|
|
|
|
const separator = '__';
|
|
|
|
/**
|
|
* Mangle a scoped package name. Which removes the `@` symbol and adds a `__`
|
|
* separator.
|
|
* @example `@antv/g6` => `antv__g6`
|
|
* @param packageName - the package name to mangle
|
|
* @returns the mangled package name
|
|
*/
|
|
export function mangleScopedPackageName(packageName: string): string {
|
|
const [scope, name] = packageName.split('/');
|
|
if (name) {
|
|
return [scope.replace('@', ''), name].join(separator);
|
|
}
|
|
|
|
return scope;
|
|
}
|
|
|
|
const reportFolderRoot = path.resolve(path.join('support', 'api'));
|
|
const reportTempFolderRoot = path.resolve(reportFolderRoot, 'temp');
|
|
const ignorePackages = new Set<string>(['@antv/g6-site', '@antv/g6-extension-3d']);
|
|
|
|
/**
|
|
* Get all typed packages.
|
|
* @returns the list of packages
|
|
*/
|
|
async function getTypedPackages() {
|
|
const packages = await getPackages(baseDir());
|
|
return packages.packages.filter((pkg) => {
|
|
const json = pkg.packageJson;
|
|
return !json.private && !ignorePackages.has(json.name);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Run the api extractor for each package that extracts API type information and comments.
|
|
*/
|
|
async function runApiExtractor() {
|
|
const packages = await getTypedPackages();
|
|
|
|
const packageNameSet = new Set([...packages.map((pkg) => pkg.packageJson.name), '@antv/layout']);
|
|
|
|
for (const pkg of packages) {
|
|
const json = pkg.packageJson;
|
|
const name = mangleScopedPackageName(json.name);
|
|
const types = (json as any).types;
|
|
|
|
if (!types) {
|
|
throw new Error(`unable to find "types" in ${pkg.dir}`);
|
|
}
|
|
|
|
const relativePath = path.relative(baseDir(), pkg.dir);
|
|
const projectFolder = baseDir(relativePath);
|
|
const mainEntryPointFilePath = path.join(pkg.dir, types);
|
|
const packageJsonFullPath = path.join(pkg.dir, 'package.json');
|
|
const apiJsonFilePath = path.join(reportFolderRoot, `${name}.api.json`);
|
|
const reportFilePath = path.join(reportFolderRoot, `${name}.api.md`);
|
|
const reportTempFilePath = path.join(reportTempFolderRoot, `${name}.api.md`);
|
|
const reportFileName = path.parse(reportFilePath).base;
|
|
const reportFolder = path.parse(reportFilePath).dir;
|
|
const reportTempFolder = path.parse(reportTempFilePath).dir;
|
|
|
|
if (FileSystem.exists(packageJsonFullPath)) {
|
|
const packageJson = JSON.parse(FileSystem.readFile(packageJsonFullPath));
|
|
if ('build:cjs' in packageJson.scripts) {
|
|
execSync(`cd ${projectFolder} && pnpm run build:cjs`);
|
|
} else {
|
|
execSync(`cd ${projectFolder} && pnpm run build`);
|
|
}
|
|
} else {
|
|
console.error('package.json 文件未找到');
|
|
}
|
|
|
|
const configObject: IConfigFile = {
|
|
projectFolder,
|
|
mainEntryPointFilePath,
|
|
apiReport: {
|
|
enabled: true,
|
|
reportFolder,
|
|
reportFileName,
|
|
reportTempFolder,
|
|
},
|
|
docModel: {
|
|
enabled: true,
|
|
apiJsonFilePath,
|
|
},
|
|
compiler: {
|
|
tsconfigFilePath: path.join(projectFolder, 'src', 'tsconfig.json'),
|
|
overrideTsconfig: {
|
|
moduleResolution: 'nodenext',
|
|
},
|
|
skipLibCheck: true,
|
|
},
|
|
enumMemberOrder: EnumMemberOrder.Preserve,
|
|
// Make `export * from 'other-remirror-packages'` to work
|
|
bundledPackages: [
|
|
...Object.keys(pkg.packageJson.dependencies ?? {}),
|
|
...Object.keys(pkg.packageJson.devDependencies ?? {}),
|
|
...Object.keys(pkg.packageJson.peerDependencies ?? {}),
|
|
].filter((name) => packageNameSet.has(name)),
|
|
};
|
|
|
|
const extractorConfig: ExtractorConfig = ExtractorConfig.prepare({
|
|
configObject,
|
|
configObjectFullPath: undefined,
|
|
packageJson: json as any,
|
|
packageJsonFullPath,
|
|
});
|
|
|
|
console.log(`running API Extractor for ${json.name}`);
|
|
|
|
const extractorResult: ExtractorResult = Extractor.invoke(extractorConfig, {
|
|
// Equivalent to the "--local" command-line parameter
|
|
localBuild: true,
|
|
|
|
// Equivalent to the "--verbose" command-line parameter
|
|
showVerboseMessages: true,
|
|
});
|
|
|
|
if (extractorResult.succeeded) {
|
|
console.log(`successfully completed API Extractor for ${json.name}`);
|
|
} else {
|
|
console.error(
|
|
`API Extractor completed with ${extractorResult.errorCount} errors and ${extractorResult.warningCount} warnings`,
|
|
);
|
|
throw new Error('failed to run API Extractor');
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Run the API extractor and then delete the temp folder.
|
|
* Self invoking function.
|
|
*/
|
|
(async function run() {
|
|
await FileSystem.deleteFolder(reportFolderRoot);
|
|
await runApiExtractor();
|
|
await FileSystem.deleteFolder(reportTempFolderRoot);
|
|
})();
|