bini-env 1.0.6 → 1.0.8

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,40 +1,96 @@
1
- import fs from 'fs';
2
- import path from 'path';
1
+ 'use strict';
2
+
3
+ var fs = require('fs');
4
+ var path = require('path');
5
+
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);
3
10
 
4
11
  // src/index.ts
12
+ if (typeof process !== "undefined" && process.env && !process.env.NODE_ENV) {
13
+ process.env.NODE_ENV = "production";
14
+ }
15
+ function suppressDotenvLogsGlobally() {
16
+ if (typeof process !== "undefined" && process.env) {
17
+ process.env.DOTENV_QUIET = "true";
18
+ }
19
+ const originalLog = console.log;
20
+ console.log = (...args) => {
21
+ const message = args.join(" ");
22
+ if (message.includes("[dotenv@") && message.includes("injecting env")) {
23
+ return;
24
+ }
25
+ originalLog(...args);
26
+ };
27
+ const originalError = console.error;
28
+ console.error = (...args) => {
29
+ const message = args.join(" ");
30
+ if (message.includes("[dotenv@") && message.includes("injecting env")) {
31
+ return;
32
+ }
33
+ originalError(...args);
34
+ };
35
+ }
36
+ suppressDotenvLogsGlobally();
5
37
  var BINI_LOGO = "\xDF";
6
- var DEFAULT_ENV_PREFIX = "BINI_";
7
- var DEFAULT_OPTIONS = {
38
+ var DEFAULT_ENV_PREFIX = ["BINI_", "VITE_"];
39
+ var DEFAULT_OPTIONS = Object.freeze({
8
40
  enabled: true,
9
41
  clearViteHeader: true,
10
42
  logo: BINI_LOGO,
11
- envPrefix: DEFAULT_ENV_PREFIX
12
- };
13
- var COLORS = {
14
- CYAN: "\x1B[36m",
15
- RESET: "\x1B[0m",
16
- GREEN: "\x1B[32m"
17
- };
43
+ envPrefix: DEFAULT_ENV_PREFIX,
44
+ loadInPreview: true,
45
+ suppressDotenvLogs: true
46
+ });
47
+ var envCache = /* @__PURE__ */ new Map();
48
+ var originalConsoleLog = console.log;
49
+ var originalConsoleError = console.error;
18
50
  function getEnv(key) {
51
+ if (envCache.has(key)) {
52
+ return envCache.get(key);
53
+ }
54
+ let value;
19
55
  const deno = globalThis.Deno;
20
56
  if (deno) {
21
57
  try {
22
- const val = deno.env.get(key);
23
- if (val !== void 0) return val;
58
+ value = deno.env.get(key);
59
+ if (value !== void 0) {
60
+ envCache.set(key, value);
61
+ return value;
62
+ }
24
63
  } catch {
25
64
  }
26
65
  }
27
66
  if (typeof process !== "undefined" && process.env) {
28
- if (process.env[key] !== void 0) return process.env[key];
67
+ value = process.env[key];
68
+ if (value !== void 0) {
69
+ envCache.set(key, value);
70
+ return value;
71
+ }
29
72
  }
30
73
  try {
31
- const metaEnv = import.meta.env;
74
+ const metaEnv = undefined;
32
75
  if (metaEnv) {
33
- if (metaEnv[key] !== void 0) return metaEnv[key];
34
- if (metaEnv[`BINI_${key}`] !== void 0) return metaEnv[`BINI_${key}`];
76
+ if (metaEnv[key] !== void 0) {
77
+ envCache.set(key, metaEnv[key]);
78
+ return metaEnv[key];
79
+ }
80
+ const biniKey = `BINI_${key}`;
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];
89
+ }
35
90
  }
36
91
  } catch {
37
92
  }
93
+ envCache.set(key, void 0);
38
94
  return void 0;
39
95
  }
