@shivaedev/errors 0.6.0 → 0.8.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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.8.0 - 2026-11-04
4
+
5
+ ### Breaking
6
+
7
+ - `SensitiveFieldConflict` reports all conflicting field names in one failure across an RPC group. Replace reads of the top-level `field`, `publicSchema` and `sensitiveSchema` with iteration over `error.conflicts`, whose entries contain those properties. When constructing the error, pass `{ conflicts }`; its message is derived from the entries.
8
+
9
+ ## 0.7.0 - 2026-11-03
10
+
11
+ ### Breaking
12
+
13
+ - `rpcBoundaryHandlers(group, options, handlers)` derives each operation's rejection schema independently. Replace the former `rpcBoundary(schema, options)` second argument with `options`; every operation must declare the fallback returned by `unexpected`. Effect and Stream handlers retain their own rejection types and required services.
14
+
3
15
  ## 0.6.0 - 2026-11-03
4
16
 
5
17
  ### Added
package/README.md CHANGED
@@ -70,19 +70,23 @@ export const Handlers = Api.toLayer({
70
70
 
71
71
  `storageSave` is the application's Effect. `unexpected` constructs a member of the declared schema from the public message. The default message is `Internal server error`; `message` supplies application text, with credential-shaped strings redacted. Before masking an unexpected failure, the boundary reports its diagnostic-redacted cause through Effect's registered `ErrorReporter`s at `Error` severity. Request tracing logs that masked failure at ERROR with its redacted stack, while declared rejections stay at INFO. The original Effect cause is kept on the server rejection's non-enumerable `cause`, so a server span can trace it. Keep `cause` out of the wire schema, as the taxonomy classes do. `ServiceUnavailable` describes a declared availability failure without implying a session-provider outage.
72
72
 
73
- Apply the same boundary to an entire handler registration with `rpcBoundaryHandlers(group, boundary, handlers)`:
73
+ Apply boundary options to an entire handler registration with `rpcBoundaryHandlers(group, options, handlers)`:
74
74
 
75
75
  ```ts
76
76
  import { rpcBoundaryHandlers } from "@shivaedev/errors/rpcBoundaryHandlers.ts";
77
77
 
78
78
  export const Handlers = Api.toLayer(
79
- rpcBoundaryHandlers(Api, expose, {
80
- Save: () => storageSave,
81
- }),
79
+ rpcBoundaryHandlers(
80
+ Api,
81
+ { unexpected: (message) => new InternalServerError({ message }) },
82
+ {
83
+ Save: () => storageSave,
84
+ },
85
+ ),
82
86
  );
83
87
  ```
84
88
 
85
- The group supplies payload and result types. Each RPC must declare the boundary's rejection schema. Effect and Stream handlers share the mapping, including failures after a stream has delivered values; native `Rpc.Wrapper` options remain available. Handler service requirements pass through to the native handler Layer. Use this map inside an Effect passed to `toLayer` when handler construction needs services. Queue-backed streams and Deferred results use native handlers with an explicit boundary at their producer instead.
89
+ The group supplies payload, result and rejection types for each operation. Each handler keeps only its own declared rejections; a rejection declared by another operation is unexpected here. Every operation must declare the fallback returned by `unexpected`. Effect and Stream handlers share the mapping, including failures after a stream has delivered values; native `Rpc.Wrapper` options remain available. Handler service requirements pass through to the native handler Layer. Use this map inside an Effect passed to `toLayer` when handler construction needs services. Queue-backed streams and Deferred results use native handlers with an explicit boundary at their producer instead.
86
90
 
87
91
  ### Masking secrets in failures
88
92
 
@@ -98,7 +102,7 @@ Schema diagnostics receive additional masking: `redactText` masks rejected value
98
102
 
99
103
  `schemaSensitiveKeys(group, extraKeys?)` from `schemaSensitiveKeys.ts` derives the key predicate from native RPC payload, success, error, stream error, defect and middleware error schemas. It includes nested sensitive annotations, Redacted schemas, encoded field names and additional application keys. The predicate’s `forRpc(tag)` method selects the schema-derived policy for one RPC; additional application keys apply to every RPC. The predicate’s `maskFailure(tag, reason)` method identifies whole error or defect roots that need masking. Its `redactFailure(tag, reason, value)` method masks encoded failure values within their schemas. The host applies this predicate to logs, error reports, RPC failure data and exported traces.
100
104
 
101
- Use `yield* schemaSensitiveKeys(group, extraKeys)` to obtain the predicate. Each schema derives its encoded sensitive names independently. Masking a containing field does not independently mark its child names sensitive; native `OptionFromNullOr` encoding preserves those field scopes. Different RPC methods can use the same field name with different sensitivity. Within one RPC, diagnostics carry plain values without schema identity, so a sensitive name cannot also name a public field in its payload, success, failure or middleware schemas, including nested fields. The Effect fails with `SensitiveFieldConflict` from `schemaFieldScope.ts`, naming both schema paths. Rename one field or mark both sensitive. Explicit application keys and built-in credential rules apply everywhere and do not create mixed visibility.
105
+ Use `yield* schemaSensitiveKeys(group, extraKeys)` to obtain the predicate. Each schema derives its encoded sensitive names independently. Masking a containing field does not independently mark its child names sensitive; native `OptionFromNullOr` encoding preserves those field scopes. Different RPC methods can use the same field name with different sensitivity. Within one RPC, diagnostics carry plain values without schema identity, so a sensitive name cannot also name a public field in its payload, success, failure or middleware schemas, including nested fields. The Effect fails once with `SensitiveFieldConflict` from `schemaFieldScope.ts`. Its `conflicts` array lists every conflicting field across the RPC group, with `field`, `publicSchema` and `sensitiveSchema` for each entry; repeated occurrences of the same name within one RPC produce one entry. The error message lists every entry and both schema paths. Rename one field or mark both sensitive. Explicit application keys and built-in credential rules apply everywhere and do not create mixed visibility.
102
106
 
103
107
  RPC failure masks preserve declared wire shapes: strings use `<redacted>`, numbers use `0`, booleans use `false`, arrays use empty arrays or masked required tuple elements, and objects retain required fields with masked values. Records use empty objects, optional fields may be omitted, schema literals remain the constants declared in the contract, and whole-value union masks choose a compatible constant alternative. Native tagged-error classes retain their declared classification, including when a failure accompanies an interruption.
104
108
 
@@ -3,7 +3,5 @@ export interface RpcBoundaryOptions<E> {
3
3
  readonly message?: string;
4
4
  readonly unexpected: (message: string) => E;
5
5
  }
6
- export declare function rpcBoundary<TSchema extends Schema.ConstraintDecoder<{
7
- readonly message: string;
8
- }>>(schema: TSchema, options: RpcBoundaryOptions<TSchema["Type"]>): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, TSchema["Type"], R>;
6
+ export declare function rpcBoundary<TSchema extends Schema.Constraint>(schema: TSchema, options: RpcBoundaryOptions<TSchema["Type"]>): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, TSchema["Type"], R>;
9
7
  //# sourceMappingURL=boundary.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"boundary.d.ts","sourceRoot":"","sources":["../src/boundary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,MAAM,EAA4B,MAAM,EAAE,MAAM,QAAQ,CAAC;AAkClF,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,CAAC,CAAC;CAC5C;AACD,wBAAgB,WAAW,CAC1B,OAAO,SAAS,MAAM,CAAC,iBAAiB,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB,CAAC,EACD,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAEtD,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAkBpF"}
1
+ {"version":3,"file":"boundary.d.ts","sourceRoot":"","sources":["../src/boundary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,MAAM,EAA4B,MAAM,EAAE,MAAM,QAAQ,CAAC;AAkClF,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,CAAC,CAAC;CAC5C;AACD,wBAAgB,WAAW,CAAC,OAAO,SAAS,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAEnH,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAkBpF"}
@@ -1 +1 @@
1
- {"version":3,"file":"boundary.js","sourceRoot":"","sources":["../src/boundary.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"boundary.js","sourceRoot":"","sources":["../src/boundary.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,19 @@
1
- import { Effect, Stream } from "effect";
1
+ import { Effect, Stream, type Types } from "effect";
2
2
  import { Rpc, type RpcGroup, RpcSchema } from "effect/rpc";
3
+ import { type RpcBoundaryOptions } from "#boundary.ts";
3
4
  type Handlers<R extends Rpc.Any> = {
4
5
  readonly [TRpc in R as TRpc["_tag"]]: (...args: Parameters<Rpc.ToHandlerFn<TRpc>>) => Rpc.WrapperOr<TRpc extends {
5
6
  readonly successSchema: RpcSchema.Stream<infer TSuccess, infer _E>;
6
7
  } ? Stream.Stream<TSuccess["Type"], unknown, unknown> : Effect.Effect<Rpc.Success<TRpc>, unknown, unknown>>;
7
8
  };
8
9
  type Bounded<T, E> = T extends Effect.Effect<infer A, infer _E, infer R> ? Effect.Effect<A, E, R> : T extends Stream.Stream<infer A, infer _E, infer R> ? Stream.Stream<A, E, R> : T extends Rpc.Wrapper<infer TValue> ? Rpc.Wrapper<Bounded<TValue, E>> : never;
9
- type BoundedHandlers<THandlers, E> = {
10
- readonly [TKey in keyof THandlers]: THandlers[TKey] extends (...args: infer TArgs) => infer TValue ? (...args: TArgs) => Bounded<TValue, E> : never;
10
+ type Rejection<TRpc extends Rpc.Any> = TRpc extends Rpc.AnyWithProps ? TRpc["errorSchema"]["Type"] | (TRpc["successSchema"] extends RpcSchema.Stream<infer _A, infer E> ? E["Type"] : never) : never;
11
+ type BoundedHandlers<TRpcs extends Rpc.Any, THandlers> = {
12
+ readonly [TKey in keyof THandlers]: THandlers[TKey] extends (...args: infer TArgs) => infer TValue ? (...args: TArgs) => Bounded<TValue, Rejection<Extract<TRpcs, {
13
+ readonly _tag: TKey;
14
+ }>>> : never;
11
15
  };
12
- export declare function rpcBoundaryHandlers<TRpcs extends Rpc.Any, E, THandlers extends Handlers<TRpcs>>(group: RpcGroup.RpcGroup<TRpcs>, boundary: <A, TError, R>(effect: Effect.Effect<A, TError, R>) => Effect.Effect<A, E, R>, handlers: THandlers): BoundedHandlers<THandlers, E>;
16
+ type GroupOptions<TRpcs extends Rpc.Any> = Types.UnionToIntersection<TRpcs extends unknown ? RpcBoundaryOptions<Rejection<TRpcs>> : never>;
17
+ export declare function rpcBoundaryHandlers<TRpcs extends Rpc.Any, THandlers extends Handlers<TRpcs>>(group: RpcGroup.RpcGroup<TRpcs>, options: NoInfer<GroupOptions<TRpcs>>, handlers: THandlers): BoundedHandlers<TRpcs, THandlers>;
13
18
  export {};
14
19
  //# sourceMappingURL=rpcBoundaryHandlers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rpcBoundaryHandlers.d.ts","sourceRoot":"","sources":["../src/rpcBoundaryHandlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,GAAG,EAAE,KAAK,QAAQ,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG3D,KAAK,QAAQ,CAAC,CAAC,SAAS,GAAG,CAAC,GAAG,IAAI;IAClC,QAAQ,EAAE,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CACrC,GAAG,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,KACtC,GAAG,CAAC,SAAS,CACjB,IAAI,SAAS;QAAE,QAAQ,CAAC,aAAa,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAA;KAAE,GAChF,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,GACjD,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CACrD;CACD,CAAC;AAEF,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC,IAChB,CAAC,SAAS,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC,GAChD,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GACtB,CAAC,SAAS,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC,GAClD,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GACtB,CAAC,SAAS,GAAG,CAAC,OAAO,CAAC,MAAM,MAAM,CAAC,GAClC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,GAC/B,KAAK,CAAC;AAEZ,KAAK,eAAe,CAAC,SAAS,EAAE,CAAC,IAAI;IACpC,QAAQ,EAAE,IAAI,IAAI,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,MAAM,KAAK,KAAK,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,KAAK;CACnJ,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,KAAK,SAAS,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,SAAS,SAAS,QAAQ,CAAC,KAAK,CAAC,EAC9F,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,EAC/B,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EACvF,QAAQ,EAAE,SAAS,GACjB,eAAe,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"rpcBoundaryHandlers.d.ts","sourceRoot":"","sources":["../src/rpcBoundaryHandlers.ts"],"names":[],"mappings":"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"}
@@ -1,17 +1,24 @@
1
- import { Effect, Result, Stream } from "effect";
1
+ import { Effect, Result, Schema, Stream } from "effect";
2
2
  import { Rpc, RpcSchema } from "effect/rpc";
3
- export function rpcBoundaryHandlers(group, boundary, handlers) {
4
- return Object.fromEntries(Object.entries(handlers).map(([tag, handler]) => [
5
- tag,
6
- (...args) => {
7
- const constructed = Result.try(() => handler(...args));
8
- if (Result.isFailure(constructed)) {
9
- const failure = boundary(Effect.die(constructed.failure));
10
- const rpc = group.requests.get(tag);
11
- return Rpc.isRpc(rpc) && RpcSchema.isStreamSchema(rpc.successSchema) ? Stream.fromEffect(failure) : failure;
12
- }
13
- return Rpc.wrapMap(constructed.success, (result) => Effect.isEffect(result) ? boundary(result) : Stream.catchCause(result, (cause) => Stream.fromEffect(boundary(Effect.failCause(cause)))));
14
- },
15
- ]));
3
+ import { rpcBoundary } from "#boundary.ts";
4
+ export function rpcBoundaryHandlers(group, options, handlers) {
5
+ return Object.fromEntries(Array.from(group.requests.values(), (rpc) => {
6
+ const tag = rpc._tag;
7
+ const handler = handlers[tag];
8
+ const streaming = RpcSchema.isStreamSchema(rpc.successSchema);
9
+ const schema = RpcSchema.isStreamSchema(rpc.successSchema) ? Schema.Union([rpc.errorSchema, rpc.successSchema.error]) : rpc.errorSchema;
10
+ const boundary = rpcBoundary(schema, options);
11
+ return [
12
+ tag,
13
+ (...args) => {
14
+ const constructed = Result.try(() => handler(...args));
15
+ if (Result.isFailure(constructed)) {
16
+ const failure = boundary(Effect.die(constructed.failure));
17
+ return streaming ? Stream.fromEffect(failure) : failure;
18
+ }
19
+ return Rpc.wrapMap(constructed.success, (result) => Effect.isEffect(result) ? boundary(result) : Stream.catchCause(result, (cause) => Stream.fromEffect(boundary(Effect.failCause(cause)))));
20
+ },
21
+ ];
22
+ }));
16
23
  }
17
24
  //# sourceMappingURL=rpcBoundaryHandlers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rpcBoundaryHandlers.js","sourceRoot":"","sources":["../src/rpcBoundaryHandlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,GAAG,EAAiB,SAAS,EAAE,MAAM,YAAY,CAAC;AA+B3D,MAAM,UAAU,mBAAmB,CAClC,KAAiC,EACjC,QAA6F,EAC7F,QAAsF;IAEtF,OAAO,MAAM,CAAC,WAAW,CACxB,MAAM,CAAC,OAAO,CAAqD,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC;QACpG,GAAG;QACH,CAAC,GAAG,IAAa,EAAE,EAAE;YACpB,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;YACvD,IAAI,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC;gBACnC,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;gBAC1D,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACpC,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,cAAc,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAC7G,CAAC;YACD,OAAO,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,CAClD,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CACvI,CAAC;QACH,CAAC;KACD,CAAC,CACF,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"rpcBoundaryHandlers.js","sourceRoot":"","sources":["../src/rpcBoundaryHandlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAc,MAAM,QAAQ,CAAC;AACpE,OAAO,EAAE,GAAG,EAAiB,SAAS,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAA2B,WAAW,EAAE,MAAM,cAAc,CAAC;AAuCpE,MAAM,UAAU,mBAAmB,CAClC,KAAoE,EACpE,OAAoC,EACpC,QAAoF;IAEpF,OAAO,MAAM,CAAC,WAAW,CACxB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE;QAC3C,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC;QACrB,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,SAAS,GAAG,SAAS,CAAC,cAAc,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC9D,MAAM,MAAM,GAAG,SAAS,CAAC,cAAc,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC;QACxI,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9C,OAAO;YACN,GAAG;YACH,CAAC,GAAG,IAAa,EAAE,EAAE;gBACpB,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;gBACvD,IAAI,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC;oBACnC,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;oBAC1D,OAAO,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;gBACzD,CAAC;gBACD,OAAO,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,CAClD,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CACvI,CAAC;YACH,CAAC;SACD,CAAC;IACH,CAAC,CAAC,CACF,CAAC;AACH,CAAC"}
@@ -1,12 +1,14 @@
1
1
  import { Effect, Schema, type SchemaAST } from "effect";
2
2
  export declare function schemaFieldKeys(ast: SchemaAST.AST, extra: readonly string[]): Set<string>;
3
3
  declare const SensitiveFieldConflict_base: Schema.Class<SensitiveFieldConflict, Schema.TaggedStruct<"SensitiveFieldConflict", {
4
- readonly field: Schema.String;
5
- readonly message: Schema.String;
6
- readonly publicSchema: Schema.String;
7
- readonly sensitiveSchema: Schema.String;
4
+ readonly conflicts: Schema.$Array<Schema.Struct<{
5
+ readonly field: Schema.String;
6
+ readonly publicSchema: Schema.String;
7
+ readonly sensitiveSchema: Schema.String;
8
+ }>>;
8
9
  }>, import("effect/Cause").YieldableError>;
9
10
  export declare class SensitiveFieldConflict extends SensitiveFieldConflict_base {
11
+ get message(): string;
10
12
  }
11
13
  export declare const validateFieldScope: (schemas: readonly {
12
14
  readonly ast: SchemaAST.AST;
@@ -1 +1 @@
1
- {"version":3,"file":"schemaFieldScope.d.ts","sourceRoot":"","sources":["../src/schemaFieldScope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;AAIxD,wBAAgB,eAAe,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,eAe3E;;;;;;;AAyED,qBAAa,sBAAuB,SAAQ,2BAK1C;CAAG;AAEL,eAAO,MAAM,kBAAkB;kBACI,SAAS,CAAC,GAAG;mBAAiB,MAAM;yFAmBrE,CAAC"}
1
+ {"version":3,"file":"schemaFieldScope.d.ts","sourceRoot":"","sources":["../src/schemaFieldScope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;AAIxD,wBAAgB,eAAe,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,eAe3E;;;;;;;;AAyED,qBAAa,sBAAuB,SAAQ,2BAE1C;IACD,IAAa,OAAO,IAAI,MAAM,CAO7B;CACD;AAED,eAAO,MAAM,kBAAkB;kBACI,SAAS,CAAC,GAAG;mBAAiB,MAAM;yFAsBrE,CAAC"}
@@ -76,26 +76,31 @@ function fieldsOf(ast, schema, extra, candidates) {
76
76
  return fields;
77
77
  }
78
78
  export class SensitiveFieldConflict extends Schema.TaggedError()("SensitiveFieldConflict", {
79
- field: Schema.String,
80
- message: Schema.String,
81
- publicSchema: Schema.String,
82
- sensitiveSchema: Schema.String,
79
+ conflicts: Schema.Array(Schema.Struct({ field: Schema.String, publicSchema: Schema.String, sensitiveSchema: Schema.String })),
83
80
  }) {
81
+ get message() {
82
+ return this.conflicts
83
+ .map(({ field, publicSchema, sensitiveSchema }) => `Sensitive field "${field}" in schema ${sensitiveSchema} conflicts with public field in schema ${publicSchema}; RPC diagnostics cannot distinguish these fields. Use distinct field names or mark both fields sensitive.`)
84
+ .join("\n");
85
+ }
84
86
  }
85
87
  export const validateFieldScope = Effect.fn("Errors.validateFieldScope")(function* (schemas, extra) {
86
88
  const candidates = new Set(schemas.flatMap(({ ast }) => [...schemaFieldKeys(ast, [])]));
87
89
  const fields = schemas.flatMap(({ ast, name }) => fieldsOf(ast, name, extra, candidates));
90
+ const conflicts = new Map();
88
91
  // A masked container protects its children without making each child name sensitive.
89
92
  for (const hidden of fields.filter((field) => candidates.has(field.key) && field.sensitive && !extra.includes(field.key) && !isSensitiveKey(field.key))) {
90
93
  const publicField = fields.find((field) => field.key === hidden.key && !field.sensitive);
91
- if (publicField !== undefined) {
92
- return yield* new SensitiveFieldConflict({
94
+ if (publicField !== undefined && !conflicts.has(hidden.key)) {
95
+ conflicts.set(hidden.key, {
93
96
  field: hidden.key,
94
- message: `Sensitive field "${hidden.key}" in schema ${hidden.path} conflicts with public field in schema ${publicField.path}; RPC diagnostics cannot distinguish these fields. Use distinct field names or mark both fields sensitive.`,
95
97
  publicSchema: publicField.path,
96
98
  sensitiveSchema: hidden.path,
97
99
  });
98
100
  }
99
101
  }
102
+ if (conflicts.size > 0) {
103
+ return yield* new SensitiveFieldConflict({ conflicts: [...conflicts.values()] });
104
+ }
100
105
  });
101
106
  //# sourceMappingURL=schemaFieldScope.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"schemaFieldScope.js","sourceRoot":"","sources":["../src/schemaFieldScope.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schemaFieldScope.js","sourceRoot":"","sources":["../src/schemaFieldScope.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,9 @@
1
1
  import { Effect } from "effect";
2
2
  import { Rpc, type RpcGroup } from "effect/rpc";
3
+ import { SensitiveFieldConflict } from "#schemaFieldScope.ts";
3
4
  export declare const schemaSensitiveKeys: <R extends Rpc.Any>(group: RpcGroup.RpcGroup<R>, extra?: readonly string[] | undefined) => Effect.Effect<((key: string) => boolean) & {
4
5
  forRpc: (tag: string | undefined) => (key: string) => boolean;
5
6
  maskFailure: (tag: string | undefined, reason: "Fail" | "Die") => boolean;
6
7
  redactFailure: (tag: string | undefined, reason: "Fail" | "Die", value: unknown) => unknown;
7
- }, import("./wireMask.ts").InvalidRedactionMask | import("#schemaFieldScope.ts").SensitiveFieldConflict, never>;
8
+ }, import("./wireMask.ts").InvalidRedactionMask | SensitiveFieldConflict, never>;
8
9
  //# sourceMappingURL=schemaSensitiveKeys.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schemaSensitiveKeys.d.ts","sourceRoot":"","sources":["../src/schemaSensitiveKeys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,GAAG,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AA6BhD,eAAO,MAAM,mBAAmB,GAAgC,CAAC,SAAS,GAAG,CAAC,GAAG,8FAOxD,MAAM;kBAIf,MAAM,GAAG,SAAS,WAJT,MAAM;uBAKV,MAAM,GAAG,SAAS,UAAU,MAAM,GAAG,KAAK;yBAExC,MAAM,GAAG,SAAS,UAAU,MAAM,GAAG,KAAK,SAAS,OAAO;+GAK/E,CAAC"}
1
+ {"version":3,"file":"schemaSensitiveKeys.d.ts","sourceRoot":"","sources":["../src/schemaSensitiveKeys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,GAAG,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAuC,MAAM,sBAAsB,CAAC;AA4BnG,eAAO,MAAM,mBAAmB,GAAgC,CAAC,SAAS,GAAG,CAAC,GAAG,8FAmBxD,MAAM;kBAIf,MAAM,GAAG,SAAS,WAJT,MAAM;uBAKV,MAAM,GAAG,SAAS,UAAU,MAAM,GAAG,KAAK;yBAExC,MAAM,GAAG,SAAS,UAAU,MAAM,GAAG,KAAK,SAAS,OAAO;gFAK/E,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { Effect } from "effect";
2
2
  import { Rpc } from "effect/rpc";
3
- import { schemaFieldKeys, validateFieldScope } from "#schemaFieldScope.ts";
3
+ import { SensitiveFieldConflict, schemaFieldKeys, validateFieldScope } from "#schemaFieldScope.ts";
4
4
  import { maskedValue } from "#schemaSensitiveAst.ts";
5
5
  import { isSensitiveKey, REDACTED } from "#sensitive.ts";
6
6
  import { wireRedactor } from "#wireRedactor.ts";
@@ -29,11 +29,21 @@ const rpcSensitiveKeys = Effect.fnUntraced(function* (rpc, extra) {
29
29
  });
30
30
  export const schemaSensitiveKeys = Effect.fnUntraced(function* (group, extra = []) {
31
31
  const policies = new Map();
32
+ const conflicts = [];
32
33
  for (const rpc of group.requests.values()) {
33
34
  if (Rpc.isRpc(rpc)) {
34
- policies.set(rpc._tag, yield* rpcSensitiveKeys(rpc, extra));
35
+ const policy = yield* rpcSensitiveKeys(rpc, extra).pipe(Effect.catchTag("SensitiveFieldConflict", (error) => {
36
+ conflicts.push(...error.conflicts);
37
+ return Effect.void;
38
+ }));
39
+ if (policy !== undefined) {
40
+ policies.set(rpc._tag, policy);
41
+ }
35
42
  }
36
43
  }
44
+ if (conflicts.length > 0) {
45
+ return yield* new SensitiveFieldConflict({ conflicts });
46
+ }
37
47
  function sensitive(key) {
38
48
  return extra.includes(key) || isSensitiveKey(key) || [...policies.values()].some((policy) => policy(key));
39
49
  }
@@ -1 +1 @@
1
- {"version":3,"file":"schemaSensitiveKeys.js","sourceRoot":"","sources":["../src/schemaSensitiveKeys.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schemaSensitiveKeys.js","sourceRoot":"","sources":["../src/schemaSensitiveKeys.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shivaedev/errors",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "Typed expected failures and secret-safe failure reporting for Effect applications",
5
5
  "keywords": [
6
6
  "effect"
@@ -45,8 +45,8 @@
45
45
  "README.md"
46
46
  ],
47
47
  "devDependencies": {
48
- "@shivaedev/quality": "0.57.0",
49
- "@shivaedev/test-story": "0.35.0",
48
+ "@shivaedev/quality": "0.58.0",
49
+ "@shivaedev/test-story": "0.37.0",
50
50
  "@types/node": "24.19.2",
51
51
  "effect": "4.0.6",
52
52
  "typescript": "7.0.2",
package/src/boundary.ts CHANGED
@@ -36,11 +36,7 @@ export interface RpcBoundaryOptions<E> {
36
36
  readonly message?: string;
37
37
  readonly unexpected: (message: string) => E;
38
38
  }
39
- export function rpcBoundary<
40
- TSchema extends Schema.ConstraintDecoder<{
41
- readonly message: string;
42
- }>,
43
- >(schema: TSchema, options: RpcBoundaryOptions<TSchema["Type"]>) {
39
+ export function rpcBoundary<TSchema extends Schema.Constraint>(schema: TSchema, options: RpcBoundaryOptions<TSchema["Type"]>) {
44
40
  const declared = Schema.is(schema);
45
41
  return <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A, TSchema["Type"], R> =>
46
42
  Effect.catchCause(self, (cause) => {
@@ -1,5 +1,6 @@
1
- import { Effect, Result, Stream } from "effect";
1
+ import { Effect, Result, Schema, Stream, type Types } from "effect";
2
2
  import { Rpc, type RpcGroup, RpcSchema } from "effect/rpc";
3
+ import { type RpcBoundaryOptions, rpcBoundary } from "#boundary.ts";
3
4
 
4
5
  type HandlerResult = Effect.Effect<unknown, unknown, unknown> | Stream.Stream<unknown, unknown, unknown>;
5
6
  type Handlers<R extends Rpc.Any> = {
@@ -21,34 +22,48 @@ type Bounded<T, E> =
21
22
  ? Rpc.Wrapper<Bounded<TValue, E>>
22
23
  : never;
23
24
 
24
- type BoundedHandlers<THandlers, E> = {
25
- readonly [TKey in keyof THandlers]: THandlers[TKey] extends (...args: infer TArgs) => infer TValue ? (...args: TArgs) => Bounded<TValue, E> : never;
25
+ type Rejection<TRpc extends Rpc.Any> = TRpc extends Rpc.AnyWithProps
26
+ ? TRpc["errorSchema"]["Type"] | (TRpc["successSchema"] extends RpcSchema.Stream<infer _A, infer E> ? E["Type"] : never)
27
+ : never;
28
+
29
+ type BoundedHandlers<TRpcs extends Rpc.Any, THandlers> = {
30
+ readonly [TKey in keyof THandlers]: THandlers[TKey] extends (...args: infer TArgs) => infer TValue
31
+ ? (...args: TArgs) => Bounded<TValue, Rejection<Extract<TRpcs, { readonly _tag: TKey }>>>
32
+ : never;
26
33
  };
27
34
 
28
- export function rpcBoundaryHandlers<TRpcs extends Rpc.Any, E, THandlers extends Handlers<TRpcs>>(
35
+ type GroupOptions<TRpcs extends Rpc.Any> = Types.UnionToIntersection<TRpcs extends unknown ? RpcBoundaryOptions<Rejection<TRpcs>> : never>;
36
+
37
+ export function rpcBoundaryHandlers<TRpcs extends Rpc.Any, THandlers extends Handlers<TRpcs>>(
29
38
  group: RpcGroup.RpcGroup<TRpcs>,
30
- boundary: <A, TError, R>(effect: Effect.Effect<A, TError, R>) => Effect.Effect<A, E, R>,
39
+ options: NoInfer<GroupOptions<TRpcs>>,
31
40
  handlers: THandlers,
32
- ): BoundedHandlers<THandlers, E>;
33
- export function rpcBoundaryHandlers(
34
- group: RpcGroup.RpcGroup<Rpc.Any>,
35
- boundary: <A, TError, R>(effect: Effect.Effect<A, TError, R>) => Effect.Effect<A, unknown, R>,
36
- handlers: Readonly<Record<string, (...args: never[]) => Rpc.WrapperOr<HandlerResult>>>,
41
+ ): BoundedHandlers<TRpcs, THandlers>;
42
+ export function rpcBoundaryHandlers<TTag extends string>(
43
+ group: RpcGroup.RpcGroup<Rpc.AnyWithProps & { readonly _tag: TTag }>,
44
+ options: RpcBoundaryOptions<unknown>,
45
+ handlers: Readonly<Record<TTag, (...args: never[]) => Rpc.WrapperOr<HandlerResult>>>,
37
46
  ) {
38
47
  return Object.fromEntries(
39
- Object.entries<(...args: never[]) => Rpc.WrapperOr<HandlerResult>>(handlers).map(([tag, handler]) => [
40
- tag,
41
- (...args: never[]) => {
42
- const constructed = Result.try(() => handler(...args));
43
- if (Result.isFailure(constructed)) {
44
- const failure = boundary(Effect.die(constructed.failure));
45
- const rpc = group.requests.get(tag);
46
- return Rpc.isRpc(rpc) && RpcSchema.isStreamSchema(rpc.successSchema) ? Stream.fromEffect(failure) : failure;
47
- }
48
- return Rpc.wrapMap(constructed.success, (result) =>
49
- Effect.isEffect(result) ? boundary(result) : Stream.catchCause(result, (cause) => Stream.fromEffect(boundary(Effect.failCause(cause)))),
50
- );
51
- },
52
- ]),
48
+ Array.from(group.requests.values(), (rpc) => {
49
+ const tag = rpc._tag;
50
+ const handler = handlers[tag];
51
+ const streaming = RpcSchema.isStreamSchema(rpc.successSchema);
52
+ const schema = RpcSchema.isStreamSchema(rpc.successSchema) ? Schema.Union([rpc.errorSchema, rpc.successSchema.error]) : rpc.errorSchema;
53
+ const boundary = rpcBoundary(schema, options);
54
+ return [
55
+ tag,
56
+ (...args: never[]) => {
57
+ const constructed = Result.try(() => handler(...args));
58
+ if (Result.isFailure(constructed)) {
59
+ const failure = boundary(Effect.die(constructed.failure));
60
+ return streaming ? Stream.fromEffect(failure) : failure;
61
+ }
62
+ return Rpc.wrapMap(constructed.success, (result) =>
63
+ Effect.isEffect(result) ? boundary(result) : Stream.catchCause(result, (cause) => Stream.fromEffect(boundary(Effect.failCause(cause)))),
64
+ );
65
+ },
66
+ ];
67
+ }),
53
68
  );
54
69
  }
@@ -91,11 +91,17 @@ function fieldsOf(ast: SchemaAST.AST, schema: string, extra: readonly string[],
91
91
  }
92
92
 
93
93
  export class SensitiveFieldConflict extends Schema.TaggedError<SensitiveFieldConflict>()("SensitiveFieldConflict", {
94
- field: Schema.String,
95
- message: Schema.String,
96
- publicSchema: Schema.String,
97
- sensitiveSchema: Schema.String,
98
- }) {}
94
+ conflicts: Schema.Array(Schema.Struct({ field: Schema.String, publicSchema: Schema.String, sensitiveSchema: Schema.String })),
95
+ }) {
96
+ override get message(): string {
97
+ return this.conflicts
98
+ .map(
99
+ ({ field, publicSchema, sensitiveSchema }) =>
100
+ `Sensitive field "${field}" in schema ${sensitiveSchema} conflicts with public field in schema ${publicSchema}; RPC diagnostics cannot distinguish these fields. Use distinct field names or mark both fields sensitive.`,
101
+ )
102
+ .join("\n");
103
+ }
104
+ }
99
105
 
100
106
  export const validateFieldScope = Effect.fn("Errors.validateFieldScope")(function* (
101
107
  schemas: readonly { readonly ast: SchemaAST.AST; readonly name: string }[],
@@ -103,18 +109,21 @@ export const validateFieldScope = Effect.fn("Errors.validateFieldScope")(functio
103
109
  ) {
104
110
  const candidates = new Set(schemas.flatMap(({ ast }) => [...schemaFieldKeys(ast, [])]));
105
111
  const fields = schemas.flatMap(({ ast, name }) => fieldsOf(ast, name, extra, candidates));
112
+ const conflicts = new Map<string, SensitiveFieldConflict["conflicts"][number]>();
106
113
  // A masked container protects its children without making each child name sensitive.
107
114
  for (const hidden of fields.filter(
108
115
  (field) => candidates.has(field.key) && field.sensitive && !extra.includes(field.key) && !isSensitiveKey(field.key),
109
116
  )) {
110
117
  const publicField = fields.find((field) => field.key === hidden.key && !field.sensitive);
111
- if (publicField !== undefined) {
112
- return yield* new SensitiveFieldConflict({
118
+ if (publicField !== undefined && !conflicts.has(hidden.key)) {
119
+ conflicts.set(hidden.key, {
113
120
  field: hidden.key,
114
- message: `Sensitive field "${hidden.key}" in schema ${hidden.path} conflicts with public field in schema ${publicField.path}; RPC diagnostics cannot distinguish these fields. Use distinct field names or mark both fields sensitive.`,
115
121
  publicSchema: publicField.path,
116
122
  sensitiveSchema: hidden.path,
117
123
  });
118
124
  }
119
125
  }
126
+ if (conflicts.size > 0) {
127
+ return yield* new SensitiveFieldConflict({ conflicts: [...conflicts.values()] });
128
+ }
120
129
  });
@@ -1,6 +1,6 @@
1
1
  import { Effect } from "effect";
2
2
  import { Rpc, type RpcGroup } from "effect/rpc";
3
- import { schemaFieldKeys, validateFieldScope } from "#schemaFieldScope.ts";
3
+ import { SensitiveFieldConflict, schemaFieldKeys, validateFieldScope } from "#schemaFieldScope.ts";
4
4
  import { maskedValue } from "#schemaSensitiveAst.ts";
5
5
  import { isSensitiveKey, REDACTED } from "#sensitive.ts";
6
6
  import { wireRedactor } from "#wireRedactor.ts";
@@ -30,11 +30,23 @@ const rpcSensitiveKeys = Effect.fnUntraced(function* (rpc: Rpc.AnyWithProps, ext
30
30
  });
31
31
  export const schemaSensitiveKeys = Effect.fnUntraced(function* <R extends Rpc.Any>(group: RpcGroup.RpcGroup<R>, extra: readonly string[] = []) {
32
32
  const policies = new Map<string, Effect.Success<ReturnType<typeof rpcSensitiveKeys>>>();
33
+ const conflicts: SensitiveFieldConflict["conflicts"][number][] = [];
33
34
  for (const rpc of group.requests.values()) {
34
35
  if (Rpc.isRpc(rpc)) {
35
- policies.set(rpc._tag, yield* rpcSensitiveKeys(rpc, extra));
36
+ const policy = yield* rpcSensitiveKeys(rpc, extra).pipe(
37
+ Effect.catchTag("SensitiveFieldConflict", (error) => {
38
+ conflicts.push(...error.conflicts);
39
+ return Effect.void;
40
+ }),
41
+ );
42
+ if (policy !== undefined) {
43
+ policies.set(rpc._tag, policy);
44
+ }
36
45
  }
37
46
  }
47
+ if (conflicts.length > 0) {
48
+ return yield* new SensitiveFieldConflict({ conflicts });
49
+ }
38
50
  function sensitive(key: string) {
39
51
  return extra.includes(key) || isSensitiveKey(key) || [...policies.values()].some((policy) => policy(key));
40
52
  }