bini-env 1.0.8 → 1.0.9

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.d.mts CHANGED
@@ -8,16 +8,22 @@ interface BiniEnvPluginOptions {
8
8
  readonly logo?: string;
9
9
  readonly envPrefix?: string | string[];
10
10
  readonly loadInPreview?: boolean;
11
+ /** @deprecated Suppression is always applied at module load; this option is ignored. */
11
12
  readonly suppressDotenvLogs?: boolean;
12
13
  }
13
14
  interface DetectedEnvFile {
14
15
  readonly name: string;
15
16
  readonly path: string;
16
17
  }
18
+ declare const biniLogger: {
19
+ readonly info: (msg: string) => void;
20
+ readonly warn: (msg: string) => void;
21
+ readonly error: (msg: string, err?: unknown) => void;
22
+ };
17
23
  declare function getEnv(key: string): string | undefined;
18
24
  declare function requireEnv(key: string): string;
19
25
  declare function loadEnv(projectRoot?: string): Promise<void>;
20
26
  declare function detectEnvFiles(projectRoot?: string): DetectedEnvFile[];
21
27
  declare function biniEnv(options?: Readonly<BiniEnvPluginOptions>): Plugin;
22
28
 
23
- export { type BiniEnvPluginOptions, type DetectedEnvFile, biniEnv, detectEnvFiles, getEnv, loadEnv, requireEnv, suppressDotenvLogsGlobally };
29
+ export { type BiniEnvPluginOptions, type DetectedEnvFile, biniEnv, biniLogger, detectEnvFiles, getEnv, loadEnv, requireEnv, suppressDotenvLogsGlobally };
package/dist/index.d.ts CHANGED
@@ -8,16 +8,22 @@ interface BiniEnvPluginOptions {
8
8
  readonly logo?: string;
9
9
  readonly envPrefix?: string | string[];
10
10
  readonly loadInPreview?: boolean;
11
+ /** @deprecated Suppression is always applied at module load; this option is ignored. */
11
12
  readonly suppressDotenvLogs?: boolean;
12
13
  }
13
14
  interface DetectedEnvFile {
14
15
  readonly name: string;
15
16
  readonly path: string;
16
17
  }
18
+ declare const biniLogger: {
19
+ readonly info: (msg: string) => void;
20
+ readonly warn: (msg: string) => void;
21
+ readonly error: (msg: string, err?: unknown) => void;
22
+ };
17
23
  declare function getEnv(key: string): string | undefined;
18
24
  declare function requireEnv(key: string): string;
19
25
  declare function loadEnv(projectRoot?: string): Promise<void>;
20
26
  declare function detectEnvFiles(projectRoot?: string): DetectedEnvFile[];
21
27
  declare function biniEnv(options?: Readonly<BiniEnvPluginOptions>): Plugin;
22
28
 
23
- export { type BiniEnvPluginOptions, type DetectedEnvFile, biniEnv, detectEnvFiles, getEnv, loadEnv, requireEnv, suppressDotenvLogsGlobally };
29
+ export { type BiniEnvPluginOptions, type DetectedEnvFile, biniEnv, biniLogger, detectEnvFiles, getEnv, loadEnv, requireEnv, suppressDotenvLogsGlobally };
package/dist/index.js CHANGED
@@ -9,28 +9,27 @@ var fs__default = /*#__PURE__*/_interopDefault(fs);
9
9
  var path__default = /*#__PURE__*/_interopDefault(path);
10
10
 
11
11
  // src/index.ts
12
+ var originalConsoleLog = console.log.bind(console);
13
+ var originalConsoleError = console.error.bind(console);
12
14
  if (typeof process !== "undefined" && process.env && !process.env.NODE_ENV) {
13
15
  process.env.NODE_ENV = "production";
14
16
  }
17
+ var _suppressionApplied = false;
15
18
  function suppressDotenvLogsGlobally() {
19
+ if (_suppressionApplied) return;
20
+ _suppressionApplied = true;
16
21
  if (typeof process !== "undefined" && process.env) {
17
22
  process.env.DOTENV_QUIET = "true";
18
23
  }
19
- const originalLog = console.log;
24
+ const isDotenvNoise = (...args) => {
25
+ const msg = args.join(" ");
26
+ return msg.includes("[dotenv@") || msg.includes("injected env") || msg.includes("injecting env");
27
+ };
20
28
  console.log = (...args) => {
21
- const message = args.join(" ");
22
- if (message.includes("[dotenv@") && message.includes("injecting env")) {
23
- return;
24
- }
25
- originalLog(...args);
29
+ if (!isDotenvNoise(...args)) originalConsoleLog(...args);
26
30
  };
27
- const originalError = console.error;
28
31
  console.error = (...args) => {
29
- const message = args.join(" ");
30
- if (message.includes("[dotenv@") && message.includes("injecting env")) {
31
- return;
32
- }
33
- originalError(...args);
32
+ if (!isDotenvNoise(...args)) originalConsoleError(...args);
34
33
  };
35
34
  }
