@orion-js/graphql 2.2.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 (34) hide show
  1. package/LICENSE +21 -0
  2. package/lib/buildSchema/getArgs/getField.js +61 -0
  3. package/lib/buildSchema/getArgs/index.js +34 -0
  4. package/lib/buildSchema/getMutation.js +30 -0
  5. package/lib/buildSchema/getQuery.js +30 -0
  6. package/lib/buildSchema/getResolvers/index.js +65 -0
  7. package/lib/buildSchema/getSubscription.js +27 -0
  8. package/lib/buildSchema/getSubscriptions/index.js +42 -0
  9. package/lib/buildSchema/getType/BigIntScalar.js +53 -0
  10. package/lib/buildSchema/getType/DateScalar.js +19 -0
  11. package/lib/buildSchema/getType/JSONScalar.js +58 -0
  12. package/lib/buildSchema/getType/getScalar.js +45 -0
  13. package/lib/buildSchema/getType/getTypeAsResolver.js +42 -0
  14. package/lib/buildSchema/getType/index.js +85 -0
  15. package/lib/buildSchema/index.js +29 -0
  16. package/lib/errorHandler.js +31 -0
  17. package/lib/getApolloOptions/formatError.js +22 -0
  18. package/lib/getApolloOptions/index.js +27 -0
  19. package/lib/index.js +70 -0
  20. package/lib/pubsub.js +19 -0
  21. package/lib/resolversSchemas/ResolverParams.js +53 -0
  22. package/lib/resolversSchemas/getBasicResultQuery.js +28 -0
  23. package/lib/resolversSchemas/getField.js +54 -0
  24. package/lib/resolversSchemas/getField.test.js +30 -0
  25. package/lib/resolversSchemas/index.js +15 -0
  26. package/lib/resolversSchemas/params.js +46 -0
  27. package/lib/resolversSchemas/serializeSchema.js +23 -0
  28. package/lib/resolversSchemas/serializeSchema.test.js +30 -0
  29. package/lib/startGraphQL.js +73 -0
  30. package/lib/startGraphiQL.js +211 -0
  31. package/lib/startWebsocket.js +61 -0
  32. package/lib/subscription/getChannelName.js +21 -0
  33. package/lib/subscription/index.js +52 -0
  34. package/package.json +41 -0
