text: /*!
   * Copyright (c) Microsoft and contributors. All rights reserved.
   * Licensed under the MIT License. See License.txt in the project root for
   * license information.
   * 
   * Azure KeyVault Keys SDK for JavaScript - 4.3.0
   */
  'use strict';
  
  Object.defineProperty(exports, '__esModule', { value: true });
  
  var tslib = require('tslib');
  var coreHttp = require('@azure/core-http');
  var logger$1 = require('@azure/logger');
  require('@azure/core-paging');
  var url = require('url');
  var coreTracing = require('@azure/core-tracing');
  var coreLro = require('@azure/core-lro');
  var crypto = require('crypto');
  var constants = require('constants');
  
  // Copyright (c) Microsoft Corporation.
  /**
   * The \@azure/logger configuration for this package.
   */
  const logger = logger$1.createClientLogger("keyvault-keys");
  
  /*
   * Copyright (c) Microsoft Corporation.
   * Licensed under the MIT License.
   *
   * Code generated by Microsoft (R) AutoRest Code Generator.
   * Changes may cause incorrect behavior and will be lost if the code is regenerated.
   */
  const KeyCreateParameters = {
      type: {
          name: "Composite",
          className: "KeyCreateParameters",
          modelProperties: {
              kty: {
                  serializedName: "kty",
                  required: true,
                  type: {
                      name: "String"
                  }
              },
              keySize: {
                  serializedName: "key_size",
                  type: {
                      name: "Number"
                  }
              },
              publicExponent: {
                  serializedName: "public_exponent",
                  type: {
                      name: "Number"
                  }
              },
              keyOps: {
                  serializedName: "key_ops",
                  type: {
                      name: "Sequence",
                      element: {
                          type: {
                              name: "String"
                          }
                      }
                  }
              },
              keyAttributes: {
                  serializedName: "attributes",
                  type: {
                      name: "Composite",
                      className: "KeyAttributes"
                  }
              },
              tags: {
                  serializedName: "tags",
                  type: {
                      name: "Dictionary",
                      value: { type: { name: "String" } }
                  }
              },
              curve: {
                  serializedName: "crv",
                  type: {
                      name: "String"
                  }
              }
          }
      }
  };
  const Attributes = {
      type: {
          name: "Composite",
          className: "Attributes",
          modelProperties: {
              enabled: {
                  serializedName: "enabled",
                  type: {
                      name: "Boolean"
                  }
              },
              notBefore: {
                  serializedName: "nbf",
                  type: {
                      name: "UnixTime"
                  }
              },
              expires: {
                  serializedName: "exp",
                  type: {
                      name: "UnixTime"
                  }
              },
              created: {
                  serializedName: "created",
                  readOnly: true,
                  type: {
                      name: "UnixTime"
                  }
              },
              updated: {
                  serializedName: "updated",
                  readOnly: true,
                  type: {
                      name: "UnixTime"
                  }
              }
          }
      }
  };
  const KeyBundle = {
      type: {
          name: "Composite",
          className: "KeyBundle",
          modelProperties: {
              key: {
                  serializedName: "key",
                  type: {
                      name: "Composite",
                      className: "JsonWebKey"
                  }
              },
              attributes: {
                  serializedName: "attributes",
                  type: {
                      name: "Composite",
                      className: "KeyAttributes"
                  }
              },
              tags: {
                  serializedName: "tags",
                  type: {
                      name: "Dictionary",
                      value: { type: { name: "String" } }
                  }
              },
              managed: {
                  serializedName: "managed",
                  readOnly: true,
                  type: {
                      name: "Boolean"
                  }
              }
          }
      }
  };
  const JsonWebKey = {
      type: {
          name: "Composite",
          className: "JsonWebKey",
          modelProperties: {
              kid: {
                  serializedName: "kid",
                  type: {
                      name: "String"
                  }
              },
              kty: {
                  serializedName: "kty",
                  type: {
                      name: "String"
                  }
              },
              keyOps: {
                  serializedName: "key_ops",
                  type: {
                      name: "Sequence",
                      element: {
                          type: {
                              name: "String"
                          }
                      }
                  }
              },
              n: {
                  serializedName: "n",
                  type: {
                      name: "Base64Url"
                  }
              },
              e: {
                  serializedName: "e",
                  type: {
                      name: "Base64Url"
                  }
              },
              d: {
                  serializedName: "d",
                  type: {
                      name: "Base64Url"
                  }
              },
              dp: {
                  serializedName: "dp",
                  type: {
                      name: "Base64Url"
                  }
              },
              dq: {
                  serializedName: "dq",
                  type: {
                      name: "Base64Url"
                  }
              },
              qi: {
                  serializedName: "qi",
                  type: {
                      name: "Base64Url"
                  }
              },
              p: {
                  serializedName: "p",
                  type: {
                      name: "Base64Url"
                  }
              },
              q: {
                  serializedName: "q",
                  type: {
                      name: "Base64Url"
                  }
              },
              k: {
                  serializedName: "k",
                  type: {
                      name: "Base64Url"
                  }
              },
              t: {
                  serializedName: "key_hsm",
                  type: {
                      name: "Base64Url"
                  }
              },
              crv: {
                  serializedName: "crv",
                  type: {
                      name: "String"
                  }
              },
              x: {
                  serializedName: "x",
                  type: {
                      name: "Base64Url"
                  }
              },
              y: {
                  serializedName: "y",
                  type: {
                      name: "Base64Url"
                  }
              }
          }
      }
  };
  const KeyVaultError = {
      type: {
          name: "Composite",
          className: "KeyVaultError",
          modelProperties: {
              error: {
                  serializedName: "error",
                  type: {
                      name: "Composite",
                      className: "ErrorModel"
                  }
              }
          }
      }
  };
  const ErrorModel = {
      type: {
          name: "Composite",
          className: "ErrorModel",
          modelProperties: {
              code: {
                  serializedName: "code",
                  readOnly: true,
                  type: {
                      name: "String"
                  }
              },
              message: {
                  serializedName: "message",
                  readOnly: true,
                  type: {
                      name: "String"
                  }
              },
              innerError: {
                  serializedName: "innererror",
                  type: {
                      name: "Composite",
                      className: "ErrorModel"
                  }
              }
          }
      }
  };
  const KeyImportParameters = {
      type: {
          name: "Composite",
          className: "KeyImportParameters",
          modelProperties: {
              hsm: {
                  serializedName: "Hsm",
                  type: {
                      name: "Boolean"
                  }
              },
              key: {
                  serializedName: "key",
                  type: {
                      name: "Composite",
                      className: "JsonWebKey"
                  }
              },
              keyAttributes: {
                  serializedName: "attributes",
                  type: {
                      name: "Composite",
                      className: "KeyAttributes"
                  }
              },
              tags: {
                  serializedName: "tags",
                  type: {
                      name: "Dictionary",
                      value: { type: { name: "String" } }
                  }
              }
          }
      }
  };
  const KeyUpdateParameters = {
      type: {
          name: "Composite",
          className: "KeyUpdateParameters",
          modelProperties: {
              keyOps: {
                  serializedName: "key_ops",
                  type: {
                      name: "Sequence",
                      element: {
                          type: {
                              name: "String"
                          }
                      }
                  }
              },
              keyAttributes: {
                  serializedName: "attributes",
                  type: {
                      name: "Composite",
                      className: "KeyAttributes"
                  }
              },
              tags: {
                  serializedName: "tags",
                  type: {
                      name: "Dictionary",
                      value: { type: { name: "String" } }
                  }
              }
          }
      }
  };
  const KeyListResult = {
      type: {
          name: "Composite",
          className: "KeyListResult",
          modelProperties: {
              value: {
                  serializedName: "value",
                  readOnly: true,
                  type: {
                      name: "Sequence",
                      element: {
                          type: {
                              name: "Composite",
                              className: "KeyItem"
                          }
                      }
                  }
              },
              nextLink: {
                  serializedName: "nextLink",
                  readOnly: true,
                  type: {
                      name: "String"
                  }
              }
          }
      }
  };
  const KeyItem = {
      type: {
          name: "Composite",
          className: "KeyItem",
          modelProperties: {
              kid: {
                  serializedName: "kid",
                  type: {
                      name: "String"
                  }
              },
              attributes: {
                  serializedName: "attributes",
                  type: {
                      name: "Composite",
                      className: "KeyAttributes"
                  }
              },
              tags: {
                  serializedName: "tags",
                  type: {
                      name: "Dictionary",
                      value: { type: { name: "String" } }
                  }
              },
              managed: {
                  serializedName: "managed",
                  readOnly: true,
                  type: {
                      name: "Boolean"
                  }
              }
          }
      }
  };
  const BackupKeyResult = {
      type: {
          name: "Composite",
          className: "BackupKeyResult",
          modelProperties: {
              value: {
                  serializedName: "value",
                  readOnly: true,
                  type: {
                      name: "Base64Url"
                  }
              }
          }
      }
  };
  const KeyRestoreParameters = {
      type: {
          name: "Composite",
          className: "KeyRestoreParameters",
          modelProperties: {
              keyBundleBackup: {
                  serializedName: "value",
                  required: true,
                  type: {
                      name: "Base64Url"
                  }
              }
          }
      }
  };
  const KeyOperationsParameters = {
      type: {
          name: "Composite",
          className: "KeyOperationsParameters",
          modelProperties: {
              algorithm: {
                  serializedName: "alg",
                  required: true,
                  type: {
                      name: "String"
                  }
              },
              value: {
                  serializedName: "value",
                  required: true,
                  type: {
                      name: "Base64Url"
                  }
              },
              iv: {
                  serializedName: "iv",
                  type: {
                      name: "Base64Url"
                  }
              },
              additionalAuthenticatedData: {
                  serializedName: "aad",
                  type: {
                      name: "Base64Url"
                  }
              },
              authenticationTag: {
                  serializedName: "tag",
                  type: {
                      name: "Base64Url"
                  }
              }
          }
      }
  };
  const KeyOperationResult = {
      type: {
          name: "Composite",
          className: "KeyOperationResult",
          modelProperties: {
              kid: {
                  serializedName: "kid",
                  readOnly: true,
                  type: {
                      name: "String"
                  }
              },
              result: {
                  serializedName: "value",
                  readOnly: true,
                  type: {
                      name: "Base64Url"
                  }
              },
              iv: {
                  serializedName: "iv",
                  readOnly: true,
                  type: {
                      name: "Base64Url"
                  }
              },
              authenticationTag: {
                  serializedName: "tag",
                  readOnly: true,
                  type: {
                      name: "Base64Url"
                  }
              },
              additionalAuthenticatedData: {
                  serializedName: "aad",
                  readOnly: true,
                  type: {
                      name: "Base64Url"
                  }
              }
          }
      }
  };
  const KeySignParameters = {
      type: {
          name: "Composite",
          className: "KeySignParameters",
          modelProperties: {
              algorithm: {
                  serializedName: "alg",
                  required: true,
                  type: {
                      name: "String"
                  }
              },
              value: {
                  serializedName: "value",
                  required: true,
                  type: {
                      name: "Base64Url"
                  }
              }
          }
      }
  };
  const KeyVerifyParameters = {
      type: {
          name: "Composite",
          className: "KeyVerifyParameters",
          modelProperties: {
              algorithm: {
                  serializedName: "alg",
                  required: true,
                  type: {
                      name: "String"
                  }
              },
              digest: {
                  serializedName: "digest",
                  required: true,
                  type: {
                      name: "Base64Url"
                  }
              },
              signature: {
                  serializedName: "value",
                  required: true,
                  type: {
                      name: "Base64Url"
                  }
              }
          }
      }
  };
  const KeyVerifyResult = {
      type: {
          name: "Composite",
          className: "KeyVerifyResult",
          modelProperties: {
              value: {
                  serializedName: "value",
                  readOnly: true,
                  type: {
                      name: "Boolean"
                  }
              }
          }
      }
  };
  const DeletedKeyListResult = {
      type: {
          name: "Composite",
          className: "DeletedKeyListResult",
          modelProperties: {
              value: {
                  serializedName: "value",
                  readOnly: true,
                  type: {
                      name: "Sequence",
                      element: {
                          type: {
                              name: "Composite",
                              className: "DeletedKeyItem"
                          }
                      }
                  }
              },
              nextLink: {
                  serializedName: "nextLink",
                  readOnly: true,
                  type: {
                      name: "String"
                  }
              }
          }
      }
  };
  const KeyProperties = {
      type: {
          name: "Composite",
          className: "KeyProperties",
          modelProperties: {
              exportable: {
                  serializedName: "exportable",
                  type: {
                      name: "Boolean"
                  }
              },
              keyType: {
                  serializedName: "kty",
                  type: {
                      name: "String"
                  }
              },
              keySize: {
                  serializedName: "key_size",
                  type: {
                      name: "Number"
                  }
              },
              reuseKey: {
                  serializedName: "reuse_key",
                  type: {
                      name: "Boolean"
                  }
              },
              curve: {
                  serializedName: "crv",
                  type: {
                      name: "String"
                  }
              }
          }
      }
  };
  const KeyAttributes = {
      type: {
          name: "Composite",
          className: "KeyAttributes",
          modelProperties: Object.assign(Object.assign({}, Attributes.type.modelProperties), { recoverableDays: {
                  serializedName: "recoverableDays",
                  readOnly: true,
                  type: {
                      name: "Number"
                  }
              }, recoveryLevel: {
                  serializedName: "recoveryLevel",
                  readOnly: true,
                  type: {
                      name: "String"
                  }
              } })
      }
  };
  const DeletedKeyBundle = {
      type: {
          name: "Composite",
          className: "DeletedKeyBundle",
          modelProperties: Object.assign(Object.assign({}, KeyBundle.type.modelProperties), { recoveryId: {
                  serializedName: "recoveryId",
                  type: {
                      name: "String"
                  }
              }, scheduledPurgeDate: {
                  serializedName: "scheduledPurgeDate",
                  readOnly: true,
                  type: {
                      name: "UnixTime"
                  }
              }, deletedDate: {
                  serializedName: "deletedDate",
                  readOnly: true,
                  type: {
                      name: "UnixTime"
                  }
              } })
      }
  };
  const DeletedKeyItem = {
      type: {
          name: "Composite",
          className: "DeletedKeyItem",
          modelProperties: Object.assign(Object.assign({}, KeyItem.type.modelProperties), { recoveryId: {
                  serializedName: "recoveryId",
                  type: {
                      name: "String"
                  }
              }, scheduledPurgeDate: {
                  serializedName: "scheduledPurgeDate",
                  readOnly: true,
                  type: {
                      name: "UnixTime"
                  }
              }, deletedDate: {
                  serializedName: "deletedDate",
                  readOnly: true,
                  type: {
                      name: "UnixTime"
                  }
              } })
      }
  };
  
  var Mappers = /*#__PURE__*/Object.freeze({
      __proto__: null,
      KeyCreateParameters: KeyCreateParameters,
      Attributes: Attributes,
      KeyBundle: KeyBundle,
      JsonWebKey: JsonWebKey,
      KeyVaultError: KeyVaultError,
      ErrorModel: ErrorModel,
      KeyImportParameters: KeyImportParameters,
      KeyUpdateParameters: KeyUpdateParameters,
      KeyListResult: KeyListResult,
      KeyItem: KeyItem,
      BackupKeyResult: BackupKeyResult,
      KeyRestoreParameters: KeyRestoreParameters,
      KeyOperationsParameters: KeyOperationsParameters,
      KeyOperationResult: KeyOperationResult,
      KeySignParameters: KeySignParameters,
      KeyVerifyParameters: KeyVerifyParameters,
      KeyVerifyResult: KeyVerifyResult,
      DeletedKeyListResult: DeletedKeyListResult,
      KeyProperties: KeyProperties,
      KeyAttributes: KeyAttributes,
      DeletedKeyBundle: DeletedKeyBundle,
      DeletedKeyItem: DeletedKeyItem
  });
  
  /*
   * Copyright (c) Microsoft Corporation.
   * Licensed under the MIT License.
   *
   * Code generated by Microsoft (R) AutoRest Code Generator.
   * Changes may cause incorrect behavior and will be lost if the code is regenerated.
   */
  const contentType = {
      parameterPath: ["options", "contentType"],
      mapper: {
          defaultValue: "application/json",
          isConstant: true,
          serializedName: "Content-Type",
          type: {
              name: "String"
          }
      }
  };
  const accept = {
      parameterPath: "accept",
      mapper: {
          defaultValue: "application/json",
          isConstant: true,
          serializedName: "Accept",
          type: {
              name: "String"
          }
      }
  };
  const vaultBaseUrl = {
      parameterPath: "vaultBaseUrl",
      mapper: {
          serializedName: "vaultBaseUrl",
          required: true,
          type: {
              name: "String"
          }
      },
      skipEncoding: true
  };
  const keyName = {
      parameterPath: "keyName",
      mapper: {
          constraints: {
              Pattern: new RegExp("^[0-9a-zA-Z-]+$")
          },
          serializedName: "key-name",
          required: true,
          type: {
              name: "String"
          }
      }
  };
  const apiVersion = {
      parameterPath: "apiVersion",
      mapper: {
          serializedName: "api-version",
          required: true,
          type: {
              name: "String"
          }
      }
  };
  const keyName1 = {
      parameterPath: "keyName",
      mapper: {
          serializedName: "key-name",
          required: true,
          type: {
              name: "String"
          }
      }
  };
  const keyVersion = {
      parameterPath: "keyVersion",
      mapper: {
          serializedName: "key-version",
          required: true,
          type: {
              name: "String"
          }
      }
  };
  const maxresults = {
      parameterPath: ["options", "maxresults"],
      mapper: {
          constraints: {
              InclusiveMaximum: 25,
              InclusiveMinimum: 1
          },
          serializedName: "maxresults",
          type: {
              name: "Number"
          }
      }
  };
  const nextLink = {
      parameterPath: "nextLink",
      mapper: {
          serializedName: "nextLink",
          required: true,
          type: {
              name: "String"
          }
      },
      skipEncoding: true
  };
  
  /*
   * Copyright (c) Microsoft Corporation.
   * Licensed under the MIT License.
   *
   * Code generated by Microsoft (R) AutoRest Code Generator.
   * Changes may cause incorrect behavior and will be lost if the code is regenerated.
   */
  const packageName = "@azure/keyvault-keys";
  const packageVersion = "4.3.0";
  /** @hidden */
  class KeyVaultClientContext extends coreHttp.ServiceClient {
      /**
       * Initializes a new instance of the KeyVaultClientContext class.
       * @param apiVersion Api Version
       * @param options The parameter options
       */
      constructor(apiVersion, options) {
          if (apiVersion === undefined) {
              throw new Error("'apiVersion' cannot be null");
          }
          // Initializing default values for options
          if (!options) {
              options = {};
          }
          if (!options.userAgent) {
              const defaultUserAgent = coreHttp.getDefaultUserAgentValue();
              options.userAgent = `${packageName}/${packageVersion} ${defaultUserAgent}`;
          }
          super(undefined, options);
          this.requestContentType = "application/json; charset=utf-8";
          this.baseUri = options.endpoint || "{vaultBaseUrl}";
          // Parameter assignments
          this.apiVersion = apiVersion;
      }
  }
  
  /*
   * Copyright (c) Microsoft Corporation.
   * Licensed under the MIT License.
   *
   * Code generated by Microsoft (R) AutoRest Code Generator.
   * Changes may cause incorrect behavior and will be lost if the code is regenerated.
   */
  /** @hidden */
  class KeyVaultClient extends KeyVaultClientContext {
      /**
       * Initializes a new instance of the KeyVaultClient class.
       * @param apiVersion Api Version
       * @param options The parameter options
       */
      constructor(apiVersion, options) {
          super(apiVersion, options);
      }
      /**
       * The create key operation can be used to create any key type in Azure Key Vault. If the named key
       * already exists, Azure Key Vault creates a new version of the key. It requires the keys/create
       * permission.
       * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
       * @param keyName The name for the new key. The system will generate the version name for the new key.
       * @param kty The type of key to create. For valid values, see JsonWebKeyType.
       * @param options The options parameters.
       */
      createKey(vaultBaseUrl, keyName, kty, options) {
          const operationArguments = {
              vaultBaseUrl,
              keyName,
              kty,
              options: coreHttp.operationOptionsToRequestOptionsBase(options || {})
          };
          return this.sendOperationRequest(operationArguments, createKeyOperationSpec);
      }
      /**
       * The import key operation may be used to import any key type into an Azure Key Vault. If the named
       * key already exists, Azure Key Vault creates a new version of the key. This operation requires the
       * keys/import permission.
       * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
       * @param keyName Name for the imported key.
       * @param key The Json web key
       * @param options The options parameters.
       */
      importKey(vaultBaseUrl, keyName, key, options) {
          const operationArguments = {
              vaultBaseUrl,
              keyName,
              key,
              options: coreHttp.operationOptionsToRequestOptionsBase(options || {})
          };
          return this.sendOperationRequest(operationArguments, importKeyOperationSpec);
      }
      /**
       * The delete key operation cannot be used to remove individual versions of a key. This operation
       * removes the cryptographic material associated with the key, which means the key is not usable for
       * Sign/Verify, Wrap/Unwrap or Encrypt/Decrypt operations. This operation requires the keys/delete
       * permission.
       * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
       * @param keyName The name of the key to delete.
       * @param options The options parameters.
       */
      deleteKey(vaultBaseUrl, keyName, options) {
          const operationArguments = {
              vaultBaseUrl,
              keyName,
              options: coreHttp.operationOptionsToRequestOptionsBase(options || {})
          };
          return this.sendOperationRequest(operationArguments, deleteKeyOperationSpec);
      }
      /**
       * In order to perform this operation, the key must already exist in the Key Vault. Note: The
       * cryptographic material of a key itself cannot be changed. This operation requires the keys/update
       * permission.
       * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
       * @param keyName The name of key to update.
       * @param keyVersion The version of the key to update.
       * @param options The options parameters.
       */
      updateKey(vaultBaseUrl, keyName, keyVersion, options) {
          const operationArguments = {
              vaultBaseUrl,
              keyName,
              keyVersion,
              options: coreHttp.operationOptionsToRequestOptionsBase(options || {})
          };
          return this.sendOperationRequest(operationArguments, updateKeyOperationSpec);
      }
      /**
       * The get key operation is applicable to all key types. If the requested key is symmetric, then no key
       * material is released in the response. This operation requires the keys/get permission.
       * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
       * @param keyName The name of the key to get.
       * @param keyVersion Adding the version parameter retrieves a specific version of a key. This URI
       *                   fragment is optional. If not specified, the latest version of the key is returned.
       * @param options The options parameters.
       */
      getKey(vaultBaseUrl, keyName, keyVersion, options) {
          const operationArguments = {
              vaultBaseUrl,
              keyName,
              keyVersion,
              options: coreHttp.operationOptionsToRequestOptionsBase(options || {})
          };
          return this.sendOperationRequest(operationArguments, getKeyOperationSpec);
      }
      /**
       * The full key identifier, attributes, and tags are provided in the response. This operation requires
       * the keys/list permission.
       * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
       * @param keyName The name of the key.
       * @param options The options parameters.
       */
      getKeyVersions(vaultBaseUrl, keyName, options) {
          const operationArguments = {
              vaultBaseUrl,
              keyName,
              options: coreHttp.operationOptionsToRequestOptionsBase(options || {})
          };
          return this.sendOperationRequest(operationArguments, getKeyVersionsOperationSpec);
      }
      /**
       * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public
       * part of a stored key. The LIST operation is applicable to all key types, however only the base key
       * identifier, attributes, and tags are provided in the response. Individual versions of a key are not
       * listed in the response. This operation requires the keys/list permission.
       * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
       * @param options The options parameters.
       */
      getKeys(vaultBaseUrl, options) {
          const operationArguments = {
              vaultBaseUrl,
              options: coreHttp.operationOptionsToRequestOptionsBase(options || {})
          };
          return this.sendOperationRequest(operationArguments, getKeysOperationSpec);
      }
      /**
       * The Key Backup operation exports a key from Azure Key Vault in a protected form. Note that this
       * operation does NOT return key material in a form that can be used outside the Azure Key Vault
       * system, the returned key material is either protected to a Azure Key Vault HSM or to Azure Key Vault
       * itself. The intent of this operation is to allow a client to GENERATE a key in one Azure Key Vault
       * instance, BACKUP the key, and then RESTORE it into another Azure Key Vault instance. The BACKUP
       * operation may be used to export, in protected form, any key type from Azure Key Vault. Individual
       * versions of a key cannot be backed up. BACKUP / RESTORE can be performed within geographical
       * boundaries only; meaning that a BACKUP from one geographical area cannot be restored to another
       * geographical area. For example, a backup from the US geographical area cannot be restored in an EU
       * geographical area. This operation requires the key/backup permission.
       * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
       * @param keyName The name of the key.
       * @param options The options parameters.
       */
      backupKey(vaultBaseUrl, keyName, options) {
          const operationArguments = {
              vaultBaseUrl,
              keyName,
              options: coreHttp.operationOptionsToRequestOptionsBase(options || {})
          };
          return this.sendOperationRequest(operationArguments, backupKeyOperationSpec);
      }
      /**
       * Imports a previously backed up key into Azure Key Vault, restoring the key, its key identifier,
       * attributes and access control policies. The RESTORE operation may be used to import a previously
       * backed up key. Individual versions of a key cannot be restored. The key is restored in its entirety
       * with the same key name as it had when it was backed up. If the key name is not available in the
       * target Key Vault, the RESTORE operation will be rejected. While the key name is retained during
       * restore, the final key identifier will change if the key is restored to a different vault. Restore
       * will restore all versions and preserve version identifiers. The RESTORE operation is subject to
       * security constraints: The target Key Vault must be owned by the same Microsoft Azure Subscription as
       * the source Key Vault The user must have RESTORE permission in the target Key Vault. This operation
       * requires the keys/restore permission.
       * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
       * @param keyBundleBackup The backup blob associated with a key bundle.
       * @param options The options parameters.
       */
      restoreKey(vaultBaseUrl, keyBundleBackup, options) {
          const operationArguments = {
              vaultBaseUrl,
              keyBundleBackup,
              options: coreHttp.operationOptionsToRequestOptionsBase(options || {})
          };
          return this.sendOperationRequest(operationArguments, restoreKeyOperationSpec);
      }
      /**
       * The ENCRYPT operation encrypts an arbitrary sequence of bytes using an encryption key that is stored
       * in Azure Key Vault. Note that the ENCRYPT operation only supports a single block of data, the size
       * of which is dependent on the target key and the encryption algorithm to be used. The ENCRYPT
       * operation is only strictly necessary for symmetric keys stored in Azure Key Vault since protection
       * with an asymmetric key can be performed using public portion of the key. This operation is supported
       * for asymmetric keys as a convenience for callers that have a key-reference but do not have access to
       * the public key material. This operation requires the keys/encrypt permission.
       * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
       * @param keyName The name of the key.
       * @param keyVersion The version of the key.
       * @param algorithm algorithm identifier
       * @param value
       * @param options The options parameters.
       */
      encrypt(vaultBaseUrl, keyName, keyVersion, algorithm, value, options) {
          const operationArguments = {
              vaultBaseUrl,
              keyName,
              keyVersion,
              algorithm,
              value,
              options: coreHttp.operationOptionsToRequestOptionsBase(options || {})
          };
          return this.sendOperationRequest(operationArguments, encryptOperationSpec);
      }
      /**
       * The DECRYPT operation decrypts a well-formed block of ciphertext using the target encryption key and
       * specified algorithm. This operation is the reverse of the ENCRYPT operation; only a single block of
       * data may be decrypted, the size of this block is dependent on the target key and the algorithm to be
       * used. The DECRYPT operation applies to asymmetric and symmetric keys stored in Azure Key Vault since
       * it uses the private portion of the key. This operation requires the keys/decrypt permission.
       * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
       * @param keyName The name of the key.
       * @param keyVersion The version of the key.
       * @param algorithm algorithm identifier
       * @param value
       * @param options The options parameters.
       */
      decrypt(vaultBaseUrl, keyName, keyVersion, algorithm, value, options) {
          const operationArguments = {
              vaultBaseUrl,
              keyName,
              keyVersion,
              algorithm,
              value,
              options: coreHttp.operationOptionsToRequestOptionsBase(options || {})
          };
          return this.sendOperationRequest(operationArguments, decryptOperationSpec);
      }
      /**
       * The SIGN operation is applicable to asymmetric and symmetric keys stored in Azure Key Vault since
       * this operation uses the private portion of the key. This operation requires the keys/sign
       * permission.
       * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
       * @param keyName The name of the key.
       * @param keyVersion The version of the key.
       * @param algorithm The signing/verification algorithm identifier. For more information on possible
       *                  algorithm types, see JsonWebKeySignatureAlgorithm.
       * @param value
       * @param options The options parameters.
       */
      sign(vaultBaseUrl, keyName, keyVersion, algorithm, value, options) {
          const operationArguments = {
              vaultBaseUrl,
              keyName,
              keyVersion,
              algorithm,
              value,
              options: coreHttp.operationOptionsToRequestOptionsBase(options || {})
          };
          return this.sendOperationRequest(operationArguments, signOperationSpec);
      }
      /**
       * The VERIFY operation is applicable to symmetric keys stored in Azure Key Vault. VERIFY is not
       * strictly necessary for asymmetric keys stored in Azure Key Vault since signature verification can be
       * performed using the public portion of the key but this operation is supported as a convenience for
       * callers that only have a key-reference and not the public portion of the key. This operation
       * requires the keys/verify permission.
       * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
       * @param keyName The name of the key.
       * @param keyVersion The version of the key.
       * @param algorithm The signing/verification algorithm. For more information on possible algorithm
       *                  types, see JsonWebKeySignatureAlgorithm.
       * @param digest The digest used for signing.
       * @param signature The signature to be verified.
       * @param options The options parameters.
       */
      verify(vaultBaseUrl, keyName, keyVersion, algorithm, digest, signature, options) {
          const operationArguments = {
              vaultBaseUrl,
              keyName,
              keyVersion,
              algorithm,
              digest,
              signature,
              options: coreHttp.operationOptionsToRequestOptionsBase(options || {})
          };
          return this.sendOperationRequest(operationArguments, verifyOperationSpec);
      }
      /**
       * The WRAP operation supports encryption of a symmetric key using a key encryption key that has
       * previously been stored in an Azure Key Vault. The WRAP operation is only strictly necessary for
       * symmetric keys stored in Azure Key Vault since protection with an asymmetric key can be performed
       * using the public portion of the key. This operation is supported for asymmetric keys as a
       * convenience for callers that have a key-reference but do not have access to the public key material.
       * This operation requires the keys/wrapKey permission.
       * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
       * @param keyName The name of the key.
       * @param keyVersion The version of the key.
       * @param algorithm algorithm identifier
       * @param value
       * @param options The options parameters.
       */
      wrapKey(vaultBaseUrl, keyName, keyVersion, algorithm, value, options) {
          const operationArguments = {
              vaultBaseUrl,
              keyName,
              keyVersion,
              algorithm,
              value,
              options: coreHttp.operationOptionsToRequestOptionsBase(options || {})
          };
          return this.sendOperationRequest(operationArguments, wrapKeyOperationSpec);
      }
      /**
       * The UNWRAP operation supports decryption of a symmetric key using the target key encryption key.
       * This operation is the reverse of the WRAP operation. The UNWRAP operation applies to asymmetric and
       * symmetric keys stored in Azure Key Vault since it uses the private portion of the key. This
       * operation requires the keys/unwrapKey permission.
       * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
       * @param keyName The name of the key.
       * @param keyVersion The version of the key.
       * @param algorithm algorithm identifier
       * @param value
       * @param options The options parameters.
       */
      unwrapKey(vaultBaseUrl, keyName, keyVersion, algorithm, value, options) {
          const operationArguments = {
              vaultBaseUrl,
              keyName,
              keyVersion,
              algorithm,
              value,
              options: coreHttp.operationOptionsToRequestOptionsBase(options || {})
          };
          return this.sendOperationRequest(operationArguments, unwrapKeyOperationSpec);
      }
      /**
       * Retrieves a list of the keys in the Key Vault as JSON Web Key structures that contain the public
       * part of a deleted key. This operation includes deletion-specific information. The Get Deleted Keys
       * operation is applicable for vaults enabled for soft-delete. While the operation can be invoked on
       * any vault, it will return an error if invoked on a non soft-delete enabled vault. This operation
       * requires the keys/list permission.
       * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
       * @param options The options parameters.
       */
      getDeletedKeys(vaultBaseUrl, options) {
          const operationArguments = {
              vaultBaseUrl,
              options: coreHttp.operationOptionsToRequestOptionsBase(options || {})
          };
          return this.sendOperationRequest(operationArguments, getDeletedKeysOperationSpec);
      }
      /**
       * The Get Deleted Key operation is applicable for soft-delete enabled vaults. While the operation can
       * be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault. This
       * operation requires the keys/get permission.
       * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
       * @param keyName The name of the key.
       * @param options The options parameters.
       */
      getDeletedKey(vaultBaseUrl, keyName, options) {
          const operationArguments = {
              vaultBaseUrl,
              keyName,
              options: coreHttp.operationOptionsToRequestOptionsBase(options || {})
          };
          return this.sendOperationRequest(operationArguments, getDeletedKeyOperationSpec);
      }
      /**
       * The Purge Deleted Key operation is applicable for soft-delete enabled vaults. While the operation
       * can be invoked on any vault, it will return an error if invoked on a non soft-delete enabled vault.
       * This operation requires the keys/purge permission.
       * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
       * @param keyName The name of the key
       * @param options The options parameters.
       */
      purgeDeletedKey(vaultBaseUrl, keyName, options) {
          const operationArguments = {
              vaultBaseUrl,
              keyName,
              options: coreHttp.operationOptionsToRequestOptionsBase(options || {})
          };
          return this.sendOperationRequest(operationArguments, purgeDeletedKeyOperationSpec);
      }
      /**
       * The Recover Deleted Key operation is applicable for deleted keys in soft-delete enabled vaults. It
       * recovers the deleted key back to its latest version under /keys. An attempt to recover an
       * non-deleted key will return an error. Consider this the inverse of the delete operation on
       * soft-delete enabled vaults. This operation requires the keys/recover permission.
       * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
       * @param keyName The name of the deleted key.
       * @param options The options parameters.
       */
      recoverDeletedKey(vaultBaseUrl, keyName, options) {
          const operationArguments = {
              vaultBaseUrl,
              keyName,
              options: coreHttp.operationOptionsToRequestOptionsBase(options || {})
          };
          return this.sendOperationRequest(operationArguments, recoverDeletedKeyOperationSpec);
      }
      /**
       * GetKeyVersionsNext
       * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
       * @param keyName The name of the key.
       * @param nextLink The nextLink from the previous successful call to the GetKeyVersions method.
       * @param options The options parameters.
       */
      getKeyVersionsNext(vaultBaseUrl, keyName, nextLink, options) {
          const operationArguments = {
              vaultBaseUrl,
              keyName,
              nextLink,
              options: coreHttp.operationOptionsToRequestOptionsBase(options || {})
          };
          return this.sendOperationRequest(operationArguments, getKeyVersionsNextOperationSpec);
      }
      /**
       * GetKeysNext
       * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
       * @param nextLink The nextLink from the previous successful call to the GetKeys method.
       * @param options The options parameters.
       */
      getKeysNext(vaultBaseUrl, nextLink, options) {
          const operationArguments = {
              vaultBaseUrl,
              nextLink,
              options: coreHttp.operationOptionsToRequestOptionsBase(options || {})
          };
          return this.sendOperationRequest(operationArguments, getKeysNextOperationSpec);
      }
      /**
       * GetDeletedKeysNext
       * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
       * @param nextLink The nextLink from the previous successful call to the GetDeletedKeys method.
       * @param options The options parameters.
       */
      getDeletedKeysNext(vaultBaseUrl, nextLink, options) {
          const operationArguments = {
              vaultBaseUrl,
              nextLink,
              options: coreHttp.operationOptionsToRequestOptionsBase(options || {})
          };
          return this.sendOperationRequest(operationArguments, getDeletedKeysNextOperationSpec);
      }
  }
  // Operation Specifications
  const serializer = new coreHttp.Serializer(Mappers, /* isXml */ false);
  const createKeyOperationSpec = {
      path: "/keys/{key-name}/create",
      httpMethod: "POST",
      responses: {
          200: {
              bodyMapper: KeyBundle
          },
          default: {
              bodyMapper: KeyVaultError
          }
      },
      requestBody: {
          parameterPath: {
              kty: ["kty"],
              keySize: ["options", "keySize"],
              publicExponent: ["options", "publicExponent"],
              keyOps: ["options", "keyOps"],
              keyAttributes: ["options", "keyAttributes"],
              tags: ["options", "tags"],
              curve: ["options", "curve"]
          },
          mapper: KeyCreateParameters
      },
      queryParameters: [apiVersion],
      urlParameters: [vaultBaseUrl, keyName],
      headerParameters: [contentType, accept],
      mediaType: "json",
      serializer
  };
  const importKeyOperationSpec = {
      path: "/keys/{key-name}",
      httpMethod: "PUT",
      responses: {
          200: {
              bodyMapper: KeyBundle
          },
          default: {
              bodyMapper: KeyVaultError
          }
      },
      requestBody: {
          parameterPath: {
              hsm: ["options", "hsm"],
              key: ["key"],
              keyAttributes: ["options", "keyAttributes"],
              tags: ["options", "tags"]
          },
          mapper: KeyImportParameters
      },
      queryParameters: [apiVersion],
      urlParameters: [vaultBaseUrl, keyName],
      headerParameters: [contentType, accept],
      mediaType: "json",
      serializer
  };
  const deleteKeyOperationSpec = {
      path: "/keys/{key-name}",
      httpMethod: "DELETE",
      responses: {
          200: {
              bodyMapper: DeletedKeyBundle
          },
          default: {
              bodyMapper: KeyVaultError
          }
      },
      queryParameters: [apiVersion],
      urlParameters: [vaultBaseUrl, keyName1],
      headerParameters: [accept],
      serializer
  };
  const updateKeyOperationSpec = {
      path: "/keys/{key-name}/{key-version}",
      httpMethod: "PATCH",
      responses: {
          200: {
              bodyMapper: KeyBundle
          },
          default: {
              bodyMapper: KeyVaultError
          }
      },
      requestBody: {
          parameterPath: {
              keyOps: ["options", "keyOps"],
              keyAttributes: ["options", "keyAttributes"],
              tags: ["options", "tags"]
          },
          mapper: KeyUpdateParameters
      },
      queryParameters: [apiVersion],
      urlParameters: [
          vaultBaseUrl,
          keyName1,
          keyVersion
      ],
      headerParameters: [contentType, accept],
      mediaType: "json",
      serializer
  };
  const getKeyOperationSpec = {
      path: "/keys/{key-name}/{key-version}",
      httpMethod: "GET",
      responses: {
          200: {
              bodyMapper: KeyBundle
          },
          default: {
              bodyMapper: KeyVaultError
          }
      },
      queryParameters: [apiVersion],
      urlParameters: [
          vaultBaseUrl,
          keyName1,
          keyVersion
      ],
      headerParameters: [accept],
      serializer
  };
  const getKeyVersionsOperationSpec = {
      path: "/keys/{key-name}/versions",
      httpMethod: "GET",
      responses: {
          200: {
              bodyMapper: KeyListResult
          },
          default: {
              bodyMapper: KeyVaultError
          }
      },
      queryParameters: [apiVersion, maxresults],
      urlParameters: [vaultBaseUrl, keyName1],
      headerParameters: [accept],
      serializer
  };
  const getKeysOperationSpec = {
      path: "/keys",
      httpMethod: "GET",
      responses: {
          200: {
              bodyMapper: KeyListResult
          },
          default: {
              bodyMapper: KeyVaultError
          }
      },
      queryParameters: [apiVersion, maxresults],
      urlParameters: [vaultBaseUrl],
      headerParameters: [accept],
      serializer
  };
  const backupKeyOperationSpec = {
      path: "/keys/{key-name}/backup",
      httpMethod: "POST",
      responses: {
          200: {
              bodyMapper: BackupKeyResult
          },
          default: {
              bodyMapper: KeyVaultError
          }
      },
      queryParameters: [apiVersion],
      urlParameters: [vaultBaseUrl, keyName1],
      headerParameters: [accept],
      serializer
  };
  const restoreKeyOperationSpec = {
      path: "/keys/restore",
      httpMethod: "POST",
      responses: {
          200: {
              bodyMapper: KeyBundle
          },
          default: {
              bodyMapper: KeyVaultError
          }
      },
      requestBody: {
          parameterPath: { keyBundleBackup: ["keyBundleBackup"] },
          mapper: KeyRestoreParameters
      },
      queryParameters: [apiVersion],
      urlParameters: [vaultBaseUrl],
      headerParameters: [contentType, accept],
      mediaType: "json",
      serializer
  };
  const encryptOperationSpec = {
      path: "/keys/{key-name}/{key-version}/encrypt",
      httpMethod: "POST",
      responses: {
          200: {
              bodyMapper: KeyOperationResult
          },
          default: {
              bodyMapper: KeyVaultError
          }
      },
      requestBody: {
          parameterPath: {
              algorithm: ["algorithm"],
              value: ["value"],
              iv: ["options", "iv"],
              additionalAuthenticatedData: ["options", "additionalAuthenticatedData"],
              authenticationTag: ["options", "authenticationTag"]
          },
          mapper: KeyOperationsParameters
      },
      queryParameters: [apiVersion],
      urlParameters: [
          vaultBaseUrl,
          keyName1,
          keyVersion
      ],
      headerParameters: [contentType, accept],
      mediaType: "json",
      serializer
  };
  const decryptOperationSpec = {
      path: "/keys/{key-name}/{key-version}/decrypt",
      httpMethod: "POST",
      responses: {
          200: {
              bodyMapper: KeyOperationResult
          },
          default: {
              bodyMapper: KeyVaultError
          }
      },
      requestBody: {
          parameterPath: {
              algorithm: ["algorithm"],
              value: ["value"],
              iv: ["options", "iv"],
              additionalAuthenticatedData: ["options", "additionalAuthenticatedData"],
              authenticationTag: ["options", "authenticationTag"]
          },
          mapper: KeyOperationsParameters
      },
      queryParameters: [apiVersion],
      urlParameters: [
          vaultBaseUrl,
          keyName1,
          keyVersion
      ],
      headerParameters: [contentType, accept],
      mediaType: "json",
      serializer
  };
  const signOperationSpec = {
      path: "/keys/{key-name}/{key-version}/sign",
      httpMethod: "POST",
      responses: {
          200: {
              bodyMapper: KeyOperationResult
          },
          default: {
              bodyMapper: KeyVaultError
          }
      },
      requestBody: {
          parameterPath: { algorithm: ["algorithm"], value: ["value"] },
          mapper: KeySignParameters
      },
      queryParameters: [apiVersion],
      urlParameters: [
          vaultBaseUrl,
          keyName1,
          keyVersion
      ],
      headerParameters: [contentType, accept],
      mediaType: "json",
      serializer
  };
  const verifyOperationSpec = {
      path: "/keys/{key-name}/{key-version}/verify",
      httpMethod: "POST",
      responses: {
          200: {
              bodyMapper: KeyVerifyResult
          },
          default: {
              bodyMapper: KeyVaultError
          }
      },
      requestBody: {
          parameterPath: {
              algorithm: ["algorithm"],
              digest: ["digest"],
              signature: ["signature"]
          },
          mapper: KeyVerifyParameters
      },
      queryParameters: [apiVersion],
      urlParameters: [
          vaultBaseUrl,
          keyName1,
          keyVersion
      ],
      headerParameters: [contentType, accept],
      mediaType: "json",
      serializer
  };
  const wrapKeyOperationSpec = {
      path: "/keys/{key-name}/{key-version}/wrapkey",
      httpMethod: "POST",
      responses: {
          200: {
              bodyMapper: KeyOperationResult
          },
          default: {
              bodyMapper: KeyVaultError
          }
      },
      requestBody: {
          parameterPath: {
              algorithm: ["algorithm"],
              value: ["value"],
              iv: ["options", "iv"],
              additionalAuthenticatedData: ["options", "additionalAuthenticatedData"],
              authenticationTag: ["options", "authenticationTag"]
          },
          mapper: KeyOperationsParameters
      },
      queryParameters: [apiVersion],
      urlParameters: [
          vaultBaseUrl,
          keyName1,
          keyVersion
      ],
      headerParameters: [contentType, accept],
      mediaType: "json",
      serializer
  };
  const unwrapKeyOperationSpec = {
      path: "/keys/{key-name}/{key-version}/unwrapkey",
      httpMethod: "POST",
      responses: {
          200: {
              bodyMapper: KeyOperationResult
          },
          default: {
              bodyMapper: KeyVaultError
          }
      },
      requestBody: {
          parameterPath: {
              algorithm: ["algorithm"],
              value: ["value"],
              iv: ["options", "iv"],
              additionalAuthenticatedData: ["options", "additionalAuthenticatedData"],
              authenticationTag: ["options", "authenticationTag"]
          },
          mapper: KeyOperationsParameters
      },
      queryParameters: [apiVersion],
      urlParameters: [
          vaultBaseUrl,
          keyName1,
          keyVersion
      ],
      headerParameters: [contentType, accept],
      mediaType: "json",
      serializer
  };
  const getDeletedKeysOperationSpec = {
      path: "/deletedkeys",
      httpMethod: "GET",
      responses: {
          200: {
              bodyMapper: DeletedKeyListResult
          },
          default: {
              bodyMapper: KeyVaultError
          }
      },
      queryParameters: [apiVersion, maxresults],
      urlParameters: [vaultBaseUrl],
      headerParameters: [accept],
      serializer
  };
  const getDeletedKeyOperationSpec = {
      path: "/deletedkeys/{key-name}",
      httpMethod: "GET",
      responses: {
          200: {
              bodyMapper: DeletedKeyBundle
          },
          default: {
              bodyMapper: KeyVaultError
          }
      },
      queryParameters: [apiVersion],
      urlParameters: [vaultBaseUrl, keyName1],
      headerParameters: [accept],
      serializer
  };
  const purgeDeletedKeyOperationSpec = {
      path: "/deletedkeys/{key-name}",
      httpMethod: "DELETE",
      responses: {
          204: {},
          default: {
              bodyMapper: KeyVaultError
          }
      },
      queryParameters: [apiVersion],
      urlParameters: [vaultBaseUrl, keyName1],
      headerParameters: [accept],
      serializer
  };
  const recoverDeletedKeyOperationSpec = {
      path: "/deletedkeys/{key-name}/recover",
      httpMethod: "POST",
      responses: {
          200: {
              bodyMapper: KeyBundle
          },
          default: {
              bodyMapper: KeyVaultError
          }
      },
      queryParameters: [apiVersion],
      urlParameters: [vaultBaseUrl, keyName1],
      headerParameters: [accept],
      serializer
  };
  const getKeyVersionsNextOperationSpec = {
      path: "{nextLink}",
      httpMethod: "GET",
      responses: {
          200: {
              bodyMapper: KeyListResult
          },
          default: {
              bodyMapper: KeyVaultError
          }
      },
      queryParameters: [apiVersion, maxresults],
      urlParameters: [
          vaultBaseUrl,
          keyName1,
          nextLink
      ],
      headerParameters: [accept],
      serializer
  };
  const getKeysNextOperationSpec = {
      path: "{nextLink}",
      httpMethod: "GET",
      responses: {
          200: {
              bodyMapper: KeyListResult
          },
          default: {
              bodyMapper: KeyVaultError
          }
      },
      queryParameters: [apiVersion, maxresults],
      urlParameters: [vaultBaseUrl, nextLink],
      headerParameters: [accept],
      serializer
  };
  const getDeletedKeysNextOperationSpec = {
      path: "{nextLink}",
      httpMethod: "GET",
      responses: {
          200: {
              bodyMapper: DeletedKeyListResult
          },
          default: {
              bodyMapper: KeyVaultError
          }
      },
      queryParameters: [apiVersion, maxresults],
      urlParameters: [vaultBaseUrl, nextLink],
      headerParameters: [accept],
      serializer
  };
  
  // Copyright (c) Microsoft Corporation.
  // Licensed under the MIT license.
  const SDK_VERSION = "4.3.0";
  
  // Copyright (c) Microsoft Corporation.
  /**
   * Representation of the Authentication Challenge
   */
  class AuthenticationChallenge {
      constructor(authorization, scope) {
          this.authorization = authorization;
          this.scope = scope;
      }
      /**
       * Checks that this AuthenticationChallenge is equal to another one given.
       * Only compares the scope.
       * This is exactly what C# is doing, as we can see here:
       * https://github.com/Azure/azure-sdk-for-net/blob/70e54b878ff1d01a45266fb3674a396b4ab9c1d2/sdk/keyvault/Azure.Security.KeyVault.Shared/src/ChallengeBasedAuthenticationPolicy.cs#L143-L147
       * @param other - The other AuthenticationChallenge
       */
      equalTo(other) {
          return other
              ? this.scope.toLowerCase() === other.scope.toLowerCase() &&
                  this.authorization.toLowerCase() === other.authorization.toLowerCase()
              : false;
      }
  }
  /**
   * Helps keep a copy of any previous authentication challenges,
   * so that we can compare on any further request.
   */
  class AuthenticationChallengeCache {
      setCachedChallenge(challenge) {
          this.challenge = challenge;
      }
  }
  /**
   * Creates a new ChallengeBasedAuthenticationPolicy factory.
   *
   * @param credential - The TokenCredential implementation that can supply the challenge token.
   */
  function challengeBasedAuthenticationPolicy(credential) {
      const tokenCache = new coreHttp.ExpiringAccessTokenCache();
      const challengeCache = new AuthenticationChallengeCache();
      return {
          create: (nextPolicy, options) => {
              return new ChallengeBasedAuthenticationPolicy(nextPolicy, options, credential, tokenCache, challengeCache);
          }
      };
  }
  /**
   * Parses an WWW-Authenticate response.
   * This transforms a string value like:
   * `Bearer authorization="some_authorization", resource="https://some.url"`
   * into an object like:
   * `{ authorization: "some_authorization", resource: "https://some.url" }`
   * @param wwwAuthenticate - String value in the WWW-Authenticate header
   */
  function parseWWWAuthenticate(wwwAuthenticate) {
      // First we split the string by either `, ` or ` `.
      const parts = wwwAuthenticate.split(/,* +/);
      // Then we only keep the strings with an equal sign after a word and before a quote.
      // also splitting these sections by their equal sign
      const keyValues = parts.reduce((acc, str) => (str.match(/\w="/) ? [...acc, str.split("=")] : acc), []);
      // Then we transform these key-value pairs back into an object.
      const parsed = keyValues.reduce((result, [key, value]) => (Object.assign(Object.assign({}, result), { [key]: value.slice(1, -1) })), {});
      return parsed;
  }
  /**
   *
   * Provides a RequestPolicy that can request a token from a TokenCredential
   * implementation and then apply it to the Authorization header of a request
   * as a Bearer token.
   *
   */
  class ChallengeBasedAuthenticationPolicy extends coreHttp.BaseRequestPolicy {
      /**
       * Creates a new ChallengeBasedAuthenticationPolicy object.
       *
       * @param nextPolicy - The next RequestPolicy in the request pipeline.
       * @param options - Options for this RequestPolicy.
       * @param credential - The TokenCredential implementation that can supply the bearer token.
       * @param tokenCache - The cache for the most recent AccessToken returned by the TokenCredential.
       */
      constructor(nextPolicy, options, credential, tokenCache, challengeCache) {
          super(nextPolicy, options);
          this.credential = credential;
          this.tokenCache = tokenCache;
          this.challengeCache = challengeCache;
          this.parseWWWAuthenticate = parseWWWAuthenticate;
      }
      /**
       * Gets or updates the token from the token cache into the headers of the received web resource.
       */
      async loadToken(webResource) {
          let accessToken = this.tokenCache.getCachedToken();
          // If there's no cached token in the cache, we try to get a new one.
          if (accessToken === undefined) {
              const receivedToken = await this.credential.getToken(this.challengeCache.challenge.scope);
              accessToken = receivedToken || undefined;
              this.tokenCache.setCachedToken(accessToken);
          }
          if (accessToken) {
              webResource.headers.set(coreHttp.Constants.HeaderConstants.AUTHORIZATION, `Bearer ${accessToken.token}`);
          }
      }
      /**
       * Parses the given WWW-Authenticate header, generates a new AuthenticationChallenge,
       * then if the challenge is different from the one cached, resets the token and forces
       * a re-authentication, otherwise continues with the existing challenge and token.
       * @param wwwAuthenticate - Value of the incoming WWW-Authenticate header.
       * @param webResource - Ongoing HTTP request.
       */
      async regenerateChallenge(wwwAuthenticate, webResource) {
          var _a;
          // The challenge based authentication will contain both:
          // - An authorization URI with a token,
          // - The resource to which that token is valid against (also called the scope).
          const parsedWWWAuth = this.parseWWWAuthenticate(wwwAuthenticate);
          const authorization = parsedWWWAuth.authorization;
          const resource = parsedWWWAuth.resource || parsedWWWAuth.scope;
          if (!(authorization && resource)) {
              return this._nextPolicy.sendRequest(webResource);
          }
          const challenge = new AuthenticationChallenge(authorization, resource + "/.default");
          // Either if there's no cached challenge at this point (could have happen in parallel),
          // or if the cached challenge has a different scope,
          // we store the just received challenge and reset the cached token, to force a re-authentication.
          if (!((_a = this.challengeCache.challenge) === null || _a === void 0 ? void 0 : _a.equalTo(challenge))) {
              this.challengeCache.setCachedChallenge(challenge);
              this.tokenCache.setCachedToken(undefined);
          }
          await this.loadToken(webResource);
          return this._nextPolicy.sendRequest(webResource);
      }
      /**
       * Applies the Bearer token to the request through the Authorization header.
       * @param webResource - Ongoing HTTP request.
       */
      async sendRequest(webResource) {
          // Ensure that we're about to use a secure connection.
          if (!webResource.url.startsWith("https:")) {
              throw new Error("The resource address for authorization must use the 'https' protocol.");
          }
          // The next request will happen differently whether we have a challenge or not.
          let response;
          if (this.challengeCache.challenge === undefined ||
              this.challengeCache.challenge === undefined) {
              // If there's no challenge in cache, a blank body will start the challenge.
              const originalBody = webResource.body;
              webResource.body = "";
              try {
                  response = await this._nextPolicy.sendRequest(webResource);
              }
              finally {
                  webResource.body = originalBody;
              }
          }
          else {
              // If we did have a challenge in memory,
              // we attempt to load the token from the cache into the request before we try to send the request.
              await this.loadToken(webResource);
              response = await this._nextPolicy.sendRequest(webResource);
          }
          // If we don't receive a response with a 401 status code,
          // then we can assume this response has nothing to do with the challenge authentication process.
          if (response.status !== 401) {
              return response;
          }
          // If the response status is 401, we only re-authenticate if the WWW-Authenticate header is present.
          const wwwAuthenticate = response.headers.get("WWW-Authenticate");
          if (!wwwAuthenticate) {
              return response;
          }
          // We re-generate the challenge and see if we have to re-authenticate.
          return this.regenerateChallenge(wwwAuthenticate, webResource);
      }
  }
  
  // Copyright (c) Microsoft Corporation.
  function parseKeyvaultIdentifier(collection, identifier) {
      if (typeof collection !== "string" || !(collection = collection.trim())) {
          throw new Error("Invalid collection argument");
      }
      if (typeof identifier !== "string" || !(identifier = identifier.trim())) {
          throw new Error("Invalid identifier argument");
      }
      let baseUri;
      try {
          baseUri = url.parse(identifier, true, true);
      }
      catch (e) {
          throw new Error(`Invalid ${collection} identifier: ${identifier}. Not a valid URI`);
      }
      // Path is of the form '/collection/name[/version]'
      const segments = (baseUri.pathname || "").split("/");
      if (segments.length !== 3 && segments.length !== 4) {
          throw new Error(`Invalid ${collection} identifier: ${identifier}. Bad number of segments: ${segments.length}`);
      }
      if (collection !== segments[1]) {
          throw new Error(`Invalid ${collection} identifier: ${identifier}. segment [1] should be "${collection}", found "${segments[1]}"`);
      }
      const vaultUrl = `${baseUri.protocol}//${baseUri.host}`;
      const name = segments[2];
      const version = segments.length === 4 ? segments[3] : undefined;
      return {
          vaultUrl,
          name,
          version
      };
  }
  
  // Copyright (c) Microsoft Corporation.
  /**
   * Returns a function that can be used for tracing options.
   *
   * @param prefix - The prefix to use, likely the name of the class / client.
   *
   * @example const withTrace = createTraceFunction("Azure.KeyVault.Certificates.CertificateClient")
   *
   * @internal
   */
  function createTraceFunction(prefix) {
      const createSpan = coreTracing.createSpanFunction({
          namespace: "Microsoft.KeyVault",
          packagePrefix: prefix
      });
      return async function (operationName, options, cb) {
          const { updatedOptions, span } = createSpan(operationName, options);
          try {
              // NOTE: we really do need to await on this function here so we can handle any exceptions thrown and properly
              // close the span.
              const result = await cb(updatedOptions, span);
              // otel 0.16+ needs this or else the code ends up being set as UNSET
              span.setStatus({
                  code: coreTracing.SpanStatusCode.OK
              });
              return result;
          }
          catch (err) {
              span.setStatus({
                  code: coreTracing.SpanStatusCode.ERROR,
                  message: err.message
              });
              throw err;
          }
          finally {
              span.end();
          }
      };
  }
  
  // Copyright (c) Microsoft Corporation.
  /**
   * Parses the given Key Vault Key Id. An example is:
   *
   *   https://<keyvault-name>.vault.azure.net/keys/<key-name>/<unique-version-id>
   *
   * On parsing the above Id, this function returns:
   *```ts
   *   {
   *      sourceId: "https://<keyvault-name>.vault.azure.net/keys/<key-name>/<unique-version-id>",
   *      vaultUrl: "https://<keyvault-name>.vault.azure.net",
   *      version: "<unique-version-id>",
   *      name: "<key-name>"
   *   }
   *```
   * @param id - The Id of the Key Vault Key.
   */
  function parseKeyVaultKeyIdentifier(id) {
      const urlParts = id.split("/");
      const collection = urlParts[3];
      return Object.assign({ sourceId: id }, parseKeyvaultIdentifier(collection, id));
  }
  
  // Copyright (c) Microsoft Corporation.
  /**
   * @internal
   * Shapes the exposed {@link KeyVaultKey} based on either a received key bundle or deleted key bundle.
   */
  function getKeyFromKeyBundle(bundle) {
      const keyBundle = bundle;
      const deletedKeyBundle = bundle;
      const parsedId = parseKeyVaultKeyIdentifier(keyBundle.key.kid);
      const attributes = keyBundle.attributes || {};
      delete keyBundle.attributes;
      const resultObject = {
          key: keyBundle.key,
          id: keyBundle.key ? keyBundle.key.kid : undefined,
          name: parsedId.name,
          keyOperations: keyBundle.key ? keyBundle.key.keyOps : undefined,
          keyType: keyBundle.key ? keyBundle.key.kty : undefined,
          properties: {
              tags: keyBundle.tags,
              enabled: attributes.enabled,
              notBefore: attributes.notBefore,
              expiresOn: attributes.expires,
              createdOn: attributes.created,
              updatedOn: attributes.updated,
              recoverableDays: attributes.recoverableDays,
              recoveryLevel: attributes.recoveryLevel,
              vaultUrl: parsedId.vaultUrl,
              version: parsedId.version,
              name: parsedId.name,
              managed: keyBundle.managed,
              id: keyBundle.key ? keyBundle.key.kid : undefined
          }
      };
      if (deletedKeyBundle.recoveryId) {
          resultObject.properties.recoveryId = deletedKeyBundle.recoveryId;
          resultObject.properties.scheduledPurgeDate = deletedKeyBundle.scheduledPurgeDate;
          resultObject.properties.deletedOn = deletedKeyBundle.deletedDate;
      }
      return resultObject;
  }
  /**
   * @internal
   * Shapes the exposed {@link DeletedKey} based on a received KeyItem.
   */
  function getDeletedKeyFromDeletedKeyItem(keyItem) {
      const commonProperties = getKeyPropertiesFromKeyItem(keyItem);
      return {
          key: {
              kid: keyItem.kid
          },
          id: keyItem.kid,
          name: commonProperties.name,
          properties: Object.assign(Object.assign({}, commonProperties), { recoveryId: keyItem.recoveryId, scheduledPurgeDate: keyItem.scheduledPurgeDate, deletedOn: keyItem.deletedDate })
      };
  }
  /**
   * @internal
   * Shapes the exposed {@link KeyProperties} based on a received KeyItem.
   */
  function getKeyPropertiesFromKeyItem(keyItem) {
      const parsedId = parseKeyVaultKeyIdentifier(keyItem.kid);
      const attributes = keyItem.attributes || {};
      const resultObject = {
          createdOn: attributes.created,
          enabled: attributes === null || attributes === void 0 ? void 0 : attributes.enabled,
          expiresOn: attributes === null || attributes === void 0 ? void 0 : attributes.expires,
          id: keyItem.kid,
          managed: keyItem.managed,
          name: parsedId.name,
          notBefore: attributes === null || attributes === void 0 ? void 0 : attributes.notBefore,
          recoverableDays: attributes === null || attributes === void 0 ? void 0 : attributes.recoverableDays,
          recoveryLevel: attributes === null || attributes === void 0 ? void 0 : attributes.recoveryLevel,
          tags: keyItem.tags,
          updatedOn: attributes.updated,
          vaultUrl: parsedId.vaultUrl,
          version: parsedId.version
      };
      return resultObject;
  }
  
  // Copyright (c) Microsoft Corporation.
  /**
   * Common properties and methods of the Key Vault Key Pollers.
   */
  class KeyVaultKeyPoller extends coreLro.Poller {
      constructor() {
          super(...arguments);
          /**
           * Defines how much time the poller is going to wait before making a new request to the service.
           */
          this.intervalInMs = 2000;
      }
      /**
       * The method used by the poller to wait before attempting to update its operation.
       */
      async delay() {
          return coreHttp.delay(this.intervalInMs);
      }
  }
  /**
   * Common properties and methods of the Key Vault Key Poller operations.
   */
  class KeyVaultKeyPollOperation {
      constructor(state, options = {}) {
          this.state = state;
          this.cancelMessage = "";
          if (options.cancelMessage) {
              this.cancelMessage = options.cancelMessage;
          }
      }
      /**
       * Meant to reach to the service and update the Poller operation.
       */
      async update() {
          throw new Error("Operation not supported.");
      }
      /**
       * Meant to reach to the service and cancel the Poller operation.
       */
      async cancel() {
          throw new Error(this.cancelMessage);
      }
      /**
       * Serializes the Poller operation.
       */
      toString() {
          return JSON.stringify({
              state: this.state
          });
      }
  }
  
  // Copyright (c) Microsoft Corporation.
  /**
   * @internal
   */
  const withTrace = createTraceFunction("Azure.KeyVault.Keys.DeleteKeyPoller");
  class DeleteKeyPollOperation extends KeyVaultKeyPollOperation {
      constructor(state, vaultUrl, client, operationOptions = {}) {
          super(state, { cancelMessage: "Canceling the deletion of a key is not supported." });
          this.state = state;
          this.vaultUrl = vaultUrl;
          this.client = client;
          this.operationOptions = operationOptions;
      }
      /**
       * Sends a delete request for the given Key Vault Key's name to the Key Vault service.
       * Since the Key Vault Key won't be immediately deleted, we have {@link beginDeleteKey}.
       */
      deleteKey(name, options = {}) {
          return withTrace("deleteKey", options, async (updatedOptions) => {
              const response = await this.client.deleteKey(this.vaultUrl, name, updatedOptions);
              return getKeyFromKeyBundle(response);
          });
      }
      /**
       * The getDeletedKey method returns the specified deleted key along with its properties.
       * This operation requires the keys/get permission.
       */
      getDeletedKey(name, options = {}) {
          return withTrace("getDeletedKey", options, async (updatedOptions) => {
              const response = await this.client.getDeletedKey(this.vaultUrl, name, updatedOptions);
              return getKeyFromKeyBundle(response);
          });
      }
      /**
       * Reaches to the service and updates the delete key's poll operation.
       */
      async update(options = {}) {
          const state = this.state;
          const { name } = state;
          if (options.abortSignal) {
              this.operationOptions.abortSignal = options.abortSignal;
          }
          if (!state.isStarted) {
              const deletedKey = await this.deleteKey(name, this.operationOptions);
              state.isStarted = true;
              state.result = deletedKey;
              if (!deletedKey.properties.recoveryId) {
                  state.isCompleted = true;
              }
          }
          if (!state.isCompleted) {
              try {
                  state.result = await this.getDeletedKey(name, this.operationOptions);
                  state.isCompleted = true;
              }
              catch (error) {
                  if (error.statusCode === 403) {
                      // At this point, the resource exists but the user doesn't have access to it.
                      state.isCompleted = true;
                  }
                  else if (error.statusCode !== 404) {
                      state.error = error;
                      state.isCompleted = true;
                      throw error;
                  }
              }
          }
          return this;
      }
  }
  
  // Copyright (c) Microsoft Corporation.
  /**
   * Class that creates a poller that waits until a key finishes being deleted.
   */
  class DeleteKeyPoller extends KeyVaultKeyPoller {
      constructor(options) {
          const { vaultUrl, client, name, operationOptions, intervalInMs = 2000, resumeFrom } = options;
          let state;
          if (resumeFrom) {
              state = JSON.parse(resumeFrom).state;
          }
          const operation = new DeleteKeyPollOperation(Object.assign(Object.assign({}, state), { name }), vaultUrl, client, operationOptions);
          super(operation);
          this.intervalInMs = intervalInMs;
      }
  }
  
  // Copyright (c) Microsoft Corporation.
  /**
   * @internal
   */
  const withTrace$1 = createTraceFunction("Azure.KeyVault.Keys.RecoverDeletedKeyPoller");
  class RecoverDeletedKeyPollOperation extends KeyVaultKeyPollOperation {
      constructor(state, vaultUrl, client, operationOptions = {}) {
          super(state, { cancelMessage: "Canceling the recovery of a deleted key is not supported." });
          this.state = state;
          this.vaultUrl = vaultUrl;
          this.client = client;
          this.operationOptions = operationOptions;
      }
      /**
       * The getKey method gets a specified key and is applicable to any key stored in Azure Key Vault.
       * This operation requires the keys/get permission.
       */
      getKey(name, options = {}) {
          return withTrace$1("generatedClient.getKey", options, async (updatedOptions) => {
              const response = await this.client.getKey(this.vaultUrl, name, (updatedOptions === null || updatedOptions === void 0 ? void 0 : updatedOptions.version) || "", updatedOptions);
              return getKeyFromKeyBundle(response);
          });
      }
      /**
       * Sends a request to recover a deleted Key Vault Key based on the given name.
       * Since the Key Vault Key won't be immediately recover the deleted key, we have {@link beginRecoverDeletedKey}.
       */
      async recoverDeletedKey(name, options = {}) {
          return withTrace$1("generatedClient.recoverDeleteKey", options, async (updatedOptions) => {
              const response = await this.client.recoverDeletedKey(this.vaultUrl, name, updatedOptions);
              return getKeyFromKeyBundle(response);
          });
      }
      /**
       * Reaches to the service and updates the delete key's poll operation.
       */
      async update(options = {}) {
          const state = this.state;
          const { name } = state;
          const operationOptions = this.operationOptions;
          if (options.abortSignal) {
              operationOptions.abortSignal = options.abortSignal;
          }
          if (!state.isStarted) {
              try {
                  state.result = await this.getKey(name, operationOptions);
                  state.isCompleted = true;
              }
              catch (_a) {
                  // Nothing to do here.
              }
              if (!state.isCompleted) {
                  state.result = await this.recoverDeletedKey(name, operationOptions);
                  state.isStarted = true;
              }
          }
          if (!state.isCompleted) {
              try {
                  state.result = await this.getKey(name, operationOptions);
                  state.isCompleted = true;
              }
              catch (error) {
                  if (error.statusCode === 403) {
                      // At this point, the resource exists but the user doesn't have access to it.
                      state.isCompleted = true;
                  }
                  else if (error.statusCode !== 404) {
                      state.error = error;
                      state.isCompleted = true;
                      throw error;
                  }
              }
          }
          return this;
      }
  }
  
  // Copyright (c) Microsoft Corporation.
  /**
   * Class that deletes a poller that waits until a key finishes being deleted
   */
  class RecoverDeletedKeyPoller extends KeyVaultKeyPoller {
      constructor(options) {
          const { vaultUrl, client, name, operationOptions, intervalInMs = 2000, resumeFrom } = options;
          let state;
          if (resumeFrom) {
              state = JSON.parse(resumeFrom).state;
          }
          const operation = new RecoverDeletedKeyPollOperation(Object.assign(Object.assign({}, state), { name }), vaultUrl, client, operationOptions);
          super(operation);
          this.intervalInMs = intervalInMs;
      }
  }
  
  // Copyright (c) Microsoft Corporation.
  // Licensed under the MIT license.
  /**
   * The latest supported Key Vault service API version
   */
  const LATEST_API_VERSION = "7.2";
  
  // Copyright (c) Microsoft Corporation.
  /**
   * @internal
   * Mapping between signature algorithms and their corresponding hash algorithms. Externally used for testing.
   **/
  const algorithmToHashAlgorithm = {
      ES256: "SHA256",
      ES256K: "SHA256",
      PS256: "SHA256",
      RS256: "SHA256",
      ES384: "SHA384",
      PS384: "SHA384",
      RS384: "SHA384",
      ES512: "SHA512",
      PS512: "SHA512",
      RS512: "SHA512"
  };
  /**
   * @internal
   * Use the platform-local hashing functionality
   */
  async function createHash(algorithm, data) {
      const hashAlgorithm = algorithmToHashAlgorithm[algorithm];
      if (!hashAlgorithm) {
          throw new Error(`Invalid algorithm ${algorithm} passed to createHash. Supported algorithms: ${Object.keys(algorithmToHashAlgorithm).join(", ")}`);
      }
      const hash = crypto.createHash(hashAlgorithm);
      hash.update(Buffer.from(data));
      const digest = hash.digest();
      return digest;
  }
  /**
   * @internal
   * Use the platform-local verify functionality
   */
  function createVerify(algorithm, data) {
      const verifyAlgorithm = algorithmToHashAlgorithm[algorithm];
      if (!verifyAlgorithm) {
          throw new Error(`Invalid algorithm ${algorithm} passed to createHash. Supported algorithms: ${Object.keys(algorithmToHashAlgorithm).join(", ")}`);
      }
      const verifier = crypto.createVerify(verifyAlgorithm);
      verifier.update(Buffer.from(data));
      verifier.end();
      return verifier;
  }
  /**
   * @internal
   * Use the platform-local randomBytes functionality
   */
  function randomBytes(length) {
      return crypto.randomBytes(length);
  }
  
  // Copyright (c) Microsoft Corporation.
  const withTrace$2 = createTraceFunction("Azure.KeyVault.Keys.RemoteCryptographyProvider");
  /**
   * The remote cryptography provider is used to run crypto operations against KeyVault.
   * @internal
   */
  class RemoteCryptographyProvider {
      constructor(key, credential, pipelineOptions = {}) {
          const libInfo = `azsdk-js-keyvault-keys/${SDK_VERSION}`;
          const userAgentOptions = pipelineOptions.userAgentOptions;
          pipelineOptions.userAgentOptions = {
              userAgentPrefix: userAgentOptions && userAgentOptions.userAgentPrefix
                  ? `${userAgentOptions.userAgentPrefix} ${libInfo}`
                  : libInfo
          };
          const authPolicy = coreHttp.isTokenCredential(credential)
              ? challengeBasedAuthenticationPolicy(credential)
              : coreHttp.signingPolicy(credential);
          const internalPipelineOptions = Object.assign(Object.assign({}, pipelineOptions), { loggingOptions: {
                  logger: logger.info,
                  allowedHeaderNames: [
                      "x-ms-keyvault-region",
                      "x-ms-keyvault-network-info",
                      "x-ms-keyvault-service-version"
                  ]
              } });
          this.client = new KeyVaultClient(pipelineOptions.serviceVersion || LATEST_API_VERSION, coreHttp.createPipelineFromOptions(internalPipelineOptions, authPolicy));
          this.key = key;
          let keyId;
          if (typeof key === "string") {
              keyId = key;
          }
          else {
              keyId = key.id;
          }
          try {
              const parsed = parseKeyVaultKeyIdentifier(keyId);
              if (parsed.name === "") {
                  throw new Error("Could not find 'name' of key in key URL");
              }
              if (!parsed.version || parsed.version === "") {
                  throw new Error("Could not find 'version' of key in key URL");
              }
              if (!parsed.vaultUrl || parsed.vaultUrl === "") {
                  throw new Error("Could not find 'vaultUrl' of key in key URL");
              }
              this.vaultUrl = parsed.vaultUrl;
              this.name = parsed.name;
              this.version = parsed.version;
          }
          catch (err) {
              logger.error(err);
              throw new Error(`${keyId} is not a valid Key Vault key ID`);
          }
      }
      // The remote client supports all algorithms and all operations.
      isSupported(_algorithm, _operation) {
          return true;
      }
      encrypt(encryptParameters, options = {}) {
          const { algorithm, plaintext } = encryptParameters, params = tslib.__rest(encryptParameters, ["algorithm", "plaintext"]);
          const requestOptions = Object.assign(Object.assign({}, options), params);
          return withTrace$2("encrypt", requestOptions, async (updatedOptions) => {
              const result = await this.client.encrypt(this.vaultUrl, this.name, this.version, algorithm, plaintext, updatedOptions);
              return {
                  algorithm: encryptParameters.algorithm,
                  result: result.result,
                  keyID: this.getKeyID(),
                  additionalAuthenticatedData: result.additionalAuthenticatedData,
                  authenticationTag: result.authenticationTag,
                  iv: result.iv
              };
          });
      }
      decrypt(decryptParameters, options = {}) {
          const { algorithm, ciphertext } = decryptParameters, params = tslib.__rest(decryptParameters, ["algorithm", "ciphertext"]);
          const requestOptions = Object.assign(Object.assign({}, options), params);
          return withTrace$2("decrypt", requestOptions, async (updatedOptions) => {
              const result = await this.client.decrypt(this.vaultUrl, this.name, this.version, algorithm, ciphertext, updatedOptions);
              return {
                  result: result.result,
                  keyID: this.getKeyID(),
                  algorithm
              };
          });
      }
      wrapKey(algorithm, keyToWrap, options = {}) {
          return withTrace$2("wrapKey", options, async (updatedOptions) => {
              const result = await this.client.wrapKey(this.vaultUrl, this.name, this.version, algorithm, keyToWrap, updatedOptions);
              return {
                  result: result.result,
                  algorithm,
                  keyID: this.getKeyID()
              };
          });
      }
      unwrapKey(algorithm, encryptedKey, options = {}) {
          return withTrace$2("unwrapKey", options, async (updatedOptions) => {
              const result = await this.client.unwrapKey(this.vaultUrl, this.name, this.version, algorithm, encryptedKey, updatedOptions);
              return {
                  result: result.result,
                  algorithm,
                  keyID: this.getKeyID()
              };
          });
      }
      sign(algorithm, digest, options = {}) {
          return withTrace$2("sign", options, async (updatedOptions) => {
              const result = await this.client.sign(this.vaultUrl, this.name, this.version, algorithm, digest, updatedOptions);
              return { result: result.result, algorithm, keyID: this.getKeyID() };
          });
      }
      verifyData(algorithm, data, signature, options = {}) {
          return withTrace$2("verifyData", options, async (updatedOptions) => {
              const hash = await createHash(algorithm, data);
              return this.verify(algorithm, hash, signature, updatedOptions);
          });
      }
      verify(algorithm, digest, signature, options = {}) {
          return withTrace$2("verify", options, async (updatedOptions) => {
              const response = await this.client.verify(this.vaultUrl, this.name, this.version, algorithm, digest, signature, updatedOptions);
              return {
                  result: response.value ? response.value : false,
                  keyID: this.getKeyID()
              };
          });
      }
      signData(algorithm, data, options = {}) {
          return withTrace$2("signData", options, async (updatedOptions) => {
              const digest = await createHash(algorithm, data);
              const result = await this.client.sign(this.vaultUrl, this.name, this.version, algorithm, digest, updatedOptions);
              return { result: result.result, algorithm, keyID: this.getKeyID() };
          });
      }
      /**
       * The ID of the key used to perform cryptographic operations for the client.
       */
      get keyId() {
          return this.getKeyID();
      }
      /**
       * Gets the {@link KeyVaultKey} used for cryptography operations, fetching it
       * from KeyVault if necessary.
       * @param options - Additional options.
       */
      getKey(options = {}) {
          return withTrace$2("getKey", options, async (updatedOptions) => {
              if (typeof this.key === "string") {
                  if (!this.name || this.name === "") {
                      throw new Error("getKey requires a key with a name");
                  }
                  const response = await this.client.getKey(this.vaultUrl, this.name, options && options.version ? options.version : this.version ? this.version : "", updatedOptions);
                  this.key = getKeyFromKeyBundle(response);
              }
              return this.key;
          });
      }
      /**
       * Attempts to retrieve the ID of the key.
       * @internal
       */
      getKeyID() {
          let kid;
          if (typeof this.key !== "string") {
              kid = this.key.id;
          }
          else {
              kid = this.key;
          }
          return kid;
      }
  }
  
  // Copyright (c) Microsoft Corporation.
  // Licensed under the MIT license.
  /**
   * @internal
   * Encodes a length of a packet in DER format
   */
  function encodeLength(length) {
      if (length <= 127) {
          return Uint8Array.of(length);
      }
      else if (length < 256) {
          return Uint8Array.of(0x81, length);
      }
      else if (length < 65536) {
          return Uint8Array.of(0x82, length >> 8, length & 0xff);
      }
      else {
          throw new Error("Unsupported length to encode");
      }
  }
  /**
   * @internal
   * Encodes a buffer for DER, as sets the id to the given id
   */
  function encodeBuffer(buffer, bufferId) {
      if (buffer.length === 0) {
          return buffer;
      }
      let result = new Uint8Array(buffer);
      // If the high bit is set, prepend a 0
      if (result[0] & 0x80) {
          const array = new Uint8Array(result.length + 1);
          array[0] = 0;
          array.set(result, 1);
          result = array;
      }
      // Prepend the DER header for this buffer
      const encodedLength = encodeLength(result.length);
      const totalLength = 1 + encodedLength.length + result.length;
      const outputBuffer = new Uint8Array(totalLength);
      outputBuffer[0] = bufferId;
      outputBuffer.set(encodedLength, 1);
      outputBuffer.set(result, 1 + encodedLength.length);
      return outputBuffer;
  }
  function makeSequence(encodedParts) {
      const totalLength = encodedParts.reduce((sum, part) => sum + part.length, 0);
      const sequence = new Uint8Array(totalLength);
      for (let i = 0; i < encodedParts.length; i++) {
          const previousLength = i > 0 ? encodedParts[i - 1].length : 0;
          sequence.set(encodedParts[i], previousLength);
      }
      const full_encoded = encodeBuffer(sequence, 0x30); // SEQUENCE
      return Buffer.from(full_encoded).toString("base64");
  }
  /**
   * Fill in the PEM with 64 character lines as per RFC:
   *
   * "To represent the encapsulated text of a PEM message, the encoding
   * function's output is delimited into text lines (using local
   * conventions), with each line except the last containing exactly 64
   * printable characters and the final line containing 64 or fewer
   * printable characters."
   */
  function formatBase64Sequence(base64Sequence) {
      const lines = base64Sequence.match(/.{1,64}/g);
      let result = "";
      if (lines) {
          for (const line of lines) {
              result += line;
              result += "\n";
          }
      }
      else {
          throw new Error("Could not create correct PEM");
      }
      return result;
  }
  /**
   * @internal
   * Encode a JWK to PEM format. To do so, it internally repackages the JWK as a DER
   * that is then encoded as a PEM.
   */
  function convertJWKtoPEM(key) {
      let result = "";
      if (key.n && key.e) {
          const parts = [key.n, key.e];
          const encodedParts = parts.map((part) => encodeBuffer(part, 0x2)); // INTEGER
          const base64Sequence = makeSequence(encodedParts);
          result += "-----BEGIN RSA PUBLIC KEY-----\n";
          result += formatBase64Sequence(base64Sequence);
          result += "-----END RSA PUBLIC KEY-----\n";
      }
      if (!result.length) {
          throw new Error("Unsupported key format for local operations");
      }
      return result.slice(0, -1); // Removing the last new line
  }
  
  // Copyright (c) Microsoft Corporation.
  // Licensed under the MIT license.
  class LocalCryptographyUnsupportedError extends Error {
  }
  
  // Copyright (c) Microsoft Corporation.
  /**
   * An RSA cryptography provider supporting RSA algorithms.
   */
  class RsaCryptographyProvider {
      constructor(key) {
          /**
           * The set of algorithms this provider supports
           * @internal
           */
          this.applicableAlgorithms = [
              "RSA1_5",
              "RSA-OAEP",
              "PS256",
              "RS256",
              "PS384",
              "RS384",
              "PS512",
              "RS512"
          ];
          /**
           * The set of operations this provider supports
           * @internal
           */
          this.applicableOperations = [
              "encrypt",
              "wrapKey",
              "verifyData"
          ];
          /**
           * Mapping between signature algorithms and their corresponding hash algorithms. Externally used for testing.
           * @internal
           */
          this.signatureAlgorithmToHashAlgorithm = {
              PS256: "SHA256",
              RS256: "SHA256",
              PS384: "SHA384",
              RS384: "SHA384",
              PS512: "SHA512",
              RS512: "SHA512"
          };
          this.key = key;
      }
      isSupported(algorithm, operation) {
          return (this.applicableAlgorithms.includes(algorithm) && this.applicableOperations.includes(operation));
      }
      encrypt(encryptParameters, _options) {
          this.ensureValid();
          const keyPEM = convertJWKtoPEM(this.key);
          const padding = encryptParameters.algorithm === "RSA1_5" ? constants.RSA_PKCS1_PADDING : constants.RSA_PKCS1_OAEP_PADDING;
          return Promise.resolve({
              algorithm: encryptParameters.algorithm,
              keyID: this.key.kid,
              result: crypto.publicEncrypt({ key: keyPEM, padding: padding }, Buffer.from(encryptParameters.plaintext))
          });
      }
      decrypt(_decryptParameters, _options) {
          throw new LocalCryptographyUnsupportedError("Decrypting using a local JsonWebKey is not supported.");
      }
      wrapKey(algorithm, keyToWrap, _options) {
          this.ensureValid();
          const keyPEM = convertJWKtoPEM(this.key);
          const padding = algorithm === "RSA1_5" ? constants.RSA_PKCS1_PADDING : constants.RSA_PKCS1_OAEP_PADDING;
          return Promise.resolve({
              algorithm: algorithm,
              result: crypto.publicEncrypt({ key: keyPEM, padding }, Buffer.from(keyToWrap)),
              keyID: this.key.kid
          });
      }
      unwrapKey(_algorithm, _encryptedKey, _options) {
          throw new LocalCryptographyUnsupportedError("Unwrapping a key using a local JsonWebKey is not supported.");
      }
      sign(_algorithm, _digest, _options) {
          throw new LocalCryptographyUnsupportedError("Signing a digest using a local JsonWebKey is not supported.");
      }
      signData(_algorithm, _data, _options) {
          throw new LocalCryptographyUnsupportedError("Signing a block of data using a local JsonWebKey is not supported.");
      }
      async verify(_algorithm, _digest, _signature, _options) {
          throw new LocalCryptographyUnsupportedError("Verifying a digest using a local JsonWebKey is not supported.");
      }
      verifyData(algorithm, data, signature, _options) {
          this.ensureValid();
          const keyPEM = convertJWKtoPEM(this.key);
          const verifier = createVerify(algorithm, data);
          return Promise.resolve({
              result: verifier.verify(keyPEM, Buffer.from(signature)),
              keyID: this.key.kid
          });
      }
      ensureValid() {
          var _a, _b;
          if (this.key &&
              ((_a = this.key.kty) === null || _a === void 0 ? void 0 : _a.toUpperCase()) !== "RSA" &&
              ((_b = this.key.kty) === null || _b === void 0 ? void 0 : _b.toUpperCase()) !== "RSA-HSM") {
              throw new Error("Key type does not match the algorithm RSA");
          }
      }
  }
  
  // Copyright (c) Microsoft Corporation.
  /**
   * An AES cryptography provider supporting AES algorithms.
   * @internal
   */
  class AesCryptographyProvider {
      constructor(key) {
          /**
           * The set of algorithms this provider supports.
           * For AES encryption, the values include the underlying algorithm used in crypto
           * as well as the key size in bytes.
           *
           * We start with support for A[SIZE]CBCPAD which uses the PKCS padding (the default padding scheme in node crypto)
           */
          this.supportedAlgorithms = {
              A128CBCPAD: {
                  algorithm: "aes-128-cbc",
                  keySizeInBytes: 128 >> 3
              },
              A192CBCPAD: {
                  algorithm: "aes-192-cbc",
                  keySizeInBytes: 192 >> 3
              },
              A256CBCPAD: {
                  algorithm: "aes-256-cbc",
                  keySizeInBytes: 256 >> 3
              }
          };
          this.supportedOperations = ["encrypt", "decrypt"];
          this.key = key;
      }
      encrypt(encryptParameters, _options) {
          const { algorithm, keySizeInBytes } = this.supportedAlgorithms[encryptParameters.algorithm];
          const iv = encryptParameters.iv || crypto.randomBytes(16);
          this.ensureValid(keySizeInBytes);
          const cipher = crypto.createCipheriv(algorithm, this.key.k.subarray(0, keySizeInBytes), iv);
          let encrypted = cipher.update(Buffer.from(encryptParameters.plaintext));
          encrypted = Buffer.concat([encrypted, cipher.final()]);
          return Promise.resolve({
              algorithm: encryptParameters.algorithm,
              result: encrypted,
              iv: iv
          });
      }
      decrypt(decryptParameters, _options) {
          const { algorithm, keySizeInBytes } = this.supportedAlgorithms[decryptParameters.algorithm];
          this.ensureValid(keySizeInBytes);
          const decipher = crypto.createDecipheriv(algorithm, this.key.k.subarray(0, keySizeInBytes), decryptParameters.iv);
          let dec = decipher.update(Buffer.from(decryptParameters.ciphertext));
          dec = Buffer.concat([dec, decipher.final()]);
          return Promise.resolve({
              algorithm: decryptParameters.algorithm,
              result: dec
          });
      }
      isSupported(algorithm, operation) {
          if (!this.key.k) {
              return false;
          }
          if (!Object.keys(this.supportedAlgorithms).includes(algorithm)) {
              return false;
          }
          if (!this.supportedOperations.includes(operation)) {
              return false;
          }
          return true;
      }
      wrapKey(_algorithm, _keyToWrap, _options) {
          throw new LocalCryptographyUnsupportedError("Wrapping a key using a local JsonWebKey is not supported for AES.");
      }
      unwrapKey(_algorithm, _encryptedKey, _options) {
          throw new LocalCryptographyUnsupportedError("Unwrapping a key using a local JsonWebKey is not supported for AES.");
      }
      sign(_algorithm, _digest, _options) {
          throw new LocalCryptographyUnsupportedError("Signing using a local JsonWebKey is not supported for AES.");
      }
      signData(_algorithm, _data, _options) {
          throw new LocalCryptographyUnsupportedError("Signing using a local JsonWebKey is not supported for AES.");
      }
      verify(_algorithm, _digest, _signature, _options) {
          throw new LocalCryptographyUnsupportedError("Verifying using a local JsonWebKey is not supported for AES.");
      }
      verifyData(_algorithm, _data, _signature, _updatedOptions) {
          throw new LocalCryptographyUnsupportedError("Verifying using a local JsonWebKey is not supported for AES.");
      }
      ensureValid(keySizeInBytes) {
          var _a, _b;
          if (this.key &&
              ((_a = this.key.kty) === null || _a === void 0 ? void 0 : _a.toUpperCase()) !== "OCT" &&
              ((_b = this.key.kty) === null || _b === void 0 ? void 0 : _b.toUpperCase()) !== "OCT-HSM") {
              throw new Error("Key type does not match the key type oct or oct-hsm");
          }
          if (!this.key.k) {
              throw new Error("Symmetric key is required");
          }
          if (this.key.k.length < keySizeInBytes) {
              throw new Error(`Key must be at least ${keySizeInBytes << 3} bits`);
          }
      }
  }
  
  // Copyright (c) Microsoft Corporation.
  const withTrace$3 = createTraceFunction("Azure.KeyVault.Keys.CryptographyClient");
  /**
   * A client used to perform cryptographic operations on an Azure Key vault key
   * or a local {@link JsonWebKey}.
   */
  class CryptographyClient {
      /**
       * Internal constructor implementation for either local or Key Vault backed keys.
       * @param key - The key to use during cryptography tasks.
       * @param credential - Teh credential to use when constructing a Key Vault Cryptography client.
       */
      constructor(key, credential, pipelineOptions = {}) {
          if (typeof key === "string") {
              // Key URL for remote-local operations.
              this.key = {
                  kind: "identifier",
                  value: key
              };
              this.remoteProvider = new RemoteCryptographyProvider(key, credential, pipelineOptions);
          }
          else if ("name" in key) {
              // KeyVault key for remote-local operations.
              this.key = {
                  kind: "KeyVaultKey",
                  value: key
              };
              this.remoteProvider = new RemoteCryptographyProvider(key, credential, pipelineOptions);
          }
          else {
              // JsonWebKey for local-only operations.
              this.key = {
                  kind: "JsonWebKey",
                  value: key
              };
          }
      }
      /**
       * The base URL to the vault. If a local {@link JsonWebKey} is used vaultUrl will be empty.
       */
      get vaultUrl() {
          var _a;
          return ((_a = this.remoteProvider) === null || _a === void 0 ? void 0 : _a.vaultUrl) || "";
      }
      /**
       * The ID of the key used to perform cryptographic operations for the client.
       */
      get keyID() {
          if (this.key.kind === "identifier") {
              return this.key.value;
          }
          else if (this.key.kind === "KeyVaultKey") {
              return this.key.value.id;
          }
          else {
              return this.key.value.kid;
          }
      }
      encrypt(...args) {
          const [parameters, options] = this.disambiguateEncryptArguments(args);
          return withTrace$3("encrypt", options, async (updatedOptions) => {
              this.ensureValid(await this.fetchKey(updatedOptions), "encrypt" /* Encrypt */);
              this.initializeIV(parameters);
              const provider = await this.getProvider("encrypt", parameters.algorithm, updatedOptions);
              try {
                  return provider.encrypt(parameters, updatedOptions);
              }
              catch (error) {
                  if (this.remoteProvider) {
                      return this.remoteProvider.encrypt(parameters, updatedOptions);
                  }
                  throw error;
              }
          });
      }
      initializeIV(parameters) {
          // For AES-GCM the service **must** generate the IV, so we only populate it for AES-CBC
          const algorithmsRequiringIV = [
              "A128CBC",
              "A128CBCPAD",
              "A192CBC",
              "A192CBCPAD",
              "A256CBC",
              "A256CBCPAD"
          ];
          if (parameters.algorithm in algorithmsRequiringIV) {
              try {
                  const cbcParams = parameters;
                  if (!cbcParams.iv) {
                      cbcParams.iv = randomBytes(16);
                  }
              }
              catch (e) {
                  throw new Error(`Unable to initialize IV for algorithm ${parameters.algorithm}. You may pass a valid IV to avoid this error. Error: ${e.message}`);
              }
          }
      }
      /**
       * Standardizes the arguments of multiple overloads into a single shape.
       * @param args - The encrypt arguments
       */
      disambiguateEncryptArguments(args) {
          if (typeof args[0] === "string") {
              // Sample shape: ["RSA1_5", buffer, options]
              return [
                  {
                      algorithm: args[0],
                      plaintext: args[1]
                  },
                  args[2] || {}
              ];
          }
          else {
              // Sample shape: [{ algorithm: "RSA1_5", plaintext: buffer }, options]
              return [args[0], (args[1] || {})];
          }
      }
      decrypt(...args) {
          const [parameters, options] = this.disambiguateDecryptArguments(args);
          return withTrace$3("decrypt", options, async (updatedOptions) => {
              this.ensureValid(await this.fetchKey(updatedOptions), "decrypt" /* Decrypt */);
              const provider = await this.getProvider("decrypt", parameters.algorithm, updatedOptions);
              try {
                  return provider.decrypt(parameters, updatedOptions);
              }
              catch (error) {
                  if (this.remoteProvider) {
                      return this.remoteProvider.decrypt(parameters, updatedOptions);
                  }
                  throw error;
              }
          });
      }
      /**
       * Standardizes the arguments of multiple overloads into a single shape.
       * @param args - The decrypt arguments
       */
      disambiguateDecryptArguments(args) {
          if (typeof args[0] === "string") {
              // Sample shape: ["RSA1_5", encryptedBuffer, options]
              return [
                  {
                      algorithm: args[0],
                      ciphertext: args[1]
                  },
                  args[2] || {}
              ];
          }
          else {
              // Sample shape: [{ algorithm: "RSA1_5", ciphertext: encryptedBuffer }, options]
              return [args[0], (args[1] || {})];
          }
      }
      /**
       * Wraps the given key using the specified cryptography algorithm
       *
       * Example usage:
       * ```ts
       * let client = new CryptographyClient(keyVaultKey, credentials);
       * let result = await client.wrapKey("RSA1_5", keyToWrap);
       * ```
       * @param algorithm - The encryption algorithm to use to wrap the given key.
       * @param key - The key to wrap.
       * @param options - Additional options.
       */
      wrapKey(algorithm, key, options = {}) {
          return withTrace$3("wrapKey", options, async (updatedOptions) => {
              this.ensureValid(await this.fetchKey(updatedOptions), "wrapKey" /* WrapKey */);
              const provider = await this.getProvider("wrapKey", algorithm, updatedOptions);
              try {
                  return provider.wrapKey(algorithm, key, updatedOptions);
              }
              catch (err) {
                  if (this.remoteProvider) {
                      return this.remoteProvider.wrapKey(algorithm, key, options);
                  }
                  throw err;
              }
          });
      }
      /**
       * Unwraps the given wrapped key using the specified cryptography algorithm
       *
       * Example usage:
       * ```ts
       * let client = new CryptographyClient(keyVaultKey, credentials);
       * let result = await client.unwrapKey("RSA1_5", keyToUnwrap);
       * ```
       * @param algorithm - The decryption algorithm to use to unwrap the key.
       * @param encryptedKey - The encrypted key to unwrap.
       * @param options - Additional options.
       */
      unwrapKey(algorithm, encryptedKey, options = {}) {
          return withTrace$3("unwrapKey", options, async (updatedOptions) => {
              this.ensureValid(await this.fetchKey(updatedOptions), "unwrapKey" /* UnwrapKey */);
              const provider = await this.getProvider("unwrapKey", algorithm, updatedOptions);
              try {
                  return provider.unwrapKey(algorithm, encryptedKey, updatedOptions);
              }
              catch (err) {
                  if (this.remoteProvider) {
                      return this.remoteProvider.unwrapKey(algorithm, encryptedKey, options);
                  }
                  throw err;
              }
          });
      }
      /**
       * Cryptographically sign the digest of a message
       *
       * Example usage:
       * ```ts
       * let client = new CryptographyClient(keyVaultKey, credentials);
       * let result = await client.sign("RS256", digest);
       * ```
       * @param algorithm - The signing algorithm to use.
       * @param digest - The digest of the data to sign.
       * @param options - Additional options.
       */
      sign(algorithm, digest, options = {}) {
          return withTrace$3("sign", options, async (updatedOptions) => {
              this.ensureValid(await this.fetchKey(updatedOptions), "sign" /* Sign */);
              const provider = await this.getProvider("sign", algorithm, updatedOptions);
              try {
                  return provider.sign(algorithm, digest, updatedOptions);
              }
              catch (err) {
                  if (this.remoteProvider) {
                      return this.remoteProvider.sign(algorithm, digest, updatedOptions);
                  }
                  throw err;
              }
          });
      }
      /**
       * Verify the signed message digest
       *
       * Example usage:
       * ```ts
       * let client = new CryptographyClient(keyVaultKey, credentials);
       * let result = await client.verify("RS256", signedDigest, signature);
       * ```
       * @param algorithm - The signing algorithm to use to verify with.
       * @param digest - The digest to verify.
       * @param signature - The signature to verify the digest against.
       * @param options - Additional options.
       */
      verify(algorithm, digest, signature, options = {}) {
          return withTrace$3("verify", options, async (updatedOptions) => {
              this.ensureValid(await this.fetchKey(updatedOptions), "verify" /* Verify */);
              const provider = await this.getProvider("verify", algorithm, updatedOptions);
              try {
                  return provider.verify(algorithm, digest, signature, updatedOptions);
              }
              catch (err) {
                  if (this.remoteProvider) {
                      return this.remoteProvider.verify(algorithm, digest, signature, updatedOptions);
                  }
                  throw err;
              }
          });
      }
      /**
       * Cryptographically sign a block of data
       *
       * Example usage:
       * ```ts
       * let client = new CryptographyClient(keyVaultKey, credentials);
       * let result = await client.signData("RS256", message);
       * ```
       * @param algorithm - The signing algorithm to use.
       * @param data - The data to sign.
       * @param options - Additional options.
       */
      signData(algorithm, data, options = {}) {
          return withTrace$3("signData", options, async (updatedOptions) => {
              this.ensureValid(await this.fetchKey(updatedOptions), "sign" /* Sign */);
              const provider = await this.getProvider("signData", algorithm, updatedOptions);
              try {
                  return provider.signData(algorithm, data, updatedOptions);
              }
              catch (err) {
                  if (this.remoteProvider) {
                      return this.remoteProvider.signData(algorithm, data, options);
                  }
                  throw err;
              }
          });
      }
      /**
       * Verify the signed block of data
       *
       * Example usage:
       * ```ts
       * let client = new CryptographyClient(keyVaultKey, credentials);
       * let result = await client.verifyData("RS256", signedMessage, signature);
       * ```
       * @param algorithm - The algorithm to use to verify with.
       * @param data - The signed block of data to verify.
       * @param signature - The signature to verify the block against.
       * @param options - Additional options.
       */
      verifyData(algorithm, data, signature, options = {}) {
          return withTrace$3("verifyData", options, async (updatedOptions) => {
              this.ensureValid(await this.fetchKey(updatedOptions), "verify" /* Verify */);
              const provider = await this.getProvider("verifyData", algorithm, updatedOptions);
              try {
                  return provider.verifyData(algorithm, data, signature, updatedOptions);
              }
              catch (err) {
                  if (this.remoteProvider) {
                      return this.remoteProvider.verifyData(algorithm, data, signature, updatedOptions);
                  }
                  throw err;
              }
          });
      }
      /**
       * @internal
       * Retrieves the {@link JsonWebKey} from the Key Vault.
       *
       * Example usage:
       * ```ts
       * let client = new CryptographyClient(keyVaultKey, credentials);
       * let result = await client.getKeyMaterial();
       * ```
       */
      async getKeyMaterial(options) {
          const key = await this.fetchKey(options);
          switch (key.kind) {
              case "JsonWebKey":
                  return key.value;
              case "KeyVaultKey":
                  return key.value.key;
              default:
                  throw new Error("Failed to exchange Key ID for an actual KeyVault Key.");
          }
      }
      /**
       * Returns the underlying key used for cryptographic operations.
       * If needed, fetches the key from KeyVault and exchanges the ID for the actual key.
       * @param options - The additional options.
       */
      async fetchKey(options) {
          if (this.key.kind === "identifier") {
              // Exchange the identifier with the actual key when needed
              const key = await this.remoteProvider.getKey(options);
              this.key = { kind: "KeyVaultKey", value: key };
          }
          return this.key;
      }
      /**
       * Gets the provider that support this algorithm and operation.
       * The available providers are ordered by priority such that the first provider that supports this
       * operation is the one we should use.
       * @param operation - The {@link KeyOperation}.
       * @param algorithm - The algorithm to use.
       */
      async getProvider(operation, algorithm, options) {
          if (!this.providers) {
              const keyMaterial = await this.getKeyMaterial(options);
              // Add local crypto providers as needed
              this.providers = [
                  new RsaCryptographyProvider(keyMaterial),
                  new AesCryptographyProvider(keyMaterial)
              ];
              // If the remote provider exists, we're in hybrid-mode. Otherwise we're in local-only mode.
              // If we're in hybrid mode the remote provider is used as a catch-all and should be last in the list.
              if (this.remoteProvider) {
                  this.providers.push(this.remoteProvider);
              }
          }
          const providers = this.providers.filter((p) => p.isSupported(algorithm, operation));
          if (providers.length === 0) {
              throw new Error(`Unable to support operation: "${operation}" with algorithm: "${algorithm}" ${this.key.kind === "JsonWebKey" ? "using a local JsonWebKey" : ""}`);
          }
          // Return the first provider that supports this request
          return providers[0];
      }
      ensureValid(key, operation) {
          var _a;
          if (key.kind === "KeyVaultKey") {
              const keyOps = key.value.keyOperations;
              const { notBefore, expiresOn } = key.value.properties;
              const now = new Date();
              // Check KeyVault Key Expiration
              if (notBefore && now < notBefore) {
                  throw new Error(`Key ${key.value.id} can't be used before ${notBefore.toISOString()}`);
              }
              if (expiresOn && now > expiresOn) {
                  throw new Error(`Key ${key.value.id} expired at ${expiresOn.toISOString()}`);
              }
              // Check Key operations
              if (operation && keyOps && !(keyOps === null || keyOps === void 0 ? void 0 : keyOps.includes(operation))) {
                  throw new Error(`Operation ${operation} is not supported on key ${key.value.id}`);
              }
          }
          else if (key.kind === "JsonWebKey") {
              // Check JsonWebKey Key operations
              if (operation && key.value.keyOps && !((_a = key.value.keyOps) === null || _a === void 0 ? void 0 : _a.includes(operation))) {
                  throw new Error(`Operation ${operation} is not supported on key ${key.value.kid}`);
              }
          }
      }
  }
  
  // Copyright (c) Microsoft Corporation.
  const withTrace$4 = createTraceFunction("Azure.KeyVault.Keys.KeyClient");
  /**
   * The KeyClient provides methods to manage {@link KeyVaultKey} in the
   * Azure Key Vault. The client supports creating, retrieving, updating,
   * deleting, purging, backing up, restoring and listing KeyVaultKeys. The
   * client also supports listing {@link DeletedKey} for a soft-delete enabled Azure Key
   * Vault.
   */
  class KeyClient {
      /**
       * Creates an instance of KeyClient.
       *
       * Example usage:
       * ```ts
       * import { KeyClient } from "@azure/keyvault-keys";
       * import { DefaultAzureCredential } from "@azure/identity";
       *
       * let vaultUrl = `https://<MY KEYVAULT HERE>.vault.azure.net`;
       * let credentials = new DefaultAzureCredential();
       *
       * let client = new KeyClient(vaultUrl, credentials);
       * ```
       * @param vaultUrl - the URL of the Key Vault. It should have this shape: `https://${your-key-vault-name}.vault.azure.net`
       * @param credential - An object that implements the `TokenCredential` interface used to authenticate requests to the service. Use the \@azure/identity package to create a credential that suits your needs.
       * @param pipelineOptions - Pipeline options used to configure Key Vault API requests. Omit this parameter to use the default pipeline configuration.
       */
      constructor(vaultUrl, credential, pipelineOptions = {}) {
          this.vaultUrl = vaultUrl;
          const libInfo = `azsdk-js-keyvault-keys/${SDK_VERSION}`;
          const userAgentOptions = pipelineOptions.userAgentOptions;
          pipelineOptions.userAgentOptions = {
              userAgentPrefix: userAgentOptions && userAgentOptions.userAgentPrefix
                  ? `${userAgentOptions.userAgentPrefix} ${libInfo}`
                  : libInfo
          };
          const authPolicy = coreHttp.isTokenCredential(credential)
              ? challengeBasedAuthenticationPolicy(credential)
              : coreHttp.signingPolicy(credential);
          const internalPipelineOptions = Object.assign(Object.assign({}, pipelineOptions), { loggingOptions: {
                  logger: logger.info,
                  allowedHeaderNames: [
                      "x-ms-keyvault-region",
                      "x-ms-keyvault-network-info",
                      "x-ms-keyvault-service-version"
                  ]
              } });
          this.client = new KeyVaultClient(pipelineOptions.serviceVersion || LATEST_API_VERSION, coreHttp.createPipelineFromOptions(internalPipelineOptions, authPolicy));
      }
      /**
       * The create key operation can be used to create any key type in Azure Key Vault. If the named key
       * already exists, Azure Key Vault creates a new version of the key. It requires the keys/create
       * permission.
       *
       * Example usage:
       * ```ts
       * let client = new KeyClient(url, credentials);
       * // Create an elliptic-curve key:
       * let result = await client.createKey("MyKey", "EC");
       * ```
       * Creates a new key, stores it, then returns key parameters and properties to the client.
       * @param name - The name of the key.
       * @param keyType - The type of the key. One of the following: 'EC', 'EC-HSM', 'RSA', 'RSA-HSM', 'oct'.
       * @param options - The optional parameters.
       */
      createKey(name, keyType, options) {
          let unflattenedOptions = {};
          if (options) {
              const { enabled, notBefore, expiresOn: expires } = options, remainingOptions = tslib.__rest(options, ["enabled", "notBefore", "expiresOn"]);
              unflattenedOptions = Object.assign(Object.assign({}, remainingOptions), { keyAttributes: {
                      enabled,
                      notBefore,
                      expires
                  } });
          }
          return withTrace$4("createKey", unflattenedOptions, async (updatedOptions) => {
              const response = await this.client.createKey(this.vaultUrl, name, keyType, updatedOptions);
              return getKeyFromKeyBundle(response);
          });
      }
      /**
       * The createEcKey method creates a new elliptic curve key in Azure Key Vault. If the named key
       * already exists, Azure Key Vault creates a new version of the key. It requires the keys/create
       * permission.
       *
       * Example usage:
       * ```ts
       * let client = new KeyClient(url, credentials);
       * let result = await client.createEcKey("MyKey", { curve: "P-256" });
       * ```
       * Creates a new key, stores it, then returns key parameters and properties to the client.
       * @param name - The name of the key.
       * @param options - The optional parameters.
       */
      async createEcKey(name, options) {
          const keyType = (options === null || options === void 0 ? void 0 : options.hsm) ? "EC-HSM" /* ECHSM */ : "EC" /* EC */;
          return this.createKey(name, keyType, options);
      }
      /**
       * The createRSAKey method creates a new RSA key in Azure Key Vault. If the named key
       * already exists, Azure Key Vault creates a new version of the key. It requires the keys/create
       * permission.
       *
       * Example usage:
       * ```ts
       * let client = new KeyClient(url, credentials);
       * let result = await client.createRsaKey("MyKey", { keySize: 2048 });
       * ```
       * Creates a new key, stores it, then returns key parameters and properties to the client.
       * @param name - The name of the key.
       * @param options - The optional parameters.
       */
      async createRsaKey(name, options) {
          const keyType = (options === null || options === void 0 ? void 0 : options.hsm) ? "RSA-HSM" /* RSAHSM */ : "RSA" /* RSA */;
          return this.createKey(name, keyType, options);
      }
      /**
       * The createOctKey method creates a new OCT key in Azure Key Vault. If the named key
       * already exists, Azure Key Vault creates a new version of the key. It requires the keys/create
       * permission.
       *
       * Example usage:
       * ```ts
       * let client = new KeyClient(url, credentials);
       * let result = await client.createOctKey("MyKey", { hsm: true });
       * ```
       * Creates a new key, stores it, then returns key parameters and properties to the client.
       * @param name - The name of the key.
       * @param options - The optional parameters.
       */
      async createOctKey(name, options) {
          const keyType = (options === null || options === void 0 ? void 0 : options.hsm) ? "oct-HSM" /* OctHSM */ : "oct" /* Oct */;
          return this.createKey(name, keyType, options);
      }
      /**
       * The import key operation may be used to import any key type into an Azure Key Vault. If the
       * named key already exists, Azure Key Vault creates a new version of the key. This operation
       * requires the keys/import permission.
       *
       * Example usage:
       * ```ts
       * let client = new KeyClient(url, credentials);
       * // Key contents in myKeyContents
       * let result = await client.importKey("MyKey", myKeyContents);
       * ```
       * Imports an externally created key, stores it, and returns key parameters and properties
       * to the client.
       * @param name - Name for the imported key.
       * @param key - The JSON web key.
       * @param options - The optional parameters.
       */
      importKey(name, key, options) {
          let unflattenedOptions = {};
          if (options) {
              const { enabled, notBefore, expiresOn: expires, hardwareProtected: hsm } = options, remainingOptions = tslib.__rest(options, ["enabled", "notBefore", "expiresOn", "hardwareProtected"]);
              unflattenedOptions = Object.assign(Object.assign({}, remainingOptions), { keyAttributes: {
                      enabled,
                      notBefore,
                      expires,
                      hsm
                  } });
          }
          return withTrace$4(`importKey`, unflattenedOptions, async (updatedOptions) => {
              const response = await this.client.importKey(this.vaultUrl, name, key, updatedOptions);
              return getKeyFromKeyBundle(response);
          });
      }
      /**
       * The delete operation applies to any key stored in Azure Key Vault. Individual versions
       * of a key can not be deleted, only all versions of a given key at once.
       *
       * This function returns a Long Running Operation poller that allows you to wait indefinitely until the key is deleted.
       *
       * This operation requires the keys/delete permission.
       *
       * Example usage:
       * ```ts
       * const client = new KeyClient(url, credentials);
       * await client.createKey("MyKey", "EC");
       * const poller = await client.beginDeleteKey("MyKey");
       *
       * // Serializing the poller
       * const serialized = poller.toString();
       * // A new poller can be created with:
       * // await client.beginDeleteKey("MyKey", { resumeFrom: serialized });
       *
       * // Waiting until it's done
       * const deletedKey = await poller.pollUntilDone();
       * console.log(deletedKey);
       * ```
       * Deletes a key from a specified key vault.
       * @param name - The name of the key.
       * @param options - The optional parameters.
       */
      async beginDeleteKey(name, options = {}) {
          const poller = new DeleteKeyPoller({
              name,
              vaultUrl: this.vaultUrl,
              client: this.client,
              intervalInMs: options.intervalInMs,
              resumeFrom: options.resumeFrom,
              operationOptions: options
          });
          // This will initialize the poller's operation (the deletion of the key).
          await poller.poll();
          return poller;
      }
      /**
       * The updateKeyProperties method changes specified properties of an existing stored key. Properties that
       * are not specified in the request are left unchanged. The value of a key itself cannot be
       * changed. This operation requires the keys/set permission.
       *
       * Example usage:
       * ```ts
       * let keyName = "MyKey";
       * let client = new KeyClient(url, credentials);
       * let key = await client.getKey(keyName);
       * let result = await client.updateKeyProperties(keyName, key.properties.version, { enabled: false });
       * ```
       * Updates the properties associated with a specified key in a given key vault.
       * @param name - The name of the key.
       * @param keyVersion - The version of the key.
       * @param options - The optional parameters.
       */
      updateKeyProperties(name, keyVersion, options = {}) {
          return withTrace$4(`updateKeyProperties`, options, async (updatedOptions) => {
              const { enabled, notBefore, expiresOn: expires } = updatedOptions, remainingOptions = tslib.__rest(updatedOptions, ["enabled", "notBefore", "expiresOn"]);
              const unflattenedOptions = Object.assign(Object.assign({}, remainingOptions), { keyAttributes: {
                      enabled,
                      notBefore,
                      expires
                  } });
              const response = await this.client.updateKey(this.vaultUrl, name, keyVersion, unflattenedOptions);
              return getKeyFromKeyBundle(response);
          });
      }
      /**
       * The getKey method gets a specified key and is applicable to any key stored in Azure Key Vault.
       * This operation requires the keys/get permission.
       *
       * Example usage:
       * ```ts
       * let client = new KeyClient(url, credentials);
       * let key = await client.getKey("MyKey");
       * ```
       * Get a specified key from a given key vault.
       * @param name - The name of the key.
       * @param options - The optional parameters.
       */
      getKey(name, options = {}) {
          return withTrace$4(`getKey`, options, async (updatedOptions) => {
              const response = await this.client.getKey(this.vaultUrl, name, options && options.version ? options.version : "", updatedOptions);
              return getKeyFromKeyBundle(response);
          });
      }
      /**
       * The getDeletedKey method returns the specified deleted key along with its properties.
       * This operation requires the keys/get permission.
       *
       * Example usage:
       * ```ts
       * let client = new KeyClient(url, credentials);
       * let key = await client.getDeletedKey("MyDeletedKey");
       * ```
       * Gets the specified deleted key.
       * @param name - The name of the key.
       * @param options - The optional parameters.
       */
      getDeletedKey(name, options = {}) {
          return withTrace$4(`getDeletedKey`, options, async (updatedOptions) => {
              const response = await this.client.getDeletedKey(this.vaultUrl, name, updatedOptions);
              return getKeyFromKeyBundle(response);
          });
      }
      /**
       * The purge deleted key operation removes the key permanently, without the possibility of
       * recovery. This operation can only be enabled on a soft-delete enabled vault. This operation
       * requires the keys/purge permission.
       *
       * Example usage:
       * ```ts
       * const client = new KeyClient(url, credentials);
       * const deletePoller = await client.beginDeleteKey("MyKey")
       * await deletePoller.pollUntilDone();
       * await client.purgeDeletedKey("MyKey");
       * ```
       * Permanently deletes the specified key.
       * @param name - The name of the key.
       * @param options - The optional parameters.
       */
      purgeDeletedKey(name, options = {}) {
          return withTrace$4(`purgeDeletedKey`, options, async (updatedOptions) => {
              await this.client.purgeDeletedKey(this.vaultUrl, name, updatedOptions);
          });
      }
      /**
       * Recovers the deleted key in the specified vault. This operation can only be performed on a
       * soft-delete enabled vault.
       *
       * This function returns a Long Running Operation poller that allows you to wait indefinitely until the deleted key is recovered.
       *
       * This operation requires the keys/recover permission.
       *
       * Example usage:
       * ```ts
       * const client = new KeyClient(url, credentials);
       * await client.createKey("MyKey", "EC");
       * const deletePoller = await client.beginDeleteKey("MyKey");
       * await deletePoller.pollUntilDone();
       * const poller = await client.beginRecoverDeletedKey("MyKey");
       *
       * // Serializing the poller
       * const serialized = poller.toString();
       * // A new poller can be created with:
       * // await client.beginRecoverDeletedKey("MyKey", { resumeFrom: serialized });
       *
       * // Waiting until it's done
       * const key = await poller.pollUntilDone();
       * console.log(key);
       * ```
       * Recovers the deleted key to the latest version.
       * @param name - The name of the deleted key.
       * @param options - The optional parameters.
       */
      async beginRecoverDeletedKey(name, options = {}) {
          const poller = new RecoverDeletedKeyPoller({
              name,
              vaultUrl: this.vaultUrl,
              client: this.client,
              intervalInMs: options.intervalInMs,
              resumeFrom: options.resumeFrom,
              operationOptions: options
          });
          // This will initialize the poller's operation (the deletion of the key).
          await poller.poll();
          return poller;
      }
      /**
       * Requests that a backup of the specified key be downloaded to the client. All versions of the
       * key will be downloaded. This operation requires the keys/backup permission.
       *
       * Example usage:
       * ```ts
       * let client = new KeyClient(url, credentials);
       * let backupContents = await client.backupKey("MyKey");
       * ```
       * Backs up the specified key.
       * @param name - The name of the key.
       * @param options - The optional parameters.
       */
      backupKey(name, options = {}) {
          return withTrace$4(`backupKey`, options, async (updatedOptions) => {
              const response = await this.client.backupKey(this.vaultUrl, name, updatedOptions);
              return response.value;
          });
      }
      /**
       * Restores a backed up key, and all its versions, to a vault. This operation requires the
       * keys/restore permission.
       *
       * Example usage:
       * ```ts
       * let client = new KeyClient(url, credentials);
       * let backupContents = await client.backupKey("MyKey");
       * // ...
       * let key = await client.restoreKeyBackup(backupContents);
       * ```
       * Restores a backed up key to a vault.
       * @param backup - The backup blob associated with a key bundle.
       * @param options - The optional parameters.
       */
      async restoreKeyBackup(backup, options = {}) {
          return withTrace$4(`restoreKeyBackup`, options, async (updatedOptions) => {
              const response = await this.client.restoreKey(this.vaultUrl, backup, updatedOptions);
              return getKeyFromKeyBundle(response);
          });
      }
      /**
       * @internal
       * @hidden
       * Deals with the pagination of {@link listPropertiesOfKeyVersions}.
       * @param name - The name of the Key Vault Key.
       * @param continuationState - An object that indicates the position of the paginated request.
       * @param options - Common options for the iterative endpoints.
       */
      listPropertiesOfKeyVersionsPage(name, continuationState, options) {
          return tslib.__asyncGenerator(this, arguments, function* listPropertiesOfKeyVersionsPage_1() {
              if (continuationState.continuationToken == null) {
                  const optionsComplete = Object.assign({ maxresults: continuationState.maxPageSize }, options);
                  const currentSetResponse = yield tslib.__await(withTrace$4("listPropertiesOfKeyVersionsPage", optionsComplete, async (updatedOptions) => this.client.getKeyVersions(this.vaultUrl, name, updatedOptions)));
                  continuationState.continuationToken = currentSetResponse.nextLink;
                  if (currentSetResponse.value) {
                      yield yield tslib.__await(currentSetResponse.value.map(getKeyPropertiesFromKeyItem, this));
                  }
              }
              while (continuationState.continuationToken) {
                  const currentSetResponse = yield tslib.__await(withTrace$4("listPropertiesOfKeyVersionsPage", options || {}, async (updatedOptions) => this.client.getKeyVersions(continuationState.continuationToken, name, updatedOptions)));
                  continuationState.continuationToken = currentSetResponse.nextLink;
                  if (currentSetResponse.value) {
                      yield yield tslib.__await(currentSetResponse.value.map(getKeyPropertiesFromKeyItem, this));
                  }
                  else {
                      break;
                  }
              }
          });
      }
      /**
       * @internal
       * @hidden
       * Deals with the iteration of all the available results of {@link listPropertiesOfKeyVersions}.
       * @param name - The name of the Key Vault Key.
       * @param options - Common options for the iterative endpoints.
       */
      listPropertiesOfKeyVersionsAll(name, options) {
          return tslib.__asyncGenerator(this, arguments, function* listPropertiesOfKeyVersionsAll_1() {
              var e_1, _a;
              const f = {};
              try {
                  for (var _b = tslib.__asyncValues(this.listPropertiesOfKeyVersionsPage(name, f, options)), _c; _c = yield tslib.__await(_b.next()), !_c.done;) {
                      const page = _c.value;
                      for (const item of page) {
                          yield yield tslib.__await(item);
                      }
                  }
              }
              catch (e_1_1) { e_1 = { error: e_1_1 }; }
              finally {
                  try {
                      if (_c && !_c.done && (_a = _b.return)) yield tslib.__await(_a.call(_b));
                  }
                  finally { if (e_1) throw e_1.error; }
              }
          });
      }
      /**
       * Iterates all versions of the given key in the vault. The full key identifier, properties, and tags are provided
       * in the response. This operation requires the keys/list permission.
       *
       * Example usage:
       * ```ts
       * let client = new KeyClient(url, credentials);
       * for await (const keyProperties of client.listPropertiesOfKeyVersions("MyKey")) {
       *   const key = await client.getKey(keyProperties.name);
       *   console.log("key version: ", key);
       * }
       * ```
       * @param name - Name of the key to fetch versions for
       * @param options - The optional parameters.
       */
      listPropertiesOfKeyVersions(name, options = {}) {
          const iter = this.listPropertiesOfKeyVersionsAll(name, options);
          return {
              next() {
                  return iter.next();
              },
              [Symbol.asyncIterator]() {
                  return this;
              },
              byPage: (settings = {}) => this.listPropertiesOfKeyVersionsPage(name, settings, options)
          };
      }
      /**
       * @internal
       * @hidden
       * Deals with the pagination of {@link listPropertiesOfKeys}.
       * @param continuationState - An object that indicates the position of the paginated request.
       * @param options - Common options for the iterative endpoints.
       */
      listPropertiesOfKeysPage(continuationState, options) {
          return tslib.__asyncGenerator(this, arguments, function* listPropertiesOfKeysPage_1() {
              if (continuationState.continuationToken == null) {
                  const optionsComplete = Object.assign({ maxresults: continuationState.maxPageSize }, options);
                  const currentSetResponse = yield tslib.__await(withTrace$4("listPropertiesOfKeysPage", optionsComplete, async (updatedOptions) => this.client.getKeys(this.vaultUrl, updatedOptions)));
                  continuationState.continuationToken = currentSetResponse.nextLink;
                  if (currentSetResponse.value) {
                      yield yield tslib.__await(currentSetResponse.value.map(getKeyPropertiesFromKeyItem, this));
                  }
              }
              while (continuationState.continuationToken) {
                  const currentSetResponse = yield tslib.__await(withTrace$4("KeysClient.listPropertiesOfKeysPage", options || {}, async (updatedOptions) => this.client.getKeys(continuationState.continuationToken, updatedOptions)));
                  continuationState.continuationToken = currentSetResponse.nextLink;
                  if (currentSetResponse.value) {
                      yield yield tslib.__await(currentSetResponse.value.map(getKeyPropertiesFromKeyItem, this));
                  }
                  else {
                      break;
                  }
              }
          });
      }
      /**
       * @internal
       * @hidden
       * Deals with the iteration of all the available results of {@link listPropertiesOfKeys}.
       * @param options - Common options for the iterative endpoints.
       */
      listPropertiesOfKeysAll(options) {
          return tslib.__asyncGenerator(this, arguments, function* listPropertiesOfKeysAll_1() {
              var e_2, _a;
              const f = {};
              try {
                  for (var _b = tslib.__asyncValues(this.listPropertiesOfKeysPage(f, options)), _c; _c = yield tslib.__await(_b.next()), !_c.done;) {
                      const page = _c.value;
                      for (const item of page) {
                          yield yield tslib.__await(item);
                      }
                  }
              }
              catch (e_2_1) { e_2 = { error: e_2_1 }; }
              finally {
                  try {
                      if (_c && !_c.done && (_a = _b.return)) yield tslib.__await(_a.call(_b));
                  }
                  finally { if (e_2) throw e_2.error; }
              }
          });
      }
      /**
       * Iterates the latest version of all keys in the vault.  The full key identifier and properties are provided
       * in the response. No values are returned for the keys. This operations requires the keys/list permission.
       *
       * Example usage:
       * ```ts
       * let client = new KeyClient(url, credentials);
       * for await (const keyProperties of client.listPropertiesOfKeys()) {
       *   const key = await client.getKey(keyProperties.name);
       *   console.log("key: ", key);
       * }
       * ```
       * List all keys in the vault
       * @param options - The optional parameters.
       */
      listPropertiesOfKeys(options = {}) {
          const iter = this.listPropertiesOfKeysAll(options);
          return {
              next() {
                  return iter.next();
              },
              [Symbol.asyncIterator]() {
                  return this;
              },
              byPage: (settings = {}) => this.listPropertiesOfKeysPage(settings, options)
          };
      }
      /**
       * @internal
       * @hidden
       * Deals with the pagination of {@link listDeletedKeys}.
       * @param continuationState - An object that indicates the position of the paginated request.
       * @param options - Common options for the iterative endpoints.
       */
      listDeletedKeysPage(continuationState, options) {
          return tslib.__asyncGenerator(this, arguments, function* listDeletedKeysPage_1() {
              if (continuationState.continuationToken == null) {
                  const optionsComplete = Object.assign({ maxresults: continuationState.maxPageSize }, options);
                  const currentSetResponse = yield tslib.__await(withTrace$4("listDeletedKeysPage", optionsComplete, async (updatedOptions) => this.client.getDeletedKeys(this.vaultUrl, updatedOptions)));
                  continuationState.continuationToken = currentSetResponse.nextLink;
                  if (currentSetResponse.value) {
                      yield yield tslib.__await(currentSetResponse.value.map(getDeletedKeyFromDeletedKeyItem, this));
                  }
              }
              while (continuationState.continuationToken) {
                  const currentSetResponse = yield tslib.__await(withTrace$4("listDeletedKeysPage", options || {}, async (updatedOptions) => this.client.getDeletedKeys(continuationState.continuationToken, updatedOptions)));
                  continuationState.continuationToken = currentSetResponse.nextLink;
                  if (currentSetResponse.value) {
                      yield yield tslib.__await(currentSetResponse.value.map(getDeletedKeyFromDeletedKeyItem, this));
                  }
                  else {
                      break;
                  }
              }
          });
      }
      /**
       * @internal
       * @hidden
       * Deals with the iteration of all the available results of {@link listDeletedKeys}.
       * @param options - Common options for the iterative endpoints.
       */
      listDeletedKeysAll(options) {
          return tslib.__asyncGenerator(this, arguments, function* listDeletedKeysAll_1() {
              var e_3, _a;
              const f = {};
              try {
                  for (var _b = tslib.__asyncValues(this.listDeletedKeysPage(f, options)), _c; _c = yield tslib.__await(_b.next()), !_c.done;) {
                      const page = _c.value;
                      for (const item of page) {
                          yield yield tslib.__await(item);
                      }
                  }
              }
              catch (e_3_1) { e_3 = { error: e_3_1 }; }
              finally {
                  try {
                      if (_c && !_c.done && (_a = _b.return)) yield tslib.__await(_a.call(_b));
                  }
                  finally { if (e_3) throw e_3.error; }
              }
          });
      }
      /**
       * Iterates the deleted keys in the vault.  The full key identifier and properties are provided
       * in the response. No values are returned for the keys. This operations requires the keys/list permission.
       *
       * Example usage:
       * ```ts
       * let client = new KeyClient(url, credentials);
       * for await (const deletedKey of client.listDeletedKeys()) {
       *   console.log("deleted key: ", deletedKey);
       * }
       * ```
       * List all keys in the vault
       * @param options - The optional parameters.
       */
      listDeletedKeys(options = {}) {
          const iter = this.listDeletedKeysAll(options);
          return {
              next() {
                  return iter.next();
              },
              [Symbol.asyncIterator]() {
                  return this;
              },
              byPage: (settings = {}) => this.listDeletedKeysPage(settings, options)
          };
      }
  }
  
  exports.CryptographyClient = CryptographyClient;
  exports.KeyClient = KeyClient;
  exports.logger = logger;
  exports.parseKeyVaultKeyIdentifier = parseKeyVaultKeyIdentifier;
  //# sourceMappingURL=index.js.map
  