Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 38 additions & 3 deletions templates/base/http-clients/fetch-http-client.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,44 @@ export class HttpClient<SecurityDataType = unknown> {
body: typeof body === "undefined" || body === null ? null : payloadFormatter(body),
}
).then(async (response) => {
const r = response as HttpResponse<T, E>;
r.data = (null as unknown) as T;
r.error = (null as unknown) as E;
// Create a Proxy that wraps the Response without mutating it
// This ensures compatibility with ESM environments where Response is read-only
// while maintaining all Response properties and methods as live/dynamic values
const r = new Proxy(response, {
get(target, prop) {
// Custom properties for our API wrapper
if (prop === 'data') {
return target._data !== undefined ? target._data : (null as unknown) as T;
}
if (prop === 'error') {
return target._error !== undefined ? target._error : (null as unknown) as E;
}

// Delegate everything else to the actual Response object
const value = target[prop];

// Bind methods to the original response to maintain correct 'this' context
if (typeof value === 'function') {
return value.bind(target);
}

return value;
},
set(target, prop, value) {
// Allow setting data and error properties
if (prop === 'data') {
target._data = value;
return true;
}
if (prop === 'error') {
target._error = value;
return true;
}

// Prevent mutation of Response properties (ESM safety)
return false;
}
}) as HttpResponse<T, E>;

const responseToParse = responseFormat ? response.clone() : response;
const data = !responseFormat ? r : await responseToParse[responseFormat]()
Expand Down
Loading