@arthur-lobo/zod-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/README.md ADDED
@@ -0,0 +1,121 @@
1
+ # Zod Env
2
+
3
+ A TypeScript library for loading and validating environment variables using [Zod](https://zod.dev/), providing strong and safe type validation for environment configurations.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @arthur-lobo/zod-env
9
+ ```
10
+
11
+ ## Description
12
+
13
+ `ZodEnv` allows you to define Zod schemas to validate environment variables, ensuring their values are in the correct format and providing default values when necessary. It supports both synchronous and asynchronous operations, and allow you to define how `.env` must be loaded.
14
+
15
+ ## Basic Usage
16
+
17
+ ### Synchronous Class: `ZodEnv`
18
+
19
+ ```typescript
20
+ import { z } from 'zod';
21
+ import { ZodEnv } from '@arthur-lobo/zod-env';
22
+
23
+ const schema = z.object({
24
+ PORT: z.coerce.number().default(3000),
25
+ DATABASE_URL: z.string(),
26
+ DEBUG: z.coerce.boolean().default(false),
27
+ });
28
+
29
+ const env = new ZodEnv({
30
+ schema,
31
+ getEnv: () => process.env, // or any function that returns an object with the variables like `import.meta.env` when using vite to build your frontend
32
+ });
33
+
34
+ // Access validated values
35
+ console.log(env.get('PORT')); // 3000 (or the value of process.env.PORT if defined)
36
+ console.log(env.get('DATABASE_URL')); // validated string
37
+ ```
38
+
39
+ ### Asynchronous Class: `AsyncZodEnv`
40
+
41
+ ```typescript
42
+ import { z } from 'zod';
43
+ import { AsyncZodEnv } from '@arthur-lobo/zod-env';
44
+
45
+ const schema = z.object({
46
+ API_KEY: z.string(),
47
+ TIMEOUT: z.coerce.number().default(5000),
48
+ });
49
+
50
+ const env = new AsyncZodEnv({
51
+ schema,
52
+ getEnv: async () => {
53
+ await someAsyncOperation();
54
+ return process.env;
55
+ },
56
+ });
57
+
58
+ // Access validated values asynchronously
59
+ const apiKey = await env.get('API_KEY');
60
+ const timeout = await env.get('TIMEOUT');
61
+ ```
62
+
63
+ ### Loading .env File
64
+
65
+ You can automatically load a `.env` file using Node.js's `loadEnv` function:
66
+
67
+ ```typescript
68
+ import { loadEnvFile } from 'node:process';
69
+
70
+ const env = new ZodEnv({
71
+ schema: z.object({
72
+ SECRET_KEY: z.string(),
73
+ }),
74
+ loadEnv: loadEnvFile, // Loads the .env file
75
+ getEnv: () => process.env,
76
+ });
77
+
78
+ console.log(env.get('SECRET_KEY')); // Validated value from .env
79
+ ```
80
+
81
+ For asynchronous operations:
82
+
83
+ ```typescript
84
+ const env = new AsyncZodEnv({
85
+ schema: z.object({
86
+ SECRET_KEY: z.string(),
87
+ }),
88
+ loadEnv: async () => loadEnvFile(), // Loads .env asynchronously
89
+ getEnv: async () => process.env,
90
+ });
91
+ ```
92
+
93
+ ## Schema Examples
94
+
95
+ ```typescript
96
+ import { z } from 'zod';
97
+
98
+ // Basic schema with default values
99
+ const basicSchema = z.object({
100
+ PORT: z.coerce.number().default(3000),
101
+ HOST: z.string().default('localhost'),
102
+ DEBUG: z.coerce.boolean().default(false),
103
+ });
104
+
105
+ // Schema with custom validations
106
+ const advancedSchema = z.object({
107
+ DATABASE_URL: z.string().url(),
108
+ JWT_SECRET: z.string().min(32, 'JWT secret must be at least 32 characters'),
109
+ MAX_CONNECTIONS: z.coerce.number().min(1).max(100),
110
+ ALLOWED_ORIGINS: z.string().transform(str => str.split(',')).pipe(z.array(z.string().url())),
111
+ });
112
+ ```
113
+
114
+ ## Benefits
115
+
116
+ - **Strong Type Validation**: Uses Zod to ensure environment variables are in the correct format.
117
+ - **Default Values**: Native support for default values in the Zod schema.
118
+ - **Flexibility**: Works with any source of environment variables (process.env, import.meta.env, custom files, etc.).
119
+ - **.env Support**: Easy integration with `.env` files via Node.js's `loadEnvFile`.
120
+ - **Async/Sync**: Choose between synchronous or asynchronous operations as needed.
121
+ - **TypeScript**: Fully typed, providing autocomplete and type checking.
package/dist/index.cjs ADDED
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ AsyncZodEnv: () => AsyncZodEnv,
24
+ ZodEnv: () => ZodEnv
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+ var import_zod = require("zod");
28
+ var ZodEnv = class {
29
+ schema;
30
+ env;
31
+ constructor({ schema, loadEnv, getEnv }) {
32
+ this.schema = schema;
33
+ loadEnv?.();
34
+ this.env = schema.parse(getEnv());
35
+ }
36
+ get(key) {
37
+ return this.env[key];
38
+ }
39
+ };
40
+ var AsyncZodEnv = class {
41
+ schema;
42
+ env;
43
+ constructor({ schema, loadEnv, getEnv }) {
44
+ this.schema = schema;
45
+ if (typeof loadEnv === "function") {
46
+ this.env = loadEnv().then(getEnv).then((result) => schema.parse(result));
47
+ } else {
48
+ this.env = getEnv().then((result) => schema.parse(result));
49
+ }
50
+ }
51
+ async get(key) {
52
+ return (await this.env)[key];
53
+ }
54
+ };
55
+ // Annotate the CommonJS export names for ESM import in node:
56
+ 0 && (module.exports = {
57
+ AsyncZodEnv,
58
+ ZodEnv
59
+ });
@@ -0,0 +1,30 @@
1
+ import { ZodObject, z } from 'zod';
2
+
3
+ interface ZodEnvConstructor {
4
+ schema: ZodObject;
5
+ loadEnv?: () => void;
6
+ getEnv: () => Record<string, any>;
7
+ }
8
+ declare class ZodEnv<S extends ZodObject> {
9
+ schema: S;
10
+ env: z.infer<S>;
11
+ constructor({ schema, loadEnv, getEnv }: ZodEnvConstructor & {
12
+ schema: S;
13
+ });
14
+ get<K extends keyof S["shape"]>(key: K): z.core.output<S>[K];
15
+ }
16
+ interface AsyncZodEnvConstructor {
17
+ schema: ZodObject;
18
+ loadEnv?: () => Promise<void>;
19
+ getEnv: () => Promise<Record<string, any>>;
20
+ }
21
+ declare class AsyncZodEnv<S extends ZodObject> {
22
+ schema: S;
23
+ env: Promise<z.infer<S>>;
24
+ constructor({ schema, loadEnv, getEnv }: AsyncZodEnvConstructor & {
25
+ schema: S;
26
+ });
27
+ get<K extends keyof S["shape"]>(key: K): Promise<z.core.output<S>[K]>;
28
+ }
29
+
30
+ export { AsyncZodEnv, ZodEnv };
@@ -0,0 +1,30 @@
1
+ import { ZodObject, z } from 'zod';
2
+
3
+ interface ZodEnvConstructor {
4
+ schema: ZodObject;
5
+ loadEnv?: () => void;
6
+ getEnv: () => Record<string, any>;
7
+ }
8
+ declare class ZodEnv<S extends ZodObject> {
9
+ schema: S;
10
+ env: z.infer<S>;
11
+ constructor({ schema, loadEnv, getEnv }: ZodEnvConstructor & {
12
+ schema: S;
13
+ });
14
+ get<K extends keyof S["shape"]>(key: K): z.core.output<S>[K];
15
+ }
16
+ interface AsyncZodEnvConstructor {
17
+ schema: ZodObject;
18
+ loadEnv?: () => Promise<void>;
19
+ getEnv: () => Promise<Record<string, any>>;
20
+ }
21
+ declare class AsyncZodEnv<S extends ZodObject> {
22
+ schema: S;
23
+ env: Promise<z.infer<S>>;
24
+ constructor({ schema, loadEnv, getEnv }: AsyncZodEnvConstructor & {
25
+ schema: S;
26
+ });
27
+ get<K extends keyof S["shape"]>(key: K): Promise<z.core.output<S>[K]>;
28
+ }
29
+
30
+ export { AsyncZodEnv, ZodEnv };
package/dist/index.js ADDED
@@ -0,0 +1,33 @@
1
+ // src/index.ts
2
+ import "zod";
3
+ var ZodEnv = class {
4
+ schema;
5
+ env;
6
+ constructor({ schema, loadEnv, getEnv }) {
7
+ this.schema = schema;
8
+ loadEnv?.();
9
+ this.env = schema.parse(getEnv());
10
+ }
11
+ get(key) {
12
+ return this.env[key];
13
+ }
14
+ };
15
+ var AsyncZodEnv = class {
16
+ schema;
17
+ env;
18
+ constructor({ schema, loadEnv, getEnv }) {
19
+ this.schema = schema;
20
+ if (typeof loadEnv === "function") {
21
+ this.env = loadEnv().then(getEnv).then((result) => schema.parse(result));
22
+ } else {
23
+ this.env = getEnv().then((result) => schema.parse(result));
24
+ }
25
+ }
26
+ async get(key) {
27
+ return (await this.env)[key];
28
+ }
29
+ };
30
+ export {
31
+ AsyncZodEnv,
32
+ ZodEnv
33
+ };
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@arthur-lobo/zod-env",
3
+ "version": "1.0.0",
4
+ "description": "load and validate your env with zod.",
5
+ "keywords": [
6
+ "zod",
7
+ "env",
8
+ "dotenv",
9
+ "validation"
10
+ ],
11
+ "license": "MIT",
12
+ "author": "Arthur Lobo",
13
+ "type": "module",
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "require": "./dist/index.cjs",
21
+ "import": "./dist/index.js"
22
+ }
23
+ },
24
+ "scripts": {
25
+ "test": "vitest --run",
26
+ "build": "tsup",
27
+ "prepack": "npm run build"
28
+ },
29
+ "files": [
30
+ "dist"
31
+ ],
32
+ "dependencies": {
33
+ "zod": "^4.3.6"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "^25.5.0",
37
+ "tsup": "^8.5.1",
38
+ "typescript": "^5.9.3",
39
+ "vitest": "^4.1.0"
40
+ }
41
+ }