sofa-api 0.11.2 → 0.12.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.mjs CHANGED
@@ -1,13 +1,11 @@
1
- import { __awaiter, __asyncValues, __rest } from 'tslib';
2
- import { getOperationAST, Kind, isScalarType, isEqualType, GraphQLBoolean, isInputObjectType, subscribe, isObjectType, isNonNullType, print, graphql, getNamedType, isListType, isEnumType, parse, printType, isIntrospectionType } from 'graphql';
3
- import Trouter from 'trouter';
1
+ import { __awaiter, __asyncValues } from 'tslib';
2
+ import { getOperationAST, Kind, isScalarType, isEqualType, GraphQLBoolean, isInputObjectType, isObjectType, isNonNullType, execute, subscribe, getNamedType, isListType, isEnumType, parse, printType, isIntrospectionType } from 'graphql';
3
+ import { Router } from 'itty-router';
4
4
  import { buildOperationNodeForField } from '@graphql-tools/utils';
5
5
  import { paramCase } from 'param-case';
6
- import { v4 } from 'uuid';
7
- import { fetch } from 'cross-undici-fetch';
6
+ import { crypto, fetch, Response } from '@whatwg-node/fetch';
8
7
  import colors from 'ansi-colors';
9
- import { dump } from 'js-yaml';
10
- import { writeFileSync } from 'fs';
8
+ import { createServerAdapter } from '@whatwg-node/server';
11
9
  import { titleCase } from 'title-case';
12
10
 
