@proappstore/compliance 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.
@@ -1,9 +1,15 @@
1
1
  import type { FileSource } from '../lib/file-source.js';
2
2
  import type { CheckResult } from '../types.js';
3
3
  /**
4
- * Verifies the PWA manifest exists at the expected location and parses
5
- * to JSON. Apps without a manifest can't be "Add to Home Screen"-d on
6
- * mobile; required by the platform.
4
+ * Verifies the PWA manifest declares the four required fields (name,
5
+ * short_name, start_url, display). Two valid sources, in order:
6
+ *
7
+ * 1. `web/public/manifest.json` — legacy static apps that ship their
8
+ * own manifest file.
9
+ * 2. The `manifest: { ... }` block inside `VitePWA({...})` in
10
+ * `web/vite.config.ts` — the path every game currently uses.
11
+ *
12
+ * Either is fine; both being missing fails.
7
13
  */
8
14
  export declare function checkManifest(source: FileSource): Promise<CheckResult>;
9
15
  //# sourceMappingURL=manifest.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/checks/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI/C;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAoC5E"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/checks/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK/C;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAoB5E"}
@@ -1,22 +1,37 @@
1
- const MANIFEST_PATH = 'web/public/manifest.json';
1
+ import { extractInlineManifest } from '../lib/inline-manifest.js';
2
+ const STATIC_MANIFEST_PATH = 'web/public/manifest.json';
3
+ const VITE_CONFIG_PATH = 'web/vite.config.ts';
2
4
  /**
3
- * Verifies the PWA manifest exists at the expected location and parses
4
- * to JSON. Apps without a manifest can't be "Add to Home Screen"-d on
5
- * mobile; required by the platform.
5
+ * Verifies the PWA manifest declares the four required fields (name,
6
+ * short_name, start_url, display). Two valid sources, in order:
7
+ *
8
+ * 1. `web/public/manifest.json` — legacy static apps that ship their
9
+ * own manifest file.
10
+ * 2. The `manifest: { ... }` block inside `VitePWA({...})` in
11
+ * `web/vite.config.ts` — the path every game currently uses.
12
+ *
13
+ * Either is fine; both being missing fails.
6
14
  */
