UNPKG

permix

Version:

Permix is a lightweight, framework-agnostic, type-safe permissions management library for JavaScript applications on the client and server sides.

104 lines (103 loc) 2.77 kB
import { PermixNotFoundError, createCheckContext, createHooks, createPermix as createPermix$1, createTemplate } from "../core/index.mjs"; //#region src/server/permix.ts function buildPermix(resolveKey, options = {}) { const onForbidden = options.onForbidden ?? (() => new Response(JSON.stringify({ error: "Forbidden" }), { status: 403, headers: { "Content-Type": "application/json" } })); const hooks = createHooks(); function get(req) { return req[resolveKey()] ?? null; } function getOrThrow(req) { const instance = get(req); if (!instance) throw new PermixNotFoundError(resolveKey()); return instance; } function setupMiddleware(callbackOrRules) { return async (req, next) => { const instance = createPermix$1(typeof callbackOrRules === "function" ? await callbackOrRules({ req, next }) : callbackOrRules); instance.hook("check", (context) => hooks.callHook("check", context)); req[resolveKey()] = instance; return next(); }; } const checkMiddleware = (...args) => { return async (req, next) => { const permix = get(req); if (!permix) throw new PermixNotFoundError(resolveKey()); if (!permix.check(...args)) return await onForbidden({ req, next, ...createCheckContext(...args) }); return next(); }; }; function getRules(req) { return get(req)?.getRules() ?? null; } function template(rules) { return createTemplate(rules); } return { setupMiddleware, checkMiddleware, template, get, getOrThrow, getRules, hook: hooks.hook, hookOnce: hooks.hookOnce, get key() { return resolveKey(); }, $inferDefinition: void 0, $inferPath: void 0 }; } /** * Create a middleware factory that wires Permix into fetch-style request handlers. * * Middleware follows the web-standard `(req, next) => Response` pattern used by * [srvx](https://github.com/h3js/srvx) and similar runtimes. * * Call `.contextKey('name')` to set a custom request key. Omit it to use a * fresh `Symbol('permix')` as the default key. * * @example * ```ts * import { serve } from 'srvx' * import { createPermix } from 'permix/server' * * const permix = createPermix<Def>() * * serve({ * middleware: [ * permix.setupMiddleware(({ req }) => ({ * post: { create: true, read: true, update: false, delete: false }, * })), * ], * fetch(req) { * return permix.checkMiddleware('post.create')(req, () => * Response.json({ ok: true }), * ) * }, * }) * ``` * * @link https://permix.letstri.dev/docs/integrations/server */ function createPermix(options = {}) { let key = Symbol("permix"); const permix = buildPermix(() => key, options); return Object.assign(permix, { contextKey(newKey) { key = newKey; return permix; } }); } //#endregion export { createPermix };