Run on all files in a directory
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.
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
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
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");
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.