ts2typebox icon indicating copy to clipboard operation
ts2typebox copied to clipboard

Run on all files in a directory

Open abdurahmanshiine opened this issue 1 year ago • 4 comments

Hey there,

I have a directory where I broke down my types into files, is there a way I could run the cli on all the files at once?

I would appreciate it as well if there was a watch mode, it would do me a great service.

Thanks a lot for this great package though, I love it.

abdurahmanshiine avatar Oct 20 '24 10:10 abdurahmanshiine

Hey @abdurahmanshiine

glad that you can make use of this package! : )

It feels like these are features that already exist and/or are rather done by external programs (correct me if I am wrong).

I have a directory where I broke down my types into files, is there a way I could run the cli on all the files at once?

You could write a script that lists all files in the directory and then execute ts2typebox for all of them. The programmatic usage example could be helpful to you here

I would appreciate it as well if there was a watch mode, it would do me a great service.

Did you try using a file watcher like nodemon for this? Given you created the script mentioned above you could watch for changes in this directory and then run the script.

I think it could be really helpful if you posted your findings/results. We could/should probably add them to the examples folder and probably in the readme.

cheers

xddq avatar Oct 20 '24 10:10 xddq

The programmatic usage example could be helpful to you here

For some reason, this is literally the only example I skipped 😅 Let me try to get it to work, and I'll post the results here

abdurahmanshiine avatar Oct 20 '24 11:10 abdurahmanshiine

Hey @xddq

I tried the programmatic approach, and things seem to work fine, but there is just one issue I couldn't get around, and that's when the file imports a type from another file. It keeps throwing this at me Unhandled: ImportDeclaration import { AccessToken } from "./common";

Any ideas on how to bypass this (if there is an easy solution)?

P.S. Here's my code for reference

import { resolve } from "node:path";
import { watch } from "fs/promises";
import { ts2typebox } from "ts2typebox";

async function run(dir: string, out: string): Promise<void> {
  console.log("Watch mode!\n");
  const watcher = watch(resolve(dir), { recursive: true });

  for await (const event of watcher) {
    if (!event.filename || event.filename.includes("4913")) continue;

    console.log(
      `Rebuilding: ${dir}${
        event.filename.includes("~")
          ? event.filename.split("~")[0]
          : event.filename
      } \n`,
    );

    try {
      const start = Bun.nanoseconds();
      const input = await Bun.file(
        resolve(
          dir +
            (event.filename.includes("~")
              ? event.filename.split("~")[0]
              : event.filename),
        ),
      ).text();
      const result = await ts2typebox({
        input,
        skipTypeCreation: true,
      });
      await Bun.write(
        `${out}${event.filename.includes("~") ? event.filename.split("~")[0] : event.filename}`,
        result,
      );
      const end = Bun.nanoseconds();

      console.log(`Rebuilt in: ${((end - start) / 1_000_000).toString()} ms\n`);
    } catch (e) {
      console.error("Error rebuilding:", e);
    }
  }
}

await run("./input/dir/path", "/output/dir/path");

abdurahmanshiine avatar Oct 20 '24 12:10 abdurahmanshiine

I know this thread is old, but in case it helps someone i will point out the way I'm currently handling this is by joining all the individual scripts content into one big string. In order to do this there shouldn't be any duplicates types.

An example:

import { readFileSync, writeFileSync } from "node:fs";
import { ts2typebox } from "ts2typebox";

(async () => {
  const files = ["one.ts", "two.ts", "..."];

  const allContent = files
    .map((f) => `${__dirname}/../${f}`)
    .map((f) => readFileSync(f, "utf-8"))
    .join("\n\n\n");

  const result = await ts2typebox({ input: allContent });
  writeFileSync(__dirname + "/generated-typebox.ts", result);
})();

Of course, all the definitions will end up in a single file.

asabatba avatar Aug 14 '25 11:08 asabatba