graph-schema-json-writer
v1.2.8
Published
Write JSON/Object GraphQL schema to GraphQL Type Definition strings or TypeScript source files
Downloads
42
Maintainers
Readme
GraphQL schema JSON Writer
Extension to graphSchemaToJson to write the schema generated from a GraphQL type def to various outputs:
- Typescript source files
- GraphQL type def files
Also includes accessor functionality to better work with the schema object generated.
Usage
{
Person: {
fields: {
name: {
type: 'String',
directives: {},
isNullable: false,
isList: false
},
age: {
type: 'Int',
directives: {
range: {
min: 0,
max: 130
}
},
isNullable: false,
isList: false
},
gender: {
type: 'Gender',
directives: {},
isNullable: false,
isList: false
}
},
directives: {},
type: 'Object',
implements: []
},
Gender: {
fields: ['male', 'female'],
directives: {},
type: 'Enum'
}
}Accessor
import { schemaToJS } from "../src/schema";
import { accessor } from "graph-schema-json-writer";
const { schemaByType, filteredSchema } = accessor;
/// ... generate JSON schema
const jsSchema = schemaToJS(schema);
// schema where all entries with keys starting with __ are filtered out
const filteredMap = filteredSchema(jsSchema);
// soreted by type
const typeMap = schemaByType(jsSchema);
console.log(typeMap);{
Object: {
Person: {
// ....
}
},
Enum: {
Gender: {
// ...
}
}
}Writer
import { schemaToJS } from "../src/schema";
import { writer } from "graph-schema-json-writer";
const { writeToTypeDef } = writer;
/// ... generate JSON schema
const jsSchema = schemaToJS(schema);
// schema where all entries with keys starting with __ are filtered out
const typeDef = writeToTypeDef(jsSchema);
console.log(typeDef);Should output the (original) GraphqL type def, nicely formatted:
type Person {
name: String!
age: Int! @range(min: 0, max: 130)
gender: Gender!
}
enum Gender {
male
female
}Writing typescript source files
The writer also supports writing a TypeScript class, complete with:
extendsclass- implements
interfaces - decorators for class itself and fields and properties
- imports for the decorators, interfaces and class extended
import { schemaToJS } from "../src/schema";
import { writer, createClass } from "graph-schema-json-writer";
/// ... generate JSON schema
const jsSchema = schemaToJS(schema);
const classType = createClass(jsSchema);
const importsMap = {
Range: "class-validator",
BaseEntity: "typeorm",
Entity: "typeorm"
};
const body = classType.writeClass("Person", jsSchema.Person, {
importsMap
});
console.log(sourceFileTxt);Output a TypeScript class with decorators
import { BaseEntity, Entity } from 'typeorm';
import { Range } from 'class-validator';
@Entity()
class Person extends BaseEntity {
name: string
@Range(min: 0, max: 130)
age: number
}Writing source files
Use the SourceFile class to write source files to disk:
import { createSoureFileWriter, importsMap } from "graph-schema-json-writer";
// include typical import maps, such as for typeorm and class-validator
const myImportsMap = {
...importsMap.all
// ...custom additions or overrides
};
const writeOpts = {
importsMap: myImportsMap,
srcFileDir: fs.join(__dirname, "db/model"),
only: ["Person", "Gender"],
enumRefs: true, // resolve enumRefs using importsMap
// classRefs true, // resolve classRefs using importsMap
validate: true // validate that each const reference has an entry in importsMap
};
const srcFileWriter = createSoureFileWriter(writeOpts);
await srcFileWriter.writeTypeDefs(jsSchema, writeOpts);
await srcFileWriter.writeIndexFiles();Files written, assuming __dirname is /src, using default flat strategy:
/src
/db
/models
Person.ts
Gender.ts
index.tsUsing defaults:
import { writeTypeDefs, importsMap } from "graph-schema-json-writer";
// ...
await writeTypeDefs(jsSchema, {
importsMap: importsMap.all,
srcFileDir: fs.join(__dirname, "db/model"),
strategy: "type-folder",
only: ["Person", "Gender"],
index: true // also add index files
});Files written using type-folder strategy:
/src
/db
/models
/class
Person.ts
index.ts
/enum/
Gender.ts
index.ts
index.tsNote: The SourceFileWriter has not yet been fully tested and could use some futher refactoring. It should include enough building blocks for you to compose a solution to fit your needs ;)
Imports map
Imports maps now have support for aliases
importsMap = {
range: { name: "Range", importPath: "validator" }
};Will result in an aliased import:
import { Range as range } from 'validator';
Use cases
This class writer could be used for writing classed for TypeORM, NestJS or TypeGraphQL etc.
Note that the class writer supports passing decorators in place of directives.
License
MIT
