agoo 2.11.7 → 2.12.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of agoo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/ext/agoo/gqleval.c +85 -21
- data/ext/agoo/gqleval.h +6 -0
- data/ext/agoo/gqlintro.c +175 -103
- data/ext/agoo/gqljson.c +3 -0
- data/ext/agoo/gqlvalue.c +5 -5
- data/ext/agoo/graphql.c +35 -24
- data/ext/agoo/graphql.h +11 -15
- data/ext/agoo/rgraphql.c +160 -6
- data/ext/agoo/rserver.c +4 -1
- data/ext/agoo/sdl.c +23 -26
- data/ext/agoo/sdl.h +1 -1
- data/lib/agoo/version.rb +1 -1
- data/test/graphql_test.rb +22 -18
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad6f1d492f68755c2012b61062a79fe3351a1b80546838d19eb4315789f4585c
|
4
|
+
data.tar.gz: 6a1a949bdf6fb76d1228e9e7e61ded57d76ca414a21529eec46ae1275e624277
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b43da3e33ef225b675164ad4793b4304bc42db3c0a0803b84584250e58713d4026b10e9a450b3de8bbe18814a3ce102438fd1448658919e5a345fafe8583bc64
|
7
|
+
data.tar.gz: fbe407798233527d8ce736bac219224b00714ca8a902b5110a5c15fd2f88a2962d04fdb6945517377c1cebdde623c2d7a0162fd414c2f17dfdb23ac01dc86779
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,20 @@
|
|
2
2
|
|
3
3
|
All changes to the Agoo gem are documented here. Releases follow semantic versioning.
|
4
4
|
|
5
|
+
## [2.12.0] - 2020-01-19
|
6
|
+
|
7
|
+
Request GraphQL access and GraphiQL support
|
8
|
+
|
9
|
+
### Added
|
10
|
+
|
11
|
+
- Optional addition of request information is now available in GraphQL resolve functions.
|
12
|
+
|
13
|
+
- Headers for GraphQL responses can now be set.
|
14
|
+
|
15
|
+
- Fixed incorrect values in introspection responses.
|
16
|
+
|
17
|
+
- Fixed JSON parser bug with null, true, and false.
|
18
|
+
|
5
19
|
## [2.11.7] - 2020-01-02
|
6
20
|
|
7
21
|
Ruby 2.7.0 cleanup
|
data/ext/agoo/gqleval.c
CHANGED
@@ -36,8 +36,9 @@ static const char query_str[] = "query";
|
|
36
36
|
static const char subscription_str[] = "subscription";
|
37
37
|
static const char variables_str[] = "variables";
|
38
38
|
|
39
|
-
|
40
39
|
gqlValue (*gql_doc_eval_func)(agooErr err, gqlDoc doc) = NULL;
|
40
|
+
agooText (*gql_build_headers)(agooErr err, agooReq req, agooText headers) = NULL;
|
41
|
+
agooText gql_headers = NULL;
|
41
42
|
|
42
43
|
static void
|
43
44
|
err_resp(agooRes res, agooErr err, int status) {
|
@@ -93,25 +94,74 @@ value_resp(agooReq req, gqlValue result, int status, int indent) {
|
|
93
94
|
break;
|
94
95
|
default:
|
95
96
|
agoo_log_cat(&agoo_error_cat, "Did not expect an HTTP status of %d.", status);
|
96
|
-
|
97
|
+
agoo_err_set(&err, AGOO_ERR_EVAL, "Did not expect an HTTP status of %d.", status);
|
98
|
+
goto FAILED;
|
97
99
|
}
|
98
100
|
agoo_res_message_push(res, text);
|
99
101
|
return;
|
100
102
|
}
|
101
103
|
if (AGOO_ERR_OK != gql_object_set(&err, msg, "data", result)) {
|
102
|
-
|
103
|
-
gql_value_destroy(result);
|
104
|
-
return;
|
104
|
+
goto FAILED;
|
105
105
|
}
|
106
106
|
text = gql_value_json(text, msg, indent, 0);
|
107
107
|
gql_value_destroy(msg); // also destroys result
|
108
|
+
result = NULL;
|
108
109
|
|
109
110
|
cnt = snprintf(buf, sizeof(buf), "HTTP/1.1 %d %s\r\nContent-Type: application/json\r\nContent-Length: %ld\r\n\r\n",
|
110
111
|
status, agoo_http_code_message(status), text->len);
|
111
|
-
if (NULL
|
112
|
-
|
112
|
+
if (NULL != gql_headers || NULL != gql_build_headers) {
|
113
|
+
agooText headers = agoo_text_allocate(4094);
|
114
|
+
|
115
|
+
headers = agoo_text_append(headers, buf, cnt - 2);
|
116
|
+
if (NULL == headers) {
|
117
|
+
agoo_log_cat(&agoo_error_cat, "Failed to allocate memory for a response.");
|
118
|
+
return;
|
119
|
+
}
|
120
|
+
if (NULL != gql_headers) {
|
121
|
+
headers = agoo_text_append(headers, gql_headers->text, (int)gql_headers->len);
|
122
|
+
} else {
|
123
|
+
headers = gql_build_headers(&err, req, headers);
|
124
|
+
}
|
125
|
+
headers = agoo_text_append(headers, "\r\n", 2);
|
126
|
+
if (NULL == headers) {
|
127
|
+
agoo_log_cat(&agoo_error_cat, "Failed to allocate memory for a response.");
|
128
|
+
return;
|
129
|
+
}
|
130
|
+
if (NULL == (text = agoo_text_prepend(text, headers->text, (int)headers->len))) {
|
131
|
+
agoo_log_cat(&agoo_error_cat, "Failed to allocate memory for a response.");
|
132
|
+
agoo_text_release(headers);
|
133
|
+
return;
|
134
|
+
}
|
135
|
+
agoo_text_release(headers);
|
136
|
+
} else {
|
137
|
+
if (NULL == (text = agoo_text_prepend(text, buf, cnt))) {
|
138
|
+
agoo_log_cat(&agoo_error_cat, "Failed to allocate memory for a response.");
|
139
|
+
return;
|
140
|
+
}
|
113
141
|
}
|
114
142
|
agoo_res_message_push(res, text);
|
143
|
+
|
144
|
+
return;
|
145
|
+
|
146
|
+
FAILED:
|
147
|
+
err_resp(res, &err, 500);
|
148
|
+
if (NULL != result) {
|
149
|
+
gql_value_destroy(result);
|
150
|
+
}
|
151
|
+
return;
|
152
|
+
}
|
153
|
+
|
154
|
+
agooText
|
155
|
+
gql_add_header(agooErr err, agooText headers, const char *key, const char *value) {
|
156
|
+
headers = agoo_text_append(headers, key, -1);
|
157
|
+
headers = agoo_text_append(headers, ": ", 2);
|
158
|
+
headers = agoo_text_append(headers, value, -1);
|
159
|
+
headers = agoo_text_append(headers, "\r\n", 2);
|
160
|
+
|
161
|
+
if (NULL == headers) {
|
162
|
+
AGOO_ERR_MEM(err, "headers");
|
163
|
+
}
|
164
|
+
return headers;
|
115
165
|
}
|
116
166
|
|
117
167
|
gqlValue
|
@@ -416,6 +466,7 @@ gql_eval_get_hook(agooReq req) {
|
|
416
466
|
return;
|
417
467
|
}
|
418
468
|
set_doc_op(doc, op_name, oplen);
|
469
|
+
doc->req = req;
|
419
470
|
|
420
471
|
if (NULL == gql_doc_eval_func) {
|
421
472
|
result = gql_doc_eval(&err, doc);
|
@@ -488,8 +539,6 @@ eval_post(agooErr err, agooReq req) {
|
|
488
539
|
gqlValue result = NULL;
|
489
540
|
gqlValue j = NULL;
|
490
541
|
|
491
|
-
// TBD handle query parameter and concatenate with JSON body variables if present
|
492
|
-
|
493
542
|
op_name = agoo_req_query_value(req, operation_name_str, sizeof(operation_name_str) - 1, &oplen);
|
494
543
|
var_json = agoo_req_query_value(req, variables_str, sizeof(variables_str) - 1, &vlen);
|
495
544
|
|
@@ -532,19 +581,24 @@ eval_post(agooErr err, agooReq req) {
|
|
532
581
|
} else if (0 == strcmp("variables", m->key)) {
|
533
582
|
gqlLink link;
|
534
583
|
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
for (link = m->value->members; NULL != link; link = link->next) {
|
540
|
-
gqlVar v = gql_op_var_create(err, link->key, link->value->type, link->value);
|
584
|
+
switch (m->value->type->scalar_kind) {
|
585
|
+
case GQL_SCALAR_OBJECT:
|
586
|
+
for (link = m->value->members; NULL != link; link = link->next) {
|
587
|
+
gqlVar v = gql_op_var_create(err, link->key, link->value->type, link->value);
|
541
588
|
|
542
|
-
|
543
|
-
|
544
|
-
|
589
|
+
link->value = NULL;
|
590
|
+
if (NULL == v) {
|
591
|
+
goto DONE;
|
592
|
+
}
|
593
|
+
v->next = vars;
|
594
|
+
vars = v;
|
545
595
|
}
|
546
|
-
|
547
|
-
|
596
|
+
break;
|
597
|
+
case GQL_SCALAR_NULL:
|
598
|
+
break;
|
599
|
+
default:
|
600
|
+
agoo_err_set(err, AGOO_ERR_EVAL, "expected variables to be an object or null.");
|
601
|
+
goto DONE;
|
548
602
|
}
|
549
603
|
}
|
550
604
|
}
|
@@ -559,6 +613,7 @@ eval_post(agooErr err, agooReq req) {
|
|
559
613
|
return NULL;
|
560
614
|
}
|
561
615
|
set_doc_op(doc, op_name, oplen);
|
616
|
+
doc->req = req;
|
562
617
|
|
563
618
|
if (NULL == gql_doc_eval_func) {
|
564
619
|
result = gql_doc_eval(err, doc);
|
@@ -569,7 +624,9 @@ eval_post(agooErr err, agooReq req) {
|
|
569
624
|
result = NULL;
|
570
625
|
}
|
571
626
|
DONE:
|
572
|
-
|
627
|
+
if (NULL != doc) {
|
628
|
+
gql_doc_destroy(doc);
|
629
|
+
}
|
573
630
|
gql_value_destroy(j);
|
574
631
|
|
575
632
|
return result;
|
@@ -595,6 +652,13 @@ gql_eval_post_hook(agooReq req) {
|
|
595
652
|
}
|
596
653
|
}
|
597
654
|
|
655
|
+
void
|
656
|
+
gql_eval_options_hook(agooReq req) {
|
657
|
+
struct _agooErr err = AGOO_ERR_INIT;
|
658
|
+
|
659
|
+
value_resp(req, gql_object_create(&err), 200, 0);
|
660
|
+
}
|
661
|
+
|
598
662
|
gqlValue
|
599
663
|
gql_get_arg_value(gqlKeyVal args, const char *key) {
|
600
664
|
gqlValue value = NULL;
|
data/ext/agoo/gqleval.h
CHANGED
@@ -15,6 +15,8 @@ typedef struct _gqlKeyVal {
|
|
15
15
|
struct _gqlValue *value;
|
16
16
|
} *gqlKeyVal;
|
17
17
|
|
18
|
+
struct _agooReq;
|
19
|
+
struct _agooText;
|
18
20
|
struct _gqlDoc;
|
19
21
|
struct _gqlField;
|
20
22
|
struct _gqlSel;
|
@@ -48,4 +50,8 @@ extern gqlRef (*gql_root_op)(const char *op);
|
|
48
50
|
|
49
51
|
extern struct _gqlValue* (*gql_doc_eval_func)(agooErr err, struct _gqlDoc *doc);
|
50
52
|
|
53
|
+
extern struct _agooText* (*gql_build_headers)(agooErr err, struct _agooReq *req, struct _agooText *headers);
|
54
|
+
extern struct _agooText* gql_add_header(agooErr err, struct _agooText *headers, const char *key, const char *value);
|
55
|
+
extern struct _agooText* gql_headers;
|
56
|
+
|
51
57
|
#endif // AGOO_GQLEVAL_H
|
data/ext/agoo/gqlintro.c
CHANGED
@@ -21,22 +21,30 @@ static int
|
|
21
21
|
create_schema_type(agooErr err) {
|
22
22
|
gqlType type;
|
23
23
|
gqlType type_type;
|
24
|
-
gqlType
|
24
|
+
gqlType type_nn;
|
25
|
+
gqlType type_nn_list;
|
26
|
+
gqlType type_nn_list_nn;
|
25
27
|
gqlType dir_type;
|
26
|
-
gqlType
|
28
|
+
gqlType dir_nn;
|
29
|
+
gqlType dir_nn_list;
|
30
|
+
gqlType dir_nn_list_nn;
|
27
31
|
|
28
32
|
if (NULL == (type = gql_type_create(err, "__Schema", NULL, 0, NULL)) ||
|
29
33
|
|
30
34
|
NULL == (type_type = gql_assure_type(err, "__Type")) ||
|
31
|
-
NULL == (
|
35
|
+
NULL == (type_nn = gql_assure_nonnull(err, type_type)) ||
|
36
|
+
NULL == (type_nn_list = gql_assure_list(err, type_nn)) ||
|
37
|
+
NULL == (type_nn_list_nn = gql_assure_nonnull(err, type_nn_list)) ||
|
32
38
|
NULL == (dir_type = gql_assure_type(err, "__Directive")) ||
|
33
|
-
NULL == (
|
39
|
+
NULL == (dir_nn = gql_assure_nonnull(err, dir_type)) ||
|
40
|
+
NULL == (dir_nn_list = gql_assure_list(err, dir_nn)) ||
|
41
|
+
NULL == (dir_nn_list_nn = gql_assure_nonnull(err, dir_nn_list)) ||
|
34
42
|
|
35
|
-
NULL == gql_type_field(err, type, "types",
|
36
|
-
NULL == gql_type_field(err, type, "queryType",
|
37
|
-
NULL == gql_type_field(err, type, "mutationType", type_type, NULL, NULL, 0
|
38
|
-
NULL == gql_type_field(err, type, "subscriptionType", type_type, NULL, NULL, 0
|
39
|
-
NULL == gql_type_field(err, type, "directives",
|
43
|
+
NULL == gql_type_field(err, type, "types", type_nn_list_nn, NULL, NULL, 0) ||
|
44
|
+
NULL == gql_type_field(err, type, "queryType", type_nn, NULL, NULL, 0) ||
|
45
|
+
NULL == gql_type_field(err, type, "mutationType", type_type, NULL, NULL, 0) ||
|
46
|
+
NULL == gql_type_field(err, type, "subscriptionType", type_type, NULL, NULL, 0) ||
|
47
|
+
NULL == gql_type_field(err, type, "directives", dir_nn_list_nn, NULL, NULL, 0)) {
|
40
48
|
|
41
49
|
return err->code;
|
42
50
|
}
|
@@ -63,34 +71,44 @@ create_type_type(agooErr err) {
|
|
63
71
|
gqlField enum_values = NULL;
|
64
72
|
gqlValue dv;
|
65
73
|
gqlType kind_type;
|
66
|
-
gqlType
|
74
|
+
gqlType kind_nn;
|
75
|
+
gqlType type_nn;
|
76
|
+
gqlType type_nn_list;
|
67
77
|
gqlType field_type;
|
78
|
+
gqlType field_nn;
|
68
79
|
gqlType field_list;
|
69
80
|
gqlType enum_type;
|
70
|
-
gqlType
|
81
|
+
gqlType enum_nn;
|
82
|
+
gqlType enum_nn_list;
|
71
83
|
gqlType input_type;
|
72
|
-
gqlType
|
84
|
+
gqlType input_nn;
|
85
|
+
gqlType input_nn_list;
|
73
86
|
|
74
87
|
if (NULL == (type = gql_type_create(err, "__Type", NULL, 0, NULL)) ||
|
75
88
|
|
76
|
-
NULL == (
|
89
|
+
NULL == (type_nn = gql_assure_nonnull(err, type)) ||
|
90
|
+
NULL == (type_nn_list = gql_assure_list(err, type_nn)) ||
|
77
91
|
NULL == (field_type = gql_assure_type(err, "__Field")) ||
|
78
|
-
NULL == (
|
92
|
+
NULL == (field_nn = gql_assure_nonnull(err, field_type)) ||
|
93
|
+
NULL == (field_list = gql_assure_list(err, field_nn)) ||
|
79
94
|
NULL == (kind_type = gql_assure_type(err, "__TypeKind")) ||
|
95
|
+
NULL == (kind_nn = gql_assure_nonnull(err, kind_type)) ||
|
80
96
|
NULL == (enum_type = gql_assure_type(err, "__EnumValue")) ||
|
81
|
-
NULL == (
|
97
|
+
NULL == (enum_nn = gql_assure_nonnull(err, enum_type)) ||
|
98
|
+
NULL == (enum_nn_list = gql_assure_list(err, enum_nn)) ||
|
82
99
|
NULL == (input_type = gql_assure_type(err, "__InputValue")) ||
|
83
|
-
NULL == (
|
84
|
-
|
85
|
-
|
86
|
-
NULL == gql_type_field(err, type, "
|
87
|
-
NULL == gql_type_field(err, type, "
|
88
|
-
NULL ==
|
89
|
-
NULL == gql_type_field(err, type, "
|
90
|
-
NULL == gql_type_field(err, type, "
|
91
|
-
NULL ==
|
92
|
-
NULL == gql_type_field(err, type, "
|
93
|
-
NULL == gql_type_field(err, type, "
|
100
|
+
NULL == (input_nn = gql_assure_nonnull(err, input_type)) ||
|
101
|
+
NULL == (input_nn_list = gql_assure_list(err, input_nn)) ||
|
102
|
+
|
103
|
+
NULL == gql_type_field(err, type, "kind", kind_nn, NULL, NULL, 0) ||
|
104
|
+
NULL == gql_type_field(err, type, "name", &gql_string_type, NULL, NULL, 0) ||
|
105
|
+
NULL == gql_type_field(err, type, "description", &gql_string_type, NULL, NULL, 0) ||
|
106
|
+
NULL == (fields = gql_type_field(err, type, "fields", field_list, NULL, NULL, 0)) ||
|
107
|
+
NULL == gql_type_field(err, type, "interfaces", type_nn_list, NULL, NULL, 0) ||
|
108
|
+
NULL == gql_type_field(err, type, "possibleTypes", type_nn_list, NULL, NULL, 0) ||
|
109
|
+
NULL == (enum_values = gql_type_field(err, type, "enumValues", enum_nn_list, NULL, NULL, 0)) ||
|
110
|
+
NULL == gql_type_field(err, type, "inputFields", input_nn_list, NULL, NULL, 0) ||
|
111
|
+
NULL == gql_type_field(err, type, "ofType", type, NULL, NULL, 0)) {
|
94
112
|
|
95
113
|
return err->code;
|
96
114
|
}
|
@@ -98,9 +116,9 @@ create_type_type(agooErr err) {
|
|
98
116
|
|
99
117
|
if (NULL == (dv = gql_bool_create(err, false)) ||
|
100
118
|
|
101
|
-
NULL == gql_field_arg(err, fields, "includeDeprecated", &gql_bool_type, NULL, 0, dv
|
119
|
+
NULL == gql_field_arg(err, fields, "includeDeprecated", &gql_bool_type, NULL, 0, dv) ||
|
102
120
|
NULL == (dv = gql_bool_create(err, false)) ||
|
103
|
-
NULL == gql_field_arg(err, enum_values, "includeDeprecated", &gql_bool_type, NULL, 0, dv
|
121
|
+
NULL == gql_field_arg(err, enum_values, "includeDeprecated", &gql_bool_type, NULL, 0, dv)) {
|
104
122
|
|
105
123
|
return err->code;
|
106
124
|
}
|
@@ -148,21 +166,31 @@ static int
|
|
148
166
|
create_field_type(agooErr err) {
|
149
167
|
gqlType type;
|
150
168
|
gqlType type_type;
|
169
|
+
gqlType type_nn;
|
151
170
|
gqlType input_type;
|
152
|
-
gqlType
|
171
|
+
gqlType input_nn;
|
172
|
+
gqlType input_nn_list;
|
173
|
+
gqlType input_nn_list_nn;
|
174
|
+
gqlType string_nn;
|
175
|
+
gqlType boolean_nn;
|
153
176
|
|
154
177
|
if (NULL == (type = gql_type_create(err, "__Field", NULL, 0, NULL)) ||
|
155
178
|
|
179
|
+
NULL == (string_nn = gql_assure_nonnull(err, &gql_string_type)) ||
|
180
|
+
NULL == (boolean_nn = gql_assure_nonnull(err, &gql_bool_type)) ||
|
156
181
|
NULL == (type_type = gql_assure_type(err, "__Type")) ||
|
182
|
+
NULL == (type_nn = gql_assure_nonnull(err, type_type)) ||
|
157
183
|
NULL == (input_type = gql_assure_type(err, "__InputValue")) ||
|
158
|
-
NULL == (
|
184
|
+
NULL == (input_nn = gql_assure_nonnull(err, input_type)) ||
|
185
|
+
NULL == (input_nn_list = gql_assure_list(err, input_nn)) ||
|
186
|
+
NULL == (input_nn_list_nn = gql_assure_nonnull(err, input_nn_list)) ||
|
159
187
|
|
160
|
-
NULL == gql_type_field(err, type, "name",
|
161
|
-
NULL == gql_type_field(err, type, "description", &gql_string_type, NULL, NULL, 0
|
162
|
-
NULL == gql_type_field(err, type, "args",
|
163
|
-
NULL == gql_type_field(err, type, "type",
|
164
|
-
NULL == gql_type_field(err, type, "isDeprecated",
|
165
|
-
NULL == gql_type_field(err, type, "deprecationReason", &gql_string_type, NULL, NULL, 0
|
188
|
+
NULL == gql_type_field(err, type, "name", string_nn, NULL, NULL, 0) ||
|
189
|
+
NULL == gql_type_field(err, type, "description", &gql_string_type, NULL, NULL, 0) ||
|
190
|
+
NULL == gql_type_field(err, type, "args", input_nn_list_nn, NULL, NULL, 0) ||
|
191
|
+
NULL == gql_type_field(err, type, "type", type_nn, NULL, NULL, 0) ||
|
192
|
+
NULL == gql_type_field(err, type, "isDeprecated", boolean_nn, NULL, NULL, 0) ||
|
193
|
+
NULL == gql_type_field(err, type, "deprecationReason", &gql_string_type, NULL, NULL, 0)) {
|
166
194
|
|
167
195
|
return err->code;
|
168
196
|
}
|
@@ -181,15 +209,19 @@ static int
|
|
181
209
|
create_input_type(agooErr err) {
|
182
210
|
gqlType type;
|
183
211
|
gqlType type_type;
|
212
|
+
gqlType type_nn;
|
213
|
+
gqlType string_nn;
|
184
214
|
|
185
215
|
if (NULL == (type = gql_type_create(err, "__InputValue", NULL, 0, NULL)) ||
|
186
216
|
|
217
|
+
NULL == (string_nn = gql_assure_nonnull(err, &gql_string_type)) ||
|
187
218
|
NULL == (type_type = gql_assure_type(err, "__Type")) ||
|
219
|
+
NULL == (type_nn = gql_assure_nonnull(err, type_type)) ||
|
188
220
|
|
189
|
-
NULL == gql_type_field(err, type, "name",
|
190
|
-
NULL == gql_type_field(err, type, "description", &gql_string_type, NULL, NULL, 0
|
191
|
-
NULL == gql_type_field(err, type, "type",
|
192
|
-
NULL == gql_type_field(err, type, "defaultValue", &gql_string_type, NULL, NULL, 0
|
221
|
+
NULL == gql_type_field(err, type, "name", string_nn, NULL, NULL, 0) ||
|
222
|
+
NULL == gql_type_field(err, type, "description", &gql_string_type, NULL, NULL, 0) ||
|
223
|
+
NULL == gql_type_field(err, type, "type", type_nn, NULL, NULL, 0) ||
|
224
|
+
NULL == gql_type_field(err, type, "defaultValue", &gql_string_type, NULL, NULL, 0)) {
|
193
225
|
|
194
226
|
return err->code;
|
195
227
|
}
|
@@ -207,12 +239,18 @@ create_input_type(agooErr err) {
|
|
207
239
|
static int
|
208
240
|
create_enum_type(agooErr err) {
|
209
241
|
gqlType type;
|
242
|
+
gqlType string_nn;
|
243
|
+
gqlType boolean_nn;
|
210
244
|
|
211
245
|
if (NULL == (type = gql_type_create(err, "__EnumValue", NULL, 0, NULL)) ||
|
212
|
-
|
213
|
-
NULL ==
|
214
|
-
NULL ==
|
215
|
-
|
246
|
+
|
247
|
+
NULL == (string_nn = gql_assure_nonnull(err, &gql_string_type)) ||
|
248
|
+
NULL == (boolean_nn = gql_assure_nonnull(err, &gql_bool_type)) ||
|
249
|
+
|
250
|
+
NULL == gql_type_field(err, type, "name", string_nn, NULL, NULL, 0) ||
|
251
|
+
NULL == gql_type_field(err, type, "description", &gql_string_type, NULL, NULL, 0) ||
|
252
|
+
NULL == gql_type_field(err, type, "isDeprecated", boolean_nn, NULL, NULL, 0) ||
|
253
|
+
NULL == gql_type_field(err, type, "deprecationReason", &gql_string_type, NULL, NULL, 0)) {
|
216
254
|
|
217
255
|
return err->code;
|
218
256
|
}
|
@@ -231,21 +269,31 @@ static int
|
|
231
269
|
create_directive_type(agooErr err) {
|
232
270
|
gqlType type;
|
233
271
|
gqlType input_type;
|
234
|
-
gqlType
|
272
|
+
gqlType input_nn;
|
273
|
+
gqlType input_nn_list;
|
274
|
+
gqlType input_nn_list_nn;
|
235
275
|
gqlType loc_type;
|
236
|
-
gqlType
|
276
|
+
gqlType loc_nn;
|
277
|
+
gqlType loc_nn_list;
|
278
|
+
gqlType loc_nn_list_nn;
|
279
|
+
gqlType string_nn;
|
237
280
|
|
238
281
|
if (NULL == (type = gql_type_create(err, "__Directive", NULL, 0, NULL)) ||
|
239
282
|
|
283
|
+
NULL == (string_nn = gql_assure_nonnull(err, &gql_string_type)) ||
|
240
284
|
NULL == (input_type = gql_assure_type(err, "__InputValue")) ||
|
241
|
-
NULL == (
|
285
|
+
NULL == (input_nn = gql_assure_nonnull(err, input_type)) ||
|
286
|
+
NULL == (input_nn_list = gql_assure_list(err, input_nn)) ||
|
287
|
+
NULL == (input_nn_list_nn = gql_assure_nonnull(err, input_nn_list)) ||
|
242
288
|
NULL == (loc_type = gql_assure_type(err, "__DirectiveLocation")) ||
|
243
|
-
NULL == (
|
289
|
+
NULL == (loc_nn = gql_assure_nonnull(err, loc_type)) ||
|
290
|
+
NULL == (loc_nn_list = gql_assure_list(err, loc_nn)) ||
|
291
|
+
NULL == (loc_nn_list_nn = gql_assure_nonnull(err, loc_nn_list)) ||
|
244
292
|
|
245
|
-
NULL == gql_type_field(err, type, "name",
|
246
|
-
NULL == gql_type_field(err, type, "description", &gql_string_type, NULL, NULL, 0
|
247
|
-
NULL == gql_type_field(err, type, "locations",
|
248
|
-
NULL == gql_type_field(err, type, "args",
|
293
|
+
NULL == gql_type_field(err, type, "name", string_nn, NULL, NULL, 0) ||
|
294
|
+
NULL == gql_type_field(err, type, "description", &gql_string_type, NULL, NULL, 0) ||
|
295
|
+
NULL == gql_type_field(err, type, "locations", loc_nn_list_nn, NULL, NULL, 0) ||
|
296
|
+
NULL == gql_type_field(err, type, "args", input_nn_list_nn, NULL, NULL, 0)) {
|
249
297
|
|
250
298
|
return err->code;
|
251
299
|
}
|
@@ -294,15 +342,18 @@ create_directive_location_type(agooErr err) {
|
|
294
342
|
static int
|
295
343
|
create_dir_skip(agooErr err) {
|
296
344
|
gqlDir dir = gql_directive_create(err, "skip", NULL, 0);
|
345
|
+
gqlType boolean_nn;
|
297
346
|
|
298
347
|
if (NULL == dir) {
|
299
348
|
return err->code;
|
300
349
|
}
|
301
350
|
dir->core = true;
|
302
|
-
if (
|
351
|
+
if (NULL == (boolean_nn = gql_assure_nonnull(err, &gql_bool_type)) ||
|
352
|
+
|
353
|
+
AGOO_ERR_OK != gql_directive_on(err, dir, "FIELD", -1) ||
|
303
354
|
AGOO_ERR_OK != gql_directive_on(err, dir, "FRAGMENT_SPREAD", -1) ||
|
304
355
|
AGOO_ERR_OK != gql_directive_on(err, dir, "INLINE_FRAGMENT", -1) ||
|
305
|
-
NULL == gql_dir_arg(err, dir, "if",
|
356
|
+
NULL == gql_dir_arg(err, dir, "if", boolean_nn, NULL, -1, NULL)) {
|
306
357
|
|
307
358
|
return err->code;
|
308
359
|
}
|
@@ -312,15 +363,18 @@ create_dir_skip(agooErr err) {
|
|
312
363
|
static int
|
313
364
|
create_dir_include(agooErr err) {
|
314
365
|
gqlDir dir = gql_directive_create(err, "include", NULL, 0);
|
366
|
+
gqlType boolean_nn;
|
315
367
|
|
316
368
|
if (NULL == dir) {
|
317
369
|
return err->code;
|
318
370
|
}
|
319
371
|
dir->core = true;
|
320
|
-
if (
|
372
|
+
if (NULL == (boolean_nn = gql_assure_nonnull(err, &gql_bool_type)) ||
|
373
|
+
|
374
|
+
AGOO_ERR_OK != gql_directive_on(err, dir, "FIELD", -1) ||
|
321
375
|
AGOO_ERR_OK != gql_directive_on(err, dir, "FRAGMENT_SPREAD", -1) ||
|
322
376
|
AGOO_ERR_OK != gql_directive_on(err, dir, "INLINE_FRAGMENT", -1) ||
|
323
|
-
NULL == gql_dir_arg(err, dir, "if",
|
377
|
+
NULL == gql_dir_arg(err, dir, "if", boolean_nn, NULL, 0, NULL)) {
|
324
378
|
|
325
379
|
return err->code;
|
326
380
|
}
|
@@ -339,7 +393,7 @@ create_dir_deprecated(agooErr err) {
|
|
339
393
|
if (AGOO_ERR_OK != gql_directive_on(err, dir, "FIELD_DEFINITION", -1) ||
|
340
394
|
AGOO_ERR_OK != gql_directive_on(err, dir, "ENUM_VALUE", -1) ||
|
341
395
|
NULL == (dv = gql_string_create(err, "No longer supported", -1)) ||
|
342
|
-
NULL == gql_dir_arg(err, dir, "reason", &gql_string_type, NULL, -1, dv
|
396
|
+
NULL == gql_dir_arg(err, dir, "reason", &gql_string_type, NULL, -1, dv)) {
|
343
397
|
|
344
398
|
return err->code;
|
345
399
|
}
|
@@ -356,9 +410,9 @@ gql_intro_init(agooErr err) {
|
|
356
410
|
AGOO_ERR_OK != create_directive_location_type(err) ||
|
357
411
|
AGOO_ERR_OK != create_directive_type(err) ||
|
358
412
|
AGOO_ERR_OK != create_schema_type(err) ||
|
359
|
-
AGOO_ERR_OK !=
|
413
|
+
AGOO_ERR_OK != create_dir_skip(err) ||
|
360
414
|
AGOO_ERR_OK != create_dir_include(err) ||
|
361
|
-
AGOO_ERR_OK !=
|
415
|
+
AGOO_ERR_OK != create_dir_deprecated(err)) {
|
362
416
|
|
363
417
|
return err->code;
|
364
418
|
}
|
@@ -843,6 +897,7 @@ type_kind(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gqlV
|
|
843
897
|
case GQL_ENUM: kind = "ENUM"; break;
|
844
898
|
case GQL_SCALAR: kind = "SCALAR"; break;
|
845
899
|
case GQL_LIST: kind = "LIST"; break;
|
900
|
+
case GQL_NON_NULL: kind = "NON_NULL"; break;
|
846
901
|
default:
|
847
902
|
return agoo_err_set(err, AGOO_ERR_ARG, "__Type kind (%d) field not valid. %s:%d", ((gqlType)obj->ptr)->kind, __FILE__, __LINE__);
|
848
903
|
}
|
@@ -888,7 +943,7 @@ type_fields(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gq
|
|
888
943
|
gqlType type = (gqlType)obj->ptr;
|
889
944
|
const char *key = sel->name;
|
890
945
|
gqlField f;
|
891
|
-
gqlValue list
|
946
|
+
gqlValue list;
|
892
947
|
gqlValue co;
|
893
948
|
struct _gqlField cf;
|
894
949
|
struct _gqlCobj child = { .clas = &field_class };
|
@@ -896,23 +951,23 @@ type_fields(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel, gq
|
|
896
951
|
gqlValue a = gql_extract_arg(err, field, sel, "includeDeprecated");
|
897
952
|
bool inc_dep = false;
|
898
953
|
|
954
|
+
if (NULL != sel->alias) {
|
955
|
+
key = sel->alias;
|
956
|
+
}
|
899
957
|
if (GQL_OBJECT != type->kind && GQL_SCHEMA != type->kind && GQL_INTERFACE != type->kind) {
|
900
|
-
if (NULL == (
|
901
|
-
AGOO_ERR_OK !=
|
958
|
+
if (NULL == (list = gql_null_create(err)) ||
|
959
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, list)) {
|
902
960
|
return err->code;
|
903
961
|
}
|
904
962
|
return AGOO_ERR_OK;
|
905
963
|
}
|
906
|
-
if (NULL
|
907
|
-
inc_dep = true;
|
908
|
-
}
|
909
|
-
if (NULL != sel->alias) {
|
910
|
-
key = sel->alias;
|
911
|
-
}
|
912
|
-
if (NULL == list ||
|
964
|
+
if (NULL == (list = gql_list_create(err, NULL)) ||
|
913
965
|
AGOO_ERR_OK != gql_object_set(err, result, key, list)) {
|
914
966
|
return err->code;
|
915
967
|
}
|
968
|
+
if (NULL != a && GQL_SCALAR_BOOL == a->type->scalar_kind && a->b) {
|
969
|
+
inc_dep = true;
|
970
|
+
}
|
916
971
|
memset(&cf, 0, sizeof(cf));
|
917
972
|
cf.type = sel->type->base;
|
918
973
|
for (f = type->fields; NULL != f; f = f->next) {
|
@@ -938,23 +993,23 @@ type_interfaces(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel
|
|
938
993
|
gqlType type = (gqlType)obj->ptr;
|
939
994
|
const char *key = sel->name;
|
940
995
|
gqlTypeLink tl;
|
941
|
-
gqlValue list
|
996
|
+
gqlValue list;
|
942
997
|
gqlValue co;
|
943
998
|
struct _gqlField cf;
|
944
999
|
struct _gqlCobj child = { .clas = &type_class };
|
945
1000
|
int d2 = depth + 1;
|
946
1001
|
|
1002
|
+
if (NULL != sel->alias) {
|
1003
|
+
key = sel->alias;
|
1004
|
+
}
|
947
1005
|
if (GQL_OBJECT != type->kind) {
|
948
|
-
if (NULL == (
|
949
|
-
AGOO_ERR_OK !=
|
1006
|
+
if (NULL == (list = gql_null_create(err)) ||
|
1007
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, list)) {
|
950
1008
|
return err->code;
|
951
1009
|
}
|
952
1010
|
return AGOO_ERR_OK;
|
953
1011
|
}
|
954
|
-
if (NULL
|
955
|
-
key = sel->alias;
|
956
|
-
}
|
957
|
-
if (NULL == list ||
|
1012
|
+
if (NULL == (list = gql_list_create(err, NULL)) ||
|
958
1013
|
AGOO_ERR_OK != gql_object_set(err, result, key, list)) {
|
959
1014
|
return err->code;
|
960
1015
|
}
|
@@ -970,6 +1025,18 @@ type_interfaces(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel sel
|
|
970
1025
|
return err->code;
|
971
1026
|
}
|
972
1027
|
}
|
1028
|
+
// The spec indicates the type is [__Type!] and makes a comment that is
|
1029
|
+
// should be non-null for Objects only. GraphiQL expected an empty list
|
1030
|
+
// which contradicts the spec.
|
1031
|
+
/*
|
1032
|
+
if (NULL == list->members) {
|
1033
|
+
gql_value_destroy(list);
|
1034
|
+
if (NULL == (list = gql_null_create(err)) ||
|
1035
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, list)) {
|
1036
|
+
return err->code;
|
1037
|
+
}
|
1038
|
+
}
|
1039
|
+
*/
|
973
1040
|
return AGOO_ERR_OK;
|
974
1041
|
}
|
975
1042
|
|
@@ -1005,7 +1072,7 @@ possible_cb(gqlType type, void *ctx) {
|
|
1005
1072
|
if (AGOO_ERR_OK != pc->err->code) {
|
1006
1073
|
return;
|
1007
1074
|
}
|
1008
|
-
if (
|
1075
|
+
if (GQL_OBJECT == type->kind && has_interface(type, pc->interface)) {
|
1009
1076
|
gqlValue co;
|
1010
1077
|
|
1011
1078
|
if (NULL == (co = gql_object_create(pc->err)) ||
|
@@ -1022,8 +1089,8 @@ type_possible_types(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel
|
|
1022
1089
|
gqlType type = (gqlType)obj->ptr;
|
1023
1090
|
const char *key = sel->name;
|
1024
1091
|
gqlTypeLink tl;
|
1025
|
-
gqlValue list = gql_list_create(err, NULL);
|
1026
1092
|
gqlValue co;
|
1093
|
+
gqlValue list;
|
1027
1094
|
struct _gqlField cf;
|
1028
1095
|
struct _gqlCobj child = { .clas = &type_class };
|
1029
1096
|
int d2 = depth + 1;
|
@@ -1031,15 +1098,12 @@ type_possible_types(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel
|
|
1031
1098
|
if (NULL != sel->alias) {
|
1032
1099
|
key = sel->alias;
|
1033
1100
|
}
|
1034
|
-
if (NULL == list ||
|
1035
|
-
AGOO_ERR_OK != gql_object_set(err, result, key, list)) {
|
1036
|
-
return err->code;
|
1037
|
-
}
|
1038
1101
|
memset(&cf, 0, sizeof(cf));
|
1039
1102
|
cf.type = sel->type->base;
|
1040
1103
|
|
1041
1104
|
switch (type->kind) {
|
1042
1105
|
case GQL_INTERFACE: {
|
1106
|
+
list = gql_list_create(err, NULL);
|
1043
1107
|
struct _posCtx pc = {
|
1044
1108
|
.err = err,
|
1045
1109
|
.doc = doc,
|
@@ -1050,11 +1114,18 @@ type_possible_types(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel
|
|
1050
1114
|
.child = &child,
|
1051
1115
|
.cf = &cf,
|
1052
1116
|
};
|
1053
|
-
|
1117
|
+
if (NULL == list ||
|
1118
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, list)) {
|
1119
|
+
return err->code;
|
1120
|
+
}
|
1054
1121
|
gql_type_iterate(possible_cb, &pc);
|
1055
1122
|
break;
|
1056
1123
|
}
|
1057
1124
|
case GQL_UNION:
|
1125
|
+
if (NULL == (list = gql_list_create(err, NULL)) ||
|
1126
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, list)) {
|
1127
|
+
return err->code;
|
1128
|
+
}
|
1058
1129
|
for (tl = type->types; NULL != tl; tl = tl->next) {
|
1059
1130
|
if (NULL == (co = gql_object_create(err)) ||
|
1060
1131
|
AGOO_ERR_OK != gql_list_append(err, list, co)) {
|
@@ -1067,10 +1138,11 @@ type_possible_types(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel
|
|
1067
1138
|
}
|
1068
1139
|
break;
|
1069
1140
|
default:
|
1070
|
-
if (NULL == (
|
1071
|
-
AGOO_ERR_OK !=
|
1141
|
+
if (NULL == (list = gql_null_create(err)) ||
|
1142
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, list)) {
|
1072
1143
|
return err->code;
|
1073
1144
|
}
|
1145
|
+
break;
|
1074
1146
|
}
|
1075
1147
|
return AGOO_ERR_OK;
|
1076
1148
|
}
|
@@ -1082,7 +1154,7 @@ type_enum_values(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel se
|
|
1082
1154
|
gqlType type = (gqlType)obj->ptr;
|
1083
1155
|
const char *key = sel->name;
|
1084
1156
|
gqlEnumVal c;
|
1085
|
-
gqlValue list
|
1157
|
+
gqlValue list;
|
1086
1158
|
gqlValue co;
|
1087
1159
|
struct _gqlField cf;
|
1088
1160
|
struct _gqlCobj child = { .clas = &enum_value_class };
|
@@ -1090,23 +1162,23 @@ type_enum_values(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel se
|
|
1090
1162
|
gqlValue a = gql_extract_arg(err, field, sel, "includeDeprecated");
|
1091
1163
|
bool inc_dep = false;
|
1092
1164
|
|
1165
|
+
if (NULL != sel->alias) {
|
1166
|
+
key = sel->alias;
|
1167
|
+
}
|
1093
1168
|
if (GQL_ENUM != type->kind) {
|
1094
|
-
if (NULL == (
|
1095
|
-
AGOO_ERR_OK !=
|
1169
|
+
if (NULL == (list = gql_null_create(err)) ||
|
1170
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, list)) {
|
1096
1171
|
return err->code;
|
1097
1172
|
}
|
1098
1173
|
return AGOO_ERR_OK;
|
1099
1174
|
}
|
1100
|
-
if (NULL
|
1101
|
-
inc_dep = true;
|
1102
|
-
}
|
1103
|
-
if (NULL != sel->alias) {
|
1104
|
-
key = sel->alias;
|
1105
|
-
}
|
1106
|
-
if (NULL == list ||
|
1175
|
+
if (NULL == (list = gql_list_create(err, NULL)) ||
|
1107
1176
|
AGOO_ERR_OK != gql_object_set(err, result, key, list)) {
|
1108
1177
|
return err->code;
|
1109
1178
|
}
|
1179
|
+
if (NULL != a && GQL_SCALAR_BOOL == a->type->scalar_kind && a->b) {
|
1180
|
+
inc_dep = true;
|
1181
|
+
}
|
1110
1182
|
memset(&cf, 0, sizeof(cf));
|
1111
1183
|
cf.type = sel->type->base;
|
1112
1184
|
for (c = type->choices; NULL != c; c = c->next) {
|
@@ -1132,23 +1204,23 @@ type_input_fields(agooErr err, gqlDoc doc, gqlCobj obj, gqlField field, gqlSel s
|
|
1132
1204
|
gqlType type = (gqlType)obj->ptr;
|
1133
1205
|
const char *key = sel->name;
|
1134
1206
|
gqlArg a;
|
1135
|
-
gqlValue list
|
1207
|
+
gqlValue list;
|
1136
1208
|
gqlValue co;
|
1137
1209
|
struct _gqlField cf;
|
1138
1210
|
struct _gqlCobj child = { .clas = &input_value_class };
|
1139
1211
|
int d2 = depth + 1;
|
1140
1212
|
|
1213
|
+
if (NULL != sel->alias) {
|
1214
|
+
key = sel->alias;
|
1215
|
+
}
|
1141
1216
|
if (GQL_INPUT != type->kind) {
|
1142
|
-
if (NULL == (
|
1143
|
-
AGOO_ERR_OK !=
|
1217
|
+
if (NULL == (list = gql_null_create(err)) ||
|
1218
|
+
AGOO_ERR_OK != gql_object_set(err, result, key, list)) {
|
1144
1219
|
return err->code;
|
1145
1220
|
}
|
1146
1221
|
return AGOO_ERR_OK;
|
1147
1222
|
}
|
1148
|
-
if (NULL
|
1149
|
-
key = sel->alias;
|
1150
|
-
}
|
1151
|
-
if (NULL == list ||
|
1223
|
+
if (NULL == (list = gql_list_create(err, NULL)) ||
|
1152
1224
|
AGOO_ERR_OK != gql_object_set(err, result, key, list)) {
|
1153
1225
|
return err->code;
|
1154
1226
|
}
|
@@ -1229,7 +1301,7 @@ schema_types_cb(gqlType type, void *ctx) {
|
|
1229
1301
|
struct _gqlCobj child = { .clas = &type_class, .ptr = (void*)type };
|
1230
1302
|
struct _gqlField cf;
|
1231
1303
|
|
1232
|
-
if (AGOO_ERR_OK != scc->err->code || GQL_LIST == type->kind) {
|
1304
|
+
if (AGOO_ERR_OK != scc->err->code || GQL_LIST == type->kind || GQL_NON_NULL == type->kind || GQL_SCHEMA == type->kind) {
|
1233
1305
|
return;
|
1234
1306
|
}
|
1235
1307
|
memset(&cf, 0, sizeof(cf));
|