Skip to content

Commit

Permalink
Add envar writer to generate code for jsr:@wuespace/envar
Browse files Browse the repository at this point in the history
With this change, it is possible to, based on the example env file,
automatically generate code to use with the `jsr:@wuespace/envar` package.

This generates a self-contained file which exports a function `initEnv(): Promise<void>`,
which initializes the variables with basic validators.

Usage:

```shell
envardoc envar -o lib/env.ts example.env
```
  • Loading branch information
pklaschka committed Dec 8, 2024
1 parent 162579c commit 541be70
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ envardoc <writer> <path-to-env-file>

- `docs` - Prints the documentation in markdown format
- `example` - Prints a `.env.example` file with all variables and comments
- `envar` - Prints TypeScript code to use with the [`jsr:@wuespace/envar`](https://jsr.io/@wuespace/envar) package.

### With Deno

Expand Down
58 changes: 58 additions & 0 deletions lib/writers/envar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import type { Writer } from "$writers";
import type { Variable } from "$ast";

export class EnvarWriter implements Writer {
writeHeader(prev: string): string {
return prev + `import {
initVariable,
REQUIRED,
OPTIONAL,
} from "jsr:@wuespace/envar";
/**
* Initializes the environment variables using the jsr:@wuespace/envar library.
*
* Automatically generated by [envardoc](https://jsr.io/@wuespace/envardoc).
*/
export function initEnv(): Promise<void> {
return Promise.all([
`;
}

writeVariable(variable: Variable, prev: string): string {
variable.description?.trim().split("\n").forEach((line) => {
prev += ` // ${line}\n`;
});
if (variable.optional) {
return this.writeOptionalVariable(variable, prev) + "\n";
} else {
return this.writeRequiredVariable(variable, prev) + "\n";
}
}

private writeOptionalVariable(variable: Variable, prev: string): string {
prev += ' initVariable("';
prev += variable.name;
prev += '", OPTIONAL';
if (variable.defaultValue) {
prev += ', "';
prev += variable.defaultValue;
prev += '"';
}
prev += "),\n";
return prev;
}

private writeRequiredVariable(variable: Variable, prev: string): string {
prev += ' initVariable("';
prev += variable.name;
prev += '", REQUIRED),\n';
return prev;
}

writeFooter(prev: string): string {
return prev.trimEnd() + `\n ]);
}
`;
}
}
1 change: 1 addition & 0 deletions lib/writers/mod.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./docs.ts";
export * from "./env-example.ts";
export * from "./envar.ts";
export * from "./Writer.ts";
25 changes: 24 additions & 1 deletion main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { parse } from "$parse";
import { DocsWriter, EnvExampleWriter, type Writer } from "$writers";
import {
DocsWriter,
EnvarWriter,
EnvExampleWriter,
type Writer,
} from "$writers";
import { Command } from "@cliffy/command";
import { exists } from "@std/fs";
import { resolve } from "@std/path";
Expand All @@ -23,6 +28,23 @@ if (import.meta.main) {
}
});

const envar = new Command()
.arguments("<path:file>")
.description("Generate jsr:@wuespace/envar source code from a .env file")
.option("-o, --output <path:string>", "Output file path")
.action(async ({ output }, path) => {
const sourceCode = await parseAndConvert(
path,
new EnvarWriter(),
);
if (output) {
await Deno.writeTextFile(output, sourceCode);
console.log(`File written: ${output}`);
} else {
console.log(sourceCode);
}
});

const envExample = new Command()
.arguments("<path:string>")
.description("Generate example .env file")
Expand Down Expand Up @@ -52,6 +74,7 @@ if (import.meta.main) {
)
.command("docs", docs)
.command("example", envExample)
.command("envar", envar)
.parse(Deno.args);
}

Expand Down

0 comments on commit 541be70

Please sign in to comment.