@omnigraph/json-schema 1.0.0-alpha-3fc47d119.0 → 1.0.0-alpha-20230420181317-a95037648
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/README.md +5 -4
- package/cjs/addExecutionLogicToComposer.js +208 -0
- package/cjs/addRootFieldResolver.js +395 -0
- package/cjs/bundle.js +65 -0
- package/cjs/directives.js +580 -0
- package/cjs/getComposerFromJSONSchema.js +1297 -0
- package/cjs/getDereferencedJSONSchemaFromOperations.js +33 -0
- package/cjs/getGraphQLSchemaFromDereferencedJSONSchema.js +39 -0
- package/cjs/getJSONSchemaStringFormatScalarMap.js +61 -0
- package/cjs/getReferencedJSONSchemaFromOperations.js +260 -0
- package/cjs/getTypeResolverFromOutputTCs.js +69 -0
- package/cjs/getUnionTypeComposers.js +85 -0
- package/cjs/getValidTypeName.js +20 -0
- package/cjs/index.js +14 -0
- package/cjs/loadGraphQLSchemaFromJSONSchemas.js +59 -0
- package/cjs/package.json +1 -0
- package/cjs/resolveDataByUnionInputType.js +40 -0
- package/cjs/scalars.js +30 -0
- package/cjs/types.js +0 -0
- package/cjs/utils.js +65 -0
- package/esm/addExecutionLogicToComposer.js +204 -0
- package/esm/addRootFieldResolver.js +390 -0
- package/esm/bundle.js +60 -0
- package/esm/directives.js +565 -0
- package/esm/getComposerFromJSONSchema.js +1293 -0
- package/esm/getDereferencedJSONSchemaFromOperations.js +29 -0
- package/esm/getGraphQLSchemaFromDereferencedJSONSchema.js +35 -0
- package/esm/getJSONSchemaStringFormatScalarMap.js +56 -0
- package/esm/getReferencedJSONSchemaFromOperations.js +255 -0
- package/esm/getTypeResolverFromOutputTCs.js +65 -0
- package/esm/getUnionTypeComposers.js +80 -0
- package/esm/getValidTypeName.js +16 -0
- package/esm/index.js +9 -0
- package/esm/loadGraphQLSchemaFromJSONSchemas.js +54 -0
- package/esm/resolveDataByUnionInputType.js +36 -0
- package/esm/scalars.js +27 -0
- package/esm/types.js +0 -0
- package/esm/utils.js +57 -0
- package/package.json +34 -27
- package/typings/addExecutionLogicToComposer.d.cts +14 -0
- package/typings/addExecutionLogicToComposer.d.ts +14 -0
- package/typings/addRootFieldResolver.d.cts +26 -0
- package/typings/addRootFieldResolver.d.ts +26 -0
- package/typings/bundle.d.cts +34 -0
- package/typings/bundle.d.ts +34 -0
- package/typings/directives.d.cts +54 -0
- package/typings/directives.d.ts +54 -0
- package/typings/getComposerFromJSONSchema.d.cts +13 -0
- package/{getComposerFromJSONSchema.d.ts → typings/getComposerFromJSONSchema.d.ts} +7 -4
- package/typings/getDereferencedJSONSchemaFromOperations.d.cts +14 -0
- package/{getDereferencedJSONSchemaFromOperations.d.ts → typings/getDereferencedJSONSchemaFromOperations.d.ts} +5 -3
- package/typings/getGraphQLSchemaFromDereferencedJSONSchema.d.cts +5 -0
- package/typings/getGraphQLSchemaFromDereferencedJSONSchema.d.ts +5 -0
- package/typings/getJSONSchemaStringFormatScalarMap.d.cts +2 -0
- package/typings/getJSONSchemaStringFormatScalarMap.d.ts +2 -0
- package/typings/getReferencedJSONSchemaFromOperations.d.cts +16 -0
- package/{getReferencedJSONSchemaFromOperations.d.ts → typings/getReferencedJSONSchemaFromOperations.d.ts} +6 -4
- package/typings/getTypeResolverFromOutputTCs.d.cts +7 -0
- package/typings/getTypeResolverFromOutputTCs.d.ts +7 -0
- package/typings/getUnionTypeComposers.d.cts +24 -0
- package/typings/getUnionTypeComposers.d.ts +24 -0
- package/{getStringScalarWithMinMaxLength.d.ts → typings/getValidTypeName.d.cts} +4 -3
- package/typings/index.d.cts +9 -0
- package/typings/index.d.ts +9 -0
- package/typings/loadGraphQLSchemaFromJSONSchemas.d.cts +3 -0
- package/typings/loadGraphQLSchemaFromJSONSchemas.d.ts +3 -0
- package/typings/resolveDataByUnionInputType.d.cts +2 -0
- package/typings/resolveDataByUnionInputType.d.ts +2 -0
- package/typings/scalars.d.cts +4 -0
- package/typings/scalars.d.ts +4 -0
- package/typings/types.d.cts +76 -0
- package/typings/types.d.ts +76 -0
- package/typings/utils.d.cts +15 -0
- package/{utils.d.ts → typings/utils.d.ts} +1 -1
- package/addExecutionLogicToComposer.d.ts +0 -15
- package/bundle.d.ts +0 -39
- package/getGenericJSONScalar.d.ts +0 -8
- package/getGraphQLSchemaFromDereferencedJSONSchema.d.ts +0 -5
- package/getJSONSchemaStringFormatScalarMap.d.ts +0 -3
- package/getTypeResolverFromOutputTCs.d.ts +0 -4
- package/getUnionTypeComposers.d.ts +0 -21
- package/getValidateFnForSchemaPath.d.ts +0 -3
- package/index.d.ts +0 -9
- package/index.js +0 -1890
- package/index.mjs +0 -1877
- package/loadGraphQLSchemaFromJSONSchemas.d.ts +0 -2
- package/resolveDataByUnionInputType.d.ts +0 -3
- package/types.d.ts +0 -63
- package/{getValidTypeName.d.ts → typings/getValidTypeName.d.ts} +1 -1
package/README.md
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
## JSON Schema (@omnigraph/json-schema)
|
|
2
2
|
|
|
3
|
-
This package generates GraphQL Schema from JSON Schema and sample JSON request and responses. You
|
|
3
|
+
This package generates GraphQL Schema from JSON Schema and sample JSON request and responses. You
|
|
4
|
+
can define your root field endpoints like below in your GraphQL Config for example;
|
|
4
5
|
|
|
5
|
-
```yaml
|
|
6
|
+
```yaml filename=".graphqlrc.yml"
|
|
6
7
|
schema:
|
|
7
8
|
myOmnigraph:
|
|
8
9
|
loader: '@omnigraph/json-schema'
|
|
9
10
|
# The base URL of your following endpoints
|
|
10
|
-
|
|
11
|
+
endpoint: http://www.my-api.com
|
|
11
12
|
# The headers will be used while downloading JSON Schemas and Samples
|
|
12
13
|
schemaHeaders:
|
|
13
14
|
Content-Type: application/json
|
|
@@ -24,7 +25,7 @@ schema:
|
|
|
24
25
|
field: me
|
|
25
26
|
# Description
|
|
26
27
|
description: My Profile
|
|
27
|
-
# The relative URL to the defined `
|
|
28
|
+
# The relative URL to the defined `endpoint`
|
|
28
29
|
path: /user/{args.id} # args will generate an argument for the field and put it here automatically
|
|
29
30
|
# The HTTP method
|
|
30
31
|
method: GET
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.addExecutionDirectivesToComposer = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
const graphql_compose_1 = require("graphql-compose");
|
|
6
|
+
const cross_helpers_1 = require("@graphql-mesh/cross-helpers");
|
|
7
|
+
const directives_js_1 = require("./directives.js");
|
|
8
|
+
const utils_js_1 = require("./utils.js");
|
|
9
|
+
const responseMetadataType = new graphql_1.GraphQLObjectType({
|
|
10
|
+
name: 'ResponseMetadata',
|
|
11
|
+
fields: {
|
|
12
|
+
url: { type: graphql_1.GraphQLString },
|
|
13
|
+
method: { type: graphql_1.GraphQLString },
|
|
14
|
+
status: { type: graphql_1.GraphQLInt },
|
|
15
|
+
statusText: { type: graphql_1.GraphQLString },
|
|
16
|
+
headers: { type: graphql_compose_1.GraphQLJSON },
|
|
17
|
+
body: { type: graphql_compose_1.GraphQLJSON },
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
async function addExecutionDirectivesToComposer(name, { schemaComposer, logger, operations, operationHeaders, endpoint, queryParams, queryStringOptions, }) {
|
|
21
|
+
var _a, _b;
|
|
22
|
+
schemaComposer.addDirective(directives_js_1.GlobalOptionsDirective);
|
|
23
|
+
schemaComposer.Query.setDirectiveByName('globalOptions', JSON.parse(JSON.stringify({
|
|
24
|
+
sourceName: name,
|
|
25
|
+
endpoint,
|
|
26
|
+
operationHeaders,
|
|
27
|
+
queryStringOptions,
|
|
28
|
+
queryParams,
|
|
29
|
+
})));
|
|
30
|
+
logger.debug(`Attaching execution directives to the schema`);
|
|
31
|
+
for (const operationConfig of operations) {
|
|
32
|
+
const { httpMethod, rootTypeName, fieldName } = (0, utils_js_1.getOperationMetadata)(operationConfig);
|
|
33
|
+
const rootTypeComposer = schemaComposer[rootTypeName];
|
|
34
|
+
const field = rootTypeComposer.getField(fieldName);
|
|
35
|
+
if ((0, utils_js_1.isPubSubOperationConfig)(operationConfig)) {
|
|
36
|
+
field.description =
|
|
37
|
+
operationConfig.description || `PubSub Topic: ${operationConfig.pubsubTopic}`;
|
|
38
|
+
field.directives = field.directives || [];
|
|
39
|
+
schemaComposer.addDirective(directives_js_1.PubSubOperationDirective);
|
|
40
|
+
field.directives.push({
|
|
41
|
+
name: 'pubsubOperation',
|
|
42
|
+
args: {
|
|
43
|
+
pubsubTopic: operationConfig.pubsubTopic,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
else if (operationConfig.path) {
|
|
48
|
+
if (cross_helpers_1.process.env.DEBUG === '1' || cross_helpers_1.process.env.DEBUG === 'fieldDetails') {
|
|
49
|
+
field.description = `
|
|
50
|
+
>**Method**: \`${operationConfig.method}\`
|
|
51
|
+
>**Base URL**: \`${endpoint}\`
|
|
52
|
+
>**Path**: \`${operationConfig.path}\`
|
|
53
|
+
${operationConfig.description || ''}
|
|
54
|
+
`;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
field.description = operationConfig.description;
|
|
58
|
+
}
|
|
59
|
+
field.directives = field.directives || [];
|
|
60
|
+
schemaComposer.addDirective(directives_js_1.HTTPOperationDirective);
|
|
61
|
+
field.directives.push({
|
|
62
|
+
name: 'httpOperation',
|
|
63
|
+
args: JSON.parse(JSON.stringify({
|
|
64
|
+
path: operationConfig.path,
|
|
65
|
+
operationSpecificHeaders: operationConfig.headers,
|
|
66
|
+
httpMethod,
|
|
67
|
+
isBinary: 'binary' in operationConfig ? operationConfig.binary : undefined,
|
|
68
|
+
requestBaseBody: 'requestBaseBody' in operationConfig ? operationConfig.requestBaseBody : undefined,
|
|
69
|
+
queryParamArgMap: operationConfig.queryParamArgMap,
|
|
70
|
+
queryStringOptionsByParam: operationConfig.queryStringOptionsByParam,
|
|
71
|
+
})),
|
|
72
|
+
});
|
|
73
|
+
const handleLinkMap = (linkMap, typeTC) => {
|
|
74
|
+
for (const linkName in linkMap) {
|
|
75
|
+
typeTC.addFields({
|
|
76
|
+
[linkName]: () => {
|
|
77
|
+
const linkObj = linkMap[linkName];
|
|
78
|
+
field.directives = field.directives || [];
|
|
79
|
+
let linkResolverMapDirective = field.directives.find(d => d.name === 'linkResolver');
|
|
80
|
+
if (!linkResolverMapDirective) {
|
|
81
|
+
schemaComposer.addDirective(directives_js_1.LinkResolverDirective);
|
|
82
|
+
linkResolverMapDirective = {
|
|
83
|
+
name: 'linkResolver',
|
|
84
|
+
args: {
|
|
85
|
+
linkResolverMap: {},
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
field.directives.push(linkResolverMapDirective);
|
|
89
|
+
}
|
|
90
|
+
const linkResolverFieldMap = linkResolverMapDirective.args.linkResolverMap;
|
|
91
|
+
let targetField;
|
|
92
|
+
let fieldTypeName;
|
|
93
|
+
try {
|
|
94
|
+
targetField = schemaComposer.Query.getField(linkObj.fieldName);
|
|
95
|
+
fieldTypeName = 'Query';
|
|
96
|
+
}
|
|
97
|
+
catch (_a) {
|
|
98
|
+
try {
|
|
99
|
+
targetField = schemaComposer.Mutation.getField(linkObj.fieldName);
|
|
100
|
+
fieldTypeName = 'Mutation';
|
|
101
|
+
}
|
|
102
|
+
catch (_b) { }
|
|
103
|
+
}
|
|
104
|
+
if (!targetField) {
|
|
105
|
+
logger.debug(`Field ${linkObj.fieldName} not found in ${name} for link ${linkName}`);
|
|
106
|
+
}
|
|
107
|
+
linkResolverFieldMap[linkName] = {
|
|
108
|
+
linkObjArgs: linkObj.args,
|
|
109
|
+
targetTypeName: fieldTypeName,
|
|
110
|
+
targetFieldName: linkObj.fieldName,
|
|
111
|
+
};
|
|
112
|
+
schemaComposer.addDirective(directives_js_1.LinkDirective);
|
|
113
|
+
return {
|
|
114
|
+
...targetField,
|
|
115
|
+
directives: [
|
|
116
|
+
{
|
|
117
|
+
name: 'link',
|
|
118
|
+
args: {
|
|
119
|
+
defaultRootType: rootTypeName,
|
|
120
|
+
defaultField: operationConfig.field,
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
args: linkObj.args ? {} : targetField.args,
|
|
125
|
+
description: linkObj.description || targetField.description,
|
|
126
|
+
};
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
if ('links' in operationConfig) {
|
|
132
|
+
const typeTC = schemaComposer.getOTC(field.type.getTypeName());
|
|
133
|
+
handleLinkMap(operationConfig.links, typeTC);
|
|
134
|
+
}
|
|
135
|
+
if ('exposeResponseMetadata' in operationConfig && operationConfig.exposeResponseMetadata) {
|
|
136
|
+
const typeTC = schemaComposer.getOTC(field.type.getTypeName());
|
|
137
|
+
schemaComposer.addDirective(directives_js_1.ResponseMetadataDirective);
|
|
138
|
+
typeTC.addFields({
|
|
139
|
+
_response: {
|
|
140
|
+
type: responseMetadataType,
|
|
141
|
+
directives: [
|
|
142
|
+
{
|
|
143
|
+
name: 'responseMetadata',
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
if ('responseByStatusCode' in operationConfig) {
|
|
150
|
+
const unionOrSingleTC = schemaComposer.getAnyTC((0, graphql_1.getNamedType)(field.type.getType()));
|
|
151
|
+
const types = 'getTypes' in unionOrSingleTC ? unionOrSingleTC.getTypes() : [unionOrSingleTC];
|
|
152
|
+
const statusCodeOneOfIndexMap = {};
|
|
153
|
+
const directives = unionOrSingleTC.getDirectives();
|
|
154
|
+
for (const directive of directives) {
|
|
155
|
+
if (directive.name === 'statusCodeOneOfIndex') {
|
|
156
|
+
statusCodeOneOfIndexMap[(_a = directive.args) === null || _a === void 0 ? void 0 : _a.statusCode] = (_b = directive.args) === null || _b === void 0 ? void 0 : _b.oneOfIndex;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
for (const statusCode in operationConfig.responseByStatusCode) {
|
|
160
|
+
const responseConfig = operationConfig.responseByStatusCode[statusCode];
|
|
161
|
+
if (responseConfig.links || responseConfig.exposeResponseMetadata) {
|
|
162
|
+
const typeTCThunked = types[statusCodeOneOfIndexMap[statusCode] || 0];
|
|
163
|
+
const originalName = typeTCThunked.getTypeName();
|
|
164
|
+
let typeTC = schemaComposer.getAnyTC(originalName);
|
|
165
|
+
if (!('addFieldArgs' in typeTC)) {
|
|
166
|
+
schemaComposer.addDirective(directives_js_1.ResolveRootDirective);
|
|
167
|
+
typeTC = schemaComposer.createObjectTC({
|
|
168
|
+
name: `${operationConfig.field}_${statusCode}_response`,
|
|
169
|
+
fields: {
|
|
170
|
+
[originalName]: {
|
|
171
|
+
type: typeTC,
|
|
172
|
+
directives: [
|
|
173
|
+
{
|
|
174
|
+
name: 'resolveRoot',
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
// If it is a scalar or enum type, it cannot be a union type, so we can set it directly
|
|
181
|
+
types[0] = typeTC;
|
|
182
|
+
field.type = typeTC;
|
|
183
|
+
}
|
|
184
|
+
if (responseConfig.exposeResponseMetadata) {
|
|
185
|
+
schemaComposer.addDirective(directives_js_1.ResponseMetadataDirective);
|
|
186
|
+
typeTC.addFields({
|
|
187
|
+
_response: {
|
|
188
|
+
type: responseMetadataType,
|
|
189
|
+
directives: [
|
|
190
|
+
{
|
|
191
|
+
name: 'responseMetadata',
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
if (responseConfig.links) {
|
|
198
|
+
handleLinkMap(responseConfig.links, typeTC);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
logger.debug(`Building the executable schema.`);
|
|
206
|
+
return schemaComposer;
|
|
207
|
+
}
|
|
208
|
+
exports.addExecutionDirectivesToComposer = addExecutionDirectivesToComposer;
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.addHTTPRootFieldResolver = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const dset_1 = require("dset");
|
|
6
|
+
const graphql_1 = require("graphql");
|
|
7
|
+
const qs_1 = require("qs");
|
|
8
|
+
const url_join_1 = tslib_1.__importDefault(require("url-join"));
|
|
9
|
+
const cross_helpers_1 = require("@graphql-mesh/cross-helpers");
|
|
10
|
+
const string_interpolation_1 = require("@graphql-mesh/string-interpolation");
|
|
11
|
+
const utils_1 = require("@graphql-mesh/utils");
|
|
12
|
+
const utils_2 = require("@graphql-tools/utils");
|
|
13
|
+
const fetch_1 = require("@whatwg-node/fetch");
|
|
14
|
+
const resolveDataByUnionInputType_js_1 = require("./resolveDataByUnionInputType.js");
|
|
15
|
+
const utils_js_1 = require("./utils.js");
|
|
16
|
+
const isListTypeOrNonNullListType = (0, utils_2.memoize1)(function isListTypeOrNonNullListType(type) {
|
|
17
|
+
if ((0, graphql_1.isNonNullType)(type)) {
|
|
18
|
+
return (0, graphql_1.isListType)(type.ofType);
|
|
19
|
+
}
|
|
20
|
+
return (0, graphql_1.isListType)(type);
|
|
21
|
+
});
|
|
22
|
+
const defaultQsOptions = {
|
|
23
|
+
indices: false,
|
|
24
|
+
};
|
|
25
|
+
function addHTTPRootFieldResolver(schema, field, logger, globalFetch, { path, operationSpecificHeaders, httpMethod, isBinary, requestBaseBody, queryParamArgMap, queryStringOptionsByParam, }, { sourceName, endpoint, timeout, operationHeaders: globalOperationHeaders, queryStringOptions: globalQueryStringOptions = {}, queryParams: globalQueryParams, }) {
|
|
26
|
+
globalQueryStringOptions = {
|
|
27
|
+
...defaultQsOptions,
|
|
28
|
+
...globalQueryStringOptions,
|
|
29
|
+
};
|
|
30
|
+
const returnNamedGraphQLType = (0, graphql_1.getNamedType)(field.type);
|
|
31
|
+
field.resolve = async (root, args, context, info) => {
|
|
32
|
+
var _a, _b;
|
|
33
|
+
const operationLogger = logger.child(`${info.parentType.name}.${info.fieldName}`);
|
|
34
|
+
operationLogger.debug(`=> Resolving`);
|
|
35
|
+
const interpolationData = { root, args, context, env: cross_helpers_1.process.env };
|
|
36
|
+
const interpolatedBaseUrl = string_interpolation_1.stringInterpolator.parse(endpoint, interpolationData);
|
|
37
|
+
const interpolatedPath = string_interpolation_1.stringInterpolator.parse(path, interpolationData);
|
|
38
|
+
let fullPath = (0, url_join_1.default)(interpolatedBaseUrl, interpolatedPath);
|
|
39
|
+
const headers = {};
|
|
40
|
+
for (const headerName in globalOperationHeaders) {
|
|
41
|
+
const nonInterpolatedValue = globalOperationHeaders[headerName];
|
|
42
|
+
const interpolatedValue = string_interpolation_1.stringInterpolator.parse(nonInterpolatedValue, interpolationData);
|
|
43
|
+
if (interpolatedValue) {
|
|
44
|
+
headers[headerName.toLowerCase()] = interpolatedValue;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (operationSpecificHeaders) {
|
|
48
|
+
for (const headerName in operationSpecificHeaders) {
|
|
49
|
+
const nonInterpolatedValue = operationSpecificHeaders[headerName];
|
|
50
|
+
const interpolatedValue = string_interpolation_1.stringInterpolator.parse(nonInterpolatedValue, interpolationData);
|
|
51
|
+
if (interpolatedValue) {
|
|
52
|
+
headers[headerName.toLowerCase()] = interpolatedValue;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const requestInit = {
|
|
57
|
+
method: httpMethod,
|
|
58
|
+
headers,
|
|
59
|
+
};
|
|
60
|
+
if (timeout) {
|
|
61
|
+
requestInit.signal = fetch_1.AbortSignal.timeout(timeout);
|
|
62
|
+
}
|
|
63
|
+
// Handle binary data
|
|
64
|
+
if (isBinary) {
|
|
65
|
+
const binaryUpload = await args.input;
|
|
66
|
+
if ((0, utils_js_1.isFileUpload)(binaryUpload)) {
|
|
67
|
+
const readable = binaryUpload.createReadStream();
|
|
68
|
+
const chunks = [];
|
|
69
|
+
for await (const chunk of readable) {
|
|
70
|
+
for (const byte of chunk) {
|
|
71
|
+
chunks.push(byte);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
requestInit.body = new Uint8Array(chunks);
|
|
75
|
+
const [, contentType] = Object.entries(headers).find(([key]) => key.toLowerCase() === 'content-type') || [];
|
|
76
|
+
if (!contentType) {
|
|
77
|
+
headers['content-type'] = binaryUpload.mimetype;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
requestInit.body = binaryUpload;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
if (requestBaseBody != null) {
|
|
84
|
+
args.input = args.input || {};
|
|
85
|
+
for (const key in requestBaseBody) {
|
|
86
|
+
const configValue = requestBaseBody[key];
|
|
87
|
+
if (typeof configValue === 'string') {
|
|
88
|
+
const value = string_interpolation_1.stringInterpolator.parse(configValue, interpolationData);
|
|
89
|
+
(0, dset_1.dset)(args.input, key, value);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
args.input[key] = configValue;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Resolve union input
|
|
97
|
+
const input = (args.input = (0, resolveDataByUnionInputType_js_1.resolveDataByUnionInputType)(args.input, (_b = (_a = field.args) === null || _a === void 0 ? void 0 : _a.find(arg => arg.name === 'input')) === null || _b === void 0 ? void 0 : _b.type, schema));
|
|
98
|
+
if (input != null) {
|
|
99
|
+
const [, contentType] = Object.entries(headers).find(([key]) => key.toLowerCase() === 'content-type') || [];
|
|
100
|
+
if (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('application/x-www-form-urlencoded')) {
|
|
101
|
+
requestInit.body = (0, qs_1.stringify)(input, globalQueryStringOptions);
|
|
102
|
+
}
|
|
103
|
+
else if (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('multipart/form-data')) {
|
|
104
|
+
delete headers['content-type'];
|
|
105
|
+
delete headers['Content-Type'];
|
|
106
|
+
const formData = new fetch_1.FormData();
|
|
107
|
+
for (const key in input) {
|
|
108
|
+
const inputValue = input[key];
|
|
109
|
+
if (inputValue != null) {
|
|
110
|
+
let formDataValue;
|
|
111
|
+
if (typeof inputValue === 'object') {
|
|
112
|
+
if (inputValue instanceof fetch_1.File) {
|
|
113
|
+
formDataValue = inputValue;
|
|
114
|
+
}
|
|
115
|
+
else if (inputValue.name && inputValue instanceof fetch_1.Blob) {
|
|
116
|
+
formDataValue = new fetch_1.File([inputValue], inputValue.name, {
|
|
117
|
+
type: inputValue.type,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
else if (inputValue.arrayBuffer) {
|
|
121
|
+
const arrayBuffer = await inputValue.arrayBuffer();
|
|
122
|
+
if (inputValue.name) {
|
|
123
|
+
formDataValue = new fetch_1.File([arrayBuffer], inputValue.name, {
|
|
124
|
+
type: inputValue.type,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
formDataValue = new fetch_1.Blob([arrayBuffer], { type: inputValue.type });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
formDataValue = JSON.stringify(inputValue);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
formDataValue = inputValue.toString();
|
|
137
|
+
}
|
|
138
|
+
formData.append(key, formDataValue);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
requestInit.body = formData;
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
requestInit.body = typeof input === 'object' ? JSON.stringify(input) : input;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (globalQueryParams) {
|
|
149
|
+
for (const queryParamName in globalQueryParams) {
|
|
150
|
+
if (args != null &&
|
|
151
|
+
queryParamArgMap != null &&
|
|
152
|
+
queryParamName in queryParamArgMap &&
|
|
153
|
+
queryParamArgMap[queryParamName] in args) {
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
const interpolatedQueryParam = string_interpolation_1.stringInterpolator.parse(globalQueryParams[queryParamName].toString(), interpolationData);
|
|
157
|
+
const queryParamsString = (0, qs_1.stringify)({
|
|
158
|
+
[queryParamName]: interpolatedQueryParam,
|
|
159
|
+
}, {
|
|
160
|
+
...globalQueryStringOptions,
|
|
161
|
+
...queryStringOptionsByParam === null || queryStringOptionsByParam === void 0 ? void 0 : queryStringOptionsByParam[queryParamName],
|
|
162
|
+
});
|
|
163
|
+
fullPath += fullPath.includes('?') ? '&' : '?';
|
|
164
|
+
fullPath += queryParamsString;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (queryParamArgMap) {
|
|
168
|
+
for (const queryParamName in queryParamArgMap) {
|
|
169
|
+
const argName = queryParamArgMap[queryParamName];
|
|
170
|
+
let argValue = args[argName];
|
|
171
|
+
if (argValue != null) {
|
|
172
|
+
// Somehow it doesn't serialize URLs so we need to do it manually.
|
|
173
|
+
if (argValue instanceof URL) {
|
|
174
|
+
argValue = argValue.toString();
|
|
175
|
+
}
|
|
176
|
+
const opts = {
|
|
177
|
+
...globalQueryStringOptions,
|
|
178
|
+
...queryStringOptionsByParam === null || queryStringOptionsByParam === void 0 ? void 0 : queryStringOptionsByParam[queryParamName],
|
|
179
|
+
};
|
|
180
|
+
let queryParamObj = argValue;
|
|
181
|
+
if (Array.isArray(argValue) || !(typeof argValue === 'object' && opts.destructObject)) {
|
|
182
|
+
queryParamObj = {
|
|
183
|
+
[queryParamName]: argValue,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
const queryParamsString = (0, qs_1.stringify)(queryParamObj, opts);
|
|
187
|
+
fullPath += fullPath.includes('?') ? '&' : '?';
|
|
188
|
+
fullPath += queryParamsString;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
operationLogger.debug(`=> Fetching `, fullPath, `=>`, requestInit);
|
|
193
|
+
const fetch = (context === null || context === void 0 ? void 0 : context.fetch) || globalFetch;
|
|
194
|
+
if (!fetch) {
|
|
195
|
+
return (0, utils_2.createGraphQLError)(`You should have fetch defined in either the config or the context!`, {
|
|
196
|
+
extensions: {
|
|
197
|
+
request: {
|
|
198
|
+
url: fullPath,
|
|
199
|
+
method: httpMethod,
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
// Trick to pass `sourceName` to the `fetch` function for tracing
|
|
205
|
+
const response = await fetch(fullPath, requestInit, context, {
|
|
206
|
+
...info,
|
|
207
|
+
sourceName,
|
|
208
|
+
});
|
|
209
|
+
// If return type is a file
|
|
210
|
+
if (returnNamedGraphQLType.name === 'File') {
|
|
211
|
+
return response.blob();
|
|
212
|
+
}
|
|
213
|
+
const responseText = await response.text();
|
|
214
|
+
operationLogger.debug(`=> Received`, {
|
|
215
|
+
headers: response.headers,
|
|
216
|
+
text: responseText,
|
|
217
|
+
});
|
|
218
|
+
let responseJson;
|
|
219
|
+
try {
|
|
220
|
+
responseJson = JSON.parse(responseText);
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
// The result might be defined as scalar
|
|
224
|
+
if ((0, graphql_1.isScalarType)(returnNamedGraphQLType)) {
|
|
225
|
+
operationLogger.debug(` => Return type is not a JSON so returning ${responseText}`);
|
|
226
|
+
return responseText;
|
|
227
|
+
}
|
|
228
|
+
else if (response.status === 204) {
|
|
229
|
+
responseJson = {};
|
|
230
|
+
}
|
|
231
|
+
else if (response.status.toString().startsWith('2')) {
|
|
232
|
+
logger.debug(`Unexpected response in ${field.name};\n\t${responseText}`);
|
|
233
|
+
return (0, utils_2.createGraphQLError)(`Unexpected response in ${field.name}`, {
|
|
234
|
+
extensions: {
|
|
235
|
+
http: {
|
|
236
|
+
status: response.status,
|
|
237
|
+
statusText: response.statusText,
|
|
238
|
+
headers: (0, utils_1.getHeadersObj)(response.headers),
|
|
239
|
+
},
|
|
240
|
+
request: {
|
|
241
|
+
url: fullPath,
|
|
242
|
+
method: httpMethod,
|
|
243
|
+
},
|
|
244
|
+
responseText,
|
|
245
|
+
originalError: {
|
|
246
|
+
message: error.message,
|
|
247
|
+
stack: error.stack,
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
return (0, utils_2.createGraphQLError)(`HTTP Error: ${response.status}, Could not invoke operation ${httpMethod} ${path}`, {
|
|
254
|
+
extensions: {
|
|
255
|
+
http: {
|
|
256
|
+
status: response.status,
|
|
257
|
+
statusText: response.statusText,
|
|
258
|
+
headers: (0, utils_1.getHeadersObj)(response.headers),
|
|
259
|
+
},
|
|
260
|
+
request: {
|
|
261
|
+
url: fullPath,
|
|
262
|
+
method: httpMethod,
|
|
263
|
+
},
|
|
264
|
+
responseText,
|
|
265
|
+
},
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (!response.status.toString().startsWith('2')) {
|
|
270
|
+
if (!(0, graphql_1.isUnionType)(returnNamedGraphQLType)) {
|
|
271
|
+
return (0, utils_2.createGraphQLError)(`HTTP Error: ${response.status}, Could not invoke operation ${httpMethod} ${path}`, {
|
|
272
|
+
extensions: {
|
|
273
|
+
http: {
|
|
274
|
+
status: response.status,
|
|
275
|
+
statusText: response.statusText,
|
|
276
|
+
headers: (0, utils_1.getHeadersObj)(response.headers),
|
|
277
|
+
},
|
|
278
|
+
request: {
|
|
279
|
+
url: fullPath,
|
|
280
|
+
method: httpMethod,
|
|
281
|
+
},
|
|
282
|
+
responseJson,
|
|
283
|
+
},
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
operationLogger.debug(`Returning `, responseJson);
|
|
288
|
+
// Sometimes API returns an array but the return type is not an array
|
|
289
|
+
const isListReturnType = isListTypeOrNonNullListType(field.type);
|
|
290
|
+
const isArrayResponse = Array.isArray(responseJson);
|
|
291
|
+
if (isListReturnType && !isArrayResponse) {
|
|
292
|
+
operationLogger.debug(`Response is not array but return type is list. Normalizing the response`);
|
|
293
|
+
responseJson = [responseJson];
|
|
294
|
+
}
|
|
295
|
+
if (!isListReturnType && isArrayResponse) {
|
|
296
|
+
operationLogger.debug(`Response is array but return type is not list. Normalizing the response`);
|
|
297
|
+
responseJson = responseJson[0];
|
|
298
|
+
}
|
|
299
|
+
const addResponseMetadata = (obj) => {
|
|
300
|
+
if (typeof obj !== 'object') {
|
|
301
|
+
return obj;
|
|
302
|
+
}
|
|
303
|
+
Object.defineProperties(obj, {
|
|
304
|
+
$field: {
|
|
305
|
+
get() {
|
|
306
|
+
return field.name;
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
$url: {
|
|
310
|
+
get() {
|
|
311
|
+
return fullPath.split('?')[0];
|
|
312
|
+
},
|
|
313
|
+
},
|
|
314
|
+
$method: {
|
|
315
|
+
get() {
|
|
316
|
+
return httpMethod;
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
$statusCode: {
|
|
320
|
+
get() {
|
|
321
|
+
return response.status;
|
|
322
|
+
},
|
|
323
|
+
},
|
|
324
|
+
$statusText: {
|
|
325
|
+
get() {
|
|
326
|
+
return response.statusText;
|
|
327
|
+
},
|
|
328
|
+
},
|
|
329
|
+
$headers: {
|
|
330
|
+
get() {
|
|
331
|
+
return requestInit.headers;
|
|
332
|
+
},
|
|
333
|
+
},
|
|
334
|
+
$request: {
|
|
335
|
+
get() {
|
|
336
|
+
return new Proxy({}, {
|
|
337
|
+
get(_, requestProp) {
|
|
338
|
+
switch (requestProp) {
|
|
339
|
+
case 'query':
|
|
340
|
+
return (0, qs_1.parse)(fullPath.split('?')[1]);
|
|
341
|
+
case 'path':
|
|
342
|
+
return new Proxy(args, {
|
|
343
|
+
get(_, prop) {
|
|
344
|
+
var _a;
|
|
345
|
+
return args[prop] || ((_a = args.input) === null || _a === void 0 ? void 0 : _a[prop]) || (obj === null || obj === void 0 ? void 0 : obj[prop]);
|
|
346
|
+
},
|
|
347
|
+
has(_, prop) {
|
|
348
|
+
return prop in args || (args.input && prop in args.input) || (obj === null || obj === void 0 ? void 0 : obj[prop]);
|
|
349
|
+
},
|
|
350
|
+
});
|
|
351
|
+
case 'header':
|
|
352
|
+
return requestInit.headers;
|
|
353
|
+
case 'body':
|
|
354
|
+
return requestInit.body;
|
|
355
|
+
}
|
|
356
|
+
},
|
|
357
|
+
});
|
|
358
|
+
},
|
|
359
|
+
},
|
|
360
|
+
$response: {
|
|
361
|
+
get() {
|
|
362
|
+
return new Proxy({}, {
|
|
363
|
+
get(_, responseProp) {
|
|
364
|
+
switch (responseProp) {
|
|
365
|
+
case 'header':
|
|
366
|
+
return (0, utils_1.getHeadersObj)(response.headers);
|
|
367
|
+
case 'body':
|
|
368
|
+
return obj;
|
|
369
|
+
case 'query':
|
|
370
|
+
return (0, qs_1.parse)(fullPath.split('?')[1]);
|
|
371
|
+
case 'path':
|
|
372
|
+
return new Proxy(args, {
|
|
373
|
+
get(_, prop) {
|
|
374
|
+
var _a;
|
|
375
|
+
return args[prop] || ((_a = args.input) === null || _a === void 0 ? void 0 : _a[prop]) || (obj === null || obj === void 0 ? void 0 : obj[prop]);
|
|
376
|
+
},
|
|
377
|
+
has(_, prop) {
|
|
378
|
+
return prop in args || (args.input && prop in args.input) || (obj === null || obj === void 0 ? void 0 : obj[prop]);
|
|
379
|
+
},
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
},
|
|
383
|
+
});
|
|
384
|
+
},
|
|
385
|
+
},
|
|
386
|
+
});
|
|
387
|
+
return obj;
|
|
388
|
+
};
|
|
389
|
+
operationLogger.debug(`Adding response metadata to the response object`);
|
|
390
|
+
return Array.isArray(responseJson)
|
|
391
|
+
? responseJson.map(obj => addResponseMetadata(obj))
|
|
392
|
+
: addResponseMetadata(responseJson);
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
exports.addHTTPRootFieldResolver = addHTTPRootFieldResolver;
|