@itwin/core-mobile 5.0.0-dev.8 → 5.0.0-dev.82
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/CHANGELOG.md +46 -1
- package/lib/cjs/backend/MobileAuthorizationBackend.js +4 -5
- package/lib/cjs/backend/MobileAuthorizationBackend.js.map +1 -1
- package/lib/cjs/backend/MobileFileHandler.js +2 -0
- package/lib/cjs/backend/MobileFileHandler.js.map +1 -1
- package/lib/cjs/backend/MobileHost.js +34 -33
- package/lib/cjs/backend/MobileHost.js.map +1 -1
- package/lib/cjs/backend/MobileRpcServer.d.ts +1 -1
- package/lib/cjs/backend/MobileRpcServer.d.ts.map +1 -1
- package/lib/cjs/backend/MobileRpcServer.js +18 -12
- package/lib/cjs/backend/MobileRpcServer.js.map +1 -1
- package/lib/cjs/backend/Request.js +3 -0
- package/lib/cjs/backend/Request.js.map +1 -1
- package/lib/cjs/common/MobileEventLoop.js +2 -2
- package/lib/cjs/common/MobileEventLoop.js.map +1 -1
- package/lib/cjs/common/MobileIpc.d.ts.map +1 -1
- package/lib/cjs/common/MobileIpc.js +69 -6
- package/lib/cjs/common/MobileIpc.js.map +1 -1
- package/lib/cjs/common/MobilePush.js +4 -2
- package/lib/cjs/common/MobilePush.js.map +1 -1
- package/lib/cjs/common/MobileRpcManager.js +8 -10
- package/lib/cjs/common/MobileRpcManager.js.map +1 -1
- package/lib/cjs/common/MobileRpcProtocol.js +13 -11
- package/lib/cjs/common/MobileRpcProtocol.js.map +1 -1
- package/lib/cjs/common/MobileRpcRequest.js +4 -7
- package/lib/cjs/common/MobileRpcRequest.js.map +1 -1
- package/lib/cjs/frontend/MobileApp.js +7 -7
- package/lib/cjs/frontend/MobileApp.js.map +1 -1
- package/lib/cjs/frontend/MobileAuthorizationFrontend.js +4 -5
- package/lib/cjs/frontend/MobileAuthorizationFrontend.js.map +1 -1
- package/package.json +14 -14
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,51 @@
|
|
|
1
1
|
# Change Log - @itwin/core-mobile
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Tue, 11 Mar 2025 15:27:53 GMT and should not be manually modified.
|
|
4
|
+
|
|
5
|
+
## 4.10.10
|
|
6
|
+
Tue, 11 Mar 2025 15:25:11 GMT
|
|
7
|
+
|
|
8
|
+
_Version update only_
|
|
9
|
+
|
|
10
|
+
## 4.10.9
|
|
11
|
+
Tue, 11 Mar 2025 05:17:33 GMT
|
|
12
|
+
|
|
13
|
+
_Version update only_
|
|
14
|
+
|
|
15
|
+
## 4.10.8
|
|
16
|
+
Thu, 06 Mar 2025 14:13:37 GMT
|
|
17
|
+
|
|
18
|
+
_Version update only_
|
|
19
|
+
|
|
20
|
+
## 4.10.7
|
|
21
|
+
Tue, 18 Feb 2025 17:27:03 GMT
|
|
22
|
+
|
|
23
|
+
_Version update only_
|
|
24
|
+
|
|
25
|
+
## 4.10.6
|
|
26
|
+
Fri, 24 Jan 2025 08:02:40 GMT
|
|
27
|
+
|
|
28
|
+
_Version update only_
|
|
29
|
+
|
|
30
|
+
## 4.10.5
|
|
31
|
+
Tue, 21 Jan 2025 21:56:45 GMT
|
|
32
|
+
|
|
33
|
+
_Version update only_
|
|
34
|
+
|
|
35
|
+
## 4.10.4
|
|
36
|
+
Mon, 13 Jan 2025 14:06:43 GMT
|
|
37
|
+
|
|
38
|
+
_Version update only_
|
|
39
|
+
|
|
40
|
+
## 4.10.3
|
|
41
|
+
Mon, 06 Jan 2025 14:00:13 GMT
|
|
42
|
+
|
|
43
|
+
_Version update only_
|
|
44
|
+
|
|
45
|
+
## 4.10.2
|
|
46
|
+
Thu, 21 Nov 2024 15:22:20 GMT
|
|
47
|
+
|
|
48
|
+
_Version update only_
|
|
4
49
|
|
|
5
50
|
## 4.10.1
|
|
6
51
|
Thu, 14 Nov 2024 18:11:00 GMT
|
|
@@ -13,11 +13,10 @@ const MobileHost_1 = require("./MobileHost");
|
|
|
13
13
|
* @internal
|
|
14
14
|
*/
|
|
15
15
|
class MobileAuthorizationBackend {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
16
|
+
_accessToken = "";
|
|
17
|
+
_expirationDate;
|
|
18
|
+
_expiryBuffer = 60 * 10; // ten minutes
|
|
19
|
+
_fetchingToken = false;
|
|
21
20
|
get _hasExpired() {
|
|
22
21
|
return this._expirationDate !== undefined && this._expirationDate.getTime() - Date.now() <= this._expiryBuffer * 1000;
|
|
23
22
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MobileAuthorizationBackend.js","sourceRoot":"","sources":["../../../src/backend/MobileAuthorizationBackend.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAIH,6CAA0C;AAE1C;;GAEG;AACH,MAAa,0BAA0B;
|
|
1
|
+
{"version":3,"file":"MobileAuthorizationBackend.js","sourceRoot":"","sources":["../../../src/backend/MobileAuthorizationBackend.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAIH,6CAA0C;AAE1C;;GAEG;AACH,MAAa,0BAA0B;IAC7B,YAAY,GAAgB,EAAE,CAAC;IAC/B,eAAe,CAAmB;IAClC,aAAa,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,cAAc;IACvC,cAAc,GAAG,KAAK,CAAC;IAE/B,IAAY,WAAW;QACrB,OAAO,IAAI,CAAC,eAAe,KAAK,SAAS,IAAI,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;IACxH,CAAC;IAEM,KAAK,CAAC,cAAc;QACzB,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,0FAA0F;YAC1F,4FAA4F;YAC5F,OAAO,EAAE,CAAC,CAAC,oDAAoD;QACjE,CAAC;QAED,IAAI,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YAC3C,OAAO,IAAI,CAAC,YAAY,CAAC;QAC3B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC;gBACH,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;gBAC3B,MAAM,MAAM,GAAG,MAAM,uBAAU,CAAC,kBAAkB,EAAE,CAAC;gBACrD,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;gBAC9B,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBACnE,OAAO,IAAI,CAAC,YAAY,CAAC;YAC3B,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,EAAE,CAAC;YACZ,CAAC;oBAAS,CAAC;gBACT,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;YAC9B,CAAC;QACH,CAAC;IACH,CAAC;IAEM,cAAc,CAAC,WAAoB,EAAE,cAAuB;QACjE,IAAI,CAAC,YAAY,GAAG,WAAW,IAAI,EAAE,CAAC;QACtC,IAAI,CAAC,eAAe,GAAG,cAAc,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/E,CAAC;CACF;AAtCD,gEAsCC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module OIDC\n */\n\nimport { AccessToken } from \"@itwin/core-bentley\";\nimport { AuthorizationClient } from \"@itwin/core-common\";\nimport { MobileHost } from \"./MobileHost\";\n\n/** Utility to provide and cache auth tokens from native mobile apps to IModelHost.\n * @internal\n */\nexport class MobileAuthorizationBackend implements AuthorizationClient {\n private _accessToken: AccessToken = \"\";\n private _expirationDate: Date | undefined;\n private _expiryBuffer = 60 * 10; // ten minutes\n private _fetchingToken = false;\n\n private get _hasExpired(): boolean {\n return this._expirationDate !== undefined && this._expirationDate.getTime() - Date.now() <= this._expiryBuffer * 1000;\n }\n\n public async getAccessToken(): Promise<AccessToken> {\n if (this._fetchingToken) {\n // NOTE: This function is from the AuthorizationClient interface. That interface documents\n // this function to return an empty string if no token is available, NOT throw an exception.\n return \"\"; // short-circuits any recursive use of this function\n }\n\n if (this._accessToken && !this._hasExpired) {\n return this._accessToken;\n } else {\n try {\n this._fetchingToken = true;\n const result = await MobileHost.authGetAccessToken();\n this._accessToken = result[0];\n this._expirationDate = result[1] ? new Date(result[1]) : undefined;\n return this._accessToken;\n } catch {\n return \"\";\n } finally {\n this._fetchingToken = false;\n }\n }\n }\n\n public setAccessToken(accessToken?: string, expirationDate?: string) {\n this._accessToken = accessToken ?? \"\";\n this._expirationDate = expirationDate ? new Date(expirationDate) : undefined;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MobileFileHandler.js","sourceRoot":"","sources":["../../../src/backend/MobileFileHandler.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module iModelHub\n */\n\nimport { Buffer } from \"node:buffer\";\nimport * as fs from \"node:fs\";\nimport * as https from \"node:https\";\nimport * as path from \"node:path\";\nimport { AccessToken, BentleyError, GetMetaDataFunction, Logger } from \"@itwin/core-bentley\";\nimport { ProgressCallback, ProgressInfo, request, RequestOptions } from \"./Request\";\nimport { MobileHost } from \"./MobileHost\";\n\nconst loggerCategory: string = \"mobile.filehandler\";\n\nconst defined = (argumentName: string, argument?: any, allowEmpty: boolean = false) => {\n if (argument === undefined || argument === null || (argument === \"\" && !allowEmpty))\n throw Error(`Argument ${argumentName} is null or undefined`);\n};\n\n/** Interface to cancel a request\n * @beta\n */\nexport interface CancelRequest {\n /** Returns true if cancel request was acknowledged */\n cancel: () => boolean;\n}\n\n/** Error thrown when user cancelled operation\n * @internal\n */\nexport class UserCancelledError extends BentleyError {\n public constructor(errorNumber: number, message: string, getMetaData?: GetMetaDataFunction) {\n super(errorNumber, message, getMetaData);\n this.name = \"User cancelled operation\";\n }\n}\n\n/** Error thrown fail to download file. ErrorNumber will correspond to HTTP error code.\n * @internal\n */\nexport class DownloadFailed extends BentleyError {\n public constructor(errorNumber: number, message: string, getMetaData?: GetMetaDataFunction) {\n super(errorNumber, message, getMetaData);\n this.name = \"Fail to download file\";\n }\n}\n\n/** Error thrown when sas-url provided for download has expired\n * @internal\n */\nexport class SasUrlExpired extends BentleyError {\n public constructor(errorNumber: number, message: string, getMetaData?: GetMetaDataFunction) {\n super(errorNumber, message, getMetaData);\n this.name = \"SaS url has expired\";\n }\n}\n\n/**\n * Provides methods to work with the file system and azure storage. An instance of this class has to be provided to [[IModelClient]] for file upload/download methods to work.\n * @internal\n */\nexport class MobileFileHandler {\n /** @internal */\n public agent?: https.Agent;\n\n /**\n * Constructor for MobileFileHandler.\n */\n constructor() {\n }\n\n /** Create a directory, recursively setting up the path as necessary. */\n private static makeDirectoryRecursive(dirPath: string) {\n if (fs.existsSync(dirPath))\n return;\n\n MobileFileHandler.makeDirectoryRecursive(path.dirname(dirPath));\n fs.mkdirSync(dirPath);\n }\n\n /**\n * Make url safe for logging by removing sensitive information\n * @param url input url that will be strip of search and query parameters and replace them by ... for security reason\n */\n private static getSafeUrlForLogging(url: string): string {\n const safeToLogDownloadUrl = new URL(url);\n if (safeToLogDownloadUrl.search && safeToLogDownloadUrl.search.length > 0)\n safeToLogDownloadUrl.search = \"...\";\n if (safeToLogDownloadUrl.hash && safeToLogDownloadUrl.hash.length > 0)\n safeToLogDownloadUrl.hash = \"...\";\n return safeToLogDownloadUrl.toString();\n }\n\n /**\n * Check if sas url has expired\n * @param download sas url for download\n * @param futureSeconds should be valid in future for given seconds.\n */\n public static isUrlExpired(downloadUrl: string, futureSeconds?: number): boolean {\n const sasUrl = new URL(downloadUrl);\n const se = sasUrl.searchParams.get(\"se\");\n if (se) {\n const expiryUTC = new Date(se);\n const now = new Date();\n const currentUTC = new Date(now.toUTCString());\n if (futureSeconds) {\n currentUTC.setSeconds(futureSeconds + currentUTC.getSeconds());\n }\n return expiryUTC <= currentUTC;\n }\n return false;\n }\n\n /**\n * Download a file from AzureBlobStorage for iModelHub. Creates the directory containing the file if necessary. If there is an error in the operation, incomplete file is deleted from disk.\n * @param downloadUrl URL to download file from.\n * @param downloadToPathname Pathname to download the file to.\n * @param fileSize Size of the file that's being downloaded.\n * @param progressCallback Callback for tracking progress.\n * @throws [[IModelHubClientError]] with [IModelHubStatus.UndefinedArgumentError]($bentley) if one of the arguments is undefined or empty.\n */\n public async downloadFile(_accessToken: AccessToken, downloadUrl: string, downloadToPathname: string, fileSize?: number, progressCallback?: ProgressCallback, cancelRequest?: CancelRequest): Promise<void> {\n // strip search and hash parameters from download Url for logging purpose\n const safeToLogUrl = MobileFileHandler.getSafeUrlForLogging(downloadUrl);\n Logger.logInfo(loggerCategory, `Downloading file from ${safeToLogUrl}`);\n\n defined(\"downloadUrl\", downloadUrl);\n defined(\"downloadToPathname\", downloadToPathname);\n if (MobileFileHandler.isUrlExpired(downloadUrl)) {\n Logger.logError(loggerCategory, `Sas url has expired ${safeToLogUrl}`);\n throw new SasUrlExpired(403, \"Download URL has expired\");\n }\n if (fs.existsSync(downloadToPathname))\n fs.unlinkSync(downloadToPathname);\n\n MobileFileHandler.makeDirectoryRecursive(path.dirname(downloadToPathname));\n try {\n await MobileHost.downloadFile(downloadUrl, downloadToPathname, progressCallback, cancelRequest);\n } catch (err) {\n if (fs.existsSync(downloadToPathname))\n fs.unlinkSync(downloadToPathname); // Just in case there was a partial download, delete the file\n\n if (!(err instanceof UserCancelledError))\n Logger.logError(loggerCategory, `Error downloading file`);\n throw err;\n }\n if (fileSize && fs.existsSync(downloadToPathname)) {\n if (fs.lstatSync(downloadToPathname).size !== fileSize) {\n fs.unlinkSync(downloadToPathname);\n Logger.logError(loggerCategory, `Downloaded file is of incorrect size ${safeToLogUrl}`);\n throw new DownloadFailed(403, \"Download failed. Expected filesize does not match\");\n }\n }\n Logger.logTrace(loggerCategory, `Downloaded file from ${safeToLogUrl}`);\n }\n /** Get encoded block id from its number. */\n private getBlockId(blockId: number) {\n return Buffer.from(blockId.toString(16).padStart(5, \"0\")).toString(\"base64\");\n }\n\n private async uploadChunk(_accessToken: AccessToken, uploadUrlString: string, fileDescriptor: number, blockId: number, callback?: ProgressCallback) {\n const chunkSize = 4 * 1024 * 1024;\n let buffer = Buffer.alloc(chunkSize);\n const bytesRead = fs.readSync(fileDescriptor, buffer, 0, chunkSize, chunkSize * blockId);\n buffer = buffer.subarray(0, bytesRead);\n\n const options: RequestOptions = {\n method: \"PUT\",\n headers: {\n \"x-ms-blob-type\": \"BlockBlob\",\n \"Content-Type\": \"application/octet-stream\",\n \"Content-Length\": buffer.length,\n },\n body: buffer,\n progressCallback: callback,\n agent: this.agent,\n timeout: {\n deadline: 60000,\n response: 60000,\n },\n };\n\n const uploadUrl = `${uploadUrlString}&comp=block&blockid=${this.getBlockId(blockId)}`;\n await request(uploadUrl, options);\n }\n\n /**\n * Upload a file to AzureBlobStorage for iModelHub.\n * @param uploadUrl URL to upload the file to.\n * @param uploadFromPathname Pathname to upload the file from.\n * @param progressCallback Callback for tracking progress.\n * @throws [[IModelHubClientError]] with [IModelHubStatus.UndefinedArgumentError]($bentley) if one of the arguments is undefined or empty.\n */\n public async uploadFile(accessToken: AccessToken, uploadUrlString: string, uploadFromPathname: string, progressCallback?: ProgressCallback): Promise<void> {\n const safeToLogUrl = MobileFileHandler.getSafeUrlForLogging(uploadUrlString);\n Logger.logTrace(loggerCategory, `Uploading file to ${safeToLogUrl}`);\n defined(\"uploadUrlString\", uploadUrlString);\n defined(\"uploadFromPathname\", uploadFromPathname);\n\n const fileSize = this.getFileSize(uploadFromPathname);\n const file = fs.openSync(uploadFromPathname, \"r\");\n const chunkSize = 4 * 1024 * 1024;\n\n try {\n let blockList = '<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?><BlockList>';\n let i = 0;\n const callback: ProgressCallback = (progress: ProgressInfo) => {\n const uploaded = i * chunkSize + progress.loaded;\n if (progressCallback)\n progressCallback({ loaded: uploaded, percent: uploaded / fileSize, total: fileSize });\n };\n for (; i * chunkSize < fileSize; ++i) {\n await this.uploadChunk(accessToken, uploadUrlString, file, i, progressCallback ? callback : undefined);\n blockList += `<Latest>${this.getBlockId(i)}</Latest>`;\n }\n blockList += \"</BlockList>\";\n\n const options: RequestOptions = {\n method: \"PUT\",\n headers: {\n \"Content-Type\": \"application/xml\",\n \"Content-Length\": blockList.length,\n },\n body: blockList,\n agent: this.agent,\n timeout: {\n response: 5000,\n deadline: 60000,\n },\n };\n\n const uploadUrl = `${uploadUrlString}&comp=blocklist`;\n await request(uploadUrl, options);\n } finally {\n fs.closeSync(file);\n }\n }\n\n /**\n * Get size of a file.\n * @param filePath Path of the file.\n * @returns Size of the file.\n */\n public getFileSize(filePath: string): number {\n return fs.statSync(filePath).size;\n }\n\n /**\n * Check if path is a directory.\n * @param filePath Path of the file.\n * @returns True if path is directory.\n */\n public isDirectory(filePath: string): boolean {\n return fs.statSync(filePath).isDirectory();\n }\n\n /**\n * Check if path exists.\n * @param filePath Path of the file.\n * @returns True if path exists.\n */\n public exists(filePath: string): boolean {\n return fs.existsSync(filePath);\n }\n\n /**\n * Deletes file.\n * @param filePath Path of the file.\n */\n public unlink(filePath: string): void {\n fs.unlinkSync(filePath);\n }\n\n /**\n * Get file name from the path.\n * @param filePath Path of the file.\n * @returns File name.\n */\n public basename(filePath: string): string {\n return path.basename(filePath);\n }\n\n /**\n * Join multiple strings into a single path.\n * @param paths Strings to join.\n * @returns Joined path.\n */\n public join(...paths: string[]): string {\n return path.join(...paths);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"MobileFileHandler.js","sourceRoot":"","sources":["../../../src/backend/MobileFileHandler.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module iModelHub\n */\n\nimport { Buffer } from \"node:buffer\";\nimport * as fs from \"node:fs\";\nimport * as https from \"node:https\";\nimport * as path from \"node:path\";\nimport { AccessToken, BentleyError, GetMetaDataFunction, Logger } from \"@itwin/core-bentley\";\nimport { ProgressCallback, ProgressInfo, request, RequestOptions } from \"./Request\";\nimport { MobileHost } from \"./MobileHost\";\n\nconst loggerCategory: string = \"mobile.filehandler\";\n\nconst defined = (argumentName: string, argument?: any, allowEmpty: boolean = false) => {\n if (argument === undefined || argument === null || (argument === \"\" && !allowEmpty))\n throw Error(`Argument ${argumentName} is null or undefined`);\n};\n\n/** Interface to cancel a request\n * @beta\n */\nexport interface CancelRequest {\n /** Returns true if cancel request was acknowledged */\n cancel: () => boolean;\n}\n\n/** Error thrown when user cancelled operation\n * @internal\n */\nexport class UserCancelledError extends BentleyError {\n public constructor(errorNumber: number, message: string, getMetaData?: GetMetaDataFunction) {\n super(errorNumber, message, getMetaData);\n this.name = \"User cancelled operation\";\n }\n}\n\n/** Error thrown fail to download file. ErrorNumber will correspond to HTTP error code.\n * @internal\n */\nexport class DownloadFailed extends BentleyError {\n public constructor(errorNumber: number, message: string, getMetaData?: GetMetaDataFunction) {\n super(errorNumber, message, getMetaData);\n this.name = \"Fail to download file\";\n }\n}\n\n/** Error thrown when sas-url provided for download has expired\n * @internal\n */\nexport class SasUrlExpired extends BentleyError {\n public constructor(errorNumber: number, message: string, getMetaData?: GetMetaDataFunction) {\n super(errorNumber, message, getMetaData);\n this.name = \"SaS url has expired\";\n }\n}\n\n/**\n * Provides methods to work with the file system and azure storage. An instance of this class has to be provided to [[IModelClient]] for file upload/download methods to work.\n * @internal\n */\nexport class MobileFileHandler {\n /** @internal */\n public agent?: https.Agent;\n\n /**\n * Constructor for MobileFileHandler.\n */\n constructor() {\n }\n\n /** Create a directory, recursively setting up the path as necessary. */\n private static makeDirectoryRecursive(dirPath: string) {\n if (fs.existsSync(dirPath))\n return;\n\n MobileFileHandler.makeDirectoryRecursive(path.dirname(dirPath));\n fs.mkdirSync(dirPath);\n }\n\n /**\n * Make url safe for logging by removing sensitive information\n * @param url input url that will be strip of search and query parameters and replace them by ... for security reason\n */\n private static getSafeUrlForLogging(url: string): string {\n const safeToLogDownloadUrl = new URL(url);\n if (safeToLogDownloadUrl.search && safeToLogDownloadUrl.search.length > 0)\n safeToLogDownloadUrl.search = \"...\";\n if (safeToLogDownloadUrl.hash && safeToLogDownloadUrl.hash.length > 0)\n safeToLogDownloadUrl.hash = \"...\";\n return safeToLogDownloadUrl.toString();\n }\n\n /**\n * Check if sas url has expired\n * @param download sas url for download\n * @param futureSeconds should be valid in future for given seconds.\n */\n public static isUrlExpired(downloadUrl: string, futureSeconds?: number): boolean {\n const sasUrl = new URL(downloadUrl);\n const se = sasUrl.searchParams.get(\"se\");\n if (se) {\n const expiryUTC = new Date(se);\n const now = new Date();\n const currentUTC = new Date(now.toUTCString());\n if (futureSeconds) {\n currentUTC.setSeconds(futureSeconds + currentUTC.getSeconds());\n }\n return expiryUTC <= currentUTC;\n }\n return false;\n }\n\n /**\n * Download a file from AzureBlobStorage for iModelHub. Creates the directory containing the file if necessary. If there is an error in the operation, incomplete file is deleted from disk.\n * @param downloadUrl URL to download file from.\n * @param downloadToPathname Pathname to download the file to.\n * @param fileSize Size of the file that's being downloaded.\n * @param progressCallback Callback for tracking progress.\n * @throws [[IModelHubClientError]] with [IModelHubStatus.UndefinedArgumentError]($bentley) if one of the arguments is undefined or empty.\n */\n public async downloadFile(_accessToken: AccessToken, downloadUrl: string, downloadToPathname: string, fileSize?: number, progressCallback?: ProgressCallback, cancelRequest?: CancelRequest): Promise<void> {\n // strip search and hash parameters from download Url for logging purpose\n const safeToLogUrl = MobileFileHandler.getSafeUrlForLogging(downloadUrl);\n Logger.logInfo(loggerCategory, `Downloading file from ${safeToLogUrl}`);\n\n defined(\"downloadUrl\", downloadUrl);\n defined(\"downloadToPathname\", downloadToPathname);\n if (MobileFileHandler.isUrlExpired(downloadUrl)) {\n Logger.logError(loggerCategory, `Sas url has expired ${safeToLogUrl}`);\n throw new SasUrlExpired(403, \"Download URL has expired\");\n }\n if (fs.existsSync(downloadToPathname))\n fs.unlinkSync(downloadToPathname);\n\n MobileFileHandler.makeDirectoryRecursive(path.dirname(downloadToPathname));\n try {\n await MobileHost.downloadFile(downloadUrl, downloadToPathname, progressCallback, cancelRequest);\n } catch (err) {\n if (fs.existsSync(downloadToPathname))\n fs.unlinkSync(downloadToPathname); // Just in case there was a partial download, delete the file\n\n if (!(err instanceof UserCancelledError))\n Logger.logError(loggerCategory, `Error downloading file`);\n throw err;\n }\n if (fileSize && fs.existsSync(downloadToPathname)) {\n if (fs.lstatSync(downloadToPathname).size !== fileSize) {\n fs.unlinkSync(downloadToPathname);\n Logger.logError(loggerCategory, `Downloaded file is of incorrect size ${safeToLogUrl}`);\n throw new DownloadFailed(403, \"Download failed. Expected filesize does not match\");\n }\n }\n Logger.logTrace(loggerCategory, `Downloaded file from ${safeToLogUrl}`);\n }\n /** Get encoded block id from its number. */\n private getBlockId(blockId: number) {\n return Buffer.from(blockId.toString(16).padStart(5, \"0\")).toString(\"base64\");\n }\n\n private async uploadChunk(_accessToken: AccessToken, uploadUrlString: string, fileDescriptor: number, blockId: number, callback?: ProgressCallback) {\n const chunkSize = 4 * 1024 * 1024;\n let buffer = Buffer.alloc(chunkSize);\n const bytesRead = fs.readSync(fileDescriptor, buffer, 0, chunkSize, chunkSize * blockId);\n buffer = buffer.subarray(0, bytesRead);\n\n const options: RequestOptions = {\n method: \"PUT\",\n headers: {\n \"x-ms-blob-type\": \"BlockBlob\",\n \"Content-Type\": \"application/octet-stream\",\n \"Content-Length\": buffer.length,\n },\n body: buffer,\n progressCallback: callback,\n agent: this.agent,\n timeout: {\n deadline: 60000,\n response: 60000,\n },\n };\n\n const uploadUrl = `${uploadUrlString}&comp=block&blockid=${this.getBlockId(blockId)}`;\n await request(uploadUrl, options);\n }\n\n /**\n * Upload a file to AzureBlobStorage for iModelHub.\n * @param uploadUrl URL to upload the file to.\n * @param uploadFromPathname Pathname to upload the file from.\n * @param progressCallback Callback for tracking progress.\n * @throws [[IModelHubClientError]] with [IModelHubStatus.UndefinedArgumentError]($bentley) if one of the arguments is undefined or empty.\n */\n public async uploadFile(accessToken: AccessToken, uploadUrlString: string, uploadFromPathname: string, progressCallback?: ProgressCallback): Promise<void> {\n const safeToLogUrl = MobileFileHandler.getSafeUrlForLogging(uploadUrlString);\n Logger.logTrace(loggerCategory, `Uploading file to ${safeToLogUrl}`);\n defined(\"uploadUrlString\", uploadUrlString);\n defined(\"uploadFromPathname\", uploadFromPathname);\n\n const fileSize = this.getFileSize(uploadFromPathname);\n const file = fs.openSync(uploadFromPathname, \"r\");\n const chunkSize = 4 * 1024 * 1024;\n\n try {\n let blockList = '<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?><BlockList>';\n let i = 0;\n const callback: ProgressCallback = (progress: ProgressInfo) => {\n const uploaded = i * chunkSize + progress.loaded;\n if (progressCallback)\n progressCallback({ loaded: uploaded, percent: uploaded / fileSize, total: fileSize });\n };\n for (; i * chunkSize < fileSize; ++i) {\n await this.uploadChunk(accessToken, uploadUrlString, file, i, progressCallback ? callback : undefined);\n blockList += `<Latest>${this.getBlockId(i)}</Latest>`;\n }\n blockList += \"</BlockList>\";\n\n const options: RequestOptions = {\n method: \"PUT\",\n headers: {\n \"Content-Type\": \"application/xml\",\n \"Content-Length\": blockList.length,\n },\n body: blockList,\n agent: this.agent,\n timeout: {\n response: 5000,\n deadline: 60000,\n },\n };\n\n const uploadUrl = `${uploadUrlString}&comp=blocklist`;\n await request(uploadUrl, options);\n } finally {\n fs.closeSync(file);\n }\n }\n\n /**\n * Get size of a file.\n * @param filePath Path of the file.\n * @returns Size of the file.\n */\n public getFileSize(filePath: string): number {\n return fs.statSync(filePath).size;\n }\n\n /**\n * Check if path is a directory.\n * @param filePath Path of the file.\n * @returns True if path is directory.\n */\n public isDirectory(filePath: string): boolean {\n return fs.statSync(filePath).isDirectory();\n }\n\n /**\n * Check if path exists.\n * @param filePath Path of the file.\n * @returns True if path exists.\n */\n public exists(filePath: string): boolean {\n return fs.existsSync(filePath);\n }\n\n /**\n * Deletes file.\n * @param filePath Path of the file.\n */\n public unlink(filePath: string): void {\n fs.unlinkSync(filePath);\n }\n\n /**\n * Get file name from the path.\n * @param filePath Path of the file.\n * @returns File name.\n */\n public basename(filePath: string): string {\n return path.basename(filePath);\n }\n\n /**\n * Join multiple strings into a single path.\n * @param paths Strings to join.\n * @returns Joined path.\n */\n public join(...paths: string[]): string {\n return path.join(...paths);\n }\n}\n"]}
|
|
@@ -52,7 +52,41 @@ class MobileAppHandler extends core_backend_1.IpcHandler {
|
|
|
52
52
|
* @beta
|
|
53
53
|
*/
|
|
54
54
|
class MobileHost {
|
|
55
|
+
static _device;
|
|
55
56
|
static get device() { return this._device; }
|
|
57
|
+
/**
|
|
58
|
+
* Raised when the mobile OS informs a mobile app that it is running low on memory.
|
|
59
|
+
*
|
|
60
|
+
* @note iOS and iPadOS send this warning so often as to make it not very useful.
|
|
61
|
+
*/
|
|
62
|
+
static onMemoryWarning = new core_bentley_1.BeEvent();
|
|
63
|
+
/**
|
|
64
|
+
* Raised when the device orientation changes on a device running a mobile app.
|
|
65
|
+
*/
|
|
66
|
+
static onOrientationChanged = new core_bentley_1.BeEvent();
|
|
67
|
+
/**
|
|
68
|
+
* Raised after a mobile app returns to the foreground.
|
|
69
|
+
*/
|
|
70
|
+
static onEnterForeground = new core_bentley_1.BeEvent();
|
|
71
|
+
/**
|
|
72
|
+
* Raised when a mobile app is about to enter the background.
|
|
73
|
+
*/
|
|
74
|
+
static onEnterBackground = new core_bentley_1.BeEvent();
|
|
75
|
+
/**
|
|
76
|
+
* Raised after a mobile backend connects to the mobile frontend.
|
|
77
|
+
*
|
|
78
|
+
* @note this will be raised at startup, and it will also be raised every time the app returns
|
|
79
|
+
* to the foreground from the background.
|
|
80
|
+
*/
|
|
81
|
+
static onConnected = new core_bentley_1.BeEvent();
|
|
82
|
+
/**
|
|
83
|
+
* Raised when a mobile app is about to be terminated by the mobile OS.
|
|
84
|
+
*/
|
|
85
|
+
static onWillTerminate = new core_bentley_1.BeEvent();
|
|
86
|
+
/**
|
|
87
|
+
* Raised when the native auth client informs the mobile host that the access token has changed.
|
|
88
|
+
*/
|
|
89
|
+
static onAuthAccessTokenChanged = new core_bentley_1.BeEvent();
|
|
56
90
|
/** Send a notification to the MobileApp connected to this MobileHost. */
|
|
57
91
|
static notifyMobileFrontend(methodName, ...args) {
|
|
58
92
|
return core_backend_1.IpcHost.send(MobileAppChannel_1.mobileAppStrings.mobileAppNotify, methodName, ...args);
|
|
@@ -146,37 +180,4 @@ class MobileHost {
|
|
|
146
180
|
}
|
|
147
181
|
}
|
|
148
182
|
exports.MobileHost = MobileHost;
|
|
149
|
-
/**
|
|
150
|
-
* Raised when the mobile OS informs a mobile app that it is running low on memory.
|
|
151
|
-
*
|
|
152
|
-
* @note iOS and iPadOS send this warning so often as to make it not very useful.
|
|
153
|
-
*/
|
|
154
|
-
MobileHost.onMemoryWarning = new core_bentley_1.BeEvent();
|
|
155
|
-
/**
|
|
156
|
-
* Raised when the device orientation changes on a device running a mobile app.
|
|
157
|
-
*/
|
|
158
|
-
MobileHost.onOrientationChanged = new core_bentley_1.BeEvent();
|
|
159
|
-
/**
|
|
160
|
-
* Raised after a mobile app returns to the foreground.
|
|
161
|
-
*/
|
|
162
|
-
MobileHost.onEnterForeground = new core_bentley_1.BeEvent();
|
|
163
|
-
/**
|
|
164
|
-
* Raised when a mobile app is about to enter the background.
|
|
165
|
-
*/
|
|
166
|
-
MobileHost.onEnterBackground = new core_bentley_1.BeEvent();
|
|
167
|
-
/**
|
|
168
|
-
* Raised after a mobile backend connects to the mobile frontend.
|
|
169
|
-
*
|
|
170
|
-
* @note this will be raised at startup, and it will also be raised every time the app returns
|
|
171
|
-
* to the foreground from the background.
|
|
172
|
-
*/
|
|
173
|
-
MobileHost.onConnected = new core_bentley_1.BeEvent();
|
|
174
|
-
/**
|
|
175
|
-
* Raised when a mobile app is about to be terminated by the mobile OS.
|
|
176
|
-
*/
|
|
177
|
-
MobileHost.onWillTerminate = new core_bentley_1.BeEvent();
|
|
178
|
-
/**
|
|
179
|
-
* Raised when the native auth client informs the mobile host that the access token has changed.
|
|
180
|
-
*/
|
|
181
|
-
MobileHost.onAuthAccessTokenChanged = new core_bentley_1.BeEvent();
|
|
182
183
|
//# sourceMappingURL=MobileHost.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MobileHost.js","sourceRoot":"","sources":["../../../src/backend/MobileHost.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\nimport { AccessToken, BeEvent, BriefcaseStatus } from \"@itwin/core-bentley\";\nimport { IpcHandler, IpcHost, NativeHost, NativeHostOpts } from \"@itwin/core-backend\";\nimport { IpcWebSocketBackend, RpcInterfaceDefinition } from \"@itwin/core-common\";\nimport { CancelRequest, DownloadFailed, UserCancelledError } from \"./MobileFileHandler\";\nimport { ProgressCallback } from \"./Request\";\nimport { mobileAppStrings } from \"../common/MobileAppChannel\";\nimport { BatteryState, DeviceEvents, MobileAppFunctions, MobileNotifications, Orientation } from \"../common/MobileAppProps\";\nimport { MobileRpcManager } from \"../common/MobileRpcManager\";\nimport { MobileAuthorizationBackend } from \"./MobileAuthorizationBackend\";\nimport { setupMobileRpc } from \"./MobileRpcServer\";\n\n/** @beta */\nexport type MobileCompletionCallback = (downloadUrl: string, downloadFileUrl: string, cancelled: boolean, err?: string) => void;\n/** @beta */\nexport type MobileProgressCallback = (bytesWritten: number, totalBytesWritten: number, totalBytesExpectedToWrite: number) => void;\n/** @beta */\nexport type MobileCancelCallback = () => boolean;\n\n/** @beta */\nexport interface DownloadTask {\n url: string;\n downloadPath: string;\n isDetached: boolean;\n isRunning: boolean;\n totalBytes?: number;\n doneBytes?: number;\n cancelId?: number;\n isBackground?: boolean;\n cancel?: MobileCancelCallback;\n toBackground: () => boolean;\n toForeground: () => boolean;\n}\n\n/** @beta */\nexport abstract class MobileDevice {\n public emit(eventName: DeviceEvents, ...args: any[]) {\n switch (eventName) {\n case \"memoryWarning\":\n MobileHost.onMemoryWarning.raiseEvent(...args);\n break;\n case \"orientationChanged\":\n MobileHost.onOrientationChanged.raiseEvent(...args);\n break;\n case \"enterForeground\":\n MobileHost.onEnterForeground.raiseEvent(...args);\n break;\n case \"enterBackground\":\n MobileHost.onEnterBackground.raiseEvent(...args);\n break;\n case \"willTerminate\":\n MobileHost.onWillTerminate.raiseEvent(...args);\n break;\n case \"authAccessTokenChanged\":\n MobileHost.onAuthAccessTokenChanged.raiseEvent(args[0], args[1]);\n break;\n }\n }\n\n public abstract getOrientation(): Orientation;\n public abstract getBatteryState(): BatteryState;\n public abstract getBatteryLevel(): number;\n public abstract createDownloadTask(downloadUrl: string, isBackground: boolean, downloadTo: string, completion: MobileCompletionCallback, progress?: MobileProgressCallback): number;\n public abstract cancelDownloadTask(cancelId: number): boolean;\n public abstract getDownloadTasks(): DownloadTask[];\n public abstract resumeDownloadInForeground(requestId: number): boolean;\n public abstract resumeDownloadInBackground(requestId: number): boolean;\n public abstract reconnect(connection: number): void;\n public abstract authGetAccessToken(callback: (accessToken?: string, expirationDate?: string, err?: string) => void): void;\n}\n\nclass MobileAppHandler extends IpcHandler implements MobileAppFunctions {\n public get channelName() { return mobileAppStrings.mobileAppChannel; }\n public async reconnect(connection: number) {\n MobileHost.reconnect(connection);\n }\n public async getAccessToken() {\n return MobileHost.authGetAccessToken();\n }\n}\n\n/** @beta */\nexport interface MobileHostOpts extends NativeHostOpts {\n mobileHost?: {\n device?: MobileDevice;\n /** list of RPC interface definitions to register */\n rpcInterfaces?: RpcInterfaceDefinition[];\n };\n}\n\n/**\n * @beta\n */\nexport class MobileHost {\n private static _device?: MobileDevice;\n public static get device() { return this._device!; }\n /**\n * Raised when the mobile OS informs a mobile app that it is running low on memory.\n *\n * @note iOS and iPadOS send this warning so often as to make it not very useful.\n */\n public static readonly onMemoryWarning = new BeEvent();\n /**\n * Raised when the device orientation changes on a device running a mobile app.\n */\n public static readonly onOrientationChanged = new BeEvent();\n /**\n * Raised after a mobile app returns to the foreground.\n */\n public static readonly onEnterForeground = new BeEvent();\n /**\n * Raised when a mobile app is about to enter the background.\n */\n public static readonly onEnterBackground = new BeEvent();\n /**\n * Raised after a mobile backend connects to the mobile frontend.\n *\n * @note this will be raised at startup, and it will also be raised every time the app returns\n * to the foreground from the background.\n */\n public static readonly onConnected = new BeEvent();\n /**\n * Raised when a mobile app is about to be terminated by the mobile OS.\n */\n public static readonly onWillTerminate = new BeEvent();\n /**\n * Raised when the native auth client informs the mobile host that the access token has changed.\n */\n public static readonly onAuthAccessTokenChanged = new BeEvent<(accessToken: string | undefined, expirationDate: string | undefined) => void>();\n\n /** Send a notification to the MobileApp connected to this MobileHost. */\n public static notifyMobileFrontend<T extends keyof MobileNotifications>(methodName: T, ...args: Parameters<MobileNotifications[T]>) {\n return IpcHost.send(mobileAppStrings.mobileAppNotify, methodName, ...args);\n }\n\n /** @internal */\n public static reconnect(connection: number) {\n this.device.reconnect(connection);\n }\n\n /** @internal */\n public static async authGetAccessToken() {\n return new Promise<[AccessToken, string]>((resolve, reject) => {\n this.device.authGetAccessToken((tokenString?: AccessToken, expirationDate?: string, error?: string) => {\n if (error) {\n reject(new Error(error));\n } else {\n resolve([tokenString ?? \"\", expirationDate ?? \"\"]);\n }\n });\n });\n }\n\n /** @internal */\n public static async downloadFile(downloadUrl: string, downloadTo: string, progress?: ProgressCallback, cancelRequest?: CancelRequest): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n\n let progressCb: MobileProgressCallback | undefined;\n let lastReportedOn = Date.now();\n const minTimeBeforeReportingProgress = 1000;\n if (progress) {\n progressCb = (_bytesWritten: number, totalBytesWritten: number, totalBytesExpectedToWrite: number) => {\n const currentTime = Date.now();\n const timeSinceLastEvent = currentTime - lastReportedOn;\n // report all event for last 5 Mbs so we never miss 100% progress event\n const lastEvent = (totalBytesExpectedToWrite - totalBytesWritten) < 1024 * 1024 * 5;\n if (timeSinceLastEvent < minTimeBeforeReportingProgress && !lastEvent)\n return;\n\n lastReportedOn = currentTime;\n const percent = Number((100 * (totalBytesWritten / totalBytesExpectedToWrite)).toFixed(2));\n progress({ total: totalBytesExpectedToWrite, loaded: totalBytesWritten, percent });\n };\n }\n const requestId = this.device.createDownloadTask(downloadUrl, false, downloadTo, (_downloadUrl: string, _downloadFileUrl: string, cancelled: boolean, err?: string) => {\n if (cancelled)\n reject(new UserCancelledError(BriefcaseStatus.DownloadCancelled, \"User cancelled download\"));\n else if (err)\n reject(new DownloadFailed(400, \"Download failed\"));\n else\n resolve();\n }, progressCb);\n if (cancelRequest) {\n cancelRequest.cancel = () => this.device.cancelDownloadTask(requestId);\n }\n });\n }\n\n public static get isValid() { return undefined !== this._device; }\n\n /** Start the backend of a mobile app. */\n public static async startup(opt?: MobileHostOpts): Promise<void> {\n const authorizationClient = new MobileAuthorizationBackend();\n if (!this.isValid) {\n this._device = opt?.mobileHost?.device ?? new (MobileDevice as any)();\n // set global device interface.\n // NOTE: __iTwinJsNativeBridge is used by backend native code.\n (global as any).__iTwinJsNativeBridge = this._device;\n this.onMemoryWarning.addListener(() => {\n MobileHost.notifyMobileFrontend(\"notifyMemoryWarning\");\n });\n this.onOrientationChanged.addListener(() => {\n try {\n MobileHost.notifyMobileFrontend(\"notifyOrientationChanged\");\n } catch { } // Ignore: frontend is not currently connected\n });\n this.onWillTerminate.addListener(() => {\n MobileHost.notifyMobileFrontend(\"notifyWillTerminate\");\n });\n this.onAuthAccessTokenChanged.addListener((accessToken: string | undefined, expirationDate: string | undefined) => {\n authorizationClient.setAccessToken(accessToken, expirationDate);\n MobileHost.notifyMobileFrontend(\"notifyAuthAccessTokenChanged\", accessToken, expirationDate);\n });\n\n // following will provide impl for device specific api.\n setupMobileRpc();\n }\n\n const socket = opt?.ipcHost?.socket ?? new IpcWebSocketBackend();\n opt = { ...opt, mobileHost: { ...opt?.mobileHost }, ipcHost: { ...opt?.ipcHost, socket } };\n\n const iModelHost = opt?.iModelHost ?? {};\n iModelHost.authorizationClient = authorizationClient;\n await NativeHost.startup({ ...opt, iModelHost });\n\n if (IpcHost.isValid)\n MobileAppHandler.register();\n\n const rpcInterfaces = opt?.mobileHost?.rpcInterfaces ?? [];\n\n MobileRpcManager.initializeImpl(rpcInterfaces);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"MobileHost.js","sourceRoot":"","sources":["../../../src/backend/MobileHost.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\nimport { AccessToken, BeEvent, BriefcaseStatus } from \"@itwin/core-bentley\";\nimport { IpcHandler, IpcHost, NativeHost, NativeHostOpts } from \"@itwin/core-backend\";\nimport { IpcWebSocketBackend, RpcInterfaceDefinition } from \"@itwin/core-common\";\nimport { CancelRequest, DownloadFailed, UserCancelledError } from \"./MobileFileHandler\";\nimport { ProgressCallback } from \"./Request\";\nimport { mobileAppStrings } from \"../common/MobileAppChannel\";\nimport { BatteryState, DeviceEvents, MobileAppFunctions, MobileNotifications, Orientation } from \"../common/MobileAppProps\";\nimport { MobileRpcManager } from \"../common/MobileRpcManager\";\nimport { MobileAuthorizationBackend } from \"./MobileAuthorizationBackend\";\nimport { setupMobileRpc } from \"./MobileRpcServer\";\n\n/** @beta */\nexport type MobileCompletionCallback = (downloadUrl: string, downloadFileUrl: string, cancelled: boolean, err?: string) => void;\n/** @beta */\nexport type MobileProgressCallback = (bytesWritten: number, totalBytesWritten: number, totalBytesExpectedToWrite: number) => void;\n/** @beta */\nexport type MobileCancelCallback = () => boolean;\n\n/** @beta */\nexport interface DownloadTask {\n url: string;\n downloadPath: string;\n isDetached: boolean;\n isRunning: boolean;\n totalBytes?: number;\n doneBytes?: number;\n cancelId?: number;\n isBackground?: boolean;\n cancel?: MobileCancelCallback;\n toBackground: () => boolean;\n toForeground: () => boolean;\n}\n\n/** @beta */\nexport abstract class MobileDevice {\n public emit(eventName: DeviceEvents, ...args: any[]) {\n switch (eventName) {\n case \"memoryWarning\":\n MobileHost.onMemoryWarning.raiseEvent(...args);\n break;\n case \"orientationChanged\":\n MobileHost.onOrientationChanged.raiseEvent(...args);\n break;\n case \"enterForeground\":\n MobileHost.onEnterForeground.raiseEvent(...args);\n break;\n case \"enterBackground\":\n MobileHost.onEnterBackground.raiseEvent(...args);\n break;\n case \"willTerminate\":\n MobileHost.onWillTerminate.raiseEvent(...args);\n break;\n case \"authAccessTokenChanged\":\n MobileHost.onAuthAccessTokenChanged.raiseEvent(args[0], args[1]);\n break;\n }\n }\n\n public abstract getOrientation(): Orientation;\n public abstract getBatteryState(): BatteryState;\n public abstract getBatteryLevel(): number;\n public abstract createDownloadTask(downloadUrl: string, isBackground: boolean, downloadTo: string, completion: MobileCompletionCallback, progress?: MobileProgressCallback): number;\n public abstract cancelDownloadTask(cancelId: number): boolean;\n public abstract getDownloadTasks(): DownloadTask[];\n public abstract resumeDownloadInForeground(requestId: number): boolean;\n public abstract resumeDownloadInBackground(requestId: number): boolean;\n public abstract reconnect(connection: number): void;\n public abstract authGetAccessToken(callback: (accessToken?: string, expirationDate?: string, err?: string) => void): void;\n}\n\nclass MobileAppHandler extends IpcHandler implements MobileAppFunctions {\n public get channelName() { return mobileAppStrings.mobileAppChannel; }\n public async reconnect(connection: number) {\n MobileHost.reconnect(connection);\n }\n public async getAccessToken() {\n return MobileHost.authGetAccessToken();\n }\n}\n\n/** @beta */\nexport interface MobileHostOpts extends NativeHostOpts {\n mobileHost?: {\n device?: MobileDevice;\n /** list of RPC interface definitions to register */\n rpcInterfaces?: RpcInterfaceDefinition[];\n };\n}\n\n/**\n * @beta\n */\nexport class MobileHost {\n private static _device?: MobileDevice;\n public static get device() { return this._device!; }\n /**\n * Raised when the mobile OS informs a mobile app that it is running low on memory.\n *\n * @note iOS and iPadOS send this warning so often as to make it not very useful.\n */\n public static readonly onMemoryWarning = new BeEvent();\n /**\n * Raised when the device orientation changes on a device running a mobile app.\n */\n public static readonly onOrientationChanged = new BeEvent();\n /**\n * Raised after a mobile app returns to the foreground.\n */\n public static readonly onEnterForeground = new BeEvent();\n /**\n * Raised when a mobile app is about to enter the background.\n */\n public static readonly onEnterBackground = new BeEvent();\n /**\n * Raised after a mobile backend connects to the mobile frontend.\n *\n * @note this will be raised at startup, and it will also be raised every time the app returns\n * to the foreground from the background.\n */\n public static readonly onConnected = new BeEvent();\n /**\n * Raised when a mobile app is about to be terminated by the mobile OS.\n */\n public static readonly onWillTerminate = new BeEvent();\n /**\n * Raised when the native auth client informs the mobile host that the access token has changed.\n */\n public static readonly onAuthAccessTokenChanged = new BeEvent<(accessToken: string | undefined, expirationDate: string | undefined) => void>();\n\n /** Send a notification to the MobileApp connected to this MobileHost. */\n public static notifyMobileFrontend<T extends keyof MobileNotifications>(methodName: T, ...args: Parameters<MobileNotifications[T]>) {\n return IpcHost.send(mobileAppStrings.mobileAppNotify, methodName, ...args);\n }\n\n /** @internal */\n public static reconnect(connection: number) {\n this.device.reconnect(connection);\n }\n\n /** @internal */\n public static async authGetAccessToken() {\n return new Promise<[AccessToken, string]>((resolve, reject) => {\n this.device.authGetAccessToken((tokenString?: AccessToken, expirationDate?: string, error?: string) => {\n if (error) {\n reject(new Error(error));\n } else {\n resolve([tokenString ?? \"\", expirationDate ?? \"\"]);\n }\n });\n });\n }\n\n /** @internal */\n public static async downloadFile(downloadUrl: string, downloadTo: string, progress?: ProgressCallback, cancelRequest?: CancelRequest): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n\n let progressCb: MobileProgressCallback | undefined;\n let lastReportedOn = Date.now();\n const minTimeBeforeReportingProgress = 1000;\n if (progress) {\n progressCb = (_bytesWritten: number, totalBytesWritten: number, totalBytesExpectedToWrite: number) => {\n const currentTime = Date.now();\n const timeSinceLastEvent = currentTime - lastReportedOn;\n // report all event for last 5 Mbs so we never miss 100% progress event\n const lastEvent = (totalBytesExpectedToWrite - totalBytesWritten) < 1024 * 1024 * 5;\n if (timeSinceLastEvent < minTimeBeforeReportingProgress && !lastEvent)\n return;\n\n lastReportedOn = currentTime;\n const percent = Number((100 * (totalBytesWritten / totalBytesExpectedToWrite)).toFixed(2));\n progress({ total: totalBytesExpectedToWrite, loaded: totalBytesWritten, percent });\n };\n }\n const requestId = this.device.createDownloadTask(downloadUrl, false, downloadTo, (_downloadUrl: string, _downloadFileUrl: string, cancelled: boolean, err?: string) => {\n if (cancelled)\n reject(new UserCancelledError(BriefcaseStatus.DownloadCancelled, \"User cancelled download\"));\n else if (err)\n reject(new DownloadFailed(400, \"Download failed\"));\n else\n resolve();\n }, progressCb);\n if (cancelRequest) {\n cancelRequest.cancel = () => this.device.cancelDownloadTask(requestId);\n }\n });\n }\n\n public static get isValid() { return undefined !== this._device; }\n\n /** Start the backend of a mobile app. */\n public static async startup(opt?: MobileHostOpts): Promise<void> {\n const authorizationClient = new MobileAuthorizationBackend();\n if (!this.isValid) {\n this._device = opt?.mobileHost?.device ?? new (MobileDevice as any)();\n // set global device interface.\n // NOTE: __iTwinJsNativeBridge is used by backend native code.\n (global as any).__iTwinJsNativeBridge = this._device;\n this.onMemoryWarning.addListener(() => {\n MobileHost.notifyMobileFrontend(\"notifyMemoryWarning\");\n });\n this.onOrientationChanged.addListener(() => {\n try {\n MobileHost.notifyMobileFrontend(\"notifyOrientationChanged\");\n } catch { } // Ignore: frontend is not currently connected\n });\n this.onWillTerminate.addListener(() => {\n MobileHost.notifyMobileFrontend(\"notifyWillTerminate\");\n });\n this.onAuthAccessTokenChanged.addListener((accessToken: string | undefined, expirationDate: string | undefined) => {\n authorizationClient.setAccessToken(accessToken, expirationDate);\n MobileHost.notifyMobileFrontend(\"notifyAuthAccessTokenChanged\", accessToken, expirationDate);\n });\n\n // following will provide impl for device specific api.\n setupMobileRpc();\n }\n\n const socket = opt?.ipcHost?.socket ?? new IpcWebSocketBackend();\n opt = { ...opt, mobileHost: { ...opt?.mobileHost }, ipcHost: { ...opt?.ipcHost, socket } };\n\n const iModelHost = opt?.iModelHost ?? {};\n iModelHost.authorizationClient = authorizationClient;\n await NativeHost.startup({ ...opt, iModelHost });\n\n if (IpcHost.isValid)\n MobileAppHandler.register();\n\n const rpcInterfaces = opt?.mobileHost?.rpcInterfaces ?? [];\n\n MobileRpcManager.initializeImpl(rpcInterfaces);\n }\n}\n"]}
|
|
@@ -16,7 +16,7 @@ export declare class MobileRpcServer {
|
|
|
16
16
|
private _createSender;
|
|
17
17
|
private _sendPending;
|
|
18
18
|
private _onConnectionMessage;
|
|
19
|
-
dispose(): void;
|
|
19
|
+
[Symbol.dispose](): void;
|
|
20
20
|
}
|
|
21
21
|
export declare function setupMobileRpc(): void;
|
|
22
22
|
//# sourceMappingURL=MobileRpcServer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MobileRpcServer.d.ts","sourceRoot":"","sources":["../../../src/backend/MobileRpcServer.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,gBAAgB,EAAqB,MAAM,6BAA6B,CAAC;AAYlF,gBAAgB;AAChB,qBAAa,eAAe;IAgBP,OAAO,CAAC,gBAAgB;IAf3C,OAAO,CAAC,MAAM,CAAC,OAAO,CAAM;IAE5B,OAAc,OAAO,EAAE,gBAAgB,CAMrC;IAEF,OAAO,CAAC,OAAO,CAAY;IAC3B,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,UAAU,CAAiB;gBACR,gBAAgB,GAAE,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC,GAAG,SAAqB;IAmB/F,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,aAAa;IAiBrB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,oBAAoB;IAiBrB,OAAO;
|
|
1
|
+
{"version":3,"file":"MobileRpcServer.d.ts","sourceRoot":"","sources":["../../../src/backend/MobileRpcServer.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,gBAAgB,EAAqB,MAAM,6BAA6B,CAAC;AAYlF,gBAAgB;AAChB,qBAAa,eAAe;IAgBP,OAAO,CAAC,gBAAgB;IAf3C,OAAO,CAAC,MAAM,CAAC,OAAO,CAAM;IAE5B,OAAc,OAAO,EAAE,gBAAgB,CAMrC;IAEF,OAAO,CAAC,OAAO,CAAY;IAC3B,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,UAAU,CAAiB;gBACR,gBAAgB,GAAE,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC,GAAG,SAAqB;IAmB/F,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,aAAa;IAiBrB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,oBAAoB;IAiBrB,CAAC,MAAM,CAAC,OAAO,CAAC;CAUxB;AAKD,wBAAgB,cAAc,SAoE7B"}
|
|
@@ -15,6 +15,20 @@ const core_bentley_1 = require("@itwin/core-bentley");
|
|
|
15
15
|
let addon;
|
|
16
16
|
/** @internal */
|
|
17
17
|
class MobileRpcServer {
|
|
18
|
+
_pendingMessages;
|
|
19
|
+
static _nextId = -1;
|
|
20
|
+
static interop = {
|
|
21
|
+
handler: (_payload) => { throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "Not implemented."); },
|
|
22
|
+
sendString: (_message, _connectionId) => { throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "No connection."); },
|
|
23
|
+
sendBinary: (_message, _connectionId) => { throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "No connection."); },
|
|
24
|
+
port: 0,
|
|
25
|
+
connectionId: 0,
|
|
26
|
+
};
|
|
27
|
+
_server;
|
|
28
|
+
_connection;
|
|
29
|
+
_port;
|
|
30
|
+
_connectionId;
|
|
31
|
+
_pingTimer;
|
|
18
32
|
constructor(_pendingMessages = undefined) {
|
|
19
33
|
this._pendingMessages = _pendingMessages;
|
|
20
34
|
/* _pingTime is a fix for ios/mobile case where when the app moves into foreground from
|
|
@@ -90,7 +104,7 @@ class MobileRpcServer {
|
|
|
90
104
|
_onConnectionMessage(data) {
|
|
91
105
|
let message = data;
|
|
92
106
|
if (Array.isArray(message)) {
|
|
93
|
-
throw new core_common_1.IModelError(
|
|
107
|
+
throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, "Unsupported data type");
|
|
94
108
|
}
|
|
95
109
|
if (Buffer.isBuffer(message)) {
|
|
96
110
|
if (message.byteOffset !== 0 || message.byteLength !== message.buffer.byteLength) {
|
|
@@ -102,7 +116,7 @@ class MobileRpcServer {
|
|
|
102
116
|
}
|
|
103
117
|
MobileRpcServer.interop.handler(message, this._connectionId);
|
|
104
118
|
}
|
|
105
|
-
dispose() {
|
|
119
|
+
[Symbol.dispose]() {
|
|
106
120
|
clearInterval(this._pingTimer);
|
|
107
121
|
if (this._connection) {
|
|
108
122
|
MobileRpcServer.interop.sendString = () => { };
|
|
@@ -113,14 +127,6 @@ class MobileRpcServer {
|
|
|
113
127
|
}
|
|
114
128
|
}
|
|
115
129
|
exports.MobileRpcServer = MobileRpcServer;
|
|
116
|
-
MobileRpcServer._nextId = -1;
|
|
117
|
-
MobileRpcServer.interop = {
|
|
118
|
-
handler: (_payload) => { throw new core_common_1.IModelError(core_common_1.BentleyStatus.ERROR, "Not implemented."); },
|
|
119
|
-
sendString: (_message, _connectionId) => { throw new core_common_1.IModelError(core_common_1.BentleyStatus.ERROR, "No connection."); },
|
|
120
|
-
sendBinary: (_message, _connectionId) => { throw new core_common_1.IModelError(core_common_1.BentleyStatus.ERROR, "No connection."); },
|
|
121
|
-
port: 0,
|
|
122
|
-
connectionId: 0,
|
|
123
|
-
};
|
|
124
130
|
let mobileReady = false;
|
|
125
131
|
let hasSuspended = false;
|
|
126
132
|
function setupMobileRpc() {
|
|
@@ -152,7 +158,7 @@ function setupMobileRpc() {
|
|
|
152
158
|
return;
|
|
153
159
|
}
|
|
154
160
|
retainUvLoop = setInterval(() => { }, 1000);
|
|
155
|
-
server.dispose();
|
|
161
|
+
server[Symbol.dispose]();
|
|
156
162
|
usePendingSender();
|
|
157
163
|
server = null;
|
|
158
164
|
global.__iTwinJsRpcReady = false;
|
|
@@ -173,7 +179,7 @@ function setupMobileRpc() {
|
|
|
173
179
|
if (server === null) {
|
|
174
180
|
return;
|
|
175
181
|
}
|
|
176
|
-
server.dispose();
|
|
182
|
+
server[Symbol.dispose]();
|
|
177
183
|
server = null;
|
|
178
184
|
});
|
|
179
185
|
MobileRpcProtocol_1.MobileRpcProtocol.obtainInterop = () => MobileRpcServer.interop;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MobileRpcServer.js","sourceRoot":"","sources":["../../../src/backend/MobileRpcServer.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\nimport * as ws from \"ws\";\nimport { BentleyStatus, IModelError } from \"@itwin/core-common\";\nimport { MobileRpcGateway, MobileRpcProtocol } from \"../common/MobileRpcProtocol\";\nimport { MobileRpcConfiguration } from \"../common/MobileRpcManager\";\nimport { MobileHost } from \"./MobileHost\";\nimport { ProcessDetector } from \"@itwin/core-bentley\";\n\ninterface MobileAddon {\n notifyListening: (port: number) => void;\n registerDeviceImpl: () => void;\n}\n\nlet addon: MobileAddon | undefined;\n\n/** @internal */\nexport class MobileRpcServer {\n private static _nextId = -1;\n\n public static interop: MobileRpcGateway = {\n handler: (_payload: ArrayBuffer | string) => { throw new IModelError(BentleyStatus.ERROR, \"Not implemented.\"); },\n sendString: (_message: string, _connectionId: number) => { throw new IModelError(BentleyStatus.ERROR, \"No connection.\"); },\n sendBinary: (_message: Uint8Array, _connectionId: number) => { throw new IModelError(BentleyStatus.ERROR, \"No connection.\"); },\n port: 0,\n connectionId: 0,\n };\n\n private _server: ws.Server;\n private _connection: ws | undefined;\n private _port: number;\n private _connectionId: number;\n private _pingTimer: NodeJS.Timeout;\n public constructor(private _pendingMessages: Array<string | Uint8Array> | undefined = undefined) {\n /* _pingTime is a fix for ios/mobile case where when the app moves into foreground from\n * background backend restart ws.Server and then notify frontend to reconnect. But ws.Server\n * listening event is not fired as node yield to kevent and wait for some io event to happen.\n * This causes a delay in reconnection which may be as long a 40 secs. To solve the issue we\n * create _pingTimer which causes kevent to yield back to uv poll so timer event can be fired.\n * This allow listening event to go through quickly (max 5ms). Once the listening event occur we\n * clear the timer. Here we use setInterval() just to make sure otherwise setTimeout() could equally\n * be effective\n */\n this._pingTimer = setInterval(() => { }, 5);\n this._port = MobileRpcConfiguration.setup.obtainPort();\n this._server = new ws.Server({ port: this._port });\n this._connectionId = ++MobileRpcServer._nextId;\n MobileRpcServer.interop.connectionId = this._connectionId;\n this._onListening();\n this._onConnection();\n }\n\n private _onListening() {\n this._server.on(\"listening\", () => {\n const address = this._server.address() as ws.AddressInfo;\n this._port = address.port;\n clearInterval(this._pingTimer);\n this._notifyListening();\n });\n }\n\n private _notifyListening() {\n MobileRpcServer.interop.port = this._port;\n\n if (addon) {\n addon.notifyListening(this._port);\n }\n\n if (this._connectionId !== 0) {\n MobileHost.reconnect(this._port);\n }\n }\n\n private _onConnection() {\n this._server.on(\"connection\", (connection) => {\n this._connection = connection;\n this._connection.on(\"message\", (data) => this._onConnectionMessage(data));\n this._createSender();\n this._sendPending();\n (global as any).__iTwinJsRpcReady = true;\n MobileHost.onConnected.raiseEvent();\n });\n }\n\n private _createSender() {\n const sender = (message: string | Uint8Array, connectionId: number) => {\n if (connectionId !== this._connectionId) {\n return;\n }\n\n this._connection!.send(message, (err) => {\n if (err) {\n throw err;\n }\n });\n };\n\n MobileRpcServer.interop.sendString = sender;\n MobileRpcServer.interop.sendBinary = sender;\n }\n\n private _sendPending() {\n if (this._pendingMessages === undefined)\n return;\n\n for (const message of this._pendingMessages) {\n this._connection!.send(message, (err) => {\n if (err) {\n throw err;\n }\n });\n }\n this._pendingMessages.length = 0;\n }\n\n private _onConnectionMessage(data: ws.Data) {\n let message = data;\n if (Array.isArray(message)) {\n throw new IModelError(BentleyStatus.ERROR, \"Unsupported data type\");\n }\n\n if (Buffer.isBuffer(message)) {\n if (message.byteOffset !== 0 || message.byteLength !== message.buffer.byteLength) {\n message = new Uint8Array(message.buffer, message.byteOffset, message.byteLength);\n } else {\n message = message.buffer;\n }\n }\n\n MobileRpcServer.interop.handler(message, this._connectionId);\n }\n\n public dispose() {\n clearInterval(this._pingTimer);\n if (this._connection) {\n MobileRpcServer.interop.sendString = () => { };\n MobileRpcServer.interop.sendBinary = () => { };\n this._connection.close();\n }\n\n this._server.close();\n }\n}\n\nlet mobileReady = false;\nlet hasSuspended = false;\n\nexport function setupMobileRpc() {\n if (mobileReady) {\n return;\n }\n\n if (ProcessDetector.isMobileAppBackend) {\n addon = (process as any)._linkedBinding(\"iModelJsMobile\");\n addon?.registerDeviceImpl();\n }\n\n let server: MobileRpcServer | null = new MobileRpcServer();\n\n /* The UV event loop (internal to node) is retained by handles,\n such as those created for setInterval/setTimeout and client/server connections.\n In a simple app, the RPC server may be the only handle retaining the UV loop.\n Thus, we install a temporary timer on suspend to prevent the loop from exiting prematurely.\n */\n let retainUvLoop: NodeJS.Timeout | undefined;\n const pendingMessages: Array<string | Uint8Array> = [];\n\n function usePendingSender() {\n const sender = (message: string | Uint8Array, _connectionId: number) => {\n pendingMessages.push(message);\n };\n MobileRpcServer.interop.sendString = sender;\n MobileRpcServer.interop.sendBinary = sender;\n }\n\n MobileHost.onEnterBackground.addListener(() => {\n hasSuspended = true;\n\n if (server === null) {\n return;\n }\n\n retainUvLoop = setInterval(() => { }, 1000);\n server.dispose();\n usePendingSender();\n server = null;\n (global as any).__iTwinJsRpcReady = false;\n });\n\n MobileHost.onEnterForeground.addListener(() => {\n if (!hasSuspended) {\n return;\n }\n\n server = new MobileRpcServer(pendingMessages);\n clearInterval(retainUvLoop);\n retainUvLoop = undefined;\n });\n\n MobileHost.onWillTerminate.addListener(() => {\n if (typeof (retainUvLoop) !== \"undefined\") {\n clearInterval(retainUvLoop);\n retainUvLoop = undefined;\n }\n\n if (server === null) {\n return;\n }\n\n server.dispose();\n server = null;\n });\n\n MobileRpcProtocol.obtainInterop = () => MobileRpcServer.interop;\n mobileReady = true;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"MobileRpcServer.js","sourceRoot":"","sources":["../../../src/backend/MobileRpcServer.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\nimport * as ws from \"ws\";\nimport { IModelError } from \"@itwin/core-common\";\nimport { MobileRpcGateway, MobileRpcProtocol } from \"../common/MobileRpcProtocol\";\nimport { MobileRpcConfiguration } from \"../common/MobileRpcManager\";\nimport { MobileHost } from \"./MobileHost\";\nimport { BentleyStatus, ProcessDetector } from \"@itwin/core-bentley\";\n\ninterface MobileAddon {\n notifyListening: (port: number) => void;\n registerDeviceImpl: () => void;\n}\n\nlet addon: MobileAddon | undefined;\n\n/** @internal */\nexport class MobileRpcServer {\n private static _nextId = -1;\n\n public static interop: MobileRpcGateway = {\n handler: (_payload: ArrayBuffer | string) => { throw new IModelError(BentleyStatus.ERROR, \"Not implemented.\"); },\n sendString: (_message: string, _connectionId: number) => { throw new IModelError(BentleyStatus.ERROR, \"No connection.\"); },\n sendBinary: (_message: Uint8Array, _connectionId: number) => { throw new IModelError(BentleyStatus.ERROR, \"No connection.\"); },\n port: 0,\n connectionId: 0,\n };\n\n private _server: ws.Server;\n private _connection: ws | undefined;\n private _port: number;\n private _connectionId: number;\n private _pingTimer: NodeJS.Timeout;\n public constructor(private _pendingMessages: Array<string | Uint8Array> | undefined = undefined) {\n /* _pingTime is a fix for ios/mobile case where when the app moves into foreground from\n * background backend restart ws.Server and then notify frontend to reconnect. But ws.Server\n * listening event is not fired as node yield to kevent and wait for some io event to happen.\n * This causes a delay in reconnection which may be as long a 40 secs. To solve the issue we\n * create _pingTimer which causes kevent to yield back to uv poll so timer event can be fired.\n * This allow listening event to go through quickly (max 5ms). Once the listening event occur we\n * clear the timer. Here we use setInterval() just to make sure otherwise setTimeout() could equally\n * be effective\n */\n this._pingTimer = setInterval(() => { }, 5);\n this._port = MobileRpcConfiguration.setup.obtainPort();\n this._server = new ws.Server({ port: this._port });\n this._connectionId = ++MobileRpcServer._nextId;\n MobileRpcServer.interop.connectionId = this._connectionId;\n this._onListening();\n this._onConnection();\n }\n\n private _onListening() {\n this._server.on(\"listening\", () => {\n const address = this._server.address() as ws.AddressInfo;\n this._port = address.port;\n clearInterval(this._pingTimer);\n this._notifyListening();\n });\n }\n\n private _notifyListening() {\n MobileRpcServer.interop.port = this._port;\n\n if (addon) {\n addon.notifyListening(this._port);\n }\n\n if (this._connectionId !== 0) {\n MobileHost.reconnect(this._port);\n }\n }\n\n private _onConnection() {\n this._server.on(\"connection\", (connection) => {\n this._connection = connection;\n this._connection.on(\"message\", (data) => this._onConnectionMessage(data));\n this._createSender();\n this._sendPending();\n (global as any).__iTwinJsRpcReady = true;\n MobileHost.onConnected.raiseEvent();\n });\n }\n\n private _createSender() {\n const sender = (message: string | Uint8Array, connectionId: number) => {\n if (connectionId !== this._connectionId) {\n return;\n }\n\n this._connection!.send(message, (err) => {\n if (err) {\n throw err;\n }\n });\n };\n\n MobileRpcServer.interop.sendString = sender;\n MobileRpcServer.interop.sendBinary = sender;\n }\n\n private _sendPending() {\n if (this._pendingMessages === undefined)\n return;\n\n for (const message of this._pendingMessages) {\n this._connection!.send(message, (err) => {\n if (err) {\n throw err;\n }\n });\n }\n this._pendingMessages.length = 0;\n }\n\n private _onConnectionMessage(data: ws.Data) {\n let message = data;\n if (Array.isArray(message)) {\n throw new IModelError(BentleyStatus.ERROR, \"Unsupported data type\");\n }\n\n if (Buffer.isBuffer(message)) {\n if (message.byteOffset !== 0 || message.byteLength !== message.buffer.byteLength) {\n message = new Uint8Array(message.buffer, message.byteOffset, message.byteLength);\n } else {\n message = message.buffer;\n }\n }\n\n MobileRpcServer.interop.handler(message, this._connectionId);\n }\n\n public [Symbol.dispose]() {\n clearInterval(this._pingTimer);\n if (this._connection) {\n MobileRpcServer.interop.sendString = () => { };\n MobileRpcServer.interop.sendBinary = () => { };\n this._connection.close();\n }\n\n this._server.close();\n }\n}\n\nlet mobileReady = false;\nlet hasSuspended = false;\n\nexport function setupMobileRpc() {\n if (mobileReady) {\n return;\n }\n\n if (ProcessDetector.isMobileAppBackend) {\n addon = (process as any)._linkedBinding(\"iModelJsMobile\");\n addon?.registerDeviceImpl();\n }\n\n let server: MobileRpcServer | null = new MobileRpcServer();\n\n /* The UV event loop (internal to node) is retained by handles,\n such as those created for setInterval/setTimeout and client/server connections.\n In a simple app, the RPC server may be the only handle retaining the UV loop.\n Thus, we install a temporary timer on suspend to prevent the loop from exiting prematurely.\n */\n let retainUvLoop: NodeJS.Timeout | undefined;\n const pendingMessages: Array<string | Uint8Array> = [];\n\n function usePendingSender() {\n const sender = (message: string | Uint8Array, _connectionId: number) => {\n pendingMessages.push(message);\n };\n MobileRpcServer.interop.sendString = sender;\n MobileRpcServer.interop.sendBinary = sender;\n }\n\n MobileHost.onEnterBackground.addListener(() => {\n hasSuspended = true;\n\n if (server === null) {\n return;\n }\n\n retainUvLoop = setInterval(() => { }, 1000);\n server[Symbol.dispose]();\n usePendingSender();\n server = null;\n (global as any).__iTwinJsRpcReady = false;\n });\n\n MobileHost.onEnterForeground.addListener(() => {\n if (!hasSuspended) {\n return;\n }\n\n server = new MobileRpcServer(pendingMessages);\n clearInterval(retainUvLoop);\n retainUvLoop = undefined;\n });\n\n MobileHost.onWillTerminate.addListener(() => {\n if (typeof (retainUvLoop) !== \"undefined\") {\n clearInterval(retainUvLoop);\n retainUvLoop = undefined;\n }\n\n if (server === null) {\n return;\n }\n\n server[Symbol.dispose]();\n server = null;\n });\n\n MobileRpcProtocol.obtainInterop = () => MobileRpcServer.interop;\n mobileReady = true;\n}\n"]}
|
|
@@ -20,6 +20,9 @@ exports.requestIdHeaderName = "X-Correlation-Id";
|
|
|
20
20
|
* @internal
|
|
21
21
|
*/
|
|
22
22
|
class ResponseError extends core_bentley_1.BentleyError {
|
|
23
|
+
_data;
|
|
24
|
+
status;
|
|
25
|
+
description;
|
|
23
26
|
constructor(errorNumber, message, getMetaData) {
|
|
24
27
|
super(errorNumber, message, getMetaData);
|
|
25
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Request.js","sourceRoot":"","sources":["../../../src/backend/Request.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module iTwinServiceClients\n */\nimport * as _ from \"lodash\";\nimport * as https from \"https\";\nimport * as sarequest from \"superagent\";\nimport { BentleyError, GetMetaDataFunction, HttpStatus, Logger, LogLevel } from \"@itwin/core-bentley\";\n\nconst loggerCategory: string = \"core-mobile-backend.Request\";\n\n/** @internal */\nexport const requestIdHeaderName = \"X-Correlation-Id\";\n\n/** @internal */\nexport interface RequestQueryStringifyOptions {\n delimiter?: string;\n encode?: boolean;\n}\n\n/** Option to control the time outs\n * Use a short response timeout to detect unresponsive networks quickly, and a long deadline to give time for downloads on slow,\n * but reliable, networks. Note that both of these timers limit how long uploads of attached files are allowed to take. Use long\n * timeouts if you're uploading files.\n * @internal\n */\nexport interface RequestTimeoutOptions {\n /** Sets a deadline (in milliseconds) for the entire request (including all uploads, redirects, server processing time) to complete.\n * If the response isn't fully downloaded within that time, the request will be aborted\n */\n deadline?: number;\n\n /** Sets maximum time (in milliseconds) to wait for the first byte to arrive from the server, but it does not limit how long the entire\n * download can take. Response timeout should be at least few seconds longer than just the time it takes the server to respond, because\n * it also includes time to make DNS lookup, TCP/IP and TLS connections, and time to upload request data.\n */\n response?: number;\n}\n\n/** @internal */\nexport interface RequestOptions {\n method: string;\n headers?: any; // {Mas-App-Guid, Mas-UUid, User-Agent}\n body?: any;\n responseType?: string;\n timeout?: RequestTimeoutOptions; // Optional timeouts. If unspecified, an arbitrary default is setup.\n stream?: any; // Optional stream to read the response to/from (only for NodeJs applications)\n readStream?: any; // Optional stream to read input from (only for NodeJs applications)\n buffer?: any;\n parser?: any;\n accept?: string;\n redirects?: number;\n errorCallback?: (response: any) => ResponseError;\n retryCallback?: (error: any, response: any) => boolean;\n progressCallback?: ProgressCallback;\n agent?: https.Agent;\n retries?: number;\n useCorsProxy?: boolean;\n}\n\n/** Response object if the request was successful. Note that the status within the range of 200-299 are considered as a success.\n * @internal\n */\nexport interface Response {\n body: any; // Parsed body of response\n text: string | undefined; // Returned for responseType:text\n header: any; // Parsed headers of response\n status: number; // Status code of response\n}\n\n/** @internal */\nexport interface ProgressInfo {\n percent?: number;\n total?: number;\n loaded: number;\n}\n\n/** @internal */\nexport type ProgressCallback = (progress: ProgressInfo) => void;\n\n/** Error object that's thrown/rejected if the Request fails due to a network error, or if the status is *not* in the range of 200-299 (inclusive)\n * @internal\n */\nexport class ResponseError extends BentleyError {\n protected _data?: any;\n public status?: number;\n public description?: string;\n public constructor(errorNumber: number | HttpStatus, message?: string, getMetaData?: GetMetaDataFunction) {\n super(errorNumber, message, getMetaData);\n }\n\n /**\n * Parses error from server's response\n * @param response Http response from the server.\n * @returns Parsed error.\n * @internal\n */\n public static parse(response: any, log = true): ResponseError {\n const error = new ResponseError(ResponseError.parseHttpStatus(response.statusType));\n if (!response) {\n error.message = \"Couldn't get response object.\";\n return error;\n }\n\n if (response.response) {\n if (response.response.error) {\n error.name = response.response.error.name || error.name;\n error.description = response.response.error.message;\n }\n if (response.response.res) {\n error.message = response.response.res.statusMessage;\n }\n if (response.response.body && Object.keys(response.response.body).length > 0) {\n error._data = {};\n _.merge(error._data, response.response.body);\n } else {\n error._data = response.response.text;\n }\n }\n\n error.status = response.status || response.statusCode;\n error.name = response.code || response.name || error.name;\n error.message = error.message || response.message || response.statusMessage;\n\n if (log)\n error.log();\n\n return error;\n }\n\n /**\n * Decides whether request should be retried or not\n * @param error Error returned by request\n * @param response Response returned by request\n * @internal\n */\n public static shouldRetry(error: any, response: any): boolean {\n if (error !== undefined && error !== null) {\n if ((error.status === undefined || error.status === null) && (error.res === undefined || error.res === null)) {\n return true;\n }\n }\n return (response !== undefined && response.statusType === HttpStatus.ServerError);\n }\n\n /**\n * @internal\n */\n public static parseHttpStatus(statusType: number): HttpStatus {\n switch (statusType) {\n case 1:\n return HttpStatus.Info;\n case 2:\n return HttpStatus.Success;\n case 3:\n return HttpStatus.Redirection;\n case 4:\n return HttpStatus.ClientError;\n case 5:\n return HttpStatus.ServerError;\n default:\n return HttpStatus.Success;\n }\n }\n\n /**\n * @internal\n */\n public logMessage(): string {\n return `${this.status} ${this.name}: ${this.message}`;\n }\n\n /**\n * Logs this error\n * @internal\n */\n public log(): void {\n Logger.logError(loggerCategory, this.logMessage(), () => this.getMetaData());\n }\n}\n\nconst logResponse = (req: sarequest.SuperAgentRequest, startTime: number) => (res: sarequest.Response) => {\n const elapsed = new Date().getTime() - startTime;\n const elapsedTime = `${elapsed}ms`;\n Logger.logTrace(loggerCategory, `${req.method.toUpperCase()} ${res.status} ${req.url} (${elapsedTime})`);\n};\n\nconst logRequest = (req: sarequest.SuperAgentRequest): sarequest.SuperAgentRequest => {\n const startTime = new Date().getTime();\n return req.on(\"response\", logResponse(req, startTime));\n};\n\n/** Wrapper around making HTTP requests with the specific options.\n *\n * Usable in both a browser and node based environment.\n *\n * @param url Server URL to address the request\n * @param options Options to pass to the request\n * @returns Resolves to the response from the server\n * @throws ResponseError if the request fails due to network issues, or if the returned status is *outside* the range of 200-299 (inclusive)\n * @internal\n */\nexport async function request(url: string, options: RequestOptions): Promise<Response> {\n let sareq: sarequest.SuperAgentRequest = sarequest(options.method, url);\n if (options.retries)\n sareq = sareq.retry(options.retries, options.retryCallback);\n\n if (Logger.isEnabled(loggerCategory, LogLevel.Trace))\n sareq = sareq.use(logRequest);\n\n if (options.headers)\n sareq = sareq.set(options.headers);\n\n Logger.logInfo(loggerCategory, url);\n\n if (options.accept)\n sareq = sareq.accept(options.accept);\n\n if (options.body)\n sareq = sareq.send(options.body);\n\n if (options.timeout)\n sareq = sareq.timeout(options.timeout);\n\n if (options.responseType)\n sareq = sareq.responseType(options.responseType);\n\n if (options.redirects)\n sareq = sareq.redirects(options.redirects);\n else\n sareq = sareq.redirects(0);\n\n if (options.buffer)\n sareq = sareq.buffer(options.buffer);\n\n if (options.parser)\n sareq = sareq.parse(options.parser);\n\n /** Default to any globally supplied proxy, unless an agent is specified in this call */\n if (options.agent)\n sareq = sareq.agent(options.agent);\n\n if (options.progressCallback) {\n sareq = sareq.on(\"progress\", (event: sarequest.ProgressEvent) => {\n if (event) {\n options.progressCallback!({\n loaded: event.loaded,\n total: event.total,\n percent: event.percent,\n });\n }\n });\n }\n\n const errorCallback = options.errorCallback ? options.errorCallback : (response: any) => ResponseError.parse(response);\n\n if (options.readStream) {\n if (typeof window !== \"undefined\")\n throw new Error(\"This option is not supported on browsers\");\n\n return new Promise<Response>((resolve, reject) => {\n sareq = sareq.type(\"blob\");\n options\n .readStream\n .pipe(sareq)\n .on(\"error\", (error: any) => {\n const parsedError = errorCallback(error);\n reject(parsedError);\n })\n .on(\"end\", () => {\n const retResponse: Response = {\n status: 201,\n header: undefined,\n body: undefined,\n text: undefined,\n };\n resolve(retResponse);\n });\n });\n }\n\n if (options.stream) {\n if (typeof window !== \"undefined\")\n throw new Error(\"This option is not supported on browsers\");\n\n return new Promise<Response>((resolve, reject) => {\n sareq\n .on(\"response\", (res: any) => {\n if (res.statusCode !== 200) {\n const parsedError = errorCallback(res);\n reject(parsedError);\n return;\n }\n })\n .pipe(options.stream)\n .on(\"error\", (error: any) => {\n const parsedError = errorCallback(error);\n reject(parsedError);\n })\n .on(\"finish\", () => {\n const retResponse: Response = {\n status: 200,\n header: undefined,\n body: undefined,\n text: undefined,\n };\n resolve(retResponse);\n });\n });\n }\n\n // console.log(\"%s %s %s\", url, options.method, queryStr);\n\n /**\n * Note:\n * Javascript's fetch returns status.OK if error is between 200-299 inclusive, and doesn't reject in this case.\n * Fetch only rejects if there's some network issue (permissions issue or similar)\n * Superagent rejects network issues, and errors outside the range of 200-299. We are currently using\n * superagent, but may eventually switch to JavaScript's fetch library.\n */\n try {\n const response = await sareq;\n const retResponse: Response = {\n body: response.body,\n text: response.text,\n header: response.header,\n status: response.status,\n };\n return retResponse;\n } catch (error) {\n const parsedError = errorCallback(error);\n throw parsedError;\n }\n}\n\n/**\n * fetch json from HTTP request\n * @param url server URL to address the request\n * @internal\n */\nexport async function getJson(url: string): Promise<any> {\n const options: RequestOptions = {\n method: \"GET\",\n responseType: \"json\",\n };\n const data = await request(url, options);\n return data.body;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Request.js","sourceRoot":"","sources":["../../../src/backend/Request.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module iTwinServiceClients\n */\nimport * as _ from \"lodash\";\nimport * as https from \"https\";\nimport * as sarequest from \"superagent\";\nimport { BentleyError, GetMetaDataFunction, HttpStatus, Logger, LogLevel } from \"@itwin/core-bentley\";\n\nconst loggerCategory: string = \"core-mobile-backend.Request\";\n\n/** @internal */\nexport const requestIdHeaderName = \"X-Correlation-Id\";\n\n/** @internal */\nexport interface RequestQueryStringifyOptions {\n delimiter?: string;\n encode?: boolean;\n}\n\n/** Option to control the time outs\n * Use a short response timeout to detect unresponsive networks quickly, and a long deadline to give time for downloads on slow,\n * but reliable, networks. Note that both of these timers limit how long uploads of attached files are allowed to take. Use long\n * timeouts if you're uploading files.\n * @internal\n */\nexport interface RequestTimeoutOptions {\n /** Sets a deadline (in milliseconds) for the entire request (including all uploads, redirects, server processing time) to complete.\n * If the response isn't fully downloaded within that time, the request will be aborted\n */\n deadline?: number;\n\n /** Sets maximum time (in milliseconds) to wait for the first byte to arrive from the server, but it does not limit how long the entire\n * download can take. Response timeout should be at least few seconds longer than just the time it takes the server to respond, because\n * it also includes time to make DNS lookup, TCP/IP and TLS connections, and time to upload request data.\n */\n response?: number;\n}\n\n/** @internal */\nexport interface RequestOptions {\n method: string;\n headers?: any; // {Mas-App-Guid, Mas-UUid, User-Agent}\n body?: any;\n responseType?: string;\n timeout?: RequestTimeoutOptions; // Optional timeouts. If unspecified, an arbitrary default is setup.\n stream?: any; // Optional stream to read the response to/from (only for NodeJs applications)\n readStream?: any; // Optional stream to read input from (only for NodeJs applications)\n buffer?: any;\n parser?: any;\n accept?: string;\n redirects?: number;\n errorCallback?: (response: any) => ResponseError;\n retryCallback?: (error: any, response: any) => boolean;\n progressCallback?: ProgressCallback;\n agent?: https.Agent;\n retries?: number;\n useCorsProxy?: boolean;\n}\n\n/** Response object if the request was successful. Note that the status within the range of 200-299 are considered as a success.\n * @internal\n */\nexport interface Response {\n body: any; // Parsed body of response\n text: string | undefined; // Returned for responseType:text\n header: any; // Parsed headers of response\n status: number; // Status code of response\n}\n\n/** @internal */\nexport interface ProgressInfo {\n percent?: number;\n total?: number;\n loaded: number;\n}\n\n/** @internal */\nexport type ProgressCallback = (progress: ProgressInfo) => void;\n\n/** Error object that's thrown/rejected if the Request fails due to a network error, or if the status is *not* in the range of 200-299 (inclusive)\n * @internal\n */\nexport class ResponseError extends BentleyError {\n protected _data?: any;\n public status?: number;\n public description?: string;\n public constructor(errorNumber: number | HttpStatus, message?: string, getMetaData?: GetMetaDataFunction) {\n super(errorNumber, message, getMetaData);\n }\n\n /**\n * Parses error from server's response\n * @param response Http response from the server.\n * @returns Parsed error.\n * @internal\n */\n public static parse(response: any, log = true): ResponseError {\n const error = new ResponseError(ResponseError.parseHttpStatus(response.statusType));\n if (!response) {\n error.message = \"Couldn't get response object.\";\n return error;\n }\n\n if (response.response) {\n if (response.response.error) {\n error.name = response.response.error.name || error.name;\n error.description = response.response.error.message;\n }\n if (response.response.res) {\n error.message = response.response.res.statusMessage;\n }\n if (response.response.body && Object.keys(response.response.body).length > 0) {\n error._data = {};\n _.merge(error._data, response.response.body);\n } else {\n error._data = response.response.text;\n }\n }\n\n error.status = response.status || response.statusCode;\n error.name = response.code || response.name || error.name;\n error.message = error.message || response.message || response.statusMessage;\n\n if (log)\n error.log();\n\n return error;\n }\n\n /**\n * Decides whether request should be retried or not\n * @param error Error returned by request\n * @param response Response returned by request\n * @internal\n */\n public static shouldRetry(error: any, response: any): boolean {\n if (error !== undefined && error !== null) {\n if ((error.status === undefined || error.status === null) && (error.res === undefined || error.res === null)) {\n return true;\n }\n }\n return (response !== undefined && response.statusType === HttpStatus.ServerError);\n }\n\n /**\n * @internal\n */\n public static parseHttpStatus(statusType: number): HttpStatus {\n switch (statusType) {\n case 1:\n return HttpStatus.Info;\n case 2:\n return HttpStatus.Success;\n case 3:\n return HttpStatus.Redirection;\n case 4:\n return HttpStatus.ClientError;\n case 5:\n return HttpStatus.ServerError;\n default:\n return HttpStatus.Success;\n }\n }\n\n /**\n * @internal\n */\n public logMessage(): string {\n return `${this.status} ${this.name}: ${this.message}`;\n }\n\n /**\n * Logs this error\n * @internal\n */\n public log(): void {\n Logger.logError(loggerCategory, this.logMessage(), () => this.getMetaData());\n }\n}\n\nconst logResponse = (req: sarequest.SuperAgentRequest, startTime: number) => (res: sarequest.Response) => {\n const elapsed = new Date().getTime() - startTime;\n const elapsedTime = `${elapsed}ms`;\n Logger.logTrace(loggerCategory, `${req.method.toUpperCase()} ${res.status} ${req.url} (${elapsedTime})`);\n};\n\nconst logRequest = (req: sarequest.SuperAgentRequest): sarequest.SuperAgentRequest => {\n const startTime = new Date().getTime();\n return req.on(\"response\", logResponse(req, startTime));\n};\n\n/** Wrapper around making HTTP requests with the specific options.\n *\n * Usable in both a browser and node based environment.\n *\n * @param url Server URL to address the request\n * @param options Options to pass to the request\n * @returns Resolves to the response from the server\n * @throws ResponseError if the request fails due to network issues, or if the returned status is *outside* the range of 200-299 (inclusive)\n * @internal\n */\nexport async function request(url: string, options: RequestOptions): Promise<Response> {\n let sareq: sarequest.SuperAgentRequest = sarequest(options.method, url);\n if (options.retries)\n sareq = sareq.retry(options.retries, options.retryCallback);\n\n if (Logger.isEnabled(loggerCategory, LogLevel.Trace))\n sareq = sareq.use(logRequest);\n\n if (options.headers)\n sareq = sareq.set(options.headers);\n\n Logger.logInfo(loggerCategory, url);\n\n if (options.accept)\n sareq = sareq.accept(options.accept);\n\n if (options.body)\n sareq = sareq.send(options.body);\n\n if (options.timeout)\n sareq = sareq.timeout(options.timeout);\n\n if (options.responseType)\n sareq = sareq.responseType(options.responseType);\n\n if (options.redirects)\n sareq = sareq.redirects(options.redirects);\n else\n sareq = sareq.redirects(0);\n\n if (options.buffer)\n sareq = sareq.buffer(options.buffer);\n\n if (options.parser)\n sareq = sareq.parse(options.parser);\n\n /** Default to any globally supplied proxy, unless an agent is specified in this call */\n if (options.agent)\n sareq = sareq.agent(options.agent);\n\n if (options.progressCallback) {\n sareq = sareq.on(\"progress\", (event: sarequest.ProgressEvent) => {\n if (event) {\n options.progressCallback!({\n loaded: event.loaded,\n total: event.total,\n percent: event.percent,\n });\n }\n });\n }\n\n const errorCallback = options.errorCallback ? options.errorCallback : (response: any) => ResponseError.parse(response);\n\n if (options.readStream) {\n if (typeof window !== \"undefined\")\n throw new Error(\"This option is not supported on browsers\");\n\n return new Promise<Response>((resolve, reject) => {\n sareq = sareq.type(\"blob\");\n options\n .readStream\n .pipe(sareq)\n .on(\"error\", (error: any) => {\n const parsedError = errorCallback(error);\n reject(parsedError);\n })\n .on(\"end\", () => {\n const retResponse: Response = {\n status: 201,\n header: undefined,\n body: undefined,\n text: undefined,\n };\n resolve(retResponse);\n });\n });\n }\n\n if (options.stream) {\n if (typeof window !== \"undefined\")\n throw new Error(\"This option is not supported on browsers\");\n\n return new Promise<Response>((resolve, reject) => {\n sareq\n .on(\"response\", (res: any) => {\n if (res.statusCode !== 200) {\n const parsedError = errorCallback(res);\n reject(parsedError);\n return;\n }\n })\n .pipe(options.stream)\n .on(\"error\", (error: any) => {\n const parsedError = errorCallback(error);\n reject(parsedError);\n })\n .on(\"finish\", () => {\n const retResponse: Response = {\n status: 200,\n header: undefined,\n body: undefined,\n text: undefined,\n };\n resolve(retResponse);\n });\n });\n }\n\n // console.log(\"%s %s %s\", url, options.method, queryStr);\n\n /**\n * Note:\n * Javascript's fetch returns status.OK if error is between 200-299 inclusive, and doesn't reject in this case.\n * Fetch only rejects if there's some network issue (permissions issue or similar)\n * Superagent rejects network issues, and errors outside the range of 200-299. We are currently using\n * superagent, but may eventually switch to JavaScript's fetch library.\n */\n try {\n const response = await sareq;\n const retResponse: Response = {\n body: response.body,\n text: response.text,\n header: response.header,\n status: response.status,\n };\n return retResponse;\n } catch (error) {\n const parsedError = errorCallback(error);\n throw parsedError;\n }\n}\n\n/**\n * fetch json from HTTP request\n * @param url server URL to address the request\n * @internal\n */\nexport async function getJson(url: string): Promise<any> {\n const options: RequestOptions = {\n method: \"GET\",\n responseType: \"json\",\n };\n const data = await request(url, options);\n return data.body;\n}\n"]}
|
|
@@ -10,6 +10,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
10
|
exports.MobileEventLoop = void 0;
|
|
11
11
|
/** @internal */
|
|
12
12
|
class MobileEventLoop {
|
|
13
|
+
static _activeTasks = 0;
|
|
14
|
+
static _idleCallback = null;
|
|
13
15
|
static addTask() {
|
|
14
16
|
++this._activeTasks;
|
|
15
17
|
if (this._idleCallback === null) {
|
|
@@ -26,6 +28,4 @@ class MobileEventLoop {
|
|
|
26
28
|
static _idleHandler() { }
|
|
27
29
|
}
|
|
28
30
|
exports.MobileEventLoop = MobileEventLoop;
|
|
29
|
-
MobileEventLoop._activeTasks = 0;
|
|
30
|
-
MobileEventLoop._idleCallback = null;
|
|
31
31
|
//# sourceMappingURL=MobileEventLoop.js.map
|