sofa-api 0.5.0 → 0.7.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 (55) hide show
  1. package/{dist/ast.d.ts → ast.d.ts} +7 -7
  2. package/{dist/common.d.ts → common.d.ts} +2 -1
  3. package/express.d.ts +5 -0
  4. package/index.cjs.js +1058 -0
  5. package/{dist/index.d.ts → index.d.ts} +6 -6
  6. package/index.esm.js +1050 -0
  7. package/{dist/logger.d.ts → logger.d.ts} +1 -1
  8. package/{dist/open-api → open-api}/index.d.ts +14 -12
  9. package/{dist/open-api → open-api}/interfaces.d.ts +325 -325
  10. package/{dist/open-api → open-api}/operations.d.ts +7 -7
  11. package/{dist/open-api → open-api}/types.d.ts +3 -3
  12. package/{dist/open-api → open-api}/utils.d.ts +2 -2
  13. package/{dist/operation.d.ts → operation.d.ts} +12 -12
  14. package/package.json +23 -71
  15. package/{dist/parse.d.ts → parse.d.ts} +6 -6
  16. package/{dist/sofa.d.ts → sofa.d.ts} +33 -33
  17. package/{dist/subscriptions.d.ts → subscriptions.d.ts} +38 -38
  18. package/{dist/types.d.ts → types.d.ts} +17 -17
  19. package/.DS_Store +0 -0
  20. package/.git/logs/refs/remotes/origin/changelog +0 -1
  21. package/.git/refs/remotes/origin/changelog +0 -1
  22. package/CHANGELOG.md +0 -30
  23. package/LICENSE +0 -21
  24. package/README.md +0 -276
  25. package/dist/ast.js +0 -16
  26. package/dist/ast.js.map +0 -1
  27. package/dist/common.js +0 -8
  28. package/dist/common.js.map +0 -1
  29. package/dist/express.d.ts +0 -5
  30. package/dist/express.js +0 -226
  31. package/dist/express.js.map +0 -1
  32. package/dist/index.js +0 -13
  33. package/dist/index.js.map +0 -1
  34. package/dist/logger.js +0 -8
  35. package/dist/logger.js.map +0 -1
  36. package/dist/open-api/index.js +0 -67
  37. package/dist/open-api/index.js.map +0 -1
  38. package/dist/open-api/interfaces.js +0 -3
  39. package/dist/open-api/interfaces.js.map +0 -1
  40. package/dist/open-api/operations.js +0 -112
  41. package/dist/open-api/operations.js.map +0 -1
  42. package/dist/open-api/types.js +0 -50
  43. package/dist/open-api/types.js.map +0 -1
  44. package/dist/open-api/utils.js +0 -29
  45. package/dist/open-api/utils.js.map +0 -1
  46. package/dist/operation.js +0 -258
  47. package/dist/operation.js.map +0 -1
  48. package/dist/parse.js +0 -46
  49. package/dist/parse.js.map +0 -1
  50. package/dist/sofa.js +0 -90
  51. package/dist/sofa.js.map +0 -1
  52. package/dist/subscriptions.js +0 -174
  53. package/dist/subscriptions.js.map +0 -1
  54. package/dist/types.js +0 -3
  55. package/dist/types.js.map +0 -1
