@ibm-aspera/sdk 0.2.9 → 0.2.29

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.
Files changed (110) hide show
  1. package/.editorconfig +13 -0
  2. package/.github/CODEOWNERS +1 -0
  3. package/.github/CODE_OF_CONDUCT.md +128 -0
  4. package/.github/CONTRIBUTING.md +147 -0
  5. package/.github/dependabot.yml +10 -0
  6. package/.github/workflows/ci.yml +39 -0
  7. package/.github/workflows/documentation.yml +44 -0
  8. package/.github/workflows/publish.yml +23 -0
  9. package/.github/workflows/version.yml +32 -0
  10. package/CHANGELOG.md +204 -0
  11. package/docs/DEVELOPMENT.md +38 -0
  12. package/eslint.config.js +104 -0
  13. package/example/README.md +7 -0
  14. package/example/index.html +14 -0
  15. package/example/package-lock.json +2989 -0
  16. package/example/package.json +30 -0
  17. package/example/public/404.html +5 -0
  18. package/example/public/sdk-code.js +326 -0
  19. package/example/src/App/App.scss +40 -0
  20. package/example/src/App/index.tsx +196 -0
  21. package/example/src/Views/AllTogether.tsx +26 -0
  22. package/example/src/Views/DragDrop.tsx +23 -0
  23. package/example/src/Views/Home.tsx +10 -0
  24. package/example/src/Views/Initialize.tsx +31 -0
  25. package/example/src/Views/Installer.tsx +154 -0
  26. package/example/src/Views/MonitorTransfers.tsx +88 -0
  27. package/example/src/Views/Other.tsx +24 -0
  28. package/example/src/Views/SelectItems.tsx +46 -0
  29. package/example/src/Views/StartTransfer.tsx +37 -0
  30. package/example/src/Views/Test.tsx +20 -0
  31. package/example/src/Views/Views.scss +111 -0
  32. package/example/src/helpers/index.ts +19 -0
  33. package/example/src/index.scss +47 -0
  34. package/example/src/main.tsx +17 -0
  35. package/example/src/vite-env.d.ts +2 -0
  36. package/example/tsconfig.json +30 -0
  37. package/example/vite.config.ts +23 -0
  38. package/jest.config.js +19 -0
  39. package/jest.setup.js +0 -0
  40. package/package.json +15 -21
  41. package/renovate.json +12 -0
  42. package/scripts/version.sh +24 -0
  43. package/src/app/core.ts +765 -0
  44. package/src/app/installer.ts +53 -0
  45. package/src/connect/core.ts +83 -0
  46. package/src/constants/constants.ts +19 -0
  47. package/src/constants/messages.ts +35 -0
  48. package/src/helpers/client/client.ts +11 -0
  49. package/src/helpers/client/http-client.ts +92 -0
  50. package/src/helpers/client/safari-client.ts +334 -0
  51. package/src/helpers/helpers.ts +253 -0
  52. package/src/helpers/http.ts +39 -0
  53. package/src/helpers/ws.ts +191 -0
  54. package/src/http-gateway/core.ts +273 -0
  55. package/src/http-gateway/download.ts +217 -0
  56. package/src/http-gateway/index.ts +19 -0
  57. package/src/http-gateway/models.ts +20 -0
  58. package/src/http-gateway/upload.ts +148 -0
  59. package/src/index.ts +72 -0
  60. package/src/models/aspera-sdk.model.ts +446 -0
  61. package/src/models/models.ts +740 -0
  62. package/tests/client.spec.ts +52 -0
  63. package/tests/core.spec.ts +13 -0
  64. package/tests/helpers.spec.ts +127 -0
  65. package/tests/http.spec.ts +14 -0
  66. package/tests/installer.spec.ts +135 -0
  67. package/tests/mocks.ts +11 -0
  68. package/tsconfig.json +14 -0
  69. package/tsconfig.module.json +16 -0
  70. package/typedoc.js +7 -0
  71. package/webpack.config.js +35 -0
  72. package/dist/commonjs/app/core.d.ts +0 -205
  73. package/dist/commonjs/app/core.js +0 -615
  74. package/dist/commonjs/app/installer.d.ts +0 -9
  75. package/dist/commonjs/app/installer.js +0 -50
  76. package/dist/commonjs/constants/constants.d.ts +0 -8
  77. package/dist/commonjs/constants/constants.js +0 -11
  78. package/dist/commonjs/constants/messages.d.ts +0 -35
  79. package/dist/commonjs/constants/messages.js +0 -38
  80. package/dist/commonjs/helpers/client/client.d.ts +0 -5
  81. package/dist/commonjs/helpers/client/client.js +0 -7
  82. package/dist/commonjs/helpers/client/http-client.d.ts +0 -42
  83. package/dist/commonjs/helpers/client/http-client.js +0 -84
  84. package/dist/commonjs/helpers/client/safari-client.d.ts +0 -101
  85. package/dist/commonjs/helpers/client/safari-client.js +0 -264
  86. package/dist/commonjs/helpers/helpers.d.ts +0 -109
  87. package/dist/commonjs/helpers/helpers.js +0 -249
  88. package/dist/commonjs/helpers/http.d.ts +0 -16
  89. package/dist/commonjs/helpers/http.js +0 -42
  90. package/dist/commonjs/helpers/ws.d.ts +0 -62
  91. package/dist/commonjs/helpers/ws.js +0 -176
  92. package/dist/commonjs/http-gateway/core.d.ts +0 -76
  93. package/dist/commonjs/http-gateway/core.js +0 -254
  94. package/dist/commonjs/http-gateway/download.d.ts +0 -14
  95. package/dist/commonjs/http-gateway/download.js +0 -186
  96. package/dist/commonjs/http-gateway/index.d.ts +0 -11
  97. package/dist/commonjs/http-gateway/index.js +0 -11
  98. package/dist/commonjs/http-gateway/models.d.ts +0 -16
  99. package/dist/commonjs/http-gateway/models.js +0 -2
  100. package/dist/commonjs/http-gateway/upload.d.ts +0 -14
  101. package/dist/commonjs/http-gateway/upload.js +0 -124
  102. package/dist/commonjs/index.d.ts +0 -8
  103. package/dist/commonjs/index.js +0 -104
  104. package/dist/commonjs/models/aspera-sdk.model.d.ts +0 -244
  105. package/dist/commonjs/models/aspera-sdk.model.js +0 -324
  106. package/dist/commonjs/models/models.d.ts +0 -692
  107. package/dist/commonjs/models/models.js +0 -2
  108. package/dist/js/aspera-sdk.js +0 -3
  109. package/dist/js/aspera-sdk.js.LICENSE.txt +0 -15
  110. package/dist/js/aspera-sdk.js.map +0 -1
