caccl-send-request 1.0.12 → 2.0.0-beta.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.
@@ -0,0 +1,5 @@
1
+ declare enum ErrorCode {
2
+ NotConnected = "CSR1",
3
+ SelfSigned = "CSR2"
4
+ }
5
+ export default ErrorCode;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ // Highest error code: CSR2
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ var ErrorCode;
5
+ (function (ErrorCode) {
6
+ ErrorCode["NotConnected"] = "CSR1";
7
+ ErrorCode["SelfSigned"] = "CSR2";
8
+ })(ErrorCode || (ErrorCode = {}));
9
+ ;
10
+ exports.default = ErrorCode;
11
+ //# sourceMappingURL=ErrorCode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorCode.js","sourceRoot":"","sources":["../src/ErrorCode.ts"],"names":[],"mappings":";AAAA,2BAA2B;;AAE3B,IAAK,SAGJ;AAHD,WAAK,SAAS;IACZ,kCAAqB,CAAA;IACrB,gCAAmB,CAAA;AACrB,CAAC,EAHI,SAAS,KAAT,SAAS,QAGb;AAAA,CAAC;AAEF,kBAAe,SAAS,CAAC"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Sends and retries an http request
3
+ * @author Gabriel Abrams
4
+ * @param opts object containing all arguments
5
+ * @param opts.host host to send request to
6
+ * @param opts.path path to send request to
7
+ * @param [opts.method=GET] http method to use
8
+ * @param [opts.params] body/data to include in the request
9
+ * @param [opts.headers] headers to include in the request
10
+ * @param [opts.numRetries=0] number of times to retry the request if it
11
+ * fails
12
+ * @param [opts.ignoreSSLIssues=false] if true, ignores SSL certificate
13
+ * issues. If host is localhost:8088, this will default to true
14
+ * @returns Returns { body, status, headers } on success
15
+ */
16
+ declare const sendRequest: (opts: {
17
+ host: string;
18
+ path: string;
19
+ method?: ('GET' | 'POST' | 'PUT' | 'DELETE');
20
+ params?: {
21
+ [x: string]: any;
22
+ };
23
+ headers?: {
24
+ [x: string]: any;
25
+ };
26
+ numRetries?: number;
27
+ ignoreSSLIssues?: boolean;
28
+ }) => Promise<{
29
+ body: any;
30
+ status: number;
31
+ headers: {
32
+ [x: string]: any;
33
+ };
34
+ }>;
35
+ export default sendRequest;
package/lib/index.js ADDED
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (_) try {
29
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ var __importDefault = (this && this.__importDefault) || function (mod) {
50
+ return (mod && mod.__esModule) ? mod : { "default": mod };
51
+ };
52
+ Object.defineProperty(exports, "__esModule", { value: true });
53
+ // Import libs
54
+ var axios_1 = __importDefault(require("axios"));
55
+ var qs_1 = __importDefault(require("qs"));
56
+ var caccl_error_1 = __importDefault(require("caccl-error"));
57
+ var https_1 = __importDefault(require("https"));
58
+ // Import shared types
59
+ var ErrorCode_1 = __importDefault(require("./ErrorCode"));
60
+ // Create an agent to ignore unauthorize ssl issues
61
+ var ignoreSSLIssuesAgent = new https_1.default.Agent({ rejectUnauthorized: false });
62
+ // Check if we should send cross-domain credentials
63
+ var sendCrossDomainCredentials = !!(process.env.DEV
64
+ || process.env.NODE_ENV === 'development');
65
+ /**
66
+ * Sends and retries an http request
67
+ * @author Gabriel Abrams
68
+ * @param opts object containing all arguments
69
+ * @param opts.host host to send request to
70
+ * @param opts.path path to send request to
71
+ * @param [opts.method=GET] http method to use
72
+ * @param [opts.params] body/data to include in the request
73
+ * @param [opts.headers] headers to include in the request
74
+ * @param [opts.numRetries=0] number of times to retry the request if it
75
+ * fails
76
+ * @param [opts.ignoreSSLIssues=false] if true, ignores SSL certificate
77
+ * issues. If host is localhost:8088, this will default to true
78
+ * @returns Returns { body, status, headers } on success
79
+ */
80
+ var sendRequest = function (opts) { return __awaiter(void 0, void 0, void 0, function () {
81
+ var numRetries, method, stringifiedParams, query, url, ignoreSSLIssues, httpsAgent, headers, data, response, err_1;
82
+ return __generator(this, function (_a) {
83
+ switch (_a.label) {
84
+ case 0:
85
+ numRetries = (opts.numRetries ? opts.numRetries : 0);
86
+ method = (opts.method || 'GET');
87
+ stringifiedParams = qs_1.default.stringify(opts.params || {}, {
88
+ encodeValuesOnly: true,
89
+ arrayFormat: 'brackets',
90
+ });
91
+ query = (method === 'GET' ? "?".concat(stringifiedParams) : '');
92
+ if (!opts.host) {
93
+ // No host included at all. Just send to a path
94
+ url = "".concat(opts.path).concat(query);
95
+ }
96
+ else {
97
+ url = "https://".concat(opts.host).concat(opts.path).concat(query);
98
+ }
99
+ ignoreSSLIssues = (opts.ignoreSSLIssues !== undefined
100
+ ? opts.ignoreSSLIssues
101
+ : opts.host === 'localhost:8088');
102
+ httpsAgent = (ignoreSSLIssues
103
+ ? ignoreSSLIssuesAgent
104
+ : undefined);
105
+ headers = opts.headers || {};
106
+ data = null;
107
+ if (!headers['Content-Type']) {
108
+ // Form encoded
109
+ headers['Content-Type'] = 'application/x-www-form-urlencoded';
110
+ // Add data if applicable
111
+ data = (method !== 'GET' ? stringifiedParams : null);
112
+ }
113
+ else {
114
+ // JSON encode
115
+ data = opts.params;
116
+ }
117
+ _a.label = 1;
118
+ case 1:
119
+ _a.trys.push([1, 3, , 4]);
120
+ return [4 /*yield*/, (0, axios_1.default)({
121
+ method: method,
122
+ url: url,
123
+ data: data,
124
+ httpsAgent: httpsAgent,
125
+ headers: headers,
126
+ withCredentials: sendCrossDomainCredentials,
127
+ })];
128
+ case 2:
129
+ response = _a.sent();
130
+ // Process response
131
+ return [2 /*return*/, {
132
+ body: response.data,
133
+ status: response.status,
134
+ headers: response.headers,
135
+ }];
136
+ case 3:
137
+ err_1 = _a.sent();
138
+ // Axios throws an error if the request status indicates an error
139
+ // sendRequest is supposed to resolve if the request went through, whether
140
+ // the status indicates an error or not.
141
+ if (err_1.response) {
142
+ // Resolve with response
143
+ return [2 /*return*/, {
144
+ body: err_1.response.data,
145
+ status: err_1.response.status,
146
+ headers: err_1.response.headers,
147
+ }];
148
+ }
149
+ // Request failed! Check if we have more attempts
150
+ if (numRetries > 0) {
151
+ // Update opts with one less retry
152
+ return [2 /*return*/, sendRequest(__assign(__assign({}, opts), { numRetries: opts.numRetries - 1 }))];
153
+ }
154
+ // Self-signed certificate error:
155
+ if (err_1.message.includes('self signed certificate')) {
156
+ throw new caccl_error_1.default({
157
+ message: 'We refused to send a request because the receiver has self-signed certificates.',
158
+ code: ErrorCode_1.default.SelfSigned,
159
+ });
160
+ }
161
+ // No tries left
162
+ throw new caccl_error_1.default({
163
+ message: 'We encountered an error when trying to send a network request. If this issue persists, contact an admin.',
164
+ code: ErrorCode_1.default.NotConnected,
165
+ });
166
+ case 4: return [2 /*return*/];
167
+ }
168
+ });
169
+ }); };
170
+ exports.default = sendRequest;
171
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "caccl-send-request",
3
- "version": "1.0.12",
3
+ "version": "2.0.0-beta.0",
4
4
  "description": "The default request sender used throughout the CACCL project.",
5
- "main": "index.js",
5
+ "main": "./lib/index.js",
6
+ "types": "./lib/index.d.ts",
6
7
  "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
8
+ "build": "tsc --project ./tsconfig.json"
8
9
  },
