@apps-in-toss/framework 0.0.13 → 0.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -32,6 +32,7 @@ var src_exports = {};
32
32
  __export(src_exports, {
33
33
  Accuracy: () => Accuracy2,
34
34
  AppsInToss: () => AppsInToss,
35
+ TossPay: () => TossPay,
35
36
  WebView: () => WebView,
36
37
  appLogin: () => appLogin,
37
38
  env: () => env,
@@ -48,10 +49,49 @@ __export(src_exports, {
48
49
  module.exports = __toCommonJS(src_exports);
49
50
 
50
51
  // src/core/registerApp.tsx
52
+ var import_react_native2 = require("@toss-design-system/react-native");
51
53
  var import_react_native_bedrock = require("react-native-bedrock");
54
+
55
+ // src/core/hooks/useAppsInTossBridge.ts
56
+ var import_react_native = require("@toss-design-system/react-native");
57
+ var import_react = require("react");
58
+
59
+ // src/core/utils/getAppsInTossGlobals.ts
60
+ function getAppsInTossGlobals() {
61
+ if (global.__appsInToss == null) {
62
+ throw new Error("invalid apps-in-toss globals");
63
+ }
64
+ return global.__appsInToss;
65
+ }
66
+
67
+ // src/core/utils/toIcon.ts
68
+ function toIcon(source) {
69
+ return source.startsWith("http") ? { source: { uri: source } } : { name: source };
70
+ }
71
+
72
+ // src/core/hooks/useAppsInTossBridge.ts
73
+ function useAppsInTossBridge() {
74
+ const controller = (0, import_react_native.useBridge)();
75
+ const appsInTossGlobals2 = getAppsInTossGlobals();
76
+ (0, import_react.useEffect)(() => {
77
+ const commonProps = {
78
+ serviceName: appsInTossGlobals2.brandDisplayName,
79
+ icon: toIcon(appsInTossGlobals2.brandIcon),
80
+ color: appsInTossGlobals2.brandPrimaryColor,
81
+ colorMode: appsInTossGlobals2.brandBridgeColorMode
82
+ };
83
+ controller.open({ ...commonProps });
84
+ }, []);
85
+ }
86
+
87
+ // src/core/registerApp.tsx
52
88
  var import_jsx_runtime = require("react/jsx-runtime");
53
89
  function AppsInTossContainer(Container, { children, ...initialProps }) {
54
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Container, { ...initialProps, children });
90
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Container, { ...initialProps, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.TDSProvider, { colorPreference: "light", token: { color: { primary: getAppsInTossGlobals().brandPrimaryColor } }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TDSContainer, { ...initialProps, children }) }) });
91
+ }
92
+ function TDSContainer({ children }) {
93
+ useAppsInTossBridge();
94
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children });
55
95
  }
