Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v1.14.2 #744

Merged
merged 10 commits into from
May 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ geojson-utils@1.0.10
http@1.4.2
id-map@1.1.0
inter-process-messaging@0.1.1
local-test:ostrio:files@1.14.1
local-test:ostrio:files@1.14.2
logging@1.1.20
meteor@1.9.3
minimongo@1.6.0
Expand All @@ -36,7 +36,7 @@ mongo-id@1.0.7
npm-mongo@3.7.0
ordered-dict@1.1.0
ostrio:cookies@2.6.0
ostrio:files@1.14.1
ostrio:files@1.14.2
promise@0.11.2
random@1.2.0
reactive-var@1.0.11
Expand Down
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