Compare commits

..

53 Commits

Author SHA1 Message Date
VIJAYA L MACHAVOLU
2d240804f5 Added csv as to filetype list and associating it with xls. 2020-12-06 23:27:33 +05:30
PARAM MITTAL
8171bc831b fix(typo): fix grammatical mistake in readme (#1119) 2019-10-30 17:37:02 +02:00
Vitaliy Makogon
d63c8ce9e2 Merge pull request #1107 from earshinov/update-to-angular8
feta(build): update to Angular 8. Use Angular CLI instead of ngm for building. Ensure compatibility with Ivy on application side.
2019-10-23 12:49:47 +03:00
Vitaliy Makogon
33ac156208 fix(ci): fix xvfb service issue 2019-10-22 16:04:21 +03:00
Eugene Arshinov
2888f4cb11 Provide angularCompilerOptions to ensure compatibility with Ivy (on the application side)
Without this configuration, the following error occurs:

```
error TS-996002: Appears in the NgModule.imports of ...Module, but could not be resolved to an NgModule class
```

Configuruation taken from https://github.com/froala/angular-froala-wysiwyg/pull/329/files#diff-bb630a56aac9aa4924037d7db039769d
2019-08-27 12:39:13 +03:00
Eugene Arshinov
7a342268bb Use Angular CLI instead of ngm for building
Some commands:

npm run build      - to build the library.  Output is in dist/ng2-file-upload/.
npm run test       - to run tests.  Coverage report is in coverage/ as before.
npm run demo.serve - to build demo application and serve it through browsersync
npm run start      - to run demo application using `ng serve`.  Requires the library to be built and linked first.
2019-08-27 12:39:13 +03:00
Eugene Arshinov
6cb3f87e57 Remove unused i18n and e2e stuff from angular.json 2019-08-27 12:39:13 +03:00
Eugene Arshinov
49a3334942 Update tslint and tslint-config-valorsoft 2019-08-27 12:39:13 +03:00
Eugene Arshinov
9fae840b69 Remove unused dependency ng2-page-scroll 2019-08-27 12:39:12 +03:00
Eugene Arshinov
7b4f871200 Run ng update to update to latest Angular 8.3.0 2019-08-27 12:39:12 +03:00
Eugene Arshinov
268534b3e1 Repair npm run test 2019-08-27 12:39:12 +03:00
Eugene Arshinov
77f2466f17 Use ng update to convert .angular-cli.json into angular.json 2019-08-27 12:39:12 +03:00
Eugene Arshinov
01c2d173f3 Update to @angular/core@6.0.0, @angular/cli@6.2.8, rxjs@6.0.0
Aux changes:
- Added package-lock.json to lock dependency versions
- Removed unused @angular/http from dependencies
2019-08-27 12:39:12 +03:00
Adrian Fâciu
fb48f4411d Merge pull request #927 from Amos47/development
Expand compression mime types
2017-12-09 23:07:49 +02:00
Adrian Fâciu
e423a3089c Merge pull request #939 from mattmcsparran/patch-1
Updated Readme for easier implementation
2017-12-09 23:06:14 +02:00
Matthew McSparran
502789dad6 Updated Readme
Updated to show what needs to be imported for a project to work like the demo.
2017-12-09 12:42:15 -05:00
Adrian Fâciu
d4bed8a045 Merge pull request #930 from adrianfaciu/release-1.3
Releasing 1.3.0
2017-11-25 19:09:39 +02:00
Adrian Fâciu
954240cfdc Releasing 1.3.0 2017-11-25 19:07:56 +02:00
Jordan Amos
7d25b57e1b expand compression mime types 2017-11-17 16:50:11 -08:00
Adrian Fâciu
0d97b76228 Merge pull request #904 from guanbo/options
Update: setOptions
2017-10-22 13:03:45 +03:00
Adrian Fâciu
9d0408e595 Merge pull request #911 from WisdomFusion/development
add file type .zip
2017-10-22 12:59:19 +03:00
WisdomFusion
35c5131c47 add file type .zip 2017-10-16 08:17:34 +08:00
Guan Bo
ccee135949 Update: setOptions
prevent from overwrite options which set before, such as authToken
2017-10-09 15:42:00 +08:00
Adrian Fâciu
aa1448392b Merge pull request #903 from adrianfaciu/chore/docs
Updating docs and formatting files
2017-10-07 13:00:53 +03:00
Adrian Fâciu
e1e36bbab4 Updating docs and formating files 2017-10-07 12:48:05 +03:00
Adrian Fâciu
bcf40f4407 Merge pull request #649 from infinum/feature/file-like-object-with-raw-file
Add rawFile in the file like object
2017-10-07 12:07:51 +03:00
Adrian Fâciu
e1bc9ff086 Merge pull request #658 from kopertop/development
Adds some Fixes for AWS Support.
2017-10-07 12:06:23 +03:00
Adrian Fâciu
631b4aa607 Merge pull request #786 from albpara/feature/emit-event-when-file-is-selected
Emit event when file is selected
2017-10-07 12:04:31 +03:00
Adrian Fâciu
57b2d0711d Merge branch 'development' into feature/emit-event-when-file-is-selected 2017-10-07 11:53:53 +03:00
Adrian Fâciu
898f297967 Merge pull request #901 from davidmds/development
Add response and function to modify the request body
2017-10-07 11:48:47 +03:00
David Martins
be7f164d98 Updating example 2017-10-06 17:22:20 -03:00
David Martins
4c0c4c70bc Fixing bug in response 2017-10-06 17:20:26 -03:00
David Martins
c84046e86e Update README 2017-10-04 17:03:16 -03:00
David Martins
14812e0cf7 Added option to send request body modifier function 2017-10-04 16:52:28 -03:00
David Martins
5357a243f6 Added event with return of request 2017-10-04 16:36:48 -03:00
Adrian Fâciu
5df3c5f076 Merge pull request #844 from spike31/patch-1
Fix correct path for isHTML5 option
2017-10-02 17:57:14 +03:00
Adrian Fâciu
7fc4945ff0 Merge pull request #857 from joshterrill/development
Added onFileDrop() event to documentation
2017-10-02 17:50:35 +03:00
Adrian Fâciu
0370d334d7 Merge pull request #898 from adrianfaciu/chore/tests
Fixing tests execution and adding a few more tests
2017-10-02 17:27:52 +03:00
Adrian Fâciu
048f534aa2 Adding tests for file select directive 2017-10-01 17:33:38 +03:00
Adrian Fâciu
0df30f996f Fixing test execution on CI 2017-10-01 17:07:54 +03:00
Adrian Fâciu
6bdf60fac4 Adding tests for file drop directive 2017-09-26 23:04:21 +03:00
Adrian
eca11298ee Fixed karma config 2017-09-26 21:40:55 +03:00
Joshua Terrill
28d98bc8af Added onFileDrop() event to documentation
In case anyone wants to use the onFileDrop event to handle the files in their own way, I've added it to the documentation.
2017-08-01 15:08:21 -07:00
Gilles Gauthier
74306fc210 Update simple demo
Fix correct path for isHTML5 option
2017-07-12 11:35:55 +02:00
Alberto Para
1f0ca3072b Emit event when file is selected 2017-05-08 23:55:06 +02:00
Dmitriy Shekhovtsov
41759be974 chore(package): dependencies upgrade 2017-04-10 13:57:32 +03:00
Dmitriy Shekhovtsov
e8d5ced3f6 chore(package): update to angular cli v1.0.0 2017-04-10 13:48:58 +03:00
smartm0use
7704e0e970 feat(package): relaxed peer dependencies to allow ng v4 (#713)
Add Angular 4 peer dependencies support
2017-04-10 13:31:27 +03:00
Chris Moyer
a333c59f82 Make sure it's a string before trying to do indexOf 2017-03-07 09:59:55 -05:00
Chris Moyer
8b36c892d5 Fixes {{file_name}} template 2017-03-06 17:41:47 -05:00
Chris Moyer
0e17d55633 Adds some Fixes for AWS Support.
AWS Requires any additional parameters to be specified BEFORE Files.
This also adds the ability to specify a {{file_name}} template in any
additional parameters to allow adding the filename to additional
parameters.

For example, you can now specify:

additionalParameter: {
	key: "path/to/uploads/{{file_name}}"
}
2017-03-06 17:30:18 -05:00
Charles Mark Maynard
99c83035d1 [On behalf of Lexmark]: Add export of FileLikeObject to allow callback to function (#619) 2017-03-01 23:28:57 +02:00
Gabrijel Škoro
e08f80ee74 Add rawFile in the file like object 2017-02-28 10:09:26 +01:00
39 changed files with 19452 additions and 8345 deletions

View File

@@ -1,11 +1,13 @@
language: node_js
node_js:
- "6"
- "10"
services:
- xvfb
before_install:
- export CHROME_BIN=chromium-browser
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
script:
- npm run pretest

View File

@@ -1,3 +1,28 @@
<a name="1.3.0"></a>
# [1.3.0](https://github.com/valor-software/ng2-file-upload/compare/v1.2.0...v1.3.0) (2017-11-25)
### Features
* **file-upload:** Add response and function to modify the request body ([#901](https://github.com/valor-software/ng2-file-upload/pull/901))
* **file-upload** add file type .zip ([#911](https://github.com/valor-software/ng2-file-upload/pull/911))
### Bug Fixes
* **file-uploader** Update: setOptions ([#904](https://github.com/valor-software/ng2-file-upload/pull/904))
* **docs** Fix correct path for isHTML5 option ([#844](https://github.com/valor-software/ng2-file-upload/pull/844))
* **docs** Added onFileDrop() event to documentation ([#857](https://github.com/valor-software/ng2-file-upload/pull/857))
<a name="1.2.1"></a>
## [1.2.1](https://github.com/valor-software/ng2-file-upload/compare/v1.2.0...v1.2.1) (2017-04-10)
### Features
* **package:** relaxed peer dependencies to allow ng v4 ([#713](https://github.com/valor-software/ng2-file-upload/issues/713)) ([7704e0e](https://github.com/valor-software/ng2-file-upload/commit/7704e0e))
<a name="1.2.0"></a>
# [1.2.0](https://github.com/valor-software/ng2-file-upload/compare/v1.1.3-0...v1.2.0) (2017-01-17)

View File

@@ -18,6 +18,30 @@ Easy to use Angular2 directives for files upload ([demo](http://valor-software.g
3. More information regarding using of ***ng2-file-upload*** is located in
[demo](http://valor-software.github.io/ng2-file-upload/) and [demo sources](https://github.com/valor-software/ng2-file-upload/tree/master/demo).
## Using ***ng2-file-upload*** in a project
1. Install as shown in the above section.
2. Import `FileUploadModule` into the module that declares the component using ***ng2-file-upload***:
```import { FileUploadModule } from 'ng2-file-upload';```
3. Add it to `[imports]` under `@NgModule`:
```imports: [ ... FileUploadModule, ... ]```
4. Import `FileUploader` into the component:
```import { FileUploader } from 'ng2-file-upload';```
5. Create a variable for the API url:
```const URL = 'path_to_api';```
6. Initialize it:
```public uploader:FileUploader = new FileUploader({url: URL}); ```
## API for `ng2FileSelect`
@@ -25,6 +49,9 @@ Easy to use Angular2 directives for files upload ([demo](http://valor-software.g
- `uploader` - (`FileUploader`) - uploader object. See using in [demo](https://github.com/valor-software/ng2-file-upload/blob/master/demo/components/file-upload/simple-demo.ts)
### Events
- `onFileSelected` - fires when files are selected and added to the uploader queue
## API for `ng2FileDrop`
### Properties
@@ -36,17 +63,21 @@ Easy to use Angular2 directives for files upload ([demo](http://valor-software.g
1. `url` - URL of File Uploader's route
2. `authToken` - Auth token that will be applied as 'Authorization' header during file send.
3. `disableMultipart` - If 'true', disable using a multipart form for file upload and instead stream the file. Some APIs (e.g. Amazon S3) may expect the file to be streamed rather than sent via a form. Defaults to false.
4. `itemAlias` - item alias (form name redefenition)
4. `itemAlias` - item alias (form name redefinition)
5. `formatDataFunction` - Function to modify the request body. 'DisableMultipart' must be 'true' for this function to be called.
6. `formatDataFunctionIsAsync` - Informs if the function sent in 'formatDataFunction' is asynchronous. Defaults to false.
7. `parametersBeforeFiles` - States if additional parameters should be appended before or after the file. Defaults to false.
### Events
- `fileOver` - it fires during 'over' and 'out' events for Drop Area; returns `boolean`: `true` if file is over Drop Area, `false` in case of out.
See using in [ts demo](https://github.com/valor-software/ng2-file-upload/blob/master/demo/components/file-upload/simple-demo.ts) and
[html demo](https://github.com/valor-software/ng2-file-upload/blob/master/demo/components/file-upload/simple-demo.html)
- `onFileDrop` - it fires after a file has been dropped on a Drop Area; you can pass in `$event` to get the list of files that were dropped. i.e. `(onFileDrop)="dropped($event)"`
# Troubleshooting
Please follow this guidelines when reporting bugs and feature requests:
Please follow these guidelines when reporting bugs and feature requests:
1. Use [GitHub Issues](https://github.com/valor-software/ng2-file-upload/issues) board to report bugs and feature requests (not our email address)
2. Please **always** write steps to reproduce the error. That way we can focus on fixing the bug, not scratching our heads trying to reproduce it.

View File

@@ -1,57 +0,0 @@
{
"project": {
"name": "ng2-file-upload"
},
"apps": [
{
"root": "demo/src",
"outDir": "demo/dist",
"assets": [
"assets"
],
"index": "index.html",
"main": "main.ts",
"test": "../../scripts/test.ts",
"tsconfig": "tsconfig.json",
"prefix": "",
"mobile": false,
"styles": [
],
"scripts": [
],
"environments": {
"source": "environments/environment.ts",
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
}
],
"addons": [],
"packages": [],
"e2e": {
"protractor": {
"config": "protractor.conf.js"
}
},
"test": {
"karma": {
"config": "karma.conf.js"
}
},
"defaults": {
"styleExt": "css",
"prefixInterfaces": false,
"inline": {
"style": false,
"template": false
},
"spec": {
"class": false,
"component": true,
"directive": true,
"module": false,
"pipe": true,
"service": true
}
}
}

112
angular.json Normal file
View File

@@ -0,0 +1,112 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"ng2-file-upload": {
"root": ".",
"sourceRoot": "src",
"projectType": "library",
"architect": {
"build": {
"builder": "@angular-devkit/build-ng-packagr:build",
"options": {
"tsConfig": "src/tsconfig.json",
"project": "src/ng-package.json"
}
}
}
},
"ng2-file-upload-demo": {
"root": "demo",
"sourceRoot": "demo/src",
"projectType": "application",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "demo/dist",
"index": "demo/src/index.html",
"main": "demo/src/main.ts",
"tsConfig": "demo/src/tsconfig.json",
"assets": [
"demo/src/assets"
],
"styles": [],
"scripts": []
},
"configurations": {
"production": {
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"fileReplacements": [
{
"replace": "demo/src/environments/environment.ts",
"with": "demo/src/environments/environment.prod.ts"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "ng2-file-upload-demo:build"
},
"configurations": {
"production": {
"browserTarget": "ng2-file-upload-demo:build:production"
}
}
}
}
},
"ng2-file-upload-test": {
"root": ".",
"sourceRoot": "test",
"projectType": "library",
"architect": {
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "test/test.ts",
"karmaConfig": "test/karma.conf.js",
"scripts": [],
"styles": [],
"tsConfig": "test/tsconfig.json"
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.json",
"demo/src/tsconfig.json",
"test/tsconfig.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "ng2-file-upload-demo",
"schematics": {
"@schematics/angular:component": {
"prefix": "",
"styleext": "css"
},
"@schematics/angular:directive": {
"prefix": ""
}
}
}

12
demo/browserslist Normal file
View File

@@ -0,0 +1,12 @@
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
# You can see what browsers were selected by your queries by running:
# npx browserslist
> 0.5%
last 2 versions
Firefox ESR
not dead
not IE 9-11 # For IE 9-11 support, remove 'not'.

View File

@@ -3,7 +3,7 @@ import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { TabsModule } from 'ng2-bootstrap';
import { TabsModule } from 'ngx-bootstrap/tabs';
import { FileUploadModule } from 'ng2-file-upload';
import { AppComponent } from './app.component';

View File

@@ -5,9 +5,9 @@ let doc = require('html-loader!markdown-loader!../../doc.md');
let tabDesc:Array<any> = [
{
heading: 'Simple',
ts: require('!!raw-loader?lang=typescript!./file-upload/simple-demo.ts'),
html: require('!!raw-loader?lang=markup!./file-upload/simple-demo.html'),
js: require('!!raw-loader?lang=javascript!./file-upload/file-catcher.js')
ts: require('!!raw-loader!./file-upload/simple-demo.ts').default,
html: require('!!raw-loader!./file-upload/simple-demo.html').default,
js: require('!!raw-loader!./file-upload/file-catcher.js').default
}
];

View File

@@ -61,8 +61,8 @@
<tbody>
<tr *ngFor="let item of uploader.queue">
<td><strong>{{ item?.file?.name }}</strong></td>
<td *ngIf="uploader.isHTML5" nowrap>{{ item?.file?.size/1024/1024 | number:'.2' }} MB</td>
<td *ngIf="uploader.isHTML5">
<td *ngIf="uploader.options.isHTML5" nowrap>{{ item?.file?.size/1024/1024 | number:'.2' }} MB</td>
<td *ngIf="uploader.options.isHTML5">
<div class="progress" style="margin-bottom: 0;">
<div class="progress-bar" role="progressbar" [ngStyle]="{ 'width': item.progress + '%' }"></div>
</div>
@@ -115,4 +115,16 @@
</div>
<br><br>
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">Response</div>
<div class="panel-body">
{{ response }}
</div>
</div>
</div>
</div>
</div>

View File

@@ -9,9 +9,36 @@ const URL = 'https://evening-anchorage-3159.herokuapp.com/api/';
templateUrl: './simple-demo.html'
})
export class SimpleDemoComponent {
public uploader:FileUploader = new FileUploader({url: URL});
public hasBaseDropZoneOver:boolean = false;
public hasAnotherDropZoneOver:boolean = false;
uploader:FileUploader;
hasBaseDropZoneOver:boolean;
hasAnotherDropZoneOver:boolean;
response:string;
constructor (){
this.uploader = new FileUploader({
url: URL,
disableMultipart: true, // 'DisableMultipart' must be 'true' for formatDataFunction to be called.
formatDataFunctionIsAsync: true,
formatDataFunction: async (item) => {
return new Promise( (resolve, reject) => {
resolve({
name: item._file.name,
length: item._file.size,
contentType: item._file.type,
date: new Date()
});
});
}
});
this.hasBaseDropZoneOver = false;
this.hasAnotherDropZoneOver = false;
this.response = '';
this.uploader.response.subscribe( res => this.response = res );
}
public fileOverBase(e:any):void {
this.hasBaseDropZoneOver = e;

View File

@@ -25,6 +25,13 @@ import { FileSelectDirective, FileDropDirective, FileUploader } from 'ng2-file-u
1. `url` - URL of File Uploader's route
2. `authToken` - auth token that will be applied as 'Authorization' header during file send.
3. `disableMultipart` - If 'true', disable using a multipart form for file upload and instead stream the file. Some APIs (e.g. Amazon S3) may expect the file to be streamed rather than sent via a form. Defaults to false.
4. `itemAlias` - item alias (form name redefenition)
5. `formatDataFunction` - Function to modify the request body. 'DisableMultipart' must be 'true' for this function to be called.
6. `formatDataFunctionIsAsync` - Informs if the function sent in 'formatDataFunction' is asynchronous. Defaults to false.
7. `parametersBeforeFiles` - States if additional parameters should be appended before or after the file. Defaults to false.
### Events
- `onFileSelected` - fires when files are selected and added to the uploader queue
## FileDrop API
@@ -37,3 +44,4 @@ import { FileSelectDirective, FileDropDirective, FileUploader } from 'ng2-file-u
- `fileOver` - it fires during 'over' and 'out' events for Drop Area; returns `boolean`: `true` if file is over Drop Area, `false` in case of out.
See using in [ts demo](https://github.com/valor-software/ng2-file-upload/blob/master/demo/components/file-upload/simple-demo.ts) and
[html demo](https://github.com/valor-software/ng2-file-upload/blob/master/demo/components/file-upload/simple-demo.html)
- `onFileDrop` - it fires after a file has been dropped on a Drop Area; you can pass in `$event` to get the list of files that were dropped. i.e. `(onFileDrop)="dropped($event)"`

View File

@@ -1,4 +1,4 @@
import './polyfills.ts';
import '../../scripts/polyfills.ts';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';

View File

@@ -1,22 +1,25 @@
{
"compilerOptions": {
"baseUrl": ".",
"declaration": false,
"downlevelIteration": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"noEmitHelpers" :true,
"noEmitHelpers": false,
"lib": ["es6", "dom"],
"types": [
"jasmine",
"webpack"
],
"mapRoot": "./",
"module": "es6",
"module": "esnext",
"moduleResolution": "node",
"outDir": "../temp/out-tsc",
"sourceMap": true,
"target": "es5",
"typeRoots": [
"../node_modules/@types"
]
}
"target": "es2015"
},
"files": [
"../../scripts/typings.d.ts",
"main.ts",
"../../scripts/polyfills.ts"
],
"exclude": [
"**/*.spec.ts"
]
}

16
demo/src/typings.d.ts vendored
View File

@@ -1,16 +0,0 @@
// Typings reference file, you can add your own global typings here
// https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html
// tslint:disable
declare const System: any;
declare const ENV:string;
// google code-prettify
declare const PR:any;
declare const require:any;
declare const global:any;
declare module jasmine {
interface Matchers {
toHaveCssClass(expected: any): boolean;
}
}

18533
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,30 +1,27 @@
{
"name": "ng2-file-upload-base",
"version": "1.2.0",
"version": "1.3.0",
"private": true,
"description": "Angular file upload directives",
"scripts": {
"lite-server": "lite-server -c demo/bs-config.json",
"demo.serve": "run-s build link demo.build lite-server",
"demo.gh-pages": "run-s build demo.build demo.deploy",
"demo.build": "ng build -prod --aot",
"demo.build": "ng build ng2-file-upload-demo --prod",
"demo.deploy": "gh-pages -d demo/dist",
"link": "ngm link -p src --here",
"link": "cd dist/ng2-file-upload/ && npm link && cd ../../ && npm link ng2-file-upload",
"lint": "exit 0",
"disable-lint": "tslint \"**/*.ts\" -c tslint.json --fix --type-check -t prose -e \"node_modules/**\" -e \"dist/**\" -e \"temp/**\" -e \"scripts/docs/**\"",
"flow.changelog": "conventional-changelog -i CHANGELOG.md -s -p angular",
"flow.github-release": "conventional-github-releaser -p angular",
"build": "ngm build -p src --clean",
"build.watch": "ngm build -p src --watch --skip-bundles",
"start": "ng serve --aot",
"build": "ng build ng2-file-upload",
"build.watch": "ng build ng2-file-upload --watch",
"start": "ng serve ng2-file-upload-demo --aot",
"pretest": "run-s lint build link",
"test": "ng test -sr",
"test-coverage": "ng test -sr -cc",
"test": "ng test ng2-file-upload-test",
"test-coverage": "ng test ng2-file-upload-test --code-coverage",
"version": "npm run flow.changelog && git add -A"
},
"main": "bundles/ng2-file-upload.umd.js",
"module": "index.js",
"typings": "index.d.ts",
"keywords": [
"angular2",
"bootstrap",
@@ -43,34 +40,29 @@
"url": "https://github.com/valor-software/ng2-file-upload/issues"
},
"homepage": "https://github.com/valor-software/ng2-file-upload#readme",
"dependencies": {},
"peerDependencies": {
"@angular/common": "^2.3.0",
"@angular/core": "^2.3.0"
},
"peerDependencies": {},
"devDependencies": {
"@angular/common": "2.4.3",
"@angular/compiler": "2.4.3",
"@angular/compiler-cli": "2.4.3",
"@angular/core": "2.4.3",
"@angular/forms": "2.4.3",
"@angular/http": "2.4.3",
"@angular/language-service": "2.4.3",
"@angular/platform-browser": "2.4.3",
"@angular/platform-browser-dynamic": "2.4.3",
"@angular/router": "3.4.3",
"@angular/tsc-wrapped": "0.5.1",
"@ngtools/webpack": "1.2.3",
"@angular-devkit/build-angular": "~0.803.0",
"@angular-devkit/build-ng-packagr": "^0.803.0",
"@angular/cli": "^8.3.0",
"@angular/common": "^8.2.3",
"@angular/compiler": "^8.2.3",
"@angular/compiler-cli": "^8.2.3",
"@angular/core": "^8.2.3",
"@angular/forms": "^8.2.3",
"@angular/language-service": "8.2.3",
"@angular/platform-browser": "^8.2.3",
"@angular/platform-browser-dynamic": "^8.2.3",
"@angular/router": "^8.2.3",
"@types/jasmine": "2.5.40",
"@types/marked": "0.0.28",
"@types/node": "7.0.0",
"@types/webpack": "^2.2.1",
"angular-cli": "1.0.0-beta.25.5",
"@types/webpack": "^3.8.18",
"bootstrap": "3.3.7",
"chokidar-cli": "1.2.0",
"classlist-polyfill": "1.0.3",
"codecov": "1.0.1",
"codelyzer": "~2.0.0-beta.4",
"codelyzer": "^5.0.1",
"conventional-changelog-cli": "1.2.0",
"conventional-github-releaser": "1.1.3",
"core-js": "^2.4.1",
@@ -80,40 +72,41 @@
"gh-pages": "0.12.0",
"gitignore-to-glob": "0.3.0",
"google-code-prettify": "1.0.5",
"html-loader": "0.4.4",
"jasmine": "2.5.3",
"jasmine-core": "2.5.2",
"html-loader": "^0.5.5",
"jasmine-core": "3.1.0",
"jasmine-data-provider": "2.2.0",
"jasmine-spec-reporter": "3.2.0",
"karma": "1.4.0",
"karma-chrome-launcher": "^2.0.0",
"jasmine-spec-reporter": "4.2.1",
"karma": "4.1.0",
"karma-chrome-launcher": "2.2.0",
"karma-cli": "^1.0.1",
"karma-jasmine": "^1.0.2",
"karma-remap-istanbul": "0.4.0",
"karma-sauce-launcher": "1.1.0",
"karma-coverage-istanbul-reporter": "1.4.3",
"karma-jasmine": "1.1.2",
"karma-remap-istanbul": "0.6.0",
"karma-sauce-launcher": "1.2.0",
"lite-server": "2.2.2",
"lodash": "4.17.4",
"markdown-loader": "^0.1.7",
"markdown-loader": "^5.1.0",
"marked": "0.3.6",
"ng2-bootstrap": "1.2.2",
"ng2-page-scroll": "4.0.0-beta.2",
"ngm-cli": "0.4.0",
"ng-packagr": "^5.5.0",
"ngx-bootstrap": "1.6.6",
"npm-run-all": "^4.0.1",
"pre-commit": "1.2.2",
"protractor": "5.0.0",
"raw-loader": "^3.1.0",
"reflect-metadata": "0.1.9",
"require-dir": "0.3.1",
"rxjs": "5.0.3",
"rxjs": "^6.5.2",
"systemjs-builder": "0.15.34",
"ts-helpers": "^1.1.1",
"ts-node": "2.0.0",
"tslint": "4.3.1",
"tslint-config-valorsoft": "1.2.0",
"tsickle": "^0.37.0",
"tslint": "^5.19.0",
"tslint-config-valorsoft": "^2.2.1",
"typedoc": "0.5.5",
"typescript": "2.1.5",
"typescript": "3.5.3",
"wallaby-webpack": "0.0.30",
"webdriver-manager": "11.1.1",
"zone.js": "0.7.5"
"zone.js": "~0.9.1"
},
"contributors": [
{
@@ -136,5 +129,8 @@
"email": "otelnov@gmail.com",
"url": "https://github.com/otelnov"
}
]
],
"dependencies": {
"tslib": "^1.10.0"
}
}

1
scripts/.gitignore vendored
View File

@@ -1 +0,0 @@
!**/*.js

View File

@@ -8,7 +8,7 @@ declare const ENV:string;
// google code-prettify
declare const PR:any;
declare const global:any;
// declare const global:any;
declare module jasmine {
interface Matchers {

View File

@@ -1,29 +1,29 @@
import { Directive, EventEmitter, ElementRef, HostListener, Input, Output } from '@angular/core';
import { FileUploader } from './file-uploader.class';
import { FileUploader, FileUploaderOptions } from './file-uploader.class';
@Directive({selector: '[ng2FileDrop]'})
@Directive({ selector: '[ng2FileDrop]' })
export class FileDropDirective {
@Input() public uploader:FileUploader;
@Output() public fileOver:EventEmitter<any> = new EventEmitter();
@Output() public onFileDrop:EventEmitter<File[]> = new EventEmitter<File[]>();
@Input() public uploader: FileUploader;
@Output() public fileOver: EventEmitter<any> = new EventEmitter();
@Output() public onFileDrop: EventEmitter<File[]> = new EventEmitter<File[]>();
protected element:ElementRef;
protected element: ElementRef;
public constructor(element:ElementRef) {
public constructor(element: ElementRef) {
this.element = element;
}
public getOptions():any {
public getOptions(): FileUploaderOptions {
return this.uploader.options;
}
public getFilters():any {
public getFilters(): any {
return {};
}
@HostListener('drop', ['$event'])
public onDrop(event:any):void {
@HostListener('drop', [ '$event' ])
public onDrop(event: any): void {
let transfer = this._getTransfer(event);
if (!transfer) {
return;
@@ -37,8 +37,8 @@ export class FileDropDirective {
this.onFileDrop.emit(transfer.files);
}
@HostListener('dragover', ['$event'])
public onDragOver(event:any):void {
@HostListener('dragover', [ '$event' ])
public onDragOver(event: any): void {
let transfer = this._getTransfer(event);
if (!this._haveFiles(transfer.types)) {
return;
@@ -49,10 +49,10 @@ export class FileDropDirective {
this.fileOver.emit(true);
}
@HostListener('dragleave', ['$event'])
public onDragLeave(event:any):any {
@HostListener('dragleave', [ '$event' ])
public onDragLeave(event: any): any {
if ((this as any).element) {
if (event.currentTarget === (this as any).element[0]) {
if (event.currentTarget === (this as any).element[ 0 ]) {
return;
}
}
@@ -61,16 +61,16 @@ export class FileDropDirective {
this.fileOver.emit(false);
}
protected _getTransfer(event:any):any {
protected _getTransfer(event: any): any {
return event.dataTransfer ? event.dataTransfer : event.originalEvent.dataTransfer; // jQuery fix;
}
protected _preventAndStop(event:any):any {
protected _preventAndStop(event: any): any {
event.preventDefault();
event.stopPropagation();
}
protected _haveFiles(types:any):any {
protected _haveFiles(types: any): any {
if (!types) {
return false;
}
@@ -83,13 +83,4 @@ export class FileDropDirective {
return false;
}
}
/*
_addOverClass(item:any):any {
item.addOverClass();
}
_removeOverClass(item:any):any {
item.removeOverClass();
}*/
}

View File

@@ -2,30 +2,30 @@ import { FileLikeObject } from './file-like-object.class';
import { FileUploader, ParsedResponseHeaders, FileUploaderOptions } from './file-uploader.class';
export class FileItem {
public file:FileLikeObject;
public _file:File;
public alias:string;
public url:string = '/';
public method:string;
public headers:any = [];
public withCredentials:boolean = true;
public formData:any = [];
public isReady:boolean = false;
public isUploading:boolean = false;
public isUploaded:boolean = false;
public isSuccess:boolean = false;
public isCancel:boolean = false;
public isError:boolean = false;
public progress:number = 0;
public index:number = void 0;
public _xhr:XMLHttpRequest;
public _form:any;
public file: FileLikeObject;
public _file: File;
public alias: string;
public url: string = '/';
public method: string;
public headers: any = [];
public withCredentials: boolean = true;
public formData: any = [];
public isReady: boolean = false;
public isUploading: boolean = false;
public isUploaded: boolean = false;
public isSuccess: boolean = false;
public isCancel: boolean = false;
public isError: boolean = false;
public progress: number = 0;
public index: number = void 0;
public _xhr: XMLHttpRequest;
public _form: any;
protected uploader:FileUploader;
protected some:File;
protected options:FileUploaderOptions;
protected uploader: FileUploader;
protected some: File;
protected options: FileUploaderOptions;
public constructor(uploader:FileUploader, some:File, options:FileUploaderOptions) {
public constructor(uploader: FileUploader, some: File, options: FileUploaderOptions) {
this.uploader = uploader;
this.some = some;
this.options = options;
@@ -38,7 +38,7 @@ export class FileItem {
this.url = uploader.options.url;
}
public upload():void {
public upload(): void {
try {
this.uploader.uploadItem(this);
} catch (e) {
@@ -47,43 +47,43 @@ export class FileItem {
}
}
public cancel():void {
public cancel(): void {
this.uploader.cancelItem(this);
}
public remove():void {
public remove(): void {
this.uploader.removeFromQueue(this);
}
public onBeforeUpload():void {
public onBeforeUpload(): void {
return void 0;
}
public onBuildForm(form:any):any {
return {form};
public onBuildForm(form: any): any {
return { form };
}
public onProgress(progress:number):any {
return {progress};
public onProgress(progress: number): any {
return { progress };
}
public onSuccess(response:string, status:number, headers:ParsedResponseHeaders):any {
return {response, status, headers};
public onSuccess(response: string, status: number, headers: ParsedResponseHeaders): any {
return { response, status, headers };
}
public onError(response:string, status:number, headers:ParsedResponseHeaders):any {
return {response, status, headers};
public onError(response: string, status: number, headers: ParsedResponseHeaders): any {
return { response, status, headers };
}
public onCancel(response:string, status:number, headers:ParsedResponseHeaders):any {
return {response, status, headers};
public onCancel(response: string, status: number, headers: ParsedResponseHeaders): any {
return { response, status, headers };
}
public onComplete(response:string, status:number, headers:ParsedResponseHeaders):any {
return {response, status, headers};
public onComplete(response: string, status: number, headers: ParsedResponseHeaders): any {
return { response, status, headers };
}
public _onBeforeUpload():void {
public _onBeforeUpload(): void {
this.isReady = true;
this.isUploading = true;
this.isUploaded = false;
@@ -94,16 +94,16 @@ export class FileItem {
this.onBeforeUpload();
}
public _onBuildForm(form:any):void {
public _onBuildForm(form: any): void {
this.onBuildForm(form);
}
public _onProgress(progress:number):void {
public _onProgress(progress: number): void {
this.progress = progress;
this.onProgress(progress);
}
public _onSuccess(response:string, status:number, headers:ParsedResponseHeaders):void {
public _onSuccess(response: string, status: number, headers: ParsedResponseHeaders): void {
this.isReady = false;
this.isUploading = false;
this.isUploaded = true;
@@ -115,7 +115,7 @@ export class FileItem {
this.onSuccess(response, status, headers);
}
public _onError(response:string, status:number, headers:ParsedResponseHeaders):void {
public _onError(response: string, status: number, headers: ParsedResponseHeaders): void {
this.isReady = false;
this.isUploading = false;
this.isUploaded = true;
@@ -127,7 +127,7 @@ export class FileItem {
this.onError(response, status, headers);
}
public _onCancel(response:string, status:number, headers:ParsedResponseHeaders):void {
public _onCancel(response: string, status: number, headers: ParsedResponseHeaders): void {
this.isReady = false;
this.isUploading = false;
this.isUploaded = false;
@@ -139,7 +139,7 @@ export class FileItem {
this.onCancel(response, status, headers);
}
public _onComplete(response:string, status:number, headers:ParsedResponseHeaders):void {
public _onComplete(response: string, status: number, headers: ParsedResponseHeaders): void {
this.onComplete(response, status, headers);
if (this.uploader.options.removeAfterUpload) {
@@ -147,7 +147,7 @@ export class FileItem {
}
}
public _prepareToUploading():void {
public _prepareToUploading(): void {
this.index = this.index || ++this.uploader._nextIndex;
this.isReady = true;
}

View File

@@ -1,30 +1,31 @@
function isElement(node:any):boolean {
function isElement(node: any): boolean {
return !!(node && (node.nodeName || node.prop && node.attr && node.find));
}
export class FileLikeObject {
public lastModifiedDate:any;
public size:any;
public type:string;
public name:string;
public lastModifiedDate: any;
public size: any;
public type: string;
public name: string;
public rawFile: string;
public constructor(fileOrInput:any) {
public constructor(fileOrInput: any) {
this.rawFile = fileOrInput;
let isInput = isElement(fileOrInput);
let fakePathOrObject = isInput ? fileOrInput.value : fileOrInput;
let postfix = typeof fakePathOrObject === 'string' ? 'FakePath' : 'Object';
let method = '_createFrom' + postfix;
(this as any)[method](fakePathOrObject);
(this as any)[ method ](fakePathOrObject);
}
public _createFromFakePath(path:string):void {
public _createFromFakePath(path: string): void {
this.lastModifiedDate = void 0;
this.size = void 0;
this.type = 'like/' + path.slice(path.lastIndexOf('.') + 1).toLowerCase();
this.name = path.slice(path.lastIndexOf('/') + path.lastIndexOf('\\') + 2);
}
public _createFromObject(object:{size:number, type:string, name:string}):void {
// this.lastModifiedDate = copy(object.lastModifiedDate);
public _createFromObject(object: { size: number, type: string, name: string }): void {
this.size = object.size;
this.type = object.type;
this.name = object.name;

View File

@@ -1,46 +1,41 @@
import { Directive, ElementRef, Input, HostListener } from '@angular/core';
import { Directive, EventEmitter, ElementRef, Input, HostListener, Output } from '@angular/core';
import { FileUploader } from './file-uploader.class';
// todo: filters
@Directive({selector: '[ng2FileSelect]'})
@Directive({ selector: '[ng2FileSelect]' })
export class FileSelectDirective {
@Input() public uploader:FileUploader;
@Input() public uploader: FileUploader;
@Output() public onFileSelected: EventEmitter<File[]> = new EventEmitter<File[]>();
protected element:ElementRef;
protected element: ElementRef;
public constructor(element:ElementRef) {
public constructor(element: ElementRef) {
this.element = element;
}
public getOptions():any {
public getOptions(): any {
return this.uploader.options;
}
public getFilters():any {
return void 0;
public getFilters(): any {
return {};
}
public isEmptyAfterSelection():boolean {
public isEmptyAfterSelection(): boolean {
return !!this.element.nativeElement.attributes.multiple;
}
@HostListener('change')
public onChange():any {
// let files = this.uploader.isHTML5 ? this.element.nativeElement[0].files : this.element.nativeElement[0];
public onChange(): any {
let files = this.element.nativeElement.files;
let options = this.getOptions();
let filters = this.getFilters();
// if(!this.uploader.isHTML5) this.destroy();
this.uploader.addToQueue(files, options, filters);
this.onFileSelected.emit(files);
if (this.isEmptyAfterSelection()) {
// todo
this.element.nativeElement.value = '';
/*this.element.nativeElement
.replaceWith(this.element = this.element.nativeElement.clone(true)); // IE fix*/
}
}
}

View File

@@ -1,6 +1,8 @@
import { FileLikeObject } from "../index";
export class FileType {
/* MS office */
public static mime_doc:string[] = [
public static mime_doc: string[] = [
'application/msword',
'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
@@ -8,7 +10,7 @@ export class FileType {
'application/vnd.ms-word.document.macroEnabled.12',
'application/vnd.ms-word.template.macroEnabled.12'
];
public static mime_xsl:string[] = [
public static mime_xsl: string[] = [
'application/vnd.ms-excel',
'application/vnd.ms-excel',
'application/vnd.ms-excel',
@@ -19,7 +21,7 @@ export class FileType {
'application/vnd.ms-excel.addin.macroEnabled.12',
'application/vnd.ms-excel.sheet.binary.macroEnabled.12'
];
public static mime_ppt:string[] = [
public static mime_ppt: string[] = [
'application/vnd.ms-powerpoint',
'application/vnd.ms-powerpoint',
'application/vnd.ms-powerpoint',
@@ -34,7 +36,7 @@ export class FileType {
];
/* PSD */
public static mime_psd:string[] = [
public static mime_psd: string[] = [
'image/photoshop',
'image/x-photoshop',
'image/psd',
@@ -44,16 +46,21 @@ export class FileType {
];
/* Compressed files */
public static mime_compress:string[] = [
public static mime_compress: string[] = [
'application/x-gtar',
'application/x-gcompress',
'application/compress',
'application/x-tar',
'application/x-rar-compressed',
'application/octet-stream'
'application/octet-stream',
'application/x-zip-compressed',
'application/zip-compressed',
'application/x-7z-compressed',
'application/gzip',
'application/x-bzip2'
];
public static getMimeClass(file:any):string {
public static getMimeClass(file: FileLikeObject): string {
let mimeClass = 'application';
if (this.mime_psd.indexOf(file.type) !== -1) {
mimeClass = 'image';
@@ -81,8 +88,8 @@ export class FileType {
return mimeClass;
}
public static fileTypeDetection(inputFilename:string):string {
let types:{[key:string]:string} = {
public static fileTypeDetection(inputFilename: string): string {
let types: { [ key: string ]: string } = {
'jpg': 'image',
'jpeg': 'image',
'tif': 'image',
@@ -107,14 +114,18 @@ export class FileType {
'mod': 'audio',
'm4a': 'audio',
'compress': 'compress',
'zip': 'compress',
'rar': 'compress',
'7z': 'compress',
'lz': 'compress',
'z01': 'compress',
'bz2': 'compress',
'gz': 'compress',
'pdf': 'pdf',
'xls': 'xls',
'xlsx': 'xls',
'ods': 'xls',
'csv': 'xls',
'mp4': 'video',
'avi': 'video',
'wmv': 'video',
@@ -144,11 +155,11 @@ export class FileType {
if (chunks.length < 2) {
return 'application';
}
let extension = chunks[chunks.length - 1].toLowerCase();
if (types[extension] === undefined) {
let extension = chunks[ chunks.length - 1 ].toLowerCase();
if (types[ extension ] === undefined) {
return 'application';
} else {
return types[extension];
return types[ extension ];
}
}
}

View File

@@ -5,9 +5,9 @@ import { FileDropDirective } from './file-drop.directive';
import { FileSelectDirective } from './file-select.directive';
@NgModule({
imports: [CommonModule],
declarations: [FileDropDirective, FileSelectDirective],
exports: [FileDropDirective, FileSelectDirective]
imports: [ CommonModule ],
declarations: [ FileDropDirective, FileSelectDirective ],
exports: [ FileDropDirective, FileSelectDirective ]
})
export class FileUploadModule {
}

View File

@@ -1,112 +1,122 @@
import { EventEmitter } from '@angular/core';
import { FileLikeObject } from './file-like-object.class';
import { FileItem } from './file-item.class';
import { FileType } from './file-type.class';
function isFile(value:any):boolean {
function isFile(value: any): boolean {
return (File && value instanceof File);
}
// function isFileLikeObject(value:any) {
export interface Headers {
name:string;
value:string;
name: string;
value: string;
}
export type ParsedResponseHeaders = {[headerFieldName:string]:string};
export type ParsedResponseHeaders = { [ headerFieldName: string ]: string };
export type FilterFunction = {name:string, fn:(item?:FileLikeObject, options?:FileUploaderOptions)=>boolean|Promise<boolean>};
export type FilterFunction = {
name: string,
fn: (item?: FileLikeObject, options?: FileUploaderOptions) => boolean
};
export interface FileUploaderOptions {
allowedMimeType?:Array<string>;
allowedFileType?:Array<string>;
autoUpload?:boolean;
isHTML5?:boolean;
filters?:Array<FilterFunction>;
headers?:Array<Headers>;
method?:string;
authToken?:string;
maxFileSize?:number;
queueLimit?:number;
removeAfterUpload?:boolean;
url?:string;
disableMultipart?:boolean;
allowedMimeType?: string[];
allowedFileType?: string[];
autoUpload?: boolean;
isHTML5?: boolean;
filters?: FilterFunction[];
headers?: Headers[];
method?: string;
authToken?: string;
maxFileSize?: number;
queueLimit?: number;
removeAfterUpload?: boolean;
url?: string;
disableMultipart?: boolean;
itemAlias?: string;
authTokenHeader?: string;
additionalParameter?:{[key: string]: any};
additionalParameter?: { [ key: string ]: any };
parametersBeforeFiles?: boolean;
formatDataFunction?: Function;
formatDataFunctionIsAsync?: boolean;
}
export class FileUploader {
public authToken:string;
public isUploading:boolean = false;
public queue:Array<FileItem> = [];
public progress:number = 0;
public _nextIndex:number = 0;
public autoUpload:any;
public authToken: string;
public isUploading: boolean = false;
public queue: FileItem[] = [];
public progress: number = 0;
public _nextIndex: number = 0;
public autoUpload: any;
public authTokenHeader: string;
public response: EventEmitter<any>;
public options:FileUploaderOptions = {
public options: FileUploaderOptions = {
autoUpload: false,
isHTML5: true,
filters: [],
removeAfterUpload: false,
disableMultipart: false
disableMultipart: false,
formatDataFunction: (item: FileItem) => item._file,
formatDataFunctionIsAsync: false
};
protected _failFilterIndex:number;
protected _failFilterIndex: number;
public constructor(options:FileUploaderOptions) {
public constructor(options: FileUploaderOptions) {
this.setOptions(options);
this.response = new EventEmitter<any>();
}
public setOptions(options:FileUploaderOptions):void {
public setOptions(options: FileUploaderOptions): void {
this.options = Object.assign(this.options, options);
this.authToken = options.authToken;
this.authTokenHeader = options.authTokenHeader || 'Authorization';
this.autoUpload = options.autoUpload;
this.options.filters.unshift({name: 'queueLimit', fn: this._queueLimitFilter});
this.authToken = this.options.authToken;
this.authTokenHeader = this.options.authTokenHeader || 'Authorization';
this.autoUpload = this.options.autoUpload;
this.options.filters.unshift({ name: 'queueLimit', fn: this._queueLimitFilter });
if (this.options.maxFileSize) {
this.options.filters.unshift({name: 'fileSize', fn: this._fileSizeFilter});
this.options.filters.unshift({ name: 'fileSize', fn: this._fileSizeFilter });
}
if (this.options.allowedFileType) {
this.options.filters.unshift({name: 'fileType', fn: this._fileTypeFilter});
this.options.filters.unshift({ name: 'fileType', fn: this._fileTypeFilter });
}
if (this.options.allowedMimeType) {
this.options.filters.unshift({name: 'mimeType', fn: this._mimeTypeFilter});
this.options.filters.unshift({ name: 'mimeType', fn: this._mimeTypeFilter });
}
for(let i = 0; i < this.queue.length; i++) {
this.queue[i].url = this.options.url;
for (let i = 0; i < this.queue.length; i++) {
this.queue[ i ].url = this.options.url;
}
// this.options.filters.unshift({name: 'folder', fn: this._folderFilter});
}
public addToQueue(files:File[], options?:FileUploaderOptions, filters?:FilterFunction[]|string):void {
let list:File[] = [];
public addToQueue(files: File[], options?: FileUploaderOptions, filters?: FilterFunction[] | string): void {
let list: File[] = [];
for (let file of files) {
list.push(file);
}
let arrayOfFilters = this._getFilters(filters);
let count = this.queue.length;
let addedFileItems:FileItem[] = [];
list.map((some:File) => {
let addedFileItems: FileItem[] = [];
list.map((some: File) => {
if (!options) {
options = this.options;
}
let temp = new FileLikeObject(some);
this._isValidFile(temp, arrayOfFilters, options).then(() => {
if (this._isValidFile(temp, arrayOfFilters, options)) {
let fileItem = new FileItem(this, some, options);
addedFileItems.push(fileItem);
this.queue.push(fileItem);
this._onAfterAddingFile(fileItem);
}).catch(() => {
let filter = arrayOfFilters[this._failFilterIndex];
} else {
let filter = arrayOfFilters[ this._failFilterIndex ];
this._onWhenAddingFileFailed(temp, filter, options);
});
}
});
if (this.queue.length !== count) {
this._onAfterAddingAll(addedFileItems);
@@ -118,9 +128,9 @@ export class FileUploader {
}
}
public removeFromQueue(value:FileItem):void {
public removeFromQueue(value: FileItem): void {
let index = this.getIndexOfItem(value);
let item = this.queue[index];
let item = this.queue[ index ];
if (item.isUploading) {
item.cancel();
}
@@ -128,149 +138,144 @@ export class FileUploader {
this.progress = this._getTotalProgress();
}
public clearQueue():void {
public clearQueue(): void {
while (this.queue.length) {
this.queue[0].remove();
this.queue[ 0 ].remove();
}
this.progress = 0;
}
public uploadItem(value:FileItem):void {
public uploadItem(value: FileItem): void {
let index = this.getIndexOfItem(value);
let item = this.queue[index];
let item = this.queue[ index ];
let transport = this.options.isHTML5 ? '_xhrTransport' : '_iframeTransport';
item._prepareToUploading();
if (this.isUploading) {
return;
}
this.isUploading = true;
(this as any)[transport](item);
(this as any)[ transport ](item);
}
public cancelItem(value:FileItem):void {
public cancelItem(value: FileItem): void {
let index = this.getIndexOfItem(value);
let item = this.queue[index];
let item = this.queue[ index ];
let prop = this.options.isHTML5 ? item._xhr : item._form;
if (item && item.isUploading) {
prop.abort();
}
}
public uploadAll():void {
let items = this.getNotUploadedItems().filter((item:FileItem) => !item.isUploading);
public uploadAll(): void {
let items = this.getNotUploadedItems().filter((item: FileItem) => !item.isUploading);
if (!items.length) {
return;
}
items.map((item:FileItem) => item._prepareToUploading());
items[0].upload();
items.map((item: FileItem) => item._prepareToUploading());
items[ 0 ].upload();
}
public cancelAll():void {
public cancelAll(): void {
let items = this.getNotUploadedItems();
items.map((item:FileItem) => item.cancel());
items.map((item: FileItem) => item.cancel());
}
public isFile(value:any):boolean {
public isFile(value: any): boolean {
return isFile(value);
}
public isFileLikeObject(value:any):boolean {
public isFileLikeObject(value: any): boolean {
return value instanceof FileLikeObject;
}
public getIndexOfItem(value:any):number {
public getIndexOfItem(value: any): number {
return typeof value === 'number' ? value : this.queue.indexOf(value);
}
public getNotUploadedItems():Array<any> {
return this.queue.filter((item:FileItem) => !item.isUploaded);
public getNotUploadedItems(): any[] {
return this.queue.filter((item: FileItem) => !item.isUploaded);
}
public getReadyItems():Array<any> {
public getReadyItems(): any[] {
return this.queue
.filter((item:FileItem) => (item.isReady && !item.isUploading))
.sort((item1:any, item2:any) => item1.index - item2.index);
.filter((item: FileItem) => (item.isReady && !item.isUploading))
.sort((item1: any, item2: any) => item1.index - item2.index);
}
public destroy():void {
return void 0;
/*forEach(this._directives, (key) => {
forEach(this._directives[key], (object) => {
object.destroy();
});
});*/
}
public onAfterAddingAll(fileItems:any):any {
return {fileItems};
}
public onBuildItemForm(fileItem:FileItem, form:any):any {
return {fileItem, form};
}
public onAfterAddingFile(fileItem:FileItem):any {
return {fileItem};
}
public onWhenAddingFileFailed(item:FileLikeObject, filter:any, options:any):any {
return {item, filter, options};
}
public onBeforeUploadItem(fileItem:FileItem):any {
return {fileItem};
}
public onProgressItem(fileItem:FileItem, progress:any):any {
return {fileItem, progress};
}
public onProgressAll(progress:any):any {
return {progress};
}
public onSuccessItem(item:FileItem, response:string, status:number, headers:ParsedResponseHeaders):any {
return {item, response, status, headers};
}
public onErrorItem(item:FileItem, response:string, status:number, headers:ParsedResponseHeaders):any {
return {item, response, status, headers};
}
public onCancelItem(item:FileItem, response:string, status:number, headers:ParsedResponseHeaders):any {
return {item, response, status, headers};
}
public onCompleteItem(item:FileItem, response:string, status:number, headers:ParsedResponseHeaders):any {
return {item, response, status, headers};
}
public onCompleteAll():any {
public destroy(): void {
return void 0;
}
public _mimeTypeFilter(item:FileLikeObject):boolean {
public onAfterAddingAll(fileItems: any): any {
return { fileItems };
}
public onBuildItemForm(fileItem: FileItem, form: any): any {
return { fileItem, form };
}
public onAfterAddingFile(fileItem: FileItem): any {
return { fileItem };
}
public onWhenAddingFileFailed(item: FileLikeObject, filter: any, options: any): any {
return { item, filter, options };
}
public onBeforeUploadItem(fileItem: FileItem): any {
return { fileItem };
}
public onProgressItem(fileItem: FileItem, progress: any): any {
return { fileItem, progress };
}
public onProgressAll(progress: any): any {
return { progress };
}
public onSuccessItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): any {
return { item, response, status, headers };
}
public onErrorItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): any {
return { item, response, status, headers };
}
public onCancelItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): any {
return { item, response, status, headers };
}
public onCompleteItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): any {
return { item, response, status, headers };
}
public onCompleteAll(): any {
return void 0;
}
public _mimeTypeFilter(item: FileLikeObject): boolean {
return !(this.options.allowedMimeType && this.options.allowedMimeType.indexOf(item.type) === -1);
}
public _fileSizeFilter(item:FileLikeObject):boolean {
public _fileSizeFilter(item: FileLikeObject): boolean {
return !(this.options.maxFileSize && item.size > this.options.maxFileSize);
}
public _fileTypeFilter(item:FileLikeObject):boolean {
public _fileTypeFilter(item: FileLikeObject): boolean {
return !(this.options.allowedFileType &&
this.options.allowedFileType.indexOf(FileType.getMimeClass(item)) === -1);
this.options.allowedFileType.indexOf(FileType.getMimeClass(item)) === -1);
}
public _onErrorItem(item:FileItem, response:string, status:number, headers:ParsedResponseHeaders):void {
public _onErrorItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): void {
item._onError(response, status, headers);
this.onErrorItem(item, response, status, headers);
}
public _onCompleteItem(item:FileItem, response:string, status:number, headers:ParsedResponseHeaders):void {
public _onCompleteItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): void {
item._onComplete(response, status, headers);
this.onCompleteItem(item, response, status, headers);
let nextItem = this.getReadyItems()[0];
let nextItem = this.getReadyItems()[ 0 ];
this.isUploading = false;
if (nextItem) {
nextItem.upload();
@@ -281,25 +286,21 @@ export class FileUploader {
this._render();
}
protected _headersGetter(parsedHeaders:ParsedResponseHeaders):any {
return (name:any):any => {
protected _headersGetter(parsedHeaders: ParsedResponseHeaders): any {
return (name: any): any => {
if (name) {
return parsedHeaders[name.toLowerCase()] || void 0;
return parsedHeaders[ name.toLowerCase() ] || void 0;
}
return parsedHeaders;
};
}
protected _xhrTransport(item:FileItem):any {
protected _xhrTransport(item: FileItem): any {
let that = this;
let xhr = item._xhr = new XMLHttpRequest();
let sendable:any;
let sendable: any;
this._onBeforeUploadItem(item);
// todo
/*item.formData.map(obj => {
obj.map((value, key) => {
form.append(key, value);
});
});*/
if (typeof item._file.size !== 'number') {
throw new TypeError('The file specified is no longer valid');
}
@@ -307,18 +308,31 @@ export class FileUploader {
sendable = new FormData();
this._onBuildItemForm(item, sendable);
sendable.append(item.alias, item._file, item.file.name);
const appendFile = () => sendable.append(item.alias, item._file, item.file.name);
if (!this.options.parametersBeforeFiles) {
appendFile();
}
// For AWS, Additional Parameters must come BEFORE Files
if (this.options.additionalParameter !== undefined) {
Object.keys(this.options.additionalParameter).forEach((key:string) => {
sendable.append(key, this.options.additionalParameter[key]);
Object.keys(this.options.additionalParameter).forEach((key: string) => {
let paramVal = this.options.additionalParameter[ key ];
// Allow an additional parameter to include the filename
if (typeof paramVal === 'string' && paramVal.indexOf('{{file_name}}') >= 0) {
paramVal = paramVal.replace('{{file_name}}', item.file.name);
}
sendable.append(key, paramVal);
});
}
if (this.options.parametersBeforeFiles) {
appendFile();
}
} else {
sendable = item._file;
sendable = this.options.formatDataFunction(item);
}
xhr.upload.onprogress = (event:any) => {
xhr.upload.onprogress = (event: any) => {
let progress = Math.round(event.lengthComputable ? event.loaded * 100 / event.total : 0);
this._onProgressItem(item, progress);
};
@@ -327,7 +341,7 @@ export class FileUploader {
let response = this._transformResponse(xhr.response, headers);
let gist = this._isSuccessCode(xhr.status) ? 'Success' : 'Error';
let method = '_on' + gist + 'Item';
(this as any)[method](item, response, xhr.status, headers);
(this as any)[ method ](item, response, xhr.status, headers);
this._onCompleteItem(item, response, xhr.status, headers);
};
xhr.onerror = () => {
@@ -357,11 +371,22 @@ export class FileUploader {
if (this.authToken) {
xhr.setRequestHeader(this.authTokenHeader, this.authToken);
}
xhr.send(sendable);
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
that.response.emit(xhr.responseText)
}
}
if (this.options.formatDataFunctionIsAsync) {
sendable.then(
(result: any) => xhr.send(JSON.stringify(result))
);
} else {
xhr.send(sendable);
}
this._render();
}
protected _getTotalProgress(value:number = 0):number {
protected _getTotalProgress(value: number = 0): number {
if (this.options.removeAfterUpload) {
return value;
}
@@ -372,7 +397,7 @@ export class FileUploader {
return Math.round(uploaded * ratio + current);
}
protected _getFilters(filters:FilterFunction[]|string):FilterFunction[] {
protected _getFilters(filters: FilterFunction[] | string): FilterFunction[] {
if (!filters) {
return this.options.filters;
}
@@ -382,109 +407,77 @@ export class FileUploader {
if (typeof filters === 'string') {
let names = filters.match(/[^\s,]+/g);
return this.options.filters
.filter((filter:any) => names.indexOf(filter.name) !== -1);
.filter((filter: any) => names.indexOf(filter.name) !== -1);
}
return this.options.filters;
}
protected _render():any {
protected _render(): any {
return void 0;
// todo: ?
}
// protected _folderFilter(item:FileItem):boolean {
// return !!(item.size || item.type);
// }
protected _queueLimitFilter():boolean {
protected _queueLimitFilter(): boolean {
return this.options.queueLimit === undefined || this.queue.length < this.options.queueLimit;
}
protected _isValidFile(file:FileLikeObject, filters:FilterFunction[], options:FileUploaderOptions): Promise<boolean> {
if (!filters.length) {
return Promise.resolve(true);
}
protected _isValidFile(file: FileLikeObject, filters: FilterFunction[], options: FileUploaderOptions): boolean {
this._failFilterIndex = -1;
return Promise.all(
filters.map((filter: FilterFunction) => {
const isValid: boolean = filter.fn.call(this, file, options);
return Promise.resolve(isValid);
})
).then((values) => {
const isValid = values.every((value: boolean) => {
this._failFilterIndex++;
return value;
})
return isValid ? Promise.resolve(isValid) : Promise.reject(isValid);
return !filters.length ? true : filters.every((filter: FilterFunction) => {
this._failFilterIndex++;
return filter.fn.call(this, file, options);
});
}
protected _isSuccessCode(status:number):boolean {
protected _isSuccessCode(status: number): boolean {
return (status >= 200 && status < 300) || status === 304;
}
/* tslint:disable */
protected _transformResponse(response:string, headers:ParsedResponseHeaders):string {
// todo: ?
/*var headersGetter = this._headersGetter(headers);
forEach($http.defaults.transformResponse, (transformFn) => {
response = transformFn(response, headersGetter);
});*/
protected _transformResponse(response: string, headers: ParsedResponseHeaders): string {
return response;
}
/* tslint:enable */
protected _parseHeaders(headers:string):ParsedResponseHeaders {
let parsed:any = {};
let key:any;
let val:any;
let i:any;
protected _parseHeaders(headers: string): ParsedResponseHeaders {
let parsed: any = {};
let key: any;
let val: any;
let i: any;
if (!headers) {
return parsed;
}
headers.split('\n').map((line:any) => {
headers.split('\n').map((line: any) => {
i = line.indexOf(':');
key = line.slice(0, i).trim().toLowerCase();
val = line.slice(i + 1).trim();
if (key) {
parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
parsed[ key ] = parsed[ key ] ? parsed[ key ] + ', ' + val : val;
}
});
return parsed;
}
/*protected _iframeTransport(item:FileItem) {
// todo: implement it later
}*/
protected _onWhenAddingFileFailed(item:FileLikeObject, filter:any, options:any):void {
protected _onWhenAddingFileFailed(item: FileLikeObject, filter: any, options: any): void {
this.onWhenAddingFileFailed(item, filter, options);
}
protected _onAfterAddingFile(item:FileItem):void {
protected _onAfterAddingFile(item: FileItem): void {
this.onAfterAddingFile(item);
}
protected _onAfterAddingAll(items:any):void {
protected _onAfterAddingAll(items: any): void {
this.onAfterAddingAll(items);
}
protected _onBeforeUploadItem(item:FileItem):void {
protected _onBeforeUploadItem(item: FileItem): void {
item._onBeforeUpload();
this.onBeforeUploadItem(item);
}
protected _onBuildItemForm(item:FileItem, form:any):void {
protected _onBuildItemForm(item: FileItem, form: any): void {
item._onBuildForm(form);
this.onBuildItemForm(item, form);
}
protected _onProgressItem(item:FileItem, progress:any):void {
protected _onProgressItem(item: FileItem, progress: any): void {
let total = this._getTotalProgress(progress);
this.progress = total;
item._onProgress(progress);
@@ -493,14 +486,12 @@ export class FileUploader {
this._render();
}
/* tslint:disable */
protected _onSuccessItem(item:FileItem, response:string, status:number, headers:ParsedResponseHeaders):void {
protected _onSuccessItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): void {
item._onSuccess(response, status, headers);
this.onSuccessItem(item, response, status, headers);
}
/* tslint:enable */
protected _onCancelItem(item:FileItem, response:string, status:number, headers:ParsedResponseHeaders):void {
protected _onCancelItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): void {
item._onCancel(response, status, headers);
this.onCancelItem(item, response, status, headers);
}

View File

@@ -2,5 +2,6 @@ export * from './file-upload/file-select.directive';
export * from './file-upload/file-drop.directive';
export * from './file-upload/file-uploader.class';
export * from './file-upload/file-item.class';
export * from './file-upload/file-like-object.class';
export { FileUploadModule } from './file-upload/file-upload.module';

7
src/ng-package.json Normal file
View File

@@ -0,0 +1,7 @@
{
"$schema": "../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../dist/ng2-file-upload",
"lib": {
"entryFile": "index.ts"
}
}

View File

@@ -1 +0,0 @@
export * from './index';

View File

@@ -1,6 +1,6 @@
{
"name": "ng2-file-upload",
"version": "1.2.0",
"version": "1.3.0",
"peerDependencies": {
"@angular/common": "*",
"@angular/core": "*"

View File

@@ -1,28 +1,147 @@
import { Component } from '@angular/core';
import { Component, DebugElement } from '@angular/core';
import { By } from '@angular/platform-browser';
import { inject, ComponentFixture, TestBed } from '@angular/core/testing';
import { FileUploader } from '../file-upload/file-uploader.class';
import { FileUploadModule } from '../file-upload/file-upload.module';
import { FileDropDirective } from '../file-upload/file-drop.directive';
@Component({
selector: 'container',
template: `<input type="file" ng2FileSelect [uploader]="uploader" />`
template: `<div type="file"
ng2FileDrop
[uploader]="uploader"
></div>`
})
export class ContainerComponent {
public uploader:FileUploader = new FileUploader({url: 'localhost:3000'});
public get url(): string { return 'localhost:3000'; }
public uploader: FileUploader = new FileUploader({ url: this.url });
}
describe('Directive: FileSelectDirective', () => {
describe('Directive: FileDropDirective', () => {
let fixture: ComponentFixture<ContainerComponent>;
let hostComponent: ContainerComponent;
let directiveElement: DebugElement;
let fileDropDirective: FileDropDirective;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [FileUploadModule],
declarations: [ContainerComponent],
providers: [ContainerComponent]
imports: [ FileUploadModule ],
declarations: [ ContainerComponent ],
providers: [ ContainerComponent ]
});
});
it('should be fine', inject([ContainerComponent], (fixture:ComponentFixture<ContainerComponent>) => {
expect(fixture).not.toBeNull();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ContainerComponent);
hostComponent = fixture.componentInstance;
fixture.detectChanges();
directiveElement = fixture.debugElement.query(By.directive(FileDropDirective));
fileDropDirective = directiveElement.injector.get(FileDropDirective) as FileDropDirective;
});
it('can be initialized', () => {
expect(fixture).toBeDefined();
expect(hostComponent).toBeDefined();
expect(fileDropDirective).toBeDefined();
});
it('can set file uploader', () => {
expect(fileDropDirective.uploader).toBe(hostComponent.uploader);
});
it('can get uploader options', () => {
const options = fileDropDirective.getOptions();
// Check url set through binding
expect(options.url).toBe(hostComponent.url);
// Check default options
expect(options.autoUpload).toBeFalsy();
expect(options.isHTML5).toBeTruthy();
expect(options.removeAfterUpload).toBeFalsy();
expect(options.disableMultipart).toBeFalsy();
});
it('can get filters', () => {
const filters = fileDropDirective.getFilters();
// TODO: Update test once implemented
expect(filters).toEqual({});
});
it('handles drop event', () => {
spyOn(fileDropDirective, 'onDrop');
directiveElement.triggerEventHandler('drop', getFakeEventData());
expect(fileDropDirective.onDrop).toHaveBeenCalled();
});
it('adds file to upload', () => {
spyOn(fileDropDirective.uploader, 'addToQueue');
let fileOverData;
fileDropDirective.fileOver.subscribe((data: any) => fileOverData = data);
let fileDropData;
fileDropDirective.onFileDrop.subscribe((data: File[]) => fileDropData = data);
fileDropDirective.onDrop(getFakeEventData());
const uploadedFiles = getFakeEventData().dataTransfer.files;
const expectedArguments = [ uploadedFiles, fileDropDirective.getOptions(), fileDropDirective.getFilters() ];
expect(fileDropDirective.uploader.addToQueue).toHaveBeenCalledWith(...expectedArguments);
expect(fileOverData).toBeFalsy();
expect(fileDropData).toEqual(uploadedFiles);
});
it('handles dragover event', () => {
spyOn(fileDropDirective, 'onDragOver');
directiveElement.triggerEventHandler('dragover', getFakeEventData());
expect(fileDropDirective.onDragOver).toHaveBeenCalled();
});
it('handles file over', () => {
let fileOverData;
fileDropDirective.fileOver.subscribe((data: any) => fileOverData = data);
fileDropDirective.onDragOver(getFakeEventData());
expect(fileOverData).toBeTruthy();
});
it('handles dragleave event', () => {
spyOn(fileDropDirective, 'onDragLeave');
directiveElement.triggerEventHandler('dragleave', getFakeEventData());
expect(fileDropDirective.onDragLeave).toHaveBeenCalled();
});
it('handles file over leave', () => {
let fileOverData;
fileDropDirective.fileOver.subscribe((data: any) => fileOverData = data);
fileDropDirective.onDragLeave(getFakeEventData());
expect(fileOverData).toBeFalsy();
});
});
function getFakeEventData(): any {
return {
dataTransfer: {
files: [ 'foo.bar' ],
types: [ 'Files' ]
},
preventDefault: () => undefined,
stopPropagation: () => undefined
}
}

View File

@@ -0,0 +1,99 @@
import { TestBed, ComponentFixture } from '@angular/core/testing';
import { Component, DebugElement } from '@angular/core';
import { By } from '@angular/platform-browser';
import { FileUploadModule } from '../file-upload/file-upload.module';
import { FileSelectDirective } from '../file-upload/file-select.directive';
import { FileUploader } from '../file-upload/file-uploader.class';
@Component({
selector: 'container',
template: `<input type="file"
ng2FileSelect
[uploader]="uploader"
/>`
})
export class ContainerComponent {
public get url(): string { return 'localhost:3000'; }
public uploader: FileUploader = new FileUploader({ url: this.url });
}
describe('Directive: FileSelectDirective', () => {
let fixture: ComponentFixture<ContainerComponent>;
let hostComponent: ContainerComponent;
let directiveElement: DebugElement;
let fileSelectDirective: FileSelectDirective;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ FileUploadModule ],
declarations: [ ContainerComponent ],
providers: [ ContainerComponent ]
});
});
beforeEach(() => {
fixture = TestBed.createComponent(ContainerComponent);
hostComponent = fixture.componentInstance;
fixture.detectChanges();
directiveElement = fixture.debugElement.query(By.directive(FileSelectDirective));
fileSelectDirective = directiveElement.injector.get(FileSelectDirective) as FileSelectDirective;
});
it('can be initialized', () => {
expect(fixture).toBeDefined();
expect(hostComponent).toBeDefined();
expect(fileSelectDirective).toBeDefined();
});
it('can set file uploader', () => {
expect(fileSelectDirective.uploader).toBe(hostComponent.uploader);
});
it('can get uploader options', () => {
const options = fileSelectDirective.getOptions();
// Check url set through binding
expect(options.url).toBe(hostComponent.url);
// Check default options
expect(options.autoUpload).toBeFalsy();
expect(options.isHTML5).toBeTruthy();
expect(options.removeAfterUpload).toBeFalsy();
expect(options.disableMultipart).toBeFalsy();
});
it('can get filters', () => {
const filters = fileSelectDirective.getFilters();
// TODO: Update test once implemented
expect(filters).toEqual({});
});
it('can check if element is empty', () => {
const isElementEmpty = fileSelectDirective.isEmptyAfterSelection();
expect(isElementEmpty).toBeFalsy();
});
it('can listed on change event', () => {
spyOn(fileSelectDirective, 'onChange');
directiveElement.triggerEventHandler('change', {});
expect(fileSelectDirective.onChange).toHaveBeenCalled();
});
it('handles change event', () => {
spyOn(fileSelectDirective.uploader, 'addToQueue');
fileSelectDirective.onChange();
const expectedArguments = [ directiveElement.nativeElement.files,
fileSelectDirective.getOptions(),
fileSelectDirective.getFilters() ];
expect(fileSelectDirective.uploader.addToQueue).toHaveBeenCalledWith(...expectedArguments);
});
});

View File

@@ -1,8 +1,9 @@
{
"compilerOptions": {
"baseUrl": ".",
"outDir": "../dist",
"target": "es5",
"module": "commonjs",
"module": "esnext",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
@@ -14,24 +15,19 @@
"stripInternal": true,
"noUnusedLocals": false,
"noUnusedParameters": false,
"lib": ["dom", "es6"],
"types": [
"jasmine",
"webpack"
],
"typeRoots": [
"../node_modules/@types"
]
"lib": ["dom", "es6"]
},
"exclude": [
"node_modules"
],
"files": [
"../scripts/typings.d.ts",
"./ng2-file-upload.ts",
"./index.ts"
],
"angularCompilerOptions": {
"genDir": "../temp/factories"
}
"annotateForClosureCompiler": true,
"strictMetadataEmit": true,
"skipTemplateCodegen": true,
"flatModuleOutFile": "ng2-file-upload.js",
"flatModuleId": "ng2-file-upload"
},
"include": [
"../scripts/typings.d.ts"
],
"exclude": [
"**/*.spec.ts"
]
}

View File

@@ -1,47 +1,42 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/0.13/config/configuration-file.html
const customLaunchers = require('./scripts/sauce-browsers').customLaunchers;
const customLaunchers = require('./sauce-browsers').customLaunchers;
module.exports = function (config) {
const configuration = {
basePath: '',
frameworks: ['jasmine', 'angular-cli'],
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-remap-istanbul'),
require('angular-cli/plugins/karma')
require('karma-coverage-istanbul-reporter'),
require('@angular-devkit/build-angular/plugins/karma')
],
files: [
{pattern: './scripts/test.ts', watched: false}
],
preprocessors: {
'./scripts/test.ts': ['angular-cli']
coverageIstanbulReporter: {
dir: require('path').join(__dirname, '../coverage'), reports: [ 'html', 'lcovonly' ],
fixWebpackSourcePaths: false
},
remapIstanbulReporter: {
reports: {
html: 'coverage',
lcovonly: './coverage/coverage.lcov'
}
},
angularCli: {
config: './angular-cli.json',
environment: 'dev'
},
reporters: config.angularCli && config.angularCli.codeCoverage
? ['dots', 'karma-remap-istanbul']
: ['dots'],
reporters: ['dots', 'coverage-istanbul'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
browsers: ['ChromeHeadless'],
browserNoActivityTimeout: 20000,
browserDisconnectTolerance: 2,
browserDisconnectTimeout: 5000,
singleRun: true,
customLaunchers: {
Chrome_travis_ci: {
base: 'Chrome',
flags: ['--no-sandbox']
base: 'ChromeHeadless',
flags: [
'--headless',
'--disable-gpu',
'--no-sandbox',
'--remote-debugging-port=9222'
]
}
},
mime: { 'text/x-typescript': ['ts','tsx'] },
@@ -72,10 +67,10 @@ module.exports = function (config) {
},
public: 'public'
};
configuration.captureTimeout = 0;
configuration.captureTimeout = 60000;
configuration.customLaunchers = customLaunchers();
configuration.browsers = Object.keys(configuration.customLaunchers);
configuration.concurrency = 3;
configuration.concurrency = 4;
configuration.browserDisconnectTolerance = 2;
configuration.browserNoActivityTimeout = 20000;
configuration.browserDisconnectTimeout = 5000;

View File

@@ -1,4 +1,4 @@
import '../demo/src/polyfills.ts';
import '../scripts/polyfills.ts';
import 'zone.js/dist/long-stack-trace-zone';
import 'zone.js/dist/proxy.js';

22
test/tsconfig.json Normal file
View File

@@ -0,0 +1,22 @@
{
"compilerOptions": {
"experimentalDecorators": true,
"module": "esnext",
"moduleResolution": "node",
"target": "es2015",
"outDir": "./out-tsc/spec",
"types": [
"jasmine",
"node"
]
},
"files": [
"../scripts/typings.d.ts",
"test.ts",
"../scripts/polyfills.ts",
],
"include": [
"../src/**/*.spec.ts",
"../demo/src/**/*.spec.ts"
]
}

7807
yarn.lock

File diff suppressed because it is too large Load Diff