From 2cc959053d2719989a36d3abeb69873cf56bd6dc Mon Sep 17 00:00:00 2001 From: Seth Silesky <5115498+silesky@users.noreply.github.com> Date: Mon, 13 Jan 2025 16:00:02 -0600 Subject: [PATCH 1/3] Settings Refactor --- .changeset/chilly-mugs-applaud.md | 5 + packages/browser/src/browser/index.ts | 137 +----------- packages/browser/src/browser/settings.ts | 207 ++++++++++++++++++ packages/browser/src/core/analytics/index.ts | 85 +------ packages/browser/src/core/events/index.ts | 14 +- .../browser/src/core/events/interfaces.ts | 4 +- packages/browser/src/index.ts | 10 +- packages/browser/src/lib/merged-options.ts | 8 +- .../src/plugins/ajs-destination/index.ts | 4 +- .../src/plugins/ajs-destination/loader.ts | 2 +- .../src/plugins/ajs-destination/utils.ts | 4 +- .../src/plugins/remote-loader/index.ts | 9 +- packages/browser/src/tester/ajs-tester.ts | 1 - packages/core/src/events/index.ts | 14 +- packages/core/src/events/interfaces.ts | 8 +- packages/core/src/queue/event-queue.ts | 7 +- packages/node/src/app/types/params.ts | 12 +- 17 files changed, 273 insertions(+), 258 deletions(-) create mode 100644 .changeset/chilly-mugs-applaud.md create mode 100644 packages/browser/src/browser/settings.ts diff --git a/.changeset/chilly-mugs-applaud.md b/.changeset/chilly-mugs-applaud.md new file mode 100644 index 000000000..380a35ca8 --- /dev/null +++ b/.changeset/chilly-mugs-applaud.md @@ -0,0 +1,5 @@ +--- +'@segment/analytics-core': patch +--- + +Fix integration type diff --git a/packages/browser/src/browser/index.ts b/packages/browser/src/browser/index.ts index abc92716f..c1cb77699 100644 --- a/packages/browser/src/browser/index.ts +++ b/packages/browser/src/browser/index.ts @@ -1,21 +1,12 @@ import { getProcessEnv } from '../lib/get-process-env' import { getCDN, setGlobalCDNUrl } from '../lib/parse-cdn' - -import { fetch } from '../lib/fetch' -import { Analytics, NullAnalytics, InitOptions } from '../core/analytics' +import { Analytics, NullAnalytics } from '../core/analytics' import { Context } from '../core/context' -import { Plan } from '../core/events' import { Plugin } from '../core/plugin' -import { MetricsOptions } from '../core/stats/remote-metrics' import { mergedOptions } from '../lib/merged-options' import { createDeferred } from '@segment/analytics-generic-utils' import { envEnrichment } from '../plugins/env-enrichment' -import { - PluginFactory, - remoteLoader, - RemotePlugin, -} from '../plugins/remote-loader' -import type { RoutingRule } from '../plugins/routing-middleware' +import { PluginFactory, remoteLoader } from '../plugins/remote-loader' import { segmentio, SegmentioSettings } from '../plugins/segmentio' import { AnalyticsBuffered, @@ -31,127 +22,9 @@ import { ClassicIntegrationSource } from '../plugins/ajs-destination/types' import { attachInspector } from '../core/inspector' import { Stats } from '../core/stats' import { setGlobalAnalyticsKey } from '../lib/global-analytics-helper' +import { CDNSettings, AnalyticsBrowserSettings, InitOptions } from './settings' -export interface RemoteIntegrationSettings { - /* @deprecated - This does not indicate browser types anymore */ - type?: string - - versionSettings?: { - version?: string - override?: string - componentTypes?: ('browser' | 'android' | 'ios' | 'server')[] - } - - /** - * We know if an integration is device mode if it has `bundlingStatus: 'bundled'` and the `browser` componentType in `versionSettings`. - * History: The term 'bundle' is left over from before action destinations, when a device mode destinations were 'bundled' in a custom bundle for every analytics.js source. - */ - bundlingStatus?: 'bundled' | 'unbundled' - - /** - * Consent settings for the integration - */ - consentSettings?: { - /** - * Consent categories for the integration - * @example ["CAT001", "CAT002"] - */ - categories: string[] - } - - // Segment.io specific - retryQueue?: boolean - - // any extra unknown settings - // eslint-disable-next-line @typescript-eslint/no-explicit-any - [key: string]: any -} - -/** - * The remote settings object for a source, typically fetched from the Segment CDN. - * Warning: this is an *unstable* object. - */ -export interface CDNSettings { - integrations: { - [creationName: string]: RemoteIntegrationSettings - } - - middlewareSettings?: { - routingRules: RoutingRule[] - } - - enabledMiddleware?: Record - metrics?: MetricsOptions - - plan?: Plan - - legacyVideoPluginsEnabled?: boolean - - remotePlugins?: RemotePlugin[] - - /** - * Top level consent settings - */ - consentSettings?: { - /** - * All unique consent categories for enabled destinations. - * There can be categories in this array that are important for consent that are not included in any integration (e.g. 2 cloud mode categories). - * @example ["Analytics", "Advertising", "CAT001"] - */ - allCategories: string[] - - /** - * Whether or not there are any unmapped destinations for enabled destinations. - */ - hasUnmappedDestinations: boolean - } - /** - * Settings for edge function. Used for signals. - */ - edgeFunction?: // this is technically non-nullable according to ajs-renderer atm, but making it optional because it's strange API choice, and we might want to change it. - | { - /** - * The URL of the edge function (.js file). - * @example 'https://cdn.edgefn.segment.com/MY-WRITEKEY/foo.js', - */ - downloadURL: string - /** - * The version of the edge function - * @example 1 - */ - version: number - } - | {} - - /** - * Settings for auto instrumentation - */ - autoInstrumentationSettings?: { - sampleRate: number - } -} - -export interface AnalyticsBrowserSettings { - writeKey: string - /** - * The settings for the Segment Source. - * If provided, `AnalyticsBrowser` will not fetch remote settings - * for the source. - */ - cdnSettings?: CDNSettings & Record - /** - * If provided, will override the default Segment CDN (https://cdn.segment.com) for this application. - */ - cdnURL?: string - /** - * Plugins or npm-installed action destinations - */ - plugins?: (Plugin | PluginFactory)[] - /** - * npm-installed classic destinations - */ - classicIntegrations?: ClassicIntegrationSource[] -} +export type { CDNSettings, AnalyticsBrowserSettings } export function loadCDNSettings( writeKey: string, @@ -316,7 +189,7 @@ async function registerPlugins( basePlugins.push( await segmentio( analytics, - mergedSettings['Segment.io'] as SegmentioSettings, + mergedSettings['Segment.io'], cdnSettings.integrations ) ) diff --git a/packages/browser/src/browser/settings.ts b/packages/browser/src/browser/settings.ts new file mode 100644 index 000000000..1947e48f6 --- /dev/null +++ b/packages/browser/src/browser/settings.ts @@ -0,0 +1,207 @@ +/** + * These settings will be exposed via the public API + */ +import { IntegrationsOptions, Plan } from '../core/events' +import { MetricsOptions } from '../core/stats/remote-metrics' +import { ClassicIntegrationSource } from '../plugins/ajs-destination/types' +import { PluginFactory, RemotePlugin } from '../plugins/remote-loader' +import { Plugin } from '../core/plugin' +import { RoutingRule } from '../plugins/routing-middleware' +import { CookieOptions, StorageSettings } from '../core/storage' +import { UserOptions } from '../core/user' +import { HighEntropyHint } from '../lib/client-hints/interfaces' + +export interface RemoteIntegrationSettings { + /* @deprecated - This does not indicate browser types anymore */ + type?: string + + versionSettings?: { + version?: string + override?: string + componentTypes?: ('browser' | 'android' | 'ios' | 'server')[] + } + + /** + * We know if an integration is device mode if it has `bundlingStatus: 'bundled'` and the `browser` componentType in `versionSettings`. + * History: The term 'bundle' is left over from before action destinations, when a device mode destinations were 'bundled' in a custom bundle for every analytics.js source. + */ + bundlingStatus?: 'bundled' | 'unbundled' + + /** + * Consent settings for the integration + */ + consentSettings?: { + /** + * Consent categories for the integration + * @example ["CAT001", "CAT002"] + */ + categories: string[] + } + + // Segment.io specific + retryQueue?: boolean + + // any extra unknown settings + // eslint-disable-next-line @typescript-eslint/no-explicit-any + [key: string]: any +} + +/** + * The remote settings object for a source, typically fetched from the Segment CDN. + * Warning: this is an *unstable* object. + */ +export interface CDNSettings { + integrations: { + [creationName: string]: RemoteIntegrationSettings + } + + middlewareSettings?: { + routingRules: RoutingRule[] + } + + enabledMiddleware?: Record + metrics?: MetricsOptions + + plan?: Plan + + legacyVideoPluginsEnabled?: boolean + + remotePlugins?: RemotePlugin[] + + /** + * Top level consent settings + */ + consentSettings?: { + /** + * All unique consent categories for enabled destinations. + * There can be categories in this array that are important for consent that are not included in any integration (e.g. 2 cloud mode categories). + * @example ["Analytics", "Advertising", "CAT001"] + */ + allCategories: string[] + + /** + * Whether or not there are any unmapped destinations for enabled destinations. + */ + hasUnmappedDestinations: boolean + } + /** + * Settings for edge function. Used for signals. + */ + edgeFunction?: // this is technically non-nullable according to ajs-renderer atm, but making it optional because it's strange API choice, and we might want to change it. + | { + /** + * The URL of the edge function (.js file). + * @example 'https://cdn.edgefn.segment.com/MY-WRITEKEY/foo.js', + */ + downloadURL: string + /** + * The version of the edge function + * @example 1 + */ + version: number + } + | {} + + /** + * Settings for auto instrumentation + */ + autoInstrumentationSettings?: { + sampleRate: number + } +} + +/** + * These are the settings that are the first argument to the npm installed plugin. + */ +export interface AnalyticsBrowserSettings { + // TODO: Having two different configuration patterns for snippet and npm is confusing. + writeKey: string + /** + * The settings for the Segment Source. + * If provided, `AnalyticsBrowser` will not fetch remote settings + * for the source. + */ + cdnSettings?: CDNSettings & Record + /** + * If provided, will override the default Segment CDN (https://cdn.segment.com) for this application. + */ + cdnURL?: string + /** + * Plugins or npm-installed action destinations + */ + plugins?: (Plugin | PluginFactory)[] + /** + * npm-installed classic destinations + */ + classicIntegrations?: ClassicIntegrationSource[] +} + +/** + * The settings that are used to configure the analytics instance + */ +export interface AnalyticsSettings { + writeKey: string + cdnSettings?: CDNSettings + cdnURL?: string +} + +export interface InitOptions { + /** + * Disables storing any data on the client-side via cookies or localstorage. + * Defaults to `false`. + * + */ + disableClientPersistence?: boolean + /** + * Disables automatically converting ISO string event properties into Dates. + * ISO string to Date conversions occur right before sending events to a classic device mode integration, + * after any destination middleware have been ran. + * Defaults to `false`. + */ + disableAutoISOConversion?: boolean + initialPageview?: boolean + cookie?: CookieOptions + storage?: StorageSettings + user?: UserOptions + group?: UserOptions + integrations?: IntegrationsOptions + 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. + * @internal + */ + updateCDNSettings?: (unstableCDNSettings: CDNSettings) => CDNSettings + /** + * Disables or sets constraints on processing of query string parameters + */ + useQueryString?: + | boolean + | { + aid?: RegExp + uid?: RegExp + } + /** + * Array of high entropy Client Hints to request. These may be rejected by the user agent - only required hints should be requested. + */ + highEntropyValuesClientHints?: HighEntropyHint[] + /** + * When using the snippet, this is the key that points to the global analytics instance (e.g. window.analytics). + * default: analytics + */ + globalAnalyticsKey?: string + + /** + * Disable sending any data to Segment's servers. All emitted events and API calls (including .ready()), will be no-ops, and no cookies or localstorage will be used. + * + * @example + * ```ts + * disable: process.env.NODE_ENV === 'test' + * ``` + */ + disable?: + | boolean + | ((unstableCDNSettings: CDNSettings) => boolean | Promise) +} diff --git a/packages/browser/src/core/analytics/index.ts b/packages/browser/src/core/analytics/index.ts index e4c57e819..8ac5461d6 100644 --- a/packages/browser/src/core/analytics/index.ts +++ b/packages/browser/src/core/analytics/index.ts @@ -18,14 +18,13 @@ import { Emitter } from '@segment/analytics-generic-utils' import { Callback, EventFactory, - Integrations, - Plan, + IntegrationsOptions, EventProperties, SegmentEvent, } from '../events' import { isDestinationPluginWithAddMiddleware, Plugin } from '../plugin' import { EventQueue } from '../queue/event-queue' -import { Group, ID, User, UserOptions } from '../user' +import { Group, ID, User } from '../user' import autoBind from '../../lib/bind-all' import { PersistedPriorityQueue } from '../../lib/priority-queue/persisted' import type { LegacyIntegration } from '../../plugins/ajs-destination/types' @@ -37,13 +36,11 @@ import { version } from '../../generated/version' 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 { CDNSettings } from '../../browser' import { CookieOptions, MemoryStorage, UniversalStorage, - StorageSettings, StoreType, applyCookieOptions, initializeStorages, @@ -55,6 +52,9 @@ import { isSegmentPlugin, SegmentIOPluginMetadata, } from '../../plugins/segmentio' +import { AnalyticsSettings, InitOptions } from '../../browser/settings' + +export type { InitOptions, AnalyticsSettings } const deprecationWarning = 'This is being deprecated and will be not be available in future releases of Analytics JS' @@ -107,79 +107,6 @@ export class AnalyticsInstanceSettings { } } -/** - * The settings that are used to configure the analytics instance - */ -export interface AnalyticsSettings { - writeKey: string - cdnSettings?: CDNSettings - cdnURL?: string -} - -export interface InitOptions { - /** - * Disables storing any data on the client-side via cookies or localstorage. - * Defaults to `false`. - * - */ - disableClientPersistence?: boolean - /** - * Disables automatically converting ISO string event properties into Dates. - * ISO string to Date conversions occur right before sending events to a classic device mode integration, - * after any destination middleware have been ran. - * Defaults to `false`. - */ - disableAutoISOConversion?: boolean - initialPageview?: boolean - cookie?: CookieOptions - storage?: StorageSettings - user?: UserOptions - group?: UserOptions - integrations?: Integrations - 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: CDNSettings) => CDNSettings - /** - * Disables or sets constraints on processing of query string parameters - */ - useQueryString?: - | boolean - | { - aid?: RegExp - uid?: RegExp - } - /** - * Array of high entropy Client Hints to request. These may be rejected by the user agent - only required hints should be requested. - */ - highEntropyValuesClientHints?: HighEntropyHint[] - /** - * When using the snippet, this is the key that points to the global analytics instance (e.g. window.analytics). - * default: analytics - */ - globalAnalyticsKey?: string - - /** - * Disable sending any data to Segment's servers. All emitted events and API calls (including .ready()), will be no-ops, and no cookies or localstorage will be used. - * - * @example - * ### Basic (Will not not fetch any CDN settings) - * ```ts - * disable: process.env.NODE_ENV === 'test' - * ``` - * - * ### Advanced (Fetches CDN Settings. Do not use this unless you require CDN settings for some reason) - * ```ts - * disable: (cdnSettings) => cdnSettings.foo === 'bar' - * ``` - */ - disable?: boolean | ((cdnSettings: CDNSettings) => boolean | Promise) -} - /* analytics-classic stubs */ function _stub(this: never) { console.warn(deprecationWarning) @@ -197,7 +124,7 @@ export class Analytics private _universalStorage: UniversalStorage initialized = false - integrations: Integrations + integrations: IntegrationsOptions options: InitOptions queue: EventQueue diff --git a/packages/browser/src/core/events/index.ts b/packages/browser/src/core/events/index.ts index d85257d5f..bf342524f 100644 --- a/packages/browser/src/core/events/index.ts +++ b/packages/browser/src/core/events/index.ts @@ -2,7 +2,7 @@ import { v4 as uuid } from '@lukeed/uuid' import { ID, User } from '../user' import { Options, - Integrations, + IntegrationsOptions, EventProperties, Traits, SegmentEvent, @@ -53,7 +53,7 @@ export class EventFactory extends CoreEventFactory { event: string, properties?: EventProperties, options?: Options, - globalIntegrations?: Integrations, + globalIntegrations?: IntegrationsOptions, pageCtx?: PageContext ): SegmentEvent { const ev = super.track(event, properties, options, globalIntegrations) @@ -66,7 +66,7 @@ export class EventFactory extends CoreEventFactory { page: string | null, properties?: EventProperties, options?: Options, - globalIntegrations?: Integrations, + globalIntegrations?: IntegrationsOptions, pageCtx?: PageContext ): SegmentEvent { const ev = super.page( @@ -85,7 +85,7 @@ export class EventFactory extends CoreEventFactory { screen: string | null, properties?: EventProperties, options?: Options, - globalIntegrations?: Integrations, + globalIntegrations?: IntegrationsOptions, pageCtx?: PageContext ): SegmentEvent { const ev = super.screen( @@ -103,7 +103,7 @@ export class EventFactory extends CoreEventFactory { userId: ID, traits?: Traits, options?: Options, - globalIntegrations?: Integrations, + globalIntegrations?: IntegrationsOptions, pageCtx?: PageContext ): SegmentEvent { const ev = super.identify(userId, traits, options, globalIntegrations) @@ -115,7 +115,7 @@ export class EventFactory extends CoreEventFactory { groupId: ID, traits?: Traits, options?: Options, - globalIntegrations?: Integrations, + globalIntegrations?: IntegrationsOptions, pageCtx?: PageContext ): SegmentEvent { const ev = super.group(groupId, traits, options, globalIntegrations) @@ -127,7 +127,7 @@ export class EventFactory extends CoreEventFactory { to: string, from: string | null, options?: Options, - globalIntegrations?: Integrations, + globalIntegrations?: IntegrationsOptions, pageCtx?: PageContext ): SegmentEvent { const ev = super.alias(to, from, options, globalIntegrations) diff --git a/packages/browser/src/core/events/interfaces.ts b/packages/browser/src/core/events/interfaces.ts index e76f42568..401406cb7 100644 --- a/packages/browser/src/core/events/interfaces.ts +++ b/packages/browser/src/core/events/interfaces.ts @@ -2,7 +2,7 @@ import { CoreOptions, CoreSegmentEvent, Callback, - Integrations, + IntegrationsOptions, Plan, TrackPlan, PlanEvent, @@ -24,7 +24,7 @@ export type EventProperties = Record export interface SegmentEvent extends CoreSegmentEvent {} export type { - Integrations, + IntegrationsOptions, Plan, TrackPlan, PlanEvent, diff --git a/packages/browser/src/index.ts b/packages/browser/src/index.ts index 1b9bf5a13..7b00d3cd5 100644 --- a/packages/browser/src/index.ts +++ b/packages/browser/src/index.ts @@ -1,10 +1,12 @@ -export { Analytics, AnalyticsSettings, InitOptions } from './core/analytics' -export { - AnalyticsBrowser, +export { Analytics } from './core/analytics' +export { AnalyticsBrowser } from './browser' +export type { AnalyticsBrowserSettings, CDNSettings, RemoteIntegrationSettings, -} from './browser' + AnalyticsSettings, + InitOptions, +} from './browser/settings' export * from './node' export * from './core/context' diff --git a/packages/browser/src/lib/merged-options.ts b/packages/browser/src/lib/merged-options.ts index a1060e523..fe56f58c6 100644 --- a/packages/browser/src/lib/merged-options.ts +++ b/packages/browser/src/lib/merged-options.ts @@ -1,4 +1,4 @@ -import { JSONObject, Options } from '../core/events/interfaces' +import { Options } from '../core/events/interfaces' import { CDNSettings } from '../browser' /** @@ -13,7 +13,7 @@ import { CDNSettings } from '../browser' export function mergedOptions( cdnSettings: CDNSettings, options: Options -): Record { +): Record { const optionOverrides = Object.entries(options.integrations ?? {}).reduce( (overrides, [integration, options]) => { if (typeof options === 'object') { @@ -28,7 +28,7 @@ export function mergedOptions( [integration]: {}, } }, - {} as Record + {} as Record ) return Object.entries(cdnSettings.integrations).reduce( @@ -41,6 +41,6 @@ export function mergedOptions( }, } }, - {} as Record + {} as Record ) } diff --git a/packages/browser/src/plugins/ajs-destination/index.ts b/packages/browser/src/plugins/ajs-destination/index.ts index 8783c89b6..1fc02a5df 100644 --- a/packages/browser/src/plugins/ajs-destination/index.ts +++ b/packages/browser/src/plugins/ajs-destination/index.ts @@ -1,4 +1,4 @@ -import { Integrations, JSONObject } from '../../core/events' +import { IntegrationsOptions, JSONObject } from '../../core/events' import { Alias, Facade, Group, Identify, Page, Track } from '@segment/facade' import { Analytics, InitOptions } from '../../core/analytics' import { CDNSettings } from '../../browser' @@ -332,7 +332,7 @@ export class LegacyDestination implements InternalPluginWithAddMiddleware { export function ajsDestinations( writeKey: string, settings: CDNSettings, - globalIntegrations: Integrations = {}, + globalIntegrations: IntegrationsOptions = {}, options: InitOptions = {}, routingMiddleware?: DestinationMiddlewareFunction, legacyIntegrationSources?: ClassicIntegrationSource[] diff --git a/packages/browser/src/plugins/ajs-destination/loader.ts b/packages/browser/src/plugins/ajs-destination/loader.ts index c808ff2ca..c8668f4d1 100644 --- a/packages/browser/src/plugins/ajs-destination/loader.ts +++ b/packages/browser/src/plugins/ajs-destination/loader.ts @@ -1,5 +1,4 @@ import { Analytics } from '../../core/analytics' -import { RemoteIntegrationSettings } from '../../browser' import { getNextIntegrationsURL } from '../../lib/parse-cdn' import { Context } from '../../core/context' import { User } from '../../core/user' @@ -9,6 +8,7 @@ import { ClassicIntegrationBuilder, ClassicIntegrationSource, } from './types' +import { RemoteIntegrationSettings } from '../../browser/settings' function normalizeName(name: string): string { return name.toLowerCase().replace('.', '').replace(/\s+/g, '-') diff --git a/packages/browser/src/plugins/ajs-destination/utils.ts b/packages/browser/src/plugins/ajs-destination/utils.ts index 49f917a2f..e448c3852 100644 --- a/packages/browser/src/plugins/ajs-destination/utils.ts +++ b/packages/browser/src/plugins/ajs-destination/utils.ts @@ -1,4 +1,4 @@ -import { Integrations } from '@segment/analytics-core' +import { IntegrationsOptions } from '@segment/analytics-core' import { RemoteIntegrationSettings } from '../..' export const isInstallableIntegration = ( @@ -20,7 +20,7 @@ export const isInstallableIntegration = ( export const isDisabledIntegration = ( integrationName: string, - globalIntegrations: Integrations + globalIntegrations: IntegrationsOptions ) => { const allDisableAndNotDefined = globalIntegrations.All === false && diff --git a/packages/browser/src/plugins/remote-loader/index.ts b/packages/browser/src/plugins/remote-loader/index.ts index 359b78c41..4e7a12da3 100644 --- a/packages/browser/src/plugins/remote-loader/index.ts +++ b/packages/browser/src/plugins/remote-loader/index.ts @@ -1,4 +1,4 @@ -import type { Integrations } from '../../core/events/interfaces' +import type { IntegrationsOptions } from '../../core/events/interfaces' import { CDNSettings } from '../../browser' import { JSONObject, JSONValue } from '../../core/events' import { Plugin, InternalPluginWithAddMiddleware } from '../../core/plugin' @@ -198,7 +198,7 @@ function validate(pluginLike: unknown): pluginLike is Plugin[] { } function isPluginDisabled( - userIntegrations: Integrations, + userIntegrations: IntegrationsOptions, remotePlugin: RemotePlugin ) { const creationNameEnabled = userIntegrations[remotePlugin.creationName] @@ -260,7 +260,7 @@ async function loadPluginFactory( export async function remoteLoader( settings: CDNSettings, - userIntegrations: Integrations, + userIntegrations: IntegrationsOptions, mergedIntegrations: Record, options?: InitOptions, routingMiddleware?: DestinationMiddlewareFunction, @@ -281,9 +281,10 @@ export async function remoteLoader( ) || (await loadPluginFactory(remotePlugin, options?.obfuscate)) if (pluginFactory) { + const intg = mergedIntegrations[remotePlugin.name] const plugin = await pluginFactory({ ...remotePlugin.settings, - ...mergedIntegrations[remotePlugin.name], + ...intg, }) const plugins = Array.isArray(plugin) ? plugin : [plugin] diff --git a/packages/browser/src/tester/ajs-tester.ts b/packages/browser/src/tester/ajs-tester.ts index ea317feba..5cd0cdfdc 100644 --- a/packages/browser/src/tester/ajs-tester.ts +++ b/packages/browser/src/tester/ajs-tester.ts @@ -24,7 +24,6 @@ function makeStub(page: playwright.Page) { async track( ...args: Parameters ): Promise { - // @ts-expect-error const ctx = await page.evaluate((innerArgs) => { // @ts-ignore return window.analytics.track(...innerArgs).then((ctx) => { diff --git a/packages/core/src/events/index.ts b/packages/core/src/events/index.ts index 8c772f536..a3f3c56e1 100644 --- a/packages/core/src/events/index.ts +++ b/packages/core/src/events/index.ts @@ -2,7 +2,7 @@ export * from './interfaces' import { dset } from 'dset' import { ID } from '../user' import { - Integrations, + IntegrationsOptions, EventProperties, CoreSegmentEvent, CoreOptions, @@ -67,7 +67,7 @@ export abstract class CoreEventFactory { event: string, properties?: EventProperties, options?: CoreOptions, - globalIntegrations?: Integrations + globalIntegrations?: IntegrationsOptions ) { this.settings.onEventMethodCall({ type: 'track', options }) return this.normalize({ @@ -85,7 +85,7 @@ export abstract class CoreEventFactory { page: string | null, properties?: EventProperties, options?: CoreOptions, - globalIntegrations?: Integrations + globalIntegrations?: IntegrationsOptions ): CoreSegmentEvent { this.settings.onEventMethodCall({ type: 'page', options }) const event: CoreSegmentEvent = { @@ -116,7 +116,7 @@ export abstract class CoreEventFactory { screen: string | null, properties?: EventProperties, options?: CoreOptions, - globalIntegrations?: Integrations + globalIntegrations?: IntegrationsOptions ): CoreSegmentEvent { this.settings.onEventMethodCall({ type: 'screen', options }) const event: CoreSegmentEvent = { @@ -144,7 +144,7 @@ export abstract class CoreEventFactory { userId: ID, traits?: UserTraits, options?: CoreOptions, - globalIntegrations?: Integrations + globalIntegrations?: IntegrationsOptions ): CoreSegmentEvent { this.settings.onEventMethodCall({ type: 'identify', options }) return this.normalize({ @@ -161,7 +161,7 @@ export abstract class CoreEventFactory { groupId: ID, traits?: GroupTraits, options?: CoreOptions, - globalIntegrations?: Integrations + globalIntegrations?: IntegrationsOptions ): CoreSegmentEvent { this.settings.onEventMethodCall({ type: 'group', options }) return this.normalize({ @@ -178,7 +178,7 @@ export abstract class CoreEventFactory { to: string, from: string | null, // TODO: can we make this undefined? options?: CoreOptions, - globalIntegrations?: Integrations + globalIntegrations?: IntegrationsOptions ): CoreSegmentEvent { this.settings.onEventMethodCall({ type: 'alias', options }) const base: CoreSegmentEvent = { diff --git a/packages/core/src/events/interfaces.ts b/packages/core/src/events/interfaces.ts index c4bfe85df..1f1f7117c 100644 --- a/packages/core/src/events/interfaces.ts +++ b/packages/core/src/events/interfaces.ts @@ -21,13 +21,13 @@ export type JSONArray = JSONValue[] export type EventProperties = Record -export type Integrations = { +export type IntegrationsOptions = { All?: boolean | undefined - [integration: string]: boolean | JSONObject | undefined + [integrationName: string]: boolean | Record | undefined } export interface CoreOptions { - integrations?: Integrations | undefined + integrations?: IntegrationsOptions | undefined timestamp?: Timestamp | undefined context?: CoreExtraContext | undefined anonymousId?: string | undefined @@ -227,7 +227,7 @@ export interface CoreSegmentEvent { traits?: Traits | undefined // Traits is only defined in 'identify' and 'group', even if it can be passed in other calls. - integrations?: Integrations | undefined + integrations?: IntegrationsOptions | undefined context?: CoreExtraContext | undefined options?: CoreOptions | undefined diff --git a/packages/core/src/queue/event-queue.ts b/packages/core/src/queue/event-queue.ts index c553e484a..86dd13679 100644 --- a/packages/core/src/queue/event-queue.ts +++ b/packages/core/src/queue/event-queue.ts @@ -4,7 +4,7 @@ import { ON_REMOVE_FROM_FUTURE, PriorityQueue } from '../priority-queue' import { CoreContext, ContextCancelation } from '../context' import { Emitter } from '@segment/analytics-generic-utils' -import { Integrations, JSONObject } from '../events/interfaces' +import { IntegrationsOptions } from '../events/interfaces' import { CorePlugin } from '../plugins' import { createTaskGroup, TaskGroup } from '../task/task-group' import { attempt, ensure } from './delivery' @@ -233,14 +233,15 @@ export abstract class CoreEventQueue< return true } - private availableExtensions(denyList: Integrations) { + private availableExtensions(denyList: IntegrationsOptions) { const available = this.plugins.filter((p) => { // Only filter out destination plugins or the Segment.io plugin if (p.type !== 'destination' && p.name !== 'Segment.io') { return true } - let alternativeNameMatch: boolean | JSONObject | undefined = undefined + let alternativeNameMatch: boolean | Record | undefined = + undefined p.alternativeNames?.forEach((name) => { if (denyList[name] !== undefined) { alternativeNameMatch = denyList[name] diff --git a/packages/node/src/app/types/params.ts b/packages/node/src/app/types/params.ts index 88dd3d247..edbb79603 100644 --- a/packages/node/src/app/types/params.ts +++ b/packages/node/src/app/types/params.ts @@ -3,7 +3,7 @@ import type { UserTraits, CoreExtraContext, EventProperties, - Integrations, + IntegrationsOptions, Timestamp, } from '@segment/analytics-core' @@ -29,7 +29,7 @@ export type AliasParams = { previousId: string context?: ExtraContext | undefined timestamp?: Timestamp | undefined - integrations?: Integrations | undefined + integrations?: IntegrationsOptions | undefined /** * Override the default messageId for the purposes of deduping events. Using a uuid library is strongly encouraged. * @link https://segment.com/docs/partners/faqs/#does-segment-de-dupe-messages @@ -47,7 +47,7 @@ export type GroupParams = { traits?: GroupTraits | undefined context?: ExtraContext | undefined timestamp?: Timestamp | undefined - integrations?: Integrations | undefined + integrations?: IntegrationsOptions | undefined /** * Override the default messageId for the purposes of deduping events. Using a uuid library is strongly encouraged. * @link https://segment.com/docs/partners/faqs/#does-segment-de-dupe-messages @@ -64,7 +64,7 @@ export type IdentifyParams = { traits?: UserTraits | undefined context?: ExtraContext | undefined timestamp?: Timestamp | undefined - integrations?: Integrations | undefined + integrations?: IntegrationsOptions | undefined /** * Override the default messageId for the purposes of deduping events. Using a uuid library is strongly encouraged. * @link https://segment.com/docs/partners/faqs/#does-segment-de-dupe-messages @@ -81,7 +81,7 @@ export type PageParams = { properties?: EventProperties | undefined timestamp?: Timestamp | undefined context?: ExtraContext | undefined - integrations?: Integrations | undefined + integrations?: IntegrationsOptions | undefined /** * Override the default messageId for the purposes of deduping events. Using a uuid library is strongly encouraged. * @link https://segment.com/docs/partners/faqs/#does-segment-de-dupe-messages @@ -94,7 +94,7 @@ export type TrackParams = { properties?: EventProperties | undefined context?: ExtraContext | undefined timestamp?: Timestamp | undefined - integrations?: Integrations | undefined + integrations?: IntegrationsOptions | undefined /** * Override the default messageId for the purposes of deduping events. Using a uuid library is strongly encouraged. * @link https://segment.com/docs/partners/faqs/#does-segment-de-dupe-messages From 5ffdb09a0888e6ff19850fc6b701412a171477bf Mon Sep 17 00:00:00 2001 From: Seth Silesky <5115498+silesky@users.noreply.github.com> Date: Mon, 13 Jan 2025 16:06:34 -0600 Subject: [PATCH 2/3] wip --- .changeset/chilly-mugs-applaud.md | 2 +- packages/browser/src/browser/index.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.changeset/chilly-mugs-applaud.md b/.changeset/chilly-mugs-applaud.md index 380a35ca8..31944b928 100644 --- a/.changeset/chilly-mugs-applaud.md +++ b/.changeset/chilly-mugs-applaud.md @@ -2,4 +2,4 @@ '@segment/analytics-core': patch --- -Fix integration type +Refactor settings diff --git a/packages/browser/src/browser/index.ts b/packages/browser/src/browser/index.ts index c1cb77699..32801d93c 100644 --- a/packages/browser/src/browser/index.ts +++ b/packages/browser/src/browser/index.ts @@ -23,6 +23,7 @@ import { attachInspector } from '../core/inspector' import { Stats } from '../core/stats' import { setGlobalAnalyticsKey } from '../lib/global-analytics-helper' import { CDNSettings, AnalyticsBrowserSettings, InitOptions } from './settings' +import { fetch } from '../lib/fetch' export type { CDNSettings, AnalyticsBrowserSettings } From a0167f0f9370a6807d15fe6156e6172f77f8770b Mon Sep 17 00:00:00 2001 From: Seth Silesky <5115498+silesky@users.noreply.github.com> Date: Mon, 13 Jan 2025 16:10:26 -0600 Subject: [PATCH 3/3] wip --- .changeset/old-stingrays-tie.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/old-stingrays-tie.md diff --git a/.changeset/old-stingrays-tie.md b/.changeset/old-stingrays-tie.md new file mode 100644 index 000000000..fe7f55707 --- /dev/null +++ b/.changeset/old-stingrays-tie.md @@ -0,0 +1,5 @@ +--- +'@segment/analytics-core': patch +--- + +Update types / variable names