bosia 0.8.15 → 0.8.16
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 +1 -1
- package/package.json +1 -1
- package/src/core/env.ts +25 -6
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ File-based routing inspired by SvelteKit, built on top of the Bun runtime and El
|
|
|
18
18
|
- **Dev server with HMR** — file watcher + SSE browser reload, no page blink
|
|
19
19
|
- **Tailwind CSS v4** — compiled at build time, shadcn-inspired design tokens out of the box
|
|
20
20
|
- **CLI** — `bosia create`, `bosia dev`, `bosia build`, `bosia add`, `bosia feat`
|
|
21
|
-
- **UI registry** — shadcn-style, copy-paste source you own: **
|
|
21
|
+
- **UI registry** — shadcn-style, copy-paste source you own: **61 components**, **162 blocks**, **23 pages**, **19 themes**
|
|
22
22
|
|
|
23
23
|
## UI Registry
|
|
24
24
|
|
package/package.json
CHANGED
package/src/core/env.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "fs";
|
|
1
|
+
import { existsSync, readdirSync, readFileSync } from "fs";
|
|
2
2
|
import { join } from "path";
|
|
3
3
|
|
|
4
4
|
// ─── Framework-reserved vars ─────────────────────────────
|
|
@@ -26,6 +26,9 @@ const FRAMEWORK_VARS = new Set([
|
|
|
26
26
|
/** Valid JS/TS identifier: starts with letter/underscore, then alphanumeric/underscore. */
|
|
27
27
|
const VALID_ENV_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
28
28
|
|
|
29
|
+
/** `.env`, `.env.production`, `.env.example`, … — but not `.envrc` or other `.env`-prefixed files. */
|
|
30
|
+
const ENV_FILE_RE = /^\.env(\..+)?$/;
|
|
31
|
+
|
|
29
32
|
/** Process escape sequences in double-quoted values. */
|
|
30
33
|
function processEscapes(raw: string): string {
|
|
31
34
|
return raw.replace(/\\(.)/g, (_, ch) => {
|
|
@@ -119,9 +122,13 @@ export function parseEnvFile(content: string, filename?: string): Record<string,
|
|
|
119
122
|
* 3. .env.[mode]
|
|
120
123
|
* 4. .env.[mode].local
|
|
121
124
|
*
|
|
125
|
+
* Variable *names* additionally come from every other `.env*` file present
|
|
126
|
+
* (`.env.production`, `.env.example`, …) with an empty value, so the `$env`
|
|
127
|
+
* export surface is the same in dev, prod and CI.
|
|
128
|
+
*
|
|
122
129
|
* @param mode "development" | "production"
|
|
123
130
|
* @param dir directory to look in (defaults to cwd)
|
|
124
|
-
* @returns merged env record (only vars
|
|
131
|
+
* @returns merged env record (only vars declared in .env files, excluding framework vars)
|
|
125
132
|
*/
|
|
126
133
|
export function loadEnv(mode: string, dir?: string): Record<string, string> {
|
|
127
134
|
const root = dir ?? process.cwd();
|
|
@@ -143,12 +150,24 @@ export function loadEnv(mode: string, dir?: string): Record<string, string> {
|
|
|
143
150
|
console.log(`✓ Loaded ${loaded.join(", ")}`);
|
|
144
151
|
}
|
|
145
152
|
|
|
153
|
+
// Names come from every `.env*` present, values only from the mode's files.
|
|
154
|
+
// Keeps the $env export surface identical in dev, prod and CI — mode decides
|
|
155
|
+
// only which names carry a value. A malformed off-mode file throws here
|
|
156
|
+
// rather than at deploy time.
|
|
157
|
+
const declaredNames = new Set(Object.keys(merged));
|
|
158
|
+
for (const entry of readdirSync(root, { withFileTypes: true })) {
|
|
159
|
+
if (!entry.isFile() || !ENV_FILE_RE.test(entry.name) || files.includes(entry.name)) continue;
|
|
160
|
+
const parsed = parseEnvFile(readFileSync(join(root, entry.name), "utf-8"), entry.name);
|
|
161
|
+
for (const key of Object.keys(parsed)) declaredNames.add(key);
|
|
162
|
+
}
|
|
163
|
+
|
|
146
164
|
// Track declared keys so html.ts only exposes .env-declared PUBLIC_* vars
|
|
147
|
-
for (const key of
|
|
165
|
+
for (const key of declaredNames) {
|
|
148
166
|
_declaredKeys.add(key);
|
|
149
167
|
}
|
|
150
168
|
|
|
151
|
-
// Apply to process.env — system env wins (don't overwrite existing)
|
|
169
|
+
// Apply to process.env — system env wins (don't overwrite existing).
|
|
170
|
+
// Name-only keys stay absent so `process.env.X ?? default` still falls back.
|
|
152
171
|
for (const [key, value] of Object.entries(merged)) {
|
|
153
172
|
if (!(key in process.env)) {
|
|
154
173
|
process.env[key] = value;
|
|
@@ -157,9 +176,9 @@ export function loadEnv(mode: string, dir?: string): Record<string, string> {
|
|
|
157
176
|
|
|
158
177
|
// Return only non-framework vars
|
|
159
178
|
const result: Record<string, string> = {};
|
|
160
|
-
for (const
|
|
179
|
+
for (const key of declaredNames) {
|
|
161
180
|
if (!FRAMEWORK_VARS.has(key)) {
|
|
162
|
-
result[key] = process.env[key] ??
|
|
181
|
+
result[key] = process.env[key] ?? merged[key] ?? "";
|
|
163
182
|
}
|
|
164
183
|
}
|
|
165
184
|
|