npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@darkair/enum-to-ts

v1.0.0

Published

Convert enums from any programming language (ex. Java) into TypeScript enum declarations

Downloads

28

Readme

enum-to-ts

This project was written to simplify the synchronization of enumerations within a single repository with code in different programming languages.

Installation

npm install --save-dev @darkair/enum-to-ts

Usage

The examples below are for a case where the backend is written in Java, and the TypeScript frontend needs to maintain synchronicity of the values used.

Simple example

import {ParseInfo, Parser} from "@darkair/enum-to-ts";

const parseInfos: ParseInfo[] = [
    {
        srcFileName: 'SomeType.java',                               // File to parsing
        srcDirectory: "../src/main/java/path/to/head/directory",    // relative path to start folder to recursive find of the source file
        enumName: 'SomeTypeEnum',                                   // TS file name (without extension)
        comment: 'This is a some type',                             // Comment for the enum
        parseFunc: Parser.parseNameValue                            // NAME(VALUE, ...) -> [1: NAME, 2: VALUE]
    }
];

async function generateEnum(): Promise<boolean> {
    try {
        await Parser.parseEnums(
            parseInfos,
            `${__dirname}/../../src/enums`              // relative path to destination folder
        );
    } catch (err) {
        // error handling
        return false;
    }
    return true;
}

Example with index.ts generation

import {ParseInfo, Parser} from "@darkair/enum-to-ts";

const parseInfos: ParseInfo[] = [
    {
        srcFileName: 'SomeType.java',                               // File to parsing
        srcDirectory: "../src/main/java/path/to/head/directory",    // relative path to start folder to recursive find of the source file
        enumName: 'SomeTypeEnum',                                   // TS file name (without extension)
        comment: 'This is a some type',                             // Comment for the enum
        parseFunc: Parser.parseNameValue                            // NAME(VALUE, ...) -> [1: NAME, 2: VALUE]
    }
];

async function generateEnum(): Promise<boolean> {
    try {
        await Parser.parseEnums(
            parseInfos,
            `${__dirname}/../../src/enums`              // relative path to destination folder
        );

        // Generate an index file if necessary
        // Result "src/enums/index.ts":
        //    export * from "SomeTypeEnum";
        //    export * from "NotGeneratedEnum1";
        //    export * from "NotGeneratedEnum2";
        await Parser.generateIndex(
            parseInfos,
            [
                'NotGeneratedEnum1',                    // Array of extra enums not generated automatically                  
                'NotGeneratedEnum2'
            ],
            `${__dirname}/../../src/enums`,             // relative path to destination folder
        );
    } catch (err) {
        // error handling
        return false;
    }
    return true;
}

Example with custom enum generator

const parseInfos: ParseInfo[] = [
    {
        srcFileName: 'SomeEnum.java',                               // File to parsing
        srcDirectory: "../src/main/java/path/to/head/directory",    // relative path to start folder to recursive find of the source file
        enumName: 'SomeEnum',                                       // TS file name (without extension)
        comment: 'This is some enums',                              // Comment to put before TS enum
        parseFunc: Parser.parseNameComment                          // NAME("COMMENT", ...) -> [1: NAME, ..., 3: COMMENT]
    }
];

async function generateEnum(): Promise<boolean> {
    try {
        await Parser.parseEnums(
            parseInfos,
            `${__dirname}/../../src/enums`,             // relative path to destination folder
            getEnums                                    // custom function to parse enum
        );
    } catch (err: Error) {
        // error handling
        return false;
    }
    return true;
}

/**
 * This custom function is generate enum with aligned comment for every values
 * Comments are parsed from the Java file by the main regular expression
 */
async function getEnums(fileContent: string, parseFunc: ParseInfo['parseFunc']): Promise<string> {
    return new Promise(resolve => {
        const readable: Readable = Readable.from(Parser.splitByEOL(fileContent));

        const lines: Array<string[]> = [];
        readable.on('data', (line: string) => {
            const res: ParseResult = parseFunc(line);
            if (res) {
                lines.push([`    ${res.name} = '${res.value}',`, res.comment]);
            }
        });

        readable.on('close', async () => {
            // Align the comment
            let maxLen: number = Math.max(...lines.map((v: string[]) => v[0].length));
            maxLen = Math.ceil(maxLen / 4 + 1) * 4;     // +1 to extra spaces
            const spacesStr: string = ' '.repeat(maxLen);
            resolve(
                // Aligning comments
                lines.map(
                    (v: [string, string]) => `${(v[0] + spacesStr).slice(0, maxLen)}// ${v[1]}`
                ).join(EOL)
            );
        });
    });
}

