@alfalab/bridge-to-native 1.4.0 → 1.4.1-beta.52a0437
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/client/bridge-to-native.d.ts +4 -1
- package/client/bridge-to-native.js +7 -4
- package/client/services-and-utils/external-links-service.d.ts +5 -1
- package/client/services-and-utils/external-links-service.js +36 -10
- package/client/services-and-utils/native-execute-service.d.ts +7 -0
- package/client/services-and-utils/native-execute-service.js +17 -0
- package/client/services-and-utils/native-navigation-and-title-service.d.ts +3 -1
- package/client/services-and-utils/native-navigation-and-title-service.js +9 -8
- package/client/services-and-utils/native-params-service.d.ts +4 -2
- package/client/services-and-utils/native-params-service.js +10 -2
- package/client/services-and-utils/utils.d.ts +2 -0
- package/client/services-and-utils/utils.js +25 -0
- package/client/types.d.ts +4 -0
- package/package.json +114 -114
- package/server/is-webview-env.js +13 -11
- package/client/services-and-utils/close-webview-util.d.ts +0 -1
- package/client/services-and-utils/close-webview-util.js +0 -11
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import { type BrowserHistoryApiWrappers, type HistoryPushStateParams, type HistoryReplaceStateParams, type LocationAssignParam, type LogError, type NativeFeatureKey, type PdfType } from './types';
|
|
2
|
+
import { type BrowserHistoryApiWrappers, type HistoryPushStateParams, type HistoryReplaceStateParams, type LocationAssignParam, type LogError, type NativeFeatureKey, type NoopOptions, type PdfType } from './types';
|
|
3
3
|
/**
|
|
4
4
|
* Сервис, предоставляет методы для WA, работающего внутри NA.
|
|
5
5
|
*/
|
|
@@ -13,12 +13,15 @@ export declare class BridgeToNative {
|
|
|
13
13
|
* будут использованы стандартные `History: pushState()` и `History: go()`.
|
|
14
14
|
* @param options.logError Функция с помощью которой B2N может залогировать ошибку,
|
|
15
15
|
* если не передать, B2N не будет логировать ошибки.
|
|
16
|
+
* @param options.noop ....
|
|
16
17
|
*/
|
|
17
18
|
constructor(options?: {
|
|
18
19
|
browserHistoryApiWrappers?: BrowserHistoryApiWrappers;
|
|
19
20
|
logError?: LogError;
|
|
21
|
+
noop?: NoopOptions;
|
|
20
22
|
} | undefined);
|
|
21
23
|
private nativeParamsService;
|
|
24
|
+
private nativeExecuteService;
|
|
22
25
|
private externalLinksService;
|
|
23
26
|
private nativeNavigationAndTitleService;
|
|
24
27
|
/**
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.BridgeToNative = void 0;
|
|
5
5
|
const external_links_service_1 = require("./services-and-utils/external-links-service");
|
|
6
|
+
const native_execute_service_1 = require("./services-and-utils/native-execute-service");
|
|
6
7
|
const native_navigation_and_title_service_1 = require("./services-and-utils/native-navigation-and-title-service");
|
|
7
8
|
const native_params_service_1 = require("./services-and-utils/native-params-service");
|
|
8
9
|
/**
|
|
@@ -17,13 +18,15 @@ class BridgeToNative {
|
|
|
17
18
|
* будут использованы стандартные `History: pushState()` и `History: go()`.
|
|
18
19
|
* @param options.logError Функция с помощью которой B2N может залогировать ошибку,
|
|
19
20
|
* если не передать, B2N не будет логировать ошибки.
|
|
21
|
+
* @param options.noop ....
|
|
20
22
|
*/
|
|
21
23
|
constructor(options) {
|
|
22
|
-
var _a, _b, _c;
|
|
24
|
+
var _a, _b, _c, _d, _e, _f;
|
|
23
25
|
this.options = options;
|
|
24
|
-
this.nativeParamsService = new native_params_service_1.NativeParamsService((_a = this.options) === null || _a === void 0 ? void 0 : _a.logError);
|
|
25
|
-
this.
|
|
26
|
-
this.
|
|
26
|
+
this.nativeParamsService = new native_params_service_1.NativeParamsService((_a = this.options) === null || _a === void 0 ? void 0 : _a.noop, (_b = this.options) === null || _b === void 0 ? void 0 : _b.logError);
|
|
27
|
+
this.nativeExecuteService = new native_execute_service_1.NativeExecuteService((_d = (_c = this.options) === null || _c === void 0 ? void 0 : _c.noop) === null || _d === void 0 ? void 0 : _d.enabled, this.nativeParamsService.environment);
|
|
28
|
+
this.externalLinksService = new external_links_service_1.ExternalLinksService(this.nativeParamsService, this.nativeExecuteService);
|
|
29
|
+
this.nativeNavigationAndTitleService = new native_navigation_and_title_service_1.NativeNavigationAndTitleService(this.nativeParamsService, this.nativeExecuteService, (_e = this.options) === null || _e === void 0 ? void 0 : _e.browserHistoryApiWrappers, (_f = this.options) === null || _f === void 0 ? void 0 : _f.logError);
|
|
27
30
|
}
|
|
28
31
|
/**
|
|
29
32
|
* Схема NA.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type PdfType } from '../types';
|
|
2
|
+
import { type NativeExecuteService } from './native-execute-service';
|
|
2
3
|
import { type NativeParamsService } from './native-params-service';
|
|
3
4
|
/**
|
|
4
5
|
* Сервис, предоставляющий методы для открытия внешних для текущего WA экранов
|
|
@@ -6,10 +7,13 @@ import { type NativeParamsService } from './native-params-service';
|
|
|
6
7
|
*/
|
|
7
8
|
export declare class ExternalLinksService {
|
|
8
9
|
private nativeParamsService;
|
|
9
|
-
|
|
10
|
+
private nativeExecuteService;
|
|
11
|
+
private navigationByNativeAppInProgress;
|
|
12
|
+
constructor(nativeParamsService: NativeParamsService, nativeExecuteService: NativeExecuteService);
|
|
10
13
|
handleNativeDeeplink(deeplink: string, closeWebviewBeforeCallNativeDeeplinkHandler?: boolean): void;
|
|
11
14
|
getHrefToOpenInBrowser(link: string): string;
|
|
12
15
|
openInBrowser(link: string): void;
|
|
13
16
|
openInNewWebview(link: string, nativeTitle?: string, closeCurrentWebview?: boolean): void;
|
|
14
17
|
openPdf(url: string, type?: PdfType, title?: string): void;
|
|
18
|
+
private navigateByNativeApp;
|
|
15
19
|
}
|
|
@@ -3,7 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ExternalLinksService = void 0;
|
|
4
4
|
const query_and_headers_keys_1 = require("../../query-and-headers-keys");
|
|
5
5
|
const constants_1 = require("../constants");
|
|
6
|
-
const
|
|
6
|
+
const utils_1 = require("./utils");
|
|
7
|
+
const CANCEL_NEW_CALLS_TO_NA_TIME = 150;
|
|
7
8
|
const QUERY_OPEN_IN_BROWSER_KEY = 'openInBrowser';
|
|
8
9
|
const QUERY_OPEN_IN_BROWSER_VALUE = 'true';
|
|
9
10
|
/**
|
|
@@ -11,20 +12,31 @@ const QUERY_OPEN_IN_BROWSER_VALUE = 'true';
|
|
|
11
12
|
* и связанных с этим действий.
|
|
12
13
|
*/
|
|
13
14
|
class ExternalLinksService {
|
|
14
|
-
constructor(nativeParamsService) {
|
|
15
|
+
constructor(nativeParamsService, nativeExecuteService) {
|
|
15
16
|
this.nativeParamsService = nativeParamsService;
|
|
17
|
+
this.nativeExecuteService = nativeExecuteService;
|
|
18
|
+
this.navigationByNativeAppInProgress = false;
|
|
16
19
|
}
|
|
17
20
|
handleNativeDeeplink(deeplink, closeWebviewBeforeCallNativeDeeplinkHandler = false) {
|
|
21
|
+
if (this.navigationByNativeAppInProgress) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
18
24
|
const clearedDeeplinkPath = deeplink.replace(constants_1.DEEP_LINK_PATTERN, '');
|
|
25
|
+
const originalNativeUrl = `${this.nativeParamsService.appId}://${clearedDeeplinkPath}`;
|
|
26
|
+
const preparedNativeUrl = this.nativeParamsService.environment === 'ios'
|
|
27
|
+
? (0, utils_1.appendFromCurrentQueryParamForIos)(originalNativeUrl)
|
|
28
|
+
: originalNativeUrl;
|
|
19
29
|
if (closeWebviewBeforeCallNativeDeeplinkHandler &&
|
|
20
30
|
this.nativeParamsService.canUseNativeFeature('savedBackStack')) {
|
|
21
|
-
(0,
|
|
31
|
+
this.nativeExecuteService.execute('closeWebview', () => (0, utils_1.closeWebviewUtil)());
|
|
22
32
|
// Проверено, ОС получает диплинк и передаёт его NA, не смотря на то,
|
|
23
33
|
// что это происходит в следующей макрозадаче после команды на закрытие WV.
|
|
24
|
-
|
|
34
|
+
this.nativeExecuteService.execute('nativeDeeplink', () => {
|
|
35
|
+
setTimeout(() => window.location.replace(preparedNativeUrl), 0);
|
|
36
|
+
}, { deeplink: preparedNativeUrl });
|
|
25
37
|
return;
|
|
26
38
|
}
|
|
27
|
-
|
|
39
|
+
this.nativeExecuteService.execute('nativeDeeplink', () => this.navigateByNativeApp(preparedNativeUrl), { deeplink: preparedNativeUrl });
|
|
28
40
|
}
|
|
29
41
|
getHrefToOpenInBrowser(link) {
|
|
30
42
|
if (!this.nativeParamsService.canUseNativeFeature('linksInBrowser')) {
|
|
@@ -35,13 +47,16 @@ class ExternalLinksService {
|
|
|
35
47
|
return url.href;
|
|
36
48
|
}
|
|
37
49
|
openInBrowser(link) {
|
|
50
|
+
if (this.navigationByNativeAppInProgress) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
38
53
|
if (!this.nativeParamsService.canUseNativeFeature('linksInBrowser')) {
|
|
39
54
|
this.openInNewWebview(link);
|
|
40
55
|
return;
|
|
41
56
|
}
|
|
42
57
|
const url = new URL(link);
|
|
43
58
|
url.searchParams.append(QUERY_OPEN_IN_BROWSER_KEY, QUERY_OPEN_IN_BROWSER_VALUE);
|
|
44
|
-
|
|
59
|
+
this.nativeExecuteService.execute('openInBrowser', () => this.navigateByNativeApp(url.href), { url: url.href });
|
|
45
60
|
}
|
|
46
61
|
openInNewWebview(link, nativeTitle = '', closeCurrentWebview = false) {
|
|
47
62
|
const url = new URL(link);
|
|
@@ -51,6 +66,9 @@ class ExternalLinksService {
|
|
|
51
66
|
this.handleNativeDeeplink(`/webFeature?type=recommendation&url=${encodeURIComponent(url.toString())}`, closeCurrentWebview);
|
|
52
67
|
}
|
|
53
68
|
openPdf(url, type = 'pdfFile', title) {
|
|
69
|
+
if (this.navigationByNativeAppInProgress) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
54
72
|
let replaceUrl = url;
|
|
55
73
|
if (this.nativeParamsService.environment === 'ios') {
|
|
56
74
|
const params = new URLSearchParams();
|
|
@@ -62,10 +80,18 @@ class ExternalLinksService {
|
|
|
62
80
|
const paramsStr = params.toString();
|
|
63
81
|
replaceUrl = `${this.nativeParamsService.appId}:///dashboard/pdf_viewer?${paramsStr}`;
|
|
64
82
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
83
|
+
replaceUrl =
|
|
84
|
+
this.nativeParamsService.environment === 'ios'
|
|
85
|
+
? (0, utils_1.appendFromCurrentQueryParamForIos)(replaceUrl)
|
|
86
|
+
: replaceUrl;
|
|
87
|
+
this.nativeExecuteService.execute('openPdf ', () => this.navigateByNativeApp(replaceUrl), { replaceUrl });
|
|
88
|
+
}
|
|
89
|
+
navigateByNativeApp(url) {
|
|
90
|
+
this.navigationByNativeAppInProgress = true;
|
|
91
|
+
window.location.replace(url);
|
|
92
|
+
setTimeout(() => {
|
|
93
|
+
this.navigationByNativeAppInProgress = false;
|
|
94
|
+
}, CANCEL_NEW_CALLS_TO_NA_TIME);
|
|
69
95
|
}
|
|
70
96
|
}
|
|
71
97
|
exports.ExternalLinksService = ExternalLinksService;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Environment, type NoopOptions } from '../types';
|
|
2
|
+
export declare class NativeExecuteService {
|
|
3
|
+
private isNoop?;
|
|
4
|
+
private environment?;
|
|
5
|
+
constructor(isNoop?: NoopOptions["enabled"] | undefined, environment?: Environment | undefined);
|
|
6
|
+
execute(action: string, fn: () => void, payload?: unknown): void;
|
|
7
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NativeExecuteService = void 0;
|
|
4
|
+
class NativeExecuteService {
|
|
5
|
+
constructor(isNoop, environment) {
|
|
6
|
+
this.isNoop = isNoop;
|
|
7
|
+
this.environment = environment;
|
|
8
|
+
}
|
|
9
|
+
execute(action, fn, payload) {
|
|
10
|
+
if (this.isNoop) {
|
|
11
|
+
console.info(`[B2N noop][${this.environment}] ${action}`, payload);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
fn();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.NativeExecuteService = NativeExecuteService;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type BrowserHistoryApiWrappers, type HistoryPushStateParams, type LocationAssignParam, type LogError } from '../types';
|
|
2
|
+
import { type NativeExecuteService } from './native-execute-service';
|
|
2
3
|
import { type NativeParamsService } from './native-params-service';
|
|
3
4
|
/**
|
|
4
5
|
* Сервис, отвечающий за взаимодействие WA с WV компонентами NA —
|
|
@@ -9,6 +10,7 @@ import { type NativeParamsService } from './native-params-service';
|
|
|
9
10
|
*/
|
|
10
11
|
export declare class NativeNavigationAndTitleService {
|
|
11
12
|
private nativeParamsService;
|
|
13
|
+
private nativeExecuteService;
|
|
12
14
|
private browserHistoryApiWrappers?;
|
|
13
15
|
private logError?;
|
|
14
16
|
private lastSetPageSettingsParams;
|
|
@@ -16,7 +18,7 @@ export declare class NativeNavigationAndTitleService {
|
|
|
16
18
|
private numOfBackSteps;
|
|
17
19
|
private isGoBackLocked;
|
|
18
20
|
private isNavigateServerSideLocked;
|
|
19
|
-
constructor(nativeParamsService: NativeParamsService, browserHistoryApiWrappers?: BrowserHistoryApiWrappers | undefined, logError?: LogError | undefined);
|
|
21
|
+
constructor(nativeParamsService: NativeParamsService, nativeExecuteService: NativeExecuteService, browserHistoryApiWrappers?: BrowserHistoryApiWrappers | undefined, logError?: LogError | undefined);
|
|
20
22
|
closeWebview(): void;
|
|
21
23
|
goBack(): void;
|
|
22
24
|
goBackAFewSteps(stepsNumber: number, autoCloseWebview?: boolean): void;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/* eslint max-lines: ["error", {"max": 350, "skipComments": true}] */
|
|
3
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
3
|
exports.NativeNavigationAndTitleService = void 0;
|
|
4
|
+
/* eslint max-lines: ["error", {"max": 360, "skipComments": true}] */
|
|
5
5
|
const query_and_headers_keys_1 = require("../../query-and-headers-keys");
|
|
6
|
-
const
|
|
6
|
+
const utils_1 = require("./utils");
|
|
7
7
|
const NativeHistoryStackStub = 0;
|
|
8
8
|
/**
|
|
9
9
|
* Сервис, отвечающий за взаимодействие WA с WV компонентами NA —
|
|
@@ -13,8 +13,9 @@ const NativeHistoryStackStub = 0;
|
|
|
13
13
|
* см. в документе {@link ./NAVIGATION_SCENARIOS.md}.
|
|
14
14
|
*/
|
|
15
15
|
class NativeNavigationAndTitleService {
|
|
16
|
-
constructor(nativeParamsService, browserHistoryApiWrappers, logError) {
|
|
16
|
+
constructor(nativeParamsService, nativeExecuteService, browserHistoryApiWrappers, logError) {
|
|
17
17
|
this.nativeParamsService = nativeParamsService;
|
|
18
|
+
this.nativeExecuteService = nativeExecuteService;
|
|
18
19
|
this.browserHistoryApiWrappers = browserHistoryApiWrappers;
|
|
19
20
|
this.logError = logError;
|
|
20
21
|
// Здесь сохраняются параметры, которые в последний раз были отправлены
|
|
@@ -39,7 +40,7 @@ class NativeNavigationAndTitleService {
|
|
|
39
40
|
}
|
|
40
41
|
// eslint-disable-next-line class-methods-use-this -- удобней использовать метод в контексте экземпляра.
|
|
41
42
|
closeWebview() {
|
|
42
|
-
(0,
|
|
43
|
+
(0, utils_1.closeWebviewUtil)();
|
|
43
44
|
}
|
|
44
45
|
goBack() {
|
|
45
46
|
if (this.isGoBackLocked) {
|
|
@@ -57,7 +58,7 @@ class NativeNavigationAndTitleService {
|
|
|
57
58
|
const maxStepsToBack = this.nativeHistoryStack.length - 1;
|
|
58
59
|
if (stepsToBack > maxStepsToBack) {
|
|
59
60
|
if (autoCloseWebview) {
|
|
60
|
-
(0,
|
|
61
|
+
(0, utils_1.closeWebviewUtil)();
|
|
61
62
|
return;
|
|
62
63
|
}
|
|
63
64
|
this.numOfBackSteps = maxStepsToBack;
|
|
@@ -154,7 +155,7 @@ class NativeNavigationAndTitleService {
|
|
|
154
155
|
}
|
|
155
156
|
this.numOfBackSteps = 1;
|
|
156
157
|
if (this.nativeHistoryStack.length < 1) {
|
|
157
|
-
(0,
|
|
158
|
+
(0, utils_1.closeWebviewUtil)();
|
|
158
159
|
return;
|
|
159
160
|
}
|
|
160
161
|
this.saveNativeHistoryStack();
|
|
@@ -277,7 +278,7 @@ class NativeNavigationAndTitleService {
|
|
|
277
278
|
const narrowedPageId = pageId !== null && pageId !== void 0 ? pageId : 1;
|
|
278
279
|
const paramsToSend = JSON.stringify({ pageId: narrowedPageId, pageTitle });
|
|
279
280
|
if (this.lastSetPageSettingsParams !== paramsToSend) {
|
|
280
|
-
(_a = this.nativeParamsService.AndroidBridge) === null || _a === void 0 ? void 0 : _a.setPageSettings(paramsToSend);
|
|
281
|
+
this.nativeExecuteService.execute('syncHistoryWithNative', () => { var _a; return (_a = this.nativeParamsService.AndroidBridge) === null || _a === void 0 ? void 0 : _a.setPageSettings(paramsToSend); }, { paramsToSend });
|
|
281
282
|
this.lastSetPageSettingsParams = paramsToSend;
|
|
282
283
|
}
|
|
283
284
|
}
|
|
@@ -286,7 +287,7 @@ class NativeNavigationAndTitleService {
|
|
|
286
287
|
const pageIdStr = pageId ? `&pageId=${pageId}` : '';
|
|
287
288
|
const paramsToSend = `ios:setPageSettings/${pageTitleStr + pageIdStr}`;
|
|
288
289
|
if (this.lastSetPageSettingsParams !== paramsToSend) {
|
|
289
|
-
window.location.replace(paramsToSend);
|
|
290
|
+
(_a = this.nativeExecuteService) === null || _a === void 0 ? void 0 : _a.execute('syncHistoryWithNative', () => window.location.replace(paramsToSend), { paramsToSend });
|
|
290
291
|
this.lastSetPageSettingsParams = paramsToSend;
|
|
291
292
|
}
|
|
292
293
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { type Environment, type LogError, type NativeFeatureKey, type Theme } from '../types';
|
|
1
|
+
import { type Environment, type LogError, type NativeFeatureKey, type NoopOptions, type Theme } from '../types';
|
|
2
2
|
/**
|
|
3
3
|
* Сервис, аккумулирующий детали о NA и предоставляющий методы, связанные с этим.
|
|
4
4
|
*/
|
|
5
5
|
export declare class NativeParamsService {
|
|
6
|
+
private noop?;
|
|
6
7
|
private logError?;
|
|
7
8
|
AndroidBridge: {
|
|
8
9
|
setPageSettings: (params: string) => void;
|
|
@@ -16,10 +17,11 @@ export declare class NativeParamsService {
|
|
|
16
17
|
theme: Theme;
|
|
17
18
|
title: string;
|
|
18
19
|
webviewLaunchTime: number | null;
|
|
19
|
-
constructor(logError?: LogError | undefined);
|
|
20
|
+
constructor(noop?: NoopOptions | undefined, logError?: LogError | undefined);
|
|
20
21
|
canUseNativeFeature(feature: NativeFeatureKey): boolean;
|
|
21
22
|
isCurrentVersionHigherOrEqual(versionToCompare: string): boolean;
|
|
22
23
|
private static isValidVersionFormat;
|
|
23
24
|
private getAppId;
|
|
24
25
|
private readNativeParamsCookie;
|
|
26
|
+
private resolveEnvironment;
|
|
25
27
|
}
|
|
@@ -7,12 +7,13 @@ const constants_1 = require("../constants");
|
|
|
7
7
|
* Сервис, аккумулирующий детали о NA и предоставляющий методы, связанные с этим.
|
|
8
8
|
*/
|
|
9
9
|
class NativeParamsService {
|
|
10
|
-
constructor(logError) {
|
|
10
|
+
constructor(noop, logError) {
|
|
11
|
+
this.noop = noop;
|
|
11
12
|
this.logError = logError;
|
|
12
13
|
this.AndroidBridge = window.Android;
|
|
13
|
-
this.environment = window.Android ? 'android' : 'ios';
|
|
14
14
|
this.nativeParamsReadErrorFlag = false;
|
|
15
15
|
const nativeParams = this.readNativeParamsCookie();
|
|
16
|
+
this.environment = this.resolveEnvironment();
|
|
16
17
|
this.appVersion = NativeParamsService.isValidVersionFormat(nativeParams === null || nativeParams === void 0 ? void 0 : nativeParams.appVersion)
|
|
17
18
|
? nativeParams.appVersion
|
|
18
19
|
: '0.0.0';
|
|
@@ -76,5 +77,12 @@ class NativeParamsService {
|
|
|
76
77
|
return null;
|
|
77
78
|
}
|
|
78
79
|
}
|
|
80
|
+
resolveEnvironment() {
|
|
81
|
+
var _a;
|
|
82
|
+
if (((_a = this.noop) === null || _a === void 0 ? void 0 : _a.enabled) && this.noop.environment) {
|
|
83
|
+
return this.noop.environment;
|
|
84
|
+
}
|
|
85
|
+
return window.Android ? 'android' : 'ios';
|
|
86
|
+
}
|
|
79
87
|
}
|
|
80
88
|
exports.NativeParamsService = NativeParamsService;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.closeWebviewUtil = void 0;
|
|
4
|
+
exports.appendFromCurrentQueryParamForIos = appendFromCurrentQueryParamForIos;
|
|
5
|
+
const QUERY_CLOSE_WEBVIEW_KEY = 'closeWebView';
|
|
6
|
+
const QUERY_CLOSE_WEBVIEW_VALUE = 'true';
|
|
7
|
+
const QUERY_FROM_CURRENT_KEY = 'fromCurrent';
|
|
8
|
+
const QUERY_FROM_CURRENT_VALUE = 'true';
|
|
9
|
+
function appendFromCurrentQueryParamForIos(nativeUrl) {
|
|
10
|
+
const qIndex = nativeUrl.indexOf('?');
|
|
11
|
+
if (qIndex === -1) {
|
|
12
|
+
return `${nativeUrl}?${QUERY_FROM_CURRENT_KEY}=${QUERY_FROM_CURRENT_VALUE}`;
|
|
13
|
+
}
|
|
14
|
+
const base = nativeUrl.slice(0, qIndex);
|
|
15
|
+
const query = nativeUrl.slice(qIndex + 1);
|
|
16
|
+
const params = new URLSearchParams(query);
|
|
17
|
+
params.set(QUERY_FROM_CURRENT_KEY, QUERY_FROM_CURRENT_VALUE);
|
|
18
|
+
return `${base}?${params.toString()}`;
|
|
19
|
+
}
|
|
20
|
+
const closeWebviewUtil = () => {
|
|
21
|
+
const originalPageUrl = new URL(window.location.href);
|
|
22
|
+
originalPageUrl.searchParams.set(QUERY_CLOSE_WEBVIEW_KEY, QUERY_CLOSE_WEBVIEW_VALUE);
|
|
23
|
+
window.location.href = originalPageUrl.toString();
|
|
24
|
+
};
|
|
25
|
+
exports.closeWebviewUtil = closeWebviewUtil;
|
package/client/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,121 +1,121 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
"name": "@alfalab/bridge-to-native",
|
|
3
|
+
"version": "1.4.1-beta.52a0437",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"description": "Утилита для удобной работы веб приложения внутри нативного приложения и коммуникации с ним.",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=20.19.2",
|
|
8
|
+
"npm": "please-use-yarn"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/core-ds/bridge-to-native.git"
|
|
13
|
+
},
|
|
14
|
+
"exports": {
|
|
15
|
+
"./client": {
|
|
16
|
+
"import": "./client/index.js",
|
|
17
|
+
"require": "./client/index.js",
|
|
18
|
+
"types": "./client/index.d.ts"
|
|
9
19
|
},
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
|
|
20
|
+
"./server": {
|
|
21
|
+
"import": "./server/index.js",
|
|
22
|
+
"require": "./server/index.js",
|
|
23
|
+
"types": "./server/index.d.ts"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"sideEffects": false,
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/core-ds/bridge-to-native/issues"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "yarn build:clean && yarn build:ts",
|
|
32
|
+
"build:clean": "shx rm -rf .publish",
|
|
33
|
+
"build:copy-package-json": "shx cp package.json .publish/package.json",
|
|
34
|
+
"build:ts": "tsc --build",
|
|
35
|
+
"format": "arui-presets-lint format",
|
|
36
|
+
"format:check": "arui-presets-lint format:check",
|
|
37
|
+
"lint": "yarn lint:scripts && yarn format:check",
|
|
38
|
+
"lint:fix": "yarn lint:scripts --fix && yarn format",
|
|
39
|
+
"lint:scripts": "arui-presets-lint scripts",
|
|
40
|
+
"pub": "npm publish .publish --userconfig \"../.npmrc\" --tag \"$TAG\"",
|
|
41
|
+
"release": "yarn build && yarn build:copy-package-json && yarn pub",
|
|
42
|
+
"test": "arui-scripts test --silent --collect-coverage"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@happy-dom/jest-environment": "18.0.1",
|
|
46
|
+
"@types/jest": "29.5.14",
|
|
47
|
+
"@types/node": "20.19.1",
|
|
48
|
+
"arui-presets-lint": "8.7.0",
|
|
49
|
+
"arui-scripts": "19.0.7",
|
|
50
|
+
"copyfiles": "2.4.1",
|
|
51
|
+
"jest-junit": "10.0.0",
|
|
52
|
+
"lint-staged": "^12.5.0",
|
|
53
|
+
"promisify-child-process": "4.1.1",
|
|
54
|
+
"shx": "0.3.4",
|
|
55
|
+
"typescript": "5.5.4"
|
|
56
|
+
},
|
|
57
|
+
"commitlint": {
|
|
58
|
+
"extends": "./node_modules/arui-presets-lint/commitlint"
|
|
59
|
+
},
|
|
60
|
+
"eslintConfig": {
|
|
61
|
+
"extends": "./node_modules/arui-presets-lint/eslint",
|
|
62
|
+
"parserOptions": {
|
|
63
|
+
"project": [
|
|
64
|
+
"./__tests__/tsconfig.json",
|
|
65
|
+
"./src/client/tsconfig.json",
|
|
66
|
+
"./src/server/tsconfig.json"
|
|
67
|
+
]
|
|
13
68
|
},
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"types": "./client/index.d.ts"
|
|
19
|
-
},
|
|
20
|
-
"./server": {
|
|
21
|
-
"import": "./server/index.js",
|
|
22
|
-
"require": "./server/index.js",
|
|
23
|
-
"types": "./server/index.d.ts"
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
"sideEffects": false,
|
|
27
|
-
"bugs": {
|
|
28
|
-
"url": "https://github.com/core-ds/bridge-to-native/issues"
|
|
29
|
-
},
|
|
30
|
-
"scripts": {
|
|
31
|
-
"build": "yarn build:clean && yarn build:ts",
|
|
32
|
-
"build:clean": "shx rm -rf .publish",
|
|
33
|
-
"build:copy-package-json": "shx cp package.json .publish/package.json",
|
|
34
|
-
"build:ts": "tsc --build",
|
|
35
|
-
"format": "arui-presets-lint format",
|
|
36
|
-
"format:check": "arui-presets-lint format:check",
|
|
37
|
-
"lint": "yarn lint:scripts && yarn format:check",
|
|
38
|
-
"lint:fix": "yarn lint:scripts --fix && yarn format",
|
|
39
|
-
"lint:scripts": "arui-presets-lint scripts",
|
|
40
|
-
"pub": "npm publish .publish --userconfig \"../.npmrc\" --tag \"$TAG\"",
|
|
41
|
-
"release": "yarn build && yarn build:copy-package-json && yarn pub",
|
|
42
|
-
"test": "arui-scripts test --silent --collect-coverage"
|
|
43
|
-
},
|
|
44
|
-
"devDependencies": {
|
|
45
|
-
"@happy-dom/jest-environment": "18.0.1",
|
|
46
|
-
"@types/jest": "29.5.14",
|
|
47
|
-
"@types/node": "20.19.1",
|
|
48
|
-
"arui-presets-lint": "8.7.0",
|
|
49
|
-
"arui-scripts": "19.0.7",
|
|
50
|
-
"copyfiles": "2.4.1",
|
|
51
|
-
"jest-junit": "10.0.0",
|
|
52
|
-
"lint-staged": "^12.5.0",
|
|
53
|
-
"promisify-child-process": "4.1.1",
|
|
54
|
-
"shx": "0.3.4",
|
|
55
|
-
"typescript": "5.5.4"
|
|
56
|
-
},
|
|
57
|
-
"commitlint": {
|
|
58
|
-
"extends": "./node_modules/arui-presets-lint/commitlint"
|
|
59
|
-
},
|
|
60
|
-
"eslintConfig": {
|
|
61
|
-
"extends": "./node_modules/arui-presets-lint/eslint",
|
|
62
|
-
"parserOptions": {
|
|
63
|
-
"project": [
|
|
64
|
-
"./__tests__/tsconfig.json",
|
|
65
|
-
"./src/client/tsconfig.json",
|
|
66
|
-
"./src/server/tsconfig.json"
|
|
67
|
-
]
|
|
68
|
-
},
|
|
69
|
-
"overrides": [
|
|
70
|
-
{
|
|
71
|
-
"files": [
|
|
72
|
-
"__tests__/**/*"
|
|
73
|
-
],
|
|
74
|
-
"rules": {
|
|
75
|
-
"max-lines": "off"
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
]
|
|
79
|
-
},
|
|
80
|
-
"jest": {
|
|
81
|
-
"projects": [
|
|
82
|
-
{
|
|
83
|
-
"displayName": "client-tests",
|
|
84
|
-
"testEnvironment": "@happy-dom/jest-environment",
|
|
85
|
-
"testPathIgnorePatterns": [
|
|
86
|
-
"/__tests__/server/"
|
|
87
|
-
]
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
"displayName": "server-tests",
|
|
91
|
-
"testEnvironment": "node",
|
|
92
|
-
"testPathIgnorePatterns": [
|
|
93
|
-
"/__tests__/client/"
|
|
94
|
-
]
|
|
95
|
-
}
|
|
96
|
-
],
|
|
97
|
-
"testRegex": [
|
|
98
|
-
"__tests__/.*\\.test\\.ts"
|
|
69
|
+
"overrides": [
|
|
70
|
+
{
|
|
71
|
+
"files": [
|
|
72
|
+
"__tests__/**/*"
|
|
99
73
|
],
|
|
100
|
-
"
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
74
|
+
"rules": {
|
|
75
|
+
"max-lines": "off"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
},
|
|
80
|
+
"jest": {
|
|
81
|
+
"projects": [
|
|
82
|
+
{
|
|
83
|
+
"displayName": "client-tests",
|
|
84
|
+
"testEnvironment": "@happy-dom/jest-environment",
|
|
85
|
+
"testPathIgnorePatterns": [
|
|
86
|
+
"/__tests__/server/"
|
|
107
87
|
]
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
"
|
|
112
|
-
"
|
|
113
|
-
|
|
114
|
-
".yarn/releases/*"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"displayName": "server-tests",
|
|
91
|
+
"testEnvironment": "node",
|
|
92
|
+
"testPathIgnorePatterns": [
|
|
93
|
+
"/__tests__/client/"
|
|
115
94
|
]
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
95
|
+
}
|
|
96
|
+
],
|
|
97
|
+
"testRegex": [
|
|
98
|
+
"__tests__/.*\\.test\\.ts"
|
|
99
|
+
],
|
|
100
|
+
"coveragePathIgnorePatterns": [
|
|
101
|
+
"/node_modules/",
|
|
102
|
+
"/src/(client|server)/index.ts"
|
|
103
|
+
],
|
|
104
|
+
"reporters": [
|
|
105
|
+
"default",
|
|
106
|
+
"jest-junit"
|
|
107
|
+
]
|
|
108
|
+
},
|
|
109
|
+
"prettier": "arui-presets-lint/prettier",
|
|
110
|
+
"stylelint": {
|
|
111
|
+
"extends": "arui-presets-lint/stylelint",
|
|
112
|
+
"ignoreFiles": [
|
|
113
|
+
"coverage/**/*.js",
|
|
114
|
+
".yarn/releases/*"
|
|
115
|
+
]
|
|
116
|
+
},
|
|
117
|
+
"publishConfig": {
|
|
118
|
+
"registry": "https://registry.npmjs.org"
|
|
119
|
+
},
|
|
120
|
+
"packageManager": "yarn@4.12.0"
|
|
121
121
|
}
|
package/server/is-webview-env.js
CHANGED
|
@@ -10,20 +10,22 @@ const utils_1 = require("./utils");
|
|
|
10
10
|
* @param request Объект запроса (Request или IncomingMessage).
|
|
11
11
|
*/
|
|
12
12
|
function isWebviewEnv(request) {
|
|
13
|
-
// Выставленная ранее кука — однозначный индикатор вебвью окружения.
|
|
14
|
-
const cookieHeader = (0, utils_1.getHeaderValue)(request, query_and_headers_keys_1.HEADER_KEY_COOKIE);
|
|
15
|
-
if ((0, utils_1.hasBridgeToNativeDataCookie)(cookieHeader)) {
|
|
16
|
-
return true;
|
|
17
|
-
}
|
|
18
13
|
const appVersion = (0, utils_1.getHeaderValue)(request, query_and_headers_keys_1.HEADER_KEY_NATIVE_APPVERSION);
|
|
14
|
+
const userAgent = (0, utils_1.getHeaderValue)(request, query_and_headers_keys_1.HEADER_KEY_USER_AGENT);
|
|
15
|
+
const isWebviewByHeaders =
|
|
19
16
|
// `app-version` в заголовках — основной индикатор запроса из вебвью.
|
|
20
|
-
|
|
17
|
+
(appVersion && regexp_patterns_1.versionPattern.test(appVersion)) ||
|
|
18
|
+
// Проверка «на всякий случай» для iOS — нет уверенности,
|
|
19
|
+
// что `app-version` стабильно и на всех версиях есть во всех запросах из вебвью.
|
|
20
|
+
(userAgent && regexp_patterns_1.webviewUaIOSPattern.test(userAgent));
|
|
21
|
+
if (isWebviewByHeaders)
|
|
21
22
|
return true;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
//
|
|
26
|
-
|
|
23
|
+
const isBrowserEnv = userAgent && !regexp_patterns_1.webviewUaIOSPattern.test(userAgent) && !appVersion;
|
|
24
|
+
if (isBrowserEnv)
|
|
25
|
+
return false;
|
|
26
|
+
// Выставленная ранее кука — однозначный индикатор вебвью окружения.
|
|
27
|
+
const cookieHeader = (0, utils_1.getHeaderValue)(request, query_and_headers_keys_1.HEADER_KEY_COOKIE);
|
|
28
|
+
if ((0, utils_1.hasBridgeToNativeDataCookie)(cookieHeader)) {
|
|
27
29
|
return true;
|
|
28
30
|
}
|
|
29
31
|
return false;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const closeWebviewUtil: () => void;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.closeWebviewUtil = void 0;
|
|
4
|
-
const QUERY_CLOSE_WEBVIEW_KEY = 'closeWebView';
|
|
5
|
-
const QUERY_CLOSE_WEBVIEW_VALUE = 'true';
|
|
6
|
-
const closeWebviewUtil = () => {
|
|
7
|
-
const originalPageUrl = new URL(window.location.href);
|
|
8
|
-
originalPageUrl.searchParams.set(QUERY_CLOSE_WEBVIEW_KEY, QUERY_CLOSE_WEBVIEW_VALUE);
|
|
9
|
-
window.location.href = originalPageUrl.toString();
|
|
10
|
-
};
|
|
11
|
-
exports.closeWebviewUtil = closeWebviewUtil;
|