'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var tslib = require('tslib');
var coreRestPipeline = require('@azure/core-rest-pipeline');
var logger$1 = require('@azure/logger');
require('@azure/core-paging');
var coreClient = require('@azure/core-client');
var coreHttpCompat = require('@azure/core-http-compat');
var coreTracing = require('@azure/core-tracing');
var coreUtil = require('@azure/core-util');
var coreLro = require('@azure/core-lro');
var crypto = require('crypto');
var constants = require('constants');

function _interopNamespace(e) {
    if (e && e.__esModule) return e;
    var n = Object.create(null);
    if (e) {
        Object.keys(e).forEach(function (k) {
            if (k !== 'default') {
                var d = Object.getOwnPropertyDescriptor(e, k);
                Object.defineProperty(n, k, d.get ? d : {
                    enumerable: true,
                    get: function () { return e[k]; }
                });
            }
        });
    }
    n["default"] = e;
    return Object.freeze(n);
}

var coreRestPipeline__namespace = /*#__PURE__*/_interopNamespace(coreRestPipeline);
var coreClient__namespace = /*#__PURE__*/_interopNamespace(coreClient);
var coreHttpCompat__namespace = /*#__PURE__*/_interopNamespace(coreHttpCompat);
var crypto__namespace = /*#__PURE__*/_interopNamespace(crypto);

// 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.
 */
/** Known values of {@link ApiVersion74} that the service accepts. */
var KnownApiVersion74;
(function (KnownApiVersion74) {
    /** Api Version '7.4' */
    KnownApiVersion74["Seven4"] = "7.4";
})(KnownApiVersion74 || (KnownApiVersion74 = {}));
/** Known values of {@link JsonWebKeyType} that the service accepts. */
exports.KnownKeyTypes = void 0;
(function (KnownJsonWebKeyType) {
    /** Elliptic Curve. */
    KnownJsonWebKeyType["EC"] = "EC";
    /** Elliptic Curve with a private key which is stored in the HSM. */
    KnownJsonWebKeyType["ECHSM"] = "EC-HSM";
    /** RSA (https://tools.ietf.org/html/rfc3447) */
    KnownJsonWebKeyType["RSA"] = "RSA";
    /** RSA with a private key which is stored in the HSM. */
    KnownJsonWebKeyType["RSAHSM"] = "RSA-HSM";
    /** Octet sequence (used to represent symmetric keys) */
    KnownJsonWebKeyType["Oct"] = "oct";
    /** Octet sequence (used to represent symmetric keys) which is stored the HSM. */
    KnownJsonWebKeyType["OctHSM"] = "oct-HSM";
})(exports.KnownKeyTypes || (exports.KnownKeyTypes = {}));
/** Known values of {@link JsonWebKeyOperation} that the service accepts. */
var KnownJsonWebKeyOperation;
(function (KnownJsonWebKeyOperation) {
    KnownJsonWebKeyOperation["Encrypt"] = "encrypt";
    KnownJsonWebKeyOperation["Decrypt"] = "decrypt";
    KnownJsonWebKeyOperation["Sign"] = "sign";
    KnownJsonWebKeyOperation["Verify"] = "verify";
    KnownJsonWebKeyOperation["WrapKey"] = "wrapKey";
    KnownJsonWebKeyOperation["UnwrapKey"] = "unwrapKey";
    KnownJsonWebKeyOperation["Import"] = "import";
    KnownJsonWebKeyOperation["Export"] = "export";
})(KnownJsonWebKeyOperation || (KnownJsonWebKeyOperation = {}));
/** Known values of {@link DeletionRecoveryLevel} that the service accepts. */
exports.KnownDeletionRecoveryLevel = void 0;
(function (KnownDeletionRecoveryLevel) {
    /** Denotes a vault state in which deletion is an irreversible operation, without the possibility for recovery. This level corresponds to no protection being available against a Delete operation; the data is irretrievably lost upon accepting a Delete operation at the entity level or higher (vault, resource group, subscription etc.) */
    KnownDeletionRecoveryLevel["Purgeable"] = "Purgeable";
    /** Denotes a vault state in which deletion is recoverable, and which also permits immediate and permanent deletion (i.e. purge). This level guarantees the recoverability of the deleted entity during the retention interval (90 days), unless a Purge operation is requested, or the subscription is cancelled. System wil permanently delete it after 90 days, if not recovered */
    KnownDeletionRecoveryLevel["RecoverablePurgeable"] = "Recoverable+Purgeable";
    /** Denotes a vault state in which deletion is recoverable without the possibility for immediate and permanent deletion (i.e. purge). This level guarantees the recoverability of the deleted entity during the retention interval(90 days) and while the subscription is still available. System wil permanently delete it after 90 days, if not recovered */
    KnownDeletionRecoveryLevel["Recoverable"] = "Recoverable";
    /** Denotes a vault and subscription state in which deletion is recoverable within retention interval (90 days), immediate and permanent deletion (i.e. purge) is not permitted, and in which the subscription itself  cannot be permanently canceled. System wil permanently delete it after 90 days, if not recovered */
    KnownDeletionRecoveryLevel["RecoverableProtectedSubscription"] = "Recoverable+ProtectedSubscription";
    /** Denotes a vault state in which deletion is recoverable, and which also permits immediate and permanent deletion (i.e. purge when 7<= SoftDeleteRetentionInDays < 90). This level guarantees the recoverability of the deleted entity during the retention interval, unless a Purge operation is requested, or the subscription is cancelled. */
    KnownDeletionRecoveryLevel["CustomizedRecoverablePurgeable"] = "CustomizedRecoverable+Purgeable";
    /** Denotes a vault state in which deletion is recoverable without the possibility for immediate and permanent deletion (i.e. purge when 7<= SoftDeleteRetentionInDays < 90).This level guarantees the recoverability of the deleted entity during the retention interval and while the subscription is still available. */
    KnownDeletionRecoveryLevel["CustomizedRecoverable"] = "CustomizedRecoverable";
    /** Denotes a vault and subscription state in which deletion is recoverable, immediate and permanent deletion (i.e. purge) is not permitted, and in which the subscription itself cannot be permanently canceled when 7<= SoftDeleteRetentionInDays < 90. This level guarantees the recoverability of the deleted entity during the retention interval, and also reflects the fact that the subscription itself cannot be cancelled. */
    KnownDeletionRecoveryLevel["CustomizedRecoverableProtectedSubscription"] = "CustomizedRecoverable+ProtectedSubscription";
})(exports.KnownDeletionRecoveryLevel || (exports.KnownDeletionRecoveryLevel = {}));
/** Known values of {@link JsonWebKeyCurveName} that the service accepts. */
exports.KnownKeyCurveNames = void 0;
(function (KnownJsonWebKeyCurveName) {
    /** The NIST P-256 elliptic curve, AKA SECG curve SECP256R1. */
    KnownJsonWebKeyCurveName["P256"] = "P-256";
    /** The NIST P-384 elliptic curve, AKA SECG curve SECP384R1. */
    KnownJsonWebKeyCurveName["P384"] = "P-384";
    /** The NIST P-521 elliptic curve, AKA SECG curve SECP521R1. */
    KnownJsonWebKeyCurveName["P521"] = "P-521";
    /** The SECG SECP256K1 elliptic curve. */
    KnownJsonWebKeyCurveName["P256K"] = "P-256K";
})(exports.KnownKeyCurveNames || (exports.KnownKeyCurveNames = {}));
/** Known values of {@link JsonWebKeyEncryptionAlgorithm} that the service accepts. */
var KnownJsonWebKeyEncryptionAlgorithm;
(function (KnownJsonWebKeyEncryptionAlgorithm) {
    KnownJsonWebKeyEncryptionAlgorithm["RSAOaep"] = "RSA-OAEP";
    KnownJsonWebKeyEncryptionAlgorithm["RSAOaep256"] = "RSA-OAEP-256";
    KnownJsonWebKeyEncryptionAlgorithm["RSA15"] = "RSA1_5";
    KnownJsonWebKeyEncryptionAlgorithm["A128GCM"] = "A128GCM";
    KnownJsonWebKeyEncryptionAlgorithm["A192GCM"] = "A192GCM";
    KnownJsonWebKeyEncryptionAlgorithm["A256GCM"] = "A256GCM";
    KnownJsonWebKeyEncryptionAlgorithm["A128KW"] = "A128KW";
    KnownJsonWebKeyEncryptionAlgorithm["A192KW"] = "A192KW";
    KnownJsonWebKeyEncryptionAlgorithm["A256KW"] = "A256KW";
    KnownJsonWebKeyEncryptionAlgorithm["A128CBC"] = "A128CBC";
    KnownJsonWebKeyEncryptionAlgorithm["A192CBC"] = "A192CBC";
    KnownJsonWebKeyEncryptionAlgorithm["A256CBC"] = "A256CBC";
    KnownJsonWebKeyEncryptionAlgorithm["A128Cbcpad"] = "A128CBCPAD";
    KnownJsonWebKeyEncryptionAlgorithm["A192Cbcpad"] = "A192CBCPAD";
    KnownJsonWebKeyEncryptionAlgorithm["A256Cbcpad"] = "A256CBCPAD";
})(KnownJsonWebKeyEncryptionAlgorithm || (KnownJsonWebKeyEncryptionAlgorithm = {}));
/** Known values of {@link JsonWebKeySignatureAlgorithm} that the service accepts. */
exports.KnownSignatureAlgorithms = void 0;
(function (KnownJsonWebKeySignatureAlgorithm) {
    /** RSASSA-PSS using SHA-256 and MGF1 with SHA-256, as described in https://tools.ietf.org/html/rfc7518 */
    KnownJsonWebKeySignatureAlgorithm["PS256"] = "PS256";
    /** RSASSA-PSS using SHA-384 and MGF1 with SHA-384, as described in https://tools.ietf.org/html/rfc7518 */
    KnownJsonWebKeySignatureAlgorithm["PS384"] = "PS384";
    /** RSASSA-PSS using SHA-512 and MGF1 with SHA-512, as described in https://tools.ietf.org/html/rfc7518 */
    KnownJsonWebKeySignatureAlgorithm["PS512"] = "PS512";
    /** RSASSA-PKCS1-v1_5 using SHA-256, as described in https://tools.ietf.org/html/rfc7518 */
    KnownJsonWebKeySignatureAlgorithm["RS256"] = "RS256";
    /** RSASSA-PKCS1-v1_5 using SHA-384, as described in https://tools.ietf.org/html/rfc7518 */
    KnownJsonWebKeySignatureAlgorithm["RS384"] = "RS384";
    /** RSASSA-PKCS1-v1_5 using SHA-512, as described in https://tools.ietf.org/html/rfc7518 */
    KnownJsonWebKeySignatureAlgorithm["RS512"] = "RS512";
    /** Reserved */
    KnownJsonWebKeySignatureAlgorithm["Rsnull"] = "RSNULL";
    /** ECDSA using P-256 and SHA-256, as described in https://tools.ietf.org/html/rfc7518. */
    KnownJsonWebKeySignatureAlgorithm["ES256"] = "ES256";
    /** ECDSA using P-384 and SHA-384, as described in https://tools.ietf.org/html/rfc7518 */
    KnownJsonWebKeySignatureAlgorithm["ES384"] = "ES384";
    /** ECDSA using P-521 and SHA-512, as described in https://tools.ietf.org/html/rfc7518 */
    KnownJsonWebKeySignatureAlgorithm["ES512"] = "ES512";
    /** ECDSA using P-256K and SHA-256, as described in https://tools.ietf.org/html/rfc7518 */
    KnownJsonWebKeySignatureAlgorithm["ES256K"] = "ES256K";
})(exports.KnownSignatureAlgorithms || (exports.KnownSignatureAlgorithms = {}));
/** Known values of {@link KeyEncryptionAlgorithm} that the service accepts. */
var KnownKeyEncryptionAlgorithm;
(function (KnownKeyEncryptionAlgorithm) {
    KnownKeyEncryptionAlgorithm["CKMRSAAESKEYWrap"] = "CKM_RSA_AES_KEY_WRAP";
    KnownKeyEncryptionAlgorithm["RSAAESKEYWrap256"] = "RSA_AES_KEY_WRAP_256";
    KnownKeyEncryptionAlgorithm["RSAAESKEYWrap384"] = "RSA_AES_KEY_WRAP_384";
})(KnownKeyEncryptionAlgorithm || (KnownKeyEncryptionAlgorithm = {}));

