@coderich/autograph 0.11.1 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +4 -6
- package/package.json +30 -44
- package/src/data/DataLoader.js +77 -70
- package/src/data/Emitter.js +89 -0
- package/src/data/Loader.js +33 -0
- package/src/data/Pipeline.js +88 -96
- package/src/data/Resolver.js +304 -0
- package/src/data/Transaction.js +49 -0
- package/src/query/Query.js +159 -334
- package/src/query/QueryBuilder.js +228 -114
- package/src/query/QueryResolver.js +110 -216
- package/src/query/QueryResolverTransaction.js +16 -0
- package/src/schema/Schema.js +593 -0
- package/src/service/AppService.js +38 -0
- package/src/service/ErrorService.js +7 -0
- package/CHANGELOG.md +0 -41
- package/LICENSE +0 -21
- package/README.md +0 -76
- package/src/.DS_Store +0 -0
- package/src/core/.DS_Store +0 -0
- package/src/core/Boom.js +0 -9
- package/src/core/EventEmitter.js +0 -95
- package/src/core/Resolver.js +0 -124
- package/src/core/Schema.js +0 -55
- package/src/core/ServerResolver.js +0 -15
- package/src/data/.DS_Store +0 -0
- package/src/data/DataService.js +0 -120
- package/src/data/DataTransaction.js +0 -96
- package/src/data/Field.js +0 -83
- package/src/data/Model.js +0 -223
- package/src/data/TreeMap.js +0 -78
- package/src/data/Type.js +0 -50
- package/src/driver/.DS_Store +0 -0
- package/src/driver/MongoDriver.js +0 -227
- package/src/driver/index.js +0 -11
- package/src/graphql/.DS_Store +0 -0
- package/src/graphql/ast/.DS_Store +0 -0
- package/src/graphql/ast/Field.js +0 -206
- package/src/graphql/ast/Model.js +0 -145
- package/src/graphql/ast/Node.js +0 -291
- package/src/graphql/ast/Schema.js +0 -133
- package/src/graphql/ast/Type.js +0 -26
- package/src/graphql/ast/TypeDefApi.js +0 -93
- package/src/graphql/extension/.DS_Store +0 -0
- package/src/graphql/extension/api.js +0 -193
- package/src/graphql/extension/framework.js +0 -71
- package/src/graphql/extension/type.js +0 -34
- package/src/query/.DS_Store +0 -0
- package/src/query/QueryBuilderTransaction.js +0 -26
- package/src/query/QueryService.js +0 -111
- package/src/service/.DS_Store +0 -0
- package/src/service/app.service.js +0 -319
- package/src/service/decorator.service.js +0 -114
- package/src/service/event.service.js +0 -66
- package/src/service/graphql.service.js +0 -92
- package/src/service/schema.service.js +0 -95
package/src/graphql/ast/Field.js
DELETED
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
const Node = require('./Node');
|
|
2
|
-
const Type = require('./Type');
|
|
3
|
-
const { uvl } = require('../../service/app.service');
|
|
4
|
-
|
|
5
|
-
module.exports = class Field extends Node {
|
|
6
|
-
constructor(model, ast) {
|
|
7
|
-
super(ast, 'field');
|
|
8
|
-
this.model = model;
|
|
9
|
-
this.schema = model.getSchema();
|
|
10
|
-
this.type = new Type(this.ast);
|
|
11
|
-
this.key = uvl(this.getDirectiveArg('field', 'key'), this.getName());
|
|
12
|
-
this.isArray = this.type.isArray.bind(this.type);
|
|
13
|
-
this.isArrayElementRequired = this.type.isArrayElementRequired.bind(this.type);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// Field Methods
|
|
17
|
-
getKey() {
|
|
18
|
-
return this.key;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
getType() {
|
|
22
|
-
return this.type.getName();
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
getDataType() {
|
|
26
|
-
const type = this.getType();
|
|
27
|
-
return this.isArray() ? [type] : type;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
getDataRef() {
|
|
31
|
-
return this.isScalar() ? null : this.getType();
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
getScalarRef() {
|
|
35
|
-
return this.schema.getScalar(this.getType());
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
getEnumRef() {
|
|
39
|
-
return this.schema.getEnum(this.getType());
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
getDefaultValue() {
|
|
43
|
-
return this.getDirectiveArg('field', 'default');
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Model Methods
|
|
47
|
-
getSchema() {
|
|
48
|
-
return this.model.getSchema();
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
getModel() {
|
|
52
|
-
return this.model;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
getModelRef() {
|
|
56
|
-
const refType = this.getDirectiveArg('field', 'id', this.getType());
|
|
57
|
-
return this.schema.getModel(refType);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
getFieldRef() {
|
|
61
|
-
const ref = this.getDirectiveArg('field', 'ref');
|
|
62
|
-
const modelRef = this.getModelRef();
|
|
63
|
-
if (!ref || !modelRef) return null;
|
|
64
|
-
return modelRef.getField(ref);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
getVirtualField() {
|
|
68
|
-
const model = this.getModelRef();
|
|
69
|
-
return model ? model.getField(this.getVirtualRef()) : null;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
getIdModel() {
|
|
73
|
-
return this.getModelRef() || this.getModel();
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
resolveField() {
|
|
77
|
-
const field = this.getVirtualField() || this;
|
|
78
|
-
return field === this ? this : field.resolveField();
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Boolean Methods
|
|
82
|
-
isScalar() {
|
|
83
|
-
return Boolean(this.type.isScalar() || !this.getModelRef());
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
isDefaulted() {
|
|
87
|
-
return Boolean(this.getDefaultValue() != null);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
isRequired() {
|
|
91
|
-
return this.type.isRequired() && this.getName() !== 'id';
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
isReference() {
|
|
95
|
-
return Boolean(this.getDirectiveArg('field', 'ref'));
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
isFKReference() {
|
|
99
|
-
const modelRef = this.getModelRef();
|
|
100
|
-
return Boolean(modelRef && !this.isEmbedded());
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
isIdField() {
|
|
104
|
-
return this.isPrimaryKeyId() || this.isFKReference();
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
isPrimaryKeyId() {
|
|
108
|
-
const key = this.getKey();
|
|
109
|
-
const idKey = this.getModel().idKey();
|
|
110
|
-
return key === idKey;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
getJoinInfo() {
|
|
114
|
-
const modelRef = this.getModelRef();
|
|
115
|
-
if (!modelRef || this.isEmbedded()) return null;
|
|
116
|
-
const vref = this.getVirtualRef();
|
|
117
|
-
const to = modelRef.getKey();
|
|
118
|
-
const by = vref || modelRef.idKey();
|
|
119
|
-
const from = vref ? this.getModel().idKey() : this.getKey();
|
|
120
|
-
return { to, by, from };
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
isConnection() {
|
|
124
|
-
// Deliberately need to specify this is a connection
|
|
125
|
-
const connection = Boolean(this.getDirectiveArg('field', 'connection'));
|
|
126
|
-
if (!connection) return false;
|
|
127
|
-
|
|
128
|
-
// Also needs to be proper
|
|
129
|
-
const modelRef = this.getModelRef();
|
|
130
|
-
return Boolean(modelRef && modelRef.isMarkedModel() && this.isArray() && !this.isEmbedded());
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
isSpliceable() {
|
|
134
|
-
const modelRef = this.getModelRef();
|
|
135
|
-
return Boolean(modelRef && modelRef.isMarkedModel() && this.isArray() && this.isEmbedded() && !this.isVirtual());
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// GQL Schema Methods
|
|
139
|
-
getGQLType(suffix, options = {}) {
|
|
140
|
-
let type = this.getType();
|
|
141
|
-
const modelType = `${type}${suffix}`;
|
|
142
|
-
if (suffix && !this.isScalar()) type = this.isEmbedded() ? modelType : 'ID';
|
|
143
|
-
type = this.isArray() ? `[${type}${this.isArrayElementRequired() ? '!' : ''}]` : type;
|
|
144
|
-
if (!suffix && this.isRequired()) type += '!';
|
|
145
|
-
if (suffix === 'InputCreate' && this.isRequired() && !this.isDefaulted()) type += '!';
|
|
146
|
-
return type;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
getExtendArgs() {
|
|
150
|
-
return this.isConnection() ? `(
|
|
151
|
-
where: ${this.getType()}InputWhere
|
|
152
|
-
sortBy: ${this.getType()}InputSort
|
|
153
|
-
limit: Int
|
|
154
|
-
skip: Int
|
|
155
|
-
first: Int
|
|
156
|
-
after: String
|
|
157
|
-
last: Int
|
|
158
|
-
before: String
|
|
159
|
-
)` : '';
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
getPayloadType() {
|
|
163
|
-
let type = this.getType();
|
|
164
|
-
const req = this.isRequired() ? '!' : '';
|
|
165
|
-
if (this.getName() === 'id') return 'ID!';
|
|
166
|
-
if (this.isConnection()) return `${type}Connection${req}`;
|
|
167
|
-
type = this.isArray() ? `[${type}${this.isArrayElementRequired() ? '!' : ''}]` : type;
|
|
168
|
-
return `${type}${req}`;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
getSubscriptionType() {
|
|
172
|
-
if (this.isFKReference()) return this.isArray() ? '[ID]' : 'ID';
|
|
173
|
-
return this.getGQLType();
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
finalize() {
|
|
177
|
-
this.props = {
|
|
178
|
-
key: this.getKey(),
|
|
179
|
-
name: this.getName(),
|
|
180
|
-
type: this.getType(),
|
|
181
|
-
model: this.model,
|
|
182
|
-
datatype: this.getDataType(),
|
|
183
|
-
defaultValue: this.getDefaultValue(),
|
|
184
|
-
isEnum: this.isEnum(),
|
|
185
|
-
isArray: this.isArray(),
|
|
186
|
-
isScalar: this.isScalar(),
|
|
187
|
-
isVirtual: this.isVirtual(),
|
|
188
|
-
isRequired: this.isRequired(),
|
|
189
|
-
isEmbedded: this.isEmbedded(),
|
|
190
|
-
isBasicType: this.isBasicType(),
|
|
191
|
-
isIdField: this.isIdField(),
|
|
192
|
-
isPrimaryKeyId: this.isPrimaryKeyId(),
|
|
193
|
-
isPersistable: this.isPersistable(),
|
|
194
|
-
idModel: this.getIdModel(),
|
|
195
|
-
modelRef: this.getModelRef(),
|
|
196
|
-
virtualRef: this.getVirtualRef(),
|
|
197
|
-
virtualField: this.getVirtualField(),
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
return this;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
toObject() {
|
|
204
|
-
return this.props;
|
|
205
|
-
}
|
|
206
|
-
};
|
package/src/graphql/ast/Model.js
DELETED
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
const Node = require('./Node');
|
|
2
|
-
const Field = require('./Field');
|
|
3
|
-
const { uvl } = require('../../service/app.service');
|
|
4
|
-
|
|
5
|
-
module.exports = class Model extends Node {
|
|
6
|
-
constructor(schema, ast) {
|
|
7
|
-
super(ast, 'model');
|
|
8
|
-
this.schema = schema;
|
|
9
|
-
this.fields = this.ast.fields.map(f => new Field(this, f));
|
|
10
|
-
this.fieldsByName = {};
|
|
11
|
-
this.fieldsByKey = {};
|
|
12
|
-
this.key = uvl(this.getDirectiveArg('model', 'key'), this.getName());
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
idKey() {
|
|
16
|
-
return this.getDirectiveArg('model', 'id', '_id');
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
getSchema() {
|
|
20
|
-
return this.schema;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
getFields() {
|
|
24
|
-
return this.fields;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
getKey() {
|
|
28
|
-
return this.key;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
getField(path = '') {
|
|
32
|
-
const [name, ...rest] = path.split('.');
|
|
33
|
-
let field = this.getFields().find(f => f.getName() === name);
|
|
34
|
-
if (!field) field = this.getFieldByKey(name);
|
|
35
|
-
if (field == null) return field;
|
|
36
|
-
|
|
37
|
-
if (rest.length) {
|
|
38
|
-
const modelRef = field.getModelRef();
|
|
39
|
-
return modelRef ? modelRef.getField(rest.join('.')) : null;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return field;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
getFieldByName(name) {
|
|
46
|
-
let field = this.fieldsByName[name];
|
|
47
|
-
|
|
48
|
-
if (!field) {
|
|
49
|
-
field = this.getFields().find(f => f.getName() === name);
|
|
50
|
-
this.fieldsByName[name] = field;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return field;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
getFieldByKey(key) {
|
|
57
|
-
let field = this.fieldsByKey[key];
|
|
58
|
-
|
|
59
|
-
if (!field) {
|
|
60
|
-
field = this.getFields().find(f => f.getKey() === key);
|
|
61
|
-
this.fieldsByKey[key] = field;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return field;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
getFieldNames() {
|
|
68
|
-
return this.getFields().map(field => field.getName());
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
getFieldMap() {
|
|
72
|
-
return this.getFields().reduce((prev, field) => Object.assign(prev, { [field.getName()]: field }), {});
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
getScalarFields() {
|
|
76
|
-
return this.getFields().filter(field => field.isBasicType());
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
getArrayFields() {
|
|
80
|
-
return this.getFields().filter(field => field.isArray());
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
getRequiredFields() {
|
|
84
|
-
return this.getFields().filter(field => field.isRequired());
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
getDefaultFields() {
|
|
88
|
-
return this.getFields().filter(field => field.getDefaultValue() != null);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
getDefaultedFields() {
|
|
92
|
-
return this.getFields().filter(field => field.isDefaulted());
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
getDataRefFields() {
|
|
96
|
-
return this.getFields().filter(field => Boolean(field.getDataRef()));
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
getModelRefFields() {
|
|
100
|
-
return this.getFields().filter(field => Boolean(field.getModelRef()));
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
getEmbeddedFields() {
|
|
104
|
-
return this.getFields().filter(field => field.isEmbedded());
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
getOnDeleteFields() {
|
|
108
|
-
return this.getFields().filter(field => Boolean(field.getDataRef()) && Boolean(field.getOnDelete()));
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
getSelectFields() {
|
|
112
|
-
return this.getFields().filter(field => field.isReadable());
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
getCountableFields() {
|
|
116
|
-
return this.getSelectFields().filter(field => field.isArray() && field.getDataRef());
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
getPersistableFields() {
|
|
120
|
-
return this.getFields().filter(field => field.isPersistable());
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Misc
|
|
124
|
-
getIndexes() {
|
|
125
|
-
return this.getDirectives('index').map((d) => {
|
|
126
|
-
return Object.entries(d.getArgs()).reduce((prev, [key, value]) => {
|
|
127
|
-
if (key === 'on') {
|
|
128
|
-
// Convert "on" field to key
|
|
129
|
-
value = value.map((el) => {
|
|
130
|
-
const field = this.getField(el);
|
|
131
|
-
if (!field) throw new Error(`Cannot create index on ${this}; Unknown fieldName '${el}'`);
|
|
132
|
-
return field.getKey();
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return Object.assign(prev, { [key]: value });
|
|
137
|
-
}, {});
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
finalize() {
|
|
142
|
-
this.fields.forEach(field => field.finalize());
|
|
143
|
-
return this;
|
|
144
|
-
}
|
|
145
|
-
};
|
package/src/graphql/ast/Node.js
DELETED
|
@@ -1,291 +0,0 @@
|
|
|
1
|
-
const { get } = require('lodash');
|
|
2
|
-
const { Kind } = require('graphql');
|
|
3
|
-
const { nvl, uvl } = require('../../service/app.service');
|
|
4
|
-
const { mergeAST } = require('../../service/graphql.service');
|
|
5
|
-
|
|
6
|
-
const operations = ['Query', 'Mutation', 'Subscription'];
|
|
7
|
-
const modelKinds = [Kind.OBJECT_TYPE_DEFINITION, Kind.OBJECT_TYPE_EXTENSION, Kind.INTERFACE_TYPE_DEFINITION, Kind.INTERFACE_TYPE_EXTENSION];
|
|
8
|
-
const inputKinds = [Kind.INPUT_OBJECT_TYPE_DEFINITION, Kind.INPUT_OBJECT_TYPE_EXTENSION];
|
|
9
|
-
const scalarKinds = [Kind.SCALAR_TYPE_DEFINITION, Kind.SCALAR_TYPE_EXTENSION];
|
|
10
|
-
const enumKinds = [Kind.ENUM_TYPE_DEFINITION, Kind.ENUM_TYPE_EXTENSION];
|
|
11
|
-
|
|
12
|
-
module.exports = class Node {
|
|
13
|
-
constructor(astLike, nodeType) {
|
|
14
|
-
this.ast = mergeAST(astLike);
|
|
15
|
-
this.arguments = (this.ast.arguments || []).map(el => new Node(el));
|
|
16
|
-
this.directives = (this.ast.directives || []).map(el => new Node(el));
|
|
17
|
-
this.toString = () => this.getName();
|
|
18
|
-
this.nodeType = nodeType;
|
|
19
|
-
this.name = get(this.ast, 'name.value');
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// Basic AST Methods
|
|
23
|
-
getAST() {
|
|
24
|
-
return this.ast;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
getKind() {
|
|
28
|
-
return this.ast.kind;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
getName() {
|
|
32
|
-
return this.name;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
getValue(ast = this.ast) {
|
|
36
|
-
const { value = {} } = ast;
|
|
37
|
-
|
|
38
|
-
switch (value.kind) {
|
|
39
|
-
case Kind.NULL: return null;
|
|
40
|
-
case Kind.LIST: return value.values.map(el => this.getValue({ value: el }));
|
|
41
|
-
case Kind.OBJECT: {
|
|
42
|
-
return value.fields.reduce((prev, field) => {
|
|
43
|
-
const node = new Node(field);
|
|
44
|
-
return Object.assign(prev, { [node.getName()]: node.getValue() });
|
|
45
|
-
}, {});
|
|
46
|
-
}
|
|
47
|
-
default: {
|
|
48
|
-
if (ast.values) return ast.values.map(v => v.name.value);
|
|
49
|
-
return value.value;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
getDescription() {
|
|
55
|
-
return get(this.ast, 'description.value');
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Directive Methods
|
|
59
|
-
getDirectives(...names) {
|
|
60
|
-
return this.directives.filter(directive => names.indexOf(directive.getName()) > -1);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
getDirective(name) {
|
|
64
|
-
return this.directives.find(directive => directive.getName() === name);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
getDirectiveArg(name, arg, defaultValue) {
|
|
68
|
-
const directive = this.getDirective(name);
|
|
69
|
-
if (!directive) return defaultValue;
|
|
70
|
-
return uvl(directive.getArg(arg), defaultValue);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
getDirectiveArgs(name, defaultValue) {
|
|
74
|
-
const directive = this.getDirective(name);
|
|
75
|
-
if (!directive) return defaultValue;
|
|
76
|
-
return directive.getArgs();
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Argument Methods
|
|
80
|
-
getArgs() {
|
|
81
|
-
return this.arguments.reduce((prev, arg) => {
|
|
82
|
-
return Object.assign(prev, { [arg.getName()]: arg.getValue() });
|
|
83
|
-
}, {});
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
getArg(arg) {
|
|
87
|
-
return this.getArgs()[arg];
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
getArguments() {
|
|
91
|
-
return this.arguments;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
getArgument(name) {
|
|
95
|
-
return this.getArguments().find(arg => arg.getName() === name);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// // Framework Methods
|
|
99
|
-
// getKey() {
|
|
100
|
-
// switch (this.nodeType) {
|
|
101
|
-
// case 'model': return uvl(this.getDirectiveArg('model', 'key'), this.getName());
|
|
102
|
-
// case 'field': return uvl(this.getDirectiveArg('field', 'key'), this.getName());
|
|
103
|
-
// default: return null;
|
|
104
|
-
// }
|
|
105
|
-
// }
|
|
106
|
-
|
|
107
|
-
getOnDelete() {
|
|
108
|
-
return this.getDirectiveArg('field', 'onDelete');
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
getDriverName() {
|
|
112
|
-
return this.getDirectiveArg('model', 'driver', 'default');
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
getNamespace() {
|
|
116
|
-
return this.getDirectiveArg('model', 'namespace', this.getName());
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
getVirtualRef() {
|
|
120
|
-
return this.getDirectiveArg('link', 'by');
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
getAuthz() {
|
|
124
|
-
return this.getDirectiveArg('field', 'authz', this.getDirectiveArg('model', 'authz', 'private'));
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
getMeta() {
|
|
128
|
-
return this.getDirectiveArg('model', 'meta');
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Booleans
|
|
132
|
-
isModel() {
|
|
133
|
-
return Boolean(modelKinds.some(k => this.getKind() === k) && operations.every(o => this.getName() !== o));
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
isInput() {
|
|
137
|
-
return Boolean(inputKinds.some(k => this.getKind() === k));
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
isScalar() {
|
|
141
|
-
return Boolean(scalarKinds.some(k => this.getKind() === k));
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
isEnum() {
|
|
145
|
-
return Boolean(enumKinds.some(k => this.getKind() === k));
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
isBasicType() {
|
|
149
|
-
return this.isScalar() || this.isEnum();
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Is the field virtual; does it's value come from another model
|
|
154
|
-
*/
|
|
155
|
-
isVirtual() {
|
|
156
|
-
return Boolean(this.getDirectiveArg('link', 'by'));
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Is a model annotated with @model
|
|
161
|
-
*/
|
|
162
|
-
isMarkedModel() {
|
|
163
|
-
return Boolean(this.getDirective('model'));
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Is the model ready, willing, and able to communicate with external data
|
|
168
|
-
*/
|
|
169
|
-
isEntity() {
|
|
170
|
-
return Boolean(this.getDALScope() !== '' && !this.isEmbedded());
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Can this be persisted to the db
|
|
175
|
-
*/
|
|
176
|
-
isPersistable() {
|
|
177
|
-
return uvl(this.getDirectiveArg('field', 'persist'), this.getDirectiveArg('model', 'persist'), true);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Is this embedded in another document
|
|
182
|
-
*/
|
|
183
|
-
isEmbedded() {
|
|
184
|
-
switch (this.nodeType) {
|
|
185
|
-
case 'model': return Boolean(this.getDirectiveArg('model', 'embed')); // Must be marked; otherwise no way to contain the API traversal
|
|
186
|
-
case 'field': {
|
|
187
|
-
const model = this.getModelRef();
|
|
188
|
-
return Boolean(!this.isReference() && model && !model.isEntity());
|
|
189
|
-
}
|
|
190
|
-
default: return false;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Define it's behavior at the Data Access Layer
|
|
196
|
-
*
|
|
197
|
-
* Model + Field:
|
|
198
|
-
* C: Can be created (Resolver should throw. NOT the same meaning as persisted)
|
|
199
|
-
* R: Can be read (if not must be stripped out)
|
|
200
|
-
* U: Can be updated (if not must be stripped out)
|
|
201
|
-
* D: Can be deleted (if not must be stripped out)
|
|
202
|
-
*/
|
|
203
|
-
getDALScope() {
|
|
204
|
-
switch (this.nodeType) {
|
|
205
|
-
case 'model': {
|
|
206
|
-
if (!this.isMarkedModel()) return '';
|
|
207
|
-
return nvl(uvl(this.getDirectiveArg('model', 'dalScope'), 'crud'), '');
|
|
208
|
-
}
|
|
209
|
-
case 'field': return nvl(uvl(this.getDirectiveArg('field', 'dalScope'), 'crud'), '');
|
|
210
|
-
default: return '';
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
hasDALScope(...els) {
|
|
215
|
-
return els.some(el => Boolean(this.getDALScope().toLowerCase().indexOf(el.toLowerCase()) > -1));
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Define it's behavior in the GraphQL API
|
|
220
|
-
*
|
|
221
|
-
* Model:
|
|
222
|
-
* C: Generate createModel Mutation
|
|
223
|
-
* R: Generate get|find|count Queries
|
|
224
|
-
* U: Generate updateModel Mutation
|
|
225
|
-
* D: Generate deleteModel Mutation
|
|
226
|
-
* Field:
|
|
227
|
-
* C: Include this field in InputCreate
|
|
228
|
-
* R: Include my value in the results (strip it out beforehand)
|
|
229
|
-
* U: Include this field in InputUpdate
|
|
230
|
-
* D: Allow the API to delete (null out)
|
|
231
|
-
*/
|
|
232
|
-
getGQLScope() {
|
|
233
|
-
switch (this.nodeType) {
|
|
234
|
-
case 'model': {
|
|
235
|
-
if (!this.isMarkedModel()) return '';
|
|
236
|
-
return nvl(uvl(this.getDirectiveArg('model', 'gqlScope'), 'cruds'), '');
|
|
237
|
-
}
|
|
238
|
-
case 'field': return nvl(uvl(this.getDirectiveArg('field', 'gqlScope'), 'cruds'), '');
|
|
239
|
-
default: return '';
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
hasGQLScope(...els) {
|
|
244
|
-
if (this.nodeType === 'field') {
|
|
245
|
-
const model = this.getModelRef();
|
|
246
|
-
if (model && !model.hasFieldScope(...els)) return false;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
return els.some(el => Boolean(this.getGQLScope().toLowerCase().indexOf(el.toLowerCase()) > -1));
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
getFieldScope() {
|
|
253
|
-
switch (this.nodeType) {
|
|
254
|
-
case 'model': return nvl(uvl(this.getDirectiveArg('model', 'fieldScope'), 'crud'), '');
|
|
255
|
-
case 'field': return nvl(uvl(this.getDirectiveArg('field', 'fieldScope'), 'crud'), '');
|
|
256
|
-
default: return '';
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
hasFieldScope(...els) {
|
|
261
|
-
return els.some(el => Boolean(this.getFieldScope().toLowerCase().indexOf(el.toLowerCase()) > -1));
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
/**
|
|
265
|
-
* Does the field have an explicit "resolve" set
|
|
266
|
-
*/
|
|
267
|
-
hasResolver() {
|
|
268
|
-
return Boolean(this.getDirectiveArg('field', 'resolve'));
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
// Create
|
|
273
|
-
isCreatable() {
|
|
274
|
-
return Boolean(this.getDALScope().toLowerCase().indexOf('c') > -1);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
// Read
|
|
278
|
-
isReadable() {
|
|
279
|
-
return Boolean(this.getDALScope().toLowerCase().indexOf('r') > -1);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
// Update
|
|
283
|
-
isUpdatable() {
|
|
284
|
-
return Boolean(this.getDALScope().toLowerCase().indexOf('u') > -1);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// Delete
|
|
288
|
-
isDeletable() {
|
|
289
|
-
return Boolean(this.getDALScope().toLowerCase().indexOf('d') > -1);
|
|
290
|
-
}
|
|
291
|
-
};
|