bini-env 1.1.0 → 1.1.2

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.mjs CHANGED
@@ -6,222 +6,96 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
6
6
  if (typeof require !== "undefined") return require.apply(this, arguments);
7
7
  throw Error('Dynamic require of "' + x + '" is not supported');
8
8
  });
9
- function isNodeLike() {
10
- return typeof process !== "undefined" && !!process.env && typeof process.versions === "object" && (typeof process.versions.node === "string" || typeof process.versions.bun === "string");
11
- }
12
- var originalConsoleLog = console.log.bind(console);
13
- var originalConsoleError = console.error.bind(console);
14
- if (isNodeLike() && !process.env.NODE_ENV) {
15
- process.env.NODE_ENV = "production";
16
- }
17
- var BINI_LOGO = "\xDF";
18
- var DEFAULT_ENV_PREFIX = ["BINI_", "VITE_"];
19
- var DEFAULT_OPTIONS = Object.freeze({
20
- enabled: true,
21
- clearViteHeader: true,
22
- logo: BINI_LOGO,
23
- envPrefix: [...DEFAULT_ENV_PREFIX],
24
- loadInPreview: true
25
- });
26
- var envCache = /* @__PURE__ */ new Map();
27
- function timestamp() {
28
- return `${"\x1B[2m" /* DIM */}${(/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", { hour12: false })}${"\x1B[0m" /* RESET */}`;
9
+ var C = {
10
+ CYAN: "\x1B[36m",
11
+ RESET: "\x1B[0m",
12
+ YELLOW: "\x1B[33m",
13
+ RED: "\x1B[31m",
14
+ BOLD: "\x1B[1m",
15
+ DIM: "\x1B[2m"
16
+ };
17
+ function _ts() {
18
+ return `${C.DIM}${(/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", { hour12: false })}${C.RESET}`;
29
19
  }
30
20
  var biniLogger = {
31
21
  info(msg) {
32
- originalConsoleLog(
33
- `${timestamp()} ${"\x1B[36m" /* CYAN */}${"\x1B[1m" /* BOLD */}[bini-env]${"\x1B[0m" /* RESET */} ${msg}`
34
- );
22
+ console.log(`${_ts()} ${C.CYAN}${C.BOLD}[bini-env]${C.RESET} ${msg}`);
35
23
  },
36
24
  warn(msg) {
37
- originalConsoleError(
38
- `${timestamp()} ${"\x1B[33m" /* YELLOW */}${"\x1B[1m" /* BOLD */}(!) [bini-env]${"\x1B[0m" /* RESET */} ${"\x1B[33m" /* YELLOW */}${msg}${"\x1B[0m" /* RESET */}`
25
+ console.warn(
26
+ `${_ts()} ${C.YELLOW}${C.BOLD}(!) [bini-env]${C.RESET} ${C.YELLOW}${msg}${C.RESET}`
39
27
  );
40
28
  },
41
29
  error(msg, err) {
42
30
  const detail = err instanceof Error ? `
43
- ${"\x1B[2m" /* DIM */}${err.message}${"\x1B[0m" /* RESET */}` : "";
44
- originalConsoleError(
45
- `${timestamp()} ${"\x1B[31m" /* RED */}${"\x1B[1m" /* BOLD */}[bini-env] error${"\x1B[0m" /* RESET */} ${msg}${detail}`
31
+ ${C.DIM}${err.message}${C.RESET}` : "";
32
+ console.error(
33
+ `${_ts()} ${C.RED}${C.BOLD}[bini-env] error${C.RESET} ${msg}${detail}`
46
34
  );
47
35
  }
48
36
  };
49
- function defer(fn) {
50
- if (typeof setImmediate !== "undefined") {
51
- setImmediate(fn);
52
- } else {
53
- Promise.resolve().then(fn);
54
- }
55
- }
56
- var _honoContext = null;
57
- function setContext(c) {
58
- _honoContext = c;
59
- }
60
- function clearContext() {
61
- _honoContext = null;
62
- }
63
37
  function getEnv(c, key) {
64
- const resolvedKey = typeof c === "string" ? c : key;
65
- const resolvedCtx = typeof c === "string" ? null : c;
66
- const ctx = resolvedCtx ?? _honoContext;
67
- if (ctx) {
68
- try {
69
- const honoEnvs = env(ctx);
70
- const value = honoEnvs[resolvedKey];
71
- if (value !== void 0) return value;
72
- } catch {
73
- }
74
- }
75
- if (envCache.has(resolvedKey)) return envCache.get(resolvedKey);
76
- if (typeof process !== "undefined" && process.env) {
77
- const value = process.env[resolvedKey];
78
- envCache.set(resolvedKey, value);
79
- return value;
80
- }
81
- envCache.set(resolvedKey, void 0);
82
- return void 0;
38
+ const honoEnvs = env(c);
39
+ return honoEnvs[key];
83
40
  }
84
41
  function requireEnv(c, key) {
85
- const resolvedKey = typeof c === "string" ? c : key;
86
- const val = getEnv(c, resolvedKey);
87
- if (val === void 0) {
42
+ const val = getEnv(c, key);
43
+ if (!val) {
88
44
  biniLogger.error(
89
- `Missing required environment variable: "${resolvedKey}"
90
- ${"\x1B[2m" /* DIM */}\u2192 In development: set it in your platform's env config.${"\x1B[0m" /* RESET */}
91
- ${"\x1B[2m" /* DIM */}\u2192 In production: set it in your hosting dashboard.${"\x1B[0m" /* RESET */}`
45
+ `Missing required environment variable: "${key}"
46
+ ${C.DIM}-> Set it in your platform's env config or hosting dashboard.${C.RESET}`
92
47
  );
93
- throw new Error(`[bini-env] Missing required environment variable: "${resolvedKey}"`);
48
+ throw new Error(`[bini-env] Missing required environment variable: "${key}"`);
94
49
  }
95
50
  return val;
96
51
  }
97
- var _envFilesCache = null;
98
- var _cacheKey = "";
99
- function detectEnvFiles(projectRoot) {
100
- if (!isNodeLike()) return [];
101
- const root = projectRoot ?? process.cwd();
102
- const nodeEnv = process.env.NODE_ENV ?? "production";
103
- const cacheKey = `${root}:${nodeEnv}`;
104
- if (_envFilesCache && _cacheKey === cacheKey) return _envFilesCache;
105
- let fsSync;
106
- let pathMod;
52
+ var DEFAULT_PREFIXES = ["BINI_", "VITE_"];
53
+ function detectEnvFiles(root) {
107
54
  try {
108
- fsSync = __require("fs");
109
- pathMod = __require("path");
55
+ const fs = __require("fs");
56
+ const path = __require("path");
57
+ const nodeEnv = process.env.NODE_ENV ?? "production";
58
+ return [
59
+ ".env.local",
60
+ `.env.${nodeEnv}.local`,
61
+ `.env.${nodeEnv}`,
62
+ ".env"
63
+ ].filter((f) => fs.existsSync(path.join(root, f)));
110
64
  } catch {
111
65
  return [];
112
66
  }
113
- const candidates = [
114
- ".env.local",
115
- `.env.${nodeEnv}.local`,
116
- `.env.${nodeEnv}`,
117
- ".env"
118
- ];
119
- const found = [];
120
- for (const file of candidates) {
121
- try {
122
- const filePath = pathMod.join(root, file);
123
- if (fsSync.existsSync(filePath)) found.push({ name: file, path: filePath });
124
- } catch {
125
- }
126
- }
127
- _envFilesCache = found;
128
- _cacheKey = cacheKey;
129
- return found;
130
- }
131
- function clearLine() {
132
- if (typeof process !== "undefined" && process.stdout?.isTTY) {
133
- process.stdout.write("\x1B[2K\r");
134
- }
135
67
  }
136
- function printResolvedUrls(urls) {
137
- if (!urls) return;
138
- if (urls.local.length > 0) {
139
- originalConsoleLog(
140
- ` ${"\x1B[32m" /* GREEN */}\u279C${"\x1B[0m" /* RESET */} Local: ${"\x1B[36m" /* CYAN */}${urls.local[0]}${"\x1B[0m" /* RESET */}`
141
- );
142
- }
143
- if (urls.network.length > 0) {
144
- originalConsoleLog(
145
- ` ${"\x1B[32m" /* GREEN */}\u279C${"\x1B[0m" /* RESET */} Network: ${"\x1B[36m" /* CYAN */}${urls.network[0]}${"\x1B[0m" /* RESET */}`
146
- );
147
- }
148
- }
149
- function patchPrintUrls(server, mode, logo, clearViteHeader, getRoot, showEnvFiles) {
150
- let started = false;
151
- const originalPrintUrls = server.printUrls.bind(server);
68
+ function printBanner(server, mode, root) {
69
+ const original = server.printUrls.bind(server);
152
70
  server.printUrls = () => {
153
- if (started) return;
154
- started = true;
155
- if (clearViteHeader) clearLine();
156
- originalConsoleLog(`
157
- ${"\x1B[36m" /* CYAN */}${logo} Bini.js${"\x1B[0m" /* RESET */} (${mode})`);
158
- if (showEnvFiles) {
159
- const found = detectEnvFiles(getRoot());
160
- if (found.length > 0) {
161
- originalConsoleLog(
162
- ` ${"\x1B[32m" /* GREEN */}\u279C${"\x1B[0m" /* RESET */} Environments: ${found.map((f) => f.name).join(", ")}`
163
- );
164
- }
165
- }
166
- if (clearViteHeader) {
167
- printResolvedUrls(server.resolvedUrls);
168
- } else {
169
- originalPrintUrls();
71
+ console.log(`
72
+ ${C.CYAN}\xDF Bini.js${C.RESET} (${mode})`);
73
+ const found = detectEnvFiles(root);
74
+ if (found.length > 0) {
75
+ console.log(` \x1B[32m\u279C\x1B[0m Environments: ${found.join(", ")}`);
170
76
  }
77
+ original();
171
78
  };
172
79
  }
173
80
  function biniEnv(options = {}) {
174
- if (options.enabled === false) {
175
- return { name: "vite-plugin-bini-env" };
176
- }
177
- const { clearViteHeader, logo, envPrefix, loadInPreview } = {
178
- ...DEFAULT_OPTIONS,
179
- ...options
180
- };
181
- let resolvedConfig;
182
- const getRoot = () => resolvedConfig?.root ?? process.cwd();
81
+ const extraPrefixes = options.envPrefix ? Array.isArray(options.envPrefix) ? options.envPrefix : [options.envPrefix] : [];
82
+ const envPrefix = [
83
+ .../* @__PURE__ */ new Set([...DEFAULT_PREFIXES, ...extraPrefixes])
84
+ ];
183
85
  return {
184
- name: "vite-plugin-bini-env",
86
+ name: "bini-env",
185
87
  config() {
186
88
  return { envPrefix };
187
89
  },
188
- configResolved(cfg) {
189
- resolvedConfig = cfg;
190
- },
191
90
  configureServer(server) {
192
- defer(() => envCache.clear());
193
- const envGlob = `${getRoot()}/.env*`;
194
- server.watcher.add(envGlob);
195
- const onEnvChange = (filePath) => {
196
- if (/\.(swp|swo|bak|tmp)$|~$/.test(filePath)) return;
197
- biniLogger.info(
198
- `env file ${filePath.replace(getRoot() + "/", "")} changed \u2014 restarting server`
199
- );
200
- envCache.clear();
201
- _envFilesCache = null;
202
- void server.restart();
203
- };
204
- server.watcher.on("add", onEnvChange);
205
- server.watcher.on("change", onEnvChange);
206
- server.httpServer?.once("close", () => {
207
- server.watcher.off("add", onEnvChange);
208
- server.watcher.off("change", onEnvChange);
209
- });
210
- if (clearViteHeader || logo !== BINI_LOGO) {
211
- patchPrintUrls(server, "dev", logo, clearViteHeader, getRoot, true);
212
- }
91
+ printBanner(server, "dev", server.config.root);
213
92
  },
214
93
  configurePreviewServer(server) {
215
- if (loadInPreview) {
216
- defer(() => envCache.clear());
217
- }
218
- if (clearViteHeader || logo !== BINI_LOGO) {
219
- patchPrintUrls(server, "preview", logo, clearViteHeader, getRoot, loadInPreview);
220
- }
94
+ printBanner(server, "preview", server.config.root);
221
95
  }
222
96
  };
223
97
  }
224
98
 
225
- export { biniEnv, biniLogger, clearContext, detectEnvFiles, getEnv, requireEnv, setContext };
99
+ export { biniEnv, biniLogger, getEnv, requireEnv };
226
100
  //# sourceMappingURL=index.mjs.map
227
101
  //# 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 { env } from 'hono/adapter';\nimport type { Plugin, PreviewServer, ResolvedConfig, UserConfig, ViteDevServer } from 'vite';\n\n/* ==========================================================================\n Runtime detection — used by Vite plugin hooks only\n ========================================================================== */\n\nfunction isNodeLike(): boolean {\n return (\n typeof process !== 'undefined' &&\n !!process.env &&\n typeof process.versions === 'object' &&\n (typeof process.versions.node === 'string' ||\n typeof (process.versions as Record<string, unknown>).bun === 'string')\n );\n}\n\n/* ==========================================================================\n Capture originals FIRST — before any patching occurs\n ========================================================================== */\n\nconst originalConsoleLog = console.log.bind(console);\nconst originalConsoleError = console.error.bind(console);\n\n/* ==========================================================================\n Default NODE_ENV\n ========================================================================== */\n\nif (isNodeLike() && !process.env.NODE_ENV) {\n process.env.NODE_ENV = 'production';\n}\n\n/* ==========================================================================\n HonoContext duck type\n\n We intentionally do NOT import Context<E,P,I> from hono because Hono 4.12\n added a [GET_MATCH_RESULT] symbol to HonoRequest, making every\n narrowly-typed Context (e.g. Context<BlankEnv, \"/chat\", BlankInput>)\n structurally incompatible with Context<any, any, any>. A minimal duck type\n that only requires what hono/adapter's env() accesses at runtime sidesteps\n the symbol variance entirely. Consumers cast with `c as any` once at the\n call site; the single `env(ctx as any)` below is the only unsafe cast in\n the entire package.\n ========================================================================== */\n\n/** Minimal shape accepted by getEnv / requireEnv. Satisfied by any Hono Context. */\nexport type HonoContext = { env: unknown } & Record<string, unknown>;\n\n/* ==========================================================================\n Public types\n ========================================================================== */\n\nexport interface BiniEnvPluginOptions {\n readonly enabled? : boolean;\n readonly clearViteHeader?: boolean;\n readonly logo? : string;\n readonly envPrefix? : string | string[];\n readonly loadInPreview? : boolean;\n}\n\nexport interface DetectedEnvFile {\n readonly name: string;\n readonly path: string;\n}\n\n/* ==========================================================================\n Constants\n ========================================================================== */\n\nconst BINI_LOGO = 'ß';\nconst DEFAULT_ENV_PREFIX = ['BINI_', 'VITE_'] as const;\n\nconst DEFAULT_OPTIONS = Object.freeze({\n enabled : true,\n clearViteHeader: true,\n logo : BINI_LOGO,\n envPrefix : [...DEFAULT_ENV_PREFIX],\n loadInPreview : true,\n} satisfies Required<BiniEnvPluginOptions>);\n\nconst enum COLORS {\n CYAN = '\\x1b[36m',\n RESET = '\\x1b[0m',\n GREEN = '\\x1b[32m',\n YELLOW = '\\x1b[33m',\n RED = '\\x1b[31m',\n BOLD = '\\x1b[1m',\n DIM = '\\x1b[2m',\n}\n\n// Build-time only cache — never used for request-scoped Hono env() results\nconst envCache = new Map<string, string | undefined>();\n\n/* ==========================================================================\n Standalone logger\n ========================================================================== */\n\nfunction timestamp(): string {\n return `${COLORS.DIM}${new Date().toLocaleTimeString('en-US', { hour12: false })}${COLORS.RESET}`;\n}\n\nexport const biniLogger = {\n info(msg: string): void {\n originalConsoleLog(\n `${timestamp()} ${COLORS.CYAN}${COLORS.BOLD}[bini-env]${COLORS.RESET} ${msg}`,\n );\n },\n warn(msg: string): void {\n originalConsoleError(\n `${timestamp()} ${COLORS.YELLOW}${COLORS.BOLD}(!) [bini-env]${COLORS.RESET} ${COLORS.YELLOW}${msg}${COLORS.RESET}`,\n );\n },\n error(msg: string, err?: unknown): void {\n const detail = err instanceof Error\n ? `\\n ${COLORS.DIM}${err.message}${COLORS.RESET}`\n : '';\n originalConsoleError(\n `${timestamp()} ${COLORS.RED}${COLORS.BOLD}[bini-env] error${COLORS.RESET} ${msg}${detail}`,\n );\n },\n} as const;\n\n/* ==========================================================================\n Vite plugin helper\n ========================================================================== */\n\nfunction defer(fn: () => void): void {\n if (typeof setImmediate !== 'undefined') {\n setImmediate(fn);\n } else {\n Promise.resolve().then(fn);\n }\n}\n\n/* ==========================================================================\n Module-level Hono context store\n\n Lets getEnv / requireEnv work without an explicit `c` argument at every\n call site. Register once in a global middleware:\n\n app.use('*', (c, next) => { setContext(c as any); return next(); });\n ========================================================================== */\n\nlet _honoContext: HonoContext | null = null;\n\nexport function setContext(c: HonoContext): void {\n _honoContext = c;\n}\n\nexport function clearContext(): void {\n _honoContext = null;\n}\n\n/* ==========================================================================\n getEnv\n\n Resolution order:\n 1. Explicit Hono Context (c param) — request-scoped, never cached\n 2. Stored Hono Context (setContext) — request-scoped, never cached\n 3. process.env (build-time / Vite plugin hooks — no c available)\n\n Usage:\n getEnv(c as any, 'KEY') — inside a Hono route / middleware\n getEnv('KEY') — outside request context (build-time)\n ========================================================================== */\n\nexport function getEnv(c: HonoContext | string, key?: string): string | undefined {\n const resolvedKey = typeof c === 'string' ? c : key!;\n const resolvedCtx = typeof c === 'string' ? null : c;\n\n // 1 & 2. Hono env() — covers all runtimes: CF Workers, Node, Bun, Deno, Edge\n const ctx = resolvedCtx ?? _honoContext;\n if (ctx) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const honoEnvs = env(ctx as any) as Record<string, string | undefined>;\n const value = honoEnvs[resolvedKey];\n if (value !== undefined) return value; // never cache — request-scoped\n } catch { /* context binding unavailable — fall through */ }\n }\n\n // 3. process.env — build-time only (Vite plugin hooks run outside any request)\n if (envCache.has(resolvedKey)) return envCache.get(resolvedKey);\n\n if (typeof process !== 'undefined' && process.env) {\n const value = process.env[resolvedKey];\n envCache.set(resolvedKey, value);\n return value;\n }\n\n envCache.set(resolvedKey, undefined);\n return undefined;\n}\n\n/* ==========================================================================\n requireEnv\n ========================================================================== */\n\nexport function requireEnv(c: HonoContext | string, key?: string): string {\n const resolvedKey = typeof c === 'string' ? c : key!;\n const val = getEnv(c, resolvedKey);\n if (val === undefined) {\n biniLogger.error(\n `Missing required environment variable: \"${resolvedKey}\"\\n` +\n ` ${COLORS.DIM}→ In development: set it in your platform's env config.${COLORS.RESET}\\n` +\n ` ${COLORS.DIM}→ In production: set it in your hosting dashboard.${COLORS.RESET}`,\n );\n throw new Error(`[bini-env] Missing required environment variable: \"${resolvedKey}\"`);\n }\n return val;\n}\n\n/* ==========================================================================\n detectEnvFiles\n Node-only — used by the Vite plugin at build/dev time, never on edge.\n ========================================================================== */\n\nlet _envFilesCache: DetectedEnvFile[] | null = null;\nlet _cacheKey = '';\n\nexport function detectEnvFiles(projectRoot?: string): DetectedEnvFile[] {\n if (!isNodeLike()) return [];\n\n const root = projectRoot ?? process.cwd();\n const nodeEnv = process.env.NODE_ENV ?? 'production';\n const cacheKey = `${root}:${nodeEnv}`;\n if (_envFilesCache && _cacheKey === cacheKey) return _envFilesCache;\n\n let fsSync: typeof import('fs');\n let pathMod: typeof import('path');\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n fsSync = require('node:fs');\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n pathMod = require('node:path');\n } catch {\n return [];\n }\n\n const candidates = [\n '.env.local',\n `.env.${nodeEnv}.local`,\n `.env.${nodeEnv}`,\n '.env',\n ];\n\n const found: DetectedEnvFile[] = [];\n for (const file of candidates) {\n try {\n const filePath = pathMod.join(root, file);\n if (fsSync.existsSync(filePath)) found.push({ name: file, path: filePath });\n } catch { /* skip unreadable paths */ }\n }\n\n _envFilesCache = found;\n _cacheKey = cacheKey;\n return found;\n}\n\n/* ==========================================================================\n Vite plugin helpers\n ========================================================================== */\n\nfunction clearLine(): void {\n if (typeof process !== 'undefined' && process.stdout?.isTTY) {\n process.stdout.write('\\x1b[2K\\r');\n }\n}\n\nfunction printResolvedUrls(\n urls: { local: string[]; network: string[] } | null | undefined,\n): void {\n if (!urls) return;\n if (urls.local.length > 0) {\n originalConsoleLog(\n ` ${COLORS.GREEN}➜${COLORS.RESET} Local: ${COLORS.CYAN}${urls.local[0]}${COLORS.RESET}`,\n );\n }\n if (urls.network.length > 0) {\n originalConsoleLog(\n ` ${COLORS.GREEN}➜${COLORS.RESET} Network: ${COLORS.CYAN}${urls.network[0]}${COLORS.RESET}`,\n );\n }\n}\n\ntype ServerLike = ViteDevServer | PreviewServer;\n\nfunction patchPrintUrls(\n server : ServerLike,\n mode : 'dev' | 'preview',\n logo : string,\n clearViteHeader: boolean,\n getRoot : () => string,\n showEnvFiles : boolean,\n): void {\n let started = false;\n const originalPrintUrls = server.printUrls.bind(server);\n\n server.printUrls = () => {\n if (started) return;\n started = true;\n\n if (clearViteHeader) clearLine();\n originalConsoleLog(`\\n ${COLORS.CYAN}${logo} Bini.js${COLORS.RESET} (${mode})`);\n\n if (showEnvFiles) {\n const found = detectEnvFiles(getRoot());\n if (found.length > 0) {\n originalConsoleLog(\n ` ${COLORS.GREEN}➜${COLORS.RESET} Environments: ${found.map(f => f.name).join(', ')}`,\n );\n }\n }\n\n if (clearViteHeader) {\n printResolvedUrls(server.resolvedUrls);\n } else {\n originalPrintUrls();\n }\n };\n}\n\n/* ==========================================================================\n Vite plugin\n ========================================================================== */\n\nexport function biniEnv(options: Readonly<BiniEnvPluginOptions> = {}): Plugin {\n if (options.enabled === false) {\n return { name: 'vite-plugin-bini-env' };\n }\n\n const { clearViteHeader, logo, envPrefix, loadInPreview } = {\n ...DEFAULT_OPTIONS,\n ...options,\n };\n\n let resolvedConfig: ResolvedConfig;\n const getRoot = () => resolvedConfig?.root ?? process.cwd();\n\n return {\n name: 'vite-plugin-bini-env',\n\n config(): UserConfig {\n return { envPrefix };\n },\n\n configResolved(cfg: ResolvedConfig) {\n resolvedConfig = cfg;\n },\n\n configureServer(server) {\n defer(() => envCache.clear());\n\n const envGlob = `${getRoot()}/.env*`;\n server.watcher.add(envGlob);\n\n const onEnvChange = (filePath: string) => {\n if (/\\.(swp|swo|bak|tmp)$|~$/.test(filePath)) return;\n\n biniLogger.info(\n `env file ${filePath.replace(getRoot() + '/', '')} changed — restarting server`,\n );\n\n envCache.clear();\n _envFilesCache = null;\n\n void server.restart();\n };\n\n server.watcher.on('add', onEnvChange);\n server.watcher.on('change', onEnvChange);\n\n server.httpServer?.once('close', () => {\n server.watcher.off('add', onEnvChange);\n server.watcher.off('change', onEnvChange);\n });\n\n if (clearViteHeader || logo !== BINI_LOGO) {\n patchPrintUrls(server, 'dev', logo, clearViteHeader, getRoot, true);\n }\n },\n\n configurePreviewServer(server) {\n if (loadInPreview) {\n defer(() => envCache.clear());\n }\n\n if (clearViteHeader || logo !== BINI_LOGO) {\n patchPrintUrls(server, 'preview', logo, clearViteHeader, getRoot, loadInPreview);\n }\n },\n };\n}\n\nexport type { Plugin } from 'vite';\nexport type { Context } from 'hono';"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * bini-env/src/index.ts\n *\n * Two responsibilities only:\n * 1. Tell Vite which env prefixes to expose to import.meta.env (biniEnv plugin)\n * 2. Read env vars from the Hono request context (getEnv / requireEnv)\n *\n * process.env is never used. All runtime env access goes through Hono's env() adapter,\n * which handles Node, Bun, Cloudflare Workers, Deno, and Vercel Edge natively.\n */\n\nimport { env } from 'hono/adapter';\nimport type { Context } from 'hono';\nimport type { Plugin, UserConfig, ViteDevServer, PreviewServer } from 'vite';\n\n/* ==========================================================================\n ANSI helpers — used by biniLogger only\n ========================================================================== */\n\nconst C = {\n CYAN : '\\x1b[36m',\n RESET : '\\x1b[0m',\n YELLOW: '\\x1b[33m',\n RED : '\\x1b[31m',\n BOLD : '\\x1b[1m',\n DIM : '\\x1b[2m',\n} as const;\n\n/* ==========================================================================\n Public types\n ========================================================================== */\n\n/**\n * Accepts any Hono Context. Typed against Hono's own Context rather than a\n * loose duck type so misuse is caught at the call site.\n */\nexport type HonoContext = Context;\n\nexport interface BiniEnvPluginOptions {\n /** Extra prefixes to expose to import.meta.env, in addition to BINI_ and VITE_. */\n readonly envPrefix?: string | string[];\n}\n\n/* ==========================================================================\n Logger\n ========================================================================== */\n\nfunction _ts(): string {\n return `${C.DIM}${new Date().toLocaleTimeString('en-US', { hour12: false })}${C.RESET}`;\n}\n\nexport const biniLogger = {\n info(msg: string): void {\n console.log(`${_ts()} ${C.CYAN}${C.BOLD}[bini-env]${C.RESET} ${msg}`);\n },\n warn(msg: string): void {\n console.warn(\n `${_ts()} ${C.YELLOW}${C.BOLD}(!) [bini-env]${C.RESET} ${C.YELLOW}${msg}${C.RESET}`,\n );\n },\n error(msg: string, err?: unknown): void {\n const detail =\n err instanceof Error ? `\\n ${C.DIM}${err.message}${C.RESET}` : '';\n console.error(\n `${_ts()} ${C.RED}${C.BOLD}[bini-env] error${C.RESET} ${msg}${detail}`,\n );\n },\n} as const;\n\n/* ==========================================================================\n getEnv\n\n Reads exclusively from Hono's env() adapter. No process.env fallback.\n Hono handles all platform differences:\n Node / Bun → process.env\n Cloudflare → c.env bindings\n Deno / Netlify → Deno.env.get()\n Vercel Edge → process.env (V8 Node compat)\n ========================================================================== */\n\nexport function getEnv(c: HonoContext, key: string): string | undefined {\n const honoEnvs = env(c) as Record<string, string | undefined>;\n return honoEnvs[key];\n}\n\n/* ==========================================================================\n requireEnv\n\n Same as getEnv but throws immediately if the variable is missing or empty.\n Always handle the thrown error in your route's catch block.\n ========================================================================== */\n\nexport function requireEnv(c: HonoContext, key: string): string {\n const val = getEnv(c, key);\n\n if (!val) {\n biniLogger.error(\n `Missing required environment variable: \"${key}\"\\n` +\n ` ${C.DIM}-> Set it in your platform's env config or hosting dashboard.${C.RESET}`,\n );\n\n throw new Error(`[bini-env] Missing required environment variable: \"${key}\"`);\n }\n\n return val;\n}\n\n/* ==========================================================================\n biniEnv — Vite plugin\n\n Tells Vite which prefixes to expose to import.meta.env.\n Prints the ß Bini.js banner on dev and preview server start.\n Vite handles .env file loading, watching, server restarts, and HMR natively.\n ========================================================================== */\n\nconst DEFAULT_PREFIXES = ['BINI_', 'VITE_'] as const;\n\nfunction detectEnvFiles(root: string): string[] {\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const fs = require('node:fs') as typeof import('fs');\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const path = require('node:path') as typeof import('path');\n const nodeEnv = process.env.NODE_ENV ?? 'production';\n return [\n '.env.local',\n `.env.${nodeEnv}.local`,\n `.env.${nodeEnv}`,\n '.env',\n ].filter(f => fs.existsSync(path.join(root, f)));\n } catch {\n return [];\n }\n}\n\nfunction printBanner(server: ViteDevServer | PreviewServer, mode: 'dev' | 'preview', root: string): void {\n const original = server.printUrls.bind(server);\n server.printUrls = () => {\n console.log(`\\n ${C.CYAN}ß Bini.js${C.RESET} (${mode})`);\n const found = detectEnvFiles(root);\n if (found.length > 0) {\n console.log(` \\x1b[32m➜\\x1b[0m Environments: ${found.join(', ')}`);\n }\n original();\n };\n}\n\nexport function biniEnv(options: Readonly<BiniEnvPluginOptions> = {}): Plugin {\n const extraPrefixes = options.envPrefix\n ? (Array.isArray(options.envPrefix) ? options.envPrefix : [options.envPrefix])\n : [];\n\n const envPrefix = [\n ...new Set([...DEFAULT_PREFIXES, ...extraPrefixes]),\n ];\n\n return {\n name: 'bini-env',\n\n config(): UserConfig {\n return { envPrefix };\n },\n\n configureServer(server) {\n printBanner(server, 'dev', server.config.root);\n },\n\n configurePreviewServer(server) {\n printBanner(server, 'preview', server.config.root);\n },\n };\n}\n\n/* ==========================================================================\n Re-exports\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.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "Universal environment variable loader and Vite plugin for Bini.js — powered by Hono, works across Node.js, Bun, Deno, Vercel Edge, Netlify Edge, and Cloudflare Workers",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -69,10 +69,10 @@
69
69
  }
70
70
  },
71
71
  "devDependencies": {
72
- "@types/node": "^25.6.0",
72
+ "@types/node": "26.1.2",
73
73
  "hono": "^4.8.4",
74
74
  "tsup": "^8.5.1",
75
- "typescript": "^5.9.3",
75
+ "typescript": "^5.8.3",
76
76
  "vite": "^8.0.8"
77
77
  },
78
78
  "engines": {