@xlameiro/env-typegen 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Refresh the published npm package metadata and README to match the current repository documentation.
8
+
3
9
  All notable changes to this project will be documented in this file.
4
10
 
5
11
  This project adheres to [Semantic Versioning](https://semver.org/) and uses
@@ -7,7 +13,39 @@ This project adheres to [Semantic Versioning](https://semver.org/) and uses
7
13
 
8
14
  <!-- Releases are added automatically by `changeset version` -->
9
15
 
10
- ## [0.1.0] — 2026-03-16
16
+ ## [0.1.1] — 2026-03-17
17
+
18
+ ### Fixed
19
+
20
+ - **A1** — VERSION was hardcoded as `"0.1.0"` in `cli.ts`; now read dynamically from `package.json` via `createRequire` so it stays in sync without manual edits.
21
+ - **A2** — Double-quotes in `@description` annotations were not escaped in the t3-generator output, corrupting the generated `createEnv(...)` call. Fixed with `.replace(/"/g, '\\"')`.
22
+ - **A3** — Prettier parse errors in `formatOutput` were silently swallowed; a `console.warn` is now emitted before the raw-content fallback.
23
+ - **A4** — Watch mode only listened for `"change"` events; it now also handles `"add"` and `"unlink"` so editor save-with-delete patterns are covered.
24
+ - **A5** — Config file changes during `--watch` were silently ignored; a second chokidar watcher now monitors the config file and reloads it on change.
25
+ - **C1** — `formatOutput` (Prettier) was called unnecessarily in dry-run mode; formatting now runs only when actually writing to disk.
26
+ - **C3** — Removed duplicate alias exports (`generateTypeScript`, `generateZod`); the canonical names `generateTypeScriptTypes` and `generateZodSchema` are the only public exports.
27
+ - **E1–E3** — README badge URLs had `YOUR_USERNAME` placeholders; replaced with the real GitHub/npm identifiers. Package name aligned to `@xlameiro/env-typegen` throughout all docs.
28
+ - **E4** — README `--format` example was misleading; corrected to use `--generator`/`-f` for generator selection and document `--no-format` for disabling Prettier.
29
+ - **E5** — `parseEnvFile` was documented as `async`/awaitable but is synchronous; removed erroneous `await` from all examples.
30
+ - **DRY** — `CONFIG_FILE_NAMES` was duplicated between `config.ts` and `watch.ts`; exported from `config.ts` and imported in `watch.ts`.
31
+
32
+ ### Added
33
+
34
+ - **B1** — `EnvTypegenConfig.input` now accepts `string | string[]`; CLI `--input`/`-i` can be repeated to process multiple `.env` files in one run.
35
+ - **B2** — `inferenceRules?: InferenceRule[]` added to `EnvTypegenConfig` and `RunGenerateOptions`; custom rules are prepended before the built-in ruleset.
36
+ - **B3** — Default generators changed from `["typescript"]` to all four: `["typescript", "zod", "t3", "declaration"]`, matching the spec.
37
+ - **B4** — Dry-run mode now prints each generated output block to stdout so users can preview content without touching the filesystem.
38
+ - **B5** — Watch mode debounces rapid file-change events (200 ms) to prevent multiple simultaneous pipeline runs on editor autosave.
39
+
40
+ ### Tests
41
+
42
+ - Regression test for double-quotes in t3-generator descriptions (A2).
43
+ - CLI version tests read expected version from `package.json` (A1).
44
+ - Four `loadConfig()` unit tests with temp-dir fixtures (no stale state).
45
+ - Dry-run stdout spy test verifying preview content appears (B4).
46
+ - Integration tests expanded to five end-to-end scenarios via `execSync` against the built `dist/cli.js`.
47
+
48
+ [0.1.1]: https://github.com/xlameiro/env-typegen/compare/packages/env-typegen@0.1.0...packages/env-typegen@0.1.1
11
49
 
12
50
  ### Added
13
51
 
@@ -54,4 +92,4 @@ This project adheres to [Semantic Versioning](https://semver.org/) and uses
54
92
  - Full TSDoc on every public export in `src/index.ts`
55
93
  - README with Quick Start (CLI examples), Programmatic API, and Configuration sections
56
94
 
57
- [0.1.0]: https://github.com/YOUR_USERNAME/env-typegen/releases/tag/v0.1.0
95
+ [0.1.0]: https://github.com/xlameiro/env-typegen/releases/tag/v0.1.0
package/README.md CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  > From `.env.example` to TypeScript in one command.
4
4
 
5
- [![npm version](https://badge.fury.io/js/env-typegen.svg)](https://npmjs.com/package/env-typegen)
6
- [![CI](https://github.com/YOUR_USERNAME/env-typegen/actions/workflows/ci.yml/badge.svg)](https://github.com/YOUR_USERNAME/env-typegen/actions/workflows/ci.yml)
5
+ [![npm version](https://badge.fury.io/js/%40xlameiro%2Fenv-typegen.svg)](https://npmjs.com/package/@xlameiro/env-typegen)
6
+ [![CI](https://github.com/xlameiro/env-typegen/actions/workflows/ci.yml/badge.svg)](https://github.com/xlameiro/env-typegen/actions/workflows/ci.yml)
7
7
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
8
8
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue)](https://www.typescriptlang.org/)
9
9
 
@@ -11,31 +11,53 @@
11
11
 
12
12
  `env-typegen` reads `.env.example` files and automatically generates:
13
13
 
14
- - TypeScript types (`type Env = { PORT: number; DATABASE_URL: string }`)
14
+ - TypeScript types (`type EnvVars = { PORT: number; DATABASE_URL: string }`)
15
15
  - Zod v4 schemas (`z.object({ PORT: z.coerce.number() })`)
16
16
  - `@t3-oss/env-nextjs` `createEnv` configuration
17
17
  - `.d.ts` declaration files that augment `NodeJS.ProcessEnv`
18
18
 
19
+ ## Install
20
+
21
+ ```bash
22
+ pnpm add -D @xlameiro/env-typegen
23
+ # or
24
+ npm install --save-dev @xlameiro/env-typegen
25
+ ```
26
+
19
27
  ## Quick Start
20
28
 
21
29
  ```bash
22
- # Generate TypeScript types (default)
30
+ # Generate all outputs (default: typescript + zod + t3 + declaration)
23
31
  npx env-typegen --input .env.example --output src/env.generated.ts
24
32
 
25
- # Generate a Zod schema
33
+ # Generate only a Zod schema
26
34
  npx env-typegen -i .env.example -o src/env.schema.ts -g zod
27
35
 
28
- # Generate multiple outputs and format with Prettier
29
- npx env-typegen -i .env.example -o src/env.ts -g typescript -g zod --format
36
+ # Generate multiple outputs explicitly
37
+ npx env-typegen -i .env.example -o src/env.ts -f typescript -f zod
38
+
39
+ # Generate without running Prettier
40
+ npx env-typegen -i .env.example -o src/env.ts --no-format
30
41
 
31
42
  # Watch mode — regenerate on every change
32
43
  npx env-typegen -i .env.example -o src/env.ts --watch
33
44
  ```
34
45
 
46
+ ## Generator formats
47
+
48
+ Use `-f` / `--format` (or `-g` / `--generator` alias):
49
+
50
+ | Value | Meaning |
51
+ | -------------------- | ------------------------------------ |
52
+ | `ts` or `typescript` | Generate TypeScript types |
53
+ | `zod` | Generate Zod schema |
54
+ | `t3` | Generate `@t3-oss/env-nextjs` config |
55
+ | `declaration` | Generate `.d.ts` declaration |
56
+
35
57
  ## Programmatic API
36
58
 
37
59
  ```ts
38
- import { runGenerate, parseEnvFile, generateTypeScriptTypes } from "env-typegen";
60
+ import { runGenerate, parseEnvFile, generateTypeScriptTypes } from "@xlameiro/env-typegen";
39
61
 
40
62
  // High-level: full pipeline
41
63
  await runGenerate({
@@ -46,7 +68,7 @@ await runGenerate({
46
68
  });
47
69
 
48
70
  // Low-level: parse then generate individually
49
- const parsed = await parseEnvFile(".env.example");
71
+ const parsed = parseEnvFile(".env.example");
50
72
  const ts = generateTypeScriptTypes(parsed);
51
73
  ```
52
74
 
@@ -55,7 +77,7 @@ const ts = generateTypeScriptTypes(parsed);
55
77
  Create `env-typegen.config.ts` at your project root:
56
78
 
57
79
  ```ts
58
- import { defineConfig } from "env-typegen";
80
+ import { defineConfig } from "@xlameiro/env-typegen";
59
81
 
60
82
  export default defineConfig({
61
83
  input: ".env.example",
@@ -67,16 +89,11 @@ export default defineConfig({
67
89
 
68
90
  ## Status
69
91
 
70
- | Phase | Description | Status |
71
- | ----- | -------------- | ------ |
72
- | 1 | Foundation | ✅ |
73
- | 2 | Parser | ✅ |
74
- | 3 | Inferrer | ✅ |
75
- | 4 | Generators | ✅ |
76
- | 5 | Config & Utils | ✅ |
77
- | 6 | CLI | ✅ |
78
- | 7 | Quality & Docs | ✅ |
79
- | 8 | Publishing | 🔜 |
92
+ `env-typegen` is actively maintained and published on npm.
93
+
94
+ ## Changelog
95
+
96
+ See [`CHANGELOG.md`](./CHANGELOG.md) for release notes.
80
97
 
81
98
  ## License
82
99
 
package/dist/cli.js CHANGED
@@ -99,7 +99,9 @@ var require_picocolors = __commonJS({
99
99
  });
100
100
 
101
101
  // src/cli.ts
102
- import path6 from "path";
102
+ import { createRequire } from "module";
103
+ import { realpathSync } from "fs";
104
+ import path7 from "path";
103
105
  import { fileURLToPath, pathToFileURL as pathToFileURL2 } from "url";
104
106
  import { inspect, parseArgs } from "util";
105
107
 
@@ -179,7 +181,7 @@ function generateT3Env(parsed) {
179
181
  const effectiveType = variable.annotatedType ?? variable.inferredType;
180
182
  let zodExpr = toT3ZodType(effectiveType);
181
183
  if (variable.description !== void 0) {
182
- zodExpr += `.describe("${variable.description}")`;
184
+ zodExpr += `.describe("${variable.description.replace(/"/g, '\\"')}")`;
183
185
  }
184
186
  if (variable.isOptional) {
185
187
  zodExpr += ".optional()";
@@ -194,7 +196,7 @@ function generateT3Env(parsed) {
194
196
  const effectiveType = variable.annotatedType ?? variable.inferredType;
195
197
  let zodExpr = toT3ZodType(effectiveType);
196
198
  if (variable.description !== void 0) {
197
- zodExpr += `.describe("${variable.description}")`;
199
+ zodExpr += `.describe("${variable.description.replace(/"/g, '\\"')}")`;
198
200
  }
199
201
  if (variable.isOptional) {
200
202
  zodExpr += ".optional()";
@@ -396,7 +398,9 @@ var inferenceRules = [
396
398
  // src/inferrer/type-inferrer.ts
397
399
  var sortedRules = [...inferenceRules].sort((left, right) => left.priority - right.priority);
398
400
  function inferType(key, value, options) {
399
- for (const rule of sortedRules) {
401
+ const extra = options?.extraRules;
402
+ const rules = extra && extra.length > 0 ? [...extra].sort((a, b) => a.priority - b.priority).concat(sortedRules) : sortedRules;
403
+ for (const rule of rules) {
400
404
  if (rule.match(key, value)) {
401
405
  return rule.type;
402
406
  }
@@ -447,7 +451,7 @@ function parseCommentBlock(lines) {
447
451
  // src/parser/env-parser.ts
448
452
  var ENV_VAR_RE = /^([A-Z_][A-Z0-9_]*)=(.*)$/;
449
453
  var SECTION_HEADER_RE = /^#\s+[-=]{3,}\s+(.+?)\s+[-=]{3,}\s*$/;
450
- function parseEnvFileContent(content, filePath) {
454
+ function parseEnvFileContent(content, filePath, options) {
451
455
  const lines = content.split("\n");
452
456
  const vars = [];
453
457
  const groups = [];
@@ -480,7 +484,11 @@ function parseEnvFileContent(content, filePath) {
480
484
  const key = envMatch[1] ?? "";
481
485
  const rawValue = envMatch[2] ?? "";
482
486
  const annotations = parseCommentBlock(commentBlock);
483
- const inferredType = inferType(key, rawValue);
487
+ const inferredType = inferType(
488
+ key,
489
+ rawValue,
490
+ ...options?.inferenceRules !== void 0 ? [{ extraRules: options.inferenceRules }] : []
491
+ );
484
492
  const isRequired = rawValue.length > 0 || annotations.isRequired;
485
493
  const isOptional = rawValue.length === 0 && !annotations.isRequired;
486
494
  const isClientSide = key.startsWith("NEXT_PUBLIC_");
@@ -528,7 +536,11 @@ import { format } from "prettier";
528
536
  async function formatOutput(content, parser = "typescript") {
529
537
  try {
530
538
  return await format(content, { parser });
531
- } catch {
539
+ } catch (err) {
540
+ console.warn(
541
+ "env-typegen: Prettier formatting failed, writing unformatted output.",
542
+ err instanceof Error ? err.message : String(err)
543
+ );
532
544
  return content;
533
545
  }
534
546
  }
@@ -550,7 +562,15 @@ function deriveOutputPath(base, generator, isSingle) {
550
562
  if (isSingle) return base;
551
563
  const ext = path5.extname(base);
552
564
  const noExt = ext.length > 0 ? base.slice(0, -ext.length) : base;
553
- return `${noExt}.${generator}${ext.length > 0 ? ext : ".ts"}`;
565
+ const baseExt = ext.length > 0 ? ext : ".ts";
566
+ const outExt = generator === "declaration" ? ".d.ts" : baseExt;
567
+ return `${noExt}.${generator}${outExt}`;
568
+ }
569
+ function deriveOutputBaseForInput(output, inputPath) {
570
+ const dir = path5.dirname(output);
571
+ const ext = path5.extname(output);
572
+ const stem = path5.basename(inputPath, path5.extname(inputPath));
573
+ return path5.join(dir, `${stem}${ext}`);
554
574
  }
555
575
  function buildOutput(generator, parsed) {
556
576
  switch (generator) {
@@ -577,7 +597,11 @@ async function persistOutput(params) {
577
597
  }
578
598
  if (dryRun) {
579
599
  if (!silent) {
580
- success(`Dry run: ${outputPath}`);
600
+ if (!isSingle) {
601
+ console.log(`// --- ${generator}: ${outputPath} ---`);
602
+ }
603
+ console.log(generated);
604
+ success(`Dry run: would write ${outputPath}`);
581
605
  }
582
606
  return;
583
607
  }
@@ -594,47 +618,97 @@ async function runGenerate(options) {
594
618
  format: shouldFormat,
595
619
  stdout = false,
596
620
  dryRun = false,
597
- silent = false
621
+ silent = false,
622
+ inferenceRules: inferenceRules2
598
623
  } = options;
624
+ const inputs = Array.isArray(input) ? input : [input];
625
+ const hasMultipleInputs = inputs.length > 1;
599
626
  const isSingle = generators.length === 1;
600
- const content = await readEnvFile(input);
601
- const parsed = parseEnvFileContent(content, input);
602
- for (const generator of generators) {
603
- let generated = buildOutput(generator, parsed);
604
- if (shouldFormat) {
605
- generated = await formatOutput(generated);
627
+ for (const inputPath of inputs) {
628
+ const outputBase = hasMultipleInputs ? deriveOutputBaseForInput(output, inputPath) : output;
629
+ const content = await readEnvFile(inputPath);
630
+ const parsed = parseEnvFileContent(
631
+ content,
632
+ inputPath,
633
+ inferenceRules2 !== void 0 ? { inferenceRules: inferenceRules2 } : void 0
634
+ );
635
+ for (const generator of generators) {
636
+ let generated = buildOutput(generator, parsed);
637
+ if (shouldFormat && !dryRun) {
638
+ generated = await formatOutput(generated);
639
+ }
640
+ const outputPath = deriveOutputPath(outputBase, generator, isSingle);
641
+ await persistOutput({
642
+ generated,
643
+ generator,
644
+ outputPath,
645
+ isSingle,
646
+ stdout,
647
+ dryRun,
648
+ silent
649
+ });
606
650
  }
607
- const outputPath = deriveOutputPath(output, generator, isSingle);
608
- await persistOutput({
609
- generated,
610
- generator,
611
- outputPath,
612
- isSingle,
613
- stdout,
614
- dryRun,
615
- silent
616
- });
617
651
  }
618
652
  }
619
653
 
620
654
  // src/watch.ts
655
+ import path6 from "path";
621
656
  import { watch } from "chokidar";
622
- function startWatch({ inputPath, runOptions }) {
623
- log(`Watching ${inputPath} for changes...`);
657
+ function debounce(fn, delay) {
658
+ let timer;
659
+ return (...args) => {
660
+ if (timer !== void 0) clearTimeout(timer);
661
+ timer = setTimeout(() => {
662
+ timer = void 0;
663
+ fn(...args);
664
+ }, delay);
665
+ };
666
+ }
667
+ function startWatch({ inputPath, runOptions, cwd = process.cwd() }) {
668
+ const inputLabel = Array.isArray(inputPath) ? inputPath.join(", ") : inputPath;
669
+ log(`Watching ${inputLabel} for changes...`);
624
670
  void runGenerate(runOptions).catch((err) => {
625
671
  const message = err instanceof Error ? err.message : JSON.stringify(err);
626
672
  error(message);
627
673
  });
628
- const watcher = watch(inputPath, { persistent: true });
629
- watcher.on("change", () => {
630
- log(`${inputPath} changed, regenerating...`);
674
+ const handleChange = debounce((eventPath) => {
675
+ log(`${eventPath} changed, regenerating...`);
631
676
  void runGenerate(runOptions).catch((err) => {
632
677
  const message = err instanceof Error ? err.message : JSON.stringify(err);
633
678
  error(message);
634
679
  });
635
- });
680
+ }, 200);
681
+ const handleConfigChange = debounce(async (eventPath) => {
682
+ log(`Config file ${eventPath} changed, reloading...`);
683
+ try {
684
+ const reloaded = await loadConfig(cwd);
685
+ if (reloaded) {
686
+ runOptions.generators = reloaded.generators ?? runOptions.generators;
687
+ runOptions.format = reloaded.format ?? runOptions.format;
688
+ if (reloaded.inferenceRules !== void 0) {
689
+ runOptions.inferenceRules = reloaded.inferenceRules;
690
+ }
691
+ }
692
+ void runGenerate(runOptions).catch((err) => {
693
+ const message = err instanceof Error ? err.message : JSON.stringify(err);
694
+ error(message);
695
+ });
696
+ } catch (err) {
697
+ const message = err instanceof Error ? err.message : JSON.stringify(err);
698
+ error(`Failed to reload config: ${message}`);
699
+ }
700
+ }, 200);
701
+ const inputWatcher = watch(inputPath, { persistent: true });
702
+ for (const event of ["add", "change", "unlink"]) {
703
+ inputWatcher.on(event, handleChange);
704
+ }
705
+ const configPaths = CONFIG_FILE_NAMES.map((name) => path6.resolve(cwd, name));
706
+ const configWatcher = watch(configPaths, { persistent: true, ignoreInitial: true });
707
+ for (const event of ["add", "change"]) {
708
+ configWatcher.on(event, (eventPath) => void handleConfigChange(eventPath));
709
+ }
636
710
  process.on("SIGINT", () => {
637
- void watcher.close().then(() => {
711
+ void Promise.all([inputWatcher.close(), configWatcher.close()]).then(() => {
638
712
  log("Watcher stopped.");
639
713
  process.exit(0);
640
714
  });
@@ -642,7 +716,8 @@ function startWatch({ inputPath, runOptions }) {
642
716
  }
643
717
 
644
718
  // src/cli.ts
645
- var VERSION = "0.1.0";
719
+ var _require = createRequire(import.meta.url);
720
+ var VERSION = _require("../package.json").version;
646
721
  var HELP_TEXT = [
647
722
  "env-typegen \u2014 Generate TypeScript types from .env.example",
648
723
  "",
@@ -650,7 +725,7 @@ var HELP_TEXT = [
650
725
  " env-typegen -i <path> [options]",
651
726
  "",
652
727
  "Options:",
653
- " -i, --input <path> Path to .env.example file",
728
+ " -i, --input <path> Path to .env.example file(s). May be specified multiple times.",
654
729
  " -o, --output <path> Output file path (default: env.generated.ts)",
655
730
  " -f, --format <name> Generator format: ts|zod|t3|declaration",
656
731
  " May be specified multiple times.",
@@ -680,11 +755,29 @@ function getErrorMessage(errorValue) {
680
755
  }
681
756
  return inspect(errorValue, { depth: 2 });
682
757
  }
758
+ function resolveConfigRelative(value, configDir) {
759
+ if (value === void 0 || path7.isAbsolute(value)) return value;
760
+ return path7.resolve(configDir, value);
761
+ }
762
+ function applyConfigPaths(config, configDir) {
763
+ let input;
764
+ if (Array.isArray(config.input)) {
765
+ input = config.input.map((v) => resolveConfigRelative(v, configDir) ?? v);
766
+ } else {
767
+ input = resolveConfigRelative(config.input, configDir);
768
+ }
769
+ const output = resolveConfigRelative(config.output, configDir);
770
+ return {
771
+ ...config,
772
+ ...input !== void 0 && { input },
773
+ ...output !== void 0 && { output }
774
+ };
775
+ }
683
776
  async function runCli(argv = process.argv.slice(2)) {
684
777
  const { values } = parseArgs({
685
778
  args: argv,
686
779
  options: {
687
- input: { type: "string", short: "i" },
780
+ input: { type: "string", short: "i", multiple: true },
688
781
  output: { type: "string", short: "o" },
689
782
  generator: { type: "string", short: "g", multiple: true },
690
783
  format: { type: "string", short: "f", multiple: true },
@@ -707,14 +800,19 @@ async function runCli(argv = process.argv.slice(2)) {
707
800
  return;
708
801
  }
709
802
  let fileConfig;
710
- if (values.config !== void 0) {
711
- const configPath = path6.resolve(values.config);
712
- const mod = await import(pathToFileURL2(configPath).href);
713
- fileConfig = mod.default;
714
- } else {
803
+ if (values.config === void 0) {
715
804
  fileConfig = await loadConfig(process.cwd());
805
+ } else {
806
+ const configPath = path7.resolve(values.config);
807
+ const configDir = path7.dirname(configPath);
808
+ const mod = await import(pathToFileURL2(configPath).href);
809
+ const rawConfig = mod.default;
810
+ if (rawConfig) {
811
+ fileConfig = applyConfigPaths(rawConfig, configDir);
812
+ }
716
813
  }
717
- const input = values.input ?? fileConfig?.input;
814
+ const cliInput = values.input?.length ? values.input : void 0;
815
+ const input = cliInput ?? fileConfig?.input;
718
816
  if (input === void 0) {
719
817
  error("No input file specified. Use -i <path> or set input in env-typegen.config.ts");
720
818
  process.exit(1);
@@ -733,7 +831,7 @@ async function runCli(argv = process.argv.slice(2)) {
733
831
  }
734
832
  generators = [...new Set(normalizedGenerators)];
735
833
  } else {
736
- generators = fileConfig?.generators ?? ["typescript"];
834
+ generators = fileConfig?.generators ?? ["typescript", "zod", "t3", "declaration"];
737
835
  }
738
836
  const shouldFormat = values["no-format"] === true ? false : fileConfig?.format ?? true;
739
837
  const useStdout = values.stdout ?? false;
@@ -747,7 +845,8 @@ async function runCli(argv = process.argv.slice(2)) {
747
845
  format: shouldFormat,
748
846
  stdout: useStdout,
749
847
  dryRun: isDryRun,
750
- silent: isSilent
848
+ silent: isSilent,
849
+ ...fileConfig?.inferenceRules !== void 0 && { inferenceRules: fileConfig.inferenceRules }
751
850
  };
752
851
  if (shouldWatch) {
753
852
  startWatch({ inputPath: input, runOptions: options });
@@ -755,7 +854,13 @@ async function runCli(argv = process.argv.slice(2)) {
755
854
  await runGenerate(options);
756
855
  }
757
856
  }
758
- if (process.argv[1] !== void 0 && path6.resolve(process.argv[1]) === path6.resolve(fileURLToPath(import.meta.url))) {
857
+ if (process.argv[1] !== void 0 && (() => {
858
+ try {
859
+ return realpathSync(path7.resolve(process.argv[1])) === realpathSync(fileURLToPath(import.meta.url));
860
+ } catch {
861
+ return false;
862
+ }
863
+ })()) {
759
864
  await runCli().catch((err) => {
760
865
  error(getErrorMessage(err));
761
866
  process.exit(1);