@namiml/sdk-core 3.4.0-dev.202604011456 → 3.4.0-dev.202604031805

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
@@ -123,7 +123,7 @@ const {
123
123
  // version — stamped by scripts/version.sh
124
124
  NAMI_SDK_VERSION: exports.NAMI_SDK_VERSION = "3.4.0",
125
125
  // full package version including dev suffix — stamped by scripts/version.sh
126
- NAMI_SDK_PACKAGE_VERSION: exports.NAMI_SDK_PACKAGE_VERSION = "3.4.0-dev.202604011456",
126
+ NAMI_SDK_PACKAGE_VERSION: exports.NAMI_SDK_PACKAGE_VERSION = "3.4.0-dev.202604031805",
127
127
  // environments
128
128
  PRODUCTION: exports.PRODUCTION = "production", DEVELOPMENT: exports.DEVELOPMENT = "development",
129
129
  // error messages
@@ -200,7 +200,7 @@ const logger = new Logger();
200
200
 
201
201
  /**
202
202
  * Creates an array with all falsey values removed. The values `false`, `null`,
203
- * `0`, `""`, `undefined`, and `NaN` are falsey.
203
+ * `0`, `-0`, `0n`, `""`, `undefined`, and `NaN` are falsy.
204
204
  *
205
205
  * @static
206
206
  * @memberOf _
@@ -1060,7 +1060,7 @@ function setCacheAdd(value) {
1060
1060
  * @name has
1061
1061
  * @memberOf SetCache
1062
1062
  * @param {*} value The value to search for.
1063
- * @returns {number} Returns `true` if `value` is found, else `false`.
1063
+ * @returns {boolean} Returns `true` if `value` is found, else `false`.
1064
1064
  */
1065
1065
  function setCacheHas(value) {
1066
1066
  return this.__data__.has(value);
@@ -7266,6 +7266,77 @@ const isValidUrl = (label) => {
7266
7266
  return false;
7267
7267
  }
7268
7268
  };
7269
+ /**
7270
+ * Parse a URL into its base path (origin + pathname) and query parameter set.
7271
+ * Query params are stored as "key=value" strings for order-independent comparison.
7272
+ * Returns undefined if the URL cannot be parsed.
7273
+ */
7274
+ const parseUrlComponents = (url) => {
7275
+ try {
7276
+ const parsed = new URL(url);
7277
+ const basePath = parsed.origin + parsed.pathname;
7278
+ const params = new Set();
7279
+ parsed.searchParams.forEach((value, key) => {
7280
+ params.add(`${key}=${value}`);
7281
+ });
7282
+ return { basePath, params };
7283
+ }
7284
+ catch {
7285
+ return undefined;
7286
+ }
7287
+ };
7288
+ /**
7289
+ * Find the best-matching URL campaign for an incoming URL using scored matching.
7290
+ * Compares base paths (origin + pathname), then scores by query param key=value overlap.
7291
+ * Priority: exact match (all campaign params present) > partial match > base-path-only fallback.
7292
+ * Among ties, the campaign with more total params (more specific) wins.
7293
+ */
7294
+ const bestUrlCampaignMatch = (incomingUrl, campaigns) => {
7295
+ const incoming = parseUrlComponents(incomingUrl);
7296
+ if (!incoming)
7297
+ return undefined;
7298
+ let bestExact;
7299
+ let bestPartial;
7300
+ for (const campaign of campaigns) {
7301
+ const campaignValue = campaign.value;
7302
+ if (!campaignValue)
7303
+ continue;
7304
+ const parsed = parseUrlComponents(campaignValue);
7305
+ if (!parsed)
7306
+ continue;
7307
+ if (parsed.basePath !== incoming.basePath)
7308
+ continue;
7309
+ const totalParams = parsed.params.size;
7310
+ // Base-path-only campaign (no query params): lowest-priority fallback
7311
+ if (totalParams === 0) {
7312
+ if (!bestExact && !bestPartial) {
7313
+ bestPartial = { campaign, score: 0, totalParams: 0 };
7314
+ }
7315
+ continue;
7316
+ }
7317
+ let score = 0;
7318
+ for (const param of parsed.params) {
7319
+ if (incoming.params.has(param)) {
7320
+ score++;
7321
+ }
7322
+ }
7323
+ if (score === totalParams) {
7324
+ // Exact match: all campaign params present in incoming URL
7325
+ if (!bestExact || totalParams > bestExact.totalParams) {
7326
+ bestExact = { campaign, totalParams };
7327
+ }
7328
+ }
7329
+ else if (!bestExact) {
7330
+ // Partial match: only consider if no exact match exists yet
7331
+ if (!bestPartial ||
7332
+ score > bestPartial.score ||
7333
+ (score === bestPartial.score && totalParams > bestPartial.totalParams)) {
7334
+ bestPartial = { campaign, score, totalParams };
7335
+ }
7336
+ }
7337
+ }
7338
+ return bestExact?.campaign ?? bestPartial?.campaign;
7339
+ };
7269
7340
  const selectSegment = (segments, splitPosition) => {
7270
7341
  const sorted = [...segments].sort((a, b) => a.split - b.split);
7271
7342
  for (const seg of sorted) {
@@ -7344,11 +7415,16 @@ const getApiCampaigns = () => getCampaignsByRule(exports.API_CAMPAIGN_RULES);
7344
7415
  * @returns An object containing the campaign and paywall data, or an empty object if not found
7345
7416
  */
7346
7417
  const getPaywallDataFromSources = (campaignsSource, paywallsSource, value, type) => {
7347
- const campaign = campaignsSource().find((campaign) => {
7348
- if (!type)
7349
- return campaign.type == exports.NamiCampaignRuleType.DEFAULT;
7350
- return campaign.type == type && campaign.value == value;
7351
- });
7418
+ const campaign = (() => {
7419
+ if (!type) {
7420
+ return campaignsSource().find(c => c.type == exports.NamiCampaignRuleType.DEFAULT);
7421
+ }
7422
+ if (type === exports.NamiCampaignRuleType.URL) {
7423
+ const urlCampaigns = campaignsSource().filter(c => c.type == exports.NamiCampaignRuleType.URL);
7424
+ return bestUrlCampaignMatch(value, urlCampaigns);
7425
+ }
7426
+ return campaignsSource().find(c => c.type == type && c.value == value);
7427
+ })();
7352
7428
  if (!campaign)
7353
7429
  return {};
7354
7430
  const paywall = paywallsSource().find((paywall) => {
@@ -63753,6 +63829,7 @@ exports.allCampaigns = allCampaigns;
63753
63829
  exports.allPaywalls = allPaywalls;
63754
63830
  exports.applyEntitlementActivation = applyEntitlementActivation;
63755
63831
  exports.audienceSplitPosition = audienceSplitPosition;
63832
+ exports.bestUrlCampaignMatch = bestUrlCampaignMatch;
63756
63833
  exports.bigintToUuid = bigintToUuid;
63757
63834
  exports.checkAnySkuHasPromoOffer = checkAnySkuHasPromoOffer;
63758
63835
  exports.checkAnySkuHasTrialOffer = checkAnySkuHasTrialOffer;
package/dist/index.d.ts CHANGED
@@ -2617,6 +2617,13 @@ declare class NamiRefs {
2617
2617
  }
2618
2618
 
2619
2619
  declare const isValidUrl: (label: string) => boolean;
2620
+ /**
2621
+ * Find the best-matching URL campaign for an incoming URL using scored matching.
2622
+ * Compares base paths (origin + pathname), then scores by query param key=value overlap.
2623
+ * Priority: exact match (all campaign params present) > partial match > base-path-only fallback.
2624
+ * Among ties, the campaign with more total params (more specific) wins.
2625
+ */
2626
+ declare const bestUrlCampaignMatch: (incomingUrl: string, campaigns: NamiCampaign[]) => NamiCampaign | undefined;
2620
2627
  declare const selectSegment: (segments: NamiCampaignSegment[], splitPosition: number) => NamiCampaignSegment;
2621
2628
  declare const mapAnonymousCampaigns: (campaigns: NamiAnonymousCampaign[], splitPosition: number, formFactor?: TDevice) => NamiCampaign[];
2622
2629
  /**
@@ -2929,5 +2936,5 @@ declare const getBillingPeriodNumber: (billingPeriod: string) => number;
2929
2936
  declare const formattedPrice: (price: number) => number;
2930
2937
  declare function toDouble(num: number): number;
2931
2938
 
2932
- 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, 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, 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, NamiAPI, NamiAnimationType, NamiCampaignManager, NamiCampaignRuleType, NamiConditionEvaluator, NamiCustomerManager, NamiEntitlementManager, NamiEventEmitter, NamiFlow, NamiFlowActionFunction, NamiFlowManager, NamiFlowStepType, NamiPaywallAction, NamiPaywallManager, PaywallManagerEvents as NamiPaywallManagerEvents, NamiProfileManager, 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, 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, activateEntitlementByPurchase, activeEntitlements, allCampaigns, allPaywalls, applyEntitlementActivation, audienceSplitPosition, 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, 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, selectSegment, setActiveNamiEntitlements, shouldValidateProductGroups, skuItems, skuMapFromEntitlements, storageService, toDouble, toNamiEntitlements, toNamiSKU, tryParseB64Gzip, tryParseJson, updateRelatedSKUsForNamiEntitlement, uuidFromSplitPosition, validateMinSDKVersion };
2939
+ 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, 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, 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, NamiAPI, NamiAnimationType, NamiCampaignManager, NamiCampaignRuleType, NamiConditionEvaluator, NamiCustomerManager, NamiEntitlementManager, NamiEventEmitter, NamiFlow, NamiFlowActionFunction, NamiFlowManager, NamiFlowStepType, NamiPaywallAction, NamiPaywallManager, PaywallManagerEvents as NamiPaywallManagerEvents, NamiProfileManager, 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, 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, activateEntitlementByPurchase, activeEntitlements, 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, 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, selectSegment, setActiveNamiEntitlements, shouldValidateProductGroups, skuItems, skuMapFromEntitlements, storageService, toDouble, toNamiEntitlements, toNamiSKU, tryParseB64Gzip, tryParseJson, updateRelatedSKUsForNamiEntitlement, uuidFromSplitPosition, validateMinSDKVersion };
2933
2940
  export type { 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, ISkuMenu, IStorageAdapter, IUIAdapter, Impression, InitialConfig, InitialConfigCompressed, InitiateStateGroup, LoginResponse, NamiAnimation, NamiAnimationObjectSpec, NamiAnimationSpec, NamiAnonymousCampaign, NamiAppSuppliedVideoDetails, NamiCampaign, NamiCampaignSegment, NamiConfiguration, NamiConfigurationState, NamiEntitlement$1 as NamiEntitlement, NamiFlowAction, NamiFlowAnimation, NamiFlowCampaign, NamiFlowDTO, NamiFlowEventHandler, NamiFlowHandoffStepHandler, NamiFlowObjectDTO, NamiFlowOn, NamiFlowStep, NamiFlowTransition, NamiFlowTransitionDirection, NamiFlowWithObject, NamiInitialConfig, NamiLanguageCodes, NamiLogLevel, NamiPaywallActionHandler, NamiPaywallComponentChange, NamiPaywallEvent, NamiPaywallEventVideoMetadata, NamiPaywallLaunchContext, NamiPresentationStyle, NamiProductDetails, NamiProductOffer, NamiProfile, NamiPurchase, NamiPurchaseCompleteResult, NamiPurchaseDetails, NamiPurchasesState, NamiSKU, NamiSKUType, NamiSubscriptionInterval, NamiSubscriptionPeriod, None, NoneSpec, PaywallActionEvent, PaywallHandle, PaywallResultHandler, PaywallSKU, PricingPhase, ProductGroup, Pulse, PulseSpec, 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, TToggleButtonComponent, TToggleSwitch, TVariablePattern, TVideoComponent, TVolumeButton, TimerState, TransactionRequest, UserAction, UserActionParameters, Wave, WaveSpec };
package/dist/index.mjs CHANGED
@@ -121,7 +121,7 @@ const {
121
121
  // version — stamped by scripts/version.sh
122
122
  NAMI_SDK_VERSION = "3.4.0",
123
123
  // full package version including dev suffix — stamped by scripts/version.sh
124
- NAMI_SDK_PACKAGE_VERSION = "3.4.0-dev.202604011456",
124
+ NAMI_SDK_PACKAGE_VERSION = "3.4.0-dev.202604031805",
125
125
  // environments
126
126
  PRODUCTION = "production", DEVELOPMENT = "development",
127
127
  // error messages
@@ -198,7 +198,7 @@ const logger = new Logger();
198
198
 
199
199
  /**
200
200
  * Creates an array with all falsey values removed. The values `false`, `null`,
201
- * `0`, `""`, `undefined`, and `NaN` are falsey.
201
+ * `0`, `-0`, `0n`, `""`, `undefined`, and `NaN` are falsy.
202
202
  *
203
203
  * @static
204
204
  * @memberOf _
@@ -1058,7 +1058,7 @@ function setCacheAdd(value) {
1058
1058
  * @name has
1059
1059
  * @memberOf SetCache
1060
1060
  * @param {*} value The value to search for.
1061
- * @returns {number} Returns `true` if `value` is found, else `false`.
1061
+ * @returns {boolean} Returns `true` if `value` is found, else `false`.
1062
1062
  */
1063
1063
  function setCacheHas(value) {
1064
1064
  return this.__data__.has(value);
@@ -7264,6 +7264,77 @@ const isValidUrl = (label) => {
7264
7264
  return false;
7265
7265
  }
7266
7266
  };
7267
+ /**
7268
+ * Parse a URL into its base path (origin + pathname) and query parameter set.
7269
+ * Query params are stored as "key=value" strings for order-independent comparison.
7270
+ * Returns undefined if the URL cannot be parsed.
7271
+ */
7272
+ const parseUrlComponents = (url) => {
7273
+ try {
7274
+ const parsed = new URL(url);
7275
+ const basePath = parsed.origin + parsed.pathname;
7276
+ const params = new Set();
7277
+ parsed.searchParams.forEach((value, key) => {
7278
+ params.add(`${key}=${value}`);
7279
+ });
7280
+ return { basePath, params };
7281
+ }
7282
+ catch {
7283
+ return undefined;
7284
+ }
7285
+ };
7286
+ /**
7287
+ * Find the best-matching URL campaign for an incoming URL using scored matching.
7288
+ * Compares base paths (origin + pathname), then scores by query param key=value overlap.
7289
+ * Priority: exact match (all campaign params present) > partial match > base-path-only fallback.
7290
+ * Among ties, the campaign with more total params (more specific) wins.
7291
+ */
7292
+ const bestUrlCampaignMatch = (incomingUrl, campaigns) => {
7293
+ const incoming = parseUrlComponents(incomingUrl);
7294
+ if (!incoming)
7295
+ return undefined;
7296
+ let bestExact;
7297
+ let bestPartial;
7298
+ for (const campaign of campaigns) {
7299
+ const campaignValue = campaign.value;
7300
+ if (!campaignValue)
7301
+ continue;
7302
+ const parsed = parseUrlComponents(campaignValue);
7303
+ if (!parsed)
7304
+ continue;
7305
+ if (parsed.basePath !== incoming.basePath)
7306
+ continue;
7307
+ const totalParams = parsed.params.size;
7308
+ // Base-path-only campaign (no query params): lowest-priority fallback
7309
+ if (totalParams === 0) {
7310
+ if (!bestExact && !bestPartial) {
7311
+ bestPartial = { campaign, score: 0, totalParams: 0 };
7312
+ }
7313
+ continue;
7314
+ }
7315
+ let score = 0;
7316
+ for (const param of parsed.params) {
7317
+ if (incoming.params.has(param)) {
7318
+ score++;
7319
+ }
7320
+ }
7321
+ if (score === totalParams) {
7322
+ // Exact match: all campaign params present in incoming URL
7323
+ if (!bestExact || totalParams > bestExact.totalParams) {
7324
+ bestExact = { campaign, totalParams };
7325
+ }
7326
+ }
7327
+ else if (!bestExact) {
7328
+ // Partial match: only consider if no exact match exists yet
7329
+ if (!bestPartial ||
7330
+ score > bestPartial.score ||
7331
+ (score === bestPartial.score && totalParams > bestPartial.totalParams)) {
7332
+ bestPartial = { campaign, score, totalParams };
7333
+ }
7334
+ }
7335
+ }
7336
+ return bestExact?.campaign ?? bestPartial?.campaign;
7337
+ };
7267
7338
  const selectSegment = (segments, splitPosition) => {
7268
7339
  const sorted = [...segments].sort((a, b) => a.split - b.split);
7269
7340
  for (const seg of sorted) {
@@ -7342,11 +7413,16 @@ const getApiCampaigns = () => getCampaignsByRule(API_CAMPAIGN_RULES);
7342
7413
  * @returns An object containing the campaign and paywall data, or an empty object if not found
7343
7414
  */
7344
7415
  const getPaywallDataFromSources = (campaignsSource, paywallsSource, value, type) => {
7345
- const campaign = campaignsSource().find((campaign) => {
7346
- if (!type)
7347
- return campaign.type == NamiCampaignRuleType.DEFAULT;
7348
- return campaign.type == type && campaign.value == value;
7349
- });
7416
+ const campaign = (() => {
7417
+ if (!type) {
7418
+ return campaignsSource().find(c => c.type == NamiCampaignRuleType.DEFAULT);
7419
+ }
7420
+ if (type === NamiCampaignRuleType.URL) {
7421
+ const urlCampaigns = campaignsSource().filter(c => c.type == NamiCampaignRuleType.URL);
7422
+ return bestUrlCampaignMatch(value, urlCampaigns);
7423
+ }
7424
+ return campaignsSource().find(c => c.type == type && c.value == value);
7425
+ })();
7350
7426
  if (!campaign)
7351
7427
  return {};
7352
7428
  const paywall = paywallsSource().find((paywall) => {
@@ -63693,4 +63769,4 @@ function namiBuySKU(skuRefId) {
63693
63769
  return result;
63694
63770
  }
63695
63771
 
63696
- 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, 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, 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, NamiAPI, NamiAnimationType, NamiCampaignManager, NamiCampaignRuleType, NamiConditionEvaluator, NamiCustomerManager, NamiEntitlementManager, NamiEventEmitter, NamiFlow, NamiFlowActionFunction, NamiFlowManager, NamiFlowStepType, NamiPaywallAction, NamiPaywallManager, PaywallManagerEvents as NamiPaywallManagerEvents, NamiProfileManager, 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, 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, activateEntitlementByPurchase, activeEntitlements, allCampaigns, allPaywalls, applyEntitlementActivation, audienceSplitPosition, 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, 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, selectSegment, setActiveNamiEntitlements, shouldValidateProductGroups, skuItems, skuMapFromEntitlements, storageService, toDouble, toNamiEntitlements, toNamiSKU, tryParseB64Gzip, tryParseJson, updateRelatedSKUsForNamiEntitlement, uuidFromSplitPosition, validateMinSDKVersion };
63772
+ 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, 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, 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, NamiAPI, NamiAnimationType, NamiCampaignManager, NamiCampaignRuleType, NamiConditionEvaluator, NamiCustomerManager, NamiEntitlementManager, NamiEventEmitter, NamiFlow, NamiFlowActionFunction, NamiFlowManager, NamiFlowStepType, NamiPaywallAction, NamiPaywallManager, PaywallManagerEvents as NamiPaywallManagerEvents, NamiProfileManager, 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, 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, activateEntitlementByPurchase, activeEntitlements, 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, 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, selectSegment, setActiveNamiEntitlements, shouldValidateProductGroups, skuItems, skuMapFromEntitlements, storageService, toDouble, toNamiEntitlements, toNamiSKU, tryParseB64Gzip, tryParseJson, updateRelatedSKUsForNamiEntitlement, uuidFromSplitPosition, validateMinSDKVersion };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@namiml/sdk-core",
3
- "version": "3.4.0-dev.202604011456",
3
+ "version": "3.4.0-dev.202604031805",
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",