diff --git a/packages/aep-mobile/package.json b/packages/aep-mobile/package.json index e2e86bd..36f57cd 100644 --- a/packages/aep-mobile/package.json +++ b/packages/aep-mobile/package.json @@ -1,7 +1,7 @@ { "name": "@adobe/griffon-toolkit-aep-mobile", "description": "Events definitions for the AEP Mobile SDK", - "version": "0.13.0", + "version": "0.14.0", "repository": { "type": "git", "url": "https://github.com/adobe/griffon-toolkit.git", diff --git a/packages/aep-mobile/schemas/personalizationEdgeRequest.json b/packages/aep-mobile/schemas/personalizationEdgeRequest.json index 588f141..b717033 100644 --- a/packages/aep-mobile/schemas/personalizationEdgeRequest.json +++ b/packages/aep-mobile/schemas/personalizationEdgeRequest.json @@ -2,7 +2,11 @@ "$id": "http://griffon.adobe.com/schemas/aep-mobile/personalizationEdgeRequest", "shortDesc": "Edge Personalization Request", "group": "event", - "allOf": [{ "$ref": "http://griffon.adobe.com/schemas/aep-mobile/edgeRequest" }], + "allOf": [ + { + "$ref": "http://griffon.adobe.com/schemas/aep-mobile/edgeRequest" + } + ], "type": "object", "properties": { "payload": { @@ -21,17 +25,25 @@ "description": "The type of event on the edge to execute", "alias": "edgeEventType", "type": "string", - "const": "personalization.request" + "enum": [ + "personalization.request", + "decisioning.propositionFetch" + ] } }, - "required": [ "eventType" ] + "required": [ + "eventType" + ] }, "query": { "inherit": true, "type": "object" } }, - "required": [ "xdm", "query" ] + "required": [ + "xdm", + "query" + ] } }, "required": [ @@ -39,4 +51,4 @@ ] } } -} \ No newline at end of file +} diff --git a/packages/aep-mobile/src/iamMessagesRequest.ts b/packages/aep-mobile/src/iamMessagesRequest.ts index 9f1b8f9..fdfb05c 100644 --- a/packages/aep-mobile/src/iamMessagesRequest.ts +++ b/packages/aep-mobile/src/iamMessagesRequest.ts @@ -12,6 +12,11 @@ governing permissions and limitations under the License. import * as kit from '@adobe/griffon-toolkit'; import schema from '../schemas/iamMessagesRequest.json'; +import { + edgeEventTypeMatcher, + LEGACY_EDGE_EVENT_TYPE, + PROPOSITION_FETCH_EDGE_EVENT_TYPE +} from './personalizationFetchEventTypes'; /** * Contains constants and functions for a IAM Messages Request. @@ -245,7 +250,7 @@ const getSurfaces = kit.search(path.surfaces); */ const matcher = kit.combineAll([ 'payload.ACPExtensionEventData.query.personalization.surfaces', - 'payload.ACPExtensionEventData.xdm.eventType==`personalization.request`', + edgeEventTypeMatcher, kit.combineAny([ 'payload.ACPExtensionEventSource==`com.adobe.eventSource.requestContent`', 'payload.ACPExtensionEventSource==`com.adobe.eventsource.requestcontent`' @@ -312,7 +317,10 @@ const mock = (input) => kit.expandWithPaths(path, { /* ADD CUSTOM CONTENT BELOW */ // additional exports should be added here: -const customExports = {}; +const customExports = { + LEGACY_EDGE_EVENT_TYPE, + PROPOSITION_FETCH_EDGE_EVENT_TYPE +}; /* END CUSTOM CONTENT */ /* The content below is autogenerated. Do not make any changes */ diff --git a/packages/aep-mobile/src/index.ts b/packages/aep-mobile/src/index.ts index fdd35a6..0cdc900 100644 --- a/packages/aep-mobile/src/index.ts +++ b/packages/aep-mobile/src/index.ts @@ -1,5 +1,6 @@ // created from ctix +export * from './personalizationFetchEventTypes'; export { default as analyticsResponse } from './analyticsResponse'; export { default as applicationLaunch } from './applicationLaunch'; export { default as applicationUpgrade } from './applicationUpgrade'; diff --git a/packages/aep-mobile/src/optimizeMessagesRequest.ts b/packages/aep-mobile/src/optimizeMessagesRequest.ts index 3427b7b..78803f5 100644 --- a/packages/aep-mobile/src/optimizeMessagesRequest.ts +++ b/packages/aep-mobile/src/optimizeMessagesRequest.ts @@ -12,6 +12,11 @@ governing permissions and limitations under the License. import * as kit from '@adobe/griffon-toolkit'; import schema from '../schemas/optimizeMessagesRequest.json'; +import { + edgeEventTypeMatcher, + LEGACY_EDGE_EVENT_TYPE, + PROPOSITION_FETCH_EDGE_EVENT_TYPE +} from './personalizationFetchEventTypes'; /** * Contains constants and functions for a Optimize Messages Request. @@ -245,7 +250,7 @@ const getDecisionScopes = kit.search(path.decisionScopes); */ const matcher = kit.combineAll([ 'payload.ACPExtensionEventData.query.personalization.decisionScopes', - 'payload.ACPExtensionEventData.xdm.eventType==`personalization.request`', + edgeEventTypeMatcher, kit.combineAny([ 'payload.ACPExtensionEventSource==`com.adobe.eventSource.requestContent`', 'payload.ACPExtensionEventSource==`com.adobe.eventsource.requestcontent`' @@ -312,7 +317,10 @@ const mock = (input) => kit.expandWithPaths(path, { /* ADD CUSTOM CONTENT BELOW */ // additional exports should be added here: -const customExports = {}; +const customExports = { + LEGACY_EDGE_EVENT_TYPE, + PROPOSITION_FETCH_EDGE_EVENT_TYPE +}; /* END CUSTOM CONTENT */ /* The content below is autogenerated. Do not make any changes */ diff --git a/packages/aep-mobile/src/personalizationEdgeRequest.ts b/packages/aep-mobile/src/personalizationEdgeRequest.ts index 6e73164..c4722b6 100644 --- a/packages/aep-mobile/src/personalizationEdgeRequest.ts +++ b/packages/aep-mobile/src/personalizationEdgeRequest.ts @@ -12,6 +12,11 @@ governing permissions and limitations under the License. import * as kit from '@adobe/griffon-toolkit'; import schema from '../schemas/personalizationEdgeRequest.json'; +import { + edgeEventTypeMatcher, + LEGACY_EDGE_EVENT_TYPE, + PROPOSITION_FETCH_EDGE_EVENT_TYPE +} from './personalizationFetchEventTypes'; /** * Contains constants and functions for a Edge Personalization Request. @@ -209,7 +214,7 @@ const getEdgeEventType = kit.search(path.edgeEventType); * @constant */ const matcher = kit.combineAll([ - 'payload.ACPExtensionEventData.xdm.eventType==`personalization.request`', + edgeEventTypeMatcher, kit.combineAny([ 'payload.ACPExtensionEventSource==`com.adobe.eventSource.requestContent`', 'payload.ACPExtensionEventSource==`com.adobe.eventsource.requestcontent`' @@ -276,7 +281,10 @@ const mock = (input) => kit.expandWithPaths(path, { /* ADD CUSTOM CONTENT BELOW */ // additional exports should be added here: -const customExports = {}; +const customExports = { + LEGACY_EDGE_EVENT_TYPE, + PROPOSITION_FETCH_EDGE_EVENT_TYPE +}; /* END CUSTOM CONTENT */ /* The content below is autogenerated. Do not make any changes */ diff --git a/packages/aep-mobile/src/personalizationFetchEventTypes.ts b/packages/aep-mobile/src/personalizationFetchEventTypes.ts new file mode 100644 index 0000000..c5a9f09 --- /dev/null +++ b/packages/aep-mobile/src/personalizationFetchEventTypes.ts @@ -0,0 +1,38 @@ +/* +Copyright 2026 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +import * as kit from '@adobe/griffon-toolkit'; + +/** + * XDM eventType sent by Mobile SDKs prior to Optimize 5.x. + * Kept for backward compatibility — Assurance must continue matching sessions + * from older SDK builds that still emit this value. + */ +export const LEGACY_EDGE_EVENT_TYPE = 'personalization.request'; + +/** + * XDM eventType introduced in Optimize 5.x (aepsdk-optimize-ios PR #159). + * Aligns Mobile SDK with the current XDM spec already used by Web SDK. + * Ref: MOB-24547 / PLATIR-51299 + */ +export const PROPOSITION_FETCH_EDGE_EVENT_TYPE = 'decisioning.propositionFetch'; + +/** + * JMESPath matcher expression that accepts both the legacy and current + * XDM eventType for a personalization fetch edge request. + * Drop-in replacement for the single-value eventType clause inside + * kit.combineAll([...]) matcher definitions. + */ +export const edgeEventTypeMatcher = kit.combineAny([ + `payload.ACPExtensionEventData.xdm.eventType==\`${LEGACY_EDGE_EVENT_TYPE}\``, + `payload.ACPExtensionEventData.xdm.eventType==\`${PROPOSITION_FETCH_EDGE_EVENT_TYPE}\`` +]); diff --git a/packages/aep-mobile/test/personalizationFetchEventTypes.spec.ts b/packages/aep-mobile/test/personalizationFetchEventTypes.spec.ts new file mode 100644 index 0000000..21115f4 --- /dev/null +++ b/packages/aep-mobile/test/personalizationFetchEventTypes.spec.ts @@ -0,0 +1,106 @@ +/* +Copyright 2026 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +import optimizeMessagesRequest from '../src/optimizeMessagesRequest'; +import personalizationEdgeRequest from '../src/personalizationEdgeRequest'; +import iamMessagesRequest from '../src/iamMessagesRequest'; +import { + LEGACY_EDGE_EVENT_TYPE, + PROPOSITION_FETCH_EDGE_EVENT_TYPE +} from '../src/personalizationFetchEventTypes'; + +describe('personalizationFetchEventTypes', () => { + describe('constants', () => { + it('LEGACY_EDGE_EVENT_TYPE is the deprecated personalization.request value', () => { + expect(LEGACY_EDGE_EVENT_TYPE).toBe('personalization.request'); + }); + + it('PROPOSITION_FETCH_EDGE_EVENT_TYPE is the current decisioning.propositionFetch value', () => { + expect(PROPOSITION_FETCH_EDGE_EVENT_TYPE).toBe('decisioning.propositionFetch'); + }); + }); + + describe('optimizeMessagesRequest backward compatibility', () => { + it('matches a legacy personalization.request optimize event', () => { + const event = optimizeMessagesRequest.mock({ + edgeEventType: LEGACY_EDGE_EVENT_TYPE, + decisionScopes: ['demoLoc1'] + }); + expect(optimizeMessagesRequest.isMatch(event)).toBe(true); + }); + + it('matches a new decisioning.propositionFetch optimize event', () => { + const event = optimizeMessagesRequest.mock({ + edgeEventType: PROPOSITION_FETCH_EDGE_EVENT_TYPE, + decisionScopes: ['demoLoc1'] + }); + expect(optimizeMessagesRequest.isMatch(event)).toBe(true); + }); + + it('does not match an unrelated edge event type', () => { + const event = optimizeMessagesRequest.mock({ + edgeEventType: 'decisioning.propositionDisplay', + decisionScopes: ['demoLoc1'] + }); + expect(optimizeMessagesRequest.isMatch(event)).toBe(false); + }); + }); + + describe('personalizationEdgeRequest backward compatibility', () => { + it('matches a legacy personalization.request edge event', () => { + const event = personalizationEdgeRequest.mock({ + edgeEventType: LEGACY_EDGE_EVENT_TYPE + }); + expect(personalizationEdgeRequest.isMatch(event)).toBe(true); + }); + + it('matches a new decisioning.propositionFetch edge event', () => { + const event = personalizationEdgeRequest.mock({ + edgeEventType: PROPOSITION_FETCH_EDGE_EVENT_TYPE + }); + expect(personalizationEdgeRequest.isMatch(event)).toBe(true); + }); + + it('does not match an unrelated edge event type', () => { + const event = personalizationEdgeRequest.mock({ + edgeEventType: 'decisioning.propositionDisplay' + }); + expect(personalizationEdgeRequest.isMatch(event)).toBe(false); + }); + }); + + describe('iamMessagesRequest backward compatibility', () => { + it('matches a legacy personalization.request IAM event', () => { + const event = iamMessagesRequest.mock({ + edgeEventType: LEGACY_EDGE_EVENT_TYPE, + surfaces: ['mobileapp://com.example.app'] + }); + expect(iamMessagesRequest.isMatch(event)).toBe(true); + }); + + it('matches a new decisioning.propositionFetch IAM event', () => { + const event = iamMessagesRequest.mock({ + edgeEventType: PROPOSITION_FETCH_EDGE_EVENT_TYPE, + surfaces: ['mobileapp://com.example.app'] + }); + expect(iamMessagesRequest.isMatch(event)).toBe(true); + }); + + it('does not match an unrelated edge event type', () => { + const event = iamMessagesRequest.mock({ + edgeEventType: 'decisioning.propositionDisplay', + surfaces: ['mobileapp://com.example.app'] + }); + expect(iamMessagesRequest.isMatch(event)).toBe(false); + }); + }); +});