diff --git a/.eslintrc.js b/.eslintrc.js index 4a0af77b6..5e73909ae 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,14 +1,20 @@ module.exports = { env: { node: true, + 'jest/globals': true, }, extends: ['airbnb-base', 'airbnb-typescript/base', 'prettier'], parser: '@typescript-eslint/parser', parserOptions: { project: './tsconfig.eslint.json', }, - plugins: ['@typescript-eslint', 'prettier'], - ignorePatterns: ['**/dist/**', '**/vercel/examples/**'], + plugins: ['@typescript-eslint', 'prettier', 'jest'], + ignorePatterns: [ + '**/dist/**', + '**/vercel/examples/**', + '**/react-native/example/**', + '**/fromExternal/**', + ], rules: { '@typescript-eslint/lines-between-class-members': 'off', '@typescript-eslint/no-unused-vars': [ @@ -20,7 +26,12 @@ module.exports = { 'import/no-extraneous-dependencies': [ 'error', { - devDependencies: ['**/jest*.ts', '**/*.test.ts', '**/rollup.config.ts'], + devDependencies: [ + '**/jest*.ts', + '**/*.test.ts', + '**/rollup.config.ts', + '**/*{.,_}{test,spec}.{ts,tsx}', + ], }, ], 'import/default': 'error', @@ -30,5 +41,13 @@ module.exports = { 'import/no-cycle': 'error', 'import/no-useless-path-segments': 'error', 'import/no-duplicates': 'error', + 'jest/no-disabled-tests': 'warn', + 'jest/no-focused-tests': 'error', + 'jest/no-identical-title': 'error', + // 'jest/prefer-to-have-length': 'warn', + 'jest/valid-expect': 'error', + }, + globals: { + BigInt: 'readonly', }, }; diff --git a/package.json b/package.json index 1538409bc..e56b47fb6 100644 --- a/package.json +++ b/package.json @@ -37,13 +37,14 @@ }, "devDependencies": { "@trivago/prettier-plugin-sort-imports": "^4.1.1", - "@typescript-eslint/eslint-plugin": "^6.1.0", - "@typescript-eslint/parser": "^6.1.0", - "eslint": "^8.45.0", + "@typescript-eslint/eslint-plugin": "^6.20.0", + "@typescript-eslint/parser": "^6.20.0", + "eslint": "^8.56.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^17.1.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jest": "^27.6.3", "eslint-plugin-prettier": "^5.0.0", "prettier": "^3.0.0", "typedoc": "0.25.0", diff --git a/packages/sdk/akamai-base/package.json b/packages/sdk/akamai-base/package.json index 0bcf01a3a..6ad56bea0 100644 --- a/packages/sdk/akamai-base/package.json +++ b/packages/sdk/akamai-base/package.json @@ -53,13 +53,14 @@ "@trivago/prettier-plugin-sort-imports": "^4.1.1", "@types/crypto-js": "^4.1.1", "@types/jest": "^29.5.1", - "@typescript-eslint/eslint-plugin": "^6.1.0", - "@typescript-eslint/parser": "^6.1.0", + "@typescript-eslint/eslint-plugin": "^6.20.0", + "@typescript-eslint/parser": "^6.20.0", "eslint": "^8.45.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^17.1.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jest": "^27.6.3", "eslint-plugin-prettier": "^5.0.0", "jest": "^29.5.0", "launchdarkly-js-test-helpers": "^2.2.0", diff --git a/packages/sdk/akamai-edgekv/package.json b/packages/sdk/akamai-edgekv/package.json index 6ecce0bb9..45b50539a 100644 --- a/packages/sdk/akamai-edgekv/package.json +++ b/packages/sdk/akamai-edgekv/package.json @@ -53,13 +53,14 @@ "@trivago/prettier-plugin-sort-imports": "^4.1.1", "@types/crypto-js": "^4.1.1", "@types/jest": "^29.5.1", - "@typescript-eslint/eslint-plugin": "^6.1.0", - "@typescript-eslint/parser": "^6.1.0", + "@typescript-eslint/eslint-plugin": "^6.20.0", + "@typescript-eslint/parser": "^6.20.0", "eslint": "^8.45.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^17.1.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jest": "^27.6.3", "eslint-plugin-prettier": "^5.0.0", "jest": "^29.5.0", "launchdarkly-js-test-helpers": "^2.2.0", diff --git a/packages/sdk/cloudflare/package.json b/packages/sdk/cloudflare/package.json index 17c7afd00..2c65a2a9b 100644 --- a/packages/sdk/cloudflare/package.json +++ b/packages/sdk/cloudflare/package.json @@ -54,13 +54,14 @@ "@types/crypto-js": "^4.1.1", "@types/jest": "^29.5.0", "@types/rollup-plugin-generate-package-json": "^3.2.3", - "@typescript-eslint/eslint-plugin": "^6.1.0", - "@typescript-eslint/parser": "^6.1.0", + "@typescript-eslint/eslint-plugin": "^6.20.0", + "@typescript-eslint/parser": "^6.20.0", "eslint": "^8.45.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^17.1.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jest": "^27.6.3", "eslint-plugin-prettier": "^5.0.0", "jest": "^29.5.0", "launchdarkly-js-test-helpers": "^2.2.0", diff --git a/packages/sdk/react-native/README.md b/packages/sdk/react-native/README.md index cff58ab1b..ce43eecb1 100644 --- a/packages/sdk/react-native/README.md +++ b/packages/sdk/react-native/README.md @@ -42,7 +42,7 @@ and re-run pod install for [auto-linking to work](https://github.com/react-nativ // App.tsx import { LDProvider, ReactNativeLDClient } from '@launchdarkly/react-native-client-sdk'; -const featureClient = new ReactNativeLDClient('mobile-key'); +const featureClient = new ReactNativeLDClient('mobile-key', AutoEnvAttributes.Enabled); const userContext = { kind: 'user', key: 'test-user-1' }; const App = () => ( @@ -100,7 +100,7 @@ yarn && yarn ios-go ## Verifying SDK build provenance with the SLSA framework -LaunchDarkly uses the [SLSA framework](https://slsa.dev/spec/v1.0/about) (Supply-chain Levels for Software Artifacts) to help developers make their supply chain more secure by ensuring the authenticity and build integrity of our published SDK packages. To learn more, see the [provenance guide](PROVENANCE.md). +LaunchDarkly uses the [SLSA framework](https://slsa.dev/spec/v1.0/about) (Supply-chain Levels for Software Artifacts) to help developers make their supply chain more secure by ensuring the authenticity and build integrity of our published SDK packages. To learn more, see the [provenance guide](PROVENANCE.md). ## About LaunchDarkly diff --git a/packages/sdk/react-native/babel.config.js b/packages/sdk/react-native/babel.config.js new file mode 100644 index 000000000..f842b77fc --- /dev/null +++ b/packages/sdk/react-native/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: ['module:metro-react-native-babel-preset'], +}; diff --git a/packages/sdk/react-native/example/App.tsx b/packages/sdk/react-native/example/App.tsx index 0855d46a7..5445bca48 100644 --- a/packages/sdk/react-native/example/App.tsx +++ b/packages/sdk/react-native/example/App.tsx @@ -1,10 +1,14 @@ import { MOBILE_KEY } from '@env'; -import { LDProvider, ReactNativeLDClient } from '@launchdarkly/react-native-client-sdk'; +import { + AutoEnvAttributes, + LDProvider, + ReactNativeLDClient, +} from '@launchdarkly/react-native-client-sdk'; import Welcome from './src/welcome'; -const featureClient = new ReactNativeLDClient(MOBILE_KEY); +const featureClient = new ReactNativeLDClient(MOBILE_KEY, AutoEnvAttributes.Enabled); const App = () => { return ( diff --git a/packages/sdk/react-native/example/package.json b/packages/sdk/react-native/example/package.json index df53d7ba1..5e6af48c4 100644 --- a/packages/sdk/react-native/example/package.json +++ b/packages/sdk/react-native/example/package.json @@ -27,7 +27,8 @@ "expo-splash-screen": "~0.20.5", "expo-status-bar": "~1.7.1", "react": "18.2.0", - "react-native": "0.72.6" + "react-native": "0.72.6", + "react-native-dotenv": "^3.4.9" }, "devDependencies": { "@babel/core": "^7.20.0", @@ -37,7 +38,7 @@ "@types/react": "~18.2.14", "@types/react-native-dotenv": "^0.2.1", "detox": "^20.14.7", - "react-native-dotenv": "^3.4.9", + "jest": "^29.7.0", "ts-jest": "^29.1.1", "typescript": "^5.2.2" } diff --git a/packages/sdk/react-native/example/tsconfig.json b/packages/sdk/react-native/example/tsconfig.json index a62623004..28d5470b2 100644 --- a/packages/sdk/react-native/example/tsconfig.json +++ b/packages/sdk/react-native/example/tsconfig.json @@ -1,8 +1,9 @@ { "extends": "expo/tsconfig.base", "compilerOptions": { + "jsx": "react", "strict": true, - "typeRoots": ["./types"] + "typeRoots": ["./types"], }, - "exclude": ["e2e"] + "exclude": ["e2e"], } diff --git a/packages/sdk/react-native/example/yarn.lock b/packages/sdk/react-native/example/yarn.lock index caafa8c67..80c8d4a39 100644 --- a/packages/sdk/react-native/example/yarn.lock +++ b/packages/sdk/react-native/example/yarn.lock @@ -46,6 +46,16 @@ __metadata: languageName: node linkType: hard +"@babel/code-frame@npm:^7.23.5": + version: 7.23.5 + resolution: "@babel/code-frame@npm:7.23.5" + dependencies: + "@babel/highlight": ^7.23.4 + chalk: ^2.4.2 + checksum: d90981fdf56a2824a9b14d19a4c0e8db93633fd488c772624b4e83e0ceac6039a27cd298a247c3214faa952bf803ba23696172ae7e7235f3b97f43ba278c569a + languageName: node + linkType: hard + "@babel/compat-data@npm:^7.20.5, @babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.22.9, @babel/compat-data@npm:^7.23.3": version: 7.23.3 resolution: "@babel/compat-data@npm:7.23.3" @@ -53,6 +63,36 @@ __metadata: languageName: node linkType: hard +"@babel/compat-data@npm:^7.23.5": + version: 7.23.5 + resolution: "@babel/compat-data@npm:7.23.5" + checksum: 06ce244cda5763295a0ea924728c09bae57d35713b675175227278896946f922a63edf803c322f855a3878323d48d0255a2a3023409d2a123483c8a69ebb4744 + languageName: node + linkType: hard + +"@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3": + version: 7.23.7 + resolution: "@babel/core@npm:7.23.7" + dependencies: + "@ampproject/remapping": ^2.2.0 + "@babel/code-frame": ^7.23.5 + "@babel/generator": ^7.23.6 + "@babel/helper-compilation-targets": ^7.23.6 + "@babel/helper-module-transforms": ^7.23.3 + "@babel/helpers": ^7.23.7 + "@babel/parser": ^7.23.6 + "@babel/template": ^7.22.15 + "@babel/traverse": ^7.23.7 + "@babel/types": ^7.23.6 + convert-source-map: ^2.0.0 + debug: ^4.1.0 + gensync: ^1.0.0-beta.2 + json5: ^2.2.3 + semver: ^6.3.1 + checksum: 32d5bf73372a47429afaae9adb0af39e47bcea6a831c4b5dcbb4791380cda6949cb8cb1a2fea8b60bb1ebe189209c80e333903df1fa8e9dcb04798c0ce5bf59e + languageName: node + linkType: hard + "@babel/core@npm:^7.13.16, @babel/core@npm:^7.20.0": version: 7.23.3 resolution: "@babel/core@npm:7.23.3" @@ -88,6 +128,18 @@ __metadata: languageName: node linkType: hard +"@babel/generator@npm:^7.23.6, @babel/generator@npm:^7.7.2": + version: 7.23.6 + resolution: "@babel/generator@npm:7.23.6" + dependencies: + "@babel/types": ^7.23.6 + "@jridgewell/gen-mapping": ^0.3.2 + "@jridgewell/trace-mapping": ^0.3.17 + jsesc: ^2.5.1 + checksum: 1a1a1c4eac210f174cd108d479464d053930a812798e09fee069377de39a893422df5b5b146199ead7239ae6d3a04697b45fc9ac6e38e0f6b76374390f91fc6c + languageName: node + linkType: hard + "@babel/helper-annotate-as-pure@npm:^7.22.5": version: 7.22.5 resolution: "@babel/helper-annotate-as-pure@npm:7.22.5" @@ -119,6 +171,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-compilation-targets@npm:^7.23.6": + version: 7.23.6 + resolution: "@babel/helper-compilation-targets@npm:7.23.6" + dependencies: + "@babel/compat-data": ^7.23.5 + "@babel/helper-validator-option": ^7.23.5 + browserslist: ^4.22.2 + lru-cache: ^5.1.1 + semver: ^6.3.1 + checksum: c630b98d4527ac8fe2c58d9a06e785dfb2b73ec71b7c4f2ddf90f814b5f75b547f3c015f110a010fd31f76e3864daaf09f3adcd2f6acdbfb18a8de3a48717590 + languageName: node + linkType: hard + "@babel/helper-create-class-features-plugin@npm:^7.18.6, @babel/helper-create-class-features-plugin@npm:^7.22.15": version: 7.22.15 resolution: "@babel/helper-create-class-features-plugin@npm:7.22.15" @@ -315,6 +380,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-option@npm:^7.23.5": + version: 7.23.5 + resolution: "@babel/helper-validator-option@npm:7.23.5" + checksum: 537cde2330a8aede223552510e8a13e9c1c8798afee3757995a7d4acae564124fe2bf7e7c3d90d62d3657434a74340a274b3b3b1c6f17e9a2be1f48af29cb09e + languageName: node + linkType: hard + "@babel/helper-wrap-function@npm:^7.22.20": version: 7.22.20 resolution: "@babel/helper-wrap-function@npm:7.22.20" @@ -337,6 +409,17 @@ __metadata: languageName: node linkType: hard +"@babel/helpers@npm:^7.23.7": + version: 7.23.8 + resolution: "@babel/helpers@npm:7.23.8" + dependencies: + "@babel/template": ^7.22.15 + "@babel/traverse": ^7.23.7 + "@babel/types": ^7.23.6 + checksum: 8b522d527921f8df45a983dc7b8e790c021250addf81ba7900ba016e165442a527348f6f877aa55e1debb3eef9e860a334b4e8d834e6c9b438ed61a63d9a7ad4 + languageName: node + linkType: hard + "@babel/highlight@npm:^7.10.4, @babel/highlight@npm:^7.23.4": version: 7.23.4 resolution: "@babel/highlight@npm:7.23.4" @@ -348,6 +431,15 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.6": + version: 7.23.6 + resolution: "@babel/parser@npm:7.23.6" + bin: + parser: ./bin/babel-parser.js + checksum: 140801c43731a6c41fd193f5c02bc71fd647a0360ca616b23d2db8be4b9739b9f951a03fc7c2db4f9b9214f4b27c1074db0f18bc3fa653783082d5af7c8860d5 + languageName: node + linkType: hard + "@babel/parser@npm:^7.13.16, @babel/parser@npm:^7.20.0, @babel/parser@npm:^7.22.15, @babel/parser@npm:^7.23.3, @babel/parser@npm:^7.23.4": version: 7.23.4 resolution: "@babel/parser@npm:7.23.4" @@ -542,7 +634,18 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-class-properties@npm:^7.0.0, @babel/plugin-syntax-class-properties@npm:^7.12.13": +"@babel/plugin-syntax-bigint@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-bigint@npm:7.8.3" + dependencies: + "@babel/helper-plugin-utils": ^7.8.0 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 3a10849d83e47aec50f367a9e56a6b22d662ddce643334b087f9828f4c3dd73bdc5909aaeabe123fed78515767f9ca43498a0e621c438d1cd2802d7fae3c9648 + languageName: node + linkType: hard + +"@babel/plugin-syntax-class-properties@npm:^7.0.0, @babel/plugin-syntax-class-properties@npm:^7.12.13, @babel/plugin-syntax-class-properties@npm:^7.8.3": version: 7.12.13 resolution: "@babel/plugin-syntax-class-properties@npm:7.12.13" dependencies: @@ -641,7 +744,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-import-meta@npm:^7.10.4": +"@babel/plugin-syntax-import-meta@npm:^7.10.4, @babel/plugin-syntax-import-meta@npm:^7.8.3": version: 7.10.4 resolution: "@babel/plugin-syntax-import-meta@npm:7.10.4" dependencies: @@ -663,7 +766,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-jsx@npm:^7.0.0, @babel/plugin-syntax-jsx@npm:^7.23.3": +"@babel/plugin-syntax-jsx@npm:^7.0.0, @babel/plugin-syntax-jsx@npm:^7.23.3, @babel/plugin-syntax-jsx@npm:^7.7.2": version: 7.23.3 resolution: "@babel/plugin-syntax-jsx@npm:7.23.3" dependencies: @@ -674,7 +777,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4": +"@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4, @babel/plugin-syntax-logical-assignment-operators@npm:^7.8.3": version: 7.10.4 resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4" dependencies: @@ -696,7 +799,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-numeric-separator@npm:^7.10.4": +"@babel/plugin-syntax-numeric-separator@npm:^7.10.4, @babel/plugin-syntax-numeric-separator@npm:^7.8.3": version: 7.10.4 resolution: "@babel/plugin-syntax-numeric-separator@npm:7.10.4" dependencies: @@ -751,7 +854,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-top-level-await@npm:^7.14.5": +"@babel/plugin-syntax-top-level-await@npm:^7.14.5, @babel/plugin-syntax-top-level-await@npm:^7.8.3": version: 7.14.5 resolution: "@babel/plugin-syntax-top-level-await@npm:7.14.5" dependencies: @@ -762,7 +865,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-typescript@npm:^7.23.3": +"@babel/plugin-syntax-typescript@npm:^7.23.3, @babel/plugin-syntax-typescript@npm:^7.7.2": version: 7.23.3 resolution: "@babel/plugin-syntax-typescript@npm:7.23.3" dependencies: @@ -1617,7 +1720,7 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.0.0, @babel/template@npm:^7.22.15": +"@babel/template@npm:^7.0.0, @babel/template@npm:^7.22.15, @babel/template@npm:^7.3.3": version: 7.22.15 resolution: "@babel/template@npm:7.22.15" dependencies: @@ -1646,6 +1749,35 @@ __metadata: languageName: node linkType: hard +"@babel/traverse@npm:^7.23.7": + version: 7.23.7 + resolution: "@babel/traverse@npm:7.23.7" + dependencies: + "@babel/code-frame": ^7.23.5 + "@babel/generator": ^7.23.6 + "@babel/helper-environment-visitor": ^7.22.20 + "@babel/helper-function-name": ^7.23.0 + "@babel/helper-hoist-variables": ^7.22.5 + "@babel/helper-split-export-declaration": ^7.22.6 + "@babel/parser": ^7.23.6 + "@babel/types": ^7.23.6 + debug: ^4.3.1 + globals: ^11.1.0 + checksum: d4a7afb922361f710efc97b1e25ec343fab8b2a4ddc81ca84f9a153f22d4482112cba8f263774be8d297918b6c4767c7a98988ab4e53ac73686c986711dd002e + languageName: node + linkType: hard + +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.23.6, @babel/types@npm:^7.3.3": + version: 7.23.6 + resolution: "@babel/types@npm:7.23.6" + dependencies: + "@babel/helper-string-parser": ^7.23.4 + "@babel/helper-validator-identifier": ^7.22.20 + to-fast-properties: ^2.0.0 + checksum: 68187dbec0d637f79bc96263ac95ec8b06d424396678e7e225492be866414ce28ebc918a75354d4c28659be6efe30020b4f0f6df81cc418a2d30645b690a8de0 + languageName: node + linkType: hard + "@babel/types@npm:^7.20.0, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.19, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.3, @babel/types@npm:^7.23.4, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": version: 7.23.4 resolution: "@babel/types@npm:7.23.4" @@ -1657,6 +1789,13 @@ __metadata: languageName: node linkType: hard +"@bcoe/v8-coverage@npm:^0.2.3": + version: 0.2.3 + resolution: "@bcoe/v8-coverage@npm:0.2.3" + checksum: 850f9305536d0f2bd13e9e0881cb5f02e4f93fad1189f7b2d4bebf694e3206924eadee1068130d43c11b750efcc9405f88a8e42ef098b6d75239c0f047de1a27 + languageName: node + linkType: hard + "@expo/bunyan@npm:4.0.0, @expo/bunyan@npm:^4.0.0": version: 4.0.0 resolution: "@expo/bunyan@npm:4.0.0" @@ -2085,6 +2224,81 @@ __metadata: languageName: node linkType: hard +"@istanbuljs/load-nyc-config@npm:^1.0.0": + version: 1.1.0 + resolution: "@istanbuljs/load-nyc-config@npm:1.1.0" + dependencies: + camelcase: ^5.3.1 + find-up: ^4.1.0 + get-package-type: ^0.1.0 + js-yaml: ^3.13.1 + resolve-from: ^5.0.0 + checksum: d578da5e2e804d5c93228450a1380e1a3c691de4953acc162f387b717258512a3e07b83510a936d9fab03eac90817473917e24f5d16297af3867f59328d58568 + languageName: node + linkType: hard + +"@istanbuljs/schema@npm:^0.1.2": + version: 0.1.3 + resolution: "@istanbuljs/schema@npm:0.1.3" + checksum: 5282759d961d61350f33d9118d16bcaed914ebf8061a52f4fa474b2cb08720c9c81d165e13b82f2e5a8a212cc5af482f0c6fc1ac27b9e067e5394c9a6ed186c9 + languageName: node + linkType: hard + +"@jest/console@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/console@npm:29.7.0" + dependencies: + "@jest/types": ^29.6.3 + "@types/node": "*" + chalk: ^4.0.0 + jest-message-util: ^29.7.0 + jest-util: ^29.7.0 + slash: ^3.0.0 + checksum: 0e3624e32c5a8e7361e889db70b170876401b7d70f509a2538c31d5cd50deb0c1ae4b92dc63fe18a0902e0a48c590c21d53787a0df41a52b34fa7cab96c384d6 + languageName: node + linkType: hard + +"@jest/core@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/core@npm:29.7.0" + dependencies: + "@jest/console": ^29.7.0 + "@jest/reporters": ^29.7.0 + "@jest/test-result": ^29.7.0 + "@jest/transform": ^29.7.0 + "@jest/types": ^29.6.3 + "@types/node": "*" + ansi-escapes: ^4.2.1 + chalk: ^4.0.0 + ci-info: ^3.2.0 + exit: ^0.1.2 + graceful-fs: ^4.2.9 + jest-changed-files: ^29.7.0 + jest-config: ^29.7.0 + jest-haste-map: ^29.7.0 + jest-message-util: ^29.7.0 + jest-regex-util: ^29.6.3 + jest-resolve: ^29.7.0 + jest-resolve-dependencies: ^29.7.0 + jest-runner: ^29.7.0 + jest-runtime: ^29.7.0 + jest-snapshot: ^29.7.0 + jest-util: ^29.7.0 + jest-validate: ^29.7.0 + jest-watcher: ^29.7.0 + micromatch: ^4.0.4 + pretty-format: ^29.7.0 + slash: ^3.0.0 + strip-ansi: ^6.0.0 + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + checksum: af759c9781cfc914553320446ce4e47775ae42779e73621c438feb1e4231a5d4862f84b1d8565926f2d1aab29b3ec3dcfdc84db28608bdf5f29867124ebcfc0d + languageName: node + linkType: hard + "@jest/create-cache-key-function@npm:^29.2.1": version: 29.7.0 resolution: "@jest/create-cache-key-function@npm:29.7.0" @@ -2115,6 +2329,16 @@ __metadata: languageName: node linkType: hard +"@jest/expect@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/expect@npm:29.7.0" + dependencies: + expect: ^29.7.0 + jest-snapshot: ^29.7.0 + checksum: a01cb85fd9401bab3370618f4b9013b90c93536562222d920e702a0b575d239d74cecfe98010aaec7ad464f67cf534a353d92d181646a4b792acaa7e912ae55e + languageName: node + linkType: hard + "@jest/fake-timers@npm:^29.7.0": version: 29.7.0 resolution: "@jest/fake-timers@npm:29.7.0" @@ -2129,6 +2353,55 @@ __metadata: languageName: node linkType: hard +"@jest/globals@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/globals@npm:29.7.0" + dependencies: + "@jest/environment": ^29.7.0 + "@jest/expect": ^29.7.0 + "@jest/types": ^29.6.3 + jest-mock: ^29.7.0 + checksum: 97dbb9459135693ad3a422e65ca1c250f03d82b2a77f6207e7fa0edd2c9d2015fbe4346f3dc9ebff1678b9d8da74754d4d440b7837497f8927059c0642a22123 + languageName: node + linkType: hard + +"@jest/reporters@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/reporters@npm:29.7.0" + dependencies: + "@bcoe/v8-coverage": ^0.2.3 + "@jest/console": ^29.7.0 + "@jest/test-result": ^29.7.0 + "@jest/transform": ^29.7.0 + "@jest/types": ^29.6.3 + "@jridgewell/trace-mapping": ^0.3.18 + "@types/node": "*" + chalk: ^4.0.0 + collect-v8-coverage: ^1.0.0 + exit: ^0.1.2 + glob: ^7.1.3 + graceful-fs: ^4.2.9 + istanbul-lib-coverage: ^3.0.0 + istanbul-lib-instrument: ^6.0.0 + istanbul-lib-report: ^3.0.0 + istanbul-lib-source-maps: ^4.0.0 + istanbul-reports: ^3.1.3 + jest-message-util: ^29.7.0 + jest-util: ^29.7.0 + jest-worker: ^29.7.0 + slash: ^3.0.0 + string-length: ^4.0.1 + strip-ansi: ^6.0.0 + v8-to-istanbul: ^9.0.1 + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + checksum: 7eadabd62cc344f629024b8a268ecc8367dba756152b761bdcb7b7e570a3864fc51b2a9810cd310d85e0a0173ef002ba4528d5ea0329fbf66ee2a3ada9c40455 + languageName: node + linkType: hard + "@jest/schemas@npm:^29.6.3": version: 29.6.3 resolution: "@jest/schemas@npm:29.6.3" @@ -2138,6 +2411,64 @@ __metadata: languageName: node linkType: hard +"@jest/source-map@npm:^29.6.3": + version: 29.6.3 + resolution: "@jest/source-map@npm:29.6.3" + dependencies: + "@jridgewell/trace-mapping": ^0.3.18 + callsites: ^3.0.0 + graceful-fs: ^4.2.9 + checksum: bcc5a8697d471396c0003b0bfa09722c3cd879ad697eb9c431e6164e2ea7008238a01a07193dfe3cbb48b1d258eb7251f6efcea36f64e1ebc464ea3c03ae2deb + languageName: node + linkType: hard + +"@jest/test-result@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/test-result@npm:29.7.0" + dependencies: + "@jest/console": ^29.7.0 + "@jest/types": ^29.6.3 + "@types/istanbul-lib-coverage": ^2.0.0 + collect-v8-coverage: ^1.0.0 + checksum: 67b6317d526e335212e5da0e768e3b8ab8a53df110361b80761353ad23b6aea4432b7c5665bdeb87658ea373b90fb1afe02ed3611ef6c858c7fba377505057fa + languageName: node + linkType: hard + +"@jest/test-sequencer@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/test-sequencer@npm:29.7.0" + dependencies: + "@jest/test-result": ^29.7.0 + graceful-fs: ^4.2.9 + jest-haste-map: ^29.7.0 + slash: ^3.0.0 + checksum: 73f43599017946be85c0b6357993b038f875b796e2f0950487a82f4ebcb115fa12131932dd9904026b4ad8be131fe6e28bd8d0aa93b1563705185f9804bff8bd + languageName: node + linkType: hard + +"@jest/transform@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/transform@npm:29.7.0" + dependencies: + "@babel/core": ^7.11.6 + "@jest/types": ^29.6.3 + "@jridgewell/trace-mapping": ^0.3.18 + babel-plugin-istanbul: ^6.1.1 + chalk: ^4.0.0 + convert-source-map: ^2.0.0 + fast-json-stable-stringify: ^2.1.0 + graceful-fs: ^4.2.9 + jest-haste-map: ^29.7.0 + jest-regex-util: ^29.6.3 + jest-util: ^29.7.0 + micromatch: ^4.0.4 + pirates: ^4.0.4 + slash: ^3.0.0 + write-file-atomic: ^4.0.2 + checksum: 0f8ac9f413903b3cb6d240102db848f2a354f63971ab885833799a9964999dd51c388162106a807f810071f864302cdd8e3f0c241c29ce02d85a36f18f3f40ab + languageName: node + linkType: hard + "@jest/types@npm:^26.6.2": version: 26.6.2 resolution: "@jest/types@npm:26.6.2" @@ -2220,6 +2551,16 @@ __metadata: languageName: node linkType: hard +"@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.18": + version: 0.3.22 + resolution: "@jridgewell/trace-mapping@npm:0.3.22" + dependencies: + "@jridgewell/resolve-uri": ^3.1.0 + "@jridgewell/sourcemap-codec": ^1.4.14 + checksum: ac7dd2cfe0b479aa1b81776d40d789243131cc792dc8b6b6a028c70fcd6171958ae1a71bf67b618ffe3c0c3feead9870c095ee46a5e30319410d92976b28f498 + languageName: node + linkType: hard + "@jridgewell/trace-mapping@npm:^0.3.17, @jridgewell/trace-mapping@npm:^0.3.9": version: 0.3.20 resolution: "@jridgewell/trace-mapping@npm:0.3.20" @@ -2633,6 +2974,47 @@ __metadata: languageName: node linkType: hard +"@types/babel__core@npm:^7.1.14": + version: 7.20.5 + resolution: "@types/babel__core@npm:7.20.5" + dependencies: + "@babel/parser": ^7.20.7 + "@babel/types": ^7.20.7 + "@types/babel__generator": "*" + "@types/babel__template": "*" + "@types/babel__traverse": "*" + checksum: a3226f7930b635ee7a5e72c8d51a357e799d19cbf9d445710fa39ab13804f79ab1a54b72ea7d8e504659c7dfc50675db974b526142c754398d7413aa4bc30845 + languageName: node + linkType: hard + +"@types/babel__generator@npm:*": + version: 7.6.8 + resolution: "@types/babel__generator@npm:7.6.8" + dependencies: + "@babel/types": ^7.0.0 + checksum: 5b332ea336a2efffbdeedb92b6781949b73498606ddd4205462f7d96dafd45ff3618770b41de04c4881e333dd84388bfb8afbdf6f2764cbd98be550d85c6bb48 + languageName: node + linkType: hard + +"@types/babel__template@npm:*": + version: 7.4.4 + resolution: "@types/babel__template@npm:7.4.4" + dependencies: + "@babel/parser": ^7.1.0 + "@babel/types": ^7.0.0 + checksum: d7a02d2a9b67e822694d8e6a7ddb8f2b71a1d6962dfd266554d2513eefbb205b33ca71a0d163b1caea3981ccf849211f9964d8bd0727124d18ace45aa6c9ae29 + languageName: node + linkType: hard + +"@types/babel__traverse@npm:*, @types/babel__traverse@npm:^7.0.6": + version: 7.20.5 + resolution: "@types/babel__traverse@npm:7.20.5" + dependencies: + "@babel/types": ^7.20.7 + checksum: 608e0ab4fc31cd47011d98942e6241b34d461608c0c0e153377c5fd822c436c475f1ded76a56bfa76a1adf8d9266b727bbf9bfac90c4cb152c97f30dadc5b7e8 + languageName: node + linkType: hard + "@types/detox@npm:^18.1.0": version: 18.1.0 resolution: "@types/detox@npm:18.1.0" @@ -2642,7 +3024,16 @@ __metadata: languageName: node linkType: hard -"@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.0": +"@types/graceful-fs@npm:^4.1.3": + version: 4.1.9 + resolution: "@types/graceful-fs@npm:4.1.9" + dependencies: + "@types/node": "*" + checksum: 79d746a8f053954bba36bd3d94a90c78de995d126289d656fb3271dd9f1229d33f678da04d10bce6be440494a5a73438e2e363e92802d16b8315b051036c5256 + languageName: node + linkType: hard + +"@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.0, @types/istanbul-lib-coverage@npm:^2.0.1": version: 2.0.6 resolution: "@types/istanbul-lib-coverage@npm:2.0.6" checksum: 3feac423fd3e5449485afac999dcfcb3d44a37c830af898b689fadc65d26526460bedb889db278e0d4d815a670331796494d073a10ee6e3a6526301fe7415778 @@ -3092,6 +3483,48 @@ __metadata: languageName: node linkType: hard +"babel-jest@npm:^29.7.0": + version: 29.7.0 + resolution: "babel-jest@npm:29.7.0" + dependencies: + "@jest/transform": ^29.7.0 + "@types/babel__core": ^7.1.14 + babel-plugin-istanbul: ^6.1.1 + babel-preset-jest: ^29.6.3 + chalk: ^4.0.0 + graceful-fs: ^4.2.9 + slash: ^3.0.0 + peerDependencies: + "@babel/core": ^7.8.0 + checksum: ee6f8e0495afee07cac5e4ee167be705c711a8cc8a737e05a587a131fdae2b3c8f9aa55dfd4d9c03009ac2d27f2de63d8ba96d3e8460da4d00e8af19ef9a83f7 + languageName: node + linkType: hard + +"babel-plugin-istanbul@npm:^6.1.1": + version: 6.1.1 + resolution: "babel-plugin-istanbul@npm:6.1.1" + dependencies: + "@babel/helper-plugin-utils": ^7.0.0 + "@istanbuljs/load-nyc-config": ^1.0.0 + "@istanbuljs/schema": ^0.1.2 + istanbul-lib-instrument: ^5.0.4 + test-exclude: ^6.0.0 + checksum: cb4fd95738219f232f0aece1116628cccff16db891713c4ccb501cddbbf9272951a5df81f2f2658dfdf4b3e7b236a9d5cbcf04d5d8c07dd5077297339598061a + languageName: node + linkType: hard + +"babel-plugin-jest-hoist@npm:^29.6.3": + version: 29.6.3 + resolution: "babel-plugin-jest-hoist@npm:29.6.3" + dependencies: + "@babel/template": ^7.3.3 + "@babel/types": ^7.3.3 + "@types/babel__core": ^7.1.14 + "@types/babel__traverse": ^7.0.6 + checksum: 51250f22815a7318f17214a9d44650ba89551e6d4f47a2dc259128428324b52f5a73979d010cefd921fd5a720d8c1d55ad74ff601cd94c7bd44d5f6292fde2d1 + languageName: node + linkType: hard + "babel-plugin-module-resolver@npm:^5.0.0": version: 5.0.0 resolution: "babel-plugin-module-resolver@npm:5.0.0" @@ -3164,6 +3597,28 @@ __metadata: languageName: node linkType: hard +"babel-preset-current-node-syntax@npm:^1.0.0": + version: 1.0.1 + resolution: "babel-preset-current-node-syntax@npm:1.0.1" + dependencies: + "@babel/plugin-syntax-async-generators": ^7.8.4 + "@babel/plugin-syntax-bigint": ^7.8.3 + "@babel/plugin-syntax-class-properties": ^7.8.3 + "@babel/plugin-syntax-import-meta": ^7.8.3 + "@babel/plugin-syntax-json-strings": ^7.8.3 + "@babel/plugin-syntax-logical-assignment-operators": ^7.8.3 + "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.3 + "@babel/plugin-syntax-numeric-separator": ^7.8.3 + "@babel/plugin-syntax-object-rest-spread": ^7.8.3 + "@babel/plugin-syntax-optional-catch-binding": ^7.8.3 + "@babel/plugin-syntax-optional-chaining": ^7.8.3 + "@babel/plugin-syntax-top-level-await": ^7.8.3 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: d118c2742498c5492c095bc8541f4076b253e705b5f1ad9a2e7d302d81a84866f0070346662355c8e25fc02caa28dc2da8d69bcd67794a0d60c4d6fab6913cc8 + languageName: node + linkType: hard + "babel-preset-expo@npm:~9.5.2": version: 9.5.2 resolution: "babel-preset-expo@npm:9.5.2" @@ -3217,6 +3672,18 @@ __metadata: languageName: node linkType: hard +"babel-preset-jest@npm:^29.6.3": + version: 29.6.3 + resolution: "babel-preset-jest@npm:29.6.3" + dependencies: + babel-plugin-jest-hoist: ^29.6.3 + babel-preset-current-node-syntax: ^1.0.0 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: aa4ff2a8a728d9d698ed521e3461a109a1e66202b13d3494e41eea30729a5e7cc03b3a2d56c594423a135429c37bf63a9fa8b0b9ce275298be3095a88c69f6fb + languageName: node + linkType: hard + "balanced-match@npm:^1.0.0": version: 1.0.2 resolution: "balanced-match@npm:1.0.2" @@ -3359,6 +3826,20 @@ __metadata: languageName: node linkType: hard +"browserslist@npm:^4.22.2": + version: 4.22.2 + resolution: "browserslist@npm:4.22.2" + dependencies: + caniuse-lite: ^1.0.30001565 + electron-to-chromium: ^1.4.601 + node-releases: ^2.0.14 + update-browserslist-db: ^1.0.13 + bin: + browserslist: cli.js + checksum: 33ddfcd9145220099a7a1ac533cecfe5b7548ffeb29b313e1b57be6459000a1f8fa67e781cf4abee97268ac594d44134fcc4a6b2b4750ceddc9796e3a22076d9 + languageName: node + linkType: hard + "bs-logger@npm:0.x": version: 0.2.6 resolution: "bs-logger@npm:0.2.6" @@ -3606,7 +4087,14 @@ __metadata: languageName: node linkType: hard -"camelcase@npm:^5.0.0": +"callsites@npm:^3.0.0": + version: 3.1.0 + resolution: "callsites@npm:3.1.0" + checksum: 072d17b6abb459c2ba96598918b55868af677154bec7e73d222ef95a8fdb9bbf7dae96a8421085cdad8cd190d86653b5b6dc55a4484f2e5b2e27d5e0c3fc15b3 + languageName: node + linkType: hard + +"camelcase@npm:^5.0.0, camelcase@npm:^5.3.1": version: 5.3.1 resolution: "camelcase@npm:5.3.1" checksum: e6effce26b9404e3c0f301498184f243811c30dfe6d0b9051863bd8e4034d09c8c2923794f280d6827e5aa055f6c434115ff97864a16a963366fb35fd673024b @@ -3627,6 +4115,13 @@ __metadata: languageName: node linkType: hard +"caniuse-lite@npm:^1.0.30001565": + version: 1.0.30001579 + resolution: "caniuse-lite@npm:1.0.30001579" + checksum: 7539dcff74d2243a30c428393dc690c87fa34d7da36434731853e9bcfe783757763b2971f5cc878e25242a93e184e53f167d11bd74955af956579f7af71cc764 + languageName: node + linkType: hard + "chalk@npm:^2.0.1, chalk@npm:^2.4.2": version: 2.4.2 resolution: "chalk@npm:2.4.2" @@ -3648,6 +4143,13 @@ __metadata: languageName: node linkType: hard +"char-regex@npm:^1.0.2": + version: 1.0.2 + resolution: "char-regex@npm:1.0.2" + checksum: b563e4b6039b15213114626621e7a3d12f31008bdce20f9c741d69987f62aeaace7ec30f6018890ad77b2e9b4d95324c9f5acfca58a9441e3b1dcdd1e2525d17 + languageName: node + linkType: hard + "charenc@npm:0.0.2, charenc@npm:~0.0.1": version: 0.0.2 resolution: "charenc@npm:0.0.2" @@ -3687,6 +4189,13 @@ __metadata: languageName: node linkType: hard +"cjs-module-lexer@npm:^1.0.0": + version: 1.2.3 + resolution: "cjs-module-lexer@npm:1.2.3" + checksum: 5ea3cb867a9bb609b6d476cd86590d105f3cfd6514db38ff71f63992ab40939c2feb68967faa15a6d2b1f90daa6416b79ea2de486e9e2485a6f8b66a21b4fb0a + languageName: node + linkType: hard + "clean-stack@npm:^2.0.0": version: 2.2.0 resolution: "clean-stack@npm:2.2.0" @@ -3766,6 +4275,20 @@ __metadata: languageName: node linkType: hard +"co@npm:^4.6.0": + version: 4.6.0 + resolution: "co@npm:4.6.0" + checksum: 5210d9223010eb95b29df06a91116f2cf7c8e0748a9013ed853b53f362ea0e822f1e5bb054fb3cefc645239a4cf966af1f6133a3b43f40d591f3b68ed6cf0510 + languageName: node + linkType: hard + +"collect-v8-coverage@npm:^1.0.0": + version: 1.0.2 + resolution: "collect-v8-coverage@npm:1.0.2" + checksum: c10f41c39ab84629d16f9f6137bc8a63d332244383fc368caf2d2052b5e04c20cd1fd70f66fcf4e2422b84c8226598b776d39d5f2d2a51867cc1ed5d1982b4da + languageName: node + linkType: hard + "color-convert@npm:^1.9.0": version: 1.9.3 resolution: "color-convert@npm:1.9.3" @@ -3962,6 +4485,23 @@ __metadata: languageName: node linkType: hard +"create-jest@npm:^29.7.0": + version: 29.7.0 + resolution: "create-jest@npm:29.7.0" + dependencies: + "@jest/types": ^29.6.3 + chalk: ^4.0.0 + exit: ^0.1.2 + graceful-fs: ^4.2.9 + jest-config: ^29.7.0 + jest-util: ^29.7.0 + prompts: ^2.0.1 + bin: + create-jest: bin/create-jest.js + checksum: 1427d49458adcd88547ef6fa39041e1fe9033a661293aa8d2c3aa1b4967cb5bf4f0c00436c7a61816558f28ba2ba81a94d5c962e8022ea9a883978fc8e1f2945 + languageName: node + linkType: hard + "cross-fetch@npm:^3.1.5": version: 3.1.8 resolution: "cross-fetch@npm:3.1.8" @@ -4091,6 +4631,18 @@ __metadata: languageName: node linkType: hard +"dedent@npm:^1.0.0": + version: 1.5.1 + resolution: "dedent@npm:1.5.1" + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + checksum: c3c300a14edf1bdf5a873f9e4b22e839d62490bc5c8d6169c1f15858a1a76733d06a9a56930e963d677a2ceeca4b6b0894cc5ea2f501aa382ca5b92af3413c2a + languageName: node + linkType: hard + "deep-extend@npm:^0.6.0": version: 0.6.0 resolution: "deep-extend@npm:0.6.0" @@ -4098,7 +4650,7 @@ __metadata: languageName: node linkType: hard -"deepmerge@npm:^4.3.0": +"deepmerge@npm:^4.2.2, deepmerge@npm:^4.3.0": version: 4.3.1 resolution: "deepmerge@npm:4.3.1" checksum: 2024c6a980a1b7128084170c4cf56b0fd58a63f2da1660dcfe977415f27b17dbe5888668b59d0b063753f3220719d5e400b7f113609489c90160bb9a5518d052 @@ -4206,6 +4758,13 @@ __metadata: languageName: node linkType: hard +"detect-newline@npm:^3.0.0": + version: 3.1.0 + resolution: "detect-newline@npm:3.1.0" + checksum: ae6cd429c41ad01b164c59ea36f264a2c479598e61cba7c99da24175a7ab80ddf066420f2bec9a1c57a6bead411b4655ff15ad7d281c000a89791f48cbe939e7 + languageName: node + linkType: hard + "detox@npm:*, detox@npm:^20.14.7": version: 20.14.7 resolution: "detox@npm:20.14.7" @@ -4340,6 +4899,20 @@ __metadata: languageName: node linkType: hard +"electron-to-chromium@npm:^1.4.601": + version: 1.4.645 + resolution: "electron-to-chromium@npm:1.4.645" + checksum: ac7d23b8123f09e2343016216b1a8f297ccfb4ae9dccefe3716023344cda8a81656916d40a87039fa3d448cac31c2c4147c6b913b22178a3a00d0221a8019513 + languageName: node + linkType: hard + +"emittery@npm:^0.13.1": + version: 0.13.1 + resolution: "emittery@npm:0.13.1" + checksum: 2b089ab6306f38feaabf4f6f02792f9ec85fc054fda79f44f6790e61bbf6bc4e1616afb9b232e0c5ec5289a8a452f79bfa6d905a6fd64e94b49981f0934001c6 + languageName: node + linkType: hard + "emoji-regex@npm:^8.0.0": version: 8.0.0 resolution: "emoji-regex@npm:8.0.0" @@ -4556,7 +5129,14 @@ __metadata: languageName: node linkType: hard -"expect@npm:^29.0.0": +"exit@npm:^0.1.2": + version: 0.1.2 + resolution: "exit@npm:0.1.2" + checksum: abc407f07a875c3961e4781dfcb743b58d6c93de9ab263f4f8c9d23bb6da5f9b7764fc773f86b43dd88030444d5ab8abcb611cb680fba8ca075362b77114bba3 + languageName: node + linkType: hard + +"expect@npm:^29.0.0, expect@npm:^29.7.0": version: 29.7.0 resolution: "expect@npm:29.7.0" dependencies: @@ -4737,7 +5317,7 @@ __metadata: languageName: node linkType: hard -"fast-json-stable-stringify@npm:2.x": +"fast-json-stable-stringify@npm:2.x, fast-json-stable-stringify@npm:^2.1.0": version: 2.1.0 resolution: "fast-json-stable-stringify@npm:2.1.0" checksum: b191531e36c607977e5b1c47811158733c34ccb3bfde92c44798929e9b4154884378536d26ad90dfecd32e1ffc09c545d23535ad91b3161a27ddbb8ebe0cbecb @@ -4865,7 +5445,7 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^4.1.0": +"find-up@npm:^4.0.0, find-up@npm:^4.1.0": version: 4.1.0 resolution: "find-up@npm:4.1.0" dependencies: @@ -5096,6 +5676,13 @@ __metadata: languageName: node linkType: hard +"get-package-type@npm:^0.1.0": + version: 0.1.0 + resolution: "get-package-type@npm:0.1.0" + checksum: bba0811116d11e56d702682ddef7c73ba3481f114590e705fc549f4d868972263896af313c57a25c076e3c0d567e11d919a64ba1b30c879be985fc9d44f96148 + languageName: node + linkType: hard + "get-port@npm:^3.2.0": version: 3.2.0 resolution: "get-port@npm:3.2.0" @@ -5339,6 +5926,13 @@ __metadata: languageName: node linkType: hard +"html-escaper@npm:^2.0.0": + version: 2.0.2 + resolution: "html-escaper@npm:2.0.2" + checksum: d2df2da3ad40ca9ee3a39c5cc6475ef67c8f83c234475f24d8e9ce0dc80a2c82df8e1d6fa78ddd1e9022a586ea1bd247a615e80a5cd9273d90111ddda7d9e974 + languageName: node + linkType: hard + "http-cache-semantics@npm:^4.1.1": version: 4.1.1 resolution: "http-cache-semantics@npm:4.1.1" @@ -5449,6 +6043,18 @@ __metadata: languageName: node linkType: hard +"import-local@npm:^3.0.2": + version: 3.1.0 + resolution: "import-local@npm:3.1.0" + dependencies: + pkg-dir: ^4.2.0 + resolve-cwd: ^3.0.0 + bin: + import-local-fixture: fixtures/cli.js + checksum: bfcdb63b5e3c0e245e347f3107564035b128a414c4da1172a20dc67db2504e05ede4ac2eee1252359f78b0bfd7b19ef180aec427c2fce6493ae782d73a04cddd + languageName: node + linkType: hard + "imurmurhash@npm:^0.1.4": version: 0.1.4 resolution: "imurmurhash@npm:0.1.4" @@ -5608,6 +6214,13 @@ __metadata: languageName: node linkType: hard +"is-generator-fn@npm:^2.0.0": + version: 2.1.0 + resolution: "is-generator-fn@npm:2.1.0" + checksum: a6ad5492cf9d1746f73b6744e0c43c0020510b59d56ddcb78a91cbc173f09b5e6beff53d75c9c5a29feb618bfef2bf458e025ecf3a57ad2268e2fb2569f56215 + languageName: node + linkType: hard + "is-glob@npm:^2.0.0": version: 2.0.1 resolution: "is-glob@npm:2.0.1" @@ -5753,23 +6366,191 @@ __metadata: languageName: node linkType: hard -"isobject@npm:^3.0.1": - version: 3.0.1 - resolution: "isobject@npm:3.0.1" - checksum: db85c4c970ce30693676487cca0e61da2ca34e8d4967c2e1309143ff910c207133a969f9e4ddb2dc6aba670aabce4e0e307146c310350b298e74a31f7d464703 +"isobject@npm:^3.0.1": + version: 3.0.1 + resolution: "isobject@npm:3.0.1" + checksum: db85c4c970ce30693676487cca0e61da2ca34e8d4967c2e1309143ff910c207133a969f9e4ddb2dc6aba670aabce4e0e307146c310350b298e74a31f7d464703 + languageName: node + linkType: hard + +"istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.0": + version: 3.2.2 + resolution: "istanbul-lib-coverage@npm:3.2.2" + checksum: 2367407a8d13982d8f7a859a35e7f8dd5d8f75aae4bb5484ede3a9ea1b426dc245aff28b976a2af48ee759fdd9be374ce2bd2669b644f31e76c5f46a2e29a831 + languageName: node + linkType: hard + +"istanbul-lib-instrument@npm:^5.0.4": + version: 5.2.1 + resolution: "istanbul-lib-instrument@npm:5.2.1" + dependencies: + "@babel/core": ^7.12.3 + "@babel/parser": ^7.14.7 + "@istanbuljs/schema": ^0.1.2 + istanbul-lib-coverage: ^3.2.0 + semver: ^6.3.0 + checksum: bf16f1803ba5e51b28bbd49ed955a736488381e09375d830e42ddeb403855b2006f850711d95ad726f2ba3f1ae8e7366de7e51d2b9ac67dc4d80191ef7ddf272 + languageName: node + linkType: hard + +"istanbul-lib-instrument@npm:^6.0.0": + version: 6.0.1 + resolution: "istanbul-lib-instrument@npm:6.0.1" + dependencies: + "@babel/core": ^7.12.3 + "@babel/parser": ^7.14.7 + "@istanbuljs/schema": ^0.1.2 + istanbul-lib-coverage: ^3.2.0 + semver: ^7.5.4 + checksum: fb23472e739cfc9b027cefcd7d551d5e7ca7ff2817ae5150fab99fe42786a7f7b56a29a2aa8309c37092e18297b8003f9c274f50ca4360949094d17fbac81472 + languageName: node + linkType: hard + +"istanbul-lib-report@npm:^3.0.0": + version: 3.0.1 + resolution: "istanbul-lib-report@npm:3.0.1" + dependencies: + istanbul-lib-coverage: ^3.0.0 + make-dir: ^4.0.0 + supports-color: ^7.1.0 + checksum: fd17a1b879e7faf9bb1dc8f80b2a16e9f5b7b8498fe6ed580a618c34df0bfe53d2abd35bf8a0a00e628fb7405462576427c7df20bbe4148d19c14b431c974b21 + languageName: node + linkType: hard + +"istanbul-lib-source-maps@npm:^4.0.0": + version: 4.0.1 + resolution: "istanbul-lib-source-maps@npm:4.0.1" + dependencies: + debug: ^4.1.1 + istanbul-lib-coverage: ^3.0.0 + source-map: ^0.6.1 + checksum: 21ad3df45db4b81852b662b8d4161f6446cd250c1ddc70ef96a585e2e85c26ed7cd9c2a396a71533cfb981d1a645508bc9618cae431e55d01a0628e7dec62ef2 + languageName: node + linkType: hard + +"istanbul-reports@npm:^3.1.3": + version: 3.1.6 + resolution: "istanbul-reports@npm:3.1.6" + dependencies: + html-escaper: ^2.0.0 + istanbul-lib-report: ^3.0.0 + checksum: 44c4c0582f287f02341e9720997f9e82c071627e1e862895745d5f52ec72c9b9f38e1d12370015d2a71dcead794f34c7732aaef3fab80a24bc617a21c3d911d6 + languageName: node + linkType: hard + +"jackspeak@npm:^2.3.5": + version: 2.3.6 + resolution: "jackspeak@npm:2.3.6" + dependencies: + "@isaacs/cliui": ^8.0.2 + "@pkgjs/parseargs": ^0.11.0 + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: 57d43ad11eadc98cdfe7496612f6bbb5255ea69fe51ea431162db302c2a11011642f50cfad57288bd0aea78384a0612b16e131944ad8ecd09d619041c8531b54 + languageName: node + linkType: hard + +"jest-changed-files@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-changed-files@npm:29.7.0" + dependencies: + execa: ^5.0.0 + jest-util: ^29.7.0 + p-limit: ^3.1.0 + checksum: 963e203893c396c5dfc75e00a49426688efea7361b0f0e040035809cecd2d46b3c01c02be2d9e8d38b1138357d2de7719ea5b5be21f66c10f2e9685a5a73bb99 + languageName: node + linkType: hard + +"jest-circus@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-circus@npm:29.7.0" + dependencies: + "@jest/environment": ^29.7.0 + "@jest/expect": ^29.7.0 + "@jest/test-result": ^29.7.0 + "@jest/types": ^29.6.3 + "@types/node": "*" + chalk: ^4.0.0 + co: ^4.6.0 + dedent: ^1.0.0 + is-generator-fn: ^2.0.0 + jest-each: ^29.7.0 + jest-matcher-utils: ^29.7.0 + jest-message-util: ^29.7.0 + jest-runtime: ^29.7.0 + jest-snapshot: ^29.7.0 + jest-util: ^29.7.0 + p-limit: ^3.1.0 + pretty-format: ^29.7.0 + pure-rand: ^6.0.0 + slash: ^3.0.0 + stack-utils: ^2.0.3 + checksum: 349437148924a5a109c9b8aad6d393a9591b4dac1918fc97d81b7fc515bc905af9918495055071404af1fab4e48e4b04ac3593477b1d5dcf48c4e71b527c70a7 + languageName: node + linkType: hard + +"jest-cli@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-cli@npm:29.7.0" + dependencies: + "@jest/core": ^29.7.0 + "@jest/test-result": ^29.7.0 + "@jest/types": ^29.6.3 + chalk: ^4.0.0 + create-jest: ^29.7.0 + exit: ^0.1.2 + import-local: ^3.0.2 + jest-config: ^29.7.0 + jest-util: ^29.7.0 + jest-validate: ^29.7.0 + yargs: ^17.3.1 + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + bin: + jest: bin/jest.js + checksum: 664901277a3f5007ea4870632ed6e7889db9da35b2434e7cb488443e6bf5513889b344b7fddf15112135495b9875892b156faeb2d7391ddb9e2a849dcb7b6c36 languageName: node linkType: hard -"jackspeak@npm:^2.3.5": - version: 2.3.6 - resolution: "jackspeak@npm:2.3.6" +"jest-config@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-config@npm:29.7.0" dependencies: - "@isaacs/cliui": ^8.0.2 - "@pkgjs/parseargs": ^0.11.0 - dependenciesMeta: - "@pkgjs/parseargs": + "@babel/core": ^7.11.6 + "@jest/test-sequencer": ^29.7.0 + "@jest/types": ^29.6.3 + babel-jest: ^29.7.0 + chalk: ^4.0.0 + ci-info: ^3.2.0 + deepmerge: ^4.2.2 + glob: ^7.1.3 + graceful-fs: ^4.2.9 + jest-circus: ^29.7.0 + jest-environment-node: ^29.7.0 + jest-get-type: ^29.6.3 + jest-regex-util: ^29.6.3 + jest-resolve: ^29.7.0 + jest-runner: ^29.7.0 + jest-util: ^29.7.0 + jest-validate: ^29.7.0 + micromatch: ^4.0.4 + parse-json: ^5.2.0 + pretty-format: ^29.7.0 + slash: ^3.0.0 + strip-json-comments: ^3.1.1 + peerDependencies: + "@types/node": "*" + ts-node: ">=9.0.0" + peerDependenciesMeta: + "@types/node": optional: true - checksum: 57d43ad11eadc98cdfe7496612f6bbb5255ea69fe51ea431162db302c2a11011642f50cfad57288bd0aea78384a0612b16e131944ad8ecd09d619041c8531b54 + ts-node: + optional: true + checksum: 4cabf8f894c180cac80b7df1038912a3fc88f96f2622de33832f4b3314f83e22b08fb751da570c0ab2b7988f21604bdabade95e3c0c041068ac578c085cf7dff languageName: node linkType: hard @@ -5785,6 +6566,28 @@ __metadata: languageName: node linkType: hard +"jest-docblock@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-docblock@npm:29.7.0" + dependencies: + detect-newline: ^3.0.0 + checksum: 66390c3e9451f8d96c5da62f577a1dad701180cfa9b071c5025acab2f94d7a3efc2515cfa1654ebe707213241541ce9c5530232cdc8017c91ed64eea1bd3b192 + languageName: node + linkType: hard + +"jest-each@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-each@npm:29.7.0" + dependencies: + "@jest/types": ^29.6.3 + chalk: ^4.0.0 + jest-get-type: ^29.6.3 + jest-util: ^29.7.0 + pretty-format: ^29.7.0 + checksum: e88f99f0184000fc8813f2a0aa79e29deeb63700a3b9b7928b8a418d7d93cd24933608591dbbdea732b473eb2021c72991b5cc51a17966842841c6e28e6f691c + languageName: node + linkType: hard + "jest-environment-emit@npm:^1.0.5": version: 1.0.5 resolution: "jest-environment-emit@npm:1.0.5" @@ -5818,7 +6621,7 @@ __metadata: languageName: node linkType: hard -"jest-environment-node@npm:^29.2.1": +"jest-environment-node@npm:^29.2.1, jest-environment-node@npm:^29.7.0": version: 29.7.0 resolution: "jest-environment-node@npm:29.7.0" dependencies: @@ -5839,6 +6642,39 @@ __metadata: languageName: node linkType: hard +"jest-haste-map@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-haste-map@npm:29.7.0" + dependencies: + "@jest/types": ^29.6.3 + "@types/graceful-fs": ^4.1.3 + "@types/node": "*" + anymatch: ^3.0.3 + fb-watchman: ^2.0.0 + fsevents: ^2.3.2 + graceful-fs: ^4.2.9 + jest-regex-util: ^29.6.3 + jest-util: ^29.7.0 + jest-worker: ^29.7.0 + micromatch: ^4.0.4 + walker: ^1.0.8 + dependenciesMeta: + fsevents: + optional: true + checksum: c2c8f2d3e792a963940fbdfa563ce14ef9e14d4d86da645b96d3cd346b8d35c5ce0b992ee08593939b5f718cf0a1f5a90011a056548a1dbf58397d4356786f01 + languageName: node + linkType: hard + +"jest-leak-detector@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-leak-detector@npm:29.7.0" + dependencies: + jest-get-type: ^29.6.3 + pretty-format: ^29.7.0 + checksum: e3950e3ddd71e1d0c22924c51a300a1c2db6cf69ec1e51f95ccf424bcc070f78664813bef7aed4b16b96dfbdeea53fe358f8aeaaea84346ae15c3735758f1605 + languageName: node + linkType: hard + "jest-matcher-utils@npm:^29.7.0": version: 29.7.0 resolution: "jest-matcher-utils@npm:29.7.0" @@ -5879,6 +6715,18 @@ __metadata: languageName: node linkType: hard +"jest-pnp-resolver@npm:^1.2.2": + version: 1.2.3 + resolution: "jest-pnp-resolver@npm:1.2.3" + peerDependencies: + jest-resolve: "*" + peerDependenciesMeta: + jest-resolve: + optional: true + checksum: db1a8ab2cb97ca19c01b1cfa9a9c8c69a143fde833c14df1fab0766f411b1148ff0df878adea09007ac6a2085ec116ba9a996a6ad104b1e58c20adbf88eed9b2 + languageName: node + linkType: hard + "jest-regex-util@npm:^27.0.6": version: 27.5.1 resolution: "jest-regex-util@npm:27.5.1" @@ -5886,6 +6734,127 @@ __metadata: languageName: node linkType: hard +"jest-regex-util@npm:^29.6.3": + version: 29.6.3 + resolution: "jest-regex-util@npm:29.6.3" + checksum: 0518beeb9bf1228261695e54f0feaad3606df26a19764bc19541e0fc6e2a3737191904607fb72f3f2ce85d9c16b28df79b7b1ec9443aa08c3ef0e9efda6f8f2a + languageName: node + linkType: hard + +"jest-resolve-dependencies@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-resolve-dependencies@npm:29.7.0" + dependencies: + jest-regex-util: ^29.6.3 + jest-snapshot: ^29.7.0 + checksum: aeb75d8150aaae60ca2bb345a0d198f23496494677cd6aefa26fc005faf354061f073982175daaf32b4b9d86b26ca928586344516e3e6969aa614cb13b883984 + languageName: node + linkType: hard + +"jest-resolve@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-resolve@npm:29.7.0" + dependencies: + chalk: ^4.0.0 + graceful-fs: ^4.2.9 + jest-haste-map: ^29.7.0 + jest-pnp-resolver: ^1.2.2 + jest-util: ^29.7.0 + jest-validate: ^29.7.0 + resolve: ^1.20.0 + resolve.exports: ^2.0.0 + slash: ^3.0.0 + checksum: 0ca218e10731aa17920526ec39deaec59ab9b966237905ffc4545444481112cd422f01581230eceb7e82d86f44a543d520a71391ec66e1b4ef1a578bd5c73487 + languageName: node + linkType: hard + +"jest-runner@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-runner@npm:29.7.0" + dependencies: + "@jest/console": ^29.7.0 + "@jest/environment": ^29.7.0 + "@jest/test-result": ^29.7.0 + "@jest/transform": ^29.7.0 + "@jest/types": ^29.6.3 + "@types/node": "*" + chalk: ^4.0.0 + emittery: ^0.13.1 + graceful-fs: ^4.2.9 + jest-docblock: ^29.7.0 + jest-environment-node: ^29.7.0 + jest-haste-map: ^29.7.0 + jest-leak-detector: ^29.7.0 + jest-message-util: ^29.7.0 + jest-resolve: ^29.7.0 + jest-runtime: ^29.7.0 + jest-util: ^29.7.0 + jest-watcher: ^29.7.0 + jest-worker: ^29.7.0 + p-limit: ^3.1.0 + source-map-support: 0.5.13 + checksum: f0405778ea64812bf9b5c50b598850d94ccf95d7ba21f090c64827b41decd680ee19fcbb494007cdd7f5d0d8906bfc9eceddd8fa583e753e736ecd462d4682fb + languageName: node + linkType: hard + +"jest-runtime@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-runtime@npm:29.7.0" + dependencies: + "@jest/environment": ^29.7.0 + "@jest/fake-timers": ^29.7.0 + "@jest/globals": ^29.7.0 + "@jest/source-map": ^29.6.3 + "@jest/test-result": ^29.7.0 + "@jest/transform": ^29.7.0 + "@jest/types": ^29.6.3 + "@types/node": "*" + chalk: ^4.0.0 + cjs-module-lexer: ^1.0.0 + collect-v8-coverage: ^1.0.0 + glob: ^7.1.3 + graceful-fs: ^4.2.9 + jest-haste-map: ^29.7.0 + jest-message-util: ^29.7.0 + jest-mock: ^29.7.0 + jest-regex-util: ^29.6.3 + jest-resolve: ^29.7.0 + jest-snapshot: ^29.7.0 + jest-util: ^29.7.0 + slash: ^3.0.0 + strip-bom: ^4.0.0 + checksum: d19f113d013e80691e07047f68e1e3448ef024ff2c6b586ce4f90cd7d4c62a2cd1d460110491019719f3c59bfebe16f0e201ed005ef9f80e2cf798c374eed54e + languageName: node + linkType: hard + +"jest-snapshot@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-snapshot@npm:29.7.0" + dependencies: + "@babel/core": ^7.11.6 + "@babel/generator": ^7.7.2 + "@babel/plugin-syntax-jsx": ^7.7.2 + "@babel/plugin-syntax-typescript": ^7.7.2 + "@babel/types": ^7.3.3 + "@jest/expect-utils": ^29.7.0 + "@jest/transform": ^29.7.0 + "@jest/types": ^29.6.3 + babel-preset-current-node-syntax: ^1.0.0 + chalk: ^4.0.0 + expect: ^29.7.0 + graceful-fs: ^4.2.9 + jest-diff: ^29.7.0 + jest-get-type: ^29.6.3 + jest-matcher-utils: ^29.7.0 + jest-message-util: ^29.7.0 + jest-util: ^29.7.0 + natural-compare: ^1.4.0 + pretty-format: ^29.7.0 + semver: ^7.5.3 + checksum: 86821c3ad0b6899521ce75ee1ae7b01b17e6dfeff9166f2cf17f012e0c5d8c798f30f9e4f8f7f5bed01ea7b55a6bc159f5eda778311162cbfa48785447c237ad + languageName: node + linkType: hard + "jest-util@npm:^27.2.0": version: 27.5.1 resolution: "jest-util@npm:27.5.1" @@ -5914,7 +6883,7 @@ __metadata: languageName: node linkType: hard -"jest-validate@npm:^29.2.1": +"jest-validate@npm:^29.2.1, jest-validate@npm:^29.7.0": version: 29.7.0 resolution: "jest-validate@npm:29.7.0" dependencies: @@ -5928,6 +6897,22 @@ __metadata: languageName: node linkType: hard +"jest-watcher@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-watcher@npm:29.7.0" + dependencies: + "@jest/test-result": ^29.7.0 + "@jest/types": ^29.6.3 + "@types/node": "*" + ansi-escapes: ^4.2.1 + chalk: ^4.0.0 + emittery: ^0.13.1 + jest-util: ^29.7.0 + string-length: ^4.0.1 + checksum: 67e6e7fe695416deff96b93a14a561a6db69389a0667e9489f24485bb85e5b54e12f3b2ba511ec0b777eca1e727235b073e3ebcdd473d68888650489f88df92f + languageName: node + linkType: hard + "jest-worker@npm:^27.2.0": version: 27.5.1 resolution: "jest-worker@npm:27.5.1" @@ -5939,6 +6924,37 @@ __metadata: languageName: node linkType: hard +"jest-worker@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-worker@npm:29.7.0" + dependencies: + "@types/node": "*" + jest-util: ^29.7.0 + merge-stream: ^2.0.0 + supports-color: ^8.0.0 + checksum: 30fff60af49675273644d408b650fc2eb4b5dcafc5a0a455f238322a8f9d8a98d847baca9d51ff197b6747f54c7901daa2287799230b856a0f48287d131f8c13 + languageName: node + linkType: hard + +"jest@npm:^29.7.0": + version: 29.7.0 + resolution: "jest@npm:29.7.0" + dependencies: + "@jest/core": ^29.7.0 + "@jest/types": ^29.6.3 + import-local: ^3.0.2 + jest-cli: ^29.7.0 + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + bin: + jest: bin/jest.js + checksum: 17ca8d67504a7dbb1998cf3c3077ec9031ba3eb512da8d71cb91bcabb2b8995c4e4b292b740cb9bf1cbff5ce3e110b3f7c777b0cefb6f41ab05445f248d0ee0b + languageName: node + linkType: hard + "jimp-compact@npm:0.16.1": version: 0.16.1 resolution: "jimp-compact@npm:0.16.1" @@ -6089,6 +7105,13 @@ __metadata: languageName: node linkType: hard +"json-parse-even-better-errors@npm:^2.3.0": + version: 2.3.1 + resolution: "json-parse-even-better-errors@npm:2.3.1" + checksum: 798ed4cf3354a2d9ccd78e86d2169515a0097a5c133337807cdf7f1fc32e1391d207ccfc276518cc1d7d8d4db93288b8a50ba4293d212ad1336e52a8ec0a941f + languageName: node + linkType: hard + "json-schema-deref-sync@npm:^0.13.0": version: 0.13.0 resolution: "json-schema-deref-sync@npm:0.13.0" @@ -6415,6 +7438,15 @@ __metadata: languageName: node linkType: hard +"make-dir@npm:^4.0.0": + version: 4.0.0 + resolution: "make-dir@npm:4.0.0" + dependencies: + semver: ^7.5.3 + checksum: bf0731a2dd3aab4db6f3de1585cea0b746bb73eb5a02e3d8d72757e376e64e6ada190b1eddcde5b2f24a81b688a9897efd5018737d05e02e2a671dda9cff8a8a + languageName: node + linkType: hard + "make-error@npm:1.x": version: 1.3.6 resolution: "make-error@npm:1.3.6" @@ -7138,6 +8170,13 @@ __metadata: languageName: node linkType: hard +"natural-compare@npm:^1.4.0": + version: 1.4.0 + resolution: "natural-compare@npm:1.4.0" + checksum: 23ad088b08f898fc9b53011d7bb78ec48e79de7627e01ab5518e806033861bef68d5b0cd0e2205c2f36690ac9571ff6bcb05eb777ced2eeda8d4ac5b44592c3d + languageName: node + linkType: hard + "ncp@npm:~2.0.0": version: 2.0.0 resolution: "ncp@npm:2.0.0" @@ -7264,6 +8303,13 @@ __metadata: languageName: node linkType: hard +"node-releases@npm:^2.0.14": + version: 2.0.14 + resolution: "node-releases@npm:2.0.14" + checksum: 59443a2f77acac854c42d321bf1b43dea0aef55cd544c6a686e9816a697300458d4e82239e2d794ea05f7bbbc8a94500332e2d3ac3f11f52e4b16cbe638b3c41 + languageName: node + linkType: hard + "node-stream-zip@npm:^1.9.1": version: 1.15.0 resolution: "node-stream-zip@npm:1.15.0" @@ -7497,7 +8543,7 @@ __metadata: languageName: node linkType: hard -"p-limit@npm:^3.0.2": +"p-limit@npm:^3.0.2, p-limit@npm:^3.1.0": version: 3.1.0 resolution: "p-limit@npm:3.1.0" dependencies: @@ -7559,6 +8605,18 @@ __metadata: languageName: node linkType: hard +"parse-json@npm:^5.2.0": + version: 5.2.0 + resolution: "parse-json@npm:5.2.0" + dependencies: + "@babel/code-frame": ^7.0.0 + error-ex: ^1.3.1 + json-parse-even-better-errors: ^2.3.0 + lines-and-columns: ^1.1.6 + checksum: 62085b17d64da57f40f6afc2ac1f4d95def18c4323577e1eced571db75d9ab59b297d1d10582920f84b15985cbfc6b6d450ccbf317644cfa176f3ed982ad87e2 + languageName: node + linkType: hard + "parse-png@npm:^2.1.0": version: 2.1.0 resolution: "parse-png@npm:2.1.0" @@ -7672,7 +8730,7 @@ __metadata: languageName: node linkType: hard -"pirates@npm:^4.0.1, pirates@npm:^4.0.5": +"pirates@npm:^4.0.1, pirates@npm:^4.0.4, pirates@npm:^4.0.5": version: 4.0.6 resolution: "pirates@npm:4.0.6" checksum: 46a65fefaf19c6f57460388a5af9ab81e3d7fd0e7bc44ca59d753cb5c4d0df97c6c6e583674869762101836d68675f027d60f841c105d72734df9dfca97cbcc6 @@ -7688,6 +8746,15 @@ __metadata: languageName: node linkType: hard +"pkg-dir@npm:^4.2.0": + version: 4.2.0 + resolution: "pkg-dir@npm:4.2.0" + dependencies: + find-up: ^4.0.0 + checksum: 9863e3f35132bf99ae1636d31ff1e1e3501251d480336edb1c211133c8d58906bed80f154a1d723652df1fda91e01c7442c2eeaf9dc83157c7ae89087e43c8d6 + languageName: node + linkType: hard + "pkg-up@npm:^3.1.0": version: 3.1.0 resolution: "pkg-up@npm:3.1.0" @@ -7819,7 +8886,7 @@ __metadata: languageName: node linkType: hard -"prompts@npm:^2.3.2, prompts@npm:^2.4.0": +"prompts@npm:^2.0.1, prompts@npm:^2.3.2, prompts@npm:^2.4.0": version: 2.4.2 resolution: "prompts@npm:2.4.2" dependencies: @@ -7875,6 +8942,13 @@ __metadata: languageName: node linkType: hard +"pure-rand@npm:^6.0.0": + version: 6.0.4 + resolution: "pure-rand@npm:6.0.4" + checksum: e1c4e69f8bf7303e5252756d67c3c7551385cd34d94a1f511fe099727ccbab74c898c03a06d4c4a24a89b51858781057b83ebbfe740d984240cdc04fead36068 + languageName: node + linkType: hard + "qrcode-terminal@npm:0.11.0": version: 0.11.0 resolution: "qrcode-terminal@npm:0.11.0" @@ -8006,6 +9080,7 @@ __metadata: expo: ~49.0.16 expo-splash-screen: ~0.20.5 expo-status-bar: ~1.7.1 + jest: ^29.7.0 react: 18.2.0 react-native: 0.72.6 react-native-dotenv: ^3.4.9 @@ -8252,6 +9327,15 @@ __metadata: languageName: node linkType: hard +"resolve-cwd@npm:^3.0.0": + version: 3.0.0 + resolution: "resolve-cwd@npm:3.0.0" + dependencies: + resolve-from: ^5.0.0 + checksum: 546e0816012d65778e580ad62b29e975a642989108d9a3c5beabfb2304192fa3c9f9146fbdfe213563c6ff51975ae41bac1d3c6e047dd9572c94863a057b4d81 + languageName: node + linkType: hard + "resolve-from@npm:^3.0.0": version: 3.0.0 resolution: "resolve-from@npm:3.0.0" @@ -8266,7 +9350,14 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.14.2, resolve@npm:^1.22.1": +"resolve.exports@npm:^2.0.0": + version: 2.0.2 + resolution: "resolve.exports@npm:2.0.2" + checksum: 1c7778ca1b86a94f8ab4055d196c7d87d1874b96df4d7c3e67bbf793140f0717fd506dcafd62785b079cd6086b9264424ad634fb904409764c3509c3df1653f2 + languageName: node + linkType: hard + +"resolve@npm:^1.14.2, resolve@npm:^1.20.0, resolve@npm:^1.22.1": version: 1.22.8 resolution: "resolve@npm:1.22.8" dependencies: @@ -8288,7 +9379,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.22.1#~builtin": +"resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.1#~builtin": version: 1.22.8 resolution: "resolve@patch:resolve@npm%3A1.22.8#~builtin::version=1.22.8&hash=c3c19d" dependencies: @@ -8479,7 +9570,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^6.3.1": +"semver@npm:^6.3.0, semver@npm:^6.3.1": version: 6.3.1 resolution: "semver@npm:6.3.1" bin: @@ -8488,7 +9579,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.0.0, semver@npm:^7.3.5, semver@npm:^7.5.2, semver@npm:^7.5.3": +"semver@npm:^7.0.0, semver@npm:^7.3.5, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4": version: 7.5.4 resolution: "semver@npm:7.5.4" dependencies: @@ -8649,7 +9740,7 @@ __metadata: languageName: node linkType: hard -"signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3": +"signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3, signal-exit@npm:^3.0.7": version: 3.0.7 resolution: "signal-exit@npm:3.0.7" checksum: a2f098f247adc367dffc27845853e9959b9e88b01cb301658cfe4194352d8d2bb32e18467c786a7fe15f1d44b233ea35633d076d5e737870b7139949d1ab6318 @@ -8741,6 +9832,16 @@ __metadata: languageName: node linkType: hard +"source-map-support@npm:0.5.13": + version: 0.5.13 + resolution: "source-map-support@npm:0.5.13" + dependencies: + buffer-from: ^1.0.0 + source-map: ^0.6.0 + checksum: 933550047b6c1a2328599a21d8b7666507427c0f5ef5eaadd56b5da0fd9505e239053c66fe181bf1df469a3b7af9d775778eee283cbb7ae16b902ddc09e93a97 + languageName: node + linkType: hard + "source-map-support@npm:^0.5.16, source-map-support@npm:~0.5.20": version: 0.5.21 resolution: "source-map-support@npm:0.5.21" @@ -8758,7 +9859,7 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.6.0, source-map@npm:~0.6.1": +"source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.1": version: 0.6.1 resolution: "source-map@npm:0.6.1" checksum: 59ce8640cf3f3124f64ac289012c2b8bd377c238e316fb323ea22fbfe83da07d81e000071d7242cad7a23cd91c7de98e4df8830ec3f133cb6133a5f6e9f67bc2 @@ -8868,6 +9969,16 @@ __metadata: languageName: node linkType: hard +"string-length@npm:^4.0.1": + version: 4.0.2 + resolution: "string-length@npm:4.0.2" + dependencies: + char-regex: ^1.0.2 + strip-ansi: ^6.0.0 + checksum: ce85533ef5113fcb7e522bcf9e62cb33871aa99b3729cec5595f4447f660b0cefd542ca6df4150c97a677d58b0cb727a3fe09ac1de94071d05526c73579bf505 + languageName: node + linkType: hard + "string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": version: 4.2.3 resolution: "string-width@npm:4.2.3" @@ -8935,6 +10046,13 @@ __metadata: languageName: node linkType: hard +"strip-bom@npm:^4.0.0": + version: 4.0.0 + resolution: "strip-bom@npm:4.0.0" + checksum: 9dbcfbaf503c57c06af15fe2c8176fb1bf3af5ff65003851a102749f875a6dbe0ab3b30115eccf6e805e9d756830d3e40ec508b62b3f1ddf3761a20ebe29d3f3 + languageName: node + linkType: hard + "strip-eof@npm:^1.0.0": version: 1.0.0 resolution: "strip-eof@npm:1.0.0" @@ -8949,6 +10067,13 @@ __metadata: languageName: node linkType: hard +"strip-json-comments@npm:^3.1.1": + version: 3.1.1 + resolution: "strip-json-comments@npm:3.1.1" + checksum: 492f73e27268f9b1c122733f28ecb0e7e8d8a531a6662efbd08e22cccb3f9475e90a1b82cab06a392f6afae6d2de636f977e231296400d0ec5304ba70f166443 + languageName: node + linkType: hard + "strip-json-comments@npm:~2.0.1": version: 2.0.1 resolution: "strip-json-comments@npm:2.0.1" @@ -9157,6 +10282,17 @@ __metadata: languageName: node linkType: hard +"test-exclude@npm:^6.0.0": + version: 6.0.0 + resolution: "test-exclude@npm:6.0.0" + dependencies: + "@istanbuljs/schema": ^0.1.2 + glob: ^7.1.4 + minimatch: ^3.0.4 + checksum: 3b34a3d77165a2cb82b34014b3aba93b1c4637a5011807557dc2f3da826c59975a5ccad765721c4648b39817e3472789f9b0fa98fc854c5c1c7a1e632aacdc28 + languageName: node + linkType: hard + "text-table@npm:^0.2.0": version: 0.2.0 resolution: "text-table@npm:0.2.0" @@ -9639,6 +10775,17 @@ __metadata: languageName: node linkType: hard +"v8-to-istanbul@npm:^9.0.1": + version: 9.2.0 + resolution: "v8-to-istanbul@npm:9.2.0" + dependencies: + "@jridgewell/trace-mapping": ^0.3.12 + "@types/istanbul-lib-coverage": ^2.0.1 + convert-source-map: ^2.0.0 + checksum: 31ef98c6a31b1dab6be024cf914f235408cd4c0dc56a5c744a5eea1a9e019ba279e1b6f90d695b78c3186feed391ed492380ccf095009e2eb91f3d058f0b4491 + languageName: node + linkType: hard + "valid-url@npm:~1.0.9": version: 1.0.9 resolution: "valid-url@npm:1.0.9" @@ -9669,7 +10816,7 @@ __metadata: languageName: node linkType: hard -"walker@npm:^1.0.7": +"walker@npm:^1.0.7, walker@npm:^1.0.8": version: 1.0.8 resolution: "walker@npm:1.0.8" dependencies: @@ -9816,6 +10963,16 @@ __metadata: languageName: node linkType: hard +"write-file-atomic@npm:^4.0.2": + version: 4.0.2 + resolution: "write-file-atomic@npm:4.0.2" + dependencies: + imurmurhash: ^0.1.4 + signal-exit: ^3.0.7 + checksum: 5da60bd4eeeb935eec97ead3df6e28e5917a6bd317478e4a85a5285e8480b8ed96032bbcc6ecd07b236142a24f3ca871c924ec4a6575e623ec1b11bf8c1c253c + languageName: node + linkType: hard + "ws@npm:^6.2.2": version: 6.2.2 resolution: "ws@npm:6.2.2" @@ -9993,7 +11150,7 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^17.0.0, yargs@npm:^17.6.2": +"yargs@npm:^17.0.0, yargs@npm:^17.3.1, yargs@npm:^17.6.2": version: 17.7.2 resolution: "yargs@npm:17.7.2" dependencies: diff --git a/packages/sdk/react-native/jest.config.ts b/packages/sdk/react-native/jest.config.ts index a740765ad..68246526c 100644 --- a/packages/sdk/react-native/jest.config.ts +++ b/packages/sdk/react-native/jest.config.ts @@ -1,7 +1,9 @@ import type { JestConfigWithTsJest } from 'ts-jest'; +import { defaults as tsjPreset } from 'ts-jest/presets'; const jestConfig: JestConfigWithTsJest = { - preset: 'ts-jest', + ...tsjPreset, + preset: 'react-native', testEnvironment: 'jsdom', transform: { '^.+\\.tsx?$': [ @@ -12,6 +14,7 @@ const jestConfig: JestConfigWithTsJest = { ], }, testPathIgnorePatterns: ['node_modules', 'example', 'dist'], + setupFiles: ['./jestSetupFile.ts'], }; export default jestConfig; diff --git a/packages/sdk/react-native/jestSetupFile.ts b/packages/sdk/react-native/jestSetupFile.ts new file mode 100644 index 000000000..03f14b96f --- /dev/null +++ b/packages/sdk/react-native/jestSetupFile.ts @@ -0,0 +1,19 @@ +jest.mock('@react-native-async-storage/async-storage', () => + jest.requireActual('@react-native-async-storage/async-storage/jest/async-storage-mock'), +); + +jest.mock('react-native', () => { + const RN = jest.requireActual('react-native'); + RN.NativeModules.SettingsManager = { + settings: { + AppleLocale: 'en-us', + }, + }; + + // HACK: force set Platform which is read-only + Object.defineProperty(RN.Platform, 'Version', { + get: () => 21, + }); + + return RN; +}); diff --git a/packages/sdk/react-native/package.json b/packages/sdk/react-native/package.json index 556f4bd74..09fd6a7b1 100644 --- a/packages/sdk/react-native/package.json +++ b/packages/sdk/react-native/package.json @@ -30,7 +30,7 @@ "build": "npx tsc && yarn link-dev", "tsw": "yarn tsc --watch", "start": "rimraf dist && yarn tsw", - "lint": "eslint . --ext .ts", + "lint": "eslint . --ext .ts,.tsx", "prettier": "prettier --write '**/*.@(js|ts|tsx|json|css)' --ignore-path ../../../.prettierignore", "test": "jest", "coverage": "yarn test --coverage", @@ -54,16 +54,18 @@ "@trivago/prettier-plugin-sort-imports": "^4.1.1", "@types/jest": "^29.5.11", "@types/react": "^18.2.31", - "@typescript-eslint/eslint-plugin": "^6.1.0", - "@typescript-eslint/parser": "^6.1.0", + "@typescript-eslint/eslint-plugin": "^6.20.0", + "@typescript-eslint/parser": "^6.20.0", "eslint": "^8.45.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^17.1.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jest": "^27.6.3", "eslint-plugin-prettier": "^5.0.0", "jest": "^29.7.0", "launchdarkly-js-test-helpers": "^2.2.0", + "metro-react-native-babel-preset": "^0.77.0", "prettier": "^3.0.0", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/packages/sdk/react-native/src/ReactNativeLDClient.test.ts b/packages/sdk/react-native/src/ReactNativeLDClient.test.ts index f7c9f717f..00569fcd3 100644 --- a/packages/sdk/react-native/src/ReactNativeLDClient.test.ts +++ b/packages/sdk/react-native/src/ReactNativeLDClient.test.ts @@ -1,4 +1,4 @@ -import { type LDContext } from '@launchdarkly/js-client-sdk-common'; +import { AutoEnvAttributes, type LDContext } from '@launchdarkly/js-client-sdk-common'; import ReactNativeLDClient from './ReactNativeLDClient'; @@ -6,7 +6,7 @@ describe('ReactNativeLDClient', () => { let ldc: ReactNativeLDClient; beforeEach(() => { - ldc = new ReactNativeLDClient('mobile-key', { sendEvents: false }); + ldc = new ReactNativeLDClient('mobile-key', AutoEnvAttributes.Enabled, { sendEvents: false }); }); test('constructing a new client', () => { diff --git a/packages/sdk/react-native/src/ReactNativeLDClient.ts b/packages/sdk/react-native/src/ReactNativeLDClient.ts index 5058b4b9a..2b13d9889 100644 --- a/packages/sdk/react-native/src/ReactNativeLDClient.ts +++ b/packages/sdk/react-native/src/ReactNativeLDClient.ts @@ -1,4 +1,5 @@ import { + AutoEnvAttributes, base64UrlEncode, BasicLogger, internal, @@ -15,7 +16,7 @@ import createPlatform from './platform'; * * @example * ```tsx - * const featureClient = new ReactNativeLDClient(MOBILE_KEY); + * const featureClient = new ReactNativeLDClient(MOBILE_KEY, AutoEnvAttributes.Enabled); * * * @@ -27,9 +28,13 @@ export default class ReactNativeLDClient extends LDClientImpl { * Creates an instance of the LaunchDarkly client. * * @param sdkKey The LaunchDarkly mobile key. + * @param autoEnvAttributes Enable / disable Auto environment attributes. When enabled, the SDK will automatically + * provide data about the mobile environment where the application is running. To learn more, + * read [Automatic environment attributes](https://docs.launchdarkly.com/sdk/features/environment-attributes). + * for more documentation. * @param options {@link LDOptions} to initialize the client with. */ - constructor(sdkKey: string, options: LDOptions = {}) { + constructor(sdkKey: string, autoEnvAttributes: AutoEnvAttributes, options: LDOptions = {}) { const logger = options.logger ?? new BasicLogger({ @@ -43,7 +48,13 @@ export default class ReactNativeLDClient extends LDClientImpl { diagnosticEventPath: `/mobile/events/diagnostic`, }; - super(sdkKey, createPlatform(logger), { ...options, logger }, internalOptions); + super( + sdkKey, + autoEnvAttributes, + createPlatform(logger), + { ...options, logger }, + internalOptions, + ); } override createStreamUriPath(context: LDContext) { diff --git a/packages/sdk/react-native/src/fromExternal/js-sha256/LICENSE b/packages/sdk/react-native/src/fromExternal/js-sha256/LICENSE new file mode 100644 index 000000000..d06f6d49a --- /dev/null +++ b/packages/sdk/react-native/src/fromExternal/js-sha256/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2014-2023 Chen, Yi-Cyuan + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/sdk/react-native/src/fromExternal/js-sha256/index.d.ts b/packages/sdk/react-native/src/fromExternal/js-sha256/index.d.ts new file mode 100644 index 000000000..1ac455ecb --- /dev/null +++ b/packages/sdk/react-native/src/fromExternal/js-sha256/index.d.ts @@ -0,0 +1,149 @@ +type Message = string | number[] | ArrayBuffer | Uint8Array; + +interface Hasher { + /** + * Update hash + * + * @param message The message you want to hash. + */ + update(message: Message): Hasher; + + /** + * Return hash in hex string. + */ + hex(): string; + + /** + * Return hash in hex string. + */ + toString(): string; + + /** + * Return hash in ArrayBuffer. + */ + arrayBuffer(): ArrayBuffer; + + /** + * Return hash in integer array. + */ + digest(): number[]; + + /** + * Return hash in integer array. + */ + array(): number[]; +} + +interface Hmac { + /** + * Computes a Hash-based message authentication code (HMAC) using a secret key + * + * @param secretKey The Secret Key + * @param message The message you want to hash. + */ + (secretKey: Message, message: Message): string; + + /** + * Create a hash object using a secret key. + * + * @param secretKey The Secret Key + */ + create(secretKey: Message): Hasher; + + /** + * Create a hash object and hash message using a secret key + * + * @param secretKey The Secret Key + * @param message The message you want to hash. + */ + update(secretKey: Message, message: Message): Hasher; + + /** + * Return hash in hex string. + * + * @param secretKey The Secret Key + * @param message The message you want to hash. + */ + hex(secretKey: Message, message: Message): string; + + /** + * Return hash in ArrayBuffer. + * + * @param secretKey The Secret Key + * @param message The message you want to hash. + */ + arrayBuffer(secretKey: Message, message: Message): ArrayBuffer; + + /** + * Return hash in integer array. + * + * @param secretKey The Secret Key + * @param message The message you want to hash. + */ + digest(secretKey: Message, message: Message): number[]; + + /** + * Return hash in integer array. + * + * @param secretKey The Secret Key + * @param message The message you want to hash. + */ + array(secretKey: Message, message: Message): number[]; +} + +interface Hash { + /** + * Hash and return hex string. + * + * @param message The message you want to hash. + */ + (message: Message): string; + + /** + * Create a hash object. + */ + create(): Hasher; + + /** + * Create a hash object and hash message. + * + * @param message The message you want to hash. + */ + update(message: Message): Hasher; + + /** + * Return hash in hex string. + * + * @param message The message you want to hash. + */ + hex(message: Message): string; + + /** + * Return hash in ArrayBuffer. + * + * @param message The message you want to hash. + */ + arrayBuffer(message: Message): ArrayBuffer; + + /** + * Return hash in integer array. + * + * @param message The message you want to hash. + */ + digest(message: Message): number[]; + + /** + * Return hash in integer array. + * + * @param message The message you want to hash. + */ + array(message: Message): number[]; + + /** + * HMAC interface + */ + hmac: Hmac; +} + +export var sha256: Hash; +export var sha224: Hash; diff --git a/packages/sdk/react-native/src/fromExternal/js-sha256/index.js b/packages/sdk/react-native/src/fromExternal/js-sha256/index.js new file mode 100644 index 000000000..6edd54555 --- /dev/null +++ b/packages/sdk/react-native/src/fromExternal/js-sha256/index.js @@ -0,0 +1,633 @@ +/** + * [js-sha256]{@link https://github.com/emn178/js-sha256} + * + * @version 0.10.1 + * @author Chen, Yi-Cyuan [emn178@gmail.com] + * @copyright Chen, Yi-Cyuan 2014-2023 + * @license MIT + */ +/*jslint bitwise: true */ +(function () { + 'use strict'; + + var ERROR = 'input is invalid type'; + var WINDOW = typeof window === 'object'; + var root = WINDOW ? window : {}; + if (root.JS_SHA256_NO_WINDOW) { + WINDOW = false; + } + var WEB_WORKER = !WINDOW && typeof self === 'object'; + var NODE_JS = + !root.JS_SHA256_NO_NODE_JS && + typeof process === 'object' && + process.versions && + process.versions.node; + if (NODE_JS) { + root = global; + } else if (WEB_WORKER) { + root = self; + } + var COMMON_JS = !root.JS_SHA256_NO_COMMON_JS && typeof module === 'object' && module.exports; + var AMD = typeof define === 'function' && define.amd; + var ARRAY_BUFFER = !root.JS_SHA256_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined'; + var HEX_CHARS = '0123456789abcdef'.split(''); + var EXTRA = [-2147483648, 8388608, 32768, 128]; + var SHIFT = [24, 16, 8, 0]; + var K = [ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, + ]; + var OUTPUT_TYPES = ['hex', 'array', 'digest', 'arrayBuffer']; + + var blocks = []; + + if (root.JS_SHA256_NO_NODE_JS || !Array.isArray) { + Array.isArray = function (obj) { + return Object.prototype.toString.call(obj) === '[object Array]'; + }; + } + + if (ARRAY_BUFFER && (root.JS_SHA256_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) { + ArrayBuffer.isView = function (obj) { + return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer; + }; + } + + var createOutputMethod = function (outputType, is224) { + return function (message) { + return new Sha256(is224, true).update(message)[outputType](); + }; + }; + + var createMethod = function (is224) { + var method = createOutputMethod('hex', is224); + method.create = function () { + return new Sha256(is224); + }; + method.update = function (message) { + return method.create().update(message); + }; + for (var i = 0; i < OUTPUT_TYPES.length; ++i) { + var type = OUTPUT_TYPES[i]; + method[type] = createOutputMethod(type, is224); + } + return method; + }; + + var createHmacOutputMethod = function (outputType, is224) { + return function (key, message) { + return new HmacSha256(key, is224, true).update(message)[outputType](); + }; + }; + + var createHmacMethod = function (is224) { + var method = createHmacOutputMethod('hex', is224); + method.create = function (key) { + return new HmacSha256(key, is224); + }; + method.update = function (key, message) { + return method.create(key).update(message); + }; + for (var i = 0; i < OUTPUT_TYPES.length; ++i) { + var type = OUTPUT_TYPES[i]; + method[type] = createHmacOutputMethod(type, is224); + } + return method; + }; + + function Sha256(is224, sharedMemory) { + if (sharedMemory) { + blocks[0] = + blocks[16] = + blocks[1] = + blocks[2] = + blocks[3] = + blocks[4] = + blocks[5] = + blocks[6] = + blocks[7] = + blocks[8] = + blocks[9] = + blocks[10] = + blocks[11] = + blocks[12] = + blocks[13] = + blocks[14] = + blocks[15] = + 0; + this.blocks = blocks; + } else { + this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + } + + if (is224) { + this.h0 = 0xc1059ed8; + this.h1 = 0x367cd507; + this.h2 = 0x3070dd17; + this.h3 = 0xf70e5939; + this.h4 = 0xffc00b31; + this.h5 = 0x68581511; + this.h6 = 0x64f98fa7; + this.h7 = 0xbefa4fa4; + } else { + // 256 + this.h0 = 0x6a09e667; + this.h1 = 0xbb67ae85; + this.h2 = 0x3c6ef372; + this.h3 = 0xa54ff53a; + this.h4 = 0x510e527f; + this.h5 = 0x9b05688c; + this.h6 = 0x1f83d9ab; + this.h7 = 0x5be0cd19; + } + + this.block = this.start = this.bytes = this.hBytes = 0; + this.finalized = this.hashed = false; + this.first = true; + this.is224 = is224; + } + + Sha256.prototype.update = function (message) { + if (this.finalized) { + return; + } + var notString, + type = typeof message; + if (type !== 'string') { + if (type === 'object') { + if (message === null) { + throw new Error(ERROR); + } else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) { + message = new Uint8Array(message); + } else if (!Array.isArray(message)) { + if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) { + throw new Error(ERROR); + } + } + } else { + throw new Error(ERROR); + } + notString = true; + } + var code, + index = 0, + i, + length = message.length, + blocks = this.blocks; + + while (index < length) { + if (this.hashed) { + this.hashed = false; + blocks[0] = this.block; + blocks[16] = + blocks[1] = + blocks[2] = + blocks[3] = + blocks[4] = + blocks[5] = + blocks[6] = + blocks[7] = + blocks[8] = + blocks[9] = + blocks[10] = + blocks[11] = + blocks[12] = + blocks[13] = + blocks[14] = + blocks[15] = + 0; + } + + if (notString) { + for (i = this.start; index < length && i < 64; ++index) { + blocks[i >> 2] |= message[index] << SHIFT[i++ & 3]; + } + } else { + for (i = this.start; index < length && i < 64; ++index) { + code = message.charCodeAt(index); + if (code < 0x80) { + blocks[i >> 2] |= code << SHIFT[i++ & 3]; + } else if (code < 0x800) { + blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } else if (code < 0xd800 || code >= 0xe000) { + blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } else { + code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff)); + blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; + blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; + } + } + } + + this.lastByteIndex = i; + this.bytes += i - this.start; + if (i >= 64) { + this.block = blocks[16]; + this.start = i - 64; + this.hash(); + this.hashed = true; + } else { + this.start = i; + } + } + if (this.bytes > 4294967295) { + this.hBytes += (this.bytes / 4294967296) << 0; + this.bytes = this.bytes % 4294967296; + } + return this; + }; + + Sha256.prototype.finalize = function () { + if (this.finalized) { + return; + } + this.finalized = true; + var blocks = this.blocks, + i = this.lastByteIndex; + blocks[16] = this.block; + blocks[i >> 2] |= EXTRA[i & 3]; + this.block = blocks[16]; + if (i >= 56) { + if (!this.hashed) { + this.hash(); + } + blocks[0] = this.block; + blocks[16] = + blocks[1] = + blocks[2] = + blocks[3] = + blocks[4] = + blocks[5] = + blocks[6] = + blocks[7] = + blocks[8] = + blocks[9] = + blocks[10] = + blocks[11] = + blocks[12] = + blocks[13] = + blocks[14] = + blocks[15] = + 0; + } + blocks[14] = (this.hBytes << 3) | (this.bytes >>> 29); + blocks[15] = this.bytes << 3; + this.hash(); + }; + + Sha256.prototype.hash = function () { + var a = this.h0, + b = this.h1, + c = this.h2, + d = this.h3, + e = this.h4, + f = this.h5, + g = this.h6, + h = this.h7, + blocks = this.blocks, + j, + s0, + s1, + maj, + t1, + t2, + ch, + ab, + da, + cd, + bc; + + for (j = 16; j < 64; ++j) { + // rightrotate + t1 = blocks[j - 15]; + s0 = ((t1 >>> 7) | (t1 << 25)) ^ ((t1 >>> 18) | (t1 << 14)) ^ (t1 >>> 3); + t1 = blocks[j - 2]; + s1 = ((t1 >>> 17) | (t1 << 15)) ^ ((t1 >>> 19) | (t1 << 13)) ^ (t1 >>> 10); + blocks[j] = (blocks[j - 16] + s0 + blocks[j - 7] + s1) << 0; + } + + bc = b & c; + for (j = 0; j < 64; j += 4) { + if (this.first) { + if (this.is224) { + ab = 300032; + t1 = blocks[0] - 1413257819; + h = (t1 - 150054599) << 0; + d = (t1 + 24177077) << 0; + } else { + ab = 704751109; + t1 = blocks[0] - 210244248; + h = (t1 - 1521486534) << 0; + d = (t1 + 143694565) << 0; + } + this.first = false; + } else { + s0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10)); + s1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7)); + ab = a & b; + maj = ab ^ (a & c) ^ bc; + ch = (e & f) ^ (~e & g); + t1 = h + s1 + ch + K[j] + blocks[j]; + t2 = s0 + maj; + h = (d + t1) << 0; + d = (t1 + t2) << 0; + } + s0 = ((d >>> 2) | (d << 30)) ^ ((d >>> 13) | (d << 19)) ^ ((d >>> 22) | (d << 10)); + s1 = ((h >>> 6) | (h << 26)) ^ ((h >>> 11) | (h << 21)) ^ ((h >>> 25) | (h << 7)); + da = d & a; + maj = da ^ (d & b) ^ ab; + ch = (h & e) ^ (~h & f); + t1 = g + s1 + ch + K[j + 1] + blocks[j + 1]; + t2 = s0 + maj; + g = (c + t1) << 0; + c = (t1 + t2) << 0; + s0 = ((c >>> 2) | (c << 30)) ^ ((c >>> 13) | (c << 19)) ^ ((c >>> 22) | (c << 10)); + s1 = ((g >>> 6) | (g << 26)) ^ ((g >>> 11) | (g << 21)) ^ ((g >>> 25) | (g << 7)); + cd = c & d; + maj = cd ^ (c & a) ^ da; + ch = (g & h) ^ (~g & e); + t1 = f + s1 + ch + K[j + 2] + blocks[j + 2]; + t2 = s0 + maj; + f = (b + t1) << 0; + b = (t1 + t2) << 0; + s0 = ((b >>> 2) | (b << 30)) ^ ((b >>> 13) | (b << 19)) ^ ((b >>> 22) | (b << 10)); + s1 = ((f >>> 6) | (f << 26)) ^ ((f >>> 11) | (f << 21)) ^ ((f >>> 25) | (f << 7)); + bc = b & c; + maj = bc ^ (b & d) ^ cd; + ch = (f & g) ^ (~f & h); + t1 = e + s1 + ch + K[j + 3] + blocks[j + 3]; + t2 = s0 + maj; + e = (a + t1) << 0; + a = (t1 + t2) << 0; + this.chromeBugWorkAround = true; + } + + this.h0 = (this.h0 + a) << 0; + this.h1 = (this.h1 + b) << 0; + this.h2 = (this.h2 + c) << 0; + this.h3 = (this.h3 + d) << 0; + this.h4 = (this.h4 + e) << 0; + this.h5 = (this.h5 + f) << 0; + this.h6 = (this.h6 + g) << 0; + this.h7 = (this.h7 + h) << 0; + }; + + Sha256.prototype.hex = function () { + this.finalize(); + + var h0 = this.h0, + h1 = this.h1, + h2 = this.h2, + h3 = this.h3, + h4 = this.h4, + h5 = this.h5, + h6 = this.h6, + h7 = this.h7; + + var hex = + HEX_CHARS[(h0 >> 28) & 0x0f] + + HEX_CHARS[(h0 >> 24) & 0x0f] + + HEX_CHARS[(h0 >> 20) & 0x0f] + + HEX_CHARS[(h0 >> 16) & 0x0f] + + HEX_CHARS[(h0 >> 12) & 0x0f] + + HEX_CHARS[(h0 >> 8) & 0x0f] + + HEX_CHARS[(h0 >> 4) & 0x0f] + + HEX_CHARS[h0 & 0x0f] + + HEX_CHARS[(h1 >> 28) & 0x0f] + + HEX_CHARS[(h1 >> 24) & 0x0f] + + HEX_CHARS[(h1 >> 20) & 0x0f] + + HEX_CHARS[(h1 >> 16) & 0x0f] + + HEX_CHARS[(h1 >> 12) & 0x0f] + + HEX_CHARS[(h1 >> 8) & 0x0f] + + HEX_CHARS[(h1 >> 4) & 0x0f] + + HEX_CHARS[h1 & 0x0f] + + HEX_CHARS[(h2 >> 28) & 0x0f] + + HEX_CHARS[(h2 >> 24) & 0x0f] + + HEX_CHARS[(h2 >> 20) & 0x0f] + + HEX_CHARS[(h2 >> 16) & 0x0f] + + HEX_CHARS[(h2 >> 12) & 0x0f] + + HEX_CHARS[(h2 >> 8) & 0x0f] + + HEX_CHARS[(h2 >> 4) & 0x0f] + + HEX_CHARS[h2 & 0x0f] + + HEX_CHARS[(h3 >> 28) & 0x0f] + + HEX_CHARS[(h3 >> 24) & 0x0f] + + HEX_CHARS[(h3 >> 20) & 0x0f] + + HEX_CHARS[(h3 >> 16) & 0x0f] + + HEX_CHARS[(h3 >> 12) & 0x0f] + + HEX_CHARS[(h3 >> 8) & 0x0f] + + HEX_CHARS[(h3 >> 4) & 0x0f] + + HEX_CHARS[h3 & 0x0f] + + HEX_CHARS[(h4 >> 28) & 0x0f] + + HEX_CHARS[(h4 >> 24) & 0x0f] + + HEX_CHARS[(h4 >> 20) & 0x0f] + + HEX_CHARS[(h4 >> 16) & 0x0f] + + HEX_CHARS[(h4 >> 12) & 0x0f] + + HEX_CHARS[(h4 >> 8) & 0x0f] + + HEX_CHARS[(h4 >> 4) & 0x0f] + + HEX_CHARS[h4 & 0x0f] + + HEX_CHARS[(h5 >> 28) & 0x0f] + + HEX_CHARS[(h5 >> 24) & 0x0f] + + HEX_CHARS[(h5 >> 20) & 0x0f] + + HEX_CHARS[(h5 >> 16) & 0x0f] + + HEX_CHARS[(h5 >> 12) & 0x0f] + + HEX_CHARS[(h5 >> 8) & 0x0f] + + HEX_CHARS[(h5 >> 4) & 0x0f] + + HEX_CHARS[h5 & 0x0f] + + HEX_CHARS[(h6 >> 28) & 0x0f] + + HEX_CHARS[(h6 >> 24) & 0x0f] + + HEX_CHARS[(h6 >> 20) & 0x0f] + + HEX_CHARS[(h6 >> 16) & 0x0f] + + HEX_CHARS[(h6 >> 12) & 0x0f] + + HEX_CHARS[(h6 >> 8) & 0x0f] + + HEX_CHARS[(h6 >> 4) & 0x0f] + + HEX_CHARS[h6 & 0x0f]; + if (!this.is224) { + hex += + HEX_CHARS[(h7 >> 28) & 0x0f] + + HEX_CHARS[(h7 >> 24) & 0x0f] + + HEX_CHARS[(h7 >> 20) & 0x0f] + + HEX_CHARS[(h7 >> 16) & 0x0f] + + HEX_CHARS[(h7 >> 12) & 0x0f] + + HEX_CHARS[(h7 >> 8) & 0x0f] + + HEX_CHARS[(h7 >> 4) & 0x0f] + + HEX_CHARS[h7 & 0x0f]; + } + return hex; + }; + + Sha256.prototype.toString = Sha256.prototype.hex; + + Sha256.prototype.digest = function () { + this.finalize(); + + var h0 = this.h0, + h1 = this.h1, + h2 = this.h2, + h3 = this.h3, + h4 = this.h4, + h5 = this.h5, + h6 = this.h6, + h7 = this.h7; + + var arr = [ + (h0 >> 24) & 0xff, + (h0 >> 16) & 0xff, + (h0 >> 8) & 0xff, + h0 & 0xff, + (h1 >> 24) & 0xff, + (h1 >> 16) & 0xff, + (h1 >> 8) & 0xff, + h1 & 0xff, + (h2 >> 24) & 0xff, + (h2 >> 16) & 0xff, + (h2 >> 8) & 0xff, + h2 & 0xff, + (h3 >> 24) & 0xff, + (h3 >> 16) & 0xff, + (h3 >> 8) & 0xff, + h3 & 0xff, + (h4 >> 24) & 0xff, + (h4 >> 16) & 0xff, + (h4 >> 8) & 0xff, + h4 & 0xff, + (h5 >> 24) & 0xff, + (h5 >> 16) & 0xff, + (h5 >> 8) & 0xff, + h5 & 0xff, + (h6 >> 24) & 0xff, + (h6 >> 16) & 0xff, + (h6 >> 8) & 0xff, + h6 & 0xff, + ]; + if (!this.is224) { + arr.push((h7 >> 24) & 0xff, (h7 >> 16) & 0xff, (h7 >> 8) & 0xff, h7 & 0xff); + } + return arr; + }; + + Sha256.prototype.array = Sha256.prototype.digest; + + Sha256.prototype.arrayBuffer = function () { + this.finalize(); + + var buffer = new ArrayBuffer(this.is224 ? 28 : 32); + var dataView = new DataView(buffer); + dataView.setUint32(0, this.h0); + dataView.setUint32(4, this.h1); + dataView.setUint32(8, this.h2); + dataView.setUint32(12, this.h3); + dataView.setUint32(16, this.h4); + dataView.setUint32(20, this.h5); + dataView.setUint32(24, this.h6); + if (!this.is224) { + dataView.setUint32(28, this.h7); + } + return buffer; + }; + + function HmacSha256(key, is224, sharedMemory) { + var i, + type = typeof key; + if (type === 'string') { + var bytes = [], + length = key.length, + index = 0, + code; + for (i = 0; i < length; ++i) { + code = key.charCodeAt(i); + if (code < 0x80) { + bytes[index++] = code; + } else if (code < 0x800) { + bytes[index++] = 0xc0 | (code >> 6); + bytes[index++] = 0x80 | (code & 0x3f); + } else if (code < 0xd800 || code >= 0xe000) { + bytes[index++] = 0xe0 | (code >> 12); + bytes[index++] = 0x80 | ((code >> 6) & 0x3f); + bytes[index++] = 0x80 | (code & 0x3f); + } else { + code = 0x10000 + (((code & 0x3ff) << 10) | (key.charCodeAt(++i) & 0x3ff)); + bytes[index++] = 0xf0 | (code >> 18); + bytes[index++] = 0x80 | ((code >> 12) & 0x3f); + bytes[index++] = 0x80 | ((code >> 6) & 0x3f); + bytes[index++] = 0x80 | (code & 0x3f); + } + } + key = bytes; + } else { + if (type === 'object') { + if (key === null) { + throw new Error(ERROR); + } else if (ARRAY_BUFFER && key.constructor === ArrayBuffer) { + key = new Uint8Array(key); + } else if (!Array.isArray(key)) { + if (!ARRAY_BUFFER || !ArrayBuffer.isView(key)) { + throw new Error(ERROR); + } + } + } else { + throw new Error(ERROR); + } + } + + if (key.length > 64) { + key = new Sha256(is224, true).update(key).array(); + } + + var oKeyPad = [], + iKeyPad = []; + for (i = 0; i < 64; ++i) { + var b = key[i] || 0; + oKeyPad[i] = 0x5c ^ b; + iKeyPad[i] = 0x36 ^ b; + } + + Sha256.call(this, is224, sharedMemory); + + this.update(iKeyPad); + this.oKeyPad = oKeyPad; + this.inner = true; + this.sharedMemory = sharedMemory; + } + HmacSha256.prototype = new Sha256(); + + HmacSha256.prototype.finalize = function () { + Sha256.prototype.finalize.call(this); + if (this.inner) { + this.inner = false; + var innerHash = this.array(); + Sha256.call(this, this.is224, this.sharedMemory); + this.update(this.oKeyPad); + this.update(innerHash); + Sha256.prototype.finalize.call(this); + } + }; + + var exports = createMethod(); + exports.sha256 = exports; + exports.sha224 = createMethod(true); + exports.sha256.hmac = createHmacMethod(); + exports.sha224.hmac = createHmacMethod(true); + + if (COMMON_JS) { + module.exports = exports; + } else { + root.sha256 = exports.sha256; + root.sha224 = exports.sha224; + if (AMD) { + define(function () { + return exports; + }); + } + } +})(); diff --git a/packages/sdk/react-native/src/react-native-sse/EventSource.ts b/packages/sdk/react-native/src/fromExternal/react-native-sse/EventSource.ts similarity index 100% rename from packages/sdk/react-native/src/react-native-sse/EventSource.ts rename to packages/sdk/react-native/src/fromExternal/react-native-sse/EventSource.ts diff --git a/packages/sdk/react-native/src/react-native-sse/LICENSE b/packages/sdk/react-native/src/fromExternal/react-native-sse/LICENSE similarity index 100% rename from packages/sdk/react-native/src/react-native-sse/LICENSE rename to packages/sdk/react-native/src/fromExternal/react-native-sse/LICENSE diff --git a/packages/sdk/react-native/src/react-native-sse/index.ts b/packages/sdk/react-native/src/fromExternal/react-native-sse/index.ts similarity index 100% rename from packages/sdk/react-native/src/react-native-sse/index.ts rename to packages/sdk/react-native/src/fromExternal/react-native-sse/index.ts diff --git a/packages/sdk/react-native/src/react-native-sse/types.ts b/packages/sdk/react-native/src/fromExternal/react-native-sse/types.ts similarity index 100% rename from packages/sdk/react-native/src/react-native-sse/types.ts rename to packages/sdk/react-native/src/fromExternal/react-native-sse/types.ts diff --git a/packages/sdk/react-native/src/platform/autoEnv.ts b/packages/sdk/react-native/src/platform/autoEnv.ts new file mode 100644 index 000000000..2aeaa7635 --- /dev/null +++ b/packages/sdk/react-native/src/platform/autoEnv.ts @@ -0,0 +1,40 @@ +import { Platform, type PlatformAndroidStatic } from 'react-native'; + +import type { LDApplication, LDDevice } from '@launchdarkly/js-client-sdk-common'; + +import locale from './locale'; + +export const ldApplication: LDApplication = { + // key is populated by client common sdk + key: '', + envAttributesVersion: '1.0', + + // TODO: populate application ID, name, version, versionName + id: '', + name: '', + version: '', + versionName: '', + locale, +}; + +export const ldDevice: LDDevice = { + // key is populated by client common sdk + key: '', + envAttributesVersion: '1.0', + manufacturer: Platform.select({ + ios: 'apple', + android: (Platform as PlatformAndroidStatic).constants.Manufacturer, + }), + model: Platform.select({ + // ios: model n/a from PlatformIOSStatic + android: (Platform as PlatformAndroidStatic).constants.Model, + }), + os: { + family: Platform.select({ + ios: 'apple', + default: Platform.OS, + }), + name: Platform.OS, + version: Platform.Version.toString(), + }, +}; diff --git a/packages/sdk/react-native/src/platform/crypto/PlatformHasher.test.ts b/packages/sdk/react-native/src/platform/crypto/PlatformHasher.test.ts new file mode 100644 index 000000000..38135983c --- /dev/null +++ b/packages/sdk/react-native/src/platform/crypto/PlatformHasher.test.ts @@ -0,0 +1,62 @@ +import PlatformHasher from './PlatformHasher'; + +/** + * The links below are different from js-sha256 and are useful to verify the + * correctness of hash and encoding output: + * https://www.liavaag.org/English/SHA-Generator/ + * https://www.liavaag.org/English/SHA-Generator/HMAC/ + */ +describe('PlatformHasher', () => { + test('sha256 produces correct base64 output', () => { + const h = new PlatformHasher('sha256'); + + h.update('test-app-id'); + const output = h.digest('base64'); + + expect(output).toEqual('XVm6ZNk6ejx6+IVtL7zfwYwRQ2/ck9+y7FaN32EcudQ='); + }); + + test('sha256 produces correct hex output', () => { + const h = new PlatformHasher('sha256'); + + h.update('test-app-id'); + const output = h.digest('hex'); + + expect(output).toEqual('5d59ba64d93a7a3c7af8856d2fbcdfc18c11436fdc93dfb2ec568ddf611cb9d4'); + }); + + test('unsupported hash algorithm', () => { + expect(() => { + // @ts-ignore + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const h = new PlatformHasher('sha1'); + }).toThrow(/unsupported/i); + }); + + test('unsupported output algorithm', () => { + expect(() => { + const h = new PlatformHasher('sha256'); + h.update('test-app-id'); + // @ts-ignore + h.digest('base122'); + }).toThrow(/unsupported/i); + }); + + test('hmac produces correct base64 output', () => { + const h = new PlatformHasher('sha256', 'hmac-key'); + + h.update('test-app-id'); + const output = h.digest('base64'); + + expect(output).toEqual('tB+++rKY29eF480Oe3ekuWk4AbXV2E8cTgk+UEB9xfA='); + }); + + test('hmac produces correct hex output', () => { + const h = new PlatformHasher('sha256', 'hmac-key'); + + h.update('test-app-id'); + const output = h.digest('hex'); + + expect(output).toEqual('b41fbefab298dbd785e3cd0e7b77a4b9693801b5d5d84f1c4e093e50407dc5f0'); + }); +}); diff --git a/packages/sdk/react-native/src/platform/crypto/PlatformHasher.ts b/packages/sdk/react-native/src/platform/crypto/PlatformHasher.ts new file mode 100644 index 000000000..081af2624 --- /dev/null +++ b/packages/sdk/react-native/src/platform/crypto/PlatformHasher.ts @@ -0,0 +1,37 @@ +import { Hasher as LDHasher } from '@launchdarkly/js-client-sdk-common'; + +import { Hasher, sha256 } from '../../fromExternal/js-sha256'; +import { base64FromByteArray } from '../../polyfills'; +import { SupportedHashAlgorithm, SupportedOutputEncoding } from './types'; + +export default class PlatformHasher implements LDHasher { + private hasher: Hasher; + + constructor(algorithm: SupportedHashAlgorithm, hmacKey?: string) { + switch (algorithm) { + case 'sha256': + this.hasher = hmacKey ? sha256.hmac.create(hmacKey) : sha256.create(); + break; + default: + throw new Error(`Unsupported hash algorithm: ${algorithm}. Only sha256 is supported.`); + } + } + + digest(encoding: SupportedOutputEncoding): string { + switch (encoding) { + case 'base64': + return base64FromByteArray(new Uint8Array(this.hasher.arrayBuffer())); + case 'hex': + return this.hasher.hex(); + default: + throw new Error( + `unsupported output encoding: ${encoding}. Only base64 and hex are supported.`, + ); + } + } + + update(data: string): this { + this.hasher.update(data); + return this; + } +} diff --git a/packages/sdk/react-native/src/platform/crypto/index.ts b/packages/sdk/react-native/src/platform/crypto/index.ts new file mode 100644 index 000000000..a4bfdd4dd --- /dev/null +++ b/packages/sdk/react-native/src/platform/crypto/index.ts @@ -0,0 +1,40 @@ +import type { Crypto, Hmac } from '@launchdarkly/js-client-sdk-common'; + +import PlatformHasher from './PlatformHasher'; +import { SupportedHashAlgorithm } from './types'; + +/* eslint-disable no-bitwise */ +/** + * To avoid dependencies on uuid, this is good enough for now. + * Ripped from the react-native repo: + * https://github.com/facebook/react-native/blob/main/packages/react-native/Libraries/Blob/BlobManager.js#L27 + * + * Based on the rfc4122-compliant solution posted at + * http://stackoverflow.com/questions/105034 + */ +function uuidv4(): string { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { + const r = (Math.random() * 16) | 0; + const v = c === 'x' ? r : (r & 0x3) | 0x8; + return v.toString(16); + }); +} + +/** + * Uses crypto-js as substitute to node:crypto because the latter + * is not yet supported in some runtimes. + * https://cryptojs.gitbook.io/docs/ + */ +export default class PlatformCrypto implements Crypto { + createHash(algorithm: SupportedHashAlgorithm): PlatformHasher { + return new PlatformHasher(algorithm); + } + + createHmac(algorithm: SupportedHashAlgorithm, key: string): Hmac { + return new PlatformHasher(algorithm, key); + } + + randomUUID(): string { + return uuidv4(); + } +} diff --git a/packages/sdk/react-native/src/platform/crypto/types.ts b/packages/sdk/react-native/src/platform/crypto/types.ts new file mode 100644 index 000000000..446d5f6df --- /dev/null +++ b/packages/sdk/react-native/src/platform/crypto/types.ts @@ -0,0 +1,2 @@ +export type SupportedHashAlgorithm = 'sha256'; +export type SupportedOutputEncoding = 'base64' | 'hex'; diff --git a/packages/sdk/react-native/src/platform/index.ts b/packages/sdk/react-native/src/platform/index.ts index ba2db6299..6e9e7a81c 100644 --- a/packages/sdk/react-native/src/platform/index.ts +++ b/packages/sdk/react-native/src/platform/index.ts @@ -1,12 +1,9 @@ /* eslint-disable max-classes-per-file */ import type { - Crypto, Encoding, EventName, EventSource, EventSourceInitDict, - Hasher, - Hmac, Info, LDLogger, Options, @@ -19,9 +16,11 @@ import type { } from '@launchdarkly/js-client-sdk-common'; import { name, version } from '../../package.json'; -import { btoa, uuidv4 } from '../polyfills'; -import RNEventSource from '../react-native-sse'; +import RNEventSource from '../fromExternal/react-native-sse'; +import { btoa } from '../polyfills'; +import { ldApplication, ldDevice } from './autoEnv'; import AsyncStorage from './ConditionalAsyncStorage'; +import PlatformCrypto from './crypto'; class PlatformRequests implements Requests { createEventSource(url: string, eventSourceInitDict: EventSourceInitDict): EventSource { @@ -43,32 +42,28 @@ class PlatformEncoding implements Encoding { } class PlatformInfo implements Info { + constructor(private readonly logger: LDLogger) {} + platformData(): PlatformData { - return { + const data = { name: 'React Native', + ld_application: ldApplication, + ld_device: ldDevice, }; + + this.logger.debug(`platformData: ${JSON.stringify(data, null, 2)}`); + return data; } sdkData(): SdkData { - return { + const data = { name, version, userAgentBase: 'ReactNativeClient', }; - } -} - -class PlatformCrypto implements Crypto { - createHash(_algorithm: string): Hasher { - throw new Error('not implemented'); - } - - createHmac(_algorithm: string, _key: string): Hmac { - throw new Error('not implemented'); - } - randomUUID(): string { - return uuidv4(); + this.logger.debug(`sdkData: ${JSON.stringify(data, null, 2)}`); + return data; } } @@ -99,7 +94,7 @@ class PlatformStorage implements Storage { const createPlatform = (logger: LDLogger): Platform => ({ crypto: new PlatformCrypto(), - info: new PlatformInfo(), + info: new PlatformInfo(logger), requests: new PlatformRequests(), encoding: new PlatformEncoding(), storage: new PlatformStorage(logger), diff --git a/packages/sdk/react-native/src/platform/locale.ts b/packages/sdk/react-native/src/platform/locale.ts new file mode 100644 index 000000000..d5a5fab5e --- /dev/null +++ b/packages/sdk/react-native/src/platform/locale.ts @@ -0,0 +1,12 @@ +import { NativeModules, Platform } from 'react-native'; + +/** + * Ripped from: + * https://dev.to/medaimane/localization-and-internationalization-in-react-native-reaching-global-audiences-3acj + */ +const locale = + Platform.OS === 'ios' + ? NativeModules.SettingsManager.settings.AppleLocale // iOS + : NativeModules.I18nManager.localeIdentifier; // Android and rest + +export default locale; diff --git a/packages/sdk/react-native/src/polyfills/btoa.ts b/packages/sdk/react-native/src/polyfills/btoa.ts index 944ce41c9..d9b29bfac 100644 --- a/packages/sdk/react-native/src/polyfills/btoa.ts +++ b/packages/sdk/react-native/src/polyfills/btoa.ts @@ -8,6 +8,10 @@ function convertToByteArray(s: string) { return Uint8Array.from(b); } -export default function btoa(s: string) { +export function btoa(s: string) { return fromByteArray(convertToByteArray(s)); } + +export function base64FromByteArray(a: Uint8Array) { + return fromByteArray(a); +} diff --git a/packages/sdk/react-native/src/polyfills/index.ts b/packages/sdk/react-native/src/polyfills/index.ts index bf2bac134..03e1b11fe 100644 --- a/packages/sdk/react-native/src/polyfills/index.ts +++ b/packages/sdk/react-native/src/polyfills/index.ts @@ -1,8 +1,8 @@ import EventTarget from 'event-target-shim'; -import btoa from './btoa'; +import { type Hasher, sha256 } from '../fromExternal/js-sha256'; +import { base64FromByteArray, btoa } from './btoa'; import CustomEvent from './CustomEvent'; -import uuidv4 from './uuid'; function setupPolyfill() { Object.assign(global, { @@ -10,4 +10,4 @@ function setupPolyfill() { CustomEvent, }); } -export { btoa, setupPolyfill, uuidv4 }; +export { base64FromByteArray, btoa, type Hasher, setupPolyfill, sha256 }; diff --git a/packages/sdk/react-native/src/provider/LDProvider.test.tsx b/packages/sdk/react-native/src/provider/LDProvider.test.tsx index 146e4673c..548aec1e8 100644 --- a/packages/sdk/react-native/src/provider/LDProvider.test.tsx +++ b/packages/sdk/react-native/src/provider/LDProvider.test.tsx @@ -1,6 +1,6 @@ import { render } from '@testing-library/react'; -import type { LDContext, LDOptions } from '@launchdarkly/js-client-sdk-common'; +import { AutoEnvAttributes, LDContext, LDOptions } from '@launchdarkly/js-client-sdk-common'; import { useLDClient } from '../hooks'; import ReactNativeLDClient from '../ReactNativeLDClient'; @@ -23,21 +23,22 @@ const TestApp = () => { describe('LDProvider', () => { let ldc: ReactNativeLDClient; let context: LDContext; - let mockSetupListeners = setupListeners as jest.Mock; + const mockSetupListeners = setupListeners as jest.Mock; beforeEach(() => { jest.useFakeTimers(); (ReactNativeLDClient as jest.Mock).mockImplementation( - (mobileKey: string, _options?: LDOptions) => { - let context: LDContext; + (mobileKey: string, autoEnvAttributes: AutoEnvAttributes, _options?: LDOptions) => { + let internalCachedContext: LDContext; return { sdkKey: mobileKey, + autoEnvAttributes, identify: jest.fn((c: LDContext) => { - context = c; + internalCachedContext = c; return Promise.resolve(); }), - getContext: jest.fn(() => context), + getContext: jest.fn(() => internalCachedContext), on: jest.fn(), logger: { debug: jest.fn(), @@ -48,7 +49,7 @@ describe('LDProvider', () => { mockSetupListeners.mockImplementation((client: ReactNativeLDClient, setState: any) => { setState({ client }); }); - ldc = new ReactNativeLDClient('mobile-key'); + ldc = new ReactNativeLDClient('mobile-key', AutoEnvAttributes.Enabled); context = { kind: 'user', key: 'test-user-key-1' }; }); @@ -82,10 +83,10 @@ describe('LDProvider', () => { }); test('identify errors are caught', async () => { - (ldc.identify as jest.Mock).mockImplementation(() => { - return Promise.reject('faking error when identifying'); - }); - const { getByText } = render( + (ldc.identify as jest.Mock).mockImplementation(() => + Promise.reject(new Error('faking error when identifying')), + ); + render( , diff --git a/packages/sdk/react-native/src/provider/setupListeners.test.ts b/packages/sdk/react-native/src/provider/setupListeners.test.ts index 763195e00..4d6878a29 100644 --- a/packages/sdk/react-native/src/provider/setupListeners.test.ts +++ b/packages/sdk/react-native/src/provider/setupListeners.test.ts @@ -1,3 +1,5 @@ +import { AutoEnvAttributes } from '@launchdarkly/js-client-sdk-common'; + import ReactNativeLDClient from '../ReactNativeLDClient'; import setupListeners from './setupListeners'; @@ -11,7 +13,7 @@ describe('setupListeners', () => { beforeEach(() => { mockSetState = jest.fn(); - ldc = new ReactNativeLDClient('mob-test-key'); + ldc = new ReactNativeLDClient('mob-test-key', AutoEnvAttributes.Enabled); }); afterEach(() => resetAllMocks()); diff --git a/packages/sdk/react-native/tsconfig.eslint.json b/packages/sdk/react-native/tsconfig.eslint.json index 56c9b3830..8241f86c3 100644 --- a/packages/sdk/react-native/tsconfig.eslint.json +++ b/packages/sdk/react-native/tsconfig.eslint.json @@ -1,5 +1,5 @@ { "extends": "./tsconfig.json", - "include": ["/**/*.ts"], + "include": ["/**/*.ts", "/**/*.tsx"], "exclude": ["node_modules"] } diff --git a/packages/sdk/react-native/tsconfig.json b/packages/sdk/react-native/tsconfig.json index e5a9204be..275a512e7 100644 --- a/packages/sdk/react-native/tsconfig.json +++ b/packages/sdk/react-native/tsconfig.json @@ -18,7 +18,16 @@ "strict": true, "stripInternal": true, "target": "ES2017", - "types": ["node"] + "types": ["node", "jest"], + "allowJs": true }, - "exclude": ["**/*.test.ts*", "dist", "node_modules", "__tests__", "example"] + "exclude": [ + "jest.config.ts", + "jestSetupFile.ts", + "**/*.test.ts*", + "dist", + "node_modules", + "__tests__", + "example" + ] } diff --git a/packages/sdk/server-node/package.json b/packages/sdk/server-node/package.json index d4071fd22..6e5358eb5 100644 --- a/packages/sdk/server-node/package.json +++ b/packages/sdk/server-node/package.json @@ -53,13 +53,14 @@ "@launchdarkly/private-js-mocks": "0.0.1", "@trivago/prettier-plugin-sort-imports": "^4.1.1", "@types/jest": "^29.4.0", - "@typescript-eslint/eslint-plugin": "^6.1.0", - "@typescript-eslint/parser": "^6.1.0", + "@typescript-eslint/eslint-plugin": "^6.20.0", + "@typescript-eslint/parser": "^6.20.0", "eslint": "^8.45.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^17.1.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jest": "^27.6.3", "eslint-plugin-prettier": "^5.0.0", "jest": "^29.5.0", "launchdarkly-js-test-helpers": "^2.2.0", diff --git a/packages/sdk/vercel/package.json b/packages/sdk/vercel/package.json index cc74cc086..0d98b507b 100644 --- a/packages/sdk/vercel/package.json +++ b/packages/sdk/vercel/package.json @@ -44,13 +44,14 @@ "@trivago/prettier-plugin-sort-imports": "^4.1.1", "@types/crypto-js": "^4.1.1", "@types/jest": "^29.5.0", - "@typescript-eslint/eslint-plugin": "^6.1.0", - "@typescript-eslint/parser": "^6.1.0", + "@typescript-eslint/eslint-plugin": "^6.20.0", + "@typescript-eslint/parser": "^6.20.0", "eslint": "^8.45.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^17.1.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jest": "^27.6.3", "eslint-plugin-prettier": "^5.0.0", "jest": "^29.5.0", "launchdarkly-js-test-helpers": "^2.2.0", diff --git a/packages/shared/akamai-edgeworker-sdk/package.json b/packages/shared/akamai-edgeworker-sdk/package.json index 644e3b306..33f310ef8 100644 --- a/packages/shared/akamai-edgeworker-sdk/package.json +++ b/packages/shared/akamai-edgeworker-sdk/package.json @@ -35,13 +35,14 @@ "@trivago/prettier-plugin-sort-imports": "^4.1.1", "@types/crypto-js": "^4.1.1", "@types/jest": "^29.5.1", - "@typescript-eslint/eslint-plugin": "^6.1.0", - "@typescript-eslint/parser": "^6.1.0", + "@typescript-eslint/eslint-plugin": "^6.20.0", + "@typescript-eslint/parser": "^6.20.0", "eslint": "^8.45.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^17.1.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jest": "^27.6.3", "eslint-plugin-prettier": "^5.0.0", "jest": "^29.5.0", "launchdarkly-js-test-helpers": "^2.2.0", diff --git a/packages/shared/common/package.json b/packages/shared/common/package.json index bb2820864..0c91bae85 100644 --- a/packages/shared/common/package.json +++ b/packages/shared/common/package.json @@ -33,13 +33,14 @@ "@launchdarkly/private-js-mocks": "0.0.1", "@trivago/prettier-plugin-sort-imports": "^4.1.1", "@types/jest": "^29.4.0", - "@typescript-eslint/eslint-plugin": "^6.1.0", - "@typescript-eslint/parser": "^6.1.0", + "@typescript-eslint/eslint-plugin": "^6.20.0", + "@typescript-eslint/parser": "^6.20.0", "eslint": "^8.45.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^17.1.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jest": "^27.6.3", "eslint-plugin-prettier": "^5.0.0", "jest": "^29.5.0", "launchdarkly-js-test-helpers": "^2.2.0", diff --git a/packages/shared/mocks/package.json b/packages/shared/mocks/package.json index 4981ad1a6..b997dd97e 100644 --- a/packages/shared/mocks/package.json +++ b/packages/shared/mocks/package.json @@ -40,13 +40,14 @@ "devDependencies": { "@trivago/prettier-plugin-sort-imports": "^4.2.0", "@types/jest": "^29.5.5", - "@typescript-eslint/eslint-plugin": "^6.7.3", - "@typescript-eslint/parser": "^6.7.3", + "@typescript-eslint/eslint-plugin": "^6.20.0", + "@typescript-eslint/parser": "^6.20.0", "eslint": "^8.50.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^17.1.0", "eslint-config-prettier": "^9.0.0", "eslint-plugin-import": "^2.28.1", + "eslint-plugin-jest": "^27.6.3", "eslint-plugin-prettier": "^5.0.0", "jest": "^29.7.0", "launchdarkly-js-test-helpers": "^2.2.0", diff --git a/packages/shared/mocks/src/platform.ts b/packages/shared/mocks/src/platform.ts index 24bcc0016..3f64c34ea 100644 --- a/packages/shared/mocks/src/platform.ts +++ b/packages/shared/mocks/src/platform.ts @@ -1,4 +1,4 @@ -import type { Encoding, Info, Platform, PlatformData, Requests, SdkData, Storage } from '@common'; +import type { Encoding, Platform, PlatformData, Requests, SdkData, Storage } from '@common'; import { setupCrypto } from './crypto'; diff --git a/packages/shared/sdk-client/package.json b/packages/shared/sdk-client/package.json index 485241a89..8dc7f3254 100644 --- a/packages/shared/sdk-client/package.json +++ b/packages/shared/sdk-client/package.json @@ -38,13 +38,14 @@ "@testing-library/jest-dom": "^5.16.5", "@types/jest": "^29.5.3", "@types/semver": "^7.5.0", - "@typescript-eslint/eslint-plugin": "^6.1.0", - "@typescript-eslint/parser": "^6.1.0", + "@typescript-eslint/eslint-plugin": "^6.20.0", + "@typescript-eslint/parser": "^6.20.0", "eslint": "^8.45.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^17.1.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jest": "^27.6.3", "eslint-plugin-prettier": "^5.0.0", "jest": "^29.6.1", "jest-diff": "^29.6.1", diff --git a/packages/shared/sdk-server-edge/package.json b/packages/shared/sdk-server-edge/package.json index 673a72e4e..0c037cc9b 100644 --- a/packages/shared/sdk-server-edge/package.json +++ b/packages/shared/sdk-server-edge/package.json @@ -44,14 +44,15 @@ "@trivago/prettier-plugin-sort-imports": "^4.1.1", "@types/crypto-js": "^4.1.1", "@types/jest": "^29.5.0", - "@typescript-eslint/eslint-plugin": "^6.1.0", - "@typescript-eslint/parser": "^6.1.0", + "@typescript-eslint/eslint-plugin": "^6.20.0", + "@typescript-eslint/parser": "^6.20.0", "esbuild": "^0.17.17", "eslint": "^8.45.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^17.1.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jest": "^27.6.3", "eslint-plugin-prettier": "^5.0.0", "jest": "^29.5.0", "launchdarkly-js-test-helpers": "^2.2.0", diff --git a/packages/shared/sdk-server/__tests__/store/serialization.test.ts b/packages/shared/sdk-server/__tests__/store/serialization.test.ts index a18ac959d..4656ea551 100644 --- a/packages/shared/sdk-server/__tests__/store/serialization.test.ts +++ b/packages/shared/sdk-server/__tests__/store/serialization.test.ts @@ -196,7 +196,7 @@ describe('when deserializing all data', () => { expect(ref?.isValid).toBeTruthy(); }); - it('handles a flag with an attribute literal in a clause', () => { + it('handles a flag with an attribute ref in a clause', () => { const jsonString = makeSerializedAllData(flagWithAttributeReferenceInClause); const parsed = deserializeAll(jsonString); const ref = parsed?.data.flags.flagName.rules?.[0].clauses?.[0].attributeReference; @@ -249,7 +249,7 @@ describe('when deserializing patch data', () => { expect(ref?.isValid).toBeTruthy(); }); - it('handles a flag with an attribute literal in a clause', () => { + it('handles a flag with an attribute ref in a clause', () => { const jsonString = makeSerializedPatchData(flagWithAttributeReferenceInClause); const parsed = deserializePatch(jsonString); const ref = (parsed?.data as Flag).rules?.[0].clauses?.[0].attributeReference; diff --git a/packages/shared/sdk-server/package.json b/packages/shared/sdk-server/package.json index 4296f9f81..cd68faa70 100644 --- a/packages/shared/sdk-server/package.json +++ b/packages/shared/sdk-server/package.json @@ -35,13 +35,14 @@ "@trivago/prettier-plugin-sort-imports": "^4.1.1", "@types/jest": "^29.4.0", "@types/semver": "^7.3.13", - "@typescript-eslint/eslint-plugin": "^6.1.0", - "@typescript-eslint/parser": "^6.1.0", + "@typescript-eslint/eslint-plugin": "^6.20.0", + "@typescript-eslint/parser": "^6.20.0", "eslint": "^8.45.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^17.1.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jest": "^27.6.3", "eslint-plugin-prettier": "^5.0.0", "jest": "^29.5.0", "jest-diff": "^28.1.1", diff --git a/packages/store/node-server-sdk-dynamodb/package.json b/packages/store/node-server-sdk-dynamodb/package.json index eeacbd2cc..e996c24d4 100644 --- a/packages/store/node-server-sdk-dynamodb/package.json +++ b/packages/store/node-server-sdk-dynamodb/package.json @@ -38,8 +38,8 @@ "@launchdarkly/node-server-sdk": "9.0.6", "@trivago/prettier-plugin-sort-imports": "^4.1.1", "@types/jest": "^29.4.0", - "@typescript-eslint/eslint-plugin": "^6.1.0", - "@typescript-eslint/parser": "^6.1.0", + "@typescript-eslint/eslint-plugin": "^6.20.0", + "@typescript-eslint/parser": "^6.20.0", "eslint": "^8.45.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^17.1.0", diff --git a/packages/store/node-server-sdk-redis/package.json b/packages/store/node-server-sdk-redis/package.json index 02ac3f8c2..f4e835384 100644 --- a/packages/store/node-server-sdk-redis/package.json +++ b/packages/store/node-server-sdk-redis/package.json @@ -36,8 +36,8 @@ "@launchdarkly/node-server-sdk": "9.0.6", "@trivago/prettier-plugin-sort-imports": "^4.1.1", "@types/jest": "^29.4.0", - "@typescript-eslint/eslint-plugin": "^6.1.0", - "@typescript-eslint/parser": "^6.1.0", + "@typescript-eslint/eslint-plugin": "^6.20.0", + "@typescript-eslint/parser": "^6.20.0", "eslint": "^8.45.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-typescript": "^17.1.0",