@player-ui/beacon-plugin 0.13.0-next.5 → 0.13.0-next.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/BeaconPlugin.native.js.map +1 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/beacon.ts +0 -1
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/beacon/core/src/index.ts","../../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/beacon/core/src/beacon.ts","../../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/beacon/core/src/symbols.ts"],"sourcesContent":["export * from \"./beacon\";\nexport * from \"./symbols\";\n","import { SyncBailHook, AsyncSeriesWaterfallHook, SyncHook } from \"tapable-ts\";\nimport type {\n Player,\n PlayerPlugin,\n PlayerFlowState,\n Logger,\n Asset,\n View,\n} from \"@player-ui/player\";\nimport { resolveDataRefs } from \"@player-ui/player\";\nimport { setIn } from \"timm\";\nimport { BeaconPluginSymbol } from \"./symbols\";\n\nexport type BeaconDataType = string | Record<string, any>;\n\nexport interface BeaconMetaData {\n /** Additional data to send along with beacons */\n beacon?: BeaconDataType;\n}\n\nexport interface AssetBeaconInfo {\n /** Additional data about the asset */\n metaData?: BeaconMetaData;\n}\n\nexport type AssetBeacon = Asset & AssetBeaconInfo;\nexport type ViewBeacon = View & AssetBeaconInfo;\n\nexport interface BeaconPluginPlugin {\n /** Use this to tap into the beacon plugin hooks */\n apply: (beaconPlugin: BeaconPlugin) => void;\n}\n\nexport interface BeaconPluginOptions {\n /** Callback when a beacon is published */\n callback?: (beacon: any) => void;\n /** A set of plugins to load */\n plugins?: BeaconPluginPlugin[];\n}\n\ninterface BeaconContext {\n /** The full current view */\n view?: ViewBeacon;\n}\n\nexport interface BeaconArgs {\n /** The action being performed */\n action: string;\n /** The specific element that the beacon originated from */\n element: string;\n /** The asset firing the beacon */\n asset: AssetBeacon;\n /** The current view */\n view?: ViewBeacon;\n /** Any additional data to attach to the event */\n data?: any;\n}\n\nexport interface HookArgs extends BeaconArgs {\n /** The current player state */\n state?: PlayerFlowState;\n /** The beacon plugin logger */\n logger: Logger;\n}\n\n/**\n * A player plugin to manage beacon events.\n * It automatically keeps track of the current user's view, and adds additional metaData to each beacon event.\n */\nexport class BeaconPlugin implements PlayerPlugin {\n name = \"Beacon\";\n\n static Symbol = BeaconPluginSymbol;\n public readonly symbol = BeaconPlugin.Symbol;\n\n private player?: Player;\n private logger?: Logger;\n\n private beaconContext: BeaconContext = {\n view: undefined,\n };\n\n private resolveDataRefs?: <T>(data: T) => T;\n\n public hooks = {\n buildBeacon: new AsyncSeriesWaterfallHook<[unknown, HookArgs]>(),\n cancelBeacon: new SyncBailHook<[HookArgs], boolean>(),\n publishBeacon: new SyncHook<[any]>(),\n };\n\n constructor(options?: BeaconPluginOptions) {\n if (options?.plugins) {\n options.plugins.forEach((plugin) => {\n plugin.apply(this);\n });\n }\n\n if (options?.callback) {\n this.hooks.publishBeacon.tap(\"BeaconCallback\", (beacon: any) => {\n if (options.callback) {\n options.callback(beacon);\n }\n });\n }\n }\n\n apply(player: Player) {\n this.player = player;\n this.logger = player.logger;\n\n player.hooks.state.tap(this.name, (playerState) => {\n if (playerState.status === \"in-progress\") {\n this.resolveDataRefs = (data) =>\n resolveDataRefs(data, {\n model: playerState.controllers.data,\n evaluate: playerState.controllers.expression.evaluate,\n });\n }\n });\n\n player.hooks.viewController.tap(this.name, (vc) => {\n this.beaconContext = {\n view: undefined,\n };\n\n vc.hooks.view.tap(this.name, (view) => {\n let beaconedView = false;\n\n view.hooks.parser.tap(this.name, (parser) => {\n /* If there is a 'beacon' property in an asset or view, skip resolving as we\n are doing this manually when beacon is fired. */\n parser.hooks.onCreateASTNode.tap(this.name, (obj) => {\n if (obj?.type !== \"asset\" && obj?.type !== \"view\") return undefined;\n\n const propertiesToSkip =\n obj.plugins?.stringResolver?.propertiesToSkip ?? [];\n\n if (propertiesToSkip.includes(\"beacon\")) return undefined;\n\n
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/beacon/core/src/index.ts","../../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/beacon/core/src/beacon.ts","../../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/beacon/core/src/symbols.ts"],"sourcesContent":["export * from \"./beacon\";\nexport * from \"./symbols\";\n","import { SyncBailHook, AsyncSeriesWaterfallHook, SyncHook } from \"tapable-ts\";\nimport type {\n Player,\n PlayerPlugin,\n PlayerFlowState,\n Logger,\n Asset,\n View,\n} from \"@player-ui/player\";\nimport { resolveDataRefs } from \"@player-ui/player\";\nimport { setIn } from \"timm\";\nimport { BeaconPluginSymbol } from \"./symbols\";\n\nexport type BeaconDataType = string | Record<string, any>;\n\nexport interface BeaconMetaData {\n /** Additional data to send along with beacons */\n beacon?: BeaconDataType;\n}\n\nexport interface AssetBeaconInfo {\n /** Additional data about the asset */\n metaData?: BeaconMetaData;\n}\n\nexport type AssetBeacon = Asset & AssetBeaconInfo;\nexport type ViewBeacon = View & AssetBeaconInfo;\n\nexport interface BeaconPluginPlugin {\n /** Use this to tap into the beacon plugin hooks */\n apply: (beaconPlugin: BeaconPlugin) => void;\n}\n\nexport interface BeaconPluginOptions {\n /** Callback when a beacon is published */\n callback?: (beacon: any) => void;\n /** A set of plugins to load */\n plugins?: BeaconPluginPlugin[];\n}\n\ninterface BeaconContext {\n /** The full current view */\n view?: ViewBeacon;\n}\n\nexport interface BeaconArgs {\n /** The action being performed */\n action: string;\n /** The specific element that the beacon originated from */\n element: string;\n /** The asset firing the beacon */\n asset: AssetBeacon;\n /** The current view */\n view?: ViewBeacon;\n /** Any additional data to attach to the event */\n data?: any;\n}\n\nexport interface HookArgs extends BeaconArgs {\n /** The current player state */\n state?: PlayerFlowState;\n /** The beacon plugin logger */\n logger: Logger;\n}\n\n/**\n * A player plugin to manage beacon events.\n * It automatically keeps track of the current user's view, and adds additional metaData to each beacon event.\n */\nexport class BeaconPlugin implements PlayerPlugin {\n name = \"Beacon\";\n\n static Symbol = BeaconPluginSymbol;\n public readonly symbol = BeaconPlugin.Symbol;\n\n private player?: Player;\n private logger?: Logger;\n\n private beaconContext: BeaconContext = {\n view: undefined,\n };\n\n private resolveDataRefs?: <T>(data: T) => T;\n\n public hooks = {\n buildBeacon: new AsyncSeriesWaterfallHook<[unknown, HookArgs]>(),\n cancelBeacon: new SyncBailHook<[HookArgs], boolean>(),\n publishBeacon: new SyncHook<[any]>(),\n };\n\n constructor(options?: BeaconPluginOptions) {\n if (options?.plugins) {\n options.plugins.forEach((plugin) => {\n plugin.apply(this);\n });\n }\n\n if (options?.callback) {\n this.hooks.publishBeacon.tap(\"BeaconCallback\", (beacon: any) => {\n if (options.callback) {\n options.callback(beacon);\n }\n });\n }\n }\n\n apply(player: Player) {\n this.player = player;\n this.logger = player.logger;\n\n player.hooks.state.tap(this.name, (playerState) => {\n if (playerState.status === \"in-progress\") {\n this.resolveDataRefs = (data) =>\n resolveDataRefs(data, {\n model: playerState.controllers.data,\n evaluate: playerState.controllers.expression.evaluate,\n });\n }\n });\n\n player.hooks.viewController.tap(this.name, (vc) => {\n this.beaconContext = {\n view: undefined,\n };\n\n vc.hooks.view.tap(this.name, (view) => {\n let beaconedView = false;\n\n view.hooks.parser.tap(this.name, (parser) => {\n /* If there is a 'beacon' property in an asset or view, skip resolving as we\n are doing this manually when beacon is fired. */\n parser.hooks.onCreateASTNode.tap(this.name, (obj) => {\n if (obj?.type !== \"asset\" && obj?.type !== \"view\") return undefined;\n\n const propertiesToSkip =\n obj.plugins?.stringResolver?.propertiesToSkip ?? [];\n\n if (propertiesToSkip.includes(\"beacon\")) return undefined;\n\n obj.plugins = setIn(\n obj.plugins ?? {},\n [\"stringResolver\", \"propertiesToSkip\"],\n [\"beacon\", ...propertiesToSkip],\n ) as any;\n\n return obj;\n });\n });\n\n view.hooks.onUpdate.tap(this.name, (viewUpdate: ViewBeacon) => {\n this.beaconContext = {\n view: viewUpdate,\n };\n\n if (!beaconedView) {\n this.beacon({\n action: \"viewed\",\n element: \"view\",\n asset: viewUpdate,\n view: viewUpdate,\n });\n\n beaconedView = true;\n }\n });\n });\n });\n\n player.hooks.expressionEvaluator.tap(this.name, (evaluator) => {\n evaluator.addExpressionFunction(\"beacon\", (_ctx, action, data) => {\n const view = this.beaconContext.view || ({} as ViewBeacon);\n this.beacon({\n action: action as string,\n data: data as any,\n element: \"view\",\n asset: view,\n view,\n });\n });\n });\n }\n\n beacon(event: BeaconArgs) {\n const { action, element, asset, view } = event;\n const { view: currentView } = this.beaconContext;\n setTimeout(async () => {\n const unresolvedData = event?.data || event.asset?.metaData?.beacon;\n\n const data = this.resolveDataRefs?.(unresolvedData) ?? unresolvedData;\n\n const defaultBeacon = {\n action,\n element,\n data,\n assetId: asset?.id,\n viewId: currentView?.id,\n };\n const state = this.player?.getState();\n const hookArgs = {\n ...event,\n data,\n state,\n view: view ?? currentView,\n logger: this.logger as Logger,\n };\n let beacon =\n (await this.hooks.buildBeacon.call(defaultBeacon, hookArgs)) ||\n defaultBeacon;\n\n // Re-resolve data refs in case the hook modified the beacon and introduced more\n if (beacon !== defaultBeacon && this.resolveDataRefs) {\n beacon = this.resolveDataRefs(beacon);\n }\n\n const shouldCancel = this.hooks.cancelBeacon.call(hookArgs) || false;\n\n if (!shouldCancel) {\n this.logger?.debug(\"Sending beacon event\", beacon);\n this.hooks.publishBeacon.call(beacon);\n }\n }, 0);\n }\n}\n","export const BeaconPluginSymbol = Symbol.for(\"BeaconPlugin\");\n"],"mappings":"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","names":[]}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/beacon/core/src/beacon.ts","../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/beacon/core/src/symbols.ts"],"sourcesContent":["import { SyncBailHook, AsyncSeriesWaterfallHook, SyncHook } from \"tapable-ts\";\nimport type {\n Player,\n PlayerPlugin,\n PlayerFlowState,\n Logger,\n Asset,\n View,\n} from \"@player-ui/player\";\nimport { resolveDataRefs } from \"@player-ui/player\";\nimport { setIn } from \"timm\";\nimport { BeaconPluginSymbol } from \"./symbols\";\n\nexport type BeaconDataType = string | Record<string, any>;\n\nexport interface BeaconMetaData {\n /** Additional data to send along with beacons */\n beacon?: BeaconDataType;\n}\n\nexport interface AssetBeaconInfo {\n /** Additional data about the asset */\n metaData?: BeaconMetaData;\n}\n\nexport type AssetBeacon = Asset & AssetBeaconInfo;\nexport type ViewBeacon = View & AssetBeaconInfo;\n\nexport interface BeaconPluginPlugin {\n /** Use this to tap into the beacon plugin hooks */\n apply: (beaconPlugin: BeaconPlugin) => void;\n}\n\nexport interface BeaconPluginOptions {\n /** Callback when a beacon is published */\n callback?: (beacon: any) => void;\n /** A set of plugins to load */\n plugins?: BeaconPluginPlugin[];\n}\n\ninterface BeaconContext {\n /** The full current view */\n view?: ViewBeacon;\n}\n\nexport interface BeaconArgs {\n /** The action being performed */\n action: string;\n /** The specific element that the beacon originated from */\n element: string;\n /** The asset firing the beacon */\n asset: AssetBeacon;\n /** The current view */\n view?: ViewBeacon;\n /** Any additional data to attach to the event */\n data?: any;\n}\n\nexport interface HookArgs extends BeaconArgs {\n /** The current player state */\n state?: PlayerFlowState;\n /** The beacon plugin logger */\n logger: Logger;\n}\n\n/**\n * A player plugin to manage beacon events.\n * It automatically keeps track of the current user's view, and adds additional metaData to each beacon event.\n */\nexport class BeaconPlugin implements PlayerPlugin {\n name = \"Beacon\";\n\n static Symbol = BeaconPluginSymbol;\n public readonly symbol = BeaconPlugin.Symbol;\n\n private player?: Player;\n private logger?: Logger;\n\n private beaconContext: BeaconContext = {\n view: undefined,\n };\n\n private resolveDataRefs?: <T>(data: T) => T;\n\n public hooks = {\n buildBeacon: new AsyncSeriesWaterfallHook<[unknown, HookArgs]>(),\n cancelBeacon: new SyncBailHook<[HookArgs], boolean>(),\n publishBeacon: new SyncHook<[any]>(),\n };\n\n constructor(options?: BeaconPluginOptions) {\n if (options?.plugins) {\n options.plugins.forEach((plugin) => {\n plugin.apply(this);\n });\n }\n\n if (options?.callback) {\n this.hooks.publishBeacon.tap(\"BeaconCallback\", (beacon: any) => {\n if (options.callback) {\n options.callback(beacon);\n }\n });\n }\n }\n\n apply(player: Player) {\n this.player = player;\n this.logger = player.logger;\n\n player.hooks.state.tap(this.name, (playerState) => {\n if (playerState.status === \"in-progress\") {\n this.resolveDataRefs = (data) =>\n resolveDataRefs(data, {\n model: playerState.controllers.data,\n evaluate: playerState.controllers.expression.evaluate,\n });\n }\n });\n\n player.hooks.viewController.tap(this.name, (vc) => {\n this.beaconContext = {\n view: undefined,\n };\n\n vc.hooks.view.tap(this.name, (view) => {\n let beaconedView = false;\n\n view.hooks.parser.tap(this.name, (parser) => {\n /* If there is a 'beacon' property in an asset or view, skip resolving as we\n are doing this manually when beacon is fired. */\n parser.hooks.onCreateASTNode.tap(this.name, (obj) => {\n if (obj?.type !== \"asset\" && obj?.type !== \"view\") return undefined;\n\n const propertiesToSkip =\n obj.plugins?.stringResolver?.propertiesToSkip ?? [];\n\n if (propertiesToSkip.includes(\"beacon\")) return undefined;\n\n
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/beacon/core/src/beacon.ts","../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/plugins/beacon/core/src/symbols.ts"],"sourcesContent":["import { SyncBailHook, AsyncSeriesWaterfallHook, SyncHook } from \"tapable-ts\";\nimport type {\n Player,\n PlayerPlugin,\n PlayerFlowState,\n Logger,\n Asset,\n View,\n} from \"@player-ui/player\";\nimport { resolveDataRefs } from \"@player-ui/player\";\nimport { setIn } from \"timm\";\nimport { BeaconPluginSymbol } from \"./symbols\";\n\nexport type BeaconDataType = string | Record<string, any>;\n\nexport interface BeaconMetaData {\n /** Additional data to send along with beacons */\n beacon?: BeaconDataType;\n}\n\nexport interface AssetBeaconInfo {\n /** Additional data about the asset */\n metaData?: BeaconMetaData;\n}\n\nexport type AssetBeacon = Asset & AssetBeaconInfo;\nexport type ViewBeacon = View & AssetBeaconInfo;\n\nexport interface BeaconPluginPlugin {\n /** Use this to tap into the beacon plugin hooks */\n apply: (beaconPlugin: BeaconPlugin) => void;\n}\n\nexport interface BeaconPluginOptions {\n /** Callback when a beacon is published */\n callback?: (beacon: any) => void;\n /** A set of plugins to load */\n plugins?: BeaconPluginPlugin[];\n}\n\ninterface BeaconContext {\n /** The full current view */\n view?: ViewBeacon;\n}\n\nexport interface BeaconArgs {\n /** The action being performed */\n action: string;\n /** The specific element that the beacon originated from */\n element: string;\n /** The asset firing the beacon */\n asset: AssetBeacon;\n /** The current view */\n view?: ViewBeacon;\n /** Any additional data to attach to the event */\n data?: any;\n}\n\nexport interface HookArgs extends BeaconArgs {\n /** The current player state */\n state?: PlayerFlowState;\n /** The beacon plugin logger */\n logger: Logger;\n}\n\n/**\n * A player plugin to manage beacon events.\n * It automatically keeps track of the current user's view, and adds additional metaData to each beacon event.\n */\nexport class BeaconPlugin implements PlayerPlugin {\n name = \"Beacon\";\n\n static Symbol = BeaconPluginSymbol;\n public readonly symbol = BeaconPlugin.Symbol;\n\n private player?: Player;\n private logger?: Logger;\n\n private beaconContext: BeaconContext = {\n view: undefined,\n };\n\n private resolveDataRefs?: <T>(data: T) => T;\n\n public hooks = {\n buildBeacon: new AsyncSeriesWaterfallHook<[unknown, HookArgs]>(),\n cancelBeacon: new SyncBailHook<[HookArgs], boolean>(),\n publishBeacon: new SyncHook<[any]>(),\n };\n\n constructor(options?: BeaconPluginOptions) {\n if (options?.plugins) {\n options.plugins.forEach((plugin) => {\n plugin.apply(this);\n });\n }\n\n if (options?.callback) {\n this.hooks.publishBeacon.tap(\"BeaconCallback\", (beacon: any) => {\n if (options.callback) {\n options.callback(beacon);\n }\n });\n }\n }\n\n apply(player: Player) {\n this.player = player;\n this.logger = player.logger;\n\n player.hooks.state.tap(this.name, (playerState) => {\n if (playerState.status === \"in-progress\") {\n this.resolveDataRefs = (data) =>\n resolveDataRefs(data, {\n model: playerState.controllers.data,\n evaluate: playerState.controllers.expression.evaluate,\n });\n }\n });\n\n player.hooks.viewController.tap(this.name, (vc) => {\n this.beaconContext = {\n view: undefined,\n };\n\n vc.hooks.view.tap(this.name, (view) => {\n let beaconedView = false;\n\n view.hooks.parser.tap(this.name, (parser) => {\n /* If there is a 'beacon' property in an asset or view, skip resolving as we\n are doing this manually when beacon is fired. */\n parser.hooks.onCreateASTNode.tap(this.name, (obj) => {\n if (obj?.type !== \"asset\" && obj?.type !== \"view\") return undefined;\n\n const propertiesToSkip =\n obj.plugins?.stringResolver?.propertiesToSkip ?? [];\n\n if (propertiesToSkip.includes(\"beacon\")) return undefined;\n\n obj.plugins = setIn(\n obj.plugins ?? {},\n [\"stringResolver\", \"propertiesToSkip\"],\n [\"beacon\", ...propertiesToSkip],\n ) as any;\n\n return obj;\n });\n });\n\n view.hooks.onUpdate.tap(this.name, (viewUpdate: ViewBeacon) => {\n this.beaconContext = {\n view: viewUpdate,\n };\n\n if (!beaconedView) {\n this.beacon({\n action: \"viewed\",\n element: \"view\",\n asset: viewUpdate,\n view: viewUpdate,\n });\n\n beaconedView = true;\n }\n });\n });\n });\n\n player.hooks.expressionEvaluator.tap(this.name, (evaluator) => {\n evaluator.addExpressionFunction(\"beacon\", (_ctx, action, data) => {\n const view = this.beaconContext.view || ({} as ViewBeacon);\n this.beacon({\n action: action as string,\n data: data as any,\n element: \"view\",\n asset: view,\n view,\n });\n });\n });\n }\n\n beacon(event: BeaconArgs) {\n const { action, element, asset, view } = event;\n const { view: currentView } = this.beaconContext;\n setTimeout(async () => {\n const unresolvedData = event?.data || event.asset?.metaData?.beacon;\n\n const data = this.resolveDataRefs?.(unresolvedData) ?? unresolvedData;\n\n const defaultBeacon = {\n action,\n element,\n data,\n assetId: asset?.id,\n viewId: currentView?.id,\n };\n const state = this.player?.getState();\n const hookArgs = {\n ...event,\n data,\n state,\n view: view ?? currentView,\n logger: this.logger as Logger,\n };\n let beacon =\n (await this.hooks.buildBeacon.call(defaultBeacon, hookArgs)) ||\n defaultBeacon;\n\n // Re-resolve data refs in case the hook modified the beacon and introduced more\n if (beacon !== defaultBeacon && this.resolveDataRefs) {\n beacon = this.resolveDataRefs(beacon);\n }\n\n const shouldCancel = this.hooks.cancelBeacon.call(hookArgs) || false;\n\n if (!shouldCancel) {\n this.logger?.debug(\"Sending beacon event\", beacon);\n this.hooks.publishBeacon.call(beacon);\n }\n }, 0);\n }\n}\n","export const BeaconPluginSymbol = Symbol.for(\"BeaconPlugin\");\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
"types"
|
|
7
7
|
],
|
|
8
8
|
"name": "@player-ui/beacon-plugin",
|
|
9
|
-
"version": "0.13.0-next.
|
|
9
|
+
"version": "0.13.0-next.7",
|
|
10
10
|
"main": "dist/cjs/index.cjs",
|
|
11
11
|
"peerDependencies": {
|
|
12
|
-
"@player-ui/player": "0.13.0-next.
|
|
13
|
-
"@player-ui/types": "0.13.0-next.
|
|
12
|
+
"@player-ui/player": "0.13.0-next.7",
|
|
13
|
+
"@player-ui/types": "0.13.0-next.7"
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
16
|
"@player-ui/make-flow": "workspace:*"
|
package/src/beacon.ts
CHANGED
|
@@ -137,7 +137,6 @@ export class BeaconPlugin implements PlayerPlugin {
|
|
|
137
137
|
|
|
138
138
|
if (propertiesToSkip.includes("beacon")) return undefined;
|
|
139
139
|
|
|
140
|
-
// eslint-disable-next-line no-param-reassign
|
|
141
140
|
obj.plugins = setIn(
|
|
142
141
|
obj.plugins ?? {},
|
|
143
142
|
["stringResolver", "propertiesToSkip"],
|