36
35
  suppressDotenvLogsGlobally();
@@ -40,22 +39,51 @@ var DEFAULT_OPTIONS = Object.freeze({
40
39
  enabled: true,
41
40
  clearViteHeader: true,
42
41
  logo: BINI_LOGO,
43
- envPrefix: DEFAULT_ENV_PREFIX,
44
- loadInPreview: true,
45
- suppressDotenvLogs: true
42
+ envPrefix: [...DEFAULT_ENV_PREFIX],
43
+ loadInPreview: true
46
44
  });
47
45
  var envCache = /* @__PURE__ */ new Map();
48
- var originalConsoleLog = console.log;
49
- var originalConsoleError = console.error;
50
- function getEnv(key) {
51
- if (envCache.has(key)) {
52
- return envCache.get(key);
46
+ function timestamp() {
47
+ return `${"\x1B[2m" /* DIM */}${(/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", { hour12: false })}${"\x1B[0m" /* RESET */}`;
48
+ }
49
+ var biniLogger = {
50
+ info(msg) {
51
+ originalConsoleLog(
52
+ `${timestamp()} ${"\x1B[36m" /* CYAN */}${"\x1B[1m" /* BOLD */}[bini-env]${"\x1B[0m" /* RESET */} ${msg}`
53
+ );
54
+ },
55
+ warn(msg) {
56
+ originalConsoleError(
57
+ `${timestamp()} ${"\x1B[33m" /* YELLOW */}${"\x1B[1m" /* BOLD */}(!) [bini-env]${"\x1B[0m" /* RESET */} ${"\x1B[33m" /* YELLOW */}${msg}${"\x1B[0m" /* RESET */}`
58
+ );
59
+ },
60
+ error(msg, err) {
61
+ const detail = err instanceof Error ? `
62
+ ${"\x1B[2m" /* DIM */}${err.message}${"\x1B[0m" /* RESET */}` : "";
63
+ originalConsoleError(
64
+ `${timestamp()} ${"\x1B[31m" /* RED */}${"\x1B[1m" /* BOLD */}[bini-env] error${"\x1B[0m" /* RESET */} ${msg}${detail}`
65
+ );
53
66
  }
54
- let value;
55
- const deno = globalThis.Deno;
67
+ };
68
+ function getDeno() {
69
+ return globalThis.Deno;
70
+ }
71
+ function hasProcessEnv() {
72
+ return typeof process !== "undefined" && !!process.env;
73
+ }
74
+ function defer(fn) {
75
+ if (typeof setImmediate !== "undefined") {
76
+ setImmediate(fn);
77
+ } else {
78
+ Promise.resolve().then(fn);
79
+ }
80
+ }
81
+ function getEnv(key) {
82
+ if (envCache.has(key)) return envCache.get(key);
83
+ const deno = getDeno();
56
84
  if (deno) {
57
85
  try {
58
- value = deno.env.get(key);
86
+ const value = deno.env.get(key);
59
87
  if (value !== void 0) {
60
88
  envCache.set(key, value);
61
89
  return value;
@@ -63,8 +91,8 @@ function getEnv(key) {
63
91
  } catch {
64
92
  }
65
93
  }
66
- if (typeof process !== "undefined" && process.env) {
67
- value = process.env[key];
94
+ if (hasProcessEnv()) {
95
+ const value = process.env[key];
68
96
  if (value !== void 0) {
69
97
  envCache.set(key, value);
70
98
  return value;
@@ -73,19 +101,11 @@ function getEnv(key) {
73
101
  try {
74
102
  const metaEnv = undefined;
75
103
  if (metaEnv) {
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];
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
+ }
89
109
  }
90
110
  }
91
111
  } catch {
@@ -95,12 +115,13 @@ function getEnv(key) {
95
115
  }
96
116
  function requireEnv(key) {
97
117
  const val = getEnv(key);
98
- if (!val) {
99
- throw new Error(
100
- `[bini-env] Missing required environment variable: "${key}".
101
- \u2192 In development: add it to your .env file.
102
- \u2192 In production: add it to your hosting dashboard environment variables.`
118
+ if (val === void 0) {
119
+ biniLogger.error(
120
+ `Missing required environment variable: "${key}"
121
+ ${"\x1B[2m" /* DIM */}\u2192 In development: add it to your .env file.${"\x1B[0m" /* RESET */}
122
+ ${"\x1B[2m" /* DIM */}\u2192 In production: set it in your hosting dashboard.${"\x1B[0m" /* RESET */}`
103
123
  );
124
+ throw new Error(`[bini-env] Missing required environment variable: "${key}"`);
104
125
  }
105
126
  return val;
106
127
  }
@@ -111,54 +132,41 @@ async function loadEnv(projectRoot) {
111
132
  if (_loadPromise) return _loadPromise;
112
133
  _loadPromise = (async () => {
113
134
  try {
114
- if (globalThis.Deno) {
115
- _envLoaded = true;
116
- return;
117
- }
118
- if (typeof process === "undefined" || !process.env) {
119
- _envLoaded = true;
120
- return;
121
- }
135
+ if (getDeno()) return;
136
+ if (!hasProcessEnv()) return;
122
137
  const root = projectRoot ?? process.cwd();
138
+ const nodeEnv = process.env.NODE_ENV ?? "production";
123
139
  const envFiles = [
124
140
  ".env",
125
- `.env.${process.env.NODE_ENV}`,
126
- `.env.${process.env.NODE_ENV}.local`,
141
+ `.env.${nodeEnv}`,
142
+ `.env.${nodeEnv}.local`,
127
143
  ".env.local"
128
144
  ];
129
- suppressDotenvLogsGlobally();
130
145
  const dotenv = await import('dotenv');
131
- for (const envFile of envFiles) {
132
- const envPath = path__default.default.join(root, envFile);
146
+ for (const file of envFiles) {
147
+ const filePath = path__default.default.join(root, file);
133
148
  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
- });
149
+ await fs__default.default.promises.access(filePath, fs__default.default.constants.R_OK);
150
+ dotenv.config({ path: filePath, override: true });
140
151
  } catch {
141
152
  }
142
153
  }
143
154
  envCache.clear();
155
+ _envLoaded = true;
144
156
  } catch (error) {
145
- if (process.env.NODE_ENV !== "production") {
146
- originalConsoleError("[bini-env] Warning: Failed to load .env file:", error);
147
- }
157
+ biniLogger.error("Failed to load .env file", error);
148
158
  } finally {
149
- _envLoaded = true;
150
159
  _loadPromise = null;
151
160
  }
152
161
  })();
153
162
  return _loadPromise;
154
163
  }
155
164
  var _envFilesCache = null;
156
- var _cachedRoot = "";
165
+ var _cacheKey = "";
157
166
  function detectEnvFiles(projectRoot = process.cwd()) {
158
- if (_envFilesCache && _cachedRoot === projectRoot) {
159
- return _envFilesCache;
160
- }
161
167
  const nodeEnv = process.env.NODE_ENV ?? "production";
168
+ const cacheKey = `${projectRoot}:${nodeEnv}`;
169
+ if (_envFilesCache && _cacheKey === cacheKey) return _envFilesCache;
162
170
  const candidates = [
163
171
  ".env.local",
164
172
  `.env.${nodeEnv}.local`,
@@ -167,22 +175,18 @@ function detectEnvFiles(projectRoot = process.cwd()) {
167
175
  ];
168
176
  const found = [];
169
177
  for (const file of candidates) {
170
- const filePath = path__default.default.join(projectRoot, file);
171
178
  try {
172
- if (fs__default.default.existsSync(filePath)) {
173
- found.push({ name: file, path: filePath });
174
- }
179
+ const filePath = path__default.default.join(projectRoot, file);
180
+ if (fs__default.default.existsSync(filePath)) found.push({ name: file, path: filePath });
175
181
  } catch {
176
182
  }
177
183
  }
178
184
  _envFilesCache = found;
179
- _cachedRoot = projectRoot;
185
+ _cacheKey = cacheKey;
180
186
  return found;
181
187
  }
182
188
  function clearLine() {
183
- if (process.stdout.isTTY) {
184
- process.stdout.write("\x1B[2K\r");
185
- }
189
+ if (process.stdout.isTTY) process.stdout.write("\x1B[2K\r");
186
190
  }
187
191
  function printResolvedUrls(urls) {
188
192
  if (!urls) return;
@@ -197,16 +201,40 @@ function printResolvedUrls(urls) {
197
201
  );
198
202
  }
199
203
  }
204
+ function patchPrintUrls(server, mode, logo, clearViteHeader, getRoot, showEnvFiles) {
205
+ let started = false;
206
+ const originalPrintUrls = server.printUrls.bind(server);
207
+ server.printUrls = () => {
208
+ if (started) return;
209
+ started = true;
210
+ if (clearViteHeader) clearLine();
211
+ originalConsoleLog(`
212
+ ${"\x1B[36m" /* CYAN */}${logo} Bini.js${"\x1B[0m" /* RESET */} (${mode})`);
213
+ if (showEnvFiles) {
214
+ const found = detectEnvFiles(getRoot());
215
+ if (found.length > 0) {
216
+ originalConsoleLog(
217
+ ` ${"\x1B[32m" /* GREEN */}\u279C${"\x1B[0m" /* RESET */} Environments: ${found.map((f) => f.name).join(", ")}`
218
+ );
219
+ }
220
+ }
221
+ if (clearViteHeader) {
222
+ printResolvedUrls(server.resolvedUrls);
223
+ } else {
224
+ originalPrintUrls();
225
+ }
226
+ };
227
+ }
200
228
  function biniEnv(options = {}) {
201
229
  if (options.enabled === false) {
202
230
  return { name: "vite-plugin-bini-env" };
203
231
  }
204
- const resolvedOptions = { ...DEFAULT_OPTIONS, ...options };
205
- const { clearViteHeader, logo, envPrefix, loadInPreview, suppressDotenvLogs } = resolvedOptions;
232
+ const { clearViteHeader, logo, envPrefix, loadInPreview } = {
233
+ ...DEFAULT_OPTIONS,
234
+ ...options
235
+ };
206
236
  let resolvedConfig;
207
- if (suppressDotenvLogs && typeof process !== "undefined") {
208
- suppressDotenvLogsGlobally();
209
- }
237
+ const getRoot = () => resolvedConfig?.root ?? process.cwd();
210
238
  return {
211
239
  name: "vite-plugin-bini-env",
212
240
  config() {
@@ -216,77 +244,34 @@ function biniEnv(options = {}) {
216
244
  resolvedConfig = cfg;
217
245
  },
218
246
  configureServer(server) {
219
- const loadEnvTask = () => {
220
- void loadEnv(resolvedConfig?.root ?? process.cwd());
221
- };
247
+ const triggerLoad = () => void loadEnv(getRoot());
222
248
  if (server.httpServer) {
223
- server.httpServer.once("listening", loadEnvTask);
249
+ server.httpServer.once("listening", triggerLoad);
224
250
  } else {
225
- setImmediate(loadEnvTask);
251
+ defer(triggerLoad);
226
252
  }
227
- let serverStarted = false;
228
- const originalPrintUrls = server.printUrls.bind(server);
229
253
  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
- };
254
+ patchPrintUrls(server, "dev", logo, clearViteHeader, getRoot, true);
248
255
  }
249
256
  },
250
257
  configurePreviewServer(server) {
251
258
  if (loadInPreview) {
252
- const loadEnvTask = () => {
253
- void loadEnv(resolvedConfig?.root ?? process.cwd());
254
- };
259
+ const triggerLoad = () => void loadEnv(getRoot());
255
260
  if (server.httpServer) {
256
- server.httpServer.once("listening", loadEnvTask);
261
+ server.httpServer.once("listening", triggerLoad);
257
262
  } else {
258
- setImmediate(loadEnvTask);
263
+ defer(triggerLoad);
259
264
  }
260
265
  }
261
- let previewStarted = false;
262
- const originalPrintUrls = server.printUrls.bind(server);
263
266
  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
- };
267
+ patchPrintUrls(server, "preview", logo, clearViteHeader, getRoot, loadInPreview);
284
268
  }
285
269
  }
286
270
  };
287
271
  }
288
272
 
289
273
  exports.biniEnv = biniEnv;
274
+ exports.biniLogger = biniLogger;
290
275
  exports.detectEnvFiles = detectEnvFiles;
291
276
  exports.getEnv = getEnv;
292
277
  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":["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';"]}
package/dist/index.mjs CHANGED
@@ -2,28 +2,27 @@ import fs from 'fs';
2
2
  import path from 'path';
3
3
 
4
4
  // src/index.ts
5
+ var originalConsoleLog = console.log.bind(console);
6
+ var originalConsoleError = console.error.bind(console);
5
7
  if (typeof process !== "undefined" && process.env && !process.env.NODE_ENV) {
6
8
  process.env.NODE_ENV = "production";
7
9
  }
10
+ var _suppressionApplied = false;
8
11
  function suppressDotenvLogsGlobally() {
12
+ if (_suppressionApplied) return;
13
+ _suppressionApplied = true;
9
14
  if (typeof process !== "undefined" && process.env) {
10
15
  process.env.DOTENV_QUIET = "true";
11
16
  }
12
- const originalLog = console.log;
17
+ const isDotenvNoise = (...args) => {
18
+ const msg = args.join(" ");
19
+ return msg.includes("[dotenv@") || msg.includes("injected env") || msg.includes("injecting env");
20
+ };
13
21
  console.log = (...args) => {
14
- const message = args.join(" ");
15
- if (message.includes("[dotenv@") && message.includes("injecting env")) {
16
- return;
17
- }
18
- originalLog(...args);
22
+ if (!isDotenvNoise(...args)) originalConsoleLog(...args);
19
23
  };
20
- const originalError = console.error;
21
24
  console.error = (...args) => {
22
- const message = args.join(" ");
23
- if (message.includes("[dotenv@") && message.includes("injecting env")) {
24
- return;
25
- }
26
- originalError(...args);
25
+ if (!isDotenvNoise(...args)) originalConsoleError(...args);
27
26
  };
28
27
  }
29
28
  suppressDotenvLogsGlobally();
@@ -33,22 +32,51 @@ var DEFAULT_OPTIONS = Object.freeze({
33
32
  enabled: true,
34
33
  clearViteHeader: true,
35
34
  logo: BINI_LOGO,
36
- envPrefix: DEFAULT_ENV_PREFIX,
37
- loadInPreview: true,
38
- suppressDotenvLogs: true
35
+ envPrefix: [...DEFAULT_ENV_PREFIX],
36
+ loadInPreview: true
39
37
  });
40
38
  var envCache = /* @__PURE__ */ new Map();
41
- var originalConsoleLog = console.log;
42
- var originalConsoleError = console.error;
43
- function getEnv(key) {
44
- if (envCache.has(key)) {
45
- return envCache.get(key);
39
+ function timestamp() {
40
+ return `${"\x1B[2m" /* DIM */}${(/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", { hour12: false })}${"\x1B[0m" /* RESET */}`;
41
+ }
42
+ var biniLogger = {
43
+ info(msg) {
44
+ originalConsoleLog(
45
+ `${timestamp()} ${"\x1B[36m" /* CYAN */}${"\x1B[1m" /* BOLD */}[bini-env]${"\x1B[0m" /* RESET */} ${msg}`
46
+ );
47
+ },
48
+ warn(msg) {
49
+ originalConsoleError(
50
+ `${timestamp()} ${"\x1B[33m" /* YELLOW */}${"\x1B[1m" /* BOLD */}(!) [bini-env]${"\x1B[0m" /* RESET */} ${"\x1B[33m" /* YELLOW */}${msg}${"\x1B[0m" /* RESET */}`
51
+ );
52
+ },
53
+ error(msg, err) {
54
+ const detail = err instanceof Error ? `
55
+ ${"\x1B[2m" /* DIM */}${err.message}${"\x1B[0m" /* RESET */}` : "";
56
+ originalConsoleError(
57
+ `${timestamp()} ${"\x1B[31m" /* RED */}${"\x1B[1m" /* BOLD */}[bini-env] error${"\x1B[0m" /* RESET */} ${msg}${detail}`
58
+ );
46
59
  }
47
- let value;
48
- const deno = globalThis.Deno;
60
+ };
61
+ function getDeno() {
62
+ return globalThis.Deno;
63
+ }
64
+ function hasProcessEnv() {
65
+ return typeof process !== "undefined" && !!process.env;
66
+ }
67
+ function defer(fn) {
68
+ if (typeof setImmediate !== "undefined") {
69
+ setImmediate(fn);
70
+ } else {
71
+ Promise.resolve().then(fn);
72
+ }
73
+ }
74
+ function getEnv(key) {
75
+ if (envCache.has(key)) return envCache.get(key);
76
+ const deno = getDeno();
49
77
  if (deno) {
50
78
  try {
51
- value = deno.env.get(key);
79
+ const value = deno.env.get(key);
52
80
  if (value !== void 0) {
53
81
  envCache.set(key, value);
54
82
  return value;
@@ -56,8 +84,8 @@ function getEnv(key) {
56
84
  } catch {
57
85
  }
58
86
  }
59
- if (typeof process !== "undefined" && process.env) {
60
- value = process.env[key];
87
+ if (hasProcessEnv()) {
88
+ const value = process.env[key];
61
89
  if (value !== void 0) {
62
90
  envCache.set(key, value);
63
91
  return value;
@@ -66,19 +94,11 @@ function getEnv(key) {
66
94
  try {
67
95
  const metaEnv = import.meta.env;
68
96
  if (metaEnv) {
69
- if (metaEnv[key] !== void 0) {
70
- envCache.set(key, metaEnv[key]);
71
- return metaEnv[key];
72
- }
73
- const biniKey = `BINI_${key}`;
74
- if (metaEnv[biniKey] !== void 0) {
75
- envCache.set(key, metaEnv[biniKey]);
76
- return metaEnv[biniKey];
77
- }
78
- const viteKey = `VITE_${key}`;
79
- if (metaEnv[viteKey] !== void 0) {
80
- envCache.set(key, metaEnv[viteKey]);
81
- return metaEnv[viteKey];
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
+ }
82
102
  }
83
103
  }
84
104
  } catch {
@@ -88,12 +108,13 @@ function getEnv(key) {
88
108
  }
89
109
  function requireEnv(key) {
90
110
  const val = getEnv(key);
91
- if (!val) {
92
- throw new Error(
93
- `[bini-env] Missing required environment variable: "${key}".
94
- \u2192 In development: add it to your .env file.
95
- \u2192 In production: add it to your hosting dashboard environment variables.`
111
+ if (val === void 0) {
112
+ biniLogger.error(
113
+ `Missing required environment variable: "${key}"
114
+ ${"\x1B[2m" /* DIM */}\u2192 In development: add it to your .env file.${"\x1B[0m" /* RESET */}
115
+ ${"\x1B[2m" /* DIM */}\u2192 In production: set it in your hosting dashboard.${"\x1B[0m" /* RESET */}`
96
116
  );
117
+ throw new Error(`[bini-env] Missing required environment variable: "${key}"`);
97
118
  }
98
119
  return val;
99
120
  }
@@ -104,54 +125,41 @@ async function loadEnv(projectRoot) {
104
125
  if (_loadPromise) return _loadPromise;
105
126
  _loadPromise = (async () => {
106
127
  try {
107
- if (globalThis.Deno) {
108
- _envLoaded = true;
109
- return;
110
- }
111
- if (typeof process === "undefined" || !process.env) {
112
- _envLoaded = true;
113
- return;
114
- }
128
+ if (getDeno()) return;
129
+ if (!hasProcessEnv()) return;
115
130
  const root = projectRoot ?? process.cwd();
131
+ const nodeEnv = process.env.NODE_ENV ?? "production";
116
132
  const envFiles = [
117
133
  ".env",
118
- `.env.${process.env.NODE_ENV}`,
119
- `.env.${process.env.NODE_ENV}.local`,
134
+ `.env.${nodeEnv}`,
135
+ `.env.${nodeEnv}.local`,
120
136
  ".env.local"
121
137
  ];
122
- suppressDotenvLogsGlobally();
123
138
  const dotenv = await import('dotenv');
124
- for (const envFile of envFiles) {
125
- const envPath = path.join(root, envFile);
139
+ for (const file of envFiles) {
140
+ const filePath = path.join(root, file);
126
141
  try {
127
- await fs.promises.access(envPath, fs.constants.R_OK);
128
- dotenv.config({
129
- path: envPath,
130
- override: true,
131
- quiet: true
132
- });
142
+ await fs.promises.access(filePath, fs.constants.R_OK);
143
+ dotenv.config({ path: filePath, override: true });
133
144
  } catch {
134
145
  }
135
146
  }
136
147
  envCache.clear();
148
+ _envLoaded = true;
137
149
  } catch (error) {
138
- if (process.env.NODE_ENV !== "production") {
139
- originalConsoleError("[bini-env] Warning: Failed to load .env file:", error);
140
- }
150
+ biniLogger.error("Failed to load .env file", error);
141
151
  } finally {
142
- _envLoaded = true;
143
152
  _loadPromise = null;
144
153
  }
145
154
  })();
146
155
  return _loadPromise;
147
156
  }
148
157
  var _envFilesCache = null;
149
- var _cachedRoot = "";
158
+ var _cacheKey = "";
150
159
  function detectEnvFiles(projectRoot = process.cwd()) {
151
- if (_envFilesCache && _cachedRoot === projectRoot) {
152
- return _envFilesCache;
153
- }
154
160
  const nodeEnv = process.env.NODE_ENV ?? "production";
161
+ const cacheKey = `${projectRoot}:${nodeEnv}`;
162
+ if (_envFilesCache && _cacheKey === cacheKey) return _envFilesCache;
155
163
  const candidates = [
156
164
  ".env.local",
157
165
  `.env.${nodeEnv}.local`,
@@ -160,22 +168,18 @@ function detectEnvFiles(projectRoot = process.cwd()) {
160
168
  ];
161
169
  const found = [];
162
170
  for (const file of candidates) {
163
- const filePath = path.join(projectRoot, file);
164
171
  try {
165
- if (fs.existsSync(filePath)) {
166
- found.push({ name: file, path: filePath });
167
- }
172
+ const filePath = path.join(projectRoot, file);
173
+ if (fs.existsSync(filePath)) found.push({ name: file, path: filePath });
168
174
  } catch {
169
175
  }
170
176
  }
171
177
  _envFilesCache = found;
172
- _cachedRoot = projectRoot;
178
+ _cacheKey = cacheKey;
173
179
  return found;
174
180
  }
175
181
  function clearLine() {
176
- if (process.stdout.isTTY) {
177
- process.stdout.write("\x1B[2K\r");
178
- }
182
+ if (process.stdout.isTTY) process.stdout.write("\x1B[2K\r");
179
183
  }
180
184
  function printResolvedUrls(urls) {
181
185
  if (!urls) return;
@@ -190,16 +194,40 @@ function printResolvedUrls(urls) {
190
194
  );
191
195
  }
192
196
  }
197
+ function patchPrintUrls(server, mode, logo, clearViteHeader, getRoot, showEnvFiles) {
198
+ let started = false;
199
+ const originalPrintUrls = server.printUrls.bind(server);
200
+ server.printUrls = () => {
201
+ if (started) return;
202
+ started = true;
203
+ if (clearViteHeader) clearLine();
204
+ originalConsoleLog(`
205
+ ${"\x1B[36m" /* CYAN */}${logo} Bini.js${"\x1B[0m" /* RESET */} (${mode})`);
206
+ if (showEnvFiles) {
207
+ const found = detectEnvFiles(getRoot());
208
+ if (found.length > 0) {
209
+ originalConsoleLog(
210
+ ` ${"\x1B[32m" /* GREEN */}\u279C${"\x1B[0m" /* RESET */} Environments: ${found.map((f) => f.name).join(", ")}`
211
+ );
212
+ }
213
+ }
214
+ if (clearViteHeader) {
215
+ printResolvedUrls(server.resolvedUrls);
216
+ } else {
217
+ originalPrintUrls();
218
+ }
219
+ };
220
+ }
193
221
  function biniEnv(options = {}) {
194
222
  if (options.enabled === false) {
195
223
  return { name: "vite-plugin-bini-env" };
196
224
  }
197
- const resolvedOptions = { ...DEFAULT_OPTIONS, ...options };
198
- const { clearViteHeader, logo, envPrefix, loadInPreview, suppressDotenvLogs } = resolvedOptions;
225
+ const { clearViteHeader, logo, envPrefix, loadInPreview } = {
226
+ ...DEFAULT_OPTIONS,
227
+ ...options
228
+ };
199
229
  let resolvedConfig;
200
- if (suppressDotenvLogs && typeof process !== "undefined") {
201
- suppressDotenvLogsGlobally();
202
- }
230
+ const getRoot = () => resolvedConfig?.root ?? process.cwd();
203
231
  return {
204
232
  name: "vite-plugin-bini-env",
205
233
  config() {
@@ -209,76 +237,32 @@ function biniEnv(options = {}) {
209
237
  resolvedConfig = cfg;
210
238
  },
211
239
  configureServer(server) {
212
- const loadEnvTask = () => {
213
- void loadEnv(resolvedConfig?.root ?? process.cwd());
214
- };
240
+ const triggerLoad = () => void loadEnv(getRoot());
215
241
  if (server.httpServer) {
216
- server.httpServer.once("listening", loadEnvTask);
242
+ server.httpServer.once("listening", triggerLoad);
217
243
  } else {
218
- setImmediate(loadEnvTask);
244
+ defer(triggerLoad);
219
245
  }
220
- let serverStarted = false;
221
- const originalPrintUrls = server.printUrls.bind(server);
222
246
  if (clearViteHeader || logo !== BINI_LOGO) {
223
- server.printUrls = () => {
224
- if (serverStarted) return;
225
- serverStarted = true;
226
- if (clearViteHeader) clearLine();
227
- originalConsoleLog(`
228
- ${"\x1B[36m" /* CYAN */}${logo} Bini.js${"\x1B[0m" /* RESET */} (dev)`);
229
- const found = detectEnvFiles(resolvedConfig?.root);
230
- if (found.length > 0) {
231
- originalConsoleLog(
232
- ` ${"\x1B[32m" /* GREEN */}\u279C${"\x1B[0m" /* RESET */} Environments: ${found.map((f) => f.name).join(", ")}`
233
- );
234
- }
235
- if (!clearViteHeader) {
236
- originalPrintUrls();
237
- } else {
238
- printResolvedUrls(server.resolvedUrls);
239
- }
240
- };
247
+ patchPrintUrls(server, "dev", logo, clearViteHeader, getRoot, true);
241
248
  }
242
249
  },
243
250
  configurePreviewServer(server) {
244
251
  if (loadInPreview) {
245
- const loadEnvTask = () => {
246
- void loadEnv(resolvedConfig?.root ?? process.cwd());
247
- };
252
+ const triggerLoad = () => void loadEnv(getRoot());
248
253
  if (server.httpServer) {
249
- server.httpServer.once("listening", loadEnvTask);
254
+ server.httpServer.once("listening", triggerLoad);
250
255
  } else {
251
- setImmediate(loadEnvTask);
256
+ defer(triggerLoad);
252
257
  }
253
258
  }
254
- let previewStarted = false;
255
- const originalPrintUrls = server.printUrls.bind(server);
256
259
  if (clearViteHeader || logo !== BINI_LOGO) {
257
- server.printUrls = () => {
258
- if (previewStarted) return;
259
- previewStarted = true;
260
- if (clearViteHeader) clearLine();
261
- originalConsoleLog(`
262
- ${"\x1B[36m" /* CYAN */}${logo} Bini.js${"\x1B[0m" /* RESET */} (preview)`);
263
- if (loadInPreview) {
264
- const found = detectEnvFiles(resolvedConfig?.root);
265
- if (found.length > 0) {
266
- originalConsoleLog(
267
- ` ${"\x1B[32m" /* GREEN */}\u279C${"\x1B[0m" /* RESET */} Environments: ${found.map((f) => f.name).join(", ")}`
268
- );
269
- }
270
- }
271
- if (!clearViteHeader) {
272
- originalPrintUrls();
273
- } else {
274
- printResolvedUrls(server.resolvedUrls);
275
- }
276
- };
260
+ patchPrintUrls(server, "preview", logo, clearViteHeader, getRoot, loadInPreview);
277
261
  }
278
262
  }
279
263
  };
280
264
  }
281
265
 
282
- export { biniEnv, detectEnvFiles, getEnv, loadEnv, requireEnv, suppressDotenvLogsGlobally };
266
+ export { biniEnv, biniLogger, detectEnvFiles, getEnv, loadEnv, requireEnv, suppressDotenvLogsGlobally };
283
267
  //# sourceMappingURL=index.mjs.map
284
268
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","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.mjs","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';"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bini-env",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "description": "Universal environment variable loader and Vite plugin for Bini.js — works in Node.js, Deno, Bun, and Vite edge functions",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -17,7 +17,7 @@
17
17
  "README.md",
18
18
  "LICENSE"
19
19
  ],
20
- "sideEffects": false,
20
+ "sideEffects": true,
21
21
  "scripts": {
22
22
  "build": "tsup",
23
23
  "dev": "tsup --watch",
@@ -58,31 +58,13 @@
58
58
  }
59
59
  },
60
60
  "dependencies": {
61
- "dotenv": "^17.3.1"
61
+ "dotenv": "^17.4.2"
62
62
  },
63
63
  "devDependencies": {
64
- "@types/node": "^22.15.3",
65
- "tsup": "^8.4.0",
66
- "typescript": "^5.8.3",
67
- "vite": "^8.0.0"
68
- },
69
- "tsup": {
70
- "entry": ["src/index.ts"],
71
- "format": ["cjs", "esm"],
72
- "dts": true,
73
- "clean": true,
74
- "splitting": false,
75
- "sourcemap": true,
76
- "minify": false,
77
- "treeshake": true,
78
- "shims": true,
79
- "external": [
80
- "vite",
81
- "dotenv"
82
- ],
83
- "noExternal": [],
84
- "platform": "node",
85
- "target": "node20"
64
+ "@types/node": "^25.6.0",
65
+ "tsup": "^8.5.1",
66
+ "typescript": "^5.9.3",
67
+ "vite": "^8.0.8"
86
68
  },
87
69
  "engines": {
88
70
  "node": ">=20.19.0 || >=22.12.0"