diff --git a/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_getrangelist_with_share_snapshot.json b/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_getrangelist_with_share_snapshot.json
new file mode 100644
index 000000000000..d7ebf29bb6ee
--- /dev/null
+++ b/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_getrangelist_with_share_snapshot.json
@@ -0,0 +1,216 @@
+{
+ "recordings": [
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093520308404681",
+ "query": {
+ "restype": "share"
+ },
+ "requestBody": null,
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "etag": "\"0x8D86061B5AAEA83\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:24 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "c26da3fc-0238-48dd-8c38-27be38ac20e3",
+ "x-ms-request-id": "eb66220e-d01a-0005-624a-921536000000",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093520308404681/dir160093520502604388",
+ "query": {
+ "restype": "directory"
+ },
+ "requestBody": null,
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "etag": "\"0x8D86061B60062DB\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:25 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "1aab52dd-91d3-46af-bec9-0915e2a0bc4d",
+ "x-ms-file-attributes": "Directory",
+ "x-ms-file-change-time": "2020-09-24T08:13:25.4498011Z",
+ "x-ms-file-creation-time": "2020-09-24T08:13:25.4498011Z",
+ "x-ms-file-id": "13835128424026341376",
+ "x-ms-file-last-write-time": "2020-09-24T08:13:25.4498011Z",
+ "x-ms-file-parent-id": "0",
+ "x-ms-file-permission-key": "2065021814682187374*8391130200578712039",
+ "x-ms-request-id": "eb662220-d01a-0005-6e4a-921536000000",
+ "x-ms-request-server-encrypted": "false",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093520308404681/dir160093520502604388/file160093520558100828",
+ "query": {},
+ "requestBody": null,
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "etag": "\"0x8D86061B655BE54\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:26 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "3d0c1b34-8062-46c9-9f91-a4aee3a53239",
+ "x-ms-file-attributes": "Archive",
+ "x-ms-file-change-time": "2020-09-24T08:13:26.0091988Z",
+ "x-ms-file-creation-time": "2020-09-24T08:13:26.0091988Z",
+ "x-ms-file-id": "11529285414812647424",
+ "x-ms-file-last-write-time": "2020-09-24T08:13:26.0091988Z",
+ "x-ms-file-parent-id": "13835128424026341376",
+ "x-ms-file-permission-key": "15912238054059149673*8391130200578712039",
+ "x-ms-request-id": "eb66222d-d01a-0005-774a-921536000000",
+ "x-ms-request-server-encrypted": "false",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093520308404681/dir160093520502604388/file160093520558100828",
+ "query": {
+ "comp": "range"
+ },
+ "requestBody": "Hello",
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "content-md5": "ixqZU8RhEpaoJ6v4xHgE1w==",
+ "etag": "\"0x8D86061B6A8CF7E\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:26 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "688a1677-133c-42d4-80df-ba9d562a8e16",
+ "x-ms-request-id": "eb662232-d01a-0005-7c4a-921536000000",
+ "x-ms-request-server-encrypted": "false",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093520308404681/dir160093520502604388/file160093520558100828",
+ "query": {
+ "comp": "range"
+ },
+ "requestBody": "World",
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "content-md5": "9aeSTmIehMkoCpon4by39g==",
+ "etag": "\"0x8D86061B6D1E2C4\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:26 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "969f103d-eb6d-4c1c-b40e-81d39cc5ebde",
+ "x-ms-request-id": "eb662234-d01a-0005-7e4a-921536000000",
+ "x-ms-request-server-encrypted": "false",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093520308404681/dir160093520502604388/file160093520558100828",
+ "query": {
+ "comp": "range"
+ },
+ "requestBody": null,
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "etag": "\"0x8D86061B6FB6B5B\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:27 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "6c9b9cd8-ac53-4f10-baed-91f6e8f8b0c0",
+ "x-ms-request-id": "eb662237-d01a-0005-014a-921536000000",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093520308404681",
+ "query": {
+ "restype": "share",
+ "comp": "snapshot"
+ },
+ "requestBody": null,
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "etag": "\"0x8D86061B5AAEA83\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:24 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "e94cbfa7-c623-44d4-a31b-f49bdc35b20b",
+ "x-ms-request-id": "eb66223d-d01a-0005-074a-921536000000",
+ "x-ms-snapshot": "2020-09-24T08:13:27.0000000Z",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093520308404681/dir160093520502604388/file160093520558100828",
+ "query": {
+ "comp": "range"
+ },
+ "requestBody": "Hello",
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "content-md5": "ixqZU8RhEpaoJ6v4xHgE1w==",
+ "etag": "\"0x8D86061B776CC5E\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:27 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "55b32162-66d1-4ab0-af6f-32ac401ad9c4",
+ "x-ms-request-id": "eb662243-d01a-0005-0d4a-921536000000",
+ "x-ms-request-server-encrypted": "false",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "GET",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093520308404681/dir160093520502604388/file160093520558100828",
+ "query": {
+ "sharesnapshot": "2020-09-24T08:13:27.0000000Z",
+ "comp": "rangelist"
+ },
+ "requestBody": null,
+ "status": 200,
+ "response": "512512",
+ "responseHeaders": {
+ "content-type": "application/xml",
+ "etag": "\"0x8D86061B6FB6B5B\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:27 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "17a1ce9d-5526-47bd-93cc-c0cbbad57cb6",
+ "x-ms-content-length": "513",
+ "x-ms-request-id": "eb662252-d01a-0005-114a-921536000000",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "DELETE",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093520308404681",
+ "query": {
+ "restype": "share"
+ },
+ "requestBody": null,
+ "status": 202,
+ "response": "",
+ "responseHeaders": {
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "19853fc6-415d-43fa-9ff6-c97d29f76ded",
+ "x-ms-request-id": "eb66225e-d01a-0005-1c4a-921536000000",
+ "x-ms-version": "2020-02-10"
+ }
+ }
+ ],
+ "uniqueTestInfo": {
+ "uniqueName": {
+ "share": "share160093520308404681",
+ "dir": "dir160093520502604388",
+ "file": "file160093520558100828"
+ },
+ "newDate": {}
+ },
+ "hash": "06462ffa1273eddcd96e0ad718d51d94"
+}
\ No newline at end of file
diff --git a/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_getrangelistdiff.json b/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_getrangelistdiff.json
new file mode 100644
index 000000000000..7c19d82db1bc
--- /dev/null
+++ b/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_getrangelistdiff.json
@@ -0,0 +1,196 @@
+{
+ "recordings": [
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093520911907846",
+ "query": {
+ "restype": "share"
+ },
+ "requestBody": null,
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "etag": "\"0x8D86061B86E0B2A\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:29 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "11c289d5-46ea-4704-91ca-0ca2752c0531",
+ "x-ms-request-id": "eb66226a-d01a-0005-284a-921536000000",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093520911907846/dir160093520964907841",
+ "query": {
+ "restype": "directory"
+ },
+ "requestBody": null,
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "etag": "\"0x8D86061B8BFB4F9\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:30 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "bdb8a3ff-e939-40cb-8b0a-59e814ab007a",
+ "x-ms-file-attributes": "Directory",
+ "x-ms-file-change-time": "2020-09-24T08:13:30.0590841Z",
+ "x-ms-file-creation-time": "2020-09-24T08:13:30.0590841Z",
+ "x-ms-file-id": "13835128424026341376",
+ "x-ms-file-last-write-time": "2020-09-24T08:13:30.0590841Z",
+ "x-ms-file-parent-id": "0",
+ "x-ms-file-permission-key": "2065021814682187374*8391130200578712039",
+ "x-ms-request-id": "eb662276-d01a-0005-334a-921536000000",
+ "x-ms-request-server-encrypted": "false",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093520911907846/dir160093520964907841/file160093521018504839",
+ "query": {},
+ "requestBody": null,
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "etag": "\"0x8D86061B910F104\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:30 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "c1979243-3d45-4aa8-95ef-7331b84e4212",
+ "x-ms-file-attributes": "Archive",
+ "x-ms-file-change-time": "2020-09-24T08:13:30.5914628Z",
+ "x-ms-file-creation-time": "2020-09-24T08:13:30.5914628Z",
+ "x-ms-file-id": "11529285414812647424",
+ "x-ms-file-last-write-time": "2020-09-24T08:13:30.5914628Z",
+ "x-ms-file-parent-id": "13835128424026341376",
+ "x-ms-file-permission-key": "15912238054059149673*8391130200578712039",
+ "x-ms-request-id": "eb66228c-d01a-0005-494a-921536000000",
+ "x-ms-request-server-encrypted": "false",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093520911907846/dir160093520964907841/file160093521018504839",
+ "query": {
+ "comp": "range"
+ },
+ "requestBody": "Hello",
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "content-md5": "ixqZU8RhEpaoJ6v4xHgE1w==",
+ "etag": "\"0x8D86061B96190B6\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:31 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "37d0ab2a-1ca0-4997-9033-69437445eb71",
+ "x-ms-request-id": "eb66229c-d01a-0005-574a-921536000000",
+ "x-ms-request-server-encrypted": "false",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093520911907846",
+ "query": {
+ "restype": "share",
+ "comp": "snapshot"
+ },
+ "requestBody": null,
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "etag": "\"0x8D86061B86E0B2A\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:29 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "c73a5527-2e9e-4361-8256-5eae4a7cbfec",
+ "x-ms-request-id": "eb6622ad-d01a-0005-664a-921536000000",
+ "x-ms-snapshot": "2020-09-24T08:13:31.0000000Z",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093520911907846/dir160093520964907841/file160093521018504839",
+ "query": {
+ "comp": "range"
+ },
+ "requestBody": null,
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "etag": "\"0x8D86061B9DB921C\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:31 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "95afae66-9f39-455c-bddc-428ed7a350cb",
+ "x-ms-request-id": "eb6622b3-d01a-0005-6c4a-921536000000",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093520911907846/dir160093520964907841/file160093521018504839",
+ "query": {
+ "comp": "range"
+ },
+ "requestBody": "World",
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "content-md5": "9aeSTmIehMkoCpon4by39g==",
+ "etag": "\"0x8D86061BA0541D6\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:32 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "87781ac4-7ccc-488a-b0fb-df0aff46f33c",
+ "x-ms-request-id": "eb6622b9-d01a-0005-724a-921536000000",
+ "x-ms-request-server-encrypted": "false",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "GET",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093520911907846/dir160093520964907841/file160093521018504839",
+ "query": {
+ "prevsharesnapshot": "2020-09-24T08:13:31.0000000Z",
+ "comp": "rangelist"
+ },
+ "requestBody": null,
+ "status": 200,
+ "response": "05115121535",
+ "responseHeaders": {
+ "content-type": "application/xml",
+ "etag": "\"0x8D86061BA0541D6\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:32 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "8d282248-60c0-46d9-88b6-026e032f094b",
+ "x-ms-content-length": "2049",
+ "x-ms-request-id": "eb6622c9-d01a-0005-804a-921536000000",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "DELETE",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093520911907846",
+ "query": {
+ "restype": "share"
+ },
+ "requestBody": null,
+ "status": 202,
+ "response": "",
+ "responseHeaders": {
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "5dc4a1a5-88d0-499e-9d9c-975d6dbb96b1",
+ "x-ms-request-id": "eb6622d9-d01a-0005-0e4a-921536000000",
+ "x-ms-version": "2020-02-10"
+ }
+ }
+ ],
+ "uniqueTestInfo": {
+ "uniqueName": {
+ "share": "share160093520911907846",
+ "dir": "dir160093520964907841",
+ "file": "file160093521018504839"
+ },
+ "newDate": {}
+ },
+ "hash": "dc7804588649762fa4dd7991f57a1f80"
+}
\ No newline at end of file
diff --git a/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_getrangelistdiff_with_share_snapshot.json b/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_getrangelistdiff_with_share_snapshot.json
new file mode 100644
index 000000000000..4d63c109c28a
--- /dev/null
+++ b/sdk/storage/storage-file-share/recordings/browsers/fileclient/recording_getrangelistdiff_with_share_snapshot.json
@@ -0,0 +1,237 @@
+{
+ "recordings": [
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093521340408444",
+ "query": {
+ "restype": "share"
+ },
+ "requestBody": null,
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "etag": "\"0x8D86061BAFC7DC2\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:33 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "677dd1c0-7537-4df4-99ac-aafabf6356df",
+ "x-ms-request-id": "eb6622e8-d01a-0005-1c4a-921536000000",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093521340408444/dir160093521393907594",
+ "query": {
+ "restype": "directory"
+ },
+ "requestBody": null,
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "etag": "\"0x8D86061BB4E02FB\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:34 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "8dc058fd-d463-4605-8f11-700f68180fa8",
+ "x-ms-file-attributes": "Directory",
+ "x-ms-file-change-time": "2020-09-24T08:13:34.3471355Z",
+ "x-ms-file-creation-time": "2020-09-24T08:13:34.3471355Z",
+ "x-ms-file-id": "13835128424026341376",
+ "x-ms-file-last-write-time": "2020-09-24T08:13:34.3471355Z",
+ "x-ms-file-parent-id": "0",
+ "x-ms-file-permission-key": "2065021814682187374*8391130200578712039",
+ "x-ms-request-id": "eb6622f9-d01a-0005-2a4a-921536000000",
+ "x-ms-request-server-encrypted": "false",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093521340408444/dir160093521393907594/file160093521447407534",
+ "query": {},
+ "requestBody": null,
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "etag": "\"0x8D86061BBA02978\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:34 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "cf2beae9-acb0-4775-8d53-388b8ef058a5",
+ "x-ms-file-attributes": "Archive",
+ "x-ms-file-change-time": "2020-09-24T08:13:34.8855160Z",
+ "x-ms-file-creation-time": "2020-09-24T08:13:34.8855160Z",
+ "x-ms-file-id": "11529285414812647424",
+ "x-ms-file-last-write-time": "2020-09-24T08:13:34.8855160Z",
+ "x-ms-file-parent-id": "13835128424026341376",
+ "x-ms-file-permission-key": "15912238054059149673*8391130200578712039",
+ "x-ms-request-id": "eb662305-d01a-0005-364a-921536000000",
+ "x-ms-request-server-encrypted": "false",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093521340408444/dir160093521393907594/file160093521447407534",
+ "query": {
+ "comp": "range"
+ },
+ "requestBody": "Hello",
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "content-md5": "ixqZU8RhEpaoJ6v4xHgE1w==",
+ "etag": "\"0x8D86061BBF1B394\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:35 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "881218b2-a52d-431d-91b2-ff531d548ff1",
+ "x-ms-request-id": "eb662312-d01a-0005-434a-921536000000",
+ "x-ms-request-server-encrypted": "false",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093521340408444",
+ "query": {
+ "restype": "share",
+ "comp": "snapshot"
+ },
+ "requestBody": null,
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "etag": "\"0x8D86061BAFC7DC2\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:33 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "f7f88397-38ac-4bd2-9f7a-04580fa3ef2d",
+ "x-ms-request-id": "eb66231b-d01a-0005-4b4a-921536000000",
+ "x-ms-snapshot": "2020-09-24T08:13:35.0000000Z",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093521340408444/dir160093521393907594/file160093521447407534",
+ "query": {
+ "comp": "range"
+ },
+ "requestBody": null,
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "etag": "\"0x8D86061BC6C9F14\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:36 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "dc25fc55-e8c1-43dd-8b15-8e08b50cf752",
+ "x-ms-request-id": "eb66231f-d01a-0005-4f4a-921536000000",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093521340408444/dir160093521393907594/file160093521447407534",
+ "query": {
+ "comp": "range"
+ },
+ "requestBody": "World",
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "content-md5": "9aeSTmIehMkoCpon4by39g==",
+ "etag": "\"0x8D86061BC962791\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:36 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "928f45eb-1f36-464b-b4ea-83d7ac0e1908",
+ "x-ms-request-id": "eb662324-d01a-0005-544a-921536000000",
+ "x-ms-request-server-encrypted": "false",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093521340408444",
+ "query": {
+ "restype": "share",
+ "comp": "snapshot"
+ },
+ "requestBody": null,
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "etag": "\"0x8D86061BAFC7DC2\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:33 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "736a00f7-605d-4929-8f40-24bd538a1ea6",
+ "x-ms-request-id": "eb66232b-d01a-0005-594a-921536000000",
+ "x-ms-snapshot": "2020-09-24T08:13:36.0000000Z",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "PUT",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093521340408444/dir160093521393907594/file160093521447407534",
+ "query": {
+ "comp": "range"
+ },
+ "requestBody": "Hello",
+ "status": 201,
+ "response": "",
+ "responseHeaders": {
+ "content-md5": "ixqZU8RhEpaoJ6v4xHgE1w==",
+ "etag": "\"0x8D86061BCEAE698\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:37 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "cd933ba2-4b8f-410e-ad3a-a9f57f51a0e0",
+ "x-ms-request-id": "eb662330-d01a-0005-5e4a-921536000000",
+ "x-ms-request-server-encrypted": "false",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "GET",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093521340408444/dir160093521393907594/file160093521447407534",
+ "query": {
+ "sharesnapshot": "2020-09-24T08:13:36.0000000Z",
+ "prevsharesnapshot": "2020-09-24T08:13:35.0000000Z",
+ "comp": "rangelist"
+ },
+ "requestBody": null,
+ "status": 200,
+ "response": "05115121535",
+ "responseHeaders": {
+ "content-type": "application/xml",
+ "etag": "\"0x8D86061BC962791\"",
+ "last-modified": "Thu, 24 Sep 2020 08:13:36 GMT",
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "f078dcb9-8015-443e-b976-8acc2c971ed9",
+ "x-ms-content-length": "2049",
+ "x-ms-request-id": "eb662338-d01a-0005-654a-921536000000",
+ "x-ms-version": "2020-02-10"
+ }
+ },
+ {
+ "method": "DELETE",
+ "url": "https://fakestorageaccount.file.core.windows.net/share160093521340408444",
+ "query": {
+ "restype": "share"
+ },
+ "requestBody": null,
+ "status": 202,
+ "response": "",
+ "responseHeaders": {
+ "server": "Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0",
+ "x-ms-client-request-id": "25ba29c7-ea5d-4fde-bacf-ac9d3386ed2c",
+ "x-ms-request-id": "eb662343-d01a-0005-6b4a-921536000000",
+ "x-ms-version": "2020-02-10"
+ }
+ }
+ ],
+ "uniqueTestInfo": {
+ "uniqueName": {
+ "share": "share160093521340408444",
+ "dir": "dir160093521393907594",
+ "file": "file160093521447407534"
+ },
+ "newDate": {}
+ },
+ "hash": "5acd47a036848052dec455d515012c9a"
+}
\ No newline at end of file
diff --git a/sdk/storage/storage-file-share/recordings/node/fileclient/recording_getrangelist_with_share_snapshot.js b/sdk/storage/storage-file-share/recordings/node/fileclient/recording_getrangelist_with_share_snapshot.js
new file mode 100644
index 000000000000..099babc58a03
--- /dev/null
+++ b/sdk/storage/storage-file-share/recordings/node/fileclient/recording_getrangelist_with_share_snapshot.js
@@ -0,0 +1,274 @@
+let nock = require('nock');
+
+module.exports.hash = "ecc86a388096f76385f242437ba54e04";
+
+module.exports.testInfo = {"uniqueName":{"share":"share160093496274204261","dir":"dir160093496386306197","file":"file160093496414402587"},"newDate":{}}
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496274204261')
+ .query(true)
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:23 GMT',
+ 'ETag',
+ '"0x8D8606125ECAA54"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc47ad-101a-0013-5c4a-92d4a8000000',
+ 'x-ms-client-request-id',
+ '9f3fc9c8-519a-4053-bd70-a009a88f955b',
+ 'x-ms-version',
+ '2020-02-10',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:23 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496274204261/dir160093496386306197')
+ .query(true)
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:24 GMT',
+ 'ETag',
+ '"0x8D860612619E89B"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc47b9-101a-0013-664a-92d4a8000000',
+ 'x-ms-client-request-id',
+ '74aeced9-0b89-4bfd-bbf7-1de223859b08',
+ 'x-ms-version',
+ '2020-02-10',
+ 'x-ms-file-change-time',
+ '2020-09-24T08:09:24.0251547Z',
+ 'x-ms-file-last-write-time',
+ '2020-09-24T08:09:24.0251547Z',
+ 'x-ms-file-creation-time',
+ '2020-09-24T08:09:24.0251547Z',
+ 'x-ms-file-permission-key',
+ '2065021814682187374*8391130200578712039',
+ 'x-ms-file-attributes',
+ 'Directory',
+ 'x-ms-file-id',
+ '13835128424026341376',
+ 'x-ms-file-parent-id',
+ '0',
+ 'x-ms-request-server-encrypted',
+ 'false',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:23 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496274204261/dir160093496386306197/file160093496414402587')
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:24 GMT',
+ 'ETag',
+ '"0x8D8606126456D6F"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc47ca-101a-0013-734a-92d4a8000000',
+ 'x-ms-client-request-id',
+ '96bc385e-4f8b-4526-a5fb-c1fc21daf807',
+ 'x-ms-version',
+ '2020-02-10',
+ 'x-ms-file-change-time',
+ '2020-09-24T08:09:24.3103599Z',
+ 'x-ms-file-last-write-time',
+ '2020-09-24T08:09:24.3103599Z',
+ 'x-ms-file-creation-time',
+ '2020-09-24T08:09:24.3103599Z',
+ 'x-ms-file-permission-key',
+ '15912238054059149673*8391130200578712039',
+ 'x-ms-file-attributes',
+ 'Archive',
+ 'x-ms-file-id',
+ '11529285414812647424',
+ 'x-ms-file-parent-id',
+ '13835128424026341376',
+ 'x-ms-request-server-encrypted',
+ 'false',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:24 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496274204261/dir160093496386306197/file160093496414402587', "Hello")
+ .query(true)
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Content-MD5',
+ 'ixqZU8RhEpaoJ6v4xHgE1w==',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:24 GMT',
+ 'ETag',
+ '"0x8D86061266FB986"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc47d2-101a-0013-7b4a-92d4a8000000',
+ 'x-ms-client-request-id',
+ '8ce7fbac-becb-452a-b555-aeaebe3b1938',
+ 'x-ms-version',
+ '2020-02-10',
+ 'x-ms-request-server-encrypted',
+ 'false',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:24 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496274204261/dir160093496386306197/file160093496414402587', "World")
+ .query(true)
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Content-MD5',
+ '9aeSTmIehMkoCpon4by39g==',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:24 GMT',
+ 'ETag',
+ '"0x8D860612699421C"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc47d8-101a-0013-014a-92d4a8000000',
+ 'x-ms-client-request-id',
+ '746651a4-17d5-4ff7-b38f-53ef2f4d83c6',
+ 'x-ms-version',
+ '2020-02-10',
+ 'x-ms-request-server-encrypted',
+ 'false',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:24 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496274204261/dir160093496386306197/file160093496414402587')
+ .query(true)
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:25 GMT',
+ 'ETag',
+ '"0x8D8606126C40370"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc47e2-101a-0013-084a-92d4a8000000',
+ 'x-ms-client-request-id',
+ '6af17d2a-74a5-404b-a24a-31eef1d453da',
+ 'x-ms-version',
+ '2020-02-10',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:25 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496274204261')
+ .query(true)
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:23 GMT',
+ 'ETag',
+ '"0x8D8606125ECAA54"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc47e7-101a-0013-0d4a-92d4a8000000',
+ 'x-ms-client-request-id',
+ 'ba3683c6-5499-43f8-946b-56beec2e5283',
+ 'x-ms-version',
+ '2020-02-10',
+ 'x-ms-snapshot',
+ '2020-09-24T08:09:25.0000000Z',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:25 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496274204261/dir160093496386306197/file160093496414402587', "Hello")
+ .query(true)
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Content-MD5',
+ 'ixqZU8RhEpaoJ6v4xHgE1w==',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:25 GMT',
+ 'ETag',
+ '"0x8D860612717FF20"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc47eb-101a-0013-114a-92d4a8000000',
+ 'x-ms-client-request-id',
+ '76d524ee-b24e-407e-abce-8319533d4cbd',
+ 'x-ms-version',
+ '2020-02-10',
+ 'x-ms-request-server-encrypted',
+ 'false',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:25 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .get('/share160093496274204261/dir160093496386306197/file160093496414402587')
+ .query(true)
+ .reply(200, "512512", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Content-Type',
+ 'application/xml',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:25 GMT',
+ 'ETag',
+ '"0x8D8606126C40370"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc47f0-101a-0013-164a-92d4a8000000',
+ 'x-ms-client-request-id',
+ '5c9e0be1-b194-4f4d-b5bd-db27aa781e4d',
+ 'x-ms-version',
+ '2020-02-10',
+ 'x-ms-content-length',
+ '513',
+ 'Access-Control-Expose-Headers',
+ 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Last-Modified,ETag,x-ms-content-length',
+ 'Access-Control-Allow-Origin',
+ '*',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:25 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .delete('/share160093496274204261')
+ .query(true)
+ .reply(202, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc47f6-101a-0013-1b4a-92d4a8000000',
+ 'x-ms-client-request-id',
+ '36207686-0abe-47a3-9690-3c2220535df8',
+ 'x-ms-version',
+ '2020-02-10',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:26 GMT'
+]);
diff --git a/sdk/storage/storage-file-share/recordings/node/fileclient/recording_getrangelistdiff.js b/sdk/storage/storage-file-share/recordings/node/fileclient/recording_getrangelistdiff.js
new file mode 100644
index 000000000000..2830a0f21822
--- /dev/null
+++ b/sdk/storage/storage-file-share/recordings/node/fileclient/recording_getrangelistdiff.js
@@ -0,0 +1,248 @@
+let nock = require('nock');
+
+module.exports.hash = "c882d73842127a37a7d097e998563de1";
+
+module.exports.testInfo = {"uniqueName":{"share":"share160093496636805058","dir":"dir160093496663502172","file":"file160093496691709903"},"newDate":{}}
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496636805058')
+ .query(true)
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:26 GMT',
+ 'ETag',
+ '"0x8D860612796617E"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc47fb-101a-0013-204a-92d4a8000000',
+ 'x-ms-client-request-id',
+ 'b6b37d5c-62c8-4894-b34f-2f3326253c60',
+ 'x-ms-version',
+ '2020-02-10',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:26 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496636805058/dir160093496663502172')
+ .query(true)
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:26 GMT',
+ 'ETag',
+ '"0x8D8606127C17D5D"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc4802-101a-0013-264a-92d4a8000000',
+ 'x-ms-client-request-id',
+ '6cbd36a6-cff3-43c4-9570-397852d72d50',
+ 'x-ms-version',
+ '2020-02-10',
+ 'x-ms-file-change-time',
+ '2020-09-24T08:09:26.8011357Z',
+ 'x-ms-file-last-write-time',
+ '2020-09-24T08:09:26.8011357Z',
+ 'x-ms-file-creation-time',
+ '2020-09-24T08:09:26.8011357Z',
+ 'x-ms-file-permission-key',
+ '2065021814682187374*8391130200578712039',
+ 'x-ms-file-attributes',
+ 'Directory',
+ 'x-ms-file-id',
+ '13835128424026341376',
+ 'x-ms-file-parent-id',
+ '0',
+ 'x-ms-request-server-encrypted',
+ 'false',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:26 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496636805058/dir160093496663502172/file160093496691709903')
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:27 GMT',
+ 'ETag',
+ '"0x8D8606127EBA251"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc4809-101a-0013-2c4a-92d4a8000000',
+ 'x-ms-client-request-id',
+ '6cdbf550-0f4e-4494-80e3-1a743894aea8',
+ 'x-ms-version',
+ '2020-02-10',
+ 'x-ms-file-change-time',
+ '2020-09-24T08:09:27.0773329Z',
+ 'x-ms-file-last-write-time',
+ '2020-09-24T08:09:27.0773329Z',
+ 'x-ms-file-creation-time',
+ '2020-09-24T08:09:27.0773329Z',
+ 'x-ms-file-permission-key',
+ '15912238054059149673*8391130200578712039',
+ 'x-ms-file-attributes',
+ 'Archive',
+ 'x-ms-file-id',
+ '11529285414812647424',
+ 'x-ms-file-parent-id',
+ '13835128424026341376',
+ 'x-ms-request-server-encrypted',
+ 'false',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:26 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496636805058/dir160093496663502172/file160093496691709903', "Hello")
+ .query(true)
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Content-MD5',
+ 'ixqZU8RhEpaoJ6v4xHgE1w==',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:27 GMT',
+ 'ETag',
+ '"0x8D8606128152AE3"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc480e-101a-0013-314a-92d4a8000000',
+ 'x-ms-client-request-id',
+ 'add8c753-ae6e-4012-bd08-c1181d0cc3bb',
+ 'x-ms-version',
+ '2020-02-10',
+ 'x-ms-request-server-encrypted',
+ 'false',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:27 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496636805058')
+ .query(true)
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:26 GMT',
+ 'ETag',
+ '"0x8D860612796617E"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc4813-101a-0013-364a-92d4a8000000',
+ 'x-ms-client-request-id',
+ 'b093cd21-642d-4506-9547-b124b9f1062d',
+ 'x-ms-version',
+ '2020-02-10',
+ 'x-ms-snapshot',
+ '2020-09-24T08:09:27.0000000Z',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:27 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496636805058/dir160093496663502172/file160093496691709903')
+ .query(true)
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:27 GMT',
+ 'ETag',
+ '"0x8D860612867788E"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc481a-101a-0013-3c4a-92d4a8000000',
+ 'x-ms-client-request-id',
+ '2cc2840a-54f4-409a-b6d9-442da3381937',
+ 'x-ms-version',
+ '2020-02-10',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:27 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496636805058/dir160093496663502172/file160093496691709903', "World")
+ .query(true)
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Content-MD5',
+ '9aeSTmIehMkoCpon4by39g==',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:28 GMT',
+ 'ETag',
+ '"0x8D860612890B2F6"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc4822-101a-0013-434a-92d4a8000000',
+ 'x-ms-client-request-id',
+ 'bbf6b3a3-2fea-4bc8-b549-722af5bdc2da',
+ 'x-ms-version',
+ '2020-02-10',
+ 'x-ms-request-server-encrypted',
+ 'false',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:28 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .get('/share160093496636805058/dir160093496663502172/file160093496691709903')
+ .query(true)
+ .reply(200, "05115121535", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Content-Type',
+ 'application/xml',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:28 GMT',
+ 'ETag',
+ '"0x8D860612890B2F6"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc482b-101a-0013-4c4a-92d4a8000000',
+ 'x-ms-client-request-id',
+ '41c801f7-f850-4164-a7bb-166370c2ab3f',
+ 'x-ms-version',
+ '2020-02-10',
+ 'x-ms-content-length',
+ '2049',
+ 'Access-Control-Expose-Headers',
+ 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Last-Modified,ETag,x-ms-content-length',
+ 'Access-Control-Allow-Origin',
+ '*',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:28 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .delete('/share160093496636805058')
+ .query(true)
+ .reply(202, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc4835-101a-0013-544a-92d4a8000000',
+ 'x-ms-client-request-id',
+ '02bf2ca1-1ab0-4d98-89a0-ed1b43b652ef',
+ 'x-ms-version',
+ '2020-02-10',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:28 GMT'
+]);
diff --git a/sdk/storage/storage-file-share/recordings/node/fileclient/recording_getrangelistdiff_with_share_snapshot.js b/sdk/storage/storage-file-share/recordings/node/fileclient/recording_getrangelistdiff_with_share_snapshot.js
new file mode 100644
index 000000000000..4cafe4d52262
--- /dev/null
+++ b/sdk/storage/storage-file-share/recordings/node/fileclient/recording_getrangelistdiff_with_share_snapshot.js
@@ -0,0 +1,298 @@
+let nock = require('nock');
+
+module.exports.hash = "ac99b21fb5d35030f069157846c8dc26";
+
+module.exports.testInfo = {"uniqueName":{"share":"share160093496883503959","dir":"dir160093496910602647","file":"file160093496938007000"},"newDate":{}}
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496883503959')
+ .query(true)
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:28 GMT',
+ 'ETag',
+ '"0x8D86061290F6335"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc483e-101a-0013-5d4a-92d4a8000000',
+ 'x-ms-client-request-id',
+ '59dd1dec-53d7-425d-9666-30324334ccd5',
+ 'x-ms-version',
+ '2020-02-10',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:28 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496883503959/dir160093496910602647')
+ .query(true)
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:29 GMT',
+ 'ETag',
+ '"0x8D86061293946B7"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc484b-101a-0013-684a-92d4a8000000',
+ 'x-ms-client-request-id',
+ 'bc262d54-df93-495e-9ddd-a70b5a28a433',
+ 'x-ms-version',
+ '2020-02-10',
+ 'x-ms-file-change-time',
+ '2020-09-24T08:09:29.2638903Z',
+ 'x-ms-file-last-write-time',
+ '2020-09-24T08:09:29.2638903Z',
+ 'x-ms-file-creation-time',
+ '2020-09-24T08:09:29.2638903Z',
+ 'x-ms-file-permission-key',
+ '2065021814682187374*8391130200578712039',
+ 'x-ms-file-attributes',
+ 'Directory',
+ 'x-ms-file-id',
+ '13835128424026341376',
+ 'x-ms-file-parent-id',
+ '0',
+ 'x-ms-request-server-encrypted',
+ 'false',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:29 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496883503959/dir160093496910602647/file160093496938007000')
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:29 GMT',
+ 'ETag',
+ '"0x8D8606129631D77"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc4853-101a-0013-704a-92d4a8000000',
+ 'x-ms-client-request-id',
+ '11131696-c253-456e-9f8e-a61a0944b783',
+ 'x-ms-version',
+ '2020-02-10',
+ 'x-ms-file-change-time',
+ '2020-09-24T08:09:29.5380855Z',
+ 'x-ms-file-last-write-time',
+ '2020-09-24T08:09:29.5380855Z',
+ 'x-ms-file-creation-time',
+ '2020-09-24T08:09:29.5380855Z',
+ 'x-ms-file-permission-key',
+ '15912238054059149673*8391130200578712039',
+ 'x-ms-file-attributes',
+ 'Archive',
+ 'x-ms-file-id',
+ '11529285414812647424',
+ 'x-ms-file-parent-id',
+ '13835128424026341376',
+ 'x-ms-request-server-encrypted',
+ 'false',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:29 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496883503959/dir160093496910602647/file160093496938007000', "Hello")
+ .query(true)
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Content-MD5',
+ 'ixqZU8RhEpaoJ6v4xHgE1w==',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:29 GMT',
+ 'ETag',
+ '"0x8D86061298D4262"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc485c-101a-0013-794a-92d4a8000000',
+ 'x-ms-client-request-id',
+ 'cd93303c-ce01-4083-b7fc-2b328923923c',
+ 'x-ms-version',
+ '2020-02-10',
+ 'x-ms-request-server-encrypted',
+ 'false',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:29 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496883503959')
+ .query(true)
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:28 GMT',
+ 'ETag',
+ '"0x8D86061290F6335"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc4863-101a-0013-804a-92d4a8000000',
+ 'x-ms-client-request-id',
+ 'fe65db0f-b63c-4519-80a3-e3af8225d632',
+ 'x-ms-version',
+ '2020-02-10',
+ 'x-ms-snapshot',
+ '2020-09-24T08:09:30.0000000Z',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:29 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496883503959/dir160093496910602647/file160093496938007000')
+ .query(true)
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:30 GMT',
+ 'ETag',
+ '"0x8D8606129DFB72A"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc4869-101a-0013-054a-92d4a8000000',
+ 'x-ms-client-request-id',
+ 'd491fba3-2005-47e9-9faf-4096b8778b1f',
+ 'x-ms-version',
+ '2020-02-10',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:30 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496883503959/dir160093496910602647/file160093496938007000', "World")
+ .query(true)
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Content-MD5',
+ '9aeSTmIehMkoCpon4by39g==',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:30 GMT',
+ 'ETag',
+ '"0x8D860612A0A032E"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc486f-101a-0013-0b4a-92d4a8000000',
+ 'x-ms-client-request-id',
+ 'd12a56d1-1338-4cc2-b596-8ef86649f216',
+ 'x-ms-version',
+ '2020-02-10',
+ 'x-ms-request-server-encrypted',
+ 'false',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:30 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496883503959')
+ .query(true)
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:28 GMT',
+ 'ETag',
+ '"0x8D86061290F6335"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc4878-101a-0013-144a-92d4a8000000',
+ 'x-ms-client-request-id',
+ 'f0fd6edd-c08f-4124-a1bd-66ae79c8eff9',
+ 'x-ms-version',
+ '2020-02-10',
+ 'x-ms-snapshot',
+ '2020-09-24T08:09:31.0000000Z',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:30 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .put('/share160093496883503959/dir160093496910602647/file160093496938007000', "Hello")
+ .query(true)
+ .reply(201, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Content-MD5',
+ 'ixqZU8RhEpaoJ6v4xHgE1w==',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:31 GMT',
+ 'ETag',
+ '"0x8D860612A5D899F"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc4881-101a-0013-1d4a-92d4a8000000',
+ 'x-ms-client-request-id',
+ '1c5b2cfc-0311-4c82-89b8-d6f043a1bf99',
+ 'x-ms-version',
+ '2020-02-10',
+ 'x-ms-request-server-encrypted',
+ 'false',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:31 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .get('/share160093496883503959/dir160093496910602647/file160093496938007000')
+ .query(true)
+ .reply(200, "05115121535", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Content-Type',
+ 'application/xml',
+ 'Last-Modified',
+ 'Thu, 24 Sep 2020 08:09:30 GMT',
+ 'ETag',
+ '"0x8D860612A0A032E"',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc4889-101a-0013-254a-92d4a8000000',
+ 'x-ms-client-request-id',
+ 'f2c78a6e-252c-4d5f-8a83-673ab8aed286',
+ 'x-ms-version',
+ '2020-02-10',
+ 'x-ms-content-length',
+ '2049',
+ 'Access-Control-Expose-Headers',
+ 'x-ms-request-id,x-ms-client-request-id,Server,x-ms-version,Content-Type,Last-Modified,ETag,x-ms-content-length',
+ 'Access-Control-Allow-Origin',
+ '*',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:31 GMT'
+]);
+
+nock('https://fakestorageaccount.file.core.windows.net:443', {"encodedQueryParams":true})
+ .delete('/share160093496883503959')
+ .query(true)
+ .reply(202, "", [
+ 'Transfer-Encoding',
+ 'chunked',
+ 'Server',
+ 'Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0',
+ 'x-ms-request-id',
+ '57bc4893-101a-0013-2d4a-92d4a8000000',
+ 'x-ms-client-request-id',
+ '1714bda0-94df-46bb-8f22-38b198f63de0',
+ 'x-ms-version',
+ '2020-02-10',
+ 'Date',
+ 'Thu, 24 Sep 2020 08:09:31 GMT'
+]);
diff --git a/sdk/storage/storage-file-share/review/storage-file-share.api.md b/sdk/storage/storage-file-share/review/storage-file-share.api.md
index 558fe7117de3..a530227db490 100644
--- a/sdk/storage/storage-file-share/review/storage-file-share.api.md
+++ b/sdk/storage/storage-file-share/review/storage-file-share.api.md
@@ -91,6 +91,14 @@ export class AnonymousCredentialPolicy extends CredentialPolicy {
export { BaseRequestPolicy }
+// @public
+export interface ClearRange {
+ // (undocumented)
+ end: number;
+ // (undocumented)
+ start: number;
+}
+
// @public
export interface CloseHandlesInfo {
// (undocumented)
@@ -682,6 +690,15 @@ export type FileGetPropertiesResponse = FileGetPropertiesHeaders & {
};
};
+// @public
+export type FileGetRangeListDiffResponse = ShareFileRangeList & FileGetRangeListHeaders & {
+ _response: coreHttp.HttpResponse & {
+ parsedHeaders: FileGetRangeListHeaders;
+ bodyAsText: string;
+ parsedBody: ShareFileRangeList;
+ };
+};
+
// @public
export interface FileGetRangeListHeaders {
date?: Date;
@@ -1072,6 +1089,7 @@ export interface LeaseOperationResponseHeaders {
etag?: string;
lastModified?: Date;
leaseId?: string;
+ leaseTime?: number;
requestId?: string;
version?: string;
}
@@ -1330,6 +1348,7 @@ export class ShareClient extends StorageClient {
getDirectoryClient(directoryName: string): ShareDirectoryClient;
getPermission(filePermissionKey: string, options?: ShareGetPermissionOptions): Promise;
getProperties(options?: ShareGetPropertiesOptions): Promise;
+ getShareLeaseClient(proposeLeaseId?: string): ShareLeaseClient;
getStatistics(options?: ShareGetStatisticsOptions): Promise;
get name(): string;
get rootDirectoryClient(): ShareDirectoryClient;
@@ -1438,6 +1457,7 @@ export interface ShareDeleteIfExistsResponse extends ShareDeleteResponse {
export interface ShareDeleteMethodOptions extends CommonOptions {
abortSignal?: AbortSignalLike;
deleteSnapshots?: DeleteSnapshotsOptionType;
+ leaseAccessConditions?: LeaseAccessConditions;
}
// @public
@@ -1487,6 +1507,7 @@ export class ShareDirectoryClient extends StorageClient {
// @public
export interface ShareExistsOptions extends CommonOptions {
abortSignal?: AbortSignalLike;
+ leaseAccessConditions?: LeaseAccessConditions;
}
// @public
@@ -1507,6 +1528,7 @@ export class ShareFileClient extends StorageClient {
forceCloseHandle(handleId: string, options?: FileForceCloseHandlesOptions): Promise;
getProperties(options?: FileGetPropertiesOptions): Promise;
getRangeList(options?: FileGetRangeListOptions): Promise;
+ getRangeListDiff(prevShareSnapshot: string, options?: FileGetRangeListOptions): Promise;
getShareLeaseClient(proposeLeaseId?: string): ShareLeaseClient;
listHandles(options?: FileListHandlesOptions): PagedAsyncIterableIterator;
get name(): string;
@@ -1524,6 +1546,15 @@ export class ShareFileClient extends StorageClient {
uploadResetableStream(streamFactory: (offset: number, count?: number) => NodeJS.ReadableStream, size: number, options?: FileParallelUploadOptions): Promise;
uploadSeekableBlob(blobFactory: (offset: number, size: number) => Blob, size: number, options?: FileParallelUploadOptions): Promise;
uploadStream(stream: Readable, size: number, bufferSize: number, maxBuffers: number, options?: FileUploadStreamOptions): Promise;
+ withShareSnapshot(shareSnapshot: string): ShareFileClient;
+}
+
+// @public
+export interface ShareFileRangeList {
+ // (undocumented)
+ clearRanges?: ClearRange[];
+ // (undocumented)
+ ranges?: RangeModel[];
}
// @public
@@ -1540,6 +1571,7 @@ export interface ShareGetAccessPolicyHeaders {
// @public
export interface ShareGetAccessPolicyOptions extends CommonOptions {
abortSignal?: AbortSignalLike;
+ leaseAccessConditions?: LeaseAccessConditions;
}
// @public (undocumented)
@@ -1602,6 +1634,7 @@ export interface ShareGetPropertiesHeaders {
// @public
export interface ShareGetPropertiesOptions extends CommonOptions {
abortSignal?: AbortSignalLike;
+ leaseAccessConditions?: LeaseAccessConditions;
}
// @public
@@ -1625,6 +1658,7 @@ export interface ShareGetStatisticsHeaders {
// @public
export interface ShareGetStatisticsOptions extends CommonOptions {
abortSignal?: AbortSignalLike;
+ leaseAccessConditions?: LeaseAccessConditions;
}
// @public
@@ -1661,12 +1695,13 @@ export interface ShareItem {
// @public
export class ShareLeaseClient {
- constructor(client: ShareFileClient, leaseId?: string);
+ constructor(client: ShareFileClient | ShareClient, leaseId?: string);
acquireLease(duration?: number, options?: LeaseOperationOptions): Promise;
breakLease(options?: LeaseOperationOptions): Promise;
changeLease(proposedLeaseId: string, options?: LeaseOperationOptions): Promise;
get leaseId(): string;
releaseLease(options?: LeaseOperationOptions): Promise;
+ renewLease(options?: LeaseOperationOptions): Promise;
get url(): string;
}
@@ -1747,6 +1782,7 @@ export interface ShareSetAccessPolicyHeaders {
// @public
export interface ShareSetAccessPolicyOptions extends CommonOptions {
abortSignal?: AbortSignalLike;
+ leaseAccessConditions?: LeaseAccessConditions;
}
// @public
@@ -1770,6 +1806,7 @@ export interface ShareSetMetadataHeaders {
// @public
export interface ShareSetMetadataOptions extends CommonOptions {
abortSignal?: AbortSignalLike;
+ leaseAccessConditions?: LeaseAccessConditions;
}
// @public
@@ -1793,6 +1830,7 @@ export interface ShareSetQuotaHeaders {
// @public
export interface ShareSetQuotaOptions extends CommonOptions {
abortSignal?: AbortSignalLike;
+ leaseAccessConditions?: LeaseAccessConditions;
}
// @public
diff --git a/sdk/storage/storage-file-share/src/Clients.ts b/sdk/storage/storage-file-share/src/Clients.ts
new file mode 100644
index 000000000000..3d690c268a7b
--- /dev/null
+++ b/sdk/storage/storage-file-share/src/Clients.ts
@@ -0,0 +1,5960 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import { HttpRequestBody, HttpResponse, isNode, TransferProgressEvent } from "@azure/core-http";
+import { CanonicalCode } from "@opentelemetry/api";
+import { AbortSignalLike } from "@azure/abort-controller";
+import {
+ CopyFileSmbInfo,
+ DeleteSnapshotsOptionType,
+ DirectoryCreateResponse,
+ DirectoryDeleteResponse,
+ DirectoryGetPropertiesResponse,
+ DirectoryItem,
+ DirectoryListFilesAndDirectoriesSegmentResponse,
+ DirectoryListHandlesResponse,
+ DirectorySetMetadataResponse,
+ DirectorySetPropertiesResponse,
+ DirectoryForceCloseHandlesHeaders,
+ FileAbortCopyResponse,
+ FileCreateResponse,
+ FileDeleteResponse,
+ FileDownloadOptionalParams,
+ FileDownloadResponseModel,
+ FileForceCloseHandlesHeaders,
+ FileGetPropertiesResponse,
+ FileGetRangeListHeaders,
+ FileGetRangeListDiffResponse,
+ FileItem,
+ FileListHandlesResponse,
+ FileSetHTTPHeadersResponse,
+ FileSetMetadataResponse,
+ FileStartCopyResponse,
+ FileUploadRangeFromURLResponse,
+ FileUploadRangeResponse,
+ HandleItem,
+ LeaseAccessConditions,
+ RangeModel,
+ ShareCreatePermissionResponse,
+ ShareCreateResponse,
+ ShareCreateSnapshotResponse,
+ ShareDeleteResponse,
+ ShareGetAccessPolicyHeaders,
+ ShareGetPermissionResponse,
+ ShareGetPropertiesResponse,
+ ShareGetStatisticsResponseModel,
+ ShareSetAccessPolicyResponse,
+ ShareSetMetadataResponse,
+ ShareSetQuotaResponse,
+ SignedIdentifierModel,
+ SourceModifiedAccessConditions
+} from "./generatedModels";
+import { Share, Directory, File } from "./generated/src/operations";
+import { newPipeline, StoragePipelineOptions, Pipeline } from "./Pipeline";
+import {
+ DEFAULT_MAX_DOWNLOAD_RETRY_REQUESTS,
+ DEFAULT_HIGH_LEVEL_CONCURRENCY,
+ FILE_MAX_SIZE_BYTES,
+ FILE_RANGE_MAX_SIZE_BYTES,
+ URLConstants
+} from "./utils/constants";
+import {
+ appendToURLPath,
+ setURLParameter,
+ truncatedISO8061Date,
+ extractConnectionStringParts,
+ getShareNameAndPathFromUrl
+} from "./utils/utils.common";
+import { Credential } from "./credentials/Credential";
+import { StorageSharedKeyCredential } from "./credentials/StorageSharedKeyCredential";
+import { AnonymousCredential } from "./credentials/AnonymousCredential";
+import { createSpan } from "./utils/tracing";
+import { StorageClient, CommonOptions } from "./StorageClient";
+import "@azure/core-paging";
+import { PageSettings, PagedAsyncIterableIterator } from "@azure/core-paging";
+import { FileSystemAttributes } from "./FileSystemAttributes";
+import { FileDownloadResponse } from "./FileDownloadResponse";
+import { Range, rangeToString } from "./Range";
+import {
+ CloseHandlesInfo,
+ FileAndDirectoryCreateCommonOptions,
+ FileAndDirectorySetPropertiesCommonOptions,
+ fileAttributesToString,
+ fileCreationTimeToString,
+ FileHttpHeaders,
+ fileLastWriteTimeToString,
+ Metadata,
+ validateAndSetDefaultsForFileAndDirectoryCreateCommonOptions,
+ validateAndSetDefaultsForFileAndDirectorySetPropertiesCommonOptions
+} from "./models";
+import { Batch } from "./utils/Batch";
+import { BufferScheduler } from "./utils/BufferScheduler";
+import { Readable } from "stream";
+import {
+ fsStat,
+ fsCreateReadStream,
+ readStreamToLocalFile,
+ streamToBuffer
+} from "./utils/utils.node";
+import { StorageClientContext } from "./generated/src/storageClientContext";
+import { SERVICE_VERSION } from "./utils/constants";
+import { generateUuid } from "@azure/core-http";
+
+/**
+ * Options to configure the {@link ShareClient.create} operation.
+ *
+ * @export
+ * @interface ShareCreateOptions
+ */
+export interface ShareCreateOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof ShareCreateOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * A name-value pair to associate with a file storage object.
+ *
+ * @type {{ [propertyName: string]: string }}
+ * @memberof ShareCreateOptions
+ */
+ metadata?: { [propertyName: string]: string };
+
+ /**
+ * Specifies the maximum size of the share, in
+ * gigabytes.
+ *
+ * @type {number}
+ * @memberof ShareCreateOptions
+ */
+ quota?: number;
+}
+
+/**
+ * Options to configure the {@link ShareClient.delete} operation.
+ *
+ * @export
+ * @interface ShareDeleteMethodOptions
+ */
+export interface ShareDeleteMethodOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof ShareDeleteMethodOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * Specifies the option
+ * include to delete the base share and all of its snapshots. Possible values
+ * include: 'include'
+ *
+ * @type {DeleteSnapshotsOptionType}
+ * @memberof ShareDeleteMethodOptions
+ */
+ deleteSnapshots?: DeleteSnapshotsOptionType;
+ /**
+ * If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof ShareDeleteMethodOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+/**
+ * Options to configure the {@link ShareClient.setMetadata} operation.
+ *
+ * @export
+ * @interface ShareSetMetadataOptions
+ */
+export interface ShareSetMetadataOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof ShareSetMetadataOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof ShareSetMetadataOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+/**
+ * Options to configure the {@link ShareClient.setAccessPolicy} operation.
+ *
+ * @export
+ * @interface ShareSetAccessPolicyOptions
+ */
+export interface ShareSetAccessPolicyOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof ShareSetAccessPolicyOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof ShareSetAccessPolicyOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+/**
+ * Options to configure the {@link ShareClient.getAccessPolicy} operation.
+ *
+ * @export
+ * @interface ShareGetAccessPolicyOptions
+ */
+export interface ShareGetAccessPolicyOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof ShareGetAccessPolicyOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof ShareGetAccessPolicyOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+/**
+ * Options to configure the {@link ShareClient.exists} operation.
+ *
+ * @export
+ * @interface ShareExistsOptions
+ */
+export interface ShareExistsOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof ShareExistsOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof ShareExistsOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+/**
+ * Options to configure the {@link ShareClient.getProperties} operation.
+ *
+ * @export
+ * @interface ShareGetPropertiesOptions
+ */
+export interface ShareGetPropertiesOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof ShareGetPropertiesOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof ShareGetPropertiesOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+/**
+ * Options to configure the {@link ShareClient.setQuota} operation.
+ *
+ * @export
+ * @interface ShareSetQuotaOptions
+ */
+export interface ShareSetQuotaOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof ShareSetQuotaOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof ShareSetQuotaOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+/**
+ * Options to configure the {@link ShareClient.getStatistics} operation.
+ *
+ * @export
+ * @interface ShareGetStatisticsOptions
+ */
+export interface ShareGetStatisticsOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof ShareGetStatisticsOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * If specified, the operation only succeeds if the resource's lease is active and matches this ID.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof ShareGetStatisticsOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+/**
+ * Signed Identifier
+ *
+ * @export
+ * @interface SignedIdentifier
+ */
+export interface SignedIdentifier {
+ /**
+ * @member {string} id a unique id
+ */
+ id: string;
+ /**
+ * @member {AccessPolicy} accessPolicy
+ */
+ accessPolicy: {
+ /**
+ * @member {Date} startsOn the date-time the policy is active.
+ */
+ startsOn: Date;
+ /**
+ * @member {string} expiresOn the date-time the policy expires.
+ */
+ expiresOn: Date;
+ /**
+ * @member {string} permissions the permissions for the acl policy
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-share-acl
+ */
+ permissions: string;
+ };
+}
+
+export declare type ShareGetAccessPolicyResponse = {
+ signedIdentifiers: SignedIdentifier[];
+} & ShareGetAccessPolicyHeaders & {
+ /**
+ * The underlying HTTP response.
+ */
+ _response: HttpResponse & {
+ /**
+ * The parsed HTTP response headers.
+ */
+ parsedHeaders: ShareGetAccessPolicyHeaders;
+ /**
+ * The response body as text (string format)
+ */
+ bodyAsText: string;
+ /**
+ * The response body as parsed JSON or XML
+ */
+ parsedBody: SignedIdentifierModel[];
+ };
+ };
+
+/**
+ * Options to configure the {@link ShareClient.createSnapshot} operation.
+ *
+ * @export
+ * @interface ShareCreateSnapshotOptions
+ */
+export interface ShareCreateSnapshotOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof ShareCreateSnapshotOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * A name-value pair to associate with a file storage object.
+ *
+ * @type {{ [propertyName: string]: string }}
+ * @memberof ShareCreateOptions
+ */
+ metadata?: { [propertyName: string]: string };
+}
+
+/**
+ * Options to configure the {@link ShareClient.createPermission} operation.
+ *
+ * @export
+ * @interface ShareCreatePermissionOptions
+ */
+export interface ShareCreatePermissionOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof ShareCreatePermissionOptions
+ */
+ abortSignal?: AbortSignalLike;
+}
+/**
+ * Options to configure the {@link ShareClient.getPermission} operation.
+ *
+ * @export
+ * @interface ShareGetPermissionOptions
+ */
+export interface ShareGetPermissionOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof ShareGetPermissionOptions
+ */
+ abortSignal?: AbortSignalLike;
+}
+
+/**
+ * Response data for the {@link ShareClient.getStatistics} Operation.
+ *
+ * @export
+ * @interface ShareGetStatisticsResponse
+ */
+export type ShareGetStatisticsResponse = ShareGetStatisticsResponseModel & {
+ /**
+ * @deprecated shareUsage is going to be deprecated. Please use ShareUsageBytes instead.
+ *
+ * The approximate size of the data stored on the share, rounded up to the nearest gigabyte. Note
+ * that this value may not include all recently created or recently resized files.
+ *
+ * @type {number}
+ * @memberof ShareGetStatisticsResponse
+ */
+ shareUsage: number;
+};
+
+/**
+ * Contains response data for the {@link ShareClient.createIfNotExists} operation.
+ *
+ * @export
+ * @interface ShareCreateIfNotExistsResponse
+ */
+export interface ShareCreateIfNotExistsResponse extends ShareCreateResponse {
+ /**
+ * Indicate whether the share is successfully created. Is false when the share is not changed as it already exists.
+ *
+ * @type {boolean}
+ * @memberof ShareCreateIfNotExistsResponse
+ */
+ succeeded: boolean;
+}
+
+/**
+ * Contains response data for the {@link ShareClient.deleteIfExists} operation.
+ *
+ * @export
+ * @interface ShareDeleteIfExistsResponse
+ */
+export interface ShareDeleteIfExistsResponse extends ShareDeleteResponse {
+ /**
+ * Indicate whether the share is successfully deleted. Is false if the share does not exist in the first place.
+ *
+ * @type {boolean}
+ * @memberof ShareDeleteIfExistsResponse
+ */
+ succeeded: boolean;
+}
+
+/**
+ * A ShareClient represents a URL to the Azure Storage share allowing you to manipulate its directories and files.
+ *
+ * @export
+ * @class ShareClient
+ */
+export class ShareClient extends StorageClient {
+ /**
+ * Share operation context provided by protocol layer.
+ *
+ * @private
+ * @type {Share}
+ * @memberof ShareClient
+ */
+ private context: Share;
+
+ private _name: string;
+
+ /**
+ * The name of the share
+ *
+ * @type {string}
+ * @memberof ShareClient
+ */
+ public get name(): string {
+ return this._name;
+ }
+
+ /**
+ * @param {string} connectionString Account connection string or a SAS connection string of an Azure storage account.
+ * [ Note - Account connection string can only be used in NODE.JS runtime. ]
+ * Account connection string example -
+ * `DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=accountKey;EndpointSuffix=core.windows.net`
+ * SAS connection string example -
+ * `BlobEndpoint=https://myaccount.blob.core.windows.net/;QueueEndpoint=https://myaccount.queue.core.windows.net/;FileEndpoint=https://myaccount.file.core.windows.net/;TableEndpoint=https://myaccount.table.core.windows.net/;SharedAccessSignature=sasString`
+ * @param {string} name Share name.
+ * @param {StoragePipelineOptions} [options] Optional. Options to configure the HTTP pipeline.
+ * @memberof ShareClient
+ */
+ constructor(connectionString: string, name: string, options?: StoragePipelineOptions);
+ /**
+ * Creates an instance of ShareClient.
+ *
+ * @param {string} url A URL string pointing to Azure Storage file share, such as
+ * "https://myaccount.file.core.windows.net/share". You can
+ * append a SAS if using AnonymousCredential, such as
+ * "https://myaccount.file.core.windows.net/share?sasString".
+ * @param {Credential} [credential] Such as AnonymousCredential or StorageSharedKeyCredential.
+ * If not specified, AnonymousCredential is used.
+ * @param {StoragePipelineOptions} [options] Optional. Options to configure the HTTP pipeline.
+ * @memberof ShareClient
+ */
+ constructor(url: string, credential?: Credential, options?: StoragePipelineOptions);
+ /**
+ * Creates an instance of ShareClient.
+ *
+ * @param {string} url A URL string pointing to Azure Storage file share, such as
+ * "https://myaccount.file.core.windows.net/share". You can
+ * append a SAS if using AnonymousCredential, such as
+ * "https://myaccount.file.core.windows.net/share?sasString".
+ * @param {Pipeline} pipeline Call newPipeline() to create a default
+ * pipeline, or provide a customized pipeline.
+ * @memberof ShareClient
+ */
+ constructor(url: string, pipeline: Pipeline);
+ constructor(
+ urlOrConnectionString: string,
+ credentialOrPipelineOrShareName?: Credential | Pipeline | string,
+ options?: StoragePipelineOptions
+ ) {
+ let pipeline: Pipeline;
+ let url: string;
+ if (credentialOrPipelineOrShareName instanceof Pipeline) {
+ // (url: string, pipeline: Pipeline)
+ url = urlOrConnectionString;
+ pipeline = credentialOrPipelineOrShareName;
+ } else if (credentialOrPipelineOrShareName instanceof Credential) {
+ // (url: string, credential?: Credential, options?: StoragePipelineOptions)
+ url = urlOrConnectionString;
+ pipeline = newPipeline(credentialOrPipelineOrShareName, options);
+ } else if (
+ !credentialOrPipelineOrShareName &&
+ typeof credentialOrPipelineOrShareName !== "string"
+ ) {
+ // (url: string, credential?: Credential, options?: StoragePipelineOptions)
+ // The second parameter is undefined. Use anonymous credential.
+ url = urlOrConnectionString;
+ pipeline = newPipeline(new AnonymousCredential(), options);
+ } else if (
+ credentialOrPipelineOrShareName &&
+ typeof credentialOrPipelineOrShareName === "string"
+ ) {
+ // (connectionString: string, name: string, options?: StoragePipelineOptions)
+ const extractedCreds = extractConnectionStringParts(urlOrConnectionString);
+ const name = credentialOrPipelineOrShareName;
+ if (extractedCreds.kind === "AccountConnString") {
+ if (isNode) {
+ const sharedKeyCredential = new StorageSharedKeyCredential(
+ extractedCreds.accountName!,
+ extractedCreds.accountKey
+ );
+ url = appendToURLPath(extractedCreds.url, name);
+ pipeline = newPipeline(sharedKeyCredential, options);
+ } else {
+ throw new Error("Account connection string is only supported in Node.js environment");
+ }
+ } else if (extractedCreds.kind === "SASConnString") {
+ url = appendToURLPath(extractedCreds.url, name) + "?" + extractedCreds.accountSas;
+ pipeline = newPipeline(new AnonymousCredential(), options);
+ } else {
+ throw new Error(
+ "Connection string must be either an Account connection string or a SAS connection string"
+ );
+ }
+ } else {
+ throw new Error("Expecting non-empty strings for name parameter");
+ }
+ super(url, pipeline);
+ this._name = getShareNameAndPathFromUrl(this.url).shareName;
+ this.context = new Share(this.storageClientContext);
+ }
+
+ /**
+ * Creates a new ShareClient object identical to the source but with the specified snapshot timestamp.
+ * Provide "" will remove the snapshot and return a URL to the base share.
+ *
+ * @param {string} snapshot The snapshot timestamp.
+ * @returns {ShareClient} A new ShareClient object identical to the source but with the specified snapshot timestamp
+ * @memberof ShareClient
+ */
+ public withSnapshot(snapshot: string): ShareClient {
+ return new ShareClient(
+ setURLParameter(
+ this.url,
+ URLConstants.Parameters.SHARE_SNAPSHOT,
+ snapshot.length === 0 ? undefined : snapshot
+ ),
+ this.pipeline
+ );
+ }
+
+ /**
+ * Creates a new share under the specified account. If the share with
+ * the same name already exists, the operation fails.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-share
+ *
+ * @param {ShareCreateOptions} [options] Options to Share Create operation.
+ * @returns {Promise} Response data for the Share Create operation.
+ * @memberof ShareClient
+ */
+ public async create(options: ShareCreateOptions = {}): Promise {
+ const { span, spanOptions } = createSpan("ShareClient-create", options.tracingOptions);
+ try {
+ return await this.context.create({
+ ...options,
+ spanOptions
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Creates a new share under the specified account. If the share with
+ * the same name already exists, it is not changed.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-share
+ *
+ * @param {ShareCreateOptions} [options]
+ * @returns {Promise}
+ * @memberof ShareClient
+ */
+ public async createIfNotExists(
+ options: ShareCreateOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareClient-createIfNotExists",
+ options.tracingOptions
+ );
+ try {
+ const res = await this.create({
+ ...options,
+ tracingOptions: { ...options!.tracingOptions, spanOptions }
+ });
+ return {
+ succeeded: true,
+ ...res
+ };
+ } catch (e) {
+ if (e.details?.errorCode === "ShareAlreadyExists") {
+ span.setStatus({
+ code: CanonicalCode.ALREADY_EXISTS,
+ message: "Expected exception when creating a share only if it doesn't already exist."
+ });
+ return {
+ succeeded: false,
+ ...e.response?.parsedHeaders,
+ _response: e.response
+ };
+ }
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Creates a {@link ShareDirectoryClient} object.
+ *
+ * @param directoryName A directory name
+ * @returns {ShareDirectoryClient} The ShareDirectoryClient object for the given directory name.
+ * @memberof ShareClient
+ */
+ public getDirectoryClient(directoryName: string): ShareDirectoryClient {
+ return new ShareDirectoryClient(
+ appendToURLPath(this.url, encodeURIComponent(directoryName)),
+ this.pipeline
+ );
+ }
+
+ /**
+ * Gets the directory client for the root directory of this share.
+ * Note that the root directory always exists and cannot be deleted.
+ *
+ * @readonly
+ * @type {ShareDirectoryClient} A new ShareDirectoryClient object for the root directory.
+ * @memberof ShareClient
+ */
+ public get rootDirectoryClient(): ShareDirectoryClient {
+ return this.getDirectoryClient("");
+ }
+
+ /**
+ * Creates a new subdirectory under this share.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-directory
+ *
+ * @param {string} directoryName
+ * @param {DirectoryCreateOptions} [options] Options to Directory Create operation.
+ * @returns {Promise<{ directoryClient: ShareDirectoryClient, directoryCreateResponse: DirectoryCreateResponse }>} Directory creation response data and the corresponding directory client.
+ * @memberof ShareClient
+ */
+ public async createDirectory(
+ directoryName: string,
+ options: DirectoryCreateOptions = {}
+ ): Promise<{
+ directoryClient: ShareDirectoryClient;
+ directoryCreateResponse: DirectoryCreateResponse;
+ }> {
+ const { span, spanOptions } = createSpan("ShareClient-createDirectory", options.tracingOptions);
+ try {
+ const directoryClient = this.getDirectoryClient(directoryName);
+ const directoryCreateResponse = await directoryClient.create({
+ ...options,
+ tracingOptions: { ...options.tracingOptions, spanOptions }
+ });
+ return {
+ directoryClient,
+ directoryCreateResponse
+ };
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Removes the specified empty sub directory under this share.
+ * Note that the directory must be empty before it can be deleted.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-directory
+ *
+ * @param {string} directoryName
+ * @param {DirectoryDeleteOptions} [options] Options to Directory Delete operation.
+ * @returns {Promise} Directory deletion response data.
+ * @memberof ShareClient
+ */
+ public async deleteDirectory(
+ directoryName: string,
+ options: DirectoryDeleteOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan("ShareClient-deleteDirectory", options.tracingOptions);
+ try {
+ const directoryClient = this.getDirectoryClient(directoryName);
+ return await directoryClient.delete({
+ ...options,
+ tracingOptions: { ...options.tracingOptions, spanOptions }
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Creates a new file or replaces a file under the root directory of this share.
+ * Note it only initializes the file with no content.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-file
+ *
+ * @param {string} fileName
+ * @param {number} size Specifies the maximum size in bytes for the file, up to 1 TB.
+ * @param {FileCreateOptions} [options] Options to File Create operation.
+ * @returns {Promise<{ fileClient: ShareFileClient, fileCreateResponse: FileCreateResponse }>} File creation response data and the corresponding file client.
+ * @memberof ShareClient
+ */
+ public async createFile(
+ fileName: string,
+ size: number,
+ options: FileCreateOptions = {}
+ ): Promise<{ fileClient: ShareFileClient; fileCreateResponse: FileCreateResponse }> {
+ const { span, spanOptions } = createSpan("ShareClient-createFile", options.tracingOptions);
+ try {
+ const directoryClient = this.rootDirectoryClient;
+ const fileClient = directoryClient.getFileClient(fileName);
+ const fileCreateResponse = await fileClient.create(size, {
+ ...options,
+ tracingOptions: { ...options.tracingOptions, spanOptions }
+ });
+ return {
+ fileClient,
+ fileCreateResponse
+ };
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Removes a file under the root directory of this share from the storage account.
+ * When a file is successfully deleted, it is immediately removed from the storage
+ * account's index and is no longer accessible to clients. The file's data is later
+ * removed from the service during garbage collection.
+ *
+ * Delete File will fail with status code 409 (Conflict) and error code `SharingViolation`
+ * if the file is open on an SMB client.
+ *
+ * Delete File is not supported on a share snapshot, which is a read-only copy of
+ * a share. An attempt to perform this operation on a share snapshot will fail with 400
+ * (`InvalidQueryParameterValue`)
+ *
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-file2
+ *
+ * @param {string} directoryName
+ * @param {string} fileName
+ * @param {FileDeleteOptions} [options] Options to File Delete operation.
+ * @returns Promise File Delete response data.
+ * @memberof ShareClient
+ */
+ public async deleteFile(
+ fileName: string,
+ options: FileDeleteOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan("ShareClient-deleteFile", options.tracingOptions);
+ try {
+ const directoryClient = this.rootDirectoryClient;
+ const fileClient = directoryClient.getFileClient(fileName);
+ return await fileClient.delete({
+ ...options,
+ tracingOptions: { ...options.tracingOptions, spanOptions }
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Returns true if the Azrue share resource represented by this client exists; false otherwise.
+ *
+ * NOTE: use this function with care since an existing share might be deleted by other clients or
+ * applications. Vice versa new shares might be added by other clients or applications after this
+ * function completes.
+ *
+ * @param {ShareExistsOptions} [options] options to Exists operation.
+ * @returns {Promise}
+ * @memberof ShareClient
+ */
+ public async exists(options: ShareExistsOptions = {}): Promise {
+ const { span, spanOptions } = createSpan("ShareClient-exists", options.tracingOptions);
+ try {
+ await this.getProperties({
+ ...options,
+ tracingOptions: { ...options.tracingOptions, spanOptions }
+ });
+ return true;
+ } catch (e) {
+ if (e.statusCode === 404) {
+ span.setStatus({
+ code: CanonicalCode.NOT_FOUND,
+ message: "Expected exception when checking share existence"
+ });
+ return false;
+ }
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Returns all user-defined metadata and system properties for the specified
+ * share.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-share-properties
+ *
+ * WARNING: The `metadata` object returned in the response will have its keys in lowercase, even if
+ * they originally contained uppercase characters. This differs from the metadata keys returned by
+ * the `listShares` method of {@link ShareServiceClient} using the `includeMetadata` option, which
+ * will retain their original casing.
+ *
+ * @returns {Promise} Response data for the Share Get Properties operation.
+ * @memberof ShareClient
+ */
+ public async getProperties(
+ options: ShareGetPropertiesOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan("ShareClient-getProperties", options.tracingOptions);
+ try {
+ return await this.context.getProperties({
+ ...options,
+ spanOptions
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Marks the specified share for deletion. The share and any directories or files
+ * contained within it are later deleted during garbage collection.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-share
+ *
+ * @param {ShareDeleteMethodOptions} [options] Options to Share Delete operation.
+ * @returns {Promise} Response data for the Share Delete operation.
+ * @memberof ShareClient
+ */
+ public async delete(options: ShareDeleteMethodOptions = {}): Promise {
+ const { span, spanOptions } = createSpan("ShareClient-delete", options.tracingOptions);
+ try {
+ return await this.context.deleteMethod({
+ ...options,
+ spanOptions
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Marks the specified share for deletion if it exists. The share and any directories or files
+ * contained within it are later deleted during garbage collection.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-share
+ *
+ * @param {ShareDeleteMethodOptions} [options]
+ * @returns {Promise}
+ * @memberof ShareClient
+ */
+ public async deleteIfExists(
+ options: ShareDeleteMethodOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan("ShareClient-deleteIfExists", options.tracingOptions);
+ try {
+ const res = await this.delete({
+ ...options,
+ tracingOptions: { ...options!.tracingOptions, spanOptions }
+ });
+ return {
+ succeeded: true,
+ ...res
+ };
+ } catch (e) {
+ if (e.details?.errorCode === "ShareNotFound") {
+ span.setStatus({
+ code: CanonicalCode.NOT_FOUND,
+ message: "Expected exception when deleting a share only if it exists."
+ });
+ return {
+ succeeded: false,
+ ...e.response?.parsedHeaders,
+ _response: e.response
+ };
+ }
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Sets one or more user-defined name-value pairs for the specified share.
+ *
+ * If no option provided, or no metadata defined in the option parameter, the share
+ * metadata will be removed.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-share-metadata
+ *
+ * @param {Metadata} [metadata] If no metadata provided, all existing directory metadata will be removed.
+ * @param {ShareSetMetadataOptions} [option] Options to Share Set Metadata operation.
+ * @returns {Promise} Response data for the Share Set Metadata operation.
+ * @memberof ShareClient
+ */
+ public async setMetadata(
+ metadata?: Metadata,
+ options: ShareSetMetadataOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan("ShareClient-setMetadata", options.tracingOptions);
+ try {
+ return await this.context.setMetadata({
+ ...options,
+ metadata,
+ spanOptions
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Gets the permissions for the specified share. The permissions indicate
+ * whether share data may be accessed publicly.
+ *
+ * WARNING: JavaScript Date will potential lost precision when parsing start and expiry string.
+ * For example, new Date("2018-12-31T03:44:23.8827891Z").toISOString() will get "2018-12-31T03:44:23.882Z".
+ *
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-share-acl
+ *
+ * @param {ShareGetAccessPolicyOptions} [option] Options to Share Get Access Policy operation.
+ * @returns {Promise} Response data for the Share Get Access Policy operation.
+ * @memberof ShareClient
+ */
+ public async getAccessPolicy(
+ options: ShareGetAccessPolicyOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan("ShareClient-getAccessPolicy", options.tracingOptions);
+ try {
+ const response = await this.context.getAccessPolicy({
+ ...options,
+ spanOptions
+ });
+
+ const res: ShareGetAccessPolicyResponse = {
+ _response: response._response,
+ date: response.date,
+ etag: response.etag,
+ lastModified: response.lastModified,
+ requestId: response.requestId,
+ signedIdentifiers: [],
+ version: response.version
+ };
+
+ for (const identifier of response) {
+ res.signedIdentifiers.push({
+ accessPolicy: {
+ expiresOn: new Date(identifier.accessPolicy!.expiresOn!),
+ permissions: identifier.accessPolicy!.permissions!,
+ startsOn: new Date(identifier.accessPolicy!.startsOn!)
+ },
+ id: identifier.id
+ });
+ }
+
+ return res;
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Sets the permissions for the specified share. The permissions indicate
+ * whether directories or files in a share may be accessed publicly.
+ *
+ * When you set permissions for a share, the existing permissions are replaced.
+ * If no shareAcl provided, the existing share ACL will be
+ * removed.
+ *
+ * When you establish a stored access policy on a share, it may take up to 30 seconds to take effect.
+ * During this interval, a shared access signature that is associated with the stored access policy will
+ * fail with status code 403 (Forbidden), until the access policy becomes active.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-share-acl
+ *
+ * @param {SignedIdentifier[]} [shareAcl] Array of signed identifiers, each having a unique Id and details of access policy.
+ * @param {ShareSetAccessPolicyOptions} [option] Options to Share Set Access Policy operation.
+ * @returns {Promise} Response data for the Share Set Access Policy operation.
+ * @memberof ShareClient
+ */
+ public async setAccessPolicy(
+ shareAcl?: SignedIdentifier[],
+ options: ShareSetAccessPolicyOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan("ShareClient-setAccessPolicy", options.tracingOptions);
+ try {
+ const acl: SignedIdentifierModel[] = [];
+ for (const identifier of shareAcl || []) {
+ acl.push({
+ accessPolicy: {
+ expiresOn: truncatedISO8061Date(identifier.accessPolicy.expiresOn),
+ permissions: identifier.accessPolicy.permissions,
+ startsOn: truncatedISO8061Date(identifier.accessPolicy.startsOn)
+ },
+ id: identifier.id
+ });
+ }
+
+ return await this.context.setAccessPolicy({
+ ...options,
+ shareAcl: acl,
+ spanOptions
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Creates a read-only snapshot of a share.
+ *
+ * @param {ShareCreateSnapshotOptions} [options={}] Options to Share Create Snapshot operation.
+ * @returns {Promise} Response data for the Share Create Snapshot operation.
+ * @memberof ShareClient
+ */
+ public async createSnapshot(
+ options: ShareCreateSnapshotOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan("ShareClient-createSnapshot", options.tracingOptions);
+ try {
+ return await this.context.createSnapshot({
+ abortSignal: options.abortSignal,
+ ...options,
+ spanOptions
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Sets quota for the specified share.
+ *
+ * @param {number} quotaInGB Specifies the maximum size of the share in gigabytes
+ * @param {ShareSetQuotaOptions} [option] Options to Share Set Quota operation.
+ * @returns {Promise} Response data for the Share Get Quota operation.
+ * @memberof ShareClient
+ */
+ public async setQuota(
+ quotaInGB: number,
+ options: ShareSetQuotaOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan("ShareClient-setQuota", options.tracingOptions);
+ try {
+ if (quotaInGB <= 0 || quotaInGB > 5120) {
+ throw new RangeError(
+ `Share quota must be greater than 0, and less than or equal to 5Tib (5120GB)`
+ );
+ }
+ return await this.context.setQuota({
+ ...options,
+ quota: quotaInGB,
+ spanOptions
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Retrieves statistics related to the share.
+ *
+ * @param {ShareGetStatisticsOptions} [option] Options to Share Get Statistics operation.
+ * @returns {Promise} Response data for the Share Get Statistics operation.
+ * @memberof ShareClient
+ */
+ public async getStatistics(
+ options: ShareGetStatisticsOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan("ShareClient-getStatistics", options.tracingOptions);
+ try {
+ const response = await this.context.getStatistics({
+ ...options,
+ spanOptions
+ });
+
+ const GBBytes = 1024 * 1024 * 1024;
+ return { ...response, shareUsage: Math.ceil(response.shareUsageBytes / GBBytes) };
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Creates a file permission (a security descriptor) at the share level.
+ * The created security descriptor can be used for the files/directories in the share.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-permission
+ *
+ * @param {ShareCreatePermissionOptions} [options] Options to Share Create Permission operation.
+ * @param filePermission File permission described in the SDDL
+ */
+ public async createPermission(
+ filePermission: string,
+ options: ShareCreatePermissionOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareClient-createPermission",
+ options.tracingOptions
+ );
+ try {
+ return await this.context.createPermission(
+ {
+ permission: filePermission
+ },
+ {
+ abortSignal: options.abortSignal,
+ spanOptions
+ }
+ );
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Gets the Security Descriptor Definition Language (SDDL) for a given file permission key
+ * which indicates a security descriptor.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-permission
+ *
+ * @param {ShareGetPermissionOptions} [options] Options to Share Create Permission operation.
+ * @param filePermissionKey File permission key which indicates the security descriptor of the permission.
+ */
+ public async getPermission(
+ filePermissionKey: string,
+ options: ShareGetPermissionOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan("ShareClient-getPermission", options.tracingOptions);
+ try {
+ return await this.context.getPermission(filePermissionKey, {
+ aborterSignal: options.abortSignal,
+ spanOptions
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Get a {@link ShareLeaseClient} that manages leases on the share.
+ *
+ * @param {string} [proposeLeaseId] Initial proposed lease Id.
+ * @returns {ShareLeaseClient} A new ShareLeaseClient object for managing leases on the share.
+ * @memberof ShareClient
+ */
+ public getShareLeaseClient(proposeLeaseId?: string) {
+ return new ShareLeaseClient(this, proposeLeaseId);
+ }
+}
+
+/**
+ * Options to configure {@link ShareDirectoryClient.create} operation.
+ *
+ * @export
+ * @interface DirectoryCreateOptions
+ */
+export interface DirectoryCreateOptions extends FileAndDirectoryCreateCommonOptions, CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof DirectoryCreateOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * A collection of key-value string pair to associate with the file storage object.
+ *
+ * @type {Metadata}
+ * @memberof DirectoryCreateOptions
+ */
+ metadata?: Metadata;
+}
+
+export interface DirectoryProperties
+ extends FileAndDirectorySetPropertiesCommonOptions,
+ CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof DirectoryProperties
+ */
+ abortSignal?: AbortSignalLike;
+}
+
+/**
+ * Options to configure Directory - List Files and Directories Segment operations.
+ *
+ * See:
+ * - {@link ShareDirectoryClient.iterateFilesAndDirectoriesSegments}
+ * - {@link ShareDirectoryClient.listFilesAndDirectoriesItems}
+ * - {@link ShareDirectoryClient.listFilesAndDirectoriesSegment}
+ *
+ * @interface DirectoryListFilesAndDirectoriesSegmentOptions
+ */
+interface DirectoryListFilesAndDirectoriesSegmentOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof DirectoryListFilesAndDirectoriesSegmentOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * Filters the results to return only entries whose
+ * name begins with the specified prefix.
+ *
+ * @type {string}
+ * @memberof DirectoryListFilesAndDirectoriesSegmentOptions
+ */
+ prefix?: string;
+
+ /**
+ * Specifies the maximum number of entries to
+ * return. If the request does not specify maxResults, or specifies a value
+ * greater than 5,000, the server will return up to 5,000 items.
+ *
+ * @type {number}
+ * @memberof DirectoryListFilesAndDirectoriesSegmentOptions
+ */
+ maxResults?: number;
+}
+
+/**
+ * Options to configure {@link ShareDirectoryClient.listFilesAndDirectories} operation.
+ *
+ * @export
+ * @interface DirectoryListFilesAndDirectoriesOptions
+ */
+export interface DirectoryListFilesAndDirectoriesOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof DirectoryListFilesAndDirectoriesOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * Filters the results to return only entries whose
+ * name begins with the specified prefix.
+ *
+ * @type {string}
+ * @memberof DirectoryListFilesAndDirectoriesOptions
+ */
+ prefix?: string;
+}
+
+/**
+ * Options to configure the {@link ShareDirectoryClient.delete} operation.
+ *
+ * @export
+ * @interface DirectoryDeleteOptions
+ */
+export interface DirectoryDeleteOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof DirectoryDeleteOptions
+ */
+ abortSignal?: AbortSignalLike;
+}
+
+/**
+ * Options to configure the {@link ShareDirectoryClient.exists} operation.
+ *
+ * @export
+ * @interface DirectoryExistsOptions
+ */
+export interface DirectoryExistsOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof DirectoryExistsOptions
+ */
+ abortSignal?: AbortSignalLike;
+}
+
+/**
+ * Options to configure the {@link ShareDirectoryClient.getProperties} operation.
+ *
+ * @export
+ * @interface DirectoryGetPropertiesOptions
+ */
+export interface DirectoryGetPropertiesOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof DirectoryGetPropertiesOptions
+ */
+ abortSignal?: AbortSignalLike;
+}
+
+/**
+ * Options to configure the {@link ShareDirectoryClient.setMetadata} operation.
+ *
+ * @export
+ * @interface DirectorySetMetadataOptions
+ */
+export interface DirectorySetMetadataOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof DirectorySetMetadataOptions
+ */
+ abortSignal?: AbortSignalLike;
+}
+
+/**
+ * Options to configure Directory - List Handles Segment operations.
+ *
+ * See:
+ * - {@link ShareDirectoryClient.listHandlesSegment}
+ * - {@link ShareDirectoryClient.iterateHandleSegments}
+ * - {@link ShareDirectoryClient.listHandleItems}
+ *
+ *
+ * @export
+ * @interface DirectoryListHandlesSegmentOptions
+ */
+export interface DirectoryListHandlesSegmentOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof DirectoryListHandlesSegmentOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * Specifies the maximum number of entries to return. If the request does not specify maxResults,
+ * or specifies a value greater than 5,000, the server will return up to 5,000 items.
+ *
+ * @type {number}
+ * @memberof DirectoryListHandlesSegmentOptions
+ */
+ maxResults?: number;
+ /**
+ * Specifies operation should apply to the directory specified in the URI, its files, its
+ * subdirectories and their files.
+ *
+ * @type {boolean}
+ * @memberof DirectoryListHandlesSegmentOptions
+ */
+ recursive?: boolean;
+}
+
+/**
+ * Options to configure the {@link ShareDirectoryClient.listHandles} operation.
+ *
+ * @export
+ * @interface DirectoryListHandlesOptions
+ */
+export interface DirectoryListHandlesOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof DirectoryListHandlesOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * Specifies whether operation should apply to the directory specified in the URI, its files, its
+ * subdirectories and their files.
+ *
+ * @type {boolean}
+ * @memberof DirectoryListHandlesOptions
+ */
+ recursive?: boolean;
+}
+
+/**
+ * Options to configure Directory - Force Close Handles Segment operations.
+ *
+ * See:
+ * - {@link ShareDirectoryClient.forceCloseHandlesSegment}
+ * - {@link ShareDirectoryClient.forceCloseAllHandles}
+ *
+ * @export
+ * @interface DirectoryForceCloseHandlesSegmentOptions
+ */
+export interface DirectoryForceCloseHandlesSegmentOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof DirectoryForceCloseHandlesSegmentOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * Specifies operation should apply to the directory specified in the URI, its files, its
+ * subdirectories and their files.
+ *
+ * @type {boolean}
+ * @memberof DirectoryForceCloseHandlesSegmentOptions
+ */
+ recursive?: boolean;
+}
+
+/**
+ * Additional response header values for close handles request.
+ */
+export interface DirectoryCloseHandlesHeaders {
+ /**
+ * This header uniquely identifies the request that was made and can be used for troubleshooting
+ * the request.
+ */
+ requestId?: string;
+ /**
+ * Indicates the version of the File service used to execute the request.
+ */
+ version?: string;
+ /**
+ * A UTC date/time value generated by the service that indicates the time at which the response
+ * was initiated.
+ */
+ date?: Date;
+ /**
+ * A string describing next handle to be closed. It is returned when more handles need to be
+ * closed to complete the request.
+ */
+ marker?: string;
+}
+
+/**
+ * Response type for {@link ShareDirectoryClient.forceCloseHandle}.
+ */
+export type DirectoryForceCloseHandlesResponse = CloseHandlesInfo &
+ DirectoryCloseHandlesHeaders & {
+ /**
+ * The underlying HTTP response.
+ */
+ _response: HttpResponse & {
+ /**
+ * The parsed HTTP response headers.
+ */
+ parsedHeaders: DirectoryForceCloseHandlesHeaders;
+ };
+ };
+
+/**
+ * Options to configure {@link ShareDirectoryClient.forceCloseHandle}.
+ *
+ * @export
+ * @interface DirectoryForceCloseHandlesOptions
+ */
+export interface DirectoryForceCloseHandlesOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof DirectoryForceCloseHandlesOptions
+ */
+ abortSignal?: AbortSignalLike;
+}
+
+/**
+ * Contains response data for the {@link DirectoryClient.createIfNotExists} operation.
+ *
+ * @export
+ * @interface DirectoryCreateIfNotExistsResponse
+ */
+export interface DirectoryCreateIfNotExistsResponse extends DirectoryCreateResponse {
+ /**
+ * Indicate whether the directory is successfully created. Is false when the directory is not changed as it already exists.
+ *
+ * @type {boolean}
+ * @memberof DirectoryCreateIfNotExistsResponse
+ */
+ succeeded: boolean;
+}
+
+/**
+ * Contains response data for the {@link DirectoryClient.deleteIfExists} operation.
+ *
+ * @export
+ * @interface DirectoryDeleteIfExistsResponse
+ */
+export interface DirectoryDeleteIfExistsResponse extends DirectoryDeleteResponse {
+ /**
+ * Indicate whether the directory is successfully deleted. Is false if the directory does not exist in the first place.
+ *
+ * @type {boolean}
+ * @memberof DirectoryDeleteIfExistsResponse
+ */
+ succeeded: boolean;
+}
+
+/**
+ * A ShareDirectoryClient represents a URL to the Azure Storage directory allowing you to manipulate its files and directories.
+ *
+ * @export
+ * @class ShareDirectoryClient
+ */
+export class ShareDirectoryClient extends StorageClient {
+ /**
+ * context provided by protocol layer.
+ *
+ * @private
+ * @type {Directory}
+ * @memberof ShareDirectoryClient
+ */
+ private context: Directory;
+
+ private _shareName: string;
+ private _path: string;
+ private _name: string;
+
+ /**
+ * The share name corresponding to this directory client
+ *
+ * @type {string}
+ * @memberof ShareDirectoryClient
+ */
+ public get shareName(): string {
+ return this._shareName;
+ }
+
+ /**
+ * The full path of the directory
+ *
+ * @type {string}
+ * @memberof ShareDirectoryClient
+ */
+ public get path(): string {
+ return this._path;
+ }
+
+ /**
+ * The name of the directory
+ *
+ * @type {string}
+ * @memberof ShareDirectoryClient
+ */
+ public get name(): string {
+ return this._name;
+ }
+
+ /**
+ * Creates an instance of DirectoryClient.
+ *
+ * @param {string} url A URL string pointing to Azure Storage file directory, such as
+ * "https://myaccount.file.core.windows.net/myshare/mydirectory". You can
+ * append a SAS if using AnonymousCredential, such as
+ * "https://myaccount.file.core.windows.net/myshare/mydirectory?sasString".
+ * This method accepts an encoded URL or non-encoded URL pointing to a directory.
+ * Encoded URL string will NOT be escaped twice, only special characters in URL path will be escaped.
+ * However, if a directory name includes %, directory name must be encoded in the URL.
+ * Such as a directory named "mydir%", the URL should be "https://myaccount.file.core.windows.net/myshare/mydir%25".
+ * @param {Credential} [credential] Such as AnonymousCredential or StorageSharedKeyCredential.
+ * If not specified, AnonymousCredential is used.
+ * @param {StoragePipelineOptions} [options] Optional. Options to configure the HTTP pipeline.
+ * @memberof ShareDirectoryClient
+ */
+ constructor(url: string, credential?: Credential, options?: StoragePipelineOptions);
+ /**
+ * Creates an instance of DirectoryClient.
+ *
+ * @param {string} url A URL string pointing to Azure Storage file directory, such as
+ * "https://myaccount.file.core.windows.net/myshare/mydirectory". You can
+ * append a SAS if using AnonymousCredential, such as
+ * "https://myaccount.file.core.windows.net/myshare/mydirectory?sasString".
+ * This method accepts an encoded URL or non-encoded URL pointing to a directory.
+ * Encoded URL string will NOT be escaped twice, only special characters in URL path will be escaped.
+ * However, if a directory name includes %, directory name must be encoded in the URL.
+ * Such as a directory named "mydir%", the URL should be "https://myaccount.file.core.windows.net/myshare/mydir%25".
+ * @param {Pipeline} pipeline Call newPipeline() to create a default
+ * pipeline, or provide a customized pipeline.
+ * @memberof ShareDirectoryClient
+ */
+ constructor(url: string, pipeline: Pipeline);
+ constructor(
+ url: string,
+ credentialOrPipeline?: Credential | Pipeline,
+ options: StoragePipelineOptions = {}
+ ) {
+ let pipeline: Pipeline;
+ if (credentialOrPipeline instanceof Pipeline) {
+ pipeline = credentialOrPipeline;
+ } else if (credentialOrPipeline instanceof Credential) {
+ pipeline = newPipeline(credentialOrPipeline, options);
+ } else {
+ // The second parameter is undefined. Use anonymous credential.
+ pipeline = newPipeline(new AnonymousCredential(), options);
+ }
+
+ super(url, pipeline);
+ ({
+ baseName: this._name,
+ shareName: this._shareName,
+ path: this._path
+ } = getShareNameAndPathFromUrl(this.url));
+ this.context = new Directory(this.storageClientContext);
+ }
+
+ /**
+ * Creates a new directory under the specified share or parent directory.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-directory
+ *
+ * @param {DirectoryCreateOptions} [options] Options to Directory Create operation.
+ * @returns {Promise} Response data for the Directory operation.
+ * @memberof ShareDirectoryClient
+ */
+ public async create(options: DirectoryCreateOptions = {}): Promise {
+ const { span, spanOptions } = createSpan("ShareDirectoryClient-create", options.tracingOptions);
+ try {
+ if (!options.fileAttributes) {
+ options = validateAndSetDefaultsForFileAndDirectoryCreateCommonOptions(options);
+ // By default set it as a directory.
+ const attributes: FileSystemAttributes = new FileSystemAttributes();
+ attributes.directory = true;
+ options.fileAttributes = attributes;
+ }
+
+ return await this.context.create(
+ fileAttributesToString(options.fileAttributes!),
+ fileCreationTimeToString(options.creationTime!),
+ fileLastWriteTimeToString(options.lastWriteTime!),
+ {
+ abortSignal: options.abortSignal,
+ metadata: options.metadata,
+ filePermission: options.filePermission,
+ filePermissionKey: options.filePermissionKey,
+ spanOptions
+ }
+ );
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Creates a new directory under the specified share or parent directory if it does not already exists.
+ * If the directory already exists, it is not modified.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-directory
+ *
+ * @param {DirectoryCreateOptions} [options]
+ * @returns {Promise}
+ * @memberof ShareDirectoryClient
+ */
+ public async createIfNotExists(
+ options: DirectoryCreateOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareDirectoryClient-createIfNotExists",
+ options.tracingOptions
+ );
+ try {
+ const res = await this.create({
+ ...options,
+ tracingOptions: { ...options!.tracingOptions, spanOptions }
+ });
+ return {
+ succeeded: true,
+ ...res
+ };
+ } catch (e) {
+ if (e.details?.errorCode === "ResourceAlreadyExists") {
+ span.setStatus({
+ code: CanonicalCode.ALREADY_EXISTS,
+ message: "Expected exception when creating a directory only if it does not already exist."
+ });
+ return {
+ succeeded: false,
+ ...e.response?.parsedHeaders,
+ _response: e.response
+ };
+ }
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Sets properties on the directory.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-directory-properties
+ *
+ * @param {properties} [DirectoryProperties] Directory properties. If no values are provided,
+ * existing values will be preserved.
+ * @returns {Promise}
+ * @memberof ShareDirectoryClient
+ */
+ public async setProperties(
+ properties: DirectoryProperties = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareDirectoryClient-setProperties",
+ properties.tracingOptions
+ );
+ try {
+ properties = validateAndSetDefaultsForFileAndDirectorySetPropertiesCommonOptions(properties);
+
+ return await this.context.setProperties(
+ fileAttributesToString(properties.fileAttributes!),
+ fileCreationTimeToString(properties.creationTime!),
+ fileLastWriteTimeToString(properties.lastWriteTime!),
+ {
+ abortSignal: properties.abortSignal,
+ filePermission: properties.filePermission,
+ filePermissionKey: properties.filePermissionKey,
+ spanOptions
+ }
+ );
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Creates a ShareDirectoryClient object for a sub directory.
+ *
+ * @param subDirectoryName A subdirectory name
+ * @returns {ShareDirectoryClient} The ShareDirectoryClient object for the given subdirectory name.
+ * @memberof ShareDirectoryClient
+ *
+ * Example usage:
+ *
+ * ```js
+ * const directoryClient = shareClient.getDirectoryClient("");
+ * await directoryClient.create();
+ * console.log("Created directory successfully");
+ * ```
+ */
+ public getDirectoryClient(subDirectoryName: string): ShareDirectoryClient {
+ return new ShareDirectoryClient(
+ appendToURLPath(this.url, encodeURIComponent(subDirectoryName)),
+ this.pipeline
+ );
+ }
+
+ /**
+ * Creates a new subdirectory under this directory.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-directory
+ *
+ * @param {string} directoryName
+ * @param {DirectoryCreateOptions} [options] Options to Directory Create operation.
+ * @returns {Promise<{ directoryClient: ShareDirectoryClient; directoryCreateResponse: DirectoryCreateResponse; }>} Directory create response data and the corresponding DirectoryClient instance.
+ * @memberof ShareDirectoryClient
+ */
+ public async createSubdirectory(
+ directoryName: string,
+ options: DirectoryCreateOptions = {}
+ ): Promise<{
+ directoryClient: ShareDirectoryClient;
+ directoryCreateResponse: DirectoryCreateResponse;
+ }> {
+ const { span, spanOptions } = createSpan(
+ "ShareDirectoryClient-createSubdirectory",
+ options.tracingOptions
+ );
+ try {
+ const directoryClient = this.getDirectoryClient(directoryName);
+ const directoryCreateResponse = await directoryClient.create({
+ ...options,
+ tracingOptions: { ...options!.tracingOptions, spanOptions }
+ });
+ return {
+ directoryClient,
+ directoryCreateResponse
+ };
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Removes the specified empty sub directory under this directory.
+ * Note that the directory must be empty before it can be deleted.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-directory
+ *
+ * @param {string} directoryName
+ * @param {DirectoryDeleteOptions} [options] Options to Directory Delete operation.
+ * @returns {DirectoryDeleteResponse} Directory deletion response data.
+ * @memberof ShareDirectoryClient
+ */
+ public async deleteSubdirectory(
+ directoryName: string,
+ options: DirectoryDeleteOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareDirectoryClient-deleteSubdirectory",
+ options.tracingOptions
+ );
+ try {
+ const directoryClient = this.getDirectoryClient(directoryName);
+ return await directoryClient.delete({
+ ...options,
+ tracingOptions: { ...options!.tracingOptions, spanOptions }
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Creates a new file or replaces a file under this directory. Note it only initializes the file with no content.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-file
+ *
+ * @param {string} fileName
+ * @param {number} size Specifies the maximum size in bytes for the file, up to 1 TB.
+ * @param {FileCreateOptions} [options] Options to File Create operation.
+ * @returns {Promise<{ fileClient: ShareFileClient, fileCreateResponse: FileCreateResponse }>} File creation response data and the corresponding file client.
+ * @memberof ShareDirectoryClient
+ */
+ public async createFile(
+ fileName: string,
+ size: number,
+ options: FileCreateOptions = {}
+ ): Promise<{ fileClient: ShareFileClient; fileCreateResponse: FileCreateResponse }> {
+ const { span, spanOptions } = createSpan(
+ "ShareDirectoryClient-createFile",
+ options.tracingOptions
+ );
+ try {
+ const fileClient = this.getFileClient(fileName);
+ const fileCreateResponse = await fileClient.create(size, {
+ ...options,
+ tracingOptions: { ...options!.tracingOptions, spanOptions }
+ });
+ return {
+ fileClient,
+ fileCreateResponse
+ };
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Removes the specified file under this directory from the storage account.
+ * When a file is successfully deleted, it is immediately removed from the storage
+ * account's index and is no longer accessible to clients. The file's data is later
+ * removed from the service during garbage collection.
+ *
+ * Delete File will fail with status code 409 (Conflict) and error code SharingViolation
+ * if the file is open on an SMB client.
+ *
+ * Delete File is not supported on a share snapshot, which is a read-only copy of
+ * a share. An attempt to perform this operation on a share snapshot will fail with 400 (InvalidQueryParameterValue)
+ *
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-file2
+ *
+ * @param {string} fileName Name of the file to delete
+ * @param {FileDeleteOptions} [options] Options to File Delete operation.
+ * @returns {Promise} File deletion response data.
+ * @memberof ShareDirectoryClient
+ */
+ public async deleteFile(
+ fileName: string,
+ options: FileDeleteOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareDirectoryClient-deleteFile",
+ options.tracingOptions
+ );
+ try {
+ const fileClient = this.getFileClient(fileName);
+ return await fileClient.delete({
+ ...options,
+ tracingOptions: { ...options!.tracingOptions, spanOptions }
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Creates a {@link ShareFileClient} object.
+ *
+ * @param {string} fileName A file name.
+ * @returns {ShareFileClient} A new ShareFileClient object for the given file name.
+ * @memberof ShareFileClient
+ *
+ * Example usage:
+ *
+ * ```js
+ * const content = "Hello world!"
+ *
+ * const fileClient = directoryClient.getFileClient("");
+ *
+ * await fileClient.create(content.length);
+ * console.log("Created file successfully!");
+ *
+ * await fileClient.uploadRange(content, 0, content.length);
+ * console.log("Updated file successfully!")
+ * ```
+ */
+ public getFileClient(fileName: string): ShareFileClient {
+ return new ShareFileClient(
+ appendToURLPath(this.url, encodeURIComponent(fileName)),
+ this.pipeline
+ );
+ }
+
+ /**
+ * Returns true if the specified directory exists; false otherwise.
+ *
+ * NOTE: use this function with care since an existing directory might be deleted by other clients or
+ * applications. Vice versa new directories might be added by other clients or applications after this
+ * function completes.
+ *
+ * @param {DirectoryExistsOptions} [options] options to Exists operation.
+ * @returns {Promise}
+ * @memberof ShareDirectoryClient
+ */
+ public async exists(options: DirectoryExistsOptions = {}): Promise {
+ const { span, spanOptions } = createSpan("ShareDirectoryClient-exists", options.tracingOptions);
+ try {
+ await this.getProperties({
+ abortSignal: options.abortSignal,
+ tracingOptions: {
+ ...options.tracingOptions,
+ spanOptions
+ }
+ });
+ return true;
+ } catch (e) {
+ if (e.statusCode === 404) {
+ span.setStatus({
+ code: CanonicalCode.NOT_FOUND,
+ message: "Expected exception when checking directory existence"
+ });
+ return false;
+ }
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Returns all system properties for the specified directory, and can also be used to check the
+ * existence of a directory. The data returned does not include the files in the directory or any
+ * subdirectories.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-directory-properties
+ *
+ * @param {DirectoryGetPropertiesOptions} [options] Options to Directory Get Properties operation.
+ * @returns {Promise} Response data for the Directory Get Properties operation.
+ * @memberof ShareDirectoryClient
+ */
+ public async getProperties(
+ options: DirectoryGetPropertiesOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareDirectoryClient-getProperties",
+ options.tracingOptions
+ );
+ try {
+ return await this.context.getProperties({
+ abortSignal: options.abortSignal,
+ spanOptions
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Removes the specified empty directory. Note that the directory must be empty before it can be
+ * deleted.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-directory
+ *
+ * @param {DirectoryDeleteOptions} [options] Options to Directory Delete operation.
+ * @returns {Promise} Response data for the Directory Delete operation.
+ * @memberof ShareDirectoryClient
+ */
+ public async delete(options: DirectoryDeleteOptions = {}): Promise {
+ const { span, spanOptions } = createSpan("ShareDirectoryClient-delete", options.tracingOptions);
+ try {
+ return await this.context.deleteMethod({
+ abortSignal: options.abortSignal,
+ spanOptions
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Removes the specified empty directory if it exists. Note that the directory must be empty before it can be
+ * deleted.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-directory
+ *
+ * @param {DirectoryDeleteOptions} [options]
+ * @returns {Promise}
+ * @memberof ShareDirectoryClient
+ */
+ public async deleteIfExists(
+ options: DirectoryDeleteOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareDirectoryClient-deleteIfExists",
+ options.tracingOptions
+ );
+ try {
+ const res = await this.delete({
+ ...options,
+ tracingOptions: { ...options!.tracingOptions, spanOptions }
+ });
+ return {
+ succeeded: true,
+ ...res
+ };
+ } catch (e) {
+ if (e.details?.errorCode === "ResourceNotFound") {
+ span.setStatus({
+ code: CanonicalCode.NOT_FOUND,
+ message: "Expected exception when deleting a directory only if it exists."
+ });
+ return {
+ succeeded: false,
+ ...e.response?.parsedHeaders,
+ _response: e.response
+ };
+ }
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Updates user defined metadata for the specified directory.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-directory-metadata
+ *
+ * @param {Metadata} [metadata] If no metadata provided, all existing directory metadata will be removed
+ * @param {DirectorySetMetadataOptions} [options] Options to Directory Set Metadata operation.
+ * @returns {Promise} Response data for the Directory Set Metadata operation.
+ * @memberof ShareDirectoryClient
+ */
+ public async setMetadata(
+ metadata?: Metadata,
+ options: DirectorySetMetadataOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareDirectoryClient-setMetadata",
+ options.tracingOptions
+ );
+ try {
+ return await this.context.setMetadata({
+ abortSignal: options.abortSignal,
+ metadata,
+ spanOptions
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Returns an AsyncIterableIterator for {@link DirectoryListFilesAndDirectoriesSegmentResponse} objects
+ *
+ * @private
+ * @param {string} [marker] A string value that identifies the portion of
+ * the list of files and directories to be returned with the next listing operation. The
+ * operation returns the ContinuationToken value within the response body if the
+ * listing operation did not return all files and directories remaining to be listed
+ * with the current page. The ContinuationToken value can be used as the value for
+ * the marker parameter in a subsequent call to request the next page of list
+ * items. The marker value is opaque to the client.
+ * @param {DirectoryListFilesAndDirectoriesSegmentOptions} [options] Options to list files and directories operation.
+ * @returns {AsyncIterableIterator}
+ * @memberof ShareDirectoryClient
+ */
+ private async *iterateFilesAndDirectoriesSegments(
+ marker?: string,
+ options: DirectoryListFilesAndDirectoriesSegmentOptions = {}
+ ): AsyncIterableIterator {
+ if (options.prefix === "") {
+ options.prefix = undefined;
+ }
+
+ let listFilesAndDirectoriesResponse;
+ do {
+ listFilesAndDirectoriesResponse = await this.listFilesAndDirectoriesSegment(marker, options);
+ marker = listFilesAndDirectoriesResponse.continuationToken;
+ yield await listFilesAndDirectoriesResponse;
+ } while (marker);
+ }
+
+ /**
+ * Returns an AsyncIterableIterator for file and directory items
+ *
+ * @private
+ * @param {DirectoryListFilesAndDirectoriesSegmentOptions} [options] Options to list files and directories operation.
+ * @returns {AsyncIterableIterator<{ kind: "file" } & FileItem | { kind: "directory" } & DirectoryItem>}
+ * @memberof ShareDirectoryClient
+ */
+ private async *listFilesAndDirectoriesItems(
+ options: DirectoryListFilesAndDirectoriesSegmentOptions = {}
+ ): AsyncIterableIterator<
+ ({ kind: "file" } & FileItem) | ({ kind: "directory" } & DirectoryItem)
+ > {
+ if (options.prefix === "") {
+ options.prefix = undefined;
+ }
+
+ let marker: string | undefined;
+ for await (const listFilesAndDirectoriesResponse of this.iterateFilesAndDirectoriesSegments(
+ marker,
+ options
+ )) {
+ for (const file of listFilesAndDirectoriesResponse.segment.fileItems) {
+ yield { kind: "file", ...file };
+ }
+ for (const directory of listFilesAndDirectoriesResponse.segment.directoryItems) {
+ yield { kind: "directory", ...directory };
+ }
+ }
+ }
+
+ /**
+ * Returns an async iterable iterator to list all the files and directories
+ * under the specified account.
+ *
+ * .byPage() returns an async iterable iterator to list the files and directories in pages.
+ *
+ * Example using `for await` syntax:
+ *
+ * ```js
+ * let i = 1;
+ * for await (const entity of directoryClient.listFilesAndDirectories()) {
+ * if (entity.kind === "directory") {
+ * console.log(`${i++} - directory\t: ${entity.name}`);
+ * } else {
+ * console.log(`${i++} - file\t: ${entity.name}`);
+ * }
+ * }
+ * ```
+ *
+ * Example using `iter.next()`:
+ *
+ * ```js
+ * let i = 1;
+ * let iter = directoryClient.listFilesAndDirectories();
+ * let entity = await iter.next();
+ * while (!entity.done) {
+ * if (entity.value.kind === "directory") {
+ * console.log(`${i++} - directory\t: ${entity.value.name}`);
+ * } else {
+ * console.log(`${i++} - file\t: ${entity.value.name}`);
+ * }
+ * entity = await iter.next();
+ * }
+ * ```
+ *
+ * Example using `byPage()`:
+ *
+ * ```js
+ * // passing optional maxPageSize in the page settings
+ * let i = 1;
+ * for await (const response of directoryClient
+ * .listFilesAndDirectories()
+ * .byPage({ maxPageSize: 20 })) {
+ * for (const fileItem of response.segment.fileItems) {
+ * console.log(`${i++} - file\t: ${fileItem.name}`);
+ * }
+ * for (const dirItem of response.segment.directoryItems) {
+ * console.log(`${i++} - directory\t: ${dirItem.name}`);
+ * }
+ * }
+ * ```
+ *
+ * Example using paging with a marker:
+ *
+ * ```js
+ * let i = 1;
+ * let iterator = directoryClient.listFilesAndDirectories().byPage({ maxPageSize: 3 });
+ * let response = (await iterator.next()).value;
+ *
+ * // Prints 3 file and directory names
+ * for (const fileItem of response.segment.fileItems) {
+ * console.log(`${i++} - file\t: ${fileItem.name}`);
+ * }
+ *
+ * for (const dirItem of response.segment.directoryItems) {
+ * console.log(`${i++} - directory\t: ${dirItem.name}`);
+ * }
+ *
+ * // Gets next marker
+ * let dirMarker = response.continuationToken;
+ *
+ * // Passing next marker as continuationToken
+ * iterator = directoryClient
+ * .listFilesAndDirectories()
+ * .byPage({ continuationToken: dirMarker, maxPageSize: 4 });
+ * response = (await iterator.next()).value;
+ *
+ * // Prints 10 file and directory names
+ * for (const fileItem of response.segment.fileItems) {
+ * console.log(`${i++} - file\t: ${fileItem.name}`);
+ * }
+ *
+ * for (const dirItem of response.segment.directoryItems) {
+ * console.log(`${i++} - directory\t: ${dirItem.name}`);
+ * }
+ * ```
+ *
+ * @param {DirectoryListFilesAndDirectoriesOptions} [options] Options to list files and directories operation.
+ * @memberof ShareDirectoryClient
+ * @returns {PagedAsyncIterableIterator<{ kind: "file" } & FileItem | { kind: "directory" } , DirectoryListFilesAndDirectoriesSegmentResponse>}
+ * An asyncIterableIterator that supports paging.
+ */
+ public listFilesAndDirectories(
+ options: DirectoryListFilesAndDirectoriesOptions = {}
+ ): PagedAsyncIterableIterator<
+ ({ kind: "file" } & FileItem) | ({ kind: "directory" } & DirectoryItem),
+ DirectoryListFilesAndDirectoriesSegmentResponse
+ > {
+ if (options.prefix === "") {
+ options.prefix = undefined;
+ }
+
+ // AsyncIterableIterator to iterate over files and directories
+ const iter = this.listFilesAndDirectoriesItems(options);
+ return {
+ /**
+ * @member {Promise} [next] The next method, part of the iteration protocol
+ */
+ async next() {
+ return iter.next();
+ },
+ /**
+ * @member {Symbol} [asyncIterator] The connection to the async iterator, part of the iteration protocol
+ */
+ [Symbol.asyncIterator]() {
+ return this;
+ },
+ /**
+ * @member {Function} [byPage] Return an AsyncIterableIterator that works a page at a time
+ */
+ byPage: (settings: PageSettings = {}) => {
+ return this.iterateFilesAndDirectoriesSegments(settings.continuationToken, {
+ maxResults: settings.maxPageSize,
+ ...options
+ });
+ }
+ };
+ }
+
+ /**
+ * Returns a list of files or directories under the specified share or directory. It lists the
+ * contents only for a single level of the directory hierarchy.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/list-directories-and-files
+ *
+ * @param {string} [marker] A string value that identifies the portion of the list to be returned with the next list operation.
+ * @param {DirectoryListFilesAndDirectoriesSegmentOptions} [options] Options to Directory List Files and Directories Segment operation.
+ * @returns {Promise} Response data for the Directory List Files and Directories operation.
+ * @memberof ShareDirectoryClient
+ */
+ private async listFilesAndDirectoriesSegment(
+ marker?: string,
+ options: DirectoryListFilesAndDirectoriesSegmentOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareDirectoryClient-listFilesAndDirectoriesSegment",
+ options.tracingOptions
+ );
+
+ if (options.prefix === "") {
+ options.prefix = undefined;
+ }
+
+ try {
+ return await this.context.listFilesAndDirectoriesSegment({
+ marker,
+ ...options,
+ spanOptions
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Returns an AsyncIterableIterator for {@link DirectoryListHandlesResponse}
+ *
+ * @private
+ * @param {string} [marker] A string value that identifies the portion of the list to be
+ * returned with the next list handles operation. The operation returns a
+ * marker value within the response body if the list returned was not complete.
+ * The marker value may then be used in a subsequent call to request the next
+ * set of list items.
+ * @param {DirectoryListHandlesSegmentOptions} [options] Options to list handles operation.
+ * @returns {AsyncIterableIterator}
+ * @memberof ShareDirectoryClient
+ */
+ private async *iterateHandleSegments(
+ marker?: string,
+ options: DirectoryListHandlesSegmentOptions = {}
+ ): AsyncIterableIterator {
+ let listHandlesResponse;
+ if (!!marker || marker === undefined) {
+ do {
+ listHandlesResponse = await this.listHandlesSegment(marker, options);
+ marker = listHandlesResponse.continuationToken;
+ yield await listHandlesResponse;
+ } while (marker);
+ }
+ }
+
+ /**
+ * Returns an AsyncIterableIterator for handles
+ *
+ * @private
+ * @param {DirectoryListHandlesSegmentOptions} [options] Options to list handles operation.
+ * @returns {AsyncIterableIterator}
+ * @memberof ShareDirectoryClient
+ */
+ private async *listHandleItems(
+ options: DirectoryListHandlesSegmentOptions = {}
+ ): AsyncIterableIterator {
+ let marker: string | undefined;
+ for await (const listHandlesResponse of this.iterateHandleSegments(marker, options)) {
+ if (listHandlesResponse.handleList) {
+ for (const handle of listHandlesResponse.handleList) {
+ yield handle;
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns an async iterable iterator to list all the handles.
+ * under the specified account.
+ *
+ * .byPage() returns an async iterable iterator to list the handles in pages.
+ *
+ * Example using `for await` syntax:
+ *
+ * ```js
+ * let i = 1;
+ * let iter = dirClient.listHandles();
+ * for await (const handle of iter) {
+ * console.log(`Handle ${i++}: ${handle.path}, opened time ${handle.openTime}, clientIp ${handle.clientIp}`);
+ * }
+ * ```
+ *
+ * Example using `iter.next()`:
+ *
+ * ```js
+ * let i = 1;
+ * let iter = dirClient.listHandles();
+ * let handleItem = await iter.next();
+ * while (!handleItem.done) {
+ * console.log(`Handle ${i++}: ${handleItem.value.path}, opened time ${handleItem.value.openTime}, clientIp ${handleItem.value.clientIp}`);
+ * handleItem = await iter.next();
+ * }
+ * ```
+ *
+ * Example using `byPage()`:
+ *
+ * ```js
+ * // passing optional maxPageSize in the page settings
+ * let i = 1;
+ * for await (const response of dirClient.listHandles({ recursive: true }).byPage({ maxPageSize: 20 })) {
+ * if (response.handleList) {
+ * for (const handle of response.handleList) {
+ * console.log(`Handle ${i++}: ${handle.path}, opened time ${handle.openTime}, clientIp ${handle.clientIp}`);
+ * }
+ * }
+ * }
+ * ```
+ *
+ * Example using paging with a marker:
+ *
+ * ```js
+ * let i = 1;
+ * let iterator = dirClient.listHandles().byPage({ maxPageSize: 2 });
+ * let response = await iterator.next();
+ *
+ * // Prints 2 handles
+ * if (response.value.handleList) {
+ * for (const handle of response.value.handleList) {
+ * console.log(`Handle ${i++}: ${handle.path}, opened time ${handle.openTime}, clientIp ${handle.clientIp}`);
+ * }
+ * }
+ *
+ * // Gets next marker
+ * let marker = response.value.continuationToken;
+ *
+ * // Passing next marker as continuationToken
+ * console.log(` continuation`);
+ * iterator = dirClient.listHandles().byPage({ continuationToken: marker, maxPageSize: 10 });
+ * response = await iterator.next();
+ *
+ * // Prints 2 more handles assuming you have more than four directory/files opened
+ * if (!response.done && response.value.handleList) {
+ * for (const handle of response.value.handleList) {
+ * console.log(`Handle ${i++}: ${handle.path}, opened time ${handle.openTime}, clientIp ${handle.clientIp}`);
+ * }
+ * }
+ * ```
+ *
+ * @param {DirectoryListHandlesOptions} [options] Options to list handles operation.
+ * @memberof ShareDirectoryClient
+ * @returns {PagedAsyncIterableIterator}
+ * An asyncIterableIterator that supports paging.
+ */
+ public listHandles(
+ options: DirectoryListHandlesOptions = {}
+ ): PagedAsyncIterableIterator {
+ // an AsyncIterableIterator to iterate over handles
+ const iter = this.listHandleItems(options);
+ return {
+ /**
+ * @member {Promise} [next] The next method, part of the iteration protocol
+ */
+ async next() {
+ return iter.next();
+ },
+ /**
+ * @member {Symbol} [asyncIterator] The connection to the async iterator, part of the iteration protocol
+ */
+ [Symbol.asyncIterator]() {
+ return this;
+ },
+ /**
+ * @member {Function} [byPage] Return an AsyncIterableIterator that works a page at a time
+ */
+ byPage: (settings: PageSettings = {}) => {
+ return this.iterateHandleSegments(settings.continuationToken, {
+ maxResults: settings.maxPageSize,
+ ...options
+ });
+ }
+ };
+ }
+
+ /**
+ * Lists handles for a directory.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/list-handles
+ *
+ * @param {string} [marker] Optional. A string value that identifies the portion of the list to be
+ * returned with the next list handles operation. The operation returns a
+ * marker value within the response body if the list returned was not complete.
+ * The marker value may then be used in a subsequent call to request the next
+ * set of list items.
+ * @param {DirectoryListHandlesSegmentOptions} [options={}]
+ * @returns {Promise}
+ * @memberof ShareDirectoryClient
+ */
+ private async listHandlesSegment(
+ marker?: string,
+ options: DirectoryListHandlesSegmentOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareDirectoryClient-listHandlesSegment",
+ options.tracingOptions
+ );
+ try {
+ marker = marker === "" ? undefined : marker;
+ const response = await this.context.listHandles({
+ marker,
+ ...options,
+ spanOptions
+ });
+
+ // TODO: Protocol layer issue that when handle list is in returned XML
+ // response.handleList is an empty string
+ if ((response.handleList as any) === "") {
+ response.handleList = undefined;
+ }
+ return response;
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Force close all handles for a directory.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/force-close-handles
+ *
+ * @param {string} [marker] Optional. A string value that identifies the position of handles that will
+ * be closed with the next force close handles operation.
+ * The operation returns a marker value within the response
+ * body if there are more handles to close. The marker value
+ * may then be used in a subsequent call to close the next set of handles.
+ * @param {DirectoryForceCloseHandlesSegmentOptions} [options={}]
+ * @returns {Promise}
+ * @memberof ShareDirectoryClient
+ */
+ private async forceCloseHandlesSegment(
+ marker?: string,
+ options: DirectoryForceCloseHandlesSegmentOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareDirectoryClient-forceCloseHandlesSegment",
+ options.tracingOptions
+ );
+ try {
+ marker = marker === "" ? undefined : marker;
+ const rawResponse = await this.context.forceCloseHandles("*", {
+ marker,
+ ...options,
+ spanOptions
+ });
+ const response = rawResponse as DirectoryForceCloseHandlesResponse;
+ response.closedHandlesCount = rawResponse.numberOfHandlesClosed || 0;
+ response.closeFailureCount = rawResponse.numberOfHandlesFailedToClose || 0;
+ return response;
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Force close all handles for a directory.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/force-close-handles
+ *
+ * @param {DirectoryForceCloseHandlesSegmentOptions} [options={}]
+ * @returns {Promise}
+ * @memberof ShareDirectoryClient
+ */
+ public async forceCloseAllHandles(
+ options: DirectoryForceCloseHandlesSegmentOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareDirectoryClient-forceCloseAllHandles",
+ options.tracingOptions
+ );
+ try {
+ let handlesClosed = 0;
+ let numberOfHandlesFailedToClose = 0;
+ let marker: string | undefined = "";
+
+ do {
+ const response: DirectoryForceCloseHandlesResponse = await this.forceCloseHandlesSegment(
+ marker,
+ { ...options, tracingOptions: { ...options!.tracingOptions, spanOptions } }
+ );
+ marker = response.marker;
+ response.closedHandlesCount && (handlesClosed += response.closedHandlesCount);
+ response.closeFailureCount && (numberOfHandlesFailedToClose += response.closeFailureCount);
+ } while (marker);
+
+ return { closedHandlesCount: handlesClosed, closeFailureCount: numberOfHandlesFailedToClose };
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Force close a specific handle for a directory.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/force-close-handles
+ *
+ * @param {Aborter} aborter Create a new Aborter instance with Aborter.none or Aborter.timeout(),
+ * goto documents of Aborter for more examples about request cancellation
+ * @param {string} handleId Specific handle ID, cannot be asterisk "*".
+ * Use forceCloseHandlesSegment() to close all handles.
+ * @param {DirectoryForceCloseHandlesOptions} [options={}]
+ * @returns {Promise}
+ * @memberof ShareDirectoryClient
+ */
+ public async forceCloseHandle(
+ handleId: string,
+ options: DirectoryForceCloseHandlesOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareDirectoryClient-forceCloseHandle",
+ options.tracingOptions
+ );
+ try {
+ if (handleId === "*") {
+ throw new RangeError(
+ `Parameter handleID should be a specified handle ID. Use forceCloseHandlesSegment() to close all handles.`
+ );
+ }
+
+ const rawResponse = await this.context.forceCloseHandles(handleId, {
+ abortSignal: options.abortSignal,
+ spanOptions
+ });
+ const response = rawResponse as DirectoryForceCloseHandlesResponse;
+ response.closedHandlesCount = rawResponse.numberOfHandlesClosed || 0;
+ response.closeFailureCount = rawResponse.numberOfHandlesFailedToClose || 0;
+ return response;
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+}
+
+/**
+ * Options to configure the {@link ShareFileClient.create} operation.
+ *
+ * @export
+ * @interface FileCreateOptions
+ */
+export interface FileCreateOptions extends FileAndDirectoryCreateCommonOptions, CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof FileCreateOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * File HTTP headers like Content-Type.
+ *
+ * @type {FileHttpHeaders}
+ * @memberof FileCreateOptions
+ */
+ fileHttpHeaders?: FileHttpHeaders;
+
+ /**
+ * A collection of key-value string pair to associate with the file storage object.
+ *
+ * @type {Metadata}
+ * @memberof FileCreateOptions
+ */
+ metadata?: Metadata;
+ /**
+ * Lease access conditions.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof FileCreateOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+export interface FileProperties extends FileAndDirectorySetPropertiesCommonOptions, CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof FileProperties
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * File HTTP headers like Content-Type.
+ *
+ * @type {FileHttpHeaders}
+ * @memberof FileProperties
+ */
+ fileHttpHeaders?: FileHttpHeaders;
+ /**
+ * Lease access conditions.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof FileProperties
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+export interface SetPropertiesResponse extends FileSetHTTPHeadersResponse {}
+
+/**
+ * Options to configure the {@link ShareFileClient.delete} operation.
+ *
+ * @export
+ * @interface FileDeleteOptions
+ */
+export interface FileDeleteOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof FileDeleteOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * Lease access conditions.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof FileDeleteOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+/**
+ * Options to configure File - Download operations.
+ *
+ * See:
+ * - {@link ShareFileClient.download}
+ * - {@link ShareFileClient.downloadToFile}
+ *
+ * @export
+ * @interface FileDownloadOptions
+ */
+export interface FileDownloadOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof FileDownloadOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * Optional. ONLY AVAILABLE IN NODE.JS.
+ *
+ * How many retries will perform when original body download stream unexpected ends.
+ * Above kind of ends will not trigger retry policy defined in a pipeline,
+ * because they doesn't emit network errors.
+ *
+ * With this option, every additional retry means an additional ShareFileClient.download() request will be made
+ * from the broken point, until the requested range has been successfully downloaded or maxRetryRequests is reached.
+ *
+ * Default value is 5, please set a larger value when loading large files in poor network.
+ *
+ * @type {number}
+ * @memberof FileDownloadOptions
+ */
+ maxRetryRequests?: number;
+
+ /**
+ * When this header is set to true and
+ * specified together with the Range header, the service returns the MD5 hash
+ * for the range, as long as the range is less than or equal to 4 MB in size.
+ *
+ * @type {boolean}
+ * @memberof FileDownloadOptions
+ */
+ rangeGetContentMD5?: boolean;
+
+ /**
+ * Download progress updating event handler.
+ *
+ * @memberof FileDownloadOptions
+ */
+ onProgress?: (progress: TransferProgressEvent) => void;
+ /**
+ * Lease access conditions.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof FileDownloadOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+/**
+ * Options to configure the {@link ShareFileClient.uploadRange} operation.
+ *
+ * @export
+ * @interface FileUploadRangeOptions
+ */
+export interface FileUploadRangeOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof FileUploadRangeOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * An MD5 hash of the content. This hash is
+ * used to verify the integrity of the data during transport. When the
+ * Content-MD5 header is specified, the File service compares the hash of the
+ * content that has arrived with the header value that was sent. If the two
+ * hashes do not match, the operation will fail with error code 400 (Bad
+ * Request).
+ *
+ * @type {Uint8Array}
+ * @memberof FileUploadRangeOptions
+ */
+ contentMD5?: Uint8Array;
+
+ /**
+ * Progress updating event handler.
+ *
+ * @memberof FileUploadRangeOptions
+ */
+ onProgress?: (progress: TransferProgressEvent) => void;
+ /**
+ * Lease access conditions.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof FileUploadRangeOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+/**
+ * Options to configure the {@link ShareFileClient.uploadRangeFromURL} operation.
+ *
+ * @export
+ * @interface FileUploadRangeFromURLOptions
+ */
+export interface FileUploadRangeFromURLOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof FileUploadRangeFromURLOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * The timeout parameter is expressed in seconds. For more information, see Setting
+ * Timeouts for File Service Operations.
+ */
+ timeoutInSeconds?: number;
+ /**
+ * Specify the crc64 calculated for the range of bytes that must be read from the copy source.
+ */
+ sourceContentCrc64?: Uint8Array;
+ /**
+ * Additional parameters for the operation
+ */
+ sourceConditions?: SourceModifiedAccessConditions;
+ /**
+ * Lease access conditions.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof FileUploadRangeFromURLOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+/**
+ * The option is defined as parity to REST definition.
+ * While it's not ready to be used now, considering Crc64 of source content is
+ * not accessible.
+ */
+// export interface IFileUploadRangeFromURLOptions extends CommonOptions {
+// /**
+// * Crc64 of the source content.
+// *
+// * @type {Uint8Array}
+// * @memberof IFileUploadRangeFromURLOptions
+// */
+// sourceContentCrc64?: Uint8Array;
+
+// /**
+// * Source modified access condition.
+// *
+// * @type {SourceModifiedAccessConditions}
+// * @memberof IFileUploadRangeFromURLOptions
+// */
+// sourceModifiedAccessConditions?: SourceModifiedAccessConditions;
+// }
+
+/**
+ * Options to configure the {@link ShareFileClient.getRangeList} operation.
+ *
+ * @export
+ * @interface FileGetRangeListOptions
+ */
+export interface FileGetRangeListOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof FileGetRangeListOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * Optional. Specifies the range of bytes over which to list ranges, inclusively.
+ *
+ * @type {Range}
+ * @memberof FileGetRangeListOptions
+ */
+ range?: Range;
+ /**
+ * Lease access conditions.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof FileGetRangeListOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+/**
+ * Options to configure the {@link ShareFileClient.exists} operation.
+ *
+ * @export
+ * @interface FileExistsOptions
+ */
+export interface FileExistsOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof FileExistsOptions
+ */
+ abortSignal?: AbortSignalLike;
+}
+
+/**
+ * Options to configure the {@link ShareFileClient.getProperties} operation.
+ *
+ * @export
+ * @interface FileGetPropertiesOptions
+ */
+export interface FileGetPropertiesOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof FileGetPropertiesOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * Lease access conditions.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof FileGetPropertiesOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+/**
+ * Contains response data for the {@link ShareFileClient.getRangeList} operation.
+ */
+export type FileGetRangeListResponse = FileGetRangeListHeaders & {
+ /**
+ * Range list for an Azure file.
+ *
+ * @type {RangeModel[]}
+ */
+ rangeList: RangeModel[];
+
+ /**
+ * The underlying HTTP response.
+ */
+ _response: HttpResponse & {
+ /**
+ * The parsed HTTP response headers.
+ */
+ parsedHeaders: FileGetRangeListHeaders;
+ /**
+ * The response body as text (string format)
+ */
+ bodyAsText: string;
+ /**
+ * The response body as parsed JSON or XML
+ */
+ parsedBody: RangeModel[];
+ };
+};
+
+/**
+ * Options to configure the {@link ShareFileClient.startCopyFromURL} operation.
+ *
+ * @export
+ * @interface FileStartCopyOptions
+ */
+export interface FileStartCopyOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof FileStartCopyOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * A collection of key-value string pair to associate with the file storage object.
+ *
+ * @type {Metadata}
+ * @memberof FileStartCopyOptions
+ */
+ metadata?: Metadata;
+ /**
+ * Lease access conditions.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof FileStartCopyOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+ /**
+ * If specified the permission (security descriptor) shall be set for the directory/file. This
+ * header can be used if Permission size is <= 8KB, else x-ms-file-permission-key header shall be
+ * used. Default value: Inherit. If SDDL is specified as input, it must have owner, group and
+ * dacl. Note: Only one of the x-ms-file-permission or x-ms-file-permission-key should be
+ * specified.
+ *
+ * @type {string}
+ * @memberof FileStartCopyOptions
+ */
+ filePermission?: string;
+ /**
+ * Key of the permission to be set for the directory/file. Note: Only one of the
+ * x-ms-file-permission or x-ms-file-permission-key should be specified.
+ *
+ * @type {string}
+ * @memberof FileStartCopyOptions
+ */
+ filePermissionKey?: string;
+ /**
+ * SMB info.
+ *
+ * @type {CopyFileSmbInfo}
+ * @memberof FileStartCopyOptions
+ */
+ copyFileSmbInfo?: CopyFileSmbInfo;
+}
+
+/**
+ * Options to configure the {@link ShareFileClient.setMetadata} operation.
+ *
+ * @export
+ * @interface FileSetMetadataOptions
+ */
+export interface FileSetMetadataOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof FileSetMetadataOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * Lease access conditions.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof FileSetMetadataOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+/**
+ * Options to configure the {@link ShareFileClient.setHttpHeaders} operation.
+ *
+ * @export
+ * @interface FileSetHttpHeadersOptions
+ */
+export interface FileSetHttpHeadersOptions
+ extends FileAndDirectorySetPropertiesCommonOptions,
+ CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof FileSetHttpHeadersOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * Lease access conditions.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof FileSetHttpHeadersOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+/**
+ * Options to configure the {@link ShareFileClient.abortCopyFromURL} operation.
+ *
+ * @export
+ * @interface FileAbortCopyFromURLOptions
+ */
+export interface FileAbortCopyFromURLOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof FileAbortCopyFromURLOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * Lease access conditions.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof FileAbortCopyFromURLOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+/**
+ * Options to configure the {@link ShareFileClient.resize} operation.
+ *
+ * @export
+ * @interface FileResizeOptions
+ */
+export interface FileResizeOptions
+ extends FileAndDirectorySetPropertiesCommonOptions,
+ CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof FileResizeOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * Lease access conditions.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof FileResizeOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+/**
+ * Options to configure the {@link ShareFileClient.clearRange} operation.
+ *
+ * @export
+ * @interface FileClearRangeOptions
+ */
+export interface FileClearRangeOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof FileClearRangeOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * Lease access conditions.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof FileClearRangeOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+/**
+ * Options to configure File - List Handles Segment operations.
+ *
+ * See:
+ * - {@link ShareFileClient.listHandlesSegment}
+ * - {@link ShareFileClient.iterateHandleSegments}
+ * - {@link ShareFileClient.listHandleItems}
+ *
+ * @export
+ * @interface FileListHandlesSegmentOptions
+ */
+export interface FileListHandlesSegmentOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof FileClearRangeOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * Specifies the maximum number of entries to return. If the request does not specify maxResults,
+ * or specifies a value greater than 5,000, the server will return up to 5,000 items.
+ *
+ * @type {number}
+ * @memberof FileListHandlesSegmentOptions
+ */
+ maxPageSize?: number;
+}
+
+export interface FileListHandlesOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof FileClearRangeOptions
+ */
+ abortSignal?: AbortSignalLike;
+}
+
+/**
+ * Options to configure File - Force Close Handles operations.
+ *
+ * See:
+ * - {@link ShareFileClient.forceCloseHandlesSegment}
+ * - {@link ShareFileClient.forceCloseAllHandles}
+ * - {@link ShareFileClient.forceCloseHandle}
+ *
+ * @export
+ * @interface FileForceCloseHandlesOptions
+ */
+export interface FileForceCloseHandlesOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof FileForceCloseHandlesOptions
+ */
+ abortSignal?: AbortSignalLike;
+}
+
+/**
+ * Additional response header values for close handles request.
+ */
+export interface FileCloseHandlesHeaders {
+ /**
+ * This header uniquely identifies the request that was made and can be used for troubleshooting
+ * the request.
+ */
+ requestId?: string;
+ /**
+ * Indicates the version of the File service used to execute the request.
+ */
+ version?: string;
+ /**
+ * A UTC date/time value generated by the service that indicates the time at which the response
+ * was initiated.
+ */
+ date?: Date;
+ /**
+ * A string describing next handle to be closed. It is returned when more handles need to be
+ * closed to complete the request.
+ */
+ marker?: string;
+}
+
+/**
+ * Response type for {@link ShareFileClient.forceCloseHandle}.
+ */
+export type FileForceCloseHandlesResponse = CloseHandlesInfo &
+ FileCloseHandlesHeaders & {
+ /**
+ * The underlying HTTP response.
+ */
+ _response: HttpResponse & {
+ /**
+ * The parsed HTTP response headers.
+ */
+ parsedHeaders: FileForceCloseHandlesHeaders;
+ };
+ };
+
+/**
+ * Option interface for ShareFileClient.uploadStream().
+ *
+ * @export
+ * @interface FileUploadStreamOptions
+ */
+export interface FileUploadStreamOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof FileUploadStreamOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * Azure File HTTP Headers.
+ *
+ * @type {FileHttpHeaders}
+ * @memberof FileUploadStreamOptions
+ */
+ fileHttpHeaders?: FileHttpHeaders;
+
+ /**
+ * Metadata of the Azure file.
+ *
+ * @type {Metadata}
+ * @memberof FileUploadStreamOptions
+ */
+ metadata?: Metadata;
+
+ /**
+ * Progress updater.
+ *
+ * @memberof FileUploadStreamOptions
+ */
+ onProgress?: (progress: TransferProgressEvent) => void;
+ /**
+ * Lease access conditions.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof FileUploadStreamOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+/**
+ * Option interface for File - Upload operations
+ *
+ * See:
+ * - {@link ShareFileClient.uploadFile}
+ * - {@link ShareFileClient.uploadSeekableStream}
+ *
+ * @export
+ * @interface FileParallelUploadOptions
+ */
+export interface FileParallelUploadOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof FileParallelUploadOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * RangeSize specifies the range size to use in each parallel upload,
+ * the default (and maximum size) is FILE_RANGE_MAX_SIZE_BYTES.
+ *
+ * @type {number}
+ * @memberof FileParallelUploadOptions
+ */
+ rangeSize?: number;
+
+ /**
+ * Progress updater.
+ *
+ * @memberof FileParallelUploadOptions
+ */
+ onProgress?: (progress: TransferProgressEvent) => void;
+
+ /**
+ * File HTTP Headers.
+ *
+ * @type {FileHttpHeaders}
+ * @memberof FileParallelUploadOptions
+ */
+ fileHttpHeaders?: FileHttpHeaders;
+
+ /**
+ * Metadata of an Azure file.
+ *
+ * @type {Metadata}
+ * @memberof FileParallelUploadOptions
+ */
+ metadata?: Metadata;
+
+ /**
+ * Concurrency indicates the maximum number of ranges to upload in parallel.
+ * If not provided, 5 concurrency will be used by default.
+ *
+ * @type {number}
+ * @memberof FileParallelUploadOptions
+ */
+ concurrency?: number;
+ /**
+ * Lease access conditions.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof FileParallelUploadOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+/**
+ * Option interface for the {@link ShareFileClient.downloadToBuffer} operation.
+ *
+ * @export
+ * @interface FileDownloadToBufferOptions
+ */
+export interface FileDownloadToBufferOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof FileDownloadToBufferOptions
+ */
+ abortSignal?: AbortSignalLike;
+ /**
+ * When downloading Azure files, download method will try to split large file into small ranges.
+ * Every small range will be downloaded via a separate request.
+ * This option defines size data every small request trying to download.
+ * Must be > 0, will use the default value if undefined,
+ *
+ * @type {number}
+ * @memberof FileDownloadToBufferOptions
+ */
+ rangeSize?: number;
+
+ /**
+ * Optional. ONLY AVAILABLE IN NODE.JS.
+ *
+ * How many retries will perform when original range download stream unexpected ends.
+ * Above kind of ends will not trigger retry policy defined in a pipeline,
+ * because they doesn't emit network errors.
+ *
+ * With this option, every additional retry means an additional ShareFileClient.download() request will be made
+ * from the broken point, until the requested range has been successfully downloaded or
+ * maxRetryRequestsPerRange is reached.
+ *
+ * Default value is 5, please set a larger value when in poor network.
+ *
+ * @type {number}
+ * @memberof FileDownloadToBufferOptions
+ */
+ maxRetryRequestsPerRange?: number;
+
+ /**
+ * Progress updater.
+ *
+ * @memberof FileDownloadToBufferOptions
+ */
+ onProgress?: (progress: TransferProgressEvent) => void;
+
+ /**
+ * Concurrency indicates the maximum number of ranges to download in parallel.
+ * If not provided, 5 concurrency will be used by default.
+ *
+ * @type {number}
+ * @memberof FileDownloadToBufferOptions
+ */
+ concurrency?: number;
+ /**
+ * Lease access conditions.
+ *
+ * @type {LeaseAccessConditions}
+ * @memberof FileDownloadToBufferOptions
+ */
+ leaseAccessConditions?: LeaseAccessConditions;
+}
+
+/**
+ * Contains response data for the {@link ShareFileClient.deleteIfExists} operation.
+ *
+ * @export
+ * @interface FileDeleteIfExistsResponse
+ */
+export interface FileDeleteIfExistsResponse extends FileDeleteResponse {
+ /**
+ * Indicate whether the file is successfully deleted. Is false if the file does not exist in the first place.
+ *
+ * @type {boolean}
+ * @memberof FileDeleteIfExistsResponse
+ */
+ succeeded: boolean;
+}
+
+/**
+ * A ShareFileClient represents a URL to an Azure Storage file.
+ *
+ * @export
+ * @class ShareFileClient
+ */
+export class ShareFileClient extends StorageClient {
+ /**
+ * context provided by protocol layer.
+ *
+ * @private
+ * @type {File}
+ * @memberof ShareFileClient
+ */
+ private context: File;
+
+ private _shareName: string;
+ private _path: string;
+ private _name: string;
+
+ /**
+ * The share name corresponding to this file client
+ *
+ * @type {string}
+ * @memberof ShareFileClient
+ */
+ public get shareName(): string {
+ return this._shareName;
+ }
+
+ /**
+ * The full path of the file
+ *
+ * @type {string}
+ * @memberof ShareFileClient
+ */
+ public get path(): string {
+ return this._path;
+ }
+
+ /**
+ * The name of the file
+ *
+ * @type {string}
+ * @memberof ShareFileClient
+ */
+ public get name(): string {
+ return this._name;
+ }
+
+ /**
+ * Creates an instance of ShareFileClient.
+ *
+ * @param {string} url A URL string pointing to Azure Storage file, such as
+ * "https://myaccount.file.core.windows.net/myshare/mydirectory/file". You can
+ * append a SAS if using AnonymousCredential, such as
+ * "https://myaccount.file.core.windows.net/myshare/mydirectory/file?sasString".
+ * This method accepts an encoded URL or non-encoded URL pointing to a file.
+ * Encoded URL string will NOT be escaped twice, only special characters in URL path will be escaped.
+ * However, if a file or directory name includes %, file or directory name must be encoded in the URL.
+ * Such as a file named "myfile%", the URL should be "https://myaccount.file.core.windows.net/myshare/mydirectory/myfile%25".
+ * @param {Credential} [credential] Such as AnonymousCredential or StorageSharedKeyCredential.
+ * If not specified, AnonymousCredential is used.
+ * @param {StoragePipelineOptions} [options] Optional. Options to configure the HTTP pipeline.
+ * @memberof ShareFileClient
+ */
+ constructor(url: string, credential?: Credential, options?: StoragePipelineOptions);
+ /**
+ * Creates an instance of ShareFileClient.
+ *
+ * @param {string} url A URL string pointing to Azure Storage file, such as
+ * "https://myaccount.file.core.windows.net/myshare/mydirectory/file". You can
+ * append a SAS if using AnonymousCredential, such as
+ * "https://myaccount.file.core.windows.net/myshare/mydirectory/file?sasString".
+ * This method accepts an encoded URL or non-encoded URL pointing to a file.
+ * Encoded URL string will NOT be escaped twice, only special characters in URL path will be escaped.
+ * However, if a file or directory name includes %, file or directory name must be encoded in the URL.
+ * Such as a file named "myfile%", the URL should be "https://myaccount.file.core.windows.net/myshare/mydirectory/myfile%25".
+ * @param {Pipeline} pipeline Call newPipeline() to create a default
+ * pipeline, or provide a customized pipeline.
+ * @memberof ShareFileClient
+ */
+ constructor(url: string, pipeline: Pipeline);
+ constructor(
+ url: string,
+ credentialOrPipeline?: Credential | Pipeline,
+ options?: StoragePipelineOptions
+ ) {
+ let pipeline: Pipeline;
+ if (credentialOrPipeline instanceof Pipeline) {
+ pipeline = credentialOrPipeline;
+ } else if (credentialOrPipeline instanceof Credential) {
+ pipeline = newPipeline(credentialOrPipeline, options);
+ } else {
+ // The second parameter is undefined. Use anonymous credential.
+ pipeline = newPipeline(new AnonymousCredential(), options);
+ }
+
+ super(url, pipeline);
+ ({
+ baseName: this._name,
+ shareName: this._shareName,
+ path: this._path
+ } = getShareNameAndPathFromUrl(this.url));
+ this.context = new File(this.storageClientContext);
+ }
+
+ /**
+ * Creates a new ShareFileClient object identical to the source but with the specified share snapshot timestamp.
+ * Provide "" will remove the snapshot and return a URL to the base ShareFileClient.
+ *
+ * @param {string} shareSnapshot The share snapshot timestamp.
+ * @returns {ShareFileClient} A new ShareFileClient object identical to the source but with the specified share snapshot timestamp.
+ * @memberof ShareFileClient
+ */
+ public withShareSnapshot(shareSnapshot: string): ShareFileClient {
+ return new ShareFileClient(
+ setURLParameter(
+ this.url,
+ URLConstants.Parameters.SHARE_SNAPSHOT,
+ shareSnapshot.length === 0 ? undefined : shareSnapshot
+ ),
+ this.pipeline
+ );
+ }
+
+ /**
+ * Creates a new file or replaces a file. Note it only initializes the file with no content.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-file
+ *
+ * @param {number} size Specifies the maximum size in bytes for the file, up to 1 TB.
+ * @param {FileCreateOptions} [options] Options to File Create operation.
+ * @returns {Promise} Response data for the File Create operation.
+ * @memberof ShareFileClient
+ *
+ * Example usage:
+ *
+ * ```js
+ * const content = "Hello world!";
+ *
+ * // Create the file
+ * await fileClient.create(content.length);
+ * console.log("Created file successfully!");
+ *
+ * // Then upload data to the file
+ * await fileClient.uploadRange(content, 0, content.length);
+ * console.log("Updated file successfully!")
+ * ```
+ */
+ public async create(size: number, options: FileCreateOptions = {}): Promise {
+ const { span, spanOptions } = createSpan("ShareFileClient-create", options.tracingOptions);
+ try {
+ if (size < 0 || size > FILE_MAX_SIZE_BYTES) {
+ throw new RangeError(`File size must >= 0 and < ${FILE_MAX_SIZE_BYTES}.`);
+ }
+ options = validateAndSetDefaultsForFileAndDirectoryCreateCommonOptions(options);
+
+ if (!options.fileAttributes) {
+ // Note: It would be Archive in service side if None is set.
+ const attributes: FileSystemAttributes = new FileSystemAttributes();
+ attributes.none = true;
+ options.fileAttributes = attributes;
+ }
+
+ options.fileHttpHeaders = options.fileHttpHeaders || {};
+
+ return await this.context.create(
+ size,
+ fileAttributesToString(options.fileAttributes!),
+ fileCreationTimeToString(options.creationTime!),
+ fileLastWriteTimeToString(options.lastWriteTime!),
+ {
+ abortSignal: options.abortSignal,
+ fileHttpHeaders: options.fileHttpHeaders,
+ metadata: options.metadata,
+ filePermission: options.filePermission,
+ filePermissionKey: options.filePermissionKey,
+ leaseAccessConditions: options.leaseAccessConditions,
+ spanOptions
+ }
+ );
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Reads or downloads a file from the system, including its metadata and properties.
+ *
+ * * In Node.js, data returns in a Readable stream `readableStreamBody`
+ * * In browsers, data returns in a promise `contentAsBlob`
+ *
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-file
+ *
+ * @param {number} [offset] From which position of the file to download, >= 0
+ * @param {number} [count] How much data to be downloaded, > 0. Will download to the end when undefined
+ * @param {FileDownloadOptions} [options] Options to File Download operation.
+ * @returns {Promise} Response data for the File Download operation.
+ * @memberof ShareFileClient
+ *
+ * Example usage (Node.js):
+ *
+ * ```js
+ * // Download a file to a string
+ * const downloadFileResponse = await fileClient.download();
+ * console.log(
+ * "Downloaded file content:",
+ * (await streamToBuffer(downloadFileResponse.readableStreamBody)).toString()}
+ * );
+ *
+ * // A helper method used to read a Node.js readable stream into string
+ * async function streamToBuffer(readableStream) {
+ * return new Promise((resolve, reject) => {
+ * const chunks = [];
+ * readableStream.on("data", (data) => {
+ * chunks.push(data instanceof Buffer ? data : Buffer.from(data));
+ * });
+ * readableStream.on("end", () => {
+ * resolve(Buffer.concat(chunks));
+ * });
+ * readableStream.on("error", reject);
+ * });
+ * }
+ * ```
+ *
+ * Example usage (browsers):
+ *
+ * ```js
+ * // Download a file to a string
+ * const downloadFileResponse = await fileClient.download(0);
+ * console.log(
+ * "Downloaded file content:",
+ * await blobToString(await downloadFileResponse.blobBody)}
+ * );
+ *
+ * // A helper method used to convert a browser Blob into string.
+ * export async function blobToString(blob: Blob): Promise {
+ * const fileReader = new FileReader();
+ * return new Promise((resolve, reject) => {
+ * fileReader.onloadend = (ev: any) => {
+ * resolve(ev.target!.result);
+ * };
+ * fileReader.onerror = reject;
+ * fileReader.readAsText(blob);
+ * });
+ * }
+ * ```
+ */
+ public async download(
+ offset: number = 0,
+ count?: number,
+ options: FileDownloadOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan("ShareFileClient-download", options.tracingOptions);
+ try {
+ if (options.rangeGetContentMD5 && offset === 0 && count === undefined) {
+ throw new RangeError(`rangeGetContentMD5 only works with partial data downloading`);
+ }
+
+ const downloadFullFile = offset === 0 && !count;
+ const res = await this.context.download({
+ abortSignal: options.abortSignal,
+ onDownloadProgress: isNode ? undefined : options.onProgress, // for Node.js, progress is reported by RetriableReadableStream
+ range: downloadFullFile ? undefined : rangeToString({ offset, count }),
+ rangeGetContentMD5: options.rangeGetContentMD5,
+ leaseAccessConditions: options.leaseAccessConditions,
+ spanOptions
+ });
+
+ // Return browser response immediately
+ if (!isNode) {
+ return res;
+ }
+
+ // We support retrying when download stream unexpected ends in Node.js runtime
+ // Following code shouldn't be bundled into browser build, however some
+ // bundlers may try to bundle following code and "FileReadResponse.ts".
+ // In this case, "FileDownloadResponse.browser.ts" will be used as a shim of "FileDownloadResponse.ts"
+ // The config is in package.json "browser" field
+ if (options.maxRetryRequests === undefined || options.maxRetryRequests < 0) {
+ // TODO: Default value or make it a required parameter?
+ options.maxRetryRequests = DEFAULT_MAX_DOWNLOAD_RETRY_REQUESTS;
+ }
+
+ if (res.contentLength === undefined) {
+ throw new RangeError(`File download response doesn't contain valid content length header`);
+ }
+
+ return new FileDownloadResponse(
+ res,
+ async (start: number): Promise => {
+ const updatedOptions: FileDownloadOptionalParams = {
+ range: rangeToString({
+ count: offset + res.contentLength! - start,
+ offset: start
+ })
+ };
+
+ // Debug purpose only
+ // console.log(
+ // `Read from internal stream, range: ${
+ // updatedOptions.range
+ // }, options: ${JSON.stringify(updatedOptions)}`
+ // );
+
+ return (
+ await this.context.download({
+ abortSignal: options.abortSignal,
+ leaseAccessConditions: options.leaseAccessConditions,
+ ...updatedOptions,
+ spanOptions
+ })
+ ).readableStreamBody!;
+ },
+ offset,
+ res.contentLength!,
+ {
+ abortSignal: options.abortSignal,
+ maxRetryRequests: options.maxRetryRequests,
+ onProgress: options.onProgress
+ }
+ );
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Returns true if the specified file exists; false otherwise.
+ *
+ * NOTE: use this function with care since an existing file might be deleted by other clients or
+ * applications. Vice versa new files might be added by other clients or applications after this
+ * function completes.
+ *
+ * @param {FileExistsOptions} [options] options to Exists operation.
+ * @returns {Promise}
+ * @memberof ShareFileClient
+ */
+ public async exists(options: FileExistsOptions = {}): Promise {
+ const { span, spanOptions } = createSpan("ShareFileClient-exists", options.tracingOptions);
+ try {
+ await this.getProperties({
+ abortSignal: options.abortSignal,
+ tracingOptions: {
+ ...options.tracingOptions,
+ spanOptions
+ }
+ });
+ return true;
+ } catch (e) {
+ if (e.statusCode === 404) {
+ span.setStatus({
+ code: CanonicalCode.NOT_FOUND,
+ message: "Expected exception when checking file existence"
+ });
+ return false;
+ }
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Returns all user-defined metadata, standard HTTP properties, and system properties
+ * for the file. It does not return the content of the file.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-file-properties
+ *
+ * @param {FileGetPropertiesOptions} [options] Options to File Get Properties operation.
+ * @returns {Promise} Response data for the File Get Properties operation.
+ * @memberof ShareFileClient
+ */
+ public async getProperties(
+ options: FileGetPropertiesOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareFileClient-getProperties",
+ options.tracingOptions
+ );
+ try {
+ return this.context.getProperties({
+ abortSignal: options.abortSignal,
+ leaseAccessConditions: options.leaseAccessConditions,
+ spanOptions
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Sets properties on the file.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-file-properties
+ *
+ * @param {FileProperties} [properties] File properties. For file HTTP headers(e.g. Content-Type),
+ * if no values are provided, existing HTTP headers will be removed.
+ * For other file properties(e.g. fileAttributes), if no values are provided,
+ * existing values will be preserved.
+ * @returns {Promise}
+ * @memberof ShareFileClient
+ */
+ public async setProperties(properties: FileProperties = {}): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareFileClient-setProperties",
+ properties.tracingOptions
+ );
+ try {
+ properties = validateAndSetDefaultsForFileAndDirectorySetPropertiesCommonOptions(properties);
+
+ properties.fileHttpHeaders = properties.fileHttpHeaders || {};
+
+ return await this.context.setHTTPHeaders(
+ fileAttributesToString(properties.fileAttributes!),
+ fileCreationTimeToString(properties.creationTime!),
+ fileLastWriteTimeToString(properties.lastWriteTime!),
+ {
+ abortSignal: properties.abortSignal,
+ fileHttpHeaders: properties.fileHttpHeaders,
+ filePermission: properties.filePermission,
+ filePermissionKey: properties.filePermissionKey,
+ leaseAccessConditions: properties.leaseAccessConditions,
+ spanOptions
+ }
+ );
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Removes the file from the storage account.
+ * When a file is successfully deleted, it is immediately removed from the storage
+ * account's index and is no longer accessible to clients. The file's data is later
+ * removed from the service during garbage collection.
+ *
+ * Delete File will fail with status code 409 (Conflict) and error code SharingViolation
+ * if the file is open on an SMB client.
+ *
+ * Delete File is not supported on a share snapshot, which is a read-only copy of
+ * a share. An attempt to perform this operation on a share snapshot will fail with 400 (InvalidQueryParameterValue)
+ *
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-file2
+ *
+ * @param {FileDeleteOptions} [options] Options to File Delete operation.
+ * @returns {Promise} Response data for the File Delete operation.
+ * @memberof ShareFileClient
+ */
+ public async delete(options: FileDeleteOptions = {}): Promise {
+ const { span, spanOptions } = createSpan("ShareFileClient-delete", options.tracingOptions);
+ try {
+ return await this.context.deleteMethod({
+ abortSignal: options.abortSignal,
+ leaseAccessConditions: options.leaseAccessConditions,
+ spanOptions
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Removes the file from the storage account if it exists.
+ * When a file is successfully deleted, it is immediately removed from the storage
+ * account's index and is no longer accessible to clients. The file's data is later
+ * removed from the service during garbage collection.
+ *
+ * Delete File will fail with status code 409 (Conflict) and error code SharingViolation
+ * if the file is open on an SMB client.
+ *
+ * Delete File is not supported on a share snapshot, which is a read-only copy of
+ * a share. An attempt to perform this operation on a share snapshot will fail with 400 (InvalidQueryParameterValue)
+ *
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-file2
+ *
+ * @param {FileDeleteOptions} [options]
+ * @returns {Promise}
+ * @memberof ShareFileClient
+ */
+ public async deleteIfExists(
+ options: FileDeleteOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareFileClient-deleteIfExists",
+ options.tracingOptions
+ );
+ try {
+ const res = await this.delete({
+ ...options,
+ tracingOptions: { ...options!.tracingOptions, spanOptions }
+ });
+ return {
+ succeeded: true,
+ ...res
+ };
+ } catch (e) {
+ if (e.details?.errorCode === "ResourceNotFound") {
+ span.setStatus({
+ code: CanonicalCode.NOT_FOUND,
+ message: "Expected exception when deleting a file only if it exists."
+ });
+ return {
+ succeeded: false,
+ ...e.response?.parsedHeaders,
+ _response: e.response
+ };
+ }
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Sets HTTP headers on the file.
+ *
+ * If no option provided, or no value provided for the file HTTP headers in the options,
+ * these file HTTP headers without a value will be cleared.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-file-properties
+ *
+ * @param {fileHttpHeaders} [FileHttpHeaders] File HTTP headers like Content-Type.
+ * Provide undefined will remove existing HTTP headers.
+ * @param {FileSetHttpHeadersOptions} [options] Options to File Set HTTP Headers operation.
+ * @returns {Promise} Response data for the File Set HTTP Headers operation.
+ * @memberof ShareFileClient
+ */
+ public async setHttpHeaders(
+ fileHttpHeaders: FileHttpHeaders = {},
+ options: FileSetHttpHeadersOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareFileClient-setHTTPHeaders",
+ options.tracingOptions
+ );
+ try {
+ // FileAttributes, filePermission, createTime, lastWriteTime will all be preserved
+ options = validateAndSetDefaultsForFileAndDirectorySetPropertiesCommonOptions(options);
+ return await this.context.setHTTPHeaders(
+ fileAttributesToString(options.fileAttributes!),
+ fileCreationTimeToString(options.creationTime!),
+ fileLastWriteTimeToString(options.lastWriteTime!),
+ {
+ abortSignal: options.abortSignal,
+ fileHttpHeaders,
+ filePermission: options.filePermission,
+ filePermissionKey: options.filePermissionKey,
+ leaseAccessConditions: options.leaseAccessConditions,
+ spanOptions
+ }
+ );
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Resize file.
+ *
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-file-properties
+ *
+ * @param {number} length Resizes a file to the specified size in bytes.
+ * If the specified byte value is less than the current size of the file,
+ * then all ranges above the specified byte value are cleared.
+ * @param {FileResizeOptions} [options] Options to File Resize operation.
+ * @returns {Promise} Response data for the File Set HTTP Headers operation.
+ * @memberof ShareFileClient
+ */
+ public async resize(
+ length: number,
+ options: FileResizeOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan("ShareFileClient-resize", options.tracingOptions);
+ try {
+ if (length < 0) {
+ throw new RangeError(`Size cannot less than 0 when resizing file.`);
+ }
+ // FileAttributes, filePermission, createTime, lastWriteTime will all be preserved.
+ options = validateAndSetDefaultsForFileAndDirectorySetPropertiesCommonOptions(options);
+
+ return await this.context.setHTTPHeaders(
+ fileAttributesToString(options.fileAttributes!),
+ fileCreationTimeToString(options.creationTime!),
+ fileLastWriteTimeToString(options.lastWriteTime!),
+ {
+ abortSignal: options.abortSignal,
+ fileContentLength: length,
+ filePermission: options.filePermission,
+ filePermissionKey: options.filePermissionKey,
+ leaseAccessConditions: options.leaseAccessConditions,
+ spanOptions
+ }
+ );
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Updates user-defined metadata for the specified file.
+ *
+ * If no metadata defined in the option parameter, the file
+ * metadata will be removed.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-file-metadata
+ *
+ * @param {Metadata} [metadata] If no metadata provided, all existing directory metadata will be removed
+ * @param {FileSetMetadataOptions} [options] Options to File Set Metadata operation.
+ * @returns {Promise} Response data for the File Set Metadata operation.
+ * @memberof ShareFileClient
+ */
+ public async setMetadata(
+ metadata: Metadata = {},
+ options: FileSetMetadataOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan("ShareFileClient-setMetadata", options.tracingOptions);
+ try {
+ return await this.context.setMetadata({
+ abortSignal: options.abortSignal,
+ metadata,
+ leaseAccessConditions: options.leaseAccessConditions,
+ spanOptions
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Upload a range of bytes to a file. Both the start and count of the
+ * range must be specified. The range can be up to 4 MB in size.
+ *
+ * @param {HttpRequestBody} body Blob, string, ArrayBuffer, ArrayBufferView or a function
+ * which returns a new Readable stream whose offset is from data source beginning.
+ * @param {number} offset Offset position of the destination Azure File to upload.
+ * @param {number} contentLength Length of body in bytes. Use Buffer.byteLength() to calculate body length for a
+ * string including non non-Base64/Hex-encoded characters.
+ * @param {FileUploadRangeOptions} [options={}] Options to File Upload Range operation.
+ * @returns {Promise} Response data for the File Upload Range operation.
+ * @memberof ShareFileClient
+ *
+ * Example usage:
+ *
+ * ```js
+ * const content = "Hello world!";
+ *
+ * // Create the file
+ * await fileClient.create(content.length);
+ * console.log("Created file successfully!");
+ *
+ * // Then upload data to the file
+ * await fileClient.uploadRange(content, 0, content.length);
+ * console.log("Updated file successfully!")
+ * ```
+ */
+ public async uploadRange(
+ body: HttpRequestBody,
+ offset: number,
+ contentLength: number,
+ options: FileUploadRangeOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan("ShareFileClient-uploadRange", options.tracingOptions);
+ try {
+ if (offset < 0) {
+ throw new RangeError(`offset must be >= 0`);
+ }
+
+ if (contentLength <= 0 || contentLength > FILE_RANGE_MAX_SIZE_BYTES) {
+ throw new RangeError(`contentLength must be > 0 and <= ${FILE_RANGE_MAX_SIZE_BYTES} bytes`);
+ }
+
+ if (contentLength > FILE_RANGE_MAX_SIZE_BYTES) {
+ throw new RangeError(`offset must be < ${FILE_RANGE_MAX_SIZE_BYTES} bytes`);
+ }
+
+ return await this.context.uploadRange(
+ rangeToString({ count: contentLength, offset }),
+ "update",
+ contentLength,
+ {
+ abortSignal: options.abortSignal,
+ contentMD5: options.contentMD5,
+ onUploadProgress: options.onProgress,
+ body: body,
+ spanOptions,
+ leaseAccessConditions: options.leaseAccessConditions
+ }
+ );
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Upload a range of bytes to a file where the contents are read from a another file's URL.
+ * The range can be up to 4 MB in size.
+ *
+ * @param {string} sourceURL Specify a URL to the copy source, Shared Access Signature(SAS) maybe needed for authentication.
+ * @param {number} sourceOffset The source offset to copy from. Pass 0 to copy from the beginning of source file.
+ * @param {number} destOffset Offset of destination file.
+ * @param {number} count Number of bytes to be uploaded from source file.
+ * @param {FileUploadRangeFromURLOptions} [options={}] Options to configure File - Upload Range from URL operation.
+ * @returns {Promise}
+ * @memberof FileURL
+ */
+ public async uploadRangeFromURL(
+ sourceURL: string,
+ sourceOffset: number,
+ destOffset: number,
+ count: number,
+ options: FileUploadRangeFromURLOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareFileClient-uploadRangeFromURL",
+ options.tracingOptions
+ );
+ try {
+ if (sourceOffset < 0 || destOffset < 0) {
+ throw new RangeError(`sourceOffset and destOffset must be >= 0`);
+ }
+
+ if (count <= 0 || count > FILE_RANGE_MAX_SIZE_BYTES) {
+ throw new RangeError(`count must be > 0 and <= ${FILE_RANGE_MAX_SIZE_BYTES} bytes`);
+ }
+
+ return await this.context.uploadRangeFromURL(
+ rangeToString({ offset: destOffset, count }),
+ sourceURL,
+ 0,
+ {
+ abortSignal: options.abortSignal,
+ sourceRange: rangeToString({ offset: sourceOffset, count }),
+ sourceModifiedAccessConditions: options.sourceConditions,
+ ...options,
+ spanOptions
+ }
+ );
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+ /**
+ * Clears the specified range and
+ * releases the space used in storage for that range.
+ *
+ * @param {number} offset
+ * @param {number} contentLength
+ * @param {FileClearRangeOptions} [options] Options to File Clear Range operation.
+ * @returns {Promise}
+ * @memberof ShareFileClient
+ */
+ public async clearRange(
+ offset: number,
+ contentLength: number,
+ options: FileClearRangeOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan("ShareFileClient-clearRange", options.tracingOptions);
+ try {
+ if (offset < 0 || contentLength <= 0) {
+ throw new RangeError(`offset must >= 0 and contentLength must be > 0`);
+ }
+
+ return await this.context.uploadRange(
+ rangeToString({ count: contentLength, offset }),
+ "clear",
+ 0,
+ {
+ abortSignal: options.abortSignal,
+ spanOptions,
+ leaseAccessConditions: options.leaseAccessConditions
+ }
+ );
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Returns the list of valid ranges for a file.
+ *
+ * @param {FileGetRangeListOptions} [options] Options to File Get range List operation.
+ * @returns {Promise}
+ * @memberof ShareFileClient
+ */
+ public async getRangeList(
+ options: FileGetRangeListOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareFileClient-getRangeList",
+ options.tracingOptions
+ );
+ try {
+ const originalResponse = await this.context.getRangeList({
+ abortSignal: options.abortSignal,
+ range: options.range ? rangeToString(options.range) : undefined,
+ leaseAccessConditions: options.leaseAccessConditions,
+ spanOptions
+ });
+
+ // Only returns ranges, ignoring clearRanges.
+ const parsedBody = originalResponse._response.parsedBody.ranges
+ ? originalResponse._response.parsedBody.ranges
+ : [];
+ return {
+ ...originalResponse,
+ _response: { ...originalResponse._response, parsedBody },
+ rangeList: originalResponse.ranges ? originalResponse.ranges : []
+ };
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Returns the list of ranges that differ between a previous share snapshot and this file.
+ *
+ * @param {string} [prevShareSnapshot] The previous snapshot parameter is an opaque DateTime value that specifies the previous share snapshot to compare with.
+ * @param {FileGetRangeListOptions} [options]
+ * @returns {Promise}
+ * @memberof ShareFileClient
+ */
+ public async getRangeListDiff(
+ prevShareSnapshot: string,
+ options: FileGetRangeListOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareFileClient-getRangeListDiff",
+ options.tracingOptions
+ );
+ try {
+ return await this.context.getRangeList({
+ prevsharesnapshot: prevShareSnapshot,
+ ...options,
+ range: options.range ? rangeToString(options.range) : undefined,
+ spanOptions
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Copies a blob or file to a destination file within the storage account.
+ *
+ * @param {string} copySource Specifies the URL of the source file or blob, up to 2 KB in length.
+ * To copy a file to another file within the same storage account, you may use Shared Key to
+ * authenticate the source file. If you are copying a file from another storage account, or if you
+ * are copying a blob from the same storage account or another storage account, then you must
+ * authenticate the source file or blob using a shared access signature. If the source is a public
+ * blob, no authentication is required to perform the copy operation. A file in a share snapshot
+ * can also be specified as a copy source.
+ * @param {FileStartCopyOptions} [options] Options to File Start Copy operation.
+ * @returns {Promise}
+ * @memberof ShareFileClient
+ */
+ public async startCopyFromURL(
+ copySource: string,
+ options: FileStartCopyOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareFileClient-startCopyFromURL",
+ options.tracingOptions
+ );
+ try {
+ return await this.context.startCopy(copySource, {
+ abortSignal: options.abortSignal,
+ metadata: options.metadata,
+ leaseAccessConditions: options.leaseAccessConditions,
+ filePermission: options.filePermission,
+ filePermissionKey: options.filePermissionKey,
+ copyFileSmbInfo: options.copyFileSmbInfo,
+ spanOptions
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Aborts a pending Copy File operation, and leaves a destination file with zero length and full
+ * metadata.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/abort-copy-file
+ *
+ * @param {string} copyId Id of the Copy File operation to abort.
+ * @param {FileAbortCopyFromURLOptions} [options] Options to File Abort Copy From URL operation.
+ * @returns {Promise}
+ * @memberof ShareFileClient
+ */
+ public async abortCopyFromURL(
+ copyId: string,
+ options: FileAbortCopyFromURLOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareFileClient-abortCopyFromURL",
+ options.tracingOptions
+ );
+ try {
+ return await this.context.abortCopy(copyId, {
+ abortSignal: options.abortSignal,
+ leaseAccessConditions: options.leaseAccessConditions,
+ spanOptions
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ // High Level functions
+
+ /**
+ * Uploads a Buffer(Node)/Blob/ArrayBuffer/ArrayBufferView to an Azure File.
+ *
+ * @param {Buffer | Blob | ArrayBuffer | ArrayBufferView} data Buffer(Node), Blob, ArrayBuffer or ArrayBufferView
+ * @param {FileParallelUploadOptions} [options]
+ * @returns {Promise}
+ */
+ public async uploadData(
+ data: Buffer | Blob | ArrayBuffer | ArrayBufferView,
+ options: FileParallelUploadOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan("ShareFileClient-uploadData", options.tracingOptions);
+ try {
+ if (isNode && data instanceof Buffer) {
+ return this.uploadBuffer(
+ (offset, count) => data.slice(offset, offset + count),
+ data.byteLength,
+ {
+ ...options,
+ tracingOptions: { ...options!.tracingOptions, spanOptions }
+ }
+ );
+ } else {
+ const browserBlob = new Blob([data]);
+ return this.uploadSeekableBlob(
+ (offset: number, size: number): Blob => {
+ return browserBlob.slice(offset, offset + size);
+ },
+ browserBlob.size,
+ { ...options, tracingOptions: { ...options!.tracingOptions, spanOptions } }
+ );
+ }
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * ONLY AVAILABLE IN BROWSERS.
+ *
+ * Uploads a browser Blob object to an Azure file. Requires a blobFactory as the data source,
+ * which need to return a Blob object with the offset and size provided.
+ *
+ * @param {(offset: number, size: number) => Blob} blobFactory
+ * @param {number} size
+ * @param {FileParallelUploadOptions} [options]
+ * @returns {Promise}
+ */
+ async uploadSeekableBlob(
+ blobFactory: (offset: number, size: number) => Blob,
+ size: number,
+ options: FileParallelUploadOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareFileClient-UploadSeekableBlob",
+ options.tracingOptions
+ );
+ try {
+ if (!options.rangeSize) {
+ options.rangeSize = FILE_RANGE_MAX_SIZE_BYTES;
+ }
+ if (options.rangeSize < 0 || options.rangeSize > FILE_RANGE_MAX_SIZE_BYTES) {
+ throw new RangeError(`options.rangeSize must be > 0 and <= ${FILE_RANGE_MAX_SIZE_BYTES}`);
+ }
+
+ if (!options.fileHttpHeaders) {
+ options.fileHttpHeaders = {};
+ }
+
+ if (!options.concurrency) {
+ options.concurrency = DEFAULT_HIGH_LEVEL_CONCURRENCY;
+ }
+ if (options.concurrency < 0) {
+ throw new RangeError(`options.concurrency cannot less than 0.`);
+ }
+
+ // Create the file
+ await this.create(size, {
+ abortSignal: options.abortSignal,
+ fileHttpHeaders: options.fileHttpHeaders,
+ metadata: options.metadata,
+ leaseAccessConditions: options.leaseAccessConditions,
+ tracingOptions: { ...options!.tracingOptions, spanOptions }
+ });
+
+ const numBlocks: number = Math.floor((size - 1) / options.rangeSize) + 1;
+ let transferProgress: number = 0;
+
+ const batch = new Batch(options.concurrency);
+ for (let i = 0; i < numBlocks; i++) {
+ batch.addOperation(
+ async (): Promise => {
+ const start = options.rangeSize! * i;
+ const end = i === numBlocks - 1 ? size : start + options.rangeSize!;
+ const contentLength = end - start;
+ await this.uploadRange(blobFactory(start, contentLength), start, contentLength, {
+ abortSignal: options.abortSignal,
+ leaseAccessConditions: options.leaseAccessConditions,
+ tracingOptions: { ...options!.tracingOptions, spanOptions }
+ });
+ // Update progress after block is successfully uploaded to server, in case of block trying
+ // TODO: Hook with convenience layer progress event in finer level
+ transferProgress += contentLength;
+ if (options.onProgress) {
+ options.onProgress({ loadedBytes: transferProgress });
+ }
+ }
+ );
+ }
+ return await batch.do();
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * ONLY AVAILABLE IN NODE.JS RUNTIME.
+ *
+ * Uploads a local file to an Azure file.
+ *
+ * @param {string} filePath Full path of local file
+ * @param {ShareFileClient} fileClient ShareFileClient
+ * @param {FileParallelUploadOptions} [options]
+ * @returns {(Promise)}
+ */
+ public async uploadFile(
+ filePath: string,
+ options: FileParallelUploadOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan("ShareFileClient-uploadFile", options.tracingOptions);
+ try {
+ const size = (await fsStat(filePath)).size;
+ return await this.uploadResetableStream(
+ (offset, count) =>
+ fsCreateReadStream(filePath, {
+ autoClose: true,
+ end: count ? offset + count - 1 : Infinity,
+ start: offset
+ }),
+ size,
+ { ...options, tracingOptions: { ...options!.tracingOptions, spanOptions } }
+ );
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * ONLY AVAILABLE IN NODE.JS RUNTIME.
+ *
+ * Accepts a Node.js Readable stream factory, and uploads in blocks to an Azure File.
+ * The Readable stream factory must returns a Node.js Readable stream starting from the offset defined. The offset
+ * is the offset in the Azure file to be uploaded.
+ *
+ * @export
+ * @param {(offset: number) => NodeJS.ReadableStream} streamFactory Returns a Node.js Readable stream starting
+ * from the offset defined
+ * @param {number} size Size of the Azure file
+ * @param {ShareFileClient} fileClient ShareFileClient
+ * @param {FileParallelUploadOptions} [options]
+ * @returns {(Promise)}
+ */
+ async uploadResetableStream(
+ streamFactory: (offset: number, count?: number) => NodeJS.ReadableStream,
+ size: number,
+ options: FileParallelUploadOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareFileClient-uploadResetableStream",
+ options.tracingOptions
+ );
+ try {
+ if (!options.rangeSize) {
+ options.rangeSize = FILE_RANGE_MAX_SIZE_BYTES;
+ }
+ if (options.rangeSize < 0 || options.rangeSize > FILE_RANGE_MAX_SIZE_BYTES) {
+ throw new RangeError(`options.rangeSize must be > 0 and <= ${FILE_RANGE_MAX_SIZE_BYTES}`);
+ }
+
+ if (!options.fileHttpHeaders) {
+ options.fileHttpHeaders = {};
+ }
+
+ if (!options.concurrency) {
+ options.concurrency = DEFAULT_HIGH_LEVEL_CONCURRENCY;
+ }
+ if (options.concurrency < 0) {
+ throw new RangeError(`options.concurrency cannot less than 0.`);
+ }
+
+ // Create the file
+ await this.create(size, {
+ abortSignal: options.abortSignal,
+ fileHttpHeaders: options.fileHttpHeaders,
+ metadata: options.metadata,
+ leaseAccessConditions: options.leaseAccessConditions,
+ tracingOptions: { ...options!.tracingOptions, spanOptions }
+ });
+
+ const numBlocks: number = Math.floor((size - 1) / options.rangeSize) + 1;
+ let transferProgress: number = 0;
+ const batch = new Batch(options.concurrency);
+
+ for (let i = 0; i < numBlocks; i++) {
+ batch.addOperation(
+ async (): Promise => {
+ const start = options.rangeSize! * i;
+ const end = i === numBlocks - 1 ? size : start + options.rangeSize!;
+ const contentLength = end - start;
+ await this.uploadRange(
+ () => streamFactory(start, contentLength),
+ start,
+ contentLength,
+ {
+ abortSignal: options.abortSignal,
+ leaseAccessConditions: options.leaseAccessConditions,
+ tracingOptions: { ...options!.tracingOptions, spanOptions }
+ }
+ );
+ // Update progress after block is successfully uploaded to server, in case of block trying
+ transferProgress += contentLength;
+ if (options.onProgress) {
+ options.onProgress({ loadedBytes: transferProgress });
+ }
+ }
+ );
+ }
+ return await batch.do();
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * ONLY AVAILABLE IN NODE.JS RUNTIME.
+ *
+ * @export
+ * @param {(offset: number, count: number) => Buffer} bufferChunk Returns a Node.js Buffer chunk starting
+ * from the offset defined till the count
+ * @param {number} size Size of the Azure file
+ * @param {ShareFileClient} fileClient ShareFileClient
+ * @param {FileParallelUploadOptions} [options]
+ * @returns {(Promise)}
+ */
+ private async uploadBuffer(
+ bufferChunk: (offset: number, count: number) => Buffer,
+ size: number,
+ options: FileParallelUploadOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareFileClient-uploadBuffer",
+ options.tracingOptions
+ );
+ try {
+ if (!options.rangeSize) {
+ options.rangeSize = FILE_RANGE_MAX_SIZE_BYTES;
+ }
+ if (options.rangeSize < 0 || options.rangeSize > FILE_RANGE_MAX_SIZE_BYTES) {
+ throw new RangeError(`options.rangeSize must be > 0 and <= ${FILE_RANGE_MAX_SIZE_BYTES}`);
+ }
+
+ if (!options.fileHttpHeaders) {
+ options.fileHttpHeaders = {};
+ }
+
+ if (!options.concurrency) {
+ options.concurrency = DEFAULT_HIGH_LEVEL_CONCURRENCY;
+ }
+ if (options.concurrency < 0) {
+ throw new RangeError(`options.concurrency cannot less than 0.`);
+ }
+
+ // Create the file
+ await this.create(size, {
+ abortSignal: options.abortSignal,
+ fileHttpHeaders: options.fileHttpHeaders,
+ metadata: options.metadata,
+ leaseAccessConditions: options.leaseAccessConditions,
+ tracingOptions: { ...options!.tracingOptions, spanOptions }
+ });
+
+ const numBlocks: number = Math.floor((size - 1) / options.rangeSize) + 1;
+ let transferProgress: number = 0;
+ const batch = new Batch(options.concurrency);
+
+ for (let i = 0; i < numBlocks; i++) {
+ batch.addOperation(
+ async (): Promise => {
+ const start = options.rangeSize! * i;
+ const end = i === numBlocks - 1 ? size : start + options.rangeSize!;
+ const contentLength = end - start;
+ await this.uploadRange(bufferChunk(start, contentLength), start, contentLength, {
+ abortSignal: options.abortSignal,
+ leaseAccessConditions: options.leaseAccessConditions,
+ tracingOptions: { ...options!.tracingOptions, spanOptions }
+ });
+ // Update progress after block is successfully uploaded to server, in case of block trying
+ transferProgress += contentLength;
+ if (options.onProgress) {
+ options.onProgress({ loadedBytes: transferProgress });
+ }
+ }
+ );
+ }
+ return await batch.do();
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * ONLY AVAILABLE IN NODE.JS RUNTIME.
+ *
+ * Downloads an Azure file in parallel to a buffer.
+ * Offset and count are optional, pass 0 for both to download the entire file.
+ *
+ * Warning: Buffers can only support files up to about one gigabyte on 32-bit systems or about two
+ * gigabytes on 64-bit systems due to limitations of Node.js/V8. For files larger than this size,
+ * consider {@link downloadToFile}.
+ *
+ * @param {Buffer} buffer Buffer to be fill, must have length larger than count
+ * @param {number} offset From which position of the Azure File to download
+ * @param {number} [count] How much data to be downloaded. Will download to the end when passing undefined
+ * @param {FileDownloadToBufferOptions} [options]
+ * @returns {Promise}
+ */
+ public async downloadToBuffer(
+ buffer: Buffer,
+ offset?: number,
+ count?: number,
+ options?: FileDownloadToBufferOptions
+ ): Promise;
+
+ /**
+ * ONLY AVAILABLE IN NODE.JS RUNTIME
+ *
+ * Downloads an Azure file in parallel to a buffer.
+ * Offset and count are optional, pass 0 for both to download the entire file
+ *
+ * Warning: Buffers can only support files up to about one gigabyte on 32-bit systems or about two
+ * gigabytes on 64-bit systems due to limitations of Node.js/V8. For files larger than this size,
+ * consider {@link downloadToFile}.
+ *
+ * @param {number} offset From which position of the Azure file to download
+ * @param {number} [count] How much data to be downloaded. Will download to the end when passing undefined
+ * @param {FileDownloadToBufferOptions} [options]
+ * @returns {Promise}
+ */
+ public async downloadToBuffer(
+ offset?: number,
+ count?: number,
+ options?: FileDownloadToBufferOptions
+ ): Promise;
+
+ public async downloadToBuffer(
+ bufferOrOffset?: Buffer | number,
+ offsetOrCount?: number,
+ countOrOptions?: FileDownloadToBufferOptions | number,
+ optOptions: FileDownloadToBufferOptions = {}
+ ): Promise {
+ let buffer: Buffer | undefined = undefined;
+ let offset: number;
+ let count: number;
+ let options: FileDownloadToBufferOptions = optOptions;
+
+ if (bufferOrOffset instanceof Buffer) {
+ buffer = bufferOrOffset;
+ offset = offsetOrCount || 0;
+ count = typeof countOrOptions === "number" ? countOrOptions : 0;
+ } else {
+ offset = typeof bufferOrOffset === "number" ? bufferOrOffset : 0;
+ count = typeof offsetOrCount === "number" ? offsetOrCount : 0;
+ options = (countOrOptions as FileDownloadToBufferOptions) || {};
+ }
+
+ const { span, spanOptions } = createSpan(
+ "ShareFileClient-downloadToBuffer",
+ options.tracingOptions
+ );
+
+ try {
+ if (!options.rangeSize) {
+ options.rangeSize = FILE_RANGE_MAX_SIZE_BYTES;
+ }
+ if (options.rangeSize < 0) {
+ throw new RangeError("rangeSize option must be > 0");
+ }
+
+ if (offset < 0) {
+ throw new RangeError("offset option must be >= 0");
+ }
+
+ if (count && count <= 0) {
+ throw new RangeError("count option must be > 0");
+ }
+
+ if (!options.concurrency) {
+ options.concurrency = DEFAULT_HIGH_LEVEL_CONCURRENCY;
+ }
+ if (options.concurrency < 0) {
+ throw new RangeError(`options.concurrency cannot less than 0.`);
+ }
+
+ // Customer doesn't specify length, get it
+ if (!count) {
+ const response = await this.getProperties({
+ abortSignal: options.abortSignal,
+ leaseAccessConditions: options.leaseAccessConditions,
+ tracingOptions: { ...options!.tracingOptions, spanOptions }
+ });
+ count = response.contentLength! - offset;
+ if (count < 0) {
+ throw new RangeError(
+ `offset ${offset} shouldn't be larger than file size ${response.contentLength!}`
+ );
+ }
+ }
+
+ if (!buffer) {
+ try {
+ buffer = Buffer.alloc(count);
+ } catch (error) {
+ throw new Error(
+ `Unable to allocate a buffer of size: ${count} bytes. Please try passing your own Buffer to ` +
+ 'the "downloadToBuffer method or try using other methods like "download" or "downloadToFile".' +
+ `\t ${error.message}`
+ );
+ }
+ }
+
+ if (buffer.length < count) {
+ throw new RangeError(
+ `The buffer's size should be equal to or larger than the request count of bytes: ${count}`
+ );
+ }
+
+ let transferProgress: number = 0;
+ const batch = new Batch(options.concurrency);
+ for (let off = offset; off < offset + count; off = off + options.rangeSize) {
+ batch.addOperation(async () => {
+ // Exclusive chunk end position
+ let chunkEnd = offset + count!;
+ if (off + options.rangeSize! < chunkEnd) {
+ chunkEnd = off + options.rangeSize!;
+ }
+ const response = await this.download(off, chunkEnd - off, {
+ abortSignal: options.abortSignal,
+ maxRetryRequests: options.maxRetryRequestsPerRange,
+ leaseAccessConditions: options.leaseAccessConditions,
+ tracingOptions: { ...options!.tracingOptions, spanOptions }
+ });
+ const stream = response.readableStreamBody!;
+ await streamToBuffer(stream, buffer!, off - offset, chunkEnd - offset);
+ // Update progress after block is downloaded, in case of block trying
+ // Could provide finer grained progress updating inside HTTP requests,
+ // only if convenience layer download try is enabled
+ transferProgress += chunkEnd - off;
+ if (options.onProgress) {
+ options.onProgress({ loadedBytes: transferProgress });
+ }
+ });
+ }
+ await batch.do();
+ return buffer;
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * ONLY AVAILABLE IN NODE.JS RUNTIME.
+ *
+ * Uploads a Node.js Readable stream into an Azure file.
+ * This method will try to create an Azure, then starts uploading chunk by chunk.
+ * Size of chunk is defined by `bufferSize` parameter.
+ * Please make sure potential size of stream doesn't exceed file size.
+ *
+ * PERFORMANCE IMPROVEMENT TIPS:
+ * * Input stream highWaterMark is better to set a same value with bufferSize
+ * parameter, which will avoid Buffer.concat() operations.
+ *
+ * @param {Readable} stream Node.js Readable stream. Must be less or equal than file size.
+ * @param {number} size Size of file to be created. Maximum size allowed is 1TB.
+ * If this value is larger than stream size, there will be empty bytes in file tail.
+ * @param {number} bufferSize Size of every buffer allocated in bytes, also the chunk/range size during
+ * the uploaded file. Size must be > 0 and <= 4 * 1024 * 1024 (4MB)
+ * @param {number} maxBuffers Max buffers will allocate during uploading, positive correlation
+ * with max uploading concurrency
+ * @param {FileUploadStreamOptions} [options]
+ * @returns {Promise}
+ */
+ public async uploadStream(
+ stream: Readable,
+ size: number,
+ bufferSize: number,
+ maxBuffers: number,
+ options: FileUploadStreamOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareFileClient-uploadStream",
+ options.tracingOptions
+ );
+ try {
+ if (!options.fileHttpHeaders) {
+ options.fileHttpHeaders = {};
+ }
+
+ if (bufferSize <= 0 || bufferSize > FILE_RANGE_MAX_SIZE_BYTES) {
+ throw new RangeError(`bufferSize must be > 0 and <= ${FILE_RANGE_MAX_SIZE_BYTES}`);
+ }
+
+ if (maxBuffers < 0) {
+ throw new RangeError(`maxBuffers must be > 0.`);
+ }
+
+ // Create the file
+ await this.create(size, {
+ abortSignal: options.abortSignal,
+ fileHttpHeaders: options.fileHttpHeaders,
+ metadata: options.metadata,
+ leaseAccessConditions: options.leaseAccessConditions,
+ tracingOptions: { ...options!.tracingOptions, spanOptions }
+ });
+
+ let transferProgress: number = 0;
+ const scheduler = new BufferScheduler(
+ stream,
+ bufferSize,
+ maxBuffers,
+ async (buffer: Buffer, offset?: number) => {
+ if (transferProgress + buffer.length > size) {
+ throw new RangeError(
+ `Stream size is larger than file size ${size} bytes, uploading failed. ` +
+ `Please make sure stream length is less or equal than file size.`
+ );
+ }
+
+ await this.uploadRange(buffer, offset!, buffer.length, {
+ abortSignal: options.abortSignal,
+ leaseAccessConditions: options.leaseAccessConditions,
+ tracingOptions: { ...options!.tracingOptions, spanOptions }
+ });
+
+ // Update progress after block is successfully uploaded to server, in case of block trying
+ transferProgress += buffer.length;
+ if (options.onProgress) {
+ options.onProgress({ loadedBytes: transferProgress });
+ }
+ },
+ // Concurrency should set a smaller value than maxBuffers, which is helpful to
+ // reduce the possibility when a outgoing handler waits for stream data, in
+ // this situation, outgoing handlers are blocked.
+ // Outgoing queue shouldn't be empty.
+ Math.ceil((maxBuffers / 4) * 3)
+ );
+ return await scheduler.do();
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * ONLY AVAILABLE IN NODE.JS RUNTIME.
+ *
+ * Downloads an Azure Blob to a local file.
+ * Fails if the the given file path already exits.
+ * Offset and count are optional, pass 0 and undefined respectively to download the entire blob.
+ *
+ * @param {string} filePath
+ * @param {number} [offset] From which position of the block blob to download.
+ * @param {number} [count] How much data to be downloaded. Will download to the end when passing undefined.
+ * @param {BlobDownloadOptions} [options] Options to Blob download options.
+ * @returns {Promise} The response data for blob download operation,
+ * but with readableStreamBody set to undefined since its
+ * content is already read and written into a local file
+ * at the specified path.
+ * @memberof BlobClient
+ */
+ public async downloadToFile(
+ filePath: string,
+ offset: number = 0,
+ count?: number,
+ options: FileDownloadOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareFileClient-downloadToFile",
+ options.tracingOptions
+ );
+ try {
+ const response = await this.download(offset, count, {
+ ...options,
+ tracingOptions: { ...options!.tracingOptions, spanOptions }
+ });
+ if (response.readableStreamBody) {
+ await readStreamToLocalFile(response.readableStreamBody, filePath);
+ }
+
+ // The stream is no longer accessible so setting it to undefined.
+ (response as any).fileDownloadStream = undefined;
+ return response;
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Lists handles for a file.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/list-handles
+ *
+ * @param {string} [marker] Optional. A string value that identifies the portion of the list to be
+ * returned with the next list handles operation. The operation returns a
+ * marker value within the response body if the list returned was not complete.
+ * The marker value may then be used in a subsequent call to request the next
+ * set of list items.
+ * @param {FileListHandlesSegmentOptions} [options={}]
+ * @returns {Promise}
+ * @memberof FileURL
+ */
+ private async listHandlesSegment(
+ marker?: string,
+ options: FileListHandlesSegmentOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareFileClient-listHandlesSegment",
+ options.tracingOptions
+ );
+ try {
+ marker = marker === "" ? undefined : marker;
+ const response = await this.context.listHandles({
+ abortSignal: options.abortSignal,
+ marker,
+ ...options,
+ spanOptions
+ });
+
+ // TODO: Protocol layer issue that when handle list is in returned XML
+ // response.handleList is an empty string
+ if ((response.handleList as any) === "") {
+ response.handleList = undefined;
+ }
+ return response;
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Returns an AsyncIterableIterator for FileListHandlesResponse
+ *
+ * @private
+ * @param {string} [marker] A string value that identifies the portion of the list to be
+ * returned with the next list handles operation. The operation returns a
+ * marker value within the response body if the list returned was not complete.
+ * The marker value may then be used in a subsequent call to request the next
+ * set of list items.
+ * @param {FileListHandlesSegmentOptions} [options] Options to list handles operation.
+ * @returns {AsyncIterableIterator}
+ * @memberof ShareFileClient
+ */
+ private async *iterateHandleSegments(
+ marker?: string,
+ options: FileListHandlesSegmentOptions = {}
+ ): AsyncIterableIterator {
+ let listHandlesResponse;
+ if (!!marker || marker === undefined) {
+ do {
+ listHandlesResponse = await this.listHandlesSegment(marker, options);
+ marker = listHandlesResponse.continuationToken;
+ yield listHandlesResponse;
+ } while (marker);
+ }
+ }
+
+ /**
+ * Returns an AsyncIterableIterator for handles
+ *
+ * @private
+ * @param {FileListHandlesSegmentOptions} [options] Options to list handles operation.
+ * @returns {AsyncIterableIterator}
+ * @memberof ShareFileClient
+ */
+ private async *listHandleItems(
+ options: FileListHandlesSegmentOptions = {}
+ ): AsyncIterableIterator {
+ let marker: string | undefined;
+ for await (const listHandlesResponse of this.iterateHandleSegments(marker, options)) {
+ if (listHandlesResponse.handleList) {
+ for (const handle of listHandlesResponse.handleList) {
+ yield handle;
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns an async iterable iterator to list all the handles.
+ * under the specified account.
+ *
+ * .byPage() returns an async iterable iterator to list the handles in pages.
+ *
+ * @param {FileListHandlesOptions} [options] Options to list handles operation.
+ * @memberof ShareFileClient
+ * @returns {PagedAsyncIterableIterator}
+ * An asyncIterableIterator that supports paging.
+ */
+ public listHandles(
+ options: FileListHandlesOptions = {}
+ ): PagedAsyncIterableIterator {
+ // an AsyncIterableIterator to iterate over handles
+ const iter = this.listHandleItems(options);
+ return {
+ /**
+ * @member {Promise} [next] The next method, part of the iteration protocol
+ */
+ async next() {
+ return iter.next();
+ },
+ /**
+ * @member {Symbol} [asyncIterator] The connection to the async iterator, part of the iteration protocol
+ */
+ [Symbol.asyncIterator]() {
+ return this;
+ },
+ /**
+ * @member {Function} [byPage] Return an AsyncIterableIterator that works a page at a time
+ */
+ byPage: (settings: PageSettings = {}) => {
+ return this.iterateHandleSegments(settings.continuationToken, {
+ maxPageSize: settings.maxPageSize,
+ ...options
+ });
+ }
+ };
+ }
+
+ /**
+ * Force close all handles for a file.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/force-close-handles
+ *
+ * @param {string} [marker] Optional. A string value that identifies the position of handles that will
+ * be closed with the next force close handles operation.
+ * The operation returns a marker value within the response
+ * body if there are more handles to close. The marker value
+ * may then be used in a subsequent call to close the next set of handles.
+ * @param {FileForceCloseHandlesOptions} [options] Options to force close handles operation.
+ * @returns {Promise}
+ * @memberof ShareFileClient
+ */
+ private async forceCloseHandlesSegment(
+ marker?: string,
+ options: FileForceCloseHandlesOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareFileClient-forceCloseHandlesSegment",
+ options.tracingOptions
+ );
+ try {
+ marker = marker === "" ? undefined : marker;
+ const rawResponse = await this.context.forceCloseHandles("*", {
+ abortSignal: options.abortSignal,
+ marker,
+ spanOptions
+ });
+ const response = rawResponse as FileForceCloseHandlesResponse;
+ response.closedHandlesCount = rawResponse.numberOfHandlesClosed || 0;
+ response.closeFailureCount = rawResponse.numberOfHandlesFailedToClose || 0;
+ return response;
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Force close all handles for a file.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/force-close-handles
+ *
+ * @param {FileForceCloseHandlesOptions} [options] Options to force close handles operation.
+ * @returns {Promise}
+ * @memberof ShareFileClient
+ */
+ public async forceCloseAllHandles(
+ options: FileForceCloseHandlesOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareFileClient-forceCloseAllHandles",
+ options.tracingOptions
+ );
+ try {
+ let handlesClosed = 0;
+ let numberOfHandlesFailedToClose = 0;
+ let marker: string | undefined = "";
+
+ do {
+ const response: FileForceCloseHandlesResponse = await this.forceCloseHandlesSegment(
+ marker,
+ { tracingOptions: { ...options!.tracingOptions, spanOptions } }
+ );
+ marker = response.marker;
+ response.closedHandlesCount && (handlesClosed += response.closedHandlesCount);
+ response.closeFailureCount && (numberOfHandlesFailedToClose += response.closeFailureCount);
+ } while (marker);
+
+ return {
+ closedHandlesCount: handlesClosed,
+ closeFailureCount: numberOfHandlesFailedToClose
+ };
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Force close a specific handle for a file.
+ * @see https://docs.microsoft.com/en-us/rest/api/storageservices/force-close-handles
+ *
+ * @param {string} handleId Specific handle ID, cannot be asterisk "*".
+ * Use forceCloseAllHandles() to close all handles.
+ * @param FileForceCloseHandlesOptions} [options] Options to force close handles operation.
+ * @returns {Promise}
+ * @memberof ShareFileClient
+ */
+ public async forceCloseHandle(
+ handleId: string,
+ options: FileForceCloseHandlesOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareFileClient-forceCloseHandle",
+ options.tracingOptions
+ );
+ try {
+ if (handleId === "*") {
+ throw new RangeError(
+ `Parameter handleID should be a specified handle ID. Use forceCloseHandlesSegment() to close all handles.`
+ );
+ }
+
+ const rawResponse = await this.context.forceCloseHandles(handleId, {
+ abortSignal: options.abortSignal,
+ spanOptions
+ });
+ const response = rawResponse as FileForceCloseHandlesResponse;
+ response.closedHandlesCount = rawResponse.numberOfHandlesClosed || 0;
+ response.closeFailureCount = rawResponse.numberOfHandlesFailedToClose || 0;
+ return response;
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * Get a {@link ShareLeaseClient} that manages leases on the file.
+ *
+ * @param {string} [proposeLeaseId] Initial proposed lease Id.
+ * @returns {ShareLeaseClient} A new ShareLeaseClient object for managing leases on the file.
+ * @memberof ShareFileClient
+ */
+ public getShareLeaseClient(proposeLeaseId?: string) {
+ return new ShareLeaseClient(this, proposeLeaseId);
+ }
+}
+
+/**
+ * The details of the response for a specific lease operation.
+ */
+export interface LeaseOperationResponseHeaders {
+ /**
+ * The ETag contains a value that you can use to perform operations conditionally. If the request
+ * version is 2011-08-18 or newer, the ETag value will be in quotes.
+ */
+ etag?: string;
+ /**
+ * Returns the date and time the file was last modified. Any operation that modifies the file,
+ * including an update of the file's metadata or properties, changes the last-modified time of
+ * the file.
+ */
+ lastModified?: Date;
+ /**
+ * Approximate time remaining in the lease period, in seconds. Only availabe for {@link ShareLeaseClient.breakLease} for share lease.
+ */
+ leaseTime?: number;
+ /**
+ * Uniquely identifies a file's lease, won't be set when returned by releaseLease.
+ */
+ leaseId?: string;
+ /**
+ * This header uniquely identifies the request that was made and can be used for troubleshooting
+ * the request.
+ */
+ requestId?: string;
+ /**
+ * Indicates the version of the Blob service used to execute the request. This header is returned
+ * for requests made against version 2009-09-19 and above.
+ */
+ version?: string;
+ /**
+ * UTC date/time value generated by the service that indicates the time at which the response was
+ * initiated
+ */
+ date?: Date;
+ errorCode?: string;
+}
+
+/**
+ * Contains the response data for operations that acquire, change, break or release a lease.
+ *
+ * See {@link ShareLeaseClient}.
+ */
+export type LeaseOperationResponse = LeaseOperationResponseHeaders & {
+ /**
+ * The underlying HTTP response.
+ */
+ _response: HttpResponse & {
+ /**
+ * The parsed HTTP response headers.
+ */
+ parsedHeaders: LeaseOperationResponseHeaders;
+ };
+};
+
+/**
+ * lease operations options.
+ *
+ * @export
+ * @interface LeaseOperationOptions
+ */
+export interface LeaseOperationOptions extends CommonOptions {
+ /**
+ * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
+ * For example, use the @azure/abort-controller to create an `AbortSignal`.
+ *
+ * @type {AbortSignalLike}
+ * @memberof LeaseOperationOptions
+ */
+ abortSignal?: AbortSignalLike;
+}
+
+/**
+ * A client that manages leases for a {@link ShareFileClient} or {@link ShareClient}.
+ * @see https://docs.microsoft.com/rest/api/storageservices/lease-file
+ * and
+ * @see https://docs.microsoft.com/rest/api/storageservices/lease-share
+ *
+ * @export
+ * @class ShareLeaseClient
+ */
+export class ShareLeaseClient {
+ private _leaseId: string;
+ private _url: string;
+ private fileOrShare: File | Share;
+ private isShare: boolean;
+ /**
+ * Gets the lease Id.
+ *
+ * @readonly
+ * @memberof ShareLeaseClient
+ * @type {string}
+ */
+ public get leaseId(): string {
+ return this._leaseId;
+ }
+
+ /**
+ * Gets the url.
+ *
+ * @readonly
+ * @memberof ShareLeaseClient
+ * @type {string}
+ */
+ public get url(): string {
+ return this._url;
+ }
+
+ /**
+ * Creates an instance of ShareLeaseClient.
+ * @param {ShareFileClient} client The client to make the lease operation requests.
+ * @param {string} leaseId Initial proposed lease id.
+ * @memberof ShareLeaseClient
+ */
+ constructor(client: ShareFileClient | ShareClient, leaseId?: string) {
+ const clientContext = new StorageClientContext(
+ SERVICE_VERSION,
+ client.url,
+ (client as any).pipeline.toServiceClientOptions()
+ );
+
+ if (client instanceof ShareClient) {
+ this.isShare = true;
+ this.fileOrShare = new Share(clientContext);
+ } else {
+ this.isShare = false;
+ this.fileOrShare = new File(clientContext);
+ }
+ this._url = client.url;
+
+ if (!leaseId) {
+ leaseId = generateUuid();
+ }
+ this._leaseId = leaseId;
+ }
+
+ /**
+ * Establishes and manages a lock on a file, share or share snapshot for write and delete operations.
+ *
+ * @param {number} duration Specifies the duration of lease in seconds. For file, the only allowed value is -1 for a lease that never expires. For share, must be -1 or between 15 to 60.
+ * @param {LeaseOperationOptions} [options={}] Options for the lease management operation.
+ * @returns {Promise} Response data for acquire lease operation.
+ * @memberof ShareLeaseClient
+ */
+ public async acquireLease(
+ duration: number = -1,
+ options: LeaseOperationOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareLeaseClient-acquireLease",
+ options.tracingOptions
+ );
+ try {
+ return await this.fileOrShare.acquireLease({
+ abortSignal: options.abortSignal,
+ duration,
+ proposedLeaseId: this._leaseId,
+ spanOptions
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * To change the ID of an existing lease.
+ *
+ * @param {string} proposedLeaseId the proposed new lease Id.
+ * @param {LeaseOperationOptions} [options={}] Options for the lease management operation.
+ * @returns {Promise} Response data for change lease operation.
+ * @memberof ShareLeaseClient
+ */
+ public async changeLease(
+ proposedLeaseId: string,
+ options: LeaseOperationOptions = {}
+ ): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareLeaseClient-changeLease",
+ options.tracingOptions
+ );
+ try {
+ const response = await this.fileOrShare.changeLease(this._leaseId, {
+ proposedLeaseId,
+ abortSignal: options.abortSignal,
+ spanOptions
+ });
+ this._leaseId = proposedLeaseId;
+ return response;
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * To free the lease if it is no longer needed so that another client may
+ * immediately acquire a lease.
+ *
+ * @param {LeaseOperationOptions} [options={}] Options for the lease management operation.
+ * @returns {Promise} Response data for release lease operation.
+ * @memberof ShareLeaseClient
+ */
+ public async releaseLease(options: LeaseOperationOptions = {}): Promise {
+ const { span, spanOptions } = createSpan(
+ "ShareLeaseClient-releaseLease",
+ options.tracingOptions
+ );
+ try {
+ return await this.fileOrShare.releaseLease(this._leaseId, {
+ abortSignal: options.abortSignal,
+ spanOptions
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * To force end the lease.
+ *
+ * @param {LeaseOperationOptions} [options={}] Options for the lease management operation.
+ * @returns {Promise} Response data for break lease operation.
+ * @memberof ShareLeaseClient
+ */
+ public async breakLease(options: LeaseOperationOptions = {}): Promise {
+ const { span, spanOptions } = createSpan("ShareLeaseClient-breakLease", options.tracingOptions);
+ try {
+ return await this.fileOrShare.breakLease({
+ abortSignal: options.abortSignal,
+ spanOptions
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+
+ /**
+ * To renew the lease. Only available for lease on share or share snapshot.
+ * Note that the lease may be renewed even if it has expired as long as the share has not been leased again since the expiration of that lease.
+ * When you renew a lease, the lease duration clock resets.
+ *
+ * @param {LeaseOperationOptions} [options={}] Options for the lease management operation.
+ * @returns {Promise} Response data for renew lease operation.
+ * @memberof ShareLeaseClient
+ */
+ public async renewLease(options: LeaseOperationOptions = {}): Promise {
+ const { span, spanOptions } = createSpan("ShareLeaseClient-renewLease", options.tracingOptions);
+
+ if (this.isShare) {
+ throw new RangeError("The renewLease operation is not available for lease on file.");
+ }
+
+ try {
+ return await this.fileOrShare.releaseLease(this._leaseId, {
+ abortSignal: options.abortSignal,
+ spanOptions
+ });
+ } catch (e) {
+ span.setStatus({
+ code: CanonicalCode.UNKNOWN,
+ message: e.message
+ });
+ throw e;
+ } finally {
+ span.end();
+ }
+ }
+}
diff --git a/sdk/storage/storage-file-share/src/ShareClient.ts b/sdk/storage/storage-file-share/src/ShareClient.ts
deleted file mode 100644
index e64e532ae62c..000000000000
--- a/sdk/storage/storage-file-share/src/ShareClient.ts
+++ /dev/null
@@ -1,1223 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-import { HttpResponse, isNode } from "@azure/core-http";
-import { CanonicalCode } from "@opentelemetry/api";
-import { AbortSignalLike } from "@azure/abort-controller";
-import {
- DeleteSnapshotsOptionType,
- DirectoryCreateResponse,
- DirectoryDeleteResponse,
- FileCreateResponse,
- FileDeleteResponse,
- ShareCreatePermissionResponse,
- ShareCreateResponse,
- ShareCreateSnapshotResponse,
- ShareDeleteResponse,
- ShareGetAccessPolicyHeaders,
- ShareGetPermissionResponse,
- ShareGetPropertiesResponse,
- ShareSetAccessPolicyResponse,
- ShareSetMetadataResponse,
- ShareSetQuotaResponse,
- SignedIdentifierModel,
- ShareGetStatisticsResponseModel
-} from "./generatedModels";
-import { Share } from "./generated/src/operations";
-import { Metadata } from "./models";
-import { newPipeline, StoragePipelineOptions, Pipeline } from "./Pipeline";
-import { StorageClient, CommonOptions } from "./StorageClient";
-import { URLConstants } from "./utils/constants";
-import {
- appendToURLPath,
- setURLParameter,
- truncatedISO8061Date,
- extractConnectionStringParts,
- getShareNameAndPathFromUrl
-} from "./utils/utils.common";
-import {
- ShareDirectoryClient,
- DirectoryCreateOptions,
- DirectoryDeleteOptions
-} from "./ShareDirectoryClient";
-import { FileCreateOptions, FileDeleteOptions, ShareFileClient } from "./ShareFileClient";
-import { Credential } from "./credentials/Credential";
-import { StorageSharedKeyCredential } from "./credentials/StorageSharedKeyCredential";
-import { AnonymousCredential } from "./credentials/AnonymousCredential";
-import { createSpan } from "./utils/tracing";
-
-/**
- * Options to configure the {@link ShareClient.create} operation.
- *
- * @export
- * @interface ShareCreateOptions
- */
-export interface ShareCreateOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof ShareCreateOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * A name-value pair to associate with a file storage object.
- *
- * @type {{ [propertyName: string]: string }}
- * @memberof ShareCreateOptions
- */
- metadata?: { [propertyName: string]: string };
-
- /**
- * Specifies the maximum size of the share, in
- * gigabytes.
- *
- * @type {number}
- * @memberof ShareCreateOptions
- */
- quota?: number;
-}
-
-/**
- * Options to configure the {@link ShareClient.delete} operation.
- *
- * @export
- * @interface ShareDeleteMethodOptions
- */
-export interface ShareDeleteMethodOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof ShareDeleteMethodOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * Specifies the option
- * include to delete the base share and all of its snapshots. Possible values
- * include: 'include'
- *
- * @type {DeleteSnapshotsOptionType}
- * @memberof ShareDeleteMethodOptions
- */
- deleteSnapshots?: DeleteSnapshotsOptionType;
-}
-
-/**
- * Options to configure the {@link ShareClient.setMetadata} operation.
- *
- * @export
- * @interface ShareSetMetadataOptions
- */
-export interface ShareSetMetadataOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof ShareSetMetadataOptions
- */
- abortSignal?: AbortSignalLike;
-}
-
-/**
- * Options to configure the {@link ShareClient.setAccessPolicy} operation.
- *
- * @export
- * @interface ShareSetAccessPolicyOptions
- */
-export interface ShareSetAccessPolicyOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof ShareSetAccessPolicyOptions
- */
- abortSignal?: AbortSignalLike;
-}
-
-/**
- * Options to configure the {@link ShareClient.getAccessPolicy} operation.
- *
- * @export
- * @interface ShareGetAccessPolicyOptions
- */
-export interface ShareGetAccessPolicyOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof ShareGetAccessPolicyOptions
- */
- abortSignal?: AbortSignalLike;
-}
-
-/**
- * Options to configure the {@link ShareClient.exists} operation.
- *
- * @export
- * @interface ShareExistsOptions
- */
-export interface ShareExistsOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof ShareExistsOptions
- */
- abortSignal?: AbortSignalLike;
-}
-
-/**
- * Options to configure the {@link ShareClient.getProperties} operation.
- *
- * @export
- * @interface ShareGetPropertiesOptions
- */
-export interface ShareGetPropertiesOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof ShareGetPropertiesOptions
- */
- abortSignal?: AbortSignalLike;
-}
-
-/**
- * Options to configure the {@link ShareClient.setQuota} operation.
- *
- * @export
- * @interface ShareSetQuotaOptions
- */
-export interface ShareSetQuotaOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof ShareSetQuotaOptions
- */
- abortSignal?: AbortSignalLike;
-}
-
-/**
- * Options to configure the {@link ShareClient.getStatistics} operation.
- *
- * @export
- * @interface ShareGetStatisticsOptions
- */
-export interface ShareGetStatisticsOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof ShareGetStatisticsOptions
- */
- abortSignal?: AbortSignalLike;
-}
-
-/**
- * Signed Identifier
- *
- * @export
- * @interface SignedIdentifier
- */
-export interface SignedIdentifier {
- /**
- * @member {string} id a unique id
- */
- id: string;
- /**
- * @member {AccessPolicy} accessPolicy
- */
- accessPolicy: {
- /**
- * @member {Date} startsOn the date-time the policy is active.
- */
- startsOn: Date;
- /**
- * @member {string} expiresOn the date-time the policy expires.
- */
- expiresOn: Date;
- /**
- * @member {string} permissions the permissions for the acl policy
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-share-acl
- */
- permissions: string;
- };
-}
-
-export declare type ShareGetAccessPolicyResponse = {
- signedIdentifiers: SignedIdentifier[];
-} & ShareGetAccessPolicyHeaders & {
- /**
- * The underlying HTTP response.
- */
- _response: HttpResponse & {
- /**
- * The parsed HTTP response headers.
- */
- parsedHeaders: ShareGetAccessPolicyHeaders;
- /**
- * The response body as text (string format)
- */
- bodyAsText: string;
- /**
- * The response body as parsed JSON or XML
- */
- parsedBody: SignedIdentifierModel[];
- };
- };
-
-/**
- * Options to configure the {@link ShareClient.createSnapshot} operation.
- *
- * @export
- * @interface ShareCreateSnapshotOptions
- */
-export interface ShareCreateSnapshotOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof ShareCreateSnapshotOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * A name-value pair to associate with a file storage object.
- *
- * @type {{ [propertyName: string]: string }}
- * @memberof ShareCreateOptions
- */
- metadata?: { [propertyName: string]: string };
-}
-
-/**
- * Options to configure the {@link ShareClient.createPermission} operation.
- *
- * @export
- * @interface ShareCreatePermissionOptions
- */
-export interface ShareCreatePermissionOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof ShareCreatePermissionOptions
- */
- abortSignal?: AbortSignalLike;
-}
-/**
- * Options to configure the {@link ShareClient.getPermission} operation.
- *
- * @export
- * @interface ShareGetPermissionOptions
- */
-export interface ShareGetPermissionOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof ShareGetPermissionOptions
- */
- abortSignal?: AbortSignalLike;
-}
-
-/**
- * Response data for the {@link ShareClient.getStatistics} Operation.
- *
- * @export
- * @interface ShareGetStatisticsResponse
- */
-export type ShareGetStatisticsResponse = ShareGetStatisticsResponseModel & {
- /**
- * @deprecated shareUsage is going to be deprecated. Please use ShareUsageBytes instead.
- *
- * The approximate size of the data stored on the share, rounded up to the nearest gigabyte. Note
- * that this value may not include all recently created or recently resized files.
- *
- * @type {number}
- * @memberof ShareGetStatisticsResponse
- */
- shareUsage: number;
-};
-
-/**
- * Contains response data for the {@link ShareClient.createIfNotExists} operation.
- *
- * @export
- * @interface ShareCreateIfNotExistsResponse
- */
-export interface ShareCreateIfNotExistsResponse extends ShareCreateResponse {
- /**
- * Indicate whether the share is successfully created. Is false when the share is not changed as it already exists.
- *
- * @type {boolean}
- * @memberof ShareCreateIfNotExistsResponse
- */
- succeeded: boolean;
-}
-
-/**
- * Contains response data for the {@link ShareClient.deleteIfExists} operation.
- *
- * @export
- * @interface ShareDeleteIfExistsResponse
- */
-export interface ShareDeleteIfExistsResponse extends ShareDeleteResponse {
- /**
- * Indicate whether the share is successfully deleted. Is false if the share does not exist in the first place.
- *
- * @type {boolean}
- * @memberof ShareDeleteIfExistsResponse
- */
- succeeded: boolean;
-}
-
-/**
- * A ShareClient represents a URL to the Azure Storage share allowing you to manipulate its directories and files.
- *
- * @export
- * @class ShareClient
- */
-export class ShareClient extends StorageClient {
- /**
- * Share operation context provided by protocol layer.
- *
- * @private
- * @type {Share}
- * @memberof ShareClient
- */
- private context: Share;
-
- private _name: string;
-
- /**
- * The name of the share
- *
- * @type {string}
- * @memberof ShareClient
- */
- public get name(): string {
- return this._name;
- }
-
- /**
- * @param {string} connectionString Account connection string or a SAS connection string of an Azure storage account.
- * [ Note - Account connection string can only be used in NODE.JS runtime. ]
- * Account connection string example -
- * `DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=accountKey;EndpointSuffix=core.windows.net`
- * SAS connection string example -
- * `BlobEndpoint=https://myaccount.blob.core.windows.net/;QueueEndpoint=https://myaccount.queue.core.windows.net/;FileEndpoint=https://myaccount.file.core.windows.net/;TableEndpoint=https://myaccount.table.core.windows.net/;SharedAccessSignature=sasString`
- * @param {string} name Share name.
- * @param {StoragePipelineOptions} [options] Optional. Options to configure the HTTP pipeline.
- * @memberof ShareClient
- */
- constructor(connectionString: string, name: string, options?: StoragePipelineOptions);
- /**
- * Creates an instance of ShareClient.
- *
- * @param {string} url A URL string pointing to Azure Storage file share, such as
- * "https://myaccount.file.core.windows.net/share". You can
- * append a SAS if using AnonymousCredential, such as
- * "https://myaccount.file.core.windows.net/share?sasString".
- * @param {Credential} [credential] Such as AnonymousCredential or StorageSharedKeyCredential.
- * If not specified, AnonymousCredential is used.
- * @param {StoragePipelineOptions} [options] Optional. Options to configure the HTTP pipeline.
- * @memberof ShareClient
- */
- constructor(url: string, credential?: Credential, options?: StoragePipelineOptions);
- /**
- * Creates an instance of ShareClient.
- *
- * @param {string} url A URL string pointing to Azure Storage file share, such as
- * "https://myaccount.file.core.windows.net/share". You can
- * append a SAS if using AnonymousCredential, such as
- * "https://myaccount.file.core.windows.net/share?sasString".
- * @param {Pipeline} pipeline Call newPipeline() to create a default
- * pipeline, or provide a customized pipeline.
- * @memberof ShareClient
- */
- constructor(url: string, pipeline: Pipeline);
- constructor(
- urlOrConnectionString: string,
- credentialOrPipelineOrShareName?: Credential | Pipeline | string,
- options?: StoragePipelineOptions
- ) {
- let pipeline: Pipeline;
- let url: string;
- if (credentialOrPipelineOrShareName instanceof Pipeline) {
- // (url: string, pipeline: Pipeline)
- url = urlOrConnectionString;
- pipeline = credentialOrPipelineOrShareName;
- } else if (credentialOrPipelineOrShareName instanceof Credential) {
- // (url: string, credential?: Credential, options?: StoragePipelineOptions)
- url = urlOrConnectionString;
- pipeline = newPipeline(credentialOrPipelineOrShareName, options);
- } else if (
- !credentialOrPipelineOrShareName &&
- typeof credentialOrPipelineOrShareName !== "string"
- ) {
- // (url: string, credential?: Credential, options?: StoragePipelineOptions)
- // The second parameter is undefined. Use anonymous credential.
- url = urlOrConnectionString;
- pipeline = newPipeline(new AnonymousCredential(), options);
- } else if (
- credentialOrPipelineOrShareName &&
- typeof credentialOrPipelineOrShareName === "string"
- ) {
- // (connectionString: string, name: string, options?: StoragePipelineOptions)
- const extractedCreds = extractConnectionStringParts(urlOrConnectionString);
- const name = credentialOrPipelineOrShareName;
- if (extractedCreds.kind === "AccountConnString") {
- if (isNode) {
- const sharedKeyCredential = new StorageSharedKeyCredential(
- extractedCreds.accountName!,
- extractedCreds.accountKey
- );
- url = appendToURLPath(extractedCreds.url, name);
- pipeline = newPipeline(sharedKeyCredential, options);
- } else {
- throw new Error("Account connection string is only supported in Node.js environment");
- }
- } else if (extractedCreds.kind === "SASConnString") {
- url = appendToURLPath(extractedCreds.url, name) + "?" + extractedCreds.accountSas;
- pipeline = newPipeline(new AnonymousCredential(), options);
- } else {
- throw new Error(
- "Connection string must be either an Account connection string or a SAS connection string"
- );
- }
- } else {
- throw new Error("Expecting non-empty strings for name parameter");
- }
- super(url, pipeline);
- this._name = getShareNameAndPathFromUrl(this.url).shareName;
- this.context = new Share(this.storageClientContext);
- }
-
- /**
- * Creates a new ShareClient object identical to the source but with the specified snapshot timestamp.
- * Provide "" will remove the snapshot and return a URL to the base share.
- *
- * @param {string} snapshot The snapshot timestamp.
- * @returns {ShareClient} A new ShareClient object identical to the source but with the specified snapshot timestamp
- * @memberof ShareClient
- */
- public withSnapshot(snapshot: string): ShareClient {
- return new ShareClient(
- setURLParameter(
- this.url,
- URLConstants.Parameters.SHARE_SNAPSHOT,
- snapshot.length === 0 ? undefined : snapshot
- ),
- this.pipeline
- );
- }
-
- /**
- * Creates a new share under the specified account. If the share with
- * the same name already exists, the operation fails.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-share
- *
- * @param {ShareCreateOptions} [options] Options to Share Create operation.
- * @returns {Promise} Response data for the Share Create operation.
- * @memberof ShareClient
- */
- public async create(options: ShareCreateOptions = {}): Promise {
- const { span, spanOptions } = createSpan("ShareClient-create", options.tracingOptions);
- try {
- return await this.context.create({
- ...options,
- spanOptions
- });
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Creates a new share under the specified account. If the share with
- * the same name already exists, it is not changed.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-share
- *
- * @param {ShareCreateOptions} [options]
- * @returns {Promise}
- * @memberof ShareClient
- */
- public async createIfNotExists(
- options: ShareCreateOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan(
- "ShareClient-createIfNotExists",
- options.tracingOptions
- );
- try {
- const res = await this.create({
- ...options,
- tracingOptions: { ...options!.tracingOptions, spanOptions }
- });
- return {
- succeeded: true,
- ...res
- };
- } catch (e) {
- if (e.details?.errorCode === "ShareAlreadyExists") {
- span.setStatus({
- code: CanonicalCode.ALREADY_EXISTS,
- message: "Expected exception when creating a share only if it doesn't already exist."
- });
- return {
- succeeded: false,
- ...e.response?.parsedHeaders,
- _response: e.response
- };
- }
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Creates a {@link ShareDirectoryClient} object.
- *
- * @param directoryName A directory name
- * @returns {ShareDirectoryClient} The ShareDirectoryClient object for the given directory name.
- * @memberof ShareClient
- */
- public getDirectoryClient(directoryName: string): ShareDirectoryClient {
- return new ShareDirectoryClient(
- appendToURLPath(this.url, encodeURIComponent(directoryName)),
- this.pipeline
- );
- }
-
- /**
- * Gets the directory client for the root directory of this share.
- * Note that the root directory always exists and cannot be deleted.
- *
- * @readonly
- * @type {ShareDirectoryClient} A new ShareDirectoryClient object for the root directory.
- * @memberof ShareClient
- */
- public get rootDirectoryClient(): ShareDirectoryClient {
- return this.getDirectoryClient("");
- }
-
- /**
- * Creates a new subdirectory under this share.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-directory
- *
- * @param {string} directoryName
- * @param {DirectoryCreateOptions} [options] Options to Directory Create operation.
- * @returns {Promise<{ directoryClient: ShareDirectoryClient, directoryCreateResponse: DirectoryCreateResponse }>} Directory creation response data and the corresponding directory client.
- * @memberof ShareClient
- */
- public async createDirectory(
- directoryName: string,
- options: DirectoryCreateOptions = {}
- ): Promise<{
- directoryClient: ShareDirectoryClient;
- directoryCreateResponse: DirectoryCreateResponse;
- }> {
- const { span, spanOptions } = createSpan("ShareClient-createDirectory", options.tracingOptions);
- try {
- const directoryClient = this.getDirectoryClient(directoryName);
- const directoryCreateResponse = await directoryClient.create({
- ...options,
- tracingOptions: { ...options.tracingOptions, spanOptions }
- });
- return {
- directoryClient,
- directoryCreateResponse
- };
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Removes the specified empty sub directory under this share.
- * Note that the directory must be empty before it can be deleted.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-directory
- *
- * @param {string} directoryName
- * @param {DirectoryDeleteOptions} [options] Options to Directory Delete operation.
- * @returns {Promise} Directory deletion response data.
- * @memberof ShareClient
- */
- public async deleteDirectory(
- directoryName: string,
- options: DirectoryDeleteOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan("ShareClient-deleteDirectory", options.tracingOptions);
- try {
- const directoryClient = this.getDirectoryClient(directoryName);
- return await directoryClient.delete({
- ...options,
- tracingOptions: { ...options.tracingOptions, spanOptions }
- });
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Creates a new file or replaces a file under the root directory of this share.
- * Note it only initializes the file with no content.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-file
- *
- * @param {string} fileName
- * @param {number} size Specifies the maximum size in bytes for the file, up to 1 TB.
- * @param {FileCreateOptions} [options] Options to File Create operation.
- * @returns {Promise<{ fileClient: ShareFileClient, fileCreateResponse: FileCreateResponse }>} File creation response data and the corresponding file client.
- * @memberof ShareClient
- */
- public async createFile(
- fileName: string,
- size: number,
- options: FileCreateOptions = {}
- ): Promise<{ fileClient: ShareFileClient; fileCreateResponse: FileCreateResponse }> {
- const { span, spanOptions } = createSpan("ShareClient-createFile", options.tracingOptions);
- try {
- const directoryClient = this.rootDirectoryClient;
- const fileClient = directoryClient.getFileClient(fileName);
- const fileCreateResponse = await fileClient.create(size, {
- ...options,
- tracingOptions: { ...options.tracingOptions, spanOptions }
- });
- return {
- fileClient,
- fileCreateResponse
- };
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Removes a file under the root directory of this share from the storage account.
- * When a file is successfully deleted, it is immediately removed from the storage
- * account's index and is no longer accessible to clients. The file's data is later
- * removed from the service during garbage collection.
- *
- * Delete File will fail with status code 409 (Conflict) and error code `SharingViolation`
- * if the file is open on an SMB client.
- *
- * Delete File is not supported on a share snapshot, which is a read-only copy of
- * a share. An attempt to perform this operation on a share snapshot will fail with 400
- * (`InvalidQueryParameterValue`)
- *
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-file2
- *
- * @param {string} directoryName
- * @param {string} fileName
- * @param {FileDeleteOptions} [options] Options to File Delete operation.
- * @returns Promise File Delete response data.
- * @memberof ShareClient
- */
- public async deleteFile(
- fileName: string,
- options: FileDeleteOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan("ShareClient-deleteFile", options.tracingOptions);
- try {
- const directoryClient = this.rootDirectoryClient;
- const fileClient = directoryClient.getFileClient(fileName);
- return await fileClient.delete({
- ...options,
- tracingOptions: { ...options.tracingOptions, spanOptions }
- });
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Returns true if the Azrue share resource represented by this client exists; false otherwise.
- *
- * NOTE: use this function with care since an existing share might be deleted by other clients or
- * applications. Vice versa new shares might be added by other clients or applications after this
- * function completes.
- *
- * @param {ShareExistsOptions} [options] options to Exists operation.
- * @returns {Promise}
- * @memberof ShareClient
- */
- public async exists(options: ShareExistsOptions = {}): Promise {
- const { span, spanOptions } = createSpan("ShareClient-exists", options.tracingOptions);
- try {
- await this.getProperties({
- abortSignal: options.abortSignal,
- tracingOptions: { ...options.tracingOptions, spanOptions }
- });
- return true;
- } catch (e) {
- if (e.statusCode === 404) {
- span.setStatus({
- code: CanonicalCode.NOT_FOUND,
- message: "Expected exception when checking share existence"
- });
- return false;
- }
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Returns all user-defined metadata and system properties for the specified
- * share.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-share-properties
- *
- * WARNING: The `metadata` object returned in the response will have its keys in lowercase, even if
- * they originally contained uppercase characters. This differs from the metadata keys returned by
- * the `listShares` method of {@link ShareServiceClient} using the `includeMetadata` option, which
- * will retain their original casing.
- *
- * @returns {Promise} Response data for the Share Get Properties operation.
- * @memberof ShareClient
- */
- public async getProperties(
- options: ShareGetPropertiesOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan("ShareClient-getProperties", options.tracingOptions);
- try {
- return await this.context.getProperties({
- abortSignal: options.abortSignal,
- spanOptions
- });
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Marks the specified share for deletion. The share and any directories or files
- * contained within it are later deleted during garbage collection.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-share
- *
- * @param {ShareDeleteMethodOptions} [options] Options to Share Delete operation.
- * @returns {Promise} Response data for the Share Delete operation.
- * @memberof ShareClient
- */
- public async delete(options: ShareDeleteMethodOptions = {}): Promise {
- const { span, spanOptions } = createSpan("ShareClient-delete", options.tracingOptions);
- try {
- return await this.context.deleteMethod({
- ...options,
- spanOptions
- });
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Marks the specified share for deletion if it exists. The share and any directories or files
- * contained within it are later deleted during garbage collection.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-share
- *
- * @param {ShareDeleteMethodOptions} [options]
- * @returns {Promise}
- * @memberof ShareClient
- */
- public async deleteIfExists(
- options: ShareDeleteMethodOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan("ShareClient-deleteIfExists", options.tracingOptions);
- try {
- const res = await this.delete({
- ...options,
- tracingOptions: { ...options!.tracingOptions, spanOptions }
- });
- return {
- succeeded: true,
- ...res
- };
- } catch (e) {
- if (e.details?.errorCode === "ShareNotFound") {
- span.setStatus({
- code: CanonicalCode.NOT_FOUND,
- message: "Expected exception when deleting a share only if it exists."
- });
- return {
- succeeded: false,
- ...e.response?.parsedHeaders,
- _response: e.response
- };
- }
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Sets one or more user-defined name-value pairs for the specified share.
- *
- * If no option provided, or no metadata defined in the option parameter, the share
- * metadata will be removed.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-share-metadata
- *
- * @param {Metadata} [metadata] If no metadata provided, all existing directory metadata will be removed.
- * @param {ShareSetMetadataOptions} [option] Options to Share Set Metadata operation.
- * @returns {Promise} Response data for the Share Set Metadata operation.
- * @memberof ShareClient
- */
- public async setMetadata(
- metadata?: Metadata,
- options: ShareSetMetadataOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan("ShareClient-setMetadata", options.tracingOptions);
- try {
- return await this.context.setMetadata({
- abortSignal: options.abortSignal,
- metadata,
- spanOptions
- });
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Gets the permissions for the specified share. The permissions indicate
- * whether share data may be accessed publicly.
- *
- * WARNING: JavaScript Date will potential lost precision when parsing start and expiry string.
- * For example, new Date("2018-12-31T03:44:23.8827891Z").toISOString() will get "2018-12-31T03:44:23.882Z".
- *
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-share-acl
- *
- * @param {ShareGetAccessPolicyOptions} [option] Options to Share Get Access Policy operation.
- * @returns {Promise} Response data for the Share Get Access Policy operation.
- * @memberof ShareClient
- */
- public async getAccessPolicy(
- options: ShareGetAccessPolicyOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan("ShareClient-getAccessPolicy", options.tracingOptions);
- try {
- const response = await this.context.getAccessPolicy({
- abortSignal: options.abortSignal,
- spanOptions
- });
-
- const res: ShareGetAccessPolicyResponse = {
- _response: response._response,
- date: response.date,
- etag: response.etag,
- lastModified: response.lastModified,
- requestId: response.requestId,
- signedIdentifiers: [],
- version: response.version
- };
-
- for (const identifier of response) {
- res.signedIdentifiers.push({
- accessPolicy: {
- expiresOn: new Date(identifier.accessPolicy!.expiresOn!),
- permissions: identifier.accessPolicy!.permissions!,
- startsOn: new Date(identifier.accessPolicy!.startsOn!)
- },
- id: identifier.id
- });
- }
-
- return res;
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Sets the permissions for the specified share. The permissions indicate
- * whether directories or files in a share may be accessed publicly.
- *
- * When you set permissions for a share, the existing permissions are replaced.
- * If no shareAcl provided, the existing share ACL will be
- * removed.
- *
- * When you establish a stored access policy on a share, it may take up to 30 seconds to take effect.
- * During this interval, a shared access signature that is associated with the stored access policy will
- * fail with status code 403 (Forbidden), until the access policy becomes active.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-share-acl
- *
- * @param {SignedIdentifier[]} [shareAcl] Array of signed identifiers, each having a unique Id and details of access policy.
- * @param {ShareSetAccessPolicyOptions} [option] Options to Share Set Access Policy operation.
- * @returns {Promise} Response data for the Share Set Access Policy operation.
- * @memberof ShareClient
- */
- public async setAccessPolicy(
- shareAcl?: SignedIdentifier[],
- options: ShareSetAccessPolicyOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan("ShareClient-setAccessPolicy", options.tracingOptions);
- try {
- const acl: SignedIdentifierModel[] = [];
- for (const identifier of shareAcl || []) {
- acl.push({
- accessPolicy: {
- expiresOn: truncatedISO8061Date(identifier.accessPolicy.expiresOn),
- permissions: identifier.accessPolicy.permissions,
- startsOn: truncatedISO8061Date(identifier.accessPolicy.startsOn)
- },
- id: identifier.id
- });
- }
-
- return await this.context.setAccessPolicy({
- abortSignal: options.abortSignal,
- shareAcl: acl,
- spanOptions
- });
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Creates a read-only snapshot of a share.
- *
- * @param {ShareCreateSnapshotOptions} [options={}] Options to Share Create Snapshot operation.
- * @returns {Promise} Response data for the Share Create Snapshot operation.
- * @memberof ShareClient
- */
- public async createSnapshot(
- options: ShareCreateSnapshotOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan("ShareClient-createSnapshot", options.tracingOptions);
- try {
- return await this.context.createSnapshot({
- abortSignal: options.abortSignal,
- ...options,
- spanOptions
- });
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Sets quota for the specified share.
- *
- * @param {number} quotaInGB Specifies the maximum size of the share in gigabytes
- * @param {ShareSetQuotaOptions} [option] Options to Share Set Quota operation.
- * @returns {Promise} Response data for the Share Get Quota operation.
- * @memberof ShareClient
- */
- public async setQuota(
- quotaInGB: number,
- options: ShareSetQuotaOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan("ShareClient-setQuota", options.tracingOptions);
- try {
- if (quotaInGB <= 0 || quotaInGB > 5120) {
- throw new RangeError(
- `Share quota must be greater than 0, and less than or equal to 5Tib (5120GB)`
- );
- }
- return await this.context.setQuota({
- abortSignal: options.abortSignal,
- quota: quotaInGB,
- spanOptions
- });
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Retrieves statistics related to the share.
- *
- * @param {ShareGetStatisticsOptions} [option] Options to Share Get Statistics operation.
- * @returns {Promise} Response data for the Share Get Statistics operation.
- * @memberof ShareClient
- */
- public async getStatistics(
- options: ShareGetStatisticsOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan("ShareClient-getStatistics", options.tracingOptions);
- try {
- const response = await this.context.getStatistics({
- abortSignal: options.abortSignal,
- spanOptions
- });
-
- const GBBytes = 1024 * 1024 * 1024;
- return { ...response, shareUsage: Math.ceil(response.shareUsageBytes / GBBytes) };
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Creates a file permission (a security descriptor) at the share level.
- * The created security descriptor can be used for the files/directories in the share.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-permission
- *
- * @param {ShareCreatePermissionOptions} [options] Options to Share Create Permission operation.
- * @param filePermission File permission described in the SDDL
- */
- public async createPermission(
- filePermission: string,
- options: ShareCreatePermissionOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan(
- "ShareClient-createPermission",
- options.tracingOptions
- );
- try {
- return await this.context.createPermission(
- {
- permission: filePermission
- },
- {
- abortSignal: options.abortSignal,
- spanOptions
- }
- );
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Gets the Security Descriptor Definition Language (SDDL) for a given file permission key
- * which indicates a security descriptor.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-permission
- *
- * @param {ShareGetPermissionOptions} [options] Options to Share Create Permission operation.
- * @param filePermissionKey File permission key which indicates the security descriptor of the permission.
- */
- public async getPermission(
- filePermissionKey: string,
- options: ShareGetPermissionOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan("ShareClient-getPermission", options.tracingOptions);
- try {
- return await this.context.getPermission(filePermissionKey, {
- aborterSignal: options.abortSignal,
- spanOptions
- });
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-}
diff --git a/sdk/storage/storage-file-share/src/ShareDirectoryClient.ts b/sdk/storage/storage-file-share/src/ShareDirectoryClient.ts
deleted file mode 100644
index ca018b60e0e3..000000000000
--- a/sdk/storage/storage-file-share/src/ShareDirectoryClient.ts
+++ /dev/null
@@ -1,1587 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-import { AbortSignalLike } from "@azure/abort-controller";
-import {
- DirectoryCreateResponse,
- DirectoryDeleteResponse,
- DirectoryGetPropertiesResponse,
- DirectoryItem,
- DirectoryListFilesAndDirectoriesSegmentResponse,
- DirectoryListHandlesResponse,
- DirectorySetMetadataResponse,
- DirectorySetPropertiesResponse,
- FileCreateResponse,
- FileDeleteResponse,
- FileItem,
- HandleItem,
- DirectoryForceCloseHandlesHeaders
-} from "./generatedModels";
-import { Directory } from "./generated/src/operations";
-import {
- Metadata,
- FileAndDirectoryCreateCommonOptions,
- FileAndDirectorySetPropertiesCommonOptions,
- validateAndSetDefaultsForFileAndDirectoryCreateCommonOptions,
- fileAttributesToString,
- fileCreationTimeToString,
- fileLastWriteTimeToString,
- validateAndSetDefaultsForFileAndDirectorySetPropertiesCommonOptions,
- CloseHandlesInfo
-} from "./models";
-import { newPipeline, StoragePipelineOptions, Pipeline } from "./Pipeline";
-import { appendToURLPath, getShareNameAndPathFromUrl } from "./utils/utils.common";
-import { StorageClient, CommonOptions } from "./StorageClient";
-import "@azure/core-paging";
-import { PageSettings, PagedAsyncIterableIterator } from "@azure/core-paging";
-import { ShareFileClient, FileCreateOptions, FileDeleteOptions } from "./ShareFileClient";
-import { Credential } from "./credentials/Credential";
-import { AnonymousCredential } from "./credentials/AnonymousCredential";
-import { FileSystemAttributes } from "./FileSystemAttributes";
-import { createSpan } from "./utils/tracing";
-import { CanonicalCode } from "@opentelemetry/api";
-import { HttpResponse } from "@azure/core-http";
-
-/**
- * Options to configure {@link ShareDirectoryClient.create} operation.
- *
- * @export
- * @interface DirectoryCreateOptions
- */
-export interface DirectoryCreateOptions extends FileAndDirectoryCreateCommonOptions, CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof DirectoryCreateOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * A collection of key-value string pair to associate with the file storage object.
- *
- * @type {Metadata}
- * @memberof DirectoryCreateOptions
- */
- metadata?: Metadata;
-}
-
-export interface DirectoryProperties
- extends FileAndDirectorySetPropertiesCommonOptions,
- CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof DirectoryProperties
- */
- abortSignal?: AbortSignalLike;
-}
-
-/**
- * Options to configure Directory - List Files and Directories Segment operations.
- *
- * See:
- * - {@link ShareDirectoryClient.iterateFilesAndDirectoriesSegments}
- * - {@link ShareDirectoryClient.listFilesAndDirectoriesItems}
- * - {@link ShareDirectoryClient.listFilesAndDirectoriesSegment}
- *
- * @interface DirectoryListFilesAndDirectoriesSegmentOptions
- */
-interface DirectoryListFilesAndDirectoriesSegmentOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof DirectoryListFilesAndDirectoriesSegmentOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * Filters the results to return only entries whose
- * name begins with the specified prefix.
- *
- * @type {string}
- * @memberof DirectoryListFilesAndDirectoriesSegmentOptions
- */
- prefix?: string;
-
- /**
- * Specifies the maximum number of entries to
- * return. If the request does not specify maxResults, or specifies a value
- * greater than 5,000, the server will return up to 5,000 items.
- *
- * @type {number}
- * @memberof DirectoryListFilesAndDirectoriesSegmentOptions
- */
- maxResults?: number;
-}
-
-/**
- * Options to configure {@link ShareDirectoryClient.listFilesAndDirectories} operation.
- *
- * @export
- * @interface DirectoryListFilesAndDirectoriesOptions
- */
-export interface DirectoryListFilesAndDirectoriesOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof DirectoryListFilesAndDirectoriesOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * Filters the results to return only entries whose
- * name begins with the specified prefix.
- *
- * @type {string}
- * @memberof DirectoryListFilesAndDirectoriesOptions
- */
- prefix?: string;
-}
-
-/**
- * Options to configure the {@link ShareDirectoryClient.delete} operation.
- *
- * @export
- * @interface DirectoryDeleteOptions
- */
-export interface DirectoryDeleteOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof DirectoryDeleteOptions
- */
- abortSignal?: AbortSignalLike;
-}
-
-/**
- * Options to configure the {@link ShareDirectoryClient.exists} operation.
- *
- * @export
- * @interface DirectoryExistsOptions
- */
-export interface DirectoryExistsOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof DirectoryExistsOptions
- */
- abortSignal?: AbortSignalLike;
-}
-
-/**
- * Options to configure the {@link ShareDirectoryClient.getProperties} operation.
- *
- * @export
- * @interface DirectoryGetPropertiesOptions
- */
-export interface DirectoryGetPropertiesOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof DirectoryGetPropertiesOptions
- */
- abortSignal?: AbortSignalLike;
-}
-
-/**
- * Options to configure the {@link ShareDirectoryClient.setMetadata} operation.
- *
- * @export
- * @interface DirectorySetMetadataOptions
- */
-export interface DirectorySetMetadataOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof DirectorySetMetadataOptions
- */
- abortSignal?: AbortSignalLike;
-}
-
-/**
- * Options to configure Directory - List Handles Segment operations.
- *
- * See:
- * - {@link ShareDirectoryClient.listHandlesSegment}
- * - {@link ShareDirectoryClient.iterateHandleSegments}
- * - {@link ShareDirectoryClient.listHandleItems}
- *
- *
- * @export
- * @interface DirectoryListHandlesSegmentOptions
- */
-export interface DirectoryListHandlesSegmentOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof DirectoryListHandlesSegmentOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * Specifies the maximum number of entries to return. If the request does not specify maxResults,
- * or specifies a value greater than 5,000, the server will return up to 5,000 items.
- *
- * @type {number}
- * @memberof DirectoryListHandlesSegmentOptions
- */
- maxResults?: number;
- /**
- * Specifies operation should apply to the directory specified in the URI, its files, its
- * subdirectories and their files.
- *
- * @type {boolean}
- * @memberof DirectoryListHandlesSegmentOptions
- */
- recursive?: boolean;
-}
-
-/**
- * Options to configure the {@link ShareDirectoryClient.listHandles} operation.
- *
- * @export
- * @interface DirectoryListHandlesOptions
- */
-export interface DirectoryListHandlesOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof DirectoryListHandlesOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * Specifies whether operation should apply to the directory specified in the URI, its files, its
- * subdirectories and their files.
- *
- * @type {boolean}
- * @memberof DirectoryListHandlesOptions
- */
- recursive?: boolean;
-}
-
-/**
- * Options to configure Directory - Force Close Handles Segment operations.
- *
- * See:
- * - {@link ShareDirectoryClient.forceCloseHandlesSegment}
- * - {@link ShareDirectoryClient.forceCloseAllHandles}
- *
- * @export
- * @interface DirectoryForceCloseHandlesSegmentOptions
- */
-export interface DirectoryForceCloseHandlesSegmentOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof DirectoryForceCloseHandlesSegmentOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * Specifies operation should apply to the directory specified in the URI, its files, its
- * subdirectories and their files.
- *
- * @type {boolean}
- * @memberof DirectoryForceCloseHandlesSegmentOptions
- */
- recursive?: boolean;
-}
-
-/**
- * Additional response header values for close handles request.
- */
-export interface DirectoryCloseHandlesHeaders {
- /**
- * This header uniquely identifies the request that was made and can be used for troubleshooting
- * the request.
- */
- requestId?: string;
- /**
- * Indicates the version of the File service used to execute the request.
- */
- version?: string;
- /**
- * A UTC date/time value generated by the service that indicates the time at which the response
- * was initiated.
- */
- date?: Date;
- /**
- * A string describing next handle to be closed. It is returned when more handles need to be
- * closed to complete the request.
- */
- marker?: string;
-}
-
-/**
- * Response type for {@link ShareDirectoryClient.forceCloseHandle}.
- */
-export type DirectoryForceCloseHandlesResponse = CloseHandlesInfo &
- DirectoryCloseHandlesHeaders & {
- /**
- * The underlying HTTP response.
- */
- _response: HttpResponse & {
- /**
- * The parsed HTTP response headers.
- */
- parsedHeaders: DirectoryForceCloseHandlesHeaders;
- };
- };
-
-/**
- * Options to configure {@link ShareDirectoryClient.forceCloseHandle}.
- *
- * @export
- * @interface DirectoryForceCloseHandlesOptions
- */
-export interface DirectoryForceCloseHandlesOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof DirectoryForceCloseHandlesOptions
- */
- abortSignal?: AbortSignalLike;
-}
-
-/**
- * Contains response data for the {@link DirectoryClient.createIfNotExists} operation.
- *
- * @export
- * @interface DirectoryCreateIfNotExistsResponse
- */
-export interface DirectoryCreateIfNotExistsResponse extends DirectoryCreateResponse {
- /**
- * Indicate whether the directory is successfully created. Is false when the directory is not changed as it already exists.
- *
- * @type {boolean}
- * @memberof DirectoryCreateIfNotExistsResponse
- */
- succeeded: boolean;
-}
-
-/**
- * Contains response data for the {@link DirectoryClient.deleteIfExists} operation.
- *
- * @export
- * @interface DirectoryDeleteIfExistsResponse
- */
-export interface DirectoryDeleteIfExistsResponse extends DirectoryDeleteResponse {
- /**
- * Indicate whether the directory is successfully deleted. Is false if the directory does not exist in the first place.
- *
- * @type {boolean}
- * @memberof DirectoryDeleteIfExistsResponse
- */
- succeeded: boolean;
-}
-
-/**
- * A ShareDirectoryClient represents a URL to the Azure Storage directory allowing you to manipulate its files and directories.
- *
- * @export
- * @class ShareDirectoryClient
- */
-export class ShareDirectoryClient extends StorageClient {
- /**
- * context provided by protocol layer.
- *
- * @private
- * @type {Directory}
- * @memberof ShareDirectoryClient
- */
- private context: Directory;
-
- private _shareName: string;
- private _path: string;
- private _name: string;
-
- /**
- * The share name corresponding to this directory client
- *
- * @type {string}
- * @memberof ShareDirectoryClient
- */
- public get shareName(): string {
- return this._shareName;
- }
-
- /**
- * The full path of the directory
- *
- * @type {string}
- * @memberof ShareDirectoryClient
- */
- public get path(): string {
- return this._path;
- }
-
- /**
- * The name of the directory
- *
- * @type {string}
- * @memberof ShareDirectoryClient
- */
- public get name(): string {
- return this._name;
- }
-
- /**
- * Creates an instance of DirectoryClient.
- *
- * @param {string} url A URL string pointing to Azure Storage file directory, such as
- * "https://myaccount.file.core.windows.net/myshare/mydirectory". You can
- * append a SAS if using AnonymousCredential, such as
- * "https://myaccount.file.core.windows.net/myshare/mydirectory?sasString".
- * This method accepts an encoded URL or non-encoded URL pointing to a directory.
- * Encoded URL string will NOT be escaped twice, only special characters in URL path will be escaped.
- * However, if a directory name includes %, directory name must be encoded in the URL.
- * Such as a directory named "mydir%", the URL should be "https://myaccount.file.core.windows.net/myshare/mydir%25".
- * @param {Credential} [credential] Such as AnonymousCredential or StorageSharedKeyCredential.
- * If not specified, AnonymousCredential is used.
- * @param {StoragePipelineOptions} [options] Optional. Options to configure the HTTP pipeline.
- * @memberof ShareDirectoryClient
- */
- constructor(url: string, credential?: Credential, options?: StoragePipelineOptions);
- /**
- * Creates an instance of DirectoryClient.
- *
- * @param {string} url A URL string pointing to Azure Storage file directory, such as
- * "https://myaccount.file.core.windows.net/myshare/mydirectory". You can
- * append a SAS if using AnonymousCredential, such as
- * "https://myaccount.file.core.windows.net/myshare/mydirectory?sasString".
- * This method accepts an encoded URL or non-encoded URL pointing to a directory.
- * Encoded URL string will NOT be escaped twice, only special characters in URL path will be escaped.
- * However, if a directory name includes %, directory name must be encoded in the URL.
- * Such as a directory named "mydir%", the URL should be "https://myaccount.file.core.windows.net/myshare/mydir%25".
- * @param {Pipeline} pipeline Call newPipeline() to create a default
- * pipeline, or provide a customized pipeline.
- * @memberof ShareDirectoryClient
- */
- constructor(url: string, pipeline: Pipeline);
- constructor(
- url: string,
- credentialOrPipeline?: Credential | Pipeline,
- options: StoragePipelineOptions = {}
- ) {
- let pipeline: Pipeline;
- if (credentialOrPipeline instanceof Pipeline) {
- pipeline = credentialOrPipeline;
- } else if (credentialOrPipeline instanceof Credential) {
- pipeline = newPipeline(credentialOrPipeline, options);
- } else {
- // The second parameter is undefined. Use anonymous credential.
- pipeline = newPipeline(new AnonymousCredential(), options);
- }
-
- super(url, pipeline);
- ({
- baseName: this._name,
- shareName: this._shareName,
- path: this._path
- } = getShareNameAndPathFromUrl(this.url));
- this.context = new Directory(this.storageClientContext);
- }
-
- /**
- * Creates a new directory under the specified share or parent directory.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-directory
- *
- * @param {DirectoryCreateOptions} [options] Options to Directory Create operation.
- * @returns {Promise} Response data for the Directory operation.
- * @memberof ShareDirectoryClient
- */
- public async create(options: DirectoryCreateOptions = {}): Promise {
- const { span, spanOptions } = createSpan("ShareDirectoryClient-create", options.tracingOptions);
- try {
- if (!options.fileAttributes) {
- options = validateAndSetDefaultsForFileAndDirectoryCreateCommonOptions(options);
- // By default set it as a directory.
- const attributes: FileSystemAttributes = new FileSystemAttributes();
- attributes.directory = true;
- options.fileAttributes = attributes;
- }
-
- return await this.context.create(
- fileAttributesToString(options.fileAttributes!),
- fileCreationTimeToString(options.creationTime!),
- fileLastWriteTimeToString(options.lastWriteTime!),
- {
- abortSignal: options.abortSignal,
- metadata: options.metadata,
- filePermission: options.filePermission,
- filePermissionKey: options.filePermissionKey,
- spanOptions
- }
- );
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Creates a new directory under the specified share or parent directory if it does not already exists.
- * If the directory already exists, it is not modified.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-directory
- *
- * @param {DirectoryCreateOptions} [options]
- * @returns {Promise}
- * @memberof ShareDirectoryClient
- */
- public async createIfNotExists(
- options: DirectoryCreateOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan(
- "ShareDirectoryClient-createIfNotExists",
- options.tracingOptions
- );
- try {
- const res = await this.create({
- ...options,
- tracingOptions: { ...options!.tracingOptions, spanOptions }
- });
- return {
- succeeded: true,
- ...res
- };
- } catch (e) {
- if (e.details?.errorCode === "ResourceAlreadyExists") {
- span.setStatus({
- code: CanonicalCode.ALREADY_EXISTS,
- message: "Expected exception when creating a directory only if it does not already exist."
- });
- return {
- succeeded: false,
- ...e.response?.parsedHeaders,
- _response: e.response
- };
- }
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Sets properties on the directory.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-directory-properties
- *
- * @param {properties} [DirectoryProperties] Directory properties. If no values are provided,
- * existing values will be preserved.
- * @returns {Promise}
- * @memberof ShareDirectoryClient
- */
- public async setProperties(
- properties: DirectoryProperties = {}
- ): Promise {
- const { span, spanOptions } = createSpan(
- "ShareDirectoryClient-setProperties",
- properties.tracingOptions
- );
- try {
- properties = validateAndSetDefaultsForFileAndDirectorySetPropertiesCommonOptions(properties);
-
- return await this.context.setProperties(
- fileAttributesToString(properties.fileAttributes!),
- fileCreationTimeToString(properties.creationTime!),
- fileLastWriteTimeToString(properties.lastWriteTime!),
- {
- abortSignal: properties.abortSignal,
- filePermission: properties.filePermission,
- filePermissionKey: properties.filePermissionKey,
- spanOptions
- }
- );
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Creates a ShareDirectoryClient object for a sub directory.
- *
- * @param subDirectoryName A subdirectory name
- * @returns {ShareDirectoryClient} The ShareDirectoryClient object for the given subdirectory name.
- * @memberof ShareDirectoryClient
- *
- * Example usage:
- *
- * ```js
- * const directoryClient = shareClient.getDirectoryClient("");
- * await directoryClient.create();
- * console.log("Created directory successfully");
- * ```
- */
- public getDirectoryClient(subDirectoryName: string): ShareDirectoryClient {
- return new ShareDirectoryClient(
- appendToURLPath(this.url, encodeURIComponent(subDirectoryName)),
- this.pipeline
- );
- }
-
- /**
- * Creates a new subdirectory under this directory.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-directory
- *
- * @param {string} directoryName
- * @param {DirectoryCreateOptions} [options] Options to Directory Create operation.
- * @returns {Promise<{ directoryClient: ShareDirectoryClient; directoryCreateResponse: DirectoryCreateResponse; }>} Directory create response data and the corresponding DirectoryClient instance.
- * @memberof ShareDirectoryClient
- */
- public async createSubdirectory(
- directoryName: string,
- options: DirectoryCreateOptions = {}
- ): Promise<{
- directoryClient: ShareDirectoryClient;
- directoryCreateResponse: DirectoryCreateResponse;
- }> {
- const { span, spanOptions } = createSpan(
- "ShareDirectoryClient-createSubdirectory",
- options.tracingOptions
- );
- try {
- const directoryClient = this.getDirectoryClient(directoryName);
- const directoryCreateResponse = await directoryClient.create({
- ...options,
- tracingOptions: { ...options!.tracingOptions, spanOptions }
- });
- return {
- directoryClient,
- directoryCreateResponse
- };
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Removes the specified empty sub directory under this directory.
- * Note that the directory must be empty before it can be deleted.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-directory
- *
- * @param {string} directoryName
- * @param {DirectoryDeleteOptions} [options] Options to Directory Delete operation.
- * @returns {DirectoryDeleteResponse} Directory deletion response data.
- * @memberof ShareDirectoryClient
- */
- public async deleteSubdirectory(
- directoryName: string,
- options: DirectoryDeleteOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan(
- "ShareDirectoryClient-deleteSubdirectory",
- options.tracingOptions
- );
- try {
- const directoryClient = this.getDirectoryClient(directoryName);
- return await directoryClient.delete({
- ...options,
- tracingOptions: { ...options!.tracingOptions, spanOptions }
- });
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Creates a new file or replaces a file under this directory. Note it only initializes the file with no content.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-file
- *
- * @param {string} fileName
- * @param {number} size Specifies the maximum size in bytes for the file, up to 1 TB.
- * @param {FileCreateOptions} [options] Options to File Create operation.
- * @returns {Promise<{ fileClient: ShareFileClient, fileCreateResponse: FileCreateResponse }>} File creation response data and the corresponding file client.
- * @memberof ShareDirectoryClient
- */
- public async createFile(
- fileName: string,
- size: number,
- options: FileCreateOptions = {}
- ): Promise<{ fileClient: ShareFileClient; fileCreateResponse: FileCreateResponse }> {
- const { span, spanOptions } = createSpan(
- "ShareDirectoryClient-createFile",
- options.tracingOptions
- );
- try {
- const fileClient = this.getFileClient(fileName);
- const fileCreateResponse = await fileClient.create(size, {
- ...options,
- tracingOptions: { ...options!.tracingOptions, spanOptions }
- });
- return {
- fileClient,
- fileCreateResponse
- };
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Removes the specified file under this directory from the storage account.
- * When a file is successfully deleted, it is immediately removed from the storage
- * account's index and is no longer accessible to clients. The file's data is later
- * removed from the service during garbage collection.
- *
- * Delete File will fail with status code 409 (Conflict) and error code SharingViolation
- * if the file is open on an SMB client.
- *
- * Delete File is not supported on a share snapshot, which is a read-only copy of
- * a share. An attempt to perform this operation on a share snapshot will fail with 400 (InvalidQueryParameterValue)
- *
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-file2
- *
- * @param {string} fileName Name of the file to delete
- * @param {FileDeleteOptions} [options] Options to File Delete operation.
- * @returns {Promise} File deletion response data.
- * @memberof ShareDirectoryClient
- */
- public async deleteFile(
- fileName: string,
- options: FileDeleteOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan(
- "ShareDirectoryClient-deleteFile",
- options.tracingOptions
- );
- try {
- const fileClient = this.getFileClient(fileName);
- return await fileClient.delete({
- ...options,
- tracingOptions: { ...options!.tracingOptions, spanOptions }
- });
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Creates a {@link ShareFileClient} object.
- *
- * @param {string} fileName A file name.
- * @returns {ShareFileClient} A new ShareFileClient object for the given file name.
- * @memberof ShareFileClient
- *
- * Example usage:
- *
- * ```js
- * const content = "Hello world!"
- *
- * const fileClient = directoryClient.getFileClient("");
- *
- * await fileClient.create(content.length);
- * console.log("Created file successfully!");
- *
- * await fileClient.uploadRange(content, 0, content.length);
- * console.log("Updated file successfully!")
- * ```
- */
- public getFileClient(fileName: string): ShareFileClient {
- return new ShareFileClient(
- appendToURLPath(this.url, encodeURIComponent(fileName)),
- this.pipeline
- );
- }
-
- /**
- * Returns true if the specified directory exists; false otherwise.
- *
- * NOTE: use this function with care since an existing directory might be deleted by other clients or
- * applications. Vice versa new directories might be added by other clients or applications after this
- * function completes.
- *
- * @param {DirectoryExistsOptions} [options] options to Exists operation.
- * @returns {Promise}
- * @memberof ShareDirectoryClient
- */
- public async exists(options: DirectoryExistsOptions = {}): Promise {
- const { span, spanOptions } = createSpan("ShareDirectoryClient-exists", options.tracingOptions);
- try {
- await this.getProperties({
- abortSignal: options.abortSignal,
- tracingOptions: {
- ...options.tracingOptions,
- spanOptions
- }
- });
- return true;
- } catch (e) {
- if (e.statusCode === 404) {
- span.setStatus({
- code: CanonicalCode.NOT_FOUND,
- message: "Expected exception when checking directory existence"
- });
- return false;
- }
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Returns all system properties for the specified directory, and can also be used to check the
- * existence of a directory. The data returned does not include the files in the directory or any
- * subdirectories.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-directory-properties
- *
- * @param {DirectoryGetPropertiesOptions} [options] Options to Directory Get Properties operation.
- * @returns {Promise} Response data for the Directory Get Properties operation.
- * @memberof ShareDirectoryClient
- */
- public async getProperties(
- options: DirectoryGetPropertiesOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan(
- "ShareDirectoryClient-getProperties",
- options.tracingOptions
- );
- try {
- return await this.context.getProperties({
- abortSignal: options.abortSignal,
- spanOptions
- });
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Removes the specified empty directory. Note that the directory must be empty before it can be
- * deleted.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-directory
- *
- * @param {DirectoryDeleteOptions} [options] Options to Directory Delete operation.
- * @returns {Promise} Response data for the Directory Delete operation.
- * @memberof ShareDirectoryClient
- */
- public async delete(options: DirectoryDeleteOptions = {}): Promise {
- const { span, spanOptions } = createSpan("ShareDirectoryClient-delete", options.tracingOptions);
- try {
- return await this.context.deleteMethod({
- abortSignal: options.abortSignal,
- spanOptions
- });
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Removes the specified empty directory if it exists. Note that the directory must be empty before it can be
- * deleted.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-directory
- *
- * @param {DirectoryDeleteOptions} [options]
- * @returns {Promise}
- * @memberof ShareDirectoryClient
- */
- public async deleteIfExists(
- options: DirectoryDeleteOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan(
- "ShareDirectoryClient-deleteIfExists",
- options.tracingOptions
- );
- try {
- const res = await this.delete({
- ...options,
- tracingOptions: { ...options!.tracingOptions, spanOptions }
- });
- return {
- succeeded: true,
- ...res
- };
- } catch (e) {
- if (e.details?.errorCode === "ResourceNotFound") {
- span.setStatus({
- code: CanonicalCode.NOT_FOUND,
- message: "Expected exception when deleting a directory only if it exists."
- });
- return {
- succeeded: false,
- ...e.response?.parsedHeaders,
- _response: e.response
- };
- }
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Updates user defined metadata for the specified directory.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-directory-metadata
- *
- * @param {Metadata} [metadata] If no metadata provided, all existing directory metadata will be removed
- * @param {DirectorySetMetadataOptions} [options] Options to Directory Set Metadata operation.
- * @returns {Promise} Response data for the Directory Set Metadata operation.
- * @memberof ShareDirectoryClient
- */
- public async setMetadata(
- metadata?: Metadata,
- options: DirectorySetMetadataOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan(
- "ShareDirectoryClient-setMetadata",
- options.tracingOptions
- );
- try {
- return await this.context.setMetadata({
- abortSignal: options.abortSignal,
- metadata,
- spanOptions
- });
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Returns an AsyncIterableIterator for {@link DirectoryListFilesAndDirectoriesSegmentResponse} objects
- *
- * @private
- * @param {string} [marker] A string value that identifies the portion of
- * the list of files and directories to be returned with the next listing operation. The
- * operation returns the ContinuationToken value within the response body if the
- * listing operation did not return all files and directories remaining to be listed
- * with the current page. The ContinuationToken value can be used as the value for
- * the marker parameter in a subsequent call to request the next page of list
- * items. The marker value is opaque to the client.
- * @param {DirectoryListFilesAndDirectoriesSegmentOptions} [options] Options to list files and directories operation.
- * @returns {AsyncIterableIterator}
- * @memberof ShareDirectoryClient
- */
- private async *iterateFilesAndDirectoriesSegments(
- marker?: string,
- options: DirectoryListFilesAndDirectoriesSegmentOptions = {}
- ): AsyncIterableIterator {
- if (options.prefix === "") {
- options.prefix = undefined;
- }
-
- let listFilesAndDirectoriesResponse;
- do {
- listFilesAndDirectoriesResponse = await this.listFilesAndDirectoriesSegment(marker, options);
- marker = listFilesAndDirectoriesResponse.continuationToken;
- yield await listFilesAndDirectoriesResponse;
- } while (marker);
- }
-
- /**
- * Returns an AsyncIterableIterator for file and directory items
- *
- * @private
- * @param {DirectoryListFilesAndDirectoriesSegmentOptions} [options] Options to list files and directories operation.
- * @returns {AsyncIterableIterator<{ kind: "file" } & FileItem | { kind: "directory" } & DirectoryItem>}
- * @memberof ShareDirectoryClient
- */
- private async *listFilesAndDirectoriesItems(
- options: DirectoryListFilesAndDirectoriesSegmentOptions = {}
- ): AsyncIterableIterator<
- ({ kind: "file" } & FileItem) | ({ kind: "directory" } & DirectoryItem)
- > {
- if (options.prefix === "") {
- options.prefix = undefined;
- }
-
- let marker: string | undefined;
- for await (const listFilesAndDirectoriesResponse of this.iterateFilesAndDirectoriesSegments(
- marker,
- options
- )) {
- for (const file of listFilesAndDirectoriesResponse.segment.fileItems) {
- yield { kind: "file", ...file };
- }
- for (const directory of listFilesAndDirectoriesResponse.segment.directoryItems) {
- yield { kind: "directory", ...directory };
- }
- }
- }
-
- /**
- * Returns an async iterable iterator to list all the files and directories
- * under the specified account.
- *
- * .byPage() returns an async iterable iterator to list the files and directories in pages.
- *
- * Example using `for await` syntax:
- *
- * ```js
- * let i = 1;
- * for await (const entity of directoryClient.listFilesAndDirectories()) {
- * if (entity.kind === "directory") {
- * console.log(`${i++} - directory\t: ${entity.name}`);
- * } else {
- * console.log(`${i++} - file\t: ${entity.name}`);
- * }
- * }
- * ```
- *
- * Example using `iter.next()`:
- *
- * ```js
- * let i = 1;
- * let iter = directoryClient.listFilesAndDirectories();
- * let entity = await iter.next();
- * while (!entity.done) {
- * if (entity.value.kind === "directory") {
- * console.log(`${i++} - directory\t: ${entity.value.name}`);
- * } else {
- * console.log(`${i++} - file\t: ${entity.value.name}`);
- * }
- * entity = await iter.next();
- * }
- * ```
- *
- * Example using `byPage()`:
- *
- * ```js
- * // passing optional maxPageSize in the page settings
- * let i = 1;
- * for await (const response of directoryClient
- * .listFilesAndDirectories()
- * .byPage({ maxPageSize: 20 })) {
- * for (const fileItem of response.segment.fileItems) {
- * console.log(`${i++} - file\t: ${fileItem.name}`);
- * }
- * for (const dirItem of response.segment.directoryItems) {
- * console.log(`${i++} - directory\t: ${dirItem.name}`);
- * }
- * }
- * ```
- *
- * Example using paging with a marker:
- *
- * ```js
- * let i = 1;
- * let iterator = directoryClient.listFilesAndDirectories().byPage({ maxPageSize: 3 });
- * let response = (await iterator.next()).value;
- *
- * // Prints 3 file and directory names
- * for (const fileItem of response.segment.fileItems) {
- * console.log(`${i++} - file\t: ${fileItem.name}`);
- * }
- *
- * for (const dirItem of response.segment.directoryItems) {
- * console.log(`${i++} - directory\t: ${dirItem.name}`);
- * }
- *
- * // Gets next marker
- * let dirMarker = response.continuationToken;
- *
- * // Passing next marker as continuationToken
- * iterator = directoryClient
- * .listFilesAndDirectories()
- * .byPage({ continuationToken: dirMarker, maxPageSize: 4 });
- * response = (await iterator.next()).value;
- *
- * // Prints 10 file and directory names
- * for (const fileItem of response.segment.fileItems) {
- * console.log(`${i++} - file\t: ${fileItem.name}`);
- * }
- *
- * for (const dirItem of response.segment.directoryItems) {
- * console.log(`${i++} - directory\t: ${dirItem.name}`);
- * }
- * ```
- *
- * @param {DirectoryListFilesAndDirectoriesOptions} [options] Options to list files and directories operation.
- * @memberof ShareDirectoryClient
- * @returns {PagedAsyncIterableIterator<{ kind: "file" } & FileItem | { kind: "directory" } , DirectoryListFilesAndDirectoriesSegmentResponse>}
- * An asyncIterableIterator that supports paging.
- */
- public listFilesAndDirectories(
- options: DirectoryListFilesAndDirectoriesOptions = {}
- ): PagedAsyncIterableIterator<
- ({ kind: "file" } & FileItem) | ({ kind: "directory" } & DirectoryItem),
- DirectoryListFilesAndDirectoriesSegmentResponse
- > {
- if (options.prefix === "") {
- options.prefix = undefined;
- }
-
- // AsyncIterableIterator to iterate over files and directories
- const iter = this.listFilesAndDirectoriesItems(options);
- return {
- /**
- * @member {Promise} [next] The next method, part of the iteration protocol
- */
- async next() {
- return iter.next();
- },
- /**
- * @member {Symbol} [asyncIterator] The connection to the async iterator, part of the iteration protocol
- */
- [Symbol.asyncIterator]() {
- return this;
- },
- /**
- * @member {Function} [byPage] Return an AsyncIterableIterator that works a page at a time
- */
- byPage: (settings: PageSettings = {}) => {
- return this.iterateFilesAndDirectoriesSegments(settings.continuationToken, {
- maxResults: settings.maxPageSize,
- ...options
- });
- }
- };
- }
-
- /**
- * Returns a list of files or directories under the specified share or directory. It lists the
- * contents only for a single level of the directory hierarchy.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/list-directories-and-files
- *
- * @param {string} [marker] A string value that identifies the portion of the list to be returned with the next list operation.
- * @param {DirectoryListFilesAndDirectoriesSegmentOptions} [options] Options to Directory List Files and Directories Segment operation.
- * @returns {Promise} Response data for the Directory List Files and Directories operation.
- * @memberof ShareDirectoryClient
- */
- private async listFilesAndDirectoriesSegment(
- marker?: string,
- options: DirectoryListFilesAndDirectoriesSegmentOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan(
- "ShareDirectoryClient-listFilesAndDirectoriesSegment",
- options.tracingOptions
- );
-
- if (options.prefix === "") {
- options.prefix = undefined;
- }
-
- try {
- return await this.context.listFilesAndDirectoriesSegment({
- marker,
- ...options,
- spanOptions
- });
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Returns an AsyncIterableIterator for {@link DirectoryListHandlesResponse}
- *
- * @private
- * @param {string} [marker] A string value that identifies the portion of the list to be
- * returned with the next list handles operation. The operation returns a
- * marker value within the response body if the list returned was not complete.
- * The marker value may then be used in a subsequent call to request the next
- * set of list items.
- * @param {DirectoryListHandlesSegmentOptions} [options] Options to list handles operation.
- * @returns {AsyncIterableIterator}
- * @memberof ShareDirectoryClient
- */
- private async *iterateHandleSegments(
- marker?: string,
- options: DirectoryListHandlesSegmentOptions = {}
- ): AsyncIterableIterator {
- let listHandlesResponse;
- if (!!marker || marker === undefined) {
- do {
- listHandlesResponse = await this.listHandlesSegment(marker, options);
- marker = listHandlesResponse.continuationToken;
- yield await listHandlesResponse;
- } while (marker);
- }
- }
-
- /**
- * Returns an AsyncIterableIterator for handles
- *
- * @private
- * @param {DirectoryListHandlesSegmentOptions} [options] Options to list handles operation.
- * @returns {AsyncIterableIterator}
- * @memberof ShareDirectoryClient
- */
- private async *listHandleItems(
- options: DirectoryListHandlesSegmentOptions = {}
- ): AsyncIterableIterator {
- let marker: string | undefined;
- for await (const listHandlesResponse of this.iterateHandleSegments(marker, options)) {
- if (listHandlesResponse.handleList) {
- for (const handle of listHandlesResponse.handleList) {
- yield handle;
- }
- }
- }
- }
-
- /**
- * Returns an async iterable iterator to list all the handles.
- * under the specified account.
- *
- * .byPage() returns an async iterable iterator to list the handles in pages.
- *
- * Example using `for await` syntax:
- *
- * ```js
- * let i = 1;
- * let iter = dirClient.listHandles();
- * for await (const handle of iter) {
- * console.log(`Handle ${i++}: ${handle.path}, opened time ${handle.openTime}, clientIp ${handle.clientIp}`);
- * }
- * ```
- *
- * Example using `iter.next()`:
- *
- * ```js
- * let i = 1;
- * let iter = dirClient.listHandles();
- * let handleItem = await iter.next();
- * while (!handleItem.done) {
- * console.log(`Handle ${i++}: ${handleItem.value.path}, opened time ${handleItem.value.openTime}, clientIp ${handleItem.value.clientIp}`);
- * handleItem = await iter.next();
- * }
- * ```
- *
- * Example using `byPage()`:
- *
- * ```js
- * // passing optional maxPageSize in the page settings
- * let i = 1;
- * for await (const response of dirClient.listHandles({ recursive: true }).byPage({ maxPageSize: 20 })) {
- * if (response.handleList) {
- * for (const handle of response.handleList) {
- * console.log(`Handle ${i++}: ${handle.path}, opened time ${handle.openTime}, clientIp ${handle.clientIp}`);
- * }
- * }
- * }
- * ```
- *
- * Example using paging with a marker:
- *
- * ```js
- * let i = 1;
- * let iterator = dirClient.listHandles().byPage({ maxPageSize: 2 });
- * let response = await iterator.next();
- *
- * // Prints 2 handles
- * if (response.value.handleList) {
- * for (const handle of response.value.handleList) {
- * console.log(`Handle ${i++}: ${handle.path}, opened time ${handle.openTime}, clientIp ${handle.clientIp}`);
- * }
- * }
- *
- * // Gets next marker
- * let marker = response.value.continuationToken;
- *
- * // Passing next marker as continuationToken
- * console.log(` continuation`);
- * iterator = dirClient.listHandles().byPage({ continuationToken: marker, maxPageSize: 10 });
- * response = await iterator.next();
- *
- * // Prints 2 more handles assuming you have more than four directory/files opened
- * if (!response.done && response.value.handleList) {
- * for (const handle of response.value.handleList) {
- * console.log(`Handle ${i++}: ${handle.path}, opened time ${handle.openTime}, clientIp ${handle.clientIp}`);
- * }
- * }
- * ```
- *
- * @param {DirectoryListHandlesOptions} [options] Options to list handles operation.
- * @memberof ShareDirectoryClient
- * @returns {PagedAsyncIterableIterator}
- * An asyncIterableIterator that supports paging.
- */
- public listHandles(
- options: DirectoryListHandlesOptions = {}
- ): PagedAsyncIterableIterator {
- // an AsyncIterableIterator to iterate over handles
- const iter = this.listHandleItems(options);
- return {
- /**
- * @member {Promise} [next] The next method, part of the iteration protocol
- */
- async next() {
- return iter.next();
- },
- /**
- * @member {Symbol} [asyncIterator] The connection to the async iterator, part of the iteration protocol
- */
- [Symbol.asyncIterator]() {
- return this;
- },
- /**
- * @member {Function} [byPage] Return an AsyncIterableIterator that works a page at a time
- */
- byPage: (settings: PageSettings = {}) => {
- return this.iterateHandleSegments(settings.continuationToken, {
- maxResults: settings.maxPageSize,
- ...options
- });
- }
- };
- }
-
- /**
- * Lists handles for a directory.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/list-handles
- *
- * @param {string} [marker] Optional. A string value that identifies the portion of the list to be
- * returned with the next list handles operation. The operation returns a
- * marker value within the response body if the list returned was not complete.
- * The marker value may then be used in a subsequent call to request the next
- * set of list items.
- * @param {DirectoryListHandlesSegmentOptions} [options={}]
- * @returns {Promise}
- * @memberof ShareDirectoryClient
- */
- private async listHandlesSegment(
- marker?: string,
- options: DirectoryListHandlesSegmentOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan(
- "ShareDirectoryClient-listHandlesSegment",
- options.tracingOptions
- );
- try {
- marker = marker === "" ? undefined : marker;
- const response = await this.context.listHandles({
- marker,
- ...options,
- spanOptions
- });
-
- // TODO: Protocol layer issue that when handle list is in returned XML
- // response.handleList is an empty string
- if ((response.handleList as any) === "") {
- response.handleList = undefined;
- }
- return response;
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Force close all handles for a directory.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/force-close-handles
- *
- * @param {string} [marker] Optional. A string value that identifies the position of handles that will
- * be closed with the next force close handles operation.
- * The operation returns a marker value within the response
- * body if there are more handles to close. The marker value
- * may then be used in a subsequent call to close the next set of handles.
- * @param {DirectoryForceCloseHandlesSegmentOptions} [options={}]
- * @returns {Promise}
- * @memberof ShareDirectoryClient
- */
- private async forceCloseHandlesSegment(
- marker?: string,
- options: DirectoryForceCloseHandlesSegmentOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan(
- "ShareDirectoryClient-forceCloseHandlesSegment",
- options.tracingOptions
- );
- try {
- marker = marker === "" ? undefined : marker;
- const rawResponse = await this.context.forceCloseHandles("*", {
- marker,
- ...options,
- spanOptions
- });
- const response = rawResponse as DirectoryForceCloseHandlesResponse;
- response.closedHandlesCount = rawResponse.numberOfHandlesClosed || 0;
- response.closeFailureCount = rawResponse.numberOfHandlesFailedToClose || 0;
- return response;
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Force close all handles for a directory.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/force-close-handles
- *
- * @param {DirectoryForceCloseHandlesSegmentOptions} [options={}]
- * @returns {Promise}
- * @memberof ShareDirectoryClient
- */
- public async forceCloseAllHandles(
- options: DirectoryForceCloseHandlesSegmentOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan(
- "ShareDirectoryClient-forceCloseAllHandles",
- options.tracingOptions
- );
- try {
- let handlesClosed = 0;
- let numberOfHandlesFailedToClose = 0;
- let marker: string | undefined = "";
-
- do {
- const response: DirectoryForceCloseHandlesResponse = await this.forceCloseHandlesSegment(
- marker,
- { ...options, tracingOptions: { ...options!.tracingOptions, spanOptions } }
- );
- marker = response.marker;
- response.closedHandlesCount && (handlesClosed += response.closedHandlesCount);
- response.closeFailureCount && (numberOfHandlesFailedToClose += response.closeFailureCount);
- } while (marker);
-
- return { closedHandlesCount: handlesClosed, closeFailureCount: numberOfHandlesFailedToClose };
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Force close a specific handle for a directory.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/force-close-handles
- *
- * @param {Aborter} aborter Create a new Aborter instance with Aborter.none or Aborter.timeout(),
- * goto documents of Aborter for more examples about request cancellation
- * @param {string} handleId Specific handle ID, cannot be asterisk "*".
- * Use forceCloseHandlesSegment() to close all handles.
- * @param {DirectoryForceCloseHandlesOptions} [options={}]
- * @returns {Promise}
- * @memberof ShareDirectoryClient
- */
- public async forceCloseHandle(
- handleId: string,
- options: DirectoryForceCloseHandlesOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan(
- "ShareDirectoryClient-forceCloseHandle",
- options.tracingOptions
- );
- try {
- if (handleId === "*") {
- throw new RangeError(
- `Parameter handleID should be a specified handle ID. Use forceCloseHandlesSegment() to close all handles.`
- );
- }
-
- const rawResponse = await this.context.forceCloseHandles(handleId, {
- abortSignal: options.abortSignal,
- spanOptions
- });
- const response = rawResponse as DirectoryForceCloseHandlesResponse;
- response.closedHandlesCount = rawResponse.numberOfHandlesClosed || 0;
- response.closeFailureCount = rawResponse.numberOfHandlesFailedToClose || 0;
- return response;
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-}
diff --git a/sdk/storage/storage-file-share/src/ShareFileClient.ts b/sdk/storage/storage-file-share/src/ShareFileClient.ts
deleted file mode 100644
index 86d55c274c0b..000000000000
--- a/sdk/storage/storage-file-share/src/ShareFileClient.ts
+++ /dev/null
@@ -1,3045 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-import { HttpRequestBody, HttpResponse, isNode, TransferProgressEvent } from "@azure/core-http";
-import { CanonicalCode } from "@opentelemetry/api";
-import { AbortSignalLike } from "@azure/abort-controller";
-import { FileDownloadResponse } from "./FileDownloadResponse";
-import {
- FileAbortCopyResponse,
- FileCreateResponse,
- FileDeleteResponse,
- FileDownloadOptionalParams,
- FileDownloadResponseModel,
- FileGetPropertiesResponse,
- FileGetRangeListHeaders,
- FileListHandlesResponse,
- FileSetHTTPHeadersResponse,
- FileSetMetadataResponse,
- FileStartCopyResponse,
- SourceModifiedAccessConditions,
- FileUploadRangeFromURLResponse,
- FileUploadRangeResponse,
- HandleItem,
- RangeModel,
- FileForceCloseHandlesHeaders,
- CopyFileSmbInfo,
- LeaseAccessConditions
-} from "./generatedModels";
-import { File } from "./generated/src/operations";
-import { Range, rangeToString } from "./Range";
-import {
- FileHttpHeaders,
- Metadata,
- FileAndDirectoryCreateCommonOptions,
- FileAndDirectorySetPropertiesCommonOptions,
- fileAttributesToString,
- fileCreationTimeToString,
- fileLastWriteTimeToString,
- validateAndSetDefaultsForFileAndDirectoryCreateCommonOptions,
- validateAndSetDefaultsForFileAndDirectorySetPropertiesCommonOptions,
- CloseHandlesInfo
-} from "./models";
-import { newPipeline, StoragePipelineOptions, Pipeline } from "./Pipeline";
-import { StorageClient, CommonOptions } from "./StorageClient";
-import {
- DEFAULT_MAX_DOWNLOAD_RETRY_REQUESTS,
- FILE_MAX_SIZE_BYTES,
- FILE_RANGE_MAX_SIZE_BYTES,
- DEFAULT_HIGH_LEVEL_CONCURRENCY
-} from "./utils/constants";
-import "@azure/core-paging";
-import { PageSettings, PagedAsyncIterableIterator } from "@azure/core-paging";
-import { Credential } from "./credentials/Credential";
-import { Batch } from "./utils/Batch";
-import { BufferScheduler } from "./utils/BufferScheduler";
-import { Readable } from "stream";
-import { AnonymousCredential } from "./credentials/AnonymousCredential";
-import {
- readStreamToLocalFile,
- streamToBuffer,
- fsStat,
- fsCreateReadStream
-} from "./utils/utils.node";
-import { FileSystemAttributes } from "./FileSystemAttributes";
-import { getShareNameAndPathFromUrl } from "./utils/utils.common";
-import { createSpan } from "./utils/tracing";
-import { StorageClientContext } from "./generated/src/storageClientContext";
-import { SERVICE_VERSION } from "./utils/constants";
-import { generateUuid } from "@azure/core-http";
-
-/**
- * Options to configure the {@link ShareFileClient.create} operation.
- *
- * @export
- * @interface FileCreateOptions
- */
-export interface FileCreateOptions extends FileAndDirectoryCreateCommonOptions, CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof FileCreateOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * File HTTP headers like Content-Type.
- *
- * @type {FileHttpHeaders}
- * @memberof FileCreateOptions
- */
- fileHttpHeaders?: FileHttpHeaders;
-
- /**
- * A collection of key-value string pair to associate with the file storage object.
- *
- * @type {Metadata}
- * @memberof FileCreateOptions
- */
- metadata?: Metadata;
- /**
- * Lease access conditions.
- *
- * @type {LeaseAccessConditions}
- * @memberof FileCreateOptions
- */
- leaseAccessConditions?: LeaseAccessConditions;
-}
-
-export interface FileProperties extends FileAndDirectorySetPropertiesCommonOptions, CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof FileProperties
- */
- abortSignal?: AbortSignalLike;
- /**
- * File HTTP headers like Content-Type.
- *
- * @type {FileHttpHeaders}
- * @memberof FileProperties
- */
- fileHttpHeaders?: FileHttpHeaders;
- /**
- * Lease access conditions.
- *
- * @type {LeaseAccessConditions}
- * @memberof FileProperties
- */
- leaseAccessConditions?: LeaseAccessConditions;
-}
-
-export interface SetPropertiesResponse extends FileSetHTTPHeadersResponse {}
-
-/**
- * Options to configure the {@link ShareFileClient.delete} operation.
- *
- * @export
- * @interface FileDeleteOptions
- */
-export interface FileDeleteOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof FileDeleteOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * Lease access conditions.
- *
- * @type {LeaseAccessConditions}
- * @memberof FileDeleteOptions
- */
- leaseAccessConditions?: LeaseAccessConditions;
-}
-
-/**
- * Options to configure File - Download operations.
- *
- * See:
- * - {@link ShareFileClient.download}
- * - {@link ShareFileClient.downloadToFile}
- *
- * @export
- * @interface FileDownloadOptions
- */
-export interface FileDownloadOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof FileDownloadOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * Optional. ONLY AVAILABLE IN NODE.JS.
- *
- * How many retries will perform when original body download stream unexpected ends.
- * Above kind of ends will not trigger retry policy defined in a pipeline,
- * because they doesn't emit network errors.
- *
- * With this option, every additional retry means an additional ShareFileClient.download() request will be made
- * from the broken point, until the requested range has been successfully downloaded or maxRetryRequests is reached.
- *
- * Default value is 5, please set a larger value when loading large files in poor network.
- *
- * @type {number}
- * @memberof FileDownloadOptions
- */
- maxRetryRequests?: number;
-
- /**
- * When this header is set to true and
- * specified together with the Range header, the service returns the MD5 hash
- * for the range, as long as the range is less than or equal to 4 MB in size.
- *
- * @type {boolean}
- * @memberof FileDownloadOptions
- */
- rangeGetContentMD5?: boolean;
-
- /**
- * Download progress updating event handler.
- *
- * @memberof FileDownloadOptions
- */
- onProgress?: (progress: TransferProgressEvent) => void;
- /**
- * Lease access conditions.
- *
- * @type {LeaseAccessConditions}
- * @memberof FileDownloadOptions
- */
- leaseAccessConditions?: LeaseAccessConditions;
-}
-
-/**
- * Options to configure the {@link ShareFileClient.uploadRange} operation.
- *
- * @export
- * @interface FileUploadRangeOptions
- */
-export interface FileUploadRangeOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof FileUploadRangeOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * An MD5 hash of the content. This hash is
- * used to verify the integrity of the data during transport. When the
- * Content-MD5 header is specified, the File service compares the hash of the
- * content that has arrived with the header value that was sent. If the two
- * hashes do not match, the operation will fail with error code 400 (Bad
- * Request).
- *
- * @type {Uint8Array}
- * @memberof FileUploadRangeOptions
- */
- contentMD5?: Uint8Array;
-
- /**
- * Progress updating event handler.
- *
- * @memberof FileUploadRangeOptions
- */
- onProgress?: (progress: TransferProgressEvent) => void;
- /**
- * Lease access conditions.
- *
- * @type {LeaseAccessConditions}
- * @memberof FileUploadRangeOptions
- */
- leaseAccessConditions?: LeaseAccessConditions;
-}
-
-/**
- * Options to configure the {@link ShareFileClient.uploadRangeFromURL} operation.
- *
- * @export
- * @interface FileUploadRangeFromURLOptions
- */
-export interface FileUploadRangeFromURLOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof FileUploadRangeFromURLOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * The timeout parameter is expressed in seconds. For more information, see Setting
- * Timeouts for File Service Operations.
- */
- timeoutInSeconds?: number;
- /**
- * Specify the crc64 calculated for the range of bytes that must be read from the copy source.
- */
- sourceContentCrc64?: Uint8Array;
- /**
- * Additional parameters for the operation
- */
- sourceConditions?: SourceModifiedAccessConditions;
- /**
- * Lease access conditions.
- *
- * @type {LeaseAccessConditions}
- * @memberof FileUploadRangeFromURLOptions
- */
- leaseAccessConditions?: LeaseAccessConditions;
-}
-
-/**
- * The option is defined as parity to REST definition.
- * While it's not ready to be used now, considering Crc64 of source content is
- * not accessible.
- */
-// export interface IFileUploadRangeFromURLOptions extends CommonOptions {
-// /**
-// * Crc64 of the source content.
-// *
-// * @type {Uint8Array}
-// * @memberof IFileUploadRangeFromURLOptions
-// */
-// sourceContentCrc64?: Uint8Array;
-
-// /**
-// * Source modified access condition.
-// *
-// * @type {SourceModifiedAccessConditions}
-// * @memberof IFileUploadRangeFromURLOptions
-// */
-// sourceModifiedAccessConditions?: SourceModifiedAccessConditions;
-// }
-
-/**
- * Options to configure the {@link ShareFileClient.getRangeList} operation.
- *
- * @export
- * @interface FileGetRangeListOptions
- */
-export interface FileGetRangeListOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof FileGetRangeListOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * Optional. Specifies the range of bytes over which to list ranges, inclusively.
- *
- * @type {Range}
- * @memberof FileGetRangeListOptions
- */
- range?: Range;
- /**
- * Lease access conditions.
- *
- * @type {LeaseAccessConditions}
- * @memberof FileGetRangeListOptions
- */
- leaseAccessConditions?: LeaseAccessConditions;
-}
-
-/**
- * Options to configure the {@link ShareFileClient.exists} operation.
- *
- * @export
- * @interface FileExistsOptions
- */
-export interface FileExistsOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof FileExistsOptions
- */
- abortSignal?: AbortSignalLike;
-}
-
-/**
- * Options to configure the {@link ShareFileClient.getProperties} operation.
- *
- * @export
- * @interface FileGetPropertiesOptions
- */
-export interface FileGetPropertiesOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof FileGetPropertiesOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * Lease access conditions.
- *
- * @type {LeaseAccessConditions}
- * @memberof FileGetPropertiesOptions
- */
- leaseAccessConditions?: LeaseAccessConditions;
-}
-
-/**
- * Contains response data for the {@link ShareFileClient.getRangeList} operation.
- */
-export type FileGetRangeListResponse = FileGetRangeListHeaders & {
- /**
- * Range list for an Azure file.
- *
- * @type {RangeModel[]}
- */
- rangeList: RangeModel[];
-
- /**
- * The underlying HTTP response.
- */
- _response: HttpResponse & {
- /**
- * The parsed HTTP response headers.
- */
- parsedHeaders: FileGetRangeListHeaders;
- /**
- * The response body as text (string format)
- */
- bodyAsText: string;
- /**
- * The response body as parsed JSON or XML
- */
- parsedBody: RangeModel[];
- };
-};
-
-/**
- * Options to configure the {@link ShareFileClient.startCopyFromURL} operation.
- *
- * @export
- * @interface FileStartCopyOptions
- */
-export interface FileStartCopyOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof FileStartCopyOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * A collection of key-value string pair to associate with the file storage object.
- *
- * @type {Metadata}
- * @memberof FileStartCopyOptions
- */
- metadata?: Metadata;
- /**
- * Lease access conditions.
- *
- * @type {LeaseAccessConditions}
- * @memberof FileStartCopyOptions
- */
- leaseAccessConditions?: LeaseAccessConditions;
- /**
- * If specified the permission (security descriptor) shall be set for the directory/file. This
- * header can be used if Permission size is <= 8KB, else x-ms-file-permission-key header shall be
- * used. Default value: Inherit. If SDDL is specified as input, it must have owner, group and
- * dacl. Note: Only one of the x-ms-file-permission or x-ms-file-permission-key should be
- * specified.
- *
- * @type {string}
- * @memberof FileStartCopyOptions
- */
- filePermission?: string;
- /**
- * Key of the permission to be set for the directory/file. Note: Only one of the
- * x-ms-file-permission or x-ms-file-permission-key should be specified.
- *
- * @type {string}
- * @memberof FileStartCopyOptions
- */
- filePermissionKey?: string;
- /**
- * SMB info.
- *
- * @type {CopyFileSmbInfo}
- * @memberof FileStartCopyOptions
- */
- copyFileSmbInfo?: CopyFileSmbInfo;
-}
-
-/**
- * Options to configure the {@link ShareFileClient.setMetadata} operation.
- *
- * @export
- * @interface FileSetMetadataOptions
- */
-export interface FileSetMetadataOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof FileSetMetadataOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * Lease access conditions.
- *
- * @type {LeaseAccessConditions}
- * @memberof FileSetMetadataOptions
- */
- leaseAccessConditions?: LeaseAccessConditions;
-}
-
-/**
- * Options to configure the {@link ShareFileClient.setHttpHeaders} operation.
- *
- * @export
- * @interface FileSetHttpHeadersOptions
- */
-export interface FileSetHttpHeadersOptions
- extends FileAndDirectorySetPropertiesCommonOptions,
- CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof FileSetHttpHeadersOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * Lease access conditions.
- *
- * @type {LeaseAccessConditions}
- * @memberof FileSetHttpHeadersOptions
- */
- leaseAccessConditions?: LeaseAccessConditions;
-}
-
-/**
- * Options to configure the {@link ShareFileClient.abortCopyFromURL} operation.
- *
- * @export
- * @interface FileAbortCopyFromURLOptions
- */
-export interface FileAbortCopyFromURLOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof FileAbortCopyFromURLOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * Lease access conditions.
- *
- * @type {LeaseAccessConditions}
- * @memberof FileAbortCopyFromURLOptions
- */
- leaseAccessConditions?: LeaseAccessConditions;
-}
-
-/**
- * Options to configure the {@link ShareFileClient.resize} operation.
- *
- * @export
- * @interface FileResizeOptions
- */
-export interface FileResizeOptions
- extends FileAndDirectorySetPropertiesCommonOptions,
- CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof FileResizeOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * Lease access conditions.
- *
- * @type {LeaseAccessConditions}
- * @memberof FileResizeOptions
- */
- leaseAccessConditions?: LeaseAccessConditions;
-}
-
-/**
- * Options to configure the {@link ShareFileClient.clearRange} operation.
- *
- * @export
- * @interface FileClearRangeOptions
- */
-export interface FileClearRangeOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof FileClearRangeOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * Lease access conditions.
- *
- * @type {LeaseAccessConditions}
- * @memberof FileClearRangeOptions
- */
- leaseAccessConditions?: LeaseAccessConditions;
-}
-
-/**
- * Options to configure File - List Handles Segment operations.
- *
- * See:
- * - {@link ShareFileClient.listHandlesSegment}
- * - {@link ShareFileClient.iterateHandleSegments}
- * - {@link ShareFileClient.listHandleItems}
- *
- * @export
- * @interface FileListHandlesSegmentOptions
- */
-export interface FileListHandlesSegmentOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof FileClearRangeOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * Specifies the maximum number of entries to return. If the request does not specify maxResults,
- * or specifies a value greater than 5,000, the server will return up to 5,000 items.
- *
- * @type {number}
- * @memberof FileListHandlesSegmentOptions
- */
- maxPageSize?: number;
-}
-
-export interface FileListHandlesOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof FileClearRangeOptions
- */
- abortSignal?: AbortSignalLike;
-}
-
-/**
- * Options to configure File - Force Close Handles operations.
- *
- * See:
- * - {@link ShareFileClient.forceCloseHandlesSegment}
- * - {@link ShareFileClient.forceCloseAllHandles}
- * - {@link ShareFileClient.forceCloseHandle}
- *
- * @export
- * @interface FileForceCloseHandlesOptions
- */
-export interface FileForceCloseHandlesOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof FileForceCloseHandlesOptions
- */
- abortSignal?: AbortSignalLike;
-}
-
-/**
- * Additional response header values for close handles request.
- */
-export interface FileCloseHandlesHeaders {
- /**
- * This header uniquely identifies the request that was made and can be used for troubleshooting
- * the request.
- */
- requestId?: string;
- /**
- * Indicates the version of the File service used to execute the request.
- */
- version?: string;
- /**
- * A UTC date/time value generated by the service that indicates the time at which the response
- * was initiated.
- */
- date?: Date;
- /**
- * A string describing next handle to be closed. It is returned when more handles need to be
- * closed to complete the request.
- */
- marker?: string;
-}
-
-/**
- * Response type for {@link ShareFileClient.forceCloseHandle}.
- */
-export type FileForceCloseHandlesResponse = CloseHandlesInfo &
- FileCloseHandlesHeaders & {
- /**
- * The underlying HTTP response.
- */
- _response: HttpResponse & {
- /**
- * The parsed HTTP response headers.
- */
- parsedHeaders: FileForceCloseHandlesHeaders;
- };
- };
-
-/**
- * Option interface for ShareFileClient.uploadStream().
- *
- * @export
- * @interface FileUploadStreamOptions
- */
-export interface FileUploadStreamOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof FileUploadStreamOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * Azure File HTTP Headers.
- *
- * @type {FileHttpHeaders}
- * @memberof FileUploadStreamOptions
- */
- fileHttpHeaders?: FileHttpHeaders;
-
- /**
- * Metadata of the Azure file.
- *
- * @type {Metadata}
- * @memberof FileUploadStreamOptions
- */
- metadata?: Metadata;
-
- /**
- * Progress updater.
- *
- * @memberof FileUploadStreamOptions
- */
- onProgress?: (progress: TransferProgressEvent) => void;
- /**
- * Lease access conditions.
- *
- * @type {LeaseAccessConditions}
- * @memberof FileUploadStreamOptions
- */
- leaseAccessConditions?: LeaseAccessConditions;
-}
-
-/**
- * Option interface for File - Upload operations
- *
- * See:
- * - {@link ShareFileClient.uploadFile}
- * - {@link ShareFileClient.uploadSeekableStream}
- *
- * @export
- * @interface FileParallelUploadOptions
- */
-export interface FileParallelUploadOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof FileParallelUploadOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * RangeSize specifies the range size to use in each parallel upload,
- * the default (and maximum size) is FILE_RANGE_MAX_SIZE_BYTES.
- *
- * @type {number}
- * @memberof FileParallelUploadOptions
- */
- rangeSize?: number;
-
- /**
- * Progress updater.
- *
- * @memberof FileParallelUploadOptions
- */
- onProgress?: (progress: TransferProgressEvent) => void;
-
- /**
- * File HTTP Headers.
- *
- * @type {FileHttpHeaders}
- * @memberof FileParallelUploadOptions
- */
- fileHttpHeaders?: FileHttpHeaders;
-
- /**
- * Metadata of an Azure file.
- *
- * @type {Metadata}
- * @memberof FileParallelUploadOptions
- */
- metadata?: Metadata;
-
- /**
- * Concurrency indicates the maximum number of ranges to upload in parallel.
- * If not provided, 5 concurrency will be used by default.
- *
- * @type {number}
- * @memberof FileParallelUploadOptions
- */
- concurrency?: number;
- /**
- * Lease access conditions.
- *
- * @type {LeaseAccessConditions}
- * @memberof FileParallelUploadOptions
- */
- leaseAccessConditions?: LeaseAccessConditions;
-}
-
-/**
- * Option interface for the {@link ShareFileClient.downloadToBuffer} operation.
- *
- * @export
- * @interface FileDownloadToBufferOptions
- */
-export interface FileDownloadToBufferOptions extends CommonOptions {
- /**
- * An implementation of the `AbortSignalLike` interface to signal the request to cancel the operation.
- * For example, use the @azure/abort-controller to create an `AbortSignal`.
- *
- * @type {AbortSignalLike}
- * @memberof FileDownloadToBufferOptions
- */
- abortSignal?: AbortSignalLike;
- /**
- * When downloading Azure files, download method will try to split large file into small ranges.
- * Every small range will be downloaded via a separate request.
- * This option defines size data every small request trying to download.
- * Must be > 0, will use the default value if undefined,
- *
- * @type {number}
- * @memberof FileDownloadToBufferOptions
- */
- rangeSize?: number;
-
- /**
- * Optional. ONLY AVAILABLE IN NODE.JS.
- *
- * How many retries will perform when original range download stream unexpected ends.
- * Above kind of ends will not trigger retry policy defined in a pipeline,
- * because they doesn't emit network errors.
- *
- * With this option, every additional retry means an additional ShareFileClient.download() request will be made
- * from the broken point, until the requested range has been successfully downloaded or
- * maxRetryRequestsPerRange is reached.
- *
- * Default value is 5, please set a larger value when in poor network.
- *
- * @type {number}
- * @memberof FileDownloadToBufferOptions
- */
- maxRetryRequestsPerRange?: number;
-
- /**
- * Progress updater.
- *
- * @memberof FileDownloadToBufferOptions
- */
- onProgress?: (progress: TransferProgressEvent) => void;
-
- /**
- * Concurrency indicates the maximum number of ranges to download in parallel.
- * If not provided, 5 concurrency will be used by default.
- *
- * @type {number}
- * @memberof FileDownloadToBufferOptions
- */
- concurrency?: number;
- /**
- * Lease access conditions.
- *
- * @type {LeaseAccessConditions}
- * @memberof FileDownloadToBufferOptions
- */
- leaseAccessConditions?: LeaseAccessConditions;
-}
-
-/**
- * Contains response data for the {@link ShareFileClient.deleteIfExists} operation.
- *
- * @export
- * @interface FileDeleteIfExistsResponse
- */
-export interface FileDeleteIfExistsResponse extends FileDeleteResponse {
- /**
- * Indicate whether the file is successfully deleted. Is false if the file does not exist in the first place.
- *
- * @type {boolean}
- * @memberof FileDeleteIfExistsResponse
- */
- succeeded: boolean;
-}
-
-/**
- * A ShareFileClient represents a URL to an Azure Storage file.
- *
- * @export
- * @class ShareFileClient
- */
-export class ShareFileClient extends StorageClient {
- /**
- * context provided by protocol layer.
- *
- * @private
- * @type {File}
- * @memberof ShareFileClient
- */
- private context: File;
-
- private _shareName: string;
- private _path: string;
- private _name: string;
-
- /**
- * The share name corresponding to this file client
- *
- * @type {string}
- * @memberof ShareFileClient
- */
- public get shareName(): string {
- return this._shareName;
- }
-
- /**
- * The full path of the file
- *
- * @type {string}
- * @memberof ShareFileClient
- */
- public get path(): string {
- return this._path;
- }
-
- /**
- * The name of the file
- *
- * @type {string}
- * @memberof ShareFileClient
- */
- public get name(): string {
- return this._name;
- }
-
- /**
- * Creates an instance of ShareFileClient.
- *
- * @param {string} url A URL string pointing to Azure Storage file, such as
- * "https://myaccount.file.core.windows.net/myshare/mydirectory/file". You can
- * append a SAS if using AnonymousCredential, such as
- * "https://myaccount.file.core.windows.net/myshare/mydirectory/file?sasString".
- * This method accepts an encoded URL or non-encoded URL pointing to a file.
- * Encoded URL string will NOT be escaped twice, only special characters in URL path will be escaped.
- * However, if a file or directory name includes %, file or directory name must be encoded in the URL.
- * Such as a file named "myfile%", the URL should be "https://myaccount.file.core.windows.net/myshare/mydirectory/myfile%25".
- * @param {Credential} [credential] Such as AnonymousCredential or StorageSharedKeyCredential.
- * If not specified, AnonymousCredential is used.
- * @param {StoragePipelineOptions} [options] Optional. Options to configure the HTTP pipeline.
- * @memberof ShareFileClient
- */
- constructor(url: string, credential?: Credential, options?: StoragePipelineOptions);
- /**
- * Creates an instance of ShareFileClient.
- *
- * @param {string} url A URL string pointing to Azure Storage file, such as
- * "https://myaccount.file.core.windows.net/myshare/mydirectory/file". You can
- * append a SAS if using AnonymousCredential, such as
- * "https://myaccount.file.core.windows.net/myshare/mydirectory/file?sasString".
- * This method accepts an encoded URL or non-encoded URL pointing to a file.
- * Encoded URL string will NOT be escaped twice, only special characters in URL path will be escaped.
- * However, if a file or directory name includes %, file or directory name must be encoded in the URL.
- * Such as a file named "myfile%", the URL should be "https://myaccount.file.core.windows.net/myshare/mydirectory/myfile%25".
- * @param {Pipeline} pipeline Call newPipeline() to create a default
- * pipeline, or provide a customized pipeline.
- * @memberof ShareFileClient
- */
- constructor(url: string, pipeline: Pipeline);
- constructor(
- url: string,
- credentialOrPipeline?: Credential | Pipeline,
- options?: StoragePipelineOptions
- ) {
- let pipeline: Pipeline;
- if (credentialOrPipeline instanceof Pipeline) {
- pipeline = credentialOrPipeline;
- } else if (credentialOrPipeline instanceof Credential) {
- pipeline = newPipeline(credentialOrPipeline, options);
- } else {
- // The second parameter is undefined. Use anonymous credential.
- pipeline = newPipeline(new AnonymousCredential(), options);
- }
-
- super(url, pipeline);
- ({
- baseName: this._name,
- shareName: this._shareName,
- path: this._path
- } = getShareNameAndPathFromUrl(this.url));
- this.context = new File(this.storageClientContext);
- }
-
- /**
- * Creates a new file or replaces a file. Note it only initializes the file with no content.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/create-file
- *
- * @param {number} size Specifies the maximum size in bytes for the file, up to 1 TB.
- * @param {FileCreateOptions} [options] Options to File Create operation.
- * @returns {Promise} Response data for the File Create operation.
- * @memberof ShareFileClient
- *
- * Example usage:
- *
- * ```js
- * const content = "Hello world!";
- *
- * // Create the file
- * await fileClient.create(content.length);
- * console.log("Created file successfully!");
- *
- * // Then upload data to the file
- * await fileClient.uploadRange(content, 0, content.length);
- * console.log("Updated file successfully!")
- * ```
- */
- public async create(size: number, options: FileCreateOptions = {}): Promise {
- const { span, spanOptions } = createSpan("ShareFileClient-create", options.tracingOptions);
- try {
- if (size < 0 || size > FILE_MAX_SIZE_BYTES) {
- throw new RangeError(`File size must >= 0 and < ${FILE_MAX_SIZE_BYTES}.`);
- }
- options = validateAndSetDefaultsForFileAndDirectoryCreateCommonOptions(options);
-
- if (!options.fileAttributes) {
- // Note: It would be Archive in service side if None is set.
- const attributes: FileSystemAttributes = new FileSystemAttributes();
- attributes.none = true;
- options.fileAttributes = attributes;
- }
-
- options.fileHttpHeaders = options.fileHttpHeaders || {};
-
- return await this.context.create(
- size,
- fileAttributesToString(options.fileAttributes!),
- fileCreationTimeToString(options.creationTime!),
- fileLastWriteTimeToString(options.lastWriteTime!),
- {
- abortSignal: options.abortSignal,
- fileHttpHeaders: options.fileHttpHeaders,
- metadata: options.metadata,
- filePermission: options.filePermission,
- filePermissionKey: options.filePermissionKey,
- leaseAccessConditions: options.leaseAccessConditions,
- spanOptions
- }
- );
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Reads or downloads a file from the system, including its metadata and properties.
- *
- * * In Node.js, data returns in a Readable stream `readableStreamBody`
- * * In browsers, data returns in a promise `contentAsBlob`
- *
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-file
- *
- * @param {number} [offset] From which position of the file to download, >= 0
- * @param {number} [count] How much data to be downloaded, > 0. Will download to the end when undefined
- * @param {FileDownloadOptions} [options] Options to File Download operation.
- * @returns {Promise} Response data for the File Download operation.
- * @memberof ShareFileClient
- *
- * Example usage (Node.js):
- *
- * ```js
- * // Download a file to a string
- * const downloadFileResponse = await fileClient.download();
- * console.log(
- * "Downloaded file content:",
- * (await streamToBuffer(downloadFileResponse.readableStreamBody)).toString()}
- * );
- *
- * // A helper method used to read a Node.js readable stream into string
- * async function streamToBuffer(readableStream) {
- * return new Promise((resolve, reject) => {
- * const chunks = [];
- * readableStream.on("data", (data) => {
- * chunks.push(data instanceof Buffer ? data : Buffer.from(data));
- * });
- * readableStream.on("end", () => {
- * resolve(Buffer.concat(chunks));
- * });
- * readableStream.on("error", reject);
- * });
- * }
- * ```
- *
- * Example usage (browsers):
- *
- * ```js
- * // Download a file to a string
- * const downloadFileResponse = await fileClient.download(0);
- * console.log(
- * "Downloaded file content:",
- * await blobToString(await downloadFileResponse.blobBody)}
- * );
- *
- * // A helper method used to convert a browser Blob into string.
- * export async function blobToString(blob: Blob): Promise {
- * const fileReader = new FileReader();
- * return new Promise((resolve, reject) => {
- * fileReader.onloadend = (ev: any) => {
- * resolve(ev.target!.result);
- * };
- * fileReader.onerror = reject;
- * fileReader.readAsText(blob);
- * });
- * }
- * ```
- */
- public async download(
- offset: number = 0,
- count?: number,
- options: FileDownloadOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan("ShareFileClient-download", options.tracingOptions);
- try {
- if (options.rangeGetContentMD5 && offset === 0 && count === undefined) {
- throw new RangeError(`rangeGetContentMD5 only works with partial data downloading`);
- }
-
- const downloadFullFile = offset === 0 && !count;
- const res = await this.context.download({
- abortSignal: options.abortSignal,
- onDownloadProgress: isNode ? undefined : options.onProgress, // for Node.js, progress is reported by RetriableReadableStream
- range: downloadFullFile ? undefined : rangeToString({ offset, count }),
- rangeGetContentMD5: options.rangeGetContentMD5,
- leaseAccessConditions: options.leaseAccessConditions,
- spanOptions
- });
-
- // Return browser response immediately
- if (!isNode) {
- return res;
- }
-
- // We support retrying when download stream unexpected ends in Node.js runtime
- // Following code shouldn't be bundled into browser build, however some
- // bundlers may try to bundle following code and "FileReadResponse.ts".
- // In this case, "FileDownloadResponse.browser.ts" will be used as a shim of "FileDownloadResponse.ts"
- // The config is in package.json "browser" field
- if (options.maxRetryRequests === undefined || options.maxRetryRequests < 0) {
- // TODO: Default value or make it a required parameter?
- options.maxRetryRequests = DEFAULT_MAX_DOWNLOAD_RETRY_REQUESTS;
- }
-
- if (res.contentLength === undefined) {
- throw new RangeError(`File download response doesn't contain valid content length header`);
- }
-
- return new FileDownloadResponse(
- res,
- async (start: number): Promise => {
- const updatedOptions: FileDownloadOptionalParams = {
- range: rangeToString({
- count: offset + res.contentLength! - start,
- offset: start
- })
- };
-
- // Debug purpose only
- // console.log(
- // `Read from internal stream, range: ${
- // updatedOptions.range
- // }, options: ${JSON.stringify(updatedOptions)}`
- // );
-
- return (
- await this.context.download({
- abortSignal: options.abortSignal,
- leaseAccessConditions: options.leaseAccessConditions,
- ...updatedOptions,
- spanOptions
- })
- ).readableStreamBody!;
- },
- offset,
- res.contentLength!,
- {
- abortSignal: options.abortSignal,
- maxRetryRequests: options.maxRetryRequests,
- onProgress: options.onProgress
- }
- );
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Returns true if the specified file exists; false otherwise.
- *
- * NOTE: use this function with care since an existing file might be deleted by other clients or
- * applications. Vice versa new files might be added by other clients or applications after this
- * function completes.
- *
- * @param {FileExistsOptions} [options] options to Exists operation.
- * @returns {Promise}
- * @memberof ShareFileClient
- */
- public async exists(options: FileExistsOptions = {}): Promise {
- const { span, spanOptions } = createSpan("ShareFileClient-exists", options.tracingOptions);
- try {
- await this.getProperties({
- abortSignal: options.abortSignal,
- tracingOptions: {
- ...options.tracingOptions,
- spanOptions
- }
- });
- return true;
- } catch (e) {
- if (e.statusCode === 404) {
- span.setStatus({
- code: CanonicalCode.NOT_FOUND,
- message: "Expected exception when checking file existence"
- });
- return false;
- }
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Returns all user-defined metadata, standard HTTP properties, and system properties
- * for the file. It does not return the content of the file.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/get-file-properties
- *
- * @param {FileGetPropertiesOptions} [options] Options to File Get Properties operation.
- * @returns {Promise} Response data for the File Get Properties operation.
- * @memberof ShareFileClient
- */
- public async getProperties(
- options: FileGetPropertiesOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan(
- "ShareFileClient-getProperties",
- options.tracingOptions
- );
- try {
- return this.context.getProperties({
- abortSignal: options.abortSignal,
- leaseAccessConditions: options.leaseAccessConditions,
- spanOptions
- });
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Sets properties on the file.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-file-properties
- *
- * @param {FileProperties} [properties] File properties. For file HTTP headers(e.g. Content-Type),
- * if no values are provided, existing HTTP headers will be removed.
- * For other file properties(e.g. fileAttributes), if no values are provided,
- * existing values will be preserved.
- * @returns {Promise}
- * @memberof ShareFileClient
- */
- public async setProperties(properties: FileProperties = {}): Promise {
- const { span, spanOptions } = createSpan(
- "ShareFileClient-setProperties",
- properties.tracingOptions
- );
- try {
- properties = validateAndSetDefaultsForFileAndDirectorySetPropertiesCommonOptions(properties);
-
- properties.fileHttpHeaders = properties.fileHttpHeaders || {};
-
- return await this.context.setHTTPHeaders(
- fileAttributesToString(properties.fileAttributes!),
- fileCreationTimeToString(properties.creationTime!),
- fileLastWriteTimeToString(properties.lastWriteTime!),
- {
- abortSignal: properties.abortSignal,
- fileHttpHeaders: properties.fileHttpHeaders,
- filePermission: properties.filePermission,
- filePermissionKey: properties.filePermissionKey,
- leaseAccessConditions: properties.leaseAccessConditions,
- spanOptions
- }
- );
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Removes the file from the storage account.
- * When a file is successfully deleted, it is immediately removed from the storage
- * account's index and is no longer accessible to clients. The file's data is later
- * removed from the service during garbage collection.
- *
- * Delete File will fail with status code 409 (Conflict) and error code SharingViolation
- * if the file is open on an SMB client.
- *
- * Delete File is not supported on a share snapshot, which is a read-only copy of
- * a share. An attempt to perform this operation on a share snapshot will fail with 400 (InvalidQueryParameterValue)
- *
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-file2
- *
- * @param {FileDeleteOptions} [options] Options to File Delete operation.
- * @returns {Promise} Response data for the File Delete operation.
- * @memberof ShareFileClient
- */
- public async delete(options: FileDeleteOptions = {}): Promise {
- const { span, spanOptions } = createSpan("ShareFileClient-delete", options.tracingOptions);
- try {
- return await this.context.deleteMethod({
- abortSignal: options.abortSignal,
- leaseAccessConditions: options.leaseAccessConditions,
- spanOptions
- });
- } catch (e) {
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Removes the file from the storage account if it exists.
- * When a file is successfully deleted, it is immediately removed from the storage
- * account's index and is no longer accessible to clients. The file's data is later
- * removed from the service during garbage collection.
- *
- * Delete File will fail with status code 409 (Conflict) and error code SharingViolation
- * if the file is open on an SMB client.
- *
- * Delete File is not supported on a share snapshot, which is a read-only copy of
- * a share. An attempt to perform this operation on a share snapshot will fail with 400 (InvalidQueryParameterValue)
- *
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-file2
- *
- * @param {FileDeleteOptions} [options]
- * @returns {Promise}
- * @memberof ShareFileClient
- */
- public async deleteIfExists(
- options: FileDeleteOptions = {}
- ): Promise {
- const { span, spanOptions } = createSpan(
- "ShareFileClient-deleteIfExists",
- options.tracingOptions
- );
- try {
- const res = await this.delete({
- ...options,
- tracingOptions: { ...options!.tracingOptions, spanOptions }
- });
- return {
- succeeded: true,
- ...res
- };
- } catch (e) {
- if (e.details?.errorCode === "ResourceNotFound") {
- span.setStatus({
- code: CanonicalCode.NOT_FOUND,
- message: "Expected exception when deleting a file only if it exists."
- });
- return {
- succeeded: false,
- ...e.response?.parsedHeaders,
- _response: e.response
- };
- }
- span.setStatus({
- code: CanonicalCode.UNKNOWN,
- message: e.message
- });
- throw e;
- } finally {
- span.end();
- }
- }
-
- /**
- * Sets HTTP headers on the file.
- *
- * If no option provided, or no value provided for the file HTTP headers in the options,
- * these file HTTP headers without a value will be cleared.
- * @see https://docs.microsoft.com/en-us/rest/api/storageservices/set-file-properties
- *
- * @param {fileHttpHeaders} [FileHttpHeaders] File HTTP headers like Content-Type.
- * Provide undefined will remove existing HTTP headers.
- * @param {FileSetHttpHeadersOptions} [options] Options to File Set HTTP Headers operation.
- * @returns {Promise