@ait-co/devtools 0.0.1
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/LICENSE +28 -0
- package/README.md +284 -0
- package/dist/chunk-YYIIG3JT.js +146 -0
- package/dist/chunk-YYIIG3JT.js.map +1 -0
- package/dist/mock/index.d.ts +613 -0
- package/dist/mock/index.js +696 -0
- package/dist/mock/index.js.map +1 -0
- package/dist/panel/index.d.ts +9 -0
- package/dist/panel/index.js +528 -0
- package/dist/panel/index.js.map +1 -0
- package/dist/unplugin/index.cjs +75 -0
- package/dist/unplugin/index.cjs.map +1 -0
- package/dist/unplugin/index.js +46 -0
- package/dist/unplugin/index.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,696 @@
|
|
|
1
|
+
import {
|
|
2
|
+
aitState
|
|
3
|
+
} from "../chunk-YYIIG3JT.js";
|
|
4
|
+
|
|
5
|
+
// src/mock/auth/index.ts
|
|
6
|
+
function appLogin() {
|
|
7
|
+
return Promise.resolve({
|
|
8
|
+
authorizationCode: `mock-auth-${crypto.randomUUID()}`,
|
|
9
|
+
referrer: aitState.state.environment === "toss" ? "DEFAULT" : "SANDBOX"
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
function getIsTossLoginIntegratedService() {
|
|
13
|
+
return Promise.resolve(aitState.state.auth.isTossLoginIntegrated);
|
|
14
|
+
}
|
|
15
|
+
function getUserKeyForGame() {
|
|
16
|
+
if (!aitState.state.auth.userKeyHash) return Promise.resolve(void 0);
|
|
17
|
+
return Promise.resolve({ hash: aitState.state.auth.userKeyHash, type: "HASH" });
|
|
18
|
+
}
|
|
19
|
+
function appsInTossSignTossCert(_params) {
|
|
20
|
+
console.log("[ait-devtools] appsInTossSignTossCert called (no-op in mock)");
|
|
21
|
+
return Promise.resolve();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// src/mock/navigation/index.ts
|
|
25
|
+
function closeView() {
|
|
26
|
+
console.log("[ait-devtools] closeView called");
|
|
27
|
+
window.history.back();
|
|
28
|
+
return Promise.resolve();
|
|
29
|
+
}
|
|
30
|
+
function openURL(url) {
|
|
31
|
+
console.log("[ait-devtools] openURL:", url);
|
|
32
|
+
window.open(url, "_blank");
|
|
33
|
+
return Promise.resolve();
|
|
34
|
+
}
|
|
35
|
+
function share(message) {
|
|
36
|
+
if (navigator.share) {
|
|
37
|
+
return navigator.share({ text: message.message }).then(() => {
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
console.log("[ait-devtools] share:", message.message);
|
|
41
|
+
return Promise.resolve();
|
|
42
|
+
}
|
|
43
|
+
function getTossShareLink(path, _ogImageUrl) {
|
|
44
|
+
return Promise.resolve(`https://toss.im/share/mock${path}`);
|
|
45
|
+
}
|
|
46
|
+
function setIosSwipeGestureEnabled(_options) {
|
|
47
|
+
console.log("[ait-devtools] setIosSwipeGestureEnabled:", _options.isEnabled);
|
|
48
|
+
return Promise.resolve();
|
|
49
|
+
}
|
|
50
|
+
function setDeviceOrientation(_options) {
|
|
51
|
+
console.log("[ait-devtools] setDeviceOrientation:", _options.type);
|
|
52
|
+
return Promise.resolve();
|
|
53
|
+
}
|
|
54
|
+
function setScreenAwakeMode(options) {
|
|
55
|
+
console.log("[ait-devtools] setScreenAwakeMode:", options.enabled);
|
|
56
|
+
return Promise.resolve({ enabled: options.enabled });
|
|
57
|
+
}
|
|
58
|
+
function setSecureScreen(options) {
|
|
59
|
+
console.log("[ait-devtools] setSecureScreen:", options.enabled);
|
|
60
|
+
return Promise.resolve({ enabled: options.enabled });
|
|
61
|
+
}
|
|
62
|
+
function requestReview() {
|
|
63
|
+
console.log("[ait-devtools] requestReview called");
|
|
64
|
+
return Promise.resolve();
|
|
65
|
+
}
|
|
66
|
+
requestReview.isSupported = () => true;
|
|
67
|
+
function getPlatformOS() {
|
|
68
|
+
return aitState.state.platform;
|
|
69
|
+
}
|
|
70
|
+
function getOperationalEnvironment() {
|
|
71
|
+
return aitState.state.environment;
|
|
72
|
+
}
|
|
73
|
+
function getTossAppVersion() {
|
|
74
|
+
return aitState.state.appVersion;
|
|
75
|
+
}
|
|
76
|
+
function isMinVersionSupported(minVersions) {
|
|
77
|
+
const platform = aitState.state.platform;
|
|
78
|
+
const required = platform === "ios" ? minVersions.ios : minVersions.android;
|
|
79
|
+
if (required === "always") return true;
|
|
80
|
+
if (required === "never") return false;
|
|
81
|
+
const current = aitState.state.appVersion.split(".").map(Number);
|
|
82
|
+
const min = required.split(".").map(Number);
|
|
83
|
+
for (let i = 0; i < 3; i++) {
|
|
84
|
+
if ((current[i] ?? 0) > (min[i] ?? 0)) return true;
|
|
85
|
+
if ((current[i] ?? 0) < (min[i] ?? 0)) return false;
|
|
86
|
+
}
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
function getSchemeUri() {
|
|
90
|
+
return aitState.state.schemeUri || window.location.pathname;
|
|
91
|
+
}
|
|
92
|
+
function getLocale() {
|
|
93
|
+
return aitState.state.locale;
|
|
94
|
+
}
|
|
95
|
+
function getDeviceId() {
|
|
96
|
+
return aitState.state.deviceId;
|
|
97
|
+
}
|
|
98
|
+
function getGroupId() {
|
|
99
|
+
return aitState.state.groupId;
|
|
100
|
+
}
|
|
101
|
+
function getNetworkStatus() {
|
|
102
|
+
return Promise.resolve(aitState.state.networkStatus);
|
|
103
|
+
}
|
|
104
|
+
function getServerTime() {
|
|
105
|
+
return Promise.resolve(Date.now());
|
|
106
|
+
}
|
|
107
|
+
getServerTime.isSupported = () => true;
|
|
108
|
+
var graniteEvent = {
|
|
109
|
+
addEventListener(event, { onEvent, onError }) {
|
|
110
|
+
const handler = () => {
|
|
111
|
+
try {
|
|
112
|
+
onEvent();
|
|
113
|
+
} catch (e) {
|
|
114
|
+
onError?.(e instanceof Error ? e : new Error(String(e)));
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
window.addEventListener(`__ait:${event}`, handler);
|
|
118
|
+
return () => window.removeEventListener(`__ait:${event}`, handler);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
var appsInTossEvent = {
|
|
122
|
+
addEventListener(_event, _handlers) {
|
|
123
|
+
return () => {
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
var tdsEvent = {
|
|
128
|
+
addEventListener(event, { onEvent }) {
|
|
129
|
+
const handler = (e) => {
|
|
130
|
+
const detail = e.detail;
|
|
131
|
+
onEvent(detail);
|
|
132
|
+
};
|
|
133
|
+
window.addEventListener(`__ait:${event}`, handler);
|
|
134
|
+
return () => window.removeEventListener(`__ait:${event}`, handler);
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
function onVisibilityChangedByTransparentServiceWeb(eventParams) {
|
|
138
|
+
const handler = () => eventParams.onEvent(!document.hidden);
|
|
139
|
+
document.addEventListener("visibilitychange", handler);
|
|
140
|
+
return () => document.removeEventListener("visibilitychange", handler);
|
|
141
|
+
}
|
|
142
|
+
var env = {
|
|
143
|
+
getDeploymentId: () => aitState.state.deploymentId
|
|
144
|
+
};
|
|
145
|
+
function getAppsInTossGlobals() {
|
|
146
|
+
return {
|
|
147
|
+
deploymentId: aitState.state.deploymentId,
|
|
148
|
+
brandDisplayName: aitState.state.brand.displayName,
|
|
149
|
+
brandIcon: aitState.state.brand.icon,
|
|
150
|
+
brandPrimaryColor: aitState.state.brand.primaryColor
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
var SafeAreaInsets = {
|
|
154
|
+
get: () => ({ ...aitState.state.safeAreaInsets }),
|
|
155
|
+
// NOTE: aitState.subscribe에 위임하므로 safeAreaInsets 외 상태 변경에도 콜백이 호출된다.
|
|
156
|
+
// 실제 SDK는 insets 변경 시에만 호출되지만, mock에서는 간소화를 위해 필터링하지 않는다.
|
|
157
|
+
subscribe: ({ onEvent }) => {
|
|
158
|
+
return aitState.subscribe(() => onEvent({ ...aitState.state.safeAreaInsets }));
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
function getSafeAreaInsets() {
|
|
162
|
+
return aitState.state.safeAreaInsets.top;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// src/mock/proxy.ts
|
|
166
|
+
var WARNED = /* @__PURE__ */ new Set();
|
|
167
|
+
function createMockProxy(moduleName, implementations) {
|
|
168
|
+
return new Proxy(implementations, {
|
|
169
|
+
get(target, prop) {
|
|
170
|
+
if (prop in target) return target[prop];
|
|
171
|
+
if (typeof prop === "symbol") return void 0;
|
|
172
|
+
if (!WARNED.has(`${moduleName}.${prop}`)) {
|
|
173
|
+
console.warn(
|
|
174
|
+
`[ait-devtools] ${moduleName}.${prop} is not mocked yet. Returning no-op. Please update ait-devtools or file an issue.`
|
|
175
|
+
);
|
|
176
|
+
WARNED.add(`${moduleName}.${prop}`);
|
|
177
|
+
}
|
|
178
|
+
return async () => void 0;
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// src/mock/permissions.ts
|
|
184
|
+
function getPermission(name) {
|
|
185
|
+
return Promise.resolve(aitState.state.permissions[name]);
|
|
186
|
+
}
|
|
187
|
+
function openPermissionDialog(name) {
|
|
188
|
+
const current = aitState.state.permissions[name];
|
|
189
|
+
if (current === "allowed") return Promise.resolve("allowed");
|
|
190
|
+
aitState.patch("permissions", { [name]: "allowed" });
|
|
191
|
+
return Promise.resolve("allowed");
|
|
192
|
+
}
|
|
193
|
+
function requestPermission(permission) {
|
|
194
|
+
return openPermissionDialog(permission.name);
|
|
195
|
+
}
|
|
196
|
+
function withPermission(fn, permissionName) {
|
|
197
|
+
const enhanced = fn;
|
|
198
|
+
enhanced.getPermission = () => getPermission(permissionName);
|
|
199
|
+
enhanced.openPermissionDialog = () => openPermissionDialog(permissionName);
|
|
200
|
+
return enhanced;
|
|
201
|
+
}
|
|
202
|
+
function checkPermission(name, fnName) {
|
|
203
|
+
const status = aitState.state.permissions[name];
|
|
204
|
+
if (status === "denied") {
|
|
205
|
+
throw new Error(`[ait-devtools] ${fnName}: Permission "${name}" is denied. Change it in the DevTools panel.`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// src/mock/device/index.ts
|
|
210
|
+
var Storage = createMockProxy("Storage", {
|
|
211
|
+
getItem: async (key) => {
|
|
212
|
+
return localStorage.getItem(`__ait_storage:${key}`);
|
|
213
|
+
},
|
|
214
|
+
setItem: async (key, value) => {
|
|
215
|
+
localStorage.setItem(`__ait_storage:${key}`, value);
|
|
216
|
+
},
|
|
217
|
+
removeItem: async (key) => {
|
|
218
|
+
localStorage.removeItem(`__ait_storage:${key}`);
|
|
219
|
+
},
|
|
220
|
+
clearItems: async () => {
|
|
221
|
+
const keys = Object.keys(localStorage).filter((k) => k.startsWith("__ait_storage:"));
|
|
222
|
+
keys.forEach((k) => localStorage.removeItem(k));
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
var Accuracy = /* @__PURE__ */ ((Accuracy2) => {
|
|
226
|
+
Accuracy2[Accuracy2["Lowest"] = 1] = "Lowest";
|
|
227
|
+
Accuracy2[Accuracy2["Low"] = 2] = "Low";
|
|
228
|
+
Accuracy2[Accuracy2["Balanced"] = 3] = "Balanced";
|
|
229
|
+
Accuracy2[Accuracy2["High"] = 4] = "High";
|
|
230
|
+
Accuracy2[Accuracy2["Highest"] = 5] = "Highest";
|
|
231
|
+
Accuracy2[Accuracy2["BestForNavigation"] = 6] = "BestForNavigation";
|
|
232
|
+
return Accuracy2;
|
|
233
|
+
})(Accuracy || {});
|
|
234
|
+
function buildLocation() {
|
|
235
|
+
return {
|
|
236
|
+
coords: { ...aitState.state.location.coords },
|
|
237
|
+
timestamp: Date.now(),
|
|
238
|
+
accessLocation: aitState.state.location.accessLocation
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
var _getCurrentLocation = async (_options) => {
|
|
242
|
+
checkPermission("geolocation", "getCurrentLocation");
|
|
243
|
+
return buildLocation();
|
|
244
|
+
};
|
|
245
|
+
var getCurrentLocation = withPermission(_getCurrentLocation, "geolocation");
|
|
246
|
+
function _startUpdateLocation(eventParams) {
|
|
247
|
+
const { onEvent, options } = eventParams;
|
|
248
|
+
const interval = Math.max(options.timeInterval, 500);
|
|
249
|
+
const id = setInterval(() => {
|
|
250
|
+
const loc = buildLocation();
|
|
251
|
+
loc.coords.latitude += (Math.random() - 0.5) * 1e-4;
|
|
252
|
+
loc.coords.longitude += (Math.random() - 0.5) * 1e-4;
|
|
253
|
+
onEvent(loc);
|
|
254
|
+
}, interval);
|
|
255
|
+
return () => clearInterval(id);
|
|
256
|
+
}
|
|
257
|
+
var startUpdateLocation = Object.assign(_startUpdateLocation, {
|
|
258
|
+
getPermission: () => withPermission(_getCurrentLocation, "geolocation").getPermission(),
|
|
259
|
+
openPermissionDialog: () => withPermission(_getCurrentLocation, "geolocation").openPermissionDialog()
|
|
260
|
+
});
|
|
261
|
+
var _openCamera = async (options) => {
|
|
262
|
+
checkPermission("camera", "openCamera");
|
|
263
|
+
return new Promise((resolve, reject) => {
|
|
264
|
+
const input = document.createElement("input");
|
|
265
|
+
input.type = "file";
|
|
266
|
+
input.accept = "image/*";
|
|
267
|
+
input.capture = "environment";
|
|
268
|
+
input.onchange = () => {
|
|
269
|
+
const file = input.files?.[0];
|
|
270
|
+
if (!file) {
|
|
271
|
+
reject(new Error("No file selected"));
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
const reader = new FileReader();
|
|
275
|
+
reader.onload = () => {
|
|
276
|
+
resolve({
|
|
277
|
+
id: crypto.randomUUID(),
|
|
278
|
+
dataUri: reader.result
|
|
279
|
+
});
|
|
280
|
+
};
|
|
281
|
+
reader.readAsDataURL(file);
|
|
282
|
+
};
|
|
283
|
+
input.click();
|
|
284
|
+
});
|
|
285
|
+
};
|
|
286
|
+
var openCamera = withPermission(_openCamera, "camera");
|
|
287
|
+
var _fetchAlbumPhotos = async (options) => {
|
|
288
|
+
checkPermission("photos", "fetchAlbumPhotos");
|
|
289
|
+
const maxCount = options?.maxCount ?? 10;
|
|
290
|
+
return new Promise((resolve, reject) => {
|
|
291
|
+
const input = document.createElement("input");
|
|
292
|
+
input.type = "file";
|
|
293
|
+
input.accept = "image/*";
|
|
294
|
+
input.multiple = true;
|
|
295
|
+
input.onchange = async () => {
|
|
296
|
+
const files = Array.from(input.files ?? []).slice(0, maxCount);
|
|
297
|
+
if (files.length === 0) {
|
|
298
|
+
reject(new Error("No files selected"));
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
const results = await Promise.all(
|
|
302
|
+
files.map((file) => new Promise((res) => {
|
|
303
|
+
const reader = new FileReader();
|
|
304
|
+
reader.onload = () => res({ id: crypto.randomUUID(), dataUri: reader.result });
|
|
305
|
+
reader.readAsDataURL(file);
|
|
306
|
+
}))
|
|
307
|
+
);
|
|
308
|
+
resolve(results);
|
|
309
|
+
};
|
|
310
|
+
input.click();
|
|
311
|
+
});
|
|
312
|
+
};
|
|
313
|
+
var fetchAlbumPhotos = withPermission(_fetchAlbumPhotos, "photos");
|
|
314
|
+
var _fetchContacts = async (options) => {
|
|
315
|
+
checkPermission("contacts", "fetchContacts");
|
|
316
|
+
let contacts = aitState.state.contacts;
|
|
317
|
+
if (options.query?.contains) {
|
|
318
|
+
const q = options.query.contains.toLowerCase();
|
|
319
|
+
contacts = contacts.filter((c) => c.name.toLowerCase().includes(q) || c.phoneNumber.includes(q));
|
|
320
|
+
}
|
|
321
|
+
const sliced = contacts.slice(options.offset, options.offset + options.size);
|
|
322
|
+
const nextOffset = options.offset + options.size;
|
|
323
|
+
return {
|
|
324
|
+
result: sliced,
|
|
325
|
+
nextOffset: nextOffset < contacts.length ? nextOffset : null,
|
|
326
|
+
done: nextOffset >= contacts.length
|
|
327
|
+
};
|
|
328
|
+
};
|
|
329
|
+
var fetchContacts = withPermission(_fetchContacts, "contacts");
|
|
330
|
+
var _getClipboardText = async () => {
|
|
331
|
+
checkPermission("clipboard", "getClipboardText");
|
|
332
|
+
try {
|
|
333
|
+
return await navigator.clipboard.readText();
|
|
334
|
+
} catch {
|
|
335
|
+
return "";
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
var getClipboardText = withPermission(_getClipboardText, "clipboard");
|
|
339
|
+
var _setClipboardText = async (text) => {
|
|
340
|
+
checkPermission("clipboard", "setClipboardText");
|
|
341
|
+
await navigator.clipboard.writeText(text);
|
|
342
|
+
};
|
|
343
|
+
var setClipboardText = withPermission(_setClipboardText, "clipboard");
|
|
344
|
+
function generateHapticFeedback(options) {
|
|
345
|
+
console.log(`[ait-devtools] haptic: ${options.type}`);
|
|
346
|
+
aitState.logAnalytics({ type: "haptic", params: { hapticType: options.type } });
|
|
347
|
+
return Promise.resolve();
|
|
348
|
+
}
|
|
349
|
+
function saveBase64Data(params) {
|
|
350
|
+
const a = document.createElement("a");
|
|
351
|
+
a.href = `data:${params.mimeType};base64,${params.data}`;
|
|
352
|
+
a.download = params.fileName;
|
|
353
|
+
a.click();
|
|
354
|
+
return Promise.resolve();
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// src/mock/iap/index.ts
|
|
358
|
+
var orderCounter = 0;
|
|
359
|
+
function generateOrderId() {
|
|
360
|
+
return `mock-order-${++orderCounter}-${Date.now()}`;
|
|
361
|
+
}
|
|
362
|
+
function buildOrderResult(sku) {
|
|
363
|
+
const product = aitState.state.iap.products.find((p) => p.sku === sku);
|
|
364
|
+
const amountStr = product?.displayAmount?.replace(/[^0-9]/g, "") ?? "1000";
|
|
365
|
+
return {
|
|
366
|
+
orderId: generateOrderId(),
|
|
367
|
+
displayName: product?.displayName ?? "Mock Product",
|
|
368
|
+
displayAmount: product?.displayAmount ?? "1,000\uC6D0",
|
|
369
|
+
amount: parseInt(amountStr, 10) || 1e3,
|
|
370
|
+
currency: "KRW",
|
|
371
|
+
fraction: 0,
|
|
372
|
+
miniAppIconUrl: product?.iconUrl || null
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
async function handlePurchase(sku, processProductGrant, onEvent, onError) {
|
|
376
|
+
const nextResult = aitState.state.iap.nextResult;
|
|
377
|
+
await new Promise((r) => setTimeout(r, 300));
|
|
378
|
+
if (nextResult !== "success") {
|
|
379
|
+
onError({ code: nextResult });
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
const result = buildOrderResult(sku);
|
|
383
|
+
try {
|
|
384
|
+
const granted = await processProductGrant({ orderId: result.orderId });
|
|
385
|
+
if (!granted) {
|
|
386
|
+
onError({ code: "PRODUCT_NOT_GRANTED_BY_PARTNER" });
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
} catch (e) {
|
|
390
|
+
onError(e);
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
aitState.patch("iap", {
|
|
394
|
+
completedOrders: [...aitState.state.iap.completedOrders, {
|
|
395
|
+
orderId: result.orderId,
|
|
396
|
+
sku,
|
|
397
|
+
status: "COMPLETED",
|
|
398
|
+
date: (/* @__PURE__ */ new Date()).toISOString()
|
|
399
|
+
}]
|
|
400
|
+
});
|
|
401
|
+
await onEvent({ type: "success", data: result });
|
|
402
|
+
}
|
|
403
|
+
var IAP = createMockProxy("IAP", {
|
|
404
|
+
// 반환되는 cancel 함수는 mock에서는 no-op이다 (실제 SDK는 결제 UI를 닫음)
|
|
405
|
+
createOneTimePurchaseOrder(params) {
|
|
406
|
+
const sku = params.options.sku ?? params.options.productId ?? "";
|
|
407
|
+
handlePurchase(sku, params.options.processProductGrant, params.onEvent, params.onError).catch((e) => console.error("[ait-devtools] IAP unexpected error:", e));
|
|
408
|
+
return () => {
|
|
409
|
+
};
|
|
410
|
+
},
|
|
411
|
+
createSubscriptionPurchaseOrder(params) {
|
|
412
|
+
handlePurchase(params.options.sku, params.options.processProductGrant, params.onEvent, params.onError).catch((e) => console.error("[ait-devtools] IAP unexpected error:", e));
|
|
413
|
+
return () => {
|
|
414
|
+
};
|
|
415
|
+
},
|
|
416
|
+
async getProductItemList() {
|
|
417
|
+
return {
|
|
418
|
+
products: aitState.state.iap.products.map((p) => ({
|
|
419
|
+
...p,
|
|
420
|
+
...p.type === "SUBSCRIPTION" ? { renewalCycle: p.renewalCycle ?? "MONTHLY" } : {}
|
|
421
|
+
}))
|
|
422
|
+
};
|
|
423
|
+
},
|
|
424
|
+
async getPendingOrders() {
|
|
425
|
+
return { orders: [...aitState.state.iap.pendingOrders] };
|
|
426
|
+
},
|
|
427
|
+
async getCompletedOrRefundedOrders() {
|
|
428
|
+
return {
|
|
429
|
+
hasNext: false,
|
|
430
|
+
nextKey: null,
|
|
431
|
+
orders: [...aitState.state.iap.completedOrders]
|
|
432
|
+
};
|
|
433
|
+
},
|
|
434
|
+
async completeProductGrant(args) {
|
|
435
|
+
const idx = aitState.state.iap.pendingOrders.findIndex((o) => o.orderId === args.params.orderId);
|
|
436
|
+
if (idx !== -1) {
|
|
437
|
+
const order = aitState.state.iap.pendingOrders[idx];
|
|
438
|
+
const pendingOrders = aitState.state.iap.pendingOrders.filter((_, i) => i !== idx);
|
|
439
|
+
const completedOrders = [...aitState.state.iap.completedOrders, {
|
|
440
|
+
orderId: order.orderId,
|
|
441
|
+
sku: order.sku,
|
|
442
|
+
status: "COMPLETED",
|
|
443
|
+
date: (/* @__PURE__ */ new Date()).toISOString()
|
|
444
|
+
}];
|
|
445
|
+
aitState.patch("iap", { pendingOrders, completedOrders });
|
|
446
|
+
}
|
|
447
|
+
return true;
|
|
448
|
+
},
|
|
449
|
+
async getSubscriptionInfo(_args) {
|
|
450
|
+
return {
|
|
451
|
+
subscription: {
|
|
452
|
+
catalogId: 1,
|
|
453
|
+
status: "ACTIVE",
|
|
454
|
+
expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1e3).toISOString(),
|
|
455
|
+
isAutoRenew: true,
|
|
456
|
+
gracePeriodExpiresAt: null,
|
|
457
|
+
isAccessible: true
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
function checkoutPayment(options) {
|
|
463
|
+
const { nextResult, failReason } = aitState.state.payment;
|
|
464
|
+
console.log("[ait-devtools] checkoutPayment:", options.params.payToken);
|
|
465
|
+
return new Promise((resolve) => {
|
|
466
|
+
setTimeout(() => {
|
|
467
|
+
if (nextResult === "success") {
|
|
468
|
+
resolve({ success: true });
|
|
469
|
+
} else {
|
|
470
|
+
resolve({ success: false, reason: failReason || "Mock payment failed" });
|
|
471
|
+
}
|
|
472
|
+
}, 300);
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// src/mock/ads/index.ts
|
|
477
|
+
function withIsSupported(fn) {
|
|
478
|
+
fn.isSupported = () => true;
|
|
479
|
+
return fn;
|
|
480
|
+
}
|
|
481
|
+
var GoogleAdMob = createMockProxy("GoogleAdMob", {
|
|
482
|
+
loadAppsInTossAdMob: withIsSupported((args) => {
|
|
483
|
+
setTimeout(() => {
|
|
484
|
+
aitState.patch("ads", { isLoaded: true });
|
|
485
|
+
args.onEvent({ type: "loaded", data: { adGroupId: args.options?.adGroupId } });
|
|
486
|
+
}, 200);
|
|
487
|
+
return () => {
|
|
488
|
+
};
|
|
489
|
+
}),
|
|
490
|
+
showAppsInTossAdMob: withIsSupported((args) => {
|
|
491
|
+
if (!aitState.state.ads.isLoaded) {
|
|
492
|
+
args.onError(new Error("Ad not loaded"));
|
|
493
|
+
return () => {
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
setTimeout(() => args.onEvent({ type: "requested" }), 50);
|
|
497
|
+
setTimeout(() => args.onEvent({ type: "show" }), 100);
|
|
498
|
+
setTimeout(() => args.onEvent({ type: "impression" }), 150);
|
|
499
|
+
setTimeout(() => {
|
|
500
|
+
args.onEvent({ type: "userEarnedReward", data: { unitType: "coins", unitAmount: 10 } });
|
|
501
|
+
}, 1e3);
|
|
502
|
+
setTimeout(() => {
|
|
503
|
+
args.onEvent({ type: "dismissed" });
|
|
504
|
+
aitState.patch("ads", { isLoaded: false });
|
|
505
|
+
}, 1500);
|
|
506
|
+
return () => {
|
|
507
|
+
};
|
|
508
|
+
}),
|
|
509
|
+
isAppsInTossAdMobLoaded: withIsSupported(
|
|
510
|
+
async (_options) => aitState.state.ads.isLoaded
|
|
511
|
+
)
|
|
512
|
+
});
|
|
513
|
+
var TossAds = createMockProxy("TossAds", {
|
|
514
|
+
initialize: withIsSupported((_options) => {
|
|
515
|
+
console.log("[ait-devtools] TossAds.initialize (mock)");
|
|
516
|
+
}),
|
|
517
|
+
attach: withIsSupported((_adGroupId, target, _options) => {
|
|
518
|
+
const el = typeof target === "string" ? document.querySelector(target) : target;
|
|
519
|
+
if (el) {
|
|
520
|
+
const placeholder = document.createElement("div");
|
|
521
|
+
placeholder.style.cssText = "background:#f0f0f0;border:1px dashed #999;padding:16px;text-align:center;color:#666;font-size:14px;";
|
|
522
|
+
placeholder.textContent = "[ait-devtools] TossAds Placeholder";
|
|
523
|
+
el.appendChild(placeholder);
|
|
524
|
+
}
|
|
525
|
+
}),
|
|
526
|
+
attachBanner: withIsSupported((_adGroupId, target, _options) => {
|
|
527
|
+
const el = typeof target === "string" ? document.querySelector(target) : target;
|
|
528
|
+
if (el) {
|
|
529
|
+
const placeholder = document.createElement("div");
|
|
530
|
+
placeholder.style.cssText = "background:#f0f0f0;border:1px dashed #999;padding:12px;text-align:center;color:#666;font-size:12px;";
|
|
531
|
+
placeholder.textContent = "[ait-devtools] Banner Ad Placeholder";
|
|
532
|
+
el.appendChild(placeholder);
|
|
533
|
+
}
|
|
534
|
+
return { destroy: () => {
|
|
535
|
+
} };
|
|
536
|
+
}),
|
|
537
|
+
destroy: withIsSupported((_slotId) => {
|
|
538
|
+
}),
|
|
539
|
+
destroyAll: withIsSupported(() => {
|
|
540
|
+
})
|
|
541
|
+
});
|
|
542
|
+
var loadFullScreenAd = withIsSupported((args) => {
|
|
543
|
+
setTimeout(() => {
|
|
544
|
+
aitState.patch("ads", { isLoaded: true });
|
|
545
|
+
args.onEvent({ type: "loaded", data: { adGroupId: args.options?.adGroupId } });
|
|
546
|
+
}, 200);
|
|
547
|
+
return () => {
|
|
548
|
+
};
|
|
549
|
+
});
|
|
550
|
+
var showFullScreenAd = withIsSupported((args) => {
|
|
551
|
+
if (!aitState.state.ads.isLoaded) {
|
|
552
|
+
args.onError(new Error("Ad not loaded"));
|
|
553
|
+
return () => {
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
setTimeout(() => args.onEvent({ type: "show" }), 100);
|
|
557
|
+
setTimeout(() => args.onEvent({ type: "dismissed" }), 1500);
|
|
558
|
+
return () => {
|
|
559
|
+
};
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
// src/mock/game/index.ts
|
|
563
|
+
function grantPromotionReward(params) {
|
|
564
|
+
console.log("[ait-devtools] grantPromotionReward:", params.params);
|
|
565
|
+
return Promise.resolve({ key: `mock-reward-${Date.now()}` });
|
|
566
|
+
}
|
|
567
|
+
function grantPromotionRewardForGame(params) {
|
|
568
|
+
console.log("[ait-devtools] grantPromotionRewardForGame:", params.params);
|
|
569
|
+
return Promise.resolve({ key: `mock-reward-${Date.now()}` });
|
|
570
|
+
}
|
|
571
|
+
function submitGameCenterLeaderBoardScore(params) {
|
|
572
|
+
aitState.patch("game", {
|
|
573
|
+
leaderboardScores: [...aitState.state.game.leaderboardScores, { score: params.score, timestamp: Date.now() }]
|
|
574
|
+
});
|
|
575
|
+
return Promise.resolve({ statusCode: "SUCCESS" });
|
|
576
|
+
}
|
|
577
|
+
function getGameCenterGameProfile() {
|
|
578
|
+
const profile = aitState.state.game.profile;
|
|
579
|
+
if (!profile) return Promise.resolve({ statusCode: "PROFILE_NOT_FOUND" });
|
|
580
|
+
return Promise.resolve({
|
|
581
|
+
statusCode: "SUCCESS",
|
|
582
|
+
nickname: profile.nickname,
|
|
583
|
+
profileImageUri: profile.profileImageUri
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
function openGameCenterLeaderboard() {
|
|
587
|
+
console.log("[ait-devtools] openGameCenterLeaderboard (no-op in browser)");
|
|
588
|
+
return Promise.resolve();
|
|
589
|
+
}
|
|
590
|
+
function contactsViral(params) {
|
|
591
|
+
setTimeout(() => {
|
|
592
|
+
params.onEvent({
|
|
593
|
+
type: "close",
|
|
594
|
+
data: {
|
|
595
|
+
closeReason: "noReward",
|
|
596
|
+
sentRewardsCount: 0
|
|
597
|
+
}
|
|
598
|
+
});
|
|
599
|
+
}, 500);
|
|
600
|
+
return () => {
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// src/mock/analytics/index.ts
|
|
605
|
+
var Analytics = {
|
|
606
|
+
screen: (params) => {
|
|
607
|
+
aitState.logAnalytics({ type: "screen", params: params ?? {} });
|
|
608
|
+
return Promise.resolve();
|
|
609
|
+
},
|
|
610
|
+
impression: (params) => {
|
|
611
|
+
aitState.logAnalytics({ type: "impression", params: params ?? {} });
|
|
612
|
+
return Promise.resolve();
|
|
613
|
+
},
|
|
614
|
+
click: (params) => {
|
|
615
|
+
aitState.logAnalytics({ type: "click", params: params ?? {} });
|
|
616
|
+
return Promise.resolve();
|
|
617
|
+
}
|
|
618
|
+
};
|
|
619
|
+
function eventLog(params) {
|
|
620
|
+
aitState.logAnalytics({ type: params.log_type, params: { log_name: params.log_name, ...params.params } });
|
|
621
|
+
return Promise.resolve();
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
// src/mock/partner/index.ts
|
|
625
|
+
var partner = {
|
|
626
|
+
async addAccessoryButton(options) {
|
|
627
|
+
console.log("[ait-devtools] partner.addAccessoryButton:", options);
|
|
628
|
+
},
|
|
629
|
+
async removeAccessoryButton() {
|
|
630
|
+
console.log("[ait-devtools] partner.removeAccessoryButton");
|
|
631
|
+
}
|
|
632
|
+
};
|
|
633
|
+
export {
|
|
634
|
+
Accuracy,
|
|
635
|
+
Analytics,
|
|
636
|
+
GoogleAdMob,
|
|
637
|
+
IAP,
|
|
638
|
+
SafeAreaInsets,
|
|
639
|
+
Storage,
|
|
640
|
+
TossAds,
|
|
641
|
+
aitState,
|
|
642
|
+
appLogin,
|
|
643
|
+
appsInTossEvent,
|
|
644
|
+
appsInTossSignTossCert,
|
|
645
|
+
checkoutPayment,
|
|
646
|
+
closeView,
|
|
647
|
+
contactsViral,
|
|
648
|
+
env,
|
|
649
|
+
eventLog,
|
|
650
|
+
fetchAlbumPhotos,
|
|
651
|
+
fetchContacts,
|
|
652
|
+
generateHapticFeedback,
|
|
653
|
+
getAppsInTossGlobals,
|
|
654
|
+
getClipboardText,
|
|
655
|
+
getCurrentLocation,
|
|
656
|
+
getDeviceId,
|
|
657
|
+
getGameCenterGameProfile,
|
|
658
|
+
getGroupId,
|
|
659
|
+
getIsTossLoginIntegratedService,
|
|
660
|
+
getLocale,
|
|
661
|
+
getNetworkStatus,
|
|
662
|
+
getOperationalEnvironment,
|
|
663
|
+
getPermission,
|
|
664
|
+
getPlatformOS,
|
|
665
|
+
getSafeAreaInsets,
|
|
666
|
+
getSchemeUri,
|
|
667
|
+
getServerTime,
|
|
668
|
+
getTossAppVersion,
|
|
669
|
+
getTossShareLink,
|
|
670
|
+
getUserKeyForGame,
|
|
671
|
+
graniteEvent,
|
|
672
|
+
grantPromotionReward,
|
|
673
|
+
grantPromotionRewardForGame,
|
|
674
|
+
isMinVersionSupported,
|
|
675
|
+
loadFullScreenAd,
|
|
676
|
+
onVisibilityChangedByTransparentServiceWeb,
|
|
677
|
+
openCamera,
|
|
678
|
+
openGameCenterLeaderboard,
|
|
679
|
+
openPermissionDialog,
|
|
680
|
+
openURL,
|
|
681
|
+
partner,
|
|
682
|
+
requestPermission,
|
|
683
|
+
requestReview,
|
|
684
|
+
saveBase64Data,
|
|
685
|
+
setClipboardText,
|
|
686
|
+
setDeviceOrientation,
|
|
687
|
+
setIosSwipeGestureEnabled,
|
|
688
|
+
setScreenAwakeMode,
|
|
689
|
+
setSecureScreen,
|
|
690
|
+
share,
|
|
691
|
+
showFullScreenAd,
|
|
692
|
+
startUpdateLocation,
|
|
693
|
+
submitGameCenterLeaderBoardScore,
|
|
694
|
+
tdsEvent
|
|
695
|
+
};
|
|
696
|
+
//# sourceMappingURL=index.js.map
|