@@ -0,0 +1,211 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = _default;
7
+
8
+ var _app = require("@orion-js/app");
9
+
10
+ // Ensures string values are safe to be used within a <script> tag.
11
+ // TODO: I don't think that's the right escape function
12
+ function safeSerialize(data) {
13
+ return data ? JSON.stringify(data).replace(/\//g, '\\/') : null;
14
+ }
15
+
16
+ const getHTML = function (apolloOptions, options, data) {
17
+ // Current latest version of GraphiQL.
18
+ const GRAPHIQL_VERSION = '0.11.11';
19
+ const {
20
+ endpointURL,
21
+ subscriptionsEndpoint
22
+ } = apolloOptions;
23
+ const queryString = data.query;
24
+ const variablesString = data.variables ? JSON.stringify(data.variables, null, 2) : null;
25
+ const operationName = data.operationName;
26
+ const useSubs = !!options.subscriptions;
27
+ return `
28
+ <!DOCTYPE html>
29
+ <html>
30
+ <head>
31
+ <meta charset="utf-8" />
32
+ <title>GraphiQL</title>
33
+ <meta name="robots" content="noindex" />
34
+ <style>
35
+ html, body {
36
+ height: 100%;
37
+ margin: 0;
38
+ overflow: hidden;
39
+ width: 100%;
40
+ }
41
+ </style>
42
+ <link href="//unpkg.com/graphiql@${GRAPHIQL_VERSION}/graphiql.css" rel="stylesheet" />
43
+ <script src="//unpkg.com/react@15.6.1/dist/react.min.js"></script>
44
+ <script src="//unpkg.com/jssha@2.3.1/src/sha512.js"></script>
45
+ <script src="//unpkg.com/react-dom@15.6.1/dist/react-dom.min.js"></script>
46
+ <script src="//unpkg.com/graphiql@${GRAPHIQL_VERSION}/graphiql.min.js"></script>
47
+ <script src="//cdn.jsdelivr.net/fetch/2.0.1/fetch.min.js"></script>
48
+ ${useSubs ? `<script src="//unpkg.com/subscriptions-transport-ws@0.5.4/browser/client.js"></script>
49
+ <script src="//unpkg.com/graphiql-subscriptions-fetcher@0.0.2/browser/client.js"></script>` : ''}
50
+ </head>
51
+ <body>
52
+ <script>
53
+ // Collect the URL parameters
54
+ var parameters = {};
55
+ window.location.search.substr(1).split('&').forEach(function (entry) {
56
+ var eq = entry.indexOf('=');
57
+ if (eq >= 0) {
58
+ parameters[decodeURIComponent(entry.slice(0, eq))] =
59
+ decodeURIComponent(entry.slice(eq + 1));
60
+ }
61
+ });
62
+ // Produce a Location query string from a parameter object.
63
+ function locationQuery(params, location) {
64
+ return (location ? location: '') + '?' + Object.keys(params).map(function (key) {
65
+ return encodeURIComponent(key) + '=' +
66
+ encodeURIComponent(params[key]);
67
+ }).join('&');
68
+ }
69
+ // Derive a fetch URL from the current URL, sans the GraphQL parameters.
70
+ var graphqlParamNames = {
71
+ query: true,
72
+ variables: true,
73
+ operationName: true
74
+ };
75
+ var otherParams = {};
76
+ for (var k in parameters) {
77
+ if (parameters.hasOwnProperty(k) && graphqlParamNames[k] !== true) {
78
+ otherParams[k] = parameters[k];
79
+ }
80
+ }
81
+ // We don't use safe-serialize for location, because it's not client input.
82
+ var fetchURL = '${endpointURL}'
83
+ // Defines a GraphQL fetcher using the fetch API.
84
+ function graphQLHttpFetcher(graphQLParams) {
85
+ const body = JSON.stringify(graphQLParams)
86
+ const headers = {
87
+ 'Accept': 'application/json',
88
+ 'Content-Type': 'application/json',
89
+ }
90
+ const publicKey = localStorage.getItem('GraphiQL:publicKey')
91
+ const secretKey = localStorage.getItem('GraphiQL:secretKey')
92
+ if (publicKey && secretKey) {
93
+ const nonce = new Date().getTime()
94
+ const shaObj = new jsSHA('SHA-512', 'TEXT')
95
+ shaObj.setHMACKey(secretKey, 'TEXT')
96
+ shaObj.update(nonce + body)
97
+ const signature = shaObj.getHMAC('HEX')
98
+ headers['X-ORION-NONCE'] = nonce
99
+ headers['X-ORION-PUBLICKEY'] = publicKey
100
+ headers['X-ORION-SIGNATURE'] = signature
101
+ }
102
+ return fetch(fetchURL, {
103
+ method: 'post',
104
+ headers,
105
+ body,
106
+ credentials: 'same-origin',
107
+ }).then(function (response) {
108
+ return response.text();
109
+ }).then(function (responseBody) {
110
+ try {
111
+ const json = JSON.parse(responseBody);
112
+ if (json.data && json.data.loginWithPassword) {
113
+ const publicKey = json.data.loginWithPassword.publicKey
114
+ const secretKey = json.data.loginWithPassword.secretKey
115
+ if (publicKey && secretKey) {
116
+ localStorage.setItem('GraphiQL:publicKey', publicKey)
117
+ localStorage.setItem('GraphiQL:secretKey', secretKey)
118
+ alert('Session saved in localStorage')
119
+ }
120
+ }
121
+ if (json.error && json.error === 'AuthError') {
122
+ localStorage.setItem('GraphiQL:publicKey', '')
123
+ localStorage.setItem('GraphiQL:secretKey', '')
124
+ alert('Logged out after receiving AuthError')
125
+ }
126
+ return json
127
+ } catch (error) {
128
+ return responseBody;
129
+ }
130
+ });
131
+ }
132
+ ${useSubs ? `
133
+ let params = {}
134
+ const publicKey = localStorage.getItem('GraphiQL:publicKey')
135
+ const secretKey = localStorage.getItem('GraphiQL:secretKey')
136
+ if (publicKey && secretKey) {
137
+ const nonce = new Date().getTime() + 500
138
+ const shaObj = new jsSHA('SHA-512', 'TEXT')
139
+ shaObj.setHMACKey(secretKey, 'TEXT')
140
+ shaObj.update(nonce + 'websockethandshake')
141
+ const signature = shaObj.getHMAC('HEX')
142
+ params = {
143
+ nonce,
144
+ publicKey,
145
+ signature
146
+ }
147
+ }
148
+
149
+ const protocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://'
150
+ let subscriptionsClient = new window.SubscriptionsTransportWs.SubscriptionClient(protocol + window.location.host + '${subscriptionsEndpoint}', {
151
+ reconnect: true,
152
+ connectionParams: params
153
+ });
154
+ let myCustomFetcher = window.GraphiQLSubscriptionsFetcher.graphQLFetcher(subscriptionsClient, graphQLHttpFetcher);
155
+ var fetcher = myCustomFetcher
156
+ ` : `
157
+ var fetcher = graphQLHttpFetcher
158
+ `}
159
+
160
+ // When the query and variables string is edited, update the URL bar so
161
+ // that it can be easily shared.
162
+ function onEditQuery(newQuery) {
163
+ parameters.query = newQuery;
164
+ updateURL();
165
+ }
166
+ function onEditVariables(newVariables) {
167
+ parameters.variables = newVariables;
168
+ updateURL();
169
+ }
170
+ function onEditOperationName(newOperationName) {
171
+ parameters.operationName = newOperationName;
172
+ updateURL();
173
+ }
174
+ function updateURL() {
175
+ var cleanParams = Object.keys(parameters).filter(function(v) {
176
+ return parameters[v];
177
+ }).reduce(function(old, v) {
178
+ old[v] = parameters[v];
179
+ return old;
180
+ }, {});
181
+ history.replaceState(null, null, locationQuery(cleanParams) + window.location.hash);
182
+ }
183
+ // Render <GraphiQL /> into the body.
184
+ ReactDOM.render(
185
+ React.createElement(GraphiQL, {
186
+ fetcher: fetcher,
187
+ onEditQuery: onEditQuery,
188
+ onEditVariables: onEditVariables,
189
+ onEditOperationName: onEditOperationName,
190
+ query: ${safeSerialize(queryString)},
191
+ response: null,
192
+ variables: ${safeSerialize(variablesString)},
193
+ operationName: ${safeSerialize(operationName)},
194
+ }),
195
+ document.body
196
+ );
197
+ </script>
198
+ </body>
199
+ </html>`;
200
+ };
201
+
202
+ function _default(apolloOptions, options) {
203
+ if (options.useGraphiql) {
204
+ (0, _app.route)('/graphiql', async function ({
205
+ query,
206
+ request
207
+ }) {
208
+ return getHTML(apolloOptions, options, query, request);
209
+ });
210
+ }
211
+ }
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = _default;
7
+
8
+ var _app = require("@orion-js/app");
9
+
10
+ var _graphql = require("graphql");
11
+
12
+ var _subscriptionsTransportWs = require("subscriptions-transport-ws");
13
+
14
+ var _graphqlSubscriptions = require("graphql-subscriptions");
15
+
16
+ var _pubsub = require("./pubsub");
17
+
18
+ function _default({
19
+ schema
20
+ }, options) {
21
+ (0, _pubsub.setPubsub)(options.pubsub || new _graphqlSubscriptions.PubSub());
22
+ const server = (0, _app.getServer)();
23
+
24
+ if (!server) {
25
+ throw new Error('Error starting GraphQL WebSocket. You must start http server before starting GraphQL WebSocket');
26
+ }
27
+
28
+ const path = '/subscriptions';
29
+ const subServer = new _subscriptionsTransportWs.SubscriptionServer({
30
+ execute: _graphql.execute,
31
+ subscribe: _graphql.subscribe,
32
+ schema,
33
+
34
+ async onConnect(connectionParams, webSocket) {
35
+ try {
36
+ const params = {
37
+ headers: {
38
+ 'x-orion-nonce': connectionParams.nonce,
39
+ 'x-orion-publickey': connectionParams.publicKey,
40
+ 'x-orion-signature': connectionParams.signature,
41
+ 'x-orion-jwt': connectionParams.jwt
42
+ },
43
+ getBody: () => 'websockethandshake',
44
+ nonceName: 'graphqlsubs'
45
+ };
46
+ const viewer = await (0, _app.getViewer)(params);
47
+ return viewer;
48
+ } catch (error) {
49
+ const viewer = await (0, _app.getViewer)();
50
+ return viewer;
51
+ }
52
+ },
53
+
54
+ onDisconnect() {}
55
+
56
+ }, {
57
+ server,
58
+ path
59
+ });
60
+ return subServer;
61
+ }
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = _default;
9
+
10
+ var _crypto = _interopRequireDefault(require("crypto"));
11
+
12
+ var _deepSortObject = _interopRequireDefault(require("deep-sort-object"));
13
+
14
+ function _default(name, params, viewer) {
15
+ const json = JSON.stringify((0, _deepSortObject.default)(params));
16
+
17
+ const hash = _crypto.default.createHash('sha1').update(json).digest('base64');
18
+
19
+ const channelName = `${name}_${hash}`;
20
+ return channelName;
21
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = _default;
9
+
10
+ var _pubsub = require("../pubsub");
11
+
12
+ var _getChannelName = _interopRequireDefault(require("./getChannelName"));
13
+
14
+ var _app = require("@orion-js/app");
15
+
16
+ function _default(options) {
17
+ const {
18
+ params,
19
+ returns,
20
+ checkPermission,
21
+ ...otherOptions
22
+ } = options; // the publish function
23
+
24
+ const subscription = function publish(params, data) {
25
+ const pubsub = (0, _pubsub.getPubsub)();
26
+ const channelName = (0, _getChannelName.default)(subscription.key, params);
27
+ pubsub.publish(channelName, {
28
+ [subscription.key]: data
29
+ });
30
+ };
31
+
32
+ subscription.subscribe = async function (callParams, viewer) {
33
+ const pubsub = (0, _pubsub.getPubsub)();
34
+
35
+ try {
36
+ await (0, _app.checkResolverPermissions)({
37
+ callParams,
38
+ viewer,
39
+ checkPermission,
40
+ otherOptions
41
+ });
42
+ const channelName = (0, _getChannelName.default)(subscription.key, callParams);
43
+ return pubsub.asyncIterator(channelName);
44
+ } catch (error) {
45
+ return pubsub.asyncIterator('unauthorized');
46
+ }
47
+ };
48
+
49
+ subscription.params = params;
50
+ subscription.returns = returns;
51
+ return subscription;
52
+ }
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@orion-js/graphql",
3
+ "version": "2.2.0",
4
+ "main": "lib/index.js",
5
+ "author": "nicolaslopezj",
6
+ "license": "MIT",
7
+ "scripts": {
8
+ "build": "rm -rf ./lib && babel ./src --out-dir ./lib",
9
+ "prepare": "yarn run build",
10
+ "watch": "rm -rf ./lib && babel ./src --watch --out-dir ./lib",
11
+ "test": "jest"
12
+ },
13
+ "dependencies": {
14
+ "@orion-js/schema": "^2.1.0",
15
+ "apollo-server-core": "^2.16.1",
16
+ "apollo-server-micro": "^2.16.1",
17
+ "deep-sort-object": "^1.0.2",
18
+ "graphql": "^14.4.2",
19
+ "graphql-iso-date": "^3.6.1",
20
+ "graphql-subscriptions": "^1.1.0",
21
+ "lodash": "^4.17.19",
22
+ "subscriptions-transport-ws": "^0.9.17"
23
+ },
24
+ "devDependencies": {
25
+ "@babel/cli": "^7.10.5",
26
+ "@babel/core": "^7.11.1",
27
+ "@babel/plugin-transform-runtime": "^7.11.0",
28
+ "@babel/preset-env": "^7.11.0",
29
+ "@babel/runtime": "^7.11.2",
30
+ "@orion-js/app": "^2.2.0",
31
+ "babel-jest": "^26.2.2",
32
+ "jest": "^26.2.2"
33
+ },
34
+ "peerDependencies": {
35
+ "@orion-js/app": "*"
36
+ },
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
40
+ "gitHead": "d50a4ec7ffc9ee6a5443a4b7b85e80527f988294"
41
+ }