@vite-env/cli 0.1.0 → 0.2.1

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/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # @vite-env/cli
2
+
3
+ CLI companion for [`@vite-env/core`](https://www.npmjs.com/package/@vite-env/core) — validate, generate, and type your Vite environment variables.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pnpm add -D @vite-env/cli
9
+ ```
10
+
11
+ ## Commands
12
+
13
+ ### `vite-env check`
14
+
15
+ Validate environment variables against your `env.ts` schema without starting the dev server. Useful in CI pipelines.
16
+
17
+ ```bash
18
+ npx vite-env check
19
+ npx vite-env check --config ./env.ts --mode production
20
+ ```
21
+
22
+ ### `vite-env generate`
23
+
24
+ Generate a `.env.example` file from your schema with type hints, defaults, and required flags.
25
+
26
+ ```bash
27
+ npx vite-env generate
28
+ npx vite-env generate --output .env.example
29
+ ```
30
+
31
+ ### `vite-env types`
32
+
33
+ Regenerate `vite-env.d.ts` from your schema without running the dev server.
34
+
35
+ ```bash
36
+ npx vite-env types
37
+ ```
38
+
39
+ ## Options
40
+
41
+ All commands accept:
42
+
43
+ | Flag | Default | Description |
44
+ | ---------- | -------- | --------------------------- |
45
+ | `--config` | `env.ts` | Path to env definition file |
46
+
47
+ `check` also accepts:
48
+
49
+ | Flag | Default | Description |
50
+ | -------- | ------------- | ------------------------------- |
51
+ | `--mode` | `development` | Vite mode for .env file loading |
52
+
53
+ `generate` also accepts:
54
+
55
+ | Flag | Default | Description |
56
+ | ---------- | -------------- | ---------------- |
57
+ | `--output` | `.env.example` | Output file path |
58
+
59
+ ## License
60
+
61
+ [MIT](https://github.com/pyyupsk/vite-env/blob/main/LICENSE)
package/dist/index.cjs CHANGED
@@ -21,6 +21,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
21
21
  enumerable: true
22
22
  }) : target, mod));
23
23
  //#endregion
24
+ let node_module = require("node:module");
24
25
  let citty = require("citty");
25
26
  let node_path = require("node:path");
26
27
  node_path = __toESM(node_path);
@@ -61,10 +62,19 @@ const checkCommand = (0, citty.defineCommand)({
61
62
  async run({ args }) {
62
63
  const root = node_process.default.cwd();
63
64
  const configPath = node_path.default.resolve(root, args.config);
64
- const { loadEnvConfig } = await import("@vite-env/core/config");
65
- const result = (0, _vite_env_core_schema.validateEnv)(await loadEnvConfig(configPath), loadCliEnv(args.mode, root));
65
+ let def;
66
+ try {
67
+ const { loadEnvConfig } = await import("@vite-env/core/config");
68
+ def = await loadEnvConfig(configPath);
69
+ } catch (e) {
70
+ consola.default.error(`Could not load env definition file at: ${configPath}\n Create an env.ts file and export default defineEnv({ ... })`);
71
+ if (e instanceof Error) consola.default.error(e.message);
72
+ node_process.default.exit(1);
73
+ }
74
+ const rawEnv = loadCliEnv(args.mode, root);
75
+ const result = (0, _vite_env_core_schema.validateEnv)(def, rawEnv);
66
76
  if (result.success) {
67
- const count = Object.keys(result.data ?? {}).length;
77
+ const count = Object.keys(result.data).length;
68
78
  consola.default.success(`${count} environment variables valid`);
69
79
  node_process.default.exit(0);
70
80
  } else {
@@ -91,18 +101,21 @@ const generateCommand = (0, citty.defineCommand)({
91
101
  async run({ args }) {
92
102
  const root = node_process.default.cwd();
93
103
  const configPath = node_path.default.resolve(root, args.config);
94
- const { loadEnvConfig } = await import("@vite-env/core/config");
95
- const def = await loadEnvConfig(configPath);
104
+ let def;
105
+ try {
106
+ const { loadEnvConfig } = await import("@vite-env/core/config");
107
+ def = await loadEnvConfig(configPath);
108
+ } catch (e) {
109
+ consola.default.error(`Could not load env definition file at: ${configPath}\n Create an env.ts file and export default defineEnv({ ... })`);
110
+ if (e instanceof Error) consola.default.error(e.message);
111
+ node_process.default.exit(1);
112
+ }
96
113
  const lines = [
97
114
  "# Auto-generated by @vite-env/cli — do not edit manually",
98
115
  "# Run: npx vite-env generate",
99
116
  ""
100
117
  ];
101
- const sections = [
102
- ["Public variables (VITE_ prefix — safe for browser)", def.client],
103
- ["Shared variables (available server + client)", def.shared],
104
- ["Server-only variables (never sent to browser)", def.server]
105
- ];
118
+ const sections = [["Client variables (VITE_ prefix — available everywhere)", def.client], ["Server-only variables (never sent to browser)", def.server]];
106
119
  for (const [heading, shape] of sections) {
107
120
  if (!shape || Object.keys(shape).length === 0) continue;
108
121
  lines.push(`# ── ${heading}`);
@@ -115,7 +128,13 @@ const generateCommand = (0, citty.defineCommand)({
115
128
  }
116
129
  }
117
130
  const output = node_path.default.resolve(root, args.output);
118
- await node_fs_promises.default.writeFile(output, lines.join("\n"), "utf-8");
131
+ try {
132
+ await node_fs_promises.default.writeFile(output, lines.join("\n"), "utf-8");
133
+ } catch (e) {
134
+ consola.default.error(`Failed to write ${args.output}. Check file permissions.`);
135
+ if (e instanceof Error) consola.default.error(e.message);
136
+ node_process.default.exit(1);
137
+ }
119
138
  consola.default.success(`Generated ${args.output}`);
120
139
  }