/*
 * 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"
                }
            },
            releasePolicy: {
                serializedName: "release_policy",
                type: {
                    name: "Composite",
                    className: "KeyReleasePolicy"
                }
            }
        }
    }
};
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 KeyReleasePolicy = {
    type: {
        name: "Composite",
        className: "KeyReleasePolicy",
        modelProperties: {
            contentType: {
                defaultValue: "application/json; charset=utf-8",
                serializedName: "contentType",
                type: {
                    name: "String"
                }
            },
            immutable: {
                serializedName: "immutable",
                type: {
                    name: "Boolean"
                }
            },
            encodedPolicy: {
                serializedName: "data",
                type: {
                    name: "Base64Url"
                }
            }
        }
    }
};
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"
                }
            },
            releasePolicy: {
                serializedName: "release_policy",
                type: {
                    name: "Composite",
                    className: "KeyReleasePolicy"
                }
            }
        }
    }
};
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" } }
                }
            },
            releasePolicy: {
                serializedName: "release_policy",
                type: {
                    name: "Composite",
                    className: "KeyReleasePolicy"
                }
            }
        }
    }
};
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" } }
                }
            },
            releasePolicy: {
                serializedName: "release_policy",
                type: {
                    name: "Composite",
                    className: "KeyReleasePolicy"
                }
            }
        }
    }
};
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 KeyReleaseParameters = {
    type: {
        name: "Composite",
        className: "KeyReleaseParameters",
        modelProperties: {
            targetAttestationToken: {
                constraints: {
                    MinLength: 1
                },
                serializedName: "target",
                required: true,
                type: {
                    name: "String"
                }
            },
            nonce: {
                serializedName: "nonce",
                type: {
                    name: "String"
                }
            },
            enc: {
                serializedName: "enc",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const KeyReleaseResult = {
    type: {
        name: "Composite",
        className: "KeyReleaseResult",
        modelProperties: {
            value: {
                serializedName: "value",
                readOnly: true,
                type: {
                    name: "String"
                }
            }
        }
    }
};
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 KeyRotationPolicy = {
    type: {
        name: "Composite",
        className: "KeyRotationPolicy",
        modelProperties: {
            id: {
                serializedName: "id",
                readOnly: true,
                type: {
                    name: "String"
                }
            },
            lifetimeActions: {
                serializedName: "lifetimeActions",
                type: {
                    name: "Sequence",
                    element: {
                        type: {
                            name: "Composite",
                            className: "LifetimeActions"
                        }
                    }
                }
            },
            attributes: {
                serializedName: "attributes",
                type: {
                    name: "Composite",
                    className: "KeyRotationPolicyAttributes"
                }
            }
        }
    }
};
const LifetimeActions = {
    type: {
        name: "Composite",
        className: "LifetimeActions",
        modelProperties: {
            trigger: {
                serializedName: "trigger",
                type: {
                    name: "Composite",
                    className: "LifetimeActionsTrigger"
                }
            },
            action: {
                serializedName: "action",
                type: {
                    name: "Composite",
                    className: "LifetimeActionsType"
                }
            }
        }
    }
};
const LifetimeActionsTrigger = {
    type: {
        name: "Composite",
        className: "LifetimeActionsTrigger",
        modelProperties: {
            timeAfterCreate: {
                serializedName: "timeAfterCreate",
                type: {
                    name: "String"
                }
            },
            timeBeforeExpiry: {
                serializedName: "timeBeforeExpiry",
                type: {
                    name: "String"
                }
            }
        }
    }
};
const LifetimeActionsType = {
    type: {
        name: "Composite",
        className: "LifetimeActionsType",
        modelProperties: {
            type: {
                serializedName: "type",
                type: {
                    name: "Enum",
                    allowedValues: ["Rotate", "Notify"]
                }
            }
        }
    }
};
const KeyRotationPolicyAttributes = {
    type: {
        name: "Composite",
        className: "KeyRotationPolicyAttributes",
        modelProperties: {
            expiryTime: {
                serializedName: "expiryTime",
                type: {
                    name: "String"
                }
            },
            created: {
                serializedName: "created",
                readOnly: true,
                type: {
                    name: "UnixTime"
                }
            },
            updated: {
                serializedName: "updated",
                readOnly: true,
                type: {
                    name: "UnixTime"
                }
            }
        }
    }
};
const GetRandomBytesRequest = {
    type: {
        name: "Composite",
        className: "GetRandomBytesRequest",
        modelProperties: {
            count: {
                constraints: {
                    InclusiveMaximum: 128,
                    InclusiveMinimum: 1
                },
                serializedName: "count",
                required: true,
                type: {
                    name: "Number"
                }
            }
        }
    }
};
const RandomBytes = {
    type: {
        name: "Composite",
        className: "RandomBytes",
        modelProperties: {
            value: {
                serializedName: "value",
                required: true,
                type: {
                    name: "Base64Url"
                }
            }
        }
    }
};
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 KeyExportParameters = {
    type: {
        name: "Composite",
        className: "KeyExportParameters",
        modelProperties: {
            wrappingKey: {
                serializedName: "wrappingKey",
                type: {
                    name: "Composite",
                    className: "JsonWebKey"
                }
            },
            wrappingKid: {
                serializedName: "wrappingKid",
                type: {
                    name: "String"
                }
            },
            enc: {
                serializedName: "enc",
                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"
                }
            }, exportable: {
                serializedName: "exportable",
                type: {
                    name: "Boolean"
                }
            } })
    }
};
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,
    KeyReleasePolicy: KeyReleasePolicy,
    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,
    KeyReleaseParameters: KeyReleaseParameters,
    KeyReleaseResult: KeyReleaseResult,
    DeletedKeyListResult: DeletedKeyListResult,
    KeyRotationPolicy: KeyRotationPolicy,
    LifetimeActions: LifetimeActions,
    LifetimeActionsTrigger: LifetimeActionsTrigger,
    LifetimeActionsType: LifetimeActionsType,
    KeyRotationPolicyAttributes: KeyRotationPolicyAttributes,
    GetRandomBytesRequest: GetRandomBytesRequest,
    RandomBytes: RandomBytes,
    KeyProperties: KeyProperties,
    KeyExportParameters: KeyExportParameters,
    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 keyRotationPolicy = {
    parameterPath: "keyRotationPolicy",
    mapper: KeyRotationPolicy
};
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.
 */