9
10
  "repository": {
10
11
  "type": "git",
@@ -25,16 +26,19 @@
25
26
  },
26
27
  "homepage": "https://github.com/harvard-edtech/caccl-send-request#readme",
27
28
  "devDependencies": {
28
- "eslint": "^5.16.0",
29
- "eslint-config-airbnb": "^17.1.1",
30
- "eslint-plugin-import": "^2.18.2",
31
- "eslint-plugin-jsx-a11y": "^6.2.3",
32
- "eslint-plugin-react": "^7.14.2"
29
+ "@types/node": "^17.0.17",
30
+ "@types/qs": "^6.9.7",
31
+ "eslint": "^8.9.0",
32
+ "eslint-config-airbnb": "^19.0.4",
33
+ "eslint-plugin-import": "^2.22.1",
34
+ "eslint-plugin-jsx-a11y": "^6.4.1",
35
+ "eslint-plugin-react": "^7.22.0",
36
+ "typescript": "^4.5.5"
33
37
  },
34
38
  "dependencies": {
35
- "axios": "^0.19.0",
36
- "caccl-error": "^1.0.2",
39
+ "axios": "^0.21.1",
40
+ "caccl-error": "^2.0.0-beta.0",
37
41
  "https": "^1.0.0",
38
- "qs": "^6.7.0"
42
+ "qs": "^6.9.6"
39
43
  }
