@namiml/sdk-core 3.4.3-dev.202606120301 → 3.4.3-dev.202606121440

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/index.cjs CHANGED
@@ -98,7 +98,7 @@ const {
98
98
  // version — stamped by scripts/version.sh
99
99
  NAMI_SDK_VERSION: exports.NAMI_SDK_VERSION = "3.4.3",
100
100
  // full package version including dev suffix — stamped by scripts/version.sh
101
- NAMI_SDK_PACKAGE_VERSION: exports.NAMI_SDK_PACKAGE_VERSION = "3.4.3-dev.202606120301",
101
+ NAMI_SDK_PACKAGE_VERSION: exports.NAMI_SDK_PACKAGE_VERSION = "3.4.3-dev.202606121440",
102
102
  // environments
103
103
  PRODUCTION: exports.PRODUCTION = "production", DEVELOPMENT: exports.DEVELOPMENT = "development",
104
104
  // error messages
@@ -12548,6 +12548,7 @@ exports.NamiFlowActionFunction = void 0;
12548
12548
  NamiFlowActionFunction["SET_TAGS"] = "setTags";
12549
12549
  NamiFlowActionFunction["PAUSE"] = "flowPause";
12550
12550
  NamiFlowActionFunction["RESUME"] = "flowResume";
12551
+ NamiFlowActionFunction["SET_LAUNCH_CONTEXT"] = "setLaunchContext";
12551
12552
  })(exports.NamiFlowActionFunction || (exports.NamiFlowActionFunction = {}));
