|
| 1 | +// Copies the PHP admin panel into the build output, so it ships with the site. |
| 2 | +// |
| 3 | +// Hostinger deploys this repository by running `npm run build` and serving |
| 4 | +// my-app/dist. That means dist is the document root: anything not in it does |
| 5 | +// not exist as far as the web is concerned, which is why niteshacars.in/admin |
| 6 | +// returned the site's own "page not found" while the panel sat perfectly well |
| 7 | +// in the repository. |
| 8 | +// |
| 9 | +// Vite copies public/ verbatim into dist/, so the panel could simply live |
| 10 | +// there -- but public/ is for the website's own assets, and burying a PHP |
| 11 | +// application inside it would be a surprise to anyone reading the tree. This |
| 12 | +// copies it explicitly instead, after the build, where the intent is visible. |
| 13 | +// |
| 14 | +// config.php is never copied. It holds the database password, it is gitignored, |
| 15 | +// and dist is rebuilt from scratch on every deploy -- so anything written into |
| 16 | +// it is temporary by construction. The panel finds its configuration outside |
| 17 | +// the build output; see config() in the panel's src/db.php. |
| 18 | + |
| 19 | +import { cp, mkdir, rm, stat } from 'node:fs/promises'; |
| 20 | +import { dirname, join } from 'node:path'; |
| 21 | +import { fileURLToPath } from 'node:url'; |
| 22 | + |
| 23 | +const root = dirname(dirname(fileURLToPath(import.meta.url))); |
| 24 | +const source = join(dirname(root), 'public_html', 'admin.niteshacars.in', 'admin'); |
| 25 | +const target = join(root, 'dist', 'admin'); |
| 26 | + |
| 27 | +// Never ship these. The test tooling is not a security boundary, but it is |
| 28 | +// noise on a public server and some of it takes arguments. |
| 29 | +const SKIP = new Set(['config.php', '.ftp-deploy-sync-state.json', '.ftp-deploy-admin-state.json']); |
| 30 | + |
| 31 | +try { |
| 32 | + await stat(source); |
| 33 | +} catch { |
| 34 | + console.error(`copy-admin-panel: no panel at ${source}`); |
| 35 | + process.exit(1); |
| 36 | +} |
| 37 | + |
| 38 | +await rm(target, { recursive: true, force: true }); |
| 39 | +await mkdir(dirname(target), { recursive: true }); |
| 40 | + |
| 41 | +let copied = 0; |
| 42 | +await cp(source, target, { |
| 43 | + recursive: true, |
| 44 | + filter: (src) => { |
| 45 | + const name = src.slice(src.lastIndexOf('/') + 1); |
| 46 | + if (SKIP.has(name)) return false; |
| 47 | + copied += 1; |
| 48 | + return true; |
| 49 | + }, |
| 50 | +}); |
| 51 | + |
| 52 | +console.log(`copy-admin-panel: ${copied} entries into dist/admin`); |
0 commit comments