graplix
Version:
Authorization framework for implementing Relation-based Access Control (ReBAC) with the Resolver (Inspired by [GraphQL](https://graphql.org))
115 lines (104 loc) • 2.15 kB
text/typescript
import DataLoader from "dataloader";
import type { GraplixInput } from "../GraplixInput";
import type { GraplixResolvers } from "../GraplixResolvers";
import type { GraplixSchema } from "../GraplixSchema";
type Artifact = {
$type: "Artifact";
entityId: string;
entityName: "Artifact";
state: {
projectId: string;
};
};
type Project = {
$type: "Project";
entityId: string;
entityName: "Project";
state: {
teamId: string;
};
};
type ObjectTypeMap = {
Artifact: Artifact;
Project: Project;
};
export const artifacts: Artifact[] = [
{
$type: "Artifact",
entityId: "0",
entityName: "Artifact",
state: {
projectId: "0",
},
},
];
export const projects: Project[] = [
{
$type: "Project",
entityId: "0",
entityName: "Project",
state: {
teamId: "0",
},
},
];
type Context = {
loaders: {
artifact: DataLoader<string, Artifact>;
project: DataLoader<string, Project>;
};
};
export const context: Context = {
loaders: {
artifact: new DataLoader<string, Artifact>(async (ids) => {
return artifacts.filter((a) => ids.includes(a.entityId));
}),
project: new DataLoader<string, Project>(async (ids) => {
return projects.filter((a) => ids.includes(a.entityId));
}),
},
};
export const schema: GraplixSchema<ObjectTypeMap> = {
Project: {
self: {
type: "Project",
},
},
Artifact: {
parent: {
type: "Project",
},
can_delete: {
when: "self",
from: "parent",
},
},
};
export const resolvers: GraplixResolvers<Context, ObjectTypeMap> = {
Project: {
identify: (entity) => entity.entityId,
relations: {
self: {
type: "Project",
async resolve(obj) {
return obj;
},
},
},
},
Artifact: {
identify: (entity) => entity.entityId,
relations: {
parent: {
type: "Project",
async resolve(obj, ctx) {
return ctx.loaders.project.load(obj.state.projectId);
},
},
},
},
};
export const input: GraplixInput<Context, ObjectTypeMap> = {
schema,
resolvers,
};