package/README.md DELETED
@@ -1,276 +0,0 @@
1
- [![sofa](https://user-images.githubusercontent.com/25294569/63839869-bfac8300-c988-11e9-978e-6b6c16c350de.gif)](https://sofa-api.com)
2
-
3
- [![npm version](https://badge.fury.io/js/sofa-api.svg)](https://npmjs.com/package/sofa-api)
4
- [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)
5
- [![renovate-app badge](https://img.shields.io/badge/renovate-app-blue.svg)](https://renovateapp.com/)
6
-
7
- The best way to create REST APIs (is GraphQL).
8
-
9
- ## Installation
10
-
11
- yarn add sofa-api
12
- # or
13
- npm install sofa-api
14
-
15
- ## Getting Started
16
-
17
- The most basic example possible:
18
-
19
- ```ts
20
- import { useSofa } from 'sofa-api';
21
- import express from 'express';
22
-
23
- const app = express();
24
-
25
- app.use(
26
- '/api',
27
- useSofa({
28
- schema,
29
- })
30
- );
31
-
32
- // GET /api/users
33
- // GET /api/messages
34
- ```
35
-
36
- ## How it works
37
-
38
- Sofa takes your GraphQL Schema, looks for available queries, mutations and subscriptions and turns all of that into REST API.
39
-
40
- Given the following schema:
41
-
42
- ```graphql
43
- type Chat {
44
- id: ID
45
- text: String
46
- }
47
-
48
- type Query {
49
- chat(id: ID): Chat
50
- chats: [Chat]
51
- me: Chat
52
- recentChats: [Chat]
53
- }
54
- ```
55
-
56
- Routes that are being generated:
57
-
58
- ```
59
- GET /chat/:id
60
- GET /chats
61
- GET /me
62
- GET /recent-chats
63
- ```
64
-
65
- ### Nested data and idea behind Models
66
-
67
- Sofa treats some types differently than others, those are called Models.
68
-
69
- The idea behind Models is to not expose full objects in every response, especially if it's a nested, not first-level data.
70
-
71
- For example, when fetching a list of chats you don't want to include all messages in the response, you want them to be just IDs (or links). Those messages would have to have their own endpoint. We call this type of data, a Model. In REST you probably call them Resources.
72
-
73
- In order to treat particular types as Models you need to provide two queries, one that exposes a list (with no non-optional arguments) and the other to fetch a single entity (id field as an argument). The model itself has to have an `id` field. Those are the only requirements.
74
-
75
- ```graphql
76
- # Message is treated as a Model
77
- type Query {
78
- messages: [Message]
79
- message(id: ID): Message
80
- }
81
-
82
- type Message {
83
- id: ID
84
- # other fields ...
85
- }
86
- ```
87
-
88
- ### Provide a Context
89
-
90
- In order for Sofa to resolve operations based on a Context, you need te be able to provide some. Here's how you do it:
91
-
92
- ```ts
93
- api.use(
94
- '/api',
95
- useSofa({
96
- schema,
97
- async context({ req }) {
98
- return {
99
- req,
100
- ...yourContext,
101
- };
102
- },
103
- })
104
- );
105
- ```
106
-
107
- > You can pass a plain object or a function.
108
-
109
- ### Use full responses instead of IDs
110
-
111
- There are some cases where sending a full object makes more sense than passing only the ID. Sofa allows you to easily define where to ignore the default behavior:
112
-
113
- ```ts
114
- api.use(
115
- '/api',
116
- useSofa({
117
- schema,
118
- ignore: ['Message.author'],
119
- })
120
- );
121
- ```
122
-
123
- Whenever Sofa tries to resolve an author of a message, instead of exposing an ID it will pass whole data.
124
-
125
- > Pattern is easy: `Type.field` or `Type`
126
-
127
- ### Customize endpoint's HTTP Method
128
-
129
- Sofa allows you to cutomize the http method. For example, in case you need `POST` instead of `GET` method in one of your query, you do the following:
130
-
131
- ```typescript
132
- api.use(
133
- '/api',
134
- sofa({
135
- schema,
136
- method: {
137
- 'Query.feed': 'POST',
138
- },
139
- })
140
- );
141
- ```
142
-
143
- When Sofa tries to define a route for `feed` of `Query`, instead of exposing it under `GET` (default for Query type) it will use `POST` method.
144
-
145
- > Pattern is easy: `Type.field` where `Type` is your query or mutation type.
146
-
147
- ### Custom depth limit
148
-
149
- Sofa prevents circular references by default, but only one level deep. In order to change it, set the `depthLimit` option to any number:
150
-
151
- ```ts
152
- api.use(
153
- '/api',
154
- useSofa({
155
- schema,
156
- depthLimit: 2,
157
- })
158
- );
159
- ```
160
-
161
- ### Custom execute phase
162
-
163
- By default, Sofa uses `graphql` function from `graphql-js` to turn an operation into data but it's very straightforward to pass your own logic. Thanks to that you can even use a remote GraphQL Server (with Fetch or through Apollo Links).
164
-
165
- ```ts
166
- api.use(
167
- '/api',
168
- useSofa({
169
- schema,
170
- async execute(args) {
171
- return yourOwnLogicHere(args);
172
- },
173
- })
174
- );
175
- ```
176
-
177
- ### Subscriptions as webhooks
178
-
179
- Sofa enables you to run GraphQL Subscriptions through WebHooks. It has a special API to start, update and stop a subscription.
180
-
181
- - `POST /webhook` - stars a subscription
182
- - `DELETE /webhook/:id` - stops it
183
- - `POST /webhook/:id`- updates it
184
-
185
- #### Starting a subscription
186
-
187
- To start a new subscription you need to include following data in request's body:
188
-
189
- - `subscription` - subscription's name, matches the name in GraphQL Schema
190
- - `variables` - variables passed to run a subscription (optional)
191
- - `url` - an url of your webhook receiving endpoint
192
-
193
- After sending it to `POST /webhook` you're going to get in return a unique ID that is your started subscription's identifier.
194
-
195
- ```json
196
- {
197
- "id": "SUBSCRIPTION-UNIQUE-ID"
198
- }
199
- ```
200
-
201
- #### Stoping a subscription
202
-
203
- In order to stop a subscription, you need to pass its id and hit `DELETE /webhook/:id`.
204
-
205
- #### Updating a subscription
206
-
207
- Updating a subscription looks very similar to how you start one. Your request's body should contain:
208
-
209
- - `variables` - variables passed to run a subscription (optional)
210
-
211
- After sending it to `POST /webhook/:id` you're going to get in return a new ID:
212
-
213
- ```json
214
- {
215
- "id": "SUBSCRIPTION-UNIQUE-ID"
216
- }
217
- ```
218
-
219
- #### Example
220
-
221
- Given the following schema:
222
-
223
- ```graphql
224
- type Subscription {
225
- onBook: Book
226
- }
227
- ```
228
-
229
- Let's start a subscription by sending that to `POST /webhook`:
230
-
231
- ```json
232
- {
233
- "subscription": "onBook",
234
- "variables": {},
235
- "url": "https://app.com/new-book"
236
- }
237
- ```
238
-
239
- In return we get an `id` that we later on use to stop or update subscription:
240
-
241
- DELETE /webhook/:id
242
-
243
- ### OpenAPI and Swagger
244
-
245
- Thanks to GraphQL's Type System Sofa is able to generate OpenAPI (Swagger) definitions out of it. Possibilities are endless here. You get all the information you need in order to write your own definitions or create a plugin that follows any specification.
246
-
247
- ```ts
248
- import { useSofa, OpenAPI } from 'sofa-api';
249
-
250
- const openApi = OpenAPI({
251
- schema,
252
- info: {
253
- title: 'Example API',
254
- version: '3.0.0',
255
- },
256
- });
257
-
258
- app.use(
259
- '/api',
260
- useSofa({
261
- schema,
262
- onRoute(info) {
263
- openApi.addRoute(info, {
264
- basePath: '/api',
265
- });
266
- },
267
- })
268
- );
269
-
270
- // writes every recorder route
271
- openApi.save('./swagger.yml');
272
- ```
273
-
274
- ## License
275
-
276
- [MIT](https://github.com/Urigo/sofa/blob/master/LICENSE) © Uri Goldshtein
package/dist/ast.js DELETED
@@ -1,16 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const graphql_1 = require("graphql");
4
- function getOperationInfo(doc) {
5
- const op = graphql_1.getOperationAST(doc, null);
6
- if (!op) {
7
- return;
8
- }
9
- return {
10
- operation: op,
11
- name: op.name.value,
12
- variables: op.variableDefinitions || [],
13
- };
14
- }
15
- exports.getOperationInfo = getOperationInfo;
16
- //# sourceMappingURL=ast.js.map
package/dist/ast.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"ast.js","sourceRoot":"","sources":["../src/ast.ts"],"names":[],"mappings":";;AAAA,qCAKiB;AAUjB,SAAgB,gBAAgB,CAAC,GAAiB;IAChD,MAAM,EAAE,GAAG,yBAAe,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAEtC,IAAI,CAAC,EAAE,EAAE;QACP,OAAO;KACR;IAED,OAAO;QACL,SAAS,EAAE,EAAE;QACb,IAAI,EAAE,EAAE,CAAC,IAAK,CAAC,KAAK;QACpB,SAAS,EAAE,EAAE,CAAC,mBAAmB,IAAI,EAAE;KACxC,CAAC;AACJ,CAAC;AAZD,4CAYC","sourcesContent":["import {\n getOperationAST,\n DocumentNode,\n OperationDefinitionNode,\n VariableDefinitionNode,\n} from 'graphql';\n\nexport type OperationInfo =\n | {\n operation: OperationDefinitionNode;\n variables: ReadonlyArray<VariableDefinitionNode>;\n name: string;\n }\n | undefined;\n\nexport function getOperationInfo(doc: DocumentNode): OperationInfo {\n const op = getOperationAST(doc, null);\n\n if (!op) {\n return;\n }\n\n return {\n operation: op,\n name: op.name!.value,\n variables: op.variableDefinitions || [],\n };\n}\n"]}
package/dist/common.js DELETED
@@ -1,8 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const changeCase = require("change-case");
4
- function convertName(name) {
5
- return changeCase.param(name);
6
- }
7
- exports.convertName = convertName;
8
- //# sourceMappingURL=common.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"common.js","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":";;AAAA,0CAA0C;AAE1C,SAAgB,WAAW,CAAC,IAAY;IACtC,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC;AAFD,kCAEC","sourcesContent":["import * as changeCase from 'change-case';\n\nexport function convertName(name: string) {\n return changeCase.param(name);\n}\n"]}
package/dist/express.d.ts DELETED
@@ -1,5 +0,0 @@
1
- import * as express from 'express';
2
- import { Sofa } from './sofa';
3
- export declare type ErrorHandler = (res: express.Response, errors: ReadonlyArray<any>) => void;
4
- export declare type ExpressMethod = 'get' | 'post' | 'put' | 'delete' | 'patch';
5
- export declare function createRouter(sofa: Sofa): express.Router;
package/dist/express.js DELETED
@@ -1,226 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- const express = require("express");
13
- const graphql_1 = require("graphql");
14
- const operation_1 = require("./operation");
15
- const ast_1 = require("./ast");
16
- const sofa_1 = require("./sofa");
17
- const common_1 = require("./common");
18
- const parse_1 = require("./parse");
19
- const subscriptions_1 = require("./subscriptions");
20
- const logger_1 = require("./logger");
21
- function createRouter(sofa) {
22
- logger_1.logger.debug('[Sofa] Creating router');
23
- const router = express.Router();
24
- const queryType = sofa.schema.getQueryType();
25
- const mutationType = sofa.schema.getMutationType();
26
- const subscriptionManager = new subscriptions_1.SubscriptionManager(sofa);
27
- if (queryType) {
28
- Object.keys(queryType.getFields()).forEach(fieldName => {
29
- const route = createQueryRoute({ sofa, router, fieldName });
30
- if (sofa.onRoute) {
31
- sofa.onRoute(route);
32
- }
33
- });
34
- }
35
- if (mutationType) {
36
- Object.keys(mutationType.getFields()).forEach(fieldName => {
37
- const route = createMutationRoute({ sofa, router, fieldName });
38
- if (sofa.onRoute) {
39
- sofa.onRoute(route);
40
- }
41
- });
42
- }
43
- router.post('/webhook', useAsync((req, res) => __awaiter(this, void 0, void 0, function* () {
44
- const { subscription, variables, url } = req.body;
45
- try {
46
- const result = yield subscriptionManager.start({
47
- subscription,
48
- variables,
49
- url,
50
- }, { req, res });
51
- res.statusCode = 200;
52
- res.statusMessage = 'OK';
53
- res.json(result);
54
- }
55
- catch (e) {
56
- console.log(e);
57
- res.statusCode = 500;
58
- res.statusMessage = 'Subscription failed';
59
- res.json(e);
60
- }
61
- })));
62
- router.post('/webhook/:id', useAsync((req, res) => __awaiter(this, void 0, void 0, function* () {
63
- const id = req.params.id;
64
- const variables = req.body.variables;
65
- try {
66
- const result = yield subscriptionManager.update({
67
- id,
68
- variables,
69
- }, {
70
- req,
71
- res,
72
- });
73
- res.statusCode = 200;
74
- res.statusMessage = 'OK';
75
- res.json(result);
76
- }
77
- catch (e) {
78
- console.log(e);
79
- res.statusCode = 500;
80
- res.statusMessage = 'Subscription failed to update';
81
- res.json(e);
82
- }
83
- })));
84
- router.delete('/webhook/:id', useAsync((req, res) => __awaiter(this, void 0, void 0, function* () {
85
- const id = req.params.id;
86
- try {
87
- const result = yield subscriptionManager.stop(id);
88
- res.statusCode = 200;
89
- res.statusMessage = 'OK';
90
- res.json(result);
91
- }
92
- catch (e) {
93
- console.log(e);
94
- res.statusCode = 500;
95
- res.statusMessage = 'Subscription failed to stop';
96
- res.json(e);
97
- }
98
- })));
99
- return router;
100
- }
101
- exports.createRouter = createRouter;
102
- function createQueryRoute({ sofa, router, fieldName, }) {
103
- logger_1.logger.debug(`[Router] Creating ${fieldName} query`);
104
- const queryType = sofa.schema.getQueryType();
105
- const operation = operation_1.buildOperation({
106
- kind: 'query',
107
- schema: sofa.schema,
108
- field: fieldName,
109
- models: sofa.models,
110
- ignore: sofa.ignore,
111
- });
112
- const info = ast_1.getOperationInfo(operation);
113
- const field = queryType.getFields()[fieldName];
114
- const fieldType = field.type;
115
- const isSingle = graphql_1.isObjectType(fieldType) ||
116
- (graphql_1.isNonNullType(fieldType) && graphql_1.isObjectType(fieldType.ofType));
117
- const hasIdArgument = field.args.some(arg => arg.name === 'id');
118
- const path = getPath(fieldName, isSingle && hasIdArgument);
119
- const method = produceMethod({
120
- typeName: queryType.name,
121
- fieldName,
122
- methodMap: sofa.method,
123
- defaultValue: 'GET',
124
- });
125
- router[method.toLocaleLowerCase()](path, useHandler({ info, fieldName, sofa, operation }));
126
- logger_1.logger.debug(`[Router] ${fieldName} query available at ${method} ${path}`);
127
- return {
128
- document: operation,
129
- path,
130
- method: method.toUpperCase(),
131
- };
132
- }
133
- function createMutationRoute({ sofa, router, fieldName, }) {
134
- logger_1.logger.debug(`[Router] Creating ${fieldName} mutation`);
135
- const mutationType = sofa.schema.getMutationType();
136
- const operation = operation_1.buildOperation({
137
- kind: 'mutation',
138
- schema: sofa.schema,
139
- field: fieldName,
140
- models: sofa.models,
141
- ignore: sofa.ignore,
142
- });
143
- const info = ast_1.getOperationInfo(operation);
144
- const path = getPath(fieldName);
145
- const method = produceMethod({
146
- typeName: mutationType.name,
147
- fieldName,
148
- methodMap: sofa.method,
149
- defaultValue: 'POST',
150
- });
151
- router[method.toLowerCase()](path, useHandler({ info, fieldName, sofa, operation }));
152
- logger_1.logger.debug(`[Router] ${fieldName} mutation available at ${method} ${path}`);
153
- return {
154
- document: operation,
155
- path,
156
- method: method.toUpperCase(),
157
- };
158
- }
159
- function useHandler(config) {
160
- const { sofa, operation, fieldName } = config;
161
- const info = config.info;
162
- return useAsync((req, res) => __awaiter(this, void 0, void 0, function* () {
163
- const variableValues = info.variables.reduce((variables, variable) => {
164
- const name = variable.variable.name.value;
165
- const value = parse_1.parseVariable({
166
- value: pickParam(req, name),
167
- variable,
168
- schema: sofa.schema,
169
- });
170
- if (typeof value === 'undefined') {
171
- return variables;
172
- }
173
- return Object.assign(Object.assign({}, variables), { [name]: value });
174
- }, {});
175
- const contextValue = sofa_1.isContextFn(sofa.context)
176
- ? yield sofa.context({ req, res })
177
- : sofa.context;
178
- const result = yield sofa.execute({
179
- schema: sofa.schema,
180
- source: graphql_1.print(operation),
181
- contextValue,
182
- variableValues,
183
- operationName: info.operation.name && info.operation.name.value,
184
- });
185
- if (result.errors) {
186
- const defaultErrorHandler = (res, errors) => {
187
- res.status(500);
188
- res.json(errors[0]);
189
- };
190
- const errorHandler = sofa.errorHandler || defaultErrorHandler;
191
- errorHandler(res, result.errors);
192
- return;
193
- }
194
- res.json(result.data && result.data[fieldName]);
195
- }));
196
- }
197
- function getPath(fieldName, hasId = false) {
198
- return `/${common_1.convertName(fieldName)}${hasId ? '/:id' : ''}`;
199
- }
200
- function pickParam(req, name) {
201
- if (req.params && req.params[name]) {
202
- return req.params[name];
203
- }
204
- if (req.query && req.query[name]) {
205
- return req.query[name];
206
- }
207
- if (req.body && req.body[name]) {
208
- return req.body[name];
209
- }
210
- }
211
- function useAsync(handler) {
212
- return (req, res, next) => {
213
- Promise.resolve(handler(req, res, next)).catch(e => {
214
- console.log(e);
215
- next(e);
216
- });
217
- };
218
- }
219
- function produceMethod({ typeName, fieldName, methodMap, defaultValue, }) {
220
- const path = `${typeName}.${fieldName}`;
221
- if (methodMap && methodMap[path]) {
222
- return methodMap[path];
223
- }
224
- return defaultValue;
225
- }
226
- //# sourceMappingURL=express.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"express.js","sourceRoot":"","sources":["../src/express.ts"],"names":[],"mappings":"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","sourcesContent":["import * as express from 'express';\nimport { DocumentNode, print, isObjectType, isNonNullType } from 'graphql';\n\nimport { buildOperation } from './operation';\nimport { getOperationInfo, OperationInfo } from './ast';\nimport { Sofa, isContextFn } from './sofa';\nimport { RouteInfo, Method, MethodMap } from './types';\nimport { convertName } from './common';\nimport { parseVariable } from './parse';\nimport { StartSubscriptionEvent, SubscriptionManager } from './subscriptions';\nimport { logger } from './logger';\n\nexport type ErrorHandler = (\n res: express.Response,\n errors: ReadonlyArray<any>\n) => void;\n\nexport type ExpressMethod = 'get' | 'post' | 'put' | 'delete' | 'patch';\n\nexport function createRouter(sofa: Sofa): express.Router {\n logger.debug('[Sofa] Creating router');\n\n const router = express.Router();\n\n const queryType = sofa.schema.getQueryType();\n const mutationType = sofa.schema.getMutationType();\n const subscriptionManager = new SubscriptionManager(sofa);\n\n if (queryType) {\n Object.keys(queryType.getFields()).forEach(fieldName => {\n const route = createQueryRoute({ sofa, router, fieldName });\n\n if (sofa.onRoute) {\n sofa.onRoute(route);\n }\n });\n }\n\n if (mutationType) {\n Object.keys(mutationType.getFields()).forEach(fieldName => {\n const route = createMutationRoute({ sofa, router, fieldName });\n\n if (sofa.onRoute) {\n sofa.onRoute(route);\n }\n });\n }\n\n router.post(\n '/webhook',\n useAsync(async (req, res) => {\n const { subscription, variables, url }: StartSubscriptionEvent = req.body;\n\n try {\n const result = await subscriptionManager.start(\n {\n subscription,\n variables,\n url,\n },\n { req, res }\n );\n\n res.statusCode = 200;\n res.statusMessage = 'OK';\n res.json(result);\n } catch (e) {\n console.log(e);\n res.statusCode = 500;\n res.statusMessage = 'Subscription failed';\n res.json(e);\n }\n })\n );\n\n router.post(\n '/webhook/:id',\n useAsync(async (req, res) => {\n const id: string = req.params.id;\n const variables: any = req.body.variables;\n\n try {\n const result = await subscriptionManager.update(\n {\n id,\n variables,\n },\n {\n req,\n res,\n }\n );\n\n res.statusCode = 200;\n res.statusMessage = 'OK';\n res.json(result);\n } catch (e) {\n console.log(e);\n res.statusCode = 500;\n res.statusMessage = 'Subscription failed to update';\n res.json(e);\n }\n })\n );\n\n router.delete(\n '/webhook/:id',\n useAsync(async (req, res) => {\n const id: string = req.params.id;\n\n try {\n const result = await subscriptionManager.stop(id);\n\n res.statusCode = 200;\n res.statusMessage = 'OK';\n res.json(result);\n } catch (e) {\n console.log(e);\n res.statusCode = 500;\n res.statusMessage = 'Subscription failed to stop';\n res.json(e);\n }\n })\n );\n\n return router;\n}\n\nfunction createQueryRoute({\n sofa,\n router,\n fieldName,\n}: {\n sofa: Sofa;\n router: express.Router;\n fieldName: string;\n}): RouteInfo {\n logger.debug(`[Router] Creating ${fieldName} query`);\n\n const queryType = sofa.schema.getQueryType()!;\n const operation = buildOperation({\n kind: 'query',\n schema: sofa.schema,\n field: fieldName,\n models: sofa.models,\n ignore: sofa.ignore,\n });\n const info = getOperationInfo(operation)!;\n const field = queryType.getFields()[fieldName];\n const fieldType = field.type;\n const isSingle =\n isObjectType(fieldType) ||\n (isNonNullType(fieldType) && isObjectType(fieldType.ofType));\n const hasIdArgument = field.args.some(arg => arg.name === 'id');\n const path = getPath(fieldName, isSingle && hasIdArgument);\n\n const method = produceMethod({\n typeName: queryType.name,\n fieldName,\n methodMap: sofa.method,\n defaultValue: 'GET',\n });\n\n router[method.toLocaleLowerCase() as ExpressMethod](\n path,\n useHandler({ info, fieldName, sofa, operation })\n );\n\n logger.debug(`[Router] ${fieldName} query available at ${method} ${path}`);\n\n return {\n document: operation,\n path,\n method: method.toUpperCase() as Method,\n };\n}\n\nfunction createMutationRoute({\n sofa,\n router,\n fieldName,\n}: {\n sofa: Sofa;\n router: express.Router;\n fieldName: string;\n}): RouteInfo {\n logger.debug(`[Router] Creating ${fieldName} mutation`);\n\n const mutationType = sofa.schema.getMutationType()!;\n const operation = buildOperation({\n kind: 'mutation',\n schema: sofa.schema,\n field: fieldName,\n models: sofa.models,\n ignore: sofa.ignore,\n });\n const info = getOperationInfo(operation)!;\n const path = getPath(fieldName);\n\n const method = produceMethod({\n typeName: mutationType.name,\n fieldName,\n methodMap: sofa.method,\n defaultValue: 'POST',\n });\n\n router[method.toLowerCase() as ExpressMethod](\n path,\n useHandler({ info, fieldName, sofa, operation })\n );\n\n logger.debug(`[Router] ${fieldName} mutation available at ${method} ${path}`);\n\n return {\n document: operation,\n path,\n method: method.toUpperCase() as Method,\n };\n}\n\nfunction useHandler(config: {\n sofa: Sofa;\n info: OperationInfo;\n operation: DocumentNode;\n fieldName: string;\n}) {\n const { sofa, operation, fieldName } = config;\n const info = config.info!;\n\n return useAsync(async (req: express.Request, res: express.Response) => {\n const variableValues = info.variables.reduce((variables, variable) => {\n const name = variable.variable.name.value;\n const value = parseVariable({\n value: pickParam(req, name),\n variable,\n schema: sofa.schema,\n });\n\n if (typeof value === 'undefined') {\n return variables;\n }\n\n return {\n ...variables,\n [name]: value,\n };\n }, {});\n\n const contextValue = isContextFn(sofa.context)\n ? await sofa.context({ req, res })\n : sofa.context;\n\n const result = await sofa.execute({\n schema: sofa.schema,\n source: print(operation),\n contextValue,\n variableValues,\n operationName: info.operation.name && info.operation.name.value,\n });\n\n if (result.errors) {\n const defaultErrorHandler: ErrorHandler = (res, errors) => {\n res.status(500);\n res.json(errors[0]);\n };\n const errorHandler: ErrorHandler =\n sofa.errorHandler || defaultErrorHandler;\n errorHandler(res, result.errors);\n return;\n }\n\n res.json(result.data && result.data[fieldName]);\n });\n}\n\nfunction getPath(fieldName: string, hasId = false) {\n return `/${convertName(fieldName)}${hasId ? '/:id' : ''}`;\n}\n\nfunction pickParam(req: express.Request, name: string) {\n if (req.params && req.params[name]) {\n return req.params[name];\n }\n\n if (req.query && req.query[name]) {\n return req.query[name];\n }\n\n if (req.body && req.body[name]) {\n return req.body[name];\n }\n}\n\nfunction useAsync<T = any>(\n handler: (\n req: express.Request,\n res: express.Response,\n next: express.NextFunction\n ) => Promise<T>\n) {\n return (\n req: express.Request,\n res: express.Response,\n next: express.NextFunction\n ) => {\n Promise.resolve(handler(req, res, next)).catch(e => {\n console.log(e);\n next(e);\n });\n };\n}\n\nfunction produceMethod({\n typeName,\n fieldName,\n methodMap,\n defaultValue,\n}: {\n typeName: string;\n fieldName: string;\n methodMap?: MethodMap;\n defaultValue: Method;\n}): Method {\n const path = `${typeName}.${fieldName}`;\n\n if (methodMap && methodMap[path]) {\n return methodMap[path];\n }\n\n return defaultValue;\n}\n"]}
package/dist/index.js DELETED
@@ -1,13 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const express_1 = require("./express");
4
- const sofa_1 = require("./sofa");
5
- exports.createSofa = sofa_1.createSofa;
6
- var open_api_1 = require("./open-api");
7
- exports.OpenAPI = open_api_1.OpenAPI;
8
- function useSofa(config) {
9
- return express_1.createRouter(sofa_1.createSofa(config));
10
- }
11
- exports.useSofa = useSofa;
12
- exports.default = useSofa;
13
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAEA,uCAAyC;AACzC,iCAAgD;AAQ9B,qBARG,iBAAU,CAQH;AAN5B,uCAAqC;AAA5B,6BAAA,OAAO,CAAA;AAEhB,SAAS,OAAO,CAAC,MAAkB;IACjC,OAAO,sBAAY,CAAC,iBAAU,CAAC,MAAM,CAAC,CAAC,CAAC;AAC1C,CAAC;AAEQ,0BAAO;AAChB,kBAAe,OAAO,CAAC","sourcesContent":["import * as express from 'express';\n\nimport { createRouter } from './express';\nimport { SofaConfig, createSofa } from './sofa';\n\nexport { OpenAPI } from './open-api';\n\nfunction useSofa(config: SofaConfig): express.Router {\n return createRouter(createSofa(config));\n}\n\nexport { useSofa, createSofa };\nexport default useSofa;\n"]}
package/dist/logger.js DELETED
@@ -1,8 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const winston_1 = require("winston");
4
- exports.logger = winston_1.createLogger({
5
- transports: [new winston_1.transports.Console()],
6
- format: winston_1.format.combine(winston_1.format.colorize(), winston_1.format.simple()),
7
- });
8
- //# sourceMappingURL=logger.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":";;AAAA,qCAA2D;AAE9C,QAAA,MAAM,GAAG,sBAAY,CAAC;IACjC,UAAU,EAAE,CAAC,IAAI,oBAAU,CAAC,OAAO,EAAE,CAAC;IACtC,MAAM,EAAE,gBAAM,CAAC,OAAO,CAAC,gBAAM,CAAC,QAAQ,EAAE,EAAE,gBAAM,CAAC,MAAM,EAAE,CAAC;CAC3D,CAAC,CAAC","sourcesContent":["import { createLogger, transports, format } from 'winston';\n\nexport const logger = createLogger({\n transports: [new transports.Console()],\n format: format.combine(format.colorize(), format.simple()),\n});\n"]}
@@ -1,67 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const graphql_1 = require("graphql");
4
- const YAML = require("yamljs");
5
- const fs_1 = require("fs");
6
- const types_1 = require("./types");
7
- const operations_1 = require("./operations");
8
- function OpenAPI({ schema, info, }) {
9
- const types = schema.getTypeMap();
10
- const swagger = {
11
- openapi: '3.0.0',
12
- info,
13
- paths: {},
14
- components: {
15
- schemas: {},
16
- },
17
- };
18
- for (const typeName in types) {
19
- const type = types[typeName];
20
- if ((graphql_1.isObjectType(type) || graphql_1.isInputObjectType(type)) &&
21
- !graphql_1.isIntrospectionType(type)) {
22
- swagger.components.schemas[typeName] = types_1.buildSchemaObjectFromType(type);
23
- }
24
- }
25
- return {
26
- addRoute(info, config) {
27
- const basePath = (config && config.basePath) || '';
28
- const path = basePath +
29
- info.path.replace(/\:[a-z0-9]+\w/i, param => `{${param.replace(':', '')}}`);
30
- if (!swagger.paths[path]) {
31
- swagger.paths[path] = {};
32
- }
33
- swagger.paths[path][info.method.toLowerCase()] = operations_1.buildPathFromOperation({
34
- url: path,
35
- operation: info.document,
36
- schema,
37
- useRequestBody: ['POST', 'PUT', 'PATCH'].includes(info.method),
38
- });
39
- swagger.components.schemas.ID = {
40
- type: 'string',
41
- };
42
- },
43
- get() {
44
- return swagger;
45
- },
46
- save(filepath) {
47
- const isJSON = /\.json$/i;
48
- const isYAML = /.ya?ml$/i;
49
- if (isJSON.test(filepath)) {
50
- writeOutput(filepath, JSON.stringify(swagger, null, 2));
51
- }
52
- else if (isYAML.test(filepath)) {
53
- writeOutput(filepath, YAML.stringify(swagger, Infinity));
54
- }
55
- else {
56
- throw new Error('We only support JSON and YAML files');
57
- }
58
- },
59
- };
60
- }
61
- exports.OpenAPI = OpenAPI;
62
- function writeOutput(filepath, contents) {
63
- fs_1.writeFileSync(filepath, contents, {
64
- encoding: 'utf-8',
65
- });
66
- }
67
- //# sourceMappingURL=index.js.map