class KeyVaultClient extends coreHttpCompat__namespace.ExtendedServiceClient {
    /**
     * Initializes a new instance of the KeyVaultClient class.
     * @param apiVersion Api Version
     * @param options The parameter options
     */
    constructor(apiVersion, options) {
        var _a, _b;
        if (apiVersion === undefined) {
            throw new Error("'apiVersion' cannot be null");
        }
        // Initializing default values for options
        if (!options) {
            options = {};
        }
        const defaults = {
            requestContentType: "application/json; charset=utf-8"
        };
        const packageDetails = `azsdk-js-keyvault-keys/4.7.2`;
        const userAgentPrefix = options.userAgentOptions && options.userAgentOptions.userAgentPrefix
            ? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`
            : `${packageDetails}`;
        const optionsWithDefaults = Object.assign(Object.assign(Object.assign({}, defaults), options), { userAgentOptions: {
                userAgentPrefix
            }, baseUri: (_b = (_a = options.endpoint) !== null && _a !== void 0 ? _a : options.baseUri) !== null && _b !== void 0 ? _b : "{vaultBaseUrl}" });
        super(optionsWithDefaults);
        if ((options === null || options === void 0 ? void 0 : options.pipeline) && options.pipeline.getOrderedPolicies().length > 0) {
            const pipelinePolicies = options.pipeline.getOrderedPolicies();
            const bearerTokenAuthenticationPolicyFound = pipelinePolicies.some((pipelinePolicy) => pipelinePolicy.name ===
                coreRestPipeline__namespace.bearerTokenAuthenticationPolicyName);
            if (!bearerTokenAuthenticationPolicyFound) {
                this.pipeline.removePolicy({
                    name: coreRestPipeline__namespace.bearerTokenAuthenticationPolicyName
                });
                this.pipeline.addPolicy(coreRestPipeline__namespace.bearerTokenAuthenticationPolicy({
                    scopes: `${optionsWithDefaults.baseUri}/.default`,
                    challengeCallbacks: {
                        authorizeRequestOnChallenge: coreClient__namespace.authorizeRequestOnClaimChallenge
                    }
                }));
            }
        }
        // Parameter assignments
        this.apiVersion = apiVersion;
    }
    /**
     * 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.
     *                The value you provide may be copied globally for the purpose of running the service. The value
     *                provided should not include personally identifiable or sensitive information.
     * @param kty The type of key to create. For valid values, see JsonWebKeyType.
     * @param options The options parameters.
     */
    createKey(vaultBaseUrl, keyName, kty, options) {
        return this.sendOperationRequest({ vaultBaseUrl, keyName, kty, options }, createKeyOperationSpec);
    }
    /**
     * The operation will rotate the key based on the key policy. It requires the keys/rotate permission.
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of key to be rotated. The system will generate a new version in the
     *                specified key.
     * @param options The options parameters.
     */
    rotateKey(vaultBaseUrl, keyName, options) {
        return this.sendOperationRequest({ vaultBaseUrl, keyName, options }, rotateKeyOperationSpec);
    }
    /**
     * 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. The value you provide may be copied globally for the
     *                purpose of running the service. The value provided should not include personally identifiable or
     *                sensitive information.
     * @param key The Json web key
     * @param options The options parameters.
     */
    importKey(vaultBaseUrl, keyName, key, options) {
        return this.sendOperationRequest({ vaultBaseUrl, keyName, key, options }, 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) {
        return this.sendOperationRequest({ vaultBaseUrl, keyName, options }, 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) {
        return this.sendOperationRequest({ vaultBaseUrl, keyName, keyVersion, options }, 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) {
        return this.sendOperationRequest({ vaultBaseUrl, keyName, keyVersion, options }, 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) {
        return this.sendOperationRequest({ vaultBaseUrl, keyName, options }, 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) {
        return this.sendOperationRequest({ vaultBaseUrl, options }, 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) {
        return this.sendOperationRequest({ vaultBaseUrl, keyName, options }, 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) {
        return this.sendOperationRequest({ vaultBaseUrl, keyBundleBackup, options }, 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) {
        return this.sendOperationRequest({ vaultBaseUrl, keyName, keyVersion, algorithm, value, options }, 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.
     * Microsoft recommends not to use CBC algorithms for decryption without first ensuring the integrity
     * of the ciphertext using an HMAC, for example. See
     * https://docs.microsoft.com/dotnet/standard/security/vulnerabilities-cbc-mode for more information.
     * @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) {
        return this.sendOperationRequest({ vaultBaseUrl, keyName, keyVersion, algorithm, value, options }, 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) {
        return this.sendOperationRequest({ vaultBaseUrl, keyName, keyVersion, algorithm, value, options }, 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) {
        return this.sendOperationRequest({
            vaultBaseUrl,
            keyName,
            keyVersion,
            algorithm,
            digest,
            signature,
            options
        }, 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) {
        return this.sendOperationRequest({ vaultBaseUrl, keyName, keyVersion, algorithm, value, options }, 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) {
        return this.sendOperationRequest({ vaultBaseUrl, keyName, keyVersion, algorithm, value, options }, unwrapKeyOperationSpec);
    }
    /**
     * The release key operation is applicable to all key types. The target key must be marked exportable.
     * This operation requires the keys/release 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.
     * @param targetAttestationToken The attestation assertion for the target of the key release.
     * @param options The options parameters.
     */
    release(vaultBaseUrl, keyName, keyVersion, targetAttestationToken, options) {
        return this.sendOperationRequest({ vaultBaseUrl, keyName, keyVersion, targetAttestationToken, options }, releaseOperationSpec);
    }
    /**
     * 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) {
        return this.sendOperationRequest({ vaultBaseUrl, options }, 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) {
        return this.sendOperationRequest({ vaultBaseUrl, keyName, options }, 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) {
        return this.sendOperationRequest({ vaultBaseUrl, keyName, options }, 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) {
        return this.sendOperationRequest({ vaultBaseUrl, keyName, options }, recoverDeletedKeyOperationSpec);
    }
    /**
     * The GetKeyRotationPolicy operation returns the specified key policy resources in the specified key
     * 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 in a given key vault.
     * @param options The options parameters.
     */
    getKeyRotationPolicy(vaultBaseUrl, keyName, options) {
        return this.sendOperationRequest({ vaultBaseUrl, keyName, options }, getKeyRotationPolicyOperationSpec);
    }
    /**
     * Set specified members in the key policy. Leave others as undefined. This operation requires the
     * keys/update permission.
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param keyName The name of the key in the given vault.
     * @param keyRotationPolicy The policy for the key.
     * @param options The options parameters.
     */
    updateKeyRotationPolicy(vaultBaseUrl, keyName, keyRotationPolicy, options) {
        return this.sendOperationRequest({ vaultBaseUrl, keyName, keyRotationPolicy, options }, updateKeyRotationPolicyOperationSpec);
    }
    /**
     * Get the requested number of bytes containing random values from a managed HSM.
     * @param vaultBaseUrl The vault name, for example https://myvault.vault.azure.net.
     * @param count The requested number of random bytes.
     * @param options The options parameters.
     */
    getRandomBytes(vaultBaseUrl, count, options) {
        return this.sendOperationRequest({ vaultBaseUrl, count, options }, getRandomBytesOperationSpec);
    }
    /**
     * 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) {
        return this.sendOperationRequest({ vaultBaseUrl, keyName, nextLink, options }, 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) {
        return this.sendOperationRequest({ vaultBaseUrl, nextLink, options }, 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) {
        return this.sendOperationRequest({ vaultBaseUrl, nextLink, options }, getDeletedKeysNextOperationSpec);
    }
}
// Operation Specifications
const serializer = coreClient__namespace.createSerializer(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"],
            releasePolicy: ["options", "releasePolicy"]
        },
        mapper: Object.assign(Object.assign({}, KeyCreateParameters), { required: true })
    },
    queryParameters: [apiVersion],
    urlParameters: [vaultBaseUrl, keyName],
    headerParameters: [contentType, accept],
    mediaType: "json",
    serializer
};
const rotateKeyOperationSpec = {
    path: "/keys/{key-name}/rotate",
    httpMethod: "POST",
    responses: {
        200: {
            bodyMapper: KeyBundle
        },
        default: {
            bodyMapper: KeyVaultError
        }
    },
    queryParameters: [apiVersion],
    urlParameters: [vaultBaseUrl, keyName],
    headerParameters: [accept],
    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"],
            releasePolicy: ["options", "releasePolicy"]
        },
        mapper: Object.assign(Object.assign({}, KeyImportParameters), { required: true })
    },
    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"],
            releasePolicy: ["options", "releasePolicy"]
        },
        mapper: Object.assign(Object.assign({}, KeyUpdateParameters), { required: true })
    },
    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: Object.assign(Object.assign({}, KeyRestoreParameters), { required: true })
    },
    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: Object.assign(Object.assign({}, KeyOperationsParameters), { required: true })
    },
    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: Object.assign(Object.assign({}, KeyOperationsParameters), { required: true })
    },
    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: Object.assign(Object.assign({}, KeySignParameters), { required: true })
    },
    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: Object.assign(Object.assign({}, KeyVerifyParameters), { required: true })
    },
    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: Object.assign(Object.assign({}, KeyOperationsParameters), { required: true })
    },
    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: Object.assign(Object.assign({}, KeyOperationsParameters), { required: true })
    },
    queryParameters: [apiVersion],
    urlParameters: [
        vaultBaseUrl,
        keyName1,
        keyVersion
    ],
    headerParameters: [contentType, accept],
    mediaType: "json",
    serializer
};
const releaseOperationSpec = {
    path: "/keys/{key-name}/{key-version}/release",
    httpMethod: "POST",
    responses: {
        200: {
            bodyMapper: KeyReleaseResult
        },
        default: {
            bodyMapper: KeyVaultError
        }
    },
    requestBody: {
        parameterPath: {
            targetAttestationToken: ["targetAttestationToken"],
            nonce: ["options", "nonce"],
            enc: ["options", "enc"]
        },
        mapper: Object.assign(Object.assign({}, KeyReleaseParameters), { required: true })
    },
    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 getKeyRotationPolicyOperationSpec = {
    path: "/keys/{key-name}/rotationpolicy",
    httpMethod: "GET",
    responses: {
        200: {
            bodyMapper: KeyRotationPolicy
        },
        default: {
            bodyMapper: KeyVaultError
        }
    },
    queryParameters: [apiVersion],
    urlParameters: [vaultBaseUrl, keyName1],
    headerParameters: [accept],
    serializer
};
const updateKeyRotationPolicyOperationSpec = {
    path: "/keys/{key-name}/rotationpolicy",
    httpMethod: "PUT",
    responses: {
        200: {
            bodyMapper: KeyRotationPolicy
        },
        default: {
            bodyMapper: KeyVaultError
        }
    },
    requestBody: keyRotationPolicy,
    queryParameters: [apiVersion],
    urlParameters: [vaultBaseUrl, keyName1],
    headerParameters: [contentType, accept],
    mediaType: "json",
    serializer
};
const getRandomBytesOperationSpec = {
    path: "/rng",
    httpMethod: "POST",
    responses: {
        200: {
            bodyMapper: RandomBytes
        },
        default: {
            bodyMapper: KeyVaultError
        }
    },
    requestBody: {
        parameterPath: { count: ["count"] },
        mapper: Object.assign(Object.assign({}, GetRandomBytesRequest), { required: true })
    },
    queryParameters: [apiVersion],
    urlParameters: [vaultBaseUrl],
    headerParameters: [contentType, accept],
    mediaType: "json",
    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.7.2";

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
const validWWWAuthenticateProperties = [
    "authorization",
    "authorization_url",
    "resource",
    "scope",
    "tenantId",
];
/**
 * Parses an WWW-Authenticate response header.
 * This transforms a string value like:
 * `Bearer authorization="https://some.url/tenantId", resource="https://some.url"`
 * into an object like:
 * `{ authorization: "https://some.url/tenantId", resource: "https://some.url" }`
 * @param headerValue - String value in the WWW-Authenticate header
 */
function parseWWWAuthenticateHeader(headerValue) {
    const pairDelimiter = /,? +/;
    const parsed = headerValue.split(pairDelimiter).reduce((kvPairs, p) => {
        if (p.match(/\w="/)) {
            // 'sampleKey="sample_value"' -> [sampleKey, "sample_value"] -> { sampleKey: sample_value }
            const [key, value] = p.split("=");
            if (validWWWAuthenticateProperties.includes(key)) {
                // The values will be wrapped in quotes, which need to be stripped out.
                return Object.assign(Object.assign({}, kvPairs), { [key]: value.slice(1, -1) });
            }
        }
        return kvPairs;
    }, {});
    // Finally, we pull the tenantId from the authorization header to support multi-tenant authentication.
    if (parsed.authorization) {
        try {
            const tenantId = new URL(parsed.authorization).pathname.substring(1);
            if (tenantId) {
                parsed.tenantId = tenantId;
            }
        }
        catch (_) {
            throw new Error(`The challenge authorization URI '${parsed.authorization}' is invalid.`);
        }
    }
    return parsed;
}

// Copyright (c) Microsoft Corporation.
function verifyChallengeResource(scope, request) {
    let scopeAsUrl;
    try {
        scopeAsUrl = new URL(scope);
    }
    catch (e) {
        throw new Error(`The challenge contains invalid scope '${scope}'`);
    }
    const requestUrl = new URL(request.url);
    if (!requestUrl.hostname.endsWith(`.${scopeAsUrl.hostname}`)) {
        throw new Error(`The challenge resource '${scopeAsUrl.hostname}' does not match the requested domain. Set disableChallengeResourceVerification to true in your client options to disable. See https://aka.ms/azsdk/blog/vault-uri for more information.`);
    }
}
/**
 * Creates challenge callback handlers to manage CAE lifecycle in Azure Key Vault.
 *
 * Key Vault supports other authentication schemes, but we ensure challenge authentication
 * is used by first sending a copy of the request, without authorization or content.
 *
 * when the challenge is received, it will be authenticated and used to send the original
 * request with authorization.
 *
 * Following the first request of a client, follow-up requests will get the cached token
 * if possible.
 *
 */
