sofa-api 0.15.5 → 0.16.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.
Files changed (3) hide show
  1. package/index.js +97 -72
  2. package/index.mjs +98 -73
  3. package/package.json +3 -3
package/index.js CHANGED
@@ -73,12 +73,12 @@ function resolveVariable({ value, type, schema, }) {
73
73
  }
74
74
  }
75
75
 
76
- var _a;
76
+ var _a, _b;
77
77
  const levels = ['error', 'warn', 'info', 'debug'];
78
78
  const toLevel = (string) => levels.includes(string) ? string : null;
79
- const currentLevel = process.env.SOFA_DEBUG
79
+ const currentLevel = ((_a = globalThis.process) === null || _a === void 0 ? void 0 : _a.env.SOFA_DEBUG)
80
80
  ? 'debug'
81
- : (_a = toLevel(process.env.SOFA_LOGGER_LEVEL)) !== null && _a !== void 0 ? _a : 'info';
81
+ : (_b = toLevel(process.env.SOFA_LOGGER_LEVEL)) !== null && _b !== void 0 ? _b : 'info';
82
82
  const log = (level, color, args) => {
83
83
  if (levels.indexOf(level) <= levels.indexOf(currentLevel)) {
84
84
  console.log(`${color(level)}:`, ...args);
@@ -275,6 +275,34 @@ class SubscriptionManager {
275
275
  }
276
276
  }
277
277
 
278
+ const defaultErrorHandler = (errors) => {
279
+ var _a;
280
+ let status;
281
+ const headers = {
282
+ 'Content-Type': 'application/json; charset=utf-8',
283
+ };
284
+ for (const error of errors) {
285
+ if (typeof error === 'object' &&
286
+ error != null &&
287
+ ((_a = error.extensions) === null || _a === void 0 ? void 0 : _a.http)) {
288
+ if (error.extensions.http.status &&
289
+ (!status || error.extensions.http.status > status)) {
290
+ status = error.extensions.http.status;
291
+ }
292
+ if (error.extensions.http.headers) {
293
+ Object.assign(headers, error.extensions.http.headers);
294
+ }
295
+ delete error.extensions.http;
296
+ }
297
+ }
298
+ if (!status) {
299
+ status = 500;
300
+ }
301
+ return new router.Response(JSON.stringify({ errors }), {
302
+ status,
303
+ headers,
304
+ });
305
+ };
278
306
  function createRouter(sofa) {
279
307
  logger.debug('[Sofa] Creating router');
280
308
  const router$1 = router.createRouter({
@@ -451,82 +479,79 @@ function createMutationRoute({ sofa, router, fieldName, }) {
451
479
  function useHandler(config) {
452
480
  const { sofa, operation, fieldName } = config;
453
481
  const info = config.info;
482
+ const errorHandler = sofa.errorHandler || defaultErrorHandler;
454
483
  return (request, serverContext) => tslib.__awaiter(this, void 0, void 0, function* () {
455
- var _a;
456
- let body = {};
457
- if (request.body != null) {
458
- const strBody = yield request.text();
459
- if (strBody) {
460
- body = JSON.parse(strBody);
484
+ var _a, _b;
485
+ try {
486
+ let body = {};
487
+ if (request.body != null) {
488
+ const strBody = yield request.text();
489
+ if (strBody) {
490
+ try {
491
+ body = JSON.parse(strBody);
492
+ }
493
+ catch (error) {
494
+ throw utils.createGraphQLError('POST body sent invalid JSON.', {
495
+ extensions: {
496
+ http: {
497
+ status: 400,
498
+ }
499
+ }
500
+ });
501
+ }
502
+ }
461
503
  }
462
- }
463
- const variableValues = info.variables.reduce((variables, variable) => {
464
- const name = variable.variable.name.value;
465
- const value = parseVariable({
466
- value: pickParam({
467
- url: request.url,
468
- body,
469
- params: request.params || {},
470
- name,
471
- }),
472
- variable,
473
- schema: sofa.schema,
474
- });
475
- if (typeof value === 'undefined') {
476
- return variables;
504
+ let variableValues = {};
505
+ try {
506
+ variableValues = info.variables.reduce((variables, variable) => {
507
+ const name = variable.variable.name.value;
508
+ const value = parseVariable({
509
+ value: pickParam({
510
+ url: request.url,
511
+ body,
512
+ params: request.params || {},
513
+ name,
514
+ }),
515
+ variable,
516
+ schema: sofa.schema,
517
+ });
518
+ if (typeof value === 'undefined') {
519
+ return variables;
520
+ }
521
+ return Object.assign(Object.assign({}, variables), { [name]: value });
522
+ }, {});
477
523
  }
478
- return Object.assign(Object.assign({}, variables), { [name]: value });
479
- }, {});
480
- const sofaServerContext = Object.assign(Object.assign({}, serverContext), { request });
481
- const contextValue = yield sofa.contextFactory(sofaServerContext);
482
- const result = yield sofa.execute({
483
- schema: sofa.schema,
484
- document: operation,
485
- contextValue,
486
- variableValues,
487
- operationName: info.operation.name && info.operation.name.value,
488
- });
489
- if (result.errors) {
490
- const defaultErrorHandler = (errors) => {
491
- var _a;
492
- let status;
493
- const headers = {
494
- 'Content-Type': 'application/json; charset=utf-8',
495
- };
496
- for (const error of errors) {
497
- if (typeof error === 'object' && error != null && ((_a = error.extensions) === null || _a === void 0 ? void 0 : _a.http)) {
498
- if (error.extensions.http.status &&
499
- (!status || error.extensions.http.status > status)) {
500
- status = error.extensions.http.status;
501
- }
502
- if (error.extensions.http.headers) {
503
- Object.assign(headers, error.extensions.http.headers);
524
+ catch (error) {
525
+ throw utils.createGraphQLError(error.message || ((_a = error.toString) === null || _a === void 0 ? void 0 : _a.call(error)) || error, {
526
+ extensions: {
527
+ http: {
528
+ status: 400,
504
529
  }
505
530
  }
506
- }
507
- if (!status) {
508
- status = 500;
509
- }
510
- if (errors.length === 1) {
511
- return new router.Response(JSON.stringify(errors[0]), {
512
- status,
513
- headers,
514
- });
515
- }
516
- return new router.Response(JSON.stringify({ errors }), {
517
- status,
518
- headers,
519
531
  });
520
- };
521
- const errorHandler = sofa.errorHandler || defaultErrorHandler;
522
- return errorHandler(result.errors);
532
+ }
533
+ const sofaServerContext = Object.assign(Object.assign({}, serverContext), { request });
534
+ const contextValue = yield sofa.contextFactory(sofaServerContext);
535
+ const result = yield sofa.execute({
536
+ schema: sofa.schema,
537
+ document: operation,
538
+ contextValue,
539
+ variableValues,
540
+ operationName: info.operation.name && info.operation.name.value,
541
+ });
542
+ if (result.errors) {
543
+ return errorHandler(result.errors);
544
+ }
545
+ return new router.Response(JSON.stringify((_b = result.data) === null || _b === void 0 ? void 0 : _b[fieldName]), {
546
+ status: config.route.responseStatus,
547
+ headers: {
548
+ 'Content-Type': 'application/json',
549
+ },
550
+ });
551
+ }
552
+ catch (error) {
553
+ return errorHandler([error]);
523
554
  }
524
- return new router.Response(JSON.stringify((_a = result.data) === null || _a === void 0 ? void 0 : _a[fieldName]), {
525
- status: config.route.responseStatus,
526
- headers: {
527
- 'Content-Type': 'application/json',
528
- },
529
- });
530
555
  });
531
556
  }
532
557
  function getPath(fieldName, hasId = false) {
package/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { __awaiter, __asyncValues } from 'tslib';
2
2
  import { getOperationAST, Kind, isScalarType, isEqualType, GraphQLBoolean, isInputObjectType, isObjectType, isNonNullType, execute, subscribe, getNamedType, isListType, isEnumType, parse, printType, isIntrospectionType } from 'graphql';
3
- import { buildOperationNodeForField } from '@graphql-tools/utils';
3
+ import { buildOperationNodeForField, createGraphQLError } from '@graphql-tools/utils';
4
4
  import { paramCase } from 'param-case';
5
5
  import { crypto, fetch } from '@whatwg-node/fetch';
6
6
  import colors from 'ansi-colors';
@@ -67,12 +67,12 @@ function resolveVariable({ value, type, schema, }) {
67
67
  }
68
68
  }
69
69
 
70
- var _a;
70
+ var _a, _b;
71
71
  const levels = ['error', 'warn', 'info', 'debug'];
72
72
  const toLevel = (string) => levels.includes(string) ? string : null;
73
- const currentLevel = process.env.SOFA_DEBUG
73
+ const currentLevel = ((_a = globalThis.process) === null || _a === void 0 ? void 0 : _a.env.SOFA_DEBUG)
74
74
  ? 'debug'
75
- : (_a = toLevel(process.env.SOFA_LOGGER_LEVEL)) !== null && _a !== void 0 ? _a : 'info';
75
+ : (_b = toLevel(process.env.SOFA_LOGGER_LEVEL)) !== null && _b !== void 0 ? _b : 'info';
76
76
  const log = (level, color, args) => {
77
77
  if (levels.indexOf(level) <= levels.indexOf(currentLevel)) {
78
78
  console.log(`${color(level)}:`, ...args);
@@ -269,6 +269,34 @@ class SubscriptionManager {
269
269
  }
270
270
  }
271
271
 
272
+ const defaultErrorHandler = (errors) => {
273
+ var _a;
274
+ let status;
275
+ const headers = {
276
+ 'Content-Type': 'application/json; charset=utf-8',
277
+ };
278
+ for (const error of errors) {
279
+ if (typeof error === 'object' &&
280
+ error != null &&
281
+ ((_a = error.extensions) === null || _a === void 0 ? void 0 : _a.http)) {
282
+ if (error.extensions.http.status &&
283
+ (!status || error.extensions.http.status > status)) {
284
+ status = error.extensions.http.status;
285
+ }
286
+ if (error.extensions.http.headers) {
287
+ Object.assign(headers, error.extensions.http.headers);
288
+ }
289
+ delete error.extensions.http;
290
+ }
291
+ }
292
+ if (!status) {
293
+ status = 500;
294
+ }
295
+ return new Response(JSON.stringify({ errors }), {
296
+ status,
297
+ headers,
298
+ });
299
+ };
272
300
  function createRouter(sofa) {
273
301
  logger.debug('[Sofa] Creating router');
274
302
  const router = createRouter$1({
@@ -445,82 +473,79 @@ function createMutationRoute({ sofa, router, fieldName, }) {
445
473
  function useHandler(config) {
446
474
  const { sofa, operation, fieldName } = config;
447
475
  const info = config.info;
476
+ const errorHandler = sofa.errorHandler || defaultErrorHandler;
448
477
  return (request, serverContext) => __awaiter(this, void 0, void 0, function* () {
449
- var _a;
450
- let body = {};
451
- if (request.body != null) {
452
- const strBody = yield request.text();
453
- if (strBody) {
454
- body = JSON.parse(strBody);
478
+ var _a, _b;
479
+ try {
480
+ let body = {};
481
+ if (request.body != null) {
482
+ const strBody = yield request.text();
483
+ if (strBody) {
484
+ try {
485
+ body = JSON.parse(strBody);
486
+ }
487
+ catch (error) {
488
+ throw createGraphQLError('POST body sent invalid JSON.', {
489
+ extensions: {
490
+ http: {
491
+ status: 400,
492
+ }
493
+ }
494
+ });
495
+ }
496
+ }
455
497
  }
456
- }
457
- const variableValues = info.variables.reduce((variables, variable) => {
458
- const name = variable.variable.name.value;
459
- const value = parseVariable({
460
- value: pickParam({
461
- url: request.url,
462
- body,
463
- params: request.params || {},
464
- name,
465
- }),
466
- variable,
467
- schema: sofa.schema,
468
- });
469
- if (typeof value === 'undefined') {
470
- return variables;
498
+ let variableValues = {};
499
+ try {
500
+ variableValues = info.variables.reduce((variables, variable) => {
501
+ const name = variable.variable.name.value;
502
+ const value = parseVariable({
503
+ value: pickParam({
504
+ url: request.url,
505
+ body,
506
+ params: request.params || {},
507
+ name,
508
+ }),
509
+ variable,
510
+ schema: sofa.schema,
511
+ });
512
+ if (typeof value === 'undefined') {
513
+ return variables;
514
+ }
515
+ return Object.assign(Object.assign({}, variables), { [name]: value });
516
+ }, {});
471
517
  }
472
- return Object.assign(Object.assign({}, variables), { [name]: value });
473
- }, {});
474
- const sofaServerContext = Object.assign(Object.assign({}, serverContext), { request });
475
- const contextValue = yield sofa.contextFactory(sofaServerContext);
476
- const result = yield sofa.execute({
477
- schema: sofa.schema,
478
- document: operation,
479
- contextValue,
480
- variableValues,
481
- operationName: info.operation.name && info.operation.name.value,
482
- });
483
- if (result.errors) {
484
- const defaultErrorHandler = (errors) => {
485
- var _a;
486
- let status;
487
- const headers = {
488
- 'Content-Type': 'application/json; charset=utf-8',
489
- };
490
- for (const error of errors) {
491
- if (typeof error === 'object' && error != null && ((_a = error.extensions) === null || _a === void 0 ? void 0 : _a.http)) {
492
- if (error.extensions.http.status &&
493
- (!status || error.extensions.http.status > status)) {
494
- status = error.extensions.http.status;
495
- }
496
- if (error.extensions.http.headers) {
497
- Object.assign(headers, error.extensions.http.headers);
518
+ catch (error) {
519
+ throw createGraphQLError(error.message || ((_a = error.toString) === null || _a === void 0 ? void 0 : _a.call(error)) || error, {
520
+ extensions: {
521
+ http: {
522
+ status: 400,
498
523
  }
499
524
  }
500
- }
501
- if (!status) {
502
- status = 500;
503
- }
504
- if (errors.length === 1) {
505
- return new Response(JSON.stringify(errors[0]), {
506
- status,
507
- headers,
508
- });
509
- }
510
- return new Response(JSON.stringify({ errors }), {
511
- status,
512
- headers,
513
525
  });
514
- };
515
- const errorHandler = sofa.errorHandler || defaultErrorHandler;
516
- return errorHandler(result.errors);
526
+ }
527
+ const sofaServerContext = Object.assign(Object.assign({}, serverContext), { request });
528
+ const contextValue = yield sofa.contextFactory(sofaServerContext);
529
+ const result = yield sofa.execute({
530
+ schema: sofa.schema,
531
+ document: operation,
532
+ contextValue,
533
+ variableValues,
534
+ operationName: info.operation.name && info.operation.name.value,
535
+ });
536
+ if (result.errors) {
537
+ return errorHandler(result.errors);
538
+ }
539
+ return new Response(JSON.stringify((_b = result.data) === null || _b === void 0 ? void 0 : _b[fieldName]), {
540
+ status: config.route.responseStatus,
541
+ headers: {
542
+ 'Content-Type': 'application/json',
543
+ },
544
+ });
545
+ }
546
+ catch (error) {
547
+ return errorHandler([error]);
517
548
  }
518
- return new Response(JSON.stringify((_a = result.data) === null || _a === void 0 ? void 0 : _a[fieldName]), {
519
- status: config.route.responseStatus,
520
- headers: {
521
- 'Content-Type': 'application/json',
522
- },
523
- });
524
549
  });
525
550
  }
526
551
  function getPath(fieldName, hasId = false) {
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "sofa-api",
3
- "version": "0.15.5",
3
+ "version": "0.16.0",
4
4
  "description": "Create REST APIs with GraphQL",
5
5
  "sideEffects": false,
6
6
  "peerDependencies": {
7
- "graphql": "^0.13.2 || ^14.0.0 || ^15.0.0 || ^16.0.0"
7
+ "graphql": "^15.0.0 || ^16.0.0"
8
8
  },
9
9
  "dependencies": {
10
10
  "@graphql-tools/utils": "9.1.4",
@@ -14,7 +14,7 @@
14
14
  "openapi-types": "12.1.0",
15
15
  "param-case": "3.0.4",
16
16
  "title-case": "3.0.3",
17
- "tslib": "2.4.1"
17
+ "tslib": "2.5.0"
18
18
  },
19
19
  "repository": {
20
20
  "type": "git",