40
96
  function requireEnv(key) {
@@ -49,35 +105,60 @@ function requireEnv(key) {
49
105
  return val;
50
106
  }
51
107
  var _envLoaded = false;
108
+ var _loadPromise = null;
52
109
  async function loadEnv(projectRoot) {
53
110
  if (_envLoaded) return;
54
- if (globalThis.Deno) {
55
- _envLoaded = true;
56
- return;
57
- }
58
- if (typeof process === "undefined" || !process.env) {
59
- _envLoaded = true;
60
- return;
61
- }
62
- if (process.env.NODE_ENV === "production") {
63
- _envLoaded = true;
64
- return;
65
- }
66
- try {
67
- const root = projectRoot ?? process.cwd();
68
- const envPath = path.join(root, ".env");
69
- if (!fs.existsSync(envPath)) {
111
+ if (_loadPromise) return _loadPromise;
112
+ _loadPromise = (async () => {
113
+ try {
114
+ if (globalThis.Deno) {
115
+ _envLoaded = true;
116
+ return;
117
+ }
118
+ if (typeof process === "undefined" || !process.env) {
119
+ _envLoaded = true;
120
+ return;
121
+ }
122
+ const root = projectRoot ?? process.cwd();
123
+ const envFiles = [
124
+ ".env",
125
+ `.env.${process.env.NODE_ENV}`,
126
+ `.env.${process.env.NODE_ENV}.local`,
127
+ ".env.local"
128
+ ];
129
+ suppressDotenvLogsGlobally();
130
+ const dotenv = await import('dotenv');
131
+ for (const envFile of envFiles) {
132
+ const envPath = path__default.default.join(root, envFile);
133
+ try {
134
+ await fs__default.default.promises.access(envPath, fs__default.default.constants.R_OK);
135
+ dotenv.config({
136
+ path: envPath,
137
+ override: true,
138
+ quiet: true
139
+ });
140
+ } catch {
141
+ }
142
+ }
143
+ envCache.clear();
144
+ } catch (error) {
145
+ if (process.env.NODE_ENV !== "production") {
146
+ originalConsoleError("[bini-env] Warning: Failed to load .env file:", error);
147
+ }
148
+ } finally {
70
149
  _envLoaded = true;
71
- return;
150
+ _loadPromise = null;
72
151
  }
73
- const dotenv = await import('dotenv');
74
- dotenv.config({ path: envPath });
75
- } catch {
76
- }
77
- _envLoaded = true;
152
+ })();
153
+ return _loadPromise;
78
154
  }
155
+ var _envFilesCache = null;
156
+ var _cachedRoot = "";
79
157
  function detectEnvFiles(projectRoot = process.cwd()) {
80
- const nodeEnv = process.env.NODE_ENV ?? "development";
158
+ if (_envFilesCache && _cachedRoot === projectRoot) {
159
+ return _envFilesCache;
160
+ }
161
+ const nodeEnv = process.env.NODE_ENV ?? "production";
81
162
  const candidates = [
82
163
  ".env.local",
83
164
  `.env.${nodeEnv}.local`,
@@ -86,33 +167,48 @@ function detectEnvFiles(projectRoot = process.cwd()) {
86
167
  ];
87
168
  const found = [];
88
169
  for (const file of candidates) {
89
- const filePath = path.join(projectRoot, file);
90
- if (fs.existsSync(filePath)) {
91
- found.push({ name: file, path: filePath });
170
+ const filePath = path__default.default.join(projectRoot, file);
171
+ try {
172
+ if (fs__default.default.existsSync(filePath)) {
173
+ found.push({ name: file, path: filePath });
174
+ }
175
+ } catch {
92
176
  }
93
177
  }
178
+ _envFilesCache = found;
179
+ _cachedRoot = projectRoot;
94
180
  return found;
95
181
  }
96
182
  function clearLine() {
97
- process.stdout.write("\x1B[2K\r");
183
+ if (process.stdout.isTTY) {
184
+ process.stdout.write("\x1B[2K\r");
185
+ }
98
186
  }
99
187
  function printResolvedUrls(urls) {
100
188
  if (!urls) return;
101
- if (urls.local.length > 0)
102
- console.log(` ${COLORS.GREEN}\u279C${COLORS.RESET} Local: ${COLORS.CYAN}${urls.local[0]}${COLORS.RESET}`);
103
- if (urls.network.length > 0)
104
- console.log(` ${COLORS.GREEN}\u279C${COLORS.RESET} Network: ${COLORS.CYAN}${urls.network[0]}${COLORS.RESET}`);
189
+ if (urls.local.length > 0) {
190
+ originalConsoleLog(
191
+ ` ${"\x1B[32m" /* GREEN */}\u279C${"\x1B[0m" /* RESET */} Local: ${"\x1B[36m" /* CYAN */}${urls.local[0]}${"\x1B[0m" /* RESET */}`
192
+ );
193
+ }
194
+ if (urls.network.length > 0) {
195
+ originalConsoleLog(
196
+ ` ${"\x1B[32m" /* GREEN */}\u279C${"\x1B[0m" /* RESET */} Network: ${"\x1B[36m" /* CYAN */}${urls.network[0]}${"\x1B[0m" /* RESET */}`
197
+ );
198
+ }
105
199
  }
106
200
  function biniEnv(options = {}) {
107
- const resolvedOptions = Object.freeze({ ...DEFAULT_OPTIONS, ...options });
108
- const { enabled, clearViteHeader, logo, envPrefix } = resolvedOptions;
201
+ if (options.enabled === false) {
202
+ return { name: "vite-plugin-bini-env" };
203
+ }
204
+ const resolvedOptions = { ...DEFAULT_OPTIONS, ...options };
205
+ const { clearViteHeader, logo, envPrefix, loadInPreview, suppressDotenvLogs } = resolvedOptions;
109
206
  let resolvedConfig;
110
- let serverStarted = false;
111
- let previewStarted = false;
207
+ if (suppressDotenvLogs && typeof process !== "undefined") {
208
+ suppressDotenvLogsGlobally();
209
+ }
112
210
  return {
113
211
  name: "vite-plugin-bini-env",
114
- apply: "serve",
115
- // Set BINI_ as the env prefix so import.meta.env.BINI_* works in client code
116
212
  config() {
117
213
  return { envPrefix };
118
214
  },
@@ -120,61 +216,81 @@ function biniEnv(options = {}) {
120
216
  resolvedConfig = cfg;
121
217
  },
122
218
  configureServer(server) {
123
- if (!enabled) return;
219
+ const loadEnvTask = () => {
220
+ void loadEnv(resolvedConfig?.root ?? process.cwd());
221
+ };
124
222
  if (server.httpServer) {
125
- server.httpServer.once("listening", () => {
126
- void loadEnv(resolvedConfig?.root ?? process.cwd());
127
- });
223
+ server.httpServer.once("listening", loadEnvTask);
128
224
  } else {
129
- void loadEnv(resolvedConfig?.root ?? process.cwd());
225
+ setImmediate(loadEnvTask);
130
226
  }
227
+ let serverStarted = false;
131
228
  const originalPrintUrls = server.printUrls.bind(server);
132
- server.printUrls = () => {
133
- if (serverStarted) return;
134
- serverStarted = true;
135
- if (clearViteHeader) clearLine();
136
- console.log(`
137
- ${COLORS.CYAN}${logo} Bini.js${COLORS.RESET} (dev)`);
138
- const found = detectEnvFiles(resolvedConfig?.root);
139
- if (found.length > 0) {
140
- const envString = found.map((f) => f.name).join(", ");
141
- console.log(` ${COLORS.GREEN}\u279C${COLORS.RESET} Environments: ${envString}`);
142
- }
143
- if (!clearViteHeader) {
144
- originalPrintUrls();
145
- } else {
146
- printResolvedUrls(server.resolvedUrls);
147
- }
148
- };
229
+ if (clearViteHeader || logo !== BINI_LOGO) {
230
+ server.printUrls = () => {
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
+ };
248
+ }
149
249
  },
150
250
  configurePreviewServer(server) {
151
- if (!enabled) return;
152
- const originalPrintUrls = server.printUrls.bind(server);
153
- server.printUrls = () => {
154
- if (previewStarted) return;
155
- previewStarted = true;
156
- if (clearViteHeader) clearLine();
157
- console.log(`
158
- ${COLORS.CYAN}${logo} Bini.js${COLORS.RESET} (preview)`);
159
- const found = detectEnvFiles(resolvedConfig?.root);
160
- if (found.length > 0) {
161
- const envString = found.map((f) => f.name).join(", ");
162
- console.log(` ${COLORS.GREEN}\u279C${COLORS.RESET} Environments: ${envString}`);
163
- }
164
- if (!clearViteHeader) {
165
- originalPrintUrls();
251
+ if (loadInPreview) {
252
+ const loadEnvTask = () => {
253
+ void loadEnv(resolvedConfig?.root ?? process.cwd());
254
+ };
255
+ if (server.httpServer) {
256
+ server.httpServer.once("listening", loadEnvTask);
166
257
  } else {
167
- printResolvedUrls(server.resolvedUrls);
258
+ setImmediate(loadEnvTask);
168
259
  }
169
- };
170
- },
171
- buildEnd() {
172
- serverStarted = false;
173
- previewStarted = false;
260
+ }
261
+ let previewStarted = false;
262
+ const originalPrintUrls = server.printUrls.bind(server);
263
+ if (clearViteHeader || logo !== BINI_LOGO) {
264
+ server.printUrls = () => {
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
+ };
284
+ }
174
285
  }
175
286
  };
176
287
  }
177
288
 
178
- export { biniEnv, detectEnvFiles, getEnv, loadEnv, requireEnv };
289
+ exports.biniEnv = biniEnv;
290
+ exports.detectEnvFiles = detectEnvFiles;
291
+ exports.getEnv = getEnv;
292
+ exports.loadEnv = loadEnv;
293
+ exports.requireEnv = requireEnv;
294
+ exports.suppressDotenvLogsGlobally = suppressDotenvLogsGlobally;
179
295
  //# sourceMappingURL=index.js.map
180
296
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// src/index.ts\nimport fs from 'fs';\nimport path from 'path';\nimport type { Plugin, ResolvedConfig, UserConfig } from 'vite';\n\n/* ==========================================================================\n Global type declarations for cross-runtime compatibility\n ========================================================================== */\n\n// Deno runtime type — declared as an interface so we can safely cast\n// without relying on a global that TypeScript doesn't know about\ninterface DenoEnv {\n get(key: string): string | undefined;\n toObject(): Record<string, string>;\n}\ninterface DenoNamespace {\n env: DenoEnv;\n}\n\n// Vite augments ImportMeta with .env\n// Using triple-slash reference so it works both inside and outside Vite projects\n/// <reference types=\"vite/client\" />\n\n/* ==========================================================================\n Types\n ========================================================================== */\n\nexport interface BiniEnvPluginOptions {\n /**\n * Enable/disable the plugin\n * @default true\n */\n readonly enabled?: boolean;\n\n /**\n * Remove Vite's default header\n * @default true\n */\n readonly clearViteHeader?: boolean;\n\n /**\n * Custom logo/text to display\n * @default 'ß'\n */\n readonly logo?: string;\n\n /**\n * Override the env var prefix exposed to client code.\n * Defaults to 'BINI_' — so BINI_MY_VAR is accessible via import.meta.env.BINI_MY_VAR\n * Set to 'VITE_' to keep Vite's default behaviour.\n * @default 'BINI_'\n */\n readonly envPrefix?: string;\n}\n\nexport interface DetectedEnvFile {\n readonly name: string;\n readonly path: string;\n}\n\n/* ==========================================================================\n Constants\n ========================================================================== */\n\nconst BINI_LOGO = 'ß' as const;\nconst DEFAULT_ENV_PREFIX = 'BINI_' as const;\n\nconst DEFAULT_OPTIONS = {\n enabled: true,\n clearViteHeader: true,\n logo: BINI_LOGO,\n envPrefix: DEFAULT_ENV_PREFIX,\n} as const;\n\nconst COLORS = {\n CYAN: '\\x1b[36m',\n RESET: '\\x1b[0m',\n GREEN: '\\x1b[32m',\n} as const;\n\n/* ==========================================================================\n getEnv — Universal env var accessor\n Works in: Node.js, Deno (edge functions), Bun, Vite client\n ========================================================================== */\n\n/**\n * Read an environment variable in any runtime.\n *\n * Priority order:\n * 1. Deno.env — Netlify edge functions / Deno runtime\n * 2. process.env — Node.js / Bun / bini-server\n * 3. import.meta.env — Vite client (BINI_-prefixed vars)\n *\n * Usage in API routes:\n * import { getEnv } from 'bini-env';\n * const smtpUser = getEnv('SMTP_USER');\n */\nexport function getEnv(key: string): string | undefined {\n // 1. Deno runtime (Netlify edge functions)\n const deno = (globalThis as unknown as { Deno?: DenoNamespace }).Deno;\n if (deno) {\n try {\n const val = deno.env.get(key);\n if (val !== undefined) return val;\n } catch {\n // Deno env access denied — fall through\n }\n }\n\n // 2. Node.js / Bun / bini-server\n if (typeof process !== 'undefined' && process.env) {\n if (process.env[key] !== undefined) return process.env[key];\n }\n\n // 3. Vite injected (import.meta.env) — BINI_-prefixed client vars\n // Wrapped in try/catch because import.meta.env doesn't exist in Node/Deno\n try {\n const metaEnv = import.meta.env as Record<string, string | undefined> | undefined;\n if (metaEnv) {\n if (metaEnv[key] !== undefined) return metaEnv[key];\n // Try with BINI_ prefix automatically\n if (metaEnv[`BINI_${key}`] !== undefined) return metaEnv[`BINI_${key}`];\n }\n } catch {\n // import.meta.env not available in this runtime — ignore\n }\n\n return undefined;\n}\n\n/**\n * Read an environment variable and throw if it's missing or empty.\n * Use this for required secrets so you get a clear error at startup\n * instead of a cryptic crash later.\n *\n * Usage:\n * const smtpPass = requireEnv('SMTP_PASS');\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 — Auto dotenv loader for bini-router API routes (Node.js only)\n Called internally by the Vite plugin. Safe to call multiple times.\n ========================================================================== */\n\nlet _envLoaded = false;\n\n/**\n * Auto-load .env into process.env for Node.js API route contexts.\n *\n * Behaviour by environment:\n * - Deno (edge functions) → no-op, Deno/Netlify injects env natively\n * - NODE_ENV=production → no-op, host injects env vars automatically\n * - Node.js dev → loads .env via dotenv (dynamic import, safe for bundlers)\n *\n * Called automatically by bini-env Vite plugin. You should not need to call this manually.\n */\nexport async function loadEnv(projectRoot?: string): Promise<void> {\n // Already loaded — skip\n if (_envLoaded) return;\n\n // Deno runtime — env is handled natively, skip\n if ((globalThis as unknown as { Deno?: DenoNamespace }).Deno) {\n _envLoaded = true;\n return;\n }\n\n // Not in a Node-like runtime — skip\n if (typeof process === 'undefined' || !process.env) {\n _envLoaded = true;\n return;\n }\n\n // Production — host injects env vars, dotenv not needed\n if (process.env.NODE_ENV === 'production') {\n _envLoaded = true;\n return;\n }\n\n try {\n const root = projectRoot ?? process.cwd();\n const envPath = path.join(root, '.env');\n\n if (!fs.existsSync(envPath)) {\n _envLoaded = true;\n return;\n }\n\n // Dynamic import so Deno/edge bundlers never try to statically resolve dotenv\n const dotenv = await import('dotenv');\n dotenv.config({ path: envPath });\n } catch {\n // dotenv not installed or read failed — silently skip.\n // requireEnv() will surface clear errors if vars are missing when used.\n }\n\n _envLoaded = true;\n}\n\n/* ==========================================================================\n detectEnvFiles — used by the Vite plugin display\n ========================================================================== */\n\n/**\n * Detect which .env files exist in the project root, in Vite's priority order.\n */\nexport function detectEnvFiles(projectRoot: string = process.cwd()): DetectedEnvFile[] {\n const nodeEnv = process.env.NODE_ENV ?? 'development';\n\n const candidates = [\n '.env.local',\n `.env.${nodeEnv}.local`,\n `.env.${nodeEnv}`,\n '.env',\n ] as const;\n\n const found: DetectedEnvFile[] = [];\n\n for (const file of candidates) {\n const filePath = path.join(projectRoot, file);\n if (fs.existsSync(filePath)) {\n found.push({ name: file, path: filePath });\n }\n }\n\n return found;\n}\n\n/* ==========================================================================\n Vite plugin\n ========================================================================== */\n\nfunction clearLine(): void {\n process.stdout.write('\\x1b[2K\\r');\n}\n\nfunction printResolvedUrls(urls: { local: string[]; network: string[] } | null | undefined): void {\n if (!urls) return;\n if (urls.local.length > 0)\n console.log(` ${COLORS.GREEN}➜${COLORS.RESET} Local: ${COLORS.CYAN}${urls.local[0]}${COLORS.RESET}`);\n if (urls.network.length > 0)\n console.log(` ${COLORS.GREEN}➜${COLORS.RESET} Network: ${COLORS.CYAN}${urls.network[0]}${COLORS.RESET}`);\n}\n\n/**\n * Bini.js Vite plugin.\n *\n * What it does:\n * - Sets envPrefix to 'BINI_' so client code uses import.meta.env.BINI_MY_VAR\n * - Auto-loads .env for API routes in dev via loadEnv()\n * - Replaces Vite's startup output with the Bini.js branded header\n */\nexport function biniEnv(options: Readonly<BiniEnvPluginOptions> = {}): Plugin {\n const resolvedOptions = Object.freeze({ ...DEFAULT_OPTIONS, ...options });\n const { enabled, clearViteHeader, logo, envPrefix } = resolvedOptions;\n\n let resolvedConfig: ResolvedConfig;\n let serverStarted = false;\n let previewStarted = false;\n\n return {\n name: 'vite-plugin-bini-env',\n\n apply: 'serve',\n\n // Set BINI_ as the env prefix so import.meta.env.BINI_* works in client code\n config(): UserConfig {\n return { envPrefix };\n },\n\n configResolved(cfg: ResolvedConfig) {\n resolvedConfig = cfg;\n },\n\n configureServer(server) {\n if (!enabled) return;\n\n // Auto-load .env after server starts — guarantees resolvedConfig is available\n // Falls back to immediate call in middleware mode where httpServer is null\n if (server.httpServer) {\n server.httpServer.once('listening', () => {\n void loadEnv(resolvedConfig?.root ?? process.cwd());\n });\n } else {\n // Middleware mode — httpServer is null, call immediately\n void loadEnv(resolvedConfig?.root ?? process.cwd());\n }\n\n const originalPrintUrls = server.printUrls.bind(server);\n\n server.printUrls = () => {\n if (serverStarted) return;\n serverStarted = true;\n\n if (clearViteHeader) clearLine();\n console.log(`\\n ${COLORS.CYAN}${logo} Bini.js${COLORS.RESET} (dev)`);\n\n const found = detectEnvFiles(resolvedConfig?.root);\n if (found.length > 0) {\n const envString = found.map((f) => f.name).join(', ');\n console.log(` ${COLORS.GREEN}➜${COLORS.RESET} Environments: ${envString}`);\n }\n\n if (!clearViteHeader) {\n originalPrintUrls();\n } else {\n printResolvedUrls(server.resolvedUrls);\n }\n };\n },\n\n configurePreviewServer(server) {\n if (!enabled) return;\n\n const originalPrintUrls = server.printUrls.bind(server);\n\n server.printUrls = () => {\n if (previewStarted) return;\n previewStarted = true;\n\n if (clearViteHeader) clearLine();\n console.log(`\\n ${COLORS.CYAN}${logo} Bini.js${COLORS.RESET} (preview)`);\n\n const found = detectEnvFiles(resolvedConfig?.root);\n if (found.length > 0) {\n const envString = found.map((f) => f.name).join(', ');\n console.log(` ${COLORS.GREEN}➜${COLORS.RESET} Environments: ${envString}`);\n }\n\n if (!clearViteHeader) {\n originalPrintUrls();\n } else {\n printResolvedUrls(server.resolvedUrls);\n }\n };\n },\n\n buildEnd() {\n serverStarted = false;\n previewStarted = false;\n },\n };\n}\n\n// Named export: import { biniEnv } from 'bini-env'\nexport type { Plugin } from 'vite';"]}
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';"]}