@namiml/sdk-core 3.4.4-dev.202607012039 → 3.4.4-dev.202607022250

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -98,7 +98,7 @@ const {
98
98
  // version — stamped by scripts/version.sh
99
99
  NAMI_SDK_VERSION: exports.NAMI_SDK_VERSION = "3.4.4",
100
100
  // full package version including dev suffix — stamped by scripts/version.sh
101
- NAMI_SDK_PACKAGE_VERSION: exports.NAMI_SDK_PACKAGE_VERSION = "3.4.4-dev.202607012039",
101
+ NAMI_SDK_PACKAGE_VERSION: exports.NAMI_SDK_PACKAGE_VERSION = "3.4.4-dev.202607022250",
102
102
  // environments
103
103
  PRODUCTION: exports.PRODUCTION = "production", DEVELOPMENT: exports.DEVELOPMENT = "development",
104
104
  // error messages
@@ -57316,12 +57316,24 @@ class CampaignRuleRepository {
57316
57316
  return campaignRules;
57317
57317
  }
57318
57318
  finalizeCampaignRules(campaignRules, paywalls) {
57319
+ // NAM-2457: a server flow rule is kept only when BOTH assets are satisfied —
57320
+ // flow.object hydrated (from flow.url, or inline) AND every screen resolvable
57321
+ // against the fetched paywalls ∪ bundled initial-config paywalls. Dropping the
57322
+ // broken copy lets isCampaignAvailable and getPaywallDataFromLabel fall
57323
+ // through to the initial-config copy of the same placement.
57324
+ const resolvableIds = new Set([
57325
+ ...paywalls.map((p) => p.id),
57326
+ ...getInitialPaywalls().map((p) => p.id),
57327
+ ]);
57319
57328
  const validated = campaignRules?.filter((cRule) => {
57320
57329
  if (cRule.paywall) {
57321
57330
  return paywalls.find((p) => p.id == cRule.paywall);
57322
57331
  }
57323
57332
  else if (cRule.flow) {
57324
- return true;
57333
+ if (!cRule.flow.object)
57334
+ return false;
57335
+ const screens = cRule.flow.object.screens ?? [];
57336
+ return screens.every((id) => resolvableIds.has(id));
57325
57337
  }
57326
57338
  return false;
57327
57339
  });
@@ -61437,13 +61449,11 @@ class NamiRefs {
61437
61449
  .filter((c) => c.flow?.url && !c.flow.object)
61438
61450
  .map(async (c) => {
61439
61451
  try {
61440
- const res = await fetch(c.flow.url, { cache: 'no-cache' });
61441
- if (res.ok) {
61442
- c.flow.object = await res.json();
61443
- }
61444
- else {
61445
- logger.warn(`Failed to fetch flow object from ${c.flow.url}: ${res.status}`);
61446
- }
61452
+ // Same bounded retry policy as page fetches (NAM-2457); on
61453
+ // exhaustion flow.object stays unset and finalizeCampaignRules
61454
+ // drops the rule so the initial-config copy serves the placement.
61455
+ const result = await fetchWithCdnRetry(c.flow.url);
61456
+ c.flow.object = result.data;
61447
61457
  }
61448
61458
  catch (err) {
61449
61459
  logger.warn(`Error fetching flow object from ${c.flow.url}: ${err}`);
package/dist/index.d.ts CHANGED
@@ -1483,6 +1483,31 @@ type TTimelineRail = {
1483
1483
  dotBorderColor?: string;
1484
1484
  conditionAttributes?: TConditionalComponent[];
1485
1485
  };
1486
+ /**
1487
+ * Targets which group a `groupStart`/`groupEnd` slot attaches to. A group qualifies when at
1488
+ * least one of its `loopSourceConditions`-surviving items passes every `itemConditions`
1489
+ * assertion (block context); `ordinal` then picks among qualifying groups in first-appearance
1490
+ * order. An empty selector qualifies any rendered group.
1491
+ */
1492
+ type TSlotGroupSelector = {
1493
+ itemConditions?: TTestObject[];
1494
+ ordinal?: "first" | "last";
1495
+ };
1496
+ /**
1497
+ * A conditionally-rendered, self-contained component injected into a content feed at a declared
1498
+ * position, after the data pipeline (filter → group → cap). Carries no backing loop item — the
1499
+ * `template` binds only non-feed context. Unrecognized `position`/`ordinal` values are skipped
1500
+ * at render time (tolerant decode).
1501
+ */
1502
+ type TSlot = {
1503
+ id: string;
1504
+ position: "groupStart" | "groupEnd" | "listStart" | "listEnd";
1505
+ /** Required for groupStart/groupEnd; ignored for list positions. */
1506
+ group?: TSlotGroupSelector;
1507
+ /** Visibility gate evaluated once with non-block context. Empty ⇒ always visible. */
1508
+ conditions?: TTestObject[];
1509
+ template: TComponent;
1510
+ };
1486
1511
  type TResponsiveGrid = TBaseComponent & {
1487
1512
  component: "responsiveGrid";
1488
1513
  components: any;
@@ -1496,6 +1521,8 @@ type TResponsiveGrid = TBaseComponent & {
1496
1521
  max?: number;
1497
1522
  /** Grouped lists only (groupBy present): render at most the first N eligible items per group. Ignored when groupBy is absent. */
1498
1523
  groupMax?: number;
1524
+ /** Conditionally-rendered components injected after the data pipeline. See {@link TSlot}. */
1525
+ slots?: TSlot[];
1499
1526
  };
1500
1527
  type TRepeatingGrid = TBaseComponent & {
1501
1528
  component: "repeatingGrid";
@@ -1513,6 +1540,8 @@ type TRepeatingGrid = TBaseComponent & {
1513
1540
  max?: number;
1514
1541
  /** Grouped lists only (groupBy present): render at most the first N eligible items per group. Ignored when groupBy is absent. */
1515
1542
  groupMax?: number;
1543
+ /** Conditionally-rendered components injected after the data pipeline. See {@link TSlot}. */
1544
+ slots?: TSlot[];
1516
1545
  };
1517
1546
  type TToggleSwitch = TBaseComponent & {
1518
1547
  component: 'toggleSwitch';
@@ -3917,4 +3946,4 @@ declare namespace internal {
3917
3946
  }
3918
3947
 
3919
3948
  export { ALREADY_CONFIGURED, ANONYMOUS_MODE, ANONYMOUS_MODE_ALREADY_OFF, ANONYMOUS_MODE_ALREADY_ON, ANONYMOUS_MODE_LOGIN_NOT_ALLOWED, ANONYMOUS_UUID, APIError, API_ACTIVE_ENTITLEMENTS, API_CAMPAIGN_RULES, API_CAMPAIGN_SESSION_TIMESTAMP, API_CONFIG, API_MAX_CALLS_LIMIT, API_PAYWALLS, API_PRODUCTS, API_RETRY_DELAY_SEC, API_TIMEOUT_LIMIT, API_VERSION, AUTH_DEVICE, AVAILABLE_ACTIVE_ENTITLEMENTS_CHANGED, AVAILABLE_CAMPAIGNS_CHANGED, AccountStateAction, AnonymousCDPError, AnonymousLoginError, AnonymousModeAlreadyOffError, AnonymousModeAlreadyOnError, BASE_STAGING_URL, BASE_URL, BASE_URL_PATH, BadRequestError, BasicNamiFlow, BorderMap, BorderSideMap, CAMPAIGN_NOT_AVAILABLE, CUSTOMER_ATTRIBUTES_KEY_PREFIX, CUSTOMER_JOURNEY_STATE_CHANGED, CUSTOM_HOST_PREFIX, CampaignNotAvailableError, CampaignRuleConversionEventType, CampaignRuleRepository, Capabilities, ClientError, ConfigRepository, ConflictError, CustomerJourneyRepository, DEVELOPMENT, DEVICE_API_TIMEOUT_LIMIT, DEVICE_ID_NOT_SET, DEVICE_ID_REQUIRED, DISABLE_ASYNC_LOGIN_LOGOUT, DeviceIDRequiredError, DeviceRepository, EXTENDED_CLIENT_INFO_DELIMITER, EXTENDED_CLIENT_INFO_PREFIX, EXTENDED_PLATFORM, EXTENDED_PLATFORM_VERSION, EXTERNAL_ID_REQUIRED, EntitlementRepository, EntitlementUtils, ExternalIDRequiredError, FLOW_SCREENS_NOT_AVAILABLE, FlowScreensNotAvailableError, HTML_REGEX, INITIAL_APP_CONFIG, INITIAL_CAMPAIGN_RULES, INITIAL_PAYWALLS, INITIAL_PRODUCTS, INITIAL_SESSION_COUNTER_VALUE, INITIAL_SUCCESS, InternalServerError, KEY_SESSION_COUNTER, LIQUID_VARIABLE_REGEX, LOCAL_NAMI_ENTITLEMENTS, LOG_HTTP_REQUESTS, LOG_HTTP_TRAFFIC, LaunchCampaignError, LaunchContextResolver, LogLevel, NAMI_CONFIGURATION, NAMI_CUSTOMER_JOURNEY_STATE, NAMI_LANGUAGE_CODE, NAMI_LAST_IMPRESSION_ID, NAMI_LAUNCH_ID, NAMI_PROFILE, NAMI_PURCHASE_CHANNEL, NAMI_PURCHASE_IMPRESSION_ID, NAMI_SDK_PACKAGE_VERSION, NAMI_SDK_VERSION, NAMI_SESSION_ID, NAMI_STORAGE_KEYS, Nami, NamiAPI, NamiAnimationType, NamiCampaignManager$2 as NamiCampaignManager, NamiCampaignRuleType, NamiConditionEvaluator, NamiCustomerManager$2 as NamiCustomerManager, NamiEntitlementManager$2 as NamiEntitlementManager, NamiEventEmitter, NamiFlow, NamiFlowActionFunction, NamiFlowManager$1 as NamiFlowManager, NamiFlowStepType, 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, RetryLimitExceededError, SDKNotInitializedError, SDK_NOT_INITIALIZED, SERVER_NAMI_ENTITLEMENTS, SESSION_REQUIRED, SHOULD_SHOW_LOADING_INDICATOR, SKU_TEXT_REGEX, SMART_TEXT_PATTERN, STARTUP_TELEMETRY, STATUS_BAD_REQUEST, STATUS_CONFLICT, STATUS_INTERNAL_SERVER_ERROR, STATUS_NOT_FOUND, STATUS_SUCCESS, SessionService, SimpleEventTarget, StorageService, UNABLE_TO_UPDATE_CDP_ID, USE_STAGING_API, VALIDATE_PRODUCT_GROUPS, VAR_REGEX, NamiProfileManager$1 as _NamiProfileManager, internal as _internal, activateEntitlementByPurchase, activeEntitlements, aggregateScreenreaderText, allCampaigns, allPaywalls, applyEntitlementActivation, audienceSplitPosition, bestUrlCampaignMatch, bigintToUuid, checkAnySkuHasPromoOffer, checkAnySkuHasTrialOffer, convertISO8601PeriodToText, convertLocale, convertOfferToPricingPhase, createNamiEntitlements, currentSku, empty, extractStandardPricingPhases, formatDate, formattedPrice, generateUUID, getApiCampaigns, getApiPaywalls, getBaseUrl, getBillingPeriodNumber, getCurrencyFormat, getDeviceData, getDeviceFormFactor, getDeviceScaleFactor, getEffectiveWebStyle, getEntitlementRefIdsForSku, getExtendedClientInfo, getFreeTrialPeriod, getInitialCampaigns, getInitialPaywalls, getPaywall, getPaywallDataFromLabel, getPercentagePriceDifference, getPeriodNumberInDays, getPeriodNumberInWeeks, getPlatformAdapters, getPriceDifference, getPricePerMonth, getProductDetail, getPurchaseAdapter, getReferenceSku, getSkuProductDetailKeys, getSkuSmartTextValue, getSlideSmartTextValue, getStandardBillingPeriod, getTranslate, getUrlParams, handleErrors, hasAllPaywalls, hasCapability, hasPurchaseManagement, initialState, invokeHandler, isAnonymousMode, isInitialConfigCompressed, isNamiFlowCampaign, isSubscription, isValidISODate, isValidUrl, logger, mapAnonymousCampaigns, namiBuySKU, normalizeLaunchContext, parseToSemver, postConversion, productDetail, registerPlatformAdapters, registerPurchaseAdapter, resolveLoopSource, selectSegment, setActiveNamiEntitlements, shouldValidateProductGroups, skuItems, skuMapFromEntitlements, storageService, toDouble, toNamiEntitlements, toNamiSKU, tryParseB64Gzip, tryParseJson, updateRelatedSKUsForNamiEntitlement, uuidFromSplitPosition, validateForm, validateMinSDKVersion, validateTextInput };
3920
- 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, LoginResponse, 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, TSpacerComponent, TStack, TSvgImageComponent, TSymbolComponent, TTestObject, TTextComponent, TTextInputComponent, TTextInputType, TTextLikeComponent, TTextListComponent, TTimelineRail, TToggleButtonComponent, TToggleSwitch, TVariablePattern, TVideoComponent, TVolumeButton, TimerState, TransactionRequest, UserAction, UserActionParameters, Wave, WaveSpec };
3949
+ 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, LoginResponse, 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
@@ -96,7 +96,7 @@ const {
96
96
  // version — stamped by scripts/version.sh
97
97
  NAMI_SDK_VERSION = "3.4.4",
98
98
  // full package version including dev suffix — stamped by scripts/version.sh
99
- NAMI_SDK_PACKAGE_VERSION = "3.4.4-dev.202607012039",
99
+ NAMI_SDK_PACKAGE_VERSION = "3.4.4-dev.202607022250",
100
100
  // environments
101
101
  PRODUCTION = "production", DEVELOPMENT = "development",
102
102
  // error messages
@@ -57314,12 +57314,24 @@ class CampaignRuleRepository {
57314
57314
  return campaignRules;
57315
57315
  }
57316
57316
  finalizeCampaignRules(campaignRules, paywalls) {
57317
+ // NAM-2457: a server flow rule is kept only when BOTH assets are satisfied —
57318
+ // flow.object hydrated (from flow.url, or inline) AND every screen resolvable
57319
+ // against the fetched paywalls ∪ bundled initial-config paywalls. Dropping the
57320
+ // broken copy lets isCampaignAvailable and getPaywallDataFromLabel fall
57321
+ // through to the initial-config copy of the same placement.
57322
+ const resolvableIds = new Set([
57323
+ ...paywalls.map((p) => p.id),
57324
+ ...getInitialPaywalls().map((p) => p.id),
57325
+ ]);
57317
57326
  const validated = campaignRules?.filter((cRule) => {
57318
57327
  if (cRule.paywall) {
57319
57328
  return paywalls.find((p) => p.id == cRule.paywall);
57320
57329
  }
57321
57330
  else if (cRule.flow) {
57322
- return true;
57331
+ if (!cRule.flow.object)
57332
+ return false;
57333
+ const screens = cRule.flow.object.screens ?? [];
57334
+ return screens.every((id) => resolvableIds.has(id));
57323
57335
  }
57324
57336
  return false;
57325
57337
  });
@@ -61435,13 +61447,11 @@ class NamiRefs {
61435
61447
  .filter((c) => c.flow?.url && !c.flow.object)
61436
61448
  .map(async (c) => {
61437
61449
  try {
61438
- const res = await fetch(c.flow.url, { cache: 'no-cache' });
61439
- if (res.ok) {
61440
- c.flow.object = await res.json();
61441
- }
61442
- else {
61443
- logger.warn(`Failed to fetch flow object from ${c.flow.url}: ${res.status}`);
61444
- }
61450
+ // Same bounded retry policy as page fetches (NAM-2457); on
61451
+ // exhaustion flow.object stays unset and finalizeCampaignRules
61452
+ // drops the rule so the initial-config copy serves the placement.
61453
+ const result = await fetchWithCdnRetry(c.flow.url);
61454
+ c.flow.object = result.data;
61445
61455
  }
61446
61456
  catch (err) {
61447
61457
  logger.warn(`Error fetching flow object from ${c.flow.url}: ${err}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@namiml/sdk-core",
3
- "version": "3.4.4-dev.202607012039",
3
+ "version": "3.4.4-dev.202607022250",
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",