@apps-in-toss/devtools 3.2.0-beta.0 → 3.3.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/CHANGELOG.md +2 -25
- package/dist/mock/2x.d.ts +34 -44
- package/dist/mock/2x.js +43 -39
- package/dist/mock/3x.d.ts +36 -20
- package/dist/mock/3x.js +137 -116
- package/dist/mock/index.d.ts +36 -20
- package/dist/mock/index.js +137 -116
- package/dist/panel/index.js +18 -38
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,38 +1,15 @@
|
|
|
1
1
|
# @apps-in-toss/devtools
|
|
2
2
|
|
|
3
|
-
## 3.2.0
|
|
3
|
+
## 3.2.0
|
|
4
4
|
|
|
5
5
|
### Minor Changes
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
|
|
9
|
-
### Patch Changes
|
|
10
|
-
|
|
11
|
-
- 광고 노출 실패 이벤트에 `reason` 응답 타입을 추가해요.
|
|
12
|
-
- Updated dependencies
|
|
13
|
-
- @apps-in-toss/web-framework@3.2.0-beta.0
|
|
7
|
+
- 1622a0e: 로컬 저장소의 여러 값을 한 번에 조회하고 저장하는 `Storage.getItems`와 `Storage.setItems` API를 추가해요.
|
|
14
8
|
|
|
15
9
|
## 3.1.1
|
|
16
10
|
|
|
17
11
|
## 3.1.0
|
|
18
12
|
|
|
19
|
-
## 3.1.0-beta.1
|
|
20
|
-
|
|
21
|
-
### Patch Changes
|
|
22
|
-
|
|
23
|
-
- d633263: failedToShow인 경우 reason 응답 타입 추가
|
|
24
|
-
|
|
25
|
-
## 3.1.0-beta.0
|
|
26
|
-
|
|
27
|
-
### Minor Changes
|
|
28
|
-
|
|
29
|
-
- 59b4b13: iac 앱브릿지 추가
|
|
30
|
-
|
|
31
|
-
### Patch Changes
|
|
32
|
-
|
|
33
|
-
- Updated dependencies [59b4b13]
|
|
34
|
-
- @apps-in-toss/web-framework@3.1.0-beta.0
|
|
35
|
-
|
|
36
13
|
## 3.0.5
|
|
37
14
|
|
|
38
15
|
## 3.0.4
|
package/dist/mock/2x.d.ts
CHANGED
|
@@ -131,39 +131,6 @@ declare const showFullScreenAd: ((args: {
|
|
|
131
131
|
}) => () => void) & {
|
|
132
132
|
isSupported: () => boolean;
|
|
133
133
|
};
|
|
134
|
-
declare const Ads: {
|
|
135
|
-
showTossAdOrShoppingAds: ((args: {
|
|
136
|
-
options: {
|
|
137
|
-
spaceUnitId: string;
|
|
138
|
-
adSpaceId: string;
|
|
139
|
-
};
|
|
140
|
-
onEvent: (event: {
|
|
141
|
-
type: string;
|
|
142
|
-
data?: {
|
|
143
|
-
unitType: string;
|
|
144
|
-
unitAmount: number;
|
|
145
|
-
};
|
|
146
|
-
}) => void;
|
|
147
|
-
onError: (error: unknown) => void;
|
|
148
|
-
}) => () => void) & {
|
|
149
|
-
isSupported: () => boolean;
|
|
150
|
-
};
|
|
151
|
-
showTossShoppingAds: ((args: {
|
|
152
|
-
options: {
|
|
153
|
-
adSpaceId: string;
|
|
154
|
-
};
|
|
155
|
-
onEvent: (event: {
|
|
156
|
-
type: string;
|
|
157
|
-
data?: {
|
|
158
|
-
unitType: string;
|
|
159
|
-
unitAmount: number;
|
|
160
|
-
};
|
|
161
|
-
}) => void;
|
|
162
|
-
onError: (error: unknown) => void;
|
|
163
|
-
}) => () => void) & {
|
|
164
|
-
isSupported: () => boolean;
|
|
165
|
-
};
|
|
166
|
-
};
|
|
167
134
|
//#endregion
|
|
168
135
|
//#region src/mock/analytics/index.d.ts
|
|
169
136
|
/**
|
|
@@ -512,16 +479,6 @@ declare const openPDFViewer: ((params: OpenPDFViewerParams) => Promise<OpenPDFVi
|
|
|
512
479
|
};
|
|
513
480
|
//#endregion
|
|
514
481
|
//#region src/mock/device/storage.d.ts
|
|
515
|
-
/**
|
|
516
|
-
* Storage mock
|
|
517
|
-
* localStorage에 `__ait_storage:` prefix로 저장하여 앱 자체 localStorage와 분리
|
|
518
|
-
*
|
|
519
|
-
* 실기기(2.x×iOS) capture는 `setItem`/`removeItem`/`clearItems` 세 메서드가
|
|
520
|
-
* `undefined`가 아니라 `null`로 resolve됨을 보였다(devtools#770). 원본 SDK 타입
|
|
521
|
-
* 선언은 여전히 `Promise<void>`이므로 시그니처는 그대로 두고, 런타임 반환값만
|
|
522
|
-
* `null`로 캐스트해 실측과 동치시킨다 — Analytics·setClipboardText와 같은 처리(#775).
|
|
523
|
-
* `getItem`은 이미 `string | null`이라 실측과 일치하므로 손대지 않는다.
|
|
524
|
-
*/
|
|
525
482
|
declare const Storage: {
|
|
526
483
|
getItem: (key: string) => Promise<string | null>;
|
|
527
484
|
setItem: (key: string, value: string) => Promise<void>;
|
|
@@ -647,6 +604,39 @@ declare const requestTossPayPaysBilling: ((options: {
|
|
|
647
604
|
isSupported: () => true;
|
|
648
605
|
};
|
|
649
606
|
//#endregion
|
|
607
|
+
//#region src/mock/viral/index.d.ts
|
|
608
|
+
/** 바이럴 캠페인 조회 mock이에요. */
|
|
609
|
+
declare function getViralCampaign(params: {
|
|
610
|
+
campaignId: string;
|
|
611
|
+
}): Promise<{
|
|
612
|
+
campaignId: string;
|
|
613
|
+
benefitName: string;
|
|
614
|
+
display: {
|
|
615
|
+
title: string | null;
|
|
616
|
+
benefitText: string | null;
|
|
617
|
+
conditionText: string | null;
|
|
618
|
+
ctaText: string | null;
|
|
619
|
+
};
|
|
620
|
+
active: boolean;
|
|
621
|
+
campaignStatus: "WAITING" | "IN_PROGRESS" | "ENDED";
|
|
622
|
+
participationAvailable: boolean;
|
|
623
|
+
participationUnavailableReason: "INACTIVE" | "NOT_STARTED" | "ENDED" | "ALL_RULES_ACHIEVED" | null;
|
|
624
|
+
rules: Array<{
|
|
625
|
+
ruleId: string;
|
|
626
|
+
ruleKey: string;
|
|
627
|
+
revision: number;
|
|
628
|
+
title: string;
|
|
629
|
+
currentValue: number;
|
|
630
|
+
targetValue: number;
|
|
631
|
+
status: "IN_PROGRESS" | "ACHIEVED" | "EXPIRED";
|
|
632
|
+
achievedAt: string | null;
|
|
633
|
+
}>;
|
|
634
|
+
}>;
|
|
635
|
+
/** 바이럴 캠페인 공유 mock이에요. */
|
|
636
|
+
declare function shareViralCampaign(params: {
|
|
637
|
+
campaignId: string;
|
|
638
|
+
}): Promise<void>;
|
|
639
|
+
//#endregion
|
|
650
640
|
//#region src/mock/navigation/index.d.ts
|
|
651
641
|
declare function closeView(): Promise<void>;
|
|
652
642
|
declare function openURL(url: string): Promise<void>;
|
|
@@ -1186,4 +1176,4 @@ declare function listUserPresets(): MockPreset[];
|
|
|
1186
1176
|
declare function saveUserPreset(label: string, state: MockPresetState, description?: string): MockPreset;
|
|
1187
1177
|
declare function deleteUserPreset(id: string): void;
|
|
1188
1178
|
//#endregion
|
|
1189
|
-
export { Accuracy,
|
|
1179
|
+
export { Accuracy, type AitDevtoolsState, Analytics, type AnalyticsLogEntry, type ConsentedUserData, type ConsentedUserDataKey, type DeclaredAgeRange, type DeviceApiMode, type DeviceModes, FetchAlbumPhotosPermissionError, FetchContactsPermissionError, GetClipboardTextPermissionError, GetCurrentLocationPermissionError, GoogleAdMob, type HapticFeedbackType, IAP, type IapNextResult, type LocationCoords, type MockContact, type MockData, type MockIapProduct, type MockLocation, type MockPreset, type MockPresetState, type NetworkStatus, OpenCameraPermissionError, type OperationalEnvironment, PermissionError, type PermissionName, type PermissionStatus, type PlatformOS, type Primitive, SafeAreaInsets, type SafeAreaInsets$1 as SafeAreaInsetsType, SetClipboardTextPermissionError, StartUpdateLocationPermissionError, Storage, TossAds, aitState, appLogin, applyPreset, appsInTossEvent, appsInTossSignTossCert, builtInPresets, captureCurrentState, checkoutPayment, closeView, contactsViral, createAsyncBridge, createConstantBridge, createEventBridge, deleteUserPreset, env, eventLog, fetchAlbumItems, fetchAlbumPhotos, fetchContacts, generateHapticFeedback, getAnonymousKey, getAppsInTossGlobals, getClipboardText, getConsentedUserData, getCurrentLocation, getDeclaredAgeRange, getDefaultPlaceholderImages, getDeviceId, getGameCenterGameProfile, getGroupId, getIsTossLoginIntegratedService, getLocale, getNetworkStatus, getOperationalEnvironment, getPermission, getPlatformOS, getSafeAreaInsets, getSchemeUri, getServerTime, getTossAppVersion, getTossShareLink, getUserKeyForGame, getViralCampaign, graniteEvent, grantPromotionReward, grantPromotionRewardForGame, isMinVersionSupported, listUserPresets, loadFullScreenAd, matchesPreset, onVisibilityChangedByTransparentServiceWeb, openCamera, openGameCenterLeaderboard, openPDFViewer, openPermissionDialog, openURL, partner, requestNotificationAgreement, requestPermission, requestReview, requestTossPayPaysBilling, saveBase64Data, saveUserPreset, setClipboardText, setDeviceOrientation, setIosSwipeGestureEnabled, setScreenAwakeMode, setSecureScreen, share, shareViralCampaign, showFullScreenAd, startUpdateLocation, submitGameCenterLeaderBoardScore, tdsEvent };
|
package/dist/mock/2x.js
CHANGED
|
@@ -768,39 +768,6 @@ const showFullScreenAd = withIsSupported(observe("showFullScreenAd", "faithful",
|
|
|
768
768
|
setTimeout(() => args.onEvent({ type: "dismissed" }), 1500);
|
|
769
769
|
return () => {};
|
|
770
770
|
}));
|
|
771
|
-
const Ads = createMockProxy("Ads", {
|
|
772
|
-
showTossAdOrShoppingAds: withIsSupported(observe("Ads.showTossAdOrShoppingAds", "faithful", (args) => {
|
|
773
|
-
if (!aitState.state.ads.isLoaded) {
|
|
774
|
-
args.onError(/* @__PURE__ */ new Error("Ad not loaded"));
|
|
775
|
-
return () => {};
|
|
776
|
-
}
|
|
777
|
-
const { rewardUnitType, rewardAmount } = aitState.state.ads;
|
|
778
|
-
setTimeout(() => args.onEvent({
|
|
779
|
-
type: "userEarnedReward",
|
|
780
|
-
data: {
|
|
781
|
-
unitType: rewardUnitType,
|
|
782
|
-
unitAmount: rewardAmount
|
|
783
|
-
}
|
|
784
|
-
}), 1e3);
|
|
785
|
-
setTimeout(() => {
|
|
786
|
-
args.onEvent({ type: "dismissed" });
|
|
787
|
-
aitState.patch("ads", { isLoaded: false });
|
|
788
|
-
}, 1500);
|
|
789
|
-
return () => {};
|
|
790
|
-
})),
|
|
791
|
-
showTossShoppingAds: withIsSupported(observe("Ads.showTossShoppingAds", "faithful", (args) => {
|
|
792
|
-
const { rewardUnitType, rewardAmount } = aitState.state.ads;
|
|
793
|
-
setTimeout(() => args.onEvent({
|
|
794
|
-
type: "userEarnedReward",
|
|
795
|
-
data: {
|
|
796
|
-
unitType: rewardUnitType,
|
|
797
|
-
unitAmount: rewardAmount
|
|
798
|
-
}
|
|
799
|
-
}), 1e3);
|
|
800
|
-
setTimeout(() => args.onEvent({ type: "dismissed" }), 1500);
|
|
801
|
-
return () => {};
|
|
802
|
-
}))
|
|
803
|
-
});
|
|
804
771
|
//#endregion
|
|
805
772
|
//#region src/mock/analytics/index.ts
|
|
806
773
|
/**
|
|
@@ -1611,20 +1578,21 @@ const openPDFViewer = Object.assign(_openPDFViewerImpl, { isSupported: () => tru
|
|
|
1611
1578
|
* `null`로 캐스트해 실측과 동치시킨다 — Analytics·setClipboardText와 같은 처리(#775).
|
|
1612
1579
|
* `getItem`은 이미 `string | null`이라 실측과 일치하므로 손대지 않는다.
|
|
1613
1580
|
*/
|
|
1581
|
+
const STORAGE_PREFIX = "__ait_storage:";
|
|
1614
1582
|
const Storage = createMockProxy("Storage", {
|
|
1615
1583
|
getItem: async (key) => {
|
|
1616
|
-
return localStorage.getItem(
|
|
1584
|
+
return localStorage.getItem(`${STORAGE_PREFIX}${key}`);
|
|
1617
1585
|
},
|
|
1618
1586
|
setItem: async (key, value) => {
|
|
1619
|
-
localStorage.setItem(
|
|
1587
|
+
localStorage.setItem(`${STORAGE_PREFIX}${key}`, value);
|
|
1620
1588
|
return null;
|
|
1621
1589
|
},
|
|
1622
1590
|
removeItem: async (key) => {
|
|
1623
|
-
localStorage.removeItem(
|
|
1591
|
+
localStorage.removeItem(`${STORAGE_PREFIX}${key}`);
|
|
1624
1592
|
return null;
|
|
1625
1593
|
},
|
|
1626
1594
|
clearItems: async () => {
|
|
1627
|
-
const keys = Object.keys(localStorage).filter((k) => k.startsWith(
|
|
1595
|
+
const keys = Object.keys(localStorage).filter((k) => k.startsWith(STORAGE_PREFIX));
|
|
1628
1596
|
for (const k of keys) localStorage.removeItem(k);
|
|
1629
1597
|
return null;
|
|
1630
1598
|
}
|
|
@@ -1964,6 +1932,40 @@ function getSafeAreaInsets() {
|
|
|
1964
1932
|
return Promise.resolve({ ...aitState.state.safeAreaInsets });
|
|
1965
1933
|
}
|
|
1966
1934
|
//#endregion
|
|
1935
|
+
//#region src/mock/viral/index.ts
|
|
1936
|
+
/** 바이럴 캠페인 조회 mock이에요. */
|
|
1937
|
+
async function getViralCampaign(params) {
|
|
1938
|
+
console.log("[@apps-in-toss/devtools] getViralCampaign:", params.campaignId);
|
|
1939
|
+
return {
|
|
1940
|
+
campaignId: params.campaignId,
|
|
1941
|
+
benefitName: "mock-benefit",
|
|
1942
|
+
display: {
|
|
1943
|
+
title: "바이럴 캠페인 제목",
|
|
1944
|
+
benefitText: "친구를 초대하면 리워드를 받아요",
|
|
1945
|
+
conditionText: "3명 초대 시 달성",
|
|
1946
|
+
ctaText: "공유하기"
|
|
1947
|
+
},
|
|
1948
|
+
active: true,
|
|
1949
|
+
campaignStatus: "IN_PROGRESS",
|
|
1950
|
+
participationAvailable: true,
|
|
1951
|
+
participationUnavailableReason: null,
|
|
1952
|
+
rules: [{
|
|
1953
|
+
ruleId: "rule-1",
|
|
1954
|
+
ruleKey: "invite",
|
|
1955
|
+
revision: 1,
|
|
1956
|
+
title: "친구 3명 초대",
|
|
1957
|
+
currentValue: 1,
|
|
1958
|
+
targetValue: 3,
|
|
1959
|
+
status: "IN_PROGRESS",
|
|
1960
|
+
achievedAt: null
|
|
1961
|
+
}]
|
|
1962
|
+
};
|
|
1963
|
+
}
|
|
1964
|
+
/** 바이럴 캠페인 공유 mock이에요. */
|
|
1965
|
+
async function shareViralCampaign(params) {
|
|
1966
|
+
console.log("[@apps-in-toss/devtools] shareViralCampaign:", params.campaignId);
|
|
1967
|
+
}
|
|
1968
|
+
//#endregion
|
|
1967
1969
|
//#region src/mock/bridge-factories.ts
|
|
1968
1970
|
/** Generic bridge escape hatches exposed by both SDK lines. */
|
|
1969
1971
|
const asyncBridgeRegistry = {
|
|
@@ -1977,11 +1979,13 @@ const asyncBridgeRegistry = {
|
|
|
1977
1979
|
getDeclaredAgeRange,
|
|
1978
1980
|
getNetworkStatus,
|
|
1979
1981
|
getServerTime,
|
|
1982
|
+
getViralCampaign,
|
|
1980
1983
|
openPDFViewer,
|
|
1981
1984
|
openURL,
|
|
1982
1985
|
requestReview,
|
|
1983
1986
|
saveBase64Data,
|
|
1984
|
-
share
|
|
1987
|
+
share,
|
|
1988
|
+
shareViralCampaign
|
|
1985
1989
|
};
|
|
1986
1990
|
function createAsyncBridge(method) {
|
|
1987
1991
|
return async (...args) => {
|
|
@@ -2419,4 +2423,4 @@ function captureCurrentState(snapshot) {
|
|
|
2419
2423
|
};
|
|
2420
2424
|
}
|
|
2421
2425
|
//#endregion
|
|
2422
|
-
export { Accuracy,
|
|
2426
|
+
export { Accuracy, Analytics, FetchAlbumPhotosPermissionError, FetchContactsPermissionError, GetClipboardTextPermissionError, GetCurrentLocationPermissionError, GoogleAdMob, IAP, OpenCameraPermissionError, PermissionError, SafeAreaInsets, SetClipboardTextPermissionError, StartUpdateLocationPermissionError, Storage, TossAds, aitState, appLogin, applyPreset, appsInTossEvent, appsInTossSignTossCert, builtInPresets, captureCurrentState, checkoutPayment, closeView, contactsViral, createAsyncBridge, createConstantBridge, createEventBridge, deleteUserPreset, env, eventLog, fetchAlbumItems, fetchAlbumPhotos, fetchContacts, generateHapticFeedback, getAnonymousKey, getAppsInTossGlobals, getClipboardText, getConsentedUserData, getCurrentLocation, getDeclaredAgeRange, getDefaultPlaceholderImages, getDeviceId, getGameCenterGameProfile, getGroupId, getIsTossLoginIntegratedService, getLocale, getNetworkStatus, getOperationalEnvironment, getPermission, getPlatformOS, getSafeAreaInsets, getSchemeUri, getServerTime, getTossAppVersion, getTossShareLink, getUserKeyForGame, getViralCampaign, graniteEvent, grantPromotionReward, grantPromotionRewardForGame, isMinVersionSupported, listUserPresets, loadFullScreenAd, matchesPreset, onVisibilityChangedByTransparentServiceWeb, openCamera, openGameCenterLeaderboard, openPDFViewer, openPermissionDialog, openURL, partner, requestNotificationAgreement, requestPermission, requestReview, requestTossPayPaysBilling, saveBase64Data, saveUserPreset, setClipboardText, setDeviceOrientation, setIosSwipeGestureEnabled, setScreenAwakeMode, setSecureScreen, share, shareViralCampaign, showFullScreenAd, startUpdateLocation, submitGameCenterLeaderBoardScore, tdsEvent };
|
package/dist/mock/3x.d.ts
CHANGED
|
@@ -156,7 +156,6 @@ declare const isMinVersionSupported: typeof SDK.isMinVersionSupported;
|
|
|
156
156
|
declare const GoogleAdMob: typeof SDK.GoogleAdMob;
|
|
157
157
|
declare const loadFullScreenAd: typeof SDK.loadFullScreenAd;
|
|
158
158
|
declare const showFullScreenAd: typeof SDK.showFullScreenAd;
|
|
159
|
-
declare const Ads: typeof SDK.Ads;
|
|
160
159
|
declare const IAP: typeof SDK.IAP;
|
|
161
160
|
declare const Analytics: typeof SDK.Analytics;
|
|
162
161
|
declare const Clipboard: typeof SDK.Clipboard;
|
|
@@ -194,9 +193,11 @@ declare const Review: typeof SDK.Review;
|
|
|
194
193
|
declare const SafeArea: typeof SDK.SafeArea;
|
|
195
194
|
declare const Screen: typeof SDK.Screen;
|
|
196
195
|
declare const Share: typeof SDK.Share;
|
|
196
|
+
declare const Storage: typeof SDK.Storage;
|
|
197
197
|
declare const TossAuth: typeof SDK.TossAuth;
|
|
198
198
|
declare const TossPay: typeof SDK.TossPay;
|
|
199
199
|
declare const User: typeof SDK.User;
|
|
200
|
+
declare const Viral: typeof SDK.Viral;
|
|
200
201
|
//#endregion
|
|
201
202
|
//#region src/mock/ads/index.d.ts
|
|
202
203
|
declare const TossAds: {
|
|
@@ -557,24 +558,6 @@ declare const startUpdateLocation: ((eventParams: StartUpdateLocationEventParams
|
|
|
557
558
|
openPermissionDialog: () => Promise<"allowed" | "denied">;
|
|
558
559
|
};
|
|
559
560
|
//#endregion
|
|
560
|
-
//#region src/mock/device/storage.d.ts
|
|
561
|
-
/**
|
|
562
|
-
* Storage mock
|
|
563
|
-
* localStorage에 `__ait_storage:` prefix로 저장하여 앱 자체 localStorage와 분리
|
|
564
|
-
*
|
|
565
|
-
* 실기기(2.x×iOS) capture는 `setItem`/`removeItem`/`clearItems` 세 메서드가
|
|
566
|
-
* `undefined`가 아니라 `null`로 resolve됨을 보였다(devtools#770). 원본 SDK 타입
|
|
567
|
-
* 선언은 여전히 `Promise<void>`이므로 시그니처는 그대로 두고, 런타임 반환값만
|
|
568
|
-
* `null`로 캐스트해 실측과 동치시킨다 — Analytics·setClipboardText와 같은 처리(#775).
|
|
569
|
-
* `getItem`은 이미 `string | null`이라 실측과 일치하므로 손대지 않는다.
|
|
570
|
-
*/
|
|
571
|
-
declare const Storage: {
|
|
572
|
-
getItem: (key: string) => Promise<string | null>;
|
|
573
|
-
setItem: (key: string, value: string) => Promise<void>;
|
|
574
|
-
removeItem: (key: string) => Promise<void>;
|
|
575
|
-
clearItems: () => Promise<void>;
|
|
576
|
-
};
|
|
577
|
-
//#endregion
|
|
578
561
|
//#region src/mock/iap/index.d.ts
|
|
579
562
|
declare function checkoutPayment(options: {
|
|
580
563
|
params: {
|
|
@@ -585,6 +568,39 @@ declare function checkoutPayment(options: {
|
|
|
585
568
|
reason?: string;
|
|
586
569
|
}>;
|
|
587
570
|
//#endregion
|
|
571
|
+
//#region src/mock/viral/index.d.ts
|
|
572
|
+
/** 바이럴 캠페인 조회 mock이에요. */
|
|
573
|
+
declare function getViralCampaign(params: {
|
|
574
|
+
campaignId: string;
|
|
575
|
+
}): Promise<{
|
|
576
|
+
campaignId: string;
|
|
577
|
+
benefitName: string;
|
|
578
|
+
display: {
|
|
579
|
+
title: string | null;
|
|
580
|
+
benefitText: string | null;
|
|
581
|
+
conditionText: string | null;
|
|
582
|
+
ctaText: string | null;
|
|
583
|
+
};
|
|
584
|
+
active: boolean;
|
|
585
|
+
campaignStatus: "WAITING" | "IN_PROGRESS" | "ENDED";
|
|
586
|
+
participationAvailable: boolean;
|
|
587
|
+
participationUnavailableReason: "INACTIVE" | "NOT_STARTED" | "ENDED" | "ALL_RULES_ACHIEVED" | null;
|
|
588
|
+
rules: Array<{
|
|
589
|
+
ruleId: string;
|
|
590
|
+
ruleKey: string;
|
|
591
|
+
revision: number;
|
|
592
|
+
title: string;
|
|
593
|
+
currentValue: number;
|
|
594
|
+
targetValue: number;
|
|
595
|
+
status: "IN_PROGRESS" | "ACHIEVED" | "EXPIRED";
|
|
596
|
+
achievedAt: string | null;
|
|
597
|
+
}>;
|
|
598
|
+
}>;
|
|
599
|
+
/** 바이럴 캠페인 공유 mock이에요. */
|
|
600
|
+
declare function shareViralCampaign(params: {
|
|
601
|
+
campaignId: string;
|
|
602
|
+
}): Promise<void>;
|
|
603
|
+
//#endregion
|
|
588
604
|
//#region src/mock/navigation/index.d.ts
|
|
589
605
|
declare function closeView(): Promise<void>;
|
|
590
606
|
declare function openURL(url: string): Promise<void>;
|
|
@@ -1051,4 +1067,4 @@ declare function listUserPresets(): MockPreset[];
|
|
|
1051
1067
|
declare function saveUserPreset(label: string, state: MockPresetState, description?: string): MockPreset;
|
|
1052
1068
|
declare function deleteUserPreset(id: string): void;
|
|
1053
1069
|
//#endregion
|
|
1054
|
-
export { Accuracy,
|
|
1070
|
+
export { Accuracy, type AitDevtoolsState, Analytics, type AnalyticsLogEntry, Clipboard, type ConsentedUserData, type ConsentedUserDataKey, type DeclaredAgeRange, Device, type DeviceApiMode, type DeviceModes, Environment, FetchAlbumPhotosPermissionError, FetchContactsPermissionError, File, Game, GetClipboardTextPermissionError, GetCurrentLocationPermissionError, GoogleAdMob, type HapticFeedbackType, IAP, type IapNextResult, type LocationCoords, Migration, type MockContact, type MockData, type MockIapProduct, type MockLocation, type MockPreset, type MockPresetState, type NetworkStatus, Notification, OpenCameraPermissionError, type OperationalEnvironment, PermissionError, type PermissionName, type PermissionStatus, type PlatformOS, type Primitive, Promotion, Review, SafeArea, SafeAreaInsets, type SafeAreaInsets$1 as SafeAreaInsetsType, Screen, SetClipboardTextPermissionError, Share, StartUpdateLocationPermissionError, Storage, TossAds, TossAuth, TossPay, User, Viral, aitState, appLogin, applyPreset, appsInTossEvent, appsInTossSignTossCert, builtInPresets, captureCurrentState, checkoutPayment, closeView, contactsViral, createAsyncBridge, createConstantBridge, createEventBridge, deleteUserPreset, env, eventLog, fetchAlbumItems, fetchAlbumPhotos, fetchContacts, generateHapticFeedback, getAnonymousKey, getAppsInTossGlobals, getClipboardText, getConsentedUserData, getCurrentLocation, getDeclaredAgeRange, getDefaultPlaceholderImages, getDeviceId, getGameCenterGameProfile, getGroupId, getIsTossLoginIntegratedService, getLocale, getNetworkStatus, getOperationalEnvironment, getPermission, getPlatformOS, getSafeAreaInsets, getSchemeUri, getServerTime, getTossAppVersion, getTossShareLink, getUserKeyForGame, getViralCampaign, graniteEvent, grantPromotionReward, grantPromotionRewardForGame, isMinVersionSupported, listUserPresets, loadFullScreenAd, matchesPreset, onVisibilityChangedByTransparentServiceWeb, openCamera, openGameCenterLeaderboard, openPDFViewer, openPermissionDialog, openURL, partner, requestNotificationAgreement, requestPermission, requestReview, requestTossPayPaysBilling, saveBase64Data, saveUserPreset, setClipboardText, setDeviceOrientation, setIosSwipeGestureEnabled, setScreenAwakeMode, setSecureScreen, share, shareViralCampaign, showFullScreenAd, startUpdateLocation, submitGameCenterLeaderBoardScore, tdsEvent };
|
package/dist/mock/3x.js
CHANGED
|
@@ -328,6 +328,86 @@ if (!globalRef[SINGLETON_KEY]) globalRef[SINGLETON_KEY] = new AitStateManager();
|
|
|
328
328
|
const aitState = globalRef[SINGLETON_KEY];
|
|
329
329
|
if (typeof window !== "undefined") window.__ait = aitState;
|
|
330
330
|
//#endregion
|
|
331
|
+
//#region src/mock/proxy.ts
|
|
332
|
+
/**
|
|
333
|
+
* 미구현 API용 Proxy 트립와이어.
|
|
334
|
+
*
|
|
335
|
+
* 미구현 프로퍼티에 접근하면 throw한다. 이는 "devtools에서는 멀쩡히 돌지만
|
|
336
|
+
* 실 SDK에선 실제로 동작하는" 시나리오를 차단하기 위한 의도적 선택이다.
|
|
337
|
+
* mock이 미구현인 API는 실 SDK에서는 존재할 수 있고, 사용자가 이를 인지하지
|
|
338
|
+
* 못한 채 개발을 이어가면 배포 시점에 놀라게 된다. 에러 메시지에 이슈 URL을
|
|
339
|
+
* 포함해 사용자가 mock 누락을 제보할 수 있게 한다.
|
|
340
|
+
*
|
|
341
|
+
* ## KNOWN_UNIMPLEMENTED 정책
|
|
342
|
+
* SDK에 존재하는 것으로 알려져 있으나 현재 mock이 없는 API 이름만 이 집합에 둔다.
|
|
343
|
+
* 이 경우에만 throw 대신 🔴 inert no-op을 반환하고 sdkCallLog에 기록한다.
|
|
344
|
+
* 완전히 미지의 이름은 여전히 throw — "잘 되는 척" 방지.
|
|
345
|
+
*/
|
|
346
|
+
const ISSUES_URL = "https://github.com/apps-in-toss-community/devtools/issues";
|
|
347
|
+
/**
|
|
348
|
+
* SDK에 존재하나 mock이 아직 없는 것으로 확인된 이름 목록.
|
|
349
|
+
* 새 API가 SDK에 추가되면 여기에 추가하고 별도 PR에서 mock 구현으로 이동한다.
|
|
350
|
+
* 확인되지 않은 이름은 절대 여기에 추가하지 않는다 — throw가 더 안전하다.
|
|
351
|
+
*/
|
|
352
|
+
const KNOWN_UNIMPLEMENTED = /* @__PURE__ */ new Set([]);
|
|
353
|
+
function createMockProxy(moduleName, implementations) {
|
|
354
|
+
return new Proxy(implementations, { get(target, prop) {
|
|
355
|
+
if (typeof prop === "symbol") return void 0;
|
|
356
|
+
if (prop in target) return target[prop];
|
|
357
|
+
const name = String(prop);
|
|
358
|
+
if (KNOWN_UNIMPLEMENTED.has(name)) return (...args) => {
|
|
359
|
+
console.warn(`[@apps-in-toss/devtools] ${moduleName}.${name} is known-unimplemented (🔴 inert). Returning undefined. Please file or upvote an issue: ${ISSUES_URL}`);
|
|
360
|
+
aitState.logSdkCall({
|
|
361
|
+
method: `${moduleName}.${name}`,
|
|
362
|
+
args,
|
|
363
|
+
timestamp: Date.now(),
|
|
364
|
+
status: "resolved",
|
|
365
|
+
result: void 0,
|
|
366
|
+
fidelity: "inert"
|
|
367
|
+
});
|
|
368
|
+
};
|
|
369
|
+
throw new Error(`[@apps-in-toss/devtools] ${moduleName}.${prop} is not mocked. This API may exist in @apps-in-toss/web-framework, but devtools' mock does not cover it yet. Please file an issue: ${ISSUES_URL}`);
|
|
370
|
+
} });
|
|
371
|
+
}
|
|
372
|
+
//#endregion
|
|
373
|
+
//#region src/mock/device/storage.ts
|
|
374
|
+
/**
|
|
375
|
+
* Storage mock
|
|
376
|
+
* localStorage에 `__ait_storage:` prefix로 저장하여 앱 자체 localStorage와 분리
|
|
377
|
+
*
|
|
378
|
+
* 실기기(2.x×iOS) capture는 `setItem`/`removeItem`/`clearItems` 세 메서드가
|
|
379
|
+
* `undefined`가 아니라 `null`로 resolve됨을 보였다(devtools#770). 원본 SDK 타입
|
|
380
|
+
* 선언은 여전히 `Promise<void>`이므로 시그니처는 그대로 두고, 런타임 반환값만
|
|
381
|
+
* `null`로 캐스트해 실측과 동치시킨다 — Analytics·setClipboardText와 같은 처리(#775).
|
|
382
|
+
* `getItem`은 이미 `string | null`이라 실측과 일치하므로 손대지 않는다.
|
|
383
|
+
*/
|
|
384
|
+
const STORAGE_PREFIX = "__ait_storage:";
|
|
385
|
+
async function getItems(keys) {
|
|
386
|
+
return Object.fromEntries(keys.map((key) => [key, localStorage.getItem(`${STORAGE_PREFIX}${key}`)]));
|
|
387
|
+
}
|
|
388
|
+
async function setItems(items) {
|
|
389
|
+
for (const [key, value] of Object.entries(items)) localStorage.setItem(`${STORAGE_PREFIX}${key}`, value);
|
|
390
|
+
return null;
|
|
391
|
+
}
|
|
392
|
+
const Storage$1 = createMockProxy("Storage", {
|
|
393
|
+
getItem: async (key) => {
|
|
394
|
+
return localStorage.getItem(`${STORAGE_PREFIX}${key}`);
|
|
395
|
+
},
|
|
396
|
+
setItem: async (key, value) => {
|
|
397
|
+
localStorage.setItem(`${STORAGE_PREFIX}${key}`, value);
|
|
398
|
+
return null;
|
|
399
|
+
},
|
|
400
|
+
removeItem: async (key) => {
|
|
401
|
+
localStorage.removeItem(`${STORAGE_PREFIX}${key}`);
|
|
402
|
+
return null;
|
|
403
|
+
},
|
|
404
|
+
clearItems: async () => {
|
|
405
|
+
const keys = Object.keys(localStorage).filter((k) => k.startsWith(STORAGE_PREFIX));
|
|
406
|
+
for (const k of keys) localStorage.removeItem(k);
|
|
407
|
+
return null;
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
//#endregion
|
|
331
411
|
//#region src/mock/native-error.ts
|
|
332
412
|
/**
|
|
333
413
|
* 실패-모드 다이얼 — 네이티브 에러 envelope 조립 (devtools#770).
|
|
@@ -499,48 +579,6 @@ function safeSerialize(value) {
|
|
|
499
579
|
}
|
|
500
580
|
}
|
|
501
581
|
//#endregion
|
|
502
|
-
//#region src/mock/proxy.ts
|
|
503
|
-
/**
|
|
504
|
-
* 미구현 API용 Proxy 트립와이어.
|
|
505
|
-
*
|
|
506
|
-
* 미구현 프로퍼티에 접근하면 throw한다. 이는 "devtools에서는 멀쩡히 돌지만
|
|
507
|
-
* 실 SDK에선 실제로 동작하는" 시나리오를 차단하기 위한 의도적 선택이다.
|
|
508
|
-
* mock이 미구현인 API는 실 SDK에서는 존재할 수 있고, 사용자가 이를 인지하지
|
|
509
|
-
* 못한 채 개발을 이어가면 배포 시점에 놀라게 된다. 에러 메시지에 이슈 URL을
|
|
510
|
-
* 포함해 사용자가 mock 누락을 제보할 수 있게 한다.
|
|
511
|
-
*
|
|
512
|
-
* ## KNOWN_UNIMPLEMENTED 정책
|
|
513
|
-
* SDK에 존재하는 것으로 알려져 있으나 현재 mock이 없는 API 이름만 이 집합에 둔다.
|
|
514
|
-
* 이 경우에만 throw 대신 🔴 inert no-op을 반환하고 sdkCallLog에 기록한다.
|
|
515
|
-
* 완전히 미지의 이름은 여전히 throw — "잘 되는 척" 방지.
|
|
516
|
-
*/
|
|
517
|
-
const ISSUES_URL = "https://github.com/apps-in-toss-community/devtools/issues";
|
|
518
|
-
/**
|
|
519
|
-
* SDK에 존재하나 mock이 아직 없는 것으로 확인된 이름 목록.
|
|
520
|
-
* 새 API가 SDK에 추가되면 여기에 추가하고 별도 PR에서 mock 구현으로 이동한다.
|
|
521
|
-
* 확인되지 않은 이름은 절대 여기에 추가하지 않는다 — throw가 더 안전하다.
|
|
522
|
-
*/
|
|
523
|
-
const KNOWN_UNIMPLEMENTED = /* @__PURE__ */ new Set([]);
|
|
524
|
-
function createMockProxy(moduleName, implementations) {
|
|
525
|
-
return new Proxy(implementations, { get(target, prop) {
|
|
526
|
-
if (typeof prop === "symbol") return void 0;
|
|
527
|
-
if (prop in target) return target[prop];
|
|
528
|
-
const name = String(prop);
|
|
529
|
-
if (KNOWN_UNIMPLEMENTED.has(name)) return (...args) => {
|
|
530
|
-
console.warn(`[@apps-in-toss/devtools] ${moduleName}.${name} is known-unimplemented (🔴 inert). Returning undefined. Please file or upvote an issue: ${ISSUES_URL}`);
|
|
531
|
-
aitState.logSdkCall({
|
|
532
|
-
method: `${moduleName}.${name}`,
|
|
533
|
-
args,
|
|
534
|
-
timestamp: Date.now(),
|
|
535
|
-
status: "resolved",
|
|
536
|
-
result: void 0,
|
|
537
|
-
fidelity: "inert"
|
|
538
|
-
});
|
|
539
|
-
};
|
|
540
|
-
throw new Error(`[@apps-in-toss/devtools] ${moduleName}.${prop} is not mocked. This API may exist in @apps-in-toss/web-framework, but devtools' mock does not cover it yet. Please file an issue: ${ISSUES_URL}`);
|
|
541
|
-
} });
|
|
542
|
-
}
|
|
543
|
-
//#endregion
|
|
544
582
|
//#region src/mock/throttle.ts
|
|
545
583
|
/**
|
|
546
584
|
* THROTTLED 시뮬레이션 (devtools#834 — #770 §3 분리).
|
|
@@ -768,39 +806,6 @@ const showFullScreenAd$1 = withIsSupported(observe("showFullScreenAd", "faithful
|
|
|
768
806
|
setTimeout(() => args.onEvent({ type: "dismissed" }), 1500);
|
|
769
807
|
return () => {};
|
|
770
808
|
}));
|
|
771
|
-
const Ads$1 = createMockProxy("Ads", {
|
|
772
|
-
showTossAdOrShoppingAds: withIsSupported(observe("Ads.showTossAdOrShoppingAds", "faithful", (args) => {
|
|
773
|
-
if (!aitState.state.ads.isLoaded) {
|
|
774
|
-
args.onError(/* @__PURE__ */ new Error("Ad not loaded"));
|
|
775
|
-
return () => {};
|
|
776
|
-
}
|
|
777
|
-
const { rewardUnitType, rewardAmount } = aitState.state.ads;
|
|
778
|
-
setTimeout(() => args.onEvent({
|
|
779
|
-
type: "userEarnedReward",
|
|
780
|
-
data: {
|
|
781
|
-
unitType: rewardUnitType,
|
|
782
|
-
unitAmount: rewardAmount
|
|
783
|
-
}
|
|
784
|
-
}), 1e3);
|
|
785
|
-
setTimeout(() => {
|
|
786
|
-
args.onEvent({ type: "dismissed" });
|
|
787
|
-
aitState.patch("ads", { isLoaded: false });
|
|
788
|
-
}, 1500);
|
|
789
|
-
return () => {};
|
|
790
|
-
})),
|
|
791
|
-
showTossShoppingAds: withIsSupported(observe("Ads.showTossShoppingAds", "faithful", (args) => {
|
|
792
|
-
const { rewardUnitType, rewardAmount } = aitState.state.ads;
|
|
793
|
-
setTimeout(() => args.onEvent({
|
|
794
|
-
type: "userEarnedReward",
|
|
795
|
-
data: {
|
|
796
|
-
unitType: rewardUnitType,
|
|
797
|
-
unitAmount: rewardAmount
|
|
798
|
-
}
|
|
799
|
-
}), 1e3);
|
|
800
|
-
setTimeout(() => args.onEvent({ type: "dismissed" }), 1500);
|
|
801
|
-
return () => {};
|
|
802
|
-
}))
|
|
803
|
-
});
|
|
804
809
|
//#endregion
|
|
805
810
|
//#region src/mock/analytics/index.ts
|
|
806
811
|
/**
|
|
@@ -1600,36 +1605,6 @@ const _openPDFViewerImpl = async (_params) => {
|
|
|
1600
1605
|
};
|
|
1601
1606
|
const openPDFViewer$1 = Object.assign(_openPDFViewerImpl, { isSupported: () => true });
|
|
1602
1607
|
//#endregion
|
|
1603
|
-
//#region src/mock/device/storage.ts
|
|
1604
|
-
/**
|
|
1605
|
-
* Storage mock
|
|
1606
|
-
* localStorage에 `__ait_storage:` prefix로 저장하여 앱 자체 localStorage와 분리
|
|
1607
|
-
*
|
|
1608
|
-
* 실기기(2.x×iOS) capture는 `setItem`/`removeItem`/`clearItems` 세 메서드가
|
|
1609
|
-
* `undefined`가 아니라 `null`로 resolve됨을 보였다(devtools#770). 원본 SDK 타입
|
|
1610
|
-
* 선언은 여전히 `Promise<void>`이므로 시그니처는 그대로 두고, 런타임 반환값만
|
|
1611
|
-
* `null`로 캐스트해 실측과 동치시킨다 — Analytics·setClipboardText와 같은 처리(#775).
|
|
1612
|
-
* `getItem`은 이미 `string | null`이라 실측과 일치하므로 손대지 않는다.
|
|
1613
|
-
*/
|
|
1614
|
-
const Storage = createMockProxy("Storage", {
|
|
1615
|
-
getItem: async (key) => {
|
|
1616
|
-
return localStorage.getItem(`__ait_storage:${key}`);
|
|
1617
|
-
},
|
|
1618
|
-
setItem: async (key, value) => {
|
|
1619
|
-
localStorage.setItem(`__ait_storage:${key}`, value);
|
|
1620
|
-
return null;
|
|
1621
|
-
},
|
|
1622
|
-
removeItem: async (key) => {
|
|
1623
|
-
localStorage.removeItem(`__ait_storage:${key}`);
|
|
1624
|
-
return null;
|
|
1625
|
-
},
|
|
1626
|
-
clearItems: async () => {
|
|
1627
|
-
const keys = Object.keys(localStorage).filter((k) => k.startsWith("__ait_storage:"));
|
|
1628
|
-
for (const k of keys) localStorage.removeItem(k);
|
|
1629
|
-
return null;
|
|
1630
|
-
}
|
|
1631
|
-
});
|
|
1632
|
-
//#endregion
|
|
1633
1608
|
//#region src/mock/iap/index.ts
|
|
1634
1609
|
let orderCounter = 0;
|
|
1635
1610
|
function generateOrderId() {
|
|
@@ -1890,6 +1865,40 @@ const SafeAreaInsets = {
|
|
|
1890
1865
|
}
|
|
1891
1866
|
};
|
|
1892
1867
|
//#endregion
|
|
1868
|
+
//#region src/mock/viral/index.ts
|
|
1869
|
+
/** 바이럴 캠페인 조회 mock이에요. */
|
|
1870
|
+
async function getViralCampaign(params) {
|
|
1871
|
+
console.log("[@apps-in-toss/devtools] getViralCampaign:", params.campaignId);
|
|
1872
|
+
return {
|
|
1873
|
+
campaignId: params.campaignId,
|
|
1874
|
+
benefitName: "mock-benefit",
|
|
1875
|
+
display: {
|
|
1876
|
+
title: "바이럴 캠페인 제목",
|
|
1877
|
+
benefitText: "친구를 초대하면 리워드를 받아요",
|
|
1878
|
+
conditionText: "3명 초대 시 달성",
|
|
1879
|
+
ctaText: "공유하기"
|
|
1880
|
+
},
|
|
1881
|
+
active: true,
|
|
1882
|
+
campaignStatus: "IN_PROGRESS",
|
|
1883
|
+
participationAvailable: true,
|
|
1884
|
+
participationUnavailableReason: null,
|
|
1885
|
+
rules: [{
|
|
1886
|
+
ruleId: "rule-1",
|
|
1887
|
+
ruleKey: "invite",
|
|
1888
|
+
revision: 1,
|
|
1889
|
+
title: "친구 3명 초대",
|
|
1890
|
+
currentValue: 1,
|
|
1891
|
+
targetValue: 3,
|
|
1892
|
+
status: "IN_PROGRESS",
|
|
1893
|
+
achievedAt: null
|
|
1894
|
+
}]
|
|
1895
|
+
};
|
|
1896
|
+
}
|
|
1897
|
+
/** 바이럴 캠페인 공유 mock이에요. */
|
|
1898
|
+
async function shareViralCampaign(params) {
|
|
1899
|
+
console.log("[@apps-in-toss/devtools] shareViralCampaign:", params.campaignId);
|
|
1900
|
+
}
|
|
1901
|
+
//#endregion
|
|
1893
1902
|
//#region src/mock/bridge-factories.ts
|
|
1894
1903
|
/** Generic bridge escape hatches exposed by both SDK lines. */
|
|
1895
1904
|
const asyncBridgeRegistry = {
|
|
@@ -1903,11 +1912,13 @@ const asyncBridgeRegistry = {
|
|
|
1903
1912
|
getDeclaredAgeRange: getDeclaredAgeRange$1,
|
|
1904
1913
|
getNetworkStatus,
|
|
1905
1914
|
getServerTime: getServerTime$1,
|
|
1915
|
+
getViralCampaign,
|
|
1906
1916
|
openPDFViewer: openPDFViewer$1,
|
|
1907
1917
|
openURL,
|
|
1908
1918
|
requestReview: requestReview$1,
|
|
1909
1919
|
saveBase64Data: saveBase64Data$1,
|
|
1910
|
-
share
|
|
1920
|
+
share,
|
|
1921
|
+
shareViralCampaign
|
|
1911
1922
|
};
|
|
1912
1923
|
function createAsyncBridge(method) {
|
|
1913
1924
|
return async (...args) => {
|
|
@@ -2427,6 +2438,10 @@ const V = {
|
|
|
2427
2438
|
android: "5.233.0",
|
|
2428
2439
|
ios: "5.233.0"
|
|
2429
2440
|
},
|
|
2441
|
+
storageBatch: {
|
|
2442
|
+
android: "5.270.0",
|
|
2443
|
+
ios: "5.270.0"
|
|
2444
|
+
},
|
|
2430
2445
|
tossLogin: {
|
|
2431
2446
|
android: "5.237.0",
|
|
2432
2447
|
ios: "5.237.0"
|
|
@@ -2505,14 +2520,6 @@ const showFullScreenAd = Object.assign((args) => showFullScreenAd$1({
|
|
|
2505
2520
|
options: args.options ?? { adGroupId: "mock-ad-group" },
|
|
2506
2521
|
onError: (error) => args.onError(error instanceof Error ? error : new Error(String(error)))
|
|
2507
2522
|
}), { isSupported: () => true });
|
|
2508
|
-
const shoppingAdsMin = {
|
|
2509
|
-
android: "5.273.0",
|
|
2510
|
-
ios: "5.273.0"
|
|
2511
|
-
};
|
|
2512
|
-
const Ads = {
|
|
2513
|
-
showTossAdOrShoppingAds: supported(Ads$1.showTossAdOrShoppingAds, shoppingAdsMin),
|
|
2514
|
-
showTossShoppingAds: supported(Ads$1.showTossShoppingAds, shoppingAdsMin)
|
|
2515
|
-
};
|
|
2516
2523
|
const IAP = {
|
|
2517
2524
|
createOneTimePurchaseOrder: supported(IAP$1.createOneTimePurchaseOrder, V.iapOneTime),
|
|
2518
2525
|
createSubscriptionPurchaseOrder: supported(IAP$1.createSubscriptionPurchaseOrder, V.iapSubscription),
|
|
@@ -2574,10 +2581,15 @@ const File = {
|
|
|
2574
2581
|
saveBase64: saveBase64Data,
|
|
2575
2582
|
openPDFViewer
|
|
2576
2583
|
};
|
|
2584
|
+
const subscribeInfoOverlayHidden = ({ onEvent }) => {
|
|
2585
|
+
const timeoutId = window.setTimeout(onEvent, 0);
|
|
2586
|
+
return () => window.clearTimeout(timeoutId);
|
|
2587
|
+
};
|
|
2577
2588
|
const Game = {
|
|
2578
2589
|
openLeaderboard: openGameCenterLeaderboard,
|
|
2579
2590
|
setLeaderboardScore: submitGameCenterLeaderBoardScore,
|
|
2580
|
-
getUserProfile: getGameCenterGameProfile
|
|
2591
|
+
getUserProfile: getGameCenterGameProfile,
|
|
2592
|
+
subscribeInfoOverlayHidden
|
|
2581
2593
|
};
|
|
2582
2594
|
const Migration = { getOriginStorage: async () => {
|
|
2583
2595
|
const createEmptyDump = () => ({
|
|
@@ -2613,6 +2625,11 @@ const Share = {
|
|
|
2613
2625
|
createLink: ({ path, ogImageUrl }) => getTossShareLink(path, ogImageUrl),
|
|
2614
2626
|
sendMessage: share
|
|
2615
2627
|
};
|
|
2628
|
+
const Storage = {
|
|
2629
|
+
...Storage$1,
|
|
2630
|
+
getItems: supported(getItems, V.storageBatch),
|
|
2631
|
+
setItems: supported(setItems, V.storageBatch)
|
|
2632
|
+
};
|
|
2616
2633
|
const TossAuth = {
|
|
2617
2634
|
login: appLogin,
|
|
2618
2635
|
isIntegrated: getIsTossLoginIntegratedService,
|
|
@@ -2633,5 +2650,9 @@ const User = {
|
|
|
2633
2650
|
getConsentedData: getConsentedUserData,
|
|
2634
2651
|
getDeclaredAgeRange
|
|
2635
2652
|
};
|
|
2653
|
+
const Viral = {
|
|
2654
|
+
getCampaign: getViralCampaign,
|
|
2655
|
+
share: shareViralCampaign
|
|
2656
|
+
};
|
|
2636
2657
|
//#endregion
|
|
2637
|
-
export { Accuracy,
|
|
2658
|
+
export { Accuracy, Analytics, Clipboard, Device, Environment, FetchAlbumPhotosPermissionError, FetchContactsPermissionError, File, Game, GetClipboardTextPermissionError, GetCurrentLocationPermissionError, GoogleAdMob, IAP, Migration, Notification, OpenCameraPermissionError, PermissionError, Promotion, Review, SafeArea, SafeAreaInsets, Screen, SetClipboardTextPermissionError, Share, StartUpdateLocationPermissionError, Storage, TossAds, TossAuth, TossPay, User, Viral, aitState, appLogin, applyPreset, appsInTossEvent, appsInTossSignTossCert, builtInPresets, captureCurrentState, checkoutPayment, closeView, contactsViral, createAsyncBridge, createConstantBridge, createEventBridge, deleteUserPreset, env, eventLog, fetchAlbumItems, fetchAlbumPhotos, fetchContacts, generateHapticFeedback, getAnonymousKey, getAppsInTossGlobals, getClipboardText, getConsentedUserData, getCurrentLocation, getDeclaredAgeRange, getDefaultPlaceholderImages, getDeviceId, getGameCenterGameProfile, getGroupId, getIsTossLoginIntegratedService, getLocale, getNetworkStatus, getOperationalEnvironment, getPermission, getPlatformOS, getSafeAreaInsets, getSchemeUri, getServerTime, getTossAppVersion, getTossShareLink, getUserKeyForGame, getViralCampaign, graniteEvent, grantPromotionReward, grantPromotionRewardForGame, isMinVersionSupported, listUserPresets, loadFullScreenAd, matchesPreset, onVisibilityChangedByTransparentServiceWeb, openCamera, openGameCenterLeaderboard, openPDFViewer, openPermissionDialog, openURL, partner, requestNotificationAgreement, requestPermission, requestReview, requestTossPayPaysBilling, saveBase64Data, saveUserPreset, setClipboardText, setDeviceOrientation, setIosSwipeGestureEnabled, setScreenAwakeMode, setSecureScreen, share, shareViralCampaign, showFullScreenAd, startUpdateLocation, submitGameCenterLeaderBoardScore, tdsEvent };
|
package/dist/mock/index.d.ts
CHANGED
|
@@ -156,7 +156,6 @@ declare const isMinVersionSupported: typeof SDK.isMinVersionSupported;
|
|
|
156
156
|
declare const GoogleAdMob: typeof SDK.GoogleAdMob;
|
|
157
157
|
declare const loadFullScreenAd: typeof SDK.loadFullScreenAd;
|
|
158
158
|
declare const showFullScreenAd: typeof SDK.showFullScreenAd;
|
|
159
|
-
declare const Ads: typeof SDK.Ads;
|
|
160
159
|
declare const IAP: typeof SDK.IAP;
|
|
161
160
|
declare const Analytics: typeof SDK.Analytics;
|
|
162
161
|
declare const Clipboard: typeof SDK.Clipboard;
|
|
@@ -194,9 +193,11 @@ declare const Review: typeof SDK.Review;
|
|
|
194
193
|
declare const SafeArea: typeof SDK.SafeArea;
|
|
195
194
|
declare const Screen: typeof SDK.Screen;
|
|
196
195
|
declare const Share: typeof SDK.Share;
|
|
196
|
+
declare const Storage: typeof SDK.Storage;
|
|
197
197
|
declare const TossAuth: typeof SDK.TossAuth;
|
|
198
198
|
declare const TossPay: typeof SDK.TossPay;
|
|
199
199
|
declare const User: typeof SDK.User;
|
|
200
|
+
declare const Viral: typeof SDK.Viral;
|
|
200
201
|
//#endregion
|
|
201
202
|
//#region src/mock/ads/index.d.ts
|
|
202
203
|
declare const TossAds: {
|
|
@@ -557,24 +558,6 @@ declare const startUpdateLocation: ((eventParams: StartUpdateLocationEventParams
|
|
|
557
558
|
openPermissionDialog: () => Promise<"allowed" | "denied">;
|
|
558
559
|
};
|
|
559
560
|
//#endregion
|
|
560
|
-
//#region src/mock/device/storage.d.ts
|
|
561
|
-
/**
|
|
562
|
-
* Storage mock
|
|
563
|
-
* localStorage에 `__ait_storage:` prefix로 저장하여 앱 자체 localStorage와 분리
|
|
564
|
-
*
|
|
565
|
-
* 실기기(2.x×iOS) capture는 `setItem`/`removeItem`/`clearItems` 세 메서드가
|
|
566
|
-
* `undefined`가 아니라 `null`로 resolve됨을 보였다(devtools#770). 원본 SDK 타입
|
|
567
|
-
* 선언은 여전히 `Promise<void>`이므로 시그니처는 그대로 두고, 런타임 반환값만
|
|
568
|
-
* `null`로 캐스트해 실측과 동치시킨다 — Analytics·setClipboardText와 같은 처리(#775).
|
|
569
|
-
* `getItem`은 이미 `string | null`이라 실측과 일치하므로 손대지 않는다.
|
|
570
|
-
*/
|
|
571
|
-
declare const Storage: {
|
|
572
|
-
getItem: (key: string) => Promise<string | null>;
|
|
573
|
-
setItem: (key: string, value: string) => Promise<void>;
|
|
574
|
-
removeItem: (key: string) => Promise<void>;
|
|
575
|
-
clearItems: () => Promise<void>;
|
|
576
|
-
};
|
|
577
|
-
//#endregion
|
|
578
561
|
//#region src/mock/iap/index.d.ts
|
|
579
562
|
declare function checkoutPayment(options: {
|
|
580
563
|
params: {
|
|
@@ -585,6 +568,39 @@ declare function checkoutPayment(options: {
|
|
|
585
568
|
reason?: string;
|
|
586
569
|
}>;
|
|
587
570
|
//#endregion
|
|
571
|
+
//#region src/mock/viral/index.d.ts
|
|
572
|
+
/** 바이럴 캠페인 조회 mock이에요. */
|
|
573
|
+
declare function getViralCampaign(params: {
|
|
574
|
+
campaignId: string;
|
|
575
|
+
}): Promise<{
|
|
576
|
+
campaignId: string;
|
|
577
|
+
benefitName: string;
|
|
578
|
+
display: {
|
|
579
|
+
title: string | null;
|
|
580
|
+
benefitText: string | null;
|
|
581
|
+
conditionText: string | null;
|
|
582
|
+
ctaText: string | null;
|
|
583
|
+
};
|
|
584
|
+
active: boolean;
|
|
585
|
+
campaignStatus: "WAITING" | "IN_PROGRESS" | "ENDED";
|
|
586
|
+
participationAvailable: boolean;
|
|
587
|
+
participationUnavailableReason: "INACTIVE" | "NOT_STARTED" | "ENDED" | "ALL_RULES_ACHIEVED" | null;
|
|
588
|
+
rules: Array<{
|
|
589
|
+
ruleId: string;
|
|
590
|
+
ruleKey: string;
|
|
591
|
+
revision: number;
|
|
592
|
+
title: string;
|
|
593
|
+
currentValue: number;
|
|
594
|
+
targetValue: number;
|
|
595
|
+
status: "IN_PROGRESS" | "ACHIEVED" | "EXPIRED";
|
|
596
|
+
achievedAt: string | null;
|
|
597
|
+
}>;
|
|
598
|
+
}>;
|
|
599
|
+
/** 바이럴 캠페인 공유 mock이에요. */
|
|
600
|
+
declare function shareViralCampaign(params: {
|
|
601
|
+
campaignId: string;
|
|
602
|
+
}): Promise<void>;
|
|
603
|
+
//#endregion
|
|
588
604
|
//#region src/mock/navigation/index.d.ts
|
|
589
605
|
declare function closeView(): Promise<void>;
|
|
590
606
|
declare function openURL(url: string): Promise<void>;
|
|
@@ -1051,4 +1067,4 @@ declare function listUserPresets(): MockPreset[];
|
|
|
1051
1067
|
declare function saveUserPreset(label: string, state: MockPresetState, description?: string): MockPreset;
|
|
1052
1068
|
declare function deleteUserPreset(id: string): void;
|
|
1053
1069
|
//#endregion
|
|
1054
|
-
export { Accuracy,
|
|
1070
|
+
export { Accuracy, type AitDevtoolsState, Analytics, type AnalyticsLogEntry, Clipboard, type ConsentedUserData, type ConsentedUserDataKey, type DeclaredAgeRange, Device, type DeviceApiMode, type DeviceModes, Environment, FetchAlbumPhotosPermissionError, FetchContactsPermissionError, File, Game, GetClipboardTextPermissionError, GetCurrentLocationPermissionError, GoogleAdMob, type HapticFeedbackType, IAP, type IapNextResult, type LocationCoords, Migration, type MockContact, type MockData, type MockIapProduct, type MockLocation, type MockPreset, type MockPresetState, type NetworkStatus, Notification, OpenCameraPermissionError, type OperationalEnvironment, PermissionError, type PermissionName, type PermissionStatus, type PlatformOS, type Primitive, Promotion, Review, SafeArea, SafeAreaInsets, type SafeAreaInsets$1 as SafeAreaInsetsType, Screen, SetClipboardTextPermissionError, Share, StartUpdateLocationPermissionError, Storage, TossAds, TossAuth, TossPay, User, Viral, aitState, appLogin, applyPreset, appsInTossEvent, appsInTossSignTossCert, builtInPresets, captureCurrentState, checkoutPayment, closeView, contactsViral, createAsyncBridge, createConstantBridge, createEventBridge, deleteUserPreset, env, eventLog, fetchAlbumItems, fetchAlbumPhotos, fetchContacts, generateHapticFeedback, getAnonymousKey, getAppsInTossGlobals, getClipboardText, getConsentedUserData, getCurrentLocation, getDeclaredAgeRange, getDefaultPlaceholderImages, getDeviceId, getGameCenterGameProfile, getGroupId, getIsTossLoginIntegratedService, getLocale, getNetworkStatus, getOperationalEnvironment, getPermission, getPlatformOS, getSafeAreaInsets, getSchemeUri, getServerTime, getTossAppVersion, getTossShareLink, getUserKeyForGame, getViralCampaign, graniteEvent, grantPromotionReward, grantPromotionRewardForGame, isMinVersionSupported, listUserPresets, loadFullScreenAd, matchesPreset, onVisibilityChangedByTransparentServiceWeb, openCamera, openGameCenterLeaderboard, openPDFViewer, openPermissionDialog, openURL, partner, requestNotificationAgreement, requestPermission, requestReview, requestTossPayPaysBilling, saveBase64Data, saveUserPreset, setClipboardText, setDeviceOrientation, setIosSwipeGestureEnabled, setScreenAwakeMode, setSecureScreen, share, shareViralCampaign, showFullScreenAd, startUpdateLocation, submitGameCenterLeaderBoardScore, tdsEvent };
|
package/dist/mock/index.js
CHANGED
|
@@ -328,6 +328,86 @@ if (!globalRef[SINGLETON_KEY]) globalRef[SINGLETON_KEY] = new AitStateManager();
|
|
|
328
328
|
const aitState = globalRef[SINGLETON_KEY];
|
|
329
329
|
if (typeof window !== "undefined") window.__ait = aitState;
|
|
330
330
|
//#endregion
|
|
331
|
+
//#region src/mock/proxy.ts
|
|
332
|
+
/**
|
|
333
|
+
* 미구현 API용 Proxy 트립와이어.
|
|
334
|
+
*
|
|
335
|
+
* 미구현 프로퍼티에 접근하면 throw한다. 이는 "devtools에서는 멀쩡히 돌지만
|
|
336
|
+
* 실 SDK에선 실제로 동작하는" 시나리오를 차단하기 위한 의도적 선택이다.
|
|
337
|
+
* mock이 미구현인 API는 실 SDK에서는 존재할 수 있고, 사용자가 이를 인지하지
|
|
338
|
+
* 못한 채 개발을 이어가면 배포 시점에 놀라게 된다. 에러 메시지에 이슈 URL을
|
|
339
|
+
* 포함해 사용자가 mock 누락을 제보할 수 있게 한다.
|
|
340
|
+
*
|
|
341
|
+
* ## KNOWN_UNIMPLEMENTED 정책
|
|
342
|
+
* SDK에 존재하는 것으로 알려져 있으나 현재 mock이 없는 API 이름만 이 집합에 둔다.
|
|
343
|
+
* 이 경우에만 throw 대신 🔴 inert no-op을 반환하고 sdkCallLog에 기록한다.
|
|
344
|
+
* 완전히 미지의 이름은 여전히 throw — "잘 되는 척" 방지.
|
|
345
|
+
*/
|
|
346
|
+
const ISSUES_URL = "https://github.com/apps-in-toss-community/devtools/issues";
|
|
347
|
+
/**
|
|
348
|
+
* SDK에 존재하나 mock이 아직 없는 것으로 확인된 이름 목록.
|
|
349
|
+
* 새 API가 SDK에 추가되면 여기에 추가하고 별도 PR에서 mock 구현으로 이동한다.
|
|
350
|
+
* 확인되지 않은 이름은 절대 여기에 추가하지 않는다 — throw가 더 안전하다.
|
|
351
|
+
*/
|
|
352
|
+
const KNOWN_UNIMPLEMENTED = /* @__PURE__ */ new Set([]);
|
|
353
|
+
function createMockProxy(moduleName, implementations) {
|
|
354
|
+
return new Proxy(implementations, { get(target, prop) {
|
|
355
|
+
if (typeof prop === "symbol") return void 0;
|
|
356
|
+
if (prop in target) return target[prop];
|
|
357
|
+
const name = String(prop);
|
|
358
|
+
if (KNOWN_UNIMPLEMENTED.has(name)) return (...args) => {
|
|
359
|
+
console.warn(`[@apps-in-toss/devtools] ${moduleName}.${name} is known-unimplemented (🔴 inert). Returning undefined. Please file or upvote an issue: ${ISSUES_URL}`);
|
|
360
|
+
aitState.logSdkCall({
|
|
361
|
+
method: `${moduleName}.${name}`,
|
|
362
|
+
args,
|
|
363
|
+
timestamp: Date.now(),
|
|
364
|
+
status: "resolved",
|
|
365
|
+
result: void 0,
|
|
366
|
+
fidelity: "inert"
|
|
367
|
+
});
|
|
368
|
+
};
|
|
369
|
+
throw new Error(`[@apps-in-toss/devtools] ${moduleName}.${prop} is not mocked. This API may exist in @apps-in-toss/web-framework, but devtools' mock does not cover it yet. Please file an issue: ${ISSUES_URL}`);
|
|
370
|
+
} });
|
|
371
|
+
}
|
|
372
|
+
//#endregion
|
|
373
|
+
//#region src/mock/device/storage.ts
|
|
374
|
+
/**
|
|
375
|
+
* Storage mock
|
|
376
|
+
* localStorage에 `__ait_storage:` prefix로 저장하여 앱 자체 localStorage와 분리
|
|
377
|
+
*
|
|
378
|
+
* 실기기(2.x×iOS) capture는 `setItem`/`removeItem`/`clearItems` 세 메서드가
|
|
379
|
+
* `undefined`가 아니라 `null`로 resolve됨을 보였다(devtools#770). 원본 SDK 타입
|
|
380
|
+
* 선언은 여전히 `Promise<void>`이므로 시그니처는 그대로 두고, 런타임 반환값만
|
|
381
|
+
* `null`로 캐스트해 실측과 동치시킨다 — Analytics·setClipboardText와 같은 처리(#775).
|
|
382
|
+
* `getItem`은 이미 `string | null`이라 실측과 일치하므로 손대지 않는다.
|
|
383
|
+
*/
|
|
384
|
+
const STORAGE_PREFIX = "__ait_storage:";
|
|
385
|
+
async function getItems(keys) {
|
|
386
|
+
return Object.fromEntries(keys.map((key) => [key, localStorage.getItem(`${STORAGE_PREFIX}${key}`)]));
|
|
387
|
+
}
|
|
388
|
+
async function setItems(items) {
|
|
389
|
+
for (const [key, value] of Object.entries(items)) localStorage.setItem(`${STORAGE_PREFIX}${key}`, value);
|
|
390
|
+
return null;
|
|
391
|
+
}
|
|
392
|
+
const Storage$1 = createMockProxy("Storage", {
|
|
393
|
+
getItem: async (key) => {
|
|
394
|
+
return localStorage.getItem(`${STORAGE_PREFIX}${key}`);
|
|
395
|
+
},
|
|
396
|
+
setItem: async (key, value) => {
|
|
397
|
+
localStorage.setItem(`${STORAGE_PREFIX}${key}`, value);
|
|
398
|
+
return null;
|
|
399
|
+
},
|
|
400
|
+
removeItem: async (key) => {
|
|
401
|
+
localStorage.removeItem(`${STORAGE_PREFIX}${key}`);
|
|
402
|
+
return null;
|
|
403
|
+
},
|
|
404
|
+
clearItems: async () => {
|
|
405
|
+
const keys = Object.keys(localStorage).filter((k) => k.startsWith(STORAGE_PREFIX));
|
|
406
|
+
for (const k of keys) localStorage.removeItem(k);
|
|
407
|
+
return null;
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
//#endregion
|
|
331
411
|
//#region src/mock/native-error.ts
|
|
332
412
|
/**
|
|
333
413
|
* 실패-모드 다이얼 — 네이티브 에러 envelope 조립 (devtools#770).
|
|
@@ -499,48 +579,6 @@ function safeSerialize(value) {
|
|
|
499
579
|
}
|
|
500
580
|
}
|
|
501
581
|
//#endregion
|
|
502
|
-
//#region src/mock/proxy.ts
|
|
503
|
-
/**
|
|
504
|
-
* 미구현 API용 Proxy 트립와이어.
|
|
505
|
-
*
|
|
506
|
-
* 미구현 프로퍼티에 접근하면 throw한다. 이는 "devtools에서는 멀쩡히 돌지만
|
|
507
|
-
* 실 SDK에선 실제로 동작하는" 시나리오를 차단하기 위한 의도적 선택이다.
|
|
508
|
-
* mock이 미구현인 API는 실 SDK에서는 존재할 수 있고, 사용자가 이를 인지하지
|
|
509
|
-
* 못한 채 개발을 이어가면 배포 시점에 놀라게 된다. 에러 메시지에 이슈 URL을
|
|
510
|
-
* 포함해 사용자가 mock 누락을 제보할 수 있게 한다.
|
|
511
|
-
*
|
|
512
|
-
* ## KNOWN_UNIMPLEMENTED 정책
|
|
513
|
-
* SDK에 존재하는 것으로 알려져 있으나 현재 mock이 없는 API 이름만 이 집합에 둔다.
|
|
514
|
-
* 이 경우에만 throw 대신 🔴 inert no-op을 반환하고 sdkCallLog에 기록한다.
|
|
515
|
-
* 완전히 미지의 이름은 여전히 throw — "잘 되는 척" 방지.
|
|
516
|
-
*/
|
|
517
|
-
const ISSUES_URL = "https://github.com/apps-in-toss-community/devtools/issues";
|
|
518
|
-
/**
|
|
519
|
-
* SDK에 존재하나 mock이 아직 없는 것으로 확인된 이름 목록.
|
|
520
|
-
* 새 API가 SDK에 추가되면 여기에 추가하고 별도 PR에서 mock 구현으로 이동한다.
|
|
521
|
-
* 확인되지 않은 이름은 절대 여기에 추가하지 않는다 — throw가 더 안전하다.
|
|
522
|
-
*/
|
|
523
|
-
const KNOWN_UNIMPLEMENTED = /* @__PURE__ */ new Set([]);
|
|
524
|
-
function createMockProxy(moduleName, implementations) {
|
|
525
|
-
return new Proxy(implementations, { get(target, prop) {
|
|
526
|
-
if (typeof prop === "symbol") return void 0;
|
|
527
|
-
if (prop in target) return target[prop];
|
|
528
|
-
const name = String(prop);
|
|
529
|
-
if (KNOWN_UNIMPLEMENTED.has(name)) return (...args) => {
|
|
530
|
-
console.warn(`[@apps-in-toss/devtools] ${moduleName}.${name} is known-unimplemented (🔴 inert). Returning undefined. Please file or upvote an issue: ${ISSUES_URL}`);
|
|
531
|
-
aitState.logSdkCall({
|
|
532
|
-
method: `${moduleName}.${name}`,
|
|
533
|
-
args,
|
|
534
|
-
timestamp: Date.now(),
|
|
535
|
-
status: "resolved",
|
|
536
|
-
result: void 0,
|
|
537
|
-
fidelity: "inert"
|
|
538
|
-
});
|
|
539
|
-
};
|
|
540
|
-
throw new Error(`[@apps-in-toss/devtools] ${moduleName}.${prop} is not mocked. This API may exist in @apps-in-toss/web-framework, but devtools' mock does not cover it yet. Please file an issue: ${ISSUES_URL}`);
|
|
541
|
-
} });
|
|
542
|
-
}
|
|
543
|
-
//#endregion
|
|
544
582
|
//#region src/mock/throttle.ts
|
|
545
583
|
/**
|
|
546
584
|
* THROTTLED 시뮬레이션 (devtools#834 — #770 §3 분리).
|
|
@@ -768,39 +806,6 @@ const showFullScreenAd$1 = withIsSupported(observe("showFullScreenAd", "faithful
|
|
|
768
806
|
setTimeout(() => args.onEvent({ type: "dismissed" }), 1500);
|
|
769
807
|
return () => {};
|
|
770
808
|
}));
|
|
771
|
-
const Ads$1 = createMockProxy("Ads", {
|
|
772
|
-
showTossAdOrShoppingAds: withIsSupported(observe("Ads.showTossAdOrShoppingAds", "faithful", (args) => {
|
|
773
|
-
if (!aitState.state.ads.isLoaded) {
|
|
774
|
-
args.onError(/* @__PURE__ */ new Error("Ad not loaded"));
|
|
775
|
-
return () => {};
|
|
776
|
-
}
|
|
777
|
-
const { rewardUnitType, rewardAmount } = aitState.state.ads;
|
|
778
|
-
setTimeout(() => args.onEvent({
|
|
779
|
-
type: "userEarnedReward",
|
|
780
|
-
data: {
|
|
781
|
-
unitType: rewardUnitType,
|
|
782
|
-
unitAmount: rewardAmount
|
|
783
|
-
}
|
|
784
|
-
}), 1e3);
|
|
785
|
-
setTimeout(() => {
|
|
786
|
-
args.onEvent({ type: "dismissed" });
|
|
787
|
-
aitState.patch("ads", { isLoaded: false });
|
|
788
|
-
}, 1500);
|
|
789
|
-
return () => {};
|
|
790
|
-
})),
|
|
791
|
-
showTossShoppingAds: withIsSupported(observe("Ads.showTossShoppingAds", "faithful", (args) => {
|
|
792
|
-
const { rewardUnitType, rewardAmount } = aitState.state.ads;
|
|
793
|
-
setTimeout(() => args.onEvent({
|
|
794
|
-
type: "userEarnedReward",
|
|
795
|
-
data: {
|
|
796
|
-
unitType: rewardUnitType,
|
|
797
|
-
unitAmount: rewardAmount
|
|
798
|
-
}
|
|
799
|
-
}), 1e3);
|
|
800
|
-
setTimeout(() => args.onEvent({ type: "dismissed" }), 1500);
|
|
801
|
-
return () => {};
|
|
802
|
-
}))
|
|
803
|
-
});
|
|
804
809
|
//#endregion
|
|
805
810
|
//#region src/mock/analytics/index.ts
|
|
806
811
|
/**
|
|
@@ -1600,36 +1605,6 @@ const _openPDFViewerImpl = async (_params) => {
|
|
|
1600
1605
|
};
|
|
1601
1606
|
const openPDFViewer$1 = Object.assign(_openPDFViewerImpl, { isSupported: () => true });
|
|
1602
1607
|
//#endregion
|
|
1603
|
-
//#region src/mock/device/storage.ts
|
|
1604
|
-
/**
|
|
1605
|
-
* Storage mock
|
|
1606
|
-
* localStorage에 `__ait_storage:` prefix로 저장하여 앱 자체 localStorage와 분리
|
|
1607
|
-
*
|
|
1608
|
-
* 실기기(2.x×iOS) capture는 `setItem`/`removeItem`/`clearItems` 세 메서드가
|
|
1609
|
-
* `undefined`가 아니라 `null`로 resolve됨을 보였다(devtools#770). 원본 SDK 타입
|
|
1610
|
-
* 선언은 여전히 `Promise<void>`이므로 시그니처는 그대로 두고, 런타임 반환값만
|
|
1611
|
-
* `null`로 캐스트해 실측과 동치시킨다 — Analytics·setClipboardText와 같은 처리(#775).
|
|
1612
|
-
* `getItem`은 이미 `string | null`이라 실측과 일치하므로 손대지 않는다.
|
|
1613
|
-
*/
|
|
1614
|
-
const Storage = createMockProxy("Storage", {
|
|
1615
|
-
getItem: async (key) => {
|
|
1616
|
-
return localStorage.getItem(`__ait_storage:${key}`);
|
|
1617
|
-
},
|
|
1618
|
-
setItem: async (key, value) => {
|
|
1619
|
-
localStorage.setItem(`__ait_storage:${key}`, value);
|
|
1620
|
-
return null;
|
|
1621
|
-
},
|
|
1622
|
-
removeItem: async (key) => {
|
|
1623
|
-
localStorage.removeItem(`__ait_storage:${key}`);
|
|
1624
|
-
return null;
|
|
1625
|
-
},
|
|
1626
|
-
clearItems: async () => {
|
|
1627
|
-
const keys = Object.keys(localStorage).filter((k) => k.startsWith("__ait_storage:"));
|
|
1628
|
-
for (const k of keys) localStorage.removeItem(k);
|
|
1629
|
-
return null;
|
|
1630
|
-
}
|
|
1631
|
-
});
|
|
1632
|
-
//#endregion
|
|
1633
1608
|
//#region src/mock/iap/index.ts
|
|
1634
1609
|
let orderCounter = 0;
|
|
1635
1610
|
function generateOrderId() {
|
|
@@ -1890,6 +1865,40 @@ const SafeAreaInsets = {
|
|
|
1890
1865
|
}
|
|
1891
1866
|
};
|
|
1892
1867
|
//#endregion
|
|
1868
|
+
//#region src/mock/viral/index.ts
|
|
1869
|
+
/** 바이럴 캠페인 조회 mock이에요. */
|
|
1870
|
+
async function getViralCampaign(params) {
|
|
1871
|
+
console.log("[@apps-in-toss/devtools] getViralCampaign:", params.campaignId);
|
|
1872
|
+
return {
|
|
1873
|
+
campaignId: params.campaignId,
|
|
1874
|
+
benefitName: "mock-benefit",
|
|
1875
|
+
display: {
|
|
1876
|
+
title: "바이럴 캠페인 제목",
|
|
1877
|
+
benefitText: "친구를 초대하면 리워드를 받아요",
|
|
1878
|
+
conditionText: "3명 초대 시 달성",
|
|
1879
|
+
ctaText: "공유하기"
|
|
1880
|
+
},
|
|
1881
|
+
active: true,
|
|
1882
|
+
campaignStatus: "IN_PROGRESS",
|
|
1883
|
+
participationAvailable: true,
|
|
1884
|
+
participationUnavailableReason: null,
|
|
1885
|
+
rules: [{
|
|
1886
|
+
ruleId: "rule-1",
|
|
1887
|
+
ruleKey: "invite",
|
|
1888
|
+
revision: 1,
|
|
1889
|
+
title: "친구 3명 초대",
|
|
1890
|
+
currentValue: 1,
|
|
1891
|
+
targetValue: 3,
|
|
1892
|
+
status: "IN_PROGRESS",
|
|
1893
|
+
achievedAt: null
|
|
1894
|
+
}]
|
|
1895
|
+
};
|
|
1896
|
+
}
|
|
1897
|
+
/** 바이럴 캠페인 공유 mock이에요. */
|
|
1898
|
+
async function shareViralCampaign(params) {
|
|
1899
|
+
console.log("[@apps-in-toss/devtools] shareViralCampaign:", params.campaignId);
|
|
1900
|
+
}
|
|
1901
|
+
//#endregion
|
|
1893
1902
|
//#region src/mock/bridge-factories.ts
|
|
1894
1903
|
/** Generic bridge escape hatches exposed by both SDK lines. */
|
|
1895
1904
|
const asyncBridgeRegistry = {
|
|
@@ -1903,11 +1912,13 @@ const asyncBridgeRegistry = {
|
|
|
1903
1912
|
getDeclaredAgeRange: getDeclaredAgeRange$1,
|
|
1904
1913
|
getNetworkStatus,
|
|
1905
1914
|
getServerTime: getServerTime$1,
|
|
1915
|
+
getViralCampaign,
|
|
1906
1916
|
openPDFViewer: openPDFViewer$1,
|
|
1907
1917
|
openURL,
|
|
1908
1918
|
requestReview: requestReview$1,
|
|
1909
1919
|
saveBase64Data: saveBase64Data$1,
|
|
1910
|
-
share
|
|
1920
|
+
share,
|
|
1921
|
+
shareViralCampaign
|
|
1911
1922
|
};
|
|
1912
1923
|
function createAsyncBridge(method) {
|
|
1913
1924
|
return async (...args) => {
|
|
@@ -2427,6 +2438,10 @@ const V = {
|
|
|
2427
2438
|
android: "5.233.0",
|
|
2428
2439
|
ios: "5.233.0"
|
|
2429
2440
|
},
|
|
2441
|
+
storageBatch: {
|
|
2442
|
+
android: "5.270.0",
|
|
2443
|
+
ios: "5.270.0"
|
|
2444
|
+
},
|
|
2430
2445
|
tossLogin: {
|
|
2431
2446
|
android: "5.237.0",
|
|
2432
2447
|
ios: "5.237.0"
|
|
@@ -2505,14 +2520,6 @@ const showFullScreenAd = Object.assign((args) => showFullScreenAd$1({
|
|
|
2505
2520
|
options: args.options ?? { adGroupId: "mock-ad-group" },
|
|
2506
2521
|
onError: (error) => args.onError(error instanceof Error ? error : new Error(String(error)))
|
|
2507
2522
|
}), { isSupported: () => true });
|
|
2508
|
-
const shoppingAdsMin = {
|
|
2509
|
-
android: "5.273.0",
|
|
2510
|
-
ios: "5.273.0"
|
|
2511
|
-
};
|
|
2512
|
-
const Ads = {
|
|
2513
|
-
showTossAdOrShoppingAds: supported(Ads$1.showTossAdOrShoppingAds, shoppingAdsMin),
|
|
2514
|
-
showTossShoppingAds: supported(Ads$1.showTossShoppingAds, shoppingAdsMin)
|
|
2515
|
-
};
|
|
2516
2523
|
const IAP = {
|
|
2517
2524
|
createOneTimePurchaseOrder: supported(IAP$1.createOneTimePurchaseOrder, V.iapOneTime),
|
|
2518
2525
|
createSubscriptionPurchaseOrder: supported(IAP$1.createSubscriptionPurchaseOrder, V.iapSubscription),
|
|
@@ -2574,10 +2581,15 @@ const File = {
|
|
|
2574
2581
|
saveBase64: saveBase64Data,
|
|
2575
2582
|
openPDFViewer
|
|
2576
2583
|
};
|
|
2584
|
+
const subscribeInfoOverlayHidden = ({ onEvent }) => {
|
|
2585
|
+
const timeoutId = window.setTimeout(onEvent, 0);
|
|
2586
|
+
return () => window.clearTimeout(timeoutId);
|
|
2587
|
+
};
|
|
2577
2588
|
const Game = {
|
|
2578
2589
|
openLeaderboard: openGameCenterLeaderboard,
|
|
2579
2590
|
setLeaderboardScore: submitGameCenterLeaderBoardScore,
|
|
2580
|
-
getUserProfile: getGameCenterGameProfile
|
|
2591
|
+
getUserProfile: getGameCenterGameProfile,
|
|
2592
|
+
subscribeInfoOverlayHidden
|
|
2581
2593
|
};
|
|
2582
2594
|
const Migration = { getOriginStorage: async () => {
|
|
2583
2595
|
const createEmptyDump = () => ({
|
|
@@ -2613,6 +2625,11 @@ const Share = {
|
|
|
2613
2625
|
createLink: ({ path, ogImageUrl }) => getTossShareLink(path, ogImageUrl),
|
|
2614
2626
|
sendMessage: share
|
|
2615
2627
|
};
|
|
2628
|
+
const Storage = {
|
|
2629
|
+
...Storage$1,
|
|
2630
|
+
getItems: supported(getItems, V.storageBatch),
|
|
2631
|
+
setItems: supported(setItems, V.storageBatch)
|
|
2632
|
+
};
|
|
2616
2633
|
const TossAuth = {
|
|
2617
2634
|
login: appLogin,
|
|
2618
2635
|
isIntegrated: getIsTossLoginIntegratedService,
|
|
@@ -2633,5 +2650,9 @@ const User = {
|
|
|
2633
2650
|
getConsentedData: getConsentedUserData,
|
|
2634
2651
|
getDeclaredAgeRange
|
|
2635
2652
|
};
|
|
2653
|
+
const Viral = {
|
|
2654
|
+
getCampaign: getViralCampaign,
|
|
2655
|
+
share: shareViralCampaign
|
|
2656
|
+
};
|
|
2636
2657
|
//#endregion
|
|
2637
|
-
export { Accuracy,
|
|
2658
|
+
export { Accuracy, Analytics, Clipboard, Device, Environment, FetchAlbumPhotosPermissionError, FetchContactsPermissionError, File, Game, GetClipboardTextPermissionError, GetCurrentLocationPermissionError, GoogleAdMob, IAP, Migration, Notification, OpenCameraPermissionError, PermissionError, Promotion, Review, SafeArea, SafeAreaInsets, Screen, SetClipboardTextPermissionError, Share, StartUpdateLocationPermissionError, Storage, TossAds, TossAuth, TossPay, User, Viral, aitState, appLogin, applyPreset, appsInTossEvent, appsInTossSignTossCert, builtInPresets, captureCurrentState, checkoutPayment, closeView, contactsViral, createAsyncBridge, createConstantBridge, createEventBridge, deleteUserPreset, env, eventLog, fetchAlbumItems, fetchAlbumPhotos, fetchContacts, generateHapticFeedback, getAnonymousKey, getAppsInTossGlobals, getClipboardText, getConsentedUserData, getCurrentLocation, getDeclaredAgeRange, getDefaultPlaceholderImages, getDeviceId, getGameCenterGameProfile, getGroupId, getIsTossLoginIntegratedService, getLocale, getNetworkStatus, getOperationalEnvironment, getPermission, getPlatformOS, getSafeAreaInsets, getSchemeUri, getServerTime, getTossAppVersion, getTossShareLink, getUserKeyForGame, getViralCampaign, graniteEvent, grantPromotionReward, grantPromotionRewardForGame, isMinVersionSupported, listUserPresets, loadFullScreenAd, matchesPreset, onVisibilityChangedByTransparentServiceWeb, openCamera, openGameCenterLeaderboard, openPDFViewer, openPermissionDialog, openURL, partner, requestNotificationAgreement, requestPermission, requestReview, requestTossPayPaysBilling, saveBase64Data, saveUserPreset, setClipboardText, setDeviceOrientation, setIosSwipeGestureEnabled, setScreenAwakeMode, setSecureScreen, share, shareViralCampaign, showFullScreenAd, startUpdateLocation, submitGameCenterLeaderBoardScore, tdsEvent };
|
package/dist/panel/index.js
CHANGED
|
@@ -27325,20 +27325,33 @@ function createMockProxy(moduleName, implementations) {
|
|
|
27325
27325
|
throw new Error(`[@apps-in-toss/devtools] ${moduleName}.${prop} is not mocked. This API may exist in @apps-in-toss/web-framework, but devtools' mock does not cover it yet. Please file an issue: ${ISSUES_URL}`);
|
|
27326
27326
|
} });
|
|
27327
27327
|
}
|
|
27328
|
+
//#endregion
|
|
27329
|
+
//#region src/mock/device/storage.ts
|
|
27330
|
+
/**
|
|
27331
|
+
* Storage mock
|
|
27332
|
+
* localStorage에 `__ait_storage:` prefix로 저장하여 앱 자체 localStorage와 분리
|
|
27333
|
+
*
|
|
27334
|
+
* 실기기(2.x×iOS) capture는 `setItem`/`removeItem`/`clearItems` 세 메서드가
|
|
27335
|
+
* `undefined`가 아니라 `null`로 resolve됨을 보였다(devtools#770). 원본 SDK 타입
|
|
27336
|
+
* 선언은 여전히 `Promise<void>`이므로 시그니처는 그대로 두고, 런타임 반환값만
|
|
27337
|
+
* `null`로 캐스트해 실측과 동치시킨다 — Analytics·setClipboardText와 같은 처리(#775).
|
|
27338
|
+
* `getItem`은 이미 `string | null`이라 실측과 일치하므로 손대지 않는다.
|
|
27339
|
+
*/
|
|
27340
|
+
const STORAGE_PREFIX = "__ait_storage:";
|
|
27328
27341
|
createMockProxy("Storage", {
|
|
27329
27342
|
getItem: async (key) => {
|
|
27330
|
-
return localStorage.getItem(
|
|
27343
|
+
return localStorage.getItem(`${STORAGE_PREFIX}${key}`);
|
|
27331
27344
|
},
|
|
27332
27345
|
setItem: async (key, value) => {
|
|
27333
|
-
localStorage.setItem(
|
|
27346
|
+
localStorage.setItem(`${STORAGE_PREFIX}${key}`, value);
|
|
27334
27347
|
return null;
|
|
27335
27348
|
},
|
|
27336
27349
|
removeItem: async (key) => {
|
|
27337
|
-
localStorage.removeItem(
|
|
27350
|
+
localStorage.removeItem(`${STORAGE_PREFIX}${key}`);
|
|
27338
27351
|
return null;
|
|
27339
27352
|
},
|
|
27340
27353
|
clearItems: async () => {
|
|
27341
|
-
const keys = Object.keys(localStorage).filter((k) => k.startsWith(
|
|
27354
|
+
const keys = Object.keys(localStorage).filter((k) => k.startsWith(STORAGE_PREFIX));
|
|
27342
27355
|
for (const k of keys) localStorage.removeItem(k);
|
|
27343
27356
|
return null;
|
|
27344
27357
|
}
|
|
@@ -27848,39 +27861,6 @@ const showFullScreenAd = withIsSupported(observe("showFullScreenAd", "faithful",
|
|
|
27848
27861
|
setTimeout(() => args.onEvent({ type: "dismissed" }), 1500);
|
|
27849
27862
|
return () => {};
|
|
27850
27863
|
}));
|
|
27851
|
-
createMockProxy("Ads", {
|
|
27852
|
-
showTossAdOrShoppingAds: withIsSupported(observe("Ads.showTossAdOrShoppingAds", "faithful", (args) => {
|
|
27853
|
-
if (!aitState.state.ads.isLoaded) {
|
|
27854
|
-
args.onError(/* @__PURE__ */ new Error("Ad not loaded"));
|
|
27855
|
-
return () => {};
|
|
27856
|
-
}
|
|
27857
|
-
const { rewardUnitType, rewardAmount } = aitState.state.ads;
|
|
27858
|
-
setTimeout(() => args.onEvent({
|
|
27859
|
-
type: "userEarnedReward",
|
|
27860
|
-
data: {
|
|
27861
|
-
unitType: rewardUnitType,
|
|
27862
|
-
unitAmount: rewardAmount
|
|
27863
|
-
}
|
|
27864
|
-
}), 1e3);
|
|
27865
|
-
setTimeout(() => {
|
|
27866
|
-
args.onEvent({ type: "dismissed" });
|
|
27867
|
-
aitState.patch("ads", { isLoaded: false });
|
|
27868
|
-
}, 1500);
|
|
27869
|
-
return () => {};
|
|
27870
|
-
})),
|
|
27871
|
-
showTossShoppingAds: withIsSupported(observe("Ads.showTossShoppingAds", "faithful", (args) => {
|
|
27872
|
-
const { rewardUnitType, rewardAmount } = aitState.state.ads;
|
|
27873
|
-
setTimeout(() => args.onEvent({
|
|
27874
|
-
type: "userEarnedReward",
|
|
27875
|
-
data: {
|
|
27876
|
-
unitType: rewardUnitType,
|
|
27877
|
-
unitAmount: rewardAmount
|
|
27878
|
-
}
|
|
27879
|
-
}), 1e3);
|
|
27880
|
-
setTimeout(() => args.onEvent({ type: "dismissed" }), 1500);
|
|
27881
|
-
return () => {};
|
|
27882
|
-
}))
|
|
27883
|
-
});
|
|
27884
27864
|
//#endregion
|
|
27885
27865
|
//#region src/panel/tabs/ads.ts
|
|
27886
27866
|
function recordEvent(type) {
|
|
@@ -30634,7 +30614,7 @@ function Panel() {
|
|
|
30634
30614
|
color: "#666",
|
|
30635
30615
|
fontWeight: 400
|
|
30636
30616
|
},
|
|
30637
|
-
children: ["v", "3.
|
|
30617
|
+
children: ["v", "3.3.0"]
|
|
30638
30618
|
}),
|
|
30639
30619
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
30640
30620
|
type: "button",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apps-in-toss/devtools",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
4
4
|
"description": "Browser development tools for Apps in Toss mini-apps — mock SDK, floating devtools panel, and universal bundler plugin. devDependency only; contributes nothing to a production bundle",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"apps-in-toss",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"unplugin": "^3.2.0"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
|
-
"@apps-in-toss/web-framework": "^3.
|
|
70
|
+
"@apps-in-toss/web-framework": "^3.3.0",
|
|
71
71
|
"@apps-in-toss/web-framework-2x": "npm:@apps-in-toss/web-framework@2.10.8",
|
|
72
72
|
"@testing-library/dom": "10.4.1",
|
|
73
73
|
"@testing-library/react": "16.3.2",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"vitest": "4.1.9"
|
|
85
85
|
},
|
|
86
86
|
"peerDependencies": {
|
|
87
|
-
"@apps-in-toss/web-framework": ">=3.
|
|
87
|
+
"@apps-in-toss/web-framework": ">=2.6.0 <3.0.0 || >=3.0.1 <4.0.0"
|
|
88
88
|
},
|
|
89
89
|
"peerDependenciesMeta": {
|
|
90
90
|
"@apps-in-toss/web-framework": {
|