Skip to content

Commit 2eed417

Browse files
committed
fix: document env vars feature
Signed-off-by: tunnckoCore <5038030+tunnckoCore@users.noreply.github.com>
1 parent 1c75669 commit 2eed417

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

README.md

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Elevate your TypeScript workflow with Zagora: a sleek, bulletproof toolkit for f
1717
- 🏠 **Familiar:** Echoes remote-RPC patterns from oRPC and tRPC, but focused on libraries, not apps.
1818
- ⚖️ **Unopinionated:** Zero assumptions - no routers, middlewares, or network concepts.
1919
- 🎁 **No Unwrapping:** Direct access to results, unlike `neverthrow` - no extra steps required.
20+
- 🎁 **EnvVars Handling:** Handling and validation of environment variables.
2021
- 🤖 **Agents Ready:** Rules for LLMs with subtle nuances and where to be careful. [Read/get here](./AGENTS.md)
2122

2223
_This library is product of 3+ months of dedication and passion, after 10 years in Open Source._<br>
@@ -589,23 +590,53 @@ const res = await proc(22);
589590

590591
You can also provide the cache through `.callable({ cache })`. That is useful, if you want to provide it at "execution place", not at "definition place". For example, you'd have a set of procedures written at one place, then throgh "router" or some object that combiens them you want to call them at a `Request/Response` server handler.
591592

593+
### Environment Variables
592594

593-
### Options Object
595+
You can provide the runtime env vars (either `process.env` or `import.meta.env`) through the second argument of `.env(schema, envs)` or at later stage through the `.callable({ env })` call. Either way, they will be validated. The parsed variables will be accessible through the handler's `options` object.
596+
597+
```ts
598+
const zaWithEnv = zagora()
599+
.env(z.object({
600+
DATABASE_URL: z.string().min(1).default('file://db.sqlite'),
601+
BETTER_AUTH_SECRET: z.string().min(1)
602+
}))
603+
.cache(new Map())
604+
605+
const fn1 = zaWithEnv
606+
.handler(({ env }) => {
607+
// env: { DATABASE_URL: string, BETTER_AUTH_SECRET: string }
608+
})
609+
.callable({ env: process.env })
610+
````
611+
612+
Keep in mind that if you have `autoCallable: true` in enabled in the instance, then you may need to provide the runtime env vars through the second argument, otherwise the types will say you have something, but in runtime you will get error.
613+
614+
Also important to note that when `disableOptions` you will loose access to the `env` vars, as well `context` and `errors`.
615+
616+
### Handler Options Object
594617

595618
Handlers receive an `options` (or "config") object as the first parameter containing:
596619

597620
- `context`: The typed & merged context (initial + runtime)
598621
- `errors`: Constructed error helpers (if errors map schemas are defined)
622+
- `env`: Parsed and validated environment variables (if env schema provided)
599623

600624
```ts
601625
const procedure = zagora()
602626
.context({ user: 'bobby' })
603627
.errors({ NOT_FOUND: z.object({ id: z.string() }) })
604628
.input(z.string())
629+
.env(z.object({
630+
DATABASE_URL: z.string().min(1).default('file://db.sqlite'),
631+
AUTH_SECRET: z.string().min(1),
632+
PORT: z.coerce.number(), // env.PORT type will be number
633+
}), process.env)
605634
.handler((options, userId) => {
606-
const { context, errors } = options;
635+
const { context, errors, env } = options;
607636
// context: { user: 'bobby', id: 123 }
608637
// errors: { NOT_FOUND: (data) => throw { kind: 'NOT_FOUND', ...data } }
638+
// env: { DATABASE_URL: string, AUTH_SECRET: string, PORT: number }
639+
609640
if (context.user !== 'bobby') {
610641
throw errors.NOT_FOUND({ id: userId });
611642
}

test/main.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -727,13 +727,15 @@ test("basic env schema support through `.env` method", () => {
727727
.input(z.string())
728728
.env(
729729
z.object({
730-
DATABASE_URL: z.string().min(4),
730+
DATABASE_URL: z.string().min(4).default("file://db.sqlite"),
731731
SOME_SECRET: z.string().min(2),
732+
PORT: z.coerce.number(),
732733
}),
733734
process.env,
734735
)
735736
.handler(({ env }, input) => {
736-
return `input=${input};url=${env.DATABASE_URL};secret=${env.SOME_SECRET}`;
737+
// env: { DATABASE_URL: string, SOME_SECRET: string, PORT: number }
738+
return `input=${input};url=${env.DATABASE_URL};secret=${env.SOME_SECRET};PORT=${env.PORT}`;
737739
})
738740
.callable({
739741
env: { SOME_SECRET: "sasa" },

0 commit comments

Comments
 (0)