fix(clients): defer URL construction and thread finalError through interceptors (#3803) #3851
+51
−77
Annotations
10 errors
|
Run test coverage:
packages/openapi-ts-tests/main/test/clients.test.ts#L201
Error: Snapshot `@hey-api/client-next > 'SDK with Node16 tsconfig' 1` mismatched
- Expected
+ Received
@@ -45,78 +45,69 @@
headers: mergeHeaders(_config.headers, options.headers),
serializedBody: undefined as string | undefined,
};
if (opts.security) {
- await setAuthParams({
- ...opts,
- security: opts.security,
- });
+ await setAuthParams({ ...opts, security: opts.security });
}
if (opts.requestValidator) {
await opts.requestValidator(opts);
}
if (opts.body !== undefined && opts.bodySerializer) {
opts.serializedBody = opts.bodySerializer(opts.body) as string | undefined;
}
- // remove Content-Type header if body is empty to avoid sending invalid requests
if (opts.body === undefined || opts.serializedBody === '') {
opts.headers.delete('Content-Type');
}
- const resolvedOpts = opts as typeof opts & ResolvedRequestOptions<ThrowOnError, Url>;
- const url = buildUrl(resolvedOpts);
-
- return { opts: resolvedOpts, url };
- };
-
- // @ts-expect-error
+ return {
+ opts: opts as typeof opts & ResolvedRequestOptions<ThrowOnError, Url>,
+ };
+ };
+
const request: Client['request'] = async (options) => {
const throwOnError = options.throwOnError ?? _config.throwOnError;
let response: Response | undefined;
try {
- const { opts, url } = await beforeRequest(options);
+ const { opts } = await beforeRequest(options);
+ // request interceptors
for (const fn of interceptors.request.fns) {
- if (fn) {
- await fn(opts);
+ if (fn) await fn(opts);
- }
}
- // fetch must be assigned here, otherwise it would throw the error:
- // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
+ const url = buildUrl(opts);
+
const _fetch = opts.fetch!;
const requestInit: ReqInit = {
...opts,
body: getValidRequestBody(opts),
};
response = await _fetch(url, requestInit);
+ // response interceptors
for (const fn of interceptors.response.fns) {
- if (fn) {
- response = await fn(response, opts);
+ if (fn) response = await fn(response, opts);
- }
}
- const result = {
- response,
- };
+ const result = { response };
if (response.ok) {
const parseAs =
(opts.parseAs === 'auto'
? getParseAs(response.headers.get('Content-Type'))
: opts.parseAs) ?? 'json';
if (response.status === 204 || response.headers.get('Content-Length') === '0') {
- let emptyData: any;
+ let emptyData: any = {};
+
switch (parseAs) {
case 'arrayBuffer':
case 'blob':
case 'text':
emptyData = await response[parseAs]();
@@ -125,66 +116,50 @@
emptyData = new FormData();
break;
case 'stream':
emptyData = response.body;
break;
- case 'json':
- default:
- emptyData = {};
- break;
- }
- return {
- data: emptyData,
- ...result,
- };
+ }
+
+ return { data: emptyData, ...result };
}
let data: any;
+
switch (parseAs) {
case 'arrayBuffer':
case 'blob':
case 'formData':
case 'text':
data = await response[parseAs]();
break;
+
case 'json': {
- // Some servers return 200 with no Content-Length and empty body.
- // response.json() would throw; read as text and parse if non-empty.
const text = await response.text();
data = text ? JSON.parse(text) : {};
break;
}
+
case 'stream':
- return {
- data: respo
|
|
Run test coverage:
packages/openapi-ts-tests/main/test/clients.test.ts#L201
Error: Snapshot `@hey-api/client-next > 'SDK with NodeNext tsconfig' 1` mismatched
- Expected
+ Received
@@ -45,78 +45,69 @@
headers: mergeHeaders(_config.headers, options.headers),
serializedBody: undefined as string | undefined,
};
if (opts.security) {
- await setAuthParams({
- ...opts,
- security: opts.security,
- });
+ await setAuthParams({ ...opts, security: opts.security });
}
if (opts.requestValidator) {
await opts.requestValidator(opts);
}
if (opts.body !== undefined && opts.bodySerializer) {
opts.serializedBody = opts.bodySerializer(opts.body) as string | undefined;
}
- // remove Content-Type header if body is empty to avoid sending invalid requests
if (opts.body === undefined || opts.serializedBody === '') {
opts.headers.delete('Content-Type');
}
- const resolvedOpts = opts as typeof opts & ResolvedRequestOptions<ThrowOnError, Url>;
- const url = buildUrl(resolvedOpts);
-
- return { opts: resolvedOpts, url };
- };
-
- // @ts-expect-error
+ return {
+ opts: opts as typeof opts & ResolvedRequestOptions<ThrowOnError, Url>,
+ };
+ };
+
const request: Client['request'] = async (options) => {
const throwOnError = options.throwOnError ?? _config.throwOnError;
let response: Response | undefined;
try {
- const { opts, url } = await beforeRequest(options);
+ const { opts } = await beforeRequest(options);
+ // request interceptors
for (const fn of interceptors.request.fns) {
- if (fn) {
- await fn(opts);
+ if (fn) await fn(opts);
- }
}
- // fetch must be assigned here, otherwise it would throw the error:
- // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
+ const url = buildUrl(opts);
+
const _fetch = opts.fetch!;
const requestInit: ReqInit = {
...opts,
body: getValidRequestBody(opts),
};
response = await _fetch(url, requestInit);
+ // response interceptors
for (const fn of interceptors.response.fns) {
- if (fn) {
- response = await fn(response, opts);
+ if (fn) response = await fn(response, opts);
- }
}
- const result = {
- response,
- };
+ const result = { response };
if (response.ok) {
const parseAs =
(opts.parseAs === 'auto'
? getParseAs(response.headers.get('Content-Type'))
: opts.parseAs) ?? 'json';
if (response.status === 204 || response.headers.get('Content-Length') === '0') {
- let emptyData: any;
+ let emptyData: any = {};
+
switch (parseAs) {
case 'arrayBuffer':
case 'blob':
case 'text':
emptyData = await response[parseAs]();
@@ -125,66 +116,50 @@
emptyData = new FormData();
break;
case 'stream':
emptyData = response.body;
break;
- case 'json':
- default:
- emptyData = {};
- break;
- }
- return {
- data: emptyData,
- ...result,
- };
+ }
+
+ return { data: emptyData, ...result };
}
let data: any;
+
switch (parseAs) {
case 'arrayBuffer':
case 'blob':
case 'formData':
case 'text':
data = await response[parseAs]();
break;
+
case 'json': {
- // Some servers return 200 with no Content-Length and empty body.
- // response.json() would throw; read as text and parse if non-empty.
const text = await response.text();
data = text ? JSON.parse(text) : {};
break;
}
+
case 'stream':
- return {
- data: res
|
|
Run test coverage:
packages/openapi-ts-tests/main/test/clients.test.ts#L201
Error: Snapshot `@hey-api/client-next > 'client with strict base URL' 1` mismatched
- Expected
+ Received
@@ -45,78 +45,69 @@
headers: mergeHeaders(_config.headers, options.headers),
serializedBody: undefined as string | undefined,
};
if (opts.security) {
- await setAuthParams({
- ...opts,
- security: opts.security,
- });
+ await setAuthParams({ ...opts, security: opts.security });
}
if (opts.requestValidator) {
await opts.requestValidator(opts);
}
if (opts.body !== undefined && opts.bodySerializer) {
opts.serializedBody = opts.bodySerializer(opts.body) as string | undefined;
}
- // remove Content-Type header if body is empty to avoid sending invalid requests
if (opts.body === undefined || opts.serializedBody === '') {
opts.headers.delete('Content-Type');
}
- const resolvedOpts = opts as typeof opts & ResolvedRequestOptions<ThrowOnError, Url>;
- const url = buildUrl(resolvedOpts);
-
- return { opts: resolvedOpts, url };
- };
-
- // @ts-expect-error
+ return {
+ opts: opts as typeof opts & ResolvedRequestOptions<ThrowOnError, Url>,
+ };
+ };
+
const request: Client['request'] = async (options) => {
const throwOnError = options.throwOnError ?? _config.throwOnError;
let response: Response | undefined;
try {
- const { opts, url } = await beforeRequest(options);
+ const { opts } = await beforeRequest(options);
+ // request interceptors
for (const fn of interceptors.request.fns) {
- if (fn) {
- await fn(opts);
+ if (fn) await fn(opts);
- }
}
- // fetch must be assigned here, otherwise it would throw the error:
- // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
+ const url = buildUrl(opts);
+
const _fetch = opts.fetch!;
const requestInit: ReqInit = {
...opts,
body: getValidRequestBody(opts),
};
response = await _fetch(url, requestInit);
+ // response interceptors
for (const fn of interceptors.response.fns) {
- if (fn) {
- response = await fn(response, opts);
+ if (fn) response = await fn(response, opts);
- }
}
- const result = {
- response,
- };
+ const result = { response };
if (response.ok) {
const parseAs =
(opts.parseAs === 'auto'
? getParseAs(response.headers.get('Content-Type'))
: opts.parseAs) ?? 'json';
if (response.status === 204 || response.headers.get('Content-Length') === '0') {
- let emptyData: any;
+ let emptyData: any = {};
+
switch (parseAs) {
case 'arrayBuffer':
case 'blob':
case 'text':
emptyData = await response[parseAs]();
@@ -125,66 +116,50 @@
emptyData = new FormData();
break;
case 'stream':
emptyData = response.body;
break;
- case 'json':
- default:
- emptyData = {};
- break;
- }
- return {
- data: emptyData,
- ...result,
- };
+ }
+
+ return { data: emptyData, ...result };
}
let data: any;
+
switch (parseAs) {
case 'arrayBuffer':
case 'blob':
case 'formData':
case 'text':
data = await response[parseAs]();
break;
+
case 'json': {
- // Some servers return 200 with no Content-Length and empty body.
- // response.json() would throw; read as text and parse if non-empty.
const text = await response.text();
data = text ? JSON.parse(text) : {};
break;
}
+
case 'stream':
- return {
- data: re
|
|
Run test coverage:
packages/openapi-ts-tests/main/test/clients.test.ts#L201
Error: Snapshot `@hey-api/client-next > 'client with custom string base URL' 1` mismatched
- Expected
+ Received
@@ -45,78 +45,69 @@
headers: mergeHeaders(_config.headers, options.headers),
serializedBody: undefined as string | undefined,
};
if (opts.security) {
- await setAuthParams({
- ...opts,
- security: opts.security,
- });
+ await setAuthParams({ ...opts, security: opts.security });
}
if (opts.requestValidator) {
await opts.requestValidator(opts);
}
if (opts.body !== undefined && opts.bodySerializer) {
opts.serializedBody = opts.bodySerializer(opts.body) as string | undefined;
}
- // remove Content-Type header if body is empty to avoid sending invalid requests
if (opts.body === undefined || opts.serializedBody === '') {
opts.headers.delete('Content-Type');
}
- const resolvedOpts = opts as typeof opts & ResolvedRequestOptions<ThrowOnError, Url>;
- const url = buildUrl(resolvedOpts);
-
- return { opts: resolvedOpts, url };
- };
-
- // @ts-expect-error
+ return {
+ opts: opts as typeof opts & ResolvedRequestOptions<ThrowOnError, Url>,
+ };
+ };
+
const request: Client['request'] = async (options) => {
const throwOnError = options.throwOnError ?? _config.throwOnError;
let response: Response | undefined;
try {
- const { opts, url } = await beforeRequest(options);
+ const { opts } = await beforeRequest(options);
+ // request interceptors
for (const fn of interceptors.request.fns) {
- if (fn) {
- await fn(opts);
+ if (fn) await fn(opts);
- }
}
- // fetch must be assigned here, otherwise it would throw the error:
- // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
+ const url = buildUrl(opts);
+
const _fetch = opts.fetch!;
const requestInit: ReqInit = {
...opts,
body: getValidRequestBody(opts),
};
response = await _fetch(url, requestInit);
+ // response interceptors
for (const fn of interceptors.response.fns) {
- if (fn) {
- response = await fn(response, opts);
+ if (fn) response = await fn(response, opts);
- }
}
- const result = {
- response,
- };
+ const result = { response };
if (response.ok) {
const parseAs =
(opts.parseAs === 'auto'
? getParseAs(response.headers.get('Content-Type'))
: opts.parseAs) ?? 'json';
if (response.status === 204 || response.headers.get('Content-Length') === '0') {
- let emptyData: any;
+ let emptyData: any = {};
+
switch (parseAs) {
case 'arrayBuffer':
case 'blob':
case 'text':
emptyData = await response[parseAs]();
@@ -125,66 +116,50 @@
emptyData = new FormData();
break;
case 'stream':
emptyData = response.body;
break;
- case 'json':
- default:
- emptyData = {};
- break;
- }
- return {
- data: emptyData,
- ...result,
- };
+ }
+
+ return { data: emptyData, ...result };
}
let data: any;
+
switch (parseAs) {
case 'arrayBuffer':
case 'blob':
case 'formData':
case 'text':
data = await response[parseAs]();
break;
+
case 'json': {
- // Some servers return 200 with no Content-Length and empty body.
- // response.json() would throw; read as text and parse if non-empty.
const text = await response.text();
data = text ? JSON.parse(text) : {};
break;
}
+
case 'stream':
- return {
- d
|
|
Run test coverage:
packages/openapi-ts-tests/main/test/clients.test.ts#L201
Error: Snapshot `@hey-api/client-next > 'client with numeric base URL' 15` mismatched
- Expected
+ Received
@@ -45,78 +45,69 @@
headers: mergeHeaders(_config.headers, options.headers),
serializedBody: undefined as string | undefined,
};
if (opts.security) {
- await setAuthParams({
- ...opts,
- security: opts.security,
- });
+ await setAuthParams({ ...opts, security: opts.security });
}
if (opts.requestValidator) {
await opts.requestValidator(opts);
}
if (opts.body !== undefined && opts.bodySerializer) {
opts.serializedBody = opts.bodySerializer(opts.body) as string | undefined;
}
- // remove Content-Type header if body is empty to avoid sending invalid requests
if (opts.body === undefined || opts.serializedBody === '') {
opts.headers.delete('Content-Type');
}
- const resolvedOpts = opts as typeof opts & ResolvedRequestOptions<ThrowOnError, Url>;
- const url = buildUrl(resolvedOpts);
-
- return { opts: resolvedOpts, url };
- };
-
- // @ts-expect-error
+ return {
+ opts: opts as typeof opts & ResolvedRequestOptions<ThrowOnError, Url>,
+ };
+ };
+
const request: Client['request'] = async (options) => {
const throwOnError = options.throwOnError ?? _config.throwOnError;
let response: Response | undefined;
try {
- const { opts, url } = await beforeRequest(options);
+ const { opts } = await beforeRequest(options);
+ // request interceptors
for (const fn of interceptors.request.fns) {
- if (fn) {
- await fn(opts);
+ if (fn) await fn(opts);
- }
}
- // fetch must be assigned here, otherwise it would throw the error:
- // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
+ const url = buildUrl(opts);
+
const _fetch = opts.fetch!;
const requestInit: ReqInit = {
...opts,
body: getValidRequestBody(opts),
};
response = await _fetch(url, requestInit);
+ // response interceptors
for (const fn of interceptors.response.fns) {
- if (fn) {
- response = await fn(response, opts);
+ if (fn) response = await fn(response, opts);
- }
}
- const result = {
- response,
- };
+ const result = { response };
if (response.ok) {
const parseAs =
(opts.parseAs === 'auto'
? getParseAs(response.headers.get('Content-Type'))
: opts.parseAs) ?? 'json';
if (response.status === 204 || response.headers.get('Content-Length') === '0') {
- let emptyData: any;
+ let emptyData: any = {};
+
switch (parseAs) {
case 'arrayBuffer':
case 'blob':
case 'text':
emptyData = await response[parseAs]();
@@ -125,66 +116,50 @@
emptyData = new FormData();
break;
case 'stream':
emptyData = response.body;
break;
- case 'json':
- default:
- emptyData = {};
- break;
- }
- return {
- data: emptyData,
- ...result,
- };
+ }
+
+ return { data: emptyData, ...result };
}
let data: any;
+
switch (parseAs) {
case 'arrayBuffer':
case 'blob':
case 'formData':
case 'text':
data = await response[parseAs]();
break;
+
case 'json': {
- // Some servers return 200 with no Content-Length and empty body.
- // response.json() would throw; read as text and parse if non-empty.
const text = await response.text();
data = text ? JSON.parse(text) : {};
break;
}
+
case 'stream':
- return {
- data:
|
|
Run test coverage:
packages/openapi-ts-tests/main/test/clients.test.ts#L201
Error: Snapshot `@hey-api/client-next > 'client without base URL' 1` mismatched
- Expected
+ Received
@@ -45,78 +45,69 @@
headers: mergeHeaders(_config.headers, options.headers),
serializedBody: undefined as string | undefined,
};
if (opts.security) {
- await setAuthParams({
- ...opts,
- security: opts.security,
- });
+ await setAuthParams({ ...opts, security: opts.security });
}
if (opts.requestValidator) {
await opts.requestValidator(opts);
}
if (opts.body !== undefined && opts.bodySerializer) {
opts.serializedBody = opts.bodySerializer(opts.body) as string | undefined;
}
- // remove Content-Type header if body is empty to avoid sending invalid requests
if (opts.body === undefined || opts.serializedBody === '') {
opts.headers.delete('Content-Type');
}
- const resolvedOpts = opts as typeof opts & ResolvedRequestOptions<ThrowOnError, Url>;
- const url = buildUrl(resolvedOpts);
-
- return { opts: resolvedOpts, url };
- };
-
- // @ts-expect-error
+ return {
+ opts: opts as typeof opts & ResolvedRequestOptions<ThrowOnError, Url>,
+ };
+ };
+
const request: Client['request'] = async (options) => {
const throwOnError = options.throwOnError ?? _config.throwOnError;
let response: Response | undefined;
try {
- const { opts, url } = await beforeRequest(options);
+ const { opts } = await beforeRequest(options);
+ // request interceptors
for (const fn of interceptors.request.fns) {
- if (fn) {
- await fn(opts);
+ if (fn) await fn(opts);
- }
}
- // fetch must be assigned here, otherwise it would throw the error:
- // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
+ const url = buildUrl(opts);
+
const _fetch = opts.fetch!;
const requestInit: ReqInit = {
...opts,
body: getValidRequestBody(opts),
};
response = await _fetch(url, requestInit);
+ // response interceptors
for (const fn of interceptors.response.fns) {
- if (fn) {
- response = await fn(response, opts);
+ if (fn) response = await fn(response, opts);
- }
}
- const result = {
- response,
- };
+ const result = { response };
if (response.ok) {
const parseAs =
(opts.parseAs === 'auto'
? getParseAs(response.headers.get('Content-Type'))
: opts.parseAs) ?? 'json';
if (response.status === 204 || response.headers.get('Content-Length') === '0') {
- let emptyData: any;
+ let emptyData: any = {};
+
switch (parseAs) {
case 'arrayBuffer':
case 'blob':
case 'text':
emptyData = await response[parseAs]();
@@ -125,66 +116,50 @@
emptyData = new FormData();
break;
case 'stream':
emptyData = response.body;
break;
- case 'json':
- default:
- emptyData = {};
- break;
- }
- return {
- data: emptyData,
- ...result,
- };
+ }
+
+ return { data: emptyData, ...result };
}
let data: any;
+
switch (parseAs) {
case 'arrayBuffer':
case 'blob':
case 'formData':
case 'text':
data = await response[parseAs]();
break;
+
case 'json': {
- // Some servers return 200 with no Content-Length and empty body.
- // response.json() would throw; read as text and parse if non-empty.
const text = await response.text();
data = text ? JSON.parse(text) : {};
break;
}
+
case 'stream':
- return {
- data: respon
|
|
Run test coverage:
packages/openapi-ts-tests/main/test/clients.test.ts#L201
Error: Snapshot `@hey-api/client-next > 'SDK with required client option' 1` mismatched
- Expected
+ Received
@@ -45,78 +45,69 @@
headers: mergeHeaders(_config.headers, options.headers),
serializedBody: undefined as string | undefined,
};
if (opts.security) {
- await setAuthParams({
- ...opts,
- security: opts.security,
- });
+ await setAuthParams({ ...opts, security: opts.security });
}
if (opts.requestValidator) {
await opts.requestValidator(opts);
}
if (opts.body !== undefined && opts.bodySerializer) {
opts.serializedBody = opts.bodySerializer(opts.body) as string | undefined;
}
- // remove Content-Type header if body is empty to avoid sending invalid requests
if (opts.body === undefined || opts.serializedBody === '') {
opts.headers.delete('Content-Type');
}
- const resolvedOpts = opts as typeof opts & ResolvedRequestOptions<ThrowOnError, Url>;
- const url = buildUrl(resolvedOpts);
-
- return { opts: resolvedOpts, url };
- };
-
- // @ts-expect-error
+ return {
+ opts: opts as typeof opts & ResolvedRequestOptions<ThrowOnError, Url>,
+ };
+ };
+
const request: Client['request'] = async (options) => {
const throwOnError = options.throwOnError ?? _config.throwOnError;
let response: Response | undefined;
try {
- const { opts, url } = await beforeRequest(options);
+ const { opts } = await beforeRequest(options);
+ // request interceptors
for (const fn of interceptors.request.fns) {
- if (fn) {
- await fn(opts);
+ if (fn) await fn(opts);
- }
}
- // fetch must be assigned here, otherwise it would throw the error:
- // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
+ const url = buildUrl(opts);
+
const _fetch = opts.fetch!;
const requestInit: ReqInit = {
...opts,
body: getValidRequestBody(opts),
};
response = await _fetch(url, requestInit);
+ // response interceptors
for (const fn of interceptors.response.fns) {
- if (fn) {
- response = await fn(response, opts);
+ if (fn) response = await fn(response, opts);
- }
}
- const result = {
- response,
- };
+ const result = { response };
if (response.ok) {
const parseAs =
(opts.parseAs === 'auto'
? getParseAs(response.headers.get('Content-Type'))
: opts.parseAs) ?? 'json';
if (response.status === 204 || response.headers.get('Content-Length') === '0') {
- let emptyData: any;
+ let emptyData: any = {};
+
switch (parseAs) {
case 'arrayBuffer':
case 'blob':
case 'text':
emptyData = await response[parseAs]();
@@ -125,66 +116,50 @@
emptyData = new FormData();
break;
case 'stream':
emptyData = response.body;
break;
- case 'json':
- default:
- emptyData = {};
- break;
- }
- return {
- data: emptyData,
- ...result,
- };
+ }
+
+ return { data: emptyData, ...result };
}
let data: any;
+
switch (parseAs) {
case 'arrayBuffer':
case 'blob':
case 'formData':
case 'text':
data = await response[parseAs]();
break;
+
case 'json': {
- // Some servers return 200 with no Content-Length and empty body.
- // response.json() would throw; read as text and parse if non-empty.
const text = await response.text();
data = text ? JSON.parse(text) : {};
break;
}
+
case 'stream':
- return {
- data
|
|
Run test coverage:
packages/openapi-ts-tests/main/test/clients.test.ts#L201
Error: Snapshot `@hey-api/client-next > 'SDK with optional client option' 1` mismatched
- Expected
+ Received
@@ -45,78 +45,69 @@
headers: mergeHeaders(_config.headers, options.headers),
serializedBody: undefined as string | undefined,
};
if (opts.security) {
- await setAuthParams({
- ...opts,
- security: opts.security,
- });
+ await setAuthParams({ ...opts, security: opts.security });
}
if (opts.requestValidator) {
await opts.requestValidator(opts);
}
if (opts.body !== undefined && opts.bodySerializer) {
opts.serializedBody = opts.bodySerializer(opts.body) as string | undefined;
}
- // remove Content-Type header if body is empty to avoid sending invalid requests
if (opts.body === undefined || opts.serializedBody === '') {
opts.headers.delete('Content-Type');
}
- const resolvedOpts = opts as typeof opts & ResolvedRequestOptions<ThrowOnError, Url>;
- const url = buildUrl(resolvedOpts);
-
- return { opts: resolvedOpts, url };
- };
-
- // @ts-expect-error
+ return {
+ opts: opts as typeof opts & ResolvedRequestOptions<ThrowOnError, Url>,
+ };
+ };
+
const request: Client['request'] = async (options) => {
const throwOnError = options.throwOnError ?? _config.throwOnError;
let response: Response | undefined;
try {
- const { opts, url } = await beforeRequest(options);
+ const { opts } = await beforeRequest(options);
+ // request interceptors
for (const fn of interceptors.request.fns) {
- if (fn) {
- await fn(opts);
+ if (fn) await fn(opts);
- }
}
- // fetch must be assigned here, otherwise it would throw the error:
- // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
+ const url = buildUrl(opts);
+
const _fetch = opts.fetch!;
const requestInit: ReqInit = {
...opts,
body: getValidRequestBody(opts),
};
response = await _fetch(url, requestInit);
+ // response interceptors
for (const fn of interceptors.response.fns) {
- if (fn) {
- response = await fn(response, opts);
+ if (fn) response = await fn(response, opts);
- }
}
- const result = {
- response,
- };
+ const result = { response };
if (response.ok) {
const parseAs =
(opts.parseAs === 'auto'
? getParseAs(response.headers.get('Content-Type'))
: opts.parseAs) ?? 'json';
if (response.status === 204 || response.headers.get('Content-Length') === '0') {
- let emptyData: any;
+ let emptyData: any = {};
+
switch (parseAs) {
case 'arrayBuffer':
case 'blob':
case 'text':
emptyData = await response[parseAs]();
@@ -125,66 +116,50 @@
emptyData = new FormData();
break;
case 'stream':
emptyData = response.body;
break;
- case 'json':
- default:
- emptyData = {};
- break;
- }
- return {
- data: emptyData,
- ...result,
- };
+ }
+
+ return { data: emptyData, ...result };
}
let data: any;
+
switch (parseAs) {
case 'arrayBuffer':
case 'blob':
case 'formData':
case 'text':
data = await response[parseAs]();
break;
+
case 'json': {
- // Some servers return 200 with no Content-Length and empty body.
- // response.json() would throw; read as text and parse if non-empty.
const text = await response.text();
data = text ? JSON.parse(text) : {};
break;
}
+
case 'stream':
- return {
- data
|
|
Run test coverage:
packages/openapi-ts-tests/main/test/clients.test.ts#L201
Error: Snapshot `@hey-api/client-next > 'default output' 1` mismatched
- Expected
+ Received
@@ -45,78 +45,69 @@
headers: mergeHeaders(_config.headers, options.headers),
serializedBody: undefined as string | undefined,
};
if (opts.security) {
- await setAuthParams({
- ...opts,
- security: opts.security,
- });
+ await setAuthParams({ ...opts, security: opts.security });
}
if (opts.requestValidator) {
await opts.requestValidator(opts);
}
if (opts.body !== undefined && opts.bodySerializer) {
opts.serializedBody = opts.bodySerializer(opts.body) as string | undefined;
}
- // remove Content-Type header if body is empty to avoid sending invalid requests
if (opts.body === undefined || opts.serializedBody === '') {
opts.headers.delete('Content-Type');
}
- const resolvedOpts = opts as typeof opts & ResolvedRequestOptions<ThrowOnError, Url>;
- const url = buildUrl(resolvedOpts);
-
- return { opts: resolvedOpts, url };
- };
-
- // @ts-expect-error
+ return {
+ opts: opts as typeof opts & ResolvedRequestOptions<ThrowOnError, Url>,
+ };
+ };
+
const request: Client['request'] = async (options) => {
const throwOnError = options.throwOnError ?? _config.throwOnError;
let response: Response | undefined;
try {
- const { opts, url } = await beforeRequest(options);
+ const { opts } = await beforeRequest(options);
+ // request interceptors
for (const fn of interceptors.request.fns) {
- if (fn) {
- await fn(opts);
+ if (fn) await fn(opts);
- }
}
- // fetch must be assigned here, otherwise it would throw the error:
- // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
+ const url = buildUrl(opts);
+
const _fetch = opts.fetch!;
const requestInit: ReqInit = {
...opts,
body: getValidRequestBody(opts),
};
response = await _fetch(url, requestInit);
+ // response interceptors
for (const fn of interceptors.response.fns) {
- if (fn) {
- response = await fn(response, opts);
+ if (fn) response = await fn(response, opts);
- }
}
- const result = {
- response,
- };
+ const result = { response };
if (response.ok) {
const parseAs =
(opts.parseAs === 'auto'
? getParseAs(response.headers.get('Content-Type'))
: opts.parseAs) ?? 'json';
if (response.status === 204 || response.headers.get('Content-Length') === '0') {
- let emptyData: any;
+ let emptyData: any = {};
+
switch (parseAs) {
case 'arrayBuffer':
case 'blob':
case 'text':
emptyData = await response[parseAs]();
@@ -125,66 +116,50 @@
emptyData = new FormData();
break;
case 'stream':
emptyData = response.body;
break;
- case 'json':
- default:
- emptyData = {};
- break;
- }
- return {
- data: emptyData,
- ...result,
- };
+ }
+
+ return { data: emptyData, ...result };
}
let data: any;
+
switch (parseAs) {
case 'arrayBuffer':
case 'blob':
case 'formData':
case 'text':
data = await response[parseAs]();
break;
+
case 'json': {
- // Some servers return 200 with no Content-Length and empty body.
- // response.json() would throw; read as text and parse if non-empty.
const text = await response.text();
data = text ? JSON.parse(text) : {};
break;
}
+
case 'stream':
- return {
- data: response.body,
|
|
Run test coverage:
packages/openapi-ts-tests/main/test/3.1.x.test.ts#L1028
Error: Snapshot `OpenAPI 3.1.x > 'client with SSE (Next.js)' 1` mismatched
- Expected
+ Received
@@ -45,78 +45,69 @@
headers: mergeHeaders(_config.headers, options.headers),
serializedBody: undefined as string | undefined,
};
if (opts.security) {
- await setAuthParams({
- ...opts,
- security: opts.security,
- });
+ await setAuthParams({ ...opts, security: opts.security });
}
if (opts.requestValidator) {
await opts.requestValidator(opts);
}
if (opts.body !== undefined && opts.bodySerializer) {
opts.serializedBody = opts.bodySerializer(opts.body) as string | undefined;
}
- // remove Content-Type header if body is empty to avoid sending invalid requests
if (opts.body === undefined || opts.serializedBody === '') {
opts.headers.delete('Content-Type');
}
- const resolvedOpts = opts as typeof opts & ResolvedRequestOptions<ThrowOnError, Url>;
- const url = buildUrl(resolvedOpts);
-
- return { opts: resolvedOpts, url };
- };
-
- // @ts-expect-error
+ return {
+ opts: opts as typeof opts & ResolvedRequestOptions<ThrowOnError, Url>,
+ };
+ };
+
const request: Client['request'] = async (options) => {
const throwOnError = options.throwOnError ?? _config.throwOnError;
let response: Response | undefined;
try {
- const { opts, url } = await beforeRequest(options);
+ const { opts } = await beforeRequest(options);
+ // request interceptors
for (const fn of interceptors.request.fns) {
- if (fn) {
- await fn(opts);
+ if (fn) await fn(opts);
- }
}
- // fetch must be assigned here, otherwise it would throw the error:
- // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
+ const url = buildUrl(opts);
+
const _fetch = opts.fetch!;
const requestInit: ReqInit = {
...opts,
body: getValidRequestBody(opts),
};
response = await _fetch(url, requestInit);
+ // response interceptors
for (const fn of interceptors.response.fns) {
- if (fn) {
- response = await fn(response, opts);
+ if (fn) response = await fn(response, opts);
- }
}
- const result = {
- response,
- };
+ const result = { response };
if (response.ok) {
const parseAs =
(opts.parseAs === 'auto'
? getParseAs(response.headers.get('Content-Type'))
: opts.parseAs) ?? 'json';
if (response.status === 204 || response.headers.get('Content-Length') === '0') {
- let emptyData: any;
+ let emptyData: any = {};
+
switch (parseAs) {
case 'arrayBuffer':
case 'blob':
case 'text':
emptyData = await response[parseAs]();
@@ -125,66 +116,50 @@
emptyData = new FormData();
break;
case 'stream':
emptyData = response.body;
break;
- case 'json':
- default:
- emptyData = {};
- break;
- }
- return {
- data: emptyData,
- ...result,
- };
+ }
+
+ return { data: emptyData, ...result };
}
let data: any;
+
switch (parseAs) {
case 'arrayBuffer':
case 'blob':
case 'formData':
case 'text':
data = await response[parseAs]();
break;
+
case 'json': {
- // Some servers return 200 with no Content-Length and empty body.
- // response.json() would throw; read as text and parse if non-empty.
const text = await response.text();
data = text ? JSON.parse(text) : {};
break;
}
+
case 'stream':
- return {
- data: response.bo
|
background
wait
wait-all
cancel
Loading