@lowerdeck/env 1.0.0
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/.turbo/turbo-build.log +11 -0
- package/.turbo/turbo-test.log +28 -0
- package/README.md +64 -0
- package/dist/env.d.ts +3 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.test.d.ts +2 -0
- package/dist/env.test.d.ts.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.modern.js +2 -0
- package/dist/index.modern.js.map +1 -0
- package/dist/index.module.js +2 -0
- package/dist/index.module.js.map +1 -0
- package/dist/index.umd.js +2 -0
- package/dist/index.umd.js.map +1 -0
- package/package.json +33 -0
- package/src/env.test.ts +38 -0
- package/src/env.ts +26 -0
- package/src/index.ts +1 -0
- package/tsconfig.json +11 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
[0m[2m[35m$[0m [2m[1mmicrobundle[0m
|
|
3
|
+
[34mBuild "@lowerdeck/env" to dist:[39m
|
|
4
|
+
[32m218 B[39m: [37mindex.cjs[39m.gz
|
|
5
|
+
[32m164 B[39m: [37mindex.cjs[39m.br
|
|
6
|
+
[32m212 B[39m: [37mindex.modern.js[39m.gz
|
|
7
|
+
[32m170 B[39m: [37mindex.modern.js[39m.br
|
|
8
|
+
[32m225 B[39m: [37mindex.module.js[39m.gz
|
|
9
|
+
[32m175 B[39m: [37mindex.module.js[39m.br
|
|
10
|
+
[32m304 B[39m: [37mindex.umd.js[39m.gz
|
|
11
|
+
[32m267 B[39m: [37mindex.umd.js[39m.br
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
|
|
2
|
+
[0m[2m[35m$[0m [2m[1mvitest run --passWithNoTests[0m
|
|
3
|
+
[?25l
|
|
4
|
+
[1m[46m RUN [49m[22m [36mv3.2.4 [39m[90m/Users/tobias/code/metorial/metorial-enterprise/oss/src/packages/backend/env[39m
|
|
5
|
+
|
|
6
|
+
[?2026h
|
|
7
|
+
[1m[33m ❯ [39m[22msrc/env.test.ts[2m [queued][22m
|
|
8
|
+
|
|
9
|
+
[2m Test Files [22m[1m[32m0 passed[39m[22m[90m (1)[39m
|
|
10
|
+
[2m Tests [22m[1m[32m0 passed[39m[22m[90m (0)[39m
|
|
11
|
+
[2m Start at [22m10:23:43
|
|
12
|
+
[2m Duration [22m102ms
|
|
13
|
+
[?2026l[?2026h[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K
|
|
14
|
+
[1m[33m ❯ [39m[22msrc/env.test.ts[2m 0/1[22m
|
|
15
|
+
|
|
16
|
+
[2m Test Files [22m[1m[32m0 passed[39m[22m[90m (1)[39m
|
|
17
|
+
[2m Tests [22m[1m[32m0 passed[39m[22m[90m (1)[39m
|
|
18
|
+
[2m Start at [22m10:23:43
|
|
19
|
+
[2m Duration [22m303ms
|
|
20
|
+
[?2026l[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K [32m✓[39m src/env.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 2[2mms[22m[39m
|
|
21
|
+
[32m✓[39m createValidatedEnv[2m > [22mvalidates env[32m 1[2mms[22m[39m
|
|
22
|
+
|
|
23
|
+
[2m Test Files [22m [1m[32m1 passed[39m[22m[90m (1)[39m
|
|
24
|
+
[2m Tests [22m [1m[32m1 passed[39m[22m[90m (1)[39m
|
|
25
|
+
[2m Start at [22m 10:23:43
|
|
26
|
+
[2m Duration [22m 335ms[2m (transform 97ms, setup 0ms, collect 128ms, tests 2ms, environment 0ms, prepare 37ms)[22m
|
|
27
|
+
|
|
28
|
+
[?25h
|
package/README.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# `@lowerdeck/env`
|
|
2
|
+
|
|
3
|
+
Type-safe environment variable validation. Ensure required environment variables exist and have proper types at application startup.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @lowerdeck/env
|
|
9
|
+
yarn add @lowerdeck/env
|
|
10
|
+
bun add @lowerdeck/env
|
|
11
|
+
pnpm add @lowerdeck/env
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
import { createValidatedEnv } from '@lowerdeck/env';
|
|
18
|
+
import { string, number, object } from '@lowerdeck/validation';
|
|
19
|
+
|
|
20
|
+
// Define environment schema
|
|
21
|
+
const env = createValidatedEnv(
|
|
22
|
+
object({
|
|
23
|
+
NODE_ENV: string().oneOf(['development', 'production', 'test']),
|
|
24
|
+
PORT: number().min(1).max(65535),
|
|
25
|
+
DATABASE_URL: string().url(),
|
|
26
|
+
API_KEY: string().min(32),
|
|
27
|
+
DEBUG: string().optional()
|
|
28
|
+
})
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
// Use validated environment variables
|
|
32
|
+
console.log(env.PORT); // number type
|
|
33
|
+
console.log(env.NODE_ENV); // 'development' | 'production' | 'test'
|
|
34
|
+
console.log(env.DATABASE_URL); // validated URL string
|
|
35
|
+
|
|
36
|
+
// Throws error if validation fails
|
|
37
|
+
// Error: Environment variable PORT is required
|
|
38
|
+
// Error: Environment variable DATABASE_URL must be a valid URL
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### With Default Values
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { createValidatedEnv } from '@lowerdeck/env';
|
|
45
|
+
import { string, number, object, optional } from '@lowerdeck/validation';
|
|
46
|
+
|
|
47
|
+
const env = createValidatedEnv(
|
|
48
|
+
object({
|
|
49
|
+
PORT: optional(number().min(1)).default(3000),
|
|
50
|
+
HOST: optional(string()).default('localhost'),
|
|
51
|
+
LOG_LEVEL: optional(string().oneOf(['debug', 'info', 'warn', 'error'])).default('info')
|
|
52
|
+
})
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
console.log(env.PORT); // 3000 if not set
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## License
|
|
59
|
+
|
|
60
|
+
This project is licensed under the Apache License 2.0.
|
|
61
|
+
|
|
62
|
+
<div align="center">
|
|
63
|
+
<sub>Built with ❤️ by <a href="https://metorial.com">Metorial</a></sub>
|
|
64
|
+
</div>
|
package/dist/env.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { ValidationType, ValidationTypeValue } from '@lowerdeck/validation';
|
|
2
|
+
export declare let createValidatedEnv: <Env extends Record<string, Record<string, ValidationType<any>>>>(env: Env) => { [K in keyof Env]: { [P in keyof Env[K]]: ValidationTypeValue<Env[K][P]>; }; };
|
|
3
|
+
//# sourceMappingURL=env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5E,eAAO,IAAI,kBAAkB,GAC3B,GAAG,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAE/D,KAAK,GAAG,KACP,GACA,CAAC,IAAI,MAAM,GAAG,GAAG,GACf,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GACpD,GAgBF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.test.d.ts","sourceRoot":"","sources":["../src/env.test.ts"],"names":[],"mappings":""}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
exports.createValidatedEnv=function(e){return Object.fromEntries(Object.entries(e).map(function(e){return[e[0],Object.fromEntries(Object.entries(e[1]).map(function(e){var r=e[0],t=e[1].validate(process.env[r]);if(!t.success)throw new Error("ENV VALIDATION: "+r+" - "+t.errors[0].message);return[r,t.value]}))]}))};
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/env.ts"],"sourcesContent":["import { ValidationType, ValidationTypeValue } from '@lowerdeck/validation';\n\nexport let createValidatedEnv = <\n Env extends Record<string, Record<string, ValidationType<any>>>\n>(\n env: Env\n): {\n [K in keyof Env]: {\n [P in keyof Env[K]]: ValidationTypeValue<Env[K][P]>;\n };\n} => {\n return Object.fromEntries(\n Object.entries(env).map(([key, value]) => [\n key,\n Object.fromEntries(\n Object.entries(value).map(([key, value]) => {\n let res = value.validate(process.env[key]);\n if (!res.success)\n throw new Error(`ENV VALIDATION: ${key} - ${res.errors[0].message}`);\n\n return [key, res.value];\n })\n )\n ])\n ) as any;\n};\n"],"names":["env","Object","fromEntries","entries","map","_ref","_ref2","key","res","validate","process","success","Error","errors","message","value"],"mappings":"2BAEgC,SAG9BA,GAMA,OAAOC,OAAOC,YACZD,OAAOE,QAAQH,GAAKI,IAAI,SAAAC,GAAY,MAAM,CAAbA,EAAA,GAE3BJ,OAAOC,YACLD,OAAOE,QAHyBE,EAAA,IAGVD,IAAI,SAAAE,GAAiB,IAAfC,EAAGD,EAAA,GACzBE,EADgCF,EAAA,GACpBG,SAASC,QAAQV,IAAIO,IACrC,IAAKC,EAAIG,QACP,MAAM,IAAIC,MAAK,mBAAoBL,EAAG,MAAMC,EAAIK,OAAO,GAAGC,SAE5D,MAAO,CAACP,EAAKC,EAAIO,MACnB,IAEH,GAEL"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
let e=e=>Object.fromEntries(Object.entries(e).map(([e,r])=>[e,Object.fromEntries(Object.entries(r).map(([e,r])=>{let t=r.validate(process.env[e]);if(!t.success)throw new Error(`ENV VALIDATION: ${e} - ${t.errors[0].message}`);return[e,t.value]}))]));export{e as createValidatedEnv};
|
|
2
|
+
//# sourceMappingURL=index.modern.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.modern.js","sources":["../src/env.ts"],"sourcesContent":["import { ValidationType, ValidationTypeValue } from '@lowerdeck/validation';\n\nexport let createValidatedEnv = <\n Env extends Record<string, Record<string, ValidationType<any>>>\n>(\n env: Env\n): {\n [K in keyof Env]: {\n [P in keyof Env[K]]: ValidationTypeValue<Env[K][P]>;\n };\n} => {\n return Object.fromEntries(\n Object.entries(env).map(([key, value]) => [\n key,\n Object.fromEntries(\n Object.entries(value).map(([key, value]) => {\n let res = value.validate(process.env[key]);\n if (!res.success)\n throw new Error(`ENV VALIDATION: ${key} - ${res.errors[0].message}`);\n\n return [key, res.value];\n })\n )\n ])\n ) as any;\n};\n"],"names":["createValidatedEnv","env","Object","fromEntries","entries","map","key","value","res","validate","process","success","Error","errors","message"],"mappings":"AAEW,IAAAA,EAGTC,GAMOC,OAAOC,YACZD,OAAOE,QAAQH,GAAKI,IAAI,EAAEC,EAAKC,KAAW,CACxCD,EACAJ,OAAOC,YACLD,OAAOE,QAAQG,GAAOF,IAAI,EAAEC,EAAKC,MAC/B,IAAIC,EAAMD,EAAME,SAASC,QAAQT,IAAIK,IACrC,IAAKE,EAAIG,QACP,MAAU,IAAAC,MAAM,mBAAmBN,OAASE,EAAIK,OAAO,GAAGC,WAE5D,MAAO,CAACR,EAAKE,EAAID"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e=function(e){return Object.fromEntries(Object.entries(e).map(function(e){return[e[0],Object.fromEntries(Object.entries(e[1]).map(function(e){var r=e[0],t=e[1].validate(process.env[r]);if(!t.success)throw new Error("ENV VALIDATION: "+r+" - "+t.errors[0].message);return[r,t.value]}))]}))};export{e as createValidatedEnv};
|
|
2
|
+
//# sourceMappingURL=index.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.module.js","sources":["../src/env.ts"],"sourcesContent":["import { ValidationType, ValidationTypeValue } from '@lowerdeck/validation';\n\nexport let createValidatedEnv = <\n Env extends Record<string, Record<string, ValidationType<any>>>\n>(\n env: Env\n): {\n [K in keyof Env]: {\n [P in keyof Env[K]]: ValidationTypeValue<Env[K][P]>;\n };\n} => {\n return Object.fromEntries(\n Object.entries(env).map(([key, value]) => [\n key,\n Object.fromEntries(\n Object.entries(value).map(([key, value]) => {\n let res = value.validate(process.env[key]);\n if (!res.success)\n throw new Error(`ENV VALIDATION: ${key} - ${res.errors[0].message}`);\n\n return [key, res.value];\n })\n )\n ])\n ) as any;\n};\n"],"names":["createValidatedEnv","env","Object","fromEntries","entries","map","_ref","_ref2","key","res","validate","process","success","Error","errors","message","value"],"mappings":"AAEW,IAAAA,EAAqB,SAG9BC,GAMA,OAAOC,OAAOC,YACZD,OAAOE,QAAQH,GAAKI,IAAI,SAAAC,GAAY,MAAM,CAAbA,EAAA,GAE3BJ,OAAOC,YACLD,OAAOE,QAHyBE,EAAA,IAGVD,IAAI,SAAAE,GAAiB,IAAfC,EAAGD,EAAA,GACzBE,EADgCF,EAAA,GACpBG,SAASC,QAAQV,IAAIO,IACrC,IAAKC,EAAIG,QACP,MAAM,IAAIC,MAAK,mBAAoBL,EAAG,MAAMC,EAAIK,OAAO,GAAGC,SAE5D,MAAO,CAACP,EAAKC,EAAIO,MACnB,IAEH,GAEL"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e||self).env={})}(this,function(e){e.createValidatedEnv=function(e){return Object.fromEntries(Object.entries(e).map(function(e){return[e[0],Object.fromEntries(Object.entries(e[1]).map(function(e){var n=e[0],t=e[1].validate(process.env[n]);if(!t.success)throw new Error("ENV VALIDATION: "+n+" - "+t.errors[0].message);return[n,t.value]}))]}))}});
|
|
2
|
+
//# sourceMappingURL=index.umd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.umd.js","sources":["../src/env.ts"],"sourcesContent":["import { ValidationType, ValidationTypeValue } from '@lowerdeck/validation';\n\nexport let createValidatedEnv = <\n Env extends Record<string, Record<string, ValidationType<any>>>\n>(\n env: Env\n): {\n [K in keyof Env]: {\n [P in keyof Env[K]]: ValidationTypeValue<Env[K][P]>;\n };\n} => {\n return Object.fromEntries(\n Object.entries(env).map(([key, value]) => [\n key,\n Object.fromEntries(\n Object.entries(value).map(([key, value]) => {\n let res = value.validate(process.env[key]);\n if (!res.success)\n throw new Error(`ENV VALIDATION: ${key} - ${res.errors[0].message}`);\n\n return [key, res.value];\n })\n )\n ])\n ) as any;\n};\n"],"names":["env","Object","fromEntries","entries","map","_ref","_ref2","key","res","validate","process","success","Error","errors","message","value"],"mappings":"kPAEgC,SAG9BA,GAMA,OAAOC,OAAOC,YACZD,OAAOE,QAAQH,GAAKI,IAAI,SAAAC,GAAY,MAAM,CAAbA,EAAA,GAE3BJ,OAAOC,YACLD,OAAOE,QAHyBE,EAAA,IAGVD,IAAI,SAAAE,GAAiB,IAAfC,EAAGD,EAAA,GACzBE,EADgCF,EAAA,GACpBG,SAASC,QAAQV,IAAIO,IACrC,IAAKC,EAAIG,QACP,MAAM,IAAIC,MAAK,mBAAoBL,EAAG,MAAMC,EAAIK,OAAO,GAAGC,SAE5D,MAAO,CAACP,EAAKC,EAAIO,MACnB,IAEH,GAEL"}
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lowerdeck/env",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"author": "Tobias Herber",
|
|
8
|
+
"license": "Apache 2",
|
|
9
|
+
"type": "module",
|
|
10
|
+
"source": "src/index.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
"require": "./dist/index.cjs",
|
|
13
|
+
"default": "./dist/index.modern.js"
|
|
14
|
+
},
|
|
15
|
+
"main": "./dist/index.cjs",
|
|
16
|
+
"module": "./dist/index.module.js",
|
|
17
|
+
"types": "dist/index.d.ts",
|
|
18
|
+
"unpkg": "./dist/index.umd.js",
|
|
19
|
+
"scripts": {
|
|
20
|
+
"test": "vitest run --passWithNoTests",
|
|
21
|
+
"lint": "prettier src/**/*.ts --check",
|
|
22
|
+
"build": "microbundle"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@lowerdeck/validation": "^1.0.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"microbundle": "^0.15.1",
|
|
29
|
+
"@lowerdeck/tsconfig": "^1.0.0",
|
|
30
|
+
"typescript": "5.8.2",
|
|
31
|
+
"vitest": "^3.1.2"
|
|
32
|
+
}
|
|
33
|
+
}
|
package/src/env.test.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { v } from '@lowerdeck/validation';
|
|
2
|
+
import { describe, expect, test } from 'vitest';
|
|
3
|
+
import { createValidatedEnv } from './env';
|
|
4
|
+
|
|
5
|
+
describe('createValidatedEnv', () => {
|
|
6
|
+
test('validates env', () => {
|
|
7
|
+
process.env.PORT = '3000';
|
|
8
|
+
process.env.TEST = 'true';
|
|
9
|
+
process.env.TEST2 = 'false';
|
|
10
|
+
process.env.HELLO = 'world';
|
|
11
|
+
|
|
12
|
+
let env = createValidatedEnv({
|
|
13
|
+
test: {
|
|
14
|
+
PORT: v.string(),
|
|
15
|
+
TEST: v.boolean()
|
|
16
|
+
},
|
|
17
|
+
test2: {
|
|
18
|
+
TEST2: v.boolean()
|
|
19
|
+
},
|
|
20
|
+
hello: {
|
|
21
|
+
HELLO: v.string()
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
expect(env).toEqual({
|
|
26
|
+
test: {
|
|
27
|
+
PORT: '3000',
|
|
28
|
+
TEST: true
|
|
29
|
+
},
|
|
30
|
+
test2: {
|
|
31
|
+
TEST2: false
|
|
32
|
+
},
|
|
33
|
+
hello: {
|
|
34
|
+
HELLO: 'world'
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
});
|
package/src/env.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ValidationType, ValidationTypeValue } from '@lowerdeck/validation';
|
|
2
|
+
|
|
3
|
+
export let createValidatedEnv = <
|
|
4
|
+
Env extends Record<string, Record<string, ValidationType<any>>>
|
|
5
|
+
>(
|
|
6
|
+
env: Env
|
|
7
|
+
): {
|
|
8
|
+
[K in keyof Env]: {
|
|
9
|
+
[P in keyof Env[K]]: ValidationTypeValue<Env[K][P]>;
|
|
10
|
+
};
|
|
11
|
+
} => {
|
|
12
|
+
return Object.fromEntries(
|
|
13
|
+
Object.entries(env).map(([key, value]) => [
|
|
14
|
+
key,
|
|
15
|
+
Object.fromEntries(
|
|
16
|
+
Object.entries(value).map(([key, value]) => {
|
|
17
|
+
let res = value.validate(process.env[key]);
|
|
18
|
+
if (!res.success)
|
|
19
|
+
throw new Error(`ENV VALIDATION: ${key} - ${res.errors[0].message}`);
|
|
20
|
+
|
|
21
|
+
return [key, res.value];
|
|
22
|
+
})
|
|
23
|
+
)
|
|
24
|
+
])
|
|
25
|
+
) as any;
|
|
26
|
+
};
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './env';
|
package/tsconfig.json
ADDED