@itwin/core-mobile 3.5.0-dev.41 → 3.5.0-dev.45
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
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
# Change Log - @itwin/core-mobile
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Thu, 10 Nov 2022 19:32:17 GMT and should not be manually modified.
|
|
4
|
+
|
|
5
|
+
## 3.4.4
|
|
6
|
+
Thu, 10 Nov 2022 19:32:17 GMT
|
|
7
|
+
|
|
8
|
+
_Version update only_
|
|
4
9
|
|
|
5
10
|
## 3.4.3
|
|
6
11
|
Fri, 28 Oct 2022 13:34:58 GMT
|
|
@@ -145,7 +145,7 @@ class MobileFileHandler {
|
|
|
145
145
|
const chunkSize = 4 * 1024 * 1024;
|
|
146
146
|
let buffer = Buffer.alloc(chunkSize);
|
|
147
147
|
const bytesRead = fs.readSync(fileDescriptor, buffer, 0, chunkSize, chunkSize * blockId);
|
|
148
|
-
buffer = buffer.
|
|
148
|
+
buffer = buffer.subarray(0, bytesRead);
|
|
149
149
|
const options = {
|
|
150
150
|
method: "PUT",
|
|
151
151
|
headers: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MobileFileHandler.js","sourceRoot":"","sources":["../../../src/backend/MobileFileHandler.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module iModelHub\r\n */\r\n\r\nimport * as fs from \"fs\";\r\nimport * as https from \"https\";\r\nimport * as path from \"path\";\r\nimport { AccessToken, BentleyError, GetMetaDataFunction, Logger } from \"@itwin/core-bentley\";\r\nimport { ProgressCallback, ProgressInfo, request, RequestOptions } from \"./Request\";\r\nimport { MobileHost } from \"./MobileHost\";\r\nimport { Base64 } from \"js-base64\";\r\n\r\nconst loggerCategory: string = \"mobile.filehandler\";\r\n\r\nconst defined = (argumentName: string, argument?: any, allowEmpty: boolean = false) => {\r\n if (argument === undefined || argument === null || (argument === \"\" && !allowEmpty))\r\n throw Error(`Argument ${argumentName} is null or undefined`);\r\n};\r\n\r\n/** Interface to cancel a request\r\n * @beta\r\n */\r\nexport interface CancelRequest {\r\n /** Returns true if cancel request was acknowledged */\r\n cancel: () => boolean;\r\n}\r\n\r\n/** Error thrown when user cancelled operation\r\n * @internal\r\n */\r\nexport class UserCancelledError extends BentleyError {\r\n public constructor(errorNumber: number, message: string, getMetaData?: GetMetaDataFunction) {\r\n super(errorNumber, message, getMetaData);\r\n this.name = \"User cancelled operation\";\r\n }\r\n}\r\n\r\n/** Error thrown fail to download file. ErrorNumber will correspond to HTTP error code.\r\n * @internal\r\n */\r\nexport class DownloadFailed extends BentleyError {\r\n public constructor(errorNumber: number, message: string, getMetaData?: GetMetaDataFunction) {\r\n super(errorNumber, message, getMetaData);\r\n this.name = \"Fail to download file\";\r\n }\r\n}\r\n\r\n/** Error thrown when sas-url provided for download has expired\r\n * @internal\r\n */\r\nexport class SasUrlExpired extends BentleyError {\r\n public constructor(errorNumber: number, message: string, getMetaData?: GetMetaDataFunction) {\r\n super(errorNumber, message, getMetaData);\r\n this.name = \"SaS url has expired\";\r\n }\r\n}\r\n\r\n/**\r\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.\r\n * @internal\r\n */\r\nexport class MobileFileHandler {\r\n /** @internal */\r\n public agent?: https.Agent;\r\n\r\n /**\r\n * Constructor for MobileFileHandler.\r\n */\r\n constructor() {\r\n }\r\n\r\n /** Create a directory, recursively setting up the path as necessary. */\r\n private static makeDirectoryRecursive(dirPath: string) {\r\n if (fs.existsSync(dirPath))\r\n return;\r\n\r\n MobileFileHandler.makeDirectoryRecursive(path.dirname(dirPath));\r\n fs.mkdirSync(dirPath);\r\n }\r\n\r\n /**\r\n * Make url safe for logging by removing sensitive information\r\n * @param url input url that will be strip of search and query parameters and replace them by ... for security reason\r\n */\r\n private static getSafeUrlForLogging(url: string): string {\r\n const safeToLogDownloadUrl = new URL(url);\r\n if (safeToLogDownloadUrl.search && safeToLogDownloadUrl.search.length > 0)\r\n safeToLogDownloadUrl.search = \"...\";\r\n if (safeToLogDownloadUrl.hash && safeToLogDownloadUrl.hash.length > 0)\r\n safeToLogDownloadUrl.hash = \"...\";\r\n return safeToLogDownloadUrl.toString();\r\n }\r\n\r\n /**\r\n * Check if sas url has expired\r\n * @param download sas url for download\r\n * @param futureSeconds should be valid in future for given seconds.\r\n */\r\n public static isUrlExpired(downloadUrl: string, futureSeconds?: number): boolean {\r\n const sasUrl = new URL(downloadUrl);\r\n const se = sasUrl.searchParams.get(\"se\");\r\n if (se) {\r\n const expiryUTC = new Date(se);\r\n const now = new Date();\r\n const currentUTC = new Date(now.toUTCString());\r\n if (futureSeconds) {\r\n currentUTC.setSeconds(futureSeconds + currentUTC.getSeconds());\r\n }\r\n return expiryUTC <= currentUTC;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\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.\r\n * @param downloadUrl URL to download file from.\r\n * @param downloadToPathname Pathname to download the file to.\r\n * @param fileSize Size of the file that's being downloaded.\r\n * @param progressCallback Callback for tracking progress.\r\n * @throws [[IModelHubClientError]] with [IModelHubStatus.UndefinedArgumentError]($bentley) if one of the arguments is undefined or empty.\r\n */\r\n public async downloadFile(_accessToken: AccessToken, downloadUrl: string, downloadToPathname: string, fileSize?: number, progressCallback?: ProgressCallback, cancelRequest?: CancelRequest): Promise<void> {\r\n // strip search and hash parameters from download Url for logging purpose\r\n const safeToLogUrl = MobileFileHandler.getSafeUrlForLogging(downloadUrl);\r\n Logger.logInfo(loggerCategory, `Downloading file from ${safeToLogUrl}`);\r\n\r\n defined(\"downloadUrl\", downloadUrl);\r\n defined(\"downloadToPathname\", downloadToPathname);\r\n if (MobileFileHandler.isUrlExpired(downloadUrl)) {\r\n Logger.logError(loggerCategory, `Sas url has expired ${safeToLogUrl}`);\r\n throw new SasUrlExpired(403, \"Download URL has expired\");\r\n }\r\n if (fs.existsSync(downloadToPathname))\r\n fs.unlinkSync(downloadToPathname);\r\n\r\n MobileFileHandler.makeDirectoryRecursive(path.dirname(downloadToPathname));\r\n try {\r\n await MobileHost.downloadFile(downloadUrl, downloadToPathname, progressCallback, cancelRequest);\r\n } catch (err) {\r\n if (fs.existsSync(downloadToPathname))\r\n fs.unlinkSync(downloadToPathname); // Just in case there was a partial download, delete the file\r\n\r\n if (!(err instanceof UserCancelledError))\r\n Logger.logError(loggerCategory, `Error downloading file`);\r\n throw err;\r\n }\r\n if (fileSize && fs.existsSync(downloadToPathname)) {\r\n if (fs.lstatSync(downloadToPathname).size !== fileSize) {\r\n fs.unlinkSync(downloadToPathname);\r\n Logger.logError(loggerCategory, `Downloaded file is of incorrect size ${safeToLogUrl}`);\r\n throw new DownloadFailed(403, \"Download failed. Expected filesize does not match\");\r\n }\r\n }\r\n Logger.logTrace(loggerCategory, `Downloaded file from ${safeToLogUrl}`);\r\n }\r\n /** Get encoded block id from its number. */\r\n private getBlockId(blockId: number) {\r\n return Base64.encode(blockId.toString(16).padStart(5, \"0\"));\r\n }\r\n\r\n private async uploadChunk(_accessToken: AccessToken, uploadUrlString: string, fileDescriptor: number, blockId: number, callback?: ProgressCallback) {\r\n const chunkSize = 4 * 1024 * 1024;\r\n let buffer = Buffer.alloc(chunkSize);\r\n const bytesRead = fs.readSync(fileDescriptor, buffer, 0, chunkSize, chunkSize * blockId);\r\n buffer = buffer.slice(0, bytesRead);\r\n\r\n const options: RequestOptions = {\r\n method: \"PUT\",\r\n headers: {\r\n \"x-ms-blob-type\": \"BlockBlob\",\r\n \"Content-Type\": \"application/octet-stream\", // eslint-disable-line @typescript-eslint/naming-convention\r\n \"Content-Length\": buffer.length, // eslint-disable-line @typescript-eslint/naming-convention\r\n },\r\n body: buffer,\r\n progressCallback: callback,\r\n agent: this.agent,\r\n timeout: {\r\n deadline: 60000,\r\n response: 60000,\r\n },\r\n };\r\n\r\n const uploadUrl = `${uploadUrlString}&comp=block&blockid=${this.getBlockId(blockId)}`;\r\n await request(uploadUrl, options);\r\n }\r\n\r\n /**\r\n * Upload a file to AzureBlobStorage for iModelHub.\r\n * @param uploadUrl URL to upload the file to.\r\n * @param uploadFromPathname Pathname to upload the file from.\r\n * @param progressCallback Callback for tracking progress.\r\n * @throws [[IModelHubClientError]] with [IModelHubStatus.UndefinedArgumentError]($bentley) if one of the arguments is undefined or empty.\r\n */\r\n public async uploadFile(accessToken: AccessToken, uploadUrlString: string, uploadFromPathname: string, progressCallback?: ProgressCallback): Promise<void> {\r\n const safeToLogUrl = MobileFileHandler.getSafeUrlForLogging(uploadUrlString);\r\n Logger.logTrace(loggerCategory, `Uploading file to ${safeToLogUrl}`);\r\n defined(\"uploadUrlString\", uploadUrlString);\r\n defined(\"uploadFromPathname\", uploadFromPathname);\r\n\r\n const fileSize = this.getFileSize(uploadFromPathname);\r\n const file = fs.openSync(uploadFromPathname, \"r\");\r\n const chunkSize = 4 * 1024 * 1024;\r\n\r\n try {\r\n let blockList = '<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?><BlockList>';\r\n let i = 0;\r\n const callback: ProgressCallback = (progress: ProgressInfo) => {\r\n const uploaded = i * chunkSize + progress.loaded;\r\n if (progressCallback)\r\n progressCallback({ loaded: uploaded, percent: uploaded / fileSize, total: fileSize });\r\n };\r\n for (; i * chunkSize < fileSize; ++i) {\r\n await this.uploadChunk(accessToken, uploadUrlString, file, i, progressCallback ? callback : undefined);\r\n blockList += `<Latest>${this.getBlockId(i)}</Latest>`;\r\n }\r\n blockList += \"</BlockList>\";\r\n\r\n const options: RequestOptions = {\r\n method: \"PUT\",\r\n headers: {\r\n \"Content-Type\": \"application/xml\", // eslint-disable-line @typescript-eslint/naming-convention\r\n \"Content-Length\": blockList.length, // eslint-disable-line @typescript-eslint/naming-convention\r\n },\r\n body: blockList,\r\n agent: this.agent,\r\n timeout: {\r\n response: 5000,\r\n deadline: 60000,\r\n },\r\n };\r\n\r\n const uploadUrl = `${uploadUrlString}&comp=blocklist`;\r\n await request(uploadUrl, options);\r\n } finally {\r\n fs.closeSync(file);\r\n }\r\n }\r\n\r\n /**\r\n * Get size of a file.\r\n * @param filePath Path of the file.\r\n * @returns Size of the file.\r\n */\r\n public getFileSize(filePath: string): number {\r\n return fs.statSync(filePath).size;\r\n }\r\n\r\n /**\r\n * Check if path is a directory.\r\n * @param filePath Path of the file.\r\n * @returns True if path is directory.\r\n */\r\n public isDirectory(filePath: string): boolean {\r\n return fs.statSync(filePath).isDirectory();\r\n }\r\n\r\n /**\r\n * Check if path exists.\r\n * @param filePath Path of the file.\r\n * @returns True if path exists.\r\n */\r\n public exists(filePath: string): boolean {\r\n return fs.existsSync(filePath);\r\n }\r\n\r\n /**\r\n * Deletes file.\r\n * @param filePath Path of the file.\r\n */\r\n public unlink(filePath: string): void {\r\n fs.unlinkSync(filePath);\r\n }\r\n\r\n /**\r\n * Get file name from the path.\r\n * @param filePath Path of the file.\r\n * @returns File name.\r\n */\r\n public basename(filePath: string): string {\r\n return path.basename(filePath);\r\n }\r\n\r\n /**\r\n * Join multiple strings into a single path.\r\n * @param paths Strings to join.\r\n * @returns Joined path.\r\n */\r\n public join(...paths: string[]): string {\r\n return path.join(...paths);\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"MobileFileHandler.js","sourceRoot":"","sources":["../../../src/backend/MobileFileHandler.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module iModelHub\r\n */\r\n\r\nimport * as fs from \"fs\";\r\nimport * as https from \"https\";\r\nimport * as path from \"path\";\r\nimport { AccessToken, BentleyError, GetMetaDataFunction, Logger } from \"@itwin/core-bentley\";\r\nimport { ProgressCallback, ProgressInfo, request, RequestOptions } from \"./Request\";\r\nimport { MobileHost } from \"./MobileHost\";\r\nimport { Base64 } from \"js-base64\";\r\n\r\nconst loggerCategory: string = \"mobile.filehandler\";\r\n\r\nconst defined = (argumentName: string, argument?: any, allowEmpty: boolean = false) => {\r\n if (argument === undefined || argument === null || (argument === \"\" && !allowEmpty))\r\n throw Error(`Argument ${argumentName} is null or undefined`);\r\n};\r\n\r\n/** Interface to cancel a request\r\n * @beta\r\n */\r\nexport interface CancelRequest {\r\n /** Returns true if cancel request was acknowledged */\r\n cancel: () => boolean;\r\n}\r\n\r\n/** Error thrown when user cancelled operation\r\n * @internal\r\n */\r\nexport class UserCancelledError extends BentleyError {\r\n public constructor(errorNumber: number, message: string, getMetaData?: GetMetaDataFunction) {\r\n super(errorNumber, message, getMetaData);\r\n this.name = \"User cancelled operation\";\r\n }\r\n}\r\n\r\n/** Error thrown fail to download file. ErrorNumber will correspond to HTTP error code.\r\n * @internal\r\n */\r\nexport class DownloadFailed extends BentleyError {\r\n public constructor(errorNumber: number, message: string, getMetaData?: GetMetaDataFunction) {\r\n super(errorNumber, message, getMetaData);\r\n this.name = \"Fail to download file\";\r\n }\r\n}\r\n\r\n/** Error thrown when sas-url provided for download has expired\r\n * @internal\r\n */\r\nexport class SasUrlExpired extends BentleyError {\r\n public constructor(errorNumber: number, message: string, getMetaData?: GetMetaDataFunction) {\r\n super(errorNumber, message, getMetaData);\r\n this.name = \"SaS url has expired\";\r\n }\r\n}\r\n\r\n/**\r\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.\r\n * @internal\r\n */\r\nexport class MobileFileHandler {\r\n /** @internal */\r\n public agent?: https.Agent;\r\n\r\n /**\r\n * Constructor for MobileFileHandler.\r\n */\r\n constructor() {\r\n }\r\n\r\n /** Create a directory, recursively setting up the path as necessary. */\r\n private static makeDirectoryRecursive(dirPath: string) {\r\n if (fs.existsSync(dirPath))\r\n return;\r\n\r\n MobileFileHandler.makeDirectoryRecursive(path.dirname(dirPath));\r\n fs.mkdirSync(dirPath);\r\n }\r\n\r\n /**\r\n * Make url safe for logging by removing sensitive information\r\n * @param url input url that will be strip of search and query parameters and replace them by ... for security reason\r\n */\r\n private static getSafeUrlForLogging(url: string): string {\r\n const safeToLogDownloadUrl = new URL(url);\r\n if (safeToLogDownloadUrl.search && safeToLogDownloadUrl.search.length > 0)\r\n safeToLogDownloadUrl.search = \"...\";\r\n if (safeToLogDownloadUrl.hash && safeToLogDownloadUrl.hash.length > 0)\r\n safeToLogDownloadUrl.hash = \"...\";\r\n return safeToLogDownloadUrl.toString();\r\n }\r\n\r\n /**\r\n * Check if sas url has expired\r\n * @param download sas url for download\r\n * @param futureSeconds should be valid in future for given seconds.\r\n */\r\n public static isUrlExpired(downloadUrl: string, futureSeconds?: number): boolean {\r\n const sasUrl = new URL(downloadUrl);\r\n const se = sasUrl.searchParams.get(\"se\");\r\n if (se) {\r\n const expiryUTC = new Date(se);\r\n const now = new Date();\r\n const currentUTC = new Date(now.toUTCString());\r\n if (futureSeconds) {\r\n currentUTC.setSeconds(futureSeconds + currentUTC.getSeconds());\r\n }\r\n return expiryUTC <= currentUTC;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\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.\r\n * @param downloadUrl URL to download file from.\r\n * @param downloadToPathname Pathname to download the file to.\r\n * @param fileSize Size of the file that's being downloaded.\r\n * @param progressCallback Callback for tracking progress.\r\n * @throws [[IModelHubClientError]] with [IModelHubStatus.UndefinedArgumentError]($bentley) if one of the arguments is undefined or empty.\r\n */\r\n public async downloadFile(_accessToken: AccessToken, downloadUrl: string, downloadToPathname: string, fileSize?: number, progressCallback?: ProgressCallback, cancelRequest?: CancelRequest): Promise<void> {\r\n // strip search and hash parameters from download Url for logging purpose\r\n const safeToLogUrl = MobileFileHandler.getSafeUrlForLogging(downloadUrl);\r\n Logger.logInfo(loggerCategory, `Downloading file from ${safeToLogUrl}`);\r\n\r\n defined(\"downloadUrl\", downloadUrl);\r\n defined(\"downloadToPathname\", downloadToPathname);\r\n if (MobileFileHandler.isUrlExpired(downloadUrl)) {\r\n Logger.logError(loggerCategory, `Sas url has expired ${safeToLogUrl}`);\r\n throw new SasUrlExpired(403, \"Download URL has expired\");\r\n }\r\n if (fs.existsSync(downloadToPathname))\r\n fs.unlinkSync(downloadToPathname);\r\n\r\n MobileFileHandler.makeDirectoryRecursive(path.dirname(downloadToPathname));\r\n try {\r\n await MobileHost.downloadFile(downloadUrl, downloadToPathname, progressCallback, cancelRequest);\r\n } catch (err) {\r\n if (fs.existsSync(downloadToPathname))\r\n fs.unlinkSync(downloadToPathname); // Just in case there was a partial download, delete the file\r\n\r\n if (!(err instanceof UserCancelledError))\r\n Logger.logError(loggerCategory, `Error downloading file`);\r\n throw err;\r\n }\r\n if (fileSize && fs.existsSync(downloadToPathname)) {\r\n if (fs.lstatSync(downloadToPathname).size !== fileSize) {\r\n fs.unlinkSync(downloadToPathname);\r\n Logger.logError(loggerCategory, `Downloaded file is of incorrect size ${safeToLogUrl}`);\r\n throw new DownloadFailed(403, \"Download failed. Expected filesize does not match\");\r\n }\r\n }\r\n Logger.logTrace(loggerCategory, `Downloaded file from ${safeToLogUrl}`);\r\n }\r\n /** Get encoded block id from its number. */\r\n private getBlockId(blockId: number) {\r\n return Base64.encode(blockId.toString(16).padStart(5, \"0\"));\r\n }\r\n\r\n private async uploadChunk(_accessToken: AccessToken, uploadUrlString: string, fileDescriptor: number, blockId: number, callback?: ProgressCallback) {\r\n const chunkSize = 4 * 1024 * 1024;\r\n let buffer = Buffer.alloc(chunkSize);\r\n const bytesRead = fs.readSync(fileDescriptor, buffer, 0, chunkSize, chunkSize * blockId);\r\n buffer = buffer.subarray(0, bytesRead);\r\n\r\n const options: RequestOptions = {\r\n method: \"PUT\",\r\n headers: {\r\n \"x-ms-blob-type\": \"BlockBlob\",\r\n \"Content-Type\": \"application/octet-stream\", // eslint-disable-line @typescript-eslint/naming-convention\r\n \"Content-Length\": buffer.length, // eslint-disable-line @typescript-eslint/naming-convention\r\n },\r\n body: buffer,\r\n progressCallback: callback,\r\n agent: this.agent,\r\n timeout: {\r\n deadline: 60000,\r\n response: 60000,\r\n },\r\n };\r\n\r\n const uploadUrl = `${uploadUrlString}&comp=block&blockid=${this.getBlockId(blockId)}`;\r\n await request(uploadUrl, options);\r\n }\r\n\r\n /**\r\n * Upload a file to AzureBlobStorage for iModelHub.\r\n * @param uploadUrl URL to upload the file to.\r\n * @param uploadFromPathname Pathname to upload the file from.\r\n * @param progressCallback Callback for tracking progress.\r\n * @throws [[IModelHubClientError]] with [IModelHubStatus.UndefinedArgumentError]($bentley) if one of the arguments is undefined or empty.\r\n */\r\n public async uploadFile(accessToken: AccessToken, uploadUrlString: string, uploadFromPathname: string, progressCallback?: ProgressCallback): Promise<void> {\r\n const safeToLogUrl = MobileFileHandler.getSafeUrlForLogging(uploadUrlString);\r\n Logger.logTrace(loggerCategory, `Uploading file to ${safeToLogUrl}`);\r\n defined(\"uploadUrlString\", uploadUrlString);\r\n defined(\"uploadFromPathname\", uploadFromPathname);\r\n\r\n const fileSize = this.getFileSize(uploadFromPathname);\r\n const file = fs.openSync(uploadFromPathname, \"r\");\r\n const chunkSize = 4 * 1024 * 1024;\r\n\r\n try {\r\n let blockList = '<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?><BlockList>';\r\n let i = 0;\r\n const callback: ProgressCallback = (progress: ProgressInfo) => {\r\n const uploaded = i * chunkSize + progress.loaded;\r\n if (progressCallback)\r\n progressCallback({ loaded: uploaded, percent: uploaded / fileSize, total: fileSize });\r\n };\r\n for (; i * chunkSize < fileSize; ++i) {\r\n await this.uploadChunk(accessToken, uploadUrlString, file, i, progressCallback ? callback : undefined);\r\n blockList += `<Latest>${this.getBlockId(i)}</Latest>`;\r\n }\r\n blockList += \"</BlockList>\";\r\n\r\n const options: RequestOptions = {\r\n method: \"PUT\",\r\n headers: {\r\n \"Content-Type\": \"application/xml\", // eslint-disable-line @typescript-eslint/naming-convention\r\n \"Content-Length\": blockList.length, // eslint-disable-line @typescript-eslint/naming-convention\r\n },\r\n body: blockList,\r\n agent: this.agent,\r\n timeout: {\r\n response: 5000,\r\n deadline: 60000,\r\n },\r\n };\r\n\r\n const uploadUrl = `${uploadUrlString}&comp=blocklist`;\r\n await request(uploadUrl, options);\r\n } finally {\r\n fs.closeSync(file);\r\n }\r\n }\r\n\r\n /**\r\n * Get size of a file.\r\n * @param filePath Path of the file.\r\n * @returns Size of the file.\r\n */\r\n public getFileSize(filePath: string): number {\r\n return fs.statSync(filePath).size;\r\n }\r\n\r\n /**\r\n * Check if path is a directory.\r\n * @param filePath Path of the file.\r\n * @returns True if path is directory.\r\n */\r\n public isDirectory(filePath: string): boolean {\r\n return fs.statSync(filePath).isDirectory();\r\n }\r\n\r\n /**\r\n * Check if path exists.\r\n * @param filePath Path of the file.\r\n * @returns True if path exists.\r\n */\r\n public exists(filePath: string): boolean {\r\n return fs.existsSync(filePath);\r\n }\r\n\r\n /**\r\n * Deletes file.\r\n * @param filePath Path of the file.\r\n */\r\n public unlink(filePath: string): void {\r\n fs.unlinkSync(filePath);\r\n }\r\n\r\n /**\r\n * Get file name from the path.\r\n * @param filePath Path of the file.\r\n * @returns File name.\r\n */\r\n public basename(filePath: string): string {\r\n return path.basename(filePath);\r\n }\r\n\r\n /**\r\n * Join multiple strings into a single path.\r\n * @param paths Strings to join.\r\n * @returns Joined path.\r\n */\r\n public join(...paths: string[]): string {\r\n return path.join(...paths);\r\n }\r\n}\r\n"]}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itwin/core-mobile",
|
|
3
|
-
"version": "3.5.0-dev.
|
|
3
|
+
"version": "3.5.0-dev.45",
|
|
4
4
|
"description": "iTwin.js MobileHost and MobileApp",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"engines": {
|
|
7
|
-
"node": ">=12.22.0 < 14.0 || >=14.17.0 <
|
|
7
|
+
"node": ">=12.22.0 < 14.0 || >=14.17.0 < 19.0"
|
|
8
8
|
},
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
@@ -21,11 +21,11 @@
|
|
|
21
21
|
"url": "http://www.bentley.com"
|
|
22
22
|
},
|
|
23
23
|
"peerDependencies": {
|
|
24
|
-
"@itwin/core-backend": "^3.5.0-dev.
|
|
25
|
-
"@itwin/core-bentley": "^3.5.0-dev.
|
|
26
|
-
"@itwin/core-common": "^3.5.0-dev.
|
|
27
|
-
"@itwin/core-frontend": "^3.5.0-dev.
|
|
28
|
-
"@itwin/presentation-common": "^3.5.0-dev.
|
|
24
|
+
"@itwin/core-backend": "^3.5.0-dev.45",
|
|
25
|
+
"@itwin/core-bentley": "^3.5.0-dev.45",
|
|
26
|
+
"@itwin/core-common": "^3.5.0-dev.45",
|
|
27
|
+
"@itwin/core-frontend": "^3.5.0-dev.45",
|
|
28
|
+
"@itwin/presentation-common": "^3.5.0-dev.45"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"deep-assign": "^2.0.0",
|
|
@@ -36,19 +36,19 @@
|
|
|
36
36
|
"ws": "^7.5.3"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@itwin/build-tools": "3.5.0-dev.
|
|
40
|
-
"@itwin/core-backend": "3.5.0-dev.
|
|
41
|
-
"@itwin/core-bentley": "3.5.0-dev.
|
|
42
|
-
"@itwin/core-common": "3.5.0-dev.
|
|
43
|
-
"@itwin/core-frontend": "3.5.0-dev.
|
|
44
|
-
"@itwin/eslint-plugin": "3.5.0-dev.
|
|
45
|
-
"@itwin/presentation-common": "3.5.0-dev.
|
|
39
|
+
"@itwin/build-tools": "3.5.0-dev.45",
|
|
40
|
+
"@itwin/core-backend": "3.5.0-dev.45",
|
|
41
|
+
"@itwin/core-bentley": "3.5.0-dev.45",
|
|
42
|
+
"@itwin/core-common": "3.5.0-dev.45",
|
|
43
|
+
"@itwin/core-frontend": "3.5.0-dev.45",
|
|
44
|
+
"@itwin/eslint-plugin": "3.5.0-dev.45",
|
|
45
|
+
"@itwin/presentation-common": "3.5.0-dev.45",
|
|
46
46
|
"@types/chai": "4.3.1",
|
|
47
47
|
"@types/deep-assign": "^0.1.0",
|
|
48
48
|
"@types/fs-extra": "^4.0.7",
|
|
49
49
|
"@types/lodash": "^4.14.0",
|
|
50
50
|
"@types/mocha": "^8.2.2",
|
|
51
|
-
"@types/node": "
|
|
51
|
+
"@types/node": "18.11.5",
|
|
52
52
|
"@types/qs": "^6.5.0",
|
|
53
53
|
"@types/superagent": "^4.1.14",
|
|
54
54
|
"@types/ws": "^7.0.0",
|