permix
Version:
Permix is a lightweight, framework-agnostic, type-safe permissions management library for JavaScript applications on the client and server sides.
87 lines (86 loc) • 2.33 kB
JavaScript
import { PermixNotFoundError, createCheckContext, createHooks, createPermix as createPermix$1, createTemplate } from "../core/index.mjs";
import { ORPCError, os } from "@orpc/server";
//#region src/orpc/permix.ts
function buildPermix(resolveKey, options = {}) {
const forbiddenHandler = options.onForbidden ?? (() => {
throw new ORPCError("FORBIDDEN", { message: "You do not have permission to perform this action" });
});
const hooks = createHooks();
const plugin = os.$context();
function setupContext(rules) {
const instance = createPermix$1(rules);
instance.hook("check", (context) => hooks.callHook("check", context));
return { [resolveKey()]: instance };
}
function checkMiddleware(...args) {
return plugin.middleware(async (opts) => {
const instance = opts.context[resolveKey()];
if (!instance) throw new PermixNotFoundError(resolveKey());
if (instance.check(...args)) return opts.next();
return forbiddenHandler({
...opts,
...createCheckContext(...args)
});
});
}
function getRules(context) {
return context[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 oRPC procedures.
*
* Use `.contextKey('name')` to set a custom context key (its literal type is
* inferred automatically). Defaults to `'permix'`.
*
* @example
* ```ts
* import { os } from '@orpc/server'
* import { createPermix } from 'permix/orpc'
*
* const permix = createPermix<{
* post: ['create']
* }>()
*
* const orpc = os
* .use(({ next }) => {
* return next({
* context: permix.setupContext({
* post: { create: true }
* }),
* })
* })
*
* export const createPost = orpc
* .use(permix.checkMiddleware('post.create'))
* .handler(() => { ... })
* ```
*
* @link https://permix.letstri.dev/docs/integrations/orpc
*/
function createPermix(options = {}) {
let key = "permix";
const permix = buildPermix(() => key, options);
return Object.assign(permix, { contextKey(newKey) {
key = newKey;
return permix;
} });
}
//#endregion
export { createPermix };