bini-env 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +219 -173
- package/dist/index.d.mts +21 -19
- package/dist/index.d.ts +21 -19
- package/dist/index.js +49 -178
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +50 -176
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs.map
CHANGED
|
@@ -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.
|
|
3
|
+
"version": "1.1.1",
|
|
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",
|