diff --git a/CHANGES.txt b/CHANGES.txt index 1453141e9..51c6f7ee2 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,7 +1,9 @@ -10.29.0 (September XX, 2024) +10.29.0 (October XX, 2024) + - Added `factory.destroy()` method, which invokes the `destroy` method on all SDK clients created by the factory. - Updated @splitsoftware/splitio-commons package to version 1.18.0 that includes minor updates: - Added support for targeting rules based on large segments for browsers. - Updated some transitive dependencies for vulnerability fixes. + - Bugfixing - Removed an overloaded `client` method in the `SplitIO.ISDK` interface that accepted a key and trafficType parameters. This interface corresponds to the SDK factory instance in NodeJS, which, unlike `SplitIO.IBrowserSDK` for the Browser, does not handle multiple client instances based on keys or traffic types. 10.28.0 (September 6, 2024) - Updated @splitsoftware/splitio-commons package to version 1.17.0 that includes minor updates: diff --git a/package-lock.json b/package-lock.json index 737623e94..399f249cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "@splitsoftware/splitio", - "version": "10.28.1-rc.1", + "version": "10.28.1-rc.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@splitsoftware/splitio", - "version": "10.28.1-rc.1", + "version": "10.28.1-rc.4", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "1.17.1-rc.0", + "@splitsoftware/splitio-commons": "1.17.1-rc.4", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", @@ -872,9 +872,9 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "1.17.1-rc.0", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.17.1-rc.0.tgz", - "integrity": "sha512-WzF8b9zuPfyCqqp8ioeImFJCzSNjuziKQasg4HvPIPjHsFgiUlK/IPp0/1QuDbptEy1qsMJOdXV0wvLG0z1sZw==", + "version": "1.17.1-rc.4", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.17.1-rc.4.tgz", + "integrity": "sha512-Yi/NkpBmvixnoTw5AxG+p3N88ZNyD0NfBdLlN+IxI7sQ6I7Sx/5yYSQSC6I68EiJZLu79fJ1xMJ3BPS+gVyqZA==", "dependencies": { "tslib": "^2.3.1" }, @@ -1357,15 +1357,14 @@ } }, "node_modules/asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "dev": true, "dependencies": { "bn.js": "^4.0.0", "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" + "minimalistic-assert": "^1.0.0" } }, "node_modules/asn1.js/node_modules/bn.js": { @@ -1695,25 +1694,75 @@ } }, "node_modules/browserify-sign": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", - "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz", + "integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==", "dev": true, "dependencies": { "bn.js": "^5.2.1", "browserify-rsa": "^4.1.0", "create-hash": "^1.2.0", "create-hmac": "^1.1.7", - "elliptic": "^6.5.4", + "elliptic": "^6.5.5", + "hash-base": "~3.0", "inherits": "^2.0.4", - "parse-asn1": "^5.1.6", - "readable-stream": "^3.6.2", + "parse-asn1": "^5.1.7", + "readable-stream": "^2.3.8", "safe-buffer": "^5.2.1" }, "engines": { - "node": ">= 4" + "node": ">= 0.12" + } + }, + "node_modules/browserify-sign/node_modules/hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": ">=4" } }, + "node_modules/browserify-sign/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/browserify-sign/node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/browserify-sign/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/browserify-sign/node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, "node_modules/browserify-zlib": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", @@ -2091,9 +2140,9 @@ "dev": true }, "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true, "engines": { "node": ">= 0.6" @@ -2612,9 +2661,9 @@ } }, "node_modules/engine.io": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", - "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.2.tgz", + "integrity": "sha512-gmNvsYi9C8iErnZdVcJnvCpSKbWTt1E8+JZo8b+daLninywUWi5NQ5STSHZ9rFjFO7imNcvb8Pc5pe/wMR5xEw==", "dev": true, "dependencies": { "@types/cookie": "^0.4.1", @@ -2622,7 +2671,7 @@ "@types/node": ">=10.0.0", "accepts": "~1.3.4", "base64id": "2.0.0", - "cookie": "~0.4.1", + "cookie": "~0.7.2", "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~5.2.1", @@ -2633,9 +2682,9 @@ } }, "node_modules/engine.io-parser": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", - "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", "dev": true, "engines": { "node": ">=10.0.0" @@ -4951,9 +5000,9 @@ "dev": true }, "node_modules/nise/node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", "dev": true, "dependencies": { "isarray": "0.0.1" @@ -5284,16 +5333,33 @@ } }, "node_modules/parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz", + "integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==", "dev": true, "dependencies": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" + "asn1.js": "^4.10.1", + "browserify-aes": "^1.2.0", + "evp_bytestokey": "^1.0.3", + "hash-base": "~3.0", + "pbkdf2": "^3.1.2", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse-asn1/node_modules/hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": ">=4" } }, "node_modules/parse-ms": { @@ -6435,16 +6501,16 @@ } }, "node_modules/socket.io": { - "version": "4.7.5", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", - "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.0.tgz", + "integrity": "sha512-8U6BEgGjQOfGz3HHTYaC/L1GaxDCJ/KM0XTkJly0EhZ5U/du9uNEZy4ZgYzEzIqlx2CMm25CrCqr1ck899eLNA==", "dev": true, "dependencies": { "accepts": "~1.3.4", "base64id": "~2.0.0", "cors": "~2.8.5", "debug": "~4.3.2", - "engine.io": "~6.5.2", + "engine.io": "~6.6.0", "socket.io-adapter": "~2.5.2", "socket.io-parser": "~4.2.4" }, @@ -8528,9 +8594,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.17.1-rc.0", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.17.1-rc.0.tgz", - "integrity": "sha512-WzF8b9zuPfyCqqp8ioeImFJCzSNjuziKQasg4HvPIPjHsFgiUlK/IPp0/1QuDbptEy1qsMJOdXV0wvLG0z1sZw==", + "version": "1.17.1-rc.4", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.17.1-rc.4.tgz", + "integrity": "sha512-Yi/NkpBmvixnoTw5AxG+p3N88ZNyD0NfBdLlN+IxI7sQ6I7Sx/5yYSQSC6I68EiJZLu79fJ1xMJ3BPS+gVyqZA==", "requires": { "tslib": "^2.3.1" } @@ -8943,15 +9009,14 @@ } }, "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "dev": true, "requires": { "bn.js": "^4.0.0", "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" + "minimalistic-assert": "^1.0.0" }, "dependencies": { "bn.js": { @@ -9234,20 +9299,73 @@ } }, "browserify-sign": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", - "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz", + "integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==", "dev": true, "requires": { "bn.js": "^5.2.1", "browserify-rsa": "^4.1.0", "create-hash": "^1.2.0", "create-hmac": "^1.1.7", - "elliptic": "^6.5.4", + "elliptic": "^6.5.5", + "hash-base": "~3.0", "inherits": "^2.0.4", - "parse-asn1": "^5.1.6", - "readable-stream": "^3.6.2", + "parse-asn1": "^5.1.7", + "readable-stream": "^2.3.8", "safe-buffer": "^5.2.1" + }, + "dependencies": { + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + } } }, "browserify-zlib": { @@ -9524,9 +9642,9 @@ "dev": true }, "cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true }, "copyfiles": { @@ -9954,9 +10072,9 @@ } }, "engine.io": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", - "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.2.tgz", + "integrity": "sha512-gmNvsYi9C8iErnZdVcJnvCpSKbWTt1E8+JZo8b+daLninywUWi5NQ5STSHZ9rFjFO7imNcvb8Pc5pe/wMR5xEw==", "dev": true, "requires": { "@types/cookie": "^0.4.1", @@ -9964,7 +10082,7 @@ "@types/node": ">=10.0.0", "accepts": "~1.3.4", "base64id": "2.0.0", - "cookie": "~0.4.1", + "cookie": "~0.7.2", "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~5.2.1", @@ -9981,9 +10099,9 @@ } }, "engine.io-parser": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", - "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", "dev": true }, "enhanced-resolve": { @@ -11715,9 +11833,9 @@ "dev": true }, "path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", "dev": true, "requires": { "isarray": "0.0.1" @@ -11977,16 +12095,29 @@ } }, "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz", + "integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==", "dev": true, "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" + "asn1.js": "^4.10.1", + "browserify-aes": "^1.2.0", + "evp_bytestokey": "^1.0.3", + "hash-base": "~3.0", + "pbkdf2": "^3.1.2", + "safe-buffer": "^5.2.1" + }, + "dependencies": { + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + } } }, "parse-ms": { @@ -12848,16 +12979,16 @@ } }, "socket.io": { - "version": "4.7.5", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", - "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.0.tgz", + "integrity": "sha512-8U6BEgGjQOfGz3HHTYaC/L1GaxDCJ/KM0XTkJly0EhZ5U/du9uNEZy4ZgYzEzIqlx2CMm25CrCqr1ck899eLNA==", "dev": true, "requires": { "accepts": "~1.3.4", "base64id": "~2.0.0", "cors": "~2.8.5", "debug": "~4.3.2", - "engine.io": "~6.5.2", + "engine.io": "~6.6.0", "socket.io-adapter": "~2.5.2", "socket.io-parser": "~4.2.4" } diff --git a/package.json b/package.json index 95344a2b8..5561c0700 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.28.1-rc.1", + "version": "10.28.1-rc.4", "description": "Split SDK", "files": [ "README.md", @@ -40,7 +40,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.17.1-rc.0", + "@splitsoftware/splitio-commons": "1.17.1-rc.4", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", diff --git a/src/__tests__/browserSuites/push-synchronization.spec.js b/src/__tests__/browserSuites/push-synchronization.spec.js index 25e7e93d7..4086050fd 100644 --- a/src/__tests__/browserSuites/push-synchronization.spec.js +++ b/src/__tests__/browserSuites/push-synchronization.spec.js @@ -47,7 +47,6 @@ const config = { }, urls: baseUrls, streamingEnabled: true, - debug: true }; const settings = settingsFactory(config); diff --git a/src/__tests__/browserSuites/readiness.spec.js b/src/__tests__/browserSuites/readiness.spec.js index 8bc7dada8..f81fafccd 100644 --- a/src/__tests__/browserSuites/readiness.spec.js +++ b/src/__tests__/browserSuites/readiness.spec.js @@ -209,12 +209,7 @@ export default function (fetchMock, assert) { t.equal(getMembershipsHits(), 4 * CLIENTS_COUNT - 1, 'It should have not tried to synchronize segments again after the last update that left us in a no segment state.'); t.equal(readyCount, CLIENTS_COUNT, 'all clients must be ready'); - Promise.all([ - client2.destroy(), - client3.destroy(), - client.destroy() - ]).then(() => { t.end(); }); - + splitio.destroy().then(() => { t.end(); }); }, 10000); }, 0); }); @@ -293,12 +288,7 @@ export default function (fetchMock, assert) { t.equal(getMembershipsHits(), 4 * CLIENTS_COUNT - 1, 'It should have not tried to synchronize segments again after the last update that left us in a no segment state.'); t.equal(readyCount, CLIENTS_COUNT, 'all clients must be ready'); - Promise.all([ - client2.destroy(), - client3.destroy(), - client.destroy() - ]).then(() => { t.end(); }); - + splitio.destroy().then(() => { t.end(); }); }, 10000); }, 0); }); @@ -373,12 +363,7 @@ export default function (fetchMock, assert) { t.equal(getMembershipsHits(), 6 * CLIENTS_COUNT - 1, 'It should keep the producer synchronizing periodically..'); t.equal(readyCount, CLIENTS_COUNT, 'all clients must be ready'); - Promise.all([ - client2.destroy(), - client3.destroy(), - client.destroy() - ]).then(() => { t.end(); }); - + splitio.destroy().then(() => { t.end(); }); }, 3000); }, 0); }); @@ -417,8 +402,8 @@ export default function (fetchMock, assert) { }); const CLIENTS_COUNT = 3; // Just so it's easier to read the assertions. const client = splitio.client(); - const client2 = splitio.client('nicolas2@split.io'); - const client3 = splitio.client('nicolas3@split.io'); + splitio.client('nicolas2@split.io'); + splitio.client('nicolas3@split.io'); client.once(client.Event.SDK_READY, () => { t.ok(Date.now() - start >= membershipsEndpointDelay, 'It should not be ready without waiting for memberships, as there are segments in the first splits payload.'); @@ -442,12 +427,7 @@ export default function (fetchMock, assert) { setTimeout(() => { t.equal(getMembershipsHits(), 6 * CLIENTS_COUNT, 'It should keep the producer synchronizing periodically..'); - Promise.all([ - client2.destroy(), - client3.destroy(), - client.destroy() - ]).then(() => { t.end(); }); - + splitio.destroy().then(() => { t.end(); }); }, 3000); }, 0); }); @@ -486,19 +466,15 @@ export default function (fetchMock, assert) { }); const CLIENTS_COUNT = 3; // Just so it's easier to read the assertions. const client = splitio.client(); - const client2 = splitio.client('nicolas2@split.io'); - const client3 = splitio.client('nicolas3@split.io'); + splitio.client('nicolas2@split.io'); + splitio.client('nicolas3@split.io'); client.once(client.Event.SDK_READY, () => { t.ok(Date.now() - start >= membershipsEndpointDelay, 'It should not be ready without waiting for memberships, when we start from cache it might be stale.'); setTimeout(() => { t.equal(getMembershipsHits(), 3 * CLIENTS_COUNT, 'memberships should had been hit once per client on the first attempt and keep syncing afterwards.'); - Promise.all([ - client2.destroy(), - client3.destroy(), - client.destroy() - ]).then(() => { t.end(); }); + splitio.destroy().then(() => { t.end(); }); }, 2500); }); client.once(client.Event.SDK_READY_TIMED_OUT, () => { @@ -533,19 +509,15 @@ export default function (fetchMock, assert) { }); const CLIENTS_COUNT = 3; // Just so it's easier to read the assertions. const client = splitio.client(); - const client2 = splitio.client('nicolas2@split.io'); - const client3 = splitio.client('nicolas3@split.io'); + splitio.client('nicolas2@split.io'); + splitio.client('nicolas3@split.io'); client.once(client.Event.SDK_READY, () => { t.ok(Date.now() - start < 50, 'It should be ready quickly, since it had no segments and update has no segments either.'); setTimeout(() => { t.equal(getMembershipsHits(), 1 * CLIENTS_COUNT, 'memberships should had been hit once per client on the first attempt but stopped syncing afterwards'); - Promise.all([ - client2.destroy(), - client3.destroy(), - client.destroy() - ]).then(() => { t.end(); }); + splitio.destroy().then(() => { t.end(); }); }, 4500); }); client.once(client.Event.SDK_READY_TIMED_OUT, () => { @@ -584,19 +556,15 @@ export default function (fetchMock, assert) { }); const CLIENTS_COUNT = 3; // Just so it's easier to read the assertions. const client = splitio.client(); - const client2 = splitio.client('nicolas2@split.io'); - const client3 = splitio.client('nicolas3@split.io'); + splitio.client('nicolas2@split.io'); + splitio.client('nicolas3@split.io'); client.once(client.Event.SDK_READY, () => { const delay = Date.now() - start; t.ok(delay >= membershipsEndpointDelay, 'It should not be ready without waiting for memberships, when we start from cache it might be stale.'); setTimeout(() => { t.equal(getMembershipsHits(), 3 * CLIENTS_COUNT, 'memberships should had been hit once per client on the first attempt but stopped syncing afterwards'); - Promise.all([ - client2.destroy(), - client3.destroy(), - client.destroy() - ]).then(() => { t.end(); }); + splitio.destroy().then(() => { t.end(); }); }, 3000); }); client.once(client.Event.SDK_READY_TIMED_OUT, () => { @@ -631,19 +599,15 @@ export default function (fetchMock, assert) { }); const CLIENTS_COUNT = 3; // Just so it's easier to read the assertions. const client = splitio.client(); - const client2 = splitio.client('nicolas2@split.io'); - const client3 = splitio.client('nicolas3@split.io'); + splitio.client('nicolas2@split.io'); + splitio.client('nicolas3@split.io'); client.once(client.Event.SDK_READY, () => { t.ok(Date.now() - start >= membershipsEndpointDelay, 'It should not be ready without waiting for memberships, when we start from cache it might be stale and we had segments even though the update has nothing.'); setTimeout(() => { t.equal(getMembershipsHits(), 3 * CLIENTS_COUNT, 'memberships should had been hit once per client on the first attempt and kept syncing afterwards'); - Promise.all([ - client2.destroy(), - client3.destroy(), - client.destroy() - ]).then(() => { t.end(); }); + splitio.destroy().then(() => { t.end(); }); }, 3000); }); client.once(client.Event.SDK_READY_TIMED_OUT, () => { @@ -681,19 +645,15 @@ export default function (fetchMock, assert) { }); const CLIENTS_COUNT = 3; // Just so it's easier to read the assertions. const client = splitio.client(); - const client2 = splitio.client('nicolas2@split.io'); - const client3 = splitio.client('nicolas3@split.io'); + splitio.client('nicolas2@split.io'); + splitio.client('nicolas3@split.io'); client.once(client.Event.SDK_READY, () => { t.ok(Date.now() - start < 50, 'It should be ready without waiting for memberships, since when it downloads changes it will have no more use for them.'); setTimeout(() => { t.equal(getMembershipsHits(), 1 * CLIENTS_COUNT, 'memberships should had been hit once per client on the first attempt and stopped syncing afterwards'); - Promise.all([ - client2.destroy(), - client3.destroy(), - client.destroy() - ]).then(() => { t.end(); }); + splitio.destroy().then(() => { t.end(); }); }, 3000); }); client.once(client.Event.SDK_READY_TIMED_OUT, () => { diff --git a/src/__tests__/browserSuites/ready-promise.spec.js b/src/__tests__/browserSuites/ready-promise.spec.js index ebcd5843c..cb13c8107 100644 --- a/src/__tests__/browserSuites/ready-promise.spec.js +++ b/src/__tests__/browserSuites/ready-promise.spec.js @@ -561,7 +561,7 @@ export default function readyPromiseAssertions(fetchMock, assert) { }); }, 0); }); - }, fromSecondsToMillis(0.2)); + }, fromSecondsToMillis(0.25)); }, 'Validate that warning messages are properly sent'); diff --git a/src/__tests__/nodeSuites/lazy-init.spec.js b/src/__tests__/nodeSuites/lazy-init.spec.js new file mode 100644 index 000000000..68e92e8f5 --- /dev/null +++ b/src/__tests__/nodeSuites/lazy-init.spec.js @@ -0,0 +1,89 @@ +import { SplitFactory as SplitFactorySS } from '../../factory/node'; +import { SplitFactory as SplitFactoryCS } from '../../factory/browser'; + +// Tests should finish without dangling timers or requests +export default function (settings, fetchMock, t) { + + t.test('Server-side', async (assert) => { + let splitio; + + for (let i = 0; i < 100; i++) { + splitio = SplitFactorySS({ + core: { + authorizationKey: 'fake-token-' + i, + }, + urls: { + sdk: 'https://not-called/api', + events: 'https://not-called/api', + auth: 'https://not-called/api', + } + }, (modules) => { + modules.lazyInit = true; + }); + + const manager = splitio.manager(); + assert.deepEqual(manager.names(), [], 'We should not have done any request yet'); + + const client = splitio.client(); + assert.equal(client.getTreatment('user-1', 'split_test'), 'control', 'We should get control'); + assert.equal(client.track('user-1', 'user', 'my_event'), true, 'We should track the event'); + } + + fetchMock.getOnce('https://not-called/api/splitChanges?s=1.1&since=-1', { status: 200, body: { splits: [], since: -1, till: 1457552620999 } }); + fetchMock.getOnce('https://not-called/api/splitChanges?s=1.1&since=1457552620999', { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.postOnce('https://not-called/api/testImpressions/bulk', 200); + fetchMock.postOnce('https://not-called/api/events/bulk', 200); + + splitio.init(); + await splitio.client().ready(); + assert.true(splitio.client().__getStatus().isReady, 'Split SDK is ready'); + await splitio.destroy(); + + assert.end(); + }); + + t.test('Client-side', async (assert) => { + let splitio; + + for (let i = 0; i < 100; i++) { + splitio = SplitFactoryCS({ + core: { + authorizationKey: 'fake-token-' + i, + key: 'user-' + i, + }, + urls: { + sdk: 'https://not-called/api', + events: 'https://not-called/api', + auth: 'https://not-called/api', + } + }, (modules) => { + modules.lazyInit = true; + }); + + const manager = splitio.manager(); + assert.deepEqual(manager.names(), [], 'We should not have done any request yet'); + + const client = splitio.client(); + assert.equal(client.getTreatment('split_test'), 'control', 'We should get control'); + assert.equal(client.track('user', 'my_event'), true, 'We should track the event'); + + const otherClient = splitio.client('other-user'); + assert.equal(otherClient.getTreatment('split_test'), 'control', 'We should get control'); + assert.equal(otherClient.track('user', 'my_event'), true, 'We should track the event'); + } + + fetchMock.getOnce('https://not-called/api/splitChanges?s=1.2&since=-1', { status: 200, body: { splits: [], since: -1, till: 1457552620999 } }); + fetchMock.getOnce('https://not-called/api/splitChanges?s=1.2&since=1457552620999', { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.getOnce('https://not-called/api/memberships/user-99', { status: 200, body: {} }); + fetchMock.getOnce('https://not-called/api/memberships/other-user', { status: 200, body: {} }); + fetchMock.postOnce('https://not-called/api/testImpressions/bulk', 200); + fetchMock.postOnce('https://not-called/api/events/bulk', 200); + + splitio.init(); + await splitio.client().ready(); + assert.true(splitio.client().__getStatus().isReady, 'Split SDK is ready'); + await splitio.destroy(); + + assert.end(); + }); +} diff --git a/src/__tests__/nodeSuites/readiness.spec.js b/src/__tests__/nodeSuites/readiness.spec.js index 519571ea3..33e377eb3 100644 --- a/src/__tests__/nodeSuites/readiness.spec.js +++ b/src/__tests__/nodeSuites/readiness.spec.js @@ -49,7 +49,7 @@ export default function (fetchMock, assert) { try { await client.ready(); } catch (e) { - await client.destroy(); + await splitio.destroy(); t.end(); } }); diff --git a/src/__tests__/online/node.spec.js b/src/__tests__/online/node.spec.js index 94ca9d830..a3e4fcac7 100644 --- a/src/__tests__/online/node.spec.js +++ b/src/__tests__/online/node.spec.js @@ -3,6 +3,9 @@ import fetchMock from '../testUtils/nodeFetchMock'; import { url } from '../testUtils'; import { settingsFactory } from '../../settings/node'; +import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; +import splitChangesMock2 from '../mocks/splitchanges.since.1457552620999.json'; + import evaluationsSuite from '../nodeSuites/evaluations.spec'; import evaluationsSemverSuite from '../nodeSuites/evaluations-semver.spec'; import eventsSuite from '../nodeSuites/events.spec'; @@ -18,10 +21,8 @@ import ipAddressesSettingDebug from '../nodeSuites/ip-addresses-setting.debug.sp import readinessSuite from '../nodeSuites/readiness.spec'; import readyPromiseSuite from '../nodeSuites/ready-promise.spec'; import { fetchSpecificSplits, fetchSpecificSplitsForFlagSets } from '../nodeSuites/fetch-specific-splits.spec'; - -import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; -import splitChangesMock2 from '../mocks/splitchanges.since.1457552620999.json'; import flagSets from '../nodeSuites/flag-sets.spec'; +import lazyInitSuite from '../nodeSuites/lazy-init.spec'; const config = { core: { @@ -94,5 +95,7 @@ tape('## Node JS - E2E CI Tests ##', async function (assert) { /* Validate flag sets */ assert.test('E2E / Flag sets', flagSets.bind(null, fetchMock)); + assert.test('E2E / SplitFactory with lazy init', lazyInitSuite.bind(null, settings, fetchMock)); + assert.end(); }); diff --git a/src/settings/defaults/version.js b/src/settings/defaults/version.js index 036701e45..384a95183 100644 --- a/src/settings/defaults/version.js +++ b/src/settings/defaults/version.js @@ -1 +1 @@ -export const packageVersion = '10.28.1-rc.1'; +export const packageVersion = '10.28.1-rc.4'; diff --git a/ts-tests/index.ts b/ts-tests/index.ts index a37c52808..f3f0a926b 100644 --- a/ts-tests/index.ts +++ b/ts-tests/index.ts @@ -163,7 +163,6 @@ browserSettings = { } }; // With sync settings should return ISDK, if settings have async storage it should return IAsyncSDK -SDK = SplitFactory(browserSettings); SDK = SplitFactory(nodeSettings); AsyncSDK = SplitFactory(asyncSettings); BrowserSDK = SplitFactory(browserSettings); @@ -195,15 +194,15 @@ SDK.settings.features = { 'split_x': 'on' }; // Browser // Client and Manager client = SDK.client(); -client = SDK.client('a customer key'); -client = SDK.client('a customer key', 'a traffic type'); manager = SDK.manager(); +manager = BrowserSDK.manager(); // Today async clients are only possible on Node. Shared client creation not available here. asyncClient = AsyncSDK.client(); asyncManager = AsyncSDK.manager(); // Browser client for attributes binding browserClient = BrowserSDK.client(); browserClient = BrowserSDK.client('a customer key'); +browserClient = BrowserSDK.client('a customer key', 'a traffic type'); // Logger SDK.Logger.enable(); @@ -240,10 +239,11 @@ const b: number = client.listenerCount(splitEvent); let nodeEventEmitter: NodeJS.EventEmitter = client; // Ready, destroy and flush -const readyPromise: Promise = client.ready(); -const destroyPromise: Promise = client.destroy(); -// @ts-ignore -const flushPromise: Promise = client.flush(); +let promise: Promise = client.ready(); +promise = client.destroy(); +promise = SDK.destroy(); +// @TODO not public yet +// promise = client.flush(); // We can call getTreatment with or without a key. treatment = client.getTreatment(splitKey, 'mySplit'); @@ -332,10 +332,11 @@ const b1: number = asyncClient.listenerCount(splitEvent); nodeEventEmitter = asyncClient; // Ready, destroy and flush (same as for sync client, just for interface checking) -const readyPromise1: Promise = asyncClient.ready(); -asyncClient.destroy(); -// @ts-ignore -asyncClient.flush(); +promise = asyncClient.ready(); +promise = asyncClient.destroy(); +promise = AsyncSDK.destroy(); +// @TODO not public yet +// promise = asyncClient.flush(); // We can call getTreatment but always with a key. asyncTreatment = asyncClient.getTreatment(splitKey, 'mySplit'); @@ -391,7 +392,7 @@ splitView = manager.split('mySplit'); splitViews = manager.splits(); // Manager implements ready promise. -const managerReadyPromise: Promise = manager.ready(); +promise = manager.ready(); // Manager implements methods from NodeJS.Events. Testing a few. manager = manager.on(splitEvent, () => { }); @@ -415,7 +416,7 @@ splitViewAsync = asyncManager.split('mySplit'); splitViewsAsync = asyncManager.splits(); // asyncManager implements ready promise. -const asyncManagerReadyPromise: Promise = asyncManager.ready(); +promise = asyncManager.ready(); // asyncManager implements methods from NodeJS.Events. Testing a few. asyncManager = asyncManager.on(splitEvent, () => { }); diff --git a/types/splitio.d.ts b/types/splitio.d.ts index bb88476bc..6edbb7cd6 100644 --- a/types/splitio.d.ts +++ b/types/splitio.d.ts @@ -491,6 +491,12 @@ interface IBasicSDK { * @property Logger */ Logger: ILoggerAPI + /** + * Destroys all the clients created by this factory. + * @function destroy + * @returns {Promise} + */ + destroy(): Promise } /****** Exposed namespace ******/ /** @@ -1374,14 +1380,6 @@ declare namespace SplitIO { * @returns {IClient} The client instance. */ client(): IClient, - /** - * Returns a shared client of the SDK. For usage on the browser. - * @function client - * @param {SplitKey} key The key for the new client instance. - * @param {string=} trafficType The traffic type of the provided key. - * @returns {IClient} The client instance. - */ - client(key: SplitKey, trafficType?: string): IClient, /** * Returns a manager instance of the SDK to explore available information. * @function manager @@ -1392,9 +1390,9 @@ declare namespace SplitIO { /** * This represents the interface for the SDK instance with synchronous storage. * @interface IBrowserSDK - * @extends ISDK + * @extends IBasicSDK */ - interface IBrowserSDK extends ISDK { + interface IBrowserSDK extends IBasicSDK { /** * Returns the default client instance of the SDK. * @function client @@ -1402,13 +1400,19 @@ declare namespace SplitIO { */ client(): IBrowserClient, /** - * Returns a shared client of the SDK. For usage on the browser. + * Returns a shared client of the SDK. * @function client * @param {SplitKey} key The key for the new client instance. * @param {string=} trafficType The traffic type of the provided key. * @returns {IBrowserClient} The client instance. */ client(key: SplitKey, trafficType?: string): IBrowserClient + /** + * Returns a manager instance of the SDK to explore available information. + * @function manager + * @returns {IManager} The manager instance. + */ + manager(): IManager, /** * User consent API. * @property UserConsent