{"_id":"@adamelshafei/lattice-core","_rev":"3-d952fdc74b3244a68858f0ec438601d3","name":"@adamelshafei/lattice-core","dist-tags":{"latest":"0.1.3"},"versions":{"0.1.1":{"name":"@adamelshafei/lattice-core","version":"0.1.1","keywords":["authorization","rbac","abac","permissions","access-control","saas","multi-tenant","typescript","fastify","express"],"author":{"name":"Adam Elshafei","email":"abdoshafey1@gmail.com"},"license":"MIT","_id":"@adamelshafei/lattice-core@0.1.1","maintainers":[{"name":"adamelshafei","email":"abdoshafey1@gmail.com"}],"homepage":"https://github.com/Adam-shafey/Lattice#readme","bugs":{"url":"https://github.com/Adam-shafey/lattice/issues"},"bin":{"lattice":"dist/core/cli/index.js"},"dist":{"shasum":"0c9a10cf8055c33052b1bfee96c79380db726157","tarball":"https://registry.npmjs.org/@adamelshafei/lattice-core/-/lattice-core-0.1.1.tgz","fileCount":81,"integrity":"sha512-jPvoU1Pi9IfOJUciQ5PitDMhhWcYfBi1tSDjii0Ft0ZUwwCc48hkA658hRfMjfMDHQThoaZI551VkV4R3RwOkQ==","signatures":[{"sig":"MEUCIQDCp/3lZzSfCWEp4pOATpGF+jNMMj7jZt7OoPS0lwqmQwIgWJn+okMJ04Aer2ngOLY9+4t22v5lCVXhAa79FDLz4Dc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":327422},"main":"dist/index.js","type":"commonjs","types":"dist/index.d.ts","prisma":{"seed":"ts-node src/scripts/seed.ts"},"gitHead":"625241fc3f989654e278586ac3bbf94ab8f8c44c","private":false,"scripts":{"cli":"node dist/core/cli/index.js --help","dev":"npm run swagger:gen && ts-node-dev --respawn --transpile-only src/scripts/dev.ts","test":"vitest run","build":"npm run swagger:gen && tsc -p tsconfig.json","start":"node dist/dev.js","prepare":"npm run build","swagger":"ts-node swagger.ts","build:admin":"cd AccessControlUI && npm install && npm run build","prisma:push":"prisma db push","prisma:seed":"prisma db seed","swagger:gen":"ts-node src/scripts/swagger.ts","test:minimal":"vitest run --reporter=basic --silent","policymanager":"ts-node src/scripts/policymanager.ts","dev:with-admin":"npm run build:admin && npm run dev","prepublishOnly":"npm test","prisma:migrate":"prisma migrate dev","prisma:generate":"prisma generate"},"_npmUser":{"name":"adamelshafei","email":"abdoshafey1@gmail.com"},"repository":{"url":"git+https://github.com/Adam-shafey/lattice.git","type":"git"},"_npmVersion":"10.9.2","description":"Permission-first backend framework for SaaS applications. Lego blocks for access control.","directories":{},"_nodeVersion":"22.14.0","dependencies":{"zod":"^3.23.8","cors":"^2.8.5","pino":"^9.9.0","cel-js":"^0.8.2","express":"^4.19.2","fastify":"^5.5.0","bcryptjs":"^2.4.3","minimist":"^1.2.8","@types/cors":"^2.8.19","jsonwebtoken":"^9.0.2","@fastify/cors":"^11.1.0","@prisma/client":"^6.14.0","swagger-autogen":"^2.23.7","@fastify/swagger":"^9.5.1","express-rate-limit":"^8.0.1","@fastify/rate-limit":"^10.3.0","@fastify/swagger-ui":"^5.2.3"},"_hasShrinkwrap":false,"devDependencies":{"prisma":"^6.14.0","vitest":"^1.6.0","ts-node":"^10.9.2","fast-glob":"^3.3.2","typescript":"^5.5.4","@types/node":"^20.14.9","ts-node-dev":"^2.0.0","@types/express":"^4.17.21","@types/bcryptjs":"^2.4.6","@types/minimist":"^1.2.5","@types/jsonwebtoken":"^9.0.6"},"_npmOperationalInternal":{"tmp":"tmp/lattice-core_0.1.1_1755909522985_0.8451379699877397","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@adamelshafei/lattice-core","version":"0.1.2","keywords":["authorization","rbac","abac","permissions","access-control","saas","multi-tenant","typescript","fastify","express"],"author":{"name":"Adam Elshafei","email":"abdoshafey1@gmail.com"},"license":"MIT","_id":"@adamelshafei/lattice-core@0.1.2","maintainers":[{"name":"adamelshafei","email":"abdoshafey1@gmail.com"}],"homepage":"https://github.com/Adam-shafey/Lattice#readme","bugs":{"url":"https://github.com/Adam-shafey/lattice/issues"},"bin":{"lattice":"dist/core/cli/index.js"},"dist":{"shasum":"cd4516996d41a4f751995738616869d8c03b4f17","tarball":"https://registry.npmjs.org/@adamelshafei/lattice-core/-/lattice-core-0.1.2.tgz","fileCount":81,"integrity":"sha512-1LyKwuJivblsFKjo+nPWHpqjyn+c3d+FO1RkFYlY0ayb+PepHJCj/s1lrBQsLZ8ImR/TrBLQLgGDo8A9VEmF9g==","signatures":[{"sig":"MEUCIQC57v7xN76GURzPERPi/qBeyv8c8rXQD5CpafrqsnZ2CwIgA/VaGH+ue3XKAEuy4tBKqbXziiRNQ1f2diGI+lrdaVE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":328385},"main":"dist/index.js","type":"commonjs","types":"dist/index.d.ts","prisma":{"seed":"ts-node src/scripts/seed.ts"},"gitHead":"abd6a6896ebf35b26a2dd76b9e572f57a0dc70fa","private":false,"scripts":{"cli":"node dist/core/cli/index.js --help","dev":"npm run swagger:gen && ts-node-dev --respawn --transpile-only src/scripts/dev.ts","test":"vitest run","build":"npm run swagger:gen && tsc -p tsconfig.json","start":"node dist/dev.js","prepare":"npm run build","swagger":"ts-node swagger.ts","build:admin":"cd AccessControlUI && npm install && npm run build","prisma:push":"prisma db push","prisma:seed":"prisma db seed","swagger:gen":"ts-node src/scripts/swagger.ts","test:minimal":"vitest run --reporter=basic --silent","policymanager":"ts-node src/scripts/policymanager.ts","dev:with-admin":"npm run build:admin && npm run dev","prepublishOnly":"npm test","prisma:migrate":"prisma migrate dev","prisma:generate":"prisma generate"},"_npmUser":{"name":"adamelshafei","email":"abdoshafey1@gmail.com"},"repository":{"url":"git+https://github.com/Adam-shafey/lattice.git","type":"git"},"_npmVersion":"10.9.2","description":"Permission-first backend framework for SaaS applications. Lego blocks for access control.","directories":{},"_nodeVersion":"22.14.0","dependencies":{"zod":"^3.23.8","cors":"^2.8.5","pino":"^9.9.0","cel-js":"^0.8.2","express":"^4.19.2","fastify":"^5.5.0","bcryptjs":"^2.4.3","minimist":"^1.2.8","@types/cors":"^2.8.19","jsonwebtoken":"^9.0.2","@fastify/cors":"^11.1.0","@prisma/client":"^6.14.0","swagger-autogen":"^2.23.7","@fastify/swagger":"^9.5.1","express-rate-limit":"^8.0.1","@fastify/rate-limit":"^10.3.0","@fastify/swagger-ui":"^5.2.3"},"_hasShrinkwrap":false,"devDependencies":{"prisma":"^6.14.0","vitest":"^1.6.0","ts-node":"^10.9.2","fast-glob":"^3.3.2","typescript":"^5.5.4","@types/node":"^20.14.9","ts-node-dev":"^2.0.0","@types/express":"^4.17.21","@types/bcryptjs":"^2.4.6","@types/minimist":"^1.2.5","@types/jsonwebtoken":"^9.0.6"},"_npmOperationalInternal":{"tmp":"tmp/lattice-core_0.1.2_1755910043581_0.026212217643887037","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@adamelshafei/lattice-core","version":"0.1.3","private":false,"type":"commonjs","main":"dist/index.js","types":"dist/index.d.ts","bin":{"lattice":"dist/core/cli/index.js"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/Adam-shafey/lattice.git"},"author":{"name":"Adam Elshafei","email":"abdoshafey1@gmail.com"},"homepage":"https://github.com/Adam-shafey/Lattice#readme","bugs":{"url":"https://github.com/Adam-shafey/lattice/issues"},"keywords":["authorization","rbac","abac","permissions","access-control","saas","multi-tenant","typescript","fastify","express"],"description":"Permission-first backend framework for SaaS applications. Lego blocks for access control.","scripts":{"swagger:gen":"ts-node src/scripts/swagger.ts","build":"npm run swagger:gen && tsc -p tsconfig.json","build:admin":"cd AccessControlUI && npm install && npm run build","dev":"npm run swagger:gen && ts-node-dev --respawn --transpile-only src/scripts/dev.ts","dev:with-admin":"npm run build:admin && npm run dev","start":"node dist/dev.js","cli":"node dist/core/cli/index.js --help","prisma:generate":"prisma generate","prisma:push":"prisma db push","prisma:migrate":"prisma migrate dev","prisma:seed":"prisma db seed","test":"vitest run","test:minimal":"vitest run --reporter=basic --silent","swagger":"ts-node swagger.ts","policymanager":"ts-node src/scripts/policymanager.ts","prepare":"npm run build","prepublishOnly":"npm test"},"dependencies":{"@fastify/cors":"^11.1.0","@fastify/rate-limit":"^10.3.0","@fastify/swagger":"^9.5.1","@fastify/swagger-ui":"^5.2.3","@prisma/client":"^6.14.0","@types/cors":"^2.8.19","bcryptjs":"^2.4.3","cel-js":"^0.8.2","cors":"^2.8.5","express":"^4.19.2","express-rate-limit":"^8.0.1","fastify":"^5.5.0","jsonwebtoken":"^9.0.2","minimist":"^1.2.8","pino":"^9.9.0","swagger-autogen":"^2.23.7","zod":"^3.23.8"},"devDependencies":{"@types/bcryptjs":"^2.4.6","@types/express":"^4.17.21","@types/jsonwebtoken":"^9.0.6","@types/minimist":"^1.2.5","@types/node":"^20.14.9","fast-glob":"^3.3.2","prisma":"^6.14.0","ts-node":"^10.9.2","ts-node-dev":"^2.0.0","typescript":"^5.5.4","vitest":"^1.6.0"},"prisma":{"seed":"ts-node src/scripts/seed.ts"},"_id":"@adamelshafei/lattice-core@0.1.3","gitHead":"40a0d8ade054e2e4c25b263183c04391e6df6244","_nodeVersion":"22.14.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-EG+H7H9rWgN9hPnQOzF7/UZyZqJKYNgcBhZd/UX9l4S0NZ/d+oLNTM0V4WYGyRIDwgN/nf/Js85TNiW+L7i/IA==","shasum":"947b8b5165ff00a7f348cfd7a1842ebd275912c4","tarball":"https://registry.npmjs.org/@adamelshafei/lattice-core/-/lattice-core-0.1.3.tgz","fileCount":82,"unpackedSize":333039,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAXDzEW+ppbLqTncr56NVcHCs4qZAQKy0a1fAmGe+pwRAiEA5Uq1vf4SZQs04VCGEnYW0kaDgXLJLN6B4EZXChI+4RA="}]},"_npmUser":{"name":"adamelshafei","email":"abdoshafey1@gmail.com"},"directories":{},"maintainers":[{"name":"adamelshafei","email":"abdoshafey1@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/lattice-core_0.1.3_1755910495881_0.4343579656707448"},"_hasShrinkwrap":false}},"time":{"created":"2025-08-23T00:38:42.916Z","modified":"2025-08-23T00:54:56.236Z","0.1.1":"2025-08-23T00:38:43.200Z","0.1.2":"2025-08-23T00:47:23.777Z","0.1.3":"2025-08-23T00:54:56.072Z"},"bugs":{"url":"https://github.com/Adam-shafey/lattice/issues"},"author":{"name":"Adam Elshafei","email":"abdoshafey1@gmail.com"},"license":"MIT","homepage":"https://github.com/Adam-shafey/Lattice#readme","keywords":["authorization","rbac","abac","permissions","access-control","saas","multi-tenant","typescript","fastify","express"],"repository":{"type":"git","url":"git+https://github.com/Adam-shafey/lattice.git"},"description":"Permission-first backend framework for SaaS applications. Lego blocks for access control.","maintainers":[{"name":"adamelshafei","email":"abdoshafey1@gmail.com"}],"readme":"# Lattice\r\n\r\n> **Lego blocks for access control**\r\n\r\n⚠️ **Beta:** Lattice is still evolving. Expect changes in APIs and features before a stable release.\r\n\r\n---\r\n\r\n## Why Lattice?\r\n\r\nBuilding SaaS apps usually means wrestling with:\r\n\r\n* Users in multiple orgs\r\n* Roles that shift across teams, projects, or orgs\r\n* Rules like *“only managers can approve expenses during business hours”*\r\n* That *one extra role* that breaks everything\r\n\r\nTraditional patterns often lead to:\r\n\r\n* ❌ Hard-coded permission checks everywhere\r\n* ❌ Role hierarchies too messy to maintain\r\n* ❌ Inconsistent security holes\r\n* ❌ Debugging rabbit holes\r\n\r\n**Lattice simplifies the model**: permissions are the building block, everything else builds on top.\r\n\r\n---\r\n\r\n## What You Get\r\n\r\n* 🔑 **Permission-first** → one consistent entry point for access decisions\r\n* 🌐 **Context-aware** → orgs, teams, projects, or any custom scope\r\n* ⚡ **Pluggable** → extend with modules, no core rewrites\r\n* 🧩 **Stack-agnostic** → Fastify, Express, Postgres, SQLite\r\n* 🔍 **RBAC + ABAC** → start simple, add complexity only when you need it\r\n* 🚀 **DX-focused** → CLI, TypeScript types, hot reload\r\n\r\n---\r\n\r\n## 🧠 Mental Model\r\n\r\nEvery check = `(ActionType:ActionId, ContextType:ContextId)`\r\n\r\n* **Permissions** → atomic actions (`users:read`, `projects:create`)\r\n* **Roles** → bundles of permissions, scoped by context\r\n* **Contexts** → the “where” (`org_123`, `team_456`)\r\n* **Context Types** → the shape of the scope (`Organization`, `Team`, `Project`)\r\n* **Policies** → business rules layered on top (e.g. *approve only during business hours*)\r\n\r\n🔑 Think of it like this:\r\n\r\n* Permissions = building blocks\r\n* Roles = buildings consisting of blocks\r\n* Contexts = towns of buildings\r\n* Policies = traffice rules\r\n\r\n---\r\n\r\n## 🚀 Quick Start\r\n\r\n```bash\r\nnpm install @adamelshafei/lattice-core\r\n```\r\n\r\n### Setup Database\r\n\r\n```bash\r\n# Copy the Prisma schema to your project\r\ncp node_modules/@adamelshafei/lattice-core/prisma/schema.prisma ./prisma/\r\n\r\n# Generate Prisma client\r\nnpx prisma generate\r\n\r\n# Push schema to database\r\nnpx prisma db push\r\n```\r\n\r\n### Use in Your App\r\n\r\n```ts\r\nimport { Lattice } from '@adamelshafei/lattice-core'\r\n\r\nconst app = Lattice({\r\n  db: { provider: 'postgres', url: process.env.DATABASE_URL },\r\n  adapter: 'fastify',\r\n  jwt: { accessTTL: '15m', refreshTTL: '7d' },\r\n  apiConfig: { apiPrefix: '/api' }\r\n});\r\n\r\nawait app.listen(3000);\r\n```\r\n\r\n---\r\n\r\n## 💡 Example\r\n\r\n```ts\r\n// Route with a simple permission\r\napp.route({\r\n  method: 'GET',\r\n  path: '/users/:id',\r\n  preHandler: app.routeAuth('users:read'),\r\n  handler: async ({ params }) => ({ id: params.id })\r\n});\r\n\r\n// Context-aware rule\r\napp.route({\r\n  method: 'POST',\r\n  path: '/teams/:teamId/users',\r\n  preHandler: app.routeAuth('users:create', { scope: 'exact' }),\r\n  handler: async () => ({ success: true })\r\n});\r\n```\r\n\r\n---\r\n\r\n## 🛡️ Policy Management\r\n\r\nLattice protects every built‑in route with a permission rule.  \r\nThe `defaultRoutePermissionPolicy` maps common actions to the permissions they require, like:\r\n\r\n```ts\r\ndefaultRoutePermissionPolicy = {\r\n  roles: { create: 'roles:{type}:create', assign: 'roles:assign:{type}' },\r\n  users: { list: 'users:read', delete: 'users:delete' },\r\n  contexts: { create: 'contexts:create', addUser: 'contexts:assign' }\r\n};\r\n```\r\n\r\nTo customize these requirements, pass a partial policy when creating the app.  \r\nAny fields you provide override the defaults:\r\n\r\n```ts\r\nimport { Lattice } from '@adamelshafei/lattice-core';\r\n\r\nconst app = Lattice({\r\n  /* ... */\r\n  policy: {\r\n    users: { list: 'users:list' }\r\n  }\r\n});\r\n```\r\n\r\nYou can also build a complete policy separately:\r\n\r\n```ts\r\nimport { createRoutePermissionPolicy } from '@adamelshafei/lattice-core';\r\n\r\nconst policy = createRoutePermissionPolicy({\r\n  users: { delete: 'users:terminate' }\r\n});\r\n```\r\n\r\n---\r\n\r\n## 🤝 Contributing\r\n\r\nWe’re aiming to make access control less painful and more fun to work with.\r\nWhether it’s a bug, feature, or idea contributions are welcome.\r\n","readmeFilename":"README.md"}