bini-env 1.1.2 → 2.0.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 +303 -162
- package/dist/index.d.ts +19 -25
- package/dist/index.js +47 -72
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +8 -0
- package/dist/node.js +37 -0
- package/dist/node.js.map +1 -0
- package/dist/vite.d.ts +6 -0
- package/dist/vite.js +104 -0
- package/dist/vite.js.map +1 -0
- package/package.json +22 -11
- package/dist/index.d.mts +0 -34
- package/dist/index.mjs +0 -101
- package/dist/index.mjs.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,34 +1,28 @@
|
|
|
1
1
|
import { Context } from 'hono';
|
|
2
|
-
import { Plugin } from 'vite';
|
|
3
|
-
export { Plugin } from 'vite';
|
|
4
2
|
|
|
5
|
-
/**
|
|
6
|
-
* bini-env/src/index.ts
|
|
7
|
-
*
|
|
8
|
-
* Two responsibilities only:
|
|
9
|
-
* 1. Tell Vite which env prefixes to expose to import.meta.env (biniEnv plugin)
|
|
10
|
-
* 2. Read env vars from the Hono request context (getEnv / requireEnv)
|
|
11
|
-
*
|
|
12
|
-
* process.env is never used. All runtime env access goes through Hono's env() adapter,
|
|
13
|
-
* which handles Node, Bun, Cloudflare Workers, Deno, and Vercel Edge natively.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Accepts any Hono Context. Typed against Hono's own Context rather than a
|
|
18
|
-
* loose duck type so misuse is caught at the call site.
|
|
19
|
-
*/
|
|
20
3
|
type HonoContext = Context;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
readonly envPrefix?: string | string[];
|
|
24
|
-
}
|
|
4
|
+
type EnvSource = Record<string, unknown>;
|
|
5
|
+
type EnvInput = HonoContext | EnvSource | undefined | null;
|
|
25
6
|
declare const biniLogger: {
|
|
26
7
|
readonly info: (msg: string) => void;
|
|
27
8
|
readonly warn: (msg: string) => void;
|
|
28
9
|
readonly error: (msg: string, err?: unknown) => void;
|
|
29
10
|
};
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Reads one variable. Returns `undefined` when it is missing or is not a string
|
|
13
|
+
* (Cloudflare bindings such as KV namespaces are not env strings).
|
|
14
|
+
*/
|
|
15
|
+
declare function getEnv(source: EnvInput, key: string): string | undefined;
|
|
16
|
+
/** Reads one variable and throws (after logging) when it is missing or empty. */
|
|
17
|
+
declare function requireEnv(source: EnvInput, key: string): string;
|
|
18
|
+
interface EnvCheck {
|
|
19
|
+
ok: boolean;
|
|
20
|
+
/** Names only, never values. */
|
|
21
|
+
missing: string[];
|
|
22
|
+
}
|
|
23
|
+
/** Checks several variables at once and logs every missing name in one message. */
|
|
24
|
+
declare function checkEnv(source: EnvInput, keys: readonly string[]): EnvCheck;
|
|
25
|
+
/** Requires several variables at once. Throws one error listing all that are missing. */
|
|
26
|
+
declare function requireEnvs<K extends string>(source: EnvInput, keys: readonly K[]): Record<K, string>;
|
|
33
27
|
|
|
34
|
-
export { type
|
|
28
|
+
export { type EnvCheck, type EnvInput, type EnvSource, type HonoContext, biniLogger, checkEnv, getEnv, requireEnv, requireEnvs };
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { env } from 'hono/adapter';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
6
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
7
|
-
}) : x)(function(x) {
|
|
8
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
9
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
10
|
-
});
|
|
3
|
+
// src/index.ts
|
|
11
4
|
var C = {
|
|
12
5
|
CYAN: "\x1B[36m",
|
|
13
6
|
RESET: "\x1B[0m",
|
|
@@ -16,91 +9,73 @@ var C = {
|
|
|
16
9
|
BOLD: "\x1B[1m",
|
|
17
10
|
DIM: "\x1B[2m"
|
|
18
11
|
};
|
|
19
|
-
function
|
|
12
|
+
function timestamp() {
|
|
20
13
|
return `${C.DIM}${(/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", { hour12: false })}${C.RESET}`;
|
|
21
14
|
}
|
|
22
15
|
var biniLogger = {
|
|
23
16
|
info(msg) {
|
|
24
|
-
console.log(`${
|
|
17
|
+
console.log(`${timestamp()} ${C.CYAN}${C.BOLD}[bini-env]${C.RESET} ${msg}`);
|
|
25
18
|
},
|
|
26
19
|
warn(msg) {
|
|
27
|
-
console.warn(
|
|
28
|
-
`${_ts()} ${C.YELLOW}${C.BOLD}(!) [bini-env]${C.RESET} ${C.YELLOW}${msg}${C.RESET}`
|
|
29
|
-
);
|
|
20
|
+
console.warn(`${timestamp()} ${C.YELLOW}${C.BOLD}(!) [bini-env]${C.RESET} ${C.YELLOW}${msg}${C.RESET}`);
|
|
30
21
|
},
|
|
31
22
|
error(msg, err) {
|
|
32
23
|
const detail = err instanceof Error ? `
|
|
33
24
|
${C.DIM}${err.message}${C.RESET}` : "";
|
|
34
|
-
console.error(
|
|
35
|
-
`${_ts()} ${C.RED}${C.BOLD}[bini-env] error${C.RESET} ${msg}${detail}`
|
|
36
|
-
);
|
|
25
|
+
console.error(`${timestamp()} ${C.RED}${C.BOLD}[bini-env] error${C.RESET} ${msg}${detail}`);
|
|
37
26
|
}
|
|
38
27
|
};
|
|
39
|
-
function
|
|
40
|
-
|
|
41
|
-
|
|
28
|
+
function isContext(value) {
|
|
29
|
+
if (typeof value !== "object" || value === null) return false;
|
|
30
|
+
const v = value;
|
|
31
|
+
return typeof v.req === "object" && v.req !== null && typeof v.get === "function";
|
|
32
|
+
}
|
|
33
|
+
function runtimeEnv() {
|
|
34
|
+
const g = globalThis;
|
|
35
|
+
if (g.process?.env) return g.process.env;
|
|
36
|
+
try {
|
|
37
|
+
const obj = g.Deno?.env?.toObject?.();
|
|
38
|
+
if (obj) return obj;
|
|
39
|
+
} catch {
|
|
40
|
+
}
|
|
41
|
+
return void 0;
|
|
42
42
|
}
|
|
43
|
-
function
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
function toEnvObject(source) {
|
|
44
|
+
if (isContext(source)) return env(source);
|
|
45
|
+
return source ?? runtimeEnv();
|
|
46
|
+
}
|
|
47
|
+
function getEnv(source, key) {
|
|
48
|
+
const value = toEnvObject(source)?.[key];
|
|
49
|
+
return typeof value === "string" ? value : void 0;
|
|
50
|
+
}
|
|
51
|
+
function requireEnv(source, key) {
|
|
52
|
+
const value = getEnv(source, key);
|
|
53
|
+
if (!value) {
|
|
46
54
|
biniLogger.error(
|
|
47
55
|
`Missing required environment variable: "${key}"
|
|
48
|
-
${C.DIM}-> Set it in your
|
|
56
|
+
${C.DIM}-> Set it in your hosting dashboard (or in .env for dev, preview and bini-server).${C.RESET}`
|
|
49
57
|
);
|
|
50
58
|
throw new Error(`[bini-env] Missing required environment variable: "${key}"`);
|
|
51
59
|
}
|
|
52
|
-
return
|
|
60
|
+
return value;
|
|
53
61
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const path = __require("path");
|
|
59
|
-
const nodeEnv = process.env.NODE_ENV ?? "production";
|
|
60
|
-
return [
|
|
61
|
-
".env.local",
|
|
62
|
-
`.env.${nodeEnv}.local`,
|
|
63
|
-
`.env.${nodeEnv}`,
|
|
64
|
-
".env"
|
|
65
|
-
].filter((f) => fs.existsSync(path.join(root, f)));
|
|
66
|
-
} catch {
|
|
67
|
-
return [];
|
|
62
|
+
function checkEnv(source, keys) {
|
|
63
|
+
const missing = keys.filter((k) => !getEnv(source, k));
|
|
64
|
+
if (missing.length > 0) {
|
|
65
|
+
biniLogger.error(`Missing environment variables: ${missing.join(", ")}`);
|
|
68
66
|
}
|
|
67
|
+
return { ok: missing.length === 0, missing };
|
|
69
68
|
}
|
|
70
|
-
function
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
original();
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
function biniEnv(options = {}) {
|
|
83
|
-
const extraPrefixes = options.envPrefix ? Array.isArray(options.envPrefix) ? options.envPrefix : [options.envPrefix] : [];
|
|
84
|
-
const envPrefix = [
|
|
85
|
-
.../* @__PURE__ */ new Set([...DEFAULT_PREFIXES, ...extraPrefixes])
|
|
86
|
-
];
|
|
87
|
-
return {
|
|
88
|
-
name: "bini-env",
|
|
89
|
-
config() {
|
|
90
|
-
return { envPrefix };
|
|
91
|
-
},
|
|
92
|
-
configureServer(server) {
|
|
93
|
-
printBanner(server, "dev", server.config.root);
|
|
94
|
-
},
|
|
95
|
-
configurePreviewServer(server) {
|
|
96
|
-
printBanner(server, "preview", server.config.root);
|
|
97
|
-
}
|
|
98
|
-
};
|
|
69
|
+
function requireEnvs(source, keys) {
|
|
70
|
+
const { missing } = checkEnv(source, keys);
|
|
71
|
+
if (missing.length > 0) {
|
|
72
|
+
throw new Error(`[bini-env] Missing environment variables: ${missing.join(", ")}`);
|
|
73
|
+
}
|
|
74
|
+
const out = {};
|
|
75
|
+
for (const k of keys) out[k] = getEnv(source, k);
|
|
76
|
+
return out;
|
|
99
77
|
}
|
|
100
78
|
|
|
101
|
-
|
|
102
|
-
exports.biniLogger = biniLogger;
|
|
103
|
-
exports.getEnv = getEnv;
|
|
104
|
-
exports.requireEnv = requireEnv;
|
|
79
|
+
export { biniLogger, checkEnv, getEnv, requireEnv, requireEnvs };
|
|
105
80
|
//# sourceMappingURL=index.js.map
|
|
106
81
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":["
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["honoEnv"],"mappings":"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","file":"index.js","sourcesContent":["import { env as honoEnv } from 'hono/adapter';\nimport type { Context } from 'hono';\n\nexport type HonoContext = Context;\nexport type EnvSource = Record<string, unknown>;\nexport type EnvInput = HonoContext | EnvSource | undefined | null;\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\nfunction timestamp(): 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(`${timestamp()} ${C.CYAN}${C.BOLD}[bini-env]${C.RESET} ${msg}`);\n },\n warn(msg: string): void {\n console.warn(`${timestamp()} ${C.YELLOW}${C.BOLD}(!) [bini-env]${C.RESET} ${C.YELLOW}${msg}${C.RESET}`);\n },\n error(msg: string, err?: unknown): void {\n const detail = err instanceof Error ? `\\n ${C.DIM}${err.message}${C.RESET}` : '';\n console.error(`${timestamp()} ${C.RED}${C.BOLD}[bini-env] error${C.RESET} ${msg}${detail}`);\n },\n} as const;\n\nfunction isContext(value: unknown): value is HonoContext {\n if (typeof value !== 'object' || value === null) return false;\n const v = value as { req?: unknown; get?: unknown };\n return typeof v.req === 'object' && v.req !== null && typeof v.get === 'function';\n}\n\n/** Best-effort read of the current runtime's environment when no source is given. */\nfunction runtimeEnv(): EnvSource | undefined {\n const g = globalThis as {\n process?: { env?: EnvSource };\n Deno?: { env?: { toObject?: () => EnvSource } };\n };\n if (g.process?.env) return g.process.env;\n try {\n const obj = g.Deno?.env?.toObject?.();\n if (obj) return obj;\n } catch {\n // Deno.env needs --allow-env; treat as unavailable\n }\n return undefined;\n}\n\nfunction toEnvObject(source: EnvInput): EnvSource | undefined {\n if (isContext(source)) return honoEnv(source) as EnvSource;\n return source ?? runtimeEnv();\n}\n\n/**\n * Reads one variable. Returns `undefined` when it is missing or is not a string\n * (Cloudflare bindings such as KV namespaces are not env strings).\n */\nexport function getEnv(source: EnvInput, key: string): string | undefined {\n const value = toEnvObject(source)?.[key];\n return typeof value === 'string' ? value : undefined;\n}\n\n/** Reads one variable and throws (after logging) when it is missing or empty. */\nexport function requireEnv(source: EnvInput, key: string): string {\n const value = getEnv(source, key);\n if (!value) {\n biniLogger.error(\n `Missing required environment variable: \"${key}\"\\n` +\n ` ${C.DIM}-> Set it in your hosting dashboard (or in .env for dev, preview and bini-server).${C.RESET}`,\n );\n throw new Error(`[bini-env] Missing required environment variable: \"${key}\"`);\n }\n return value;\n}\n\nexport interface EnvCheck {\n ok: boolean;\n /** Names only, never values. */\n missing: string[];\n}\n\n/** Checks several variables at once and logs every missing name in one message. */\nexport function checkEnv(source: EnvInput, keys: readonly string[]): EnvCheck {\n const missing = keys.filter((k) => !getEnv(source, k));\n if (missing.length > 0) {\n biniLogger.error(`Missing environment variables: ${missing.join(', ')}`);\n }\n return { ok: missing.length === 0, missing };\n}\n\n/** Requires several variables at once. Throws one error listing all that are missing. */\nexport function requireEnvs<K extends string>(source: EnvInput, keys: readonly K[]): Record<K, string> {\n const { missing } = checkEnv(source, keys);\n if (missing.length > 0) {\n throw new Error(`[bini-env] Missing environment variables: ${missing.join(', ')}`);\n }\n const out = {} as Record<K, string>;\n for (const k of keys) out[k] = getEnv(source, k) as string;\n return out;\n}"]}
|
package/dist/node.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
declare function envFilesFor(root: string, mode: string): string[];
|
|
2
|
+
interface LoadEnvResult {
|
|
3
|
+
files: string[];
|
|
4
|
+
injected: number;
|
|
5
|
+
}
|
|
6
|
+
declare function loadEnvFiles(root?: string, mode?: string): LoadEnvResult;
|
|
7
|
+
|
|
8
|
+
export { type LoadEnvResult, envFilesFor, loadEnvFiles };
|
package/dist/node.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { parseEnv } from 'util';
|
|
4
|
+
|
|
5
|
+
// src/node.ts
|
|
6
|
+
function envFilesFor(root, mode) {
|
|
7
|
+
return [`.env.${mode}.local`, `.env.${mode}`, ".env.local", ".env"].map((file) => path.join(root, file)).filter((file) => existsSync(file));
|
|
8
|
+
}
|
|
9
|
+
function loadEnvFiles(root = process.cwd(), mode = process.env.NODE_ENV ?? "production") {
|
|
10
|
+
const files = envFilesFor(root, mode);
|
|
11
|
+
let injected = 0;
|
|
12
|
+
for (const file of files) {
|
|
13
|
+
let raw;
|
|
14
|
+
try {
|
|
15
|
+
raw = readFileSync(file, "utf8");
|
|
16
|
+
} catch {
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
if (raw.charCodeAt(0) === 65279) raw = raw.slice(1);
|
|
20
|
+
let parsed;
|
|
21
|
+
try {
|
|
22
|
+
parsed = parseEnv(raw);
|
|
23
|
+
} catch {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
27
|
+
if (value === void 0 || process.env[key] !== void 0) continue;
|
|
28
|
+
process.env[key] = value;
|
|
29
|
+
injected++;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return { files, injected };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export { envFilesFor, loadEnvFiles };
|
|
36
|
+
//# sourceMappingURL=node.js.map
|
|
37
|
+
//# sourceMappingURL=node.js.map
|
package/dist/node.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/node.ts"],"names":[],"mappings":";;;;;AAIO,SAAS,WAAA,CAAY,MAAc,IAAA,EAAwB;AAChE,EAAA,OAAO,CAAC,CAAA,KAAA,EAAQ,IAAI,CAAA,MAAA,CAAA,EAAU,CAAA,KAAA,EAAQ,IAAI,CAAA,CAAA,EAAI,YAAA,EAAc,MAAM,CAAA,CAC/D,GAAA,CAAI,CAAC,SAAS,IAAA,CAAK,IAAA,CAAK,IAAA,EAAM,IAAI,CAAC,CAAA,CACnC,OAAO,CAAC,IAAA,KAAS,UAAA,CAAW,IAAI,CAAC,CAAA;AACtC;AAOO,SAAS,YAAA,CACd,OAAe,OAAA,CAAQ,GAAA,IACvB,IAAA,GAAe,OAAA,CAAQ,GAAA,CAAI,QAAA,IAAY,YAAA,EACxB;AACf,EAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,IAAA,EAAM,IAAI,CAAA;AACpC,EAAA,IAAI,QAAA,GAAW,CAAA;AAEf,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AACF,MAAA,GAAA,GAAM,YAAA,CAAa,MAAM,MAAM,CAAA;AAAA,IACjC,CAAA,CAAA,MAAQ;AACN,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,GAAA,CAAI,WAAW,CAAC,CAAA,KAAM,OAAQ,GAAA,GAAM,GAAA,CAAI,MAAM,CAAC,CAAA;AAEnD,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAA,GAAS,SAAS,GAAG,CAAA;AAAA,IACvB,CAAA,CAAA,MAAQ;AACN,MAAA;AAAA,IACF;AAEA,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AACjD,MAAA,IAAI,UAAU,MAAA,IAAa,OAAA,CAAQ,GAAA,CAAI,GAAG,MAAM,MAAA,EAAW;AAC3D,MAAA,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA,GAAI,KAAA;AACnB,MAAA,QAAA,EAAA;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,OAAO,QAAA,EAAS;AAC3B","file":"node.js","sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport path from 'node:path';\nimport { parseEnv } from 'node:util';\n\nexport function envFilesFor(root: string, mode: string): string[] {\n return [`.env.${mode}.local`, `.env.${mode}`, '.env.local', '.env']\n .map((file) => path.join(root, file))\n .filter((file) => existsSync(file));\n}\n\nexport interface LoadEnvResult {\n files: string[];\n injected: number;\n}\n\nexport function loadEnvFiles(\n root: string = process.cwd(),\n mode: string = process.env.NODE_ENV ?? 'production',\n): LoadEnvResult {\n const files = envFilesFor(root, mode);\n let injected = 0;\n\n for (const file of files) {\n let raw: string;\n try {\n raw = readFileSync(file, 'utf8');\n } catch {\n continue;\n }\n\n if (raw.charCodeAt(0) === 0xfeff) raw = raw.slice(1);\n\n let parsed: Record<string, string | undefined>;\n try {\n parsed = parseEnv(raw) as Record<string, string | undefined>;\n } catch {\n continue;\n }\n\n for (const [key, value] of Object.entries(parsed)) {\n if (value === undefined || process.env[key] !== undefined) continue;\n process.env[key] = value;\n injected++;\n }\n }\n\n return { files, injected };\n}"]}
|
package/dist/vite.d.ts
ADDED
package/dist/vite.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { existsSync } from 'fs';
|
|
3
|
+
import { loadEnv } from 'vite';
|
|
4
|
+
|
|
5
|
+
// src/vite.ts
|
|
6
|
+
var ENV_PREFIXES = ["BINI_", "VITE_"];
|
|
7
|
+
var SECRET_NAME = /SECRET|PASSWORD|PASSWD|PRIVATE|TOKEN/i;
|
|
8
|
+
var C = {
|
|
9
|
+
CYAN: "\x1B[36m",
|
|
10
|
+
YELLOW: "\x1B[33m",
|
|
11
|
+
GREEN: "\x1B[32m",
|
|
12
|
+
BOLD: "\x1B[1m",
|
|
13
|
+
DIM: "\x1B[2m",
|
|
14
|
+
RESET: "\x1B[0m"
|
|
15
|
+
};
|
|
16
|
+
var biniLogger = {
|
|
17
|
+
warn(msg) {
|
|
18
|
+
const ts = `${C.DIM}${(/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", { hour12: false })}${C.RESET}`;
|
|
19
|
+
console.warn(`${ts} ${C.YELLOW}${C.BOLD}(!) [bini-env]${C.RESET} ${C.YELLOW}${msg}${C.RESET}`);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
function envFilesFor(root, mode) {
|
|
23
|
+
return [`.env.${mode}.local`, `.env.${mode}`, ".env.local", ".env"].map((file) => path.join(root, file)).filter((file) => existsSync(file));
|
|
24
|
+
}
|
|
25
|
+
var warnedPublicSecrets = /* @__PURE__ */ new Set();
|
|
26
|
+
function injectEnvIntoProcess(mode, envDir) {
|
|
27
|
+
const loaded = loadEnv(mode, envDir, "");
|
|
28
|
+
let injected = 0;
|
|
29
|
+
for (const [key, value] of Object.entries(loaded)) {
|
|
30
|
+
const isPrefixed = ENV_PREFIXES.some((p) => key.startsWith(p));
|
|
31
|
+
if (isPrefixed && SECRET_NAME.test(key) && !warnedPublicSecrets.has(key)) {
|
|
32
|
+
warnedPublicSecrets.add(key);
|
|
33
|
+
biniLogger.warn(
|
|
34
|
+
`"${key}" starts with a public prefix (${ENV_PREFIXES.join(" / ")}) so it is bundled into client code. Rename it without the prefix if it is a secret.`
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
if (value === void 0 || process.env[key] !== void 0) continue;
|
|
38
|
+
process.env[key] = value;
|
|
39
|
+
injected++;
|
|
40
|
+
}
|
|
41
|
+
return injected;
|
|
42
|
+
}
|
|
43
|
+
function hideReadyLine(logger) {
|
|
44
|
+
const originalInfo = logger.info.bind(logger);
|
|
45
|
+
logger.info = ((msg, options) => {
|
|
46
|
+
if (typeof msg === "string" && msg.includes("ready in")) return;
|
|
47
|
+
originalInfo(msg, options);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
function printBanner(server, label) {
|
|
51
|
+
const { root, mode } = server.config;
|
|
52
|
+
const originalPrintUrls = server.printUrls.bind(server);
|
|
53
|
+
server.printUrls = () => {
|
|
54
|
+
console.log(`
|
|
55
|
+
${C.CYAN}\xDF Bini.js${C.RESET} (${label})`);
|
|
56
|
+
const files = envFilesFor(root, mode).map((f) => path.basename(f));
|
|
57
|
+
if (files.length > 0) {
|
|
58
|
+
console.log(` ${C.GREEN}\u279C${C.RESET} Environments: ${files.join(", ")}`);
|
|
59
|
+
}
|
|
60
|
+
originalPrintUrls();
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function biniEnv() {
|
|
64
|
+
return {
|
|
65
|
+
name: "bini-env",
|
|
66
|
+
enforce: "pre",
|
|
67
|
+
config(userConfig, { command, mode }) {
|
|
68
|
+
if (userConfig.envDir !== false) {
|
|
69
|
+
const root = path.resolve(userConfig.root ?? process.cwd());
|
|
70
|
+
const envDir = typeof userConfig.envDir === "string" ? path.resolve(root, userConfig.envDir) : root;
|
|
71
|
+
try {
|
|
72
|
+
if (command === "serve") {
|
|
73
|
+
injectEnvIntoProcess(mode, envDir);
|
|
74
|
+
} else {
|
|
75
|
+
const loaded = loadEnv(mode, envDir, [...ENV_PREFIXES]);
|
|
76
|
+
for (const key of Object.keys(loaded)) {
|
|
77
|
+
if (SECRET_NAME.test(key) && !warnedPublicSecrets.has(key)) {
|
|
78
|
+
warnedPublicSecrets.add(key);
|
|
79
|
+
biniLogger.warn(
|
|
80
|
+
`"${key}" starts with a public prefix (${ENV_PREFIXES.join(" / ")}) so it is bundled into client code. Rename it without the prefix if it is a secret.`
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
} catch (err) {
|
|
86
|
+
biniLogger.warn(`Failed to load .env files: ${err.message}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return { envPrefix: [...ENV_PREFIXES] };
|
|
90
|
+
},
|
|
91
|
+
configureServer(server) {
|
|
92
|
+
hideReadyLine(server.config.logger);
|
|
93
|
+
printBanner(server, "dev");
|
|
94
|
+
},
|
|
95
|
+
configurePreviewServer(server) {
|
|
96
|
+
hideReadyLine(server.config.logger);
|
|
97
|
+
printBanner(server, "preview");
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export { biniEnv };
|
|
103
|
+
//# sourceMappingURL=vite.js.map
|
|
104
|
+
//# sourceMappingURL=vite.js.map
|
package/dist/vite.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/vite.ts"],"names":[],"mappings":"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","file":"vite.js","sourcesContent":["import path from 'node:path';\nimport { existsSync } from 'node:fs';\nimport { loadEnv } from 'vite';\nimport type { Logger, Plugin, PreviewServer, UserConfig, ViteDevServer } from 'vite';\n\nconst ENV_PREFIXES = ['BINI_', 'VITE_'] as const;\nconst SECRET_NAME = /SECRET|PASSWORD|PASSWD|PRIVATE|TOKEN/i;\n\nconst C = {\n CYAN: '\\x1b[36m',\n YELLOW: '\\x1b[33m',\n GREEN: '\\x1b[32m',\n BOLD: '\\x1b[1m',\n DIM: '\\x1b[2m',\n RESET: '\\x1b[0m',\n} as const;\n\nconst biniLogger = {\n warn(msg: string): void {\n const ts = `${C.DIM}${new Date().toLocaleTimeString('en-US', { hour12: false })}${C.RESET}`;\n console.warn(`${ts} ${C.YELLOW}${C.BOLD}(!) [bini-env]${C.RESET} ${C.YELLOW}${msg}${C.RESET}`);\n },\n} as const;\n\nfunction envFilesFor(root: string, mode: string): string[] {\n return [`.env.${mode}.local`, `.env.${mode}`, '.env.local', '.env']\n .map((file) => path.join(root, file))\n .filter((file) => existsSync(file));\n}\n\nconst warnedPublicSecrets = new Set<string>();\n\nfunction injectEnvIntoProcess(mode: string, envDir: string): number {\n const loaded = loadEnv(mode, envDir, '');\n let injected = 0;\n\n for (const [key, value] of Object.entries(loaded)) {\n const isPrefixed = ENV_PREFIXES.some((p) => key.startsWith(p));\n\n if (isPrefixed && SECRET_NAME.test(key) && !warnedPublicSecrets.has(key)) {\n warnedPublicSecrets.add(key);\n biniLogger.warn(\n `\"${key}\" starts with a public prefix (${ENV_PREFIXES.join(' / ')}) so it is bundled into client code. ` +\n `Rename it without the prefix if it is a secret.`,\n );\n }\n\n if (value === undefined || process.env[key] !== undefined) continue;\n process.env[key] = value;\n injected++;\n }\n\n return injected;\n}\n\nfunction hideReadyLine(logger: Logger): void {\n const originalInfo = logger.info.bind(logger);\n logger.info = ((msg: string, options?: Parameters<Logger['info']>[1]) => {\n if (typeof msg === 'string' && msg.includes('ready in')) return;\n originalInfo(msg, options);\n }) as Logger['info'];\n}\n\nfunction printBanner(server: ViteDevServer | PreviewServer, label: 'dev' | 'preview'): void {\n const { root, mode } = server.config;\n const originalPrintUrls = server.printUrls.bind(server);\n\n server.printUrls = () => {\n console.log(`\\n ${C.CYAN}ß Bini.js${C.RESET} (${label})`);\n const files = envFilesFor(root, mode).map((f) => path.basename(f));\n if (files.length > 0) {\n console.log(` ${C.GREEN}➜${C.RESET} Environments: ${files.join(', ')}`);\n }\n originalPrintUrls();\n };\n}\n\nexport function biniEnv(): Plugin {\n return {\n name: 'bini-env',\n enforce: 'pre',\n\n config(userConfig: UserConfig, { command, mode }): UserConfig {\n if (userConfig.envDir !== false) {\n const root = path.resolve(userConfig.root ?? process.cwd());\n const envDir =\n typeof userConfig.envDir === 'string'\n ? path.resolve(root, userConfig.envDir)\n : root;\n\n try {\n if (command === 'serve') {\n injectEnvIntoProcess(mode, envDir);\n } else {\n const loaded = loadEnv(mode, envDir, [...ENV_PREFIXES]);\n for (const key of Object.keys(loaded)) {\n if (SECRET_NAME.test(key) && !warnedPublicSecrets.has(key)) {\n warnedPublicSecrets.add(key);\n biniLogger.warn(\n `\"${key}\" starts with a public prefix (${ENV_PREFIXES.join(' / ')}) so it is bundled into client code. ` +\n `Rename it without the prefix if it is a secret.`,\n );\n }\n }\n }\n } catch (err) {\n biniLogger.warn(`Failed to load .env files: ${(err as Error).message}`);\n }\n }\n return { envPrefix: [...ENV_PREFIXES] };\n },\n\n configureServer(server) {\n hideReadyLine(server.config.logger);\n printBanner(server, 'dev');\n },\n\n configurePreviewServer(server) {\n hideReadyLine(server.config.logger);\n printBanner(server, 'preview');\n },\n };\n}\n\nexport type { Plugin } from 'vite';"]}
|
package/package.json
CHANGED
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bini-env",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Universal environment variable loader and Vite plugin for Bini.js
|
|
5
|
-
"
|
|
3
|
+
"version": "2.0.1",
|
|
4
|
+
"description": "Universal environment variable loader and Vite plugin for Bini.js",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
6
7
|
"module": "./dist/index.js",
|
|
7
8
|
"types": "./dist/index.d.ts",
|
|
8
9
|
"exports": {
|
|
9
10
|
".": {
|
|
10
11
|
"types": "./dist/index.d.ts",
|
|
11
|
-
"
|
|
12
|
-
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./vite": {
|
|
15
|
+
"types": "./dist/vite.d.ts",
|
|
16
|
+
"default": "./dist/vite.js"
|
|
17
|
+
},
|
|
18
|
+
"./node": {
|
|
19
|
+
"types": "./dist/node.d.ts",
|
|
20
|
+
"default": "./dist/node.js"
|
|
13
21
|
}
|
|
14
22
|
},
|
|
15
23
|
"files": [
|
|
@@ -17,13 +25,16 @@
|
|
|
17
25
|
"README.md",
|
|
18
26
|
"LICENSE"
|
|
19
27
|
],
|
|
20
|
-
"sideEffects":
|
|
28
|
+
"sideEffects": [
|
|
29
|
+
"./dist/vite.js"
|
|
30
|
+
],
|
|
21
31
|
"scripts": {
|
|
22
32
|
"build": "tsup",
|
|
23
33
|
"dev": "tsup --watch",
|
|
24
|
-
"prepublishOnly": "npm run build",
|
|
34
|
+
"prepublishOnly": "npm run build && npm run check:edge",
|
|
25
35
|
"test": "node --test",
|
|
26
|
-
"type-check": "tsc --noEmit"
|
|
36
|
+
"type-check": "tsc --noEmit",
|
|
37
|
+
"check:edge": "node -e \"const fs=require('fs');const s=fs.readFileSync('dist/index.js','utf8');const re=/(?:from\\s*['\\\"]|require\\(\\s*['\\\"])(node:|vite)/;if(re.test(s)){console.error('[bini-env] edge entry leaks node:/vite imports:');console.error(s.match(re)[0]);process.exit(1)}else{console.log('[bini-env] dist/index.js is edge-safe')}\""
|
|
27
38
|
},
|
|
28
39
|
"keywords": [
|
|
29
40
|
"vite",
|
|
@@ -65,18 +76,18 @@
|
|
|
65
76
|
"optional": false
|
|
66
77
|
},
|
|
67
78
|
"vite": {
|
|
68
|
-
"optional":
|
|
79
|
+
"optional": true
|
|
69
80
|
}
|
|
70
81
|
},
|
|
71
82
|
"devDependencies": {
|
|
72
|
-
"@types/node": "
|
|
83
|
+
"@types/node": "^22.10.0",
|
|
73
84
|
"hono": "^4.8.4",
|
|
74
85
|
"tsup": "^8.5.1",
|
|
75
86
|
"typescript": "^5.8.3",
|
|
76
87
|
"vite": "^8.0.8"
|
|
77
88
|
},
|
|
78
89
|
"engines": {
|
|
79
|
-
"node": ">=20.
|
|
90
|
+
"node": ">=20.12.0"
|
|
80
91
|
},
|
|
81
92
|
"publishConfig": {
|
|
82
93
|
"access": "public",
|
package/dist/index.d.mts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { Context } from 'hono';
|
|
2
|
-
import { Plugin } from 'vite';
|
|
3
|
-
export { Plugin } from 'vite';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* bini-env/src/index.ts
|
|
7
|
-
*
|
|
8
|
-
* Two responsibilities only:
|
|
9
|
-
* 1. Tell Vite which env prefixes to expose to import.meta.env (biniEnv plugin)
|
|
10
|
-
* 2. Read env vars from the Hono request context (getEnv / requireEnv)
|
|
11
|
-
*
|
|
12
|
-
* process.env is never used. All runtime env access goes through Hono's env() adapter,
|
|
13
|
-
* which handles Node, Bun, Cloudflare Workers, Deno, and Vercel Edge natively.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Accepts any Hono Context. Typed against Hono's own Context rather than a
|
|
18
|
-
* loose duck type so misuse is caught at the call site.
|
|
19
|
-
*/
|
|
20
|
-
type HonoContext = Context;
|
|
21
|
-
interface BiniEnvPluginOptions {
|
|
22
|
-
/** Extra prefixes to expose to import.meta.env, in addition to BINI_ and VITE_. */
|
|
23
|
-
readonly envPrefix?: string | string[];
|
|
24
|
-
}
|
|
25
|
-
declare const biniLogger: {
|
|
26
|
-
readonly info: (msg: string) => void;
|
|
27
|
-
readonly warn: (msg: string) => void;
|
|
28
|
-
readonly error: (msg: string, err?: unknown) => void;
|
|
29
|
-
};
|
|
30
|
-
declare function getEnv(c: HonoContext, key: string): string | undefined;
|
|
31
|
-
declare function requireEnv(c: HonoContext, key: string): string;
|
|
32
|
-
declare function biniEnv(options?: Readonly<BiniEnvPluginOptions>): Plugin;
|
|
33
|
-
|
|
34
|
-
export { type BiniEnvPluginOptions, type HonoContext, biniEnv, biniLogger, getEnv, requireEnv };
|