Skip to content

Commit

Permalink
Merge pull request #744 from VeliovGroup/dev
Browse files Browse the repository at this point in the history
v1.14.2
- 🐞 Fix #742, thanks to @menelike and @jankapunkt 
- 🤓 Update *TypeScript* definitions, thanks to @OliverColeman PR #743, see #226 thread for details
- 🤝 Compatibility with `[email protected]`
- 📋 Documentation update to address issue described in #737, thanks to @menelike, @Lickshotz, @s-ol, and @jankapunkt
  • Loading branch information
dr-dimitru authored May 4, 2020
2 parents 0f73a36 + 9db7452 commit 3b4dd5e
Show file tree
Hide file tree
Showing 9 changed files with 1,592 additions and 403 deletions.
1,338 changes: 1,099 additions & 239 deletions .npm/package/npm-shrinkwrap.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions .versions
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
- [Why this package?](https://github.com/VeliovGroup/Meteor-Files#why-meteor-files)
- [Installation](https://github.com/VeliovGroup/Meteor-Files#installation)
- [ES6 Import](https://github.com/VeliovGroup/Meteor-Files#es6-import)
- [TypeScript Definitions](https://github.com/VeliovGroup/Meteor-Files/wiki/TypeScript-definitions)
- [TypeScript Definitions](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/typescript-definitions.md)
- [FAQ](https://github.com/VeliovGroup/Meteor-Files#faq)
- [API](https://github.com/VeliovGroup/Meteor-Files#api-overview-full-api):
- [Initialize Collection](https://github.com/VeliovGroup/Meteor-Files#new-filescollectionconfig-isomorphic)
Expand Down Expand Up @@ -109,6 +109,8 @@ import { FilesCollection } from 'meteor/ostrio:files';
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` upload streams are hard-coded to `1` and chunk size is reduced by algorithm, due to error thrown if too many connection is open by the browser or 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

## API overview (*[full API](https://github.com/VeliovGroup/Meteor-Files/wiki)*)

Expand Down
68 changes: 67 additions & 1 deletion docs/custom-response-headers.md
Original file line number Diff line number Diff line change
@@ -1 +1,67 @@
Please refer to [`docs/custom-response-headers.md`](https://github.com/VeliovGroup/Meteor-Files/blob/master/docs/custom-response-headers.md).
# Custom Response Headers

- `config.responseHeaders` option (*passed into [`FilesCollection` Constructor](https://github.com/VeliovGroup/Meteor-Files/wiki/Constructor)*)

*Allows to change default response headers.*

## Default function:

We recommend to keep original function structure, with your modifications

```js
function responseHeaders (responseCode, fileRef, versionRef) {
const headers = {};
switch (responseCode) {
case '206':
headers['Pragma'] = 'private';
headers['Transfer-Encoding'] = 'chunked';
break;
case '400':
headers['Cache-Control'] = 'no-cache';
break;
case '416':
headers['Content-Range'] = 'bytes */' + versionRef.size;
}
headers['Connection'] = 'keep-alive';
headers['Content-Type'] = versionRef.type || 'application/octet-stream';
headers['Accept-Ranges'] = 'bytes';
return headers;
}
```

## Adding custom header example:

We recommend to pass `responseHeaders` as a <em>Function</em>, response headers __should be conditional__.

```js
// As function (keep original function with additions):
const Uploads = new FilesCollection({
responseHeaders(responseCode, fileRef, versionRef, version, http) {
const headers = {};
switch (responseCode) {
case '206':
headers['Pragma'] = 'private';
headers['Transfer-Encoding'] = 'chunked';
break;
case '400':
headers['Cache-Control'] = 'no-cache';
break;
case '416':
headers['Content-Range'] = 'bytes */' + versionRef.size;
}
headers['Connection'] = 'keep-alive';
headers['Content-Type'] = versionRef.type || 'application/octet-stream';
headers['Accept-Ranges'] = 'bytes';
headers['Access-Control-Allow-Origin'] = '*';// <-- Custom header
return headers;
}
});

// As object (not recommended):
const Uploads = new FilesCollection({
responseHeaders: {
Connection: 'keep-alive',
'Access-Control-Allow-Origin': '*'
}
});
```
184 changes: 92 additions & 92 deletions docs/toc.md

Large diffs are not rendered by default.

154 changes: 102 additions & 52 deletions docs/typescript-definitions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,22 @@

```ts
declare module "meteor/ostrio:files" {

import { Mongo } from 'meteor/mongo';
import { ReactiveVar } from 'meteor/reactive-var';
import { SimpleSchemaDefinition } from 'simpl-schema';


interface Version<MetadataType> {
extension: string;
meta: MetadataType;
path: string;
size: number;
type: string;
}


class FileObj {
class FileObj<MetadataType> {
_id: string;
size: number;
name: string;
type: string;
Expand All @@ -17,92 +28,112 @@ declare module "meteor/ostrio:files" {
isText: boolean;
isJSON: boolean;
isPDF: boolean;
ext?: string;
extension?: string;
extensionWithDot: string;
_storagePath: string;
_downloadRoute: string;
_collectionName: string;
public?: boolean;
meta?: Object;
meta?: MetadataType;
userId?: string;
updatedAt?: Date;
versions: Object;
versions: {
[propName: string]: Version<MetadataType>;
};
mime: string;
"mime-type": string;
}

type FileRef = any; // File record from Mongo DB... don't know the details yet

interface FileData {
type FileRef<MetadataType> = FileObj<MetadataType> & {
remove: (callback: (error: any) => void) => void;
link: (version?: string, location?: string) => string;
get: (property?: string) => FileObj<MetadataType> | any;
fetch: () => FileObj<MetadataType>[]
with: () => FileCursor<MetadataType>
}


interface FileData<MetadataType> {
size: number;
type: string;
mime: string;
"mime-type": string;
ext: string;
extension: string;
name: string;
meta: MetadataType;
}

interface FilesCollectionConfig {
storagePath?: string;
collection?: Mongo.Collection<any>;

interface FilesCollectionConfig<MetadataType> {
storagePath?: string | ((fileObj: FileObj<MetadataType>) => string);
collection?: Mongo.Collection<FileObj<MetadataType>>;
collectionName?: string;
continueUploadTTL?: string;
ddp?: Object;
cacheControl?: string;
responseHeaders?: { [x: string]: string } | ((responseCode?, fileRef?, versionRef?, version?) => { [x: string]: string });
responseHeaders?: { [x: string]: string } | ((responseCode?: string, fileRef?: FileRef<MetadataType>, versionRef?: Version<MetadataType>, version?: string) => { [x: string]: string });
throttle?: number | boolean;
downloadRoute?: string;
schema?: Object;
schema?: SimpleSchemaDefinition;
chunkSize?: number;
namingFunction?: () => string;
namingFunction?: (fileObj: FileObj<MetadataType>) => string;
permissions?: number;
parentDirPermissions?: number;
integrityCheck?: boolean;
strict?: boolean;
downloadCallback?: (fileObj: FileObj) => boolean;
protected?: boolean | ((fileObj: FileObj) => boolean | number);
downloadCallback?: (fileObj: FileObj<MetadataType>) => boolean;
protected?: boolean | ((fileObj: FileObj<MetadataType>) => boolean | number);
public?: boolean;
onBeforeUpload?: (fileData: FileData) => boolean | string;
onBeforeRemove?: (cursor: Mongo.Cursor<any>) => boolean;
onInitiateUpload?: (fileData: FileData) => void;
onAfterUpload?: (fileRef: FileRef) => any;
onAfterRemove?: (files: Object[]) => any;
onBeforeUpload?: (fileData: FileData<MetadataType>) => boolean | string;
onBeforeRemove?: (cursor: Mongo.Cursor<FileObj<MetadataType>>) => boolean;
onInitiateUpload?: (fileData: FileData<MetadataType>) => void;
onAfterUpload?: (fileRef: FileRef<MetadataType>) => any;
onAfterRemove?: (files: FileObj<MetadataType>[]) => any;
onbeforeunloadMessage?: string | (() => string);
allowClientCode?: boolean;
debug?: boolean;
interceptDownload?: (http: any, fileRef: any, version: string) => boolean;
interceptDownload?: (http: Object, fileRef: FileRef<MetadataType>, version: string) => boolean;
}


export interface SearchOptions {
export interface SearchOptions<MetadataType, TransformedType> {
sort?: Mongo.SortSpecifier;
skip?: number;
limit?: number;
fields?: Mongo.FieldSpecifier;
reactive?: boolean;
transform?: Function;
transform?: (fileObj: FileObj<MetadataType>) => FileObj<TransformedType>;
}


export interface InsertOptions {
export interface InsertOptions<MetadataType> {
file: File | Object | string;
isBase64?: boolean;
meta?: { [x: string]: any };
meta?: MetadataType;
transport?: 'ddp' | 'http'
onStart?: (error: Object, fileData: Object) => any;
onUploaded?: (error: Object, fileData: Object) => any;
onAbort?: (fileData: Object) => any;
onError?: (error: Object, fileData: Object) => any;
onProgress?: (progress: number, fileData: Object) => any;
onBeforeUpload?: (fileData: Object) => any;
onStart?: (error: Object, fileData: FileData<MetadataType>) => any;
onUploaded?: (error: Object, fileRef: FileRef<MetadataType>) => any;
onAbort?: (fileData: FileData<MetadataType>) => any;
onError?: (error: Object, fileData: FileData<MetadataType>) => any;
onProgress?: (progress: number, fileData: FileData<MetadataType>) => any;
onBeforeUpload?: (fileData: FileData<MetadataType>) => any;
streams?: number | 'dynamic';
chunkSize?: number | 'dynamic';
allowWebWorkers?: boolean;
}

export interface LoadOptions {

export interface LoadOptions<MetadataType> {
fileName: string;
meta?: Object;
meta?: MetadataType;
type?: string;
size?: number;
}


export class FileUpload {
file: File;
onPause: ReactiveVar<boolean>;
Expand All @@ -119,16 +150,18 @@ declare module "meteor/ostrio:files" {
on(event: string, callback: Function): void;
}

export class FileCursor extends FileObj { // Is it correct to say that it extends FileObj?

export class FileCursor<MetadataType> extends FileObj<MetadataType> { // Is it correct to say that it extends FileObj?
remove(callback: (err) => void): void;
link(): string;
get(property: string): Object | any;
fetch(): Object[];
with(): ReactiveVar<FileCursor>;
with(): ReactiveVar<FileCursor<MetadataType>>;
}

export class FilesCursor extends Mongo.Cursor<FileObj> {
cursor: Mongo.Cursor<FileObj>; // Refers to base cursor? Why is this existing?

export class FilesCursor<MetadataType> extends Mongo.Cursor<FileObj<MetadataType>> {
cursor: Mongo.Cursor<FileObj<MetadataType>>; // Refers to base cursor? Why is this existing?

get(): Object[];
hasNext(): boolean;
Expand All @@ -138,29 +171,46 @@ declare module "meteor/ostrio:files" {
first(): Object;
last(): Object;
remove(callback: (err) => void): void;
each(): FileCursor[];
each(): FileCursor<MetadataType>[];
current(): Object | undefined;
}

export class FilesCollection {
collection: Mongo.Collection<FileObj>;
schema: any;

constructor(config: FilesCollectionConfig)

find(selector?: Mongo.Selector, options?: SearchOptions): FilesCursor;
findOne(selector?: Mongo.Selector, options?: SearchOptions): FileCursor;
insert(settings: InsertOptions, autoStart?: boolean): FileUpload;
remove(select: Mongo.Selector, callback: (error) => any): FilesCollection;
link(fileRef: FileRef, version?: string): string;
export class FilesCollection<MetadataType = { [x: string]: any }> {
collection: Mongo.Collection<FileObj<MetadataType>>;
schema: SimpleSchemaDefinition;

constructor(config: FilesCollectionConfig<MetadataType>)

/**
* Find and return Cursor for matching documents.
*
* @param selector [[http://docs.meteor.com/api/collections.html#selectors | Mongo-Style selector]]
* @param options [[http://docs.meteor.com/api/collections.html#sortspecifiers | Mongo-Style selector Options]]
* @typeParam TransformedType The result of transforming a document with options.tranform().
*/
find<TransformedType = FileRef<MetadataType>>(selector?: Mongo.Selector<Partial<FileObj<MetadataType>>>, options?: SearchOptions<MetadataType, TransformedType>): FilesCursor<TransformedType>;
/**
* Finds the first document that matches the selector, as ordered by sort and skip options.
*
* @param selector [[http://docs.meteor.com/api/collections.html#selectors | Mongo-Style selector]]
* @param options [[http://docs.meteor.com/api/collections.html#sortspecifiers | Mongo-Style selector Options]]
* @typeParam TransformedType The result of transforming a document with options.tranform().
*/
findOne<TransformedType = FileRef<MetadataType>>(selector?: Mongo.Selector<Partial<FileObj<MetadataType>>> | string, options?: SearchOptions<MetadataType, TransformedType>): FileCursor<TransformedType>;
insert(settings: InsertOptions<MetadataType>, autoStart?: boolean): FileUpload;
remove(select: Mongo.Selector<FileObj<MetadataType>> | string, callback?: (error: Object) => Object): FilesCollection<MetadataType>;
link(fileRef: FileRef<MetadataType>, version?: string): string;
allow(options: Mongo.AllowDenyOptions): void;
deny(options: Mongo.AllowDenyOptions): void;
denyClient(): void;
on(event: string, callback: (fileRef: FileRef) => void): void;
unlink(fileRef: FileRef, version?: string): FilesCollection;
addFile(path: string, opts: LoadOptions, callback: (err: any, fileRef: FileRef) => any, proceedAfterUpload: boolean);
load(url: string, opts: LoadOptions, callback: (err: any, fileRef: FileRef) => any, proceedAfterUpload: boolean);
write(buffer: Buffer, opts: LoadOptions, callback: (err: any, fileRef: FileRef) => any, proceedAfterUpload: boolean);
on(event: string, callback: (fileRef: FileRef<MetadataType>) => void): void;
unlink(fileRef: FileRef<MetadataType>, version?: string): FilesCollection<MetadataType>;
addFile(path: string, opts: LoadOptions<MetadataType>, callback: (err: any, fileRef: FileRef<MetadataType>) => any, proceedAfterUpload: boolean): FilesCollection<MetadataType>;
load(url: string, opts: LoadOptions<MetadataType>, callback: (err: Object, fileRef: FileRef<MetadataType>) => any, proceedAfterUpload: boolean): FilesCollection<MetadataType>;
write(buffer: Buffer, opts: LoadOptions<MetadataType>, callback: (err: Object, fileRef: FileRef<MetadataType>) => any, proceedAfterUpload: boolean): FilesCollection<MetadataType>;
}
}
```
Loading

0 comments on commit 3b4dd5e

Please sign in to comment.