@empline/preflight
v1.0.72
Published
Distributable preflight validation system with app-specific plugin support
Maintainers
Readme
Preflight Manager
A distributable preflight validation system that supports:
- Core checks bundled with the package
- App-specific checks discovered from
scripts/active/preflights/ - Configuration via
preflight.config.ts - Category-based filtering
- Parallel execution
- Beautiful progress reporting
Table of Contents
- Installation
- Quick Start
- Applying to an Existing App
- Configuration
- Writing Custom Checks
- Available Categories
- CI Integration
- Automatic Updates with Dependabot/Renovate
- Contributing & Making Enhancements
Installation
npm install @empline/preflight
# or
pnpm add @empline/preflightQuick Start
# Run all checks
npx preflight
# Run specific categories
npx preflight security
npx preflight security database
# Quick mode (critical checks only)
npx preflight --quick
# Parallel execution
npx preflight --parallel
# Verbose output
npx preflight --verboseApplying to an Existing App
Follow these steps to add preflight checks to an existing repository:
Step 1: Install the Package
# In your app directory (e.g., C:\apps\website-webanto)
cd C:\apps\website-webanto
pnpm add @empline/preflightStep 2: Create Configuration File
Copy the template or create preflight.config.ts in your app root:
# Copy template (if available)
cp node_modules/@empline/preflight/templates/preflight.config.ts.template preflight.config.tsOr create manually:
// preflight.config.ts
import type { AppConfig } from "@empline/preflight";
const config: AppConfig = {
appName: "website-webanto",
// Choose which categories to run (empty = all)
categories: ["security", "typescript", "runtime", "ui"],
// Skip categories that don't apply
excludeCategories: ["business"],
// Skip specific checks
excludeChecks: [],
// Where your app-specific checks live
pluginDir: "scripts/active/preflights",
};
export default config;Step 3: Create App-Specific Checks Directory
mkdir -p scripts/active/preflightsStep 4: Add to Build/CI Pipeline
// package.json
{
"scripts": {
"preflight": "preflight",
"preflight:quick": "preflight --quick",
"build": "preflight && next build"
}
}Step 5: (Optional) Add App-Specific Checks
Create checks specific to your app in scripts/active/preflights/:
// scripts/active/preflights/business/my-validation.ts
import { PreflightCheckResult, emoji } from "@empline/preflight";
export const id = "business/my-validation";
export const name = "My Custom Validation";
export const category = "business";
export const blocking = true;
export const description = "Validates my app-specific rules";
export async function run(): Promise<PreflightCheckResult> {
// Your validation logic
return { passed: true, findings: [], duration: 0 };
}Configuration
Full configuration options for preflight.config.ts:
import type { AppConfig } from "@empline/preflight";
const config: AppConfig = {
// App identifier (auto-detected from folder name if not set)
appName: "my-app",
// Categories to run (empty array = run all categories)
categories: ["security", "typescript", "runtime"],
// Categories to always skip
excludeCategories: ["ui"],
// Specific check IDs to skip
excludeChecks: ["business/price-calculation-validation"],
// Specific check IDs to always include (overrides excludeCategories)
includeChecks: [],
// Directory for app-specific checks (relative to config file)
pluginDir: "scripts/active/preflights",
// Custom categories for this app
customCategories: {
"my-domain": {
pattern: "MyPattern|OtherPattern",
description: "Domain-specific checks",
},
},
// Skip CI-only checks when running locally
respectCiOnly: true,
// Timeout per check (ms)
defaultTimeout: 30000,
// Max parallel checks
concurrency: 4,
// Output paths for reports
output: {
json: ".preflight/report.json",
sarif: ".preflight/report.sarif",
},
};
export default config;Writing Custom Checks
Create a new check in scripts/active/preflights/:
import {
PreflightCheckResult,
PreflightFinding,
STANDARD_EXCLUDES,
emoji,
writeFindings,
fileCache,
} from "@empline/preflight";
// Required: Check metadata
export const id = "business/my-check";
export const name = "My Custom Check";
export const category = "business";
export const blocking = true;
export const description = "Validates something important";
export const tags = ["custom", "validation"];
// Required: Main run function
export async function run(): Promise<PreflightCheckResult> {
const startTime = Date.now();
const findings: PreflightFinding[] = [];
// Use fileCache for efficient file scanning
const files = await fileCache.getCodeFiles();
for (const file of files) {
// Your validation logic here
}
return {
passed: findings.filter(f => f.level === "error").length === 0,
findings,
duration: Date.now() - startTime,
};
}Built-in Preflight Checks
The package ships with 449 preflight checks organized into 42 categories:
| Category | Checks | Description | |----------|--------|-------------| | ai | 3 | AI/ML code quality and recognition pipeline validation | | api | 7 | API completeness, contracts, pagination, response consistency | | architecture | 7 | Component architecture, page consistency, orphaned pages | | auth | 7 | Authentication, session security, role validation | | business | 12 | Business invariants, pricing, inventory, order validation | | code-hygiene | 15 | Console logs, dead code, TODO tracking, comment hygiene | | code-quality | 7 | TypeScript safety, magic numbers, duplicate logic | | config | 1 | Configuration validation | | css | 2 | Dead CSS detection, sticky header validation | | database | 18 | Prisma schema, migrations, seed validation, query patterns | | data-integrity | 5 | Cart integrity, product flow, store data validation | | dependencies | 3 | Dependency health, deprecated packages | | deployment | 6 | Production config, environment validation, rollback safety | | drift-prevention | 9 | Breaking changes, consistency patterns, performance regression | | e2e | 10 | E2E test quality, performance baselines, resource monitoring | | email | 3 | Email template validation and verification | | environment | 1 | Environment variable validation | | framework | 2 | Framework compatibility, Turbopack enforcement | | governance | 5 | Codeowners, naming conventions, route naming | | image | 2 | Card edge protection, orientation validation | | integrations | 2 | Platform feed integrity, integration validation | | nextjs | 7 | Next.js routes, metadata, image optimization | | observability | 1 | Centralized logging validation | | organization | 12 | File organization, API routes, script organization | | payments | 2 | Stripe/PayPal webhook validation (auto-detect) | | performance | 6 | Bundle optimization, Core Web Vitals, runtime regression | | prisma | 1 | Prisma 7 compatibility | | quality | 13 | Lint, syntax, unused imports, file validation | | react | 5 | React best practices, error boundaries, memory leaks | | runtime | 11 | Client env usage, JSON safety, Tailwind runtime | | security | 15 | CSRF, env leakage, injection prevention, rate limiting | | seo | 1 | Missing metadata detection | | tailwind | 1 | Tailwind 4 compatibility | | tanstack | 1 | TanStack Query compatibility | | testing | 14 | E2E best practices, test coverage, flakiness detection | | ui | 54 | Spacing, accessibility, component patterns, dark mode | | zod | 1 | Zod schema validation |
Highlighted Checks
Security:
security/env-value-leakage- Detects secrets hardcoded outside .env filessecurity/csrf-protection- Validates CSRF protection on formssecurity/sql-injection-prevention- Scans for SQL injection vulnerabilities
Business:
business/price-calculation-validation- Ensures Decimal.js for monetary calculationsbusiness/inventory-atomicity-validation- Validates inventory operationsbusiness/order-state-machine-validation- Validates order state transitions
Payments:
payments/stripe-webhook-validation- Validates Stripe webhook signaturespayments/paypal-webhook-validation- Validates PayPal webhook/IPN signatures
Database:
database/prisma-schema-syntax- Validates Prisma schema before builddatabase/migration-safety- Checks for safe migration patternsdatabase/seed-coverage-validation- Ensures seed data completeness
UI:
ui/accessibility-critical- Critical accessibility checksui/spacing-check- Validates consistent spacing patternsui/tailwind-consistency- Ensures Tailwind usage patterns
CI Integration
GitHub Actions
name: Preflight Checks
on: [push, pull_request]
jobs:
preflight:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'pnpm'
- run: pnpm install
- run: pnpm preflight --parallel
env:
CI: trueVercel
Add to your build command in package.json:
{
"scripts": {
"build": "preflight && next build"
}
}Or in vercel.json:
{
"buildCommand": "pnpm preflight && pnpm build"
}Automatic Updates with Dependabot/Renovate
This package is designed to be automatically updated across all your apps using Dependabot or Renovate.
Using Dependabot
Create .github/dependabot.yml in each app repository:
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "daily"
groups:
preflight:
patterns:
- "@empline/preflight"
commit-message:
prefix: "chore(deps)"Using Renovate
Create renovate.json in each app repository:
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:recommended"],
"packageRules": [
{
"matchPackageNames": ["@empline/preflight"],
"automerge": true,
"automergeType": "pr",
"schedule": ["every weekday"]
}
]
}How Updates Flow
- You update this package (add new checks, fix bugs, add features)
- Publish to npm with a new version
- Dependabot/Renovate detects the new version in each app
- PRs are auto-created in each app repository
- CI runs preflight checks on the PR
- Auto-merge (if configured) merges the update
Contributing & Making Enhancements
Repository Structure
preflight-manager/
├── src/
│ ├── core/ # Types, categories, config loader
│ ├── utils/ # Console, findings, progress, plugin loader
│ ├── shared/ # Glob patterns, file cache, concurrency
│ ├── checks/ # Core checks (shipped with package)
│ ├── runner.ts # Main orchestrator
│ └── index.ts # Package exports
├── templates/
│ ├── preflight.config.ts.template # Config template for apps
│ ├── new-check.ts.template # Generic check template
│ └── domain-specific/
│ └── trading-card-system/ # Domain-specific check templates
└── package.jsonAdding a New Core Check
- Create the check file in
src/checks/<category>/:
// src/checks/security/new-security-check.ts
export const id = "security/new-check";
export const name = "New Security Check";
export const category = "security";
export const blocking = true;
export const description = "Checks for something important";
export async function run(): Promise<PreflightCheckResult> {
// Implementation
}- The check is automatically discovered by the runner.
Adding New Utilities
- Add to the appropriate file in
src/utils/orsrc/shared/ - Export from
src/index.ts - Update the README if it's a public API
Publishing Updates
# 1. Make your changes
# 2. Update version
npm version patch # or minor/major
# 3. Build
npm run build
# 4. Publish
npm publish
# 5. Push tags
git push --tagsVersioning Guidelines
- Patch (1.0.x): Bug fixes, non-breaking check improvements
- Minor (1.x.0): New checks, new utilities, new features
- Major (x.0.0): Breaking changes to config format or API
Testing Changes Locally
Before publishing, test in a consuming app:
# In preflight-manager
npm run build
npm link
# In your app
npm link @empline/preflight
npx preflightCore Exports
The package exports utilities for use in your checks:
import {
// Types
PreflightCheckResult,
PreflightFinding,
AppConfig,
// Glob patterns
STANDARD_EXCLUDES,
CODE_FILE_PATTERN,
PRODUCTION_CODE_EXCLUDES,
// File cache (95% faster file scanning)
fileCache,
// Console utilities
emoji,
createProgressBar,
createDivider,
// Findings writer
writeFindings,
createFinding,
// Progress reporter
createUniversalProgressReporter,
// Config utilities
loadAppConfig,
shouldRunCheck,
} from "@empline/preflight";License
MIT
