mirror of https://github.com/msgbyte/tailchat
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
2.3 KiB
TypeScript
91 lines
2.3 KiB
TypeScript
import { parse, ParserPlugin } from '@babel/parser';
|
|
import traverse from '@babel/traverse';
|
|
import generate from '@babel/generator';
|
|
import template from '@babel/template';
|
|
import type { Comment } from '@babel/types';
|
|
import { program, isFunctionDeclaration } from '@babel/types';
|
|
import fs from 'fs-extra';
|
|
import _ from 'lodash';
|
|
|
|
export * from './tsgenerator';
|
|
export * from './parser';
|
|
|
|
const babelPlugins: ParserPlugin[] = ['jsx', 'typescript'];
|
|
const buildNamedExport = template('export function %%name%%(): any', {
|
|
plugins: babelPlugins,
|
|
});
|
|
|
|
interface Options {
|
|
entryPath: string;
|
|
// targetPath: string; // TODO
|
|
}
|
|
export async function generateFunctionDeclare(options: Options) {
|
|
const sourcecode = await fs.readFile(options.entryPath, 'utf8');
|
|
|
|
const exported = getSourceCodeExportedFunction(sourcecode);
|
|
|
|
const astList = exported.map((e) => {
|
|
return buildNamedExport({
|
|
name: e.name,
|
|
});
|
|
});
|
|
|
|
const code = generate(program(_.flatten(astList))).code;
|
|
|
|
return code;
|
|
}
|
|
|
|
interface ExportedItem {
|
|
name: string;
|
|
comments?: string;
|
|
}
|
|
function getSourceCodeExportedFunction(sourcecode: string): ExportedItem[] {
|
|
const ast = parse(sourcecode, {
|
|
sourceType: 'module',
|
|
plugins: babelPlugins,
|
|
});
|
|
|
|
const exported: ExportedItem[] = [];
|
|
|
|
traverse(ast, {
|
|
ExportNamedDeclaration({ node }) {
|
|
if (node.declaration) {
|
|
if (isFunctionDeclaration(node.declaration)) {
|
|
const name = node.declaration.id?.name;
|
|
if (typeof name === 'string') {
|
|
exported.push({
|
|
name,
|
|
comments: getCommentStr(node.leadingComments),
|
|
});
|
|
}
|
|
}
|
|
} else {
|
|
const names = node.specifiers.map((s) => {
|
|
const exported = s.exported;
|
|
if (exported.type === 'Identifier') {
|
|
return {
|
|
name: exported.name,
|
|
comments: getCommentStr(node.leadingComments),
|
|
};
|
|
} else {
|
|
return null;
|
|
}
|
|
});
|
|
exported.push(...names.filter((n): n is any => !!n));
|
|
}
|
|
},
|
|
});
|
|
|
|
return exported;
|
|
}
|
|
|
|
function getCommentStr(
|
|
comments: Comment[] | null | undefined
|
|
): string | undefined {
|
|
if (!comments) {
|
|
return undefined;
|
|
}
|
|
|
|
return comments.map((c) => c.value).join('\n');
|
|
}
|