@njweber/app-check 0.1.0 → 0.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/README.md CHANGED
@@ -9,8 +9,10 @@ npx @njweber/app-check ./build/app-release.aab ./build/YourApp.ipa ./assets/icon
9
9
 
10
10
  | Artifact | What it's checked for | Under the hood |
11
11
  |---|---|---|
12
- | `*.aab`, `*.apk` | Android 16 KB page-size compliance | [`store-check`](https://github.com/nwebersoftware/store-check) |
13
- | `*.ipa` | App Store submission pitfalls | [`ipa-check`](https://github.com/nwebersoftware/ipa-check) |
12
+ | `*.aab` | Android 16 KB page size **and** the manifest audit | [`store-check`](https://github.com/nwebersoftware/store-check) + [`manifest-check`](https://github.com/nwebersoftware/manifest-check) |
13
+ | `*.apk` | Android 16 KB page size | [`store-check`](https://github.com/nwebersoftware/store-check) |
14
+ | `AndroidManifest.xml` | Android manifest audit | [`manifest-check`](https://github.com/nwebersoftware/manifest-check) |
15
+ | `*.ipa` | App Store submission pitfalls **and** privacy usage descriptions | [`ipa-check`](https://github.com/nwebersoftware/ipa-check) + [`privacy-check`](https://github.com/nwebersoftware/privacy-check) |
14
16
  | `*.png` | icon size / alpha rules | [`icon-check`](https://github.com/nwebersoftware/icon-check) |
15
17
 
16
18
  ```
@@ -57,7 +59,11 @@ to discover mid-review.
57
59
 
58
60
  ## Family
59
61
 
60
- Each check is also its own focused tool: `store-check` · `ipa-check` · `icon-check`.
62
+ Each check is also its own focused tool: `store-check` · `manifest-check` · `ipa-check` · `privacy-check` · `icon-check`.
63
+
64
+ An `.ipa` deliberately runs **two** audits — submission shape (`ipa-check`) and privacy declarations
65
+ (`privacy-check`). An `.aab` runs **two** as well — the 16 KB page-size check (`store-check`) and the
66
+ manifest audit (`manifest-check`).
61
67
 
62
68
  ## License
63
69
 
package/bin/app-check.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { readFileSync, readdirSync } from 'node:fs';
3
- import { extname, join } from 'node:path';
3
+ import { join } from 'node:path';
4
4
 
5
- import { classify, runCheck, SUPPORTED } from '../src/run.mjs';
5
+ import { classify, checksFor, runCheck } from '../src/run.mjs';
6
6
 
7
7
  const HELP = `app-check — check a mobile build before the stores do
8
8
 
@@ -47,7 +47,7 @@ function collect(dir, out = []) {
47
47
  if (e.name.startsWith('.') || SKIP.has(e.name)) continue;
48
48
  const p = join(dir, e.name);
49
49
  if (e.isDirectory()) collect(p, out);
50
- else if (SUPPORTED.includes(extname(e.name).toLowerCase())) out.push(p);
50
+ else if (classify(e.name)) out.push(p);
51
51
  }
52
52
  return out;
53
53
  }
@@ -79,10 +79,12 @@ for (const file of files) {
79
79
  badInput = true;
80
80
  continue;
81
81
  }
82
- const co = { label: file };
83
- if (kind === 'icon' && opts.android) co.platform = 'android';
84
- if (kind === 'ios' && opts.bundleId) co.bundleId = opts.bundleId;
85
- results.push(runCheck(kind, buf, co));
82
+ for (const k of checksFor(kind, file)) {
83
+ const co = { label: file };
84
+ if (k === 'icon' && opts.android) co.platform = 'android';
85
+ if (k === 'ios' && opts.bundleId) co.bundleId = opts.bundleId;
86
+ results.push(runCheck(k, buf, co));
87
+ }
86
88
  }
87
89
 
88
90
  const failed = results.filter((r) => !r.report.ok).length;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@njweber/app-check",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "One command to check a mobile build before the stores do — Android 16 KB page size, iOS .ipa pitfalls, and icon rules.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -19,7 +19,9 @@
19
19
  "engines": { "node": ">=18" },
20
20
  "dependencies": {
21
21
  "@njweber/store-check": "^0.1.0",
22
+ "@njweber/android-manifest-check": "^0.1.0",
22
23
  "@njweber/ipa-check": "^0.1.0",
24
+ "@njweber/privacy-check": "^0.1.0",
23
25
  "icon-check": "^0.1.0"
24
26
  }
25
27
  }
package/src/run.mjs CHANGED
@@ -1,22 +1,35 @@
1
1
  import { checkArtifact, formatReport as fmtAndroid } from '@njweber/store-check/src/check.mjs';
2
+ import { checkManifest, formatReport as fmtManifest } from '@njweber/android-manifest-check/src/check.mjs';
2
3
  import { checkIpa, formatReport as fmtIpa } from '@njweber/ipa-check/src/check.mjs';
4
+ import { checkPrivacy, formatReport as fmtPrivacy } from '@njweber/privacy-check/src/check.mjs';
3
5
  import { checkIcon, formatReport as fmtIcon } from 'icon-check/src/check.mjs';
4
6
 
5
7
  const TOOLS = {
6
8
  android: { name: 'store-check', run: (buf) => checkArtifact(buf), fmt: fmtAndroid },
9
+ manifest: { name: 'manifest-check', run: (buf) => checkManifest(buf), fmt: fmtManifest },
7
10
  ios: { name: 'ipa-check', run: (buf, o) => checkIpa(buf, o), fmt: fmtIpa },
11
+ privacy: { name: 'privacy-check', run: (buf) => checkPrivacy(buf), fmt: fmtPrivacy },
8
12
  icon: { name: 'icon-check', run: (buf, o) => checkIcon(buf, o), fmt: fmtIcon },
9
13
  };
10
14
 
11
- /** Map a file path to the check that applies, by extension. */
15
+ /** Map a file path to the primary check that applies. */
12
16
  export function classify(file) {
13
17
  const lower = String(file).toLowerCase();
18
+ if (lower.endsWith('androidmanifest.xml')) return 'manifest';
14
19
  if (lower.endsWith('.aab') || lower.endsWith('.apk')) return 'android';
15
20
  if (lower.endsWith('.ipa')) return 'ios';
16
21
  if (lower.endsWith('.png')) return 'icon';
17
22
  return null;
18
23
  }
19
24
 
25
+ /** Every check that should run for an artifact (some artifacts get more than one audit). */
26
+ export function checksFor(kind, file = '') {
27
+ const lower = String(file).toLowerCase();
28
+ if (kind === 'ios') return ['ios', 'privacy'];
29
+ if (kind === 'android') return lower.endsWith('.aab') ? ['android', 'manifest'] : ['android'];
30
+ return [kind];
31
+ }
32
+
20
33
  /**
21
34
  * Run one check, never throwing: a bad artifact becomes a failing result, not a crash.
22
35
  * Returns { kind, name, label, report, text, error }.