export async function handleDeeplink()

in desktop/flipper-ui-core/src/deeplink.tsx [25:128]


export async function handleDeeplink(
  store: Store,
  logger: Logger,
  query: string,
): Promise<void> {
  const trackInteraction = track.bind(null, logger, query);
  const unknownError = () => {
    trackInteraction({
      state: 'ERROR',
      errorMessage: UNKNOWN,
    });
    throw new Error(UNKNOWN);
  };
  const uri = new URL(query);

  trackInteraction({
    state: 'INIT',
  });
  if (uri.protocol !== 'flipper:') {
    throw unknownError();
  }
  if (uri.href === 'flipper://' || uri.pathname === '//welcome') {
    // We support an empty protocol for just opening Flipper from anywhere
    // or alternatively flipper://welcome to open the welcome screen.
    return;
  }
  if (uri.href.startsWith('flipper://open-plugin')) {
    return handleOpenPluginDeeplink(store, query, trackInteraction);
  }
  if (uri.pathname.match(/^\/*import\/*$/)) {
    const url = uri.searchParams.get('url');
    if (url) {
      const handle = Dialog.loading({
        message: 'Importing Flipper trace...',
      });
      return fetch(url)
        .then((res) => res.text())
        .then((data) => importDataToStore(url, data, store))
        .catch((e: Error) => {
          console.warn('Failed to download Flipper trace', e);
          message.error({
            duration: 0,
            content: 'Failed to download Flipper trace: ' + e,
          });
        })
        .finally(() => {
          handle.close();
        });
    }
    throw unknownError();
  } else if (uri.pathname.match(/^\/*support-form\/*$/)) {
    const formParam = uri.searchParams.get('form');
    const grp = deeplinkFormParamToGroups(formParam);
    if (grp) {
      grp.handleSupportFormDeeplinks(store);
      return;
    }
    throw unknownError();
  } else if (uri.pathname.match(/^\/*login\/*$/)) {
    const token = uri.searchParams.get('token');
    showLoginDialog(token ?? '');
    return;
  }
  const match = uriComponents(query);
  if (match.length > 1) {
    // deprecated, use the open-plugin format instead, which is more flexible
    // and will guide the user through any necessary set up steps
    // flipper://<client>/<pluginId>/<payload>
    console.warn(
      `Deprecated deeplink format: '${query}', use 'flipper://open-plugin?plugin-id=${
        match[1]
      }&client=${match[0]}&payload=${encodeURIComponent(match[2])}' instead.`,
    );
    const deepLinkPayload = match[2];
    const deepLinkParams = new URLSearchParams(deepLinkPayload);
    const deviceParam = deepLinkParams.get('device');

    // if there is a device Param, find a matching device
    const selectedDevice = deviceParam
      ? store
          .getState()
          .connections.devices.find((v) => v.title === deviceParam)
      : undefined;

    // if a client is specified, find it, withing the device if applicable
    const selectedClient = getAllClients(store.getState().connections).find(
      (c) =>
        c.query.app === match[0] &&
        (selectedDevice == null || c.device === selectedDevice),
    );

    store.dispatch(
      selectPlugin({
        selectedAppId: selectedClient?.id,
        selectedDevice: selectedClient ? selectedClient.device : selectedDevice,
        selectedPlugin: match[1],
        deepLinkPayload,
      }),
    );
    return;
  } else {
    throw unknownError();
  }
}