@@ -0,0 +1,765 @@
1
+ import {messages} from '../constants/messages';
2
+ import {client} from '../helpers/client/client';
3
+ import {errorLog, generateErrorBody, generatePromiseObjects, isSafari, isValidTransferSpec, randomUUID, throwError} from '../helpers/helpers';
4
+ import { httpDownload, httpUpload } from '../http-gateway';
5
+ import {handleHttpGatewayDrop, httpGatewaySelectFileFolderDialog, httpGetAllTransfers, httpGetTransfer, httpRemoveTransfer, sendTransferUpdate} from '../http-gateway/core';
6
+ import {HttpGatewayInfo} from '../http-gateway/models';
7
+ import {asperaSdk} from '../index';
8
+ import {AsperaSdkInfo, AsperaSdkClientInfo, TransferResponse} from '../models/aspera-sdk.model';
9
+ import {CustomBrandingOptions, DataTransferResponse, AsperaSdkSpec, BrowserStyleFile, AsperaSdkTransfer, FileDialogOptions, FolderDialogOptions, InitOptions, ModifyTransferOptions, ResumeTransferOptions, SafariExtensionEvent, TransferSpec, WebsocketEvent} from '../models/models';
10
+ import {registerActivityCallback as oldHttpRegisterActivityCallback} from '@ibm-aspera/http-gateway-sdk-js';
11
+ import {Connect, ConnectInstaller} from '@ibm-aspera/connect-sdk-js';
12
+ import {initConnect} from '../connect/core';
13
+ import * as ConnectTypes from '@ibm-aspera/connect-sdk-js/dist/esm/core/types';
14
+
15
+ /**
16
+ * Check if IBM Aspera for Desktop connection works. This function is called by init
17
+ * when initializing the SDK. This function can be used at any point for checking.
18
+ *
19
+ * @returns a promise that resolves if server can connect or rejects if not
20
+ */
21
+ export const testConnection = (): Promise<any> => {
22
+ if (asperaSdk.useHttpGateway || asperaSdk.useConnect) {
23
+ return Promise.resolve(asperaSdk.globals.sdkResponseData);
24
+ }
25
+
26
+ return client.request('get_info')
27
+ .then((data: AsperaSdkClientInfo) => {
28
+ asperaSdk.globals.asperaSdkInfo = data;
29
+ asperaSdk.globals.asperaAppVerified = true;
30
+ return asperaSdk.globals.sdkResponseData;
31
+ });
32
+ };
33
+
34
+ /**
35
+ * Initialize drag and drop. HTTP Gateway and Connect does not need to init.
36
+ * Ignore if only HTTP Gateway
37
+ * @param initCall - Indicate if called via init flow and should not reject
38
+ *
39
+ * @returns a promise that resolves if the initialization was successful or not
40
+ */
41
+ export const initDragDrop = (initCall?: boolean): Promise<boolean> => {
42
+ if (asperaSdk.useHttpGateway || asperaSdk.useConnect) {
43
+ return Promise.resolve(true);
44
+ } else if (!asperaSdk.isReady) {
45
+ return throwError(messages.serverNotVerified);
46
+ }
47
+
48
+ const promiseInfo = generatePromiseObjects();
49
+
50
+ client.request('init_drag_drop')
51
+ .then((data: boolean) => promiseInfo.resolver(data))
52
+ .catch(error => {
53
+ errorLog(messages.dragDropInitFailed, error);
54
+
55
+ if (initCall) {
56
+ promiseInfo.resolver(false);
57
+ errorLog(messages.dragDropInitFailedInit, error);
58
+ } else {
59
+ promiseInfo.rejecter(generateErrorBody(messages.dragDropInitFailed, error));
60
+ }
61
+ });
62
+
63
+ return promiseInfo.promise;
64
+ };
65
+
66
+ /**
67
+ * Initialize IBM Aspera client. If client cannot (reject/catch), then
68
+ * client should attempt fixing server URL or trying again. If still fails disable UI elements.
69
+ *
70
+ * @param options initialization options:
71
+ *
72
+ * - `appId` the unique ID for the website. Transfers initiated during this session
73
+ * will be associated with this ID. It is recommended to use a unique ID to keep transfer
74
+ * information private from other websites.
75
+ *
76
+ * - `supportMultipleUsers` when enabled (defaults to false), the SDK will iterate over a port
77
+ * range and generate a session id to determine the running instance of the desktop app for the
78
+ * current user. This is needed when multiple users may be logged into the same machine
79
+ * simultaneously, for example on a Windows Server.
80
+ *
81
+ * @returns a promise that resolves if IBM Aspera Desktop is running properly or
82
+ * rejects if unable to connect
83
+ */
84
+ export const init = (options?: InitOptions): Promise<any> => {
85
+ const appId = options?.appId ?? randomUUID();
86
+
87
+ asperaSdk.globals.appId = appId;
88
+
89
+ // Watch for old HTTP Gateway transfers in case used.
90
+ oldHttpRegisterActivityCallback(oldHttpTransfers => {
91
+ oldHttpTransfers.transfers.forEach(oldHttpTransfer => {
92
+ sendTransferUpdate(oldHttpTransfer as unknown as AsperaSdkTransfer);
93
+ });
94
+ });
95
+
96
+ // For now ignore multi user support in Safari
97
+ if (options?.supportMultipleUsers && !isSafari()) {
98
+ asperaSdk.globals.supportMultipleUsers = true;
99
+ asperaSdk.globals.sessionId = randomUUID();
100
+ }
101
+
102
+ const handleErrors = (error: unknown) => {
103
+ errorLog(messages.serverError, error);
104
+ asperaSdk.globals.asperaAppVerified = false;
105
+ throw generateErrorBody(messages.serverError, error);
106
+ };
107
+
108
+ const getConnectStartCalls = (): Promise<unknown> => {
109
+ asperaSdk.globals.connect = new Connect({
110
+ minVersion: options.connectSettings.minVersion || '3.10.1',
111
+ dragDropEnabled: options.connectSettings.dragDropEnabled,
112
+ connectMethod: options.connectSettings.method,
113
+ });
114
+ asperaSdk.globals.connectInstaller = new ConnectInstaller({
115
+ sdkLocation: options.connectSettings.sdkLocation,
116
+ correlationId: options.connectSettings.correlationId,
117
+ style: 'carbon',
118
+ });
119
+
120
+ asperaSdk.globals.connectAW4 = {
121
+ Connect,
122
+ ConnectInstaller,
123
+ };
124
+
125
+ return initConnect(!options.connectSettings.hideIncludedInstaller);
126
+ };
127
+
128
+ const getDesktopStartCalls = (): Promise<unknown> => {
129
+ return asperaSdk.activityTracking.setup()
130
+ .then(() => testConnection())
131
+ .then(() => initDragDrop(true))
132
+ .then(() => asperaSdk.globals.sdkResponseData)
133
+ .catch(handleErrors);
134
+ };
135
+
136
+ if (options?.httpGatewaySettings?.url && !asperaSdk.globals.httpGatewayVerified) {
137
+ let finalHttpGatewayUrl = options.httpGatewaySettings.url.trim();
138
+
139
+ if (finalHttpGatewayUrl.indexOf('http') !== 0) {
140
+ finalHttpGatewayUrl = `https://${finalHttpGatewayUrl}`;
141
+ }
142
+
143
+ if (finalHttpGatewayUrl.endsWith('/')) {
144
+ finalHttpGatewayUrl = finalHttpGatewayUrl.slice(0, -1);
145
+ }
146
+
147
+ asperaSdk.globals.httpGatewayUrl = finalHttpGatewayUrl;
148
+
149
+ return fetch(`${asperaSdk.globals.httpGatewayUrl}/info`, {method: 'GET'}).then(response => {
150
+ return response.json().then(responseData => {
151
+ if (response.status >= 400) {
152
+ throw Error(responseData);
153
+ }
154
+
155
+ return responseData;
156
+ });
157
+ }).then((response: HttpGatewayInfo) => {
158
+ asperaSdk.globals.httpGatewayInfo = response;
159
+ asperaSdk.globals.httpGatewayVerified = true;
160
+
161
+ const iframeContainer = document.createElement('div');
162
+ iframeContainer.id = 'aspera-http-gateway-iframes';
163
+ iframeContainer.style = 'display: none;';
164
+ document.body.appendChild(iframeContainer);
165
+
166
+ asperaSdk.globals.httpGatewayIframeContainer = iframeContainer;
167
+
168
+ if (options?.httpGatewaySettings?.forceGateway) {
169
+ return Promise.resolve(asperaSdk.globals.sdkResponseData);
170
+ } else {
171
+ return options?.connectSettings?.useConnect ? getConnectStartCalls() : getDesktopStartCalls();
172
+ }
173
+ }).catch(error => {
174
+ // If HTTP Gateway fails log and move on to desktop
175
+ errorLog(messages.httpInitFail, error);
176
+
177
+ return options?.connectSettings?.useConnect ? getConnectStartCalls() : getDesktopStartCalls();
178
+ });
179
+ }
180
+
181
+ return options?.connectSettings?.useConnect ? getConnectStartCalls() : getDesktopStartCalls();
182
+ };
183
+
184
+ /**
185
+ * Start a transfer
186
+ *
187
+ * @param transferSpec standard transferSpec for transfer
188
+ * @param asperaSdkSpec IBM Aspera settings when starting a transfer.
189
+ *
190
+ * @returns a promise that resolves if transfer initiation is successful and rejects if transfer cannot be started
191
+ */
192
+ export const startTransfer = (transferSpec: TransferSpec, asperaSdkSpec: AsperaSdkSpec): Promise<AsperaSdkTransfer> => {
193
+ if (!isValidTransferSpec(transferSpec)) {
194
+ return throwError(messages.notValidTransferSpec, {transferSpec});
195
+ }
196
+
197
+ if (asperaSdk.useHttpGateway) {
198
+ return transferSpec.direction === 'receive' ? httpDownload(transferSpec, asperaSdkSpec) : httpUpload(transferSpec, asperaSdkSpec);
199
+ } else if (asperaSdk.useConnect) {
200
+ return asperaSdk.globals.connect.startTransferPromise(transferSpec as unknown as ConnectTypes.TransferSpec, asperaSdkSpec).then(response => {
201
+ return response.transfer_specs[0] as unknown as AsperaSdkTransfer;
202
+ });
203
+ } else if (!asperaSdk.isReady) {
204
+ return throwError(messages.serverNotVerified);
205
+ }
206
+
207
+ const promiseInfo = generatePromiseObjects();
208
+
209
+ const payload = {
210
+ transfer_spec: transferSpec,
211
+ desktop_spec: asperaSdkSpec,
212
+ app_id: asperaSdk.globals.appId,
213
+ };
214
+
215
+ client.request('start_transfer', payload)
216
+ .then((data: any) => promiseInfo.resolver(data))
217
+ .catch(error => {
218
+ errorLog(messages.transferFailed, error);
219
+ promiseInfo.rejecter(generateErrorBody(messages.transferFailed, error));
220
+ });
221
+
222
+ return promiseInfo.promise;
223
+ };
224
+
225
+ /**
226
+ * Register a callback event for getting transfer updates
227
+ *
228
+ * @param callback callback function to receive transfers
229
+ *
230
+ * @returns ID representing the callback for deregistration purposes
231
+ */
232
+ export const registerActivityCallback = (callback: (transfers: TransferResponse) => void): string => {
233
+ return asperaSdk.activityTracking.setCallback(callback);
234
+ };
235
+
236
+ /**
237
+ * Remove a callback from the transfer callback
238
+ *
239
+ * @param id the ID returned by `registerActivityCallback`
240
+ */
241
+ export const deregisterActivityCallback = (id: string): void => {
242
+ asperaSdk.activityTracking.removeCallback(id);
243
+ };
244
+
245
+ /**
246
+ * Register a callback for getting updates about the connection status of IBM Aspera SDK.
247
+ *
248
+ * For example, to be notified of when the SDK loses connection with the application or connection
249
+ * is re-established. This can be useful if you want to handle the case where the user quits IBM Aspera
250
+ * after `init` has already been called, and want to prompt the user to relaunch the application.
251
+ *
252
+ * @param callback callback function to receive events
253
+ *
254
+ * @returns ID representing the callback for deregistration purposes
255
+ */
256
+ export const registerStatusCallback = (callback: (status: WebsocketEvent) => void): string => {
257
+ return asperaSdk.activityTracking.setWebSocketEventCallback(callback);
258
+ };
259
+
260
+ /**
261
+ * Remove a callback from getting connection status events.
262
+ *
263
+ * @param id the ID returned by `registerStatusCallback`
264
+ */
265
+ export const deregisterStatusCallback = (id: string): void => {
266
+ asperaSdk.activityTracking.removeWebSocketEventCallback(id);
267
+ };
268
+
269
+ /**
270
+ * Remove a transfer. This will stop the transfer if it is in progress.
271
+ *
272
+ * @param id transfer uuid
273
+ *
274
+ * @returns a promise that resolves if transfer is removed and rejects if transfer cannot be removed
275
+ */
276
+ export const removeTransfer = (id: string): Promise<any> => {
277
+ if (asperaSdk.useHttpGateway) {
278
+ return httpRemoveTransfer(id);
279
+ } else if (asperaSdk.useConnect) {
280
+ return asperaSdk.globals.connect.removeTransfer(id);
281
+ }
282
+
283
+ if (!asperaSdk.isReady) {
284
+ return throwError(messages.serverNotVerified);
285
+ }
286
+
287
+ const promiseInfo = generatePromiseObjects();
288
+
289
+ const payload = {
290
+ transfer_id: id,
291
+ };
292
+
293
+ client.request('remove_transfer', payload)
294
+ .then((data: any) => promiseInfo.resolver(data))
295
+ .catch(error => {
296
+ errorLog(messages.removeTransferFailed, error);
297
+ promiseInfo.rejecter(generateErrorBody(messages.removeTransferFailed, error));
298
+ });
299
+
300
+ return promiseInfo.promise;
301
+ };
302
+
303
+ /**
304
+ * Stop a transfer.
305
+ *
306
+ * @param id transfer uuid
307
+ *
308
+ * @returns a promise that resolves if transfer is stopped and rejects if transfer cannot be stopped
309
+ */
310
+ export const stopTransfer = (id: string): Promise<any> => {
311
+ if (asperaSdk.useConnect) {
312
+ return asperaSdk.globals.connect.stopTransfer(id);
313
+ }
314
+
315
+ if (!asperaSdk.isReady) {
316
+ return throwError(messages.serverNotVerified);
317
+ }
318
+
319
+ const promiseInfo = generatePromiseObjects();
320
+
321
+ const payload = {
322
+ transfer_id: id,
323
+ };
324
+
325
+ client.request('stop_transfer', payload)
326
+ .then((data: any) => promiseInfo.resolver(data))
327
+ .catch(error => {
328
+ errorLog(messages.stopTransferFailed, error);
329
+ promiseInfo.rejecter(generateErrorBody(messages.stopTransferFailed, error));
330
+ });
331
+
332
+ return promiseInfo.promise;
333
+ };
334
+
335
+ /**
336
+ * Resume a paused or failed transfer.
337
+ *
338
+ * @param id transfer uuid
339
+ * @param options resume transfer options
340
+ *
341
+ * @returns a promise that resolves with the new transfer object if transfer is resumed
342
+ */
343
+ export const resumeTransfer = (id: string, options?: ResumeTransferOptions): Promise<AsperaSdkTransfer> => {
344
+ if (asperaSdk.useConnect) {
345
+ return asperaSdk.globals.connect.resumeTransfer(id, options).then(response => {
346
+ return response.transfer_spec as unknown as AsperaSdkTransfer;
347
+ });
348
+ }
349
+
350
+ if (!asperaSdk.isReady) {
351
+ return throwError(messages.serverNotVerified);
352
+ }
353
+
354
+ const promiseInfo = generatePromiseObjects();
355
+
356
+ const payload = {
357
+ transfer_id: id,
358
+ transfer_spec: options,
359
+ };
360
+
361
+ client.request('resume_transfer', payload)
362
+ .then((data: AsperaSdkTransfer) => promiseInfo.resolver(data))
363
+ .catch(error => {
364
+ errorLog(messages.resumeTransferFailed, error);
365
+ promiseInfo.rejecter(generateErrorBody(messages.resumeTransferFailed, error));
366
+ });
367
+
368
+ return promiseInfo.promise;
369
+ };
370
+
371
+ /**
372
+ * Displays a file browser dialog for the user to select files.
373
+ *
374
+ * @param options file dialog options
375
+ *
376
+ * @returns a promise that resolves with the selected file(s) and rejects if user cancels dialog
377
+ */
378
+ export const showSelectFileDialog = (options?: FileDialogOptions): Promise<DataTransferResponse> => {
379
+ if (asperaSdk.useHttpGateway) {
380
+ return httpGatewaySelectFileFolderDialog(options, false);
381
+ } else if (asperaSdk.useConnect) {
382
+ return asperaSdk.globals.connect.showSelectFileDialogPromise(options).then(response => {
383
+ return response as unknown as DataTransferResponse;
384
+ });
385
+ } else if (!asperaSdk.isReady) {
386
+ return throwError(messages.serverNotVerified);
387
+ }
388
+
389
+ const promiseInfo = generatePromiseObjects();
390
+
391
+ const payload = {
392
+ options: options || {},
393
+ app_id: asperaSdk.globals.appId,
394
+ };
395
+
396
+ client.request('show_file_dialog', payload)
397
+ .then((data: any) => promiseInfo.resolver(data))
398
+ .catch(error => {
399
+ errorLog(messages.showSelectFileDialogFailed, error);
400
+ promiseInfo.rejecter(generateErrorBody(messages.showSelectFileDialogFailed, error));
401
+ });
402
+
403
+ return promiseInfo.promise;
404
+ };
405
+
406
+ /**
407
+ * Displays a folder browser dialog for the user to select folders.
408
+ *
409
+ * @param options folder dialog options
410
+ *
411
+ * @returns a promise that resolves with the selected folder(s) and rejects if user cancels dialog
412
+ */
413
+ export const showSelectFolderDialog = (options?: FolderDialogOptions): Promise<DataTransferResponse> => {
414
+ if (asperaSdk.useHttpGateway) {
415
+ return httpGatewaySelectFileFolderDialog(options, true);
416
+ } else if (asperaSdk.useConnect) {
417
+ return asperaSdk.globals.connect.showSelectFolderDialogPromise(options).then(response => {
418
+ return response as unknown as DataTransferResponse;
419
+ });
420
+ } else if (!asperaSdk.isReady) {
421
+ return throwError(messages.serverNotVerified);
422
+ }
423
+
424
+ const promiseInfo = generatePromiseObjects();
425
+
426
+ const payload = {
427
+ options: options || {},
428
+ app_id: asperaSdk.globals.appId,
429
+ };
430
+
431
+ client.request('show_folder_dialog', payload)
432
+ .then((data: any) => promiseInfo.resolver(data))
433
+ .catch(error => {
434
+ errorLog(messages.showSelectFolderDialogFailed, error);
435
+ promiseInfo.rejecter(generateErrorBody(messages.showSelectFolderDialogFailed, error));
436
+ });
437
+
438
+ return promiseInfo.promise;
439
+ };
440
+
441
+ /**
442
+ * Opens the IBM Aspera preferences page.
443
+ *
444
+ * @returns a promise that resolves when the preferences page is opened.
445
+ */
446
+ export const showPreferences = (): Promise<any> => {
447
+ if (asperaSdk.useConnect) {
448
+ return asperaSdk.globals.connect.showPreferences();
449
+ }
450
+
451
+ if (!asperaSdk.isReady) {
452
+ return throwError(messages.serverNotVerified);
453
+ }
454
+
455
+ const promiseInfo = generatePromiseObjects();
456
+
457
+ client.request('open_preferences')
458
+ .then((data: any) => promiseInfo.resolver(data))
459
+ .catch(error => {
460
+ errorLog(messages.showPreferencesFailed, error);
461
+ promiseInfo.rejecter(generateErrorBody(messages.showPreferencesFailed, error));
462
+ });
463
+
464
+ return promiseInfo.promise;
465
+ };
466
+
467
+ /**
468
+ * Get all transfers associated with the current application.
469
+ *
470
+ * @returns a promise that resolves with an array of transfers.
471
+ */
472
+ export const getAllTransfers = (): Promise<AsperaSdkTransfer[]> => {
473
+ const promiseInfo = generatePromiseObjects();
474
+
475
+ if (asperaSdk.useHttpGateway) {
476
+ return Promise.resolve(httpGetAllTransfers());
477
+ } else if (asperaSdk.useConnect) {
478
+ asperaSdk.globals.connect.getAllTransfers({
479
+ success: data => {
480
+ promiseInfo.resolver(data.transfers);
481
+ }, error: error => {
482
+ promiseInfo.rejecter(error);
483
+ },
484
+ });
485
+
486
+ return promiseInfo.promise;
487
+ }
488
+
489
+ if (!asperaSdk.isReady) {
490
+ return throwError(messages.serverNotVerified);
491
+ }
492
+
493
+ const payload = {
494
+ app_id: asperaSdk.globals.appId,
495
+ };
496
+
497
+ client.request('get_all_transfers', payload)
498
+ .then((data: AsperaSdkTransfer[]) => promiseInfo.resolver(data))
499
+ .catch(error => {
500
+ errorLog(messages.getAllTransfersFailed, error);
501
+ promiseInfo.rejecter(generateErrorBody(messages.getAllTransfersFailed, error));
502
+ });
503
+
504
+ return promiseInfo.promise;
505
+ };
506
+
507
+ /**
508
+ * Get a specific transfer by ID.
509
+ *
510
+ * @param id transfer uuid
511
+ *
512
+ * @returns a promise that resolves with the transfer.
513
+ */
514
+ export const getTransfer = (id: string): Promise<AsperaSdkTransfer> => {
515
+ if (asperaSdk.useHttpGateway) {
516
+ const transfer = httpGetTransfer(id);
517
+
518
+ if (transfer) {
519
+ return Promise.resolve(transfer);
520
+ } else {
521
+ return Promise.reject(generateErrorBody(messages.getTransferFailed, {reason: 'Not found'}));
522
+ }
523
+ } else if (asperaSdk.useConnect) {
524
+ return asperaSdk.globals.connect.getTransfer(id).then(response => {
525
+ return response.transfer_info as unknown as AsperaSdkTransfer;
526
+ });
527
+ }
528
+
529
+ if (!asperaSdk.isReady) {
530
+ return throwError(messages.serverNotVerified);
531
+ }
532
+
533
+ const promiseInfo = generatePromiseObjects();
534
+
535
+ const payload = {
536
+ transfer_id: id,
537
+ };
538
+
539
+ client.request('get_transfer', payload)
540
+ .then((data: AsperaSdkTransfer) => promiseInfo.resolver(data))
541
+ .catch(error => {
542
+ errorLog(messages.getTransferFailed, error);
543
+ promiseInfo.rejecter(generateErrorBody(messages.getTransferFailed, error));
544
+ });
545
+
546
+ return promiseInfo.promise;
547
+ };
548
+
549
+ /**
550
+ * Opens and highlights the downloaded file in Finder or Windows Explorer. If multiple files,
551
+ * then only the first file will be selected.
552
+ *
553
+ * @param id transfer uuid
554
+ *
555
+ * @returns a promise that resolves if the file can be shown and rejects if not
556
+ */
557
+ export const showDirectory = (id: string): Promise<any> => {
558
+ if (asperaSdk.useConnect) {
559
+ return asperaSdk.globals.connect.showDirectory(id);
560
+ }
561
+
562
+ if (!asperaSdk.isReady) {
563
+ return throwError(messages.serverNotVerified);
564
+ }
565
+
566
+ const promiseInfo = generatePromiseObjects();
567
+
568
+ const payload = {
569
+ transfer_id: id,
570
+ };
571
+
572
+ client.request('show_directory', payload)
573
+ .then((data: any) => promiseInfo.resolver(data))
574
+ .catch(error => {
575
+ errorLog(messages.showDirectoryFailed, error);
576
+ promiseInfo.rejecter(generateErrorBody(messages.showDirectoryFailed, error));
577
+ });
578
+
579
+ return promiseInfo.promise;
580
+ };
581
+
582
+ /**
583
+ * Modify the speed of a running transfer.
584
+ *
585
+ * @param id transfer uuid
586
+ * @param options transfer rate options
587
+ *
588
+ * @returns a promise that resolves if the transfer rate can be modified and rejects if not
589
+ */
590
+ export const modifyTransfer = (id: string, options: ModifyTransferOptions): Promise<AsperaSdkTransfer> => {
591
+ if (asperaSdk.useConnect) {
592
+ return asperaSdk.globals.connect.modifyTransfer(id, options).then(response => {
593
+ return response as unknown as AsperaSdkTransfer;
594
+ });
595
+ }
596
+
597
+ if (!asperaSdk.isReady) {
598
+ return throwError(messages.serverNotVerified);
599
+ }
600
+
601
+ const promiseInfo = generatePromiseObjects();
602
+
603
+ const payload = {
604
+ transfer_id: id,
605
+ transfer_spec: options,
606
+ };
607
+
608
+ client.request('modify_transfer', payload)
609
+ .then((data: any) => promiseInfo.resolver(data))
610
+ .catch(error => {
611
+ errorLog(messages.modifyTransferFailed, error);
612
+ promiseInfo.rejecter(generateErrorBody(messages.modifyTransferFailed, error));
613
+ });
614
+
615
+ return promiseInfo.promise;
616
+ };
617
+
618
+ /**
619
+ * Set the custom branding template to be used by IBM Aspera. If the app is already
620
+ * configured to use a different branding, then the branding template you specify will be
621
+ * stored by the app, allowing the end user to switch at any point.
622
+ *
623
+ * @param id custom branding template id. This should be consistent across page loads.
624
+ * @param options custom branding options
625
+ *
626
+ * @returns a promise that resolves if the branding was properly set.
627
+ */
628
+ export const setBranding = (id: string, options: CustomBrandingOptions): Promise<any> => {
629
+ if (!asperaSdk.isReady) {
630
+ return throwError(messages.serverNotVerified);
631
+ }
632
+
633
+ const promiseInfo = generatePromiseObjects();
634
+
635
+ const branding = {
636
+ id,
637
+ name: options.name,
638
+ theme: options.theme,
639
+ };
640
+
641
+ const payload = {
642
+ branding,
643
+ };
644
+
645
+ client.request('update_branding', payload)
646
+ .then((data: any) => promiseInfo.resolver(data))
647
+ .catch(error => {
648
+ errorLog(messages.setBrandingFailed, error);
649
+ promiseInfo.rejecter(generateErrorBody(messages.setBrandingFailed, error));
650
+ });
651
+
652
+ return promiseInfo.promise;
653
+ };
654
+
655
+ /**
656
+ * Create a dropzone for the given element selector.
657
+ *
658
+ * @param callback the function to call once the files are dropped
659
+ * @param elementSelector the selector of the element on the page that should watch for drop events
660
+ * @param connectOptions options for connect
661
+ */
662
+ export const createDropzone = (
663
+ callback: (data: {event: DragEvent; files: DataTransferResponse}) => void,
664
+ elementSelector: string,
665
+ connectOptions?: ConnectTypes.DragDropOptions,
666
+ ): void => {
667
+ if (asperaSdk.useConnect) {
668
+ asperaSdk.globals.connect.setDragDropTargets(elementSelector, connectOptions, result => {
669
+ callback({
670
+ event: result.event,
671
+ files: result.files as unknown as DataTransferResponse,
672
+ });
673
+ });
674
+
675
+ return;
676
+ }
677
+
678
+ const elements = document.querySelectorAll(elementSelector);
679
+ if (!elements || !elements.length) {
680
+ errorLog(messages.unableToFindElementOnPage);
681
+ return;
682
+ }
683
+
684
+ const dragEvent = (event: DragEvent) => {
685
+ event.preventDefault();
686
+ };
687
+
688
+ const dropEvent = (event: DragEvent) => {
689
+ event.preventDefault();
690
+ if (event.dataTransfer && event.dataTransfer.files && event.dataTransfer.files.length && event.dataTransfer.files[0]) {
691
+ const files: BrowserStyleFile[] = [];
692
+
693
+ for (let i = 0; i < event.dataTransfer.files.length; i++) {
694
+ const file = event.dataTransfer.files[i];
695
+ files.push({
696
+ lastModified: file.lastModified,
697
+ name: file.name,
698
+ size: file.size,
699
+ type: file.type
700
+ });
701
+ }
702
+
703
+ const payload = {
704
+ files,
705
+ app_id: asperaSdk.globals.appId,
706
+ };
707
+
708
+ if (asperaSdk.isReady) {
709
+ client.request('dropped_files', payload)
710
+ .then((data: any) => callback({event, files: data}))
711
+ .catch(error => {
712
+ errorLog(messages.unableToReadDropped, error);
713
+ });
714
+ } else if (asperaSdk.httpGatewayIsReady) {
715
+ handleHttpGatewayDrop(event.dataTransfer.items, callback, event);
716
+ }
717
+ }
718
+ };
719
+
720
+ elements.forEach(element => {
721
+ element.addEventListener('dragover', dragEvent);
722
+ element.addEventListener('drop', dropEvent);
723
+ asperaSdk.globals.dropZonesCreated.set(elementSelector, [{event: 'dragover', callback: dragEvent}, {event: 'drop', callback: dropEvent}]);
724
+ });
725
+ };
726
+
727
+ /**
728
+ * Remove dropzone.
729
+ *
730
+ * @param elementSelector the selector of the element on the page that should remove
731
+ */
732
+ export const removeDropzone = (elementSelector: string): void => {
733
+ const foundDropzone = asperaSdk.globals.dropZonesCreated.get(elementSelector);
734
+
735
+ if (foundDropzone) {
736
+ foundDropzone.forEach(data => {
737
+ const elements = document.querySelectorAll(elementSelector);
738
+
739
+ if (elements && elements.length) {
740
+ elements.forEach(element => {
741
+ element.removeEventListener(data.event, data.callback);
742
+ });
743
+ }
744
+ });
745
+ }
746
+ };
747
+
748
+ /**
749
+ * Get metadata about the IBM Aspera installation.
750
+ *
751
+ * @returns a promise that returns information about the user's IBM Aspera installation.
752
+ */
753
+ export const getInfo = (): Promise<AsperaSdkInfo> => {
754
+ if (asperaSdk.useHttpGateway || asperaSdk.useConnect) {
755
+ return Promise.resolve(asperaSdk.globals.sdkResponseData);
756
+ }
757
+
758
+ if (!asperaSdk.isReady) {
759
+ return throwError(messages.serverNotVerified);
760
+ }
761
+
762
+ return new Promise((resolve, _) => {
763
+ resolve(asperaSdk.globals.sdkResponseData);
764
+ });
765
+ };