@drttix/drt-sdk 0.6.5 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/azure-pipelines.yml +15 -6
  2. package/demo/default.html +2 -1
  3. package/demo/test.html +529 -102
  4. package/demo/with-base.html +10 -8
  5. package/dist/bundle/drt-sdk.js +1 -0
  6. package/dist/cjs/index.d.ts +5 -0
  7. package/dist/cjs/index.js +5 -0
  8. package/dist/cjs/src/generated/portal/core/OpenAPI.js +1 -1
  9. package/dist/cjs/src/generated/portal/core/request.js +3 -1
  10. package/dist/cjs/src/generated/portal/services/AccountService.d.ts +12 -2
  11. package/dist/cjs/src/generated/portal/services/AccountService.js +26 -2
  12. package/dist/cjs/src/generated/portal/services/AuthService.d.ts +2 -1
  13. package/dist/cjs/src/generated/portal/services/AuthService.js +5 -1
  14. package/dist/cjs/src/generated/portal/services/FeaturesBlockedSeatsService.d.ts +10 -7
  15. package/dist/cjs/src/generated/portal/services/FeaturesBlockedSeatsService.js +19 -7
  16. package/dist/cjs/src/generated/portal/services/OrderLookupService.d.ts +4 -3
  17. package/dist/cjs/src/generated/portal/services/OrderLookupService.js +7 -3
  18. package/dist/cjs/src/generated/scanner/core/request.d.ts +7 -10
  19. package/dist/cjs/src/generated/scanner/core/request.js +56 -37
  20. package/dist/cjs/src/generated/shopper/core/request.js +3 -1
  21. package/dist/cjs/src/scripts/build-all.js +9 -1
  22. package/dist/esm/index.d.ts +5 -0
  23. package/dist/esm/index.js +5 -0
  24. package/dist/esm/src/generated/portal/core/OpenAPI.js +1 -1
  25. package/dist/esm/src/generated/portal/core/request.js +3 -1
  26. package/dist/esm/src/generated/portal/services/AccountService.d.ts +12 -2
  27. package/dist/esm/src/generated/portal/services/AccountService.js +26 -2
  28. package/dist/esm/src/generated/portal/services/AuthService.d.ts +2 -1
  29. package/dist/esm/src/generated/portal/services/AuthService.js +5 -1
  30. package/dist/esm/src/generated/portal/services/FeaturesBlockedSeatsService.d.ts +10 -7
  31. package/dist/esm/src/generated/portal/services/FeaturesBlockedSeatsService.js +19 -7
  32. package/dist/esm/src/generated/portal/services/OrderLookupService.d.ts +4 -3
  33. package/dist/esm/src/generated/portal/services/OrderLookupService.js +7 -3
  34. package/dist/esm/src/generated/scanner/core/request.d.ts +7 -10
  35. package/dist/esm/src/generated/scanner/core/request.js +58 -39
  36. package/dist/esm/src/generated/shopper/core/request.js +3 -1
  37. package/dist/esm/src/scripts/build-all.js +9 -1
  38. package/index.ts +5 -0
  39. package/package.json +3 -1
  40. package/src/custom/custom-request.txt +7 -2
  41. package/src/generated/portal/core/OpenAPI.ts +1 -1
  42. package/src/generated/portal/core/request.ts +7 -2
  43. package/src/generated/portal/services/AccountService.ts +30 -1
  44. package/src/generated/portal/services/AuthService.ts +7 -1
  45. package/src/generated/portal/services/FeaturesBlockedSeatsService.ts +23 -6
  46. package/src/generated/portal/services/OrderLookupService.ts +7 -2
  47. package/src/generated/scanner/core/request.ts +331 -266
  48. package/src/generated/shopper/core/request.ts +7 -2
  49. package/src/scripts/build-all.ts +14 -1
@@ -2,321 +2,386 @@
2
2
  /* istanbul ignore file */
3
3
  /* tslint:disable */
4
4
  /* eslint-disable */