7
15
  export async function checkManifest(source) {
8
- const raw = await source.read(MANIFEST_PATH);
9
- if (raw === null) {
10
- return {
11
- name: 'PWA manifest',
12
- status: 'fail',
13
- detail: `${MANIFEST_PATH} missing`,
14
- suggestions: [
15
- 'Add a manifest.json with at least name, short_name, start_url, display, icons.',
16
- 'See template-standalone for a working example.',
17
- ],
18
- };
16
+ const staticRaw = await source.read(STATIC_MANIFEST_PATH);
17
+ if (staticRaw !== null) {
18
+ return validateStaticManifest(staticRaw);
19
19
  }
20
+ const viteConfig = await source.read(VITE_CONFIG_PATH);
21
+ if (viteConfig !== null && /\bVitePWA\s*\(/.test(viteConfig)) {
22
+ return validateInlineManifest(viteConfig);
23
+ }
24
+ return {
25
+ name: 'PWA manifest',
26
+ status: 'fail',
27
+ detail: `no manifest source found (looked for ${STATIC_MANIFEST_PATH} and a VitePWA(...) block in ${VITE_CONFIG_PATH})`,
28
+ suggestions: [
29
+ 'Add a VitePWA(...) plugin to web/vite.config.ts with an inline manifest:{...} block, OR',
30
+ 'Add a static web/public/manifest.json with at least name, short_name, start_url, display, icons.',
31
+ ],
32
+ };
33
+ }
34
+ function validateStaticManifest(raw) {
20
35
  let parsed;
21
36
  try {
22
37
  parsed = JSON.parse(raw);
@@ -25,7 +40,7 @@ export async function checkManifest(source) {
25
40
  return {
26
41
  name: 'PWA manifest',
27
42
  status: 'fail',
28
- detail: `${MANIFEST_PATH} is not valid JSON`,
43
+ detail: `${STATIC_MANIFEST_PATH} is not valid JSON`,
29
44
  };
30
45
  }
31
46
  const required = ['name', 'short_name', 'start_url', 'display'];
@@ -34,10 +49,38 @@ export async function checkManifest(source) {
34
49
  return {
35
50
  name: 'PWA manifest',
36
51
  status: 'warn',
37
- detail: `missing fields: ${missing.join(', ')}`,
52
+ detail: `missing fields in ${STATIC_MANIFEST_PATH}: ${missing.join(', ')}`,
38
53
  suggestions: [`Add the ${missing.join(', ')} field(s) to manifest.json so installs work.`],
39
54
  };
40
55
  }
41
- return { name: 'PWA manifest', status: 'pass', detail: MANIFEST_PATH };
56
+ return { name: 'PWA manifest', status: 'pass', detail: STATIC_MANIFEST_PATH };
57
+ }
58
+ function validateInlineManifest(viteConfig) {
59
+ const inline = extractInlineManifest(viteConfig);
60
+ if (!inline) {
61
+ return {
62
+ name: 'PWA manifest',
63
+ status: 'fail',
64
+ detail: `VitePWA(...) call found in ${VITE_CONFIG_PATH} but the manifest:{...} block could not be parsed`,
65
+ suggestions: [
66
+ 'Add a top-level `manifest: { name, short_name, start_url, display, icons, ... }` to your VitePWA() options.',
67
+ ],
68
+ };
69
+ }
70
+ const required = ['name', 'short_name', 'start_url', 'display'];
71
+ const missing = required.filter((k) => typeof inline[k] !== 'string' || inline[k] === '');
72
+ if (missing.length > 0) {
73
+ return {
74
+ name: 'PWA manifest',
75
+ status: 'warn',
76
+ detail: `missing fields in inline manifest (${VITE_CONFIG_PATH}): ${missing.join(', ')}`,
77
+ suggestions: [`Add ${missing.join(', ')} to the manifest:{...} inside VitePWA({...}).`],
78
+ };
79
+ }
80
+ return {
81
+ name: 'PWA manifest',
82
+ status: 'pass',
83
+ detail: `inline in ${VITE_CONFIG_PATH} (name="${inline.name}", display="${inline.display}")`,
84
+ };
42
85
  }
43
86
  //# sourceMappingURL=manifest.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/checks/manifest.ts"],"names":[],"mappings":"AAGA,MAAM,aAAa,GAAG,0BAA0B,CAAC;AAEjD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAAkB;IACpD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC7C,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACjB,OAAO;YACL,IAAI,EAAE,cAAc;YACpB,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,GAAG,aAAa,UAAU;YAClC,WAAW,EAAE;gBACX,gFAAgF;gBAChF,gDAAgD;aACjD;SACF,CAAC;IACJ,CAAC;IAED,IAAI,MAAwF,CAAC;IAC7F,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,IAAI,EAAE,cAAc;YACpB,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,GAAG,aAAa,oBAAoB;SAC7C,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,CAAU,CAAC;IACzE,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IAC1F,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO;YACL,IAAI,EAAE,cAAc;YACpB,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,mBAAmB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC/C,WAAW,EAAE,CAAC,WAAW,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,8CAA8C,CAAC;SAC3F,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;AACzE,CAAC"}
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/checks/manifest.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"no-brand-overrides.d.ts","sourceRoot":"","sources":["../../src/checks/no-brand-overrides.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAgDpF;AA2DD,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAO,GACrC,MAAM,EAAE,CAmDV"}
1
+ {"version":3,"file":"no-brand-overrides.d.ts","sourceRoot":"","sources":["../../src/checks/no-brand-overrides.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CA8CpF;AA2DD,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAO,GACrC,MAAM,EAAE,CAmEV"}
@@ -31,9 +31,7 @@ export async function checkNoBrandOverrides(source) {
31
31
  // `fontFamily: "Comic Sans"` IS a string literal and is the thing
32
32
  // we're auditing. For .css/.scss use the css-only stripper (no `//`
33
33
  // syntax at the language level).
34
- const content = ext === '.css' || ext === '.scss'
35
- ? stripCssComments(raw)
36
- : stripCommentsOnly(raw);
34
+ const content = ext === '.css' || ext === '.scss' ? stripCssComments(raw) : stripCommentsOnly(raw);
37
35
  // Canonical theme file: the platform's CSS variables ARE defined here.
38
36
  // Apps own this file post-scaffold (they can technically modify token
39
37
  // values, and we accept the imperfection — the loud places where a
@@ -141,11 +139,22 @@ export function scanContent(filename, content, opts = {}) {
141
139
  // quoted string in the value and check each one separately. If there are
142
140
  // no quoted strings, the value is treated as a CSS-style comma list
143
141
  // (`font-family: Comic Sans, serif`).
144
- const fontHeadRe = /(font-family|fontFamily)\s*[:=]/g;
142
+ // Patterns:
143
+ // - `font-family:` (kebab-case + colon) — real CSS rule
144
+ // - `fontFamily:` (camelCase + colon) — JSX inline style object property
145
+ // - `fontFamily=` (camelCase + equals) — JSX attribute on a styled component
146
+ // Deliberately NOT matched: `font-family=` (kebab + equals). That form
147
+ // only legitimately appears as an SVG/HTML attribute, and in practice
148
+ // shows up most often inside JS template-literal SVG generators —
149
+ // greedily slicing those values picks up adjacent SVG attributes
150
+ // (`font-size="280"`, `fill="rgba(...)"`) as fake "font candidates"
151
+ // and false-positives. Real SVG-in-JSX with kebab fontFamily is rare
152
+ // enough to skip.
153
+ const fontHeadRe = /(font-family\s*:|fontFamily\s*[:=])/g;
145
154
  const quotedRe = /(['"`])([^'"`\n]+)\1/g;
146
155
  let m;
147
156
  while ((m = fontHeadRe.exec(content)) !== null) {
148
- const isJsx = m[1] === 'fontFamily';
157
+ const isJsx = m[1].startsWith('fontFamily');
149
158
  const start = m.index + m[0].length;
150
159
  const value = sliceFontValue(content, start, isJsx);
151
160
  const quotedStrings = [...value.matchAll(quotedRe)].map((x) => x[2]);
@@ -154,7 +163,10 @@ export function scanContent(filename, content, opts = {}) {
154
163
  for (const cand of candidates) {
155
164
  const tokens = cand
156
165
  .split(',')
157
- .map((t) => t.trim().replace(/^["']|["']$/g, '').toLowerCase())
166
+ .map((t) => t
167
+ .trim()
168
+ .replace(/^["']|["']$/g, '')
169
+ .toLowerCase())
158
170
  .filter(Boolean);
159
171
  for (const t of tokens) {
160
172
  if (!ALLOWED_FONT_TOKENS.has(t)) {
@@ -1 +1 @@
1
- {"version":3,"file":"no-brand-overrides.js","sourceRoot":"","sources":["../../src/checks/no-brand-overrides.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"no-brand-overrides.js","sourceRoot":"","sources":["../../src/checks/no-brand-overrides.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { FileSource } from '../lib/file-source.js';
2
+ import type { CheckResult } from '../types.js';
3
+ /**
4
+ * Verifies the PWA manifest declares at least one icon with
5
+ * `purpose: "maskable"` (or a combined value containing "maskable" such
6
+ * as "any maskable").
7
+ *
8
+ * Why this matters: on Android, Chrome's installability heuristics
9
+ * downgrade a PWA to a launcher *shortcut* (just a bookmark with the
10
+ * site favicon) when no maskable icon is declared. With a maskable
11
+ * icon, the same install becomes a real PWA — its own task slot, app
12
+ * drawer entry, and adaptive icon shape.
13
+ *
14
+ * Detection is intentionally lenient: we look for a `purpose:` value
15
+ * containing the substring `maskable` anywhere in the icons array.
16
+ * That catches `'maskable'`, `'any maskable'`, `"maskable any"`, and
17
+ * separate-entry styles alike.
18
+ */
19
+ export declare function checkMaskableIcon(source: FileSource): Promise<CheckResult>;
20
+ //# sourceMappingURL=pwa-maskable-icon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pwa-maskable-icon.d.ts","sourceRoot":"","sources":["../../src/checks/pwa-maskable-icon.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK/C;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAmBhF"}
@@ -0,0 +1,91 @@
1
+ import { extractInlineManifest } from '../lib/inline-manifest.js';
2
+ const STATIC_MANIFEST_PATH = 'web/public/manifest.json';
3
+ const VITE_CONFIG_PATH = 'web/vite.config.ts';
4
+ /**
5
+ * Verifies the PWA manifest declares at least one icon with
6
+ * `purpose: "maskable"` (or a combined value containing "maskable" such
7
+ * as "any maskable").
8
+ *
9
+ * Why this matters: on Android, Chrome's installability heuristics
10
+ * downgrade a PWA to a launcher *shortcut* (just a bookmark with the
11
+ * site favicon) when no maskable icon is declared. With a maskable
12
+ * icon, the same install becomes a real PWA — its own task slot, app
13
+ * drawer entry, and adaptive icon shape.
14
+ *
15
+ * Detection is intentionally lenient: we look for a `purpose:` value
16
+ * containing the substring `maskable` anywhere in the icons array.
17
+ * That catches `'maskable'`, `'any maskable'`, `"maskable any"`, and
18
+ * separate-entry styles alike.
19
+ */
20
+ export async function checkMaskableIcon(source) {
21
+ const staticRaw = await source.read(STATIC_MANIFEST_PATH);
22
+ if (staticRaw !== null) {
23
+ return validateStatic(staticRaw);
24
+ }
25
+ const viteConfig = await source.read(VITE_CONFIG_PATH);
26
+ if (viteConfig !== null && /\bVitePWA\s*\(/.test(viteConfig)) {
27
+ return validateInline(viteConfig);
28
+ }
29
+ // No manifest source found at all — the `checkManifest` rule will
30
+ // already fail loudly. Pass here so we don't double-report the same
31
+ // root cause as two failures.
32
+ return {
33
+ name: 'PWA maskable icon',
34
+ status: 'pass',
35
+ detail: 'no manifest source (already reported by PWA manifest check)',
36
+ };
37
+ }
38
+ function validateStatic(raw) {
39
+ let parsed;
40
+ try {
41
+ parsed = JSON.parse(raw);
42
+ }
43
+ catch {
44
+ return {
45
+ name: 'PWA maskable icon',
46
+ status: 'fail',
47
+ detail: `${STATIC_MANIFEST_PATH} is not valid JSON`,
48
+ };
49
+ }
50
+ const icons = Array.isArray(parsed.icons) ? parsed.icons : [];
51
+ const hasMaskable = icons.some((icon) => typeof icon?.purpose === 'string' && /\bmaskable\b/.test(icon.purpose));
52
+ if (hasMaskable) {
53
+ return { name: 'PWA maskable icon', status: 'pass', detail: STATIC_MANIFEST_PATH };
54
+ }
55
+ return buildFail(STATIC_MANIFEST_PATH);
56
+ }
57
+ function validateInline(viteConfig) {
58
+ const inline = extractInlineManifest(viteConfig);
59
+ if (!inline || !inline.iconsRaw) {
60
+ return {
61
+ name: 'PWA maskable icon',
62
+ status: 'fail',
63
+ detail: `inline manifest in ${VITE_CONFIG_PATH} has no parsable icons array`,
64
+ suggestions: [
65
+ 'Add an icons array to the manifest:{...} block in VitePWA({...}).',
66
+ ],
67
+ };
68
+ }
69
+ // Lenient string-level check — see the doc-comment on `checkMaskableIcon`.
70
+ const hasMaskable = /purpose\s*:\s*['"`][^'"`]*\bmaskable\b[^'"`]*['"`]/.test(inline.iconsRaw);
71
+ if (hasMaskable) {
72
+ return {
73
+ name: 'PWA maskable icon',
74
+ status: 'pass',
75
+ detail: `inline manifest in ${VITE_CONFIG_PATH}`,
76
+ };
77
+ }
78
+ return buildFail(`inline manifest in ${VITE_CONFIG_PATH}`);
79
+ }
80
+ function buildFail(where) {
81
+ return {
82
+ name: 'PWA maskable icon',
83
+ status: 'fail',
84
+ detail: `no icon declares purpose containing "maskable" (${where})`,
85
+ suggestions: [
86
+ "Add `purpose: 'any maskable'` to each icon entry (or a dedicated 512×512 icon with `purpose: 'maskable'`).",
87
+ 'Without it, Android Chrome installs the app as a launcher shortcut, not a real PWA.',
88
+ ],
89
+ };
90
+ }
91
+ //# sourceMappingURL=pwa-maskable-icon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pwa-maskable-icon.js","sourceRoot":"","sources":["../../src/checks/pwa-maskable-icon.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,7 @@ import type { CheckResult } from '../types.js';
6
6
  * 92% of devices · portrait + landscape") and visitors know what to
7
7
  * expect before they tap.
8
8
  *
9
- * Two declarations are required, both in `web/public/manifest.json`:
9
+ * Two declarations are required:
10
10
  *
11
11
  * "orientation": "any" | "portrait" | "landscape" |
12
12
  * "portrait-primary" | "landscape-primary"
@@ -19,6 +19,9 @@ import type { CheckResult } from '../types.js';
19
19
  *
20
20
  * If you genuinely don't care about orientation, set `"any"`. Don't
21
21
  * leave it off — that's the only value that returns a fail.
22
+ *
23
+ * Read from either a static `web/public/manifest.json` or the inline
24
+ * `manifest:{...}` inside VitePWA(...) in `web/vite.config.ts`.
22
25
  */
23
26
  export declare function checkViewportSupport(source: FileSource): Promise<CheckResult>;
24
27
  //# sourceMappingURL=viewport-support.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"viewport-support.d.ts","sourceRoot":"","sources":["../../src/checks/viewport-support.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI/C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAqEnF"}
1
+ {"version":3,"file":"viewport-support.d.ts","sourceRoot":"","sources":["../../src/checks/viewport-support.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK/C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CA2DnF"}
@@ -1,11 +1,13 @@
1
- const MANIFEST_PATH = 'web/public/manifest.json';
1
+ import { extractInlineManifest } from '../lib/inline-manifest.js';
2
+ const STATIC_MANIFEST_PATH = 'web/public/manifest.json';
3
+ const VITE_CONFIG_PATH = 'web/vite.config.ts';
2
4
  /**
3
5
  * Apps and games must declare which screens and orientations they
4
6
  * support, so the storefront can render a coverage badge ("works on
5
7
  * 92% of devices · portrait + landscape") and visitors know what to
6
8
  * expect before they tap.
7
9
  *
8
- * Two declarations are required, both in `web/public/manifest.json`:
10
+ * Two declarations are required:
9
11
  *
10
12
  * "orientation": "any" | "portrait" | "landscape" |
11
13
  * "portrait-primary" | "landscape-primary"
@@ -18,25 +20,17 @@ const MANIFEST_PATH = 'web/public/manifest.json';
18
20
  *
19
21
  * If you genuinely don't care about orientation, set `"any"`. Don't
20
22
  * leave it off — that's the only value that returns a fail.
23
+ *
24
+ * Read from either a static `web/public/manifest.json` or the inline
25
+ * `manifest:{...}` inside VitePWA(...) in `web/vite.config.ts`.
21
26
  */
22
27
  export async function checkViewportSupport(source) {
23
- const raw = await source.read(MANIFEST_PATH);
24
- if (raw === null) {
25
- return {
26
- name: 'Viewport support',
27
- status: 'fail',
28
- detail: `${MANIFEST_PATH} not found`,
29
- };
30
- }
31
- let manifest;
32
- try {
33
- manifest = JSON.parse(raw);
34
- }
35
- catch {
28
+ const manifest = await loadManifest(source);
29
+ if (!manifest) {
36
30
  return {
37
31
  name: 'Viewport support',
38
32
  status: 'fail',
39
- detail: `${MANIFEST_PATH} unparseable`,
33
+ detail: `no manifest source found (looked for ${STATIC_MANIFEST_PATH} and a VitePWA(...) block in ${VITE_CONFIG_PATH})`,
40
34
  };
41
35
  }
42
36
  const orientation = manifest.orientation;
@@ -63,7 +57,7 @@ export async function checkViewportSupport(source) {
63
57
  detail: `${issues.length} viewport-declaration issue${issues.length === 1 ? '' : 's'}`,
64
58
  suggestions: [
65
59
  ...issues,
66
- 'Edit web/public/manifest.json: add "orientation": "any" (or portrait/landscape) and "min_viewport_width": 360.',
60
+ 'Add `"orientation": "any"` (or portrait/landscape) and `"min_viewport_width": 360` to the manifest — either in web/public/manifest.json or inside the manifest:{...} of VitePWA() in web/vite.config.ts.',
67
61
  ],
68
62
  };
69
63
  }
@@ -81,6 +75,22 @@ export async function checkViewportSupport(source) {
81
75
  detail: `orientation=${orientation} · min ${minWidth}px`,
82
76
  };
83
77
  }
78
+ async function loadManifest(source) {
79
+ const staticRaw = await source.read(STATIC_MANIFEST_PATH);
80
+ if (staticRaw !== null) {
81
+ try {
82
+ return JSON.parse(staticRaw);
83
+ }
84
+ catch {
85
+ return null;
86
+ }
87
+ }
88
+ const viteConfig = await source.read(VITE_CONFIG_PATH);
89
+ if (viteConfig !== null && /\bVitePWA\s*\(/.test(viteConfig)) {
90
+ return extractInlineManifest(viteConfig);
91
+ }
92
+ return null;
93
+ }
84
94
  const VALID_ORIENTATIONS = new Set([
85
95
  'any',
86
96
  'portrait',
@@ -1 +1 @@
1
- {"version":3,"file":"viewport-support.js","sourceRoot":"","sources":["../../src/checks/viewport-support.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"viewport-support.js","sourceRoot":"","sources":["../../src/checks/viewport-support.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -6,6 +6,7 @@ import { checkDarkMode } from './checks/dark-mode.js';
6
6
  import { checkHtmlMeta } from './checks/html-meta.js';
7
7
  import { checkLicenseMit } from './checks/license-mit.js';
8
8
  import { checkManifest } from './checks/manifest.js';
9
+ import { checkMaskableIcon } from './checks/pwa-maskable-icon.js';
9
10
  import { checkNoBrandOverrides } from './checks/no-brand-overrides.js';
10
11
  import { checkNoEnvProduction } from './checks/no-env-production.js';
11
12
  import { checkNoPlaceholders } from './checks/no-placeholders.js';
@@ -23,7 +24,7 @@ export type { FileSource } from './lib/file-source.js';
23
24
  export type { LiveAuditInput, LiveAuditReport } from './live/index.js';
24
25
  export { auditLive, checkBrandFontsLive, checkBundleSizeLive, checkManifestLive, checkNoTrackingLive, checkUnsafeVhLive, } from './live/index.js';
25
26
  export type { CheckResult, CheckStatus } from './types.js';
26
- export { checkBrandFonts, checkBrandTokens, checkBundleSize, checkClaudeMdSlim, checkDarkMode, checkHtmlMeta, checkLicenseMit, checkManifest, checkNoBrandOverrides, checkNoEnvProduction, checkNoPlaceholders, checkNoScroll, checkNoTracking, checkPwaMeta, checkPwaOffline, checkStoreLink, checkUnsafeVh, checkViewportSupport, fsFileSource, isGameProject, mapFileSource, };
27
+ export { checkBrandFonts, checkBrandTokens, checkBundleSize, checkClaudeMdSlim, checkDarkMode, checkHtmlMeta, checkLicenseMit, checkManifest, checkMaskableIcon, checkNoBrandOverrides, checkNoEnvProduction, checkNoPlaceholders, checkNoScroll, checkNoTracking, checkPwaMeta, checkPwaOffline, checkStoreLink, checkUnsafeVh, checkViewportSupport, fsFileSource, isGameProject, mapFileSource, };
27
28
  /**
28
29
  * Runs every compliance check against the source. Two front doors:
29
30
  * - `runChecks(repoDir)` — CLI / CI; reads from disk.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAmB,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,YAAY,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAIvE,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,eAAe,EACf,aAAa,EACb,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,YAAY,EACZ,eAAe,EACf,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,aAAa,GACd,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAEvE;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAE3F"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAmB,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,YAAY,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAIvE,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,YAAY,EACZ,eAAe,EACf,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,aAAa,GACd,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAEvE;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAE3F"}
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ import { checkDarkMode } from './checks/dark-mode.js';
6
6
  import { checkHtmlMeta } from './checks/html-meta.js';
7
7
  import { checkLicenseMit } from './checks/license-mit.js';
8
8
  import { checkManifest } from './checks/manifest.js';
9
+ import { checkMaskableIcon } from './checks/pwa-maskable-icon.js';
9
10
  import { checkNoBrandOverrides } from './checks/no-brand-overrides.js';
10
11
  import { checkNoEnvProduction } from './checks/no-env-production.js';
11
12
  import { checkNoPlaceholders } from './checks/no-placeholders.js';
@@ -22,7 +23,7 @@ import { isGameProject } from './lib/project-type.js';
22
23
  // browser/Workers env, no filesystem). Separate export path so callers
23
24
  // don't accidentally pull node:fs in via the file-walking checks.
24
25
  export { auditLive, checkBrandFontsLive, checkBundleSizeLive, checkManifestLive, checkNoTrackingLive, checkUnsafeVhLive, } from './live/index.js';
25
- export { checkBrandFonts, checkBrandTokens, checkBundleSize, checkClaudeMdSlim, checkDarkMode, checkHtmlMeta, checkLicenseMit, checkManifest, checkNoBrandOverrides, checkNoEnvProduction, checkNoPlaceholders, checkNoScroll, checkNoTracking, checkPwaMeta, checkPwaOffline, checkStoreLink, checkUnsafeVh, checkViewportSupport, fsFileSource, isGameProject, mapFileSource, };
26
+ export { checkBrandFonts, checkBrandTokens, checkBundleSize, checkClaudeMdSlim, checkDarkMode, checkHtmlMeta, checkLicenseMit, checkManifest, checkMaskableIcon, checkNoBrandOverrides, checkNoEnvProduction, checkNoPlaceholders, checkNoScroll, checkNoTracking, checkPwaMeta, checkPwaOffline, checkStoreLink, checkUnsafeVh, checkViewportSupport, fsFileSource, isGameProject, mapFileSource, };
26
27
  /**
27
28
  * Runs every compliance check against the source. Two front doors:
28
29
  * - `runChecks(repoDir)` — CLI / CI; reads from disk.
@@ -54,6 +55,7 @@ async function runChecksOn(source) {
54
55
  checkPwaMeta(source),
55
56
  checkPwaOffline(source),
56
57
  checkManifest(source),
58
+ checkMaskableIcon(source),
57
59
  checkStoreLink(source),
58
60
  checkDarkMode(source),
59
61
  checkBundleSize(source),
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Extracts the PWA manifest object that vite-plugin-pwa embeds inline in
3
+ * `web/vite.config.ts`. The plugin call looks like:
4
+ *
5
+ * VitePWA({
6
+ * registerType: 'autoUpdate',
7
+ * manifest: {
8
+ * name: 'My Game',
9
+ * short_name: 'My Game',
10
+ * start_url: '/',
11
+ * display: 'standalone',
12
+ * ...
13
+ * },
14
+ * })
15
+ *
16
+ * We don't run a full TS parser — that would pull in ts-morph or
17
+ * @babel/parser just for one field. Instead we balance braces from the
18
+ * `manifest:` keyword and pull primitive top-level keys out of the
19
+ * resulting block with focused regexes. Robust enough for the patterns
20
+ * the games actually use; falls back to `null` on anything weird.
21
+ */
22
+ export interface InlineManifest {
23
+ name?: string | undefined;
24
+ short_name?: string | undefined;
25
+ start_url?: string | undefined;
26
+ display?: string | undefined;
27
+ orientation?: string | undefined;
28
+ min_viewport_width?: number | undefined;
29
+ icons?: unknown;
30
+ /** Literal source of the icons array, if present. Used by checks that
31
+ * need to inspect per-icon fields (e.g. maskable `purpose`). */
32
+ iconsRaw?: string | undefined;
33
+ }
34
+ export declare function extractInlineManifest(viteConfig: string): InlineManifest | null;
35
+ //# sourceMappingURL=inline-manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inline-manifest.d.ts","sourceRoot":"","sources":["../../src/lib/inline-manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;oEACgE;IAChE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/B;AAED,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAqF/E"}
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Extracts the PWA manifest object that vite-plugin-pwa embeds inline in
3
+ * `web/vite.config.ts`. The plugin call looks like:
4
+ *
5
+ * VitePWA({
6
+ * registerType: 'autoUpdate',
7
+ * manifest: {
8
+ * name: 'My Game',
9
+ * short_name: 'My Game',
10
+ * start_url: '/',
11
+ * display: 'standalone',
12
+ * ...
13
+ * },
14
+ * })
15
+ *
16
+ * We don't run a full TS parser — that would pull in ts-morph or
17
+ * @babel/parser just for one field. Instead we balance braces from the
18
+ * `manifest:` keyword and pull primitive top-level keys out of the
19
+ * resulting block with focused regexes. Robust enough for the patterns
20
+ * the games actually use; falls back to `null` on anything weird.
21
+ */
22
+ export function extractInlineManifest(viteConfig) {
23
+ const start = viteConfig.search(/\bmanifest\s*:\s*\{/);
24
+ if (start < 0)
25
+ return null;
26
+ const openIdx = viteConfig.indexOf('{', start);
27
+ if (openIdx < 0)
28
+ return null;
29
+ // Balance braces to find the end of the manifest object literal.
30
+ // Handles nested objects (icons array entries) and quoted strings
31
+ // (so a `}` inside a quoted value isn't counted).
32
+ let depth = 0;
33
+ let inSingle = false;
34
+ let inDouble = false;
35
+ let inBacktick = false;
36
+ let escaped = false;
37
+ let endIdx = -1;
38
+ for (let i = openIdx; i < viteConfig.length; i++) {
39
+ const ch = viteConfig[i];
40
+ if (escaped) {
41
+ escaped = false;
42
+ continue;
43
+ }
44
+ if (ch === '\\') {
45
+ escaped = true;
46
+ continue;
47
+ }
48
+ if (inSingle) {
49
+ if (ch === "'")
50
+ inSingle = false;
51
+ continue;
52
+ }
53
+ if (inDouble) {
54
+ if (ch === '"')
55
+ inDouble = false;
56
+ continue;
57
+ }
58
+ if (inBacktick) {
59
+ if (ch === '`')
60
+ inBacktick = false;
61
+ continue;
62
+ }
63
+ if (ch === "'") {
64
+ inSingle = true;
65
+ continue;
66
+ }
67
+ if (ch === '"') {
68
+ inDouble = true;
69
+ continue;
70
+ }
71
+ if (ch === '`') {
72
+ inBacktick = true;
73
+ continue;
74
+ }
75
+ if (ch === '{')
76
+ depth++;
77
+ else if (ch === '}') {
78
+ depth--;
79
+ if (depth === 0) {
80
+ endIdx = i;
81
+ break;
82
+ }
83
+ }
84
+ }
85
+ if (endIdx < 0)
86
+ return null;
87
+ const block = viteConfig.slice(openIdx + 1, endIdx);
88
+ const readString = (key) => {
89
+ const re = new RegExp(`(?:^|[\\s,])${key}\\s*:\\s*['"\`]([^'"\`]*)['"\`]`);
90
+ const m = block.match(re);
91
+ return m ? m[1] : undefined;
92
+ };
93
+ const readNumber = (key) => {
94
+ const re = new RegExp(`(?:^|[\\s,])${key}\\s*:\\s*(\\d+(?:\\.\\d+)?)`);
95
+ const m = block.match(re);
96
+ return m ? Number(m[1]) : undefined;
97
+ };
98
+ const hasIcons = /(?:^|[\s,])icons\s*:\s*\[/.test(block);
99
+ const iconsRaw = extractIconsArray(block);
100
+ return {
101
+ name: readString('name'),
102
+ short_name: readString('short_name'),
103
+ start_url: readString('start_url'),
104
+ display: readString('display'),
105
+ orientation: readString('orientation'),
106
+ min_viewport_width: readNumber('min_viewport_width'),
107
+ icons: hasIcons || undefined,
108
+ iconsRaw,
109
+ };
110
+ }
111
+ /** Returns the literal source of the `icons: [ ... ]` array including
112
+ * surrounding brackets, or undefined if no such array is found. Balances
113
+ * brackets and respects strings so a `]` inside a value isn't counted. */
114
+ function extractIconsArray(block) {
115
+ const m = block.match(/(?:^|[\s,])icons\s*:\s*\[/);
116
+ if (!m || m.index === undefined)
117
+ return undefined;
118
+ const openIdx = block.indexOf('[', m.index);
119
+ if (openIdx < 0)
120
+ return undefined;
121
+ let depth = 0;
122
+ let inSingle = false;
123
+ let inDouble = false;
124
+ let inBacktick = false;
125
+ let escaped = false;
126
+ for (let i = openIdx; i < block.length; i++) {
127
+ const ch = block[i];
128
+ if (escaped) {
129
+ escaped = false;
130
+ continue;
131
+ }
132
+ if (ch === '\\') {
133
+ escaped = true;
134
+ continue;
135
+ }
136
+ if (inSingle) {
137
+ if (ch === "'")
138
+ inSingle = false;
139
+ continue;
140
+ }
141
+ if (inDouble) {
142
+ if (ch === '"')
143
+ inDouble = false;
144
+ continue;
145
+ }
146
+ if (inBacktick) {
147
+ if (ch === '`')
148
+ inBacktick = false;
149
+ continue;
150
+ }
151
+ if (ch === "'") {
152
+ inSingle = true;
153
+ continue;
154
+ }
155
+ if (ch === '"') {
156
+ inDouble = true;
157
+ continue;
158
+ }
159
+ if (ch === '`') {
160
+ inBacktick = true;
161
+ continue;
162
+ }
163
+ if (ch === '[')
164
+ depth++;
165
+ else if (ch === ']') {
166
+ depth--;
167
+ if (depth === 0)
168
+ return block.slice(openIdx, i + 1);
169
+ }
170
+ }
171
+ return undefined;
172
+ }
173
+ //# sourceMappingURL=inline-manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inline-manifest.js","sourceRoot":"","sources":["../../src/lib/inline-manifest.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proappstore/compliance",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Compliance checks for apps published on proappstore.online — used by the CLI for local feedback and by CI for gating.",
5
5
  "license": "MIT",
6
6
  "type": "module",