From 3eea75387b1dab3a4a2f5b81d71e815a6f1c6e51 Mon Sep 17 00:00:00 2001 From: Md Junaed Hossain <169046794+junaed-optimizely@users.noreply.github.com> Date: Tue, 8 Oct 2024 18:23:43 +0600 Subject: [PATCH 01/11] Prepared the pipeline for 5.x.x --- .github/workflows/integration_test.yml | 4 ++-- .github/workflows/javascript.yml | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 6b73ba748..048ad11c9 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -37,7 +37,7 @@ jobs: SDK: javascript FULLSTACK_TEST_REPO: ${{ inputs.FULLSTACK_TEST_REPO }} BUILD_NUMBER: ${{ github.run_id }} - TESTAPP_BRANCH: master + TESTAPP_BRANCH: test-5.x.x GITHUB_TOKEN: ${{ secrets.CI_USER_TOKEN }} EVENT_TYPE: ${{ github.event_name }} GITHUB_CONTEXT: ${{ toJson(github) }} @@ -53,4 +53,4 @@ jobs: run: | CLIENT=node home/runner/travisci-tools/trigger-script-with-status-update.sh # Run only browser builds when it's FSC not for FPS. - [ "$FULLSTACK_TEST_REPO" == "ProdTesting" ] || CLIENT=browser home/runner/travisci-tools/trigger-script-with-status-update.sh \ No newline at end of file + [ "$FULLSTACK_TEST_REPO" == "ProdTesting" ] || CLIENT=browser home/runner/travisci-tools/trigger-script-with-status-update.sh diff --git a/.github/workflows/javascript.yml b/.github/workflows/javascript.yml index cf3f8c49f..73e3aa048 100644 --- a/.github/workflows/javascript.yml +++ b/.github/workflows/javascript.yml @@ -2,13 +2,13 @@ name: Javascript on: push: - branches: [ master ] + branches: [ 5.x.x ] pull_request: - branches: [ master ] + branches: [ 5.x.x ] jobs: lint_markdown_files: - uses: optimizely/javascript-sdk/.github/workflows/lint_markdown.yml@master + uses: optimizely/javascript-sdk/.github/workflows/lint_markdown.yml@5.x.x lint: runs-on: ubuntu-latest @@ -27,13 +27,13 @@ jobs: npm run lint integration_tests: - uses: optimizely/javascript-sdk/.github/workflows/integration_test.yml@master + uses: optimizely/javascript-sdk/.github/workflows/integration_test.yml@5.x.x secrets: CI_USER_TOKEN: ${{ secrets.CI_USER_TOKEN }} TRAVIS_COM_TOKEN: ${{ secrets.TRAVIS_COM_TOKEN }} fullstack_production_suite: - uses: optimizely/javascript-sdk/.github/workflows/integration_test.yml@master + uses: optimizely/javascript-sdk/.github/workflows/integration_test.yml@5.x.x with: FULLSTACK_TEST_REPO: ProdTesting secrets: From 8f572ff6ecc2be713154ec2071dc3f3dbb0b3020 Mon Sep 17 00:00:00 2001 From: Md Junaed Hossain <169046794+junaed-optimizely@users.noreply.github.com> Date: Wed, 9 Oct 2024 22:32:52 +0600 Subject: [PATCH 02/11] [FSSDK-10586] rollout experiment key returns wrong decision (#949) --- lib/core/decision_service/index.tests.js | 4 ++++ lib/core/project_config/index.ts | 1 + lib/optimizely/index.ts | 2 +- lib/shared_types.ts | 1 + lib/tests/test_data.js | 5 +++++ 5 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/core/decision_service/index.tests.js b/lib/core/decision_service/index.tests.js index ba0dd5fbb..f61d67630 100644 --- a/lib/core/decision_service/index.tests.js +++ b/lib/core/decision_service/index.tests.js @@ -1675,6 +1675,7 @@ describe('lib/core/decision_service', function() { status: 'Not started', key: '594031', id: '594031', + isRollout: true, variations: [ { id: '594032', @@ -1812,6 +1813,7 @@ describe('lib/core/decision_service', function() { status: 'Not started', key: '594037', id: '594037', + isRollout: true, variations: [ { id: '594038', @@ -1996,6 +1998,7 @@ describe('lib/core/decision_service', function() { status: 'Not started', key: '594037', id: '594037', + isRollout: true, variations: [ { id: '594038', @@ -2150,6 +2153,7 @@ describe('lib/core/decision_service', function() { layerId: '599055', forcedVariations: {}, audienceIds: [], + isRollout: true, variations: [ { key: '599057', diff --git a/lib/core/project_config/index.ts b/lib/core/project_config/index.ts index 68ffbeacd..a52b46efa 100644 --- a/lib/core/project_config/index.ts +++ b/lib/core/project_config/index.ts @@ -167,6 +167,7 @@ export const createProjectConfig = function(datafileObj?: JSON, datafileStr: str projectConfig.rolloutIdMap = keyBy(projectConfig.rollouts || [], 'id'); objectValues(projectConfig.rolloutIdMap || {}).forEach(rollout => { (rollout.experiments || []).forEach(experiment => { + experiment.isRollout = true projectConfig.experiments.push(experiment); // Creates { : } map inside of the experiment experiment.variationKeyMap = keyBy(experiment.variations, 'key'); diff --git a/lib/optimizely/index.ts b/lib/optimizely/index.ts index 2a3eb5a0d..8605adec0 100644 --- a/lib/optimizely/index.ts +++ b/lib/optimizely/index.ts @@ -479,7 +479,7 @@ export default class Optimizely implements Client { } const experiment = configObj.experimentKeyMap[experimentKey]; - if (!experiment) { + if (!experiment || experiment.isRollout) { this.logger.log(LOG_LEVEL.DEBUG, ERROR_MESSAGES.INVALID_EXPERIMENT_KEY, MODULE_NAME, experimentKey); return null; } diff --git a/lib/shared_types.ts b/lib/shared_types.ts index 08291ecf2..495051866 100644 --- a/lib/shared_types.ts +++ b/lib/shared_types.ts @@ -178,6 +178,7 @@ export interface Experiment { audienceIds: string[]; trafficAllocation: TrafficAllocation[]; forcedVariations?: { [key: string]: string }; + isRollout?: boolean; } export enum VariableType { diff --git a/lib/tests/test_data.js b/lib/tests/test_data.js index eddf1a3fd..eb38fa6cf 100644 --- a/lib/tests/test_data.js +++ b/lib/tests/test_data.js @@ -1647,6 +1647,7 @@ export var datafileWithFeaturesExpectedData = { status: 'Not started', key: '599056', id: '599056', + isRollout: true, variationKeyMap: { 599057: { key: '599057', @@ -1711,6 +1712,7 @@ export var datafileWithFeaturesExpectedData = { ], key: '594031', id: '594031', + isRollout: true, variationKeyMap: { 594032: { variables: [ @@ -1783,6 +1785,7 @@ export var datafileWithFeaturesExpectedData = { ], key: '594037', id: '594037', + isRollout: true, variationKeyMap: { 594038: { variables: [ @@ -1856,6 +1859,7 @@ export var datafileWithFeaturesExpectedData = { ], key: '594060', id: '594060', + isRollout: true, variationKeyMap: { 594061: { variables: [ @@ -1920,6 +1924,7 @@ export var datafileWithFeaturesExpectedData = { ], key: '594066', id: '594066', + isRollout: true, variationKeyMap: { 594067: { variables: [ From 617fa351af3433b4e3beea1b1d244911c4c376c0 Mon Sep 17 00:00:00 2001 From: Md Junaed Hossain <169046794+junaed-optimizely@users.noreply.github.com> Date: Wed, 29 Jan 2025 19:54:24 +0600 Subject: [PATCH 03/11] [FSSDK-11098] using readyPromise instead of onReady (#995) --- lib/index.browser.tests.js | 4 ++++ lib/optimizely_user_context/index.ts | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/index.browser.tests.js b/lib/index.browser.tests.js index e14b91463..115c337a7 100644 --- a/lib/index.browser.tests.js +++ b/lib/index.browser.tests.js @@ -584,6 +584,10 @@ describe('javascript-sdk (Browser)', function() { const fakeOptimizely = { onReady: () => Promise.resolve({ success: true }), identifyUser: sinon.stub().returns(), + isOdpIntegrated: () => true, + readyPromise: Promise.resolve({ + success: true, + }), }; const fakeErrorHandler = { handleError: function() {} }; diff --git a/lib/optimizely_user_context/index.ts b/lib/optimizely_user_context/index.ts index 0b689237a..b9939ae51 100644 --- a/lib/optimizely_user_context/index.ts +++ b/lib/optimizely_user_context/index.ts @@ -64,8 +64,10 @@ export default class OptimizelyUserContext implements IOptimizelyUserContext { this.forcedDecisionsMap = {}; if (shouldIdentifyUser) { - this.optimizely.onReady().then(({ success }) => { - if (success) { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + optimizely.readyPromise.then(({ success }) => { + if (success && optimizely.isOdpIntegrated()) { this.identifyUser(); } }); From 90ef0d736a314ef8cbcbf2f08202fde598090333 Mon Sep 17 00:00:00 2001 From: Md Junaed Hossain <169046794+junaed-optimizely@users.noreply.github.com> Date: Wed, 29 Jan 2025 20:28:54 +0600 Subject: [PATCH 04/11] [FSSDK-11098] prep for release (#996) --- CHANGELOG.md | 6 ++++++ lib/index.browser.tests.js | 2 +- lib/index.lite.tests.js | 2 +- lib/index.node.tests.js | 2 +- lib/utils/enums/index.ts | 2 +- package-lock.json | 4 ++-- package.json | 2 +- tests/index.react_native.spec.ts | 2 +- 8 files changed, 14 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0fd73fdf..abbb80136 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [5.3.5] - Jan 29, 2025 + +### Bug Fixes +- Rollout experiment key exclusion from activate method([#949](https://github.com/optimizely/javascript-sdk/pull/949)) +- Using `optimizely.readyPromise` instead of `optimizely.onReady` to avoid setTimeout call in edge environments. ([#995](https://github.com/optimizely/javascript-sdk/pull/995)) + ## [5.3.4] - Jun 28, 2024 ### Changed diff --git a/lib/index.browser.tests.js b/lib/index.browser.tests.js index 115c337a7..a01e60ef0 100644 --- a/lib/index.browser.tests.js +++ b/lib/index.browser.tests.js @@ -193,7 +193,7 @@ describe('javascript-sdk (Browser)', function() { optlyInstance.onReady().catch(function() {}); assert.instanceOf(optlyInstance, Optimizely); - assert.equal(optlyInstance.clientVersion, '5.3.4'); + assert.equal(optlyInstance.clientVersion, '5.3.5'); }); it('should set the JavaScript client engine and version', function() { diff --git a/lib/index.lite.tests.js b/lib/index.lite.tests.js index 30282dcf5..5eaaf80cc 100644 --- a/lib/index.lite.tests.js +++ b/lib/index.lite.tests.js @@ -76,7 +76,7 @@ describe('optimizelyFactory', function() { optlyInstance.onReady().catch(function() {}); assert.instanceOf(optlyInstance, Optimizely); - assert.equal(optlyInstance.clientVersion, '5.3.4'); + assert.equal(optlyInstance.clientVersion, '5.3.5'); }); }); }); diff --git a/lib/index.node.tests.js b/lib/index.node.tests.js index 98aac4c97..f66dc0b69 100644 --- a/lib/index.node.tests.js +++ b/lib/index.node.tests.js @@ -90,7 +90,7 @@ describe('optimizelyFactory', function() { optlyInstance.onReady().catch(function() {}); assert.instanceOf(optlyInstance, Optimizely); - assert.equal(optlyInstance.clientVersion, '5.3.4'); + assert.equal(optlyInstance.clientVersion, '5.3.5'); }); describe('event processor configuration', function() { diff --git a/lib/utils/enums/index.ts b/lib/utils/enums/index.ts index 962d06c30..404bca534 100644 --- a/lib/utils/enums/index.ts +++ b/lib/utils/enums/index.ts @@ -221,7 +221,7 @@ export const NODE_CLIENT_ENGINE = 'node-sdk'; export const REACT_CLIENT_ENGINE = 'react-sdk'; export const REACT_NATIVE_CLIENT_ENGINE = 'react-native-sdk'; export const REACT_NATIVE_JS_CLIENT_ENGINE = 'react-native-js-sdk'; -export const CLIENT_VERSION ='5.3.4' +export const CLIENT_VERSION ='5.3.5' export const DECISION_NOTIFICATION_TYPES = { AB_TEST: 'ab-test', diff --git a/package-lock.json b/package-lock.json index 28b366dc1..35bbbae1a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@optimizely/optimizely-sdk", - "version": "5.3.4", + "version": "5.3.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@optimizely/optimizely-sdk", - "version": "5.3.4", + "version": "5.3.5", "license": "Apache-2.0", "dependencies": { "decompress-response": "^4.2.1", diff --git a/package.json b/package.json index 75d8fe42e..1b93e7539 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@optimizely/optimizely-sdk", - "version": "5.3.4", + "version": "5.3.5", "description": "JavaScript SDK for Optimizely Feature Experimentation, Optimizely Full Stack (legacy), and Optimizely Rollouts", "module": "dist/optimizely.browser.es.js", "main": "dist/optimizely.node.min.js", diff --git a/tests/index.react_native.spec.ts b/tests/index.react_native.spec.ts index a11f40c32..11bed1752 100644 --- a/tests/index.react_native.spec.ts +++ b/tests/index.react_native.spec.ts @@ -93,7 +93,7 @@ describe('javascript-sdk/react-native', () => { expect(optlyInstance).toBeInstanceOf(Optimizely); // @ts-ignore - expect(optlyInstance.clientVersion).toEqual('5.3.4'); + expect(optlyInstance.clientVersion).toEqual('5.3.5'); }); it('should set the React Native JS client engine and javascript SDK version', () => { From a204cb7ca21b615e47e0815e3f1249ca756c7e20 Mon Sep 17 00:00:00 2001 From: Md Junaed Hossain <169046794+junaed-optimizely@users.noreply.github.com> Date: Tue, 6 May 2025 18:16:02 +0600 Subject: [PATCH 05/11] [FSSDK-11197] EventTags type fix for v5 (#1040) --- lib/core/event_builder/build_event_v1.ts | 8 ++------ lib/modules/event_processor/events.ts | 6 ++---- lib/modules/event_processor/v1/buildEventV1.ts | 3 ++- lib/shared_types.ts | 5 ++++- lib/utils/event_tag_utils/index.ts | 9 ++++----- 5 files changed, 14 insertions(+), 17 deletions(-) diff --git a/lib/core/event_builder/build_event_v1.ts b/lib/core/event_builder/build_event_v1.ts index b1f5b271d..a6506792b 100644 --- a/lib/core/event_builder/build_event_v1.ts +++ b/lib/core/event_builder/build_event_v1.ts @@ -13,13 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { - EventTags, - ConversionEvent, - ImpressionEvent, -} from '../../modules/event_processor'; +import { ConversionEvent, ImpressionEvent } from '../../modules/event_processor'; -import { Event } from '../../shared_types'; +import { Event, EventTags } from '../../shared_types'; type ProcessableEvent = ConversionEvent | ImpressionEvent diff --git a/lib/modules/event_processor/events.ts b/lib/modules/event_processor/events.ts index 65cce503b..61abab4e5 100644 --- a/lib/modules/event_processor/events.ts +++ b/lib/modules/event_processor/events.ts @@ -1,3 +1,5 @@ +import { EventTags } from "../../shared_types" + /** * Copyright 2022, Optimizely * @@ -82,10 +84,6 @@ export interface ConversionEvent extends BaseEvent { tags: EventTags | undefined } -export type EventTags = { - [key: string]: string | number | null -} - export function areEventContextsEqual(eventA: BaseEvent, eventB: BaseEvent): boolean { const contextA = eventA.context const contextB = eventB.context diff --git a/lib/modules/event_processor/v1/buildEventV1.ts b/lib/modules/event_processor/v1/buildEventV1.ts index 699498dc4..c0ab1aba7 100644 --- a/lib/modules/event_processor/v1/buildEventV1.ts +++ b/lib/modules/event_processor/v1/buildEventV1.ts @@ -13,9 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { EventTags, ConversionEvent, ImpressionEvent, VisitorAttribute } from '../events' +import { ConversionEvent, ImpressionEvent, VisitorAttribute } from '../events' import { ProcessableEvent } from '../eventProcessor' import { EventV1Request } from '../eventDispatcher' +import { EventTags } from '../../../shared_types' const ACTIVATE_EVENT_KEY = 'campaign_activated' const CUSTOM_ATTRIBUTE_FEATURE_TYPE = 'custom' diff --git a/lib/shared_types.ts b/lib/shared_types.ts index 495051866..75885b83e 100644 --- a/lib/shared_types.ts +++ b/lib/shared_types.ts @@ -74,7 +74,10 @@ export interface UserProfile { } export type EventTags = { - [key: string]: string | number | null; + revenue?: string | number | null; + value?: string | number | null; + $opt_event_properties?: Record; + [key: string]: unknown; }; export interface UserProfileService { diff --git a/lib/utils/event_tag_utils/index.ts b/lib/utils/event_tag_utils/index.ts index 7917f3baa..e3550a73d 100644 --- a/lib/utils/event_tag_utils/index.ts +++ b/lib/utils/event_tag_utils/index.ts @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { EventTags } from '../../modules/event_processor'; +import { EventTags } from '../../shared_types'; import { LoggerFacade } from '../../modules/logging'; - import { LOG_LEVEL, LOG_MESSAGES, @@ -42,7 +41,7 @@ export function getRevenueValue(eventTags: EventTags, logger: LoggerFacade): num return null; } - const parsedRevenueValue = typeof rawValue === 'string' ? parseInt(rawValue) : rawValue; + const parsedRevenueValue = typeof rawValue === 'string' ? parseInt(rawValue) : Math.trunc(rawValue); if (isFinite(parsedRevenueValue)) { logger.log(LOG_LEVEL.INFO, LOG_MESSAGES.PARSED_REVENUE_VALUE, MODULE_NAME, parsedRevenueValue); @@ -66,7 +65,7 @@ export function getEventValue(eventTags: EventTags, logger: LoggerFacade): numbe return null; } - const parsedEventValue = typeof rawValue === 'string' ? parseFloat(rawValue) : rawValue; + const parsedEventValue = typeof rawValue === 'string' ? parseFloat(rawValue): rawValue; if (isFinite(parsedEventValue)) { logger.log(LOG_LEVEL.INFO, LOG_MESSAGES.PARSED_NUMERIC_VALUE, MODULE_NAME, parsedEventValue); @@ -75,4 +74,4 @@ export function getEventValue(eventTags: EventTags, logger: LoggerFacade): numbe logger.log(LOG_LEVEL.INFO, LOG_MESSAGES.FAILED_TO_PARSE_VALUE, MODULE_NAME, rawValue); return null; } -} \ No newline at end of file +} From 7e89e43d03a3ce4d9a9a82b6a66b29bfbb35fd18 Mon Sep 17 00:00:00 2001 From: Raju Ahmed Date: Thu, 9 Oct 2025 22:07:35 +0600 Subject: [PATCH 06/11] [FSSDK-11925] fix type in event.experimentIds field in projectConfig (#1088) solves #991 --- lib/core/optimizely_config/index.ts | 1 - lib/core/project_config/index.tests.js | 25 +++++++++++++++++-------- lib/core/project_config/index.ts | 16 +++++++++++++++- lib/shared_types.ts | 6 +++++- 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/lib/core/optimizely_config/index.ts b/lib/core/optimizely_config/index.ts index 4b435b830..8fd66246e 100644 --- a/lib/core/optimizely_config/index.ts +++ b/lib/core/optimizely_config/index.ts @@ -62,7 +62,6 @@ export class OptimizelyConfig { public events: OptimizelyEvent[]; private datafile: string; - constructor(configObj: ProjectConfig, datafile: string, logger?: LoggerFacade) { this.sdkKey = configObj.sdkKey ?? ''; this.environmentKey = configObj.environmentKey ?? ''; diff --git a/lib/core/project_config/index.tests.js b/lib/core/project_config/index.tests.js index 24134e3cd..d920ed7a3 100644 --- a/lib/core/project_config/index.tests.js +++ b/lib/core/project_config/index.tests.js @@ -31,6 +31,15 @@ var logger = getLogger(); describe('lib/core/project_config', function() { describe('createProjectConfig method', function() { + // Copy experimentIds to experimentsIds in each event to fix typo in property name + // https://github.com/optimizely/javascript-sdk/issues/991 + const copyEventExperimentIds = (event) => { + return { + ...event, + experimentsIds: event.experimentIds, + } + }; + it('should set properties correctly when createProjectConfig is called', function() { var testData = testDatafile.getTestProjectConfig(); var configObj = projectConfig.createProjectConfig(testData); @@ -42,7 +51,7 @@ describe('lib/core/project_config', function() { assert.strictEqual(configObj.accountId, testData.accountId); assert.strictEqual(configObj.projectId, testData.projectId); assert.strictEqual(configObj.revision, testData.revision); - assert.deepEqual(configObj.events, testData.events); + assert.deepEqual(configObj.events, testData.events.map((e) => copyEventExperimentIds(e))); assert.deepEqual(configObj.audiences, testData.audiences); testData.groups.forEach(function(group) { group.experiments.forEach(function(experiment) { @@ -99,13 +108,13 @@ describe('lib/core/project_config', function() { assert.deepEqual(configObj.experimentKeyMap, expectedExperimentKeyMap); var expectedEventKeyMap = { - testEvent: testData.events[0], - 'Total Revenue': testData.events[1], - testEventWithAudiences: testData.events[2], - testEventWithoutExperiments: testData.events[3], - testEventWithExperimentNotRunning: testData.events[4], - testEventWithMultipleExperiments: testData.events[5], - testEventLaunched: testData.events[6], + testEvent: copyEventExperimentIds(testData.events[0]), + 'Total Revenue': copyEventExperimentIds(testData.events[1]), + testEventWithAudiences: copyEventExperimentIds(testData.events[2]), + testEventWithoutExperiments: copyEventExperimentIds(testData.events[3]), + testEventWithExperimentNotRunning: copyEventExperimentIds(testData.events[4]), + testEventWithMultipleExperiments: copyEventExperimentIds(testData.events[5]), + testEventLaunched: copyEventExperimentIds(testData.events[6]), }; assert.deepEqual(configObj.eventKeyMap, expectedEventKeyMap); diff --git a/lib/core/project_config/index.ts b/lib/core/project_config/index.ts index a52b46efa..9f0258fac 100644 --- a/lib/core/project_config/index.ts +++ b/lib/core/project_config/index.ts @@ -1,5 +1,5 @@ /** - * Copyright 2016-2024, Optimizely + * Copyright 2016-2025, Optimizely * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,6 +50,10 @@ interface Event { key: string; id: string; experimentsIds: string[]; + + // the field is named experimentIds in the datafile, but this type previously defined it as experimentsIds. + // keeping both to avoid breaking changes, removed experimentsIds in v6. + experimentIds: string[]; // fix typo in property name (https://github.com/optimizely/javascript-sdk/issues/991) } interface VariableUsageMap { @@ -101,6 +105,16 @@ const MODULE_NAME = 'PROJECT_CONFIG'; // eslint-disable-next-line @typescript-eslint/no-explicit-any function createMutationSafeDatafileCopy(datafile: any): ProjectConfig { const datafileCopy = assign({}, datafile); + + datafileCopy.events = (datafile.events || []).map((event: Event) => { + const eventCopy: Event = assign({}, event); + + // Copy experimentIds to experimentsIds in each event to fix typo in property name + // https://github.com/optimizely/javascript-sdk/issues/991 + eventCopy.experimentsIds = event.experimentIds; + return eventCopy; + }); + datafileCopy.audiences = (datafile.audiences || []).map((audience: Audience) => { return assign({}, audience); }); diff --git a/lib/shared_types.ts b/lib/shared_types.ts index 75885b83e..9e52c8a69 100644 --- a/lib/shared_types.ts +++ b/lib/shared_types.ts @@ -1,5 +1,5 @@ /** - * Copyright 2020-2024, Optimizely + * Copyright 2020-2025, Optimizely * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -469,6 +469,10 @@ export type OptimizelyEvent = { id: string; key: string; experimentsIds: string[]; + + // the field is named experimentIds in the datafile, but this type previously defined it as experimentsIds. + // keeping both to avoid breaking changes, removed experimentsIds in v6. + experimentIds: string[]; // fix typo in property name (https://github.com/optimizely/javascript-sdk/issues/991) }; export interface OptimizelyFeature { From 6e82cb73623fc767cc03d66e7036dc39b55f9f7d Mon Sep 17 00:00:00 2001 From: Md Junaed Hossain <169046794+junaed-optimizely@users.noreply.github.com> Date: Fri, 10 Oct 2025 23:04:25 +0600 Subject: [PATCH 07/11] [FSSDK-11938] custom header (#1092) --- .../datafile-manager/datafileManager.ts | 1 + .../httpPollingDatafileManager.ts | 11 ++++- lib/shared_types.ts | 1 + tests/nodeDatafileManager.spec.ts | 45 +++++++++++++++++++ 4 files changed, 57 insertions(+), 1 deletion(-) diff --git a/lib/modules/datafile-manager/datafileManager.ts b/lib/modules/datafile-manager/datafileManager.ts index abf11d8e9..5c9fdc6cd 100644 --- a/lib/modules/datafile-manager/datafileManager.ts +++ b/lib/modules/datafile-manager/datafileManager.ts @@ -44,6 +44,7 @@ export interface DatafileManagerConfig { updateInterval?: number; urlTemplate?: string; cache?: PersistentKeyValueCache; + customHeaders?: Record; } export interface NodeDatafileManagerConfig extends DatafileManagerConfig { diff --git a/lib/modules/datafile-manager/httpPollingDatafileManager.ts b/lib/modules/datafile-manager/httpPollingDatafileManager.ts index c3311997e..c9b4ad2f4 100644 --- a/lib/modules/datafile-manager/httpPollingDatafileManager.ts +++ b/lib/modules/datafile-manager/httpPollingDatafileManager.ts @@ -15,7 +15,7 @@ */ import { getLogger } from '../logging'; -import { sprintf } from '../../utils/fns'; +import { sprintf, assign } from '../../utils/fns'; import { DatafileManager, DatafileManagerConfig, DatafileUpdate } from './datafileManager'; import EventEmitter, { Disposer } from './eventEmitter'; import { AbortableRequest, Response, Headers } from './http'; @@ -96,6 +96,8 @@ export default abstract class HttpPollingDatafileManager implements DatafileMana private sdkKey: string; + private customHeaders?: Record; + // When true, this means the update interval timeout fired before the current // sync completed. In that case, we should sync again immediately upon // completion of the current request, instead of waiting another update @@ -114,11 +116,13 @@ export default abstract class HttpPollingDatafileManager implements DatafileMana updateInterval = DEFAULT_UPDATE_INTERVAL, urlTemplate = DEFAULT_URL_TEMPLATE, cache = noOpKeyValueCache, + customHeaders, } = configWithDefaultsApplied; this.cache = cache; this.cacheKey = 'opt-datafile-' + sdkKey; this.sdkKey = sdkKey; + this.customHeaders = customHeaders; this.isReadyPromiseSettled = false; this.readyPromiseResolver = (): void => { }; this.readyPromiseRejecter = (): void => { }; @@ -266,6 +270,11 @@ export default abstract class HttpPollingDatafileManager implements DatafileMana private syncDatafile(): void { const headers: Headers = {}; + + if (this.customHeaders) { + assign(headers, this.customHeaders); + } + if (this.lastResponseLastModified) { headers['if-modified-since'] = this.lastResponseLastModified; } diff --git a/lib/shared_types.ts b/lib/shared_types.ts index 9e52c8a69..0dc03e41f 100644 --- a/lib/shared_types.ts +++ b/lib/shared_types.ts @@ -95,6 +95,7 @@ export interface DatafileOptions { updateInterval?: number; urlTemplate?: string; datafileAccessToken?: string; + customHeaders?: Record; } export interface OdpOptions { diff --git a/tests/nodeDatafileManager.spec.ts b/tests/nodeDatafileManager.spec.ts index 14fb49d05..91c1363c3 100644 --- a/tests/nodeDatafileManager.spec.ts +++ b/tests/nodeDatafileManager.spec.ts @@ -183,4 +183,49 @@ describe('nodeDatafileManager', () => { expect(makeGetRequestSpy).toBeCalledWith('https://myawesomeurl/', expect.anything()); await manager.stop(); }); + + it('passes custom headers to makeGetRequest and merges with system headers', async () => { + makeGetRequestSpy.mockReturnValue({ + abort: jest.fn(), + responsePromise: Promise.resolve({ + statusCode: 200, + body: '{"foo":"bar"}', + headers: { + 'last-modified': 'Fri, 08 Mar 2019 18:57:17 GMT', + }, + }), + }); + const manager = new NodeDatafileManager({ + sdkKey: '1234', + autoUpdate: true, + customHeaders: { + 'X-Custom-Header': 'custom-value', + 'X-Environment': 'production', + }, + }); + manager.start(); + await manager.onReady(); + + // First request should have custom headers + expect(makeGetRequestSpy).toBeCalledTimes(1); + expect(makeGetRequestSpy.mock.calls[0][0]).toBe('https://cdn.optimizely.com/datafiles/1234.json'); + expect(makeGetRequestSpy.mock.calls[0][1]).toEqual({ + 'X-Custom-Header': 'custom-value', + 'X-Environment': 'production', + }); + + // Advance time to trigger second request + await advanceTimersByTime(300000); + + // Second request should have both custom headers AND if-modified-since + expect(makeGetRequestSpy).toBeCalledTimes(2); + expect(makeGetRequestSpy.mock.calls[1][0]).toBe('https://cdn.optimizely.com/datafiles/1234.json'); + expect(makeGetRequestSpy.mock.calls[1][1]).toEqual({ + 'X-Custom-Header': 'custom-value', + 'X-Environment': 'production', + 'if-modified-since': 'Fri, 08 Mar 2019 18:57:17 GMT', + }); + + await manager.stop(); + }); }); From ae2b8951a485e5eacbfd3e2457b30b278e9c555d Mon Sep 17 00:00:00 2001 From: Md Junaed Hossain <169046794+junaed-optimizely@users.noreply.github.com> Date: Mon, 13 Oct 2025 18:10:19 +0600 Subject: [PATCH 08/11] [FSSDK-11938] release prep (#1093) --- CHANGELOG.md | 9 +++++++++ lib/index.browser.tests.js | 2 +- lib/index.lite.tests.js | 2 +- lib/index.node.tests.js | 2 +- lib/utils/enums/index.ts | 2 +- package-lock.json | 4 ++-- package.json | 2 +- tests/index.react_native.spec.ts | 2 +- 8 files changed, 17 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index abbb80136..65c989ae0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [5.4.0] - Oct 13, 2025 + +### New Features +- Added `customHeaders` option to `datafileOptions` for passing custom HTTP headers in datafile requests ([#1092](https://github.com/optimizely/javascript-sdk/pull/1092)) +### Bug Fixes +- Fix the EventTags type to allow event properties ([#1040](https://github.com/optimizely/javascript-sdk/pull/1040)) +- Fix typo in event.experimentIds field in project config ([#1088](https://github.com/optimizely/javascript-sdk/pull/1088)) + + ## [5.3.5] - Jan 29, 2025 ### Bug Fixes diff --git a/lib/index.browser.tests.js b/lib/index.browser.tests.js index a01e60ef0..4bd592e8d 100644 --- a/lib/index.browser.tests.js +++ b/lib/index.browser.tests.js @@ -193,7 +193,7 @@ describe('javascript-sdk (Browser)', function() { optlyInstance.onReady().catch(function() {}); assert.instanceOf(optlyInstance, Optimizely); - assert.equal(optlyInstance.clientVersion, '5.3.5'); + assert.equal(optlyInstance.clientVersion, '5.4.0'); }); it('should set the JavaScript client engine and version', function() { diff --git a/lib/index.lite.tests.js b/lib/index.lite.tests.js index 5eaaf80cc..7b184299c 100644 --- a/lib/index.lite.tests.js +++ b/lib/index.lite.tests.js @@ -76,7 +76,7 @@ describe('optimizelyFactory', function() { optlyInstance.onReady().catch(function() {}); assert.instanceOf(optlyInstance, Optimizely); - assert.equal(optlyInstance.clientVersion, '5.3.5'); + assert.equal(optlyInstance.clientVersion, '5.4.0'); }); }); }); diff --git a/lib/index.node.tests.js b/lib/index.node.tests.js index f66dc0b69..3efc3b1a6 100644 --- a/lib/index.node.tests.js +++ b/lib/index.node.tests.js @@ -90,7 +90,7 @@ describe('optimizelyFactory', function() { optlyInstance.onReady().catch(function() {}); assert.instanceOf(optlyInstance, Optimizely); - assert.equal(optlyInstance.clientVersion, '5.3.5'); + assert.equal(optlyInstance.clientVersion, '5.4.0'); }); describe('event processor configuration', function() { diff --git a/lib/utils/enums/index.ts b/lib/utils/enums/index.ts index 404bca534..4b70e6a97 100644 --- a/lib/utils/enums/index.ts +++ b/lib/utils/enums/index.ts @@ -221,7 +221,7 @@ export const NODE_CLIENT_ENGINE = 'node-sdk'; export const REACT_CLIENT_ENGINE = 'react-sdk'; export const REACT_NATIVE_CLIENT_ENGINE = 'react-native-sdk'; export const REACT_NATIVE_JS_CLIENT_ENGINE = 'react-native-js-sdk'; -export const CLIENT_VERSION ='5.3.5' +export const CLIENT_VERSION ='5.4.0' export const DECISION_NOTIFICATION_TYPES = { AB_TEST: 'ab-test', diff --git a/package-lock.json b/package-lock.json index 35bbbae1a..70b2e15be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@optimizely/optimizely-sdk", - "version": "5.3.5", + "version": "5.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@optimizely/optimizely-sdk", - "version": "5.3.5", + "version": "5.4.0", "license": "Apache-2.0", "dependencies": { "decompress-response": "^4.2.1", diff --git a/package.json b/package.json index 1b93e7539..fbb679ecf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@optimizely/optimizely-sdk", - "version": "5.3.5", + "version": "5.4.0", "description": "JavaScript SDK for Optimizely Feature Experimentation, Optimizely Full Stack (legacy), and Optimizely Rollouts", "module": "dist/optimizely.browser.es.js", "main": "dist/optimizely.node.min.js", diff --git a/tests/index.react_native.spec.ts b/tests/index.react_native.spec.ts index 11bed1752..5a0789b19 100644 --- a/tests/index.react_native.spec.ts +++ b/tests/index.react_native.spec.ts @@ -93,7 +93,7 @@ describe('javascript-sdk/react-native', () => { expect(optlyInstance).toBeInstanceOf(Optimizely); // @ts-ignore - expect(optlyInstance.clientVersion).toEqual('5.3.5'); + expect(optlyInstance.clientVersion).toEqual('5.4.0'); }); it('should set the React Native JS client engine and javascript SDK version', () => { From 34682eafad5af210919e273e86b8a10b8009807e Mon Sep 17 00:00:00 2001 From: Md Junaed Hossain <169046794+junaed-optimizely@users.noreply.github.com> Date: Fri, 5 Dec 2025 22:53:45 +0600 Subject: [PATCH 09/11] [FSSDK-12114] peer deps update --- package-lock.json | 4 ++-- package.json | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 70b2e15be..7cf720cea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -69,8 +69,8 @@ }, "peerDependencies": { "@babel/runtime": "^7.0.0", - "@react-native-async-storage/async-storage": "^1.2.0", - "@react-native-community/netinfo": "^11.3.2", + "@react-native-async-storage/async-storage": ">=1.0.0 <3.0.0", + "@react-native-community/netinfo": ">=5.0.0 <12.0.0", "fast-text-encoding": "^1.0.6", "react-native-get-random-values": "^1.11.0" }, diff --git a/package.json b/package.json index fbb679ecf..889942831 100644 --- a/package.json +++ b/package.json @@ -161,9 +161,9 @@ }, "peerDependencies": { "@babel/runtime": "^7.0.0", - "@react-native-async-storage/async-storage": "^1.2.0", - "@react-native-community/netinfo": "^11.3.2", - "react-native-get-random-values": "^1.11.0", + "@react-native-async-storage/async-storage": ">=1.0.0 <3.0.0", + "@react-native-community/netinfo": ">=5.0.0 <12.0.0", + "react-native-get-random-values": ">=1.11.0 <3.0.0", "fast-text-encoding": "^1.0.6" }, "peerDependenciesMeta": { From c20678f310e308a5eb97c053e107ef3bd26ff365 Mon Sep 17 00:00:00 2001 From: Md Junaed Hossain <169046794+junaed-optimizely@users.noreply.github.com> Date: Mon, 8 Dec 2025 18:49:15 +0600 Subject: [PATCH 10/11] [FSSDK-12115] Notification center type definition update (#1119) --- lib/core/decision_service/index.ts | 3 +- lib/core/notification_center/index.ts | 2 +- lib/export_types.ts | 17 ++ lib/shared_types.ts | 90 +++++- lib/utils/enums/index.ts | 4 +- package-lock.json | 410 +------------------------- 6 files changed, 110 insertions(+), 416 deletions(-) diff --git a/lib/core/decision_service/index.ts b/lib/core/decision_service/index.ts index 28f97a09e..3a66f4a03 100644 --- a/lib/core/decision_service/index.ts +++ b/lib/core/decision_service/index.ts @@ -44,6 +44,7 @@ import * as stringValidator from '../../utils/string_value_validator'; import { BucketerParams, DecisionResponse, + DecisionSource, Experiment, ExperimentBucketMap, FeatureFlag, @@ -60,7 +61,7 @@ const MODULE_NAME = 'DECISION_SERVICE'; export interface DecisionObj { experiment: Experiment | null; variation: Variation | null; - decisionSource: string; + decisionSource: DecisionSource; } interface DecisionServiceOptions { diff --git a/lib/core/notification_center/index.ts b/lib/core/notification_center/index.ts index a0a91dffe..92337a994 100644 --- a/lib/core/notification_center/index.ts +++ b/lib/core/notification_center/index.ts @@ -15,7 +15,7 @@ */ import { LogHandler, ErrorHandler } from '../../modules/logging'; import { objectValues } from '../../utils/fns'; -import { NotificationListener, ListenerPayload } from '../../shared_types'; +import { ListenerPayload, NotificationListener, NotificationPayloadMap } from '../../shared_types'; import { LOG_LEVEL, diff --git a/lib/export_types.ts b/lib/export_types.ts index 759bb86c0..d9e714085 100644 --- a/lib/export_types.ts +++ b/lib/export_types.ts @@ -37,6 +37,9 @@ export { UserProfileService, UserProfile, ListenerPayload, + DecisionListenerPayload, + LogEventListenerPayload, + NotificationPayloadMap, OptimizelyDecision, OptimizelyUserContext, NotificationListener, @@ -47,4 +50,18 @@ export { NotificationCenter, OptimizelySegmentOption, ICache, + // Decision info types + DecisionNotificationType, + DecisionSource, + DecisionSourceInfo, + VariablesMap, + // Specific decision info types for type narrowing + AbTestDecisionInfo, + FeatureDecisionInfo, + FeatureTestDecisionInfo, + FeatureVariableDecisionInfo, + AllFeatureVariablesDecisionInfo, + FlagDecisionInfo, + DecisionInfoMap, + DecisionListenerPayloadForType, } from './shared_types'; diff --git a/lib/shared_types.ts b/lib/shared_types.ts index 0dc03e41f..7ff6e0311 100644 --- a/lib/shared_types.ts +++ b/lib/shared_types.ts @@ -23,7 +23,7 @@ import { ErrorHandler, LogHandler, LogLevel, LoggerFacade } from './modules/logg import { EventProcessor } from './modules/event_processor'; import { NotificationCenter as NotificationCenterImpl } from './core/notification_center'; -import { NOTIFICATION_TYPES } from './utils/enums'; +import { NOTIFICATION_TYPES, DECISION_NOTIFICATION_TYPES, DECISION_SOURCES } from './utils/enums'; import { IOptimizelyUserContext as OptimizelyUserContext } from './optimizely_user_context'; @@ -120,9 +120,93 @@ export interface ListenerPayload { attributes?: UserAttributes; } -export type NotificationListener = (notificationData: T) => void; +export type DecisionNotificationType = typeof DECISION_NOTIFICATION_TYPES[keyof typeof DECISION_NOTIFICATION_TYPES]; + +export type DecisionSource = typeof DECISION_SOURCES[keyof typeof DECISION_SOURCES]; + +export type DecisionSourceInfo = { + experimentKey?: string; + variationKey?: string; +}; + +export type VariablesMap = { [variableKey: string]: unknown }; + +export type AbTestDecisionInfo = { + experimentKey: string; + variationKey: string | null; +}; -// NotificationCenter-related types +export type FeatureDecisionInfo = { + featureKey: string; + featureEnabled: boolean; + source: DecisionSource; + sourceInfo: DecisionSourceInfo; +}; + +export type FeatureTestDecisionInfo = { + experimentKey: string; + variationKey: string | null; +}; + +export type FeatureVariableDecisionInfo = { + featureKey: string; + featureEnabled: boolean; + source: DecisionSource; + variableKey: string; + variableValue: FeatureVariableValue; + variableType: VariableType; + sourceInfo: DecisionSourceInfo; +}; + +export type AllFeatureVariablesDecisionInfo = { + featureKey: string; + featureEnabled: boolean; + source: DecisionSource; + variableValues: VariablesMap; + sourceInfo: DecisionSourceInfo; +}; + +export type FlagDecisionInfo = { + flagKey: string; + enabled: boolean; + variationKey: string | null; + ruleKey: string | null; + variables: VariablesMap; + reasons: string[]; + decisionEventDispatched: boolean; + experimentId?: string; + variationId?: string; +}; + +export type DecisionInfoMap = { + [DECISION_NOTIFICATION_TYPES.AB_TEST]: AbTestDecisionInfo; + [DECISION_NOTIFICATION_TYPES.FEATURE]: FeatureDecisionInfo; + [DECISION_NOTIFICATION_TYPES.FEATURE_TEST]: FeatureTestDecisionInfo; + [DECISION_NOTIFICATION_TYPES.FEATURE_VARIABLE]: FeatureVariableDecisionInfo; + [DECISION_NOTIFICATION_TYPES.ALL_FEATURE_VARIABLES]: AllFeatureVariablesDecisionInfo; + [DECISION_NOTIFICATION_TYPES.FLAG]: FlagDecisionInfo; +}; + +export type DecisionListenerPayloadForType = ListenerPayload & { + type: T; + decisionInfo: DecisionInfoMap[T]; +}; + +export type DecisionListenerPayload = { + [T in DecisionNotificationType]: DecisionListenerPayloadForType; +}[DecisionNotificationType]; + +export type LogEventListenerPayload = Event; + +export type NotificationPayloadMap = { + [NOTIFICATION_TYPES.ACTIVATE]: ActivateListenerPayload; + [NOTIFICATION_TYPES.DECISION]: DecisionListenerPayload; + [NOTIFICATION_TYPES.TRACK]: TrackListenerPayload; + [NOTIFICATION_TYPES.LOG_EVENT]: LogEventListenerPayload; + [NOTIFICATION_TYPES.OPTIMIZELY_CONFIG_UPDATE]: undefined; +}; + +export type NotificationListener = (notificationData: T) => void; export interface NotificationCenter { addNotificationListener( notificationType: string, diff --git a/lib/utils/enums/index.ts b/lib/utils/enums/index.ts index 4b70e6a97..a89a9470e 100644 --- a/lib/utils/enums/index.ts +++ b/lib/utils/enums/index.ts @@ -230,7 +230,7 @@ export const DECISION_NOTIFICATION_TYPES = { FEATURE_VARIABLE: 'feature-variable', ALL_FEATURE_VARIABLES: 'all-feature-variables', FLAG: 'flag', -}; +} as const; /* * Represents the source of a decision for feature management. When a feature @@ -242,7 +242,7 @@ export const DECISION_SOURCES = { FEATURE_TEST: 'feature-test', ROLLOUT: 'rollout', EXPERIMENT: 'experiment', -}; +} as const; export const AUDIENCE_EVALUATION_TYPES = { RULE: 'rule', diff --git a/package-lock.json b/package-lock.json index 7cf720cea..c9d67d807 100644 --- a/package-lock.json +++ b/package-lock.json @@ -72,7 +72,7 @@ "@react-native-async-storage/async-storage": ">=1.0.0 <3.0.0", "@react-native-community/netinfo": ">=5.0.0 <12.0.0", "fast-text-encoding": "^1.0.6", - "react-native-get-random-values": "^1.11.0" + "react-native-get-random-values": ">=1.11.0 <3.0.0" }, "peerDependenciesMeta": { "@react-native-async-storage/async-storage": { @@ -2622,32 +2622,6 @@ "node": ">=0.1.90" } }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -3016,17 +2990,6 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, - "node_modules/@jest/core/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/@jest/core/node_modules/jest-config": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", @@ -3106,51 +3069,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/core/node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, "node_modules/@jest/create-cache-key-function": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz", @@ -4348,38 +4266,6 @@ "node": ">= 10" } }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/@types/babel__core": { "version": "7.20.2", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.2.tgz", @@ -6522,17 +6408,6 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, - "node_modules/create-jest/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/create-jest/node_modules/jest-config": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", @@ -6612,59 +6487,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/create-jest/node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -9089,17 +8911,6 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, - "node_modules/jest-cli/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/jest-cli/node_modules/jest-config": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", @@ -9179,51 +8990,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-cli/node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, "node_modules/jest-diff": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", @@ -14716,14 +14482,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/v8-to-istanbul": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", @@ -16961,31 +16719,6 @@ "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", "dev": true }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - } - } - }, "@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -17268,14 +17001,6 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "optional": true, - "peer": true - }, "jest-config": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", @@ -17331,29 +17056,6 @@ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", "dev": true - }, - "ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - } } } }, @@ -18356,38 +18058,6 @@ "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", "dev": true }, - "@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true, - "optional": true, - "peer": true - }, - "@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, - "optional": true, - "peer": true - }, - "@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, - "optional": true, - "peer": true - }, - "@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true, - "optional": true, - "peer": true - }, "@types/babel__core": { "version": "7.20.2", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.2.tgz", @@ -20079,14 +19749,6 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "optional": true, - "peer": true - }, "jest-config": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", @@ -20142,40 +19804,9 @@ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", "dev": true - }, - "ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - } } } }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "optional": true, - "peer": true - }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -21963,14 +21594,6 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "optional": true, - "peer": true - }, "jest-config": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", @@ -22026,29 +21649,6 @@ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", "dev": true - }, - "ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - } } } }, @@ -26372,14 +25972,6 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, - "optional": true, - "peer": true - }, "v8-to-istanbul": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", From 781499be601415228e22be619a200a2d71c65a41 Mon Sep 17 00:00:00 2001 From: Md Junaed Hossain <169046794+junaed-optimizely@users.noreply.github.com> Date: Mon, 8 Dec 2025 19:21:42 +0600 Subject: [PATCH 11/11] release-5.4.1 (#1121) --- .github/workflows/release.yml | 2 +- CHANGELOG.md | 7 +++++++ lib/index.browser.tests.js | 2 +- lib/index.lite.tests.js | 2 +- lib/index.node.tests.js | 2 +- lib/utils/enums/index.ts | 2 +- package-lock.json | 4 ++-- package.json | 2 +- tests/index.react_native.spec.ts | 2 +- 9 files changed, 16 insertions(+), 9 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4d0e71680..47c5c0dc0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,7 +2,7 @@ name: Publish SDK to NPM on: release: - types: [published, edited] + types: [published] workflow_dispatch: {} jobs: diff --git a/CHANGELOG.md b/CHANGELOG.md index 65c989ae0..d09e07847 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [5.4.1] - Dec 8, 2025 + +### Changed +- Widen React Native peer dependency version ranges ([#1118](https://github.com/optimizely/javascript-sdk/pull/1118)) +- Improve notification center type definitions with strongly-typed listener payloads ([#1119](https://github.com/optimizely/javascript-sdk/pull/1119)) + + ## [5.4.0] - Oct 13, 2025 ### New Features diff --git a/lib/index.browser.tests.js b/lib/index.browser.tests.js index 4bd592e8d..c6dd96e4e 100644 --- a/lib/index.browser.tests.js +++ b/lib/index.browser.tests.js @@ -193,7 +193,7 @@ describe('javascript-sdk (Browser)', function() { optlyInstance.onReady().catch(function() {}); assert.instanceOf(optlyInstance, Optimizely); - assert.equal(optlyInstance.clientVersion, '5.4.0'); + assert.equal(optlyInstance.clientVersion, '5.4.1'); }); it('should set the JavaScript client engine and version', function() { diff --git a/lib/index.lite.tests.js b/lib/index.lite.tests.js index 7b184299c..7a30a4fcf 100644 --- a/lib/index.lite.tests.js +++ b/lib/index.lite.tests.js @@ -76,7 +76,7 @@ describe('optimizelyFactory', function() { optlyInstance.onReady().catch(function() {}); assert.instanceOf(optlyInstance, Optimizely); - assert.equal(optlyInstance.clientVersion, '5.4.0'); + assert.equal(optlyInstance.clientVersion, '5.4.1'); }); }); }); diff --git a/lib/index.node.tests.js b/lib/index.node.tests.js index 3efc3b1a6..d9e6107b2 100644 --- a/lib/index.node.tests.js +++ b/lib/index.node.tests.js @@ -90,7 +90,7 @@ describe('optimizelyFactory', function() { optlyInstance.onReady().catch(function() {}); assert.instanceOf(optlyInstance, Optimizely); - assert.equal(optlyInstance.clientVersion, '5.4.0'); + assert.equal(optlyInstance.clientVersion, '5.4.1'); }); describe('event processor configuration', function() { diff --git a/lib/utils/enums/index.ts b/lib/utils/enums/index.ts index a89a9470e..f757621c4 100644 --- a/lib/utils/enums/index.ts +++ b/lib/utils/enums/index.ts @@ -221,7 +221,7 @@ export const NODE_CLIENT_ENGINE = 'node-sdk'; export const REACT_CLIENT_ENGINE = 'react-sdk'; export const REACT_NATIVE_CLIENT_ENGINE = 'react-native-sdk'; export const REACT_NATIVE_JS_CLIENT_ENGINE = 'react-native-js-sdk'; -export const CLIENT_VERSION ='5.4.0' +export const CLIENT_VERSION ='5.4.1' export const DECISION_NOTIFICATION_TYPES = { AB_TEST: 'ab-test', diff --git a/package-lock.json b/package-lock.json index c9d67d807..a5d803c6b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@optimizely/optimizely-sdk", - "version": "5.4.0", + "version": "5.4.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@optimizely/optimizely-sdk", - "version": "5.4.0", + "version": "5.4.1", "license": "Apache-2.0", "dependencies": { "decompress-response": "^4.2.1", diff --git a/package.json b/package.json index 889942831..73b8cd3db 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@optimizely/optimizely-sdk", - "version": "5.4.0", + "version": "5.4.1", "description": "JavaScript SDK for Optimizely Feature Experimentation, Optimizely Full Stack (legacy), and Optimizely Rollouts", "module": "dist/optimizely.browser.es.js", "main": "dist/optimizely.node.min.js", diff --git a/tests/index.react_native.spec.ts b/tests/index.react_native.spec.ts index 5a0789b19..fea41446f 100644 --- a/tests/index.react_native.spec.ts +++ b/tests/index.react_native.spec.ts @@ -93,7 +93,7 @@ describe('javascript-sdk/react-native', () => { expect(optlyInstance).toBeInstanceOf(Optimizely); // @ts-ignore - expect(optlyInstance.clientVersion).toEqual('5.4.0'); + expect(optlyInstance.clientVersion).toEqual('5.4.1'); }); it('should set the React Native JS client engine and javascript SDK version', () => {