function createKeyVaultChallengeCallbacks(options = {}) {
    const { disableChallengeResourceVerification } = options;
    let challengeState = { status: "none" };
    function requestToOptions(request) {
        return {
            abortSignal: request.abortSignal,
            requestOptions: {
                timeout: request.timeout > 0 ? request.timeout : undefined,
            },
            tracingOptions: request.tracingOptions,
        };
    }
    async function authorizeRequest({ request, getAccessToken, }) {
        const requestOptions = requestToOptions(request);
        switch (challengeState.status) {
            case "none":
                challengeState = {
                    status: "started",
                    originalBody: request.body,
                };
                request.body = null;
                break;
            case "started":
                break; // Retry, we should not overwrite the original body
            case "complete": {
                const token = await getAccessToken(challengeState.scopes, requestOptions);
                if (token) {
                    request.headers.set("authorization", `Bearer ${token.token}`);
                }
                break;
            }
        }
        return Promise.resolve();
    }
    async function authorizeRequestOnChallenge({ request, response, getAccessToken, }) {
        if (request.body === null && challengeState.status === "started") {
            // Reset the original body before doing anything else.
            // Note: If successful status will be "complete", otherwise "none" will
            // restart the process.
            request.body = challengeState.originalBody;
        }
        const getTokenOptions = requestToOptions(request);
        const challenge = response.headers.get("WWW-Authenticate");
        if (!challenge) {
            throw new Error("Missing challenge.");
        }
        const parsedChallenge = parseWWWAuthenticateHeader(challenge) || {};
        const scope = parsedChallenge.resource
            ? parsedChallenge.resource + "/.default"
            : parsedChallenge.scope;
        if (!scope) {
            throw new Error("Missing scope.");
        }
        if (!disableChallengeResourceVerification) {
            verifyChallengeResource(scope, request);
        }
        const accessToken = await getAccessToken([scope], Object.assign(Object.assign({}, getTokenOptions), { tenantId: parsedChallenge.tenantId }));
        if (!accessToken) {
            return false;
        }
        request.headers.set("Authorization", `Bearer ${accessToken.token}`);
        challengeState = {
            status: "complete",
            scopes: [scope],
        };
        return true;
    }
    return {
        authorizeRequest,
        authorizeRequestOnChallenge,
    };
}

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
/**
 * Parses a Key Vault identifier into its components.
 *
 * @param collection - The collection of the Key Vault identifier.
 * @param identifier - The Key Vault identifier to be parsed.
 */
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 = new URL(identifier);
    }
    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.
