sofa-api 0.12.0 → 0.14.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/README.md CHANGED
@@ -150,7 +150,7 @@ Sofa allows you to cutomize the http method, path and response status. For examp
150
150
  ```typescript
151
151
  api.use(
152
152
  '/api',
153
- sofa({
153
+ useSofa({
154
154
  schema,
155
155
  routes: {
156
156
  'Query.feed': { method: 'POST' },
@@ -341,7 +341,7 @@ app.use(
341
341
  writeFileSync('./swagger.json', JSON.stringify(openApi.get(), null, 2));
342
342
  ```
343
343
 
344
- OpenAPI (Swagger) with custom tags, summary and description
344
+ OpenAPI (Swagger) with custom tags, summary and description
345
345
 
346
346
  ```ts
347
347
  const openApi = OpenAPI({
package/index.js CHANGED
@@ -297,12 +297,11 @@ function createRouter(sofa) {
297
297
  router.post('/webhook', (request, serverContext) => tslib.__awaiter(this, void 0, void 0, function* () {
298
298
  const { subscription, variables, url } = yield request.json();
299
299
  try {
300
- const contextValue = yield sofa.contextFactory(serverContext);
301
300
  const result = yield subscriptionManager.start({
302
301
  subscription,
303
302
  variables,
304
303
  url,
305
- }, contextValue);
304
+ }, Object.assign(Object.assign({}, serverContext), { request }));
306
305
  return new fetch.Response(JSON.stringify(result), {
307
306
  status: 200,
308
307
  statusText: 'OK',
@@ -324,7 +323,8 @@ function createRouter(sofa) {
324
323
  const body = yield request.json();
325
324
  const variables = body.variables;
326
325
  try {
327
- const contextValue = yield sofa.contextFactory(serverContext);
326
+ const sofaServerContext = Object.assign(Object.assign({}, serverContext), { request });
327
+ const contextValue = yield sofa.contextFactory(sofaServerContext);
328
328
  const result = yield subscriptionManager.update({
329
329
  id,
330
330
  variables,
@@ -367,7 +367,7 @@ function createRouter(sofa) {
367
367
  return router;
368
368
  }
369
369
  function createQueryRoute({ sofa, router, fieldName, }) {
370
- var _a, _b, _c, _d, _e, _f;
370
+ var _a, _b, _c, _d, _e, _f, _g;
371
371
  logger.debug(`[Router] Creating ${fieldName} query`);
372
372
  const queryType = sofa.schema.getQueryType();
373
373
  const operationNode = utils.buildOperationNodeForField({
@@ -402,13 +402,14 @@ function createQueryRoute({ sofa, router, fieldName, }) {
402
402
  path: route.path,
403
403
  method: route.method.toUpperCase(),
404
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 : '',
405
+ description: (_g = (_f = routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.description) !== null && _f !== void 0 ? _f : field.description) !== null && _g !== void 0 ? _g : '',
406
406
  };
407
407
  }
408
408
  function createMutationRoute({ sofa, router, fieldName, }) {
409
- var _a, _b, _c, _d;
409
+ var _a, _b, _c, _d, _e, _f;
410
410
  logger.debug(`[Router] Creating ${fieldName} mutation`);
411
411
  const mutationType = sofa.schema.getMutationType();
412
+ const field = mutationType.getFields()[fieldName];
412
413
  const operationNode = utils.buildOperationNodeForField({
413
414
  kind: 'mutation',
414
415
  schema: sofa.schema,
@@ -437,7 +438,7 @@ function createMutationRoute({ sofa, router, fieldName, }) {
437
438
  path,
438
439
  method,
439
440
  tags: (routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.tags) || [],
440
- description: (routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.description) || '',
441
+ description: (_f = (_e = routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.description) !== null && _e !== void 0 ? _e : field.description) !== null && _f !== void 0 ? _f : '',
441
442
  };
442
443
  }
443
444
  function useHandler(config) {
@@ -469,7 +470,8 @@ function useHandler(config) {
469
470
  }
470
471
  return Object.assign(Object.assign({}, variables), { [name]: value });
471
472
  }, {});
472
- const contextValue = yield sofa.contextFactory(serverContext);
473
+ const sofaServerContext = Object.assign(Object.assign({}, serverContext), { request });
474
+ const contextValue = yield sofa.contextFactory(sofaServerContext);
473
475
  const result = yield sofa.execute({
474
476
  schema: sofa.schema,
475
477
  document: operation,
@@ -479,8 +481,9 @@ function useHandler(config) {
479
481
  });
480
482
  if (result.errors) {
481
483
  const defaultErrorHandler = (errors) => {
482
- return new fetch.Response(errors[0], {
484
+ return new fetch.Response(JSON.stringify(errors[0]), {
483
485
  status: 500,
486
+ headers: { 'Content-Type': 'application/json' },
484
487
  });
485
488
  };
486
489
  const errorHandler = sofa.errorHandler || defaultErrorHandler;
@@ -642,6 +645,7 @@ function resolveField(field, opts) {
642
645
  // type -> $ref
643
646
  // scalar -> swagger primitive
644
647
  function resolveFieldType(type, opts) {
648
+ var _a;
645
649
  if (graphql.isNonNullType(type)) {
646
650
  return resolveFieldType(type.ofType, opts);
647
651
  }
@@ -658,9 +662,11 @@ function resolveFieldType(type, opts) {
658
662
  }
659
663
  if (graphql.isScalarType(type)) {
660
664
  return (mapToPrimitive(type.name) ||
661
- opts.customScalars[type.name] || {
662
- type: 'object',
663
- });
665
+ opts.customScalars[type.name] ||
666
+ ((_a = type.extensions) === null || _a === void 0 ? void 0 : _a.jsonSchema)
667
+ || {
668
+ type: 'object',
669
+ });
664
670
  }
665
671
  if (graphql.isEnumType(type)) {
666
672
  return {
@@ -683,13 +689,15 @@ function buildPathFromOperation({ url, schema, operation, useRequestBody, tags,
683
689
  requestBody: {
684
690
  content: {
685
691
  'application/json': {
686
- schema: resolveRequestBody(info.operation.variableDefinitions),
692
+ schema: resolveRequestBody(info.operation.variableDefinitions, {
693
+ customScalars,
694
+ }),
687
695
  },
688
696
  },
689
697
  },
690
698
  }
691
699
  : {
692
- parameters: resolveParameters(url, info.operation.variableDefinitions),
700
+ parameters: resolveParameters(url, info.operation.variableDefinitions, { customScalars }),
693
701
  })), { responses: {
694
702
  200: {
695
703
  description: summary,
@@ -705,7 +713,7 @@ function buildPathFromOperation({ url, schema, operation, useRequestBody, tags,
705
713
  },
706
714
  } });
707
715
  }
708
- function resolveParameters(url, variables) {
716
+ function resolveParameters(url, variables, opts) {
709
717
  if (!variables) {
710
718
  return [];
711
719
  }
@@ -714,11 +722,11 @@ function resolveParameters(url, variables) {
714
722
  in: isInPath(url, variable.variable.name.value) ? 'path' : 'query',
715
723
  name: variable.variable.name.value,
716
724
  required: variable.type.kind === graphql.Kind.NON_NULL_TYPE,
717
- schema: resolveParamSchema(variable.type),
725
+ schema: resolveParamSchema(variable.type, opts),
718
726
  };
719
727
  });
720
728
  }
721
- function resolveRequestBody(variables) {
729
+ function resolveRequestBody(variables, opts) {
722
730
  if (!variables) {
723
731
  return {};
724
732
  }
@@ -728,25 +736,26 @@ function resolveRequestBody(variables) {
728
736
  if (variable.type.kind === graphql.Kind.NON_NULL_TYPE) {
729
737
  required.push(variable.variable.name.value);
730
738
  }
731
- properties[variable.variable.name.value] = resolveParamSchema(variable.type);
739
+ properties[variable.variable.name.value] = resolveParamSchema(variable.type, opts);
732
740
  });
733
741
  return Object.assign({ type: 'object', properties }, (required.length ? { required } : {}));
734
742
  }
735
743
  // array -> [type]
736
744
  // type -> $ref
737
745
  // scalar -> swagger primitive
738
- function resolveParamSchema(type) {
746
+ function resolveParamSchema(type, opts) {
739
747
  if (type.kind === graphql.Kind.NON_NULL_TYPE) {
740
- return resolveParamSchema(type.type);
748
+ return resolveParamSchema(type.type, opts);
741
749
  }
742
750
  if (type.kind === graphql.Kind.LIST_TYPE) {
743
751
  return {
744
752
  type: 'array',
745
- items: resolveParamSchema(type.type),
753
+ items: resolveParamSchema(type.type, opts),
746
754
  };
747
755
  }
748
756
  const primitive = mapToPrimitive(type.name.value);
749
- return (primitive || {
757
+ return (primitive ||
758
+ opts.customScalars[type.name.value] || {
750
759
  $ref: mapToRef(type.name.value),
751
760
  });
752
761
  }
package/index.mjs CHANGED
@@ -291,12 +291,11 @@ function createRouter(sofa) {
291
291
  router.post('/webhook', (request, serverContext) => __awaiter(this, void 0, void 0, function* () {
292
292
  const { subscription, variables, url } = yield request.json();
293
293
  try {
294
- const contextValue = yield sofa.contextFactory(serverContext);
295
294
  const result = yield subscriptionManager.start({
296
295
  subscription,
297
296
  variables,
298
297
  url,
299
- }, contextValue);
298
+ }, Object.assign(Object.assign({}, serverContext), { request }));
300
299
  return new Response(JSON.stringify(result), {
301
300
  status: 200,
302
301
  statusText: 'OK',
@@ -318,7 +317,8 @@ function createRouter(sofa) {
318
317
  const body = yield request.json();
319
318
  const variables = body.variables;
320
319
  try {
321
- const contextValue = yield sofa.contextFactory(serverContext);
320
+ const sofaServerContext = Object.assign(Object.assign({}, serverContext), { request });
321
+ const contextValue = yield sofa.contextFactory(sofaServerContext);
322
322
  const result = yield subscriptionManager.update({
323
323
  id,
324
324
  variables,
@@ -361,7 +361,7 @@ function createRouter(sofa) {
361
361
  return router;
362
362
  }
363
363
  function createQueryRoute({ sofa, router, fieldName, }) {
364
- var _a, _b, _c, _d, _e, _f;
364
+ var _a, _b, _c, _d, _e, _f, _g;
365
365
  logger.debug(`[Router] Creating ${fieldName} query`);
366
366
  const queryType = sofa.schema.getQueryType();
367
367
  const operationNode = buildOperationNodeForField({
@@ -396,13 +396,14 @@ function createQueryRoute({ sofa, router, fieldName, }) {
396
396
  path: route.path,
397
397
  method: route.method.toUpperCase(),
398
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 : '',
399
+ description: (_g = (_f = routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.description) !== null && _f !== void 0 ? _f : field.description) !== null && _g !== void 0 ? _g : '',
400
400
  };
401
401
  }
402
402
  function createMutationRoute({ sofa, router, fieldName, }) {
403
- var _a, _b, _c, _d;
403
+ var _a, _b, _c, _d, _e, _f;
404
404
  logger.debug(`[Router] Creating ${fieldName} mutation`);
405
405
  const mutationType = sofa.schema.getMutationType();
406
+ const field = mutationType.getFields()[fieldName];
406
407
  const operationNode = buildOperationNodeForField({
407
408
  kind: 'mutation',
408
409
  schema: sofa.schema,
@@ -431,7 +432,7 @@ function createMutationRoute({ sofa, router, fieldName, }) {
431
432
  path,
432
433
  method,
433
434
  tags: (routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.tags) || [],
434
- description: (routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.description) || '',
435
+ description: (_f = (_e = routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.description) !== null && _e !== void 0 ? _e : field.description) !== null && _f !== void 0 ? _f : '',
435
436
  };
436
437
  }
437
438
  function useHandler(config) {
@@ -463,7 +464,8 @@ function useHandler(config) {
463
464
  }
464
465
  return Object.assign(Object.assign({}, variables), { [name]: value });
465
466
  }, {});
466
- const contextValue = yield sofa.contextFactory(serverContext);
467
+ const sofaServerContext = Object.assign(Object.assign({}, serverContext), { request });
468
+ const contextValue = yield sofa.contextFactory(sofaServerContext);
467
469
  const result = yield sofa.execute({
468
470
  schema: sofa.schema,
469
471
  document: operation,
@@ -473,8 +475,9 @@ function useHandler(config) {
473
475
  });
474
476
  if (result.errors) {
475
477
  const defaultErrorHandler = (errors) => {
476
- return new Response(errors[0], {
478
+ return new Response(JSON.stringify(errors[0]), {
477
479
  status: 500,
480
+ headers: { 'Content-Type': 'application/json' },
478
481
  });
479
482
  };
480
483
  const errorHandler = sofa.errorHandler || defaultErrorHandler;
@@ -636,6 +639,7 @@ function resolveField(field, opts) {
636
639
  // type -> $ref
637
640
  // scalar -> swagger primitive
638
641
  function resolveFieldType(type, opts) {
642
+ var _a;
639
643
  if (isNonNullType(type)) {
640
644
  return resolveFieldType(type.ofType, opts);
641
645
  }
@@ -652,9 +656,11 @@ function resolveFieldType(type, opts) {
652
656
  }
653
657
  if (isScalarType(type)) {
654
658
  return (mapToPrimitive(type.name) ||
655
- opts.customScalars[type.name] || {
656
- type: 'object',
657
- });
659
+ opts.customScalars[type.name] ||
660
+ ((_a = type.extensions) === null || _a === void 0 ? void 0 : _a.jsonSchema)
661
+ || {
662
+ type: 'object',
663
+ });
658
664
  }
659
665
  if (isEnumType(type)) {
660
666
  return {
@@ -677,13 +683,15 @@ function buildPathFromOperation({ url, schema, operation, useRequestBody, tags,
677
683
  requestBody: {
678
684
  content: {
679
685
  'application/json': {
680
- schema: resolveRequestBody(info.operation.variableDefinitions),
686
+ schema: resolveRequestBody(info.operation.variableDefinitions, {
687
+ customScalars,
688
+ }),
681
689
  },
682
690
  },
683
691
  },
684
692
  }
685
693
  : {
686
- parameters: resolveParameters(url, info.operation.variableDefinitions),
694
+ parameters: resolveParameters(url, info.operation.variableDefinitions, { customScalars }),
687
695
  })), { responses: {
688
696
  200: {
689
697
  description: summary,
@@ -699,7 +707,7 @@ function buildPathFromOperation({ url, schema, operation, useRequestBody, tags,
699
707
  },
700
708
  } });
701
709
  }
702
- function resolveParameters(url, variables) {
710
+ function resolveParameters(url, variables, opts) {
703
711
  if (!variables) {
704
712
  return [];
705
713
  }
@@ -708,11 +716,11 @@ function resolveParameters(url, variables) {
708
716
  in: isInPath(url, variable.variable.name.value) ? 'path' : 'query',
709
717
  name: variable.variable.name.value,
710
718
  required: variable.type.kind === Kind.NON_NULL_TYPE,
711
- schema: resolveParamSchema(variable.type),
719
+ schema: resolveParamSchema(variable.type, opts),
712
720
  };
713
721
  });
714
722
  }
715
- function resolveRequestBody(variables) {
723
+ function resolveRequestBody(variables, opts) {
716
724
  if (!variables) {
717
725
  return {};
718
726
  }
@@ -722,25 +730,26 @@ function resolveRequestBody(variables) {
722
730
  if (variable.type.kind === Kind.NON_NULL_TYPE) {
723
731
  required.push(variable.variable.name.value);
724
732
  }
725
- properties[variable.variable.name.value] = resolveParamSchema(variable.type);
733
+ properties[variable.variable.name.value] = resolveParamSchema(variable.type, opts);
726
734
  });
727
735
  return Object.assign({ type: 'object', properties }, (required.length ? { required } : {}));
728
736
  }
729
737
  // array -> [type]
730
738
  // type -> $ref
731
739
  // scalar -> swagger primitive
732
- function resolveParamSchema(type) {
740
+ function resolveParamSchema(type, opts) {
733
741
  if (type.kind === Kind.NON_NULL_TYPE) {
734
- return resolveParamSchema(type.type);
742
+ return resolveParamSchema(type.type, opts);
735
743
  }
736
744
  if (type.kind === Kind.LIST_TYPE) {
737
745
  return {
738
746
  type: 'array',
739
- items: resolveParamSchema(type.type),
747
+ items: resolveParamSchema(type.type, opts),
740
748
  };
741
749
  }
742
750
  const primitive = mapToPrimitive(type.name.value);
743
- return (primitive || {
751
+ return (primitive ||
752
+ opts.customScalars[type.name.value] || {
744
753
  $ref: mapToRef(type.name.value),
745
754
  });
746
755
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sofa-api",
3
- "version": "0.12.0",
3
+ "version": "0.14.0",
4
4
  "description": "Create REST APIs with GraphQL",
5
5
  "sideEffects": false,
6
6
  "peerDependencies": {
@@ -8,9 +8,9 @@
8
8
  },
9
9
  "dependencies": {
10
10
  "@graphql-tools/utils": "8.12.0",
11
- "ansi-colors": "4.1.3",
12
11
  "@whatwg-node/fetch": "^0.4.3",
13
12
  "@whatwg-node/server": "^0.4.1",
13
+ "ansi-colors": "4.1.3",
14
14
  "itty-router": "^2.6.1",
15
15
  "openapi-types": "12.0.2",
16
16
  "param-case": "3.0.4",
package/types.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { DefaultServerAdapterContext } from '@whatwg-node/server';
1
2
  import { DocumentNode } from 'graphql';
2
3
  export declare type ContextValue = Record<string, any>;
3
4
  export declare type Ignore = string[];
@@ -10,7 +11,7 @@ export interface RouteInfo {
10
11
  description?: string;
11
12
  }
12
13
  export declare type OnRoute = (info: RouteInfo) => void;
13
- export declare type ContextFn = (init: {
14
- req: any;
15
- res: any;
16
- }) => Promise<ContextValue> | ContextValue;
14
+ export declare type ContextFn = (serverContext: DefaultSofaServerContext) => Promise<ContextValue> | ContextValue;
15
+ export declare type DefaultSofaServerContext = DefaultServerAdapterContext & {
16
+ request: Request;
17
+ };