diff --git a/packages/core/postgrest-js/src/PostgrestQueryBuilder.ts b/packages/core/postgrest-js/src/PostgrestQueryBuilder.ts index 25bb604b4..d82bb70ad 100644 --- a/packages/core/postgrest-js/src/PostgrestQueryBuilder.ts +++ b/packages/core/postgrest-js/src/PostgrestQueryBuilder.ts @@ -52,6 +52,16 @@ export default class PostgrestQueryBuilder< this.fetch = fetch } + /** + * Clone URL and headers to prevent shared state between operations. + */ + private cloneRequestState(): { url: URL; headers: Headers } { + return { + url: new URL(this.url.toString()), + headers: new Headers(this.headers), + } + } + /** * Perform a SELECT query on the table or view. * @@ -115,16 +125,18 @@ export default class PostgrestQueryBuilder< return c }) .join('') - this.url.searchParams.set('select', cleanedColumns) + + const { url, headers } = this.cloneRequestState() + url.searchParams.set('select', cleanedColumns) if (count) { - this.headers.append('Prefer', `count=${count}`) + headers.append('Prefer', `count=${count}`) } return new PostgrestFilterBuilder({ method, - url: this.url, - headers: this.headers, + url, + headers, schema: this.schema, fetch: this.fetch, }) @@ -205,26 +217,27 @@ export default class PostgrestQueryBuilder< 'POST' > { const method = 'POST' + const { url, headers } = this.cloneRequestState() if (count) { - this.headers.append('Prefer', `count=${count}`) + headers.append('Prefer', `count=${count}`) } if (!defaultToNull) { - this.headers.append('Prefer', `missing=default`) + headers.append('Prefer', `missing=default`) } if (Array.isArray(values)) { const columns = values.reduce((acc, x) => acc.concat(Object.keys(x)), [] as string[]) if (columns.length > 0) { const uniqueColumns = [...new Set(columns)].map((column) => `"${column}"`) - this.url.searchParams.set('columns', uniqueColumns.join(',')) + url.searchParams.set('columns', uniqueColumns.join(',')) } } return new PostgrestFilterBuilder({ method, - url: this.url, - headers: this.headers, + url, + headers, schema: this.schema, body: values, fetch: this.fetch ?? fetch, @@ -375,29 +388,30 @@ export default class PostgrestQueryBuilder< 'POST' > { const method = 'POST' + const { url, headers } = this.cloneRequestState() - this.headers.append('Prefer', `resolution=${ignoreDuplicates ? 'ignore' : 'merge'}-duplicates`) + headers.append('Prefer', `resolution=${ignoreDuplicates ? 'ignore' : 'merge'}-duplicates`) - if (onConflict !== undefined) this.url.searchParams.set('on_conflict', onConflict) + if (onConflict !== undefined) url.searchParams.set('on_conflict', onConflict) if (count) { - this.headers.append('Prefer', `count=${count}`) + headers.append('Prefer', `count=${count}`) } if (!defaultToNull) { - this.headers.append('Prefer', 'missing=default') + headers.append('Prefer', 'missing=default') } if (Array.isArray(values)) { const columns = values.reduce((acc, x) => acc.concat(Object.keys(x)), [] as string[]) if (columns.length > 0) { const uniqueColumns = [...new Set(columns)].map((column) => `"${column}"`) - this.url.searchParams.set('columns', uniqueColumns.join(',')) + url.searchParams.set('columns', uniqueColumns.join(',')) } } return new PostgrestFilterBuilder({ method, - url: this.url, - headers: this.headers, + url, + headers, schema: this.schema, body: values, fetch: this.fetch ?? fetch, @@ -442,14 +456,16 @@ export default class PostgrestQueryBuilder< 'PATCH' > { const method = 'PATCH' + const { url, headers } = this.cloneRequestState() + if (count) { - this.headers.append('Prefer', `count=${count}`) + headers.append('Prefer', `count=${count}`) } return new PostgrestFilterBuilder({ method, - url: this.url, - headers: this.headers, + url, + headers, schema: this.schema, body: values, fetch: this.fetch ?? fetch, @@ -489,14 +505,16 @@ export default class PostgrestQueryBuilder< 'DELETE' > { const method = 'DELETE' + const { url, headers } = this.cloneRequestState() + if (count) { - this.headers.append('Prefer', `count=${count}`) + headers.append('Prefer', `count=${count}`) } return new PostgrestFilterBuilder({ method, - url: this.url, - headers: this.headers, + url, + headers, schema: this.schema, fetch: this.fetch ?? fetch, })