@freeappstore/compliance 0.3.0 → 0.6.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.
Files changed (141) hide show
  1. package/dist/checks/brand-fonts.d.ts +2 -1
  2. package/dist/checks/brand-fonts.d.ts.map +1 -1
  3. package/dist/checks/brand-fonts.js +11 -7
  4. package/dist/checks/brand-fonts.js.map +1 -1
  5. package/dist/checks/brand-tokens.d.ts +22 -0
  6. package/dist/checks/brand-tokens.d.ts.map +1 -0
  7. package/dist/checks/brand-tokens.js +53 -0
  8. package/dist/checks/brand-tokens.js.map +1 -0
  9. package/dist/checks/bundle-size.d.ts +7 -1
  10. package/dist/checks/bundle-size.d.ts.map +1 -1
  11. package/dist/checks/bundle-size.js +35 -15
  12. package/dist/checks/bundle-size.js.map +1 -1
  13. package/dist/checks/claude-md-slim.d.ts +4 -0
  14. package/dist/checks/claude-md-slim.d.ts.map +1 -0
  15. package/dist/checks/claude-md-slim.js +88 -0
  16. package/dist/checks/claude-md-slim.js.map +1 -0
  17. package/dist/checks/dark-mode.d.ts +20 -0
  18. package/dist/checks/dark-mode.d.ts.map +1 -0
  19. package/dist/checks/dark-mode.js +56 -0
  20. package/dist/checks/dark-mode.js.map +1 -0
  21. package/dist/checks/html-meta.d.ts +16 -0
  22. package/dist/checks/html-meta.d.ts.map +1 -0
  23. package/dist/checks/html-meta.js +51 -0
  24. package/dist/checks/html-meta.js.map +1 -0
  25. package/dist/checks/license-mit.d.ts +13 -0
  26. package/dist/checks/license-mit.d.ts.map +1 -0
  27. package/dist/checks/license-mit.js +45 -0
  28. package/dist/checks/license-mit.js.map +1 -0
  29. package/dist/checks/manifest.d.ts +2 -1
  30. package/dist/checks/manifest.d.ts.map +1 -1
  31. package/dist/checks/manifest.js +7 -12
  32. package/dist/checks/manifest.js.map +1 -1
  33. package/dist/checks/no-brand-overrides.d.ts +2 -1
  34. package/dist/checks/no-brand-overrides.d.ts.map +1 -1
  35. package/dist/checks/no-brand-overrides.js +94 -30
  36. package/dist/checks/no-brand-overrides.js.map +1 -1
  37. package/dist/checks/no-env-production.d.ts +16 -0
  38. package/dist/checks/no-env-production.d.ts.map +1 -0
  39. package/dist/checks/no-env-production.js +37 -0
  40. package/dist/checks/no-env-production.js.map +1 -0
  41. package/dist/checks/no-placeholders.d.ts +2 -1
  42. package/dist/checks/no-placeholders.d.ts.map +1 -1
  43. package/dist/checks/no-placeholders.js +11 -9
  44. package/dist/checks/no-placeholders.js.map +1 -1
  45. package/dist/checks/no-scroll.d.ts +2 -1
  46. package/dist/checks/no-scroll.d.ts.map +1 -1
  47. package/dist/checks/no-scroll.js +13 -47
  48. package/dist/checks/no-scroll.js.map +1 -1
  49. package/dist/checks/no-tracking.d.ts +2 -1
  50. package/dist/checks/no-tracking.d.ts.map +1 -1
  51. package/dist/checks/no-tracking.js +77 -21
  52. package/dist/checks/no-tracking.js.map +1 -1
  53. package/dist/checks/pwa-meta.d.ts +19 -0
  54. package/dist/checks/pwa-meta.d.ts.map +1 -0
  55. package/dist/checks/pwa-meta.js +42 -0
  56. package/dist/checks/pwa-meta.js.map +1 -0
  57. package/dist/checks/pwa-offline.d.ts +40 -0
  58. package/dist/checks/pwa-offline.d.ts.map +1 -0
  59. package/dist/checks/pwa-offline.js +388 -0
  60. package/dist/checks/pwa-offline.js.map +1 -0
  61. package/dist/checks/store-link.d.ts +17 -0
  62. package/dist/checks/store-link.d.ts.map +1 -0
  63. package/dist/checks/store-link.js +36 -0
  64. package/dist/checks/store-link.js.map +1 -0
  65. package/dist/checks/unsafe-vh.d.ts +2 -1
  66. package/dist/checks/unsafe-vh.d.ts.map +1 -1
  67. package/dist/checks/unsafe-vh.js +25 -15
  68. package/dist/checks/unsafe-vh.js.map +1 -1
  69. package/dist/checks/viewport-support.d.ts +2 -1
  70. package/dist/checks/viewport-support.d.ts.map +1 -1
  71. package/dist/checks/viewport-support.js +13 -8
  72. package/dist/checks/viewport-support.js.map +1 -1
  73. package/dist/index.d.ts +28 -11
  74. package/dist/index.d.ts.map +1 -1
  75. package/dist/index.js +49 -19
  76. package/dist/index.js.map +1 -1
  77. package/dist/lib/file-source.d.ts +52 -0
  78. package/dist/lib/file-source.d.ts.map +1 -0
  79. package/dist/lib/file-source.js +156 -0
  80. package/dist/lib/file-source.js.map +1 -0
  81. package/dist/lib/gzip.d.ts +8 -0
  82. package/dist/lib/gzip.d.ts.map +1 -0
  83. package/dist/lib/gzip.js +26 -0
  84. package/dist/lib/gzip.js.map +1 -0
  85. package/dist/lib/project-type.d.ts +18 -0
  86. package/dist/lib/project-type.d.ts.map +1 -0
  87. package/dist/lib/project-type.js +34 -0
  88. package/dist/lib/project-type.js.map +1 -0
  89. package/dist/lib/strip.d.ts +60 -0
  90. package/dist/lib/strip.d.ts.map +1 -0
  91. package/dist/lib/strip.js +169 -0
  92. package/dist/lib/strip.js.map +1 -0
  93. package/dist/live/index.d.ts.map +1 -1
  94. package/dist/live/index.js +14 -8
  95. package/dist/live/index.js.map +1 -1
  96. package/package.json +10 -10
  97. package/LICENSE +0 -21
  98. package/dist/checks/brand-fonts.test.d.ts +0 -2
  99. package/dist/checks/brand-fonts.test.d.ts.map +0 -1
  100. package/dist/checks/brand-fonts.test.js +0 -45
  101. package/dist/checks/brand-fonts.test.js.map +0 -1
  102. package/dist/checks/bundle-size.test.d.ts +0 -2
  103. package/dist/checks/bundle-size.test.d.ts.map +0 -1
  104. package/dist/checks/bundle-size.test.js +0 -57
  105. package/dist/checks/bundle-size.test.js.map +0 -1
  106. package/dist/checks/manifest.test.d.ts +0 -2
  107. package/dist/checks/manifest.test.d.ts.map +0 -1
  108. package/dist/checks/manifest.test.js +0 -53
  109. package/dist/checks/manifest.test.js.map +0 -1
  110. package/dist/checks/no-brand-overrides.test.d.ts +0 -2
  111. package/dist/checks/no-brand-overrides.test.d.ts.map +0 -1
  112. package/dist/checks/no-brand-overrides.test.js +0 -102
  113. package/dist/checks/no-brand-overrides.test.js.map +0 -1
  114. package/dist/checks/no-placeholders.test.d.ts +0 -2
  115. package/dist/checks/no-placeholders.test.d.ts.map +0 -1
  116. package/dist/checks/no-placeholders.test.js +0 -46
  117. package/dist/checks/no-placeholders.test.js.map +0 -1
  118. package/dist/checks/no-scroll.test.d.ts +0 -2
  119. package/dist/checks/no-scroll.test.d.ts.map +0 -1
  120. package/dist/checks/no-scroll.test.js +0 -105
  121. package/dist/checks/no-scroll.test.js.map +0 -1
  122. package/dist/checks/no-tracking.test.d.ts +0 -2
  123. package/dist/checks/no-tracking.test.d.ts.map +0 -1
  124. package/dist/checks/no-tracking.test.js +0 -42
  125. package/dist/checks/no-tracking.test.js.map +0 -1
  126. package/dist/checks/unsafe-vh.test.d.ts +0 -2
  127. package/dist/checks/unsafe-vh.test.d.ts.map +0 -1
  128. package/dist/checks/unsafe-vh.test.js +0 -115
  129. package/dist/checks/unsafe-vh.test.js.map +0 -1
  130. package/dist/checks/viewport-support.test.d.ts +0 -2
  131. package/dist/checks/viewport-support.test.d.ts.map +0 -1
  132. package/dist/checks/viewport-support.test.js +0 -63
  133. package/dist/checks/viewport-support.test.js.map +0 -1
  134. package/dist/lib/walk.d.ts +0 -6
  135. package/dist/lib/walk.d.ts.map +0 -1
  136. package/dist/lib/walk.js +0 -35
  137. package/dist/lib/walk.js.map +0 -1
  138. package/dist/live/index.test.d.ts +0 -2
  139. package/dist/live/index.test.d.ts.map +0 -1
  140. package/dist/live/index.test.js +0 -259
  141. package/dist/live/index.test.js.map +0 -1
