Leon4gr45's picture
Upload folder using huggingface_hub (part 2)
1477a90 verified
Raw
History Blame Contribute Delete
22.1 kB
// Code generated by @openmeter/typespec-typescript. DO NOT EDIT.
import type { output, ZodType } from 'zod'
export function toCamelCase(name: string): string {
return name.replace(/_([a-z0-9])/g, (_m, c: string) => c.toUpperCase())
}
export function toSnakeCase(name: string): string {
return name.replace(/([A-Z])/g, (_m, c: string) => `_${c.toLowerCase()}`)
}
type ZodDef = {
type: string
innerType?: ZodType
valueType?: ZodType
element?: ZodType
discriminator?: string
options?: ZodType[]
entries?: Record<string, string>
defaultValue?: unknown
}
function def(schema: ZodType | undefined): ZodDef | undefined {
return (schema as { def?: ZodDef } | undefined)?.def
}
// Unwrap optional/nullable/default to the schema that describes the value's
// shape. These wrappers never change keys, so the walker looks through them
// before classifying a node.
function unwrap(schema: ZodType | undefined): ZodType | undefined {
let current = schema
for (let i = 0; i < 100 && current; i++) {
const d = def(current)
if (
d &&
(d.type === 'optional' ||
d.type === 'nullable' ||
d.type === 'default') &&
d.innerType
) {
current = d.innerType
continue
}
return current
}
/* v8 ignore next -- loop returns inside; reached only past the cycle guard */
return current
}
// The default to write for a field the caller omitted, present only when the
// field is required-with-default in the spec — emitted as `.default(x)` with no
// `.optional()` in the wrapper chain (TypeSpec `field: T = x`, not
// `field?: T = x`). Such fields must be present on the wire (e.g. a CloudEvents
// envelope's `specversion`, which the server's parser rejects when absent), yet
// the generated request type allows omitting them so callers get the documented
// default for free — toWire is the layer that has to reconcile the two.
// Spec-optional fields (`.optional().default(x)`) return undefined and stay off
// the wire: their default is the server's to apply, and materializing them
// client-side would silently overwrite server state on update requests.
function requiredDefault(
schema: ZodType | undefined,
): { value: unknown } | undefined {
let current = schema
let found: { value: unknown } | undefined
for (let i = 0; i < 100 && current; i++) {
const d = def(current)
/* v8 ignore next 3 -- every zod schema carries a def; guards the type only */
if (!d) {
break
}
if (d.type === 'optional') {
return undefined
}
if (d.type === 'default') {
found ??= { value: d.defaultValue }
} else if (d.type !== 'nullable') {
break
}
current = d.innerType
}
return found
}
function shapeOf(
schema: ZodType | undefined,
): Record<string, ZodType> | undefined {
return (schema as { shape?: Record<string, ZodType> } | undefined)?.shape
}
// The element schema for array data: the schema's own element when it is an
// array, or the array variant's element when it is a union of T and T[]
// (the single-or-batch body shape).
function arrayElement(schema: ZodType | undefined): ZodType | undefined {
const d = def(schema)
if (d?.type === 'array') {
return d.element
}
if (d?.type === 'union') {
for (const option of d.options ?? []) {
const od = def(unwrap(option))
if (od?.type === 'array') {
return od.element
}
}
}
return undefined
}
// Whether a record value schema needs walking: it carries renamable fields
// (object/record/array/union of such) or date-typed values that must map
// between `Date` and the RFC 3339 wire string. Other scalars, literals,
// unknown, and any are left untouched, so user data (labels, dimensions,
// event payloads) is never rewritten.
function needsWalk(schema: ZodType | undefined): boolean {
const s = unwrap(schema)
const d = def(s)
/* v8 ignore next 3 -- a record always has a value schema; defensive only */
if (!d) {
return false
}
if (
d.type === 'object' ||
d.type === 'record' ||
d.type === 'date' ||
d.type === 'bigint'
) {
return true
}
if (d.type === 'array') {
return needsWalk(d.element)
}
if (d.type === 'union') {
return (d.options ?? []).some(needsWalk)
}
return false
}
// Thrown by toWire when a bigint value (an int64/uint64 field) is outside
// JSON's exactly-representable integer range. The wire carries int64 as a JSON
// number (the server decodes it into a Go int64), so a value beyond 2^53-1
// cannot be sent without silent precision corruption — a typed, immediate
// failure is the only honest option. request() catches it like any Error and
// surfaces it as Result.error.
export class UnsafeIntegerError extends Error {
constructor(value: bigint) {
super(
`bigint value ${value} exceeds JSON's safe integer range and cannot be sent without precision loss`,
)
this.name = 'UnsafeIntegerError'
}
}
// An RFC 3339 string standing in for a `Date` on request input. The
// `Record<never, never>` intersection keeps a plain string assignable while
// stopping the union simplifier from absorbing sibling string literals — a
// bare `| string` would collapse `'immediate' | 'next_billing_cycle' | Date |
// string` to `string | Date` and kill literal autocomplete.
export type DateString = string & Record<never, never>
// The request-side widening of a payload type: every `Date` also accepts its
// RFC 3339 string form. Applied to the generated `…Request` aliases only —
// domain interfaces and response types stay `Date`, so responses always carry
// real `Date`s. At runtime the mapper passes request strings through verbatim
// (never re-parses or normalizes them), so the wire sees exactly what was given
// and the optional wire validation still checks the string against the RFC 3339
// wire schema.
export type AcceptDateStrings<T> = T extends Date
? Date | DateString
: T extends (infer E)[]
? AcceptDateStrings<E>[]
: T extends object
? { [K in keyof T]: AcceptDateStrings<T[K]> }
: T
// Literal siblings of `Date` must survive the widening. Checked at compile
// time in both the emitter build and the generated SDK's typecheck, so a
// regression to a bare `| string` arm fails the build.
type _LiteralsSurviveWidening =
'x' extends Extract<AcceptDateStrings<'x' | Date>, 'x'>
? true
: {
__error: 'AcceptDateStrings absorbed literal union members into string'
}
const _literalsSurviveWidening: _LiteralsSurviveWidening = true
void _literalsSurviveWidening
type Direction = {
// The wire→public or public→wire key rename for object fields.
rename: (key: string) => string
// The data key holding a discriminated union's discriminator, given the
// schema's (camelCase) discriminator key.
discriminatorKey: (camelKey: string) => string
// The value mapping at a date-typed node: public `Date` → RFC 3339 wire
// string, wire string → `Date`. Values already in the target form (or not
// convertible) pass through unchanged.
mapDate: (value: unknown) => unknown
// The value mapping at a bigint-typed (int64/uint64) node: public `bigint` →
// JSON number (throwing UnsafeIntegerError beyond 2^53-1, where JSON numbers
// lose integer precision), wire number → `bigint`. Without the public→wire
// mapping, JSON.stringify throws an opaque TypeError on any bigint. Values
// already in the target form (or not convertible) pass through unchanged.
mapBigInt: (value: unknown) => unknown
// Whether absent required-with-default fields are materialized (see
// requiredDefault). True only public→wire: requests must satisfy the wire
// contract, while responses are reported as the server sent them — fromWire
// fabricating fields would mask genuine contract violations.
applyDefaults: boolean
// JSON.stringify omits object properties and record entries whose value is
// undefined. True only public→wire so validation sees the effective JSON
// payload instead of an intermediate object that the transport cannot send.
// Array entries are deliberately unaffected: JSON serializes undefined array
// values as null rather than omitting them.
omitUndefinedObjectEntries: boolean
}
// A handful of schemas are genuinely self-referential (e.g. the `and`/`or`
// legs of a filter tree), so nesting depth is bounded only by the DATA the
// server sends, not by the schema. Without a limit, a crafted or
// accidentally-deep response recurses until the JS engine throws a raw
// `RangeError: Maximum call stack size exceeded` — still caught by request()
// and surfaced as Result.error, but as an opaque native error instead of a
// typed one. 500 levels is far beyond any real filter/record/array nesting
// in the API today; it exists to fail predictably, not to constrain valid data.
const MAX_WALK_DEPTH = 500
export class DepthLimitExceededError extends Error {
constructor() {
super(`wire mapping exceeded maximum nesting depth (${MAX_WALK_DEPTH})`)
this.name = 'DepthLimitExceededError'
}
}
function walk(
data: unknown,
schema: ZodType | undefined,
dir: Direction,
depth = 0,
): unknown {
if (data === null || data === undefined) {
return data
}
// A Date can only ever mean its wire serialization, wherever it sits — a
// typed date field, a record value, or an unknown-schema position. Wire→
// public data never contains Date instances (it comes from JSON.parse), so
// this only rewrites public→wire. The same holds for bigint: JSON.parse
// never produces one, and public→wire it must become a JSON number wherever
// it sits.
if (data instanceof Date) {
return dir.mapDate(data)
}
if (typeof data === 'bigint') {
return dir.mapBigInt(data)
}
if (depth > MAX_WALK_DEPTH) {
throw new DepthLimitExceededError()
}
const s = unwrap(schema)
const d = def(s)
// A date-typed node maps between the public `Date` and the RFC 3339 wire
// string (fromWire revives the string; a string handed to toWire by an
// untyped caller passes through as-is).
if (d?.type === 'date') {
return dir.mapDate(data)
}
// A bigint-typed node revives the wire's JSON number into the public
// `bigint` (public→wire bigints were already mapped by the value check
// above, so only fromWire reaches a number here).
if (d?.type === 'bigint') {
return dir.mapBigInt(data)
}
if (Array.isArray(data)) {
// The schema may be the array itself or a union with an array variant
// (e.g. a single-or-batch body `T | T[]`); resolve the element schema from
// whichever applies so array items are still walked with their shape.
const element = arrayElement(s)
return data.map((item) => walk(item, element, dir, depth + 1))
}
if (typeof data !== 'object') {
// A wire datetime can sit behind a union (`DateTime | null`,
// enum-or-DateTime): revive the string only when the union's date variant
// is its sole plausible owner, so enum literals and plain-string variants
// pass through untouched.
if (
typeof data === 'string' &&
d?.type === 'union' &&
unionDateClaims(s, data)
) {
return dir.mapDate(data)
}
return data
}
const record = data as Record<string, unknown>
if (d?.type === 'record') {
// Record keys are user data (label/dimension names) — preserved verbatim.
// Only the value is walked, and only when it needs mapping. A null
// prototype avoids the `__proto__` key silently reassigning `out`'s own
// prototype instead of becoming a visible entry (user data may contain
// any key, including reserved object-literal property names). The
// prototype is restored once every key is a plain own property, so the
// returned object still behaves normally for consumers (instanceof,
// template literals) — `Object.prototype` itself was never touched.
const valueSchema = needsWalk(d.valueType) ? d.valueType : undefined
const out: Record<string, unknown> = Object.create(null)
for (const [key, value] of Object.entries(record)) {
if (dir.omitUndefinedObjectEntries && value === undefined) {
continue
}
out[key] = valueSchema ? walk(value, valueSchema, dir, depth + 1) : value
}
Object.setPrototypeOf(out, Object.prototype)
return out
}
if (d?.type === 'union') {
const variant = selectVariant(record, s, dir)
if (!variant) {
// No confident match: leave keys untransformed rather than guess.
return data
}
return walk(data, variant, dir, depth + 1)
}
if (d?.type === 'object') {
const shape = shapeOf(s) ?? {}
// A null prototype avoids two failure modes from data-controlled keys
// like `__proto__`/`constructor`: (1) `fieldFor` below reading an
// inherited Object.prototype member instead of correctly treating the
// key as schema-undeclared, and (2) the assignment at the end of this
// loop reassigning `out`'s own prototype instead of adding a visible key.
const out: Record<string, unknown> = Object.create(null)
for (const [key, value] of Object.entries(record)) {
if (dir.omitUndefinedObjectEntries && value === undefined) {
continue
}
const fieldSchema = fieldFor(shape, key)
// Keys the schema does not declare are dropped, so the result matches the
// typed shape exactly (a server-added field has no place in the type).
if (fieldSchema === undefined) {
continue
}
out[dir.rename(key)] = walk(value, fieldSchema, dir, depth + 1)
}
if (dir.applyDefaults) {
// Shape keys are generated camelCase identifiers (never data-controlled),
// so direct indexing into `record` is safe here. Runs after the data loop
// so an explicit `key: undefined` entry is also replaced by the default.
for (const [key, fieldSchema] of Object.entries(shape)) {
if (record[key] !== undefined) {
continue
}
const dflt = requiredDefault(fieldSchema)
if (dflt !== undefined) {
out[dir.rename(key)] = walk(dflt.value, fieldSchema, dir, depth + 1)
}
}
}
Object.setPrototypeOf(out, Object.prototype)
return out
}
// Scalar or unknown schema: pass through untransformed.
return data
}
// Resolve a data key to its field schema. The schema is camelCase-keyed; a
// wire→public data key is snake, so it is camelized to index the shape.
// Own-property checks (not `shape[key]`) so a data-controlled key like
// `__proto__` or `constructor` cannot resolve to an inherited
// Object.prototype member and be mistaken for a declared schema field.
function fieldFor(
shape: Record<string, ZodType>,
dataKey: string,
): ZodType | undefined {
if (Object.hasOwn(shape, dataKey)) {
return shape[dataKey]
}
const camelKey = toCamelCase(dataKey)
return Object.hasOwn(shape, camelKey) ? shape[camelKey] : undefined
}
function selectVariant(
data: Record<string, unknown>,
schema: ZodType | undefined,
dir: Direction,
): ZodType | undefined {
const d = def(schema)
const options = d?.options ?? []
if (d?.discriminator && schema) {
// O(1) dispatch on the discriminator literal. The data key is the wire-name in
// fromWire (snake) and the public name in toWire (camel); the variant map is
// keyed by the literal value, which is identical in both directions.
const dataKey = dir.discriminatorKey(d.discriminator)
return variantsByDiscriminator(schema, d).get(data[dataKey])
}
// Non-discriminated union: the codegen gate guarantees at most one object
// variant (it fails the build for a mapped union with two or more), so the single
// object-shaped option is unambiguous. Other variants (scalars, arrays) reach the
// walk through their own data-kind branches, not here.
return options.find((option) => def(unwrap(option))?.type === 'object')
}
// Memoized literal→variant map for a discriminated union, built once per schema.
const variantMapCache = new WeakMap<ZodType, Map<unknown, ZodType>>()
function variantsByDiscriminator(
schema: ZodType,
d: ZodDef,
): Map<unknown, ZodType> {
const cached = variantMapCache.get(schema)
if (cached) {
return cached
}
const map = new Map<unknown, ZodType>()
for (const option of d.options ?? []) {
const shape = shapeOf(unwrap(option))
const literal = literalValue(shape?.[d.discriminator as string])
if (literal !== undefined) {
map.set(literal, option)
}
}
variantMapCache.set(schema, map)
return map
}
function literalValue(schema: ZodType | undefined): unknown {
const s = unwrap(schema)
if (def(s)?.type === 'literal') {
return (s as { value?: unknown }).value
}
/* v8 ignore next -- a discriminated-union variant's discriminator is a literal */
return undefined
}
// Whether a union's date variant is the sole plausible owner of a string
// value: the union carries a date option, no string-capable sibling (a plain
// string variant, an enum containing the value, an equal string literal)
// claims it, and the value actually parses as a date. `DateTime | null`
// revives its RFC 3339 string; `'immediate' | DateTime` keeps the enum
// literal a string. Fail-open: an unclaimed string stays a string.
function unionDateClaims(schema: ZodType | undefined, value: string): boolean {
let hasDate = false
for (const option of def(schema)?.options ?? []) {
const od = def(unwrap(option))
if (od?.type === 'date') {
hasDate = true
} else if (od?.type === 'string') {
return false
} else if (
od?.type === 'enum' &&
Object.values(od.entries ?? {}).includes(value)
) {
return false
} else if (od?.type === 'literal' && literalValue(option) === value) {
return false
}
}
return hasDate && !Number.isNaN(Date.parse(value))
}
const toWireDirection: Direction = {
rename: toSnakeCase,
discriminatorKey: (camelKey) => camelKey,
mapDate: (value) => (value instanceof Date ? value.toISOString() : value),
mapBigInt: (value) => {
if (typeof value !== 'bigint') {
return value
}
if (
value > BigInt(Number.MAX_SAFE_INTEGER) ||
value < -BigInt(Number.MAX_SAFE_INTEGER)
) {
throw new UnsafeIntegerError(value)
}
return Number(value)
},
applyDefaults: true,
omitUndefinedObjectEntries: true,
}
// Path binding names are transport metadata, not JSON object member names, so
// they must remain exactly as declared while their values receive the same
// Date/bigint/default mapping used by request bodies and query parameters.
const toPathWireDirection: Direction = {
...toWireDirection,
rename: (key) => key,
}
const fromWireDirection: Direction = {
rename: toCamelCase,
discriminatorKey: (camelKey) => toSnakeCase(camelKey),
mapDate: (value) => (typeof value === 'string' ? new Date(value) : value),
mapBigInt: (value) =>
typeof value === 'number' && Number.isInteger(value)
? BigInt(value)
: value,
applyDefaults: false,
omitUndefinedObjectEntries: false,
}
// Rewrite a request body or query object from the camelCase public shape to the
// snake_case wire shape, driven by its schema. Record keys (label/dimension names)
// are preserved; `Date` values serialize to RFC 3339 strings; `bigint` values
// (int64 fields) become JSON numbers; omitted required-with-default fields are
// filled with their declared default (see requiredDefault); explicit undefined
// object/record entries are omitted just as JSON.stringify would omit them. The
// return is typed as the input `T` so call sites stay cast-free (the runtime object
// has snake keys and wire-encoded dates, but the value is write-only — it flows
// straight into `json:`/`toURLSearchParams`, both of which accept any object).
export function toWire<T>(data: T, schema: ZodType): T {
return walk(data, schema, toWireDirection) as T
}
// Rewrite path-parameter values to their transport representation without
// renaming the path binding keys. The returned object is subsequently validated
// against the generated `…PathParamsWire` schema and URL-encoded by the func.
export function toPathWire<T>(data: T, schema: ZodType): T {
return walk(data, schema, toPathWireDirection) as T
}
// Rewrite a response body from the snake_case wire shape to the camelCase public
// shape: renames keys and revives RFC 3339 strings into `Date`s at date-typed
// nodes — never applies defaults or any other coercion. The result is the
// schema's output shape: `walk` produces exactly the schema's known fields in
// camelCase, so the inferred `output<S>` type describes the runtime value (the
// same wire-trust boundary as a plain `.json<T>()`, with no `.parse()`).
export function fromWire<S extends ZodType>(
data: unknown,
schema: S,
): output<S> {
return walk(data, schema, fromWireDirection) as output<S>
}
// Thrown by assertValid when the optional `validate` client option is on and data
// fails its schema. request() catches it like any Error and surfaces it as
// Result.error.
export class ValidationError extends Error {
constructor(
message: string,
public readonly issues: unknown,
) {
super(message)
this.name = 'ValidationError'
}
}
// Opt-in schema check used by the funcs (when the validate option is on) against
// the snake_case wire payload: the request body after toWire, the raw response
// before fromWire, each against its generated `…Wire` schema. It is a GATE, not a
// transform — the safeParse output (coercions/defaults) is discarded, so validation
// never mutates the payload or return value. Off by default; the SDK does not
// validate by default (additive server fields must not break clients).
export function assertValid(schema: ZodType, data: unknown): void {
const result = schema.safeParse(data)
if (!result.success) {
throw new ValidationError('schema validation failed', result.error.issues)
}
}