@apps-in-toss/framework 2.9.2 → 2.10.0

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
@@ -1654,7 +1654,7 @@ var AppsInToss = {
1654
1654
  };
1655
1655
 
1656
1656
  // src/components/WebView.tsx
1657
- var import_native_modules18 = require("@apps-in-toss/native-modules");
1657
+ var import_native_modules19 = require("@apps-in-toss/native-modules");
1658
1658
  var appsInTossAsyncBridges = __toESM(require("@apps-in-toss/native-modules/async-bridges"), 1);
1659
1659
  var appsInTossConstantBridges = __toESM(require("@apps-in-toss/native-modules/constant-bridges"), 1);
1660
1660
  var appsInTossEventBridges = __toESM(require("@apps-in-toss/native-modules/event-bridges"), 1);
@@ -1794,7 +1794,7 @@ function convertIntentURL(url) {
1794
1794
  return `${scheme}://${url.hostname}${url.pathname}${url.search}`;
1795
1795
  }
1796
1796
 
1797
- // src/ads/fetchTossAd.ts
1797
+ // src/ads/fetchAppsInTossAd.ts
1798
1798
  var import_native_modules12 = require("@apps-in-toss/native-modules");
1799
1799
 
1800
1800
  // ../../../.yarn/cache/es-toolkit-npm-1.34.1-4cd6371dcb-aab6d07be3.zip/node_modules/es-toolkit/dist/function/noop.mjs
