|
1 | | -// Post-build step: package the built site (dist/) into dist/api-validator.zip so |
2 | | -// the "Run Locally" button can hand a user the whole app as a static bundle they |
3 | | -// serve themselves. Runs after `vite build`; uses the system `zip` (present on |
4 | | -// macOS and the ubuntu CI runner). |
| 1 | +// Post-build step: package the SINGLE-FILE build (dist-local/, a self-contained |
| 2 | +// index.html produced by `SINGLEFILE=1 vite build`) into dist/api-validator.zip, |
| 3 | +// which the live site serves for the "Run Locally" button. Because everything — |
| 4 | +// JS, CSS, and the Monaco workers — is inlined, a user can just unzip and open |
| 5 | +// index.html directly (file://); no server or external fetches required. |
5 | 6 | // |
6 | | -// The build uses a relative base ('./'), so assets resolve from any folder. The |
7 | | -// app still needs a real HTTP server — browsers block ES modules and web workers |
8 | | -// over file:// — so we include double-clickable launchers + a how-to. |
| 7 | +// Uses the system `zip` (present on macOS and the ubuntu CI runner). Never fails |
| 8 | +// the build over the optional archive — the site still deploys. |
9 | 9 | import { execSync } from 'node:child_process'; |
10 | | -import { existsSync, writeFileSync, chmodSync } from 'node:fs'; |
| 10 | +import { existsSync, writeFileSync } from 'node:fs'; |
11 | 11 |
|
| 12 | +const SRC = 'dist-local'; // single-file build output |
| 13 | +const OUTDIR = 'dist'; // where the servable zip must land |
12 | 14 | const OUT = 'api-validator.zip'; |
13 | 15 |
|
14 | | -if (!existsSync('dist')) { |
15 | | - console.error('zip-dist: dist/ not found — run `vite build` first.'); |
16 | | - process.exit(1); |
| 16 | +if (!existsSync(SRC)) { |
| 17 | + console.warn(`zip-dist: ${SRC}/ not found (run \`SINGLEFILE=1 vite build\`) — skipping zip.`); |
| 18 | + process.exit(0); |
17 | 19 | } |
18 | 20 |
|
19 | | -// How-to that travels inside the archive. |
| 21 | +// Short how-to that travels inside the archive. |
20 | 22 | writeFileSync( |
21 | | - 'dist/RUN-LOCALLY.txt', |
| 23 | + `${SRC}/RUN-LOCALLY.txt`, |
22 | 24 | [ |
23 | 25 | 'API Validator — run locally', |
24 | 26 | '', |
25 | | - 'This is the fully built, static app. It runs entirely in your browser; there', |
26 | | - 'is no backend and no keys are required.', |
| 27 | + 'index.html is fully self-contained (all JavaScript, CSS, and workers are', |
| 28 | + 'inlined). Just unzip and open index.html in your browser — double-click it,', |
| 29 | + 'or drag it into a browser window. No server, no internet, no keys.', |
27 | 30 | '', |
28 | | - 'IMPORTANT: you must serve the folder over http — you cannot just double-click', |
29 | | - 'index.html. Browsers block JavaScript modules and web workers over file://,', |
30 | | - 'so the page would load but the app would not run.', |
31 | | - '', |
32 | | - 'Easiest: double-click the launcher for your OS (it starts a local server and', |
33 | | - 'opens your browser):', |
34 | | - ' • macOS: start.command', |
35 | | - ' • Windows: start.bat', |
36 | | - ' • Linux: start.sh (or run it in a terminal)', |
37 | | - '', |
38 | | - 'Or do it by hand, from inside this folder:', |
39 | | - ' python3 -m http.server 8000 # then open http://localhost:8000/', |
40 | | - ' # or: npx serve .', |
| 31 | + 'Everything runs locally in your browser.', |
41 | 32 | '', |
42 | 33 | 'Source: https://github.com/api-commons/api-validator', |
43 | 34 | '', |
44 | 35 | ].join('\n'), |
45 | 36 | ); |
46 | 37 |
|
47 | | -// macOS / Linux launcher — serve this folder and open the browser. |
48 | | -writeFileSync( |
49 | | - 'dist/start.command', |
50 | | - [ |
51 | | - '#!/bin/bash', |
52 | | - 'cd "$(dirname "$0")"', |
53 | | - 'PORT=8000', |
54 | | - 'URL="http://localhost:$PORT/"', |
55 | | - 'echo "Serving API Validator at $URL (press Ctrl+C to stop)"', |
56 | | - '( sleep 1; (command -v open >/dev/null && open "$URL") || (command -v xdg-open >/dev/null && xdg-open "$URL") ) &', |
57 | | - 'python3 -m http.server "$PORT" 2>/dev/null || python -m http.server "$PORT"', |
58 | | - '', |
59 | | - ].join('\n'), |
60 | | -); |
61 | | -// A plain .sh alias for Linux users who prefer it. |
62 | | -writeFileSync('dist/start.sh', 'exec "$(dirname "$0")/start.command"\n'); |
63 | | -chmodSync('dist/start.command', 0o755); |
64 | | -chmodSync('dist/start.sh', 0o755); |
65 | | - |
66 | | -// Windows launcher. |
67 | | -writeFileSync( |
68 | | - 'dist/start.bat', |
69 | | - [ |
70 | | - '@echo off', |
71 | | - 'cd /d "%~dp0"', |
72 | | - 'set PORT=8000', |
73 | | - 'start "" "http://localhost:%PORT%/"', |
74 | | - 'py -m http.server %PORT% 2>nul || python -m http.server %PORT%', |
75 | | - '', |
76 | | - ].join('\r\n'), |
77 | | -); |
78 | | - |
79 | | -// Build the archive from inside dist/ (so paths are relative), excluding any |
80 | | -// pre-existing zip. -X drops extra macOS metadata for a clean cross-platform zip. |
81 | | -// Never fail the build over the optional archive — the site still deploys. |
82 | 38 | try { |
83 | | - execSync(`cd dist && rm -f ${OUT} && zip -r -q -X ${OUT} . -x '*.zip'`, { stdio: 'inherit' }); |
84 | | - console.log(`zip-dist: wrote dist/${OUT}`); |
| 39 | + execSync(`rm -f ${OUTDIR}/${OUT} && cd ${SRC} && zip -r -q -X ../${OUTDIR}/${OUT} . -x '*.zip'`, { stdio: 'inherit' }); |
| 40 | + console.log(`zip-dist: wrote ${OUTDIR}/${OUT} from ${SRC}/`); |
85 | 41 | } catch (e) { |
86 | 42 | console.warn(`zip-dist: could not create ${OUT} (is \`zip\` installed?) — skipping. ${e?.message || e}`); |
87 | 43 | } |
0 commit comments