@imagekit/javascript 5.0.0-beta.6 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,192 +0,0 @@
1
- interface TransformationObject {
2
- type: "transformation";
3
- value: string;
4
- }
5
-
6
- interface GifToVideoOrThumbnailObject {
7
- type: "gif-to-video" | "thumbnail";
8
- value?: string;
9
- }
10
-
11
- interface AbsObject {
12
- type: "abs";
13
- value: string;
14
- protocol: "hls" | "dash";
15
- }
16
-
17
- type PostTransformation = TransformationObject | GifToVideoOrThumbnailObject | AbsObject;
18
-
19
- interface Transformation {
20
- /**
21
- * Specifies pre-transformations to be applied. Must be a valid string of transformations like "w-300,h-300".
22
- * Refer to the docs for more details on transformations.
23
- */
24
- pre?: string;
25
-
26
- /**
27
- * Specifies post-transformations to be applied. This is an array of transformation objects, each with:
28
- * - type: One of "transformation", "gif-to-video", "thumbnail", or "abs".
29
- * - value: A valid transformation string required if "type" is "transformation" or "abs". Optional if "type" is "gif-to-video" or "thumbnail".
30
- * - protocol: Used only when type is "abs". Can be "hls" or "dash".
31
- *
32
- * Refer to the docs for more details on transformations and usage in post.
33
- */
34
- post?: PostTransformation[];
35
- }
36
-
37
- /**
38
- * Options used when uploading a file using the V1 API.
39
- * Check out the official documentation:
40
- * {@link https://imagekit.io/docs/api-reference/upload-file/upload-file}
41
- */
42
- export interface UploadOptions {
43
- /**
44
- * This field accepts three main input formats for the file content:
45
- * - "binary": Directly pass the binary data. Typically used when uploading via the browser using a File or Blob.
46
- * - "base64": A base64-encoded string of the file content.
47
- * - "url": A direct URL from which ImageKit server will download the file and upload.
48
- */
49
- file: string | Blob | File;
50
-
51
- /**
52
- * The name with which the file should be uploaded.
53
- * - Valid characters: alphanumeric (a-z, A-Z, 0-9, including Unicode letters and numerals) and the special chars ". _ -"
54
- * - Any other character (including space) is replaced with "_"
55
- *
56
- * Example: "company_logo.png"
57
- */
58
- fileName: string;
59
-
60
- /**
61
- * The HMAC-SHA1 digest of the concatenation of "token + expire". The signing key is your ImageKit private API key.
62
- * Required for client-side authentication. Must be computed on the server side.
63
- * Calculate this signature in your secure server and pass it to the client.
64
- */
65
- signature: string;
66
-
67
- /**
68
- * A unique value to identify and prevent replays. Typically a UUID (e.g., version 4).
69
- * Each request must carry a fresh token. The server rejects reused tokens, even if the original request failed.
70
- */
71
- token: string;
72
-
73
- /**
74
- * A Unix timestamp in seconds, less than 1 hour in the future.
75
- */
76
- expire: number;
77
-
78
- /**
79
- * The public API key of your ImageKit account. You can find it in the [ImageKit dashboard](https://imagekit.io/dashboard/developer/api-keys).
80
- */
81
- publicKey: string;
82
-
83
- /**
84
- * Whether to use a unique filename for this file or not.
85
- * - Accepts true or false.
86
- * - If set true, ImageKit.io will add a unique suffix to the filename parameter to get a unique filename.
87
- * - If set false, then the image is uploaded with the provided filename parameter and any existing file with the same name is replaced.
88
- * Default value - true
89
- */
90
- useUniqueFileName?: boolean;
91
-
92
- /**
93
- * Optionally set tags on the uploaded file.
94
- * If passing an array, the SDK automatically joins them into a comma-separated string when sending to the server.
95
- * Example: ["t-shirt", "round-neck", "men"] => "t-shirt,round-neck,men"
96
- */
97
- tags?: string | string[];
98
-
99
- /**
100
- * The folder path where the file will be stored, e.g., "/images/folder/".
101
- * - If the path doesn't exist, it is created on-the-fly.
102
- * - Nested folders are supported by using multiple "/".
103
- * - Default: "/"
104
- */
105
- folder?: string;
106
-
107
- /**
108
- * Whether to mark the file as private (only relevant for image uploads).
109
- * A private file requires signed URLs or named transformations for access.
110
- * Default: false
111
- */
112
- isPrivateFile?: boolean;
113
-
114
- /**
115
- * A string in "x,y,width,height" format that defines the region of interest in an image (top-left coords and area size).
116
- * Example: "10,10,100,100".
117
- */
118
- customCoordinates?: string;
119
-
120
- /**
121
- * A comma-separated or array-based set of fields to return in the upload response.
122
- * Example: "tags,customCoordinates,isPrivateFile,metadata"
123
- */
124
- responseFields?: string | string[];
125
-
126
- /**
127
- * An array of extension objects to apply to the image, e.g. background removal, auto-tagging, etc.
128
- * The SDK will JSON-stringify this array automatically before sending.
129
- */
130
- extensions?: object[];
131
-
132
- /**
133
- * A webhook URL to receive the final status of any pending extensions once they've completed processing.
134
- */
135
- webhookUrl?: string;
136
-
137
- /**
138
- * Defaults to true. If false, and "useUniqueFileName" is also false, the API immediately fails if a file with the same name/folder already exists.
139
- */
140
- overwriteFile?: boolean;
141
-
142
- /**
143
- * Defaults to true. If true, and an existing file is found at the same location, its AITags are removed. Set to false to keep existing AITags.
144
- */
145
- overwriteAITags?: boolean;
146
-
147
- /**
148
- * Defaults to true. If no tags are specified in the request, existing tags are removed from overwritten files. Setting to false has no effect if the request includes tags.
149
- */
150
- overwriteTags?: boolean;
151
-
152
- /**
153
- * Defaults to true. If no customMetadata is specified in the request, existing customMetadata is removed from overwritten files. Setting to false has no effect if the request specifies customMetadata.
154
- */
155
- overwriteCustomMetadata?: boolean;
156
-
157
- /**
158
- * A stringified JSON or an object containing custom metadata fields to store with the file.
159
- * Custom metadata fields must be pre-defined in your ImageKit configuration.
160
- */
161
- customMetadata?: string | Record<string, string | number | boolean | Array<string | number | boolean>>;
162
-
163
- /**
164
- * Defines pre and post transformations to be applied to the file during upload. The SDK enforces certain validation rules for pre/post transformations.
165
- * For details, see:
166
- * {@link https://imagekit.io/docs/dam/pre-and-post-transformation-on-upload}
167
- */
168
- transformation?: Transformation;
169
-
170
- /**
171
- * An optional XMLHttpRequest instance for the upload. The SDK merges it with its own logic to handle progress events, etc.
172
- * You can listen to `progress` or other events on this object for custom logic.
173
- */
174
- xhr?: XMLHttpRequest;
175
-
176
- /**
177
- * A string specifying the checks to be performed server-side before uploading to the media library, e.g. size or mime type checks.
178
- * For format details, see: {@link https://imagekit.io/docs/api-reference/upload-file/upload-file#upload-api-checks}
179
- */
180
- checks?: string;
181
-
182
- /**
183
- * Optional callback function that will be called with the progress event when the file is being uploaded.
184
- */
185
- onProgress?: (event: ProgressEvent) => void;
186
-
187
- /**
188
- * An AbortSignal instance that can be used to cancel the request if needed.
189
- * When aborted, the request fails with an ImageKitAbortError.
190
- */
191
- abortSignal?: AbortSignal;
192
- }
@@ -1,182 +0,0 @@
1
- /**
2
- * Type of files to include in result set. Accepts three values:
3
- * all - include all types of files in result set
4
- * image - only search in image type files
5
- * non-image - only search in files which are not image, e.g., JS or CSS or video files.
6
- *
7
- * {@link https://imagekit.io/docs/api-reference/digital-asset-management-dam/list-and-search-assets}
8
- */
9
- type FileType = "all" | "image" | "non-image";
10
-
11
- /**
12
- * Metadata object structure
13
- *
14
- * {@link https://imagekit.io/docs/api-reference/file-metadata/get-uploaded-file-metadata#Responses}
15
- *
16
- * Contents of Object
17
- *
18
- * - Exif
19
- *
20
- * For more information about the Exif standard, please refer to the specification found on http://www.exif.org. A comprehensive list of available Exif attributes and their meaning can be found on http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/.
21
- *
22
- * - Perceptual Hash (pHash)
23
- *
24
- * Perceptual hashing allows you to construct a hash value that uniquely identifies an input image based on the image's contents. It is different from cryptographic hash functions like MD5 and SHA1. pHash provides similar hash value after minor distortions, like small rotations, blurring, and compression in the image.
25
- */
26
- interface Metadata {
27
- height: number;
28
- width: number;
29
- size: number;
30
- format: string;
31
- hasColorProfile: boolean;
32
- quality: number;
33
- density: number;
34
- hasTransparency: boolean;
35
- pHash: string;
36
- exif: {
37
- image: {
38
- Make: string;
39
- Model: string;
40
- Orientation: number;
41
- XResolution: number;
42
- YResolution: number;
43
- ResolutionUnit: number;
44
- Software: string;
45
- ModifyDate: string;
46
- YCbCrPositioning: number;
47
- ExifOffset: number;
48
- GPSInfo: number;
49
- };
50
- thumbnail: {
51
- Compression: number;
52
- XResolution: number;
53
- YResolution: number;
54
- ResolutionUnit: number;
55
- ThumbnailOffset: number;
56
- ThumbnailLength: number;
57
- };
58
- exif: {
59
- ExposureTime: number;
60
- FNumber: number;
61
- ExposureProgram: number;
62
- ISO: number;
63
- ExifVersion: string;
64
- DateTimeOriginal: string;
65
- CreateDate: string;
66
- ShutterSpeedValue: number;
67
- ApertureValue: number;
68
- ExposureCompensation: number;
69
- MeteringMode: number;
70
- Flash: number;
71
- FocalLength: number;
72
- SubSecTime: string;
73
- SubSecTimeOriginal: string;
74
- SubSecTimeDigitized: string;
75
- FlashpixVersion: string;
76
- ColorSpace: number;
77
- ExifImageWidth: number;
78
- ExifImageHeight: number;
79
- InteropOffset: number;
80
- FocalPlaneXResolution: number;
81
- FocalPlaneYResolution: number;
82
- FocalPlaneResolutionUnit: number;
83
- CustomRendered: number;
84
- ExposureMode: number;
85
- WhiteBalance: number;
86
- SceneCaptureType: number;
87
- };
88
- gps: { GPSVersionID: number[] };
89
- interoperability: {
90
- InteropIndex: string;
91
- InteropVersion: string;
92
- };
93
- makernote: any;
94
- };
95
- }
96
-
97
- export interface ResponseMetadata {
98
- statusCode: number;
99
- requestId: string;
100
- headers: Record<string, string | number | boolean>;
101
- }
102
-
103
- /**
104
- * Response from server when file is uploaded successfully.
105
- *
106
- * {@link https://imagekit.io/docs/api-reference/upload-file/upload-file#Responses}
107
- */
108
- export interface UploadResponse {
109
- /**
110
- * Unique fileId. Store this fileld in your database, as this will be used to perform update action on this file.
111
- */
112
- fileId?: string;
113
- /**
114
- * The name of the uploaded file.
115
- */
116
- name?: string;
117
- /**
118
- * The URL of the file.
119
- */
120
- url?: string;
121
- /**
122
- * In case of an image, a small thumbnail URL.
123
- */
124
- thumbnailUrl?: string;
125
- /**
126
- * Height of the uploaded image file. Only applicable when file type is image.
127
- */
128
- height?: number;
129
- /**
130
- * Width of the uploaded image file. Only applicable when file type is image.
131
- */
132
- width?: number;
133
- /**
134
- * Size of the uploaded file in bytes.
135
- */
136
- size?: number;
137
- /**
138
- * Type of file. It can either be image or non-image.
139
- */
140
- fileType?: FileType;
141
- /**
142
- * The path of the file uploaded. It includes any folder that you specified while uploading.
143
- */
144
- filePath?: string;
145
- /**
146
- * Array of tags associated with the image.
147
- */
148
- tags?: string[];
149
- /**
150
- * Is the file marked as private. It can be either true or false.
151
- */
152
- isPrivateFile?: boolean;
153
- /**
154
- * Value of custom coordinates associated with the image in format x,y,width,height.
155
- */
156
- customCoordinates?: string | null;
157
- /**
158
- * The metadata of the upload file. Use responseFields property in request to get the metadata returned in response of upload API.
159
- */
160
- metadata?: Metadata;
161
- /*
162
- * AITags field is populated only because the google-auto-tagging extension was executed synchronously and it received a successresponse.
163
- */
164
- AITags?: object[];
165
-
166
- /*
167
- * Field object which will contain the status of each extension at the time of completion of the update/upload request.
168
- */
169
- extensionStatus?: { [key: string]: string }
170
-
171
- /**
172
- * Message indicating that the file upload is accepted. This field is only present when the upload is accepted but not yet processed.
173
- * This can happen when the file is being processed for pre-transformation for video.
174
- * The upload will be completed once the pre-transformation is done.
175
- */
176
- message?: string
177
-
178
- /**
179
- * Response metadata for debugging purposes.
180
- */
181
- readonly $ResponseMetadata: ResponseMetadata;
182
- }
@@ -1,7 +0,0 @@
1
- // src/interfaces/index.ts
2
- // Re-export all interfaces so that TypeDoc includes referenced types in the documentation
3
-
4
- export * from './UploadResponse';
5
- export * from './UploadOptions';
6
- export * from './Transformation';
7
- export * from './SrcOptions';
package/src/upload.ts DELETED
@@ -1,274 +0,0 @@
1
- import errorMessages from "./constants/errorMessages";
2
- import { ResponseMetadata, UploadOptions, UploadResponse } from "./interfaces";
3
-
4
- /**
5
- * Represents an error when a request to ImageKit is invalid.
6
- */
7
- export class ImageKitInvalidRequestError extends Error {
8
- /**
9
- * Optional metadata about the response. It is only available if server returns a response.
10
- */
11
- readonly $ResponseMetadata?: ResponseMetadata;
12
- constructor(message: string, responseMetadata?: ResponseMetadata) {
13
- super(message);
14
- this.name = "ImageKitInvalidRequestError";
15
- this.$ResponseMetadata = responseMetadata;
16
- }
17
- }
18
-
19
- /**
20
- * Represents an error when an upload operation is aborted.
21
- */
22
- export class ImageKitAbortError extends Error {
23
- /**
24
- * The reason why the operation was aborted, which can be any JavaScript value. If not specified, the reason is set to "AbortError" DOMException.
25
- */
26
- reason?: unknown;
27
- constructor(message: string, reason?: unknown) {
28
- super(message);
29
- this.name = "ImageKitAbortError";
30
- this.reason = reason;
31
- }
32
- }
33
-
34
- /**
35
- * Represents a network error during an upload operation to ImageKit.
36
- */
37
- export class ImageKitUploadNetworkError extends Error {
38
- constructor(message: string) {
39
- super(message);
40
- this.name = "ImageKitUploadNetworkError";
41
- }
42
- }
43
-
44
- /**
45
- * Represents a server error from ImageKit during an upload operation.
46
- */
47
- export class ImageKitServerError extends Error {
48
- /**
49
- * Optional metadata about the response. It is only available if server returns a response.
50
- */
51
- readonly $ResponseMetadata?: ResponseMetadata;
52
- constructor(message: string, responseMetadata?: ResponseMetadata) {
53
- super(message);
54
- this.name = "ImageKitServerError";
55
- this.$ResponseMetadata = responseMetadata;
56
- }
57
- }
58
-
59
- /**
60
- * Uploads a file to ImageKit with the given upload options. This function uses V1 API, check the [API docs](https://imagekit.io/docs/api-reference/upload-file/upload-file) for more details.
61
- *
62
- * @throws {ImageKitInvalidRequestError} If the request is invalid.
63
- * @throws {ImageKitAbortError} If the request is aborted.
64
- * @throws {ImageKitUploadNetworkError} If there is a network error.
65
- * @throws {ImageKitServerError} If there is a server error.
66
- *
67
- * @param {UploadOptions} uploadOptions - The options for uploading the file.
68
- * @returns {Promise<UploadResponse>} A Promise resolving to a successful UploadResponse.
69
- */
70
- export const upload = (uploadOptions: UploadOptions): Promise<UploadResponse> => {
71
- if(!uploadOptions) {
72
- return Promise.reject(new ImageKitInvalidRequestError("Invalid options provided for upload"));
73
- }
74
- return new Promise((resolve, reject) => {
75
- const { xhr: userProvidedXHR } = uploadOptions || {};
76
- delete uploadOptions.xhr;
77
- const xhr = userProvidedXHR || new XMLHttpRequest();
78
-
79
- if (!uploadOptions.file) {
80
- return reject(new ImageKitInvalidRequestError(errorMessages.MISSING_UPLOAD_FILE_PARAMETER.message));
81
- }
82
-
83
- if (!uploadOptions.fileName) {
84
- return reject(new ImageKitInvalidRequestError(errorMessages.MISSING_UPLOAD_FILENAME_PARAMETER.message));
85
- }
86
-
87
- if (!uploadOptions.publicKey || uploadOptions.publicKey.length === 0) {
88
- return reject(new ImageKitInvalidRequestError(errorMessages.MISSING_PUBLIC_KEY.message));
89
- }
90
-
91
- if (!uploadOptions.token) {
92
- return reject(new ImageKitInvalidRequestError(errorMessages.MISSING_TOKEN.message));
93
- }
94
-
95
- if (!uploadOptions.signature) {
96
- return reject(new ImageKitInvalidRequestError(errorMessages.MISSING_SIGNATURE.message));
97
- }
98
-
99
- if (!uploadOptions.expire) {
100
- return reject(new ImageKitInvalidRequestError(errorMessages.MISSING_EXPIRE.message));
101
- }
102
-
103
- if (uploadOptions.transformation) {
104
- if (!(Object.keys(uploadOptions.transformation).includes("pre") || Object.keys(uploadOptions.transformation).includes("post"))) {
105
- return reject(new ImageKitInvalidRequestError(errorMessages.INVALID_TRANSFORMATION.message));
106
- }
107
- if (Object.keys(uploadOptions.transformation).includes("pre") && !uploadOptions.transformation.pre) {
108
- return reject(new ImageKitInvalidRequestError(errorMessages.INVALID_PRE_TRANSFORMATION.message));
109
- }
110
- if (Object.keys(uploadOptions.transformation).includes("post")) {
111
- if (Array.isArray(uploadOptions.transformation.post)) {
112
- for (let transformation of uploadOptions.transformation.post) {
113
- if (transformation.type === "abs" && !(transformation.protocol || transformation.value)) {
114
- return reject(new ImageKitInvalidRequestError(errorMessages.INVALID_POST_TRANSFORMATION.message));
115
- } else if (transformation.type === "transformation" && !transformation.value) {
116
- return reject(new ImageKitInvalidRequestError(errorMessages.INVALID_POST_TRANSFORMATION.message));
117
- }
118
- }
119
- } else {
120
- return reject(new ImageKitInvalidRequestError(errorMessages.INVALID_POST_TRANSFORMATION.message));
121
- }
122
- }
123
- }
124
-
125
- var formData = new FormData();
126
- let key: keyof typeof uploadOptions;
127
- for (key in uploadOptions) {
128
- if (key) {
129
- if (key === "file" && typeof uploadOptions.file != "string") {
130
- formData.append('file', uploadOptions.file, String(uploadOptions.fileName));
131
- } else if (key === "tags" && Array.isArray(uploadOptions.tags)) {
132
- formData.append('tags', uploadOptions.tags.join(","));
133
- } else if (key === 'signature') {
134
- formData.append("signature", uploadOptions.signature);
135
- } else if (key === 'expire') {
136
- formData.append("expire", String(uploadOptions.expire));
137
- } else if (key === 'token') {
138
- formData.append("token", uploadOptions.token);
139
- } else if (key === "responseFields" && Array.isArray(uploadOptions.responseFields)) {
140
- formData.append('responseFields', uploadOptions.responseFields.join(","));
141
- } else if (key === "extensions" && Array.isArray(uploadOptions.extensions)) {
142
- formData.append('extensions', JSON.stringify(uploadOptions.extensions));
143
- } else if (key === "customMetadata" && typeof uploadOptions.customMetadata === "object" &&
144
- !Array.isArray(uploadOptions.customMetadata) && uploadOptions.customMetadata !== null) {
145
- formData.append('customMetadata', JSON.stringify(uploadOptions.customMetadata));
146
- } else if (key === "transformation" && typeof uploadOptions.transformation === "object" &&
147
- uploadOptions.transformation !== null) {
148
- formData.append(key, JSON.stringify(uploadOptions.transformation));
149
- } else if (key === 'checks' && uploadOptions.checks) {
150
- formData.append("checks", uploadOptions.checks);
151
- } else if (uploadOptions[key] !== undefined) {
152
- if (["onProgress", "abortSignal"].includes(key)) continue;
153
- formData.append(key, String(uploadOptions[key]));
154
- }
155
- }
156
- }
157
-
158
- formData.append("publicKey", uploadOptions.publicKey);
159
-
160
- if (uploadOptions.onProgress) {
161
- xhr.upload.onprogress = function (event: ProgressEvent) {
162
- if (uploadOptions.onProgress) uploadOptions.onProgress(event)
163
- };
164
- }
165
-
166
- function onAbortHandler() {
167
- xhr.abort();
168
- return reject(new ImageKitAbortError(
169
- "Upload aborted",
170
- uploadOptions.abortSignal?.reason
171
- ));
172
- }
173
-
174
- if (uploadOptions.abortSignal) {
175
- if (uploadOptions.abortSignal.aborted) {
176
- // If the signal is already aborted, return immediately with the reason
177
-
178
- return reject(new ImageKitAbortError(
179
- "Upload aborted",
180
- uploadOptions.abortSignal?.reason
181
- ));
182
- }
183
-
184
- // If the signal is not already aborted, add an event listener to abort the request when the signal is aborted
185
- uploadOptions.abortSignal.addEventListener("abort", onAbortHandler);
186
-
187
- // On XHR completion (success, fail, or abort), remove just this abort handler
188
- xhr.addEventListener("loadend", () => {
189
- if (uploadOptions.abortSignal) {
190
- uploadOptions.abortSignal.removeEventListener("abort", onAbortHandler);
191
- }
192
- });
193
- }
194
-
195
- xhr.open('POST', 'https://upload.imagekit.io/api/v1/files/upload');
196
- xhr.onerror = function (e) {
197
- return reject(new ImageKitUploadNetworkError(errorMessages.UPLOAD_ENDPOINT_NETWORK_ERROR.message));
198
- }
199
- xhr.onload = function () {
200
- if (xhr.status >= 200 && xhr.status < 300) {
201
- try {
202
- var body = JSON.parse(xhr.responseText);
203
- var uploadResponse = addResponseHeadersAndBody(body, xhr);
204
- return resolve(uploadResponse);
205
- } catch (ex: any) {
206
- return reject(ex);
207
- }
208
- } else if (xhr.status >= 400 && xhr.status < 500) {
209
- // Send ImageKitInvalidRequestError
210
- try {
211
- var body = JSON.parse(xhr.responseText);
212
- return reject(new ImageKitInvalidRequestError(
213
- body.message ?? "Invalid request. Please check the parameters.",
214
- getResponseMetadata(xhr)
215
- ));
216
- } catch (ex: any) {
217
- return reject(ex);
218
- }
219
- } else {
220
- // Send ImageKitServerError
221
- try {
222
- var body = JSON.parse(xhr.responseText);
223
- return reject(new ImageKitServerError(
224
- body.message ?? "Server error occurred while uploading the file. This is rare and usually temporary.",
225
- getResponseMetadata(xhr)
226
- ));
227
- } catch (ex: any) {
228
- return reject(new ImageKitServerError(
229
- "Server error occurred while uploading the file. This is rare and usually temporary.",
230
- getResponseMetadata(xhr)
231
- ));
232
- }
233
- }
234
- };
235
- xhr.send(formData);
236
- });
237
- };
238
-
239
-
240
- const addResponseHeadersAndBody = (body: any, xhr: XMLHttpRequest) => {
241
- let response = { ...body };
242
- const responseMetadata = getResponseMetadata(xhr);
243
- Object.defineProperty(response, "$ResponseMetadata", {
244
- value: responseMetadata,
245
- enumerable: false,
246
- writable: false
247
- });
248
- return response;
249
- }
250
-
251
- const getResponseMetadata = (xhr: XMLHttpRequest): ResponseMetadata => {
252
- const headers = getResponseHeaderMap(xhr);
253
- const responseMetadata = {
254
- statusCode: xhr.status,
255
- headers: headers,
256
- requestId: headers["x-request-id"]
257
- }
258
- return responseMetadata;
259
- }
260
-
261
- function getResponseHeaderMap(xhr: XMLHttpRequest): Record<string, string> {
262
- const headers: Record<string, string> = {};
263
- const responseHeaders = xhr.getAllResponseHeaders();
264
- if (Object.keys(responseHeaders).length) {
265
- responseHeaders
266
- .trim()
267
- .split(/[\r\n]+/)
268
- .map(value => value.split(/: /))
269
- .forEach(keyValue => {
270
- headers[keyValue[0].trim().toLowerCase()] = keyValue[1].trim();
271
- });
272
- }
273
- return headers;
274
- }