const tracingClient = coreTracing.createTracingClient({
    namespace: "Microsoft.KeyVault",
    packageName: "@azure/keyvault-keys",
    packageVersion: SDK_VERSION,
});

// 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,
            exportable: attributes.exportable,
            releasePolicy: keyBundle.releasePolicy,
            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;
}
/**
 * @internal
 */
const keyRotationTransformations = {
    propertiesToGenerated: function (parameters) {
        var _a;
        const policy = {
            attributes: {
                expiryTime: parameters.expiresIn,
            },
            lifetimeActions: (_a = parameters.lifetimeActions) === null || _a === void 0 ? void 0 : _a.map((action) => {
                const generatedAction = {
                    action: { type: action.action },
                    trigger: {},
                };
                if (action.timeAfterCreate) {
                    generatedAction.trigger.timeAfterCreate = action.timeAfterCreate;
                }
                if (action.timeBeforeExpiry) {
                    generatedAction.trigger.timeBeforeExpiry = action.timeBeforeExpiry;
                }
                return generatedAction;
            }),
        };
        return policy;
    },
    generatedToPublic(generated) {
        var _a, _b, _c, _d;
        const policy = {
            id: generated.id,
            createdOn: (_a = generated.attributes) === null || _a === void 0 ? void 0 : _a.created,
            updatedOn: (_b = generated.attributes) === null || _b === void 0 ? void 0 : _b.updated,
            expiresIn: (_c = generated.attributes) === null || _c === void 0 ? void 0 : _c.expiryTime,
            lifetimeActions: (_d = generated.lifetimeActions) === null || _d === void 0 ? void 0 : _d.map((action) => {
                var _a, _b;
                return {
                    action: action.action.type,
                    timeAfterCreate: (_a = action.trigger) === null || _a === void 0 ? void 0 : _a.timeAfterCreate,
                    timeBeforeExpiry: (_b = action.trigger) === null || _b === void 0 ? void 0 : _b.timeBeforeExpiry,
                };
            }),
        };
        return policy;
    },
};

