Closed mklueh closed 8 years ago
I don´t know what I´m doing wrong here, but I´ve just installed the package as described in the description.
When I go into the Slingshot class, there is no function "createDirective" indeed.
(function () { ////////////////////////////////////////////////////////////////////////////////// // // // packages/lsun:slingshot/lib/restrictions.js // // // ////////////////////////////////////////////////////////////////////////////////// // /** // 1 * @module meteor-slingshot // 2 */ // 3 // 4 Slingshot = {}; // 5 // 6 /* global matchAllowedFileTypes: true */ // 7 matchAllowedFileTypes = Match.OneOf(String, [String], RegExp, null); // 8 // 9 /** // 10 * List of configured restrictions by name. // 11 * // 12 * @type {Object.<String, Function>} // 13 * @private // 14 */ // 15 // 16 Slingshot._restrictions = {}; // 17 // 18 /** // 19 * Creates file upload restrictions for a specific directive. // 20 * // 21 * @param {string} name - A unique identifier of the directive. // 22 * @param {Object} restrictions - The file upload restrictions. // 23 * @returns {Object} // 24 */ // 25 // 26 Slingshot.fileRestrictions = function (name, restrictions) { // 27 check(restrictions, { // 28 authorize: Match.Optional(Function), // 29 maxSize: Match.Optional(Match.OneOf(Number, null)), // 30 allowedFileTypes: Match.Optional(matchAllowedFileTypes) // 31 }); // 32 // 33 if (Meteor.isServer) { // 34 var directive = Slingshot.getDirective(name); // 35 if (directive) { // 36 _.extend(directive._directive, restrictions); // 37 } // 38 } // 39 // 40 return (Slingshot._restrictions[name] = // 41 _.extend(Slingshot._restrictions[name] || {}, restrictions)); // 42 }; // 43 // 44 /** // 45 * @param {string} name - The unique identifier of the directive to // 46 * retrieve the restrictions for. // 47 * @returns {Object} // 48 */ // 49 // 50 Slingshot.getRestrictions = function (name) { // 51 return this._restrictions[name] || {}; // 52 }; // 53 // 54 ////////////////////////////////////////////////////////////////////////////////// }).call(this); (function () { ////////////////////////////////////////////////////////////////////////////////// // // // packages/lsun:slingshot/lib/validators.js // // // ////////////////////////////////////////////////////////////////////////////////// // Slingshot.Validators = { // 1 // 2 /** // 3 * // 4 * @method checkAll // 5 * // 6 * @throws Meteor.Error // 7 * // 8 * @param {Object} context // 9 * @param {FileInfo} file // 10 * @param {Object} [meta] // 11 * @param {Object} [restrictions] // 12 * // 13 * @returns {Boolean} // 14 */ // 15 // 16 checkAll: function (context, file, meta, restrictions) { // 17 return this.checkFileSize(file.size, restrictions.maxSize) && // 18 this.checkFileType(file.type, restrictions.allowedFileTypes) && // 19 (typeof restrictions.authorize !== 'function' || // 20 restrictions.authorize.call(context, file, meta)); // 21 }, // 22 // 23 /** // 24 * @throws Meteor.Error // 25 * // 26 * @param {Number} size - Size of file in bytes. // 27 * @param {Number} maxSize - Max size of file in bytes. // 28 * @returns {boolean} // 29 */ // 30 // 31 checkFileSize: function (size, maxSize) { // 32 maxSize = Math.min(maxSize, Infinity); // 33 // 34 if (maxSize && size > maxSize) // 35 throw new Meteor.Error("Upload denied", "File exceeds allowed size of " + // 36 formatBytes(maxSize)); // 37 // 38 return true; // 39 }, // 40 // 41 /** // 42 * // 43 * @throws Meteor.Error // 44 * // 45 * @param {String} type - Mime type // 46 * @param {(RegExp|Array|String)} [allowed] - Allowed file type(s) // 47 * @returns {boolean} // 48 */ // 49 // 50 checkFileType: function (type, allowed) { // 51 if (allowed instanceof RegExp) { // 52 // 53 if (!allowed.test(type)) // 54 throw new Meteor.Error("Upload denied", // 55 type + " is not an allowed file type"); // 56 // 57 return true; // 58 } // 59 // 60 if (_.isArray(allowed)) { // 61 if (allowed.indexOf(type) < 0) { // 62 throw new Meteor.Error("Upload denied", // 63 type + " is not one of the followed allowed file types: " + // 64 allowed.join(", ")); // 65 } // 66 // 67 return true; // 68 } // 69 // 70 if (allowed && allowed !== type) { // 71 throw new Meteor.Error("Upload denied", "Only files of type " + allowed + // 72 " can be uploaded"); // 73 } // 74 // 75 return true; // 76 } // 77 }; // 78 // 79 /** Human readable data-size in bytes. // 80 * // 81 * @param size {Number} // 82 * @returns {string} // 83 */ // 84 // 85 function formatBytes(size) { // 86 var units = ['Bytes', 'KB', 'MB', 'GB', 'TB'], // 87 unit = units.shift(); // 88 // 89 while (size >= 0x400 && units.length) { // 90 size /= 0x400; // 91 unit = units.shift(); // 92 } // 93 // 94 return (Math.round(size * 100) / 100) + " " + unit; // 95 } // 96 // 97 ////////////////////////////////////////////////////////////////////////////////// }).call(this); (function () { ////////////////////////////////////////////////////////////////////////////////// // // // packages/lsun:slingshot/lib/upload.js // // // ////////////////////////////////////////////////////////////////////////////////// // /** // 1 * @fileOverview Defines client side API in which files can be uploaded. // 2 */ // 3 // 4 /** // 5 * // 6 * @param {string} directive - Name of server-directive to use. // 7 * @param {object} [metaData] - Data to be sent to directive. // 8 * @constructor // 9 */ // 10 // 11 Slingshot.Upload = function (directive, metaData) { // 12 // 13 if (!window.File || !window.FormData) { // 14 throw new Error("Browser does not support HTML5 uploads"); // 15 } // 16 // 17 var self = this, // 18 loaded = new ReactiveVar(), // 19 total = new ReactiveVar(), // 20 status = new ReactiveVar("idle"), // 21 dataUri, // 22 preloaded; // 23 // 24 function buildFormData() { // 25 var formData = new window.FormData(); // 26 // 27 _.each(self.instructions.postData, function (field) { // 28 formData.append(field.name, field.value); // 29 }); // 30 // 31 formData.append("file", self.file); // 32 // 33 return formData; // 34 } // 35 // 36 _.extend(self, { // 37 // 38 /** // 39 * @returns {string} // 40 */ // 41 // 42 status: function () { // 43 return status.get(); // 44 }, // 45 // 46 /** // 47 * @returns {number} // 48 */ // 49 // 50 progress: function () { // 51 return self.uploaded() / total.get(); // 52 }, // 53 // 54 /** // 55 * @returns {number} // 56 */ // 57 // 58 uploaded: function () { // 59 return loaded.get(); // 60 }, // 61 // 62 /** // 63 * @param {File} file // 64 * @returns {null|Error} Returns null on success, Error on failure. // 65 */ // 66 // 67 validate: function(file) { // 68 var context = { // 69 userId: Meteor.userId && Meteor.userId() // 70 }; // 71 try { // 72 var validators = Slingshot.Validators, // 73 restrictions = Slingshot.getRestrictions(directive); // 74 // 75 validators.checkAll(context, file, metaData, restrictions) && null; // 76 } catch(error) { // 77 return error; // 78 } // 79 }, // 80 // 81 /** // 82 * @param {(File|Blob)} file // 83 * @param {Function} [callback] // 84 * @returns {Slingshot.Upload} // 85 */ // 86 // 87 send: function (file, callback) { // 88 if (! (file instanceof window.File) && ! (file instanceof window.Blob)) // 89 throw new Error("Not a file"); // 90 // 91 self.file = file; // 92 // 93 self.request(function (error, instructions) { // 94 if (error) { // 95 return callback(error); // 96 } // 97 // 98 self.instructions = instructions; // 99 // 100 self.transfer(callback); // 101 }); // 102 // 103 return self; // 104 }, // 105 // 106 /** // 107 * @param {Function} [callback] // 108 * @returns {Slingshot.Upload} // 109 */ // 110 // 111 request: function (callback) { // 112 // 113 if (!self.file) { // 114 callback(new Error("No file to request upload for")); // 115 } // 116 // 117 var file = _.pick(self.file, "name", "size", "type"); // 118 // 119 status.set("authorizing"); // 120 // 121 var error = this.validate(file); // 122 if (error) { // 123 status.set("failed"); // 124 callback(error); // 125 return self; // 126 } // 127 // 128 Meteor.call("slingshot/uploadRequest", directive, // 129 file, metaData, function (error, instructions) { // 130 status.set(error ? "failed" : "authorized"); // 131 callback(error, instructions); // 132 }); // 133 // 134 return self; // 135 }, // 136 // 137 /** // 138 * @param {Function} [callback] // 139 * // 140 * @returns {Slingshot.Upload} // 141 */ // 142 // 143 transfer: function (callback) { // 144 if (status.curValue !== "authorized") { // 145 throw new Error("Cannot transfer file at upload status: " + // 146 status.curValue); // 147 } // 148 // 149 status.set("transferring"); // 150 loaded.set(0); // 151 // 152 var xhr = new XMLHttpRequest(); // 153 // 154 xhr.upload.addEventListener("progress", function (event) { // 155 if (event.lengthComputable) { // 156 loaded.set(event.loaded); // 157 total.set(event.total); // 158 } // 159 }, false); // 160 // 161 function getError() { // 162 return new Meteor.Error(xhr.statusText + " - " + xhr.status, // 163 "Failed to upload file to cloud storage"); // 164 } // 165 // 166 xhr.addEventListener("load", function () { // 167 // 168 if (xhr.status < 400) { // 169 status.set("done"); // 170 loaded.set(total.get()); // 171 callback(null, self.instructions.download); // 172 } // 173 else { // 174 status.set("failed"); // 175 callback(getError()); // 176 } // 177 }); // 178 // 179 xhr.addEventListener("error", function () { // 180 status.set("failed"); // 181 callback(getError()); // 182 }); // 183 // 184 xhr.addEventListener("abort", function () { // 185 status.set("aborted"); // 186 callback(new Meteor.Error("Aborted", // 187 "The upload has been aborted by the user")); // 188 }); // 189 // 190 xhr.open("POST", self.instructions.upload, true); // 191 // 192 _.each(self.instructions.headers, function (value, key) { // 193 xhr.setRequestHeader(key, value); // 194 }); // 195 // 196 xhr.send(buildFormData()); // 197 self.xhr = xhr; // 198 // 199 return self; // 200 }, // 201 // 202 /** // 203 * @returns {boolean} // 204 */ // 205 // 206 isImage: function () { // 207 self.status(); //React to status change. // 208 return Boolean(self.file && self.file.type.split("/")[0] === "image"); // 209 }, // 210 // 211 /** // 212 * Latency compensated url of the file to be uploaded. // 213 * // 214 * @param {boolean} preload // 215 * // 216 * @returns {string} // 217 */ // 218 // 219 url: function (preload) { // 220 if (!dataUri) { // 221 var localUrl = new ReactiveVar(), // 222 URL = (window.URL || window.webkitURL); // 223 // 224 dataUri = new ReactiveVar(); // 225 // 226 Tracker.nonreactive(function () { // 227 // 228 /* // 229 It is important that we generate the local url not more than once // 230 throughout the entire lifecycle of `self` to prevent flickering. // 231 */ // 232 // 233 var previewRequirement = new Tracker.Dependency(); // 234 // 235 Tracker.autorun(function (computation) { // 236 if (self.file) { // 237 if (URL) { // 238 localUrl.set(URL.createObjectURL(self.file)); // 239 computation.stop(); // 240 } // 241 else if (Tracker.active && window.FileReader) { // 242 readDataUrl(self.file, function (result) { // 243 localUrl.set(result); // 244 computation.stop(); // 245 }); // 246 } // 247 } // 248 else { // 249 previewRequirement.depend(); // 250 } // 251 }); // 252 // 253 Tracker.autorun(function (computation) { // 254 var status = self.status(); // 255 // 256 if (self.instructions && status === "done") { // 257 computation.stop(); // 258 dataUri.set(self.instructions.download); // 259 } // 260 else if (status === "failed" || status === "aborted") { // 261 computation.stop(); // 262 } // 263 else if (self.file && !dataUri.curValue) { // 264 previewRequirement.changed(); // 265 dataUri.set(localUrl.get()); // 266 } // 267 }); // 268 }); // 269 } // 270 // 271 if (preload) { // 272 // 273 if (self.file && !self.isImage()) // 274 throw new Error("Cannot pre-load anything other than images"); // 275 // 276 if (!preloaded) { // 277 Tracker.nonreactive(function () { // 278 preloaded = new ReactiveVar(); // 279 // 280 Tracker.autorun(function (computation) { // 281 var url = dataUri.get(); // 282 // 283 if (self.instructions) { // 284 preloadImage(url, function () { // 285 computation.stop(); // 286 preloaded.set(url); // 287 }); // 288 } // 289 else // 290 preloaded.set(url); // 291 }); // 292 }); // 293 } // 294 // 295 return preloaded.get(); // 296 } // 297 else // 298 return dataUri.get(); // 299 }, // 300 // 301 /** Gets an upload parameter for the directive. // 302 * // 303 * @param {String} name // 304 * @returns {String|Number|Undefined} // 305 */ // 306 // 307 param: function (name) { // 308 self.status(); //React to status changes. // 309 // 310 var data = self.instructions && self.instructions.postData, // 311 field = data && _.findWhere(data, {name: name}); // 312 // 313 return field && field.value; // 314 } // 315 // 316 }); // 317 }; // 318 // 319 /** // 320 * // 321 * @param {String} image - URL of image to preload. // 322 * @param {Function} callback // 323 */ // 324 // 325 function preloadImage(image, callback) { // 326 var preloader = new window.Image(); // 327 // 328 preloader.onload = callback; // 329 // 330 preloader.src = image; // 331 } // 332 // 333 function readDataUrl(file, callback) { // 334 var reader = new window.FileReader(); // 335 // 336 reader.onloadend = function () { // 337 callback(reader.result); // 338 }; // 339 // 340 reader.readAsDataURL(file); // 341 } // 342 // 343 ////////////////////////////////////////////////////////////////////////////////// }).call(this);
Am I missing something?
Ok I had it outside the server context, so it used the clientside Slingshot.js
I don´t know what I´m doing wrong here, but I´ve just installed the package as described in the description.
When I go into the Slingshot class, there is no function "createDirective" indeed.
Am I missing something?