@prover-coder-ai/openapi-effect 1.0.19 → 1.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -3
- package/src/index.ts +16 -11
- package/src/shell/api-client/create-client-middleware.ts +179 -0
- package/src/shell/api-client/create-client-response.ts +115 -0
- package/src/shell/api-client/create-client-runtime-helpers.ts +142 -0
- package/src/shell/api-client/create-client-runtime-types.ts +97 -0
- package/src/shell/api-client/create-client-runtime.ts +316 -0
- package/src/shell/api-client/create-client-types.ts +278 -286
- package/src/shell/api-client/create-client.ts +89 -496
- package/src/shell/api-client/index.ts +28 -1
- package/src/shell/api-client/openapi-compat-path.ts +82 -0
- package/src/shell/api-client/openapi-compat-request.ts +153 -0
- package/src/shell/api-client/openapi-compat-serializers.ts +277 -0
- package/src/shell/api-client/openapi-compat-utils.ts +10 -0
- package/src/shell/api-client/openapi-compat-value-guards.ts +9 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { serializeArrayParam, serializeObjectParam, serializePrimitiveParam } from "./openapi-compat-serializers.js"
|
|
2
|
+
import { isPrimitive, isRecord } from "./openapi-compat-value-guards.js"
|
|
3
|
+
|
|
4
|
+
const PATH_PARAM_RE = /\{[^{}]+\}/g
|
|
5
|
+
|
|
6
|
+
type PathStyle = "simple" | "label" | "matrix"
|
|
7
|
+
|
|
8
|
+
type PathTokenMeta = {
|
|
9
|
+
name: string
|
|
10
|
+
explode: boolean
|
|
11
|
+
style: PathStyle
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const toPathTokenMeta = (rawName: string): PathTokenMeta => {
|
|
15
|
+
let name = rawName
|
|
16
|
+
let explode = false
|
|
17
|
+
let style: PathStyle = "simple"
|
|
18
|
+
|
|
19
|
+
if (name.endsWith("*")) {
|
|
20
|
+
explode = true
|
|
21
|
+
name = name.slice(0, Math.max(0, name.length - 1))
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (name.startsWith(".")) {
|
|
25
|
+
style = "label"
|
|
26
|
+
name = name.slice(1)
|
|
27
|
+
} else if (name.startsWith(";")) {
|
|
28
|
+
style = "matrix"
|
|
29
|
+
name = name.slice(1)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return { name, explode, style }
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const serializePathValue = (
|
|
36
|
+
name: string,
|
|
37
|
+
value: unknown,
|
|
38
|
+
meta: PathTokenMeta
|
|
39
|
+
): string | undefined => {
|
|
40
|
+
if (Array.isArray(value)) {
|
|
41
|
+
return serializeArrayParam(name, value, { style: meta.style, explode: meta.explode })
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (isRecord(value)) {
|
|
45
|
+
return serializeObjectParam(name, value, { style: meta.style, explode: meta.explode })
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (!isPrimitive(value)) {
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (meta.style === "matrix") {
|
|
53
|
+
return `;${serializePrimitiveParam(name, value)}`
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const encoded = encodeURIComponent(String(value))
|
|
57
|
+
return meta.style === "label" ? `.${encoded}` : encoded
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export const defaultPathSerializer = (
|
|
61
|
+
pathname: string,
|
|
62
|
+
pathParams: Record<string, unknown>
|
|
63
|
+
): string => {
|
|
64
|
+
let nextURL = pathname
|
|
65
|
+
|
|
66
|
+
for (const match of pathname.match(PATH_PARAM_RE) ?? []) {
|
|
67
|
+
const rawName = match.slice(1, -1)
|
|
68
|
+
const meta = toPathTokenMeta(rawName)
|
|
69
|
+
const value = pathParams[meta.name]
|
|
70
|
+
|
|
71
|
+
if (value === undefined || value === null) {
|
|
72
|
+
continue
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const serializedValue = serializePathValue(meta.name, value, meta)
|
|
76
|
+
if (serializedValue !== undefined) {
|
|
77
|
+
nextURL = nextURL.replace(match, serializedValue)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return nextURL
|
|
82
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import type { HeadersOptions, PathSerializer, QuerySerializer } from "./create-client-types.js"
|
|
2
|
+
|
|
3
|
+
const isRecord = (value: unknown): value is Record<string, unknown> => (
|
|
4
|
+
value !== null && typeof value === "object" && !Array.isArray(value)
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
const toFormRecord = (value: unknown): Record<string, string> => {
|
|
8
|
+
if (!isRecord(value)) {
|
|
9
|
+
return {}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const formRecord: Record<string, string> = {}
|
|
13
|
+
for (const [key, item] of Object.entries(value)) {
|
|
14
|
+
formRecord[key] = String(item)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return formRecord
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type HeaderRecord = Record<
|
|
21
|
+
string,
|
|
22
|
+
string | number | boolean | Array<string | number | boolean> | null | undefined
|
|
23
|
+
>
|
|
24
|
+
|
|
25
|
+
const isHeaderRecord = (headers: HeadersOptions): headers is HeaderRecord => (
|
|
26
|
+
!(headers instanceof Headers) && !Array.isArray(headers)
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
const getHeaderValue = (headers: Headers | HeadersOptions | undefined, key: string): string | undefined => {
|
|
30
|
+
if (headers === undefined) {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (headers instanceof Headers) {
|
|
35
|
+
return headers.get(key) ?? undefined
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (!isHeaderRecord(headers)) {
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const value = headers[key]
|
|
43
|
+
if (value === undefined || value === null || Array.isArray(value)) {
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return String(value)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const stringifyBody = (body: unknown): string => {
|
|
51
|
+
return JSON.stringify(body)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const defaultBodySerializer = (
|
|
55
|
+
body: unknown,
|
|
56
|
+
headers?: Headers | HeadersOptions
|
|
57
|
+
): string => {
|
|
58
|
+
if (body === undefined) {
|
|
59
|
+
return ""
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const contentType = getHeaderValue(headers, "Content-Type") ?? getHeaderValue(headers, "content-type")
|
|
63
|
+
if (contentType === "application/x-www-form-urlencoded") {
|
|
64
|
+
return new URLSearchParams(toFormRecord(body)).toString()
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return stringifyBody(body)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export const createFinalURL = (
|
|
71
|
+
pathname: string,
|
|
72
|
+
options: {
|
|
73
|
+
baseUrl: string
|
|
74
|
+
params: {
|
|
75
|
+
query?: Record<string, unknown>
|
|
76
|
+
path?: Record<string, unknown>
|
|
77
|
+
}
|
|
78
|
+
querySerializer: QuerySerializer<object>
|
|
79
|
+
pathSerializer: PathSerializer
|
|
80
|
+
}
|
|
81
|
+
): string => {
|
|
82
|
+
let finalURL = `${options.baseUrl}${pathname}`
|
|
83
|
+
|
|
84
|
+
if (options.params.path) {
|
|
85
|
+
finalURL = options.pathSerializer(finalURL, options.params.path)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
let queryString = options.querySerializer(options.params.query ?? {})
|
|
89
|
+
if (queryString.startsWith("?")) {
|
|
90
|
+
queryString = queryString.slice(1)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (queryString.length > 0) {
|
|
94
|
+
finalURL = `${finalURL}?${queryString}`
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return finalURL
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const applyHeaderValue = (target: Headers, key: string, value: HeaderRecord[string]): void => {
|
|
101
|
+
if (value === null) {
|
|
102
|
+
target.delete(key)
|
|
103
|
+
return
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (Array.isArray(value)) {
|
|
107
|
+
for (const item of value) {
|
|
108
|
+
target.append(key, String(item))
|
|
109
|
+
}
|
|
110
|
+
return
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (value !== undefined) {
|
|
114
|
+
target.set(key, String(value))
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const mergeHeaderSource = (target: Headers, source: HeadersOptions): void => {
|
|
119
|
+
if (source instanceof Headers) {
|
|
120
|
+
for (const [key, value] of source.entries()) {
|
|
121
|
+
target.set(key, value)
|
|
122
|
+
}
|
|
123
|
+
return
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (!isHeaderRecord(source)) {
|
|
127
|
+
return
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
for (const [key, value] of Object.entries(source)) {
|
|
131
|
+
applyHeaderValue(target, key, value)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export const mergeHeaders = (
|
|
136
|
+
...allHeaders: Array<HeadersOptions | undefined>
|
|
137
|
+
): Headers => {
|
|
138
|
+
const finalHeaders = new Headers()
|
|
139
|
+
|
|
140
|
+
for (const source of allHeaders) {
|
|
141
|
+
if (source === undefined || typeof source !== "object") {
|
|
142
|
+
continue
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
mergeHeaderSource(finalHeaders, source)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return finalHeaders
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export const removeTrailingSlash = (url: string): string => (
|
|
152
|
+
url.endsWith("/") ? url.slice(0, Math.max(0, url.length - 1)) : url
|
|
153
|
+
)
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import type { QuerySerializer, QuerySerializerOptions } from "./create-client-types.js"
|
|
2
|
+
import { isPrimitive, isRecord, type Primitive } from "./openapi-compat-value-guards.js"
|
|
3
|
+
|
|
4
|
+
type PathStyle = "simple" | "label" | "matrix"
|
|
5
|
+
type ObjectParamStyle = PathStyle | "form" | "deepObject"
|
|
6
|
+
type ArrayParamStyle = PathStyle | "form" | "spaceDelimited" | "pipeDelimited"
|
|
7
|
+
|
|
8
|
+
const OBJECT_JOINER_BY_STYLE: Readonly<Record<ObjectParamStyle, string>> = {
|
|
9
|
+
simple: ",",
|
|
10
|
+
label: ".",
|
|
11
|
+
matrix: ";",
|
|
12
|
+
form: "&",
|
|
13
|
+
deepObject: "&"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const ARRAY_JOINER_BY_STYLE: Readonly<
|
|
17
|
+
Record<ArrayParamStyle, { explodeFalse: string; explodeTrue: string }>
|
|
18
|
+
> = {
|
|
19
|
+
simple: { explodeFalse: ",", explodeTrue: "," },
|
|
20
|
+
label: { explodeFalse: ",", explodeTrue: "." },
|
|
21
|
+
matrix: { explodeFalse: ",", explodeTrue: ";" },
|
|
22
|
+
form: { explodeFalse: ",", explodeTrue: "&" },
|
|
23
|
+
spaceDelimited: { explodeFalse: "%20", explodeTrue: "&" },
|
|
24
|
+
pipeDelimited: { explodeFalse: "|", explodeTrue: "&" }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const encodeValue = (value: Primitive, allowReserved: boolean): string => (
|
|
28
|
+
allowReserved ? String(value) : encodeURIComponent(String(value))
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
const formatExplodeFalse = (
|
|
32
|
+
name: string,
|
|
33
|
+
style: ObjectParamStyle | ArrayParamStyle,
|
|
34
|
+
value: string
|
|
35
|
+
): string => {
|
|
36
|
+
if (style === "simple") {
|
|
37
|
+
return value
|
|
38
|
+
}
|
|
39
|
+
if (style === "label") {
|
|
40
|
+
return `.${value}`
|
|
41
|
+
}
|
|
42
|
+
if (style === "matrix") {
|
|
43
|
+
return `;${name}=${value}`
|
|
44
|
+
}
|
|
45
|
+
return `${name}=${value}`
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const formatExplodeTrue = (
|
|
49
|
+
style: ObjectParamStyle | ArrayParamStyle,
|
|
50
|
+
joiner: string,
|
|
51
|
+
value: string
|
|
52
|
+
): string => (
|
|
53
|
+
style === "label" || style === "matrix" ? `${joiner}${value}` : value
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
const toPrimitiveList = (value: Array<unknown>): Array<Primitive> => {
|
|
57
|
+
const items: Array<Primitive> = []
|
|
58
|
+
for (const item of value) {
|
|
59
|
+
if (isPrimitive(item)) {
|
|
60
|
+
items.push(item)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return items
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const getQueryEntries = (queryParams: unknown): Array<[string, unknown]> => (
|
|
67
|
+
isRecord(queryParams) ? Object.entries(queryParams) : []
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
const toObjectPairs = (
|
|
71
|
+
name: string,
|
|
72
|
+
value: Record<string, unknown>,
|
|
73
|
+
allowReserved: boolean,
|
|
74
|
+
explode: boolean,
|
|
75
|
+
style: ObjectParamStyle
|
|
76
|
+
): Array<string> => {
|
|
77
|
+
const entries: Array<string> = []
|
|
78
|
+
|
|
79
|
+
for (const [key, rawValue] of Object.entries(value)) {
|
|
80
|
+
if (!isPrimitive(rawValue)) {
|
|
81
|
+
continue
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (!explode) {
|
|
85
|
+
entries.push(key, encodeValue(rawValue, allowReserved))
|
|
86
|
+
continue
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const nextName = style === "deepObject" ? `${name}[${key}]` : key
|
|
90
|
+
entries.push(
|
|
91
|
+
serializePrimitiveParam(nextName, rawValue, {
|
|
92
|
+
allowReserved
|
|
93
|
+
})
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return entries
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const toArrayValues = (
|
|
101
|
+
name: string,
|
|
102
|
+
value: Array<unknown>,
|
|
103
|
+
style: ArrayParamStyle,
|
|
104
|
+
allowReserved: boolean,
|
|
105
|
+
explode: boolean
|
|
106
|
+
): Array<string> => {
|
|
107
|
+
const entries: Array<string> = []
|
|
108
|
+
|
|
109
|
+
for (const item of toPrimitiveList(value)) {
|
|
110
|
+
if (explode && style !== "simple" && style !== "label") {
|
|
111
|
+
entries.push(
|
|
112
|
+
serializePrimitiveParam(name, item, {
|
|
113
|
+
allowReserved
|
|
114
|
+
})
|
|
115
|
+
)
|
|
116
|
+
continue
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
entries.push(encodeValue(item, allowReserved))
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return entries
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const finalizeSerializedParam = (options: {
|
|
126
|
+
name: string
|
|
127
|
+
style: ObjectParamStyle | ArrayParamStyle
|
|
128
|
+
explode: boolean
|
|
129
|
+
values: Array<string>
|
|
130
|
+
joinerWhenExplodeFalse: string
|
|
131
|
+
joinerWhenExplodeTrue: string
|
|
132
|
+
}): string => {
|
|
133
|
+
const joiner = options.explode ? options.joinerWhenExplodeTrue : options.joinerWhenExplodeFalse
|
|
134
|
+
const serializedValue = options.values.join(joiner)
|
|
135
|
+
|
|
136
|
+
return options.explode
|
|
137
|
+
? formatExplodeTrue(options.style, options.joinerWhenExplodeTrue, serializedValue)
|
|
138
|
+
: formatExplodeFalse(options.name, options.style, serializedValue)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export const serializePrimitiveParam = (
|
|
142
|
+
name: string,
|
|
143
|
+
value: Primitive,
|
|
144
|
+
options?: { allowReserved?: boolean }
|
|
145
|
+
): string => (
|
|
146
|
+
`${name}=${encodeValue(value, options?.allowReserved === true)}`
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
export const serializeObjectParam = (
|
|
150
|
+
name: string,
|
|
151
|
+
value: unknown,
|
|
152
|
+
options: {
|
|
153
|
+
style: ObjectParamStyle
|
|
154
|
+
explode: boolean
|
|
155
|
+
allowReserved?: boolean
|
|
156
|
+
}
|
|
157
|
+
): string => {
|
|
158
|
+
if (!isRecord(value)) {
|
|
159
|
+
return ""
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const pairs = toObjectPairs(
|
|
163
|
+
name,
|
|
164
|
+
value,
|
|
165
|
+
options.allowReserved === true,
|
|
166
|
+
options.explode,
|
|
167
|
+
options.style
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
return finalizeSerializedParam({
|
|
171
|
+
name,
|
|
172
|
+
style: options.style,
|
|
173
|
+
explode: options.explode,
|
|
174
|
+
values: pairs,
|
|
175
|
+
joinerWhenExplodeFalse: ",",
|
|
176
|
+
joinerWhenExplodeTrue: OBJECT_JOINER_BY_STYLE[options.style]
|
|
177
|
+
})
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export const serializeArrayParam = (
|
|
181
|
+
name: string,
|
|
182
|
+
value: Array<unknown>,
|
|
183
|
+
options: {
|
|
184
|
+
style: ArrayParamStyle
|
|
185
|
+
explode: boolean
|
|
186
|
+
allowReserved?: boolean
|
|
187
|
+
}
|
|
188
|
+
): string => {
|
|
189
|
+
if (!Array.isArray(value)) {
|
|
190
|
+
return ""
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const values = toArrayValues(
|
|
194
|
+
name,
|
|
195
|
+
value,
|
|
196
|
+
options.style,
|
|
197
|
+
options.allowReserved === true,
|
|
198
|
+
options.explode
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
return finalizeSerializedParam({
|
|
202
|
+
name,
|
|
203
|
+
style: options.style,
|
|
204
|
+
explode: options.explode,
|
|
205
|
+
values,
|
|
206
|
+
joinerWhenExplodeFalse: ARRAY_JOINER_BY_STYLE[options.style].explodeFalse,
|
|
207
|
+
joinerWhenExplodeTrue: ARRAY_JOINER_BY_STYLE[options.style].explodeTrue
|
|
208
|
+
})
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const serializeQueryEntry = (
|
|
212
|
+
name: string,
|
|
213
|
+
value: unknown,
|
|
214
|
+
options?: QuerySerializerOptions
|
|
215
|
+
): string | undefined => {
|
|
216
|
+
if (value === undefined || value === null) {
|
|
217
|
+
return
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return Array.isArray(value)
|
|
221
|
+
? serializeArrayQueryEntry(name, value, options)
|
|
222
|
+
: serializeNonArrayQueryEntry(name, value, options)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const serializeArrayQueryEntry = (
|
|
226
|
+
name: string,
|
|
227
|
+
value: Array<unknown>,
|
|
228
|
+
options?: QuerySerializerOptions
|
|
229
|
+
): string | undefined => {
|
|
230
|
+
if (value.length === 0) {
|
|
231
|
+
return
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return serializeArrayParam(name, value, {
|
|
235
|
+
style: "form",
|
|
236
|
+
explode: true,
|
|
237
|
+
...options?.array,
|
|
238
|
+
allowReserved: options?.allowReserved === true
|
|
239
|
+
})
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const serializeNonArrayQueryEntry = (
|
|
243
|
+
name: string,
|
|
244
|
+
value: unknown,
|
|
245
|
+
options?: QuerySerializerOptions
|
|
246
|
+
): string | undefined => {
|
|
247
|
+
if (isRecord(value)) {
|
|
248
|
+
return serializeObjectParam(name, value, {
|
|
249
|
+
style: "deepObject",
|
|
250
|
+
explode: true,
|
|
251
|
+
...options?.object,
|
|
252
|
+
allowReserved: options?.allowReserved === true
|
|
253
|
+
})
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (isPrimitive(value)) {
|
|
257
|
+
return serializePrimitiveParam(name, value, options)
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return undefined
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export const createQuerySerializer = <T = unknown>(
|
|
264
|
+
options?: QuerySerializerOptions
|
|
265
|
+
): QuerySerializer<T> =>
|
|
266
|
+
(queryParams) => {
|
|
267
|
+
const serialized: Array<string> = []
|
|
268
|
+
|
|
269
|
+
for (const [name, value] of getQueryEntries(queryParams)) {
|
|
270
|
+
const entry = serializeQueryEntry(name, value, options)
|
|
271
|
+
if (entry !== undefined) {
|
|
272
|
+
serialized.push(entry)
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return serialized.join("&")
|
|
277
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export {
|
|
2
|
+
createQuerySerializer,
|
|
3
|
+
serializeArrayParam,
|
|
4
|
+
serializeObjectParam,
|
|
5
|
+
serializePrimitiveParam
|
|
6
|
+
} from "./openapi-compat-serializers.js"
|
|
7
|
+
|
|
8
|
+
export { defaultPathSerializer } from "./openapi-compat-path.js"
|
|
9
|
+
|
|
10
|
+
export { createFinalURL, defaultBodySerializer, mergeHeaders, removeTrailingSlash } from "./openapi-compat-request.js"
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type Primitive = string | number | boolean
|
|
2
|
+
|
|
3
|
+
export const isPrimitive = (value: unknown): value is Primitive => (
|
|
4
|
+
typeof value === "string" || typeof value === "number" || typeof value === "boolean"
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
export const isRecord = (value: unknown): value is Record<string, unknown> => (
|
|
8
|
+
value !== null && typeof value === "object" && !Array.isArray(value)
|
|
9
|
+
)
|