expo-linking 2.3.1 → 3.0.0

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/CHANGELOG.md CHANGED
@@ -10,10 +10,27 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
- ## 2.3.1 — 2021-06-23
13
+ ## 3.0.0 — 2021-12-03
14
+
15
+ ### 🛠 Breaking changes
16
+
17
+ - Remove deprecated `useUrl` method. ([#15226](https://github.com/expo/expo/pull/15226) by [@Simek](https://github.com/Simek))
18
+
19
+ ### 💡 Others
20
+
21
+ - Update `qs` dependency. ([#15069](https://github.com/expo/expo/pull/15069) by [@Simek](https://github.com/Simek))
22
+ - Extract `sendIntent` method `extras` parameter to the separate type named `SendIntentExtras`. ([#15226](https://github.com/expo/expo/pull/15226) by [@Simek](https://github.com/Simek))
23
+
24
+ ## 2.4.1 — 2021-10-01
14
25
 
15
26
  _This version does not introduce any user-facing changes._
16
27
 
28
+ ## 2.4.0 — 2021-09-09
29
+
30
+ ### 🎉 New features
31
+
32
+ - Update JS code to read manifest2 when manifest is not available. ([#13602](https://github.com/expo/expo/pull/13602) by [@wschurman](https://github.com/wschurman))
33
+
17
34
  ## 2.3.0 — 2021-06-16
18
35
 
19
36
  ### 🐛 Bug fixes
package/README.md CHANGED
@@ -13,7 +13,7 @@ For managed [managed](https://docs.expo.io/versions/latest/introduction/managed-
13
13
 
14
14
  # Installation in bare React Native projects
15
15
 
16
- For bare React Native projects, you must ensure that you have [installed and configured the `react-native-unimodules` package](https://github.com/expo/expo/tree/master/packages/react-native-unimodules) before continuing.
16
+ For bare React Native projects, you must ensure that you have [installed and configured the `expo` package](https://docs.expo.dev/bare/installing-expo-modules/) before continuing.
17
17
 
18
18
  ### Add the package to your npm dependencies
19
19
 
@@ -1,17 +1,17 @@
1
- import { Platform } from '@unimodules/core';
1
+ import { Platform } from 'expo-modules-core';
2
2
  import invariant from 'invariant';
3
3
  const EventTypes = ['url'];
4
4
  const listeners = [];
5
5
  export default {
6
6
  addEventListener(type, listener) {
7
7
  invariant(EventTypes.indexOf(type) !== -1, `Linking.addEventListener(): ${type} is not a valid event`);
8
- const nativeListener = nativeEvent => listener({ url: window.location.href, nativeEvent });
8
+ const nativeListener = (nativeEvent) => listener({ url: window.location.href, nativeEvent });
9
9
  listeners.push({ listener, nativeListener });
10
10
  window.addEventListener('message', nativeListener, false);
11
11
  },
12
12
  removeEventListener(type, listener) {
13
13
  invariant(EventTypes.indexOf(type) !== -1, `Linking.removeEventListener(): ${type} is not a valid event.`);
14
- const listenerIndex = listeners.findIndex(pair => pair.listener === listener);
14
+ const listenerIndex = listeners.findIndex((pair) => pair.listener === listener);
15
15
  invariant(listenerIndex !== -1, 'Linking.removeEventListener(): cannot remove an unregistered event listener.');
16
16
  const nativeListener = listeners[listenerIndex].nativeListener;
17
17
  window.removeEventListener('message', nativeListener, false);
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoLinking.web.js","sourceRoot":"","sources":["../src/ExpoLinking.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,SAAS,MAAM,WAAW,CAAC;AAIlC,MAAM,UAAU,GAAG,CAAC,KAAK,CAAC,CAAC;AAE3B,MAAM,SAAS,GAAmE,EAAE,CAAC;AAErF,eAAe;IACb,gBAAgB,CAAC,IAAW,EAAE,QAAqB;QACjD,SAAS,CACP,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAC/B,+BAA+B,IAAI,uBAAuB,CAC3D,CAAC;QACF,MAAM,cAAc,GAAsB,WAAW,CAAC,EAAE,CACtD,QAAQ,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;QACvD,SAAS,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC;QAC7C,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,cAAc,EAAE,KAAK,CAAC,CAAC;IAC5D,CAAC;IAED,mBAAmB,CAAC,IAAW,EAAE,QAAqB;QACpD,SAAS,CACP,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAC/B,kCAAkC,IAAI,wBAAwB,CAC/D,CAAC;QACF,MAAM,aAAa,GAAG,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;QAC9E,SAAS,CACP,aAAa,KAAK,CAAC,CAAC,EACpB,8EAA8E,CAC/E,CAAC;QACF,MAAM,cAAc,GAAG,SAAS,CAAC,aAAa,CAAC,CAAC,cAAc,CAAC;QAC/D,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,cAAc,EAAE,KAAK,CAAC,CAAC;QAC7D,SAAS,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,GAAW;QAC1B,uFAAuF;QACvF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,IAAI,CAAC,QAAQ,CAAC,cAAc;YAAE,OAAO,EAAE,CAAC;QACxC,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAW;QACvB,IAAI,QAAQ,CAAC,cAAc,EAAE;YAC3B,aAAa;YACb,MAAM,CAAC,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC;SAC5D;IACH,CAAC;CACF,CAAC","sourcesContent":["import { Platform } from '@unimodules/core';\nimport invariant from 'invariant';\n\nimport { NativeURLListener, URLListener } from './Linking.types';\n\nconst EventTypes = ['url'];\n\nconst listeners: { listener: URLListener; nativeListener: NativeURLListener }[] = [];\n\nexport default {\n addEventListener(type: 'url', listener: URLListener): void {\n invariant(\n EventTypes.indexOf(type) !== -1,\n `Linking.addEventListener(): ${type} is not a valid event`\n );\n const nativeListener: NativeURLListener = nativeEvent =>\n listener({ url: window.location.href, nativeEvent });\n listeners.push({ listener, nativeListener });\n window.addEventListener('message', nativeListener, false);\n },\n\n removeEventListener(type: 'url', listener: URLListener): void {\n invariant(\n EventTypes.indexOf(type) !== -1,\n `Linking.removeEventListener(): ${type} is not a valid event.`\n );\n const listenerIndex = listeners.findIndex(pair => pair.listener === listener);\n invariant(\n listenerIndex !== -1,\n 'Linking.removeEventListener(): cannot remove an unregistered event listener.'\n );\n const nativeListener = listeners[listenerIndex].nativeListener;\n window.removeEventListener('message', nativeListener, false);\n listeners.splice(listenerIndex, 1);\n },\n\n async canOpenURL(url: string): Promise<boolean> {\n // In reality this should be able to return false for links like `chrome://` on chrome.\n return true;\n },\n\n async getInitialURL(): Promise<string> {\n if (!Platform.isDOMAvailable) return '';\n return window.location.href;\n },\n\n async openURL(url: string): Promise<void> {\n if (Platform.isDOMAvailable) {\n // @ts-ignore\n window.location = new URL(url, window.location).toString();\n }\n },\n};\n"]}
1
+ {"version":3,"file":"ExpoLinking.web.js","sourceRoot":"","sources":["../src/ExpoLinking.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,SAAS,MAAM,WAAW,CAAC;AAIlC,MAAM,UAAU,GAAG,CAAC,KAAK,CAAC,CAAC;AAE3B,MAAM,SAAS,GAAmE,EAAE,CAAC;AAErF,eAAe;IACb,gBAAgB,CAAC,IAAW,EAAE,QAAqB;QACjD,SAAS,CACP,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAC/B,+BAA+B,IAAI,uBAAuB,CAC3D,CAAC;QACF,MAAM,cAAc,GAAsB,CAAC,WAAW,EAAE,EAAE,CACxD,QAAQ,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;QACvD,SAAS,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC;QAC7C,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,cAAc,EAAE,KAAK,CAAC,CAAC;IAC5D,CAAC;IAED,mBAAmB,CAAC,IAAW,EAAE,QAAqB;QACpD,SAAS,CACP,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAC/B,kCAAkC,IAAI,wBAAwB,CAC/D,CAAC;QACF,MAAM,aAAa,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;QAChF,SAAS,CACP,aAAa,KAAK,CAAC,CAAC,EACpB,8EAA8E,CAC/E,CAAC;QACF,MAAM,cAAc,GAAG,SAAS,CAAC,aAAa,CAAC,CAAC,cAAc,CAAC;QAC/D,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,cAAc,EAAE,KAAK,CAAC,CAAC;QAC7D,SAAS,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,GAAW;QAC1B,uFAAuF;QACvF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,IAAI,CAAC,QAAQ,CAAC,cAAc;YAAE,OAAO,EAAE,CAAC;QACxC,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAW;QACvB,IAAI,QAAQ,CAAC,cAAc,EAAE;YAC3B,aAAa;YACb,MAAM,CAAC,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC;SAC5D;IACH,CAAC;CACF,CAAC","sourcesContent":["import { Platform } from 'expo-modules-core';\nimport invariant from 'invariant';\n\nimport { NativeURLListener, URLListener } from './Linking.types';\n\nconst EventTypes = ['url'];\n\nconst listeners: { listener: URLListener; nativeListener: NativeURLListener }[] = [];\n\nexport default {\n addEventListener(type: 'url', listener: URLListener): void {\n invariant(\n EventTypes.indexOf(type) !== -1,\n `Linking.addEventListener(): ${type} is not a valid event`\n );\n const nativeListener: NativeURLListener = (nativeEvent) =>\n listener({ url: window.location.href, nativeEvent });\n listeners.push({ listener, nativeListener });\n window.addEventListener('message', nativeListener, false);\n },\n\n removeEventListener(type: 'url', listener: URLListener): void {\n invariant(\n EventTypes.indexOf(type) !== -1,\n `Linking.removeEventListener(): ${type} is not a valid event.`\n );\n const listenerIndex = listeners.findIndex((pair) => pair.listener === listener);\n invariant(\n listenerIndex !== -1,\n 'Linking.removeEventListener(): cannot remove an unregistered event listener.'\n );\n const nativeListener = listeners[listenerIndex].nativeListener;\n window.removeEventListener('message', nativeListener, false);\n listeners.splice(listenerIndex, 1);\n },\n\n async canOpenURL(url: string): Promise<boolean> {\n // In reality this should be able to return false for links like `chrome://` on chrome.\n return true;\n },\n\n async getInitialURL(): Promise<string> {\n if (!Platform.isDOMAvailable) return '';\n return window.location.href;\n },\n\n async openURL(url: string): Promise<void> {\n if (Platform.isDOMAvailable) {\n // @ts-ignore\n window.location = new URL(url, window.location).toString();\n }\n },\n};\n"]}
@@ -1,10 +1,9 @@
1
- import { CreateURLOptions, ParsedURL, QueryParams, URLListener } from './Linking.types';
1
+ import { CreateURLOptions, ParsedURL, QueryParams, SendIntentExtras, URLListener } from './Linking.types';
2
2
  /**
3
3
  * Create a URL that works for the environment the app is currently running in.
4
4
  * The scheme in bare and standalone must be defined in the app.json under `expo.scheme`.
5
5
  *
6
- * **Examples**
7
- *
6
+ * # Examples
8
7
  * - Bare: empty string
9
8
  * - Standalone, Custom: `yourscheme:///path`
10
9
  * - Web (dev): `https://localhost:19006/path`
@@ -13,87 +12,107 @@ import { CreateURLOptions, ParsedURL, QueryParams, URLListener } from './Linking
13
12
  * - Expo Client (prod): `exp://exp.host/@yourname/your-app/--/path`
14
13
  *
15
14
  * @param path addition path components to append to the base URL.
16
- * @param queryParams An object of parameters that will be converted into a query string.
15
+ * @param queryParams An object with a set of query parameters. These will be merged with any
16
+ * Expo-specific parameters that are needed (e.g. release channel) and then appended to the URL
17
+ * as a query string.
18
+ * @param scheme Optional URI protocol to use in the URL `<scheme>:///`, when `undefined` the scheme
19
+ * will be chosen from the Expo config (`app.config.js` or `app.json`).
20
+ * @return A URL string which points to your app with the given deep link information.
21
+ * @deprecated An alias for [`createURL()`](#linkingcreateurlpath-namedparameters). This method is
22
+ * deprecated and will be removed in a future SDK version.
17
23
  */
18
24
  export declare function makeUrl(path?: string, queryParams?: QueryParams, scheme?: string): string;
19
25
  /**
20
- * Create a URL that works for the environment the app is currently running in.
21
- * The scheme in bare and standalone must be defined in the Expo config (app.config.js or app.json) under `expo.scheme`.
26
+ * Helper method for constructing a deep link into your app, given an optional path and set of query
27
+ * parameters. Creates a URI scheme with two slashes by default.
22
28
  *
23
- * **Examples**
29
+ * The scheme in bare and standalone must be defined in the Expo config (`app.config.js` or `app.json`)
30
+ * under `expo.scheme`.
24
31
  *
25
- * - Bare: `<scheme>://path` -- uses provided scheme or scheme from Expo config `scheme`.
32
+ * # Examples
33
+ * - Bare: `<scheme>://path` - uses provided scheme or scheme from Expo config `scheme`.
26
34
  * - Standalone, Custom: `yourscheme://path`
27
35
  * - Web (dev): `https://localhost:19006/path`
28
36
  * - Web (prod): `https://myapp.com/path`
29
37
  * - Expo Client (dev): `exp://128.0.0.1:19000/--/path`
30
38
  * - Expo Client (prod): `exp://exp.host/@yourname/your-app/--/path`
31
39
  *
32
- * @param path addition path components to append to the base URL.
33
- * @param scheme URI protocol `<scheme>://` that must be built into your native app.
34
- * @param queryParams An object of parameters that will be converted into a query string.
40
+ * @param path Addition path components to append to the base URL.
41
+ * @param namedParameters Additional options object.
42
+ * @return A URL string which points to your app with the given deep link information.
35
43
  */
36
44
  export declare function createURL(path: string, { scheme, queryParams, isTripleSlashed }?: CreateURLOptions): string;
37
45
  /**
38
- * Returns the components and query parameters for a given URL.
39
- *
40
- * @param url Input URL to parse
46
+ * Helper method for parsing out deep link information from a URL.
47
+ * @param url A URL that points to the currently running experience (e.g. an output of `Linking.createURL()`).
48
+ * @return A `ParsedURL` object.
41
49
  */
42
50
  export declare function parse(url: string): ParsedURL;
43
51
  /**
44
- * Add a handler to Linking changes by listening to the `url` event type
45
- * and providing the handler
46
- *
47
- * See https://reactnative.dev/docs/linking.html#addeventlistener
52
+ * Add a handler to `Linking` changes by listening to the `url` event type and providing the handler.
53
+ * It is recommended to use the [`useURL()`](#useurl) hook instead.
54
+ * @param type The only valid type is `'url'`.
55
+ * @param handler An [`URLListener`](#urllistener) function that takes an `event` object of the type
56
+ * [`EventType`](#eventype).
57
+ * @see [React Native Docs Linking page](https://reactnative.dev/docs/linking#addeventlistener).
48
58
  */
49
59
  export declare function addEventListener(type: string, handler: URLListener): void;
50
60
  /**
51
61
  * Remove a handler by passing the `url` event type and the handler.
52
- *
53
- * See https://reactnative.dev/docs/linking.html#removeeventlistener
62
+ * @param type The only valid type is `'url'`.
63
+ * @param handler An [`URLListener`](#urllistener) function that takes an `event` object of the type
64
+ * [`EventType`](#eventype).
65
+ * @see [React Native Docs Linking page](https://reactnative.dev/docs/linking#removeeventlistener).
54
66
  */
55
67
  export declare function removeEventListener(type: string, handler: URLListener): void;
56
68
  /**
57
- * **Native:** Parses the link that opened the app. If no link opened the app, all the fields will be \`null\`.
58
- * **Web:** Parses the current window URL.
69
+ * Helper method which wraps React Native's `Linking.getInitialURL()` in `Linking.parse()`.
70
+ * Parses the deep link information out of the URL used to open the experience initially.
71
+ * If no link opened the app, all the fields will be `null`.
72
+ * > On the web it parses the current window URL.
73
+ * @return A promise that resolves with `ParsedURL` object.
59
74
  */
60
75
  export declare function parseInitialURLAsync(): Promise<ParsedURL>;
61
76
  /**
62
- * Launch an Android intent with optional extras
63
- *
77
+ * Launch an Android intent with extras.
78
+ * > Use [IntentLauncher](../intent-launcher) instead, `sendIntent` is only included in
79
+ * > `Linking` for API compatibility with React Native's Linking API.
64
80
  * @platform android
65
81
  */
66
- export declare function sendIntent(action: string, extras?: {
67
- key: string;
68
- value: string | number | boolean;
69
- }[]): Promise<void>;
82
+ export declare function sendIntent(action: string, extras?: SendIntentExtras[]): Promise<void>;
70
83
  /**
71
- * Attempt to open the system settings for an the app.
72
- *
84
+ * Open the operating system settings app and displays the app’s custom settings, if it has any.
73
85
  * @platform ios
74
86
  */
75
87
  export declare function openSettings(): Promise<void>;
76
88
  /**
77
- * If the app launch was triggered by an app link,
78
- * it will give the link url, otherwise it will give `null`
89
+ * Get the URL that was used to launch the app if it was launched by a link.
90
+ * @return The URL string that launched your app, or `null`.
79
91
  */
80
92
  export declare function getInitialURL(): Promise<string | null>;
81
93
  /**
82
- * Try to open the given `url` with any of the installed apps.
94
+ * Attempt to open the given URL with an installed app. See the [Linking guide](/guides/linking)
95
+ * for more information.
96
+ * @param url A URL for the operating system to open, eg: `tel:5555555`, `exp://`.
97
+ * @return A `Promise` that is fulfilled with `true` if the link is opened operating system
98
+ * automatically or the user confirms the prompt to open the link. The `Promise` rejects if there
99
+ * are no applications registered for the URL or the user cancels the dialog.
83
100
  */
84
101
  export declare function openURL(url: string): Promise<true>;
85
102
  /**
86
103
  * Determine whether or not an installed app can handle a given URL.
87
- * On web this always returns true because there is no API for detecting what URLs can be opened.
104
+ * On web this always returns `true` because there is no API for detecting what URLs can be opened.
105
+ * @param url The URL that you want to test can be opened.
106
+ * @return A `Promise` object that is fulfilled with `true` if the URL can be handled, otherwise it
107
+ * `false` if not.
108
+ *
109
+ * The `Promise` will reject on Android if it was impossible to check if the URL can be opened, and
110
+ * on iOS if you didn't [add the specific scheme in the `LSApplicationQueriesSchemes` key inside **Info.plist**](/guides/linking#opening-links-to-other-apps).
88
111
  */
89
112
  export declare function canOpenURL(url: string): Promise<boolean>;
90
113
  /**
91
114
  * Returns the initial URL followed by any subsequent changes to the URL.
115
+ * @return Returns the initial URL or `null`.
92
116
  */
93
117
  export declare function useURL(): string | null;
94
- /**
95
- * Returns the initial URL followed by any subsequent changes to the URL.
96
- * @deprecated Use `useURL` instead.
97
- */
98
- export declare function useUrl(): string | null;
99
118
  export * from './Linking.types';
package/build/Linking.js CHANGED
@@ -1,5 +1,5 @@
1
- import { Platform, UnavailabilityError } from '@unimodules/core';
2
1
  import Constants from 'expo-constants';
2
+ import { Platform, UnavailabilityError } from 'expo-modules-core';
3
3
  import invariant from 'invariant';
4
4
  import qs from 'qs';
5
5
  import { useEffect, useState } from 'react';
@@ -14,7 +14,10 @@ function getHostUri() {
14
14
  if (Constants.manifest?.hostUri) {
15
15
  return Constants.manifest.hostUri;
16
16
  }
17
- else if (!Constants.manifest?.hostUri && !hasCustomScheme()) {
17
+ else if (Constants.manifest2?.extra?.expoClient?.hostUri) {
18
+ return Constants.manifest2.extra.expoClient.hostUri;
19
+ }
20
+ else if (!hasCustomScheme()) {
18
21
  // we're probably not using up-to-date xdl, so just fake it for now
19
22
  // we have to remove the /--/ on the end since this will be inserted again later
20
23
  return removeScheme(Constants.linkingUri).replace(/\/--($|\/.*$)/, '');
@@ -41,7 +44,7 @@ function removeLeadingSlash(url) {
41
44
  function removeTrailingSlashAndQueryString(url) {
42
45
  return url.replace(/\/?\?.*$/, '');
43
46
  }
44
- function ensureLeadingSlash(input, shouldAppend) {
47
+ function ensureTrailingSlash(input, shouldAppend) {
45
48
  const hasSlash = input.endsWith('/');
46
49
  if (hasSlash && !shouldAppend) {
47
50
  return input.substring(0, input.length - 1);
@@ -51,7 +54,7 @@ function ensureLeadingSlash(input, shouldAppend) {
51
54
  }
52
55
  return input;
53
56
  }
54
- function ensureTrailingSlash(input, shouldAppend) {
57
+ function ensureLeadingSlash(input, shouldAppend) {
55
58
  const hasSlash = input.startsWith('/');
56
59
  if (hasSlash && !shouldAppend) {
57
60
  return input.substring(1);
@@ -61,12 +64,12 @@ function ensureTrailingSlash(input, shouldAppend) {
61
64
  }
62
65
  return input;
63
66
  }
67
+ // @needsAudit
64
68
  /**
65
69
  * Create a URL that works for the environment the app is currently running in.
66
70
  * The scheme in bare and standalone must be defined in the app.json under `expo.scheme`.
67
71
  *
68
- * **Examples**
69
- *
72
+ * # Examples
70
73
  * - Bare: empty string
71
74
  * - Standalone, Custom: `yourscheme:///path`
72
75
  * - Web (dev): `https://localhost:19006/path`
@@ -75,40 +78,50 @@ function ensureTrailingSlash(input, shouldAppend) {
75
78
  * - Expo Client (prod): `exp://exp.host/@yourname/your-app/--/path`
76
79
  *
77
80
  * @param path addition path components to append to the base URL.
78
- * @param queryParams An object of parameters that will be converted into a query string.
81
+ * @param queryParams An object with a set of query parameters. These will be merged with any
82
+ * Expo-specific parameters that are needed (e.g. release channel) and then appended to the URL
83
+ * as a query string.
84
+ * @param scheme Optional URI protocol to use in the URL `<scheme>:///`, when `undefined` the scheme
85
+ * will be chosen from the Expo config (`app.config.js` or `app.json`).
86
+ * @return A URL string which points to your app with the given deep link information.
87
+ * @deprecated An alias for [`createURL()`](#linkingcreateurlpath-namedparameters). This method is
88
+ * deprecated and will be removed in a future SDK version.
79
89
  */
80
90
  export function makeUrl(path = '', queryParams, scheme) {
81
91
  return createURL(path, { queryParams, scheme, isTripleSlashed: true });
82
92
  }
93
+ // @needsAudit
83
94
  /**
84
- * Create a URL that works for the environment the app is currently running in.
85
- * The scheme in bare and standalone must be defined in the Expo config (app.config.js or app.json) under `expo.scheme`.
95
+ * Helper method for constructing a deep link into your app, given an optional path and set of query
96
+ * parameters. Creates a URI scheme with two slashes by default.
86
97
  *
87
- * **Examples**
98
+ * The scheme in bare and standalone must be defined in the Expo config (`app.config.js` or `app.json`)
99
+ * under `expo.scheme`.
88
100
  *
89
- * - Bare: `<scheme>://path` -- uses provided scheme or scheme from Expo config `scheme`.
101
+ * # Examples
102
+ * - Bare: `<scheme>://path` - uses provided scheme or scheme from Expo config `scheme`.
90
103
  * - Standalone, Custom: `yourscheme://path`
91
104
  * - Web (dev): `https://localhost:19006/path`
92
105
  * - Web (prod): `https://myapp.com/path`
93
106
  * - Expo Client (dev): `exp://128.0.0.1:19000/--/path`
94
107
  * - Expo Client (prod): `exp://exp.host/@yourname/your-app/--/path`
95
108
  *
96
- * @param path addition path components to append to the base URL.
97
- * @param scheme URI protocol `<scheme>://` that must be built into your native app.
98
- * @param queryParams An object of parameters that will be converted into a query string.
109
+ * @param path Addition path components to append to the base URL.
110
+ * @param namedParameters Additional options object.
111
+ * @return A URL string which points to your app with the given deep link information.
99
112
  */
100
113
  export function createURL(path, { scheme, queryParams = {}, isTripleSlashed = false } = {}) {
101
114
  if (Platform.OS === 'web') {
102
115
  if (!Platform.isDOMAvailable)
103
116
  return '';
104
- const origin = ensureLeadingSlash(window.location.origin, false);
117
+ const origin = ensureTrailingSlash(window.location.origin, false);
105
118
  let queryString = qs.stringify(queryParams);
106
119
  if (queryString) {
107
120
  queryString = `?${queryString}`;
108
121
  }
109
122
  let outputPath = path;
110
123
  if (outputPath)
111
- outputPath = ensureTrailingSlash(path, true);
124
+ outputPath = ensureLeadingSlash(path, true);
112
125
  return encodeURI(`${origin}${outputPath}${queryString}`);
113
126
  }
114
127
  const resolvedScheme = resolveScheme({ scheme });
@@ -151,13 +164,14 @@ export function createURL(path, { scheme, queryParams = {}, isTripleSlashed = fa
151
164
  if (queryString) {
152
165
  queryString = `?${queryString}`;
153
166
  }
154
- hostUri = ensureTrailingSlash(hostUri, !isTripleSlashed);
167
+ hostUri = ensureLeadingSlash(hostUri, !isTripleSlashed);
155
168
  return encodeURI(`${resolvedScheme}:${isTripleSlashed ? '/' : ''}/${hostUri}${path}${queryString}`);
156
169
  }
170
+ // @needsAudit
157
171
  /**
158
- * Returns the components and query parameters for a given URL.
159
- *
160
- * @param url Input URL to parse
172
+ * Helper method for parsing out deep link information from a URL.
173
+ * @param url A URL that points to the currently running experience (e.g. an output of `Linking.createURL()`).
174
+ * @return A `ParsedURL` object.
161
175
  */
162
176
  export function parse(url) {
163
177
  validateURL(url);
@@ -180,10 +194,7 @@ export function parse(url) {
180
194
  let expoPrefix = null;
181
195
  if (hostUriStripped) {
182
196
  const parts = hostUriStripped.split('/');
183
- expoPrefix = parts
184
- .slice(1)
185
- .concat(['--/'])
186
- .join('/');
197
+ expoPrefix = parts.slice(1).concat(['--/']).join('/');
187
198
  }
188
199
  if (isExpoHosted() && !hasCustomScheme() && expoPrefix && path.startsWith(expoPrefix)) {
189
200
  path = path.substring(expoPrefix.length);
@@ -200,26 +211,35 @@ export function parse(url) {
200
211
  scheme,
201
212
  };
202
213
  }
214
+ // @needsAudit
203
215
  /**
204
- * Add a handler to Linking changes by listening to the `url` event type
205
- * and providing the handler
206
- *
207
- * See https://reactnative.dev/docs/linking.html#addeventlistener
216
+ * Add a handler to `Linking` changes by listening to the `url` event type and providing the handler.
217
+ * It is recommended to use the [`useURL()`](#useurl) hook instead.
218
+ * @param type The only valid type is `'url'`.
219
+ * @param handler An [`URLListener`](#urllistener) function that takes an `event` object of the type
220
+ * [`EventType`](#eventype).
221
+ * @see [React Native Docs Linking page](https://reactnative.dev/docs/linking#addeventlistener).
208
222
  */
209
223
  export function addEventListener(type, handler) {
210
224
  NativeLinking.addEventListener(type, handler);
211
225
  }
212
226
  /**
213
227
  * Remove a handler by passing the `url` event type and the handler.
214
- *
215
- * See https://reactnative.dev/docs/linking.html#removeeventlistener
228
+ * @param type The only valid type is `'url'`.
229
+ * @param handler An [`URLListener`](#urllistener) function that takes an `event` object of the type
230
+ * [`EventType`](#eventype).
231
+ * @see [React Native Docs Linking page](https://reactnative.dev/docs/linking#removeeventlistener).
216
232
  */
217
233
  export function removeEventListener(type, handler) {
218
234
  NativeLinking.removeEventListener(type, handler);
219
235
  }
236
+ // @needsAudit
220
237
  /**
221
- * **Native:** Parses the link that opened the app. If no link opened the app, all the fields will be \`null\`.
222
- * **Web:** Parses the current window URL.
238
+ * Helper method which wraps React Native's `Linking.getInitialURL()` in `Linking.parse()`.
239
+ * Parses the deep link information out of the URL used to open the experience initially.
240
+ * If no link opened the app, all the fields will be `null`.
241
+ * > On the web it parses the current window URL.
242
+ * @return A promise that resolves with `ParsedURL` object.
223
243
  */
224
244
  export async function parseInitialURLAsync() {
225
245
  const initialUrl = await NativeLinking.getInitialURL();
@@ -233,9 +253,11 @@ export async function parseInitialURLAsync() {
233
253
  }
234
254
  return parse(initialUrl);
235
255
  }
256
+ // @needsAudit
236
257
  /**
237
- * Launch an Android intent with optional extras
238
- *
258
+ * Launch an Android intent with extras.
259
+ * > Use [IntentLauncher](../intent-launcher) instead, `sendIntent` is only included in
260
+ * > `Linking` for API compatibility with React Native's Linking API.
239
261
  * @platform android
240
262
  */
241
263
  export async function sendIntent(action, extras) {
@@ -244,9 +266,9 @@ export async function sendIntent(action, extras) {
244
266
  }
245
267
  throw new UnavailabilityError('Linking', 'sendIntent');
246
268
  }
269
+ // @needsAudit
247
270
  /**
248
- * Attempt to open the system settings for an the app.
249
- *
271
+ * Open the operating system settings app and displays the app’s custom settings, if it has any.
250
272
  * @platform ios
251
273
  */
252
274
  export async function openSettings() {
@@ -258,30 +280,46 @@ export async function openSettings() {
258
280
  }
259
281
  await openURL('app-settings:');
260
282
  }
283
+ // @needsAudit
261
284
  /**
262
- * If the app launch was triggered by an app link,
263
- * it will give the link url, otherwise it will give `null`
285
+ * Get the URL that was used to launch the app if it was launched by a link.
286
+ * @return The URL string that launched your app, or `null`.
264
287
  */
265
288
  export async function getInitialURL() {
266
289
  return (await NativeLinking.getInitialURL()) ?? null;
267
290
  }
291
+ // @needsAudit
268
292
  /**
269
- * Try to open the given `url` with any of the installed apps.
293
+ * Attempt to open the given URL with an installed app. See the [Linking guide](/guides/linking)
294
+ * for more information.
295
+ * @param url A URL for the operating system to open, eg: `tel:5555555`, `exp://`.
296
+ * @return A `Promise` that is fulfilled with `true` if the link is opened operating system
297
+ * automatically or the user confirms the prompt to open the link. The `Promise` rejects if there
298
+ * are no applications registered for the URL or the user cancels the dialog.
270
299
  */
271
300
  export async function openURL(url) {
272
301
  validateURL(url);
273
302
  return await NativeLinking.openURL(url);
274
303
  }
304
+ // @needsAudit
275
305
  /**
276
306
  * Determine whether or not an installed app can handle a given URL.
277
- * On web this always returns true because there is no API for detecting what URLs can be opened.
307
+ * On web this always returns `true` because there is no API for detecting what URLs can be opened.
308
+ * @param url The URL that you want to test can be opened.
309
+ * @return A `Promise` object that is fulfilled with `true` if the URL can be handled, otherwise it
310
+ * `false` if not.
311
+ *
312
+ * The `Promise` will reject on Android if it was impossible to check if the URL can be opened, and
313
+ * on iOS if you didn't [add the specific scheme in the `LSApplicationQueriesSchemes` key inside **Info.plist**](/guides/linking#opening-links-to-other-apps).
278
314
  */
279
315
  export async function canOpenURL(url) {
280
316
  validateURL(url);
281
317
  return await NativeLinking.canOpenURL(url);
282
318
  }
319
+ // @needsAudit
283
320
  /**
284
321
  * Returns the initial URL followed by any subsequent changes to the URL.
322
+ * @return Returns the initial URL or `null`.
285
323
  */
286
324
  export function useURL() {
287
325
  const [url, setLink] = useState(null);
@@ -289,19 +327,11 @@ export function useURL() {
289
327
  setLink(event.url);
290
328
  }
291
329
  useEffect(() => {
292
- getInitialURL().then(url => setLink(url));
330
+ getInitialURL().then((url) => setLink(url));
293
331
  addEventListener('url', onChange);
294
332
  return () => removeEventListener('url', onChange);
295
333
  }, []);
296
334
  return url;
297
335
  }
298
- /**
299
- * Returns the initial URL followed by any subsequent changes to the URL.
300
- * @deprecated Use `useURL` instead.
301
- */
302
- export function useUrl() {
303
- console.warn(`Linking.useUrl has been deprecated in favor of Linking.useURL. This API will be removed in SDK 44.`);
304
- return useURL();
305
- }
306
336
  export * from './Linking.types';
307
337
  //# sourceMappingURL=Linking.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Linking.js","sourceRoot":"","sources":["../src/Linking.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,SAAS,MAAM,gBAAgB,CAAC;AACvC,OAAO,SAAS,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,GAAG,MAAM,WAAW,CAAC;AAE5B,OAAO,aAAa,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE3D,SAAS,WAAW,CAAC,GAAW;IAC9B,SAAS,CAAC,OAAO,GAAG,KAAK,QAAQ,EAAE,wCAAwC,GAAG,GAAG,CAAC,CAAC;IACnF,SAAS,CAAC,GAAG,EAAE,8BAA8B,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,UAAU;IACjB,IAAI,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE;QAC/B,OAAO,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC;KACnC;SAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,IAAI,CAAC,eAAe,EAAE,EAAE;QAC7D,mEAAmE;QACnE,gFAAgF;QAChF,OAAO,YAAY,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;KACxE;SAAM;QACL,OAAO,IAAI,CAAC;KACb;AACH,CAAC;AAED,SAAS,YAAY;IACnB,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,OAAO,CAAC,CAAC,CACP,OAAO;QACP,CAAC,mEAAmE,CAAC,IAAI,CAAC,OAAO,CAAC;YAChF,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,CACjC,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,GAAW;IAC/B,OAAO,GAAG,CAAC,OAAO,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,UAAU,CAAC,GAAW;IAC7B,OAAO,GAAG,CAAC,OAAO,CAAC,qCAAqC,EAAE,EAAE,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,kBAAkB,CAAC,GAAW;IACrC,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,iCAAiC,CAAC,GAAW;IACpD,OAAO,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAa,EAAE,YAAqB;IAC9D,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,QAAQ,IAAI,CAAC,YAAY,EAAE;QAC7B,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;KAC7C;SAAM,IAAI,CAAC,QAAQ,IAAI,YAAY,EAAE;QACpC,OAAO,GAAG,KAAK,GAAG,CAAC;KACpB;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAa,EAAE,YAAqB;IAC/D,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACvC,IAAI,QAAQ,IAAI,CAAC,YAAY,EAAE;QAC7B,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;KAC3B;SAAM,IAAI,CAAC,QAAQ,IAAI,YAAY,EAAE;QACpC,OAAO,IAAI,KAAK,EAAE,CAAC;KACpB;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,OAAO,CAAC,OAAe,EAAE,EAAE,WAAyB,EAAE,MAAe;IACnF,OAAO,SAAS,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC;AACzE,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,SAAS,CACvB,IAAY,EACZ,EAAE,MAAM,EAAE,WAAW,GAAG,EAAE,EAAE,eAAe,GAAG,KAAK,KAAuB,EAAE;IAE5E,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE;QACzB,IAAI,CAAC,QAAQ,CAAC,cAAc;YAAE,OAAO,EAAE,CAAC;QAExC,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACjE,IAAI,WAAW,GAAG,EAAE,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC5C,IAAI,WAAW,EAAE;YACf,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;SACjC;QAED,IAAI,UAAU,GAAG,IAAI,CAAC;QACtB,IAAI,UAAU;YAAE,UAAU,GAAG,mBAAmB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAE7D,OAAO,SAAS,CAAC,GAAG,MAAM,GAAG,UAAU,GAAG,WAAW,EAAE,CAAC,CAAC;KAC1D;IAED,MAAM,cAAc,GAAG,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IAEjD,IAAI,OAAO,GAAG,UAAU,EAAE,IAAI,EAAE,CAAC;IAEjC,IAAI,eAAe,EAAE,IAAI,YAAY,EAAE,EAAE;QACvC,OAAO,GAAG,EAAE,CAAC;KACd;IAED,IAAI,IAAI,EAAE;QACR,IAAI,YAAY,EAAE,IAAI,OAAO,EAAE;YAC7B,IAAI,GAAG,OAAO,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;SAC1C;QACD,IAAI,eAAe,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;YAC5C,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;SACnB;KACF;SAAM;QACL,IAAI,GAAG,EAAE,CAAC;KACX;IAED,6EAA6E;IAC7E,uBAAuB;IACvB,IAAI,WAAW,GAAG,EAAE,CAAC;IACrB,MAAM,sBAAsB,GAAG,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAC3D,IAAI,sBAAsB,EAAE;QAC1B,OAAO,GAAG,sBAAsB,CAAC,CAAC,CAAC,CAAC;QACpC,WAAW,GAAG,sBAAsB,CAAC,CAAC,CAAC,CAAC;QACxC,IAAI,iBAAiB,GAAG,EAAE,CAAC;QAC3B,IAAI;YACF,MAAM,YAAY,GAAG,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAC3C,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE;gBACpC,iBAAiB,GAAG,YAAY,CAAC;aAClC;SACF;QAAC,OAAO,CAAC,EAAE,GAAE;QACd,WAAW,GAAG;YACZ,GAAG,WAAW;YACd,GAAG,iBAAiB;SACrB,CAAC;KACH;IACD,WAAW,GAAG,EAAE,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IACxC,IAAI,WAAW,EAAE;QACf,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;KACjC;IAED,OAAO,GAAG,mBAAmB,CAAC,OAAO,EAAE,CAAC,eAAe,CAAC,CAAC;IAEzD,OAAO,SAAS,CACd,GAAG,cAAc,IAAI,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,OAAO,GAAG,IAAI,GAAG,WAAW,EAAE,CAClF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,GAAW;IAC/B,WAAW,CAAC,GAAG,CAAC,CAAC;IAEjB,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,EAAE,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAErD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,KAAK,EAAE;QAChC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAE,CAAC,CAAC;KAChE;IACD,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC;IAEjC,MAAM,OAAO,GAAG,UAAU,EAAE,IAAI,EAAE,CAAC;IACnC,MAAM,eAAe,GAAG,UAAU,CAAC,iCAAiC,CAAC,OAAO,CAAC,CAAC,CAAC;IAE/E,IAAI,IAAI,GAAG,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC;IACnC,IAAI,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC;IACvC,IAAI,MAAM,GAAG,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC;IAErC,IAAI,MAAM,EAAE;QACV,sBAAsB;QACtB,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;KACjD;IAED,IAAI,IAAI,EAAE;QACR,IAAI,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAEhC,IAAI,UAAU,GAAkB,IAAI,CAAC;QACrC,IAAI,eAAe,EAAE;YACnB,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACzC,UAAU,GAAG,KAAK;iBACf,KAAK,CAAC,CAAC,CAAC;iBACR,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC;iBACf,IAAI,CAAC,GAAG,CAAC,CAAC;SACd;QAED,IAAI,YAAY,EAAE,IAAI,CAAC,eAAe,EAAE,IAAI,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE;YACrF,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YACzC,QAAQ,GAAG,IAAI,CAAC;SACjB;aAAM,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE;YACjC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;SAC9C;KACF;IAED,OAAO;QACL,QAAQ;QACR,IAAI;QACJ,WAAW;QACX,MAAM;KACP,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,OAAoB;IACjE,aAAa,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAChD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,OAAoB;IACpE,aAAa,CAAC,mBAAmB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACnD,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,aAAa,EAAE,CAAC;IACvD,IAAI,CAAC,UAAU,EAAE;QACf,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,IAAI;YACV,WAAW,EAAE,IAAI;SAClB,CAAC;KACH;IAED,OAAO,KAAK,CAAC,UAAU,CAAC,CAAC;AAC3B,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,MAAc,EACd,MAA4D;IAE5D,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE;QAC7B,OAAO,MAAM,aAAa,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACvD;IACD,MAAM,IAAI,mBAAmB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;AACzD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE;QACzB,MAAM,IAAI,mBAAmB,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;KAC1D;IACD,IAAI,aAAa,CAAC,YAAY,EAAE;QAC9B,OAAO,MAAM,aAAa,CAAC,YAAY,EAAE,CAAC;KAC3C;IACD,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,OAAO,CAAC,MAAM,aAAa,CAAC,aAAa,EAAE,CAAC,IAAI,IAAI,CAAC;AACvD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,GAAW;IACvC,WAAW,CAAC,GAAG,CAAC,CAAC;IACjB,OAAO,MAAM,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;AAC1C,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW;IAC1C,WAAW,CAAC,GAAG,CAAC,CAAC;IACjB,OAAO,MAAM,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AAC7C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,MAAM;IACpB,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAErD,SAAS,QAAQ,CAAC,KAAsB;QACtC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IAED,SAAS,CAAC,GAAG,EAAE;QACb,aAAa,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1C,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAClC,OAAO,GAAG,EAAE,CAAC,mBAAmB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACpD,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,MAAM;IACpB,OAAO,CAAC,IAAI,CACV,oGAAoG,CACrG,CAAC;IACF,OAAO,MAAM,EAAE,CAAC;AAClB,CAAC;AAED,cAAc,iBAAiB,CAAC","sourcesContent":["import { Platform, UnavailabilityError } from '@unimodules/core';\nimport Constants from 'expo-constants';\nimport invariant from 'invariant';\nimport qs from 'qs';\nimport { useEffect, useState } from 'react';\nimport URL from 'url-parse';\n\nimport NativeLinking from './ExpoLinking';\nimport { CreateURLOptions, ParsedURL, QueryParams, URLListener } from './Linking.types';\nimport { hasCustomScheme, resolveScheme } from './Schemes';\n\nfunction validateURL(url: string): void {\n invariant(typeof url === 'string', 'Invalid URL: should be a string. Was: ' + url);\n invariant(url, 'Invalid URL: cannot be empty');\n}\n\nfunction getHostUri(): string | null {\n if (Constants.manifest?.hostUri) {\n return Constants.manifest.hostUri;\n } else if (!Constants.manifest?.hostUri && !hasCustomScheme()) {\n // we're probably not using up-to-date xdl, so just fake it for now\n // we have to remove the /--/ on the end since this will be inserted again later\n return removeScheme(Constants.linkingUri).replace(/\\/--($|\\/.*$)/, '');\n } else {\n return null;\n }\n}\n\nfunction isExpoHosted(): boolean {\n const hostUri = getHostUri();\n return !!(\n hostUri &&\n (/^(.*\\.)?(expo\\.io|exp\\.host|exp\\.direct|expo\\.test)(:.*)?(\\/.*)?$/.test(hostUri) ||\n Constants.manifest?.developer)\n );\n}\n\nfunction removeScheme(url: string): string {\n return url.replace(/^[a-zA-Z0-9+.-]+:\\/\\//, '');\n}\n\nfunction removePort(url: string): string {\n return url.replace(/(?=([a-zA-Z0-9+.-]+:\\/\\/)?[^/]):\\d+/, '');\n}\n\nfunction removeLeadingSlash(url: string): string {\n return url.replace(/^\\//, '');\n}\n\nfunction removeTrailingSlashAndQueryString(url: string): string {\n return url.replace(/\\/?\\?.*$/, '');\n}\n\nfunction ensureLeadingSlash(input: string, shouldAppend: boolean): string {\n const hasSlash = input.endsWith('/');\n if (hasSlash && !shouldAppend) {\n return input.substring(0, input.length - 1);\n } else if (!hasSlash && shouldAppend) {\n return `${input}/`;\n }\n return input;\n}\n\nfunction ensureTrailingSlash(input: string, shouldAppend: boolean): string {\n const hasSlash = input.startsWith('/');\n if (hasSlash && !shouldAppend) {\n return input.substring(1);\n } else if (!hasSlash && shouldAppend) {\n return `/${input}`;\n }\n return input;\n}\n\n/**\n * Create a URL that works for the environment the app is currently running in.\n * The scheme in bare and standalone must be defined in the app.json under `expo.scheme`.\n *\n * **Examples**\n *\n * - Bare: empty string\n * - Standalone, Custom: `yourscheme:///path`\n * - Web (dev): `https://localhost:19006/path`\n * - Web (prod): `https://myapp.com/path`\n * - Expo Client (dev): `exp://128.0.0.1:19000/--/path`\n * - Expo Client (prod): `exp://exp.host/@yourname/your-app/--/path`\n *\n * @param path addition path components to append to the base URL.\n * @param queryParams An object of parameters that will be converted into a query string.\n */\nexport function makeUrl(path: string = '', queryParams?: QueryParams, scheme?: string): string {\n return createURL(path, { queryParams, scheme, isTripleSlashed: true });\n}\n\n/**\n * Create a URL that works for the environment the app is currently running in.\n * The scheme in bare and standalone must be defined in the Expo config (app.config.js or app.json) under `expo.scheme`.\n *\n * **Examples**\n *\n * - Bare: `<scheme>://path` -- uses provided scheme or scheme from Expo config `scheme`.\n * - Standalone, Custom: `yourscheme://path`\n * - Web (dev): `https://localhost:19006/path`\n * - Web (prod): `https://myapp.com/path`\n * - Expo Client (dev): `exp://128.0.0.1:19000/--/path`\n * - Expo Client (prod): `exp://exp.host/@yourname/your-app/--/path`\n *\n * @param path addition path components to append to the base URL.\n * @param scheme URI protocol `<scheme>://` that must be built into your native app.\n * @param queryParams An object of parameters that will be converted into a query string.\n */\nexport function createURL(\n path: string,\n { scheme, queryParams = {}, isTripleSlashed = false }: CreateURLOptions = {}\n): string {\n if (Platform.OS === 'web') {\n if (!Platform.isDOMAvailable) return '';\n\n const origin = ensureLeadingSlash(window.location.origin, false);\n let queryString = qs.stringify(queryParams);\n if (queryString) {\n queryString = `?${queryString}`;\n }\n\n let outputPath = path;\n if (outputPath) outputPath = ensureTrailingSlash(path, true);\n\n return encodeURI(`${origin}${outputPath}${queryString}`);\n }\n\n const resolvedScheme = resolveScheme({ scheme });\n\n let hostUri = getHostUri() || '';\n\n if (hasCustomScheme() && isExpoHosted()) {\n hostUri = '';\n }\n\n if (path) {\n if (isExpoHosted() && hostUri) {\n path = `/--/${removeLeadingSlash(path)}`;\n }\n if (isTripleSlashed && !path.startsWith('/')) {\n path = `/${path}`;\n }\n } else {\n path = '';\n }\n\n // merge user-provided query params with any that were already in the hostUri\n // e.g. release-channel\n let queryString = '';\n const queryStringMatchResult = hostUri.match(/(.*)\\?(.+)/);\n if (queryStringMatchResult) {\n hostUri = queryStringMatchResult[1];\n queryString = queryStringMatchResult[2];\n let paramsFromHostUri = {};\n try {\n const parsedParams = qs.parse(queryString);\n if (typeof parsedParams === 'object') {\n paramsFromHostUri = parsedParams;\n }\n } catch (e) {}\n queryParams = {\n ...queryParams,\n ...paramsFromHostUri,\n };\n }\n queryString = qs.stringify(queryParams);\n if (queryString) {\n queryString = `?${queryString}`;\n }\n\n hostUri = ensureTrailingSlash(hostUri, !isTripleSlashed);\n\n return encodeURI(\n `${resolvedScheme}:${isTripleSlashed ? '/' : ''}/${hostUri}${path}${queryString}`\n );\n}\n\n/**\n * Returns the components and query parameters for a given URL.\n *\n * @param url Input URL to parse\n */\nexport function parse(url: string): ParsedURL {\n validateURL(url);\n\n const parsed = URL(url, /* parseQueryString */ true);\n\n for (const param in parsed.query) {\n parsed.query[param] = decodeURIComponent(parsed.query[param]!);\n }\n const queryParams = parsed.query;\n\n const hostUri = getHostUri() || '';\n const hostUriStripped = removePort(removeTrailingSlashAndQueryString(hostUri));\n\n let path = parsed.pathname || null;\n let hostname = parsed.hostname || null;\n let scheme = parsed.protocol || null;\n\n if (scheme) {\n // Remove colon at end\n scheme = scheme.substring(0, scheme.length - 1);\n }\n\n if (path) {\n path = removeLeadingSlash(path);\n\n let expoPrefix: string | null = null;\n if (hostUriStripped) {\n const parts = hostUriStripped.split('/');\n expoPrefix = parts\n .slice(1)\n .concat(['--/'])\n .join('/');\n }\n\n if (isExpoHosted() && !hasCustomScheme() && expoPrefix && path.startsWith(expoPrefix)) {\n path = path.substring(expoPrefix.length);\n hostname = null;\n } else if (path.indexOf('+') > -1) {\n path = path.substring(path.indexOf('+') + 1);\n }\n }\n\n return {\n hostname,\n path,\n queryParams,\n scheme,\n };\n}\n\n/**\n * Add a handler to Linking changes by listening to the `url` event type\n * and providing the handler\n *\n * See https://reactnative.dev/docs/linking.html#addeventlistener\n */\nexport function addEventListener(type: string, handler: URLListener) {\n NativeLinking.addEventListener(type, handler);\n}\n\n/**\n * Remove a handler by passing the `url` event type and the handler.\n *\n * See https://reactnative.dev/docs/linking.html#removeeventlistener\n */\nexport function removeEventListener(type: string, handler: URLListener) {\n NativeLinking.removeEventListener(type, handler);\n}\n\n/**\n * **Native:** Parses the link that opened the app. If no link opened the app, all the fields will be \\`null\\`.\n * **Web:** Parses the current window URL.\n */\nexport async function parseInitialURLAsync(): Promise<ParsedURL> {\n const initialUrl = await NativeLinking.getInitialURL();\n if (!initialUrl) {\n return {\n scheme: null,\n hostname: null,\n path: null,\n queryParams: null,\n };\n }\n\n return parse(initialUrl);\n}\n\n/**\n * Launch an Android intent with optional extras\n *\n * @platform android\n */\nexport async function sendIntent(\n action: string,\n extras?: { key: string; value: string | number | boolean }[]\n): Promise<void> {\n if (Platform.OS === 'android') {\n return await NativeLinking.sendIntent(action, extras);\n }\n throw new UnavailabilityError('Linking', 'sendIntent');\n}\n\n/**\n * Attempt to open the system settings for an the app.\n *\n * @platform ios\n */\nexport async function openSettings(): Promise<void> {\n if (Platform.OS === 'web') {\n throw new UnavailabilityError('Linking', 'openSettings');\n }\n if (NativeLinking.openSettings) {\n return await NativeLinking.openSettings();\n }\n await openURL('app-settings:');\n}\n\n/**\n * If the app launch was triggered by an app link,\n * it will give the link url, otherwise it will give `null`\n */\nexport async function getInitialURL(): Promise<string | null> {\n return (await NativeLinking.getInitialURL()) ?? null;\n}\n\n/**\n * Try to open the given `url` with any of the installed apps.\n */\nexport async function openURL(url: string): Promise<true> {\n validateURL(url);\n return await NativeLinking.openURL(url);\n}\n\n/**\n * Determine whether or not an installed app can handle a given URL.\n * On web this always returns true because there is no API for detecting what URLs can be opened.\n */\nexport async function canOpenURL(url: string): Promise<boolean> {\n validateURL(url);\n return await NativeLinking.canOpenURL(url);\n}\n\n/**\n * Returns the initial URL followed by any subsequent changes to the URL.\n */\nexport function useURL(): string | null {\n const [url, setLink] = useState<string | null>(null);\n\n function onChange(event: { url: string }) {\n setLink(event.url);\n }\n\n useEffect(() => {\n getInitialURL().then(url => setLink(url));\n addEventListener('url', onChange);\n return () => removeEventListener('url', onChange);\n }, []);\n\n return url;\n}\n\n/**\n * Returns the initial URL followed by any subsequent changes to the URL.\n * @deprecated Use `useURL` instead.\n */\nexport function useUrl(): string | null {\n console.warn(\n `Linking.useUrl has been deprecated in favor of Linking.useURL. This API will be removed in SDK 44.`\n );\n return useURL();\n}\n\nexport * from './Linking.types';\n"]}
1
+ {"version":3,"file":"Linking.js","sourceRoot":"","sources":["../src/Linking.ts"],"names":[],"mappings":"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","sourcesContent":["import Constants from 'expo-constants';\nimport { Platform, UnavailabilityError } from 'expo-modules-core';\nimport invariant from 'invariant';\nimport qs from 'qs';\nimport { useEffect, useState } from 'react';\nimport URL from 'url-parse';\n\nimport NativeLinking from './ExpoLinking';\nimport {\n CreateURLOptions,\n ParsedURL,\n QueryParams,\n SendIntentExtras,\n URLListener,\n} from './Linking.types';\nimport { hasCustomScheme, resolveScheme } from './Schemes';\n\nfunction validateURL(url: string): void {\n invariant(typeof url === 'string', 'Invalid URL: should be a string. Was: ' + url);\n invariant(url, 'Invalid URL: cannot be empty');\n}\n\nfunction getHostUri(): string | null {\n if (Constants.manifest?.hostUri) {\n return Constants.manifest.hostUri;\n } else if (Constants.manifest2?.extra?.expoClient?.hostUri) {\n return Constants.manifest2.extra.expoClient.hostUri;\n } else if (!hasCustomScheme()) {\n // we're probably not using up-to-date xdl, so just fake it for now\n // we have to remove the /--/ on the end since this will be inserted again later\n return removeScheme(Constants.linkingUri).replace(/\\/--($|\\/.*$)/, '');\n } else {\n return null;\n }\n}\n\nfunction isExpoHosted(): boolean {\n const hostUri = getHostUri();\n return !!(\n hostUri &&\n (/^(.*\\.)?(expo\\.io|exp\\.host|exp\\.direct|expo\\.test)(:.*)?(\\/.*)?$/.test(hostUri) ||\n Constants.manifest?.developer)\n );\n}\n\nfunction removeScheme(url: string): string {\n return url.replace(/^[a-zA-Z0-9+.-]+:\\/\\//, '');\n}\n\nfunction removePort(url: string): string {\n return url.replace(/(?=([a-zA-Z0-9+.-]+:\\/\\/)?[^/]):\\d+/, '');\n}\n\nfunction removeLeadingSlash(url: string): string {\n return url.replace(/^\\//, '');\n}\n\nfunction removeTrailingSlashAndQueryString(url: string): string {\n return url.replace(/\\/?\\?.*$/, '');\n}\n\nfunction ensureTrailingSlash(input: string, shouldAppend: boolean): string {\n const hasSlash = input.endsWith('/');\n if (hasSlash && !shouldAppend) {\n return input.substring(0, input.length - 1);\n } else if (!hasSlash && shouldAppend) {\n return `${input}/`;\n }\n return input;\n}\n\nfunction ensureLeadingSlash(input: string, shouldAppend: boolean): string {\n const hasSlash = input.startsWith('/');\n if (hasSlash && !shouldAppend) {\n return input.substring(1);\n } else if (!hasSlash && shouldAppend) {\n return `/${input}`;\n }\n return input;\n}\n\n// @needsAudit\n/**\n * Create a URL that works for the environment the app is currently running in.\n * The scheme in bare and standalone must be defined in the app.json under `expo.scheme`.\n *\n * # Examples\n * - Bare: empty string\n * - Standalone, Custom: `yourscheme:///path`\n * - Web (dev): `https://localhost:19006/path`\n * - Web (prod): `https://myapp.com/path`\n * - Expo Client (dev): `exp://128.0.0.1:19000/--/path`\n * - Expo Client (prod): `exp://exp.host/@yourname/your-app/--/path`\n *\n * @param path addition path components to append to the base URL.\n * @param queryParams An object with a set of query parameters. These will be merged with any\n * Expo-specific parameters that are needed (e.g. release channel) and then appended to the URL\n * as a query string.\n * @param scheme Optional URI protocol to use in the URL `<scheme>:///`, when `undefined` the scheme\n * will be chosen from the Expo config (`app.config.js` or `app.json`).\n * @return A URL string which points to your app with the given deep link information.\n * @deprecated An alias for [`createURL()`](#linkingcreateurlpath-namedparameters). This method is\n * deprecated and will be removed in a future SDK version.\n */\nexport function makeUrl(path: string = '', queryParams?: QueryParams, scheme?: string): string {\n return createURL(path, { queryParams, scheme, isTripleSlashed: true });\n}\n\n// @needsAudit\n/**\n * Helper method for constructing a deep link into your app, given an optional path and set of query\n * parameters. Creates a URI scheme with two slashes by default.\n *\n * The scheme in bare and standalone must be defined in the Expo config (`app.config.js` or `app.json`)\n * under `expo.scheme`.\n *\n * # Examples\n * - Bare: `<scheme>://path` - uses provided scheme or scheme from Expo config `scheme`.\n * - Standalone, Custom: `yourscheme://path`\n * - Web (dev): `https://localhost:19006/path`\n * - Web (prod): `https://myapp.com/path`\n * - Expo Client (dev): `exp://128.0.0.1:19000/--/path`\n * - Expo Client (prod): `exp://exp.host/@yourname/your-app/--/path`\n *\n * @param path Addition path components to append to the base URL.\n * @param namedParameters Additional options object.\n * @return A URL string which points to your app with the given deep link information.\n */\nexport function createURL(\n path: string,\n { scheme, queryParams = {}, isTripleSlashed = false }: CreateURLOptions = {}\n): string {\n if (Platform.OS === 'web') {\n if (!Platform.isDOMAvailable) return '';\n\n const origin = ensureTrailingSlash(window.location.origin, false);\n let queryString = qs.stringify(queryParams);\n if (queryString) {\n queryString = `?${queryString}`;\n }\n\n let outputPath = path;\n if (outputPath) outputPath = ensureLeadingSlash(path, true);\n\n return encodeURI(`${origin}${outputPath}${queryString}`);\n }\n\n const resolvedScheme = resolveScheme({ scheme });\n\n let hostUri = getHostUri() || '';\n\n if (hasCustomScheme() && isExpoHosted()) {\n hostUri = '';\n }\n\n if (path) {\n if (isExpoHosted() && hostUri) {\n path = `/--/${removeLeadingSlash(path)}`;\n }\n if (isTripleSlashed && !path.startsWith('/')) {\n path = `/${path}`;\n }\n } else {\n path = '';\n }\n\n // merge user-provided query params with any that were already in the hostUri\n // e.g. release-channel\n let queryString = '';\n const queryStringMatchResult = hostUri.match(/(.*)\\?(.+)/);\n if (queryStringMatchResult) {\n hostUri = queryStringMatchResult[1];\n queryString = queryStringMatchResult[2];\n let paramsFromHostUri = {};\n try {\n const parsedParams = qs.parse(queryString);\n if (typeof parsedParams === 'object') {\n paramsFromHostUri = parsedParams;\n }\n } catch (e) {}\n queryParams = {\n ...queryParams,\n ...paramsFromHostUri,\n };\n }\n queryString = qs.stringify(queryParams);\n if (queryString) {\n queryString = `?${queryString}`;\n }\n\n hostUri = ensureLeadingSlash(hostUri, !isTripleSlashed);\n\n return encodeURI(\n `${resolvedScheme}:${isTripleSlashed ? '/' : ''}/${hostUri}${path}${queryString}`\n );\n}\n\n// @needsAudit\n/**\n * Helper method for parsing out deep link information from a URL.\n * @param url A URL that points to the currently running experience (e.g. an output of `Linking.createURL()`).\n * @return A `ParsedURL` object.\n */\nexport function parse(url: string): ParsedURL {\n validateURL(url);\n\n const parsed = URL(url, /* parseQueryString */ true);\n\n for (const param in parsed.query) {\n parsed.query[param] = decodeURIComponent(parsed.query[param]!);\n }\n const queryParams = parsed.query;\n\n const hostUri = getHostUri() || '';\n const hostUriStripped = removePort(removeTrailingSlashAndQueryString(hostUri));\n\n let path = parsed.pathname || null;\n let hostname = parsed.hostname || null;\n let scheme = parsed.protocol || null;\n\n if (scheme) {\n // Remove colon at end\n scheme = scheme.substring(0, scheme.length - 1);\n }\n\n if (path) {\n path = removeLeadingSlash(path);\n\n let expoPrefix: string | null = null;\n if (hostUriStripped) {\n const parts = hostUriStripped.split('/');\n expoPrefix = parts.slice(1).concat(['--/']).join('/');\n }\n\n if (isExpoHosted() && !hasCustomScheme() && expoPrefix && path.startsWith(expoPrefix)) {\n path = path.substring(expoPrefix.length);\n hostname = null;\n } else if (path.indexOf('+') > -1) {\n path = path.substring(path.indexOf('+') + 1);\n }\n }\n\n return {\n hostname,\n path,\n queryParams,\n scheme,\n };\n}\n\n// @needsAudit\n/**\n * Add a handler to `Linking` changes by listening to the `url` event type and providing the handler.\n * It is recommended to use the [`useURL()`](#useurl) hook instead.\n * @param type The only valid type is `'url'`.\n * @param handler An [`URLListener`](#urllistener) function that takes an `event` object of the type\n * [`EventType`](#eventype).\n * @see [React Native Docs Linking page](https://reactnative.dev/docs/linking#addeventlistener).\n */\nexport function addEventListener(type: string, handler: URLListener): void {\n NativeLinking.addEventListener(type, handler);\n}\n\n/**\n * Remove a handler by passing the `url` event type and the handler.\n * @param type The only valid type is `'url'`.\n * @param handler An [`URLListener`](#urllistener) function that takes an `event` object of the type\n * [`EventType`](#eventype).\n * @see [React Native Docs Linking page](https://reactnative.dev/docs/linking#removeeventlistener).\n */\nexport function removeEventListener(type: string, handler: URLListener): void {\n NativeLinking.removeEventListener(type, handler);\n}\n\n// @needsAudit\n/**\n * Helper method which wraps React Native's `Linking.getInitialURL()` in `Linking.parse()`.\n * Parses the deep link information out of the URL used to open the experience initially.\n * If no link opened the app, all the fields will be `null`.\n * > On the web it parses the current window URL.\n * @return A promise that resolves with `ParsedURL` object.\n */\nexport async function parseInitialURLAsync(): Promise<ParsedURL> {\n const initialUrl = await NativeLinking.getInitialURL();\n if (!initialUrl) {\n return {\n scheme: null,\n hostname: null,\n path: null,\n queryParams: null,\n };\n }\n\n return parse(initialUrl);\n}\n\n// @needsAudit\n/**\n * Launch an Android intent with extras.\n * > Use [IntentLauncher](../intent-launcher) instead, `sendIntent` is only included in\n * > `Linking` for API compatibility with React Native's Linking API.\n * @platform android\n */\nexport async function sendIntent(action: string, extras?: SendIntentExtras[]): Promise<void> {\n if (Platform.OS === 'android') {\n return await NativeLinking.sendIntent(action, extras);\n }\n throw new UnavailabilityError('Linking', 'sendIntent');\n}\n\n// @needsAudit\n/**\n * Open the operating system settings app and displays the app’s custom settings, if it has any.\n * @platform ios\n */\nexport async function openSettings(): Promise<void> {\n if (Platform.OS === 'web') {\n throw new UnavailabilityError('Linking', 'openSettings');\n }\n if (NativeLinking.openSettings) {\n return await NativeLinking.openSettings();\n }\n await openURL('app-settings:');\n}\n\n// @needsAudit\n/**\n * Get the URL that was used to launch the app if it was launched by a link.\n * @return The URL string that launched your app, or `null`.\n */\nexport async function getInitialURL(): Promise<string | null> {\n return (await NativeLinking.getInitialURL()) ?? null;\n}\n\n// @needsAudit\n/**\n * Attempt to open the given URL with an installed app. See the [Linking guide](/guides/linking)\n * for more information.\n * @param url A URL for the operating system to open, eg: `tel:5555555`, `exp://`.\n * @return A `Promise` that is fulfilled with `true` if the link is opened operating system\n * automatically or the user confirms the prompt to open the link. The `Promise` rejects if there\n * are no applications registered for the URL or the user cancels the dialog.\n */\nexport async function openURL(url: string): Promise<true> {\n validateURL(url);\n return await NativeLinking.openURL(url);\n}\n\n// @needsAudit\n/**\n * Determine whether or not an installed app can handle a given URL.\n * On web this always returns `true` because there is no API for detecting what URLs can be opened.\n * @param url The URL that you want to test can be opened.\n * @return A `Promise` object that is fulfilled with `true` if the URL can be handled, otherwise it\n * `false` if not.\n *\n * The `Promise` will reject on Android if it was impossible to check if the URL can be opened, and\n * on iOS if you didn't [add the specific scheme in the `LSApplicationQueriesSchemes` key inside **Info.plist**](/guides/linking#opening-links-to-other-apps).\n */\nexport async function canOpenURL(url: string): Promise<boolean> {\n validateURL(url);\n return await NativeLinking.canOpenURL(url);\n}\n\n// @needsAudit\n/**\n * Returns the initial URL followed by any subsequent changes to the URL.\n * @return Returns the initial URL or `null`.\n */\nexport function useURL(): string | null {\n const [url, setLink] = useState<string | null>(null);\n\n function onChange(event: { url: string }) {\n setLink(event.url);\n }\n\n useEffect(() => {\n getInitialURL().then((url) => setLink(url));\n addEventListener('url', onChange);\n return () => removeEventListener('url', onChange);\n }, []);\n\n return url;\n}\n\nexport * from './Linking.types';\n"]}
@@ -3,7 +3,13 @@ export declare type QueryParams = ParsedQs;
3
3
  export declare type ParsedURL = {
4
4
  scheme: string | null;
5
5
  hostname: string | null;
6
+ /**
7
+ * The path into the app specified by the URL.
8
+ */
6
9
  path: string | null;
10
+ /**
11
+ * The set of query parameters specified by the query string of the url used to open the app.
12
+ */
7
13
  queryParams: QueryParams | null;
8
14
  };
9
15
  export declare type CreateURLOptions = {
@@ -26,3 +32,7 @@ export declare type EventType = {
26
32
  };
27
33
  export declare type URLListener = (event: EventType) => void;
28
34
  export declare type NativeURLListener = (nativeEvent: MessageEvent) => void;
35
+ export declare type SendIntentExtras = {
36
+ key: string;
37
+ value: string | number | boolean;
38
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"Linking.types.js","sourceRoot":"","sources":["../src/Linking.types.ts"],"names":[],"mappings":"","sourcesContent":["import { ParsedQs } from 'qs';\n\nexport type QueryParams = ParsedQs;\n\nexport type ParsedURL = {\n scheme: string | null;\n hostname: string | null;\n path: string | null;\n queryParams: QueryParams | null;\n};\n\nexport type CreateURLOptions = {\n /**\n * URI protocol `<scheme>://` that must be built into your native app.\n */\n scheme?: string;\n /**\n * An object of parameters that will be converted into a query string.\n */\n queryParams?: QueryParams;\n /**\n * Should the URI be triple slashed `scheme:///path` or double slashed `scheme://path`.\n */\n isTripleSlashed?: boolean;\n};\n\nexport type EventType = { url: string; nativeEvent?: MessageEvent };\n\nexport type URLListener = (event: EventType) => void;\n\nexport type NativeURLListener = (nativeEvent: MessageEvent) => void;\n"]}
1
+ {"version":3,"file":"Linking.types.js","sourceRoot":"","sources":["../src/Linking.types.ts"],"names":[],"mappings":"","sourcesContent":["import { ParsedQs } from 'qs';\n\n// @docsMissing\nexport type QueryParams = ParsedQs;\n\n// @needsAudit @docsMissing\nexport type ParsedURL = {\n scheme: string | null;\n hostname: string | null;\n /**\n * The path into the app specified by the URL.\n */\n path: string | null;\n /**\n * The set of query parameters specified by the query string of the url used to open the app.\n */\n queryParams: QueryParams | null;\n};\n\n// @needsAudit\nexport type CreateURLOptions = {\n /**\n * URI protocol `<scheme>://` that must be built into your native app.\n */\n scheme?: string;\n /**\n * An object of parameters that will be converted into a query string.\n */\n queryParams?: QueryParams;\n /**\n * Should the URI be triple slashed `scheme:///path` or double slashed `scheme://path`.\n */\n isTripleSlashed?: boolean;\n};\n\n// @docsMissing\nexport type EventType = {\n url: string;\n nativeEvent?: MessageEvent;\n};\n\n// @docsMissing\nexport type URLListener = (event: EventType) => void;\n\n// @docsMissing\nexport type NativeURLListener = (nativeEvent: MessageEvent) => void;\n\n// @docsMissing\nexport type SendIntentExtras = { key: string; value: string | number | boolean };\n"]}
package/build/Schemes.js CHANGED
@@ -1,5 +1,5 @@
1
- import { Platform } from '@unimodules/core';
2
1
  import Constants, { ExecutionEnvironment } from 'expo-constants';
2
+ import { Platform } from 'expo-modules-core';
3
3
  const LINKING_GUIDE_URL = `https://docs.expo.io/guides/linking/`;
4
4
  export function hasCustomScheme() {
5
5
  if (Constants.executionEnvironment === ExecutionEnvironment.Bare) {
@@ -56,15 +56,18 @@ export function collectManifestSchemes() {
56
56
  // They'll be added when we drop support for `expo build` or decide
57
57
  // to have them only work with `eas build`.
58
58
  const platformManifest = Platform.select({
59
- ios: Constants.manifest?.ios,
60
- android: Constants.manifest?.android,
59
+ ios: Constants.manifest?.ios ?? Constants.manifest2?.extra?.expoClient?.ios,
60
+ android: Constants.manifest?.android ?? Constants.manifest2?.extra?.expoClient?.android,
61
61
  web: {},
62
62
  }) ?? {};
63
- const schemes = getSchemes(Constants.manifest);
63
+ const schemes = getSchemes(Constants.manifest ?? Constants.manifest2?.extra?.expoClient);
64
64
  // Add the detached scheme after the manifest scheme for legacy ExpoKit support.
65
65
  if (Constants.manifest?.detach?.scheme) {
66
66
  schemes.push(Constants.manifest.detach.scheme);
67
67
  }
68
+ if (Constants.manifest2?.extra?.expoClient?.detach?.scheme) {
69
+ schemes.push(Constants.manifest2.extra.expoClient.detach.scheme);
70
+ }
68
71
  // Add the unimplemented platform schemes last.
69
72
  schemes.push(...getSchemes(platformManifest));
70
73
  return schemes;
@@ -73,9 +76,11 @@ function getNativeAppIdScheme() {
73
76
  // Add the native application identifier to the list of schemes for parity with `expo build`.
74
77
  // The native app id has been added to builds for a long time to support Google Sign-In.
75
78
  return (Platform.select({
76
- ios: Constants.manifest?.ios?.bundleIdentifier,
79
+ ios: Constants.manifest?.ios?.bundleIdentifier ??
80
+ Constants.manifest2?.extra?.expoClient?.ios?.bundleIdentifier,
77
81
  // TODO: This may change to android.applicationId in the future.
78
- android: Constants.manifest?.android?.package,
82
+ android: Constants.manifest?.android?.package ??
83
+ Constants.manifest2?.extra?.expoClient?.android?.package,
79
84
  }) ?? null);
80
85
  }
81
86
  export function hasConstantsManifest() {
@@ -120,7 +125,7 @@ export function resolveScheme(props) {
120
125
  // TODO: Will this cause issues for things like Facebook or Google that use `reversed-client-id://` or `fb<FBID>:/`?
121
126
  // Traditionally these APIs don't use the Linking API directly.
122
127
  console.warn(`The provided Linking scheme '${props.scheme}' does not appear in the list of possible URI schemes in your Expo config. Expected one of: ${schemes
123
- .map(scheme => `'${scheme}'`)
128
+ .map((scheme) => `'${scheme}'`)
124
129
  .join(', ')}`);
125
130
  }
126
131
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Schemes.js","sourceRoot":"","sources":["../src/Schemes.ts"],"names":[],"mappings":"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","sourcesContent":["import { Platform } from '@unimodules/core';\nimport Constants, { ExecutionEnvironment } from 'expo-constants';\n\nconst LINKING_GUIDE_URL = `https://docs.expo.io/guides/linking/`;\n\nexport function hasCustomScheme(): boolean {\n if (Constants.executionEnvironment === ExecutionEnvironment.Bare) {\n // Bare always uses a custom scheme.\n return true;\n } else if (Constants.executionEnvironment === ExecutionEnvironment.Standalone) {\n // Standalone uses a custom scheme when one is defined.\n const manifestSchemes = collectManifestSchemes();\n return !!manifestSchemes.length;\n }\n // Store client uses the default scheme.\n return false;\n}\n\ntype SchemeConfig = {\n scheme?: string | string[];\n};\n\nfunction getSchemes(config: SchemeConfig): string[] {\n if (config) {\n if (Array.isArray(config.scheme)) {\n const validate = (value: any): value is string => {\n return typeof value === 'string';\n };\n return config.scheme.filter<string>(validate);\n } else if (typeof config.scheme === 'string') {\n return [config.scheme];\n }\n }\n return [];\n}\n\n// Valid schemes for the Expo client.\nconst EXPO_CLIENT_SCHEMES = Platform.select({\n // Results from `npx uri-scheme list --info-path ios/Exponent/Supporting/Info.plist`\n ios: [\n 'exp',\n 'exps',\n 'fb1696089354000816',\n 'host.exp.exponent',\n 'com.googleusercontent.apps.603386649315-vp4revvrcgrcjme51ebuhbkbspl048l9',\n ],\n // Collected manually\n android: ['exp', 'exps'],\n});\n\n/**\n * Collect a list of platform schemes from the manifest.\n *\n * This method is based on the `Scheme` modules from `@expo/config-plugins`\n * which are used for collecting the schemes before prebuilding a native app.\n *\n * - iOS: scheme -> ios.scheme -> ios.bundleIdentifier\n * - Android: scheme -> android.scheme -> android.package\n */\nexport function collectManifestSchemes(): string[] {\n // ios.scheme, android.scheme, and scheme as an array are not yet added to the\n // Expo config spec, but there's no harm in adding them early.\n // They'll be added when we drop support for `expo build` or decide\n // to have them only work with `eas build`.\n const platformManifest =\n (Platform.select<any>({\n ios: Constants.manifest?.ios,\n android: Constants.manifest?.android,\n web: {},\n }) as SchemeConfig) ?? {};\n\n const schemes = getSchemes(Constants.manifest as any);\n\n // Add the detached scheme after the manifest scheme for legacy ExpoKit support.\n if (Constants.manifest?.detach?.scheme) {\n schemes.push(Constants.manifest.detach.scheme);\n }\n\n // Add the unimplemented platform schemes last.\n schemes.push(...getSchemes(platformManifest));\n\n return schemes;\n}\n\nfunction getNativeAppIdScheme(): string | null {\n // Add the native application identifier to the list of schemes for parity with `expo build`.\n // The native app id has been added to builds for a long time to support Google Sign-In.\n return (\n Platform.select({\n ios: Constants.manifest?.ios?.bundleIdentifier,\n // TODO: This may change to android.applicationId in the future.\n android: Constants.manifest?.android?.package,\n }) ?? null\n );\n}\n\nexport function hasConstantsManifest(): boolean {\n // Ensure the user has linked the expo-constants manifest in bare workflow.\n return (\n !!Object.keys(Constants.manifest ?? {}).length ||\n !!Object.keys(Constants.manifest2 ?? {}).length\n );\n}\n\nexport function resolveScheme(props: { scheme?: string; isSilent?: boolean }): string {\n if (\n Constants.executionEnvironment !== ExecutionEnvironment.StoreClient &&\n !hasConstantsManifest()\n ) {\n throw new Error(\n `expo-linking needs access to the expo-constants manifest (app.json or app.config.js) to determine what URI scheme to use. Setup the manifest and rebuild: https://github.com/expo/expo/blob/master/packages/expo-constants/README.md`\n );\n }\n\n const manifestSchemes = collectManifestSchemes();\n const nativeAppId = getNativeAppIdScheme();\n\n if (!manifestSchemes.length) {\n if (__DEV__ && !props.isSilent) {\n // Assert a config warning if no scheme is setup yet. `isSilent` is used for warnings, but we'll ignore it for exceptions.\n console.warn(\n `Linking requires a build-time setting \\`scheme\\` in the project's Expo config (app.config.js or app.json) for production apps, if it's left blank, your app may crash. The scheme does not apply to development in the Expo client but you should add it as soon as you start working with Linking to avoid creating a broken build. Learn more: ${LINKING_GUIDE_URL}`\n );\n } else if (!__DEV__ || Constants.executionEnvironment !== ExecutionEnvironment.StoreClient) {\n // Throw in production or when not in store client. Use the __DEV__ flag so users can test this functionality with `expo start --no-dev`,\n throw new Error(\n 'Cannot make a deep link into a standalone app with no custom scheme defined'\n );\n }\n }\n\n // In the Expo client...\n if (Constants.executionEnvironment === ExecutionEnvironment.StoreClient) {\n if (props.scheme) {\n // This enables users to use the fb or google redirects on iOS in the Expo client.\n if (EXPO_CLIENT_SCHEMES.includes(props.scheme)) {\n return props.scheme;\n }\n // Silently ignore to make bare workflow development easier.\n }\n // Fallback to the default client scheme.\n return 'exp';\n }\n\n const schemes = [...manifestSchemes, nativeAppId].filter(Boolean);\n\n if (props.scheme) {\n if (__DEV__) {\n // Bare workflow development assertion about the provided scheme matching the Expo config.\n if (!schemes.includes(props.scheme) && !props.isSilent) {\n // TODO: Will this cause issues for things like Facebook or Google that use `reversed-client-id://` or `fb<FBID>:/`?\n // Traditionally these APIs don't use the Linking API directly.\n console.warn(\n `The provided Linking scheme '${\n props.scheme\n }' does not appear in the list of possible URI schemes in your Expo config. Expected one of: ${schemes\n .map(scheme => `'${scheme}'`)\n .join(', ')}`\n );\n }\n }\n // Return the user provided value.\n return props.scheme;\n }\n // If no scheme is provided, we'll guess what the scheme is based on the manifest.\n // This is to attempt to keep managed apps working across expo build and EAS build.\n // EAS build ejects the app before building it so we can assume that the user will\n // be using one of defined schemes.\n\n // If the native app id is the only scheme,\n if (!!nativeAppId && !manifestSchemes.length && !props.isSilent) {\n // Assert a config warning if no scheme is setup yet.\n // This warning only applies to managed workflow EAS apps, as bare workflow\n console.warn(\n `Linking requires a build-time setting \\`scheme\\` in the project's Expo config (app.config.js or app.json) for bare or production apps. Manually providing a \\`scheme\\` property can circumvent this warning. Using native app identifier as the scheme '${nativeAppId}'. Learn more: ${LINKING_GUIDE_URL}`\n );\n return nativeAppId;\n }\n // When the native app id is defined, it'll be added to the list of schemes, for most\n // users this will be unexpected behavior and cause all apps to warn when the Linking API\n // is used without a predefined scheme. For now, if the native app id is defined, require\n // at least one more scheme to be added before throwing a warning.\n // i.e. `scheme: ['foo', 'bar']` (unimplemented functionality).\n const [scheme, ...extraSchemes] = manifestSchemes;\n\n if (!scheme) {\n const errorMessage = `Linking requires a build-time setting \\`scheme\\` in the project's Expo config (app.config.js or app.json) for bare or production apps. Manually providing a \\`scheme\\` property can circumvent this error. Learn more: ${LINKING_GUIDE_URL}`;\n // Throw in production, use the __DEV__ flag so users can test this functionality with `expo start --no-dev`\n throw new Error(errorMessage);\n }\n if (extraSchemes.length && !props.isSilent) {\n console.warn(\n `Linking found multiple possible URI schemes in your Expo config.\\nUsing '${scheme}'. Ignoring: ${[\n ...extraSchemes,\n nativeAppId,\n ]\n .filter(Boolean)\n .join(', ')}.\\nPlease supply the preferred URI scheme to the Linking API.`\n );\n }\n return scheme;\n}\n"]}
1
+ {"version":3,"file":"Schemes.js","sourceRoot":"","sources":["../src/Schemes.ts"],"names":[],"mappings":"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","sourcesContent":["import Constants, { ExecutionEnvironment } from 'expo-constants';\nimport { Platform } from 'expo-modules-core';\n\nconst LINKING_GUIDE_URL = `https://docs.expo.io/guides/linking/`;\n\nexport function hasCustomScheme(): boolean {\n if (Constants.executionEnvironment === ExecutionEnvironment.Bare) {\n // Bare always uses a custom scheme.\n return true;\n } else if (Constants.executionEnvironment === ExecutionEnvironment.Standalone) {\n // Standalone uses a custom scheme when one is defined.\n const manifestSchemes = collectManifestSchemes();\n return !!manifestSchemes.length;\n }\n // Store client uses the default scheme.\n return false;\n}\n\ntype SchemeConfig = {\n scheme?: string | string[];\n};\n\nfunction getSchemes(config: SchemeConfig | null | undefined): string[] {\n if (config) {\n if (Array.isArray(config.scheme)) {\n const validate = (value: any): value is string => {\n return typeof value === 'string';\n };\n return config.scheme.filter<string>(validate);\n } else if (typeof config.scheme === 'string') {\n return [config.scheme];\n }\n }\n return [];\n}\n\n// Valid schemes for the Expo client.\nconst EXPO_CLIENT_SCHEMES = Platform.select({\n // Results from `npx uri-scheme list --info-path ios/Exponent/Supporting/Info.plist`\n ios: [\n 'exp',\n 'exps',\n 'fb1696089354000816',\n 'host.exp.exponent',\n 'com.googleusercontent.apps.603386649315-vp4revvrcgrcjme51ebuhbkbspl048l9',\n ],\n // Collected manually\n android: ['exp', 'exps'],\n});\n\n/**\n * Collect a list of platform schemes from the manifest.\n *\n * This method is based on the `Scheme` modules from `@expo/config-plugins`\n * which are used for collecting the schemes before prebuilding a native app.\n *\n * - iOS: scheme -> ios.scheme -> ios.bundleIdentifier\n * - Android: scheme -> android.scheme -> android.package\n */\nexport function collectManifestSchemes(): string[] {\n // ios.scheme, android.scheme, and scheme as an array are not yet added to the\n // Expo config spec, but there's no harm in adding them early.\n // They'll be added when we drop support for `expo build` or decide\n // to have them only work with `eas build`.\n const platformManifest =\n (Platform.select<any>({\n ios: Constants.manifest?.ios ?? Constants.manifest2?.extra?.expoClient?.ios,\n android: Constants.manifest?.android ?? Constants.manifest2?.extra?.expoClient?.android,\n web: {},\n }) as SchemeConfig) ?? {};\n\n const schemes = getSchemes(Constants.manifest ?? Constants.manifest2?.extra?.expoClient);\n\n // Add the detached scheme after the manifest scheme for legacy ExpoKit support.\n if (Constants.manifest?.detach?.scheme) {\n schemes.push(Constants.manifest.detach.scheme);\n }\n if (Constants.manifest2?.extra?.expoClient?.detach?.scheme) {\n schemes.push(Constants.manifest2.extra.expoClient.detach.scheme);\n }\n\n // Add the unimplemented platform schemes last.\n schemes.push(...getSchemes(platformManifest));\n\n return schemes;\n}\n\nfunction getNativeAppIdScheme(): string | null {\n // Add the native application identifier to the list of schemes for parity with `expo build`.\n // The native app id has been added to builds for a long time to support Google Sign-In.\n return (\n Platform.select({\n ios:\n Constants.manifest?.ios?.bundleIdentifier ??\n Constants.manifest2?.extra?.expoClient?.ios?.bundleIdentifier,\n // TODO: This may change to android.applicationId in the future.\n android:\n Constants.manifest?.android?.package ??\n Constants.manifest2?.extra?.expoClient?.android?.package,\n }) ?? null\n );\n}\n\nexport function hasConstantsManifest(): boolean {\n // Ensure the user has linked the expo-constants manifest in bare workflow.\n return (\n !!Object.keys(Constants.manifest ?? {}).length ||\n !!Object.keys(Constants.manifest2 ?? {}).length\n );\n}\n\nexport function resolveScheme(props: { scheme?: string; isSilent?: boolean }): string {\n if (\n Constants.executionEnvironment !== ExecutionEnvironment.StoreClient &&\n !hasConstantsManifest()\n ) {\n throw new Error(\n `expo-linking needs access to the expo-constants manifest (app.json or app.config.js) to determine what URI scheme to use. Setup the manifest and rebuild: https://github.com/expo/expo/blob/master/packages/expo-constants/README.md`\n );\n }\n\n const manifestSchemes = collectManifestSchemes();\n const nativeAppId = getNativeAppIdScheme();\n\n if (!manifestSchemes.length) {\n if (__DEV__ && !props.isSilent) {\n // Assert a config warning if no scheme is setup yet. `isSilent` is used for warnings, but we'll ignore it for exceptions.\n console.warn(\n `Linking requires a build-time setting \\`scheme\\` in the project's Expo config (app.config.js or app.json) for production apps, if it's left blank, your app may crash. The scheme does not apply to development in the Expo client but you should add it as soon as you start working with Linking to avoid creating a broken build. Learn more: ${LINKING_GUIDE_URL}`\n );\n } else if (!__DEV__ || Constants.executionEnvironment !== ExecutionEnvironment.StoreClient) {\n // Throw in production or when not in store client. Use the __DEV__ flag so users can test this functionality with `expo start --no-dev`,\n throw new Error(\n 'Cannot make a deep link into a standalone app with no custom scheme defined'\n );\n }\n }\n\n // In the Expo client...\n if (Constants.executionEnvironment === ExecutionEnvironment.StoreClient) {\n if (props.scheme) {\n // This enables users to use the fb or google redirects on iOS in the Expo client.\n if (EXPO_CLIENT_SCHEMES.includes(props.scheme)) {\n return props.scheme;\n }\n // Silently ignore to make bare workflow development easier.\n }\n // Fallback to the default client scheme.\n return 'exp';\n }\n\n const schemes = [...manifestSchemes, nativeAppId].filter(Boolean);\n\n if (props.scheme) {\n if (__DEV__) {\n // Bare workflow development assertion about the provided scheme matching the Expo config.\n if (!schemes.includes(props.scheme) && !props.isSilent) {\n // TODO: Will this cause issues for things like Facebook or Google that use `reversed-client-id://` or `fb<FBID>:/`?\n // Traditionally these APIs don't use the Linking API directly.\n console.warn(\n `The provided Linking scheme '${\n props.scheme\n }' does not appear in the list of possible URI schemes in your Expo config. Expected one of: ${schemes\n .map((scheme) => `'${scheme}'`)\n .join(', ')}`\n );\n }\n }\n // Return the user provided value.\n return props.scheme;\n }\n // If no scheme is provided, we'll guess what the scheme is based on the manifest.\n // This is to attempt to keep managed apps working across expo build and EAS build.\n // EAS build ejects the app before building it so we can assume that the user will\n // be using one of defined schemes.\n\n // If the native app id is the only scheme,\n if (!!nativeAppId && !manifestSchemes.length && !props.isSilent) {\n // Assert a config warning if no scheme is setup yet.\n // This warning only applies to managed workflow EAS apps, as bare workflow\n console.warn(\n `Linking requires a build-time setting \\`scheme\\` in the project's Expo config (app.config.js or app.json) for bare or production apps. Manually providing a \\`scheme\\` property can circumvent this warning. Using native app identifier as the scheme '${nativeAppId}'. Learn more: ${LINKING_GUIDE_URL}`\n );\n return nativeAppId;\n }\n // When the native app id is defined, it'll be added to the list of schemes, for most\n // users this will be unexpected behavior and cause all apps to warn when the Linking API\n // is used without a predefined scheme. For now, if the native app id is defined, require\n // at least one more scheme to be added before throwing a warning.\n // i.e. `scheme: ['foo', 'bar']` (unimplemented functionality).\n const [scheme, ...extraSchemes] = manifestSchemes;\n\n if (!scheme) {\n const errorMessage = `Linking requires a build-time setting \\`scheme\\` in the project's Expo config (app.config.js or app.json) for bare or production apps. Manually providing a \\`scheme\\` property can circumvent this error. Learn more: ${LINKING_GUIDE_URL}`;\n // Throw in production, use the __DEV__ flag so users can test this functionality with `expo start --no-dev`\n throw new Error(errorMessage);\n }\n if (extraSchemes.length && !props.isSilent) {\n console.warn(\n `Linking found multiple possible URI schemes in your Expo config.\\nUsing '${scheme}'. Ignoring: ${[\n ...extraSchemes,\n nativeAppId,\n ]\n .filter(Boolean)\n .join(', ')}.\\nPlease supply the preferred URI scheme to the Linking API.`\n );\n }\n return scheme;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-linking",
3
- "version": "2.3.1",
3
+ "version": "3.0.0",
4
4
  "description": "Create and open deep links universally",
5
5
  "main": "build/Linking.js",
6
6
  "types": "build/Linking.d.ts",
@@ -28,11 +28,11 @@
28
28
  },
29
29
  "author": "650 Industries, Inc.",
30
30
  "license": "MIT",
31
- "homepage": "https://docs.expo.io/versions/latest/sdk/linking",
31
+ "homepage": "https://docs.expo.dev/versions/latest/sdk/linking",
32
32
  "dependencies": {
33
- "expo-constants": "~11.0.1",
33
+ "expo-constants": "~13.0.0",
34
34
  "invariant": "^2.2.4",
35
- "qs": "^6.5.0",
35
+ "qs": "^6.9.1",
36
36
  "url-parse": "^1.4.4"
37
37
  },
38
38
  "devDependencies": {
@@ -42,5 +42,5 @@
42
42
  "jest": {
43
43
  "preset": "expo-module-scripts"
44
44
  },
45
- "gitHead": "7f0e39e0f45a4ade0ddb603d50983fad2e831908"
45
+ "gitHead": "2e5c6983b86d5ecfca028ba64002897d8adc2cc4"
46
46
  }
@@ -1,4 +1,4 @@
1
- import { Platform } from '@unimodules/core';
1
+ import { Platform } from 'expo-modules-core';
2
2
  import invariant from 'invariant';
3
3
 
4
4
  import { NativeURLListener, URLListener } from './Linking.types';
@@ -13,7 +13,7 @@ export default {
13
13
  EventTypes.indexOf(type) !== -1,
14
14
  `Linking.addEventListener(): ${type} is not a valid event`
15
15
  );
16
- const nativeListener: NativeURLListener = nativeEvent =>
16
+ const nativeListener: NativeURLListener = (nativeEvent) =>
17
17
  listener({ url: window.location.href, nativeEvent });
18
18
  listeners.push({ listener, nativeListener });
19
19
  window.addEventListener('message', nativeListener, false);
@@ -24,7 +24,7 @@ export default {
24
24
  EventTypes.indexOf(type) !== -1,
25
25
  `Linking.removeEventListener(): ${type} is not a valid event.`
26
26
  );
27
- const listenerIndex = listeners.findIndex(pair => pair.listener === listener);
27
+ const listenerIndex = listeners.findIndex((pair) => pair.listener === listener);
28
28
  invariant(
29
29
  listenerIndex !== -1,
30
30
  'Linking.removeEventListener(): cannot remove an unregistered event listener.'
package/src/Linking.ts CHANGED
@@ -1,12 +1,18 @@
1
- import { Platform, UnavailabilityError } from '@unimodules/core';
2
1
  import Constants from 'expo-constants';
2
+ import { Platform, UnavailabilityError } from 'expo-modules-core';
3
3
  import invariant from 'invariant';
4
4
  import qs from 'qs';
5
5
  import { useEffect, useState } from 'react';
6
6
  import URL from 'url-parse';
7
7
 
8
8
  import NativeLinking from './ExpoLinking';
9
- import { CreateURLOptions, ParsedURL, QueryParams, URLListener } from './Linking.types';
9
+ import {
10
+ CreateURLOptions,
11
+ ParsedURL,
12
+ QueryParams,
13
+ SendIntentExtras,
14
+ URLListener,
15
+ } from './Linking.types';
10
16
  import { hasCustomScheme, resolveScheme } from './Schemes';
11
17
 
12
18
  function validateURL(url: string): void {
@@ -17,7 +23,9 @@ function validateURL(url: string): void {
17
23
  function getHostUri(): string | null {
18
24
  if (Constants.manifest?.hostUri) {
19
25
  return Constants.manifest.hostUri;
20
- } else if (!Constants.manifest?.hostUri && !hasCustomScheme()) {
26
+ } else if (Constants.manifest2?.extra?.expoClient?.hostUri) {
27
+ return Constants.manifest2.extra.expoClient.hostUri;
28
+ } else if (!hasCustomScheme()) {
21
29
  // we're probably not using up-to-date xdl, so just fake it for now
22
30
  // we have to remove the /--/ on the end since this will be inserted again later
23
31
  return removeScheme(Constants.linkingUri).replace(/\/--($|\/.*$)/, '');
@@ -51,7 +59,7 @@ function removeTrailingSlashAndQueryString(url: string): string {
51
59
  return url.replace(/\/?\?.*$/, '');
52
60
  }
53
61
 
54
- function ensureLeadingSlash(input: string, shouldAppend: boolean): string {
62
+ function ensureTrailingSlash(input: string, shouldAppend: boolean): string {
55
63
  const hasSlash = input.endsWith('/');
56
64
  if (hasSlash && !shouldAppend) {
57
65
  return input.substring(0, input.length - 1);
@@ -61,7 +69,7 @@ function ensureLeadingSlash(input: string, shouldAppend: boolean): string {
61
69
  return input;
62
70
  }
63
71
 
64
- function ensureTrailingSlash(input: string, shouldAppend: boolean): string {
72
+ function ensureLeadingSlash(input: string, shouldAppend: boolean): string {
65
73
  const hasSlash = input.startsWith('/');
66
74
  if (hasSlash && !shouldAppend) {
67
75
  return input.substring(1);
@@ -71,12 +79,12 @@ function ensureTrailingSlash(input: string, shouldAppend: boolean): string {
71
79
  return input;
72
80
  }
73
81
 
82
+ // @needsAudit
74
83
  /**
75
84
  * Create a URL that works for the environment the app is currently running in.
76
85
  * The scheme in bare and standalone must be defined in the app.json under `expo.scheme`.
77
86
  *
78
- * **Examples**
79
- *
87
+ * # Examples
80
88
  * - Bare: empty string
81
89
  * - Standalone, Custom: `yourscheme:///path`
82
90
  * - Web (dev): `https://localhost:19006/path`
@@ -85,28 +93,38 @@ function ensureTrailingSlash(input: string, shouldAppend: boolean): string {
85
93
  * - Expo Client (prod): `exp://exp.host/@yourname/your-app/--/path`
86
94
  *
87
95
  * @param path addition path components to append to the base URL.
88
- * @param queryParams An object of parameters that will be converted into a query string.
96
+ * @param queryParams An object with a set of query parameters. These will be merged with any
97
+ * Expo-specific parameters that are needed (e.g. release channel) and then appended to the URL
98
+ * as a query string.
99
+ * @param scheme Optional URI protocol to use in the URL `<scheme>:///`, when `undefined` the scheme
100
+ * will be chosen from the Expo config (`app.config.js` or `app.json`).
101
+ * @return A URL string which points to your app with the given deep link information.
102
+ * @deprecated An alias for [`createURL()`](#linkingcreateurlpath-namedparameters). This method is
103
+ * deprecated and will be removed in a future SDK version.
89
104
  */
90
105
  export function makeUrl(path: string = '', queryParams?: QueryParams, scheme?: string): string {
91
106
  return createURL(path, { queryParams, scheme, isTripleSlashed: true });
92
107
  }
93
108
 
109
+ // @needsAudit
94
110
  /**
95
- * Create a URL that works for the environment the app is currently running in.
96
- * The scheme in bare and standalone must be defined in the Expo config (app.config.js or app.json) under `expo.scheme`.
111
+ * Helper method for constructing a deep link into your app, given an optional path and set of query
112
+ * parameters. Creates a URI scheme with two slashes by default.
97
113
  *
98
- * **Examples**
114
+ * The scheme in bare and standalone must be defined in the Expo config (`app.config.js` or `app.json`)
115
+ * under `expo.scheme`.
99
116
  *
100
- * - Bare: `<scheme>://path` -- uses provided scheme or scheme from Expo config `scheme`.
117
+ * # Examples
118
+ * - Bare: `<scheme>://path` - uses provided scheme or scheme from Expo config `scheme`.
101
119
  * - Standalone, Custom: `yourscheme://path`
102
120
  * - Web (dev): `https://localhost:19006/path`
103
121
  * - Web (prod): `https://myapp.com/path`
104
122
  * - Expo Client (dev): `exp://128.0.0.1:19000/--/path`
105
123
  * - Expo Client (prod): `exp://exp.host/@yourname/your-app/--/path`
106
124
  *
107
- * @param path addition path components to append to the base URL.
108
- * @param scheme URI protocol `<scheme>://` that must be built into your native app.
109
- * @param queryParams An object of parameters that will be converted into a query string.
125
+ * @param path Addition path components to append to the base URL.
126
+ * @param namedParameters Additional options object.
127
+ * @return A URL string which points to your app with the given deep link information.
110
128
  */
111
129
  export function createURL(
112
130
  path: string,
@@ -115,14 +133,14 @@ export function createURL(
115
133
  if (Platform.OS === 'web') {
116
134
  if (!Platform.isDOMAvailable) return '';
117
135
 
118
- const origin = ensureLeadingSlash(window.location.origin, false);
136
+ const origin = ensureTrailingSlash(window.location.origin, false);
119
137
  let queryString = qs.stringify(queryParams);
120
138
  if (queryString) {
121
139
  queryString = `?${queryString}`;
122
140
  }
123
141
 
124
142
  let outputPath = path;
125
- if (outputPath) outputPath = ensureTrailingSlash(path, true);
143
+ if (outputPath) outputPath = ensureLeadingSlash(path, true);
126
144
 
127
145
  return encodeURI(`${origin}${outputPath}${queryString}`);
128
146
  }
@@ -170,17 +188,18 @@ export function createURL(
170
188
  queryString = `?${queryString}`;
171
189
  }
172
190
 
173
- hostUri = ensureTrailingSlash(hostUri, !isTripleSlashed);
191
+ hostUri = ensureLeadingSlash(hostUri, !isTripleSlashed);
174
192
 
175
193
  return encodeURI(
176
194
  `${resolvedScheme}:${isTripleSlashed ? '/' : ''}/${hostUri}${path}${queryString}`
177
195
  );
178
196
  }
179
197
 
198
+ // @needsAudit
180
199
  /**
181
- * Returns the components and query parameters for a given URL.
182
- *
183
- * @param url Input URL to parse
200
+ * Helper method for parsing out deep link information from a URL.
201
+ * @param url A URL that points to the currently running experience (e.g. an output of `Linking.createURL()`).
202
+ * @return A `ParsedURL` object.
184
203
  */
185
204
  export function parse(url: string): ParsedURL {
186
205
  validateURL(url);
@@ -210,10 +229,7 @@ export function parse(url: string): ParsedURL {
210
229
  let expoPrefix: string | null = null;
211
230
  if (hostUriStripped) {
212
231
  const parts = hostUriStripped.split('/');
213
- expoPrefix = parts
214
- .slice(1)
215
- .concat(['--/'])
216
- .join('/');
232
+ expoPrefix = parts.slice(1).concat(['--/']).join('/');
217
233
  }
218
234
 
219
235
  if (isExpoHosted() && !hasCustomScheme() && expoPrefix && path.startsWith(expoPrefix)) {
@@ -232,28 +248,37 @@ export function parse(url: string): ParsedURL {
232
248
  };
233
249
  }
234
250
 
251
+ // @needsAudit
235
252
  /**
236
- * Add a handler to Linking changes by listening to the `url` event type
237
- * and providing the handler
238
- *
239
- * See https://reactnative.dev/docs/linking.html#addeventlistener
253
+ * Add a handler to `Linking` changes by listening to the `url` event type and providing the handler.
254
+ * It is recommended to use the [`useURL()`](#useurl) hook instead.
255
+ * @param type The only valid type is `'url'`.
256
+ * @param handler An [`URLListener`](#urllistener) function that takes an `event` object of the type
257
+ * [`EventType`](#eventype).
258
+ * @see [React Native Docs Linking page](https://reactnative.dev/docs/linking#addeventlistener).
240
259
  */
241
- export function addEventListener(type: string, handler: URLListener) {
260
+ export function addEventListener(type: string, handler: URLListener): void {
242
261
  NativeLinking.addEventListener(type, handler);
243
262
  }
244
263
 
245
264
  /**
246
265
  * Remove a handler by passing the `url` event type and the handler.
247
- *
248
- * See https://reactnative.dev/docs/linking.html#removeeventlistener
266
+ * @param type The only valid type is `'url'`.
267
+ * @param handler An [`URLListener`](#urllistener) function that takes an `event` object of the type
268
+ * [`EventType`](#eventype).
269
+ * @see [React Native Docs Linking page](https://reactnative.dev/docs/linking#removeeventlistener).
249
270
  */
250
- export function removeEventListener(type: string, handler: URLListener) {
271
+ export function removeEventListener(type: string, handler: URLListener): void {
251
272
  NativeLinking.removeEventListener(type, handler);
252
273
  }
253
274
 
275
+ // @needsAudit
254
276
  /**
255
- * **Native:** Parses the link that opened the app. If no link opened the app, all the fields will be \`null\`.
256
- * **Web:** Parses the current window URL.
277
+ * Helper method which wraps React Native's `Linking.getInitialURL()` in `Linking.parse()`.
278
+ * Parses the deep link information out of the URL used to open the experience initially.
279
+ * If no link opened the app, all the fields will be `null`.
280
+ * > On the web it parses the current window URL.
281
+ * @return A promise that resolves with `ParsedURL` object.
257
282
  */
258
283
  export async function parseInitialURLAsync(): Promise<ParsedURL> {
259
284
  const initialUrl = await NativeLinking.getInitialURL();
@@ -269,24 +294,23 @@ export async function parseInitialURLAsync(): Promise<ParsedURL> {
269
294
  return parse(initialUrl);
270
295
  }
271
296
 
297
+ // @needsAudit
272
298
  /**
273
- * Launch an Android intent with optional extras
274
- *
299
+ * Launch an Android intent with extras.
300
+ * > Use [IntentLauncher](../intent-launcher) instead, `sendIntent` is only included in
301
+ * > `Linking` for API compatibility with React Native's Linking API.
275
302
  * @platform android
276
303
  */
277
- export async function sendIntent(
278
- action: string,
279
- extras?: { key: string; value: string | number | boolean }[]
280
- ): Promise<void> {
304
+ export async function sendIntent(action: string, extras?: SendIntentExtras[]): Promise<void> {
281
305
  if (Platform.OS === 'android') {
282
306
  return await NativeLinking.sendIntent(action, extras);
283
307
  }
284
308
  throw new UnavailabilityError('Linking', 'sendIntent');
285
309
  }
286
310
 
311
+ // @needsAudit
287
312
  /**
288
- * Attempt to open the system settings for an the app.
289
- *
313
+ * Open the operating system settings app and displays the app’s custom settings, if it has any.
290
314
  * @platform ios
291
315
  */
292
316
  export async function openSettings(): Promise<void> {
@@ -299,33 +323,49 @@ export async function openSettings(): Promise<void> {
299
323
  await openURL('app-settings:');
300
324
  }
301
325
 
326
+ // @needsAudit
302
327
  /**
303
- * If the app launch was triggered by an app link,
304
- * it will give the link url, otherwise it will give `null`
328
+ * Get the URL that was used to launch the app if it was launched by a link.
329
+ * @return The URL string that launched your app, or `null`.
305
330
  */
306
331
  export async function getInitialURL(): Promise<string | null> {
307
332
  return (await NativeLinking.getInitialURL()) ?? null;
308
333
  }
309
334
 
335
+ // @needsAudit
310
336
  /**
311
- * Try to open the given `url` with any of the installed apps.
337
+ * Attempt to open the given URL with an installed app. See the [Linking guide](/guides/linking)
338
+ * for more information.
339
+ * @param url A URL for the operating system to open, eg: `tel:5555555`, `exp://`.
340
+ * @return A `Promise` that is fulfilled with `true` if the link is opened operating system
341
+ * automatically or the user confirms the prompt to open the link. The `Promise` rejects if there
342
+ * are no applications registered for the URL or the user cancels the dialog.
312
343
  */
313
344
  export async function openURL(url: string): Promise<true> {
314
345
  validateURL(url);
315
346
  return await NativeLinking.openURL(url);
316
347
  }
317
348
 
349
+ // @needsAudit
318
350
  /**
319
351
  * Determine whether or not an installed app can handle a given URL.
320
- * On web this always returns true because there is no API for detecting what URLs can be opened.
352
+ * On web this always returns `true` because there is no API for detecting what URLs can be opened.
353
+ * @param url The URL that you want to test can be opened.
354
+ * @return A `Promise` object that is fulfilled with `true` if the URL can be handled, otherwise it
355
+ * `false` if not.
356
+ *
357
+ * The `Promise` will reject on Android if it was impossible to check if the URL can be opened, and
358
+ * on iOS if you didn't [add the specific scheme in the `LSApplicationQueriesSchemes` key inside **Info.plist**](/guides/linking#opening-links-to-other-apps).
321
359
  */
322
360
  export async function canOpenURL(url: string): Promise<boolean> {
323
361
  validateURL(url);
324
362
  return await NativeLinking.canOpenURL(url);
325
363
  }
326
364
 
365
+ // @needsAudit
327
366
  /**
328
367
  * Returns the initial URL followed by any subsequent changes to the URL.
368
+ * @return Returns the initial URL or `null`.
329
369
  */
330
370
  export function useURL(): string | null {
331
371
  const [url, setLink] = useState<string | null>(null);
@@ -335,7 +375,7 @@ export function useURL(): string | null {
335
375
  }
336
376
 
337
377
  useEffect(() => {
338
- getInitialURL().then(url => setLink(url));
378
+ getInitialURL().then((url) => setLink(url));
339
379
  addEventListener('url', onChange);
340
380
  return () => removeEventListener('url', onChange);
341
381
  }, []);
@@ -343,15 +383,4 @@ export function useURL(): string | null {
343
383
  return url;
344
384
  }
345
385
 
346
- /**
347
- * Returns the initial URL followed by any subsequent changes to the URL.
348
- * @deprecated Use `useURL` instead.
349
- */
350
- export function useUrl(): string | null {
351
- console.warn(
352
- `Linking.useUrl has been deprecated in favor of Linking.useURL. This API will be removed in SDK 44.`
353
- );
354
- return useURL();
355
- }
356
-
357
386
  export * from './Linking.types';
@@ -1,14 +1,23 @@
1
1
  import { ParsedQs } from 'qs';
2
2
 
3
+ // @docsMissing
3
4
  export type QueryParams = ParsedQs;
4
5
 
6
+ // @needsAudit @docsMissing
5
7
  export type ParsedURL = {
6
8
  scheme: string | null;
7
9
  hostname: string | null;
10
+ /**
11
+ * The path into the app specified by the URL.
12
+ */
8
13
  path: string | null;
14
+ /**
15
+ * The set of query parameters specified by the query string of the url used to open the app.
16
+ */
9
17
  queryParams: QueryParams | null;
10
18
  };
11
19
 
20
+ // @needsAudit
12
21
  export type CreateURLOptions = {
13
22
  /**
14
23
  * URI protocol `<scheme>://` that must be built into your native app.
@@ -24,8 +33,17 @@ export type CreateURLOptions = {
24
33
  isTripleSlashed?: boolean;
25
34
  };
26
35
 
27
- export type EventType = { url: string; nativeEvent?: MessageEvent };
36
+ // @docsMissing
37
+ export type EventType = {
38
+ url: string;
39
+ nativeEvent?: MessageEvent;
40
+ };
28
41
 
42
+ // @docsMissing
29
43
  export type URLListener = (event: EventType) => void;
30
44
 
45
+ // @docsMissing
31
46
  export type NativeURLListener = (nativeEvent: MessageEvent) => void;
47
+
48
+ // @docsMissing
49
+ export type SendIntentExtras = { key: string; value: string | number | boolean };
package/src/Schemes.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { Platform } from '@unimodules/core';
2
1
  import Constants, { ExecutionEnvironment } from 'expo-constants';
2
+ import { Platform } from 'expo-modules-core';
3
3
 
4
4
  const LINKING_GUIDE_URL = `https://docs.expo.io/guides/linking/`;
5
5
 
@@ -20,7 +20,7 @@ type SchemeConfig = {
20
20
  scheme?: string | string[];
21
21
  };
22
22
 
23
- function getSchemes(config: SchemeConfig): string[] {
23
+ function getSchemes(config: SchemeConfig | null | undefined): string[] {
24
24
  if (config) {
25
25
  if (Array.isArray(config.scheme)) {
26
26
  const validate = (value: any): value is string => {
@@ -64,17 +64,20 @@ export function collectManifestSchemes(): string[] {
64
64
  // to have them only work with `eas build`.
65
65
  const platformManifest =
66
66
  (Platform.select<any>({
67
- ios: Constants.manifest?.ios,
68
- android: Constants.manifest?.android,
67
+ ios: Constants.manifest?.ios ?? Constants.manifest2?.extra?.expoClient?.ios,
68
+ android: Constants.manifest?.android ?? Constants.manifest2?.extra?.expoClient?.android,
69
69
  web: {},
70
70
  }) as SchemeConfig) ?? {};
71
71
 
72
- const schemes = getSchemes(Constants.manifest as any);
72
+ const schemes = getSchemes(Constants.manifest ?? Constants.manifest2?.extra?.expoClient);
73
73
 
74
74
  // Add the detached scheme after the manifest scheme for legacy ExpoKit support.
75
75
  if (Constants.manifest?.detach?.scheme) {
76
76
  schemes.push(Constants.manifest.detach.scheme);
77
77
  }
78
+ if (Constants.manifest2?.extra?.expoClient?.detach?.scheme) {
79
+ schemes.push(Constants.manifest2.extra.expoClient.detach.scheme);
80
+ }
78
81
 
79
82
  // Add the unimplemented platform schemes last.
80
83
  schemes.push(...getSchemes(platformManifest));
@@ -87,9 +90,13 @@ function getNativeAppIdScheme(): string | null {
87
90
  // The native app id has been added to builds for a long time to support Google Sign-In.
88
91
  return (
89
92
  Platform.select({
90
- ios: Constants.manifest?.ios?.bundleIdentifier,
93
+ ios:
94
+ Constants.manifest?.ios?.bundleIdentifier ??
95
+ Constants.manifest2?.extra?.expoClient?.ios?.bundleIdentifier,
91
96
  // TODO: This may change to android.applicationId in the future.
92
- android: Constants.manifest?.android?.package,
97
+ android:
98
+ Constants.manifest?.android?.package ??
99
+ Constants.manifest2?.extra?.expoClient?.android?.package,
93
100
  }) ?? null
94
101
  );
95
102
  }
@@ -154,7 +161,7 @@ export function resolveScheme(props: { scheme?: string; isSilent?: boolean }): s
154
161
  `The provided Linking scheme '${
155
162
  props.scheme
156
163
  }' does not appear in the list of possible URI schemes in your Expo config. Expected one of: ${schemes
157
- .map(scheme => `'${scheme}'`)
164
+ .map((scheme) => `'${scheme}'`)
158
165
  .join(', ')}`
159
166
  );
160
167
  }