@stacksjs/env 0.75.72 → 0.75.74
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.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/numeric-keys.d.ts +22 -0
- package/dist/numeric-keys.js +1 -0
- package/dist/runtime.js +1 -1
- package/dist/types.js +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./runtime";export*from"./deployment";export*from"./integrations";export*from"./types";export*from"./crypto";export*from"./parser";export*from"./plugin";export*from"./cli";export*from"./plaintext";export*from"./tenants";export*from"./utils";
|
|
1
|
+
export*from"./runtime";export*from"./numeric-keys";export*from"./deployment";export*from"./integrations";export*from"./types";export*from"./crypto";export*from"./parser";export*from"./plugin";export*from"./cli";export*from"./plaintext";export*from"./tenants";export*from"./utils";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Record the variables an app's `config/env.ts` validates as numbers, so the
|
|
3
|
+
* proxy hands them over as numbers too. Called by `defineEnv()`.
|
|
4
|
+
*/
|
|
5
|
+
export declare function registerNumericEnvKeys(schema: Record<string, unknown>): void;
|
|
6
|
+
/** Whether a variable was declared as a number, by the framework or the app. */
|
|
7
|
+
export declare function isDeclaredNumericEnvKey(key: string): boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Which environment variables hold numbers.
|
|
10
|
+
*
|
|
11
|
+
* The proxy used to decide by name suffix alone (`_PORT`, `_TTL`, ...), so 21
|
|
12
|
+
* of the 26 framework variables typed `number` in `types.ts` came back as
|
|
13
|
+
* strings: every `PORT_*`, the database pool's `*_MS`, and the auth lifetimes.
|
|
14
|
+
* `AUTH_TOKEN_EXPIRY=7200000` in `.env` made `Date.now() + tokenExpiry` a
|
|
15
|
+
* string concatenation, and every token issued after it carried an
|
|
16
|
+
* `Invalid Date`. The type said number; nothing made it one.
|
|
17
|
+
*
|
|
18
|
+
* Kept in step with `types.ts` by `numeric-keys.test.ts`.
|
|
19
|
+
*/
|
|
20
|
+
export declare const FRAMEWORK_NUMERIC_ENV_KEYS: ReadonlySet<string>;
|
|
21
|
+
/** Name suffixes that have always meant a number, for variables nothing declared. */
|
|
22
|
+
export declare const NUMERIC_ENV_SUFFIXES: readonly string[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const FRAMEWORK_NUMERIC_ENV_KEYS=new Set(["PORT","PORT_BACKEND","PORT_ADMIN","PORT_LIBRARY","PORT_DESKTOP","PORT_EMAIL","PORT_DOCS","PORT_INSPECT","PORT_API","PORT_SYSTEM_TRAY","DB_PORT","DB_POOL_MAX","DB_POOL_IDLE_TIMEOUT_MS","DB_POOL_ACQUIRE_TIMEOUT_MS","DB_QUERY_LOGGING_SLOW_THRESHOLD","DB_QUERY_LOGGING_RETENTION_DAYS","DB_QUERY_LOGGING_PRUNE_FREQUENCY","MAIL_PORT","STRIPE_CONNECT_FEE_PERCENT","BROADCAST_PORT","REDIS_PORT","AUTH_TOKEN_EXPIRY","AUTH_REFRESH_TOKEN_EXPIRY","AUTH_TOKEN_ROTATION","AUTH_PASSWORD_RESET_EXPIRE","AUTH_PASSWORD_RESET_THROTTLE"]),NUMERIC_ENV_SUFFIXES=["_PORT","_TIMEOUT","_TTL","_SIZE","_LIMIT","_MAX","_MIN","_INTERVAL","_RETRIES","_CONCURRENCY","_WORKERS","_CONNECTIONS"];const declaredNumericKeys=new Set;export function registerNumericEnvKeys(schema){for(const[key,entry]of Object.entries(schema))if(entry?.validation?.name==="number")declaredNumericKeys.add(key)}export function isDeclaredNumericEnvKey(key){return FRAMEWORK_NUMERIC_ENV_KEYS.has(key)||declaredNumericKeys.has(key)}
|
package/dist/runtime.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var {require}=import.meta;import p from"node:process";import{projectPath}from"@stacksjs/path";import fs from"node:fs";import{envEnum}from"./types";let decryptionRuntime;function getDecryptionRuntime(){decryptionRuntime||=require("./plugin");return decryptionRuntime}const warnedUndecryptable=new Set;function warnUndecryptable(key){if(warnedUndecryptable.has(key))return;warnedUndecryptable.add(key);const envName=getDecryptionRuntime().activeEnvName();console.warn(`[env] warning: "${key}" is encrypted but no usable private key was found for the "${envName}" environment; falling back to its default. Set DOTENV_PRIVATE_KEY_${envName.toUpperCase()} or ship .env.keys.`)}const handler={get:(target,key)=>{const bag=target;let value=bag[key];if(typeof value==="string"&&(value.startsWith("encrypted:")||value.startsWith("enc:"))){const decrypted=getDecryptionRuntime().decryptEnvValue(value);if(decrypted===void 0){warnUndecryptable(key);delete bag[key];return}bag[key]=decrypted;value=decrypted}
|
|
1
|
+
var {require}=import.meta;import p from"node:process";import{projectPath}from"@stacksjs/path";import fs from"node:fs";import{isDeclaredNumericEnvKey,NUMERIC_ENV_SUFFIXES}from"./numeric-keys";import{envEnum}from"./types";let decryptionRuntime;function getDecryptionRuntime(){decryptionRuntime||=require("./plugin");return decryptionRuntime}const warnedUndecryptable=new Set;function warnUndecryptable(key){if(warnedUndecryptable.has(key))return;warnedUndecryptable.add(key);const envName=getDecryptionRuntime().activeEnvName();console.warn(`[env] warning: "${key}" is encrypted but no usable private key was found for the "${envName}" environment; falling back to its default. Set DOTENV_PRIVATE_KEY_${envName.toUpperCase()} or ship .env.keys.`)}const handler={get:(target,key)=>{const bag=target;let value=bag[key];if(typeof value==="string"&&(value.startsWith("encrypted:")||value.startsWith("enc:"))){const decrypted=getDecryptionRuntime().decryptEnvValue(value);if(decrypted===void 0){warnUndecryptable(key);delete bag[key];return}bag[key]=decrypted;value=decrypted}if(typeof value==="string"&&isDeclaredNumericEnvKey(key)&&/^-?\d+(?:\.\d+)?$/.test(value.trim()))return Number(value);if(typeof value==="string"&&/^\d+$/.test(value)&&(value==="0"||!value.startsWith("0"))&&NUMERIC_ENV_SUFFIXES.some((s)=>key.endsWith(s)))return Number(value);if(typeof value==="string"){const lower=value.toLowerCase();if(lower==="true")return!0;if(lower==="false")return!1}return value},set:(target,key,value)=>{return Reflect.set(target,key,value,target)},deleteProperty:(target,key)=>Reflect.deleteProperty(target,key)};export function process(){return typeof Bun<"u"?Bun.env:p.env}export const env=new Proxy(process(),handler);export function writeEnv(key,value,options){const envPath=options?.path||projectPath(".env"),lines=fs.readFileSync(envPath,"utf-8").split(`
|
|
2
2
|
`),index=lines.findIndex((line)=>line.startsWith(`${key}=`)),quotedValue=/[\s"'#$\\]/.test(value)?`"${value.replace(/"/g,"\\\"")}"`:value;if(index!==-1)lines[index]=`${key}=${quotedValue}`;else lines.push(`${key}=${quotedValue}`);fs.writeFileSync(envPath,lines.join(`
|
|
3
3
|
`))}export function validateEnv(envProxy=env){const errors=[],bag=envProxy;for(const[key,allowedValues]of Object.entries(envEnum)){const value=bag[key];if(value!==void 0&&value!==""&&!allowedValues.includes(String(value)))errors.push(`${key}="${value}" is not valid. Allowed values: ${allowedValues.join(", ")}`)}return errors}export function requireEnv(keys,envProxy=env){const missing=[],bag=envProxy;for(const key of keys){const value=bag[key];if(value===void 0||value===""||value===null)missing.push(key)}if(missing.length>0)throw Error(`[env] Missing required environment variable(s): ${missing.join(", ")}. Set them in .env or your process environment before booting.`);return envProxy}
|
package/dist/types.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const envEnum={APP_ENV:["local","dev","development","staging","prod","production"],DB_CONNECTION:["mysql","sqlite","postgres","singlestore","vitess","turso","libsql","dynamodb"],DB_MIGRATE_FRESH:["allow","confirm","disabled"],MAIL_MAILER:["smtp","mailgun","ses","log","sendgrid","mailtrap","capture"],SEARCH_ENGINE_DRIVER:["opensearch","meilisearch","algolia","typesense"],FRONTEND_APP_ENV:["development","staging","production"]};export function defineEnv(schema){return schema}
|
|
1
|
+
import{registerNumericEnvKeys}from"./numeric-keys";export const envEnum={APP_ENV:["local","dev","development","staging","prod","production"],DB_CONNECTION:["mysql","sqlite","postgres","singlestore","vitess","turso","libsql","dynamodb"],DB_MIGRATE_FRESH:["allow","confirm","disabled"],MAIL_MAILER:["smtp","mailgun","ses","log","sendgrid","mailtrap","capture"],SEARCH_ENGINE_DRIVER:["opensearch","meilisearch","algolia","typesense"],FRONTEND_APP_ENV:["development","staging","production"]};export function defineEnv(schema){registerNumericEnvKeys(schema);return schema}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/env",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.75.
|
|
5
|
+
"version": "0.75.74",
|
|
6
6
|
"description": "Stacks env helper methods.",
|
|
7
7
|
"author": "Chris Breuer",
|
|
8
8
|
"contributors": [
|
|
@@ -56,10 +56,10 @@
|
|
|
56
56
|
"prepublishOnly": "bun run build"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@stacksjs/path": "0.75.
|
|
59
|
+
"@stacksjs/path": "0.75.74"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"better-dx": "^0.2.24",
|
|
63
|
-
"@stacksjs/validation": "0.75.
|
|
63
|
+
"@stacksjs/validation": "0.75.74"
|
|
64
64
|
}
|
|
65
65
|
}
|