sofa-api 0.15.1 → 0.15.3
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/ast.d.ts +1 -1
- package/index.d.ts +1 -1
- package/index.js +62 -43
- package/index.mjs +48 -29
- package/package.json +5 -6
- package/router.d.ts +4 -5
- package/subscriptions.d.ts +2 -2
- package/types.d.ts +7 -7
package/ast.d.ts
CHANGED
package/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { SofaConfig } from './sofa';
|
|
2
2
|
export { OpenAPI } from './open-api';
|
|
3
|
-
export declare function useSofa(config: SofaConfig): import("@whatwg-node/
|
|
3
|
+
export declare function useSofa(config: SofaConfig): import("@whatwg-node/router").Router<import("./types").DefaultSofaServerContext>;
|
package/index.js
CHANGED
|
@@ -6,13 +6,13 @@ 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 ittyRouter = require('itty-router');
|
|
10
9
|
const utils = require('@graphql-tools/utils');
|
|
11
10
|
const paramCase = require('param-case');
|
|
12
11
|
const fetch = require('@whatwg-node/fetch');
|
|
13
12
|
const colors = _interopDefault(require('ansi-colors'));
|
|
14
|
-
const
|
|
13
|
+
const router = require('@whatwg-node/router');
|
|
15
14
|
const titleCase = require('title-case');
|
|
15
|
+
const definition = require('graphql/type/definition');
|
|
16
16
|
|
|
17
17
|
function getOperationInfo(doc) {
|
|
18
18
|
const op = graphql.getOperationAST(doc, null);
|
|
@@ -192,20 +192,27 @@ class SubscriptionManager {
|
|
|
192
192
|
});
|
|
193
193
|
// success
|
|
194
194
|
(() => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
195
|
-
var e_1,
|
|
195
|
+
var _a, e_1, _b, _c;
|
|
196
196
|
try {
|
|
197
|
-
for (var execution_1 = tslib.__asyncValues(execution), execution_1_1; execution_1_1 = yield execution_1.next(),
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
result
|
|
202
|
-
|
|
197
|
+
for (var _d = true, execution_1 = tslib.__asyncValues(execution), execution_1_1; execution_1_1 = yield execution_1.next(), _a = execution_1_1.done, !_a;) {
|
|
198
|
+
_c = execution_1_1.value;
|
|
199
|
+
_d = false;
|
|
200
|
+
try {
|
|
201
|
+
const result = _c;
|
|
202
|
+
yield this.sendData({
|
|
203
|
+
id,
|
|
204
|
+
result,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
finally {
|
|
208
|
+
_d = true;
|
|
209
|
+
}
|
|
203
210
|
}
|
|
204
211
|
}
|
|
205
212
|
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
206
213
|
finally {
|
|
207
214
|
try {
|
|
208
|
-
if (
|
|
215
|
+
if (!_d && !_a && (_b = execution_1.return)) yield _b.call(execution_1);
|
|
209
216
|
}
|
|
210
217
|
finally { if (e_1) throw e_1.error; }
|
|
211
218
|
}
|
|
@@ -271,7 +278,7 @@ class SubscriptionManager {
|
|
|
271
278
|
|
|
272
279
|
function createRouter(sofa) {
|
|
273
280
|
logger.debug('[Sofa] Creating router');
|
|
274
|
-
const router =
|
|
281
|
+
const router$1 = router.createRouter({
|
|
275
282
|
base: sofa.basePath,
|
|
276
283
|
});
|
|
277
284
|
const queryType = sofa.schema.getQueryType();
|
|
@@ -279,7 +286,7 @@ function createRouter(sofa) {
|
|
|
279
286
|
const subscriptionManager = new SubscriptionManager(sofa);
|
|
280
287
|
if (queryType) {
|
|
281
288
|
Object.keys(queryType.getFields()).forEach((fieldName) => {
|
|
282
|
-
const route = createQueryRoute({ sofa, router, fieldName });
|
|
289
|
+
const route = createQueryRoute({ sofa, router: router$1, fieldName });
|
|
283
290
|
if (sofa.onRoute) {
|
|
284
291
|
sofa.onRoute(route);
|
|
285
292
|
}
|
|
@@ -287,13 +294,13 @@ function createRouter(sofa) {
|
|
|
287
294
|
}
|
|
288
295
|
if (mutationType) {
|
|
289
296
|
Object.keys(mutationType.getFields()).forEach((fieldName) => {
|
|
290
|
-
const route = createMutationRoute({ sofa, router, fieldName });
|
|
297
|
+
const route = createMutationRoute({ sofa, router: router$1, fieldName });
|
|
291
298
|
if (sofa.onRoute) {
|
|
292
299
|
sofa.onRoute(route);
|
|
293
300
|
}
|
|
294
301
|
});
|
|
295
302
|
}
|
|
296
|
-
router.post('/webhook', (request, serverContext) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
303
|
+
router$1.post('/webhook', (request, serverContext) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
297
304
|
const { subscription, variables, url } = yield request.json();
|
|
298
305
|
try {
|
|
299
306
|
const result = yield subscriptionManager.start({
|
|
@@ -301,7 +308,7 @@ function createRouter(sofa) {
|
|
|
301
308
|
variables,
|
|
302
309
|
url,
|
|
303
310
|
}, Object.assign(Object.assign({}, serverContext), { request }));
|
|
304
|
-
return new
|
|
311
|
+
return new router.Response(JSON.stringify(result), {
|
|
305
312
|
status: 200,
|
|
306
313
|
statusText: 'OK',
|
|
307
314
|
headers: {
|
|
@@ -310,13 +317,13 @@ function createRouter(sofa) {
|
|
|
310
317
|
});
|
|
311
318
|
}
|
|
312
319
|
catch (error) {
|
|
313
|
-
return new
|
|
320
|
+
return new router.Response(JSON.stringify(error), {
|
|
314
321
|
status: 500,
|
|
315
322
|
statusText: 'Subscription failed',
|
|
316
323
|
});
|
|
317
324
|
}
|
|
318
325
|
}));
|
|
319
|
-
router.post('/webhook/:id', (request, serverContext) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
326
|
+
router$1.post('/webhook/:id', (request, serverContext) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
320
327
|
var _a;
|
|
321
328
|
const id = (_a = request.params) === null || _a === void 0 ? void 0 : _a.id;
|
|
322
329
|
const body = yield request.json();
|
|
@@ -328,7 +335,7 @@ function createRouter(sofa) {
|
|
|
328
335
|
id,
|
|
329
336
|
variables,
|
|
330
337
|
}, contextValue);
|
|
331
|
-
return new
|
|
338
|
+
return new router.Response(JSON.stringify(result), {
|
|
332
339
|
status: 200,
|
|
333
340
|
statusText: 'OK',
|
|
334
341
|
headers: {
|
|
@@ -337,18 +344,18 @@ function createRouter(sofa) {
|
|
|
337
344
|
});
|
|
338
345
|
}
|
|
339
346
|
catch (error) {
|
|
340
|
-
return new
|
|
347
|
+
return new router.Response(JSON.stringify(error), {
|
|
341
348
|
status: 500,
|
|
342
349
|
statusText: 'Subscription failed to update',
|
|
343
350
|
});
|
|
344
351
|
}
|
|
345
352
|
}));
|
|
346
|
-
router.delete('/webhook/:id', (request) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
353
|
+
router$1.delete('/webhook/:id', (request) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
347
354
|
var _b;
|
|
348
355
|
const id = (_b = request.params) === null || _b === void 0 ? void 0 : _b.id;
|
|
349
356
|
try {
|
|
350
357
|
const result = yield subscriptionManager.stop(id);
|
|
351
|
-
return new
|
|
358
|
+
return new router.Response(JSON.stringify(result), {
|
|
352
359
|
status: 200,
|
|
353
360
|
statusText: 'OK',
|
|
354
361
|
headers: {
|
|
@@ -357,13 +364,13 @@ function createRouter(sofa) {
|
|
|
357
364
|
});
|
|
358
365
|
}
|
|
359
366
|
catch (error) {
|
|
360
|
-
return new
|
|
367
|
+
return new router.Response(JSON.stringify(error), {
|
|
361
368
|
status: 500,
|
|
362
369
|
statusText: 'Subscription failed to stop',
|
|
363
370
|
});
|
|
364
371
|
}
|
|
365
372
|
}));
|
|
366
|
-
return router;
|
|
373
|
+
return router$1;
|
|
367
374
|
}
|
|
368
375
|
function createQueryRoute({ sofa, router, fieldName, }) {
|
|
369
376
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
@@ -394,7 +401,8 @@ function createQueryRoute({ sofa, router, fieldName, }) {
|
|
|
394
401
|
path: (_c = routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.path) !== null && _c !== void 0 ? _c : getPath(fieldName, isSingle && hasIdArgument),
|
|
395
402
|
responseStatus: (_d = routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.responseStatus) !== null && _d !== void 0 ? _d : 200,
|
|
396
403
|
};
|
|
397
|
-
|
|
404
|
+
const routerMethod = route.method.toLowerCase();
|
|
405
|
+
router[routerMethod](route.path, useHandler({ info, route, fieldName, sofa, operation }));
|
|
398
406
|
logger.debug(`[Router] ${fieldName} query available at ${route.method} ${route.path}`);
|
|
399
407
|
return {
|
|
400
408
|
document: operation,
|
|
@@ -430,7 +438,8 @@ function createMutationRoute({ sofa, router, fieldName, }) {
|
|
|
430
438
|
responseStatus: (_d = routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.responseStatus) !== null && _d !== void 0 ? _d : 200,
|
|
431
439
|
};
|
|
432
440
|
const { method, path } = route;
|
|
433
|
-
|
|
441
|
+
const routerKey = method.toLowerCase();
|
|
442
|
+
router[routerKey](path, useHandler({ info, route, fieldName, sofa, operation }));
|
|
434
443
|
logger.debug(`[Router] ${fieldName} mutation available at ${method} ${path}`);
|
|
435
444
|
return {
|
|
436
445
|
document: operation,
|
|
@@ -500,12 +509,12 @@ function useHandler(config) {
|
|
|
500
509
|
status = 500;
|
|
501
510
|
}
|
|
502
511
|
if (errors.length === 1) {
|
|
503
|
-
return new
|
|
512
|
+
return new router.Response(JSON.stringify(errors[0]), {
|
|
504
513
|
status,
|
|
505
514
|
headers,
|
|
506
515
|
});
|
|
507
516
|
}
|
|
508
|
-
return new
|
|
517
|
+
return new router.Response(JSON.stringify({ errors }), {
|
|
509
518
|
status,
|
|
510
519
|
headers,
|
|
511
520
|
});
|
|
@@ -513,7 +522,7 @@ function useHandler(config) {
|
|
|
513
522
|
const errorHandler = sofa.errorHandler || defaultErrorHandler;
|
|
514
523
|
return errorHandler(result.errors);
|
|
515
524
|
}
|
|
516
|
-
return new
|
|
525
|
+
return new router.Response(JSON.stringify((_a = result.data) === null || _a === void 0 ? void 0 : _a[fieldName]), {
|
|
517
526
|
status: config.route.responseStatus,
|
|
518
527
|
headers: {
|
|
519
528
|
'Content-Type': 'application/json',
|
|
@@ -685,12 +694,12 @@ function resolveFieldType(type, opts) {
|
|
|
685
694
|
};
|
|
686
695
|
}
|
|
687
696
|
if (graphql.isScalarType(type)) {
|
|
688
|
-
|
|
697
|
+
const resolved = mapToPrimitive(type.name) ||
|
|
689
698
|
opts.customScalars[type.name] ||
|
|
690
|
-
((_a = type.extensions) === null || _a === void 0 ? void 0 : _a.jsonSchema)
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
699
|
+
((_a = type.extensions) === null || _a === void 0 ? void 0 : _a.jsonSchema) || {
|
|
700
|
+
type: 'object',
|
|
701
|
+
};
|
|
702
|
+
return Object.assign({}, resolved);
|
|
694
703
|
}
|
|
695
704
|
if (graphql.isEnumType(type)) {
|
|
696
705
|
return {
|
|
@@ -705,6 +714,7 @@ function resolveFieldType(type, opts) {
|
|
|
705
714
|
|
|
706
715
|
function buildPathFromOperation({ url, schema, operation, useRequestBody, tags, description, customScalars, }) {
|
|
707
716
|
const info = getOperationInfo(operation);
|
|
717
|
+
const enumTypes = resolveEnumTypes(schema);
|
|
708
718
|
const summary = resolveSummary(schema, info.operation);
|
|
709
719
|
return Object.assign(Object.assign({ tags,
|
|
710
720
|
description,
|
|
@@ -714,14 +724,14 @@ function buildPathFromOperation({ url, schema, operation, useRequestBody, tags,
|
|
|
714
724
|
content: {
|
|
715
725
|
'application/json': {
|
|
716
726
|
schema: resolveRequestBody(info.operation.variableDefinitions, {
|
|
717
|
-
customScalars,
|
|
727
|
+
customScalars, enumTypes
|
|
718
728
|
}),
|
|
719
729
|
},
|
|
720
730
|
},
|
|
721
731
|
},
|
|
722
732
|
}
|
|
723
733
|
: {
|
|
724
|
-
parameters: resolveParameters(url, info.operation.variableDefinitions, { customScalars }),
|
|
734
|
+
parameters: resolveParameters(url, info.operation.variableDefinitions, { customScalars, enumTypes }),
|
|
725
735
|
})), { responses: {
|
|
726
736
|
200: {
|
|
727
737
|
description: summary,
|
|
@@ -730,13 +740,22 @@ function buildPathFromOperation({ url, schema, operation, useRequestBody, tags,
|
|
|
730
740
|
schema: resolveResponse({
|
|
731
741
|
schema,
|
|
732
742
|
operation: info.operation,
|
|
733
|
-
customScalars,
|
|
743
|
+
opts: { customScalars, enumTypes },
|
|
734
744
|
}),
|
|
735
745
|
},
|
|
736
746
|
},
|
|
737
747
|
},
|
|
738
748
|
} });
|
|
739
749
|
}
|
|
750
|
+
function resolveEnumTypes(schema) {
|
|
751
|
+
const enumTypes = Object.values(schema.getTypeMap()).filter(graphql.isEnumType).map(definition.assertEnumType);
|
|
752
|
+
return Object.fromEntries(enumTypes.map(type => ([type.name,
|
|
753
|
+
{
|
|
754
|
+
type: 'string',
|
|
755
|
+
enum: type.getValues().map(value => value.name),
|
|
756
|
+
},
|
|
757
|
+
])));
|
|
758
|
+
}
|
|
740
759
|
function resolveParameters(url, variables, opts) {
|
|
741
760
|
if (!variables) {
|
|
742
761
|
return [];
|
|
@@ -779,23 +798,23 @@ function resolveParamSchema(type, opts) {
|
|
|
779
798
|
}
|
|
780
799
|
const primitive = mapToPrimitive(type.name.value);
|
|
781
800
|
return (primitive ||
|
|
782
|
-
opts.customScalars[type.name.value] ||
|
|
783
|
-
|
|
784
|
-
|
|
801
|
+
opts.customScalars[type.name.value] ||
|
|
802
|
+
opts.enumTypes[type.name.value] ||
|
|
803
|
+
{ $ref: mapToRef(type.name.value) });
|
|
785
804
|
}
|
|
786
|
-
function resolveResponse({ schema, operation,
|
|
805
|
+
function resolveResponse({ schema, operation, opts, }) {
|
|
787
806
|
const operationType = operation.operation;
|
|
788
807
|
const rootField = operation.selectionSet.selections[0];
|
|
789
808
|
if (rootField.kind === graphql.Kind.FIELD) {
|
|
790
809
|
if (operationType === 'query') {
|
|
791
810
|
const queryType = schema.getQueryType();
|
|
792
811
|
const field = queryType.getFields()[rootField.name.value];
|
|
793
|
-
return resolveFieldType(field.type,
|
|
812
|
+
return resolveFieldType(field.type, opts);
|
|
794
813
|
}
|
|
795
814
|
if (operationType === 'mutation') {
|
|
796
815
|
const mutationType = schema.getMutationType();
|
|
797
816
|
const field = mutationType.getFields()[rootField.name.value];
|
|
798
|
-
return resolveFieldType(field.type,
|
|
817
|
+
return resolveFieldType(field.type, opts);
|
|
799
818
|
}
|
|
800
819
|
}
|
|
801
820
|
}
|
|
@@ -879,7 +898,7 @@ function OpenAPI({ schema, info, servers, components, security, tags, customScal
|
|
|
879
898
|
}
|
|
880
899
|
|
|
881
900
|
function useSofa(config) {
|
|
882
|
-
return
|
|
901
|
+
return createRouter(createSofa(config));
|
|
883
902
|
}
|
|
884
903
|
|
|
885
904
|
exports.OpenAPI = OpenAPI;
|
package/index.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
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 { Router } from 'itty-router';
|
|
4
3
|
import { buildOperationNodeForField } from '@graphql-tools/utils';
|
|
5
4
|
import { paramCase } from 'param-case';
|
|
6
|
-
import { crypto, fetch
|
|
5
|
+
import { crypto, fetch } from '@whatwg-node/fetch';
|
|
7
6
|
import colors from 'ansi-colors';
|
|
8
|
-
import {
|
|
7
|
+
import { createRouter as createRouter$1, Response } from '@whatwg-node/router';
|
|
9
8
|
import { titleCase } from 'title-case';
|
|
9
|
+
import { assertEnumType } from 'graphql/type/definition';
|
|
10
10
|
|
|
11
11
|
function getOperationInfo(doc) {
|
|
12
12
|
const op = getOperationAST(doc, null);
|
|
@@ -186,20 +186,27 @@ class SubscriptionManager {
|
|
|
186
186
|
});
|
|
187
187
|
// success
|
|
188
188
|
(() => __awaiter(this, void 0, void 0, function* () {
|
|
189
|
-
var e_1,
|
|
189
|
+
var _a, e_1, _b, _c;
|
|
190
190
|
try {
|
|
191
|
-
for (var execution_1 = __asyncValues(execution), execution_1_1; execution_1_1 = yield execution_1.next(),
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
result
|
|
196
|
-
|
|
191
|
+
for (var _d = true, execution_1 = __asyncValues(execution), execution_1_1; execution_1_1 = yield execution_1.next(), _a = execution_1_1.done, !_a;) {
|
|
192
|
+
_c = execution_1_1.value;
|
|
193
|
+
_d = false;
|
|
194
|
+
try {
|
|
195
|
+
const result = _c;
|
|
196
|
+
yield this.sendData({
|
|
197
|
+
id,
|
|
198
|
+
result,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
finally {
|
|
202
|
+
_d = true;
|
|
203
|
+
}
|
|
197
204
|
}
|
|
198
205
|
}
|
|
199
206
|
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
200
207
|
finally {
|
|
201
208
|
try {
|
|
202
|
-
if (
|
|
209
|
+
if (!_d && !_a && (_b = execution_1.return)) yield _b.call(execution_1);
|
|
203
210
|
}
|
|
204
211
|
finally { if (e_1) throw e_1.error; }
|
|
205
212
|
}
|
|
@@ -265,7 +272,7 @@ class SubscriptionManager {
|
|
|
265
272
|
|
|
266
273
|
function createRouter(sofa) {
|
|
267
274
|
logger.debug('[Sofa] Creating router');
|
|
268
|
-
const router =
|
|
275
|
+
const router = createRouter$1({
|
|
269
276
|
base: sofa.basePath,
|
|
270
277
|
});
|
|
271
278
|
const queryType = sofa.schema.getQueryType();
|
|
@@ -388,7 +395,8 @@ function createQueryRoute({ sofa, router, fieldName, }) {
|
|
|
388
395
|
path: (_c = routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.path) !== null && _c !== void 0 ? _c : getPath(fieldName, isSingle && hasIdArgument),
|
|
389
396
|
responseStatus: (_d = routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.responseStatus) !== null && _d !== void 0 ? _d : 200,
|
|
390
397
|
};
|
|
391
|
-
|
|
398
|
+
const routerMethod = route.method.toLowerCase();
|
|
399
|
+
router[routerMethod](route.path, useHandler({ info, route, fieldName, sofa, operation }));
|
|
392
400
|
logger.debug(`[Router] ${fieldName} query available at ${route.method} ${route.path}`);
|
|
393
401
|
return {
|
|
394
402
|
document: operation,
|
|
@@ -424,7 +432,8 @@ function createMutationRoute({ sofa, router, fieldName, }) {
|
|
|
424
432
|
responseStatus: (_d = routeConfig === null || routeConfig === void 0 ? void 0 : routeConfig.responseStatus) !== null && _d !== void 0 ? _d : 200,
|
|
425
433
|
};
|
|
426
434
|
const { method, path } = route;
|
|
427
|
-
|
|
435
|
+
const routerKey = method.toLowerCase();
|
|
436
|
+
router[routerKey](path, useHandler({ info, route, fieldName, sofa, operation }));
|
|
428
437
|
logger.debug(`[Router] ${fieldName} mutation available at ${method} ${path}`);
|
|
429
438
|
return {
|
|
430
439
|
document: operation,
|
|
@@ -679,12 +688,12 @@ function resolveFieldType(type, opts) {
|
|
|
679
688
|
};
|
|
680
689
|
}
|
|
681
690
|
if (isScalarType(type)) {
|
|
682
|
-
|
|
691
|
+
const resolved = mapToPrimitive(type.name) ||
|
|
683
692
|
opts.customScalars[type.name] ||
|
|
684
|
-
((_a = type.extensions) === null || _a === void 0 ? void 0 : _a.jsonSchema)
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
693
|
+
((_a = type.extensions) === null || _a === void 0 ? void 0 : _a.jsonSchema) || {
|
|
694
|
+
type: 'object',
|
|
695
|
+
};
|
|
696
|
+
return Object.assign({}, resolved);
|
|
688
697
|
}
|
|
689
698
|
if (isEnumType(type)) {
|
|
690
699
|
return {
|
|
@@ -699,6 +708,7 @@ function resolveFieldType(type, opts) {
|
|
|
699
708
|
|
|
700
709
|
function buildPathFromOperation({ url, schema, operation, useRequestBody, tags, description, customScalars, }) {
|
|
701
710
|
const info = getOperationInfo(operation);
|
|
711
|
+
const enumTypes = resolveEnumTypes(schema);
|
|
702
712
|
const summary = resolveSummary(schema, info.operation);
|
|
703
713
|
return Object.assign(Object.assign({ tags,
|
|
704
714
|
description,
|
|
@@ -708,14 +718,14 @@ function buildPathFromOperation({ url, schema, operation, useRequestBody, tags,
|
|
|
708
718
|
content: {
|
|
709
719
|
'application/json': {
|
|
710
720
|
schema: resolveRequestBody(info.operation.variableDefinitions, {
|
|
711
|
-
customScalars,
|
|
721
|
+
customScalars, enumTypes
|
|
712
722
|
}),
|
|
713
723
|
},
|
|
714
724
|
},
|
|
715
725
|
},
|
|
716
726
|
}
|
|
717
727
|
: {
|
|
718
|
-
parameters: resolveParameters(url, info.operation.variableDefinitions, { customScalars }),
|
|
728
|
+
parameters: resolveParameters(url, info.operation.variableDefinitions, { customScalars, enumTypes }),
|
|
719
729
|
})), { responses: {
|
|
720
730
|
200: {
|
|
721
731
|
description: summary,
|
|
@@ -724,13 +734,22 @@ function buildPathFromOperation({ url, schema, operation, useRequestBody, tags,
|
|
|
724
734
|
schema: resolveResponse({
|
|
725
735
|
schema,
|
|
726
736
|
operation: info.operation,
|
|
727
|
-
customScalars,
|
|
737
|
+
opts: { customScalars, enumTypes },
|
|
728
738
|
}),
|
|
729
739
|
},
|
|
730
740
|
},
|
|
731
741
|
},
|
|
732
742
|
} });
|
|
733
743
|
}
|
|
744
|
+
function resolveEnumTypes(schema) {
|
|
745
|
+
const enumTypes = Object.values(schema.getTypeMap()).filter(isEnumType).map(assertEnumType);
|
|
746
|
+
return Object.fromEntries(enumTypes.map(type => ([type.name,
|
|
747
|
+
{
|
|
748
|
+
type: 'string',
|
|
749
|
+
enum: type.getValues().map(value => value.name),
|
|
750
|
+
},
|
|
751
|
+
])));
|
|
752
|
+
}
|
|
734
753
|
function resolveParameters(url, variables, opts) {
|
|
735
754
|
if (!variables) {
|
|
736
755
|
return [];
|
|
@@ -773,23 +792,23 @@ function resolveParamSchema(type, opts) {
|
|
|
773
792
|
}
|
|
774
793
|
const primitive = mapToPrimitive(type.name.value);
|
|
775
794
|
return (primitive ||
|
|
776
|
-
opts.customScalars[type.name.value] ||
|
|
777
|
-
|
|
778
|
-
|
|
795
|
+
opts.customScalars[type.name.value] ||
|
|
796
|
+
opts.enumTypes[type.name.value] ||
|
|
797
|
+
{ $ref: mapToRef(type.name.value) });
|
|
779
798
|
}
|
|
780
|
-
function resolveResponse({ schema, operation,
|
|
799
|
+
function resolveResponse({ schema, operation, opts, }) {
|
|
781
800
|
const operationType = operation.operation;
|
|
782
801
|
const rootField = operation.selectionSet.selections[0];
|
|
783
802
|
if (rootField.kind === Kind.FIELD) {
|
|
784
803
|
if (operationType === 'query') {
|
|
785
804
|
const queryType = schema.getQueryType();
|
|
786
805
|
const field = queryType.getFields()[rootField.name.value];
|
|
787
|
-
return resolveFieldType(field.type,
|
|
806
|
+
return resolveFieldType(field.type, opts);
|
|
788
807
|
}
|
|
789
808
|
if (operationType === 'mutation') {
|
|
790
809
|
const mutationType = schema.getMutationType();
|
|
791
810
|
const field = mutationType.getFields()[rootField.name.value];
|
|
792
|
-
return resolveFieldType(field.type,
|
|
811
|
+
return resolveFieldType(field.type, opts);
|
|
793
812
|
}
|
|
794
813
|
}
|
|
795
814
|
}
|
|
@@ -873,7 +892,7 @@ function OpenAPI({ schema, info, servers, components, security, tags, customScal
|
|
|
873
892
|
}
|
|
874
893
|
|
|
875
894
|
function useSofa(config) {
|
|
876
|
-
return
|
|
895
|
+
return createRouter(createSofa(config));
|
|
877
896
|
}
|
|
878
897
|
|
|
879
898
|
export { OpenAPI, useSofa };
|
package/package.json
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sofa-api",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.3",
|
|
4
4
|
"description": "Create REST APIs with GraphQL",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"peerDependencies": {
|
|
7
7
|
"graphql": "^0.13.2 || ^14.0.0 || ^15.0.0 || ^16.0.0"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@graphql-tools/utils": "9.1.
|
|
11
|
-
"@whatwg-node/fetch": "^0.
|
|
12
|
-
"@whatwg-node/
|
|
10
|
+
"@graphql-tools/utils": "9.1.3",
|
|
11
|
+
"@whatwg-node/fetch": "^0.6.0",
|
|
12
|
+
"@whatwg-node/router": "^0.1.2",
|
|
13
13
|
"ansi-colors": "4.1.3",
|
|
14
|
-
"
|
|
15
|
-
"openapi-types": "12.0.2",
|
|
14
|
+
"openapi-types": "12.1.0",
|
|
16
15
|
"param-case": "3.0.4",
|
|
17
16
|
"title-case": "3.0.3",
|
|
18
17
|
"tslib": "2.4.1"
|
package/router.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { Request as IttyRequest, Router } from 'itty-router';
|
|
2
1
|
import type { Sofa } from './sofa';
|
|
3
|
-
|
|
2
|
+
import type { DefaultSofaServerContext } from './types';
|
|
3
|
+
import { Router } from '@whatwg-node/router';
|
|
4
|
+
export type ErrorHandler = (errors: ReadonlyArray<any>) => Response;
|
|
4
5
|
declare module 'graphql' {
|
|
5
6
|
interface GraphQLHTTPErrorExtensions {
|
|
6
7
|
status?: number;
|
|
@@ -10,6 +11,4 @@ declare module 'graphql' {
|
|
|
10
11
|
http?: GraphQLHTTPErrorExtensions;
|
|
11
12
|
}
|
|
12
13
|
}
|
|
13
|
-
declare
|
|
14
|
-
export declare function createRouter(sofa: Sofa): Router<SofaRequest, {}>;
|
|
15
|
-
export {};
|
|
14
|
+
export declare function createRouter(sofa: Sofa): Router<DefaultSofaServerContext>;
|
package/subscriptions.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ExecutionResult } from 'graphql';
|
|
2
2
|
import type { ContextValue } from './types';
|
|
3
3
|
import type { Sofa } from './sofa';
|
|
4
|
-
export
|
|
5
|
-
export
|
|
4
|
+
export type ID = string;
|
|
5
|
+
export type SubscriptionFieldName = string;
|
|
6
6
|
export interface StartSubscriptionEvent {
|
|
7
7
|
subscription: SubscriptionFieldName;
|
|
8
8
|
variables: any;
|
package/types.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { DefaultServerAdapterContext } from '@whatwg-node/
|
|
1
|
+
import { DefaultServerAdapterContext } from '@whatwg-node/router';
|
|
2
2
|
import { DocumentNode } from 'graphql';
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
3
|
+
export type ContextValue = Record<string, any>;
|
|
4
|
+
export type Ignore = string[];
|
|
5
|
+
export type Method = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
6
6
|
export interface RouteInfo {
|
|
7
7
|
document: DocumentNode;
|
|
8
8
|
path: string;
|
|
@@ -10,8 +10,8 @@ export interface RouteInfo {
|
|
|
10
10
|
tags?: string[];
|
|
11
11
|
description?: string;
|
|
12
12
|
}
|
|
13
|
-
export
|
|
14
|
-
export
|
|
15
|
-
export
|
|
13
|
+
export type OnRoute = (info: RouteInfo) => void;
|
|
14
|
+
export type ContextFn = (serverContext: DefaultSofaServerContext) => Promise<ContextValue> | ContextValue;
|
|
15
|
+
export type DefaultSofaServerContext = DefaultServerAdapterContext & {
|
|
16
16
|
request: Request;
|
|
17
17
|
};
|