@casoon/astro-post-audit 0.1.3

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.
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Post-install script: downloads the prebuilt astro-post-audit binary
5
+ * for the current platform from GitHub Releases.
6
+ */
7
+
8
+ const { execSync } = require("child_process");
9
+ const fs = require("fs");
10
+ const path = require("path");
11
+ const https = require("https");
12
+
13
+ const PACKAGE = "astro-post-audit";
14
+ const VERSION = require("../package.json").version;
15
+ const REPO = "casoon/astro-post-audit";
16
+
17
+ function getPlatformTarget() {
18
+ const platform = process.platform;
19
+ const arch = process.arch;
20
+
21
+ const targets = {
22
+ "darwin-x64": "x86_64-apple-darwin",
23
+ "darwin-arm64": "aarch64-apple-darwin",
24
+ "linux-x64": "x86_64-unknown-linux-gnu",
25
+ "linux-arm64": "aarch64-unknown-linux-gnu",
26
+ "win32-x64": "x86_64-pc-windows-msvc",
27
+ "win32-arm64": "aarch64-pc-windows-msvc",
28
+ };
29
+
30
+ const key = `${platform}-${arch}`;
31
+ const target = targets[key];
32
+
33
+ if (!target) {
34
+ console.error(`Unsupported platform: ${key}`);
35
+ console.error(`Supported platforms: ${Object.keys(targets).join(", ")}`);
36
+ process.exit(1);
37
+ }
38
+
39
+ return target;
40
+ }
41
+
42
+ function getBinaryName() {
43
+ return process.platform === "win32"
44
+ ? `${PACKAGE}.exe`
45
+ : PACKAGE;
46
+ }
47
+
48
+ function getDownloadUrl(target) {
49
+ const ext = process.platform === "win32" ? ".zip" : ".tar.gz";
50
+ return `https://github.com/${REPO}/releases/download/v${VERSION}/${PACKAGE}-v${VERSION}-${target}${ext}`;
51
+ }
52
+
53
+ async function download(url, dest) {
54
+ return new Promise((resolve, reject) => {
55
+ const follow = (url, redirects = 0) => {
56
+ if (redirects > 5) {
57
+ reject(new Error("Too many redirects"));
58
+ return;
59
+ }
60
+
61
+ https.get(url, (res) => {
62
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
63
+ follow(res.headers.location, redirects + 1);
64
+ return;
65
+ }
66
+
67
+ if (res.statusCode !== 200) {
68
+ reject(new Error(`Download failed: HTTP ${res.statusCode} from ${url}`));
69
+ return;
70
+ }
71
+
72
+ const file = fs.createWriteStream(dest);
73
+ res.pipe(file);
74
+ file.on("finish", () => {
75
+ file.close(resolve);
76
+ });
77
+ }).on("error", reject);
78
+ };
79
+
80
+ follow(url);
81
+ });
82
+ }
83
+
84
+ async function main() {
85
+ const target = getPlatformTarget();
86
+ const binaryName = getBinaryName();
87
+ const binDir = path.join(__dirname);
88
+ const binaryPath = path.join(binDir, binaryName);
89
+
90
+ // Skip if binary already exists (e.g., local dev)
91
+ if (fs.existsSync(binaryPath)) {
92
+ console.log(`${PACKAGE} binary already exists, skipping download.`);
93
+ return;
94
+ }
95
+
96
+ const url = getDownloadUrl(target);
97
+ const archiveExt = process.platform === "win32" ? ".zip" : ".tar.gz";
98
+ const archivePath = path.join(binDir, `download${archiveExt}`);
99
+
100
+ console.log(`Downloading ${PACKAGE} v${VERSION} for ${target}...`);
101
+ console.log(` URL: ${url}`);
102
+
103
+ try {
104
+ await download(url, archivePath);
105
+
106
+ // Extract
107
+ if (process.platform === "win32") {
108
+ // Use PowerShell to extract zip on Windows
109
+ execSync(
110
+ `powershell -Command "Expand-Archive -Path '${archivePath}' -DestinationPath '${binDir}' -Force"`,
111
+ { stdio: "inherit" }
112
+ );
113
+ } else {
114
+ execSync(`tar -xzf "${archivePath}" -C "${binDir}"`, {
115
+ stdio: "inherit",
116
+ });
117
+ }
118
+
119
+ // Ensure binary is executable
120
+ if (process.platform !== "win32") {
121
+ fs.chmodSync(binaryPath, 0o755);
122
+ }
123
+
124
+ // Cleanup archive
125
+ fs.unlinkSync(archivePath);
126
+
127
+ console.log(`${PACKAGE} v${VERSION} installed successfully.`);
128
+ } catch (err) {
129
+ console.warn(`Failed to download ${PACKAGE}: ${err.message}`);
130
+ console.warn(
131
+ "You can install it manually from: " +
132
+ `https://github.com/${REPO}/releases`
133
+ );
134
+ // Don't fail the install — the integration will warn if the binary is missing
135
+ }
136
+ }
137
+
138
+ main();
package/bin/run.cjs ADDED
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Thin wrapper that executes the platform-specific astro-post-audit binary.
5
+ */
6
+
7
+ const { execFileSync } = require("child_process");
8
+ const path = require("path");
9
+ const fs = require("fs");
10
+
11
+ const binaryName =
12
+ process.platform === "win32" ? "astro-post-audit.exe" : "astro-post-audit";
13
+ const binaryPath = path.join(__dirname, binaryName);
14
+
15
+ if (!fs.existsSync(binaryPath)) {
16
+ console.error(
17
+ `Error: ${binaryName} not found at ${binaryPath}\n` +
18
+ "Run 'npm rebuild astro-post-audit' or reinstall the package."
19
+ );
20
+ process.exit(2);
21
+ }
22
+
23
+ try {
24
+ execFileSync(binaryPath, process.argv.slice(2), {
25
+ stdio: "inherit",
26
+ });
27
+ } catch (err) {
28
+ // execFileSync throws on non-zero exit code, forward it
29
+ process.exit(err.status ?? 2);
30
+ }
@@ -0,0 +1,3 @@
1
+ export { default } from './integration.js';
2
+ export type { PostAuditOptions } from './integration.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export { default } from './integration.js';
@@ -0,0 +1,27 @@
1
+ import type { AstroIntegration } from 'astro';
2
+ export interface PostAuditOptions {
3
+ /** Path to rules.toml config file */
4
+ config?: string;
5
+ /** Base URL (auto-detected from Astro site config if not set) */
6
+ site?: string;
7
+ /** Treat warnings as errors */
8
+ strict?: boolean;
9
+ /** Output format: 'text' or 'json' */
10
+ format?: 'text' | 'json';
11
+ /** Glob patterns to exclude */
12
+ exclude?: string[];
13
+ /** Skip sitemap checks */
14
+ noSitemapCheck?: boolean;
15
+ /** Enable asset reference checking */
16
+ checkAssets?: boolean;
17
+ /** Enable structured data validation */
18
+ checkStructuredData?: boolean;
19
+ /** Enable security heuristic checks */
20
+ checkSecurity?: boolean;
21
+ /** Enable duplicate content detection */
22
+ checkDuplicates?: boolean;
23
+ /** Disable the integration (useful for dev) */
24
+ disable?: boolean;
25
+ }
26
+ export default function postAudit(options?: PostAuditOptions): AstroIntegration;
27
+ //# sourceMappingURL=integration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../src/integration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAM9C,MAAM,WAAW,gBAAgB;IAC/B,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+BAA+B;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,sCAAsC;IACtC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,0BAA0B;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,sCAAsC;IACtC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,wCAAwC;IACxC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,uCAAuC;IACvC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,yCAAyC;IACzC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,+CAA+C;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,OAAO,GAAE,gBAAqB,GAC7B,gBAAgB,CAyElB"}
@@ -0,0 +1,71 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ import { existsSync } from 'node:fs';
3
+ import { dirname, join } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ export default function postAudit(options = {}) {
6
+ let siteUrl;
7
+ return {
8
+ name: 'astro-post-audit',
9
+ hooks: {
10
+ 'astro:config:done': ({ config }) => {
11
+ siteUrl = config.site?.toString();
12
+ },
13
+ 'astro:build:done': ({ dir, logger }) => {
14
+ if (options.disable)
15
+ return;
16
+ const distPath = fileURLToPath(dir);
17
+ const binDir = join(dirname(fileURLToPath(import.meta.url)), '..', 'bin');
18
+ const binaryName = process.platform === 'win32'
19
+ ? 'astro-post-audit.exe'
20
+ : 'astro-post-audit';
21
+ const binaryPath = join(binDir, binaryName);
22
+ if (!existsSync(binaryPath)) {
23
+ logger.warn('astro-post-audit binary not found. Run "npm rebuild @casoon/astro-post-audit".');
24
+ return;
25
+ }
26
+ const args = [distPath];
27
+ // Use site from options, or auto-detect from Astro config
28
+ const site = options.site ?? siteUrl;
29
+ if (site)
30
+ args.push('--site', site);
31
+ if (options.strict)
32
+ args.push('--strict');
33
+ if (options.format)
34
+ args.push('--format', options.format);
35
+ if (options.config)
36
+ args.push('--config', options.config);
37
+ if (options.noSitemapCheck)
38
+ args.push('--no-sitemap-check');
39
+ if (options.checkAssets)
40
+ args.push('--check-assets');
41
+ if (options.checkStructuredData)
42
+ args.push('--check-structured-data');
43
+ if (options.checkSecurity)
44
+ args.push('--check-security');
45
+ if (options.checkDuplicates)
46
+ args.push('--check-duplicates');
47
+ if (options.exclude) {
48
+ for (const pattern of options.exclude) {
49
+ args.push('--exclude', pattern);
50
+ }
51
+ }
52
+ logger.info('Running post-build audit...');
53
+ try {
54
+ execFileSync(binaryPath, args, { stdio: 'inherit' });
55
+ logger.info('All checks passed!');
56
+ }
57
+ catch (err) {
58
+ const exitCode = err && typeof err === 'object' && 'status' in err
59
+ ? err.status
60
+ : undefined;
61
+ if (exitCode === 1) {
62
+ logger.warn('Audit found issues. See output above.');
63
+ }
64
+ else {
65
+ logger.error(`Audit failed with exit code ${exitCode ?? 'unknown'}`);
66
+ }
67
+ }
68
+ },
69
+ },
70
+ };
71
+ }
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@casoon/astro-post-audit",
3
+ "version": "0.1.3",
4
+ "description": "Fast post-build auditor for Astro sites: SEO, links, and lightweight WCAG checks",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "bin": {
16
+ "astro-post-audit": "bin/run.cjs"
17
+ },
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "postinstall": "node bin/install.cjs"
21
+ },
22
+ "files": [
23
+ "bin/",
24
+ "dist/"
25
+ ],
26
+ "keywords": [
27
+ "astro",
28
+ "astro-integration",
29
+ "seo",
30
+ "audit",
31
+ "accessibility",
32
+ "static-site",
33
+ "wcag",
34
+ "canonical",
35
+ "links"
36
+ ],
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "https://github.com/casoon/astro-post-audit"
40
+ },
41
+ "engines": {
42
+ "node": ">=18"
43
+ },
44
+ "os": [
45
+ "darwin",
46
+ "linux",
47
+ "win32"
48
+ ],
49
+ "cpu": [
50
+ "x64",
51
+ "arm64"
52
+ ],
53
+ "peerDependencies": {
54
+ "astro": "^5.0.0 || ^6.0.0-beta.0 || ^6.0.0"
55
+ },
56
+ "peerDependenciesMeta": {
57
+ "astro": {
58
+ "optional": true
59
+ }
60
+ },
61
+ "devDependencies": {
62
+ "@types/node": "^22.10.1",
63
+ "astro": "^6.0.0-beta.15",
64
+ "typescript": "^5.9.3"
65
+ }
66
+ }