Browse Source

Merge branch 'master' into feature/tl-preset

Renée Kooi 6 years ago
parent
commit
5800fe9ed6
56 changed files with 603 additions and 398 deletions
  1. 6 0
      bin/endtoend-build-tests
  2. 61 16
      package-lock.json
  3. 1 0
      package.json
  4. 10 10
      packages/@uppy/aws-s3-multipart/types/index.d.ts
  5. 6 6
      packages/@uppy/aws-s3/types/index.d.ts
  6. 4 4
      packages/@uppy/companion-client/types/index.d.ts
  7. 1 1
      packages/@uppy/companion/package.json
  8. 3 1
      packages/@uppy/companion/src/server/provider/instagram/adapter.js
  9. 1 1
      packages/@uppy/core/types/core-tests.ts
  10. 156 152
      packages/@uppy/core/types/index.d.ts
  11. 1 1
      packages/@uppy/dashboard/src/index.js
  12. 6 6
      packages/@uppy/dashboard/types/index.d.ts
  13. 5 5
      packages/@uppy/drag-drop/types/index.d.ts
  14. 6 6
      packages/@uppy/dropbox/types/index.d.ts
  15. 5 5
      packages/@uppy/file-input/types/index.d.ts
  16. 5 5
      packages/@uppy/form/types/index.d.ts
  17. 5 5
      packages/@uppy/golden-retriever/types/index.d.ts
  18. 6 6
      packages/@uppy/google-drive/types/index.d.ts
  19. 5 5
      packages/@uppy/informer/types/index.d.ts
  20. 6 6
      packages/@uppy/instagram/types/index.d.ts
  21. 5 5
      packages/@uppy/progress-bar/types/index.d.ts
  22. 3 5
      packages/@uppy/react/src/CommonTypes.d.ts
  23. 19 19
      packages/@uppy/react/src/Dashboard.d.ts
  24. 5 5
      packages/@uppy/react/src/DashboardModal.d.ts
  25. 2 2
      packages/@uppy/react/src/DragDrop.d.ts
  26. 3 3
      packages/@uppy/react/src/ProgressBar.d.ts
  27. 3 3
      packages/@uppy/react/src/StatusBar.d.ts
  28. 5 5
      packages/@uppy/redux-dev-tools/types/index.d.ts
  29. 5 5
      packages/@uppy/status-bar/types/index.d.ts
  30. 3 3
      packages/@uppy/store-default/types/index.d.ts
  31. 9 0
      packages/@uppy/store-default/types/store-default-tests.ts
  32. 19 21
      packages/@uppy/store-redux/types/index.d.ts
  33. 13 0
      packages/@uppy/store-redux/types/store-redux-tests.ts
  34. 5 5
      packages/@uppy/thumbnail-generator/types/index.d.ts
  35. 6 6
      packages/@uppy/transloadit/types/index.d.ts
  36. 5 5
      packages/@uppy/tus/types/index.d.ts
  37. 5 5
      packages/@uppy/url/types/index.d.ts
  38. 6 6
      packages/@uppy/utils/types/index.d.ts
  39. 14 15
      packages/@uppy/webcam/types/index.d.ts
  40. 8 0
      packages/@uppy/webcam/types/webcam-tests.ts
  41. 12 10
      packages/@uppy/xhr-upload/src/index.js
  42. 14 14
      packages/@uppy/xhr-upload/types/index.d.ts
  43. 9 0
      packages/@uppy/xhr-upload/types/xhr-upload-tests.ts
  44. 29 0
      test/endtoend/typescript/index.html
  45. 50 0
      test/endtoend/typescript/main.ts
  46. 18 0
      test/endtoend/typescript/test.js
  47. 2 2
      test/endtoend/wdio.base.conf.js
  48. 1 1
      tsconfig.json
  49. 10 10
      website/src/_posts/2018-12-0.29.md
  50. 5 1
      website/src/docs/aws-s3.md
  51. 1 1
      website/src/docs/tus.md
  52. 2 0
      website/src/examples/dashboard/app.es6
  53. 2 0
      website/src/examples/dragdrop/app.es6
  54. 2 0
      website/src/examples/statusbar/app.es6
  55. 2 0
      website/src/examples/transloadit/app.es6
  56. 2 0
      website/src/examples/xhrupload/app.es6

+ 6 - 0
bin/endtoend-build-tests

@@ -28,3 +28,9 @@ pushd "${__root}/test/endtoend/create-react-app"
   npm install
   npm run build
 popd
+pushd "${__root}/test/endtoend/typescript"
+  mkdir -p dist
+  cp "${__root}/packages/uppy/dist/uppy.min.css" dist/
+  cp index.html dist/
+  browserify main.ts -p [ tsify --target ES3 ] -o dist/bundle.js
+popd

+ 61 - 16
package-lock.json

@@ -2099,6 +2099,12 @@
 			"integrity": "sha1-xnhwBYADV5AJCD9UrAq6+1wz0kI=",
 			"dev": true
 		},
+		"any-promise": {
+			"version": "1.3.0",
+			"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+			"integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=",
+			"dev": true
+		},
 		"anymatch": {
 			"version": "1.3.0",
 			"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.0.tgz",
@@ -2491,9 +2497,9 @@
 			}
 		},
 		"aws-sdk": {
-			"version": "2.387.0",
-			"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.387.0.tgz",
-			"integrity": "sha512-GSJwNBqdDDqRpTBNnSlAVeQ4wqIiWIhqsnvE0GcGmVQWDq7yM89EiYqkIcB8dFV/l6bm7f0TFDtEbIwoRP6C4w==",
+			"version": "2.389.0",
+			"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.389.0.tgz",
+			"integrity": "sha512-4KBH2o4f/ncTJfKzUsMNxxPNWkF7eFVZlYLRpeFAYEgw+r8xE//0YBReNnySS5Y5oQTOtg376bOlQSWtFhKv1g==",
 			"requires": {
 				"buffer": "4.9.1",
 				"events": "1.1.1",
@@ -2516,11 +2522,6 @@
 						"isarray": "^1.0.0"
 					}
 				},
-				"events": {
-					"version": "1.1.1",
-					"resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
-					"integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ="
-				},
 				"ieee754": {
 					"version": "1.1.8",
 					"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz",
@@ -4954,6 +4955,12 @@
 						"typedarray": "^0.0.6"
 					}
 				},
+				"events": {
+					"version": "2.1.0",
+					"resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz",
+					"integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==",
+					"dev": true
+				},
 				"safe-buffer": {
 					"version": "5.1.2",
 					"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
@@ -9290,10 +9297,9 @@
 			"dev": true
 		},
 		"events": {
-			"version": "2.1.0",
-			"resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz",
-			"integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==",
-			"dev": true
+			"version": "1.1.1",
+			"resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
+			"integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ="
 		},
 		"evp_bytestokey": {
 			"version": "1.0.3",
@@ -15353,13 +15359,13 @@
 			"dev": true
 		},
 		"morgan": {
-			"version": "1.9.0",
-			"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz",
-			"integrity": "sha1-0B+mxlhZt2/PMbPLU6OCGjEdgFE=",
+			"version": "1.9.1",
+			"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz",
+			"integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==",
 			"requires": {
 				"basic-auth": "~2.0.0",
 				"debug": "2.6.9",
-				"depd": "~1.1.1",
+				"depd": "~1.1.2",
 				"on-finished": "~2.3.0",
 				"on-headers": "~1.0.1"
 			}
@@ -15404,6 +15410,11 @@
 						"once": "^1.3.0",
 						"path-is-absolute": "^1.0.0"
 					}
+				},
+				"lodash": {
+					"version": "3.10.1",
+					"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+					"integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y="
 				}
 			}
 		},
@@ -22991,6 +23002,40 @@
 			"integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=",
 			"dev": true
 		},
