summaryrefslogtreecommitdiffhomepage
path: root/packages/sdk/js/src/v2/gen/core/queryKeySerializer.gen.ts
blob: 320204aef108409af21c70cc51c9d2e6a606fe63 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// This file is auto-generated by @hey-api/openapi-ts

/**
 * JSON-friendly union that mirrors what Pinia Colada can hash.
 */
export type JsonValue = null | string | number | boolean | JsonValue[] | { [key: string]: JsonValue }

/**
 * Replacer that converts non-JSON values (bigint, Date, etc.) to safe substitutes.
 */
export const queryKeyJsonReplacer = (_key: string, value: unknown) => {
  if (value === undefined || typeof value === "function" || typeof value === "symbol") {
    return undefined
  }
  if (typeof value === "bigint") {
    return value.toString()
  }
  if (value instanceof Date) {
    return value.toISOString()
  }
  return value
}

/**
 * Safely stringifies a value and parses it back into a JsonValue.
 */
export const stringifyToJsonValue = (input: unknown): JsonValue | undefined => {
  try {
    const json = JSON.stringify(input, queryKeyJsonReplacer)
    if (json === undefined) {
      return undefined
    }
    return JSON.parse(json) as JsonValue
  } catch {
    return undefined
  }
}

/**
 * Detects plain objects (including objects with a null prototype).
 */
const isPlainObject = (value: unknown): value is Record<string, unknown> => {
  if (value === null || typeof value !== "object") {
    return false
  }
  const prototype = Object.getPrototypeOf(value as object)
  return prototype === Object.prototype || prototype === null
}

/**
 * Turns URLSearchParams into a sorted JSON object for deterministic keys.
 */
const serializeSearchParams = (params: URLSearchParams): JsonValue => {
  const entries = Array.from(params.entries()).sort(([a], [b]) => a.localeCompare(b))
  const result: Record<string, JsonValue> = {}

  for (const [key, value] of entries) {
    const existing = result[key]
    if (existing === undefined) {
      result[key] = value
      continue
    }

    if (Array.isArray(existing)) {
      ;(existing as string[]).push(value)
    } else {
      result[key] = [existing, value]
    }
  }

  return result
}

/**
 * Normalizes any accepted value into a JSON-friendly shape for query keys.
 */
export const serializeQueryKeyValue = (value: unknown): JsonValue | undefined => {
  if (value === null) {
    return null
  }

  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
    return value
  }

  if (value === undefined || typeof value === "function" || typeof value === "symbol") {
    return undefined
  }

  if (typeof value === "bigint") {
    return value.toString()
  }

  if (value instanceof Date) {
    return value.toISOString()
  }

  if (Array.isArray(value)) {
    return stringifyToJsonValue(value)
  }

  if (typeof URLSearchParams !== "undefined" && value instanceof URLSearchParams) {
    return serializeSearchParams(value)
  }

  if (isPlainObject(value)) {
    return stringifyToJsonValue(value)
  }

  return undefined
}