13
11
  function getOperationInfo(doc) {
@@ -56,7 +54,7 @@ function resolveVariable({ value, type, schema, }) {
56
54
  return value;
57
55
  }
58
56
  if (type.kind === Kind.LIST_TYPE) {
59
- return (Array.isArray(value) ? value : [value]).map(val => resolveVariable({
57
+ return (Array.isArray(value) ? value : [value]).map((val) => resolveVariable({
60
58
  value: val,
61
59
  type: type.type,
62
60
  schema,
@@ -109,20 +107,17 @@ class SubscriptionManager {
109
107
  }
110
108
  start(event, contextValue) {
111
109
  return __awaiter(this, void 0, void 0, function* () {
112
- const id = v4();
110
+ const id = crypto.randomUUID();
113
111
  const name = event.subscription;
114
112
  if (!this.operations.has(name)) {
115
113
  throw new Error(`Subscription '${name}' is not available`);
116
114
  }
117
- const { document, operationName, variables } = this.operations.get(name);
118
115
  logger.info(`[Subscription] Start ${id}`, event);
119
116
  const result = yield this.execute({
120
117
  id,
121
118
  name,
122
119
  url: event.url,
123
- document,
124
- operationName,
125
- variables,
120
+ variables: event.variables,
126
121
  contextValue,
127
122
  });
128
123
  if (typeof result !== 'undefined') {
@@ -161,9 +156,9 @@ class SubscriptionManager {
161
156
  }, contextValue);
162
157
  });
163
158
  }
164
- execute({ id, document, name, url, operationName, variables, contextValue, }) {
159
+ execute({ id, name, url, variables, contextValue, }) {
165
160
  return __awaiter(this, void 0, void 0, function* () {
166
- const variableNodes = this.operations.get(name).variables;
161
+ const { document, operationName, variables: variableNodes } = this.operations.get(name);
167
162
  const variableValues = variableNodes.reduce((values, variable) => {
168
163
  const value = parseVariable({
169
164
  value: variables[variable.variable.name.value],
@@ -173,9 +168,9 @@ class SubscriptionManager {
173
168
  if (typeof value === 'undefined') {
174
169
  return values;
175
170
  }
176
- return Object.assign(Object.assign({}, values), { [name]: value });
171
+ return Object.assign(Object.assign({}, values), { [variable.variable.name.value]: value });
177
172
  }, {});
178
- const execution = yield subscribe({
173
+ const execution = yield this.sofa.subscribe({
179
174
  schema: this.sofa.schema,
180
175
  document,
181
176
  operationName,
@@ -235,7 +230,7 @@ class SubscriptionManager {
235
230
  body: JSON.stringify(result),
236
231
  headers: {
237
232
  'Content-Type': 'application/json',
238
- }
233
+ },
239
234
  });
240
235
  yield response.text();
241
236
  });
@@ -271,7 +266,9 @@ class SubscriptionManager {
271
266
 
272
267
  function createRouter(sofa) {
273
268
  logger.debug('[Sofa] Creating router');
274
- const router = new Trouter();
269
+ const router = Router({
270
+ base: sofa.basePath,
271
+ });
275
272
  const queryType = sofa.schema.getQueryType();
276
273
  const mutationType = sofa.schema.getMutationType();
277
274
  const subscriptionManager = new SubscriptionManager(sofa);
@@ -291,95 +288,80 @@ function createRouter(sofa) {
291
288
  }
292
289
  });
293
290
  }
294
- router.post('/webhook', ({ body, contextValue }) => __awaiter(this, void 0, void 0, function* () {
295
- const { subscription, variables, url } = body;
291
+ router.post('/webhook', (request, serverContext) => __awaiter(this, void 0, void 0, function* () {
292
+ const { subscription, variables, url } = yield request.json();
296
293
  try {
294
+ const contextValue = yield sofa.contextFactory(serverContext);
297
295
  const result = yield subscriptionManager.start({
298
296
  subscription,
299
297
  variables,
300
298
  url,
301
299
  }, contextValue);
302
- return {
303
- type: 'result',
300
+ return new Response(JSON.stringify(result), {
304
301
  status: 200,
305
- statusMessage: 'OK',
306
- body: result,
307
- };
302
+ statusText: 'OK',
303
+ headers: {
304
+ 'Content-Type': 'application/json',
305
+ },
306
+ });
308
307
  }
309
308
  catch (error) {
310
- return {
311
- type: 'error',
309
+ return new Response(JSON.stringify(error), {
312
310
  status: 500,
313
- statusMessage: 'Subscription failed',
314
- error,
315
- };
311
+ statusText: 'Subscription failed',
312
+ });
316
313
  }
317
314
  }));
318
- router.post('/webhook/:id', ({ body, params, contextValue }) => __awaiter(this, void 0, void 0, function* () {
319
- const id = params.id;
315
+ router.post('/webhook/:id', (request, serverContext) => __awaiter(this, void 0, void 0, function* () {
316
+ var _a;
317
+ const id = (_a = request.params) === null || _a === void 0 ? void 0 : _a.id;
318
+ const body = yield request.json();
320
319
  const variables = body.variables;
321
320
  try {
321
+ const contextValue = yield sofa.contextFactory(serverContext);
322
322
  const result = yield subscriptionManager.update({
323
323
  id,
324
324
  variables,
325
325
  }, contextValue);
326
- return {
327
- type: 'result',
326
+ return new Response(JSON.stringify(result), {
328
327
  status: 200,
329
- statusMessage: 'OK',
330
- body: result,
331
- };
328
+ statusText: 'OK',
329
+ headers: {
330
+ 'Content-Type': 'application/json',
331
+ },
332
+ });
332
333
  }
333
334
  catch (error) {
334
- return {
335
- type: 'error',
335
+ return new Response(JSON.stringify(error), {
336
336
  status: 500,
337
- statusMessage: 'Subscription failed to update',
338
- error,
339
- };
337
+ statusText: 'Subscription failed to update',
338
+ });
340
339
  }
341
340
  }));
342
- router.delete('/webhook/:id', ({ params }) => __awaiter(this, void 0, void 0, function* () {
343
- const id = params.id;
341
+ router.delete('/webhook/:id', (request) => __awaiter(this, void 0, void 0, function* () {
342
+ var _b;
343
+ const id = (_b = request.params) === null || _b === void 0 ? void 0 : _b.id;
344
344
  try {
345
345
  const result = yield subscriptionManager.stop(id);
346
- return {
347
- type: 'result',
346
+ return new Response(JSON.stringify(result), {
348
347
  status: 200,
349
- statusMessage: 'OK',
350
- body: result,
351
- };
348
+ statusText: 'OK',
349
+ headers: {
350
+ 'Content-Type': 'application/json',
351
+ },
352
+ });
352
353
  }
353
354
  catch (error) {
354
- return {
355
- type: 'error',
355
+ return new Response(JSON.stringify(error), {
356
356
  status: 500,
357
- statusMessage: 'Subscription failed to stop',
358
- error,
359
- };
360
- }
361
- }));
362
- return ({ method, url, body, contextValue }) => __awaiter(this, void 0, void 0, function* () {
363
- if (!url.startsWith(sofa.basePath)) {
364
- return null;
365
- }
366
- // trim base path and search
367
- const [slicedUrl] = url.slice(sofa.basePath.length).split('?');
368
- const trouterMethod = method.toUpperCase();
369
- const obj = router.find(trouterMethod, slicedUrl);
370
- for (const handler of obj.handlers) {
371
- return yield handler({
372
- url,
373
- body,
374
- params: obj.params,
375
- contextValue,
357
+ statusText: 'Subscription failed to stop',
376
358
  });
377
359
  }
378
- return null;
379
- });
360
+ }));
361
+ return router;
380
362
  }
381
363
  function createQueryRoute({ sofa, router, fieldName, }) {
382
- var _a, _b, _c, _d;
364
+ var _a, _b, _c, _d, _e, _f;
383
365
  logger.debug(`[Router] Creating ${fieldName} query`);
384
366
  const queryType = sofa.schema.getQueryType();
385
367
  const operationNode = buildOperationNodeForField({
@@ -407,12 +389,14 @@ function createQueryRoute({ sofa, router, fieldName, }) {
407
389
  path: (_c = routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.path) !== null && _c !== void 0 ? _c : getPath(fieldName, isSingle && hasIdArgument),
408
390
  responseStatus: (_d = routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.responseStatus) !== null && _d !== void 0 ? _d : 200,
409
391
  };
410
- router[route.method.toLocaleLowerCase()](route.path, useHandler({ info, route, fieldName, sofa, operation }));
392
+ router[route.method](route.path, useHandler({ info, route, fieldName, sofa, operation }));
411
393
  logger.debug(`[Router] ${fieldName} query available at ${route.method} ${route.path}`);
412
394
  return {
413
395
  document: operation,
414
396
  path: route.path,
415
397
  method: route.method.toUpperCase(),
398
+ tags: (_e = routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.tags) !== null && _e !== void 0 ? _e : [],
399
+ description: (_f = routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.description) !== null && _f !== void 0 ? _f : '',
416
400
  };
417
401
  }
418
402
  function createMutationRoute({ sofa, router, fieldName, }) {
@@ -440,22 +424,37 @@ function createMutationRoute({ sofa, router, fieldName, }) {
440
424
  responseStatus: (_d = routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.responseStatus) !== null && _d !== void 0 ? _d : 200,
441
425
  };
442
426
  const { method, path } = route;
443
- router[method.toLowerCase()](path, useHandler({ info, route, fieldName, sofa, operation }));
427
+ router[method](path, useHandler({ info, route, fieldName, sofa, operation }));
444
428
  logger.debug(`[Router] ${fieldName} mutation available at ${method} ${path}`);
445
429
  return {
446
430
  document: operation,
447
431
  path,
448
432
  method,
433
+ tags: (routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.tags) || [],
434
+ description: (routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.description) || '',
449
435
  };
450
436
  }
451
437
  function useHandler(config) {
452
438
  const { sofa, operation, fieldName } = config;
453
439
  const info = config.info;
454
- return ({ url, body, params, contextValue }) => __awaiter(this, void 0, void 0, function* () {
440
+ return (request, serverContext) => __awaiter(this, void 0, void 0, function* () {
441
+ var _a;
442
+ let body = {};
443
+ if (request.body != null) {
444
+ const strBody = yield request.text();
445
+ if (strBody) {
446
+ body = JSON.parse(strBody);
447
+ }
448
+ }
455
449
  const variableValues = info.variables.reduce((variables, variable) => {
456
450
  const name = variable.variable.name.value;
457
451
  const value = parseVariable({
458
- value: pickParam({ url, body, params, name }),
452
+ value: pickParam({
453
+ url: request.url,
454
+ body,
455
+ params: request.params || {},
456
+ name,
457
+ }),
459
458
  variable,
460
459
  schema: sofa.schema,
461
460
  });
@@ -464,36 +463,36 @@ function useHandler(config) {
464
463
  }
465
464
  return Object.assign(Object.assign({}, variables), { [name]: value });
466
465
  }, {});
466
+ const contextValue = yield sofa.contextFactory(serverContext);
467
467
  const result = yield sofa.execute({
468
468
  schema: sofa.schema,
469
- source: print(operation),
469
+ document: operation,
470
470
  contextValue,
471
471
  variableValues,
472
472
  operationName: info.operation.name && info.operation.name.value,
473
473
  });
474
474
  if (result.errors) {
475
475
  const defaultErrorHandler = (errors) => {
476
- return {
477
- type: 'error',
476
+ return new Response(errors[0], {
478
477
  status: 500,
479
- error: errors[0],
480
- };
478
+ });
481
479
  };
482
480
  const errorHandler = sofa.errorHandler || defaultErrorHandler;
483
481
  return errorHandler(result.errors);
484
482
  }
485
- return {
486
- type: 'result',
483
+ return new Response(JSON.stringify((_a = result.data) === null || _a === void 0 ? void 0 : _a[fieldName]), {
487
484
  status: config.route.responseStatus,
488
- body: result.data && result.data[fieldName],
489
- };
485
+ headers: {
486
+ 'Content-Type': 'application/json',
487
+ },
488
+ });
490
489
  });
491
490
  }
492
491
  function getPath(fieldName, hasId = false) {
493
492
  return `/${convertName(fieldName)}${hasId ? '/:id' : ''}`;
494
493
  }
495
494
  function pickParam({ name, url, params, body, }) {
496
- if (params && params.hasOwnProperty(name)) {
495
+ if (name in params) {
497
496
  return params[name];
498
497
  }
499
498
  const searchParams = new URLSearchParams(url.split('?')[1]);
@@ -513,9 +512,25 @@ function createSofa(config) {
513
512
  const depthLimit = config.depthLimit || 1;
514
513
  logger.debug(`[Sofa] models: ${models.join(', ')}`);
515
514
  logger.debug(`[Sofa] ignore: ${ignore.join(', ')}`);
516
- return Object.assign({ execute: graphql, models,
515
+ return Object.assign({ execute,
516
+ subscribe,
517
+ models,
517
518
  ignore,
518
- depthLimit }, config);
519
+ depthLimit,
520
+ contextFactory(serverContext) {
521
+ if (config.context != null) {
522
+ if (isContextFn(config.context)) {
523
+ return config.context(serverContext);
524
+ }
525
+ else {
526
+ return config.context;
527
+ }
528
+ }
529
+ return serverContext;
530
+ } }, config);
531
+ }
532
+ function isContextFn(context) {
533
+ return typeof context === 'function';
519
534
  }
520
535
  // Objects and Unions are the only things that are used to define return types
521
536
  // and both might contain an ID
@@ -598,7 +613,7 @@ function mapToRef(type) {
598
613
  return `#/components/schemas/${type}`;
599
614
  }
600
615
 
601
- function buildSchemaObjectFromType(type) {
616
+ function buildSchemaObjectFromType(type, opts) {
602
617
  const required = [];
603
618
  const properties = {};
604
619
  const fields = type.getFields();
@@ -607,28 +622,27 @@ function buildSchemaObjectFromType(type) {
607
622
  if (isNonNullType(field.type)) {
608
623
  required.push(field.name);
609
624
  }
610
- properties[fieldName] = resolveField(field);
625
+ properties[fieldName] = resolveField(field, opts);
611
626
  if (field.description) {
612
627
  properties[fieldName].description = field.description;
613
628
  }
614
629
  }
615
630
  return Object.assign(Object.assign(Object.assign({ type: 'object' }, (required.length ? { required } : {})), { properties }), (type.description ? { description: type.description } : {}));
616
631
  }
617
- function resolveField(field) {
618
- return resolveFieldType(field.type);
632
+ function resolveField(field, opts) {
633
+ return resolveFieldType(field.type, opts);
619
634
  }
620
635
  // array -> [type]
621
636
  // type -> $ref
622
637
  // scalar -> swagger primitive
623
- function resolveFieldType(type) {
624
- var _a, _b;
638
+ function resolveFieldType(type, opts) {
625
639
  if (isNonNullType(type)) {
626
- return resolveFieldType(type.ofType);
640
+ return resolveFieldType(type.ofType, opts);
627
641
  }
628
642
  if (isListType(type)) {
629
643
  return {
630
644
  type: 'array',
631
- items: resolveFieldType(type.ofType),
645
+ items: resolveFieldType(type.ofType, opts),
632
646
  };
633
647
  }
634
648
  if (isObjectType(type)) {
@@ -637,14 +651,15 @@ function resolveFieldType(type) {
637
651
  };
638
652
  }
639
653
  if (isScalarType(type)) {
640
- return (mapToPrimitive(type.name) || {
654
+ return (mapToPrimitive(type.name) ||
655
+ opts.customScalars[type.name] || {
641
656
  type: 'object',
642
657
  });
643
658
  }
644
659
  if (isEnumType(type)) {
645
660
  return {
646
661
  type: 'string',
647
- enum: (_b = (_a = type.astNode) === null || _a === void 0 ? void 0 : _a.values) === null || _b === void 0 ? void 0 : _b.map((value) => value.name.value),
662
+ enum: type.getValues().map((value) => value.name),
648
663
  };
649
664
  }
650
665
  return {
@@ -652,10 +667,12 @@ function resolveFieldType(type) {
652
667
  };
653
668
  }
654
669
 
655
- function buildPathFromOperation({ url, schema, operation, useRequestBody, }) {
670
+ function buildPathFromOperation({ url, schema, operation, useRequestBody, tags, description, customScalars, }) {
656
671
  const info = getOperationInfo(operation);
657
- const description = resolveDescription(schema, info.operation);
658
- return Object.assign(Object.assign({ operationId: info.name }, (useRequestBody
672
+ const summary = resolveSummary(schema, info.operation);
673
+ return Object.assign(Object.assign({ tags,
674
+ description,
675
+ summary, operationId: info.name }, (useRequestBody
659
676
  ? {
660
677
  requestBody: {
661
678
  content: {
@@ -669,12 +686,13 @@ function buildPathFromOperation({ url, schema, operation, useRequestBody, }) {
669
686
  parameters: resolveParameters(url, info.operation.variableDefinitions),
670
687
  })), { responses: {
671
688
  200: {
672
- description,
689
+ description: summary,
673
690
  content: {
674
691
  'application/json': {
675
692
  schema: resolveResponse({
676
693
  schema,
677
694
  operation: info.operation,
695
+ customScalars,
678
696
  }),
679
697
  },
680
698
  },
@@ -700,7 +718,7 @@ function resolveRequestBody(variables) {
700
718
  }
701
719
  const properties = {};
702
720
  const required = [];
703
- variables.forEach(variable => {
721
+ variables.forEach((variable) => {
704
722
  if (variable.type.kind === Kind.NON_NULL_TYPE) {
705
723
  required.push(variable.variable.name.value);
706
724
  }
@@ -726,26 +744,26 @@ function resolveParamSchema(type) {
726
744
  $ref: mapToRef(type.name.value),
727
745
  });
728
746
  }
729
- function resolveResponse({ schema, operation, }) {
747
+ function resolveResponse({ schema, operation, customScalars, }) {
730
748
  const operationType = operation.operation;
731
749
  const rootField = operation.selectionSet.selections[0];
732
750
  if (rootField.kind === Kind.FIELD) {
733
751
  if (operationType === 'query') {
734
752
  const queryType = schema.getQueryType();
735
753
  const field = queryType.getFields()[rootField.name.value];
736
- return resolveFieldType(field.type);
754
+ return resolveFieldType(field.type, { customScalars });
737
755
  }
738
756
  if (operationType === 'mutation') {
739
757
  const mutationType = schema.getMutationType();
740
758
  const field = mutationType.getFields()[rootField.name.value];
741
- return resolveFieldType(field.type);
759
+ return resolveFieldType(field.type, { customScalars });
742
760
  }
743
761
  }
744
762
  }
745
763
  function isInPath(url, param) {
746
764
  return url.indexOf(`{${param}}`) !== -1;
747
765
  }
748
- function resolveDescription(schema, operation) {
766
+ function resolveSummary(schema, operation) {
749
767
  const selection = operation.selectionSet.selections[0];
750
768
  const fieldName = selection.name.value;
751
769
  const typeDefinition = schema.getType(titleCase(operation.operation));
@@ -756,7 +774,7 @@ function resolveDescription(schema, operation) {
756
774
  if (!isObjectTypeDefinitionNode(definitionNode)) {
757
775
  return '';
758
776
  }
759
- const fieldNode = definitionNode.fields.find(field => field.name.value === fieldName);
777
+ const fieldNode = definitionNode.fields.find((field) => field.name.value === fieldName);
760
778
  const descriptionDefinition = fieldNode && fieldNode.description;
761
779
  return descriptionDefinition && descriptionDefinition.value
762
780
  ? descriptionDefinition.value
@@ -766,13 +784,13 @@ function isObjectTypeDefinitionNode(node) {
766
784
  return node.kind === Kind.OBJECT_TYPE_DEFINITION;
767
785
  }
768
786
 
769
- function OpenAPI({ schema, info, servers, components, security, tags, }) {
787
+ function OpenAPI({ schema, info, servers, components, security, tags, customScalars = {}, }) {
770
788
  const types = schema.getTypeMap();
771
789
  const swagger = {
772
790
  openapi: '3.0.0',
773
791
  info,
774
792
  servers,
775
- tags,
793
+ tags: [],
776
794
  paths: {},
777
795
  components: {
778
796
  schemas: {},
@@ -782,7 +800,9 @@ function OpenAPI({ schema, info, servers, components, security, tags, }) {
782
800
  const type = types[typeName];
783
801
  if ((isObjectType(type) || isInputObjectType(type)) &&
784
802
  !isIntrospectionType(type)) {
785
- swagger.components.schemas[typeName] = buildSchemaObjectFromType(type);
803
+ swagger.components.schemas[typeName] = buildSchemaObjectFromType(type, {
804
+ customScalars,
805
+ });
786
806
  }
787
807
  }
788
808
  if (components) {
@@ -791,6 +811,9 @@ function OpenAPI({ schema, info, servers, components, security, tags, }) {
791
811
  if (security) {
792
812
  swagger.security = security;
793
813
  }
814
+ if (tags) {
815
+ swagger.tags = tags;
816
+ }
794
817
  return {
795
818
  addRoute(info, config) {
796
819
  const basePath = (config === null || config === void 0 ? void 0 : config.basePath) || '';
@@ -799,91 +822,25 @@ function OpenAPI({ schema, info, servers, components, security, tags, }) {
799
822
  if (!swagger.paths[path]) {
800
823
  swagger.paths[path] = {};
801
824
  }
802
- swagger.paths[path][info.method.toLowerCase()] = buildPathFromOperation({
825
+ const pathsObj = swagger.paths[path];
826
+ pathsObj[info.method.toLowerCase()] = buildPathFromOperation({
803
827
  url: path,
804
828
  operation: info.document,
805
829
  schema,
806
830
  useRequestBody: ['POST', 'PUT', 'PATCH'].includes(info.method),
831
+ tags: info.tags || [],
832
+ description: info.description || '',
833
+ customScalars,
807
834
  });
808
835
  },
809
836
  get() {
810
837
  return swagger;
811
838
  },
812
- save(filepath) {
813
- const isJSON = /\.json$/i;
814
- const isYAML = /.ya?ml$/i;
815
- if (isJSON.test(filepath)) {
816
- writeOutput(filepath, JSON.stringify(swagger, null, 2));
817
- }
818
- else if (isYAML.test(filepath)) {
819
- writeOutput(filepath, dump(swagger));
820
- }
821
- else {
822
- throw new Error('We only support JSON and YAML files');
823
- }
824
- },
825
839
  };
826
- }
827
- function writeOutput(filepath, contents) {
828
- writeFileSync(filepath, contents, {
829
- encoding: 'utf-8',
830
- });
831
840
  }
832
841
 
833
- function isContextFn(context) {
834
- return typeof context === 'function';
835
- }
836
- function useSofa(_a) {
837
- var { context } = _a, config = __rest(_a, ["context"]);
838
- const invokeSofa = createSofaRouter(config);
839
- return (req, res, next) => __awaiter(this, void 0, void 0, function* () {
840
- var _b;
841
- try {
842
- let contextValue = { req };
843
- if (context) {
844
- if (typeof context === 'function') {
845
- contextValue = yield context({ req, res });
846
- }
847
- else {
848
- contextValue = context;
849
- }
850
- }
851
- const response = yield invokeSofa({
852
- method: req.method,
853
- url: (_b = req.originalUrl) !== null && _b !== void 0 ? _b : req.url,
854
- body: req.body,
855
- contextValue,
856
- });
857
- if (response == null) {
858
- next();
859
- }
860
- else {
861
- const headers = {
862
- 'Content-Type': 'application/json',
863
- };
864
- if (response.statusMessage) {
865
- res.writeHead(response.status, response.statusMessage, headers);
866
- }
867
- else {
868
- res.writeHead(response.status, headers);
869
- }
870
- if (response.type === 'result') {
871
- res.end(JSON.stringify(response.body));
872
- }
873
- if (response.type === 'error') {
874
- res.end(JSON.stringify(response.error));
875
- }
876
- }
877
- }
878
- catch (error) {
879
- next(error);
880
- }
881
- });
882
- }
883
- function createSofaRouter(config) {
884
- const sofa = createSofa(config);
885
- const router = createRouter(sofa);
886
- return router;
842
+ function useSofa(config) {
843
+ return createServerAdapter(createRouter(createSofa(config)));
887
844
  }
888
845
 
889
- export { OpenAPI, createSofaRouter, isContextFn, useSofa };
846
+ export { OpenAPI, useSofa };
@@ -1,16 +1,26 @@
1
1
  import { GraphQLSchema } from 'graphql';
2
2
  import { RouteInfo } from '../types';
3
- export declare function OpenAPI({ schema, info, servers, components, security, tags, }: {
3
+ import { OpenAPIV3 } from 'openapi-types';
4
+ export declare function OpenAPI({ schema, info, servers, components, security, tags, customScalars, }: {
4
5
  schema: GraphQLSchema;
5
- info: Record<string, any>;
6
- servers?: Record<string, any>[];
6
+ info: OpenAPIV3.InfoObject;
7
+ servers?: OpenAPIV3.ServerObject[];
7
8
  components?: Record<string, any>;
8
- security?: Record<string, any>[];
9
- tags?: Record<string, any>[];
9
+ security?: OpenAPIV3.SecurityRequirementObject[];
10
+ tags?: OpenAPIV3.TagObject[];
11
+ /**
12
+ * Override mapping of custom scalars to OpenAPI
13
+ * @example
14
+ * ```js
15
+ * {
16
+ * Date: { type: "string", format: "date" }
17
+ * }
18
+ * ```
19
+ */
20
+ customScalars?: Record<string, any>;
10
21
  }): {
11
22
  addRoute(info: RouteInfo, config?: {
12
- basePath?: string | undefined;
13
- } | undefined): void;
14
- get(): any;
15
- save(filepath: string): void;
23
+ basePath?: string;
24
+ }): void;
25
+ get(): OpenAPIV3.Document<{}>;
16
26
  };
@@ -1,7 +1,11 @@
1
1
  import { DocumentNode, GraphQLSchema } from 'graphql';
2
- export declare function buildPathFromOperation({ url, schema, operation, useRequestBody, }: {
2
+ import { OpenAPIV3 } from 'openapi-types';
3
+ export declare function buildPathFromOperation({ url, schema, operation, useRequestBody, tags, description, customScalars, }: {
3
4
  url: string;
4
5
  schema: GraphQLSchema;
5
6
  operation: DocumentNode;
6
7
  useRequestBody: boolean;
7
- }): any;
8
+ tags?: string[];
9
+ description?: string;
10
+ customScalars: Record<string, any>;
11
+ }): OpenAPIV3.OperationObject;