Initial Commit
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
import type { DirectiveDescriptor } from "./directives.types.js";
|
||||
|
||||
/**
|
||||
* `@auth(scope: String!)` directive descriptor. Engine adapters install it at
|
||||
* schema-build time; the handler checks `ctx.principal` against the declared
|
||||
* scope and raises the host's auth error when the scope is not present.
|
||||
*
|
||||
* The handler here is the **contract** body — concrete engines wire it into
|
||||
* the resolver pipeline. The default raises a typed error noting the missing
|
||||
* scope so callers see a stable failure shape during early integration.
|
||||
*/
|
||||
export const authDirective: DirectiveDescriptor<{ readonly scope: string }> = {
|
||||
name: "auth",
|
||||
sdl: "directive @auth(scope: String!) on FIELD_DEFINITION",
|
||||
locations: ["FIELD_DEFINITION"],
|
||||
args: [{ name: "scope", type: "String!" }],
|
||||
handler: (args, ctx) => {
|
||||
const scopes: readonly string[] = ctx.principal?.scopes ?? [];
|
||||
if (!scopes.includes(args.scope)) {
|
||||
throw new Error(
|
||||
`@auth(scope: "${args.scope}") failed — principal does not carry the required scope`
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* `@rateLimit(rpm: Int!)` directive descriptor. Engine adapters install it at
|
||||
* schema-build time; the handler delegates to the host's rate-limit slot.
|
||||
* The contract body checks the argument bound and otherwise yields — concrete
|
||||
* engines wire it into the request pipeline.
|
||||
*/
|
||||
export const rateLimitDirective: DirectiveDescriptor<{ readonly rpm: number }> =
|
||||
{
|
||||
name: "rateLimit",
|
||||
sdl: "directive @rateLimit(rpm: Int!) on FIELD_DEFINITION",
|
||||
locations: ["FIELD_DEFINITION"],
|
||||
args: [{ name: "rpm", type: "Int!" }],
|
||||
handler: (args) => {
|
||||
if (!Number.isInteger(args.rpm) || args.rpm <= 0) {
|
||||
throw new Error(
|
||||
`@rateLimit(rpm: ${String(args.rpm)}) — rpm must be a positive integer`
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/** Lookup of every host-supplied directive descriptor, keyed by name. */
|
||||
export const HOST_DIRECTIVES = Object.freeze({
|
||||
auth: authDirective,
|
||||
rateLimit: rateLimitDirective,
|
||||
}) as Readonly<Record<"auth" | "rateLimit", DirectiveDescriptor>>;
|
||||
Reference in New Issue
Block a user