12552
12553
  const HandoffTag = {
12553
12554
  SEQUENCE: '__handoff_sequence__',
@@ -12692,89 +12693,33 @@ class NamiConditionEvaluator {
12692
12693
  return true;
12693
12694
  return false;
12694
12695
  }
12695
- // this.log(
12696
- // `Evaluating filter: ${filter.operator} with values: ${filter.values} against resolved value: ${JSON.stringify(resolvedValue)}`
12697
- // );
12698
12696
  switch (filter.operator) {
12699
12697
  case FilterOperator.I_CONTAINS:
12700
12698
  if (Array.isArray(resolvedValue)) {
12701
- const result = filter.values.some(expected => {
12702
- const expectedStr = String(expected);
12703
- return resolvedValue.some(item => item.localeCompare(expectedStr, undefined, { sensitivity: 'accent' }) === 0);
12704
- });
12705
- // this.log(`i_contains evaluation result: ${result}`);
12699
+ const result = filter.values.some(expected => typeof expected === 'string' && resolvedValue.some(item => item.localeCompare(expected, undefined, { sensitivity: 'accent' }) === 0));
12706
12700
  return result;
12707
12701
  }
12708
12702
  this.log('Resolved value is not an array of strings for i_contains.');
12709
12703
  return false;
12710
12704
  case FilterOperator.EQUALS: {
12711
- const result = filter.values.some(expected => {
12712
- const expectedStr = String(expected);
12713
- if (typeof resolvedValue === 'string') {
12714
- // this.log(`Comparing string ${resolvedValue} == ${expected}`);
12715
- return resolvedValue === expectedStr;
12716
- }
12717
- if (typeof resolvedValue === 'boolean') {
12718
- const expectedBool = expectedStr.toLowerCase() === 'true';
12719
- // this.log(`Comparing boolean ${resolvedValue} == ${expectedBool}`);
12720
- return resolvedValue === expectedBool;
12721
- }
12722
- this.log(`Unsupported type for equals comparison: ${typeof resolvedValue}`);
12723
- return false;
12724
- });
12725
- // this.log(`equals evaluation result: ${result}`);
12726
- return result;
12705
+ return filter.values.some(expected => this.strictEquals(resolvedValue, expected, false));
12727
12706
  }
12728
12707
  case FilterOperator.I_EQUALS: {
12729
- const result = filter.values.some(expected => {
12730
- const expectedStr = String(expected);
12731
- if (typeof resolvedValue === 'string') {
12732
- const match = resolvedValue.localeCompare(expectedStr, undefined, { sensitivity: 'accent' }) === 0;
12733
- // this.log(`Comparing string ${resolvedValue} ~= ${expected}: ${match}`);
12734
- return match;
12735
- }
12736
- if (typeof resolvedValue === 'boolean') {
12737
- const expectedBool = expectedStr.toLowerCase() === 'true';
12738
- // this.log(`Comparing boolean ${resolvedValue} ~= ${expectedBool}`);
12739
- return resolvedValue === expectedBool;
12740
- }
12741
- this.log(`Unsupported type for i_equals comparison: ${typeof resolvedValue}`);
12742
- return false;
12743
- });
12744
- // this.log(`i_equals evaluation result: ${result}`);
12745
- return result;
12708
+ return filter.values.some(expected => this.strictEquals(resolvedValue, expected, true));
12746
12709
  }
12747
12710
  case FilterOperator.NOT_EQUALS: {
12748
- const result = filter.values.every(expected => {
12749
- const expectedStr = String(expected);
12750
- if (typeof resolvedValue === 'string') {
12751
- return resolvedValue !== expectedStr;
12752
- }
12753
- return true;
12754
- });
12755
- // this.log(`not_equals evaluation result: ${result}`);
12756
- return result;
12711
+ return filter.values.every(expected => !this.strictEquals(resolvedValue, expected, false));
12757
12712
  }
12758
12713
  case FilterOperator.NOT_I_EQUALS: {
12759
- const result = filter.values.every(expected => {
12760
- const expectedStr = String(expected);
12761
- if (typeof resolvedValue === 'string') {
12762
- return (resolvedValue.localeCompare(expectedStr, undefined, { sensitivity: 'accent' }) !== 0);
12763
- }
12764
- return true;
12765
- });
12766
- // this.log(`not_i_equals evaluation result: ${result}`);
12767
- return result;
12714
+ return filter.values.every(expected => !this.strictEquals(resolvedValue, expected, true));
12768
12715
  }
12769
12716
  case FilterOperator.NOT_CONTAINS: {
12770
12717
  const result = filter.values.every(expected => {
12771
- const expectedStr = String(expected);
12772
- if (typeof resolvedValue === 'string') {
12773
- return !resolvedValue.includes(expectedStr);
12718
+ if (typeof resolvedValue === 'string' && typeof expected === 'string') {
12719
+ return !resolvedValue.includes(expected);
12774
12720
  }
12775
12721
  return true;
12776
12722
  });
12777
- // this.log(`not_contains evaluation result: ${result}`);
12778
12723
  return result;
12779
12724
  }
12780
12725
  case FilterOperator.GREATER_THAN:
@@ -12803,6 +12748,21 @@ class NamiConditionEvaluator {
12803
12748
  return false;
12804
12749
  }
12805
12750
  }
12751
+ /** Type-strict equality: string↔string (optionally case-insensitive), boolean↔boolean, or number↔number. */
12752
+ strictEquals(resolved, expected, caseInsensitive) {
12753
+ if (typeof resolved === 'string' && typeof expected === 'string') {
12754
+ return caseInsensitive
12755
+ ? resolved.localeCompare(expected, undefined, { sensitivity: 'accent' }) === 0
12756
+ : resolved === expected;
12757
+ }
12758
+ if (typeof resolved === 'boolean' && typeof expected === 'boolean') {
12759
+ return resolved === expected;
12760
+ }
12761
+ if (typeof resolved === 'number' && typeof expected === 'number') {
12762
+ return resolved === expected;
12763
+ }
12764
+ return false;
12765
+ }
12806
12766
  resolve(identifier) {
12807
12767
  const exact = this.resolveRaw(identifier);
12808
12768
  if (exact !== undefined) {
@@ -12865,7 +12825,6 @@ class NamiConditionEvaluator {
12865
12825
  }
12866
12826
  break;
12867
12827
  default:
12868
- // this.log(`Unsupported property: .${property}`);
12869
12828
  return undefined;
12870
12829
  }
12871
12830
  this.log(`Could not extract .${property} from type ${typeof baseValue}`);
@@ -14172,6 +14131,17 @@ class NamiFlow extends BasicNamiFlow {
14172
14131
  this.forward(entry.id);
14173
14132
  }
14174
14133
  }
14134
+ applyLaunchContextAttributes(attrs) {
14135
+ if (!this.context) {
14136
+ this.context = { customAttributes: {} };
14137
+ new LaunchContextResolver(this.context);
14138
+ }
14139
+ // Guard against a runtime-supplied context that omits customAttributes
14140
+ // (the field is required by the type but may be absent in untyped JSON).
14141
+ this.context.customAttributes ??= {};
14142
+ // New values win: merge attrs over existing entries.
14143
+ Object.assign(this.context.customAttributes, attrs);
14144
+ }
14175
14145
  registerResolvers(context) {
14176
14146
  if (context) {
14177
14147
  new LaunchContextResolver(context);
@@ -14428,6 +14398,9 @@ class NamiFlow extends BasicNamiFlow {
14428
14398
  this.back();
14429
14399
  break;
14430
14400
  case exports.NamiFlowActionFunction.NEXT:
14401
+ if (action.parameters?.customAttributes) {
14402
+ this.applyLaunchContextAttributes(action.parameters.customAttributes);
14403
+ }
14431
14404
  if (action.parameters?.step) {
14432
14405
  this.forward(action.parameters.step);
14433
14406
  }
@@ -14436,6 +14409,9 @@ class NamiFlow extends BasicNamiFlow {
14436
14409
  }
14437
14410
  break;
14438
14411
  case exports.NamiFlowActionFunction.NAVIGATE:
14412
+ if (action.parameters?.customAttributes) {
14413
+ this.applyLaunchContextAttributes(action.parameters.customAttributes);
14414
+ }
14439
14415
  if (action.parameters?.step) {
14440
14416
  if (this.previousFlowStep?.id === action.parameters.step) {
14441
14417
  this.back();
@@ -14561,6 +14537,20 @@ class NamiFlow extends BasicNamiFlow {
14561
14537
  });
14562
14538
  }
14563
14539
  break;
14540
+ case exports.NamiFlowActionFunction.SET_LAUNCH_CONTEXT: {
14541
+ // Two supported shapes: { customAttributes: {...} } (nav-action wire shape)
14542
+ // and { key, value } (used by Apple/Android/Roku). We deliberately do NOT
14543
+ // treat arbitrary top-level parameters as attributes to avoid writing
14544
+ // reserved keys (step, delay, …) into the launch context.
14545
+ const params = action.parameters;
14546
+ if (params?.customAttributes) {
14547
+ this.applyLaunchContextAttributes(params.customAttributes);
14548
+ }
14549
+ else if (params?.key !== undefined && params?.value !== undefined) {
14550
+ this.applyLaunchContextAttributes({ [params.key]: params.value });
14551
+ }
14552
+ break;
14553
+ }
14564
14554
  default:
14565
14555
  logger.warn(`Missing action handler for ${action.function}`, action);
14566
14556
  break;
package/dist/index.d.ts CHANGED
@@ -102,7 +102,7 @@ type FilterOperator = (typeof FilterOperator)[keyof typeof FilterOperator];
102
102
  interface NamiConditionFilter {
103
103
  identifier: string;
104
104
  operator: FilterOperator;
105
- values: (string | number)[];
105
+ values: (string | boolean | number)[];
106
106
  }
107
107
  interface NamiConditions {
108
108
  filter?: NamiConditionFilter[];
@@ -134,7 +134,8 @@ declare enum NamiFlowActionFunction {
134
134
  FLOW_DISABLED = "flowInteractionDisabled",
135
135
  SET_TAGS = "setTags",
136
136
  PAUSE = "flowPause",
137
- RESUME = "flowResume"
137
+ RESUME = "flowResume",
138
+ SET_LAUNCH_CONTEXT = "setLaunchContext"
138
139
  }
139
140
  type NamiFlowHandoffStepHandler = (handoffTag: string, handoffData?: Record<string, any>) => void;
140
141
  type NamiFlowEventHandler = (eventHandler: Record<string, any>) => void;
@@ -1303,6 +1304,14 @@ type NamiPaywallEvent = {
1303
1304
  purchaseChannel?: string;
1304
1305
  };
1305
1306
  type NamiPaywallActionHandler = (event: NamiPaywallEvent) => void;
1307
+ /**
1308
+ * Permitted value types for entries in {@link NamiPaywallLaunchContext.customAttributes}.
1309
+ *
1310
+ * Values are matched strictly by type: the string "true" and the boolean true are
1311
+ * distinct values that never compare equal. A key present with any non-null value —
1312
+ * including false or "false" — is considered "set".
1313
+ */
1314
+ type NamiCustomAttributeValue = string | boolean | number;
1306
1315
  /**
1307
1316
  * @type NamiPaywallLaunchContext
1308
1317
  * Will be used to pass custom context while launching paywall
@@ -1310,7 +1319,7 @@ type NamiPaywallActionHandler = (event: NamiPaywallEvent) => void;
1310
1319
  type NamiPaywallLaunchContext = {
1311
1320
  productGroups?: string[];
1312
1321
  customAttributes: {
1313
- [key: string]: string;
1322
+ [key: string]: NamiCustomAttributeValue;
1314
1323
  };
1315
1324
  customObject?: {
1316
1325
  [key: string]: any;
@@ -1930,6 +1939,7 @@ declare class NamiFlow extends BasicNamiFlow {
1930
1939
  [timerId: string]: TimerState;
1931
1940
  };
1932
1941
  constructor(campaign: NamiFlowCampaign, paywall: PaywallHandle, manager: NamiFlowManager$2, context?: NamiPaywallLaunchContext);
1942
+ private applyLaunchContextAttributes;
1933
1943
  private registerResolvers;
1934
1944
  get currentFlowStep(): NamiFlowStep | undefined;
1935
1945
  get nextStepAvailable(): boolean;
@@ -3062,6 +3072,8 @@ declare class NamiConditionEvaluator {
3062
3072
  evaluate(conditions: NamiConditions): boolean;
3063
3073
  evaluateOrdered(conditions?: NamiConditions): boolean;
3064
3074
  private evaluateFilter;
3075
+ /** Type-strict equality: string↔string (optionally case-insensitive), boolean↔boolean, or number↔number. */
3076
+ private strictEquals;
3065
3077
  private resolve;
3066
3078
  private resolveRaw;
3067
3079
  private extractProperty;
@@ -3476,4 +3488,4 @@ declare namespace internal {
3476
3488
  }
3477
3489
 
3478
3490
  export { ALREADY_CONFIGURED, ANONYMOUS_MODE, ANONYMOUS_MODE_ALREADY_OFF, ANONYMOUS_MODE_ALREADY_ON, ANONYMOUS_MODE_LOGIN_NOT_ALLOWED, ANONYMOUS_UUID, APIError, API_ACTIVE_ENTITLEMENTS, API_CAMPAIGN_RULES, API_CAMPAIGN_SESSION_TIMESTAMP, API_CONFIG, API_MAX_CALLS_LIMIT, API_PAYWALLS, API_PRODUCTS, API_RETRY_DELAY_SEC, API_TIMEOUT_LIMIT, API_VERSION, AUTH_DEVICE, AVAILABLE_ACTIVE_ENTITLEMENTS_CHANGED, AVAILABLE_CAMPAIGNS_CHANGED, AccountStateAction, AnonymousCDPError, AnonymousLoginError, AnonymousModeAlreadyOffError, AnonymousModeAlreadyOnError, BASE_STAGING_URL, BASE_URL, BASE_URL_PATH, BadRequestError, BasicNamiFlow, BorderMap, BorderSideMap, CAMPAIGN_NOT_AVAILABLE, CUSTOMER_ATTRIBUTES_KEY_PREFIX, CUSTOMER_JOURNEY_STATE_CHANGED, CUSTOM_HOST_PREFIX, CampaignNotAvailableError, CampaignRuleConversionEventType, CampaignRuleRepository, Capabilities, ClientError, ConfigRepository, ConflictError, CustomerJourneyRepository, DEVELOPMENT, DEVICE_API_TIMEOUT_LIMIT, DEVICE_ID_NOT_SET, DEVICE_ID_REQUIRED, DISABLE_ASYNC_LOGIN_LOGOUT, DeviceIDRequiredError, DeviceRepository, EXTENDED_CLIENT_INFO_DELIMITER, EXTENDED_CLIENT_INFO_PREFIX, EXTENDED_PLATFORM, EXTENDED_PLATFORM_VERSION, EXTERNAL_ID_REQUIRED, EntitlementRepository, EntitlementUtils, ExternalIDRequiredError, FLOW_SCREENS_NOT_AVAILABLE, FlowScreensNotAvailableError, HTML_REGEX, INITIAL_APP_CONFIG, INITIAL_CAMPAIGN_RULES, INITIAL_PAYWALLS, INITIAL_PRODUCTS, INITIAL_SESSION_COUNTER_VALUE, INITIAL_SUCCESS, InternalServerError, KEY_SESSION_COUNTER, LIQUID_VARIABLE_REGEX, LOCAL_NAMI_ENTITLEMENTS, LOG_HTTP_REQUESTS, LOG_HTTP_TRAFFIC, LaunchCampaignError, LaunchContextResolver, LogLevel, NAMI_CONFIGURATION, NAMI_CUSTOMER_JOURNEY_STATE, NAMI_LANGUAGE_CODE, NAMI_LAST_IMPRESSION_ID, NAMI_LAUNCH_ID, NAMI_PROFILE, NAMI_PURCHASE_CHANNEL, NAMI_PURCHASE_IMPRESSION_ID, NAMI_SDK_PACKAGE_VERSION, NAMI_SDK_VERSION, NAMI_SESSION_ID, NAMI_STORAGE_KEYS, Nami, NamiAPI, NamiAnimationType, NamiCampaignManager$2 as NamiCampaignManager, NamiCampaignRuleType, NamiConditionEvaluator, NamiCustomerManager$2 as NamiCustomerManager, NamiEntitlementManager$2 as NamiEntitlementManager, NamiEventEmitter, NamiFlow, NamiFlowActionFunction, NamiFlowManager$1 as NamiFlowManager, NamiFlowStepType, NamiPaywallAction, NamiPaywallManager$2 as NamiPaywallManager, PaywallManagerEvents as NamiPaywallManagerEvents, NamiPurchaseManager$2 as NamiPurchaseManager, NamiRefs, NamiReservedActions, NotFoundError, PAYWALL_ACTION_EVENT, PLATFORM_ID_REQUIRED, PRODUCTION, PaywallManagerEvents, PaywallRepository, PaywallState, PlacementLabelResolver, PlatformIDRequiredError, ProductRepository, RECONFIG_SUCCESS, RetryLimitExceededError, SDKNotInitializedError, SDK_NOT_INITIALIZED, SERVER_NAMI_ENTITLEMENTS, SESSION_REQUIRED, SHOULD_SHOW_LOADING_INDICATOR, SKU_TEXT_REGEX, SMART_TEXT_PATTERN, STARTUP_TELEMETRY, STATUS_BAD_REQUEST, STATUS_CONFLICT, STATUS_INTERNAL_SERVER_ERROR, STATUS_NOT_FOUND, STATUS_SUCCESS, SessionService, SimpleEventTarget, StorageService, UNABLE_TO_UPDATE_CDP_ID, USE_STAGING_API, VALIDATE_PRODUCT_GROUPS, VAR_REGEX, NamiProfileManager$1 as _NamiProfileManager, internal as _internal, activateEntitlementByPurchase, activeEntitlements, aggregateScreenreaderText, allCampaigns, allPaywalls, applyEntitlementActivation, audienceSplitPosition, bestUrlCampaignMatch, bigintToUuid, checkAnySkuHasPromoOffer, checkAnySkuHasTrialOffer, convertISO8601PeriodToText, convertLocale, convertOfferToPricingPhase, createNamiEntitlements, currentSku, empty, extractStandardPricingPhases, formatDate, formattedPrice, generateUUID, getApiCampaigns, getApiPaywalls, getBaseUrl, getBillingPeriodNumber, getCurrencyFormat, getDeviceData, getDeviceFormFactor, getDeviceScaleFactor, getEffectiveWebStyle, getEntitlementRefIdsForSku, getExtendedClientInfo, getFreeTrialPeriod, getInitialCampaigns, getInitialPaywalls, getPaywall, getPaywallDataFromLabel, getPercentagePriceDifference, getPeriodNumberInDays, getPeriodNumberInWeeks, getPlatformAdapters, getPriceDifference, getPricePerMonth, getProductDetail, getPurchaseAdapter, getReferenceSku, getSkuProductDetailKeys, getSkuSmartTextValue, getSlideSmartTextValue, getStandardBillingPeriod, getTranslate, getUrlParams, handleErrors, hasAllPaywalls, hasCapability, hasPurchaseManagement, initialState, invokeHandler, isAnonymousMode, isInitialConfigCompressed, isNamiFlowCampaign, isSubscription, isValidISODate, isValidUrl, logger, mapAnonymousCampaigns, namiBuySKU, normalizeLaunchContext, parseToSemver, postConversion, productDetail, registerPlatformAdapters, registerPurchaseAdapter, selectSegment, setActiveNamiEntitlements, shouldValidateProductGroups, skuItems, skuMapFromEntitlements, storageService, toDouble, toNamiEntitlements, toNamiSKU, tryParseB64Gzip, tryParseJson, updateRelatedSKUsForNamiEntitlement, uuidFromSplitPosition, validateMinSDKVersion };
3479
- export type { AccountStateHandler$1 as AccountStateHandler, AlignmentType, AmazonProduct, ApiResponse, AppleProduct, AvailableCampaignsResponseHandler, BorderLocationType, BorderSideType, Callback$1 as Callback, CloseHandler, CustomerJourneyState, DeepLinkUrlHandler, Device, DevicePayload, DeviceProfile, DirectionType, ExtendedPlatformInfo, FlexDirectionObject, FlowNavigationOptions, FontCollection, FontDetails, FormFactor, GoogleProduct, IConfig, IDeviceAdapter, IEntitlements$1 as IEntitlements, IPaywall, IPlatformAdapters, IProductsWithComponents, IPurchaseAdapter, ISkuMenu, IStorageAdapter, IUIAdapter, Impression, InitialConfig, InitialConfigCompressed, InitiateStateGroup, LoginResponse, NamiAnimation, NamiAnimationObjectSpec, NamiAnimationSpec, NamiAnonymousCampaign, NamiAppSuppliedVideoDetails, NamiCampaign, NamiCampaignManagerStatic, NamiCampaignSegment, NamiConfiguration, NamiConfigurationState, NamiCustomerManagerStatic, NamiEntitlement$1 as NamiEntitlement, NamiEntitlementManagerStatic, NamiFlowAction, NamiFlowAnimation, NamiFlowCampaign, NamiFlowDTO, NamiFlowEventHandler, NamiFlowHandoffStepHandler, NamiFlowManagerStatic, NamiFlowObjectDTO, NamiFlowOn, NamiFlowStep, NamiFlowTransition, NamiFlowTransitionDirection, NamiFlowWithObject, NamiInitialConfig, NamiLanguageCodes, NamiLogLevel, NamiPaywallActionHandler, NamiPaywallComponentChange, NamiPaywallEvent, NamiPaywallEventVideoMetadata, NamiPaywallLaunchContext, NamiPaywallManagerStatic, NamiPresentationStyle, NamiProductDetails, NamiProductOffer, NamiProfile, NamiPurchase, NamiPurchaseCompleteResult, NamiPurchaseDetails, NamiPurchaseManagerStatic, NamiPurchasesState, NamiSKU, NamiSKUType, NamiSubscriptionInterval, NamiSubscriptionPeriod, None, NoneSpec, PaywallActionEvent, PaywallHandle, PaywallResultHandler, PaywallSKU, PricingPhase, ProductGroup, Pulse, PulseSpec, PurchaseContext, PurchaseResult, PurchaseValidationRequest, SKU, SKUActionHandler, ScreenInfo, Session, TBaseComponent, TButtonContainer, TCarouselContainer, TCarouselSlide, TCarouselSlidesState, TCollapseContainer, TComponent, TConditionalAttributes, TConditionalComponent, TContainer, TContainerPosition, TCountdownTimerTextComponent, TDevice, TDisabledButton, TField, TFieldSettings, TFlexProductContainer, THeaderFooter, TImageComponent, TInitialState, TMediaTypes, TOffer, TPages, TPaywallContext, TPaywallLaunchContext, TPaywallMedia, TPaywallTemplate, TPlayPauseButton, TProductContainer, TProductGroup, TProgressBarComponent, TProgressIndicatorComponent, TQRCodeComponent, TRadioButton, TRepeatingGrid, TResponsiveGrid, TSegmentPicker, TSegmentPickerItem, TSemverObj, TSpacerComponent, TStack, TSvgImageComponent, TSymbolComponent, TTestObject, TTextComponent, TTextLikeComponent, TTextListComponent, TTimelineRail, TToggleButtonComponent, TToggleSwitch, TVariablePattern, TVideoComponent, TVolumeButton, TimerState, TransactionRequest, UserAction, UserActionParameters, Wave, WaveSpec };
3491
+ export type { AccountStateHandler$1 as AccountStateHandler, AlignmentType, AmazonProduct, ApiResponse, AppleProduct, AvailableCampaignsResponseHandler, BorderLocationType, BorderSideType, Callback$1 as Callback, CloseHandler, CustomerJourneyState, DeepLinkUrlHandler, Device, DevicePayload, DeviceProfile, DirectionType, ExtendedPlatformInfo, FlexDirectionObject, FlowNavigationOptions, FontCollection, FontDetails, FormFactor, GoogleProduct, IConfig, IDeviceAdapter, IEntitlements$1 as IEntitlements, IPaywall, IPlatformAdapters, IProductsWithComponents, IPurchaseAdapter, ISkuMenu, IStorageAdapter, IUIAdapter, Impression, InitialConfig, InitialConfigCompressed, InitiateStateGroup, LoginResponse, NamiAnimation, NamiAnimationObjectSpec, NamiAnimationSpec, NamiAnonymousCampaign, NamiAppSuppliedVideoDetails, NamiCampaign, NamiCampaignManagerStatic, NamiCampaignSegment, NamiConfiguration, NamiConfigurationState, NamiCustomAttributeValue, NamiCustomerManagerStatic, NamiEntitlement$1 as NamiEntitlement, NamiEntitlementManagerStatic, NamiFlowAction, NamiFlowAnimation, NamiFlowCampaign, NamiFlowDTO, NamiFlowEventHandler, NamiFlowHandoffStepHandler, NamiFlowManagerStatic, NamiFlowObjectDTO, NamiFlowOn, NamiFlowStep, NamiFlowTransition, NamiFlowTransitionDirection, NamiFlowWithObject, NamiInitialConfig, NamiLanguageCodes, NamiLogLevel, NamiPaywallActionHandler, NamiPaywallComponentChange, NamiPaywallEvent, NamiPaywallEventVideoMetadata, NamiPaywallLaunchContext, NamiPaywallManagerStatic, NamiPresentationStyle, NamiProductDetails, NamiProductOffer, NamiProfile, NamiPurchase, NamiPurchaseCompleteResult, NamiPurchaseDetails, NamiPurchaseManagerStatic, NamiPurchasesState, NamiSKU, NamiSKUType, NamiSubscriptionInterval, NamiSubscriptionPeriod, None, NoneSpec, PaywallActionEvent, PaywallHandle, PaywallResultHandler, PaywallSKU, PricingPhase, ProductGroup, Pulse, PulseSpec, PurchaseContext, PurchaseResult, PurchaseValidationRequest, SKU, SKUActionHandler, ScreenInfo, Session, TBaseComponent, TButtonContainer, TCarouselContainer, TCarouselSlide, TCarouselSlidesState, TCollapseContainer, TComponent, TConditionalAttributes, TConditionalComponent, TContainer, TContainerPosition, TCountdownTimerTextComponent, TDevice, TDisabledButton, TField, TFieldSettings, TFlexProductContainer, THeaderFooter, TImageComponent, TInitialState, TMediaTypes, TOffer, TPages, TPaywallContext, TPaywallLaunchContext, TPaywallMedia, TPaywallTemplate, TPlayPauseButton, TProductContainer, TProductGroup, TProgressBarComponent, TProgressIndicatorComponent, TQRCodeComponent, TRadioButton, TRepeatingGrid, TResponsiveGrid, TSegmentPicker, TSegmentPickerItem, TSemverObj, TSpacerComponent, TStack, TSvgImageComponent, TSymbolComponent, TTestObject, TTextComponent, TTextLikeComponent, TTextListComponent, TTimelineRail, TToggleButtonComponent, TToggleSwitch, TVariablePattern, TVideoComponent, TVolumeButton, TimerState, TransactionRequest, UserAction, UserActionParameters, Wave, WaveSpec };
package/dist/index.mjs CHANGED
@@ -96,7 +96,7 @@ const {
96
96
  // version — stamped by scripts/version.sh
97
97
  NAMI_SDK_VERSION = "3.4.3",
98
98
  // full package version including dev suffix — stamped by scripts/version.sh
99
- NAMI_SDK_PACKAGE_VERSION = "3.4.3-dev.202606120301",
99
+ NAMI_SDK_PACKAGE_VERSION = "3.4.3-dev.202606121440",
100
100
  // environments
101
101
  PRODUCTION = "production", DEVELOPMENT = "development",
102
102
  // error messages
@@ -12546,6 +12546,7 @@ var NamiFlowActionFunction;
12546
12546
  NamiFlowActionFunction["SET_TAGS"] = "setTags";
12547
12547
  NamiFlowActionFunction["PAUSE"] = "flowPause";
12548
12548
  NamiFlowActionFunction["RESUME"] = "flowResume";
12549
+ NamiFlowActionFunction["SET_LAUNCH_CONTEXT"] = "setLaunchContext";
12549
12550
  })(NamiFlowActionFunction || (NamiFlowActionFunction = {}));
12550
12551
  const HandoffTag = {
12551
12552
  SEQUENCE: '__handoff_sequence__',
@@ -12690,89 +12691,33 @@ class NamiConditionEvaluator {
12690
12691
  return true;
12691
12692
  return false;
12692
12693
  }
12693
- // this.log(
12694
- // `Evaluating filter: ${filter.operator} with values: ${filter.values} against resolved value: ${JSON.stringify(resolvedValue)}`
12695
- // );
12696
12694
  switch (filter.operator) {
12697
12695
  case FilterOperator.I_CONTAINS:
12698
12696
  if (Array.isArray(resolvedValue)) {
12699
- const result = filter.values.some(expected => {
12700
- const expectedStr = String(expected);
12701
- return resolvedValue.some(item => item.localeCompare(expectedStr, undefined, { sensitivity: 'accent' }) === 0);
12702
- });
12703
- // this.log(`i_contains evaluation result: ${result}`);
12697
+ const result = filter.values.some(expected => typeof expected === 'string' && resolvedValue.some(item => item.localeCompare(expected, undefined, { sensitivity: 'accent' }) === 0));
12704
12698
  return result;
12705
12699
  }
12706
12700
  this.log('Resolved value is not an array of strings for i_contains.');
12707
12701
  return false;
12708
12702
  case FilterOperator.EQUALS: {
12709
- const result = filter.values.some(expected => {
12710
- const expectedStr = String(expected);
12711
- if (typeof resolvedValue === 'string') {
12712
- // this.log(`Comparing string ${resolvedValue} == ${expected}`);
12713
- return resolvedValue === expectedStr;
12714
- }
12715
- if (typeof resolvedValue === 'boolean') {
12716
- const expectedBool = expectedStr.toLowerCase() === 'true';
12717
- // this.log(`Comparing boolean ${resolvedValue} == ${expectedBool}`);
12718
- return resolvedValue === expectedBool;
12719
- }
12720
- this.log(`Unsupported type for equals comparison: ${typeof resolvedValue}`);
12721
- return false;
12722
- });
12723
- // this.log(`equals evaluation result: ${result}`);
12724
- return result;
12703
+ return filter.values.some(expected => this.strictEquals(resolvedValue, expected, false));
12725
12704
  }
12726
12705
  case FilterOperator.I_EQUALS: {
12727
- const result = filter.values.some(expected => {
12728
- const expectedStr = String(expected);
12729
- if (typeof resolvedValue === 'string') {
12730
- const match = resolvedValue.localeCompare(expectedStr, undefined, { sensitivity: 'accent' }) === 0;
12731
- // this.log(`Comparing string ${resolvedValue} ~= ${expected}: ${match}`);
12732
- return match;
12733
- }
12734
- if (typeof resolvedValue === 'boolean') {
12735
- const expectedBool = expectedStr.toLowerCase() === 'true';
12736
- // this.log(`Comparing boolean ${resolvedValue} ~= ${expectedBool}`);
12737
- return resolvedValue === expectedBool;
12738
- }
12739
- this.log(`Unsupported type for i_equals comparison: ${typeof resolvedValue}`);
12740
- return false;
12741
- });
12742
- // this.log(`i_equals evaluation result: ${result}`);
12743
- return result;
12706
+ return filter.values.some(expected => this.strictEquals(resolvedValue, expected, true));
12744
12707
  }
12745
12708
  case FilterOperator.NOT_EQUALS: {
12746
- const result = filter.values.every(expected => {
12747
- const expectedStr = String(expected);
12748
- if (typeof resolvedValue === 'string') {
12749
- return resolvedValue !== expectedStr;
12750
- }
12751
- return true;
12752
- });
12753
- // this.log(`not_equals evaluation result: ${result}`);
12754
- return result;
12709
+ return filter.values.every(expected => !this.strictEquals(resolvedValue, expected, false));
12755
12710
  }
12756
12711
  case FilterOperator.NOT_I_EQUALS: {
12757
- const result = filter.values.every(expected => {
12758
- const expectedStr = String(expected);
12759
- if (typeof resolvedValue === 'string') {
12760
- return (resolvedValue.localeCompare(expectedStr, undefined, { sensitivity: 'accent' }) !== 0);
12761
- }
12762
- return true;
12763
- });
12764
- // this.log(`not_i_equals evaluation result: ${result}`);
12765
- return result;
12712
+ return filter.values.every(expected => !this.strictEquals(resolvedValue, expected, true));
12766
12713
  }
12767
12714
  case FilterOperator.NOT_CONTAINS: {
12768
12715
  const result = filter.values.every(expected => {
12769
- const expectedStr = String(expected);
12770
- if (typeof resolvedValue === 'string') {
12771
- return !resolvedValue.includes(expectedStr);
12716
+ if (typeof resolvedValue === 'string' && typeof expected === 'string') {
12717
+ return !resolvedValue.includes(expected);
12772
12718
  }
12773
12719
  return true;
12774
12720
  });
12775
- // this.log(`not_contains evaluation result: ${result}`);
12776
12721
  return result;
12777
12722
  }
12778
12723
  case FilterOperator.GREATER_THAN:
@@ -12801,6 +12746,21 @@ class NamiConditionEvaluator {
12801
12746
  return false;
12802
12747
  }
12803
12748
  }
12749
+ /** Type-strict equality: string↔string (optionally case-insensitive), boolean↔boolean, or number↔number. */
12750
+ strictEquals(resolved, expected, caseInsensitive) {
12751
+ if (typeof resolved === 'string' && typeof expected === 'string') {
12752
+ return caseInsensitive
12753
+ ? resolved.localeCompare(expected, undefined, { sensitivity: 'accent' }) === 0
12754
+ : resolved === expected;
12755
+ }
12756
+ if (typeof resolved === 'boolean' && typeof expected === 'boolean') {
12757
+ return resolved === expected;
12758
+ }
12759
+ if (typeof resolved === 'number' && typeof expected === 'number') {
12760
+ return resolved === expected;
12761
+ }
12762
+ return false;
12763
+ }
12804
12764
  resolve(identifier) {
12805
12765
  const exact = this.resolveRaw(identifier);
12806
12766
  if (exact !== undefined) {
@@ -12863,7 +12823,6 @@ class NamiConditionEvaluator {
12863
12823
  }
12864
12824
  break;
12865
12825
  default:
12866
- // this.log(`Unsupported property: .${property}`);
12867
12826
  return undefined;
12868
12827
  }
12869
12828
  this.log(`Could not extract .${property} from type ${typeof baseValue}`);
@@ -14170,6 +14129,17 @@ class NamiFlow extends BasicNamiFlow {
14170
14129
  this.forward(entry.id);
14171
14130
  }
14172
14131
  }
14132
+ applyLaunchContextAttributes(attrs) {
14133
+ if (!this.context) {
14134
+ this.context = { customAttributes: {} };
14135
+ new LaunchContextResolver(this.context);
14136
+ }
14137
+ // Guard against a runtime-supplied context that omits customAttributes
14138
+ // (the field is required by the type but may be absent in untyped JSON).
14139
+ this.context.customAttributes ??= {};
14140
+ // New values win: merge attrs over existing entries.
14141
+ Object.assign(this.context.customAttributes, attrs);
14142
+ }
14173
14143
  registerResolvers(context) {
14174
14144
  if (context) {
14175
14145
  new LaunchContextResolver(context);
@@ -14426,6 +14396,9 @@ class NamiFlow extends BasicNamiFlow {
14426
14396
  this.back();
14427
14397
  break;
14428
14398
  case NamiFlowActionFunction.NEXT:
14399
+ if (action.parameters?.customAttributes) {
14400
+ this.applyLaunchContextAttributes(action.parameters.customAttributes);
14401
+ }
14429
14402
  if (action.parameters?.step) {
14430
14403
  this.forward(action.parameters.step);
14431
14404
  }
@@ -14434,6 +14407,9 @@ class NamiFlow extends BasicNamiFlow {
14434
14407
  }
14435
14408
  break;
14436
14409
  case NamiFlowActionFunction.NAVIGATE:
14410
+ if (action.parameters?.customAttributes) {
14411
+ this.applyLaunchContextAttributes(action.parameters.customAttributes);
14412
+ }
14437
14413
  if (action.parameters?.step) {
14438
14414
  if (this.previousFlowStep?.id === action.parameters.step) {
14439
14415
  this.back();
@@ -14559,6 +14535,20 @@ class NamiFlow extends BasicNamiFlow {
14559
14535
  });
14560
14536
  }
14561
14537
  break;
14538
+ case NamiFlowActionFunction.SET_LAUNCH_CONTEXT: {
14539
+ // Two supported shapes: { customAttributes: {...} } (nav-action wire shape)
14540
+ // and { key, value } (used by Apple/Android/Roku). We deliberately do NOT
14541
+ // treat arbitrary top-level parameters as attributes to avoid writing
14542
+ // reserved keys (step, delay, …) into the launch context.
14543
+ const params = action.parameters;
14544
+ if (params?.customAttributes) {
14545
+ this.applyLaunchContextAttributes(params.customAttributes);
14546
+ }
14547
+ else if (params?.key !== undefined && params?.value !== undefined) {
14548
+ this.applyLaunchContextAttributes({ [params.key]: params.value });
14549
+ }
14550
+ break;
14551
+ }
14562
14552
  default:
14563
14553
  logger.warn(`Missing action handler for ${action.function}`, action);
14564
14554
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@namiml/sdk-core",
3
- "version": "3.4.3-dev.202606120301",
3
+ "version": "3.4.3-dev.202606121440",
4
4
  "description": "Platform-agnostic core for the Nami SDK — business logic, API, types, and state management",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",