40
44
  }
@@ -0,0 +1,8 @@
1
+ // Highest error code: CSR2
2
+
3
+ enum ErrorCode {
4
+ NotConnected = 'CSR1',
5
+ SelfSigned = 'CSR2',
6
+ };
7
+
8
+ export default ErrorCode;
package/src/index.ts ADDED
@@ -0,0 +1,153 @@
1
+ // Import libs
2
+ import axios from 'axios';
3
+ import qs from 'qs';
4
+ import CACCLError from 'caccl-error';
5
+ import https from 'https';
6
+
7
+ // Import shared types
8
+ import ErrorCode from './ErrorCode';
9
+
10
+ // Create an agent to ignore unauthorize ssl issues
11
+ const ignoreSSLIssuesAgent = new https.Agent({ rejectUnauthorized: false });
12
+
13
+ // Check if we should send cross-domain credentials
14
+ const sendCrossDomainCredentials = !!(
15
+ process.env.DEV
16
+ || process.env.NODE_ENV === 'development'
17
+ );
18
+
19
+ /**
20
+ * Sends and retries an http request
21
+ * @author Gabriel Abrams
22
+ * @param opts object containing all arguments
23
+ * @param opts.host host to send request to
24
+ * @param opts.path path to send request to
25
+ * @param [opts.method=GET] http method to use
26
+ * @param [opts.params] body/data to include in the request
27
+ * @param [opts.headers] headers to include in the request
28
+ * @param [opts.numRetries=0] number of times to retry the request if it
29
+ * fails
30
+ * @param [opts.ignoreSSLIssues=false] if true, ignores SSL certificate
31
+ * issues. If host is localhost:8088, this will default to true
32
+ * @returns Returns { body, status, headers } on success
33
+ */
34
+ const sendRequest = async (
35
+ opts: {
36
+ host: string,
37
+ path: string,
38
+ method?: ('GET' | 'POST' | 'PUT' | 'DELETE'),
39
+ params?: { [k in string]: any },
40
+ headers?: { [k in string]: any },
41
+ numRetries?: number,
42
+ ignoreSSLIssues?: boolean,
43
+ },
44
+ ): Promise<{
45
+ body: any,
46
+ status: number,
47
+ headers: { [k in string]: any },
48
+ }> => {
49
+ // Set max number of retries if not defined
50
+ const numRetries = (opts.numRetries ? opts.numRetries : 0);
51
+
52
+ // Process method
53
+ const method: ('GET' | 'POST' | 'PUT' | 'DELETE') = (opts.method || 'GET');
54
+
55
+ // Stringify parameters
56
+ const stringifiedParams = qs.stringify(opts.params || {}, {
57
+ encodeValuesOnly: true,
58
+ arrayFormat: 'brackets',
59
+ });
60
+
61
+ // Create url (include query if GET)
62
+ const query = (method === 'GET' ? `?${stringifiedParams}` : '');
63
+ let url;
64
+ if (!opts.host) {
65
+ // No host included at all. Just send to a path
66
+ url = `${opts.path}${query}`;
67
+ } else {
68
+ url = `https://${opts.host}${opts.path}${query}`;
69
+ }
70
+
71
+ // Default ignoreSSLIssues
72
+ const ignoreSSLIssues = (
73
+ opts.ignoreSSLIssues !== undefined
74
+ ? opts.ignoreSSLIssues
75
+ : opts.host === 'localhost:8088'
76
+ );
77
+
78
+ // Prep to ignore ssl issues
79
+ const httpsAgent = (
80
+ ignoreSSLIssues
81
+ ? ignoreSSLIssuesAgent
82
+ : undefined
83
+ );
84
+
85
+ // Update headers
86
+ const headers = opts.headers || {};
87
+ let data = null;
88
+ if (!headers['Content-Type']) {
89
+ // Form encoded
90
+ headers['Content-Type'] = 'application/x-www-form-urlencoded';
91
+ // Add data if applicable
92
+ data = (method !== 'GET' ? stringifiedParams : null);
93
+ } else {
94
+ // JSON encode
95
+ data = opts.params;
96
+ }
97
+
98
+ // Send request
99
+ try {
100
+ const response = await axios({
101
+ method,
102
+ url,
103
+ data,
104
+ httpsAgent,
105
+ headers,
106
+ withCredentials: sendCrossDomainCredentials,
107
+ });
108
+
109
+ // Process response
110
+ return {
111
+ body: response.data,
112
+ status: response.status,
113
+ headers: response.headers,
114
+ };
115
+ } catch (err) {
116
+ // Axios throws an error if the request status indicates an error
117
+ // sendRequest is supposed to resolve if the request went through, whether
118
+ // the status indicates an error or not.
119
+ if (err.response) {
120
+ // Resolve with response
121
+ return {
122
+ body: err.response.data,
123
+ status: err.response.status,
124
+ headers: err.response.headers,
125
+ };
126
+ }
127
+
128
+ // Request failed! Check if we have more attempts
129
+ if (numRetries > 0) {
130
+ // Update opts with one less retry
131
+ return sendRequest({
132
+ ...opts,
133
+ numRetries: opts.numRetries - 1,
134
+ });
135
+ }
136
+
137
+ // Self-signed certificate error:
138
+ if (err.message.includes('self signed certificate')) {
139
+ throw new CACCLError({
140
+ message: 'We refused to send a request because the receiver has self-signed certificates.',
141
+ code: ErrorCode.SelfSigned,
142
+ });
143
+ }
144
+
145
+ // No tries left
146
+ throw new CACCLError({
147
+ message: 'We encountered an error when trying to send a network request. If this issue persists, contact an admin.',
148
+ code: ErrorCode.NotConnected,
149
+ });
150
+ }
151
+ };
152
+
153
+ export default sendRequest;
package/tsconfig.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ "module": "commonjs",
4
+ "esModuleInterop": true,
5
+ "noImplicitAny": true,
6
+ "noEmitOnError": true,
7
+ "removeComments": false,
8
+ "declaration": true,
9
+ "sourceMap": true,
10
+ "target": "es5",
11
+ "outDir": "./lib"
12
+ },
13
+ "include": [
14
+ "./src"
15
+ ],
16
+ "ts-node": {
17
+ "files": true
18
+ }
19
+ }
package/errorCodes.js DELETED
@@ -1,6 +0,0 @@
1
- // Highest error code: CSR2
2
-
3
- module.exports = {
4
- notConnected: 'CSR1',
5
- selfSigned: 'CSR2',
6
- };
package/index.js DELETED
@@ -1,129 +0,0 @@
1
- const axios = require('axios');
2
- const qs = require('qs');
3
- const CACCLError = require('caccl-error');
4
- const https = require('https');
5
-
6
- const errorCodes = require('./errorCodes');
7
-
8
- // Create an agent to ignore unauthorize ssl issues
9
- const ignoreSSLIssuesAgent = new https.Agent({ rejectUnauthorized: false });
10
-
11
- // Check if we should send cross-domain credentials
12
- const sendCrossDomainCredentials = !!(
13
- process.env.DEV
14
- || process.env.NODE_ENV === 'development'
15
- );
16
-
17
- /**
18
- * Sends and retries an http request
19
- * @author Gabriel Abrams
20
- * @param {string} host - host to send request to
21
- * @param {string} path - path to send request to
22
- * @param {string} [method=GET] - http method to use
23
- * @param {object} [params] - body/data to include in the request
24
- * @param {object} [headers] - headers to include in the request
25
- * @param {number} [numRetries=0] - number of times to retry the request if it
26
- * fails
27
- * @param {boolean} [ignoreSSLIssues=false] - if true, ignores SSL certificate
28
- * issues. If host is localhost:8088, this will default to true
29
- * @return {Promise.<CACCLErrror|object>} Returns { body, status, headers } on
30
- * success, CACCLError on failure
31
- */
32
- const sendRequest = (options) => {
33
- // Set max number of retries if not defined
34
- const numRetries = (options.numRetries ? options.numRetries : 0);
35
-
36
- // Use default method if applicable
37
- const method = options.method || 'GET';
38
-
39
- // Stringify parameters
40
- const stringifiedParams = qs.stringify(options.params || {}, {
41
- encodeValuesOnly: true,
42
- arrayFormat: 'brackets',
43
- });
44
-
45
- // Create url (include query if GET)
46
- const query = (method === 'GET' ? `?${stringifiedParams}` : '');
47
- let url;
48
- if (!options.host) {
49
- // No host included at all. Just send to a path
50
- url = `${options.path}${query}`;
51
- } else {
52
- url = `https://${options.host}${options.path}${query}`;
53
- }
54
-
55
- // Default ignoreSSLIssues
56
- const ignoreSSLIssues = (
57
- options.ignoreSSLIssues !== undefined
58
- ? options.ignoreSSLIssues
59
- : options.host === 'localhost:8088'
60
- );
61
-
62
- // Prep to ignore ssl issues
63
- const httpsAgent = (
64
- ignoreSSLIssues
65
- ? ignoreSSLIssuesAgent
66
- : undefined
67
- );
68
-
69
- // Update headers
70
- const headers = options.headers || {};
71
- let data = null;
72
- if (!headers['Content-Type']) {
73
- // Form encoded
74
- headers['Content-Type'] = 'application/x-www-form-urlencoded';
75
- // Add data if applicable
76
- data = (method !== 'GET' ? stringifiedParams : null);
77
- } else {
78
- // JSON encode
79
- data = options.params;
80
- }
81
-
82
- // Send request
83
- return axios({
84
- method,
85
- url,
86
- data,
87
- httpsAgent,
88
- headers,
89
- withCredentials: sendCrossDomainCredentials,
90
- })
91
- .catch((err) => {
92
- // Axios throws an error if the request status indicates an error
93
- // sendRequest is supposed to resolve if the request went through, whether
94
- // the status indicates an error or not.
95
- if (err.response) {
96
- // Resolve with response
97
- return Promise.resolve(err.response);
98
- }
99
- // Request failed! Check if we have more attempts
100
- if (numRetries > 0) {
101
- // Update options with one less retry
102
- const newOptions = options;
103
- newOptions.numRetries -= 1;
104
- return sendRequest(newOptions);
105
- }
106
-
107
- // Self-signed certificate error:
108
- if (err.message.includes('self signed certificate')) {
109
- throw new CACCLError({
110
- message: 'We refused to send a request because the receiver has self-signed certificates.',
111
- code: errorCodes.selfSigned,
112
- });
113
- }
114
-
115
- // No tries left
116
- throw new CACCLError({
117
- message: 'We encountered an error when trying to send a network request. If this issue persists, contact an admin.',
118
- code: errorCodes.notConnected,
119
- });
120
- })
121
- .then((response) => {
122
- return {
123
- body: response.data,
124
- status: response.status,
125
- headers: response.headers,
126
- };
127
- });
128
- };
129
- module.exports = sendRequest;