@aturi.to/waypoints 0.1.2 → 0.1.3
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/README.md +147 -3
- package/dist/index.cjs +383 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +265 -4
- package/dist/index.d.ts +265 -4
- package/dist/index.js +370 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -7,6 +7,38 @@ type WaypointType = 'post' | 'profile' | 'list' | 'record' | 'unknown';
|
|
|
7
7
|
* and are independent of this.
|
|
8
8
|
*/
|
|
9
9
|
type RedirectCompatFamily = 'bluesky-social' | 'standard-site' | 'tangled' | 'margin' | 'grain' | 'pinksky' | 'semble' | 'streamplace' | 'popfeed' | 'sifa' | 'blento' | 'atproto-explorer';
|
|
10
|
+
/**
|
|
11
|
+
* A client's support for Bluesky-style *compose intent links*: a URL that opens
|
|
12
|
+
* the app's composer, optionally pre-filled with text.
|
|
13
|
+
* See https://docs.bsky.app/docs/advanced-guides/intent-links.
|
|
14
|
+
*
|
|
15
|
+
* bsky.app established `/intent/compose?text=…`, and the social-app forks in the
|
|
16
|
+
* catalog inherit the same route, so a link built for one works on any of them.
|
|
17
|
+
* Only add an entry once the client's own route has been confirmed — a link to
|
|
18
|
+
* a client that doesn't handle it lands the user on a 404 or an empty home feed.
|
|
19
|
+
*/
|
|
20
|
+
type ComposeIntentData = {
|
|
21
|
+
/**
|
|
22
|
+
* The compose route, absolute and free of any query string
|
|
23
|
+
* (e.g. `https://bsky.app/intent/compose`).
|
|
24
|
+
*/
|
|
25
|
+
url: string;
|
|
26
|
+
/**
|
|
27
|
+
* Query parameter carrying the pre-filled post text. Omitted when the client
|
|
28
|
+
* routes the intent but ignores the text: the link still opens a composer,
|
|
29
|
+
* just an empty one. Check this before offering a "share this to…" affordance,
|
|
30
|
+
* since there the text is the whole point.
|
|
31
|
+
*
|
|
32
|
+
* Bluesky's post limit is 300 grapheme clusters; longer text is the caller's
|
|
33
|
+
* problem to truncate.
|
|
34
|
+
*/
|
|
35
|
+
textParam?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Deep link into the client's native app for the same intent, when it
|
|
38
|
+
* publishes a scheme (e.g. `bluesky://intent/compose`).
|
|
39
|
+
*/
|
|
40
|
+
appUrl?: string;
|
|
41
|
+
};
|
|
10
42
|
type WaypointData = {
|
|
11
43
|
id: string;
|
|
12
44
|
name: string;
|
|
@@ -14,6 +46,12 @@ type WaypointData = {
|
|
|
14
46
|
getUrl: (handle: string, collection?: string, rkey?: string, did?: string) => string | null;
|
|
15
47
|
supportedTypes: WaypointType[];
|
|
16
48
|
category: string;
|
|
49
|
+
/**
|
|
50
|
+
* Compose intent support, when the client has a confirmed intent route.
|
|
51
|
+
* Absent means "no known support" rather than a proven absence — read it with
|
|
52
|
+
* `supportsComposeIntent` / `getComposeIntentUrl`.
|
|
53
|
+
*/
|
|
54
|
+
composeIntent?: ComposeIntentData;
|
|
17
55
|
/**
|
|
18
56
|
* Data families this waypoint participates in. Auto-redirect rules are only
|
|
19
57
|
* emitted between waypoints that share at least one family. An empty array
|
|
@@ -89,6 +127,57 @@ type WaypointActivity = 'present' | 'absent' | 'unknown';
|
|
|
89
127
|
* disabled or still in flight).
|
|
90
128
|
*/
|
|
91
129
|
declare function waypointActivity(waypoint: Pick<WaypointData, 'expectedCollections'>, repoCollections: ReadonlySet<string> | null): WaypointActivity;
|
|
130
|
+
/** Placeholder a compose intent template leaves for the caller's post text. */
|
|
131
|
+
declare const COMPOSE_INTENT_TEXT_PLACEHOLDER = "{text}";
|
|
132
|
+
/** Whether the client can be handed a link that opens its composer. */
|
|
133
|
+
declare function supportsComposeIntent(waypoint: Pick<WaypointData, 'composeIntent'>): boolean;
|
|
134
|
+
/**
|
|
135
|
+
* Build a link that opens the client's composer, pre-filled with `text` when
|
|
136
|
+
* the client reads it. Returns null when the client has no known intent route.
|
|
137
|
+
*
|
|
138
|
+
* getComposeIntentUrl(WAYPOINT_DESTINATIONS_DATA.deer, 'hello!')
|
|
139
|
+
* // 'https://deer.social/intent/compose?text=hello!'
|
|
140
|
+
*/
|
|
141
|
+
declare function getComposeIntentUrl(waypoint: Pick<WaypointData, 'composeIntent'>, text?: string): string | null;
|
|
142
|
+
/**
|
|
143
|
+
* The native-app flavour of `getComposeIntentUrl`. Null unless the client
|
|
144
|
+
* publishes a scheme of its own — most web clients don't, so fall back to the
|
|
145
|
+
* https link rather than treating null as "unsupported".
|
|
146
|
+
*/
|
|
147
|
+
declare function getComposeIntentAppUrl(waypoint: Pick<WaypointData, 'composeIntent'>, text?: string): string | null;
|
|
148
|
+
/**
|
|
149
|
+
* The client's intent URL with a literal `{text}` where the post text goes, for
|
|
150
|
+
* handing to consumers that build their own links (JSON APIs, docs, templates).
|
|
151
|
+
* Substitute the placeholder with URL-encoded text. Clients that ignore the
|
|
152
|
+
* text get a template with no placeholder at all.
|
|
153
|
+
*/
|
|
154
|
+
declare function getComposeIntentTemplate(waypoint: Pick<WaypointData, 'composeIntent'>): string | null;
|
|
155
|
+
/**
|
|
156
|
+
* Catalog-ordered list of every client with a compose intent route, optionally
|
|
157
|
+
* narrowed to those that also render a given record type.
|
|
158
|
+
*/
|
|
159
|
+
declare function getComposeIntentWaypoints(type?: WaypointType): WaypointData[];
|
|
160
|
+
/**
|
|
161
|
+
* JSON-safe view of a client's compose intent, for surfaces that can't ship a
|
|
162
|
+
* function (HTTP responses, the extension's message passing, docs tables).
|
|
163
|
+
*/
|
|
164
|
+
type ComposeIntentDescriptor = {
|
|
165
|
+
/** Ready to open. Pre-filled when `text` was supplied and the client reads it. */
|
|
166
|
+
url: string;
|
|
167
|
+
/** The same URL with a literal `{text}` where the post text goes. */
|
|
168
|
+
urlTemplate: string;
|
|
169
|
+
/** Query parameter carrying the text; null when the client ignores it. */
|
|
170
|
+
textParam: string | null;
|
|
171
|
+
/**
|
|
172
|
+
* False when the composer opens empty no matter what you pass — the link is
|
|
173
|
+
* still a valid "start a post over there" jump, just not a share.
|
|
174
|
+
*/
|
|
175
|
+
prefillsText: boolean;
|
|
176
|
+
/** Native-app deep link for the same intent, when the client publishes one. */
|
|
177
|
+
appUrl?: string;
|
|
178
|
+
};
|
|
179
|
+
/** Serialize a waypoint's compose intent. Null when it has none. */
|
|
180
|
+
declare function describeComposeIntent(waypoint: Pick<WaypointData, 'composeIntent'>, text?: string): ComposeIntentDescriptor | null;
|
|
92
181
|
|
|
93
182
|
type ParsedURI = {
|
|
94
183
|
type: 'post' | 'profile' | 'list' | 'record' | 'unknown';
|
|
@@ -135,7 +224,7 @@ declare function resolveHandle(handle: string): Promise<string | null>;
|
|
|
135
224
|
*/
|
|
136
225
|
declare function getDisplayName(handle: string, did?: string): string;
|
|
137
226
|
|
|
138
|
-
type SourceApp = 'aturi' | 'aturiExplore' | 'bluesky' | 'bluepy' | 'blacksky' | 'reddwarf' | 'impro' | 'witchsky' | 'deer' | 'mu' | 'anisota' | 'pinksky' | 'leaflet' | 'tangled' | 'margin' | 'pdsls' | 'atptools' | 'semble' | 'streamplace' | 'grain' | 'popfeed' | 'sifa' | 'blento' | 'standardReader' | 'taproot' | 'offprint' | 'pckt' | 'headDetected';
|
|
227
|
+
type SourceApp = 'aturi' | 'aturiExplore' | 'bluesky' | 'bluepy' | 'blacksky' | 'reddwarf' | 'impro' | 'lea' | 'witchsky' | 'deer' | 'northsky' | 'mu' | 'anisota' | 'pinksky' | 'leaflet' | 'tangled' | 'margin' | 'pdsls' | 'atptools' | 'semble' | 'streamplace' | 'grain' | 'popfeed' | 'sifa' | 'blento' | 'standardReader' | 'taproot' | 'offprint' | 'pckt' | 'headDetected';
|
|
139
228
|
type ReverseMatch = {
|
|
140
229
|
source: SourceApp;
|
|
141
230
|
parsed: ParsedURI;
|
|
@@ -170,6 +259,12 @@ type ResolvedWaypoint = {
|
|
|
170
259
|
name: string;
|
|
171
260
|
category: string;
|
|
172
261
|
url: string;
|
|
262
|
+
/**
|
|
263
|
+
* Whether this client can be handed a link that opens its composer, and how
|
|
264
|
+
* to build one. Null when it has no confirmed compose intent route. Supply
|
|
265
|
+
* `composeText` to get the links back pre-filled.
|
|
266
|
+
*/
|
|
267
|
+
composeIntent: ComposeIntentDescriptor | null;
|
|
173
268
|
};
|
|
174
269
|
type ResolvedRecommendation = {
|
|
175
270
|
ids: string[];
|
|
@@ -194,6 +289,8 @@ type BuildWaypointsOptions = {
|
|
|
194
289
|
did?: string;
|
|
195
290
|
/** Waypoint id to omit (e.g. the source app the user is already on). */
|
|
196
291
|
excludeSourceId?: string;
|
|
292
|
+
/** Text to pre-fill into each waypoint's compose intent link, if it has one. */
|
|
293
|
+
composeText?: string;
|
|
197
294
|
};
|
|
198
295
|
/**
|
|
199
296
|
* Turn a parsed AT URI into the list of waypoints that can render it plus the
|
|
@@ -209,7 +306,7 @@ declare function buildWaypointsForParsed(parsed: ParsedURI, options?: BuildWaypo
|
|
|
209
306
|
* Resolve an AT URI string (e.g. "at://did:plc:abc/app.bsky.feed.post/rkey")
|
|
210
307
|
* directly into its waypoints. Returns null if the string isn't a valid AT URI.
|
|
211
308
|
*/
|
|
212
|
-
declare function resolveAtUri(uri: string): ResolveResult | null;
|
|
309
|
+
declare function resolveAtUri(uri: string, options?: Pick<BuildWaypointsOptions, 'composeText'>): ResolveResult | null;
|
|
213
310
|
type ResolveUrlOptions = {
|
|
214
311
|
/**
|
|
215
312
|
* When the URL pattern isn't recognized, fetch the page and look for a
|
|
@@ -225,6 +322,8 @@ type ResolveUrlOptions = {
|
|
|
225
322
|
* your own implementation.
|
|
226
323
|
*/
|
|
227
324
|
resolveHandle?: (handle: string) => Promise<string | null>;
|
|
325
|
+
/** Text to pre-fill into each waypoint's compose intent link, if it has one. */
|
|
326
|
+
composeText?: string;
|
|
228
327
|
};
|
|
229
328
|
/**
|
|
230
329
|
* Resolve a pasted/shared page URL back into the AT URI it represents and the
|
|
@@ -240,6 +339,8 @@ type ResolveApiInput = {
|
|
|
240
339
|
atUri?: string;
|
|
241
340
|
/** Set false to skip the server-side <head> probe. */
|
|
242
341
|
headDetect?: boolean;
|
|
342
|
+
/** Text to pre-fill into the returned compose intent links. */
|
|
343
|
+
composeText?: string;
|
|
243
344
|
};
|
|
244
345
|
type ResolveApiParsed = {
|
|
245
346
|
type: WaypointType;
|
|
@@ -252,7 +353,12 @@ type ResolveApiParsed = {
|
|
|
252
353
|
type ResolveApiSuccess = {
|
|
253
354
|
ok: true;
|
|
254
355
|
inputKind: 'atUri' | 'url';
|
|
255
|
-
|
|
356
|
+
/**
|
|
357
|
+
* How the endpoint found the AT URI. `atTags` means the page declared it
|
|
358
|
+
* itself via `<meta name="at:canonical">` (or `at:alternate`); `headLink` is
|
|
359
|
+
* the older `<link href="at://…">` the same probe falls back to.
|
|
360
|
+
*/
|
|
361
|
+
detectedVia: 'atUri' | 'urlPattern' | 'atTags' | 'headLink' | null;
|
|
256
362
|
source: SourceApp;
|
|
257
363
|
isKnownHost: boolean;
|
|
258
364
|
parsed: ResolveApiParsed;
|
|
@@ -285,4 +391,159 @@ type ResolveViaApiOptions = {
|
|
|
285
391
|
*/
|
|
286
392
|
declare function resolveViaApi(input: ResolveApiInput, options?: ResolveViaApiOptions): Promise<ResolveApiResponse>;
|
|
287
393
|
|
|
288
|
-
|
|
394
|
+
/**
|
|
395
|
+
* Universal links: the aturi.to URL for a record or an identity.
|
|
396
|
+
*
|
|
397
|
+
* A universal link is the client-agnostic address of an atproto record. Drop
|
|
398
|
+
* one anywhere and the recipient lands on a preview of the record and picks
|
|
399
|
+
* the client they want to open it in, instead of being pushed into whichever
|
|
400
|
+
* app the sender happened to use.
|
|
401
|
+
*
|
|
402
|
+
* This module is the whole round trip:
|
|
403
|
+
* - `buildUniversalLink` returns that address for anything that names a
|
|
404
|
+
* record: an AT URI, a handle, a DID, a URL from any client in the catalog.
|
|
405
|
+
* - `parseUniversalLink` turns one back into a `ParsedURI`.
|
|
406
|
+
* - `describeUniversalLink` adds the strings a share sheet or a copy button
|
|
407
|
+
* needs (a label, a `navigator.share()` payload, markdown/HTML snippets).
|
|
408
|
+
* - `buildUniversalLinkTags` emits the `<head>` tags that let *other* apps
|
|
409
|
+
* be resolved back into records, the read side of the same trip.
|
|
410
|
+
*
|
|
411
|
+
* Everything here is pure and synchronous. Nothing fetches.
|
|
412
|
+
*/
|
|
413
|
+
/** Where universal links point unless an `origin` says otherwise. */
|
|
414
|
+
declare const UNIVERSAL_LINK_ORIGIN = "https://aturi.to";
|
|
415
|
+
/** The oEmbed link `type` attribute, per the spec's discovery section. */
|
|
416
|
+
declare const OEMBED_LINK_TYPE = "application/json+oembed";
|
|
417
|
+
/**
|
|
418
|
+
* Anything that names a record or an identity:
|
|
419
|
+
* - an AT URI (`at://did:plc:abc/app.bsky.feed.post/3k7`)
|
|
420
|
+
* - a bare handle or DID (`alice.bsky.social`, `@alice.bsky.social`, `did:plc:abc`)
|
|
421
|
+
* - a scheme-less AT URI (`alice.bsky.social/app.bsky.feed.post/3k7`)
|
|
422
|
+
* - a page URL from any client in the catalog, an aturi.to link included
|
|
423
|
+
* - a `ParsedURI` you already have from `parseURI` / `matchSupportedUrl`
|
|
424
|
+
*/
|
|
425
|
+
type UniversalLinkTarget = string | ParsedURI;
|
|
426
|
+
type UniversalLinkOptions = {
|
|
427
|
+
/**
|
|
428
|
+
* Origin to build against. Defaults to aturi.to; point it at your own
|
|
429
|
+
* deployment if you run a fork. Trailing slashes are trimmed.
|
|
430
|
+
*/
|
|
431
|
+
origin?: string;
|
|
432
|
+
/**
|
|
433
|
+
* DID for the target, for input that only carries a handle. Handle → DID
|
|
434
|
+
* resolution is a network call, so this package never does it for you:
|
|
435
|
+
* pass `resolveHandle`'s result if you want DID-stable links.
|
|
436
|
+
*/
|
|
437
|
+
did?: string;
|
|
438
|
+
/**
|
|
439
|
+
* Address every link by DID instead of handle. A handle can be reassigned
|
|
440
|
+
* to another identity; a DID is stable for the life of the account, so a
|
|
441
|
+
* DID link never rots. Ignored when no DID is known.
|
|
442
|
+
*/
|
|
443
|
+
preferDid?: boolean;
|
|
444
|
+
/** Query parameters to append, e.g. `{ ref: 'my-app' }`. Empty values are dropped. */
|
|
445
|
+
params?: Record<string, string | number | boolean | null | undefined>;
|
|
446
|
+
};
|
|
447
|
+
/** `navigator.share()`'s payload, which most native share sheets also accept. */
|
|
448
|
+
type UniversalLinkSharePayload = {
|
|
449
|
+
title: string;
|
|
450
|
+
text: string;
|
|
451
|
+
url: string;
|
|
452
|
+
};
|
|
453
|
+
/** Ready-to-paste forms of the same link. */
|
|
454
|
+
type UniversalLinkSnippets = {
|
|
455
|
+
url: string;
|
|
456
|
+
atUri: string;
|
|
457
|
+
markdown: string;
|
|
458
|
+
html: string;
|
|
459
|
+
};
|
|
460
|
+
type UniversalLink = {
|
|
461
|
+
url: string;
|
|
462
|
+
atUri: string;
|
|
463
|
+
type: WaypointType;
|
|
464
|
+
handle: string;
|
|
465
|
+
did: string | null;
|
|
466
|
+
collection: string | null;
|
|
467
|
+
rkey: string | null;
|
|
468
|
+
/** Human label for the target, e.g. `Post by @alice.bsky.social`. */
|
|
469
|
+
label: string;
|
|
470
|
+
share: UniversalLinkSharePayload;
|
|
471
|
+
snippets: UniversalLinkSnippets;
|
|
472
|
+
/** oEmbed endpoint for this link, or null for anything that isn't a post. */
|
|
473
|
+
oembedUrl: string | null;
|
|
474
|
+
};
|
|
475
|
+
type DescribeUniversalLinkOptions = UniversalLinkOptions & {
|
|
476
|
+
/** Override the share sheet's title. Defaults to the label. */
|
|
477
|
+
title?: string;
|
|
478
|
+
/** Override the share sheet's text. Defaults to the label. */
|
|
479
|
+
text?: string;
|
|
480
|
+
};
|
|
481
|
+
type UniversalLinkMetaTag = {
|
|
482
|
+
name: string;
|
|
483
|
+
content: string;
|
|
484
|
+
};
|
|
485
|
+
type UniversalLinkLinkTag = {
|
|
486
|
+
rel: string;
|
|
487
|
+
href: string;
|
|
488
|
+
type?: string;
|
|
489
|
+
};
|
|
490
|
+
type UniversalLinkTags = {
|
|
491
|
+
meta: UniversalLinkMetaTag[];
|
|
492
|
+
link: UniversalLinkLinkTag[];
|
|
493
|
+
/** The same tags as a ready-to-paste `<head>` fragment. */
|
|
494
|
+
html: string;
|
|
495
|
+
};
|
|
496
|
+
/**
|
|
497
|
+
* Build the aturi.to link for a target. Returns null for input that doesn't
|
|
498
|
+
* name a record or an identity.
|
|
499
|
+
*
|
|
500
|
+
* ```ts
|
|
501
|
+
* buildUniversalLink('at://did:plc:abc/app.bsky.feed.post/3k7');
|
|
502
|
+
* // 'https://aturi.to/profile/did:plc:abc/post/3k7'
|
|
503
|
+
* buildUniversalLink('https://bsky.app/profile/alice.bsky.social/post/3k7');
|
|
504
|
+
* // 'https://aturi.to/profile/alice.bsky.social/post/3k7'
|
|
505
|
+
* ```
|
|
506
|
+
*/
|
|
507
|
+
declare function buildUniversalLink(input: UniversalLinkTarget, options?: UniversalLinkOptions): string | null;
|
|
508
|
+
/**
|
|
509
|
+
* Turn an aturi.to URL back into the record it addresses. Accepts every shape
|
|
510
|
+
* the site serves: the canonical `/profile/…` links, the `/explore/…` record
|
|
511
|
+
* views, the legacy bare-path (`aturi.to/{handle}/{collection}/{rkey}`) and
|
|
512
|
+
* `at://`-in-path forms. Returns null for any other host or path.
|
|
513
|
+
*/
|
|
514
|
+
declare function parseUniversalLink(url: string | URL, options?: Pick<UniversalLinkOptions, 'origin'>): ParsedURI | null;
|
|
515
|
+
/** Whether a URL is an aturi.to link this package can resolve to a record. */
|
|
516
|
+
declare function isUniversalLink(url: string | URL, options?: Pick<UniversalLinkOptions, 'origin'>): boolean;
|
|
517
|
+
/**
|
|
518
|
+
* Everything a copy button or a share sheet needs for one target: the link
|
|
519
|
+
* itself, a human label, a `navigator.share()` payload, and the link in the
|
|
520
|
+
* forms people paste it in.
|
|
521
|
+
*
|
|
522
|
+
* ```ts
|
|
523
|
+
* const link = describeUniversalLink('at://did:plc:abc/app.bsky.feed.post/3k7');
|
|
524
|
+
* await navigator.share(link.share);
|
|
525
|
+
* await navigator.clipboard.writeText(link.snippets.markdown);
|
|
526
|
+
* ```
|
|
527
|
+
*/
|
|
528
|
+
declare function describeUniversalLink(input: UniversalLinkTarget, options?: DescribeUniversalLinkOptions): UniversalLink | null;
|
|
529
|
+
/**
|
|
530
|
+
* `<head>` tags that connect a page to the record it renders, so the rest of
|
|
531
|
+
* the Atmosphere can find its way back. Two consumers today:
|
|
532
|
+
*
|
|
533
|
+
* - `<meta name="at:canonical">` is the AT Tags proposal
|
|
534
|
+
* (https://tangled.org/chrisshank.com/at-tags/). Aturi's browser extension
|
|
535
|
+
* reads it off the live page and `aturi.to/api/resolve` reads it off the
|
|
536
|
+
* HTML, which is what turns your URL into "…and here are the 25 other
|
|
537
|
+
* clients that can open this". The `<link rel="alternate" href="at://…">`
|
|
538
|
+
* alongside it is the older spelling of the same declaration, kept because
|
|
539
|
+
* the resolver still falls back to it.
|
|
540
|
+
* - `<link type="application/json+oembed">` points unfurlers at the hosted
|
|
541
|
+
* oEmbed endpoint, so a link to your page previews as the post it is.
|
|
542
|
+
* Emitted for posts only, since that's all the endpoint renders.
|
|
543
|
+
*
|
|
544
|
+
* Serving these does not hand anything to aturi.to; they're static strings
|
|
545
|
+
* describing a record you already display.
|
|
546
|
+
*/
|
|
547
|
+
declare function buildUniversalLinkTags(input: UniversalLinkTarget, options?: UniversalLinkOptions): UniversalLinkTags | null;
|
|
548
|
+
|
|
549
|
+
export { type BuildWaypointsOptions, CATEGORY_ORDER, COMPAT_FAMILIES, COMPAT_FAMILY_ORDER, COMPOSE_INTENT_TEXT_PLACEHOLDER, type CategorizedWaypointsData, type CompatFamilyMeta, type ComposeIntentData, type ComposeIntentDescriptor, DID_REQUIRED_WAYPOINTS, type DescribeUniversalLinkOptions, type HandleResolution, OEMBED_LINK_TYPE, type ParsedURI, type RedirectCompatFamily, type ResolveApiFailure, type ResolveApiInput, type ResolveApiParsed, type ResolveApiResponse, type ResolveApiSuccess, type ResolveResult, type ResolveUrlOptions, type ResolveViaApiOptions, type ResolvedRecommendation, type ResolvedWaypoint, type ReverseMatch, SUPPORTED_HOSTS, type SourceApp, UNIVERSAL_LINK_ORIGIN, type UniversalLink, type UniversalLinkLinkTag, type UniversalLinkMetaTag, type UniversalLinkOptions, type UniversalLinkSharePayload, type UniversalLinkSnippets, type UniversalLinkTags, type UniversalLinkTarget, WAYPOINT_CATEGORIES_DATA, WAYPOINT_DESTINATIONS_DATA, WAYPOINT_ORDER, type WaypointActivity, type WaypointCategoryData, type WaypointData, type WaypointType, buildUniversalLink, buildUniversalLinkTags, buildWaypointsForParsed, describeComposeIntent, describeUniversalLink, getCategorizedWaypointsData, getComposeIntentAppUrl, getComposeIntentTemplate, getComposeIntentUrl, getComposeIntentWaypoints, getDisplayName, getFeaturedWaypointData, getRecommendedWaypointsData, getWaypointCountData, getWaypointDataForType, isSupportedHost, isUniversalLink, matchSupportedUrl, parseAtUri, parseURI, parseUniversalLink, resolveAtUri, resolveHandle, resolveHandleStatus, resolveUrl, resolveViaApi, supportsComposeIntent, waypointActivity };
|