Skip to content

Commit 0434113

Browse files
committed
chore: back to top links
Signed-off-by: tunnckoCore <5038030+tunnckoCore@users.noreply.github.com>
1 parent 8fc5bf3 commit 0434113

File tree

1 file changed

+45
-6
lines changed

1 file changed

+45
-6
lines changed

README.md

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ import * ZagoraTypes from 'zagora/types';
154154
import * zagoraUtils from 'zagora/utils';
155155
```
156156

157+
[Back to top](#zagora)
157158

158159
## Why zagora?
159160

@@ -164,6 +165,8 @@ Both `tRPC` and `oRPC` are promoted as "backend", or specifically for when you'r
164165

165166
They are built around the network, Zagora is built around functions with excellent egonomics, developer experience, and no assumptions. **It produces just functions, i cannot stress that enough.**
166167

168+
[Back to top](#zagora)
169+
167170
### Why Zagora over oRPC/tRPC/neverthrow/effect.ts?
168171

169172
- Zagora is focused on producing "just functions", not networks, routers, or groups.
@@ -193,12 +196,16 @@ They are built around the network, Zagora is built around functions with excelle
193196

194197
Funny enough, you can use Zagora to build fully type-safe CLIs with auto-generated detailed help, based on the provided schemas. I have another library for that, which i will overhaul soon - [zodest](https://npmjs.com/package/zodest).
195198

199+
[Back to top](#zagora)
200+
196201
### Why Zagora over plain TypeScript functions?
197202

198203
- Plain TypeScript offers compile-time types but no runtime validation — a mismatch between runtime and
199204
compile-time can blow up.
200205
- Zagora combines runtime validation/transforms (StandardSchema) with full compile-time inference, and returns a safe, uniform result tuple inspired by true functional programming
201206

207+
[Back to top](#zagora)
208+
202209
### Why Zagora over standalone Zod/Valibot usage?
203210

204211
- zagora gives a small ergonomic layer
@@ -209,6 +216,8 @@ Funny enough, you can use Zagora to build fully type-safe CLIs with auto-generat
209216
- single place to validate inputs/outputs/errors
210217
- unified non-throwing result shape
211218

219+
[Back to top](#zagora)
220+
212221
## Features
213222

214223
### Type-Safe Input/Output Validation
@@ -229,25 +238,27 @@ const procedure = zagora()
229238
// NOTE: you don't need to pass `age` because it has a default value set in schema.
230239
const result = procedure({ name: 'John' });
231240
if (result.ok) {
232-
console.log(result.data);
233-
// ^ { id: string, age: number, verified: boolean }
241+
console.log(result.data);
242+
// ^ { id: string, age: number, verified: boolean }
234243
}
235244

236245
// @ts-expect-error -- this will be reported at compile-time, AND error at runtime.
237246
const res2 = procedure('foobar');
238247
if (!res2.ok) {
239-
console.error(res2.error);
240-
// ^ { kind: 'VALIDATION_ERROR', message: string, issues: Schema.Issue[] }
248+
console.error(res2.error);
249+
// ^ { kind: 'VALIDATION_ERROR', message: string, issues: Schema.Issue[] }
241250
}
242251

243252
// note: this will error at runtime - age is no valid schema defined number
244253
const resul3 = procedure({ name: 'Barry', age: -5 });
245254
if (!resul3.ok) {
246-
console.error(resul3.error);
247-
// ^ { kind: 'VALIDATION_ERROR', message: string, issues: Schema.Issue[] }
255+
console.error(resul3.error);
256+
// ^ { kind: 'VALIDATION_ERROR', message: string, issues: Schema.Issue[] }
248257
}
249258
```
250259

