@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.
- package/dist/cjs/src/generated/portal/core/request.d.ts +7 -10
- package/dist/cjs/src/generated/portal/core/request.js +54 -37
- package/dist/cjs/src/scripts/build-all.js +4 -1
- package/dist/esm/src/generated/portal/core/request.d.ts +7 -10
- package/dist/esm/src/generated/portal/core/request.js +56 -39
- package/dist/esm/src/scripts/build-all.js +4 -1
- package/package.json +25 -25
- package/src/generated/portal/core/request.ts +326 -266
- package/src/scripts/build-all.ts +6 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { ApiRequestOptions } from
|
|
2
|
-
import type { ApiResult } from
|
|
3
|
-
import { CancelablePromise } from
|
|
4
|
-
import type { OnCancel } from
|
|
5
|
-
import type { OpenAPIConfig } from
|
|
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
|
-
*
|
|
24
|
-
*
|
|
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 ===
|
|
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 ===
|
|
24
|
-
typeof value.type ===
|
|
25
|
-
typeof value.stream ===
|
|
26
|
-
typeof value.arrayBuffer ===
|
|
27
|
-
typeof value.constructor ===
|
|
28
|
-
typeof value.constructor.name ===
|
|
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(
|
|
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 ===
|
|
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(
|
|
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 ===
|
|
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:
|
|
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[
|
|
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[
|
|
143
|
+
headers["Authorization"] = `Basic ${credentials}`;
|
|
144
144
|
}
|
|
145
145
|
if (options.body !== undefined) {
|
|
146
146
|
if (options.mediaType) {
|
|
147
|
-
headers[
|
|
147
|
+
headers["Content-Type"] = options.mediaType;
|
|
148
148
|
}
|
|
149
149
|
else if ((0, exports.isBlob)(options.body)) {
|
|
150
|
-
headers[
|
|
150
|
+
headers["Content-Type"] = options.body.type || "application/octet-stream";
|
|
151
151
|
}
|
|
152
152
|
else if ((0, exports.isString)(options.body)) {
|
|
153
|
-
headers[
|
|
153
|
+
headers["Content-Type"] = "text/plain";
|
|
154
154
|
}
|
|
155
155
|
else if (!(0, exports.isFormData)(options.body)) {
|
|
156
|
-
headers[
|
|
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(
|
|
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) ||
|
|
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(
|
|
208
|
+
const contentType = response.headers.get("Content-Type");
|
|
207
209
|
if (contentType) {
|
|
208
|
-
const jsonTypes = [
|
|
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:
|
|
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 :
|
|
234
|
-
const errorStatusText = (_b = result.statusText) !== null && _b !== void 0 ? _b :
|
|
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
|
-
*
|
|
249
|
-
*
|
|
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
|
-
|
|
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
|
|
2
|
-
import type { ApiResult } from
|
|
3
|
-
import { CancelablePromise } from
|
|
4
|
-
import type { OnCancel } from
|
|
5
|
-
import type { OpenAPIConfig } from
|
|
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
|
-
*
|
|
24
|
-
*
|
|
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
|
|
6
|
-
import { CancelablePromise } from
|
|
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 ===
|
|
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 ===
|
|
18
|
-
typeof value.type ===
|
|
19
|
-
typeof value.stream ===
|
|
20
|
-
typeof value.arrayBuffer ===
|
|
21
|
-
typeof value.constructor ===
|
|
22
|
-
typeof value.constructor.name ===
|
|
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(
|
|
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 ===
|
|
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(
|
|
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 ===
|
|
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:
|
|
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[
|
|
127
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
128
128
|
}
|
|
129
129
|
if (isStringWithValue(username) && isStringWithValue(password)) {
|
|
130
130
|
const credentials = base64(`${username}:${password}`);
|
|
131
|
-
headers[
|
|
131
|
+
headers["Authorization"] = `Basic ${credentials}`;
|
|
132
132
|
}
|
|
133
133
|
if (options.body !== undefined) {
|
|
134
134
|
if (options.mediaType) {
|
|
135
|
-
headers[
|
|
135
|
+
headers["Content-Type"] = options.mediaType;
|
|
136
136
|
}
|
|
137
137
|
else if (isBlob(options.body)) {
|
|
138
|
-
headers[
|
|
138
|
+
headers["Content-Type"] = options.body.type || "application/octet-stream";
|
|
139
139
|
}
|
|
140
140
|
else if (isString(options.body)) {
|
|
141
|
-
headers[
|
|
141
|
+
headers["Content-Type"] = "text/plain";
|
|
142
142
|
}
|
|
143
143
|
else if (!isFormData(options.body)) {
|
|
144
|
-
headers[
|
|
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(
|
|
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) ||
|
|
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(
|
|
192
|
+
const contentType = response.headers.get("Content-Type");
|
|
191
193
|
if (contentType) {
|
|
192
|
-
const jsonTypes = [
|
|
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:
|
|
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 :
|
|
217
|
-
const errorStatusText = (_b = result.statusText) !== null && _b !== void 0 ? _b :
|
|
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
|
-
*
|
|
231
|
-
*
|
|
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
|
-
|
|
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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
|
6
|
-
import type { ApiRequestOptions } from
|
|
7
|
-
import type { ApiResult } from
|
|
8
|
-
import { CancelablePromise } from
|
|
9
|
-
import type { OnCancel } from
|
|
10
|
-
import type { OpenAPIConfig } from
|
|
11
|
-
|
|
12
|
-
export const isDefined = <T>(
|
|
13
|
-
|
|
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
|
-
|
|
19
|
+
return typeof value === "string";
|
|
18
20
|
};
|
|
19
21
|
|
|
20
22
|
export const isStringWithValue = (value: any): value is string => {
|
|
21
|
-
|
|
23
|
+
return isString(value) && value !== "";
|
|
22
24
|
};
|
|
23
25
|
|
|
24
26
|
export const isBlob = (value: any): value is Blob => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
40
|
+
return value instanceof FormData;
|
|
39
41
|
};
|
|
40
42
|
|
|
41
43
|
export const base64 = (str: string): string => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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 = (
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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>(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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 (
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
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
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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
|
-
|
|
221
|
+
const controller = new AbortController();
|
|
205
222
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
223
|
+
const request: RequestInit = {
|
|
224
|
+
headers,
|
|
225
|
+
body: body ?? formData,
|
|
226
|
+
method: options.method,
|
|
227
|
+
signal: controller.signal,
|
|
228
|
+
};
|
|
212
229
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
230
|
+
if (config.WITH_CREDENTIALS) {
|
|
231
|
+
request.credentials = config.CREDENTIALS;
|
|
232
|
+
}
|
|
216
233
|
|
|
217
|
-
|
|
234
|
+
onCancel(() => controller.abort());
|
|
218
235
|
|
|
219
|
-
|
|
236
|
+
return await fetch(url, request);
|
|
220
237
|
};
|
|
221
238
|
|
|
222
|
-
export const getResponseHeader = (
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
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 = (
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
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
|
-
*
|
|
288
|
-
*
|
|
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>(
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
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
|
};
|
package/src/scripts/build-all.ts
CHANGED
|
@@ -45,17 +45,22 @@ for (const spec of specs) {
|
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
|
|
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
|
|