TypeScript GraphQL for MongoDB — Numio
Generates TypeScript MongoDB document types from a schema annotated with @entity, @id, @column, @link, @embedded and @map, using @graphql-codegen/typescript-mongodb. Each @entity type gets a <Name>DbObject type; fields without a directive are left out.
Keeping the stored MongoDB document shape typed alongside the GraphQL API types of the same entity.
When to use it
- Keeping the stored MongoDB document shape typed alongside the GraphQL API types of the same entity.
- Seeing how @map paths and @link references translate into nested objects and ObjectId arrays before writing data-access code.
How to use
- Paste a schema whose types use @entity and whose fields use @id, @column, @link, @embedded or @map(path: ...).
- Read the DbObject types near the end of the output; the GraphQL types themselves are generated above them.
- Copy the result into a .ts file; it imports ObjectId from the mongodb package.
GraphQL schema with MongoDB directives
type User @entity {
id: ID! @id
email: String! @column @map(path: "login.email")
profile: Profile! @embedded
posts: [Post!]! @link
}
type Profile @entity(embedded: true) {
name: String! @column
}
type Post @entity {
id: ID! @id
title: String! @column
}TypeScript DbObject types
…
export type AdditionalEntityFields = {
path?: InputMaybe<Scalars["String"]["input"]>
type?: InputMaybe<Scalars["String"]["input"]>
}
import { ObjectId } from "mongodb"
export type UserDbObject = {
_id: ObjectId
login: {
email: string
}
profile: ProfileDbObject
posts: Array<PostDbObject["_id"]>
}
export type ProfileDbObject = {
name: string
}
export type PostDbObject = {
_id: ObjectId
title: string
}Details and limitations
@id becomes _id: ObjectId, @link becomes the linked entity's _id (Array<PostDbObject["_id"]> for lists), and @map(path: "login.email") creates a nested login object.
Fields with no directive (no @column, @id, @link, @embedded) are not included in the DbObject type; nullable columns become optional Maybe<T> properties.
The output also contains the standard typescript-plugin types (elided above). Generation runs in a Web Worker in your browser.
FAQ
Do I need to declare the @entity and @column directives in my schema?
No. The plugin adds its own directive definitions, which is also why an AdditionalEntityFields input type appears in the output.
How are embedded documents typed?
A type declared with @entity(embedded: true) gets a DbObject type without _id, and a field marked @embedded references it, for example profile: ProfileDbObject.
Why is a field missing from the DbObject type?
Only fields with @id, @column, @link, @embedded or @map are stored fields. Add @column to include a plain field.