@namiml/sdk-core 3.4.0-dev.202604012247 → 3.4.0-dev.202604032229

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
@@ -1,23 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  let _adapters = null;
4
- const __coreAdaptersInstanceId = Math.random().toString(16).slice(2);
5
4
  function registerPlatformAdapters(adapters) {
6
5
  _adapters = adapters;
7
- try {
8
- globalThis.__NAMI_CORE_LAST_REGISTER_INSTANCE_ID = __coreAdaptersInstanceId;
9
- globalThis.__NAMI_CORE_LAST_REGISTERED_AT = Date.now();
10
- }
11
- catch {
12
- // ignore
13
- }
14
- // Vega/Metro debugging: confirms which core module instance is registering adapters.
15
- console.warn('[NamiCore] registerPlatformAdapters', {
16
- instanceId: __coreAdaptersInstanceId,
17
- hasDeviceAdapter: Boolean(adapters?.device),
18
- hasStorageAdapter: Boolean(adapters?.storage),
19
- hasUIAdapter: Boolean(adapters?.ui),
20
- });
21
6
  }
22
7
  const _fallback = {
23
8
  storage: {
@@ -42,23 +27,6 @@ const _fallback = {
42
27
  },
43
28
  };
44
29
  function getPlatformAdapters() {
45
- let lastRegisterInstanceId;
46
- let lastRegisteredAt;
47
- try {
48
- lastRegisterInstanceId = globalThis.__NAMI_CORE_LAST_REGISTER_INSTANCE_ID;
49
- lastRegisteredAt = globalThis.__NAMI_CORE_LAST_REGISTERED_AT;
50
- }
51
- catch {
52
- // ignore
53
- }
54
- // Vega/Metro debugging: if you see different instanceIds across calls, core is loaded twice (CJS+ESM).
55
- console.warn('[NamiCore] getPlatformAdapters', {
56
- instanceId: __coreAdaptersInstanceId,
57
- lastRegisterInstanceId,
58
- lastRegisteredAt,
59
- hasAdapters: Boolean(_adapters),
60
- usingFallback: !_adapters,
61
- });
62
30
  return _adapters ?? _fallback;
63
31
  }
64
32
 
@@ -123,7 +91,7 @@ const {
123
91
  // version — stamped by scripts/version.sh
124
92
  NAMI_SDK_VERSION: exports.NAMI_SDK_VERSION = "3.4.0",
125
93
  // 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.202604012247",
94
+ NAMI_SDK_PACKAGE_VERSION: exports.NAMI_SDK_PACKAGE_VERSION = "3.4.0-dev.202604032229",
127
95
  // environments
128
96
  PRODUCTION: exports.PRODUCTION = "production", DEVELOPMENT: exports.DEVELOPMENT = "development",
129
97
  // error messages
@@ -7049,10 +7017,7 @@ const hasGetRandomValues = typeof cryptoObj?.getRandomValues === 'function';
7049
7017
  const FALLBACK_BASE = 16;
7050
7018
  const FALLBACK_BASE_RECIPROCAL = 1 / FALLBACK_BASE;
7051
7019
  const getDeviceData = (namiCommands) => {
7052
- console.log('[NamiCore] getDeviceData');
7053
- const data = getPlatformAdapters().device.getDeviceData(namiCommands);
7054
- console.log('[NamiCore] getDeviceData data', data);
7055
- return data;
7020
+ return getPlatformAdapters().device.getDeviceData(namiCommands);
7056
7021
  };
7057
7022
  const getDeviceFormFactor = () => {
7058
7023
  const config = storageService.getNamiConfig();
@@ -7266,6 +7231,77 @@ const isValidUrl = (label) => {
7266
7231
  return false;
7267
7232
  }
7268
7233
  };
7234
+ /**
7235
+ * Parse a URL into its base path (origin + pathname) and query parameter set.
7236
+ * Query params are stored as "key=value" strings for order-independent comparison.
7237
+ * Returns undefined if the URL cannot be parsed.
7238
+ */
7239
+ const parseUrlComponents = (url) => {
7240
+ try {
7241
+ const parsed = new URL(url);
7242
+ const basePath = parsed.origin + parsed.pathname;
7243
+ const params = new Set();
7244
+ parsed.searchParams.forEach((value, key) => {
7245
+ params.add(`${key}=${value}`);
7246
+ });
7247
+ return { basePath, params };
7248
+ }
7249
+ catch {
7250
+ return undefined;
7251
+ }
7252
+ };
7253
+ /**
7254
+ * Find the best-matching URL campaign for an incoming URL using scored matching.
7255
+ * Compares base paths (origin + pathname), then scores by query param key=value overlap.
7256
+ * Priority: exact match (all campaign params present) > partial match > base-path-only fallback.
7257
+ * Among ties, the campaign with more total params (more specific) wins.
7258
+ */
7259
+ const bestUrlCampaignMatch = (incomingUrl, campaigns) => {
7260
+ const incoming = parseUrlComponents(incomingUrl);
7261
+ if (!incoming)
7262
+ return undefined;
7263
+ let bestExact;
7264
+ let bestPartial;
7265
+ for (const campaign of campaigns) {
7266
+ const campaignValue = campaign.value;
7267
+ if (!campaignValue)
7268
+ continue;
7269
+ const parsed = parseUrlComponents(campaignValue);
7270
+ if (!parsed)
7271
+ continue;
7272
+ if (parsed.basePath !== incoming.basePath)
7273
+ continue;
7274
+ const totalParams = parsed.params.size;
7275
+ // Base-path-only campaign (no query params): lowest-priority fallback
7276
+ if (totalParams === 0) {
7277
+ if (!bestExact && !bestPartial) {
7278
+ bestPartial = { campaign, score: 0, totalParams: 0 };
7279
+ }
7280
+ continue;
7281
+ }
7282
+ let score = 0;
7283
+ for (const param of parsed.params) {
7284
+ if (incoming.params.has(param)) {
7285
+ score++;
7286
+ }
7287
+ }
7288
+ if (score === totalParams) {
7289
+ // Exact match: all campaign params present in incoming URL
7290
+ if (!bestExact || totalParams > bestExact.totalParams) {
7291
+ bestExact = { campaign, totalParams };
7292
+ }
7293
+ }
7294
+ else if (!bestExact) {
7295
+ // Partial match: only consider if no exact match exists yet
7296
+ if (!bestPartial ||
7297
+ score > bestPartial.score ||
7298
+ (score === bestPartial.score && totalParams > bestPartial.totalParams)) {
7299
+ bestPartial = { campaign, score, totalParams };
7300
+ }
7301
+ }
7302
+ }
7303
+ return bestExact?.campaign ?? bestPartial?.campaign;
7304
+ };
7269
7305
  const selectSegment = (segments, splitPosition) => {
7270
7306
  const sorted = [...segments].sort((a, b) => a.split - b.split);
7271
7307
  for (const seg of sorted) {
@@ -7344,11 +7380,16 @@ const getApiCampaigns = () => getCampaignsByRule(exports.API_CAMPAIGN_RULES);
7344
7380
  * @returns An object containing the campaign and paywall data, or an empty object if not found
7345
7381
  */
7346
7382
  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
- });
7383
+ const campaign = (() => {
7384
+ if (!type) {
7385
+ return campaignsSource().find(c => c.type == exports.NamiCampaignRuleType.DEFAULT);
7386
+ }
7387
+ if (type === exports.NamiCampaignRuleType.URL) {
7388
+ const urlCampaigns = campaignsSource().filter(c => c.type == exports.NamiCampaignRuleType.URL);
7389
+ return bestUrlCampaignMatch(value, urlCampaigns);
7390
+ }
7391
+ return campaignsSource().find(c => c.type == type && c.value == value);
7392
+ })();
7352
7393
  if (!campaign)
7353
7394
  return {};
7354
7395
  const paywall = paywallsSource().find((paywall) => {
@@ -7900,7 +7941,7 @@ class CampaignRuleRepository {
7900
7941
  }
7901
7942
  // get campaign rules according to device's form_factor
7902
7943
  campaignRules = campaignRules?.filter((cRule) => (cRule.paywall && cRule.form_factors.some((f) => f.form_factor === this.currentFormFactor)) ||
7903
- (cRule.flow && cRule.flow?.object?.form_factors?.some((f) => f.form_factor === this.currentFormFactor)));
7944
+ (cRule.flow && cRule.form_factors?.some((f) => f.form_factor === this.currentFormFactor)));
7904
7945
  // Keep only those campaign rules whose corresponding paywall is available
7905
7946
  campaignRules = campaignRules?.filter((cRule) => {
7906
7947
  if (cRule.paywall) {
@@ -7927,11 +7968,14 @@ class CampaignRuleRepository {
7927
7968
  if (campaign.page_urls) {
7928
7969
  urls.push(...Object.values(campaign.page_urls));
7929
7970
  }
7971
+ if (campaign.flow?.page_urls) {
7972
+ urls.push(...Object.values(campaign.flow.page_urls));
7973
+ }
7930
7974
  }
7931
7975
  return urls;
7932
7976
  }
7933
7977
  static hasPaywallUrls(campaigns) {
7934
- return campaigns.some((c) => c.paywall_url || c.page_urls);
7978
+ return campaigns.some((c) => c.paywall_url || c.page_urls || c.flow?.page_urls);
7935
7979
  }
7936
7980
  async fetchCampaignRulesRaw() {
7937
7981
  const authDevice = storageService.getDevice();
@@ -7947,7 +7991,7 @@ class CampaignRuleRepository {
7947
7991
  campaignRules = await this.getCampaigns(authDevice.id);
7948
7992
  }
7949
7993
  campaignRules = campaignRules?.filter((cRule) => (cRule.paywall && cRule.form_factors.some((f) => f.form_factor === this.currentFormFactor)) ||
7950
- (cRule.flow && cRule.flow?.object?.form_factors?.some((f) => f.form_factor === this.currentFormFactor)));
7994
+ (cRule.flow && cRule.form_factors?.some((f) => f.form_factor === this.currentFormFactor)));
7951
7995
  return campaignRules;
7952
7996
  }
7953
7997
  finalizeCampaignRules(campaignRules, paywalls) {
@@ -11625,6 +11669,24 @@ class NamiRefs {
11625
11669
  const campaignRulesStartTime = Date.now();
11626
11670
  const rawCampaigns = await campaignRepo.fetchCampaignRulesRaw();
11627
11671
  const campaignRulesDuration = Date.now() - campaignRulesStartTime;
11672
+ // Hydrate flow objects: fetch flow JSON from flow.url for campaigns that
11673
+ // use the new URL-based format (3.4.0+) instead of inline flow.object
11674
+ await Promise.all(rawCampaigns
11675
+ .filter((c) => c.flow?.url && !c.flow.object)
11676
+ .map(async (c) => {
11677
+ try {
11678
+ const res = await fetch(c.flow.url, { cache: 'no-cache' });
11679
+ if (res.ok) {
11680
+ c.flow.object = await res.json();
11681
+ }
11682
+ else {
11683
+ logger.warn(`Failed to fetch flow object from ${c.flow.url}: ${res.status}`);
11684
+ }
11685
+ }
11686
+ catch (err) {
11687
+ logger.warn(`Error fetching flow object from ${c.flow.url}: ${err}`);
11688
+ }
11689
+ }));
11628
11690
  const useIndividual = !campaignRepo.useLegacyPaywallFetch &&
11629
11691
  CampaignRuleRepository.hasPaywallUrls(rawCampaigns);
11630
11692
  let paywalls;
@@ -63753,6 +63815,7 @@ exports.allCampaigns = allCampaigns;
63753
63815
  exports.allPaywalls = allPaywalls;
63754
63816
  exports.applyEntitlementActivation = applyEntitlementActivation;
63755
63817
  exports.audienceSplitPosition = audienceSplitPosition;
63818
+ exports.bestUrlCampaignMatch = bestUrlCampaignMatch;
63756
63819
  exports.bigintToUuid = bigintToUuid;
63757
63820
  exports.checkAnySkuHasPromoOffer = checkAnySkuHasPromoOffer;
63758
63821
  exports.checkAnySkuHasTrialOffer = checkAnySkuHasTrialOffer;
package/dist/index.d.ts CHANGED
@@ -138,6 +138,8 @@ interface NamiFlowDTO {
138
138
  flow_id?: string;
139
139
  object_id?: string;
140
140
  object?: NamiFlowObjectDTO;
141
+ url?: string;
142
+ page_urls?: Record<string, string>;
141
143
  }
142
144
  type NamiFlowWithObject = Omit<NamiFlowDTO, 'object'> & {
143
145
  object: NamiFlowObjectDTO;
@@ -2617,6 +2619,13 @@ declare class NamiRefs {
2617
2619
  }
2618
2620
 
2619
2621
  declare const isValidUrl: (label: string) => boolean;
2622
+ /**
2623
+ * Find the best-matching URL campaign for an incoming URL using scored matching.
2624
+ * Compares base paths (origin + pathname), then scores by query param key=value overlap.
2625
+ * Priority: exact match (all campaign params present) > partial match > base-path-only fallback.
2626
+ * Among ties, the campaign with more total params (more specific) wins.
2627
+ */
2628
+ declare const bestUrlCampaignMatch: (incomingUrl: string, campaigns: NamiCampaign[]) => NamiCampaign | undefined;
2620
2629
  declare const selectSegment: (segments: NamiCampaignSegment[], splitPosition: number) => NamiCampaignSegment;
2621
2630
  declare const mapAnonymousCampaigns: (campaigns: NamiAnonymousCampaign[], splitPosition: number, formFactor?: TDevice) => NamiCampaign[];
2622
2631
  /**
@@ -2929,5 +2938,5 @@ declare const getBillingPeriodNumber: (billingPeriod: string) => number;
2929
2938
  declare const formattedPrice: (price: number) => number;
2930
2939
  declare function toDouble(num: number): number;
2931
2940
 
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 };
2941
+ 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
2942
  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
@@ -1,21 +1,6 @@
1
1
  let _adapters = null;
2
- const __coreAdaptersInstanceId = Math.random().toString(16).slice(2);
3
2
  function registerPlatformAdapters(adapters) {
4
3
  _adapters = adapters;
5
- try {
6
- globalThis.__NAMI_CORE_LAST_REGISTER_INSTANCE_ID = __coreAdaptersInstanceId;
7
- globalThis.__NAMI_CORE_LAST_REGISTERED_AT = Date.now();
8
- }
9
- catch {
10
- // ignore
11
- }
12
- // Vega/Metro debugging: confirms which core module instance is registering adapters.
13
- console.warn('[NamiCore] registerPlatformAdapters', {
14
- instanceId: __coreAdaptersInstanceId,
15
- hasDeviceAdapter: Boolean(adapters?.device),
16
- hasStorageAdapter: Boolean(adapters?.storage),
17
- hasUIAdapter: Boolean(adapters?.ui),
18
- });
19
4
  }
20
5
  const _fallback = {
21
6
  storage: {
@@ -40,23 +25,6 @@ const _fallback = {
40
25
  },
41
26
  };
42
27
  function getPlatformAdapters() {
43
- let lastRegisterInstanceId;
44
- let lastRegisteredAt;
45
- try {
46
- lastRegisterInstanceId = globalThis.__NAMI_CORE_LAST_REGISTER_INSTANCE_ID;
47
- lastRegisteredAt = globalThis.__NAMI_CORE_LAST_REGISTERED_AT;
48
- }
49
- catch {
50
- // ignore
51
- }
52
- // Vega/Metro debugging: if you see different instanceIds across calls, core is loaded twice (CJS+ESM).
53
- console.warn('[NamiCore] getPlatformAdapters', {
54
- instanceId: __coreAdaptersInstanceId,
55
- lastRegisterInstanceId,
56
- lastRegisteredAt,
57
- hasAdapters: Boolean(_adapters),
58
- usingFallback: !_adapters,
59
- });
60
28
  return _adapters ?? _fallback;
61
29
  }
62
30
 
@@ -121,7 +89,7 @@ const {
121
89
  // version — stamped by scripts/version.sh
122
90
  NAMI_SDK_VERSION = "3.4.0",
123
91
  // full package version including dev suffix — stamped by scripts/version.sh
124
- NAMI_SDK_PACKAGE_VERSION = "3.4.0-dev.202604012247",
92
+ NAMI_SDK_PACKAGE_VERSION = "3.4.0-dev.202604032229",
125
93
  // environments
126
94
  PRODUCTION = "production", DEVELOPMENT = "development",
127
95
  // error messages
@@ -7047,10 +7015,7 @@ const hasGetRandomValues = typeof cryptoObj?.getRandomValues === 'function';
7047
7015
  const FALLBACK_BASE = 16;
7048
7016
  const FALLBACK_BASE_RECIPROCAL = 1 / FALLBACK_BASE;
7049
7017
  const getDeviceData = (namiCommands) => {
7050
- console.log('[NamiCore] getDeviceData');
7051
- const data = getPlatformAdapters().device.getDeviceData(namiCommands);
7052
- console.log('[NamiCore] getDeviceData data', data);
7053
- return data;
7018
+ return getPlatformAdapters().device.getDeviceData(namiCommands);
7054
7019
  };
7055
7020
  const getDeviceFormFactor = () => {
7056
7021
  const config = storageService.getNamiConfig();
@@ -7264,6 +7229,77 @@ const isValidUrl = (label) => {
7264
7229
  return false;
7265
7230
  }
7266
7231
  };
7232
+ /**
7233
+ * Parse a URL into its base path (origin + pathname) and query parameter set.
7234
+ * Query params are stored as "key=value" strings for order-independent comparison.
7235
+ * Returns undefined if the URL cannot be parsed.
7236
+ */
7237
+ const parseUrlComponents = (url) => {
7238
+ try {
7239
+ const parsed = new URL(url);
7240
+ const basePath = parsed.origin + parsed.pathname;
7241
+ const params = new Set();
7242
+ parsed.searchParams.forEach((value, key) => {
7243
+ params.add(`${key}=${value}`);
7244
+ });
7245
+ return { basePath, params };
7246
+ }
7247
+ catch {
7248
+ return undefined;
7249
+ }
7250
+ };
7251
+ /**
7252
+ * Find the best-matching URL campaign for an incoming URL using scored matching.
7253
+ * Compares base paths (origin + pathname), then scores by query param key=value overlap.
7254
+ * Priority: exact match (all campaign params present) > partial match > base-path-only fallback.
7255
+ * Among ties, the campaign with more total params (more specific) wins.
7256
+ */
7257
+ const bestUrlCampaignMatch = (incomingUrl, campaigns) => {
7258
+ const incoming = parseUrlComponents(incomingUrl);
7259
+ if (!incoming)
7260
+ return undefined;
7261
+ let bestExact;
7262
+ let bestPartial;
7263
+ for (const campaign of campaigns) {
7264
+ const campaignValue = campaign.value;
7265
+ if (!campaignValue)
7266
+ continue;
7267
+ const parsed = parseUrlComponents(campaignValue);
7268
+ if (!parsed)
7269
+ continue;
7270
+ if (parsed.basePath !== incoming.basePath)
7271
+ continue;
7272
+ const totalParams = parsed.params.size;
7273
+ // Base-path-only campaign (no query params): lowest-priority fallback
7274
+ if (totalParams === 0) {
7275
+ if (!bestExact && !bestPartial) {
7276
+ bestPartial = { campaign, score: 0, totalParams: 0 };
7277
+ }
7278
+ continue;
7279
+ }
7280
+ let score = 0;
7281
+ for (const param of parsed.params) {
7282
+ if (incoming.params.has(param)) {
7283
+ score++;
7284
+ }
7285
+ }
7286
+ if (score === totalParams) {
7287
+ // Exact match: all campaign params present in incoming URL
7288
+ if (!bestExact || totalParams > bestExact.totalParams) {
7289
+ bestExact = { campaign, totalParams };
7290
+ }
7291
+ }
7292
+ else if (!bestExact) {
7293
+ // Partial match: only consider if no exact match exists yet
7294
+ if (!bestPartial ||
7295
+ score > bestPartial.score ||
7296
+ (score === bestPartial.score && totalParams > bestPartial.totalParams)) {
7297
+ bestPartial = { campaign, score, totalParams };
7298
+ }
7299
+ }
7300
+ }
7301
+ return bestExact?.campaign ?? bestPartial?.campaign;
7302
+ };
7267
7303
  const selectSegment = (segments, splitPosition) => {
7268
7304
  const sorted = [...segments].sort((a, b) => a.split - b.split);
7269
7305
  for (const seg of sorted) {
@@ -7342,11 +7378,16 @@ const getApiCampaigns = () => getCampaignsByRule(API_CAMPAIGN_RULES);
7342
7378
  * @returns An object containing the campaign and paywall data, or an empty object if not found
7343
7379
  */
7344
7380
  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
- });
7381
+ const campaign = (() => {
7382
+ if (!type) {
7383
+ return campaignsSource().find(c => c.type == NamiCampaignRuleType.DEFAULT);
7384
+ }
7385
+ if (type === NamiCampaignRuleType.URL) {
7386
+ const urlCampaigns = campaignsSource().filter(c => c.type == NamiCampaignRuleType.URL);
7387
+ return bestUrlCampaignMatch(value, urlCampaigns);
7388
+ }
7389
+ return campaignsSource().find(c => c.type == type && c.value == value);
7390
+ })();
7350
7391
  if (!campaign)
7351
7392
  return {};
7352
7393
  const paywall = paywallsSource().find((paywall) => {
@@ -7898,7 +7939,7 @@ class CampaignRuleRepository {
7898
7939
  }
7899
7940
  // get campaign rules according to device's form_factor
7900
7941
  campaignRules = campaignRules?.filter((cRule) => (cRule.paywall && cRule.form_factors.some((f) => f.form_factor === this.currentFormFactor)) ||
7901
- (cRule.flow && cRule.flow?.object?.form_factors?.some((f) => f.form_factor === this.currentFormFactor)));
7942
+ (cRule.flow && cRule.form_factors?.some((f) => f.form_factor === this.currentFormFactor)));
7902
7943
  // Keep only those campaign rules whose corresponding paywall is available
7903
7944
  campaignRules = campaignRules?.filter((cRule) => {
7904
7945
  if (cRule.paywall) {
@@ -7925,11 +7966,14 @@ class CampaignRuleRepository {
7925
7966
  if (campaign.page_urls) {
7926
7967
  urls.push(...Object.values(campaign.page_urls));
7927
7968
  }
7969
+ if (campaign.flow?.page_urls) {
7970
+ urls.push(...Object.values(campaign.flow.page_urls));
7971
+ }
7928
7972
  }
7929
7973
  return urls;
7930
7974
  }
7931
7975
  static hasPaywallUrls(campaigns) {
7932
- return campaigns.some((c) => c.paywall_url || c.page_urls);
7976
+ return campaigns.some((c) => c.paywall_url || c.page_urls || c.flow?.page_urls);
7933
7977
  }
7934
7978
  async fetchCampaignRulesRaw() {
7935
7979
  const authDevice = storageService.getDevice();
@@ -7945,7 +7989,7 @@ class CampaignRuleRepository {
7945
7989
  campaignRules = await this.getCampaigns(authDevice.id);
7946
7990
  }
7947
7991
  campaignRules = campaignRules?.filter((cRule) => (cRule.paywall && cRule.form_factors.some((f) => f.form_factor === this.currentFormFactor)) ||
7948
- (cRule.flow && cRule.flow?.object?.form_factors?.some((f) => f.form_factor === this.currentFormFactor)));
7992
+ (cRule.flow && cRule.form_factors?.some((f) => f.form_factor === this.currentFormFactor)));
7949
7993
  return campaignRules;
7950
7994
  }
7951
7995
  finalizeCampaignRules(campaignRules, paywalls) {
@@ -11623,6 +11667,24 @@ class NamiRefs {
11623
11667
  const campaignRulesStartTime = Date.now();
11624
11668
  const rawCampaigns = await campaignRepo.fetchCampaignRulesRaw();
11625
11669
  const campaignRulesDuration = Date.now() - campaignRulesStartTime;
11670
+ // Hydrate flow objects: fetch flow JSON from flow.url for campaigns that
11671
+ // use the new URL-based format (3.4.0+) instead of inline flow.object
11672
+ await Promise.all(rawCampaigns
11673
+ .filter((c) => c.flow?.url && !c.flow.object)
11674
+ .map(async (c) => {
11675
+ try {
11676
+ const res = await fetch(c.flow.url, { cache: 'no-cache' });
11677
+ if (res.ok) {
11678
+ c.flow.object = await res.json();
11679
+ }
11680
+ else {
11681
+ logger.warn(`Failed to fetch flow object from ${c.flow.url}: ${res.status}`);
11682
+ }
11683
+ }
11684
+ catch (err) {
11685
+ logger.warn(`Error fetching flow object from ${c.flow.url}: ${err}`);
11686
+ }
11687
+ }));
11626
11688
  const useIndividual = !campaignRepo.useLegacyPaywallFetch &&
11627
11689
  CampaignRuleRepository.hasPaywallUrls(rawCampaigns);
11628
11690
  let paywalls;
@@ -63693,4 +63755,4 @@ function namiBuySKU(skuRefId) {
63693
63755
  return result;
63694
63756
  }
63695
63757
 
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 };
63758
+ 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.202604012247",
3
+ "version": "3.4.0-dev.202604032229",
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",