@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.
@@ -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.externalLinksService = new external_links_service_1.ExternalLinksService(this.nativeParamsService);
26
- this.nativeNavigationAndTitleService = new native_navigation_and_title_service_1.NativeNavigationAndTitleService(this.nativeParamsService, (_b = this.options) === null || _b === void 0 ? void 0 : _b.browserHistoryApiWrappers, (_c = this.options) === null || _c === void 0 ? void 0 : _c.logError);
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
- setTimeout(() => window.location.replace(preparedNativeUrl), 0);
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
@@ -18,4 +18,8 @@ export type NativeFeaturesFromVersion = Readonly<{
18
18
  }>;
19
19
  export type PdfType = 'pdfFile' | 'base64' | 'binary';
20
20
  export type Theme = 'light' | 'dark';
21
+ export type NoopOptions = {
22
+ enabled: boolean;
23
+ environment?: Environment;
24
+ };
21
25
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfalab/bridge-to-native",
3
- "version": "1.4.0-beta.7b254fa",
3
+ "version": "1.4.1-beta.52a0437",
4
4
  "license": "MIT",
5
5
  "description": "Утилита для удобной работы веб приложения внутри нативного приложения и коммуникации с ним.",
6
6
  "engines": {
@@ -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
- if (appVersion && regexp_patterns_1.versionPattern.test(appVersion)) {
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
- const userAgent = (0, utils_1.getHeaderValue)(request, query_and_headers_keys_1.HEADER_KEY_USER_AGENT);
24
- // Проверка «на всякий случай» для iOS — нет уверенности,
25
- // что `app-version` стабильно и на всех версиях есть во всех запросах из вебвью.
26
- if (userAgent && regexp_patterns_1.webviewUaIOSPattern.test(userAgent)) {
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;