Skip to content

Commit 0a830ac

Browse files
committed
take xhr from user
1 parent ce60c41 commit 0a830ac

File tree

3 files changed

+127
-49
lines changed

3 files changed

+127
-49
lines changed

src/index.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -84,25 +84,25 @@ class ImageKit {
8484
* @param uploadOptions
8585
*/
8686
upload(uploadOptions: UploadOptions, options?: Partial<ImageKitOptions>): Promise<IKResponse<UploadResponse>>
87-
upload(uploadOptions: UploadOptions, callback: (err: Error | null, response: IKResponse<UploadResponse> | null) => void, options?: Partial<ImageKitOptions>): XMLHttpRequest;
88-
upload(uploadOptions: UploadOptions, callbackOrOptions?: ((err: Error | null, response: IKResponse<UploadResponse> | null) => void) | Partial<ImageKitOptions>, options?: Partial<ImageKitOptions>): XMLHttpRequest | Promise<IKResponse<UploadResponse>> {
87+
upload(uploadOptions: UploadOptions, callback: (err: Error | null, response: IKResponse<UploadResponse> | null) => void, options?: Partial<ImageKitOptions>): void;
88+
upload(uploadOptions: UploadOptions, callbackOrOptions?: ((err: Error | null, response: IKResponse<UploadResponse> | null) => void) | Partial<ImageKitOptions>, options?: Partial<ImageKitOptions>): void | Promise<IKResponse<UploadResponse>> {
8989
let callback;
90+
if (typeof uploadOptions !== "object") {
91+
throw ("First parameter needs to be object");
92+
}
9093
if (typeof callbackOrOptions === 'function') {
9194
callback = callbackOrOptions;
9295
} else {
9396
options = callbackOrOptions || {};
9497
}
95-
var mergedOptions = {
98+
var mergedOptions = {
9699
...this.options,
97100
...options,
98101
};
99-
const xhr = new XMLHttpRequest();
100-
const promise = promisify<IKResponse<UploadResponse>>(this, upload)(xhr, uploadOptions, mergedOptions, callback);
101-
if (typeof promise === "object" && typeof promise.then === "function") {
102-
return promise
103-
} else {
104-
return xhr;
105-
}
102+
const { xhr: userProvidedXHR } = uploadOptions || {};
103+
delete uploadOptions.xhr;
104+
const xhr = userProvidedXHR || new XMLHttpRequest();
105+
return promisify<IKResponse<UploadResponse>>(this, upload)(xhr, uploadOptions, mergedOptions, callback);
106106
}
107107
}
108108

src/interfaces/UploadOptions.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,9 @@ export interface UploadOptions {
9898
* Before setting any custom metadata on an asset you have to create the field using custom metadata fields API.
9999
*/
100100
customMetadata?: string | Record<string, string | number | boolean | Array<string | number | boolean>>
101+
102+
/**
103+
* Optional XMLHttpRequest object that you can send for upload API request. You can listen to `progress` and other events on this object for any custom logic.
104+
*/
105+
xhr?: XMLHttpRequest
101106
}

test/upload.js

Lines changed: 112 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ const uploadSuccessResponseObj = {
2121
"isPrivateFile": false,
2222
"customCoordinates": null,
2323
"fileType": "image",
24-
"AITags":[{"name":"Face","confidence":99.95,"source":"aws-auto-tagging"}],
25-
"extensionStatus":{"aws-auto-tagging":"success"}
24+
"AITags": [{ "name": "Face", "confidence": 99.95, "source": "aws-auto-tagging" }],
25+
"extensionStatus": { "aws-auto-tagging": "success" }
2626
};
2727

2828
function successSignature() {
@@ -94,14 +94,16 @@ describe("File upload", function () {
9494
server.restore();
9595
});
9696

97-
it('Invalid Options', function () {
98-
97+
it('Invalid options', function (done) {
9998
var callback = sinon.spy();
10099

101-
imagekit.upload(undefined, callback);
102-
expect(server.requests.length).to.be.equal(1);
103-
expect(callback.calledOnce).to.be.true;
104-
sinon.assert.calledWith(callback, { help: "", message: "Invalid uploadOptions parameter" }, null);
100+
try {
101+
imagekit.upload(undefined, callback);
102+
} catch (ex) {
103+
// console.log(ex);
104+
expect(ex).to.be.deep.equal("First parameter needs to be object");
105+
done();
106+
}
105107
});
106108

107109
it('Missing fileName', function () {
@@ -139,14 +141,14 @@ describe("File upload", function () {
139141
var callback = sinon.spy();
140142

141143
imagekit.upload(fileOptions, callback, {
142-
authenticationEndpoint : ""
144+
authenticationEndpoint: ""
143145
});
144146

145147
expect(server.requests.length).to.be.equal(1);
146148
sinon.assert.calledWith(callback, { message: "Missing authentication endpoint for upload", help: "" }, null);
147149
});
148150

149-
it('Missing public key', function(){
151+
it('Missing public key', function () {
150152
const fileOptions = {
151153
fileName: "test_file_name",
152154
file: "test_file"
@@ -155,7 +157,7 @@ describe("File upload", function () {
155157
var callback = sinon.spy();
156158

157159
imagekit.upload(fileOptions, callback, {
158-
publicKey : ""
160+
publicKey: ""
159161
});
160162

161163
expect(server.requests.length).to.be.equal(1);
@@ -171,7 +173,7 @@ describe("File upload", function () {
171173
var callback = sinon.spy();
172174

173175
imagekit.upload(fileOptions, callback, {
174-
authenticationEndpoint : "https://does-not-exist-sdfsdf/aut"
176+
authenticationEndpoint: "https://does-not-exist-sdfsdf/aut"
175177
});
176178

177179
expect(server.requests.length).to.be.equal(2);
@@ -349,7 +351,7 @@ describe("File upload", function () {
349351
sinon.assert.calledWith(callback, null, uploadSuccessResponseObj);
350352
});
351353

352-
it('With extensions parameter', function(){
354+
it('With extensions parameter', function () {
353355
const fileOptions = {
354356
fileName: "test_file_name",
355357
file: "test_file",
@@ -367,7 +369,6 @@ describe("File upload", function () {
367369
],
368370
webhookUrl: "https://your-domain/?appId=some-id"
369371
};
370-
var jsonStringifiedExtensions = JSON.stringify(fileOptions.extensions);
371372
var callback = sinon.spy();
372373

373374
imagekit.upload(fileOptions, callback);
@@ -389,7 +390,7 @@ describe("File upload", function () {
389390
expect(arg.get('useUniqueFileName')).to.be.equal('false');
390391
expect(arg.get('isPrivateFile')).to.be.equal('true');
391392
expect(arg.get('publicKey')).to.be.equal('test_public_key');
392-
expect(arg.get('extensions')).to.be.equal(jsonStringifiedExtensions);
393+
expect(arg.get('extensions')).to.be.equal(JSON.stringify(fileOptions.extensions));
393394
expect(arg.get('webhookUrl')).to.be.equal('https://your-domain/?appId=some-id')
394395

395396
expect(callback.calledOnce).to.be.true;
@@ -531,15 +532,15 @@ describe("File upload", function () {
531532

532533
expect(server.requests.length).to.be.equal(2);
533534
server.respondWith("GET", newAuthEndpoint,
534-
[
535-
200,
536-
{ "Content-Type": "application/json" },
537-
JSON.stringify({
538-
signature: "override_test_signature",
539-
expire: 123123,
540-
token: "override_test_token"
541-
})
542-
]);
535+
[
536+
200,
537+
{ "Content-Type": "application/json" },
538+
JSON.stringify({
539+
signature: "override_test_signature",
540+
expire: 123123,
541+
token: "override_test_token"
542+
})
543+
]);
543544
server.respond();
544545
successUploadResponse();
545546

@@ -555,12 +556,14 @@ describe("File upload", function () {
555556
expect(arg.get('useUniqueFileName')).to.be.equal(undefined);
556557
expect(arg.get('customCoordinates')).to.be.equal(undefined);
557558
expect(arg.get('responseFields')).to.be.equal(undefined);
559+
expect(arg.get('extensions')).to.be.equal(undefined);
560+
expect(arg.get('customMetadata')).to.be.equal(undefined);
558561

559562
expect(callback.calledOnce).to.be.true;
560563
sinon.assert.calledWith(callback, null, uploadSuccessResponseObj);
561564
});
562565

563-
it('With overwrite parameters', function(){
566+
it('With overwrite parameters', function () {
564567
const fileOptions = {
565568
fileName: "test_file_name",
566569
file: "test_file",
@@ -581,7 +584,6 @@ describe("File upload", function () {
581584
overwriteTags: false,
582585
overwriteCustomMetadata: false
583586
};
584-
var jsonStringifiedExtensions = JSON.stringify(fileOptions.extensions);
585587
var callback = sinon.spy();
586588

587589
imagekit.upload(fileOptions, callback);
@@ -603,7 +605,7 @@ describe("File upload", function () {
603605
expect(arg.get('useUniqueFileName')).to.be.equal('false');
604606
expect(arg.get('isPrivateFile')).to.be.equal('true');
605607
expect(arg.get('publicKey')).to.be.equal('test_public_key');
606-
expect(arg.get('extensions')).to.be.equal(jsonStringifiedExtensions);
608+
expect(arg.get('extensions')).to.be.equal(JSON.stringify(fileOptions.extensions));
607609
expect(arg.get('overwriteFile')).to.be.equal('false');
608610
expect(arg.get('overwriteAITags')).to.be.equal('false');
609611
expect(arg.get('overwriteTags')).to.be.equal('false');
@@ -613,7 +615,7 @@ describe("File upload", function () {
613615
sinon.assert.calledWith(callback, null, uploadSuccessResponseObj);
614616
});
615617

616-
it('With customMetadata', function(){
618+
it('With customMetadata', function () {
617619
const fileOptions = {
618620
fileName: "test_file_name",
619621
file: "test_file",
@@ -638,8 +640,6 @@ describe("File upload", function () {
638640
color: "red"
639641
},
640642
};
641-
var jsonStringifiedExtensions = JSON.stringify(fileOptions.extensions);
642-
var customMetadata = JSON.stringify(fileOptions.customMetadata);
643643
var callback = sinon.spy();
644644

645645
imagekit.upload(fileOptions, callback);
@@ -661,18 +661,20 @@ describe("File upload", function () {
661661
expect(arg.get('useUniqueFileName')).to.be.equal('false');
662662
expect(arg.get('isPrivateFile')).to.be.equal('true');
663663
expect(arg.get('publicKey')).to.be.equal('test_public_key');
664-
expect(arg.get('extensions')).to.be.equal(jsonStringifiedExtensions);
664+
expect(arg.get('extensions')).to.be.equal(JSON.stringify(fileOptions.extensions));
665665
expect(arg.get('overwriteFile')).to.be.equal('false');
666666
expect(arg.get('overwriteAITags')).to.be.equal('false');
667667
expect(arg.get('overwriteTags')).to.be.equal('false');
668668
expect(arg.get('overwriteCustomMetadata')).to.be.equal('false');
669-
expect(arg.get('customMetadata')).to.be.equal(customMetadata);
669+
expect(arg.get('customMetadata')).to.be.equal(JSON.stringify(fileOptions.customMetadata));
670670

671671
expect(callback.calledOnce).to.be.true;
672672
sinon.assert.calledWith(callback, null, uploadSuccessResponseObj);
673673
});
674674

675-
it('check XHR object', function(){
675+
it('check custom XHR object is used', function () {
676+
var xhr = new XMLHttpRequest();
677+
xhr.onprogress = sinon.spy();
676678
const fileOptions = {
677679
fileName: "test_file_name",
678680
file: "test_file",
@@ -688,13 +690,13 @@ describe("File upload", function () {
688690
maxTags: 10
689691
}
690692
],
693+
xhr
691694
};
692-
var jsonStringifiedExtensions = JSON.stringify(fileOptions.extensions);
693695
var callback = sinon.spy();
694-
695-
var xhr = imagekit.upload(fileOptions, callback);
696-
696+
imagekit.upload(fileOptions, callback);
697697
expect(server.requests.length).to.be.equal(2);
698+
expect(server.requests[0]).to.be.equal(xhr);
699+
expect(server.requests[0].onprogress.toString()).to.be.equal("spy");
698700
successSignature();
699701
successUploadResponse();
700702

@@ -711,10 +713,81 @@ describe("File upload", function () {
711713
expect(arg.get('useUniqueFileName')).to.be.equal('false');
712714
expect(arg.get('isPrivateFile')).to.be.equal('true');
713715
expect(arg.get('publicKey')).to.be.equal('test_public_key');
714-
expect(arg.get('extensions')).to.be.equal(jsonStringifiedExtensions);
715-
expect(server.requests[0]).to.be.equal(xhr);
716+
expect(arg.get('extensions')).to.be.equal(JSON.stringify(fileOptions.extensions));
716717

717718
expect(callback.calledOnce).to.be.true;
718719
sinon.assert.calledWith(callback, null, uploadSuccessResponseObj);
719720
});
721+
722+
it('Upload using promise - success', function (done) {
723+
const fileOptions = {
724+
fileName: "test_file_name",
725+
file: "test_file",
726+
tags: "test_tag1,test_tag2",
727+
customCoordinates: "10, 10, 100, 100",
728+
responseFields: "tags, customCoordinates, isPrivateFile, metadata",
729+
useUniqueFileName: false,
730+
isPrivateFile: true,
731+
extensions: [
732+
{
733+
name: "aws-auto-tagging",
734+
minConfidence: 80,
735+
maxTags: 10
736+
}
737+
]
738+
};
739+
imagekit.upload(fileOptions).then((response) => {
740+
expect(server.requests.length).to.be.equal(2);
741+
var arg = server.requests[0].requestBody;
742+
743+
expect(arg.get('file')).to.be.equal("test_file");
744+
expect(arg.get('fileName')).to.be.equal("test_file_name");
745+
expect(arg.get('token')).to.be.equal("test_token");
746+
expect(arg.get('expire')).to.be.equal("123");
747+
expect(arg.get('signature')).to.be.equal("test_signature");
748+
expect(arg.get('tags')).to.be.equal("test_tag1,test_tag2");
749+
expect(arg.get('customCoordinates')).to.be.equal("10, 10, 100, 100");
750+
expect(arg.get('responseFields')).to.be.equal("tags, customCoordinates, isPrivateFile, metadata");
751+
expect(arg.get('useUniqueFileName')).to.be.equal('false');
752+
expect(arg.get('isPrivateFile')).to.be.equal('true');
753+
expect(arg.get('publicKey')).to.be.equal('test_public_key');
754+
expect(arg.get('extensions')).to.be.equal(JSON.stringify(fileOptions.extensions));
755+
expect(response).to.be.deep.equal(uploadSuccessResponseObj)
756+
done();
757+
});
758+
759+
successSignature();
760+
successUploadResponse();
761+
});
762+
763+
it('Upload using promise - error', function (done) {
764+
var errRes = {
765+
help: "For support kindly contact us at [email protected] .",
766+
message: "Your account cannot be authenticated."
767+
}
768+
const fileOptions = {
769+
fileName: "test_file_name",
770+
file: "test_file",
771+
tags: "test_tag1,test_tag2",
772+
customCoordinates: "10, 10, 100, 100",
773+
responseFields: "tags, customCoordinates, isPrivateFile, metadata",
774+
useUniqueFileName: false,
775+
isPrivateFile: true,
776+
extensions: [
777+
{
778+
name: "aws-auto-tagging",
779+
minConfidence: 80,
780+
maxTags: 10
781+
}
782+
]
783+
};
784+
imagekit.upload(fileOptions).then(() => {
785+
}).catch((ex) => {
786+
expect(ex).to.be.deep.equal(errRes);
787+
done();
788+
})
789+
790+
successSignature();
791+
errorUploadResponse(500, errRes);
792+
});
720793
});

0 commit comments

Comments
 (0)