Example: Enum + Description class

const parseInfos: ParseInfo[] = [
    {
        srcFileName: 'SomeEnum.java',                               // File to parsing
        srcDirectory: "../src/main/java/path/to/head/directory",    // relative path to start folder to recursive find of the source file
        enumName: 'SomeEnum',                                       // TS file name (without extension)
        descriptionEnumName: 'SomeEnumDescription',                 // Name of the description class for the frontend (optional)
        comment: 'This is some enums',                              // Comment to put before TS enum
        parseFunc: Parser.parseNameValueComment                     // NAME(VALUE, "COMMENT", ...) -> [1: NAME, 2: VALUE, ..., 4: COMMENT]
    }
];

/**
 * Result:
 *     export enum SomeEnum {
 *         VALUE1 = "VALUE1",       // Value1 comment 
 *         VALUE2 = "VALUE2",       // Value2 comment 
 *     }
 *     export enum SomeEnumDescription {
 *         VALUE1 = "Value1 comment",
 *         VALUE2 = "Value2 comment",
 *     }
 */
async function generateEnum(): Promise<boolean> {
    try {
        await Parser.parseEnumsWithDescription(
            parseInfos,
            `${__dirname}/../../src/enums`
        );
    } catch (err) {
        console.log(colorize.red(err.message));
        return false;
    }
    return true;
}

Example of custom "parseFunc"

