@shivaedev/errors 0.3.0 → 0.4.1

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,23 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.1 - 2026-11-01
4
+
5
+ ### Fixed
6
+
7
+ - Mask rejected values in Schema error text (`got` and `Expected …, actual …`) and native issue inputs during diagnostic and wire redaction, including error reporting. Keep schema paths and expected types readable.
8
+
9
+ ## 0.4.0 - 2026-10-31
10
+
11
+ ### Fixed
12
+
13
+ - Derive encoded sensitive names separately for each RPC schema, keeping private fields in one method from changing public state and native failure decoding in another method.
14
+ - Keep the child key names of a fully masked field public elsewhere, including through native `OptionFromNullOr` encoding.
15
+
16
+ ### Breaking
17
+
18
+ - Refuse RPC registration when a schema-sensitive field name also names a public field within that method's schemas, including nested fields, encoded names and middleware errors. Diagnostics cannot distinguish those plain values. Rename one field or mark both sensitive; fields in separate RPC methods may keep different sensitivity.
19
+ - `schemaSensitiveKeys` now returns an Effect. Native consumers must use `yield* schemaSensitiveKeys(group, extraKeys)` to obtain the predicate and handle `SensitiveFieldConflict` from `@shivaedev/errors/schemaFieldScope.ts`. `appHost` and Work Board's `boardLayer` include that failure in their Layer error channels.
20
+
3
21
  ## 0.3.0 - 2026-10-31
4
22
 
5
23
  ### Added
package/README.md CHANGED
@@ -88,11 +88,15 @@ The group supplies payload and result types. Each RPC must declare the boundary'
88
88
 
89
89
  `sensitive.ts` decides which names are secret. `isSensitiveKey(key)` matches credential-shaped names whatever their casing or separator, such as `sessionId`, `bearerToken`, `access_key_id` or `cardNumber`, and database diagnostic keys `db.user`, `db.user.name` and `db.connection_string`. A `SensitiveKey` is any `(key: string) => boolean`, so an application can widen the policy with its own names. `redactText(text, sensitive, maxLength?, key?)` masks credential-shaped text and `key=value` assignments inside a string, URL user information, query values and fragments, and cuts it at 2,048 characters by default; passing `Infinity` keeps complete public text. The optional `key` supplies context for standalone URL components such as `url.query`. `redactUrl(value, key?)` from `sensitive.ts` applies just the URL rules, including nested JSON strings. Masked values become `REDACTED`, the string `<redacted>`.
90
90
 
91
+ Schema diagnostics receive additional masking: `redactText` masks rejected values after `got` or `Expected …, actual …`, before URL masking and truncation. Expected types and schema paths remain readable. Structured redaction also masks the native Schema issue tree's reported `input` values, so those values do not reappear in error reports.
92
+
91
93
  `redact.ts` applies that policy to structured values. `redact(value, sensitive?)` masks values under sensitive keys and credential text inside strings, summarises large collections and binary data, and stops cyclic payloads at a depth limit; use it for diagnostics. `redactRecord(values, sensitive?)` masks every top-level record entry without limiting the number of keys, while applying diagnostic limits within each value. `redactWire(value, sensitive?)` applies the same masking without summaries or truncation; use it for failure data sent to a client.
92
94
 
93
95
  `redactCause.ts` applies it to Effect causes. `redactCause(cause, sensitive?)` rebuilds a cause with masked defects and keeps its typed failures, interruptions and annotations as they are, so the failure channel keeps its type. `redactDiagnosticCause(cause, sensitive?)` masks failures, defects and annotations for diagnostics, `redactDefect(defect, sensitive?)` masks one defect, and `redactingErrorReporter(reporter, sensitive?)` wraps an Effect error reporter so it only ever receives diagnostic-masked causes.
94
96
 
95
- `schemaSensitiveKeys(group, extraKeys?)` from `schemaSensitiveKeys.ts` derives the key predicate from native RPC payload, success, error, defect and middleware error schemas. It includes nested sensitive annotations, Redacted schemas, encoded field names and additional application keys. Its `forRpc(tag)` method selects the schema-derived policy for one RPC; additional application keys apply to every RPC. Its `maskFailure(tag, reason)` method identifies whole error or defect roots that need masking. The host applies this predicate to logs, error reports, RPC failure data and exported traces.
97
+ `schemaSensitiveKeys(group, extraKeys?)` from `schemaSensitiveKeys.ts` derives the key predicate from native RPC payload, success, 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. The host applies this predicate to logs, error reports, RPC failure data and exported traces.
98
+
99
+ 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.
96
100
 
97
101
  The policy matches names and credential or URL shapes, not arbitrary values: it does not scan prose for personal data, so keep secrets out of free text and span names.
98
102
 
@@ -1 +1 @@
1
- {"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../src/redact.ts"],"names":[],"mappings":"AACA,OAAO,EAA0D,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAyD1G,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,GAAE,YAA6B,GAAG,OAAO,CAExF;AACD,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,GAAE,YAA6B,GAAG,OAAO,CAE5F;AACD,wBAAgB,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS,GAAE,YAA6B,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzI"}
1
+ {"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../src/redact.ts"],"names":[],"mappings":"AACA,OAAO,EAA0D,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AA0D1G,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,GAAE,YAA6B,GAAG,OAAO,CAExF;AACD,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,GAAE,YAA6B,GAAG,OAAO,CAE5F;AACD,wBAAgB,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS,GAAE,YAA6B,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzI"}
package/dist/redact.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Predicate, Redacted } from "effect";
1
+ import { Predicate, Redacted, SchemaIssue } from "effect";
2
2
  import { isSensitiveKey, REDACTED, redactErrorStack, redactText } from "#sensitive.ts";
3
3
  const MAX_DEPTH = 8;
4
4
  const MAX_ENTRIES = 50;
