files.com 1.0.295 → 1.0.297
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/_VERSION +1 -1
- package/docs/models/Automation.md +8 -8
- package/lib/Api.js +180 -80
- package/lib/Errors.js +2 -2
- package/lib/isomorphic/File.node.js +5 -3
- package/lib/models/Automation.js +4 -4
- package/package.json +2 -3
- package/src/Api.js +68 -30
- package/src/Errors.js +2 -2
- package/src/isomorphic/File.node.js +5 -2
- package/src/models/Automation.js +4 -4
- package/test/package.json +2 -1
- package/test/src/index.js +54 -40
package/_VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.0.
|
|
1
|
+
1.0.297
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"automation": "create_folder",
|
|
9
9
|
"deleted": true,
|
|
10
10
|
"disabled": true,
|
|
11
|
-
"trigger": "
|
|
11
|
+
"trigger": "daily",
|
|
12
12
|
"interval": "week",
|
|
13
13
|
"last_modified_at": "2000-01-01T01:00:00Z",
|
|
14
14
|
"name": "example",
|
|
@@ -49,13 +49,13 @@
|
|
|
49
49
|
* `automation` (string): Automation type
|
|
50
50
|
* `deleted` (boolean): Indicates if the automation has been deleted.
|
|
51
51
|
* `disabled` (boolean): If true, this automation will not run.
|
|
52
|
-
* `trigger` (string): How this automation is triggered to run.
|
|
52
|
+
* `trigger` (string): How this automation is triggered to run.
|
|
53
53
|
* `interval` (string): If trigger is `daily`, this specifies how often to run this automation. One of: `day`, `week`, `week_end`, `month`, `month_end`, `quarter`, `quarter_end`, `year`, `year_end`
|
|
54
54
|
* `last_modified_at` (date-time): Time when automation was last modified. Does not change for name or description updates.
|
|
55
55
|
* `name` (string): Name for this automation.
|
|
56
56
|
* `schedule` (object): If trigger is `custom_schedule`, Custom schedule description for when the automation should be run.
|
|
57
57
|
* `source` (string): Source Path
|
|
58
|
-
* `destinations` (array): Destination
|
|
58
|
+
* `destinations` (array): Destination Paths
|
|
59
59
|
* `destination_replace_from` (string): If set, this string in the destination path will be replaced with the value in `destination_replace_to`.
|
|
60
60
|
* `destination_replace_to` (string): If set, this string will replace the value `destination_replace_from` in the destination filename. You can use special patterns here.
|
|
61
61
|
* `description` (string): Description for the this Automation.
|
|
@@ -126,7 +126,7 @@ await Automation.create({
|
|
|
126
126
|
'description': "example",
|
|
127
127
|
'disabled': true,
|
|
128
128
|
'name': "example",
|
|
129
|
-
'trigger': "
|
|
129
|
+
'trigger': "daily",
|
|
130
130
|
'trigger_actions': ["create"],
|
|
131
131
|
'value': {"limit":"1"},
|
|
132
132
|
'recurring_day': 25,
|
|
@@ -151,7 +151,7 @@ await Automation.create({
|
|
|
151
151
|
* `description` (string): Description for the this Automation.
|
|
152
152
|
* `disabled` (boolean): If true, this automation will not run.
|
|
153
153
|
* `name` (string): Name for this automation.
|
|
154
|
-
* `trigger` (string): How this automation is triggered to run.
|
|
154
|
+
* `trigger` (string): How this automation is triggered to run.
|
|
155
155
|
* `trigger_actions` (array(string)): If trigger is `action`, this is the list of action types on which to trigger the automation. Valid actions are create, read, update, destroy, move, copy
|
|
156
156
|
* `value` (object): A Hash of attributes specific to the automation type.
|
|
157
157
|
* `recurring_day` (int64): If trigger type is `daily`, this specifies a day number to run in one of the supported intervals: `week`, `month`, `quarter`, `year`.
|
|
@@ -193,7 +193,7 @@ await automation.update({
|
|
|
193
193
|
'description': "example",
|
|
194
194
|
'disabled': true,
|
|
195
195
|
'name': "example",
|
|
196
|
-
'trigger': "
|
|
196
|
+
'trigger': "daily",
|
|
197
197
|
'trigger_actions': ["create"],
|
|
198
198
|
'value': {"limit":"1"},
|
|
199
199
|
'recurring_day': 25,
|
|
@@ -218,7 +218,7 @@ await automation.update({
|
|
|
218
218
|
* `description` (string): Description for the this Automation.
|
|
219
219
|
* `disabled` (boolean): If true, this automation will not run.
|
|
220
220
|
* `name` (string): Name for this automation.
|
|
221
|
-
* `trigger` (string): How this automation is triggered to run.
|
|
221
|
+
* `trigger` (string): How this automation is triggered to run.
|
|
222
222
|
* `trigger_actions` (array(string)): If trigger is `action`, this is the list of action types on which to trigger the automation. Valid actions are create, read, update, destroy, move, copy
|
|
223
223
|
* `value` (object): A Hash of attributes specific to the automation type.
|
|
224
224
|
* `recurring_day` (int64): If trigger type is `daily`, this specifies a day number to run in one of the supported intervals: `week`, `month`, `quarter`, `year`.
|
|
@@ -232,7 +232,7 @@ await automation.update({
|
|
|
232
232
|
"automation": "create_folder",
|
|
233
233
|
"deleted": true,
|
|
234
234
|
"disabled": true,
|
|
235
|
-
"trigger": "
|
|
235
|
+
"trigger": "daily",
|
|
236
236
|
"interval": "week",
|
|
237
237
|
"last_modified_at": "2000-01-01T01:00:00Z",
|
|
238
238
|
"name": "example",
|
package/lib/Api.js
CHANGED
|
@@ -7,92 +7,192 @@ exports.default = void 0;
|
|
|
7
7
|
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
8
8
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
9
9
|
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
10
|
-
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
11
10
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
12
11
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
13
12
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
14
|
-
var
|
|
15
|
-
var
|
|
13
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
14
|
+
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
|
|
15
|
+
var _crossFetch = _interopRequireDefault(require("cross-fetch"));
|
|
16
16
|
var _Files = _interopRequireDefault(require("./Files"));
|
|
17
17
|
var errors = _interopRequireWildcard(require("./Errors"));
|
|
18
18
|
var _Logger = _interopRequireDefault(require("./Logger"));
|
|
19
19
|
var _utils = require("./utils");
|
|
20
|
+
var _excluded = ["timeoutSecs"];
|
|
20
21
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
21
22
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
22
23
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
23
24
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
25
|
+
var _fetchWithTimeout = function _fetchWithTimeout(url) {
|
|
26
|
+
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
|
|
27
|
+
timeoutSecs = _ref.timeoutSecs,
|
|
28
|
+
options = (0, _objectWithoutProperties2.default)(_ref, _excluded);
|
|
29
|
+
return timeoutSecs <= 0 ? (0, _crossFetch.default)(url, options) : Promise.race([(0, _crossFetch.default)(url, options), new Promise(function (_, reject) {
|
|
30
|
+
setTimeout(function () {
|
|
31
|
+
return reject(new errors.FilesError('Request timed out'));
|
|
32
|
+
}, timeoutSecs * 1000);
|
|
33
|
+
})]);
|
|
34
|
+
};
|
|
35
|
+
var fetchWithRetry = /*#__PURE__*/function () {
|
|
36
|
+
var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(url, options) {
|
|
37
|
+
var retries,
|
|
38
|
+
maxRetries,
|
|
39
|
+
minRetryDelaySecs,
|
|
40
|
+
maxRetryDelaySecs,
|
|
41
|
+
nextRetries,
|
|
42
|
+
delaySecs,
|
|
43
|
+
_args = arguments;
|
|
44
|
+
return _regenerator.default.wrap(function _callee$(_context) {
|
|
45
|
+
while (1) switch (_context.prev = _context.next) {
|
|
46
|
+
case 0:
|
|
47
|
+
retries = _args.length > 2 && _args[2] !== undefined ? _args[2] : 0;
|
|
48
|
+
maxRetries = _Files.default.getMaxNetworkRetries();
|
|
49
|
+
minRetryDelaySecs = _Files.default.getMinNetworkRetryDelay();
|
|
50
|
+
maxRetryDelaySecs = _Files.default.getMaxNetworkRetryDelay();
|
|
51
|
+
_context.prev = 4;
|
|
52
|
+
_context.next = 7;
|
|
53
|
+
return _fetchWithTimeout(url, options);
|
|
54
|
+
case 7:
|
|
55
|
+
return _context.abrupt("return", _context.sent);
|
|
56
|
+
case 10:
|
|
57
|
+
_context.prev = 10;
|
|
58
|
+
_context.t0 = _context["catch"](4);
|
|
59
|
+
_Logger.default.info("Request #".concat(retries + 1, " failed: ").concat(_context.t0.message));
|
|
60
|
+
if (!(retries >= maxRetries)) {
|
|
61
|
+
_context.next = 17;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
throw _context.t0;
|
|
65
|
+
case 17:
|
|
66
|
+
nextRetries = retries + 1;
|
|
67
|
+
_Logger.default.info("Retrying request (retry ".concat(nextRetries, " of ").concat(maxRetries, ")"));
|
|
68
|
+
delaySecs = Math.min(minRetryDelaySecs * Math.pow(2, retries), maxRetryDelaySecs); // exponential backoff
|
|
69
|
+
_context.next = 22;
|
|
70
|
+
return new Promise(function (resolve) {
|
|
71
|
+
return setTimeout(resolve, delaySecs * 1000);
|
|
72
|
+
});
|
|
73
|
+
case 22:
|
|
74
|
+
return _context.abrupt("return", fetchWithRetry(url, options, nextRetries));
|
|
75
|
+
case 23:
|
|
76
|
+
case "end":
|
|
77
|
+
return _context.stop();
|
|
78
|
+
}
|
|
79
|
+
}, _callee, null, [[4, 10]]);
|
|
80
|
+
}));
|
|
81
|
+
return function fetchWithRetry(_x, _x2) {
|
|
82
|
+
return _ref2.apply(this, arguments);
|
|
83
|
+
};
|
|
84
|
+
}();
|
|
24
85
|
var Api = /*#__PURE__*/(0, _createClass2.default)(function Api() {
|
|
25
86
|
(0, _classCallCheck2.default)(this, Api);
|
|
26
87
|
});
|
|
27
|
-
(0, _defineProperty2.default)(Api, "_configureAutoRetry", function () {
|
|
28
|
-
(0, _axiosRetry.default)(_axios.default, {
|
|
29
|
-
retries: _Files.default.getMaxNetworkRetries(),
|
|
30
|
-
retryDelay: function retryDelay(retries) {
|
|
31
|
-
_Logger.default.info("Retrying request (retry ".concat(retries, " of ").concat(_Files.default.getMaxNetworkRetries(), ")"));
|
|
32
|
-
return Math.min(retries * _Files.default.getMinNetworkRetryDelay() * 1000, _Files.default.getMaxNetworkRetryDelay() * 1000);
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
88
|
(0, _defineProperty2.default)(Api, "_sendVerbatim", /*#__PURE__*/function () {
|
|
37
|
-
var
|
|
38
|
-
var isExternal, baseUrl, url, response;
|
|
39
|
-
return _regenerator.default.wrap(function
|
|
40
|
-
while (1) switch (
|
|
89
|
+
var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(path, verb, options) {
|
|
90
|
+
var isExternal, baseUrl, url, agent, response, headers, contentType, data, normalizedResponse;
|
|
91
|
+
return _regenerator.default.wrap(function _callee2$(_context2) {
|
|
92
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
41
93
|
case 0:
|
|
42
94
|
isExternal = /^[a-zA-Z]+:\/\//.test(path);
|
|
43
95
|
baseUrl = _Files.default.getBaseUrl();
|
|
44
96
|
if (!(!isExternal && !baseUrl)) {
|
|
45
|
-
|
|
97
|
+
_context2.next = 4;
|
|
46
98
|
break;
|
|
47
99
|
}
|
|
48
100
|
throw new errors.ConfigurationError('Base URL has not been set - use Files.setBaseUrl() to set it');
|
|
49
101
|
case 4:
|
|
50
102
|
url = isExternal ? path : "".concat(baseUrl).concat(_Files.default.getEndpointPrefix()).concat(path);
|
|
51
103
|
_Logger.default.debug("Sending request: ".concat(verb, " ").concat(url));
|
|
52
|
-
_Logger.default.debug('Sending options:', _objectSpread(_objectSpread({
|
|
104
|
+
_Logger.default.debug('Sending options:', _objectSpread(_objectSpread({
|
|
105
|
+
method: verb
|
|
106
|
+
}, options), {}, {
|
|
53
107
|
headers: _objectSpread(_objectSpread({}, options.headers), {}, {
|
|
54
108
|
'X-FilesAPI-Key': '<redacted>'
|
|
55
109
|
})
|
|
56
110
|
}));
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
return (
|
|
111
|
+
_context2.prev = 7;
|
|
112
|
+
agent = (options === null || options === void 0 ? void 0 : options.agent) || (options === null || options === void 0 ? void 0 : options.httpsAgent) || (options === null || options === void 0 ? void 0 : options.httpAgent);
|
|
113
|
+
_context2.next = 11;
|
|
114
|
+
return fetchWithRetry(url, _objectSpread({
|
|
115
|
+
agent: agent,
|
|
61
116
|
method: verb,
|
|
62
|
-
|
|
63
|
-
url: url
|
|
117
|
+
timeoutSecs: _Files.default.getNetworkTimeout()
|
|
64
118
|
}, options));
|
|
65
119
|
case 11:
|
|
66
|
-
response =
|
|
120
|
+
response = _context2.sent;
|
|
121
|
+
headers = Object.fromEntries(response.headers.entries());
|
|
67
122
|
_Logger.default.debug("Status: ".concat(response.status, " ").concat(response.statusText));
|
|
68
123
|
if (_Files.default.shouldDebugResponseHeaders()) {
|
|
69
124
|
_Logger.default.debug('Response Headers: ');
|
|
70
|
-
_Logger.default.debug(
|
|
125
|
+
_Logger.default.debug(headers);
|
|
126
|
+
}
|
|
127
|
+
contentType = headers['content-type'] || '';
|
|
128
|
+
if (!contentType.includes('application/json')) {
|
|
129
|
+
_context2.next = 22;
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
_context2.next = 19;
|
|
133
|
+
return response.json();
|
|
134
|
+
case 19:
|
|
135
|
+
data = _context2.sent;
|
|
136
|
+
_context2.next = 35;
|
|
137
|
+
break;
|
|
138
|
+
case 22:
|
|
139
|
+
if (!contentType.includes('text/')) {
|
|
140
|
+
_context2.next = 28;
|
|
141
|
+
break;
|
|
71
142
|
}
|
|
72
|
-
|
|
143
|
+
_context2.next = 25;
|
|
144
|
+
return response.text();
|
|
145
|
+
case 25:
|
|
146
|
+
data = _context2.sent;
|
|
147
|
+
_context2.next = 35;
|
|
148
|
+
break;
|
|
149
|
+
case 28:
|
|
150
|
+
if (!contentType.includes('multipart/form-data')) {
|
|
151
|
+
_context2.next = 34;
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
_context2.next = 31;
|
|
155
|
+
return response.formData();
|
|
156
|
+
case 31:
|
|
157
|
+
data = _context2.sent;
|
|
158
|
+
_context2.next = 35;
|
|
159
|
+
break;
|
|
160
|
+
case 34:
|
|
161
|
+
data = response.body;
|
|
162
|
+
case 35:
|
|
163
|
+
normalizedResponse = {
|
|
73
164
|
status: response.status,
|
|
74
165
|
reason: response.statusText,
|
|
75
|
-
headers:
|
|
76
|
-
data:
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
166
|
+
headers: headers,
|
|
167
|
+
data: data
|
|
168
|
+
};
|
|
169
|
+
if (response.ok) {
|
|
170
|
+
_context2.next = 38;
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
throw {
|
|
174
|
+
response: normalizedResponse
|
|
175
|
+
};
|
|
176
|
+
case 38:
|
|
177
|
+
return _context2.abrupt("return", normalizedResponse);
|
|
178
|
+
case 41:
|
|
179
|
+
_context2.prev = 41;
|
|
180
|
+
_context2.t0 = _context2["catch"](7);
|
|
181
|
+
errors.handleErrorResponse(_context2.t0);
|
|
182
|
+
case 44:
|
|
83
183
|
case "end":
|
|
84
|
-
return
|
|
184
|
+
return _context2.stop();
|
|
85
185
|
}
|
|
86
|
-
},
|
|
186
|
+
}, _callee2, null, [[7, 41]]);
|
|
87
187
|
}));
|
|
88
|
-
return function (
|
|
89
|
-
return
|
|
188
|
+
return function (_x3, _x4, _x5) {
|
|
189
|
+
return _ref3.apply(this, arguments);
|
|
90
190
|
};
|
|
91
191
|
}());
|
|
92
192
|
(0, _defineProperty2.default)(Api, "sendFilePart", function (externalUrl, verb, data) {
|
|
93
193
|
var headers = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
94
194
|
var params = {
|
|
95
|
-
|
|
195
|
+
body: data
|
|
96
196
|
};
|
|
97
197
|
if (headers) {
|
|
98
198
|
params.headers = headers;
|
|
@@ -100,20 +200,20 @@ var Api = /*#__PURE__*/(0, _createClass2.default)(function Api() {
|
|
|
100
200
|
return Api._sendVerbatim(externalUrl, verb, params);
|
|
101
201
|
});
|
|
102
202
|
(0, _defineProperty2.default)(Api, "_autoPaginate", /*#__PURE__*/function () {
|
|
103
|
-
var
|
|
203
|
+
var _ref4 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(path, verb, params, options, response, metadata) {
|
|
104
204
|
var _options$autoPaginate;
|
|
105
|
-
var _response$headers, nextCursor,
|
|
106
|
-
return _regenerator.default.wrap(function
|
|
107
|
-
while (1) switch (
|
|
205
|
+
var _response$headers, nextCursor, _ref5, autoPaginateCount, previousAutoPaginateData, nextPage, nextParams, nextMetadata;
|
|
206
|
+
return _regenerator.default.wrap(function _callee3$(_context3) {
|
|
207
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
108
208
|
case 0:
|
|
109
209
|
if (!((_options$autoPaginate = options.autoPaginate) !== null && _options$autoPaginate !== void 0 ? _options$autoPaginate : _Files.default.getAutoPaginate())) {
|
|
110
|
-
|
|
210
|
+
_context3.next = 12;
|
|
111
211
|
break;
|
|
112
212
|
}
|
|
113
213
|
nextCursor = response === null || response === void 0 || (_response$headers = response.headers) === null || _response$headers === void 0 ? void 0 : _response$headers['x-files-cursor'];
|
|
114
|
-
|
|
214
|
+
_ref5 = metadata || {}, autoPaginateCount = _ref5.autoPaginateCount, previousAutoPaginateData = _ref5.previousAutoPaginateData;
|
|
115
215
|
if (!nextCursor) {
|
|
116
|
-
|
|
216
|
+
_context3.next = 10;
|
|
117
217
|
break;
|
|
118
218
|
}
|
|
119
219
|
nextPage = (Number(params === null || params === void 0 ? void 0 : params.page) || 1) + 1;
|
|
@@ -125,30 +225,30 @@ var Api = /*#__PURE__*/(0, _createClass2.default)(function Api() {
|
|
|
125
225
|
autoPaginateCount: (autoPaginateCount || 1) + 1,
|
|
126
226
|
previousAutoPaginateData: [].concat((0, _toConsumableArray2.default)(previousAutoPaginateData || []), (0, _toConsumableArray2.default)((response === null || response === void 0 ? void 0 : response.data) || []))
|
|
127
227
|
};
|
|
128
|
-
return
|
|
228
|
+
return _context3.abrupt("return", Api.sendRequest(path, verb, nextParams, options, nextMetadata));
|
|
129
229
|
case 10:
|
|
130
230
|
if (!previousAutoPaginateData) {
|
|
131
|
-
|
|
231
|
+
_context3.next = 12;
|
|
132
232
|
break;
|
|
133
233
|
}
|
|
134
|
-
return
|
|
234
|
+
return _context3.abrupt("return", _objectSpread(_objectSpread({}, response), {}, {
|
|
135
235
|
autoPaginateRequests: autoPaginateCount,
|
|
136
236
|
data: [].concat((0, _toConsumableArray2.default)(previousAutoPaginateData), (0, _toConsumableArray2.default)((response === null || response === void 0 ? void 0 : response.data) || []))
|
|
137
237
|
}));
|
|
138
238
|
case 12:
|
|
139
|
-
return
|
|
239
|
+
return _context3.abrupt("return", response);
|
|
140
240
|
case 13:
|
|
141
241
|
case "end":
|
|
142
|
-
return
|
|
242
|
+
return _context3.stop();
|
|
143
243
|
}
|
|
144
|
-
},
|
|
244
|
+
}, _callee3);
|
|
145
245
|
}));
|
|
146
|
-
return function (
|
|
147
|
-
return
|
|
246
|
+
return function (_x6, _x7, _x8, _x9, _x10, _x11) {
|
|
247
|
+
return _ref4.apply(this, arguments);
|
|
148
248
|
};
|
|
149
249
|
}());
|
|
150
250
|
(0, _defineProperty2.default)(Api, "sendRequest", /*#__PURE__*/function () {
|
|
151
|
-
var
|
|
251
|
+
var _ref6 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(path, verb) {
|
|
152
252
|
var params,
|
|
153
253
|
options,
|
|
154
254
|
metadata,
|
|
@@ -162,13 +262,13 @@ var Api = /*#__PURE__*/(0, _createClass2.default)(function Api() {
|
|
|
162
262
|
hasParams,
|
|
163
263
|
pairs,
|
|
164
264
|
response,
|
|
165
|
-
|
|
166
|
-
return _regenerator.default.wrap(function
|
|
167
|
-
while (1) switch (
|
|
265
|
+
_args4 = arguments;
|
|
266
|
+
return _regenerator.default.wrap(function _callee4$(_context4) {
|
|
267
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
168
268
|
case 0:
|
|
169
|
-
params =
|
|
170
|
-
options =
|
|
171
|
-
metadata =
|
|
269
|
+
params = _args4.length > 2 && _args4[2] !== undefined ? _args4[2] : null;
|
|
270
|
+
options = _args4.length > 3 && _args4[3] !== undefined ? _args4[3] : {};
|
|
271
|
+
metadata = _args4.length > 4 && _args4[4] !== undefined ? _args4[4] : null;
|
|
172
272
|
headers = _objectSpread(_objectSpread({
|
|
173
273
|
Accept: 'application/json'
|
|
174
274
|
}, options.headers), {}, {
|
|
@@ -176,26 +276,26 @@ var Api = /*#__PURE__*/(0, _createClass2.default)(function Api() {
|
|
|
176
276
|
});
|
|
177
277
|
isExternal = /^[a-zA-Z]+:\/\//.test(path);
|
|
178
278
|
if (isExternal) {
|
|
179
|
-
|
|
279
|
+
_context4.next = 17;
|
|
180
280
|
break;
|
|
181
281
|
}
|
|
182
282
|
sessionId = options.sessionId || _Files.default.getSessionId();
|
|
183
283
|
if (!sessionId) {
|
|
184
|
-
|
|
284
|
+
_context4.next = 11;
|
|
185
285
|
break;
|
|
186
286
|
}
|
|
187
287
|
headers['X-FilesAPI-Auth'] = sessionId;
|
|
188
|
-
|
|
288
|
+
_context4.next = 17;
|
|
189
289
|
break;
|
|
190
290
|
case 11:
|
|
191
291
|
isCreatingSession = path === '/sessions' && verb.toUpperCase() === 'POST'; // api key cannot be used when creating a session
|
|
192
292
|
if (isCreatingSession) {
|
|
193
|
-
|
|
293
|
+
_context4.next = 17;
|
|
194
294
|
break;
|
|
195
295
|
}
|
|
196
296
|
apiKey = options.apiKey || _Files.default.getApiKey();
|
|
197
297
|
if (apiKey) {
|
|
198
|
-
|
|
298
|
+
_context4.next = 16;
|
|
199
299
|
break;
|
|
200
300
|
}
|
|
201
301
|
throw new errors.ConfigurationError('API key has not been set - use Files.setApiKey() to set it');
|
|
@@ -209,41 +309,41 @@ var Api = /*#__PURE__*/(0, _createClass2.default)(function Api() {
|
|
|
209
309
|
hasParams = (0, _utils.isObject)(params) && !(0, _utils.isEmpty)(params);
|
|
210
310
|
if (hasParams) {
|
|
211
311
|
if (verb.toUpperCase() === 'GET') {
|
|
212
|
-
pairs = Object.entries(params).map(function (
|
|
213
|
-
var
|
|
214
|
-
key =
|
|
215
|
-
value =
|
|
312
|
+
pairs = Object.entries(params).map(function (_ref7) {
|
|
313
|
+
var _ref8 = (0, _slicedToArray2.default)(_ref7, 2),
|
|
314
|
+
key = _ref8[0],
|
|
315
|
+
value = _ref8[1];
|
|
216
316
|
return "".concat(encodeURIComponent(key), "=").concat(encodeURIComponent(value));
|
|
217
317
|
});
|
|
218
318
|
requestPath += path.includes('?') ? '&' : '?';
|
|
219
319
|
requestPath += pairs.join('&');
|
|
220
320
|
} else {
|
|
221
|
-
updatedOptions.
|
|
321
|
+
updatedOptions.body = JSON.stringify(params);
|
|
222
322
|
headers['Content-Type'] = 'application/json';
|
|
223
323
|
}
|
|
224
324
|
}
|
|
225
325
|
if (_Files.default.shouldDebugRequest()) {
|
|
226
326
|
_Logger.default.debug('Request Options:');
|
|
227
327
|
_Logger.default.debug(_objectSpread(_objectSpread({}, updatedOptions), {}, {
|
|
228
|
-
|
|
328
|
+
body: hasParams ? "payload keys: ".concat(Object.keys(params).join(', ')) : '(none)',
|
|
229
329
|
headers: _objectSpread(_objectSpread({}, headers), {}, {
|
|
230
330
|
'X-FilesAPI-Key': '<redacted>'
|
|
231
331
|
})
|
|
232
332
|
}));
|
|
233
333
|
}
|
|
234
|
-
|
|
334
|
+
_context4.next = 24;
|
|
235
335
|
return Api._sendVerbatim(requestPath, verb, updatedOptions);
|
|
236
336
|
case 24:
|
|
237
|
-
response =
|
|
238
|
-
return
|
|
337
|
+
response = _context4.sent;
|
|
338
|
+
return _context4.abrupt("return", Api._autoPaginate(path, verb, params, updatedOptions, response, metadata));
|
|
239
339
|
case 26:
|
|
240
340
|
case "end":
|
|
241
|
-
return
|
|
341
|
+
return _context4.stop();
|
|
242
342
|
}
|
|
243
|
-
},
|
|
343
|
+
}, _callee4);
|
|
244
344
|
}));
|
|
245
|
-
return function (
|
|
246
|
-
return
|
|
345
|
+
return function (_x12, _x13) {
|
|
346
|
+
return _ref6.apply(this, arguments);
|
|
247
347
|
};
|
|
248
348
|
}());
|
|
249
349
|
var _default = Api;
|
package/lib/Errors.js
CHANGED
|
@@ -56,14 +56,14 @@ var handleErrorResponse = function handleErrorResponse(error) {
|
|
|
56
56
|
var message = ((_errorData = errorData) === null || _errorData === void 0 ? void 0 : _errorData.error) || (response === null || response === void 0 ? void 0 : response.statusText) || error.message;
|
|
57
57
|
var code = (response === null || response === void 0 ? void 0 : response.status) || ((_errorData2 = errorData) === null || _errorData2 === void 0 ? void 0 : _errorData2['http-code']) || 0;
|
|
58
58
|
if (!errorData) {
|
|
59
|
-
_Logger.default.error('FilesApiError Exception
|
|
59
|
+
_Logger.default.error('FilesApiError Exception:', code, message);
|
|
60
60
|
throw new FilesApiError(message, code);
|
|
61
61
|
}
|
|
62
62
|
if (Array.isArray(errorData)) {
|
|
63
63
|
errorData = errorData[0];
|
|
64
64
|
}
|
|
65
65
|
if (!errorData.type) {
|
|
66
|
-
_Logger.default.error('FilesApiError Exception
|
|
66
|
+
_Logger.default.error('FilesApiError Exception:', code, message);
|
|
67
67
|
throw new FilesApiError(message, code);
|
|
68
68
|
}
|
|
69
69
|
var parts = errorData.type.split('/');
|
|
@@ -24,8 +24,12 @@ var saveUrlToStream = /*#__PURE__*/function () {
|
|
|
24
24
|
var https = require('https');
|
|
25
25
|
https.get(url, function (response) {
|
|
26
26
|
response.pipe(stream);
|
|
27
|
-
stream.on('finish',
|
|
27
|
+
stream.on('finish', function () {
|
|
28
|
+
stream.close();
|
|
29
|
+
resolve();
|
|
30
|
+
});
|
|
28
31
|
}).on('error', function (error) {
|
|
32
|
+
stream.close();
|
|
29
33
|
reject(error);
|
|
30
34
|
});
|
|
31
35
|
}));
|
|
@@ -80,8 +84,6 @@ var saveUrlToFile = /*#__PURE__*/function () {
|
|
|
80
84
|
_context3.next = 3;
|
|
81
85
|
return saveUrlToStream(url, stream);
|
|
82
86
|
case 3:
|
|
83
|
-
stream.close();
|
|
84
|
-
case 4:
|
|
85
87
|
case "end":
|
|
86
88
|
return _context3.stop();
|
|
87
89
|
}
|
package/lib/models/Automation.js
CHANGED
|
@@ -59,7 +59,7 @@ var Automation = /*#__PURE__*/(0, _createClass2.default)(function Automation() {
|
|
|
59
59
|
(0, _defineProperty2.default)(this, "setDisabled", function (value) {
|
|
60
60
|
_this.attributes.disabled = value;
|
|
61
61
|
});
|
|
62
|
-
// string # How this automation is triggered to run.
|
|
62
|
+
// string # How this automation is triggered to run.
|
|
63
63
|
(0, _defineProperty2.default)(this, "getTrigger", function () {
|
|
64
64
|
return _this.attributes.trigger;
|
|
65
65
|
});
|
|
@@ -101,7 +101,7 @@ var Automation = /*#__PURE__*/(0, _createClass2.default)(function Automation() {
|
|
|
101
101
|
(0, _defineProperty2.default)(this, "setSource", function (value) {
|
|
102
102
|
_this.attributes.source = value;
|
|
103
103
|
});
|
|
104
|
-
// array # Destination
|
|
104
|
+
// array # Destination Paths
|
|
105
105
|
(0, _defineProperty2.default)(this, "getDestinations", function () {
|
|
106
106
|
return _this.attributes.destinations;
|
|
107
107
|
});
|
|
@@ -267,7 +267,7 @@ var Automation = /*#__PURE__*/(0, _createClass2.default)(function Automation() {
|
|
|
267
267
|
// description - string - Description for the this Automation.
|
|
268
268
|
// disabled - boolean - If true, this automation will not run.
|
|
269
269
|
// name - string - Name for this automation.
|
|
270
|
-
// trigger - string - How this automation is triggered to run.
|
|
270
|
+
// trigger - string - How this automation is triggered to run.
|
|
271
271
|
// trigger_actions - array(string) - If trigger is `action`, this is the list of action types on which to trigger the automation. Valid actions are create, read, update, destroy, move, copy
|
|
272
272
|
// value - object - A Hash of attributes specific to the automation type.
|
|
273
273
|
// recurring_day - int64 - If trigger type is `daily`, this specifies a day number to run in one of the supported intervals: `week`, `month`, `quarter`, `year`.
|
|
@@ -616,7 +616,7 @@ var Automation = /*#__PURE__*/(0, _createClass2.default)(function Automation() {
|
|
|
616
616
|
// description - string - Description for the this Automation.
|
|
617
617
|
// disabled - boolean - If true, this automation will not run.
|
|
618
618
|
// name - string - Name for this automation.
|
|
619
|
-
// trigger - string - How this automation is triggered to run.
|
|
619
|
+
// trigger - string - How this automation is triggered to run.
|
|
620
620
|
// trigger_actions - array(string) - If trigger is `action`, this is the list of action types on which to trigger the automation. Valid actions are create, read, update, destroy, move, copy
|
|
621
621
|
// value - object - A Hash of attributes specific to the automation type.
|
|
622
622
|
// recurring_day - int64 - If trigger type is `daily`, this specifies a day number to run in one of the supported intervals: `week`, `month`, `quarter`, `year`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "files.com",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.297",
|
|
4
4
|
"description": "Files.com SDK for JavaScript",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"files.com",
|
|
@@ -20,8 +20,7 @@
|
|
|
20
20
|
"main": "lib/files.js",
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@babel/runtime": "^7.10.3",
|
|
23
|
-
"
|
|
24
|
-
"axios-retry": "^3.5.0",
|
|
23
|
+
"cross-fetch": "^4.0.0",
|
|
25
24
|
"readable-stream": "^4.4.0",
|
|
26
25
|
"safe-buffer": "^5.2.1"
|
|
27
26
|
},
|
package/src/Api.js
CHANGED
|
@@ -1,29 +1,45 @@
|
|
|
1
|
-
import
|
|
2
|
-
import axiosRetry from 'axios-retry'
|
|
1
|
+
import fetch from 'cross-fetch'
|
|
3
2
|
|
|
4
3
|
import Files from './Files'
|
|
5
4
|
import * as errors from './Errors'
|
|
6
5
|
import Logger from './Logger'
|
|
7
6
|
import { isEmpty, isObject } from './utils'
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
8
|
+
const _fetchWithTimeout = (url, { timeoutSecs, ...options } = {}) =>
|
|
9
|
+
timeoutSecs <= 0
|
|
10
|
+
? fetch(url, options)
|
|
11
|
+
: Promise.race([
|
|
12
|
+
fetch(url, options),
|
|
13
|
+
new Promise((_, reject) => {
|
|
14
|
+
setTimeout(() => reject(new errors.FilesError('Request timed out')), timeoutSecs * 1000)
|
|
15
|
+
})
|
|
16
|
+
])
|
|
17
|
+
|
|
18
|
+
const fetchWithRetry = async (url, options, retries = 0) => {
|
|
19
|
+
const maxRetries = Files.getMaxNetworkRetries()
|
|
20
|
+
const minRetryDelaySecs = Files.getMinNetworkRetryDelay()
|
|
21
|
+
const maxRetryDelaySecs = Files.getMaxNetworkRetryDelay()
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
return await _fetchWithTimeout(url, options)
|
|
25
|
+
} catch (error) {
|
|
26
|
+
Logger.info(`Request #${retries + 1} failed: ${error.message}`)
|
|
27
|
+
|
|
28
|
+
if (retries >= maxRetries) {
|
|
29
|
+
throw error
|
|
30
|
+
} else {
|
|
31
|
+
const nextRetries = retries + 1
|
|
32
|
+
Logger.info(`Retrying request (retry ${nextRetries} of ${maxRetries})`)
|
|
33
|
+
|
|
34
|
+
const delaySecs = Math.min(minRetryDelaySecs * 2 ** retries, maxRetryDelaySecs) // exponential backoff
|
|
35
|
+
await new Promise(resolve => setTimeout(resolve, delaySecs * 1000))
|
|
36
|
+
|
|
37
|
+
return fetchWithRetry(url, options, nextRetries)
|
|
38
|
+
}
|
|
25
39
|
}
|
|
40
|
+
}
|
|
26
41
|
|
|
42
|
+
class Api {
|
|
27
43
|
static _sendVerbatim = async (path, verb, options) => {
|
|
28
44
|
const isExternal = /^[a-zA-Z]+:\/\//.test(path)
|
|
29
45
|
const baseUrl = Files.getBaseUrl()
|
|
@@ -39,6 +55,7 @@ class Api {
|
|
|
39
55
|
Logger.debug(`Sending request: ${verb} ${url}`)
|
|
40
56
|
|
|
41
57
|
Logger.debug('Sending options:', {
|
|
58
|
+
method: verb,
|
|
42
59
|
...options,
|
|
43
60
|
headers: {
|
|
44
61
|
...options.headers,
|
|
@@ -46,36 +63,57 @@ class Api {
|
|
|
46
63
|
},
|
|
47
64
|
})
|
|
48
65
|
|
|
49
|
-
Api._configureAutoRetry()
|
|
50
|
-
|
|
51
66
|
try {
|
|
52
|
-
const
|
|
67
|
+
const agent = options?.agent || options?.httpsAgent || options?.httpAgent
|
|
68
|
+
|
|
69
|
+
const response = await fetchWithRetry(url, {
|
|
70
|
+
agent,
|
|
53
71
|
method: verb,
|
|
54
|
-
|
|
55
|
-
url,
|
|
72
|
+
timeoutSecs: Files.getNetworkTimeout(),
|
|
56
73
|
...options,
|
|
57
74
|
})
|
|
58
75
|
|
|
76
|
+
const headers = Object.fromEntries(response.headers.entries())
|
|
77
|
+
|
|
59
78
|
Logger.debug(`Status: ${response.status} ${response.statusText}`)
|
|
60
79
|
|
|
61
80
|
if (Files.shouldDebugResponseHeaders()) {
|
|
62
81
|
Logger.debug('Response Headers: ')
|
|
63
|
-
Logger.debug(
|
|
82
|
+
Logger.debug(headers)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const contentType = headers['content-type'] || ''
|
|
86
|
+
let data
|
|
87
|
+
|
|
88
|
+
if (contentType.includes('application/json')) {
|
|
89
|
+
data = await response.json()
|
|
90
|
+
} else if (contentType.includes('text/')) {
|
|
91
|
+
data = await response.text()
|
|
92
|
+
} else if (contentType.includes('multipart/form-data')) {
|
|
93
|
+
data = await response.formData()
|
|
94
|
+
} else {
|
|
95
|
+
data = response.body
|
|
64
96
|
}
|
|
65
97
|
|
|
66
|
-
|
|
98
|
+
const normalizedResponse = {
|
|
67
99
|
status: response.status,
|
|
68
100
|
reason: response.statusText,
|
|
69
|
-
headers
|
|
70
|
-
data
|
|
101
|
+
headers,
|
|
102
|
+
data,
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (!response.ok) {
|
|
106
|
+
throw { response: normalizedResponse }
|
|
71
107
|
}
|
|
108
|
+
|
|
109
|
+
return normalizedResponse
|
|
72
110
|
} catch (error) {
|
|
73
111
|
errors.handleErrorResponse(error)
|
|
74
112
|
}
|
|
75
113
|
}
|
|
76
114
|
|
|
77
115
|
static sendFilePart = (externalUrl, verb, data, headers = {}) => {
|
|
78
|
-
const params = { data }
|
|
116
|
+
const params = { body: data }
|
|
79
117
|
|
|
80
118
|
if (headers) {
|
|
81
119
|
params.headers = headers
|
|
@@ -166,7 +204,7 @@ class Api {
|
|
|
166
204
|
requestPath += path.includes('?') ? '&' : '?'
|
|
167
205
|
requestPath += pairs.join('&')
|
|
168
206
|
} else {
|
|
169
|
-
updatedOptions.
|
|
207
|
+
updatedOptions.body = JSON.stringify(params)
|
|
170
208
|
headers['Content-Type'] = 'application/json'
|
|
171
209
|
}
|
|
172
210
|
}
|
|
@@ -175,7 +213,7 @@ class Api {
|
|
|
175
213
|
Logger.debug('Request Options:')
|
|
176
214
|
Logger.debug({
|
|
177
215
|
...updatedOptions,
|
|
178
|
-
|
|
216
|
+
body: hasParams
|
|
179
217
|
? `payload keys: ${Object.keys(params).join(', ')}`
|
|
180
218
|
: '(none)',
|
|
181
219
|
headers: {
|
package/src/Errors.js
CHANGED
|
@@ -32,7 +32,7 @@ export const handleErrorResponse = error => {
|
|
|
32
32
|
const code = response?.status || errorData?.['http-code'] || 0
|
|
33
33
|
|
|
34
34
|
if (!errorData) {
|
|
35
|
-
Logger.error('FilesApiError Exception
|
|
35
|
+
Logger.error('FilesApiError Exception:', code, message)
|
|
36
36
|
throw new FilesApiError(message, code)
|
|
37
37
|
}
|
|
38
38
|
|
|
@@ -41,7 +41,7 @@ export const handleErrorResponse = error => {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
if (!errorData.type) {
|
|
44
|
-
Logger.error('FilesApiError Exception
|
|
44
|
+
Logger.error('FilesApiError Exception:', code, message)
|
|
45
45
|
throw new FilesApiError(message, code)
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -14,9 +14,13 @@ const saveUrlToStream = async (url, stream) => new Promise((resolve, reject) =>
|
|
|
14
14
|
https.get(url, response => {
|
|
15
15
|
response.pipe(stream)
|
|
16
16
|
|
|
17
|
-
stream.on('finish',
|
|
17
|
+
stream.on('finish', () => {
|
|
18
|
+
stream.close()
|
|
19
|
+
resolve()
|
|
20
|
+
})
|
|
18
21
|
})
|
|
19
22
|
.on('error', error => {
|
|
23
|
+
stream.close()
|
|
20
24
|
reject(error)
|
|
21
25
|
})
|
|
22
26
|
})
|
|
@@ -37,7 +41,6 @@ const saveUrlToString = async url => new Promise((resolve, reject) => {
|
|
|
37
41
|
const saveUrlToFile = async (url, destinationPath) => {
|
|
38
42
|
const stream = openDiskFileWriteStream(destinationPath)
|
|
39
43
|
await saveUrlToStream(url, stream)
|
|
40
|
-
stream.close()
|
|
41
44
|
}
|
|
42
45
|
|
|
43
46
|
export {
|
package/src/models/Automation.js
CHANGED
|
@@ -51,7 +51,7 @@ class Automation {
|
|
|
51
51
|
this.attributes.disabled = value
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
// string # How this automation is triggered to run.
|
|
54
|
+
// string # How this automation is triggered to run.
|
|
55
55
|
getTrigger = () => this.attributes.trigger
|
|
56
56
|
|
|
57
57
|
setTrigger = value => {
|
|
@@ -93,7 +93,7 @@ class Automation {
|
|
|
93
93
|
this.attributes.source = value
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
// array # Destination
|
|
96
|
+
// array # Destination Paths
|
|
97
97
|
getDestinations = () => this.attributes.destinations
|
|
98
98
|
|
|
99
99
|
setDestinations = value => {
|
|
@@ -235,7 +235,7 @@ class Automation {
|
|
|
235
235
|
// description - string - Description for the this Automation.
|
|
236
236
|
// disabled - boolean - If true, this automation will not run.
|
|
237
237
|
// name - string - Name for this automation.
|
|
238
|
-
// trigger - string - How this automation is triggered to run.
|
|
238
|
+
// trigger - string - How this automation is triggered to run.
|
|
239
239
|
// trigger_actions - array(string) - If trigger is `action`, this is the list of action types on which to trigger the automation. Valid actions are create, read, update, destroy, move, copy
|
|
240
240
|
// value - object - A Hash of attributes specific to the automation type.
|
|
241
241
|
// recurring_day - int64 - If trigger type is `daily`, this specifies a day number to run in one of the supported intervals: `week`, `month`, `quarter`, `year`.
|
|
@@ -422,7 +422,7 @@ class Automation {
|
|
|
422
422
|
// description - string - Description for the this Automation.
|
|
423
423
|
// disabled - boolean - If true, this automation will not run.
|
|
424
424
|
// name - string - Name for this automation.
|
|
425
|
-
// trigger - string - How this automation is triggered to run.
|
|
425
|
+
// trigger - string - How this automation is triggered to run.
|
|
426
426
|
// trigger_actions - array(string) - If trigger is `action`, this is the list of action types on which to trigger the automation. Valid actions are create, read, update, destroy, move, copy
|
|
427
427
|
// value - object - A Hash of attributes specific to the automation type.
|
|
428
428
|
// recurring_day - int64 - If trigger type is `daily`, this specifies a day number to run in one of the supported intervals: `week`, `month`, `quarter`, `year`.
|
package/test/package.json
CHANGED
package/test/src/index.js
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import assert from 'assert'
|
|
2
|
-
// import * as errors from 'files.com/lib/Errors'
|
|
3
|
-
const errors = require('files.com/lib/Errors')
|
|
4
1
|
import Files from 'files.com/lib/Files'
|
|
5
2
|
import Logger, { LogLevel } from 'files.com/lib/Logger'
|
|
6
3
|
import ApiKey from 'files.com/lib/models/ApiKey'
|
|
@@ -9,6 +6,9 @@ import Folder from 'files.com/lib/models/Folder'
|
|
|
9
6
|
import Session from 'files.com/lib/models/Session'
|
|
10
7
|
import User from 'files.com/lib/models/User'
|
|
11
8
|
import { isBrowser } from 'files.com/lib/utils'
|
|
9
|
+
import invariant from 'tiny-invariant'
|
|
10
|
+
|
|
11
|
+
const errors = require('files.com/lib/Errors')
|
|
12
12
|
|
|
13
13
|
// name of an existing folder in your root to create/delete test files and folders
|
|
14
14
|
const SDK_TEST_ROOT_FOLDER = 'sdk-test'
|
|
@@ -32,11 +32,17 @@ if (apiDomain.substr(-10) === 'staging.av') {
|
|
|
32
32
|
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
const DEBUG_MODE = false
|
|
36
|
+
|
|
37
|
+
Files.setLogLevel(DEBUG_MODE ? LogLevel.DEBUG : LogLevel.INFO)
|
|
36
38
|
|
|
37
39
|
Files.configureDebugging({
|
|
38
|
-
debugRequest:
|
|
39
|
-
debugResponseHeaders:
|
|
40
|
+
debugRequest: DEBUG_MODE,
|
|
41
|
+
debugResponseHeaders: DEBUG_MODE,
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
Files.configureNetwork({
|
|
45
|
+
networkTimeout: DEBUG_MODE ? 10 : 30,
|
|
40
46
|
})
|
|
41
47
|
|
|
42
48
|
const testSuite = async () => {
|
|
@@ -49,7 +55,7 @@ const testSuite = async () => {
|
|
|
49
55
|
|
|
50
56
|
const firstPageItems = await Folder.listFor('/', { per_page: 1 })
|
|
51
57
|
|
|
52
|
-
|
|
58
|
+
invariant(firstPageItems.length === 1, 'First page should have 1 item')
|
|
53
59
|
|
|
54
60
|
Files.configureNetwork({
|
|
55
61
|
autoPaginate: true,
|
|
@@ -59,7 +65,7 @@ const testSuite = async () => {
|
|
|
59
65
|
const allPageItems = await Folder.listFor('/', { per_page: 1 })
|
|
60
66
|
|
|
61
67
|
// if auto-pagination executed, we'll have found more than just the 1 we requested
|
|
62
|
-
|
|
68
|
+
invariant(allPageItems.length > 1, 'Auto-pagination should have found more than 1 item across all pages')
|
|
63
69
|
|
|
64
70
|
Logger.info('***** testFolderListAutoPagination() succeeded! *****')
|
|
65
71
|
}
|
|
@@ -72,18 +78,20 @@ const testSuite = async () => {
|
|
|
72
78
|
|
|
73
79
|
const file = await File.uploadFile(destinationPath, sourceFilePath)
|
|
74
80
|
|
|
75
|
-
|
|
76
|
-
|
|
81
|
+
invariant(!!file.path, 'Uploaded file response object should have a path')
|
|
82
|
+
invariant(file.display_name === displayName, 'Uploaded file response object should have the same display_name as the file we uploaded')
|
|
77
83
|
|
|
78
84
|
const foundFile = await File.find(destinationPath)
|
|
79
85
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
86
|
+
invariant(foundFile.path === destinationPath, 'Found file should have the same path as the file we uploaded')
|
|
87
|
+
invariant(foundFile.display_name === displayName, 'Found file should have the same display_name as the file we uploaded')
|
|
88
|
+
invariant(typeof foundFile.getDownloadUri() === 'undefined', 'Found file should not have a download uri yet')
|
|
83
89
|
|
|
84
90
|
if (!isBrowser()) {
|
|
85
91
|
const downloadableFile = await foundFile.download()
|
|
86
|
-
|
|
92
|
+
|
|
93
|
+
invariant(downloadableFile.size > 0, 'Uploaded file should not be empty')
|
|
94
|
+
invariant(typeof downloadableFile.getDownloadUri() !== 'undefined', 'Downloadable file should have a download uri')
|
|
87
95
|
|
|
88
96
|
const downloadPath = `./${displayName}`
|
|
89
97
|
await downloadableFile.downloadToFile(downloadPath)
|
|
@@ -92,7 +100,8 @@ const testSuite = async () => {
|
|
|
92
100
|
const originalBuffer = fs.readFileSync(sourceFilePath)
|
|
93
101
|
const downloadedBuffer = fs.readFileSync(downloadPath)
|
|
94
102
|
|
|
95
|
-
|
|
103
|
+
invariant(originalBuffer.length === downloadedBuffer.length, 'Source file length should match downloaded file length')
|
|
104
|
+
invariant(originalBuffer.equals(downloadedBuffer), 'Source file contents should match downloaded file contents')
|
|
96
105
|
|
|
97
106
|
fs.unlinkSync(downloadPath)
|
|
98
107
|
}
|
|
@@ -109,22 +118,22 @@ const testSuite = async () => {
|
|
|
109
118
|
const sourceFileContents = 'The quick brown fox jumped over the lazy dogs.'
|
|
110
119
|
const file = await File.uploadData(destinationPath, sourceFileContents)
|
|
111
120
|
|
|
112
|
-
|
|
113
|
-
|
|
121
|
+
invariant(!!file.path, 'Uploaded file response object should have a path')
|
|
122
|
+
invariant(file.display_name === displayName, 'Uploaded file response object should have the same display_name as the file we uploaded')
|
|
114
123
|
|
|
115
124
|
const foundFile = await File.find(destinationPath)
|
|
116
125
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
126
|
+
invariant(foundFile.path === destinationPath, 'Found file should have the same path as the file we uploaded')
|
|
127
|
+
invariant(foundFile.display_name === displayName, 'Found file should have the same display_name as the file we uploaded')
|
|
128
|
+
invariant(typeof foundFile.getDownloadUri() === 'undefined', 'Found file should not have a download uri yet')
|
|
120
129
|
|
|
121
130
|
if (!isBrowser()) {
|
|
122
131
|
const downloadableFile = await foundFile.download()
|
|
123
|
-
|
|
132
|
+
invariant(typeof downloadableFile.getDownloadUri() !== 'undefined', 'Downloadable file should have a download uri')
|
|
124
133
|
|
|
125
134
|
const downloadedFileContents = await downloadableFile.downloadToString()
|
|
126
135
|
|
|
127
|
-
|
|
136
|
+
invariant(sourceFileContents === downloadedFileContents, 'Source file contents should match downloaded file contents')
|
|
128
137
|
}
|
|
129
138
|
|
|
130
139
|
await file.delete()
|
|
@@ -141,14 +150,14 @@ const testSuite = async () => {
|
|
|
141
150
|
|
|
142
151
|
const file = await File.uploadFile(destinationPath, sourceFilePath)
|
|
143
152
|
|
|
144
|
-
|
|
145
|
-
|
|
153
|
+
invariant(!!file.path, 'Uploaded file response object should have a path')
|
|
154
|
+
invariant(file.display_name === displayName, 'Uploaded file response object should have the same display_name as the file we uploaded')
|
|
146
155
|
|
|
147
156
|
const foundFile = await File.find(destinationPath)
|
|
148
157
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
158
|
+
invariant(foundFile.path === destinationPath, 'Found file should have the same path as the file we uploaded')
|
|
159
|
+
invariant(foundFile.display_name === displayName, 'Found file should have the same display_name as the file we uploaded')
|
|
160
|
+
invariant(typeof foundFile.getDownloadUri() === 'undefined', 'Found file should not have a download uri yet')
|
|
152
161
|
|
|
153
162
|
await file.delete()
|
|
154
163
|
|
|
@@ -167,7 +176,7 @@ const testSuite = async () => {
|
|
|
167
176
|
|
|
168
177
|
const session = await Session.create({ username, password })
|
|
169
178
|
|
|
170
|
-
|
|
179
|
+
invariant(!!session.id, 'Session should have an id')
|
|
171
180
|
|
|
172
181
|
const manual = await ApiKey.list({ user_id: 0 }, { sessionId: session.id })
|
|
173
182
|
|
|
@@ -175,7 +184,7 @@ const testSuite = async () => {
|
|
|
175
184
|
|
|
176
185
|
const auto = await ApiKey.list({ user_id: 0 })
|
|
177
186
|
|
|
178
|
-
|
|
187
|
+
invariant(JSON.stringify(manual.attributes) === JSON.stringify(auto.attributes), 'Manual and auto session API key lists should match')
|
|
179
188
|
|
|
180
189
|
await Session.destroy()
|
|
181
190
|
|
|
@@ -197,7 +206,7 @@ const testSuite = async () => {
|
|
|
197
206
|
caughtInvalidCredentialsError = error instanceof errors.NotAuthenticated_InvalidCredentialsError
|
|
198
207
|
}
|
|
199
208
|
|
|
200
|
-
|
|
209
|
+
invariant(caughtInvalidCredentialsError === true, 'should have caught an invalid credentials error')
|
|
201
210
|
|
|
202
211
|
// restore valid api key
|
|
203
212
|
Files.setApiKey(apiKey)
|
|
@@ -218,9 +227,9 @@ const testSuite = async () => {
|
|
|
218
227
|
|
|
219
228
|
const updatedUser = await User.find(firstUser.id)
|
|
220
229
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
230
|
+
invariant(updatedUser.isLoaded(), 'updated user should be loaded')
|
|
231
|
+
invariant(oldName !== newName, 'old name should not equal new name')
|
|
232
|
+
invariant(updatedUser.name === newName, 'updated user name should match new name')
|
|
224
233
|
|
|
225
234
|
Logger.info('***** testUserListAndUpdate() succeeded! *****');
|
|
226
235
|
}
|
|
@@ -229,13 +238,18 @@ const testSuite = async () => {
|
|
|
229
238
|
// execute all tests
|
|
230
239
|
//
|
|
231
240
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
241
|
+
try {
|
|
242
|
+
await testFolderListAutoPagination()
|
|
243
|
+
await testUploadAndDownloadToFile()
|
|
244
|
+
await testUploadAndDownloadToString()
|
|
245
|
+
// await testUploadHugeFile() // to run this test, put a file (or symlink) at huge-file.ext
|
|
246
|
+
await testSession()
|
|
247
|
+
await testFailure()
|
|
248
|
+
await testUserListAndUpdate()
|
|
249
|
+
} catch (error) {
|
|
250
|
+
console.log('*** TEST SUITE FAILED ***')
|
|
251
|
+
console.error(error)
|
|
252
|
+
}
|
|
239
253
|
}
|
|
240
254
|
|
|
241
255
|
export default testSuite
|