@apps-in-toss/framework 0.0.14 → 0.0.16
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 +243 -32
- package/dist/index.d.cts +22 -7
- package/dist/index.d.ts +22 -7
- package/dist/index.js +239 -25
- package/dist/plugins/index.cjs +8 -33566
- package/dist/plugins/index.d.cts +1 -76
- package/dist/plugins/index.d.ts +1 -76
- package/dist/plugins/index.js +1 -33581
- package/package.json +9 -17
- package/plugins.d.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -5,10 +5,49 @@ var __export = (target, all) => {
|
|
|
5
5
|
};
|
|
6
6
|
|
|
7
7
|
// src/core/registerApp.tsx
|
|
8
|
+
import { TDSProvider } from "@toss-design-system/react-native";
|
|
8
9
|
import { Bedrock } from "react-native-bedrock";
|
|
9
|
-
|
|
10
|
+
|
|
11
|
+
// src/core/hooks/useAppsInTossBridge.ts
|
|
12
|
+
import { useBridge } from "@toss-design-system/react-native";
|
|
13
|
+
import { useEffect } from "react";
|
|
14
|
+
|
|
15
|
+
// src/core/utils/getAppsInTossGlobals.ts
|
|
16
|
+
function getAppsInTossGlobals() {
|
|
17
|
+
if (global.__appsInToss == null) {
|
|
18
|
+
throw new Error("invalid apps-in-toss globals");
|
|
19
|
+
}
|
|
20
|
+
return global.__appsInToss;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// src/core/utils/toIcon.ts
|
|
24
|
+
function toIcon(source) {
|
|
25
|
+
return source.startsWith("http") ? { source: { uri: source } } : { name: source };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// src/core/hooks/useAppsInTossBridge.ts
|
|
29
|
+
function useAppsInTossBridge() {
|
|
30
|
+
const controller = useBridge();
|
|
31
|
+
const appsInTossGlobals2 = getAppsInTossGlobals();
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
const commonProps = {
|
|
34
|
+
serviceName: appsInTossGlobals2.brandDisplayName,
|
|
35
|
+
icon: toIcon(appsInTossGlobals2.brandIcon),
|
|
36
|
+
color: appsInTossGlobals2.brandPrimaryColor,
|
|
37
|
+
colorMode: appsInTossGlobals2.brandBridgeColorMode
|
|
38
|
+
};
|
|
39
|
+
controller.open({ ...commonProps });
|
|
40
|
+
}, []);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// src/core/registerApp.tsx
|
|
44
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
10
45
|
function AppsInTossContainer(Container, { children, ...initialProps }) {
|
|
11
|
-
return /* @__PURE__ */ jsx(Container, { ...initialProps, children });
|
|
46
|
+
return /* @__PURE__ */ jsx(Container, { ...initialProps, children: /* @__PURE__ */ jsx(TDSProvider, { colorPreference: "light", token: { color: { primary: getAppsInTossGlobals().brandPrimaryColor } }, children: /* @__PURE__ */ jsx(TDSContainer, { ...initialProps, children }) }) });
|
|
47
|
+
}
|
|
48
|
+
function TDSContainer({ children }) {
|
|
49
|
+
useAppsInTossBridge();
|
|
50
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
12
51
|
}
|
|
13
52
|
function registerApp(container, { context }) {
|
|
14
53
|
return Bedrock.registerApp(AppsInTossContainer.bind(null, container), {
|
|
@@ -207,13 +246,131 @@ var TossPay = {
|
|
|
207
246
|
|
|
208
247
|
// src/components/WebView.tsx
|
|
209
248
|
import {
|
|
210
|
-
|
|
211
|
-
|
|
249
|
+
PartnerWebViewScreen,
|
|
250
|
+
ExternalWebViewScreen
|
|
251
|
+
} from "@toss-design-system/react-native";
|
|
212
252
|
import { useMemo } from "react";
|
|
213
|
-
import { useBridgeHandler } from "react-native-bedrock";
|
|
253
|
+
import { getSchemeUri, useBridgeHandler } from "react-native-bedrock";
|
|
214
254
|
import * as bedrockAsyncBridges from "react-native-bedrock/async-bridges";
|
|
215
255
|
import * as bedrockConstantBridges from "react-native-bedrock/constant-bridges";
|
|
216
256
|
|
|
257
|
+
// src/components/GameWebView.tsx
|
|
258
|
+
import {
|
|
259
|
+
WebView as PlainWebView
|
|
260
|
+
} from "@react-native-bedrock/native/react-native-webview";
|
|
261
|
+
import { forwardRef } from "react";
|
|
262
|
+
import { View as View3 } from "react-native";
|
|
263
|
+
import { closeView } from "react-native-bedrock";
|
|
264
|
+
|
|
265
|
+
// src/components/GameWebViewNavigationBar/GameNavigationBar.tsx
|
|
266
|
+
import { SvgXml } from "@react-native-bedrock/native/react-native-svg";
|
|
267
|
+
import { PageNavbar } from "@toss-design-system/react-native";
|
|
268
|
+
import { Platform as Platform3, TouchableOpacity, View as View2 } from "react-native";
|
|
269
|
+
|
|
270
|
+
// src/components/GameWebViewNavigationBar/HeaderRight.tsx
|
|
271
|
+
import { StyleSheet, View } from "react-native";
|
|
272
|
+
|
|
273
|
+
// src/components/GameWebViewNavigationBar/byPlatform.ts
|
|
274
|
+
import { Platform } from "react-native";
|
|
275
|
+
function byPlatform({
|
|
276
|
+
...props
|
|
277
|
+
}) {
|
|
278
|
+
return (props[Platform.OS] ?? props.fallback)();
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// src/components/GameWebViewNavigationBar/constants.ts
|
|
282
|
+
var RIGHT_MARGIN = 24;
|
|
283
|
+
var IOS_DEFAULT_MARGIN = 20;
|
|
284
|
+
|
|
285
|
+
// src/components/GameWebViewNavigationBar/HeaderRight.tsx
|
|
286
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
287
|
+
function IOSHeaderRight(props) {
|
|
288
|
+
return /* @__PURE__ */ jsx2(View, { style: styles.ios, ...props });
|
|
289
|
+
}
|
|
290
|
+
function AndroidHeaderRight(props) {
|
|
291
|
+
return /* @__PURE__ */ jsx2(View, { style: styles.android, ...props });
|
|
292
|
+
}
|
|
293
|
+
function HeaderRight(props) {
|
|
294
|
+
return byPlatform({
|
|
295
|
+
ios: () => /* @__PURE__ */ jsx2(IOSHeaderRight, { ...props }),
|
|
296
|
+
android: () => /* @__PURE__ */ jsx2(AndroidHeaderRight, { ...props }),
|
|
297
|
+
fallback: () => /* @__PURE__ */ jsx2(IOSHeaderRight, { ...props })
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
var styles = StyleSheet.create({
|
|
301
|
+
ios: {
|
|
302
|
+
marginRight: -IOS_DEFAULT_MARGIN + RIGHT_MARGIN,
|
|
303
|
+
flexDirection: "row"
|
|
304
|
+
},
|
|
305
|
+
android: {
|
|
306
|
+
flexDirection: "row"
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
// src/components/GameWebViewNavigationBar/useSafeAreaTop.ts
|
|
311
|
+
import { useSafeAreaInsets } from "@react-native-bedrock/native/react-native-safe-area-context";
|
|
312
|
+
import { Platform as Platform2 } from "react-native";
|
|
313
|
+
function useSafeAreaTop() {
|
|
314
|
+
const safeAreaInsets = useSafeAreaInsets();
|
|
315
|
+
const hasDynamicIsland = Platform2.OS === "ios" && safeAreaInsets.top > 50;
|
|
316
|
+
const safeAreaTop = hasDynamicIsland ? safeAreaInsets.top - 5 : safeAreaInsets.top;
|
|
317
|
+
return safeAreaTop;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// src/components/GameWebViewNavigationBar/GameNavigationBar.tsx
|
|
321
|
+
import { Fragment as Fragment2, jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
322
|
+
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>';
|
|
323
|
+
function GameNavigationBar({ onClose }) {
|
|
324
|
+
const safeAreaTop = useSafeAreaTop();
|
|
325
|
+
return /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
326
|
+
/* @__PURE__ */ jsx3(PageNavbar, { preference: { type: "none" } }),
|
|
327
|
+
/* @__PURE__ */ jsx3(
|
|
328
|
+
View2,
|
|
329
|
+
{
|
|
330
|
+
style: {
|
|
331
|
+
width: "100%",
|
|
332
|
+
height: Platform3.OS === "ios" ? 44 : 54,
|
|
333
|
+
flexDirection: "row",
|
|
334
|
+
alignItems: "center",
|
|
335
|
+
justifyContent: "flex-end",
|
|
336
|
+
position: "absolute",
|
|
337
|
+
zIndex: 9999,
|
|
338
|
+
marginTop: safeAreaTop,
|
|
339
|
+
paddingRight: Platform3.OS === "ios" ? 10 : 8
|
|
340
|
+
},
|
|
341
|
+
pointerEvents: "box-none",
|
|
342
|
+
children: /* @__PURE__ */ jsx3(HeaderRight, { children: /* @__PURE__ */ jsx3(
|
|
343
|
+
TouchableOpacity,
|
|
344
|
+
{
|
|
345
|
+
hitSlop: { left: 8, right: 8 },
|
|
346
|
+
style: {
|
|
347
|
+
padding: Platform3.OS === "ios" ? 7 : 9
|
|
348
|
+
},
|
|
349
|
+
onPress: onClose,
|
|
350
|
+
children: /* @__PURE__ */ jsx3(SvgXml, { xml: originXML, width: 30, height: 30 })
|
|
351
|
+
}
|
|
352
|
+
) })
|
|
353
|
+
}
|
|
354
|
+
)
|
|
355
|
+
] });
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// src/components/GameWebView.tsx
|
|
359
|
+
import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
360
|
+
var GameWebView = forwardRef(function GameWebView2(props, ref) {
|
|
361
|
+
return /* @__PURE__ */ jsxs2(Fragment3, { children: [
|
|
362
|
+
/* @__PURE__ */ jsx4(
|
|
363
|
+
GameNavigationBar,
|
|
364
|
+
{
|
|
365
|
+
onClose: () => {
|
|
366
|
+
closeView();
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
),
|
|
370
|
+
/* @__PURE__ */ jsx4(View3, { style: { flex: 1 }, children: /* @__PURE__ */ jsx4(PlainWebView, { ref, ...props }) })
|
|
371
|
+
] });
|
|
372
|
+
});
|
|
373
|
+
|
|
217
374
|
// src/async-bridges.ts
|
|
218
375
|
var async_bridges_exports = {};
|
|
219
376
|
__export(async_bridges_exports, {
|
|
@@ -246,19 +403,41 @@ __export(event_bridges_exports, {
|
|
|
246
403
|
});
|
|
247
404
|
|
|
248
405
|
// src/components/WebView.tsx
|
|
249
|
-
import { jsx as
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
406
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
407
|
+
var appsInTossGlobals = getAppsInTossGlobals();
|
|
408
|
+
var TYPES = ["partner", "external", "game"];
|
|
409
|
+
var WEBVIEW_TYPES = {
|
|
410
|
+
partner: PartnerWebViewScreen,
|
|
411
|
+
external: ExternalWebViewScreen,
|
|
412
|
+
game: GameWebView
|
|
413
|
+
};
|
|
414
|
+
function mergeSchemeQueryParamsInto(url) {
|
|
415
|
+
const baseUrl = new URL(url);
|
|
416
|
+
const schemeUrl = new URL(getSchemeUri());
|
|
417
|
+
baseUrl.pathname = schemeUrl.pathname;
|
|
418
|
+
for (const [key, value] of schemeUrl.searchParams.entries()) {
|
|
419
|
+
baseUrl.searchParams.set(key, value);
|
|
420
|
+
}
|
|
421
|
+
return baseUrl;
|
|
422
|
+
}
|
|
423
|
+
function getWebViewUri(local) {
|
|
424
|
+
if (__DEV__) {
|
|
425
|
+
const devUrl = `http://${local.host}:${local.port}`;
|
|
426
|
+
return mergeSchemeQueryParamsInto(devUrl).toString();
|
|
427
|
+
}
|
|
428
|
+
const { url: rawUrl } = AppsInTossModule.getWebBundleURL({});
|
|
429
|
+
const url = mergeSchemeQueryParamsInto(rawUrl);
|
|
430
|
+
const deploymentId = env.getDeploymentId();
|
|
431
|
+
if (deploymentId) {
|
|
432
|
+
url.searchParams.set("_deploymentId", deploymentId);
|
|
433
|
+
}
|
|
434
|
+
return url.toString();
|
|
435
|
+
}
|
|
436
|
+
function WebView({ type, local, onMessage, ...props }) {
|
|
437
|
+
if (!TYPES.includes(type)) {
|
|
438
|
+
throw new Error(`Invalid WebView type: '${type}'`);
|
|
439
|
+
}
|
|
440
|
+
const uri = useMemo(() => getWebViewUri(local), [local]);
|
|
262
441
|
const handler = useBridgeHandler({
|
|
263
442
|
onMessage,
|
|
264
443
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
@@ -276,14 +455,43 @@ function WebView({ local, onMessage, ...props }) {
|
|
|
276
455
|
...async_bridges_exports
|
|
277
456
|
}
|
|
278
457
|
});
|
|
279
|
-
|
|
280
|
-
|
|
458
|
+
const baseProps = useMemo(() => {
|
|
459
|
+
switch (type) {
|
|
460
|
+
case "partner": {
|
|
461
|
+
const headerOnlyProp = {
|
|
462
|
+
header: {
|
|
463
|
+
..."header" in props ? props.header : {},
|
|
464
|
+
icon: toIcon(ensureValue(appsInTossGlobals.brandIcon, "icon")),
|
|
465
|
+
title: ensureValue(appsInTossGlobals.brandDisplayName, "displayName"),
|
|
466
|
+
rightButtons: void 0
|
|
467
|
+
// TODO: onClick 이벤트를 받아야 하기에 런타임에서 설정 받아야 함
|
|
468
|
+
}
|
|
469
|
+
};
|
|
470
|
+
return headerOnlyProp;
|
|
471
|
+
}
|
|
472
|
+
case "external": {
|
|
473
|
+
const headerOnlyProp = {
|
|
474
|
+
header: {
|
|
475
|
+
..."header" in props ? props.header : {},
|
|
476
|
+
icon: toIcon(ensureValue(appsInTossGlobals.brandIcon, "icon")),
|
|
477
|
+
title: ensureValue(appsInTossGlobals.brandDisplayName, "displayName")
|
|
478
|
+
}
|
|
479
|
+
};
|
|
480
|
+
return headerOnlyProp;
|
|
481
|
+
}
|
|
482
|
+
default: {
|
|
483
|
+
return {};
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}, [type, props]);
|
|
487
|
+
const BaseWebView = WEBVIEW_TYPES[type];
|
|
488
|
+
return /* @__PURE__ */ jsx5(
|
|
489
|
+
BaseWebView,
|
|
281
490
|
{
|
|
282
491
|
ref: handler.ref,
|
|
283
492
|
...props,
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
},
|
|
493
|
+
...baseProps,
|
|
494
|
+
source: { uri },
|
|
287
495
|
sharedCookiesEnabled: true,
|
|
288
496
|
thirdPartyCookiesEnabled: true,
|
|
289
497
|
cacheEnabled: false,
|
|
@@ -294,14 +502,20 @@ function WebView({ local, onMessage, ...props }) {
|
|
|
294
502
|
}
|
|
295
503
|
);
|
|
296
504
|
}
|
|
505
|
+
function ensureValue(value, name) {
|
|
506
|
+
if (value === void 0) {
|
|
507
|
+
throw new Error(`${name} is required`);
|
|
508
|
+
}
|
|
509
|
+
return value;
|
|
510
|
+
}
|
|
297
511
|
|
|
298
512
|
// src/hooks/useGeolocation.ts
|
|
299
|
-
import { useState, useEffect } from "react";
|
|
513
|
+
import { useState, useEffect as useEffect2 } from "react";
|
|
300
514
|
import { useVisibility } from "react-native-bedrock";
|
|
301
515
|
function useGeolocation({ accuracy, distanceInterval, timeInterval }) {
|
|
302
516
|
const isVisible = useVisibility();
|
|
303
517
|
const [location, setLocation] = useState(null);
|
|
304
|
-
|
|
518
|
+
useEffect2(() => {
|
|
305
519
|
if (!isVisible) {
|
|
306
520
|
return;
|
|
307
521
|
}
|