260+
[Back to top](#zagora)
261+
251262
### Typed Errors
252263

253264
Define custom error types with schemas for better error handling.
@@ -285,6 +296,9 @@ if (res.ok) {
285296
}
286297
```
287298

299+
[Back to top](#zagora)
300+
301+
### Error Type Guards
288302
Isn't it amazing? You will never see `Error` or `try/catch` blocks again, and everything is typed top to bottom, well-known and intuitive.
289303

290304
But wait, there's more: **Type Guards**!
@@ -419,6 +433,8 @@ hello('invalid-keys');
419433

420434
**Important:** if you want the error validation to actually throw on unknown keys passed to the error helper, then you need to make the error object schema more strict - just like `z.object(...).strict()`.
421435

436+
[Back to top](#zagora)
437+
422438
### Context Management
423439

424440
In some advanced scenarios, you may need to pass runtime context to handlers, like `req`, `db`, `user`, sessions, and other dependencies. It's fully typed dependency injection mechanism.
@@ -443,6 +459,7 @@ procedure('charlie');
443459
// => 'foo-bar has foo -> qux, id = charlie'
444460
```
445461

462+
[Back to top](#zagora)
446463

447464
### Object Inputs
448465

@@ -453,6 +470,8 @@ zagora()
453470
.callable()
454471
```
455472

473+
[Back to top](#zagora)
474+
456475
### Tuple Inputs (Multiple Arguments)
457476

458477
Tuple schemas is used for defining multiple arguments in a handler. It's one of the ABSOLUTE KEY features of Zagora, and it is one of the most complex stuff to achieve - but the end results is astonishing. It just works - you define schema and you get fully typed and validated arguments, INCLUDING per-argument reporting/diagnostics, INCLUDING filling defaults if `.default()` is used and respecting `.optional()`.
@@ -494,6 +513,8 @@ fnTwo('Barry', 25) // => Barry is 25, from unknown
494513
fnTwo('Barry', 33, 'USA') // => Barry is 33, from USA
495514
```
496515

516+
[Back to top](#zagora)
517+
497518
### Default Values
498519

499520
Optionals and default values are supported at any level with any schema, whether it's through the Tuple Args, or if it's primitive schema for `string`, `array`, or `object`.
@@ -512,6 +533,8 @@ fn({ name: 'John' }) // age defaults to 18
512533
// => 'John is 18, from unknown'
513534
```
514535

536+
[Back to top](#zagora)
537+
515538
### Async Support
516539

517540
Zagora is fully async-aware at every level of the system:
@@ -573,6 +596,8 @@ const procAsyncOutput = zagora()
573596
const result2 = await procAsyncOutput('hello'); // ZagoraResult
574597
```
575598

599+
[Back to top](#zagora)
600+
576601
### Caching/Memoization
577602

578603
Built-in caching with custom cache adapter. Cache key includes the input, the input/output/error schemas, and handler function body. That can be used to implement custom caching strategies, and memoization.
@@ -622,6 +647,8 @@ const res = await proc(22);
622647

623648
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.
624649

650+
[Back to top](#zagora)
651+
625652
### Environment Variables
626653

627654
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.
@@ -645,6 +672,8 @@ Keep in mind that if you have `autoCallable: true` enabled in the instance, then
645672

646673
Also important to note that when `disableOptions` you will loose access to the `env` vars, as well `context` and `errors` which is normal behavior.
647674

675+
[Back to top](#zagora)
676+
648677
### Handler Options Object
649678

650679
Handlers receive an `options` (or "config") object as the first parameter containing:
@@ -687,6 +716,8 @@ zagora({ disableOptions: true })
687716
.handler((userId) => userId); // No options
688717
```
689718

719+
[Back to top](#zagora)
720+
690721
### Auto-Callable Mode
691722

692723
Skip the need for `.callable()` call and get the procedure function directly:
@@ -707,6 +738,8 @@ hello('bob'); // ZagoraResult => 'Hello, BOB'
707738
hello('alice'); // ZagoraResult => 'Hello, ALICE'
708739
```
709740

741+
[Back to top](#zagora)
742+
710743
### Never-Throwing Guarantees
711744

712745
Zagora ensures functions never throw - all errors are wrapped in the `Result` object:
@@ -727,6 +760,8 @@ const result = procedure();
727760
// result.error.cause.message === 'Oops'
728761
```
729762

763+
[Back to top](#zagora)
764+
730765
### Type Safety Guarantees
731766

732767
Full TypeScript support with type inference:
@@ -739,6 +774,8 @@ And because the type system of Zagora is pretty complex, we also have tests not
739774

740775
If you are interested, you can inspect the [test/types-testing.test.ts](./test/types-testing.test.ts) file.
741776

777+
[Back to top](#zagora)
778+
742779
## API Reference
743780

744781
### `zagora(config?)`
@@ -763,6 +800,8 @@ Creates a new Zagora instance.
763800
+ if `cache` passed, it will override the previously passed through `.cache` method (if so)
764801
+ if `env` passed, it will be deep-merged with the provided through the `.env` method (if so)
765802

803+
[Back to top](#zagora)
804+
766805
## Error Types
767806

768807
- `VALIDATION_ERROR` kind - Schema validation failures

0 commit comments

Comments
 (0)