bini-env 1.0.8 → 1.0.10
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 +112 -82
- package/dist/index.d.mts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +170 -143
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +170 -139
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -27
package/dist/index.js
CHANGED
|
@@ -1,36 +1,43 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
3
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
4
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
5
|
+
}) : x)(function(x) {
|
|
6
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
7
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
8
|
+
});
|
|
10
9
|
|
|
11
10
|
// src/index.ts
|
|
12
|
-
|
|
11
|
+
function isNodeLike() {
|
|
12
|
+
return typeof process !== "undefined" && !!process.env && typeof process.versions === "object" && // Edge runtimes (Vercel, Cloudflare) expose a minimal `process` but not
|
|
13
|
+
// `process.versions.node`. Checking for it keeps us out of edge bundles.
|
|
14
|
+
(typeof process.versions.node === "string" || // Bun sets process.versions.bun
|
|
15
|
+
typeof process.versions.bun === "string");
|
|
16
|
+
}
|
|
17
|
+
function isDenoRuntime() {
|
|
18
|
+
return typeof globalThis.Deno !== "undefined";
|
|
19
|
+
}
|
|
20
|
+
var originalConsoleLog = console.log.bind(console);
|
|
21
|
+
var originalConsoleError = console.error.bind(console);
|
|
22
|
+
if (isNodeLike() && !process.env.NODE_ENV) {
|
|
13
23
|
process.env.NODE_ENV = "production";
|
|
14
24
|
}
|
|
25
|
+
var _suppressionApplied = false;
|
|
15
26
|
function suppressDotenvLogsGlobally() {
|
|
16
|
-
if (
|
|
27
|
+
if (_suppressionApplied) return;
|
|
28
|
+
_suppressionApplied = true;
|
|
29
|
+
if (isNodeLike()) {
|
|
17
30
|
process.env.DOTENV_QUIET = "true";
|
|
18
31
|
}
|
|
19
|
-
const
|
|
32
|
+
const isDotenvNoise = (...args) => {
|
|
33
|
+
const msg = args.join(" ");
|
|
34
|
+
return msg.includes("[dotenv@") || msg.includes("injected env") || msg.includes("injecting env");
|
|
35
|
+
};
|
|
20
36
|
console.log = (...args) => {
|
|
21
|
-
|
|
22
|
-
if (message.includes("[dotenv@") && message.includes("injecting env")) {
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
originalLog(...args);
|
|
37
|
+
if (!isDotenvNoise(...args)) originalConsoleLog(...args);
|
|
26
38
|
};
|
|
27
|
-
const originalError = console.error;
|
|
28
39
|
console.error = (...args) => {
|
|
29
|
-
|
|
30
|
-
if (message.includes("[dotenv@") && message.includes("injecting env")) {
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
originalError(...args);
|
|
40
|
+
if (!isDotenvNoise(...args)) originalConsoleError(...args);
|
|
34
41
|
};
|
|
35
42
|
}
|
|
36
43
|
suppressDotenvLogsGlobally();
|
|
@@ -40,22 +47,48 @@ var DEFAULT_OPTIONS = Object.freeze({
|
|
|
40
47
|
enabled: true,
|
|
41
48
|
clearViteHeader: true,
|
|
42
49
|
logo: BINI_LOGO,
|
|
43
|
-
envPrefix: DEFAULT_ENV_PREFIX,
|
|
44
|
-
loadInPreview: true
|
|
45
|
-
suppressDotenvLogs: true
|
|
50
|
+
envPrefix: [...DEFAULT_ENV_PREFIX],
|
|
51
|
+
loadInPreview: true
|
|
46
52
|
});
|
|
47
53
|
var envCache = /* @__PURE__ */ new Map();
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
function timestamp() {
|
|
55
|
+
return `${"\x1B[2m" /* DIM */}${(/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", { hour12: false })}${"\x1B[0m" /* RESET */}`;
|
|
56
|
+
}
|
|
57
|
+
var biniLogger = {
|
|
58
|
+
info(msg) {
|
|
59
|
+
originalConsoleLog(
|
|
60
|
+
`${timestamp()} ${"\x1B[36m" /* CYAN */}${"\x1B[1m" /* BOLD */}[bini-env]${"\x1B[0m" /* RESET */} ${msg}`
|
|
61
|
+
);
|
|
62
|
+
},
|
|
63
|
+
warn(msg) {
|
|
64
|
+
originalConsoleError(
|
|
65
|
+
`${timestamp()} ${"\x1B[33m" /* YELLOW */}${"\x1B[1m" /* BOLD */}(!) [bini-env]${"\x1B[0m" /* RESET */} ${"\x1B[33m" /* YELLOW */}${msg}${"\x1B[0m" /* RESET */}`
|
|
66
|
+
);
|
|
67
|
+
},
|
|
68
|
+
error(msg, err) {
|
|
69
|
+
const detail = err instanceof Error ? `
|
|
70
|
+
${"\x1B[2m" /* DIM */}${err.message}${"\x1B[0m" /* RESET */}` : "";
|
|
71
|
+
originalConsoleError(
|
|
72
|
+
`${timestamp()} ${"\x1B[31m" /* RED */}${"\x1B[1m" /* BOLD */}[bini-env] error${"\x1B[0m" /* RESET */} ${msg}${detail}`
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
function getDeno() {
|
|
77
|
+
return globalThis.Deno;
|
|
78
|
+
}
|
|
79
|
+
function defer(fn) {
|
|
80
|
+
if (typeof setImmediate !== "undefined") {
|
|
81
|
+
setImmediate(fn);
|
|
82
|
+
} else {
|
|
83
|
+
Promise.resolve().then(fn);
|
|
53
84
|
}
|
|
54
|
-
|
|
55
|
-
|
|
85
|
+
}
|
|
86
|
+
function getEnv(key) {
|
|
87
|
+
if (envCache.has(key)) return envCache.get(key);
|
|
88
|
+
const deno = getDeno();
|
|
56
89
|
if (deno) {
|
|
57
90
|
try {
|
|
58
|
-
value = deno.env.get(key);
|
|
91
|
+
const value = deno.env.get(key);
|
|
59
92
|
if (value !== void 0) {
|
|
60
93
|
envCache.set(key, value);
|
|
61
94
|
return value;
|
|
@@ -64,7 +97,7 @@ function getEnv(key) {
|
|
|
64
97
|
}
|
|
65
98
|
}
|
|
66
99
|
if (typeof process !== "undefined" && process.env) {
|
|
67
|
-
value = process.env[key];
|
|
100
|
+
const value = process.env[key];
|
|
68
101
|
if (value !== void 0) {
|
|
69
102
|
envCache.set(key, value);
|
|
70
103
|
return value;
|
|
@@ -73,19 +106,11 @@ function getEnv(key) {
|
|
|
73
106
|
try {
|
|
74
107
|
const metaEnv = undefined;
|
|
75
108
|
if (metaEnv) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (metaEnv[biniKey] !== void 0) {
|
|
82
|
-
envCache.set(key, metaEnv[biniKey]);
|
|
83
|
-
return metaEnv[biniKey];
|
|
84
|
-
}
|
|
85
|
-
const viteKey = `VITE_${key}`;
|
|
86
|
-
if (metaEnv[viteKey] !== void 0) {
|
|
87
|
-
envCache.set(key, metaEnv[viteKey]);
|
|
88
|
-
return metaEnv[viteKey];
|
|
109
|
+
for (const candidate of [key, `BINI_${key}`, `VITE_${key}`]) {
|
|
110
|
+
if (metaEnv[candidate] !== void 0) {
|
|
111
|
+
envCache.set(key, metaEnv[candidate]);
|
|
112
|
+
return metaEnv[candidate];
|
|
113
|
+
}
|
|
89
114
|
}
|
|
90
115
|
}
|
|
91
116
|
} catch {
|
|
@@ -95,12 +120,13 @@ function getEnv(key) {
|
|
|
95
120
|
}
|
|
96
121
|
function requireEnv(key) {
|
|
97
122
|
const val = getEnv(key);
|
|
98
|
-
if (
|
|
99
|
-
|
|
100
|
-
`
|
|
101
|
-
\u2192 In development: add it to your .env file
|
|
102
|
-
\u2192 In production:
|
|
123
|
+
if (val === void 0) {
|
|
124
|
+
biniLogger.error(
|
|
125
|
+
`Missing required environment variable: "${key}"
|
|
126
|
+
${"\x1B[2m" /* DIM */}\u2192 In development: add it to your .env file.${"\x1B[0m" /* RESET */}
|
|
127
|
+
${"\x1B[2m" /* DIM */}\u2192 In production: set it in your hosting dashboard.${"\x1B[0m" /* RESET */}`
|
|
103
128
|
);
|
|
129
|
+
throw new Error(`[bini-env] Missing required environment variable: "${key}"`);
|
|
104
130
|
}
|
|
105
131
|
return val;
|
|
106
132
|
}
|
|
@@ -111,54 +137,57 @@ async function loadEnv(projectRoot) {
|
|
|
111
137
|
if (_loadPromise) return _loadPromise;
|
|
112
138
|
_loadPromise = (async () => {
|
|
113
139
|
try {
|
|
114
|
-
if (
|
|
115
|
-
_envLoaded = true;
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
if (typeof process === "undefined" || !process.env) {
|
|
119
|
-
_envLoaded = true;
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
140
|
+
if (isDenoRuntime() || !isNodeLike()) return;
|
|
122
141
|
const root = projectRoot ?? process.cwd();
|
|
142
|
+
const nodeEnv = process.env.NODE_ENV ?? "production";
|
|
123
143
|
const envFiles = [
|
|
124
144
|
".env",
|
|
125
|
-
`.env.${
|
|
126
|
-
`.env.${
|
|
145
|
+
`.env.${nodeEnv}`,
|
|
146
|
+
`.env.${nodeEnv}.local`,
|
|
127
147
|
".env.local"
|
|
128
148
|
];
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
149
|
+
const [dotenvMod, fsMod, pathMod] = await Promise.all([
|
|
150
|
+
import('dotenv'),
|
|
151
|
+
import('fs'),
|
|
152
|
+
import('path')
|
|
153
|
+
]);
|
|
154
|
+
const dotenv = dotenvMod;
|
|
155
|
+
const fs = fsMod.default ?? fsMod;
|
|
156
|
+
const path = pathMod.default ?? pathMod;
|
|
157
|
+
for (const file of envFiles) {
|
|
158
|
+
const filePath = path.join(root, file);
|
|
133
159
|
try {
|
|
134
|
-
await
|
|
135
|
-
dotenv.config({
|
|
136
|
-
path: envPath,
|
|
137
|
-
override: true,
|
|
138
|
-
quiet: true
|
|
139
|
-
});
|
|
160
|
+
await fs.promises.access(filePath, fs.constants.R_OK);
|
|
161
|
+
dotenv.config({ path: filePath, override: true });
|
|
140
162
|
} catch {
|
|
141
163
|
}
|
|
142
164
|
}
|
|
143
165
|
envCache.clear();
|
|
166
|
+
_envLoaded = true;
|
|
144
167
|
} catch (error) {
|
|
145
|
-
|
|
146
|
-
originalConsoleError("[bini-env] Warning: Failed to load .env file:", error);
|
|
147
|
-
}
|
|
168
|
+
biniLogger.error("Failed to load .env file", error);
|
|
148
169
|
} finally {
|
|
149
|
-
_envLoaded = true;
|
|
150
170
|
_loadPromise = null;
|
|
151
171
|
}
|
|
152
172
|
})();
|
|
153
173
|
return _loadPromise;
|
|
154
174
|
}
|
|
155
175
|
var _envFilesCache = null;
|
|
156
|
-
var
|
|
157
|
-
function detectEnvFiles(projectRoot
|
|
158
|
-
if (
|
|
159
|
-
|
|
160
|
-
}
|
|
176
|
+
var _cacheKey = "";
|
|
177
|
+
function detectEnvFiles(projectRoot) {
|
|
178
|
+
if (!isNodeLike()) return [];
|
|
179
|
+
const root = projectRoot ?? process.cwd();
|
|
161
180
|
const nodeEnv = process.env.NODE_ENV ?? "production";
|
|
181
|
+
const cacheKey = `${root}:${nodeEnv}`;
|
|
182
|
+
if (_envFilesCache && _cacheKey === cacheKey) return _envFilesCache;
|
|
183
|
+
let fsSync;
|
|
184
|
+
let pathMod;
|
|
185
|
+
try {
|
|
186
|
+
fsSync = __require("fs");
|
|
187
|
+
pathMod = __require("path");
|
|
188
|
+
} catch {
|
|
189
|
+
return [];
|
|
190
|
+
}
|
|
162
191
|
const candidates = [
|
|
163
192
|
".env.local",
|
|
164
193
|
`.env.${nodeEnv}.local`,
|
|
@@ -167,20 +196,18 @@ function detectEnvFiles(projectRoot = process.cwd()) {
|
|
|
167
196
|
];
|
|
168
197
|
const found = [];
|
|
169
198
|
for (const file of candidates) {
|
|
170
|
-
const filePath = path__default.default.join(projectRoot, file);
|
|
171
199
|
try {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
200
|
+
const filePath = pathMod.join(root, file);
|
|
201
|
+
if (fsSync.existsSync(filePath)) found.push({ name: file, path: filePath });
|
|
175
202
|
} catch {
|
|
176
203
|
}
|
|
177
204
|
}
|
|
178
205
|
_envFilesCache = found;
|
|
179
|
-
|
|
206
|
+
_cacheKey = cacheKey;
|
|
180
207
|
return found;
|
|
181
208
|
}
|
|
182
209
|
function clearLine() {
|
|
183
|
-
if (process.stdout
|
|
210
|
+
if (typeof process !== "undefined" && process.stdout?.isTTY) {
|
|
184
211
|
process.stdout.write("\x1B[2K\r");
|
|
185
212
|
}
|
|
186
213
|
}
|
|
@@ -197,16 +224,40 @@ function printResolvedUrls(urls) {
|
|
|
197
224
|
);
|
|
198
225
|
}
|
|
199
226
|
}
|
|
227
|
+
function patchPrintUrls(server, mode, logo, clearViteHeader, getRoot, showEnvFiles) {
|
|
228
|
+
let started = false;
|
|
229
|
+
const originalPrintUrls = server.printUrls.bind(server);
|
|
230
|
+
server.printUrls = () => {
|
|
231
|
+
if (started) return;
|
|
232
|
+
started = true;
|
|
233
|
+
if (clearViteHeader) clearLine();
|
|
234
|
+
originalConsoleLog(`
|
|
235
|
+
${"\x1B[36m" /* CYAN */}${logo} Bini.js${"\x1B[0m" /* RESET */} (${mode})`);
|
|
236
|
+
if (showEnvFiles) {
|
|
237
|
+
const found = detectEnvFiles(getRoot());
|
|
238
|
+
if (found.length > 0) {
|
|
239
|
+
originalConsoleLog(
|
|
240
|
+
` ${"\x1B[32m" /* GREEN */}\u279C${"\x1B[0m" /* RESET */} Environments: ${found.map((f) => f.name).join(", ")}`
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (clearViteHeader) {
|
|
245
|
+
printResolvedUrls(server.resolvedUrls);
|
|
246
|
+
} else {
|
|
247
|
+
originalPrintUrls();
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
}
|
|
200
251
|
function biniEnv(options = {}) {
|
|
201
252
|
if (options.enabled === false) {
|
|
202
253
|
return { name: "vite-plugin-bini-env" };
|
|
203
254
|
}
|
|
204
|
-
const
|
|
205
|
-
|
|
255
|
+
const { clearViteHeader, logo, envPrefix, loadInPreview } = {
|
|
256
|
+
...DEFAULT_OPTIONS,
|
|
257
|
+
...options
|
|
258
|
+
};
|
|
206
259
|
let resolvedConfig;
|
|
207
|
-
|
|
208
|
-
suppressDotenvLogsGlobally();
|
|
209
|
-
}
|
|
260
|
+
const getRoot = () => resolvedConfig?.root ?? process.cwd();
|
|
210
261
|
return {
|
|
211
262
|
name: "vite-plugin-bini-env",
|
|
212
263
|
config() {
|
|
@@ -216,77 +267,53 @@ function biniEnv(options = {}) {
|
|
|
216
267
|
resolvedConfig = cfg;
|
|
217
268
|
},
|
|
218
269
|
configureServer(server) {
|
|
219
|
-
const
|
|
220
|
-
void loadEnv(resolvedConfig?.root ?? process.cwd());
|
|
221
|
-
};
|
|
270
|
+
const triggerLoad = () => void loadEnv(getRoot());
|
|
222
271
|
if (server.httpServer) {
|
|
223
|
-
server.httpServer.once("listening",
|
|
272
|
+
server.httpServer.once("listening", triggerLoad);
|
|
224
273
|
} else {
|
|
225
|
-
|
|
274
|
+
defer(triggerLoad);
|
|
226
275
|
}
|
|
227
|
-
|
|
228
|
-
|
|
276
|
+
const envGlob = `${getRoot()}/.env*`;
|
|
277
|
+
server.watcher.add(envGlob);
|
|
278
|
+
const onEnvChange = (filePath) => {
|
|
279
|
+
if (/\.(swp|swo|bak|tmp)$|~$/.test(filePath)) return;
|
|
280
|
+
biniLogger.info(
|
|
281
|
+
`env file ${filePath.replace(getRoot() + "/", "")} changed \u2014 restarting server`
|
|
282
|
+
);
|
|
283
|
+
_envLoaded = false;
|
|
284
|
+
_loadPromise = null;
|
|
285
|
+
envCache.clear();
|
|
286
|
+
_envFilesCache = null;
|
|
287
|
+
void server.restart();
|
|
288
|
+
};
|
|
289
|
+
server.watcher.on("add", onEnvChange);
|
|
290
|
+
server.watcher.on("change", onEnvChange);
|
|
291
|
+
server.httpServer?.once("close", () => {
|
|
292
|
+
server.watcher.off("add", onEnvChange);
|
|
293
|
+
server.watcher.off("change", onEnvChange);
|
|
294
|
+
});
|
|
229
295
|
if (clearViteHeader || logo !== BINI_LOGO) {
|
|
230
|
-
server
|
|
231
|
-
if (serverStarted) return;
|
|
232
|
-
serverStarted = true;
|
|
233
|
-
if (clearViteHeader) clearLine();
|
|
234
|
-
originalConsoleLog(`
|
|
235
|
-
${"\x1B[36m" /* CYAN */}${logo} Bini.js${"\x1B[0m" /* RESET */} (dev)`);
|
|
236
|
-
const found = detectEnvFiles(resolvedConfig?.root);
|
|
237
|
-
if (found.length > 0) {
|
|
238
|
-
originalConsoleLog(
|
|
239
|
-
` ${"\x1B[32m" /* GREEN */}\u279C${"\x1B[0m" /* RESET */} Environments: ${found.map((f) => f.name).join(", ")}`
|
|
240
|
-
);
|
|
241
|
-
}
|
|
242
|
-
if (!clearViteHeader) {
|
|
243
|
-
originalPrintUrls();
|
|
244
|
-
} else {
|
|
245
|
-
printResolvedUrls(server.resolvedUrls);
|
|
246
|
-
}
|
|
247
|
-
};
|
|
296
|
+
patchPrintUrls(server, "dev", logo, clearViteHeader, getRoot, true);
|
|
248
297
|
}
|
|
249
298
|
},
|
|
250
299
|
configurePreviewServer(server) {
|
|
251
300
|
if (loadInPreview) {
|
|
252
|
-
const
|
|
253
|
-
void loadEnv(resolvedConfig?.root ?? process.cwd());
|
|
254
|
-
};
|
|
301
|
+
const triggerLoad = () => void loadEnv(getRoot());
|
|
255
302
|
if (server.httpServer) {
|
|
256
|
-
server.httpServer.once("listening",
|
|
303
|
+
server.httpServer.once("listening", triggerLoad);
|
|
257
304
|
} else {
|
|
258
|
-
|
|
305
|
+
defer(triggerLoad);
|
|
259
306
|
}
|
|
260
307
|
}
|
|
261
|
-
let previewStarted = false;
|
|
262
|
-
const originalPrintUrls = server.printUrls.bind(server);
|
|
263
308
|
if (clearViteHeader || logo !== BINI_LOGO) {
|
|
264
|
-
server
|
|
265
|
-
if (previewStarted) return;
|
|
266
|
-
previewStarted = true;
|
|
267
|
-
if (clearViteHeader) clearLine();
|
|
268
|
-
originalConsoleLog(`
|
|
269
|
-
${"\x1B[36m" /* CYAN */}${logo} Bini.js${"\x1B[0m" /* RESET */} (preview)`);
|
|
270
|
-
if (loadInPreview) {
|
|
271
|
-
const found = detectEnvFiles(resolvedConfig?.root);
|
|
272
|
-
if (found.length > 0) {
|
|
273
|
-
originalConsoleLog(
|
|
274
|
-
` ${"\x1B[32m" /* GREEN */}\u279C${"\x1B[0m" /* RESET */} Environments: ${found.map((f) => f.name).join(", ")}`
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
if (!clearViteHeader) {
|
|
279
|
-
originalPrintUrls();
|
|
280
|
-
} else {
|
|
281
|
-
printResolvedUrls(server.resolvedUrls);
|
|
282
|
-
}
|
|
283
|
-
};
|
|
309
|
+
patchPrintUrls(server, "preview", logo, clearViteHeader, getRoot, loadInPreview);
|
|
284
310
|
}
|
|
285
311
|
}
|
|
286
312
|
};
|
|
287
313
|
}
|
|
288
314
|
|
|
289
315
|
exports.biniEnv = biniEnv;
|
|
316
|
+
exports.biniLogger = biniLogger;
|
|
290
317
|
exports.detectEnvFiles = detectEnvFiles;
|
|
291
318
|
exports.getEnv = getEnv;
|
|
292
319
|
exports.loadEnv = loadEnv;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":["path","fs"],"mappings":"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","file":"index.js","sourcesContent":["// bini-env/src/index.ts\nimport fs from 'fs';\nimport path from 'path';\nimport type { Plugin, ResolvedConfig, UserConfig } from 'vite';\n\n/* ==========================================================================\n Default NODE_ENV — must run before anything else\n ========================================================================== */\n\nif (typeof process !== 'undefined' && process.env && !process.env.NODE_ENV) {\n process.env.NODE_ENV = 'production';\n}\n\n/* ==========================================================================\n IMMEDIATE DOTENV SUPPRESSION - Runs at module load\n ========================================================================== */\n\nexport function suppressDotenvLogsGlobally(): void {\n if (typeof process !== 'undefined' && process.env) {\n process.env.DOTENV_QUIET = 'true';\n }\n\n const originalLog = console.log;\n console.log = (...args: any[]) => {\n const message = args.join(' ');\n if (message.includes('[dotenv@') && message.includes('injecting env')) {\n return;\n }\n originalLog(...args);\n };\n\n const originalError = console.error;\n console.error = (...args: any[]) => {\n const message = args.join(' ');\n if (message.includes('[dotenv@') && message.includes('injecting env')) {\n return;\n }\n originalError(...args);\n };\n}\n\n// Run suppression immediately when module loads\nsuppressDotenvLogsGlobally();\n\n/* ==========================================================================\n Global type declarations for cross-runtime compatibility\n ========================================================================== */\n\ninterface DenoEnv {\n get(key: string): string | undefined;\n toObject(): Record<string, string>;\n}\ninterface DenoNamespace {\n env: DenoEnv;\n}\n\n/// <reference types=\"vite/client\" />\n\n/* ==========================================================================\n Types\n ========================================================================== */\n\nexport interface BiniEnvPluginOptions {\n readonly enabled?: boolean;\n readonly clearViteHeader?: boolean;\n readonly logo?: string;\n readonly envPrefix?: string | string[];\n readonly loadInPreview?: boolean;\n readonly suppressDotenvLogs?: boolean;\n}\n\nexport interface DetectedEnvFile {\n readonly name: string;\n readonly path: string;\n}\n\n/* ==========================================================================\n Constants\n ========================================================================== */\n\nconst BINI_LOGO = 'ß';\nconst DEFAULT_ENV_PREFIX: string[] = ['BINI_', 'VITE_'];\n\nconst DEFAULT_OPTIONS: Required<BiniEnvPluginOptions> = Object.freeze({\n enabled: true,\n clearViteHeader: true,\n logo: BINI_LOGO,\n envPrefix: DEFAULT_ENV_PREFIX,\n loadInPreview: true,\n suppressDotenvLogs: true,\n});\n\nconst enum COLORS {\n CYAN = '\\x1b[36m',\n RESET = '\\x1b[0m',\n GREEN = '\\x1b[32m',\n}\n\nconst envCache = new Map<string, string | undefined>();\n\n// Store original console functions before any patching\nconst originalConsoleLog = console.log;\nconst originalConsoleError = console.error;\n\n/* ==========================================================================\n getEnv\n ========================================================================== */\n\nexport function getEnv(key: string): string | undefined {\n if (envCache.has(key)) {\n return envCache.get(key);\n }\n\n let value: string | undefined;\n\n // 1. Deno runtime\n const deno = (globalThis as unknown as { Deno?: DenoNamespace }).Deno;\n if (deno) {\n try {\n value = deno.env.get(key);\n if (value !== undefined) {\n envCache.set(key, value);\n return value;\n }\n } catch {\n // fall through\n }\n }\n\n // 2. Node.js / Bun\n if (typeof process !== 'undefined' && process.env) {\n value = process.env[key];\n if (value !== undefined) {\n envCache.set(key, value);\n return value;\n }\n }\n\n // 3. Vite client (import.meta.env)\n try {\n const metaEnv = import.meta.env as Record<string, string | undefined> | undefined;\n if (metaEnv) {\n if (metaEnv[key] !== undefined) {\n envCache.set(key, metaEnv[key]);\n return metaEnv[key];\n }\n const biniKey = `BINI_${key}`;\n if (metaEnv[biniKey] !== undefined) {\n envCache.set(key, metaEnv[biniKey]);\n return metaEnv[biniKey];\n }\n const viteKey = `VITE_${key}`;\n if (metaEnv[viteKey] !== undefined) {\n envCache.set(key, metaEnv[viteKey]);\n return metaEnv[viteKey];\n }\n }\n } catch {\n // import.meta.env not available\n }\n\n envCache.set(key, undefined);\n return undefined;\n}\n\n/* ==========================================================================\n requireEnv\n ========================================================================== */\n\nexport function requireEnv(key: string): string {\n const val = getEnv(key);\n if (!val) {\n throw new Error(\n `[bini-env] Missing required environment variable: \"${key}\".\\n` +\n ` → In development: add it to your .env file.\\n` +\n ` → In production: add it to your hosting dashboard environment variables.`,\n );\n }\n return val;\n}\n\n/* ==========================================================================\n loadEnv\n ========================================================================== */\n\nlet _envLoaded = false;\nlet _loadPromise: Promise<void> | null = null;\n\nexport async function loadEnv(projectRoot?: string): Promise<void> {\n if (_envLoaded) return;\n if (_loadPromise) return _loadPromise;\n\n _loadPromise = (async () => {\n try {\n // Deno — env is already available via Deno.env\n if ((globalThis as unknown as { Deno?: DenoNamespace }).Deno) {\n _envLoaded = true;\n return;\n }\n\n if (typeof process === 'undefined' || !process.env) {\n _envLoaded = true;\n return;\n }\n\n const root = projectRoot ?? process.cwd();\n\n // Load order: lowest → highest priority\n const envFiles = [\n '.env',\n `.env.${process.env.NODE_ENV}`,\n `.env.${process.env.NODE_ENV}.local`,\n '.env.local',\n ];\n\n suppressDotenvLogsGlobally();\n\n const dotenv = await import('dotenv');\n\n for (const envFile of envFiles) {\n const envPath = path.join(root, envFile);\n try {\n await fs.promises.access(envPath, fs.constants.R_OK);\n dotenv.config({\n path : envPath,\n override: true,\n quiet : true,\n } as Parameters<typeof dotenv.config>[0]);\n } catch {\n // file doesn't exist — skip\n }\n }\n\n // Clear cache so newly loaded vars are picked up\n envCache.clear();\n\n } catch (error) {\n if (process.env.NODE_ENV !== 'production') {\n originalConsoleError('[bini-env] Warning: Failed to load .env file:', error);\n }\n } finally {\n _envLoaded = true;\n _loadPromise = null;\n }\n })();\n\n return _loadPromise;\n}\n\n/* ==========================================================================\n detectEnvFiles\n ========================================================================== */\n\nlet _envFilesCache: DetectedEnvFile[] | null = null;\nlet _cachedRoot = '';\n\nexport function detectEnvFiles(projectRoot: string = process.cwd()): DetectedEnvFile[] {\n if (_envFilesCache && _cachedRoot === projectRoot) {\n return _envFilesCache;\n }\n\n const nodeEnv = process.env.NODE_ENV ?? 'production';\n const candidates = [\n '.env.local',\n `.env.${nodeEnv}.local`,\n `.env.${nodeEnv}`,\n '.env',\n ];\n\n const found: DetectedEnvFile[] = [];\n\n for (const file of candidates) {\n const filePath = path.join(projectRoot, file);\n try {\n if (fs.existsSync(filePath)) {\n found.push({ name: file, path: filePath });\n }\n } catch {\n // skip\n }\n }\n\n _envFilesCache = found;\n _cachedRoot = projectRoot;\n\n return found;\n}\n\n/* ==========================================================================\n Vite plugin\n ========================================================================== */\n\nfunction clearLine(): void {\n if (process.stdout.isTTY) {\n process.stdout.write('\\x1b[2K\\r');\n }\n}\n\nfunction printResolvedUrls(\n urls: { local: string[]; network: string[] } | null | undefined,\n): void {\n if (!urls) return;\n if (urls.local.length > 0) {\n originalConsoleLog(\n ` ${COLORS.GREEN}➜${COLORS.RESET} Local: ${COLORS.CYAN}${urls.local[0]}${COLORS.RESET}`,\n );\n }\n if (urls.network.length > 0) {\n originalConsoleLog(\n ` ${COLORS.GREEN}➜${COLORS.RESET} Network: ${COLORS.CYAN}${urls.network[0]}${COLORS.RESET}`,\n );\n }\n}\n\nexport function biniEnv(options: Readonly<BiniEnvPluginOptions> = {}): Plugin {\n if (options.enabled === false) {\n return { name: 'vite-plugin-bini-env' };\n }\n\n const resolvedOptions = { ...DEFAULT_OPTIONS, ...options };\n const { clearViteHeader, logo, envPrefix, loadInPreview, suppressDotenvLogs } = resolvedOptions;\n\n let resolvedConfig: ResolvedConfig;\n\n if (suppressDotenvLogs && typeof process !== 'undefined') {\n suppressDotenvLogsGlobally();\n }\n\n return {\n name: 'vite-plugin-bini-env',\n\n config(): UserConfig {\n return { envPrefix };\n },\n\n configResolved(cfg: ResolvedConfig) {\n resolvedConfig = cfg;\n },\n\n configureServer(server) {\n const loadEnvTask = () => {\n void loadEnv(resolvedConfig?.root ?? process.cwd());\n };\n\n if (server.httpServer) {\n server.httpServer.once('listening', loadEnvTask);\n } else {\n setImmediate(loadEnvTask);\n }\n\n let serverStarted = false;\n const originalPrintUrls = server.printUrls.bind(server);\n\n if (clearViteHeader || logo !== BINI_LOGO) {\n server.printUrls = () => {\n if (serverStarted) return;\n serverStarted = true;\n\n if (clearViteHeader) clearLine();\n originalConsoleLog(`\\n ${COLORS.CYAN}${logo} Bini.js${COLORS.RESET} (dev)`);\n\n const found = detectEnvFiles(resolvedConfig?.root);\n if (found.length > 0) {\n originalConsoleLog(\n ` ${COLORS.GREEN}➜${COLORS.RESET} Environments: ${found.map(f => f.name).join(', ')}`,\n );\n }\n\n if (!clearViteHeader) {\n originalPrintUrls();\n } else {\n printResolvedUrls(server.resolvedUrls);\n }\n };\n }\n },\n\n configurePreviewServer(server) {\n if (loadInPreview) {\n const loadEnvTask = () => {\n void loadEnv(resolvedConfig?.root ?? process.cwd());\n };\n\n if (server.httpServer) {\n server.httpServer.once('listening', loadEnvTask);\n } else {\n setImmediate(loadEnvTask);\n }\n }\n\n let previewStarted = false;\n const originalPrintUrls = server.printUrls.bind(server);\n\n if (clearViteHeader || logo !== BINI_LOGO) {\n server.printUrls = () => {\n if (previewStarted) return;\n previewStarted = true;\n\n if (clearViteHeader) clearLine();\n originalConsoleLog(`\\n ${COLORS.CYAN}${logo} Bini.js${COLORS.RESET} (preview)`);\n\n if (loadInPreview) {\n const found = detectEnvFiles(resolvedConfig?.root);\n if (found.length > 0) {\n originalConsoleLog(\n ` ${COLORS.GREEN}➜${COLORS.RESET} Environments: ${found.map(f => f.name).join(', ')}`,\n );\n }\n }\n\n if (!clearViteHeader) {\n originalPrintUrls();\n } else {\n printResolvedUrls(server.resolvedUrls);\n }\n };\n }\n },\n };\n}\n\nexport type { Plugin } from 'vite';"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// bini-env/src/index.ts\nimport type { Plugin, PreviewServer, ResolvedConfig, UserConfig, ViteDevServer } from 'vite';\n\n/* ==========================================================================\n Runtime detection — must run before anything else\n ========================================================================== */\n\nfunction isNodeLike(): boolean {\n return (\n typeof process !== 'undefined' &&\n !!process.env &&\n typeof process.versions === 'object' &&\n // Edge runtimes (Vercel, Cloudflare) expose a minimal `process` but not\n // `process.versions.node`. Checking for it keeps us out of edge bundles.\n (typeof process.versions.node === 'string' ||\n // Bun sets process.versions.bun\n typeof (process.versions as Record<string, unknown>).bun === 'string')\n );\n}\n\nfunction isDenoRuntime(): boolean {\n return typeof (globalThis as unknown as { Deno?: unknown }).Deno !== 'undefined';\n}\n\n/* ==========================================================================\n Capture originals FIRST — before any patching occurs\n ========================================================================== */\n\nconst originalConsoleLog = console.log.bind(console);\nconst originalConsoleError = console.error.bind(console);\n\n/* ==========================================================================\n Default NODE_ENV — must run before anything else\n ========================================================================== */\n\nif (isNodeLike() && !process.env.NODE_ENV) {\n process.env.NODE_ENV = 'production';\n}\n\n/* ==========================================================================\n DOTENV LOG SUPPRESSION\n Patched once at module load; subsequent calls are no-ops.\n ========================================================================== */\n\nlet _suppressionApplied = false;\n\nexport function suppressDotenvLogsGlobally(): void {\n if (_suppressionApplied) return;\n _suppressionApplied = true;\n\n if (isNodeLike()) {\n process.env.DOTENV_QUIET = 'true';\n }\n\n const isDotenvNoise = (...args: unknown[]): boolean => {\n const msg = args.join(' ');\n return (\n msg.includes('[dotenv@') ||\n msg.includes('injected env') ||\n msg.includes('injecting env')\n );\n };\n\n console.log = (...args: unknown[]) => {\n if (!isDotenvNoise(...args)) originalConsoleLog(...args);\n };\n\n console.error = (...args: unknown[]) => {\n if (!isDotenvNoise(...args)) originalConsoleError(...args);\n };\n}\n\n// Apply once at module load\nsuppressDotenvLogsGlobally();\n\n/* ==========================================================================\n Cross-runtime type declarations\n ========================================================================== */\n\ninterface DenoEnv {\n get(key: string): string | undefined;\n}\ninterface DenoNamespace {\n env: DenoEnv;\n}\n\n/* ==========================================================================\n Public types\n ========================================================================== */\n\nexport interface BiniEnvPluginOptions {\n readonly enabled?: boolean;\n readonly clearViteHeader?: boolean;\n readonly logo?: string;\n readonly envPrefix?: string | string[];\n readonly loadInPreview?: boolean;\n /** @deprecated Suppression is always applied at module load; this option is ignored. */\n readonly suppressDotenvLogs?: boolean;\n}\n\nexport interface DetectedEnvFile {\n readonly name: string;\n readonly path: string;\n}\n\n/* ==========================================================================\n Constants\n ========================================================================== */\n\nconst BINI_LOGO = 'ß';\nconst DEFAULT_ENV_PREFIX = ['BINI_', 'VITE_'] as const;\n\nconst DEFAULT_OPTIONS = Object.freeze({\n enabled : true,\n clearViteHeader: true,\n logo : BINI_LOGO,\n envPrefix : [...DEFAULT_ENV_PREFIX],\n loadInPreview : true,\n} satisfies Omit<Required<BiniEnvPluginOptions>, 'suppressDotenvLogs'>);\n\nconst enum COLORS {\n CYAN = '\\x1b[36m',\n RESET = '\\x1b[0m',\n GREEN = '\\x1b[32m',\n YELLOW = '\\x1b[33m',\n RED = '\\x1b[31m',\n BOLD = '\\x1b[1m',\n DIM = '\\x1b[2m',\n}\n\nconst envCache = new Map<string, string | undefined>();\n\n/* ==========================================================================\n Standalone logger\n ========================================================================== */\n\nfunction timestamp(): string {\n return `${COLORS.DIM}${new Date().toLocaleTimeString('en-US', { hour12: false })}${COLORS.RESET}`;\n}\n\nexport const biniLogger = {\n info(msg: string): void {\n originalConsoleLog(\n `${timestamp()} ${COLORS.CYAN}${COLORS.BOLD}[bini-env]${COLORS.RESET} ${msg}`,\n );\n },\n warn(msg: string): void {\n originalConsoleError(\n `${timestamp()} ${COLORS.YELLOW}${COLORS.BOLD}(!) [bini-env]${COLORS.RESET} ${COLORS.YELLOW}${msg}${COLORS.RESET}`,\n );\n },\n error(msg: string, err?: unknown): void {\n const detail = err instanceof Error\n ? `\\n ${COLORS.DIM}${err.message}${COLORS.RESET}`\n : '';\n originalConsoleError(\n `${timestamp()} ${COLORS.RED}${COLORS.BOLD}[bini-env] error${COLORS.RESET} ${msg}${detail}`,\n );\n },\n} as const;\n\n/* ==========================================================================\n Runtime helpers\n ========================================================================== */\n\nfunction getDeno(): DenoNamespace | undefined {\n return (globalThis as unknown as { Deno?: DenoNamespace }).Deno;\n}\n\n/** Schedule a task compatible with Node, Bun, Deno, and edge runtimes. */\nfunction defer(fn: () => void): void {\n if (typeof setImmediate !== 'undefined') {\n setImmediate(fn);\n } else {\n Promise.resolve().then(fn);\n }\n}\n\n/* ==========================================================================\n getEnv\n ========================================================================== */\n\nexport function getEnv(key: string): string | undefined {\n if (envCache.has(key)) return envCache.get(key);\n\n // 1. Deno runtime\n const deno = getDeno();\n if (deno) {\n try {\n const value = deno.env.get(key);\n if (value !== undefined) {\n envCache.set(key, value);\n return value;\n }\n } catch { /* fall through */ }\n }\n\n // 2. Node.js / Bun / Edge (process.env is available on most edge runtimes too)\n if (typeof process !== 'undefined' && process.env) {\n const value = process.env[key];\n if (value !== undefined) {\n envCache.set(key, value);\n return value;\n }\n }\n\n // 3. Vite client (import.meta.env) — also checks BINI_ and VITE_ prefixed variants\n try {\n const metaEnv = import.meta.env as Record<string, string | undefined> | undefined;\n if (metaEnv) {\n for (const candidate of [key, `BINI_${key}`, `VITE_${key}`]) {\n if (metaEnv[candidate] !== undefined) {\n envCache.set(key, metaEnv[candidate]);\n return metaEnv[candidate];\n }\n }\n }\n } catch { /* import.meta.env not available in this runtime */ }\n\n envCache.set(key, undefined);\n return undefined;\n}\n\n/* ==========================================================================\n requireEnv\n ========================================================================== */\n\nexport function requireEnv(key: string): string {\n const val = getEnv(key);\n if (val === undefined) {\n biniLogger.error(\n `Missing required environment variable: \"${key}\"\\n` +\n ` ${COLORS.DIM}→ In development: add it to your .env file.${COLORS.RESET}\\n` +\n ` ${COLORS.DIM}→ In production: set it in your hosting dashboard.${COLORS.RESET}`,\n );\n throw new Error(`[bini-env] Missing required environment variable: \"${key}\"`);\n }\n return val;\n}\n\n/* ==========================================================================\n loadEnv\n - Only runs on Node-like runtimes (Node.js, Bun).\n - Edge runtimes and Deno skip entirely — they get vars from the host.\n - Idempotent; concurrent calls share one promise.\n ========================================================================== */\n\nlet _envLoaded = false;\nlet _loadPromise: Promise<void> | null = null;\n\nexport async function loadEnv(projectRoot?: string): Promise<void> {\n if (_envLoaded) return;\n if (_loadPromise) return _loadPromise;\n\n _loadPromise = (async () => {\n try {\n // Deno and edge runtimes do not use .env files — vars are injected by host\n if (isDenoRuntime() || !isNodeLike()) return;\n\n const root = projectRoot ?? process.cwd();\n const nodeEnv = process.env.NODE_ENV ?? 'production';\n\n // Load order: lowest → highest priority (later files override earlier ones)\n const envFiles = [\n '.env',\n `.env.${nodeEnv}`,\n `.env.${nodeEnv}.local`,\n '.env.local',\n ];\n\n // Dynamic import keeps `dotenv` and `fs`/`path` out of edge bundles entirely.\n // Bundlers that trace static imports (esbuild, Rollup) will NOT follow\n // a runtime-gated dynamic import when tree-shaking is enabled.\n const [dotenvMod, fsMod, pathMod] = await Promise.all([\n import('dotenv'),\n import('node:fs'),\n import('node:path'),\n ]);\n const dotenv = dotenvMod;\n const fs = fsMod.default ?? fsMod;\n const path = pathMod.default ?? pathMod;\n\n for (const file of envFiles) {\n const filePath = path.join(root, file);\n try {\n await fs.promises.access(filePath, fs.constants.R_OK);\n dotenv.config({ path: filePath, override: true });\n } catch { /* file absent — skip */ }\n }\n\n // Invalidate cache so newly loaded vars are picked up by getEnv\n envCache.clear();\n _envLoaded = true;\n\n } catch (error) {\n biniLogger.error('Failed to load .env file', error);\n // Do NOT set _envLoaded — allow a retry on the next call.\n } finally {\n _loadPromise = null;\n }\n })();\n\n return _loadPromise;\n}\n\n/* ==========================================================================\n detectEnvFiles\n Node-only utility used by the Vite plugin (build-time only, never edge).\n ========================================================================== */\n\nlet _envFilesCache: DetectedEnvFile[] | null = null;\nlet _cacheKey = '';\n\nexport function detectEnvFiles(projectRoot?: string): DetectedEnvFile[] {\n // Guard: this function uses fs synchronously; bail on non-Node runtimes.\n if (!isNodeLike()) return [];\n\n const root = projectRoot ?? process.cwd();\n const nodeEnv = process.env.NODE_ENV ?? 'production';\n const cacheKey = `${root}:${nodeEnv}`;\n if (_envFilesCache && _cacheKey === cacheKey) return _envFilesCache;\n\n // Inline the fs/path usage so no top-level import is needed.\n // This function is only ever called from the Vite plugin (configureServer /\n // configurePreviewServer), which runs in Node — never in an edge bundle.\n let fsSync: typeof import('fs');\n let pathMod: typeof import('path');\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n fsSync = require('node:fs');\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n pathMod = require('node:path');\n } catch {\n return [];\n }\n\n const candidates = [\n '.env.local',\n `.env.${nodeEnv}.local`,\n `.env.${nodeEnv}`,\n '.env',\n ];\n\n const found: DetectedEnvFile[] = [];\n for (const file of candidates) {\n try {\n const filePath = pathMod.join(root, file);\n if (fsSync.existsSync(filePath)) found.push({ name: file, path: filePath });\n } catch { /* skip unreadable paths */ }\n }\n\n _envFilesCache = found;\n _cacheKey = cacheKey;\n return found;\n}\n\n/* ==========================================================================\n Vite plugin helpers\n ========================================================================== */\n\nfunction clearLine(): void {\n if (typeof process !== 'undefined' && process.stdout?.isTTY) {\n process.stdout.write('\\x1b[2K\\r');\n }\n}\n\nfunction printResolvedUrls(\n urls: { local: string[]; network: string[] } | null | undefined,\n): void {\n if (!urls) return;\n if (urls.local.length > 0) {\n originalConsoleLog(\n ` ${COLORS.GREEN}➜${COLORS.RESET} Local: ${COLORS.CYAN}${urls.local[0]}${COLORS.RESET}`,\n );\n }\n if (urls.network.length > 0) {\n originalConsoleLog(\n ` ${COLORS.GREEN}➜${COLORS.RESET} Network: ${COLORS.CYAN}${urls.network[0]}${COLORS.RESET}`,\n );\n }\n}\n\ntype ServerLike = ViteDevServer | PreviewServer;\n\nfunction patchPrintUrls(\n server : ServerLike,\n mode : 'dev' | 'preview',\n logo : string,\n clearViteHeader: boolean,\n getRoot : () => string,\n showEnvFiles : boolean,\n): void {\n let started = false;\n const originalPrintUrls = server.printUrls.bind(server);\n\n server.printUrls = () => {\n if (started) return;\n started = true;\n\n if (clearViteHeader) clearLine();\n originalConsoleLog(`\\n ${COLORS.CYAN}${logo} Bini.js${COLORS.RESET} (${mode})`);\n\n if (showEnvFiles) {\n const found = detectEnvFiles(getRoot());\n if (found.length > 0) {\n originalConsoleLog(\n ` ${COLORS.GREEN}➜${COLORS.RESET} Environments: ${found.map(f => f.name).join(', ')}`,\n );\n }\n }\n\n if (clearViteHeader) {\n printResolvedUrls(server.resolvedUrls);\n } else {\n originalPrintUrls();\n }\n };\n}\n\n/* ==========================================================================\n Vite plugin\n ========================================================================== */\n\nexport function biniEnv(options: Readonly<BiniEnvPluginOptions> = {}): Plugin {\n if (options.enabled === false) {\n return { name: 'vite-plugin-bini-env' };\n }\n\n const { clearViteHeader, logo, envPrefix, loadInPreview } = {\n ...DEFAULT_OPTIONS,\n ...options,\n };\n\n let resolvedConfig: ResolvedConfig;\n const getRoot = () => resolvedConfig?.root ?? process.cwd();\n\n return {\n name: 'vite-plugin-bini-env',\n\n config(): UserConfig {\n return { envPrefix };\n },\n\n configResolved(cfg: ResolvedConfig) {\n resolvedConfig = cfg;\n },\n\n configureServer(server) {\n const triggerLoad = () => void loadEnv(getRoot());\n if (server.httpServer) {\n server.httpServer.once('listening', triggerLoad);\n } else {\n defer(triggerLoad);\n }\n\n // Watch for new or changed .env files and restart the dev server so the\n // fresh variables are picked up. Chokidar (bundled with Vite) handles the\n // add/change events; we reset _envLoaded so loadEnv re-reads on restart.\n const envGlob = `${getRoot()}/.env*`;\n server.watcher.add(envGlob);\n\n const onEnvChange = (filePath: string) => {\n // Ignore editor swap/temp files (.env.swp, .env~, etc.)\n if (/\\.(swp|swo|bak|tmp)$|~$/.test(filePath)) return;\n\n biniLogger.info(\n `env file ${filePath.replace(getRoot() + '/', '')} changed — restarting server`,\n );\n\n // Reset load state so the restarted server re-reads all .env files\n _envLoaded = false;\n _loadPromise = null;\n envCache.clear();\n _envFilesCache = null;\n\n void server.restart();\n };\n\n server.watcher.on('add', onEnvChange);\n server.watcher.on('change', onEnvChange);\n\n // Remove listeners when the server closes so they don't stack across\n // restarts — Vite calls configureServer again on each restart.\n server.httpServer?.once('close', () => {\n server.watcher.off('add', onEnvChange);\n server.watcher.off('change', onEnvChange);\n });\n\n if (clearViteHeader || logo !== BINI_LOGO) {\n patchPrintUrls(server, 'dev', logo, clearViteHeader, getRoot, true);\n }\n },\n\n configurePreviewServer(server) {\n if (loadInPreview) {\n const triggerLoad = () => void loadEnv(getRoot());\n if (server.httpServer) {\n server.httpServer.once('listening', triggerLoad);\n } else {\n defer(triggerLoad);\n }\n }\n\n if (clearViteHeader || logo !== BINI_LOGO) {\n patchPrintUrls(server, 'preview', logo, clearViteHeader, getRoot, loadInPreview);\n }\n },\n };\n}\n\nexport type { Plugin } from 'vite';"]}
|