type-graphql-dependency package
@imqueue/graphql-dependency for type-graphql — declare cross-service dependencies on the decorated classes you already have, instead of on raw GraphQLObjectType values.
The engine underneath is @imqueue/graphql-dependency, and the concepts are its concepts: a bulk **loader** per type, **requirements** describing which types own which, and an optional **initializer** that pre-fills fields the requirement filters need. What this package changes is where they are written. DependencyFor() is a class decorator, so a type's relations sit on the class that defines it, and Dependency resolves a class back to its dependency description at request time.
Remarks
type-graphql builds its schema from decorated classes, which means the GraphQLObjectType a class becomes does not exist while the decorators are running. Every declaration is therefore deferred: DependencyFor() registers a hook rather than wiring anything, and the hooks run once the schema is built.
**Running them is the application's job.** Nothing here calls them. After building the schema, pass it to every hook in schemaHooks — miss that step and no dependency is ever registered, no error is raised, and the dependency fields simply stay empty:
const schema = await buildSchema({ resolvers: [...] });
schemaHooks.forEach(hook => hook(schema));
Because the wiring is deferred, the mistakes it catches surface then rather than at start-up: a class that is not a GraphQL type, a relation naming a field that does not exist, a filter referring to an unknown field. All of them throw TypeError from inside the hook, so run the hooks during boot rather than lazily on first request.
Example
import {
Dependency,
DependencyFor,
schemaHooks,
} from '@imqueue/type-graphql-dependency';
import { buildSchema, ObjectType } from 'type-graphql';
@DependencyFor<Partial<Consumer>>({
require: [
[() => ApiKey, [{ as: 'apiKeys', filter: { consumerId: 'id' } }]],
],
async load(context, filter, fields) {
const { data } = await context.consumer.listConsumer(filter, fields);
return data;
},
})
@ObjectType()
export class Consumer {
// ... field definitions ...
}
// once, at boot
const schema = await buildSchema({ resolvers: [ConsumerResolver] });
schemaHooks.forEach(hook => hook(schema));
// later, in a resolver
await Dependency(Consumer).load(data, context, fields);
Functions
|
Function |
Description |
|---|---|
|
Class decorator declaring how a | |
|
Registers a hook to run when the schema is created, ignoring a handler already registered. |
Interfaces
|
Interface |
Description |
|---|---|
|
The callable Dependency exposes: a class in, its dependency description out, plus the schema it resolves classes against. | |
|
One relation from the decorated class to a dependent class: where the loaded objects are attached, and how they are matched. | |
|
What DependencyFor() declares for one class — any combination of requirements, an initializer and a loader. |
Variables
|
Variable |
Description |
|---|---|
|
The dependency description for a | |
|
Every deferred wiring hook registered so far, in the order it was registered. |
Type Aliases
|
Type Alias |
Description |
|---|---|
|
A deferred piece of dependency wiring, run once the | |
|
The class a requirement points at, named through a thunk. |
Read this page as plain markdown — no HTML, no navigation. For pasting into an LLM, or for an agent to fetch.