utquidem
Version:
The meta-framework suite designed from scratch for frontend-focused modern web development.
96 lines (84 loc) • 2.42 kB
text/typescript
import fs from 'fs';
import { merge } from '@modern-js/utils/lodash';
import ts from 'typescript';
let enumsMap = {};
const createEnumObject = (enumNode: ts.EnumDeclaration, namespace?: string) => {
let obj: Record<string, unknown> = {};
const finnal = obj;
if (namespace) {
namespace.split('.').forEach(s => {
// eslint-disable-next-line no-multi-assign
obj = obj[s] = {};
});
}
// eslint-disable-next-line no-multi-assign
obj = obj[enumNode.name.escapedText as string] = {};
enumNode.members
.filter((member: ts.EnumMember) => member.kind === ts.SyntaxKind.EnumMember)
.forEach(m => {
obj[(m.name as ts.Identifier).escapedText as string] =
m.initializer?.kind === ts.SyntaxKind.NumericLiteral
? // @ts-expect-error
Number(m.initializer.text)
: // @ts-expect-error
m.initializer?.text;
});
enumsMap = merge(enumsMap, finnal);
};
const visit = (node: ts.Node) => {
if (
node.kind === ts.SyntaxKind.EnumDeclaration &&
node.modifiers &&
node?.modifiers[0].kind === ts.SyntaxKind.DeclareKeyword &&
node?.modifiers[1].kind === ts.SyntaxKind.ConstKeyword
) {
createEnumObject(node as ts.EnumDeclaration);
}
if (
node.kind === ts.SyntaxKind.ModuleDeclaration &&
node.modifiers &&
node.modifiers[0].kind === ts.SyntaxKind.DeclareKeyword
) {
let namespace = (node as any).name.escapedText;
let declaration = (node as any).body;
while (declaration?.kind === ts.SyntaxKind.ModuleDeclaration) {
namespace += `.${declaration.name.escapedText}`;
declaration = declaration.body;
}
if (declaration?.kind === ts.SyntaxKind.ModuleBlock) {
declaration.statements
.filter((s: any) => s.kind === ts.SyntaxKind.EnumDeclaration)
.forEach((s: any) => {
createEnumObject(s, namespace);
});
}
}
ts.forEachChild(node, visit);
};
/**
*
* parse const enum in dts
*
* declare const enum Test {
* a = 1,
* b = 2,
* }
*
* Test: {
* a: 1,
* b: 2,
* }
*/
export const parseDTS = (files: string[]): Record<string, unknown> => {
for (const filepath of files) {
if (fs.existsSync(filepath)) {
const source = ts.createSourceFile(
filepath,
fs.readFileSync(filepath, 'utf8'),
ts.ScriptTarget.ES2015,
);
visit(source);
}
}
return enumsMap;
};