@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.
- package/dist/checks/brand-fonts.d.ts +2 -1
- package/dist/checks/brand-fonts.d.ts.map +1 -1
- package/dist/checks/brand-fonts.js +11 -7
- package/dist/checks/brand-fonts.js.map +1 -1
- package/dist/checks/brand-tokens.d.ts +22 -0
- package/dist/checks/brand-tokens.d.ts.map +1 -0
- package/dist/checks/brand-tokens.js +53 -0
- package/dist/checks/brand-tokens.js.map +1 -0
- package/dist/checks/bundle-size.d.ts +7 -1
- package/dist/checks/bundle-size.d.ts.map +1 -1
- package/dist/checks/bundle-size.js +35 -15
- package/dist/checks/bundle-size.js.map +1 -1
- package/dist/checks/claude-md-slim.d.ts +4 -0
- package/dist/checks/claude-md-slim.d.ts.map +1 -0
- package/dist/checks/claude-md-slim.js +88 -0
- package/dist/checks/claude-md-slim.js.map +1 -0
- package/dist/checks/dark-mode.d.ts +20 -0
- package/dist/checks/dark-mode.d.ts.map +1 -0
- package/dist/checks/dark-mode.js +56 -0
- package/dist/checks/dark-mode.js.map +1 -0
- package/dist/checks/html-meta.d.ts +16 -0
- package/dist/checks/html-meta.d.ts.map +1 -0
- package/dist/checks/html-meta.js +51 -0
- package/dist/checks/html-meta.js.map +1 -0
- package/dist/checks/license-mit.d.ts +13 -0
- package/dist/checks/license-mit.d.ts.map +1 -0
- package/dist/checks/license-mit.js +45 -0
- package/dist/checks/license-mit.js.map +1 -0
- package/dist/checks/manifest.d.ts +2 -1
- package/dist/checks/manifest.d.ts.map +1 -1
- package/dist/checks/manifest.js +7 -12
- package/dist/checks/manifest.js.map +1 -1
- package/dist/checks/no-brand-overrides.d.ts +2 -1
- package/dist/checks/no-brand-overrides.d.ts.map +1 -1
- package/dist/checks/no-brand-overrides.js +94 -30
- package/dist/checks/no-brand-overrides.js.map +1 -1
- package/dist/checks/no-env-production.d.ts +16 -0
- package/dist/checks/no-env-production.d.ts.map +1 -0
- package/dist/checks/no-env-production.js +37 -0
- package/dist/checks/no-env-production.js.map +1 -0
- package/dist/checks/no-placeholders.d.ts +2 -1
- package/dist/checks/no-placeholders.d.ts.map +1 -1
- package/dist/checks/no-placeholders.js +11 -9
- package/dist/checks/no-placeholders.js.map +1 -1
- package/dist/checks/no-scroll.d.ts +2 -1
- package/dist/checks/no-scroll.d.ts.map +1 -1
- package/dist/checks/no-scroll.js +13 -47
- package/dist/checks/no-scroll.js.map +1 -1
- package/dist/checks/no-tracking.d.ts +2 -1
- package/dist/checks/no-tracking.d.ts.map +1 -1
- package/dist/checks/no-tracking.js +77 -21
- package/dist/checks/no-tracking.js.map +1 -1
- package/dist/checks/pwa-meta.d.ts +19 -0
- package/dist/checks/pwa-meta.d.ts.map +1 -0
- package/dist/checks/pwa-meta.js +42 -0
- package/dist/checks/pwa-meta.js.map +1 -0
- package/dist/checks/pwa-offline.d.ts +40 -0
- package/dist/checks/pwa-offline.d.ts.map +1 -0
- package/dist/checks/pwa-offline.js +388 -0
- package/dist/checks/pwa-offline.js.map +1 -0
- package/dist/checks/store-link.d.ts +17 -0
- package/dist/checks/store-link.d.ts.map +1 -0
- package/dist/checks/store-link.js +36 -0
- package/dist/checks/store-link.js.map +1 -0
- package/dist/checks/unsafe-vh.d.ts +2 -1
- package/dist/checks/unsafe-vh.d.ts.map +1 -1
- package/dist/checks/unsafe-vh.js +25 -15
- package/dist/checks/unsafe-vh.js.map +1 -1
- package/dist/checks/viewport-support.d.ts +2 -1
- package/dist/checks/viewport-support.d.ts.map +1 -1
- package/dist/checks/viewport-support.js +13 -8
- package/dist/checks/viewport-support.js.map +1 -1
- package/dist/index.d.ts +28 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +49 -19
- package/dist/index.js.map +1 -1
- package/dist/lib/file-source.d.ts +52 -0
- package/dist/lib/file-source.d.ts.map +1 -0
- package/dist/lib/file-source.js +156 -0
- package/dist/lib/file-source.js.map +1 -0
- package/dist/lib/gzip.d.ts +8 -0
- package/dist/lib/gzip.d.ts.map +1 -0
- package/dist/lib/gzip.js +26 -0
- package/dist/lib/gzip.js.map +1 -0
- package/dist/lib/project-type.d.ts +18 -0
- package/dist/lib/project-type.d.ts.map +1 -0
- package/dist/lib/project-type.js +34 -0
- package/dist/lib/project-type.js.map +1 -0
- package/dist/lib/strip.d.ts +60 -0
- package/dist/lib/strip.d.ts.map +1 -0
- package/dist/lib/strip.js +169 -0
- package/dist/lib/strip.js.map +1 -0
- package/dist/live/index.d.ts.map +1 -1
- package/dist/live/index.js +14 -8
- package/dist/live/index.js.map +1 -1
- package/package.json +10 -10
- package/LICENSE +0 -21
- package/dist/checks/brand-fonts.test.d.ts +0 -2
- package/dist/checks/brand-fonts.test.d.ts.map +0 -1
- package/dist/checks/brand-fonts.test.js +0 -45
- package/dist/checks/brand-fonts.test.js.map +0 -1
- package/dist/checks/bundle-size.test.d.ts +0 -2
- package/dist/checks/bundle-size.test.d.ts.map +0 -1
- package/dist/checks/bundle-size.test.js +0 -57
- package/dist/checks/bundle-size.test.js.map +0 -1
- package/dist/checks/manifest.test.d.ts +0 -2
- package/dist/checks/manifest.test.d.ts.map +0 -1
- package/dist/checks/manifest.test.js +0 -53
- package/dist/checks/manifest.test.js.map +0 -1
- package/dist/checks/no-brand-overrides.test.d.ts +0 -2
- package/dist/checks/no-brand-overrides.test.d.ts.map +0 -1
- package/dist/checks/no-brand-overrides.test.js +0 -102
- package/dist/checks/no-brand-overrides.test.js.map +0 -1
- package/dist/checks/no-placeholders.test.d.ts +0 -2
- package/dist/checks/no-placeholders.test.d.ts.map +0 -1
- package/dist/checks/no-placeholders.test.js +0 -46
- package/dist/checks/no-placeholders.test.js.map +0 -1
- package/dist/checks/no-scroll.test.d.ts +0 -2
- package/dist/checks/no-scroll.test.d.ts.map +0 -1
- package/dist/checks/no-scroll.test.js +0 -105
- package/dist/checks/no-scroll.test.js.map +0 -1
- package/dist/checks/no-tracking.test.d.ts +0 -2
- package/dist/checks/no-tracking.test.d.ts.map +0 -1
- package/dist/checks/no-tracking.test.js +0 -42
- package/dist/checks/no-tracking.test.js.map +0 -1
- package/dist/checks/unsafe-vh.test.d.ts +0 -2
- package/dist/checks/unsafe-vh.test.d.ts.map +0 -1
- package/dist/checks/unsafe-vh.test.js +0 -115
- package/dist/checks/unsafe-vh.test.js.map +0 -1
- package/dist/checks/viewport-support.test.d.ts +0 -2
- package/dist/checks/viewport-support.test.d.ts.map +0 -1
- package/dist/checks/viewport-support.test.js +0 -63
- package/dist/checks/viewport-support.test.js.map +0 -1
- package/dist/lib/walk.d.ts +0 -6
- package/dist/lib/walk.d.ts.map +0 -1
- package/dist/lib/walk.js +0 -35
- package/dist/lib/walk.js.map +0 -1
- package/dist/live/index.test.d.ts +0 -2
- package/dist/live/index.test.d.ts.map +0 -1
- package/dist/live/index.test.js +0 -259
- package/dist/live/index.test.js.map +0 -1
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filesystem-agnostic file access for compliance checks.
|
|
3
|
+
*
|
|
4
|
+
* Why: the CLI scans a real directory on disk; the VibeCode agent runs
|
|
5
|
+
* in a Cloudflare Worker (no node:fs) and holds files in a Map. Both
|
|
6
|
+
* call the same checks via this interface so rules stay in one place.
|
|
7
|
+
*
|
|
8
|
+
* Conventions:
|
|
9
|
+
* - Paths are POSIX-style and relative to the repo root
|
|
10
|
+
* (e.g. `web/src/App.tsx`).
|
|
11
|
+
* - `read` returns null for missing files — checks decide whether
|
|
12
|
+
* missing == fail or missing == not-applicable.
|
|
13
|
+
* - `list()` already excludes noise dirs (.git, node_modules, dist,
|
|
14
|
+
* etc.). Implementations are responsible for that filtering.
|
|
15
|
+
*/
|
|
16
|
+
import { readdir, readFile } from 'node:fs/promises';
|
|
17
|
+
import { join, relative, sep } from 'node:path';
|
|
18
|
+
const SKIP_DIRS = new Set([
|
|
19
|
+
'.git',
|
|
20
|
+
'node_modules',
|
|
21
|
+
'dist',
|
|
22
|
+
'.next',
|
|
23
|
+
'.cache',
|
|
24
|
+
'.wrangler',
|
|
25
|
+
'.turbo',
|
|
26
|
+
]);
|
|
27
|
+
/**
|
|
28
|
+
* Filesystem-backed FileSource — used by the CLI and CI. Walks the
|
|
29
|
+
* directory tree once on first list() iteration; uses node:fs for
|
|
30
|
+
* read/readBytes/listDir.
|
|
31
|
+
*
|
|
32
|
+
* Paths containing `..` segments are rejected — every read returns
|
|
33
|
+
* null. Defense in depth: today's checks only pass paths that came
|
|
34
|
+
* from `list()` (which stays inside the root), but a future buggy or
|
|
35
|
+
* malicious check could try `source.read('../etc/passwd')`. We refuse
|
|
36
|
+
* rather than letting `path.join` resolve outside repoDir.
|
|
37
|
+
*/
|
|
38
|
+
export function fsFileSource(repoDir) {
|
|
39
|
+
return {
|
|
40
|
+
async *list() {
|
|
41
|
+
yield* walk(repoDir, repoDir);
|
|
42
|
+
},
|
|
43
|
+
async read(path) {
|
|
44
|
+
if (hasTraversal(path))
|
|
45
|
+
return null;
|
|
46
|
+
try {
|
|
47
|
+
return await readFile(join(repoDir, path), 'utf8');
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
async readBytes(path) {
|
|
54
|
+
if (hasTraversal(path))
|
|
55
|
+
return null;
|
|
56
|
+
try {
|
|
57
|
+
const buf = await readFile(join(repoDir, path));
|
|
58
|
+
return new Uint8Array(buf);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
async listDir(dir) {
|
|
65
|
+
if (hasTraversal(dir))
|
|
66
|
+
return null;
|
|
67
|
+
try {
|
|
68
|
+
return await readdir(join(repoDir, dir));
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/** True if `path` contains a `..` segment or is absolute. */
|
|
77
|
+
function hasTraversal(path) {
|
|
78
|
+
if (path.startsWith('/') || /^[a-zA-Z]:/.test(path))
|
|
79
|
+
return true; // absolute
|
|
80
|
+
return path.split(/[/\\]/).some((seg) => seg === '..');
|
|
81
|
+
}
|
|
82
|
+
async function* walk(dir, root) {
|
|
83
|
+
let entries;
|
|
84
|
+
try {
|
|
85
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
for (const entry of entries) {
|
|
91
|
+
const full = join(dir, entry.name);
|
|
92
|
+
if (entry.isDirectory()) {
|
|
93
|
+
if (SKIP_DIRS.has(entry.name))
|
|
94
|
+
continue;
|
|
95
|
+
yield* walk(full, root);
|
|
96
|
+
}
|
|
97
|
+
else if (entry.isFile()) {
|
|
98
|
+
// Always emit POSIX-style paths so checks can rely on consistent
|
|
99
|
+
// separators across platforms.
|
|
100
|
+
yield relative(root, full).split(sep).join('/');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Map-backed FileSource — used by the VibeCode agent (Workers env).
|
|
106
|
+
* The agent's session DO holds the virtual filesystem as a Map; this
|
|
107
|
+
* adapter exposes it through the same interface as the on-disk CLI.
|
|
108
|
+
*
|
|
109
|
+
* `readBytes` decodes the stored UTF-8 string back to bytes — fine for
|
|
110
|
+
* text-only checks. The agent has no built artefacts (it runs pre-
|
|
111
|
+
* deploy), so bundle-size will return its "not built yet" warn anyway.
|
|
112
|
+
*
|
|
113
|
+
* `listDir` synthesises directory listings from the Map keys.
|
|
114
|
+
*/
|
|
115
|
+
export function mapFileSource(files) {
|
|
116
|
+
return {
|
|
117
|
+
async *list() {
|
|
118
|
+
for (const path of files.keys()) {
|
|
119
|
+
if (isSkippedPath(path))
|
|
120
|
+
continue;
|
|
121
|
+
yield path;
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
async read(path) {
|
|
125
|
+
return files.get(path) ?? null;
|
|
126
|
+
},
|
|
127
|
+
async readBytes(path) {
|
|
128
|
+
const text = files.get(path);
|
|
129
|
+
if (text === undefined)
|
|
130
|
+
return null;
|
|
131
|
+
return new TextEncoder().encode(text);
|
|
132
|
+
},
|
|
133
|
+
async listDir(dir) {
|
|
134
|
+
const prefix = dir.endsWith('/') ? dir : `${dir}/`;
|
|
135
|
+
const children = new Set();
|
|
136
|
+
let saw = false;
|
|
137
|
+
for (const path of files.keys()) {
|
|
138
|
+
if (!path.startsWith(prefix))
|
|
139
|
+
continue;
|
|
140
|
+
saw = true;
|
|
141
|
+
const rest = path.slice(prefix.length);
|
|
142
|
+
const slash = rest.indexOf('/');
|
|
143
|
+
children.add(slash === -1 ? rest : rest.slice(0, slash));
|
|
144
|
+
}
|
|
145
|
+
return saw ? [...children] : null;
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function isSkippedPath(path) {
|
|
150
|
+
for (const seg of path.split('/')) {
|
|
151
|
+
if (SKIP_DIRS.has(seg))
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=file-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-source.js","sourceRoot":"","sources":["../../src/lib/file-source.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gzip via the Web Streams API. Available in Node 18+ and Cloudflare
|
|
3
|
+
* Workers, so the same helper works in both the CLI's filesystem
|
|
4
|
+
* checks and the audit Worker's live checks. Avoids divergence
|
|
5
|
+
* between source-side and live measurements of bundle size.
|
|
6
|
+
*/
|
|
7
|
+
export declare function gzipByteLength(input: Uint8Array): Promise<number>;
|
|
8
|
+
//# sourceMappingURL=gzip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gzip.d.ts","sourceRoot":"","sources":["../../src/lib/gzip.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBvE"}
|
package/dist/lib/gzip.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gzip via the Web Streams API. Available in Node 18+ and Cloudflare
|
|
3
|
+
* Workers, so the same helper works in both the CLI's filesystem
|
|
4
|
+
* checks and the audit Worker's live checks. Avoids divergence
|
|
5
|
+
* between source-side and live measurements of bundle size.
|
|
6
|
+
*/
|
|
7
|
+
export async function gzipByteLength(input) {
|
|
8
|
+
const readable = new ReadableStream({
|
|
9
|
+
start(controller) {
|
|
10
|
+
controller.enqueue(input);
|
|
11
|
+
controller.close();
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
const compressed = readable.pipeThrough(new CompressionStream('gzip'));
|
|
15
|
+
const reader = compressed.getReader();
|
|
16
|
+
let total = 0;
|
|
17
|
+
for (;;) {
|
|
18
|
+
const { value, done } = await reader.read();
|
|
19
|
+
if (done)
|
|
20
|
+
break;
|
|
21
|
+
if (value)
|
|
22
|
+
total += value.byteLength;
|
|
23
|
+
}
|
|
24
|
+
return total;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=gzip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gzip.js","sourceRoot":"","sources":["../../src/lib/gzip.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAiB;IACpD,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAa;QAC9C,KAAK,CAAC,UAAU;YACd,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC1B,UAAU,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC;KACF,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,EAAE,CAAC;IACtC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,SAAS,CAAC;QACR,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QAC5C,IAAI,IAAI;YAAE,MAAM;QAChB,IAAI,KAAK;YAAE,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC;IACvC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FileSource } from './file-source.js';
|
|
2
|
+
/**
|
|
3
|
+
* "Is this a game project?" — used by checks that diverge between apps
|
|
4
|
+
* (FreeAppStore) and games (FreeGameStore). Apps run inside a sidebar+
|
|
5
|
+
* scrolling Shell; games run inside a viewport-locked GameShell with
|
|
6
|
+
* different brand tokens. Several rules need to know which they're
|
|
7
|
+
* looking at.
|
|
8
|
+
*
|
|
9
|
+
* Detection signals (any one is sufficient):
|
|
10
|
+
* - `@freeappstore/games` listed in any package.json
|
|
11
|
+
* - A TS/JS source file imports from `@freeappstore/games`
|
|
12
|
+
*
|
|
13
|
+
* Both signals exist because workspace hoisting can put the dep in the
|
|
14
|
+
* root package.json (where a per-app scan would miss it) and template
|
|
15
|
+
* scaffolds put the import in app source.
|
|
16
|
+
*/
|
|
17
|
+
export declare function isGameProject(source: FileSource): Promise<boolean>;
|
|
18
|
+
//# sourceMappingURL=project-type.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-type.d.ts","sourceRoot":"","sources":["../../src/lib/project-type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAaxE"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Is this a game project?" — used by checks that diverge between apps
|
|
3
|
+
* (FreeAppStore) and games (FreeGameStore). Apps run inside a sidebar+
|
|
4
|
+
* scrolling Shell; games run inside a viewport-locked GameShell with
|
|
5
|
+
* different brand tokens. Several rules need to know which they're
|
|
6
|
+
* looking at.
|
|
7
|
+
*
|
|
8
|
+
* Detection signals (any one is sufficient):
|
|
9
|
+
* - `@freeappstore/games` listed in any package.json
|
|
10
|
+
* - A TS/JS source file imports from `@freeappstore/games`
|
|
11
|
+
*
|
|
12
|
+
* Both signals exist because workspace hoisting can put the dep in the
|
|
13
|
+
* root package.json (where a per-app scan would miss it) and template
|
|
14
|
+
* scaffolds put the import in app source.
|
|
15
|
+
*/
|
|
16
|
+
export async function isGameProject(source) {
|
|
17
|
+
for await (const path of source.list()) {
|
|
18
|
+
const base = path.split('/').pop() ?? '';
|
|
19
|
+
if (base !== 'package.json')
|
|
20
|
+
continue;
|
|
21
|
+
const content = await source.read(path);
|
|
22
|
+
if (content && /@freeappstore\/games/.test(content))
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
for await (const path of source.list()) {
|
|
26
|
+
if (!path.endsWith('.ts') && !path.endsWith('.tsx'))
|
|
27
|
+
continue;
|
|
28
|
+
const content = await source.read(path);
|
|
29
|
+
if (content && /from\s+['"]@freeappstore\/games['"]/.test(content))
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=project-type.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-type.js","sourceRoot":"","sources":["../../src/lib/project-type.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAAkB;IACpD,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,cAAc;YAAE,SAAS;QACtC,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,OAAO,IAAI,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;IACnE,CAAC;IACD,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACvC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,SAAS;QAC9D,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,OAAO,IAAI,qCAAqC,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;IAClF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source-stripping helpers shared by checks that run regex against raw
|
|
3
|
+
* source files. The whole class of bugs these prevent: a regex matches
|
|
4
|
+
* a token (like `<meta name="viewport">`, `new Audio(`, `100vh`,
|
|
5
|
+
* `@amplitude`) that lives inside a comment or a string literal —
|
|
6
|
+
* never actually evaluated, but the static check fires anyway.
|
|
7
|
+
*
|
|
8
|
+
* Two design rules:
|
|
9
|
+
* 1. All strippers preserve character positions — they replace
|
|
10
|
+
* removed bytes with spaces (newlines kept), so any `regex.index`
|
|
11
|
+
* result still refers to the same line/column in the real source.
|
|
12
|
+
* 2. The strippers don't try to be a full tokenizer. They handle the
|
|
13
|
+
* common cases (escapes inside strings, nested comment-like text
|
|
14
|
+
* inside strings) and accept that pathological constructs
|
|
15
|
+
* (template-literal `${...}` containing braces, regex literals
|
|
16
|
+
* with asymmetric braces) need a real parser. In practice the
|
|
17
|
+
* compliance fixtures don't hit these.
|
|
18
|
+
*/
|
|
19
|
+
/** Replace `<!-- ... -->` comment bodies with spaces. */
|
|
20
|
+
export declare function stripHtmlComments(src: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Replace JS/TS line + block comment bodies AND string-literal
|
|
23
|
+
* contents with spaces. Use this when a regex against the source
|
|
24
|
+
* shouldn't match documentation strings or commented-out code (the
|
|
25
|
+
* common pattern: matching SDK names, API calls, CSS unit tokens).
|
|
26
|
+
*
|
|
27
|
+
* Handles single, double, and backtick strings with `\` escapes.
|
|
28
|
+
* Doesn't track template-literal `${...}` interpolation contents and
|
|
29
|
+
* doesn't recognise regex literals — both edge cases would need a
|
|
30
|
+
* tokenizer.
|
|
31
|
+
*/
|
|
32
|
+
export declare function stripCommentsAndStrings(src: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Like `stripCommentsAndStrings` but preserves string contents.
|
|
35
|
+
* Use when the regex needs to see string values — e.g. inspecting
|
|
36
|
+
* `font-family: "Comic Sans"` inside JSX, where the string value IS
|
|
37
|
+
* the thing being audited.
|
|
38
|
+
*/
|
|
39
|
+
export declare function stripCommentsOnly(src: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* Replace `/* ... */` comment bodies with spaces. CSS doesn't have
|
|
42
|
+
* `//` line comments at the language level (some preprocessors add
|
|
43
|
+
* them, but plain CSS doesn't), so this is the simpler variant.
|
|
44
|
+
*/
|
|
45
|
+
export declare function stripCssComments(src: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* Dispatch to the right stripper based on file extension. For unknown
|
|
48
|
+
* extensions, falls back to `stripCommentsAndStrings` (JS-style) —
|
|
49
|
+
* conservative because most source files compliance checks touch are
|
|
50
|
+
* JS-flavoured.
|
|
51
|
+
*/
|
|
52
|
+
export declare function stripForExt(src: string, ext: string): string;
|
|
53
|
+
/**
|
|
54
|
+
* Like `stripForExt` but preserves string-literal contents — useful
|
|
55
|
+
* when the regex needs to match tokens that legitimately appear inside
|
|
56
|
+
* strings (e.g. `@amplitude/` inside an `import from "@amplitude/..."`,
|
|
57
|
+
* which is the literal package-name string we want to catch).
|
|
58
|
+
*/
|
|
59
|
+
export declare function stripCommentsForExt(src: string, ext: string): string;
|
|
60
|
+
//# sourceMappingURL=strip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strip.d.ts","sourceRoot":"","sources":["../../src/lib/strip.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,yDAAyD;AACzD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAwBrD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAepD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAa5D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAapE"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source-stripping helpers shared by checks that run regex against raw
|
|
3
|
+
* source files. The whole class of bugs these prevent: a regex matches
|
|
4
|
+
* a token (like `<meta name="viewport">`, `new Audio(`, `100vh`,
|
|
5
|
+
* `@amplitude`) that lives inside a comment or a string literal —
|
|
6
|
+
* never actually evaluated, but the static check fires anyway.
|
|
7
|
+
*
|
|
8
|
+
* Two design rules:
|
|
9
|
+
* 1. All strippers preserve character positions — they replace
|
|
10
|
+
* removed bytes with spaces (newlines kept), so any `regex.index`
|
|
11
|
+
* result still refers to the same line/column in the real source.
|
|
12
|
+
* 2. The strippers don't try to be a full tokenizer. They handle the
|
|
13
|
+
* common cases (escapes inside strings, nested comment-like text
|
|
14
|
+
* inside strings) and accept that pathological constructs
|
|
15
|
+
* (template-literal `${...}` containing braces, regex literals
|
|
16
|
+
* with asymmetric braces) need a real parser. In practice the
|
|
17
|
+
* compliance fixtures don't hit these.
|
|
18
|
+
*/
|
|
19
|
+
/** Replace `<!-- ... -->` comment bodies with spaces. */
|
|
20
|
+
export function stripHtmlComments(src) {
|
|
21
|
+
const out = src.split('');
|
|
22
|
+
let i = 0;
|
|
23
|
+
while (i < src.length) {
|
|
24
|
+
if (src[i] === '<' &&
|
|
25
|
+
src[i + 1] === '!' &&
|
|
26
|
+
src[i + 2] === '-' &&
|
|
27
|
+
src[i + 3] === '-') {
|
|
28
|
+
const start = i;
|
|
29
|
+
i += 4;
|
|
30
|
+
while (i < src.length &&
|
|
31
|
+
!(src[i] === '-' && src[i + 1] === '-' && src[i + 2] === '>'))
|
|
32
|
+
i++;
|
|
33
|
+
i = Math.min(src.length, i + 3);
|
|
34
|
+
blank(out, start, i);
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
i++;
|
|
38
|
+
}
|
|
39
|
+
return out.join('');
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Replace JS/TS line + block comment bodies AND string-literal
|
|
43
|
+
* contents with spaces. Use this when a regex against the source
|
|
44
|
+
* shouldn't match documentation strings or commented-out code (the
|
|
45
|
+
* common pattern: matching SDK names, API calls, CSS unit tokens).
|
|
46
|
+
*
|
|
47
|
+
* Handles single, double, and backtick strings with `\` escapes.
|
|
48
|
+
* Doesn't track template-literal `${...}` interpolation contents and
|
|
49
|
+
* doesn't recognise regex literals — both edge cases would need a
|
|
50
|
+
* tokenizer.
|
|
51
|
+
*/
|
|
52
|
+
export function stripCommentsAndStrings(src) {
|
|
53
|
+
return stripCode(src, { strings: true });
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Like `stripCommentsAndStrings` but preserves string contents.
|
|
57
|
+
* Use when the regex needs to see string values — e.g. inspecting
|
|
58
|
+
* `font-family: "Comic Sans"` inside JSX, where the string value IS
|
|
59
|
+
* the thing being audited.
|
|
60
|
+
*/
|
|
61
|
+
export function stripCommentsOnly(src) {
|
|
62
|
+
return stripCode(src, { strings: false });
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Replace `/* ... */` comment bodies with spaces. CSS doesn't have
|
|
66
|
+
* `//` line comments at the language level (some preprocessors add
|
|
67
|
+
* them, but plain CSS doesn't), so this is the simpler variant.
|
|
68
|
+
*/
|
|
69
|
+
export function stripCssComments(src) {
|
|
70
|
+
const out = src.split('');
|
|
71
|
+
let i = 0;
|
|
72
|
+
while (i < src.length) {
|
|
73
|
+
if (src[i] === '/' && src[i + 1] === '*') {
|
|
74
|
+
const start = i;
|
|
75
|
+
i += 2;
|
|
76
|
+
while (i < src.length && !(src[i] === '*' && src[i + 1] === '/'))
|
|
77
|
+
i++;
|
|
78
|
+
i = Math.min(src.length, i + 2);
|
|
79
|
+
blank(out, start, i);
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
i++;
|
|
83
|
+
}
|
|
84
|
+
return out.join('');
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Dispatch to the right stripper based on file extension. For unknown
|
|
88
|
+
* extensions, falls back to `stripCommentsAndStrings` (JS-style) —
|
|
89
|
+
* conservative because most source files compliance checks touch are
|
|
90
|
+
* JS-flavoured.
|
|
91
|
+
*/
|
|
92
|
+
export function stripForExt(src, ext) {
|
|
93
|
+
switch (ext.toLowerCase()) {
|
|
94
|
+
case '.html':
|
|
95
|
+
case '.htm':
|
|
96
|
+
return stripHtmlComments(src);
|
|
97
|
+
case '.css':
|
|
98
|
+
case '.scss':
|
|
99
|
+
return stripCssComments(src);
|
|
100
|
+
case '.json':
|
|
101
|
+
return src; // JSON has no comments
|
|
102
|
+
default:
|
|
103
|
+
return stripCommentsAndStrings(src);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Like `stripForExt` but preserves string-literal contents — useful
|
|
108
|
+
* when the regex needs to match tokens that legitimately appear inside
|
|
109
|
+
* strings (e.g. `@amplitude/` inside an `import from "@amplitude/..."`,
|
|
110
|
+
* which is the literal package-name string we want to catch).
|
|
111
|
+
*/
|
|
112
|
+
export function stripCommentsForExt(src, ext) {
|
|
113
|
+
switch (ext.toLowerCase()) {
|
|
114
|
+
case '.html':
|
|
115
|
+
case '.htm':
|
|
116
|
+
return stripHtmlComments(src);
|
|
117
|
+
case '.css':
|
|
118
|
+
case '.scss':
|
|
119
|
+
return stripCssComments(src);
|
|
120
|
+
case '.json':
|
|
121
|
+
return src;
|
|
122
|
+
default:
|
|
123
|
+
return stripCommentsOnly(src);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function stripCode(src, opts) {
|
|
127
|
+
const out = src.split('');
|
|
128
|
+
let i = 0;
|
|
129
|
+
while (i < src.length) {
|
|
130
|
+
const c = src[i];
|
|
131
|
+
if (c === '/' && src[i + 1] === '/') {
|
|
132
|
+
const start = i;
|
|
133
|
+
while (i < src.length && src[i] !== '\n')
|
|
134
|
+
i++;
|
|
135
|
+
blank(out, start, i);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
if (c === '/' && src[i + 1] === '*') {
|
|
139
|
+
const start = i;
|
|
140
|
+
i += 2;
|
|
141
|
+
while (i < src.length && !(src[i] === '*' && src[i + 1] === '/'))
|
|
142
|
+
i++;
|
|
143
|
+
i = Math.min(src.length, i + 2);
|
|
144
|
+
blank(out, start, i);
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (opts.strings && (c === '"' || c === "'" || c === '`')) {
|
|
148
|
+
const quote = c;
|
|
149
|
+
const start = i + 1; // keep the opening quote in place
|
|
150
|
+
i++;
|
|
151
|
+
while (i < src.length && src[i] !== quote) {
|
|
152
|
+
if (src[i] === '\\' && i + 1 < src.length)
|
|
153
|
+
i++;
|
|
154
|
+
i++;
|
|
155
|
+
}
|
|
156
|
+
blank(out, start, i);
|
|
157
|
+
i++; // skip closing quote
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
i++;
|
|
161
|
+
}
|
|
162
|
+
return out.join('');
|
|
163
|
+
}
|
|
164
|
+
function blank(out, from, to) {
|
|
165
|
+
for (let k = from; k < to; k++)
|
|
166
|
+
if (out[k] !== '\n')
|
|
167
|
+
out[k] = ' ';
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=strip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strip.js","sourceRoot":"","sources":["../../src/lib/strip.ts"],"names":[],"mappings":"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"}
|
package/dist/live/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/live/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/live/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAc/C,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AA2BD,wBAAsB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CA2D/E;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAa7D;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAe7D;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA8C3F;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAoD7F;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAoD3F"}
|
package/dist/live/index.js
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
* results in D1 so creators (or platform admins) can see drift over
|
|
18
18
|
* time without leaving the storefront.
|
|
19
19
|
*/
|
|
20
|
+
import { gzipByteLength } from '../lib/gzip.js';
|
|
20
21
|
const TRACKER_PATTERNS = [
|
|
21
22
|
/google-analytics\.com/i,
|
|
22
23
|
/gtag\(/i,
|
|
@@ -216,22 +217,23 @@ export async function checkBundleSizeLive(html, liveUrl) {
|
|
|
216
217
|
return { name: 'Bundle size (live)', status: 'fail', detail: `${jsUrl} → ${res.status}` };
|
|
217
218
|
}
|
|
218
219
|
const body = await res.arrayBuffer();
|
|
219
|
-
//
|
|
220
|
-
//
|
|
221
|
-
//
|
|
220
|
+
// Real gzip via the shared helper — same math the source-side
|
|
221
|
+
// check uses, so live and source verdicts can never disagree on
|
|
222
|
+
// a borderline app.
|
|
222
223
|
const rawKb = Math.round(body.byteLength / 1024);
|
|
223
|
-
const
|
|
224
|
-
|
|
224
|
+
const gzippedBytes = await gzipByteLength(new Uint8Array(body));
|
|
225
|
+
const gzipKb = Math.round(gzippedBytes / 1024);
|
|
226
|
+
if (gzipKb > 300) {
|
|
225
227
|
return {
|
|
226
228
|
name: 'Bundle size (live)',
|
|
227
229
|
status: 'fail',
|
|
228
|
-
detail:
|
|
230
|
+
detail: `${gzipKb} KB gzipped (raw ${rawKb} KB) — over 300 KB limit`,
|
|
229
231
|
};
|
|
230
232
|
}
|
|
231
233
|
return {
|
|
232
234
|
name: 'Bundle size (live)',
|
|
233
235
|
status: 'pass',
|
|
234
|
-
detail:
|
|
236
|
+
detail: `${gzipKb} KB gzipped (raw ${rawKb} KB)`,
|
|
235
237
|
};
|
|
236
238
|
}
|
|
237
239
|
catch (err) {
|
|
@@ -278,7 +280,11 @@ export async function checkUnsafeVhLive(html, liveUrl) {
|
|
|
278
280
|
try {
|
|
279
281
|
const res = await fetchWithTimeout(cssUrl);
|
|
280
282
|
if (!res.ok) {
|
|
281
|
-
return {
|
|
283
|
+
return {
|
|
284
|
+
name: 'No unsafe 100vh (live)',
|
|
285
|
+
status: 'warn',
|
|
286
|
+
detail: `${cssUrl} → HTTP ${res.status}`,
|
|
287
|
+
};
|
|
282
288
|
}
|
|
283
289
|
const css = await res.text();
|
|
284
290
|
const matches = css.match(/\b100vh\b/g) ?? [];
|
package/dist/live/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/live/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/live/index.ts"],"names":[],"mappings":"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"}
|