@slashgear/gdpr-cookie-scanner 1.4.0 → 2.0.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 (68) hide show
  1. package/.dockerignore +13 -0
  2. package/.github/workflows/ci.yml +2 -2
  3. package/.github/workflows/docker.yml +49 -0
  4. package/.github/workflows/pages.yml +40 -0
  5. package/.github/workflows/release.yml +1 -1
  6. package/.nvmrc +1 -0
  7. package/CHANGELOG.md +65 -0
  8. package/Dockerfile +36 -0
  9. package/README.md +42 -15
  10. package/dist/cli.js +21 -3
  11. package/dist/cli.js.map +1 -1
  12. package/dist/report/generator.d.ts +1 -4
  13. package/dist/report/generator.d.ts.map +1 -1
  14. package/dist/report/generator.js +45 -23
  15. package/dist/report/generator.js.map +1 -1
  16. package/dist/report/html.d.ts +3 -0
  17. package/dist/report/html.d.ts.map +1 -0
  18. package/dist/report/html.js +766 -0
  19. package/dist/report/html.js.map +1 -0
  20. package/dist/types.d.ts +2 -0
  21. package/dist/types.d.ts.map +1 -1
  22. package/docs/index.html +314 -0
  23. package/docs/reports/github.com/after-accept.png +0 -0
  24. package/docs/reports/github.com/after-reject.png +0 -0
  25. package/docs/reports/github.com/gdpr-checklist-github.com-2026-02-22.md +44 -0
  26. package/docs/reports/github.com/gdpr-cookies-github.com-2026-02-22.md +29 -0
  27. package/docs/reports/github.com/gdpr-report-github.com-2026-02-22.md +102 -0
  28. package/docs/reports/github.com/gdpr-report-github.com-2026-02-22.pdf +0 -0
  29. package/docs/reports/gitlab.com/after-accept.png +0 -0
  30. package/docs/reports/gitlab.com/after-reject.png +0 -0
  31. package/docs/reports/gitlab.com/gdpr-checklist-gitlab.com-2026-02-22.md +44 -0
  32. package/docs/reports/gitlab.com/gdpr-cookies-gitlab.com-2026-02-22.md +55 -0
  33. package/docs/reports/gitlab.com/gdpr-report-gitlab.com-2026-02-22.md +200 -0
  34. package/docs/reports/gitlab.com/gdpr-report-gitlab.com-2026-02-22.pdf +0 -0
  35. package/docs/reports/gitlab.com/modal-initial.png +0 -0
  36. package/docs/reports/npmjs.com/after-accept.png +0 -0
  37. package/docs/reports/npmjs.com/after-reject.png +0 -0
  38. package/docs/reports/npmjs.com/gdpr-checklist-npmjs.com-2026-02-22.md +44 -0
  39. package/docs/reports/npmjs.com/gdpr-cookies-npmjs.com-2026-02-22.md +25 -0
  40. package/docs/reports/npmjs.com/gdpr-report-npmjs.com-2026-02-22.md +88 -0
  41. package/docs/reports/npmjs.com/gdpr-report-npmjs.com-2026-02-22.pdf +0 -0
  42. package/docs/reports/reddit.com/after-accept.png +0 -0
  43. package/docs/reports/reddit.com/after-reject.png +0 -0
  44. package/docs/reports/reddit.com/gdpr-checklist-reddit.com-2026-02-22.md +44 -0
  45. package/docs/reports/reddit.com/gdpr-cookies-reddit.com-2026-02-22.md +33 -0
  46. package/docs/reports/reddit.com/gdpr-report-reddit.com-2026-02-22.md +148 -0
  47. package/docs/reports/reddit.com/gdpr-report-reddit.com-2026-02-22.pdf +0 -0
  48. package/docs/reports/reddit.com/modal-initial.png +0 -0
  49. package/docs/reports/stackoverflow.com/after-accept.png +0 -0
  50. package/docs/reports/stackoverflow.com/after-reject.png +0 -0
  51. package/docs/reports/stackoverflow.com/gdpr-checklist-stackoverflow.com-2026-02-22.md +44 -0
  52. package/docs/reports/stackoverflow.com/gdpr-cookies-stackoverflow.com-2026-02-22.md +67 -0
  53. package/docs/reports/stackoverflow.com/gdpr-report-stackoverflow.com-2026-02-22.md +206 -0
  54. package/docs/reports/stackoverflow.com/gdpr-report-stackoverflow.com-2026-02-22.pdf +0 -0
  55. package/docs/reports/stackoverflow.com/modal-initial.png +0 -0
  56. package/docs/reports/www.afp.com/after-accept.png +0 -0
  57. package/docs/reports/www.afp.com/after-reject.png +0 -0
  58. package/docs/reports/www.afp.com/gdpr-checklist-afp.com-2026-02-22.md +44 -0
  59. package/docs/reports/www.afp.com/gdpr-cookies-afp.com-2026-02-22.md +42 -0
  60. package/docs/reports/www.afp.com/gdpr-report-afp.com-2026-02-22.md +202 -0
  61. package/docs/reports/www.afp.com/gdpr-report-afp.com-2026-02-22.pdf +0 -0
  62. package/docs/reports/www.afp.com/modal-initial.png +0 -0
  63. package/docs/style.css +439 -0
  64. package/package.json +6 -6
  65. package/src/cli.ts +28 -4
  66. package/src/report/generator.ts +54 -29
  67. package/src/report/html.ts +940 -0
  68. package/src/types.ts +3 -0