const parseInfos: ParseInfo[] = [
    {
        srcFileName: 'SomeEnum.java',                               // File to parsing
        srcDirectory: "../src/main/java/path/to/head/directory",    // relative path to start folder to recursive find of the source file
        enumName: 'SomeEnum',                                       // TS file name (without extension)
        parseFunc: (line: string): ParseResult | null => {
            const regExp: RegExp = /([A-Z0-9_]+)\((['"])(.*?)(?<!\\)\2, ([A-Z0-9_]+)\)/;      // NAME("COMMENT", VALUE)
            const regArr: RegExpMatchArray = line.match(regExp);
            return !regArr ? null : {
                name: regArr[1],
                value: regArr[4],
                comment: regArr[3],
            };
        }
    }
];

Documentation

interface ParseInfo

export interface ParseInfo {
    srcFileName: string;                                // File to parsing
    srcDirectory: string;                               // Base directory to find srcFileName
    enumName: string;                                   // Name of the main enum for the frontend
    descriptionEnumName?: string;                       // Name of the description class for the frontend (optional)
    comment?: string;                                   // Comment for the enum (optional)
    parseFunc: (line: string) => ParseResult | null;    // Function for parsing a line
}

Parser.parseEnums

Parse files specified by the parseInfos.

static async parseEnums(
    parseInfos: ParseInfo[],
    destPath: string,
    getEnumsFunc?: typeof Parser.getEnums,
);

Options

| Parameter | Description | |--------------|---------------------------------------------------------------------------------------------------------------------------| | parseInfos | config array of parsing files | | destPath | relative path to destination folder | | getEnumsFunc | custom function for parse enum from the fileasync getEnums(fileContent: string, parseFunc: ParseInfo['parseFunc']) |

Parser.parseEnumsWithDescription

Parse files with descriptions of enums specified by the parseInfos.

static async parseEnumsWithDescription(
    parseInfos: ParseInfo[],
    destPath: string,
    getEnumsFunc?: typeof Parser.getEnumsWithDescription,
);

Options

| Parameter | Description | |--------------|---------------------------------------------------------------------------------------------------------------------------| | parseInfos | config array of parsing files | | destPath | relative path to destination folder | | getEnumsFunc | custom function for parse enum from the fileasync getEnums(fileContent: string, parseFunc: ParseInfo['parseFunc']) |

Parser.parseName

Parse NAME -> [1: NAME]

static parseName(line: string): ParseResult | null;

Options

| Parameter | Description | |--------------|-------------------------| | line | single string from file |

Parser.parseNameValue

Parse NAME(VALUE) -> [1: NAME, 2: VALUE]

static parseNameValue(line: string): ParseResult | null;

Options

| Parameter | Description | |--------------|-------------------------| | line | single string from file |

Parser.parseNameComment

Parse NAME("COMMENT") -> [1: NAME, ..., 3: COMMENT]

static parseNameComment(line: string): ParseResult | null;

Options

| Parameter | Description | |--------------|-------------------------| | line | single string from file |

Parser.parseNameValueComment

Parse NAME(VALUE, "COMMENT") -> [1: NAME, 2: VALUE, ..., 4: COMMENT]

static parseNameValueComment(line: string): ParseResult | null;

Options

| Parameter | Description | |--------------|-------------------------| | line | single string from file |

Parser.parseNameCommentValue

Parse NAME("COMMENT", VALUE, ...) -> [1: NAME, 2: COMMENT, ..., 4: VALUE]

static parseNameCommentValue(line: string): ParseResult | null;

Options

| Parameter | Description | |--------------|-------------------------| | line | single string from file |

Parser.generateIndex

Generate index.ts.

static async generateIndex(
    parseInfos: ParseInfo[],
    extraEnums: string[],
    destPath: string,
);

Options

| Parameter | Description | |------------|------------------------------------------------------------------| | parseInfos | config array of parsing files | | extraEnums | enumerations that are not generated but exist in the same folder | | destPath | relative path to destination folder |

Parser.splitByEOL

Split file content into lines, regardless of the OS they were saved in

static splitByEOL(
    content: string,
    ignoreEmptyLines: boolean = true
): string[];

Parser.content.createFileContent

Generate general file content

static createFileContent(
    enumName: string,
    enumContent: string,
    commentContent: string,
    descriptionContent: string
): string;

Options

| Parameter | Description | |--------------------|----------------------------------------------------------------------------------------------------| | enumName | enum name | | enumContent | string with concatenated enum content likeVALUE1 = "VALUE1",VALUE2 = "VALUE2 | | commentContent | correct multiline comment content like/* comment */ | | descriptionContent | full content of description enumenum DescEnum { ... } |

Parser.content.createCommentContent

Generate comment content

static createCommentContent(
    comment: string
): string;

Parser.content.createDescriptionContent

Generate description content

static createDescriptionContent(
    descriptionName: string,
    content: string
): string;

Parser.fs.findFilePath

Recursively find the path to a file in a specified directory

static async findFilePath(
    srcFileName: string,        // MyEnum.java
    srcPath: string             // relative path to source file
): Promise<string | null>;

Parser.fs.findFilePath

Write file

static async writeFile(
    enunName: string,           // MyEnum
    destDir: string,            // `${__dirname}/../../src/enums`
    fileContent: string
): void;

Parser.log.success

Output a success string. Format: [✓] {message}

static success(
    message: string
);

Parser.log.ignored

Output an ignored string. Format: [-] {message}

static ignored(
    message: string
);

Parser.log.successGeneration

Output a success string after generation an enum. Format: [✓] {enumName} has been generated

static successGeneration(
    enumName: string
);

Parser.log.ignoreGeneration

Оutput that the generation ignored. Format: [-] Generation of {subject} was ignored

static ignoreGeneration(
    subject: string
);

Example of custom generation

A complete example of custom parsing and enumeration generation

for (const info: ParseInfo of parseInfos) {
    const foundFilePath = await Parser.fs.findFilePath(info.srcFileName, "../src/main/java/ru/my/path");
    if (!foundFilePath) {
        throw new Error(`File ${info.srcFileName} is not found`);
    }
    const parsedFileContent: string = (await readFile(foundFilePath)).toString();

    const enums: [string, string] = await getMyEnums(
        parsedFileContent,
        info.parseFunc
    );
    const enumContent: string = enums[0];               // 'VALUE1 = "VALUE1",\nVALUE2 = "VALUE2",'
    const descriptionEnumContent: string = enums[1];    // 'DESC1 = "desc 1",\nDESC2 = "desc 2",'


    const fileContent: string = Parser.content.createFileContent(
        info.enumName,
        enumContent,
        Parser.content.createCommentContent(info.comment),
        Parser.content.createDescriptionContent(info.descriptionEnumName, descriptionEnumContent)
    );

    await Parser.fs.writeFile(info.enumName, `${__dirname}/../../src/enums`, fileContent);
    Parser.log.successGeneration(info.enumName);
}

Output

/**
 * comment
 */

enum MyEnum {
    VALUE1 = "VALUE1",
    VALUE2 = "VALUE2",
}

enum DescEnum {
    DESC1 = "desc 1",
    DESC2 = "desc 2",
}