@@ -1,21 +1,16 @@
1
- import { readFile } from 'node:fs/promises';
2
- import { join } from 'node:path';
1
+ const MANIFEST_PATH = 'web/public/manifest.json';
3
2
  /**
4
3
  * Verifies the PWA manifest exists at the expected location and parses
5
4
  * to JSON. Apps without a manifest can't be "Add to Home Screen"-d on
6
5
  * mobile; required by the platform.
7
6
  */
8
- export async function checkManifest(repoDir) {
9
- const path = join(repoDir, 'web', 'public', 'manifest.json');
10
- let raw;
11
- try {
12
- raw = await readFile(path, 'utf8');
13
- }
14
- catch {
7
+ export async function checkManifest(source) {
8
+ const raw = await source.read(MANIFEST_PATH);
9
+ if (raw === null) {
15
10
  return {
16
11
  name: 'PWA manifest',
17
12
  status: 'fail',
18
- detail: 'web/public/manifest.json missing',
13
+ detail: `${MANIFEST_PATH} missing`,
19
14
  suggestions: [
20
15
  'Add a manifest.json with at least name, short_name, start_url, display, icons.',
21
16
  'See template-standalone for a working example.',
@@ -30,7 +25,7 @@ export async function checkManifest(repoDir) {
30
25
  return {
31
26
  name: 'PWA manifest',
32
27
  status: 'fail',
33
- detail: `web/public/manifest.json is not valid JSON`,
28
+ detail: `${MANIFEST_PATH} is not valid JSON`,
34
29
  };
35
30
  }
36
31
  const required = ['name', 'short_name', 'start_url', 'display'];
@@ -43,6 +38,6 @@ export async function checkManifest(repoDir) {
43
38
  suggestions: [`Add the ${missing.join(', ')} field(s) to manifest.json so installs work.`],
44
39
  };
45
40
  }
46
- return { name: 'PWA manifest', status: 'pass', detail: 'web/public/manifest.json' };
41
+ return { name: 'PWA manifest', status: 'pass', detail: MANIFEST_PATH };
47
42
  }
48
43
  //# sourceMappingURL=manifest.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/checks/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAe;IACjD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;IAC7D,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,IAAI,EAAE,cAAc;YACpB,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,kCAAkC;YAC1C,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,4CAA4C;SACrD,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,0BAA0B,EAAE,CAAC;AACtF,CAAC"}
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,3 +1,4 @@
1
+ import type { FileSource } from '../lib/file-source.js';
1
2
  import type { CheckResult } from '../types.js';
2
3
  /**
3
4
  * Apps and games on the platform must look consistent with the storefront
@@ -17,7 +18,7 @@ import type { CheckResult } from '../types.js';
17
18
  * red, etc.). We don't try to gate every hex literal — too noisy and
18
19
  * too many false positives.
19
20
  */
20
- export declare function checkNoBrandOverrides(repoDir: string): Promise<CheckResult>;
21
+ export declare function checkNoBrandOverrides(source: FileSource): Promise<CheckResult>;
21
22
  export declare function scanContent(filename: string, content: string, opts?: {
22
23
  skipVarRedefs?: boolean;
23
24
  }): string[];
@@ -1 +1 @@
1
- {"version":3,"file":"no-brand-overrides.d.ts","sourceRoot":"","sources":["../../src/checks/no-brand-overrides.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAwCjF;AA2DD,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAO,GACrC,MAAM,EAAE,CAyCV"}
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,6 +1,4 @@
1
- import { readFile } from 'node:fs/promises';
2
- import { extname, relative } from 'node:path';
3
- import { walk } from '../lib/walk.js';
1
+ import { stripCommentsOnly, stripCssComments } from '../lib/strip.js';
4
2
  /**
5
3
  * Apps and games on the platform must look consistent with the storefront
6
4
  * and with each other — brand colors, fonts, and layout rhythm come from
@@ -19,23 +17,30 @@ import { walk } from '../lib/walk.js';
19
17
  * red, etc.). We don't try to gate every hex literal — too noisy and
20
18
  * too many false positives.
21
19
  */
22
- export async function checkNoBrandOverrides(repoDir) {
20
+ export async function checkNoBrandOverrides(source) {
23
21
  const issues = [];
24
- for await (const file of walk(repoDir)) {
25
- const ext = extname(file).toLowerCase();
22
+ for await (const path of source.list()) {
23
+ const ext = extOf(path);
26
24
  if (!SCANNED_EXTS.has(ext))
27
25
  continue;
28
- const content = await readFile(file, 'utf8').catch(() => '');
29
- if (!content)
26
+ const raw = await source.read(path);
27
+ if (!raw)
30
28
  continue;
31
- const rel = relative(repoDir, file);
29
+ // Strip comment bodies so a `// font-family: "Comic Sans"` note
30
+ // doesn't fire. Preserve string-literal contents — the JSX value
31
+ // `fontFamily: "Comic Sans"` IS a string literal and is the thing
32
+ // we're auditing. For .css/.scss use the css-only stripper (no `//`
33
+ // syntax at the language level).
34
+ const content = ext === '.css' || ext === '.scss'
35
+ ? stripCssComments(raw)
36
+ : stripCommentsOnly(raw);
32
37
  // Canonical theme file: the platform's CSS variables ARE defined here.
33
38
  // Apps own this file post-scaffold (they can technically modify token
34
39
  // values, and we accept the imperfection — the loud places where a
35
40
  // brand override actually causes inconsistency are inline styles +
36
41
  // per-component CSS, which this check still covers).
37
- const isThemeFile = rel === 'web/src/index.css' || rel === 'web/src/main.css';
38
- const fileIssues = scanContent(rel, content, { skipVarRedefs: isThemeFile });
42
+ const isThemeFile = path === 'web/src/index.css' || path === 'web/src/main.css';
43
+ const fileIssues = scanContent(path, content, { skipVarRedefs: isThemeFile });
39
44
  issues.push(...fileIssues);
40
45
  // Cap at 10 — beyond that the user has bigger problems and we don't
41
46
  // want a 200-line failure report.
@@ -118,10 +123,6 @@ const ALLOWED_FONT_TOKENS = new Set([
118
123
  export function scanContent(filename, content, opts = {}) {
119
124
  const out = [];
120
125
  // 1. CSS variable overrides for protected tokens.
121
- // Match `--accent: <something>;` outside of var() invocations.
122
- // The regex looks for "<two dashes><name>:" near the start of a line,
123
- // which is how CSS declarations look. var(--accent) won't match because
124
- // there's a `(` not a `:`.
125
126
  if (!opts.skipVarRedefs) {
126
127
  const varDeclRe = /(?:^|[\s;{,])(--[a-z-]+)\s*:/gim;
127
128
  let m;
@@ -133,27 +134,90 @@ export function scanContent(filename, content, opts = {}) {
133
134
  }
134
135
  }
135
136
  }
136
- // 2. font-family overrides. Pull every string after `font-family:` (in
137
- // CSS) or `fontFamily:` (in JSX/TS), parse the comma-separated list,
138
- // and flag any quoted token not in ALLOWED_FONT_TOKENS.
139
- const fontRe = /(?:font-family|fontFamily)\s*[:=]\s*["'`]?([^;"'`}\n]+)["'`]?/g;
137
+ // 2. font-family overrides.
138
+ // Capture the value of every font-family / fontFamily declaration, then
139
+ // extract candidate font names. JSX values can be ternaries
140
+ // (`fontFamily: isFoo ? "Fraunces" : "Manrope"`), so we pull out every
141
+ // quoted string in the value and check each one separately. If there are
142
+ // no quoted strings, the value is treated as a CSS-style comma list
143
+ // (`font-family: Comic Sans, serif`).
144
+ const fontHeadRe = /(font-family|fontFamily)\s*[:=]/g;
145
+ const quotedRe = /(['"`])([^'"`\n]+)\1/g;
140
146
  let m;
141
- while ((m = fontRe.exec(content)) !== null) {
142
- const list = m[1];
143
- const tokens = list
144
- .split(',')
145
- .map((t) => t.trim().replace(/^["']|["']$/g, '').toLowerCase())
146
- .filter(Boolean);
147
- for (const t of tokens) {
148
- if (!ALLOWED_FONT_TOKENS.has(t)) {
149
- const line = lineNumberAt(content, m.index);
150
- out.push(`${filename}:${line} non-brand font "${t}"`);
151
- break; // one warning per declaration is plenty
147
+ while ((m = fontHeadRe.exec(content)) !== null) {
148
+ const isJsx = m[1] === 'fontFamily';
149
+ const start = m.index + m[0].length;
150
+ const value = sliceFontValue(content, start, isJsx);
151
+ const quotedStrings = [...value.matchAll(quotedRe)].map((x) => x[2]);
152
+ const candidates = quotedStrings.length > 0 ? quotedStrings : [value];
153
+ let flagged = false;
154
+ for (const cand of candidates) {
155
+ const tokens = cand
156
+ .split(',')
157
+ .map((t) => t.trim().replace(/^["']|["']$/g, '').toLowerCase())
158
+ .filter(Boolean);
159
+ for (const t of tokens) {
160
+ if (!ALLOWED_FONT_TOKENS.has(t)) {
161
+ const line = lineNumberAt(content, m.index);
162
+ out.push(`${filename}:${line} non-brand font "${t}"`);
163
+ flagged = true;
164
+ break;
165
+ }
152
166
  }
167
+ if (flagged)
168
+ break;
153
169
  }
154
170
  }
155
171
  return out;
156
172
  }
173
+ /**
174
+ * Walk forward from `start` until we hit the end of the font-family value.
175
+ *
176
+ * CSS values end at `;` or `}` or newline.
177
+ * JSX values end at `}` or at a `,` followed by another identifier+colon
178
+ * (the next style property). Commas inside quoted strings or before
179
+ * non-identifiers (e.g. font fallbacks) are part of the value.
180
+ */
181
+ function sliceFontValue(content, start, isJsx) {
182
+ let i = start;
183
+ let quote = null;
184
+ while (i < content.length) {
185
+ const c = content[i];
186
+ if (quote) {
187
+ if (c === '\\') {
188
+ i += 2;
189
+ continue;
190
+ }
191
+ if (c === quote)
192
+ quote = null;
193
+ i++;
194
+ continue;
195
+ }
196
+ if (c === '"' || c === "'" || c === '`') {
197
+ quote = c;
198
+ i++;
199
+ continue;
200
+ }
201
+ if (c === '\n' || c === ';' || c === '}')
202
+ break;
203
+ if (isJsx && c === ',') {
204
+ // Lookahead: is this `,` followed by `identifier:`? If yes, end of value.
205
+ let j = i + 1;
206
+ while (j < content.length && (content[j] === ' ' || content[j] === '\t'))
207
+ j++;
208
+ const rest = content.slice(j, j + 64);
209
+ if (/^[A-Za-z_$][\w$]*\s*:/.test(rest))
210
+ break;
211
+ }
212
+ i++;
213
+ }
214
+ return content.slice(start, i);
215
+ }
216
+ function extOf(path) {
217
+ const dot = path.lastIndexOf('.');
218
+ const slash = path.lastIndexOf('/');
219
+ return dot > slash ? path.slice(dot).toLowerCase() : '';
220
+ }
157
221
  function lineNumberAt(content, index) {
158
222
  let n = 1;
159
223
  for (let i = 0; i < index; i++)
@@ -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,16 @@
1
+ import type { FileSource } from '../lib/file-source.js';
2
+ import type { CheckResult } from '../types.js';
3
+ /**
4
+ * `.env.production` is a frequent accidental commit — Vite reads it at
5
+ * build time, and it's the file most likely to contain real API keys
6
+ * for the production deploy. The platform's templates instruct creators
7
+ * to use Cloudflare Pages env vars or Wrangler secrets instead. This
8
+ * check is a safety net: even if the creator's gitignore misses it, we
9
+ * fail compliance before publish.
10
+ *
11
+ * Scope: any `.env.production` file anywhere in the repo. We don't try
12
+ * to differentiate "this one's empty" from "this one has secrets" —
13
+ * the file shouldn't exist at all.
14
+ */
15
+ export declare function checkNoEnvProduction(source: FileSource): Promise<CheckResult>;
16
+ //# sourceMappingURL=no-env-production.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-env-production.d.ts","sourceRoot":"","sources":["../../src/checks/no-env-production.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;;;;;;GAWG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAsBnF"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * `.env.production` is a frequent accidental commit — Vite reads it at
3
+ * build time, and it's the file most likely to contain real API keys
4
+ * for the production deploy. The platform's templates instruct creators
5
+ * to use Cloudflare Pages env vars or Wrangler secrets instead. This
6
+ * check is a safety net: even if the creator's gitignore misses it, we
7
+ * fail compliance before publish.
8
+ *
9
+ * Scope: any `.env.production` file anywhere in the repo. We don't try
10
+ * to differentiate "this one's empty" from "this one has secrets" —
11
+ * the file shouldn't exist at all.
12
+ */
13
+ export async function checkNoEnvProduction(source) {
14
+ const offenders = [];
15
+ for await (const path of source.list()) {
16
+ const base = path.split('/').pop() ?? '';
17
+ if (base === '.env.production')
18
+ offenders.push(path);
19
+ }
20
+ if (offenders.length === 0) {
21
+ return {
22
+ name: 'No .env.production',
23
+ status: 'pass',
24
+ detail: 'no production env files committed',
25
+ };
26
+ }
27
+ return {
28
+ name: 'No .env.production',
29
+ status: 'fail',
30
+ detail: `${offenders.length} .env.production file(s): ${offenders.join(', ')}`,
31
+ suggestions: [
32
+ 'Delete the file and add `.env.production` to .gitignore.',
33
+ 'Use Cloudflare Pages → Settings → Environment Variables for production secrets instead.',
34
+ ],
35
+ };
36
+ }
37
+ //# sourceMappingURL=no-env-production.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-env-production.js","sourceRoot":"","sources":["../../src/checks/no-env-production.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,MAAkB;IAC3D,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACvC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;QACzC,IAAI,IAAI,KAAK,iBAAiB;YAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvD,CAAC;IACD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO;YACL,IAAI,EAAE,oBAAoB;YAC1B,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,mCAAmC;SAC5C,CAAC;IACJ,CAAC;IACD,OAAO;QACL,IAAI,EAAE,oBAAoB;QAC1B,MAAM,EAAE,MAAM;QACd,MAAM,EAAE,GAAG,SAAS,CAAC,MAAM,6BAA6B,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QAC9E,WAAW,EAAE;YACX,0DAA0D;YAC1D,yFAAyF;SAC1F;KACF,CAAC;AACJ,CAAC"}
@@ -1,3 +1,4 @@
1
+ import type { FileSource } from '../lib/file-source.js';
1
2
  import type { CheckResult } from '../types.js';
2
3
  /**
3
4
  * Catches the case where APPNAME placeholders from the template were
@@ -5,5 +6,5 @@ import type { CheckResult } from '../types.js';
5
6
  * but if someone clones the template manually and forgets the find/
6
7
  * replace step, every page renders with `<title>APPNAME — …</title>`.
7
8
  */
8
- export declare function checkNoPlaceholders(repoDir: string): Promise<CheckResult>;
9
+ export declare function checkNoPlaceholders(source: FileSource): Promise<CheckResult>;
9
10
  //# sourceMappingURL=no-placeholders.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"no-placeholders.d.ts","sourceRoot":"","sources":["../../src/checks/no-placeholders.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAqB/C;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAsB/E"}
1
+ {"version":3,"file":"no-placeholders.d.ts","sourceRoot":"","sources":["../../src/checks/no-placeholders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAoB/C;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAsBlF"}
@@ -1,6 +1,3 @@
1
- import { readFile } from 'node:fs/promises';
2
- import { extname } from 'node:path';
3
- import { walk } from '../lib/walk.js';
4
1
  const TEXT_EXTS = new Set([
5
2
  '.md',
6
3
  '.txt',
@@ -24,14 +21,14 @@ const TEXT_EXTS = new Set([
24
21
  * but if someone clones the template manually and forgets the find/
25
22
  * replace step, every page renders with `<title>APPNAME — …</title>`.
26
23
  */
27
- export async function checkNoPlaceholders(repoDir) {
24
+ export async function checkNoPlaceholders(source) {
28
25
  const offenders = [];
29
- for await (const file of walk(repoDir)) {
30
- if (!TEXT_EXTS.has(extname(file).toLowerCase()))
26
+ for await (const path of source.list()) {
27
+ if (!TEXT_EXTS.has(extOf(path)))
31
28
  continue;
32
- const content = await readFile(file, 'utf8').catch(() => '');
33
- if (content.includes('APPNAME')) {
34
- offenders.push(file.replace(repoDir + '/', ''));
29
+ const content = await source.read(path);
30
+ if (content?.includes('APPNAME')) {
31
+ offenders.push(path);
35
32
  if (offenders.length >= 5)
36
33
  break; // don't spam, summarize
37
34
  }
@@ -49,4 +46,9 @@ export async function checkNoPlaceholders(repoDir) {
49
46
  ],
50
47
  };
51
48
  }
49
+ function extOf(path) {
50
+ const dot = path.lastIndexOf('.');
51
+ const slash = path.lastIndexOf('/');
52
+ return dot > slash ? path.slice(dot).toLowerCase() : '';
53
+ }
52
54
  //# sourceMappingURL=no-placeholders.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"no-placeholders.js","sourceRoot":"","sources":["../../src/checks/no-placeholders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEtC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC;IACxB,KAAK;IACL,MAAM;IACN,OAAO;IACP,KAAK;IACL,MAAM;IACN,KAAK;IACL,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,OAAO;IACP,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;CACP,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAe;IACvD,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACvC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;YAAE,SAAS;QAC1D,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAC7D,IAAI,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YAChC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;YAChD,IAAI,SAAS,CAAC,MAAM,IAAI,CAAC;gBAAE,MAAM,CAAC,wBAAwB;QAC5D,CAAC;IACH,CAAC;IACD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,IAAI,EAAE,0BAA0B,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC;IACjG,CAAC;IACD,OAAO;QACL,IAAI,EAAE,0BAA0B;QAChC,MAAM,EAAE,MAAM;QACd,MAAM,EAAE,GAAG,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,mCAAmC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACpH,WAAW,EAAE;YACX,0FAA0F;YAC1F,mFAAmF;SACpF;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"no-placeholders.js","sourceRoot":"","sources":["../../src/checks/no-placeholders.ts"],"names":[],"mappings":"AAGA,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC;IACxB,KAAK;IACL,MAAM;IACN,OAAO;IACP,KAAK;IACL,MAAM;IACN,KAAK;IACL,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,OAAO;IACP,OAAO;IACP,MAAM;IACN,OAAO;IACP,MAAM;CACP,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,MAAkB;IAC1D,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACvC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAAE,SAAS;QAC1C,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,OAAO,EAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACjC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrB,IAAI,SAAS,CAAC,MAAM,IAAI,CAAC;gBAAE,MAAM,CAAC,wBAAwB;QAC5D,CAAC;IACH,CAAC;IACD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,IAAI,EAAE,0BAA0B,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC;IACjG,CAAC;IACD,OAAO;QACL,IAAI,EAAE,0BAA0B;QAChC,MAAM,EAAE,MAAM;QACd,MAAM,EAAE,GAAG,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,mCAAmC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACpH,WAAW,EAAE;YACX,0FAA0F;YAC1F,mFAAmF;SACpF;KACF,CAAC;AACJ,CAAC;AAED,SAAS,KAAK,CAAC,IAAY;IACzB,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACpC,OAAO,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAC1D,CAAC"}
@@ -1,3 +1,4 @@
1
+ import type { FileSource } from '../lib/file-source.js';
1
2
  import type { CheckResult } from '../types.js';
2
3
  /**
3
4
  * Games on FreeGameStore must fit the viewport — no horizontal or
@@ -20,5 +21,5 @@ import type { CheckResult } from '../types.js';
20
21
  * detect "is this a game project" by looking for the @freeappstore/games
21
22
  * dep, the canonical signal that the app uses GameShell.
22
23
  */
23
- export declare function checkNoScroll(repoDir: string): Promise<CheckResult>;
24
+ export declare function checkNoScroll(source: FileSource): Promise<CheckResult>;
24
25
  //# sourceMappingURL=no-scroll.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"no-scroll.d.ts","sourceRoot":"","sources":["../../src/checks/no-scroll.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA6EzE"}
1
+ {"version":3,"file":"no-scroll.d.ts","sourceRoot":"","sources":["../../src/checks/no-scroll.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAuE5E"}
@@ -1,6 +1,4 @@
1
- import { readFile } from 'node:fs/promises';
2
- import { extname, relative } from 'node:path';
3
- import { walk } from '../lib/walk.js';
1
+ import { isGameProject } from '../lib/project-type.js';
4
2
  /**
5
3
  * Games on FreeGameStore must fit the viewport — no horizontal or
6
4
  * vertical scroll at the document level. Static analysis catches the
@@ -22,9 +20,9 @@ import { walk } from '../lib/walk.js';
22
20
  * detect "is this a game project" by looking for the @freeappstore/games
23
21
  * dep, the canonical signal that the app uses GameShell.
24
22
  */
25
- export async function checkNoScroll(repoDir) {
23
+ export async function checkNoScroll(source) {
26
24
  // Skip apps — only games are subject to no-scroll.
27
- if (!(await isGame(repoDir))) {
25
+ if (!(await isGameProject(source))) {
28
26
  return {
29
27
  name: 'No scroll (games only)',
30
28
  status: 'pass',
@@ -33,33 +31,27 @@ export async function checkNoScroll(repoDir) {
33
31
  }
34
32
  const issues = [];
35
33
  let sawViewportLock = false;
36
- for await (const file of walk(repoDir)) {
37
- const ext = extname(file).toLowerCase();
34
+ for await (const path of source.list()) {
35
+ const ext = extOf(path);
38
36
  if (!SCAN_EXTS.has(ext))
39
37
  continue;
40
- const content = await readFile(file, 'utf8').catch(() => '');
38
+ const content = await source.read(path);
41
39
  if (!content)
42
40
  continue;
43
- const rel = relative(repoDir, file);
44
- // 1. Forbidden overflow declarations on root elements.
45
41
  for (const re of FORBIDDEN_OVERFLOW) {
46
42
  const m = re.exec(content);
47
43
  if (m) {
48
44
  const line = lineNumberAt(content, m.index);
49
- issues.push(`${rel}:${line} ${m[0]} — root scrolling not allowed in games`);
45
+ issues.push(`${path}:${line} ${m[0]} — root scrolling not allowed in games`);
50
46
  }
51
47
  }
52
- // 2. min-height on root elements (creates pages taller than viewport).
53
48
  for (const re of FORBIDDEN_MIN_HEIGHT) {
54
49
  const m = re.exec(content);
55
50
  if (m) {
56
51
  const line = lineNumberAt(content, m.index);
57
- issues.push(`${rel}:${line} ${m[0]} — use exact viewport height (100svh) instead`);
52
+ issues.push(`${path}:${line} ${m[0]} — use exact viewport height (100svh) instead`);
58
53
  }
59
54
  }
60
- // 3. Look for at least one viewport-lock pattern. GameShell sets
61
- // `height: 100svh` on a fixed wrapper; we accept any 100svh / 100vh
62
- // declaration as evidence the game considered viewport sizing.
63
55
  if (VIEWPORT_LOCK.test(content))
64
56
  sawViewportLock = true;
65
57
  if (issues.length >= 8)
@@ -96,42 +88,16 @@ export async function checkNoScroll(repoDir) {
96
88
  };
97
89
  }
98
90
  const SCAN_EXTS = new Set(['.css', '.scss', '.tsx', '.ts', '.jsx', '.js', '.html']);
99
- // Match `overflow: scroll` and `overflow: auto` on html/body selectors,
100
- // or as bare global rules in CSS. Conservative: only flags when paired
101
- // with html/body — avoids false positives for component-scoped overflow.
102
- //
103
- // IMPORTANT: no `g` flag. Module-scoped regexes with `g` share lastIndex
104
- // across parallel test runs and produce flaky matches; we only need
105
- // first-match-per-file anyway.
106
91
  const FORBIDDEN_OVERFLOW = [
107
92
  /(?:^|[\s,{])(?:html|body)\s*\{[^}]*overflow\s*:\s*(?:scroll|auto)/im,
108
93
  /(?:^|[\s,{])(?:html|body)\s*\{[^}]*overflow-(?:x|y)\s*:\s*(?:scroll|auto)/im,
109
94
  ];
110
- const FORBIDDEN_MIN_HEIGHT = [
111
- /(?:^|[\s,{])(?:html|body)\s*\{[^}]*min-height\s*:\s*100vh/im,
112
- ];
95
+ const FORBIDDEN_MIN_HEIGHT = [/(?:^|[\s,{])(?:html|body)\s*\{[^}]*min-height\s*:\s*100vh/im];
113
96
  const VIEWPORT_LOCK = /(?:height|max-height)\s*:\s*100(?:s?vh)|GameShell|@freeappstore\/games/i;
114
- async function isGame(repoDir) {
115
- // Fast path: look for the explicit games-sdk dep in any package.json.
116
- // Falls back to scanning JSX for GameShell import — catches cases
117
- // where the dep is hoisted to a workspace root.
118
- for await (const file of walk(repoDir)) {
119
- const base = file.split('/').pop() ?? '';
120
- if (base !== 'package.json')
121
- continue;
122
- const content = await readFile(file, 'utf8').catch(() => '');
123
- if (/@freeappstore\/games/.test(content))
124
- return true;
125
- }
126
- for await (const file of walk(repoDir)) {
127
- const ext = extname(file).toLowerCase();
128
- if (ext !== '.tsx' && ext !== '.ts')
129
- continue;
130
- const content = await readFile(file, 'utf8').catch(() => '');
131
- if (/from\s+['"]@freeappstore\/games['"]/.test(content))
132
- return true;
133
- }
134
- return false;
97
+ function extOf(path) {
98
+ const dot = path.lastIndexOf('.');
99
+ const slash = path.lastIndexOf('/');
100
+ return dot > slash ? path.slice(dot).toLowerCase() : '';
135
101
  }
136
102
  function lineNumberAt(content, index) {
137
103
  let n = 1;
@@ -1 +1 @@
1
- {"version":3,"file":"no-scroll.js","sourceRoot":"","sources":["../../src/checks/no-scroll.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"no-scroll.js","sourceRoot":"","sources":["../../src/checks/no-scroll.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { FileSource } from '../lib/file-source.js';
1
2
  import type { CheckResult } from '../types.js';
2
- export declare function checkNoTracking(repoDir: string): Promise<CheckResult>;
3
+ export declare function checkNoTracking(source: FileSource): Promise<CheckResult>;
3
4
  //# sourceMappingURL=no-tracking.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"no-tracking.d.ts","sourceRoot":"","sources":["../../src/checks/no-tracking.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAkB/C,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAgC3E"}
1
+ {"version":3,"file":"no-tracking.d.ts","sourceRoot":"","sources":["../../src/checks/no-tracking.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAuE/C,wBAAsB,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CA6C9E"}