package/.dockerignore ADDED
@@ -0,0 +1,13 @@
1
+ .git
2
+ .github
3
+ .claude
4
+ .changeset
5
+ node_modules/
6
+ dist/
7
+ reports/
8
+ gdpr-reports/
9
+ tests/
10
+ *.md
11
+ *.log
12
+ .DS_Store
13
+ .nvmrc
@@ -11,7 +11,7 @@ jobs:
11
11
  runs-on: ubuntu-latest
12
12
 
13
13
  steps:
14
- - uses: actions/checkout@v4
14
+ - uses: actions/checkout@v6
15
15
 
16
16
  - uses: pnpm/action-setup@v4
17
17
  with:
@@ -19,7 +19,7 @@ jobs:
19
19
 
20
20
  - uses: actions/setup-node@v4
21
21
  with:
22
- node-version: 22
22
+ node-version: 24
23
23
  cache: pnpm
24
24
 
25
25
  - name: Install dependencies
@@ -0,0 +1,49 @@
1
+ name: Docker
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ docker:
9
+ runs-on: ubuntu-latest
10
+ permissions:
11
+ contents: read
12
+ packages: write
13
+
14
+ steps:
15
+ - uses: actions/checkout@v6
16
+
17
+ - name: Set up QEMU
18
+ uses: docker/setup-qemu-action@v3
19
+
20
+ - name: Set up Docker Buildx
21
+ uses: docker/setup-buildx-action@v3
22
+
23
+ - name: Log in to GitHub Container Registry
24
+ uses: docker/login-action@v3
25
+ with:
26
+ registry: ghcr.io
27
+ username: ${{ github.actor }}
28
+ password: ${{ secrets.GITHUB_TOKEN }}
29
+
30
+ - name: Extract metadata
31
+ id: meta
32
+ uses: docker/metadata-action@v5
33
+ with:
34
+ images: ghcr.io/slashgear/gdpr-cookie-scanner
35
+ tags: |
36
+ type=semver,pattern={{version}}
37
+ type=semver,pattern={{major}}.{{minor}}
38
+ type=raw,value=latest
39
+
40
+ - name: Build and push
41
+ uses: docker/build-push-action@v6
42
+ with:
43
+ context: .
44
+ platforms: linux/amd64,linux/arm64
45
+ push: true
46
+ tags: ${{ steps.meta.outputs.tags }}
47
+ labels: ${{ steps.meta.outputs.labels }}
48
+ cache-from: type=gha
49
+ cache-to: type=gha,mode=max
@@ -0,0 +1,40 @@
1
+ name: Deploy GitHub Pages
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ paths:
8
+ - "docs/**"
9
+ workflow_dispatch:
10
+
11
+ permissions:
12
+ contents: read
13
+ pages: write
14
+ id-token: write
15
+
16
+ concurrency:
17
+ group: pages
18
+ cancel-in-progress: false
19
+
20
+ jobs:
21
+ deploy:
22
+ environment:
23
+ name: github-pages
24
+ url: ${{ steps.deployment.outputs.page_url }}
25
+ runs-on: ubuntu-latest
26
+ steps:
27
+ - name: Checkout
28
+ uses: actions/checkout@v4
29
+
30
+ - name: Configure Pages
31
+ uses: actions/configure-pages@v4
32
+
33
+ - name: Upload artifact
34
+ uses: actions/upload-pages-artifact@v3
35
+ with:
36
+ path: docs/
37
+
38
+ - name: Deploy to GitHub Pages
39
+ id: deployment
40
+ uses: actions/deploy-pages@v4
@@ -12,7 +12,7 @@ jobs:
12
12
  pull-requests: write
