@njweber/app-check 0.1.0 → 0.1.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/README.md CHANGED
@@ -10,7 +10,7 @@ npx @njweber/app-check ./build/app-release.aab ./build/YourApp.ipa ./assets/icon
10
10
  | Artifact | What it's checked for | Under the hood |
11
11
  |---|---|---|
12
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) |
13
+ | `*.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
14
  | `*.png` | icon size / alpha rules | [`icon-check`](https://github.com/nwebersoftware/icon-check) |
15
15
 
16
16
  ```
@@ -57,7 +57,10 @@ to discover mid-review.
57
57
 
58
58
  ## Family
59
59
 
60
- Each check is also its own focused tool: `store-check` · `ipa-check` · `icon-check`.
60
+ Each check is also its own focused tool: `store-check` · `ipa-check` · `privacy-check` · `icon-check`.
61
+
62
+ An `.ipa` deliberately runs **two** audits — submission shape (`ipa-check`) and privacy declarations
63
+ (`privacy-check`).
61
64
 
62
65
  ## License
63
66
 
package/bin/app-check.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  import { readFileSync, readdirSync } from 'node:fs';
3
3
  import { extname, join } from 'node:path';
4
4
 
5
- import { classify, runCheck, SUPPORTED } from '../src/run.mjs';
5
+ import { classify, checksFor, runCheck, SUPPORTED } from '../src/run.mjs';
6
6
 
7
7
  const HELP = `app-check — check a mobile build before the stores do
8
8
 
@@ -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)) {
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.1.1",
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": {
@@ -20,6 +20,7 @@
20
20
  "dependencies": {
21
21
  "@njweber/store-check": "^0.1.0",
22
22
  "@njweber/ipa-check": "^0.1.0",
23
+ "@njweber/privacy-check": "^0.1.0",
23
24
  "icon-check": "^0.1.0"
24
25
  }
25
26
  }
package/src/run.mjs CHANGED
@@ -1,14 +1,16 @@
1
1
  import { checkArtifact, formatReport as fmtAndroid } from '@njweber/store-check/src/check.mjs';
2
2
  import { checkIpa, formatReport as fmtIpa } from '@njweber/ipa-check/src/check.mjs';
3
+ import { checkPrivacy, formatReport as fmtPrivacy } from '@njweber/privacy-check/src/check.mjs';
3
4
  import { checkIcon, formatReport as fmtIcon } from 'icon-check/src/check.mjs';
4
5
 
5
6
  const TOOLS = {
6
7
  android: { name: 'store-check', run: (buf) => checkArtifact(buf), fmt: fmtAndroid },
7
8
  ios: { name: 'ipa-check', run: (buf, o) => checkIpa(buf, o), fmt: fmtIpa },
9
+ privacy: { name: 'privacy-check', run: (buf) => checkPrivacy(buf), fmt: fmtPrivacy },
8
10
  icon: { name: 'icon-check', run: (buf, o) => checkIcon(buf, o), fmt: fmtIcon },
9
11
  };
10
12
 
11
- /** Map a file path to the check that applies, by extension. */
13
+ /** Map a file path to the primary check that applies, by extension. */
12
14
  export function classify(file) {
13
15
  const lower = String(file).toLowerCase();
14
16
  if (lower.endsWith('.aab') || lower.endsWith('.apk')) return 'android';
@@ -17,6 +19,12 @@ export function classify(file) {
17
19
  return null;
18
20
  }
19
21
 
22
+ /** Every check that should run for an artifact kind (an .ipa gets two audits). */
23
+ export function checksFor(kind) {
24
+ if (kind === 'ios') return ['ios', 'privacy'];
25
+ return [kind];
26
+ }
27
+
20
28
  /**
21
29
  * Run one check, never throwing: a bad artifact becomes a failing result, not a crash.
22
30
  * Returns { kind, name, label, report, text, error }.