@drttix/drt-sdk 0.2.0 → 0.2.1

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