From 293145257c9e56982443d6febdca96ffa3742fce Mon Sep 17 00:00:00 2001 From: glecaros Date: Sun, 1 May 2016 21:56:55 -0700 Subject: [PATCH 1/4] Implemented wrappers for FileTransfer. --- src/index.ts | 3 + src/plugins/filetransfer.ts | 189 ++++++++++++++++++++++++++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 src/plugins/filetransfer.ts diff --git a/src/index.ts b/src/index.ts index 1d43e9c14..52e1f8ca8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -31,6 +31,7 @@ import {Dialogs} from './plugins/dialogs'; import {EmailComposer} from './plugins/emailcomposer'; import {Facebook} from './plugins/facebook'; import {File} from './plugins/file'; +import {Transfer} from './plugins/filetransfer'; import {Flashlight} from './plugins/flashlight'; import {Geolocation} from './plugins/geolocation'; import {Globalization} from './plugins/globalization'; @@ -108,6 +109,7 @@ export { StatusBar, Toast, TouchID, + Transfer, Vibration, WebIntent } @@ -166,6 +168,7 @@ window['IonicNative'] = { StatusBar: StatusBar, Toast: Toast, TouchID: TouchID, + Transfer: Transfer, Vibration: Vibration, WebIntent: WebIntent }; diff --git a/src/plugins/filetransfer.ts b/src/plugins/filetransfer.ts new file mode 100644 index 000000000..49b6e0061 --- /dev/null +++ b/src/plugins/filetransfer.ts @@ -0,0 +1,189 @@ +import {Plugin, Cordova} from './plugin'; +import {Observable} from 'rxjs/Observable'; + +declare var FileTransfer; + +export interface FileUploadOptions { + + /** + * The name of the form element. + * Defaults to 'file'. + */ + fileKey?: string; + + /** + * The file name to use when saving the file on the server. + * Defaults to 'image.jpg'. + */ + fileName?: string; + + /** + * The HTTP method to use - either PUT or POST. + * Defaults to POST. + */ + httpMethod?: string; + + /** + * The mime type of the data to upload. + * Defaults to image/jpeg. + */ + mimeType?: string; + + /** + * A set of optional key/value pairs to pass in the HTTP request. + */ + params?: { [s: string]: any; } + + /** + * Whether to upload the data in chunked streaming mode. + * Defaults to true. + */ + chunkedMode?: boolean; + + /** + * A map of header name/header values. Use an array to specify more + * than one value. On iOS, FireOS, and Android, if a header named + * Content-Type is present, multipart form data will NOT be used. + */ + headers?: { [s: string]: any; } +} + +export interface FileUploadResult { + + /** + * The number of bytes sent to the server as part of the upload. + */ + bytesSent: number; + + /** + * The HTTP response code returned by the server. + */ + responseCode: number; + + /** + * The HTTP response returned by the server. + */ + response: string; + + /** + * The HTTP response headers by the server. + */ + headers: { [s: string]: any; } +} + +export interface FileTransferError { + + /** + * One of the predefined error codes listed below. + */ + code: number; + + /** + * URL to the source. + */ + source: string; + + /** + * URL to the target. + */ + target: string; + + /** + * HTTP status code. This attribute is only available when a response + * code is received from the HTTP connection. + */ + http_status: number; + + /** + * Response body. This attribute is only available when a response is received from the HTTP connection. + */ + body: string; + + /** + * Either e.getMessage or e.toString. + */ + exception: string; +} + +/** + * @name Transfer + * @description This plugin allows you to upload and download files. + * Example: + * Create instance: + * const fileTransfer = new Transfer(); + * + * Upload a file: + * fileTransfer.upload(..).then(..).catch(..); + * + * Download a file: + * fileTransfer.download(..).then(..).catch(..); + * + * Abort active transfer: + * fileTransfer.abort(); + */ +@Plugin({ + plugin: 'cordova-plugin-file-transfer', + pluginRef: 'FileTransfer', + repo: 'https://github.com/apache/cordova-plugin-file-transfer' +}) +export class Transfer { + + public static FILE_NOT_FOUND_ERR: number = 1; + public static INVALID_URL_ERR: number = 2; + public static CONNECTION_ERR: number = 3; + public static ABORT_ERR: number = 4; + public static NOT_MODIFIED_ERR: number = 4; + + ft: any; + + constructor() { + this.ft = new FileTransfer(); + } + + /** + * Sends a file to a server. + * + * @param {string} fileUrl Filesystem URL representing the file on the device or a data URI. For backwards compatibility, this can also be the full path of the file on the device. + * @param {string} url URL of the server to receive the file, as encoded by encodeURI(). + * @param {FileUploadOptions} options Optional parameters. + * @param {boolean} trustAllHosts: Optional parameter, defaults to false. If set to true, it accepts all security certificates. This is useful since Android rejects self-signed security certificates. Not recommended for production use. Supported on Android and iOS. + * @return Returns a Promise that resolves to a FileUploadResult and rejects with FileTransferError. + */ + upload(fileUrl: string, url: string, options?: FileUploadOptions, trustAllHosts?: boolean): Promise { + return new Promise((resolve, reject) => { + this.ft.upload(fileUrl, url, (result: FileUploadResult) => { + resolve(result); + }, (err: FileTransferError) => { + reject(err); + }); + }); + } + + /** + * Downloads a file from server. + * + * @param {string} source URL of the server to download the file, as encoded by encodeURI(). + * @param {stirng} target Filesystem url representing the file on the device. For backwards compatibility, this can also be the full path of the file on the device. + * @param {boolean} trustAllHosts Optional parameter, defaults to false. If set to true, it accepts all security certificates. This is useful because Android rejects self-signed security certificates. Not recommended for production use. Supported on Android and iOS. + * @param {object} Optional parameters, currently only supports headers (such as Authorization (Basic Authentication), etc). + * @return Returns a Promise that resolves to a FileEntry object. + */ + download(source: string, target: string, trustAllHosts?: boolean, options?: { [s: string]: any; }): Promise { + return new Promise((resolve, reject) => { + this.ft.download(source, target, (result: any) => { + resolve(result); + }, (err: FileTransferError) => { + reject(err); + }, trustAllHosts, options); + }) + } + + /** + * Aborts an in-progress transfer. The onerror callback is passed a FileTransferError + * object which has an error code of FileTransferError.ABORT_ERR. + */ + abort() { + return this.ft.abort(); + } + +} From e9739882f42aa8cfac025502f161182272496c1a Mon Sep 17 00:00:00 2001 From: glecaros Date: Mon, 2 May 2016 23:13:53 -0700 Subject: [PATCH 2/4] Exposed onprogress. --- src/plugins/filetransfer.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/plugins/filetransfer.ts b/src/plugins/filetransfer.ts index 49b6e0061..77dac2413 100644 --- a/src/plugins/filetransfer.ts +++ b/src/plugins/filetransfer.ts @@ -178,11 +178,19 @@ export class Transfer { }) } + /** + * Registers a listener that gets called whenever a new chunk of data is transferred. + * @param {function} Listener that takes a progress event. + */ + onProgress(listener: (event: ProgressEvent) => any): void { + this.ft.onprocess = listener; + } + /** * Aborts an in-progress transfer. The onerror callback is passed a FileTransferError * object which has an error code of FileTransferError.ABORT_ERR. */ - abort() { + abort(): void { return this.ft.abort(); } From 631d7f2d85177645f7bde295351d959bcfaa91ef Mon Sep 17 00:00:00 2001 From: glecaros Date: Sat, 7 May 2016 21:05:23 -0700 Subject: [PATCH 3/4] Added missing parameters to upload. --- src/plugins/filetransfer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/filetransfer.ts b/src/plugins/filetransfer.ts index 77dac2413..9de541d1f 100644 --- a/src/plugins/filetransfer.ts +++ b/src/plugins/filetransfer.ts @@ -155,7 +155,7 @@ export class Transfer { resolve(result); }, (err: FileTransferError) => { reject(err); - }); + }, options, trustAllHosts); }); } From 9ddde5762d9618b374d5ee594e4c9de0fc21041c Mon Sep 17 00:00:00 2001 From: glecaros Date: Sat, 14 May 2016 00:24:45 -0700 Subject: [PATCH 4/4] Reimplemented using CordovaInstance. Fixed wrapInstance signature to match how it is called. --- src/plugins/filetransfer.ts | 41 +++++++++++++++++-------------------- src/plugins/plugin.ts | 2 +- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/plugins/filetransfer.ts b/src/plugins/filetransfer.ts index 9de541d1f..52e9c8fb5 100644 --- a/src/plugins/filetransfer.ts +++ b/src/plugins/filetransfer.ts @@ -1,5 +1,4 @@ -import {Plugin, Cordova} from './plugin'; -import {Observable} from 'rxjs/Observable'; +import {Plugin, CordovaInstance} from './plugin'; declare var FileTransfer; @@ -134,10 +133,10 @@ export class Transfer { public static ABORT_ERR: number = 4; public static NOT_MODIFIED_ERR: number = 4; - ft: any; + private _objectInstance: any; constructor() { - this.ft = new FileTransfer(); + this._objectInstance = new FileTransfer(); } /** @@ -149,14 +148,12 @@ export class Transfer { * @param {boolean} trustAllHosts: Optional parameter, defaults to false. If set to true, it accepts all security certificates. This is useful since Android rejects self-signed security certificates. Not recommended for production use. Supported on Android and iOS. * @return Returns a Promise that resolves to a FileUploadResult and rejects with FileTransferError. */ + @CordovaInstance({ + successIndex: 2, + errorIndex: 3 + }) upload(fileUrl: string, url: string, options?: FileUploadOptions, trustAllHosts?: boolean): Promise { - return new Promise((resolve, reject) => { - this.ft.upload(fileUrl, url, (result: FileUploadResult) => { - resolve(result); - }, (err: FileTransferError) => { - reject(err); - }, options, trustAllHosts); - }); + return; } /** @@ -168,30 +165,30 @@ export class Transfer { * @param {object} Optional parameters, currently only supports headers (such as Authorization (Basic Authentication), etc). * @return Returns a Promise that resolves to a FileEntry object. */ + @CordovaInstance({ + successIndex: 2, + errorIndex: 3 + }) download(source: string, target: string, trustAllHosts?: boolean, options?: { [s: string]: any; }): Promise { - return new Promise((resolve, reject) => { - this.ft.download(source, target, (result: any) => { - resolve(result); - }, (err: FileTransferError) => { - reject(err); - }, trustAllHosts, options); - }) + return; } /** * Registers a listener that gets called whenever a new chunk of data is transferred. * @param {function} Listener that takes a progress event. */ + onProgress(listener: (event: ProgressEvent) => any): void { - this.ft.onprocess = listener; + this._objectInstance.onprogress = listener; } /** * Aborts an in-progress transfer. The onerror callback is passed a FileTransferError * object which has an error code of FileTransferError.ABORT_ERR. */ - abort(): void { - return this.ft.abort(); - } + @CordovaInstance({ + sync: true + }) + abort(): void {} } diff --git a/src/plugins/plugin.ts b/src/plugins/plugin.ts index 71a6a9f17..4b3f38107 100644 --- a/src/plugins/plugin.ts +++ b/src/plugins/plugin.ts @@ -160,7 +160,7 @@ function callInstance(pluginObj: any, methodName: string, args: any[], opts: any return pluginObj._objectInstance[methodName].apply(pluginObj._objectInstance, args); } -function wrapInstance (pluginObj: any, methodName: string, args: any[], opts: any = {}) { +function wrapInstance (pluginObj: any, methodName: string, opts: any = {}) { return (...args) => { if (opts.sync) { return callInstance(pluginObj, methodName, args, opts);