diff --git a/.github/dependabot.yml b/.github/dependabot.yml index ad92a92..7d22cd8 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,6 +5,10 @@ version: 2 updates: + - package-ecosystem: "github-actions" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "monthly" - package-ecosystem: "npm" # See documentation for possible values directory: "/" # Location of package manifests schedule: @@ -24,6 +28,9 @@ updates: # node-gyp now depends on python 3.10, we install 3.6 in our dockerfile - dependency-name: "node-gyp" - dependency-name: "prebuild" + versioning-strategy: increase + allow: + - dependency-type: "development" groups: development-dependencies: diff --git a/.github/docker/Dockerfile.glibc b/.github/docker/Dockerfile.glibc index e0a89d3..b22a180 100644 --- a/.github/docker/Dockerfile.glibc +++ b/.github/docker/Dockerfile.glibc @@ -16,7 +16,7 @@ RUN apt-get -qq update && apt-get -qq install -y python3 build-essential && ldd RUN npm run install:libmongocrypt ARG RUN_TEST -RUN [ -n "$RUN_TEST" ] && npm run test || echo 'skipping testing!' +RUN if [ -n "$RUN_TEST" ]; then npm test ; else echo "skipping tests" ; fi FROM scratch diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dd07514..3c74b60 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,6 +13,7 @@ jobs: matrix: os: [macos-latest, windows-2019] node: [16.x, 18.x, 20.x, 22.x] + fail-fast: false runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 @@ -20,8 +21,8 @@ jobs: - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node }} - cache: 'npm' - registry-url: 'https://registry.npmjs.org' + cache: "npm" + registry-url: "https://registry.npmjs.org" - name: Build with Node.js ${{ matrix.node }} on ${{ matrix.os }} run: node .github/scripts/libmongocrypt.mjs ${{ runner.os == 'Windows' && '--build' || '' }} @@ -37,6 +38,7 @@ jobs: matrix: linux_arch: [s390x, arm64, amd64] node: [16.x, 18.x, 20.x, 22.x] + fail-fast: false steps: - uses: actions/checkout@v4 diff --git a/.mocharc.json b/.mocharc.json index 33df4eb..13b5622 100644 --- a/.mocharc.json +++ b/.mocharc.json @@ -11,5 +11,6 @@ "recursive": true, "failZero": true, "reporter": "test/tools/mongodb_reporter.js", - "color": true -} + "color": true, + "timeout": 0 +} \ No newline at end of file diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 8ace915..0f6aa44 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "6.1.0" + ".": "6.1.1" } diff --git a/HISTORY.md b/HISTORY.md index 3729008..1fcb28f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,14 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [6.1.1](https://github.com/mongodb-js/mongodb-client-encryption/compare/v6.1.0...v6.1.1) (2024-12-09) + + +### Bug Fixes + +* **NODE-6326:** explicitly chain object lifetimes ([#42](https://github.com/mongodb-js/mongodb-client-encryption/issues/42)) ([ddb3fb8](https://github.com/mongodb-js/mongodb-client-encryption/commit/ddb3fb867df87ef6e6b1a0bbf9e9385d94a180dd)) +* **NODE-6591:** remove bindings as a dependency ([#57](https://github.com/mongodb-js/mongodb-client-encryption/issues/57)) ([e6e830d](https://github.com/mongodb-js/mongodb-client-encryption/commit/e6e830d318838c8ec09d5c6a3f459902e18193d3)) + ## [6.1.0](https://github.com/mongodb-js/mongodb-client-encryption/compare/v6.1.0-alpha...v6.1.0) (2024-08-13) diff --git a/addon/mongocrypt.cc b/addon/mongocrypt.cc index 9ea3c41..b0ab3dd 100644 --- a/addon/mongocrypt.cc +++ b/addon/mongocrypt.cc @@ -126,11 +126,15 @@ Function MongoCrypt::Init(Napi::Env env) { StaticValue("libmongocryptVersion", String::New(env, mongocrypt_version(nullptr)))}); } +mongocrypt_t* MongoCrypt::mongo_crypt() { + return _state->mongo_crypt.get(); +} + void MongoCrypt::logHandler(mongocrypt_log_level_t level, const char* message, uint32_t message_len, void* ctx) { - MongoCrypt* mongoCrypt = static_cast(ctx); + MongoCrypt* mongoCrypt = static_cast(ctx)->js_wrapper; if (!mongoCrypt) { fprintf(stderr, "Log handler called without `MongoCrypt` instance\n"); return; @@ -203,6 +207,18 @@ static bool aes_256_generic_hook(MongoCrypt* mongoCrypt, } std::unique_ptr MongoCrypt::createJSCryptoHooks() { + static auto get_js_wrapper_for_ctx = [](void* ctx, mongocrypt_status_t* status) -> MongoCrypt* { + MongoCrypt* wrapper = static_cast(ctx)->js_wrapper; + if (!wrapper) { + mongocrypt_status_set(status, + MONGOCRYPT_STATUS_ERROR_CLIENT, + 1, + "MongoCrypt instance has been destroyed", + -1); + } + return wrapper; + }; + auto aes_256_cbc_encrypt = [](void* ctx, mongocrypt_binary_t* key, mongocrypt_binary_t* iv, @@ -210,7 +226,9 @@ std::unique_ptr MongoCrypt::createJSCryptoHooks() { mongocrypt_binary_t* out, uint32_t* bytes_written, mongocrypt_status_t* status) -> bool { - MongoCrypt* mc = static_cast(ctx); + MongoCrypt* mc = get_js_wrapper_for_ctx(ctx, status); + if (!mc) + return false; return aes_256_generic_hook( mc, key, iv, in, out, bytes_written, status, mc->GetCallback("aes256CbcEncryptHook")); }; @@ -222,7 +240,9 @@ std::unique_ptr MongoCrypt::createJSCryptoHooks() { mongocrypt_binary_t* out, uint32_t* bytes_written, mongocrypt_status_t* status) -> bool { - MongoCrypt* mc = static_cast(ctx); + MongoCrypt* mc = get_js_wrapper_for_ctx(ctx, status); + if (!mc) + return false; return aes_256_generic_hook( mc, key, iv, in, out, bytes_written, status, mc->GetCallback("aes256CbcDecryptHook")); }; @@ -234,7 +254,9 @@ std::unique_ptr MongoCrypt::createJSCryptoHooks() { mongocrypt_binary_t* out, uint32_t* bytes_written, mongocrypt_status_t* status) -> bool { - MongoCrypt* mc = static_cast(ctx); + MongoCrypt* mc = get_js_wrapper_for_ctx(ctx, status); + if (!mc) + return false; return aes_256_generic_hook( mc, key, iv, in, out, bytes_written, status, mc->GetCallback("aes256CtrEncryptHook")); }; @@ -246,7 +268,9 @@ std::unique_ptr MongoCrypt::createJSCryptoHooks() { mongocrypt_binary_t* out, uint32_t* bytes_written, mongocrypt_status_t* status) -> bool { - MongoCrypt* mc = static_cast(ctx); + MongoCrypt* mc = get_js_wrapper_for_ctx(ctx, status); + if (!mc) + return false; return aes_256_generic_hook( mc, key, iv, in, out, bytes_written, status, mc->GetCallback("aes256CtrDecryptHook")); }; @@ -255,7 +279,9 @@ std::unique_ptr MongoCrypt::createJSCryptoHooks() { mongocrypt_binary_t* out, uint32_t count, mongocrypt_status_t* status) -> bool { - MongoCrypt* mongoCrypt = static_cast(ctx); + MongoCrypt* mongoCrypt = get_js_wrapper_for_ctx(ctx, status); + if (!mongoCrypt) + return false; Napi::Env env = mongoCrypt->Env(); HandleScope scope(env); Function hook = mongoCrypt->GetCallback("randomHook"); @@ -283,7 +309,9 @@ std::unique_ptr MongoCrypt::createJSCryptoHooks() { mongocrypt_binary_t* in, mongocrypt_binary_t* out, mongocrypt_status_t* status) -> bool { - MongoCrypt* mongoCrypt = static_cast(ctx); + MongoCrypt* mongoCrypt = get_js_wrapper_for_ctx(ctx, status); + if (!mongoCrypt) + return false; Napi::Env env = mongoCrypt->Env(); HandleScope scope(env); Function hook = mongoCrypt->GetCallback("hmacSha512Hook"); @@ -314,7 +342,9 @@ std::unique_ptr MongoCrypt::createJSCryptoHooks() { mongocrypt_binary_t* in, mongocrypt_binary_t* out, mongocrypt_status_t* status) -> bool { - MongoCrypt* mongoCrypt = static_cast(ctx); + MongoCrypt* mongoCrypt = get_js_wrapper_for_ctx(ctx, status); + if (!mongoCrypt) + return false; Napi::Env env = mongoCrypt->Env(); HandleScope scope(env); Function hook = mongoCrypt->GetCallback("hmacSha256Hook"); @@ -344,7 +374,9 @@ std::unique_ptr MongoCrypt::createJSCryptoHooks() { mongocrypt_binary_t* in, mongocrypt_binary_t* out, mongocrypt_status_t* status) -> bool { - MongoCrypt* mongoCrypt = static_cast(ctx); + MongoCrypt* mongoCrypt = get_js_wrapper_for_ctx(ctx, status); + if (!mongoCrypt) + return false; Napi::Env env = mongoCrypt->Env(); HandleScope scope(env); Function hook = mongoCrypt->GetCallback("sha256Hook"); @@ -373,7 +405,9 @@ std::unique_ptr MongoCrypt::createJSCryptoHooks() { mongocrypt_binary_t* in, mongocrypt_binary_t* out, mongocrypt_status_t* status) -> bool { - MongoCrypt* mongoCrypt = static_cast(ctx); + MongoCrypt* mongoCrypt = get_js_wrapper_for_ctx(ctx, status); + if (!mongoCrypt) + return false; Napi::Env env = mongoCrypt->Env(); HandleScope scope(env); Function hook = mongoCrypt->GetCallback("signRsaSha256Hook"); @@ -410,12 +444,12 @@ std::unique_ptr MongoCrypt::createJSCryptoHooks() { aes_256_ctr_decrypt, nullptr, sign_rsa_sha256, - this}); + _state.get()}); } bool MongoCrypt::installCryptoHooks() { - const auto& hooks = *_crypto_hooks; - if (!mongocrypt_setopt_crypto_hooks(_mongo_crypt.get(), + const auto& hooks = *_state->crypto_hooks; + if (!mongocrypt_setopt_crypto_hooks(mongo_crypt(), hooks.aes_256_cbc_encrypt, hooks.aes_256_cbc_decrypt, hooks.random, @@ -429,25 +463,26 @@ bool MongoCrypt::installCryptoHooks() { // Added after `mongocrypt_setopt_crypto_hooks`, they should be treated as the same during // configuration if (!mongocrypt_setopt_crypto_hook_sign_rsaes_pkcs1_v1_5( - _mongo_crypt.get(), hooks.sign_rsa_sha256, this)) { + mongo_crypt(), hooks.sign_rsa_sha256, hooks.ctx)) { return false; } if (!mongocrypt_setopt_aes_256_ctr( - _mongo_crypt.get(), hooks.aes_256_ctr_encrypt, hooks.aes_256_ctr_decrypt, hooks.ctx)) { + mongo_crypt(), hooks.aes_256_ctr_encrypt, hooks.aes_256_ctr_decrypt, hooks.ctx)) { return false; } if (hooks.aes_256_ecb_encrypt && - !mongocrypt_setopt_aes_256_ecb(_mongo_crypt.get(), hooks.aes_256_ecb_encrypt, hooks.ctx)) { + !mongocrypt_setopt_aes_256_ecb(mongo_crypt(), hooks.aes_256_ecb_encrypt, hooks.ctx)) { return false; } return true; } -MongoCrypt::MongoCrypt(const CallbackInfo& info) - : ObjectWrap(info), _mongo_crypt(mongocrypt_new()) { +MongoCrypt::MongoCrypt(const CallbackInfo& info) : ObjectWrap(info) { + _state->mongo_crypt.reset(mongocrypt_new()); + _state->js_wrapper = this; if (info.Length() < 1 || !info[0].IsObject()) { throw TypeError::New(Env(), "First parameter must be an object"); } @@ -460,8 +495,8 @@ MongoCrypt::MongoCrypt(const CallbackInfo& info) std::unique_ptr kmsProvidersBinary( Uint8ArrayToBinary(kmsProvidersOptions)); - if (!mongocrypt_setopt_kms_providers(_mongo_crypt.get(), kmsProvidersBinary.get())) { - throw TypeError::New(Env(), errorStringFromStatus(_mongo_crypt.get())); + if (!mongocrypt_setopt_kms_providers(mongo_crypt(), kmsProvidersBinary.get())) { + throw TypeError::New(Env(), errorStringFromStatus(mongo_crypt())); } } @@ -470,8 +505,8 @@ MongoCrypt::MongoCrypt(const CallbackInfo& info) std::unique_ptr schemaMapBinary( Uint8ArrayToBinary(schemaMapBuffer)); - if (!mongocrypt_setopt_schema_map(_mongo_crypt.get(), schemaMapBinary.get())) { - throw TypeError::New(Env(), errorStringFromStatus(_mongo_crypt.get())); + if (!mongocrypt_setopt_schema_map(mongo_crypt(), schemaMapBinary.get())) { + throw TypeError::New(Env(), errorStringFromStatus(mongo_crypt())); } } @@ -481,23 +516,23 @@ MongoCrypt::MongoCrypt(const CallbackInfo& info) std::unique_ptr encryptedFieldsMapBinary( Uint8ArrayToBinary(encryptedFieldsMapBuffer)); - if (!mongocrypt_setopt_encrypted_field_config_map(_mongo_crypt.get(), + if (!mongocrypt_setopt_encrypted_field_config_map(mongo_crypt(), encryptedFieldsMapBinary.get())) { - throw TypeError::New(Env(), errorStringFromStatus(_mongo_crypt.get())); + throw TypeError::New(Env(), errorStringFromStatus(mongo_crypt())); } } if (options.Has("logger")) { SetCallback("logger", options["logger"]); - if (!mongocrypt_setopt_log_handler(_mongo_crypt.get(), MongoCrypt::logHandler, this)) { - throw TypeError::New(Env(), errorStringFromStatus(_mongo_crypt.get())); + if (!mongocrypt_setopt_log_handler(mongo_crypt(), MongoCrypt::logHandler, _state.get())) { + throw TypeError::New(Env(), errorStringFromStatus(mongo_crypt())); } } - if (!_crypto_hooks) { - _crypto_hooks = opensslcrypto::createOpenSSLCryptoHooks(); + if (!_state->crypto_hooks) { + _state->crypto_hooks = opensslcrypto::createOpenSSLCryptoHooks(); } - if (!_crypto_hooks && options.Has("cryptoCallbacks")) { + if (!_state->crypto_hooks && options.Has("cryptoCallbacks")) { Object cryptoCallbacks = options.Get("cryptoCallbacks").ToObject(); SetCallback("aes256CbcEncryptHook", cryptoCallbacks["aes256CbcEncryptHook"]); @@ -509,9 +544,9 @@ MongoCrypt::MongoCrypt(const CallbackInfo& info) SetCallback("hmacSha256Hook", cryptoCallbacks["hmacSha256Hook"]); SetCallback("sha256Hook", cryptoCallbacks["sha256Hook"]); SetCallback("signRsaSha256Hook", cryptoCallbacks["signRsaSha256Hook"]); - _crypto_hooks = createJSCryptoHooks(); + _state->crypto_hooks = createJSCryptoHooks(); } - if (_crypto_hooks && !installCryptoHooks()) { + if (_state->crypto_hooks && !installCryptoHooks()) { throw Error::New(Env(), "unable to configure crypto hooks"); } @@ -523,33 +558,36 @@ MongoCrypt::MongoCrypt(const CallbackInfo& info) Array search_paths = search_paths_v.As(); for (uint32_t i = 0; i < search_paths.Length(); i++) { mongocrypt_setopt_append_crypt_shared_lib_search_path( - _mongo_crypt.get(), search_paths.Get(i).ToString().Utf8Value().c_str()); + mongo_crypt(), search_paths.Get(i).ToString().Utf8Value().c_str()); } } if (options.Has("cryptSharedLibPath")) { mongocrypt_setopt_set_crypt_shared_lib_path_override( - _mongo_crypt.get(), options.Get("cryptSharedLibPath").ToString().Utf8Value().c_str()); + mongo_crypt(), options.Get("cryptSharedLibPath").ToString().Utf8Value().c_str()); } if (options.Get("bypassQueryAnalysis").ToBoolean()) { - mongocrypt_setopt_bypass_query_analysis(_mongo_crypt.get()); + mongocrypt_setopt_bypass_query_analysis(mongo_crypt()); } - mongocrypt_setopt_use_range_v2(_mongo_crypt.get()); + mongocrypt_setopt_use_range_v2(mongo_crypt()); - mongocrypt_setopt_use_need_kms_credentials_state(_mongo_crypt.get()); + mongocrypt_setopt_use_need_kms_credentials_state(mongo_crypt()); // Initialize after all options are set. - if (!mongocrypt_init(_mongo_crypt.get())) { - throw TypeError::New(Env(), errorStringFromStatus(_mongo_crypt.get())); + if (!mongocrypt_init(mongo_crypt())) { + throw TypeError::New(Env(), errorStringFromStatus(mongo_crypt())); } } +MongoCrypt::~MongoCrypt() { + _state->js_wrapper = nullptr; +} + Value MongoCrypt::CryptSharedLibVersionInfo(const CallbackInfo& info) { - uint64_t version_numeric = mongocrypt_crypt_shared_lib_version(_mongo_crypt.get()); - const char* version_string = - mongocrypt_crypt_shared_lib_version_string(_mongo_crypt.get(), nullptr); + uint64_t version_numeric = mongocrypt_crypt_shared_lib_version(mongo_crypt()); + const char* version_string = mongocrypt_crypt_shared_lib_version_string(mongo_crypt(), nullptr); if (version_string == nullptr) { return Env().Null(); } @@ -561,21 +599,21 @@ Value MongoCrypt::CryptSharedLibVersionInfo(const CallbackInfo& info) { } Value MongoCrypt::CryptoHooksProvider(const CallbackInfo& info) { - if (!_crypto_hooks) + if (!_state->crypto_hooks) return Env().Null(); - return String::New(Env(), _crypto_hooks->id); + return String::New(Env(), _state->crypto_hooks->id); } Value MongoCrypt::Status(const CallbackInfo& info) { std::unique_ptr status(mongocrypt_status_new()); - mongocrypt_status(_mongo_crypt.get(), status.get()); + mongocrypt_status(mongo_crypt(), status.get()); return ExtractStatus(Env(), status.get()); } Value MongoCrypt::MakeEncryptionContext(const CallbackInfo& info) { std::string ns = info[0].ToString(); std::unique_ptr context( - mongocrypt_ctx_new(_mongo_crypt.get())); + mongocrypt_ctx_new(mongo_crypt())); Uint8Array commandBuffer = Uint8ArrayFromValue(info[1], "command"); @@ -585,7 +623,7 @@ Value MongoCrypt::MakeEncryptionContext(const CallbackInfo& info) { throw TypeError::New(Env(), errorStringFromStatus(context.get())); } - return MongoCryptContext::NewInstance(Env(), std::move(context)); + return MongoCryptContext::NewInstance(Env(), _state, std::move(context)); } Value MongoCrypt::MakeExplicitEncryptionContext(const CallbackInfo& info) { @@ -610,7 +648,7 @@ Value MongoCrypt::MakeExplicitEncryptionContextInternal( const Uint8Array& valueBuffer, const Object& options) { std::unique_ptr context( - mongocrypt_ctx_new(_mongo_crypt.get())); + mongocrypt_ctx_new(mongo_crypt())); if (!options.Get("keyId").IsUndefined()) { Uint8Array keyId = Uint8ArrayFromValue(options["keyId"], "keyId"); @@ -680,7 +718,7 @@ Value MongoCrypt::MakeExplicitEncryptionContextInternal( throw TypeError::New(Env(), errorStringFromStatus(context.get())); } - return MongoCryptContext::NewInstance(Env(), std::move(context)); + return MongoCryptContext::NewInstance(Env(), _state, std::move(context)); } Value MongoCrypt::MakeDecryptionContext(const CallbackInfo& info) { @@ -688,13 +726,13 @@ Value MongoCrypt::MakeDecryptionContext(const CallbackInfo& info) { std::unique_ptr binary(Uint8ArrayToBinary(value)); std::unique_ptr context( - mongocrypt_ctx_new(_mongo_crypt.get())); + mongocrypt_ctx_new(mongo_crypt())); if (!mongocrypt_ctx_decrypt_init(context.get(), binary.get())) { throw TypeError::New(Env(), errorStringFromStatus(context.get())); } - return MongoCryptContext::NewInstance(Env(), std::move(context)); + return MongoCryptContext::NewInstance(Env(), _state, std::move(context)); } Value MongoCrypt::MakeExplicitDecryptionContext(const CallbackInfo& info) { @@ -702,20 +740,20 @@ Value MongoCrypt::MakeExplicitDecryptionContext(const CallbackInfo& info) { std::unique_ptr binary(Uint8ArrayToBinary(value)); std::unique_ptr context( - mongocrypt_ctx_new(_mongo_crypt.get())); + mongocrypt_ctx_new(mongo_crypt())); if (!mongocrypt_ctx_explicit_decrypt_init(context.get(), binary.get())) { throw TypeError::New(Env(), errorStringFromStatus(context.get())); } - return MongoCryptContext::NewInstance(Env(), std::move(context)); + return MongoCryptContext::NewInstance(Env(), _state, std::move(context)); } Value MongoCrypt::MakeDataKeyContext(const CallbackInfo& info) { Uint8Array optionsBuffer = Uint8ArrayFromValue(info[0], "options"); std::unique_ptr context( - mongocrypt_ctx_new(_mongo_crypt.get())); + mongocrypt_ctx_new(mongo_crypt())); std::unique_ptr binary( Uint8ArrayToBinary(optionsBuffer)); @@ -759,14 +797,14 @@ Value MongoCrypt::MakeDataKeyContext(const CallbackInfo& info) { throw TypeError::New(Env(), errorStringFromStatus(context.get())); } - return MongoCryptContext::NewInstance(Env(), std::move(context)); + return MongoCryptContext::NewInstance(Env(), _state, std::move(context)); } Value MongoCrypt::MakeRewrapManyDataKeyContext(const CallbackInfo& info) { Uint8Array filter_buffer = Uint8ArrayFromValue(info[0], "filter"); std::unique_ptr context( - mongocrypt_ctx_new(_mongo_crypt.get())); + mongocrypt_ctx_new(mongo_crypt())); Napi::Value key_encryption_key = info[1]; if (key_encryption_key.IsTypedArray()) { @@ -783,7 +821,7 @@ Value MongoCrypt::MakeRewrapManyDataKeyContext(const CallbackInfo& info) { throw TypeError::New(Env(), errorStringFromStatus(context.get())); } - return MongoCryptContext::NewInstance(Env(), std::move(context)); + return MongoCryptContext::NewInstance(Env(), _state, std::move(context)); } // Store callbacks as nested properties on the MongoCrypt binding object @@ -829,12 +867,18 @@ Function MongoCryptContext::Init(Napi::Env env) { InstanceAccessor("state", &MongoCryptContext::State, nullptr)}); } +mongocrypt_ctx_t* MongoCryptContext::context() { + return _state->context.get(); +} + Object MongoCryptContext::NewInstance( - Napi::Env env, std::unique_ptr context) { + Napi::Env env, + std::shared_ptr mongo_crypt, + std::unique_ptr context) { InstanceData* instance_data = env.GetInstanceData(); Object obj = instance_data->MongoCryptContextCtor.Value().New({}); MongoCryptContext* instance = MongoCryptContext::Unwrap(obj); - instance->_context = std::move(context); + *instance->_state = ContextState{mongo_crypt, std::move(context)}; return obj; } @@ -842,17 +886,17 @@ MongoCryptContext::MongoCryptContext(const CallbackInfo& info) : ObjectWrap(info Value MongoCryptContext::Status(const CallbackInfo& info) { std::unique_ptr status(mongocrypt_status_new()); - mongocrypt_ctx_status(_context.get(), status.get()); + mongocrypt_ctx_status(context(), status.get()); return ExtractStatus(Env(), status.get()); } Value MongoCryptContext::State(const CallbackInfo& info) { - return Number::New(Env(), mongocrypt_ctx_state(_context.get())); + return Number::New(Env(), mongocrypt_ctx_state(context())); } Value MongoCryptContext::NextMongoOperation(const CallbackInfo& info) { std::unique_ptr op_bson(mongocrypt_binary_new()); - mongocrypt_ctx_mongo_op(_context.get(), op_bson.get()); + mongocrypt_ctx_mongo_op(context(), op_bson.get()); return BufferFromBinary(Env(), op_bson.get()); } @@ -861,12 +905,12 @@ void MongoCryptContext::AddMongoOperationResponse(const CallbackInfo& info) { std::unique_ptr reply_bson( Uint8ArrayToBinary(buffer)); - mongocrypt_ctx_mongo_feed(_context.get(), reply_bson.get()); + mongocrypt_ctx_mongo_feed(context(), reply_bson.get()); // return value } void MongoCryptContext::FinishMongoOperation(const CallbackInfo& info) { - mongocrypt_ctx_mongo_done(_context.get()); + mongocrypt_ctx_mongo_done(context()); } void MongoCryptContext::ProvideKMSProviders(const CallbackInfo& info) { @@ -874,31 +918,25 @@ void MongoCryptContext::ProvideKMSProviders(const CallbackInfo& info) { std::unique_ptr kms_bson( Uint8ArrayToBinary(buffer)); - mongocrypt_ctx_provide_kms_providers(_context.get(), kms_bson.get()); + mongocrypt_ctx_provide_kms_providers(context(), kms_bson.get()); } Value MongoCryptContext::NextKMSRequest(const CallbackInfo& info) { - mongocrypt_kms_ctx_t* kms_context = mongocrypt_ctx_next_kms_ctx(_context.get()); + mongocrypt_kms_ctx_t* kms_context = mongocrypt_ctx_next_kms_ctx(context()); if (kms_context == nullptr) { return Env().Null(); } else { - Object result = MongoCryptKMSRequest::NewInstance(Env(), kms_context); - // The lifetime of the `kms_context` pointer is not specified - // anywhere, so it seems reasonable to assume that it is at - // least the lifetime of this context object. - // Use a symbol to enforce that lifetime dependency. - result.Set("__kmsRequestContext", Value()); - return result; + return MongoCryptKMSRequest::NewInstance(Env(), _state, kms_context); } } void MongoCryptContext::FinishKMSRequests(const CallbackInfo& info) { - mongocrypt_ctx_kms_done(_context.get()); + mongocrypt_ctx_kms_done(context()); } Value MongoCryptContext::FinalizeContext(const CallbackInfo& info) { std::unique_ptr output(mongocrypt_binary_new()); - mongocrypt_ctx_finalize(_context.get(), output.get()); + mongocrypt_ctx_finalize(context(), output.get()); return BufferFromBinary(Env(), output.get()); } @@ -914,10 +952,14 @@ Function MongoCryptKMSRequest::Init(Napi::Env env) { InstanceAccessor("message", &MongoCryptKMSRequest::Message, nullptr)}); } -Object MongoCryptKMSRequest::NewInstance(Napi::Env env, mongocrypt_kms_ctx_t* kms_context) { +Object MongoCryptKMSRequest::NewInstance( + Napi::Env env, + std::shared_ptr context_state, + mongocrypt_kms_ctx_t* kms_context) { InstanceData* instance_data = env.GetInstanceData(); Object obj = instance_data->MongoCryptKMSRequestCtor.Value().New({}); MongoCryptKMSRequest* instance = MongoCryptKMSRequest::Unwrap(obj); + instance->_context_state = context_state; instance->_kms_context = kms_context; return obj; } diff --git a/addon/mongocrypt.h b/addon/mongocrypt.h index fb3d73d..b7753d0 100644 --- a/addon/mongocrypt.h +++ b/addon/mongocrypt.h @@ -62,7 +62,15 @@ class MongoCrypt : public Napi::ObjectWrap { public: static Napi::Function Init(Napi::Env env); + struct State { + std::unique_ptr crypto_hooks; + std::unique_ptr mongo_crypt; + MongoCrypt* js_wrapper; + }; + private: + ~MongoCrypt(); + Napi::Value MakeEncryptionContext(const Napi::CallbackInfo& info); Napi::Value MakeExplicitEncryptionContext(const Napi::CallbackInfo& info); Napi::Value MakeDecryptionContext(const Napi::CallbackInfo& info); @@ -91,15 +99,24 @@ class MongoCrypt : public Napi::ObjectWrap { uint32_t message_len, void* ctx); - std::unique_ptr _crypto_hooks; - std::unique_ptr _mongo_crypt; + mongocrypt_t* mongo_crypt(); // shorthand for _state->mongo_crypt.get() + + std::shared_ptr _state = std::make_shared(); }; class MongoCryptContext : public Napi::ObjectWrap { public: static Napi::Function Init(Napi::Env env); static Napi::Object NewInstance( - Napi::Env env, std::unique_ptr context); + Napi::Env env, + std::shared_ptr mongo_crypt, + std::unique_ptr context); + + struct ContextState { + // Keep reference to the MongoCrypt instance alive while this instance is alive + std::shared_ptr mongo_crypt; + std::unique_ptr context; + }; private: Napi::Value NextMongoOperation(const Napi::CallbackInfo& info); @@ -116,13 +133,17 @@ class MongoCryptContext : public Napi::ObjectWrap { private: friend class Napi::ObjectWrap; explicit MongoCryptContext(const Napi::CallbackInfo& info); - std::unique_ptr _context; + + mongocrypt_ctx_t* context(); // shorthand for _state->context.get() + std::shared_ptr _state = std::make_shared(); }; class MongoCryptKMSRequest : public Napi::ObjectWrap { public: static Napi::Function Init(Napi::Env env); - static Napi::Object NewInstance(Napi::Env env, mongocrypt_kms_ctx_t* kms_context); + static Napi::Object NewInstance(Napi::Env env, + std::shared_ptr context_state, + mongocrypt_kms_ctx_t* kms_context); private: void AddResponse(const Napi::CallbackInfo& info); @@ -136,6 +157,9 @@ class MongoCryptKMSRequest : public Napi::ObjectWrap { private: friend class Napi::ObjectWrap; explicit MongoCryptKMSRequest(const Napi::CallbackInfo& info); + + // Keep reference to the MongoCryptContext instance alive while this instance is alive + std::shared_ptr _context_state; mongocrypt_kms_ctx_t* _kms_context; }; diff --git a/package-lock.json b/package-lock.json index 9abdab5..0812b74 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,36 +1,35 @@ { "name": "mongodb-client-encryption", - "version": "6.1.0", + "version": "6.1.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "mongodb-client-encryption", - "version": "6.1.0", + "version": "6.1.1", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "bindings": "^1.5.0", "node-addon-api": "^4.3.0", "prebuild-install": "^7.1.2" }, "devDependencies": { "@types/bindings": "^1.5.5", "@types/chai": "^4.3.17", - "@types/mocha": "^10.0.7", - "@types/node": "^22.1.0", + "@types/mocha": "^10.0.9", + "@types/node": "^22.8.6", "@types/semver": "^7.5.8", "@types/sinon": "^17.0.3", "@types/sinon-chai": "^3.2.12", - "@typescript-eslint/eslint-plugin": "^8.0.1", - "bson": "^6.8.0", - "chai": "^4.4.1", + "@typescript-eslint/eslint-plugin": "^8.12.2", + "bson": "^6.9.0", + "chai": "^4.5.0", "chai-subset": "^1.6.0", "clang-format": "^1.8.0", - "eslint": "^9.8.0", + "eslint": "^9.13.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.2.1", - "mocha": "^10.7.0", + "mocha": "^10.8.2", "node-gyp": "^10.1.0", "prebuild": "^13.0.0", "prettier": "^3.2.5", @@ -272,9 +271,9 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz", - "integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", + "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", "dev": true, "dependencies": { "@eslint/object-schema": "^2.1.4", @@ -285,6 +284,15 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@eslint/core": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.7.0.tgz", + "integrity": "sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/eslintrc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", @@ -309,9 +317,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.8.0.tgz", - "integrity": "sha512-MfluB7EUfxXtv3i/++oh89uzAr4PDI4nn201hsp+qaXqsjAWzinlZEHEfPgAX4doIlKvPG/i0A9dpKxOLII8yA==", + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.13.0.tgz", + "integrity": "sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -326,6 +334,40 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.2.tgz", + "integrity": "sha512-CXtq5nR4Su+2I47WPOlWud98Y5Lv8Kyxp2ukhgFx/eW6Blm18VXJO5WuQylPugRo8nbluoi6GvvxBLqHcvqUUw==", + "dev": true, + "dependencies": { + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -340,9 +382,9 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", - "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", "dev": true, "engines": { "node": ">=18.18" @@ -671,6 +713,18 @@ "integrity": "sha512-zmZ21EWzR71B4Sscphjief5djsLre50M6lI622OSySTmn9DB3j+C3kWroHfBQWXbOBwbgg/M8CG/hUxDLIloow==", "dev": true }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, "node_modules/@types/minimist": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", @@ -678,18 +732,18 @@ "dev": true }, "node_modules/@types/mocha": { - "version": "10.0.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.7.tgz", - "integrity": "sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==", + "version": "10.0.9", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.9.tgz", + "integrity": "sha512-sicdRoWtYevwxjOHNMPTl3vSfJM6oyW8o1wXeI7uww6b6xHg8eBznQDNSGBCDJmsE8UMxP05JgZRtsKbTqt//Q==", "dev": true }, "node_modules/@types/node": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", - "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==", + "version": "22.8.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.8.6.tgz", + "integrity": "sha512-tosuJYKrIqjQIlVCM4PEGxOmyg3FCPa/fViuJChnGeEIhjA46oy8FMVoF9su1/v8PNs2a8Q0iFNyOx0uOF91nw==", "dev": true, "dependencies": { - "undici-types": "~6.13.0" + "undici-types": "~6.19.8" } }, "node_modules/@types/normalize-package-data": { @@ -730,16 +784,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.0.1.tgz", - "integrity": "sha512-5g3Y7GDFsJAnY4Yhvk8sZtFfV6YNF2caLzjrRPUBzewjPCaj0yokePB4LJSobyCzGMzjZZYFbwuzbfDHlimXbQ==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.12.2.tgz", + "integrity": "sha512-gQxbxM8mcxBwaEmWdtLCIGLfixBMHhQjBqR8sVWNTPpcj45WlYL2IObS/DNMLH1DBP0n8qz+aiiLTGfopPEebw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.0.1", - "@typescript-eslint/type-utils": "8.0.1", - "@typescript-eslint/utils": "8.0.1", - "@typescript-eslint/visitor-keys": "8.0.1", + "@typescript-eslint/scope-manager": "8.12.2", + "@typescript-eslint/type-utils": "8.12.2", + "@typescript-eslint/utils": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -762,6 +816,53 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.12.2.tgz", + "integrity": "sha512-gPLpLtrj9aMHOvxJkSbDBmbRuYdtiEbnvO25bCMza3DhMjTQw0u7Y1M+YR5JPbMsXXnSPuCf5hfq0nEkQDL/JQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.12.2.tgz", + "integrity": "sha512-VwDwMF1SZ7wPBUZwmMdnDJ6sIFk4K4s+ALKLP6aIQsISkPv8jhiw65sAK6SuWODN/ix+m+HgbYDkH+zLjrzvOA==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.12.2.tgz", + "integrity": "sha512-PChz8UaKQAVNHghsHcPyx1OMHoFRUEA7rJSK/mDhdq85bk+PLsUHUBqTQTFt18VJZbmxBovM65fezlheQRsSDA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.12.2", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/parser": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.0.1.tgz", @@ -796,6 +897,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.0.1.tgz", "integrity": "sha512-NpixInP5dm7uukMiRyiHjRKkom5RIFA4dfiHvalanD2cF0CLUuQqxfg8PtEUo9yqJI2bBhF+pcSafqnG3UBnRQ==", "dev": true, + "peer": true, "dependencies": { "@typescript-eslint/types": "8.0.1", "@typescript-eslint/visitor-keys": "8.0.1" @@ -809,14 +911,55 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.0.1.tgz", - "integrity": "sha512-+/UT25MWvXeDX9YaHv1IS6KI1fiuTto43WprE7pgSMswHbn1Jm9GEM4Txp+X74ifOWV8emu2AWcbLhpJAvD5Ng==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.12.2.tgz", + "integrity": "sha512-bwuU4TAogPI+1q/IJSKuD4shBLc/d2vGcRT588q+jzayQyjVK2X6v/fbR4InY2U2sgf8MEvVCqEWUzYzgBNcGQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "8.0.1", - "@typescript-eslint/utils": "8.0.1", + "@typescript-eslint/typescript-estree": "8.12.2", + "@typescript-eslint/utils": "8.12.2", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.12.2.tgz", + "integrity": "sha512-VwDwMF1SZ7wPBUZwmMdnDJ6sIFk4K4s+ALKLP6aIQsISkPv8jhiw65sAK6SuWODN/ix+m+HgbYDkH+zLjrzvOA==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.12.2.tgz", + "integrity": "sha512-mME5MDwGe30Pq9zKPvyduyU86PH7aixwqYR2grTglAdB+AN8xXQ1vFGpYaUSJ5o5P/5znsSBeNcs5g5/2aQwow==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2", "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", "ts-api-utils": "^1.3.0" }, "engines": { @@ -832,11 +975,53 @@ } } }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.12.2.tgz", + "integrity": "sha512-PChz8UaKQAVNHghsHcPyx1OMHoFRUEA7rJSK/mDhdq85bk+PLsUHUBqTQTFt18VJZbmxBovM65fezlheQRsSDA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.12.2", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/types": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.0.1.tgz", "integrity": "sha512-PpqTVT3yCA/bIgJ12czBuE3iBlM3g4inRSC5J0QOdQFAn07TYrYEQBBKgXH1lQpglup+Zy6c1fxuwTk4MTNKIw==", "dev": true, + "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -850,6 +1035,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.0.1.tgz", "integrity": "sha512-8V9hriRvZQXPWU3bbiUV4Epo7EvgM6RTs+sUmxp5G//dBGy402S7Fx0W0QkB2fb4obCF8SInoUzvTYtc3bkb5w==", "dev": true, + "peer": true, "dependencies": { "@typescript-eslint/types": "8.0.1", "@typescript-eslint/visitor-keys": "8.0.1", @@ -878,6 +1064,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "peer": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -887,6 +1074,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "peer": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -898,15 +1086,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.0.1.tgz", - "integrity": "sha512-CBFR0G0sCt0+fzfnKaciu9IBsKvEKYwN9UZ+eeogK1fYHg4Qxk1yf/wLQkLXlq8wbU2dFlgAesxt8Gi76E8RTA==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.12.2.tgz", + "integrity": "sha512-UTTuDIX3fkfAz6iSVa5rTuSfWIYZ6ATtEocQ/umkRSyC9O919lbZ8dcH7mysshrCdrAM03skJOEYaBugxN+M6A==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.0.1", - "@typescript-eslint/types": "8.0.1", - "@typescript-eslint/typescript-estree": "8.0.1" + "@typescript-eslint/scope-manager": "8.12.2", + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/typescript-estree": "8.12.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -919,11 +1107,111 @@ "eslint": "^8.57.0 || ^9.0.0" } }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.12.2.tgz", + "integrity": "sha512-gPLpLtrj9aMHOvxJkSbDBmbRuYdtiEbnvO25bCMza3DhMjTQw0u7Y1M+YR5JPbMsXXnSPuCf5hfq0nEkQDL/JQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.12.2.tgz", + "integrity": "sha512-VwDwMF1SZ7wPBUZwmMdnDJ6sIFk4K4s+ALKLP6aIQsISkPv8jhiw65sAK6SuWODN/ix+m+HgbYDkH+zLjrzvOA==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.12.2.tgz", + "integrity": "sha512-mME5MDwGe30Pq9zKPvyduyU86PH7aixwqYR2grTglAdB+AN8xXQ1vFGpYaUSJ5o5P/5znsSBeNcs5g5/2aQwow==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.12.2.tgz", + "integrity": "sha512-PChz8UaKQAVNHghsHcPyx1OMHoFRUEA7rJSK/mDhdq85bk+PLsUHUBqTQTFt18VJZbmxBovM65fezlheQRsSDA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.12.2", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/visitor-keys": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.0.1.tgz", "integrity": "sha512-W5E+o0UfUcK5EgchLZsyVWqARmsM7v54/qEq6PY3YI5arkgmCzHiuk0zKSJJbm71V0xdRna4BGomkCTXz2/LkQ==", "dev": true, + "peer": true, "dependencies": { "@typescript-eslint/types": "8.0.1", "eslint-visitor-keys": "^3.4.3" @@ -943,9 +1231,9 @@ "dev": true }, "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -1143,6 +1431,7 @@ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, + "peer": true, "engines": { "node": ">=8" } @@ -1291,14 +1580,6 @@ "node": ">=8" } }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, "node_modules/bl": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/bl/-/bl-3.0.1.tgz", @@ -1349,9 +1630,9 @@ "dev": true }, "node_modules/bson": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-6.8.0.tgz", - "integrity": "sha512-iOJg8pr7wq2tg/zSlCCHMi3hMm5JTOxLTagf3zxhcenHsFp+c6uOs6K7W5UE7A4QIJGtqh/ZovFNMP4mOPJynQ==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.9.0.tgz", + "integrity": "sha512-X9hJeyeM0//Fus+0pc5dSUMhhrrmWwQUtdavaQeF3Ta6m69matZkGWV/MrBcnwUeLC8W9kwwc2hfkZgUuCX3Ig==", "dev": true, "engines": { "node": ">=16.20.1" @@ -1589,9 +1870,9 @@ "dev": true }, "node_modules/chai": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", "dev": true, "dependencies": { "assertion-error": "^1.1.0", @@ -1600,7 +1881,7 @@ "get-func-name": "^2.0.2", "loupe": "^2.3.6", "pathval": "^1.1.1", - "type-detect": "^4.0.8" + "type-detect": "^4.1.0" }, "engines": { "node": ">=4" @@ -1615,6 +1896,15 @@ "node": ">=4" } }, + "node_modules/chai/node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -2486,6 +2776,7 @@ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "peer": true, "dependencies": { "path-type": "^4.0.0" }, @@ -2737,27 +3028,31 @@ } }, "node_modules/eslint": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.8.0.tgz", - "integrity": "sha512-K8qnZ/QJzT2dLKdZJVX6W4XOwBzutMYmt0lqUS+JdXgd+HTYFlonFgkJ8s44d/zMPPCnOOk0kMWCApCPhiOy9A==", + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.13.0.tgz", + "integrity": "sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.11.0", - "@eslint/config-array": "^0.17.1", + "@eslint/config-array": "^0.18.0", + "@eslint/core": "^0.7.0", "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.8.0", + "@eslint/js": "9.13.0", + "@eslint/plugin-kit": "^0.2.0", + "@humanfs/node": "^0.16.5", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.0", - "@nodelib/fs.walk": "^1.2.8", + "@humanwhocodes/retry": "^0.3.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.0.2", - "eslint-visitor-keys": "^4.0.0", - "espree": "^10.1.0", + "eslint-scope": "^8.1.0", + "eslint-visitor-keys": "^4.1.0", + "espree": "^10.2.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -2767,14 +3062,11 @@ "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", "text-table": "^0.2.0" }, "bin": { @@ -2785,6 +3077,14 @@ }, "funding": { "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, "node_modules/eslint-config-prettier": { @@ -2830,9 +3130,9 @@ } }, "node_modules/eslint-scope": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", - "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -2858,9 +3158,9 @@ } }, "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2870,14 +3170,14 @@ } }, "node_modules/espree": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", - "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, "dependencies": { - "acorn": "^8.12.0", + "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.0.0" + "eslint-visitor-keys": "^4.2.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2887,9 +3187,9 @@ } }, "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3096,11 +3396,6 @@ "node": ">=16.0.0" } }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -3620,6 +3915,7 @@ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "peer": true, "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -4016,15 +4312,6 @@ "node": ">=8" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", @@ -4862,9 +5149,9 @@ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, "node_modules/mocha": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.0.tgz", - "integrity": "sha512-v8/rBWr2VO5YkspYINnvu81inSz2y3ODJrhO175/Exzor1RcEZZkizgE2A+w/CAXXoESS8Kys5E62dOHGHzULA==", + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", + "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", "dev": true, "dependencies": { "ansi-colors": "^4.1.3", @@ -5923,6 +6210,7 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, + "peer": true, "engines": { "node": ">=8" } @@ -6738,6 +7026,7 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, + "peer": true, "engines": { "node": ">=8" } @@ -7612,9 +7901,9 @@ } }, "node_modules/undici-types": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", - "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==", + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "dev": true }, "node_modules/unique-filename": { @@ -8094,9 +8383,9 @@ "dev": true }, "@eslint/config-array": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz", - "integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", + "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", "dev": true, "requires": { "@eslint/object-schema": "^2.1.4", @@ -8104,6 +8393,12 @@ "minimatch": "^3.1.2" } }, + "@eslint/core": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.7.0.tgz", + "integrity": "sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==", + "dev": true + }, "@eslint/eslintrc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", @@ -8122,9 +8417,9 @@ } }, "@eslint/js": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.8.0.tgz", - "integrity": "sha512-MfluB7EUfxXtv3i/++oh89uzAr4PDI4nn201hsp+qaXqsjAWzinlZEHEfPgAX4doIlKvPG/i0A9dpKxOLII8yA==", + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.13.0.tgz", + "integrity": "sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA==", "dev": true }, "@eslint/object-schema": { @@ -8133,6 +8428,31 @@ "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", "dev": true }, + "@eslint/plugin-kit": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.2.tgz", + "integrity": "sha512-CXtq5nR4Su+2I47WPOlWud98Y5Lv8Kyxp2ukhgFx/eW6Blm18VXJO5WuQylPugRo8nbluoi6GvvxBLqHcvqUUw==", + "dev": true, + "requires": { + "levn": "^0.4.1" + } + }, + "@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true + }, + "@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "requires": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + } + }, "@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -8140,9 +8460,9 @@ "dev": true }, "@humanwhocodes/retry": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", - "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", "dev": true }, "@hutson/parse-repository-url": { @@ -8401,6 +8721,18 @@ "integrity": "sha512-zmZ21EWzR71B4Sscphjief5djsLre50M6lI622OSySTmn9DB3j+C3kWroHfBQWXbOBwbgg/M8CG/hUxDLIloow==", "dev": true }, + "@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true + }, + "@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, "@types/minimist": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", @@ -8408,18 +8740,18 @@ "dev": true }, "@types/mocha": { - "version": "10.0.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.7.tgz", - "integrity": "sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==", + "version": "10.0.9", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.9.tgz", + "integrity": "sha512-sicdRoWtYevwxjOHNMPTl3vSfJM6oyW8o1wXeI7uww6b6xHg8eBznQDNSGBCDJmsE8UMxP05JgZRtsKbTqt//Q==", "dev": true }, "@types/node": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", - "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==", + "version": "22.8.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.8.6.tgz", + "integrity": "sha512-tosuJYKrIqjQIlVCM4PEGxOmyg3FCPa/fViuJChnGeEIhjA46oy8FMVoF9su1/v8PNs2a8Q0iFNyOx0uOF91nw==", "dev": true, "requires": { - "undici-types": "~6.13.0" + "undici-types": "~6.19.8" } }, "@types/normalize-package-data": { @@ -8460,20 +8792,48 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.0.1.tgz", - "integrity": "sha512-5g3Y7GDFsJAnY4Yhvk8sZtFfV6YNF2caLzjrRPUBzewjPCaj0yokePB4LJSobyCzGMzjZZYFbwuzbfDHlimXbQ==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.12.2.tgz", + "integrity": "sha512-gQxbxM8mcxBwaEmWdtLCIGLfixBMHhQjBqR8sVWNTPpcj45WlYL2IObS/DNMLH1DBP0n8qz+aiiLTGfopPEebw==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.0.1", - "@typescript-eslint/type-utils": "8.0.1", - "@typescript-eslint/utils": "8.0.1", - "@typescript-eslint/visitor-keys": "8.0.1", + "@typescript-eslint/scope-manager": "8.12.2", + "@typescript-eslint/type-utils": "8.12.2", + "@typescript-eslint/utils": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^1.3.0" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.12.2.tgz", + "integrity": "sha512-gPLpLtrj9aMHOvxJkSbDBmbRuYdtiEbnvO25bCMza3DhMjTQw0u7Y1M+YR5JPbMsXXnSPuCf5hfq0nEkQDL/JQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2" + } + }, + "@typescript-eslint/types": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.12.2.tgz", + "integrity": "sha512-VwDwMF1SZ7wPBUZwmMdnDJ6sIFk4K4s+ALKLP6aIQsISkPv8jhiw65sAK6SuWODN/ix+m+HgbYDkH+zLjrzvOA==", + "dev": true + }, + "@typescript-eslint/visitor-keys": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.12.2.tgz", + "integrity": "sha512-PChz8UaKQAVNHghsHcPyx1OMHoFRUEA7rJSK/mDhdq85bk+PLsUHUBqTQTFt18VJZbmxBovM65fezlheQRsSDA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "8.12.2", + "eslint-visitor-keys": "^3.4.3" + } + } } }, "@typescript-eslint/parser": { @@ -8495,34 +8855,89 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.0.1.tgz", "integrity": "sha512-NpixInP5dm7uukMiRyiHjRKkom5RIFA4dfiHvalanD2cF0CLUuQqxfg8PtEUo9yqJI2bBhF+pcSafqnG3UBnRQ==", "dev": true, + "peer": true, "requires": { "@typescript-eslint/types": "8.0.1", "@typescript-eslint/visitor-keys": "8.0.1" } }, "@typescript-eslint/type-utils": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.0.1.tgz", - "integrity": "sha512-+/UT25MWvXeDX9YaHv1IS6KI1fiuTto43WprE7pgSMswHbn1Jm9GEM4Txp+X74ifOWV8emu2AWcbLhpJAvD5Ng==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.12.2.tgz", + "integrity": "sha512-bwuU4TAogPI+1q/IJSKuD4shBLc/d2vGcRT588q+jzayQyjVK2X6v/fbR4InY2U2sgf8MEvVCqEWUzYzgBNcGQ==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "8.0.1", - "@typescript-eslint/utils": "8.0.1", + "@typescript-eslint/typescript-estree": "8.12.2", + "@typescript-eslint/utils": "8.12.2", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" + }, + "dependencies": { + "@typescript-eslint/types": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.12.2.tgz", + "integrity": "sha512-VwDwMF1SZ7wPBUZwmMdnDJ6sIFk4K4s+ALKLP6aIQsISkPv8jhiw65sAK6SuWODN/ix+m+HgbYDkH+zLjrzvOA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.12.2.tgz", + "integrity": "sha512-mME5MDwGe30Pq9zKPvyduyU86PH7aixwqYR2grTglAdB+AN8xXQ1vFGpYaUSJ5o5P/5znsSBeNcs5g5/2aQwow==", + "dev": true, + "requires": { + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.12.2.tgz", + "integrity": "sha512-PChz8UaKQAVNHghsHcPyx1OMHoFRUEA7rJSK/mDhdq85bk+PLsUHUBqTQTFt18VJZbmxBovM65fezlheQRsSDA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "8.12.2", + "eslint-visitor-keys": "^3.4.3" + } + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, "@typescript-eslint/types": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.0.1.tgz", "integrity": "sha512-PpqTVT3yCA/bIgJ12czBuE3iBlM3g4inRSC5J0QOdQFAn07TYrYEQBBKgXH1lQpglup+Zy6c1fxuwTk4MTNKIw==", - "dev": true + "dev": true, + "peer": true }, "@typescript-eslint/typescript-estree": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.0.1.tgz", "integrity": "sha512-8V9hriRvZQXPWU3bbiUV4Epo7EvgM6RTs+sUmxp5G//dBGy402S7Fx0W0QkB2fb4obCF8SInoUzvTYtc3bkb5w==", "dev": true, + "peer": true, "requires": { "@typescript-eslint/types": "8.0.1", "@typescript-eslint/visitor-keys": "8.0.1", @@ -8539,6 +8954,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "peer": true, "requires": { "balanced-match": "^1.0.0" } @@ -8548,6 +8964,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "peer": true, "requires": { "brace-expansion": "^2.0.1" } @@ -8555,15 +8972,77 @@ } }, "@typescript-eslint/utils": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.0.1.tgz", - "integrity": "sha512-CBFR0G0sCt0+fzfnKaciu9IBsKvEKYwN9UZ+eeogK1fYHg4Qxk1yf/wLQkLXlq8wbU2dFlgAesxt8Gi76E8RTA==", + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.12.2.tgz", + "integrity": "sha512-UTTuDIX3fkfAz6iSVa5rTuSfWIYZ6ATtEocQ/umkRSyC9O919lbZ8dcH7mysshrCdrAM03skJOEYaBugxN+M6A==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.0.1", - "@typescript-eslint/types": "8.0.1", - "@typescript-eslint/typescript-estree": "8.0.1" + "@typescript-eslint/scope-manager": "8.12.2", + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/typescript-estree": "8.12.2" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.12.2.tgz", + "integrity": "sha512-gPLpLtrj9aMHOvxJkSbDBmbRuYdtiEbnvO25bCMza3DhMjTQw0u7Y1M+YR5JPbMsXXnSPuCf5hfq0nEkQDL/JQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2" + } + }, + "@typescript-eslint/types": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.12.2.tgz", + "integrity": "sha512-VwDwMF1SZ7wPBUZwmMdnDJ6sIFk4K4s+ALKLP6aIQsISkPv8jhiw65sAK6SuWODN/ix+m+HgbYDkH+zLjrzvOA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.12.2.tgz", + "integrity": "sha512-mME5MDwGe30Pq9zKPvyduyU86PH7aixwqYR2grTglAdB+AN8xXQ1vFGpYaUSJ5o5P/5znsSBeNcs5g5/2aQwow==", + "dev": true, + "requires": { + "@typescript-eslint/types": "8.12.2", + "@typescript-eslint/visitor-keys": "8.12.2", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "8.12.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.12.2.tgz", + "integrity": "sha512-PChz8UaKQAVNHghsHcPyx1OMHoFRUEA7rJSK/mDhdq85bk+PLsUHUBqTQTFt18VJZbmxBovM65fezlheQRsSDA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "8.12.2", + "eslint-visitor-keys": "^3.4.3" + } + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, "@typescript-eslint/visitor-keys": { @@ -8571,6 +9050,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.0.1.tgz", "integrity": "sha512-W5E+o0UfUcK5EgchLZsyVWqARmsM7v54/qEq6PY3YI5arkgmCzHiuk0zKSJJbm71V0xdRna4BGomkCTXz2/LkQ==", "dev": true, + "peer": true, "requires": { "@typescript-eslint/types": "8.0.1", "eslint-visitor-keys": "^3.4.3" @@ -8583,9 +9063,9 @@ "dev": true }, "acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true }, "acorn-jsx": { @@ -8742,7 +9222,8 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true + "dev": true, + "peer": true }, "arrify": { "version": "1.0.1", @@ -8858,14 +9339,6 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "requires": { - "file-uri-to-path": "1.0.0" - } - }, "bl": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/bl/-/bl-3.0.1.tgz", @@ -8910,9 +9383,9 @@ "dev": true }, "bson": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-6.8.0.tgz", - "integrity": "sha512-iOJg8pr7wq2tg/zSlCCHMi3hMm5JTOxLTagf3zxhcenHsFp+c6uOs6K7W5UE7A4QIJGtqh/ZovFNMP4mOPJynQ==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.9.0.tgz", + "integrity": "sha512-X9hJeyeM0//Fus+0pc5dSUMhhrrmWwQUtdavaQeF3Ta6m69matZkGWV/MrBcnwUeLC8W9kwwc2hfkZgUuCX3Ig==", "dev": true }, "buffer": { @@ -9082,9 +9555,9 @@ "dev": true }, "chai": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", "dev": true, "requires": { "assertion-error": "^1.1.0", @@ -9093,7 +9566,15 @@ "get-func-name": "^2.0.2", "loupe": "^2.3.6", "pathval": "^1.1.1", - "type-detect": "^4.0.8" + "type-detect": "^4.1.0" + }, + "dependencies": { + "type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true + } } }, "chai-subset": { @@ -9780,6 +10261,7 @@ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "peer": true, "requires": { "path-type": "^4.0.0" } @@ -9989,27 +10471,31 @@ "dev": true }, "eslint": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.8.0.tgz", - "integrity": "sha512-K8qnZ/QJzT2dLKdZJVX6W4XOwBzutMYmt0lqUS+JdXgd+HTYFlonFgkJ8s44d/zMPPCnOOk0kMWCApCPhiOy9A==", + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.13.0.tgz", + "integrity": "sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.11.0", - "@eslint/config-array": "^0.17.1", + "@eslint/config-array": "^0.18.0", + "@eslint/core": "^0.7.0", "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.8.0", + "@eslint/js": "9.13.0", + "@eslint/plugin-kit": "^0.2.0", + "@humanfs/node": "^0.16.5", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.0", - "@nodelib/fs.walk": "^1.2.8", + "@humanwhocodes/retry": "^0.3.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.0.2", - "eslint-visitor-keys": "^4.0.0", - "espree": "^10.1.0", + "eslint-scope": "^8.1.0", + "eslint-visitor-keys": "^4.1.0", + "espree": "^10.2.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -10019,21 +10505,18 @@ "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", "text-table": "^0.2.0" }, "dependencies": { "eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true } } @@ -10056,9 +10539,9 @@ } }, "eslint-scope": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", - "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", "dev": true, "requires": { "esrecurse": "^4.3.0", @@ -10072,20 +10555,20 @@ "dev": true }, "espree": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", - "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, "requires": { - "acorn": "^8.12.0", + "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.0.0" + "eslint-visitor-keys": "^4.2.0" }, "dependencies": { "eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true } } @@ -10258,11 +10741,6 @@ "flat-cache": "^4.0.0" } }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, "fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -10668,6 +11146,7 @@ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "peer": true, "requires": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -10963,12 +11442,6 @@ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true - }, "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", @@ -11633,9 +12106,9 @@ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, "mocha": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.0.tgz", - "integrity": "sha512-v8/rBWr2VO5YkspYINnvu81inSz2y3ODJrhO175/Exzor1RcEZZkizgE2A+w/CAXXoESS8Kys5E62dOHGHzULA==", + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", + "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", "dev": true, "requires": { "ansi-colors": "^4.1.3", @@ -12485,7 +12958,8 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true + "dev": true, + "peer": true }, "pathval": { "version": "1.1.1", @@ -13052,7 +13526,8 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true + "dev": true, + "peer": true }, "smart-buffer": { "version": "4.2.0", @@ -13731,9 +14206,9 @@ "optional": true }, "undici-types": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", - "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==", + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "dev": true }, "unique-filename": { diff --git a/package.json b/package.json index 3458f5b..064c944 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mongodb-client-encryption", - "version": "6.1.0", + "version": "6.1.1", "description": "Official client encryption module for the MongoDB Node.js driver", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -21,7 +21,7 @@ "clang-format": "clang-format --style=file:.clang-format --Werror -i addon/*", "check:eslint": "ESLINT_USE_FLAT_CONFIG=false eslint src test", "check:clang-format": "clang-format --style=file:.clang-format --dry-run --Werror addon/*", - "test": "mocha test", + "test": "mocha --v8-expose-gc test", "prepare": "tsc", "rebuild": "node-gyp rebuild", "prebuild": "prebuild --runtime napi --strip --verbose --all" @@ -37,27 +37,26 @@ "gypfile": true, "mongodb:libmongocrypt": "1.11.0", "dependencies": { - "bindings": "^1.5.0", "node-addon-api": "^4.3.0", "prebuild-install": "^7.1.2" }, "devDependencies": { "@types/bindings": "^1.5.5", "@types/chai": "^4.3.17", - "@types/mocha": "^10.0.7", - "@types/node": "^22.1.0", + "@types/mocha": "^10.0.9", + "@types/node": "^22.8.6", "@types/semver": "^7.5.8", "@types/sinon": "^17.0.3", "@types/sinon-chai": "^3.2.12", - "@typescript-eslint/eslint-plugin": "^8.0.1", - "bson": "^6.8.0", - "chai": "^4.4.1", + "@typescript-eslint/eslint-plugin": "^8.12.2", + "bson": "^6.9.0", + "chai": "^4.5.0", "chai-subset": "^1.6.0", "clang-format": "^1.8.0", - "eslint": "^9.8.0", + "eslint": "^9.13.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.2.1", - "mocha": "^10.7.0", + "mocha": "^10.8.2", "node-gyp": "^10.1.0", "prebuild": "^13.0.0", "prettier": "^3.2.5", @@ -97,4 +96,4 @@ "moduleResolution": "node" } } -} +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 85ab3d2..ab43cb4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1,15 @@ import { cryptoCallbacks } from './crypto_callbacks'; export { cryptoCallbacks }; -import bindings = require('bindings'); -const mc: MongoCryptBindings = bindings('mongocrypt'); +function load() { + try { + return require('../build/Release/mongocrypt.node'); + } catch { + return require('../build/Debug/mongocrypt.node'); + } +} + +const mc: MongoCryptBindings = load(); /** * The value returned by the native bindings diff --git a/test/bindings.test.ts b/test/bindings.test.ts index 3d6fbcb..67d5670 100644 --- a/test/bindings.test.ts +++ b/test/bindings.test.ts @@ -406,10 +406,15 @@ describe('MongoCryptConstructor', () => { describe('MongoCryptContext', () => { let context: MongoCryptContext; + let weakMongoCryptRef: WeakRef; + beforeEach(() => { - context = new MongoCrypt({ + let crypt = new MongoCrypt({ kmsProviders: serialize({ aws: {} }) - }).makeDecryptionContext(serialize({})); + }); + context = crypt.makeDecryptionContext(serialize({})); + weakMongoCryptRef = new WeakRef(crypt); + crypt = null; }); for (const property of ['status', 'state']) { @@ -444,5 +449,15 @@ describe('MongoCryptContext', () => { context.addMongoOperationResponse(new Uint8Array(Buffer.from([1, 2, 3]))) ).not.to.throw(); }); + + it('can be called with multiple Uint8Arrays and intermittent GC', () => { + for (let i = 0; i < 20; i++) { + globalThis.gc(); + expect(() => + context.addMongoOperationResponse(new Uint8Array(Buffer.from([1, 2, 3]))) + ).not.to.throw(); + } + expect(weakMongoCryptRef.deref()).to.equal(undefined); + }); }); }); diff --git a/tsconfig.json b/tsconfig.json index 6e89abe..c82117d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,7 +9,7 @@ "moduleResolution": "node", "skipLibCheck": true, "lib": [ - "es2020" + "es2020", "es2021.WeakRef" ], // We don't make use of tslib helpers, all syntax used is supported by target engine "importHelpers": false,