deeplink-parity 0.3.0 → 0.3.1

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/dist/cli.js CHANGED
@@ -55,7 +55,17 @@ async function main() {
55
55
  return;
56
56
  }
57
57
  const source = wellKnown ? localSource(resolve(wellKnown)) : networkSource();
58
- const result = await run({ roots, source, sha256 });
58
+ const result = await run({
59
+ roots,
60
+ source,
61
+ sha256,
62
+ onDiscovered: (count) => {
63
+ // some apps declare a domain per country; say so before spending minutes on it
64
+ if (!wellKnown && count > 50) {
65
+ console.error(`Checking ${count} domains — requests are pooled, so this will take a while.`);
66
+ }
67
+ },
68
+ });
59
69
  if (result.iosApps.length === 0 && result.androidApps.length === 0 && result.findings.length === 0) {
60
70
  console.error(`No app configuration declaring deep links was found in ${roots.join(', ')}`);
61
71
  console.error('Expected a .entitlements file with applinks:, or an AndroidManifest.xml with intent-filters.');
@@ -1,6 +1,12 @@
1
1
  import { readFile } from 'node:fs/promises';
2
2
  import { join } from 'node:path';
3
3
  const TIMEOUT_MS = 10_000;
4
+ /**
5
+ * Identify the tool to the hosts being read. An operator seeing these requests in a log
6
+ * should be able to tell what they are and who to ask, rather than finding an anonymous
7
+ * Node default.
8
+ */
9
+ const USER_AGENT = 'deeplink-parity (+https://github.com/camosss/deeplink-parity)';
4
10
  export const AASA_FILE = 'apple-app-site-association';
5
11
  export const ASSETLINKS_FILE = 'assetlinks.json';
6
12
  export function aasaUrl(domain) {
@@ -20,7 +26,7 @@ async function fetchRaw(url) {
20
26
  const res = await fetch(url, {
21
27
  redirect: 'manual',
22
28
  signal: controller.signal,
23
- headers: { accept: 'application/json' },
29
+ headers: { accept: 'application/json', 'user-agent': USER_AGENT },
24
30
  });
25
31
  const redirected = res.status >= 300 && res.status < 400;
26
32
  return {
package/dist/run.js CHANGED
@@ -9,7 +9,7 @@ import { isWildcardDomain, wildcardFinding } from './rules/wildcard.js';
9
9
  function emptyView() {
10
10
  return { domains: new Set(), paths: new Map() };
11
11
  }
12
- export async function run({ roots, source, sha256 }) {
12
+ export async function run({ roots, source, sha256, onDiscovered }) {
13
13
  const discovered = await Promise.all(roots.map(async (root) => Promise.all([discoverIos(root), discoverAndroid(root)])));
14
14
  const iosApps = discovered.flatMap(([ios]) => ios);
15
15
  const androidApps = discovered.flatMap(([, android]) => android);
@@ -21,6 +21,10 @@ export async function run({ roots, source, sha256 }) {
21
21
  }
22
22
  const ios = emptyView();
23
23
  const android = emptyView();
24
+ onDiscovered?.(new Set([
25
+ ...iosApps.flatMap((a) => a.domains),
26
+ ...androidApps.flatMap((a) => a.hosts.map((h) => h.host)),
27
+ ]).size);
24
28
  for (const app of iosApps) {
25
29
  // the same domain can be declared by several targets; fetch it once
26
30
  const fresh = app.domains.filter((d) => !ios.domains.has(d));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deeplink-parity",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Checks that what your mobile app declares about deep links matches what is actually hosted — across iOS and Android.",
5
5
  "type": "module",
6
6
  "bin": {