@@ -1822,14 +1822,50 @@ function generateSessionId() {
1822
1822
  // src/ads/constants.ts
1823
1823
  var sessionId = generateSessionId();
1824
1824
 
1825
+ // src/ads/fetchAppsInTossAd.ts
1826
+ var ANDROID_SUPPORTED_VERSION = "5.264.0";
1827
+ var IOS_SUPPORTED_VERSION = "5.264.0";
1828
+ var APP_BRIDGE_METHOD_NAME2 = "fetchAppsInTossAd";
1829
+ var UNSUPPORTED_ERROR_MESSAGE = "This feature is not supported in the current environment";
1830
+ function fetchAppsInTossAd(params) {
1831
+ const { body, onEvent, onError } = params;
1832
+ if (!fetchAppsInTossAd.isSupported()) {
1833
+ onError(new Error(UNSUPPORTED_ERROR_MESSAGE));
1834
+ return noop;
1835
+ }
1836
+ const spaceUnitId = normalizeAdGroupId(body.spaceUnitId);
1837
+ if (spaceUnitId.length === 0) {
1838
+ onError(createInvalidAdGroupIdError());
1839
+ return noop;
1840
+ }
1841
+ return import_native_modules12.INTERNAL__appBridgeHandler.invokeAppBridgeMethod(
1842
+ APP_BRIDGE_METHOD_NAME2,
1843
+ { ...body, spaceUnitId, sessionId: body.sessionId ?? sessionId },
1844
+ {
1845
+ onSuccess: onEvent,
1846
+ onError
1847
+ }
1848
+ );
1849
+ }
1850
+ fetchAppsInTossAd.isSupported = () => {
1851
+ if ((0, import_native_modules12.getOperationalEnvironment)() !== "toss") {
1852
+ return false;
1853
+ }
1854
+ return (0, import_native_modules12.isMinVersionSupported)({
1855
+ android: ANDROID_SUPPORTED_VERSION,
1856
+ ios: IOS_SUPPORTED_VERSION
1857
+ });
1858
+ };
1859
+
1825
1860
  // src/ads/fetchTossAd.ts
1861
+ var import_native_modules13 = require("@apps-in-toss/native-modules");
1826
1862
  var ANDROID_FETCH_TOSS_AD_SUPPORTED_VERSION = "5.241.0";
1827
1863
  var IOS_FETCH_TOSS_AD_SUPPORTED_VERSION = "5.241.0";
1828
- var UNSUPPORTED_ERROR_MESSAGE = "This feature is not supported in the current environment";
1829
- var ENVIRONMENT = (0, import_native_modules12.getOperationalEnvironment)();
1864
+ var UNSUPPORTED_ERROR_MESSAGE2 = "This feature is not supported in the current environment";
1865
+ var ENVIRONMENT = (0, import_native_modules13.getOperationalEnvironment)();
1830
1866
  function fetchTossAd(params) {
1831
1867
  if (!fetchTossAd.isSupported()) {
1832
- params.onError(new Error(UNSUPPORTED_ERROR_MESSAGE));
1868
+ params.onError(new Error(UNSUPPORTED_ERROR_MESSAGE2));
1833
1869
  return noop;
1834
1870
  }
1835
1871
  const { onEvent, onError, options } = params;
@@ -1839,7 +1875,7 @@ function fetchTossAd(params) {
1839
1875
  return noop;
1840
1876
  }
1841
1877
  const wireHeaders = options.headers;
1842
- const unregisterCallbacks = import_native_modules12.INTERNAL__appBridgeHandler.invokeAppBridgeMethod(
1878
+ const unregisterCallbacks = import_native_modules13.INTERNAL__appBridgeHandler.invokeAppBridgeMethod(
1843
1879
  "fetchTossAd",
1844
1880
  {
1845
1881
  spaceUnitId: adGroupId,
@@ -1863,14 +1899,14 @@ fetchTossAd.isSupported = () => {
1863
1899
  if (ENVIRONMENT !== "toss") {
1864
1900
  return false;
1865
1901
  }
1866
- return (0, import_native_modules12.isMinVersionSupported)({
1902
+ return (0, import_native_modules13.isMinVersionSupported)({
1867
1903
  android: ANDROID_FETCH_TOSS_AD_SUPPORTED_VERSION,
1868
1904
  ios: IOS_FETCH_TOSS_AD_SUPPORTED_VERSION
1869
1905
  });
1870
1906
  };
1871
1907
 
1872
1908
  // src/ads/integratedAd.ts
1873
- var import_native_modules14 = require("@apps-in-toss/native-modules");
1909
+ var import_native_modules15 = require("@apps-in-toss/native-modules");
1874
1910
 
1875
1911
  // src/ads/generateRequestId.ts
1876
1912
  function generateRequestId() {
@@ -1890,7 +1926,7 @@ function getReferrer() {
1890
1926
  }
1891
1927
 
1892
1928
  // src/ads/remotes.ts
1893
- var import_native_modules13 = require("@apps-in-toss/native-modules");
1929
+ var import_native_modules14 = require("@apps-in-toss/native-modules");
1894
1930
 
1895
1931
  // src/ads/getIsDev.ts
1896
1932
  var import_react_native33 = require("@granite-js/react-native");
@@ -1903,9 +1939,9 @@ function getIsDev() {
1903
1939
  }
1904
1940
 
1905
1941
  // src/ads/remotes.ts
1906
- var OPERATIONAL_ENVIRONMENT = (0, import_native_modules13.getOperationalEnvironment)();
1907
- var OS = (0, import_native_modules13.getPlatformOS)();
1908
- var APP_VER = (0, import_native_modules13.getTossAppVersion)();
1942
+ var OPERATIONAL_ENVIRONMENT = (0, import_native_modules14.getOperationalEnvironment)();
1943
+ var OS = (0, import_native_modules14.getPlatformOS)();
1944
+ var APP_VER = (0, import_native_modules14.getTossAppVersion)();
1909
1945
  var ALPHA_EVENT_TRACKER_HTTP_ENDPOINT = "https://alpha-trillion.toss.im/trk/sdk-mediation/event";
1910
1946
  var LIVE_EVENT_TRACKER_HTTP_ENDPOINT = "https://trillion.toss.im/trk/sdk-mediation/event";
1911
1947
  function getPostEventTrackingUrl() {
@@ -1937,18 +1973,18 @@ function postEventTracking(params) {
1937
1973
  var INTEGRATED_AD_SDK_VERSION = "0.0.0";
1938
1974
  var ANDROID_INTEGRATED_AD_SUPPORTED_VERSION = "5.247.0";
1939
1975
  var IOS_INTEGRATED_AD_SUPPORTED_VERSION = "5.247.0";
1940
- var UNSUPPORTED_ERROR_MESSAGE2 = "This feature is not supported in the current environment";
1976
+ var UNSUPPORTED_ERROR_MESSAGE3 = "This feature is not supported in the current environment";
1941
1977
  var INTG_AD_ADM_FALLBACK_RID_MAP = {};
1942
1978
  function integratedAdIsSupported() {
1943
- return (0, import_native_modules14.isMinVersionSupported)({
1979
+ return (0, import_native_modules15.isMinVersionSupported)({
1944
1980
  android: ANDROID_INTEGRATED_AD_SUPPORTED_VERSION,
1945
1981
  ios: IOS_INTEGRATED_AD_SUPPORTED_VERSION
1946
1982
  });
1947
1983
  }
1948
1984
  function generateLoadFullScreenAd(sdkId) {
1949
1985
  const fn = (params) => {
1950
- if (!import_native_modules14.GoogleAdMob.loadAppsInTossAdMob.isSupported()) {
1951
- params.onError(new Error(UNSUPPORTED_ERROR_MESSAGE2));
1986
+ if (!import_native_modules15.GoogleAdMob.loadAppsInTossAdMob.isSupported()) {
1987
+ params.onError(new Error(UNSUPPORTED_ERROR_MESSAGE3));
1952
1988
  return noop;
1953
1989
  }
1954
1990
  const normalizedAdGroupId = normalizeAdGroupId(params.options.adGroupId);
@@ -1966,7 +2002,7 @@ function generateLoadFullScreenAd(sdkId) {
1966
2002
  if (!integratedAdIsSupported()) {
1967
2003
  const fallbackOptions = { ...normalizedParams.options };
1968
2004
  delete fallbackOptions.headers;
1969
- return import_native_modules14.GoogleAdMob.loadAppsInTossAdMob({
2005
+ return import_native_modules15.GoogleAdMob.loadAppsInTossAdMob({
1970
2006
  ...normalizedParams,
1971
2007
  options: fallbackOptions,
1972
2008
  onEvent: (event) => {
@@ -2006,7 +2042,7 @@ function generateLoadFullScreenAd(sdkId) {
2006
2042
  const { adGroupId } = options;
2007
2043
  const referrer = getReferrer();
2008
2044
  const wireHeaders = options.headers;
2009
- const unregisterCallbacks = import_native_modules14.INTERNAL__appBridgeHandler.invokeAppBridgeMethod(
2045
+ const unregisterCallbacks = import_native_modules15.INTERNAL__appBridgeHandler.invokeAppBridgeMethod(
2010
2046
  "loadTossAdOrAdmob",
2011
2047
  {
2012
2048
  spaceUnitId: adGroupId,
@@ -2026,14 +2062,14 @@ function generateLoadFullScreenAd(sdkId) {
2026
2062
  );
2027
2063
  return unregisterCallbacks;
2028
2064
  };
2029
- fn.isSupported = import_native_modules14.GoogleAdMob.loadAppsInTossAdMob.isSupported;
2065
+ fn.isSupported = import_native_modules15.GoogleAdMob.loadAppsInTossAdMob.isSupported;
2030
2066
  return fn;
2031
2067
  }
2032
2068
  var loadFullScreenAd = generateLoadFullScreenAd("107");
2033
2069
  var loadFullScreenAdForWeb = generateLoadFullScreenAd("107");
2034
2070
  function showFullScreenAd(params) {
2035
- if (!import_native_modules14.GoogleAdMob.showAppsInTossAdMob.isSupported()) {
2036
- params.onError(new Error(UNSUPPORTED_ERROR_MESSAGE2));
2071
+ if (!import_native_modules15.GoogleAdMob.showAppsInTossAdMob.isSupported()) {
2072
+ params.onError(new Error(UNSUPPORTED_ERROR_MESSAGE3));
2037
2073
  return noop;
2038
2074
  }
2039
2075
  const normalizedAdGroupId = normalizeAdGroupId(params.options.adGroupId);
@@ -2049,7 +2085,7 @@ function showFullScreenAd(params) {
2049
2085
  }
2050
2086
  };
2051
2087
  if (!integratedAdIsSupported()) {
2052
- return import_native_modules14.GoogleAdMob.showAppsInTossAdMob({
2088
+ return import_native_modules15.GoogleAdMob.showAppsInTossAdMob({
2053
2089
  ...normalizedParams,
2054
2090
  onEvent: (event) => {
2055
2091
  const requestId = INTG_AD_ADM_FALLBACK_RID_MAP[normalizedAdGroupId] ?? "";
@@ -2148,7 +2184,7 @@ function showFullScreenAd(params) {
2148
2184
  const { onEvent, onError, options } = normalizedParams;
2149
2185
  const { adGroupId } = options;
2150
2186
  const referrer = getReferrer();
2151
- const unregisterCallbacks = import_native_modules14.INTERNAL__appBridgeHandler.invokeAppBridgeMethod(
2187
+ const unregisterCallbacks = import_native_modules15.INTERNAL__appBridgeHandler.invokeAppBridgeMethod(
2152
2188
  "showTossAdOrAdmob",
2153
2189
  { spaceUnitId: adGroupId, referrer, sessionId },
2154
2190
  {
@@ -2168,7 +2204,8 @@ function showFullScreenAd(params) {
2168
2204
  onEvent({ type: "show" });
2169
2205
  },
2170
2206
  onUserEarnedReward: (data) => {
2171
- onEvent({ type: "userEarnedReward", data });
2207
+ const normalized = "type" in data ? { unitType: data.type, unitAmount: data.amount } : data;
2208
+ onEvent({ type: "userEarnedReward", data: normalized });
2172
2209
  },
2173
2210
  onSuccess: () => {
2174
2211
  onEvent({ type: "requested" });
@@ -2180,7 +2217,7 @@ function showFullScreenAd(params) {
2180
2217
  );
2181
2218
  return unregisterCallbacks;
2182
2219
  }
2183
- showFullScreenAd.isSupported = import_native_modules14.GoogleAdMob.showAppsInTossAdMob.isSupported;
2220
+ showFullScreenAd.isSupported = import_native_modules15.GoogleAdMob.showAppsInTossAdMob.isSupported;
2184
2221
 
2185
2222
  // src/ads/tossAdEventLog.ts
2186
2223
  var import_react_native34 = require("@granite-js/react-native");
@@ -2493,7 +2530,7 @@ function mergeRefs(...refs) {
2493
2530
  }
2494
2531
 
2495
2532
  // src/hooks/useCreateUserAgent.ts
2496
- var import_native_modules15 = require("@apps-in-toss/native-modules");
2533
+ var import_native_modules16 = require("@apps-in-toss/native-modules");
2497
2534
  var import_react_native36 = require("react-native");
2498
2535
  var FontA11yCategory = {
2499
2536
  Large: "Large",
@@ -2627,8 +2664,8 @@ function useCreateUserAgent({
2627
2664
  safeArea,
2628
2665
  safeAreaBottomTransparency
2629
2666
  }) {
2630
- const platform = (0, import_native_modules15.getPlatformOS)();
2631
- const appVersion = (0, import_native_modules15.getTossAppVersion)();
2667
+ const platform = (0, import_native_modules16.getPlatformOS)();
2668
+ const appVersion = (0, import_native_modules16.getTossAppVersion)();
2632
2669
  const { fontScale } = (0, import_react_native36.useWindowDimensions)();
2633
2670
  const platformString = platform === "ios" ? "iPhone" : "Android phone";
2634
2671
  const fontA11y = mapFontScaleToCategory(fontScale, platform);
@@ -2650,7 +2687,7 @@ function useCreateUserAgent({
2650
2687
  }
2651
2688
 
2652
2689
  // src/hooks/useGeolocation.ts
2653
- var import_native_modules16 = require("@apps-in-toss/native-modules");
2690
+ var import_native_modules17 = require("@apps-in-toss/native-modules");
2654
2691
  var import_react_native37 = require("@granite-js/react-native");
2655
2692
  var import_react26 = require("react");
2656
2693
  function useGeolocation({ accuracy, distanceInterval, timeInterval }) {
@@ -2660,7 +2697,7 @@ function useGeolocation({ accuracy, distanceInterval, timeInterval }) {
2660
2697
  if (!isVisible) {
2661
2698
  return;
2662
2699
  }
2663
- return (0, import_native_modules16.startUpdateLocation)({
2700
+ return (0, import_native_modules17.startUpdateLocation)({
2664
2701
  options: {
2665
2702
  accuracy,
2666
2703
  distanceInterval,
@@ -2713,7 +2750,7 @@ function useTopNavigation() {
2713
2750
  }
2714
2751
 
2715
2752
  // src/hooks/useWebViewMemoryDebug.tsx
2716
- var import_native_modules17 = require("@apps-in-toss/native-modules");
2753
+ var import_native_modules18 = require("@apps-in-toss/native-modules");
2717
2754
  var import_react_native39 = require("@granite-js/react-native");
2718
2755
  var import_tds_react_native15 = require("@toss/tds-react-native");
2719
2756
  function useHandleWebViewProcessDidTerminate(webViewRef) {
@@ -2741,7 +2778,7 @@ function webViewDebugLog(logName, params) {
2741
2778
  deployment_id: global2.deploymentId
2742
2779
  }
2743
2780
  };
2744
- if ((0, import_native_modules17.getOperationalEnvironment)() === "toss") {
2781
+ if ((0, import_native_modules18.getOperationalEnvironment)() === "toss") {
2745
2782
  sendLog(event, { pipelines: ["core"] });
2746
2783
  } else {
2747
2784
  console.log("[webViewDebugLog]", event);
@@ -2841,7 +2878,7 @@ function getWebViewURL(local) {
2841
2878
  const devUrl = `http://${local.host}:${local.port}`;
2842
2879
  return mergeSchemeQueryParamsInto(devUrl);
2843
2880
  }
2844
- const { url: rawUrl } = (0, import_native_modules18.safeSyncPostMessage)("getWebBundleURL", {});
2881
+ const { url: rawUrl } = (0, import_native_modules19.safeSyncPostMessage)("getWebBundleURL", {});
2845
2882
  const url = mergeSchemeQueryParamsInto(rawUrl);
2846
2883
  const deploymentId = env.getDeploymentId();
2847
2884
  if (deploymentId) {
@@ -2875,39 +2912,42 @@ function WebView({ type, local, onMessage, ...props }) {
2875
2912
  };
2876
2913
  },
2877
2914
  homeEvent: ({ onEvent }) => homeEvent.subscribe(onEvent),
2878
- updateLocationEvent: ({ onEvent, onError, options }) => import_native_modules18.appsInTossEvent.addEventListener("updateLocationEvent", { onEvent, onError, options }),
2915
+ updateLocationEvent: ({ onEvent, onError, options }) => import_native_modules19.appsInTossEvent.addEventListener("updateLocationEvent", { onEvent, onError, options }),
2879
2916
  safeAreaInsetsChange: ({ onEvent }) => safeAreaInsetsEvent.subscribe(onEvent),
2880
2917
  /** @internal */
2881
- appBridgeCallbackEvent: ({ onEvent, onError, options }) => import_native_modules18.appsInTossEvent.addEventListener("appBridgeCallbackEvent", { onEvent, onError, options }),
2918
+ appBridgeCallbackEvent: ({ onEvent, onError, options }) => import_native_modules19.appsInTossEvent.addEventListener("appBridgeCallbackEvent", { onEvent, onError, options }),
2882
2919
  /** AdMobV2 */
2883
- loadAppsInTossAdMob: import_native_modules18.GoogleAdMob.loadAppsInTossAdMob,
2884
- showAppsInTossAdMob: import_native_modules18.GoogleAdMob.showAppsInTossAdMob,
2920
+ loadAppsInTossAdMob: import_native_modules19.GoogleAdMob.loadAppsInTossAdMob,
2921
+ showAppsInTossAdMob: import_native_modules19.GoogleAdMob.showAppsInTossAdMob,
2885
2922
  /** IntegratedAd */
2886
2923
  loadFullScreenAd: loadFullScreenAdForWeb,
2887
2924
  showFullScreenAd,
2888
2925
  /** TossAd */
2889
2926
  fetchTossAd,
2927
+ // v1.4 배너: web 이벤트 브릿지는 payload를 options로 전달하지만 fetchAppsInTossAd는 body로 받으므로 어댑팅한다.
2928
+ fetchAppsInTossAd: ({ onEvent, onError, options }) => fetchAppsInTossAd({ body: options, onEvent, onError }),
2890
2929
  /** IAP */
2891
- iapCreateOneTimePurchaseOrder: import_native_modules18.IAP.createOneTimePurchaseOrder,
2892
- requestSubscriptionPurchase: import_native_modules18.requestSubscriptionPurchase,
2893
- requestOneTimePurchase: import_native_modules18.requestOneTimePurchase,
2894
- requestNotificationAgreement: import_native_modules18.requestNotificationAgreement
2930
+ iapCreateOneTimePurchaseOrder: import_native_modules19.IAP.createOneTimePurchaseOrder,
2931
+ requestSubscriptionPurchase: import_native_modules19.requestSubscriptionPurchase,
2932
+ requestOneTimePurchase: import_native_modules19.requestOneTimePurchase,
2933
+ requestNotificationAgreement: import_native_modules19.requestNotificationAgreement
2895
2934
  },
2896
2935
  constantHandlerMap: {
2897
2936
  ...appsInTossConstantBridges,
2898
2937
  getSafeAreaInsets: () => insets,
2899
2938
  ...Object.fromEntries(Object.entries(global2).map(([key, value]) => [key, () => value])),
2900
- getServerTime_isSupported: import_native_modules18.getServerTime.isSupported,
2901
- requestReview_isSupported: import_native_modules18.requestReview.isSupported,
2939
+ getServerTime_isSupported: import_native_modules19.getServerTime.isSupported,
2940
+ requestReview_isSupported: import_native_modules19.requestReview.isSupported,
2902
2941
  /** AdMobV2 */
2903
- loadAppsInTossAdMob_isSupported: import_native_modules18.GoogleAdMob.loadAppsInTossAdMob.isSupported,
2904
- showAppsInTossAdMob_isSupported: import_native_modules18.GoogleAdMob.showAppsInTossAdMob.isSupported,
2905
- isAppsInTossAdMobLoaded_isSupported: import_native_modules18.GoogleAdMob.isAppsInTossAdMobLoaded.isSupported,
2942
+ loadAppsInTossAdMob_isSupported: import_native_modules19.GoogleAdMob.loadAppsInTossAdMob.isSupported,
2943
+ showAppsInTossAdMob_isSupported: import_native_modules19.GoogleAdMob.showAppsInTossAdMob.isSupported,
2944
+ isAppsInTossAdMobLoaded_isSupported: import_native_modules19.GoogleAdMob.isAppsInTossAdMobLoaded.isSupported,
2906
2945
  /** IntegratedAd */
2907
2946
  loadFullScreenAd_isSupported: loadFullScreenAdForWeb.isSupported,
2908
2947
  showFullScreenAd_isSupported: showFullScreenAd.isSupported,
2909
2948
  /** TossAd */
2910
2949
  fetchTossAd_isSupported: fetchTossAd.isSupported,
2950
+ fetchAppsInTossAd_isSupported: fetchAppsInTossAd.isSupported,
2911
2951
  /** env */
2912
2952
  getDeploymentId: env.getDeploymentId,
2913
2953
  getWebViewType: env.getWebViewType,
@@ -2915,7 +2955,7 @@ function WebView({ type, local, onMessage, ...props }) {
2915
2955
  },
2916
2956
  asyncHandlerMap: {
2917
2957
  ...appsInTossAsyncBridges,
2918
- getServerTime: import_native_modules18.getServerTime,
2958
+ getServerTime: import_native_modules19.getServerTime,
2919
2959
  setIosSwipeGestureEnabled: (options) => {
2920
2960
  setAllowsBackForwardNavigationGestures(options.isEnabled);
2921
2961
  return appsInTossAsyncBridges.setIosSwipeGestureEnabled(options);
@@ -2933,20 +2973,20 @@ function WebView({ type, local, onMessage, ...props }) {
2933
2973
  getCurrentLocation: appsInTossAsyncBridges.getCurrentLocation,
2934
2974
  openCamera: appsInTossAsyncBridges.openCamera,
2935
2975
  /** Storage */
2936
- getStorageItem: import_native_modules18.Storage.getItem,
2937
- setStorageItem: import_native_modules18.Storage.setItem,
2938
- removeStorageItem: import_native_modules18.Storage.removeItem,
2939
- clearItems: import_native_modules18.Storage.clearItems,
2976
+ getStorageItem: import_native_modules19.Storage.getItem,
2977
+ setStorageItem: import_native_modules19.Storage.setItem,
2978
+ removeStorageItem: import_native_modules19.Storage.removeItem,
2979
+ clearItems: import_native_modules19.Storage.clearItems,
2940
2980
  /** IAP */
2941
- iapGetProductItemList: import_native_modules18.IAP.getProductItemList,
2942
- iapCreateOneTimePurchaseOrder: import_native_modules18.iapCreateOneTimePurchaseOrder,
2943
- processProductGrant: import_native_modules18.processProductGrant,
2944
- getPendingOrders: import_native_modules18.IAP.getPendingOrders,
2945
- getCompletedOrRefundedOrders: import_native_modules18.IAP.getCompletedOrRefundedOrders,
2946
- completeProductGrant: import_native_modules18.IAP.completeProductGrant,
2947
- getSubscriptionInfo: import_native_modules18.IAP.getSubscriptionInfo,
2981
+ iapGetProductItemList: import_native_modules19.IAP.getProductItemList,
2982
+ iapCreateOneTimePurchaseOrder: import_native_modules19.iapCreateOneTimePurchaseOrder,
2983
+ processProductGrant: import_native_modules19.processProductGrant,
2984
+ getPendingOrders: import_native_modules19.IAP.getPendingOrders,
2985
+ getCompletedOrRefundedOrders: import_native_modules19.IAP.getCompletedOrRefundedOrders,
2986
+ completeProductGrant: import_native_modules19.IAP.completeProductGrant,
2987
+ getSubscriptionInfo: import_native_modules19.IAP.getSubscriptionInfo,
2948
2988
  /** AdMobV2 */
2949
- isAppsInTossAdMobLoaded: import_native_modules18.GoogleAdMob.isAppsInTossAdMobLoaded,
2989
+ isAppsInTossAdMobLoaded: import_native_modules19.GoogleAdMob.isAppsInTossAdMobLoaded,
2950
2990
  /** Toss Ads */
2951
2991
  tossAdEventLog,
2952
2992
  /** Private */
@@ -3171,6 +3211,159 @@ var AD_STATUS_ERROR_MAP = {
3171
3211
  }
3172
3212
  };
3173
3213
 
3214
+ // src/ads/inlineAd/errorTracking.ts
3215
+ var BANNER_ERROR_LOG_NAME = "display_ads_all::error__banner";
3216
+ var MAX_STACK_TRACE_LENGTH = 255;
3217
+ function logBannerErrorToAppLog(info) {
3218
+ void tossAdEventLog({
3219
+ log_name: BANNER_ERROR_LOG_NAME,
3220
+ log_type: "debug",
3221
+ params: {
3222
+ error_code: info.errorCode,
3223
+ error_message: info.errorMessage,
3224
+ ad_group_id: info.adGroupId,
3225
+ mediation_id: info.mediationId,
3226
+ event_context_token: info.eventContextToken
3227
+ }
3228
+ }).catch(noop);
3229
+ }
3230
+ function trackBannerError(info) {
3231
+ if (info.endpointError) {
3232
+ void fetch(info.endpointError, {
3233
+ method: "POST",
3234
+ headers: { "Content-Type": "application/json" },
3235
+ body: JSON.stringify({
3236
+ eventContextToken: info.eventContextToken,
3237
+ mediationId: info.mediationId,
3238
+ errorCode: info.errorCode,
3239
+ errorMessage: info.errorMessage,
3240
+ stackTrace: info.stackTrace?.slice(0, MAX_STACK_TRACE_LENGTH)
3241
+ })
3242
+ // POST 실패(CORS·네트워크) → 앱로그 fallback (endpoint와 같은 채널이라 함께 막히는 경우 대비).
3243
+ }).catch(() => logBannerErrorToAppLog(info));
3244
+ return;
3245
+ }
3246
+ logBannerErrorToAppLog(info);
3247
+ }
3248
+
3249
+ // src/ads/inlineAd/loadAd.ts
3250
+ var import_native_modules20 = require("@apps-in-toss/native-modules");
3251
+
3252
+ // src/ads/fetchAppsInTossAdSchema.ts
3253
+ var APPS_IN_TOSS_AD_SPEC_VERSION = "1.4.1";
3254
+ var FETCH_APPS_IN_TOSS_AD_DEVICE_MACRO = "{{device}}";
3255
+ var TOSS_APP_BUNDLE_IDS = {
3256
+ ios: "com.vivarepublica.cash",
3257
+ android: "viva.republica.toss"
3258
+ };
3259
+ function resolveTossAppBundleId(os) {
3260
+ return TOSS_APP_BUNDLE_IDS[os];
3261
+ }
3262
+
3263
+ // package.json
3264
+ var package_default = {
3265
+ name: "@apps-in-toss/framework",
3266
+ type: "module",
3267
+ version: "2.10.0",
3268
+ description: "The framework for Apps In Toss",
3269
+ scripts: {
3270
+ typecheck: "tsc --noEmit",
3271
+ test: "vitest --no-watch",
3272
+ "test:no-parallel": "vitest --no-watch --config=vitest.no-parallel.config.mts",
3273
+ lint: "eslint .",
3274
+ build: "tsup"
3275
+ },
3276
+ main: "./dist/index.cjs",
3277
+ module: "./dist/index.js",
3278
+ types: "./dist/index.d.ts",
3279
+ exports: {
3280
+ ".": {
3281
+ types: "./dist/index.d.ts",
3282
+ import: "./dist/index.js",
3283
+ require: "./dist/index.cjs"
3284
+ },
3285
+ "./plugins": {
3286
+ types: "./dist/plugins/index.d.ts",
3287
+ import: "./dist/plugins/index.js",
3288
+ require: "./dist/plugins/index.cjs"
3289
+ },
3290
+ "./internal": {
3291
+ types: "./dist/internal.d.ts",
3292
+ import: "./dist/internal.js",
3293
+ require: "./dist/internal.cjs"
3294
+ },
3295
+ "./bridge-entry": "./src/bridge-entry.ts",
3296
+ "./bridge-meta": {
3297
+ types: "./dist/bridge-meta.d.ts",
3298
+ default: "./dist/bridge-meta.js"
3299
+ },
3300
+ "./jest": {
3301
+ types: "./dist/jest/index.d.ts",
3302
+ import: "./dist/jest/index.js",
3303
+ require: "./dist/jest/index.cjs"
3304
+ },
3305
+ "./package.json": "./package.json"
3306
+ },
3307
+ files: [
3308
+ "dist/**/*",
3309
+ "src/bridge-entry.ts",
3310
+ "src/async-bridges.ts",
3311
+ "src/constant-bridges.ts",
3312
+ "src/event-bridges.ts",
3313
+ "hermesc/**/*",
3314
+ "plugins.d.ts",
3315
+ "jest.d.ts"
3316
+ ],
3317
+ bin: {
3318
+ ait: "./bin/ait.js"
3319
+ },
3320
+ dependencies: {
3321
+ "@apps-in-toss/analytics": "workspace:*",
3322
+ "@apps-in-toss/cli": "workspace:*",
3323
+ "@apps-in-toss/native-modules": "workspace:*",
3324
+ "@apps-in-toss/plugins": "workspace:*",
3325
+ "@apps-in-toss/types": "workspace:*",
3326
+ "@apps-in-toss/user-scripts": "workspace:^",
3327
+ "es-hangul": "^2.3.2"
3328
+ },
3329
+ devDependencies: {
3330
+ "@apps-in-toss/ait-format": "1.0.0",
3331
+ "@babel/runtime": "^7",
3332
+ "@granite-js/mpack": "catalog:granite-js",
3333
+ "@granite-js/native": "catalog:granite-js",
3334
+ "@granite-js/plugin-core": "catalog:granite-js",
3335
+ "@granite-js/react-native": "catalog:granite-js",
3336
+ "@granite-js/utils": "catalog:granite-js",
3337
+ "@toss/tds-react-native": "catalog:react-native",
3338
+ "@types/kill-port": "2.0.1",
3339
+ "@types/react": "catalog:react-native",
3340
+ "brick-module": "catalog:brick-module",
3341
+ "es-toolkit": "^1.34.1",
3342
+ eslint: "^9.7.0",
3343
+ execa: "catalog:tooling",
3344
+ jsdom: "^25.0.1",
3345
+ "kill-port": "2.0.1",
3346
+ react: "catalog:react-native",
3347
+ "react-native": "catalog:react-native",
3348
+ tsup: "^8.3.5",
3349
+ typescript: "5.8.3",
3350
+ vitest: "^3.0.3",
3351
+ "workspace-tools": "^0.38.2"
3352
+ },
3353
+ peerDependencies: {
3354
+ "@granite-js/native": "*",
3355
+ "@granite-js/react-native": "*",
3356
+ "@toss/tds-react-native": ">=2.0.0",
3357
+ "@types/react": "*",
3358
+ "brick-module": "*",
3359
+ react: "*",
3360
+ "react-native": "*"
3361
+ }
3362
+ };
3363
+
3364
+ // src/ads/sdkVersion.ts
3365
+ var SDK_VERSION = package_default.version;
3366
+
3174
3367
  // src/ads/inlineAd/loadAd.ts
3175
3368
  function createError(code, message) {
3176
3369
  return {
@@ -3197,6 +3390,28 @@ function fetchTossAdPromise(options) {
3197
3390
  });
3198
3391
  });
3199
3392
  }
3393
+ function requestAd(adGroupId) {
3394
+ if (fetchAppsInTossAd.isSupported()) {
3395
+ const body = {
3396
+ specVersion: APPS_IN_TOSS_AD_SPEC_VERSION,
3397
+ platform: "RN",
3398
+ spaceUnitId: adGroupId,
3399
+ sdkVersion: SDK_VERSION,
3400
+ availableStyleIds: AVAILABLE_STYLE_IDS,
3401
+ // device는 매크로키만 보내고 native가 실제 device로 치환한다.
3402
+ device: FETCH_APPS_IN_TOSS_AD_DEVICE_MACRO,
3403
+ app: {
3404
+ version: (0, import_native_modules20.getTossAppVersion)(),
3405
+ bundle: resolveTossAppBundleId((0, import_native_modules20.getPlatformOS)()),
3406
+ subBundle: global.__granite?.app?.name ?? ""
3407
+ }
3408
+ };
3409
+ return new Promise((resolve, reject) => {
3410
+ fetchAppsInTossAd({ body, onEvent: resolve, onError: reject });
3411
+ });
3412
+ }
3413
+ return fetchTossAdPromise({ adGroupId, sdkId: SDK_ID, availableStyleIds: AVAILABLE_STYLE_IDS });
3414
+ }
3200
3415
  function isApiResponse(payload) {
3201
3416
  return Boolean(payload && typeof payload === "object" && "resultType" in payload);
3202
3417
  }
@@ -3210,6 +3425,7 @@ function normalizeAdResponse(adResponse) {
3210
3425
  })).filter((ad) => AVAILABLE_STYLE_IDS.includes(String(ad.styleId))) : [];
3211
3426
  return {
3212
3427
  requestId: adResponse.requestId ?? "",
3428
+ eventContextToken: adResponse.eventContextToken ?? "",
3213
3429
  status: adResponse.status ?? "OK",
3214
3430
  ads,
3215
3431
  ext: adResponse.ext
@@ -3250,7 +3466,7 @@ async function loadAd(adGroupId) {
3250
3466
  error: createError(ERROR_CODES.INVALID_SPACE, INVALID_AD_GROUP_ID_ERROR_MESSAGE)
3251
3467
  };
3252
3468
  }
3253
- if (!fetchTossAd.isSupported()) {
3469
+ if (!fetchAppsInTossAd.isSupported() && !fetchTossAd.isSupported()) {
3254
3470
  return {
3255
3471
  type: "error",
3256
3472
  error: createError(ERROR_CODES.SDK_NOT_INITIALIZED, "This feature is not supported in the current environment")
@@ -3258,11 +3474,7 @@ async function loadAd(adGroupId) {
3258
3474
  }
3259
3475
  let response;
3260
3476
  try {
3261
- const raw = await fetchTossAdPromise({
3262
- adGroupId: normalizedAdGroupId,
3263
- sdkId: SDK_ID,
3264
- availableStyleIds: AVAILABLE_STYLE_IDS
3265
- });
3477
+ const raw = await requestAd(normalizedAdGroupId);
3266
3478
  response = normalizeApiResponse(raw);
3267
3479
  } catch (error) {
3268
3480
  if (isAdError(error)) {
@@ -3364,6 +3576,162 @@ function supertossWeb(uri) {
3364
3576
  return `supertoss://web?url=${encodeURIComponent(uri)}&external=true`;
3365
3577
  }
3366
3578
 
3579
+ // src/ads/inlineAd/renderConfig.ts
3580
+ var listBannerPalette = {
3581
+ "1": {
3582
+ light: {
3583
+ title: "#4e5968",
3584
+ subtitle: "#6b7684",
3585
+ adClearance: "#b0b8c1",
3586
+ iconBg: "rgba(2,32,71,0.05)",
3587
+ iconBorder: "rgba(2,32,71,0.05)"
3588
+ },
3589
+ dark: {
3590
+ title: "rgba(253,253,255,0.75)",
3591
+ subtitle: "rgba(248,248,255,0.6)",
3592
+ adClearance: "rgba(242,242,255,0.47)",
3593
+ iconBg: "#ffffff",
3594
+ iconBorder: "rgba(217,217,255,0.11)"
3595
+ }
3596
+ },
3597
+ "2": {
3598
+ light: {
3599
+ title: "#4e5968",
3600
+ subtitle: "#6b7684",
3601
+ adClearance: "#b0b8c1",
3602
+ iconBg: "rgba(2,32,71,0.05)",
3603
+ iconBorder: "rgba(2,32,71,0.05)"
3604
+ },
3605
+ dark: {
3606
+ title: "rgba(253,253,255,0.75)",
3607
+ subtitle: "rgba(248,248,255,0.6)",
3608
+ adClearance: "rgba(242,242,255,0.47)",
3609
+ iconBg: "rgba(217,217,255,0.11)",
3610
+ iconBorder: "rgba(217,217,255,0.11)"
3611
+ }
3612
+ }
3613
+ };
3614
+ var feedBannerPalette = {
3615
+ "1": {
3616
+ light: {
3617
+ brandLogoBg: "rgba(2,32,71,0.05)",
3618
+ brandLogoBorder: "rgba(2,32,71,0.05)",
3619
+ brandName: "#6b7684",
3620
+ adBadge: "#8b95a1",
3621
+ title: "#333d4b",
3622
+ subtitle: "#4e5968",
3623
+ adClearance: "#8b95a1",
3624
+ imageOverlayBorder: "rgba(2,32,71,0.05)"
3625
+ },
3626
+ dark: {
3627
+ brandLogoBg: "#ffffff",
3628
+ brandLogoBorder: "rgba(217,217,255,0.11)",
3629
+ brandName: "#9e9ea4",
3630
+ adBadge: "#7e7e87",
3631
+ title: "#e4e4e5",
3632
+ subtitle: "#c3c3c6",
3633
+ adClearance: "#7e7e87",
3634
+ imageOverlayBorder: "rgba(217,217,255,0.11)"
3635
+ }
3636
+ },
3637
+ "2": {
3638
+ light: {
3639
+ brandLogoBg: "rgba(2,32,71,0.05)",
3640
+ brandLogoBorder: "rgba(2,32,71,0.05)",
3641
+ brandName: "#6b7684",
3642
+ adBadge: "#8b95a1",
3643
+ title: "#333d4b",
3644
+ subtitle: "#4e5968",
3645
+ adClearance: "#8b95a1",
3646
+ imageOverlayBorder: "rgba(2,32,71,0.05)"
3647
+ },
3648
+ dark: {
3649
+ brandLogoBg: "rgba(217,217,255,0.11)",
3650
+ brandLogoBorder: "rgba(217,217,255,0.11)",
3651
+ brandName: "#9e9ea4",
3652
+ adBadge: "#7e7e87",
3653
+ title: "#e4e4e5",
3654
+ subtitle: "#c3c3c6",
3655
+ adClearance: "#7e7e87",
3656
+ imageOverlayBorder: "rgba(217,217,255,0.11)"
3657
+ }
3658
+ }
3659
+ };
3660
+ function resolveCreativeVersion(creativeVersion) {
3661
+ return String(creativeVersion) === "2" ? "2" : "1";
3662
+ }
3663
+ function resolveListBannerRenderConfig(creativeVersion, theme) {
3664
+ const version = resolveCreativeVersion(creativeVersion);
3665
+ const isV2 = version === "2";
3666
+ return {
3667
+ colors: listBannerPalette[version][theme],
3668
+ defaultPaddingValue: DEFAULT_INLINE_AD_PADDING_BANNER,
3669
+ titleSlotId: isV2 ? "1001" : "101",
3670
+ subtitleSlotId: isV2 ? "1002" : "102",
3671
+ iconImageSlotId: isV2 ? "2505" : "202",
3672
+ adClearancePaddingRight: isV2 ? 24 : void 0
3673
+ };
3674
+ }
3675
+ function resolveFeedBannerRenderConfig(creativeVersion, theme) {
3676
+ const version = resolveCreativeVersion(creativeVersion);
3677
+ const isV2 = version === "2";
3678
+ return {
3679
+ colors: feedBannerPalette[version][theme],
3680
+ defaultPaddingValue: isV2 ? DEFAULT_INLINE_AD_PADDING_BANNER : DEFAULT_INLINE_AD_PADDING_NATIVE_IMAGE,
3681
+ brandImageSlotId: isV2 ? "2500" : "202",
3682
+ brandNameSlotId: isV2 ? "1004" : "103",
3683
+ titleSlotId: isV2 ? "1000" : "101",
3684
+ subtitleSlotId: isV2 ? "1002" : "102",
3685
+ mainImageSlotId: isV2 ? "2005" : "201",
3686
+ ctaButtonSlotId: "0",
3687
+ adBadgeText: isV2 ? "AD" : "\uAD11\uACE0",
3688
+ showTextArea: !isV2,
3689
+ adBadgePaddingLeft: isV2 ? 1 : void 0,
3690
+ imageButtonBackgroundColor: isV2 ? "#000000" : void 0,
3691
+ cardOverlayBorderWidth: isV2 ? 1.5 : void 0
3692
+ };
3693
+ }
3694
+
3695
+ // src/ads/inlineAd/resultTracking.ts
3696
+ async function fireResultTracking(result, adGroupId, ctx) {
3697
+ if (result.type !== "success") {
3698
+ return;
3699
+ }
3700
+ if (ctx.resultEndpoint == null || ctx.mediationId == null) {
3701
+ return;
3702
+ }
3703
+ const body = {
3704
+ mediationId: ctx.mediationId,
3705
+ spaceUnitId: adGroupId,
3706
+ requestId: result.response?.requestId ?? "",
3707
+ eventContextToken: ctx.eventContextToken,
3708
+ winnerSource: "TOSS",
3709
+ content: null,
3710
+ adUnitId: ctx.adUnitId ?? null,
3711
+ placementId: ctx.placementId ?? null,
3712
+ tossFailed: null
3713
+ };
3714
+ try {
3715
+ const res = await fetch(ctx.resultEndpoint, {
3716
+ method: "POST",
3717
+ headers: { "Content-Type": "application/json" },
3718
+ body: JSON.stringify(body)
3719
+ });
3720
+ if (!res.ok) {
3721
+ throw new Error(`HTTP ${res.status}`);
3722
+ }
3723
+ } catch (error) {
3724
+ trackBannerError({
3725
+ errorCode: ERROR_CODES.NETWORK_ERROR,
3726
+ errorMessage: `RESULT_TRACKING failed: ${error instanceof Error ? error.message : String(error)}`,
3727
+ adGroupId,
3728
+ mediationId: ctx.mediationId,
3729
+ eventContextToken: ctx.eventContextToken,
3730
+ endpointError: ctx.errorEndpoint
3731
+ });
3732
+ }
3733
+ }
3734
+
3367
3735
  // src/ads/inlineAd/tracking.ts
3368
3736
  var GlobalEventDeduplicator = class _GlobalEventDeduplicator {
3369
3737
  static MAX_EVENTS = 1e4;
@@ -3386,12 +3754,13 @@ var GlobalEventDeduplicator = class _GlobalEventDeduplicator {
3386
3754
  };
3387
3755
  var globalEventDeduplicator = new GlobalEventDeduplicator();
3388
3756
  var EventTracker = class {
3389
- constructor(eventTrackingUrls = [], eventTypes = [], eventPayload = "", requestId, creativeId, requestHeaders) {
3757
+ constructor(eventTrackingUrls = [], eventTypes = [], eventPayload = "", requestId, creativeId, requestHeaders, onTrackingError) {
3390
3758
  this.eventTrackingUrls = eventTrackingUrls;
3391
3759
  this.eventPayload = eventPayload;
3392
3760
  this.requestId = requestId;
3393
3761
  this.creativeId = creativeId;
3394
3762
  this.requestHeaders = requestHeaders;
3763
+ this.onTrackingError = onTrackingError;
3395
3764
  this.eventTypes = new Set(eventTypes);
3396
3765
  this.repeatableEvents = /* @__PURE__ */ new Set(["VIEW_MUTE", "VIEW_UNMUTE"]);
3397
3766
  }
@@ -3415,7 +3784,13 @@ var EventTracker = class {
3415
3784
  type: eventType,
3416
3785
  data: this.eventPayload
3417
3786
  };
3418
- await Promise.allSettled(this.eventTrackingUrls.map((url) => this.sendTrackingRequest(url, payload)));
3787
+ const results = await Promise.allSettled(
3788
+ this.eventTrackingUrls.map((url) => this.sendTrackingRequest(url, payload))
3789
+ );
3790
+ const failedUrls = this.eventTrackingUrls.filter((_, index) => results[index]?.status === "rejected");
3791
+ if (failedUrls.length > 0) {
3792
+ this.onTrackingError?.(failedUrls);
3793
+ }
3419
3794
  if (!this.repeatableEvents.has(eventType) && this.requestId && this.creativeId) {
3420
3795
  globalEventDeduplicator.markTracked(this.requestId, this.creativeId, eventType);
3421
3796
  }
@@ -3428,14 +3803,33 @@ var EventTracker = class {
3428
3803
  if (this.requestId) {
3429
3804
  headers["X-Toss-RequestId"] = this.requestId;
3430
3805
  }
3431
- await fetch(url, {
3806
+ const response = await fetch(url, {
3432
3807
  method: "POST",
3433
3808
  headers,
3434
3809
  body: JSON.stringify(payload)
3435
3810
  });
3811
+ if (!response.ok) {
3812
+ throw new Error(`HTTP ${response.status}`);
3813
+ }
3436
3814
  }
3437
3815
  };
3438
3816
 
3817
+ // src/ads/inlineAd/trackingContext.ts
3818
+ function nonEmptyString(value) {
3819
+ return typeof value === "string" && value.length > 0 ? value : void 0;
3820
+ }
3821
+ function extractAdTrackingContext(response) {
3822
+ const mediation = response?.ext?.mediation;
3823
+ return {
3824
+ mediationId: nonEmptyString(mediation?.mediationId),
3825
+ eventContextToken: nonEmptyString(response?.eventContextToken),
3826
+ resultEndpoint: nonEmptyString(mediation?.endpoint?.result),
3827
+ errorEndpoint: nonEmptyString(mediation?.endpoint?.error),
3828
+ adUnitId: nonEmptyString(mediation?.admob?.adUnitId),
3829
+ placementId: typeof mediation?.admob?.placementId === "number" ? mediation.admob.placementId : void 0
3830
+ };
3831
+ }
3832
+
3439
3833
  // src/ads/inlineAd/ui/FeedBannerAdView.tsx
3440
3834
  var import_react_native_svg2 = require("@granite-js/native/react-native-svg");
3441
3835
  var import_react29 = require("react");
@@ -3445,6 +3839,12 @@ var ARROW_PATH = "m7.5 20.4c-.5-.5-.5-1.2 0-1.7l6.7-6.7-6.8-6.7c-.5-.5-.5-1.2 0-
3445
3839
  function FeedBannerAdView({
3446
3840
  brandName,
3447
3841
  brandLogoUri,
3842
+ brandImageSlotId,
3843
+ brandNameSlotId,
3844
+ titleSlotId,
3845
+ subtitleSlotId,
3846
+ mainImageSlotId,
3847
+ ctaButtonSlotId,
3448
3848
  title,
3449
3849
  subtitle,
3450
3850
  mainImageUri,
@@ -3452,6 +3852,11 @@ function FeedBannerAdView({
3452
3852
  ctaTextColor,
3453
3853
  ctaBackgroundColor,
3454
3854
  adClearanceText,
3855
+ adBadgeText,
3856
+ showTextArea,
3857
+ adBadgePaddingLeft,
3858
+ imageButtonBackgroundColor,
3859
+ cardOverlayBorderWidth,
3455
3860
  colors: colors4,
3456
3861
  isAdBadgeEnabled,
3457
3862
  paddingStyle,
@@ -3489,7 +3894,7 @@ function FeedBannerAdView({
3489
3894
  import_react_native44.Pressable,
3490
3895
  {
3491
3896
  accessibilityRole: "button",
3492
- onPress: () => onPress("202"),
3897
+ onPress: () => onPress(brandImageSlotId),
3493
3898
  onPressIn: handlePressIn,
3494
3899
  onPressOut: handlePressOut,
3495
3900
  style: styles.logoContainer,
@@ -3504,7 +3909,7 @@ function FeedBannerAdView({
3504
3909
  import_react_native44.Pressable,
3505
3910
  {
3506
3911
  accessibilityRole: "button",
3507
- onPress: () => onPress("103"),
3912
+ onPress: () => onPress(brandNameSlotId),
3508
3913
  onPressIn: handlePressIn,
3509
3914
  onPressOut: handlePressOut,
3510
3915
  children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
@@ -3518,15 +3923,23 @@ function FeedBannerAdView({
3518
3923
  )
3519
3924
  }
3520
3925
  ),
3521
- isAdBadgeEnabled ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native44.Text, { allowFontScaling: false, numberOfLines: 1, style: [styles.adBadge, { color: colors4.adBadge }], children: "\uAD11\uACE0" }) : null
3926
+ isAdBadgeEnabled ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3927
+ import_react_native44.Text,
3928
+ {
3929
+ allowFontScaling: false,
3930
+ numberOfLines: 1,
3931
+ style: [styles.adBadge, { color: colors4.adBadge, paddingLeft: adBadgePaddingLeft }],
3932
+ children: adBadgeText
3933
+ }
3934
+ ) : null
3522
3935
  ] })
3523
3936
  ] }),
3524
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react_native44.View, { style: styles.textArea, children: [
3937
+ showTextArea ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react_native44.View, { style: styles.textArea, children: [
3525
3938
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3526
3939
  import_react_native44.Pressable,
3527
3940
  {
3528
3941
  accessibilityRole: "button",
3529
- onPress: () => onPress("101"),
3942
+ onPress: () => onPress(titleSlotId),
3530
3943
  onPressIn: handlePressIn,
3531
3944
  onPressOut: handlePressOut,
3532
3945
  children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native44.Text, { allowFontScaling: false, style: [styles.title, { color: colors4.title }], children: title })
@@ -3536,23 +3949,26 @@ function FeedBannerAdView({
3536
3949
  import_react_native44.Pressable,
3537
3950
  {
3538
3951
  accessibilityRole: "button",
3539
- onPress: () => onPress("102"),
3952
+ onPress: () => onPress(subtitleSlotId),
3540
3953
  onPressIn: handlePressIn,
3541
3954
  onPressOut: handlePressOut,
3542
3955
  children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native44.Text, { allowFontScaling: false, style: [styles.subtitle, { color: colors4.subtitle }], children: subtitle })
3543
3956
  }
3544
3957
  )
3545
- ] })
3958
+ ] }) : null
3546
3959
  ] }),
3547
3960
  /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react_native44.View, { style: styles.card, children: [
3548
3961
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3549
3962
  import_react_native44.Pressable,
3550
3963
  {
3551
3964
  accessibilityRole: "button",
3552
- onPress: () => onPress("201"),
3965
+ onPress: () => onPress(mainImageSlotId),
3553
3966
  onPressIn: handlePressIn,
3554
3967
  onPressOut: handlePressOut,
3555
- style: styles.imageButton,
3968
+ style: [
3969
+ styles.imageButton,
3970
+ imageButtonBackgroundColor ? { backgroundColor: imageButtonBackgroundColor } : null
3971
+ ],
3556
3972
  children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native44.View, { style: styles.imageContainer, children: mainImageUri ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native44.Image, { source: { uri: mainImageUri }, style: styles.mainImage, resizeMode: "cover" }) : null })
3557
3973
  }
3558
3974
  ),
@@ -3560,7 +3976,7 @@ function FeedBannerAdView({
3560
3976
  import_react_native44.Pressable,
3561
3977
  {
3562
3978
  accessibilityRole: "button",
3563
- onPress: () => onPress("0"),
3979
+ onPress: () => onPress(ctaButtonSlotId),
3564
3980
  onPressIn: handlePressIn,
3565
3981
  onPressOut: handlePressOut,
3566
3982
  style: [styles.cta, { backgroundColor: resolvedCtaBackground }],
@@ -3570,7 +3986,18 @@ function FeedBannerAdView({
3570
3986
  ]
3571
3987
  }
3572
3988
  ),
3573
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native44.View, { style: [styles.cardOverlay, { borderColor: colors4.imageOverlayBorder }] })
3989
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3990
+ import_react_native44.View,
3991
+ {
3992
+ style: [
3993
+ styles.cardOverlay,
3994
+ {
3995
+ borderColor: colors4.imageOverlayBorder,
3996
+ borderWidth: cardOverlayBorderWidth ?? styles.cardOverlay.borderWidth
3997
+ }
3998
+ ]
3999
+ }
4000
+ )
3574
4001
  ] }),
3575
4002
  adClearanceText ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native44.Text, { allowFontScaling: false, style: [styles.adClearance, { color: colors4.adClearance }], children: adClearanceText }) : null
3576
4003
  ] })
@@ -3700,8 +4127,12 @@ var SQUIRCLE_PATH = "M0 17.352C0 3.564 3.564 0 17.352 0H18.648C32.436 0 36 3.564
3700
4127
  function ListBannerAdView({
3701
4128
  title,
3702
4129
  subtitle,
4130
+ titleSlotId,
4131
+ subtitleSlotId,
4132
+ iconImageSlotId,
3703
4133
  adClearanceText,
3704
4134
  adClearanceFontSize,
4135
+ adClearancePaddingRight,
3705
4136
  imageUri,
3706
4137
  paddingStyle,
3707
4138
  colors: colors4,
@@ -3737,7 +4168,7 @@ function ListBannerAdView({
3737
4168
  import_react_native45.Pressable,
3738
4169
  {
3739
4170
  accessibilityRole: "button",
3740
- onPress: () => onPress("202"),
4171
+ onPress: () => onPress(iconImageSlotId),
3741
4172
  onPressIn: handlePressIn,
3742
4173
  onPressOut: handlePressOut,
3743
4174
  style: styles2.iconWrapper,
@@ -3772,7 +4203,7 @@ function ListBannerAdView({
3772
4203
  import_react_native45.Pressable,
3773
4204
  {
3774
4205
  accessibilityRole: "button",
3775
- onPress: () => onPress("101"),
4206
+ onPress: () => onPress(titleSlotId),
3776
4207
  onPressIn: handlePressIn,
3777
4208
  onPressOut: handlePressOut,
3778
4209
  children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native45.Text, { allowFontScaling: false, style: [styles2.title, { color: colors4.title }], children: title })
@@ -3782,7 +4213,7 @@ function ListBannerAdView({
3782
4213
  import_react_native45.Pressable,
3783
4214
  {
3784
4215
  accessibilityRole: "button",
3785
- onPress: () => onPress("102"),
4216
+ onPress: () => onPress(subtitleSlotId),
3786
4217
  onPressIn: handlePressIn,
3787
4218
  onPressOut: handlePressOut,
3788
4219
  children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native45.Text, { allowFontScaling: false, style: [styles2.subtitle, { color: colors4.subtitle }], children: subtitle })
@@ -3799,7 +4230,8 @@ function ListBannerAdView({
3799
4230
  {
3800
4231
  color: colors4.adClearance,
3801
4232
  fontSize: adClearanceFontSize,
3802
- lineHeight: adClearanceFontSize * 1.2
4233
+ lineHeight: adClearanceFontSize * 1.2,
4234
+ paddingRight: adClearancePaddingRight
3803
4235
  }
3804
4236
  ],
3805
4237
  children: adClearanceText
@@ -3911,12 +4343,12 @@ function buildBannerEventPayload(slotId, adGroupId, ad) {
3911
4343
  }
3912
4344
  };
3913
4345
  }
3914
- function buildBannerErrorPayload(slotId, adGroupId, error) {
4346
+ function buildBannerErrorPayload(slotId, adGroupId, error, mediationId) {
3915
4347
  return {
3916
4348
  slotId,
3917
4349
  adGroupId,
3918
4350
  adMetadata: {},
3919
- error
4351
+ error: mediationId ? { ...error, mediationId } : error
3920
4352
  };
3921
4353
  }
3922
4354
  function buildNoFillPayload(slotId, adGroupId) {
@@ -3929,44 +4361,6 @@ function buildNoFillPayload(slotId, adGroupId) {
3929
4361
 
3930
4362
  // src/ads/inlineAd/InlineAd.tsx
3931
4363
  var import_jsx_runtime27 = require("react/jsx-runtime");
3932
- var themePalette = {
3933
- light: {
3934
- title: "#4e5968",
3935
- subtitle: "#6b7684",
3936
- adClearance: "#b0b8c1",
3937
- iconBg: "rgba(2,32,71,0.05)",
3938
- iconBorder: "rgba(2,32,71,0.05)"
3939
- },
3940
- dark: {
3941
- title: "rgba(253,253,255,0.75)",
3942
- subtitle: "rgba(248,248,255,0.6)",
3943
- adClearance: "rgba(242,242,255,0.47)",
3944
- iconBg: "#ffffff",
3945
- iconBorder: "rgba(217,217,255,0.11)"
3946
- }
3947
- };
3948
- var feedThemePalette = {
3949
- light: {
3950
- brandLogoBg: "rgba(2,32,71,0.05)",
3951
- brandLogoBorder: "rgba(2,32,71,0.05)",
3952
- brandName: "#6b7684",
3953
- adBadge: "#8b95a1",
3954
- title: "#333d4b",
3955
- subtitle: "#4e5968",
3956
- adClearance: "#8b95a1",
3957
- imageOverlayBorder: "rgba(2,32,71,0.05)"
3958
- },
3959
- dark: {
3960
- brandLogoBg: "#ffffff",
3961
- brandLogoBorder: "rgba(217,217,255,0.11)",
3962
- brandName: "#9e9ea4",
3963
- adBadge: "#7e7e87",
3964
- title: "#e4e4e5",
3965
- subtitle: "#c3c3c6",
3966
- adClearance: "#7e7e87",
3967
- imageOverlayBorder: "rgba(217,217,255,0.11)"
3968
- }
3969
- };
3970
4364
  function createError2(code, message) {
3971
4365
  return {
3972
4366
  code,
@@ -4044,8 +4438,6 @@ function InlineAd(props) {
4044
4438
  const resolvedTheme = selectedTheme === "auto" ? colorScheme === "dark" ? "dark" : "light" : selectedTheme;
4045
4439
  const resolvedTone = tone ?? DEFAULT_INLINE_AD_TONE;
4046
4440
  const resolvedVariant = variant ?? DEFAULT_INLINE_AD_VARIANT;
4047
- const colors4 = themePalette[resolvedTheme];
4048
- const feedColors = feedThemePalette[resolvedTheme];
4049
4441
  const backgroundColor = resolvedTone === "grey" ? resolvedTheme === "dark" ? "#101013" : "#f2f4f7" : resolvedTheme === "dark" ? "#17171c" : "#ffffff";
4050
4442
  callbacksRef.current = {
4051
4443
  onAdRendered,
@@ -4067,35 +4459,43 @@ function InlineAd(props) {
4067
4459
  }, []);
4068
4460
  (0, import_react31.useEffect)(() => {
4069
4461
  const normalizedAdGroupId = normalizeAdGroupId(adGroupId);
4462
+ const emitFailure = (error, responseContext) => {
4463
+ callbacksRef.current.onAdFailedToRender?.(
4464
+ buildBannerErrorPayload(slotIdRef.current, normalizedAdGroupId, error, responseContext?.mediationId)
4465
+ );
4466
+ trackBannerError({
4467
+ errorCode: error.code,
4468
+ errorMessage: error.message,
4469
+ adGroupId: normalizedAdGroupId,
4470
+ mediationId: responseContext?.mediationId,
4471
+ eventContextToken: responseContext?.eventContextToken,
4472
+ endpointError: responseContext?.errorEndpoint
4473
+ });
4474
+ };
4070
4475
  const loadAdRequest = () => {
4071
4476
  if (loadingRef.current) {
4072
4477
  return;
4073
4478
  }
4074
4479
  if (normalizedAdGroupId.length === 0) {
4075
- const error = createError2(ERROR_CODES.INVALID_SPACE, INVALID_AD_GROUP_ID_ERROR_MESSAGE);
4076
- callbacksRef.current.onAdFailedToRender?.(
4077
- buildBannerErrorPayload(slotIdRef.current, normalizedAdGroupId, error)
4078
- );
4480
+ emitFailure(createError2(ERROR_CODES.INVALID_SPACE, INVALID_AD_GROUP_ID_ERROR_MESSAGE));
4079
4481
  return;
4080
4482
  }
4081
4483
  loadingRef.current = true;
4082
4484
  loadAd(normalizedAdGroupId).then((result) => {
4083
4485
  if (!isMountedRef.current) return;
4486
+ const responseContext = extractAdTrackingContext(result.response);
4487
+ void fireResultTracking(result, normalizedAdGroupId, responseContext);
4084
4488
  if (result.type === "noFill") {
4085
4489
  callbacksRef.current.onNoFill?.(buildNoFillPayload(slotIdRef.current, normalizedAdGroupId));
4086
4490
  return;
4087
4491
  }
4088
4492
  if (result.type === "error") {
4089
- callbacksRef.current.onAdFailedToRender?.(
4090
- buildBannerErrorPayload(slotIdRef.current, normalizedAdGroupId, result.error)
4091
- );
4493
+ emitFailure(result.error, responseContext);
4092
4494
  return;
4093
4495
  }
4094
4496
  if (!isValidCreative(result.ad)) {
4095
4497
  const invalidError = createError2(ERROR_CODES.INTERNAL_ERROR, "Invalid creative payload");
4096
- callbacksRef.current.onAdFailedToRender?.(
4097
- buildBannerErrorPayload(slotIdRef.current, normalizedAdGroupId, invalidError)
4098
- );
4498
+ emitFailure(invalidError, responseContext);
4099
4499
  return;
4100
4500
  }
4101
4501
  if (result.responseExt?.refetchSeconds !== void 0) {
@@ -4112,21 +4512,29 @@ function InlineAd(props) {
4112
4512
  }
4113
4513
  const payload = buildBannerEventPayload(slotIdRef.current, normalizedAdGroupId, result.ad);
4114
4514
  eventPayloadRef.current = payload;
4515
+ const reportEventTrackingFailure = (failedUrls) => trackBannerError({
4516
+ errorCode: ERROR_CODES.NETWORK_ERROR,
4517
+ errorMessage: `eventTracking delivery failed (${failedUrls.length})`,
4518
+ adGroupId: normalizedAdGroupId,
4519
+ mediationId: responseContext.mediationId,
4520
+ eventContextToken: responseContext.eventContextToken,
4521
+ endpointError: responseContext.errorEndpoint
4522
+ });
4115
4523
  eventTrackerRef.current = new EventTracker(
4116
4524
  result.ad.eventTrackingUrls ?? [],
4117
4525
  result.ad.eventTypes ?? [],
4118
4526
  result.ad.eventPayload ?? "",
4119
4527
  result.requestId,
4120
- result.ad.creative?.id
4528
+ result.ad.creative?.id,
4529
+ void 0,
4530
+ reportEventTrackingFailure
4121
4531
  );
4122
4532
  setIsAdBadgeEnabled(result.responseExt?.isAdBadgeEnabled !== false);
4123
4533
  setAd(result.ad);
4124
4534
  }).catch((error) => {
4125
4535
  if (!isMountedRef.current) return;
4126
4536
  const adError = error instanceof Error ? createError2(ERROR_CODES.INTERNAL_ERROR, error.message) : createError2(ERROR_CODES.INTERNAL_ERROR, "Unknown error");
4127
- callbacksRef.current.onAdFailedToRender?.(
4128
- buildBannerErrorPayload(slotIdRef.current, normalizedAdGroupId, adError)
4129
- );
4537
+ emitFailure(adError);
4130
4538
  }).finally(() => {
4131
4539
  loadingRef.current = false;
4132
4540
  });
@@ -4165,7 +4573,9 @@ function InlineAd(props) {
4165
4573
  }
4166
4574
  const impressionKey = `${ad.requestId ?? "request"}:${ad.creative?.id ?? "creative"}`;
4167
4575
  const resolvedStyleId = ad.styleId || LIST_BANNER_STYLE_ID;
4168
- const defaultPaddingValue = resolvedStyleId === LIST_BANNER_STYLE_ID ? DEFAULT_INLINE_AD_PADDING_BANNER : DEFAULT_INLINE_AD_PADDING_NATIVE_IMAGE;
4576
+ const listBannerConfig = resolveListBannerRenderConfig(ad.creativeVersion, resolvedTheme);
4577
+ const feedBannerConfig = resolveFeedBannerRenderConfig(ad.creativeVersion, resolvedTheme);
4578
+ const defaultPaddingValue = resolvedStyleId === LIST_BANNER_STYLE_ID ? listBannerConfig.defaultPaddingValue : feedBannerConfig.defaultPaddingValue;
4169
4579
  const paddingStyle = resolvePaddingStyle(defaultPaddingValue);
4170
4580
  const isListBanner = String(resolvedStyleId) === LIST_BANNER_STYLE_ID;
4171
4581
  const isFeedBanner = String(resolvedStyleId) === FEED_BANNER_STYLE_ID;
@@ -4261,11 +4671,15 @@ function InlineAd(props) {
4261
4671
  {
4262
4672
  title: listCreative.title,
4263
4673
  subtitle: subtitleText,
4674
+ titleSlotId: listBannerConfig.titleSlotId,
4675
+ subtitleSlotId: listBannerConfig.subtitleSlotId,
4676
+ iconImageSlotId: listBannerConfig.iconImageSlotId,
4264
4677
  adClearanceText,
4265
4678
  adClearanceFontSize,
4679
+ adClearancePaddingRight: listBannerConfig.adClearancePaddingRight,
4266
4680
  imageUri,
4267
4681
  paddingStyle,
4268
- colors: colors4,
4682
+ colors: listBannerConfig.colors,
4269
4683
  onPress: handleClick
4270
4684
  }
4271
4685
  ) : null,
@@ -4274,6 +4688,12 @@ function InlineAd(props) {
4274
4688
  {
4275
4689
  brandName: feedCreative.brandName,
4276
4690
  brandLogoUri,
4691
+ brandImageSlotId: feedBannerConfig.brandImageSlotId,
4692
+ brandNameSlotId: feedBannerConfig.brandNameSlotId,
4693
+ titleSlotId: feedBannerConfig.titleSlotId,
4694
+ subtitleSlotId: feedBannerConfig.subtitleSlotId,
4695
+ mainImageSlotId: feedBannerConfig.mainImageSlotId,
4696
+ ctaButtonSlotId: feedBannerConfig.ctaButtonSlotId,
4277
4697
  title: feedCreative.title,
4278
4698
  subtitle: feedCreative.subTitle,
4279
4699
  mainImageUri,
@@ -4281,7 +4701,12 @@ function InlineAd(props) {
4281
4701
  ctaTextColor: feedCreative.ctaTextColor,
4282
4702
  ctaBackgroundColor: feedCreative.ctaBackgroundColor,
4283
4703
  adClearanceText,
4284
- colors: feedColors,
4704
+ adBadgeText: feedBannerConfig.adBadgeText,
4705
+ showTextArea: feedBannerConfig.showTextArea,
4706
+ adBadgePaddingLeft: feedBannerConfig.adBadgePaddingLeft,
4707
+ imageButtonBackgroundColor: feedBannerConfig.imageButtonBackgroundColor,
4708
+ cardOverlayBorderWidth: feedBannerConfig.cardOverlayBorderWidth,
4709
+ colors: feedBannerConfig.colors,
4285
4710
  isAdBadgeEnabled,
4286
4711
  paddingStyle,
4287
4712
  onPress: handleClick