56
96
  function registerApp(container, { context }) {
57
97
  return import_react_native_bedrock.Bedrock.registerApp(AppsInTossContainer.bind(null, container), {
@@ -80,8 +120,8 @@ var import_react_native_bedrock3 = require("react-native-bedrock");
80
120
  var import_react_native_bedrock2 = require("react-native-bedrock");
81
121
 
82
122
  // src/native-modules/AppsInTossModule.ts
83
- var import_react_native = require("react-native");
84
- var AppsInTossModuleInstance = import_react_native.NativeModules.AppsInTossModule;
123
+ var import_react_native3 = require("react-native");
124
+ var AppsInTossModuleInstance = import_react_native3.NativeModules.AppsInTossModule;
85
125
  var AppsInTossModule = AppsInTossModuleInstance;
86
126
 
87
127
  // src/native-modules/getPermission.ts
@@ -107,8 +147,8 @@ async function requestPermission(permission) {
107
147
  }
108
148
 
109
149
  // src/native-event-emitter/nativeEventEmitter.ts
110
- var import_react_native2 = require("react-native");
111
- var nativeEventEmitter = new import_react_native2.NativeEventEmitter(AppsInTossModuleInstance);
150
+ var import_react_native4 = require("react-native");
151
+ var nativeEventEmitter = new import_react_native4.NativeEventEmitter(AppsInTossModuleInstance);
112
152
 
113
153
  // src/native-event-emitter/event-plugins/UpdateLocationEvent.ts
114
154
  var UpdateLocationEvent = class extends import_react_native_bedrock2.BedrockEventDefinition {
@@ -146,6 +186,16 @@ function startUpdateLocation(eventParams) {
146
186
  return appsInTossEvent.addEventListener("updateLocationEvent", eventParams);
147
187
  }
148
188
 
189
+ // src/native-modules/checkoutPayment.ts
190
+ async function checkoutPayment(options) {
191
+ return AppsInTossModule.checkoutPayment(options);
192
+ }
193
+
194
+ // src/native-modules/executePayment.ts
195
+ async function executePayment(options) {
196
+ return AppsInTossModule.executePayment(options);
197
+ }
198
+
149
199
  // src/native-modules/setClipboardText.ts
150
200
  async function setClipboardText(text) {
151
201
  const permissionStatus = await requestPermission({ name: "clipboard", access: "write" });
@@ -232,17 +282,140 @@ function getOperationalEnvironment() {
232
282
  return AppsInTossModule.operationalEnvironment;
233
283
  }
234
284
 
285
+ // src/native-modules/index.ts
286
+ var TossPay = {
287
+ checkoutPayment,
288
+ executePayment
289
+ };
290
+
235
291
  // src/components/WebView.tsx
236
- var import_react_native_webview = require("@react-native-bedrock/native/react-native-webview");
237
- var import_react = require("react");
238
- var import_react_native_bedrock4 = require("react-native-bedrock");
292
+ var import_react_native11 = require("@toss-design-system/react-native");
293
+ var import_react3 = require("react");
294
+ var import_react_native_bedrock5 = require("react-native-bedrock");
239
295
  var bedrockAsyncBridges = __toESM(require("react-native-bedrock/async-bridges"), 1);
240
296
  var bedrockConstantBridges = __toESM(require("react-native-bedrock/constant-bridges"), 1);
241
297
 
298
+ // src/components/GameWebView.tsx
299
+ var import_react_native_webview = require("@react-native-bedrock/native/react-native-webview");
300
+ var import_react2 = require("react");
301
+ var import_react_native10 = require("react-native");
302
+ var import_react_native_bedrock4 = require("react-native-bedrock");
303
+
304
+ // src/components/GameWebViewNavigationBar/GameNavigationBar.tsx
305
+ var import_react_native_svg = require("@react-native-bedrock/native/react-native-svg");
306
+ var import_react_native8 = require("@toss-design-system/react-native");
307
+ var import_react_native9 = require("react-native");
308
+
309
+ // src/components/GameWebViewNavigationBar/HeaderRight.tsx
310
+ var import_react_native6 = require("react-native");
311
+
312
+ // src/components/GameWebViewNavigationBar/byPlatform.ts
313
+ var import_react_native5 = require("react-native");
314
+ function byPlatform({
315
+ ...props
316
+ }) {
317
+ return (props[import_react_native5.Platform.OS] ?? props.fallback)();
318
+ }
319
+
320
+ // src/components/GameWebViewNavigationBar/constants.ts
321
+ var RIGHT_MARGIN = 24;
322
+ var IOS_DEFAULT_MARGIN = 20;
323
+
324
+ // src/components/GameWebViewNavigationBar/HeaderRight.tsx
325
+ var import_jsx_runtime2 = require("react/jsx-runtime");
326
+ function IOSHeaderRight(props) {
327
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native6.View, { style: styles.ios, ...props });
328
+ }
329
+ function AndroidHeaderRight(props) {
330
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native6.View, { style: styles.android, ...props });
331
+ }
332
+ function HeaderRight(props) {
333
+ return byPlatform({
334
+ ios: () => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IOSHeaderRight, { ...props }),
335
+ android: () => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AndroidHeaderRight, { ...props }),
336
+ fallback: () => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IOSHeaderRight, { ...props })
337
+ });
338
+ }
339
+ var styles = import_react_native6.StyleSheet.create({
340
+ ios: {
341
+ marginRight: -IOS_DEFAULT_MARGIN + RIGHT_MARGIN,
342
+ flexDirection: "row"
343
+ },
344
+ android: {
345
+ flexDirection: "row"
346
+ }
347
+ });
348
+
349
+ // src/components/GameWebViewNavigationBar/useSafeAreaTop.ts
350
+ var import_react_native_safe_area_context = require("@react-native-bedrock/native/react-native-safe-area-context");
351
+ var import_react_native7 = require("react-native");
352
+ function useSafeAreaTop() {
353
+ const safeAreaInsets = (0, import_react_native_safe_area_context.useSafeAreaInsets)();
354
+ const hasDynamicIsland = import_react_native7.Platform.OS === "ios" && safeAreaInsets.top > 50;
355
+ const safeAreaTop = hasDynamicIsland ? safeAreaInsets.top - 5 : safeAreaInsets.top;
356
+ return safeAreaTop;
357
+ }
358
+
359
+ // src/components/GameWebViewNavigationBar/GameNavigationBar.tsx
360
+ var import_jsx_runtime3 = require("react/jsx-runtime");
361
+ var originXML = '<svg fill="none" height="30" viewBox="0 0 30 30" width="30" xmlns="https://www.w3.org/2000/svg"><rect fill="#031832" fill-opacity=".46" height="30" rx="15" width="30"/><rect height="29.5" rx="14.75" stroke="#d9d9ff" stroke-opacity=".11" stroke-width=".5" width="29.5" x=".25" y=".25"/><path clip-rule="evenodd" d="m16.5119 15.0014 4.7092-4.7092c.0929-.0928.1666-.2031.2169-.32441.0503-.12134.0762-.25141.0762-.38276.0001-.13136-.0258-.26144-.076-.38281s-.1239-.23166-.2167-.32457c-.0929-.09291-.2031-.16662-.3245-.21692-.1213-.05031-.2514-.07622-.3827-.07626-.1314-.00004-.2615.0258-.3828.07603-.1214.05023-.2317.12388-.3246.21673l-4.7092 4.70997-4.71-4.70997c-.1897-.17718-.4408-.27373-.70034-.26927s-.5072.10959-.69069.2932c-.1835.1836-.28848.43132-.29279.69087-.00432.25954.09238.51057.26968.70017l4.71004 4.7092-4.71004 4.7092c-.1392.1401-.23385.3183-.27204.5121-.0382.1939-.01823.3946.05739.5771s.20351.3386.36759.4486.35702.169.55456.1697c.25583 0 .51164-.0975.70664-.2925l4.71-4.71 4.7092 4.71c.0927.093.2029.1668.3243.2172.1213.0504.2514.0763.3828.0763s.2614-.0259.3828-.0763c.1213-.0504.2315-.1242.3243-.2172.0929-.0929.1667-.2032.217-.3246s.0762-.2515.0762-.3829-.0259-.2616-.0762-.383-.1241-.2317-.217-.3245z" fill="#fdfdfe" fill-opacity=".89" fill-rule="evenodd"/></svg>';
362
+ function GameNavigationBar({ onClose }) {
363
+ const safeAreaTop = useSafeAreaTop();
364
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
365
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native8.PageNavbar, { preference: { type: "none" } }),
366
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
367
+ import_react_native9.View,
368
+ {
369
+ style: {
370
+ width: "100%",
371
+ height: import_react_native9.Platform.OS === "ios" ? 44 : 54,
372
+ flexDirection: "row",
373
+ alignItems: "center",
374
+ justifyContent: "flex-end",
375
+ position: "absolute",
376
+ zIndex: 9999,
377
+ marginTop: safeAreaTop,
378
+ paddingRight: import_react_native9.Platform.OS === "ios" ? 10 : 8
379
+ },
380
+ pointerEvents: "box-none",
381
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HeaderRight, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
382
+ import_react_native9.TouchableOpacity,
383
+ {
384
+ hitSlop: { left: 8, right: 8 },
385
+ style: {
386
+ padding: import_react_native9.Platform.OS === "ios" ? 7 : 9
387
+ },
388
+ onPress: onClose,
389
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg.SvgXml, { xml: originXML, width: 30, height: 30 })
390
+ }
391
+ ) })
392
+ }
393
+ )
394
+ ] });
395
+ }
396
+
397
+ // src/components/GameWebView.tsx
398
+ var import_jsx_runtime4 = require("react/jsx-runtime");
399
+ var GameWebView = (0, import_react2.forwardRef)(function GameWebView2(props, ref) {
400
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
401
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
402
+ GameNavigationBar,
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 }) })
410
+ ] });
411
+ });
412
+
242
413
  // src/async-bridges.ts
