acl-next 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/middleware.ts","../src/acl.ts","../src/backends/memory.ts","../src/backends/redis.ts","../src/backends/mongodb.ts","../src/index.ts"],"names":["_a","_b","result","toArray","union","toStr"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Acl } from \"./acl.js\";\nimport type { OneOrMany, Permission, UserId } from \"./types.js\";\n\n/**\n * Minimal structural request shape the middleware needs. Compatible with\n * Express (and most HTTP frameworks) without depending on their types.\n */\nexport interface AclRequest {\n originalUrl?: string;\n url?: string;\n method: string;\n session?: { userId?: UserId };\n user?: { id?: UserId };\n}\n\nexport interface AclResponse {\n status(code: number): {\n end(body?: string): unknown;\n json(body: unknown): unknown;\n send(body: unknown): unknown;\n };\n}\n\nexport type AclNext = (err?: unknown) => void;\n\nexport type AclMiddleware = (req: AclRequest, res: AclResponse, next: AclNext) => void;\n\n/** Resolves the userId for a request when not supplied statically. */\nexport type UserIdResolver = (req: AclRequest, res: AclResponse) => UserId | undefined;\n\n/** Error thrown by the middleware; pair it with {@link aclErrorHandler}. */\nexport class HttpError extends Error {\n readonly errorCode: number;\n override readonly name = \"HttpError\";\n\n constructor(errorCode: number, message: string) {\n super(message);\n this.errorCode = errorCode;\n }\n}\n\n/**\n * Build an Express-style middleware that authorizes the current request.\n *\n * @param acl The Acl instance to check against.\n * @param numPathComponents How many leading URL path components form the\n * resource name (default: the whole path).\n * @param userId A static user id, or a resolver `(req, res) => id`.\n * Defaults to `req.session.userId` / `req.user.id`.\n * @param actions Permission(s) to check (default: the HTTP method).\n */\nexport function aclMiddleware(\n acl: Acl,\n numPathComponents?: number,\n userId?: UserId | UserIdResolver,\n actions?: OneOrMany<Permission>,\n): AclMiddleware {\n return (req, res, next) => {\n let resolvedUserId: UserId | undefined;\n if (typeof userId === \"function\") {\n resolvedUserId = userId(req, res);\n } else if (userId !== undefined) {\n resolvedUserId = userId;\n } else {\n resolvedUserId = req.session?.userId ?? req.user?.id;\n }\n\n if (resolvedUserId === undefined || resolvedUserId === null) {\n next(new HttpError(401, \"User not authenticated\"));\n return;\n }\n\n const fullUrl = (req.originalUrl ?? req.url ?? \"\").split(\"?\")[0] ?? \"\";\n const resource = numPathComponents\n ? fullUrl\n .split(\"/\")\n .slice(0, numPathComponents + 1)\n .join(\"/\")\n : fullUrl;\n\n const resolvedActions = actions ?? req.method.toLowerCase();\n\n acl.logger?.debug(`Requesting ${resolvedActions} on ${resource} by user ${resolvedUserId}`);\n\n acl.isAllowed(resolvedUserId, resource, resolvedActions).then(\n (allowed) => {\n if (allowed) {\n acl.logger?.debug(`Allowed ${resolvedActions} on ${resource} by user ${resolvedUserId}`);\n next();\n } else {\n acl.logger?.debug(\n `Not allowed ${resolvedActions} on ${resource} by user ${resolvedUserId}`,\n );\n next(new HttpError(403, \"Insufficient permissions to access resource\"));\n }\n },\n () => next(new Error(\"Error checking permissions to access resource\")),\n );\n };\n}\n\n/**\n * Express error handler that renders {@link HttpError}s. Pass `\"json\"` or\n * `\"html\"` to choose the response format (defaults to plain text).\n */\nexport function aclErrorHandler(\n contentType?: \"json\" | \"html\",\n): (err: unknown, req: AclRequest, res: AclResponse, next: AclNext) => void {\n return (err, _req, res, next) => {\n if (!(err instanceof HttpError) || !err.errorCode) {\n next(err);\n return;\n }\n const response = res.status(err.errorCode);\n if (contentType === \"json\") {\n response.json({ message: err.message });\n } else if (contentType === \"html\") {\n response.send(err.message);\n } else {\n response.end(err.message);\n }\n };\n}\n","import { type AclMiddleware, type UserIdResolver, aclMiddleware } from \"./middleware.js\";\nimport type {\n AclOptions,\n AllowRule,\n Backend,\n Buckets,\n Logger,\n OneOrMany,\n Permission,\n Resource,\n Role,\n UserId,\n} from \"./types.js\";\n\nconst DEFAULT_BUCKETS: Buckets = {\n meta: \"meta\",\n parents: \"parents\",\n permissions: \"permissions\",\n resources: \"resources\",\n roles: \"roles\",\n users: \"users\",\n};\n\nconst toArray = <T>(value: OneOrMany<T>): T[] => (Array.isArray(value) ? value : [value]);\n\n/** Set-union of two arrays, preserving first-seen order. */\nconst union = <T>(a: readonly T[], b: readonly T[]): T[] => [...new Set([...a, ...b])];\n\n/** The per-resource permissions bucket name (e.g. `allows_blogs`). */\nconst allowsBucket = (resource: Resource): string => `allows_${resource}`;\n\nconst keyFromAllowsBucket = (bucket: string): string => bucket.replace(/^allows_/, \"\");\n\n/**\n * Access Control List. Models authorization as users -> roles -> resources ->\n * permissions, with role hierarchies (parents).\n *\n * Promise-native: every method returns a Promise (the legacy callback API is\n * intentionally dropped). Storage is delegated to a {@link Backend}.\n *\n * @typeParam T - the backend transaction type.\n */\nexport class Acl<T = unknown> {\n readonly backend: Backend<T>;\n readonly logger: Logger | undefined;\n readonly buckets: Buckets;\n\n constructor(backend: Backend<T>, logger?: Logger, options?: AclOptions) {\n this.backend = backend;\n this.logger = logger;\n this.buckets = { ...DEFAULT_BUCKETS, ...options?.buckets };\n }\n\n /** Adds roles to a given user id. */\n async addUserRoles(userId: UserId, roles: OneOrMany<Role>): Promise<void> {\n const transaction = this.backend.begin();\n this.backend.add(transaction, this.buckets.meta, \"users\", userId);\n this.backend.add(transaction, this.buckets.users, userId, roles);\n for (const role of toArray(roles)) {\n this.backend.add(transaction, this.buckets.roles, role, userId);\n }\n await this.backend.end(transaction);\n }\n\n /** Removes roles from a given user id. */\n async removeUserRoles(userId: UserId, roles: OneOrMany<Role>): Promise<void> {\n const transaction = this.backend.begin();\n this.backend.remove(transaction, this.buckets.users, userId, roles);\n for (const role of toArray(roles)) {\n this.backend.remove(transaction, this.buckets.roles, role, userId);\n }\n await this.backend.end(transaction);\n }\n\n /** Returns all the roles assigned to a given user id. */\n userRoles(userId: UserId): Promise<Role[]> {\n return this.backend.get(this.buckets.users, userId);\n }\n\n /** Returns all users that have the given role. */\n roleUsers(roleName: Role): Promise<UserId[]> {\n return this.backend.get(this.buckets.roles, roleName);\n }\n\n /** Returns whether the user has the given role. */\n async hasRole(userId: UserId, role: Role): Promise<boolean> {\n const roles = await this.userRoles(userId);\n return roles.includes(role);\n }\n\n /** Adds one or more parent roles to a role. */\n async addRoleParents(role: Role, parents: OneOrMany<Role>): Promise<void> {\n const transaction = this.backend.begin();\n this.backend.add(transaction, this.buckets.meta, \"roles\", role);\n this.backend.add(transaction, this.buckets.parents, role, parents);\n await this.backend.end(transaction);\n }\n\n /** Removes parent role(s) from a role. Omit `parents` to remove all of them. */\n async removeRoleParents(role: Role, parents?: OneOrMany<Role>): Promise<void> {\n const transaction = this.backend.begin();\n if (parents !== undefined) {\n this.backend.remove(transaction, this.buckets.parents, role, parents);\n } else {\n this.backend.del(transaction, this.buckets.parents, role);\n }\n await this.backend.end(transaction);\n }\n\n /** Removes a role from the system, including all its permissions. */\n async removeRole(role: Role): Promise<void> {\n // Note: this is not fully transactional.\n const resources = await this.backend.get(this.buckets.resources, role);\n const transaction = this.backend.begin();\n\n for (const resource of resources) {\n this.backend.del(transaction, allowsBucket(resource), role);\n }\n\n this.backend.del(transaction, this.buckets.resources, role);\n this.backend.del(transaction, this.buckets.parents, role);\n this.backend.del(transaction, this.buckets.roles, role);\n this.backend.remove(transaction, this.buckets.meta, \"roles\", role);\n\n // The `users` bucket keeps the removed role: we don't know which users\n // have it assigned.\n await this.backend.end(transaction);\n }\n\n /** Removes a resource from the system. */\n async removeResource(resource: Resource): Promise<void> {\n const roles = await this.backend.get(this.buckets.meta, \"roles\");\n const transaction = this.backend.begin();\n this.backend.del(transaction, allowsBucket(resource), roles);\n for (const role of roles) {\n this.backend.remove(transaction, this.buckets.resources, role, resource);\n }\n await this.backend.end(transaction);\n }\n\n /** Adds permissions to roles over resources (compact array form). */\n allow(rules: AllowRule[]): Promise<void>;\n /** Adds the given permissions to the given roles over the given resources. */\n allow(\n roles: OneOrMany<Role>,\n resources: OneOrMany<Resource>,\n permissions: OneOrMany<Permission>,\n ): Promise<void>;\n async allow(\n roles: AllowRule[] | OneOrMany<Role>,\n resources?: OneOrMany<Resource>,\n permissions?: OneOrMany<Permission>,\n ): Promise<void> {\n if (resources === undefined) {\n return this.allowEx(roles as AllowRule[]);\n }\n\n const rolesArr = toArray(roles as OneOrMany<Role>);\n const resourcesArr = toArray(resources);\n const transaction = this.backend.begin();\n\n this.backend.add(transaction, this.buckets.meta, \"roles\", rolesArr);\n\n for (const resource of resourcesArr) {\n for (const role of rolesArr) {\n this.backend.add(\n transaction,\n allowsBucket(resource),\n role,\n permissions as OneOrMany<Permission>,\n );\n }\n }\n for (const role of rolesArr) {\n this.backend.add(transaction, this.buckets.resources, role, resourcesArr);\n }\n\n await this.backend.end(transaction);\n }\n\n /** Removes permissions from a role over resources. Omit `permissions` to remove all. */\n removeAllow(\n role: Role,\n resources: OneOrMany<Resource>,\n permissions?: OneOrMany<Permission>,\n ): Promise<void> {\n return this.removePermissions(\n role,\n toArray(resources),\n permissions !== undefined ? toArray(permissions) : null,\n );\n }\n\n /**\n * Removes permissions from a role over the given resources. When\n * `permissions` is null the resource is fully revoked for the role.\n *\n * Note: loses atomicity when pruning emptied role/resource links.\n */\n async removePermissions(\n role: Role,\n resources: Resource[],\n permissions: Permission[] | null,\n ): Promise<void> {\n const transaction = this.backend.begin();\n for (const resource of resources) {\n const bucket = allowsBucket(resource);\n if (permissions) {\n this.backend.remove(transaction, bucket, role, permissions);\n } else {\n this.backend.del(transaction, bucket, role);\n this.backend.remove(transaction, this.buckets.resources, role, resource);\n }\n }\n await this.backend.end(transaction);\n\n // Remove the resource from the role when no rights remain. Not atomic.\n const cleanup = this.backend.begin();\n await Promise.all(\n resources.map(async (resource) => {\n const remaining = await this.backend.get(allowsBucket(resource), role);\n if (remaining.length === 0) {\n this.backend.remove(cleanup, this.buckets.resources, role, resource);\n }\n }),\n );\n await this.backend.end(cleanup);\n }\n\n /**\n * Returns, per resource, the permissions a user has. Uses the backend's\n * `unions` optimization when available.\n */\n async allowedPermissions(\n userId: UserId,\n resources: OneOrMany<Resource>,\n ): Promise<Record<Resource, Permission[]>> {\n if (!userId) {\n return {};\n }\n if (this.backend.unions) {\n return this.optimizedAllowedPermissions(userId, resources);\n }\n\n const resourcesArr = toArray(resources);\n const roles = await this.userRoles(userId);\n const result: Record<Resource, Permission[]> = {};\n await Promise.all(\n resourcesArr.map(async (resource) => {\n result[resource] = await this.resourcePermissions(roles, resource);\n }),\n );\n return result;\n }\n\n /** `allowedPermissions` variant using the backend `unions` bulk query. */\n async optimizedAllowedPermissions(\n userId: UserId,\n resources: OneOrMany<Resource>,\n ): Promise<Record<Resource, Permission[]>> {\n if (!userId) {\n return {};\n }\n const resourcesArr = toArray(resources);\n const roles = await this.allUserRoles(userId);\n const buckets = resourcesArr.map(allowsBucket);\n\n const response =\n roles.length === 0\n ? Object.fromEntries(buckets.map((bucket) => [bucket, [] as Permission[]]))\n : // biome-ignore lint/style/noNonNullAssertion: guarded by the `this.backend.unions` caller\n await this.backend.unions!(buckets, roles);\n\n const result: Record<Resource, Permission[]> = {};\n for (const bucket of Object.keys(response)) {\n result[keyFromAllowsBucket(bucket)] = response[bucket] ?? [];\n }\n return result;\n }\n\n /** Checks if a user is allowed all of the given permissions on a resource. */\n async isAllowed(\n userId: UserId,\n resource: Resource,\n permissions: OneOrMany<Permission>,\n ): Promise<boolean> {\n const roles = await this.backend.get(this.buckets.users, userId);\n if (roles.length) {\n return this.areAnyRolesAllowed(roles, resource, permissions);\n }\n return false;\n }\n\n /** Returns true if any of the roles has all of the given permissions. */\n areAnyRolesAllowed(\n roles: OneOrMany<Role>,\n resource: Resource,\n permissions: OneOrMany<Permission>,\n ): Promise<boolean> {\n const rolesArr = toArray(roles);\n const permsArr = toArray(permissions);\n if (rolesArr.length === 0) {\n return Promise.resolve(false);\n }\n return this.checkPermissions(rolesArr, resource, permsArr);\n }\n\n /** Returns a map of resource -> permissions the roles have. */\n whatResources(roles: OneOrMany<Role>): Promise<Record<Resource, Permission[]>>;\n /** Returns the resources the roles have all of the given permissions over. */\n whatResources(roles: OneOrMany<Role>, permissions: OneOrMany<Permission>): Promise<Resource[]>;\n whatResources(\n roles: OneOrMany<Role>,\n permissions?: OneOrMany<Permission>,\n ): Promise<Record<Resource, Permission[]> | Resource[]> {\n const rolesArr = toArray(roles);\n const perms = permissions === undefined ? undefined : toArray(permissions);\n return this.permittedResources(rolesArr, perms);\n }\n\n /** Backing implementation for {@link whatResources}. */\n async permittedResources(\n roles: OneOrMany<Role>,\n permissions?: Permission[],\n ): Promise<Record<Resource, Permission[]> | Resource[]> {\n const rolesArr = toArray(roles);\n const resources = await this.rolesResources(rolesArr);\n\n if (permissions === undefined) {\n const result: Record<Resource, Permission[]> = {};\n await Promise.all(\n resources.map(async (resource) => {\n result[resource] = await this.resourcePermissions(rolesArr, resource);\n }),\n );\n return result;\n }\n\n const result: Resource[] = [];\n await Promise.all(\n resources.map(async (resource) => {\n const p = await this.resourcePermissions(rolesArr, resource);\n if (permissions.some((perm) => p.includes(perm))) {\n result.push(resource);\n }\n }),\n );\n return result;\n }\n\n /**\n * Express-style middleware that authorizes the current request against this\n * Acl. See {@link aclMiddleware} for parameter semantics. Pair with\n * {@link aclErrorHandler} to render the resulting 401/403 errors.\n */\n middleware(\n numPathComponents?: number,\n userId?: UserId | UserIdResolver,\n actions?: OneOrMany<Permission>,\n ): AclMiddleware {\n return aclMiddleware(this as unknown as Acl, numPathComponents, userId, actions);\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n /** Compact array form of {@link allow}. */\n private async allowEx(rules: OneOrMany<AllowRule>): Promise<void> {\n const demuxed: Array<{\n roles: OneOrMany<Role>;\n resources: OneOrMany<Resource>;\n permissions: OneOrMany<Permission>;\n }> = [];\n\n for (const rule of toArray(rules)) {\n for (const a of rule.allows) {\n demuxed.push({ roles: rule.roles, resources: a.resources, permissions: a.permissions });\n }\n }\n\n // Sequential to mirror the legacy bluebird.reduce.\n for (const d of demuxed) {\n await this.allow(d.roles, d.resources, d.permissions);\n }\n }\n\n /** Direct parents of the given roles. */\n private rolesParents(roles: Role[]): Promise<Role[]> {\n return this.backend.union(this.buckets.parents, roles);\n }\n\n /** All roles in the hierarchy, including the given roles. */\n private async allRoles(roleNames: Role[]): Promise<Role[]> {\n const parents = await this.rolesParents(roleNames);\n if (parents.length > 0) {\n const parentRoles = await this.allRoles(parents);\n return union(roleNames, parentRoles);\n }\n return roleNames;\n }\n\n /** All roles in the hierarchy of the given user. */\n private async allUserRoles(userId: UserId): Promise<Role[]> {\n const roles = await this.userRoles(userId);\n if (roles && roles.length > 0) {\n return this.allRoles(roles);\n }\n return [];\n }\n\n /** All resources reachable by the given roles (through the hierarchy). */\n private async rolesResources(roles: OneOrMany<Role>): Promise<Resource[]> {\n const allRoles = await this.allRoles(toArray(roles));\n const result: Resource[] = [];\n await Promise.all(\n allRoles.map(async (role) => {\n const resources = await this.backend.get(this.buckets.resources, role);\n result.push(...resources);\n }),\n );\n return result;\n }\n\n /** Permissions the given roles (and their parents) have over a resource. */\n private async resourcePermissions(roles: Role[], resource: Resource): Promise<Permission[]> {\n if (roles.length === 0) {\n return [];\n }\n const resourcePermissions = await this.backend.union(allowsBucket(resource), roles);\n const parents = await this.rolesParents(roles);\n if (parents?.length) {\n const morePermissions = await this.resourcePermissions(parents, resource);\n return union(resourcePermissions, morePermissions);\n }\n return resourcePermissions;\n }\n\n /**\n * Whether the roles (and their parents) satisfy all permissions on a resource.\n *\n * NOTE: does not handle circular role hierarchies.\n */\n private async checkPermissions(\n roles: Role[],\n resource: Resource,\n permissions: Permission[],\n ): Promise<boolean> {\n const resourcePermissions = await this.backend.union(allowsBucket(resource), roles);\n\n if (resourcePermissions.includes(\"*\")) {\n return true;\n }\n\n const remaining = permissions.filter((p) => !resourcePermissions.includes(p));\n if (remaining.length === 0) {\n return true;\n }\n\n const parents = await this.backend.union(this.buckets.parents, roles);\n if (parents?.length) {\n return this.checkPermissions(parents, resource, remaining);\n }\n return false;\n }\n}\n","import type { Backend, Key, OneOrMany, StoredValue } from \"../types.js\";\n\n/** A queued mutation. The memory transaction is simply a list of these. */\ntype Mutation = () => void;\n\n/** In-memory transaction: an ordered list of pending mutations. */\nexport type MemoryTransaction = Mutation[];\n\nconst toArray = <T>(value: OneOrMany<T>): T[] => (Array.isArray(value) ? value : [value]);\n\n/** Keys and values are normalized to strings (see migration notes). */\nconst toStr = (value: Key | StoredValue): string => `${value}`;\n\n/**\n * In-memory storage backend. No external dependencies — ideal for tests and\n * single-process apps. Data lives in a `Map<bucket, Map<key, values[]>>`.\n */\nexport class MemoryBackend implements Backend<MemoryTransaction> {\n private buckets = new Map<string, Map<string, string[]>>();\n\n begin(): MemoryTransaction {\n return [];\n }\n\n async end(transaction: MemoryTransaction): Promise<void> {\n for (const mutation of transaction) {\n mutation();\n }\n }\n\n async clean(): Promise<void> {\n this.buckets.clear();\n }\n\n async get(bucket: string, key: Key): Promise<string[]> {\n const values = this.buckets.get(bucket)?.get(toStr(key));\n return values ? [...values] : [];\n }\n\n async unions(buckets: string[], keys: Key[]): Promise<Record<string, string[]>> {\n const keyStrs = keys.map(toStr);\n const result: Record<string, string[]> = {};\n\n for (const bucket of buckets) {\n const store = this.buckets.get(bucket);\n if (!store) {\n result[bucket] = [];\n continue;\n }\n const union = new Set<string>();\n for (const key of keyStrs) {\n for (const value of store.get(key) ?? []) {\n union.add(value);\n }\n }\n result[bucket] = [...union];\n }\n\n return result;\n }\n\n async union(bucket: string, keys: Key[]): Promise<string[]> {\n let store = this.buckets.get(bucket);\n\n // Legacy behavior: if no exact bucket matches, treat existing bucket names\n // as regular expressions and use the first that matches `bucket`.\n if (!store) {\n for (const name of this.buckets.keys()) {\n if (new RegExp(`^${name}$`).test(bucket)) {\n store = this.buckets.get(name);\n break;\n }\n }\n }\n\n if (!store) {\n return [];\n }\n\n const union = new Set<string>();\n for (const key of keys) {\n for (const value of store.get(toStr(key)) ?? []) {\n union.add(value);\n }\n }\n return [...union];\n }\n\n add(\n transaction: MemoryTransaction,\n bucket: string,\n key: Key,\n values: OneOrMany<StoredValue>,\n ): void {\n const keyStr = toStr(key);\n const valueStrs = toArray(values).map(toStr);\n\n transaction.push(() => {\n let store = this.buckets.get(bucket);\n if (!store) {\n store = new Map();\n this.buckets.set(bucket, store);\n }\n const existing = store.get(keyStr);\n // New values first, then existing — matches the legacy union order.\n store.set(\n keyStr,\n existing ? [...new Set([...valueStrs, ...existing])] : [...new Set(valueStrs)],\n );\n });\n }\n\n del(transaction: MemoryTransaction, bucket: string, keys: OneOrMany<Key>): void {\n const keyStrs = toArray(keys).map(toStr);\n\n transaction.push(() => {\n const store = this.buckets.get(bucket);\n if (!store) {\n return;\n }\n for (const key of keyStrs) {\n store.delete(key);\n }\n });\n }\n\n remove(\n transaction: MemoryTransaction,\n bucket: string,\n key: Key,\n values: OneOrMany<StoredValue>,\n ): void {\n const keyStr = toStr(key);\n const toRemove = new Set(toArray(values).map(toStr));\n\n transaction.push(() => {\n const existing = this.buckets.get(bucket)?.get(keyStr);\n if (existing) {\n this.buckets.get(bucket)?.set(\n keyStr,\n existing.filter((value) => !toRemove.has(value)),\n );\n }\n });\n }\n}\n","import type { Backend, Key, OneOrMany, StoredValue } from \"../types.js\";\n\n/**\n * Minimal structural type for a node-redis v4+ client. Declared here (rather\n * than importing from `redis`) so this module stays decoupled from the driver:\n * any compatible client works, and consumers without `redis` installed can\n * still type-check the rest of the package.\n */\nexport interface RedisClientLike {\n multi(): RedisMultiLike;\n sMembers(key: string): Promise<string[]>;\n sUnion(keys: string[]): Promise<string[]>;\n keys(pattern: string): Promise<string[]>;\n del(keys: string | string[]): Promise<number>;\n}\n\nexport interface RedisMultiLike {\n sAdd(key: string, members: string | string[]): RedisMultiLike;\n sRem(key: string, members: string | string[]): RedisMultiLike;\n del(keys: string | string[]): RedisMultiLike;\n exec(): Promise<unknown[]>;\n}\n\nconst toArray = <T>(value: OneOrMany<T>): T[] => (Array.isArray(value) ? value : [value]);\nconst toStr = (value: Key | StoredValue): string => `${value}`;\n\n/** Redis storage backend (node-redis v4+). Sets map directly to Redis sets. */\nexport class RedisBackend implements Backend<RedisMultiLike> {\n private readonly redis: RedisClientLike;\n private readonly prefix: string;\n\n constructor(redis: RedisClientLike, prefix = \"acl\") {\n this.redis = redis;\n this.prefix = prefix;\n }\n\n begin(): RedisMultiLike {\n return this.redis.multi();\n }\n\n async end(transaction: RedisMultiLike): Promise<void> {\n await transaction.exec();\n }\n\n async clean(): Promise<void> {\n const keys = await this.redis.keys(`${this.prefix}*`);\n if (keys.length) {\n await this.redis.del(keys);\n }\n }\n\n get(bucket: string, key: Key): Promise<string[]> {\n return this.redis.sMembers(this.bucketKey(bucket, key));\n }\n\n async unions(buckets: string[], keys: Key[]): Promise<Record<string, string[]>> {\n const result: Record<string, string[]> = {};\n await Promise.all(\n buckets.map(async (bucket) => {\n result[bucket] = await this.redis.sUnion(this.bucketKeys(bucket, keys));\n }),\n );\n return result;\n }\n\n union(bucket: string, keys: Key[]): Promise<string[]> {\n return this.redis.sUnion(this.bucketKeys(bucket, keys));\n }\n\n add(transaction: RedisMultiLike, bucket: string, key: Key, values: OneOrMany<StoredValue>): void {\n transaction.sAdd(this.bucketKey(bucket, key), toArray(values).map(toStr));\n }\n\n del(transaction: RedisMultiLike, bucket: string, keys: OneOrMany<Key>): void {\n transaction.del(toArray(keys).map((key) => this.bucketKey(bucket, key)));\n }\n\n remove(\n transaction: RedisMultiLike,\n bucket: string,\n key: Key,\n values: OneOrMany<StoredValue>,\n ): void {\n transaction.sRem(this.bucketKey(bucket, key), toArray(values).map(toStr));\n }\n\n private bucketKey(bucket: string, key: Key): string {\n return `${this.prefix}_${bucket}@${key}`;\n }\n\n private bucketKeys(bucket: string, keys: Key[]): string[] {\n return keys.map((key) => this.bucketKey(bucket, key));\n }\n}\n","import type { Backend, Key, OneOrMany, StoredValue } from \"../types.js\";\n\n/**\n * Minimal structural types for the mongodb v4+ driver, declared here so this\n * module stays decoupled from the driver (mongodb is an optional peer dep).\n */\nexport interface MongoCollectionLike {\n findOne(filter: object, options?: object): Promise<Record<string, unknown> | null>;\n find(filter: object, options?: object): { toArray(): Promise<Record<string, unknown>[]> };\n updateOne(filter: object, update: object, options?: object): Promise<unknown>;\n deleteMany(filter: object): Promise<unknown>;\n createIndex(spec: object): Promise<string>;\n drop(): Promise<boolean>;\n}\n\nexport interface MongoDbLike {\n collection(name: string): MongoCollectionLike;\n collections(): Promise<MongoCollectionLike[]>;\n}\n\n/** Each queued mutation is an async function; the transaction runs them in series. */\nexport type MongoTransaction = Array<() => Promise<void>>;\n\nexport interface MongoDBBackendOptions {\n prefix?: string;\n /** Store every bucket in one collection (distinguished by `_bucketname`). */\n useSingle?: boolean;\n /** Use bucket names verbatim as collection names (skip sanitization). */\n useRawCollectionNames?: boolean;\n}\n\n/** Collection that holds meta + all `allows_*` buckets when `useSingle` is on. */\nconst SINGLE_COLLECTION = \"resources\";\n\nconst toArray = <T>(value: OneOrMany<T>): T[] => (Array.isArray(value) ? value : [value]);\n\n/** Field names cannot contain dots; encode keys/values before storing. */\nfunction encode(text: Key | StoredValue): string | number {\n if (typeof text === \"string\") {\n return encodeURIComponent(text).replace(/\\./g, \"%2E\");\n }\n return text;\n}\n\nconst decode = (text: string): string => decodeURIComponent(text);\n\n/**\n * MongoDB storage backend (mongodb v4+ driver).\n *\n * Each (bucket, key) pair is a document whose field names are the set members\n * (stored as `{ <member>: true }`), since MongoDB has no native set type.\n */\nexport class MongoDBBackend implements Backend<MongoTransaction> {\n private readonly db: MongoDbLike;\n private readonly prefix: string;\n private readonly useSingle: boolean;\n private readonly useRawCollectionNames: boolean;\n\n constructor(db: MongoDbLike, options: MongoDBBackendOptions = {}) {\n this.db = db;\n this.prefix = options.prefix ?? \"\";\n this.useSingle = options.useSingle ?? false;\n this.useRawCollectionNames = options.useRawCollectionNames ?? false;\n }\n\n begin(): MongoTransaction {\n return [];\n }\n\n async end(transaction: MongoTransaction): Promise<void> {\n for (const mutation of transaction) {\n await mutation();\n }\n }\n\n async clean(): Promise<void> {\n const collections = await this.db.collections();\n await Promise.all(collections.map((collection) => collection.drop().catch(() => false)));\n }\n\n async get(bucket: string, key: Key): Promise<string[]> {\n const collection = this.collection(bucket);\n const doc = await collection.findOne(this.filter(bucket, encode(key)), {\n projection: { _bucketname: 0 },\n });\n if (!doc) {\n return [];\n }\n return this.members(doc);\n }\n\n async union(bucket: string, keys: Key[]): Promise<string[]> {\n const collection = this.collection(bucket);\n const filter = this.useSingle\n ? { _bucketname: bucket, key: { $in: keys.map(encode) } }\n : { key: { $in: keys.map(encode) } };\n\n const docs = await collection.find(filter, { projection: { _bucketname: 0 } }).toArray();\n const union = new Set<string>();\n for (const doc of docs) {\n for (const member of this.members(doc)) {\n union.add(member);\n }\n }\n return [...union];\n }\n\n add(\n transaction: MongoTransaction,\n bucket: string,\n key: Key,\n values: OneOrMany<StoredValue>,\n ): void {\n if (key === \"key\") {\n throw new Error(\"Key name 'key' is not allowed.\");\n }\n const filter = this.filter(bucket, encode(key));\n const doc = this.buildDoc(values);\n\n transaction.push(async () => {\n await this.collection(bucket).updateOne(filter, { $set: doc }, { upsert: true });\n });\n transaction.push(async () => {\n await this.collection(bucket).createIndex({ _bucketname: 1, key: 1 });\n });\n }\n\n del(transaction: MongoTransaction, bucket: string, keys: OneOrMany<Key>): void {\n const encoded = toArray(keys).map(encode);\n const filter = this.useSingle\n ? { _bucketname: bucket, key: { $in: encoded } }\n : { key: { $in: encoded } };\n\n transaction.push(async () => {\n await this.collection(bucket).deleteMany(filter);\n });\n }\n\n remove(\n transaction: MongoTransaction,\n bucket: string,\n key: Key,\n values: OneOrMany<StoredValue>,\n ): void {\n const filter = this.filter(bucket, encode(key));\n const doc = this.buildDoc(values);\n\n transaction.push(async () => {\n await this.collection(bucket).updateOne(filter, { $unset: doc }, { upsert: true });\n });\n }\n\n // --- helpers ---------------------------------------------------------------\n\n private collection(bucket: string): MongoCollectionLike {\n const name = this.useSingle ? SINGLE_COLLECTION : bucket;\n return this.db.collection(this.prefix + this.sanitizeCollectionName(name));\n }\n\n private filter(bucket: string, key: string | number): Record<string, unknown> {\n return this.useSingle ? { _bucketname: bucket, key } : { key };\n }\n\n /** Build a `{ <encoded member>: true }` doc from one or many values. */\n private buildDoc(values: OneOrMany<StoredValue>): Record<string, true> {\n const doc: Record<string, true> = {};\n for (const value of toArray(values)) {\n doc[`${encode(value)}`] = true;\n }\n return doc;\n }\n\n /** Decode a stored document's field names back into set members. */\n private members(doc: Record<string, unknown>): string[] {\n return Object.keys(doc)\n .filter((field) => field !== \"key\" && field !== \"_id\")\n .map(decode);\n }\n\n private sanitizeCollectionName(name: string): string {\n if (this.useRawCollectionNames) {\n return name;\n }\n // Collection names cannot contain slashes or whitespace.\n return decodeURIComponent(name).replace(/[/\\s]/g, \"_\");\n }\n}\n","/**\n * acl-next — modern TypeScript ACL / RBAC.\n *\n * Fork of optimalbits/node_acl (MIT, (c) 2011-2013 Manuel Astudillo).\n *\n * Public surface is filled in across the modernization phases:\n * - Phase 2: types & Backend interface\n * - Phase 3: backends (memory, redis, mongodb)\n * - Phase 4: the Acl class\n * - Phase 5: express middleware\n */\n\nexport const VERSION = \"1.0.0-alpha.0\";\n\nexport { Acl } from \"./acl.js\";\nexport { Acl as default } from \"./acl.js\";\nexport { aclErrorHandler, aclMiddleware, HttpError } from \"./middleware.js\";\nexport type {\n AclMiddleware,\n AclNext,\n AclRequest,\n AclResponse,\n UserIdResolver,\n} from \"./middleware.js\";\nexport { MemoryBackend } from \"./backends/memory.js\";\nexport type { MemoryTransaction } from \"./backends/memory.js\";\nexport { RedisBackend } from \"./backends/redis.js\";\nexport type { RedisClientLike, RedisMultiLike } from \"./backends/redis.js\";\nexport { MongoDBBackend } from \"./backends/mongodb.js\";\nexport type {\n MongoCollectionLike,\n MongoDbLike,\n MongoDBBackendOptions,\n MongoTransaction,\n} from \"./backends/mongodb.js\";\n\nexport type {\n AclOptions,\n AllowRule,\n Backend,\n Buckets,\n Key,\n Logger,\n OneOrMany,\n Permission,\n Resource,\n Role,\n StoredValue,\n UserId,\n} from \"./types.js\";\n"]}
@@ -0,0 +1,346 @@
1
+ /**
2
+ * Core domain types and the storage Backend interface.
3
+ *
4
+ * This is the typed, promise-native successor to the legacy lib/backend.js
5
+ * contract. Backends are namespaced (bucketed) key -> set-of-values stores
6
+ * with batched, committed writes.
7
+ */
8
+ /** A user identifier. Users are created implicitly by assigning them roles. */
9
+ type UserId = string | number;
10
+ /** A role name. `"*"` is reserved to mean "all permissions". */
11
+ type Role = string;
12
+ /** A resource name (e.g. a URL or logical resource). */
13
+ type Resource = string;
14
+ /** A permission/action name (e.g. `"get"`, `"edit"`). */
15
+ type Permission = string;
16
+ /** A key within a bucket. */
17
+ type Key = string | number;
18
+ /** A value stored inside a bucket's set. */
19
+ type StoredValue = string | number;
20
+ /** One or many of `T` — mirrors the original "accepts string or array" API. */
21
+ type OneOrMany<T> = T | T[];
22
+ /** Optional logger; when provided, the Acl instance emits debug output. */
23
+ interface Logger {
24
+ debug(...args: unknown[]): void;
25
+ }
26
+ /** Names of the internal storage buckets. Overridable via {@link AclOptions}. */
27
+ interface Buckets {
28
+ meta: string;
29
+ parents: string;
30
+ permissions: string;
31
+ resources: string;
32
+ roles: string;
33
+ users: string;
34
+ }
35
+ /** Options accepted by the Acl constructor. */
36
+ interface AclOptions {
37
+ buckets?: Partial<Buckets>;
38
+ }
39
+ /** A single entry of the array form of `allow(...)`. */
40
+ interface AllowRule {
41
+ roles: OneOrMany<Role>;
42
+ allows: Array<{
43
+ resources: OneOrMany<Resource>;
44
+ permissions: OneOrMany<Permission>;
45
+ }>;
46
+ }
47
+ /**
48
+ * Storage backend interface.
49
+ *
50
+ * Writes are not applied immediately: callers obtain a transaction with
51
+ * {@link Backend.begin}, queue mutations with {@link Backend.add},
52
+ * {@link Backend.del} and {@link Backend.remove}, then commit them with
53
+ * {@link Backend.end}. Backends that support it commit atomically.
54
+ *
55
+ * @typeParam T - the backend-specific transaction type produced by `begin`.
56
+ */
57
+ interface Backend<T = unknown> {
58
+ /** Start a transaction (a queue of pending mutations). */
59
+ begin(): T;
60
+ /** Commit a transaction. */
61
+ end(transaction: T): Promise<void>;
62
+ /** Remove all stored data. */
63
+ clean(): Promise<void>;
64
+ /** Get the set of values stored at `bucket`/`key` (empty array if none). */
65
+ get(bucket: string, key: Key): Promise<string[]>;
66
+ /** Union of the sets stored at the given `keys` within one `bucket`. */
67
+ union(bucket: string, keys: Key[]): Promise<string[]>;
68
+ /**
69
+ * Per-bucket union of `keys` across multiple `buckets`, keyed by bucket.
70
+ * Optional — Acl falls back to repeated {@link Backend.union} calls when a
71
+ * backend does not implement it.
72
+ */
73
+ unions?(buckets: string[], keys: Key[]): Promise<Record<string, string[]>>;
74
+ /** Queue: add `values` to the set at `bucket`/`key`. */
75
+ add(transaction: T, bucket: string, key: Key, values: OneOrMany<StoredValue>): void;
76
+ /** Queue: delete the given `keys` from `bucket`. */
77
+ del(transaction: T, bucket: string, keys: OneOrMany<Key>): void;
78
+ /** Queue: remove `values` from the set at `bucket`/`key`. */
79
+ remove(transaction: T, bucket: string, key: Key, values: OneOrMany<StoredValue>): void;
80
+ }
81
+
82
+ /**
83
+ * Minimal structural request shape the middleware needs. Compatible with
84
+ * Express (and most HTTP frameworks) without depending on their types.
85
+ */
86
+ interface AclRequest {
87
+ originalUrl?: string;
88
+ url?: string;
89
+ method: string;
90
+ session?: {
91
+ userId?: UserId;
92
+ };
93
+ user?: {
94
+ id?: UserId;
95
+ };
96
+ }
97
+ interface AclResponse {
98
+ status(code: number): {
99
+ end(body?: string): unknown;
100
+ json(body: unknown): unknown;
101
+ send(body: unknown): unknown;
102
+ };
103
+ }
104
+ type AclNext = (err?: unknown) => void;
105
+ type AclMiddleware = (req: AclRequest, res: AclResponse, next: AclNext) => void;
106
+ /** Resolves the userId for a request when not supplied statically. */
107
+ type UserIdResolver = (req: AclRequest, res: AclResponse) => UserId | undefined;
108
+ /** Error thrown by the middleware; pair it with {@link aclErrorHandler}. */
109
+ declare class HttpError extends Error {
110
+ readonly errorCode: number;
111
+ readonly name = "HttpError";
112
+ constructor(errorCode: number, message: string);
113
+ }
114
+ /**
115
+ * Build an Express-style middleware that authorizes the current request.
116
+ *
117
+ * @param acl The Acl instance to check against.
118
+ * @param numPathComponents How many leading URL path components form the
119
+ * resource name (default: the whole path).
120
+ * @param userId A static user id, or a resolver `(req, res) => id`.
121
+ * Defaults to `req.session.userId` / `req.user.id`.
122
+ * @param actions Permission(s) to check (default: the HTTP method).
123
+ */
124
+ declare function aclMiddleware(acl: Acl, numPathComponents?: number, userId?: UserId | UserIdResolver, actions?: OneOrMany<Permission>): AclMiddleware;
125
+ /**
126
+ * Express error handler that renders {@link HttpError}s. Pass `"json"` or
127
+ * `"html"` to choose the response format (defaults to plain text).
128
+ */
129
+ declare function aclErrorHandler(contentType?: "json" | "html"): (err: unknown, req: AclRequest, res: AclResponse, next: AclNext) => void;
130
+
131
+ /**
132
+ * Access Control List. Models authorization as users -> roles -> resources ->
133
+ * permissions, with role hierarchies (parents).
134
+ *
135
+ * Promise-native: every method returns a Promise (the legacy callback API is
136
+ * intentionally dropped). Storage is delegated to a {@link Backend}.
137
+ *
138
+ * @typeParam T - the backend transaction type.
139
+ */
140
+ declare class Acl<T = unknown> {
141
+ readonly backend: Backend<T>;
142
+ readonly logger: Logger | undefined;
143
+ readonly buckets: Buckets;
144
+ constructor(backend: Backend<T>, logger?: Logger, options?: AclOptions);
145
+ /** Adds roles to a given user id. */
146
+ addUserRoles(userId: UserId, roles: OneOrMany<Role>): Promise<void>;
147
+ /** Removes roles from a given user id. */
148
+ removeUserRoles(userId: UserId, roles: OneOrMany<Role>): Promise<void>;
149
+ /** Returns all the roles assigned to a given user id. */
150
+ userRoles(userId: UserId): Promise<Role[]>;
151
+ /** Returns all users that have the given role. */
152
+ roleUsers(roleName: Role): Promise<UserId[]>;
153
+ /** Returns whether the user has the given role. */
154
+ hasRole(userId: UserId, role: Role): Promise<boolean>;
155
+ /** Adds one or more parent roles to a role. */
156
+ addRoleParents(role: Role, parents: OneOrMany<Role>): Promise<void>;
157
+ /** Removes parent role(s) from a role. Omit `parents` to remove all of them. */
158
+ removeRoleParents(role: Role, parents?: OneOrMany<Role>): Promise<void>;
159
+ /** Removes a role from the system, including all its permissions. */
160
+ removeRole(role: Role): Promise<void>;
161
+ /** Removes a resource from the system. */
162
+ removeResource(resource: Resource): Promise<void>;
163
+ /** Adds permissions to roles over resources (compact array form). */
164
+ allow(rules: AllowRule[]): Promise<void>;
165
+ /** Adds the given permissions to the given roles over the given resources. */
166
+ allow(roles: OneOrMany<Role>, resources: OneOrMany<Resource>, permissions: OneOrMany<Permission>): Promise<void>;
167
+ /** Removes permissions from a role over resources. Omit `permissions` to remove all. */
168
+ removeAllow(role: Role, resources: OneOrMany<Resource>, permissions?: OneOrMany<Permission>): Promise<void>;
169
+ /**
170
+ * Removes permissions from a role over the given resources. When
171
+ * `permissions` is null the resource is fully revoked for the role.
172
+ *
173
+ * Note: loses atomicity when pruning emptied role/resource links.
174
+ */
175
+ removePermissions(role: Role, resources: Resource[], permissions: Permission[] | null): Promise<void>;
176
+ /**
177
+ * Returns, per resource, the permissions a user has. Uses the backend's
178
+ * `unions` optimization when available.
179
+ */
180
+ allowedPermissions(userId: UserId, resources: OneOrMany<Resource>): Promise<Record<Resource, Permission[]>>;
181
+ /** `allowedPermissions` variant using the backend `unions` bulk query. */
182
+ optimizedAllowedPermissions(userId: UserId, resources: OneOrMany<Resource>): Promise<Record<Resource, Permission[]>>;
183
+ /** Checks if a user is allowed all of the given permissions on a resource. */
184
+ isAllowed(userId: UserId, resource: Resource, permissions: OneOrMany<Permission>): Promise<boolean>;
185
+ /** Returns true if any of the roles has all of the given permissions. */
186
+ areAnyRolesAllowed(roles: OneOrMany<Role>, resource: Resource, permissions: OneOrMany<Permission>): Promise<boolean>;
187
+ /** Returns a map of resource -> permissions the roles have. */
188
+ whatResources(roles: OneOrMany<Role>): Promise<Record<Resource, Permission[]>>;
189
+ /** Returns the resources the roles have all of the given permissions over. */
190
+ whatResources(roles: OneOrMany<Role>, permissions: OneOrMany<Permission>): Promise<Resource[]>;
191
+ /** Backing implementation for {@link whatResources}. */
192
+ permittedResources(roles: OneOrMany<Role>, permissions?: Permission[]): Promise<Record<Resource, Permission[]> | Resource[]>;
193
+ /**
194
+ * Express-style middleware that authorizes the current request against this
195
+ * Acl. See {@link aclMiddleware} for parameter semantics. Pair with
196
+ * {@link aclErrorHandler} to render the resulting 401/403 errors.
197
+ */
198
+ middleware(numPathComponents?: number, userId?: UserId | UserIdResolver, actions?: OneOrMany<Permission>): AclMiddleware;
199
+ /** Compact array form of {@link allow}. */
200
+ private allowEx;
201
+ /** Direct parents of the given roles. */
202
+ private rolesParents;
203
+ /** All roles in the hierarchy, including the given roles. */
204
+ private allRoles;
205
+ /** All roles in the hierarchy of the given user. */
206
+ private allUserRoles;
207
+ /** All resources reachable by the given roles (through the hierarchy). */
208
+ private rolesResources;
209
+ /** Permissions the given roles (and their parents) have over a resource. */
210
+ private resourcePermissions;
211
+ /**
212
+ * Whether the roles (and their parents) satisfy all permissions on a resource.
213
+ *
214
+ * NOTE: does not handle circular role hierarchies.
215
+ */
216
+ private checkPermissions;
217
+ }
218
+
219
+ /** A queued mutation. The memory transaction is simply a list of these. */
220
+ type Mutation = () => void;
221
+ /** In-memory transaction: an ordered list of pending mutations. */
222
+ type MemoryTransaction = Mutation[];
223
+ /**
224
+ * In-memory storage backend. No external dependencies — ideal for tests and
225
+ * single-process apps. Data lives in a `Map<bucket, Map<key, values[]>>`.
226
+ */
227
+ declare class MemoryBackend implements Backend<MemoryTransaction> {
228
+ private buckets;
229
+ begin(): MemoryTransaction;
230
+ end(transaction: MemoryTransaction): Promise<void>;
231
+ clean(): Promise<void>;
232
+ get(bucket: string, key: Key): Promise<string[]>;
233
+ unions(buckets: string[], keys: Key[]): Promise<Record<string, string[]>>;
234
+ union(bucket: string, keys: Key[]): Promise<string[]>;
235
+ add(transaction: MemoryTransaction, bucket: string, key: Key, values: OneOrMany<StoredValue>): void;
236
+ del(transaction: MemoryTransaction, bucket: string, keys: OneOrMany<Key>): void;
237
+ remove(transaction: MemoryTransaction, bucket: string, key: Key, values: OneOrMany<StoredValue>): void;
238
+ }
239
+
240
+ /**
241
+ * Minimal structural type for a node-redis v4+ client. Declared here (rather
242
+ * than importing from `redis`) so this module stays decoupled from the driver:
243
+ * any compatible client works, and consumers without `redis` installed can
244
+ * still type-check the rest of the package.
245
+ */
246
+ interface RedisClientLike {
247
+ multi(): RedisMultiLike;
248
+ sMembers(key: string): Promise<string[]>;
249
+ sUnion(keys: string[]): Promise<string[]>;
250
+ keys(pattern: string): Promise<string[]>;
251
+ del(keys: string | string[]): Promise<number>;
252
+ }
253
+ interface RedisMultiLike {
254
+ sAdd(key: string, members: string | string[]): RedisMultiLike;
255
+ sRem(key: string, members: string | string[]): RedisMultiLike;
256
+ del(keys: string | string[]): RedisMultiLike;
257
+ exec(): Promise<unknown[]>;
258
+ }
259
+ /** Redis storage backend (node-redis v4+). Sets map directly to Redis sets. */
260
+ declare class RedisBackend implements Backend<RedisMultiLike> {
261
+ private readonly redis;
262
+ private readonly prefix;
263
+ constructor(redis: RedisClientLike, prefix?: string);
264
+ begin(): RedisMultiLike;
265
+ end(transaction: RedisMultiLike): Promise<void>;
266
+ clean(): Promise<void>;
267
+ get(bucket: string, key: Key): Promise<string[]>;
268
+ unions(buckets: string[], keys: Key[]): Promise<Record<string, string[]>>;
269
+ union(bucket: string, keys: Key[]): Promise<string[]>;
270
+ add(transaction: RedisMultiLike, bucket: string, key: Key, values: OneOrMany<StoredValue>): void;
271
+ del(transaction: RedisMultiLike, bucket: string, keys: OneOrMany<Key>): void;
272
+ remove(transaction: RedisMultiLike, bucket: string, key: Key, values: OneOrMany<StoredValue>): void;
273
+ private bucketKey;
274
+ private bucketKeys;
275
+ }
276
+
277
+ /**
278
+ * Minimal structural types for the mongodb v4+ driver, declared here so this
279
+ * module stays decoupled from the driver (mongodb is an optional peer dep).
280
+ */
281
+ interface MongoCollectionLike {
282
+ findOne(filter: object, options?: object): Promise<Record<string, unknown> | null>;
283
+ find(filter: object, options?: object): {
284
+ toArray(): Promise<Record<string, unknown>[]>;
285
+ };
286
+ updateOne(filter: object, update: object, options?: object): Promise<unknown>;
287
+ deleteMany(filter: object): Promise<unknown>;
288
+ createIndex(spec: object): Promise<string>;
289
+ drop(): Promise<boolean>;
290
+ }
291
+ interface MongoDbLike {
292
+ collection(name: string): MongoCollectionLike;
293
+ collections(): Promise<MongoCollectionLike[]>;
294
+ }
295
+ /** Each queued mutation is an async function; the transaction runs them in series. */
296
+ type MongoTransaction = Array<() => Promise<void>>;
297
+ interface MongoDBBackendOptions {
298
+ prefix?: string;
299
+ /** Store every bucket in one collection (distinguished by `_bucketname`). */
300
+ useSingle?: boolean;
301
+ /** Use bucket names verbatim as collection names (skip sanitization). */
302
+ useRawCollectionNames?: boolean;
303
+ }
304
+ /**
305
+ * MongoDB storage backend (mongodb v4+ driver).
306
+ *
307
+ * Each (bucket, key) pair is a document whose field names are the set members
308
+ * (stored as `{ <member>: true }`), since MongoDB has no native set type.
309
+ */
310
+ declare class MongoDBBackend implements Backend<MongoTransaction> {
311
+ private readonly db;
312
+ private readonly prefix;
313
+ private readonly useSingle;
314
+ private readonly useRawCollectionNames;
315
+ constructor(db: MongoDbLike, options?: MongoDBBackendOptions);
316
+ begin(): MongoTransaction;
317
+ end(transaction: MongoTransaction): Promise<void>;
318
+ clean(): Promise<void>;
319
+ get(bucket: string, key: Key): Promise<string[]>;
320
+ union(bucket: string, keys: Key[]): Promise<string[]>;
321
+ add(transaction: MongoTransaction, bucket: string, key: Key, values: OneOrMany<StoredValue>): void;
322
+ del(transaction: MongoTransaction, bucket: string, keys: OneOrMany<Key>): void;
323
+ remove(transaction: MongoTransaction, bucket: string, key: Key, values: OneOrMany<StoredValue>): void;
324
+ private collection;
325
+ private filter;
326
+ /** Build a `{ <encoded member>: true }` doc from one or many values. */
327
+ private buildDoc;
328
+ /** Decode a stored document's field names back into set members. */
329
+ private members;
330
+ private sanitizeCollectionName;
331
+ }
332
+
333
+ /**
334
+ * acl-next — modern TypeScript ACL / RBAC.
335
+ *
336
+ * Fork of optimalbits/node_acl (MIT, (c) 2011-2013 Manuel Astudillo).
337
+ *
338
+ * Public surface is filled in across the modernization phases:
339
+ * - Phase 2: types & Backend interface
340
+ * - Phase 3: backends (memory, redis, mongodb)
341
+ * - Phase 4: the Acl class
342
+ * - Phase 5: express middleware
343
+ */
344
+ declare const VERSION = "1.0.0-alpha.0";
345
+
346
+ export { Acl, type AclMiddleware, type AclNext, type AclOptions, type AclRequest, type AclResponse, type AllowRule, type Backend, type Buckets, HttpError, type Key, type Logger, MemoryBackend, type MemoryTransaction, type MongoCollectionLike, MongoDBBackend, type MongoDBBackendOptions, type MongoDbLike, type MongoTransaction, type OneOrMany, type Permission, RedisBackend, type RedisClientLike, type RedisMultiLike, type Resource, type Role, type StoredValue, type UserId, type UserIdResolver, VERSION, aclErrorHandler, aclMiddleware, Acl as default };