{"version":3,"file":"schema-like.cjs","names":[],"sources":["../../src/utils/schema-like.ts"],"sourcesContent":["/**\n * The SDK's answer to \"the caller handed me a schema\" — one normalizer behind\n * every option that takes one.\n *\n * Internal, and imported by path rather than through the `utils` barrel: the\n * function exists so `decodeFrame` and anything else that validates a payload\n * share one reading of the two shapes below, not so consumers can call it. The\n * types are public, because an option typed `SchemaLike<T>` is a name the\n * consumer has to be able to write down.\n *\n * Two shapes are accepted on purpose:\n *\n * - [Standard Schema](https://standardschema.dev) (`~standard`), which zod\n *   (>=3.24), valibot and arktype all implement, so the SDK validates against\n *   any of them without depending on one;\n * - `.safeParse`, because the SDK's own zod range starts at `^3.23.0`, which\n *   predates `~standard`, and because it is the method every zod user already\n *   knows.\n */\n\n/** One field-level complaint from a schema validation. */\nexport interface SchemaIssue {\n    /** Dotted path to the offending field, or `\"<root>\"` for the value itself. */\n    path: string;\n    /** What the validator said was wrong. */\n    message: string;\n}\n\n/** A path segment as Standard Schema reports it: a key, or an object holding one. */\ntype IssuePathSegment = PropertyKey | { readonly key: PropertyKey };\n\n/** One issue as either supported shape reports it. */\ninterface RawIssue {\n    readonly message: string;\n    readonly path?: readonly IssuePathSegment[] | undefined;\n}\n\n/** A schema exposing the [Standard Schema](https://standardschema.dev) interface. */\nexport interface StandardSchemaLike<T> {\n    readonly \"~standard\": {\n        readonly validate: (\n            value: unknown,\n        ) =>\n            | { readonly value: T; readonly issues?: undefined }\n            | { readonly issues: readonly RawIssue[] }\n            | Promise<\n                  | { readonly value: T; readonly issues?: undefined }\n                  | { readonly issues: readonly RawIssue[] }\n              >;\n    };\n}\n\n/** A schema exposing zod's `.safeParse`, including versions older than `~standard`. */\nexport interface SafeParseSchemaLike<T> {\n    readonly safeParse: (\n        value: unknown,\n    ) =>\n        | { readonly success: true; readonly data: T }\n        | { readonly success: false; readonly error: { readonly issues: readonly RawIssue[] } };\n}\n\n/** Anything the SDK can validate a payload against. */\nexport type SchemaLike<T> = StandardSchemaLike<T> | SafeParseSchemaLike<T>;\n\n/** Outcome of validating one value against a {@link SchemaLike}. */\nexport type SchemaValidation<T> = { ok: true; data: T } | { ok: false; issues: SchemaIssue[] };\n\n/**\n * The issue reported when a schema answers asynchronously.\n *\n * A frame is decoded inside the transport's `message` handler and delivered from\n * it, so there is nowhere to await: awaiting would deliver frames in whatever\n * order their validations settled, which is worse than refusing. Reported as a\n * validation failure rather than thrown, so it arrives through the same\n * `onValidationError` the caller already registered.\n */\nconst ASYNC_ISSUE: SchemaIssue = {\n    path: \"<root>\",\n    message:\n        \"the schema validated asynchronously, and a frame is decoded synchronously — \" +\n        \"there is nowhere to await it. Use a synchronous schema, or validate inside your \" +\n        \"own handler.\",\n};\n\n/**\n * Format a Standard Schema issue path as a dotted string.\n *\n * @param path - The reported path, if any.\n * @returns The dotted path, or `\"<root>\"` when the value itself is at fault.\n */\nfunction formatPath(path: readonly IssuePathSegment[] | undefined): string {\n    if (!path || path.length === 0) return \"<root>\";\n    return path\n        .map((segment) =>\n            typeof segment === \"object\" && segment !== null ? String(segment.key) : String(segment),\n        )\n        .join(\".\");\n}\n\n/**\n * Normalize one issue from either supported shape.\n *\n * @param issue - The issue as the validator reported it.\n * @returns The issue with a dotted path.\n */\nfunction toIssue(issue: RawIssue): SchemaIssue {\n    return { path: formatPath(issue.path), message: issue.message };\n}\n\n/**\n * Validate a value against a schema, whichever of the two shapes it has.\n *\n * @param schema - A Standard Schema or a `.safeParse` schema.\n * @param value - The value to validate.\n * @returns The validated output, or the issues explaining why it was refused.\n */\nexport function validateWithSchema<T>(schema: SchemaLike<T>, value: unknown): SchemaValidation<T> {\n    if (\"~standard\" in schema) {\n        const result = schema[\"~standard\"].validate(value);\n        if (typeof (result as { then?: unknown }).then === \"function\") {\n            return { ok: false, issues: [ASYNC_ISSUE] };\n        }\n        const settled = result as\n            | { readonly value: T; readonly issues?: undefined }\n            | { readonly issues: readonly RawIssue[] };\n        if (settled.issues) return { ok: false, issues: settled.issues.map(toIssue) };\n        return { ok: true, data: settled.value };\n    }\n    const result = schema.safeParse(value);\n    if (result.success) return { ok: true, data: result.data };\n    return { ok: false, issues: result.error.issues.map(toIssue) };\n}\n"],"mappings":"AA4EA,IAAM,EAA2B,CAC7B,KAAM,SACN,QACI,0KAGR,EAQA,SAAS,EAAW,EAAuD,CAEvE,MADI,CAAC,GAAQ,EAAK,SAAW,EAAU,SAChC,EACF,IAAK,GACgD,OAAlD,OAAO,GAAY,UAAY,EAA0B,EAAQ,IAAc,CAAO,CAC1F,CAAC,CACA,KAAK,GAAG,CACjB,CAQA,SAAS,EAAQ,EAA8B,CAC3C,MAAO,CAAE,KAAM,EAAW,EAAM,IAAI,EAAG,QAAS,EAAM,OAAQ,CAClE,CASA,SAAgB,EAAsB,EAAuB,EAAqC,CAC9F,GAAI,cAAe,EAAQ,CACvB,IAAM,EAAS,EAAO,YAAY,CAAC,SAAS,CAAK,EACjD,GAAI,OAAQ,EAA8B,MAAS,WAC/C,MAAO,CAAE,GAAI,GAAO,OAAQ,CAAC,CAAW,CAAE,EAE9C,IAAM,EAAU,EAIhB,OADI,EAAQ,OAAe,CAAE,GAAI,GAAO,OAAQ,EAAQ,OAAO,IAAI,CAAO,CAAE,EACrE,CAAE,GAAI,GAAM,KAAM,EAAQ,KAAM,CAC3C,CACA,IAAM,EAAS,EAAO,UAAU,CAAK,EAErC,OADI,EAAO,QAAgB,CAAE,GAAI,GAAM,KAAM,EAAO,IAAK,EAClD,CAAE,GAAI,GAAO,OAAQ,EAAO,MAAM,OAAO,IAAI,CAAO,CAAE,CACjE"}