@apps-in-toss/framework 0.0.0-dev.1743134070910 → 0.0.0-dev.1744801739343
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +263 -35
- package/dist/index.d.cts +152 -8
- package/dist/index.d.ts +152 -8
- package/dist/index.js +257 -32
- package/package.json +21 -12
- package/src/constant-bridges.ts +2 -0
package/dist/index.cjs
CHANGED
|
@@ -32,6 +32,7 @@ var src_exports = {};
|
|
|
32
32
|
__export(src_exports, {
|
|
33
33
|
Accuracy: () => Accuracy2,
|
|
34
34
|
AppsInToss: () => AppsInToss,
|
|
35
|
+
Storage: () => Storage,
|
|
35
36
|
TossPay: () => TossPay,
|
|
36
37
|
WebView: () => WebView,
|
|
37
38
|
appLogin: () => appLogin,
|
|
@@ -40,7 +41,9 @@ __export(src_exports, {
|
|
|
40
41
|
fetchContacts: () => fetchContacts,
|
|
41
42
|
getClipboardText: () => getClipboardText,
|
|
42
43
|
getCurrentLocation: () => getCurrentLocation,
|
|
44
|
+
getDeviceId: () => getDeviceId,
|
|
43
45
|
getOperationalEnvironment: () => getOperationalEnvironment,
|
|
46
|
+
getTossAppVersion: () => getTossAppVersion,
|
|
44
47
|
openCamera: () => openCamera,
|
|
45
48
|
setClipboardText: () => setClipboardText,
|
|
46
49
|
startUpdateLocation: () => startUpdateLocation,
|
|
@@ -282,6 +285,39 @@ function getOperationalEnvironment() {
|
|
|
282
285
|
return AppsInTossModule.operationalEnvironment;
|
|
283
286
|
}
|
|
284
287
|
|
|
288
|
+
// src/native-modules/getTossAppVersion.ts
|
|
289
|
+
function getTossAppVersion() {
|
|
290
|
+
return AppsInTossModule.tossAppVersion;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// src/native-modules/getDeviceId.ts
|
|
294
|
+
function getDeviceId() {
|
|
295
|
+
return AppsInTossModule.deviceId;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// src/native-modules/storage.ts
|
|
299
|
+
function getItem(key) {
|
|
300
|
+
return AppsInTossModule.getStorageItem({ key });
|
|
301
|
+
}
|
|
302
|
+
function setItem(key, value) {
|
|
303
|
+
return AppsInTossModule.setStorageItem({
|
|
304
|
+
key,
|
|
305
|
+
value
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
function removeItem(key) {
|
|
309
|
+
return AppsInTossModule.removeStorageItem({ key });
|
|
310
|
+
}
|
|
311
|
+
function clearItems() {
|
|
312
|
+
return AppsInTossModule.clearStorage({});
|
|
313
|
+
}
|
|
314
|
+
var Storage = {
|
|
315
|
+
getItem,
|
|
316
|
+
setItem,
|
|
317
|
+
removeItem,
|
|
318
|
+
clearItems
|
|
319
|
+
};
|
|
320
|
+
|
|
285
321
|
// src/native-modules/index.ts
|
|
286
322
|
var TossPay = {
|
|
287
323
|
checkoutPayment,
|
|
@@ -289,16 +325,19 @@ var TossPay = {
|
|
|
289
325
|
};
|
|
290
326
|
|
|
291
327
|
// src/components/WebView.tsx
|
|
292
|
-
var
|
|
293
|
-
var
|
|
328
|
+
var import_react_native12 = require("@toss-design-system/react-native");
|
|
329
|
+
var import_private = require("@toss-design-system/react-native/private");
|
|
330
|
+
var import_react4 = require("react");
|
|
294
331
|
var import_react_native_bedrock5 = require("react-native-bedrock");
|
|
295
332
|
var bedrockAsyncBridges = __toESM(require("react-native-bedrock/async-bridges"), 1);
|
|
296
333
|
var bedrockConstantBridges = __toESM(require("react-native-bedrock/constant-bridges"), 1);
|
|
297
334
|
|
|
298
335
|
// src/components/GameWebView.tsx
|
|
299
336
|
var import_react_native_webview = require("@react-native-bedrock/native/react-native-webview");
|
|
337
|
+
var import_react_native10 = require("@toss-design-system/react-native");
|
|
338
|
+
var import_es_hangul = require("es-hangul");
|
|
300
339
|
var import_react2 = require("react");
|
|
301
|
-
var
|
|
340
|
+
var import_react_native11 = require("react-native");
|
|
302
341
|
var import_react_native_bedrock4 = require("react-native-bedrock");
|
|
303
342
|
|
|
304
343
|
// src/components/GameWebViewNavigationBar/GameNavigationBar.tsx
|
|
@@ -382,6 +421,9 @@ function GameNavigationBar({ onClose }) {
|
|
|
382
421
|
import_react_native9.TouchableOpacity,
|
|
383
422
|
{
|
|
384
423
|
hitSlop: { left: 8, right: 8 },
|
|
424
|
+
accessibilityRole: "button",
|
|
425
|
+
accessible: true,
|
|
426
|
+
accessibilityLabel: "\uAC8C\uC784\uC885\uB8CC",
|
|
385
427
|
style: {
|
|
386
428
|
padding: import_react_native9.Platform.OS === "ios" ? 7 : 9
|
|
387
429
|
},
|
|
@@ -397,16 +439,41 @@ function GameNavigationBar({ onClose }) {
|
|
|
397
439
|
// src/components/GameWebView.tsx
|
|
398
440
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
399
441
|
var GameWebView = (0, import_react2.forwardRef)(function GameWebView2(props, ref) {
|
|
442
|
+
const { openConfirm } = (0, import_react_native10.useDialog)();
|
|
443
|
+
const { brandDisplayName } = getAppsInTossGlobals();
|
|
444
|
+
const handleClose = (0, import_react2.useCallback)(async () => {
|
|
445
|
+
const isConfirmed = await openConfirm({
|
|
446
|
+
title: `${(0, import_es_hangul.josa)(brandDisplayName, "\uC744/\uB97C")} \uC885\uB8CC\uD560\uAE4C\uC694?`,
|
|
447
|
+
leftButton: "\uCDE8\uC18C",
|
|
448
|
+
rightButton: "\uC885\uB8CC\uD558\uAE30",
|
|
449
|
+
closeOnDimmerClick: true
|
|
450
|
+
});
|
|
451
|
+
if (isConfirmed) {
|
|
452
|
+
(0, import_react_native_bedrock4.closeView)();
|
|
453
|
+
}
|
|
454
|
+
}, [brandDisplayName, openConfirm]);
|
|
455
|
+
(0, import_react2.useEffect)(() => {
|
|
456
|
+
if (import_react_native11.Platform.OS === "ios") {
|
|
457
|
+
(0, import_react_native_bedrock4.setIosSwipeGestureEnabled)({ isEnabled: false });
|
|
458
|
+
return () => {
|
|
459
|
+
(0, import_react_native_bedrock4.setIosSwipeGestureEnabled)({ isEnabled: true });
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
return;
|
|
463
|
+
}, []);
|
|
464
|
+
(0, import_react2.useEffect)(() => {
|
|
465
|
+
const backHandler = () => {
|
|
466
|
+
handleClose();
|
|
467
|
+
return true;
|
|
468
|
+
};
|
|
469
|
+
import_react_native11.BackHandler.addEventListener("hardwareBackPress", backHandler);
|
|
470
|
+
return () => {
|
|
471
|
+
import_react_native11.BackHandler.removeEventListener("hardwareBackPress", backHandler);
|
|
472
|
+
};
|
|
473
|
+
}, [handleClose]);
|
|
400
474
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
401
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
402
|
-
|
|
403
|
-
{
|
|
404
|
-
onClose: () => {
|
|
405
|
-
(0, import_react_native_bedrock4.closeView)();
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
),
|
|
409
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native10.View, { style: { flex: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_webview.WebView, { ref, ...props }) })
|
|
475
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(GameNavigationBar, { onClose: handleClose }),
|
|
476
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native11.View, { style: { flex: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_webview.WebView, { ref, ...props }) })
|
|
410
477
|
] });
|
|
411
478
|
});
|
|
412
479
|
|
|
@@ -424,10 +491,138 @@ __export(async_bridges_exports, {
|
|
|
424
491
|
setClipboardText: () => setClipboardText
|
|
425
492
|
});
|
|
426
493
|
|
|
494
|
+
// src/bridge-handler/useBridgeHandler.tsx
|
|
495
|
+
var import_react3 = require("react");
|
|
496
|
+
function serializeError(error) {
|
|
497
|
+
return JSON.stringify(error, (_, value) => {
|
|
498
|
+
if (value instanceof Error) {
|
|
499
|
+
return {
|
|
500
|
+
name: value.name,
|
|
501
|
+
message: value.message,
|
|
502
|
+
stack: value.stack,
|
|
503
|
+
__isError: true
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
return value;
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
function methodHandler({
|
|
510
|
+
args,
|
|
511
|
+
eventId,
|
|
512
|
+
functionName,
|
|
513
|
+
handlerMap,
|
|
514
|
+
injectJavaScript
|
|
515
|
+
}) {
|
|
516
|
+
const func = async (...args2) => {
|
|
517
|
+
const result = await handlerMap[functionName](...args2);
|
|
518
|
+
return result;
|
|
519
|
+
};
|
|
520
|
+
if (!func) {
|
|
521
|
+
console.error(`${functionName} is not a function`);
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
func(...args).then((result) => {
|
|
525
|
+
injectJavaScript?.(`
|
|
526
|
+
window.__BEDROCK_NATIVE_EMITTER.emit('${functionName}/resolve/${eventId}', ${JSON.stringify(result, null, 0)});
|
|
527
|
+
`);
|
|
528
|
+
}).catch((error) => {
|
|
529
|
+
const serializedError = serializeError(error);
|
|
530
|
+
injectJavaScript?.(`
|
|
531
|
+
window.__BEDROCK_NATIVE_EMITTER.emit('${functionName}/reject/${eventId}', ${serializedError});
|
|
532
|
+
`);
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
var globalEventListenerMap = /* @__PURE__ */ new Map();
|
|
536
|
+
function useBridgeHandler({
|
|
537
|
+
onMessage,
|
|
538
|
+
constantHandlerMap,
|
|
539
|
+
asyncHandlerMap,
|
|
540
|
+
eventListenerMap,
|
|
541
|
+
injectedJavaScript: originalInjectedJavaScript
|
|
542
|
+
}) {
|
|
543
|
+
const ref = (0, import_react3.useRef)(null);
|
|
544
|
+
const injectedJavaScript = (0, import_react3.useMemo)(
|
|
545
|
+
() => [
|
|
546
|
+
`window.__CONSTANT_HANDLER_MAP = ${JSON.stringify(
|
|
547
|
+
Object.entries(constantHandlerMap).reduce(
|
|
548
|
+
(acc, [key, value]) => {
|
|
549
|
+
acc[key] = typeof value === "function" ? value() : value;
|
|
550
|
+
return acc;
|
|
551
|
+
},
|
|
552
|
+
{}
|
|
553
|
+
)
|
|
554
|
+
)}`,
|
|
555
|
+
originalInjectedJavaScript,
|
|
556
|
+
"true"
|
|
557
|
+
].join("\n"),
|
|
558
|
+
[constantHandlerMap, originalInjectedJavaScript]
|
|
559
|
+
);
|
|
560
|
+
const createHandleOnEvent = (functionName, eventId) => (response) => {
|
|
561
|
+
ref.current?.injectJavaScript(`
|
|
562
|
+
window.__BEDROCK_NATIVE_EMITTER.emit('${functionName}/onEvent/${eventId}', ${JSON.stringify(response, null, 0)});
|
|
563
|
+
`);
|
|
564
|
+
};
|
|
565
|
+
const createHandleOnError = (functionName, eventId) => (error) => {
|
|
566
|
+
ref.current?.injectJavaScript(`
|
|
567
|
+
window.__BEDROCK_NATIVE_EMITTER.emit('${functionName}/onError/${eventId}', ${JSON.stringify(error, null, 0)});
|
|
568
|
+
`);
|
|
569
|
+
};
|
|
570
|
+
const $onMessage = (0, import_react3.useCallback)(
|
|
571
|
+
async (e) => {
|
|
572
|
+
onMessage?.(e);
|
|
573
|
+
const data = JSON.parse(e.nativeEvent.data);
|
|
574
|
+
if (typeof data !== "object" || data === null || typeof data.functionName !== "string" || typeof data.eventId !== "string" || typeof data.type !== "string" || !["addEventListener", "removeEventListener", "method"].includes(data.type)) {
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
switch (data.type) {
|
|
578
|
+
case "addEventListener": {
|
|
579
|
+
const handleOnEvent = createHandleOnEvent(data.functionName, data.eventId);
|
|
580
|
+
const handleOnError = createHandleOnError(data.functionName, data.eventId);
|
|
581
|
+
const remove = eventListenerMap[data.functionName]?.({
|
|
582
|
+
onEvent: handleOnEvent,
|
|
583
|
+
onError: handleOnError,
|
|
584
|
+
options: data.args
|
|
585
|
+
});
|
|
586
|
+
if (remove) {
|
|
587
|
+
globalEventListenerMap.set(`${data.functionName}/${data.eventId}`, remove);
|
|
588
|
+
}
|
|
589
|
+
break;
|
|
590
|
+
}
|
|
591
|
+
case "removeEventListener": {
|
|
592
|
+
const key = `${data.functionName}/${data.eventId}`;
|
|
593
|
+
const remove = globalEventListenerMap.get(key);
|
|
594
|
+
remove?.();
|
|
595
|
+
globalEventListenerMap.delete(key);
|
|
596
|
+
break;
|
|
597
|
+
}
|
|
598
|
+
case "method": {
|
|
599
|
+
methodHandler({
|
|
600
|
+
args: data.args,
|
|
601
|
+
eventId: data.eventId,
|
|
602
|
+
functionName: data.functionName,
|
|
603
|
+
handlerMap: asyncHandlerMap,
|
|
604
|
+
injectJavaScript: ref.current?.injectJavaScript
|
|
605
|
+
});
|
|
606
|
+
break;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
},
|
|
610
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
611
|
+
[onMessage]
|
|
612
|
+
);
|
|
613
|
+
return {
|
|
614
|
+
ref,
|
|
615
|
+
injectedJavaScript,
|
|
616
|
+
onMessage: $onMessage
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
|
|
427
620
|
// src/constant-bridges.ts
|
|
428
621
|
var constant_bridges_exports = {};
|
|
429
622
|
__export(constant_bridges_exports, {
|
|
430
|
-
|
|
623
|
+
getDeviceId: () => getDeviceId,
|
|
624
|
+
getOperationalEnvironment: () => getOperationalEnvironment,
|
|
625
|
+
getTossAppVersion: () => getTossAppVersion
|
|
431
626
|
});
|
|
432
627
|
|
|
433
628
|
// src/env.ts
|
|
@@ -444,9 +639,10 @@ __export(event_bridges_exports, {
|
|
|
444
639
|
// src/components/WebView.tsx
|
|
445
640
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
446
641
|
var appsInTossGlobals = getAppsInTossGlobals();
|
|
642
|
+
var TYPES = ["partner", "external", "game"];
|
|
447
643
|
var WEBVIEW_TYPES = {
|
|
448
|
-
partner:
|
|
449
|
-
external:
|
|
644
|
+
partner: import_react_native12.PartnerWebViewScreen,
|
|
645
|
+
external: import_react_native12.ExternalWebViewScreen,
|
|
450
646
|
game: GameWebView
|
|
451
647
|
};
|
|
452
648
|
function mergeSchemeQueryParamsInto(url) {
|
|
@@ -472,45 +668,65 @@ function getWebViewUri(local) {
|
|
|
472
668
|
return url.toString();
|
|
473
669
|
}
|
|
474
670
|
function WebView({ type, local, onMessage, ...props }) {
|
|
475
|
-
|
|
476
|
-
|
|
671
|
+
if (!TYPES.includes(type)) {
|
|
672
|
+
throw new Error(`Invalid WebView type: '${type}'`);
|
|
673
|
+
}
|
|
674
|
+
const bedrockEvent = (0, import_react_native_bedrock5.useBedrockEvent)();
|
|
675
|
+
const uri = (0, import_react4.useMemo)(() => getWebViewUri(local), [local]);
|
|
676
|
+
const top = (0, import_private.useSafeAreaTop)();
|
|
677
|
+
const bottom = (0, import_private.useSafeAreaBottom)();
|
|
678
|
+
const handler = useBridgeHandler({
|
|
477
679
|
onMessage,
|
|
478
680
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
479
|
-
eventListenerMap:
|
|
681
|
+
eventListenerMap: {
|
|
682
|
+
...event_bridges_exports,
|
|
683
|
+
backEvent: ({ onEvent, onError, options }) => bedrockEvent.addEventListener("backEvent", { onEvent, onError, options })
|
|
684
|
+
},
|
|
480
685
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
481
686
|
// @ts-expect-error
|
|
482
687
|
constantHandlerMap: {
|
|
483
688
|
...bedrockConstantBridges,
|
|
484
|
-
...constant_bridges_exports
|
|
689
|
+
...constant_bridges_exports,
|
|
690
|
+
getSafeAreaTop: () => top,
|
|
691
|
+
getSafeAreaBottom: () => bottom
|
|
485
692
|
},
|
|
486
693
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
487
694
|
// @ts-expect-error
|
|
488
695
|
asyncHandlerMap: {
|
|
489
696
|
...bedrockAsyncBridges,
|
|
490
|
-
...async_bridges_exports
|
|
697
|
+
...async_bridges_exports,
|
|
698
|
+
/** internal */
|
|
699
|
+
openPermissionDialog: AppsInTossModule.openPermissionDialog,
|
|
700
|
+
/** Storage */
|
|
701
|
+
getStorageItem: Storage.getItem,
|
|
702
|
+
setStorageItem: Storage.setItem,
|
|
703
|
+
removeStorageItem: Storage.removeItem,
|
|
704
|
+
clearItems: Storage.clearItems
|
|
491
705
|
}
|
|
492
706
|
});
|
|
493
|
-
const baseProps = (0,
|
|
707
|
+
const baseProps = (0, import_react4.useMemo)(() => {
|
|
494
708
|
switch (type) {
|
|
495
709
|
case "partner": {
|
|
496
|
-
|
|
710
|
+
const headerOnlyProp = {
|
|
497
711
|
header: {
|
|
498
|
-
...props.header,
|
|
499
|
-
icon: toIcon(appsInTossGlobals.brandIcon),
|
|
500
|
-
title: appsInTossGlobals.brandDisplayName,
|
|
712
|
+
..."header" in props ? props.header : {},
|
|
713
|
+
icon: toIcon(ensureValue(appsInTossGlobals.brandIcon, "icon")),
|
|
714
|
+
title: ensureValue(appsInTossGlobals.brandDisplayName, "displayName"),
|
|
501
715
|
rightButtons: void 0
|
|
502
716
|
// TODO: onClick 이벤트를 받아야 하기에 런타임에서 설정 받아야 함
|
|
503
717
|
}
|
|
504
718
|
};
|
|
719
|
+
return headerOnlyProp;
|
|
505
720
|
}
|
|
506
721
|
case "external": {
|
|
507
|
-
|
|
722
|
+
const headerOnlyProp = {
|
|
508
723
|
header: {
|
|
509
|
-
...props.header,
|
|
510
|
-
icon: toIcon(appsInTossGlobals.brandIcon),
|
|
511
|
-
title: appsInTossGlobals.brandDisplayName
|
|
724
|
+
..."header" in props ? props.header : {},
|
|
725
|
+
icon: toIcon(ensureValue(appsInTossGlobals.brandIcon, "icon")),
|
|
726
|
+
title: ensureValue(appsInTossGlobals.brandDisplayName, "displayName")
|
|
512
727
|
}
|
|
513
728
|
};
|
|
729
|
+
return headerOnlyProp;
|
|
514
730
|
}
|
|
515
731
|
default: {
|
|
516
732
|
return {};
|
|
@@ -518,31 +734,40 @@ function WebView({ type, local, onMessage, ...props }) {
|
|
|
518
734
|
}
|
|
519
735
|
}, [type, props]);
|
|
520
736
|
const BaseWebView = WEBVIEW_TYPES[type];
|
|
737
|
+
const webviewDebuggingEnabled = (0, import_react4.useMemo)(
|
|
738
|
+
() => getOperationalEnvironment() === "sandbox",
|
|
739
|
+
[]
|
|
740
|
+
);
|
|
521
741
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
522
742
|
BaseWebView,
|
|
523
743
|
{
|
|
524
744
|
ref: handler.ref,
|
|
525
|
-
...baseProps,
|
|
526
745
|
...props,
|
|
746
|
+
...baseProps,
|
|
527
747
|
source: { uri },
|
|
528
748
|
sharedCookiesEnabled: true,
|
|
749
|
+
webviewDebuggingEnabled,
|
|
529
750
|
thirdPartyCookiesEnabled: true,
|
|
530
|
-
cacheEnabled: false,
|
|
531
|
-
cacheMode: "LOAD_NO_CACHE",
|
|
532
751
|
onMessage: handler.onMessage,
|
|
533
752
|
injectedJavaScript: handler.injectedJavaScript,
|
|
534
753
|
injectedJavaScriptBeforeContentLoaded: handler.injectedJavaScript
|
|
535
754
|
}
|
|
536
755
|
);
|
|
537
756
|
}
|
|
757
|
+
function ensureValue(value, name) {
|
|
758
|
+
if (value === void 0) {
|
|
759
|
+
throw new Error(`${name} is required`);
|
|
760
|
+
}
|
|
761
|
+
return value;
|
|
762
|
+
}
|
|
538
763
|
|
|
539
764
|
// src/hooks/useGeolocation.ts
|
|
540
|
-
var
|
|
765
|
+
var import_react5 = require("react");
|
|
541
766
|
var import_react_native_bedrock6 = require("react-native-bedrock");
|
|
542
767
|
function useGeolocation({ accuracy, distanceInterval, timeInterval }) {
|
|
543
768
|
const isVisible = (0, import_react_native_bedrock6.useVisibility)();
|
|
544
|
-
const [location, setLocation] = (0,
|
|
545
|
-
(0,
|
|
769
|
+
const [location, setLocation] = (0, import_react5.useState)(null);
|
|
770
|
+
(0, import_react5.useEffect)(() => {
|
|
546
771
|
if (!isVisible) {
|
|
547
772
|
return;
|
|
548
773
|
}
|
|
@@ -573,6 +798,7 @@ var Accuracy2 = /* @__PURE__ */ ((Accuracy3) => {
|
|
|
573
798
|
0 && (module.exports = {
|
|
574
799
|
Accuracy,
|
|
575
800
|
AppsInToss,
|
|
801
|
+
Storage,
|
|
576
802
|
TossPay,
|
|
577
803
|
WebView,
|
|
578
804
|
appLogin,
|
|
@@ -581,7 +807,9 @@ var Accuracy2 = /* @__PURE__ */ ((Accuracy3) => {
|
|
|
581
807
|
fetchContacts,
|
|
582
808
|
getClipboardText,
|
|
583
809
|
getCurrentLocation,
|
|
810
|
+
getDeviceId,
|
|
584
811
|
getOperationalEnvironment,
|
|
812
|
+
getTossAppVersion,
|
|
585
813
|
openCamera,
|
|
586
814
|
setClipboardText,
|
|
587
815
|
startUpdateLocation,
|
package/dist/index.d.cts
CHANGED
|
@@ -70,7 +70,7 @@ interface Location {
|
|
|
70
70
|
*/
|
|
71
71
|
timestamp: number;
|
|
72
72
|
/**
|
|
73
|
-
* @description 위치 정보를 나타내는 객체예요. 자세한 내용은 [LocationCoords](/reference/framework/Types/LocationCoords.html)을 참고해주세요.
|
|
73
|
+
* @description 위치 정보를 나타내는 객체예요. 자세한 내용은 [LocationCoords](/react-native/reference/framework/Types/LocationCoords.html)을 참고해주세요.
|
|
74
74
|
*/
|
|
75
75
|
coords: LocationCoords;
|
|
76
76
|
}
|
|
@@ -154,7 +154,7 @@ interface UpdateLocationEventEmitter extends EventEmitterSchema<'updateLocation'
|
|
|
154
154
|
* @param {number} [options.accuracy] 위치 정확도를 설정해요.
|
|
155
155
|
* @param {number} [options.timeInterval] 위치 정보를 업데이트하는 최소 주기로, 단위는 밀리초(ms)예요. 이 값은 위치 업데이트가 발생하는 가장 짧은 간격을 설정하지만, 시스템이나 환경의 영향을 받아 지정한 주기보다 더 긴 간격으로 업데이트될 수 있어요.
|
|
156
156
|
* @param {number} [options.distanceInterval] 위치 변경 거리를 미터(m) 단위로 설정해요.
|
|
157
|
-
* @param {(location: Location) => void} [options.callback] 위치 정보가 변경될 때 호출되는 콜백 함수예요. 자세한 내용은 [Location](/reference/framework/Types/Location.html)을 참고해주세요.
|
|
157
|
+
* @param {(location: Location) => void} [options.callback] 위치 정보가 변경될 때 호출되는 콜백 함수예요. 자세한 내용은 [Location](/react-native/reference/framework/Types/Location.html)을 참고해주세요.
|
|
158
158
|
*
|
|
159
159
|
* @example
|
|
160
160
|
* ### 위치 정보 변경 감지하기
|
|
@@ -569,7 +569,7 @@ interface TossMoneyExecutePaymentResult {
|
|
|
569
569
|
* @param {ExecutePaymentOptions} options 결제를 실행할 때 필요한 옵션이에요.
|
|
570
570
|
* @param {string} options.orderNo 결제를 생성할 때 사용한 주문번호예요.
|
|
571
571
|
* @param {string} options.payToken 결제 인증 과정에서 전달받은 결제 토큰이에요. 결제를 실행할 때 사용해요.
|
|
572
|
-
* @returns {Promise<CardExecutePaymentResult | TossMoneyExecutePaymentResult>} 결제 결과 객체를 반환해요. 자세한 내용은 [카드 결제 결과](reference/framework/토스페이/CardExecutePaymentResult.html) 또는 [토스머니 결제 결과](reference/framework/토스페이/TossMoneyExecutePaymentResult.html)를 참고하세요.
|
|
572
|
+
* @returns {Promise<CardExecutePaymentResult | TossMoneyExecutePaymentResult>} 결제 결과 객체를 반환해요. 자세한 내용은 [카드 결제 결과](/react-native/reference/framework/토스페이/CardExecutePaymentResult.html) 또는 [토스머니 결제 결과](/react-native/reference/framework/토스페이/TossMoneyExecutePaymentResult.html)를 참고하세요.
|
|
573
573
|
*
|
|
574
574
|
* @example
|
|
575
575
|
*
|
|
@@ -858,7 +858,7 @@ interface GetCurrentLocationOptions {
|
|
|
858
858
|
*
|
|
859
859
|
* @param {GetCurrentLocationOptions} options 위치 정보를 가져올 때 사용하는 옵션 객체예요.
|
|
860
860
|
* @param {Accuracy} [options.accuracy] 위치 정보의 정확도 수준이에요. 정확도는 `Accuracy` 타입으로 설정돼요.
|
|
861
|
-
* @returns {Promise<Location>} 디바이스의 위치 정보가 담긴 객체를 반환해요. 자세한 내용은 [Location](/reference/framework/Types/Location.html)을 참고해주세요.
|
|
861
|
+
* @returns {Promise<Location>} 디바이스의 위치 정보가 담긴 객체를 반환해요. 자세한 내용은 [Location](/react-native/reference/framework/Types/Location.html)을 참고해주세요.
|
|
862
862
|
*
|
|
863
863
|
* @example
|
|
864
864
|
* ### 디바이스의 현재 위치 정보 가져오기
|
|
@@ -1027,13 +1027,157 @@ declare function appLogin(): Promise<{
|
|
|
1027
1027
|
*/
|
|
1028
1028
|
declare function getOperationalEnvironment(): 'toss' | 'sandbox';
|
|
1029
1029
|
|
|
1030
|
+
/**
|
|
1031
|
+
* @public
|
|
1032
|
+
* @category 환경 확인
|
|
1033
|
+
* @name getTossAppVersion
|
|
1034
|
+
* @description 토스 앱 버전을 가져옵니다. 예를 들어, `5.206.0`과 같은 형태로 반환돼요. 토스 앱 버전을 로그로 남기거나, 특정 기능이 특정 버전 이상에서만 실행될 때 사용돼요.
|
|
1035
|
+
* @signature
|
|
1036
|
+
* ```typescript
|
|
1037
|
+
* function getTossAppVersion(): string
|
|
1038
|
+
* ```
|
|
1039
|
+
*
|
|
1040
|
+
* @returns {string} 토스 앱 버전
|
|
1041
|
+
*
|
|
1042
|
+
* @example
|
|
1043
|
+
*
|
|
1044
|
+
*
|
|
1045
|
+
* ### 토스 앱 버전 확인하기
|
|
1046
|
+
*
|
|
1047
|
+
* ```tsx
|
|
1048
|
+
* import { getTossAppVersion } from '@apps-in-toss/framework';
|
|
1049
|
+
* import { Text } from 'react-native';
|
|
1050
|
+
*
|
|
1051
|
+
* export function TossAppVersionPage() {
|
|
1052
|
+
* return (
|
|
1053
|
+
* <Text>{getTossAppVersion()}</Text>
|
|
1054
|
+
* )
|
|
1055
|
+
* }
|
|
1056
|
+
* ```
|
|
1057
|
+
*/
|
|
1058
|
+
declare function getTossAppVersion(): string;
|
|
1059
|
+
|
|
1060
|
+
/**
|
|
1061
|
+
* @public
|
|
1062
|
+
* @category 환경 확인
|
|
1063
|
+
* @kind function
|
|
1064
|
+
* @name getDeviceId
|
|
1065
|
+
* @description
|
|
1066
|
+
* 사용 중인 기기의 고유 식별자를 문자열로 반환해요.
|
|
1067
|
+
*
|
|
1068
|
+
* 이 함수는 현재 사용 중인 기기의 고유 식별자를 문자열로 반환해요. 기기별로 설정이나 데이터를 저장하거나 사용자의 기기를 식별해서 로그를 기록하고 분석하는 데 사용할 수 있어요. 같은 사용자의 여러 기기를 구분하는 데도 유용해요.
|
|
1069
|
+
*
|
|
1070
|
+
* @returns {string} 기기의 고유 식별자를 나타내는 문자열이에요.
|
|
1071
|
+
*
|
|
1072
|
+
* @example
|
|
1073
|
+
* ### 기기 고유 식별자 가져오기
|
|
1074
|
+
*
|
|
1075
|
+
* ```tsx
|
|
1076
|
+
* import { getDeviceId } from '@apps-in-toss/framework';
|
|
1077
|
+
* import { Text } from 'react-native';
|
|
1078
|
+
*
|
|
1079
|
+
* function MyPage() {
|
|
1080
|
+
* const id = getDeviceId();
|
|
1081
|
+
*
|
|
1082
|
+
* return (
|
|
1083
|
+
* <Text>사용자의 기기 고유 식별자: {id}</Text>
|
|
1084
|
+
* );
|
|
1085
|
+
* }
|
|
1086
|
+
* ```
|
|
1087
|
+
*/
|
|
1088
|
+
declare function getDeviceId(): string;
|
|
1089
|
+
|
|
1090
|
+
/**
|
|
1091
|
+
* @public
|
|
1092
|
+
* @category 저장소
|
|
1093
|
+
* @name getItem
|
|
1094
|
+
* @description 모바일 앱의 로컬 저장소에서 문자열 데이터를 가져와요. 주로 앱이 종료되었다가 다시 시작해도 데이터가 유지되어야 하는 경우에 사용해요.
|
|
1095
|
+
* @param {string} key - 가져올 아이템의 키를 입력해요.
|
|
1096
|
+
* @returns {Promise<string | null>} 지정한 키에 저장된 문자열 값을 반환해요. 값이 없으면 `null`을 반환해요.
|
|
1097
|
+
* @example
|
|
1098
|
+
*
|
|
1099
|
+
* ### `my-key`에 저장된 아이템 가져오기
|
|
1100
|
+
* ```ts
|
|
1101
|
+
* const value = await Storage.getItem('my-key');
|
|
1102
|
+
* console.log(value); // 'value'
|
|
1103
|
+
* ```
|
|
1104
|
+
*/
|
|
1105
|
+
declare function getItem(key: string): Promise<string | null>;
|
|
1106
|
+
/**
|
|
1107
|
+
* @public
|
|
1108
|
+
* @category 저장소
|
|
1109
|
+
* @name setItem
|
|
1110
|
+
* @description 모바일 앱의 로컬 저장소에 문자열 데이터를 저장해요. 주로 앱이 종료되었다가 다시 시작해도 데이터가 유지되어야 하는 경우에 사용해요.
|
|
1111
|
+
* @param {string} key - 저장할 아이템의 키를 입력해요.
|
|
1112
|
+
* @param {string} value - 저장할 아이템의 값을 입력해요.
|
|
1113
|
+
* @returns {Promise<void>} 아이템을 성공적으로 저장하면 아무 값도 반환하지 않아요.
|
|
1114
|
+
* @example
|
|
1115
|
+
*
|
|
1116
|
+
* ### `my-key`에 아이템 저장하기
|
|
1117
|
+
* ```ts
|
|
1118
|
+
* import { Storage } from '@apps-in-toss/framework';
|
|
1119
|
+
*
|
|
1120
|
+
* await Storage.setItem('my-key', 'value');
|
|
1121
|
+
* ```
|
|
1122
|
+
*/
|
|
1123
|
+
declare function setItem(key: string, value: string): Promise<void>;
|
|
1124
|
+
/**
|
|
1125
|
+
* @public
|
|
1126
|
+
* @category 저장소
|
|
1127
|
+
* @name removeItem
|
|
1128
|
+
* @description 모바일 앱의 로컬 저장소에서 특정 키에 해당하는 아이템을 삭제해요.
|
|
1129
|
+
* @param {string} key - 삭제할 아이템의 키를 입력해요.
|
|
1130
|
+
* @returns {Promise<void>} 아이템을 삭제하면 아무 값도 반환하지 않아요.
|
|
1131
|
+
* @example
|
|
1132
|
+
*
|
|
1133
|
+
* ### `my-key`에 저장된 아이템 삭제하기
|
|
1134
|
+
* ```ts
|
|
1135
|
+
* import { Storage } from '@apps-in-toss/framework';
|
|
1136
|
+
*
|
|
1137
|
+
* await Storage.removeItem('my-key');
|
|
1138
|
+
* ```
|
|
1139
|
+
*/
|
|
1140
|
+
declare function removeItem(key: string): Promise<void>;
|
|
1141
|
+
/**
|
|
1142
|
+
* @public
|
|
1143
|
+
* @category 저장소
|
|
1144
|
+
* @name clearItems
|
|
1145
|
+
* @description 모바일 앱의 로컬 저장소의 모든 아이템을 삭제해요.
|
|
1146
|
+
* @returns {Promise<void>} 아이템을 삭제하면 아무 값도 반환하지 않고 저장소가 초기화돼요.
|
|
1147
|
+
* @example
|
|
1148
|
+
*
|
|
1149
|
+
* ### 저장소 초기화하기
|
|
1150
|
+
* ```ts
|
|
1151
|
+
* import { Storage } from '@apps-in-toss/framework';
|
|
1152
|
+
*
|
|
1153
|
+
* await Storage.clearItems();
|
|
1154
|
+
* ```
|
|
1155
|
+
*/
|
|
1156
|
+
declare function clearItems(): Promise<void>;
|
|
1157
|
+
/**
|
|
1158
|
+
* @public
|
|
1159
|
+
* @category 저장소
|
|
1160
|
+
* @name Storage
|
|
1161
|
+
* @description 네이티브의 저장소를 사용해요.
|
|
1162
|
+
* @property {typeof getItem} [getItem] 모바일 앱의 로컬 저장소에서 아이템을 가져오는 함수예요. 자세한 내용은 [getItem](/react-native/reference/framework/저장소/getItem)을 참고하세요.
|
|
1163
|
+
* @property {typeof setItem} [setItem] 모바일 앱의 로컬 저장소에 아이템을 저장하는 함수예요. 자세한 내용은 [setItem](/react-native/reference/framework/저장소/setItem)을 참고하세요.
|
|
1164
|
+
* @property {typeof removeItem} [removeItem] 모바일 앱의 로컬 저장소에서 아이템을 삭제하는 함수예요. 자세한 내용은 [removeItem](/react-native/reference/framework/저장소/removeItem)을 참고하세요.
|
|
1165
|
+
* @property {typeof clearItems} [clearItems] 모바일 앱의 로컬 저장소를 초기화하는 함수예요. 자세한 내용은 [clearItems](/react-native/reference/framework/저장소/clearItems)을 참고하세요.
|
|
1166
|
+
*/
|
|
1167
|
+
declare const Storage: {
|
|
1168
|
+
getItem: typeof getItem;
|
|
1169
|
+
setItem: typeof setItem;
|
|
1170
|
+
removeItem: typeof removeItem;
|
|
1171
|
+
clearItems: typeof clearItems;
|
|
1172
|
+
};
|
|
1173
|
+
|
|
1030
1174
|
/**
|
|
1031
1175
|
* @public
|
|
1032
1176
|
* @category 토스페이
|
|
1033
1177
|
* @name TossPay
|
|
1034
1178
|
* @description 토스페이 결제 관련 함수를 모아둔 객체예요.
|
|
1035
|
-
* @property {typeof checkoutPayment} [checkoutPayment] 토스페이 결제를 생성하는 함수예요. 자세한 내용은 [checkoutPayment](reference/framework/토스페이/checkoutPayment)를 참고하세요.
|
|
1036
|
-
* @property {typeof executePayment} [executePayment] 토스페이 결제를 실행하는 함수예요. 자세한 내용은 [executePayment](reference/framework/토스페이/executePayment)를 참고하세요.
|
|
1179
|
+
* @property {typeof checkoutPayment} [checkoutPayment] 토스페이 결제를 생성하는 함수예요. 자세한 내용은 [checkoutPayment](/react-native/reference/framework/토스페이/checkoutPayment)를 참고하세요.
|
|
1180
|
+
* @property {typeof executePayment} [executePayment] 토스페이 결제를 실행하는 함수예요. 자세한 내용은 [executePayment](/react-native/reference/framework/토스페이/executePayment)를 참고하세요.
|
|
1037
1181
|
*/
|
|
1038
1182
|
declare const TossPay: {
|
|
1039
1183
|
checkoutPayment: typeof checkoutPayment;
|
|
@@ -1076,7 +1220,7 @@ type UseGeolocationOptions = Omit<StartUpdateLocationOptions, 'callback'>;
|
|
|
1076
1220
|
* @param {Accuracy} [options.accuracy] 위치 정확도를 설정해요. `Accuracy.Lowest`: 오차범위 3KM 이내, `Accuracy.Low`: 오차범위 1KM 이내, `Accuracy.Balanced`: 오차범위 몇 백미터 이내, `Accuracy.High`: 오차범위 10M 이내, `Accuracy.Highest`: 가장 높은 정확도, `Accuracy.BestForNavigation`: 네비게이션을 위한 최고 정확도
|
|
1077
1221
|
* @param {number} [options.timeInterval] 위치 정보를 업데이트하는 최소 주기로, 단위는 밀리초(ms)예요. 이 값은 위치 업데이트가 발생하는 가장 짧은 간격을 설정하지만, 시스템이나 환경의 영향을 받아 지정한 주기보다 더 긴 간격으로 업데이트될 수 있어요.
|
|
1078
1222
|
* @param {number} [options.distanceInterval] 위치 변경 거리를 미터(m) 단위로 설정해요.
|
|
1079
|
-
* @returns {Location | null} 디바이스의 위치 정보가 담긴 객체를 반환해요. 자세한 내용은 [Location](/reference/framework/Types/Location.html)을 참고해주세요.
|
|
1223
|
+
* @returns {Location | null} 디바이스의 위치 정보가 담긴 객체를 반환해요. 자세한 내용은 [Location](/react-native/reference/framework/Types/Location.html)을 참고해주세요.
|
|
1080
1224
|
*
|
|
1081
1225
|
* @example
|
|
1082
1226
|
* ### 위치 정보 변경 감지하기
|
|
@@ -1112,4 +1256,4 @@ declare const env: {
|
|
|
1112
1256
|
getDeploymentId: () => string | undefined;
|
|
1113
1257
|
};
|
|
1114
1258
|
|
|
1115
|
-
export { Accuracy, AppsInToss, type ContactEntity, type ExternalWebViewProps, type FetchAlbumPhotosOptions, type GameWebViewProps, type GetCurrentLocationOptions, type ImageResponse, type Location, type LocationCoords, type OpenCameraOptions, type PartnerWebViewProps, type StartUpdateLocationOptions, type StartUpdateLocationSubscription, TossPay, type UpdateLocationEventEmitter, type UseGeolocationOptions, WebView, type WebViewProps, appLogin, env, fetchAlbumPhotos, fetchContacts, getClipboardText, getCurrentLocation, getOperationalEnvironment, openCamera, setClipboardText, startUpdateLocation, useGeolocation };
|
|
1259
|
+
export { Accuracy, AppsInToss, type ContactEntity, type ExternalWebViewProps, type FetchAlbumPhotosOptions, type GameWebViewProps, type GetCurrentLocationOptions, type ImageResponse, type Location, type LocationCoords, type OpenCameraOptions, type PartnerWebViewProps, type StartUpdateLocationOptions, type StartUpdateLocationSubscription, Storage, TossPay, type UpdateLocationEventEmitter, type UseGeolocationOptions, WebView, type WebViewProps, appLogin, env, fetchAlbumPhotos, fetchContacts, getClipboardText, getCurrentLocation, getDeviceId, getOperationalEnvironment, getTossAppVersion, openCamera, setClipboardText, startUpdateLocation, useGeolocation };
|
package/dist/index.d.ts
CHANGED
|
@@ -70,7 +70,7 @@ interface Location {
|
|
|
70
70
|
*/
|
|
71
71
|
timestamp: number;
|
|
72
72
|
/**
|
|
73
|
-
* @description 위치 정보를 나타내는 객체예요. 자세한 내용은 [LocationCoords](/reference/framework/Types/LocationCoords.html)을 참고해주세요.
|
|
73
|
+
* @description 위치 정보를 나타내는 객체예요. 자세한 내용은 [LocationCoords](/react-native/reference/framework/Types/LocationCoords.html)을 참고해주세요.
|
|
74
74
|
*/
|
|
75
75
|
coords: LocationCoords;
|
|
76
76
|
}
|
|
@@ -154,7 +154,7 @@ interface UpdateLocationEventEmitter extends EventEmitterSchema<'updateLocation'
|
|
|
154
154
|
* @param {number} [options.accuracy] 위치 정확도를 설정해요.
|
|
155
155
|
* @param {number} [options.timeInterval] 위치 정보를 업데이트하는 최소 주기로, 단위는 밀리초(ms)예요. 이 값은 위치 업데이트가 발생하는 가장 짧은 간격을 설정하지만, 시스템이나 환경의 영향을 받아 지정한 주기보다 더 긴 간격으로 업데이트될 수 있어요.
|
|
156
156
|
* @param {number} [options.distanceInterval] 위치 변경 거리를 미터(m) 단위로 설정해요.
|
|
157
|
-
* @param {(location: Location) => void} [options.callback] 위치 정보가 변경될 때 호출되는 콜백 함수예요. 자세한 내용은 [Location](/reference/framework/Types/Location.html)을 참고해주세요.
|
|
157
|
+
* @param {(location: Location) => void} [options.callback] 위치 정보가 변경될 때 호출되는 콜백 함수예요. 자세한 내용은 [Location](/react-native/reference/framework/Types/Location.html)을 참고해주세요.
|
|
158
158
|
*
|
|
159
159
|
* @example
|
|
160
160
|
* ### 위치 정보 변경 감지하기
|
|
@@ -569,7 +569,7 @@ interface TossMoneyExecutePaymentResult {
|
|
|
569
569
|
* @param {ExecutePaymentOptions} options 결제를 실행할 때 필요한 옵션이에요.
|
|
570
570
|
* @param {string} options.orderNo 결제를 생성할 때 사용한 주문번호예요.
|
|
571
571
|
* @param {string} options.payToken 결제 인증 과정에서 전달받은 결제 토큰이에요. 결제를 실행할 때 사용해요.
|
|
572
|
-
* @returns {Promise<CardExecutePaymentResult | TossMoneyExecutePaymentResult>} 결제 결과 객체를 반환해요. 자세한 내용은 [카드 결제 결과](reference/framework/토스페이/CardExecutePaymentResult.html) 또는 [토스머니 결제 결과](reference/framework/토스페이/TossMoneyExecutePaymentResult.html)를 참고하세요.
|
|
572
|
+
* @returns {Promise<CardExecutePaymentResult | TossMoneyExecutePaymentResult>} 결제 결과 객체를 반환해요. 자세한 내용은 [카드 결제 결과](/react-native/reference/framework/토스페이/CardExecutePaymentResult.html) 또는 [토스머니 결제 결과](/react-native/reference/framework/토스페이/TossMoneyExecutePaymentResult.html)를 참고하세요.
|
|
573
573
|
*
|
|
574
574
|
* @example
|
|
575
575
|
*
|
|
@@ -858,7 +858,7 @@ interface GetCurrentLocationOptions {
|
|
|
858
858
|
*
|
|
859
859
|
* @param {GetCurrentLocationOptions} options 위치 정보를 가져올 때 사용하는 옵션 객체예요.
|
|
860
860
|
* @param {Accuracy} [options.accuracy] 위치 정보의 정확도 수준이에요. 정확도는 `Accuracy` 타입으로 설정돼요.
|
|
861
|
-
* @returns {Promise<Location>} 디바이스의 위치 정보가 담긴 객체를 반환해요. 자세한 내용은 [Location](/reference/framework/Types/Location.html)을 참고해주세요.
|
|
861
|
+
* @returns {Promise<Location>} 디바이스의 위치 정보가 담긴 객체를 반환해요. 자세한 내용은 [Location](/react-native/reference/framework/Types/Location.html)을 참고해주세요.
|
|
862
862
|
*
|
|
863
863
|
* @example
|
|
864
864
|
* ### 디바이스의 현재 위치 정보 가져오기
|
|
@@ -1027,13 +1027,157 @@ declare function appLogin(): Promise<{
|
|
|
1027
1027
|
*/
|
|
1028
1028
|
declare function getOperationalEnvironment(): 'toss' | 'sandbox';
|
|
1029
1029
|
|
|
1030
|
+
/**
|
|
1031
|
+
* @public
|
|
1032
|
+
* @category 환경 확인
|
|
1033
|
+
* @name getTossAppVersion
|
|
1034
|
+
* @description 토스 앱 버전을 가져옵니다. 예를 들어, `5.206.0`과 같은 형태로 반환돼요. 토스 앱 버전을 로그로 남기거나, 특정 기능이 특정 버전 이상에서만 실행될 때 사용돼요.
|
|
1035
|
+
* @signature
|
|
1036
|
+
* ```typescript
|
|
1037
|
+
* function getTossAppVersion(): string
|
|
1038
|
+
* ```
|
|
1039
|
+
*
|
|
1040
|
+
* @returns {string} 토스 앱 버전
|
|
1041
|
+
*
|
|
1042
|
+
* @example
|
|
1043
|
+
*
|
|
1044
|
+
*
|
|
1045
|
+
* ### 토스 앱 버전 확인하기
|
|
1046
|
+
*
|
|
1047
|
+
* ```tsx
|
|
1048
|
+
* import { getTossAppVersion } from '@apps-in-toss/framework';
|
|
1049
|
+
* import { Text } from 'react-native';
|
|
1050
|
+
*
|
|
1051
|
+
* export function TossAppVersionPage() {
|
|
1052
|
+
* return (
|
|
1053
|
+
* <Text>{getTossAppVersion()}</Text>
|
|
1054
|
+
* )
|
|
1055
|
+
* }
|
|
1056
|
+
* ```
|
|
1057
|
+
*/
|
|
1058
|
+
declare function getTossAppVersion(): string;
|
|
1059
|
+
|
|
1060
|
+
/**
|
|
1061
|
+
* @public
|
|
1062
|
+
* @category 환경 확인
|
|
1063
|
+
* @kind function
|
|
1064
|
+
* @name getDeviceId
|
|
1065
|
+
* @description
|
|
1066
|
+
* 사용 중인 기기의 고유 식별자를 문자열로 반환해요.
|
|
1067
|
+
*
|
|
1068
|
+
* 이 함수는 현재 사용 중인 기기의 고유 식별자를 문자열로 반환해요. 기기별로 설정이나 데이터를 저장하거나 사용자의 기기를 식별해서 로그를 기록하고 분석하는 데 사용할 수 있어요. 같은 사용자의 여러 기기를 구분하는 데도 유용해요.
|
|
1069
|
+
*
|
|
1070
|
+
* @returns {string} 기기의 고유 식별자를 나타내는 문자열이에요.
|
|
1071
|
+
*
|
|
1072
|
+
* @example
|
|
1073
|
+
* ### 기기 고유 식별자 가져오기
|
|
1074
|
+
*
|
|
1075
|
+
* ```tsx
|
|
1076
|
+
* import { getDeviceId } from '@apps-in-toss/framework';
|
|
1077
|
+
* import { Text } from 'react-native';
|
|
1078
|
+
*
|
|
1079
|
+
* function MyPage() {
|
|
1080
|
+
* const id = getDeviceId();
|
|
1081
|
+
*
|
|
1082
|
+
* return (
|
|
1083
|
+
* <Text>사용자의 기기 고유 식별자: {id}</Text>
|
|
1084
|
+
* );
|
|
1085
|
+
* }
|
|
1086
|
+
* ```
|
|
1087
|
+
*/
|
|
1088
|
+
declare function getDeviceId(): string;
|
|
1089
|
+
|
|
1090
|
+
/**
|
|
1091
|
+
* @public
|
|
1092
|
+
* @category 저장소
|
|
1093
|
+
* @name getItem
|
|
1094
|
+
* @description 모바일 앱의 로컬 저장소에서 문자열 데이터를 가져와요. 주로 앱이 종료되었다가 다시 시작해도 데이터가 유지되어야 하는 경우에 사용해요.
|
|
1095
|
+
* @param {string} key - 가져올 아이템의 키를 입력해요.
|
|
1096
|
+
* @returns {Promise<string | null>} 지정한 키에 저장된 문자열 값을 반환해요. 값이 없으면 `null`을 반환해요.
|
|
1097
|
+
* @example
|
|
1098
|
+
*
|
|
1099
|
+
* ### `my-key`에 저장된 아이템 가져오기
|
|
1100
|
+
* ```ts
|
|
1101
|
+
* const value = await Storage.getItem('my-key');
|
|
1102
|
+
* console.log(value); // 'value'
|
|
1103
|
+
* ```
|
|
1104
|
+
*/
|
|
1105
|
+
declare function getItem(key: string): Promise<string | null>;
|
|
1106
|
+
/**
|
|
1107
|
+
* @public
|
|
1108
|
+
* @category 저장소
|
|
1109
|
+
* @name setItem
|
|
1110
|
+
* @description 모바일 앱의 로컬 저장소에 문자열 데이터를 저장해요. 주로 앱이 종료되었다가 다시 시작해도 데이터가 유지되어야 하는 경우에 사용해요.
|
|
1111
|
+
* @param {string} key - 저장할 아이템의 키를 입력해요.
|
|
1112
|
+
* @param {string} value - 저장할 아이템의 값을 입력해요.
|
|
1113
|
+
* @returns {Promise<void>} 아이템을 성공적으로 저장하면 아무 값도 반환하지 않아요.
|
|
1114
|
+
* @example
|
|
1115
|
+
*
|
|
1116
|
+
* ### `my-key`에 아이템 저장하기
|
|
1117
|
+
* ```ts
|
|
1118
|
+
* import { Storage } from '@apps-in-toss/framework';
|
|
1119
|
+
*
|
|
1120
|
+
* await Storage.setItem('my-key', 'value');
|
|
1121
|
+
* ```
|
|
1122
|
+
*/
|
|
1123
|
+
declare function setItem(key: string, value: string): Promise<void>;
|
|
1124
|
+
/**
|
|
1125
|
+
* @public
|
|
1126
|
+
* @category 저장소
|
|
1127
|
+
* @name removeItem
|
|
1128
|
+
* @description 모바일 앱의 로컬 저장소에서 특정 키에 해당하는 아이템을 삭제해요.
|
|
1129
|
+
* @param {string} key - 삭제할 아이템의 키를 입력해요.
|
|
1130
|
+
* @returns {Promise<void>} 아이템을 삭제하면 아무 값도 반환하지 않아요.
|
|
1131
|
+
* @example
|
|
1132
|
+
*
|
|
1133
|
+
* ### `my-key`에 저장된 아이템 삭제하기
|
|
1134
|
+
* ```ts
|
|
1135
|
+
* import { Storage } from '@apps-in-toss/framework';
|
|
1136
|
+
*
|
|
1137
|
+
* await Storage.removeItem('my-key');
|
|
1138
|
+
* ```
|
|
1139
|
+
*/
|
|
1140
|
+
declare function removeItem(key: string): Promise<void>;
|
|
1141
|
+
/**
|
|
1142
|
+
* @public
|
|
1143
|
+
* @category 저장소
|
|
1144
|
+
* @name clearItems
|
|
1145
|
+
* @description 모바일 앱의 로컬 저장소의 모든 아이템을 삭제해요.
|
|
1146
|
+
* @returns {Promise<void>} 아이템을 삭제하면 아무 값도 반환하지 않고 저장소가 초기화돼요.
|
|
1147
|
+
* @example
|
|
1148
|
+
*
|
|
1149
|
+
* ### 저장소 초기화하기
|
|
1150
|
+
* ```ts
|
|
1151
|
+
* import { Storage } from '@apps-in-toss/framework';
|
|
1152
|
+
*
|
|
1153
|
+
* await Storage.clearItems();
|
|
1154
|
+
* ```
|
|
1155
|
+
*/
|
|
1156
|
+
declare function clearItems(): Promise<void>;
|
|
1157
|
+
/**
|
|
1158
|
+
* @public
|
|
1159
|
+
* @category 저장소
|
|
1160
|
+
* @name Storage
|
|
1161
|
+
* @description 네이티브의 저장소를 사용해요.
|
|
1162
|
+
* @property {typeof getItem} [getItem] 모바일 앱의 로컬 저장소에서 아이템을 가져오는 함수예요. 자세한 내용은 [getItem](/react-native/reference/framework/저장소/getItem)을 참고하세요.
|
|
1163
|
+
* @property {typeof setItem} [setItem] 모바일 앱의 로컬 저장소에 아이템을 저장하는 함수예요. 자세한 내용은 [setItem](/react-native/reference/framework/저장소/setItem)을 참고하세요.
|
|
1164
|
+
* @property {typeof removeItem} [removeItem] 모바일 앱의 로컬 저장소에서 아이템을 삭제하는 함수예요. 자세한 내용은 [removeItem](/react-native/reference/framework/저장소/removeItem)을 참고하세요.
|
|
1165
|
+
* @property {typeof clearItems} [clearItems] 모바일 앱의 로컬 저장소를 초기화하는 함수예요. 자세한 내용은 [clearItems](/react-native/reference/framework/저장소/clearItems)을 참고하세요.
|
|
1166
|
+
*/
|
|
1167
|
+
declare const Storage: {
|
|
1168
|
+
getItem: typeof getItem;
|
|
1169
|
+
setItem: typeof setItem;
|
|
1170
|
+
removeItem: typeof removeItem;
|
|
1171
|
+
clearItems: typeof clearItems;
|
|
1172
|
+
};
|
|
1173
|
+
|
|
1030
1174
|
/**
|
|
1031
1175
|
* @public
|
|
1032
1176
|
* @category 토스페이
|
|
1033
1177
|
* @name TossPay
|
|
1034
1178
|
* @description 토스페이 결제 관련 함수를 모아둔 객체예요.
|
|
1035
|
-
* @property {typeof checkoutPayment} [checkoutPayment] 토스페이 결제를 생성하는 함수예요. 자세한 내용은 [checkoutPayment](reference/framework/토스페이/checkoutPayment)를 참고하세요.
|
|
1036
|
-
* @property {typeof executePayment} [executePayment] 토스페이 결제를 실행하는 함수예요. 자세한 내용은 [executePayment](reference/framework/토스페이/executePayment)를 참고하세요.
|
|
1179
|
+
* @property {typeof checkoutPayment} [checkoutPayment] 토스페이 결제를 생성하는 함수예요. 자세한 내용은 [checkoutPayment](/react-native/reference/framework/토스페이/checkoutPayment)를 참고하세요.
|
|
1180
|
+
* @property {typeof executePayment} [executePayment] 토스페이 결제를 실행하는 함수예요. 자세한 내용은 [executePayment](/react-native/reference/framework/토스페이/executePayment)를 참고하세요.
|
|
1037
1181
|
*/
|
|
1038
1182
|
declare const TossPay: {
|
|
1039
1183
|
checkoutPayment: typeof checkoutPayment;
|
|
@@ -1076,7 +1220,7 @@ type UseGeolocationOptions = Omit<StartUpdateLocationOptions, 'callback'>;
|
|
|
1076
1220
|
* @param {Accuracy} [options.accuracy] 위치 정확도를 설정해요. `Accuracy.Lowest`: 오차범위 3KM 이내, `Accuracy.Low`: 오차범위 1KM 이내, `Accuracy.Balanced`: 오차범위 몇 백미터 이내, `Accuracy.High`: 오차범위 10M 이내, `Accuracy.Highest`: 가장 높은 정확도, `Accuracy.BestForNavigation`: 네비게이션을 위한 최고 정확도
|
|
1077
1221
|
* @param {number} [options.timeInterval] 위치 정보를 업데이트하는 최소 주기로, 단위는 밀리초(ms)예요. 이 값은 위치 업데이트가 발생하는 가장 짧은 간격을 설정하지만, 시스템이나 환경의 영향을 받아 지정한 주기보다 더 긴 간격으로 업데이트될 수 있어요.
|
|
1078
1222
|
* @param {number} [options.distanceInterval] 위치 변경 거리를 미터(m) 단위로 설정해요.
|
|
1079
|
-
* @returns {Location | null} 디바이스의 위치 정보가 담긴 객체를 반환해요. 자세한 내용은 [Location](/reference/framework/Types/Location.html)을 참고해주세요.
|
|
1223
|
+
* @returns {Location | null} 디바이스의 위치 정보가 담긴 객체를 반환해요. 자세한 내용은 [Location](/react-native/reference/framework/Types/Location.html)을 참고해주세요.
|
|
1080
1224
|
*
|
|
1081
1225
|
* @example
|
|
1082
1226
|
* ### 위치 정보 변경 감지하기
|
|
@@ -1112,4 +1256,4 @@ declare const env: {
|
|
|
1112
1256
|
getDeploymentId: () => string | undefined;
|
|
1113
1257
|
};
|
|
1114
1258
|
|
|
1115
|
-
export { Accuracy, AppsInToss, type ContactEntity, type ExternalWebViewProps, type FetchAlbumPhotosOptions, type GameWebViewProps, type GetCurrentLocationOptions, type ImageResponse, type Location, type LocationCoords, type OpenCameraOptions, type PartnerWebViewProps, type StartUpdateLocationOptions, type StartUpdateLocationSubscription, TossPay, type UpdateLocationEventEmitter, type UseGeolocationOptions, WebView, type WebViewProps, appLogin, env, fetchAlbumPhotos, fetchContacts, getClipboardText, getCurrentLocation, getOperationalEnvironment, openCamera, setClipboardText, startUpdateLocation, useGeolocation };
|
|
1259
|
+
export { Accuracy, AppsInToss, type ContactEntity, type ExternalWebViewProps, type FetchAlbumPhotosOptions, type GameWebViewProps, type GetCurrentLocationOptions, type ImageResponse, type Location, type LocationCoords, type OpenCameraOptions, type PartnerWebViewProps, type StartUpdateLocationOptions, type StartUpdateLocationSubscription, Storage, TossPay, type UpdateLocationEventEmitter, type UseGeolocationOptions, WebView, type WebViewProps, appLogin, env, fetchAlbumPhotos, fetchContacts, getClipboardText, getCurrentLocation, getDeviceId, getOperationalEnvironment, getTossAppVersion, openCamera, setClipboardText, startUpdateLocation, useGeolocation };
|
package/dist/index.js
CHANGED
|
@@ -238,6 +238,39 @@ function getOperationalEnvironment() {
|
|
|
238
238
|
return AppsInTossModule.operationalEnvironment;
|
|
239
239
|
}
|
|
240
240
|
|
|
241
|
+
// src/native-modules/getTossAppVersion.ts
|
|
242
|
+
function getTossAppVersion() {
|
|
243
|
+
return AppsInTossModule.tossAppVersion;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// src/native-modules/getDeviceId.ts
|
|
247
|
+
function getDeviceId() {
|
|
248
|
+
return AppsInTossModule.deviceId;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// src/native-modules/storage.ts
|
|
252
|
+
function getItem(key) {
|
|
253
|
+
return AppsInTossModule.getStorageItem({ key });
|
|
254
|
+
}
|
|
255
|
+
function setItem(key, value) {
|
|
256
|
+
return AppsInTossModule.setStorageItem({
|
|
257
|
+
key,
|
|
258
|
+
value
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
function removeItem(key) {
|
|
262
|
+
return AppsInTossModule.removeStorageItem({ key });
|
|
263
|
+
}
|
|
264
|
+
function clearItems() {
|
|
265
|
+
return AppsInTossModule.clearStorage({});
|
|
266
|
+
}
|
|
267
|
+
var Storage = {
|
|
268
|
+
getItem,
|
|
269
|
+
setItem,
|
|
270
|
+
removeItem,
|
|
271
|
+
clearItems
|
|
272
|
+
};
|
|
273
|
+
|
|
241
274
|
// src/native-modules/index.ts
|
|
242
275
|
var TossPay = {
|
|
243
276
|
checkoutPayment,
|
|
@@ -249,8 +282,9 @@ import {
|
|
|
249
282
|
PartnerWebViewScreen,
|
|
250
283
|
ExternalWebViewScreen
|
|
251
284
|
} from "@toss-design-system/react-native";
|
|
252
|
-
import {
|
|
253
|
-
import {
|
|
285
|
+
import { useSafeAreaBottom, useSafeAreaTop as useSafeAreaTop2 } from "@toss-design-system/react-native/private";
|
|
286
|
+
import { useMemo as useMemo2 } from "react";
|
|
287
|
+
import { getSchemeUri, useBedrockEvent } from "react-native-bedrock";
|
|
254
288
|
import * as bedrockAsyncBridges from "react-native-bedrock/async-bridges";
|
|
255
289
|
import * as bedrockConstantBridges from "react-native-bedrock/constant-bridges";
|
|
256
290
|
|
|
@@ -258,9 +292,11 @@ import * as bedrockConstantBridges from "react-native-bedrock/constant-bridges";
|
|
|
258
292
|
import {
|
|
259
293
|
WebView as PlainWebView
|
|
260
294
|
} from "@react-native-bedrock/native/react-native-webview";
|
|
261
|
-
import {
|
|
262
|
-
import {
|
|
263
|
-
import {
|
|
295
|
+
import { useDialog } from "@toss-design-system/react-native";
|
|
296
|
+
import { josa } from "es-hangul";
|
|
297
|
+
import { forwardRef, useCallback, useEffect as useEffect2 } from "react";
|
|
298
|
+
import { BackHandler, Platform as Platform4, View as View3 } from "react-native";
|
|
299
|
+
import { closeView, setIosSwipeGestureEnabled } from "react-native-bedrock";
|
|
264
300
|
|
|
265
301
|
// src/components/GameWebViewNavigationBar/GameNavigationBar.tsx
|
|
266
302
|
import { SvgXml } from "@react-native-bedrock/native/react-native-svg";
|
|
@@ -343,6 +379,9 @@ function GameNavigationBar({ onClose }) {
|
|
|
343
379
|
TouchableOpacity,
|
|
344
380
|
{
|
|
345
381
|
hitSlop: { left: 8, right: 8 },
|
|
382
|
+
accessibilityRole: "button",
|
|
383
|
+
accessible: true,
|
|
384
|
+
accessibilityLabel: "\uAC8C\uC784\uC885\uB8CC",
|
|
346
385
|
style: {
|
|
347
386
|
padding: Platform3.OS === "ios" ? 7 : 9
|
|
348
387
|
},
|
|
@@ -358,15 +397,40 @@ function GameNavigationBar({ onClose }) {
|
|
|
358
397
|
// src/components/GameWebView.tsx
|
|
359
398
|
import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
360
399
|
var GameWebView = forwardRef(function GameWebView2(props, ref) {
|
|
400
|
+
const { openConfirm } = useDialog();
|
|
401
|
+
const { brandDisplayName } = getAppsInTossGlobals();
|
|
402
|
+
const handleClose = useCallback(async () => {
|
|
403
|
+
const isConfirmed = await openConfirm({
|
|
404
|
+
title: `${josa(brandDisplayName, "\uC744/\uB97C")} \uC885\uB8CC\uD560\uAE4C\uC694?`,
|
|
405
|
+
leftButton: "\uCDE8\uC18C",
|
|
406
|
+
rightButton: "\uC885\uB8CC\uD558\uAE30",
|
|
407
|
+
closeOnDimmerClick: true
|
|
408
|
+
});
|
|
409
|
+
if (isConfirmed) {
|
|
410
|
+
closeView();
|
|
411
|
+
}
|
|
412
|
+
}, [brandDisplayName, openConfirm]);
|
|
413
|
+
useEffect2(() => {
|
|
414
|
+
if (Platform4.OS === "ios") {
|
|
415
|
+
setIosSwipeGestureEnabled({ isEnabled: false });
|
|
416
|
+
return () => {
|
|
417
|
+
setIosSwipeGestureEnabled({ isEnabled: true });
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
return;
|
|
421
|
+
}, []);
|
|
422
|
+
useEffect2(() => {
|
|
423
|
+
const backHandler = () => {
|
|
424
|
+
handleClose();
|
|
425
|
+
return true;
|
|
426
|
+
};
|
|
427
|
+
BackHandler.addEventListener("hardwareBackPress", backHandler);
|
|
428
|
+
return () => {
|
|
429
|
+
BackHandler.removeEventListener("hardwareBackPress", backHandler);
|
|
430
|
+
};
|
|
431
|
+
}, [handleClose]);
|
|
361
432
|
return /* @__PURE__ */ jsxs2(Fragment3, { children: [
|
|
362
|
-
/* @__PURE__ */ jsx4(
|
|
363
|
-
GameNavigationBar,
|
|
364
|
-
{
|
|
365
|
-
onClose: () => {
|
|
366
|
-
closeView();
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
),
|
|
433
|
+
/* @__PURE__ */ jsx4(GameNavigationBar, { onClose: handleClose }),
|
|
370
434
|
/* @__PURE__ */ jsx4(View3, { style: { flex: 1 }, children: /* @__PURE__ */ jsx4(PlainWebView, { ref, ...props }) })
|
|
371
435
|
] });
|
|
372
436
|
});
|
|
@@ -385,10 +449,138 @@ __export(async_bridges_exports, {
|
|
|
385
449
|
setClipboardText: () => setClipboardText
|
|
386
450
|
});
|
|
387
451
|
|
|
452
|
+
// src/bridge-handler/useBridgeHandler.tsx
|
|
453
|
+
import { useCallback as useCallback2, useMemo, useRef } from "react";
|
|
454
|
+
function serializeError(error) {
|
|
455
|
+
return JSON.stringify(error, (_, value) => {
|
|
456
|
+
if (value instanceof Error) {
|
|
457
|
+
return {
|
|
458
|
+
name: value.name,
|
|
459
|
+
message: value.message,
|
|
460
|
+
stack: value.stack,
|
|
461
|
+
__isError: true
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
return value;
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
function methodHandler({
|
|
468
|
+
args,
|
|
469
|
+
eventId,
|
|
470
|
+
functionName,
|
|
471
|
+
handlerMap,
|
|
472
|
+
injectJavaScript
|
|
473
|
+
}) {
|
|
474
|
+
const func = async (...args2) => {
|
|
475
|
+
const result = await handlerMap[functionName](...args2);
|
|
476
|
+
return result;
|
|
477
|
+
};
|
|
478
|
+
if (!func) {
|
|
479
|
+
console.error(`${functionName} is not a function`);
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
func(...args).then((result) => {
|
|
483
|
+
injectJavaScript?.(`
|
|
484
|
+
window.__BEDROCK_NATIVE_EMITTER.emit('${functionName}/resolve/${eventId}', ${JSON.stringify(result, null, 0)});
|
|
485
|
+
`);
|
|
486
|
+
}).catch((error) => {
|
|
487
|
+
const serializedError = serializeError(error);
|
|
488
|
+
injectJavaScript?.(`
|
|
489
|
+
window.__BEDROCK_NATIVE_EMITTER.emit('${functionName}/reject/${eventId}', ${serializedError});
|
|
490
|
+
`);
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
var globalEventListenerMap = /* @__PURE__ */ new Map();
|
|
494
|
+
function useBridgeHandler({
|
|
495
|
+
onMessage,
|
|
496
|
+
constantHandlerMap,
|
|
497
|
+
asyncHandlerMap,
|
|
498
|
+
eventListenerMap,
|
|
499
|
+
injectedJavaScript: originalInjectedJavaScript
|
|
500
|
+
}) {
|
|
501
|
+
const ref = useRef(null);
|
|
502
|
+
const injectedJavaScript = useMemo(
|
|
503
|
+
() => [
|
|
504
|
+
`window.__CONSTANT_HANDLER_MAP = ${JSON.stringify(
|
|
505
|
+
Object.entries(constantHandlerMap).reduce(
|
|
506
|
+
(acc, [key, value]) => {
|
|
507
|
+
acc[key] = typeof value === "function" ? value() : value;
|
|
508
|
+
return acc;
|
|
509
|
+
},
|
|
510
|
+
{}
|
|
511
|
+
)
|
|
512
|
+
)}`,
|
|
513
|
+
originalInjectedJavaScript,
|
|
514
|
+
"true"
|
|
515
|
+
].join("\n"),
|
|
516
|
+
[constantHandlerMap, originalInjectedJavaScript]
|
|
517
|
+
);
|
|
518
|
+
const createHandleOnEvent = (functionName, eventId) => (response) => {
|
|
519
|
+
ref.current?.injectJavaScript(`
|
|
520
|
+
window.__BEDROCK_NATIVE_EMITTER.emit('${functionName}/onEvent/${eventId}', ${JSON.stringify(response, null, 0)});
|
|
521
|
+
`);
|
|
522
|
+
};
|
|
523
|
+
const createHandleOnError = (functionName, eventId) => (error) => {
|
|
524
|
+
ref.current?.injectJavaScript(`
|
|
525
|
+
window.__BEDROCK_NATIVE_EMITTER.emit('${functionName}/onError/${eventId}', ${JSON.stringify(error, null, 0)});
|
|
526
|
+
`);
|
|
527
|
+
};
|
|
528
|
+
const $onMessage = useCallback2(
|
|
529
|
+
async (e) => {
|
|
530
|
+
onMessage?.(e);
|
|
531
|
+
const data = JSON.parse(e.nativeEvent.data);
|
|
532
|
+
if (typeof data !== "object" || data === null || typeof data.functionName !== "string" || typeof data.eventId !== "string" || typeof data.type !== "string" || !["addEventListener", "removeEventListener", "method"].includes(data.type)) {
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
switch (data.type) {
|
|
536
|
+
case "addEventListener": {
|
|
537
|
+
const handleOnEvent = createHandleOnEvent(data.functionName, data.eventId);
|
|
538
|
+
const handleOnError = createHandleOnError(data.functionName, data.eventId);
|
|
539
|
+
const remove = eventListenerMap[data.functionName]?.({
|
|
540
|
+
onEvent: handleOnEvent,
|
|
541
|
+
onError: handleOnError,
|
|
542
|
+
options: data.args
|
|
543
|
+
});
|
|
544
|
+
if (remove) {
|
|
545
|
+
globalEventListenerMap.set(`${data.functionName}/${data.eventId}`, remove);
|
|
546
|
+
}
|
|
547
|
+
break;
|
|
548
|
+
}
|
|
549
|
+
case "removeEventListener": {
|
|
550
|
+
const key = `${data.functionName}/${data.eventId}`;
|
|
551
|
+
const remove = globalEventListenerMap.get(key);
|
|
552
|
+
remove?.();
|
|
553
|
+
globalEventListenerMap.delete(key);
|
|
554
|
+
break;
|
|
555
|
+
}
|
|
556
|
+
case "method": {
|
|
557
|
+
methodHandler({
|
|
558
|
+
args: data.args,
|
|
559
|
+
eventId: data.eventId,
|
|
560
|
+
functionName: data.functionName,
|
|
561
|
+
handlerMap: asyncHandlerMap,
|
|
562
|
+
injectJavaScript: ref.current?.injectJavaScript
|
|
563
|
+
});
|
|
564
|
+
break;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
},
|
|
568
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
569
|
+
[onMessage]
|
|
570
|
+
);
|
|
571
|
+
return {
|
|
572
|
+
ref,
|
|
573
|
+
injectedJavaScript,
|
|
574
|
+
onMessage: $onMessage
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
|
|
388
578
|
// src/constant-bridges.ts
|
|
389
579
|
var constant_bridges_exports = {};
|
|
390
580
|
__export(constant_bridges_exports, {
|
|
391
|
-
|
|
581
|
+
getDeviceId: () => getDeviceId,
|
|
582
|
+
getOperationalEnvironment: () => getOperationalEnvironment,
|
|
583
|
+
getTossAppVersion: () => getTossAppVersion
|
|
392
584
|
});
|
|
393
585
|
|
|
394
586
|
// src/env.ts
|
|
@@ -405,6 +597,7 @@ __export(event_bridges_exports, {
|
|
|
405
597
|
// src/components/WebView.tsx
|
|
406
598
|
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
407
599
|
var appsInTossGlobals = getAppsInTossGlobals();
|
|
600
|
+
var TYPES = ["partner", "external", "game"];
|
|
408
601
|
var WEBVIEW_TYPES = {
|
|
409
602
|
partner: PartnerWebViewScreen,
|
|
410
603
|
external: ExternalWebViewScreen,
|
|
@@ -433,45 +626,65 @@ function getWebViewUri(local) {
|
|
|
433
626
|
return url.toString();
|
|
434
627
|
}
|
|
435
628
|
function WebView({ type, local, onMessage, ...props }) {
|
|
436
|
-
|
|
629
|
+
if (!TYPES.includes(type)) {
|
|
630
|
+
throw new Error(`Invalid WebView type: '${type}'`);
|
|
631
|
+
}
|
|
632
|
+
const bedrockEvent = useBedrockEvent();
|
|
633
|
+
const uri = useMemo2(() => getWebViewUri(local), [local]);
|
|
634
|
+
const top = useSafeAreaTop2();
|
|
635
|
+
const bottom = useSafeAreaBottom();
|
|
437
636
|
const handler = useBridgeHandler({
|
|
438
637
|
onMessage,
|
|
439
638
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
440
|
-
eventListenerMap:
|
|
639
|
+
eventListenerMap: {
|
|
640
|
+
...event_bridges_exports,
|
|
641
|
+
backEvent: ({ onEvent, onError, options }) => bedrockEvent.addEventListener("backEvent", { onEvent, onError, options })
|
|
642
|
+
},
|
|
441
643
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
442
644
|
// @ts-expect-error
|
|
443
645
|
constantHandlerMap: {
|
|
444
646
|
...bedrockConstantBridges,
|
|
445
|
-
...constant_bridges_exports
|
|
647
|
+
...constant_bridges_exports,
|
|
648
|
+
getSafeAreaTop: () => top,
|
|
649
|
+
getSafeAreaBottom: () => bottom
|
|
446
650
|
},
|
|
447
651
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
448
652
|
// @ts-expect-error
|
|
449
653
|
asyncHandlerMap: {
|
|
450
654
|
...bedrockAsyncBridges,
|
|
451
|
-
...async_bridges_exports
|
|
655
|
+
...async_bridges_exports,
|
|
656
|
+
/** internal */
|
|
657
|
+
openPermissionDialog: AppsInTossModule.openPermissionDialog,
|
|
658
|
+
/** Storage */
|
|
659
|
+
getStorageItem: Storage.getItem,
|
|
660
|
+
setStorageItem: Storage.setItem,
|
|
661
|
+
removeStorageItem: Storage.removeItem,
|
|
662
|
+
clearItems: Storage.clearItems
|
|
452
663
|
}
|
|
453
664
|
});
|
|
454
|
-
const baseProps =
|
|
665
|
+
const baseProps = useMemo2(() => {
|
|
455
666
|
switch (type) {
|
|
456
667
|
case "partner": {
|
|
457
|
-
|
|
668
|
+
const headerOnlyProp = {
|
|
458
669
|
header: {
|
|
459
|
-
...props.header,
|
|
460
|
-
icon: toIcon(appsInTossGlobals.brandIcon),
|
|
461
|
-
title: appsInTossGlobals.brandDisplayName,
|
|
670
|
+
..."header" in props ? props.header : {},
|
|
671
|
+
icon: toIcon(ensureValue(appsInTossGlobals.brandIcon, "icon")),
|
|
672
|
+
title: ensureValue(appsInTossGlobals.brandDisplayName, "displayName"),
|
|
462
673
|
rightButtons: void 0
|
|
463
674
|
// TODO: onClick 이벤트를 받아야 하기에 런타임에서 설정 받아야 함
|
|
464
675
|
}
|
|
465
676
|
};
|
|
677
|
+
return headerOnlyProp;
|
|
466
678
|
}
|
|
467
679
|
case "external": {
|
|
468
|
-
|
|
680
|
+
const headerOnlyProp = {
|
|
469
681
|
header: {
|
|
470
|
-
...props.header,
|
|
471
|
-
icon: toIcon(appsInTossGlobals.brandIcon),
|
|
472
|
-
title: appsInTossGlobals.brandDisplayName
|
|
682
|
+
..."header" in props ? props.header : {},
|
|
683
|
+
icon: toIcon(ensureValue(appsInTossGlobals.brandIcon, "icon")),
|
|
684
|
+
title: ensureValue(appsInTossGlobals.brandDisplayName, "displayName")
|
|
473
685
|
}
|
|
474
686
|
};
|
|
687
|
+
return headerOnlyProp;
|
|
475
688
|
}
|
|
476
689
|
default: {
|
|
477
690
|
return {};
|
|
@@ -479,31 +692,40 @@ function WebView({ type, local, onMessage, ...props }) {
|
|
|
479
692
|
}
|
|
480
693
|
}, [type, props]);
|
|
481
694
|
const BaseWebView = WEBVIEW_TYPES[type];
|
|
695
|
+
const webviewDebuggingEnabled = useMemo2(
|
|
696
|
+
() => getOperationalEnvironment() === "sandbox",
|
|
697
|
+
[]
|
|
698
|
+
);
|
|
482
699
|
return /* @__PURE__ */ jsx5(
|
|
483
700
|
BaseWebView,
|
|
484
701
|
{
|
|
485
702
|
ref: handler.ref,
|
|
486
|
-
...baseProps,
|
|
487
703
|
...props,
|
|
704
|
+
...baseProps,
|
|
488
705
|
source: { uri },
|
|
489
706
|
sharedCookiesEnabled: true,
|
|
707
|
+
webviewDebuggingEnabled,
|
|
490
708
|
thirdPartyCookiesEnabled: true,
|
|
491
|
-
cacheEnabled: false,
|
|
492
|
-
cacheMode: "LOAD_NO_CACHE",
|
|
493
709
|
onMessage: handler.onMessage,
|
|
494
710
|
injectedJavaScript: handler.injectedJavaScript,
|
|
495
711
|
injectedJavaScriptBeforeContentLoaded: handler.injectedJavaScript
|
|
496
712
|
}
|
|
497
713
|
);
|
|
498
714
|
}
|
|
715
|
+
function ensureValue(value, name) {
|
|
716
|
+
if (value === void 0) {
|
|
717
|
+
throw new Error(`${name} is required`);
|
|
718
|
+
}
|
|
719
|
+
return value;
|
|
720
|
+
}
|
|
499
721
|
|
|
500
722
|
// src/hooks/useGeolocation.ts
|
|
501
|
-
import { useState, useEffect as
|
|
723
|
+
import { useState, useEffect as useEffect3 } from "react";
|
|
502
724
|
import { useVisibility } from "react-native-bedrock";
|
|
503
725
|
function useGeolocation({ accuracy, distanceInterval, timeInterval }) {
|
|
504
726
|
const isVisible = useVisibility();
|
|
505
727
|
const [location, setLocation] = useState(null);
|
|
506
|
-
|
|
728
|
+
useEffect3(() => {
|
|
507
729
|
if (!isVisible) {
|
|
508
730
|
return;
|
|
509
731
|
}
|
|
@@ -533,6 +755,7 @@ var Accuracy2 = /* @__PURE__ */ ((Accuracy3) => {
|
|
|
533
755
|
export {
|
|
534
756
|
Accuracy2 as Accuracy,
|
|
535
757
|
AppsInToss,
|
|
758
|
+
Storage,
|
|
536
759
|
TossPay,
|
|
537
760
|
WebView,
|
|
538
761
|
appLogin,
|
|
@@ -541,7 +764,9 @@ export {
|
|
|
541
764
|
fetchContacts,
|
|
542
765
|
getClipboardText,
|
|
543
766
|
getCurrentLocation,
|
|
767
|
+
getDeviceId,
|
|
544
768
|
getOperationalEnvironment,
|
|
769
|
+
getTossAppVersion,
|
|
545
770
|
openCamera,
|
|
546
771
|
setClipboardText,
|
|
547
772
|
startUpdateLocation,
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apps-in-toss/framework",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.0-dev.
|
|
4
|
+
"version": "0.0.0-dev.1744801739343",
|
|
5
5
|
"description": "The framework for Apps In Toss",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"prepack": "yarn build",
|
|
8
8
|
"typecheck": "tsc --noEmit",
|
|
9
|
+
"test:no-parallel": "vitest --no-watch",
|
|
9
10
|
"lint": "eslint .",
|
|
10
11
|
"build": "tsup"
|
|
11
12
|
},
|
|
@@ -55,32 +56,40 @@
|
|
|
55
56
|
"ait": "./bin/ait.js"
|
|
56
57
|
},
|
|
57
58
|
"dependencies": {
|
|
58
|
-
"@apps-in-toss/cli": "0.0.0-dev.
|
|
59
|
-
"@apps-in-toss/plugins": "0.0.0-dev.
|
|
59
|
+
"@apps-in-toss/cli": "0.0.0-dev.1744801739343",
|
|
60
|
+
"@apps-in-toss/plugins": "0.0.0-dev.1744801739343",
|
|
61
|
+
"es-hangul": "^2.3.2"
|
|
60
62
|
},
|
|
61
63
|
"devDependencies": {
|
|
62
|
-
"@react-native-bedrock/mpack-next": "0.0.
|
|
63
|
-
"@react-native-bedrock/native": "
|
|
64
|
-
"@toss-design-system/react-native": "^0.
|
|
64
|
+
"@react-native-bedrock/mpack-next": "0.0.0-dev.1744801739343",
|
|
65
|
+
"@react-native-bedrock/native": "workspace:*",
|
|
66
|
+
"@toss-design-system/react-native": "^0.5.0",
|
|
67
|
+
"@types/kill-port": "^2.0.1",
|
|
65
68
|
"@types/react": "18.3.3",
|
|
69
|
+
"@types/yauzl": "^2.10.3",
|
|
70
|
+
"es-toolkit": "^1.34.1",
|
|
66
71
|
"eslint": "^9.7.0",
|
|
72
|
+
"execa": "^9.5.2",
|
|
73
|
+
"kill-port": "^2.0.1",
|
|
67
74
|
"react": "18.2.0",
|
|
68
75
|
"react-native": "0.72.6",
|
|
69
|
-
"react-native-bedrock": "0.0.
|
|
76
|
+
"react-native-bedrock": "0.0.0-dev.1744801739343",
|
|
70
77
|
"tsup": "^8.3.5",
|
|
71
78
|
"typescript": "4.9.5",
|
|
72
|
-
"vitest": "^3.0.3"
|
|
79
|
+
"vitest": "^3.0.3",
|
|
80
|
+
"workspace-tools": "^0.38.2",
|
|
81
|
+
"yauzl": "^3.2.0"
|
|
73
82
|
},
|
|
74
83
|
"peerDependencies": {
|
|
75
|
-
"@react-native-bedrock/native": "
|
|
76
|
-
"@toss-design-system/react-native": "
|
|
84
|
+
"@react-native-bedrock/native": ">= 0.0.18",
|
|
85
|
+
"@toss-design-system/react-native": ">= 0.5.0",
|
|
77
86
|
"@types/react": "*",
|
|
78
87
|
"react": "*",
|
|
79
88
|
"react-native": "*",
|
|
80
|
-
"react-native-bedrock": "
|
|
89
|
+
"react-native-bedrock": ">= 0.0.18"
|
|
81
90
|
},
|
|
82
91
|
"publishConfig": {
|
|
83
92
|
"access": "public"
|
|
84
93
|
},
|
|
85
|
-
"gitHead": "
|
|
94
|
+
"gitHead": "aebed4e46de1690956a3b9be49b55811b5ddfa24"
|
|
86
95
|
}
|
package/src/constant-bridges.ts
CHANGED