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

DependencyFor(options)

Class decorator declaring how a type-graphql entity is loaded and what it depends on, wiring it into @imqueue/graphql-dependency.

onCreateSchema(handler)

Registers a hook to run when the schema is created, ignoring a handler already registered.

Interfaces

Interface

Description

DependencyInterface

The callable Dependency exposes: a class in, its dependency description out, plus the schema it resolves classes against.

DependentTypeRelations

One relation from the decorated class to a dependent class: where the loaded objects are attached, and how they are matched.

DependsOptions

What DependencyFor() declares for one class — any combination of requirements, an initializer and a loader.

Variables

Variable

Description

Dependency

The dependency description for a type-graphql class — the runtime half of this package, for loading dependencies inside a resolver.

schemaHooks

Every deferred wiring hook registered so far, in the order it was registered.

Type Aliases

Type Alias

Description

CreateSchemaHook

A deferred piece of dependency wiring, run once the type-graphql schema exists and the classes it was declared against have become GraphQL types.

DependentType

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.