Repository: prisma/prisma
File: packages/client-engine-runtime/src/json-protocol.ts (TypeScript)

Code before:
  }

  return result
}

function isTaggedValue(value: unknown): value is JsonOutputTaggedValue {
  return value !== null && typeof value == 'object' && typeof value['$type'] === 'string'
}

/**
 * Normalizes the value inside a tagged value to match the snapshots in tests.
 * Sometimes there are multiple equally valid representations of the same value
 * (e.g. a decimal string may contain an arbitrary number of trailing zeros,
 * datetime strings may specify the UTC offset as either '+00:00' or 'Z', etc).
 * Since these differences have no effect on the actual values received from the
 * Prisma Client once the response is deserialized to JavaScript values, we don't
 * spend extra CPU cycles on normalizing them in the data mapper. Instead, we
 * patch and normalize them here to ensure they are consistent with the snapshots
 * in the query engine tests.
 */
function normalizeTaggedValue({ $type, value }: JsonOutputTaggedValue): JsonOutputTaggedValue {
  switch ($type) {
    case 'BigInt':
      return { $type, value: String(value) }
    case 'Bytes':
      return { $type, value: Buffer.from(value, 'base64').toString('base64') }
    case 'DateTime':
      return { $type, value: new Date(value).toISOString() }
    case 'Decimal':
      return { $type, value: String(new Decimal(value)) }
    case 'Json':
      return { $type, value: JSON.stringify(JSON.parse(value)) }
    default:
      assertNever(value, 'Unknown tagged value')
  }
}

function mapObjectValues<K extends PropertyKey, T, U>(
  object: Record<K, T>,
  mapper: (value: T, key: K) => U,
): Record<K, U> {
  const result = {} as Record<K, U>

  for (const key of Object.keys(object)) {
    result[key] = mapper(object[key] as T, key as K)
  }

  return result
}

export function deserializeJsonResponse(result: unknown): unknown {

Review comment (suggestion):
Should this be something like this instead?
```suggestion
function normalizeTaggedValue<T extends JsonInputTaggedValue | JsonOutputTaggedValue>({
  $type,
  value,
}: T): T {
```

Code after:

    return mapObjectValues(result, normalizeJsonProtocolValues)
  }

  return result
}

function isTaggedValue(value: unknown): value is JsonOutputTaggedValue {
  return value !== null && typeof value == 'object' && typeof value['$type'] === 'string'
}

/**
 * Normalizes the value inside a tagged value to match the snapshots in tests.
 * Sometimes there are multiple equally valid representations of the same value
 * (e.g. a decimal string may contain an arbitrary number of trailing zeros,
 * datetime strings may specify the UTC offset as either '+00:00' or 'Z', etc).
 * Since these differences have no effect on the actual values received from the
 * Prisma Client once the response is deserialized to JavaScript values, we don't
 * spend extra CPU cycles on normalizing them in the data mapper. Instead, we
 * patch and normalize them here to ensure they are consistent with the snapshots
 * in the query engine tests.
 */
function normalizeTaggedValue({
  $type,
  value,
}: JsonInputTaggedValue | JsonOutputTaggedValue): JsonInputTaggedValue | JsonOutputTaggedValue {
  switch ($type) {
    case 'BigInt':
      return { $type, value: String(value) }
    case 'Bytes':
      return { $type, value: Buffer.from(value, 'base64').toString('base64') }
    case 'DateTime':
      return { $type, value: new Date(value).toISOString() }
    case 'Decimal':
      return { $type, value: String(new Decimal(value)) }
    case 'Json':
      return { $type, value: JSON.stringify(JSON.parse(value)) }
    case 'Raw':
      return { $type, value }
    case 'FieldRef':
      return { $type, value }
    case 'Enum':
      return { $type, value }
    default:
      assertNever(value, 'Unknown tagged value')
  }
}

function mapObjectValues<K extends PropertyKey, T, U>(
  object: Record<K, T>,
  mapper: (value: T, key: K) => U,