Schema Parsing Logic
Relevant source files
The following files were used as context for generating this wiki page:
Schema Parsing Logic in @joindeed/prisma-auth converts declarative @Auth annotations, written as Prisma model comments, into structured role-based access control (RBAC) configurations. This logic enables the middleware to identify which roles and arguments apply to specific Prisma models or fields.
The system uses a PEG.js-generated parser to interpret the domain-specific language (DSL) defined in triple-slash (///) Prisma comments. These annotations define allowed operations—such as read, create, update, or delete—and the roles permitted to perform them, optionally including arguments for dynamic matching logic.
Annotation Structure and DSL
The parsing logic identifies a specific DSL starting with the @Auth( token within Prisma schema descriptions. The parser extracts operation names, associated roles, and any arguments passed to those roles.
Parser Grammar and Components
The parser, generated from a PEGGS grammar, recognizes several key structures:
- Operations: Keywords like
read,create,update, anddeletefollowed by a colon. - Role Arrays: A bracketed list of roles (e.g.,
[Owner, Admin]). - Roles with Arguments: Roles that accept key-value pairs in parentheses (e.g.,
Owner(privileges:[x])).
Sources: src/generated/parser.ts:503-600, src/descriptionToRoles.ts:18-24
Grammar Extraction Flow
The following diagram illustrates how a raw description string is processed into a structured role object.
Core Data Structures
The parsing logic relies on several interfaces to represent the extracted authorization rules.
| Interface | Purpose | Derived From |
|---|---|---|
RoleDescription | Represents a single role name and its associated arguments. | src/descriptionToRoles.ts |
RoleArgs | A dictionary of string or string array arguments passed to a role matcher. | src/descriptionToRoles.ts |
RolesPerType | Maps Prisma model names to their specific role configurations. | src/index.ts |
Role Configuration Example
A parsed @Auth(read:[Owner(userField:id)]) annotation results in the following structure:
{
"read": [
{
"name": "Owner",
"args": { "userField": "id" }
}
]
}
Sources: src/descriptionToRoles.ts:3-12, src/descriptionToRoles.test.ts:32-45
Integration with Middleware
The parsed roles are used by various middleware components to enforce constraints at different levels of the Prisma query.
Field-Level Parsing
makeFieldConstraintMiddleware extracts the description from specific field metadata within the GraphQL info object. It uses descriptionToRoles to determine if the current user matches any of the required roles for that specific field.
Sources: src/makeFieldConstraintMiddleware.ts:28-36
Type-Level Parsing
makeTypeConstraintMiddleware performs similar parsing but targets the description of the GraphQL type itself (e.g., the User model description). This enforces authorization on 1-to-1 relations by checking the model-level @Auth annotation.
Sources: src/makeTypeConstraintMiddleware.ts:58-61
Data Flow for Authorization Enforcement
The sequence below shows how the parsing logic feeds into the middleware execution.
Utility and Helper Functions
The parsing logic is supported by internal helpers that handle GraphQL and Prisma metadata:
extractNonListType: A utility that strips GraphQL modifiers (like!) to get the base model name for role lookups.PrismaSelect.filterBy: Uses the parsed model-level descriptions to determine whichwhereconstraints andselectdependencies must be injected into the Prisma query.
Sources: src/makeTypeConstraintMiddleware.ts:13-20, src/select.ts:182-195
Summary
Schema Parsing Logic serves as the bridge between declarative Prisma schema comments and the runtime authorization engine. By utilizing a formal PEGGS-based parser, the system ensures that complex role definitions and arguments are accurately translated into the structured data required by the Field, Type, and List constraint middlewares to secure Prisma relations and fields.