13
13
 
14
14
  steps:
15
- - uses: actions/checkout@v4
15
+ - uses: actions/checkout@v6
16
16
 
17
17
  - uses: pnpm/action-setup@v4
18
18
  with:
package/.nvmrc ADDED
@@ -0,0 +1 @@
1
+ 24
package/CHANGELOG.md CHANGED
@@ -1,5 +1,70 @@
1
1
  # @slashgear/gdpr-cookie-scanner
2
2
 
3
+ ## 2.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - 98880ac: feat!: require Node.js 24 LTS (breaking change for Node 20/22 users)
8
+
9
+ Node.js 24 became Active LTS in October 2025. This is a breaking change for
10
+ users running Node 20 or 22. A `.nvmrc` file is provided so `nvm use`
11
+ automatically selects the correct version when entering the project directory.
12
+
13
+ ### Minor Changes
14
+
15
+ - bd769d6: Add GitHub Pages landing page with live GDPR reports
16
+
17
+ Adds a static landing page (`docs/`) hosted on GitHub Pages that showcases the tool
18
+ with real scan results for 6 tech sites (reddit.com, dev.to, github.com, gitlab.com,
19
+ stackoverflow.com, npmjs.com). The page is vanilla HTML/CSS with dark mode support
20
+ and links directly to the rendered Markdown reports on GitHub.
21
+
22
+ Also adds `.github/workflows/pages.yml` to automatically deploy `docs/` on every
23
+ push to `main` that touches that directory.
24
+
25
+ - cf9c42a: feat: add Docker image for containerised usage
26
+
27
+ A `Dockerfile` is now included at the root of the repository, enabling
28
+ `gdpr-scan` to be run in any environment that supports Docker without
29
+ needing a local Node.js or Playwright installation.
30
+
31
+ The image uses a two-stage build:
32
+
33
+ - **Builder** (`node:24-slim`) — compiles TypeScript to `dist/`
34
+ - **Runtime** (`node:24-slim` + `playwright install chromium --with-deps`) —
35
+ installs only Chromium and its system dependencies instead of the full
36
+ official Playwright image (which bundles Chromium, Firefox and WebKit).
37
+ This keeps the final image around **400–600 MB** vs ~1.5–1.8 GB for the
38
+ unoptimised approach.
39
+
40
+ A `.dockerignore` is also included to exclude source files, Git history,
41
+ and dev artefacts from the build context.
42
+
43
+ Usage:
44
+
45
+ ```bash
46
+ # Build
47
+ docker build -t gdpr-scan .
48
+
49
+ # Run a scan (mount a local directory to retrieve the reports)
50
+ docker run --rm -v $(pwd)/reports:/reports gdpr-scan scan https://example.com -o /reports
51
+ ```
52
+
53
+ - 5cba8a8: feat: add multi-format report output and a standalone HTML report
54
+
55
+ The CLI now accepts a `-f, --format <formats>` option (comma-separated, defaults
56
+ to `md,pdf`) that controls which report files are produced. Supported values:
57
+ `md`, `html`, `json`, `pdf`.
58
+
59
+ The new `html` format generates a self-contained, styled HTML report directly from
60
+ the scan result — no external dependencies, no network requests. It includes a
61
+ colour-coded grade badge, per-dimension score cards with progress bars,
62
+ dark-pattern issue cards, modal details, cookies by phase, network tracker tables,
63
+ recommendations, and a compliance checklist.
64
+
65
+ This makes the report easier to share (single file, opens in any browser) and
66
+ provides a better reading experience than the Markdown version.
67
+
3
68
  ## 1.4.0
4
69
 
5
70
  ### Minor Changes
