Skip to content
This repository has been archived by the owner on Apr 15, 2020. It is now read-only.

Commit

Permalink
feat(WrapType): add WrapType transform
Browse files Browse the repository at this point in the history
  • Loading branch information
yaacovCR committed Oct 3, 2019
1 parent 226a644 commit 43f13fc
Show file tree
Hide file tree
Showing 3 changed files with 211 additions and 0 deletions.
147 changes: 147 additions & 0 deletions src/test/testAlternateMergeSchemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
RenameObjectFields,
TransformObjectFields,
ExtendSchema,
WrapType,
} from '../transforms';
import {
propertySchema,
Expand Down Expand Up @@ -485,6 +486,152 @@ type Query {
});
});

describe('WrapType transform', () => {
let transformedPropertySchema: GraphQLSchema;

before(async () => {
transformedPropertySchema = transformSchema(propertySchema, [
new WrapType('Query', 'Namespace_Query', 'namespace'),
]);
});

it('should modify the schema', () => {
/* tslint:disable:max-line-length */
expect(printSchema(transformedPropertySchema)).to.equal(`type Address {
street: String
city: String
state: String
zip: String
}
"""Simple fake datetime"""
scalar DateTime
input InputWithDefault {
test: String = "Foo"
}
"""
The \`JSON\` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf).
"""
scalar JSON
type Location {
name: String!
}
type Namespace_Query {
propertyById(id: ID!): Property
properties(limit: Int): [Property!]
contextTest(key: String!): String
dateTimeTest: DateTime
jsonTest(input: JSON): JSON
interfaceTest(kind: TestInterfaceKind): TestInterface
unionTest(output: String): TestUnion
errorTest: String
errorTestNonNull: String!
relay: Query!
defaultInputTest(input: InputWithDefault!): String
}
type Property {
id: ID!
name: String!
location: Location
address: Address
error: String
}
type Query {
namespace: Namespace_Query
}
type TestImpl1 implements TestInterface {
kind: TestInterfaceKind
testString: String
foo: String
}
type TestImpl2 implements TestInterface {
kind: TestInterfaceKind
testString: String
bar: String
}
interface TestInterface {
kind: TestInterfaceKind
testString: String
}
enum TestInterfaceKind {
ONE
TWO
}
union TestUnion = TestImpl1 | UnionImpl
type UnionImpl {
someField: String
}
`
/* tslint:enable:max-line-length */
);
});

it('should work', async () => {
const result = await graphql(
transformedPropertySchema,
`
query($pid: ID!) {
namespace {
propertyById(id: $pid) {
id
name
error
}
}
}
`,
{},
{},
{
pid: 'p1',
},
);

expect(result).to.deep.equal({
data: {
namespace: {
propertyById: {
id: 'p1',
name: 'Super great hotel',
error: null,
},
},
},
errors: [
{
extensions: {
code: 'SOME_CUSTOM_CODE',
},
locations: [
{
column: 15,
line: 7,
},
],
message: 'Property.error error',
path: [
'namespace',
'propertyById',
'error',
],
},
]
});
});
});

describe('ExtendSchema transform', () => {
let transformedPropertySchema: GraphQLSchema;

Expand Down
63 changes: 63 additions & 0 deletions src/transforms/WrapType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/* tslint:disable:no-unused-expression */

import { GraphQLSchema, GraphQLObjectType } from 'graphql';
import { Request } from '../Interfaces';
import { Transform } from './transforms';
import { cloneType, healSchema } from '../utils';
import { extractFields } from '../stitching';
import { default as ExtendSchema } from './ExtendSchema';

export default class WrapType implements Transform {
private outerTypeName: string;
private innerTypeName: string;
private fieldName: string;
private transformer: Transform;

constructor(
outerTypeName: string,
innerTypeName: string,
fieldName: string
) {
this.outerTypeName = outerTypeName;
this.innerTypeName = innerTypeName;
this.fieldName = fieldName;
this.transformer = new ExtendSchema({
resolvers: {
[outerTypeName]: {
[fieldName]: parent => parent,
},
},
fieldNodeTransformerMap: {
[outerTypeName]: {
[fieldName]: (fieldNode, fragments) => extractFields({ fieldNode, fragments }),
},
}
});
}

public transformSchema(schema: GraphQLSchema): GraphQLSchema {
const typeMap = schema.getTypeMap();

// Clone the outer type before modification.
// When healing, changing the type name of a root type changes the root type name.
const innerType = cloneType(typeMap[this.outerTypeName]);
innerType.name = this.innerTypeName;

typeMap[this.innerTypeName] = innerType;

typeMap[this.outerTypeName] = new GraphQLObjectType({
name: this.outerTypeName,
fields: {
[this.fieldName]: {
type: typeMap[this.innerTypeName] as GraphQLObjectType,
},
},
});

return this.transformer.transformSchema(healSchema(schema));
}

public transformRequest(originalRequest: Request): Request {
return this.transformer.transformRequest(originalRequest);
}
}
1 change: 1 addition & 0 deletions src/transforms/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ export { default as WrapQuery } from './WrapQuery';
export { default as TransformQuery } from './TransformQuery';

export { default as ExtendSchema } from './ExtendSchema';
export { default as WrapType } from './WrapType';
export { default as MapFields } from './MapFields';

0 comments on commit 43f13fc

Please sign in to comment.