expo-linking 2.4.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -10,9 +10,16 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
- ## 2.4.2 — 2021-10-15
13
+ ## 3.0.0 — 2021-12-03
14
14
 
15
- _This version does not introduce any user-facing changes._
15
+ ### 🛠 Breaking changes
16
+
17
+ - Remove deprecated `useUrl` method. ([#15226](https://github.com/expo/expo/pull/15226) by [@Simek](https://github.com/Simek))
18
+
19
+ ### 💡 Others
20
+
21
+ - Update `qs` dependency. ([#15069](https://github.com/expo/expo/pull/15069) by [@Simek](https://github.com/Simek))
22
+ - Extract `sendIntent` method `extras` parameter to the separate type named `SendIntentExtras`. ([#15226](https://github.com/expo/expo/pull/15226) by [@Simek](https://github.com/Simek))
16
23
 
17
24
  ## 2.4.1 — 2021-10-01
18
25
 
package/README.md CHANGED
@@ -13,7 +13,7 @@ For managed [managed](https://docs.expo.io/versions/latest/introduction/managed-
13
13
 
14
14
  # Installation in bare React Native projects
15
15
 
16
- For bare React Native projects, you must ensure that you have [installed and configured the `react-native-unimodules` package](https://github.com/expo/expo/tree/master/packages/react-native-unimodules) before continuing.
16
+ For bare React Native projects, you must ensure that you have [installed and configured the `expo` package](https://docs.expo.dev/bare/installing-expo-modules/) before continuing.
17
17
 
18
18
  ### Add the package to your npm dependencies
19
19
 
@@ -1,10 +1,9 @@
1
- import { CreateURLOptions, ParsedURL, QueryParams, URLListener } from './Linking.types';
1
+ import { CreateURLOptions, ParsedURL, QueryParams, SendIntentExtras, URLListener } from './Linking.types';
2
2
  /**
3
3
  * Create a URL that works for the environment the app is currently running in.
4
4
  * The scheme in bare and standalone must be defined in the app.json under `expo.scheme`.
5
5
  *
6
- * **Examples**
7
- *
6
+ * # Examples
8
7
  * - Bare: empty string
9
8
  * - Standalone, Custom: `yourscheme:///path`
10
9
  * - Web (dev): `https://localhost:19006/path`
@@ -13,87 +12,107 @@ import { CreateURLOptions, ParsedURL, QueryParams, URLListener } from './Linking
13
12
  * - Expo Client (prod): `exp://exp.host/@yourname/your-app/--/path`
14
13
  *
15
14
  * @param path addition path components to append to the base URL.
16
- * @param queryParams An object of parameters that will be converted into a query string.
15
+ * @param queryParams An object with a set of query parameters. These will be merged with any
16
+ * Expo-specific parameters that are needed (e.g. release channel) and then appended to the URL
17
+ * as a query string.
18
+ * @param scheme Optional URI protocol to use in the URL `<scheme>:///`, when `undefined` the scheme
19
+ * will be chosen from the Expo config (`app.config.js` or `app.json`).
20
+ * @return A URL string which points to your app with the given deep link information.
21
+ * @deprecated An alias for [`createURL()`](#linkingcreateurlpath-namedparameters). This method is
22
+ * deprecated and will be removed in a future SDK version.
17
23
  */
18
24
  export declare function makeUrl(path?: string, queryParams?: QueryParams, scheme?: string): string;
19
25
  /**
20
- * Create a URL that works for the environment the app is currently running in.
21
- * The scheme in bare and standalone must be defined in the Expo config (app.config.js or app.json) under `expo.scheme`.
26
+ * Helper method for constructing a deep link into your app, given an optional path and set of query
27
+ * parameters. Creates a URI scheme with two slashes by default.
22
28
  *
23
- * **Examples**
29
+ * The scheme in bare and standalone must be defined in the Expo config (`app.config.js` or `app.json`)
30
+ * under `expo.scheme`.
24
31
  *
25
- * - Bare: `<scheme>://path` -- uses provided scheme or scheme from Expo config `scheme`.
32
+ * # Examples
33
+ * - Bare: `<scheme>://path` - uses provided scheme or scheme from Expo config `scheme`.
26
34
  * - Standalone, Custom: `yourscheme://path`
27
35
  * - Web (dev): `https://localhost:19006/path`
28
36
  * - Web (prod): `https://myapp.com/path`
29
37
  * - Expo Client (dev): `exp://128.0.0.1:19000/--/path`
30
38
  * - Expo Client (prod): `exp://exp.host/@yourname/your-app/--/path`
31
39
  *
32
- * @param path addition path components to append to the base URL.
33
- * @param scheme URI protocol `<scheme>://` that must be built into your native app.
34
- * @param queryParams An object of parameters that will be converted into a query string.
40
+ * @param path Addition path components to append to the base URL.
41
+ * @param namedParameters Additional options object.
42
+ * @return A URL string which points to your app with the given deep link information.
35
43
  */
36
44
  export declare function createURL(path: string, { scheme, queryParams, isTripleSlashed }?: CreateURLOptions): string;
37
45
  /**
38
- * Returns the components and query parameters for a given URL.
39
- *
40
- * @param url Input URL to parse
46
+ * Helper method for parsing out deep link information from a URL.
47
+ * @param url A URL that points to the currently running experience (e.g. an output of `Linking.createURL()`).
48
+ * @return A `ParsedURL` object.
41
49
  */
42
50
  export declare function parse(url: string): ParsedURL;
43
51
  /**
44
- * Add a handler to Linking changes by listening to the `url` event type
45
- * and providing the handler
46
- *
47
- * See https://reactnative.dev/docs/linking.html#addeventlistener
52
+ * Add a handler to `Linking` changes by listening to the `url` event type and providing the handler.
53
+ * It is recommended to use the [`useURL()`](#useurl) hook instead.
54
+ * @param type The only valid type is `'url'`.
55
+ * @param handler An [`URLListener`](#urllistener) function that takes an `event` object of the type
56
+ * [`EventType`](#eventype).
57
+ * @see [React Native Docs Linking page](https://reactnative.dev/docs/linking#addeventlistener).
48
58
  */
49
59
  export declare function addEventListener(type: string, handler: URLListener): void;
50
60
  /**
51
61
  * Remove a handler by passing the `url` event type and the handler.
52
- *
53
- * See https://reactnative.dev/docs/linking.html#removeeventlistener
62
+ * @param type The only valid type is `'url'`.
63
+ * @param handler An [`URLListener`](#urllistener) function that takes an `event` object of the type
64
+ * [`EventType`](#eventype).
65
+ * @see [React Native Docs Linking page](https://reactnative.dev/docs/linking#removeeventlistener).
54
66
  */
55
67
  export declare function removeEventListener(type: string, handler: URLListener): void;
56
68
  /**
57
- * **Native:** Parses the link that opened the app. If no link opened the app, all the fields will be \`null\`.
58
- * **Web:** Parses the current window URL.
69
+ * Helper method which wraps React Native's `Linking.getInitialURL()` in `Linking.parse()`.
70
+ * Parses the deep link information out of the URL used to open the experience initially.
71
+ * If no link opened the app, all the fields will be `null`.
72
+ * > On the web it parses the current window URL.
73
+ * @return A promise that resolves with `ParsedURL` object.
59
74
  */
60
75
  export declare function parseInitialURLAsync(): Promise<ParsedURL>;
61
76
  /**
62
- * Launch an Android intent with optional extras
63
- *
77
+ * Launch an Android intent with extras.
78
+ * > Use [IntentLauncher](../intent-launcher) instead, `sendIntent` is only included in
79
+ * > `Linking` for API compatibility with React Native's Linking API.
64
80
  * @platform android
65
81
  */
66
- export declare function sendIntent(action: string, extras?: {
67
- key: string;
68
- value: string | number | boolean;
69
- }[]): Promise<void>;
82
+ export declare function sendIntent(action: string, extras?: SendIntentExtras[]): Promise<void>;
70
83
  /**
71
- * Attempt to open the system settings for an the app.
72
- *
84
+ * Open the operating system settings app and displays the app’s custom settings, if it has any.
73
85
  * @platform ios
74
86
  */
75
87
  export declare function openSettings(): Promise<void>;
76
88
  /**
77
- * If the app launch was triggered by an app link,
78
- * it will give the link url, otherwise it will give `null`
89
+ * Get the URL that was used to launch the app if it was launched by a link.
90
+ * @return The URL string that launched your app, or `null`.
79
91
  */
80
92
  export declare function getInitialURL(): Promise<string | null>;
81
93
  /**
82
- * Try to open the given `url` with any of the installed apps.
94
+ * Attempt to open the given URL with an installed app. See the [Linking guide](/guides/linking)
95
+ * for more information.
96
+ * @param url A URL for the operating system to open, eg: `tel:5555555`, `exp://`.
97
+ * @return A `Promise` that is fulfilled with `true` if the link is opened operating system
98
+ * automatically or the user confirms the prompt to open the link. The `Promise` rejects if there
99
+ * are no applications registered for the URL or the user cancels the dialog.
83
100
  */
84
101
  export declare function openURL(url: string): Promise<true>;
85
102
  /**
86
103
  * Determine whether or not an installed app can handle a given URL.
87
- * On web this always returns true because there is no API for detecting what URLs can be opened.
104
+ * On web this always returns `true` because there is no API for detecting what URLs can be opened.
105
+ * @param url The URL that you want to test can be opened.
106
+ * @return A `Promise` object that is fulfilled with `true` if the URL can be handled, otherwise it
107
+ * `false` if not.
108
+ *
109
+ * The `Promise` will reject on Android if it was impossible to check if the URL can be opened, and
110
+ * on iOS if you didn't [add the specific scheme in the `LSApplicationQueriesSchemes` key inside **Info.plist**](/guides/linking#opening-links-to-other-apps).
88
111
  */
89
112
  export declare function canOpenURL(url: string): Promise<boolean>;
90
113
  /**
91
114
  * Returns the initial URL followed by any subsequent changes to the URL.
115
+ * @return Returns the initial URL or `null`.
92
116
  */
93
117
  export declare function useURL(): string | null;
94
- /**
95
- * Returns the initial URL followed by any subsequent changes to the URL.
96
- * @deprecated Use `useURL` instead.
97
- */
98
- export declare function useUrl(): string | null;
99
118
  export * from './Linking.types';
package/build/Linking.js CHANGED
@@ -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
- * **Examples**
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 that will be converted into a query string.
81
+ * @param queryParams An object with a set of query parameters. These will be merged with any
82
+ * Expo-specific parameters that are needed (e.g. release channel) and then appended to the URL
83
+ * as a query string.
84
+ * @param scheme Optional URI protocol to use in the URL `<scheme>:///`, when `undefined` the scheme
85
+ * will be chosen from the Expo config (`app.config.js` or `app.json`).
86
+ * @return A URL string which points to your app with the given deep link information.
87
+ * @deprecated An alias for [`createURL()`](#linkingcreateurlpath-namedparameters). This method is
88
+ * deprecated and will be removed in a future SDK version.
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
- * Create a URL that works for the environment the app is currently running in.
88
- * The scheme in bare and standalone must be defined in the Expo config (app.config.js or app.json) under `expo.scheme`.
95
+ * Helper method for constructing a deep link into your app, given an optional path and set of query
96
+ * parameters. Creates a URI scheme with two slashes by default.
89
97
  *
90
- * **Examples**
98
+ * The scheme in bare and standalone must be defined in the Expo config (`app.config.js` or `app.json`)
99
+ * under `expo.scheme`.
91
100
  *
92
- * - Bare: `<scheme>://path` -- uses provided scheme or scheme from Expo config `scheme`.
101
+ * # Examples
102
+ * - Bare: `<scheme>://path` - uses provided scheme or scheme from Expo config `scheme`.
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 addition path components to append to the base URL.
100
- * @param scheme URI protocol `<scheme>://` that must be built into your native app.
101
- * @param queryParams An object of parameters that will be converted into a query string.
109
+ * @param path Addition path components to append to the base URL.
110
+ * @param namedParameters Additional options object.
111
+ * @return A URL string which points to your app with the given deep link information.
102
112
  */
103
113
  export function createURL(path, { scheme, queryParams = {}, isTripleSlashed = false } = {}) {
104
114
  if (Platform.OS === 'web') {
@@ -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
- * Returns the components and query parameters for a given URL.
162
- *
163
- * @param url Input URL to parse
172
+ * Helper method for parsing out deep link information from a URL.
173
+ * @param url A URL that points to the currently running experience (e.g. an output of `Linking.createURL()`).
174
+ * @return A `ParsedURL` object.
164
175
  */
165
176
  export function parse(url) {
166
177
  validateURL(url);
@@ -200,26 +211,35 @@ export function parse(url) {
200
211
  scheme,
201
212
  };
202
213
  }
214
+ // @needsAudit
203
215
  /**
204
- * Add a handler to Linking changes by listening to the `url` event type
205
- * and providing the handler
206
- *
207
- * See https://reactnative.dev/docs/linking.html#addeventlistener
216
+ * Add a handler to `Linking` changes by listening to the `url` event type and providing the handler.
217
+ * It is recommended to use the [`useURL()`](#useurl) hook instead.
218
+ * @param type The only valid type is `'url'`.
219
+ * @param handler An [`URLListener`](#urllistener) function that takes an `event` object of the type
220
+ * [`EventType`](#eventype).
221
+ * @see [React Native Docs Linking page](https://reactnative.dev/docs/linking#addeventlistener).
208
222
  */
209
223
  export function addEventListener(type, handler) {
210
224
  NativeLinking.addEventListener(type, handler);
211
225
  }
212
226
  /**
213
227
  * Remove a handler by passing the `url` event type and the handler.
214
- *
215
- * See https://reactnative.dev/docs/linking.html#removeeventlistener
228
+ * @param type The only valid type is `'url'`.
229
+ * @param handler An [`URLListener`](#urllistener) function that takes an `event` object of the type
230
+ * [`EventType`](#eventype).
231
+ * @see [React Native Docs Linking page](https://reactnative.dev/docs/linking#removeeventlistener).
216
232
  */
217
233
  export function removeEventListener(type, handler) {
218
234
  NativeLinking.removeEventListener(type, handler);
219
235
  }
236
+ // @needsAudit
220
237
  /**
221
- * **Native:** Parses the link that opened the app. If no link opened the app, all the fields will be \`null\`.
222
- * **Web:** Parses the current window URL.
238
+ * Helper method which wraps React Native's `Linking.getInitialURL()` in `Linking.parse()`.
239
+ * Parses the deep link information out of the URL used to open the experience initially.
240
+ * If no link opened the app, all the fields will be `null`.
241
+ * > On the web it parses the current window URL.
242
+ * @return A promise that resolves with `ParsedURL` object.
223
243
  */
224
244
  export async function parseInitialURLAsync() {
225
245
  const initialUrl = await NativeLinking.getInitialURL();
@@ -233,9 +253,11 @@ export async function parseInitialURLAsync() {
233
253
  }
234
254
  return parse(initialUrl);
235
255
  }
256
+ // @needsAudit
236
257
  /**
237
- * Launch an Android intent with optional extras
238
- *
258
+ * Launch an Android intent with extras.
259
+ * > Use [IntentLauncher](../intent-launcher) instead, `sendIntent` is only included in
260
+ * > `Linking` for API compatibility with React Native's Linking API.
239
261
  * @platform android
240
262
  */
241
263
  export async function sendIntent(action, extras) {
@@ -244,9 +266,9 @@ export async function sendIntent(action, extras) {
244
266
  }
245
267
  throw new UnavailabilityError('Linking', 'sendIntent');
246
268
  }
269
+ // @needsAudit
247
270
  /**
248
- * Attempt to open the system settings for an the app.
249
- *
271
+ * Open the operating system settings app and displays the app’s custom settings, if it has any.
250
272
  * @platform ios
251
273
  */
252
274
  export async function openSettings() {
@@ -258,30 +280,46 @@ export async function openSettings() {
258
280
  }
259
281
  await openURL('app-settings:');
260
282
  }
283
+ // @needsAudit
261
284
  /**
262
- * If the app launch was triggered by an app link,
263
- * it will give the link url, otherwise it will give `null`
285
+ * Get the URL that was used to launch the app if it was launched by a link.
286
+ * @return The URL string that launched your app, or `null`.
264
287
  */
265
288
  export async function getInitialURL() {
266
289
  return (await NativeLinking.getInitialURL()) ?? null;
267
290
  }
291
+ // @needsAudit
268
292
  /**
269
- * Try to open the given `url` with any of the installed apps.
293
+ * Attempt to open the given URL with an installed app. See the [Linking guide](/guides/linking)
294
+ * for more information.
295
+ * @param url A URL for the operating system to open, eg: `tel:5555555`, `exp://`.
296
+ * @return A `Promise` that is fulfilled with `true` if the link is opened operating system
297
+ * automatically or the user confirms the prompt to open the link. The `Promise` rejects if there
298
+ * are no applications registered for the URL or the user cancels the dialog.
270
299
  */
271
300
  export async function openURL(url) {
272
301
  validateURL(url);
273
302
  return await NativeLinking.openURL(url);
274
303
  }
304
+ // @needsAudit
275
305
  /**
276
306
  * Determine whether or not an installed app can handle a given URL.
277
- * On web this always returns true because there is no API for detecting what URLs can be opened.
307
+ * On web this always returns `true` because there is no API for detecting what URLs can be opened.
308
+ * @param url The URL that you want to test can be opened.
309
+ * @return A `Promise` object that is fulfilled with `true` if the URL can be handled, otherwise it
310
+ * `false` if not.
311
+ *
312
+ * The `Promise` will reject on Android if it was impossible to check if the URL can be opened, and
313
+ * on iOS if you didn't [add the specific scheme in the `LSApplicationQueriesSchemes` key inside **Info.plist**](/guides/linking#opening-links-to-other-apps).
278
314
  */
279
315
  export async function canOpenURL(url) {
280
316
  validateURL(url);
281
317
  return await NativeLinking.canOpenURL(url);
282
318
  }
319
+ // @needsAudit
283
320
  /**
284
321
  * Returns the initial URL followed by any subsequent changes to the URL.
322
+ * @return Returns the initial URL or `null`.
285
323
  */
286
324
  export function useURL() {
287
325
  const [url, setLink] = useState(null);
@@ -295,13 +333,5 @@ export function useURL() {
295
333
  }, []);
296
334
  return url;
297
335
  }
298
- /**
299
- * Returns the initial URL followed by any subsequent changes to the URL.
300
- * @deprecated Use `useURL` instead.
301
- */
302
- export function useUrl() {
303
- console.warn(`Linking.useUrl has been deprecated in favor of Linking.useURL. This API will be removed in SDK 44.`);
304
- return useURL();
305
- }
306
336
  export * from './Linking.types';
307
337
  //# sourceMappingURL=Linking.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Linking.js","sourceRoot":"","sources":["../src/Linking.ts"],"names":[],"mappings":"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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 URL from 'url-parse';\n\nimport NativeLinking from './ExpoLinking';\nimport {\n CreateURLOptions,\n ParsedURL,\n QueryParams,\n SendIntentExtras,\n URLListener,\n} from './Linking.types';\nimport { hasCustomScheme, resolveScheme } from './Schemes';\n\nfunction validateURL(url: string): void {\n invariant(typeof url === 'string', 'Invalid URL: should be a string. Was: ' + url);\n invariant(url, 'Invalid URL: cannot be empty');\n}\n\nfunction getHostUri(): string | null {\n if (Constants.manifest?.hostUri) {\n return Constants.manifest.hostUri;\n } else if (Constants.manifest2?.extra?.expoClient?.hostUri) {\n return Constants.manifest2.extra.expoClient.hostUri;\n } else if (!hasCustomScheme()) {\n // we're probably not using up-to-date xdl, so just fake it for now\n // we have to remove the /--/ on the end since this will be inserted again later\n return removeScheme(Constants.linkingUri).replace(/\\/--($|\\/.*$)/, '');\n } else {\n return null;\n }\n}\n\nfunction isExpoHosted(): boolean {\n const hostUri = getHostUri();\n return !!(\n hostUri &&\n (/^(.*\\.)?(expo\\.io|exp\\.host|exp\\.direct|expo\\.test)(:.*)?(\\/.*)?$/.test(hostUri) ||\n Constants.manifest?.developer)\n );\n}\n\nfunction removeScheme(url: string): string {\n return url.replace(/^[a-zA-Z0-9+.-]+:\\/\\//, '');\n}\n\nfunction removePort(url: string): string {\n return url.replace(/(?=([a-zA-Z0-9+.-]+:\\/\\/)?[^/]):\\d+/, '');\n}\n\nfunction removeLeadingSlash(url: string): string {\n return url.replace(/^\\//, '');\n}\n\nfunction removeTrailingSlashAndQueryString(url: string): string {\n return url.replace(/\\/?\\?.*$/, '');\n}\n\nfunction ensureTrailingSlash(input: string, shouldAppend: boolean): string {\n const hasSlash = input.endsWith('/');\n if (hasSlash && !shouldAppend) {\n return input.substring(0, input.length - 1);\n } else if (!hasSlash && shouldAppend) {\n return `${input}/`;\n }\n return input;\n}\n\nfunction ensureLeadingSlash(input: string, shouldAppend: boolean): string {\n const hasSlash = input.startsWith('/');\n if (hasSlash && !shouldAppend) {\n return input.substring(1);\n } else if (!hasSlash && shouldAppend) {\n return `/${input}`;\n }\n return input;\n}\n\n// @needsAudit\n/**\n * Create a URL that works for the environment the app is currently running in.\n * The scheme in bare and standalone must be defined in the app.json under `expo.scheme`.\n *\n * # Examples\n * - Bare: empty string\n * - Standalone, Custom: `yourscheme:///path`\n * - Web (dev): `https://localhost:19006/path`\n * - Web (prod): `https://myapp.com/path`\n * - Expo Client (dev): `exp://128.0.0.1:19000/--/path`\n * - Expo Client (prod): `exp://exp.host/@yourname/your-app/--/path`\n *\n * @param path addition path components to append to the base URL.\n * @param queryParams An object with a set of query parameters. These will be merged with any\n * Expo-specific parameters that are needed (e.g. release channel) and then appended to the URL\n * as a query string.\n * @param scheme Optional URI protocol to use in the URL `<scheme>:///`, when `undefined` the scheme\n * will be chosen from the Expo config (`app.config.js` or `app.json`).\n * @return A URL string which points to your app with the given deep link information.\n * @deprecated An alias for [`createURL()`](#linkingcreateurlpath-namedparameters). This method is\n * deprecated and will be removed in a future SDK version.\n */\nexport function makeUrl(path: string = '', queryParams?: QueryParams, scheme?: string): string {\n return createURL(path, { queryParams, scheme, isTripleSlashed: true });\n}\n\n// @needsAudit\n/**\n * Helper method for constructing a deep link into your app, given an optional path and set of query\n * parameters. Creates a URI scheme with two slashes by default.\n *\n * The scheme in bare and standalone must be defined in the Expo config (`app.config.js` or `app.json`)\n * under `expo.scheme`.\n *\n * # Examples\n * - Bare: `<scheme>://path` - uses provided scheme or scheme from Expo config `scheme`.\n * - Standalone, Custom: `yourscheme://path`\n * - Web (dev): `https://localhost:19006/path`\n * - Web (prod): `https://myapp.com/path`\n * - Expo Client (dev): `exp://128.0.0.1:19000/--/path`\n * - Expo Client (prod): `exp://exp.host/@yourname/your-app/--/path`\n *\n * @param path Addition path components to append to the base URL.\n * @param namedParameters Additional options object.\n * @return A URL string which points to your app with the given deep link information.\n */\nexport function createURL(\n path: string,\n { scheme, queryParams = {}, isTripleSlashed = false }: CreateURLOptions = {}\n): string {\n if (Platform.OS === 'web') {\n if (!Platform.isDOMAvailable) return '';\n\n const origin = ensureTrailingSlash(window.location.origin, false);\n let queryString = qs.stringify(queryParams);\n if (queryString) {\n queryString = `?${queryString}`;\n }\n\n let outputPath = path;\n if (outputPath) outputPath = ensureLeadingSlash(path, true);\n\n return encodeURI(`${origin}${outputPath}${queryString}`);\n }\n\n const resolvedScheme = resolveScheme({ scheme });\n\n let hostUri = getHostUri() || '';\n\n if (hasCustomScheme() && isExpoHosted()) {\n hostUri = '';\n }\n\n if (path) {\n if (isExpoHosted() && hostUri) {\n path = `/--/${removeLeadingSlash(path)}`;\n }\n if (isTripleSlashed && !path.startsWith('/')) {\n path = `/${path}`;\n }\n } else {\n path = '';\n }\n\n // merge user-provided query params with any that were already in the hostUri\n // e.g. release-channel\n let queryString = '';\n const queryStringMatchResult = hostUri.match(/(.*)\\?(.+)/);\n if (queryStringMatchResult) {\n hostUri = queryStringMatchResult[1];\n queryString = queryStringMatchResult[2];\n let paramsFromHostUri = {};\n try {\n const parsedParams = qs.parse(queryString);\n if (typeof parsedParams === 'object') {\n paramsFromHostUri = parsedParams;\n }\n } catch (e) {}\n queryParams = {\n ...queryParams,\n ...paramsFromHostUri,\n };\n }\n queryString = qs.stringify(queryParams);\n if (queryString) {\n queryString = `?${queryString}`;\n }\n\n hostUri = ensureLeadingSlash(hostUri, !isTripleSlashed);\n\n return encodeURI(\n `${resolvedScheme}:${isTripleSlashed ? '/' : ''}/${hostUri}${path}${queryString}`\n );\n}\n\n// @needsAudit\n/**\n * Helper method for parsing out deep link information from a URL.\n * @param url A URL that points to the currently running experience (e.g. an output of `Linking.createURL()`).\n * @return A `ParsedURL` object.\n */\nexport function parse(url: string): ParsedURL {\n validateURL(url);\n\n const parsed = URL(url, /* parseQueryString */ true);\n\n for (const param in parsed.query) {\n parsed.query[param] = decodeURIComponent(parsed.query[param]!);\n }\n const queryParams = parsed.query;\n\n const hostUri = getHostUri() || '';\n const hostUriStripped = removePort(removeTrailingSlashAndQueryString(hostUri));\n\n let path = parsed.pathname || null;\n let hostname = parsed.hostname || null;\n let scheme = parsed.protocol || null;\n\n if (scheme) {\n // Remove colon at end\n scheme = scheme.substring(0, scheme.length - 1);\n }\n\n if (path) {\n path = removeLeadingSlash(path);\n\n let expoPrefix: string | null = null;\n if (hostUriStripped) {\n const parts = hostUriStripped.split('/');\n expoPrefix = parts.slice(1).concat(['--/']).join('/');\n }\n\n if (isExpoHosted() && !hasCustomScheme() && expoPrefix && path.startsWith(expoPrefix)) {\n path = path.substring(expoPrefix.length);\n hostname = null;\n } else if (path.indexOf('+') > -1) {\n path = path.substring(path.indexOf('+') + 1);\n }\n }\n\n return {\n hostname,\n path,\n queryParams,\n scheme,\n };\n}\n\n// @needsAudit\n/**\n * Add a handler to `Linking` changes by listening to the `url` event type and providing the handler.\n * It is recommended to use the [`useURL()`](#useurl) hook instead.\n * @param type The only valid type is `'url'`.\n * @param handler An [`URLListener`](#urllistener) function that takes an `event` object of the type\n * [`EventType`](#eventype).\n * @see [React Native Docs Linking page](https://reactnative.dev/docs/linking#addeventlistener).\n */\nexport function addEventListener(type: string, handler: URLListener): void {\n NativeLinking.addEventListener(type, handler);\n}\n\n/**\n * Remove a handler by passing the `url` event type and the handler.\n * @param type The only valid type is `'url'`.\n * @param handler An [`URLListener`](#urllistener) function that takes an `event` object of the type\n * [`EventType`](#eventype).\n * @see [React Native Docs Linking page](https://reactnative.dev/docs/linking#removeeventlistener).\n */\nexport function removeEventListener(type: string, handler: URLListener): void {\n NativeLinking.removeEventListener(type, handler);\n}\n\n// @needsAudit\n/**\n * Helper method which wraps React Native's `Linking.getInitialURL()` in `Linking.parse()`.\n * Parses the deep link information out of the URL used to open the experience initially.\n * If no link opened the app, all the fields will be `null`.\n * > On the web it parses the current window URL.\n * @return A promise that resolves with `ParsedURL` object.\n */\nexport async function parseInitialURLAsync(): Promise<ParsedURL> {\n const initialUrl = await NativeLinking.getInitialURL();\n if (!initialUrl) {\n return {\n scheme: null,\n hostname: null,\n path: null,\n queryParams: null,\n };\n }\n\n return parse(initialUrl);\n}\n\n// @needsAudit\n/**\n * Launch an Android intent with extras.\n * > Use [IntentLauncher](../intent-launcher) instead, `sendIntent` is only included in\n * > `Linking` for API compatibility with React Native's Linking API.\n * @platform android\n */\nexport async function sendIntent(action: string, extras?: SendIntentExtras[]): Promise<void> {\n if (Platform.OS === 'android') {\n return await NativeLinking.sendIntent(action, extras);\n }\n throw new UnavailabilityError('Linking', 'sendIntent');\n}\n\n// @needsAudit\n/**\n * Open the operating system settings app and displays the app’s custom settings, if it has any.\n * @platform ios\n */\nexport async function openSettings(): Promise<void> {\n if (Platform.OS === 'web') {\n throw new UnavailabilityError('Linking', 'openSettings');\n }\n if (NativeLinking.openSettings) {\n return await NativeLinking.openSettings();\n }\n await openURL('app-settings:');\n}\n\n// @needsAudit\n/**\n * Get the URL that was used to launch the app if it was launched by a link.\n * @return The URL string that launched your app, or `null`.\n */\nexport async function getInitialURL(): Promise<string | null> {\n return (await NativeLinking.getInitialURL()) ?? null;\n}\n\n// @needsAudit\n/**\n * Attempt to open the given URL with an installed app. See the [Linking guide](/guides/linking)\n * for more information.\n * @param url A URL for the operating system to open, eg: `tel:5555555`, `exp://`.\n * @return A `Promise` that is fulfilled with `true` if the link is opened operating system\n * automatically or the user confirms the prompt to open the link. The `Promise` rejects if there\n * are no applications registered for the URL or the user cancels the dialog.\n */\nexport async function openURL(url: string): Promise<true> {\n validateURL(url);\n return await NativeLinking.openURL(url);\n}\n\n// @needsAudit\n/**\n * Determine whether or not an installed app can handle a given URL.\n * On web this always returns `true` because there is no API for detecting what URLs can be opened.\n * @param url The URL that you want to test can be opened.\n * @return A `Promise` object that is fulfilled with `true` if the URL can be handled, otherwise it\n * `false` if not.\n *\n * The `Promise` will reject on Android if it was impossible to check if the URL can be opened, and\n * on iOS if you didn't [add the specific scheme in the `LSApplicationQueriesSchemes` key inside **Info.plist**](/guides/linking#opening-links-to-other-apps).\n */\nexport async function canOpenURL(url: string): Promise<boolean> {\n validateURL(url);\n return await NativeLinking.canOpenURL(url);\n}\n\n// @needsAudit\n/**\n * Returns the initial URL followed by any subsequent changes to the URL.\n * @return Returns the initial URL or `null`.\n */\nexport function useURL(): string | null {\n const [url, setLink] = useState<string | null>(null);\n\n function onChange(event: { url: string }) {\n setLink(event.url);\n }\n\n useEffect(() => {\n getInitialURL().then((url) => setLink(url));\n addEventListener('url', onChange);\n return () => removeEventListener('url', onChange);\n }, []);\n\n return url;\n}\n\nexport * from './Linking.types';\n"]}
@@ -3,7 +3,13 @@ export declare type QueryParams = ParsedQs;
3
3
  export declare type ParsedURL = {
4
4
  scheme: string | null;
5
5
  hostname: string | null;
6
+ /**
7
+ * The path into the app specified by the URL.
8
+ */
6
9
  path: string | null;
10
+ /**
11
+ * The set of query parameters specified by the query string of the url used to open the app.
12
+ */
7
13
  queryParams: QueryParams | null;
8
14
  };
9
15
  export declare type CreateURLOptions = {
@@ -26,3 +32,7 @@ export declare type EventType = {
26
32
  };
27
33
  export declare type URLListener = (event: EventType) => void;
28
34
  export declare type NativeURLListener = (nativeEvent: MessageEvent) => void;
35
+ export declare type SendIntentExtras = {
36
+ key: string;
37
+ value: string | number | boolean;
38
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"Linking.types.js","sourceRoot":"","sources":["../src/Linking.types.ts"],"names":[],"mappings":"","sourcesContent":["import { ParsedQs } from 'qs';\n\nexport type QueryParams = ParsedQs;\n\nexport type ParsedURL = {\n scheme: string | null;\n hostname: string | null;\n path: string | null;\n queryParams: QueryParams | null;\n};\n\nexport type CreateURLOptions = {\n /**\n * URI protocol `<scheme>://` that must be built into your native app.\n */\n scheme?: string;\n /**\n * An object of parameters that will be converted into a query string.\n */\n queryParams?: QueryParams;\n /**\n * Should the URI be triple slashed `scheme:///path` or double slashed `scheme://path`.\n */\n isTripleSlashed?: boolean;\n};\n\nexport type EventType = { url: string; nativeEvent?: MessageEvent };\n\nexport type URLListener = (event: EventType) => void;\n\nexport type NativeURLListener = (nativeEvent: MessageEvent) => void;\n"]}
1
+ {"version":3,"file":"Linking.types.js","sourceRoot":"","sources":["../src/Linking.types.ts"],"names":[],"mappings":"","sourcesContent":["import { ParsedQs } from 'qs';\n\n// @docsMissing\nexport type QueryParams = ParsedQs;\n\n// @needsAudit @docsMissing\nexport type ParsedURL = {\n scheme: string | null;\n hostname: string | null;\n /**\n * The path into the app specified by the URL.\n */\n path: string | null;\n /**\n * The set of query parameters specified by the query string of the url used to open the app.\n */\n queryParams: QueryParams | null;\n};\n\n// @needsAudit\nexport type CreateURLOptions = {\n /**\n * URI protocol `<scheme>://` that must be built into your native app.\n */\n scheme?: string;\n /**\n * An object of parameters that will be converted into a query string.\n */\n queryParams?: QueryParams;\n /**\n * Should the URI be triple slashed `scheme:///path` or double slashed `scheme://path`.\n */\n isTripleSlashed?: boolean;\n};\n\n// @docsMissing\nexport type EventType = {\n url: string;\n nativeEvent?: MessageEvent;\n};\n\n// @docsMissing\nexport type URLListener = (event: EventType) => void;\n\n// @docsMissing\nexport type NativeURLListener = (nativeEvent: MessageEvent) => void;\n\n// @docsMissing\nexport type SendIntentExtras = { key: string; value: string | number | boolean };\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-linking",
3
- "version": "2.4.2",
3
+ "version": "3.0.0",
4
4
  "description": "Create and open deep links universally",
5
5
  "main": "build/Linking.js",
6
6
  "types": "build/Linking.d.ts",
@@ -30,9 +30,9 @@
30
30
  "license": "MIT",
31
31
  "homepage": "https://docs.expo.dev/versions/latest/sdk/linking",
32
32
  "dependencies": {
33
- "expo-constants": "~12.1.1",
33
+ "expo-constants": "~13.0.0",
34
34
  "invariant": "^2.2.4",
35
- "qs": "^6.5.0",
35
+ "qs": "^6.9.1",
36
36
  "url-parse": "^1.4.4"
37
37
  },
38
38
  "devDependencies": {
@@ -42,5 +42,5 @@
42
42
  "jest": {
43
43
  "preset": "expo-module-scripts"
44
44
  },
45
- "gitHead": "d23e1ac491da96b51c25eb2533efcd56499ee287"
45
+ "gitHead": "2e5c6983b86d5ecfca028ba64002897d8adc2cc4"
46
46
  }
package/src/Linking.ts CHANGED
@@ -6,7 +6,13 @@ import { useEffect, useState } from 'react';
6
6
  import URL from 'url-parse';
7
7
 
8
8
  import NativeLinking from './ExpoLinking';
9
- import { CreateURLOptions, ParsedURL, QueryParams, URLListener } from './Linking.types';
9
+ import {
10
+ CreateURLOptions,
11
+ ParsedURL,
12
+ QueryParams,
13
+ SendIntentExtras,
14
+ URLListener,
15
+ } from './Linking.types';
10
16
  import { hasCustomScheme, resolveScheme } from './Schemes';
11
17
 
12
18
  function validateURL(url: string): void {
@@ -73,12 +79,12 @@ function ensureLeadingSlash(input: string, shouldAppend: boolean): string {
73
79
  return input;
74
80
  }
75
81
 
82
+ // @needsAudit
76
83
  /**
77
84
  * Create a URL that works for the environment the app is currently running in.
78
85
  * The scheme in bare and standalone must be defined in the app.json under `expo.scheme`.
79
86
  *
80
- * **Examples**
81
- *
87
+ * # Examples
82
88
  * - Bare: empty string
83
89
  * - Standalone, Custom: `yourscheme:///path`
84
90
  * - Web (dev): `https://localhost:19006/path`
@@ -87,28 +93,38 @@ function ensureLeadingSlash(input: string, shouldAppend: boolean): string {
87
93
  * - Expo Client (prod): `exp://exp.host/@yourname/your-app/--/path`
88
94
  *
89
95
  * @param path addition path components to append to the base URL.
90
- * @param queryParams An object of parameters that will be converted into a query string.
96
+ * @param queryParams An object with a set of query parameters. These will be merged with any
97
+ * Expo-specific parameters that are needed (e.g. release channel) and then appended to the URL
98
+ * as a query string.
99
+ * @param scheme Optional URI protocol to use in the URL `<scheme>:///`, when `undefined` the scheme
100
+ * will be chosen from the Expo config (`app.config.js` or `app.json`).
101
+ * @return A URL string which points to your app with the given deep link information.
102
+ * @deprecated An alias for [`createURL()`](#linkingcreateurlpath-namedparameters). This method is
103
+ * deprecated and will be removed in a future SDK version.
91
104
  */
92
105
  export function makeUrl(path: string = '', queryParams?: QueryParams, scheme?: string): string {
93
106
  return createURL(path, { queryParams, scheme, isTripleSlashed: true });
94
107
  }
95
108
 
109
+ // @needsAudit
96
110
  /**
97
- * Create a URL that works for the environment the app is currently running in.
98
- * The scheme in bare and standalone must be defined in the Expo config (app.config.js or app.json) under `expo.scheme`.
111
+ * Helper method for constructing a deep link into your app, given an optional path and set of query
112
+ * parameters. Creates a URI scheme with two slashes by default.
99
113
  *
100
- * **Examples**
114
+ * The scheme in bare and standalone must be defined in the Expo config (`app.config.js` or `app.json`)
115
+ * under `expo.scheme`.
101
116
  *
102
- * - Bare: `<scheme>://path` -- uses provided scheme or scheme from Expo config `scheme`.
117
+ * # Examples
118
+ * - Bare: `<scheme>://path` - uses provided scheme or scheme from Expo config `scheme`.
103
119
  * - Standalone, Custom: `yourscheme://path`
104
120
  * - Web (dev): `https://localhost:19006/path`
105
121
  * - Web (prod): `https://myapp.com/path`
106
122
  * - Expo Client (dev): `exp://128.0.0.1:19000/--/path`
107
123
  * - Expo Client (prod): `exp://exp.host/@yourname/your-app/--/path`
108
124
  *
109
- * @param path addition path components to append to the base URL.
110
- * @param scheme URI protocol `<scheme>://` that must be built into your native app.
111
- * @param queryParams An object of parameters that will be converted into a query string.
125
+ * @param path Addition path components to append to the base URL.
126
+ * @param namedParameters Additional options object.
127
+ * @return A URL string which points to your app with the given deep link information.
112
128
  */
113
129
  export function createURL(
114
130
  path: string,
@@ -179,10 +195,11 @@ export function createURL(
179
195
  );
180
196
  }
181
197
 
198
+ // @needsAudit
182
199
  /**
183
- * Returns the components and query parameters for a given URL.
184
- *
185
- * @param url Input URL to parse
200
+ * Helper method for parsing out deep link information from a URL.
201
+ * @param url A URL that points to the currently running experience (e.g. an output of `Linking.createURL()`).
202
+ * @return A `ParsedURL` object.
186
203
  */
187
204
  export function parse(url: string): ParsedURL {
188
205
  validateURL(url);
@@ -231,28 +248,37 @@ export function parse(url: string): ParsedURL {
231
248
  };
232
249
  }
233
250
 
251
+ // @needsAudit
234
252
  /**
235
- * Add a handler to Linking changes by listening to the `url` event type
236
- * and providing the handler
237
- *
238
- * See https://reactnative.dev/docs/linking.html#addeventlistener
253
+ * Add a handler to `Linking` changes by listening to the `url` event type and providing the handler.
254
+ * It is recommended to use the [`useURL()`](#useurl) hook instead.
255
+ * @param type The only valid type is `'url'`.
256
+ * @param handler An [`URLListener`](#urllistener) function that takes an `event` object of the type
257
+ * [`EventType`](#eventype).
258
+ * @see [React Native Docs Linking page](https://reactnative.dev/docs/linking#addeventlistener).
239
259
  */
240
- export function addEventListener(type: string, handler: URLListener) {
260
+ export function addEventListener(type: string, handler: URLListener): void {
241
261
  NativeLinking.addEventListener(type, handler);
242
262
  }
243
263
 
244
264
  /**
245
265
  * Remove a handler by passing the `url` event type and the handler.
246
- *
247
- * See https://reactnative.dev/docs/linking.html#removeeventlistener
266
+ * @param type The only valid type is `'url'`.
267
+ * @param handler An [`URLListener`](#urllistener) function that takes an `event` object of the type
268
+ * [`EventType`](#eventype).
269
+ * @see [React Native Docs Linking page](https://reactnative.dev/docs/linking#removeeventlistener).
248
270
  */
249
- export function removeEventListener(type: string, handler: URLListener) {
271
+ export function removeEventListener(type: string, handler: URLListener): void {
250
272
  NativeLinking.removeEventListener(type, handler);
251
273
  }
252
274
 
275
+ // @needsAudit
253
276
  /**
254
- * **Native:** Parses the link that opened the app. If no link opened the app, all the fields will be \`null\`.
255
- * **Web:** Parses the current window URL.
277
+ * Helper method which wraps React Native's `Linking.getInitialURL()` in `Linking.parse()`.
278
+ * Parses the deep link information out of the URL used to open the experience initially.
279
+ * If no link opened the app, all the fields will be `null`.
280
+ * > On the web it parses the current window URL.
281
+ * @return A promise that resolves with `ParsedURL` object.
256
282
  */
257
283
  export async function parseInitialURLAsync(): Promise<ParsedURL> {
258
284
  const initialUrl = await NativeLinking.getInitialURL();
@@ -268,24 +294,23 @@ export async function parseInitialURLAsync(): Promise<ParsedURL> {
268
294
  return parse(initialUrl);
269
295
  }
270
296
 
297
+ // @needsAudit
271
298
  /**
272
- * Launch an Android intent with optional extras
273
- *
299
+ * Launch an Android intent with extras.
300
+ * > Use [IntentLauncher](../intent-launcher) instead, `sendIntent` is only included in
301
+ * > `Linking` for API compatibility with React Native's Linking API.
274
302
  * @platform android
275
303
  */
276
- export async function sendIntent(
277
- action: string,
278
- extras?: { key: string; value: string | number | boolean }[]
279
- ): Promise<void> {
304
+ export async function sendIntent(action: string, extras?: SendIntentExtras[]): Promise<void> {
280
305
  if (Platform.OS === 'android') {
281
306
  return await NativeLinking.sendIntent(action, extras);
282
307
  }
283
308
  throw new UnavailabilityError('Linking', 'sendIntent');
284
309
  }
285
310
 
311
+ // @needsAudit
286
312
  /**
287
- * Attempt to open the system settings for an the app.
288
- *
313
+ * Open the operating system settings app and displays the app’s custom settings, if it has any.
289
314
  * @platform ios
290
315
  */
291
316
  export async function openSettings(): Promise<void> {
@@ -298,33 +323,49 @@ export async function openSettings(): Promise<void> {
298
323
  await openURL('app-settings:');
299
324
  }
300
325
 
326
+ // @needsAudit
301
327
  /**
302
- * If the app launch was triggered by an app link,
303
- * it will give the link url, otherwise it will give `null`
328
+ * Get the URL that was used to launch the app if it was launched by a link.
329
+ * @return The URL string that launched your app, or `null`.
304
330
  */
305
331
  export async function getInitialURL(): Promise<string | null> {
306
332
  return (await NativeLinking.getInitialURL()) ?? null;
307
333
  }
308
334
 
335
+ // @needsAudit
309
336
  /**
310
- * Try to open the given `url` with any of the installed apps.
337
+ * Attempt to open the given URL with an installed app. See the [Linking guide](/guides/linking)
338
+ * for more information.
339
+ * @param url A URL for the operating system to open, eg: `tel:5555555`, `exp://`.
340
+ * @return A `Promise` that is fulfilled with `true` if the link is opened operating system
341
+ * automatically or the user confirms the prompt to open the link. The `Promise` rejects if there
342
+ * are no applications registered for the URL or the user cancels the dialog.
311
343
  */
312
344
  export async function openURL(url: string): Promise<true> {
313
345
  validateURL(url);
314
346
  return await NativeLinking.openURL(url);
315
347
  }
316
348
 
349
+ // @needsAudit
317
350
  /**
318
351
  * 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.
352
+ * On web this always returns `true` because there is no API for detecting what URLs can be opened.
353
+ * @param url The URL that you want to test can be opened.
354
+ * @return A `Promise` object that is fulfilled with `true` if the URL can be handled, otherwise it
355
+ * `false` if not.
356
+ *
357
+ * The `Promise` will reject on Android if it was impossible to check if the URL can be opened, and
358
+ * on iOS if you didn't [add the specific scheme in the `LSApplicationQueriesSchemes` key inside **Info.plist**](/guides/linking#opening-links-to-other-apps).
320
359
  */
321
360
  export async function canOpenURL(url: string): Promise<boolean> {
322
361
  validateURL(url);
323
362
  return await NativeLinking.canOpenURL(url);
324
363
  }
325
364
 
365
+ // @needsAudit
326
366
  /**
327
367
  * Returns the initial URL followed by any subsequent changes to the URL.
368
+ * @return Returns the initial URL or `null`.
328
369
  */
329
370
  export function useURL(): string | null {
330
371
  const [url, setLink] = useState<string | null>(null);
@@ -342,15 +383,4 @@ export function useURL(): string | null {
342
383
  return url;
343
384
  }
344
385
 
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
386
  export * from './Linking.types';
@@ -1,14 +1,23 @@
1
1
  import { ParsedQs } from 'qs';
2
2
 
3
+ // @docsMissing
3
4
  export type QueryParams = ParsedQs;
4
5
 
6
+ // @needsAudit @docsMissing
5
7
  export type ParsedURL = {
6
8
  scheme: string | null;
7
9
  hostname: string | null;
10
+ /**
11
+ * The path into the app specified by the URL.
12
+ */
8
13
  path: string | null;
14
+ /**
15
+ * The set of query parameters specified by the query string of the url used to open the app.
16
+ */
9
17
  queryParams: QueryParams | null;
10
18
  };
11
19
 
20
+ // @needsAudit
12
21
  export type CreateURLOptions = {
13
22
  /**
14
23
  * URI protocol `<scheme>://` that must be built into your native app.
@@ -24,8 +33,17 @@ export type CreateURLOptions = {
24
33
  isTripleSlashed?: boolean;
25
34
  };
26
35
 
27
- export type EventType = { url: string; nativeEvent?: MessageEvent };
36
+ // @docsMissing
37
+ export type EventType = {
38
+ url: string;
39
+ nativeEvent?: MessageEvent;
40
+ };
28
41
 
42
+ // @docsMissing
29
43
  export type URLListener = (event: EventType) => void;
30
44
 
45
+ // @docsMissing
31
46
  export type NativeURLListener = (nativeEvent: MessageEvent) => void;
47
+
48
+ // @docsMissing
49
+ export type SendIntentExtras = { key: string; value: string | number | boolean };