bini-env 1.0.9 → 1.1.0

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.js CHANGED
@@ -1,38 +1,21 @@
1
1
  'use strict';
2
2
 
3
- var fs = require('fs');
4
- var path = require('path');
3
+ var adapter = require('hono/adapter');
5
4
 
6
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
-
8
- var fs__default = /*#__PURE__*/_interopDefault(fs);
9
- var path__default = /*#__PURE__*/_interopDefault(path);
10
-
11
- // src/index.ts
5
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
6
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
7
+ }) : x)(function(x) {
8
+ if (typeof require !== "undefined") return require.apply(this, arguments);
9
+ throw Error('Dynamic require of "' + x + '" is not supported');
10
+ });
11
+ function isNodeLike() {
12
+ return typeof process !== "undefined" && !!process.env && typeof process.versions === "object" && (typeof process.versions.node === "string" || typeof process.versions.bun === "string");
13
+ }
12
14
  var originalConsoleLog = console.log.bind(console);
13
15
  var originalConsoleError = console.error.bind(console);
14
- if (typeof process !== "undefined" && process.env && !process.env.NODE_ENV) {
16
+ if (isNodeLike() && !process.env.NODE_ENV) {
15
17
  process.env.NODE_ENV = "production";
16
18
  }
17
- var _suppressionApplied = false;
18
- function suppressDotenvLogsGlobally() {
19
- if (_suppressionApplied) return;
20
- _suppressionApplied = true;
21
- if (typeof process !== "undefined" && process.env) {
22
- process.env.DOTENV_QUIET = "true";
23
- }
24
- const isDotenvNoise = (...args) => {
25
- const msg = args.join(" ");
26
- return msg.includes("[dotenv@") || msg.includes("injected env") || msg.includes("injecting env");
27
- };
28
- console.log = (...args) => {
29
- if (!isDotenvNoise(...args)) originalConsoleLog(...args);
30
- };
31
- console.error = (...args) => {
32
- if (!isDotenvNoise(...args)) originalConsoleError(...args);
33
- };
34
- }
35
- suppressDotenvLogsGlobally();
36
19
  var BINI_LOGO = "\xDF";
37
20
  var DEFAULT_ENV_PREFIX = ["BINI_", "VITE_"];
38
21
  var DEFAULT_OPTIONS = Object.freeze({
@@ -65,12 +48,6 @@ var biniLogger = {
65
48
  );
66
49
  }
67
50
  };
68
- function getDeno() {
69
- return globalThis.Deno;
70
- }
71
- function hasProcessEnv() {
72
- return typeof process !== "undefined" && !!process.env;
73
- }
74
51
  function defer(fn) {
75
52
  if (typeof setImmediate !== "undefined") {
76
53
  setImmediate(fn);
@@ -78,95 +55,63 @@ function defer(fn) {
78
55
  Promise.resolve().then(fn);
79
56
  }
80
57
  }
81
- function getEnv(key) {
82
- if (envCache.has(key)) return envCache.get(key);
83
- const deno = getDeno();
84
- if (deno) {
58
+ var _honoContext = null;
59
+ function setContext(c) {
60
+ _honoContext = c;
61
+ }
62
+ function clearContext() {
63
+ _honoContext = null;
64
+ }
65
+ function getEnv(c, key) {
66
+ const resolvedKey = typeof c === "string" ? c : key;
67
+ const resolvedCtx = typeof c === "string" ? null : c;
68
+ const ctx = resolvedCtx ?? _honoContext;
69
+ if (ctx) {
85
70
  try {
86
- const value = deno.env.get(key);
87
- if (value !== void 0) {
88
- envCache.set(key, value);
89
- return value;
90
- }
71
+ const honoEnvs = adapter.env(ctx);
72
+ const value = honoEnvs[resolvedKey];
73
+ if (value !== void 0) return value;
91
74
  } catch {
92
75
  }
93
76
  }
94
- if (hasProcessEnv()) {
95
- const value = process.env[key];
96
- if (value !== void 0) {
97
- envCache.set(key, value);
98
- return value;
99
- }
100
- }
101
- try {
102
- const metaEnv = undefined;
103
- if (metaEnv) {
104
- for (const candidate of [key, `BINI_${key}`, `VITE_${key}`]) {
105
- if (metaEnv[candidate] !== void 0) {
106
- envCache.set(key, metaEnv[candidate]);
107
- return metaEnv[candidate];
108
- }
109
- }
110
- }
111
- } catch {
77
+ if (envCache.has(resolvedKey)) return envCache.get(resolvedKey);
78
+ if (typeof process !== "undefined" && process.env) {
79
+ const value = process.env[resolvedKey];
80
+ envCache.set(resolvedKey, value);
81
+ return value;
112
82
  }
113
- envCache.set(key, void 0);
83
+ envCache.set(resolvedKey, void 0);
114
84
  return void 0;
115
85
  }
116
- function requireEnv(key) {
117
- const val = getEnv(key);
86
+ function requireEnv(c, key) {
87
+ const resolvedKey = typeof c === "string" ? c : key;
88
+ const val = getEnv(c, resolvedKey);
118
89
  if (val === void 0) {
119
90
  biniLogger.error(
120
- `Missing required environment variable: "${key}"
121
- ${"\x1B[2m" /* DIM */}\u2192 In development: add it to your .env file.${"\x1B[0m" /* RESET */}
91
+ `Missing required environment variable: "${resolvedKey}"
92
+ ${"\x1B[2m" /* DIM */}\u2192 In development: set it in your platform's env config.${"\x1B[0m" /* RESET */}
122
93
  ${"\x1B[2m" /* DIM */}\u2192 In production: set it in your hosting dashboard.${"\x1B[0m" /* RESET */}`
123
94
  );
124
- throw new Error(`[bini-env] Missing required environment variable: "${key}"`);
95
+ throw new Error(`[bini-env] Missing required environment variable: "${resolvedKey}"`);
125
96
  }
126
97
  return val;
127
98
  }
128
- var _envLoaded = false;
129
- var _loadPromise = null;
130
- async function loadEnv(projectRoot) {
131
- if (_envLoaded) return;
132
- if (_loadPromise) return _loadPromise;
133
- _loadPromise = (async () => {
134
- try {
135
- if (getDeno()) return;
136
- if (!hasProcessEnv()) return;
137
- const root = projectRoot ?? process.cwd();
138
- const nodeEnv = process.env.NODE_ENV ?? "production";
139
- const envFiles = [
140
- ".env",
141
- `.env.${nodeEnv}`,
142
- `.env.${nodeEnv}.local`,
143
- ".env.local"
144
- ];
145
- const dotenv = await import('dotenv');
146
- for (const file of envFiles) {
147
- const filePath = path__default.default.join(root, file);
148
- try {
149
- await fs__default.default.promises.access(filePath, fs__default.default.constants.R_OK);
150
- dotenv.config({ path: filePath, override: true });
151
- } catch {
152
- }
153
- }
154
- envCache.clear();
155
- _envLoaded = true;
156
- } catch (error) {
157
- biniLogger.error("Failed to load .env file", error);
158
- } finally {
159
- _loadPromise = null;
160
- }
161
- })();
162
- return _loadPromise;
163
- }
164
99
  var _envFilesCache = null;
165
100
  var _cacheKey = "";
166
- function detectEnvFiles(projectRoot = process.cwd()) {
101
+ function detectEnvFiles(projectRoot) {
102
+ if (!isNodeLike()) return [];
103
+ const root = projectRoot ?? process.cwd();
167
104
  const nodeEnv = process.env.NODE_ENV ?? "production";
168
- const cacheKey = `${projectRoot}:${nodeEnv}`;
105
+ const cacheKey = `${root}:${nodeEnv}`;
169
106
  if (_envFilesCache && _cacheKey === cacheKey) return _envFilesCache;
107
+ let fsSync;
108
+ let pathMod;
109
+ try {
110
+ fsSync = __require("fs");
111
+ pathMod = __require("path");
112
+ } catch {
113
+ return [];
114
+ }
170
115
  const candidates = [
171
116
  ".env.local",
172
117
  `.env.${nodeEnv}.local`,
@@ -176,8 +121,8 @@ function detectEnvFiles(projectRoot = process.cwd()) {
176
121
  const found = [];
177
122
  for (const file of candidates) {
178
123
  try {
179
- const filePath = path__default.default.join(projectRoot, file);
180
- if (fs__default.default.existsSync(filePath)) found.push({ name: file, path: filePath });
124
+ const filePath = pathMod.join(root, file);
125
+ if (fsSync.existsSync(filePath)) found.push({ name: file, path: filePath });
181
126
  } catch {
182
127
  }
183
128
  }
@@ -186,7 +131,9 @@ function detectEnvFiles(projectRoot = process.cwd()) {
186
131
  return found;
187
132
  }
188
133
  function clearLine() {
189
- if (process.stdout.isTTY) process.stdout.write("\x1B[2K\r");
134
+ if (typeof process !== "undefined" && process.stdout?.isTTY) {
135
+ process.stdout.write("\x1B[2K\r");
136
+ }
190
137
  }
191
138
  function printResolvedUrls(urls) {
192
139
  if (!urls) return;
@@ -244,24 +191,31 @@ function biniEnv(options = {}) {
244
191
  resolvedConfig = cfg;
245
192
  },
246
193
  configureServer(server) {
247
- const triggerLoad = () => void loadEnv(getRoot());
248
- if (server.httpServer) {
249
- server.httpServer.once("listening", triggerLoad);
250
- } else {
251
- defer(triggerLoad);
252
- }
194
+ defer(() => envCache.clear());
195
+ const envGlob = `${getRoot()}/.env*`;
196
+ server.watcher.add(envGlob);
197
+ const onEnvChange = (filePath) => {
198
+ if (/\.(swp|swo|bak|tmp)$|~$/.test(filePath)) return;
199
+ biniLogger.info(
200
+ `env file ${filePath.replace(getRoot() + "/", "")} changed \u2014 restarting server`
201
+ );
202
+ envCache.clear();
203
+ _envFilesCache = null;
204
+ void server.restart();
205
+ };
206
+ server.watcher.on("add", onEnvChange);
207
+ server.watcher.on("change", onEnvChange);
208
+ server.httpServer?.once("close", () => {
209
+ server.watcher.off("add", onEnvChange);
210
+ server.watcher.off("change", onEnvChange);
211
+ });
253
212
  if (clearViteHeader || logo !== BINI_LOGO) {
254
213
  patchPrintUrls(server, "dev", logo, clearViteHeader, getRoot, true);
255
214
  }
256
215
  },
257
216
  configurePreviewServer(server) {
258
217
  if (loadInPreview) {
259
- const triggerLoad = () => void loadEnv(getRoot());
260
- if (server.httpServer) {
261
- server.httpServer.once("listening", triggerLoad);
262
- } else {
263
- defer(triggerLoad);
264
- }
218
+ defer(() => envCache.clear());
265
219
  }
266
220
  if (clearViteHeader || logo !== BINI_LOGO) {
267
221
  patchPrintUrls(server, "preview", logo, clearViteHeader, getRoot, loadInPreview);
@@ -272,10 +226,10 @@ function biniEnv(options = {}) {
272
226
 
273
227
  exports.biniEnv = biniEnv;
274
228
  exports.biniLogger = biniLogger;
229
+ exports.clearContext = clearContext;
275
230
  exports.detectEnvFiles = detectEnvFiles;
276
231
  exports.getEnv = getEnv;
277
- exports.loadEnv = loadEnv;
278
232
  exports.requireEnv = requireEnv;
279
- exports.suppressDotenvLogsGlobally = suppressDotenvLogsGlobally;
233
+ exports.setContext = setContext;
280
234
  //# sourceMappingURL=index.js.map
281
235
  //# sourceMappingURL=index.js.map
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, PreviewServer, ResolvedConfig, UserConfig, ViteDevServer } from 'vite';\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 (typeof process !== 'undefined' && process.env && !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 (typeof process !== 'undefined' && process.env) {\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\n// suppressDotenvLogs intentionally omitted — it is deprecated and ignored\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 Used for messages emitted outside plugin context (loadEnv, requireEnv,\n standalone getEnv calls) where resolvedConfig.logger is not yet available.\n\n Format mirrors Vite exactly:\n info → 12:00:00 [bini-env] … cyan bold prefix\n warn → 12:00:00 (!) [bini-env] … yellow bold, Vite's (!) convention\n error → 12:00:00 [bini-env] error … red bold, optional dim detail line\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\nfunction hasProcessEnv(): boolean {\n return typeof process !== 'undefined' && !!process.env;\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\n if (hasProcessEnv()) {\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 - Idempotent: repeated awaits are safe; concurrent calls share one promise.\n - A failed load resets _envLoaded so a retry is possible (e.g. transient\n file-access race on startup).\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 if (getDeno()) return; // Deno — env already available via Deno.env\n if (!hasProcessEnv()) 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 const dotenv = await import('dotenv');\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 // Surface all load failures — silent swallowing hides misconfigured\n // deployments that are impossible to debug after the fact.\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 Cache key includes both root and NODE_ENV so changes in either invalidate.\n ========================================================================== */\n\nlet _envFilesCache: DetectedEnvFile[] | null = null;\nlet _cacheKey = '';\n\nexport function detectEnvFiles(projectRoot: string = process.cwd()): DetectedEnvFile[] {\n const nodeEnv = process.env.NODE_ENV ?? 'production';\n const cacheKey = `${projectRoot}:${nodeEnv}`;\n if (_envFilesCache && _cacheKey === cacheKey) return _envFilesCache;\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 = path.join(projectRoot, file);\n if (fs.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 (process.stdout.isTTY) process.stdout.write('\\x1b[2K\\r');\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\n/**\n * Patches server.printUrls to emit the Bini.js header and detected env files,\n * then delegates to the original printUrls or our own URL renderer depending\n * on whether clearViteHeader is enabled.\n * Guards against double-invocation with the `started` flag.\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 // Trigger env load once the HTTP server is up, or defer if middleware-only\n const triggerLoad = () => void loadEnv(getRoot());\n if (server.httpServer) {\n server.httpServer.once('listening', triggerLoad);\n } else {\n defer(triggerLoad);\n }\n\n // Only patch printUrls when we actually need to change the output\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';"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":["env"],"mappings":"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","file":"index.js","sourcesContent":["// bini-env/src/index.ts\nimport { env } from 'hono/adapter';\nimport type { Plugin, PreviewServer, ResolvedConfig, UserConfig, ViteDevServer } from 'vite';\n\n/* ==========================================================================\n Runtime detection — used by Vite plugin hooks only\n ========================================================================== */\n\nfunction isNodeLike(): boolean {\n return (\n typeof process !== 'undefined' &&\n !!process.env &&\n typeof process.versions === 'object' &&\n (typeof process.versions.node === 'string' ||\n typeof (process.versions as Record<string, unknown>).bun === 'string')\n );\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\n ========================================================================== */\n\nif (isNodeLike() && !process.env.NODE_ENV) {\n process.env.NODE_ENV = 'production';\n}\n\n/* ==========================================================================\n HonoContext duck type\n\n We intentionally do NOT import Context<E,P,I> from hono because Hono 4.12\n added a [GET_MATCH_RESULT] symbol to HonoRequest, making every\n narrowly-typed Context (e.g. Context<BlankEnv, \"/chat\", BlankInput>)\n structurally incompatible with Context<any, any, any>. A minimal duck type\n that only requires what hono/adapter's env() accesses at runtime sidesteps\n the symbol variance entirely. Consumers cast with `c as any` once at the\n call site; the single `env(ctx as any)` below is the only unsafe cast in\n the entire package.\n ========================================================================== */\n\n/** Minimal shape accepted by getEnv / requireEnv. Satisfied by any Hono Context. */\nexport type HonoContext = { env: unknown } & Record<string, unknown>;\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}\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 Required<BiniEnvPluginOptions>);\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\n// Build-time only cache — never used for request-scoped Hono env() results\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 Vite plugin helper\n ========================================================================== */\n\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 Module-level Hono context store\n\n Lets getEnv / requireEnv work without an explicit `c` argument at every\n call site. Register once in a global middleware:\n\n app.use('*', (c, next) => { setContext(c as any); return next(); });\n ========================================================================== */\n\nlet _honoContext: HonoContext | null = null;\n\nexport function setContext(c: HonoContext): void {\n _honoContext = c;\n}\n\nexport function clearContext(): void {\n _honoContext = null;\n}\n\n/* ==========================================================================\n getEnv\n\n Resolution order:\n 1. Explicit Hono Context (c param) — request-scoped, never cached\n 2. Stored Hono Context (setContext) — request-scoped, never cached\n 3. process.env (build-time / Vite plugin hooks — no c available)\n\n Usage:\n getEnv(c as any, 'KEY') — inside a Hono route / middleware\n getEnv('KEY') — outside request context (build-time)\n ========================================================================== */\n\nexport function getEnv(c: HonoContext | string, key?: string): string | undefined {\n const resolvedKey = typeof c === 'string' ? c : key!;\n const resolvedCtx = typeof c === 'string' ? null : c;\n\n // 1 & 2. Hono env() — covers all runtimes: CF Workers, Node, Bun, Deno, Edge\n const ctx = resolvedCtx ?? _honoContext;\n if (ctx) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const honoEnvs = env(ctx as any) as Record<string, string | undefined>;\n const value = honoEnvs[resolvedKey];\n if (value !== undefined) return value; // never cache — request-scoped\n } catch { /* context binding unavailable — fall through */ }\n }\n\n // 3. process.env — build-time only (Vite plugin hooks run outside any request)\n if (envCache.has(resolvedKey)) return envCache.get(resolvedKey);\n\n if (typeof process !== 'undefined' && process.env) {\n const value = process.env[resolvedKey];\n envCache.set(resolvedKey, value);\n return value;\n }\n\n envCache.set(resolvedKey, undefined);\n return undefined;\n}\n\n/* ==========================================================================\n requireEnv\n ========================================================================== */\n\nexport function requireEnv(c: HonoContext | string, key?: string): string {\n const resolvedKey = typeof c === 'string' ? c : key!;\n const val = getEnv(c, resolvedKey);\n if (val === undefined) {\n biniLogger.error(\n `Missing required environment variable: \"${resolvedKey}\"\\n` +\n ` ${COLORS.DIM}→ In development: set it in your platform's env config.${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: \"${resolvedKey}\"`);\n }\n return val;\n}\n\n/* ==========================================================================\n detectEnvFiles\n Node-only — used by the Vite plugin at build/dev time, never on edge.\n ========================================================================== */\n\nlet _envFilesCache: DetectedEnvFile[] | null = null;\nlet _cacheKey = '';\n\nexport function detectEnvFiles(projectRoot?: string): DetectedEnvFile[] {\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 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 defer(() => envCache.clear());\n\n const envGlob = `${getRoot()}/.env*`;\n server.watcher.add(envGlob);\n\n const onEnvChange = (filePath: string) => {\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 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 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 defer(() => envCache.clear());\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';\nexport type { Context } from 'hono';"]}
package/dist/index.mjs CHANGED
@@ -1,31 +1,19 @@
1
- import fs from 'fs';
2
- import path from 'path';
1
+ import { env } from 'hono/adapter';
3
2
 
4
- // src/index.ts
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
+ });
9
+ function isNodeLike() {
10
+ return typeof process !== "undefined" && !!process.env && typeof process.versions === "object" && (typeof process.versions.node === "string" || typeof process.versions.bun === "string");
11
+ }
5
12
  var originalConsoleLog = console.log.bind(console);
6
13
  var originalConsoleError = console.error.bind(console);
7
- if (typeof process !== "undefined" && process.env && !process.env.NODE_ENV) {
14
+ if (isNodeLike() && !process.env.NODE_ENV) {
8
15
  process.env.NODE_ENV = "production";
9
16
  }
10
- var _suppressionApplied = false;
11
- function suppressDotenvLogsGlobally() {
12
- if (_suppressionApplied) return;
13
- _suppressionApplied = true;
14
- if (typeof process !== "undefined" && process.env) {
15
- process.env.DOTENV_QUIET = "true";
16
- }
17
- const isDotenvNoise = (...args) => {
18
- const msg = args.join(" ");
19
- return msg.includes("[dotenv@") || msg.includes("injected env") || msg.includes("injecting env");
20
- };
21
- console.log = (...args) => {
22
- if (!isDotenvNoise(...args)) originalConsoleLog(...args);
23
- };
24
- console.error = (...args) => {
25
- if (!isDotenvNoise(...args)) originalConsoleError(...args);
26
- };
27
- }
28
- suppressDotenvLogsGlobally();
29
17
  var BINI_LOGO = "\xDF";
30
18
  var DEFAULT_ENV_PREFIX = ["BINI_", "VITE_"];
31
19
  var DEFAULT_OPTIONS = Object.freeze({
@@ -58,12 +46,6 @@ var biniLogger = {
58
46
  );
59
47
  }
60
48
  };
61
- function getDeno() {
62
- return globalThis.Deno;
63
- }
64
- function hasProcessEnv() {
65
- return typeof process !== "undefined" && !!process.env;
66
- }
67
49
  function defer(fn) {
68
50
  if (typeof setImmediate !== "undefined") {
69
51
  setImmediate(fn);
@@ -71,95 +53,63 @@ function defer(fn) {
71
53
  Promise.resolve().then(fn);
72
54
  }
73
55
  }
74
- function getEnv(key) {
75
- if (envCache.has(key)) return envCache.get(key);
76
- const deno = getDeno();
77
- if (deno) {
56
+ var _honoContext = null;
57
+ function setContext(c) {
58
+ _honoContext = c;
59
+ }
60
+ function clearContext() {
61
+ _honoContext = null;
62
+ }
63
+ function getEnv(c, key) {
64
+ const resolvedKey = typeof c === "string" ? c : key;
65
+ const resolvedCtx = typeof c === "string" ? null : c;
66
+ const ctx = resolvedCtx ?? _honoContext;
67
+ if (ctx) {
78
68
  try {
79
- const value = deno.env.get(key);
80
- if (value !== void 0) {
81
- envCache.set(key, value);
82
- return value;
83
- }
69
+ const honoEnvs = env(ctx);
70
+ const value = honoEnvs[resolvedKey];
71
+ if (value !== void 0) return value;
84
72
  } catch {
85
73
  }
86
74
  }
87
- if (hasProcessEnv()) {
88
- const value = process.env[key];
89
- if (value !== void 0) {
90
- envCache.set(key, value);
91
- return value;
92
- }
93
- }
94
- try {
95
- const metaEnv = import.meta.env;
96
- if (metaEnv) {
97
- for (const candidate of [key, `BINI_${key}`, `VITE_${key}`]) {
98
- if (metaEnv[candidate] !== void 0) {
99
- envCache.set(key, metaEnv[candidate]);
100
- return metaEnv[candidate];
101
- }
102
- }
103
- }
104
- } catch {
75
+ if (envCache.has(resolvedKey)) return envCache.get(resolvedKey);
76
+ if (typeof process !== "undefined" && process.env) {
77
+ const value = process.env[resolvedKey];
78
+ envCache.set(resolvedKey, value);
79
+ return value;
105
80
  }
106
- envCache.set(key, void 0);
81
+ envCache.set(resolvedKey, void 0);
107
82
  return void 0;
108
83
  }
109
- function requireEnv(key) {
110
- const val = getEnv(key);
84
+ function requireEnv(c, key) {
85
+ const resolvedKey = typeof c === "string" ? c : key;
86
+ const val = getEnv(c, resolvedKey);
111
87
  if (val === void 0) {
112
88
  biniLogger.error(
113
- `Missing required environment variable: "${key}"
114
- ${"\x1B[2m" /* DIM */}\u2192 In development: add it to your .env file.${"\x1B[0m" /* RESET */}
89
+ `Missing required environment variable: "${resolvedKey}"
90
+ ${"\x1B[2m" /* DIM */}\u2192 In development: set it in your platform's env config.${"\x1B[0m" /* RESET */}
115
91
  ${"\x1B[2m" /* DIM */}\u2192 In production: set it in your hosting dashboard.${"\x1B[0m" /* RESET */}`
116
92
  );
117
- throw new Error(`[bini-env] Missing required environment variable: "${key}"`);
93
+ throw new Error(`[bini-env] Missing required environment variable: "${resolvedKey}"`);
118
94
  }
119
95
  return val;
120
96
  }
121
- var _envLoaded = false;
122
- var _loadPromise = null;
123
- async function loadEnv(projectRoot) {
124
- if (_envLoaded) return;
125
- if (_loadPromise) return _loadPromise;
126
- _loadPromise = (async () => {
127
- try {
128
- if (getDeno()) return;
129
- if (!hasProcessEnv()) return;
130
- const root = projectRoot ?? process.cwd();
131
- const nodeEnv = process.env.NODE_ENV ?? "production";
132
- const envFiles = [
133
- ".env",
134
- `.env.${nodeEnv}`,
135
- `.env.${nodeEnv}.local`,
136
- ".env.local"
137
- ];
138
- const dotenv = await import('dotenv');
139
- for (const file of envFiles) {
140
- const filePath = path.join(root, file);
141
- try {
142
- await fs.promises.access(filePath, fs.constants.R_OK);
143
- dotenv.config({ path: filePath, override: true });
144
- } catch {
145
- }
146
- }
147
- envCache.clear();
148
- _envLoaded = true;
149
- } catch (error) {
150
- biniLogger.error("Failed to load .env file", error);
151
- } finally {
152
- _loadPromise = null;
153
- }
154
- })();
155
- return _loadPromise;
156
- }
157
97
  var _envFilesCache = null;
158
98
  var _cacheKey = "";
159
- function detectEnvFiles(projectRoot = process.cwd()) {
99
+ function detectEnvFiles(projectRoot) {
100
+ if (!isNodeLike()) return [];
101
+ const root = projectRoot ?? process.cwd();
160
102
  const nodeEnv = process.env.NODE_ENV ?? "production";
161
- const cacheKey = `${projectRoot}:${nodeEnv}`;
103
+ const cacheKey = `${root}:${nodeEnv}`;
162
104
  if (_envFilesCache && _cacheKey === cacheKey) return _envFilesCache;
105
+ let fsSync;
106
+ let pathMod;
107
+ try {
108
+ fsSync = __require("fs");
109
+ pathMod = __require("path");
110
+ } catch {
111
+ return [];
112
+ }
163
113
  const candidates = [
164
114
  ".env.local",
165
115
  `.env.${nodeEnv}.local`,
@@ -169,8 +119,8 @@ function detectEnvFiles(projectRoot = process.cwd()) {
169
119
  const found = [];
170
120
  for (const file of candidates) {
171
121
  try {
172
- const filePath = path.join(projectRoot, file);
173
- if (fs.existsSync(filePath)) found.push({ name: file, path: filePath });
122
+ const filePath = pathMod.join(root, file);
123
+ if (fsSync.existsSync(filePath)) found.push({ name: file, path: filePath });
174
124
  } catch {
175
125
  }
176
126
  }
@@ -179,7 +129,9 @@ function detectEnvFiles(projectRoot = process.cwd()) {
179
129
  return found;
180
130
  }
181
131
  function clearLine() {
182
- if (process.stdout.isTTY) process.stdout.write("\x1B[2K\r");
132
+ if (typeof process !== "undefined" && process.stdout?.isTTY) {
133
+ process.stdout.write("\x1B[2K\r");
134
+ }
183
135
  }
184
136
  function printResolvedUrls(urls) {
185
137
  if (!urls) return;
@@ -237,24 +189,31 @@ function biniEnv(options = {}) {
237
189
  resolvedConfig = cfg;
238
190
  },
239
191
  configureServer(server) {
240
- const triggerLoad = () => void loadEnv(getRoot());
241
- if (server.httpServer) {
242
- server.httpServer.once("listening", triggerLoad);
243
- } else {
244
- defer(triggerLoad);
245
- }
192
+ defer(() => envCache.clear());
193
+ const envGlob = `${getRoot()}/.env*`;
194
+ server.watcher.add(envGlob);
195
+ const onEnvChange = (filePath) => {
196
+ if (/\.(swp|swo|bak|tmp)$|~$/.test(filePath)) return;
197
+ biniLogger.info(
198
+ `env file ${filePath.replace(getRoot() + "/", "")} changed \u2014 restarting server`
199
+ );
200
+ envCache.clear();
201
+ _envFilesCache = null;
202
+ void server.restart();
203
+ };
204
+ server.watcher.on("add", onEnvChange);
205
+ server.watcher.on("change", onEnvChange);
206
+ server.httpServer?.once("close", () => {
207
+ server.watcher.off("add", onEnvChange);
208
+ server.watcher.off("change", onEnvChange);
209
+ });
246
210
  if (clearViteHeader || logo !== BINI_LOGO) {
247
211
  patchPrintUrls(server, "dev", logo, clearViteHeader, getRoot, true);
248
212
  }
249
213
  },
250
214
  configurePreviewServer(server) {
251
215
  if (loadInPreview) {
252
- const triggerLoad = () => void loadEnv(getRoot());
253
- if (server.httpServer) {
254
- server.httpServer.once("listening", triggerLoad);
255
- } else {
256
- defer(triggerLoad);
257
- }
216
+ defer(() => envCache.clear());
258
217
  }
259
218
  if (clearViteHeader || logo !== BINI_LOGO) {
260
219
  patchPrintUrls(server, "preview", logo, clearViteHeader, getRoot, loadInPreview);
@@ -263,6 +222,6 @@ function biniEnv(options = {}) {
263
222
  };
264
223
  }
265
224
 
266
- export { biniEnv, biniLogger, detectEnvFiles, getEnv, loadEnv, requireEnv, suppressDotenvLogsGlobally };
225
+ export { biniEnv, biniLogger, clearContext, detectEnvFiles, getEnv, requireEnv, setContext };
267
226
  //# sourceMappingURL=index.mjs.map
268
227
  //# sourceMappingURL=index.mjs.map