sofa-api 0.12.0 → 0.13.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 +2 -2
- package/index.js +20 -15
- package/index.mjs +20 -15
- package/package.json +2 -2
- package/types.d.ts +5 -4
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
|
-
|
|
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
|
-
},
|
|
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
|
|
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,
|
|
@@ -469,7 +469,8 @@ function useHandler(config) {
|
|
|
469
469
|
}
|
|
470
470
|
return Object.assign(Object.assign({}, variables), { [name]: value });
|
|
471
471
|
}, {});
|
|
472
|
-
const
|
|
472
|
+
const sofaServerContext = Object.assign(Object.assign({}, serverContext), { request });
|
|
473
|
+
const contextValue = yield sofa.contextFactory(sofaServerContext);
|
|
473
474
|
const result = yield sofa.execute({
|
|
474
475
|
schema: sofa.schema,
|
|
475
476
|
document: operation,
|
|
@@ -479,8 +480,9 @@ function useHandler(config) {
|
|
|
479
480
|
});
|
|
480
481
|
if (result.errors) {
|
|
481
482
|
const defaultErrorHandler = (errors) => {
|
|
482
|
-
return new fetch.Response(errors[0], {
|
|
483
|
+
return new fetch.Response(JSON.stringify(errors[0]), {
|
|
483
484
|
status: 500,
|
|
485
|
+
headers: { 'Content-Type': 'application/json' },
|
|
484
486
|
});
|
|
485
487
|
};
|
|
486
488
|
const errorHandler = sofa.errorHandler || defaultErrorHandler;
|
|
@@ -683,13 +685,15 @@ function buildPathFromOperation({ url, schema, operation, useRequestBody, tags,
|
|
|
683
685
|
requestBody: {
|
|
684
686
|
content: {
|
|
685
687
|
'application/json': {
|
|
686
|
-
schema: resolveRequestBody(info.operation.variableDefinitions
|
|
688
|
+
schema: resolveRequestBody(info.operation.variableDefinitions, {
|
|
689
|
+
customScalars,
|
|
690
|
+
}),
|
|
687
691
|
},
|
|
688
692
|
},
|
|
689
693
|
},
|
|
690
694
|
}
|
|
691
695
|
: {
|
|
692
|
-
parameters: resolveParameters(url, info.operation.variableDefinitions),
|
|
696
|
+
parameters: resolveParameters(url, info.operation.variableDefinitions, { customScalars }),
|
|
693
697
|
})), { responses: {
|
|
694
698
|
200: {
|
|
695
699
|
description: summary,
|
|
@@ -705,7 +709,7 @@ function buildPathFromOperation({ url, schema, operation, useRequestBody, tags,
|
|
|
705
709
|
},
|
|
706
710
|
} });
|
|
707
711
|
}
|
|
708
|
-
function resolveParameters(url, variables) {
|
|
712
|
+
function resolveParameters(url, variables, opts) {
|
|
709
713
|
if (!variables) {
|
|
710
714
|
return [];
|
|
711
715
|
}
|
|
@@ -714,11 +718,11 @@ function resolveParameters(url, variables) {
|
|
|
714
718
|
in: isInPath(url, variable.variable.name.value) ? 'path' : 'query',
|
|
715
719
|
name: variable.variable.name.value,
|
|
716
720
|
required: variable.type.kind === graphql.Kind.NON_NULL_TYPE,
|
|
717
|
-
schema: resolveParamSchema(variable.type),
|
|
721
|
+
schema: resolveParamSchema(variable.type, opts),
|
|
718
722
|
};
|
|
719
723
|
});
|
|
720
724
|
}
|
|
721
|
-
function resolveRequestBody(variables) {
|
|
725
|
+
function resolveRequestBody(variables, opts) {
|
|
722
726
|
if (!variables) {
|
|
723
727
|
return {};
|
|
724
728
|
}
|
|
@@ -728,25 +732,26 @@ function resolveRequestBody(variables) {
|
|
|
728
732
|
if (variable.type.kind === graphql.Kind.NON_NULL_TYPE) {
|
|
729
733
|
required.push(variable.variable.name.value);
|
|
730
734
|
}
|
|
731
|
-
properties[variable.variable.name.value] = resolveParamSchema(variable.type);
|
|
735
|
+
properties[variable.variable.name.value] = resolveParamSchema(variable.type, opts);
|
|
732
736
|
});
|
|
733
737
|
return Object.assign({ type: 'object', properties }, (required.length ? { required } : {}));
|
|
734
738
|
}
|
|
735
739
|
// array -> [type]
|
|
736
740
|
// type -> $ref
|
|
737
741
|
// scalar -> swagger primitive
|
|
738
|
-
function resolveParamSchema(type) {
|
|
742
|
+
function resolveParamSchema(type, opts) {
|
|
739
743
|
if (type.kind === graphql.Kind.NON_NULL_TYPE) {
|
|
740
|
-
return resolveParamSchema(type.type);
|
|
744
|
+
return resolveParamSchema(type.type, opts);
|
|
741
745
|
}
|
|
742
746
|
if (type.kind === graphql.Kind.LIST_TYPE) {
|
|
743
747
|
return {
|
|
744
748
|
type: 'array',
|
|
745
|
-
items: resolveParamSchema(type.type),
|
|
749
|
+
items: resolveParamSchema(type.type, opts),
|
|
746
750
|
};
|
|
747
751
|
}
|
|
748
752
|
const primitive = mapToPrimitive(type.name.value);
|
|
749
|
-
return (primitive ||
|
|
753
|
+
return (primitive ||
|
|
754
|
+
opts.customScalars[type.name.value] || {
|
|
750
755
|
$ref: mapToRef(type.name.value),
|
|
751
756
|
});
|
|
752
757
|
}
|
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
|
-
},
|
|
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
|
|
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,
|
|
@@ -463,7 +463,8 @@ function useHandler(config) {
|
|
|
463
463
|
}
|
|
464
464
|
return Object.assign(Object.assign({}, variables), { [name]: value });
|
|
465
465
|
}, {});
|
|
466
|
-
const
|
|
466
|
+
const sofaServerContext = Object.assign(Object.assign({}, serverContext), { request });
|
|
467
|
+
const contextValue = yield sofa.contextFactory(sofaServerContext);
|
|
467
468
|
const result = yield sofa.execute({
|
|
468
469
|
schema: sofa.schema,
|
|
469
470
|
document: operation,
|
|
@@ -473,8 +474,9 @@ function useHandler(config) {
|
|
|
473
474
|
});
|
|
474
475
|
if (result.errors) {
|
|
475
476
|
const defaultErrorHandler = (errors) => {
|
|
476
|
-
return new Response(errors[0], {
|
|
477
|
+
return new Response(JSON.stringify(errors[0]), {
|
|
477
478
|
status: 500,
|
|
479
|
+
headers: { 'Content-Type': 'application/json' },
|
|
478
480
|
});
|
|
479
481
|
};
|
|
480
482
|
const errorHandler = sofa.errorHandler || defaultErrorHandler;
|
|
@@ -677,13 +679,15 @@ function buildPathFromOperation({ url, schema, operation, useRequestBody, tags,
|
|
|
677
679
|
requestBody: {
|
|
678
680
|
content: {
|
|
679
681
|
'application/json': {
|
|
680
|
-
schema: resolveRequestBody(info.operation.variableDefinitions
|
|
682
|
+
schema: resolveRequestBody(info.operation.variableDefinitions, {
|
|
683
|
+
customScalars,
|
|
684
|
+
}),
|
|
681
685
|
},
|
|
682
686
|
},
|
|
683
687
|
},
|
|
684
688
|
}
|
|
685
689
|
: {
|
|
686
|
-
parameters: resolveParameters(url, info.operation.variableDefinitions),
|
|
690
|
+
parameters: resolveParameters(url, info.operation.variableDefinitions, { customScalars }),
|
|
687
691
|
})), { responses: {
|
|
688
692
|
200: {
|
|
689
693
|
description: summary,
|
|
@@ -699,7 +703,7 @@ function buildPathFromOperation({ url, schema, operation, useRequestBody, tags,
|
|
|
699
703
|
},
|
|
700
704
|
} });
|
|
701
705
|
}
|
|
702
|
-
function resolveParameters(url, variables) {
|
|
706
|
+
function resolveParameters(url, variables, opts) {
|
|
703
707
|
if (!variables) {
|
|
704
708
|
return [];
|
|
705
709
|
}
|
|
@@ -708,11 +712,11 @@ function resolveParameters(url, variables) {
|
|
|
708
712
|
in: isInPath(url, variable.variable.name.value) ? 'path' : 'query',
|
|
709
713
|
name: variable.variable.name.value,
|
|
710
714
|
required: variable.type.kind === Kind.NON_NULL_TYPE,
|
|
711
|
-
schema: resolveParamSchema(variable.type),
|
|
715
|
+
schema: resolveParamSchema(variable.type, opts),
|
|
712
716
|
};
|
|
713
717
|
});
|
|
714
718
|
}
|
|
715
|
-
function resolveRequestBody(variables) {
|
|
719
|
+
function resolveRequestBody(variables, opts) {
|
|
716
720
|
if (!variables) {
|
|
717
721
|
return {};
|
|
718
722
|
}
|
|
@@ -722,25 +726,26 @@ function resolveRequestBody(variables) {
|
|
|
722
726
|
if (variable.type.kind === Kind.NON_NULL_TYPE) {
|
|
723
727
|
required.push(variable.variable.name.value);
|
|
724
728
|
}
|
|
725
|
-
properties[variable.variable.name.value] = resolveParamSchema(variable.type);
|
|
729
|
+
properties[variable.variable.name.value] = resolveParamSchema(variable.type, opts);
|
|
726
730
|
});
|
|
727
731
|
return Object.assign({ type: 'object', properties }, (required.length ? { required } : {}));
|
|
728
732
|
}
|
|
729
733
|
// array -> [type]
|
|
730
734
|
// type -> $ref
|
|
731
735
|
// scalar -> swagger primitive
|
|
732
|
-
function resolveParamSchema(type) {
|
|
736
|
+
function resolveParamSchema(type, opts) {
|
|
733
737
|
if (type.kind === Kind.NON_NULL_TYPE) {
|
|
734
|
-
return resolveParamSchema(type.type);
|
|
738
|
+
return resolveParamSchema(type.type, opts);
|
|
735
739
|
}
|
|
736
740
|
if (type.kind === Kind.LIST_TYPE) {
|
|
737
741
|
return {
|
|
738
742
|
type: 'array',
|
|
739
|
-
items: resolveParamSchema(type.type),
|
|
743
|
+
items: resolveParamSchema(type.type, opts),
|
|
740
744
|
};
|
|
741
745
|
}
|
|
742
746
|
const primitive = mapToPrimitive(type.name.value);
|
|
743
|
-
return (primitive ||
|
|
747
|
+
return (primitive ||
|
|
748
|
+
opts.customScalars[type.name.value] || {
|
|
744
749
|
$ref: mapToRef(type.name.value),
|
|
745
750
|
});
|
|
746
751
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sofa-api",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.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 = (
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
14
|
+
export declare type ContextFn = (serverContext: DefaultSofaServerContext) => Promise<ContextValue> | ContextValue;
|
|
15
|
+
export declare type DefaultSofaServerContext = DefaultServerAdapterContext & {
|
|
16
|
+
request: Request;
|
|
17
|
+
};
|