@s4e/jsentinel-cli
v0.3.3
Published
JSentinel CLI: framework-agnostic manifest generator
Readme
@s4e/jsentinel-cli
Manifest generator for JSentinel. Scans your production build and writes a single manifest.json describing scripts your pages load.
- same‑origin JS/CSS with SRI hashes
- inline scripts, classified as stable or volatile (stable are hashed)
- external scripts from build outputs
Install
npm i -D @s4e/jsentinel-cliConfigure
Create a single configuration file at your project root. Use JSENTINEL_ENV=production environment variable for production mode (defaults to development if not set). Obtain your S4E dashboard API token (s4eToken) via [email protected].
jsentinel.config.json:
{
"$schema": "./node_modules/@s4e/jsentinel-cli/schema/jsentinel.config.schema.json",
"baseUrl": "/",
"inputs": ["dist", ".next/static", "public"],
"output": "public/manifest.json",
"hashAlgo": "sha256",
"exclude": ["**/*.map"],
"s4eToken": "<YOUR_S4E_TOKEN>"
}Environment Variables:
- JSENTINEL_ENV: Set to
productionfor production mode. Defaults to development mode if not set.
Development vs Production Modes
Development Mode (Default):
- ✅ Host validation: License host check is skipped (allows localhost, any domain)
- ✅ S4E delivery: Skipped - manifest file is written locally only
- ✅ Use case: Local development, testing, CI/CD without S4E integration
Production Mode (JSENTINEL_ENV=production):
- ✅ Host validation: License host check is enforced (must match license host)
- ✅ S4E delivery: Enabled - manifest is sent to S4E dashboard
- ✅ Use case: Production deployments with full security enforcement
Configuration properties
All keys go inside your jsentinel.config.json root object:
$schema (string): JSON Schema reference for editor IntelliSense. Do not modify.
baseUrl (string, default: "/"): Base URL prefix used for same‑origin keys. If missing trailing
/, it will be added. For.next/staticinputs, the web path is normalized to/_next/static/.inputs (string[], default:
["dist","build","public",".next/static","out"]): Directories to scan for built assets (JS/CSS/HTML). CLI positionals override this list.output (string, default:
"public/manifest.json"): Destination path for the generated manifest JSON file.hashAlgo ("sha256" | "sha384" | "sha512", default: "sha256"): Hash algorithm for integrity (SRI) values in the manifest.
exclude (string[], default:
[]): Glob patterns to exclude during scanning (applied relative to each input dir).post (string, default: ""): When set, the CLI will POST the manifest JSON to this URL after generation (separate from S4E collector).
header (string[], default:
[]): Additional request headers for POST, expressed askey:valuestrings (e.g.,x-custom: foo).token (string, default: ""): Bearer token used to set the
authorization: Bearer <token>header when posting to your--postURL.signSecret (string, default: ""): HMAC‑SHA256 secret for signing the POST body. Adds header
x-signature: sha256=<base64>.idempotencyKey (string, default: ""): Value for the
idempotency-keyheader to ensure idempotent delivery to your--postendpoint.timeout (number ≥ 0, default:
10000): HTTP timeout in milliseconds for headers and body when posting the manifest.retries (number ≥ 0, default:
2): Retry count for 5xx or network errors when posting the manifest (exponential backoff).insecure (boolean, default:
false): Iftrue, disables TLS verification for HTTPS requests (not recommended).verbose (boolean, default:
false): Iftrue, prints additional logs (headers, sizes, attempts).dumpResponse (boolean, default:
false): Iftrue, prints the first 2KB of the successful POST response body.dryRun (boolean, default:
false): Iftrue, performs all steps except the final POST (no network call).s4eToken (string, REQUIRED): JWT used for sending payloads to the S4E dashboard collector. This is separate from
token, which is only used for your own--postuploads.
Generate
Production:
JSENTINEL_ENV=production jsentinel manifest -c jsentinel.config.jsonDevelopment (default):
jsentinel manifest -c jsentinel.config.jsonPackage.json scripts:
{
"scripts": {
"jsentinel": "jsentinel manifest -c jsentinel.config.json",
"jsentinel:prod": "JSENTINEL_ENV=production jsentinel manifest -c jsentinel.config.json",
"build": "your-build-command && npm run jsentinel",
"build:prod": "your-build-command && npm run jsentinel:prod"
}
}Common examples:
- Vite:
vite build && npm run jsentinel(dev) /vite build && npm run jsentinel:prod(prod) - Next.js:
next build && npm run jsentinel(dev) /next build && npm run jsentinel:prod(prod) - Vue CLI:
vue-cli-service build && npm run jsentinel(dev) /vue-cli-service build && npm run jsentinel:prod(prod)
Output
The CLI writes manifest.json (example):
{
"version": "2024-07-01T12:34:56.000Z",
"hashAlgo": "sha256",
"scripts": [
{
"src": "/assets/app-abc123.js",
"type": "same-origin",
"hash": "sha256-..."
},
{
"inline": "console.log('hi')",
"type": "inline-stable",
"hash": "sha256-..."
},
{ "inline": "window.__NEXT_DATA__=...", "type": "inline-volatile" },
{
"src": "https://cdn.example.com/[email protected]/index.min.js",
"type": "versioned-cdn"
},
{
"src": "https://example.com/loader.js?v=1",
"type": "dynamic-loader",
"host": "example.com",
"path": "/loader.js",
"query": "v=1"
}
]
}Support
License/dashboard tokens: [email protected]
