{"_id":"@andrewthecoder/erwinmvc","_rev":"2-c83c837b0757c3215e4bb1fe2ffc1a50","name":"@andrewthecoder/erwinmvc","dist-tags":{"latest":"0.8.4"},"versions":{"0.8.3":{"name":"@andrewthecoder/erwinmvc","version":"0.8.3","keywords":["mvc","framework","express","prisma","ejs","typescript","node"],"author":{"name":"Erwin Interactive"},"license":"MIT","_id":"@andrewthecoder/erwinmvc@0.8.3","maintainers":[{"name":"andrewerwin","email":"andrewerwin73@gmail.com"}],"homepage":"https://github.com/andrewthecodertx/erwinmvc#readme","bugs":{"url":"https://github.com/andrewthecodertx/erwinmvc/issues"},"bin":{"erwinmvc":"dist/cli.js"},"dist":{"shasum":"cdaf2fa6a06701c461399ab69c631a9fab3e851f","tarball":"https://registry.npmjs.org/@andrewthecoder/erwinmvc/-/erwinmvc-0.8.3.tgz","fileCount":63,"integrity":"sha512-pQX9Fu4GAsmCbH2bdUgpM9/0UpPi88jmKrXnwAtZUdnNLXq4Q25F0I/eAFFDKwNzmjDSBedWcmFTfbxdVD1hRw==","signatures":[{"sig":"MEQCIEisGMepChn9gvuKchtPPl5yMeafSjpgqH3wjt0EOFodAiB3taaTzEW7S4UqX2j+M1TXSNVvFVbwjEl8i3bOUYCtYQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":150547},"main":"dist/framework/index.js","types":"dist/framework/index.d.ts","engines":{"node":">=20.0.0"},"gitHead":"26e579548a7b1d69a79bc6f371a7cdecbc0690fd","scripts":{"dev":"tsx src/cli.ts","test":"jest","build":"tsc -p tsconfig.json && node scripts/build-cli.js","prepare":"npm run build"},"_npmUser":{"name":"andrewerwin","email":"andrewerwin73@gmail.com"},"repository":{"url":"git+https://github.com/andrewthecodertx/erwinmvc.git","type":"git"},"_npmVersion":"11.16.0","description":"A lightweight, full-featured MVC framework for Node.js with Express, Prisma, and EJS","directories":{},"_nodeVersion":"26.2.0","dependencies":{"ejs":"^3.1.10","zod":"^3.23.8","cors":"^2.8.5","redis":"^4.7.0","dotenv":"^16.4.5","helmet":"^8.0.0","prisma":"^6.0.0","express":"^4.21.0","postcss":"^8.4.38","bcryptjs":"^2.4.3","base64url":"^3.0.1","commander":"^12.1.0","tailwindcss":"^4.2.2","jsonwebtoken":"^9.0.2","connect-redis":"^7.1.1","@prisma/client":"^6.0.0","express-session":"^1.18.0","@simplewebauthn/server":"^13.3.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.1","jest":"^29.7.0","esbuild":"^0.24.0","ts-jest":"^29.2.5","supertest":"^7.0.0","@types/ejs":"^3.1.5","typescript":"^5.6.3","@types/cors":"^2.8.17","@types/jest":"^29.5.13","@types/node":"^22.19.15","@types/express":"^5.0.0","@types/bcryptjs":"^2.4.6","@types/supertest":"^6.0.2","@types/jsonwebtoken":"^9.0.7","@types/express-session":"^1.18.0"},"_npmOperationalInternal":{"tmp":"tmp/erwinmvc_0.8.3_1780722168146_0.440803557585544","host":"s3://npm-registry-packages-npm-production"}},"0.8.4":{"name":"@andrewthecoder/erwinmvc","version":"0.8.4","description":"A lightweight, full-featured MVC framework for Node.js with Express, Prisma, and EJS","main":"dist/framework/index.js","types":"dist/framework/index.d.ts","bin":{"erwinmvc":"dist/cli.js"},"scripts":{"build":"tsc -p tsconfig.json && node scripts/build-cli.js","dev":"tsx src/cli.ts","test":"jest","prepare":"npm run build"},"publishConfig":{"access":"public"},"keywords":["mvc","framework","express","prisma","ejs","typescript","node"],"author":{"name":"Erwin Interactive"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/andrewthecodertx/erwinmvc.git"},"engines":{"node":">=20.0.0"},"dependencies":{"@prisma/client":"^6.0.0","@simplewebauthn/server":"^13.3.0","base64url":"^3.0.1","bcryptjs":"^2.4.3","commander":"^12.1.0","connect-redis":"^7.1.1","cors":"^2.8.5","dotenv":"^16.4.5","ejs":"^3.1.10","express":"^4.21.0","express-session":"^1.18.0","helmet":"^8.0.0","jsonwebtoken":"^9.0.2","postcss":"^8.4.38","prisma":"^6.0.0","redis":"^4.7.0","tailwindcss":"^4.2.2","zod":"^3.23.8"},"devDependencies":{"@types/bcryptjs":"^2.4.6","@types/cors":"^2.8.17","@types/ejs":"^3.1.5","@types/express":"^5.0.0","@types/express-session":"^1.18.0","@types/jest":"^29.5.13","@types/jsonwebtoken":"^9.0.7","@types/node":"^22.19.15","@types/supertest":"^6.0.2","esbuild":"^0.24.0","jest":"^29.7.0","supertest":"^7.0.0","ts-jest":"^29.2.5","tsx":"^4.19.1","typescript":"^5.6.3"},"gitHead":"26e579548a7b1d69a79bc6f371a7cdecbc0690fd","_id":"@andrewthecoder/erwinmvc@0.8.4","bugs":{"url":"https://github.com/andrewthecodertx/erwinmvc/issues"},"homepage":"https://github.com/andrewthecodertx/erwinmvc#readme","_nodeVersion":"26.2.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-28LvRG9DrVYQ0RmfbImstsEOZOJkmQvO5aKex6ZUxbsZLYgUF1aq+2aKGi/wJgD+cpWNO6tqeNltXsWXdDbwkA==","shasum":"c8a778b85e32939821f5d9fb92803e966f0f75cf","tarball":"https://registry.npmjs.org/@andrewthecoder/erwinmvc/-/erwinmvc-0.8.4.tgz","fileCount":63,"unpackedSize":150760,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCan5EMSAu1NMNZ8maBgvOqs2WkihTxA6E/n0qG3jFnJwIgJLFa3LoJ2GPkKKSh472An/4Z7QL1lCEAT6Il9HqxL3Q="}]},"_npmUser":{"name":"andrewerwin","email":"andrewerwin73@gmail.com"},"directories":{},"maintainers":[{"name":"andrewerwin","email":"andrewerwin73@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/erwinmvc_0.8.4_1780722284379_0.12205067809479364"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-06T05:02:48.002Z","modified":"2026-06-06T05:04:44.617Z","0.8.3":"2026-06-06T05:02:48.278Z","0.8.4":"2026-06-06T05:04:44.514Z"},"bugs":{"url":"https://github.com/andrewthecodertx/erwinmvc/issues"},"author":{"name":"Erwin Interactive"},"license":"MIT","homepage":"https://github.com/andrewthecodertx/erwinmvc#readme","keywords":["mvc","framework","express","prisma","ejs","typescript","node"],"repository":{"type":"git","url":"git+https://github.com/andrewthecodertx/erwinmvc.git"},"description":"A lightweight, full-featured MVC framework for Node.js with Express, Prisma, and EJS","maintainers":[{"name":"andrewerwin","email":"andrewerwin73@gmail.com"}],"readme":"# @andrewthecoder/erwinmvc\n\n[![npm version](https://img.shields.io/npm/v/@andrewthecoder/erwinmvc.svg)](https://www.npmjs.com/package/@andrewthecoder/erwinmvc)\n\nA lightweight, full-featured MVC framework for Node.js 20+ built with TypeScript.\n\n## Features\n\n- **Express** - Fast, unopinionated web framework for routing and middleware\n- **EJS Templating** - Server-side templating with embedded JavaScript\n- **Prisma ORM** - Type-safe database client (optional, PostgreSQL/MySQL/SQLite support)\n- **Redis Sessions** - Scalable session management with connect-redis\n- **JWT Authentication** - Secure token-based auth with bcrypt password hashing\n- **Session-Based Auth** - Traditional session management with Express-Session\n- **WebAuthn (Passkeys)** - Passwordless authentication with security keys (YubiKey, Touch ID, Face ID)\n- **Tailwind CSS** - Modern, utility-first CSS framework (optional, included with `--with-tailwind`)\n- **Zod Validation** - Type-safe form validation with TypeScript-first schemas\n- **CLI Tools** - Scaffold apps with `--with-tailwind`, generate models/controllers/resources\n- **Flash Messages** - Session-based success/error messages for forms\n- **Cookie Parser** - Built-in cookie parsing for JWT and session support\n- **Helmet Security** - HTTP header security middleware\n- **CORS Support** - Cross-origin resource sharing middleware\n- **GitHub Actions CI** - Automated testing with optional CI setup\n\n## Quick Start\n\n```bash\nnpx @andrewthecoder/erwinmvc init myapp\ncd myapp\nnpm run dev\n```\n\nVisit http://localhost:3000 - your app is running!\n\n## CLI Commands\n\n### Initialize a new app\n\n```bash\n# Basic app\nnpx @andrewthecoder/erwinmvc init myapp\n\n# With Tailwind CSS\nnpx @andrewthecoder/erwinmvc init myapp --with-tailwind\n\n# With database support (Prisma)\nnpx @andrewthecoder/erwinmvc init myapp --with-database\n\n# With database + Tailwind\nnpx @andrewthecoder/erwinmvc init myapp --with-database --with-tailwind\n\n# With GitHub Actions CI\nnpx @andrewthecoder/erwinmvc init myapp --with-ci\n\n# Skip npm install (install manually later)\nnpx @andrewthecoder/erwinmvc init myapp --skip-install\n```\n\n### Generate models\n\n```bash\n# Generate a Prisma model\nnpx erwinmvc generate model User\nnpx erwinmvc g model User\n\n# Generate without running migration\nnpx erwinmvc generate model User --skip-migrate\n```\n\n### Generate controllers\n\n```bash\n# Generate a CRUD controller\nnpx erwinmvc generate controller User\nnpx erwinmvc g controller User\n\n# Generate without views\nnpx erwinmvc generate controller User --no-views\n```\n\n### Generate resources (model + controller + views)\n\n```bash\n# Complete resource with all features\nnpx erwinmvc generate resource Post\nnpx erwinmvc g resource Post\n\n# Skip specific parts\nnpx erwinmvc generate resource Post --skip-model\nnpx erwinmvc generate resource Post --skip-views\nnpx erwinmvc generate resource Post --skip-controller\n\n# Skip database migration\nnpx erwinmvc generate resource Post --skip-migrate\n\n# API-only resource (no views, JSON responses)\nnpx erwinmvc generate resource Post --api-only\n```\n\n### Authentication commands\n\n```bash\n# Generate complete authentication system (login/register)\nnpx erwinmvc make:auth\nnpx erwinmvc ma\n\n# Skip User model (use existing)\nnpx erwinmvc make:auth --without-model\n\n# Only JWT (no sessions)\nnpx erwinmvc make:auth --jwt-only\n\n# Only sessions (no JWT)\nnpx erwinmvc make:auth --session-only\n```\n\n### WebAuthn (Passkeys)\n\n```bash\n# Generate WebAuthn authentication (security key login)\nnpx erwinmvc webauthn\nnpx erwinmvc w\n\n# Skip database migration\nnpx erwinmvc webauthn --skip-migrate\n```\n\n### List routes\n\n```bash\n# Show all defined routes\nnpx erwinmvc list:routes\nnpx erwinmvc lr\n```\n\n## Project Structure\n\n```\nmyapp/\n├── src/\n│   ├── controllers/   # MVC controllers\n│   ├── views/         # EJS templates\n│   └── server.ts      # App entry point\n├── public/            # Static assets\n│   └── dist/          # Compiled CSS (Tailwind)\n├── prisma/            # Database (optional)\n│   └── schema.prisma  # Prisma schema\n├── .github/           # CI workflows (optional)\n├── package.json\n├── tsconfig.json\n├── tailwind.config.ts  # Tailwind config (optional)\n└── postcss.config.cjs  # PostCSS config (optional)\n```\n\n## Database Setup\n\n```bash\n# Setup Prisma database\nnpx erwinmvc init myapp --with-database\ncd myapp\n\n# Edit .env with your DATABASE_URL\n# DATABASE_URL=\"postgresql://user:password@localhost:5432/mydb\"\n\n# Run migrations\nnpx prisma migrate dev --name init\n\n# Generate Prisma client (auto-run by CLI)\nnpx prisma generate\n```\n\n## Tailwind CSS Setup\n\n```bash\nnpx erwinmvc init myapp --with-tailwind\ncd myapp\n\n# Configure content paths in tailwind.config.ts\n# Edit src/assets/tailwind.css for custom styles\n\n# Build CSS\nnpx tailwindcss -i ./src/assets/tailwind.css -o ./public/dist/tailwind.css --watch\n```\n\n## Authentication\n\n### Session + JWT Auth\n\nThe `make:auth` command generates:\n\n- User model with password hashing\n- Register/login forms with Zod validation\n- Session-based authentication\n- JWT token generation for API access\n- Password verification with bcrypt\n- Flash messages for errors/success\n\n### WebAuthn (Passkeys)\n\nThe `webauthn` command generates:\n\n- Passkey registration flow\n- Passkey authentication flow\n- User credential storage in database\n- Security key support (YubiKey, Touch ID, Face ID)\n\n## Validation\n\nUse Zod schemas for type-safe form validation:\n\n```typescript\nimport { z } from \"zod\";\nimport { validate } from \"@andrewthecoder/erwinmvc\";\n\nconst userSchema = z.object({\n  username: z.string().min(3),\n  email: z.string().email(),\n  password: z.string().min(8)\n});\n\napp.post(\"/users\", validate(userSchema), async (req, res) => {\n  const user = req.validatedBody; // Type-safe validated data\n  // ...\n});\n```\n\n## API Reference\n\n### Core Functions\n\n- `createMvcApp(options)` - Create Express app with views, static files\n- `startServer(app)` - Start HTTP server on port 3000\n- `hashPassword(plain)` - Hash password with bcrypt\n- `verifyPassword(plain, hash)` - Verify password\n- `signToken(payload, expiresIn)` - Sign JWT token\n- `verifyToken(token)` - Verify and decode JWT\n- `authenticate` - Express middleware for JWT authentication\n- `validate(schema, strategy)` - Zod validation middleware\n\n### WebAuthn Functions\n\n- `startRegistration(req, res)` - Begin WebAuthn registration\n- `completeRegistration(req, res)` - Complete WebAuthn registration\n- `startAuthentication(req, res)` - Begin WebAuthn login\n- `completeAuthentication(req, res)` - Complete WebAuthn login\n- `getRPConfig()` - Get relying party configuration\n\n### Validation Helpers\n\n- `getFieldErrors(error)` - Extract field errors from Zod error\n- `getOldInput(req)` - Get previously submitted form data\n- `getErrors(req)` - Get flash error messages\n- `hasFieldError(field, errors)` - Check if field has errors\n- `getFieldError(field, errors)` - Get error message for field\n\n## Environment Variables\n\nRequired for full functionality:\n\n```env\n# Required\nJWT_SECRET=your-secret-key-here\n\n# Database (optional)\nDATABASE_URL=postgresql://user:password@localhost:5432/mydb\n\n# WebAuthn (optional, defaults to localhost)\nWEBAUTHN_RP_ID=localhost\nWEBAUTHN_RP_NAME=MyApp\n```\n\n## Testing\n\n```bash\n# Run all tests\nnpm test\n\n# Run specific test file\nnpm test -- auth\nnpm test -- cli\nnpm test -- generators\n\n# With coverage\nnpm run test -- --coverage\n```\n\n## Production Build\n\n```bash\n# Build TypeScript and CLI\nnpm run build\n\n# The app is ready for production deployment\n# Server runs on port 3000\n```\n\n## License\n\nMIT, see [LICENSE](LICENSE).\n\n## Contributing\n\nPRs welcome. Please open an issue first for major changes.\n","readmeFilename":"README.md"}