@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.
Files changed (89) hide show
  1. package/README.md +5 -4
  2. package/cjs/addExecutionLogicToComposer.js +208 -0
  3. package/cjs/addRootFieldResolver.js +395 -0
  4. package/cjs/bundle.js +65 -0
  5. package/cjs/directives.js +580 -0
  6. package/cjs/getComposerFromJSONSchema.js +1297 -0
  7. package/cjs/getDereferencedJSONSchemaFromOperations.js +33 -0
  8. package/cjs/getGraphQLSchemaFromDereferencedJSONSchema.js +39 -0
  9. package/cjs/getJSONSchemaStringFormatScalarMap.js +61 -0
  10. package/cjs/getReferencedJSONSchemaFromOperations.js +260 -0
  11. package/cjs/getTypeResolverFromOutputTCs.js +69 -0
  12. package/cjs/getUnionTypeComposers.js +85 -0
  13. package/cjs/getValidTypeName.js +20 -0
  14. package/cjs/index.js +14 -0
  15. package/cjs/loadGraphQLSchemaFromJSONSchemas.js +59 -0
  16. package/cjs/package.json +1 -0
  17. package/cjs/resolveDataByUnionInputType.js +40 -0
  18. package/cjs/scalars.js +30 -0
  19. package/cjs/types.js +0 -0
  20. package/cjs/utils.js +65 -0
  21. package/esm/addExecutionLogicToComposer.js +204 -0
  22. package/esm/addRootFieldResolver.js +390 -0
  23. package/esm/bundle.js +60 -0
  24. package/esm/directives.js +565 -0
  25. package/esm/getComposerFromJSONSchema.js +1293 -0
  26. package/esm/getDereferencedJSONSchemaFromOperations.js +29 -0
  27. package/esm/getGraphQLSchemaFromDereferencedJSONSchema.js +35 -0
  28. package/esm/getJSONSchemaStringFormatScalarMap.js +56 -0
  29. package/esm/getReferencedJSONSchemaFromOperations.js +255 -0
  30. package/esm/getTypeResolverFromOutputTCs.js +65 -0
  31. package/esm/getUnionTypeComposers.js +80 -0
  32. package/esm/getValidTypeName.js +16 -0
  33. package/esm/index.js +9 -0
  34. package/esm/loadGraphQLSchemaFromJSONSchemas.js +54 -0
  35. package/esm/resolveDataByUnionInputType.js +36 -0
  36. package/esm/scalars.js +27 -0
  37. package/esm/types.js +0 -0
  38. package/esm/utils.js +57 -0
  39. package/package.json +34 -27
  40. package/typings/addExecutionLogicToComposer.d.cts +14 -0
  41. package/typings/addExecutionLogicToComposer.d.ts +14 -0
  42. package/typings/addRootFieldResolver.d.cts +26 -0
  43. package/typings/addRootFieldResolver.d.ts +26 -0
  44. package/typings/bundle.d.cts +34 -0
  45. package/typings/bundle.d.ts +34 -0
  46. package/typings/directives.d.cts +54 -0
  47. package/typings/directives.d.ts +54 -0
  48. package/typings/getComposerFromJSONSchema.d.cts +13 -0
  49. package/{getComposerFromJSONSchema.d.ts → typings/getComposerFromJSONSchema.d.ts} +7 -4
  50. package/typings/getDereferencedJSONSchemaFromOperations.d.cts +14 -0
  51. package/{getDereferencedJSONSchemaFromOperations.d.ts → typings/getDereferencedJSONSchemaFromOperations.d.ts} +5 -3
  52. package/typings/getGraphQLSchemaFromDereferencedJSONSchema.d.cts +5 -0
  53. package/typings/getGraphQLSchemaFromDereferencedJSONSchema.d.ts +5 -0
  54. package/typings/getJSONSchemaStringFormatScalarMap.d.cts +2 -0
  55. package/typings/getJSONSchemaStringFormatScalarMap.d.ts +2 -0
  56. package/typings/getReferencedJSONSchemaFromOperations.d.cts +16 -0
  57. package/{getReferencedJSONSchemaFromOperations.d.ts → typings/getReferencedJSONSchemaFromOperations.d.ts} +6 -4
  58. package/typings/getTypeResolverFromOutputTCs.d.cts +7 -0
  59. package/typings/getTypeResolverFromOutputTCs.d.ts +7 -0
  60. package/typings/getUnionTypeComposers.d.cts +24 -0
  61. package/typings/getUnionTypeComposers.d.ts +24 -0
  62. package/{getStringScalarWithMinMaxLength.d.ts → typings/getValidTypeName.d.cts} +4 -3
  63. package/typings/index.d.cts +9 -0
  64. package/typings/index.d.ts +9 -0
  65. package/typings/loadGraphQLSchemaFromJSONSchemas.d.cts +3 -0
  66. package/typings/loadGraphQLSchemaFromJSONSchemas.d.ts +3 -0
  67. package/typings/resolveDataByUnionInputType.d.cts +2 -0
  68. package/typings/resolveDataByUnionInputType.d.ts +2 -0
  69. package/typings/scalars.d.cts +4 -0
  70. package/typings/scalars.d.ts +4 -0
  71. package/typings/types.d.cts +76 -0
  72. package/typings/types.d.ts +76 -0
  73. package/typings/utils.d.cts +15 -0
  74. package/{utils.d.ts → typings/utils.d.ts} +1 -1
  75. package/addExecutionLogicToComposer.d.ts +0 -15
  76. package/bundle.d.ts +0 -39
  77. package/getGenericJSONScalar.d.ts +0 -8
  78. package/getGraphQLSchemaFromDereferencedJSONSchema.d.ts +0 -5
  79. package/getJSONSchemaStringFormatScalarMap.d.ts +0 -3
  80. package/getTypeResolverFromOutputTCs.d.ts +0 -4
  81. package/getUnionTypeComposers.d.ts +0 -21
  82. package/getValidateFnForSchemaPath.d.ts +0 -3
  83. package/index.d.ts +0 -9
  84. package/index.js +0 -1890
  85. package/index.mjs +0 -1877
  86. package/loadGraphQLSchemaFromJSONSchemas.d.ts +0 -2
  87. package/resolveDataByUnionInputType.d.ts +0 -3
  88. package/types.d.ts +0 -63
  89. package/{getValidTypeName.d.ts → typings/getValidTypeName.d.ts} +1 -1
