expo-linking 2.4.1 → 3.1.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 +26 -0
- package/README.md +4 -4
- package/build/ExpoLinking.d.ts +1 -0
- package/build/ExpoLinking.d.ts.map +1 -0
- package/build/ExpoLinking.web.d.ts +1 -0
- package/build/ExpoLinking.web.d.ts.map +1 -0
- package/build/Linking.d.ts +64 -41
- package/build/Linking.d.ts.map +1 -0
- package/build/Linking.js +73 -41
- package/build/Linking.js.map +1 -1
- package/build/Linking.types.d.ts +11 -0
- package/build/Linking.types.d.ts.map +1 -0
- package/build/Linking.types.js.map +1 -1
- package/build/Schemes.d.ts +5 -1
- package/build/Schemes.d.ts.map +1 -0
- package/build/Schemes.js +19 -14
- package/build/Schemes.js.map +1 -1
- package/package.json +5 -5
- package/src/Linking.ts +84 -51
- package/src/Linking.types.ts +19 -1
- package/src/Schemes.ts +19 -14
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,32 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 3.1.0 — 2022-04-18
|
|
14
|
+
|
|
15
|
+
### 🎉 New features
|
|
16
|
+
|
|
17
|
+
- `addEventListener` returns `EmitterSubscription` rather than `void` ([#17014](https://github.com/expo/expo/pull/17014) by [@frankcalise](https://github.com/frankcalise))
|
|
18
|
+
|
|
19
|
+
### 🐛 Bug fixes
|
|
20
|
+
|
|
21
|
+
- `addEventListener` and `removeEventListener` only accept `'url'` as `type` param, rather than `string`
|
|
22
|
+
- `useURL` hook now cleans up `addEventListener` via `remove` rather than `removeEventListener` ([#17014](https://github.com/expo/expo/pull/17014) by [@frankcalise](https://github.com/frankcalise))
|
|
23
|
+
|
|
24
|
+
### 💡 Others
|
|
25
|
+
|
|
26
|
+
- Export public `Schemes` methods in main file. ([#17058](https://github.com/expo/expo/pull/17058) by [@Simek](https://github.com/Simek))
|
|
27
|
+
|
|
28
|
+
## 3.0.0 — 2021-12-03
|
|
29
|
+
|
|
30
|
+
### 🛠 Breaking changes
|
|
31
|
+
|
|
32
|
+
- Remove deprecated `useUrl` method. ([#15226](https://github.com/expo/expo/pull/15226) by [@Simek](https://github.com/Simek))
|
|
33
|
+
|
|
34
|
+
### 💡 Others
|
|
35
|
+
|
|
36
|
+
- Update `qs` dependency. ([#15069](https://github.com/expo/expo/pull/15069) by [@Simek](https://github.com/Simek))
|
|
37
|
+
- 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))
|
|
38
|
+
|
|
13
39
|
## 2.4.1 — 2021-10-01
|
|
14
40
|
|
|
15
41
|
_This version does not introduce any user-facing changes._
|
package/README.md
CHANGED
|
@@ -4,16 +4,16 @@ Create and open deep links universally.
|
|
|
4
4
|
|
|
5
5
|
# API documentation
|
|
6
6
|
|
|
7
|
-
- [Documentation for the
|
|
8
|
-
- [Documentation for the latest stable release](https://docs.expo.
|
|
7
|
+
- [Documentation for the main branch](https://github.com/expo/expo/blob/main/docs/pages/versions/unversioned/sdk/linking.md)
|
|
8
|
+
- [Documentation for the latest stable release](https://docs.expo.dev/versions/latest/sdk/linking/)
|
|
9
9
|
|
|
10
10
|
# Installation in managed Expo projects
|
|
11
11
|
|
|
12
|
-
For
|
|
12
|
+
For [managed](https://docs.expo.dev/versions/latest/introduction/managed-vs-bare/) Expo projects, please follow the installation instructions in the [API documentation for the latest stable release](https://docs.expo.dev/versions/latest/sdk/asset/). If you follow the link and there is no documentation available then this library is not yet usable within managed projects — it is likely to be included in an upcoming Expo SDK release.
|
|
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 `
|
|
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
|
|
package/build/ExpoLinking.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExpoLinking.d.ts","sourceRoot":"","sources":["../src/ExpoLinking.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,eAAe,OAAO,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExpoLinking.web.d.ts","sourceRoot":"","sources":["../src/ExpoLinking.web.ts"],"names":[],"mappings":"AAGA,OAAO,EAAqB,WAAW,EAAE,MAAM,iBAAiB,CAAC;;2BAOxC,KAAK,YAAY,WAAW,GAAG,IAAI;8BAWhC,KAAK,YAAY,WAAW,GAAG,IAAI;oBAevC,MAAM,GAAG,QAAQ,OAAO,CAAC;qBAKxB,QAAQ,MAAM,CAAC;iBAKnB,MAAM,GAAG,QAAQ,IAAI,CAAC;;AArC3C,wBA2CE"}
|
package/build/Linking.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EmitterSubscription } from 'react-native';
|
|
2
|
+
import { CreateURLOptions, ParsedURL, QueryParams, SendIntentExtras, URLListener } from './Linking.types';
|
|
2
3
|
/**
|
|
3
4
|
* Create a URL that works for the environment the app is currently running in.
|
|
4
5
|
* The scheme in bare and standalone must be defined in the app.json under `expo.scheme`.
|
|
5
6
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
7
|
+
* # Examples
|
|
8
8
|
* - Bare: empty string
|
|
9
9
|
* - Standalone, Custom: `yourscheme:///path`
|
|
10
10
|
* - Web (dev): `https://localhost:19006/path`
|
|
@@ -13,87 +13,110 @@ import { CreateURLOptions, ParsedURL, QueryParams, URLListener } from './Linking
|
|
|
13
13
|
* - Expo Client (prod): `exp://exp.host/@yourname/your-app/--/path`
|
|
14
14
|
*
|
|
15
15
|
* @param path addition path components to append to the base URL.
|
|
16
|
-
* @param queryParams An object of parameters
|
|
16
|
+
* @param queryParams An object with a set of query parameters. These will be merged with any
|
|
17
|
+
* Expo-specific parameters that are needed (e.g. release channel) and then appended to the URL
|
|
18
|
+
* as a query string.
|
|
19
|
+
* @param scheme Optional URI protocol to use in the URL `<scheme>:///`, when `undefined` the scheme
|
|
20
|
+
* will be chosen from the Expo config (`app.config.js` or `app.json`).
|
|
21
|
+
* @return A URL string which points to your app with the given deep link information.
|
|
22
|
+
* @deprecated An alias for [`createURL()`](#linkingcreateurlpath-namedparameters). This method is
|
|
23
|
+
* deprecated and will be removed in a future SDK version.
|
|
17
24
|
*/
|
|
18
25
|
export declare function makeUrl(path?: string, queryParams?: QueryParams, scheme?: string): string;
|
|
19
26
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
27
|
+
* Helper method for constructing a deep link into your app, given an optional path and set of query
|
|
28
|
+
* parameters. Creates a URI scheme with two slashes by default.
|
|
22
29
|
*
|
|
23
|
-
*
|
|
30
|
+
* The scheme in bare and standalone must be defined in the Expo config (`app.config.js` or `app.json`)
|
|
31
|
+
* under `expo.scheme`.
|
|
24
32
|
*
|
|
25
|
-
*
|
|
33
|
+
* # Examples
|
|
34
|
+
* - Bare: `<scheme>://path` - uses provided scheme or scheme from Expo config `scheme`.
|
|
26
35
|
* - Standalone, Custom: `yourscheme://path`
|
|
27
36
|
* - Web (dev): `https://localhost:19006/path`
|
|
28
37
|
* - Web (prod): `https://myapp.com/path`
|
|
29
38
|
* - Expo Client (dev): `exp://128.0.0.1:19000/--/path`
|
|
30
39
|
* - Expo Client (prod): `exp://exp.host/@yourname/your-app/--/path`
|
|
31
40
|
*
|
|
32
|
-
* @param path
|
|
33
|
-
* @param
|
|
34
|
-
* @
|
|
41
|
+
* @param path Addition path components to append to the base URL.
|
|
42
|
+
* @param namedParameters Additional options object.
|
|
43
|
+
* @return A URL string which points to your app with the given deep link information.
|
|
35
44
|
*/
|
|
36
45
|
export declare function createURL(path: string, { scheme, queryParams, isTripleSlashed }?: CreateURLOptions): string;
|
|
37
46
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* @
|
|
47
|
+
* Helper method for parsing out deep link information from a URL.
|
|
48
|
+
* @param url A URL that points to the currently running experience (e.g. an output of `Linking.createURL()`).
|
|
49
|
+
* @return A `ParsedURL` object.
|
|
41
50
|
*/
|
|
42
51
|
export declare function parse(url: string): ParsedURL;
|
|
43
52
|
/**
|
|
44
|
-
* Add a handler to Linking changes by listening to the `url` event type
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
53
|
+
* Add a handler to `Linking` changes by listening to the `url` event type and providing the handler.
|
|
54
|
+
* It is recommended to use the [`useURL()`](#useurl) hook instead.
|
|
55
|
+
* @param type The only valid type is `'url'`.
|
|
56
|
+
* @param handler An [`URLListener`](#urllistener) function that takes an `event` object of the type
|
|
57
|
+
* [`EventType`](#eventype).
|
|
58
|
+
* @return An EmitterSubscription that has the remove method from EventSubscription
|
|
59
|
+
* @see [React Native Docs Linking page](https://reactnative.dev/docs/linking#addeventlistener).
|
|
48
60
|
*/
|
|
49
|
-
export declare function addEventListener(type:
|
|
61
|
+
export declare function addEventListener(type: 'url', handler: URLListener): EmitterSubscription;
|
|
50
62
|
/**
|
|
51
63
|
* Remove a handler by passing the `url` event type and the handler.
|
|
52
|
-
*
|
|
53
|
-
*
|
|
64
|
+
* @param type The only valid type is `'url'`.
|
|
65
|
+
* @param handler An [`URLListener`](#urllistener) function that takes an `event` object of the type
|
|
66
|
+
* [`EventType`](#eventype).
|
|
67
|
+
* @see [React Native Docs Linking page](https://reactnative.dev/docs/linking#removeeventlistener).
|
|
54
68
|
*/
|
|
55
|
-
export declare function removeEventListener(type:
|
|
69
|
+
export declare function removeEventListener(type: 'url', handler: URLListener): void;
|
|
56
70
|
/**
|
|
57
|
-
*
|
|
58
|
-
*
|
|
71
|
+
* Helper method which wraps React Native's `Linking.getInitialURL()` in `Linking.parse()`.
|
|
72
|
+
* Parses the deep link information out of the URL used to open the experience initially.
|
|
73
|
+
* If no link opened the app, all the fields will be `null`.
|
|
74
|
+
* > On the web it parses the current window URL.
|
|
75
|
+
* @return A promise that resolves with `ParsedURL` object.
|
|
59
76
|
*/
|
|
60
77
|
export declare function parseInitialURLAsync(): Promise<ParsedURL>;
|
|
61
78
|
/**
|
|
62
|
-
* Launch an Android intent with
|
|
63
|
-
*
|
|
79
|
+
* Launch an Android intent with extras.
|
|
80
|
+
* > Use [IntentLauncher](./intent-launcher) instead, `sendIntent` is only included in
|
|
81
|
+
* > `Linking` for API compatibility with React Native's Linking API.
|
|
64
82
|
* @platform android
|
|
65
83
|
*/
|
|
66
|
-
export declare function sendIntent(action: string, extras?:
|
|
67
|
-
key: string;
|
|
68
|
-
value: string | number | boolean;
|
|
69
|
-
}[]): Promise<void>;
|
|
84
|
+
export declare function sendIntent(action: string, extras?: SendIntentExtras[]): Promise<void>;
|
|
70
85
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
86
|
+
* Open the operating system settings app and displays the app’s custom settings, if it has any.
|
|
73
87
|
* @platform ios
|
|
74
88
|
*/
|
|
75
89
|
export declare function openSettings(): Promise<void>;
|
|
76
90
|
/**
|
|
77
|
-
*
|
|
78
|
-
*
|
|
91
|
+
* Get the URL that was used to launch the app if it was launched by a link.
|
|
92
|
+
* @return The URL string that launched your app, or `null`.
|
|
79
93
|
*/
|
|
80
94
|
export declare function getInitialURL(): Promise<string | null>;
|
|
81
95
|
/**
|
|
82
|
-
*
|
|
96
|
+
* Attempt to open the given URL with an installed app. See the [Linking guide](/guides/linking)
|
|
97
|
+
* for more information.
|
|
98
|
+
* @param url A URL for the operating system to open, eg: `tel:5555555`, `exp://`.
|
|
99
|
+
* @return A `Promise` that is fulfilled with `true` if the link is opened operating system
|
|
100
|
+
* automatically or the user confirms the prompt to open the link. The `Promise` rejects if there
|
|
101
|
+
* are no applications registered for the URL or the user cancels the dialog.
|
|
83
102
|
*/
|
|
84
103
|
export declare function openURL(url: string): Promise<true>;
|
|
85
104
|
/**
|
|
86
105
|
* 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.
|
|
106
|
+
* On web this always returns `true` because there is no API for detecting what URLs can be opened.
|
|
107
|
+
* @param url The URL that you want to test can be opened.
|
|
108
|
+
* @return A `Promise` object that is fulfilled with `true` if the URL can be handled, otherwise it
|
|
109
|
+
* `false` if not.
|
|
110
|
+
*
|
|
111
|
+
* The `Promise` will reject on Android if it was impossible to check if the URL can be opened, and
|
|
112
|
+
* 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
113
|
*/
|
|
89
114
|
export declare function canOpenURL(url: string): Promise<boolean>;
|
|
90
115
|
/**
|
|
91
116
|
* Returns the initial URL followed by any subsequent changes to the URL.
|
|
117
|
+
* @return Returns the initial URL or `null`.
|
|
92
118
|
*/
|
|
93
119
|
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
120
|
export * from './Linking.types';
|
|
121
|
+
export * from './Schemes';
|
|
122
|
+
//# sourceMappingURL=Linking.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Linking.d.ts","sourceRoot":"","sources":["../src/Linking.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAInD,OAAO,EACL,gBAAgB,EAChB,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,WAAW,EACZ,MAAM,iBAAiB,CAAC;AAoEzB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,OAAO,CAAC,IAAI,GAAE,MAAW,EAAE,WAAW,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7F;AAGD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,EAAE,MAAM,EAAE,WAAgB,EAAE,eAAuB,EAAE,GAAE,gBAAqB,GAC3E,MAAM,CAgER;AAGD;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CA6C5C;AAGD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,GAAG,mBAAmB,CAEvF;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAE3E;AAGD;;;;;;GAMG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,SAAS,CAAC,CAY/D;AAGD;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAK3F;AAGD;;;GAGG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAQlD;AAGD;;;GAGG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAE5D;AAGD;;;;;;;GAOG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGxD;AAGD;;;;;;;;;GASG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAG9D;AAGD;;;GAGG;AACH,wBAAgB,MAAM,IAAI,MAAM,GAAG,IAAI,CActC;AAED,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC"}
|
package/build/Linking.js
CHANGED
|
@@ -64,12 +64,12 @@ function ensureLeadingSlash(input, shouldAppend) {
|
|
|
64
64
|
}
|
|
65
65
|
return input;
|
|
66
66
|
}
|
|
67
|
+
// @needsAudit
|
|
67
68
|
/**
|
|
68
69
|
* Create a URL that works for the environment the app is currently running in.
|
|
69
70
|
* The scheme in bare and standalone must be defined in the app.json under `expo.scheme`.
|
|
70
71
|
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
72
|
+
* # Examples
|
|
73
73
|
* - Bare: empty string
|
|
74
74
|
* - Standalone, Custom: `yourscheme:///path`
|
|
75
75
|
* - Web (dev): `https://localhost:19006/path`
|
|
@@ -78,27 +78,37 @@ function ensureLeadingSlash(input, shouldAppend) {
|
|
|
78
78
|
* - Expo Client (prod): `exp://exp.host/@yourname/your-app/--/path`
|
|
79
79
|
*
|
|
80
80
|
* @param path addition path components to append to the base URL.
|
|
81
|
-
* @param queryParams An object of parameters
|
|
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.
|
|
82
89
|
*/
|
|
83
90
|
export function makeUrl(path = '', queryParams, scheme) {
|
|
84
91
|
return createURL(path, { queryParams, scheme, isTripleSlashed: true });
|
|
85
92
|
}
|
|
93
|
+
// @needsAudit
|
|
86
94
|
/**
|
|
87
|
-
*
|
|
88
|
-
*
|
|
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.
|
|
89
97
|
*
|
|
90
|
-
*
|
|
98
|
+
* The scheme in bare and standalone must be defined in the Expo config (`app.config.js` or `app.json`)
|
|
99
|
+
* under `expo.scheme`.
|
|
91
100
|
*
|
|
92
|
-
*
|
|
101
|
+
* # Examples
|
|
102
|
+
* - Bare: `<scheme>://path` - uses provided scheme or scheme from Expo config `scheme`.
|
|
93
103
|
* - Standalone, Custom: `yourscheme://path`
|
|
94
104
|
* - Web (dev): `https://localhost:19006/path`
|
|
95
105
|
* - Web (prod): `https://myapp.com/path`
|
|
96
106
|
* - Expo Client (dev): `exp://128.0.0.1:19000/--/path`
|
|
97
107
|
* - Expo Client (prod): `exp://exp.host/@yourname/your-app/--/path`
|
|
98
108
|
*
|
|
99
|
-
* @param path
|
|
100
|
-
* @param
|
|
101
|
-
* @
|
|
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.
|
|
102
112
|
*/
|
|
103
113
|
export function createURL(path, { scheme, queryParams = {}, isTripleSlashed = false } = {}) {
|
|
104
114
|
if (Platform.OS === 'web') {
|
|
@@ -144,7 +154,7 @@ export function createURL(path, { scheme, queryParams = {}, isTripleSlashed = fa
|
|
|
144
154
|
paramsFromHostUri = parsedParams;
|
|
145
155
|
}
|
|
146
156
|
}
|
|
147
|
-
catch
|
|
157
|
+
catch { }
|
|
148
158
|
queryParams = {
|
|
149
159
|
...queryParams,
|
|
150
160
|
...paramsFromHostUri,
|
|
@@ -157,10 +167,11 @@ export function createURL(path, { scheme, queryParams = {}, isTripleSlashed = fa
|
|
|
157
167
|
hostUri = ensureLeadingSlash(hostUri, !isTripleSlashed);
|
|
158
168
|
return encodeURI(`${resolvedScheme}:${isTripleSlashed ? '/' : ''}/${hostUri}${path}${queryString}`);
|
|
159
169
|
}
|
|
170
|
+
// @needsAudit
|
|
160
171
|
/**
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
* @
|
|
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.
|
|
164
175
|
*/
|
|
165
176
|
export function parse(url) {
|
|
166
177
|
validateURL(url);
|
|
@@ -200,26 +211,36 @@ 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
|
-
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
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
|
+
* @return An EmitterSubscription that has the remove method from EventSubscription
|
|
222
|
+
* @see [React Native Docs Linking page](https://reactnative.dev/docs/linking#addeventlistener).
|
|
208
223
|
*/
|
|
209
224
|
export function addEventListener(type, handler) {
|
|
210
|
-
NativeLinking.addEventListener(type, handler);
|
|
225
|
+
return NativeLinking.addEventListener(type, handler);
|
|
211
226
|
}
|
|
212
227
|
/**
|
|
213
228
|
* Remove a handler by passing the `url` event type and the handler.
|
|
214
|
-
*
|
|
215
|
-
*
|
|
229
|
+
* @param type The only valid type is `'url'`.
|
|
230
|
+
* @param handler An [`URLListener`](#urllistener) function that takes an `event` object of the type
|
|
231
|
+
* [`EventType`](#eventype).
|
|
232
|
+
* @see [React Native Docs Linking page](https://reactnative.dev/docs/linking#removeeventlistener).
|
|
216
233
|
*/
|
|
217
234
|
export function removeEventListener(type, handler) {
|
|
218
235
|
NativeLinking.removeEventListener(type, handler);
|
|
219
236
|
}
|
|
237
|
+
// @needsAudit
|
|
220
238
|
/**
|
|
221
|
-
*
|
|
222
|
-
*
|
|
239
|
+
* Helper method which wraps React Native's `Linking.getInitialURL()` in `Linking.parse()`.
|
|
240
|
+
* Parses the deep link information out of the URL used to open the experience initially.
|
|
241
|
+
* If no link opened the app, all the fields will be `null`.
|
|
242
|
+
* > On the web it parses the current window URL.
|
|
243
|
+
* @return A promise that resolves with `ParsedURL` object.
|
|
223
244
|
*/
|
|
224
245
|
export async function parseInitialURLAsync() {
|
|
225
246
|
const initialUrl = await NativeLinking.getInitialURL();
|
|
@@ -233,9 +254,11 @@ export async function parseInitialURLAsync() {
|
|
|
233
254
|
}
|
|
234
255
|
return parse(initialUrl);
|
|
235
256
|
}
|
|
257
|
+
// @needsAudit
|
|
236
258
|
/**
|
|
237
|
-
* Launch an Android intent with
|
|
238
|
-
*
|
|
259
|
+
* Launch an Android intent with extras.
|
|
260
|
+
* > Use [IntentLauncher](./intent-launcher) instead, `sendIntent` is only included in
|
|
261
|
+
* > `Linking` for API compatibility with React Native's Linking API.
|
|
239
262
|
* @platform android
|
|
240
263
|
*/
|
|
241
264
|
export async function sendIntent(action, extras) {
|
|
@@ -244,9 +267,9 @@ export async function sendIntent(action, extras) {
|
|
|
244
267
|
}
|
|
245
268
|
throw new UnavailabilityError('Linking', 'sendIntent');
|
|
246
269
|
}
|
|
270
|
+
// @needsAudit
|
|
247
271
|
/**
|
|
248
|
-
*
|
|
249
|
-
*
|
|
272
|
+
* Open the operating system settings app and displays the app’s custom settings, if it has any.
|
|
250
273
|
* @platform ios
|
|
251
274
|
*/
|
|
252
275
|
export async function openSettings() {
|
|
@@ -258,30 +281,46 @@ export async function openSettings() {
|
|
|
258
281
|
}
|
|
259
282
|
await openURL('app-settings:');
|
|
260
283
|
}
|
|
284
|
+
// @needsAudit
|
|
261
285
|
/**
|
|
262
|
-
*
|
|
263
|
-
*
|
|
286
|
+
* Get the URL that was used to launch the app if it was launched by a link.
|
|
287
|
+
* @return The URL string that launched your app, or `null`.
|
|
264
288
|
*/
|
|
265
289
|
export async function getInitialURL() {
|
|
266
290
|
return (await NativeLinking.getInitialURL()) ?? null;
|
|
267
291
|
}
|
|
292
|
+
// @needsAudit
|
|
268
293
|
/**
|
|
269
|
-
*
|
|
294
|
+
* Attempt to open the given URL with an installed app. See the [Linking guide](/guides/linking)
|
|
295
|
+
* for more information.
|
|
296
|
+
* @param url A URL for the operating system to open, eg: `tel:5555555`, `exp://`.
|
|
297
|
+
* @return A `Promise` that is fulfilled with `true` if the link is opened operating system
|
|
298
|
+
* automatically or the user confirms the prompt to open the link. The `Promise` rejects if there
|
|
299
|
+
* are no applications registered for the URL or the user cancels the dialog.
|
|
270
300
|
*/
|
|
271
301
|
export async function openURL(url) {
|
|
272
302
|
validateURL(url);
|
|
273
303
|
return await NativeLinking.openURL(url);
|
|
274
304
|
}
|
|
305
|
+
// @needsAudit
|
|
275
306
|
/**
|
|
276
307
|
* 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.
|
|
308
|
+
* On web this always returns `true` because there is no API for detecting what URLs can be opened.
|
|
309
|
+
* @param url The URL that you want to test can be opened.
|
|
310
|
+
* @return A `Promise` object that is fulfilled with `true` if the URL can be handled, otherwise it
|
|
311
|
+
* `false` if not.
|
|
312
|
+
*
|
|
313
|
+
* The `Promise` will reject on Android if it was impossible to check if the URL can be opened, and
|
|
314
|
+
* 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
315
|
*/
|
|
279
316
|
export async function canOpenURL(url) {
|
|
280
317
|
validateURL(url);
|
|
281
318
|
return await NativeLinking.canOpenURL(url);
|
|
282
319
|
}
|
|
320
|
+
// @needsAudit
|
|
283
321
|
/**
|
|
284
322
|
* Returns the initial URL followed by any subsequent changes to the URL.
|
|
323
|
+
* @return Returns the initial URL or `null`.
|
|
285
324
|
*/
|
|
286
325
|
export function useURL() {
|
|
287
326
|
const [url, setLink] = useState(null);
|
|
@@ -290,18 +329,11 @@ export function useURL() {
|
|
|
290
329
|
}
|
|
291
330
|
useEffect(() => {
|
|
292
331
|
getInitialURL().then((url) => setLink(url));
|
|
293
|
-
addEventListener('url', onChange);
|
|
294
|
-
return () =>
|
|
332
|
+
const subscription = addEventListener('url', onChange);
|
|
333
|
+
return () => subscription.remove();
|
|
295
334
|
}, []);
|
|
296
335
|
return url;
|
|
297
336
|
}
|
|
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
337
|
export * from './Linking.types';
|
|
338
|
+
export * from './Schemes';
|
|
307
339
|
//# sourceMappingURL=Linking.js.map
|
package/build/Linking.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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 { 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.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/**\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 = 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/**\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.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/**\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 { EmitterSubscription } from 'react-native';\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 {}\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 * @return An EmitterSubscription that has the remove method from EventSubscription\n * @see [React Native Docs Linking page](https://reactnative.dev/docs/linking#addeventlistener).\n */\nexport function addEventListener(type: 'url', handler: URLListener): EmitterSubscription {\n return 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: 'url', 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 const subscription = addEventListener('url', onChange);\n return () => subscription.remove();\n }, []);\n\n return url;\n}\n\nexport * from './Linking.types';\nexport * from './Schemes';\n"]}
|
package/build/Linking.types.d.ts
CHANGED
|
@@ -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,8 @@ 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
|
+
};
|
|
39
|
+
//# sourceMappingURL=Linking.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Linking.types.d.ts","sourceRoot":"","sources":["../src/Linking.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAG9B,oBAAY,WAAW,GAAG,QAAQ,CAAC;AAGnC,oBAAY,SAAS,GAAG;IACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB;;OAEG;IACH,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB;;OAEG;IACH,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;CACjC,CAAC;AAGF,oBAAY,gBAAgB,GAAG;IAC7B;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAGF,oBAAY,SAAS,GAAG;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,YAAY,CAAC;CAC5B,CAAC;AAGF,oBAAY,WAAW,GAAG,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;AAGrD,oBAAY,iBAAiB,GAAG,CAAC,WAAW,EAAE,YAAY,KAAK,IAAI,CAAC;AAGpE,oBAAY,gBAAgB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC"}
|
|
@@ -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 = {
|
|
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.d.ts
CHANGED
|
@@ -9,8 +9,12 @@ export declare function hasCustomScheme(): boolean;
|
|
|
9
9
|
* - Android: scheme -> android.scheme -> android.package
|
|
10
10
|
*/
|
|
11
11
|
export declare function collectManifestSchemes(): string[];
|
|
12
|
+
/**
|
|
13
|
+
* Ensure the user has linked the expo-constants manifest in bare workflow.
|
|
14
|
+
*/
|
|
12
15
|
export declare function hasConstantsManifest(): boolean;
|
|
13
|
-
export declare function resolveScheme(
|
|
16
|
+
export declare function resolveScheme(options: {
|
|
14
17
|
scheme?: string;
|
|
15
18
|
isSilent?: boolean;
|
|
16
19
|
}): string;
|
|
20
|
+
//# sourceMappingURL=Schemes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Schemes.d.ts","sourceRoot":"","sources":["../src/Schemes.ts"],"names":[],"mappings":"AAMA,wBAAgB,eAAe,IAAI,OAAO,CAWzC;AAkCD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CA0BjD;AAmBD;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAK9C;AAGD,wBAAgB,aAAa,CAAC,OAAO,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAiGtF"}
|
package/build/Schemes.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Constants, { ExecutionEnvironment } from 'expo-constants';
|
|
2
2
|
import { Platform } from 'expo-modules-core';
|
|
3
|
-
const LINKING_GUIDE_URL = `https://docs.expo.
|
|
3
|
+
const LINKING_GUIDE_URL = `https://docs.expo.dev/guides/linking/`;
|
|
4
|
+
// @docsMissing
|
|
4
5
|
export function hasCustomScheme() {
|
|
5
6
|
if (Constants.executionEnvironment === ExecutionEnvironment.Bare) {
|
|
6
7
|
// Bare always uses a custom scheme.
|
|
@@ -83,20 +84,24 @@ function getNativeAppIdScheme() {
|
|
|
83
84
|
Constants.manifest2?.extra?.expoClient?.android?.package,
|
|
84
85
|
}) ?? null);
|
|
85
86
|
}
|
|
87
|
+
// @needsAudit
|
|
88
|
+
/**
|
|
89
|
+
* Ensure the user has linked the expo-constants manifest in bare workflow.
|
|
90
|
+
*/
|
|
86
91
|
export function hasConstantsManifest() {
|
|
87
|
-
// Ensure the user has linked the expo-constants manifest in bare workflow.
|
|
88
92
|
return (!!Object.keys(Constants.manifest ?? {}).length ||
|
|
89
93
|
!!Object.keys(Constants.manifest2 ?? {}).length);
|
|
90
94
|
}
|
|
91
|
-
|
|
95
|
+
// @docsMissing
|
|
96
|
+
export function resolveScheme(options) {
|
|
92
97
|
if (Constants.executionEnvironment !== ExecutionEnvironment.StoreClient &&
|
|
93
98
|
!hasConstantsManifest()) {
|
|
94
|
-
throw new Error(`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/
|
|
99
|
+
throw new Error(`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/main/packages/expo-constants/README.md`);
|
|
95
100
|
}
|
|
96
101
|
const manifestSchemes = collectManifestSchemes();
|
|
97
102
|
const nativeAppId = getNativeAppIdScheme();
|
|
98
103
|
if (!manifestSchemes.length) {
|
|
99
|
-
if (__DEV__ && !
|
|
104
|
+
if (__DEV__ && !options.isSilent) {
|
|
100
105
|
// Assert a config warning if no scheme is setup yet. `isSilent` is used for warnings, but we'll ignore it for exceptions.
|
|
101
106
|
console.warn(`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}`);
|
|
102
107
|
}
|
|
@@ -107,10 +112,10 @@ export function resolveScheme(props) {
|
|
|
107
112
|
}
|
|
108
113
|
// In the Expo client...
|
|
109
114
|
if (Constants.executionEnvironment === ExecutionEnvironment.StoreClient) {
|
|
110
|
-
if (
|
|
115
|
+
if (options.scheme) {
|
|
111
116
|
// This enables users to use the fb or google redirects on iOS in the Expo client.
|
|
112
|
-
if (EXPO_CLIENT_SCHEMES.includes(
|
|
113
|
-
return
|
|
117
|
+
if (EXPO_CLIENT_SCHEMES.includes(options.scheme)) {
|
|
118
|
+
return options.scheme;
|
|
114
119
|
}
|
|
115
120
|
// Silently ignore to make bare workflow development easier.
|
|
116
121
|
}
|
|
@@ -118,26 +123,26 @@ export function resolveScheme(props) {
|
|
|
118
123
|
return 'exp';
|
|
119
124
|
}
|
|
120
125
|
const schemes = [...manifestSchemes, nativeAppId].filter(Boolean);
|
|
121
|
-
if (
|
|
126
|
+
if (options.scheme) {
|
|
122
127
|
if (__DEV__) {
|
|
123
128
|
// Bare workflow development assertion about the provided scheme matching the Expo config.
|
|
124
|
-
if (!schemes.includes(
|
|
129
|
+
if (!schemes.includes(options.scheme) && !options.isSilent) {
|
|
125
130
|
// TODO: Will this cause issues for things like Facebook or Google that use `reversed-client-id://` or `fb<FBID>:/`?
|
|
126
131
|
// Traditionally these APIs don't use the Linking API directly.
|
|
127
|
-
console.warn(`The provided Linking scheme '${
|
|
132
|
+
console.warn(`The provided Linking scheme '${options.scheme}' does not appear in the list of possible URI schemes in your Expo config. Expected one of: ${schemes
|
|
128
133
|
.map((scheme) => `'${scheme}'`)
|
|
129
134
|
.join(', ')}`);
|
|
130
135
|
}
|
|
131
136
|
}
|
|
132
137
|
// Return the user provided value.
|
|
133
|
-
return
|
|
138
|
+
return options.scheme;
|
|
134
139
|
}
|
|
135
140
|
// If no scheme is provided, we'll guess what the scheme is based on the manifest.
|
|
136
141
|
// This is to attempt to keep managed apps working across expo build and EAS build.
|
|
137
142
|
// EAS build ejects the app before building it so we can assume that the user will
|
|
138
143
|
// be using one of defined schemes.
|
|
139
144
|
// If the native app id is the only scheme,
|
|
140
|
-
if (!!nativeAppId && !manifestSchemes.length && !
|
|
145
|
+
if (!!nativeAppId && !manifestSchemes.length && !options.isSilent) {
|
|
141
146
|
// Assert a config warning if no scheme is setup yet.
|
|
142
147
|
// This warning only applies to managed workflow EAS apps, as bare workflow
|
|
143
148
|
console.warn(`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}`);
|
|
@@ -154,7 +159,7 @@ export function resolveScheme(props) {
|
|
|
154
159
|
// Throw in production, use the __DEV__ flag so users can test this functionality with `expo start --no-dev`
|
|
155
160
|
throw new Error(errorMessage);
|
|
156
161
|
}
|
|
157
|
-
if (extraSchemes.length && !
|
|
162
|
+
if (extraSchemes.length && !options.isSilent) {
|
|
158
163
|
console.warn(`Linking found multiple possible URI schemes in your Expo config.\nUsing '${scheme}'. Ignoring: ${[
|
|
159
164
|
...extraSchemes,
|
|
160
165
|
nativeAppId,
|
package/build/Schemes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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"]}
|
|
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.dev/guides/linking/`;\n\n// @docsMissing\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\n// @needsAudit\n/**\n * Ensure the user has linked the expo-constants manifest in bare workflow.\n */\nexport function hasConstantsManifest(): boolean {\n return (\n !!Object.keys(Constants.manifest ?? {}).length ||\n !!Object.keys(Constants.manifest2 ?? {}).length\n );\n}\n\n// @docsMissing\nexport function resolveScheme(options: { 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/main/packages/expo-constants/README.md`\n );\n }\n\n const manifestSchemes = collectManifestSchemes();\n const nativeAppId = getNativeAppIdScheme();\n\n if (!manifestSchemes.length) {\n if (__DEV__ && !options.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 (options.scheme) {\n // This enables users to use the fb or google redirects on iOS in the Expo client.\n if (EXPO_CLIENT_SCHEMES.includes(options.scheme)) {\n return options.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 (options.scheme) {\n if (__DEV__) {\n // Bare workflow development assertion about the provided scheme matching the Expo config.\n if (!schemes.includes(options.scheme) && !options.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 options.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 options.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 && !options.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 && !options.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": "
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Create and open deep links universally",
|
|
5
5
|
"main": "build/Linking.js",
|
|
6
6
|
"types": "build/Linking.d.ts",
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
"license": "MIT",
|
|
31
31
|
"homepage": "https://docs.expo.dev/versions/latest/sdk/linking",
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"expo-constants": "~
|
|
33
|
+
"expo-constants": "~13.1.0",
|
|
34
34
|
"invariant": "^2.2.4",
|
|
35
|
-
"qs": "^6.
|
|
36
|
-
"url-parse": "^1.
|
|
35
|
+
"qs": "^6.9.1",
|
|
36
|
+
"url-parse": "^1.5.9"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@types/qs": "^6.5.3",
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"jest": {
|
|
43
43
|
"preset": "expo-module-scripts"
|
|
44
44
|
},
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "22dce752354bb429c84851bc4389abe47a766b1f"
|
|
46
46
|
}
|
package/src/Linking.ts
CHANGED
|
@@ -3,10 +3,17 @@ 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
|
+
import { EmitterSubscription } from 'react-native';
|
|
6
7
|
import URL from 'url-parse';
|
|
7
8
|
|
|
8
9
|
import NativeLinking from './ExpoLinking';
|
|
9
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
CreateURLOptions,
|
|
12
|
+
ParsedURL,
|
|
13
|
+
QueryParams,
|
|
14
|
+
SendIntentExtras,
|
|
15
|
+
URLListener,
|
|
16
|
+
} from './Linking.types';
|
|
10
17
|
import { hasCustomScheme, resolveScheme } from './Schemes';
|
|
11
18
|
|
|
12
19
|
function validateURL(url: string): void {
|
|
@@ -73,12 +80,12 @@ function ensureLeadingSlash(input: string, shouldAppend: boolean): string {
|
|
|
73
80
|
return input;
|
|
74
81
|
}
|
|
75
82
|
|
|
83
|
+
// @needsAudit
|
|
76
84
|
/**
|
|
77
85
|
* Create a URL that works for the environment the app is currently running in.
|
|
78
86
|
* The scheme in bare and standalone must be defined in the app.json under `expo.scheme`.
|
|
79
87
|
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
88
|
+
* # Examples
|
|
82
89
|
* - Bare: empty string
|
|
83
90
|
* - Standalone, Custom: `yourscheme:///path`
|
|
84
91
|
* - Web (dev): `https://localhost:19006/path`
|
|
@@ -87,28 +94,38 @@ function ensureLeadingSlash(input: string, shouldAppend: boolean): string {
|
|
|
87
94
|
* - Expo Client (prod): `exp://exp.host/@yourname/your-app/--/path`
|
|
88
95
|
*
|
|
89
96
|
* @param path addition path components to append to the base URL.
|
|
90
|
-
* @param queryParams An object of parameters
|
|
97
|
+
* @param queryParams An object with a set of query parameters. These will be merged with any
|
|
98
|
+
* Expo-specific parameters that are needed (e.g. release channel) and then appended to the URL
|
|
99
|
+
* as a query string.
|
|
100
|
+
* @param scheme Optional URI protocol to use in the URL `<scheme>:///`, when `undefined` the scheme
|
|
101
|
+
* will be chosen from the Expo config (`app.config.js` or `app.json`).
|
|
102
|
+
* @return A URL string which points to your app with the given deep link information.
|
|
103
|
+
* @deprecated An alias for [`createURL()`](#linkingcreateurlpath-namedparameters). This method is
|
|
104
|
+
* deprecated and will be removed in a future SDK version.
|
|
91
105
|
*/
|
|
92
106
|
export function makeUrl(path: string = '', queryParams?: QueryParams, scheme?: string): string {
|
|
93
107
|
return createURL(path, { queryParams, scheme, isTripleSlashed: true });
|
|
94
108
|
}
|
|
95
109
|
|
|
110
|
+
// @needsAudit
|
|
96
111
|
/**
|
|
97
|
-
*
|
|
98
|
-
*
|
|
112
|
+
* Helper method for constructing a deep link into your app, given an optional path and set of query
|
|
113
|
+
* parameters. Creates a URI scheme with two slashes by default.
|
|
99
114
|
*
|
|
100
|
-
*
|
|
115
|
+
* The scheme in bare and standalone must be defined in the Expo config (`app.config.js` or `app.json`)
|
|
116
|
+
* under `expo.scheme`.
|
|
101
117
|
*
|
|
102
|
-
*
|
|
118
|
+
* # Examples
|
|
119
|
+
* - Bare: `<scheme>://path` - uses provided scheme or scheme from Expo config `scheme`.
|
|
103
120
|
* - Standalone, Custom: `yourscheme://path`
|
|
104
121
|
* - Web (dev): `https://localhost:19006/path`
|
|
105
122
|
* - Web (prod): `https://myapp.com/path`
|
|
106
123
|
* - Expo Client (dev): `exp://128.0.0.1:19000/--/path`
|
|
107
124
|
* - Expo Client (prod): `exp://exp.host/@yourname/your-app/--/path`
|
|
108
125
|
*
|
|
109
|
-
* @param path
|
|
110
|
-
* @param
|
|
111
|
-
* @
|
|
126
|
+
* @param path Addition path components to append to the base URL.
|
|
127
|
+
* @param namedParameters Additional options object.
|
|
128
|
+
* @return A URL string which points to your app with the given deep link information.
|
|
112
129
|
*/
|
|
113
130
|
export function createURL(
|
|
114
131
|
path: string,
|
|
@@ -161,7 +178,7 @@ export function createURL(
|
|
|
161
178
|
if (typeof parsedParams === 'object') {
|
|
162
179
|
paramsFromHostUri = parsedParams;
|
|
163
180
|
}
|
|
164
|
-
} catch
|
|
181
|
+
} catch {}
|
|
165
182
|
queryParams = {
|
|
166
183
|
...queryParams,
|
|
167
184
|
...paramsFromHostUri,
|
|
@@ -179,10 +196,11 @@ export function createURL(
|
|
|
179
196
|
);
|
|
180
197
|
}
|
|
181
198
|
|
|
199
|
+
// @needsAudit
|
|
182
200
|
/**
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
* @
|
|
201
|
+
* Helper method for parsing out deep link information from a URL.
|
|
202
|
+
* @param url A URL that points to the currently running experience (e.g. an output of `Linking.createURL()`).
|
|
203
|
+
* @return A `ParsedURL` object.
|
|
186
204
|
*/
|
|
187
205
|
export function parse(url: string): ParsedURL {
|
|
188
206
|
validateURL(url);
|
|
@@ -231,28 +249,38 @@ export function parse(url: string): ParsedURL {
|
|
|
231
249
|
};
|
|
232
250
|
}
|
|
233
251
|
|
|
252
|
+
// @needsAudit
|
|
234
253
|
/**
|
|
235
|
-
* Add a handler to Linking changes by listening to the `url` event type
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
*
|
|
254
|
+
* Add a handler to `Linking` changes by listening to the `url` event type and providing the handler.
|
|
255
|
+
* It is recommended to use the [`useURL()`](#useurl) hook instead.
|
|
256
|
+
* @param type The only valid type is `'url'`.
|
|
257
|
+
* @param handler An [`URLListener`](#urllistener) function that takes an `event` object of the type
|
|
258
|
+
* [`EventType`](#eventype).
|
|
259
|
+
* @return An EmitterSubscription that has the remove method from EventSubscription
|
|
260
|
+
* @see [React Native Docs Linking page](https://reactnative.dev/docs/linking#addeventlistener).
|
|
239
261
|
*/
|
|
240
|
-
export function addEventListener(type:
|
|
241
|
-
NativeLinking.addEventListener(type, handler);
|
|
262
|
+
export function addEventListener(type: 'url', handler: URLListener): EmitterSubscription {
|
|
263
|
+
return NativeLinking.addEventListener(type, handler);
|
|
242
264
|
}
|
|
243
265
|
|
|
244
266
|
/**
|
|
245
267
|
* Remove a handler by passing the `url` event type and the handler.
|
|
246
|
-
*
|
|
247
|
-
*
|
|
268
|
+
* @param type The only valid type is `'url'`.
|
|
269
|
+
* @param handler An [`URLListener`](#urllistener) function that takes an `event` object of the type
|
|
270
|
+
* [`EventType`](#eventype).
|
|
271
|
+
* @see [React Native Docs Linking page](https://reactnative.dev/docs/linking#removeeventlistener).
|
|
248
272
|
*/
|
|
249
|
-
export function removeEventListener(type:
|
|
273
|
+
export function removeEventListener(type: 'url', handler: URLListener): void {
|
|
250
274
|
NativeLinking.removeEventListener(type, handler);
|
|
251
275
|
}
|
|
252
276
|
|
|
277
|
+
// @needsAudit
|
|
253
278
|
/**
|
|
254
|
-
*
|
|
255
|
-
*
|
|
279
|
+
* Helper method which wraps React Native's `Linking.getInitialURL()` in `Linking.parse()`.
|
|
280
|
+
* Parses the deep link information out of the URL used to open the experience initially.
|
|
281
|
+
* If no link opened the app, all the fields will be `null`.
|
|
282
|
+
* > On the web it parses the current window URL.
|
|
283
|
+
* @return A promise that resolves with `ParsedURL` object.
|
|
256
284
|
*/
|
|
257
285
|
export async function parseInitialURLAsync(): Promise<ParsedURL> {
|
|
258
286
|
const initialUrl = await NativeLinking.getInitialURL();
|
|
@@ -268,24 +296,23 @@ export async function parseInitialURLAsync(): Promise<ParsedURL> {
|
|
|
268
296
|
return parse(initialUrl);
|
|
269
297
|
}
|
|
270
298
|
|
|
299
|
+
// @needsAudit
|
|
271
300
|
/**
|
|
272
|
-
* Launch an Android intent with
|
|
273
|
-
*
|
|
301
|
+
* Launch an Android intent with extras.
|
|
302
|
+
* > Use [IntentLauncher](./intent-launcher) instead, `sendIntent` is only included in
|
|
303
|
+
* > `Linking` for API compatibility with React Native's Linking API.
|
|
274
304
|
* @platform android
|
|
275
305
|
*/
|
|
276
|
-
export async function sendIntent(
|
|
277
|
-
action: string,
|
|
278
|
-
extras?: { key: string; value: string | number | boolean }[]
|
|
279
|
-
): Promise<void> {
|
|
306
|
+
export async function sendIntent(action: string, extras?: SendIntentExtras[]): Promise<void> {
|
|
280
307
|
if (Platform.OS === 'android') {
|
|
281
308
|
return await NativeLinking.sendIntent(action, extras);
|
|
282
309
|
}
|
|
283
310
|
throw new UnavailabilityError('Linking', 'sendIntent');
|
|
284
311
|
}
|
|
285
312
|
|
|
313
|
+
// @needsAudit
|
|
286
314
|
/**
|
|
287
|
-
*
|
|
288
|
-
*
|
|
315
|
+
* Open the operating system settings app and displays the app’s custom settings, if it has any.
|
|
289
316
|
* @platform ios
|
|
290
317
|
*/
|
|
291
318
|
export async function openSettings(): Promise<void> {
|
|
@@ -298,33 +325,49 @@ export async function openSettings(): Promise<void> {
|
|
|
298
325
|
await openURL('app-settings:');
|
|
299
326
|
}
|
|
300
327
|
|
|
328
|
+
// @needsAudit
|
|
301
329
|
/**
|
|
302
|
-
*
|
|
303
|
-
*
|
|
330
|
+
* Get the URL that was used to launch the app if it was launched by a link.
|
|
331
|
+
* @return The URL string that launched your app, or `null`.
|
|
304
332
|
*/
|
|
305
333
|
export async function getInitialURL(): Promise<string | null> {
|
|
306
334
|
return (await NativeLinking.getInitialURL()) ?? null;
|
|
307
335
|
}
|
|
308
336
|
|
|
337
|
+
// @needsAudit
|
|
309
338
|
/**
|
|
310
|
-
*
|
|
339
|
+
* Attempt to open the given URL with an installed app. See the [Linking guide](/guides/linking)
|
|
340
|
+
* for more information.
|
|
341
|
+
* @param url A URL for the operating system to open, eg: `tel:5555555`, `exp://`.
|
|
342
|
+
* @return A `Promise` that is fulfilled with `true` if the link is opened operating system
|
|
343
|
+
* automatically or the user confirms the prompt to open the link. The `Promise` rejects if there
|
|
344
|
+
* are no applications registered for the URL or the user cancels the dialog.
|
|
311
345
|
*/
|
|
312
346
|
export async function openURL(url: string): Promise<true> {
|
|
313
347
|
validateURL(url);
|
|
314
348
|
return await NativeLinking.openURL(url);
|
|
315
349
|
}
|
|
316
350
|
|
|
351
|
+
// @needsAudit
|
|
317
352
|
/**
|
|
318
353
|
* Determine whether or not an installed app can handle a given URL.
|
|
319
|
-
* On web this always returns true because there is no API for detecting what URLs can be opened.
|
|
354
|
+
* On web this always returns `true` because there is no API for detecting what URLs can be opened.
|
|
355
|
+
* @param url The URL that you want to test can be opened.
|
|
356
|
+
* @return A `Promise` object that is fulfilled with `true` if the URL can be handled, otherwise it
|
|
357
|
+
* `false` if not.
|
|
358
|
+
*
|
|
359
|
+
* The `Promise` will reject on Android if it was impossible to check if the URL can be opened, and
|
|
360
|
+
* on iOS if you didn't [add the specific scheme in the `LSApplicationQueriesSchemes` key inside **Info.plist**](/guides/linking#opening-links-to-other-apps).
|
|
320
361
|
*/
|
|
321
362
|
export async function canOpenURL(url: string): Promise<boolean> {
|
|
322
363
|
validateURL(url);
|
|
323
364
|
return await NativeLinking.canOpenURL(url);
|
|
324
365
|
}
|
|
325
366
|
|
|
367
|
+
// @needsAudit
|
|
326
368
|
/**
|
|
327
369
|
* Returns the initial URL followed by any subsequent changes to the URL.
|
|
370
|
+
* @return Returns the initial URL or `null`.
|
|
328
371
|
*/
|
|
329
372
|
export function useURL(): string | null {
|
|
330
373
|
const [url, setLink] = useState<string | null>(null);
|
|
@@ -335,22 +378,12 @@ export function useURL(): string | null {
|
|
|
335
378
|
|
|
336
379
|
useEffect(() => {
|
|
337
380
|
getInitialURL().then((url) => setLink(url));
|
|
338
|
-
addEventListener('url', onChange);
|
|
339
|
-
return () =>
|
|
381
|
+
const subscription = addEventListener('url', onChange);
|
|
382
|
+
return () => subscription.remove();
|
|
340
383
|
}, []);
|
|
341
384
|
|
|
342
385
|
return url;
|
|
343
386
|
}
|
|
344
387
|
|
|
345
|
-
/**
|
|
346
|
-
* Returns the initial URL followed by any subsequent changes to the URL.
|
|
347
|
-
* @deprecated Use `useURL` instead.
|
|
348
|
-
*/
|
|
349
|
-
export function useUrl(): string | null {
|
|
350
|
-
console.warn(
|
|
351
|
-
`Linking.useUrl has been deprecated in favor of Linking.useURL. This API will be removed in SDK 44.`
|
|
352
|
-
);
|
|
353
|
-
return useURL();
|
|
354
|
-
}
|
|
355
|
-
|
|
356
388
|
export * from './Linking.types';
|
|
389
|
+
export * from './Schemes';
|
package/src/Linking.types.ts
CHANGED
|
@@ -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
|
-
|
|
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,8 +1,9 @@
|
|
|
1
1
|
import Constants, { ExecutionEnvironment } from 'expo-constants';
|
|
2
2
|
import { Platform } from 'expo-modules-core';
|
|
3
3
|
|
|
4
|
-
const LINKING_GUIDE_URL = `https://docs.expo.
|
|
4
|
+
const LINKING_GUIDE_URL = `https://docs.expo.dev/guides/linking/`;
|
|
5
5
|
|
|
6
|
+
// @docsMissing
|
|
6
7
|
export function hasCustomScheme(): boolean {
|
|
7
8
|
if (Constants.executionEnvironment === ExecutionEnvironment.Bare) {
|
|
8
9
|
// Bare always uses a custom scheme.
|
|
@@ -101,21 +102,25 @@ function getNativeAppIdScheme(): string | null {
|
|
|
101
102
|
);
|
|
102
103
|
}
|
|
103
104
|
|
|
105
|
+
// @needsAudit
|
|
106
|
+
/**
|
|
107
|
+
* Ensure the user has linked the expo-constants manifest in bare workflow.
|
|
108
|
+
*/
|
|
104
109
|
export function hasConstantsManifest(): boolean {
|
|
105
|
-
// Ensure the user has linked the expo-constants manifest in bare workflow.
|
|
106
110
|
return (
|
|
107
111
|
!!Object.keys(Constants.manifest ?? {}).length ||
|
|
108
112
|
!!Object.keys(Constants.manifest2 ?? {}).length
|
|
109
113
|
);
|
|
110
114
|
}
|
|
111
115
|
|
|
112
|
-
|
|
116
|
+
// @docsMissing
|
|
117
|
+
export function resolveScheme(options: { scheme?: string; isSilent?: boolean }): string {
|
|
113
118
|
if (
|
|
114
119
|
Constants.executionEnvironment !== ExecutionEnvironment.StoreClient &&
|
|
115
120
|
!hasConstantsManifest()
|
|
116
121
|
) {
|
|
117
122
|
throw new Error(
|
|
118
|
-
`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/
|
|
123
|
+
`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/main/packages/expo-constants/README.md`
|
|
119
124
|
);
|
|
120
125
|
}
|
|
121
126
|
|
|
@@ -123,7 +128,7 @@ export function resolveScheme(props: { scheme?: string; isSilent?: boolean }): s
|
|
|
123
128
|
const nativeAppId = getNativeAppIdScheme();
|
|
124
129
|
|
|
125
130
|
if (!manifestSchemes.length) {
|
|
126
|
-
if (__DEV__ && !
|
|
131
|
+
if (__DEV__ && !options.isSilent) {
|
|
127
132
|
// Assert a config warning if no scheme is setup yet. `isSilent` is used for warnings, but we'll ignore it for exceptions.
|
|
128
133
|
console.warn(
|
|
129
134
|
`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}`
|
|
@@ -138,10 +143,10 @@ export function resolveScheme(props: { scheme?: string; isSilent?: boolean }): s
|
|
|
138
143
|
|
|
139
144
|
// In the Expo client...
|
|
140
145
|
if (Constants.executionEnvironment === ExecutionEnvironment.StoreClient) {
|
|
141
|
-
if (
|
|
146
|
+
if (options.scheme) {
|
|
142
147
|
// This enables users to use the fb or google redirects on iOS in the Expo client.
|
|
143
|
-
if (EXPO_CLIENT_SCHEMES.includes(
|
|
144
|
-
return
|
|
148
|
+
if (EXPO_CLIENT_SCHEMES.includes(options.scheme)) {
|
|
149
|
+
return options.scheme;
|
|
145
150
|
}
|
|
146
151
|
// Silently ignore to make bare workflow development easier.
|
|
147
152
|
}
|
|
@@ -151,15 +156,15 @@ export function resolveScheme(props: { scheme?: string; isSilent?: boolean }): s
|
|
|
151
156
|
|
|
152
157
|
const schemes = [...manifestSchemes, nativeAppId].filter(Boolean);
|
|
153
158
|
|
|
154
|
-
if (
|
|
159
|
+
if (options.scheme) {
|
|
155
160
|
if (__DEV__) {
|
|
156
161
|
// Bare workflow development assertion about the provided scheme matching the Expo config.
|
|
157
|
-
if (!schemes.includes(
|
|
162
|
+
if (!schemes.includes(options.scheme) && !options.isSilent) {
|
|
158
163
|
// TODO: Will this cause issues for things like Facebook or Google that use `reversed-client-id://` or `fb<FBID>:/`?
|
|
159
164
|
// Traditionally these APIs don't use the Linking API directly.
|
|
160
165
|
console.warn(
|
|
161
166
|
`The provided Linking scheme '${
|
|
162
|
-
|
|
167
|
+
options.scheme
|
|
163
168
|
}' does not appear in the list of possible URI schemes in your Expo config. Expected one of: ${schemes
|
|
164
169
|
.map((scheme) => `'${scheme}'`)
|
|
165
170
|
.join(', ')}`
|
|
@@ -167,7 +172,7 @@ export function resolveScheme(props: { scheme?: string; isSilent?: boolean }): s
|
|
|
167
172
|
}
|
|
168
173
|
}
|
|
169
174
|
// Return the user provided value.
|
|
170
|
-
return
|
|
175
|
+
return options.scheme;
|
|
171
176
|
}
|
|
172
177
|
// If no scheme is provided, we'll guess what the scheme is based on the manifest.
|
|
173
178
|
// This is to attempt to keep managed apps working across expo build and EAS build.
|
|
@@ -175,7 +180,7 @@ export function resolveScheme(props: { scheme?: string; isSilent?: boolean }): s
|
|
|
175
180
|
// be using one of defined schemes.
|
|
176
181
|
|
|
177
182
|
// If the native app id is the only scheme,
|
|
178
|
-
if (!!nativeAppId && !manifestSchemes.length && !
|
|
183
|
+
if (!!nativeAppId && !manifestSchemes.length && !options.isSilent) {
|
|
179
184
|
// Assert a config warning if no scheme is setup yet.
|
|
180
185
|
// This warning only applies to managed workflow EAS apps, as bare workflow
|
|
181
186
|
console.warn(
|
|
@@ -195,7 +200,7 @@ export function resolveScheme(props: { scheme?: string; isSilent?: boolean }): s
|
|
|
195
200
|
// Throw in production, use the __DEV__ flag so users can test this functionality with `expo start --no-dev`
|
|
196
201
|
throw new Error(errorMessage);
|
|
197
202
|
}
|
|
198
|
-
if (extraSchemes.length && !
|
|
203
|
+
if (extraSchemes.length && !options.isSilent) {
|
|
199
204
|
console.warn(
|
|
200
205
|
`Linking found multiple possible URI schemes in your Expo config.\nUsing '${scheme}'. Ignoring: ${[
|
|
201
206
|
...extraSchemes,
|