@@ -32,7 +32,8 @@ function collection(value, sensitive, depth, bounded, parentKey) {
32
32
  const entries = entriesOf(value, sensitive, bounded);
33
33
  const kept = entries.slice(0, bounded ? MAX_ENTRIES : entries.length).map(([key, nested]) => {
34
34
  const stackHeader = key === "stack" && typeof nested === "string" && (sensitive("name") || sensitive("message"));
35
- return [key, sensitive(key) || stackHeader ? REDACTED : walk(nested, sensitive, depth + 1, bounded, key)];
35
+ const schemaInput = key === "input" && SchemaIssue.isIssue(value);
36
+ return [key, sensitive(key) || stackHeader || schemaInput ? REDACTED : walk(nested, sensitive, depth + 1, bounded, key)];
36
37
  });
37
38
  return Object.fromEntries(bounded && entries.length > MAX_ENTRIES ? [...kept, ["<truncated>", `${entries.length - MAX_ENTRIES} more keys`]] : kept);
38
39
  }
@@ -1 +1 @@
1
- {"version":3,"file":"redact.js","sourceRoot":"","sources":["../src/redact.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"redact.js","sourceRoot":"","sources":["../src/redact.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { Effect, Schema, type SchemaAST } from "effect";
2
+ export declare function schemaFieldKeys(ast: SchemaAST.AST, extra: readonly string[]): Set<string>;
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;
8
+ }>, import("effect/Cause").YieldableError>;
9
+ export declare class SensitiveFieldConflict extends SensitiveFieldConflict_base {
10
+ }
11
+ export declare const validateFieldScope: (schemas: readonly {
12
+ readonly ast: SchemaAST.AST;
13
+ readonly name: string;
14
+ }[], extra: readonly string[]) => Effect.Effect<undefined, SensitiveFieldConflict, never>;
15
+ export {};
16
+ //# sourceMappingURL=schemaFieldScope.d.ts.map
@@ -0,0 +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;;;;;;;AAyDD,qBAAa,sBAAuB,SAAQ,2BAK1C;CAAG;AAEL,eAAO,MAAM,kBAAkB;kBACI,SAAS,CAAC,GAAG;mBAAiB,MAAM;yFAmBrE,CAAC"}
@@ -0,0 +1,90 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { children, collect, collectEncodedKeys, collectFieldKeys, marked, maskedValue } from "#schemaSensitiveAst.ts";
3
+ import { isSensitiveKey } from "#sensitive.ts";
4
+ export function schemaFieldKeys(ast, extra) {
5
+ const keys = new Set(extra);
6
+ const nodes = new Set();
7
+ collect(ast, nodes);
8
+ const properties = [...nodes].flatMap((node) => (node._tag === "Objects" ? node.propertySignatures : []));
9
+ collectFieldKeys(properties, keys, marked);
10
+ let previousSize;
11
+ do {
12
+ previousSize = keys.size;
13
+ collectFieldKeys(properties, keys, (node) => maskedValue(node, keys));
14
+ for (const node of nodes) {
15
+ collectEncodedKeys(node, keys);
16
+ }
17
+ } while (keys.size !== previousSize);
18
+ return keys;
19
+ }
20
+ function fieldsOf(ast, schema, extra, candidates) {
21
+ const fields = [];
22
+ function visitIndex(index, path, hidden, seen) {
23
+ const accepts = Schema.is(Schema.make(index.parameter));
24
+ for (const key of candidates) {
25
+ if (accepts(key)) {
26
+ fields.push({ key, path: `${path}[${key}]`, sensitive: hidden || extra.includes(key) || isSensitiveKey(key) });
27
+ }
28
+ }
29
+ visit(index.type, `${path}[value]`, hidden, seen);
30
+ }
31
+ function visitObject(node, path, hidden, seen) {
32
+ for (const property of node.propertySignatures) {
33
+ if (typeof property.name !== "string") {
34
+ continue;
35
+ }
36
+ const sensitive = hidden || extra.includes(property.name) || isSensitiveKey(property.name) || maskedValue(property.type, schemaFieldKeys(property.type, []));
37
+ const fieldPath = `${path}.${property.name}`;
38
+ fields.push({ key: property.name, path: fieldPath, sensitive });
39
+ visit(property.type, fieldPath, sensitive, seen);
40
+ }
41
+ for (const index of node.indexSignatures) {
42
+ visitIndex(index, path, hidden, seen);
43
+ }
44
+ }
45
+ function visit(node, path, hidden, ancestors) {
46
+ if (ancestors.has(node)) {
47
+ return;
48
+ }
49
+ const seen = new Set(ancestors).add(node);
50
+ const masked = hidden || marked(node);
51
+ if (node._tag === "Objects") {
52
+ visitObject(node, path, masked, seen);
53
+ return;
54
+ }
55
+ for (const [index, child] of children(node).entries()) {
56
+ visit(child, `${path}[${index}]`, masked, seen);
57
+ }
58
+ }
59
+ visit(ast, schema, false, new Set());
60
+ for (const key of schemaFieldKeys(ast, [])) {
61
+ if (!fields.some((field) => field.key === key && field.sensitive)) {
62
+ fields.push({ key, path: `${schema}.encoded.${key}`, sensitive: true });
63
+ }
64
+ }
65
+ return fields;
66
+ }
67
+ export class SensitiveFieldConflict extends Schema.TaggedError()("SensitiveFieldConflict", {
68
+ field: Schema.String,
69
+ message: Schema.String,
70
+ publicSchema: Schema.String,
71
+ sensitiveSchema: Schema.String,
72
+ }) {
73
+ }
74
+ export const validateFieldScope = Effect.fn("Errors.validateFieldScope")(function* (schemas, extra) {
75
+ const candidates = new Set(schemas.flatMap(({ ast }) => [...schemaFieldKeys(ast, [])]));
76
+ const fields = schemas.flatMap(({ ast, name }) => fieldsOf(ast, name, extra, candidates));
77
+ // A masked container protects its children without making each child name sensitive.
78
+ for (const hidden of fields.filter((field) => candidates.has(field.key) && field.sensitive && !extra.includes(field.key) && !isSensitiveKey(field.key))) {
79
+ const publicField = fields.find((field) => field.key === hidden.key && !field.sensitive);
80
+ if (publicField !== undefined) {
81
+ return yield* new SensitiveFieldConflict({
82
+ field: hidden.key,
83
+ 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.`,
84
+ publicSchema: publicField.path,
85
+ sensitiveSchema: hidden.path,
86
+ });
87
+ }
88
+ }
89
+ });
90
+ //# sourceMappingURL=schemaFieldScope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemaFieldScope.js","sourceRoot":"","sources":["../src/schemaFieldScope.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { type SchemaAST } from "effect";
2
+ export declare function children(ast: SchemaAST.AST): readonly SchemaAST.AST[];
2
3
  export declare function marked(ast: SchemaAST.AST, seen?: Set<SchemaAST.AST>): boolean;
3
4
  export declare function collectEncodedKeys(ast: SchemaAST.AST, keys: Set<string>): void;
4
5
  export declare function maskedValue(ast: SchemaAST.AST, keys: ReadonlySet<string>, seen?: Set<SchemaAST.AST>): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"schemaSensitiveAst.d.ts","sourceRoot":"","sources":["../src/schemaSensitiveAst.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;AAsBnD,wBAAgB,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,EAAE,IAAI,qBAA2B,GAAG,OAAO,CAenF;AAOD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,QAcvE;AAOD,wBAAgB,WAAW,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,IAAI,qBAA2B,GAAG,OAAO,CAmBnH;AACD,wBAAgB,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,SAAS,UAAO,QAQtF;AAMD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,SAAS,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,KAAK,OAAO,QAMlJ"}
1
+ {"version":3,"file":"schemaSensitiveAst.d.ts","sourceRoot":"","sources":["../src/schemaSensitiveAst.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;AAGnD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,GAAG,SAAS,SAAS,CAAC,GAAG,EAAE,CAerE;AAID,wBAAgB,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,EAAE,IAAI,qBAA2B,GAAG,OAAO,CAenF;AAgBD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,QAkBvE;AAOD,wBAAgB,WAAW,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,IAAI,qBAA2B,GAAG,OAAO,CAuBnH;AACD,wBAAgB,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,SAAS,UAAO,QAQtF;AAMD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,SAAS,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,KAAK,OAAO,QAMlJ"}
@@ -1,6 +1,6 @@
1
1
  import { Predicate } from "effect";
2
2
  import { isSensitiveKey } from "#sensitive.ts";
3
- function children(ast) {
3
+ export function children(ast) {
4
4
  switch (ast._tag) {
5
5
  case "Objects":
6
6
  return [...ast.propertySignatures.map((property) => property.type), ...ast.indexSignatures.flatMap((index) => [index.parameter, index.type])];
@@ -37,10 +37,21 @@ function containsSensitive(ast, keys) {
37
37
  return (marked(ast)
38
38
  || propertiesOf(ast).some((property) => typeof property.name === "string" && (keys.has(property.name) || isSensitiveKey(property.name))));
39
39
  }
40
+ function preservesFields(source, target) {
41
+ return (source._tag === "Declaration"
42
+ && Predicate.hasProperty(source.annotations?.representation, "id")
43
+ && source.annotations.representation.id === "effect/schema/Option"
44
+ && target._tag === "Union"
45
+ && target.types.some((type) => type._tag === "Null"));
46
+ }
40
47
  export function collectEncodedKeys(ast, keys) {
41
48
  let source = ast;
42
49
  let sensitive = false;
43
50
  for (const link of ast.encoding ?? []) {
51
+ if (preservesFields(source, link.to)) {
52
+ source = link.to;
53
+ continue;
54
+ }
44
55
  sensitive ||= containsSensitive(source, keys);
45
56
  if (sensitive) {
46
57
  for (const property of propertiesOf(link.to)) {
@@ -69,6 +80,10 @@ export function maskedValue(ast, keys, seen = new Set()) {
69
80
  let source = ast;
70
81
  let sensitive = false;
71
82
  for (const link of ast.encoding ?? []) {
83
+ if (preservesFields(source, link.to)) {
84
+ source = link.to;
85
+ continue;
86
+ }
72
87
  sensitive ||= containsSensitive(source, keys);
73
88
  if (sensitive && !fixedOutput(link.to)) {
74
89
  return true;
@@ -1 +1 @@
1
- {"version":3,"file":"schemaSensitiveAst.js","sourceRoot":"","sources":["../src/schemaSensitiveAst.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schemaSensitiveAst.js","sourceRoot":"","sources":["../src/schemaSensitiveAst.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
+ import { Effect } from "effect";
1
2
  import { Rpc, type RpcGroup } from "effect/rpc";
2
- export declare function schemaSensitiveKeys<R extends Rpc.Any>(group: RpcGroup.RpcGroup<R>, extra?: readonly string[]): ((key: string) => boolean) & {
3
+ export declare const schemaSensitiveKeys: <R extends Rpc.Any>(group: RpcGroup.RpcGroup<R>, extra?: readonly string[] | undefined) => Effect.Effect<((key: string) => boolean) & {
3
4
  forRpc: (tag: string | undefined) => (key: string) => boolean;
4
5
  maskFailure: (tag: string | undefined, reason: "Fail" | "Die") => boolean;
5
- };
6
+ }, import("#schemaFieldScope.ts").SensitiveFieldConflict, never>;
6
7
  //# sourceMappingURL=schemaSensitiveKeys.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schemaSensitiveKeys.d.ts","sourceRoot":"","sources":["../src/schemaSensitiveKeys.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAgChD,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,GAAE,SAAS,MAAM,EAAO,UAOxF,MAAM;kBAIf,MAAM,GAAG,SAAS,WAJT,MAAM;uBAKV,MAAM,GAAG,SAAS,UAAU,MAAM,GAAG,KAAK;EAG9D"}
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;AAoBhD,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;gEAG7D,CAAC"}
@@ -1,39 +1,28 @@
1
+ import { Effect } from "effect";
1
2
  import { Rpc } from "effect/rpc";
2
- import { collect, collectEncodedKeys, collectFieldKeys, marked, maskedValue } from "#schemaSensitiveAst.ts";
3
+ import { schemaFieldKeys, validateFieldScope } from "#schemaFieldScope.ts";
4
+ import { maskedValue } from "#schemaSensitiveAst.ts";
3
5
  import { isSensitiveKey } from "#sensitive.ts";
4
- function rpcSensitiveKeys(rpc, extra) {
5
- const keys = new Set(extra);
6
- const nodes = new Set();
6
+ const rpcSensitiveKeys = Effect.fnUntraced(function* (rpc, extra) {
7
7
  const schemas = [
8
- rpc.payloadSchema,
9
- rpc.successSchema,
10
- rpc.errorSchema,
11
- rpc.defectSchema,
12
- ...[...rpc.middlewares].map((m) => m.error),
8
+ { ast: rpc.payloadSchema.ast, name: `${rpc._tag}.payload` },
9
+ { ast: rpc.successSchema.ast, name: `${rpc._tag}.success` },
10
+ { ast: rpc.errorSchema.ast, name: `${rpc._tag}.error` },
11
+ { ast: rpc.defectSchema.ast, name: `${rpc._tag}.defect` },
12
+ ...[...rpc.middlewares].map((middleware, index) => ({ ast: middleware.error.ast, name: `${rpc._tag}.middleware[${index}].error` })),
13
13
  ];
14
- for (const schema of schemas) {
15
- collect(schema.ast, nodes);
16
- }
17
- const properties = [...nodes].flatMap((ast) => (ast._tag === "Objects" ? ast.propertySignatures : []));
18
- collectFieldKeys(properties, keys, marked);
19
- let previousSize;
20
- do {
21
- previousSize = keys.size;
22
- collectFieldKeys(properties, keys, (ast) => maskedValue(ast, keys));
23
- for (const ast of nodes) {
24
- collectEncodedKeys(ast, keys);
25
- }
26
- } while (keys.size !== previousSize);
14
+ yield* validateFieldScope(schemas, extra);
15
+ const keys = new Set(schemas.flatMap(({ ast }) => [...schemaFieldKeys(ast, extra)]));
27
16
  return Object.assign((key) => keys.has(key) || isSensitiveKey(key), {
28
17
  die: maskedValue(rpc.defectSchema.ast, keys),
29
18
  fail: [rpc.errorSchema, ...[...rpc.middlewares].map((m) => m.error)].some((schema) => maskedValue(schema.ast, keys)),
30
19
  });
31
- }
32
- export function schemaSensitiveKeys(group, extra = []) {
20
+ });
21
+ export const schemaSensitiveKeys = Effect.fnUntraced(function* (group, extra = []) {
33
22
  const policies = new Map();
34
23
  for (const rpc of group.requests.values()) {
35
24
  if (Rpc.isRpc(rpc)) {
36
- policies.set(rpc._tag, rpcSensitiveKeys(rpc, extra));
25
+ policies.set(rpc._tag, yield* rpcSensitiveKeys(rpc, extra));
37
26
  }
38
27
  }
39
28
  function sensitive(key) {
@@ -43,5 +32,5 @@ export function schemaSensitiveKeys(group, extra = []) {
43
32
  forRpc: (tag) => (tag === undefined ? sensitive : (policies.get(tag) ?? sensitive)),
44
33
  maskFailure: (tag, reason) => [...policies].some(([method, policy]) => (tag === undefined || tag === method) && (reason === "Fail" ? policy.fail : policy.die)),
45
34
  });
46
- }
35
+ });
47
36
  //# sourceMappingURL=schemaSensitiveKeys.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"schemaSensitiveKeys.js","sourceRoot":"","sources":["../src/schemaSensitiveKeys.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAiB,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC5G,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,SAAS,gBAAgB,CAAC,GAAqB,EAAE,KAAwB;IACxE,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IAC5B,MAAM,KAAK,GAAG,IAAI,GAAG,EAAiB,CAAC;IACvC,MAAM,OAAO,GAAiB;QAC7B,GAAG,CAAC,aAAa;QACjB,GAAG,CAAC,aAAa;QACjB,GAAG,CAAC,WAAW;QACf,GAAG,CAAC,YAAY;QAChB,GAAG,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;KAC3C,CAAC;IACF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC9B,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC;IACD,MAAM,UAAU,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACvG,gBAAgB,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAC3C,IAAI,YAAoB,CAAC;IACzB,GAAG,CAAC;QACH,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC;QACzB,gBAAgB,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;QACpE,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;YACzB,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC/B,CAAC;IACF,CAAC,QAAQ,IAAI,CAAC,IAAI,KAAK,YAAY,EAAE;IACrC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,GAAW,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE;QAC3E,GAAG,EAAE,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC;QAC5C,IAAI,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;KACpH,CAAC,CAAC;AACJ,CAAC;AACD,MAAM,UAAU,mBAAmB,CAAoB,KAA2B,EAAE,KAAK,GAAsB,EAAE;IAChH,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA+C,CAAC;IACxE,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;QAC3C,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACpB,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,gBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QACtD,CAAC;IACF,CAAC;IACD,SAAS,SAAS,CAAC,GAAW;QAC7B,OAAO,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3G,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE;QAC/B,MAAM,EAAE,CAAC,GAAuB,EAAE,EAAE,CAAC,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,CAAC;QACvG,WAAW,EAAE,CAAC,GAAuB,EAAE,MAAsB,EAAE,EAAE,CAChE,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;KAClI,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"schemaSensitiveKeys.js","sourceRoot":"","sources":["../src/schemaSensitiveKeys.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sensitive.d.ts","sourceRoot":"","sources":["../src/sensitive.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,QAAQ,eAAe,CAAC;AAwBrC,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;AAQpD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAOnD;AAyBD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,SAAa,EAAE,GAAG,SAAK,GAAG,MAAM,CAG1G;AACD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,GAAG,MAAM,GAAG,SAAS,CAK1F;AA8BD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,SAAK,GAAG,MAAM,CAkBzD"}
1
+ {"version":3,"file":"sensitive.d.ts","sourceRoot":"","sources":["../src/sensitive.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,QAAQ,eAAe,CAAC;AAwBrC,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;AAQpD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAOnD;AA8BD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,SAAa,EAAE,GAAG,SAAK,GAAG,MAAM,CAG1G;AACD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,GAAG,MAAM,GAAG,SAAS,CAK1F;AA8BD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,SAAK,GAAG,MAAM,CAkBzD"}
package/dist/sensitive.js CHANGED
@@ -61,8 +61,13 @@ function scrub(text, sensitive) {
61
61
  const credentials = text.replaceAll(PRIVATE_KEY, REDACTED).replaceAll(AUTH_SCHEME, `$<scheme> ${REDACTED}`).replaceAll(JWT, REDACTED);
62
62
  return redactAssignments(credentials, sensitive);
63
63
  }
64
+ function redactSchemaValues(text) {
65
+ return text
66
+ .replaceAll(/(?<expected>\bExpected[^\r\n]*?, (?:got|actual)[ \t]+)(?:"(?:\\[\s\S]|[^"\\])*"|[^\r\n]*)/gu, `$<expected>${REDACTED}`)
67
+ .replaceAll(/\bgot[ \t]+"(?:\\[\s\S]|[^"\\])*"/gu, `got ${REDACTED}`);
68
+ }
64
69
  export function redactText(text, sensitive, maxLength = MAX_STRING, key = "") {
65
- const scrubbed = scrub(redactUrl(text, key), sensitive);
70
+ const scrubbed = scrub(redactUrl(redactSchemaValues(text), key), sensitive);
66
71
  return scrubbed.length > maxLength ? `${scrubbed.slice(0, maxLength)}…<${scrubbed.length - maxLength} more chars>` : scrubbed;
67
72
  }
68
73
  export function redactErrorStack(error, sensitive) {
@@ -1 +1 @@
1
- {"version":3,"file":"sensitive.js","sourceRoot":"","sources":["../src/sensitive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAExC,MAAM,CAAC,MAAM,QAAQ,GAAG,YAAY,CAAC;AACrC,MAAM,UAAU,GAAG,IAAI,CAAC;AACxB,MAAM,eAAe,GAAG;IACvB,UAAU;IACV,YAAY;IACZ,QAAQ;IACR,OAAO;IACP,eAAe;IACf,QAAQ;IACR,QAAQ;IACR,WAAW;IACX,YAAY;IACZ,YAAY;IACZ,KAAK;IACL,QAAQ;IACR,WAAW;IACX,WAAW;IACX,YAAY;IACZ,eAAe;IACf,MAAM;IACN,MAAM;CACN,CAAC;AACF,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;AACpE,MAAM,eAAe,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,qBAAqB,CAAC,CAAC;AAEpG,SAAS,OAAO,CAAC,GAAW;IAC3B,OAAO,GAAG;SACR,UAAU,CAAC,qCAAqC,EAAE,mBAAmB,CAAC;SACtE,UAAU,CAAC,wCAAwC,EAAE,oBAAoB,CAAC;SAC1E,WAAW,EAAE;SACb,KAAK,CAAC,UAAU,CAAC,CAAC;AACrB,CAAC;AACD,MAAM,UAAU,cAAc,CAAC,GAAW;IACzC,MAAM,UAAU,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC9D,OAAO,CACN,eAAe,CAAC,QAAQ,CAAC,UAAU,CAAC;WACjC,eAAe,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;WACzD,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAC9D,CAAC;AACH,CAAC;AACD,MAAM,WAAW,GAAG,sDAAsD,CAAC;AAC3E,MAAM,GAAG,GAAG,uDAAuD,CAAC;AACpE,MAAM,WAAW,GAAG,qFAAqF,CAAC;AAC1G,SAAS,iBAAiB,CAAC,IAAY,EAAE,SAAuB;IAC/D,MAAM,OAAO,GAAG,kFAAkF,CAAC;IACnG,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,IAAI,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,KAAK,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACjF,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACjC,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;YACpB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,SAAS,GAAG,QAAQ,EAAE,CAAC;YAC5E,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;QAC5B,CAAC;aAAM,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACpC,6FAA6F;YAC7F,OAAO,CAAC,SAAS,GAAG,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;QACjE,CAAC;IACF,CAAC;IACD,OAAO,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AACpC,CAAC;AACD,SAAS,KAAK,CAAC,IAAY,EAAE,SAAuB;IACnD,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,UAAU,CAAC,WAAW,EAAE,aAAa,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACtI,OAAO,iBAAiB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;AAClD,CAAC;AACD,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,SAAuB,EAAE,SAAS,GAAG,UAAU,EAAE,GAAG,GAAG,EAAE;IACjG,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC;IACxD,OAAO,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,KAAK,QAAQ,CAAC,MAAM,GAAG,SAAS,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC/H,CAAC;AACD,MAAM,UAAU,gBAAgB,CAAC,KAAY,EAAE,SAAuB;IACrE,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;AACnH,CAAC;AAED,SAAS,KAAK,CAAC,KAAa;IAC3B,OAAO,KAAK;SACV,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAC;SAC5E,IAAI,CAAC,GAAG,CAAC,CAAC;AACb,CAAC;AAED,SAAS,GAAG,CAAC,KAAa;IACzB,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAClE,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACtC,OAAO,CACN,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,UAAU,CAChH,wDAAwD,EACxD,eAAe,QAAQ,GAAG,CAC1B,GAAG,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC,CAC3C,CAAC;AACH,CAAC;AAED,MAAM,aAAa,GAAG,MAAM,CAAC,mBAAmB,CAC/C,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO,EAAE;IACrC,OAAO,EAAE,CAAC,GAAW,EAAE,IAAa,EAAE,EAAE,CAAC,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;CACjG,CAAC,CACF,CAAC;AACF,SAAS,UAAU,CAAC,KAAa;IAChC,OAAO,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpG,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAa,EAAE,GAAG,GAAG,EAAE;IAChD,IAAI,uDAAuD,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACvE,OAAO,QAAQ,CAAC;IACjB,CAAC;IACD,IAAI,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACrC,OAAO,GAAG,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC;IACD,IAAI,4CAA4C,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,oDAAoD,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9H,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC;IACD,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,QAAQ,CAAC;QACjB,CAAC;IACF,CAAC;IACD,iGAAiG;IACjG,OAAO,KAAK,CAAC,UAAU,CAAC,wCAAwC,EAAE,GAAG,CAAC,CAAC;AACxE,CAAC"}
1
+ {"version":3,"file":"sensitive.js","sourceRoot":"","sources":["../src/sensitive.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.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "Typed expected failures and secret-safe failure reporting for Effect applications",
5
5
  "keywords": [
6
6
  "effect"
@@ -45,8 +45,9 @@
45
45
  "README.md"
46
46
  ],
47
47
  "devDependencies": {
48
- "@shivaedev/quality": "0.50.0",
48
+ "@shivaedev/quality": "0.53.1",
49
49
  "@shivaedev/test": "0.12.0",
50
+ "@shivaedev/test-story": "0.31.4",
50
51
  "@types/node": "24.19.2",
51
52
  "effect": "4.0.6",
52
53
  "typescript": "7.0.2",
package/src/redact.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Predicate, Redacted } from "effect";
1
+ import { Predicate, Redacted, SchemaIssue } from "effect";
2
2
  import { isSensitiveKey, REDACTED, redactErrorStack, redactText, type SensitiveKey } from "#sensitive.ts";
3
3
 
4
4
  const MAX_DEPTH = 8;
@@ -33,7 +33,8 @@ function collection(value: object, sensitive: SensitiveKey, depth: number, bound
33
33
  const entries = entriesOf(value, sensitive, bounded);
34
34
  const kept = entries.slice(0, bounded ? MAX_ENTRIES : entries.length).map(([key, nested]): [string, unknown] => {
35
35
  const stackHeader = key === "stack" && typeof nested === "string" && (sensitive("name") || sensitive("message"));
36
- return [key, sensitive(key) || stackHeader ? REDACTED : walk(nested, sensitive, depth + 1, bounded, key)];
36
+ const schemaInput = key === "input" && SchemaIssue.isIssue(value);
37
+ return [key, sensitive(key) || stackHeader || schemaInput ? REDACTED : walk(nested, sensitive, depth + 1, bounded, key)];
37
38
  });
38
39
  return Object.fromEntries(bounded && entries.length > MAX_ENTRIES ? [...kept, ["<truncated>", `${entries.length - MAX_ENTRIES} more keys`]] : kept);
39
40
  }
@@ -0,0 +1,104 @@
1
+ import { Effect, Schema, type SchemaAST } from "effect";
2
+ import { children, collect, collectEncodedKeys, collectFieldKeys, marked, maskedValue } from "#schemaSensitiveAst.ts";
3
+ import { isSensitiveKey } from "#sensitive.ts";
4
+
5
+ export function schemaFieldKeys(ast: SchemaAST.AST, extra: readonly string[]) {
6
+ const keys = new Set(extra);
7
+ const nodes = new Set<SchemaAST.AST>();
8
+ collect(ast, nodes);
9
+ const properties = [...nodes].flatMap((node) => (node._tag === "Objects" ? node.propertySignatures : []));
10
+ collectFieldKeys(properties, keys, marked);
11
+ let previousSize: number;
12
+ do {
13
+ previousSize = keys.size;
14
+ collectFieldKeys(properties, keys, (node) => maskedValue(node, keys));
15
+ for (const node of nodes) {
16
+ collectEncodedKeys(node, keys);
17
+ }
18
+ } while (keys.size !== previousSize);
19
+ return keys;
20
+ }
21
+
22
+ interface Field {
23
+ readonly key: string;
24
+ readonly path: string;
25
+ readonly sensitive: boolean;
26
+ }
27
+
28
+ function fieldsOf(ast: SchemaAST.AST, schema: string, extra: readonly string[], candidates: ReadonlySet<string>): Field[] {
29
+ const fields: Field[] = [];
30
+ function visitIndex(index: SchemaAST.IndexSignature, path: string, hidden: boolean, seen: ReadonlySet<SchemaAST.AST>) {
31
+ const accepts = Schema.is(Schema.make(index.parameter));
32
+ for (const key of candidates) {
33
+ if (accepts(key)) {
34
+ fields.push({ key, path: `${path}[${key}]`, sensitive: hidden || extra.includes(key) || isSensitiveKey(key) });
35
+ }
36
+ }
37
+ visit(index.type, `${path}[value]`, hidden, seen);
38
+ }
39
+ function visitObject(node: SchemaAST.Objects, path: string, hidden: boolean, seen: ReadonlySet<SchemaAST.AST>) {
40
+ for (const property of node.propertySignatures) {
41
+ if (typeof property.name !== "string") {
42
+ continue;
43
+ }
44
+ const sensitive =
45
+ hidden || extra.includes(property.name) || isSensitiveKey(property.name) || maskedValue(property.type, schemaFieldKeys(property.type, []));
46
+ const fieldPath = `${path}.${property.name}`;
47
+ fields.push({ key: property.name, path: fieldPath, sensitive });
48
+ visit(property.type, fieldPath, sensitive, seen);
49
+ }
50
+ for (const index of node.indexSignatures) {
51
+ visitIndex(index, path, hidden, seen);
52
+ }
53
+ }
54
+ function visit(node: SchemaAST.AST, path: string, hidden: boolean, ancestors: ReadonlySet<SchemaAST.AST>) {
55
+ if (ancestors.has(node)) {
56
+ return;
57
+ }
58
+ const seen = new Set(ancestors).add(node);
59
+ const masked = hidden || marked(node);
60
+ if (node._tag === "Objects") {
61
+ visitObject(node, path, masked, seen);
62
+ return;
63
+ }
64
+ for (const [index, child] of children(node).entries()) {
65
+ visit(child, `${path}[${index}]`, masked, seen);
66
+ }
67
+ }
68
+ visit(ast, schema, false, new Set());
69
+ for (const key of schemaFieldKeys(ast, [])) {
70
+ if (!fields.some((field) => field.key === key && field.sensitive)) {
71
+ fields.push({ key, path: `${schema}.encoded.${key}`, sensitive: true });
72
+ }
73
+ }
74
+ return fields;
75
+ }
76
+
77
+ export class SensitiveFieldConflict extends Schema.TaggedError<SensitiveFieldConflict>()("SensitiveFieldConflict", {
78
+ field: Schema.String,
79
+ message: Schema.String,
80
+ publicSchema: Schema.String,
81
+ sensitiveSchema: Schema.String,
82
+ }) {}
83
+
84
+ export const validateFieldScope = Effect.fn("Errors.validateFieldScope")(function* (
85
+ schemas: readonly { readonly ast: SchemaAST.AST; readonly name: string }[],
86
+ extra: readonly string[],
87
+ ) {
88
+ const candidates = new Set(schemas.flatMap(({ ast }) => [...schemaFieldKeys(ast, [])]));
89
+ const fields = schemas.flatMap(({ ast, name }) => fieldsOf(ast, name, extra, candidates));
90
+ // A masked container protects its children without making each child name sensitive.
91
+ for (const hidden of fields.filter(
92
+ (field) => candidates.has(field.key) && field.sensitive && !extra.includes(field.key) && !isSensitiveKey(field.key),
93
+ )) {
94
+ const publicField = fields.find((field) => field.key === hidden.key && !field.sensitive);
95
+ if (publicField !== undefined) {
96
+ return yield* new SensitiveFieldConflict({
97
+ field: hidden.key,
98
+ 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.`,
99
+ publicSchema: publicField.path,
100
+ sensitiveSchema: hidden.path,
101
+ });
102
+ }
103
+ }
104
+ });
@@ -1,7 +1,7 @@
1
1
  import { Predicate, type SchemaAST } from "effect";
2
2
  import { isSensitiveKey } from "#sensitive.ts";
3
3
 
4
- function children(ast: SchemaAST.AST): readonly SchemaAST.AST[] {
4
+ export function children(ast: SchemaAST.AST): readonly SchemaAST.AST[] {
5
5
  switch (ast._tag) {
6
6
  case "Objects":
7
7
  return [...ast.propertySignatures.map((property) => property.type), ...ast.indexSignatures.flatMap((index) => [index.parameter, index.type])];
@@ -42,10 +42,23 @@ function containsSensitive(ast: SchemaAST.AST, keys: ReadonlySet<string>): boole
42
42
  || propertiesOf(ast).some((property) => typeof property.name === "string" && (keys.has(property.name) || isSensitiveKey(property.name)))
43
43
  );
44
44
  }
45
+ function preservesFields(source: SchemaAST.AST, target: SchemaAST.AST): boolean {
46
+ return (
47
+ source._tag === "Declaration"
48
+ && Predicate.hasProperty(source.annotations?.representation, "id")
49
+ && source.annotations.representation.id === "effect/schema/Option"
50
+ && target._tag === "Union"
51
+ && target.types.some((type) => type._tag === "Null")
52
+ );
53
+ }
45
54
  export function collectEncodedKeys(ast: SchemaAST.AST, keys: Set<string>) {
46
55
  let source = ast;
47
56
  let sensitive = false;
48
57
  for (const link of ast.encoding ?? []) {
58
+ if (preservesFields(source, link.to)) {
59
+ source = link.to;
60
+ continue;
61
+ }
49
62
  sensitive ||= containsSensitive(source, keys);
50
63
  if (sensitive) {
51
64
  for (const property of propertiesOf(link.to)) {
@@ -74,6 +87,10 @@ export function maskedValue(ast: SchemaAST.AST, keys: ReadonlySet<string>, seen
74
87
  let source = ast;
75
88
  let sensitive = false;
76
89
  for (const link of ast.encoding ?? []) {
90
+ if (preservesFields(source, link.to)) {
91
+ source = link.to;
92
+ continue;
93
+ }
77
94
  sensitive ||= containsSensitive(source, keys);
78
95
  if (sensitive && !fixedOutput(link.to)) {
79
96
  return true;
@@ -1,41 +1,29 @@
1
- import type { Schema, SchemaAST } from "effect";
1
+ import { Effect } from "effect";
2
2
  import { Rpc, type RpcGroup } from "effect/rpc";
3
- import { collect, collectEncodedKeys, collectFieldKeys, marked, maskedValue } from "#schemaSensitiveAst.ts";
3
+ import { schemaFieldKeys, validateFieldScope } from "#schemaFieldScope.ts";
4
+ import { maskedValue } from "#schemaSensitiveAst.ts";
4
5
  import { isSensitiveKey } from "#sensitive.ts";
5
6
 
6
- function rpcSensitiveKeys(rpc: Rpc.AnyWithProps, extra: readonly string[]) {
7
- const keys = new Set(extra);
8
- const nodes = new Set<SchemaAST.AST>();
9
- const schemas: Schema.Top[] = [
10
- rpc.payloadSchema,
11
- rpc.successSchema,
12
- rpc.errorSchema,
13
- rpc.defectSchema,
14
- ...[...rpc.middlewares].map((m) => m.error),
7
+ const rpcSensitiveKeys = Effect.fnUntraced(function* (rpc: Rpc.AnyWithProps, extra: readonly string[]) {
8
+ const schemas = [
9
+ { ast: rpc.payloadSchema.ast, name: `${rpc._tag}.payload` },
10
+ { ast: rpc.successSchema.ast, name: `${rpc._tag}.success` },
11
+ { ast: rpc.errorSchema.ast, name: `${rpc._tag}.error` },
12
+ { ast: rpc.defectSchema.ast, name: `${rpc._tag}.defect` },
13
+ ...[...rpc.middlewares].map((middleware, index) => ({ ast: middleware.error.ast, name: `${rpc._tag}.middleware[${index}].error` })),
15
14
  ];
16
- for (const schema of schemas) {
17
- collect(schema.ast, nodes);
18
- }
19
- const properties = [...nodes].flatMap((ast) => (ast._tag === "Objects" ? ast.propertySignatures : []));
20
- collectFieldKeys(properties, keys, marked);
21
- let previousSize: number;
22
- do {
23
- previousSize = keys.size;
24
- collectFieldKeys(properties, keys, (ast) => maskedValue(ast, keys));
25
- for (const ast of nodes) {
26
- collectEncodedKeys(ast, keys);
27
- }
28
- } while (keys.size !== previousSize);
15
+ yield* validateFieldScope(schemas, extra);
16
+ const keys = new Set(schemas.flatMap(({ ast }) => [...schemaFieldKeys(ast, extra)]));
29
17
  return Object.assign((key: string) => keys.has(key) || isSensitiveKey(key), {
30
18
  die: maskedValue(rpc.defectSchema.ast, keys),
31
19
  fail: [rpc.errorSchema, ...[...rpc.middlewares].map((m) => m.error)].some((schema) => maskedValue(schema.ast, keys)),
32
20
  });
33
- }
34
- export function schemaSensitiveKeys<R extends Rpc.Any>(group: RpcGroup.RpcGroup<R>, extra: readonly string[] = []) {
35
- const policies = new Map<string, ReturnType<typeof rpcSensitiveKeys>>();
21
+ });
22
+ export const schemaSensitiveKeys = Effect.fnUntraced(function* <R extends Rpc.Any>(group: RpcGroup.RpcGroup<R>, extra: readonly string[] = []) {
23
+ const policies = new Map<string, Effect.Success<ReturnType<typeof rpcSensitiveKeys>>>();
36
24
  for (const rpc of group.requests.values()) {
37
25
  if (Rpc.isRpc(rpc)) {
38
- policies.set(rpc._tag, rpcSensitiveKeys(rpc, extra));
26
+ policies.set(rpc._tag, yield* rpcSensitiveKeys(rpc, extra));
39
27
  }
40
28
  }
41
29
  function sensitive(key: string) {
@@ -46,4 +34,4 @@ export function schemaSensitiveKeys<R extends Rpc.Any>(group: RpcGroup.RpcGroup<
46
34
  maskFailure: (tag: string | undefined, reason: "Fail" | "Die") =>
47
35
  [...policies].some(([method, policy]) => (tag === undefined || tag === method) && (reason === "Fail" ? policy.fail : policy.die)),
48
36
  });
49
- }
37
+ });
package/src/sensitive.ts CHANGED
@@ -64,8 +64,13 @@ function scrub(text: string, sensitive: SensitiveKey): string {
64
64
  const credentials = text.replaceAll(PRIVATE_KEY, REDACTED).replaceAll(AUTH_SCHEME, `$<scheme> ${REDACTED}`).replaceAll(JWT, REDACTED);
65
65
  return redactAssignments(credentials, sensitive);
66
66
  }
67
+ function redactSchemaValues(text: string): string {
68
+ return text
69
+ .replaceAll(/(?<expected>\bExpected[^\r\n]*?, (?:got|actual)[ \t]+)(?:"(?:\\[\s\S]|[^"\\])*"|[^\r\n]*)/gu, `$<expected>${REDACTED}`)
70
+ .replaceAll(/\bgot[ \t]+"(?:\\[\s\S]|[^"\\])*"/gu, `got ${REDACTED}`);
71
+ }
67
72
  export function redactText(text: string, sensitive: SensitiveKey, maxLength = MAX_STRING, key = ""): string {
68
- const scrubbed = scrub(redactUrl(text, key), sensitive);
73
+ const scrubbed = scrub(redactUrl(redactSchemaValues(text), key), sensitive);
69
74
  return scrubbed.length > maxLength ? `${scrubbed.slice(0, maxLength)}…<${scrubbed.length - maxLength} more chars>` : scrubbed;
70
75
  }
71
76
  export function redactErrorStack(error: Error, sensitive: SensitiveKey): string | undefined {