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