API reference › @evolu/common › Type › redacted
function redacted<Inner extends AnyType>(
inner: ValidateRedactedInner<Inner>,
): RedactedType<Inner>;
Defined in: packages/common/src/Type.ts:10084
Validates a secret string with an inner Type and wraps the inner Output in Redacted.
Use it where an app receives a secret it holds, such as a form field or environment configuration, so the decoded value does not leak through logging or serialization.
The inner Type's errors are returned unchanged, so it must refine
String, and its errors must not contain the value, as with
SimplePassword, Mnemonic, and brands over them. The compiler
rejects an inner Type that does not refine String or whose errors have a
value property, such as minLength or regex, so a custom inner
error must not keep the input under another name. A non-string fails with a
value-free RedactedError instead of the String error, which keeps the
input.
Encoding reveals the secret: to and json encode the revealed value
with the inner Type. A json parse error keeps the whole malformed
text, which can contain the secret. Each decode creates a new wrapper, so
compare round trips by their revealed values.
The Output is not Data, so it cannot be an Evolu column or an item of unique.
A union lets its other members see the raw input, and their errors
keep it. By default, a union reports the error of its first member, so a
member listed before the redacted Type leaks the secret. When all errors are
collected, as with { errors: "all" } and always with Standard Schema
validation, every member does, including the Null or Undefined member of
nullOr or undefinedOr, which list the redacted Type first.
Prefer optional for an absent secret, or list the redacted Type
first.
Example
import {
assertEqual,
assertErr,
assertOk,
object,
redacted,
revealRedacted,
SimplePassword,
String,
} from "@evolu/common";
const SignIn = object({
email: String,
password: redacted(SimplePassword),
});
const signIn = SignIn.fromUnknown({
email: "ada@example.com",
password: "correct horse",
});
assertOk(signIn);
assertEqual(revealRedacted(signIn.value.password), "correct horse");
assertEqual(
JSON.stringify(signIn.value),
'{"email":"ada@example.com","password":"<redacted>"}',
);
// Encoding reveals the secret.
assertEqual(SignIn.to(signIn.value).password, "correct horse");
assertErr(SignIn.fromUnknown({ email: "ada@example.com", password: "short" }), {
type: "Object",
reason: {
kind: "Properties",
errors: {
password: { type: "SimplePassword", reason: "TooShort" },
},
},
});
assertErr(SignIn.fromUnknown({ email: "ada@example.com", password: 42 }), {
type: "Object",
reason: {
kind: "Properties",
errors: { password: { type: "Redacted" } },
},
});