UNPKG

permix

Version:

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

94 lines (93 loc) 2.46 kB
import { PermixNotFoundError, createCheckContext, createHooks, createPermix as createPermix$1, createTemplate } from "../core/index.mjs"; import { TRPCError, initTRPC } from "@trpc/server"; //#region src/trpc/permix.ts function buildPermix(resolveKey, options = {}) { const forbiddenHandler = options.onForbidden ?? (() => { throw new TRPCError({ code: "FORBIDDEN", message: "You do not have permission to perform this action" }); }); const hooks = createHooks(); const t = initTRPC.context().create(); function setupContext(rules) { const instance = createPermix$1(rules); instance.hook("check", (context) => hooks.callHook("check", context)); return { [resolveKey()]: instance }; } function checkMiddleware(...args) { return t.middleware(async (opts) => { const instance = opts.ctx[resolveKey()]; if (!instance) throw new PermixNotFoundError(resolveKey()); if (instance.check(...args)) return opts.next(); return forbiddenHandler({ ...opts, ...createCheckContext(...args) }); }); } function getRules(ctx) { return ctx[resolveKey()]?.getRules() ?? null; } function template(rules) { return createTemplate(rules); } return { setupContext, checkMiddleware, getRules, template, hook: hooks.hook, hookOnce: hooks.hookOnce, get key() { return resolveKey(); }, $inferDefinition: void 0, $inferPath: void 0 }; } /** * Create a middleware factory that wires Permix into tRPC procedures. * * Use `.contextKey('name')` to set a custom context key (its literal type is * inferred automatically). Defaults to `'permix'`. * * @example * ```ts * import { initTRPC } from '@trpc/server' * import { createPermix } from 'permix/trpc' * * const permix = createPermix<{ * post: ['create', 'read'] * }>() * * const t = initTRPC.context<Context>().create() * * const trpc = t.procedure * .use(({ next }) => { * return next({ * ctx: permix.setupContext({ * post: { create: true }, * }), * }) * }) * * export const router = trpc.router({ * createPost: trpc * .use(permix.checkMiddleware('post.create')) * .mutation(({ ctx }) => { ... }), * }) * ``` * * @link https://permix.letstri.dev/docs/integrations/trpc */ function createPermix(options = {}) { let key = "permix"; const permix = buildPermix(() => key, options); return Object.assign(permix, { contextKey(newKey) { key = newKey; return permix; } }); } //#endregion export { createPermix };