From dc52fa7676b4aa5271fa95a3ab30cd3873e2e0f6 Mon Sep 17 00:00:00 2001 From: "dr.dimitru" Date: Wed, 3 Mar 2021 12:43:53 +0200 Subject: [PATCH 01/29] Minor emhancements - Codebase minor clean up = Return error `405` (*was `401`*) when attempt to remove file from client-features with disabled `.remove()` on the Client --- server.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server.js b/server.js index 4243161..4d49078 100644 --- a/server.js +++ b/server.js @@ -765,7 +765,7 @@ export class FilesCollection extends FilesCollectionCore { } throw new Meteor.Error(404, 'Cursor is empty, no files is removed'); } else { - throw new Meteor.Error(401, '[FilesCollection] [remove] Run code from client is not allowed!'); + throw new Meteor.Error(405, '[FilesCollection] [remove] Running code on a client is not allowed!'); } }; @@ -1116,7 +1116,7 @@ export class FilesCollection extends FilesCollectionCore { const userId = this._getUserId(mtok); if (userId) { - result.user = () => Meteor.users.findOne(userId); + result.user = () => Meteor.users.findOne(userId); result.userId = userId; } } From 472d06ecae0933fb62425c3f0073ba75242312c9 Mon Sep 17 00:00:00 2001 From: Harry Adel Date: Fri, 9 Apr 2021 00:46:58 +0200 Subject: [PATCH 02/29] Add missing isDate method --- lib.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib.js b/lib.js index 804cd48..6880b83 100644 --- a/lib.js +++ b/lib.js @@ -19,6 +19,9 @@ const helpers = { isFunction(obj) { return typeof obj === 'function' || false; }, + isDate(date) { + return !Number.isNaN(new Date(date).getDate()); + }, isEmpty(obj) { if (this.isDate(obj)) { return false; From b09112c3e5e06deec811f577266ca69bcf1b72f3 Mon Sep 17 00:00:00 2001 From: make-github-pseudonymous-again <5165674+make-github-pseudonymous-again@users.noreply.github.com> Date: Mon, 21 Jun 2021 11:22:55 +0200 Subject: [PATCH 03/29] docs: Update GridFS articles. Add additional argument against using `gridfs-stream`. Update links to point to mongodb driver version 3.6. Use `MongoInternals.NpmModules.mongodb.modules` since `MongoInternals.NpmModule` is undocumented (see for instance https://github.com/meteor/meteor/blob/1dbf57ac5f9c405ee6bab30a13e51a3966d4014e/packages/mongo/mongo_driver.js#L16-L29). --- docs/gridfs-bucket-integration.md | 10 +++++----- docs/gridfs-integration.md | 7 +++---- docs/gridfs-migration.md | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/docs/gridfs-bucket-integration.md b/docs/gridfs-bucket-integration.md index 34496bb..50b26f6 100644 --- a/docs/gridfs-bucket-integration.md +++ b/docs/gridfs-bucket-integration.md @@ -2,7 +2,7 @@ This example shows how to handle (store, serve, remove) uploaded files via GridFS. The Javascript Mongo driver (the one that Meteor uses under the hood) allows to define -[so called "Buckets"](http://mongodb.github.io/node-mongodb-native/3.2/api/GridFSBucket.html). +[so called "Buckets"](http://mongodb.github.io/node-mongodb-native/3.6/api/GridFSBucket.html). The Buckets are basically named collections for storing the file's metadata and chunkdata. This allows to *horizontally scale your files* the same way you do with your document collections. @@ -42,7 +42,7 @@ import { MongoInternals } from 'meteor/mongo'; export const createBucket = (bucketName) => { const options = bucketName ? {bucketName} : (void 0); - return new MongoInternals.NpmModule.GridFSBucket(MongoInternals.defaultRemoteCollectionDriver().mongo.db, options); + return new MongoInternals.NpmModules.mongodb.module.GridFSBucket(MongoInternals.defaultRemoteCollectionDriver().mongo.db, options); } ``` @@ -62,7 +62,7 @@ we also wrap this in a function: ```js import { MongoInternals } from 'meteor/mongo'; -export const createObjectId = ({ gridFsFileId }) => new MongoInternals.NpmModule.ObjectID(gridFsFileId); +export const createObjectId = ({ gridFsFileId }) => new MongoInternals.NpmModules.mongodb.module.ObjectID(gridFsFileId); ``` ## 3. Create an upload handler for the bucket @@ -88,7 +88,7 @@ export const createAfterUpdate = bucket => fs.createReadStream(file.versions[ versionName ].path) // this is where we upload the binary to the bucket using bucket.openUploadStream - // see http://mongodb.github.io/node-mongodb-native/3.2/api/GridFSBucket.html#openUploadStream + // see http://mongodb.github.io/node-mongodb-native/3.6/api/GridFSBucket.html#openUploadStream .pipe(bucket.openUploadStream( file.name, { @@ -135,7 +135,7 @@ const createInterceptDownload = bucket => const { gridFsFileId } = file.versions[ versionName ].meta || {}; if (gridFsFileId) { // opens the download stream using a given gfs id - // see: http://mongodb.github.io/node-mongodb-native/3.2/api/GridFSBucket.html#openDownloadStream + // see: http://mongodb.github.io/node-mongodb-native/3.6/api/GridFSBucket.html#openDownloadStream const gfsId = createObjectId({ gridFsFileId }); const readStream = bucket.openDownloadStream(gfsId); diff --git a/docs/gridfs-integration.md b/docs/gridfs-integration.md index fe3e2f8..a9681bd 100644 --- a/docs/gridfs-integration.md +++ b/docs/gridfs-integration.md @@ -1,7 +1,6 @@ ### Use GridFS with `gridfs-stream` as a storage -**Deprecation warning:** The `gridfs-stream` [has not been updated in a long time](https://github.com/aheckmann/gridfs-stream) and is therefore -considered deprecated. An alternative is to use the Mongo driver's native `GridFSBucket`, which is also [described in +> :warning: **Deprecation warning:** The `gridfs-stream` [has not been updated in a long time](https://github.com/aheckmann/gridfs-stream) and its implementation relies on the deprecated [`GridStore API`](https://mongodb.github.io/node-mongodb-native/3.6/api/GridStore.html). An alternative is to use the Mongo driver's native `GridFSBucket`, which is also [described in this wiki](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/gridfs-bucket-integration.md). Example below shows how to handle (store, serve, remove) uploaded files via GridFS. @@ -59,7 +58,7 @@ let gfs; if (Meteor.isServer) { gfs = Grid( MongoInternals.defaultRemoteCollectionDriver().mongo.db, - MongoInternals.NpmModule + MongoInternals.NpmModules.mongodb.module ); } ``` @@ -132,7 +131,7 @@ let gfs; if (Meteor.isServer) { gfs = Grid( MongoInternals.defaultRemoteCollectionDriver().mongo.db, - MongoInternals.NpmModule + MongoInternals.NpmModules.mongodb.module ); } diff --git a/docs/gridfs-migration.md b/docs/gridfs-migration.md index f3022da..43f7334 100644 --- a/docs/gridfs-migration.md +++ b/docs/gridfs-migration.md @@ -20,7 +20,7 @@ First create three Methods in P that each share one of the three crucial Parts o *This assumes the [default configuration of your GridFS](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/gridfs-bucket-integration.md) which is by default using the `db.fs.files` and `db.fs.chunks` collections.* -*For custom configuration you may consult the JS Mongo Native Driver documentation on [GridFSBucket](http://mongodb.github.io/node-mongodb-native/3.2/api/GridFSBucket.html).* +*For custom configuration you may consult the JS Mongo Native Driver documentation on [GridFSBucket](http://mongodb.github.io/node-mongodb-native/3.6/api/GridFSBucket.html).* #### P/server/sync.js From 0cd9e5f33b4d77cd138a90ff1d8c81eba2491b33 Mon Sep 17 00:00:00 2001 From: Alexander Prinzhorn Date: Sun, 22 Aug 2021 11:50:32 +0200 Subject: [PATCH 04/29] Update gridfs-bucket-integration.md --- docs/gridfs-bucket-integration.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docs/gridfs-bucket-integration.md b/docs/gridfs-bucket-integration.md index 34496bb..6ad3adb 100644 --- a/docs/gridfs-bucket-integration.md +++ b/docs/gridfs-bucket-integration.md @@ -32,10 +32,7 @@ For support of `206` partial content see [this article](https://github.com/Velio Before we can use a bucket, we need to define it with a given name. This is similar to creating a collection using a name for documents. -In a larger app we will need lots of buckets in order to horizontally scale. -It thus makes sense to create these buckets from a function. - -The following code is such a helper function that can easily be extended to accept more options: +The following code is a helper function to create a bucket. It can easily be extended to accept more options: ```js import { MongoInternals } from 'meteor/mongo'; From 25115c664d21aa06c7eea848b1cd17db9a26449d Mon Sep 17 00:00:00 2001 From: Alexander Prinzhorn Date: Mon, 23 Aug 2021 14:39:12 +0200 Subject: [PATCH 05/29] Update gridfs-bucket-integration.md --- docs/gridfs-bucket-integration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/gridfs-bucket-integration.md b/docs/gridfs-bucket-integration.md index 34496bb..0ed8ff9 100644 --- a/docs/gridfs-bucket-integration.md +++ b/docs/gridfs-bucket-integration.md @@ -112,7 +112,7 @@ export const createAfterUpdate = bucket => self.collection.update(file._id, { $set: { - [ property ]: ver._id.toHexString(); + [ property ]: ver._id.toHexString(), } }); From 6c4a93695c555fbcc705c1012956c9f61e4942a6 Mon Sep 17 00:00:00 2001 From: Alexander Prinzhorn Date: Mon, 23 Aug 2021 14:44:50 +0200 Subject: [PATCH 06/29] Update gridfs-bucket-integration.md --- docs/gridfs-bucket-integration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/gridfs-bucket-integration.md b/docs/gridfs-bucket-integration.md index 34496bb..3958b26 100644 --- a/docs/gridfs-bucket-integration.md +++ b/docs/gridfs-bucket-integration.md @@ -130,7 +130,7 @@ factory function as in step 3: ```js import { createObjectId } from '../createObjectId'; -const createInterceptDownload = bucket => +export const createInterceptDownload = bucket => function interceptDownload (http, file, versionName) { const { gridFsFileId } = file.versions[ versionName ].meta || {}; if (gridFsFileId) { @@ -169,7 +169,7 @@ is removing the file handle: ```js import { createObjectId } from '../createObjectId' -const createOnAfterRemove = bucket => +export const createOnAfterRemove = bucket => function onAfterRemove (files) { files.forEach(file => { Object.keys(file.versions).forEach(versionName => { From ba67f58e612304c69b8a3ba91bcc4ed672452087 Mon Sep 17 00:00:00 2001 From: Alexander Prinzhorn Date: Mon, 23 Aug 2021 14:49:49 +0200 Subject: [PATCH 07/29] Update gridfs-bucket-integration.md --- docs/gridfs-bucket-integration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/gridfs-bucket-integration.md b/docs/gridfs-bucket-integration.md index 34496bb..222dff6 100644 --- a/docs/gridfs-bucket-integration.md +++ b/docs/gridfs-bucket-integration.md @@ -74,8 +74,8 @@ In order to stay flexible enough in the choice of the bucket we use a factory f import { Meteor } from 'meteor/meteor'; import fs from 'fs'; -export const createAfterUpdate = bucket => - function createOnAfterUpload (file) { +export const createOnAfterUpload = bucket => + function onAfterUpload (file) { const self = this; // here you could manipulate your file From b5b1a5db98a9c3c726790f8c0bce37a2a77a5a84 Mon Sep 17 00:00:00 2001 From: Alexander Prinzhorn Date: Mon, 23 Aug 2021 16:21:55 +0200 Subject: [PATCH 08/29] Update gridfs-streaming.md --- docs/gridfs-streaming.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/gridfs-streaming.md b/docs/gridfs-streaming.md index c34573a..a91f1bb 100644 --- a/docs/gridfs-streaming.md +++ b/docs/gridfs-streaming.md @@ -1,4 +1,4 @@ -By default files served from GridFS returned with `200` response code. Which means if you serve video/audio/large downloads, file will be entirely read to memory and serve to client. This behavior is not best solution in terms of performance and resource usage. +By default files served from GridFS returned with `200` response code. This behavior is not best solution in terms of performance and resource usage. `206` partial content response is much better from all sides, for video and audio it allows to support time-seeking, for large files - resumable downloads. For server-side it reduces memory and CPU consumption. @@ -145,4 +145,4 @@ interceptDownload(http, image, versionName) { } return Boolean(_id); } -``` \ No newline at end of file +``` From 5f3bcebdaebd4bb0d006dbcd90ff376a71a59b2b Mon Sep 17 00:00:00 2001 From: "dr.dimitru" Date: Tue, 7 Jun 2022 10:50:35 +0300 Subject: [PATCH 09/29] =?UTF-8?q?=F0=9F=91=A8=E2=80=8D=F0=9F=92=BB=20Wrap?= =?UTF-8?q?=20stream.close=20into=20try...catch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/server.js b/server.js index 4d49078..10d41ba 100644 --- a/server.js +++ b/server.js @@ -1834,12 +1834,17 @@ export class FilesCollection extends FilesCollectionCore { const closeStream = () => { if (!stream._isEnded) { - if (typeof stream.close === 'function') { - stream.close(closeStreamCb); - } else if (typeof stream.end === 'function') { - stream.end(closeStreamCb); - } else if (typeof stream.destroy === 'function') { - stream.destroy('Got to close this stream', closeStreamCb); + try { + if (typeof stream.close === 'function') { + stream.close(closeStreamCb); + } else if (typeof stream.end === 'function') { + stream.end(closeStreamCb); + } else if (typeof stream.destroy === 'function') { + stream.destroy('Got to close this stream', closeStreamCb); + } + } catch (closeStreamError) { + // Perhaps one of the method has thrown an error + // or stream has been already ended/closed/exhausted } } }; From 9438083b1355914f50c7909b3282f9dd5e1d04cc Mon Sep 17 00:00:00 2001 From: "dr.dimitru" Date: Tue, 7 Jun 2022 11:07:11 +0300 Subject: [PATCH 10/29] =?UTF-8?q?=F0=9F=91=A8=E2=80=8D=F0=9F=92=BB=20es6?= =?UTF-8?q?=20string=20notation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib.js b/lib.js index 804cd48..3d3a86c 100644 --- a/lib.js +++ b/lib.js @@ -114,7 +114,7 @@ const helpers = { const _helpers = ['String', 'Number', 'Date']; for (let i = 0; i < _helpers.length; i++) { helpers['is' + _helpers[i]] = function (obj) { - return Object.prototype.toString.call(obj) === '[object ' + _helpers[i] + ']'; + return Object.prototype.toString.call(obj) === `[object ${_helpers[i]}]`; }; } From 2df6195b6775091c02285de60ad052b3b303131b Mon Sep 17 00:00:00 2001 From: "dr.dimitru" Date: Tue, 7 Jun 2022 11:07:41 +0300 Subject: [PATCH 11/29] =?UTF-8?q?=E2=98=9D=EF=B8=8F=20Year=20bump?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index aa54073..6bd2bc3 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021, dr.dimitru (Dmitry A.; Veliov Group, LLC) +Copyright (c) 2022, dr.dimitru (Dmitry A.; Veliov Group, LLC) All rights reserved. Redistribution and use in source and binary forms, From e7397c720afbc860e9ffcd23d46bfb3836296a1d Mon Sep 17 00:00:00 2001 From: "dr.dimitru" Date: Tue, 7 Jun 2022 11:26:53 +0300 Subject: [PATCH 12/29] =?UTF-8?q?=F0=9F=A7=B9=20Codebase=20cleanup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- write-stream.js | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/write-stream.js b/write-stream.js index 1221c5f..ab8c13e 100644 --- a/write-stream.js +++ b/write-stream.js @@ -1,16 +1,16 @@ -import fs from 'fs-extra'; -import { Meteor } from 'meteor/meteor'; +import fs from 'fs-extra'; +import { Meteor } from 'meteor/meteor'; import { helpers } from './lib.js'; -const NOOP = () => {}; +const noop = () => {}; -/* +/** * @const {Object} bound - Meteor.bindEnvironment (Fiber wrapper) * @const {Object} fdCache - File Descriptors Cache */ -const bound = Meteor.bindEnvironment(callback => callback()); +const bound = Meteor.bindEnvironment(callback => callback()); const fdCache = {}; -/* +/** * @private * @locus Server * @class WriteStream @@ -30,10 +30,10 @@ export default class WriteStream { return; } - this.fd = null; + this.fd = null; + this.ended = false; + this.aborted = false; this.writtenChunks = 0; - this.ended = false; - this.aborted = false; if (fdCache[this.path] && !fdCache[this.path].ended && !fdCache[this.path].aborted) { this.fd = fdCache[this.path].fd; @@ -62,7 +62,7 @@ export default class WriteStream { } } - /* + /** * @memberOf writeStream * @name write * @param {Number} num - Chunk position in a stream @@ -94,7 +94,7 @@ export default class WriteStream { return false; } - /* + /** * @memberOf writeStream * @name end * @param {Function} callback - Callback @@ -131,7 +131,7 @@ export default class WriteStream { return false; } - /* + /** * @memberOf writeStream * @name abort * @param {Function} callback - Callback @@ -141,11 +141,11 @@ export default class WriteStream { abort(callback) { this.aborted = true; delete fdCache[this.path]; - fs.unlink(this.path, (callback || NOOP)); + fs.unlink(this.path, (callback || noop)); return true; } - /* + /** * @memberOf writeStream * @name stop * @summary Stop writing to writableStream From 591a9113b41a7ab426b0ec5104f14a6a7a231620 Mon Sep 17 00:00:00 2001 From: "dr.dimitru" Date: Tue, 7 Jun 2022 11:27:16 +0300 Subject: [PATCH 13/29] =?UTF-8?q?=F0=9F=A7=B9=20Codebase=20cleanup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server.js | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/server.js b/server.js index 10d41ba..6600ba0 100644 --- a/server.js +++ b/server.js @@ -15,14 +15,14 @@ import fs from 'fs-extra'; import nodeQs from 'querystring'; import nodePath from 'path'; -/* +/** * @const {Object} bound - Meteor.bindEnvironment (Fiber wrapper) * @const {Function} NOOP - No Operation function, placeholder for required callbacks */ const bound = Meteor.bindEnvironment(callback => callback()); const NOOP = () => { }; -/* +/** * @locus Anywhere * @class FilesCollection * @param config {Object} - [Both] Configuration object with next properties: @@ -246,21 +246,21 @@ export class FilesCollection extends FilesCollectionCore { const headers = {}; switch (responseCode) { case '206': - headers.Pragma = 'private'; + headers.Pragma = 'private'; headers['Transfer-Encoding'] = 'chunked'; break; case '400': - headers['Cache-Control'] = 'no-cache'; + headers['Cache-Control'] = 'no-cache'; break; case '416': - headers['Content-Range'] = `bytes */${versionRef.size}`; + headers['Content-Range'] = `bytes */${versionRef.size}`; break; default: break; } - headers.Connection = 'keep-alive'; - headers['Content-Type'] = versionRef.type || 'application/octet-stream'; + headers.Connection = 'keep-alive'; + headers['Content-Type'] = versionRef.type || 'application/octet-stream'; headers['Accept-Ranges'] = 'bytes'; return headers; }; @@ -884,7 +884,7 @@ export class FilesCollection extends FilesCollectionCore { } } - /* + /** * @locus Server * @memberOf FilesCollection * @name _prepareUpload @@ -972,7 +972,7 @@ export class FilesCollection extends FilesCollectionCore { return {result, opts}; } - /* + /** * @locus Server * @memberOf FilesCollection * @name _finishUpload @@ -1007,7 +1007,7 @@ export class FilesCollection extends FilesCollectionCore { }); } - /* + /** * @locus Server * @memberOf FilesCollection * @name _handleUpload @@ -1029,7 +1029,7 @@ export class FilesCollection extends FilesCollectionCore { } } - /* + /** * @locus Anywhere * @memberOf FilesCollection * @name _getMimeType @@ -1050,7 +1050,7 @@ export class FilesCollection extends FilesCollectionCore { return mime; } - /* + /** * @locus Anywhere * @memberOf FilesCollection * @name _getUserId @@ -1076,7 +1076,7 @@ export class FilesCollection extends FilesCollectionCore { return null; } - /* + /** * @locus Anywhere * @memberOf FilesCollection * @name _getUser @@ -1088,7 +1088,7 @@ export class FilesCollection extends FilesCollectionCore { this.getUser(...arguments) : this._getUserDefault(...arguments); } - /* + /** * @locus Anywhere * @memberOf FilesCollection * @name _getUserDefault @@ -1125,7 +1125,7 @@ export class FilesCollection extends FilesCollectionCore { return result; } - /* + /** * @locus Server * @memberOf FilesCollection * @name write @@ -1224,7 +1224,7 @@ export class FilesCollection extends FilesCollectionCore { return this; } - /* + /** * @locus Server * @memberOf FilesCollection * @name load @@ -1409,7 +1409,7 @@ export class FilesCollection extends FilesCollectionCore { return this; } - /* + /** * @locus Server * @memberOf FilesCollection * @name addFile @@ -1512,7 +1512,7 @@ export class FilesCollection extends FilesCollectionCore { return this; } - /* + /** * @locus Anywhere * @memberOf FilesCollection * @name remove @@ -1551,7 +1551,7 @@ export class FilesCollection extends FilesCollectionCore { return this; } - /* + /** * @locus Server * @memberOf FilesCollection * @name deny @@ -1565,7 +1565,7 @@ export class FilesCollection extends FilesCollectionCore { return this.collection; } - /* + /** * @locus Server * @memberOf FilesCollection * @name allow @@ -1579,7 +1579,7 @@ export class FilesCollection extends FilesCollectionCore { return this.collection; } - /* + /** * @locus Server * @memberOf FilesCollection * @name denyClient @@ -1596,7 +1596,7 @@ export class FilesCollection extends FilesCollectionCore { return this.collection; } - /* + /** * @locus Server * @memberOf FilesCollection * @name allowClient @@ -1614,7 +1614,7 @@ export class FilesCollection extends FilesCollectionCore { } - /* + /** * @locus Server * @memberOf FilesCollection * @name unlink @@ -1644,7 +1644,7 @@ export class FilesCollection extends FilesCollectionCore { return this; } - /* + /** * @locus Server * @memberOf FilesCollection * @name _404 @@ -1667,7 +1667,7 @@ export class FilesCollection extends FilesCollectionCore { } } - /* + /** * @locus Server * @memberOf FilesCollection * @name download @@ -1726,7 +1726,7 @@ export class FilesCollection extends FilesCollectionCore { return this._404(http); } - /* + /** * @locus Server * @memberOf FilesCollection * @name serve From b87ebb0b2e898b086530d971d5fbd8527e45ec5e Mon Sep 17 00:00:00 2001 From: "dr.dimitru" Date: Wed, 8 Jun 2022 22:17:32 +0300 Subject: [PATCH 14/29] =?UTF-8?q?=F0=9F=93=94=20Fix:=20#803?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- docs/link.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9d323c5..4e9776e 100644 --- a/README.md +++ b/README.md @@ -160,7 +160,7 @@ Template.uploadForm.events({ }); ``` -For multiple file upload see [this demo code](https://github.com/VeliovGroup/Meteor-Files-Demos/blob/master/demo/imports/client/upload/upload-form.js#L73). +For multiple file upload see [this demo code](https://github.com/veliovgroup/meteor-files-website/blob/master/imports/client/upload/upload-form.js#L130). Upload base64 string (*introduced in v1.7.1*): diff --git a/docs/link.md b/docs/link.md index d48b0c0..10eb0f3 100644 --- a/docs/link.md +++ b/docs/link.md @@ -15,7 +15,7 @@ Use `.link()` method of [*FileCursor* instance](https://github.com/veliovgroup/M FilesCollection#link(fileRef, version, URIBase); // [*Isomorphic*] ``` -- `fileRef` {*Object*} - Object returned from MongoDB collection or [after upload](https://github.com/veliovgroup/meteor-files-website/blob/master/imports/client/upload/upload-form.js#L85) +- `fileRef` {*Object*} - Object returned from MongoDB collection or [after upload](https://github.com/veliovgroup/meteor-files-website/blob/master/imports/client/upload/upload-form.js#L194-L205) - `version` {*String*|*void 0*} - [OPTIONAL] File's subversion name, default: `original`. If requested subversion isn't found, `original` will be returned - `URIBase` {*String*} - [OPTIONAL] base URI (domain), default: `ROOT_URL` or `MOBILE_ROOT_URL` on *Cordova*. - Returns {*String*} - Absolute URL to file From 588b2cde75e8ad8e16e6cf76f32afe112fb0267c Mon Sep 17 00:00:00 2001 From: "dr.dimitru" Date: Wed, 8 Jun 2022 22:30:39 +0300 Subject: [PATCH 15/29] =?UTF-8?q?=F0=9F=91=A8=E2=80=8D=F0=9F=92=BB=20Decou?= =?UTF-8?q?ple=20from=20`fs-extra`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server.js | 249 ++++++++++++++++++++++++------------------------ write-stream.js | 31 +++--- 2 files changed, 140 insertions(+), 140 deletions(-) diff --git a/server.js b/server.js index 6600ba0..ec6780a 100644 --- a/server.js +++ b/server.js @@ -11,16 +11,16 @@ import FilesCollectionCore from './core.js'; import { fixJSONParse, fixJSONStringify, helpers } from './lib.js'; import AbortController from 'abort-controller'; -import fs from 'fs-extra'; +import fs from 'fs'; import nodeQs from 'querystring'; import nodePath from 'path'; /** * @const {Object} bound - Meteor.bindEnvironment (Fiber wrapper) - * @const {Function} NOOP - No Operation function, placeholder for required callbacks + * @const {Function} noop - No Operation function, placeholder for required callbacks */ const bound = Meteor.bindEnvironment(callback => callback()); -const NOOP = () => { }; +const noop = function noop () {}; /** * @locus Anywhere @@ -291,9 +291,12 @@ export class FilesCollection extends FilesCollectionCore { this._debug('[FilesCollection.storagePath] Set to:', this.storagePath({})); - fs.mkdirs(this.storagePath({}), { mode: this.parentDirPermissions }, (error) => { + fs.mkdir(this.storagePath({}), { + mode: this.parentDirPermissions, + recursive: true + }, (error) => { if (error) { - throw new Meteor.Error(401, `[FilesCollection.${self.collectionName}] Path "${this.storagePath({})}" is not writable! ${error}`); + throw new Meteor.Error(401, `[FilesCollection.${self.collectionName}] Path "${this.storagePath({})}" is not writable!`, error); } }); @@ -343,7 +346,7 @@ export class FilesCollection extends FilesCollectionCore { changed(doc) { if (doc.isFinished) { self._debug(`[FilesCollection] [_preCollectionCursor.observe] [changed]: ${doc._id}`); - self._preCollection.remove({_id: doc._id}, NOOP); + self._preCollection.remove({_id: doc._id}, noop); } }, removed(doc) { @@ -574,7 +577,7 @@ export class FilesCollection extends FilesCollectionCore { return; } - this.emit('_handleUpload', result, opts, NOOP); + this.emit('_handleUpload', result, opts, noop); if (!httpResp.headersSent) { httpResp.writeHead(204); @@ -849,7 +852,7 @@ export class FilesCollection extends FilesCollectionCore { throw handleUploadErr; } } else { - self.emit('_handleUpload', result, opts, NOOP); + self.emit('_handleUpload', result, opts, noop); } return true; }; @@ -981,7 +984,7 @@ export class FilesCollection extends FilesCollectionCore { */ _finishUpload(result, opts, cb) { this._debug(`[FilesCollection] [Upload] [finish(ing)Upload] -> ${result.path}`); - fs.chmod(result.path, this.permissions, NOOP); + fs.chmod(result.path, this.permissions, noop); result.type = this._getMimeType(opts.file); result.public = this.public; this._updateFileTypes(result); @@ -1189,36 +1192,35 @@ export class FilesCollection extends FilesCollectionCore { result._id = fileId; - fs.ensureFile(opts.path, (efError) => { + fs.stat(opts.path, (statErr, stats) => { bound(() => { - if (efError) { - callback && callback(efError); - this._debug(`[FilesCollection] [write] [ensureFile] [Error:] ${fileName} -> ${opts.path}`, efError); - } else { - const stream = fs.createWriteStream(opts.path, {flags: 'w', mode: this.permissions}); - stream.end(buffer, (streamErr) => { - bound(() => { - if (streamErr) { - callback && callback(streamErr); - } else { - this.collection.insert(result, (insertErr, _id) => { - if (insertErr) { - callback && callback(insertErr); - this._debug(`[FilesCollection] [write] [insert] Error: ${fileName} -> ${this.collectionName}`, insertErr); - } else { - const fileRef = this.collection.findOne(_id); - callback && callback(null, fileRef); - if (proceedAfterUpload === true) { - this.onAfterUpload && this.onAfterUpload.call(this, fileRef); - this.emit('afterUpload', fileRef); - } - this._debug(`[FilesCollection] [write]: ${fileName} -> ${this.collectionName}`); + if (statErr || !stats.isFile()) { + fs.writeFileSync(opts.path, ''); + } + + const stream = fs.createWriteStream(opts.path, {flags: 'w', mode: this.permissions}); + stream.end(buffer, (streamErr) => { + bound(() => { + if (streamErr) { + callback && callback(streamErr); + } else { + this.collection.insert(result, (insertErr, _id) => { + if (insertErr) { + callback && callback(insertErr); + this._debug(`[FilesCollection] [write] [insert] Error: ${fileName} -> ${this.collectionName}`, insertErr); + } else { + const fileRef = this.collection.findOne(_id); + callback && callback(null, fileRef); + if (proceedAfterUpload === true) { + this.onAfterUpload && this.onAfterUpload.call(this, fileRef); + this.emit('afterUpload', fileRef); } - }); - } - }); + this._debug(`[FilesCollection] [write]: ${fileName} -> ${this.collectionName}`); + } + }); + } }); - } + }); }); }); return this; @@ -1300,108 +1302,107 @@ export class FilesCollection extends FilesCollectionCore { }); }; - fs.ensureFile(opts.path, (efError) => { + fs.stat(opts.path, (statErr, stats) => { bound(() => { - if (efError) { - callback && callback(efError); - this._debug(`[FilesCollection] [load] [ensureFile] [Error:] ${fileName} -> ${opts.path}`, efError); - } else { - let isEnded = false; - let timer = null; - const wStream = fs.createWriteStream(opts.path, {flags: 'w', mode: this.permissions, autoClose: true, emitClose: false }); - const onEnd = (_error, response) => { - if (!isEnded) { - if (timer) { - Meteor.clearTimeout(timer); - timer = null; - } - - isEnded = true; - if (response && response.status === 200) { - this._debug(`[FilesCollection] [load] Received: ${url}`); - const result = this._dataToSchema({ - name: fileName, - path: opts.path, - meta: opts.meta, - type: opts.type || response.headers.get('content-type') || this._getMimeType({path: opts.path}), - size: opts.size || parseInt(response.headers.get('content-length') || 0), - userId: opts.userId, - extension - }); + if (statErr || !stats.isFile()) { + fs.writeFileSync(opts.path, ''); + } - if (!result.size) { - fs.stat(opts.path, (statError, stats) => { - bound(() => { - if (statError) { - callback && callback(statError); - } else { - result.versions.original.size = (result.size = stats.size); - storeResult(result, callback); - } - }); - }); - } else { - storeResult(result, callback); - } - } else { - const error = _error || new Meteor.Error(response?.status || 408, response?.statusText || 'Bad response with empty details'); - this._debug(`[FilesCollection] [load] [fetch(${url})] Error:`, error); + let isEnded = false; + let timer = null; + const wStream = fs.createWriteStream(opts.path, {flags: 'w', mode: this.permissions, autoClose: true, emitClose: false }); + const onEnd = (_error, response) => { + if (!isEnded) { + if (timer) { + Meteor.clearTimeout(timer); + timer = null; + } - if (!wStream.destroyed) { - wStream.destroy(); - } + isEnded = true; + if (response && response.status === 200) { + this._debug(`[FilesCollection] [load] Received: ${url}`); + const result = this._dataToSchema({ + name: fileName, + path: opts.path, + meta: opts.meta, + type: opts.type || response.headers.get('content-type') || this._getMimeType({path: opts.path}), + size: opts.size || parseInt(response.headers.get('content-length') || 0), + userId: opts.userId, + extension + }); - fs.remove(opts.path, (removeError) => { + if (!result.size) { + fs.stat(opts.path, (statError, newStats) => { bound(() => { - callback && callback(error); - if (removeError) { - this._debug(`[FilesCollection] [load] [fetch(${url})] [fs.remove(${opts.path})] removeError:`, removeError); + if (statError) { + callback && callback(statError); + } else { + result.versions.original.size = (result.size = newStats.size); + storeResult(result, callback); } }); }); + } else { + storeResult(result, callback); } + } else { + const error = _error || new Meteor.Error(response?.status || 408, response?.statusText || 'Bad response with empty details'); + this._debug(`[FilesCollection] [load] [fetch(${url})] Error:`, error); + + if (!wStream.destroyed) { + wStream.destroy(); + } + + fs.remove(opts.path, (removeError) => { + bound(() => { + callback && callback(error); + if (removeError) { + this._debug(`[FilesCollection] [load] [fetch(${url})] [fs.remove(${opts.path})] removeError:`, removeError); + } + }); + }); } - }; + } + }; - let resp = void 0; - wStream.on('error', (error) => { - bound(() => { - onEnd(error); - }); + let resp = void 0; + wStream.on('error', (error) => { + bound(() => { + onEnd(error); }); - wStream.on('close', () => { - bound(() => { - onEnd(void 0, resp); - }); + }); + wStream.on('close', () => { + bound(() => { + onEnd(void 0, resp); }); - wStream.on('finish', () => { - bound(() => { - onEnd(void 0, resp); - }); + }); + wStream.on('finish', () => { + bound(() => { + onEnd(void 0, resp); }); + }); - const controller = new AbortController(); - fetch(url, { - headers: opts.headers || {}, - signal: controller.signal - }).then((res) => { - resp = res; - res.body.on('error', (error) => { - bound(() => { - onEnd(error); - }); + const controller = new AbortController(); + fetch(url, { + headers: opts.headers || {}, + signal: controller.signal + }).then((res) => { + resp = res; + res.body.on('error', (error) => { + bound(() => { + onEnd(error); }); - res.body.pipe(wStream); - }).catch((fetchError) => { - onEnd(fetchError); }); + res.body.pipe(wStream); + }).catch((fetchError) => { + onEnd(fetchError); + }); - if (opts.timeout > 0) { - timer = Meteor.setTimeout(() => { - onEnd(new Meteor.Error(408, `Request timeout after ${opts.timeout}ms`)); - controller.abort(); - }, opts.timeout); - } + if (opts.timeout > 0) { + timer = Meteor.setTimeout(() => { + onEnd(new Meteor.Error(408, `Request timeout after ${opts.timeout}ms`)); + controller.abort(); + }, opts.timeout); } }); }); @@ -1546,7 +1547,7 @@ export class FilesCollection extends FilesCollectionCore { self.onAfterRemove(docs); }); } else { - this.collection.remove(selector, (callback || NOOP)); + this.collection.remove(selector, (callback || noop)); } return this; } @@ -1628,17 +1629,17 @@ export class FilesCollection extends FilesCollectionCore { this._debug(`[FilesCollection] [unlink(${fileRef._id}, ${version})]`); if (version) { if (helpers.isObject(fileRef.versions) && helpers.isObject(fileRef.versions[version]) && fileRef.versions[version].path) { - fs.unlink(fileRef.versions[version].path, (callback || NOOP)); + fs.unlink(fileRef.versions[version].path, (callback || noop)); } } else { if (helpers.isObject(fileRef.versions)) { for(let vKey in fileRef.versions) { if (fileRef.versions[vKey] && fileRef.versions[vKey].path) { - fs.unlink(fileRef.versions[vKey].path, (callback || NOOP)); + fs.unlink(fileRef.versions[vKey].path, (callback || noop)); } } } else { - fs.unlink(fileRef.path, (callback || NOOP)); + fs.unlink(fileRef.path, (callback || noop)); } } return this; diff --git a/write-stream.js b/write-stream.js index ab8c13e..f37db84 100644 --- a/write-stream.js +++ b/write-stream.js @@ -39,24 +39,23 @@ export default class WriteStream { this.fd = fdCache[this.path].fd; this.writtenChunks = fdCache[this.path].writtenChunks; } else { - fs.ensureFile(this.path, (efError) => { + fs.stat(this.path, (statError, stats) => { bound(() => { - if (efError) { - this.abort(); - throw new Meteor.Error(500, '[FilesCollection] [writeStream] [ensureFile] [Error:] ' + efError); - } else { - fs.open(this.path, 'r+', this.permissions, (oError, fd) => { - bound(() => { - if (oError) { - this.abort(); - throw new Meteor.Error(500, '[FilesCollection] [writeStream] [ensureFile] [open] [Error:] ' + oError); - } else { - this.fd = fd; - fdCache[this.path] = this; - } - }); - }); + if (statError || !stats.isFile()) { + fs.writeFileSync(this.path, ''); } + + fs.open(this.path, 'r+', this.permissions, (oError, fd) => { + bound(() => { + if (oError) { + this.abort(); + throw new Meteor.Error(500, '[FilesCollection] [writeStream] [ensureFile] [open] [Error:]', oError); + } else { + this.fd = fd; + fdCache[this.path] = this; + } + }); + }); }); }); } From 1c34a0028e97859c32336302834413a1402f70c1 Mon Sep 17 00:00:00 2001 From: "dr.dimitru" Date: Wed, 8 Jun 2022 22:46:54 +0300 Subject: [PATCH 16/29] =?UTF-8?q?=F0=9F=91=A8=E2=80=8D=F0=9F=92=BB=20Minor?= =?UTF-8?q?=20refactoring?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/server.js b/server.js index ec6780a..f700f3d 100644 --- a/server.js +++ b/server.js @@ -1696,10 +1696,8 @@ export class FilesCollection extends FilesCollectionCore { if (!vRef || !helpers.isObject(vRef)) { return this._404(http); } else if (fileRef) { - if (this.downloadCallback) { - if (!this.downloadCallback.call(Object.assign(http, this._getUser(http)), fileRef)) { - return this._404(http); - } + if (helpers.isFunction(this.downloadCallback) && !this.downloadCallback.call(Object.assign(http, this._getUser(http)), fileRef)) { + return this._404(http); } if (this.interceptDownload && helpers.isFunction(this.interceptDownload) && this.interceptDownload(http, fileRef, version) === true) { From 634c7915ab48f889cec9dcfe20d1f70ae5f78dd6 Mon Sep 17 00:00:00 2001 From: "dr.dimitru" Date: Wed, 8 Jun 2022 23:00:50 +0300 Subject: [PATCH 17/29] =?UTF-8?q?=F0=9F=91=B7=E2=80=8D=E2=99=82=EF=B8=8F?= =?UTF-8?q?=20Fix:=20#827,=20thanks=20to=20@aertms?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.js b/server.js index f700f3d..4bf5422 100644 --- a/server.js +++ b/server.js @@ -1832,7 +1832,7 @@ export class FilesCollection extends FilesCollectionCore { }; const closeStream = () => { - if (!stream._isEnded) { + if (!stream._isEnded && !stream.destroyed) { try { if (typeof stream.close === 'function') { stream.close(closeStreamCb); From c14a4e27dbe0c946a3bc0ee800a3d6a6fd3855e9 Mon Sep 17 00:00:00 2001 From: "dr.dimitru" Date: Wed, 8 Jun 2022 23:26:55 +0300 Subject: [PATCH 18/29] =?UTF-8?q?=F0=9F=91=B7=E2=80=8D=E2=99=82=EF=B8=8F?= =?UTF-8?q?=20Fix:=20#832,=20thanks=20to=20@polygonwood?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.js b/server.js index 4bf5422..e6df788 100644 --- a/server.js +++ b/server.js @@ -334,7 +334,7 @@ export class FilesCollection extends FilesCollectionCore { } check(this._preCollectionName, String); - this._preCollection._ensureIndex({ createdAt: 1 }, { expireAfterSeconds: this.continueUploadTTL, background: true }); + this._preCollection.createIndex({ createdAt: 1 }, { expireAfterSeconds: this.continueUploadTTL, background: true }); const _preCollectionCursor = this._preCollection.find({}, { fields: { _id: 1, From dcc46c91f75a34480438683d2987232f65eec93e Mon Sep 17 00:00:00 2001 From: "dr.dimitru" Date: Wed, 8 Jun 2022 23:32:43 +0300 Subject: [PATCH 19/29] Update server.js --- server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.js b/server.js index e6df788..902f772 100644 --- a/server.js +++ b/server.js @@ -317,7 +317,7 @@ export class FilesCollection extends FilesCollectionCore { check(this.responseHeaders, Match.OneOf(Object, Function)); check(this.allowQueryStringCookies, Boolean); - new Cookies({ + this._cookies = new Cookies({ allowQueryStringCookies: this.allowQueryStringCookies, allowedCordovaOrigins: this.allowedOrigins }); From f12012398d6a69d33c3746de44673b5db7ad94ce Mon Sep 17 00:00:00 2001 From: "dr.dimitru" Date: Wed, 8 Jun 2022 23:33:45 +0300 Subject: [PATCH 20/29] =?UTF-8?q?=F0=9F=91=B7=E2=80=8D=E2=99=82=EF=B8=8F?= =?UTF-8?q?=20Fix:=20#813,=20thanks=20@Prinzhorn?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- upload.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/upload.js b/upload.js index f87d3df..71832d2 100644 --- a/upload.js +++ b/upload.js @@ -294,10 +294,6 @@ export class UploadInstance extends EventEmitter { if (this.beforeunload) { window.removeEventListener('beforeunload', this.beforeunload, false); } - if (this.result) { - this.result.progress.set(0); - return; - } return; }); } else { From 4564863f5b4e7ffdb7f61951b3ea542ec42ab00c Mon Sep 17 00:00:00 2001 From: "dr.dimitru" Date: Thu, 9 Jun 2022 00:36:26 +0300 Subject: [PATCH 21/29] =?UTF-8?q?=F0=9F=91=A8=E2=80=8D=F0=9F=92=BB=20Fix:?= =?UTF-8?q?=20#834,=20thanks=20to=20@bladerunner2020?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- upload.js | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/upload.js b/upload.js index 71832d2..b226483 100644 --- a/upload.js +++ b/upload.js @@ -245,6 +245,23 @@ export class UploadInstance extends EventEmitter { this.result.config._onEnd = () => this.emit('_onEnd'); + this._setProgress = (progress) => { + if (this.result.progress.get() >= 100) { + return; + } + + let sentBytes = this.config.chunkSize * this.sentChunks; + if (sentBytes > this.fileData.size) { + // this case often occurs, when the last chunk + // is smaller than chunkSize, so we limit to fileSize + sentBytes = this.fileData.size; + } + + this.result.progress.set(progress); + this.config.onProgress && this.config.onProgress.call(this.result, progress, this.fileData); + this.result.emit('progress', progress, this.fileData, { chunksSent: this.sentChunks, chunksLength: this.fileLength, bytesSent: sentBytes }); + }; + this.addListener('end', this.end); this.addListener('start', this.start); this.addListener('upload', this.upload); @@ -254,21 +271,16 @@ export class UploadInstance extends EventEmitter { this.addListener('proceedChunk', this.proceedChunk); this.addListener('calculateStats', helpers.throttle(() => { + if (this.result.progress.get() >= 100) { + return; + } + const _t = (this.transferTime / (this.sentChunks || 1)); this.result.estimateTime.set((_t * (this.fileLength - this.sentChunks))); this.result.estimateSpeed.set((this.config.chunkSize / (_t / 1000))); const progress = Math.round((this.sentChunks / this.fileLength) * 100); - let sentBytes = this.config.chunkSize * this.sentChunks; - if (sentBytes > this.fileData.size) { - // this case often occurs, when the last chunk - // is smaller than chunkSize, so we limit to fileSize - sentBytes = this.fileData.size; - } - - this.result.progress.set(progress); - this.config.onProgress && this.config.onProgress.call(this.result, progress, this.fileData); - this.result.emit('progress', progress, this.fileData, { chunksSent: this.sentChunks, chunksLength: this.fileLength, bytesSent: sentBytes }); + this._setProgress(progress); }, 250)); this.addListener('_onEnd', () => { @@ -307,6 +319,7 @@ export class UploadInstance extends EventEmitter { console.timeEnd(`insert ${this.fileData.name}`); } + this._setProgress(100); this.emit('_onEnd'); this.result.emit('uploaded', error, data); this.config.onUploaded && this.config.onUploaded.call(this.result, error, data); From bd581ebd1eebb90b565460c6ec3316c05a852381 Mon Sep 17 00:00:00 2001 From: "dr.dimitru" Date: Thu, 9 Jun 2022 08:27:38 +0300 Subject: [PATCH 22/29] =?UTF-8?q?=F0=9F=A7=B9=20Codebase=20cleanup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- upload.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/upload.js b/upload.js index b226483..fdd6b6b 100644 --- a/upload.js +++ b/upload.js @@ -92,7 +92,7 @@ export class FileUpload extends EventEmitter { export class UploadInstance extends EventEmitter { constructor(config, collection) { super(); - this.config = config; + this.config = config; this.collection = collection; this.collection._debug('[FilesCollection] [insert()]'); From 637f2037b6722af733b7e85dbad27c59f213e04f Mon Sep 17 00:00:00 2001 From: "dr.dimitru" Date: Thu, 9 Jun 2022 08:27:47 +0300 Subject: [PATCH 23/29] =?UTF-8?q?=F0=9F=A7=B9=20Codebase=20cleanup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server.js | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/server.js b/server.js index 902f772..e636356 100644 --- a/server.js +++ b/server.js @@ -20,7 +20,7 @@ import nodePath from 'path'; * @const {Function} noop - No Operation function, placeholder for required callbacks */ const bound = Meteor.bindEnvironment(callback => callback()); -const noop = function noop () {}; +const noop = function noop () {}; /** * @locus Anywhere @@ -538,7 +538,7 @@ export class FilesCollection extends FilesCollectionCore { throw new Meteor.Error(408, 'Can\'t continue upload, session expired. Start upload again.'); } - ({result, opts} = this._prepareUpload(Object.assign(opts, _continueUpload), user.userId, 'HTTP')); + ({result, opts} = this._prepareUpload(Object.assign(opts, _continueUpload), user.userId, 'HTTP')); if (opts.eof) { // FINISH UPLOAD SCENARIO: @@ -704,10 +704,10 @@ export class FilesCollection extends FilesCollectionCore { let version; if (_file.includes('-')) { version = _file.split('-')[0]; - _file = _file.split('-')[1].split('?')[0]; + _file = _file.split('-')[1].split('?')[0]; } else { version = 'original'; - _file = _file.split('?')[0]; + _file = _file.split('?')[0]; } const params = { @@ -798,7 +798,7 @@ export class FilesCollection extends FilesCollectionCore { throw new Meteor.Error(400, 'Can\'t start upload, data substitution detected!'); } - opts._id = opts.fileId; + opts._id = opts.fileId; opts.createdAt = new Date(); opts.maxLength = opts.fileLength; try { @@ -921,16 +921,16 @@ export class FilesCollection extends FilesCollectionCore { opts.file.meta = {}; } - let result = opts.file; - result.name = fileName; - result.meta = opts.file.meta; + let result = opts.file; + result.name = fileName; + result.meta = opts.file.meta; result.extension = extension; - result.ext = extension; - result._id = opts.fileId; - result.userId = userId || null; - opts.FSName = opts.FSName.replace(/([^a-z0-9\-\_]+)/gi, '-'); - result.path = `${this.storagePath(result)}${nodePath.sep}${opts.FSName}${extensionWithDot}`; - result = Object.assign(result, this._dataToSchema(result)); + result.ext = extension; + result._id = opts.fileId; + result.userId = userId || null; + opts.FSName = opts.FSName.replace(/([^a-z0-9\-\_]+)/gi, '-'); + result.path = `${this.storagePath(result)}${nodePath.sep}${opts.FSName}${extensionWithDot}`; + result = Object.assign(result, this._dataToSchema(result)); if (this.onBeforeUpload && helpers.isFunction(this.onBeforeUpload)) { ctx = Object.assign({ @@ -985,7 +985,7 @@ export class FilesCollection extends FilesCollectionCore { _finishUpload(result, opts, cb) { this._debug(`[FilesCollection] [Upload] [finish(ing)Upload] -> ${result.path}`); fs.chmod(result.path, this.permissions, noop); - result.type = this._getMimeType(opts.file); + result.type = this._getMimeType(opts.file); result.public = this.public; this._updateFileTypes(result); @@ -1153,7 +1153,7 @@ export class FilesCollection extends FilesCollectionCore { if (helpers.isFunction(opts)) { proceedAfterUpload = callback; callback = opts; - opts = {}; + opts = {}; } else if (helpers.isBoolean(callback)) { proceedAfterUpload = callback; } else if (helpers.isBoolean(opts)) { @@ -1164,8 +1164,8 @@ export class FilesCollection extends FilesCollectionCore { check(callback, Match.Optional(Function)); check(proceedAfterUpload, Match.Optional(Boolean)); - const fileId = opts.fileId || Random.id(); - const FSName = this.namingFunction ? this.namingFunction(opts) : fileId; + const fileId = opts.fileId || Random.id(); + const FSName = this.namingFunction ? this.namingFunction(opts) : fileId; const fileName = (opts.name || opts.fileName) ? (opts.name || opts.fileName) : FSName; const {extension, extensionWithDot} = this._getExt(fileName); @@ -1281,7 +1281,7 @@ export class FilesCollection extends FilesCollectionCore { const fileName = (opts.name || opts.fileName) ? (opts.name || opts.fileName) : pathParts[pathParts.length - 1].split('?')[0] || FSName; const {extension, extensionWithDot} = this._getExt(fileName); - opts.path = `${this.storagePath(opts)}${nodePath.sep}${FSName}${extensionWithDot}`; + opts.path = `${this.storagePath(opts)}${nodePath.sep}${FSName}${extensionWithDot}`; const storeResult = (result, cb) => { result._id = fileId; @@ -1435,7 +1435,7 @@ export class FilesCollection extends FilesCollectionCore { if (helpers.isFunction(opts)) { proceedAfterUpload = callback; callback = opts; - opts = {}; + opts = {}; } else if (helpers.isBoolean(callback)) { proceedAfterUpload = callback; } else if (helpers.isBoolean(opts)) { @@ -1458,11 +1458,11 @@ export class FilesCollection extends FilesCollectionCore { if (!helpers.isObject(opts)) { opts = {}; } - opts.path = path; + opts.path = path; if (!opts.fileName) { const pathParts = path.split(nodePath.sep); - opts.fileName = path.split(nodePath.sep)[pathParts.length - 1]; + opts.fileName = path.split(nodePath.sep)[pathParts.length - 1]; } const {extension} = this._getExt(opts.fileName); @@ -1780,11 +1780,11 @@ export class FilesCollection extends FilesCollectionCore { reqRange = {start, end}; if (isNaN(start) && !isNaN(end)) { reqRange.start = end - take; - reqRange.end = end; + reqRange.end = end; } if (!isNaN(start) && isNaN(end)) { reqRange.start = start; - reqRange.end = start + take; + reqRange.end = start + take; } if ((start + take) >= vRef.size) { From 0cf755c37f543634afea1b3b59f921208d742dc0 Mon Sep 17 00:00:00 2001 From: "dr.dimitru" Date: Thu, 9 Jun 2022 08:27:56 +0300 Subject: [PATCH 24/29] =?UTF-8?q?=F0=9F=A7=B9=20Codebase=20cleanup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib.js b/lib.js index 3cc5b7f..0505777 100644 --- a/lib.js +++ b/lib.js @@ -177,20 +177,20 @@ const fixJSONStringify = function(obj) { * @name formatFleURL * @param {Object} fileRef - File reference object * @param {String} version - [Optional] Version of file you would like build URL for - * @param {String} URIBase - [Optional] URI base, see - https://github.com/VeliovGroup/Meteor-Files/issues/626 + * @param {String} uriBase - [Optional] URI base, see - https://github.com/VeliovGroup/Meteor-Files/issues/626 * @summary Returns formatted URL for file * @returns {String} Downloadable link */ -const formatFleURL = (fileRef, version = 'original', _URIBase = (__meteor_runtime_config__ || {}).ROOT_URL) => { +const formatFleURL = (fileRef, version = 'original', _uriBase = (__meteor_runtime_config__ || {}).ROOT_URL) => { check(fileRef, Object); check(version, String); - let URIBase = _URIBase; + let uriBase = _uriBase; - if (!helpers.isString(URIBase)) { - URIBase = (__meteor_runtime_config__ || {}).ROOT_URL || '/'; + if (!helpers.isString(uriBase)) { + uriBase = (__meteor_runtime_config__ || {}).ROOT_URL || '/'; } - const _root = URIBase.replace(/\/+$/, ''); + const _root = uriBase.replace(/\/+$/, ''); const vRef = (fileRef.versions && fileRef.versions[version]) || fileRef || {}; let ext; From 5e5a470eb630c6dd22be79fee1f90c3e555c5517 Mon Sep 17 00:00:00 2001 From: "dr.dimitru" Date: Thu, 9 Jun 2022 08:28:04 +0300 Subject: [PATCH 25/29] =?UTF-8?q?=F0=9F=A7=B9=20Codebase=20cleanup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cursor.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cursor.js b/cursor.js index 689903b..7b2e807 100644 --- a/cursor.js +++ b/cursor.js @@ -10,7 +10,7 @@ import { Meteor } from 'meteor/meteor'; */ export class FileCursor { constructor(_fileRef, _collection) { - this._fileRef = _fileRef; + this._fileRef = _fileRef; this._collection = _collection; Object.assign(this, _fileRef); } @@ -38,14 +38,14 @@ export class FileCursor { * @memberOf FileCursor * @name link * @param version {String} - Name of file's subversion - * @param URIBase {String} - [Optional] URI base, see - https://github.com/VeliovGroup/Meteor-Files/issues/626 + * @param uriBase {String} - [Optional] URI base, see - https://github.com/VeliovGroup/Meteor-Files/issues/626 * @summary Returns downloadable URL to File * @returns {String} */ - link(version = 'original', URIBase) { + link(version = 'original', uriBase) { this._collection._debug(`[FilesCollection] [FileCursor] [link(${version})]`); if (this._fileRef) { - return this._collection.link(this._fileRef, version, URIBase); + return this._collection.link(this._fileRef, version, uriBase); } return ''; } @@ -103,9 +103,9 @@ export class FileCursor { export class FilesCursor { constructor(_selector = {}, options, _collection) { this._collection = _collection; - this._selector = _selector; - this._current = -1; - this.cursor = this._collection.collection.find(this._selector, options); + this._selector = _selector; + this._current = -1; + this.cursor = this._collection.collection.find(this._selector, options); } /* From 4de19194e45a574fbf654b8f6a29fb9158edf354 Mon Sep 17 00:00:00 2001 From: "dr.dimitru" Date: Thu, 9 Jun 2022 08:28:14 +0300 Subject: [PATCH 26/29] =?UTF-8?q?=F0=9F=A7=B9=20Codebase=20cleanup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core.js b/core.js index a0209df..ff9a937 100644 --- a/core.js +++ b/core.js @@ -170,7 +170,7 @@ export default class FilesCollectionCore extends EventEmitter { name: data.name, extension: data.extension, ext: data.extension, - extensionWithDot: '.' + data.extension, + extensionWithDot: `.${data.extension}`, path: data.path, meta: data.meta, type: data.type, @@ -257,17 +257,17 @@ export default class FilesCollectionCore extends EventEmitter { * @name link * @param {Object} fileRef - File reference object * @param {String} version - Version of file you would like to request - * @param {String} URIBase - [Optional] URI base, see - https://github.com/VeliovGroup/Meteor-Files/issues/626 + * @param {String} uriBase - [Optional] URI base, see - https://github.com/VeliovGroup/Meteor-Files/issues/626 * @summary Returns downloadable URL * @returns {String} Empty string returned in case if file not found in DB */ - link(fileRef, version = 'original', URIBase) { + link(fileRef, version = 'original', uriBase) { this._debug(`[FilesCollection] [link(${(helpers.isObject(fileRef) ? fileRef._id : void 0)}, ${version})]`); check(fileRef, Object); if (!fileRef) { return ''; } - return formatFleURL(fileRef, version, URIBase); + return formatFleURL(fileRef, version, uriBase); } } From c59fad186f74cb283a0f4bdafc29e23654521f03 Mon Sep 17 00:00:00 2001 From: "dr.dimitru" Date: Thu, 9 Jun 2022 08:28:48 +0300 Subject: [PATCH 27/29] =?UTF-8?q?=F0=9F=A7=B9=20Codebase=20cleanup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Get `Accounts` and `Template` from `Package` global object --- client.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/client.js b/client.js index ff43bd5..0f806af 100644 --- a/client.js +++ b/client.js @@ -113,7 +113,6 @@ export class FilesCollection extends FilesCollectionCore { } if (!config.disableSetTokenCookie) { - const setTokenCookie = () => { if (Meteor.connection._lastSessionId) { cookie.set('x_mtok', Meteor.connection._lastSessionId, { path: '/', sameSite: 'Lax' }); @@ -123,14 +122,14 @@ export class FilesCollection extends FilesCollectionCore { } }; - if (typeof Accounts !== 'undefined' && Accounts !== null) { + const _accounts = (Package && Package['accounts-base'] && Package['accounts-base'].Accounts) ? Package['accounts-base'].Accounts : undefined; + if (_accounts) { DDP.onReconnect((conn) => { conn.onReconnect = setTokenCookie; }); Meteor.startup(setTokenCookie); - Accounts.onLogin(setTokenCookie); + _accounts.onLogin(setTokenCookie); } - } check(this.onbeforeunloadMessage, Match.OneOf(String, Function)); @@ -225,7 +224,7 @@ export class FilesCollection extends FilesCollectionCore { * @see https://developer.mozilla.org/en-US/docs/Web/API/FileReader * @param {Object} config - Configuration object with next properties: * {File|Object} file - HTML5 `files` item, like in change event: `e.currentTarget.files[0]` - * {String} fileId - Optionnal `fileId` used at insert + * {String} fileId - Optional `fileId` used at insert * {Object} meta - Additional data as object, use later for search * {Boolean} allowWebWorkers- Allow/Deny WebWorkers usage * {Number|dynamic} chunkSize - Chunk size for upload @@ -289,21 +288,22 @@ export class FilesCollection extends FilesCollectionCore { * @name fileURL * @param {Object} fileRef - File reference object * @param {String} version - [Optional] Version of file you would like to request - * @param {String} URIBase - [Optional] URI base, see - https://github.com/VeliovGroup/Meteor-Files/issues/626 + * @param {String} uriBase - [Optional] URI base, see - https://github.com/VeliovGroup/Meteor-Files/issues/626 * @summary Get download URL for file by fileRef, even without subscription * @example {{fileURL fileRef}} * @returns {String} */ Meteor.startup(() => { - if (typeof Template !== 'undefined' && Template !== null) { - Template.registerHelper('fileURL', (fileRef, _version = 'original', _URIBase) => { + const _template = (Package && Package.templating && Package.templating.Template) ? Package.templating.Template : undefined; + if (_template) { + _template.registerHelper('fileURL', (fileRef, _version = 'original', _uriBase) => { if (!helpers.isObject(fileRef)) { return ''; } const version = (!helpers.isString(_version)) ? 'original' : _version; - const URIBase = (!helpers.isString(_URIBase)) ? void 0 : _URIBase; - return formatFleURL(fileRef, version, URIBase); + const uriBase = (!helpers.isString(_uriBase)) ? void 0 : _uriBase; + return formatFleURL(fileRef, version, uriBase); }); } }); From 0199a2f9a85b175dc45804a5c276ca428ac7dd2a Mon Sep 17 00:00:00 2001 From: "dr.dimitru" Date: Thu, 9 Jun 2022 08:31:50 +0300 Subject: [PATCH 28/29] =?UTF-8?q?=F0=9F=9F=A8=20It's=20veliovgroup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/ISSUE_TEMPLATE | 2 +- CHANGELOG.md | 2 +- CONTRIBUTING.md | 14 ++-- HISTORY.md | 2 +- README.md | 106 ++++++++++++------------ client.js | 2 +- core.js | 2 +- cursor.js | 2 +- demo-simplest-download-button/README.md | 2 +- demo-simplest-streaming/README.md | 2 +- demo-simplest-upload/README.md | 2 +- demo/README.md | 2 +- docs/3rd-party-storage.md | 12 +-- docs/about-transports.md | 2 +- docs/constructor.md | 16 ++-- docs/custom-response-headers.md | 2 +- docs/find.md | 2 +- docs/findOne.md | 2 +- docs/gridfs-bucket-integration.md | 4 +- docs/gridfs-integration.md | 4 +- docs/gridfs-migration.md | 2 +- docs/gridfs-streaming.md | 2 +- docs/insert.md | 2 +- docs/load.md | 2 +- docs/meteorup-usage.md | 4 +- docs/react-example.md | 2 +- docs/readme.md | 98 +++++++++++----------- docs/remove.md | 2 +- docs/schema.md | 2 +- docs/template-helper.md | 6 +- docs/toc.md | 98 +++++++++++----------- docs/unlink.md | 3 +- lib.js | 2 +- server.js | 2 +- 34 files changed, 206 insertions(+), 205 deletions(-) diff --git a/.github/ISSUE_TEMPLATE b/.github/ISSUE_TEMPLATE index 31a24ed..d2be8f2 100644 --- a/.github/ISSUE_TEMPLATE +++ b/.github/ISSUE_TEMPLATE @@ -4,7 +4,7 @@ - Version of `Meteor` you're experiencing this issue - Where this issue appears? OS (Mac/Win/Linux)? Browser name and its version? - Is it *Client* or *Server* issue? - - Post *Client* and/or *Server* logs with enabled `debug` option, you can enable "debug" mode in [*Constructor*](https://github.com/VeliovGroup/Meteor-Files/wiki/Constructor) + - Post *Client* and/or *Server* logs with enabled `debug` option, you can enable "debug" mode in [*Constructor*](https://github.com/veliovgroup/Meteor-Files/wiki/Constructor) ### I had an issue and I've solved it on my own: - Provide a description of steps that you've followed to solve the problem diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f99ebd..cda1132 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1 +1 @@ -For full changelog see [releases on GitHub](https://github.com/VeliovGroup/Meteor-Files/releases) \ No newline at end of file +For full changelog see [releases on GitHub](https://github.com/veliovgroup/Meteor-Files/releases) \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c950960..29f6de0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ ### I'm having an issue: - 1. Search [issues](https://github.com/VeliovGroup/Meteor-Files/issues), maybe your issue is already solved - 2. We have useful threads marked as [`In a case of the fire - Read This`](https://github.com/VeliovGroup/Meteor-Files/issues?utf8=✓&q=label%3A%22In%20a%20case%20of%20the%20fire%20-%20Read%20This%22), read them too + 1. Search [issues](https://github.com/veliovgroup/Meteor-Files/issues), maybe your issue is already solved + 2. We have useful threads marked as [`In a case of the fire - Read This`](https://github.com/veliovgroup/Meteor-Files/issues?utf8=✓&q=label%3A%22In%20a%20case%20of%20the%20fire%20-%20Read%20This%22), read them too 3. Before submitting an issue make sure it's only related to `Meteor-Files` package 4. If your issue is not solved: - Give an expressive description of what is went wrong @@ -8,23 +8,23 @@ - Version of `Meteor` you're experiencing this issue - Where this issue appears? OS (Mac/Win/Linux)? Browser name and its version? - Is it *Client* or *Server* issue? - - Post *Client* and/or *Server* logs with enabled `debug` option, you can enable "debug" mode in [*Constructor*](https://github.com/VeliovGroup/Meteor-Files/wiki/Constructor) + - Post *Client* and/or *Server* logs with enabled `debug` option, you can enable "debug" mode in [*Constructor*](https://github.com/veliovgroup/Meteor-Files/wiki/Constructor) ### I had an issue and I've solved it on my own: - Provide a description of steps that you've followed to solve the problem - Provide links to websites and/or pages with the information that helped you (*if there are any*) ### I have a suggestion: - 1. PRs are always welcome - [send a PR](https://github.com/VeliovGroup/Meteor-Files/compare) - - Always send PRs only to [`dev` branch](https://github.com/VeliovGroup/Meteor-Files/compare/dev), thank you + 1. PRs are always welcome - [send a PR](https://github.com/veliovgroup/Meteor-Files/compare) + - Always send PRs only to [`dev` branch](https://github.com/veliovgroup/Meteor-Files/compare/dev), thank you 2. If you're can not send a PR for some reason: - Create a new issue ticket - Describe your feature / request - How you going to use it? Give a usage example(s) ### Documentation is missing something or incorrect (have typos, etc.): - 1. PRs are always welcome - [send a PR](https://github.com/VeliovGroup/Meteor-Files/compare) - - Always send PRs only to [`dev` branch](https://github.com/VeliovGroup/Meteor-Files/compare/dev), thank you + 1. PRs are always welcome - [send a PR](https://github.com/veliovgroup/Meteor-Files/compare) + - Always send PRs only to [`dev` branch](https://github.com/veliovgroup/Meteor-Files/compare/dev), thank you 2. If you're can not send a PR to docs for some reason: - Create a new issue ticket - Give an expressive description what you have changed/added and why diff --git a/HISTORY.md b/HISTORY.md index 446485e..384c24b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1 +1 @@ -For full package history see [releases on GitHub](https://github.com/VeliovGroup/Meteor-Files/releases) \ No newline at end of file +For full package history see [releases on GitHub](https://github.com/veliovgroup/Meteor-Files/releases) \ No newline at end of file diff --git a/README.md b/README.md index 4e9776e..8ef8e4e 100644 --- a/README.md +++ b/README.md @@ -1,48 +1,48 @@ [![support](https://img.shields.io/badge/support-GitHub-white)](https://github.com/sponsors/dr-dimitru) [![support](https://img.shields.io/badge/support-PayPal-white)](https://paypal.me/veliovgroup) [![Mentioned in Awesome ostrio:files](https://awesome.re/mentioned-badge.svg)](https://project-awesome.org/Urigo/awesome-meteor#files) -[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/VeliovGroup/Meteor-Files) -[![GitHub stars](https://img.shields.io/github/stars/VeliovGroup/Meteor-Files.svg)](https://github.com/VeliovGroup/Meteor-Files/stargazers) +[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/veliovgroup/Meteor-Files) +[![GitHub stars](https://img.shields.io/github/stars/veliovgroup/Meteor-Files.svg)](https://github.com/veliovgroup/Meteor-Files/stargazers) # Files for Meteor.js -Stable, fast, robust, and well-maintained Meteor.js package for files management using MongoDB Collection API. What does exactly this means? Calling [`.insert()`](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/insert.md) method would initiate a file upload and then insert new record into collection. Calling [`.remove()`](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/remove.md) method would erase stored file and record from MongoDB Collection. And so on, no need to learn new APIs. It's flavored with extra low-level methods like [`.unlink()`](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/unlink.md) and [`.write()`](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/write.md) for complex integrations. +Stable, fast, robust, and well-maintained Meteor.js package for files management using MongoDB Collection API. What does exactly this means? Calling [`.insert()`](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/insert.md) method would initiate a file upload and then insert new record into collection. Calling [`.remove()`](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/remove.md) method would erase stored file and record from MongoDB Collection. And so on, no need to learn new APIs. It's flavored with extra low-level methods like [`.unlink()`](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/unlink.md) and [`.write()`](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/write.md) for complex integrations. ## ToC: -- [Wiki](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/toc.md) - Full documentation -- [Installation](https://github.com/VeliovGroup/Meteor-Files#installation) - - [ES6 Import](https://github.com/VeliovGroup/Meteor-Files#es6-import) -- [API](https://github.com/VeliovGroup/Meteor-Files#api-overview-full-api): - - [Initialize Collection](https://github.com/VeliovGroup/Meteor-Files#new-filescollectionconfig-isomorphic) - - [Upload file](https://github.com/VeliovGroup/Meteor-Files#insertsettings-autostart-client) - - [Stream files](https://github.com/VeliovGroup/Meteor-Files#stream-files) - - [Download Button](https://github.com/VeliovGroup/Meteor-Files#download-button) -- [Documentation and tutorials](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/toc.md) - - [__Demo apps and examples__](https://github.com/VeliovGroup/Meteor-Files#demo-application) - - [3rd-party storage integration](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/3rd-party-storage.md) examples - AWS S3, DropBox, GridFS and Google Storage - - [TypeScript Definitions](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/typescript-definitions.md) -- [Related Packages](https://github.com/VeliovGroup/Meteor-Files#related-packages) -- [Why this package?](https://github.com/VeliovGroup/Meteor-Files#why-meteor-files) -- [Help / Support](https://github.com/VeliovGroup/Meteor-Files#get-support) -- [FAQ](https://github.com/VeliovGroup/Meteor-Files#faq) -- [Awards](https://github.com/VeliovGroup/Meteor-Files#awards) -- [Help & Contribute](https://github.com/VeliovGroup/Meteor-Files#contribution) -- [Support this project](https://github.com/VeliovGroup/Meteor-Files#support-meteor-files-project) -- [Supporters](https://github.com/VeliovGroup/Meteor-Files#supporters) +- [Wiki](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/toc.md) - Full documentation +- [Installation](https://github.com/veliovgroup/Meteor-Files#installation) + - [ES6 Import](https://github.com/veliovgroup/Meteor-Files#es6-import) +- [API](https://github.com/veliovgroup/Meteor-Files#api-overview-full-api): + - [Initialize Collection](https://github.com/veliovgroup/Meteor-Files#new-filescollectionconfig-isomorphic) + - [Upload file](https://github.com/veliovgroup/Meteor-Files#insertsettings-autostart-client) + - [Stream files](https://github.com/veliovgroup/Meteor-Files#stream-files) + - [Download Button](https://github.com/veliovgroup/Meteor-Files#download-button) +- [Documentation and tutorials](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/toc.md) + - [__Demo apps and examples__](https://github.com/veliovgroup/Meteor-Files#demo-application) + - [3rd-party storage integration](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/3rd-party-storage.md) examples - AWS S3, DropBox, GridFS and Google Storage + - [TypeScript Definitions](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/typescript-definitions.md) +- [Related Packages](https://github.com/veliovgroup/Meteor-Files#related-packages) +- [Why this package?](https://github.com/veliovgroup/Meteor-Files#why-meteor-files) +- [Help / Support](https://github.com/veliovgroup/Meteor-Files#get-support) +- [FAQ](https://github.com/veliovgroup/Meteor-Files#faq) +- [Awards](https://github.com/veliovgroup/Meteor-Files#awards) +- [Help & Contribute](https://github.com/veliovgroup/Meteor-Files#contribution) +- [Support this project](https://github.com/veliovgroup/Meteor-Files#support-meteor-files-project) +- [Supporters](https://github.com/veliovgroup/Meteor-Files#supporters) ## Why `Meteor-Files`? -- Compatible with all front-end frameworks from Blaze to [React](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/react-example.md) -- Upload via `HTTP` and `DDP` transports, [read about difference](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/about-transports.md) +- Compatible with all front-end frameworks from Blaze to [React](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/react-example.md) +- Upload via `HTTP` and `DDP` transports, [read about difference](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/about-transports.md) - Sustainable and resumable uploads, which will survive connection interruption and server reboot (*if a server has persistent storage*) - Upload files through computing cloud without persistent File System, like Heroku -- You need store files at *[GridFS](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/gridfs-bucket-integration.md#use-gridfs-with-gridfsbucket-as-a-storage)*, *[AWS S3](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/aws-s3-integration.md)*, *[Google Storage](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/google-cloud-storage-integration.md)* or *[DropBox](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/dropbox-integration.md)*? (*[Use 3rd-party storage](hhttps://github.com/VeliovGroup/Meteor-Files/blob/master/docs/3rd-party-storage.md)*) -- You need to check file mime-type, size or extension? Easy! Use *[`onBeforeUpload`](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/constructor.md)* hook -- You need to [resize images](https://github.com/VeliovGroup/Meteor-Files-Demos/blob/master/demo/imports/server/image-processing.js#L19) after upload? Easy too! Use *[`onAfterUpload`](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/constructor.md)* hook, and *[manage file's subversions](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/file-subversions.md)* in a single record +- You need store files at *[GridFS](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/gridfs-bucket-integration.md#use-gridfs-with-gridfsbucket-as-a-storage)*, *[AWS S3](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/aws-s3-integration.md)*, *[Google Storage](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/google-cloud-storage-integration.md)* or *[DropBox](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/dropbox-integration.md)*? (*[Use 3rd-party storage](hhttps://github.com/veliovgroup/Meteor-Files/blob/master/docs/3rd-party-storage.md)*) +- You need to check file mime-type, size or extension? Easy! Use *[`onBeforeUpload`](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/constructor.md)* hook +- You need to [resize images](https://github.com/veliovgroup/Meteor-Files-Demos/blob/master/demo/imports/server/image-processing.js#L19) after upload? Easy too! Use *[`onAfterUpload`](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/constructor.md)* hook, and *[manage file's subversions](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/file-subversions.md)* in a single record ## Installation: @@ -56,11 +56,11 @@ meteor add ostrio:files import { FilesCollection } from 'meteor/ostrio:files'; ``` -## API overview (*[full API](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/readme.md)*) +## API overview (*[full API](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/readme.md)*) ### `new FilesCollection([config])` [*Isomorphic*] -Read full docs for [`FilesCollection` Constructor](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/constructor.md) +Read full docs for [`FilesCollection` Constructor](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/constructor.md) Shared code: @@ -93,7 +93,7 @@ if (Meteor.isServer) { ### `insert(settings[, autoStart])` [*Client*] -Read full docs for [`insert()` method](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/insert.md) +Read full docs for [`insert()` method](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/insert.md) Upload form (template): @@ -181,7 +181,7 @@ Images.insert({ }); ``` -For more expressive example see [Upload demo app](https://github.com/VeliovGroup/Meteor-Files-Demos/tree/master/demo-simplest-upload) +For more expressive example see [Upload demo app](https://github.com/veliovgroup/Meteor-Files-Demos/tree/master/demo-simplest-upload) ### Stream files @@ -215,7 +215,7 @@ const Videos = new FilesCollection({collectionName: 'Videos'}); if (Meteor.isServer) { // Upload sample files on server's startup: Meteor.startup(() => { - Images.load('https://raw.githubusercontent.com/VeliovGroup/Meteor-Files/master/logo.png', { + Images.load('https://raw.githubusercontent.com/veliovgroup/Meteor-Files/master/logo.png', { fileName: 'logo.png' }); Videos.load('http://www.sample-videos.com/video/mp4/240/big_buck_bunny_240p_5mb.mp4', { @@ -250,7 +250,7 @@ Template.file.helpers({ }); ``` -For more expressive example see [Streaming demo app](https://github.com/VeliovGroup/Meteor-Files-Demos/tree/master/demo-simplest-streaming) +For more expressive example see [Streaming demo app](https://github.com/veliovgroup/Meteor-Files-Demos/tree/master/demo-simplest-streaming) ### Download button @@ -274,7 +274,7 @@ const Images = new FilesCollection({collectionName: 'Images'}); if (Meteor.isServer) { // Load sample image into FilesCollection on server's startup: Meteor.startup(function () { - Images.load('https://raw.githubusercontent.com/VeliovGroup/Meteor-Files/master/logo.png', { + Images.load('https://raw.githubusercontent.com/veliovgroup/Meteor-Files/master/logo.png', { fileName: 'logo.png', meta: {} }); @@ -299,33 +299,33 @@ Template.file.helpers({ }); ``` -For more expressive example see [Download demo](https://github.com/VeliovGroup/Meteor-Files-Demos/tree/master/demo-simplest-download-button) +For more expressive example see [Download demo](https://github.com/veliovgroup/Meteor-Files-Demos/tree/master/demo-simplest-download-button) ## FAQ: -1. __Where are files stored by default?__: by default if `config.storagePath` isn't passed into [*Constructor*](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/constructor.md) it's equals to `assets/app/uploads` and relative to running script: +1. __Where are files stored by default?__: by default if `config.storagePath` isn't passed into [*Constructor*](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/constructor.md) it's equals to `assets/app/uploads` and relative to running script: - __a.__ On `development` stage: `yourDevAppDir/.meteor/local/build/programs/server`. __Note: All files will be removed as soon as your application rebuilds__ or you run `meteor reset`. To keep your storage persistent during development use an absolute path *outside of your project folder*, e.g. `/data` directory. - - __b.__ On `production`: `yourProdAppDir/programs/server`. __Note: If using MeteorUp (MUP), Docker volumes must to be added to__ `mup.json`, see [MUP usage](hhttps://github.com/VeliovGroup/Meteor-Files/blob/master/docs/meteorup-usage.md) -2. __Cordova usage and development__: With support of community we do regular testing on virtual and real devices. To make sure `Meteor-Files` library runs smoothly in Cordova environment — enable [withCredentials](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials); enable `{allowQueryStringCookies: true}` and `{allowedOrigins: true}` on both `Client` and `Server`. For more details read [Cookie's repository FAQ](https://github.com/VeliovGroup/Meteor-Cookies#faq) -3. __How to pause/continue upload and get progress/speed/remaining time?__: see *Object* returned from [`insert` method](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/insert.md) + - __b.__ On `production`: `yourProdAppDir/programs/server`. __Note: If using MeteorUp (MUP), Docker volumes must to be added to__ `mup.json`, see [MUP usage](hhttps://github.com/veliovgroup/Meteor-Files/blob/master/docs/meteorup-usage.md) +2. __Cordova usage and development__: With support of community we do regular testing on virtual and real devices. To make sure `Meteor-Files` library runs smoothly in Cordova environment — enable [withCredentials](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials); enable `{allowQueryStringCookies: true}` and `{allowedOrigins: true}` on both `Client` and `Server`. For more details read [Cookie's repository FAQ](https://github.com/veliovgroup/Meteor-Cookies#faq) +3. __How to pause/continue upload and get progress/speed/remaining time?__: see *Object* returned from [`insert` method](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/insert.md) 4. When using any of `accounts` packages - package `accounts-base` must be explicitly added to `.meteor/packages` above `ostrio:files` 5. __cURL/POST uploads__ - Take a look on [POST-Example](https://github.com/noris666/Meteor-Files-POST-Example) by [@noris666](https://github.com/noris666) -6. In __Safari__ (Mobile and Desktop) for `DDP` chunk size is reduced by algorithm, due to error thrown if frame is too big. Limit simultaneous uploads to `6` is recommended for Safari. This issue should be fixed in Safari 11. Switching to `http` transport (*which has no such issue*) is recommended for Safari. See [#458](https://github.com/VeliovGroup/Meteor-Files/issues/458) -7. Make sure you're using single domain for the Meteor app, and the same domain for hosting Meteor-Files endpoints, see [#737](https://github.com/VeliovGroup/Meteor-Files/issues/737) for details -8. When proxying requests to Meteor-Files endpoint make sure protocol `http/1.1` is used, see [#742](https://github.com/VeliovGroup/Meteor-Files/issues/742) for details +6. In __Safari__ (Mobile and Desktop) for `DDP` chunk size is reduced by algorithm, due to error thrown if frame is too big. Limit simultaneous uploads to `6` is recommended for Safari. This issue should be fixed in Safari 11. Switching to `http` transport (*which has no such issue*) is recommended for Safari. See [#458](https://github.com/veliovgroup/Meteor-Files/issues/458) +7. Make sure you're using single domain for the Meteor app, and the same domain for hosting Meteor-Files endpoints, see [#737](https://github.com/veliovgroup/Meteor-Files/issues/737) for details +8. When proxying requests to Meteor-Files endpoint make sure protocol `http/1.1` is used, see [#742](https://github.com/veliovgroup/Meteor-Files/issues/742) for details ## Awards: - + ## Get Support: -- [Ask a question via Gitter chat](https://gitter.im/VeliovGroup/Meteor-Files) -- [Ask a question or submit an issue](https://github.com/VeliovGroup/Meteor-Files/issues) -- [Releases / Changelog / History](https://github.com/VeliovGroup/Meteor-Files/releases) -- For more docs and examples [read wiki](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/readme.md) +- [Ask a question via Gitter chat](https://gitter.im/veliovgroup/Meteor-Files) +- [Ask a question or submit an issue](https://github.com/veliovgroup/Meteor-Files/issues) +- [Releases / Changelog / History](https://github.com/veliovgroup/Meteor-Files/releases) +- For more docs and examples [read wiki](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/readme.md) ## Demo application: @@ -334,12 +334,12 @@ For more expressive example see [Download demo](https://github.com/VeliovGroup/M ## Related Packages: -- [pyfiles (meteor-python-files)](https://github.com/VeliovGroup/meteor-python-files) Python Client for Meteor-Files package -- [meteor-autoform-file](https://github.com/VeliovGroup/meteor-autoform-file) - Upload and manage files with [autoForm](https://github.com/aldeed/meteor-autoform) +- [pyfiles (meteor-python-files)](https://github.com/veliovgroup/meteor-python-files) Python Client for Meteor-Files package +- [meteor-autoform-file](https://github.com/veliovgroup/meteor-autoform-file) - Upload and manage files with [autoForm](https://github.com/aldeed/meteor-autoform) ## Support Meteor-Files project: -- Star on [GitHub](https://github.com/VeliovGroup/Meteor-Files) +- Star on [GitHub](https://github.com/veliovgroup/Meteor-Files) - Star on [Atmosphere](https://atmospherejs.com/ostrio/files) - Share via [Facebook](https://www.facebook.com/sharer.php?u=https%3A%2F%2Fgithub.com%2FVeliovGroup%2FMeteor-Files) and [Twitter](https://twitter.com/share?url=https%3A%2F%2Fgithub.com%2FVeliovGroup%2FMeteor-Files) - [Sponsor via GitHub](https://github.com/sponsors/dr-dimitru) @@ -348,8 +348,8 @@ For more expressive example see [Download demo](https://github.com/VeliovGroup/M ## Contribution: -- __Want to help?__ Please check [issues](https://github.com/VeliovGroup/Meteor-Files/issues) for open and tagged as [`help wanted` issues](https://github.com/VeliovGroup/Meteor-Files/issues?q=is%3Aissue+is%3Aopen+label%3A"help+wanted"); -- __Want to contribute?__ Read and follow [PR rules](https://github.com/VeliovGroup/Meteor-Files/blob/master/.github/PULL_REQUEST_TEMPLATE). All PRs are welcome on [`dev` branch](https://github.com/VeliovGroup/Meteor-Files/tree/dev). Please, always give expressive description to your changes and additions. +- __Want to help?__ Please check [issues](https://github.com/veliovgroup/Meteor-Files/issues) for open and tagged as [`help wanted` issues](https://github.com/veliovgroup/Meteor-Files/issues?q=is%3Aissue+is%3Aopen+label%3A"help+wanted"); +- __Want to contribute?__ Read and follow [PR rules](https://github.com/veliovgroup/Meteor-Files/blob/master/.github/PULL_REQUEST_TEMPLATE). All PRs are welcome on [`dev` branch](https://github.com/veliovgroup/Meteor-Files/tree/dev). Please, always give expressive description to your changes and additions. ## Supporters: diff --git a/client.js b/client.js index 0f806af..756fa80 100644 --- a/client.js +++ b/client.js @@ -288,7 +288,7 @@ export class FilesCollection extends FilesCollectionCore { * @name fileURL * @param {Object} fileRef - File reference object * @param {String} version - [Optional] Version of file you would like to request - * @param {String} uriBase - [Optional] URI base, see - https://github.com/VeliovGroup/Meteor-Files/issues/626 + * @param {String} uriBase - [Optional] URI base, see - https://github.com/veliovgroup/Meteor-Files/issues/626 * @summary Get download URL for file by fileRef, even without subscription * @example {{fileURL fileRef}} * @returns {String} diff --git a/core.js b/core.js index ff9a937..59f600d 100644 --- a/core.js +++ b/core.js @@ -257,7 +257,7 @@ export default class FilesCollectionCore extends EventEmitter { * @name link * @param {Object} fileRef - File reference object * @param {String} version - Version of file you would like to request - * @param {String} uriBase - [Optional] URI base, see - https://github.com/VeliovGroup/Meteor-Files/issues/626 + * @param {String} uriBase - [Optional] URI base, see - https://github.com/veliovgroup/Meteor-Files/issues/626 * @summary Returns downloadable URL * @returns {String} Empty string returned in case if file not found in DB */ diff --git a/cursor.js b/cursor.js index 7b2e807..d7583db 100644 --- a/cursor.js +++ b/cursor.js @@ -38,7 +38,7 @@ export class FileCursor { * @memberOf FileCursor * @name link * @param version {String} - Name of file's subversion - * @param uriBase {String} - [Optional] URI base, see - https://github.com/VeliovGroup/Meteor-Files/issues/626 + * @param uriBase {String} - [Optional] URI base, see - https://github.com/veliovgroup/Meteor-Files/issues/626 * @summary Returns downloadable URL to File * @returns {String} */ diff --git a/demo-simplest-download-button/README.md b/demo-simplest-download-button/README.md index 6f78f48..3f48e45 100644 --- a/demo-simplest-download-button/README.md +++ b/demo-simplest-download-button/README.md @@ -1,4 +1,4 @@ 301 ======== -Moved to [Meteor-Files-Demos](https://github.com/VeliovGroup/Meteor-Files-Demos) repository \ No newline at end of file +Moved to [Meteor-Files-Demos](https://github.com/veliovgroup/Meteor-Files-Demos) repository \ No newline at end of file diff --git a/demo-simplest-streaming/README.md b/demo-simplest-streaming/README.md index 6f78f48..3f48e45 100644 --- a/demo-simplest-streaming/README.md +++ b/demo-simplest-streaming/README.md @@ -1,4 +1,4 @@ 301 ======== -Moved to [Meteor-Files-Demos](https://github.com/VeliovGroup/Meteor-Files-Demos) repository \ No newline at end of file +Moved to [Meteor-Files-Demos](https://github.com/veliovgroup/Meteor-Files-Demos) repository \ No newline at end of file diff --git a/demo-simplest-upload/README.md b/demo-simplest-upload/README.md index 6f78f48..3f48e45 100644 --- a/demo-simplest-upload/README.md +++ b/demo-simplest-upload/README.md @@ -1,4 +1,4 @@ 301 ======== -Moved to [Meteor-Files-Demos](https://github.com/VeliovGroup/Meteor-Files-Demos) repository \ No newline at end of file +Moved to [Meteor-Files-Demos](https://github.com/veliovgroup/Meteor-Files-Demos) repository \ No newline at end of file diff --git a/demo/README.md b/demo/README.md index 6f78f48..3f48e45 100644 --- a/demo/README.md +++ b/demo/README.md @@ -1,4 +1,4 @@ 301 ======== -Moved to [Meteor-Files-Demos](https://github.com/VeliovGroup/Meteor-Files-Demos) repository \ No newline at end of file +Moved to [Meteor-Files-Demos](https://github.com/veliovgroup/Meteor-Files-Demos) repository \ No newline at end of file diff --git a/docs/3rd-party-storage.md b/docs/3rd-party-storage.md index 0a8dfa4..069ffff 100644 --- a/docs/3rd-party-storage.md +++ b/docs/3rd-party-storage.md @@ -5,10 +5,10 @@ Any 3rd party storage with REST API or Node.js SDK can be easily integrated. __Integration examples:__ -- [AWS S3 Bucket Integration](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/aws-s3-integration.md) -- [DropBox Integration](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/dropbox-integration.md) -- [GridFS using `GridFSBucket`](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/gridfs-bucket-integration.md#use-gridfs-with-gridfsbucket-as-a-storage) -- [GridFS using `gridfs-stream` (legacy)](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/gridfs-integration.md) -- [Google Cloud Storage Integration](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/google-cloud-storage-integration.md) +- [AWS S3 Bucket Integration](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/aws-s3-integration.md) +- [DropBox Integration](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/dropbox-integration.md) +- [GridFS using `GridFSBucket`](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/gridfs-bucket-integration.md#use-gridfs-with-gridfsbucket-as-a-storage) +- [GridFS using `gridfs-stream` (legacy)](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/gridfs-integration.md) +- [Google Cloud Storage Integration](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/google-cloud-storage-integration.md) -*AWS S3* and *DropBox* is available in [demo app](https://github.com/VeliovGroup/Meteor-Files-Demos/tree/master/demo) out-of-the box +*AWS S3* and *DropBox* is available in [demo app](https://github.com/veliovgroup/Meteor-Files-Demos/tree/master/demo) out-of-the box diff --git a/docs/about-transports.md b/docs/about-transports.md index a12d020..4a2fc52 100644 --- a/docs/about-transports.md +++ b/docs/about-transports.md @@ -34,7 +34,7 @@ The cons: ## RTC Data Chanel (UDP) -This transport supported only in [webrtc-data-channel](https://github.com/VeliovGroup/Meteor-Files/tree/webrtc-data-channel) branch. It's in testing mode, we're waiting for community feedback, before merging to `master`. If you're interested in RTC/DC uploads, try this branch locally. Any feedback on RTC/DC usage for uploads is highly appreciated! +This transport supported only in [webrtc-data-channel](https://github.com/veliovgroup/Meteor-Files/tree/webrtc-data-channel) branch. It's in testing mode, we're waiting for community feedback, before merging to `master`. If you're interested in RTC/DC uploads, try this branch locally. Any feedback on RTC/DC usage for uploads is highly appreciated! The pros: diff --git a/docs/constructor.md b/docs/constructor.md index 865dd0e..b8df784 100644 --- a/docs/constructor.md +++ b/docs/constructor.md @@ -159,10 +159,10 @@ Allows to change default response headers - Default Function + Default Function - We recommend to keep original function structure, with your modifications, see example altering default headers + We recommend to keep original function structure, with your modifications, see example altering default headers @@ -206,10 +206,10 @@ Collection Schema - Default Schema + Default Schema - For more info read Schema docs + For more info read Schema docs @@ -324,7 +324,7 @@ Arguments:
Context: @@ -363,7 +363,7 @@ Arguments:
  • - fileObj {Object|null} - If requested file exists - file object, otherwise - + fileObj {Object|null} - If requested file exists - file object, otherwise - null

@@ -517,7 +517,7 @@ false - See: #208 + See: #208 @@ -1116,7 +1116,7 @@ const Images = new FilesCollection({ #### Use onBeforeRemove to avoid unauthorized remove: -*For more info see [remove method](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/remove.md).* +*For more info see [remove method](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/remove.md).* ```js import { FilesCollection } from 'meteor/ostrio:files'; diff --git a/docs/custom-response-headers.md b/docs/custom-response-headers.md index 68e8d71..dda625e 100644 --- a/docs/custom-response-headers.md +++ b/docs/custom-response-headers.md @@ -1,6 +1,6 @@ # Custom Response Headers -- `config.responseHeaders` option (*passed into [`FilesCollection` Constructor](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/constructor.md)*) +- `config.responseHeaders` option (*passed into [`FilesCollection` Constructor](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/constructor.md)*) *Allows to change default response headers.* diff --git a/docs/find.md b/docs/find.md index fd45352..ec09e30 100644 --- a/docs/find.md +++ b/docs/find.md @@ -4,7 +4,7 @@ Find and return Cursor for matching documents. - `selector` {*String*|*Object*} - [Mongo-Style selector](http://docs.meteor.com/api/collections.html#selectors) - `options` {*Object*} - [Mongo-Style selector Options](http://docs.meteor.com/api/collections.html#sortspecifiers) -- Returns {*[FilesCursor](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/FilesCursor.md)*} +- Returns {*[FilesCursor](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/FilesCursor.md)*} ```js import { Meteor } from 'meteor/meteor'; diff --git a/docs/findOne.md b/docs/findOne.md index 268b9c4..284f125 100644 --- a/docs/findOne.md +++ b/docs/findOne.md @@ -4,7 +4,7 @@ Finds the first document that matches the selector, as ordered by sort and skip - `selector` {*String*|*Object*} - [Mongo-Style selector](http://docs.meteor.com/api/collections.html#selectors) - `options` {*Object*} - [Mongo-Style selector Options](http://docs.meteor.com/api/collections.html#sortspecifiers) -- Returns {*[FileCursor](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/FileCursor.md)*} +- Returns {*[FileCursor](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/FileCursor.md)*} ```js import { FilesCollection } from 'meteor/ostrio:files'; diff --git a/docs/gridfs-bucket-integration.md b/docs/gridfs-bucket-integration.md index e332aa6..14610bd 100644 --- a/docs/gridfs-bucket-integration.md +++ b/docs/gridfs-bucket-integration.md @@ -9,7 +9,7 @@ This allows to *horizontally scale your files* the same way you do with your doc **A note for beginners:** This tutorial is a bit advanced and we try to explain the involved steps as detailed as possible. If you still need some reference to play with, we have set up an example project. The project -is available via [`files-gridfs-autoform-example`](https://github.com/VeliovGroup/files-gridfs-autoform-example) +is available via [`files-gridfs-autoform-example`](https://github.com/veliovgroup/files-gridfs-autoform-example) ## About GridFS @@ -25,7 +25,7 @@ plus some additional metadata. Please note - by default all files will be served with `200` response code, which is fine if you planning to deal only with small files, or not planning to serve files back to users (*use only upload and storage*). -For support of `206` partial content see [this article](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/gridfs-streaming.md). +For support of `206` partial content see [this article](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/gridfs-streaming.md). ## 1. Create a `GridFSBucket` factory diff --git a/docs/gridfs-integration.md b/docs/gridfs-integration.md index a9681bd..b4c4305 100644 --- a/docs/gridfs-integration.md +++ b/docs/gridfs-integration.md @@ -1,11 +1,11 @@ ### Use GridFS with `gridfs-stream` as a storage > :warning: **Deprecation warning:** The `gridfs-stream` [has not been updated in a long time](https://github.com/aheckmann/gridfs-stream) and its implementation relies on the deprecated [`GridStore API`](https://mongodb.github.io/node-mongodb-native/3.6/api/GridStore.html). An alternative is to use the Mongo driver's native `GridFSBucket`, which is also [described in -this wiki](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/gridfs-bucket-integration.md). +this wiki](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/gridfs-bucket-integration.md). Example below shows how to handle (store, serve, remove) uploaded files via GridFS. -Please note - by default all files will be served with `200` response code, which is fine if you planning to deal only with small files, or not planning to serve files back to users (*use only upload and storage*). For support of `206` partial content see [this article](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/gridfs-streaming.md). +Please note - by default all files will be served with `200` response code, which is fine if you planning to deal only with small files, or not planning to serve files back to users (*use only upload and storage*). For support of `206` partial content see [this article](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/gridfs-streaming.md). ### Preparation diff --git a/docs/gridfs-migration.md b/docs/gridfs-migration.md index 43f7334..1d45bda 100644 --- a/docs/gridfs-migration.md +++ b/docs/gridfs-migration.md @@ -18,7 +18,7 @@ First create three Methods in P that each share one of the three crucial Parts o - Sharing the `fs.files`* metadata for the files' respective subversions - Sharing the `fs.chunks`* (the actual data) of all stored files and their subversions -*This assumes the [default configuration of your GridFS](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/gridfs-bucket-integration.md) which is by default using the `db.fs.files` and `db.fs.chunks` collections.* +*This assumes the [default configuration of your GridFS](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/gridfs-bucket-integration.md) which is by default using the `db.fs.files` and `db.fs.chunks` collections.* *For custom configuration you may consult the JS Mongo Native Driver documentation on [GridFSBucket](http://mongodb.github.io/node-mongodb-native/3.6/api/GridFSBucket.html).* diff --git a/docs/gridfs-streaming.md b/docs/gridfs-streaming.md index a91f1bb..cd57254 100644 --- a/docs/gridfs-streaming.md +++ b/docs/gridfs-streaming.md @@ -2,7 +2,7 @@ By default files served from GridFS returned with `200` response code. This beha `206` partial content response is much better from all sides, for video and audio it allows to support time-seeking, for large files - resumable downloads. For server-side it reduces memory and CPU consumption. -Below is code sample suggested by [@j1016h](https://github.com/j1016h), where [`interceptDownload`](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/constructor.md) is used to alter default file-serving behavior - *use it as it at your own risk, or take it and modify to meet your own needs*. +Below is code sample suggested by [@j1016h](https://github.com/j1016h), where [`interceptDownload`](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/constructor.md) is used to alter default file-serving behavior - *use it as it at your own risk, or take it and modify to meet your own needs*. ```js interceptDownload(http, image, versionName) { diff --git a/docs/insert.md b/docs/insert.md index 5ed901c..eebd293 100644 --- a/docs/insert.md +++ b/docs/insert.md @@ -77,7 +77,7 @@ Upload file to a Server via DDP or HTTP. Upload as base64 string, useful for data taken from `canvas` - See Examples + See Examples diff --git a/docs/load.md b/docs/load.md index bd84cca..198a408 100644 --- a/docs/load.md +++ b/docs/load.md @@ -34,7 +34,7 @@ Write file to file system from remote URL (external resource) and add record to import { FilesCollection } from 'meteor/ostrio:files'; const Images = new FilesCollection({collectionName: 'Images'}); -Images.load('https://raw.githubusercontent.com/VeliovGroup/Meteor-Files/master/logo.png', { +Images.load('https://raw.githubusercontent.com/veliovgroup/Meteor-Files/master/logo.png', { fileName: 'logo.png', fileId: 'abc123myId', //optional timeout: 60000, // optional timeout diff --git a/docs/meteorup-usage.md b/docs/meteorup-usage.md index 081936c..0d9cde6 100644 --- a/docs/meteorup-usage.md +++ b/docs/meteorup-usage.md @@ -4,7 +4,7 @@ [MeteorUp (MUP)](https://github.com/kadirahq/meteor-up) uses Docker, and by default, there is no volume mounted on the server. Therefore, even if `storagePath` is declared in constructor, files that are being uploaded are still being stored in cache, and on every deploy, all the uploaded files __get erased__. -Read more at [Issue #270](https://github.com/VeliovGroup/Meteor-Files/issues/72) and [Issue #290](https://github.com/VeliovGroup/Meteor-Files/issues/290). +Read more at [Issue #270](https://github.com/veliovgroup/Meteor-Files/issues/72) and [Issue #290](https://github.com/veliovgroup/Meteor-Files/issues/290). To solve this issue, a volume has to be declared in `project-root/mup.json`. In this example, images will be stored at `/images` directory. @@ -74,4 +74,4 @@ Images = new FilesCollection({ }); ``` -Now, files will be uploaded to `/images` on server, and can be accessed like in [demos](https://github.com/VeliovGroup/Meteor-Files-Demos). +Now, files will be uploaded to `/images` on server, and can be accessed like in [demos](https://github.com/veliovgroup/Meteor-Files-Demos). diff --git a/docs/react-example.md b/docs/react-example.md index 74c3a81..ee14a4b 100644 --- a/docs/react-example.md +++ b/docs/react-example.md @@ -1,6 +1,6 @@ # React.js usage -*This example is for the front-end UI only. The server side [methods](https://github.com/VeliovGroup/Meteor-Files/wiki#api) and [publications](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/collection.md) are the same.* +*This example is for the front-end UI only. The server side [methods](https://github.com/veliovgroup/Meteor-Files/wiki#api) and [publications](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/collection.md) are the same.* ## Brief: diff --git a/docs/readme.md b/docs/readme.md index 379415e..105ff03 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -3,22 +3,22 @@ ## About: - Event-driven API -- [TypeScript Definitions](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/typescript-definitions.md) +- [TypeScript Definitions](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/typescript-definitions.md) - Upload / Read files in Cordova app: __Cordva support__ (Any with support of `FileReader`) - File upload: - - Upload via *HTTP* or *DDP*, [read about difference](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/about-transports.md#about-upload-transports) + - Upload via *HTTP* or *DDP*, [read about difference](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/about-transports.md#about-upload-transports) - Ready for small and large files (optimized RAM usage) - Pause / Resume upload - Auto-pause when connection to server is interrupted - Parallel multi-stream async upload (*faster than ever*) - Support of non-Latin (non-Roman) file names -- [Use third-party storage](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/3rd-party-storage.md): - - [AWS S3 Bucket Integration](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/aws-s3-integration.md) - - [DropBox Integration](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/dropbox-integration.md) - - [GridFS using `GridFSBucket`](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/gridfs-bucket-integration.md#use-gridfs-with-gridfsbucket-as-a-storage) - - [GridFS using `gridfs-stream` (legacy)](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/gridfs-integration.md) +- [Use third-party storage](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/3rd-party-storage.md): + - [AWS S3 Bucket Integration](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/aws-s3-integration.md) + - [DropBox Integration](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/dropbox-integration.md) + - [GridFS using `GridFSBucket`](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/gridfs-bucket-integration.md#use-gridfs-with-gridfsbucket-as-a-storage) + - [GridFS using `gridfs-stream` (legacy)](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/gridfs-integration.md) - Google Drive - - [Google Cloud Storage Integration](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/google-cloud-storage-integration.md) + - [Google Cloud Storage Integration](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/google-cloud-storage-integration.md) - any other with JS/REST API - Get upload speed - Get remaining upload time @@ -37,27 +37,27 @@ - Support for file subversions, like thumbnails, audio/video file formats, revisions, and etc. - Store wherever you like: - You may use `Meteor-Files` as temporary storage - - After file is uploaded and stored on FS you able to `mv` or `cp` its content, see [3rd-party storage integration](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/3rd-party-storage.md) examples + - After file is uploaded and stored on FS you able to `mv` or `cp` its content, see [3rd-party storage integration](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/3rd-party-storage.md) examples - Subscribe on files (*collections*) you need ## ToC: ### API: -- [`FilesCollection` Constructor](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/constructor.md) [*Isomorphic*] - Initialize FilesCollection - - [SimpleSchema Integration](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/constructor.md#attach-schema-isomorphic) - - [Collection `deny` rules](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/constructor.md#deny-collection-interaction-on-client-server) - - [Collection `allow` rules](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/constructor.md#allow-collection-interaction-on-client-server) - - [Control upload access](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/constructor.md#use-onbeforeupload-to-avoid-unauthorized-upload) - - [Control remove access](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/constructor.md#use-onbeforeremove-to-avoid-unauthorized-remove) - - [Custom response headers](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/custom-response-headers.md#custom-response-headers) for CORS or anything else -- [`FileCursor` Class](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/FileCursor.md) - Instance of this class is returned from `.findOne()` method +- [`FilesCollection` Constructor](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/constructor.md) [*Isomorphic*] - Initialize FilesCollection + - [SimpleSchema Integration](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/constructor.md#attach-schema-isomorphic) + - [Collection `deny` rules](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/constructor.md#deny-collection-interaction-on-client-server) + - [Collection `allow` rules](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/constructor.md#allow-collection-interaction-on-client-server) + - [Control upload access](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/constructor.md#use-onbeforeupload-to-avoid-unauthorized-upload) + - [Control remove access](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/constructor.md#use-onbeforeremove-to-avoid-unauthorized-remove) + - [Custom response headers](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/custom-response-headers.md#custom-response-headers) for CORS or anything else +- [`FileCursor` Class](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/FileCursor.md) - Instance of this class is returned from `.findOne()` method - `remove(callback)` - {*undefined*} - Remove document - `link()` - {*String*} - Returns downloadable URL to File - `get(property)` - {*Object*|*mix*} - Returns current document as a plain Object - `fetch()` - {[*Object*]}- Returns current document as plain Object in Array - `with()` - {*FileCursor*} - Returns reactive version of current FileCursor -- [`FilesCursor` Class](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/FilesCursor.md) - Instance of this class is returned from `.find()` method +- [`FilesCursor` Class](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/FilesCursor.md) - Instance of this class is returned from `.find()` method - `fetch()` - {*[Object]*} - Returns all matching document(s) as an Array - `count()` - {*Number*} - Returns the number of documents that match a query - `remove(callback)` - {*undefined*} - Removes all documents that match a query @@ -65,44 +65,44 @@ - `each()` - {*[FileCursor]*} - Returns an Array of `FileCursor` made for each document on current Cursor - `observe(callbacks)` - {*Object*} - Functions to call to deliver the result set as it changes - `observeChanges(callbacks)` - {*Object*} - Watch a query. Receive callbacks as the result set changes - - [See all methods](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/FilesCursor.md) -- [Default Collection Schema](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/schema.md#schema) - - [Attach SimpleSchema and Collection2](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/schema.md#attach-schema-recommended) - - [Extend Schema](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/schema.md#extend-default-schema) - - [Override Schema](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/schema.md#pass-your-own-schema-not-recommended) -- [`write()`](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/write.md) [*Server*] - Write `Buffer` to FS and FilesCollection -- [`load()`](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/load.md) [*Server*] - Write file to FS and FilesCollection from remote URL -- [`addFile()`](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/addFile.md) [*Server*] - Add local file to FilesCollection from FS -- [`findOne()`](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/findOne.md) [*Isomorphic*] - Find one file in FilesCollection -- [`find()`](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/find.md) [*Isomorphic*] - Create cursor for FilesCollection -- [`insert()`](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/insert.md) [*Client*] - Upload file to server - - [`FileUpload.pipe()`](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/insert.md#piping) -- [`remove()`](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/remove.md) [*Isomorphic*] - Remove files from FilesCollection and unlink from FS -- [`unlink()`](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/unlink.md) [*Server*] - Unlink file from FS -- [`link()`](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/link.md) [*Isomorphic*] - Generate downloadable link -- [`collection`](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/collection.md) [*Isomorphic*] - `Meteor.Collection` instance -- [Template helper `fileURL`](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/template-helper.md) [*Client*] - Generate downloadable link in a template + - [See all methods](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/FilesCursor.md) +- [Default Collection Schema](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/schema.md#schema) + - [Attach SimpleSchema and Collection2](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/schema.md#attach-schema-recommended) + - [Extend Schema](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/schema.md#extend-default-schema) + - [Override Schema](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/schema.md#pass-your-own-schema-not-recommended) +- [`write()`](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/write.md) [*Server*] - Write `Buffer` to FS and FilesCollection +- [`load()`](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/load.md) [*Server*] - Write file to FS and FilesCollection from remote URL +- [`addFile()`](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/addFile.md) [*Server*] - Add local file to FilesCollection from FS +- [`findOne()`](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/findOne.md) [*Isomorphic*] - Find one file in FilesCollection +- [`find()`](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/find.md) [*Isomorphic*] - Create cursor for FilesCollection +- [`insert()`](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/insert.md) [*Client*] - Upload file to server + - [`FileUpload.pipe()`](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/insert.md#piping) +- [`remove()`](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/remove.md) [*Isomorphic*] - Remove files from FilesCollection and unlink from FS +- [`unlink()`](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/unlink.md) [*Server*] - Unlink file from FS +- [`link()`](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/link.md) [*Isomorphic*] - Generate downloadable link +- [`collection`](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/collection.md) [*Isomorphic*] - `Meteor.Collection` instance +- [Template helper `fileURL`](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/template-helper.md) [*Client*] - Generate downloadable link in a template ### Examples: -- `docs` [Third-party storage (AWS S3, DropBox, GridFS and Google Storage)](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/3rd-party-storage.md) -- `code-sample` [File subversions](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/file-subversions.md) - Create video file with preview and multiple formats +- `docs` [Third-party storage (AWS S3, DropBox, GridFS and Google Storage)](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/3rd-party-storage.md) +- `code-sample` [File subversions](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/file-subversions.md) - Create video file with preview and multiple formats - `code-sample repo` [cURL/POST upload](https://github.com/noris666/Meteor-Files-POST-Example) by [@noris666](https://github.com/noris666) -- `tutorial` [MUP/Docker Persistent Storage](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/meteorup-usage.md) - Deploy via MeteorUp to Docker container with persistent `storagePath` -- `tutorial` [React.js usage](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/react-example.md) - React with a progress bar and component with links to view, re-name, and delete the files -- `tutorial` [Migrating from CollectionFS/CFS](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/convert-from-cfs-to-meteor-files.md) - Live conversion from the depreciated CFS to Meteor-Files (*Amazon S3 specifically, but applies to all*) -- `tutorial` [Geting `FilesCollection` instance](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/collection-instances.md#filescollection-instances-and-mongocollection-instances) - Retrieve the *FilesCollection* by it's underlying `Mongo.Collection` instance -- `tutorial` [Migrating / moving GridFS stored files](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/gridfs-migration.md) - Three step way of moving/copying/syncing GridFS-stored files between multiple Meteor applications -- `tutorial` [GridFS streaming](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/gridfs-streaming.md) - Implement `206` partial content response +- `tutorial` [MUP/Docker Persistent Storage](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/meteorup-usage.md) - Deploy via MeteorUp to Docker container with persistent `storagePath` +- `tutorial` [React.js usage](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/react-example.md) - React with a progress bar and component with links to view, re-name, and delete the files +- `tutorial` [Migrating from CollectionFS/CFS](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/convert-from-cfs-to-meteor-files.md) - Live conversion from the depreciated CFS to Meteor-Files (*Amazon S3 specifically, but applies to all*) +- `tutorial` [Geting `FilesCollection` instance](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/collection-instances.md#filescollection-instances-and-mongocollection-instances) - Retrieve the *FilesCollection* by it's underlying `Mongo.Collection` instance +- `tutorial` [Migrating / moving GridFS stored files](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/gridfs-migration.md) - Three step way of moving/copying/syncing GridFS-stored files between multiple Meteor applications +- `tutorial` [GridFS streaming](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/gridfs-streaming.md) - Implement `206` partial content response - __Post-processing:__ - - `tutorial` [Create Thumbnails](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/image-processing.md) - - `tutorial` [Image post-processing using AWS Lambda](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/aws-s3-integration.md#further-image-jpeg-png-processing-with-aws-lambda) - - `code-sample` [Resize, create thumbnail](https://github.com/VeliovGroup/Meteor-Files-Demos/blob/master/demo/imports/server/image-processing.js#L19) + - `tutorial` [Create Thumbnails](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/image-processing.md) + - `tutorial` [Image post-processing using AWS Lambda](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/aws-s3-integration.md#further-image-jpeg-png-processing-with-aws-lambda) + - `code-sample` [Resize, create thumbnail](https://github.com/veliovgroup/Meteor-Files-Demos/blob/master/demo/imports/server/image-processing.js#L19) ### Related Packages: -- [`pyfiles` (meteor-python-files))](https://github.com/VeliovGroup/meteor-python-files) Python Client for Meteor-Files package -- [`meteor-autoform-file`](https://github.com/VeliovGroup/meteor-autoform-file) - Upload and manage files with [autoForm](https://github.com/aldeed/meteor-autoform) +- [`pyfiles` (meteor-python-files))](https://github.com/veliovgroup/meteor-python-files) Python Client for Meteor-Files package +- [`meteor-autoform-file`](https://github.com/veliovgroup/meteor-autoform-file) - Upload and manage files with [autoForm](https://github.com/aldeed/meteor-autoform) ### Articles: @@ -110,4 +110,4 @@ ### WIP: -- Experimental [webrtc-data-channel](https://github.com/VeliovGroup/Meteor-Files/tree/webrtc-data-channel) branch, welcome for feedback/discussion +- Experimental [webrtc-data-channel](https://github.com/veliovgroup/Meteor-Files/tree/webrtc-data-channel) branch, welcome for feedback/discussion diff --git a/docs/remove.md b/docs/remove.md index c4be6b0..64e9e3a 100644 --- a/docs/remove.md +++ b/docs/remove.md @@ -34,7 +34,7 @@ Images.remove({_id: 'Rfy2HLutYK4XWkwhm'}, (error) => { }); ``` -*Use onBeforeRemove to avoid unauthorized actions, for more info see [onBeforeRemove callback](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/constructor.md#use-onbeforeremove-to-avoid-unauthorized-remove)* +*Use onBeforeRemove to avoid unauthorized actions, for more info see [onBeforeRemove callback](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/constructor.md#use-onbeforeremove-to-avoid-unauthorized-remove)* ```js import { FilesCollection } from 'meteor/ostrio:files'; diff --git a/docs/schema.md b/docs/schema.md index dba829d..c077405 100644 --- a/docs/schema.md +++ b/docs/schema.md @@ -1,6 +1,6 @@ # Schema -*Below is default Files collection schema. Please keep default schema structure when extending it!. To pass your own schema use* `schema` *property when passing config to* [`FilesCollection`](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/constructor.md) *constructor.* +*Below is default Files collection schema. Please keep default schema structure when extending it!. To pass your own schema use* `schema` *property when passing config to* [`FilesCollection`](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/constructor.md) *constructor.* For more info see [Collection2](https://github.com/aldeed/meteor-collection2) and [simple-schema](https://atmospherejs.com/aldeed/simple-schema) packages. diff --git a/docs/template-helper.md b/docs/template-helper.md index 107a10a..e86b10f 100644 --- a/docs/template-helper.md +++ b/docs/template-helper.md @@ -34,7 +34,7 @@ if (Meteor.isClient) { __Note:__ If requested version of file is not available - the original file will be returned. -For more info about file's subversions see: [create subversions](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/file-subversions.md) section +For more info about file's subversions see: [create subversions](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/file-subversions.md) section ```handlebars @@ -59,7 +59,7 @@ For `compare` helper see [ostrio:templatehelpers](https://atmospherejs.com/ostri __Note:__ If thumbnail (*subversion of the file*) is not available the original file will be returned. -For more info about file's subversions see: [create subversions](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/file-subversions.md) section +For more info about file's subversions see: [create subversions](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/file-subversions.md) section ```handlebars {{fileRef.name}} @@ -69,7 +69,7 @@ For more info about file's subversions see: [create subversions](https://github. #### Example for video with multiple subversions: -For more info about file's subversions see: [create subversions](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/file-subversions.md) section +For more info about file's subversions see: [create subversions](https://github.com/veliovgroup/Meteor-Files/blob/master/docs/file-subversions.md) section ```handlebars