@namiml/sdk-core 3.4.12 → 3.4.13-dev.202610261518
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 +114 -23
- package/dist/index.d.ts +4 -2
- package/dist/index.mjs +115 -24
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -104,9 +104,9 @@ exports.Capabilities = void 0;
|
|
|
104
104
|
|
|
105
105
|
const {
|
|
106
106
|
// version — stamped by scripts/version.sh
|
|
107
|
-
NAMI_SDK_VERSION: exports.NAMI_SDK_VERSION = "3.4.
|
|
107
|
+
NAMI_SDK_VERSION: exports.NAMI_SDK_VERSION = "3.4.13",
|
|
108
108
|
// full package version including dev suffix — stamped by scripts/version.sh
|
|
109
|
-
NAMI_SDK_PACKAGE_VERSION: exports.NAMI_SDK_PACKAGE_VERSION = "3.4.
|
|
109
|
+
NAMI_SDK_PACKAGE_VERSION: exports.NAMI_SDK_PACKAGE_VERSION = "3.4.13-dev.202610261518",
|
|
110
110
|
// environments
|
|
111
111
|
PRODUCTION: exports.PRODUCTION = "production", DEVELOPMENT: exports.DEVELOPMENT = "development",
|
|
112
112
|
// error messages
|
|
@@ -130,7 +130,9 @@ CAMPAIGN_CACHE_TTL_PREFIX: exports.CAMPAIGN_CACHE_TTL_PREFIX = "campaignCacheTTL
|
|
|
130
130
|
// and the builder preview can evaluate time conditions at any moment (NAM-4635).
|
|
131
131
|
TIME_OVERRIDE_PREFIX: exports.TIME_OVERRIDE_PREFIX = "timeOverride=",
|
|
132
132
|
// Page condition values that resolve against the per-presentation time snapshot (NAM-4635).
|
|
133
|
-
SYSTEM_TIME_TOKEN_PREFIX: exports.SYSTEM_TIME_TOKEN_PREFIX = "${system.time.",
|
|
133
|
+
SYSTEM_TIME_TOKEN_PREFIX: exports.SYSTEM_TIME_TOKEN_PREFIX = "${system.time.",
|
|
134
|
+
// Flow branch-condition identifiers that the condition evaluator handles itself, read live (NAM-5226).
|
|
135
|
+
SYSTEM_TIME_FILTER_PREFIX: exports.SYSTEM_TIME_FILTER_PREFIX = "System.time.", EXTENDED_PLATFORM: exports.EXTENDED_PLATFORM = "extended-platform", EXTENDED_PLATFORM_VERSION: exports.EXTENDED_PLATFORM_VERSION = "extended-platform-version", API_MAX_CALLS_LIMIT: exports.API_MAX_CALLS_LIMIT = 2, API_RETRY_DELAY_SEC: exports.API_RETRY_DELAY_SEC = 2, API_TIMEOUT_LIMIT: exports.API_TIMEOUT_LIMIT = 20000, DEVICE_API_TIMEOUT_LIMIT: exports.DEVICE_API_TIMEOUT_LIMIT = 2000,
|
|
134
136
|
// Platform-config attempts when no initial config was supplied (Android's
|
|
135
137
|
// CONFIG_MAX_ATTEMPTS; Apple's retry(maxAttempts: 3)).
|
|
136
138
|
CONFIG_MAX_ATTEMPTS: exports.CONFIG_MAX_ATTEMPTS = 3,
|
|
@@ -61329,6 +61331,10 @@ const isSystemTimeAssertion = (assertion) => typeof assertion.value === "string"
|
|
|
61329
61331
|
const parseInstant = (value) => {
|
|
61330
61332
|
if (typeof value !== "string" || !INSTANT.test(value))
|
|
61331
61333
|
return null;
|
|
61334
|
+
// `Date` rolls an impossible day over (2026-02-30 → March 2) instead of rejecting it.
|
|
61335
|
+
const [year, month, day] = value.slice(0, 10).split("-").map(Number);
|
|
61336
|
+
if (day > new Date(Date.UTC(year, month, 0)).getUTCDate())
|
|
61337
|
+
return null;
|
|
61332
61338
|
const date = new Date(value);
|
|
61333
61339
|
return Number.isNaN(date.getTime()) ? null : date;
|
|
61334
61340
|
};
|
|
@@ -61368,16 +61374,33 @@ const parseDay = (expected) => {
|
|
|
61368
61374
|
const zoned = splitZoned(expected);
|
|
61369
61375
|
return zoned && DAYS.includes(zoned.value) ? { day: zoned.value, zone: zoned.zone } : null;
|
|
61370
61376
|
};
|
|
61377
|
+
/** `H:mm@zone` / `HH:mm@zone` as minutes since local midnight plus the zone, or `null`. */
|
|
61378
|
+
const parseZonedTime = (expected) => {
|
|
61379
|
+
const zoned = splitZoned(expected);
|
|
61380
|
+
const match = zoned && TIME_OF_DAY.exec(zoned.value);
|
|
61381
|
+
return zoned && match ? { minutes: Number(match[1]) * 60 + Number(match[2]), zone: zoned.zone } : null;
|
|
61382
|
+
};
|
|
61383
|
+
/**
|
|
61384
|
+
* Every element parsed by `parse`, or `null` when `values` is not a non-empty array or any element
|
|
61385
|
+
* is invalid — a valid match elsewhere in the list never rescues an invalid element.
|
|
61386
|
+
*/
|
|
61387
|
+
const parseAll = (values, parse) => {
|
|
61388
|
+
if (!Array.isArray(values) || values.length === 0)
|
|
61389
|
+
return null;
|
|
61390
|
+
const parsed = [];
|
|
61391
|
+
for (const value of values) {
|
|
61392
|
+
const item = typeof value === "string" ? parse(value) : null;
|
|
61393
|
+
if (item === null)
|
|
61394
|
+
return null;
|
|
61395
|
+
parsed.push(item);
|
|
61396
|
+
}
|
|
61397
|
+
return parsed;
|
|
61398
|
+
};
|
|
61371
61399
|
const evaluateDayOfWeek = (operator, expected, now) => {
|
|
61372
61400
|
const isDay = ({ day, zone }) => projectInZone(now, zone)?.dayOfWeek === day;
|
|
61373
61401
|
if (operator === "in") {
|
|
61374
|
-
|
|
61375
|
-
|
|
61376
|
-
const days = expected.map(parseDay);
|
|
61377
|
-
// Any invalid element invalidates the whole assertion, even when another element matches.
|
|
61378
|
-
if (days.some((day) => day === null))
|
|
61379
|
-
return false;
|
|
61380
|
-
return days.some((day) => isDay(day));
|
|
61402
|
+
const days = parseAll(expected, parseDay);
|
|
61403
|
+
return days !== null && days.some(isDay);
|
|
61381
61404
|
}
|
|
61382
61405
|
if (operator !== "equals" && operator !== "notEquals")
|
|
61383
61406
|
return false;
|
|
@@ -61392,14 +61415,11 @@ const evaluateDayOfWeek = (operator, expected, now) => {
|
|
|
61392
61415
|
const evaluateTimeOfDay = (operator, expected, now) => {
|
|
61393
61416
|
if (!isOrderingOperator(operator))
|
|
61394
61417
|
return false;
|
|
61395
|
-
const
|
|
61396
|
-
const
|
|
61397
|
-
if (!
|
|
61418
|
+
const time = parseZonedTime(expected);
|
|
61419
|
+
const projected = time && projectInZone(now, time.zone);
|
|
61420
|
+
if (!time || !projected)
|
|
61398
61421
|
return false;
|
|
61399
|
-
|
|
61400
|
-
if (!projected)
|
|
61401
|
-
return false;
|
|
61402
|
-
return ORDERING[operator](projected.minutes, Number(match[1]) * 60 + Number(match[2]));
|
|
61422
|
+
return ORDERING[operator](projected.minutes, time.minutes);
|
|
61403
61423
|
};
|
|
61404
61424
|
const evaluateNow = (operator, expected, now) => {
|
|
61405
61425
|
if (!isOrderingOperator(operator))
|
|
@@ -61429,11 +61449,66 @@ const evaluateSystemTimeAssertion = (assertion, now) => {
|
|
|
61429
61449
|
return false;
|
|
61430
61450
|
}
|
|
61431
61451
|
};
|
|
61452
|
+
// Flow branch conditions use the engine's operator names; they compare the same way as Pages'.
|
|
61453
|
+
const FLOW_ORDERING = {
|
|
61454
|
+
equals: ORDERING.equals,
|
|
61455
|
+
greater_than: ORDERING.gt,
|
|
61456
|
+
greater_than_or_equal_to: ORDERING.gte,
|
|
61457
|
+
less_than: ORDERING.lt,
|
|
61458
|
+
less_than_or_equal_to: ORDERING.lte,
|
|
61459
|
+
};
|
|
61460
|
+
const flowComparison = (operator) => Object.prototype.hasOwnProperty.call(FLOW_ORDERING, operator) ? FLOW_ORDERING[operator] : null;
|
|
61461
|
+
/** True when a Flow filter identifier is `System.time.<leaf>` (any leaf; unknown leaves evaluate `false`). */
|
|
61462
|
+
const isSystemTimeFilter = (identifier) => typeof identifier === "string" && identifier.startsWith(exports.SYSTEM_TIME_FILTER_PREFIX);
|
|
61463
|
+
/**
|
|
61464
|
+
* Evaluates a Flow branch filter on `System.time.*` (the "Flow branch conditions" section of
|
|
61465
|
+
* `shared/time_conditions/README.md`, verified against `flow_vectors.json`). Every value is
|
|
61466
|
+
* validated before anything is compared, so an invalid value is `false` for every operator,
|
|
61467
|
+
* `not_equals` included. Several values match when any one does; `not_equals` when none does.
|
|
61468
|
+
*/
|
|
61469
|
+
const evaluateSystemTimeFilter = (filter, now) => {
|
|
61470
|
+
if (!isSystemTimeFilter(filter.identifier) || Number.isNaN(now.getTime()))
|
|
61471
|
+
return false;
|
|
61472
|
+
switch (filter.identifier.slice(exports.SYSTEM_TIME_FILTER_PREFIX.length)) {
|
|
61473
|
+
case "dayOfWeek": {
|
|
61474
|
+
if (filter.operator !== "equals" && filter.operator !== "not_equals")
|
|
61475
|
+
return false;
|
|
61476
|
+
const days = parseAll(filter.values, parseDay);
|
|
61477
|
+
if (!days)
|
|
61478
|
+
return false;
|
|
61479
|
+
const projected = days.map(({ zone }) => projectInZone(now, zone));
|
|
61480
|
+
if (projected.some((p) => p === null))
|
|
61481
|
+
return false;
|
|
61482
|
+
const matched = days.some(({ day }, i) => projected[i].dayOfWeek === day);
|
|
61483
|
+
return filter.operator === "equals" ? matched : !matched;
|
|
61484
|
+
}
|
|
61485
|
+
case "timeOfDay": {
|
|
61486
|
+
const compare = flowComparison(filter.operator);
|
|
61487
|
+
const times = compare ? parseAll(filter.values, parseZonedTime) : null;
|
|
61488
|
+
if (!compare || !times)
|
|
61489
|
+
return false;
|
|
61490
|
+
const projected = times.map(({ zone }) => projectInZone(now, zone));
|
|
61491
|
+
if (projected.some((p) => p === null))
|
|
61492
|
+
return false;
|
|
61493
|
+
return times.some(({ minutes }, i) => compare(projected[i].minutes, minutes));
|
|
61494
|
+
}
|
|
61495
|
+
case "now": {
|
|
61496
|
+
const compare = flowComparison(filter.operator);
|
|
61497
|
+
const instants = compare ? parseAll(filter.values, parseInstant) : null;
|
|
61498
|
+
if (!compare || !instants)
|
|
61499
|
+
return false;
|
|
61500
|
+
return instants.some((instant) => compare(now.getTime(), instant.getTime()));
|
|
61501
|
+
}
|
|
61502
|
+
default:
|
|
61503
|
+
return false;
|
|
61504
|
+
}
|
|
61505
|
+
};
|
|
61432
61506
|
/** Parses a `timeOverride=<ISO-8601 with offset>` namiCommand; `null` when it is not a valid one. */
|
|
61433
61507
|
const parseTimeOverride = (command) => command.startsWith(exports.TIME_OVERRIDE_PREFIX) ? parseInstant(command.slice(exports.TIME_OVERRIDE_PREFIX.length)) : null;
|
|
61434
61508
|
/**
|
|
61435
61509
|
* The instant to snapshot for a Page or flow-screen presentation: the `timeOverride=` namiCommand
|
|
61436
|
-
* when present and valid, otherwise the device clock. Call it once per presentation.
|
|
61510
|
+
* when present and valid, otherwise the device clock. Call it once per presentation. Flow branch
|
|
61511
|
+
* conditions call it once per condition block instead, so they see the time live.
|
|
61437
61512
|
*/
|
|
61438
61513
|
const getSystemTimeNow = () => {
|
|
61439
61514
|
const command = storageService
|
|
@@ -63129,6 +63204,15 @@ function toComparableNumber(value) {
|
|
|
63129
63204
|
}
|
|
63130
63205
|
return null;
|
|
63131
63206
|
}
|
|
63207
|
+
/**
|
|
63208
|
+
* The instant for one condition block: read on first use, then shared by every filter in the
|
|
63209
|
+
* block, so ANDed `System.time` filters see the same moment. Each block reads the clock afresh —
|
|
63210
|
+
* Flow branch conditions are live, never a snapshot from flow start (NAM-5226).
|
|
63211
|
+
*/
|
|
63212
|
+
function blockClock() {
|
|
63213
|
+
let now;
|
|
63214
|
+
return () => (now ??= getSystemTimeNow());
|
|
63215
|
+
}
|
|
63132
63216
|
class NamiConditionEvaluator {
|
|
63133
63217
|
constructor() {
|
|
63134
63218
|
this.resolvers = new Map();
|
|
@@ -63151,7 +63235,8 @@ class NamiConditionEvaluator {
|
|
|
63151
63235
|
if (filters.length === 0) {
|
|
63152
63236
|
return true;
|
|
63153
63237
|
}
|
|
63154
|
-
const
|
|
63238
|
+
const now = blockClock();
|
|
63239
|
+
const results = filters.map(filter => this.evaluateFilter(filter, now));
|
|
63155
63240
|
switch (conditions.operator) {
|
|
63156
63241
|
case LogicalOperator.AND:
|
|
63157
63242
|
return results.every(result => result);
|
|
@@ -63170,17 +63255,18 @@ class NamiConditionEvaluator {
|
|
|
63170
63255
|
if (filters.length === 0) {
|
|
63171
63256
|
return true;
|
|
63172
63257
|
}
|
|
63258
|
+
const now = blockClock();
|
|
63173
63259
|
switch (conditions.operator) {
|
|
63174
63260
|
case LogicalOperator.AND:
|
|
63175
63261
|
for (const filter of filters) {
|
|
63176
|
-
if (!this.evaluateFilter(filter)) {
|
|
63262
|
+
if (!this.evaluateFilter(filter, now)) {
|
|
63177
63263
|
return false;
|
|
63178
63264
|
}
|
|
63179
63265
|
}
|
|
63180
63266
|
return true;
|
|
63181
63267
|
case LogicalOperator.OR:
|
|
63182
63268
|
for (const filter of filters) {
|
|
63183
|
-
if (this.evaluateFilter(filter)) {
|
|
63269
|
+
if (this.evaluateFilter(filter, now)) {
|
|
63184
63270
|
return true;
|
|
63185
63271
|
}
|
|
63186
63272
|
}
|
|
@@ -63188,14 +63274,19 @@ class NamiConditionEvaluator {
|
|
|
63188
63274
|
case LogicalOperator.NONE:
|
|
63189
63275
|
default:
|
|
63190
63276
|
for (const filter of filters) {
|
|
63191
|
-
if (!this.evaluateFilter(filter)) {
|
|
63277
|
+
if (!this.evaluateFilter(filter, now)) {
|
|
63192
63278
|
return false;
|
|
63193
63279
|
}
|
|
63194
63280
|
}
|
|
63195
63281
|
return true;
|
|
63196
63282
|
}
|
|
63197
63283
|
}
|
|
63198
|
-
evaluateFilter(filter) {
|
|
63284
|
+
evaluateFilter(filter, now = blockClock()) {
|
|
63285
|
+
// System.time.* is evaluated here, ahead of the resolvers and the unresolved-value rule below,
|
|
63286
|
+
// which would otherwise make not_equals true for a field no resolver knows.
|
|
63287
|
+
if (isSystemTimeFilter(filter.identifier)) {
|
|
63288
|
+
return evaluateSystemTimeFilter(filter, now());
|
|
63289
|
+
}
|
|
63199
63290
|
const resolvedValue = this.resolve(filter.identifier);
|
|
63200
63291
|
if (Nami.instance.maxLogging) {
|
|
63201
63292
|
logger.debug(`[NamiConditionEvaluator] resolve(${filter.identifier}) → ${JSON.stringify(resolvedValue)} (type: ${typeof resolvedValue})`);
|
package/dist/index.d.ts
CHANGED
|
@@ -3263,6 +3263,7 @@ declare const SIMULATE_PAYWALL_FETCH_FAILURE: string;
|
|
|
3263
3263
|
declare const CAMPAIGN_CACHE_TTL_PREFIX: string;
|
|
3264
3264
|
declare const TIME_OVERRIDE_PREFIX: string;
|
|
3265
3265
|
declare const SYSTEM_TIME_TOKEN_PREFIX: string;
|
|
3266
|
+
declare const SYSTEM_TIME_FILTER_PREFIX: string;
|
|
3266
3267
|
declare const EXTENDED_PLATFORM: string;
|
|
3267
3268
|
declare const EXTENDED_PLATFORM_VERSION: string;
|
|
3268
3269
|
declare const API_MAX_CALLS_LIMIT: number;
|
|
@@ -3366,7 +3367,8 @@ declare const evaluateSystemTimeAssertion: (assertion: TTestObject, now: Date) =
|
|
|
3366
3367
|
declare const parseTimeOverride: (command: string) => Date | null;
|
|
3367
3368
|
/**
|
|
3368
3369
|
* The instant to snapshot for a Page or flow-screen presentation: the `timeOverride=` namiCommand
|
|
3369
|
-
* when present and valid, otherwise the device clock. Call it once per presentation.
|
|
3370
|
+
* when present and valid, otherwise the device clock. Call it once per presentation. Flow branch
|
|
3371
|
+
* conditions call it once per condition block instead, so they see the time live.
|
|
3370
3372
|
*/
|
|
3371
3373
|
declare const getSystemTimeNow: () => Date;
|
|
3372
3374
|
/**
|
|
@@ -4428,5 +4430,5 @@ declare namespace internal {
|
|
|
4428
4430
|
};
|
|
4429
4431
|
}
|
|
4430
4432
|
|
|
4431
|
-
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_TRAFFIC_OBSERVER, 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_CACHE_TTL_PREFIX, CAMPAIGN_NOT_AVAILABLE, CONFIG_API_TIMEOUT_LIMIT, CONFIG_MAX_ATTEMPTS, CUSTOMER_ATTRIBUTES_KEY_PREFIX, CUSTOMER_JOURNEY_STATE_CHANGED, CUSTOM_HOST_PREFIX, CampaignNotAvailableError, CampaignRuleConversionEventType, CampaignRuleRepository, Capabilities, ClientError, ConfigRepository, ConflictError, CustomerJourneyRepository, DEFAULT_JOURNEY_SETTINGS, 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, NamiHandoffTag, NamiPaywallAction, NamiPaywallManager$2 as NamiPaywallManager, PaywallManagerEvents as NamiPaywallManagerEvents, NamiPermissionOutcome, NamiPurchaseManager$2 as NamiPurchaseManager, NamiRefs, NamiReservedActions, NotFoundError, PAYWALL_ACTION_EVENT, PLATFORM_ID_REQUIRED, PRODUCTION, PaywallManagerEvents, PaywallRepository, PaywallState, PlacementLabelResolver, PlatformIDRequiredError, ProductRepository, RECONFIG_SUCCESS, RESUME_THROTTLE_MS, RetryLimitExceededError, SDKNotInitializedError, SDK_NOT_INITIALIZED, SERVER_NAMI_ENTITLEMENTS, SESSION_REQUIRED, SHOULD_SHOW_LOADING_INDICATOR, SIMULATE_CONFIG_FETCH_FAILURE, SIMULATE_PAYWALL_FETCH_FAILURE, SKU_TEXT_REGEX, SMART_TEXT_PATTERN, STARTUP_TELEMETRY, STATUS_BAD_REQUEST, STATUS_CONFLICT, STATUS_INTERNAL_SERVER_ERROR, STATUS_NOT_FOUND, STATUS_SUCCESS, SYSTEM_TIME_TOKEN_PREFIX, SessionService, SimpleEventTarget, StorageService, TIME_OVERRIDE_PREFIX, TRANSPORT_FAILURE_STATUS, 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, didReceiveResponse, empty, evaluateSystemTimeAssertion, evaluateSystemTimeCondition, extractStandardPricingPhases, formatDate, formattedPrice, generateUUID, getApiCampaigns, getApiPaywalls, getBaseUrl, getBillingPeriodNumber, getCurrencyFormat, getDeviceData, getDeviceFormFactor, getDeviceScaleFactor, getEffectiveWebStyle, getEntitlementRefIdsForSku, getExtendedClientInfo, getFreeTrialPeriod, getInitialCampaigns, getInitialPaywalls, getJourneySettings, getPaywall, getPaywallDataFromLabel, getPercentagePriceDifference, getPeriodNumberInDays, getPeriodNumberInWeeks, getPlatformAdapters, getPriceDifference, getPricePerMonth, getProductDetail, getPurchaseAdapter, getReferenceSku, getSkuProductDetailKeys, getSkuSmartTextValue, getSlideSmartTextValue, getStandardBillingPeriod, getSystemTimeNow, getTranslate, getUrlParams, handleErrors, hasAllPaywalls, hasCapability, hasPurchaseManagement, initialState, invokeHandler, isAnonymousMode, isInitialConfigCompressed, isNamiFlowCampaign, isSubscription, isSystemTimeAssertion, isValidISODate, isValidUrl, logger, mapAnonymousCampaigns, namiBuySKU, normalizeLaunchContext, parseTimeOverride, parseToSemver, postConversion, productDetail, registerAPITrafficObserver, registerPlatformAdapters, registerPurchaseAdapter, resolveLoopSource, selectSegment, setActiveNamiEntitlements, shouldValidateProductGroups, skuItems, skuMapFromEntitlements, storageService, toDouble, toNamiEntitlements, toNamiSKU, tryParseB64Gzip, tryParseJson, updateRelatedSKUsForNamiEntitlement, uuidFromSplitPosition, validateForm, validateMinSDKVersion, validateTextInput };
|
|
4433
|
+
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_TRAFFIC_OBSERVER, 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_CACHE_TTL_PREFIX, CAMPAIGN_NOT_AVAILABLE, CONFIG_API_TIMEOUT_LIMIT, CONFIG_MAX_ATTEMPTS, CUSTOMER_ATTRIBUTES_KEY_PREFIX, CUSTOMER_JOURNEY_STATE_CHANGED, CUSTOM_HOST_PREFIX, CampaignNotAvailableError, CampaignRuleConversionEventType, CampaignRuleRepository, Capabilities, ClientError, ConfigRepository, ConflictError, CustomerJourneyRepository, DEFAULT_JOURNEY_SETTINGS, 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, NamiHandoffTag, NamiPaywallAction, NamiPaywallManager$2 as NamiPaywallManager, PaywallManagerEvents as NamiPaywallManagerEvents, NamiPermissionOutcome, NamiPurchaseManager$2 as NamiPurchaseManager, NamiRefs, NamiReservedActions, NotFoundError, PAYWALL_ACTION_EVENT, PLATFORM_ID_REQUIRED, PRODUCTION, PaywallManagerEvents, PaywallRepository, PaywallState, PlacementLabelResolver, PlatformIDRequiredError, ProductRepository, RECONFIG_SUCCESS, RESUME_THROTTLE_MS, RetryLimitExceededError, SDKNotInitializedError, SDK_NOT_INITIALIZED, SERVER_NAMI_ENTITLEMENTS, SESSION_REQUIRED, SHOULD_SHOW_LOADING_INDICATOR, SIMULATE_CONFIG_FETCH_FAILURE, SIMULATE_PAYWALL_FETCH_FAILURE, SKU_TEXT_REGEX, SMART_TEXT_PATTERN, STARTUP_TELEMETRY, STATUS_BAD_REQUEST, STATUS_CONFLICT, STATUS_INTERNAL_SERVER_ERROR, STATUS_NOT_FOUND, STATUS_SUCCESS, SYSTEM_TIME_FILTER_PREFIX, SYSTEM_TIME_TOKEN_PREFIX, SessionService, SimpleEventTarget, StorageService, TIME_OVERRIDE_PREFIX, TRANSPORT_FAILURE_STATUS, 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, didReceiveResponse, empty, evaluateSystemTimeAssertion, evaluateSystemTimeCondition, extractStandardPricingPhases, formatDate, formattedPrice, generateUUID, getApiCampaigns, getApiPaywalls, getBaseUrl, getBillingPeriodNumber, getCurrencyFormat, getDeviceData, getDeviceFormFactor, getDeviceScaleFactor, getEffectiveWebStyle, getEntitlementRefIdsForSku, getExtendedClientInfo, getFreeTrialPeriod, getInitialCampaigns, getInitialPaywalls, getJourneySettings, getPaywall, getPaywallDataFromLabel, getPercentagePriceDifference, getPeriodNumberInDays, getPeriodNumberInWeeks, getPlatformAdapters, getPriceDifference, getPricePerMonth, getProductDetail, getPurchaseAdapter, getReferenceSku, getSkuProductDetailKeys, getSkuSmartTextValue, getSlideSmartTextValue, getStandardBillingPeriod, getSystemTimeNow, getTranslate, getUrlParams, handleErrors, hasAllPaywalls, hasCapability, hasPurchaseManagement, initialState, invokeHandler, isAnonymousMode, isInitialConfigCompressed, isNamiFlowCampaign, isSubscription, isSystemTimeAssertion, isValidISODate, isValidUrl, logger, mapAnonymousCampaigns, namiBuySKU, normalizeLaunchContext, parseTimeOverride, parseToSemver, postConversion, productDetail, registerAPITrafficObserver, registerPlatformAdapters, registerPurchaseAdapter, resolveLoopSource, selectSegment, setActiveNamiEntitlements, shouldValidateProductGroups, skuItems, skuMapFromEntitlements, storageService, toDouble, toNamiEntitlements, toNamiSKU, tryParseB64Gzip, tryParseJson, updateRelatedSKUsForNamiEntitlement, uuidFromSplitPosition, validateForm, validateMinSDKVersion, validateTextInput };
|
|
4432
4434
|
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, FormFieldValidator, GoogleProduct, IConfig, IDeviceAdapter, IEntitlements$1 as IEntitlements, IPaywall, IPlatformAdapters, IProductsWithComponents, IPurchaseAdapter, ISkuMenu, IStorageAdapter, IUIAdapter, Impression, InitialConfig, InitialConfigCompressed, InitiateStateGroup, JourneySettings, LoginResponse, NamiAPITrafficKind, NamiAPITrafficObserver, NamiAPITrafficRecord, NamiAnimation, NamiAnimationObjectSpec, NamiAnimationSpec, NamiAnonymousCampaign, NamiAppSuppliedVideoDetails, NamiCampaign, NamiCampaignManagerStatic, NamiCampaignSegment, NamiCompletionResult, NamiConfiguration, NamiConfigurationState, NamiCustomAttributeValue, NamiCustomerManagerStatic, NamiEntitlement$1 as NamiEntitlement, NamiEntitlementManagerStatic, NamiFlowAction, NamiFlowAnimation, NamiFlowCampaign, NamiFlowCompletionCondition, NamiFlowDTO, NamiFlowEventHandler, NamiFlowHandoffStepHandler, NamiFlowManagerStatic, NamiFlowObjectDTO, NamiFlowOn, NamiFlowStep, NamiFlowTransition, NamiFlowTransitionDirection, NamiFlowWithObject, NamiHandoffAttributeValue, NamiHandoffComplete, NamiHandoffOutcome, NamiHandoffTagValue, NamiInitialConfig, NamiKnownHandoffTag, NamiLanguageCodes, NamiLogLevel, NamiLoginSuccess, NamiPaywallActionHandler, NamiPaywallComponentChange, NamiPaywallEvent, NamiPaywallEventVideoMetadata, NamiPaywallLaunchContext, NamiPaywallManagerStatic, NamiPresentationStyle, NamiProductDetails, NamiProductOffer, NamiProfile, NamiPurchase, NamiPurchaseCompleteResult, NamiPurchaseDetails, NamiPurchaseManagerStatic, NamiPurchaseSuccess, NamiPurchasesState, NamiSKU, NamiSKUType, NamiSubscriptionInterval, NamiSubscriptionPeriod, NamiUserDataEnvelope, 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, TSlot, TSlotGroupSelector, TSpacerComponent, TStack, TSvgImageComponent, TSymbolComponent, TTestObject, TTextComponent, TTextInputComponent, TTextInputType, TTextLikeComponent, TTextListComponent, TTimelineRail, TToggleButtonComponent, TToggleSwitch, TVariablePattern, TVideoComponent, TVolumeButton, TimerState, TransactionRequest, UserAction, UserActionParameters, Wave, WaveSpec };
|
package/dist/index.mjs
CHANGED
|
@@ -102,9 +102,9 @@ var Capabilities;
|
|
|
102
102
|
|
|
103
103
|
const {
|
|
104
104
|
// version — stamped by scripts/version.sh
|
|
105
|
-
NAMI_SDK_VERSION = "3.4.
|
|
105
|
+
NAMI_SDK_VERSION = "3.4.13",
|
|
106
106
|
// full package version including dev suffix — stamped by scripts/version.sh
|
|
107
|
-
NAMI_SDK_PACKAGE_VERSION = "3.4.
|
|
107
|
+
NAMI_SDK_PACKAGE_VERSION = "3.4.13-dev.202610261518",
|
|
108
108
|
// environments
|
|
109
109
|
PRODUCTION = "production", DEVELOPMENT = "development",
|
|
110
110
|
// error messages
|
|
@@ -128,7 +128,9 @@ CAMPAIGN_CACHE_TTL_PREFIX = "campaignCacheTTL=",
|
|
|
128
128
|
// and the builder preview can evaluate time conditions at any moment (NAM-4635).
|
|
129
129
|
TIME_OVERRIDE_PREFIX = "timeOverride=",
|
|
130
130
|
// Page condition values that resolve against the per-presentation time snapshot (NAM-4635).
|
|
131
|
-
SYSTEM_TIME_TOKEN_PREFIX = "${system.time.",
|
|
131
|
+
SYSTEM_TIME_TOKEN_PREFIX = "${system.time.",
|
|
132
|
+
// Flow branch-condition identifiers that the condition evaluator handles itself, read live (NAM-5226).
|
|
133
|
+
SYSTEM_TIME_FILTER_PREFIX = "System.time.", EXTENDED_PLATFORM = "extended-platform", EXTENDED_PLATFORM_VERSION = "extended-platform-version", API_MAX_CALLS_LIMIT = 2, API_RETRY_DELAY_SEC = 2, API_TIMEOUT_LIMIT = 20000, DEVICE_API_TIMEOUT_LIMIT = 2000,
|
|
132
134
|
// Platform-config attempts when no initial config was supplied (Android's
|
|
133
135
|
// CONFIG_MAX_ATTEMPTS; Apple's retry(maxAttempts: 3)).
|
|
134
136
|
CONFIG_MAX_ATTEMPTS = 3,
|
|
@@ -61327,6 +61329,10 @@ const isSystemTimeAssertion = (assertion) => typeof assertion.value === "string"
|
|
|
61327
61329
|
const parseInstant = (value) => {
|
|
61328
61330
|
if (typeof value !== "string" || !INSTANT.test(value))
|
|
61329
61331
|
return null;
|
|
61332
|
+
// `Date` rolls an impossible day over (2026-02-30 → March 2) instead of rejecting it.
|
|
61333
|
+
const [year, month, day] = value.slice(0, 10).split("-").map(Number);
|
|
61334
|
+
if (day > new Date(Date.UTC(year, month, 0)).getUTCDate())
|
|
61335
|
+
return null;
|
|
61330
61336
|
const date = new Date(value);
|
|
61331
61337
|
return Number.isNaN(date.getTime()) ? null : date;
|
|
61332
61338
|
};
|
|
@@ -61366,16 +61372,33 @@ const parseDay = (expected) => {
|
|
|
61366
61372
|
const zoned = splitZoned(expected);
|
|
61367
61373
|
return zoned && DAYS.includes(zoned.value) ? { day: zoned.value, zone: zoned.zone } : null;
|
|
61368
61374
|
};
|
|
61375
|
+
/** `H:mm@zone` / `HH:mm@zone` as minutes since local midnight plus the zone, or `null`. */
|
|
61376
|
+
const parseZonedTime = (expected) => {
|
|
61377
|
+
const zoned = splitZoned(expected);
|
|
61378
|
+
const match = zoned && TIME_OF_DAY.exec(zoned.value);
|
|
61379
|
+
return zoned && match ? { minutes: Number(match[1]) * 60 + Number(match[2]), zone: zoned.zone } : null;
|
|
61380
|
+
};
|
|
61381
|
+
/**
|
|
61382
|
+
* Every element parsed by `parse`, or `null` when `values` is not a non-empty array or any element
|
|
61383
|
+
* is invalid — a valid match elsewhere in the list never rescues an invalid element.
|
|
61384
|
+
*/
|
|
61385
|
+
const parseAll = (values, parse) => {
|
|
61386
|
+
if (!Array.isArray(values) || values.length === 0)
|
|
61387
|
+
return null;
|
|
61388
|
+
const parsed = [];
|
|
61389
|
+
for (const value of values) {
|
|
61390
|
+
const item = typeof value === "string" ? parse(value) : null;
|
|
61391
|
+
if (item === null)
|
|
61392
|
+
return null;
|
|
61393
|
+
parsed.push(item);
|
|
61394
|
+
}
|
|
61395
|
+
return parsed;
|
|
61396
|
+
};
|
|
61369
61397
|
const evaluateDayOfWeek = (operator, expected, now) => {
|
|
61370
61398
|
const isDay = ({ day, zone }) => projectInZone(now, zone)?.dayOfWeek === day;
|
|
61371
61399
|
if (operator === "in") {
|
|
61372
|
-
|
|
61373
|
-
|
|
61374
|
-
const days = expected.map(parseDay);
|
|
61375
|
-
// Any invalid element invalidates the whole assertion, even when another element matches.
|
|
61376
|
-
if (days.some((day) => day === null))
|
|
61377
|
-
return false;
|
|
61378
|
-
return days.some((day) => isDay(day));
|
|
61400
|
+
const days = parseAll(expected, parseDay);
|
|
61401
|
+
return days !== null && days.some(isDay);
|
|
61379
61402
|
}
|
|
61380
61403
|
if (operator !== "equals" && operator !== "notEquals")
|
|
61381
61404
|
return false;
|
|
@@ -61390,14 +61413,11 @@ const evaluateDayOfWeek = (operator, expected, now) => {
|
|
|
61390
61413
|
const evaluateTimeOfDay = (operator, expected, now) => {
|
|
61391
61414
|
if (!isOrderingOperator(operator))
|
|
61392
61415
|
return false;
|
|
61393
|
-
const
|
|
61394
|
-
const
|
|
61395
|
-
if (!
|
|
61416
|
+
const time = parseZonedTime(expected);
|
|
61417
|
+
const projected = time && projectInZone(now, time.zone);
|
|
61418
|
+
if (!time || !projected)
|
|
61396
61419
|
return false;
|
|
61397
|
-
|
|
61398
|
-
if (!projected)
|
|
61399
|
-
return false;
|
|
61400
|
-
return ORDERING[operator](projected.minutes, Number(match[1]) * 60 + Number(match[2]));
|
|
61420
|
+
return ORDERING[operator](projected.minutes, time.minutes);
|
|
61401
61421
|
};
|
|
61402
61422
|
const evaluateNow = (operator, expected, now) => {
|
|
61403
61423
|
if (!isOrderingOperator(operator))
|
|
@@ -61427,11 +61447,66 @@ const evaluateSystemTimeAssertion = (assertion, now) => {
|
|
|
61427
61447
|
return false;
|
|
61428
61448
|
}
|
|
61429
61449
|
};
|
|
61450
|
+
// Flow branch conditions use the engine's operator names; they compare the same way as Pages'.
|
|
61451
|
+
const FLOW_ORDERING = {
|
|
61452
|
+
equals: ORDERING.equals,
|
|
61453
|
+
greater_than: ORDERING.gt,
|
|
61454
|
+
greater_than_or_equal_to: ORDERING.gte,
|
|
61455
|
+
less_than: ORDERING.lt,
|
|
61456
|
+
less_than_or_equal_to: ORDERING.lte,
|
|
61457
|
+
};
|
|
61458
|
+
const flowComparison = (operator) => Object.prototype.hasOwnProperty.call(FLOW_ORDERING, operator) ? FLOW_ORDERING[operator] : null;
|
|
61459
|
+
/** True when a Flow filter identifier is `System.time.<leaf>` (any leaf; unknown leaves evaluate `false`). */
|
|
61460
|
+
const isSystemTimeFilter = (identifier) => typeof identifier === "string" && identifier.startsWith(SYSTEM_TIME_FILTER_PREFIX);
|
|
61461
|
+
/**
|
|
61462
|
+
* Evaluates a Flow branch filter on `System.time.*` (the "Flow branch conditions" section of
|
|
61463
|
+
* `shared/time_conditions/README.md`, verified against `flow_vectors.json`). Every value is
|
|
61464
|
+
* validated before anything is compared, so an invalid value is `false` for every operator,
|
|
61465
|
+
* `not_equals` included. Several values match when any one does; `not_equals` when none does.
|
|
61466
|
+
*/
|
|
61467
|
+
const evaluateSystemTimeFilter = (filter, now) => {
|
|
61468
|
+
if (!isSystemTimeFilter(filter.identifier) || Number.isNaN(now.getTime()))
|
|
61469
|
+
return false;
|
|
61470
|
+
switch (filter.identifier.slice(SYSTEM_TIME_FILTER_PREFIX.length)) {
|
|
61471
|
+
case "dayOfWeek": {
|
|
61472
|
+
if (filter.operator !== "equals" && filter.operator !== "not_equals")
|
|
61473
|
+
return false;
|
|
61474
|
+
const days = parseAll(filter.values, parseDay);
|
|
61475
|
+
if (!days)
|
|
61476
|
+
return false;
|
|
61477
|
+
const projected = days.map(({ zone }) => projectInZone(now, zone));
|
|
61478
|
+
if (projected.some((p) => p === null))
|
|
61479
|
+
return false;
|
|
61480
|
+
const matched = days.some(({ day }, i) => projected[i].dayOfWeek === day);
|
|
61481
|
+
return filter.operator === "equals" ? matched : !matched;
|
|
61482
|
+
}
|
|
61483
|
+
case "timeOfDay": {
|
|
61484
|
+
const compare = flowComparison(filter.operator);
|
|
61485
|
+
const times = compare ? parseAll(filter.values, parseZonedTime) : null;
|
|
61486
|
+
if (!compare || !times)
|
|
61487
|
+
return false;
|
|
61488
|
+
const projected = times.map(({ zone }) => projectInZone(now, zone));
|
|
61489
|
+
if (projected.some((p) => p === null))
|
|
61490
|
+
return false;
|
|
61491
|
+
return times.some(({ minutes }, i) => compare(projected[i].minutes, minutes));
|
|
61492
|
+
}
|
|
61493
|
+
case "now": {
|
|
61494
|
+
const compare = flowComparison(filter.operator);
|
|
61495
|
+
const instants = compare ? parseAll(filter.values, parseInstant) : null;
|
|
61496
|
+
if (!compare || !instants)
|
|
61497
|
+
return false;
|
|
61498
|
+
return instants.some((instant) => compare(now.getTime(), instant.getTime()));
|
|
61499
|
+
}
|
|
61500
|
+
default:
|
|
61501
|
+
return false;
|
|
61502
|
+
}
|
|
61503
|
+
};
|
|
61430
61504
|
/** Parses a `timeOverride=<ISO-8601 with offset>` namiCommand; `null` when it is not a valid one. */
|
|
61431
61505
|
const parseTimeOverride = (command) => command.startsWith(TIME_OVERRIDE_PREFIX) ? parseInstant(command.slice(TIME_OVERRIDE_PREFIX.length)) : null;
|
|
61432
61506
|
/**
|
|
61433
61507
|
* The instant to snapshot for a Page or flow-screen presentation: the `timeOverride=` namiCommand
|
|
61434
|
-
* when present and valid, otherwise the device clock. Call it once per presentation.
|
|
61508
|
+
* when present and valid, otherwise the device clock. Call it once per presentation. Flow branch
|
|
61509
|
+
* conditions call it once per condition block instead, so they see the time live.
|
|
61435
61510
|
*/
|
|
61436
61511
|
const getSystemTimeNow = () => {
|
|
61437
61512
|
const command = storageService
|
|
@@ -63127,6 +63202,15 @@ function toComparableNumber(value) {
|
|
|
63127
63202
|
}
|
|
63128
63203
|
return null;
|
|
63129
63204
|
}
|
|
63205
|
+
/**
|
|
63206
|
+
* The instant for one condition block: read on first use, then shared by every filter in the
|
|
63207
|
+
* block, so ANDed `System.time` filters see the same moment. Each block reads the clock afresh —
|
|
63208
|
+
* Flow branch conditions are live, never a snapshot from flow start (NAM-5226).
|
|
63209
|
+
*/
|
|
63210
|
+
function blockClock() {
|
|
63211
|
+
let now;
|
|
63212
|
+
return () => (now ??= getSystemTimeNow());
|
|
63213
|
+
}
|
|
63130
63214
|
class NamiConditionEvaluator {
|
|
63131
63215
|
constructor() {
|
|
63132
63216
|
this.resolvers = new Map();
|
|
@@ -63149,7 +63233,8 @@ class NamiConditionEvaluator {
|
|
|
63149
63233
|
if (filters.length === 0) {
|
|
63150
63234
|
return true;
|
|
63151
63235
|
}
|
|
63152
|
-
const
|
|
63236
|
+
const now = blockClock();
|
|
63237
|
+
const results = filters.map(filter => this.evaluateFilter(filter, now));
|
|
63153
63238
|
switch (conditions.operator) {
|
|
63154
63239
|
case LogicalOperator.AND:
|
|
63155
63240
|
return results.every(result => result);
|
|
@@ -63168,17 +63253,18 @@ class NamiConditionEvaluator {
|
|
|
63168
63253
|
if (filters.length === 0) {
|
|
63169
63254
|
return true;
|
|
63170
63255
|
}
|
|
63256
|
+
const now = blockClock();
|
|
63171
63257
|
switch (conditions.operator) {
|
|
63172
63258
|
case LogicalOperator.AND:
|
|
63173
63259
|
for (const filter of filters) {
|
|
63174
|
-
if (!this.evaluateFilter(filter)) {
|
|
63260
|
+
if (!this.evaluateFilter(filter, now)) {
|
|
63175
63261
|
return false;
|
|
63176
63262
|
}
|
|
63177
63263
|
}
|
|
63178
63264
|
return true;
|
|
63179
63265
|
case LogicalOperator.OR:
|
|
63180
63266
|
for (const filter of filters) {
|
|
63181
|
-
if (this.evaluateFilter(filter)) {
|
|
63267
|
+
if (this.evaluateFilter(filter, now)) {
|
|
63182
63268
|
return true;
|
|
63183
63269
|
}
|
|
63184
63270
|
}
|
|
@@ -63186,14 +63272,19 @@ class NamiConditionEvaluator {
|
|
|
63186
63272
|
case LogicalOperator.NONE:
|
|
63187
63273
|
default:
|
|
63188
63274
|
for (const filter of filters) {
|
|
63189
|
-
if (!this.evaluateFilter(filter)) {
|
|
63275
|
+
if (!this.evaluateFilter(filter, now)) {
|
|
63190
63276
|
return false;
|
|
63191
63277
|
}
|
|
63192
63278
|
}
|
|
63193
63279
|
return true;
|
|
63194
63280
|
}
|
|
63195
63281
|
}
|
|
63196
|
-
evaluateFilter(filter) {
|
|
63282
|
+
evaluateFilter(filter, now = blockClock()) {
|
|
63283
|
+
// System.time.* is evaluated here, ahead of the resolvers and the unresolved-value rule below,
|
|
63284
|
+
// which would otherwise make not_equals true for a field no resolver knows.
|
|
63285
|
+
if (isSystemTimeFilter(filter.identifier)) {
|
|
63286
|
+
return evaluateSystemTimeFilter(filter, now());
|
|
63287
|
+
}
|
|
63197
63288
|
const resolvedValue = this.resolve(filter.identifier);
|
|
63198
63289
|
if (Nami.instance.maxLogging) {
|
|
63199
63290
|
logger.debug(`[NamiConditionEvaluator] resolve(${filter.identifier}) → ${JSON.stringify(resolvedValue)} (type: ${typeof resolvedValue})`);
|
|
@@ -66901,4 +66992,4 @@ var internal = /*#__PURE__*/Object.freeze({
|
|
|
66901
66992
|
NamiPurchaseManager: NamiPurchaseManager
|
|
66902
66993
|
});
|
|
66903
66994
|
|
|
66904
|
-
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_TRAFFIC_OBSERVER, 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_CACHE_TTL_PREFIX, CAMPAIGN_NOT_AVAILABLE, CONFIG_API_TIMEOUT_LIMIT, CONFIG_MAX_ATTEMPTS, CUSTOMER_ATTRIBUTES_KEY_PREFIX, CUSTOMER_JOURNEY_STATE_CHANGED, CUSTOM_HOST_PREFIX, CampaignNotAvailableError, CampaignRuleConversionEventType, CampaignRuleRepository, Capabilities, ClientError, ConfigRepository, ConflictError, CustomerJourneyRepository, DEFAULT_JOURNEY_SETTINGS, 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$1 as NamiCampaignManager, NamiCampaignRuleType, NamiConditionEvaluator, NamiCustomerManager$1 as NamiCustomerManager, NamiEntitlementManager$1 as NamiEntitlementManager, NamiEventEmitter, NamiFlow, NamiFlowActionFunction, NamiFlowManager$1 as NamiFlowManager, NamiFlowStepType, NamiHandoffTag, NamiPaywallAction, NamiPaywallManager$1 as NamiPaywallManager, PaywallManagerEvents as NamiPaywallManagerEvents, NamiPermissionOutcome, NamiPurchaseManager$1 as NamiPurchaseManager, NamiRefs, NamiReservedActions, NotFoundError, PAYWALL_ACTION_EVENT, PLATFORM_ID_REQUIRED, PRODUCTION, PaywallManagerEvents, PaywallRepository, PaywallState, PlacementLabelResolver, PlatformIDRequiredError, ProductRepository, RECONFIG_SUCCESS, RESUME_THROTTLE_MS, RetryLimitExceededError, SDKNotInitializedError, SDK_NOT_INITIALIZED, SERVER_NAMI_ENTITLEMENTS, SESSION_REQUIRED, SHOULD_SHOW_LOADING_INDICATOR, SIMULATE_CONFIG_FETCH_FAILURE, SIMULATE_PAYWALL_FETCH_FAILURE, SKU_TEXT_REGEX, SMART_TEXT_PATTERN, STARTUP_TELEMETRY, STATUS_BAD_REQUEST, STATUS_CONFLICT, STATUS_INTERNAL_SERVER_ERROR, STATUS_NOT_FOUND, STATUS_SUCCESS, SYSTEM_TIME_TOKEN_PREFIX, SessionService, SimpleEventTarget, StorageService, TIME_OVERRIDE_PREFIX, TRANSPORT_FAILURE_STATUS, 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, didReceiveResponse, empty, evaluateSystemTimeAssertion, evaluateSystemTimeCondition, extractStandardPricingPhases, formatDate, formattedPrice, generateUUID, getApiCampaigns, getApiPaywalls, getBaseUrl, getBillingPeriodNumber, getCurrencyFormat, getDeviceData, getDeviceFormFactor, getDeviceScaleFactor, getEffectiveWebStyle, getEntitlementRefIdsForSku, getExtendedClientInfo, getFreeTrialPeriod, getInitialCampaigns, getInitialPaywalls, getJourneySettings, getPaywall, getPaywallDataFromLabel, getPercentagePriceDifference, getPeriodNumberInDays, getPeriodNumberInWeeks, getPlatformAdapters, getPriceDifference, getPricePerMonth, getProductDetail, getPurchaseAdapter, getReferenceSku, getSkuProductDetailKeys, getSkuSmartTextValue, getSlideSmartTextValue, getStandardBillingPeriod, getSystemTimeNow, getTranslate, getUrlParams, handleErrors, hasAllPaywalls, hasCapability, hasPurchaseManagement, initialState, invokeHandler, isAnonymousMode, isInitialConfigCompressed, isNamiFlowCampaign, isSubscription, isSystemTimeAssertion, isValidISODate, isValidUrl, logger, mapAnonymousCampaigns, namiBuySKU, normalizeLaunchContext, parseTimeOverride, parseToSemver, postConversion, productDetail, registerAPITrafficObserver, registerPlatformAdapters, registerPurchaseAdapter, resolveLoopSource, selectSegment, setActiveNamiEntitlements, shouldValidateProductGroups, skuItems, skuMapFromEntitlements, storageService, toDouble, toNamiEntitlements, toNamiSKU, tryParseB64Gzip, tryParseJson, updateRelatedSKUsForNamiEntitlement, uuidFromSplitPosition, validateForm, validateMinSDKVersion, validateTextInput };
|
|
66995
|
+
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_TRAFFIC_OBSERVER, 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_CACHE_TTL_PREFIX, CAMPAIGN_NOT_AVAILABLE, CONFIG_API_TIMEOUT_LIMIT, CONFIG_MAX_ATTEMPTS, CUSTOMER_ATTRIBUTES_KEY_PREFIX, CUSTOMER_JOURNEY_STATE_CHANGED, CUSTOM_HOST_PREFIX, CampaignNotAvailableError, CampaignRuleConversionEventType, CampaignRuleRepository, Capabilities, ClientError, ConfigRepository, ConflictError, CustomerJourneyRepository, DEFAULT_JOURNEY_SETTINGS, 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$1 as NamiCampaignManager, NamiCampaignRuleType, NamiConditionEvaluator, NamiCustomerManager$1 as NamiCustomerManager, NamiEntitlementManager$1 as NamiEntitlementManager, NamiEventEmitter, NamiFlow, NamiFlowActionFunction, NamiFlowManager$1 as NamiFlowManager, NamiFlowStepType, NamiHandoffTag, NamiPaywallAction, NamiPaywallManager$1 as NamiPaywallManager, PaywallManagerEvents as NamiPaywallManagerEvents, NamiPermissionOutcome, NamiPurchaseManager$1 as NamiPurchaseManager, NamiRefs, NamiReservedActions, NotFoundError, PAYWALL_ACTION_EVENT, PLATFORM_ID_REQUIRED, PRODUCTION, PaywallManagerEvents, PaywallRepository, PaywallState, PlacementLabelResolver, PlatformIDRequiredError, ProductRepository, RECONFIG_SUCCESS, RESUME_THROTTLE_MS, RetryLimitExceededError, SDKNotInitializedError, SDK_NOT_INITIALIZED, SERVER_NAMI_ENTITLEMENTS, SESSION_REQUIRED, SHOULD_SHOW_LOADING_INDICATOR, SIMULATE_CONFIG_FETCH_FAILURE, SIMULATE_PAYWALL_FETCH_FAILURE, SKU_TEXT_REGEX, SMART_TEXT_PATTERN, STARTUP_TELEMETRY, STATUS_BAD_REQUEST, STATUS_CONFLICT, STATUS_INTERNAL_SERVER_ERROR, STATUS_NOT_FOUND, STATUS_SUCCESS, SYSTEM_TIME_FILTER_PREFIX, SYSTEM_TIME_TOKEN_PREFIX, SessionService, SimpleEventTarget, StorageService, TIME_OVERRIDE_PREFIX, TRANSPORT_FAILURE_STATUS, 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, didReceiveResponse, empty, evaluateSystemTimeAssertion, evaluateSystemTimeCondition, extractStandardPricingPhases, formatDate, formattedPrice, generateUUID, getApiCampaigns, getApiPaywalls, getBaseUrl, getBillingPeriodNumber, getCurrencyFormat, getDeviceData, getDeviceFormFactor, getDeviceScaleFactor, getEffectiveWebStyle, getEntitlementRefIdsForSku, getExtendedClientInfo, getFreeTrialPeriod, getInitialCampaigns, getInitialPaywalls, getJourneySettings, getPaywall, getPaywallDataFromLabel, getPercentagePriceDifference, getPeriodNumberInDays, getPeriodNumberInWeeks, getPlatformAdapters, getPriceDifference, getPricePerMonth, getProductDetail, getPurchaseAdapter, getReferenceSku, getSkuProductDetailKeys, getSkuSmartTextValue, getSlideSmartTextValue, getStandardBillingPeriod, getSystemTimeNow, getTranslate, getUrlParams, handleErrors, hasAllPaywalls, hasCapability, hasPurchaseManagement, initialState, invokeHandler, isAnonymousMode, isInitialConfigCompressed, isNamiFlowCampaign, isSubscription, isSystemTimeAssertion, isValidISODate, isValidUrl, logger, mapAnonymousCampaigns, namiBuySKU, normalizeLaunchContext, parseTimeOverride, parseToSemver, postConversion, productDetail, registerAPITrafficObserver, registerPlatformAdapters, registerPurchaseAdapter, resolveLoopSource, selectSegment, setActiveNamiEntitlements, shouldValidateProductGroups, skuItems, skuMapFromEntitlements, storageService, toDouble, toNamiEntitlements, toNamiSKU, tryParseB64Gzip, tryParseJson, updateRelatedSKUsForNamiEntitlement, uuidFromSplitPosition, validateForm, validateMinSDKVersion, validateTextInput };
|
package/package.json
CHANGED