32 lines
1.8 KiB
JavaScript
32 lines
1.8 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* check-no-repo-pb-hooks.mjs — no PocketBase hooks (pb_hooks, *.pb.js) may live in the repo.
|
|
*
|
|
* WHY: the cloud container pulls this repo every few seconds. A PocketBase hook is server-side JS; one pushed
|
|
* by any plugin writer would run on the team backend within seconds, which is the rogue-writer hole the
|
|
* roundtable test closed. The container never points PocketBase at the repo (--hooksDir is outside the
|
|
* pulled tree; the one team sign-in hook is baked into the image and pinned, deployment/cloud/Dockerfile).
|
|
* This gate keeps anyone from adding a hooks folder that LOOKS like it would run, or that a later recipe
|
|
* change could start running.
|
|
*
|
|
* HOW: every tracked path; a self-test on every run (a poisoned list must fail), so the gate cannot go blind.
|
|
*/
|
|
import { execFileSync } from 'node:child_process'
|
|
import { join, dirname } from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
|
|
const ROOT = process.env.DOXA_REPO || join(dirname(fileURLToPath(import.meta.url)), '..')
|
|
|
|
export const offending = (paths) => paths.filter((p) => /(^|\/)pb_hooks(\/|$)/.test(p) || /\.pb\.(js|ts)$/.test(p))
|
|
|
|
if (offending(['README.md', 'backend/pocketbase/pb_hooks/x.pb.js', 'a/b.pb.ts']).length !== 2) {
|
|
console.error('✗ check:no-repo-pb-hooks self-test failed: the matcher went blind'); process.exit(1)
|
|
}
|
|
const tracked = execFileSync('git', ['ls-files', '-z'], { cwd: ROOT }).toString().split('\0').filter(Boolean)
|
|
const bad = offending(tracked)
|
|
if (bad.length) {
|
|
console.error(`✗ PocketBase hooks in the repo (server-side JS must never ride the live pull):\n${bad.map((p) => ' ' + p).join('\n')}`)
|
|
console.error(' The team sign-in hook is baked into the image (deployment/cloud/Dockerfile); anything else needs a design review.')
|
|
process.exit(1)
|
|
}
|
|
console.log(`✓ no PocketBase hooks among ${tracked.length} tracked files`)
|