expo-linking 6.1.0 → 6.2.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 +10 -0
- package/build/Linking.types.d.ts +1 -2
- package/build/Linking.types.d.ts.map +1 -1
- package/build/Linking.types.js.map +1 -1
- package/build/createURL.d.ts +10 -6
- package/build/createURL.d.ts.map +1 -1
- package/build/createURL.js +31 -20
- package/build/createURL.js.map +1 -1
- package/build/createURL.web.d.ts.map +1 -1
- package/build/createURL.web.js +3 -2
- package/build/createURL.web.js.map +1 -1
- package/package.json +4 -7
- package/src/Linking.types.ts +1 -3
- package/src/createURL.ts +36 -22
- package/src/createURL.web.ts +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,16 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 6.2.0 — 2023-11-14
|
|
14
|
+
|
|
15
|
+
### 💡 Others
|
|
16
|
+
|
|
17
|
+
- Migrate to new standard `URL` support on native. ([#24941](https://github.com/expo/expo/pull/24941) by [@EvanBacon](https://github.com/EvanBacon))
|
|
18
|
+
|
|
19
|
+
## 6.1.1 — 2023-10-17
|
|
20
|
+
|
|
21
|
+
_This version does not introduce any user-facing changes._
|
|
22
|
+
|
|
13
23
|
## 6.1.0 — 2023-09-15
|
|
14
24
|
|
|
15
25
|
### 🛠 Breaking changes
|
package/build/Linking.types.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Linking.types.d.ts","sourceRoot":"","sources":["../src/Linking.types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Linking.types.d.ts","sourceRoot":"","sources":["../src/Linking.types.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;AAGxE,MAAM,MAAM,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,MAAM,MAAM,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,MAAM,MAAM,SAAS,GAAG;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,YAAY,CAAC;CAC5B,CAAC;AAGF,MAAM,MAAM,WAAW,GAAG,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;AAGrD,MAAM,MAAM,iBAAiB,GAAG,CAAC,WAAW,EAAE,YAAY,KAAK,IAAI,CAAC;AAGpE,MAAM,MAAM,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":["
|
|
1
|
+
{"version":3,"file":"Linking.types.js","sourceRoot":"","sources":["../src/Linking.types.ts"],"names":[],"mappings":"","sourcesContent":["// @docsMissing\nexport type QueryParams = Record<string, undefined | string | string[]>;\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/createURL.d.ts
CHANGED
|
@@ -3,16 +3,20 @@ import { CreateURLOptions, ParsedURL } from './Linking.types';
|
|
|
3
3
|
* Helper method for constructing a deep link into your app, given an optional path and set of query
|
|
4
4
|
* parameters. Creates a URI scheme with two slashes by default.
|
|
5
5
|
*
|
|
6
|
-
* The scheme
|
|
7
|
-
* under `expo.scheme
|
|
6
|
+
* The scheme must be defined in the Expo config (`app.config.js` or `app.json`) under `expo.scheme`
|
|
7
|
+
* or `expo.{android,ios}.scheme`. Platform-specific schemes defined under `expo.{android,ios}.scheme`
|
|
8
|
+
* take precedence over universal schemes defined under `expo.scheme`.
|
|
8
9
|
*
|
|
9
10
|
* # Examples
|
|
10
|
-
* -
|
|
11
|
-
* - Standalone, Custom: `yourscheme://path`
|
|
11
|
+
* - Development and production builds: `<scheme>://path` - uses the optional `scheme` property if provided, and otherwise uses the first scheme defined by your Expo config
|
|
12
12
|
* - Web (dev): `https://localhost:19006/path`
|
|
13
13
|
* - Web (prod): `https://myapp.com/path`
|
|
14
|
-
* - Expo
|
|
15
|
-
*
|
|
14
|
+
* - Expo Go (dev): `exp://128.0.0.1:8081/--/path`
|
|
15
|
+
*
|
|
16
|
+
* The behavior of this method in Expo Go for published updates is undefined and should not be relied upon.
|
|
17
|
+
* The created URL in this case is neither stable nor predictable during the lifetime of the app.
|
|
18
|
+
* If a stable URL is needed, for example in authorization callbacks, a build (or development build)
|
|
19
|
+
* of your application should be used and the scheme provided.
|
|
16
20
|
*
|
|
17
21
|
* @param path Addition path components to append to the base URL.
|
|
18
22
|
* @param namedParameters Additional options object.
|
package/build/createURL.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createURL.d.ts","sourceRoot":"","sources":["../src/createURL.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"createURL.d.ts","sourceRoot":"","sources":["../src/createURL.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAoD9D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,EAAE,MAAM,EAAE,WAAgB,EAAE,eAAuB,EAAE,GAAE,gBAAqB,GAC3E,MAAM,CAsDR;AAGD;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAoD5C"}
|
package/build/createURL.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import Constants from 'expo-constants';
|
|
2
|
-
import qs from 'qs';
|
|
3
|
-
import URL from 'url-parse';
|
|
4
2
|
import { hasCustomScheme, resolveScheme } from './Schemes';
|
|
5
3
|
import { validateURL } from './validateURL';
|
|
6
4
|
function getHostUri() {
|
|
@@ -49,16 +47,20 @@ function ensureLeadingSlash(input, shouldAppend) {
|
|
|
49
47
|
* Helper method for constructing a deep link into your app, given an optional path and set of query
|
|
50
48
|
* parameters. Creates a URI scheme with two slashes by default.
|
|
51
49
|
*
|
|
52
|
-
* The scheme
|
|
53
|
-
* under `expo.scheme
|
|
50
|
+
* The scheme must be defined in the Expo config (`app.config.js` or `app.json`) under `expo.scheme`
|
|
51
|
+
* or `expo.{android,ios}.scheme`. Platform-specific schemes defined under `expo.{android,ios}.scheme`
|
|
52
|
+
* take precedence over universal schemes defined under `expo.scheme`.
|
|
54
53
|
*
|
|
55
54
|
* # Examples
|
|
56
|
-
* -
|
|
57
|
-
* - Standalone, Custom: `yourscheme://path`
|
|
55
|
+
* - Development and production builds: `<scheme>://path` - uses the optional `scheme` property if provided, and otherwise uses the first scheme defined by your Expo config
|
|
58
56
|
* - Web (dev): `https://localhost:19006/path`
|
|
59
57
|
* - Web (prod): `https://myapp.com/path`
|
|
60
|
-
* - Expo
|
|
61
|
-
*
|
|
58
|
+
* - Expo Go (dev): `exp://128.0.0.1:8081/--/path`
|
|
59
|
+
*
|
|
60
|
+
* The behavior of this method in Expo Go for published updates is undefined and should not be relied upon.
|
|
61
|
+
* The created URL in this case is neither stable nor predictable during the lifetime of the app.
|
|
62
|
+
* If a stable URL is needed, for example in authorization callbacks, a build (or development build)
|
|
63
|
+
* of your application should be used and the scheme provided.
|
|
62
64
|
*
|
|
63
65
|
* @param path Addition path components to append to the base URL.
|
|
64
66
|
* @param namedParameters Additional options object.
|
|
@@ -90,10 +92,9 @@ export function createURL(path, { scheme, queryParams = {}, isTripleSlashed = fa
|
|
|
90
92
|
queryString = queryStringMatchResult[2];
|
|
91
93
|
let paramsFromHostUri = {};
|
|
92
94
|
try {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
95
|
+
paramsFromHostUri = Object.fromEntries(
|
|
96
|
+
// @ts-ignore: [Symbol.iterator] is indeed, available on every platform.
|
|
97
|
+
new URLSearchParams(queryString));
|
|
97
98
|
}
|
|
98
99
|
catch { }
|
|
99
100
|
queryParams = {
|
|
@@ -101,7 +102,9 @@ export function createURL(path, { scheme, queryParams = {}, isTripleSlashed = fa
|
|
|
101
102
|
...paramsFromHostUri,
|
|
102
103
|
};
|
|
103
104
|
}
|
|
104
|
-
queryString =
|
|
105
|
+
queryString = new URLSearchParams(
|
|
106
|
+
// For legacy purposes, we'll strip out the nullish values before creating the URL.
|
|
107
|
+
Object.fromEntries(Object.entries(queryParams).filter(([, value]) => value != null))).toString();
|
|
105
108
|
if (queryString) {
|
|
106
109
|
queryString = `?${queryString}`;
|
|
107
110
|
}
|
|
@@ -116,16 +119,24 @@ export function createURL(path, { scheme, queryParams = {}, isTripleSlashed = fa
|
|
|
116
119
|
*/
|
|
117
120
|
export function parse(url) {
|
|
118
121
|
validateURL(url);
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
+
const queryParams = {};
|
|
123
|
+
let path = null;
|
|
124
|
+
let hostname = null;
|
|
125
|
+
let scheme = null;
|
|
126
|
+
try {
|
|
127
|
+
const parsed = new URL(url);
|
|
128
|
+
parsed.searchParams.forEach((value, key) => {
|
|
129
|
+
queryParams[key] = decodeURIComponent(value);
|
|
130
|
+
});
|
|
131
|
+
path = parsed.pathname || null;
|
|
132
|
+
hostname = parsed.hostname || null;
|
|
133
|
+
scheme = parsed.protocol || null;
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
path = url;
|
|
122
137
|
}
|
|
123
|
-
const queryParams = parsed.query;
|
|
124
138
|
const hostUri = getHostUri() || '';
|
|
125
139
|
const hostUriStripped = removePort(removeTrailingSlashAndQueryString(hostUri));
|
|
126
|
-
let path = parsed.pathname || null;
|
|
127
|
-
let hostname = parsed.hostname || null;
|
|
128
|
-
let scheme = parsed.protocol || null;
|
|
129
140
|
if (scheme) {
|
|
130
141
|
// Remove colon at end
|
|
131
142
|
scheme = scheme.substring(0, scheme.length - 1);
|
package/build/createURL.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createURL.js","sourceRoot":"","sources":["../src/createURL.ts"],"names":[],"mappings":"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","sourcesContent":["import Constants from 'expo-constants';\nimport qs from 'qs';\nimport URL from 'url-parse';\n\nimport { CreateURLOptions, ParsedURL } from './Linking.types';\nimport { hasCustomScheme, resolveScheme } from './Schemes';\nimport { validateURL } from './validateURL';\n\nfunction getHostUri(): string | null {\n if (Constants.expoConfig?.hostUri) {\n return Constants.expoConfig.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|expo\\.dev)(:.*)?(\\/.*)?$/.test(hostUri) ||\n Constants.expoGoConfig?.developer)\n );\n}\n\nfunction removeScheme(url: string): string {\n return url.replace(/^[a-zA-Z0-9+.-]+:\\/\\//, '');\n}\n\nfunction removePort(url: string): string {\n return url.replace(/(?=([a-zA-Z0-9+.-]+:\\/\\/)?[^/]):\\d+/, '');\n}\n\nfunction removeLeadingSlash(url: string): string {\n return url.replace(/^\\//, '');\n}\n\nfunction removeTrailingSlashAndQueryString(url: string): string {\n return url.replace(/\\/?\\?.*$/, '');\n}\n\nfunction ensureLeadingSlash(input: string, shouldAppend: boolean): string {\n const hasSlash = input.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 * 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:8081/--/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 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"]}
|
|
1
|
+
{"version":3,"file":"createURL.js","sourceRoot":"","sources":["../src/createURL.ts"],"names":[],"mappings":"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","sourcesContent":["import Constants from 'expo-constants';\n\nimport { CreateURLOptions, ParsedURL } from './Linking.types';\nimport { hasCustomScheme, resolveScheme } from './Schemes';\nimport { validateURL } from './validateURL';\n\nfunction getHostUri(): string | null {\n if (Constants.expoConfig?.hostUri) {\n return Constants.expoConfig.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|expo\\.dev)(:.*)?(\\/.*)?$/.test(hostUri) ||\n Constants.expoGoConfig?.developer)\n );\n}\n\nfunction removeScheme(url: string): string {\n return url.replace(/^[a-zA-Z0-9+.-]+:\\/\\//, '');\n}\n\nfunction removePort(url: string): string {\n return url.replace(/(?=([a-zA-Z0-9+.-]+:\\/\\/)?[^/]):\\d+/, '');\n}\n\nfunction removeLeadingSlash(url: string): string {\n return url.replace(/^\\//, '');\n}\n\nfunction removeTrailingSlashAndQueryString(url: string): string {\n return url.replace(/\\/?\\?.*$/, '');\n}\n\nfunction ensureLeadingSlash(input: string, shouldAppend: boolean): string {\n const hasSlash = input.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 * 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 must be defined in the Expo config (`app.config.js` or `app.json`) under `expo.scheme`\n * or `expo.{android,ios}.scheme`. Platform-specific schemes defined under `expo.{android,ios}.scheme`\n * take precedence over universal schemes defined under `expo.scheme`.\n *\n * # Examples\n * - Development and production builds: `<scheme>://path` - uses the optional `scheme` property if provided, and otherwise uses the first scheme defined by your Expo config\n * - Web (dev): `https://localhost:19006/path`\n * - Web (prod): `https://myapp.com/path`\n * - Expo Go (dev): `exp://128.0.0.1:8081/--/path`\n *\n * The behavior of this method in Expo Go for published updates is undefined and should not be relied upon.\n * The created URL in this case is neither stable nor predictable during the lifetime of the app.\n * If a stable URL is needed, for example in authorization callbacks, a build (or development build)\n * of your application should be used and the scheme provided.\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 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 paramsFromHostUri = Object.fromEntries(\n // @ts-ignore: [Symbol.iterator] is indeed, available on every platform.\n new URLSearchParams(queryString)\n );\n } catch {}\n queryParams = {\n ...queryParams,\n ...paramsFromHostUri,\n };\n }\n queryString = new URLSearchParams(\n // For legacy purposes, we'll strip out the nullish values before creating the URL.\n Object.fromEntries(\n Object.entries(queryParams).filter(([, value]) => value != null) as [string, string][]\n )\n ).toString();\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 queryParams: Record<string, string> = {};\n let path: string | null = null;\n let hostname: string | null = null;\n let scheme: string | null = null;\n\n try {\n const parsed = new URL(url);\n\n parsed.searchParams.forEach((value, key) => {\n queryParams[key] = decodeURIComponent(value);\n });\n path = parsed.pathname || null;\n hostname = parsed.hostname || null;\n scheme = parsed.protocol || null;\n } catch {\n path = url;\n }\n\n const hostUri = getHostUri() || '';\n const hostUriStripped = removePort(removeTrailingSlashAndQueryString(hostUri));\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"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createURL.web.d.ts","sourceRoot":"","sources":["../src/createURL.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE9D,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,WAAgB,EAAE,GAAE,gBAAqB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"createURL.web.d.ts","sourceRoot":"","sources":["../src/createURL.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE9D,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,WAAgB,EAAE,GAAE,gBAAqB,GAAG,MAAM,CAe3F;AAED,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAoC5C"}
|
package/build/createURL.web.js
CHANGED
|
@@ -7,8 +7,9 @@ export function createURL(path, { queryParams = {} } = {}) {
|
|
|
7
7
|
url.searchParams.set(key, encodeURIComponent(value));
|
|
8
8
|
}
|
|
9
9
|
else if (value != null) {
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
url.searchParams.set(key,
|
|
11
|
+
// @ts-expect-error: browser supports using array
|
|
12
|
+
value);
|
|
12
13
|
}
|
|
13
14
|
});
|
|
14
15
|
return url.toString().replace(/\/$/, '');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createURL.web.js","sourceRoot":"","sources":["../src/createURL.web.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,EAAE,WAAW,GAAG,EAAE,KAAuB,EAAE;IACjF,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,EAAE,CAAC;IAC7C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QACnD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;YAC7B,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC;SACtD;aAAM,IAAI,KAAK,IAAI,IAAI,EAAE;YACxB,
|
|
1
|
+
{"version":3,"file":"createURL.web.js","sourceRoot":"","sources":["../src/createURL.web.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,EAAE,WAAW,GAAG,EAAE,KAAuB,EAAE;IACjF,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,EAAE,CAAC;IAC7C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QACnD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;YAC7B,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC;SACtD;aAAM,IAAI,KAAK,IAAI,IAAI,EAAE;YACxB,GAAG,CAAC,YAAY,CAAC,GAAG,CAClB,GAAG;YACH,iDAAiD;YACjD,KAAK,CACN,CAAC;SACH;IACH,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,GAAW;IAC/B,IAAI,MAAW,CAAC;IAChB,IAAI;QACF,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;KACvB;IAAC,MAAM;QACN,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;YACjC,OAAO;gBACL,QAAQ,EAAE,IAAI;gBACd,IAAI,EAAE,GAAG;gBACT,WAAW,EAAE,EAAE;gBACf,MAAM,EAAE,IAAI;aACb,CAAC;SACH;QACD,OAAO;YACL,QAAQ,EAAE,WAAW;YACrB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,EAAE;YACf,MAAM,EAAE,MAAM;SACf,CAAC;KACH;IACD,MAAM,WAAW,GAA2B,EAAE,CAAC;IAC/C,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACzC,WAAW,CAAC,GAAG,CAAC,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IACH,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,IAAI;QACjC,oFAAoF;QACpF,IAAI,EACF,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ;YAClC,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,MAAM,CAAC,QAAQ,KAAK,EAAE;gBACxB,CAAC,CAAC,IAAI;gBACN,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;QACxC,WAAW;QACX,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;KAC1C,CAAC;AACJ,CAAC","sourcesContent":["import { CreateURLOptions, ParsedURL } from './Linking.types';\n\nexport function createURL(path: string, { queryParams = {} }: CreateURLOptions = {}): string {\n if (typeof window === 'undefined') return '';\n const url = new URL(path, window.location.origin);\n Object.entries(queryParams).forEach(([key, value]) => {\n if (typeof value === 'string') {\n url.searchParams.set(key, encodeURIComponent(value));\n } else if (value != null) {\n url.searchParams.set(\n key,\n // @ts-expect-error: browser supports using array\n value\n );\n }\n });\n return url.toString().replace(/\\/$/, '');\n}\n\nexport function parse(url: string): ParsedURL {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n if (typeof window === 'undefined') {\n return {\n hostname: null,\n path: url,\n queryParams: {},\n scheme: null,\n };\n }\n return {\n hostname: 'localhost',\n path: url,\n queryParams: {},\n scheme: 'http',\n };\n }\n const queryParams: Record<string, string> = {};\n parsed.searchParams.forEach((value, key) => {\n queryParams[key] = decodeURIComponent(value);\n });\n return {\n hostname: parsed.hostname || null,\n // TODO: We should probably update native to follow the default URL behavior closer.\n path:\n !parsed.hostname && !parsed.pathname\n ? null\n : parsed.pathname === ''\n ? null\n : parsed.pathname.replace(/^\\//, ''),\n queryParams,\n scheme: parsed.protocol.replace(/:$/, ''),\n };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-linking",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.2.0",
|
|
4
4
|
"description": "Create and open deep links universally",
|
|
5
5
|
"main": "build/Linking.js",
|
|
6
6
|
"types": "build/Linking.d.ts",
|
|
@@ -30,11 +30,8 @@
|
|
|
30
30
|
"license": "MIT",
|
|
31
31
|
"homepage": "https://docs.expo.dev/versions/latest/sdk/linking",
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"invariant": "^2.2.4",
|
|
36
|
-
"qs": "^6.11.0",
|
|
37
|
-
"url-parse": "^1.5.9"
|
|
33
|
+
"expo-constants": "~15.3.0",
|
|
34
|
+
"invariant": "^2.2.4"
|
|
38
35
|
},
|
|
39
36
|
"devDependencies": {
|
|
40
37
|
"expo-module-scripts": "^3.0.0"
|
|
@@ -42,5 +39,5 @@
|
|
|
42
39
|
"jest": {
|
|
43
40
|
"preset": "expo-module-scripts"
|
|
44
41
|
},
|
|
45
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "3142a086578deffd8704a8f1b6f0f661527d836c"
|
|
46
43
|
}
|
package/src/Linking.types.ts
CHANGED
package/src/createURL.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import Constants from 'expo-constants';
|
|
2
|
-
import qs from 'qs';
|
|
3
|
-
import URL from 'url-parse';
|
|
4
2
|
|
|
5
3
|
import { CreateURLOptions, ParsedURL } from './Linking.types';
|
|
6
4
|
import { hasCustomScheme, resolveScheme } from './Schemes';
|
|
@@ -58,16 +56,20 @@ function ensureLeadingSlash(input: string, shouldAppend: boolean): string {
|
|
|
58
56
|
* Helper method for constructing a deep link into your app, given an optional path and set of query
|
|
59
57
|
* parameters. Creates a URI scheme with two slashes by default.
|
|
60
58
|
*
|
|
61
|
-
* The scheme
|
|
62
|
-
* under `expo.scheme
|
|
59
|
+
* The scheme must be defined in the Expo config (`app.config.js` or `app.json`) under `expo.scheme`
|
|
60
|
+
* or `expo.{android,ios}.scheme`. Platform-specific schemes defined under `expo.{android,ios}.scheme`
|
|
61
|
+
* take precedence over universal schemes defined under `expo.scheme`.
|
|
63
62
|
*
|
|
64
63
|
* # Examples
|
|
65
|
-
* -
|
|
66
|
-
* - Standalone, Custom: `yourscheme://path`
|
|
64
|
+
* - Development and production builds: `<scheme>://path` - uses the optional `scheme` property if provided, and otherwise uses the first scheme defined by your Expo config
|
|
67
65
|
* - Web (dev): `https://localhost:19006/path`
|
|
68
66
|
* - Web (prod): `https://myapp.com/path`
|
|
69
|
-
* - Expo
|
|
70
|
-
*
|
|
67
|
+
* - Expo Go (dev): `exp://128.0.0.1:8081/--/path`
|
|
68
|
+
*
|
|
69
|
+
* The behavior of this method in Expo Go for published updates is undefined and should not be relied upon.
|
|
70
|
+
* The created URL in this case is neither stable nor predictable during the lifetime of the app.
|
|
71
|
+
* If a stable URL is needed, for example in authorization callbacks, a build (or development build)
|
|
72
|
+
* of your application should be used and the scheme provided.
|
|
71
73
|
*
|
|
72
74
|
* @param path Addition path components to append to the base URL.
|
|
73
75
|
* @param namedParameters Additional options object.
|
|
@@ -105,17 +107,22 @@ export function createURL(
|
|
|
105
107
|
queryString = queryStringMatchResult[2];
|
|
106
108
|
let paramsFromHostUri = {};
|
|
107
109
|
try {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
110
|
+
paramsFromHostUri = Object.fromEntries(
|
|
111
|
+
// @ts-ignore: [Symbol.iterator] is indeed, available on every platform.
|
|
112
|
+
new URLSearchParams(queryString)
|
|
113
|
+
);
|
|
112
114
|
} catch {}
|
|
113
115
|
queryParams = {
|
|
114
116
|
...queryParams,
|
|
115
117
|
...paramsFromHostUri,
|
|
116
118
|
};
|
|
117
119
|
}
|
|
118
|
-
queryString =
|
|
120
|
+
queryString = new URLSearchParams(
|
|
121
|
+
// For legacy purposes, we'll strip out the nullish values before creating the URL.
|
|
122
|
+
Object.fromEntries(
|
|
123
|
+
Object.entries(queryParams).filter(([, value]) => value != null) as [string, string][]
|
|
124
|
+
)
|
|
125
|
+
).toString();
|
|
119
126
|
if (queryString) {
|
|
120
127
|
queryString = `?${queryString}`;
|
|
121
128
|
}
|
|
@@ -136,20 +143,27 @@ export function createURL(
|
|
|
136
143
|
export function parse(url: string): ParsedURL {
|
|
137
144
|
validateURL(url);
|
|
138
145
|
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
146
|
+
const queryParams: Record<string, string> = {};
|
|
147
|
+
let path: string | null = null;
|
|
148
|
+
let hostname: string | null = null;
|
|
149
|
+
let scheme: string | null = null;
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
const parsed = new URL(url);
|
|
153
|
+
|
|
154
|
+
parsed.searchParams.forEach((value, key) => {
|
|
155
|
+
queryParams[key] = decodeURIComponent(value);
|
|
156
|
+
});
|
|
157
|
+
path = parsed.pathname || null;
|
|
158
|
+
hostname = parsed.hostname || null;
|
|
159
|
+
scheme = parsed.protocol || null;
|
|
160
|
+
} catch {
|
|
161
|
+
path = url;
|
|
143
162
|
}
|
|
144
|
-
const queryParams = parsed.query;
|
|
145
163
|
|
|
146
164
|
const hostUri = getHostUri() || '';
|
|
147
165
|
const hostUriStripped = removePort(removeTrailingSlashAndQueryString(hostUri));
|
|
148
166
|
|
|
149
|
-
let path = parsed.pathname || null;
|
|
150
|
-
let hostname = parsed.hostname || null;
|
|
151
|
-
let scheme = parsed.protocol || null;
|
|
152
|
-
|
|
153
167
|
if (scheme) {
|
|
154
168
|
// Remove colon at end
|
|
155
169
|
scheme = scheme.substring(0, scheme.length - 1);
|
package/src/createURL.web.ts
CHANGED
|
@@ -7,8 +7,11 @@ export function createURL(path: string, { queryParams = {} }: CreateURLOptions =
|
|
|
7
7
|
if (typeof value === 'string') {
|
|
8
8
|
url.searchParams.set(key, encodeURIComponent(value));
|
|
9
9
|
} else if (value != null) {
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
url.searchParams.set(
|
|
11
|
+
key,
|
|
12
|
+
// @ts-expect-error: browser supports using array
|
|
13
|
+
value
|
|
14
|
+
);
|
|
12
15
|
}
|
|
13
16
|
});
|
|
14
17
|
return url.toString().replace(/\/$/, '');
|