121
140
  });
@@ -155,18 +174,27 @@ const typesCommand = (0, citty.defineCommand)({
155
174
  async run({ args }) {
156
175
  const root = node_process.default.cwd();
157
176
  const configPath = node_path.default.resolve(root, args.config);
158
- const { loadEnvConfig } = await import("@vite-env/core/config");
159
- await (0, _vite_env_core_dts.generateDts)(await loadEnvConfig(configPath), root);
177
+ let def;
178
+ try {
179
+ const { loadEnvConfig } = await import("@vite-env/core/config");
180
+ def = await loadEnvConfig(configPath);
181
+ } catch (e) {
182
+ consola.default.error(`Could not load env definition file at: ${configPath}\n Create an env.ts file and export default defineEnv({ ... })`);
183
+ if (e instanceof Error) consola.default.error(e.message);
184
+ node_process.default.exit(1);
185
+ }
186
+ await (0, _vite_env_core_dts.generateDts)(def, root);
160
187
  consola.default.success("Generated vite-env.d.ts");
161
188
  }
162
189
  });
163
190
  //#endregion
164
191
  //#region src/index.ts
192
+ const { version } = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href)("../package.json");
165
193
  (0, citty.runMain)((0, citty.defineCommand)({
166
194
  meta: {
167
195
  name: "vite-env",
168
196
  description: "The env.ts layer for Vite",
169
- version: "0.1.0"
197
+ version
170
198
  },
171
199
  subCommands: {
172
200
  check: checkCommand,
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["process","path","process","path","fs","z","process","path"],"sources":["../src/commands/check.ts","../src/commands/generate.ts","../src/commands/types.ts","../src/index.ts"],"sourcesContent":["import type { EnvDefinition } from '@vite-env/core'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { formatZodError } from '@vite-env/core/format'\nimport { validateEnv } from '@vite-env/core/schema'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { loadEnv } from 'vite'\n\nexport function loadCliEnv(mode: string, root: string): Record<string, string> {\n const fileEnv = loadEnv(mode, root, '')\n const procEnv = Object.fromEntries(\n Object.entries(process.env).filter(\n (entry): entry is [string, string] => typeof entry[1] === 'string',\n ),\n )\n return { ...fileEnv, ...procEnv }\n}\n\nexport const checkCommand = defineCommand({\n meta: {\n description: 'Validate environment variables without starting dev server',\n },\n args: {\n config: {\n type: 'string',\n default: 'env.ts',\n description: 'Path to env definition file',\n },\n mode: { type: 'string', default: 'development', description: 'Vite mode' },\n },\n async run({ args }) {\n const root = process.cwd()\n const configPath = path.resolve(root, args.config)\n\n const { loadEnvConfig } = await import('@vite-env/core/config')\n const def: EnvDefinition = await loadEnvConfig(configPath)\n\n const rawEnv = loadCliEnv(args.mode, root)\n const result = validateEnv(def, rawEnv)\n\n if (result.success) {\n const count = Object.keys(result.data ?? {}).length\n consola.success(`${count} environment variables valid`)\n process.exit(0)\n }\n else {\n consola.error('Environment validation failed:')\n consola.log(formatZodError(result.errors))\n process.exit(1)\n }\n },\n})\n","import type { EnvDefinition } from '@vite-env/core'\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { z } from 'zod'\n\nexport const generateCommand = defineCommand({\n meta: { description: 'Generate .env.example from your env.ts schema' },\n args: {\n config: { type: 'string', default: 'env.ts' },\n output: { type: 'string', default: '.env.example' },\n },\n async run({ args }) {\n const root = process.cwd()\n const configPath = path.resolve(root, args.config)\n const { loadEnvConfig } = await import('@vite-env/core/config')\n const def: EnvDefinition = await loadEnvConfig(configPath)\n\n const lines: string[] = [\n '# Auto-generated by @vite-env/cli — do not edit manually',\n '# Run: npx vite-env generate',\n '',\n ]\n\n const sections: Array<[string, z.ZodRawShape | undefined]> = [\n ['Public variables (VITE_ prefix — safe for browser)', def.client],\n ['Shared variables (available server + client)', def.shared],\n ['Server-only variables (never sent to browser)', def.server],\n ]\n\n for (const [heading, shape] of sections) {\n if (!shape || Object.keys(shape).length === 0)\n continue\n lines.push(`# ── ${heading}`)\n\n for (const [key, schema] of Object.entries(shape)) {\n // Zod v4: ZodRawShape values are $ZodType, cast for instanceof checks\n const s = schema as unknown as z.ZodTypeAny\n const hint = buildHint(s)\n const defaultVal = getDefault(s)\n const reqFlag = isRequired(s) ? ' — required' : ''\n lines.push(`# ${key}: ${hint}${reqFlag}`, `${key}=${defaultVal}`, '')\n }\n }\n\n const output = path.resolve(root, args.output)\n await fs.writeFile(output, lines.join('\\n'), 'utf-8')\n consola.success(`Generated ${args.output}`)\n },\n})\n\nexport function buildHint(schema: z.ZodTypeAny): string {\n const inner = unwrap(schema)\n if (inner instanceof z.ZodString)\n return 'string'\n if (inner instanceof z.ZodNumber)\n return 'number'\n if (inner instanceof z.ZodBoolean)\n return 'boolean (true | false | 1 | 0)'\n if (inner instanceof z.ZodEnum)\n return `enum: ${(inner.options as string[]).join(' | ')}`\n if (inner instanceof z.ZodPipe)\n return buildHint(inner.def.out as unknown as z.ZodTypeAny)\n return 'string'\n}\n\nexport function getDefault(schema: z.ZodTypeAny): string {\n if (schema instanceof z.ZodDefault) {\n const val = (schema.def as { defaultValue: unknown }).defaultValue\n return String(typeof val === 'function' ? val() : val)\n }\n return ''\n}\n\nfunction isRequired(schema: z.ZodTypeAny): boolean {\n return !(schema instanceof z.ZodOptional) && !(schema instanceof z.ZodDefault)\n}\n\nfunction unwrap(schema: z.ZodTypeAny): z.ZodTypeAny {\n if (schema instanceof z.ZodOptional)\n return unwrap(schema.unwrap() as unknown as z.ZodTypeAny)\n if (schema instanceof z.ZodDefault)\n return unwrap((schema.def as { innerType: unknown }).innerType as z.ZodTypeAny)\n if (schema instanceof z.ZodPipe)\n return unwrap(schema.def.out as unknown as z.ZodTypeAny)\n return schema\n}\n","import type { EnvDefinition } from '@vite-env/core'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { generateDts } from '@vite-env/core/dts'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\n\nexport const typesCommand = defineCommand({\n meta: { description: 'Regenerate vite-env.d.ts from your env.ts schema' },\n args: {\n config: { type: 'string', default: 'env.ts' },\n },\n async run({ args }) {\n const root = process.cwd()\n const configPath = path.resolve(root, args.config)\n const { loadEnvConfig } = await import('@vite-env/core/config')\n const def: EnvDefinition = await loadEnvConfig(configPath)\n\n await generateDts(def, root)\n consola.success('Generated vite-env.d.ts')\n },\n})\n","#!/usr/bin/env node\nimport { defineCommand, runMain } from 'citty'\nimport { checkCommand } from './commands/check'\nimport { generateCommand } from './commands/generate'\nimport { typesCommand } from './commands/types'\n\nconst main = defineCommand({\n meta: {\n name: 'vite-env',\n description: 'The env.ts layer for Vite',\n version: '0.1.0',\n },\n subCommands: {\n check: checkCommand,\n generate: generateCommand,\n types: typesCommand,\n },\n})\n\nrunMain(main)\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["process","path","process","path","fs","z","process","path"],"sources":["../src/commands/check.ts","../src/commands/generate.ts","../src/commands/types.ts","../src/index.ts"],"sourcesContent":["import type { EnvDefinition } from '@vite-env/core'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { formatZodError } from '@vite-env/core/format'\nimport { validateEnv } from '@vite-env/core/schema'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { loadEnv } from 'vite'\n\nexport function loadCliEnv(mode: string, root: string): Record<string, string> {\n const fileEnv = loadEnv(mode, root, '')\n const procEnv = Object.fromEntries(\n Object.entries(process.env).filter(\n (entry): entry is [string, string] => typeof entry[1] === 'string',\n ),\n )\n return { ...fileEnv, ...procEnv }\n}\n\nexport const checkCommand = defineCommand({\n meta: {\n description: 'Validate environment variables without starting dev server',\n },\n args: {\n config: {\n type: 'string',\n default: 'env.ts',\n description: 'Path to env definition file',\n },\n mode: { type: 'string', default: 'development', description: 'Vite mode' },\n },\n async run({ args }) {\n const root = process.cwd()\n const configPath = path.resolve(root, args.config)\n\n let def: EnvDefinition\n try {\n const { loadEnvConfig } = await import('@vite-env/core/config')\n def = await loadEnvConfig(configPath)\n }\n catch (e) {\n consola.error(\n `Could not load env definition file at: ${configPath}\\n`\n + ` Create an env.ts file and export default defineEnv({ ... })`,\n )\n if (e instanceof Error)\n consola.error(e.message)\n process.exit(1)\n }\n\n const rawEnv = loadCliEnv(args.mode, root)\n const result = validateEnv(def, rawEnv)\n\n if (result.success) {\n const count = Object.keys(result.data).length\n consola.success(`${count} environment variables valid`)\n process.exit(0)\n }\n else {\n consola.error('Environment validation failed:')\n consola.log(formatZodError(result.errors))\n process.exit(1)\n }\n },\n})\n","import type { EnvDefinition } from '@vite-env/core'\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { z } from 'zod'\n\nexport const generateCommand = defineCommand({\n meta: { description: 'Generate .env.example from your env.ts schema' },\n args: {\n config: { type: 'string', default: 'env.ts' },\n output: { type: 'string', default: '.env.example' },\n },\n async run({ args }) {\n const root = process.cwd()\n const configPath = path.resolve(root, args.config)\n\n let def: EnvDefinition\n try {\n const { loadEnvConfig } = await import('@vite-env/core/config')\n def = await loadEnvConfig(configPath)\n }\n catch (e) {\n consola.error(\n `Could not load env definition file at: ${configPath}\\n`\n + ` Create an env.ts file and export default defineEnv({ ... })`,\n )\n if (e instanceof Error)\n consola.error(e.message)\n process.exit(1)\n }\n\n const lines: string[] = [\n '# Auto-generated by @vite-env/cli — do not edit manually',\n '# Run: npx vite-env generate',\n '',\n ]\n\n const sections: Array<[string, z.ZodRawShape | undefined]> = [\n ['Client variables (VITE_ prefix — available everywhere)', def.client],\n ['Server-only variables (never sent to browser)', def.server],\n ]\n\n for (const [heading, shape] of sections) {\n if (!shape || Object.keys(shape).length === 0)\n continue\n lines.push(`# ── ${heading}`)\n\n for (const [key, schema] of Object.entries(shape)) {\n // Zod v4: ZodRawShape values are $ZodType, cast for instanceof checks\n const s = schema as unknown as z.ZodTypeAny\n const hint = buildHint(s)\n const defaultVal = getDefault(s)\n const reqFlag = isRequired(s) ? ' — required' : ''\n lines.push(`# ${key}: ${hint}${reqFlag}`, `${key}=${defaultVal}`, '')\n }\n }\n\n const output = path.resolve(root, args.output)\n try {\n await fs.writeFile(output, lines.join('\\n'), 'utf-8')\n }\n catch (e) {\n consola.error(`Failed to write ${args.output}. Check file permissions.`)\n if (e instanceof Error)\n consola.error(e.message)\n process.exit(1)\n }\n consola.success(`Generated ${args.output}`)\n },\n})\n\nexport function buildHint(schema: z.ZodTypeAny): string {\n const inner = unwrap(schema)\n if (inner instanceof z.ZodString)\n return 'string'\n if (inner instanceof z.ZodNumber)\n return 'number'\n if (inner instanceof z.ZodBoolean)\n return 'boolean (true | false | 1 | 0)'\n if (inner instanceof z.ZodEnum)\n return `enum: ${(inner.options as string[]).join(' | ')}`\n if (inner instanceof z.ZodPipe)\n return buildHint(inner.def.out as unknown as z.ZodTypeAny)\n return 'string'\n}\n\nexport function getDefault(schema: z.ZodTypeAny): string {\n if (schema instanceof z.ZodDefault) {\n const val = (schema.def as { defaultValue: unknown }).defaultValue\n return String(typeof val === 'function' ? val() : val)\n }\n return ''\n}\n\nfunction isRequired(schema: z.ZodTypeAny): boolean {\n return !(schema instanceof z.ZodOptional) && !(schema instanceof z.ZodDefault)\n}\n\nfunction unwrap(schema: z.ZodTypeAny): z.ZodTypeAny {\n if (schema instanceof z.ZodOptional)\n return unwrap(schema.unwrap() as unknown as z.ZodTypeAny)\n if (schema instanceof z.ZodDefault)\n return unwrap((schema.def as { innerType: unknown }).innerType as z.ZodTypeAny)\n if (schema instanceof z.ZodPipe)\n return unwrap(schema.def.out as unknown as z.ZodTypeAny)\n return schema\n}\n","import type { EnvDefinition } from '@vite-env/core'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { generateDts } from '@vite-env/core/dts'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\n\nexport const typesCommand = defineCommand({\n meta: { description: 'Regenerate vite-env.d.ts from your env.ts schema' },\n args: {\n config: { type: 'string', default: 'env.ts' },\n },\n async run({ args }) {\n const root = process.cwd()\n const configPath = path.resolve(root, args.config)\n\n let def: EnvDefinition\n try {\n const { loadEnvConfig } = await import('@vite-env/core/config')\n def = await loadEnvConfig(configPath)\n }\n catch (e) {\n consola.error(\n `Could not load env definition file at: ${configPath}\\n`\n + ` Create an env.ts file and export default defineEnv({ ... })`,\n )\n if (e instanceof Error)\n consola.error(e.message)\n process.exit(1)\n }\n\n await generateDts(def, root)\n consola.success('Generated vite-env.d.ts')\n },\n})\n","#!/usr/bin/env node\nimport { createRequire } from 'node:module'\nimport { defineCommand, runMain } from 'citty'\nimport { checkCommand } from './commands/check'\nimport { generateCommand } from './commands/generate'\nimport { typesCommand } from './commands/types'\n\nconst require = createRequire(import.meta.url)\nconst { version } = require('../package.json') as { version: string }\n\nconst main = defineCommand({\n meta: {\n name: 'vite-env',\n description: 'The env.ts layer for Vite',\n version,\n },\n subCommands: {\n check: checkCommand,\n generate: generateCommand,\n types: typesCommand,\n },\n})\n\nrunMain(main)\n"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire } from "node:module";
2
3
  import { defineCommand, runMain } from "citty";
3
4
  import path from "node:path";
4
5
  import process from "node:process";
@@ -35,10 +36,19 @@ const checkCommand = defineCommand({
35
36
  async run({ args }) {
36
37
  const root = process.cwd();
37
38
  const configPath = path.resolve(root, args.config);
38
- const { loadEnvConfig } = await import("@vite-env/core/config");
39
- const result = validateEnv(await loadEnvConfig(configPath), loadCliEnv(args.mode, root));
39
+ let def;
40
+ try {
41
+ const { loadEnvConfig } = await import("@vite-env/core/config");
42
+ def = await loadEnvConfig(configPath);
43
+ } catch (e) {
44
+ consola.error(`Could not load env definition file at: ${configPath}\n Create an env.ts file and export default defineEnv({ ... })`);
45
+ if (e instanceof Error) consola.error(e.message);
46
+ process.exit(1);
47
+ }
48
+ const rawEnv = loadCliEnv(args.mode, root);
49
+ const result = validateEnv(def, rawEnv);
40
50
  if (result.success) {
41
- const count = Object.keys(result.data ?? {}).length;
51
+ const count = Object.keys(result.data).length;
42
52
  consola.success(`${count} environment variables valid`);
43
53
  process.exit(0);
44
54
  } else {
@@ -65,18 +75,21 @@ const generateCommand = defineCommand({
65
75
  async run({ args }) {
66
76
  const root = process.cwd();
67
77
  const configPath = path.resolve(root, args.config);
68
- const { loadEnvConfig } = await import("@vite-env/core/config");
69
- const def = await loadEnvConfig(configPath);
78
+ let def;
79
+ try {
80
+ const { loadEnvConfig } = await import("@vite-env/core/config");
81
+ def = await loadEnvConfig(configPath);
82
+ } catch (e) {
83
+ consola.error(`Could not load env definition file at: ${configPath}\n Create an env.ts file and export default defineEnv({ ... })`);
84
+ if (e instanceof Error) consola.error(e.message);
85
+ process.exit(1);
86
+ }
70
87
  const lines = [
71
88
  "# Auto-generated by @vite-env/cli — do not edit manually",
72
89
  "# Run: npx vite-env generate",
73
90
  ""
74
91
  ];
75
- const sections = [
76
- ["Public variables (VITE_ prefix — safe for browser)", def.client],
77
- ["Shared variables (available server + client)", def.shared],
78
- ["Server-only variables (never sent to browser)", def.server]
79
- ];
92
+ const sections = [["Client variables (VITE_ prefix — available everywhere)", def.client], ["Server-only variables (never sent to browser)", def.server]];
80
93
  for (const [heading, shape] of sections) {
81
94
  if (!shape || Object.keys(shape).length === 0) continue;
82
95
  lines.push(`# ── ${heading}`);
@@ -89,7 +102,13 @@ const generateCommand = defineCommand({
89
102
  }
90
103
  }
91
104
  const output = path.resolve(root, args.output);
92
- await fs.writeFile(output, lines.join("\n"), "utf-8");
105
+ try {
106
+ await fs.writeFile(output, lines.join("\n"), "utf-8");
107
+ } catch (e) {
108
+ consola.error(`Failed to write ${args.output}. Check file permissions.`);
109
+ if (e instanceof Error) consola.error(e.message);
110
+ process.exit(1);
111
+ }
93
112
  consola.success(`Generated ${args.output}`);
94
113
  }
95
114
  });
@@ -119,30 +138,42 @@ function unwrap(schema) {
119
138
  return schema;
120
139
  }
121
140
  //#endregion
141
+ //#region src/commands/types.ts
142
+ const typesCommand = defineCommand({
143
+ meta: { description: "Regenerate vite-env.d.ts from your env.ts schema" },
144
+ args: { config: {
145
+ type: "string",
146
+ default: "env.ts"
147
+ } },
148
+ async run({ args }) {
149
+ const root = process.cwd();
150
+ const configPath = path.resolve(root, args.config);
151
+ let def;
152
+ try {
153
+ const { loadEnvConfig } = await import("@vite-env/core/config");
154
+ def = await loadEnvConfig(configPath);
155
+ } catch (e) {
156
+ consola.error(`Could not load env definition file at: ${configPath}\n Create an env.ts file and export default defineEnv({ ... })`);
157
+ if (e instanceof Error) consola.error(e.message);
158
+ process.exit(1);
159
+ }
160
+ await generateDts(def, root);
161
+ consola.success("Generated vite-env.d.ts");
162
+ }
163
+ });
164
+ //#endregion
122
165
  //#region src/index.ts
166
+ const { version } = createRequire(import.meta.url)("../package.json");
123
167
  runMain(defineCommand({
124
168
  meta: {
125
169
  name: "vite-env",
126
170
  description: "The env.ts layer for Vite",
127
- version: "0.1.0"
171
+ version
128
172
  },
129
173
  subCommands: {
130
174
  check: checkCommand,
131
175
  generate: generateCommand,
132
- types: defineCommand({
133
- meta: { description: "Regenerate vite-env.d.ts from your env.ts schema" },
134
- args: { config: {
135
- type: "string",
136
- default: "env.ts"
137
- } },
138
- async run({ args }) {
139
- const root = process.cwd();
140
- const configPath = path.resolve(root, args.config);
141
- const { loadEnvConfig } = await import("@vite-env/core/config");
142
- await generateDts(await loadEnvConfig(configPath), root);
143
- consola.success("Generated vite-env.d.ts");
144
- }
145
- })
176
+ types: typesCommand
146
177
  }
147
178
  }));
148
179
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/commands/check.ts","../src/commands/generate.ts","../src/commands/types.ts","../src/index.ts"],"sourcesContent":["import type { EnvDefinition } from '@vite-env/core'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { formatZodError } from '@vite-env/core/format'\nimport { validateEnv } from '@vite-env/core/schema'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { loadEnv } from 'vite'\n\nexport function loadCliEnv(mode: string, root: string): Record<string, string> {\n const fileEnv = loadEnv(mode, root, '')\n const procEnv = Object.fromEntries(\n Object.entries(process.env).filter(\n (entry): entry is [string, string] => typeof entry[1] === 'string',\n ),\n )\n return { ...fileEnv, ...procEnv }\n}\n\nexport const checkCommand = defineCommand({\n meta: {\n description: 'Validate environment variables without starting dev server',\n },\n args: {\n config: {\n type: 'string',\n default: 'env.ts',\n description: 'Path to env definition file',\n },\n mode: { type: 'string', default: 'development', description: 'Vite mode' },\n },\n async run({ args }) {\n const root = process.cwd()\n const configPath = path.resolve(root, args.config)\n\n const { loadEnvConfig } = await import('@vite-env/core/config')\n const def: EnvDefinition = await loadEnvConfig(configPath)\n\n const rawEnv = loadCliEnv(args.mode, root)\n const result = validateEnv(def, rawEnv)\n\n if (result.success) {\n const count = Object.keys(result.data ?? {}).length\n consola.success(`${count} environment variables valid`)\n process.exit(0)\n }\n else {\n consola.error('Environment validation failed:')\n consola.log(formatZodError(result.errors))\n process.exit(1)\n }\n },\n})\n","import type { EnvDefinition } from '@vite-env/core'\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { z } from 'zod'\n\nexport const generateCommand = defineCommand({\n meta: { description: 'Generate .env.example from your env.ts schema' },\n args: {\n config: { type: 'string', default: 'env.ts' },\n output: { type: 'string', default: '.env.example' },\n },\n async run({ args }) {\n const root = process.cwd()\n const configPath = path.resolve(root, args.config)\n const { loadEnvConfig } = await import('@vite-env/core/config')\n const def: EnvDefinition = await loadEnvConfig(configPath)\n\n const lines: string[] = [\n '# Auto-generated by @vite-env/cli — do not edit manually',\n '# Run: npx vite-env generate',\n '',\n ]\n\n const sections: Array<[string, z.ZodRawShape | undefined]> = [\n ['Public variables (VITE_ prefix — safe for browser)', def.client],\n ['Shared variables (available server + client)', def.shared],\n ['Server-only variables (never sent to browser)', def.server],\n ]\n\n for (const [heading, shape] of sections) {\n if (!shape || Object.keys(shape).length === 0)\n continue\n lines.push(`# ── ${heading}`)\n\n for (const [key, schema] of Object.entries(shape)) {\n // Zod v4: ZodRawShape values are $ZodType, cast for instanceof checks\n const s = schema as unknown as z.ZodTypeAny\n const hint = buildHint(s)\n const defaultVal = getDefault(s)\n const reqFlag = isRequired(s) ? ' — required' : ''\n lines.push(`# ${key}: ${hint}${reqFlag}`, `${key}=${defaultVal}`, '')\n }\n }\n\n const output = path.resolve(root, args.output)\n await fs.writeFile(output, lines.join('\\n'), 'utf-8')\n consola.success(`Generated ${args.output}`)\n },\n})\n\nexport function buildHint(schema: z.ZodTypeAny): string {\n const inner = unwrap(schema)\n if (inner instanceof z.ZodString)\n return 'string'\n if (inner instanceof z.ZodNumber)\n return 'number'\n if (inner instanceof z.ZodBoolean)\n return 'boolean (true | false | 1 | 0)'\n if (inner instanceof z.ZodEnum)\n return `enum: ${(inner.options as string[]).join(' | ')}`\n if (inner instanceof z.ZodPipe)\n return buildHint(inner.def.out as unknown as z.ZodTypeAny)\n return 'string'\n}\n\nexport function getDefault(schema: z.ZodTypeAny): string {\n if (schema instanceof z.ZodDefault) {\n const val = (schema.def as { defaultValue: unknown }).defaultValue\n return String(typeof val === 'function' ? val() : val)\n }\n return ''\n}\n\nfunction isRequired(schema: z.ZodTypeAny): boolean {\n return !(schema instanceof z.ZodOptional) && !(schema instanceof z.ZodDefault)\n}\n\nfunction unwrap(schema: z.ZodTypeAny): z.ZodTypeAny {\n if (schema instanceof z.ZodOptional)\n return unwrap(schema.unwrap() as unknown as z.ZodTypeAny)\n if (schema instanceof z.ZodDefault)\n return unwrap((schema.def as { innerType: unknown }).innerType as z.ZodTypeAny)\n if (schema instanceof z.ZodPipe)\n return unwrap(schema.def.out as unknown as z.ZodTypeAny)\n return schema\n}\n","import type { EnvDefinition } from '@vite-env/core'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { generateDts } from '@vite-env/core/dts'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\n\nexport const typesCommand = defineCommand({\n meta: { description: 'Regenerate vite-env.d.ts from your env.ts schema' },\n args: {\n config: { type: 'string', default: 'env.ts' },\n },\n async run({ args }) {\n const root = process.cwd()\n const configPath = path.resolve(root, args.config)\n const { loadEnvConfig } = await import('@vite-env/core/config')\n const def: EnvDefinition = await loadEnvConfig(configPath)\n\n await generateDts(def, root)\n consola.success('Generated vite-env.d.ts')\n },\n})\n","#!/usr/bin/env node\nimport { defineCommand, runMain } from 'citty'\nimport { checkCommand } from './commands/check'\nimport { generateCommand } from './commands/generate'\nimport { typesCommand } from './commands/types'\n\nconst main = defineCommand({\n meta: {\n name: 'vite-env',\n description: 'The env.ts layer for Vite',\n version: '0.1.0',\n },\n subCommands: {\n check: checkCommand,\n generate: generateCommand,\n types: typesCommand,\n },\n})\n\nrunMain(main)\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/commands/check.ts","../src/commands/generate.ts","../src/commands/types.ts","../src/index.ts"],"sourcesContent":["import type { EnvDefinition } from '@vite-env/core'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { formatZodError } from '@vite-env/core/format'\nimport { validateEnv } from '@vite-env/core/schema'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { loadEnv } from 'vite'\n\nexport function loadCliEnv(mode: string, root: string): Record<string, string> {\n const fileEnv = loadEnv(mode, root, '')\n const procEnv = Object.fromEntries(\n Object.entries(process.env).filter(\n (entry): entry is [string, string] => typeof entry[1] === 'string',\n ),\n )\n return { ...fileEnv, ...procEnv }\n}\n\nexport const checkCommand = defineCommand({\n meta: {\n description: 'Validate environment variables without starting dev server',\n },\n args: {\n config: {\n type: 'string',\n default: 'env.ts',\n description: 'Path to env definition file',\n },\n mode: { type: 'string', default: 'development', description: 'Vite mode' },\n },\n async run({ args }) {\n const root = process.cwd()\n const configPath = path.resolve(root, args.config)\n\n let def: EnvDefinition\n try {\n const { loadEnvConfig } = await import('@vite-env/core/config')\n def = await loadEnvConfig(configPath)\n }\n catch (e) {\n consola.error(\n `Could not load env definition file at: ${configPath}\\n`\n + ` Create an env.ts file and export default defineEnv({ ... })`,\n )\n if (e instanceof Error)\n consola.error(e.message)\n process.exit(1)\n }\n\n const rawEnv = loadCliEnv(args.mode, root)\n const result = validateEnv(def, rawEnv)\n\n if (result.success) {\n const count = Object.keys(result.data).length\n consola.success(`${count} environment variables valid`)\n process.exit(0)\n }\n else {\n consola.error('Environment validation failed:')\n consola.log(formatZodError(result.errors))\n process.exit(1)\n }\n },\n})\n","import type { EnvDefinition } from '@vite-env/core'\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\nimport { z } from 'zod'\n\nexport const generateCommand = defineCommand({\n meta: { description: 'Generate .env.example from your env.ts schema' },\n args: {\n config: { type: 'string', default: 'env.ts' },\n output: { type: 'string', default: '.env.example' },\n },\n async run({ args }) {\n const root = process.cwd()\n const configPath = path.resolve(root, args.config)\n\n let def: EnvDefinition\n try {\n const { loadEnvConfig } = await import('@vite-env/core/config')\n def = await loadEnvConfig(configPath)\n }\n catch (e) {\n consola.error(\n `Could not load env definition file at: ${configPath}\\n`\n + ` Create an env.ts file and export default defineEnv({ ... })`,\n )\n if (e instanceof Error)\n consola.error(e.message)\n process.exit(1)\n }\n\n const lines: string[] = [\n '# Auto-generated by @vite-env/cli — do not edit manually',\n '# Run: npx vite-env generate',\n '',\n ]\n\n const sections: Array<[string, z.ZodRawShape | undefined]> = [\n ['Client variables (VITE_ prefix — available everywhere)', def.client],\n ['Server-only variables (never sent to browser)', def.server],\n ]\n\n for (const [heading, shape] of sections) {\n if (!shape || Object.keys(shape).length === 0)\n continue\n lines.push(`# ── ${heading}`)\n\n for (const [key, schema] of Object.entries(shape)) {\n // Zod v4: ZodRawShape values are $ZodType, cast for instanceof checks\n const s = schema as unknown as z.ZodTypeAny\n const hint = buildHint(s)\n const defaultVal = getDefault(s)\n const reqFlag = isRequired(s) ? ' — required' : ''\n lines.push(`# ${key}: ${hint}${reqFlag}`, `${key}=${defaultVal}`, '')\n }\n }\n\n const output = path.resolve(root, args.output)\n try {\n await fs.writeFile(output, lines.join('\\n'), 'utf-8')\n }\n catch (e) {\n consola.error(`Failed to write ${args.output}. Check file permissions.`)\n if (e instanceof Error)\n consola.error(e.message)\n process.exit(1)\n }\n consola.success(`Generated ${args.output}`)\n },\n})\n\nexport function buildHint(schema: z.ZodTypeAny): string {\n const inner = unwrap(schema)\n if (inner instanceof z.ZodString)\n return 'string'\n if (inner instanceof z.ZodNumber)\n return 'number'\n if (inner instanceof z.ZodBoolean)\n return 'boolean (true | false | 1 | 0)'\n if (inner instanceof z.ZodEnum)\n return `enum: ${(inner.options as string[]).join(' | ')}`\n if (inner instanceof z.ZodPipe)\n return buildHint(inner.def.out as unknown as z.ZodTypeAny)\n return 'string'\n}\n\nexport function getDefault(schema: z.ZodTypeAny): string {\n if (schema instanceof z.ZodDefault) {\n const val = (schema.def as { defaultValue: unknown }).defaultValue\n return String(typeof val === 'function' ? val() : val)\n }\n return ''\n}\n\nfunction isRequired(schema: z.ZodTypeAny): boolean {\n return !(schema instanceof z.ZodOptional) && !(schema instanceof z.ZodDefault)\n}\n\nfunction unwrap(schema: z.ZodTypeAny): z.ZodTypeAny {\n if (schema instanceof z.ZodOptional)\n return unwrap(schema.unwrap() as unknown as z.ZodTypeAny)\n if (schema instanceof z.ZodDefault)\n return unwrap((schema.def as { innerType: unknown }).innerType as z.ZodTypeAny)\n if (schema instanceof z.ZodPipe)\n return unwrap(schema.def.out as unknown as z.ZodTypeAny)\n return schema\n}\n","import type { EnvDefinition } from '@vite-env/core'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { generateDts } from '@vite-env/core/dts'\nimport { defineCommand } from 'citty'\nimport consola from 'consola'\n\nexport const typesCommand = defineCommand({\n meta: { description: 'Regenerate vite-env.d.ts from your env.ts schema' },\n args: {\n config: { type: 'string', default: 'env.ts' },\n },\n async run({ args }) {\n const root = process.cwd()\n const configPath = path.resolve(root, args.config)\n\n let def: EnvDefinition\n try {\n const { loadEnvConfig } = await import('@vite-env/core/config')\n def = await loadEnvConfig(configPath)\n }\n catch (e) {\n consola.error(\n `Could not load env definition file at: ${configPath}\\n`\n + ` Create an env.ts file and export default defineEnv({ ... })`,\n )\n if (e instanceof Error)\n consola.error(e.message)\n process.exit(1)\n }\n\n await generateDts(def, root)\n consola.success('Generated vite-env.d.ts')\n },\n})\n","#!/usr/bin/env node\nimport { createRequire } from 'node:module'\nimport { defineCommand, runMain } from 'citty'\nimport { checkCommand } from './commands/check'\nimport { generateCommand } from './commands/generate'\nimport { typesCommand } from './commands/types'\n\nconst require = createRequire(import.meta.url)\nconst { version } = require('../package.json') as { version: string }\n\nconst main = defineCommand({\n meta: {\n name: 'vite-env',\n description: 'The env.ts layer for Vite',\n version,\n },\n subCommands: {\n check: checkCommand,\n generate: generateCommand,\n types: typesCommand,\n },\n})\n\nrunMain(main)\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,9 +1,24 @@
1
1
  {
2
2
  "name": "@vite-env/cli",
3
3
  "type": "module",
4
- "version": "0.1.0",
4
+ "version": "0.2.1",
5
5
  "description": "CLI for @vite-env/core — check, generate, types",
6
6
  "license": "MIT",
7
+ "homepage": "https://github.com/pyyupsk/vite-env#cli",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/pyyupsk/vite-env.git",
11
+ "directory": "packages/cli"
12
+ },
13
+ "keywords": [
14
+ "vite",
15
+ "vite-env",
16
+ "cli",
17
+ "environment-variables",
18
+ "env",
19
+ "dotenv",
20
+ "validation"
21
+ ],
7
22
  "exports": {
8
23
  ".": {
9
24
  "import": {
@@ -24,18 +39,21 @@
24
39
  "vite-env": "./dist/index.mjs"
25
40
  },
26
41
  "files": [
42
+ "README.md",
27
43
  "dist"
28
44
  ],
29
45
  "engines": {
30
46
  "node": ">=20.19.0"
31
47
  },
48
+ "peerDependencies": {
49
+ "vite": ">=8.0.0",
50
+ "zod": "^4.0.0"
51
+ },
32
52
  "dependencies": {
33
53
  "citty": "^0.2.2",
34
54
  "consola": "^3.4.2",
35
55
  "jiti": "^2.6.1",
36
- "vite": "^8.0.3",
37
- "zod": "^4.3.6",
38
- "@vite-env/core": "0.1.0"
56
+ "@vite-env/core": "0.2.1"
39
57
  },
40
58
  "devDependencies": {
41
59
  "@types/node": "^25.5.2",