Skip to content

Commit

Permalink
First pass at extend package
Browse files Browse the repository at this point in the history
  • Loading branch information
emmatown committed Oct 12, 2021
1 parent dc97425 commit 3b6d533
Show file tree
Hide file tree
Showing 4 changed files with 548 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/itchy-monkeys-flash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@graphql-ts/extend": minor
---

Initial release
22 changes: 22 additions & 0 deletions packages/extend/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "@graphql-ts/extend",
"version": "0.0.0",
"main": "dist/graphql-ts-extend.cjs.js",
"module": "dist/graphql-ts-extend.esm.js",
"files": [
"dist"
],
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.9.2"
},
"peerDependencies": {
"@graphql-ts/schema": "^0.3.0",
"graphql": "^15.0.0"
},
"devDependencies": {
"@graphql-ts/schema": "^0.3.1",
"graphql": "^15.5.0"
},
"repository": "https://github.com/Thinkmill/graphql-ts/tree/main/packages/extend"
}
317 changes: 317 additions & 0 deletions packages/extend/src/extend.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,317 @@
import { GraphQLSchema, graphqlSync, printSchema } from "graphql";
import { graphql } from "@graphql-ts/schema";
import { extend } from ".";

const getGql =
(schema: GraphQLSchema) =>
([source]: TemplateStringsArray) =>
graphqlSync({ schema, source });

expect.addSnapshotSerializer({
test(arg) {
return arg instanceof GraphQLSchema;
},
serialize(val: GraphQLSchema) {
return printSchema(val).trim();
},
});

const onlyQuery = new GraphQLSchema({
query: graphql.object()({
name: "Query",
fields: {
thing: graphql.field({
type: graphql.String,
resolve() {
return "Thing";
},
}),
},
}).graphQLType,
});

test("basic query", () => {
const extended = extend({
query: {
hello: graphql.field({
type: graphql.String,
resolve() {
return "Hello!";
},
}),
},
})(onlyQuery);
expect(extended).toMatchInlineSnapshot(`
type Query {
thing: String
hello: String
}
`);
const gql = getGql(extended);
expect(gql`
query {
hello
thing
}
`).toMatchInlineSnapshot(`
Object {
"data": Object {
"hello": "Hello!",
"thing": "Thing",
},
}
`);
});

test("basic mutation with no existing mutations", () => {
const extended = extend({
mutation: {
something: graphql.field({
type: graphql.String,
resolve() {
return "";
},
}),
},
})(onlyQuery);
expect(extended).toMatchInlineSnapshot(`
type Mutation {
something: String
}
type Query {
thing: String
}
`);
const gql = getGql(extended);
expect(gql`
mutation {
something
}
`).toMatchInlineSnapshot(`
Object {
"data": Object {
"something": "",
},
}
`);
});

test("basic mutation with existing mutations", () => {
const queryAndMutation = new GraphQLSchema({
query: graphql.object()({
name: "Query",
fields: {
thing: graphql.field({
type: graphql.String,
resolve() {
return "Thing";
},
}),
},
}).graphQLType,
mutation: graphql.object()({
name: "Mutation",
fields: {
thing: graphql.field({
type: graphql.String,
resolve() {
return "Thing";
},
}),
},
}).graphQLType,
});
const extended = extend({
mutation: {
something: graphql.field({
type: graphql.String,
resolve() {
return "";
},
}),
},
})(queryAndMutation);
expect(extended).toMatchInlineSnapshot(`
type Query {
thing: String
}
type Mutation {
thing: String
something: String
}
`);
const gql = getGql(extended);
expect(gql`
mutation {
something
}
`).toMatchInlineSnapshot(`
Object {
"data": Object {
"something": "",
},
}
`);
});

test("errors when query type is used elsewhere in schema", () => {
const Query: graphql.ObjectType<{}> = graphql.object<{}>()({
name: "Query",
fields: () => ({
thing: graphql.field({
type: graphql.String,
resolve() {
return "Thing";
},
}),
other: graphql.field({
type: Query,
resolve() {
return {};
},
}),
}),
});
const initial = new GraphQLSchema({
query: Query.graphQLType,
});
try {
extend({
mutation: {
something: graphql.field({
type: graphql.String,
resolve() {
return "";
},
}),
},
})(initial);
expect(true).toBe(false);
} catch (err) {
expect(err.message).toMatchInlineSnapshot(`
"@graphql-ts/extend doesn't yet support using the query and mutation types in other types but
- Query is used at Query.other"
`);
}
});

test("errors when query and mutation type is used elsewhere in schema", () => {
const Query: graphql.ObjectType<{}> = graphql.object<{}>()({
name: "Query",
fields: () => ({
thing: graphql.field({
type: graphql.String,
resolve() {
return "Thing";
},
}),
}),
});
const Mutation: graphql.ObjectType<{}> = graphql.object<{}>()({
name: "Mutation",
fields: () => ({
thing: graphql.field({
type: graphql.String,
resolve() {
return "Thing";
},
}),
other: graphql.field({
type: Mutation,
resolve() {
return {};
},
}),
}),
});
const initial = new GraphQLSchema({
query: Query.graphQLType,
mutation: Mutation.graphQLType,
});
try {
extend({
mutation: {
something: graphql.field({
type: graphql.String,
resolve() {
return "";
},
}),
},
})(initial);
expect(true).toBe(false);
} catch (err) {
expect(err.message).toMatchInlineSnapshot(`
"@graphql-ts/extend doesn't yet support using the query and mutation types in other types but
- Mutation is used at Mutation.other"
`);
}
});

test("errors when query and mutation type is used elsewhere in schema", () => {
const Query: graphql.ObjectType<{}> = graphql.object<{}>()({
name: "Query",
fields: () => ({
thing: graphql.field({
type: graphql.String,
resolve() {
return "Thing";
},
}),
other: graphql.field({
type: Query,
resolve() {
return {};
},
}),
otherBlah: graphql.field({
type: Query,
resolve() {
return {};
},
}),
}),
});
const Mutation: graphql.ObjectType<{}> = graphql.object<{}>()({
name: "Mutation",
fields: () => ({
thing: graphql.field({
type: graphql.String,
resolve() {
return "Thing";
},
}),
other: graphql.field({
type: Mutation,
resolve() {
return {};
},
}),
}),
});
const initial = new GraphQLSchema({
query: Query.graphQLType,
mutation: Mutation.graphQLType,
});
try {
extend({
mutation: {
something: graphql.field({
type: graphql.String,
resolve() {
return "";
},
}),
},
})(initial);
expect(true).toBe(false);
} catch (err) {
expect(err.message).toMatchInlineSnapshot(`
"@graphql-ts/extend doesn't yet support using the query and mutation types in other types but
- Query is used at Query.other, Query.otherBlah
- Mutation is used at Mutation.other"
`);
}
});

0 comments on commit 3b6d533

Please sign in to comment.