honertia 0.1.9 → 0.1.10
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 +58 -13
- package/dist/effect/action.d.ts +63 -6
- package/dist/effect/action.d.ts.map +1 -1
- package/dist/effect/action.js +27 -5
- package/dist/effect/index.d.ts +2 -2
- package/dist/effect/index.d.ts.map +1 -1
- package/dist/effect/index.js +2 -2
- package/dist/effect/validation.d.ts +27 -2
- package/dist/effect/validation.d.ts.map +1 -1
- package/dist/effect/validation.js +9 -1
- package/dist/schema.d.ts +1 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -511,10 +511,11 @@ const input = yield* validateRequest(
|
|
|
511
511
|
S.Struct({ name: requiredString, description: S.optional(S.String) }),
|
|
512
512
|
{ errorComponent: 'Projects/Create' }
|
|
513
513
|
)
|
|
514
|
-
// input is
|
|
514
|
+
// input is Validated<{ name: string, description?: string }>
|
|
515
515
|
```
|
|
516
516
|
|
|
517
517
|
On validation failure, re-renders `errorComponent` with field-level errors.
|
|
518
|
+
`validateRequest` returns a branded `Validated<T>` value that you can require for writes.
|
|
518
519
|
|
|
519
520
|
#### `DatabaseService` - Database Access
|
|
520
521
|
|
|
@@ -552,7 +553,9 @@ import { Effect, Schema as S } from 'effect'
|
|
|
552
553
|
import {
|
|
553
554
|
action,
|
|
554
555
|
authorize,
|
|
556
|
+
asTrusted,
|
|
555
557
|
validateRequest,
|
|
558
|
+
dbMutation,
|
|
556
559
|
DatabaseService,
|
|
557
560
|
redirect,
|
|
558
561
|
requiredString,
|
|
@@ -575,12 +578,12 @@ export const createProject = action(
|
|
|
575
578
|
|
|
576
579
|
// 3. Database - perform the mutation
|
|
577
580
|
const db = yield* DatabaseService
|
|
578
|
-
yield*
|
|
579
|
-
db.insert(projects).values({
|
|
581
|
+
yield* dbMutation(db, async (db) => {
|
|
582
|
+
await db.insert(projects).values(asTrusted({
|
|
580
583
|
...input,
|
|
581
584
|
userId: auth.user.id,
|
|
582
|
-
})
|
|
583
|
-
)
|
|
585
|
+
}))
|
|
586
|
+
})
|
|
584
587
|
|
|
585
588
|
// 4. Response - redirect on success
|
|
586
589
|
return yield* redirect('/projects')
|
|
@@ -656,23 +659,63 @@ export const searchProjects = action(
|
|
|
656
659
|
|
|
657
660
|
### Helper Utilities
|
|
658
661
|
|
|
662
|
+
#### `dbMutation` - Safe Writes
|
|
663
|
+
|
|
664
|
+
Use `dbMutation` for writes that require validated or trusted input:
|
|
665
|
+
|
|
666
|
+
```typescript
|
|
667
|
+
import { DatabaseService, dbMutation, validateRequest, asTrusted, authorize } from 'honertia/effect'
|
|
668
|
+
|
|
669
|
+
const auth = yield* authorize()
|
|
670
|
+
const input = yield* validateRequest(CreateProjectSchema)
|
|
671
|
+
const values = asTrusted({ userId: auth.user.id, ...input })
|
|
672
|
+
const db = yield* DatabaseService
|
|
673
|
+
|
|
674
|
+
yield* dbMutation(db, async (db) => {
|
|
675
|
+
await db.insert(projects).values(values)
|
|
676
|
+
})
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
Use `asTrusted` for server-derived values like audit logs or usage meters, or when combining validated input with server-only fields.
|
|
680
|
+
`dbMutation` also wraps `execute`/`run` params to require validated or trusted inputs.
|
|
681
|
+
|
|
682
|
+
Why this design: we intentionally use nominal brands that do not survive spreads or merges. That means any modified or combined object must be explicitly re-branded with `asTrusted`, which makes trust boundaries visible and prevents accidental writes of unvalidated data.
|
|
683
|
+
|
|
684
|
+
```typescript
|
|
685
|
+
const input = yield* validateRequest(CreateProjectSchema)
|
|
686
|
+
|
|
687
|
+
// This fails typechecking because the brand is dropped by the merge
|
|
688
|
+
const merged = { ...input, userId: auth.user.id }
|
|
689
|
+
// await db.insert(projects).values(merged)
|
|
690
|
+
|
|
691
|
+
// Explicitly re-brand after adding server data
|
|
692
|
+
const values = asTrusted({ ...input, userId: auth.user.id })
|
|
693
|
+
await db.insert(projects).values(values)
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
For multi-step writes, use `dbTransaction` so writes require validated or trusted input.
|
|
697
|
+
|
|
659
698
|
#### `dbTransaction` - Database Transactions
|
|
660
699
|
|
|
661
700
|
Run multiple database operations in a transaction with automatic rollback on failure. The database instance is passed explicitly to keep the dependency visible and consistent with other service patterns:
|
|
662
701
|
|
|
663
702
|
```typescript
|
|
664
|
-
import { DatabaseService, dbTransaction } from 'honertia/effect'
|
|
703
|
+
import { DatabaseService, dbTransaction, asTrusted } from 'honertia/effect'
|
|
665
704
|
|
|
666
705
|
const db = yield* DatabaseService
|
|
706
|
+
const user = asTrusted({ name: 'Alice', email: 'alice@example.com' })
|
|
707
|
+
const balanceUpdate = asTrusted({ balance: 100 })
|
|
667
708
|
|
|
668
709
|
yield* dbTransaction(db, async (tx) => {
|
|
669
|
-
await tx.insert(users).values(
|
|
670
|
-
await tx.update(accounts).set(
|
|
710
|
+
await tx.insert(users).values(user)
|
|
711
|
+
await tx.update(accounts).set(balanceUpdate).where(eq(accounts.userId, id))
|
|
671
712
|
// If any operation fails, the entire transaction rolls back
|
|
672
713
|
return { success: true }
|
|
673
714
|
})
|
|
674
715
|
```
|
|
675
716
|
|
|
717
|
+
`dbTransaction` wraps `insert`, `update`, and `execute`/`run` params; `delete` has no payload, so build its conditions from validated or trusted values.
|
|
718
|
+
|
|
676
719
|
## Core Concepts
|
|
677
720
|
|
|
678
721
|
### Effect-Based Handlers
|
|
@@ -684,7 +727,9 @@ import { Effect } from 'effect'
|
|
|
684
727
|
import {
|
|
685
728
|
action,
|
|
686
729
|
authorize,
|
|
730
|
+
asTrusted,
|
|
687
731
|
validateRequest,
|
|
732
|
+
dbMutation,
|
|
688
733
|
DatabaseService,
|
|
689
734
|
render,
|
|
690
735
|
redirect,
|
|
@@ -716,12 +761,12 @@ export const createProject = action(
|
|
|
716
761
|
})
|
|
717
762
|
const db = yield* DatabaseService
|
|
718
763
|
|
|
719
|
-
yield*
|
|
720
|
-
db.insert(schema.projects).values({
|
|
764
|
+
yield* dbMutation(db, async (db) => {
|
|
765
|
+
await db.insert(schema.projects).values(asTrusted({
|
|
721
766
|
...input,
|
|
722
767
|
userId: auth.user.id,
|
|
723
|
-
})
|
|
724
|
-
)
|
|
768
|
+
}))
|
|
769
|
+
})
|
|
725
770
|
|
|
726
771
|
return yield* redirect('/projects')
|
|
727
772
|
})
|
|
@@ -892,7 +937,7 @@ export const createProject = Effect.gen(function* () {
|
|
|
892
937
|
errorComponent: 'Projects/Create', // Re-render with errors on validation failure
|
|
893
938
|
})
|
|
894
939
|
|
|
895
|
-
// input is
|
|
940
|
+
// input is Validated<{ name: string, description: string | null }>
|
|
896
941
|
yield* insertProject(input)
|
|
897
942
|
|
|
898
943
|
return yield* redirect('/projects')
|
package/dist/effect/action.d.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import { Effect } from 'effect';
|
|
8
8
|
import { type AuthUser } from './services.js';
|
|
9
9
|
import { UnauthorizedError, ForbiddenError, Redirect } from './errors.js';
|
|
10
|
+
import { type Validated, type Trusted } from './validation.js';
|
|
10
11
|
/**
|
|
11
12
|
* Semantic wrapper for Effect actions.
|
|
12
13
|
*
|
|
@@ -25,8 +26,8 @@ import { UnauthorizedError, ForbiddenError, Redirect } from './errors.js';
|
|
|
25
26
|
* // Opt-in to database
|
|
26
27
|
* const db = yield* DatabaseService
|
|
27
28
|
*
|
|
28
|
-
* yield*
|
|
29
|
-
* db.insert(projects).values({ ...input, userId: auth.user.id })
|
|
29
|
+
* yield* dbMutation(db, input, (db, input) =>
|
|
30
|
+
* db.insert(projects).values(asTrusted({ ...input, userId: auth.user.id }))
|
|
30
31
|
* )
|
|
31
32
|
* return new Redirect({ url: '/projects', status: 303 })
|
|
32
33
|
* })
|
|
@@ -52,19 +53,75 @@ export declare function action<R, E>(handler: Effect.Effect<Response | Redirect,
|
|
|
52
53
|
* const auth = yield* authorize((a) => a.user.id === project.userId)
|
|
53
54
|
*/
|
|
54
55
|
export declare function authorize(check?: (user: AuthUser) => boolean): Effect.Effect<AuthUser, UnauthorizedError | ForbiddenError, never>;
|
|
56
|
+
/**
|
|
57
|
+
* Run a database mutation with a safe wrapper.
|
|
58
|
+
* Writes only accept validated or trusted inputs for insert/update/execute params.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* const input = yield* validateRequest(CreateProjectSchema)
|
|
62
|
+
* const db = yield* DatabaseService
|
|
63
|
+
* yield* dbMutation(db, async (db) => {
|
|
64
|
+
* await db.insert(projects).values(asTrusted({ ...input, userId: auth.user.id }))
|
|
65
|
+
* })
|
|
66
|
+
*/
|
|
67
|
+
export declare function dbMutation<DB, T>(db: DB, operation: (db: SafeTx<DB>) => Promise<T>): Effect.Effect<T, Error>;
|
|
68
|
+
type SafeInput<A> = Validated<A> | Trusted<A>;
|
|
69
|
+
type SafeValues<V> = V extends Array<infer E> ? Array<SafeInput<E>> | SafeInput<V> : V extends ReadonlyArray<infer E> ? ReadonlyArray<SafeInput<E>> | SafeInput<V> : SafeInput<V>;
|
|
70
|
+
type SafeParam<P> = P extends ReadonlyArray<any> ? SafeValues<P> : P extends Array<any> ? SafeValues<P> : P extends Record<string, unknown> ? SafeInput<P> : P;
|
|
71
|
+
type WrapExecuteArgs<A extends unknown[]> = A extends [infer Q, infer P, ...infer Rest] ? [Q, SafeParam<P>, ...Rest] : A;
|
|
72
|
+
type WrapSecondArg<A extends unknown[]> = A extends [infer First, infer Second, ...infer Rest] ? [First, SafeParam<Second>, ...Rest] : A;
|
|
73
|
+
type WrapMethod<I, K extends string> = I extends Record<K, (...args: infer A) => infer R> ? Omit<I, K> & {
|
|
74
|
+
[P in K]: (...args: WrapExecuteArgs<A>) => R;
|
|
75
|
+
} : I;
|
|
76
|
+
type WrapBuilder<I> = WrapMethod<WrapMethod<WrapMethod<I, 'execute'>, 'run'>, 'query'>;
|
|
77
|
+
type WrapValues<I> = I extends {
|
|
78
|
+
values: (values: infer V) => infer R;
|
|
79
|
+
} ? WrapBuilder<Omit<I, 'values'> & {
|
|
80
|
+
values: (values: SafeValues<V>) => R;
|
|
81
|
+
}> : WrapBuilder<I>;
|
|
82
|
+
type WrapSet<I> = I extends {
|
|
83
|
+
set: (values: infer V) => infer R;
|
|
84
|
+
} ? WrapBuilder<Omit<I, 'set'> & {
|
|
85
|
+
set: (values: SafeValues<V>) => R;
|
|
86
|
+
}> : WrapBuilder<I>;
|
|
87
|
+
type SafeInsert<Tx> = Tx extends {
|
|
88
|
+
insert: (...args: infer A) => infer I;
|
|
89
|
+
} ? Omit<Tx, 'insert'> & {
|
|
90
|
+
insert: (...args: WrapSecondArg<A>) => WrapValues<I>;
|
|
91
|
+
} : Tx;
|
|
92
|
+
type SafeUpdate<Tx> = Tx extends {
|
|
93
|
+
update: (...args: infer A) => infer I;
|
|
94
|
+
} ? Omit<Tx, 'update'> & {
|
|
95
|
+
update: (...args: WrapSecondArg<A>) => WrapSet<I>;
|
|
96
|
+
} : Tx;
|
|
97
|
+
type SafeDelete<Tx> = Tx extends {
|
|
98
|
+
delete: (...args: infer A) => infer I;
|
|
99
|
+
} ? Omit<Tx, 'delete'> & {
|
|
100
|
+
delete: (...args: WrapSecondArg<A>) => WrapBuilder<I>;
|
|
101
|
+
} : Tx;
|
|
102
|
+
export type SafeTx<Tx> = WrapBuilder<SafeDelete<SafeUpdate<SafeInsert<Tx>>>>;
|
|
103
|
+
type TransactionClient<DB> = DB extends {
|
|
104
|
+
transaction: (fn: (tx: infer Tx) => Promise<any>) => Promise<any>;
|
|
105
|
+
} ? Tx : never;
|
|
55
106
|
/**
|
|
56
107
|
* Run multiple database operations in a transaction.
|
|
57
108
|
* Automatically rolls back on any failure.
|
|
58
109
|
*
|
|
110
|
+
* The transaction client is wrapped as `SafeTx` so writes only accept
|
|
111
|
+
* validated or trusted inputs for insert/update/execute params.
|
|
112
|
+
*
|
|
59
113
|
* @example
|
|
114
|
+
* const input = yield* validateRequest(CreateUserSchema)
|
|
115
|
+
* const balanceUpdate = asTrusted({ balance: 100 })
|
|
60
116
|
* const db = yield* DatabaseService
|
|
61
117
|
* yield* dbTransaction(db, async (tx) => {
|
|
62
|
-
* await tx.insert(users).values(
|
|
63
|
-
* await tx.update(accounts).set(
|
|
118
|
+
* await tx.insert(users).values(input)
|
|
119
|
+
* await tx.update(accounts).set(balanceUpdate).where(eq(accounts.userId, id))
|
|
64
120
|
* return { success: true }
|
|
65
121
|
* })
|
|
66
122
|
*/
|
|
67
123
|
export declare function dbTransaction<DB extends {
|
|
68
|
-
transaction: (fn: (tx:
|
|
69
|
-
}, T>(db: DB, operations: (tx:
|
|
124
|
+
transaction: (fn: (tx: any) => Promise<any>) => Promise<any>;
|
|
125
|
+
}, T>(db: DB, operations: (tx: SafeTx<TransactionClient<DB>>) => Promise<T>): Effect.Effect<T, Error>;
|
|
126
|
+
export {};
|
|
70
127
|
//# sourceMappingURL=action.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../../src/effect/action.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAA;AACvC,OAAO,
|
|
1
|
+
{"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../../src/effect/action.ts"],"names":[],"mappings":"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"}
|
package/dist/effect/action.js
CHANGED
|
@@ -25,8 +25,8 @@ import { UnauthorizedError, ForbiddenError } from './errors.js';
|
|
|
25
25
|
* // Opt-in to database
|
|
26
26
|
* const db = yield* DatabaseService
|
|
27
27
|
*
|
|
28
|
-
* yield*
|
|
29
|
-
* db.insert(projects).values({ ...input, userId: auth.user.id })
|
|
28
|
+
* yield* dbMutation(db, input, (db, input) =>
|
|
29
|
+
* db.insert(projects).values(asTrusted({ ...input, userId: auth.user.id }))
|
|
30
30
|
* )
|
|
31
31
|
* return new Redirect({ url: '/projects', status: 303 })
|
|
32
32
|
* })
|
|
@@ -69,21 +69,43 @@ export function authorize(check) {
|
|
|
69
69
|
return user;
|
|
70
70
|
});
|
|
71
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Run a database mutation with a safe wrapper.
|
|
74
|
+
* Writes only accept validated or trusted inputs for insert/update/execute params.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* const input = yield* validateRequest(CreateProjectSchema)
|
|
78
|
+
* const db = yield* DatabaseService
|
|
79
|
+
* yield* dbMutation(db, async (db) => {
|
|
80
|
+
* await db.insert(projects).values(asTrusted({ ...input, userId: auth.user.id }))
|
|
81
|
+
* })
|
|
82
|
+
*/
|
|
83
|
+
export function dbMutation(db, operation) {
|
|
84
|
+
return Effect.tryPromise({
|
|
85
|
+
try: () => operation(db),
|
|
86
|
+
catch: (error) => error instanceof Error ? error : new Error(String(error)),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
72
89
|
/**
|
|
73
90
|
* Run multiple database operations in a transaction.
|
|
74
91
|
* Automatically rolls back on any failure.
|
|
75
92
|
*
|
|
93
|
+
* The transaction client is wrapped as `SafeTx` so writes only accept
|
|
94
|
+
* validated or trusted inputs for insert/update/execute params.
|
|
95
|
+
*
|
|
76
96
|
* @example
|
|
97
|
+
* const input = yield* validateRequest(CreateUserSchema)
|
|
98
|
+
* const balanceUpdate = asTrusted({ balance: 100 })
|
|
77
99
|
* const db = yield* DatabaseService
|
|
78
100
|
* yield* dbTransaction(db, async (tx) => {
|
|
79
|
-
* await tx.insert(users).values(
|
|
80
|
-
* await tx.update(accounts).set(
|
|
101
|
+
* await tx.insert(users).values(input)
|
|
102
|
+
* await tx.update(accounts).set(balanceUpdate).where(eq(accounts.userId, id))
|
|
81
103
|
* return { success: true }
|
|
82
104
|
* })
|
|
83
105
|
*/
|
|
84
106
|
export function dbTransaction(db, operations) {
|
|
85
107
|
return Effect.tryPromise({
|
|
86
|
-
try: () => db.transaction(operations),
|
|
108
|
+
try: () => db.transaction((tx) => operations(tx)),
|
|
87
109
|
catch: (error) => error instanceof Error ? error : new Error(String(error)),
|
|
88
110
|
});
|
|
89
111
|
}
|
package/dist/effect/index.d.ts
CHANGED
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
export { DatabaseService, AuthService, AuthUserService, HonertiaService, RequestService, ResponseFactoryService, type AuthUser, type HonertiaRenderer, type RequestContext, type ResponseFactory, type HonertiaDatabaseType, type HonertiaAuthType, } from './services.js';
|
|
7
7
|
export { ValidationError, UnauthorizedError, NotFoundError, ForbiddenError, HttpError, Redirect, type AppError, } from './errors.js';
|
|
8
8
|
export * from './schema.js';
|
|
9
|
-
export { getValidationData, formatSchemaErrors, validate, validateRequest, } from './validation.js';
|
|
9
|
+
export { getValidationData, formatSchemaErrors, validate, validateRequest, asValidated, asTrusted, type Validated, type Trusted, } from './validation.js';
|
|
10
10
|
export { effectBridge, buildContextLayer, getEffectRuntime, type EffectBridgeConfig, } from './bridge.js';
|
|
11
11
|
export { effectHandler, effect, handle, errorToResponse, } from './handler.js';
|
|
12
|
-
export { action, authorize, dbTransaction, } from './action.js';
|
|
12
|
+
export { action, authorize, dbMutation, dbTransaction, type SafeTx, } from './action.js';
|
|
13
13
|
export { redirect, render, renderWithErrors, json, text, notFound, forbidden, httpError, prefersJson, jsonOrRender, share, } from './responses.js';
|
|
14
14
|
export { EffectRouteBuilder, effectRoutes, type EffectHandler, type BaseServices, } from './routing.js';
|
|
15
15
|
export { RequireAuthLayer, RequireGuestLayer, isAuthenticated, currentUser, requireAuth, requireGuest, shareAuth, shareAuthMiddleware, effectAuthRoutes, betterAuthFormAction, betterAuthLogoutAction, loadUser, type AuthRoutesConfig, type BetterAuthFormActionConfig, type BetterAuthLogoutConfig, type BetterAuthActionResult, } from './auth.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/effect/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,eAAe,EACf,WAAW,EACX,eAAe,EACf,eAAe,EACf,cAAc,EACd,sBAAsB,EACtB,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,GACtB,MAAM,eAAe,CAAA;AAGtB,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,SAAS,EACT,QAAQ,EACR,KAAK,QAAQ,GACd,MAAM,aAAa,CAAA;AAGpB,cAAc,aAAa,CAAA;AAG3B,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,eAAe,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/effect/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,eAAe,EACf,WAAW,EACX,eAAe,EACf,eAAe,EACf,cAAc,EACd,sBAAsB,EACtB,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,GACtB,MAAM,eAAe,CAAA;AAGtB,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,SAAS,EACT,QAAQ,EACR,KAAK,QAAQ,GACd,MAAM,aAAa,CAAA;AAGpB,cAAc,aAAa,CAAA;AAG3B,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,eAAe,EACf,WAAW,EACX,SAAS,EACT,KAAK,SAAS,EACd,KAAK,OAAO,GACb,MAAM,iBAAiB,CAAA;AAGxB,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAA;AAGpB,OAAO,EACL,aAAa,EACb,MAAM,EACN,MAAM,EACN,eAAe,GAChB,MAAM,cAAc,CAAA;AAGrB,OAAO,EACL,MAAM,EACN,SAAS,EACT,UAAU,EACV,aAAa,EACb,KAAK,MAAM,GACZ,MAAM,aAAa,CAAA;AAGpB,OAAO,EACL,QAAQ,EACR,MAAM,EACN,gBAAgB,EAChB,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,SAAS,EACT,WAAW,EACX,YAAY,EACZ,KAAK,GACN,MAAM,gBAAgB,CAAA;AAGvB,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,KAAK,aAAa,EAClB,KAAK,YAAY,GAClB,MAAM,cAAc,CAAA;AAGrB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,WAAW,EACX,YAAY,EACZ,SAAS,EACT,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,EACtB,QAAQ,EACR,KAAK,gBAAgB,EACrB,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,GAC5B,MAAM,WAAW,CAAA"}
|
package/dist/effect/index.js
CHANGED
|
@@ -10,13 +10,13 @@ export { ValidationError, UnauthorizedError, NotFoundError, ForbiddenError, Http
|
|
|
10
10
|
// Schema Validators
|
|
11
11
|
export * from './schema.js';
|
|
12
12
|
// Validation Helpers
|
|
13
|
-
export { getValidationData, formatSchemaErrors, validate, validateRequest, } from './validation.js';
|
|
13
|
+
export { getValidationData, formatSchemaErrors, validate, validateRequest, asValidated, asTrusted, } from './validation.js';
|
|
14
14
|
// Bridge
|
|
15
15
|
export { effectBridge, buildContextLayer, getEffectRuntime, } from './bridge.js';
|
|
16
16
|
// Handler
|
|
17
17
|
export { effectHandler, effect, handle, errorToResponse, } from './handler.js';
|
|
18
18
|
// Action Composables
|
|
19
|
-
export { action, authorize, dbTransaction, } from './action.js';
|
|
19
|
+
export { action, authorize, dbMutation, dbTransaction, } from './action.js';
|
|
20
20
|
// Response Helpers
|
|
21
21
|
export { redirect, render, renderWithErrors, json, text, notFound, forbidden, httpError, prefersJson, jsonOrRender, share, } from './responses.js';
|
|
22
22
|
// Routing
|
|
@@ -15,6 +15,30 @@ export declare const getValidationData: Effect.Effect<Record<string, unknown>, V
|
|
|
15
15
|
* Format Effect Schema parse errors into field-level validation errors.
|
|
16
16
|
*/
|
|
17
17
|
export declare function formatSchemaErrors(error: ParseResult.ParseError, messages?: Record<string, string>, attributes?: Record<string, string>): Record<string, string>;
|
|
18
|
+
/**
|
|
19
|
+
* Nominal brand marker for validated data.
|
|
20
|
+
* Private field prevents the brand from surviving object spreads.
|
|
21
|
+
*/
|
|
22
|
+
declare class ValidatedBrand {
|
|
23
|
+
private readonly __validatedBrand;
|
|
24
|
+
}
|
|
25
|
+
export type Validated<A> = A & ValidatedBrand;
|
|
26
|
+
/**
|
|
27
|
+
* Mark data as validated (type-level only).
|
|
28
|
+
*/
|
|
29
|
+
export declare const asValidated: <A>(input: A) => Validated<A>;
|
|
30
|
+
/**
|
|
31
|
+
* Nominal brand marker for trusted (server-derived) data.
|
|
32
|
+
* Private field prevents the brand from surviving object spreads.
|
|
33
|
+
*/
|
|
34
|
+
declare class TrustedBrand {
|
|
35
|
+
private readonly __trustedBrand;
|
|
36
|
+
}
|
|
37
|
+
export type Trusted<A> = A & TrustedBrand;
|
|
38
|
+
/**
|
|
39
|
+
* Mark data as trusted (type-level only).
|
|
40
|
+
*/
|
|
41
|
+
export declare const asTrusted: <A>(input: A) => Trusted<A>;
|
|
18
42
|
/**
|
|
19
43
|
* Options for validation functions.
|
|
20
44
|
*/
|
|
@@ -51,10 +75,11 @@ export interface ValidateOptions {
|
|
|
51
75
|
* Validate data against a schema.
|
|
52
76
|
* Returns validated data or fails with ValidationError.
|
|
53
77
|
*/
|
|
54
|
-
export declare function validate<A, I>(schema: S.Schema<A, I>, data: unknown, options?: ValidateOptions): Effect.Effect<A
|
|
78
|
+
export declare function validate<A, I>(schema: S.Schema<A, I>, data: unknown, options?: ValidateOptions): Effect.Effect<Validated<A>, ValidationError, never>;
|
|
55
79
|
/**
|
|
56
80
|
* Validate request data against a schema.
|
|
57
81
|
* Extracts data from request and validates in one step.
|
|
58
82
|
*/
|
|
59
|
-
export declare function validateRequest<A, I>(schema: S.Schema<A, I>, options?: ValidateOptions): Effect.Effect<A
|
|
83
|
+
export declare function validateRequest<A, I>(schema: S.Schema<A, I>, options?: ValidateOptions): Effect.Effect<Validated<A>, ValidationError, RequestService>;
|
|
84
|
+
export {};
|
|
60
85
|
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/effect/validation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE7C;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,CAC3C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvB,eAAe,EACf,cAAc,CA0Bd,CAAA;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,WAAW,CAAC,UAAU,EAC7B,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EACrC,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACtC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgBxB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAEjC;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAEnC;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAC3B,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EACtB,IAAI,EAAE,OAAO,EACb,OAAO,GAAE,eAAoB,GAC5B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,eAAe,EAAE,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/effect/validation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE7C;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,CAC3C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvB,eAAe,EACf,cAAc,CA0Bd,CAAA;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,WAAW,CAAC,UAAU,EAC7B,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EACrC,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACtC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgBxB;AAED;;;GAGG;AACH,OAAO,OAAO,cAAc;IAC1B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAM;CACxC;AAED,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,cAAc,CAAA;AAE7C;;GAEG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,EAAE,OAAO,CAAC,KAAG,SAAS,CAAC,CAAC,CAC9B,CAAA;AAEvB;;;GAGG;AACH,OAAO,OAAO,YAAY;IACxB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAM;CACtC;AAED,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,YAAY,CAAA;AAEzC;;GAEG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,OAAO,CAAC,KAAG,OAAO,CAAC,CAAC,CAC5B,CAAA;AAErB;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAEjC;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAEnC;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAC3B,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EACtB,IAAI,EAAE,OAAO,EACb,OAAO,GAAE,eAAoB,GAC5B,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,KAAK,CAAC,CAUrD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,CAAC,EAClC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EACtB,OAAO,GAAE,eAAoB,GAC5B,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,cAAc,CAAC,CAK9D"}
|
|
@@ -41,6 +41,14 @@ export function formatSchemaErrors(error, messages = {}, attributes = {}) {
|
|
|
41
41
|
}
|
|
42
42
|
return errors;
|
|
43
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Mark data as validated (type-level only).
|
|
46
|
+
*/
|
|
47
|
+
export const asValidated = (input) => input;
|
|
48
|
+
/**
|
|
49
|
+
* Mark data as trusted (type-level only).
|
|
50
|
+
*/
|
|
51
|
+
export const asTrusted = (input) => input;
|
|
44
52
|
/**
|
|
45
53
|
* Validate data against a schema.
|
|
46
54
|
* Returns validated data or fails with ValidationError.
|
|
@@ -49,7 +57,7 @@ export function validate(schema, data, options = {}) {
|
|
|
49
57
|
return S.decodeUnknown(schema)(data).pipe(Effect.mapError((error) => new ValidationError({
|
|
50
58
|
errors: formatSchemaErrors(error, options.messages, options.attributes),
|
|
51
59
|
component: options.errorComponent,
|
|
52
|
-
})));
|
|
60
|
+
})), Effect.map(asValidated));
|
|
53
61
|
}
|
|
54
62
|
/**
|
|
55
63
|
* Validate request data against a schema.
|
package/dist/schema.d.ts
CHANGED
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* Import from 'honertia/schema' for validation functionality.
|
|
6
6
|
*/
|
|
7
7
|
export { S, trimmed, nullableString, optionalString, requiredString, required, alpha, alphaDash, alphaNum, startsWith, endsWith, lowercase, uppercase, coercedNumber, positiveInt, nonNegativeInt, parsePositiveInt, between, digits, digitsBetween, gt, gte, lt, lte, multipleOf, coercedBoolean, checkbox, accepted, declined, coercedDate, nullableDate, after, afterOrEqual, before, beforeOrEqual, ensureArray, distinct, minItems, maxItems, inArray, notIn, email, nullableEmail, url, nullableUrl, uuid, nullableUuid, ip, ipv4, ipv6, macAddress, jsonString, confirmed, size, min, max, password, nullable, filled, excludeIf, } from './effect/schema.js';
|
|
8
|
-
export { getValidationData, formatSchemaErrors, validate, validateRequest, } from './effect/validation.js';
|
|
8
|
+
export { getValidationData, formatSchemaErrors, validate, validateRequest, asValidated, asTrusted, type Validated, type Trusted, } from './effect/validation.js';
|
|
9
9
|
//# sourceMappingURL=schema.d.ts.map
|
package/dist/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAEL,CAAC,EAED,OAAO,EACP,cAAc,EACd,cAAc,EACd,cAAc,EACd,QAAQ,EACR,KAAK,EACL,SAAS,EACT,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,SAAS,EACT,SAAS,EAET,aAAa,EACb,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,OAAO,EACP,MAAM,EACN,aAAa,EACb,EAAE,EACF,GAAG,EACH,EAAE,EACF,GAAG,EACH,UAAU,EAEV,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,QAAQ,EAER,WAAW,EACX,YAAY,EACZ,KAAK,EACL,YAAY,EACZ,MAAM,EACN,aAAa,EAEb,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,QAAQ,EAER,OAAO,EACP,KAAK,EAEL,KAAK,EACL,aAAa,EACb,GAAG,EACH,WAAW,EACX,IAAI,EACJ,YAAY,EACZ,EAAE,EACF,IAAI,EACJ,IAAI,EACJ,UAAU,EACV,UAAU,EAEV,SAAS,EAET,IAAI,EACJ,GAAG,EACH,GAAG,EAEH,QAAQ,EAER,QAAQ,EACR,MAAM,EACN,SAAS,GACV,MAAM,oBAAoB,CAAA;AAG3B,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,eAAe,
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAEL,CAAC,EAED,OAAO,EACP,cAAc,EACd,cAAc,EACd,cAAc,EACd,QAAQ,EACR,KAAK,EACL,SAAS,EACT,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,SAAS,EACT,SAAS,EAET,aAAa,EACb,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,OAAO,EACP,MAAM,EACN,aAAa,EACb,EAAE,EACF,GAAG,EACH,EAAE,EACF,GAAG,EACH,UAAU,EAEV,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,QAAQ,EAER,WAAW,EACX,YAAY,EACZ,KAAK,EACL,YAAY,EACZ,MAAM,EACN,aAAa,EAEb,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,QAAQ,EAER,OAAO,EACP,KAAK,EAEL,KAAK,EACL,aAAa,EACb,GAAG,EACH,WAAW,EACX,IAAI,EACJ,YAAY,EACZ,EAAE,EACF,IAAI,EACJ,IAAI,EACJ,UAAU,EACV,UAAU,EAEV,SAAS,EAET,IAAI,EACJ,GAAG,EACH,GAAG,EAEH,QAAQ,EAER,QAAQ,EACR,MAAM,EACN,SAAS,GACV,MAAM,oBAAoB,CAAA;AAG3B,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,eAAe,EACf,WAAW,EACX,SAAS,EACT,KAAK,SAAS,EACd,KAAK,OAAO,GACb,MAAM,wBAAwB,CAAA"}
|
package/dist/schema.js
CHANGED
|
@@ -31,4 +31,4 @@ password,
|
|
|
31
31
|
// Utility
|
|
32
32
|
nullable, filled, excludeIf, } from './effect/schema.js';
|
|
33
33
|
// Validation Helpers
|
|
34
|
-
export { getValidationData, formatSchemaErrors, validate, validateRequest, } from './effect/validation.js';
|
|
34
|
+
export { getValidationData, formatSchemaErrors, validate, validateRequest, asValidated, asTrusted, } from './effect/validation.js';
|