graphql-http 0.2.0 → 1.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.
package/package.json CHANGED
@@ -1,37 +1,99 @@
1
1
  {
2
2
  "name": "graphql-http",
3
- "version": "0.2.0",
4
- "description": "A GraphQL client for executing GraphQL queries over HTTP.",
5
- "scripts": {
6
- "test": "eslint lib && jest"
7
- },
8
- "repository": {
9
- "type": "git",
10
- "url": "git+https://github.com/petermelias/graphql-http.git"
11
- },
3
+ "version": "1.2.0",
4
+ "description": "Simple, pluggable, zero-dependency, GraphQL over HTTP Protocol compliant server and client",
12
5
  "keywords": [
13
6
  "graphql",
7
+ "client",
8
+ "relay",
9
+ "express",
10
+ "apollo",
11
+ "server",
14
12
  "http",
15
- "xhr",
16
- "graphql-client",
17
- "axios",
18
- "fetch"
13
+ "transport",
14
+ "observables",
15
+ "fastify"
19
16
  ],
20
- "author": "Peter M. Elias",
17
+ "author": "Denis Badurina <badurinadenis@gmail.com>",
21
18
  "license": "MIT",
22
- "bugs": {
23
- "url": "https://github.com/petermelias/graphql-http/issues"
19
+ "homepage": "https://github.com/enisdenjo/graphql-http#readme",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/enisdenjo/graphql-http.git"
23
+ },
24
+ "engines": {
25
+ "node": ">=12"
26
+ },
27
+ "packageManager": "yarn@3.2.2",
28
+ "main": "lib/index.js",
29
+ "module": "lib/index.mjs",
30
+ "browser": "umd/graphql-http.js",
31
+ "exports": {
32
+ ".": {
33
+ "require": "./lib/index.js",
34
+ "import": "./lib/index.mjs",
35
+ "types": "./lib/index.d.ts",
36
+ "browser": "./umd/graphql-http.js"
37
+ },
38
+ "./package.json": "./package.json"
39
+ },
40
+ "types": "lib/index.d.ts",
41
+ "files": [
42
+ "lib",
43
+ "umd",
44
+ "README.md",
45
+ "LICENSE.md"
46
+ ],
47
+ "sideEffects": [
48
+ "umd/*"
49
+ ],
50
+ "publishConfig": {
51
+ "access": "public"
52
+ },
53
+ "scripts": {
54
+ "gendocs": "typedoc --options typedoc.js src/",
55
+ "lint": "eslint 'src'",
56
+ "type-check": "tsc --noEmit",
57
+ "test": "NODE_OPTIONS=--experimental-vm-modules jest",
58
+ "build:esm": "tsc -b tsconfig.esm.json && node scripts/esm-post-process.js",
59
+ "build:cjs": "tsc -b tsconfig.cjs.json",
60
+ "build:umd": "rollup -c && gzip umd/graphql-http.min.js -c > umd/graphql-http.min.js.gz",
61
+ "build": "yarn build:esm && yarn build:cjs && yarn build:umd",
62
+ "release": "semantic-release"
24
63
  },
25
- "homepage": "https://github.com/petermelias/graphql-http#readme",
26
- "dependencies": {
27
- "isomorphic-fetch": "^2.2.1",
28
- "lodash.merge": "^4.0.0"
64
+ "peerDependencies": {
65
+ "graphql": ">=0.11 <=16"
29
66
  },
30
- "peerDependencies": {},
31
67
  "devDependencies": {
32
- "eslint": "^3.9.0",
33
- "eslint-config-semistandard": "^7.0.0",
34
- "fetch-mock": "^5.5.0",
35
- "jest": "^16.0.2"
68
+ "@babel/core": "^7.18.10",
69
+ "@babel/plugin-proposal-class-properties": "^7.18.6",
70
+ "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
71
+ "@babel/plugin-proposal-object-rest-spread": "^7.18.9",
72
+ "@babel/plugin-proposal-optional-chaining": "^7.18.9",
73
+ "@babel/preset-env": "^7.18.10",
74
+ "@babel/preset-typescript": "^7.18.6",
75
+ "@rollup/plugin-typescript": "^8.3.4",
76
+ "@semantic-release/changelog": "^6.0.1",
77
+ "@semantic-release/git": "^10.0.1",
78
+ "@types/jest": "^28.1.6",
79
+ "@typescript-eslint/eslint-plugin": "^5.33.0",
80
+ "@typescript-eslint/parser": "^5.33.0",
81
+ "babel-jest": "^28.1.3",
82
+ "eslint": "^8.21.0",
83
+ "eslint-config-prettier": "^8.5.0",
84
+ "eslint-plugin-prettier": "^4.2.1",
85
+ "graphql": "^16.5.0",
86
+ "jest": "^28.1.3",
87
+ "jest-jasmine2": "^28.1.3",
88
+ "node-fetch": "^3.2.10",
89
+ "prettier": "^2.7.1",
90
+ "replacestream": "^4.0.3",
91
+ "rollup": "^2.77.3",
92
+ "rollup-plugin-terser": "^7.0.2",
93
+ "semantic-release": "^19.0.3",
94
+ "tslib": "^2.4.0",
95
+ "typedoc": "^0.23.10",
96
+ "typedoc-plugin-markdown": "^3.13.4",
97
+ "typescript": "^4.7.4"
36
98
  }
37
99
  }
@@ -0,0 +1,190 @@
1
+ (function (global, factory) {
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3
+ typeof define === 'function' && define.amd ? define(['exports'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.graphqlHttp = {}));
5
+ })(this, (function (exports) { 'use strict';
6
+
7
+ /**
8
+ *
9
+ * utils
10
+ *
11
+ */
12
+ /** @private */
13
+ function isObject(val) {
14
+ return typeof val === 'object' && val !== null;
15
+ }
16
+
17
+ /**
18
+ *
19
+ * client
20
+ *
21
+ */
22
+ /**
23
+ * Creates a disposable GraphQL over HTTP client to transmit
24
+ * GraphQL operation results.
25
+ *
26
+ * @category Client
27
+ */
28
+ function createClient(options) {
29
+ const { credentials = 'same-origin', referrer, referrerPolicy, shouldRetry = () => false, } = options;
30
+ const fetchFn = (options.fetchFn || fetch);
31
+ const AbortControllerImpl = (options.abortControllerImpl ||
32
+ AbortController);
33
+ // we dont use yet another AbortController here because of
34
+ // node's max EventEmitters listeners being only 10
35
+ const client = (() => {
36
+ let disposed = false;
37
+ const listeners = [];
38
+ return {
39
+ get disposed() {
40
+ return disposed;
41
+ },
42
+ onDispose(cb) {
43
+ if (disposed) {
44
+ // empty the call stack and then call the cb
45
+ setTimeout(() => cb(), 0);
46
+ return () => {
47
+ // noop
48
+ };
49
+ }
50
+ listeners.push(cb);
51
+ return () => {
52
+ listeners.splice(listeners.indexOf(cb), 1);
53
+ };
54
+ },
55
+ dispose() {
56
+ if (disposed)
57
+ return;
58
+ disposed = true;
59
+ // we copy the listeners so that onDispose unlistens dont "pull the rug under our feet"
60
+ for (const listener of [...listeners]) {
61
+ listener();
62
+ }
63
+ },
64
+ };
65
+ })();
66
+ return {
67
+ subscribe(request, sink) {
68
+ if (client.disposed)
69
+ throw new Error('Client has been disposed');
70
+ const control = new AbortControllerImpl();
71
+ const unlisten = client.onDispose(() => {
72
+ unlisten();
73
+ control.abort();
74
+ });
75
+ (async () => {
76
+ var _a;
77
+ let retryingErr = null, retries = 0;
78
+ for (;;) {
79
+ if (retryingErr) {
80
+ const should = await shouldRetry(retryingErr, retries);
81
+ // requst might've been canceled while waiting for retry
82
+ if (control.signal.aborted)
83
+ return;
84
+ if (!should)
85
+ throw retryingErr;
86
+ retries++;
87
+ }
88
+ try {
89
+ const url = typeof options.url === 'function'
90
+ ? await options.url(request)
91
+ : options.url;
92
+ if (control.signal.aborted)
93
+ return;
94
+ const headers = typeof options.headers === 'function'
95
+ ? await options.headers()
96
+ : (_a = options.headers) !== null && _a !== void 0 ? _a : {};
97
+ if (control.signal.aborted)
98
+ return;
99
+ let res;
100
+ try {
101
+ res = await fetchFn(url, {
102
+ signal: control.signal,
103
+ method: 'POST',
104
+ headers: Object.assign(Object.assign({}, headers), { 'content-type': 'application/json; charset=utf-8', accept: 'application/graphql+json, application/json' }),
105
+ credentials,
106
+ referrer,
107
+ referrerPolicy,
108
+ body: JSON.stringify(request),
109
+ });
110
+ }
111
+ catch (err) {
112
+ throw new NetworkError(err);
113
+ }
114
+ if (!res.ok)
115
+ throw new NetworkError(res);
116
+ if (!res.body)
117
+ throw new Error('Missing response body');
118
+ const contentType = res.headers.get('content-type');
119
+ if (!contentType)
120
+ throw new Error('Missing response content-type');
121
+ if (!contentType.includes('application/graphql+json') &&
122
+ !contentType.includes('application/json')) {
123
+ throw new Error(`Unsupported response content-type ${contentType}`);
124
+ }
125
+ const result = await res.json();
126
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
127
+ sink.next(result);
128
+ return control.abort();
129
+ }
130
+ catch (err) {
131
+ if (control.signal.aborted)
132
+ return;
133
+ // all non-network errors are worth reporting immediately
134
+ if (!(err instanceof NetworkError))
135
+ throw err;
136
+ // try again
137
+ retryingErr = err;
138
+ }
139
+ }
140
+ })()
141
+ .then(() => sink.complete())
142
+ .catch((err) => sink.error(err));
143
+ return () => control.abort();
144
+ },
145
+ dispose() {
146
+ client.dispose();
147
+ },
148
+ };
149
+ }
150
+ /**
151
+ * A network error caused by the client or an unexpected response from the server.
152
+ *
153
+ * To avoid bundling DOM typings (because the client can run in Node env too),
154
+ * you should supply the `Response` generic depending on your Fetch implementation.
155
+ *
156
+ * @category Client
157
+ */
158
+ class NetworkError extends Error {
159
+ constructor(msgOrErrOrResponse) {
160
+ let message, response;
161
+ if (isResponseLike(msgOrErrOrResponse)) {
162
+ response = msgOrErrOrResponse;
163
+ message =
164
+ 'Server responded with ' +
165
+ msgOrErrOrResponse.status +
166
+ ': ' +
167
+ msgOrErrOrResponse.statusText;
168
+ }
169
+ else if (msgOrErrOrResponse instanceof Error)
170
+ message = msgOrErrOrResponse.message;
171
+ else
172
+ message = String(msgOrErrOrResponse);
173
+ super(message);
174
+ this.name = this.constructor.name;
175
+ this.response = response;
176
+ }
177
+ }
178
+ function isResponseLike(val) {
179
+ return (isObject(val) &&
180
+ typeof val['ok'] === 'boolean' &&
181
+ typeof val['status'] === 'number' &&
182
+ typeof val['statusText'] === 'string');
183
+ }
184
+
185
+ exports.NetworkError = NetworkError;
186
+ exports.createClient = createClient;
187
+
188
+ Object.defineProperty(exports, '__esModule', { value: true });
189
+
190
+ }));
@@ -0,0 +1 @@
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).graphqlHttp={})}(this,(function(e){"use strict";class t extends Error{constructor(e){let t,r;var o;(function(e){return"object"==typeof e&&null!==e})(o=e)&&"boolean"==typeof o.ok&&"number"==typeof o.status&&"string"==typeof o.statusText?(r=e,t="Server responded with "+e.status+": "+e.statusText):t=e instanceof Error?e.message:String(e),super(t),this.name=this.constructor.name,this.response=r}}e.NetworkError=t,e.createClient=function(e){const{credentials:r="same-origin",referrer:o,referrerPolicy:n,shouldRetry:s=(()=>!1)}=e,i=e.fetchFn||fetch,a=e.abortControllerImpl||AbortController,c=(()=>{let e=!1;const t=[];return{get disposed(){return e},onDispose:r=>e?(setTimeout((()=>r()),0),()=>{}):(t.push(r),()=>{t.splice(t.indexOf(r),1)}),dispose(){if(!e){e=!0;for(const e of[...t])e()}}}})();return{subscribe(l,p){if(c.disposed)throw new Error("Client has been disposed");const f=new a,u=c.onDispose((()=>{u(),f.abort()}));return(async()=>{var a;let c=null,u=0;for(;;){if(c){const e=await s(c,u);if(f.signal.aborted)return;if(!e)throw c;u++}try{const s="function"==typeof e.url?await e.url(l):e.url;if(f.signal.aborted)return;const c="function"==typeof e.headers?await e.headers():null!==(a=e.headers)&&void 0!==a?a:{};if(f.signal.aborted)return;let u;try{u=await i(s,{signal:f.signal,method:"POST",headers:Object.assign(Object.assign({},c),{"content-type":"application/json; charset=utf-8",accept:"application/graphql+json, application/json"}),credentials:r,referrer:o,referrerPolicy:n,body:JSON.stringify(l)})}catch(e){throw new t(e)}if(!u.ok)throw new t(u);if(!u.body)throw new Error("Missing response body");const d=u.headers.get("content-type");if(!d)throw new Error("Missing response content-type");if(!d.includes("application/graphql+json")&&!d.includes("application/json"))throw new Error(`Unsupported response content-type ${d}`);const h=await u.json();return p.next(h),f.abort()}catch(e){if(f.signal.aborted)return;if(!(e instanceof t))throw e;c=e}}})().then((()=>p.complete())).catch((e=>p.error(e))),()=>f.abort()},dispose(){c.dispose()}}},Object.defineProperty(e,"__esModule",{value:!0})}));
Binary file
package/.eslintrc.json DELETED
@@ -1,8 +0,0 @@
1
- {
2
- "ecmaVersion": 5,
3
- "sourceType": "module",
4
- "env": {
5
- "browser": true,
6
- "node": true
7
- }
8
- }
package/.npmignore DELETED
@@ -1,33 +0,0 @@
1
- # Logs
2
- logs
3
- *.log
4
- npm-debug.log*
5
-
6
- # Runtime data
7
- pids
8
- *.pid
9
- *.seed
10
-
11
- # Directory for instrumented libs generated by jscoverage/JSCover
12
- lib-cov
13
-
14
- # Coverage directory used by tools like istanbul
15
- coverage
16
-
17
- # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
18
- .grunt
19
-
20
- # node-waf configuration
21
- .lock-wscript
22
-
23
- # Compiled binary addons (http://nodejs.org/api/addons.html)
24
- build/Release
25
-
26
- # Dependency directory
27
- node_modules
28
-
29
- # Optional npm cache directory
30
- .npm
31
-
32
- # Optional REPL history
33
- .node_repl_history
package/index.js DELETED
@@ -1 +0,0 @@
1
- module.exports = require('./lib');
@@ -1,90 +0,0 @@
1
- 'use strict';
2
-
3
- var url = require('url');
4
- var fetchMock = require('fetch-mock');
5
-
6
- var GQL = require('../');
7
-
8
- describe('GQLClient', function() {
9
- afterEach(function () {
10
- fetchMock.restore();
11
- });
12
-
13
- pit('should work', function () {
14
- fetchMock.get('*', {
15
- body: {data: {whatwhat: true}},
16
- headers: {
17
- 'Content-Type': 'application/json; charset=utf-8'
18
- }
19
- });
20
-
21
- var client = GQL.GQLClient('https://example.com/gql');
22
-
23
- return client.query('query{whatwhat}').then(function (result) {
24
- expect(result).toEqual({
25
- data: {whatwhat: true}
26
- });
27
- });
28
- });
29
-
30
- pit('should properly not work with 200', function () {
31
- fetchMock.get('*', {
32
- body: {errors: [{message: 'you don fucked up'}]},
33
- headers: {
34
- 'Content-Type': 'application/json; charset=utf-8'
35
- }
36
- });
37
-
38
- var client = GQL.GQLClient('https://example.com/gql');
39
-
40
- return client.query('query{whatwhat}').then(fail, function (error) {
41
- expect(error instanceof GQL.GraphQLResponseError).toBe(true);
42
-
43
- expect(error.message).toMatch(/1 error\(s\)/);
44
- expect(error.message).toMatch(/you don fucked up/);
45
- });
46
- });
47
-
48
- pit('should properly not work with different status code', function () {
49
- fetchMock.get('*', {
50
- body: {errors: [{message: 'you don fucked up'}]},
51
- headers: {
52
- 'Content-Type': 'application/json; charset=utf-8'
53
- },
54
- status: 400
55
- });
56
-
57
- var client = GQL.GQLClient('https://example.com/gql');
58
-
59
- return client.query('query{whatwhat}').then(fail, function (error) {
60
- expect(error instanceof GQL.GraphQLResponseError).toBe(true);
61
-
62
- expect(error.message).not.toMatch(/1 error\(s\)/);
63
- expect(error.message).toMatch(/Received status 400/);
64
- expect(error.message).toMatch(/you don fucked up/);
65
- });
66
- });
67
-
68
- pit('should work with onlyBody mutate', function () {
69
- fetchMock.post('*', {
70
- body: {data: {whatwhat: true}},
71
- headers: {
72
- 'Content-Type': 'application/json; charset=utf-8'
73
- }
74
- });
75
-
76
- var client = GQL.GQLClient('https://example.com/gql');
77
-
78
- return client.configure({onlyBody: true})
79
- .mutate('mutation foo{bar(){baz}}')
80
- .then(function (result) {
81
- expect(result).toEqual({
82
- data: {whatwhat: true}
83
- });
84
-
85
- var request = fetchMock.lastCall();
86
-
87
- expect(url.parse(request[0]).search).toBe(null);
88
- });
89
- });
90
- });