@vqh2602/mini-app-sdk 1.0.6 → 1.0.8
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/README.md +13 -0
- package/bin/simulator.js +36 -6
- package/dist/cli/commands/create.js +1 -1
- package/dist/cli/commands/dev.d.ts +1 -0
- package/dist/cli/commands/dev.d.ts.map +1 -1
- package/dist/cli/commands/dev.js +3 -2
- package/dist/cli/commands/dev.js.map +1 -1
- package/dist/cli/commands/simulator.d.ts +1 -0
- package/dist/cli/commands/simulator.d.ts.map +1 -1
- package/dist/cli/commands/simulator.js +3 -2
- package/dist/cli/commands/simulator.js.map +1 -1
- package/dist/cli/commands/upload.d.ts +3 -0
- package/dist/cli/commands/upload.d.ts.map +1 -1
- package/dist/cli/commands/upload.js +45 -27
- package/dist/cli/commands/upload.js.map +1 -1
- package/dist/cli/index.js +5 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/utils/auth.d.ts +34 -0
- package/dist/cli/utils/auth.d.ts.map +1 -0
- package/dist/cli/utils/auth.js +99 -0
- package/dist/cli/utils/auth.js.map +1 -0
- package/dist/cli/utils/server.d.ts +15 -1
- package/dist/cli/utils/server.d.ts.map +1 -1
- package/dist/cli/utils/server.js +71 -7
- package/dist/cli/utils/server.js.map +1 -1
- package/dist/core/client.d.ts +148 -16
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/client.js +113 -53
- package/dist/core/client.js.map +1 -1
- package/dist/core/index.d.ts +10 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +10 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/modules/auth.d.ts +64 -4
- package/dist/core/modules/auth.d.ts.map +1 -1
- package/dist/core/modules/auth.js +205 -2
- package/dist/core/modules/auth.js.map +1 -1
- package/dist/core/modules/debug.d.ts +14 -0
- package/dist/core/modules/debug.d.ts.map +1 -0
- package/dist/core/modules/debug.js +19 -0
- package/dist/core/modules/debug.js.map +1 -0
- package/dist/core/modules/device.d.ts +4 -1
- package/dist/core/modules/device.d.ts.map +1 -1
- package/dist/core/modules/device.js +4 -1
- package/dist/core/modules/device.js.map +1 -1
- package/dist/core/modules/file.d.ts +38 -0
- package/dist/core/modules/file.d.ts.map +1 -0
- package/dist/core/modules/file.js +25 -0
- package/dist/core/modules/file.js.map +1 -0
- package/dist/core/modules/lifecycle.d.ts +23 -0
- package/dist/core/modules/lifecycle.d.ts.map +1 -1
- package/dist/core/modules/lifecycle.js +30 -0
- package/dist/core/modules/lifecycle.js.map +1 -1
- package/dist/core/modules/media.d.ts +65 -0
- package/dist/core/modules/media.d.ts.map +1 -1
- package/dist/core/modules/media.js +36 -0
- package/dist/core/modules/media.js.map +1 -1
- package/dist/core/modules/navigation.d.ts +3 -3
- package/dist/core/modules/navigation.d.ts.map +1 -1
- package/dist/core/modules/navigation.js +3 -3
- package/dist/core/modules/navigation.js.map +1 -1
- package/dist/core/modules/payment.d.ts +39 -0
- package/dist/core/modules/payment.d.ts.map +1 -0
- package/dist/core/modules/payment.js +25 -0
- package/dist/core/modules/payment.js.map +1 -0
- package/dist/core/modules/permissions.d.ts +28 -0
- package/dist/core/modules/permissions.d.ts.map +1 -0
- package/dist/core/modules/permissions.js +31 -0
- package/dist/core/modules/permissions.js.map +1 -0
- package/dist/core/modules/phone.d.ts +22 -0
- package/dist/core/modules/phone.d.ts.map +1 -0
- package/dist/core/modules/phone.js +31 -0
- package/dist/core/modules/phone.js.map +1 -0
- package/dist/core/modules/storage.d.ts +88 -4
- package/dist/core/modules/storage.d.ts.map +1 -1
- package/dist/core/modules/storage.js +78 -13
- package/dist/core/modules/storage.js.map +1 -1
- package/dist/core/modules/system.d.ts +67 -0
- package/dist/core/modules/system.d.ts.map +1 -0
- package/dist/core/modules/system.js +55 -0
- package/dist/core/modules/system.js.map +1 -0
- package/dist/core/modules/ui.d.ts +40 -9
- package/dist/core/modules/ui.d.ts.map +1 -1
- package/dist/core/modules/ui.js +45 -11
- package/dist/core/modules/ui.js.map +1 -1
- package/dist/core/modules/user.d.ts +18 -0
- package/dist/core/modules/user.d.ts.map +1 -0
- package/dist/core/modules/user.js +19 -0
- package/dist/core/modules/user.js.map +1 -0
- package/dist/core/modules/utility.d.ts +23 -0
- package/dist/core/modules/utility.d.ts.map +1 -0
- package/dist/core/modules/utility.js +19 -0
- package/dist/core/modules/utility.js.map +1 -0
- package/dist/core/types/index.d.ts +66 -8
- package/dist/core/types/index.d.ts.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/mock/index.d.ts +0 -6
- package/dist/mock/index.d.ts.map +1 -1
- package/dist/mock/index.js +0 -6
- package/dist/mock/index.js.map +1 -1
- package/dist/mock/mock-engine.d.ts +6 -25
- package/dist/mock/mock-engine.d.ts.map +1 -1
- package/dist/mock/mock-engine.js +8 -325
- package/dist/mock/mock-engine.js.map +1 -1
- package/dist/mock/presets.d.ts +2 -2
- package/dist/mock/presets.d.ts.map +1 -1
- package/dist/mock/presets.js +2 -42
- package/dist/mock/presets.js.map +1 -1
- package/dist/mock/store.d.ts +2 -33
- package/dist/mock/store.d.ts.map +1 -1
- package/dist/mock/store.js +2 -130
- package/dist/mock/store.js.map +1 -1
- package/dist/transport/adaptive-transport.d.ts +2 -0
- package/dist/transport/adaptive-transport.d.ts.map +1 -1
- package/dist/transport/adaptive-transport.js +11 -3
- package/dist/transport/adaptive-transport.js.map +1 -1
- package/dist/transport/bridge-hub.d.ts +46 -0
- package/dist/transport/bridge-hub.d.ts.map +1 -0
- package/dist/transport/bridge-hub.js +268 -0
- package/dist/transport/bridge-hub.js.map +1 -0
- package/dist/transport/index.d.ts +1 -0
- package/dist/transport/index.d.ts.map +1 -1
- package/dist/transport/index.js +1 -0
- package/dist/transport/index.js.map +1 -1
- package/dist/transport/mock-transport.d.ts +2 -0
- package/dist/transport/mock-transport.d.ts.map +1 -1
- package/dist/transport/mock-transport.js +6 -0
- package/dist/transport/mock-transport.js.map +1 -1
- package/dist/transport/native-transport.d.ts +7 -6
- package/dist/transport/native-transport.d.ts.map +1 -1
- package/dist/transport/native-transport.js +49 -122
- package/dist/transport/native-transport.js.map +1 -1
- package/dist/transport/postmessage-transport.d.ts +9 -1
- package/dist/transport/postmessage-transport.d.ts.map +1 -1
- package/dist/transport/postmessage-transport.js +216 -14
- package/dist/transport/postmessage-transport.js.map +1 -1
- package/dist/transport/timeout-policy.d.ts +5 -0
- package/dist/transport/timeout-policy.d.ts.map +1 -0
- package/dist/transport/timeout-policy.js +21 -0
- package/dist/transport/timeout-policy.js.map +1 -0
- package/dist/transport/transport.interface.d.ts +2 -0
- package/dist/transport/transport.interface.d.ts.map +1 -1
- package/dist/transport/types.d.ts +4 -1
- package/dist/transport/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/simulator-dist/assets/index-DkSKbR3O.js +120 -0
- package/simulator-dist/index.html +1 -1
- package/dist/mock/handlers/auth.handler.d.ts +0 -24
- package/dist/mock/handlers/auth.handler.d.ts.map +0 -1
- package/dist/mock/handlers/auth.handler.js +0 -106
- package/dist/mock/handlers/auth.handler.js.map +0 -1
- package/dist/mock/handlers/device.handler.d.ts +0 -16
- package/dist/mock/handlers/device.handler.d.ts.map +0 -1
- package/dist/mock/handlers/device.handler.js +0 -53
- package/dist/mock/handlers/device.handler.js.map +0 -1
- package/dist/mock/handlers/media.handler.d.ts +0 -9
- package/dist/mock/handlers/media.handler.d.ts.map +0 -1
- package/dist/mock/handlers/media.handler.js +0 -20
- package/dist/mock/handlers/media.handler.js.map +0 -1
- package/dist/mock/handlers/payment.handler.d.ts +0 -27
- package/dist/mock/handlers/payment.handler.d.ts.map +0 -1
- package/dist/mock/handlers/payment.handler.js +0 -62
- package/dist/mock/handlers/payment.handler.js.map +0 -1
- package/dist/mock/handlers/storage.handler.d.ts +0 -18
- package/dist/mock/handlers/storage.handler.d.ts.map +0 -1
- package/dist/mock/handlers/storage.handler.js +0 -40
- package/dist/mock/handlers/storage.handler.js.map +0 -1
- package/dist/mock/handlers/ui.handler.d.ts +0 -34
- package/dist/mock/handlers/ui.handler.d.ts.map +0 -1
- package/dist/mock/handlers/ui.handler.js +0 -59
- package/dist/mock/handlers/ui.handler.js.map +0 -1
- package/simulator-dist/assets/index-DpHZwm7N.js +0 -199
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native-transport.d.ts","sourceRoot":"","sources":["../../src/transport/native-transport.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"native-transport.d.ts","sourceRoot":"","sources":["../../src/transport/native-transport.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAe,mBAAmB,EAAqD,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAKjJ,wBAAgB,uBAAuB,IAAI,OAAO,CAMjD;AAED,qBAAa,qBAAsB,YAAW,UAAU;IACtD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,gBAAgB,CAAC,CAAS;IAClC,OAAO,CAAC,KAAK,CAAU;IACvB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,GAAG,CAAY;gBAEX,MAAM,GAAE,eAAoB;IASjC,OAAO,IAAI,aAAa;IAIxB,WAAW,IAAI,OAAO;IAItB,cAAc,IAAI,MAAM;IAIxB,MAAM,CAAC,CAAC,GAAG,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IA2FlG,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,mBAAmB,GAAG,MAAM,IAAI;IAI5D,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,mBAAmB,GAAG,IAAI;IAIvD,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,IAAI;IAOvC,OAAO,IAAI,IAAI;IAgBf,OAAO,IAAI,IAAI;CAGvB"}
|
|
@@ -1,26 +1,29 @@
|
|
|
1
|
+
import { BridgeHub, isForwardingShim } from './bridge-hub.js';
|
|
2
|
+
import { bridgeTimeoutMs } from './timeout-policy.js';
|
|
1
3
|
let requestSequence = 1;
|
|
2
|
-
|
|
3
|
-
const forwardingShims = new WeakSet();
|
|
4
|
+
let transportSequence = 1;
|
|
4
5
|
export function isNativeBridgeAvailable() {
|
|
5
6
|
if (typeof window === 'undefined')
|
|
6
7
|
return false;
|
|
7
8
|
const win = window;
|
|
8
9
|
const send = win.SuperAppBridge?.postMessage;
|
|
9
10
|
return typeof win.FlutterBridge?.postMessage === 'function' ||
|
|
10
|
-
(typeof send === 'function' && !
|
|
11
|
+
(typeof send === 'function' && !isForwardingShim(send));
|
|
11
12
|
}
|
|
12
13
|
export class NativeBridgeTransport {
|
|
13
|
-
|
|
14
|
+
transportId;
|
|
14
15
|
appId;
|
|
15
16
|
defaultTimeoutMs;
|
|
16
17
|
debug;
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
isDestroyed = false;
|
|
19
|
+
hub;
|
|
19
20
|
constructor(config = {}) {
|
|
21
|
+
this.transportId = `native_trans_${Date.now()}_${transportSequence++}`;
|
|
20
22
|
this.appId = config.appId || 'mini_app_default';
|
|
21
|
-
this.defaultTimeoutMs = config.timeoutMs
|
|
23
|
+
this.defaultTimeoutMs = config.timeoutMs;
|
|
22
24
|
this.debug = config.debug ?? false;
|
|
23
|
-
this.
|
|
25
|
+
this.hub = BridgeHub.getShared();
|
|
26
|
+
this.hub.installOnGlobalBridge();
|
|
24
27
|
}
|
|
25
28
|
getType() {
|
|
26
29
|
return 'native';
|
|
@@ -28,94 +31,18 @@ export class NativeBridgeTransport {
|
|
|
28
31
|
isConnected() {
|
|
29
32
|
return isNativeBridgeAvailable();
|
|
30
33
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return;
|
|
34
|
-
const win = window;
|
|
35
|
-
if (!win.SuperAppBridge) {
|
|
36
|
-
// Keep the shared callback/listener contract used by the Flutter host and
|
|
37
|
-
// plain JS clients, even when this SDK is the first script to initialize.
|
|
38
|
-
win.SuperAppBridge = {};
|
|
39
|
-
}
|
|
40
|
-
const bridge = win.SuperAppBridge;
|
|
41
|
-
bridge._callbacks ||= {};
|
|
42
|
-
bridge._listeners ||= {};
|
|
43
|
-
if (!bridge.postMessage) {
|
|
44
|
-
bridge.postMessage = (msg) => {
|
|
45
|
-
win.FlutterBridge?.postMessage(typeof msg === 'string' ? msg : JSON.stringify(msg));
|
|
46
|
-
};
|
|
47
|
-
forwardingShims.add(bridge.postMessage);
|
|
48
|
-
}
|
|
49
|
-
if (!bridge.dispatchResponse) {
|
|
50
|
-
bridge.dispatchResponse = (res) => {
|
|
51
|
-
const callback = bridge._callbacks[res.id];
|
|
52
|
-
if (callback) {
|
|
53
|
-
delete bridge._callbacks[res.id];
|
|
54
|
-
callback(res);
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
if (!bridge.dispatchEvent) {
|
|
59
|
-
bridge.dispatchEvent = (evt) => {
|
|
60
|
-
for (const listener of [...(bridge._listeners[evt.event] || [])]) {
|
|
61
|
-
try {
|
|
62
|
-
listener(evt.payload);
|
|
63
|
-
}
|
|
64
|
-
catch (error) {
|
|
65
|
-
console.error(error);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
bridge.addEventListener ||= (event, handler) => {
|
|
71
|
-
(bridge._listeners[event] ||= []).push(handler);
|
|
72
|
-
};
|
|
73
|
-
bridge.removeEventListener ||= (event, handler) => {
|
|
74
|
-
bridge._listeners[event] = (bridge._listeners[event] || []).filter(fn => fn !== handler);
|
|
75
|
-
};
|
|
76
|
-
// Install once per bridge object, rather than stacking new wrappers per call.
|
|
77
|
-
// Also reconnect if a host replaces the bridge after SDK initialization.
|
|
78
|
-
if (this.installedBridges.has(bridge))
|
|
79
|
-
return;
|
|
80
|
-
this.installedBridges.add(bridge);
|
|
81
|
-
const previousResponse = bridge.dispatchResponse;
|
|
82
|
-
bridge.dispatchResponse = (res) => {
|
|
83
|
-
this.handleNativeResponse(res);
|
|
84
|
-
previousResponse.call(bridge, res);
|
|
85
|
-
};
|
|
86
|
-
const previousEvent = bridge.dispatchEvent;
|
|
87
|
-
bridge.dispatchEvent = (evt) => {
|
|
88
|
-
this.emit(evt.event, evt.payload);
|
|
89
|
-
previousEvent.call(bridge, evt);
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
handleNativeResponse(res) {
|
|
93
|
-
if (!res || !res.id)
|
|
94
|
-
return;
|
|
95
|
-
if (this.debug) {
|
|
96
|
-
console.log(`[NativeBridgeTransport] Response received:`, res);
|
|
97
|
-
}
|
|
98
|
-
const pending = this.callbacks.get(res.id);
|
|
99
|
-
if (!pending)
|
|
100
|
-
return;
|
|
101
|
-
clearTimeout(pending.timer);
|
|
102
|
-
this.callbacks.delete(res.id);
|
|
103
|
-
if (typeof window !== 'undefined') {
|
|
104
|
-
const win = window;
|
|
105
|
-
if (win.SuperAppBridge?._callbacks) {
|
|
106
|
-
delete win.SuperAppBridge._callbacks[res.id];
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
if (res.success) {
|
|
110
|
-
pending.resolve(res.data);
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
pending.reject(res.error || { code: 'UNKNOWN_ERROR', message: 'Operation failed without error payload' });
|
|
114
|
-
}
|
|
34
|
+
getTransportId() {
|
|
35
|
+
return this.transportId;
|
|
115
36
|
}
|
|
116
37
|
invoke(action, payload = {}, timeoutMs) {
|
|
38
|
+
if (this.isDestroyed) {
|
|
39
|
+
return Promise.reject({
|
|
40
|
+
code: 'TRANSPORT_DESTROYED',
|
|
41
|
+
message: 'NativeBridgeTransport has been destroyed and cannot invoke actions',
|
|
42
|
+
});
|
|
43
|
+
}
|
|
117
44
|
const id = `sdk_req_${Date.now()}_${requestSequence++}`;
|
|
118
|
-
const timeout = timeoutMs ?? this.defaultTimeoutMs;
|
|
45
|
+
const timeout = bridgeTimeoutMs(action, timeoutMs ?? this.defaultTimeoutMs);
|
|
119
46
|
const request = {
|
|
120
47
|
id,
|
|
121
48
|
action,
|
|
@@ -125,9 +52,9 @@ export class NativeBridgeTransport {
|
|
|
125
52
|
timestamp: Date.now(),
|
|
126
53
|
};
|
|
127
54
|
return new Promise((resolve, reject) => {
|
|
128
|
-
this.
|
|
55
|
+
this.hub.installOnGlobalBridge();
|
|
129
56
|
const timer = setTimeout(() => {
|
|
130
|
-
this.
|
|
57
|
+
this.hub.unregisterCallback(id);
|
|
131
58
|
if (typeof window !== 'undefined') {
|
|
132
59
|
const win = window;
|
|
133
60
|
if (win.SuperAppBridge?._callbacks) {
|
|
@@ -143,7 +70,14 @@ export class NativeBridgeTransport {
|
|
|
143
70
|
}
|
|
144
71
|
reject(timeoutError);
|
|
145
72
|
}, timeout);
|
|
146
|
-
this.
|
|
73
|
+
this.hub.registerCallback(id, {
|
|
74
|
+
transportId: this.transportId,
|
|
75
|
+
action,
|
|
76
|
+
resolve,
|
|
77
|
+
reject,
|
|
78
|
+
timer,
|
|
79
|
+
createdAt: Date.now(),
|
|
80
|
+
});
|
|
147
81
|
if (this.debug) {
|
|
148
82
|
console.log(`[NativeBridgeTransport] Invoking ${action}:`, request);
|
|
149
83
|
}
|
|
@@ -153,7 +87,7 @@ export class NativeBridgeTransport {
|
|
|
153
87
|
if (win.SuperAppBridge) {
|
|
154
88
|
win.SuperAppBridge._callbacks = win.SuperAppBridge._callbacks || {};
|
|
155
89
|
win.SuperAppBridge._callbacks[id] = (res) => {
|
|
156
|
-
this.
|
|
90
|
+
this.hub.dispatchResponse(res);
|
|
157
91
|
};
|
|
158
92
|
}
|
|
159
93
|
if (win.FlutterBridge?.postMessage) {
|
|
@@ -164,7 +98,7 @@ export class NativeBridgeTransport {
|
|
|
164
98
|
}
|
|
165
99
|
else {
|
|
166
100
|
clearTimeout(timer);
|
|
167
|
-
this.
|
|
101
|
+
this.hub.unregisterCallback(id);
|
|
168
102
|
if (win.SuperAppBridge?._callbacks) {
|
|
169
103
|
delete win.SuperAppBridge._callbacks[id];
|
|
170
104
|
}
|
|
@@ -176,7 +110,7 @@ export class NativeBridgeTransport {
|
|
|
176
110
|
}
|
|
177
111
|
else {
|
|
178
112
|
clearTimeout(timer);
|
|
179
|
-
this.
|
|
113
|
+
this.hub.unregisterCallback(id);
|
|
180
114
|
reject({
|
|
181
115
|
code: 'ENVIRONMENT_ERROR',
|
|
182
116
|
message: 'Cannot invoke native bridge in a non-browser environment',
|
|
@@ -185,36 +119,29 @@ export class NativeBridgeTransport {
|
|
|
185
119
|
});
|
|
186
120
|
}
|
|
187
121
|
on(event, listener) {
|
|
188
|
-
|
|
189
|
-
this.listeners.set(event, new Set());
|
|
190
|
-
}
|
|
191
|
-
this.listeners.get(event).add(listener);
|
|
192
|
-
return () => this.off(event, listener);
|
|
122
|
+
return this.hub.addListener(this.transportId, event, listener);
|
|
193
123
|
}
|
|
194
124
|
off(event, listener) {
|
|
195
|
-
|
|
196
|
-
if (set) {
|
|
197
|
-
set.delete(listener);
|
|
198
|
-
if (set.size === 0) {
|
|
199
|
-
this.listeners.delete(event);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
125
|
+
this.hub.removeListener(this.transportId, event, listener);
|
|
202
126
|
}
|
|
203
127
|
emit(event, payload) {
|
|
204
128
|
if (this.debug) {
|
|
205
|
-
console.log(`[NativeBridgeTransport]
|
|
129
|
+
console.log(`[NativeBridgeTransport] Emitting event [${event}]:`, payload);
|
|
206
130
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
});
|
|
131
|
+
this.hub.dispatchEvent({ event, payload });
|
|
132
|
+
}
|
|
133
|
+
destroy() {
|
|
134
|
+
if (this.isDestroyed)
|
|
135
|
+
return;
|
|
136
|
+
this.isDestroyed = true;
|
|
137
|
+
this.hub.cancelPendingRequestsForTransport(this.transportId, 'ABORTED', 'NativeBridgeTransport was destroyed before request completed');
|
|
138
|
+
this.hub.removeListenersForTransport(this.transportId);
|
|
139
|
+
if (this.debug) {
|
|
140
|
+
console.log(`[NativeBridgeTransport] Transport ${this.transportId} destroyed.`);
|
|
217
141
|
}
|
|
218
142
|
}
|
|
143
|
+
dispose() {
|
|
144
|
+
this.destroy();
|
|
145
|
+
}
|
|
219
146
|
}
|
|
220
147
|
//# sourceMappingURL=native-transport.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native-transport.js","sourceRoot":"","sources":["../../src/transport/native-transport.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"native-transport.js","sourceRoot":"","sources":["../../src/transport/native-transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,19 +2,27 @@ import { ITransport } from './transport.interface.js';
|
|
|
2
2
|
import { BridgeEventListener, TransportConfig, TransportType } from './types.js';
|
|
3
3
|
export declare class PostMessageTransport implements ITransport {
|
|
4
4
|
private appId;
|
|
5
|
-
private defaultTimeoutMs
|
|
5
|
+
private defaultTimeoutMs?;
|
|
6
6
|
private debug;
|
|
7
|
+
private trustedHostOrigin?;
|
|
7
8
|
private callbacks;
|
|
8
9
|
private listeners;
|
|
9
10
|
private messageListener?;
|
|
10
11
|
constructor(config?: TransportConfig);
|
|
11
12
|
getType(): TransportType;
|
|
12
13
|
isConnected(): boolean;
|
|
14
|
+
getTrustedHostOrigin(): string | undefined;
|
|
15
|
+
setTrustedHostOrigin(origin: string): void;
|
|
16
|
+
isValidHostOrigin(origin: string): boolean;
|
|
17
|
+
private resolveAutoDetectedHostOrigin;
|
|
18
|
+
getTargetOrigin(): string;
|
|
19
|
+
private initHandshake;
|
|
13
20
|
private initMessageListener;
|
|
14
21
|
invoke<T = any>(action: string, payload?: Record<string, any>, timeoutMs?: number): Promise<T>;
|
|
15
22
|
on(event: string, listener: BridgeEventListener): () => void;
|
|
16
23
|
off(event: string, listener: BridgeEventListener): void;
|
|
17
24
|
emit(event: string, payload: any): void;
|
|
18
25
|
destroy(): void;
|
|
26
|
+
dispose(): void;
|
|
19
27
|
}
|
|
20
28
|
//# sourceMappingURL=postmessage-transport.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postmessage-transport.d.ts","sourceRoot":"","sources":["../../src/transport/postmessage-transport.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"postmessage-transport.d.ts","sourceRoot":"","sources":["../../src/transport/postmessage-transport.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAe,mBAAmB,EAAiC,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAI7H,qBAAa,oBAAqB,YAAW,UAAU;IACrD,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,gBAAgB,CAAC,CAAS;IAClC,OAAO,CAAC,KAAK,CAAU;IACvB,OAAO,CAAC,iBAAiB,CAAC,CAAS;IACnC,OAAO,CAAC,SAAS,CAUH;IACd,OAAO,CAAC,SAAS,CAAoD;IACrE,OAAO,CAAC,eAAe,CAAC,CAAgC;gBAE5C,MAAM,GAAE,eAAoB;IASjC,OAAO,IAAI,aAAa;IAIxB,WAAW,IAAI,OAAO;IAItB,oBAAoB,IAAI,MAAM,GAAG,SAAS;IAI1C,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAO1C,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAsBjD,OAAO,CAAC,6BAA6B;IAkD9B,eAAe,IAAI,MAAM;IA0BhC,OAAO,CAAC,aAAa;IAiBrB,OAAO,CAAC,mBAAmB;IAuGpB,MAAM,CAAC,CAAC,GAAG,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAyDlG,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,mBAAmB,GAAG,MAAM,IAAI;IAQ5D,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,mBAAmB,GAAG,IAAI;IAUvD,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,IAAI;IAavC,OAAO,IAAI,IAAI;IAiBf,OAAO,IAAI,IAAI;CAGvB"}
|
|
@@ -1,16 +1,20 @@
|
|
|
1
|
+
import { bridgeTimeoutMs } from './timeout-policy.js';
|
|
1
2
|
let requestSequence = 1;
|
|
2
3
|
export class PostMessageTransport {
|
|
3
4
|
appId;
|
|
4
5
|
defaultTimeoutMs;
|
|
5
6
|
debug;
|
|
7
|
+
trustedHostOrigin;
|
|
6
8
|
callbacks = new Map();
|
|
7
9
|
listeners = new Map();
|
|
8
10
|
messageListener;
|
|
9
11
|
constructor(config = {}) {
|
|
10
12
|
this.appId = config.appId || 'mini_app_simulator';
|
|
11
|
-
this.defaultTimeoutMs = config.timeoutMs
|
|
13
|
+
this.defaultTimeoutMs = config.timeoutMs;
|
|
12
14
|
this.debug = config.debug ?? false;
|
|
15
|
+
this.trustedHostOrigin = config.trustedHostOrigin || this.resolveAutoDetectedHostOrigin();
|
|
13
16
|
this.initMessageListener();
|
|
17
|
+
this.initHandshake();
|
|
14
18
|
}
|
|
15
19
|
getType() {
|
|
16
20
|
return 'postmessage';
|
|
@@ -18,31 +22,206 @@ export class PostMessageTransport {
|
|
|
18
22
|
isConnected() {
|
|
19
23
|
return typeof window !== 'undefined' && window.parent !== window;
|
|
20
24
|
}
|
|
25
|
+
getTrustedHostOrigin() {
|
|
26
|
+
return this.trustedHostOrigin;
|
|
27
|
+
}
|
|
28
|
+
setTrustedHostOrigin(origin) {
|
|
29
|
+
if (!this.isValidHostOrigin(origin) && origin !== '*') {
|
|
30
|
+
throw new Error(`[PostMessageTransport] Invalid host origin: "${origin}". Must be a valid HTTP localhost or HTTPS origin.`);
|
|
31
|
+
}
|
|
32
|
+
this.trustedHostOrigin = origin;
|
|
33
|
+
}
|
|
34
|
+
isValidHostOrigin(origin) {
|
|
35
|
+
if (!origin || typeof origin !== 'string')
|
|
36
|
+
return false;
|
|
37
|
+
try {
|
|
38
|
+
const url = new URL(origin);
|
|
39
|
+
if (url.protocol !== 'http:' && url.protocol !== 'https:') {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
// In development, localhost and 127.0.0.1 or local domains are allowed
|
|
43
|
+
if (url.hostname === 'localhost' ||
|
|
44
|
+
url.hostname === '127.0.0.1' ||
|
|
45
|
+
url.hostname.endsWith('.localhost')) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
// For remote hosts, HTTPS is required
|
|
49
|
+
return url.protocol === 'https:';
|
|
50
|
+
}
|
|
51
|
+
catch (_) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
resolveAutoDetectedHostOrigin() {
|
|
56
|
+
if (typeof window === 'undefined')
|
|
57
|
+
return undefined;
|
|
58
|
+
const win = window;
|
|
59
|
+
// 1. Explicit global injection by host container
|
|
60
|
+
if (win.__SUPERAPP_TRUSTED_HOST_ORIGIN__) {
|
|
61
|
+
return win.__SUPERAPP_TRUSTED_HOST_ORIGIN__;
|
|
62
|
+
}
|
|
63
|
+
if (win.__SUPERAPP_HOST_ORIGIN__) {
|
|
64
|
+
return win.__SUPERAPP_HOST_ORIGIN__;
|
|
65
|
+
}
|
|
66
|
+
// 2. Query param ?hostOrigin=... or ?trustedHostOrigin=...
|
|
67
|
+
try {
|
|
68
|
+
if (win.location?.search) {
|
|
69
|
+
const params = new URLSearchParams(win.location.search);
|
|
70
|
+
const fromParam = params.get('trustedHostOrigin') || params.get('hostOrigin');
|
|
71
|
+
if (fromParam) {
|
|
72
|
+
const parsed = new URL(fromParam).origin;
|
|
73
|
+
if (this.isValidHostOrigin(parsed)) {
|
|
74
|
+
return parsed;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch (_) { }
|
|
80
|
+
// 3. window.location.ancestorOrigins (Chromium & WebKit)
|
|
81
|
+
try {
|
|
82
|
+
if (win.location?.ancestorOrigins && win.location.ancestorOrigins.length > 0) {
|
|
83
|
+
const ancestor = win.location.ancestorOrigins[0];
|
|
84
|
+
if (ancestor && ancestor !== 'null' && this.isValidHostOrigin(ancestor)) {
|
|
85
|
+
return ancestor;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch (_) { }
|
|
90
|
+
// 4. document.referrer
|
|
91
|
+
try {
|
|
92
|
+
if (typeof document !== 'undefined' && document.referrer) {
|
|
93
|
+
const referrerOrigin = new URL(document.referrer).origin;
|
|
94
|
+
if (referrerOrigin && referrerOrigin !== 'null' && this.isValidHostOrigin(referrerOrigin)) {
|
|
95
|
+
return referrerOrigin;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch (_) { }
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
getTargetOrigin() {
|
|
103
|
+
if (this.trustedHostOrigin && this.trustedHostOrigin !== '*') {
|
|
104
|
+
return this.trustedHostOrigin;
|
|
105
|
+
}
|
|
106
|
+
const detected = this.resolveAutoDetectedHostOrigin();
|
|
107
|
+
if (detected) {
|
|
108
|
+
this.trustedHostOrigin = detected;
|
|
109
|
+
return detected;
|
|
110
|
+
}
|
|
111
|
+
if (typeof window !== 'undefined' && window.location?.origin && window.location.origin !== 'null') {
|
|
112
|
+
try {
|
|
113
|
+
const url = new URL(window.location.origin);
|
|
114
|
+
if (url.hostname === 'localhost' || url.hostname === '127.0.0.1') {
|
|
115
|
+
return window.location.origin;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch (_) { }
|
|
119
|
+
}
|
|
120
|
+
if (this.debug) {
|
|
121
|
+
console.warn('[PostMessageTransport] Warning: No trustedHostOrigin configured. Using fallback target origin.');
|
|
122
|
+
}
|
|
123
|
+
return '*';
|
|
124
|
+
}
|
|
125
|
+
initHandshake() {
|
|
126
|
+
if (typeof window === 'undefined' || !window.parent || window.parent === window)
|
|
127
|
+
return;
|
|
128
|
+
try {
|
|
129
|
+
const target = this.trustedHostOrigin || '*';
|
|
130
|
+
window.parent.postMessage({
|
|
131
|
+
type: 'SUPERAPP_BRIDGE_HANDSHAKE',
|
|
132
|
+
appId: this.appId,
|
|
133
|
+
clientOrigin: window.location?.origin,
|
|
134
|
+
timestamp: Date.now(),
|
|
135
|
+
}, target);
|
|
136
|
+
}
|
|
137
|
+
catch (_) { }
|
|
138
|
+
}
|
|
21
139
|
initMessageListener() {
|
|
22
140
|
if (typeof window === 'undefined')
|
|
23
141
|
return;
|
|
24
142
|
this.messageListener = (event) => {
|
|
143
|
+
// 1. Verify event source is parent window
|
|
144
|
+
if (typeof window !== 'undefined' && window.parent) {
|
|
145
|
+
if (event.source && event.source !== window.parent) {
|
|
146
|
+
if (this.debug) {
|
|
147
|
+
console.warn('[PostMessageTransport] Rejected message: event.source !== window.parent');
|
|
148
|
+
}
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// 2. Verify event origin against trustedHostOrigin
|
|
153
|
+
if (this.trustedHostOrigin && this.trustedHostOrigin !== '*') {
|
|
154
|
+
if (event.origin && event.origin !== this.trustedHostOrigin) {
|
|
155
|
+
if (this.debug) {
|
|
156
|
+
console.warn(`[PostMessageTransport] Rejected message from untrusted origin: "${event.origin}". Expected: "${this.trustedHostOrigin}"`);
|
|
157
|
+
}
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
25
161
|
const data = event.data;
|
|
26
162
|
if (!data || typeof data !== 'object')
|
|
27
163
|
return;
|
|
164
|
+
// Handle handshake messages
|
|
165
|
+
if (data.type === 'SUPERAPP_SIMULATOR_HANDSHAKE' || data.type === 'SUPERAPP_SIMULATOR_HANDSHAKE_ACK') {
|
|
166
|
+
const hostOrigin = data.hostOrigin || event.origin;
|
|
167
|
+
if (hostOrigin && this.isValidHostOrigin(hostOrigin)) {
|
|
168
|
+
if (!this.trustedHostOrigin) {
|
|
169
|
+
this.trustedHostOrigin = hostOrigin;
|
|
170
|
+
if (this.debug) {
|
|
171
|
+
console.log(`[PostMessageTransport] Handshake established with host origin: ${this.trustedHostOrigin}`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
28
177
|
if (data.type === 'SUPERAPP_BRIDGE_RESPONSE') {
|
|
29
178
|
const res = data.response;
|
|
30
179
|
if (!res || !res.id)
|
|
31
180
|
return;
|
|
32
181
|
const pending = this.callbacks.get(res.id);
|
|
33
|
-
if (pending) {
|
|
34
|
-
clearTimeout(pending.timer);
|
|
35
|
-
this.callbacks.delete(res.id);
|
|
182
|
+
if (!pending) {
|
|
36
183
|
if (this.debug) {
|
|
37
|
-
console.
|
|
38
|
-
}
|
|
39
|
-
if (res.success) {
|
|
40
|
-
pending.resolve(res.data);
|
|
184
|
+
console.warn(`[PostMessageTransport] Response received for unknown or expired request: ${res.id}`);
|
|
41
185
|
}
|
|
42
|
-
|
|
43
|
-
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
// 3. Verify sessionNonce
|
|
189
|
+
if (pending.sessionNonce) {
|
|
190
|
+
if (!res.sessionNonce || res.sessionNonce !== pending.sessionNonce) {
|
|
191
|
+
const errorMsg = `Session nonce verification failed for request ${res.id}.`;
|
|
192
|
+
console.error(`[PostMessageTransport] Security Violation: ${errorMsg}`);
|
|
193
|
+
clearTimeout(pending.timer);
|
|
194
|
+
this.callbacks.delete(res.id);
|
|
195
|
+
pending.reject({
|
|
196
|
+
code: 'SECURITY_ERROR',
|
|
197
|
+
message: errorMsg,
|
|
198
|
+
});
|
|
199
|
+
return;
|
|
44
200
|
}
|
|
45
201
|
}
|
|
202
|
+
// 4. Verify action
|
|
203
|
+
if (res.action && pending.action && res.action !== pending.action) {
|
|
204
|
+
const errorMsg = `Action mismatch for request ${res.id}: expected "${pending.action}", received "${res.action}".`;
|
|
205
|
+
console.error(`[PostMessageTransport] Security Violation: ${errorMsg}`);
|
|
206
|
+
clearTimeout(pending.timer);
|
|
207
|
+
this.callbacks.delete(res.id);
|
|
208
|
+
pending.reject({
|
|
209
|
+
code: 'SECURITY_ERROR',
|
|
210
|
+
message: errorMsg,
|
|
211
|
+
});
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
clearTimeout(pending.timer);
|
|
215
|
+
this.callbacks.delete(res.id);
|
|
216
|
+
if (this.debug) {
|
|
217
|
+
console.log(`[PostMessageTransport] Response received:`, res);
|
|
218
|
+
}
|
|
219
|
+
if (res.success) {
|
|
220
|
+
pending.resolve(res.data);
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
pending.reject(res.error || { code: 'UNKNOWN_ERROR', message: 'Request failed in simulator' });
|
|
224
|
+
}
|
|
46
225
|
}
|
|
47
226
|
else if (data.type === 'SUPERAPP_BRIDGE_EVENT') {
|
|
48
227
|
if (data.event) {
|
|
@@ -54,14 +233,16 @@ export class PostMessageTransport {
|
|
|
54
233
|
}
|
|
55
234
|
invoke(action, payload = {}, timeoutMs) {
|
|
56
235
|
const id = `req_${Date.now()}_${requestSequence++}`;
|
|
57
|
-
const
|
|
236
|
+
const sessionNonce = `nonce_${Date.now()}_${Math.random().toString(36).substring(2, 11)}_${requestSequence}`;
|
|
237
|
+
const timeout = bridgeTimeoutMs(action, timeoutMs ?? this.defaultTimeoutMs);
|
|
58
238
|
const request = {
|
|
59
239
|
id,
|
|
60
240
|
action,
|
|
61
241
|
payload,
|
|
62
242
|
appId: this.appId,
|
|
63
|
-
origin: typeof window !== 'undefined' ? window.location
|
|
243
|
+
origin: typeof window !== 'undefined' ? window.location?.origin : 'miniapp://simulator',
|
|
64
244
|
timestamp: Date.now(),
|
|
245
|
+
sessionNonce,
|
|
65
246
|
};
|
|
66
247
|
return new Promise((resolve, reject) => {
|
|
67
248
|
const timer = setTimeout(() => {
|
|
@@ -72,15 +253,23 @@ export class PostMessageTransport {
|
|
|
72
253
|
};
|
|
73
254
|
reject(timeoutError);
|
|
74
255
|
}, timeout);
|
|
75
|
-
this.callbacks.set(id, {
|
|
256
|
+
this.callbacks.set(id, {
|
|
257
|
+
resolve,
|
|
258
|
+
reject,
|
|
259
|
+
timer,
|
|
260
|
+
action,
|
|
261
|
+
sessionNonce,
|
|
262
|
+
createdAt: Date.now(),
|
|
263
|
+
});
|
|
76
264
|
if (typeof window !== 'undefined' && window.parent) {
|
|
77
265
|
if (this.debug) {
|
|
78
266
|
console.log(`[PostMessageTransport] PostMessage out to parent:`, request);
|
|
79
267
|
}
|
|
268
|
+
const targetOrigin = this.getTargetOrigin();
|
|
80
269
|
window.parent.postMessage({
|
|
81
270
|
type: 'SUPERAPP_BRIDGE_REQUEST',
|
|
82
271
|
request,
|
|
83
|
-
},
|
|
272
|
+
}, targetOrigin);
|
|
84
273
|
}
|
|
85
274
|
else {
|
|
86
275
|
clearTimeout(timer);
|
|
@@ -122,9 +311,22 @@ export class PostMessageTransport {
|
|
|
122
311
|
}
|
|
123
312
|
}
|
|
124
313
|
destroy() {
|
|
314
|
+
for (const [id, pending] of this.callbacks.entries()) {
|
|
315
|
+
clearTimeout(pending.timer);
|
|
316
|
+
pending.reject({
|
|
317
|
+
code: 'ABORTED',
|
|
318
|
+
message: 'PostMessageTransport was destroyed',
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
this.callbacks.clear();
|
|
322
|
+
this.listeners.clear();
|
|
125
323
|
if (typeof window !== 'undefined' && this.messageListener) {
|
|
126
324
|
window.removeEventListener('message', this.messageListener);
|
|
325
|
+
this.messageListener = undefined;
|
|
127
326
|
}
|
|
128
327
|
}
|
|
328
|
+
dispose() {
|
|
329
|
+
this.destroy();
|
|
330
|
+
}
|
|
129
331
|
}
|
|
130
332
|
//# sourceMappingURL=postmessage-transport.js.map
|