diff --git a/.changeset/polite-bottles-smell.md b/.changeset/polite-bottles-smell.md new file mode 100644 index 000000000..2b996dd94 --- /dev/null +++ b/.changeset/polite-bottles-smell.md @@ -0,0 +1,5 @@ +--- +'@segment/analytics-next': minor +--- + +Add updateCDNSettings option diff --git a/packages/browser/src/browser/__tests__/update-cdn-settings.test.ts b/packages/browser/src/browser/__tests__/update-cdn-settings.test.ts new file mode 100644 index 000000000..44493e1b1 --- /dev/null +++ b/packages/browser/src/browser/__tests__/update-cdn-settings.test.ts @@ -0,0 +1,70 @@ +import { AnalyticsBrowser } from '../..' +import { setGlobalCDNUrl } from '../../lib/parse-cdn' +import { remoteLoader } from '../../plugins/remote-loader' +import unfetch from 'unfetch' +import { createSuccess } from '../../test-helpers/factories' +jest.mock('unfetch') + +const INTG_TO_DELETE = 'deleteMe' + +const cdnSettings = { + integrations: { + [INTG_TO_DELETE]: { bar: true }, + otherIntegration: { foo: true }, + }, +} +const mockFetchSettingsSuccessResponse = (cdnSettings: any) => { + return jest + .mocked(unfetch) + .mockImplementation(() => createSuccess(cdnSettings)) +} + +jest.mock('../../plugins/remote-loader') +const remoteLoaderSpy = jest.fn().mockResolvedValue([]) +jest.mocked(remoteLoader).mockImplementation(remoteLoaderSpy) + +describe('updateCDNSettings configuration option', () => { + beforeEach(() => { + setGlobalCDNUrl(undefined as any) + ;(window as any).analytics = undefined + }) + it('should update the configuration options if they are passed directly', async () => { + await AnalyticsBrowser.load( + { + writeKey: 'foo', + cdnSettings, + }, + { + updateCDNSettings: (settings) => { + delete settings.integrations.deleteMe + return settings + }, + } + ) + const [arg1] = remoteLoaderSpy.mock.lastCall + expect(arg1.integrations.otherIntegration).toEqual( + cdnSettings.integrations.otherIntegration + ) + expect(arg1.integrations[INTG_TO_DELETE]).toBeUndefined() + }) + + it('should update the configuration options if they are fetched', async () => { + mockFetchSettingsSuccessResponse(cdnSettings) + await AnalyticsBrowser.load( + { + writeKey: 'foo', + }, + { + updateCDNSettings: (settings) => { + delete settings.integrations.deleteMe + return settings + }, + } + ) + const [arg1] = remoteLoaderSpy.mock.lastCall + expect(arg1.integrations.otherIntegration).toEqual( + cdnSettings.integrations.otherIntegration + ) + expect(arg1.integrations[INTG_TO_DELETE]).toBeUndefined() + }) +}) diff --git a/packages/browser/src/browser/index.ts b/packages/browser/src/browser/index.ts index b85fba41e..a0a5d10d2 100644 --- a/packages/browser/src/browser/index.ts +++ b/packages/browser/src/browser/index.ts @@ -268,10 +268,14 @@ async function loadAnalytics( // this is an ugly side-effect, but it's for the benefits of the plugins that get their cdn via getCDN() if (settings.cdnURL) setGlobalCDNUrl(settings.cdnURL) - const legacySettings = + let legacySettings = settings.cdnSettings ?? (await loadLegacySettings(settings.writeKey, settings.cdnURL)) + if (options.updateCDNSettings) { + legacySettings = options.updateCDNSettings(legacySettings) + } + const retryQueue: boolean = legacySettings.integrations['Segment.io']?.retryQueue ?? true diff --git a/packages/browser/src/core/analytics/index.ts b/packages/browser/src/core/analytics/index.ts index 507264e58..0ffe4eb9b 100644 --- a/packages/browser/src/core/analytics/index.ts +++ b/packages/browser/src/core/analytics/index.ts @@ -49,6 +49,7 @@ import { PriorityQueue } from '../../lib/priority-queue' import { getGlobal } from '../../lib/get-global' import { AnalyticsClassic, AnalyticsCore } from './interfaces' import { HighEntropyHint } from '../../lib/client-hints/interfaces' +import type { LegacySettings } from '../../browser' const deprecationWarning = 'This is being deprecated and will be not be available in future releases of Analytics JS' @@ -98,6 +99,11 @@ export interface InitOptions { plan?: Plan retryQueue?: boolean obfuscate?: boolean + /** + * This callback allows you to update/mutate CDN Settings. + * This is called directly after settings are fetched from the CDN. + */ + updateCDNSettings?: (settings: LegacySettings) => LegacySettings /** * Disables or sets constraints on processing of query string parameters */