+		"tsconfig": {
+			"version": "5.0.3",
+			"resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-5.0.3.tgz",
+			"integrity": "sha1-X0J45wGACWeo/Dg/0ZZIh48qbjo=",
+			"dev": true,
+			"requires": {
+				"any-promise": "^1.3.0",
+				"parse-json": "^2.2.0",
+				"strip-bom": "^2.0.0",
+				"strip-json-comments": "^2.0.0"
+			}
+		},
+		"tsify": {
+			"version": "4.0.1",
+			"resolved": "https://registry.npmjs.org/tsify/-/tsify-4.0.1.tgz",
+			"integrity": "sha512-ClznEI+pmwY5wmD0J7HCSVERwkD+l71ch3Dqyod2JuQLEsFaiNDI+vPjaGadsuVFVvmzgoI7HghrBtWsSmCDHQ==",
+			"dev": true,
+			"requires": {
+				"convert-source-map": "^1.1.0",
+				"fs.realpath": "^1.0.0",
+				"object-assign": "^4.1.0",
+				"semver": "^5.6.0",
+				"through2": "^2.0.0",
+				"tsconfig": "^5.0.3"
+			},
+			"dependencies": {
+				"semver": {
+					"version": "5.6.0",
+					"resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
+					"integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==",
+					"dev": true
+				}
+			}
+		},
 		"tslib": {
 			"version": "1.9.3",
 			"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",

+ 1 - 0
package.json

@@ -69,6 +69,7 @@
     "replace-x": "^1.5.0",
     "temp-write": "^3.4.0",
     "tinyify": "^2.4.3",
+    "tsify": "^4.0.1",
     "typescript": "^2.9.2",
     "verdaccio": "^3.8.5",
     "watchify": "^3.11.0",

+ 10 - 10
packages/@uppy/aws-s3-multipart/types/index.d.ts

@@ -1,4 +1,4 @@
-import { Plugin, PluginOptions, Uppy, UppyFile } from '@uppy/core';
+import Uppy = require('@uppy/core');
 
 declare module AwsS3Multipart {
   interface AwsS3Part {
@@ -7,26 +7,26 @@ declare module AwsS3Multipart {
     ETag?: string;
   }
 
-  interface AwsS3MultipartOptions extends PluginOptions {
+  interface AwsS3MultipartOptions extends Uppy.PluginOptions {
     serverUrl: string;
-    createMultipartUpload(file: UppyFile): Promise<{ uploadId: string, key: string }>;
-    listParts(file: UppyFile, opts: { uploadId: string, key: string }): Promise<AwsS3Part[]>;
-    prepareUploadPart(file: UppyFile, partData: { uploadId: string, key: string, body: Blob, number: number }): Promise<{ url: string }>;
-    abortMultipartUpload(file: UppyFile, opts: { uploadId: string, key: string }): Promise<void>;
-    completeMultipartUpload(file: UppyFile, opts: { uploadId: string, key: string, parts: AwsS3Part[] }): Promise<{ location?: string }>;
+    createMultipartUpload(file: Uppy.UppyFile): Promise<{ uploadId: string, key: string }>;
+    listParts(file: Uppy.UppyFile, opts: { uploadId: string, key: string }): Promise<AwsS3Part[]>;
+    prepareUploadPart(file: Uppy.UppyFile, partData: { uploadId: string, key: string, body: Blob, number: number }): Promise<{ url: string }>;
+    abortMultipartUpload(file: Uppy.UppyFile, opts: { uploadId: string, key: string }): Promise<void>;
+    completeMultipartUpload(file: Uppy.UppyFile, opts: { uploadId: string, key: string, parts: AwsS3Part[] }): Promise<{ location?: string }>;
     timeout: number;
     limit: number;
   }
 }
 
-declare class AwsS3Multipart extends Plugin {
-  constructor(uppy: Uppy, opts: Partial<AwsS3Multipart.AwsS3MultipartOptions>);
+declare class AwsS3Multipart extends Uppy.Plugin {
+  constructor(uppy: Uppy.Uppy, opts: Partial<AwsS3Multipart.AwsS3MultipartOptions>);
 }
 
 export = AwsS3Multipart;
 
 declare module '@uppy/core' {
   export interface Uppy {
-    use(pluginClass: typeof AwsS3Multipart, opts: Partial<AwsS3Multipart.AwsS3MultipartOptions>): Uppy;
+    use(pluginClass: typeof AwsS3Multipart, opts: Partial<AwsS3Multipart.AwsS3MultipartOptions>): Uppy.Uppy;
   }
 }

+ 6 - 6
packages/@uppy/aws-s3/types/index.d.ts

@@ -1,4 +1,4 @@
-import { Plugin, PluginOptions, Uppy, UppyFile } from '@uppy/core';
+import Uppy = require('@uppy/core');
 
 declare module AwsS3 {
   interface AwsS3UploadParameters {
@@ -8,22 +8,22 @@ declare module AwsS3 {
     headers?: { [type: string]: string };
   }
 
-  interface AwsS3Options extends PluginOptions {
+  interface AwsS3Options extends Uppy.PluginOptions {
     serverUrl: string;
-    getUploadParameters(file: UppyFile): Promise<AwsS3UploadParameters>;
+    getUploadParameters(file: Uppy.UppyFile): Promise<AwsS3UploadParameters>;
     timeout: number;
     limit: number;
   }
 }
 
-declare class AwsS3 extends Plugin {
-  constructor(uppy: Uppy, opts: Partial<AwsS3.AwsS3Options>);
+declare class AwsS3 extends Uppy.Plugin {
+  constructor(uppy: Uppy.Uppy, opts: Partial<AwsS3.AwsS3Options>);
 }
 
 export = AwsS3;
 
 declare module '@uppy/core' {
   export interface Uppy {
-    use(pluginClass: typeof AwsS3, opts: Partial<AwsS3.AwsS3Options>): Uppy;
+    use(pluginClass: typeof AwsS3, opts: Partial<AwsS3.AwsS3Options>): Uppy.Uppy;
   }
 }

+ 4 - 4
packages/@uppy/companion-client/types/index.d.ts

@@ -1,4 +1,4 @@
-import { Uppy, Plugin } from '@uppy/core';
+import Uppy = require('@uppy/core');
 
 export interface RequestClientOptions {
   serverUrl: string;
@@ -6,7 +6,7 @@ export interface RequestClientOptions {
 }
 
 export class RequestClient {
-  constructor (uppy: Uppy, opts: RequestClientOptions);
+  constructor (uppy: Uppy.Uppy, opts: RequestClientOptions);
   get (path: string): Promise<any>;
   post (path: string, data: object): Promise<any>;
   delete (path: string, data: object): Promise<any>;
@@ -19,13 +19,13 @@ export interface ProviderOptions extends RequestClientOptions {
 }
 
 export class Provider extends RequestClient {
-  constructor (uppy: Uppy, opts: ProviderOptions);
+  constructor (uppy: Uppy.Uppy, opts: ProviderOptions);
   checkAuth (): Promise<boolean>;
   authUrl (): string;
   fileUrl (id: string): string;
   list (directory: string): Promise<any>;
   logout (redirect?: string): Promise<any>;
-  static initPlugin(plugin: Plugin, opts: object, defaultOpts?: object): void;
+  static initPlugin(plugin: Uppy.Plugin, opts: object, defaultOpts?: object): void;
 }
 
 export interface SocketOptions {

+ 1 - 1
packages/@uppy/companion/package.json

@@ -46,7 +46,7 @@
     "isobject": "3.0.1",
     "jsonwebtoken": "^8.0.1",
     "lodash.merge": "^4.6.0",
-    "morgan": "1.9.0",
+    "morgan": "1.9.1",
     "ms": "^2.0.0",
     "node-redis-pubsub": "^2.0.0",
     "node-schedule": "^1.3.0",

+ 3 - 1
packages/@uppy/companion/src/server/provider/instagram/adapter.js

@@ -72,5 +72,7 @@ exports.getItemThumbnailUrl = (item) => {
 }
 
 exports.getNextPagePath = (items) => {
-  return `recent?max_id=${exports.getItemId(items[items.length - 1])}`
+  if (items.length) {
+    return `recent?max_id=${exports.getItemId(items[items.length - 1])}`
+  }
 }

+ 1 - 1
packages/@uppy/core/types/core-tests.ts

@@ -1,4 +1,4 @@
-import Uppy, { UppyFile } from '../';
+import Uppy = require('../');
 
 {
   const uppy = Uppy();

+ 156 - 152
packages/@uppy/core/types/index.d.ts

@@ -1,166 +1,170 @@
-interface IndexedObject<T> {
-  [key: string]: T;
-  [key: number]: T;
-}
-export interface UppyFile<TMeta extends IndexedObject<any> = {}> {
-  data: Blob | File;
-  extension: string;
-  id: string;
-  isPaused?: boolean;
-  isRemote: boolean;
-  meta: {
+declare module Uppy {
+  interface IndexedObject<T> {
+    [key: string]: T;
+    [key: number]: T;
+  }
+  interface UppyFile<TMeta extends IndexedObject<any> = {}> {
+    data: Blob | File;
+    extension: string;
+    id: string;
+    isPaused?: boolean;
+    isRemote: boolean;
+    meta: {
+      name: string;
+      type?: string;
+    } & TMeta;
     name: string;
+    preview?: string;
+    progress?: {
+      uploadStarted: number;
+      uploadComplete: boolean;
+      percentage: number;
+      bytesUploaded: number;
+      bytesTotal: number;
+    };
+    remote?: {
+      host: string;
+      url: string;
+      body?: object;
+    };
+    size: number;
+    source?: string;
     type?: string;
-  } & TMeta;
-  name: string;
-  preview?: string;
-  progress?: {
-    uploadStarted: number;
-    uploadComplete: boolean;
-    percentage: number;
-    bytesUploaded: number;
-    bytesTotal: number;
-  };
-  remote?: {
-    host: string;
-    url: string;
-    body?: object;
-  };
-  size: number;
-  source?: string;
-  type?: string;
-}
+  }
 
-export interface UploadedUppyFile<TMeta extends IndexedObject<any> = {}> extends UppyFile<TMeta> {
-  uploadURL: string;
-}
+  interface UploadedUppyFile<TMeta extends IndexedObject<any> = {}> extends UppyFile<TMeta> {
+    uploadURL: string;
+  }
 
-export interface FailedUppyFile<TMeta extends IndexedObject<any> = {}> extends UppyFile<TMeta> {
-  error: string;
-}
+  interface FailedUppyFile<TMeta extends IndexedObject<any> = {}> extends UppyFile<TMeta> {
+    error: string;
+  }
 
-export interface AddFileOptions extends Partial<UppyFile> {
-  // `.data` is the only required property here.
-  data: Blob | File;
-}
+  interface AddFileOptions extends Partial<UppyFile> {
+    // `.data` is the only required property here.
+    data: Blob | File;
+  }
 
-export interface PluginOptions {
-  id?: string;
-}
+  interface PluginOptions {
+    id?: string;
+  }
 
-export class Plugin {
-  id: string;
-  uppy: Uppy;
-  type: string;
-  constructor(uppy: Uppy, opts?: PluginOptions);
-  getPluginState(): object;
-  setPluginState(update: any): object;
-  update(state?: object): void;
-  mount(target: any, plugin: any): void;
-  render(state: object): void;
-  addTarget(plugin: any): void;
-  unmount(): void;
-  install(): void;
-  uninstall(): void;
-}
+  class Plugin {
+    id: string;
+    uppy: Uppy;
+    type: string;
+    constructor(uppy: Uppy, opts?: PluginOptions);
+    getPluginState(): object;
+    setPluginState(update: any): object;
+    update(state?: object): void;
+    mount(target: any, plugin: any): void;
+    render(state: object): void;
+    addTarget(plugin: any): void;
+    unmount(): void;
+    install(): void;
+    uninstall(): void;
+  }
 
-export interface Store {
-  getState(): object;
-  setState(patch: object): void;
-  subscribe(listener: any): () => void;
-}
+  interface Store {
+    getState(): object;
+    setState(patch: object): void;
+    subscribe(listener: any): () => void;
+  }
 
-interface LocaleStrings {
-  [key: string]: string | LocaleStrings;
-}
-interface Locale {
-  strings: LocaleStrings;
-  pluralize?: (n: number) => number;
-}
+  interface LocaleStrings {
+    [key: string]: string | LocaleStrings;
+  }
+  interface Locale {
+    strings: LocaleStrings;
+    pluralize?: (n: number) => number;
+  }
 
-export interface UppyOptions {
-  id: string;
-  autoProceed: boolean;
-  allowMultipleUploads: boolean;
-  debug: boolean;
-  restrictions: {
-    maxFileSize: number | null;
-    maxNumberOfFiles: number | null;
-    minNumberOfFiles: number | null;
-    allowedFileTypes: string[] | null;
-  };
-  target: string | Plugin;
-  meta: any;
-  onBeforeFileAdded: (currentFile: UppyFile, files: {[key: string]: UppyFile}) => UppyFile | boolean | undefined;
-  onBeforeUpload: (files: {[key: string]: UppyFile}) => {[key: string]: UppyFile} | boolean;
-  locale: Locale;
-  store: Store;
-}
+  interface UppyOptions {
+    id: string;
+    autoProceed: boolean;
+    allowMultipleUploads: boolean;
+    debug: boolean;
+    restrictions: {
+      maxFileSize: number | null;
+      maxNumberOfFiles: number | null;
+      minNumberOfFiles: number | null;
+      allowedFileTypes: string[] | null;
+    };
+    target: string | Plugin;
+    meta: any;
+    onBeforeFileAdded: (currentFile: UppyFile, files: {[key: string]: UppyFile}) => UppyFile | boolean | undefined;
+    onBeforeUpload: (files: {[key: string]: UppyFile}) => {[key: string]: UppyFile} | boolean;
+    locale: Locale;
+    store: Store;
+  }
 
-export interface UploadResult<TMeta extends IndexedObject<any> = {}> {
-  successful: UploadedUppyFile<TMeta>[];
-  failed: FailedUppyFile<TMeta>[];
-}
+  interface UploadResult<TMeta extends IndexedObject<any> = {}> {
+    successful: UploadedUppyFile<TMeta>[];
+    failed: FailedUppyFile<TMeta>[];
+  }
 
-interface State<TMeta extends IndexedObject<any> = {}> extends IndexedObject<any> {
-  capabilities?: {resumableUploads?: boolean};
-  currentUploads: {};
-  error?: string;
-  files: {[key: string]: UploadedUppyFile<TMeta> | FailedUppyFile<TMeta>};
-  info?: {
-    isHidden: boolean;
-    type: string;
-    message: string;
-    details: string;
-  };
-  plugins?: IndexedObject<any>;
-  totalProgress: number;
-}
-type LogLevel = 'info' | 'warning' | 'error';
-export class Uppy {
-  constructor(opts?: Partial<UppyOptions>);
-  on(event: 'upload-success', callback: (file: UppyFile, body: any, uploadURL: string) => void): Uppy;
-  on(event: 'complete', callback: (result: UploadResult) => void): Uppy;
-  on(event: string, callback: (...args: any[]) => void): Uppy;
-  off(event: string, callback: any): Uppy;
-  updateAll(state: object): void;
-  setState(patch: object): void;
-  getState<TMeta extends IndexedObject<any> = {}>(): State<TMeta>;
-  readonly state: State;
-  setFileState(fileID: string, state: object): void;
-  resetProgress(): void;
-  addPreProcessor(fn: any): void;
-  removePreProcessor(fn: any): void;
-  addPostProcessor(fn: any): void;
-  removePostProcessor(fn: any): void;
-  addUploader(fn: any): void;
-  removeUploader(fn: any): void;
-  setMeta(data: any): void;
-  setFileMeta(fileID: string, data: object): void;
-  getFile<TMeta extends IndexedObject<any> = {}>(fileID: string): UppyFile<TMeta>;
-  getFiles<TMeta extends IndexedObject<any> = {}>(): Array<UppyFile<TMeta>>;
-  addFile(file: AddFileOptions): void;
-  removeFile(fileID: string): void;
-  pauseResume(fileID: string): boolean;
-  pauseAll(): void;
-  resumeAll(): void;
-  retryAll(): void;
-  cancelAll(): void;
-  retryUpload(fileID: string): any;
-  reset(): void;
-  getID(): string;
-  use<T extends typeof Plugin>(pluginClass: T, opts: object): Uppy;
-  getPlugin(name: string): Plugin;
-  iteratePlugins(callback: (plugin: Plugin) => void): void;
-  removePlugin(instance: Plugin): void;
-  close(): void;
-  info(message: string | {message: string; details: string}, type?: LogLevel, duration?: number): void;
-  hideInfo(): void;
-  log(msg: string, type?: LogLevel): void;
-  run(): Uppy;
-  restore(uploadID: string): Promise<UploadResult>;
-  addResultData(uploadID: string, data: object): void;
-  upload(): Promise<UploadResult>;
+  interface State<TMeta extends IndexedObject<any> = {}> extends IndexedObject<any> {
+    capabilities?: {resumableUploads?: boolean};
+    currentUploads: {};
+    error?: string;
+    files: {[key: string]: UploadedUppyFile<TMeta> | FailedUppyFile<TMeta>};
+    info?: {
+      isHidden: boolean;
+      type: string;
+      message: string;
+      details: string;
+    };
+    plugins?: IndexedObject<any>;
+    totalProgress: number;
+  }
+  type LogLevel = 'info' | 'warning' | 'error';
+  class Uppy {
+    constructor(opts?: Partial<UppyOptions>);
+    on(event: 'upload-success', callback: (file: UppyFile, body: any, uploadURL: string) => void): Uppy;
+    on(event: 'complete', callback: (result: UploadResult) => void): Uppy;
+    on(event: string, callback: (...args: any[]) => void): Uppy;
+    off(event: string, callback: any): Uppy;
+    updateAll(state: object): void;
+    setState(patch: object): void;
+    getState<TMeta extends IndexedObject<any> = {}>(): State<TMeta>;
+    readonly state: State;
+    setFileState(fileID: string, state: object): void;
+    resetProgress(): void;
+    addPreProcessor(fn: any): void;
+    removePreProcessor(fn: any): void;
+    addPostProcessor(fn: any): void;
+    removePostProcessor(fn: any): void;
+    addUploader(fn: any): void;
+    removeUploader(fn: any): void;
+    setMeta(data: any): void;
+    setFileMeta(fileID: string, data: object): void;
+    getFile<TMeta extends IndexedObject<any> = {}>(fileID: string): UppyFile<TMeta>;
+    getFiles<TMeta extends IndexedObject<any> = {}>(): Array<UppyFile<TMeta>>;
+    addFile(file: AddFileOptions): void;
+    removeFile(fileID: string): void;
+    pauseResume(fileID: string): boolean;
+    pauseAll(): void;
+    resumeAll(): void;
+    retryAll(): void;
+    cancelAll(): void;
+    retryUpload(fileID: string): any;
+    reset(): void;
+    getID(): string;
+    use<T extends typeof Plugin>(pluginClass: T, opts: object): Uppy;
+    getPlugin(name: string): Plugin;
+    iteratePlugins(callback: (plugin: Plugin) => void): void;
+    removePlugin(instance: Plugin): void;
+    close(): void;
+    info(message: string | {message: string; details: string}, type?: LogLevel, duration?: number): void;
+    hideInfo(): void;
+    log(msg: string, type?: LogLevel): void;
+    run(): Uppy;
+    restore(uploadID: string): Promise<UploadResult>;
+    addResultData(uploadID: string, data: object): void;
+    upload(): Promise<UploadResult>;
+  }
 }
 
-export default function createUppy(opts?: Partial<UppyOptions>): Uppy;
+declare function Uppy(opts?: Partial<Uppy.UppyOptions>): Uppy.Uppy;
+
+export = Uppy;

+ 1 - 1
packages/@uppy/dashboard/src/index.js

@@ -461,7 +461,7 @@ module.exports = class Dashboard extends Plugin {
     }
 
     if (!this.opts.inline && !showModalTrigger) {
-      this.uppy.log('Dashboard modal trigger not found. Make sure `trigger` is set in Dashboard options unless you are planning to call openModal() method yourself')
+      this.uppy.log('Dashboard modal trigger not found. Make sure `trigger` is set in Dashboard options unless you are planning to call openModal() method yourself', 'error')
     }
 
     // Drag Drop

+ 6 - 6
packages/@uppy/dashboard/types/index.d.ts

@@ -1,7 +1,7 @@
-import { Plugin, PluginOptions, Uppy } from '@uppy/core';
+import Uppy = require('@uppy/core');
 
 declare module Dashboard {
-  interface DashboardOptions extends PluginOptions {
+  interface DashboardOptions extends Uppy.PluginOptions {
     onRequestCloseModal: () => void;
     disablePageScrollWhenModalOpen: boolean;
     closeModalOnClickOutside: boolean;
@@ -24,9 +24,9 @@ declare module Dashboard {
   }
 }
 
-declare class Dashboard extends Plugin {
-  constructor(uppy: Uppy, opts: Partial<Dashboard.DashboardOptions>);
-  addTarget(plugin: Plugin): HTMLElement;
+declare class Dashboard extends Uppy.Plugin {
+  constructor(uppy: Uppy.Uppy, opts: Partial<Dashboard.DashboardOptions>);
+  addTarget(plugin: Uppy.Plugin): HTMLElement;
   hideAllPanels(): void;
   openModal(): void;
   closeModal(): void;
@@ -40,6 +40,6 @@ export = Dashboard;
 
 declare module '@uppy/core' {
   export interface Uppy {
-    use(pluginClass: typeof Dashboard, opts: Partial<Dashboard.DashboardOptions>): Uppy;
+    use(pluginClass: typeof Dashboard, opts: Partial<Dashboard.DashboardOptions>): Uppy.Uppy;
   }
 }

+ 5 - 5
packages/@uppy/drag-drop/types/index.d.ts

@@ -1,7 +1,7 @@
-import { Plugin, PluginOptions, Uppy } from '@uppy/core';
+import Uppy = require('@uppy/core');
 
 declare module DragDrop {
-  interface DragDropOptions extends PluginOptions {
+  interface DragDropOptions extends Uppy.PluginOptions {
     inputName: string;
     allowMultipleFiles: boolean;
     width: string;
@@ -10,14 +10,14 @@ declare module DragDrop {
   }
 }
 
-declare class DragDrop extends Plugin {
-  constructor(uppy: Uppy, opts: Partial<DragDrop.DragDropOptions>);
+declare class DragDrop extends Uppy.Plugin {
+  constructor(uppy: Uppy.Uppy, opts: Partial<DragDrop.DragDropOptions>);
 }
 
 export = DragDrop;
 
 declare module '@uppy/core' {
   export interface Uppy {
-    use(pluginClass: typeof DragDrop, opts: Partial<DragDrop.DragDropOptions>): Uppy;
+    use(pluginClass: typeof DragDrop, opts: Partial<DragDrop.DragDropOptions>): Uppy.Uppy;
   }
 }

+ 6 - 6
packages/@uppy/dropbox/types/index.d.ts

@@ -1,21 +1,21 @@
-import { Plugin, PluginOptions, Uppy } from '@uppy/core';
-import { ProviderOptions } from '@uppy/companion-client';
+import Uppy = require('@uppy/core');
+import CompanionClient = require('@uppy/companion-client');
 
 declare module Dropbox {
-  interface DropboxOptions extends PluginOptions, ProviderOptions {
+  interface DropboxOptions extends Uppy.PluginOptions, CompanionClient.ProviderOptions {
     serverUrl: string;
     serverPattern: string | RegExp | Array<string | RegExp>;
   }
 }
 
-declare class Dropbox extends Plugin {
-  constructor(uppy: Uppy, opts: Partial<Dropbox.DropboxOptions>);
+declare class Dropbox extends Uppy.Plugin {
+  constructor(uppy: Uppy.Uppy, opts: Partial<Dropbox.DropboxOptions>);
 }
 
 export = Dropbox;
 
 declare module '@uppy/core' {
   export interface Uppy {
-    use(pluginClass: typeof Dropbox, opts: Partial<Dropbox.DropboxOptions>): Uppy;
+    use(pluginClass: typeof Dropbox, opts: Partial<Dropbox.DropboxOptions>): Uppy.Uppy;
   }
 }

+ 5 - 5
packages/@uppy/file-input/types/index.d.ts

@@ -1,20 +1,20 @@
-import { Plugin, PluginOptions, Uppy } from '@uppy/core';
+import Uppy = require('@uppy/core');
 
 declare module FileInput {
-  interface FileInputOptions extends PluginOptions {
+  interface FileInputOptions extends Uppy.PluginOptions {
     pretty: boolean;
     inputName: string;
   }
 }
 
-declare class FileInput extends Plugin {
-  constructor(uppy: Uppy, opts: Partial<FileInput.FileInputOptions>);
+declare class FileInput extends Uppy.Plugin {
+  constructor(uppy: Uppy.Uppy, opts: Partial<FileInput.FileInputOptions>);
 }
 
 export = FileInput;
 
 declare module '@uppy/core' {
   export interface Uppy {
-    use(pluginClass: typeof FileInput, opts: Partial<FileInput.FileInputOptions>): Uppy;
+    use(pluginClass: typeof FileInput, opts: Partial<FileInput.FileInputOptions>): Uppy.Uppy;
   }
 }

+ 5 - 5
packages/@uppy/form/types/index.d.ts

@@ -1,7 +1,7 @@
-import { Plugin, PluginOptions, Uppy } from '@uppy/core';
+import Uppy = require('@uppy/core');
 
 declare module Form {
-  interface FormOptions extends PluginOptions {
+  interface FormOptions extends Uppy.PluginOptions {
     getMetaFromForm: boolean;
     addResultToForm: boolean;
     submitOnSuccess: boolean;
@@ -10,14 +10,14 @@ declare module Form {
   }
 }
 
-declare class Form extends Plugin {
-  constructor(uppy: Uppy, opts: Partial<Form.FormOptions>);
+declare class Form extends Uppy.Plugin {
+  constructor(uppy: Uppy.Uppy, opts: Partial<Form.FormOptions>);
 }
 
 export = Form;
 
 declare module '@uppy/core' {
   export interface Uppy {
-    use(pluginClass: typeof Form, opts: Partial<Form.FormOptions>): Uppy;
+    use(pluginClass: typeof Form, opts: Partial<Form.FormOptions>): Uppy.Uppy;
   }
 }

+ 5 - 5
packages/@uppy/golden-retriever/types/index.d.ts

@@ -1,21 +1,21 @@
-import { Plugin, PluginOptions, Uppy } from '@uppy/core';
+import Uppy = require('@uppy/core');
 
 declare module GoldenRetriever {
-  interface GoldenRetrieverOptions extends PluginOptions {
+  interface GoldenRetrieverOptions extends Uppy.PluginOptions {
     expires: number;
     serviceWorker: boolean;
     indexedDB: any;
   }
 }
 
-declare class GoldenRetriever extends Plugin {
-  constructor(uppy: Uppy, opts: Partial<GoldenRetriever.GoldenRetrieverOptions>);
+declare class GoldenRetriever extends Uppy.Plugin {
+  constructor(uppy: Uppy.Uppy, opts: Partial<GoldenRetriever.GoldenRetrieverOptions>);
 }
 
 export = GoldenRetriever;
 
 declare module '@uppy/core' {
   export interface Uppy {
-    use(pluginClass: typeof GoldenRetriever, opts: Partial<GoldenRetriever.GoldenRetrieverOptions>): Uppy;
+    use(pluginClass: typeof GoldenRetriever, opts: Partial<GoldenRetriever.GoldenRetrieverOptions>): Uppy.Uppy;
   }
 }

+ 6 - 6
packages/@uppy/google-drive/types/index.d.ts

@@ -1,21 +1,21 @@
-import { Plugin, PluginOptions, Uppy } from '@uppy/core';
-import { ProviderOptions } from '@uppy/companion-client';
+import Uppy = require('@uppy/core');
+import CompanionClient = require('@uppy/companion-client');
 
 declare module GoogleDrive {
-  interface GoogleDriveOptions extends PluginOptions, ProviderOptions {
+  interface GoogleDriveOptions extends Uppy.PluginOptions, CompanionClient.ProviderOptions {
     serverUrl: string;
     serverPattern: string | RegExp | Array<string | RegExp>;
   }
 }
 
-declare class GoogleDrive extends Plugin {
-  constructor(uppy: Uppy, opts: Partial<GoogleDrive.GoogleDriveOptions>);
+declare class GoogleDrive extends Uppy.Plugin {
+  constructor(uppy: Uppy.Uppy, opts: Partial<GoogleDrive.GoogleDriveOptions>);
 }
 
 export = GoogleDrive;
 
 declare module '@uppy/core' {
   export interface Uppy {
-    use(pluginClass: typeof GoogleDrive, opts: Partial<GoogleDrive.GoogleDriveOptions>): Uppy;
+    use(pluginClass: typeof GoogleDrive, opts: Partial<GoogleDrive.GoogleDriveOptions>): Uppy.Uppy;
   }
 }

+ 5 - 5
packages/@uppy/informer/types/index.d.ts

@@ -1,4 +1,4 @@
-import { Plugin, PluginOptions, Uppy } from '@uppy/core';
+import Uppy = require('@uppy/core');
 
 declare module Informer {
   interface Color {
@@ -6,21 +6,21 @@ declare module Informer {
     text: string | number;
   }
 
-  interface InformerOptions extends PluginOptions {
+  interface InformerOptions extends Uppy.PluginOptions {
     typeColors: {
       [type: string]: Color
     };
   }
 }
 
-declare class Informer extends Plugin {
-  constructor(uppy: Uppy, opts: Partial<Informer.InformerOptions>);
+declare class Informer extends Uppy.Plugin {
+  constructor(uppy: Uppy.Uppy, opts: Partial<Informer.InformerOptions>);
 }
 
 export = Informer;
 
 declare module '@uppy/core' {
   export interface Uppy {
-    use(pluginClass: typeof Informer, opts: Partial<Informer.InformerOptions>): Uppy;
+    use(pluginClass: typeof Informer, opts: Partial<Informer.InformerOptions>): Uppy.Uppy;
   }
 }

+ 6 - 6
packages/@uppy/instagram/types/index.d.ts

@@ -1,21 +1,21 @@
-import { Plugin, PluginOptions, Uppy } from '@uppy/core';
-import { ProviderOptions } from '@uppy/companion-client';
+import Uppy = require('@uppy/core');
+import CompanionClient = require('@uppy/companion-client');
 
 declare module Instagram {
-  interface InstagramOptions extends PluginOptions, ProviderOptions {
+  interface InstagramOptions extends Uppy.PluginOptions, CompanionClient.ProviderOptions {
     serverUrl: string;
     serverPattern: string | RegExp | Array<string | RegExp>;
   }
 }
 
-declare class Instagram extends Plugin {
-  constructor(uppy: Uppy, opts: Partial<Instagram.InstagramOptions>);
+declare class Instagram extends Uppy.Plugin {
+  constructor(uppy: Uppy.Uppy, opts: Partial<Instagram.InstagramOptions>);
 }
 
 export = Instagram;
 
 declare module '@uppy/core' {
   export interface Uppy {
-    use(pluginClass: typeof Instagram, opts: Partial<Instagram.InstagramOptions>): Uppy;
+    use(pluginClass: typeof Instagram, opts: Partial<Instagram.InstagramOptions>): Uppy.Uppy;
   }
 }

+ 5 - 5
packages/@uppy/progress-bar/types/index.d.ts

@@ -1,20 +1,20 @@
-import { Plugin, PluginOptions, Uppy } from '@uppy/core';
+import Uppy = require('@uppy/core');
 
 declare module ProgressBar {
-  interface ProgressBarOptions extends PluginOptions {
+  interface ProgressBarOptions extends Uppy.PluginOptions {
     hideAfterFinish: boolean;
     fixed: boolean;
   }
 }
 
-declare class ProgressBar extends Plugin {
-  constructor(uppy: Uppy, opts: Partial<ProgressBar.ProgressBarOptions>);
+declare class ProgressBar extends Uppy.Plugin {
+  constructor(uppy: Uppy.Uppy, opts: Partial<ProgressBar.ProgressBarOptions>);
 }
 
 export = ProgressBar;
 
 declare module '@uppy/core' {
   export interface Uppy {
-    use(pluginClass: typeof ProgressBar, opts: Partial<ProgressBar.ProgressBarOptions>): Uppy;
+    use(pluginClass: typeof ProgressBar, opts: Partial<ProgressBar.ProgressBarOptions>): Uppy.Uppy;
   }
 }

+ 3 - 5
packages/@uppy/react/src/CommonTypes.d.ts

@@ -1,6 +1,4 @@
-export { Uppy } from '../../core/types';
+import UppyCore = require('@uppy/core');
 
-export interface Locale {
-    strings: { [index: string]: string };
-    pluralize: (noun: string) => string;
-}
+export interface Uppy extends UppyCore.Uppy {}
+export interface Locale extends UppyCore.Locale {}

+ 19 - 19
packages/@uppy/react/src/Dashboard.d.ts

@@ -1,28 +1,28 @@
 import { Uppy, Locale } from './CommonTypes';
 
 interface MetaField {
-    id: string;
-    name: string;
-    placeholder?: string;
+  id: string;
+  name: string;
+  placeholder?: string;
 }
 
 export interface DashboardProps {
-    uppy: Uppy;
-    inline?: boolean;
-    plugins?: Array<string>;
-    width?: number;
-    height?: number;
-    showProgressDetails?: boolean;
-    showLinkToFileUploadResult?: boolean;
-    hideUploadButton?: boolean;
-    hideProgressAfterFinish?: boolean;
-    note?: string;
-    metaFields?: Array<MetaField>;
-    proudlyDisplayPoweredByUppy?: boolean;
-    disableStatusBar?: boolean;
-    disableInformer?: boolean;
-    disableThumbnailGenerator?: boolean;
-    locale?: Locale;
+  uppy: Uppy;
+  inline?: boolean;
+  plugins?: Array<string>;
+  width?: number;
+  height?: number;
+  showProgressDetails?: boolean;
+  showLinkToFileUploadResult?: boolean;
+  hideUploadButton?: boolean;
+  hideProgressAfterFinish?: boolean;
+  note?: string;
+  metaFields?: Array<MetaField>;
+  proudlyDisplayPoweredByUppy?: boolean;
+  disableStatusBar?: boolean;
+  disableInformer?: boolean;
+  disableThumbnailGenerator?: boolean;
+  locale?: Locale;
 }
 
 /**

+ 5 - 5
packages/@uppy/react/src/DashboardModal.d.ts

@@ -1,11 +1,11 @@
 import { DashboardProps } from './Dashboard';
 
 export interface DashboardModalProps extends DashboardProps {
-    target?: HTMLElement;
-    open?: boolean;
-    onRequestClose?: VoidFunction;
-    closeModalOnClickOutside?: boolean;
-    disablePageScrollWhenModalOpen?: boolean;
+  target: string | HTMLElement;
+  open?: boolean;
+  onRequestClose?: VoidFunction;
+  closeModalOnClickOutside?: boolean;
+  disablePageScrollWhenModalOpen?: boolean;
 }
 
 /**

+ 2 - 2
packages/@uppy/react/src/DragDrop.d.ts

@@ -1,8 +1,8 @@
 import { Uppy, Locale } from './CommonTypes';
 
 export interface DragDropProps {
-    uppy: Uppy;
-    locale?: Locale;
+  uppy: Uppy;
+  locale?: Locale;
 }
 
 /**

+ 3 - 3
packages/@uppy/react/src/ProgressBar.d.ts

@@ -1,9 +1,9 @@
 import { Uppy } from './CommonTypes';
 
 export interface ProgressBarProps {
-    uppy: Uppy;
-    fixed?: boolean;
-    hideAfterFinish?: boolean;
+  uppy: Uppy;
+  fixed?: boolean;
+  hideAfterFinish?: boolean;
 }
 
 /**

+ 3 - 3
packages/@uppy/react/src/StatusBar.d.ts

@@ -1,9 +1,9 @@
 import { Uppy } from './CommonTypes';
 
 export interface StatusBarProps {
-    uppy: Uppy;
-    showProgressDetails?: boolean;
-    hideAfterFinish?: boolean;
+  uppy: Uppy;
+  showProgressDetails?: boolean;
+  hideAfterFinish?: boolean;
 }
 
 /**

+ 5 - 5
packages/@uppy/redux-dev-tools/types/index.d.ts

@@ -1,18 +1,18 @@
-import { Plugin, PluginOptions, Uppy } from '@uppy/core';
+import Uppy = require('@uppy/core');
 
 declare module ReduxDevTools {
-  interface ReduxDevToolsOptions extends PluginOptions {
+  interface ReduxDevToolsOptions extends Uppy.PluginOptions {
   }
 }
 
-declare class ReduxDevTools extends Plugin {
-  constructor(uppy: Uppy, opts: Partial<ReduxDevTools.ReduxDevToolsOptions>);
+declare class ReduxDevTools extends Uppy.Plugin {
+  constructor(uppy: Uppy.Uppy, opts: Partial<ReduxDevTools.ReduxDevToolsOptions>);
 }
 
 export = ReduxDevTools;
 
 declare module '@uppy/core' {
   export interface Uppy {
-    use(pluginClass: typeof ReduxDevTools, opts: Partial<ReduxDevTools.ReduxDevToolsOptions>): Uppy;
+    use(pluginClass: typeof ReduxDevTools, opts: Partial<ReduxDevTools.ReduxDevToolsOptions>): Uppy.Uppy;
   }
 }

+ 5 - 5
packages/@uppy/status-bar/types/index.d.ts

@@ -1,21 +1,21 @@
-import { Plugin, PluginOptions, Uppy } from '@uppy/core';
+import Uppy = require('@uppy/core');
 
 declare module StatusBar {
-  export interface StatusBarOptions extends PluginOptions {
+  export interface StatusBarOptions extends Uppy.PluginOptions {
     showProgressDetails: boolean;
     hideUploadButton: boolean;
     hideAfterFinish: boolean;
   }
 }
 
-declare class StatusBar extends Plugin {
-  constructor(uppy: Uppy, opts: Partial<StatusBar.StatusBarOptions>);
+declare class StatusBar extends Uppy.Plugin {
+  constructor(uppy: Uppy.Uppy, opts: Partial<StatusBar.StatusBarOptions>);
 }
 
 export = StatusBar;
 
 declare module '@uppy/core' {
   export interface Uppy {
-    use(pluginClass: typeof StatusBar, opts: Partial<StatusBar.StatusBarOptions>): Uppy;
+    use(pluginClass: typeof StatusBar, opts: Partial<StatusBar.StatusBarOptions>): Uppy.Uppy;
   }
 }

+ 3 - 3
packages/@uppy/store-default/types/index.d.ts

@@ -1,6 +1,6 @@
-import { Store } from '@uppy/core';
+import Uppy = require('@uppy/core');
 
-declare class DefaultStore implements Store {
+declare class DefaultStore implements Uppy.Store {
   constructor();
   getState(): object;
   setState(patch: object): void;
@@ -8,4 +8,4 @@ declare class DefaultStore implements Store {
 }
 
 declare function createDefaultStore(): DefaultStore;
-export = createDefaultStore;
+export = createDefaultStore;

+ 9 - 0
packages/@uppy/store-default/types/store-default-tests.ts

@@ -0,0 +1,9 @@
+import Uppy = require('@uppy/core');
+import DefaultStore = require('../');
+
+const store = DefaultStore();
+
+store.setState({ a: 'b' });
+store.getState();
+
+Uppy({ store });

+ 19 - 21
packages/@uppy/store-redux/types/index.d.ts

@@ -1,26 +1,24 @@
-import { Store } from '@uppy/core';
+import Uppy = require('@uppy/core');
 import { Reducer, Middleware, Store as Redux } from 'redux';
 
-export interface ReduxStoreOptions {
-  store: Redux<object>;
-  id?: string;
-  selector?: (state: any) => object;
-}
-
-declare class ReduxStore implements Store {
-  constructor(opts: ReduxStoreOptions);
-  getState(): object;
-  setState(patch: object): void;
-  subscribe(listener: any): () => void;
-}
+declare namespace ReduxStore {
+  interface ReduxStoreOptions {
+    store: Redux<object>;
+    id?: string;
+    selector?: (state: any) => object;
+  }
 
-export const reducer: Reducer<object>;
-export const middleware: Middleware;
-// Redux action name.
-export const STATE_UPDATE: string;
+  interface ReduxStore extends Uppy.Store {
+    constructor(opts: ReduxStoreOptions): ReduxStore;
+    getState(): object;
+    setState(patch: object): void;
+    subscribe(listener: any): () => void;
+  }
 
-// Typescript forbids the next two lines with the following error message:
-// "An export assignment cannot be used in a module with other exported elements."
+  const reducer: Reducer<object>;
+  const middleware: Middleware;
+  const STATE_UPDATE: string;
+}
+declare function ReduxStore(opts: ReduxStore.ReduxStoreOptions): ReduxStore.ReduxStore;
 
-// declare function createReduxStore(opts: ReduxStoreOptions): ReduxStore;
-// export = createReduxStore;
+export = ReduxStore;

+ 13 - 0
packages/@uppy/store-redux/types/store-redux-tests.ts

@@ -0,0 +1,13 @@
+import { createStore, combineReducers } from 'redux';
+import Uppy = require('@uppy/core');
+import ReduxStore = require('../');
+
+const reducer = combineReducers({
+  uppy: ReduxStore.reducer
+});
+
+const store = ReduxStore({
+  store: createStore(reducer)
+});
+
+Uppy({ store });

+ 5 - 5
packages/@uppy/thumbnail-generator/types/index.d.ts

@@ -1,19 +1,19 @@
-import { Plugin, PluginOptions, Uppy } from '@uppy/core';
+import Uppy = require('@uppy/core');
 
 declare module ThumbnailGenerator {
-  interface ThumbnailGeneratorOptions extends PluginOptions {
+  interface ThumbnailGeneratorOptions extends Uppy.PluginOptions {
     thumbnailWidth: number;
   }
 }
 
-declare class ThumbnailGenerator extends Plugin {
-  constructor(uppy: Uppy, opts: Partial<ThumbnailGenerator.ThumbnailGeneratorOptions>);
+declare class ThumbnailGenerator extends Uppy.Plugin {
+  constructor(uppy: Uppy.Uppy, opts: Partial<ThumbnailGenerator.ThumbnailGeneratorOptions>);
 }
 
 export = ThumbnailGenerator;
 
 declare module '@uppy/core' {
   export interface Uppy {
-    use(pluginClass: typeof ThumbnailGenerator, opts: Partial<ThumbnailGenerator.ThumbnailGeneratorOptions>): Uppy;
+    use(pluginClass: typeof ThumbnailGenerator, opts: Partial<ThumbnailGenerator.ThumbnailGeneratorOptions>): Uppy.Uppy;
   }
 }

+ 6 - 6
packages/@uppy/transloadit/types/index.d.ts

@@ -1,4 +1,4 @@
-import { Plugin, PluginOptions, Uppy, UppyFile } from '@uppy/core';
+import Uppy = require('@uppy/core');
 
 declare module Transloadit {
   interface AssemblyParameters {
@@ -15,7 +15,7 @@ declare module Transloadit {
     signature?: string;
   }
 
-  interface TransloaditOptions extends PluginOptions {
+  interface TransloaditOptions extends Uppy.PluginOptions {
     params: AssemblyParameters;
     signature: string;
     service: string;
@@ -23,18 +23,18 @@ declare module Transloadit {
     waitForMetadata: boolean;
     importFromUploadURLs: boolean;
     alwaysRunAssembly: boolean;
-    getAssemblyOptions: (file: UppyFile) => AssemblyOptions | Promise<AssemblyOptions>;
+    getAssemblyOptions: (file: Uppy.UppyFile) => AssemblyOptions | Promise<AssemblyOptions>;
   }
 }
 
-declare class Transloadit extends Plugin {
-  constructor(uppy: Uppy, opts: Partial<Transloadit.TransloaditOptions>);
+declare class Transloadit extends Uppy.Plugin {
+  constructor(uppy: Uppy.Uppy, opts: Partial<Transloadit.TransloaditOptions>);
 }
 
 export = Transloadit;
 
 declare module '@uppy/core' {
   export interface Uppy {
-    use(pluginClass: typeof Transloadit, opts: Partial<Transloadit.TransloaditOptions>): Uppy;
+    use(pluginClass: typeof Transloadit, opts: Partial<Transloadit.TransloaditOptions>): Uppy.Uppy;
   }
 }

+ 5 - 5
packages/@uppy/tus/types/index.d.ts

@@ -1,7 +1,7 @@
-import { Plugin, PluginOptions, Uppy } from '@uppy/core';
+import Uppy = require('@uppy/core');
 
 declare module Tus {
-  export interface TusOptions extends PluginOptions {
+  export interface TusOptions extends Uppy.PluginOptions {
     limit: number;
     endpoint: string;
     uploadUrl: string;
@@ -11,14 +11,14 @@ declare module Tus {
   }
 }
 
-declare class Tus extends Plugin {
-  constructor(uppy: Uppy, opts: Partial<Tus.TusOptions>);
+declare class Tus extends Uppy.Plugin {
+  constructor(uppy: Uppy.Uppy, opts: Partial<Tus.TusOptions>);
 }
 
 export = Tus;
 
 declare module '@uppy/core' {
   export interface Uppy {
-    use(pluginClass: typeof Tus, opts: Partial<Tus.TusOptions>): Uppy;
+    use(pluginClass: typeof Tus, opts: Partial<Tus.TusOptions>): Uppy.Uppy;
   }
 }

+ 5 - 5
packages/@uppy/url/types/index.d.ts

@@ -1,20 +1,20 @@
-import { Plugin, PluginOptions, Uppy } from '@uppy/core';
+import Uppy = require('@uppy/core');
 
 declare module Url {
-  export interface UrlOptions extends PluginOptions {
+  export interface UrlOptions extends Uppy.PluginOptions {
     serverUrl: string;
     // TODO inherit from ProviderOptions
   }
 }
 
-declare class Url extends Plugin {
-  constructor(uppy: Uppy, opts: Partial<Url.UrlOptions>);
+declare class Url extends Uppy.Plugin {
+  constructor(uppy: Uppy.Uppy, opts: Partial<Url.UrlOptions>);
 }
 
 export = Url;
 
 declare module '@uppy/core' {
   export interface Uppy {
-    use(pluginClass: typeof Url, opts: Partial<Url.UrlOptions>): Uppy;
+    use(pluginClass: typeof Url, opts: Partial<Url.UrlOptions>): Uppy.Uppy;
   }
 }

+ 6 - 6
packages/@uppy/utils/types/index.d.ts

@@ -26,7 +26,7 @@ declare module '@uppy/utils/lib/dataURItoFile' {
 }
 
 declare module '@uppy/utils/lib/emitSocketProgress' {
-  import { UppyFile } from '@uppy/core';
+  import Uppy = require('@uppy/core');
 
   interface ProgressData {
     progress: number;
@@ -34,7 +34,7 @@ declare module '@uppy/utils/lib/emitSocketProgress' {
     bytesTotal: number;
   }
 
-  export default function emitSocketProgress(uploader: object, progressData: ProgressData, file: UppyFile): void;
+  export default function emitSocketProgress(uploader: object, progressData: ProgressData, file: Uppy.UppyFile): void;
 }
 
 declare module '@uppy/utils/lib/findAllDOMElements' {
@@ -46,9 +46,9 @@ declare module '@uppy/utils/lib/findDOMElement' {
 }
 
 declare module '@uppy/utils/lib/generateFileID' {
-  import { UppyFile } from '@uppy/core';
+  import Uppy = require('@uppy/core');
 
-  export default function generateFileID(file: UppyFile): string;
+  export default function generateFileID(file: Uppy.UppyFile): string;
 }
 
 declare module '@uppy/utils/lib/getBytesRemaining' {
@@ -64,9 +64,9 @@ declare module '@uppy/utils/lib/getFileNameAndExtension' {
 }
 
 declare module '@uppy/utils/lib/getFileType' {
-  import { UppyFile } from '@uppy/core';
+  import Uppy = require('@uppy/core');
 
-  export default function getFileType(file: UppyFile): string | null;
+  export default function getFileType(file: Uppy.UppyFile): string | null;
 }
 
 declare module '@uppy/utils/lib/getFileTypeExtension' {

+ 14 - 15
packages/@uppy/webcam/types/index.d.ts

@@ -1,26 +1,25 @@
-import { Plugin, PluginOptions, Uppy } from '@uppy/core';
+import Uppy = require('@uppy/core');
 
 declare module Webcam {
+  export type WebcamMode = 'video-audio' | 'video-only' | 'audio-only' | 'picture';
 
-    export type WebcamMode = 'video-audio' | 'video-only' | 'audio-only' | 'picture';
-
-    export interface WebcamOptions extends PluginOptions {
-        onBeforeSnapshot?: () => Promise<void>;
-        countdown?: number | boolean;
-        mirror?: boolean;
-        facingMode?: string;
-        modes: WebcamMode[];
-    }
+  export interface WebcamOptions extends Uppy.PluginOptions {
+    onBeforeSnapshot?: () => Promise<void>;
+    countdown?: number | boolean;
+    mirror?: boolean;
+    facingMode?: string;
+    modes: WebcamMode[];
+  }
 }
 
-declare class Webcam extends Plugin {
-    constructor(uppy: Uppy, opts: Partial<Webcam.WebcamOptions>);
+declare class Webcam extends Uppy.Plugin {
+  constructor(uppy: Uppy.Uppy, opts: Partial<Webcam.WebcamOptions>);
 }
 
 export = Webcam;
 
 declare module '@uppy/core' {
-    export interface Uppy {
-        use(pluginClass: typeof Webcam, opts: Partial<Webcam.WebcamOptions>): Uppy;
-    }
+  export interface Uppy {
+    use(pluginClass: typeof Webcam, opts: Partial<Webcam.WebcamOptions>): Uppy.Uppy;
+  }
 }

+ 8 - 0
packages/@uppy/webcam/types/webcam-tests.ts

@@ -0,0 +1,8 @@
+import Uppy = require('@uppy/core');
+import Webcam = require('../');
+
+{
+  Uppy().use(Webcam, {
+    modes: ['video-only']
+  });
+}

+ 12 - 10
packages/@uppy/xhr-upload/src/index.js

@@ -202,20 +202,17 @@ module.exports = class XHRUpload extends Plugin {
       })
 
       const xhr = new XMLHttpRequest()
-      if (opts.responseType !== '') {
-        xhr.responseType = opts.responseType
-      }
 
       const id = cuid()
 
       xhr.upload.addEventListener('loadstart', (ev) => {
         this.uppy.log(`[XHRUpload] ${id} started`)
-        // Begin checking for timeouts when loading starts.
-        timer.progress()
       })
 
       xhr.upload.addEventListener('progress', (ev) => {
         this.uppy.log(`[XHRUpload] ${id} progress: ${ev.loaded} / ${ev.total}`)
+        // Begin checking for timeouts when progress starts, instead of loading,
+        // to avoid timing out requests on browser concurrency queue
         timer.progress()
 
         if (ev.lengthComputable) {
@@ -276,8 +273,12 @@ module.exports = class XHRUpload extends Plugin {
       })
 
       xhr.open(opts.method.toUpperCase(), opts.endpoint, true)
-      // IE10 does not allow setting `withCredentials` before `open()` is called.
+      // IE10 does not allow setting `withCredentials` and `responseType`
+      // before `open()` is called.
       xhr.withCredentials = opts.withCredentials
+      if (opts.responseType !== '') {
+        xhr.responseType = opts.responseType
+      }
 
       Object.keys(opts.headers).forEach((header) => {
         xhr.setRequestHeader(header, opts.headers[header])
@@ -362,9 +363,6 @@ module.exports = class XHRUpload extends Plugin {
       })
 
       const xhr = new XMLHttpRequest()
-      if (this.opts.responseType !== '') {
-        xhr.responseType = this.opts.responseType
-      }
 
       const timer = this.createProgressTimeout(this.opts.timeout, (error) => {
         xhr.abort()
@@ -428,8 +426,12 @@ module.exports = class XHRUpload extends Plugin {
       })
 
       xhr.open(method.toUpperCase(), endpoint, true)
-      // IE10 does not allow setting `withCredentials` before `open()` is called.
+      // IE10 does not allow setting `withCredentials` and `responseType`
+      // before `open()` is called.
       xhr.withCredentials = this.opts.withCredentials
+      if (this.opts.responseType !== '') {
+        xhr.responseType = this.opts.responseType
+      }
 
       Object.keys(this.opts.headers).forEach((header) => {
         xhr.setRequestHeader(header, this.opts.headers[header])

+ 14 - 14
packages/@uppy/xhr-upload/types/index.d.ts

@@ -1,28 +1,28 @@
-import { Plugin, PluginOptions, Uppy } from '@uppy/core';
+import Uppy = require('@uppy/core');
 
 declare module XHRUpload {
-  export interface XHRUploadOptions extends PluginOptions {
-    limit: string;
-    bundle: boolean;
-    formData: FormData;
-    headers: any;
-    metaFields: string[];
-    fieldName: string;
-    timeout: number;
-    responseUrlFieldName: string;
+  export interface XHRUploadOptions extends Uppy.PluginOptions {
+    limit?: number;
+    bundle?: boolean;
+    formData?: FormData;
+    headers?: any;
+    metaFields?: string[];
+    fieldName?: string;
+    timeout?: number;
+    responseUrlFieldName?: string;
     endpoint: string;
-    method: 'GET' | 'POST' | 'HEAD';
+    method?: 'GET' | 'POST' | 'PUT' | 'HEAD';
   }
 }
 
-declare class XHRUpload extends Plugin {
-  constructor(uppy: Uppy, opts: Partial<XHRUpload.XHRUploadOptions>);
+declare class XHRUpload extends Uppy.Plugin {
+  constructor(uppy: Uppy.Uppy, opts: XHRUpload.XHRUploadOptions);
 }
 
 export = XHRUpload;
 
 declare module '@uppy/core' {
   export interface Uppy {
-    use(pluginClass: typeof XHRUpload, opts: Partial<XHRUpload.XHRUploadOptions>): Uppy;
+    use(pluginClass: typeof XHRUpload, opts: XHRUpload.XHRUploadOptions): Uppy.Uppy;
   }
 }

+ 9 - 0
packages/@uppy/xhr-upload/types/xhr-upload-tests.ts

@@ -0,0 +1,9 @@
+import Uppy = require('@uppy/core');
+import XHRUpload = require('../');
+
+{
+  Uppy().use(XHRUpload, {
+    bundle: false,
+    endpoint: 'xyz'
+  } as XHRUpload.XHRUploadOptions);
+}

+ 29 - 0
test/endtoend/typescript/index.html

@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <title>Uppy test page</title>
+</head>
+
+<body>
+  <style>
+    main {
+      max-width: 700px;
+      margin: auto;
+    }
+  </style>
+  <main>
+    <h2>Compiled Typescript</h2>
+    <form id=upload-form>
+      <input type="meta" value="example meta">
+    </form>
+    <button id="pick-files">Open modal</button>
+  </main>
+
+  <link href="uppy.min.css" rel="stylesheet">
+  <script src="bundle.js"></script>
+</body>
+
+</html>

+ 50 - 0
test/endtoend/typescript/main.ts

@@ -0,0 +1,50 @@
+import 'es6-promise/auto'
+import 'whatwg-fetch'
+import Uppy = require('@uppy/core')
+import Dashboard = require('@uppy/dashboard')
+import Instagram = require('@uppy/instagram')
+import Dropbox = require('@uppy/dropbox')
+import GoogleDrive = require('@uppy/google-drive')
+import Url = require('@uppy/url')
+import Webcam = require('@uppy/webcam')
+import Tus = require('@uppy/tus')
+import Form = require('@uppy/form')
+
+const TUS_ENDPOINT = 'https://master.tus.io/files/'
+
+const uppy = Uppy({
+  debug: true,
+  meta: {
+    username: 'John',
+    license: 'Creative Commons'
+  }
+})
+  .use(Dashboard, {
+    target: document.body,
+    trigger: '#pick-files',
+    metaFields: [
+      { id: 'license', name: 'License', placeholder: 'specify license' },
+      { id: 'caption', name: 'Caption', placeholder: 'add caption' }
+    ],
+    showProgressDetails: true,
+    proudlyDisplayPoweredByUppy: true,
+    note: '2 files, images and video only'
+  })
+  .use(GoogleDrive, { target: Dashboard, serverUrl: 'http://localhost:3020' })
+  .use(Instagram, { target: Dashboard, serverUrl: 'http://localhost:3020' })
+  .use(Dropbox, { target: Dashboard, serverUrl: 'http://localhost:3020' })
+  .use(Url, { target: Dashboard, serverUrl: 'http://localhost:3020' })
+  .use(Webcam, { target: Dashboard })
+  .use(Tus, { endpoint: TUS_ENDPOINT })
+  .use(Form, { target: '#upload-form' })
+  // .use(GoldenRetriever, {serviceWorker: true})
+
+uppy.on('complete', (result) => {
+  if (result.failed.length === 0) {
+    console.log('Upload successful 😀')
+  } else {
+    console.warn('Upload failed 😞')
+  }
+  console.log('successful files:', result.successful)
+  console.log('failed files:', result.failed)
+})

+ 18 - 0
test/endtoend/typescript/test.js

@@ -0,0 +1,18 @@
+/* global browser, expect  */
+describe('Project compiled with Uppy\'s TypeScript typings', () => {
+  it('Should have correct imports (thus not crash)', () => {
+    browser.url('http://localhost:4567/typescript')
+
+    browser.waitForExist('.uppy-Root')
+    browser.click('#pick-files')
+
+    const typeofUppy = browser.execute(function () {
+      return typeof window.uppy
+    })
+    // It was initialized correctly
+    expect(typeofUppy.value).to.equal('object')
+
+    // The dashboard is shown
+    expect(browser.isVisible(`.uppy-Dashboard`)).to.equal(true)
+  })
+})

+ 2 - 2
test/endtoend/wdio.base.conf.js

@@ -17,8 +17,7 @@ exports.config = {
   // directory is where your package.json resides, so `wdio` will be called from there.
   //
   specs: [
-    // 'test/endtoend/*/test.js',
-    'test/endtoend/transloadit/test.js'
+    'test/endtoend/*/test.js'
   ],
 
   // Patterns to exclude.
@@ -95,6 +94,7 @@ exports.config = {
     { mount: '/providers', path: './test/endtoend/providers/dist' },
     { mount: '/thumbnails', path: './test/endtoend/thumbnails/dist' },
     { mount: '/transloadit', path: './test/endtoend/transloadit/dist' },
+    { mount: '/typescript', path: './test/endtoend/typescript/dist' },
     { mount: '/url-plugin', path: './test/endtoend/url-plugin/dist' },
     { mount: '/create-react-app', path: './test/endtoend/create-react-app/build' }
   ],

+ 1 - 1
tsconfig.json

@@ -20,7 +20,7 @@
     "packages/*/types/index.d.ts",
     "packages/*/types/*-tests.ts",
     "packages/@uppy/*/types/index.d.ts",
-    "packages/@uppy/*/types/*-tests.ts",
+    "packages/@uppy/*/types/*-tests.ts"
   ],
   "exclude": [
     "packages/@uppy/companion"

+ 10 - 10
website/src/_posts/2018-12-0.29.md

@@ -1,5 +1,5 @@
 ---
-title: "Uppy 0.29: Separate Core and Plugin styles, React Native in tus-js-client"
+title: "Uppy 0.29: separate Core and Plugin styles, React Native in tus-js-client"
 date: 2018-12-11
 author: arturi
 image: "https://uppy.io/images/blog/0.29/uppy-core-plugins-separate-styles.jpg"
@@ -8,7 +8,7 @@ published: true
 
 <img src="/images/blog/0.29/uppy-core-plugins-separate-styles.jpg">
 
-`0.29` brings bug fixes and improvements, while we are busy working on Uppy React Native support (which first had to [land in the js client for our resumable file upload protocol: tus.io](https://github.com/tus/tus-js-client#react-native-support)) and a Preset (still debating the name) which will make it easier to leverage Transloadit's encoding platform, and offer a smooth migration path for users not on Uppy yet. The highlights of this release are: separating Core and Plugin styles, more accurate progress reporting by factoring in sizes across files, adding a `responseType` option for XHR Upload and fixing visual Webcam bugs.
+`0.29` brings bug fixes and improvements, while we are busy working on Uppy React Native support (which first had to [land in the js client for our resumable file upload protocol: tus.io](https://github.com/tus/tus-js-client#react-native-support)) and a Preset (still debating the name) which will make it easier to leverage Transloadit's encoding platform, and offer a smooth migration path for users not yet on Uppy. The highlights of this release are: separating Core and Plugin styles, more accurate progress reporting by factoring in sizes across files, adding a `responseType` option for XHR Upload, and fixing visual Webcam bugs.
 
 <!--more-->
 
@@ -26,7 +26,7 @@ import '@uppy/webcam/dist/style.css'
 
 Each plugin's file contained the Core styles. If you added multiple plugins, the core styles ended up being duplicated. This bloated file sizes and could even break styles entirely because of CSS's precedence rules.
 
-Now you have to include “general” styles from `@uppy/core` as well:
+Now, you have to include “general” styles from `@uppy/core` as well:
 
 ```js
 import Uppy from '@uppy/core'
@@ -35,14 +35,14 @@ import '@uppy/core/dist/style.css' // <-- add this separately and one time only
 import '@uppy/webcam/dist/style.css'
 ```
 
-Thus the Core styles are only included once. `@uppy/core` styles must be included before Plugin styles.
+Thus, the Core styles are only included once. `@uppy/core` styles must be included before Plugin styles.
 
-Please [see documentation for the Plugin](https://uppy.io/docs/plugins/) you are using to find out whether it requires a CSS file to work. Generally speaking UI plugins, such as the Dashboard, Webcam and Status Bar need a CSS file, while utility plugins, such as Tus or XHR Upload, don’t.
+Please see the [documentation](https://uppy.io/docs/plugins/) for the Plugin you are using to find out whether it requires a CSS file to work. Generally speaking, UI plugins, such as the Dashboard, Webcam and Status Bar, need a CSS file, while utility plugins, such as Tus or XHR Upload, don’t.
 
 ⚠️ Important things to remember:
 
-1. Dashboard is a universal UI that comes with the Status Bar and Informer Plugins built in, and as such Dashboard styles already come with the Informer and Status Bar styles.
-2. Dashboard also ships with “Remote Provider” styles — you don’t need to include anything besides `@uppy/dashboard/dist/style.css` for Google Drive, Instagram and Dropbox to work. However, Url and Webcam plugins, still have to be included manually. Here’s an example:
+1. Dashboard is a universal UI that comes with the Status Bar and Informer Plugins built in, and as such, Dashboard styles already come with the Informer and Status Bar styles.
+2. Dashboard also ships with “Remote Provider” styles — you don’t need to include anything besides `@uppy/dashboard/dist/style.css` for Google Drive, Instagram and Dropbox to work. However, the Url and Webcam plugins still have to be included manually. Here’s an example:
 
 ```js
 import Uppy from '@uppy/core'
@@ -61,7 +61,7 @@ import '@uppy/url/dist/style.css'
 
 ## Using File Sizes For Progress Calculation
 
-When possible, file sizes are now used for calculating the total progress. Before, we’ve used uploaded percentage for each file. That meant, if you were uploading 4 files, and 3 small were already uploaded, while one very large file was still in progress, Uppy may display progress as 90%. Long story short, Uppy now has a more accurate progress bar 🚀
+When possible, file sizes are now used for calculating the total progress. Before, we’ve used uploaded percentage for each file. Meaning that if you were uploading four files — and three small were already uploaded, while one very large file was still in progress — Uppy might still display progress as being 90%. Long story short, Uppy now has a more accurate progress bar 🚀
 
 Some internal details, if you are interested:
 
@@ -74,12 +74,12 @@ Some internal details, if you are interested:
 
 When using XHR Upload, you can now configure the XMLHttpRequest `.responseType` value. This allows the S3 Plugin to tell Firefox not to log XML errors when getting empty responses, so it finally fixes the spurious warnings that were caused by this, see [#518](https://github.com/transloadit/uppy/issues/518).
 
-Because AwsS3 now sets `responseType`: `'text'`, we can no longer use the `responseXML` property. We already did text based parsing for successful responses, and now do the same for error responses.
+Because AwsS3 now sets `responseType`: `'text'`, we can no longer use the `responseXML` property. We already did text based parsing for successful responses, and will now do the same for error responses.
 
 ## Misc Changes
 
 - @uppy/core: Don't pass removed file IDs to next upload step, fixes (#1148 / @goto-bus-stop)
-- @uppy/core: Fixed getFileType() when passed a file with an upper case extension (#1169 / @jderrough)
+- @uppy/core: Fixed getFileType() when passed a file with an uppercase extension (#1169 / @jderrough)
 - @uppy/companion: Use `createCipheriv` instead of deprecated `createCipher` (#1149 / @goto-bus-stop)
 - @uppy/companion: Store Provider instances on `this.provider` instead of `this[this.id]` (@goto-bus-stop / #1174)
 - @uppy/companion: Pin grant to known stable version (@ifedapoolarewaju / #1165)

+ 5 - 1
website/src/docs/aws-s3.md

@@ -111,7 +111,7 @@ strings: {
 ## S3 Bucket configuration
 
 S3 buckets do not allow public uploads by default.
-In order to allow Uppy to upload directly to a bucket, its CORS permissions need to be configured.
+In order to allow Uppy to upload directly to a bucket, at least its CORS permissions need to be configured, and you potentially need to change some of the *Public access settings* that provide an extra layer of public access protection even if the correct CORS permissions are in place.
 
 CORS permissions can be found in the [S3 Management Console](https://console.aws.amazon.com/s3/home).
 Click the bucket that will receive the uploads, then go into the "Permissions" tab and select the "CORS configuration" button.
@@ -182,6 +182,10 @@ The final configuration should look something like this:
 </CORSConfiguration>
 ```
 
+Even with these CORS rules in place, you browser might still encounter HTTP status 403 responses with `AccessDenied` in the response body when it tries to `POST` to your bucket. In this case, within the "Permissions" tab of the [S3 Management Console](https://console.aws.amazon.com/s3/home), choose "Public access settings".
+
+It will list general *Public access settings for this bucket*, which can override the rules imposed by your CORS settings. Click on *edit* to manage these settings. Under *Manage public access control lists (ACLs) for this bucket*, make sure that *Block new public ACLs and uploading public objects (Recommended)* is unchecked, and *Save* these settings.
+
 In-depth documentation about CORS rules is available on the [AWS documentation site](https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html).
 
 ## POST uploads

+ 1 - 1
website/src/docs/tus.md

@@ -37,7 +37,7 @@ const Tus = Uppy.Tus
 
 ## Options
 
-The `@uppy/tus` plugin supports all of [tus-js-client][]’s options. In addition tot that, it has the following configurable options:
+The `@uppy/tus` plugin supports all of [tus-js-client][]’s options. In addition to that, it has the following configurable options:
 
 ### `id: 'Tus'`
 

+ 2 - 0
website/src/examples/dashboard/app.es6

@@ -1,3 +1,5 @@
+require('es6-promise/auto')
+require('whatwg-fetch')
 const Uppy = require('@uppy/core')
 const Dashboard = require('@uppy/dashboard')
 const GoogleDrive = require('@uppy/google-drive')

+ 2 - 0
website/src/examples/dragdrop/app.es6

@@ -1,3 +1,5 @@
+require('es6-promise/auto')
+require('whatwg-fetch')
 const Uppy = require('@uppy/core')
 const DragDrop = require('@uppy/drag-drop')
 const ProgressBar = require('@uppy/progress-bar')

+ 2 - 0
website/src/examples/statusbar/app.es6

@@ -1,3 +1,5 @@
+require('es6-promise/auto')
+require('whatwg-fetch')
 const Uppy = require('@uppy/core')
 const FileInput = require('@uppy/file-input')
 const StatusBar = require('@uppy/status-bar')

+ 2 - 0
website/src/examples/transloadit/app.es6

@@ -1,3 +1,5 @@
+require('es6-promise/auto')
+require('whatwg-fetch')
 const Uppy = require('@uppy/core')
 const Dashboard = require('@uppy/dashboard')
 const Webcam = require('@uppy/webcam')

+ 2 - 0
website/src/examples/xhrupload/app.es6

@@ -1,3 +1,5 @@
+require('es6-promise/auto')
+require('whatwg-fetch')
 const Uppy = require('@uppy/core')
 const FileInput = require('@uppy/file-input')
 const XHRUpload = require('@uppy/xhr-upload')