@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.
@@ -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,10 +7,13 @@ import { type NativeParamsService } from './native-params-service';
6
7
  */
7
8
  export declare class ExternalLinksService {
8
9
  private nativeParamsService;
9
- constructor(nativeParamsService: NativeParamsService);
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 close_webview_util_1 = require("./close-webview-util");
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, close_webview_util_1.closeWebviewUtil)();
31
+ this.nativeExecuteService.execute('closeWebview', () => (0, utils_1.closeWebviewUtil)());
22
32
  // Проверено, ОС получает диплинк и передаёт его NA, не смотря на то,
23
33
  // что это происходит в следующей макрозадаче после команды на закрытие WV.
24
- setTimeout(() => window.location.replace(`${this.nativeParamsService.appId}://${clearedDeeplinkPath}`), 0);
34
+ this.nativeExecuteService.execute('nativeDeeplink', () => {
35
+ setTimeout(() => window.location.replace(preparedNativeUrl), 0);
36
+ }, { deeplink: preparedNativeUrl });
25
37
  return;
26
38
  }
27
- window.location.replace(`${this.nativeParamsService.appId}://${clearedDeeplinkPath}`);
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
- window.location.replace(url.href);
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
- const windowObjectReference = window.open(replaceUrl);
66
- if (windowObjectReference === null) {
67
- window.location.replace(replaceUrl);
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 close_webview_util_1 = require("./close-webview-util");
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, close_webview_util_1.closeWebviewUtil)();
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, close_webview_util_1.closeWebviewUtil)();
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, close_webview_util_1.closeWebviewUtil)();
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,2 @@
1
+ export declare function appendFromCurrentQueryParamForIos(nativeUrl: string): string;
2
+ export declare const closeWebviewUtil: () => void;
@@ -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
@@ -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,121 +1,121 @@
1
1
  {
2
- "name": "@alfalab/bridge-to-native",
3
- "version": "1.4.0",
4
- "license": "MIT",
5
- "description": "Утилита для удобной работы веб приложения внутри нативного приложения и коммуникации с ним.",
6
- "engines": {
7
- "node": ">=20.19.2",
8
- "npm": "please-use-yarn"
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
- "repository": {
11
- "type": "git",
12
- "url": "git+https://github.com/core-ds/bridge-to-native.git"
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
- "exports": {
15
- "./client": {
16
- "import": "./client/index.js",
17
- "require": "./client/index.js",
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
- "coveragePathIgnorePatterns": [
101
- "/node_modules/",
102
- "/src/(client|server)/index.ts"
103
- ],
104
- "reporters": [
105
- "default",
106
- "jest-junit"
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
- "prettier": "arui-presets-lint/prettier",
110
- "stylelint": {
111
- "extends": "arui-presets-lint/stylelint",
112
- "ignoreFiles": [
113
- "coverage/**/*.js",
114
- ".yarn/releases/*"
88
+ },
89
+ {
90
+ "displayName": "server-tests",
91
+ "testEnvironment": "node",
92
+ "testPathIgnorePatterns": [
93
+ "/__tests__/client/"
115
94
  ]
116
- },
117
- "publishConfig": {
118
- "registry": "https://registry.npmjs.org"
119
- },
120
- "packageManager": "yarn@4.12.0"
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
  }
@@ -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;
@@ -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;