5
- import { ApiError } from './ApiError';
6
- import type { ApiRequestOptions } from './ApiRequestOptions';
7
- import type { ApiResult } from './ApiResult';
8
- import { CancelablePromise } from './CancelablePromise';
9
- import type { OnCancel } from './CancelablePromise';
10
- import type { OpenAPIConfig } from './OpenAPI';
11
-
12
- export const isDefined = <T>(value: T | null | undefined): value is Exclude<T, null | undefined> => {
13
- return value !== undefined && value !== null;
5
+ import { ApiError } from "./ApiError";
6
+ import type { ApiRequestOptions } from "./ApiRequestOptions";
7
+ import type { ApiResult } from "./ApiResult";
8
+ import { CancelablePromise } from "./CancelablePromise";
9
+ import type { OnCancel } from "./CancelablePromise";
10
+ import type { OpenAPIConfig } from "./OpenAPI";
11
+
12
+ export const isDefined = <T>(
13
+ value: T | null | undefined
14
+ ): value is Exclude<T, null | undefined> => {
15
+ return value !== undefined && value !== null;
14
16
  };
15
17
 
16
18
  export const isString = (value: any): value is string => {
17
- return typeof value === 'string';
19
+ return typeof value === "string";
18
20
  };
19
21
 
20
22
  export const isStringWithValue = (value: any): value is string => {
21
- return isString(value) && value !== '';
23
+ return isString(value) && value !== "";
22
24
  };
23
25
 
24
26
  export const isBlob = (value: any): value is Blob => {
25
- return (
26
- typeof value === 'object' &&
27
- typeof value.type === 'string' &&
28
- typeof value.stream === 'function' &&
29
- typeof value.arrayBuffer === 'function' &&
30
- typeof value.constructor === 'function' &&
31
- typeof value.constructor.name === 'string' &&
32
- /^(Blob|File)$/.test(value.constructor.name) &&
33
- /^(Blob|File)$/.test(value[Symbol.toStringTag])
34
- );
27
+ return (
28
+ typeof value === "object" &&
29
+ typeof value.type === "string" &&
30
+ typeof value.stream === "function" &&
31
+ typeof value.arrayBuffer === "function" &&
32
+ typeof value.constructor === "function" &&
33
+ typeof value.constructor.name === "string" &&
34
+ /^(Blob|File)$/.test(value.constructor.name) &&
35
+ /^(Blob|File)$/.test(value[Symbol.toStringTag])
36
+ );
35
37
  };
36
38
 
37
39
  export const isFormData = (value: any): value is FormData => {
38
- return value instanceof FormData;
40
+ return value instanceof FormData;
39
41
  };
40
42
 
41
43
  export const base64 = (str: string): string => {
42
- try {
43
- return btoa(str);
44
- } catch (err) {
45
- // @ts-ignore
46
- return Buffer.from(str).toString('base64');
47
- }
44
+ try {
45
+ return btoa(str);
46
+ } catch (err) {
47
+ // @ts-ignore
48
+ return Buffer.from(str).toString("base64");
49
+ }
48
50
  };
49
51
 
50
52
  export const getQueryString = (params: Record<string, any>): string => {
51
- const qs: string[] = [];
52
-
53
- const append = (key: string, value: any) => {
54
- qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
55
- };
56
-
57
- const process = (key: string, value: any) => {
58
- if (isDefined(value)) {
59
- if (Array.isArray(value)) {
60
- value.forEach(v => {
61
- process(key, v);
62
- });
63
- } else if (typeof value === 'object') {
64
- Object.entries(value).forEach(([k, v]) => {
65
- process(`${key}[${k}]`, v);
66
- });
67
- } else {
68
- append(key, value);
69
- }
70
- }
71
- };
72
-
73
- Object.entries(params).forEach(([key, value]) => {
74
- process(key, value);
75
- });
76
-
77
- if (qs.length > 0) {
78
- return `?${qs.join('&')}`;
79
- }
80
-
81
- return '';
53
+ const qs: string[] = [];
54
+
55
+ const append = (key: string, value: any) => {
56
+ qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
57
+ };
58
+
59
+ const process = (key: string, value: any) => {
60
+ if (isDefined(value)) {
61
+ if (Array.isArray(value)) {
62
+ value.forEach((v) => {
63
+ process(key, v);
64
+ });
65
+ } else if (typeof value === "object") {
66
+ Object.entries(value).forEach(([k, v]) => {
67
+ process(`${key}[${k}]`, v);
68
+ });
69
+ } else {
70
+ append(key, value);
71
+ }
72
+ }
73
+ };
74
+
75
+ Object.entries(params).forEach(([key, value]) => {
76
+ process(key, value);
77
+ });
78
+
79
+ if (qs.length > 0) {
80
+ return `?${qs.join("&")}`;
81
+ }
82
+
83
+ return "";
82
84
  };
83
85
 
84
86
  const getUrl = (config: OpenAPIConfig, options: ApiRequestOptions): string => {
85
- const encoder = config.ENCODE_PATH || encodeURI;
86
-
87
- const path = options.url
88
- .replace('{api-version}', config.VERSION)
89
- .replace(/{(.*?)}/g, (substring: string, group: string) => {
90
- if (options.path?.hasOwnProperty(group)) {
91
- return encoder(String(options.path[group]));
92
- }
93
- return substring;
94
- });
95
-
96
- const url = `${config.BASE}${path}`;
97
- if (options.query) {
98
- return `${url}${getQueryString(options.query)}`;
99
- }
100
- return url;
87
+ const encoder = config.ENCODE_PATH || encodeURI;
88
+
89
+ const path = options.url
90
+ .replace("{api-version}", config.VERSION)
91
+ .replace(/{(.*?)}/g, (substring: string, group: string) => {
92
+ if (options.path?.hasOwnProperty(group)) {
93
+ return encoder(String(options.path[group]));
94
+ }
95
+ return substring;
96
+ });
97
+
98
+ const url = `${config.BASE}${path}`;
99
+ if (options.query) {
100
+ return `${url}${getQueryString(options.query)}`;
101
+ }
102
+ return url;
101
103
  };
102
104
 
103
- export const getFormData = (options: ApiRequestOptions): FormData | undefined => {
104
- if (options.formData) {
105
- const formData = new FormData();
106
-
107
- const process = (key: string, value: any) => {
108
- if (isString(value) || isBlob(value)) {
109
- formData.append(key, value);
110
- } else {
111
- formData.append(key, JSON.stringify(value));
112
- }
113
- };
114
-
115
- Object.entries(options.formData)
116
- .filter(([_, value]) => isDefined(value))
117
- .forEach(([key, value]) => {
118
- if (Array.isArray(value)) {
119
- value.forEach(v => process(key, v));
120
- } else {
121
- process(key, value);
122
- }
123
- });
124
-
125
- return formData;
126
- }
127
- return undefined;
105
+ export const getFormData = (
106
+ options: ApiRequestOptions
107
+ ): FormData | undefined => {
108
+ if (options.formData) {
109
+ const formData = new FormData();
110
+
111
+ const process = (key: string, value: any) => {
112
+ if (isString(value) || isBlob(value)) {
113
+ formData.append(key, value);
114
+ } else {
115
+ formData.append(key, JSON.stringify(value));
116
+ }
117
+ };
118
+
119
+ Object.entries(options.formData)
120
+ .filter(([_, value]) => isDefined(value))
121
+ .forEach(([key, value]) => {
122
+ if (Array.isArray(value)) {
123
+ value.forEach((v) => process(key, v));
124
+ } else {
125
+ process(key, value);
126
+ }
127
+ });
128
+
129
+ return formData;
130
+ }
131
+ return undefined;
128
132
  };
129
133
 
130
134
  type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
131
135
 
132
- export const resolve = async <T>(options: ApiRequestOptions, resolver?: T | Resolver<T>): Promise<T | undefined> => {
133
- if (typeof resolver === 'function') {
134
- return (resolver as Resolver<T>)(options);
135
- }
136
- return resolver;
136
+ export const resolve = async <T>(
137
+ options: ApiRequestOptions,
138
+ resolver?: T | Resolver<T>
139
+ ): Promise<T | undefined> => {
140
+ if (typeof resolver === "function") {
141
+ return (resolver as Resolver<T>)(options);
142
+ }
143
+ return resolver;
137
144
  };
138
145
 
139
- export const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions): Promise<Headers> => {
140
- const [token, username, password, additionalHeaders] = await Promise.all([
141
- resolve(options, config.TOKEN),
142
- resolve(options, config.USERNAME),
143
- resolve(options, config.PASSWORD),
144
- resolve(options, config.HEADERS),
145
- ]);
146
-
147
- const headers = Object.entries({
148
- Accept: 'application/json',
149
- ...additionalHeaders,
150
- ...options.headers,
151
- })
152
- .filter(([_, value]) => isDefined(value))
153
- .reduce((headers, [key, value]) => ({
154
- ...headers,
155
- [key]: String(value),
156
- }), {} as Record<string, string>);
157
-
158
- if (isStringWithValue(token)) {
159
- headers['Authorization'] = `Bearer ${token}`;
160
- }
161
-
162
- if (isStringWithValue(username) && isStringWithValue(password)) {
163
- const credentials = base64(`${username}:${password}`);
164
- headers['Authorization'] = `Basic ${credentials}`;
165
- }
166
-
167
- if (options.body !== undefined) {
168
- if (options.mediaType) {
169
- headers['Content-Type'] = options.mediaType;
170
- } else if (isBlob(options.body)) {
171
- headers['Content-Type'] = options.body.type || 'application/octet-stream';
172
- } else if (isString(options.body)) {
173
- headers['Content-Type'] = 'text/plain';
174
- } else if (!isFormData(options.body)) {
175
- headers['Content-Type'] = 'application/json';
176
- }
177
- }
178
-
179
- return new Headers(headers);
146
+ export const getHeaders = async (
147
+ config: OpenAPIConfig,
148
+ options: ApiRequestOptions
149
+ ): Promise<Headers> => {
150
+ const [token, username, password, additionalHeaders] = await Promise.all([
151
+ resolve(options, config.TOKEN),
152
+ resolve(options, config.USERNAME),
153
+ resolve(options, config.PASSWORD),
154
+ resolve(options, config.HEADERS),
155
+ ]);
156
+
157
+ // Filter out undefined/null values from options.headers first
158
+ const optionsHeaders = Object.fromEntries(
159
+ Object.entries(options.headers || {}).filter(([_, value]) => isDefined(value))
160
+ );
161
+
162
+ const headers = Object.entries({
163
+ Accept: "application/json",
164
+ ...optionsHeaders,
165
+ ...additionalHeaders, // config.HEADERS takes precedence when set (for DRT.init())
166
+ })
167
+ .filter(([_, value]) => isDefined(value))
168
+ .reduce(
169
+ (headers, [key, value]) => ({
170
+ ...headers,
171
+ [key]: String(value),
172
+ }),
173
+ {} as Record<string, string>
174
+ );
175
+
176
+ if (isStringWithValue(token)) {
177
+ headers["Authorization"] = `Bearer ${token}`;
178
+ }
179
+
180
+ if (isStringWithValue(username) && isStringWithValue(password)) {
181
+ const credentials = base64(`${username}:${password}`);
182
+ headers["Authorization"] = `Basic ${credentials}`;
183
+ }
184
+
185
+ if (options.body !== undefined) {
186
+ if (options.mediaType) {
187
+ headers["Content-Type"] = options.mediaType;
188
+ } else if (isBlob(options.body)) {
189
+ headers["Content-Type"] = options.body.type || "application/octet-stream";
190
+ } else if (isString(options.body)) {
191
+ headers["Content-Type"] = "text/plain";
192
+ } else if (!isFormData(options.body)) {
193
+ headers["Content-Type"] = "application/json";
194
+ }
195
+ }
196
+
197
+ return new Headers(headers);
180
198
  };
181
199
 
182
200
  export const getRequestBody = (options: ApiRequestOptions): any => {
183
- if (options.body !== undefined) {
184
- if (options.mediaType?.includes('/json')) {
185
- return JSON.stringify(options.body)
186
- } else if (isString(options.body) || isBlob(options.body) || isFormData(options.body)) {
187
- return options.body;
188
- } else {
189
- return JSON.stringify(options.body);
190
- }
191
- }
192
- return undefined;
201
+ if (options.body !== undefined) {
202
+ if (options.mediaType?.includes("/json")) {
203
+ return JSON.stringify(options.body);
204
+ } else if (
205
+ isString(options.body) ||
206
+ isBlob(options.body) ||
207
+ isFormData(options.body)
208
+ ) {
209
+ return options.body;
210
+ } else {
211
+ return JSON.stringify(options.body);
212
+ }
213
+ }
214
+ return undefined;
193
215
  };
194
216
 
195
217
  export const sendRequest = async (
196
- config: OpenAPIConfig,
197
- options: ApiRequestOptions,
198
- url: string,
199
- body: any,
200
- formData: FormData | undefined,
201
- headers: Headers,
202
- onCancel: OnCancel
218
+ config: OpenAPIConfig,
219
+ options: ApiRequestOptions,
220
+ url: string,
221
+ body: any,
222
+ formData: FormData | undefined,
223
+ headers: Headers,
224
+ onCancel: OnCancel
203
225
  ): Promise<Response> => {
204
- const controller = new AbortController();
226
+ const controller = new AbortController();
205
227
 
206
- const request: RequestInit = {
207
- headers,
208
- body: body ?? formData,
209
- method: options.method,
210
- signal: controller.signal,
211
- };
228
+ const request: RequestInit = {
229
+ headers,
230
+ body: body ?? formData,
231
+ method: options.method,
232
+ signal: controller.signal,
233
+ };
212
234
 
213
- if (config.WITH_CREDENTIALS) {
214
- request.credentials = config.CREDENTIALS;
215
- }
235
+ if (config.WITH_CREDENTIALS) {
236
+ request.credentials = config.CREDENTIALS;
237
+ }
216
238
 
217
- onCancel(() => controller.abort());
239
+ onCancel(() => controller.abort());
218
240
 
219
- return await fetch(url, request);
241
+ return await fetch(url, request);
220
242
  };
221
243
 
222
- export const getResponseHeader = (response: Response, responseHeader?: string): string | undefined => {
223
- if (responseHeader) {
224
- const content = response.headers.get(responseHeader);
225
- if (isString(content)) {
226
- return content;
227
- }
228
- }
229
- return undefined;
244
+ export const getResponseHeader = (
245
+ response: Response,
246
+ responseHeader?: string
247
+ ): string | undefined => {
248
+ if (responseHeader) {
249
+ const content = response.headers.get(responseHeader);
250
+ if (isString(content)) {
251
+ return content;
252
+ }
253
+ }
254
+ return undefined;
230
255
  };
231
256
 
232
257
  export const getResponseBody = async (response: Response): Promise<any> => {
233
- if (response.status !== 204) {
234
- try {
235
- const contentType = response.headers.get('Content-Type');
236
- if (contentType) {
237
- const jsonTypes = ['application/json', 'application/problem+json']
238
- const isJSON = jsonTypes.some(type => contentType.toLowerCase().startsWith(type));
239
- if (isJSON) {
240
- return await response.json();
241
- } else {
242
- return await response.text();
243
- }
244
- }
245
- } catch (error) {
246
- console.error(error);
247
- }
248
- }
249
- return undefined;
258
+ if (response.status !== 204) {
259
+ try {
260
+ const contentType = response.headers.get("Content-Type");
261
+ if (contentType) {
262
+ const jsonTypes = ["application/json", "application/problem+json"];
263
+ const isJSON = jsonTypes.some((type) =>
264
+ contentType.toLowerCase().startsWith(type)
265
+ );
266
+ if (isJSON) {
267
+ return await response.json();
268
+ } else {
269
+ return await response.text();
270
+ }
271
+ }
272
+ } catch (error) {
273
+ console.error(error);
274
+ }
275
+ }
276
+ return undefined;
250
277
  };
251
278
 
252
- export const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => {
253
- const errors: Record<number, string> = {
254
- 400: 'Bad Request',
255
- 401: 'Unauthorized',
256
- 403: 'Forbidden',
257
- 404: 'Not Found',
258
- 500: 'Internal Server Error',
259
- 502: 'Bad Gateway',
260
- 503: 'Service Unavailable',
261
- ...options.errors,
262
- }
263
-
264
- const error = errors[result.status];
265
- if (error) {
266
- throw new ApiError(options, result, error);
267
- }
268
-
269
- if (!result.ok) {
270
- const errorStatus = result.status ?? 'unknown';
271
- const errorStatusText = result.statusText ?? 'unknown';
272
- const errorBody = (() => {
273
- try {
274
- return JSON.stringify(result.body, null, 2);
275
- } catch (e) {
276
- return undefined;
277
- }
278
- })();
279
-
280
- throw new ApiError(options, result,
281
- `Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody}`
282
- );
283
- }
279
+ export const catchErrorCodes = (
280
+ options: ApiRequestOptions,
281
+ result: ApiResult
282
+ ): void => {
283
+ const errors: Record<number, string> = {
284
+ 400: "Bad Request",
285
+ 401: "Unauthorized",
286
+ 403: "Forbidden",
287
+ 404: "Not Found",
288
+ 500: "Internal Server Error",
289
+ 502: "Bad Gateway",
290
+ 503: "Service Unavailable",
291
+ ...options.errors,
292
+ };
293
+
294
+ const error = errors[result.status];
295
+ if (error) {
296
+ throw new ApiError(options, result, error);
297
+ }
298
+
299
+ if (!result.ok) {
300
+ const errorStatus = result.status ?? "unknown";
301
+ const errorStatusText = result.statusText ?? "unknown";
302
+ const errorBody = (() => {
303
+ try {
304
+ return JSON.stringify(result.body, null, 2);
305
+ } catch (e) {
306
+ return undefined;
307
+ }
308
+ })();
309
+
310
+ throw new ApiError(
311
+ options,
312
+ result,
313
+ `Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody}`
314
+ );
315
+ }
284
316
  };
285
317
 
318
+ let globalCookieHeader: string | undefined;
319
+
286
320
  /**
287
- * Request method
288
- * @param config The OpenAPI configuration object
289
- * @param options The request options from the service
290
- * @returns CancelablePromise<T>
291
- * @throws ApiError
321
+ * Wraps sendRequest to capture cookies on login
322
+ * and attach cookies on other requests
292
323
  */
293
- export const request = <T>(config: OpenAPIConfig, options: ApiRequestOptions): CancelablePromise<T> => {
294
- return new CancelablePromise(async (resolve, reject, onCancel) => {
295
- try {
296
- const url = getUrl(config, options);
297
- const formData = getFormData(options);
298
- const body = getRequestBody(options);
299
- const headers = await getHeaders(config, options);
300
-
301
- if (!onCancel.isCancelled) {
302
- const response = await sendRequest(config, options, url, body, formData, headers, onCancel);
303
- const responseBody = await getResponseBody(response);
304
- const responseHeader = getResponseHeader(response, options.responseHeader);
305
-
306
- const result: ApiResult = {
307
- url,
308
- ok: response.ok,
309
- status: response.status,
310
- statusText: response.statusText,
311
- body: responseHeader ?? responseBody,
312
- };
313
-
314
- catchErrorCodes(options, result);
315
-
316
- resolve(result.body);
317
- }
318
- } catch (error) {
319
- reject(error);
320
- }
321
- });
324
+ export const request = <T>(
325
+ config: OpenAPIConfig,
326
+ options: ApiRequestOptions
327
+ ): CancelablePromise<T> => {
328
+ return new CancelablePromise(async (resolve, reject, onCancel) => {
329
+ try {
330
+ const url = getUrl(config, options);
331
+ const formData = getFormData(options);
332
+ const body = getRequestBody(options);
333
+
334
+ // Before making headers, possibly attach cookie if we have it
335
+ const baseHeaders = await getHeaders(config, options);
336
+ // We will build combined headers
337
+ const headerObj: Record<string, string> = {};
338
+ baseHeaders.forEach((value, key) => {
339
+ headerObj[key] = value;
340
+ });
341
+ if (globalCookieHeader) {
342
+ // Attach stored cookie
343
+ headerObj["Cookie"] = globalCookieHeader;
344
+ }
345
+ const headers = new Headers(headerObj);
346
+
347
+ if (!onCancel.isCancelled) {
348
+ const response = await sendRequest(
349
+ config,
350
+ options,
351
+ url,
352
+ body,
353
+ formData,
354
+ headers,
355
+ onCancel
356
+ );
357
+
358
+ // Capture Set-Cookie if present
359
+ const setCookie = response.headers.get("set-cookie");
360
+ if (setCookie) {
361
+ // Overwrite or append as needed
362
+ globalCookieHeader = setCookie;
363
+ }
364
+
365
+ const responseBody = await getResponseBody(response);
366
+ const responseHeader = getResponseHeader(
367
+ response,
368
+ options.responseHeader
369
+ );
370
+
371
+ const result: ApiResult = {
372
+ url,
373
+ ok: response.ok,
374
+ status: response.status,
375
+ statusText: response.statusText,
376
+ body: responseHeader ?? responseBody,
377
+ };
378
+
379
+ catchErrorCodes(options, result);
380
+
381
+ resolve(result.body as T);
382
+ }
383
+ } catch (error) {
384
+ reject(error);
385
+ }
386
+ });
322
387
  };