UNPKG

@azure/storage-file-share

Version:
1,012 lines 134 kB
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. import { __asyncGenerator, __asyncValues, __await } from "tslib"; import { isTokenCredential } from "@azure/core-auth"; import { isNode } from "@azure/core-util"; import { isPipelineLike, newPipeline } 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, appendToURLQuery, httpAuthorizationToString, setURLPath, setURLQueries, EscapePath, ConvertInternalResponseOfListFiles, ConvertInternalResponseOfListHandles, assertResponse, removeEmptyString, asSharePermission, parseOctalFileMode, toOctalFileMode, } from "./utils/utils.common"; import { Credential } from "../../storage-blob/src/credentials/Credential"; import { StorageSharedKeyCredential } from "../../storage-blob/src/credentials/StorageSharedKeyCredential"; import { AnonymousCredential } from "../../storage-blob/src/credentials/AnonymousCredential"; import { tracingClient } from "./utils/tracing"; import { StorageClient } from "./StorageClient"; import { FileDownloadResponse } from "./FileDownloadResponse"; import { rangeToString } from "./Range"; import { fileAttributesToString, fileCreationTimeToString, fileLastWriteTimeToString, validateAndSetDefaultsForFileAndDirectoryCreateCommonOptions, validateAndSetDefaultsForFileAndDirectorySetPropertiesCommonOptions, toShareProtocolsString, toShareProtocols, fileChangeTimeToString, } from "./models"; import { Batch } from "./utils/Batch"; import { BufferScheduler } from "./utils/BufferScheduler"; import { fsStat, fsCreateReadStream, readStreamToLocalFile, streamToBuffer, } from "./utils/utils.node"; import { randomUUID } from "@azure/core-util"; import { generateFileSASQueryParameters, generateFileSASQueryParametersInternal, } from "./FileSASSignatureValues"; /** * A ShareClient represents a URL to the Azure Storage share allowing you to manipulate its directories and files. */ export class ShareClient extends StorageClient { /** * The name of the share */ get name() { return this._name; } constructor(urlOrConnectionString, credentialOrPipelineOrShareName, // Legacy, no way to fix the eslint error without breaking. Disable the rule for this line. options) { let pipeline; let url; if (isPipelineLike(credentialOrPipelineOrShareName)) { // (url: string, pipeline: Pipeline) url = urlOrConnectionString; pipeline = credentialOrPipelineOrShareName; } else if (credentialOrPipelineOrShareName instanceof Credential || isTokenCredential(credentialOrPipelineOrShareName)) { // (url: string, credential?: Credential, options?: ShareClientOptions) url = urlOrConnectionString; pipeline = newPipeline(credentialOrPipelineOrShareName, options); } else if (!credentialOrPipelineOrShareName && typeof credentialOrPipelineOrShareName !== "string") { // (url: string, credential?: Credential, options?: ShareClientOptions) // 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?: ShareClientOptions) 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.shareClientConfig = options; this.context = this.storageClientContext.share; } /** * 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 snapshot - The snapshot timestamp. * @returns A new ShareClient object identical to the source but with the specified snapshot timestamp */ withSnapshot(snapshot) { return new ShareClient(setURLParameter(this.url, URLConstants.Parameters.SHARE_SNAPSHOT, snapshot.length === 0 ? undefined : snapshot), this.pipeline, this.shareClientConfig); } /** * Creates a new share under the specified account. If the share with * the same name already exists, the operation fails. * @see https://learn.microsoft.com/en-us/rest/api/storageservices/create-share * * @param options - Options to Share Create operation. * @returns Response data for the Share Create operation. */ async create(options = {}) { return tracingClient.withSpan("ShareClient-create", options, async (updatedOptions) => { return assertResponse(await this.context.create(Object.assign(Object.assign(Object.assign({}, updatedOptions), this.shareClientConfig), { enabledProtocols: toShareProtocolsString(updatedOptions.protocols) }))); }); } /** * Creates a new share under the specified account. If the share with * the same name already exists, it is not changed. * @see https://learn.microsoft.com/en-us/rest/api/storageservices/create-share * * @param options - */ async createIfNotExists(options = {}) { return tracingClient.withSpan("ShareClient-createIfNotExists", options, async (updatedOptions) => { var _a, _b; try { const res = await this.create(updatedOptions); return Object.assign({ succeeded: true }, res); } catch (e) { if (((_a = e.details) === null || _a === void 0 ? void 0 : _a.errorCode) === "ShareAlreadyExists") { return Object.assign(Object.assign({ succeeded: false }, (_b = e.response) === null || _b === void 0 ? void 0 : _b.parsedHeaders), { _response: e.response }); } throw e; } }); } /** * Creates a {@link ShareDirectoryClient} object. * * @param directoryName - A directory name * @returns The ShareDirectoryClient object for the given directory name. */ // Legacy, no way to fix the eslint error without breaking. Disable the rule for this line. /* eslint-disable-next-line @azure/azure-sdk/ts-naming-subclients */ getDirectoryClient(directoryName) { return new ShareDirectoryClient(appendToURLPath(this.url, EscapePath(directoryName)), this.pipeline, this.shareClientConfig); } /** * Gets the directory client for the root directory of this share. * Note that the root directory always exists and cannot be deleted. * * @readonly A new ShareDirectoryClient object for the root directory. */ // Legacy, no way to fix the eslint error without breaking. Disable the rule for this line. /* eslint-disable-next-line @azure/azure-sdk/ts-naming-subclients */ get rootDirectoryClient() { return this.getDirectoryClient(""); } /** * Creates a new subdirectory under this share. * @see https://learn.microsoft.com/en-us/rest/api/storageservices/create-directory * * @param directoryName - * @param options - Options to Directory Create operation. * @returns Directory creation response data and the corresponding directory client. */ async createDirectory(directoryName, options = {}) { return tracingClient.withSpan("ShareClient-createDirectory", options, async (updatedOptions) => { const directoryClient = this.getDirectoryClient(directoryName); const directoryCreateResponse = await directoryClient.create(updatedOptions); return { directoryClient, directoryCreateResponse, }; }); } /** * Removes the specified empty sub directory under this share. * Note that the directory must be empty before it can be deleted. * @see https://learn.microsoft.com/en-us/rest/api/storageservices/delete-directory * * @param directoryName - * @param options - Options to Directory Delete operation. * @returns Directory deletion response data. */ async deleteDirectory(directoryName, options = {}) { return tracingClient.withSpan("ShareClient-deleteDirectory", options, async (updatedOptions) => { const directoryClient = this.getDirectoryClient(directoryName); return directoryClient.delete(updatedOptions); }); } /** * 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://learn.microsoft.com/en-us/rest/api/storageservices/create-file * * @param fileName - * @param size - Specifies the maximum size in bytes for the file, up to 4 TB. * @param options - Options to File Create operation. * @returns File creation response data and the corresponding file client. */ async createFile(fileName, size, options = {}) { return tracingClient.withSpan("ShareClient-createFile", options, async (updatedOptions) => { const directoryClient = this.rootDirectoryClient; const fileClient = directoryClient.getFileClient(fileName); const fileCreateResponse = await fileClient.create(size, updatedOptions); return { fileClient, fileCreateResponse, }; }); } /** * 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://learn.microsoft.com/en-us/rest/api/storageservices/delete-file2 * * @param directoryName - * @param fileName - * @param options - Options to File Delete operation. * @returns Promise<FileDeleteResponse> File Delete response data. */ async deleteFile(fileName, options = {}) { return tracingClient.withSpan("ShareClient-deleteFile", options, async (updatedOptions) => { const directoryClient = this.rootDirectoryClient; const fileClient = directoryClient.getFileClient(fileName); return fileClient.delete(updatedOptions); }); } /** * 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 options - options to Exists operation. */ async exists(options = {}) { return tracingClient.withSpan("ShareClient-exists", options, async (updatedOptions) => { try { await this.getProperties(updatedOptions); return true; } catch (e) { if (e.statusCode === 404) { return false; } throw e; } }); } /** * Returns all user-defined metadata and system properties for the specified * share. * @see https://learn.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 Response data for the Share Get Properties operation. */ async getProperties(options = {}) { return tracingClient.withSpan("ShareClient-getProperties", options, async (updatedOptions) => { const res = assertResponse(await this.context.getProperties(updatedOptions)); return Object.assign(Object.assign(Object.assign({}, res), this.shareClientConfig), { protocols: toShareProtocols(res.enabledProtocols) }); }); } /** * Marks the specified share for deletion. The share and any directories or files * contained within it are later deleted during garbage collection. * @see https://learn.microsoft.com/en-us/rest/api/storageservices/delete-share * * @param options - Options to Share Delete operation. * @returns Response data for the Share Delete operation. */ async delete(options = {}) { return tracingClient.withSpan("ShareClient-delete", options, async (updatedOptions) => { return assertResponse(await this.context.delete(Object.assign(Object.assign({}, updatedOptions), this.shareClientConfig))); }); } /** * 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://learn.microsoft.com/en-us/rest/api/storageservices/delete-share * * @param options - */ async deleteIfExists(options = {}) { return tracingClient.withSpan("ShareClient-deleteIfExists", options, async (updatedOptions) => { var _a, _b; try { const res = await this.delete(updatedOptions); return Object.assign({ succeeded: true }, res); } catch (e) { if (((_a = e.details) === null || _a === void 0 ? void 0 : _a.errorCode) === "ShareNotFound") { return Object.assign(Object.assign({ succeeded: false }, (_b = e.response) === null || _b === void 0 ? void 0 : _b.parsedHeaders), { _response: e.response }); } throw e; } }); } /** * 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://learn.microsoft.com/en-us/rest/api/storageservices/set-share-metadata * * @param metadata - If no metadata provided, all existing directory metadata will be removed. * @param option - Options to Share Set Metadata operation. * @returns Response data for the Share Set Metadata operation. */ async setMetadata(metadata, options = {}) { return tracingClient.withSpan("ShareClient-setMetadata", options, async (updatedOptions) => { return assertResponse(await this.context.setMetadata(Object.assign(Object.assign(Object.assign({}, updatedOptions), this.shareClientConfig), { metadata }))); }); } /** * 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://learn.microsoft.com/en-us/rest/api/storageservices/get-share-acl * * @param option - Options to Share Get Access Policy operation. * @returns Response data for the Share Get Access Policy operation. */ async getAccessPolicy(options = {}) { return tracingClient.withSpan("ShareClient-getAccessPolicy", options, async (updatedOptions) => { const response = assertResponse(await this.context.getAccessPolicy(Object.assign(Object.assign({}, updatedOptions), this.shareClientConfig))); const res = { _response: response._response, date: response.date, etag: response.etag, lastModified: response.lastModified, requestId: response.requestId, signedIdentifiers: [], version: response.version, }; for (const identifier of response) { let accessPolicy = undefined; if (identifier.accessPolicy) { accessPolicy = { permissions: identifier.accessPolicy.permissions, }; if (identifier.accessPolicy.expiresOn) { accessPolicy.expiresOn = new Date(identifier.accessPolicy.expiresOn); } if (identifier.accessPolicy.startsOn) { accessPolicy.startsOn = new Date(identifier.accessPolicy.startsOn); } } res.signedIdentifiers.push({ accessPolicy, id: identifier.id, }); } return res; }); } /** * 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://learn.microsoft.com/en-us/rest/api/storageservices/set-share-acl * * @param shareAcl - Array of signed identifiers, each having a unique Id and details of access policy. * @param option - Options to Share Set Access Policy operation. * @returns Response data for the Share Set Access Policy operation. */ async setAccessPolicy(shareAcl, options = {}) { return tracingClient.withSpan("ShareClient-setAccessPolicy", options, async (updatedOptions) => { var _a, _b, _c; const acl = []; for (const identifier of shareAcl || []) { acl.push({ accessPolicy: { expiresOn: ((_a = identifier.accessPolicy) === null || _a === void 0 ? void 0 : _a.expiresOn) ? truncatedISO8061Date(identifier.accessPolicy.expiresOn) : undefined, permissions: (_b = identifier.accessPolicy) === null || _b === void 0 ? void 0 : _b.permissions, startsOn: ((_c = identifier.accessPolicy) === null || _c === void 0 ? void 0 : _c.startsOn) ? truncatedISO8061Date(identifier.accessPolicy.startsOn) : undefined, }, id: identifier.id, }); } return assertResponse(await this.context.setAccessPolicy(Object.assign(Object.assign(Object.assign({}, updatedOptions), this.shareClientConfig), { shareAcl: acl }))); }); } /** * Creates a read-only snapshot of a share. * * @param options - Options to Share Create Snapshot operation. * @returns Response data for the Share Create Snapshot operation. */ async createSnapshot(options = {}) { return tracingClient.withSpan("ShareClient-createSnapshot", options, async (updatedOptions) => { return assertResponse(await this.context.createSnapshot(Object.assign(Object.assign({}, updatedOptions), this.shareClientConfig))); }); } /** * Sets quota for the specified share. * * @deprecated Use {@link ShareClient.setProperties} instead. * * @param quotaInGB - Specifies the maximum size of the share in gigabytes * @param option - Options to Share Set Quota operation. * @returns Response data for the Share Get Quota operation. */ async setQuota(quotaInGB, options = {}) { return tracingClient.withSpan("ShareClient-setQuota", options, async (updatedOptions) => { return assertResponse(await this.context.setProperties(Object.assign(Object.assign(Object.assign({}, updatedOptions), this.shareClientConfig), { quota: quotaInGB }))); }); } /** * Sets properties of the share. * * @param option - Options to Share Set Properties operation. * @returns Response data for the Share Set Properties operation. */ async setProperties(options = {}) { return tracingClient.withSpan("ShareClient-setProperties", options, async (updatedOptions) => { return assertResponse(await this.context.setProperties(Object.assign(Object.assign(Object.assign({}, options), this.shareClientConfig), { quota: options.quotaInGB, tracingOptions: updatedOptions.tracingOptions }))); }); } /** * Retrieves statistics related to the share. * * @param option - Options to Share Get Statistics operation. * @returns Response data for the Share Get Statistics operation. */ async getStatistics(options = {}) { return tracingClient.withSpan("ShareClient-getStatistics", options, async (updatedOptions) => { const response = assertResponse(await this.context.getStatistics(Object.assign(Object.assign({}, updatedOptions), this.shareClientConfig))); const GBBytes = 1024 * 1024 * 1024; return Object.assign(Object.assign({}, response), { shareUsage: Math.ceil(response.shareUsageBytes / GBBytes) }); }); } /** * 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://learn.microsoft.com/en-us/rest/api/storageservices/create-permission * * @param options - Options to Share Create Permission operation. * @param filePermission - File permission described in the SDDL */ async createPermission(filePermission, options = {}) { return tracingClient.withSpan("ShareClient-createPermission", options, async (updatedOptions) => { return assertResponse(await this.context.createPermission(asSharePermission(filePermission), Object.assign(Object.assign({}, updatedOptions), this.shareClientConfig))); }); } /** * Gets the Security Descriptor Definition Language (SDDL) for a given file permission key * which indicates a security descriptor. * @see https://learn.microsoft.com/en-us/rest/api/storageservices/get-permission * * @param options - Options to Share Create Permission operation. * @param filePermissionKey - File permission key which indicates the security descriptor of the permission. */ async getPermission(filePermissionKey, options = {}) { return tracingClient.withSpan("ShareClient-getPermission", options, async (updatedOptions) => { return assertResponse(await this.context.getPermission(filePermissionKey, Object.assign(Object.assign({}, updatedOptions), this.shareClientConfig))); }); } /** * Get a {@link ShareLeaseClient} that manages leases on the file. * * @param proposeLeaseId - Initial proposed lease Id. * @returns A new ShareLeaseClient object for managing leases on the file. */ getShareLeaseClient(proposeLeaseId) { return new ShareLeaseClient(this, proposeLeaseId); } /** * Only available for ShareClient constructed with a shared key credential. * * Generates a Service Shared Access Signature (SAS) URI based on the client properties * and parameters passed in. The SAS is signed by the shared key credential of the client. * * @see https://learn.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas * * @param options - Optional parameters. * @returns The SAS URI consisting of the URI to the resource represented by this client, followed by the generated SAS token. */ generateSasUrl(options) { if (!(this.credential instanceof StorageSharedKeyCredential)) { throw RangeError("Can only generate the SAS when the client is initialized with a shared key credential"); } const sas = generateFileSASQueryParameters(Object.assign({ shareName: this.name }, options), this.credential).toString(); return appendToURLQuery(this.url, sas); } /** * Only available for ShareClient constructed with a shared key credential. * * Generates string to sign for a Service Shared Access Signature (SAS) URI based on the client properties * and parameters passed in. The SAS is signed by the shared key credential of the client. * * @see https://learn.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas * * @param options - Optional parameters. * @returns The SAS URI consisting of the URI to the resource represented by this client, followed by the generated SAS token. */ /* eslint-disable-next-line @azure/azure-sdk/ts-naming-options*/ generateSasStringToSign(options) { if (!(this.credential instanceof StorageSharedKeyCredential)) { throw RangeError("Can only generate the SAS when the client is initialized with a shared key credential"); } return generateFileSASQueryParametersInternal(Object.assign({ shareName: this.name }, options), this.credential).stringToSign; } } /** * A ShareDirectoryClient represents a URL to the Azure Storage directory allowing you to manipulate its files and directories. */ export class ShareDirectoryClient extends StorageClient { /** * The share name corresponding to this directory client */ get shareName() { return this._shareName; } /** * The full path of the directory */ get path() { return this._path; } /** * The name of the directory */ get name() { return this._name; } constructor(url, credentialOrPipeline, // Legacy, no way to fix the eslint error without breaking. Disable the rule for this line. /* eslint-disable-next-line @azure/azure-sdk/ts-naming-options */ options = {}) { let pipeline; if (isPipelineLike(credentialOrPipeline)) { pipeline = credentialOrPipeline; } else if (credentialOrPipeline instanceof Credential || isTokenCredential(credentialOrPipeline)) { 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.shareClientConfig = options; this.context = this.storageClientContext.directory; } /** * Creates a new directory under the specified share or parent directory. * @see https://learn.microsoft.com/en-us/rest/api/storageservices/create-directory * * @param options - Options to Directory Create operation. * @returns Response data for the Directory operation. */ async create(options = {}) { if (!options.fileAttributes) { options = validateAndSetDefaultsForFileAndDirectoryCreateCommonOptions(options); } return tracingClient.withSpan("ShareDirectoryClient-create", options, async (updatedOptions) => { var _a, _b, _c; const rawResponse = await this.context.create(Object.assign(Object.assign(Object.assign({}, updatedOptions), { fileChangeOn: fileChangeTimeToString(updatedOptions.changeTime), fileCreatedOn: fileCreationTimeToString(updatedOptions.creationTime), fileLastWriteOn: fileLastWriteTimeToString(updatedOptions.lastWriteTime), fileAttributes: updatedOptions.fileAttributes ? fileAttributesToString(updatedOptions.fileAttributes) : undefined, owner: (_a = updatedOptions.posixProperties) === null || _a === void 0 ? void 0 : _a.owner, group: (_b = updatedOptions.posixProperties) === null || _b === void 0 ? void 0 : _b.group, fileMode: toOctalFileMode((_c = updatedOptions.posixProperties) === null || _c === void 0 ? void 0 : _c.fileMode) }), this.shareClientConfig)); const wrappedRes = Object.assign(Object.assign({}, rawResponse), { _response: rawResponse._response, posixProperties: { fileMode: parseOctalFileMode(rawResponse.fileMode), fileType: rawResponse.nfsFileType, owner: rawResponse.owner, group: rawResponse.group, } }); return assertResponse(wrappedRes); }); } /** * 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://learn.microsoft.com/en-us/rest/api/storageservices/create-directory * * @param options - */ async createIfNotExists(options = {}) { return tracingClient.withSpan("ShareDirectoryClient-createIfNotExists", options, async (updatedOptions) => { var _a, _b; try { const res = await this.create(updatedOptions); return Object.assign({ succeeded: true }, res); } catch (e) { if (((_a = e.details) === null || _a === void 0 ? void 0 : _a.errorCode) === "ResourceAlreadyExists") { return Object.assign(Object.assign({ succeeded: false }, (_b = e.response) === null || _b === void 0 ? void 0 : _b.parsedHeaders), { _response: e.response }); } throw e; } }); } /** * Sets properties on the directory. * @see https://learn.microsoft.com/en-us/rest/api/storageservices/set-directory-properties * * @param DirectoryProperties - Directory properties. If no values are provided, * existing values will be preserved. */ async setProperties(properties = {}) { properties = validateAndSetDefaultsForFileAndDirectorySetPropertiesCommonOptions(properties); return tracingClient.withSpan("ShareDirectoryClient-setProperties", properties, async (updatedOptions) => { var _a, _b, _c; const rawResponse = await this.context.setProperties(Object.assign(Object.assign(Object.assign({}, updatedOptions), { fileChangeOn: fileChangeTimeToString(updatedOptions.changeTime), fileCreatedOn: fileCreationTimeToString(updatedOptions.creationTime), fileLastWriteOn: fileLastWriteTimeToString(updatedOptions.lastWriteTime), fileAttributes: updatedOptions.fileAttributes ? fileAttributesToString(updatedOptions.fileAttributes) : undefined, owner: (_a = updatedOptions.posixProperties) === null || _a === void 0 ? void 0 : _a.owner, group: (_b = updatedOptions.posixProperties) === null || _b === void 0 ? void 0 : _b.group, fileMode: toOctalFileMode((_c = updatedOptions.posixProperties) === null || _c === void 0 ? void 0 : _c.fileMode) }), this.shareClientConfig)); return assertResponse(Object.assign(Object.assign({}, rawResponse), { _response: rawResponse._response, posixProperties: { fileMode: parseOctalFileMode(rawResponse.fileMode), owner: rawResponse.owner, group: rawResponse.group, } })); }); } /** * Creates a ShareDirectoryClient object for a sub directory. * * @param subDirectoryName - A subdirectory name * @returns The ShareDirectoryClient object for the given subdirectory name. * * Example usage: * * ```js * const directoryClient = shareClient.getDirectoryClient("<directory name>"); * await directoryClient.create(); * console.log("Created directory successfully"); * ``` */ getDirectoryClient(subDirectoryName) { return new ShareDirectoryClient(appendToURLPath(this.url, EscapePath(subDirectoryName)), this.pipeline, this.shareClientConfig); } /** * Creates a new subdirectory under this directory. * @see https://learn.microsoft.com/en-us/rest/api/storageservices/create-directory * * @param directoryName - * @param options - Options to Directory Create operation. * @returns Directory create response data and the corresponding DirectoryClient instance. */ async createSubdirectory(directoryName, options = {}) { return tracingClient.withSpan("ShareDirectoryClient-createSubdirectory", options, async (updatedOptions) => { const directoryClient = this.getDirectoryClient(directoryName); const directoryCreateResponse = await directoryClient.create(updatedOptions); return { directoryClient, directoryCreateResponse, }; }); } /** * Removes the specified empty sub directory under this directory. * Note that the directory must be empty before it can be deleted. * @see https://learn.microsoft.com/en-us/rest/api/storageservices/delete-directory * * @param directoryName - * @param options - Options to Directory Delete operation. * @returns Directory deletion response data. */ async deleteSubdirectory(directoryName, options = {}) { return tracingClient.withSpan("ShareDirectoryClient-deleteSubdirectory", options, async (updatedOptions) => { const directoryClient = this.getDirectoryClient(directoryName); return directoryClient.delete(updatedOptions); }); } /** * Creates a new file or replaces a file under this directory. Note it only initializes the file with no content. * @see https://learn.microsoft.com/en-us/rest/api/storageservices/create-file * * @param fileName - * @param size - Specifies the maximum size in bytes for the file, up to 4 TB. * @param options - Options to File Create operation. * @returns File creation response data and the corresponding file client. */ async createFile(fileName, size, options = {}) { return tracingClient.withSpan("ShareDirectoryClient-createFile", options, async (updatedOptions) => { const fileClient = this.getFileClient(fileName); const fileCreateResponse = await fileClient.create(size, updatedOptions); return { fileClient, fileCreateResponse, }; }); } /** * 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://learn.microsoft.com/en-us/rest/api/storageservices/delete-file2 * * @param fileName - Name of the file to delete * @param options - Options to File Delete operation. * @returns File deletion response data. */ async deleteFile(fileName, options = {}) { return tracingClient.withSpan("ShareDirectoryClient-deleteFile", options, async (updatedOptions) => { const fileClient = this.getFileClient(fileName); return fileClient.delete(updatedOptions); }); } /** * Creates a {@link ShareFileClient} object. * * @param fileName - A file name. * @returns A new ShareFileClient object for the given file name. * * Example usage: * * ```js * const content = "Hello world!" * * const fileClient = directoryClient.getFileClient("<file name>"); * * await fileClient.create(content.length); * console.log("Created file successfully!"); * * await fileClient.uploadRange(content, 0, content.length); * console.log("Updated file successfully!") * ``` */ // Legacy, no way to fix the eslint error without breaking. Disable the rule for this line. /* eslint-disable-next-line @azure/azure-sdk/ts-naming-subclients */ getFileClient(fileName) { return new ShareFileClient(appendToURLPath(this.url, EscapePath(fileName)), this.pipeline, this.shareClientConfig); } /** * 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 options - options to Exists operation. */ async exists(options = {}) { return tracingClient.withSpan("ShareDirectoryClient-exists", options, async (updatedOptions) => { try { await this.getProperties(Object.assign(Object.assign({}, updatedOptions), this.shareClientConfig)); return true; } catch (e) { if (e.statusCode === 404) { return false; } throw e; } }); } /** * 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://learn.microsoft.com/en-us/rest/api/storageservices/get-directory-properties * * @param options - Options to Directory Get Properties operation. * @returns Response data for the Directory Get Properties operation. */ async getProperties(options = {}) { return tracingClient.withSpan("ShareDirectoryClient-getProperties", options, async (updatedOptions) => { const rawResponse = await this.context.getProperties(Object.assign(Object.assign({}, updatedOptions), this.shareClientConfig)); return assertResponse(Object.assign(Object.assign({}, rawResponse), { _response: rawResponse._response, posixProperties: { fileMode: parseOctalFileMode(rawResponse.fileMode), owner: rawResponse.owner, group: rawResponse.group, fileType: rawResponse.nfsFileType, } })); }); } /** * Removes the specified empty directory. Note that the directory must be empty before it can be * deleted. * @see https://learn.microsoft.com/en-us/rest/api/storageservices/delete-directory * * @param options - Options to Directory Delete operation. * @returns Response data for the Directory Delete operation. */ async delete(options = {}) { return tracingClient.withSpan("ShareDirectoryClient-delete", options, async (updatedOptions) => { return assertResponse(await this.context.delete(Object.assign(Object.assign({}, updatedOptions), this.shareClientConfig))); }); } /** * Removes the specified empty directory if it exists. Note that the directory must be empty before it can be * deleted. * @see https://learn.microsoft.com/en-us/rest/api/storageservices/delete-directory * * @param options - */ async deleteIfExists(options = {}) { return tracingClient.withSpan("ShareDirectoryClient-deleteIfExists", options, async (updatedOptions) => { var _a, _b, _c; try { const res = await this.delete(updatedOptions); return Object.assign({ succeeded: true }, res); } catch (e) { if (((_a = e.details) === null || _a === void 0 ? void 0 : _a.errorCode) === "ResourceNotFound" || ((_b = e.details) === null || _b === void 0 ? void 0 : _b.errorCode) === "ParentNotFound") { return Object.assign(Object.assign({ succeeded: false }, (_c = e.response) === null || _c === void 0 ? void 0 : _c.parsedHeaders), { _response: e.response }); } throw e; } }); } /** * Updates user defined metadata for the specified directory. * @see https://learn.microsoft.com/en-us/rest/api/storageservices/set-directory-metadata * * @param metadata - If no metadata provided, all existing directory metadata will be removed * @param options - Options to Directory Set Metadata operation. * @returns Response data for the Directory Set Metadata operation. */ async setMetadata(metadata, options = {}) { return tracingClient.withSpan("ShareDirectoryClient-setMetadata", options, async (updatedOptions) => { return assertResponse(await this.context.setMetadata(Object.assign(Object.assign(Object.assign({}, updatedOptions), { metadata }), this.shareClientConfig))); }); } /** * Returns an AsyncIterableIterator for {@link DirectoryListFilesAndDirectoriesSegmentResponse} objects * * @param 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 options - Options to list files and directories operation. */ iterateFilesAndDirectoriesSegments(marker_1) { return __asyncGenerator(this, arguments, function* iterateFilesAndDirectoriesSegments_1(marker, options = {}) { if (options.prefix === "") { options.prefix = undefined; } let listFilesAndDirectoriesResponse; do { listFilesAndDirectoriesResponse = yield __await(this.listFilesAndDirectoriesSegment(marker, options)); marker = listFilesAndDirectoriesResponse.continuationToken; yield yield __await(yield __await(listFilesAndDirectoriesResponse)); } while (marker); }); } /** * Returns an AsyncIterableIterator for file and directory items * * @param options - Options to list files and directories operation. */ listFilesAndDirectoriesItems() { return __asyncGenerator(this, arguments, function* listFilesAndDirectoriesItems_1(options = {}) { var _a, e_1, _b, _c; if (options.prefix === "") { options.prefix = undefined; } let marker; try { for (var _d = true, _e = __asyncValues(this.iterateFilesAndDirectoriesSegments(marker, options)), _f; _f = yield __await(_e.next()), _a = _f.done, !_a; _d = true) { _c = _f.value; _d = false; const listFilesAndDirectoriesResponse = _c; for (const file of listFilesAndDirectoriesResponse.segment.fileItems) { yield yield __await(Object.assign({ kind: "file" }, file)); } for (const directory of listFilesAndDirectoriesResponse.segment.directoryItems) { yield yield __await(Object.assign({ kind: "directory" }, directory)); } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e)); } finally { if (e_1) throw e_1.error; } } }); } /** * 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 options - Options to list files and directories operation. * @returns An asyncIterableIterator that supports paging. */ listFilesAndDirectories(options = {}) { const include = []; if (options.includeTimestamps) { include.push("Timestamps"); } if (options.includeEtag) { include.push("Etag"); } if (options.in