// 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 coreUtil.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.
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 tracingClient.withSpan("DeleteKeyPoller.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 tracingClient.withSpan("DeleteKeyPoller.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.
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 tracingClient.withSpan("RecoverDeleteKeyPoller.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 tracingClient.withSpan("RecoverDeletedKeyPoller.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.
/**
 * The latest supported Key Vault service API version
 */
const LATEST_API_VERSION = "7.4";
/** Known values of {@link KeyOperation} that the service accepts. */
exports.KnownKeyOperations = void 0;
(function (KnownKeyOperations) {
    /** Key operation - encrypt */
    KnownKeyOperations["Encrypt"] = "encrypt";
    /** Key operation - decrypt */
    KnownKeyOperations["Decrypt"] = "decrypt";
    /** Key operation - sign */
    KnownKeyOperations["Sign"] = "sign";
    /** Key operation - verify */
    KnownKeyOperations["Verify"] = "verify";
    /** Key operation - wrapKey */
    KnownKeyOperations["WrapKey"] = "wrapKey";
    /** Key operation - unwrapKey */
    KnownKeyOperations["UnwrapKey"] = "unwrapKey";
    /** Key operation - import */
    KnownKeyOperations["Import"] = "import";
})(exports.KnownKeyOperations || (exports.KnownKeyOperations = {}));
/** Known values of {@link KeyExportEncryptionAlgorithm} that the service accepts. */
exports.KnownKeyExportEncryptionAlgorithm = void 0;
(function (KnownKeyExportEncryptionAlgorithm) {
    /** CKM_RSA_AES_KEY_WRAP Key Export Encryption Algorithm */
    KnownKeyExportEncryptionAlgorithm["CkmRsaAesKeyWrap"] = "CKM_RSA_AES_KEY_WRAP";
    /** RSA_AES_KEY_WRAP_256 Key Export Encryption Algorithm */
    KnownKeyExportEncryptionAlgorithm["RsaAesKeyWrap256"] = "RSA_AES_KEY_WRAP_256";
    /** RSA_AES_KEY_WRAP_384 Key Export Encryption Algorithm */
    KnownKeyExportEncryptionAlgorithm["RsaAesKeyWrap384"] = "RSA_AES_KEY_WRAP_384";
})(exports.KnownKeyExportEncryptionAlgorithm || (exports.KnownKeyExportEncryptionAlgorithm = {}));

// 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.
/**
 * The remote cryptography provider is used to run crypto operations against KeyVault.
 * @internal
 */
class RemoteCryptographyProvider {
    constructor(key, credential, pipelineOptions = {}) {
        var _a;
        this.client = getOrInitializeClient(credential, pipelineOptions);
        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.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 = (_a = parsed.version) !== null && _a !== void 0 ? _a : "";
        }
        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 tracingClient.withSpan("RemoteCryptographyProvider.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 tracingClient.withSpan("RemoteCryptographyProvider.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 tracingClient.withSpan("RemoteCryptographyProvider.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 tracingClient.withSpan("RemoteCryptographyProvider.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 tracingClient.withSpan("RemoteCryptographyProvider.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 tracingClient.withSpan("RemoteCryptographyProvider.verifyData", options, async (updatedOptions) => {
            const hash = await createHash(algorithm, data);
            return this.verify(algorithm, hash, signature, updatedOptions);
        });
    }
    verify(algorithm, digest, signature, options = {}) {
        return tracingClient.withSpan("RemoteCryptographyProvider.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 tracingClient.withSpan("RemoteCryptographyProvider.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 tracingClient.withSpan("RemoteCryptographyProvider.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.
     */
    getKeyID() {
        let kid;
        if (typeof this.key !== "string") {
            kid = this.key.id;
        }
        else {
            kid = this.key;
        }
        return kid;
    }
}
/**
 * A helper method to either get the passed down generated client or initialize a new one.
 * An already constructed generated client may be passed down from {@link KeyClient} in which case we should reuse it.
 *
 * @internal
 * @param credential - The credential to use when initializing a new client.
 * @param options - The options for constructing a client or the underlying client if one already exists.
 * @returns - A generated client instance
 */
function getOrInitializeClient(credential, options) {
    if (options.generatedClient) {
        return options.generatedClient;
    }
    const libInfo = `azsdk-js-keyvault-keys/${SDK_VERSION}`;
    const userAgentOptions = options.userAgentOptions;
    options.userAgentOptions = {
        userAgentPrefix: userAgentOptions && userAgentOptions.userAgentPrefix
            ? `${userAgentOptions.userAgentPrefix} ${libInfo}`
            : libInfo,
    };
    const authPolicy = coreRestPipeline.bearerTokenAuthenticationPolicy({
        credential,
        scopes: [],
        challengeCallbacks: createKeyVaultChallengeCallbacks(options),
    });
    const internalPipelineOptions = Object.assign(Object.assign({}, options), { loggingOptions: {
            logger: logger.info,
            allowedHeaderNames: [
                "x-ms-keyvault-region",
                "x-ms-keyvault-network-info",
                "x-ms-keyvault-service-version",
            ],
        } });
    const client = new KeyVaultClient(options.serviceVersion || LATEST_API_VERSION, internalPipelineOptions);
    client.pipeline.addPolicy(authPolicy);
    return client;
}

// 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
         */
        this.applicableAlgorithms = [
            "RSA1_5",
            "RSA-OAEP",
            "PS256",
            "RS256",
            "PS384",
            "RS384",
            "PS512",
            "RS512",
        ];
        /**
         * The set of operations this provider supports
         */
        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__namespace.randomBytes(16);
        this.ensureValid(keySizeInBytes);
        const cipher = crypto__namespace.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__namespace.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.
/**
 * 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" || this.key.kind === "remoteOnlyIdentifier") {
            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 tracingClient.withSpan("CryptographyClient.encrypt", options, async (updatedOptions) => {
            this.ensureValid(await this.fetchKey(updatedOptions), exports.KnownKeyOperations.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 tracingClient.withSpan("CryptographyClient.decrypt", options, async (updatedOptions) => {
            this.ensureValid(await this.fetchKey(updatedOptions), exports.KnownKeyOperations.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 tracingClient.withSpan("CryptographyClient.wrapKey", options, async (updatedOptions) => {
            this.ensureValid(await this.fetchKey(updatedOptions), exports.KnownKeyOperations.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 tracingClient.withSpan("CryptographyClient.unwrapKey", options, async (updatedOptions) => {
            this.ensureValid(await this.fetchKey(updatedOptions), exports.KnownKeyOperations.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 tracingClient.withSpan("CryptographyClient.sign", options, async (updatedOptions) => {
            this.ensureValid(await this.fetchKey(updatedOptions), exports.KnownKeyOperations.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 tracingClient.withSpan("CryptographyClient.verify", options, async (updatedOptions) => {
            this.ensureValid(await this.fetchKey(updatedOptions), exports.KnownKeyOperations.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 tracingClient.withSpan("CryptographyClient.signData", options, async (updatedOptions) => {
            this.ensureValid(await this.fetchKey(updatedOptions), exports.KnownKeyOperations.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 tracingClient.withSpan("CryptographyClient.verifyData", options, async (updatedOptions) => {
            this.ensureValid(await this.fetchKey(updatedOptions), exports.KnownKeyOperations.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;
            }
        });
    }
    /**
     * Retrieves the {@link JsonWebKey} from the Key Vault, if possible. Returns undefined if the key could not be retrieved due to insufficient permissions.
     *
     * 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:
                return undefined;
        }
    }
    /**
     * Returns the underlying key used for cryptographic operations.
     * If needed, attempts to fetch 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
            let key;
            try {
                key = await this.remoteProvider.getKey(options);
            }
            catch (e) {
                if (coreRestPipeline.isRestError(e) && e.statusCode === 403) {
                    // If we don't have permission to get the key, we'll fall back to using the remote provider.
                    // Marking the key as a remoteOnlyIdentifier will ensure that we don't attempt to fetch the key again.
                    logger.verbose(`Permission denied to get key ${this.key.value}. Falling back to remote operation.`);
                    this.key = { kind: "remoteOnlyIdentifier", value: this.key.value };
                }
                else {
                    throw e;
                }
            }
            if (key) {
                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);
            this.providers = [];
            // Add local crypto providers as needed
            if (keyMaterial) {
                this.providers.push(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.
/** Known values of {@link EncryptionAlgorithm} that the service accepts. */
exports.KnownEncryptionAlgorithms = void 0;
(function (KnownEncryptionAlgorithms) {
    /** Encryption Algorithm - RSA-OAEP */
    KnownEncryptionAlgorithms["RSAOaep"] = "RSA-OAEP";
    /** Encryption Algorithm - RSA-OAEP-256 */
    KnownEncryptionAlgorithms["RSAOaep256"] = "RSA-OAEP-256";
    /** Encryption Algorithm - RSA1_5 */
    KnownEncryptionAlgorithms["RSA15"] = "RSA1_5";
    /** Encryption Algorithm - A128GCM */
    KnownEncryptionAlgorithms["A128GCM"] = "A128GCM";
    /** Encryption Algorithm - A192GCM */
    KnownEncryptionAlgorithms["A192GCM"] = "A192GCM";
    /** Encryption Algorithm - A256GCM */
    KnownEncryptionAlgorithms["A256GCM"] = "A256GCM";
    /** Encryption Algorithm - A128KW */
    KnownEncryptionAlgorithms["A128KW"] = "A128KW";
    /** Encryption Algorithm - A192KW */
    KnownEncryptionAlgorithms["A192KW"] = "A192KW";
    /** Encryption Algorithm - A256KW */
    KnownEncryptionAlgorithms["A256KW"] = "A256KW";
    /** Encryption Algorithm - A128CBC */
    KnownEncryptionAlgorithms["A128CBC"] = "A128CBC";
    /** Encryption Algorithm - A192CBC */
    KnownEncryptionAlgorithms["A192CBC"] = "A192CBC";
    /** Encryption Algorithm - A256CBC */
    KnownEncryptionAlgorithms["A256CBC"] = "A256CBC";
    /** Encryption Algorithm - A128CBCPAD */
    KnownEncryptionAlgorithms["A128Cbcpad"] = "A128CBCPAD";
    /** Encryption Algorithm - A192CBCPAD */
    KnownEncryptionAlgorithms["A192Cbcpad"] = "A192CBCPAD";
    /** Encryption Algorithm - A256CBCPAD */
    KnownEncryptionAlgorithms["A256Cbcpad"] = "A256CBCPAD";
})(exports.KnownEncryptionAlgorithms || (exports.KnownEncryptionAlgorithms = {}));

// Copyright (c) Microsoft Corporation.
/**
 * 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`. You should validate that this URL references a valid Key Vault or Managed HSM resource. See https://aka.ms/azsdk/blog/vault-uri for details.
     * @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 = coreRestPipeline.bearerTokenAuthenticationPolicy({
            credential,
            scopes: [],
            challengeCallbacks: createKeyVaultChallengeCallbacks(pipelineOptions),
        });
        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.credential = credential;
        this.client = new KeyVaultClient(pipelineOptions.serviceVersion || LATEST_API_VERSION, internalPipelineOptions);
        this.client.pipeline.addPolicy(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, exportable } = options, remainingOptions = tslib.__rest(options, ["enabled", "notBefore", "expiresOn", "exportable"]);
            unflattenedOptions = Object.assign(Object.assign({}, remainingOptions), { keyAttributes: {
                    enabled,
                    notBefore,
                    expires,
                    exportable,
                } });
        }
        return tracingClient.withSpan("KeyClient.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) ? exports.KnownKeyTypes.ECHSM : exports.KnownKeyTypes.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) ? exports.KnownKeyTypes.RSAHSM : exports.KnownKeyTypes.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) ? exports.KnownKeyTypes.OctHSM : exports.KnownKeyTypes.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, exportable, expiresOn: expires, hardwareProtected: hsm } = options, remainingOptions = tslib.__rest(options, ["enabled", "notBefore", "exportable", "expiresOn", "hardwareProtected"]);
            unflattenedOptions = Object.assign(Object.assign({}, remainingOptions), { keyAttributes: {
                    enabled,
                    notBefore,
                    expires,
                    hsm,
                    exportable,
                } });
        }
        return tracingClient.withSpan(`KeyClient.importKey`, unflattenedOptions, async (updatedOptions) => {
            const response = await this.client.importKey(this.vaultUrl, name, key, updatedOptions);
            return getKeyFromKeyBundle(response);
        });
    }
    /**
     * Gets a {@link CryptographyClient} for the given key.
     *
     * Example usage:
     * ```ts
     * let client = new KeyClient(url, credentials);
     * // get a cryptography client for a given key
     * let cryptographyClient = client.getCryptographyClient("MyKey");
     * ```
     * @param name - The name of the key used to perform cryptographic operations.
     * @param version - Optional version of the key used to perform cryptographic operations.
     * @returns - A {@link CryptographyClient} using the same options, credentials, and http client as this {@link KeyClient}
     */
    getCryptographyClient(keyName, options) {
        const keyUrl = new URL(["keys", keyName, options === null || options === void 0 ? void 0 : options.keyVersion].filter(Boolean).join("/"), this.vaultUrl);
        // The goals of this method are discoverability and performance (by sharing a client and pipeline).
        // The existing cryptography client does not accept a pipeline as an argument, nor does it expose it.
        // In order to avoid publicly exposing the pipeline we will pass in the underlying client as an undocumented
        // property to the constructor so that crypto providers downstream can use it.
        const constructorOptions = {
            generatedClient: this.client,
        };
        const cryptoClient = new CryptographyClient(keyUrl.toString(), this.credential, constructorOptions);
        return cryptoClient;
    }
    /**
     * 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;
    }
    updateKeyProperties(...args) {
        const [name, keyVersion, options] = this.disambiguateUpdateKeyPropertiesArgs(args);
        return tracingClient.withSpan(`KeyClient.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);
        });
    }
    /**
     * Standardizes an overloaded arguments collection for the updateKeyProperties method.
     *
     * @param args - The arguments collection.
     * @returns - The standardized arguments collection.
     */
    disambiguateUpdateKeyPropertiesArgs(args) {
        if (typeof args[1] === "string") {
            // [name, keyVersion, options?] => [name, keyVersion, options || {}]
            return [args[0], args[1], args[2] || {}];
        }
        else {
            // [name, options?] => [name , "", options || {}]
            return [args[0], "", args[1] || {}];
        }
    }
    /**
     * 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 tracingClient.withSpan(`KeyClient.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 tracingClient.withSpan(`KeyClient.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 tracingClient.withSpan(`KeyClient.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 tracingClient.withSpan(`KeyClient.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 tracingClient.withSpan(`KeyClient.restoreKeyBackup`, options, async (updatedOptions) => {
            const response = await this.client.restoreKey(this.vaultUrl, backup, updatedOptions);
            return getKeyFromKeyBundle(response);
        });
    }
    /**
     * Gets the requested number of bytes containing random values from a managed HSM.
     * This operation requires the managedHsm/rng permission.
     *
     * Example usage:
     * ```ts
     * let client = new KeyClient(vaultUrl, credentials);
     * let { bytes } = await client.getRandomBytes(10);
     * ```
     * @param count - The number of bytes to generate between 1 and 128 inclusive.
     * @param options - The optional parameters.
     */
    getRandomBytes(count, options = {}) {
        return tracingClient.withSpan("KeyClient.getRandomBytes", options, async (updatedOptions) => {
            const response = await this.client.getRandomBytes(this.vaultUrl, count, updatedOptions);
            return response.value;
        });
    }
    /**
     * Rotates the key based on the key policy by generating a new version of the key. This operation requires the keys/rotate permission.
     *
     * Example usage:
     * ```ts
     * let client = new KeyClient(vaultUrl, credentials);
     * let key = await client.rotateKey("MyKey");
     * ```
     *
     * @param name - The name of the key to rotate.
     * @param options - The optional parameters.
     */
    rotateKey(name, options = {}) {
        return tracingClient.withSpan("KeyClient.rotateKey", options, async (updatedOptions) => {
            const key = await this.client.rotateKey(this.vaultUrl, name, updatedOptions);
            return getKeyFromKeyBundle(key);
        });
    }
    /**
     * Releases a key from a managed HSM.
     *
     * The release key operation is applicable to all key types. The operation requires the key to be marked exportable and the keys/release permission.
     *
     * Example usage:
     * ```ts
     * let client = new KeyClient(vaultUrl, credentials);
     * let result = await client.releaseKey("myKey", target)
     * ```
     *
     * @param name - The name of the key.
     * @param targetAttestationToken - The attestation assertion for the target of the key release.
     * @param options - The optional parameters.
     */
    releaseKey(name, targetAttestationToken, options = {}) {
        return tracingClient.withSpan("KeyClient.releaseKey", options, async (updatedOptions) => {
            const { nonce, algorithm } = updatedOptions, rest = tslib.__rest(updatedOptions, ["nonce", "algorithm"]);
            const result = await this.client.release(this.vaultUrl, name, (options === null || options === void 0 ? void 0 : options.version) || "", targetAttestationToken, Object.assign({ enc: algorithm, nonce }, rest));
            return { value: result.value };
        });
    }
    /**
     * Gets the rotation policy of a Key Vault Key.
     * By default, all keys have a policy that will notify 30 days before expiry.
     *
     * This operation requires the keys/get permission.
     * Example usage:
     * ```ts
     * let client = new KeyClient(vaultUrl, credentials);
     * let result = await client.getKeyRotationPolicy("myKey");
     * ```
     *
     * @param keyName - The name of the key.
     * @param options - The optional parameters.
     */
    getKeyRotationPolicy(keyName, options = {}) {
        return tracingClient.withSpan("KeyClient.getKeyRotationPolicy", options, async () => {
            const policy = await this.client.getKeyRotationPolicy(this.vaultUrl, keyName);
            return keyRotationTransformations.generatedToPublic(policy);
        });
    }
    /**
     * Updates the rotation policy of a Key Vault Key.
     * This operation requires the keys/update permission.
     *
     * Example usage:
     * ```ts
     * let client = new KeyClient(vaultUrl, credentials);
     * const setPolicy = await client.updateKeyRotationPolicy("MyKey", myPolicy);
     * ```
     *
     * @param keyName - The name of the key.
     * @param policyProperties - The {@link KeyRotationPolicyProperties} for the policy.
     * @param options - The optional parameters.
     */
    updateKeyRotationPolicy(keyName, policy, options = {}) {
        return tracingClient.withSpan("KeyClient.updateKeyRotationPolicy", options, async (updatedOptions) => {
            const result = await this.client.updateKeyRotationPolicy(this.vaultUrl, keyName, keyRotationTransformations.propertiesToGenerated(policy), updatedOptions);
            return keyRotationTransformations.generatedToPublic(result);
        });
    }
    /**
     * 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(tracingClient.withSpan("KeyClient.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(tracingClient.withSpan("KeyClient.listPropertiesOfKeyVersionsPage", options || {}, async (updatedOptions) => this.client.getKeyVersionsNext(this.vaultUrl, name, continuationState.continuationToken, updatedOptions)));
                continuationState.continuationToken = currentSetResponse.nextLink;
                if (currentSetResponse.value) {
                    yield yield tslib.__await(currentSetResponse.value.map(getKeyPropertiesFromKeyItem, this));
                }
                else {
                    break;
                }
            }
        });
    }
    /**
     * 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 _a, e_1, _b, _c;
            const f = {};
            try {
                for (var _d = true, _e = tslib.__asyncValues(this.listPropertiesOfKeyVersionsPage(name, f, options)), _f; _f = yield tslib.__await(_e.next()), _a = _f.done, !_a;) {
                    _c = _f.value;
                    _d = false;
                    try {
                        const page = _c;
                        for (const item of page) {
                            yield yield tslib.__await(item);
                        }
                    }
                    finally {
                        _d = true;
                    }
                }
            }
            catch (e_1_1) { e_1 = { error: e_1_1 }; }
            finally {
                try {
                    if (!_d && !_a && (_b = _e.return)) yield tslib.__await(_b.call(_e));
                }
                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),
        };
    }
    /**
     * 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(tracingClient.withSpan("KeyClient.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(tracingClient.withSpan("KeyClient.listPropertiesOfKeysPage", options || {}, async (updatedOptions) => this.client.getKeysNext(this.vaultUrl, continuationState.continuationToken, updatedOptions)));
                continuationState.continuationToken = currentSetResponse.nextLink;
                if (currentSetResponse.value) {
                    yield yield tslib.__await(currentSetResponse.value.map(getKeyPropertiesFromKeyItem, this));
                }
                else {
                    break;
                }
            }
        });
    }
    /**
     * 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 _a, e_2, _b, _c;
            const f = {};
            try {
                for (var _d = true, _e = tslib.__asyncValues(this.listPropertiesOfKeysPage(f, options)), _f; _f = yield tslib.__await(_e.next()), _a = _f.done, !_a;) {
                    _c = _f.value;
                    _d = false;
                    try {
                        const page = _c;
                        for (const item of page) {
                            yield yield tslib.__await(item);
                        }
                    }
                    finally {
                        _d = true;
                    }
                }
            }
            catch (e_2_1) { e_2 = { error: e_2_1 }; }
            finally {
                try {
                    if (!_d && !_a && (_b = _e.return)) yield tslib.__await(_b.call(_e));
                }
                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),
        };
    }
    /**
     * 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(tracingClient.withSpan("KeyClient.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(tracingClient.withSpan("KeyClient.listDeletedKeysPage", options || {}, async (updatedOptions) => this.client.getDeletedKeysNext(this.vaultUrl, continuationState.continuationToken, updatedOptions)));
                continuationState.continuationToken = currentSetResponse.nextLink;
                if (currentSetResponse.value) {
                    yield yield tslib.__await(currentSetResponse.value.map(getDeletedKeyFromDeletedKeyItem, this));
                }
                else {
                    break;
                }
            }
        });
    }
    /**
     * 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 _a, e_3, _b, _c;
            const f = {};
            try {
                for (var _d = true, _e = tslib.__asyncValues(this.listDeletedKeysPage(f, options)), _f; _f = yield tslib.__await(_e.next()), _a = _f.done, !_a;) {
                    _c = _f.value;
                    _d = false;
                    try {
                        const page = _c;
                        for (const item of page) {
                            yield yield tslib.__await(item);
                        }
                    }
                    finally {
                        _d = true;
                    }
                }
            }
            catch (e_3_1) { e_3 = { error: e_3_1 }; }
            finally {
                try {
                    if (!_d && !_a && (_b = _e.return)) yield tslib.__await(_b.call(_e));
                }
                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
