From 08cf6a850d9e2f957b11edfa759c8d2b1df729b8 Mon Sep 17 00:00:00 2001 From: Aleksej Kozlov Date: Mon, 3 Mar 2025 20:48:10 +0200 Subject: [PATCH] feat: add support of objects in query params --- .../base/http-clients/fetch-http-client.ejs | 28 +- tests/__snapshots__/extended.test.ts.snap | 1320 +++++++++++++---- tests/__snapshots__/simple.test.ts.snap | 1320 +++++++++++++---- tests/fetch-http-client-query-params.test.ts | 78 + .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/inline.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 60 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../jsAxios/__snapshots__/basic.test.ts.snap | 27 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 28 +- .../patch/__snapshots__/basic.test.ts.snap | 30 +- .../paths/__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- .../__snapshots__/basic.test.ts.snap | 30 +- 37 files changed, 3021 insertions(+), 740 deletions(-) create mode 100644 tests/fetch-http-client-query-params.test.ts diff --git a/templates/base/http-clients/fetch-http-client.ejs b/templates/base/http-clients/fetch-http-client.ejs index 9f6a5c309..d76c92d73 100644 --- a/templates/base/http-clients/fetch-http-client.ejs +++ b/templates/base/http-clients/fetch-http-client.ejs @@ -80,21 +80,35 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value.map(([arrayKey, value]: any) => this.encodeQueryParam(`${key}[${arrayKey}]`, value)).join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { const query = rawQuery || {}; const keys = Object.keys(query).filter((key) => "undefined" !== typeof query[key]); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) - .join("&"); + : this.addQueryParam(query, key); + }) + .join("&"); } protected addQueryParams(rawQuery?: QueryParamsType): string { diff --git a/tests/__snapshots__/extended.test.ts.snap b/tests/__snapshots__/extended.test.ts.snap index f3f968648..3005573d0 100644 --- a/tests/__snapshots__/extended.test.ts.snap +++ b/tests/__snapshots__/extended.test.ts.snap @@ -2801,9 +2801,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -2812,11 +2828,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -4795,9 +4813,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -4806,11 +4840,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -5077,9 +5113,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -5088,11 +5140,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -5394,9 +5448,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -5405,11 +5475,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -6414,9 +6486,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -6425,11 +6513,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -7220,9 +7310,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -7231,11 +7337,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -7580,9 +7688,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -7591,11 +7715,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -7934,9 +8060,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -7945,11 +8087,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -8301,9 +8445,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -8312,11 +8472,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -9134,9 +9296,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -9145,11 +9323,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -9747,9 +9927,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -9758,11 +9954,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -10064,9 +10262,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -10075,11 +10289,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -10387,9 +10603,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -10398,11 +10630,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -10740,9 +10974,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -10751,11 +11001,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -11094,9 +11346,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -11105,11 +11373,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -11473,9 +11743,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -11484,11 +11770,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -11820,9 +12108,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -11831,11 +12135,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -50228,9 +50534,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -50239,11 +50561,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -65645,9 +65969,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -65656,11 +65996,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -66681,9 +67023,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -66692,11 +67050,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -67176,9 +67536,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -67187,11 +67563,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -67629,9 +68007,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -67640,11 +68034,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -68029,9 +68425,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -68040,11 +68452,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -68343,9 +68757,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -68354,11 +68784,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -68705,9 +69137,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -68716,11 +69164,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -69419,9 +69869,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -69430,11 +69896,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -69996,9 +70464,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -70007,11 +70491,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -70424,9 +70910,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -70435,11 +70937,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -70933,9 +71437,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -70944,11 +71464,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -71426,9 +71948,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -71437,11 +71975,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -71795,9 +72335,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -71806,11 +72362,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -72235,9 +72793,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -72246,11 +72820,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -73166,9 +73742,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -73177,11 +73769,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -73963,9 +74557,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -73974,11 +74584,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -74352,9 +74964,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -74363,11 +74991,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -74665,9 +75295,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -74676,11 +75322,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -74961,9 +75609,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -74972,11 +75636,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -75295,9 +75961,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -75306,11 +75988,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -76038,9 +76722,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -76049,11 +76749,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -76931,9 +77633,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -76942,11 +77660,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -78757,9 +79477,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -78768,11 +79504,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -79535,9 +80273,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -79546,11 +80300,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -79886,9 +80642,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -79897,11 +80669,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -80347,9 +81121,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -80358,11 +81148,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/__snapshots__/simple.test.ts.snap b/tests/__snapshots__/simple.test.ts.snap index 7aa1ca417..3dae41269 100644 --- a/tests/__snapshots__/simple.test.ts.snap +++ b/tests/__snapshots__/simple.test.ts.snap @@ -254,9 +254,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -265,11 +281,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -2606,9 +2624,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -2617,11 +2651,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -2888,9 +2924,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -2899,11 +2951,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -3179,9 +3233,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -3190,11 +3260,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -3607,9 +3679,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -3618,11 +3706,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -4378,9 +4468,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -4389,11 +4495,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -4720,9 +4828,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -4731,11 +4855,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -5018,9 +5144,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -5029,11 +5171,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -5362,9 +5506,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -5373,11 +5533,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -5712,9 +5874,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -5723,11 +5901,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -6367,9 +6547,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -6378,11 +6574,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -6682,9 +6880,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -6693,11 +6907,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -6988,9 +7204,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -6999,11 +7231,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -7341,9 +7575,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -7352,11 +7602,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -7656,9 +7908,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -7667,11 +7935,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -7985,9 +8255,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -7996,11 +8282,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -8312,9 +8600,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -8323,11 +8627,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -17284,9 +17590,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -17295,11 +17617,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -38421,9 +38745,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -38432,11 +38772,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -38997,9 +39339,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -39008,11 +39366,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -39672,9 +40032,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -39683,11 +40059,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -39966,9 +40344,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -39977,11 +40371,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -40369,9 +40765,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -40380,11 +40792,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -40657,9 +41071,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -40668,11 +41098,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -40952,9 +41384,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -40963,11 +41411,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -41448,9 +41898,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -41459,11 +41925,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -41944,9 +42412,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -41955,11 +42439,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -42300,9 +42786,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -42311,11 +42813,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -42675,9 +43179,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -42686,11 +43206,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -43064,9 +43586,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -43075,11 +43613,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -43427,9 +43967,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -43438,11 +43994,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -43751,9 +44309,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -43762,11 +44336,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -44167,9 +44743,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -44178,11 +44770,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -44859,9 +45453,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -44870,11 +45480,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -45215,9 +45827,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -45226,11 +45854,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -45535,9 +46165,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -45546,11 +46192,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -45812,9 +46460,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -45823,11 +46487,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -46114,9 +46780,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -46125,11 +46807,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -46539,9 +47223,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -46550,11 +47250,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -47190,9 +47892,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -47201,11 +47919,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -48377,9 +49097,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -48388,11 +49124,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -49170,9 +49908,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -49181,11 +49935,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -49535,9 +50291,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -49546,11 +50318,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -49837,9 +50611,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -49848,11 +50638,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/fetch-http-client-query-params.test.ts b/tests/fetch-http-client-query-params.test.ts new file mode 100644 index 000000000..d8315a9fc --- /dev/null +++ b/tests/fetch-http-client-query-params.test.ts @@ -0,0 +1,78 @@ +import * as fs from "node:fs/promises"; +import * as os from "node:os"; +import * as path from "node:path"; +import { pathToFileURL } from "node:url"; +import { Eta } from "eta"; +import * as ts from "typescript"; +import { afterAll, beforeAll, describe, expect, test } from "vitest"; + +describe("fetch http client query serialization", () => { + let tmpdir = ""; + let client: { + toQueryString(rawQuery?: Record): string; + }; + + beforeAll(async () => { + tmpdir = await fs.mkdtemp(path.join(os.tmpdir(), "swagger-typescript-api")); + + const template = await fs.readFile( + path.resolve( + import.meta.dirname, + "../templates/base/http-clients/fetch-http-client.ejs", + ), + { encoding: "utf8" }, + ); + + const eta = new Eta(); + const rendered = eta.renderString(template, { + apiConfig: { baseUrl: "" }, + config: { unwrapResponseData: false }, + generateResponses: false, + }); + + const transpiled = ts.transpileModule(rendered, { + compilerOptions: { + module: ts.ModuleKind.ES2022, + target: ts.ScriptTarget.ES2022, + }, + }).outputText; + + const modulePath = path.join(tmpdir, "fetch-http-client.mjs"); + await fs.writeFile(modulePath, transpiled, { encoding: "utf8" }); + + const { HttpClient } = await import(pathToFileURL(modulePath).href); + client = new HttpClient(); + }); + + afterAll(async () => { + await fs.rm(tmpdir, { recursive: true, force: true }); + }); + + test("serializes primitives as scalar params", () => { + expect(client.toQueryString({ page: 3 })).toBe("page=3"); + }); + + test("serializes arrays with bracketed indexes", () => { + expect(client.toQueryString({ tags: ["one", "two"] })).toBe( + "tags%5B0%5D=one&tags%5B1%5D=two", + ); + }); + + test("serializes plain objects with bracketed keys", () => { + expect(client.toQueryString({ filter: { status: "active" } })).toBe( + "filter%5Bstatus%5D=active", + ); + }); + + test("keeps null values on the scalar path", () => { + expect(client.toQueryString({ empty: null })).toBe("empty=null"); + }); + + test("keeps Date values on the scalar path", () => { + const value = new Date("2025-10-23T00:00:00.000Z"); + + expect(client.toQueryString({ when: value })).toBe( + `when=${encodeURIComponent(`${value}`)}`, + ); + }); +}); diff --git a/tests/spec/another-query-params/__snapshots__/basic.test.ts.snap b/tests/spec/another-query-params/__snapshots__/basic.test.ts.snap index f987d8084..622519f79 100644 --- a/tests/spec/another-query-params/__snapshots__/basic.test.ts.snap +++ b/tests/spec/another-query-params/__snapshots__/basic.test.ts.snap @@ -125,9 +125,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -136,11 +152,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/binary-produces-base-path-with-extracts/__snapshots__/basic.test.ts.snap b/tests/spec/binary-produces-base-path-with-extracts/__snapshots__/basic.test.ts.snap index d7c83ca17..eb389eaeb 100644 --- a/tests/spec/binary-produces-base-path-with-extracts/__snapshots__/basic.test.ts.snap +++ b/tests/spec/binary-produces-base-path-with-extracts/__snapshots__/basic.test.ts.snap @@ -188,9 +188,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -199,11 +215,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/binary-produces-base-path/__snapshots__/basic.test.ts.snap b/tests/spec/binary-produces-base-path/__snapshots__/basic.test.ts.snap index 857ec1d5e..4f6bd0ac6 100644 --- a/tests/spec/binary-produces-base-path/__snapshots__/basic.test.ts.snap +++ b/tests/spec/binary-produces-base-path/__snapshots__/basic.test.ts.snap @@ -108,9 +108,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -119,11 +135,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/binary-produces/__snapshots__/basic.test.ts.snap b/tests/spec/binary-produces/__snapshots__/basic.test.ts.snap index 186a4ce80..f4ef760cd 100644 --- a/tests/spec/binary-produces/__snapshots__/basic.test.ts.snap +++ b/tests/spec/binary-produces/__snapshots__/basic.test.ts.snap @@ -114,9 +114,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -125,11 +141,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/contentMediaType/__snapshots__/basic.test.ts.snap b/tests/spec/contentMediaType/__snapshots__/basic.test.ts.snap index 1530d4b8b..a1441efb8 100644 --- a/tests/spec/contentMediaType/__snapshots__/basic.test.ts.snap +++ b/tests/spec/contentMediaType/__snapshots__/basic.test.ts.snap @@ -110,9 +110,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -121,11 +137,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/custom-extensions/__snapshots__/basic.test.ts.snap b/tests/spec/custom-extensions/__snapshots__/basic.test.ts.snap index aedb9d00f..34931887c 100644 --- a/tests/spec/custom-extensions/__snapshots__/basic.test.ts.snap +++ b/tests/spec/custom-extensions/__snapshots__/basic.test.ts.snap @@ -97,9 +97,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -108,11 +124,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/defaultAsSuccess/__snapshots__/basic.test.ts.snap b/tests/spec/defaultAsSuccess/__snapshots__/basic.test.ts.snap index 3b1386313..86c287caf 100644 --- a/tests/spec/defaultAsSuccess/__snapshots__/basic.test.ts.snap +++ b/tests/spec/defaultAsSuccess/__snapshots__/basic.test.ts.snap @@ -137,9 +137,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -148,11 +164,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/defaultResponse/__snapshots__/basic.test.ts.snap b/tests/spec/defaultResponse/__snapshots__/basic.test.ts.snap index a2198338c..196453375 100644 --- a/tests/spec/defaultResponse/__snapshots__/basic.test.ts.snap +++ b/tests/spec/defaultResponse/__snapshots__/basic.test.ts.snap @@ -97,9 +97,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -108,11 +124,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/deprecated/__snapshots__/basic.test.ts.snap b/tests/spec/deprecated/__snapshots__/basic.test.ts.snap index a8e4b05d3..33b63ee36 100644 --- a/tests/spec/deprecated/__snapshots__/basic.test.ts.snap +++ b/tests/spec/deprecated/__snapshots__/basic.test.ts.snap @@ -97,9 +97,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -108,11 +124,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/dot-path-params/__snapshots__/basic.test.ts.snap b/tests/spec/dot-path-params/__snapshots__/basic.test.ts.snap index 161782a20..415d4c484 100644 --- a/tests/spec/dot-path-params/__snapshots__/basic.test.ts.snap +++ b/tests/spec/dot-path-params/__snapshots__/basic.test.ts.snap @@ -99,9 +99,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -110,11 +126,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/enumNamesAsValues/__snapshots__/basic.test.ts.snap b/tests/spec/enumNamesAsValues/__snapshots__/basic.test.ts.snap index 626a368e5..e8935c56e 100644 --- a/tests/spec/enumNamesAsValues/__snapshots__/basic.test.ts.snap +++ b/tests/spec/enumNamesAsValues/__snapshots__/basic.test.ts.snap @@ -289,9 +289,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -300,11 +316,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/enumNamesAsValues/__snapshots__/inline.test.ts.snap b/tests/spec/enumNamesAsValues/__snapshots__/inline.test.ts.snap index 816ee8685..b793a8e99 100644 --- a/tests/spec/enumNamesAsValues/__snapshots__/inline.test.ts.snap +++ b/tests/spec/enumNamesAsValues/__snapshots__/inline.test.ts.snap @@ -109,9 +109,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -120,11 +136,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/enumNotFirstInComponents/__snapshots__/basic.test.ts.snap b/tests/spec/enumNotFirstInComponents/__snapshots__/basic.test.ts.snap index ed22a3bd2..2949b96e7 100644 --- a/tests/spec/enumNotFirstInComponents/__snapshots__/basic.test.ts.snap +++ b/tests/spec/enumNotFirstInComponents/__snapshots__/basic.test.ts.snap @@ -127,9 +127,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -138,11 +154,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/extractRequestBody/__snapshots__/basic.test.ts.snap b/tests/spec/extractRequestBody/__snapshots__/basic.test.ts.snap index f34bbe52c..596c0f993 100644 --- a/tests/spec/extractRequestBody/__snapshots__/basic.test.ts.snap +++ b/tests/spec/extractRequestBody/__snapshots__/basic.test.ts.snap @@ -268,9 +268,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -279,11 +295,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/extractRequestParams/__snapshots__/basic.test.ts.snap b/tests/spec/extractRequestParams/__snapshots__/basic.test.ts.snap index e8ebb16f1..27aebea51 100644 --- a/tests/spec/extractRequestParams/__snapshots__/basic.test.ts.snap +++ b/tests/spec/extractRequestParams/__snapshots__/basic.test.ts.snap @@ -227,9 +227,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -238,11 +254,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/extractResponseBody/__snapshots__/basic.test.ts.snap b/tests/spec/extractResponseBody/__snapshots__/basic.test.ts.snap index eaf33c1de..6c144f3f5 100644 --- a/tests/spec/extractResponseBody/__snapshots__/basic.test.ts.snap +++ b/tests/spec/extractResponseBody/__snapshots__/basic.test.ts.snap @@ -252,9 +252,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -263,11 +279,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/extractResponseError/__snapshots__/basic.test.ts.snap b/tests/spec/extractResponseError/__snapshots__/basic.test.ts.snap index e4a3e4f26..93762b007 100644 --- a/tests/spec/extractResponseError/__snapshots__/basic.test.ts.snap +++ b/tests/spec/extractResponseError/__snapshots__/basic.test.ts.snap @@ -247,9 +247,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -258,11 +274,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/issue-1321/__snapshots__/basic.test.ts.snap b/tests/spec/issue-1321/__snapshots__/basic.test.ts.snap index a5629bd9c..cecb2f32f 100644 --- a/tests/spec/issue-1321/__snapshots__/basic.test.ts.snap +++ b/tests/spec/issue-1321/__snapshots__/basic.test.ts.snap @@ -130,9 +130,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -141,11 +157,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } @@ -467,9 +485,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -478,11 +512,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/issue-1433/__snapshots__/basic.test.ts.snap b/tests/spec/issue-1433/__snapshots__/basic.test.ts.snap index 39c9636df..5bbca924e 100644 --- a/tests/spec/issue-1433/__snapshots__/basic.test.ts.snap +++ b/tests/spec/issue-1433/__snapshots__/basic.test.ts.snap @@ -101,9 +101,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -112,11 +128,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/jsAxios/__snapshots__/basic.test.ts.snap b/tests/spec/jsAxios/__snapshots__/basic.test.ts.snap index 0b4dbc534..406228e57 100644 --- a/tests/spec/jsAxios/__snapshots__/basic.test.ts.snap +++ b/tests/spec/jsAxios/__snapshots__/basic.test.ts.snap @@ -46,9 +46,23 @@ export class HttpClient { addQueryParam(query, key) { return this.encodeQueryParam(key, query[key]); } + isPlainObject(value) { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } addArrayQueryParam(query, key) { - const value = query[key]; - return value.map((v) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue); + return value + .map(([arrayKey, value]) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } toQueryString(rawQuery) { const query = rawQuery || {}; @@ -56,11 +70,12 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } addQueryParams(rawQuery) { diff --git a/tests/spec/jsonapi-media-type/__snapshots__/basic.test.ts.snap b/tests/spec/jsonapi-media-type/__snapshots__/basic.test.ts.snap index 5f4c7ab8e..4fb5cd8a3 100644 --- a/tests/spec/jsonapi-media-type/__snapshots__/basic.test.ts.snap +++ b/tests/spec/jsonapi-media-type/__snapshots__/basic.test.ts.snap @@ -123,9 +123,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -134,11 +150,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/moduleNameFirstTag/__snapshots__/basic.test.ts.snap b/tests/spec/moduleNameFirstTag/__snapshots__/basic.test.ts.snap index 347ca8d6b..0b42a2465 100644 --- a/tests/spec/moduleNameFirstTag/__snapshots__/basic.test.ts.snap +++ b/tests/spec/moduleNameFirstTag/__snapshots__/basic.test.ts.snap @@ -222,9 +222,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -233,11 +249,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/moduleNameIndex/__snapshots__/basic.test.ts.snap b/tests/spec/moduleNameIndex/__snapshots__/basic.test.ts.snap index fe0d3c479..32a175a47 100644 --- a/tests/spec/moduleNameIndex/__snapshots__/basic.test.ts.snap +++ b/tests/spec/moduleNameIndex/__snapshots__/basic.test.ts.snap @@ -222,9 +222,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -233,11 +249,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/on-insert-path-param/__snapshots__/basic.test.ts.snap b/tests/spec/on-insert-path-param/__snapshots__/basic.test.ts.snap index 9328e352a..a6257e541 100644 --- a/tests/spec/on-insert-path-param/__snapshots__/basic.test.ts.snap +++ b/tests/spec/on-insert-path-param/__snapshots__/basic.test.ts.snap @@ -97,9 +97,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -108,11 +124,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/operationId-starting-with-number/__snapshots__/basic.test.ts.snap b/tests/spec/operationId-starting-with-number/__snapshots__/basic.test.ts.snap index d1b17a5a3..68b25a160 100644 --- a/tests/spec/operationId-starting-with-number/__snapshots__/basic.test.ts.snap +++ b/tests/spec/operationId-starting-with-number/__snapshots__/basic.test.ts.snap @@ -146,21 +146,35 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value.map(([arrayKey, value]: any) => this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value)).join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { const query = rawQuery || {}; const keys = Object.keys(query).filter((key) => "undefined" !== typeof query[key]); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) - .join("&"); + : this.addQueryParam(query, key); + }) + .join("&"); } protected addQueryParams(rawQuery?: QueryParamsType): string { diff --git a/tests/spec/patch/__snapshots__/basic.test.ts.snap b/tests/spec/patch/__snapshots__/basic.test.ts.snap index a307e33c9..4d2c53050 100644 --- a/tests/spec/patch/__snapshots__/basic.test.ts.snap +++ b/tests/spec/patch/__snapshots__/basic.test.ts.snap @@ -1854,9 +1854,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -1865,11 +1881,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/paths/__snapshots__/basic.test.ts.snap b/tests/spec/paths/__snapshots__/basic.test.ts.snap index 31cc5e038..7dbefac07 100644 --- a/tests/spec/paths/__snapshots__/basic.test.ts.snap +++ b/tests/spec/paths/__snapshots__/basic.test.ts.snap @@ -570,9 +570,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -581,11 +597,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/responses/__snapshots__/basic.test.ts.snap b/tests/spec/responses/__snapshots__/basic.test.ts.snap index f8eb1386c..154d94dd9 100644 --- a/tests/spec/responses/__snapshots__/basic.test.ts.snap +++ b/tests/spec/responses/__snapshots__/basic.test.ts.snap @@ -137,9 +137,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -148,11 +164,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/singleHttpClient/__snapshots__/basic.test.ts.snap b/tests/spec/singleHttpClient/__snapshots__/basic.test.ts.snap index 3679cfb08..acf9c17b6 100644 --- a/tests/spec/singleHttpClient/__snapshots__/basic.test.ts.snap +++ b/tests/spec/singleHttpClient/__snapshots__/basic.test.ts.snap @@ -97,9 +97,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -108,11 +124,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/sortTypes-false/__snapshots__/basic.test.ts.snap b/tests/spec/sortTypes-false/__snapshots__/basic.test.ts.snap index 69d5302ed..56c35ac11 100644 --- a/tests/spec/sortTypes-false/__snapshots__/basic.test.ts.snap +++ b/tests/spec/sortTypes-false/__snapshots__/basic.test.ts.snap @@ -1854,9 +1854,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -1865,11 +1881,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/sortTypes/__snapshots__/basic.test.ts.snap b/tests/spec/sortTypes/__snapshots__/basic.test.ts.snap index 785d970ce..986c3c6d0 100644 --- a/tests/spec/sortTypes/__snapshots__/basic.test.ts.snap +++ b/tests/spec/sortTypes/__snapshots__/basic.test.ts.snap @@ -1854,9 +1854,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -1865,11 +1881,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/typeSuffixPrefix/__snapshots__/basic.test.ts.snap b/tests/spec/typeSuffixPrefix/__snapshots__/basic.test.ts.snap index aef88befe..0dc17f37b 100644 --- a/tests/spec/typeSuffixPrefix/__snapshots__/basic.test.ts.snap +++ b/tests/spec/typeSuffixPrefix/__snapshots__/basic.test.ts.snap @@ -1866,9 +1866,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -1877,11 +1893,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); } diff --git a/tests/spec/unionEnums/__snapshots__/basic.test.ts.snap b/tests/spec/unionEnums/__snapshots__/basic.test.ts.snap index 1c1388696..494740a3b 100644 --- a/tests/spec/unionEnums/__snapshots__/basic.test.ts.snap +++ b/tests/spec/unionEnums/__snapshots__/basic.test.ts.snap @@ -109,9 +109,25 @@ export class HttpClient { return this.encodeQueryParam(key, query[key]); } + protected isPlainObject(value: unknown): value is Record { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; + } + protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + const rawValue = query[key]; + const value = Array.isArray(rawValue) + ? rawValue.map((value, index) => [index, value]) + : Object.entries(rawValue as Record); + return value + .map(([arrayKey, value]: any) => + this.encodeQueryParam(\`\${key}[\${arrayKey}]\`, value), + ) + .join("&"); } protected toQueryString(rawQuery?: QueryParamsType): string { @@ -120,11 +136,13 @@ export class HttpClient { (key) => "undefined" !== typeof query[key], ); return keys - .map((key) => - Array.isArray(query[key]) + .map((key) => { + const value = query[key]; + + return Array.isArray(value) || this.isPlainObject(value) ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) + : this.addQueryParam(query, key); + }) .join("&"); }