diff --git a/.changeset/cute-games-shop.md b/.changeset/cute-games-shop.md new file mode 100644 index 0000000..35d090b --- /dev/null +++ b/.changeset/cute-games-shop.md @@ -0,0 +1,5 @@ +--- +'typestone': minor +--- + +Changes the default parsing behavior to strip input values from issues, which can be overridden by setting the `exposeInput` flag diff --git a/packages/typestone/src/error/issues.ts b/packages/typestone/src/error/issues.ts index c5fb265..71ab32f 100644 --- a/packages/typestone/src/error/issues.ts +++ b/packages/typestone/src/error/issues.ts @@ -3,7 +3,7 @@ import { type Path } from '../internal/process/types.ts'; export interface BaseIssue { readonly code: TCode; readonly message: string; - readonly input: unknown; + readonly input?: unknown; readonly path: Path; readonly abort?: boolean; diff --git a/packages/typestone/src/internal/process/process-schema.ts b/packages/typestone/src/internal/process/process-schema.ts index 7ed674e..06dc0ba 100644 --- a/packages/typestone/src/internal/process/process-schema.ts +++ b/packages/typestone/src/internal/process/process-schema.ts @@ -21,7 +21,14 @@ export function processSchema< let iteration = iterator.next(); while (!iteration.done) { - const issue = iteration.value; + let issue: Issue; + if (context.exposeInput) { + const { input, ...newIssue } = iteration.value; + issue = newIssue; + } else { + issue = iteration.value; + } + issues.push(issue); if (issue.abort) break; iteration = iterator.next(); diff --git a/packages/typestone/src/internal/process/types.ts b/packages/typestone/src/internal/process/types.ts index 7830293..70bd8e3 100644 --- a/packages/typestone/src/internal/process/types.ts +++ b/packages/typestone/src/internal/process/types.ts @@ -4,7 +4,20 @@ export type Path = PropertyKey[]; export type ProcessMode = 'encode' | 'decode'; -export interface ProcessContext { +export interface ProcessOptions { + /** + * When `true`, this will expose the `input` value for all issues. + * + * This should be used with caution as exposing the input value can cause + * sensitive information to be leaked. + */ + readonly exposeInput?: boolean; +} + +export interface ProcessContext< + TValue, + TMode extends ProcessMode, +> extends ProcessOptions { readonly value: TValue; readonly path: Path; readonly mode: TMode; diff --git a/packages/typestone/src/methods/decode/decode.ts b/packages/typestone/src/methods/decode/decode.ts index e26bbe1..b256886 100644 --- a/packages/typestone/src/methods/decode/decode.ts +++ b/packages/typestone/src/methods/decode/decode.ts @@ -1,14 +1,16 @@ import { type RawInput, type RawOutput } from '../../def/def.ts'; +import { type ProcessOptions } from '../../internal/process/types.ts'; import { type Schema } from '../../schemas/schema/schema.ts'; import { safeDecode } from '../safe-decode/safe-decode.ts'; export type DecodeMethod = ( this: TSchema, input: RawInput, + options?: ProcessOptions, ) => RawOutput; -export const decode: DecodeMethod = function (input) { - const result = safeDecode.call(this, input); +export const decode: DecodeMethod = function (input, options) { + const result = safeDecode.call(this, input, options); if (!result.success) throw new Error('Decoding failed.'); return result.data; }; diff --git a/packages/typestone/src/methods/encode/encode.ts b/packages/typestone/src/methods/encode/encode.ts index c10ada0..371dc8f 100644 --- a/packages/typestone/src/methods/encode/encode.ts +++ b/packages/typestone/src/methods/encode/encode.ts @@ -1,14 +1,16 @@ import { type RawInput, type RawOutput } from '../../def/def.ts'; +import { type ProcessOptions } from '../../internal/process/types.ts'; import { type Schema } from '../../schemas/schema/schema.ts'; import { safeEncode } from '../safe-encode/safe-encode.ts'; export type EncodeMethod = ( this: TSchema, output: RawOutput, + options?: ProcessOptions, ) => RawInput; -export const encode: EncodeMethod = function (output) { - const result = safeEncode.call(this, output); +export const encode: EncodeMethod = function (output, options) { + const result = safeEncode.call(this, output, options); if (!result.success) throw new Error('Encoding failed.'); return result.data; }; diff --git a/packages/typestone/src/methods/parse/parse.ts b/packages/typestone/src/methods/parse/parse.ts index 2eb9474..94b4898 100644 --- a/packages/typestone/src/methods/parse/parse.ts +++ b/packages/typestone/src/methods/parse/parse.ts @@ -1,14 +1,16 @@ import { type RawOutput } from '../../def/def.ts'; +import { type ProcessOptions } from '../../internal/process/types.ts'; import { type Schema } from '../../schemas/schema/schema.ts'; import { safeDecode } from '../safe-decode/safe-decode.ts'; export type ParseMethod = ( this: TSchema, value: unknown, + options?: ProcessOptions, ) => RawOutput; -export const parse: ParseMethod = function (value) { - const result = safeDecode.call(this, value); +export const parse: ParseMethod = function (value, options) { + const result = safeDecode.call(this, value, options); if (!result.success) throw new Error('Parsing failed.'); return result.data; }; diff --git a/packages/typestone/src/methods/safe-decode/safe-decode.ts b/packages/typestone/src/methods/safe-decode/safe-decode.ts index 856dae8..9750a67 100644 --- a/packages/typestone/src/methods/safe-decode/safe-decode.ts +++ b/packages/typestone/src/methods/safe-decode/safe-decode.ts @@ -1,15 +1,20 @@ import { type RawInput, type RawOutput } from '../../def/def.ts'; import { processSchema } from '../../internal/process/process-schema.ts'; -import { type ParseResult } from '../../internal/process/types.ts'; +import { + type ParseResult, + type ProcessOptions, +} from '../../internal/process/types.ts'; import { type Schema } from '../../schemas/schema/schema.ts'; export type SafeDecodeMethod = ( this: TSchema, input: RawInput, + options?: ProcessOptions, ) => ParseResult>; -export const safeDecode: SafeDecodeMethod = function (input) { +export const safeDecode: SafeDecodeMethod = function (input, options) { return processSchema(this, { + ...options, mode: 'decode', value: input, path: [], diff --git a/packages/typestone/src/methods/safe-encode/safe-encode.ts b/packages/typestone/src/methods/safe-encode/safe-encode.ts index 4511e78..9ef125f 100644 --- a/packages/typestone/src/methods/safe-encode/safe-encode.ts +++ b/packages/typestone/src/methods/safe-encode/safe-encode.ts @@ -1,15 +1,20 @@ import { type RawInput, type RawOutput } from '../../def/def.ts'; import { processSchema } from '../../internal/process/process-schema.ts'; -import { type ParseResult } from '../../internal/process/types.ts'; +import { + type ParseResult, + type ProcessOptions, +} from '../../internal/process/types.ts'; import { type Schema } from '../../schemas/schema/schema.ts'; export type SafeEncodeMethod = ( this: TSchema, output: RawOutput, + options?: ProcessOptions, ) => ParseResult>; -export const safeEncode: SafeEncodeMethod = function (output) { +export const safeEncode: SafeEncodeMethod = function (output, options) { return processSchema(this, { + ...options, mode: 'encode', value: output, path: [],