sales-frontend-bridge 0.0.1 → 0.0.2
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 +267 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +141 -2
- package/dist/index.d.ts +141 -2
- package/dist/index.js +267 -3
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
package/dist/index.cjs
CHANGED
|
@@ -1,8 +1,272 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
var
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
5
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
// src/bridge/utils/platform-detector-utils.ts
|
|
8
|
+
var platformDetectorUtils = {
|
|
9
|
+
getPlatform() {
|
|
10
|
+
if (window.n2bridge) {
|
|
11
|
+
return "android";
|
|
12
|
+
}
|
|
13
|
+
if (window.webkit) {
|
|
14
|
+
return "ios";
|
|
15
|
+
}
|
|
16
|
+
if (window.self !== window.top) {
|
|
17
|
+
return "portal";
|
|
18
|
+
}
|
|
19
|
+
return "web";
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// src/bridge/core/core.ts
|
|
24
|
+
var Core = class {
|
|
25
|
+
constructor() {
|
|
26
|
+
this.initializeWindowBridge();
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Promise를 처리하기 위한 고유 ID 생성
|
|
30
|
+
* @returns
|
|
31
|
+
*/
|
|
32
|
+
generatePromiseId() {
|
|
33
|
+
const timestamp = Date.now();
|
|
34
|
+
const random = Math.random().toString(36).slice(2, 11);
|
|
35
|
+
return `${timestamp}_${random}`;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* 네이티브 통신을 위해 window.n2bridge 객체 초기화
|
|
39
|
+
*/
|
|
40
|
+
initializeWindowBridge() {
|
|
41
|
+
if (!window.n2bridge) {
|
|
42
|
+
window.n2bridge = {
|
|
43
|
+
promises: {},
|
|
44
|
+
resolvePromise: () => {
|
|
45
|
+
},
|
|
46
|
+
finallyResolvePromise: () => {
|
|
47
|
+
},
|
|
48
|
+
callFromNative: () => {
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
window.n2bridge.resolvePromise = this.createResolvePromiseHandler();
|
|
53
|
+
window.n2bridge.finallyResolvePromise = this.createFinallyResolvePromiseHandler();
|
|
54
|
+
window.n2bridge.callFromNative = this.createCallFromNativeHandler();
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Promise 처리 함수(Native에서 호출)
|
|
58
|
+
* @returns
|
|
59
|
+
*/
|
|
60
|
+
createResolvePromiseHandler() {
|
|
61
|
+
return (promiseId, data, error) => {
|
|
62
|
+
console.log("[resolvePromise]::", promiseId, data, error);
|
|
63
|
+
const promise = window.n2bridge.promises[promiseId];
|
|
64
|
+
if (!promise) {
|
|
65
|
+
console.error("[resolvePromise] Promise not found::", promiseId);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
if (error) {
|
|
70
|
+
promise.reject(error);
|
|
71
|
+
this.cleanupPromise(promiseId);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (promise.retain) {
|
|
75
|
+
promise.retain(data);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
promise.resolve(data);
|
|
79
|
+
this.cleanupPromise(promiseId);
|
|
80
|
+
} catch (err) {
|
|
81
|
+
console.error("[resolvePromise] Error handling promise::", err);
|
|
82
|
+
this.cleanupPromise(promiseId);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Promise 최종 처리 함수
|
|
88
|
+
* @returns
|
|
89
|
+
*/
|
|
90
|
+
createFinallyResolvePromiseHandler() {
|
|
91
|
+
return (promiseId, data, error) => {
|
|
92
|
+
const promise = window.n2bridge.promises[promiseId];
|
|
93
|
+
if (!promise) {
|
|
94
|
+
console.error("[resolvePromise] Promise not found::", promiseId);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
if (error) {
|
|
99
|
+
promise.reject(error);
|
|
100
|
+
this.cleanupPromise(promiseId);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (promise.retain) {
|
|
104
|
+
promise.retain(data);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
promise.resolve(data);
|
|
108
|
+
this.cleanupPromise(promiseId);
|
|
109
|
+
} catch (err) {
|
|
110
|
+
console.error("[resolvePromise] Error handling promise::", err);
|
|
111
|
+
this.cleanupPromise(promiseId);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Native 에서 웹으로 호출하는 함수
|
|
117
|
+
* TODO: 필요시 추가 코딩
|
|
118
|
+
* @returns
|
|
119
|
+
*/
|
|
120
|
+
createCallFromNativeHandler() {
|
|
121
|
+
return (jsonStr) => {
|
|
122
|
+
try {
|
|
123
|
+
const command = JSON.parse(jsonStr);
|
|
124
|
+
console.log("[callFromNative]::", command);
|
|
125
|
+
} catch (error) {
|
|
126
|
+
console.error("[callFromNative] parse error::", error);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* 부모 통신
|
|
132
|
+
* @param service
|
|
133
|
+
* @param action
|
|
134
|
+
* @param option
|
|
135
|
+
* @returns
|
|
136
|
+
*/
|
|
137
|
+
async callToNative(action, options) {
|
|
138
|
+
const { retainCallback: retain, ...commandOptions } = options || {};
|
|
139
|
+
return new Promise((resolve, reject) => {
|
|
140
|
+
const promiseId = `${action}_${this.generatePromiseId()}`;
|
|
141
|
+
console.log("[callToNative] promiseId::", promiseId);
|
|
142
|
+
window.n2bridge.promises[promiseId] = { resolve, reject, retain };
|
|
143
|
+
try {
|
|
144
|
+
const command = {
|
|
145
|
+
action,
|
|
146
|
+
eventName: action,
|
|
147
|
+
promiseId,
|
|
148
|
+
option: commandOptions
|
|
149
|
+
};
|
|
150
|
+
console.log("[callToNative] command::", command);
|
|
151
|
+
const platform = platformDetectorUtils.getPlatform();
|
|
152
|
+
if (platform === "android") {
|
|
153
|
+
window.n2bridge?.callFromWeb?.(JSON.stringify(command));
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (platform === "ios") {
|
|
157
|
+
window.webkit?.messageHandlers?.n2bridge?.postMessage(JSON.stringify(command));
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
if (platform === "portal") {
|
|
161
|
+
window.parent.postMessage(command, "*");
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
console.warn(`[callToNative] \uD604\uC7AC \uD50C\uB7AB\uD3FC(${platform})\uC5D0\uC11C\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uC11C\uBE44\uC2A4(${action})\uC785\uB2C8\uB2E4.`);
|
|
165
|
+
this.cleanupPromise(promiseId);
|
|
166
|
+
reject(new Error(`Unsupported platform: ${platform}`));
|
|
167
|
+
} catch (error) {
|
|
168
|
+
console.error("[callToNative] error::", error);
|
|
169
|
+
this.cleanupPromise(promiseId);
|
|
170
|
+
reject(error);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* promiseId를 초기화 해줍니다.
|
|
176
|
+
* @param promiseId
|
|
177
|
+
*/
|
|
178
|
+
cleanupPromise(promiseId) {
|
|
179
|
+
delete window.n2bridge.promises[promiseId];
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
// src/bridge/common-bridge.ts
|
|
184
|
+
var CommonBridge = class {
|
|
185
|
+
constructor() {
|
|
186
|
+
__publicField(this, "platform");
|
|
187
|
+
__publicField(this, "core");
|
|
188
|
+
this.platform = platformDetectorUtils.getPlatform();
|
|
189
|
+
this.core = new Core();
|
|
190
|
+
}
|
|
191
|
+
// 공통 기능 구현
|
|
192
|
+
//! 분기가 생기면 각 클래스에서 Override
|
|
193
|
+
async logout(options) {
|
|
194
|
+
return this.core.callToNative("logout", options);
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
// src/bridge/native-bridge.ts
|
|
199
|
+
var NativeBridge = class extends CommonBridge {
|
|
200
|
+
/**
|
|
201
|
+
*
|
|
202
|
+
* @param options
|
|
203
|
+
* @returns
|
|
204
|
+
*/
|
|
205
|
+
async showWebPopup(options) {
|
|
206
|
+
return this.core.callToNative("showWebPopup", options);
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
// src/bridge/portal-bridge.ts
|
|
211
|
+
var PortalBridge = class extends CommonBridge {
|
|
212
|
+
/**
|
|
213
|
+
* 영업포탈 tab open
|
|
214
|
+
* @param options
|
|
215
|
+
* @returns
|
|
216
|
+
*/
|
|
217
|
+
async openUrlWindow(options) {
|
|
218
|
+
return this.core.callToNative("openMdi", options);
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
// src/bridge/factory/bridge-factory.ts
|
|
223
|
+
var BridgeFactory = class {
|
|
224
|
+
static create() {
|
|
225
|
+
const platform = platformDetectorUtils.getPlatform();
|
|
226
|
+
switch (platform) {
|
|
227
|
+
case "android":
|
|
228
|
+
case "ios":
|
|
229
|
+
return new NativeBridge();
|
|
230
|
+
case "portal":
|
|
231
|
+
return new PortalBridge();
|
|
232
|
+
case "web":
|
|
233
|
+
default:
|
|
234
|
+
console.warn(`[BridgeFactory] \uD604\uC7AC \uD50C\uB7AB\uD3FC(${platform})\uC5D0\uC11C\uB294 Bridge \uAC1D\uCCB4\uB97C \uC0DD\uC131\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`);
|
|
235
|
+
return new CommonBridge();
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
// src/bridge/bridge.ts
|
|
241
|
+
var Bridge = class {
|
|
242
|
+
static getInstance() {
|
|
243
|
+
if (!this.instance) {
|
|
244
|
+
this.instance = BridgeFactory.create();
|
|
245
|
+
}
|
|
246
|
+
return this.instance;
|
|
247
|
+
}
|
|
248
|
+
// 플랫폼별 접근자들만 제공
|
|
249
|
+
static getCommonBridge() {
|
|
250
|
+
return this.getInstance();
|
|
251
|
+
}
|
|
252
|
+
static getNativeBridge() {
|
|
253
|
+
const instance = this.getInstance();
|
|
254
|
+
return instance instanceof NativeBridge ? instance : null;
|
|
255
|
+
}
|
|
256
|
+
static getPortalBridge() {
|
|
257
|
+
const instance = this.getInstance();
|
|
258
|
+
return instance instanceof PortalBridge ? instance : null;
|
|
259
|
+
}
|
|
260
|
+
// 플랫폼 체크
|
|
261
|
+
static isNativePlatform() {
|
|
262
|
+
return this.getInstance() instanceof NativeBridge;
|
|
263
|
+
}
|
|
264
|
+
static isPortalPlatform() {
|
|
265
|
+
return this.getInstance() instanceof PortalBridge;
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
__publicField(Bridge, "instance");
|
|
269
|
+
|
|
270
|
+
exports.Bridge = Bridge;
|
|
7
271
|
//# sourceMappingURL=index.cjs.map
|
|
8
272
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/sample/index.ts"],"names":[],"mappings":";;;AAAO,IAAM,KAAQ,GAAA,MAAM,OAAQ,CAAA,GAAA,CAAI,OAAO","file":"index.cjs","sourcesContent":["export const hello = () => console.log('hello');\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/bridge/utils/platform-detector-utils.ts","../src/bridge/core/core.ts","../src/bridge/common-bridge.ts","../src/bridge/native-bridge.ts","../src/bridge/portal-bridge.ts","../src/bridge/factory/bridge-factory.ts","../src/bridge/bridge.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["import { Platform } from '../types/common.types';\n\nexport const platformDetectorUtils = {\n getPlatform(): Platform {\n // TODO: platform 탐지는 좀 더 세밀하게 할 수 있도록 네이티브에 요청\n if (window.n2bridge) {\n return 'android';\n }\n\n if (window.webkit) {\n return 'ios';\n }\n\n if (window.self !== window.top) {\n return 'portal';\n }\n\n return 'web';\n }\n};\n","import { platformDetectorUtils } from '../utils/platform-detector-utils';\nimport { IBridgeCommand, IBridgeOptions, IBridgePromise } from '../types/core.types';\nimport { BridgeAction } from '../types/bridge-types';\n\n/**\n * Bridge 통신 위한 핵심 클래스\n */\nexport class Core {\n constructor() {\n this.initializeWindowBridge();\n }\n\n /**\n * Promise를 처리하기 위한 고유 ID 생성\n * @returns\n */\n private generatePromiseId(): string {\n const timestamp = Date.now();\n const random = Math.random().toString(36).slice(2, 11);\n\n return `${timestamp}_${random}`;\n }\n\n /**\n * 네이티브 통신을 위해 window.n2bridge 객체 초기화\n */\n private initializeWindowBridge(): void {\n // 예외 체크\n if (!window.n2bridge) {\n window.n2bridge = {\n promises: {},\n resolvePromise: () => {},\n finallyResolvePromise: () => {},\n callFromNative: () => {}\n };\n }\n\n // 항상 최신 함수로 업데이트\n window.n2bridge.resolvePromise = this.createResolvePromiseHandler();\n window.n2bridge.finallyResolvePromise = this.createFinallyResolvePromiseHandler();\n window.n2bridge.callFromNative = this.createCallFromNativeHandler();\n }\n\n /**\n * Promise 처리 함수(Native에서 호출)\n * @returns\n */\n private createResolvePromiseHandler() {\n return (promiseId: string, data?: any, error?: any) => {\n console.log('[resolvePromise]::', promiseId, data, error);\n\n const promise: IBridgePromise | undefined = window.n2bridge.promises[promiseId];\n if (!promise) {\n console.error('[resolvePromise] Promise not found::', promiseId);\n return;\n }\n\n try {\n if (error) {\n promise.reject(error);\n this.cleanupPromise(promiseId);\n return;\n }\n\n if (promise.retain) {\n promise.retain(data);\n return;\n }\n\n promise.resolve(data);\n this.cleanupPromise(promiseId);\n } catch (err) {\n console.error('[resolvePromise] Error handling promise::', err);\n this.cleanupPromise(promiseId);\n }\n };\n }\n\n /**\n * Promise 최종 처리 함수\n * @returns\n */\n private createFinallyResolvePromiseHandler() {\n return (promiseId: string, data?: any, error?: any) => {\n const promise: IBridgePromise | undefined = window.n2bridge.promises[promiseId];\n if (!promise) {\n console.error('[resolvePromise] Promise not found::', promiseId);\n return;\n }\n\n try {\n if (error) {\n promise.reject(error);\n this.cleanupPromise(promiseId);\n return;\n }\n\n if (promise.retain) {\n promise.retain(data);\n return;\n }\n\n promise.resolve(data);\n this.cleanupPromise(promiseId);\n } catch (err) {\n console.error('[resolvePromise] Error handling promise::', err);\n this.cleanupPromise(promiseId);\n }\n };\n }\n\n /**\n * Native 에서 웹으로 호출하는 함수\n * TODO: 필요시 추가 코딩\n * @returns\n */\n private createCallFromNativeHandler() {\n return (jsonStr: string) => {\n try {\n const command = JSON.parse(jsonStr);\n console.log('[callFromNative]::', command);\n } catch (error) {\n console.error('[callFromNative] parse error::', error);\n }\n };\n }\n\n /**\n * 부모 통신\n * @param service\n * @param action\n * @param option\n * @returns\n */\n async callToNative<T = any>(action: BridgeAction, options?: IBridgeOptions): Promise<T> {\n const { retainCallback: retain, ...commandOptions } = options || {};\n\n return new Promise<T>((resolve, reject) => {\n const promiseId = `${action}_${this.generatePromiseId()}`;\n console.log('[callToNative] promiseId::', promiseId);\n\n // 바로 window.n2bridge.promises에 저장\n window.n2bridge.promises[promiseId] = { resolve, reject, retain };\n\n try {\n const command: IBridgeCommand = {\n action,\n eventName: action,\n promiseId,\n option: commandOptions\n };\n\n console.log('[callToNative] command::', command);\n\n const platform = platformDetectorUtils.getPlatform();\n\n if (platform === 'android') {\n window.n2bridge?.callFromWeb?.(JSON.stringify(command));\n\n return;\n }\n\n if (platform === 'ios') {\n window.webkit?.messageHandlers?.n2bridge?.postMessage(JSON.stringify(command));\n\n return;\n }\n\n if (platform === 'portal') {\n window.parent.postMessage(command, '*');\n\n return;\n }\n\n // 지원하지 않는 플랫폼\n console.warn(`[callToNative] 현재 플랫폼(${platform})에서는 지원하지 않는 서비스(${action})입니다.`);\n this.cleanupPromise(promiseId);\n reject(new Error(`Unsupported platform: ${platform}`));\n } catch (error) {\n console.error('[callToNative] error::', error);\n this.cleanupPromise(promiseId);\n reject(error);\n }\n });\n }\n\n /**\n * promiseId를 초기화 해줍니다.\n * @param promiseId\n */\n private cleanupPromise(promiseId: string): void {\n delete window.n2bridge.promises[promiseId];\n }\n}\n","import { ICommonBridge } from './types/common.types';\nimport { Core } from './core/core';\nimport { Platform } from './types/common.types';\nimport { platformDetectorUtils } from './utils/platform-detector-utils';\nimport { ILoginOptions } from './types/bridge-types';\n\n/**\n * App, 영업포털과 동일하게 사용가능한 기능 정의 클래스\n */\nexport class CommonBridge implements ICommonBridge {\n protected platform: Platform;\n protected core: Core;\n\n constructor() {\n this.platform = platformDetectorUtils.getPlatform();\n this.core = new Core();\n }\n\n // 공통 기능 구현\n //! 분기가 생기면 각 클래스에서 Override\n async logout(options: ILoginOptions): Promise<void> {\n return this.core.callToNative('logout', options);\n }\n}\n","import { INativeBridge } from './types/common.types';\nimport { CommonBridge } from './common-bridge';\nimport { IShowWebPopupOptions } from './types/bridge-types';\n\nexport class NativeBridge extends CommonBridge implements INativeBridge {\n /**\n *\n * @param options\n * @returns\n */\n async showWebPopup<T = any>(options: IShowWebPopupOptions): Promise<T> {\n return this.core.callToNative<T>('showWebPopup', options);\n }\n}\n","import { CommonBridge } from './common-bridge';\nimport { IPortalBridge } from './types/common.types';\n\n/**\n * 영업포탈 전용 Bridge\n */\nexport class PortalBridge extends CommonBridge implements IPortalBridge {\n /**\n * 영업포탈 tab open\n * @param options\n * @returns\n */\n async openUrlWindow<T = any>(options: any): Promise<T> {\n return this.core.callToNative<T>('openMdi', options);\n }\n}\n","import { platformDetectorUtils } from '../utils/platform-detector-utils';\nimport { NativeBridge } from '../native-bridge';\nimport { PortalBridge } from '../portal-bridge';\nimport { CommonBridge } from '../common-bridge';\n\n/**\n * 브릿지 객체 생성 전용 클래스\n */\nexport class BridgeFactory {\n static create(): NativeBridge | PortalBridge | CommonBridge {\n const platform = platformDetectorUtils.getPlatform();\n\n switch (platform) {\n case 'android':\n case 'ios':\n return new NativeBridge();\n\n case 'portal':\n return new PortalBridge();\n\n case 'web':\n default:\n console.warn(`[BridgeFactory] 현재 플랫폼(${platform})에서는 Bridge 객체를 생성할 수 없습니다.`);\n\n return new CommonBridge();\n }\n }\n}\n","import { NativeBridge } from './native-bridge';\nimport { PortalBridge } from './portal-bridge';\nimport { CommonBridge } from './common-bridge';\nimport { BridgeFactory } from './factory/bridge-factory';\n\nexport class Bridge {\n private static instance: NativeBridge | PortalBridge | CommonBridge;\n\n static getInstance() {\n if (!this.instance) {\n this.instance = BridgeFactory.create();\n }\n return this.instance;\n }\n\n // 플랫폼별 접근자들만 제공\n static getCommonBridge(): CommonBridge {\n return this.getInstance();\n }\n\n static getNativeBridge(): NativeBridge | null {\n const instance = this.getInstance();\n return instance instanceof NativeBridge ? instance : null;\n }\n\n static getPortalBridge(): PortalBridge | null {\n const instance = this.getInstance();\n return instance instanceof PortalBridge ? instance : null;\n }\n\n // 플랫폼 체크\n static isNativePlatform(): boolean {\n return this.getInstance() instanceof NativeBridge;\n }\n\n static isPortalPlatform(): boolean {\n return this.getInstance() instanceof PortalBridge;\n }\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,142 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Actions
|
|
3
|
+
*/
|
|
4
|
+
/** 사용가능한 브릿지 액션명 (필요시, 계속 추가)*/
|
|
5
|
+
type CommonAction = 'logout';
|
|
6
|
+
type NativeAction = CommonAction | 'showWebPopup';
|
|
7
|
+
type PortalAction = CommonAction | 'openMdi';
|
|
8
|
+
type BridgeAction = NativeAction | PortalAction;
|
|
9
|
+
/**
|
|
10
|
+
* Params
|
|
11
|
+
*/
|
|
12
|
+
interface IOpenUrlWindowParams {
|
|
13
|
+
}
|
|
14
|
+
interface ILogoutParams {
|
|
15
|
+
}
|
|
16
|
+
interface ILoginOptions {
|
|
17
|
+
}
|
|
18
|
+
interface IShowWebPopupOptions {
|
|
19
|
+
/** 0: fullscreen, 1: title bar, 2: size 지정 가능 팝업, 3: wk webview */
|
|
20
|
+
popupType: 0 | 1 | 2 | 3;
|
|
21
|
+
/** tㅏ이즈 */
|
|
22
|
+
size?: {
|
|
23
|
+
width: string;
|
|
24
|
+
height: string;
|
|
25
|
+
};
|
|
26
|
+
/** URL */
|
|
27
|
+
url: string;
|
|
28
|
+
/** 파라미터 */
|
|
29
|
+
param: Record<string, unknown>;
|
|
30
|
+
}
|
|
2
31
|
|
|
3
|
-
|
|
32
|
+
type Platform = 'web' | 'android' | 'ios' | 'portal';
|
|
33
|
+
interface ICommonBridge {
|
|
34
|
+
logout(options: ILogoutParams): Promise<any>;
|
|
35
|
+
}
|
|
36
|
+
interface INativeOnlyBridge {
|
|
37
|
+
showWebPopup<T>(options: IShowWebPopupOptions): Promise<T>;
|
|
38
|
+
}
|
|
39
|
+
interface IPortalOnlyBridge {
|
|
40
|
+
openUrlWindow(options: IOpenUrlWindowParams): Promise<void>;
|
|
41
|
+
}
|
|
42
|
+
interface INativeBridge extends ICommonBridge, INativeOnlyBridge {
|
|
43
|
+
}
|
|
44
|
+
interface IPortalBridge extends ICommonBridge, IPortalOnlyBridge {
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
type RetainCallback<T = any> = (params: T) => void;
|
|
48
|
+
/**
|
|
49
|
+
* Command의 옵션
|
|
50
|
+
*/
|
|
51
|
+
interface IBridgeOptions {
|
|
52
|
+
retainCallback?: RetainCallback;
|
|
53
|
+
[key: string]: any;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Bridge 통신 위한 핵심 클래스
|
|
58
|
+
*/
|
|
59
|
+
declare class Core {
|
|
60
|
+
constructor();
|
|
61
|
+
/**
|
|
62
|
+
* Promise를 처리하기 위한 고유 ID 생성
|
|
63
|
+
* @returns
|
|
64
|
+
*/
|
|
65
|
+
private generatePromiseId;
|
|
66
|
+
/**
|
|
67
|
+
* 네이티브 통신을 위해 window.n2bridge 객체 초기화
|
|
68
|
+
*/
|
|
69
|
+
private initializeWindowBridge;
|
|
70
|
+
/**
|
|
71
|
+
* Promise 처리 함수(Native에서 호출)
|
|
72
|
+
* @returns
|
|
73
|
+
*/
|
|
74
|
+
private createResolvePromiseHandler;
|
|
75
|
+
/**
|
|
76
|
+
* Promise 최종 처리 함수
|
|
77
|
+
* @returns
|
|
78
|
+
*/
|
|
79
|
+
private createFinallyResolvePromiseHandler;
|
|
80
|
+
/**
|
|
81
|
+
* Native 에서 웹으로 호출하는 함수
|
|
82
|
+
* TODO: 필요시 추가 코딩
|
|
83
|
+
* @returns
|
|
84
|
+
*/
|
|
85
|
+
private createCallFromNativeHandler;
|
|
86
|
+
/**
|
|
87
|
+
* 부모 통신
|
|
88
|
+
* @param service
|
|
89
|
+
* @param action
|
|
90
|
+
* @param option
|
|
91
|
+
* @returns
|
|
92
|
+
*/
|
|
93
|
+
callToNative<T = any>(action: BridgeAction, options?: IBridgeOptions): Promise<T>;
|
|
94
|
+
/**
|
|
95
|
+
* promiseId를 초기화 해줍니다.
|
|
96
|
+
* @param promiseId
|
|
97
|
+
*/
|
|
98
|
+
private cleanupPromise;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* App, 영업포털과 동일하게 사용가능한 기능 정의 클래스
|
|
103
|
+
*/
|
|
104
|
+
declare class CommonBridge implements ICommonBridge {
|
|
105
|
+
protected platform: Platform;
|
|
106
|
+
protected core: Core;
|
|
107
|
+
constructor();
|
|
108
|
+
logout(options: ILoginOptions): Promise<void>;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
declare class NativeBridge extends CommonBridge implements INativeBridge {
|
|
112
|
+
/**
|
|
113
|
+
*
|
|
114
|
+
* @param options
|
|
115
|
+
* @returns
|
|
116
|
+
*/
|
|
117
|
+
showWebPopup<T = any>(options: IShowWebPopupOptions): Promise<T>;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* 영업포탈 전용 Bridge
|
|
122
|
+
*/
|
|
123
|
+
declare class PortalBridge extends CommonBridge implements IPortalBridge {
|
|
124
|
+
/**
|
|
125
|
+
* 영업포탈 tab open
|
|
126
|
+
* @param options
|
|
127
|
+
* @returns
|
|
128
|
+
*/
|
|
129
|
+
openUrlWindow<T = any>(options: any): Promise<T>;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
declare class Bridge {
|
|
133
|
+
private static instance;
|
|
134
|
+
static getInstance(): CommonBridge | NativeBridge | PortalBridge;
|
|
135
|
+
static getCommonBridge(): CommonBridge;
|
|
136
|
+
static getNativeBridge(): NativeBridge | null;
|
|
137
|
+
static getPortalBridge(): PortalBridge | null;
|
|
138
|
+
static isNativePlatform(): boolean;
|
|
139
|
+
static isPortalPlatform(): boolean;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export { Bridge };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,142 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Actions
|
|
3
|
+
*/
|
|
4
|
+
/** 사용가능한 브릿지 액션명 (필요시, 계속 추가)*/
|
|
5
|
+
type CommonAction = 'logout';
|
|
6
|
+
type NativeAction = CommonAction | 'showWebPopup';
|
|
7
|
+
type PortalAction = CommonAction | 'openMdi';
|
|
8
|
+
type BridgeAction = NativeAction | PortalAction;
|
|
9
|
+
/**
|
|
10
|
+
* Params
|
|
11
|
+
*/
|
|
12
|
+
interface IOpenUrlWindowParams {
|
|
13
|
+
}
|
|
14
|
+
interface ILogoutParams {
|
|
15
|
+
}
|
|
16
|
+
interface ILoginOptions {
|
|
17
|
+
}
|
|
18
|
+
interface IShowWebPopupOptions {
|
|
19
|
+
/** 0: fullscreen, 1: title bar, 2: size 지정 가능 팝업, 3: wk webview */
|
|
20
|
+
popupType: 0 | 1 | 2 | 3;
|
|
21
|
+
/** tㅏ이즈 */
|
|
22
|
+
size?: {
|
|
23
|
+
width: string;
|
|
24
|
+
height: string;
|
|
25
|
+
};
|
|
26
|
+
/** URL */
|
|
27
|
+
url: string;
|
|
28
|
+
/** 파라미터 */
|
|
29
|
+
param: Record<string, unknown>;
|
|
30
|
+
}
|
|
2
31
|
|
|
3
|
-
|
|
32
|
+
type Platform = 'web' | 'android' | 'ios' | 'portal';
|
|
33
|
+
interface ICommonBridge {
|
|
34
|
+
logout(options: ILogoutParams): Promise<any>;
|
|
35
|
+
}
|
|
36
|
+
interface INativeOnlyBridge {
|
|
37
|
+
showWebPopup<T>(options: IShowWebPopupOptions): Promise<T>;
|
|
38
|
+
}
|
|
39
|
+
interface IPortalOnlyBridge {
|
|
40
|
+
openUrlWindow(options: IOpenUrlWindowParams): Promise<void>;
|
|
41
|
+
}
|
|
42
|
+
interface INativeBridge extends ICommonBridge, INativeOnlyBridge {
|
|
43
|
+
}
|
|
44
|
+
interface IPortalBridge extends ICommonBridge, IPortalOnlyBridge {
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
type RetainCallback<T = any> = (params: T) => void;
|
|
48
|
+
/**
|
|
49
|
+
* Command의 옵션
|
|
50
|
+
*/
|
|
51
|
+
interface IBridgeOptions {
|
|
52
|
+
retainCallback?: RetainCallback;
|
|
53
|
+
[key: string]: any;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Bridge 통신 위한 핵심 클래스
|
|
58
|
+
*/
|
|
59
|
+
declare class Core {
|
|
60
|
+
constructor();
|
|
61
|
+
/**
|
|
62
|
+
* Promise를 처리하기 위한 고유 ID 생성
|
|
63
|
+
* @returns
|
|
64
|
+
*/
|
|
65
|
+
private generatePromiseId;
|
|
66
|
+
/**
|
|
67
|
+
* 네이티브 통신을 위해 window.n2bridge 객체 초기화
|
|
68
|
+
*/
|
|
69
|
+
private initializeWindowBridge;
|
|
70
|
+
/**
|
|
71
|
+
* Promise 처리 함수(Native에서 호출)
|
|
72
|
+
* @returns
|
|
73
|
+
*/
|
|
74
|
+
private createResolvePromiseHandler;
|
|
75
|
+
/**
|
|
76
|
+
* Promise 최종 처리 함수
|
|
77
|
+
* @returns
|
|
78
|
+
*/
|
|
79
|
+
private createFinallyResolvePromiseHandler;
|
|
80
|
+
/**
|
|
81
|
+
* Native 에서 웹으로 호출하는 함수
|
|
82
|
+
* TODO: 필요시 추가 코딩
|
|
83
|
+
* @returns
|
|
84
|
+
*/
|
|
85
|
+
private createCallFromNativeHandler;
|
|
86
|
+
/**
|
|
87
|
+
* 부모 통신
|
|
88
|
+
* @param service
|
|
89
|
+
* @param action
|
|
90
|
+
* @param option
|
|
91
|
+
* @returns
|
|
92
|
+
*/
|
|
93
|
+
callToNative<T = any>(action: BridgeAction, options?: IBridgeOptions): Promise<T>;
|
|
94
|
+
/**
|
|
95
|
+
* promiseId를 초기화 해줍니다.
|
|
96
|
+
* @param promiseId
|
|
97
|
+
*/
|
|
98
|
+
private cleanupPromise;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* App, 영업포털과 동일하게 사용가능한 기능 정의 클래스
|
|
103
|
+
*/
|
|
104
|
+
declare class CommonBridge implements ICommonBridge {
|
|
105
|
+
protected platform: Platform;
|
|
106
|
+
protected core: Core;
|
|
107
|
+
constructor();
|
|
108
|
+
logout(options: ILoginOptions): Promise<void>;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
declare class NativeBridge extends CommonBridge implements INativeBridge {
|
|
112
|
+
/**
|
|
113
|
+
*
|
|
114
|
+
* @param options
|
|
115
|
+
* @returns
|
|
116
|
+
*/
|
|
117
|
+
showWebPopup<T = any>(options: IShowWebPopupOptions): Promise<T>;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* 영업포탈 전용 Bridge
|
|
122
|
+
*/
|
|
123
|
+
declare class PortalBridge extends CommonBridge implements IPortalBridge {
|
|
124
|
+
/**
|
|
125
|
+
* 영업포탈 tab open
|
|
126
|
+
* @param options
|
|
127
|
+
* @returns
|
|
128
|
+
*/
|
|
129
|
+
openUrlWindow<T = any>(options: any): Promise<T>;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
declare class Bridge {
|
|
133
|
+
private static instance;
|
|
134
|
+
static getInstance(): CommonBridge | NativeBridge | PortalBridge;
|
|
135
|
+
static getCommonBridge(): CommonBridge;
|
|
136
|
+
static getNativeBridge(): NativeBridge | null;
|
|
137
|
+
static getPortalBridge(): PortalBridge | null;
|
|
138
|
+
static isNativePlatform(): boolean;
|
|
139
|
+
static isPortalPlatform(): boolean;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export { Bridge };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,270 @@
|
|
|
1
|
-
|
|
2
|
-
var
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
// src/bridge/utils/platform-detector-utils.ts
|
|
6
|
+
var platformDetectorUtils = {
|
|
7
|
+
getPlatform() {
|
|
8
|
+
if (window.n2bridge) {
|
|
9
|
+
return "android";
|
|
10
|
+
}
|
|
11
|
+
if (window.webkit) {
|
|
12
|
+
return "ios";
|
|
13
|
+
}
|
|
14
|
+
if (window.self !== window.top) {
|
|
15
|
+
return "portal";
|
|
16
|
+
}
|
|
17
|
+
return "web";
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// src/bridge/core/core.ts
|
|
22
|
+
var Core = class {
|
|
23
|
+
constructor() {
|
|
24
|
+
this.initializeWindowBridge();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Promise를 처리하기 위한 고유 ID 생성
|
|
28
|
+
* @returns
|
|
29
|
+
*/
|
|
30
|
+
generatePromiseId() {
|
|
31
|
+
const timestamp = Date.now();
|
|
32
|
+
const random = Math.random().toString(36).slice(2, 11);
|
|
33
|
+
return `${timestamp}_${random}`;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 네이티브 통신을 위해 window.n2bridge 객체 초기화
|
|
37
|
+
*/
|
|
38
|
+
initializeWindowBridge() {
|
|
39
|
+
if (!window.n2bridge) {
|
|
40
|
+
window.n2bridge = {
|
|
41
|
+
promises: {},
|
|
42
|
+
resolvePromise: () => {
|
|
43
|
+
},
|
|
44
|
+
finallyResolvePromise: () => {
|
|
45
|
+
},
|
|
46
|
+
callFromNative: () => {
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
window.n2bridge.resolvePromise = this.createResolvePromiseHandler();
|
|
51
|
+
window.n2bridge.finallyResolvePromise = this.createFinallyResolvePromiseHandler();
|
|
52
|
+
window.n2bridge.callFromNative = this.createCallFromNativeHandler();
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Promise 처리 함수(Native에서 호출)
|
|
56
|
+
* @returns
|
|
57
|
+
*/
|
|
58
|
+
createResolvePromiseHandler() {
|
|
59
|
+
return (promiseId, data, error) => {
|
|
60
|
+
console.log("[resolvePromise]::", promiseId, data, error);
|
|
61
|
+
const promise = window.n2bridge.promises[promiseId];
|
|
62
|
+
if (!promise) {
|
|
63
|
+
console.error("[resolvePromise] Promise not found::", promiseId);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
if (error) {
|
|
68
|
+
promise.reject(error);
|
|
69
|
+
this.cleanupPromise(promiseId);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (promise.retain) {
|
|
73
|
+
promise.retain(data);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
promise.resolve(data);
|
|
77
|
+
this.cleanupPromise(promiseId);
|
|
78
|
+
} catch (err) {
|
|
79
|
+
console.error("[resolvePromise] Error handling promise::", err);
|
|
80
|
+
this.cleanupPromise(promiseId);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Promise 최종 처리 함수
|
|
86
|
+
* @returns
|
|
87
|
+
*/
|
|
88
|
+
createFinallyResolvePromiseHandler() {
|
|
89
|
+
return (promiseId, data, error) => {
|
|
90
|
+
const promise = window.n2bridge.promises[promiseId];
|
|
91
|
+
if (!promise) {
|
|
92
|
+
console.error("[resolvePromise] Promise not found::", promiseId);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
if (error) {
|
|
97
|
+
promise.reject(error);
|
|
98
|
+
this.cleanupPromise(promiseId);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (promise.retain) {
|
|
102
|
+
promise.retain(data);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
promise.resolve(data);
|
|
106
|
+
this.cleanupPromise(promiseId);
|
|
107
|
+
} catch (err) {
|
|
108
|
+
console.error("[resolvePromise] Error handling promise::", err);
|
|
109
|
+
this.cleanupPromise(promiseId);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Native 에서 웹으로 호출하는 함수
|
|
115
|
+
* TODO: 필요시 추가 코딩
|
|
116
|
+
* @returns
|
|
117
|
+
*/
|
|
118
|
+
createCallFromNativeHandler() {
|
|
119
|
+
return (jsonStr) => {
|
|
120
|
+
try {
|
|
121
|
+
const command = JSON.parse(jsonStr);
|
|
122
|
+
console.log("[callFromNative]::", command);
|
|
123
|
+
} catch (error) {
|
|
124
|
+
console.error("[callFromNative] parse error::", error);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* 부모 통신
|
|
130
|
+
* @param service
|
|
131
|
+
* @param action
|
|
132
|
+
* @param option
|
|
133
|
+
* @returns
|
|
134
|
+
*/
|
|
135
|
+
async callToNative(action, options) {
|
|
136
|
+
const { retainCallback: retain, ...commandOptions } = options || {};
|
|
137
|
+
return new Promise((resolve, reject) => {
|
|
138
|
+
const promiseId = `${action}_${this.generatePromiseId()}`;
|
|
139
|
+
console.log("[callToNative] promiseId::", promiseId);
|
|
140
|
+
window.n2bridge.promises[promiseId] = { resolve, reject, retain };
|
|
141
|
+
try {
|
|
142
|
+
const command = {
|
|
143
|
+
action,
|
|
144
|
+
eventName: action,
|
|
145
|
+
promiseId,
|
|
146
|
+
option: commandOptions
|
|
147
|
+
};
|
|
148
|
+
console.log("[callToNative] command::", command);
|
|
149
|
+
const platform = platformDetectorUtils.getPlatform();
|
|
150
|
+
if (platform === "android") {
|
|
151
|
+
window.n2bridge?.callFromWeb?.(JSON.stringify(command));
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (platform === "ios") {
|
|
155
|
+
window.webkit?.messageHandlers?.n2bridge?.postMessage(JSON.stringify(command));
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
if (platform === "portal") {
|
|
159
|
+
window.parent.postMessage(command, "*");
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
console.warn(`[callToNative] \uD604\uC7AC \uD50C\uB7AB\uD3FC(${platform})\uC5D0\uC11C\uB294 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uC11C\uBE44\uC2A4(${action})\uC785\uB2C8\uB2E4.`);
|
|
163
|
+
this.cleanupPromise(promiseId);
|
|
164
|
+
reject(new Error(`Unsupported platform: ${platform}`));
|
|
165
|
+
} catch (error) {
|
|
166
|
+
console.error("[callToNative] error::", error);
|
|
167
|
+
this.cleanupPromise(promiseId);
|
|
168
|
+
reject(error);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* promiseId를 초기화 해줍니다.
|
|
174
|
+
* @param promiseId
|
|
175
|
+
*/
|
|
176
|
+
cleanupPromise(promiseId) {
|
|
177
|
+
delete window.n2bridge.promises[promiseId];
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
// src/bridge/common-bridge.ts
|
|
182
|
+
var CommonBridge = class {
|
|
183
|
+
constructor() {
|
|
184
|
+
__publicField(this, "platform");
|
|
185
|
+
__publicField(this, "core");
|
|
186
|
+
this.platform = platformDetectorUtils.getPlatform();
|
|
187
|
+
this.core = new Core();
|
|
188
|
+
}
|
|
189
|
+
// 공통 기능 구현
|
|
190
|
+
//! 분기가 생기면 각 클래스에서 Override
|
|
191
|
+
async logout(options) {
|
|
192
|
+
return this.core.callToNative("logout", options);
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
// src/bridge/native-bridge.ts
|
|
197
|
+
var NativeBridge = class extends CommonBridge {
|
|
198
|
+
/**
|
|
199
|
+
*
|
|
200
|
+
* @param options
|
|
201
|
+
* @returns
|
|
202
|
+
*/
|
|
203
|
+
async showWebPopup(options) {
|
|
204
|
+
return this.core.callToNative("showWebPopup", options);
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
// src/bridge/portal-bridge.ts
|
|
209
|
+
var PortalBridge = class extends CommonBridge {
|
|
210
|
+
/**
|
|
211
|
+
* 영업포탈 tab open
|
|
212
|
+
* @param options
|
|
213
|
+
* @returns
|
|
214
|
+
*/
|
|
215
|
+
async openUrlWindow(options) {
|
|
216
|
+
return this.core.callToNative("openMdi", options);
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
// src/bridge/factory/bridge-factory.ts
|
|
221
|
+
var BridgeFactory = class {
|
|
222
|
+
static create() {
|
|
223
|
+
const platform = platformDetectorUtils.getPlatform();
|
|
224
|
+
switch (platform) {
|
|
225
|
+
case "android":
|
|
226
|
+
case "ios":
|
|
227
|
+
return new NativeBridge();
|
|
228
|
+
case "portal":
|
|
229
|
+
return new PortalBridge();
|
|
230
|
+
case "web":
|
|
231
|
+
default:
|
|
232
|
+
console.warn(`[BridgeFactory] \uD604\uC7AC \uD50C\uB7AB\uD3FC(${platform})\uC5D0\uC11C\uB294 Bridge \uAC1D\uCCB4\uB97C \uC0DD\uC131\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`);
|
|
233
|
+
return new CommonBridge();
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
// src/bridge/bridge.ts
|
|
239
|
+
var Bridge = class {
|
|
240
|
+
static getInstance() {
|
|
241
|
+
if (!this.instance) {
|
|
242
|
+
this.instance = BridgeFactory.create();
|
|
243
|
+
}
|
|
244
|
+
return this.instance;
|
|
245
|
+
}
|
|
246
|
+
// 플랫폼별 접근자들만 제공
|
|
247
|
+
static getCommonBridge() {
|
|
248
|
+
return this.getInstance();
|
|
249
|
+
}
|
|
250
|
+
static getNativeBridge() {
|
|
251
|
+
const instance = this.getInstance();
|
|
252
|
+
return instance instanceof NativeBridge ? instance : null;
|
|
253
|
+
}
|
|
254
|
+
static getPortalBridge() {
|
|
255
|
+
const instance = this.getInstance();
|
|
256
|
+
return instance instanceof PortalBridge ? instance : null;
|
|
257
|
+
}
|
|
258
|
+
// 플랫폼 체크
|
|
259
|
+
static isNativePlatform() {
|
|
260
|
+
return this.getInstance() instanceof NativeBridge;
|
|
261
|
+
}
|
|
262
|
+
static isPortalPlatform() {
|
|
263
|
+
return this.getInstance() instanceof PortalBridge;
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
__publicField(Bridge, "instance");
|
|
267
|
+
|
|
268
|
+
export { Bridge };
|
|
5
269
|
//# sourceMappingURL=index.js.map
|
|
6
270
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/sample/index.ts"],"names":[],"mappings":";AAAO,IAAM,KAAQ,GAAA,MAAM,OAAQ,CAAA,GAAA,CAAI,OAAO","file":"index.js","sourcesContent":["export const hello = () => console.log('hello');\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/bridge/utils/platform-detector-utils.ts","../src/bridge/core/core.ts","../src/bridge/common-bridge.ts","../src/bridge/native-bridge.ts","../src/bridge/portal-bridge.ts","../src/bridge/factory/bridge-factory.ts","../src/bridge/bridge.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { Platform } from '../types/common.types';\n\nexport const platformDetectorUtils = {\n getPlatform(): Platform {\n // TODO: platform 탐지는 좀 더 세밀하게 할 수 있도록 네이티브에 요청\n if (window.n2bridge) {\n return 'android';\n }\n\n if (window.webkit) {\n return 'ios';\n }\n\n if (window.self !== window.top) {\n return 'portal';\n }\n\n return 'web';\n }\n};\n","import { platformDetectorUtils } from '../utils/platform-detector-utils';\nimport { IBridgeCommand, IBridgeOptions, IBridgePromise } from '../types/core.types';\nimport { BridgeAction } from '../types/bridge-types';\n\n/**\n * Bridge 통신 위한 핵심 클래스\n */\nexport class Core {\n constructor() {\n this.initializeWindowBridge();\n }\n\n /**\n * Promise를 처리하기 위한 고유 ID 생성\n * @returns\n */\n private generatePromiseId(): string {\n const timestamp = Date.now();\n const random = Math.random().toString(36).slice(2, 11);\n\n return `${timestamp}_${random}`;\n }\n\n /**\n * 네이티브 통신을 위해 window.n2bridge 객체 초기화\n */\n private initializeWindowBridge(): void {\n // 예외 체크\n if (!window.n2bridge) {\n window.n2bridge = {\n promises: {},\n resolvePromise: () => {},\n finallyResolvePromise: () => {},\n callFromNative: () => {}\n };\n }\n\n // 항상 최신 함수로 업데이트\n window.n2bridge.resolvePromise = this.createResolvePromiseHandler();\n window.n2bridge.finallyResolvePromise = this.createFinallyResolvePromiseHandler();\n window.n2bridge.callFromNative = this.createCallFromNativeHandler();\n }\n\n /**\n * Promise 처리 함수(Native에서 호출)\n * @returns\n */\n private createResolvePromiseHandler() {\n return (promiseId: string, data?: any, error?: any) => {\n console.log('[resolvePromise]::', promiseId, data, error);\n\n const promise: IBridgePromise | undefined = window.n2bridge.promises[promiseId];\n if (!promise) {\n console.error('[resolvePromise] Promise not found::', promiseId);\n return;\n }\n\n try {\n if (error) {\n promise.reject(error);\n this.cleanupPromise(promiseId);\n return;\n }\n\n if (promise.retain) {\n promise.retain(data);\n return;\n }\n\n promise.resolve(data);\n this.cleanupPromise(promiseId);\n } catch (err) {\n console.error('[resolvePromise] Error handling promise::', err);\n this.cleanupPromise(promiseId);\n }\n };\n }\n\n /**\n * Promise 최종 처리 함수\n * @returns\n */\n private createFinallyResolvePromiseHandler() {\n return (promiseId: string, data?: any, error?: any) => {\n const promise: IBridgePromise | undefined = window.n2bridge.promises[promiseId];\n if (!promise) {\n console.error('[resolvePromise] Promise not found::', promiseId);\n return;\n }\n\n try {\n if (error) {\n promise.reject(error);\n this.cleanupPromise(promiseId);\n return;\n }\n\n if (promise.retain) {\n promise.retain(data);\n return;\n }\n\n promise.resolve(data);\n this.cleanupPromise(promiseId);\n } catch (err) {\n console.error('[resolvePromise] Error handling promise::', err);\n this.cleanupPromise(promiseId);\n }\n };\n }\n\n /**\n * Native 에서 웹으로 호출하는 함수\n * TODO: 필요시 추가 코딩\n * @returns\n */\n private createCallFromNativeHandler() {\n return (jsonStr: string) => {\n try {\n const command = JSON.parse(jsonStr);\n console.log('[callFromNative]::', command);\n } catch (error) {\n console.error('[callFromNative] parse error::', error);\n }\n };\n }\n\n /**\n * 부모 통신\n * @param service\n * @param action\n * @param option\n * @returns\n */\n async callToNative<T = any>(action: BridgeAction, options?: IBridgeOptions): Promise<T> {\n const { retainCallback: retain, ...commandOptions } = options || {};\n\n return new Promise<T>((resolve, reject) => {\n const promiseId = `${action}_${this.generatePromiseId()}`;\n console.log('[callToNative] promiseId::', promiseId);\n\n // 바로 window.n2bridge.promises에 저장\n window.n2bridge.promises[promiseId] = { resolve, reject, retain };\n\n try {\n const command: IBridgeCommand = {\n action,\n eventName: action,\n promiseId,\n option: commandOptions\n };\n\n console.log('[callToNative] command::', command);\n\n const platform = platformDetectorUtils.getPlatform();\n\n if (platform === 'android') {\n window.n2bridge?.callFromWeb?.(JSON.stringify(command));\n\n return;\n }\n\n if (platform === 'ios') {\n window.webkit?.messageHandlers?.n2bridge?.postMessage(JSON.stringify(command));\n\n return;\n }\n\n if (platform === 'portal') {\n window.parent.postMessage(command, '*');\n\n return;\n }\n\n // 지원하지 않는 플랫폼\n console.warn(`[callToNative] 현재 플랫폼(${platform})에서는 지원하지 않는 서비스(${action})입니다.`);\n this.cleanupPromise(promiseId);\n reject(new Error(`Unsupported platform: ${platform}`));\n } catch (error) {\n console.error('[callToNative] error::', error);\n this.cleanupPromise(promiseId);\n reject(error);\n }\n });\n }\n\n /**\n * promiseId를 초기화 해줍니다.\n * @param promiseId\n */\n private cleanupPromise(promiseId: string): void {\n delete window.n2bridge.promises[promiseId];\n }\n}\n","import { ICommonBridge } from './types/common.types';\nimport { Core } from './core/core';\nimport { Platform } from './types/common.types';\nimport { platformDetectorUtils } from './utils/platform-detector-utils';\nimport { ILoginOptions } from './types/bridge-types';\n\n/**\n * App, 영업포털과 동일하게 사용가능한 기능 정의 클래스\n */\nexport class CommonBridge implements ICommonBridge {\n protected platform: Platform;\n protected core: Core;\n\n constructor() {\n this.platform = platformDetectorUtils.getPlatform();\n this.core = new Core();\n }\n\n // 공통 기능 구현\n //! 분기가 생기면 각 클래스에서 Override\n async logout(options: ILoginOptions): Promise<void> {\n return this.core.callToNative('logout', options);\n }\n}\n","import { INativeBridge } from './types/common.types';\nimport { CommonBridge } from './common-bridge';\nimport { IShowWebPopupOptions } from './types/bridge-types';\n\nexport class NativeBridge extends CommonBridge implements INativeBridge {\n /**\n *\n * @param options\n * @returns\n */\n async showWebPopup<T = any>(options: IShowWebPopupOptions): Promise<T> {\n return this.core.callToNative<T>('showWebPopup', options);\n }\n}\n","import { CommonBridge } from './common-bridge';\nimport { IPortalBridge } from './types/common.types';\n\n/**\n * 영업포탈 전용 Bridge\n */\nexport class PortalBridge extends CommonBridge implements IPortalBridge {\n /**\n * 영업포탈 tab open\n * @param options\n * @returns\n */\n async openUrlWindow<T = any>(options: any): Promise<T> {\n return this.core.callToNative<T>('openMdi', options);\n }\n}\n","import { platformDetectorUtils } from '../utils/platform-detector-utils';\nimport { NativeBridge } from '../native-bridge';\nimport { PortalBridge } from '../portal-bridge';\nimport { CommonBridge } from '../common-bridge';\n\n/**\n * 브릿지 객체 생성 전용 클래스\n */\nexport class BridgeFactory {\n static create(): NativeBridge | PortalBridge | CommonBridge {\n const platform = platformDetectorUtils.getPlatform();\n\n switch (platform) {\n case 'android':\n case 'ios':\n return new NativeBridge();\n\n case 'portal':\n return new PortalBridge();\n\n case 'web':\n default:\n console.warn(`[BridgeFactory] 현재 플랫폼(${platform})에서는 Bridge 객체를 생성할 수 없습니다.`);\n\n return new CommonBridge();\n }\n }\n}\n","import { NativeBridge } from './native-bridge';\nimport { PortalBridge } from './portal-bridge';\nimport { CommonBridge } from './common-bridge';\nimport { BridgeFactory } from './factory/bridge-factory';\n\nexport class Bridge {\n private static instance: NativeBridge | PortalBridge | CommonBridge;\n\n static getInstance() {\n if (!this.instance) {\n this.instance = BridgeFactory.create();\n }\n return this.instance;\n }\n\n // 플랫폼별 접근자들만 제공\n static getCommonBridge(): CommonBridge {\n return this.getInstance();\n }\n\n static getNativeBridge(): NativeBridge | null {\n const instance = this.getInstance();\n return instance instanceof NativeBridge ? instance : null;\n }\n\n static getPortalBridge(): PortalBridge | null {\n const instance = this.getInstance();\n return instance instanceof PortalBridge ? instance : null;\n }\n\n // 플랫폼 체크\n static isNativePlatform(): boolean {\n return this.getInstance() instanceof NativeBridge;\n }\n\n static isPortalPlatform(): boolean {\n return this.getInstance() instanceof PortalBridge;\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sales-frontend-bridge",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -24,14 +24,15 @@
|
|
|
24
24
|
"@types/node": "^22.14.0",
|
|
25
25
|
"tsup": "^8.4.0",
|
|
26
26
|
"typescript": "5.8.2",
|
|
27
|
-
"sales-frontend-eslint-config-v8": "^0.0.
|
|
28
|
-
"sales-frontend-typescript-config": "0.0.
|
|
27
|
+
"eslint-config-sales-frontend-eslint-config-v8": "^0.0.4",
|
|
28
|
+
"sales-frontend-typescript-config": "0.0.1"
|
|
29
29
|
},
|
|
30
30
|
"scripts": {
|
|
31
31
|
"lint": "eslint . --max-warnings 0",
|
|
32
32
|
"generate:component": "turbo gen react-component",
|
|
33
33
|
"check-types": "tsc --noEmit",
|
|
34
34
|
"storybook": "tsup --watch",
|
|
35
|
-
"build": "tsup"
|
|
35
|
+
"build": "tsup",
|
|
36
|
+
"release": "pnpm publish"
|
|
36
37
|
}
|
|
37
38
|
}
|