243
414
  var async_bridges_exports = {};
244
415
  __export(async_bridges_exports, {
245
416
  appLogin: () => appLogin,
417
+ checkoutPayment: () => checkoutPayment,
418
+ executePayment: () => executePayment,
246
419
  fetchAlbumPhotos: () => fetchAlbumPhotos,
247
420
  fetchContacts: () => fetchContacts,
248
421
  getClipboardText: () => getClipboardText,
@@ -269,20 +442,38 @@ __export(event_bridges_exports, {
269
442
  });
270
443
 
271
444
  // src/components/WebView.tsx
272
- var import_jsx_runtime2 = require("react/jsx-runtime");
273
- function WebView({ local, onMessage, ...props }) {
274
- const uri = (0, import_react.useMemo)(() => {
275
- if (__DEV__) {
276
- return `http://${local.host}:${local.port}`;
277
- }
278
- const url = new URL(AppsInTossModule.getWebBundleURL({}).url);
279
- const deploymentId = env.getDeploymentId();
280
- if (deploymentId) {
281
- url.searchParams.set("_deploymentId", deploymentId);
282
- }
283
- return url.toString();
284
- }, [local]);
285
- const handler = (0, import_react_native_bedrock4.useBridgeHandler)({
445
+ var import_jsx_runtime5 = require("react/jsx-runtime");
446
+ var appsInTossGlobals = getAppsInTossGlobals();
447
+ var WEBVIEW_TYPES = {
448
+ partner: import_react_native11.PartnerWebViewScreen,
449
+ external: import_react_native11.ExternalWebViewScreen,
450
+ game: GameWebView
451
+ };
452
+ function mergeSchemeQueryParamsInto(url) {
453
+ const baseUrl = new URL(url);
454
+ const schemeUrl = new URL((0, import_react_native_bedrock5.getSchemeUri)());
455
+ baseUrl.pathname = schemeUrl.pathname;
456
+ for (const [key, value] of schemeUrl.searchParams.entries()) {
457
+ baseUrl.searchParams.set(key, value);
458
+ }
459
+ return baseUrl;
460
+ }
461
+ function getWebViewUri(local) {
462
+ if (__DEV__) {
463
+ const devUrl = `http://${local.host}:${local.port}`;
464
+ return mergeSchemeQueryParamsInto(devUrl).toString();
465
+ }
466
+ const { url: rawUrl } = AppsInTossModule.getWebBundleURL({});
467
+ const url = mergeSchemeQueryParamsInto(rawUrl);
468
+ const deploymentId = env.getDeploymentId();
469
+ if (deploymentId) {
470
+ url.searchParams.set("_deploymentId", deploymentId);
471
+ }
472
+ return url.toString();
473
+ }
474
+ function WebView({ type, local, onMessage, ...props }) {
475
+ const uri = (0, import_react3.useMemo)(() => getWebViewUri(local), [local]);
476
+ const handler = (0, import_react_native_bedrock5.useBridgeHandler)({
286
477
  onMessage,
287
478
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
288
479
  eventListenerMap: event_bridges_exports,
@@ -299,14 +490,41 @@ function WebView({ local, onMessage, ...props }) {
299
490
  ...async_bridges_exports
300
491
  }
301
492
  });
302
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
303
- import_react_native_webview.WebView,
493
+ const baseProps = (0, import_react3.useMemo)(() => {
494
+ switch (type) {
495
+ case "partner": {
496
+ return {
497
+ header: {
498
+ ...props.header,
499
+ icon: toIcon(appsInTossGlobals.brandIcon),
500
+ title: appsInTossGlobals.brandDisplayName,
501
+ rightButtons: void 0
502
+ // TODO: onClick 이벤트를 받아야 하기에 런타임에서 설정 받아야 함
503
+ }
504
+ };
505
+ }
506
+ case "external": {
507
+ return {
508
+ header: {
509
+ ...props.header,
510
+ icon: toIcon(appsInTossGlobals.brandIcon),
511
+ title: appsInTossGlobals.brandDisplayName
512
+ }
513
+ };
514
+ }
515
+ default: {
516
+ return {};
517
+ }
518
+ }
519
+ }, [type, props]);
520
+ const BaseWebView = WEBVIEW_TYPES[type];
521
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
522
+ BaseWebView,
304
523
  {
305
524
  ref: handler.ref,
525
+ ...baseProps,
306
526
  ...props,
307
- source: {
308
- uri
309
- },
527
+ source: { uri },
310
528
  sharedCookiesEnabled: true,
311
529
  thirdPartyCookiesEnabled: true,
312
530
  cacheEnabled: false,
@@ -319,12 +537,12 @@ function WebView({ local, onMessage, ...props }) {
319
537
  }
320
538
 
321
539
  // src/hooks/useGeolocation.ts
322
- var import_react2 = require("react");
323
- var import_react_native_bedrock5 = require("react-native-bedrock");
540
+ var import_react4 = require("react");
541
+ var import_react_native_bedrock6 = require("react-native-bedrock");
324
542
  function useGeolocation({ accuracy, distanceInterval, timeInterval }) {
325
- const isVisible = (0, import_react_native_bedrock5.useVisibility)();
326
- const [location, setLocation] = (0, import_react2.useState)(null);
327
- (0, import_react2.useEffect)(() => {
543
+ const isVisible = (0, import_react_native_bedrock6.useVisibility)();
544
+ const [location, setLocation] = (0, import_react4.useState)(null);
545
+ (0, import_react4.useEffect)(() => {
328
546
  if (!isVisible) {
329
547
  return;
330
548
  }
@@ -355,6 +573,7 @@ var Accuracy2 = /* @__PURE__ */ ((Accuracy3) => {
355
573
  0 && (module.exports = {
356
574
  Accuracy,
357
575
  AppsInToss,
576
+ TossPay,
358
577
  WebView,
359
578
  appLogin,
360
579
  env,