vite-plugin-typed-env 0.1.0 → 0.1.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/dist/index.cjs +367 -0
- package/dist/index.d.cts +35 -0
- package/dist/index.d.mts +35 -0
- package/dist/index.mjs +338 -0
- package/package.json +8 -2
- package/.claude/settings.local.json +0 -8
- package/.prettierrc.cjs +0 -14
- package/src/generator.ts +0 -119
- package/src/index.ts +0 -174
- package/src/inferrer.ts +0 -165
- package/src/parser.ts +0 -72
- package/tests/index.test.ts +0 -154
- package/tsconfig.json +0 -12
- package/tsdown.config.ts +0 -9
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
Object.defineProperties(exports, {
|
|
2
|
+
__esModule: { value: true },
|
|
3
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
4
|
+
});
|
|
5
|
+
//#region \0rolldown/runtime.js
|
|
6
|
+
var __create = Object.create;
|
|
7
|
+
var __defProp = Object.defineProperty;
|
|
8
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
9
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
10
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
11
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
14
|
+
key = keys[i];
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
16
|
+
get: ((k) => from[k]).bind(null, key),
|
|
17
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
23
|
+
value: mod,
|
|
24
|
+
enumerable: true
|
|
25
|
+
}) : target, mod));
|
|
26
|
+
//#endregion
|
|
27
|
+
let node_fs = require("node:fs");
|
|
28
|
+
node_fs = __toESM(node_fs);
|
|
29
|
+
let node_path = require("node:path");
|
|
30
|
+
node_path = __toESM(node_path);
|
|
31
|
+
//#region src/parser.ts
|
|
32
|
+
const ANNOTATION_RE = /^#\s*@(\w+)(?::\s*(.+))?$/;
|
|
33
|
+
function parseAnnotations(lines) {
|
|
34
|
+
const ann = {};
|
|
35
|
+
for (const line of lines) {
|
|
36
|
+
const m = line.match(ANNOTATION_RE);
|
|
37
|
+
if (!m) continue;
|
|
38
|
+
const [, key, value] = m;
|
|
39
|
+
if (key === "optional") ann.optional = true;
|
|
40
|
+
else if (key === "type" && value) ann.type = value.trim();
|
|
41
|
+
else if (key === "default" && value) ann.default = value.trim();
|
|
42
|
+
else if (key === "desc" && value) ann.description = value.trim();
|
|
43
|
+
}
|
|
44
|
+
return ann;
|
|
45
|
+
}
|
|
46
|
+
function parseEnvFile(content) {
|
|
47
|
+
const lines = content.split("\n");
|
|
48
|
+
const entries = [];
|
|
49
|
+
const pendingComments = [];
|
|
50
|
+
for (let i = 0; i < lines.length; i++) {
|
|
51
|
+
const raw = lines[i].trim();
|
|
52
|
+
if (raw === "") {
|
|
53
|
+
pendingComments.length = 0;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (raw.startsWith("#")) {
|
|
57
|
+
pendingComments.push(raw);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
const eqIdx = raw.indexOf("=");
|
|
61
|
+
if (eqIdx === -1) continue;
|
|
62
|
+
const key = raw.slice(0, eqIdx).trim();
|
|
63
|
+
let value = raw.slice(eqIdx + 1).trim();
|
|
64
|
+
if (value.startsWith("\"") && value.endsWith("\"") || value.startsWith("'") && value.endsWith("'")) value = value.slice(1, -1);
|
|
65
|
+
const annotations = parseAnnotations(pendingComments);
|
|
66
|
+
const description = pendingComments.filter((l) => !ANNOTATION_RE.test(l)).map((l) => l.replace(/^#\s*/, "")).join(" ").trim();
|
|
67
|
+
entries.push({
|
|
68
|
+
key,
|
|
69
|
+
value,
|
|
70
|
+
annotations: {
|
|
71
|
+
...annotations,
|
|
72
|
+
description: description || void 0
|
|
73
|
+
},
|
|
74
|
+
comment: ""
|
|
75
|
+
});
|
|
76
|
+
pendingComments.length = 0;
|
|
77
|
+
}
|
|
78
|
+
return entries;
|
|
79
|
+
}
|
|
80
|
+
//#endregion
|
|
81
|
+
//#region src/inferrer.ts
|
|
82
|
+
function isBoolean(v) {
|
|
83
|
+
return [
|
|
84
|
+
"true",
|
|
85
|
+
"false",
|
|
86
|
+
"1",
|
|
87
|
+
"0",
|
|
88
|
+
"yes",
|
|
89
|
+
"no"
|
|
90
|
+
].includes(v.toLowerCase());
|
|
91
|
+
}
|
|
92
|
+
function isNumber(v) {
|
|
93
|
+
return v !== "" && !isNaN(Number(v));
|
|
94
|
+
}
|
|
95
|
+
function isUrl(v) {
|
|
96
|
+
try {
|
|
97
|
+
new URL(v);
|
|
98
|
+
return v.startsWith("http://") || v.startsWith("https://") || v.includes("://");
|
|
99
|
+
} catch {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function isNumberArray(v) {
|
|
104
|
+
if (!v.includes(",")) return false;
|
|
105
|
+
return v.split(",").every((s) => isNumber(s.trim()));
|
|
106
|
+
}
|
|
107
|
+
function isStringArray(v) {
|
|
108
|
+
return v.includes(",") && v.split(",").length > 1;
|
|
109
|
+
}
|
|
110
|
+
function inferFromAnnotation(ann) {
|
|
111
|
+
const enumMatch = ann.match(/^enum\((.+)\)$/);
|
|
112
|
+
if (enumMatch) {
|
|
113
|
+
const values = enumMatch[1].split(",").map((s) => s.trim());
|
|
114
|
+
return {
|
|
115
|
+
tsType: values.map((v) => `'${v}'`).join(" | "),
|
|
116
|
+
zodSchema: `z.enum([${values.map((v) => `'${v}'`).join(", ")}])`
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
if (ann === "number[]") return {
|
|
120
|
+
tsType: "number[]",
|
|
121
|
+
zodSchema: `z.string().transform(v => v.split(',').map(Number))`
|
|
122
|
+
};
|
|
123
|
+
if (ann === "string[]") return {
|
|
124
|
+
tsType: "string[]",
|
|
125
|
+
zodSchema: `z.string().transform(v => v.split(','))`
|
|
126
|
+
};
|
|
127
|
+
if (ann === "url") return {
|
|
128
|
+
tsType: "string",
|
|
129
|
+
zodSchema: `z.string().url()`
|
|
130
|
+
};
|
|
131
|
+
if (ann === "number") return {
|
|
132
|
+
tsType: "number",
|
|
133
|
+
zodSchema: `z.coerce.number()`
|
|
134
|
+
};
|
|
135
|
+
if (ann === "boolean") return {
|
|
136
|
+
tsType: "boolean",
|
|
137
|
+
zodSchema: `z.enum(['true','false','1','0']).transform(v => v === 'true' || v === '1')`
|
|
138
|
+
};
|
|
139
|
+
if (ann === "port") return {
|
|
140
|
+
tsType: "number",
|
|
141
|
+
zodSchema: `z.coerce.number().int().min(1).max(65535)`
|
|
142
|
+
};
|
|
143
|
+
if (ann === "email") return {
|
|
144
|
+
tsType: "string",
|
|
145
|
+
zodSchema: `z.string().email()`
|
|
146
|
+
};
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
function inferFromValue(value) {
|
|
150
|
+
if (value === "") return {
|
|
151
|
+
tsType: "string",
|
|
152
|
+
zodSchema: "z.string()"
|
|
153
|
+
};
|
|
154
|
+
if (isBoolean(value)) return {
|
|
155
|
+
tsType: "boolean",
|
|
156
|
+
zodSchema: `z.enum(['true','false','1','0','yes','no']).transform(v => ['true','1','yes'].includes(v.toLowerCase()))`
|
|
157
|
+
};
|
|
158
|
+
if (isNumber(value)) return {
|
|
159
|
+
tsType: "number",
|
|
160
|
+
zodSchema: Number.isInteger(Number(value)) ? "z.coerce.number().int()" : "z.coerce.number()"
|
|
161
|
+
};
|
|
162
|
+
if (isNumberArray(value)) return {
|
|
163
|
+
tsType: "number[]",
|
|
164
|
+
zodSchema: `z.string().transform(v => v.split(',').map(Number))`
|
|
165
|
+
};
|
|
166
|
+
if (isUrl(value)) return {
|
|
167
|
+
tsType: "string",
|
|
168
|
+
zodSchema: "z.string().url()"
|
|
169
|
+
};
|
|
170
|
+
if (isStringArray(value)) return {
|
|
171
|
+
tsType: "string[]",
|
|
172
|
+
zodSchema: `z.string().transform(v => v.split(',').map(s => s.trim()))`
|
|
173
|
+
};
|
|
174
|
+
return {
|
|
175
|
+
tsType: "string",
|
|
176
|
+
zodSchema: "z.string().min(1)"
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function inferType(entry) {
|
|
180
|
+
const { value, annotations } = entry;
|
|
181
|
+
const isOptional = annotations.optional === true || value === "";
|
|
182
|
+
const base = (annotations.type ? inferFromAnnotation(annotations.type) : null) ?? inferFromValue(value);
|
|
183
|
+
let zodSchema = base.zodSchema;
|
|
184
|
+
if (annotations.default !== void 0) zodSchema = `${zodSchema}.default('${annotations.default}')`;
|
|
185
|
+
else if (isOptional) zodSchema = `${zodSchema}.optional()`;
|
|
186
|
+
return {
|
|
187
|
+
tsType: base.tsType,
|
|
188
|
+
zodSchema,
|
|
189
|
+
isOptional,
|
|
190
|
+
defaultValue: annotations.default
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
//#endregion
|
|
194
|
+
//#region src/generator.ts
|
|
195
|
+
function generateDts(items, options) {
|
|
196
|
+
const lines = [];
|
|
197
|
+
lines.push(`// Auto-generated by vite-plugin-typed-env. DO NOT EDIT.`);
|
|
198
|
+
lines.push(`// Re-run vite to regenerate this file.`);
|
|
199
|
+
lines.push(``);
|
|
200
|
+
if (options.augmentImportMeta) {
|
|
201
|
+
lines.push(`/// <reference types="vite/client" />`);
|
|
202
|
+
lines.push(``);
|
|
203
|
+
lines.push(`interface ImportMetaEnv {`);
|
|
204
|
+
for (const { entry, inferred } of items) {
|
|
205
|
+
if (entry.annotations.description) lines.push(` /** ${entry.annotations.description} */`);
|
|
206
|
+
const opt = inferred.isOptional ? "?" : "";
|
|
207
|
+
lines.push(` readonly ${entry.key}${opt}: ${inferred.tsType}`);
|
|
208
|
+
}
|
|
209
|
+
lines.push(`}`);
|
|
210
|
+
lines.push(``);
|
|
211
|
+
lines.push(`interface ImportMeta {`);
|
|
212
|
+
lines.push(` readonly env: ImportMetaEnv`);
|
|
213
|
+
lines.push(`}`);
|
|
214
|
+
} else {
|
|
215
|
+
lines.push(`export interface Env {`);
|
|
216
|
+
for (const { entry, inferred } of items) {
|
|
217
|
+
if (entry.annotations.description) lines.push(` /** ${entry.annotations.description} */`);
|
|
218
|
+
const opt = inferred.isOptional ? "?" : "";
|
|
219
|
+
lines.push(` ${entry.key}${opt}: ${inferred.tsType}`);
|
|
220
|
+
}
|
|
221
|
+
lines.push(`}`);
|
|
222
|
+
}
|
|
223
|
+
return lines.join("\n");
|
|
224
|
+
}
|
|
225
|
+
function generateZodSchema(items) {
|
|
226
|
+
const lines = [];
|
|
227
|
+
lines.push(`// Auto-generated by vite-plugin-typed-env. DO NOT EDIT.`);
|
|
228
|
+
lines.push(`import { z } from 'zod'`);
|
|
229
|
+
lines.push(``);
|
|
230
|
+
lines.push(`export const envSchema = z.object({`);
|
|
231
|
+
for (const { entry, inferred } of items) {
|
|
232
|
+
if (entry.annotations.description) lines.push(` // ${entry.annotations.description}`);
|
|
233
|
+
lines.push(` ${entry.key}: ${inferred.zodSchema},`);
|
|
234
|
+
}
|
|
235
|
+
lines.push(`})`);
|
|
236
|
+
lines.push(``);
|
|
237
|
+
lines.push(`export type Env = z.infer<typeof envSchema>`);
|
|
238
|
+
return lines.join("\n");
|
|
239
|
+
}
|
|
240
|
+
function generateLoader(items, options) {
|
|
241
|
+
const lines = [];
|
|
242
|
+
lines.push(`// Auto-generated by vite-plugin-typed-env. DO NOT EDIT.`);
|
|
243
|
+
lines.push(``);
|
|
244
|
+
if (options.schema === "zod") {
|
|
245
|
+
lines.push(`import { envSchema } from './env.schema'`);
|
|
246
|
+
lines.push(``);
|
|
247
|
+
lines.push(`const _parsed = envSchema.safeParse(import.meta.env)`);
|
|
248
|
+
lines.push(``);
|
|
249
|
+
lines.push(`if (!_parsed.success) {`);
|
|
250
|
+
lines.push(` const errors = _parsed.error.flatten().fieldErrors`);
|
|
251
|
+
lines.push(` const msg = Object.entries(errors)`);
|
|
252
|
+
lines.push(` .map(([k, v]) => \` \${k}: \${(v as string[]).join(', ')}\`)`);
|
|
253
|
+
lines.push(` .join('\\n')`);
|
|
254
|
+
lines.push(` throw new Error(\`[env-ts] Invalid environment variables:\\n\${msg}\`)`);
|
|
255
|
+
lines.push(`}`);
|
|
256
|
+
lines.push(``);
|
|
257
|
+
lines.push(`export const env = _parsed.data`);
|
|
258
|
+
lines.push(`export default env`);
|
|
259
|
+
} else {
|
|
260
|
+
const required = items.filter(({ inferred }) => !inferred.isOptional);
|
|
261
|
+
lines.push(`const _raw = import.meta.env`);
|
|
262
|
+
lines.push(``);
|
|
263
|
+
if (required.length > 0) {
|
|
264
|
+
lines.push(`const _required = [${required.map(({ entry }) => `'${entry.key}'`).join(", ")}] as const`);
|
|
265
|
+
lines.push(`for (const key of _required) {`);
|
|
266
|
+
lines.push(` if (!_raw[key]) throw new Error(\`[env-ts] Missing required env var: \${key}\`)`);
|
|
267
|
+
lines.push(`}`);
|
|
268
|
+
lines.push(``);
|
|
269
|
+
}
|
|
270
|
+
lines.push(`export const env = _raw as import('./env').Env`);
|
|
271
|
+
lines.push(`export default env`);
|
|
272
|
+
}
|
|
273
|
+
return lines.join("\n");
|
|
274
|
+
}
|
|
275
|
+
//#endregion
|
|
276
|
+
//#region src/index.ts
|
|
277
|
+
async function generateTypes(envDir, outputDir, options) {
|
|
278
|
+
const envFileNames = [
|
|
279
|
+
".env",
|
|
280
|
+
".env.local",
|
|
281
|
+
`.env.${process.env.NODE_ENV ?? "development"}`,
|
|
282
|
+
`.env.${process.env.NODE_ENV ?? "development"}.local`,
|
|
283
|
+
...options.envFiles
|
|
284
|
+
];
|
|
285
|
+
const entries = /* @__PURE__ */ new Map();
|
|
286
|
+
for (const fileName of envFileNames) {
|
|
287
|
+
const filePath = node_path.default.join(envDir, fileName);
|
|
288
|
+
if (!node_fs.default.existsSync(filePath)) continue;
|
|
289
|
+
const parsed = parseEnvFile(node_fs.default.readFileSync(filePath, "utf-8"));
|
|
290
|
+
for (const entry of parsed) entries.set(entry.key, entry);
|
|
291
|
+
}
|
|
292
|
+
if (entries.size === 0) {
|
|
293
|
+
console.warn("[env-ts] No .env files found or all are empty, skipping generation.");
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
const items = Array.from(entries.values()).map((entry) => ({
|
|
297
|
+
entry,
|
|
298
|
+
inferred: inferType(entry)
|
|
299
|
+
}));
|
|
300
|
+
if (options.strict) {
|
|
301
|
+
const missing = items.filter(({ inferred }) => !inferred.isOptional && inferred.defaultValue === void 0).filter(({ entry }) => {
|
|
302
|
+
const v = process.env[entry.key];
|
|
303
|
+
return v === void 0 || v === "";
|
|
304
|
+
}).map(({ entry }) => entry.key);
|
|
305
|
+
if (missing.length > 0) {
|
|
306
|
+
const msg = `[env-ts] Missing required env variables: ${missing.join(", ")}`;
|
|
307
|
+
if (process.env.NODE_ENV === "production") throw new Error(msg);
|
|
308
|
+
else console.warn(msg);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
node_fs.default.mkdirSync(outputDir, { recursive: true });
|
|
312
|
+
const genOptions = {
|
|
313
|
+
schema: options.schema,
|
|
314
|
+
augmentImportMeta: options.augmentImportMeta
|
|
315
|
+
};
|
|
316
|
+
const dtsContent = generateDts(items, genOptions);
|
|
317
|
+
writeIfChanged(node_path.default.join(outputDir, "env.d.ts"), dtsContent);
|
|
318
|
+
if (options.schema === "zod") {
|
|
319
|
+
const schemaContent = generateZodSchema(items);
|
|
320
|
+
writeIfChanged(node_path.default.join(outputDir, "env.schema.ts"), schemaContent);
|
|
321
|
+
}
|
|
322
|
+
const loaderContent = generateLoader(items, genOptions);
|
|
323
|
+
writeIfChanged(node_path.default.join(outputDir, "env.ts"), loaderContent);
|
|
324
|
+
console.log(`[env-ts] Generated ${items.length} env types → ${node_path.default.relative(process.cwd(), outputDir)}/`);
|
|
325
|
+
}
|
|
326
|
+
function writeIfChanged(filePath, content) {
|
|
327
|
+
if (node_fs.default.existsSync(filePath)) {
|
|
328
|
+
if (node_fs.default.readFileSync(filePath, "utf-8") === content) return;
|
|
329
|
+
}
|
|
330
|
+
node_fs.default.writeFileSync(filePath, content, "utf-8");
|
|
331
|
+
}
|
|
332
|
+
function envTs(userOptions = {}) {
|
|
333
|
+
const options = {
|
|
334
|
+
schema: "zod",
|
|
335
|
+
output: "src",
|
|
336
|
+
augmentImportMeta: true,
|
|
337
|
+
strict: true,
|
|
338
|
+
envFiles: [],
|
|
339
|
+
...userOptions
|
|
340
|
+
};
|
|
341
|
+
let config;
|
|
342
|
+
let outputDir;
|
|
343
|
+
return {
|
|
344
|
+
name: "vite-plugin-typed-env",
|
|
345
|
+
enforce: "pre",
|
|
346
|
+
configResolved(resolvedConfig) {
|
|
347
|
+
config = resolvedConfig;
|
|
348
|
+
outputDir = node_path.default.resolve(config.root, options.output);
|
|
349
|
+
},
|
|
350
|
+
async buildStart() {
|
|
351
|
+
await generateTypes(config.envDir === false ? config.root : config.envDir, outputDir, options);
|
|
352
|
+
},
|
|
353
|
+
async handleHotUpdate({ file, server }) {
|
|
354
|
+
if (!file) return;
|
|
355
|
+
const fileName = node_path.default.basename(file);
|
|
356
|
+
if (!(fileName.startsWith(".env") || options.envFiles.includes(file))) return;
|
|
357
|
+
console.log(`[env-ts] Detected change in ${fileName}, regenerating...`);
|
|
358
|
+
await generateTypes(config.envDir === false ? config.root : config.envDir, outputDir, options);
|
|
359
|
+
server.hot.send({ type: "full-reload" });
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
//#endregion
|
|
364
|
+
exports.default = envTs;
|
|
365
|
+
exports.generateTypes = generateTypes;
|
|
366
|
+
|
|
367
|
+
//# sourceMappingURL=index.cjs.map
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Plugin } from "vite";
|
|
2
|
+
|
|
3
|
+
//#region src/index.d.ts
|
|
4
|
+
interface EnvTsOptions {
|
|
5
|
+
/**
|
|
6
|
+
* 生成 Zod schema 文件
|
|
7
|
+
* @default 'zod'
|
|
8
|
+
*/
|
|
9
|
+
schema?: 'zod' | false;
|
|
10
|
+
/**
|
|
11
|
+
* 生成文件的输出目录(相对于项目根目录)
|
|
12
|
+
* @default 'src'
|
|
13
|
+
*/
|
|
14
|
+
output?: string;
|
|
15
|
+
/**
|
|
16
|
+
* 是否扩展 Vite 的 ImportMetaEnv 类型
|
|
17
|
+
* 开启后 import.meta.env.YOUR_VAR 自动有类型
|
|
18
|
+
* @default true
|
|
19
|
+
*/
|
|
20
|
+
augmentImportMeta?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* 缺失必填变量时是否让构建失败
|
|
23
|
+
* @default true
|
|
24
|
+
*/
|
|
25
|
+
strict?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* 额外监听的 .env 文件(默认自动检测 .env, .env.local 等)
|
|
28
|
+
*/
|
|
29
|
+
envFiles?: string[];
|
|
30
|
+
}
|
|
31
|
+
declare function generateTypes(envDir: string, outputDir: string, options: Required<EnvTsOptions>): Promise<void>;
|
|
32
|
+
declare function envTs(userOptions?: EnvTsOptions): Plugin;
|
|
33
|
+
//#endregion
|
|
34
|
+
export { EnvTsOptions, envTs as default, generateTypes };
|
|
35
|
+
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Plugin } from "vite";
|
|
2
|
+
|
|
3
|
+
//#region src/index.d.ts
|
|
4
|
+
interface EnvTsOptions {
|
|
5
|
+
/**
|
|
6
|
+
* 生成 Zod schema 文件
|
|
7
|
+
* @default 'zod'
|
|
8
|
+
*/
|
|
9
|
+
schema?: 'zod' | false;
|
|
10
|
+
/**
|
|
11
|
+
* 生成文件的输出目录(相对于项目根目录)
|
|
12
|
+
* @default 'src'
|
|
13
|
+
*/
|
|
14
|
+
output?: string;
|
|
15
|
+
/**
|
|
16
|
+
* 是否扩展 Vite 的 ImportMetaEnv 类型
|
|
17
|
+
* 开启后 import.meta.env.YOUR_VAR 自动有类型
|
|
18
|
+
* @default true
|
|
19
|
+
*/
|
|
20
|
+
augmentImportMeta?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* 缺失必填变量时是否让构建失败
|
|
23
|
+
* @default true
|
|
24
|
+
*/
|
|
25
|
+
strict?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* 额外监听的 .env 文件(默认自动检测 .env, .env.local 等)
|
|
28
|
+
*/
|
|
29
|
+
envFiles?: string[];
|
|
30
|
+
}
|
|
31
|
+
declare function generateTypes(envDir: string, outputDir: string, options: Required<EnvTsOptions>): Promise<void>;
|
|
32
|
+
declare function envTs(userOptions?: EnvTsOptions): Plugin;
|
|
33
|
+
//#endregion
|
|
34
|
+
export { EnvTsOptions, envTs as default, generateTypes };
|
|
35
|
+
//# sourceMappingURL=index.d.mts.map
|