This package generates TypeScript type definitions from a GraphQL schema. It can be used from the command line or through its Node API.
This package is specially adapted for Condict. It is not especially flexible and the output format is not configurable.
Condict deals with many kinds of IDs for many kinds of resources. To prevent confusion and errors, this package has support for custom ID types. Any GraphQL scalar type annotated with a directive named @id
will be treated as follows:
- The generated TypeScript definition will use the special
IdOf<T>
type. It is anumber
value with a hidden field of typeT
(the resource name). The typeIdOf<'X'>
is incompatible withIdOf<'Y'>
. - The resource name can be specified with the
of
parameter on the directive:@id(of: "MyThing")
. Otherwise, it becomes the scalar type name, minus theId
suffix, if there is one.
Example transformations:
GraphQL schema | TypeScript definition |
---|---|
scalar LemmaId @id |
export type LemmaId = IdOf<'Lemma'>; |
scalar NamedId @id(of: "Foo") |
export type NamedId = IdOf<'Foo'>; |
scalar SomeKey @id |
export type SomeKey = IdOf<'SomeKey'>; |
scalar MyOwnId @id(of: "MyOwnId") |
export type MyOwnId = IdOf<'MyOwnId'>; |
In addition to the @id
directive, this package also supports custom marshalling of scalars through the @marshal
directive. The directive takes a single parameter, as
, which determines how the scalar is marshalled.
Marshalling affects how values of the type are transferred in JSON payloads (requests and responses), and determines which literal types the scalar accepts in queries and mutations. The table below summarises the @marshal
types.
GraphQL schema | Query literal type | JSON payload type | TypeScript type |
---|---|---|---|
@marshal(as: INT_TYPE) |
integer | number | number |
@marshal(as: FLOAT_TYPE) |
integer, floating-point | number | number |
@marshal(as: STRING_TYPE) |
string | string | string |
An example:
scalar Date @marshal(as: INT_TYPE)
extend type Query {
nextDay(date: Date!): Date!
}
query {
nextDay(date: 1592644245435)
# INT_TYPE only accepts integer literals
invalid1: nextDay(date: 1592644245435.0)
invalid2: nextDay(date: "1592644245435")
}
condict-graphql-typer --schema-dir=<schema-dir> --target=server --output=<output-file>
condict-graphql-typer --schema-dir=<schema-dir> --target=client --src=<src-dir> --defs=<defs-file>
condict-graphql-typer --help
Builds TypeScript type definitions from all .graphql files in <schema-dir>
(searched recursively), saving the result in <output-file>
.
--schema-dir <schema-dir>
/-s <schema-dir>
: The directory that is searched for .graphql schema files. The directory is searched recursively. All .graphql files that are found are concatenated together and parsed as a single string. Each .graphql file should be a syntactically valid, self-contained schema file. The files cannot contain queries, only schema definitions.--target (server|client)
/-t (server|client)
: Determines whether to write server type definitions (server
), or client operation type definitions (client
).--output <output-file>
/-o <output-file>
: Server only. The file that TypeScript definitions are written to. Any existing contents will be overwritten.--src=<src-dir>
: Client only. Client only. The source directory that is searched for client .graphql files. Every file namedquery.graphql
contains one or more operations (queries, mutations, subscriptions) and receives a generatedquery.ts
in the same directory. All other .graphql files are expected to contain fragment definitions, which are made available to all operations across the codebase.--defs=<defs-file>
/-d <defs-file>
: Client only. The path to the shared definitions file, which will receive generated definitions for theIdOf
,Query
,QueryArgs
andQueryResult
types as well as enum, input and custom ID types.--help
/-h
: Shows a help screen.
Server types example:
const gqlTyper = require('@condict/graphql-typer');
const schema = gqlTyper.buildGraphqlSchema('../graphql-schema');
const definitions = gqlTyper.defineServerTypes(schema);
console.log(definitions); // This value should be saved to a file
Client types example:
const gqlTyper = require('@condict/graphql-typer');
const schema = gqlTyper.buildGraphqlSchema('../graphql-schema');
const sharedPath = './graphql-shared.ts';
const srcDir = './src';
gqlTyper.defineClientTypes(schema, sharedPath, srcDir);
buildGraphqlSchema(schemaDir: string): GraphQLSchema
Reads all .graphql files in the schemaDir
directory (searched recursively), and constructs a GraphQL schema instance. If the schema is invalid, an error is thrown.
findAllGraphqlFiles(schemaDir: string): string[]
Returns the full paths of every .graphql file inside schemaDir
(searched recursively). Matching paths are sorted alphabetically.
getIdKind(type: GraphQLScalarType): string | null
Given a GraphQL scalar type, determines whether it is a custom ID type (with the @id
directive), and if so, gets the name of the resource it belongs to. If the type is not a custom ID type, returns null.
GraphQLScalarType
does not directly store the type's directives. Instead, they are looked up through the AST node. As a result, this function returns null
for any scalar type that lacks an AST node.
getMarshalType(type: GraphQLScalarType): MarshalType | null
Given a GraphQL scalar type, determines whether it has a @marshal
directive, and if so, gets the type it should be marshalled as. If the scalar type has no @marshal
directive, returns null.
GraphQLScalarType
does not directly store the type's directives. Instead, they are looked up through the AST node. As a result, this function returns null
for any scalar type that lacks an AST node.
defineServerTypes(schema: GraphQLSchema): string
Constructs TypeScript definitions for the types in the specified schema, which are returned as a TypeScript source string. Note that only user-defined types are exported; introspection types like __Type
and __Schema
are always skipped.
defineClientTypes(schema: GraphQLSchema, sharedPath: string, srcDir: string): void
Constructs TypeScript definitions for all operations in every applicable .graphql file in srcDir
, based on schema
. Shared type definitions (the IdOf
, Query
, QueryArgs
and QueryResult
types) are put in sharedPath
.
Note that unlike getServerTypes()
, this function writes the result to each applicable file, rather than returning a string with definitions.