@alfalab/bridge-to-native 1.4.0-beta.7b254fa → 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 +3 -1
- package/client/services-and-utils/external-links-service.js +9 -6
- 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 +5 -4
- 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/types.d.ts +4 -0
- package/package.json +1 -1
- package/server/is-webview-env.js +13 -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,8 +7,9 @@ import { type NativeParamsService } from './native-params-service';
|
|
|
6
7
|
*/
|
|
7
8
|
export declare class ExternalLinksService {
|
|
8
9
|
private nativeParamsService;
|
|
10
|
+
private nativeExecuteService;
|
|
9
11
|
private navigationByNativeAppInProgress;
|
|
10
|
-
constructor(nativeParamsService: NativeParamsService);
|
|
12
|
+
constructor(nativeParamsService: NativeParamsService, nativeExecuteService: NativeExecuteService);
|
|
11
13
|
handleNativeDeeplink(deeplink: string, closeWebviewBeforeCallNativeDeeplinkHandler?: boolean): void;
|
|
12
14
|
getHrefToOpenInBrowser(link: string): string;
|
|
13
15
|
openInBrowser(link: string): void;
|
|
@@ -12,8 +12,9 @@ const QUERY_OPEN_IN_BROWSER_VALUE = 'true';
|
|
|
12
12
|
* и связанных с этим действий.
|
|
13
13
|
*/
|
|
14
14
|
class ExternalLinksService {
|
|
15
|
-
constructor(nativeParamsService) {
|
|
15
|
+
constructor(nativeParamsService, nativeExecuteService) {
|
|
16
16
|
this.nativeParamsService = nativeParamsService;
|
|
17
|
+
this.nativeExecuteService = nativeExecuteService;
|
|
17
18
|
this.navigationByNativeAppInProgress = false;
|
|
18
19
|
}
|
|
19
20
|
handleNativeDeeplink(deeplink, closeWebviewBeforeCallNativeDeeplinkHandler = false) {
|
|
@@ -27,13 +28,15 @@ class ExternalLinksService {
|
|
|
27
28
|
: originalNativeUrl;
|
|
28
29
|
if (closeWebviewBeforeCallNativeDeeplinkHandler &&
|
|
29
30
|
this.nativeParamsService.canUseNativeFeature('savedBackStack')) {
|
|
30
|
-
(0, utils_1.closeWebviewUtil)();
|
|
31
|
+
this.nativeExecuteService.execute('closeWebview', () => (0, utils_1.closeWebviewUtil)());
|
|
31
32
|
// Проверено, ОС получает диплинк и передаёт его NA, не смотря на то,
|
|
32
33
|
// что это происходит в следующей макрозадаче после команды на закрытие WV.
|
|
33
|
-
|
|
34
|
+
this.nativeExecuteService.execute('nativeDeeplink', () => {
|
|
35
|
+
setTimeout(() => window.location.replace(preparedNativeUrl), 0);
|
|
36
|
+
}, { deeplink: preparedNativeUrl });
|
|
34
37
|
return;
|
|
35
38
|
}
|
|
36
|
-
this.navigateByNativeApp(preparedNativeUrl);
|
|
39
|
+
this.nativeExecuteService.execute('nativeDeeplink', () => this.navigateByNativeApp(preparedNativeUrl), { deeplink: preparedNativeUrl });
|
|
37
40
|
}
|
|
38
41
|
getHrefToOpenInBrowser(link) {
|
|
39
42
|
if (!this.nativeParamsService.canUseNativeFeature('linksInBrowser')) {
|
|
@@ -53,7 +56,7 @@ class ExternalLinksService {
|
|
|
53
56
|
}
|
|
54
57
|
const url = new URL(link);
|
|
55
58
|
url.searchParams.append(QUERY_OPEN_IN_BROWSER_KEY, QUERY_OPEN_IN_BROWSER_VALUE);
|
|
56
|
-
this.navigateByNativeApp(url.href);
|
|
59
|
+
this.nativeExecuteService.execute('openInBrowser', () => this.navigateByNativeApp(url.href), { url: url.href });
|
|
57
60
|
}
|
|
58
61
|
openInNewWebview(link, nativeTitle = '', closeCurrentWebview = false) {
|
|
59
62
|
const url = new URL(link);
|
|
@@ -81,7 +84,7 @@ class ExternalLinksService {
|
|
|
81
84
|
this.nativeParamsService.environment === 'ios'
|
|
82
85
|
? (0, utils_1.appendFromCurrentQueryParamForIos)(replaceUrl)
|
|
83
86
|
: replaceUrl;
|
|
84
|
-
this.navigateByNativeApp(replaceUrl);
|
|
87
|
+
this.nativeExecuteService.execute('openPdf ', () => this.navigateByNativeApp(replaceUrl), { replaceUrl });
|
|
85
88
|
}
|
|
86
89
|
navigateByNativeApp(url) {
|
|
87
90
|
this.navigationByNativeAppInProgress = true;
|
|
@@ -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,7 +1,7 @@
|
|
|
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
6
|
const utils_1 = require("./utils");
|
|
7
7
|
const NativeHistoryStackStub = 0;
|
|
@@ -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
|
// Здесь сохраняются параметры, которые в последний раз были отправлены
|
|
@@ -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;
|
package/client/types.d.ts
CHANGED
package/package.json
CHANGED
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;
|