UNPKG

24.1 kBJavaScriptView Raw
1'use strict';
2
3var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
4
5var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
6
7var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8
9function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
10
11function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
12
13function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
14
15var _require = require("./config"),
16 upload_prefix = _require.upload_prefix;
17
18var isSecure = !(upload_prefix && upload_prefix.slice(0, 5) === 'http:');
19var https = isSecure ? require('https') : require('http');
20
21var fs = require('fs');
22var path = require('path');
23var Q = require('q');
24var Writable = require("stream").Writable;
25
26var defaultsDeep = require('lodash/defaultsDeep');
27
28var UploadStream = require('./upload_stream');
29var utils = require("./utils");
30var extend = utils.extend,
31 includes = utils.includes,
32 isArray = utils.isArray,
33 isObject = utils.isObject,
34 build_upload_params = utils.build_upload_params;
35
36var Cache = require('./cache');
37var entries = require('./utils/entries');
38
39exports.unsigned_upload_stream = function unsigned_upload_stream(upload_preset, callback) {
40 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
41
42 return exports.upload_stream(callback, utils.merge(options, {
43 unsigned: true,
44 upload_preset: upload_preset
45 }));
46};
47
48exports.upload_stream = function upload_stream(callback) {
49 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
50
51 return exports.upload(null, callback, extend({
52 stream: true
53 }, options));
54};
55
56exports.unsigned_upload = function unsigned_upload(file, upload_preset, callback) {
57 var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
58
59 return exports.upload(file, callback, utils.merge(options, {
60 unsigned: true,
61 upload_preset: upload_preset
62 }));
63};
64
65exports.upload = function upload(file, callback) {
66 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
67
68 return call_api("upload", callback, options, function () {
69 var params = build_upload_params(options);
70 if (file != null && file.match(/^ftp:|^https?:|^s3:|^data:[^;]*;base64,([a-zA-Z0-9\/+\n=]+)$/)) {
71 return [params, { file: file }];
72 } else {
73 return [params, {}, file];
74 }
75 });
76};
77
78exports.upload_large = function upload_large(path, callback) {
79 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
80
81 if (path != null && path.match(/^https?:/)) {
82 return exports.upload(path, callback, options);
83 } else {
84 return exports.upload_chunked(path, callback, extend({
85 resource_type: 'raw'
86 }, options));
87 }
88};
89
90exports.upload_chunked = function upload_chunked(path, callback, options) {
91 var file_reader = fs.createReadStream(path);
92 var out_stream = exports.upload_chunked_stream(callback, options);
93 return file_reader.pipe(out_stream);
94};
95
96var Chunkable = function (_Writable) {
97 _inherits(Chunkable, _Writable);
98
99 function Chunkable(options) {
100 _classCallCheck(this, Chunkable);
101
102 var _this = _possibleConstructorReturn(this, (Chunkable.__proto__ || Object.getPrototypeOf(Chunkable)).call(this, options));
103
104 _this.chunk_size = options.chunk_size != null ? options.chunk_size : 20000000;
105 _this.buffer = new Buffer(0);
106 _this.active = true;
107 _this.on('finish', function () {
108 if (_this.active) {
109 return _this.emit('ready', _this.buffer, true, function () {});
110 }
111 });
112 return _this;
113 }
114
115 _createClass(Chunkable, [{
116 key: '_write',
117 value: function _write(data, encoding, done) {
118 var _this2 = this;
119
120 if (!this.active) {
121 return done();
122 }
123 if (this.buffer.length + data.length <= this.chunk_size) {
124 this.buffer = Buffer.concat([this.buffer, data], this.buffer.length + data.length);
125 return done();
126 } else {
127 var grab = this.chunk_size - this.buffer.length;
128 this.buffer = Buffer.concat([this.buffer, data.slice(0, grab)], this.buffer.length + grab);
129 return this.emit('ready', this.buffer, false, function (active) {
130 _this2.active = active;
131 if (_this2.active) {
132 _this2.buffer = data.slice(grab);
133 return done();
134 }
135 });
136 }
137 }
138 }]);
139
140 return Chunkable;
141}(Writable);
142
143;
144
145exports.upload_large_stream = function upload_large_stream(_unused_, callback) {
146 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
147
148 return exports.upload_chunked_stream(callback, extend({
149 resource_type: 'raw'
150 }, options));
151};
152
153exports.upload_chunked_stream = function upload_chunked_stream(callback) {
154 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
155
156 options = extend({}, options, {
157 stream: true
158 });
159 options.x_unique_upload_id = utils.random_public_id();
160 var params = build_upload_params(options);
161 var chunk_size = options.chunk_size != null ? options.chunk_size : options.part_size;
162 var chunker = new Chunkable({
163 chunk_size: chunk_size
164 });
165 var sent = 0;
166 chunker.on('ready', function (buffer, is_last, done) {
167 var chunk_start = sent;
168 sent += buffer.length;
169 options.content_range = `bytes ${chunk_start}-${sent - 1}/${is_last ? sent : -1}`;
170 params.timestamp = utils.timestamp();
171 var finished_part = function finished_part(result) {
172 if (result.error != null || is_last) {
173 if (typeof callback === "function") {
174 callback(result);
175 }
176 return done(false);
177 } else {
178 return done(true);
179 }
180 };
181 var stream = call_api("upload", finished_part, options, function () {
182 return [params, {}, buffer];
183 });
184 return stream.write(buffer, 'buffer', function () {
185 return stream.end();
186 });
187 });
188 return chunker;
189};
190
191exports.explicit = function explicit(public_id, callback) {
192 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
193
194 return call_api("explicit", callback, options, function () {
195 return utils.build_explicit_api_params(public_id, options);
196 });
197};
198
199// Creates a new archive in the server and returns information in JSON format
200exports.create_archive = function create_archive(callback) {
201 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
202 var target_format = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
203
204 return call_api("generate_archive", callback, options, function () {
205 var opt = utils.archive_params(options);
206 if (target_format) {
207 opt.target_format = target_format;
208 }
209 return [opt];
210 });
211};
212
213// Creates a new zip archive in the server and returns information in JSON format
214exports.create_zip = function create_zip(callback) {
215 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
216
217 return exports.create_archive(callback, options, "zip");
218};
219
220exports.destroy = function destroy(public_id, callback) {
221 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
222
223 return call_api("destroy", callback, options, function () {
224 return [{
225 timestamp: utils.timestamp(),
226 type: options.type,
227 invalidate: options.invalidate,
228 public_id: public_id
229 }];
230 });
231};
232
233exports.rename = function rename(from_public_id, to_public_id, callback) {
234 var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
235
236 return call_api("rename", callback, options, function () {
237 return [{
238 timestamp: utils.timestamp(),
239 type: options.type,
240 from_public_id: from_public_id,
241 to_public_id: to_public_id,
242 overwrite: options.overwrite,
243 invalidate: options.invalidate,
244 to_type: options.to_type
245 }];
246 });
247};
248
249var TEXT_PARAMS = ["public_id", "font_family", "font_size", "font_color", "text_align", "font_weight", "font_style", "background", "opacity", "text_decoration"];
250
251exports.text = function text(text, callback) {
252 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
253
254 return call_api("text", callback, options, function () {
255 var textParams = utils.only(options, TEXT_PARAMS);
256 var params = _extends({
257 timestamp: utils.timestamp(),
258 text: text
259 }, textParams);
260
261 return [params];
262 });
263};
264
265exports.generate_sprite = function generate_sprite(tag, callback) {
266 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
267
268 return call_api("sprite", callback, options, function () {
269 var transformation = utils.generate_transformation_string(extend({}, options, {
270 fetch_format: options.format
271 }));
272 return [{
273 timestamp: utils.timestamp(),
274 tag: tag,
275 transformation: transformation,
276 async: options.async,
277 notification_url: options.notification_url
278 }];
279 });
280};
281
282exports.multi = function multi(tag, callback) {
283 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
284
285 return call_api("multi", callback, options, function () {
286 var transformation = utils.generate_transformation_string(extend({}, options));
287 return [{
288 timestamp: utils.timestamp(),
289 tag: tag,
290 transformation: transformation,
291 format: options.format,
292 async: options.async,
293 notification_url: options.notification_url
294 }];
295 });
296};
297
298exports.explode = function explode(public_id, callback) {
299 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
300
301 return call_api("explode", callback, options, function () {
302 var transformation = utils.generate_transformation_string(extend({}, options));
303 return [{
304 timestamp: utils.timestamp(),
305 public_id: public_id,
306 transformation: transformation,
307 format: options.format,
308 type: options.type,
309 notification_url: options.notification_url
310 }];
311 });
312};
313
314// options may include 'exclusive' (boolean) which causes clearing this tag from all other resources
315exports.add_tag = function add_tag(tag) {
316 var public_ids = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
317 var callback = arguments[2];
318 var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
319
320 var exclusive = utils.option_consume("exclusive", options);
321 var command = exclusive ? "set_exclusive" : "add";
322 return call_tags_api(tag, command, public_ids, callback, options);
323};
324
325exports.remove_tag = function remove_tag(tag) {
326 var public_ids = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
327 var callback = arguments[2];
328 var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
329
330 return call_tags_api(tag, "remove", public_ids, callback, options);
331};
332
333exports.remove_all_tags = function remove_all_tags() {
334 var public_ids = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
335 var callback = arguments[1];
336 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
337
338 return call_tags_api(null, "remove_all", public_ids, callback, options);
339};
340
341exports.replace_tag = function replace_tag(tag) {
342 var public_ids = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
343 var callback = arguments[2];
344 var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
345
346 return call_tags_api(tag, "replace", public_ids, callback, options);
347};
348
349function call_tags_api(tag, command) {
350 var public_ids = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
351 var callback = arguments[3];
352 var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
353
354 return call_api("tags", callback, options, function () {
355 var params = {
356 timestamp: utils.timestamp(),
357 public_ids: utils.build_array(public_ids),
358 command: command,
359 type: options.type
360 };
361 if (tag != null) {
362 params.tag = tag;
363 }
364 return [params];
365 });
366}
367
368exports.add_context = function add_context(context) {
369 var public_ids = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
370 var callback = arguments[2];
371 var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
372
373 return call_context_api(context, 'add', public_ids, callback, options);
374};
375
376exports.remove_all_context = function remove_all_context() {
377 var public_ids = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
378 var callback = arguments[1];
379 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
380
381 return call_context_api(null, 'remove_all', public_ids, callback, options);
382};
383
384function call_context_api(context, command) {
385 var public_ids = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
386 var callback = arguments[3];
387 var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
388
389 return call_api('context', callback, options, function () {
390 var params = {
391 timestamp: utils.timestamp(),
392 public_ids: utils.build_array(public_ids),
393 command: command,
394 type: options.type
395 };
396 if (context != null) {
397 params.context = utils.encode_context(context);
398 }
399 return [params];
400 });
401}
402
403/**
404 * Cache (part of) the upload results.
405 * @param result
406 * @param {object} options
407 * @param {string} options.type
408 * @param {string} options.resource_type
409 */
410function cacheResults(result, _ref) {
411 var type = _ref.type,
412 resource_type = _ref.resource_type;
413
414 if (result.responsive_breakpoints) {
415 result.responsive_breakpoints.forEach(function (_ref2) {
416 var transformation = _ref2.transformation,
417 url = _ref2.url,
418 breakpoints = _ref2.breakpoints;
419 return Cache.set(result.public_id, { type, resource_type, raw_transformation: transformation, format: path.extname(breakpoints[0].url).slice(1) }, breakpoints.map(function (i) {
420 return i.width;
421 }));
422 });
423 }
424}
425
426function parseResult(buffer, res) {
427 var result = '';
428 try {
429 result = JSON.parse(buffer);
430 } catch (jsonError) {
431 result = {
432 error: {
433 message: `Server return invalid JSON response. Status Code ${res.statusCode}. ${jsonError}`
434 }
435 };
436 }
437 return result;
438}
439
440function call_api(action, callback, options, get_params) {
441 if (typeof callback !== "function") {
442 callback = function callback() {};
443 }
444
445 var deferred = Q.defer();
446 if (options == null) {
447 options = {};
448 }
449
450 var _get_params$call = get_params.call(),
451 _get_params$call2 = _slicedToArray(_get_params$call, 3),
452 params = _get_params$call2[0],
453 unsigned_params = _get_params$call2[1],
454 file = _get_params$call2[2];
455
456 params = utils.process_request_params(params, options);
457 params = extend(params, unsigned_params);
458 var api_url = utils.api_url(action, options);
459 var boundary = utils.random_public_id();
460 var errorRaised = false;
461 var handle_response = function handle_response(res) {
462 // var buffer;
463 if (errorRaised) {
464
465 // Already reported
466 } else if (res.error) {
467 errorRaised = true;
468 deferred.reject(res);
469 return callback(res);
470 } else if (includes([200, 400, 401, 404, 420, 500], res.statusCode)) {
471 var buffer = "";
472 res.on("data", function (d) {
473 return buffer += d;
474 });
475 res.on("end", function () {
476 var result = void 0;
477 if (errorRaised) {
478 return;
479 }
480 result = parseResult(buffer, res);
481 if (result.error) {
482 result["error"]["http_code"] = res.statusCode;
483 deferred.reject(result.error);
484 } else {
485 cacheResults(result, options);
486 deferred.resolve(result);
487 }
488 return callback(result);
489 });
490 res.on("error", function (error) {
491 errorRaised = true;
492 deferred.reject(error);
493 return callback({ error });
494 });
495 } else {
496 var error = {
497 message: `Server returned unexpected status code - ${res.statusCode}`,
498 http_code: res.statusCode
499 };
500 deferred.reject(error);
501 return callback({ error });
502 }
503 };
504 var post_data = entries(params).reduce(function (entries, _ref3) {
505 var _ref4 = _slicedToArray(_ref3, 2),
506 key = _ref4[0],
507 value = _ref4[1];
508
509 if (isArray(value)) {
510 key = key.endsWith('[]') ? key : key + '[]';
511 var items = value.map(function (v) {
512 return [key, v];
513 });
514 entries = entries.concat(items);
515 } else {
516 entries.push([key, value]);
517 }
518 return entries;
519 }, []).filter(function (_ref5) {
520 var _ref6 = _slicedToArray(_ref5, 2),
521 key = _ref6[0],
522 value = _ref6[1];
523
524 return value != null;
525 }).map(function (_ref7) {
526 var _ref8 = _slicedToArray(_ref7, 2),
527 key = _ref8[0],
528 value = _ref8[1];
529
530 return Buffer.from(encodeFieldPart(boundary, key, value), 'utf8');
531 });
532
533 var result = post(api_url, post_data, boundary, file, handle_response, options);
534 if (isObject(result)) {
535 return result;
536 } else {
537 return deferred.promise;
538 }
539}
540
541function post(url, post_data, boundary, file, callback, options) {
542 var file_header;
543 var finish_buffer = Buffer.from("--" + boundary + "--", 'ascii');
544 if (file != null || options.stream) {
545 var filename = options.stream ? "file" : path.basename(file);
546 file_header = Buffer.from(encodeFilePart(boundary, 'application/octet-stream', 'file', filename), 'binary');
547 }
548 var post_options = require('url').parse(url);
549 var headers = {
550 'Content-Type': `multipart/form-data; boundary=${boundary}`,
551 'User-Agent': utils.getUserAgent()
552 };
553 if (options.content_range != null) {
554 headers['Content-Range'] = options.content_range;
555 }
556 if (options.x_unique_upload_id != null) {
557 headers['X-Unique-Upload-Id'] = options.x_unique_upload_id;
558 }
559 post_options = extend(post_options, {
560 method: 'POST',
561 headers: headers
562 });
563 if (options.agent != null) {
564 post_options.agent = options.agent;
565 }
566 var post_request = https.request(post_options, callback);
567 var upload_stream = new UploadStream({ boundary });
568 upload_stream.pipe(post_request);
569 var timeout = false;
570 post_request.on("error", function (error) {
571 if (timeout) {
572 error = {
573 message: "Request Timeout",
574 http_code: 499
575 };
576 }
577 return callback({ error });
578 });
579 post_request.setTimeout(options.timeout != null ? options.timeout : 60000, function () {
580 timeout = true;
581 return post_request.abort();
582 });
583 var _iteratorNormalCompletion = true;
584 var _didIteratorError = false;
585 var _iteratorError = undefined;
586
587 try {
588 for (var _iterator = post_data[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
589 var postDatum = _step.value;
590
591 post_request.write(postDatum);
592 }
593 } catch (err) {
594 _didIteratorError = true;
595 _iteratorError = err;
596 } finally {
597 try {
598 if (!_iteratorNormalCompletion && _iterator.return) {
599 _iterator.return();
600 }
601 } finally {
602 if (_didIteratorError) {
603 throw _iteratorError;
604 }
605 }
606 }
607
608 if (options.stream) {
609 post_request.write(file_header);
610 return upload_stream;
611 } else if (file != null) {
612 post_request.write(file_header);
613 fs.createReadStream(file).on('error', function (error) {
614 callback({
615 error: error
616 });
617 return post_request.abort();
618 }).pipe(upload_stream);
619 } else {
620 post_request.write(finish_buffer);
621 post_request.end();
622 }
623 return true;
624}
625
626function encodeFieldPart(boundary, name, value) {
627 return [`--${boundary}`, `Content-Disposition: form-data; name="${name}"`, '', value, ''].join("\r\n");
628}
629
630function encodeFilePart(boundary, type, name, filename) {
631 return [`--${boundary}`, `Content-Disposition: form-data; name="${name}"; filename="${filename}"`, `Content-Type: ${type}`, '', ''].join("\r\n");
632}
633
634exports.direct_upload = function direct_upload(callback_url) {
635 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
636
637 var params = build_upload_params(extend({
638 callback: callback_url
639 }, options));
640 params = utils.process_request_params(params, options);
641 var api_url = utils.api_url("upload", options);
642 return {
643 hidden_fields: params,
644 form_attrs: {
645 action: api_url,
646 method: "POST",
647 enctype: "multipart/form-data"
648 }
649 };
650};
651
652exports.upload_tag_params = function upload_tag_params() {
653 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
654
655 var params = build_upload_params(options);
656 params = utils.process_request_params(params, options);
657 return JSON.stringify(params);
658};
659
660exports.upload_url = function upload_url() {
661 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
662
663 if (options.resource_type == null) {
664 options.resource_type = "auto";
665 }
666 return utils.api_url("upload", options);
667};
668
669exports.image_upload_tag = function image_upload_tag(field) {
670 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
671
672 var html_options = options.html || {};
673 var tag_options = extend({
674 type: "file",
675 name: "file",
676 "data-url": exports.upload_url(options),
677 "data-form-data": exports.upload_tag_params(options),
678 "data-cloudinary-field": field,
679 "data-max-chunk-size": options.chunk_size,
680 "class": [html_options["class"], "cloudinary-fileupload"].join(" ")
681 }, html_options);
682 return `<input ${utils.html_attrs(tag_options)}/>`;
683};
684
685exports.unsigned_image_upload_tag = function unsigned_image_upload_tag(field, upload_preset) {
686 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
687
688 return exports.image_upload_tag(field, utils.merge(options, {
689 unsigned: true,
690 upload_preset: upload_preset
691 }));
692};
\No newline at end of file