@@ -0,0 +1,390 @@
1
+ import { dset } from 'dset';
2
+ import { getNamedType, isListType, isNonNullType, isScalarType, isUnionType, } from 'graphql';
3
+ import { parse as qsParse, stringify as qsStringify } from 'qs';
4
+ import urlJoin from 'url-join';
5
+ import { process } from '@graphql-mesh/cross-helpers';
6
+ import { stringInterpolator } from '@graphql-mesh/string-interpolation';
7
+ import { getHeadersObj } from '@graphql-mesh/utils';
8
+ import { createGraphQLError, memoize1 } from '@graphql-tools/utils';
9
+ import { AbortSignal, Blob, File, FormData } from '@whatwg-node/fetch';
10
+ import { resolveDataByUnionInputType } from './resolveDataByUnionInputType.js';
11
+ import { isFileUpload } from './utils.js';
12
+ const isListTypeOrNonNullListType = memoize1(function isListTypeOrNonNullListType(type) {
13
+ if (isNonNullType(type)) {
14
+ return isListType(type.ofType);
15
+ }
16
+ return isListType(type);
17
+ });
18
+ const defaultQsOptions = {
19
+ indices: false,
20
+ };
21
+ export function addHTTPRootFieldResolver(schema, field, logger, globalFetch, { path, operationSpecificHeaders, httpMethod, isBinary, requestBaseBody, queryParamArgMap, queryStringOptionsByParam, }, { sourceName, endpoint, timeout, operationHeaders: globalOperationHeaders, queryStringOptions: globalQueryStringOptions = {}, queryParams: globalQueryParams, }) {
22
+ globalQueryStringOptions = {
23
+ ...defaultQsOptions,
24
+ ...globalQueryStringOptions,
25
+ };
26
+ const returnNamedGraphQLType = getNamedType(field.type);
27
+ field.resolve = async (root, args, context, info) => {
28
+ var _a, _b;
29
+ const operationLogger = logger.child(`${info.parentType.name}.${info.fieldName}`);
30
+ operationLogger.debug(`=> Resolving`);
31
+ const interpolationData = { root, args, context, env: process.env };
32
+ const interpolatedBaseUrl = stringInterpolator.parse(endpoint, interpolationData);
33
+ const interpolatedPath = stringInterpolator.parse(path, interpolationData);
34
+ let fullPath = urlJoin(interpolatedBaseUrl, interpolatedPath);
35
+ const headers = {};
36
+ for (const headerName in globalOperationHeaders) {
37
+ const nonInterpolatedValue = globalOperationHeaders[headerName];
38
+ const interpolatedValue = stringInterpolator.parse(nonInterpolatedValue, interpolationData);
39
+ if (interpolatedValue) {
40
+ headers[headerName.toLowerCase()] = interpolatedValue;
41
+ }
42
+ }
43
+ if (operationSpecificHeaders) {
44
+ for (const headerName in operationSpecificHeaders) {
45
+ const nonInterpolatedValue = operationSpecificHeaders[headerName];
46
+ const interpolatedValue = stringInterpolator.parse(nonInterpolatedValue, interpolationData);
47
+ if (interpolatedValue) {
48
+ headers[headerName.toLowerCase()] = interpolatedValue;
49
+ }
50
+ }
51
+ }
52
+ const requestInit = {
53
+ method: httpMethod,
54
+ headers,
55
+ };
56
+ if (timeout) {
57
+ requestInit.signal = AbortSignal.timeout(timeout);
58
+ }
59
+ // Handle binary data
60
+ if (isBinary) {
61
+ const binaryUpload = await args.input;
62
+ if (isFileUpload(binaryUpload)) {
63
+ const readable = binaryUpload.createReadStream();
64
+ const chunks = [];
65
+ for await (const chunk of readable) {
66
+ for (const byte of chunk) {
67
+ chunks.push(byte);
68
+ }
69
+ }
70
+ requestInit.body = new Uint8Array(chunks);
71
+ const [, contentType] = Object.entries(headers).find(([key]) => key.toLowerCase() === 'content-type') || [];
72
+ if (!contentType) {
73
+ headers['content-type'] = binaryUpload.mimetype;
74
+ }
75
+ }
76
+ requestInit.body = binaryUpload;
77
+ }
78
+ else {
79
+ if (requestBaseBody != null) {
80
+ args.input = args.input || {};
81
+ for (const key in requestBaseBody) {
82
+ const configValue = requestBaseBody[key];
83
+ if (typeof configValue === 'string') {
84
+ const value = stringInterpolator.parse(configValue, interpolationData);
85
+ dset(args.input, key, value);
86
+ }
87
+ else {
88
+ args.input[key] = configValue;
89
+ }
90
+ }
91
+ }
92
+ // Resolve union input
93
+ const input = (args.input = 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));
94
+ if (input != null) {
95
+ const [, contentType] = Object.entries(headers).find(([key]) => key.toLowerCase() === 'content-type') || [];
96
+ if (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('application/x-www-form-urlencoded')) {
97
+ requestInit.body = qsStringify(input, globalQueryStringOptions);
98
+ }
99
+ else if (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('multipart/form-data')) {
100
+ delete headers['content-type'];
101
+ delete headers['Content-Type'];
102
+ const formData = new FormData();
103
+ for (const key in input) {
104
+ const inputValue = input[key];
105
+ if (inputValue != null) {
106
+ let formDataValue;
107
+ if (typeof inputValue === 'object') {
108
+ if (inputValue instanceof File) {
109
+ formDataValue = inputValue;
110
+ }
111
+ else if (inputValue.name && inputValue instanceof Blob) {
112
+ formDataValue = new File([inputValue], inputValue.name, {
113
+ type: inputValue.type,
114
+ });
115
+ }
116
+ else if (inputValue.arrayBuffer) {
117
+ const arrayBuffer = await inputValue.arrayBuffer();
118
+ if (inputValue.name) {
119
+ formDataValue = new File([arrayBuffer], inputValue.name, {
120
+ type: inputValue.type,
121
+ });
122
+ }
123
+ else {
124
+ formDataValue = new Blob([arrayBuffer], { type: inputValue.type });
125
+ }
126
+ }
127
+ else {
128
+ formDataValue = JSON.stringify(inputValue);
129
+ }
130
+ }
131
+ else {
132
+ formDataValue = inputValue.toString();
133
+ }
134
+ formData.append(key, formDataValue);
135
+ }
136
+ }
137
+ requestInit.body = formData;
138
+ }
139
+ else {
140
+ requestInit.body = typeof input === 'object' ? JSON.stringify(input) : input;
141
+ }
142
+ }
143
+ }
144
+ if (globalQueryParams) {
145
+ for (const queryParamName in globalQueryParams) {
146
+ if (args != null &&
147
+ queryParamArgMap != null &&
148
+ queryParamName in queryParamArgMap &&
149
+ queryParamArgMap[queryParamName] in args) {
150
+ continue;
151
+ }
152
+ const interpolatedQueryParam = stringInterpolator.parse(globalQueryParams[queryParamName].toString(), interpolationData);
153
+ const queryParamsString = qsStringify({
154
+ [queryParamName]: interpolatedQueryParam,
155
+ }, {
156
+ ...globalQueryStringOptions,
157
+ ...queryStringOptionsByParam === null || queryStringOptionsByParam === void 0 ? void 0 : queryStringOptionsByParam[queryParamName],
158
+ });
159
+ fullPath += fullPath.includes('?') ? '&' : '?';
160
+ fullPath += queryParamsString;
161
+ }
162
+ }
163
+ if (queryParamArgMap) {
164
+ for (const queryParamName in queryParamArgMap) {
165
+ const argName = queryParamArgMap[queryParamName];
166
+ let argValue = args[argName];
167
+ if (argValue != null) {
168
+ // Somehow it doesn't serialize URLs so we need to do it manually.
169
+ if (argValue instanceof URL) {
170
+ argValue = argValue.toString();
171
+ }
172
+ const opts = {
173
+ ...globalQueryStringOptions,
174
+ ...queryStringOptionsByParam === null || queryStringOptionsByParam === void 0 ? void 0 : queryStringOptionsByParam[queryParamName],
175
+ };
176
+ let queryParamObj = argValue;
177
+ if (Array.isArray(argValue) || !(typeof argValue === 'object' && opts.destructObject)) {
178
+ queryParamObj = {
179
+ [queryParamName]: argValue,
180
+ };
181
+ }
182
+ const queryParamsString = qsStringify(queryParamObj, opts);
183
+ fullPath += fullPath.includes('?') ? '&' : '?';
184
+ fullPath += queryParamsString;
185
+ }
186
+ }
187
+ }
188
+ operationLogger.debug(`=> Fetching `, fullPath, `=>`, requestInit);
189
+ const fetch = (context === null || context === void 0 ? void 0 : context.fetch) || globalFetch;
190
+ if (!fetch) {
191
+ return createGraphQLError(`You should have fetch defined in either the config or the context!`, {
192
+ extensions: {
193
+ request: {
194
+ url: fullPath,
195
+ method: httpMethod,
196
+ },
197
+ },
198
+ });
199
+ }
200
+ // Trick to pass `sourceName` to the `fetch` function for tracing
201
+ const response = await fetch(fullPath, requestInit, context, {
202
+ ...info,
203
+ sourceName,
204
+ });
205
+ // If return type is a file
206
+ if (returnNamedGraphQLType.name === 'File') {
207
+ return response.blob();
208
+ }
209
+ const responseText = await response.text();
210
+ operationLogger.debug(`=> Received`, {
211
+ headers: response.headers,
212
+ text: responseText,
213
+ });
214
+ let responseJson;
215
+ try {
216
+ responseJson = JSON.parse(responseText);
217
+ }
218
+ catch (error) {
219
+ // The result might be defined as scalar
220
+ if (isScalarType(returnNamedGraphQLType)) {
221
+ operationLogger.debug(` => Return type is not a JSON so returning ${responseText}`);
222
+ return responseText;
223
+ }
224
+ else if (response.status === 204) {
225
+ responseJson = {};
226
+ }
227
+ else if (response.status.toString().startsWith('2')) {
228
+ logger.debug(`Unexpected response in ${field.name};\n\t${responseText}`);
229
+ return createGraphQLError(`Unexpected response in ${field.name}`, {
230
+ extensions: {
231
+ http: {
232
+ status: response.status,
233
+ statusText: response.statusText,
234
+ headers: getHeadersObj(response.headers),
235
+ },
236
+ request: {
237
+ url: fullPath,
238
+ method: httpMethod,
239
+ },
240
+ responseText,
241
+ originalError: {
242
+ message: error.message,
243
+ stack: error.stack,
244
+ },
245
+ },
246
+ });
247
+ }
248
+ else {
249
+ return createGraphQLError(`HTTP Error: ${response.status}, Could not invoke operation ${httpMethod} ${path}`, {
250
+ extensions: {
251
+ http: {
252
+ status: response.status,
253
+ statusText: response.statusText,
254
+ headers: getHeadersObj(response.headers),
255
+ },
256
+ request: {
257
+ url: fullPath,
258
+ method: httpMethod,
259
+ },
260
+ responseText,
261
+ },
262
+ });
263
+ }
264
+ }
265
+ if (!response.status.toString().startsWith('2')) {
266
+ if (!isUnionType(returnNamedGraphQLType)) {
267
+ return createGraphQLError(`HTTP Error: ${response.status}, Could not invoke operation ${httpMethod} ${path}`, {
268
+ extensions: {
269
+ http: {
270
+ status: response.status,
271
+ statusText: response.statusText,
272
+ headers: getHeadersObj(response.headers),
273
+ },
274
+ request: {
275
+ url: fullPath,
276
+ method: httpMethod,
277
+ },
278
+ responseJson,
279
+ },
280
+ });
281
+ }
282
+ }
283
+ operationLogger.debug(`Returning `, responseJson);
284
+ // Sometimes API returns an array but the return type is not an array
285
+ const isListReturnType = isListTypeOrNonNullListType(field.type);
286
+ const isArrayResponse = Array.isArray(responseJson);
287
+ if (isListReturnType && !isArrayResponse) {
288
+ operationLogger.debug(`Response is not array but return type is list. Normalizing the response`);
289
+ responseJson = [responseJson];
290
+ }
291
+ if (!isListReturnType && isArrayResponse) {
292
+ operationLogger.debug(`Response is array but return type is not list. Normalizing the response`);
293
+ responseJson = responseJson[0];
294
+ }
295
+ const addResponseMetadata = (obj) => {
296
+ if (typeof obj !== 'object') {
297
+ return obj;
298
+ }
299
+ Object.defineProperties(obj, {
300
+ $field: {
301
+ get() {
302
+ return field.name;
303
+ },
304
+ },
305
+ $url: {
306
+ get() {
307
+ return fullPath.split('?')[0];
308
+ },
309
+ },
310
+ $method: {
311
+ get() {
312
+ return httpMethod;
313
+ },
314
+ },
315
+ $statusCode: {
316
+ get() {
317
+ return response.status;
318
+ },
319
+ },
320
+ $statusText: {
321
+ get() {
322
+ return response.statusText;
323
+ },
324
+ },
325
+ $headers: {
326
+ get() {
327
+ return requestInit.headers;
328
+ },
329
+ },
330
+ $request: {
331
+ get() {
332
+ return new Proxy({}, {
333
+ get(_, requestProp) {
334
+ switch (requestProp) {
335
+ case 'query':
336
+ return qsParse(fullPath.split('?')[1]);
337
+ case 'path':
338
+ return new Proxy(args, {
339
+ get(_, prop) {
340
+ var _a;
341
+ return args[prop] || ((_a = args.input) === null || _a === void 0 ? void 0 : _a[prop]) || (obj === null || obj === void 0 ? void 0 : obj[prop]);
342
+ },
343
+ has(_, prop) {
344
+ return prop in args || (args.input && prop in args.input) || (obj === null || obj === void 0 ? void 0 : obj[prop]);
345
+ },
346
+ });
347
+ case 'header':
348
+ return requestInit.headers;
349
+ case 'body':
350
+ return requestInit.body;
351
+ }
352
+ },
353
+ });
354
+ },
355
+ },
356
+ $response: {
357
+ get() {
358
+ return new Proxy({}, {
359
+ get(_, responseProp) {
360
+ switch (responseProp) {
361
+ case 'header':
362
+ return getHeadersObj(response.headers);
363
+ case 'body':
364
+ return obj;
365
+ case 'query':
366
+ return qsParse(fullPath.split('?')[1]);
367
+ case 'path':
368
+ return new Proxy(args, {
369
+ get(_, prop) {
370
+ var _a;
371
+ return args[prop] || ((_a = args.input) === null || _a === void 0 ? void 0 : _a[prop]) || (obj === null || obj === void 0 ? void 0 : obj[prop]);
372
+ },
373
+ has(_, prop) {
374
+ return prop in args || (args.input && prop in args.input) || (obj === null || obj === void 0 ? void 0 : obj[prop]);
375
+ },
376
+ });
377
+ }
378
+ },
379
+ });
380
+ },
381
+ },
382
+ });
383
+ return obj;
384
+ };
385
+ operationLogger.debug(`Adding response metadata to the response object`);
386
+ return Array.isArray(responseJson)
387
+ ? responseJson.map(obj => addResponseMetadata(obj))
388
+ : addResponseMetadata(responseJson);
389
+ };
390
+ }
package/esm/bundle.js ADDED
@@ -0,0 +1,60 @@
1
+ import { dereferenceObject, referenceJSONSchema } from 'json-machete';
2
+ import { DefaultLogger } from '@graphql-mesh/utils';
3
+ import { fetch as crossUndiciFetch } from '@whatwg-node/fetch';
4
+ import { getGraphQLSchemaFromDereferencedJSONSchema } from './getGraphQLSchemaFromDereferencedJSONSchema.js';
5
+ export async function createBundleFromDereferencedSchema(name, { dereferencedSchema, endpoint, operations, operationHeaders, logger = new DefaultLogger(name), }) {
6
+ logger.debug(`Creating references from dereferenced schema`);
7
+ const referencedSchema = await referenceJSONSchema(dereferencedSchema);
8
+ logger.debug(`Bundle generation finished`);
9
+ return {
10
+ name,
11
+ endpoint,
12
+ operations,
13
+ operationHeaders: typeof operationHeaders === 'object' ? operationHeaders : {},
14
+ referencedSchema,
15
+ };
16
+ }
17
+ /**
18
+ * Generates a local GraphQLSchema instance from
19
+ * previously generated JSON Schema bundle
20
+ */
21
+ export async function getGraphQLSchemaFromBundle({ name, endpoint: bundledBaseUrl, operations, operationHeaders: bundledOperationHeaders = {}, referencedSchema, }, { cwd = process.cwd(), logger = new DefaultLogger(name), fetch = crossUndiciFetch, endpoint: overwrittenBaseUrl, operationHeaders: additionalOperationHeaders = {}, queryParams, queryStringOptions, } = {}) {
22
+ logger.info(`Dereferencing the bundle`);
23
+ const fullyDeferencedSchema = await dereferenceObject(referencedSchema, {
24
+ cwd,
25
+ fetchFn: fetch,
26
+ logger,
27
+ });
28
+ const endpoint = overwrittenBaseUrl || bundledBaseUrl;
29
+ let operationHeaders = {};
30
+ if (typeof additionalOperationHeaders === 'function') {
31
+ operationHeaders = async (resolverData, operationConfig) => {
32
+ const result = await additionalOperationHeaders(resolverData, {
33
+ endpoint,
34
+ field: operationConfig.field,
35
+ method: 'method' in operationConfig ? operationConfig.method : 'POST',
36
+ path: 'path' in operationConfig ? operationConfig.path : operationConfig.pubsubTopic,
37
+ });
38
+ return {
39
+ ...bundledOperationHeaders,
40
+ ...result,
41
+ };
42
+ };
43
+ }
44
+ else {
45
+ operationHeaders = {
46
+ ...bundledOperationHeaders,
47
+ ...additionalOperationHeaders,
48
+ };
49
+ }
50
+ logger.info(`Creating the GraphQL Schema from dereferenced schema`);
51
+ return getGraphQLSchemaFromDereferencedJSONSchema(name, {
52
+ fullyDeferencedSchema,
53
+ logger,
54
+ endpoint,
55
+ operations,
56
+ operationHeaders,
57
+ queryParams,
58
+ queryStringOptions,
59
+ });
60
+ }