-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathLinkDirective.js
100 lines (87 loc) · 2.92 KB
/
LinkDirective.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { SchemaDirectiveVisitor } from 'graphql-tools';
import { GraphQLList, GraphQLObjectType, GraphQLNonNull } from 'graphql/type';
import { Mongo } from 'meteor/mongo';
import { setupMongoDirective } from './MongoDirective';
export default class LinkDirective extends SchemaDirectiveVisitor {
visitFieldDefinition(field, details) {
const { objectType } = details;
const { args } = this;
if (!objectType._mongoCollectionName) {
throw new Meteor.Error(
'collection-not-found',
`You are trying to set the link: ${
field.name
} but your object type does not have @mongo directive set-up`
);
}
const isArrayField = field.type instanceof GraphQLList;
let referencedType;
if (isArrayField) {
referencedType = field.type.ofType;
} else {
referencedType = field.type;
}
if (referencedType instanceof GraphQLNonNull) {
referencedType = referencedType.ofType;
} else {
if (!(referencedType instanceof GraphQLObjectType)) {
throw new Meteor.Error(
'invalid-type',
`You are trying to attach a link on a invalid type. @link directive only works with GraphQLObjectType `
);
}
}
let referencedCollectionName = referencedType._mongoCollectionName;
if (!referencedCollectionName) {
const objectNodeDirectives = referencedType.astNode.directives;
const mongoDirective = objectNodeDirectives.find(directive => {
return directive.name.value === 'mongo';
});
if (mongoDirective) {
const nameArgument = mongoDirective.arguments.find(
argument => argument.name.value === 'name'
);
setupMongoDirective(referencedType, {
name: nameArgument.value.value,
});
referencedCollectionName = nameArgument.value.value;
} else {
throw new Meteor.Error(
'invalid-collection',
`The referenced type does not have a collection setup using @mongo directive`
);
}
}
const thisCollectionName = objectType._mongoCollectionName;
const referencedCollection = Mongo.Collection.get(referencedCollectionName);
const thisCollection = Mongo.Collection.get(thisCollectionName);
let config = {};
if (args.to) {
config = Object.assign({}, args);
config.inversedBy = args.to;
delete config.to;
} else {
if (args.field) {
config = Object.assign(
{
type: isArrayField ? 'many' : 'one',
field: args.field,
index: true,
},
args
);
} else {
throw new Meteor.Error(
`invalid-args`,
`You have provided invalid arguments for this link in ${thisCollectionName}. The "field" property is missing.`
);
}
}
thisCollection.addLinks({
[field.name]: {
collection: referencedCollection,
...config,
},
});
}
}