{"_id":"@areumtecnologia/mysql-db-handler","_rev":"14-d301e07d5da49cecfefa5bcd53fc1e77","name":"@areumtecnologia/mysql-db-handler","dist-tags":{"latest":"1.0.14"},"versions":{"1.0.0":{"name":"@areumtecnologia/mysql-db-handler","version":"1.0.0","author":{"name":"Renan Moreira / Áreum Tecnologia"},"license":"MIT","_id":"@areumtecnologia/mysql-db-handler@1.0.0","maintainers":[{"name":"areumtecnologia","email":"dev@areum.com.br"}],"dist":{"shasum":"85c955ef25a89d5584917d07888666d200667498","tarball":"https://registry.npmjs.org/@areumtecnologia/mysql-db-handler/-/mysql-db-handler-1.0.0.tgz","fileCount":7,"integrity":"sha512-L4dJq3PBPSMfN/RkPg8VoiyfAwucrzzfOMrOjGLaiflKgzfnF/OoCpt6aTE4VY3T9aEIQiHXPNY2rlJxzxHPqg==","signatures":[{"sig":"MEYCIQDwkicqWg1FYkuiUT+rFz2quSgXKx0k6omyA6eyiOBkLgIhAIgfcZXlANF9dlsIH4DFiMkO/MVsEW7Y5ak84/Pubnkq","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":24075},"main":"index.js","gitHead":"4f849ffa170a338bc29484df6341cf298860f6c4","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_npmUser":{"name":"areumtecnologia","email":"dev@areum.com.br"},"_npmVersion":"11.6.0","description":"A powerful MySQL wrapper with connection pooling, singleton support, and advanced query handling for Node.js.","directories":{},"_nodeVersion":"25.1.0","dependencies":{"mysql2":"^3.0.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/mysql-db-handler_1.0.0_1763837402128_0.7085939016643619","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@areumtecnologia/mysql-db-handler","version":"1.0.2","author":{"name":"Renan Moreira / Áreum Tecnologia"},"license":"MIT","_id":"@areumtecnologia/mysql-db-handler@1.0.2","maintainers":[{"name":"areumtecnologia","email":"dev@areum.com.br"}],"dist":{"shasum":"0bd8eb1bd92dabe7e0a286984538f99830f85418","tarball":"https://registry.npmjs.org/@areumtecnologia/mysql-db-handler/-/mysql-db-handler-1.0.2.tgz","fileCount":7,"integrity":"sha512-+XVLoPu0qw74YN4L086br+OfvRe0jO2xvXEeMsUJCojqcc2/HHVgbrmJH11Acm2cvOpIBe43Ok5bAWV1ETqGkg==","signatures":[{"sig":"MEQCICMkQBXO5wk6e/I/HzeByMGCeyQnh0aDZSb/YyzGaNG3AiBatoA24D09erbfEz7sOw5Os7Zx3aqJ+hVhhNSzm/erhg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":24073},"main":"index.js","gitHead":"ad4c985d4a7964f01db6a02c66151199cc938a99","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_npmUser":{"name":"areumtecnologia","email":"dev@areum.com.br"},"_npmVersion":"11.6.0","description":"A powerful MySQL wrapper with connection pooling, singleton support, and advanced query handling for Node.js.","directories":{},"_nodeVersion":"25.1.0","dependencies":{"mysql2":"^3.0.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/mysql-db-handler_1.0.2_1763838475591_0.5065914723402805","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@areumtecnologia/mysql-db-handler","version":"1.0.3","author":{"name":"Renan Moreira / Áreum Tecnologia"},"license":"MIT","_id":"@areumtecnologia/mysql-db-handler@1.0.3","maintainers":[{"name":"areumtecnologia","email":"dev@areum.com.br"}],"dist":{"shasum":"6c72c94b59e2e13a7beaa60e658b8c61c98e976f","tarball":"https://registry.npmjs.org/@areumtecnologia/mysql-db-handler/-/mysql-db-handler-1.0.3.tgz","fileCount":7,"integrity":"sha512-/hdYuRl199MdsGDdFvUit2hgVbXpBaVNGIm4JARGvQpTbAsZAFqqgWvp/n7vAFFJil/u0EfH/OBv2cfpMLE6tA==","signatures":[{"sig":"MEYCIQCJ2ei2sWWgGnVYg/L4RAWvyNYI2f14FpxNcZ4jRl/DdwIhAOTSxvL2kidJ8fgmrf+ES4AKJzniIvPJGtB31/v7YhCI","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":24171},"main":"index.js","gitHead":"6e498ab03c561c8b01104c207b0c70e9e0c6546d","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_npmUser":{"name":"areumtecnologia","email":"dev@areum.com.br"},"_npmVersion":"11.6.0","description":"A powerful MySQL wrapper with connection pooling, singleton support, and advanced query handling for Node.js.","directories":{},"_nodeVersion":"25.1.0","dependencies":{"mysql2":"^3.0.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/mysql-db-handler_1.0.3_1763838820303_0.23473493908269782","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@areumtecnologia/mysql-db-handler","version":"1.0.4","author":{"name":"Renan Moreira / Áreum Tecnologia"},"license":"MIT","_id":"@areumtecnologia/mysql-db-handler@1.0.4","maintainers":[{"name":"areumtecnologia","email":"dev@areum.com.br"}],"dist":{"shasum":"531337ee7ab4b729b74c36bfceecf979d921df83","tarball":"https://registry.npmjs.org/@areumtecnologia/mysql-db-handler/-/mysql-db-handler-1.0.4.tgz","fileCount":9,"integrity":"sha512-K+edY6ih3iNg/2n1ypYYerXZcmyhbr/xHtR/IIf/YldE8fvu0ITVrMoXogJrWkEpqRr3rkYEUtldrlo4rR4rWQ==","signatures":[{"sig":"MEUCIGsjR2HPlIIVcFpLyizOIGJPg6wDDLP50rNGsXNjgfwJAiEArNaCO60ulN+3+ZJulBGH5kPjR3zbhB0L7AwWQw3c8P8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":25220},"main":"index.js","gitHead":"6e498ab03c561c8b01104c207b0c70e9e0c6546d","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_npmUser":{"name":"areumtecnologia","email":"dev@areum.com.br"},"_npmVersion":"11.6.0","description":"A powerful MySQL wrapper with connection pooling, singleton support, and advanced query handling for Node.js.","directories":{},"_nodeVersion":"25.2.1","dependencies":{"mysql2":"^3.0.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/mysql-db-handler_1.0.4_1766437571927_0.6649787353427874","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@areumtecnologia/mysql-db-handler","version":"1.0.5","author":{"name":"Renan Moreira / Áreum Tecnologia"},"license":"MIT","_id":"@areumtecnologia/mysql-db-handler@1.0.5","maintainers":[{"name":"areumtecnologia","email":"dev@areum.com.br"}],"dist":{"shasum":"3d99cd30838ace64bcebfdfac79eb2e0d3591287","tarball":"https://registry.npmjs.org/@areumtecnologia/mysql-db-handler/-/mysql-db-handler-1.0.5.tgz","fileCount":7,"integrity":"sha512-yi8tMXSCc0OiFQjo05gFJKfBtCAuN6/4X3V/M/g8HfGG0SsgIXlX8lSc0Bd/vDfr0bLuDUmxtZOR8p6UrH2a6A==","signatures":[{"sig":"MEYCIQCYdddYxvuWcudRoSW7tFw4Yg6//paqVoEnAP6PRvU+fgIhANaA519zYF8UQr7oJ8BWfGd2Fn4quD1OCvR+w+G61zAN","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":28477},"main":"index.js","gitHead":"6e498ab03c561c8b01104c207b0c70e9e0c6546d","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_npmUser":{"name":"areumtecnologia","email":"dev@areum.com.br"},"_npmVersion":"11.6.0","description":"A powerful MySQL wrapper with connection pooling, singleton support, and advanced query handling for Node.js.","directories":{},"_nodeVersion":"25.2.1","dependencies":{"mysql2":"^3.0.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/mysql-db-handler_1.0.5_1780529557362_0.27574797613369517","host":"s3://npm-registry-packages-npm-production"}},"1.0.6":{"name":"@areumtecnologia/mysql-db-handler","version":"1.0.6","author":{"name":"Renan Moreira / Áreum Tecnologia"},"license":"MIT","_id":"@areumtecnologia/mysql-db-handler@1.0.6","maintainers":[{"name":"areumtecnologia","email":"dev@areum.com.br"}],"dist":{"shasum":"6ee1cc665ada4448b6c0da4fbbbd4b882c40cd18","tarball":"https://registry.npmjs.org/@areumtecnologia/mysql-db-handler/-/mysql-db-handler-1.0.6.tgz","fileCount":7,"integrity":"sha512-DabCrM8YYDK37kAOaRaT7Ykcb2cQouJvf3mwsmxNqimQQGZb1SDMb4z1UzqxF34Xq6Vrzi6vg4pAZvxvfAimWA==","signatures":[{"sig":"MEQCIC/z6viFG3DS2pEFpdy8UmPn1jg47MOZarqFKEpKdelyAiATXJZU9ES8zsYqtTva0EbbcjnjUXgGMpZm/LHlI/X7qA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":28569},"main":"index.js","gitHead":"d6bdf2a43b1f3288c2d1169115922159acda35c6","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_npmUser":{"name":"areumtecnologia","email":"dev@areum.com.br"},"_npmVersion":"11.6.0","description":"A powerful MySQL wrapper with connection pooling, singleton support, and advanced query handling for Node.js.","directories":{},"_nodeVersion":"25.2.1","dependencies":{"mysql2":"^3.22.5"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/mysql-db-handler_1.0.6_1781616122410_0.6896038631365873","host":"s3://npm-registry-packages-npm-production"}},"1.0.7":{"name":"@areumtecnologia/mysql-db-handler","version":"1.0.7","author":{"name":"Renan Moreira / Áreum Tecnologia"},"license":"MIT","_id":"@areumtecnologia/mysql-db-handler@1.0.7","maintainers":[{"name":"areumtecnologia","email":"dev@areum.com.br"}],"dist":{"shasum":"a7ca49b2e6b2233fa40791e2ef6ded4e83286c1c","tarball":"https://registry.npmjs.org/@areumtecnologia/mysql-db-handler/-/mysql-db-handler-1.0.7.tgz","fileCount":7,"integrity":"sha512-+tfe5b3q8VL+Gy0hK88ORd0Sj4gjL3yddegFzE4LBsI6hhs/N3cbwiJsRsb2FwjxXPgd/u3Gz3p2HhOXyFv0Jw==","signatures":[{"sig":"MEYCIQDlO0ed2z4637sAz322Q52PWOJaJFX7Wp/qvkwaP2SvUAIhAOzfwmqZCLJRARN2SAIMv9N7PLuHkXIeMweH3tKfQea/","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":28569},"main":"index.js","gitHead":"d6bdf2a43b1f3288c2d1169115922159acda35c6","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_npmUser":{"name":"areumtecnologia","email":"dev@areum.com.br"},"_npmVersion":"11.6.0","description":"A powerful MySQL wrapper with connection pooling, singleton support, and advanced query handling for Node.js.","directories":{},"_nodeVersion":"25.2.1","dependencies":{"mysql2":"^3.22.5"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/mysql-db-handler_1.0.7_1781616417235_0.5306589815077538","host":"s3://npm-registry-packages-npm-production"}},"1.0.8":{"name":"@areumtecnologia/mysql-db-handler","version":"1.0.8","author":{"name":"Renan Moreira / Áreum Tecnologia"},"license":"MIT","_id":"@areumtecnologia/mysql-db-handler@1.0.8","maintainers":[{"name":"areumtecnologia","email":"dev@areum.com.br"}],"dist":{"shasum":"0b7cd8062147455e4729254388747c4cf63598eb","tarball":"https://registry.npmjs.org/@areumtecnologia/mysql-db-handler/-/mysql-db-handler-1.0.8.tgz","fileCount":7,"integrity":"sha512-LVN3aMQQX16Lq9cGliYSKuql+BLW5Uoo31gJzn4l88krQXpUsJeYrhrSH6cCsWA+4KpagGH+1X99SfLTjhFITQ==","signatures":[{"sig":"MEQCIAe6jd1D5RpdCjWD4KnVCQy4P/ZYfR9j1egzStYYXO2+AiBgpxqNutThEUGtagXtbH+7cOazVUSf1Vw4yaHsY6uEIg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":34519},"main":"index.js","gitHead":"dd6d9618745860ab81ecc7e22c11e18712aa4ea0","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_npmUser":{"name":"areumtecnologia","email":"dev@areum.com.br"},"_npmVersion":"11.6.0","description":"A powerful MySQL wrapper with connection pooling, singleton support, and advanced query handling for Node.js.","directories":{},"_nodeVersion":"25.2.1","dependencies":{"mysql2":"^3.22.5"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/mysql-db-handler_1.0.8_1784044055661_0.663496614870374","host":"s3://npm-registry-packages-npm-production"}},"1.0.9":{"name":"@areumtecnologia/mysql-db-handler","version":"1.0.9","author":{"name":"Renan Moreira / Áreum Tecnologia"},"license":"MIT","_id":"@areumtecnologia/mysql-db-handler@1.0.9","maintainers":[{"name":"areumtecnologia","email":"dev@areum.com.br"}],"dist":{"shasum":"fa367cc1f24fcfb96706146580c16376f7638700","tarball":"https://registry.npmjs.org/@areumtecnologia/mysql-db-handler/-/mysql-db-handler-1.0.9.tgz","fileCount":7,"integrity":"sha512-5WDyJ+/KmmfcHK1Z9Ul50fRcZIfOKGflvdxxPFNe84b3P1H4SjDqjgFTjCy9XT5fQQOwAa2P121Kgdu6JlwTmQ==","signatures":[{"sig":"MEYCIQCZePkcvAcJfdpmJcC3MzNy/LlEP+fLT9C4tu0V+k/VqwIhAMtwiWulG0XwmUAVElsOWaXSSg4ZYVdJ9hjlqgQXjkeB","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":36145},"main":"index.js","gitHead":"dd6d9618745860ab81ecc7e22c11e18712aa4ea0","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_npmUser":{"name":"areumtecnologia","email":"dev@areum.com.br"},"_npmVersion":"11.6.0","description":"A powerful MySQL wrapper with connection pooling, singleton support, and advanced query handling for Node.js.","directories":{},"_nodeVersion":"25.2.1","dependencies":{"mysql2":"^3.22.5"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/mysql-db-handler_1.0.9_1784044731365_0.754482508137446","host":"s3://npm-registry-packages-npm-production"}},"1.0.10":{"name":"@areumtecnologia/mysql-db-handler","version":"1.0.10","author":{"name":"Renan Moreira / Áreum Tecnologia"},"license":"MIT","_id":"@areumtecnologia/mysql-db-handler@1.0.10","maintainers":[{"name":"areumtecnologia","email":"dev@areum.com.br"}],"dist":{"shasum":"60c539a49db577ca9fe311a230a70836cfb8f18d","tarball":"https://registry.npmjs.org/@areumtecnologia/mysql-db-handler/-/mysql-db-handler-1.0.10.tgz","fileCount":6,"integrity":"sha512-Lcv/MbJLStyG2iFWjJ/YjJpKLIReAVpu955sD55i+Y/36U7YcPaoqPDAryQ7e+1qoR+7fPt/TWmjrwFuvsFj+Q==","signatures":[{"sig":"MEQCIBeYmv2FRjjmDoyLFc5YpSWdQIH5kdrWMRDCPb/G79UDAiAOgrv3/1KZB5gzrMCN/C1BXYej4at1dYyBIOqeSYdP7w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":38115},"main":"index.js","gitHead":"dd6d9618745860ab81ecc7e22c11e18712aa4ea0","scripts":{"test":"node tests/update_operators.test.js && node tests/selectToDatatable.test.js"},"_npmUser":{"name":"areumtecnologia","email":"dev@areum.com.br"},"_npmVersion":"11.6.0","description":"A powerful MySQL wrapper with connection pooling, singleton support, and advanced query handling for Node.js.","directories":{},"_nodeVersion":"25.2.1","dependencies":{"mysql2":"^3.23.1"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/mysql-db-handler_1.0.10_1784933012906_0.2950156098784098","host":"s3://npm-registry-packages-npm-production"}},"1.0.11":{"name":"@areumtecnologia/mysql-db-handler","version":"1.0.11","author":{"name":"Renan Moreira / Áreum Tecnologia"},"license":"MIT","_id":"@areumtecnologia/mysql-db-handler@1.0.11","maintainers":[{"name":"areumtecnologia","email":"dev@areum.com.br"}],"dist":{"shasum":"03ad4f72cec9b76d8baf8e0be832d8d39607acb4","tarball":"https://registry.npmjs.org/@areumtecnologia/mysql-db-handler/-/mysql-db-handler-1.0.11.tgz","fileCount":6,"integrity":"sha512-EFDgL2T5os4I+tutqpIGBgvcpHxcztWRfReIb34lWhUe6CGwit5sbtdldMNFvLG/vR34RRVcylcQt3I1fU9pYQ==","signatures":[{"sig":"MEUCIFKP3QrhqZ5l5BnQtGf2FiyQAZamvtN53UAZIciOOC9OAiEA48Olzw7RmuxTh4HWCN5j6IhcBH6vAW/AlyybKrh9Qz8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIBXMmJBb+7jdCvH0WEoYYQg/eZS40CYhrN7h5laqxtQsAiAHY4rJ7LtUcDpA1gMf4HZr6c7aWaSNihlLtnlzAD8XXg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":55522},"main":"index.js","gitHead":"dd6d9618745860ab81ecc7e22c11e18712aa4ea0","scripts":{"test":"node tests/update_operators.test.js && node tests/selectToDatatable.test.js && node tests/transactions.test.js && node tests/customersSales.test.js"},"_npmUser":{"name":"areumtecnologia","email":"dev@areum.com.br"},"_npmVersion":"11.6.0","description":"A powerful MySQL wrapper with connection pooling, singleton support, and advanced query handling for Node.js.","directories":{},"_nodeVersion":"25.2.1","dependencies":{"mysql2":"^3.24.4","node-cache":"^5.1.2"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/mysql-db-handler_1.0.11_1790036555197_0.31965194570995115","host":"s3://npm-registry-packages-npm-production"}},"1.0.12":{"name":"@areumtecnologia/mysql-db-handler","version":"1.0.12","author":{"name":"Renan Moreira / Áreum Tecnologia"},"license":"MIT","_id":"@areumtecnologia/mysql-db-handler@1.0.12","maintainers":[{"name":"areumtecnologia","email":"dev@areum.com.br"}],"dist":{"shasum":"6d7f0a3950d9717cfa6468344d02619430f2c357","tarball":"https://registry.npmjs.org/@areumtecnologia/mysql-db-handler/-/mysql-db-handler-1.0.12.tgz","fileCount":6,"integrity":"sha512-GwdreGbjGGjra62IlduqqkSwWwInq4Iw3sxOhvtuR7LO0uSV7MDXZ0gadgyHYZQzW86AjzOE/5Zi5URw0F9jNw==","signatures":[{"sig":"MEQCIBnEa4TP6unsSN241wUBzZroyUbLys99nyFN0zRGodNhAiASYYRyu8XC64NWFXJfdD/Tl7bPsqqcIOQZLqYmrt+Axw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQCxCxPpC6TPGfuAvBRrxVEox1Qr4Usp+g/YSzoylTbvaAIhAJlA9p/51zR1vOSqvPPFtvqT1KCd+HXnGtZXedekNBFn","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":59477},"main":"index.js","gitHead":"dd6d9618745860ab81ecc7e22c11e18712aa4ea0","scripts":{"test":"node tests/security_and_robustness.test.js && node tests/update_operators.test.js && node tests/selectToDatatable.test.js && node tests/transactions.test.js && node tests/customersSales.test.js"},"_npmUser":{"name":"areumtecnologia","email":"dev@areum.com.br"},"_npmVersion":"11.6.0","description":"A powerful MySQL wrapper with connection pooling, singleton support, and advanced query handling for Node.js.","directories":{},"_nodeVersion":"25.2.1","dependencies":{"mysql2":"^3.24.4","node-cache":"^5.1.2"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/mysql-db-handler_1.0.12_1790040925228_0.2943916667800879","host":"s3://npm-registry-packages-npm-production"}},"1.0.13":{"name":"@areumtecnologia/mysql-db-handler","version":"1.0.13","author":{"name":"Renan Moreira / Áreum Tecnologia"},"license":"MIT","_id":"@areumtecnologia/mysql-db-handler@1.0.13","maintainers":[{"name":"areumtecnologia","email":"dev@areum.com.br"}],"dist":{"shasum":"fedd86a925798217d4f5786199527b600dbfcc3f","tarball":"https://registry.npmjs.org/@areumtecnologia/mysql-db-handler/-/mysql-db-handler-1.0.13.tgz","fileCount":6,"integrity":"sha512-fo5NykSG2/2kpakjX1XV44+v0A5n2wZphgJlnV+D3Q5kaQVpQyoq6j5xK6seDGUu3LPGPdH5xWBhe6YafTGzGQ==","signatures":[{"sig":"MEUCICvIeZ7ygWAPu+Xshe/rPEx/6xJJOXFPCScvTMt7eJclAiEAytja3mRHlDqFfZ+ME1A1jt7Hrmw4gDWEmgBUzY+y5LM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQDnK1ZJ1dieyHn1BXZcJc/o0kFddVVWVfSlveMi3kZhHAIgfcDKNWXyDW9IfdcK3M90O0aDE3Xpl5kGJDcQz/vB5Vw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":61324},"main":"index.js","gitHead":"dd6d9618745860ab81ecc7e22c11e18712aa4ea0","scripts":{"test":"node tests/security_and_robustness.test.js && node tests/update_operators.test.js && node tests/selectToDatatable.test.js && node tests/transactions.test.js && node tests/customersSales.test.js"},"_npmUser":{"name":"areumtecnologia","email":"dev@areum.com.br"},"_npmVersion":"11.6.0","description":"A powerful MySQL wrapper with connection pooling, singleton support, and advanced query handling for Node.js.","directories":{},"_nodeVersion":"25.2.1","dependencies":{"mysql2":"^3.24.4","node-cache":"^5.1.2"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/mysql-db-handler_1.0.13_1790088049463_0.5414789554548214","host":"s3://npm-registry-packages-npm-production"}},"1.0.14":{"_id":"@areumtecnologia/mysql-db-handler@1.0.14","dist":{"shasum":"165b691afb7314b83873d6909e7a50125344c5f6","tarball":"https://registry.npmjs.org/@areumtecnologia/mysql-db-handler/-/mysql-db-handler-1.0.14.tgz","fileCount":6,"integrity":"sha512-1OLNv7k1voshrPvaobIaS92aJLNj1cE9Wm0ukInGmUPmfyGlcUMs4Oi7w0Vt+Aiq2GlqgpVe4LP6Pa1zEYALxw==","signatures":[{"sig":"MEUCIQD+3XdGnioXDG4rCpT4Bn94OKuZZZywiLcgJL6vhW/W7AIgGmTwHzKIBiIkX8CETu9+A3Prrj4s7RRffcTGJqnplUA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCaVJ021j0Bn76tNjhA+cRV5iIpvEp/AvFc2c1WjG2PtAIhAOOPW2FgeykGWJcAtV8x8Oew48SDS4Ey/X0px40sbk1M"}],"unpackedSize":67296},"main":"index.js","name":"@areumtecnologia/mysql-db-handler","author":{"name":"Renan Moreira / Áreum Tecnologia"},"gitHead":"dd6d9618745860ab81ecc7e22c11e18712aa4ea0","license":"MIT","scripts":{"test":"node tests/security_and_robustness.test.js && node tests/update_operators.test.js && node tests/selectToDatatable.test.js && node tests/transactions.test.js && node tests/customersSales.test.js"},"version":"1.0.14","_npmUser":{"name":"areumtecnologia","email":"dev@areum.com.br"},"_npmVersion":"11.6.0","description":"A powerful MySQL wrapper with connection pooling, singleton support, and advanced query handling for Node.js.","directories":{},"maintainers":[{"name":"areumtecnologia","email":"dev@areum.com.br"}],"_nodeVersion":"25.2.1","dependencies":{"mysql2":"^3.24.4","node-cache":"^5.1.2"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mysql-db-handler_1.0.14_1790088215589_0.975524003748204"}}},"time":{"created":"2025-11-22T18:50:02.061Z","modified":"2026-09-22T14:43:35.830Z","1.0.0":"2025-11-22T18:50:02.343Z","1.0.2":"2025-11-22T19:07:55.820Z","1.0.3":"2025-11-22T19:13:40.480Z","1.0.4":"2025-12-22T21:06:12.081Z","1.0.5":"2026-06-03T23:32:37.527Z","1.0.6":"2026-06-16T13:22:02.583Z","1.0.7":"2026-06-16T13:26:57.402Z","1.0.8":"2026-07-14T15:47:35.818Z","1.0.9":"2026-07-14T15:58:51.491Z","1.0.10":"2026-07-24T22:43:33.047Z","1.0.11":"2026-09-22T00:22:35.289Z","1.0.12":"2026-09-22T01:35:25.317Z","1.0.13":"2026-09-22T14:40:49.549Z","1.0.14":"2026-09-22T14:43:35.658Z"},"author":{"name":"Renan Moreira / Áreum Tecnologia"},"license":"MIT","description":"A powerful MySQL wrapper with connection pooling, singleton support, and advanced query handling for Node.js.","maintainers":[{"name":"areumtecnologia","email":"dev@areum.com.br"}],"readme":"# @areumtecnologia/mysql-db-handler\r\n\r\nA powerful, robust, and production-ready MySQL wrapper for Node.js. It features connection pooling, query caching (optional), jQuery DataTables server-side processing integration, safe error handling, and a flexible abstraction layer for CRUD operations.\r\n\r\n## Table of Contents\r\n\r\n* [Features](#features)\r\n* [Installation](#installation)\r\n* [Core Classes](#core-classes)\r\n  * [DataBase (Standard Connection)](#1-database-standard-connection)\r\n  * [DataBase (With Query & Schema Caching)](#2-database-with-query--schema-caching)\r\n  * [DataBaseHandler (CRUD Abstraction)](#3-databasehandler-crud-abstraction)\r\n* [Basic Usage](#basic-usage)\r\n  * [1. Initializing Connection](#1-initializing-connection)\r\n  * [2. Executing Raw SQL](#2-executing-raw-sql)\r\n  * [3. Using the DataBaseHandler](#3-using-the-databasehandler)\r\n* [Advanced Querying (`select` method)](#advanced-querying-select-method)\r\n  * [Basic Selection](#basic-selection)\r\n  * [Working with the `IN` and `NOT IN` Operators](#working-with-the-in-and-not-in-operators)\r\n    * [Automatic `IN` Detection](#automatic-in-detection)\r\n    * [Explicit `IN` / `NOT IN` Operator](#explicit-in--not-in-operator)\r\n    * [Empty Array Safety (`IN ()` Protection)](#empty-array-safety-in-protection)\r\n  * [Combining Multiple Conditions (AND / OR)](#combining-multiple-conditions-and--or)\r\n* [CRUD Operations](#crud-operations)\r\n  * [Inserting Records (`insert`)](#inserting-records-insert)\r\n  * [Updating Records (`update`)](#updating-records-update)\r\n  * [Deleting Records (`delete`)](#deleting-records-delete)\r\n* [jQuery DataTables Server-Side Support (`selectToDatatable`)](#jquery-datatables-server-side-support-selecttodatatable)\r\n  * [Key Features & Performance](#key-features--performance-optimizations)\r\n  * [Method Signature](#method-signature)\r\n  * [Basic Express.js Example](#basic-expressjs-example)\r\n  * [Enforcing Backend Security (`strictCondition`)](#enforcing-backend-security-strictcondition)\r\n  * [Using JOINs and Custom Expressions](#using-joins-and-custom-expressions)\r\n  * [Frontend jQuery DataTables Setup](#frontend-jquery-datatables-setup)\r\n  * [Response Structure & Error Handling](#response-structure--error-handling)\r\n* [Transaction Support (ACID & Transparent)](#transaction-support-acid--transparent)\r\n  * [1. Explicit Block (`db.transaction`)](#1-explicit-block-dbtransaction)\r\n  * [2. Singleton Compatibility with `AsyncLocalStorage`](#2-singleton-compatibility-with-asynclocalstorage)\r\n  * [3. Post-Commit Hook (`db.onCommit`)](#3-post-commit-hook-dboncommit)\r\n  * [4. Route Wrapper (`db.transactional`)](#4-route-wrapper-dbtransactional)\r\n  * [5. Express Lazy Middleware (`db.autoTransaction`)](#5-express-lazy-middleware-dbautotransaction)\r\n  * [6. Nested Transactions & Savepoints](#6-nested-transactions--savepoints)\r\n* [Database Singleton Pattern](#database-singleton-pattern)\r\n* [Error Handling Strategy](#error-handling-strategy)\r\n* [Contributing](#contributing)\r\n* [License](#license)\r\n\r\n---\r\n\r\n## Features\r\n\r\n* **Connection Pooling:** Efficiently manages and recycles database connections using `mysql2/promise`.\r\n* **ACID Transactions:** Comprehensive transaction management with automatic `BEGIN`, `COMMIT`, `ROLLBACK`, and safe connection release.\r\n* **Transparent Singleton Support:** Powered by native Node.js `AsyncLocalStorage`. Shared table singletons automatically adopt the current transaction without passing `tx` around.\r\n* **Post-Commit Hooks (`onCommit`):** Execute external tasks (banking APIs, emails, webhooks) strictly after database transactions successfully commit.\r\n* **Express Lazy Middleware:** Zero-code change transactions via `db.autoTransaction()`. Reads remain non-blocking on the pool, while write operations seamlessly open and commit transactions on demand.\r\n* **Savepoints (Nested Transactions):** Safely run sub-transactions with partial rollback support without aborting outer transactions.\r\n* **Flexible Query Builder:** Run complex operations without writing manual SQL strings.\r\n* **Automatic `IN` Handling:** Smart processing of arrays for SQL `IN` and `NOT IN` operations (including prevention of empty array query crashes).\r\n* **Optional Caching Wrapper:** Native support for query and schema caching using `node-cache` (automatically bypassed during active transactions).\r\n* **Server-Side DataTables Integration:** Effortless integration with jQuery DataTables server-side requests, handling filters, sorting, search (global and column-based), regex, and count totals automatically.\r\n* **Robust Error Handling:** Intercepts and wraps database errors in predictable objects outside transactions, while throwing inside transactions to ensure immediate rollback.\r\n\r\n---\r\n\r\n## Installation\r\n\r\n```bash\r\nnpm install @areumtecnologia/mysql-db-handler\r\n```\r\n\r\nIf you wish to use the caching features, ensure `node-cache` is installed:\r\n```bash\r\nnpm install node-cache\r\n```\r\n\r\n---\r\n\r\n## Core Classes\r\n\r\nThe package exports the following primary components:\r\n\r\n### 1. `DataBase` (Standard Connection)\r\nLocated in `lib/database.js`. Manages standard pooled connections, schema discovery, and query execution.\r\n\r\n### 2. `DataBase` (With Query & Schema Caching)\r\nLocated in `lib/database-cache.js`. Overrides the standard `DataBase` implementation to provide in-memory query and table schema caching. It is ideal for read-heavy environments.\r\n\r\n### 3. `DataBaseHandler` (CRUD Abstraction)\r\nLocated in `lib/databasehandler.js`. Bind this class to a specific table to perform database actions through utility methods (`select`, `selectBy`, `insert`, `update`, `delete`, `selectToDatatable`).\r\n\r\n---\r\n\r\n## Basic Usage\r\n\r\n### 1. Initializing Connection\r\n\r\n```javascript\r\nconst { DataBase } = require('@areumtecnologia/mysql-db-handler');\r\n\r\n// Configuration matches mysql2 connection configuration\r\nconst db = new DataBase({\r\n    host: 'localhost',\r\n    user: 'root',\r\n    password: 'password',\r\n    database: 'my_app_db',\r\n    port: 3306,\r\n    connectionLimit: 10,\r\n    waitForConnections: true,\r\n    queueLimit: 0\r\n});\r\n```\r\n\r\n### 2. Executing Raw SQL\r\n\r\nRaw queries are executed through connection pooling. The library handles obtaining and releasing the connection automatically.\r\n\r\n```javascript\r\ntry {\r\n    const rows = await db.query('SELECT * FROM users WHERE active = ? AND role = ?', [1, 'editor']);\r\n    console.log('Active editors:', rows);\r\n} catch (error) {\r\n    console.error('Database query failed:', error);\r\n}\r\n```\r\n\r\n### 3. Using the DataBaseHandler\r\n\r\nWrap a table with a handler to abstract SQL construction.\r\n\r\n```javascript\r\nconst { DataBase, DataBaseHandler } = require('@areumtecnologia/mysql-db-handler');\r\n\r\nconst db = new DataBase({ /* config */ });\r\nconst usersHandler = new DataBaseHandler(db, 'users');\r\n```\r\n\r\n---\r\n\r\n## Advanced Querying (`select` method)\r\n\r\nThe `select(params, clauses)` method builds complex SQL `WHERE` clauses from arrays of condition objects.\r\n\r\n### Basic Selection\r\n\r\nYou can pass condition objects where the key is the column name and the value is the target value.\r\n\r\n```javascript\r\n// Simple equals comparison (=)\r\nconst users = await usersHandler.select([\r\n    { role: 'admin' }\r\n]);\r\n// Executes: SELECT * FROM users WHERE `role` = ?\r\n```\r\n\r\n### Working with the `IN` and `NOT IN` Operators\r\n\r\nThe library provides special support for SQL `IN` operations by mapping JavaScript arrays to queries.\r\n\r\n#### Automatic `IN` Detection\r\nIf a condition's value is an array, and no operator is explicitly set, the query builder automatically treats it as an `IN` statement:\r\n\r\n```javascript\r\nconst activeUsers = await usersHandler.select([\r\n    { status: ['active', 'pending'] }\r\n]);\r\n// Executes: SELECT * FROM users WHERE `status` IN (?, ?)\r\n// Bindings: ['active', 'pending']\r\n```\r\n\r\n#### Explicit `IN` / `NOT IN` Operator\r\nYou can explicitly define the `operator` as `'IN'` or `'NOT IN'`:\r\n\r\n```javascript\r\n// Using NOT IN explicitly\r\nconst nonAdminUsers = await usersHandler.select([\r\n    { role: ['admin', 'superadmin'], operator: 'NOT IN' }\r\n]);\r\n// Executes: SELECT * FROM users WHERE `role` NOT IN (?, ?)\r\n// Bindings: ['admin', 'superadmin']\r\n```\r\n\r\n#### Empty Array Safety (`IN ()` Protection)\r\nIn standard SQL, executing a query with an empty array in the `IN` clause (e.g., `WHERE status IN ()`) yields a syntax error and crashes the execution. The library automatically mitigates this:\r\n\r\n* **Empty `IN`**: Evaluates to `1 = 0` (always false). No records match this sub-clause, ensuring safe execution.\r\n* **Empty `NOT IN`**: Evaluates to `1 = 1` (always true). All records match this sub-clause, returning all values since nothing is excluded.\r\n\r\n```javascript\r\n// Safe empty array handling\r\nconst results = await usersHandler.select([\r\n    { id: [], operator: 'IN' }\r\n]);\r\n// Executes: SELECT * FROM users WHERE 1 = 0\r\n\r\nconst allResults = await usersHandler.select([\r\n    { id: [], operator: 'NOT IN' }\r\n]);\r\n// Executes: SELECT * FROM users WHERE 1 = 1\r\n```\r\n\r\n### Combining Multiple Conditions (AND / OR)\r\n\r\nInterleave condition objects with string elements representing logical operators:\r\n\r\n```javascript\r\nconst filteredProducts = await productsHandler.select(\r\n    [\r\n        { category: 'electronics' },\r\n        'AND',\r\n        { price: 500, operator: '>' },\r\n        'AND',\r\n        { brand: ['Sony', 'LG'] } // Automatically mapped to IN\r\n    ],\r\n    {\r\n        'ORDERBY': 'price',\r\n        'DESC': true,\r\n        'LIMIT': 20\r\n    }\r\n);\r\n// Executes: \r\n// SELECT * FROM products WHERE `category` = ? AND `price` > ? AND `brand` IN (?, ?) ORDER BY price DESC LIMIT 20\r\n```\r\n\r\n---\r\n\r\n## CRUD Operations\r\n\r\n### Inserting Records (`insert`)\r\n\r\nAdds a new row to the associated table using key-value properties.\r\n\r\n```javascript\r\nconst result = await usersHandler.insert({\r\n    name: 'John Doe',\r\n    email: 'john.doe@example.com',\r\n    role: 'member',\r\n    created_at: new Date()\r\n});\r\n\r\nconsole.log('Inserted ID:', result.insertId);\r\n```\r\n\r\n### Updating Records (`update`)\r\n\r\nPerforms selective updates by specifying both a `set` payload and a `where` filter. The `where` filter supports both standard flat objects (where conditions are implicitly joined by `AND` using `=` or `REGEXP`) and complex array configurations (with operators, `AND`, and `OR`), sharing the same advanced querying capabilities as the `select` method.\r\n\r\n#### 1. Simple Object Syntax (Implicit AND, = operator)\r\n\r\n```javascript\r\nconst result = await usersHandler.update({\r\n    set: {\r\n        status: 'suspended',\r\n        notes: 'Violated terms of service'\r\n    },\r\n    where: {\r\n        id: 42,\r\n        status: 'active'\r\n    }\r\n});\r\n\r\nconsole.log('Affected rows:', result.affectedRows);\r\n// Executes: UPDATE users SET `status` = ?, `notes` = ? WHERE `id` = ? AND `status` = ?\r\n```\r\n\r\n#### 2. Advanced Array Syntax (with operators, AND/OR, and IN)\r\n\r\nYou can pass an array of condition objects interleaved with `AND` or `OR` string elements to construct complex queries:\r\n\r\n```javascript\r\n// Example updating records based on numeric thresholds and logical operators\r\nconst result = await usersHandler.update({\r\n    set: {\r\n        status: 'inactive'\r\n    },\r\n    where: [\r\n        { age: 18, operator: '<' },\r\n        'AND',\r\n        { status: 'active' }\r\n    ]\r\n});\r\n// Executes: UPDATE users SET `status` = ? WHERE `age` < ? AND `status` = ?\r\n\r\n// Example updating records using automatic IN operator detection\r\nconst result = await usersHandler.update({\r\n    set: {\r\n        role: 'archived'\r\n    },\r\n    where: [\r\n        { id: [10, 20, 30] } // Automatically builds: WHERE `id` IN (?, ?, ?)\r\n    ]\r\n});\r\n// Executes: UPDATE users SET `role` = ? WHERE `id` IN (?, ?, ?)\r\n\r\n// Example combining complex logic (AND/OR)\r\nconst result = await usersHandler.update({\r\n    set: {\r\n        category: 'Premium'\r\n    },\r\n    where: [\r\n        { total_purchases: 1000, operator: '>' },\r\n        'AND',\r\n        { status: 'active' },\r\n        'OR',\r\n        { is_vip: 1 }\r\n    ]\r\n});\r\n// Executes: UPDATE users SET `category` = ? WHERE `total_purchases` > ? AND `status` = ? OR `is_vip` = ?\r\n```\r\n\r\n### Deleting Records (`delete`)\r\n\r\nDeletes rows matching the conditions object (joined by implicit `AND` operators).\r\n\r\n```javascript\r\nconst result = await usersHandler.delete({\r\n    status: 'temporary',\r\n    is_expired: 1\r\n});\r\n\r\nconsole.log('Deleted rows:', result.affectedRows);\r\n```\r\n\r\n---\r\n\r\n## jQuery DataTables Server-Side Support (`selectToDatatable`)\r\n\r\nThe `selectToDatatable` method provides seamless, high-performance integration with [jQuery DataTables](https://datatables.net/) server-side processing. It automatically handles pagination, search (global and column-based), multi-column ordering, regex filters, total/filtered counts, and backend security constraints.\r\n\r\n### Key Features & Performance Optimizations\r\n\r\n* **Smart Single `COUNT(*)`:** When no client-side search filter is active (the default state in standard page loads and pagination), `recordsFiltered` is automatically set to `recordsTotal`. The method skips the redundant second `COUNT(*)` query, **reducing database count latency and I/O by up to 50%**.\r\n* **Short-Circuit on Zero Results:** If search criteria yield zero records (`recordsFiltered === 0`), the data retrieval query (`SELECT ... LIMIT`) is skipped entirely, returning an empty array `data: []` instantly without triggering expensive `filesort` or index scans.\r\n* **Format & Content-Type Agnostic:** Fully supports both `application/json` (with native JavaScript boolean values `true`/`false`) and `application/x-www-form-urlencoded` (nested or bracket-flattened parameters like `columns[0][data]`).\r\n* **Multi-Column Sorting:** Seamlessly parses multiple order directives (e.g. holding Shift or configuring `order: [[0, 'asc'], [1, 'desc']]`), producing `ORDER BY \\`col1\\` ASC, \\`col2\\` DESC`.\r\n* **Safe Qualified Column Identifiers:** Automatically splits table/alias qualified column names (e.g. `u.name`, `p.title`) and escapes each component separately (`` `u`.`name` ``), avoiding MySQL `ER_BAD_FIELD_ERROR` issues when using JOINs.\r\n* **Prototype Pollution Protection (CWE-1321):** Deeply sanitizes incoming request keys, blocking injections targeting `__proto__`, `constructor`, or `prototype`.\r\n\r\n---\r\n\r\n### Method Signature\r\n\r\n```javascript\r\nawait handler.selectToDatatable(rawDtQuery, strictCondition = [])\r\n```\r\n\r\n| Parameter | Type | Description |\r\n| :--- | :--- | :--- |\r\n| `rawDtQuery` | `Object` | The request payload sent by jQuery DataTables (`req.body` or `req.query`). Supports both flat bracketed keys and nested objects. |\r\n| `strictCondition` | `Array` *(Optional)* | Backend conditions that the client cannot view or modify (e.g. multi-tenant isolation, user scoping, active-only filters). |\r\n\r\n---\r\n\r\n### Basic Express.js Example\r\n\r\n```javascript\r\nconst express = require('express');\r\nconst { db, usersHandler } = require('./databaseController');\r\n\r\nconst app = express();\r\napp.use(express.json());\r\napp.use(express.urlencoded({ extended: true }));\r\n\r\napp.post('/api/users/datatable', async (req, res) => {\r\n    // req.body contains: { draw, start, length, search, order, columns }\r\n    const result = await usersHandler.selectToDatatable(req.body);\r\n    res.json(result);\r\n});\r\n```\r\n\r\n---\r\n\r\n### Enforcing Backend Security (`strictCondition`)\r\n\r\nNever rely on the client to enforce data access boundaries. Pass a `strictCondition` array to apply non-bypassable constraints. It shares the same query-building syntax as `select()`, supporting custom operators, arrays (`IN`), and `AND`/`OR` conjunctions:\r\n\r\n```javascript\r\napp.post('/api/orders/datatable', async (req, res) => {\r\n    // Client-side parameters cannot bypass these conditions:\r\n    const strictConditions = [\r\n        { tenant_id: req.user.tenantId },\r\n        'AND',\r\n        { status: 'deleted', operator: '!=' },\r\n        'AND',\r\n        { store_id: [101, 102, 105] } // Automatically mapped to: `store_id` IN (?, ?, ?)\r\n    ];\r\n\r\n    const result = await ordersHandler.selectToDatatable(req.body, strictConditions);\r\n    res.json(result);\r\n});\r\n```\r\n\r\n---\r\n\r\n### Using JOINs and Custom Expressions\r\n\r\nIf your table requires JOINs or computed fields, initialize the `DataBaseHandler` with an expression parameter:\r\n\r\n```javascript\r\n// Table: 'sales s'\r\n// Expression: JOIN with customers and users, selecting extra fields\r\nconst salesHandler = new DataBaseHandler(\r\n    db, \r\n    'customers_sales s', \r\n    ', c.name AS customer_name, u.name AS user_name ' +\r\n    'LEFT JOIN customers c ON c.id = s.customer ' +\r\n    'LEFT JOIN users u ON u.id = s.user'\r\n);\r\n\r\napp.post('/api/sales/datatable', async (req, res) => {\r\n    // DataTables columns can now search and sort by qualified identifiers:\r\n    // e.g. columns: [{ data: 's.id' }, { data: 'c.name' }, { data: 's.amount' }]\r\n    const result = await salesHandler.selectToDatatable(req.body, [\r\n        { 's.deleted_at': null, operator: 'IS' }\r\n    ]);\r\n    res.json(result);\r\n});\r\n```\r\n\r\n---\r\n\r\n### Frontend jQuery DataTables Setup\r\n\r\nConfigure your frontend DataTables instance with `serverSide: true`:\r\n\r\n```javascript\r\n$('#usersTable').DataTable({\r\n    processing: true,\r\n    serverSide: true,\r\n    ajax: {\r\n        url: '/api/users/datatable',\r\n        type: 'POST',\r\n        contentType: 'application/json',\r\n        data: function (d) {\r\n            return JSON.stringify(d);\r\n        }\r\n    },\r\n    columns: [\r\n        { data: 'id', name: 'id' },\r\n        { data: 'name', name: 'name' },\r\n        { data: 'email', name: 'email' },\r\n        { data: 'role', name: 'role' },\r\n        { \r\n            data: null, \r\n            orderable: false, \r\n            searchable: false,\r\n            render: function (data, type, row) {\r\n                return `<button onclick=\"editUser(${row.id})\">Edit</button>`;\r\n            }\r\n        }\r\n    ],\r\n    order: [[0, 'desc']]\r\n});\r\n```\r\n\r\n---\r\n\r\n### Response Structure & Error Handling\r\n\r\nThe method always returns the standard JSON response expected by DataTables:\r\n\r\n#### Success Response\r\n```json\r\n{\r\n  \"draw\": 1,\r\n  \"recordsTotal\": 1250,\r\n  \"recordsFiltered\": 45,\r\n  \"data\": [\r\n    { \"id\": 42, \"name\": \"John Doe\", \"email\": \"john@example.com\", \"role\": \"admin\" },\r\n    { \"id\": 43, \"name\": \"Jane Smith\", \"email\": \"jane@example.com\", \"role\": \"editor\" }\r\n  ]\r\n}\r\n```\r\n\r\n#### Safe Error Handling\r\nIf an underlying database error occurs, `selectToDatatable` catches it safely, notifies your `onError` handler (if configured), and returns a structured response with the error message so the client table does not hang indefinitely:\r\n\r\n```json\r\n{\r\n  \"draw\": 1,\r\n  \"recordsTotal\": 0,\r\n  \"recordsFiltered\": 0,\r\n  \"data\": [],\r\n  \"error\": \"ER_NO_SUCH_TABLE: Table 'my_app_db.invalid_table' doesn't exist\"\r\n}\r\n```\r\n\r\n\r\n---\r\n\r\n## Transaction Support (ACID & Transparent)\r\n\r\nThe library provides first-class transaction support built on top of Node.js native `AsyncLocalStorage`. Transactions can be used explicitly or completely transparently across shared Singletons without manual connection passing.\r\n\r\n### 1. Explicit Block (`db.transaction`)\r\n\r\nWrap operations in `db.transaction(callback)`. If the callback resolves, `COMMIT` is executed automatically. If an error is thrown or unhandled, `ROLLBACK` is performed automatically and the connection is safely released back to the pool.\r\n\r\n```javascript\r\nawait db.transaction(async () => {\r\n    await usersHandler.insert({ name: 'Alice', balance: 500 });\r\n    await auditHandler.insert({ action: 'USER_CREATED', user: 'Alice' });\r\n    // If any error occurs, all operations in this block are rolled back!\r\n});\r\n```\r\n\r\n### 2. Singleton Compatibility with `AsyncLocalStorage`\r\n\r\nWhen running inside `db.transaction()`, **you do not need to pass transaction instances to your handlers**. Globally shared table handlers (Singletons) automatically bind to the active transaction of the current asynchronous execution context:\r\n\r\n```javascript\r\n// databaseController.js - Exporting global singletons\r\nconst db = require('./db-singleton');\r\nconst { DataBaseHandler } = require('@areumtecnologia/mysql-db-handler');\r\n\r\nconst customersSales = new DataBaseHandler(db, 'customers_sales');\r\nconst customersProducts = new DataBaseHandler(db, 'customers_products');\r\n\r\nmodule.exports = { db, customersSales, customersProducts };\r\n```\r\n\r\n```javascript\r\n// salesRouter.js - In your route handler\r\nconst { db, customersSales, customersProducts } = require('./databaseController');\r\n\r\nrouter.post('/sales', async (req, res) => {\r\n    try {\r\n        let saleResult;\r\n        await db.transaction(async () => {\r\n            saleResult = await customersSales.insert(req.body.sale);\r\n            \r\n            // Check stock and update\r\n            const product = (await customersProducts.select([{ id: req.body.productId }]))[0];\r\n            if (!product || product.stock < req.body.amount) {\r\n                // Throwing an error here triggers automatic ROLLBACK for both tables!\r\n                throw new Error('Insufficient product stock');\r\n            }\r\n\r\n            await customersProducts.update({\r\n                set: { stock: product.stock - req.body.amount },\r\n                where: { id: req.body.productId }\r\n            });\r\n        });\r\n\r\n        res.json(saleResult);\r\n    } catch (err) {\r\n        res.status(500).json({ error: err.message });\r\n    }\r\n});\r\n```\r\n\r\n### 3. Post-Commit Hook (`db.onCommit`)\r\n\r\nWhen integrating with external third-party APIs (e.g., banking APIs, payment gateways, invoice generators, SMS, emails), **never perform slow external network calls while holding database locks**.\r\n\r\n`db.onCommit(callback)` queues actions that will run **only after the database transaction successfully commits**:\r\n\r\n```javascript\r\nawait db.transaction(async () => {\r\n    const sale = await customersSales.insert(payload);\r\n    \r\n    // Schedule bank invoice creation: only runs if DB transaction commits!\r\n    db.onCommit(async () => {\r\n        await bankApiClient.registerInvoice(sale.insertId, invoiceData);\r\n    });\r\n});\r\n```\r\n\r\n### 4. Route Wrapper (`db.transactional`)\r\n\r\nEasily wrap asynchronous route handlers or service functions to run within a transaction without nesting `try/catch` or `db.transaction` boilerplate:\r\n\r\n```javascript\r\nrouter.post('/orders', db.transactional(async (req, res) => {\r\n    const order = await ordersHandler.insert(req.body);\r\n    await itemsHandler.insert({ orderId: order.insertId, items: req.body.items });\r\n    res.json(order);\r\n}));\r\n```\r\n\r\n### 5. Express Lazy Middleware (`db.autoTransaction`)\r\n\r\nFor maximum transparency with **zero lines changed** in your route handlers, enable the `autoTransaction` middleware in your Express app:\r\n\r\n```javascript\r\n// server.js / app.js\r\napp.use(db.autoTransaction({\r\n    methods: ['POST', 'PUT', 'DELETE', 'PATCH'], // HTTP methods to protect\r\n    lazy: true // Only opens a transaction when a write operation occurs\r\n}));\r\n```\r\n\r\n* **Lazy Allocation:** `GET` requests or routes that only execute `select` queries will not open a transaction or hold connections.\r\n* **On-Demand Write:** As soon as an `insert`, `update`, or `delete` is called on any handler during the request, a dedicated transaction starts automatically.\r\n* **Automatic Completion:** When `res.send()` or `res.json()` completes with HTTP status `< 400`, the transaction automatically commits. If status is `>= 400` or an exception is thrown, it rolls back automatically.\r\n\r\n### 6. Nested Transactions & Savepoints\r\n\r\nThe library natively supports nested transactions using MySQL `SAVEPOINT`s. Calling `db.transaction()` inside an existing transaction creates a savepoint instead of a new connection:\r\n\r\n```javascript\r\nawait db.transaction(async () => {\r\n    await mainHandler.insert({ status: 'started' });\r\n\r\n    try {\r\n        // Nested block runs under a SAVEPOINT\r\n        await db.transaction(async () => {\r\n            await subHandler.insert({ data: 'optional_task' });\r\n            throw new Error('Non-critical sub-task failed');\r\n        });\r\n    } catch (e) {\r\n        // Sub-task is rolled back to SAVEPOINT, but the main transaction can still commit!\r\n        console.warn('Sub-task skipped:', e.message);\r\n    }\r\n\r\n    await mainHandler.insert({ status: 'completed' });\r\n});\r\n```\r\n\r\n---\r\n\r\n## Database Singleton Pattern\r\n\r\nTo prevent initializing redundant pool connections across various modules in a Node.js project, it is highly recommended to configure a single shared instance (Singleton).\r\n\r\nCreate a `db.js` file:\r\n```javascript\r\n// db.js\r\nconst { DataBase } = require('@areumtecnologia/mysql-db-handler');\r\n\r\nconst dbInstance = new DataBase({\r\n    host: process.env.DB_HOST || 'localhost',\r\n    user: process.env.DB_USER || 'root',\r\n    password: process.env.DB_PASSWORD,\r\n    database: process.env.DB_NAME,\r\n    connectionLimit: parseInt(process.env.DB_POOL_LIMIT) || 10\r\n});\r\n\r\nmodule.exports = dbInstance;\r\n```\r\n\r\nImport it in your business controllers/repositories:\r\n```javascript\r\n// usersRepository.js\r\nconst db = require('./db');\r\nconst { DataBaseHandler } = require('@areumtecnologia/mysql-db-handler');\r\n\r\nconst usersHandler = new DataBaseHandler(db, 'users');\r\n\r\nmodule.exports = {\r\n    getUserById: (id) => usersHandler.selectBy({ id })\r\n};\r\n```\r\n\r\n---\r\n\r\n## Error Handling Strategy\r\n\r\nDatabase exceptions generated during execution are caught internally by the `DataBase` instance. This means that instead of raising unhandled exceptions that could crash your Node.js application, the library wraps the error.\r\n\r\nSpecifically, the following methods from **`DataBase`** and **`DataBaseHandler`** return an object with an `error` property when an execution error occurs:\r\n*   `DataBase.query()`\r\n*   `DataBaseHandler.select()` / `selectBy()`\r\n*   `DataBaseHandler.insert()`\r\n*   `DataBaseHandler.update()`\r\n*   `DataBaseHandler.delete()`\r\n*   `DataBaseHandler.selectToDatatable()`\r\n\r\n### Example: Checking for errors in queries\r\n\r\n```javascript\r\n// Example with Select if column doesn't exist (triggers database error)\r\nconst users = await usersHandler.select([{ non_existent_column: 'admin' }]);\r\nif (users.error) {\r\n    console.error('Failed to select users:', users.error.message);\r\n}\r\n\r\n// Example with Insert\r\nconst insertResult = await usersHandler.insert({ name: 'John Doe' });\r\nif (insertResult.error) {\r\n    console.error('Failed to insert user:', insertResult.error.message);\r\n}\r\n\r\n// Example with Update\r\nconst updateResult = await usersHandler.update({\r\n    set: { status: 'active' },\r\n    where: { id: 999 }\r\n});\r\nif (updateResult.error) {\r\n    console.error('Failed to update user:', updateResult.error.message);\r\n}\r\n\r\n// Example with Delete\r\nconst deleteResult = await usersHandler.delete({ id: 999 });\r\nif (deleteResult.error) {\r\n    console.error('Failed to delete user:', deleteResult.error.message);\r\n}\r\n```\r\n\r\n> [!NOTE]\r\n> If you execute a `select` using valid columns but search for values that do not exist in the table (e.g. `await usersHandler.select([{ role: 'non_existent_role' }])`), this is **not** considered a database error. The query will execute successfully and return an empty array `[]` (without any `error` property). An error is only returned for actual database execution failures (such as syntax errors, missing columns, database connection drops, etc.).\r\n\r\n---\r\n\r\n## Contributing\r\n\r\nContributions are welcome! Please open an issue or submit a pull request.\r\n\r\n1. Fork the repository\r\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\r\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\r\n4. Push to the branch (`git push origin feature/amazing-feature`)\r\n5. Open a Pull Request\r\n\r\n---\r\n\r\n## License\r\n\r\nMIT\r\n","readmeFilename":"README.md"}