package/Dockerfile ADDED
@@ -0,0 +1,36 @@
1
+ # ── Stage 1: build ────────────────────────────────────────────────────────────
2
+ FROM node:24-slim AS builder
3
+ WORKDIR /app
4
+
5
+ RUN npm install -g pnpm@latest
6
+
7
+ COPY package.json pnpm-lock.yaml ./
8
+ RUN pnpm install --frozen-lockfile
9
+
10
+ COPY tsconfig.json ./
11
+ COPY src ./src
12
+ RUN pnpm build
13
+
14
+ # ── Stage 2: runtime ──────────────────────────────────────────────────────────
15
+ # node:24-slim + Chromium only (~400-600 MB) vs the full Playwright image
16
+ # (~1.5-1.8 GB with all 3 browser stacks).
17
+ FROM node:24-slim
18
+ WORKDIR /app
19
+ ENV NODE_ENV=production
20
+
21
+ RUN npm install -g pnpm@latest
22
+
23
+ # Install production dependencies first — playwright CLI is needed for browser install
24
+ COPY package.json pnpm-lock.yaml ./
25
+ RUN pnpm install --prod --frozen-lockfile
26
+
27
+ # Install Chromium + its system dependencies, then clean up apt caches
28
+ RUN pnpm exec playwright install chromium --with-deps \
29
+ && rm -rf /var/lib/apt/lists/*
30
+
31
+ COPY --from=builder /app/dist ./dist
32
+
33
+ VOLUME ["/reports"]
34
+
35
+ ENTRYPOINT ["node", "dist/cli.js"]
36
+ CMD ["--help"]
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # gdpr-cookie-scanner
2
2
 
3
- [![CI](https://github.com/Slashgear/gdpr-report/actions/workflows/ci.yml/badge.svg)](https://github.com/Slashgear/gdpr-report/actions/workflows/ci.yml)
3
+ [![CI](https://github.com/Slashgear/gdpr-cookie-scanner/actions/workflows/ci.yml/badge.svg)](https://github.com/Slashgear/gdpr-cookie-scanner/actions/workflows/ci.yml)
4
4
  [![npm version](https://img.shields.io/npm/v/@slashgear/gdpr-cookie-scanner?logo=npm)](https://www.npmjs.com/package/@slashgear/gdpr-cookie-scanner)
5
5
  [![npm downloads](https://img.shields.io/npm/dw/@slashgear/gdpr-cookie-scanner?logo=npm&label=downloads%2Fweek)](https://www.npmjs.com/package/@slashgear/gdpr-cookie-scanner)
6
6
  [![License: MIT](https://img.shields.io/npm/l/@slashgear/gdpr-cookie-scanner)](LICENSE)
7
- [![Node ≥ 20](https://img.shields.io/node/v/@slashgear/gdpr-cookie-scanner?logo=node.js)](https://nodejs.org)
7
+ [![Node ≥ 24](https://img.shields.io/node/v/@slashgear/gdpr-cookie-scanner?logo=node.js)](https://nodejs.org)
8
8
  [![TypeScript](https://img.shields.io/badge/TypeScript-5-3178c6?logo=typescript&logoColor=white)](https://www.typescriptlang.org)
9
9
  [![Playwright](https://img.shields.io/badge/Playwright-✓-45ba4b?logo=playwright&logoColor=white)](https://playwright.dev)
10
10
  [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](CODE_OF_CONDUCT.md)
@@ -35,6 +35,20 @@ npx @slashgear/gdpr-cookie-scanner gdpr-scan scan https://example.com
35
35
  npx playwright install chromium
36
36
  ```
37
37
 
38
+ ## Docker
39
+
40
+ No Node.js required — pull and run directly:
41
+
42
+ ```bash
43
+ docker run --rm \
44
+ -v $(pwd)/reports:/reports \
45
+ ghcr.io/slashgear/gdpr-cookie-scanner \
46
+ scan https://example.com -o /reports
47
+ ```
48
+
49
+ The image is published to [GitHub Container Registry](https://ghcr.io/slashgear/gdpr-cookie-scanner)
50
+ on every release and supports `linux/amd64` and `linux/arm64`.
51
+
38
52
  ## Usage
39
53
 
40
54
  ```bash
@@ -43,13 +57,14 @@ gdpr-scan scan <url> [options]
43
57
 
44
58
  ### Options
45
59
 
46
- | Option | Default | Description |
47
- | ----------------------- | ---------------- | ------------------------------- |
48
- | `-o, --output <dir>` | `./gdpr-reports` | Output directory for the report |
49
- | `-t, --timeout <ms>` | `30000` | Navigation timeout |
50
- | `--no-screenshots` | | Disable screenshot capture |
51
- | `-l, --locale <locale>` | `fr-FR` | Browser locale |
52
- | `-v, --verbose` | | Show full stack trace on error |
60
+ | Option | Default | Description |
61
+ | ------------------------ | ---------------- | ------------------------------------------------------------- |
62
+ | `-o, --output <dir>` | `./gdpr-reports` | Output directory for the report |
63
+ | `-t, --timeout <ms>` | `30000` | Navigation timeout |
64
+ | `-f, --format <formats>` | `md,pdf` | Output formats: `md`, `html`, `json`, `pdf` (comma-separated) |
65
+ | `--no-screenshots` | — | Disable screenshot capture |
66
+ | `-l, --locale <locale>` | `fr-FR` | Browser locale |
67
+ | `-v, --verbose` | — | Show full stack trace on error |
53
68
 
54
69
  ### Examples
55
70
 
@@ -63,6 +78,12 @@ gdpr-scan scan https://example.com -o ./reports
63
78
  # Scan in English, without screenshots
64
79
  gdpr-scan scan https://example.com --locale en-US --no-screenshots
65
80
 
81
+ # Generate only an HTML report
82
+ gdpr-scan scan https://example.com -f html
83
+
84
+ # Generate all formats at once
85
+ gdpr-scan scan https://example.com -f md,html,json,pdf
86
+
66
87
  # Show the built-in tracker database
67
88
  gdpr-scan list-trackers
68
89
  ```
@@ -74,14 +95,22 @@ flowchart LR
74
95
  URL([URL]) --> Chromium[Chromium] --> Classify[Classify] --> Score[Score] --> Report[Report]
75
96
  ```
76
97
 
77
- A real Chromium browser loads the page, interacts with the consent modal (reject then accept in a fresh session), and captures cookies and network requests at each step. Results are classified, scored across 4 compliance dimensions, and rendered into Markdown and PDF reports.
98
+ A real Chromium browser loads the page, interacts with the consent modal (reject then accept in a fresh session), and captures cookies and network requests at each step. Results are classified, scored across 4 compliance dimensions, and rendered into one or more report files depending on `--format`.
99
+
100
+ ## Generated reports
78
101
 
79
- ## Generated report
102
+ Each scan produces up to 4 file types in `<output-dir>/<hostname>/`:
80
103
 
81
- The Markdown report contains:
104
+ | Format | Files | Description |
105
+ | ------ | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
106
+ | `md` | `gdpr-report-*.md`, `gdpr-checklist-*.md`, `gdpr-cookies-*.md` | Main compliance report, per-rule checklist with legal references, and deduplicated cookie inventory |
107
+ | `html` | `gdpr-report-*.html` | Self-contained styled report — grade badge, score cards, dark-pattern issues, cookie and tracker tables. Opens in any browser, no dependencies |
108
+ | `json` | `gdpr-report-*.json` | Full raw scan result for programmatic processing or CI integration |
109
+ | `pdf` | `gdpr-report-*.pdf` | PDF built from the Markdown reports via Playwright |
110
+
111
+ All formats contain:
82
112
 
83
113
  - **Global score** (0–100) and **grade** A/B/C/D/F
84
- - Executive summary
85
114
  - Modal analysis: buttons, checkboxes, font size, screenshots
86
115
  - Detected dark patterns (missing reject button, visual asymmetry, pre-ticked boxes, misleading wording…)
87
116
  - Cookie table before interaction, after reject, after accept
@@ -89,8 +118,6 @@ The Markdown report contains:
89
118
  - Targeted recommendations
90
119
  - Legal references (RGPD, ePrivacy directive, CEPD guidelines, CNIL 2022)
91
120
 
92
- The file is created at: `<output-dir>/gdpr-report-<domain>-<date>.md`
93
-
94
121
  ## Scoring
95
122
 
96
123
  The score is made up of 4 criteria (25 points each):
package/dist/cli.js CHANGED
@@ -19,6 +19,7 @@ program
19
19
  .option("--no-screenshots", "Disable screenshot capture")
20
20
  .option("-l, --locale <locale>", "Browser locale for language detection", "fr-FR")
21
21
  .option("-v, --verbose", "Show detailed output", false)
22
+ .option("-f, --format <formats>", "Output formats: md, html, json, pdf (comma-separated)", "md,pdf")
22
23
  .action(async (url, opts) => {
23
24
  console.log();
24
25
  console.log(chalk.bold.blue(" GDPR Cookie Scanner"));
@@ -29,6 +30,15 @@ program
29
30
  console.log(chalk.gray(` Target : ${url}`));
30
31
  console.log(chalk.gray(` Output : ${outputDir}`));
31
32
  console.log();
33
+ const validFormats = new Set(["md", "html", "json", "pdf"]);
34
+ const formats = opts.format
35
+ .split(",")
36
+ .map((f) => f.trim().toLowerCase())
37
+ .filter((f) => validFormats.has(f));
38
+ if (formats.length === 0) {
39
+ console.error(chalk.red(" Invalid --format value. Valid options: md, html, json, pdf"));
40
+ process.exit(2);
41
+ }
32
42
  const options = {
33
43
  url: normalizedUrl,
34
44
  outputDir,
@@ -36,6 +46,7 @@ program
36
46
  screenshots: opts.screenshots !== false,
37
47
  locale: opts.locale,
38
48
  verbose: opts.verbose,
49
+ formats,
39
50
  };
40
51
  const spinner = ora("Launching browser...").start();
41
52
  try {
@@ -47,7 +58,7 @@ program
47
58
  spinner.succeed("Scan complete");
48
59
  console.log();
49
60
  const generator = new ReportGenerator(options);
50
- const { reportPath, pdfPath } = await generator.generate(result);
61
+ const paths = await generator.generate(result);
51
62
  console.log(chalk.bold(` Compliance score: ${formatScore(result.compliance.total)} ${result.compliance.grade}`));
52
63
  console.log();
53
64
  if (result.compliance.issues.length > 0) {
@@ -61,8 +72,15 @@ program
61
72
  }
62
73
  console.log();
63
74
  }
64
- console.log(chalk.green(` Report saved: ${reportPath}`));
65
- console.log(chalk.green(` PDF saved: ${pdfPath}`));
75
+ const labels = {
76
+ md: "Markdown",
77
+ html: "HTML",
78
+ json: "JSON",
79
+ pdf: "PDF",
80
+ };
81
+ for (const [fmt, path] of Object.entries(paths)) {
82
+ console.log(chalk.green(` ${(labels[fmt] ?? fmt).padEnd(8)} ${path}`));
83
+ }
66
84
  console.log();
67
85
  process.exit(result.compliance.grade === "F" ? 1 : 0);
68
86
  }
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGxD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,mDAAmD,CAAC;KAChE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,sDAAsD,CAAC;KACnE,QAAQ,CAAC,OAAO,EAAE,4BAA4B,CAAC;KAC/C,MAAM,CAAC,oBAAoB,EAAE,iCAAiC,EAAE,gBAAgB,CAAC;KACjF,MAAM,CAAC,oBAAoB,EAAE,oCAAoC,EAAE,OAAO,CAAC;KAC3E,MAAM,CAAC,kBAAkB,EAAE,4BAA4B,CAAC;KACxD,MAAM,CAAC,uBAAuB,EAAE,uCAAuC,EAAE,OAAO,CAAC;KACjF,MAAM,CAAC,eAAe,EAAE,sBAAsB,EAAE,KAAK,CAAC;KACtD,MAAM,CACL,wBAAwB,EACxB,uDAAuD,EACvD,QAAQ,CACT;KACA,MAAM,CAAC,KAAK,EAAE,GAAW,EAAE,IAAI,EAAE,EAAE;IAClC,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC,CAAC;IACnE,MAAM,aAAa,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC,QAAQ,CAAC;IACjD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC;IAEvD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,SAAS,EAAE,CAAC,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,MAAM,YAAY,GAAG,IAAI,GAAG,CAAe,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;IAC1E,MAAM,OAAO,GAAI,IAAI,CAAC,MAAiB;SACpC,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;SAClC,MAAM,CAAC,CAAC,CAAC,EAAqB,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAiB,CAAC,CAAC,CAAC;IAEzE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC,CAAC;QACzF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAgB;QAC3B,GAAG,EAAE,aAAa;QAClB,SAAS;QACT,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;QACnC,WAAW,EAAE,IAAI,CAAC,WAAW,KAAK,KAAK;QACvC,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,OAAO;KACR,CAAC;IAEF,MAAM,OAAO,GAAG,GAAG,CAAC,sBAAsB,CAAC,CAAC,KAAK,EAAE,CAAC;IAEpD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;QAErC,OAAO,CAAC,IAAI,GAAG,sCAAsC,CAAC;QACtD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YACzC,OAAO,CAAC,IAAI,GAAG,KAAK,CAAC;QACvB,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QACjC,OAAO,CAAC,GAAG,EAAE,CAAC;QAEd,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC;QAC/C,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAE/C,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,IAAI,CACR,uBAAuB,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,CACzF,CACF,CAAC;QACF,OAAO,CAAC,GAAG,EAAE,CAAC;QAEd,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,qBAAqB,CAAC,CAAC,CAAC;YACrF,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;gBACzD,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAChF,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;YAClD,CAAC;YACD,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxC,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,IAAI,CAAC,eAAe,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,oBAAoB,CAAC,CACnF,CAAC;YACJ,CAAC;YACD,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,CAAC;QAED,MAAM,MAAM,GAA2B;YACrC,EAAE,EAAE,UAAU;YACd,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,MAAM;YACZ,GAAG,EAAE,KAAK;SACX,CAAC;QACF,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAChD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,CAAC;QAEd,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC5B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3F,IAAI,IAAI,CAAC,OAAO,IAAI,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YACtD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;QACvC,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,eAAe,CAAC;KACxB,WAAW,CAAC,4CAA4C,CAAC;KACzD,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,+BAA+B,CAAC,CAAC;IACrE,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC7C,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9C,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC;QAC3B,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC,CAAC;IAC1D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,oBAAoB,CAAC,CAAC;AAChF,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAE5B,SAAS,YAAY,CAAC,GAAW;IAC/B,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9D,OAAO,WAAW,GAAG,EAAE,CAAC;IAC1B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,MAAM,OAAO,GACX,KAAK,IAAI,EAAE;QACT,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;QACpB,CAAC,CAAC,KAAK,IAAI,EAAE;YACX,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;YACrB,CAAC,CAAC,KAAK,IAAI,EAAE;gBACX,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC;gBAC7B,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC3B,OAAO,GAAG,OAAO,MAAM,CAAC;AAC1B,CAAC"}
@@ -3,10 +3,7 @@ import type { ScanOptions } from "../types.js";
3
3
  export declare class ReportGenerator {
4
4
  private readonly options;
5
5
  constructor(options: ScanOptions);
6
- generate(result: ScanResult): Promise<{
7
- reportPath: string;
8
- pdfPath: string;
9
- }>;
6
+ generate(result: ScanResult): Promise<Record<string, string>>;
10
7
  private buildHtmlBody;
11
8
  private inlineImages;
12
9
  private wrapHtml;
@@ -1 +1 @@
1
- {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/report/generator.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,UAAU,EAKX,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,WAAW;IAE3C,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;YAmCtE,aAAa;YAkDb,YAAY;IAmC1B,OAAO,CAAC,QAAQ;IAgDhB,OAAO,CAAC,aAAa;IA6ErB,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,qBAAqB;IAkD7B,OAAO,CAAC,iBAAiB;IA2EzB,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,kBAAkB;IAqC1B,OAAO,CAAC,iBAAiB;IA4BzB,OAAO,CAAC,8BAA8B;IAiBtC,OAAO,CAAC,mBAAmB;IAgD3B,OAAO,CAAC,oBAAoB;IA2D5B,OAAO,CAAC,qBAAqB;IA6H7B,OAAO,CAAC,cAAc;CAmRvB"}
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/report/generator.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,UAAU,EAKX,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,WAAW;IAE3C,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YA2DrD,aAAa;YAkDb,YAAY;IAmC1B,OAAO,CAAC,QAAQ;IAgDhB,OAAO,CAAC,aAAa;IA6ErB,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,qBAAqB;IAkD7B,OAAO,CAAC,iBAAiB;IA2EzB,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,kBAAkB;IAqC1B,OAAO,CAAC,iBAAiB;IA4BzB,OAAO,CAAC,8BAA8B;IAiBtC,OAAO,CAAC,mBAAmB;IAgD3B,OAAO,CAAC,oBAAoB;IA2D5B,OAAO,CAAC,qBAAqB;IA6H7B,OAAO,CAAC,cAAc;CAmRvB"}
@@ -5,6 +5,7 @@ import { promisify } from "util";
5
5
  import { fileURLToPath } from "url";
6
6
  import { Marked } from "marked";
7
7
  import { generatePdf } from "./pdf.js";
8
+ import { generateHtmlReport } from "./html.js";
8
9
  const execFileAsync = promisify(execFile);
9
10
  const oxfmtBin = join(dirname(fileURLToPath(import.meta.url)), "../../node_modules/.bin/oxfmt");
10
11
  export class ReportGenerator {
@@ -16,29 +17,50 @@ export class ReportGenerator {
16
17
  await mkdir(this.options.outputDir, { recursive: true });
17
18
  const hostname = new URL(result.url).hostname.replace(/^www\./, "");
18
19
  const date = new Date(result.scanDate).toISOString().split("T")[0];
19
- const filename = `gdpr-report-${hostname}-${date}.md`;
20
- const outputPath = join(this.options.outputDir, filename);
21
- const markdown = this.buildMarkdown(result);
22
- await writeFile(outputPath, markdown, "utf-8");
23
- await execFileAsync(oxfmtBin, [outputPath]).catch(() => { });
24
- const checklistFilename = `gdpr-checklist-${hostname}-${date}.md`;
25
- const checklistPath = join(this.options.outputDir, checklistFilename);
26
- const checklist = this.buildChecklist(result);
27
- await writeFile(checklistPath, checklist, "utf-8");
28
- await execFileAsync(oxfmtBin, [checklistPath]).catch(() => { });
29
- const cookiesFilename = `gdpr-cookies-${hostname}-${date}.md`;
30
- const cookiesPath = join(this.options.outputDir, cookiesFilename);
31
- const cookiesInventory = this.buildCookiesInventory(result);
32
- await writeFile(cookiesPath, cookiesInventory, "utf-8");
33
- await execFileAsync(oxfmtBin, [cookiesPath]).catch(() => { });
34
- const combined = [markdown, checklist, cookiesInventory].join("\n\n---\n\n");
35
- const rawBody = await this.buildHtmlBody(combined);
36
- const body = await this.inlineImages(rawBody, this.options.outputDir);
37
- const html = this.wrapHtml(body, hostname);
38
- const pdfFilename = `gdpr-report-${hostname}-${date}.pdf`;
39
- const pdfPath = join(this.options.outputDir, pdfFilename);
40
- await generatePdf(html, pdfPath);
41
- return { reportPath: outputPath, pdfPath };
20
+ const base = `gdpr-report-${hostname}-${date}`;
21
+ const formats = this.options.formats;
22
+ const paths = {};
23
+ // ── Markdown ──────────────────────────────────────────────────
24
+ if (formats.includes("md")) {
25
+ const mdPath = join(this.options.outputDir, `${base}.md`);
26
+ await writeFile(mdPath, this.buildMarkdown(result), "utf-8");
27
+ await execFileAsync(oxfmtBin, [mdPath]).catch(() => { });
28
+ paths.md = mdPath;
29
+ const checklistPath = join(this.options.outputDir, `gdpr-checklist-${hostname}-${date}.md`);
30
+ await writeFile(checklistPath, this.buildChecklist(result), "utf-8");
31
+ await execFileAsync(oxfmtBin, [checklistPath]).catch(() => { });
32
+ const cookiesPath = join(this.options.outputDir, `gdpr-cookies-${hostname}-${date}.md`);
33
+ await writeFile(cookiesPath, this.buildCookiesInventory(result), "utf-8");
34
+ await execFileAsync(oxfmtBin, [cookiesPath]).catch(() => { });
35
+ }
36
+ // ── HTML ──────────────────────────────────────────────────────
37
+ if (formats.includes("html")) {
38
+ const htmlPath = join(this.options.outputDir, `${base}.html`);
39
+ await writeFile(htmlPath, generateHtmlReport(result), "utf-8");
40
+ paths.html = htmlPath;
41
+ }
42
+ // ── JSON ──────────────────────────────────────────────────────
43
+ if (formats.includes("json")) {
44
+ const jsonPath = join(this.options.outputDir, `${base}.json`);
45
+ await writeFile(jsonPath, JSON.stringify(result, null, 2), "utf-8");
46
+ paths.json = jsonPath;
47
+ }
48
+ // ── PDF (via Markdown → HTML → Playwright) ────────────────────
49
+ if (formats.includes("pdf")) {
50
+ const markdown = paths.md
51
+ ? await import("fs/promises").then((m) => m.readFile(paths.md, "utf-8"))
52
+ : this.buildMarkdown(result);
53
+ const checklist = this.buildChecklist(result);
54
+ const cookiesInventory = this.buildCookiesInventory(result);
55
+ const combined = [markdown, checklist, cookiesInventory].join("\n\n---\n\n");
56
+ const rawBody = await this.buildHtmlBody(combined);
57
+ const body = await this.inlineImages(rawBody, this.options.outputDir);
58
+ const html = this.wrapHtml(body, hostname);
59
+ const pdfPath = join(this.options.outputDir, `${base}.pdf`);
60
+ await generatePdf(html, pdfPath);
61
+ paths.pdf = pdfPath;
62
+ }
63
+ return paths;
42
64
  }
43
65
  async buildHtmlBody(markdown) {
44
66
  const entries = [];