diff --git a/.gitignore b/.gitignore index 9a947e2c..f57e80f9 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ npm-debug.log # WebStorm .idea +.vscode # ignore build and dist for now /bundles @@ -19,6 +20,7 @@ npm-debug.log # ignore incline compiling /demo/**/*.js /demo/**/*.d.ts +!/demo/custom-typings.d.ts /demo/**/*.js.map /components/**/*.js /components/**/*.d.ts diff --git a/.ng2-config.js b/.ng2-config.js new file mode 100644 index 00000000..1229229e --- /dev/null +++ b/.ng2-config.js @@ -0,0 +1,29 @@ +'use strict'; +var pkg = require('./package.json'); + +module.exports = { + // metadata + title: pkg.description, + baseUrl: '/', + // root folder name + src: 'demo', + dist: 'demo-build', + htmlIndexes: ['index.html'], + // karma bundle src + spec: './spec-bundle.js', + // webpack entry + entry: { + polyfills: './demo/polyfills.ts', + vendor: './demo/vendor.ts', + main: './demo/index.ts' + }, + commonChunks: { + name: ['polyfills', 'vendor'].reverse() + }, + // webpack alias + alias: {}, + copy: [ + {from: 'demo/favicon.ico', to: 'favicon.ico'}, + {from: 'demo/assets', to: 'assets'} + ] +}; diff --git a/.travis.yml b/.travis.yml index 56eb9da3..2e447976 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,12 +2,14 @@ language: node_js node_js: - "6" +before_install: npm i -g npm@latest + script: - npm run flow.install:typings - npm test after_success: - - ./node_modules/.bin/codecov + - ./node_modules/.bin/codecov -f coverage/coverage-final.json addons: # sauce labs tunel connector (read more https://docs.travis-ci.com/user/sauce-connect/ ) diff --git a/components/file-upload/file-drop.directive.spec.ts b/components/file-upload/file-drop.directive.spec.ts index 264e4095..eb0aad8f 100644 --- a/components/file-upload/file-drop.directive.spec.ts +++ b/components/file-upload/file-drop.directive.spec.ts @@ -1,20 +1,27 @@ -import {Component} from '@angular/core'; -import {it, inject, beforeEachProviders} from '@angular/core/testing'; -import {ComponentFixture} from '@angular/compiler/testing'; -import {FileUploader} from './file-uploader.class'; -import {FileSelectDirective} from './file-select.directive'; +import { Component } from '@angular/core'; +import { inject, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FileUploader } from './file-uploader.class'; +import { FileUploadModule } from './file-upload.module'; + @Component({ selector: 'container', - template: `<input type="file" ng2FileSelect [uploader]="uploader" />`, - directives: [FileSelectDirective] + template: `<input type="file" ng2FileSelect [uploader]="uploader" />` }) export class ContainerComponent { public uploader:FileUploader = new FileUploader({url: 'localhost:3000'}); } + describe('Directive: FileSelectDirective', () => { - beforeEachProviders(() => [ - ContainerComponent - ]); + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [FileUploadModule], + declarations: [ContainerComponent], + providers: [ContainerComponent] + }); + }); + it('should be fine', inject([ContainerComponent], (fixture:ComponentFixture<ContainerComponent>) => { expect(fixture).not.toBeNull(); })); diff --git a/components/file-upload/file-drop.directive.ts b/components/file-upload/file-drop.directive.ts index a918adf8..13d8f3b0 100644 --- a/components/file-upload/file-drop.directive.ts +++ b/components/file-upload/file-drop.directive.ts @@ -9,6 +9,7 @@ export class FileDropDirective { @Output() public onFileDrop:EventEmitter<File[]> = new EventEmitter<File[]>(); private element:ElementRef; + public constructor(element:ElementRef) { this.element = element; } @@ -80,12 +81,13 @@ export class FileDropDirective { return false; } } -/* - _addOverClass(item:any):any { - item.addOverClass(); - } - _removeOverClass(item:any):any { - item.removeOverClass(); - }*/ + /* + _addOverClass(item:any):any { + item.addOverClass(); + } + + _removeOverClass(item:any):any { + item.removeOverClass(); + }*/ } diff --git a/components/file-upload/file-item.class.ts b/components/file-upload/file-item.class.ts index 7f59e164..b9f3099b 100644 --- a/components/file-upload/file-item.class.ts +++ b/components/file-upload/file-item.class.ts @@ -1,5 +1,5 @@ -import {FileLikeObject} from './file-like-object.class'; -import {FileUploader, ParsedResponseHeaders, FileUploaderOptions} from './file-uploader.class'; +import { FileLikeObject } from './file-like-object.class'; +import { FileUploader, ParsedResponseHeaders, FileUploaderOptions } from './file-uploader.class'; export class FileItem { public file:FileLikeObject; @@ -67,19 +67,19 @@ export class FileItem { } public onSuccess(response:string, status:number, headers:ParsedResponseHeaders):any { - return {response,status,headers}; + return {response, status, headers}; } public onError(response:string, status:number, headers:ParsedResponseHeaders):any { - return {response,status,headers}; + return {response, status, headers}; } public onCancel(response:string, status:number, headers:ParsedResponseHeaders):any { - return {response,status,headers}; + return {response, status, headers}; } public onComplete(response:string, status:number, headers:ParsedResponseHeaders):any { - return {response,status,headers}; + return {response, status, headers}; } public _onBeforeUpload():void { diff --git a/components/file-upload/file-like-object.class.ts b/components/file-upload/file-like-object.class.ts index 2d0ccf76..0245dbba 100644 --- a/components/file-upload/file-like-object.class.ts +++ b/components/file-upload/file-like-object.class.ts @@ -23,7 +23,7 @@ export class FileLikeObject { this.name = path.slice(path.lastIndexOf('/') + path.lastIndexOf('\\') + 2); } - public _createFromObject(object:{size: number, type: string, name: string}):void { + public _createFromObject(object:{size:number, type:string, name:string}):void { // this.lastModifiedDate = copy(object.lastModifiedDate); this.size = object.size; this.type = object.type; diff --git a/components/file-upload/file-select.directive.ts b/components/file-upload/file-select.directive.ts index 250bf2ca..4b8325cb 100644 --- a/components/file-upload/file-select.directive.ts +++ b/components/file-upload/file-select.directive.ts @@ -1,6 +1,6 @@ import { Directive, ElementRef, Input, HostListener } from '@angular/core'; -import {FileUploader} from './file-uploader.class'; +import { FileUploader } from './file-uploader.class'; // todo: filters @@ -9,6 +9,7 @@ export class FileSelectDirective { @Input() public uploader:FileUploader; private element:ElementRef; + public constructor(element:ElementRef) { this.element = element; } diff --git a/components/file-upload/file-upload.module.ts b/components/file-upload/file-upload.module.ts new file mode 100644 index 00000000..e9c5b0fe --- /dev/null +++ b/components/file-upload/file-upload.module.ts @@ -0,0 +1,13 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; + +import { FileDropDirective } from './file-drop.directive'; +import { FileSelectDirective } from './file-select.directive'; + +@NgModule({ + imports: [CommonModule], + declarations: [FileDropDirective, FileSelectDirective], + exports: [FileDropDirective, FileSelectDirective] +}) +export class FileUploadModule { +} diff --git a/components/file-upload/file-uploader.class.ts b/components/file-upload/file-uploader.class.ts index 88df666d..641700da 100644 --- a/components/file-upload/file-uploader.class.ts +++ b/components/file-upload/file-uploader.class.ts @@ -1,6 +1,6 @@ -import {FileLikeObject} from './file-like-object.class'; -import {FileItem} from './file-item.class'; -import {FileType} from './file-type.class'; +import { FileLikeObject } from './file-like-object.class'; +import { FileItem } from './file-item.class'; +import { FileType } from './file-type.class'; function isFile(value:any):boolean { return (File && value instanceof File); @@ -295,13 +295,13 @@ export class FileUploader { if (typeof item._file.size !== 'number') { throw new TypeError('The file specified is no longer valid'); } - if(!this.options.disableMultipart) { - sendable = new FormData(); - this._onBuildItemForm(item, sendable); + if (!this.options.disableMultipart) { + sendable = new FormData(); + this._onBuildItemForm(item, sendable); - sendable.append(item.alias, item._file, item.file.name); + sendable.append(item.alias, item._file, item.file.name); } else { - sendable = item._file; + sendable = item._file; } xhr.upload.onprogress = (event:any) => { diff --git a/components/file-upload/readme.md b/components/file-upload/readme.md index c1f7d2dc..9954d39b 100644 --- a/components/file-upload/readme.md +++ b/components/file-upload/readme.md @@ -1,6 +1,6 @@ ### Usage ```typescript -import {FileSelectDirective, FileDropDirective, FileUploader} from 'ng2-file-upload/ng2-file-upload'; +import { FileSelectDirective, FileDropDirective, FileUploader } from 'ng2-file-upload/ng2-file-upload'; ``` ### Annotations diff --git a/demo/app.component.ts b/demo/app.component.ts new file mode 100644 index 00000000..2a7a3577 --- /dev/null +++ b/demo/app.component.ts @@ -0,0 +1,34 @@ +import { Component } from '@angular/core'; + +let gettingStarted = require('./getting-started.md'); + +@Component({ + selector: 'app', + template: ` + <main class="bd-pageheader"> + <div class="container"> + <h1>ng2-file-upload</h1> + <p>The Angular2 File Upload directives</p> + <a class="btn btn-primary" href="https://github.com/valor-software/ng2-file-upload">View on GitHub</a> + <div class="row"> + <div class="col-lg-1"><iframe src="https://ghbtns.com/github-btn.html?user=valor-software&repo=ng2-file-upload&type=star&count=true" frameborder="0" scrolling="0" width="170px" height="20px"></iframe></div> + <div class="col-lg-1"><iframe src="https://ghbtns.com/github-btn.html?user=valor-software&repo=ng2-file-upload&type=fork&count=true" frameborder="0" scrolling="0" width="170px" height="20px"></iframe></div> + </div> + </div> + </main> + + <div class="container"> + <section id="getting-started">${gettingStarted}</section> + + <file-upload-section class="col-md-12"></file-upload-section> + </div> + + <footer class="footer"> + <div class="container"> + <p class="text-muted text-center"><a href="https://github.com/valor-software/ng2-file-upload">ng2-file-upload</a> is maintained by <a href="https://github.com/valor-software">valor-software</a>.</p> + </div> + </footer> + ` +}) +export class DemoComponent { +} diff --git a/demo/components/file-upload-section.ts b/demo/components/file-upload-section.ts index eb4d586b..c374c100 100644 --- a/demo/components/file-upload-section.ts +++ b/demo/components/file-upload-section.ts @@ -1,10 +1,5 @@ -import {Component} from '@angular/core'; -import {CORE_DIRECTIVES} from '@angular/common'; +import { Component } from '@angular/core'; -import {TAB_DIRECTIVES} from 'ng2-bootstrap/ng2-bootstrap'; -import {SimpleDemoComponent} from './file-upload/simple-demo'; - -let name = 'File Upload'; let doc = require('../../components/file-upload/readme.md'); let tabDesc:Array<any> = [ @@ -16,13 +11,16 @@ let tabDesc:Array<any> = [ } ]; -let tabsContent:string = ``; -tabDesc.forEach((desc:any) => { - tabsContent += ` - <tab heading="${desc.heading}" (select)="select($event)"> +@Component({ + selector: 'file-upload-section', + template: ` + <section [id]="name.toLowerCase()"> + <div class="row"> + <tabset> + <tab *ngFor="let desc of tabs" heading="{{desc.heading}}" (select)="select($event)"> <div class="card card-block panel panel-default panel-body"> - <${desc.heading.toLowerCase()}-demo *ngIf="currentHeading === '${desc.heading}'"></${desc.heading.toLowerCase()}-demo> + <simple-demo></simple-demo> <br> @@ -30,48 +28,38 @@ tabDesc.forEach((desc:any) => { <tabset> <tab heading="Markup"> <div class="card card-block panel panel-default panel-body"> - <pre class="language-html"><code class="language-html" ng-non-bindable>${desc.html}</code></pre> + <pre class="language-html"><code class="language-html" ng-non-bindable [innerHTML]="desc.html"></code></pre> </div> </tab> <tab heading="TypeScript"> <div class="card card-block panel panel-default panel-body"> - <pre class="language-typescript"><code class="language-typescript" ng-non-bindable>${desc.ts}</code></pre> + <pre class="language-typescript"><code class="language-typescript" ng-non-bindable [innerHTML]="desc.ts"></code></pre> </div> </tab> <tab heading="Backend Demo"> <div class="card card-block panel panel-default panel-body"> - <pre class="language-javascript"><code class="language-javascript" ng-non-bindable>${desc.js}</code></pre> + <pre class="language-javascript"><code class="language-javascript" ng-non-bindable [innerHTML]="desc.js"></code></pre> </div> </tab> </tabset> </div> </div> </tab> - `; -}); - -@Component({ - selector: 'file-upload-section', - template: ` - <section id="${name.toLowerCase()}"> - <div class="row"> - <tabset> - - ${tabsContent} - </tabset> </div> <div class="row"> <h2>API</h2> - <div class="card card-block panel panel-default panel-body">${doc}</div> + <div class="card card-block panel panel-default panel-body" [innerHTML]="doc"></div> </div> </section> - `, - directives: [SimpleDemoComponent, TAB_DIRECTIVES, CORE_DIRECTIVES] + ` }) export class FileUploadSectionComponent { + public name:string = 'File Upload'; public currentHeading:string = 'Simple'; + public doc:string = doc; + public tabs:any = tabDesc; public select(e:any):void { if (e.heading) { diff --git a/demo/components/file-upload/simple-demo.ts b/demo/components/file-upload/simple-demo.ts index cd0bf52c..10ce86bf 100644 --- a/demo/components/file-upload/simple-demo.ts +++ b/demo/components/file-upload/simple-demo.ts @@ -1,6 +1,5 @@ -import {Component} from '@angular/core'; -import {CORE_DIRECTIVES, FORM_DIRECTIVES, NgClass, NgStyle} from '@angular/common'; -import {FILE_UPLOAD_DIRECTIVES, FileUploader} from '../../../ng2-file-upload'; +import { Component } from '@angular/core'; +import { FileUploader } from '../../../ng2-file-upload'; // webpack html imports let template = require('./simple-demo.html'); @@ -10,8 +9,7 @@ const URL = 'https://evening-anchorage-3159.herokuapp.com/api/'; @Component({ selector: 'simple-demo', - template: template, - directives: [FILE_UPLOAD_DIRECTIVES, NgClass, NgStyle, CORE_DIRECTIVES, FORM_DIRECTIVES] + template: template }) export class SimpleDemoComponent { public uploader:FileUploader = new FileUploader({url: URL}); diff --git a/demo/components/file-upload/zs-file-demo/demo.ts b/demo/components/file-upload/zs-file-demo/demo.ts index be81a986..eb19adda 100644 --- a/demo/components/file-upload/zs-file-demo/demo.ts +++ b/demo/components/file-upload/zs-file-demo/demo.ts @@ -1,5 +1,5 @@ -import {Component, ElementRef, Renderer, Input, HostListener, HostBinding, OnInit} from '@angular/core'; -import {FileUploader, FileUploaderOptions} from '../../../../ng2-file-upload'; +import { Component, ElementRef, Renderer, Input, HostListener, HostBinding, OnInit } from '@angular/core'; +import { FileUploader, FileUploaderOptions } from '../../../../ng2-file-upload'; @Component({ selector: 'demo-file-upload', diff --git a/demo/custom-typings.d.ts b/demo/custom-typings.d.ts new file mode 100644 index 00000000..8b7203f2 --- /dev/null +++ b/demo/custom-typings.d.ts @@ -0,0 +1 @@ +declare const ENV:string; diff --git a/demo/index.ts b/demo/index.ts index 2ee024cc..c732090e 100644 --- a/demo/index.ts +++ b/demo/index.ts @@ -1,44 +1,4 @@ -import {bootstrap} from '@angular/platform-browser-dynamic'; -import {Component} from '@angular/core'; -import {NgClass} from '@angular/common'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { NgFileUploadDemo } from './ng2-file-upload-demo.module'; -import {FileUploadSectionComponent} from './components/file-upload-section'; - -let gettingStarted = require('./getting-started.md'); - -@Component({ - selector: 'app', - template: ` - <main class="bd-pageheader"> - <div class="container"> - <h1>ng2-file-upload</h1> - <p>The Angular2 File Upload directives</p> - <a class="btn btn-primary" href="https://github.com/valor-software/ng2-file-upload">View on GitHub</a> - <div class="row"> - <div class="col-lg-1"><iframe src="https://ghbtns.com/github-btn.html?user=valor-software&repo=ng2-file-upload&type=star&count=true" frameborder="0" scrolling="0" width="170px" height="20px"></iframe></div> - <div class="col-lg-1"><iframe src="https://ghbtns.com/github-btn.html?user=valor-software&repo=ng2-file-upload&type=fork&count=true" frameborder="0" scrolling="0" width="170px" height="20px"></iframe></div> - </div> - </div> - </main> - - <div class="container"> - <section id="getting-started">${gettingStarted}</section> - - <file-upload-section class="col-md-12"></file-upload-section> - </div> - - <footer class="footer"> - <div class="container"> - <p class="text-muted text-center"><a href="https://github.com/valor-software/ng2-file-upload">ng2-file-upload</a> is maintained by <a href="https://github.com/valor-software">valor-software</a>.</p> - </div> - </footer> - `, - directives: [ - NgClass, - FileUploadSectionComponent - ] -}) -export class DemoComponent { -} - -bootstrap(DemoComponent); +platformBrowserDynamic().bootstrapModule(NgFileUploadDemo); diff --git a/demo/ng2-file-upload-demo.module.ts b/demo/ng2-file-upload-demo.module.ts new file mode 100644 index 00000000..ca73c121 --- /dev/null +++ b/demo/ng2-file-upload-demo.module.ts @@ -0,0 +1,18 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { BrowserModule } from '@angular/platform-browser'; + +import { Ng2BootstrapModule } from 'ng2-bootstrap/ng2-bootstrap'; +import { FileUploadModule } from '../components/file-upload/file-upload.module'; +import { DemoComponent } from './app.component.ts'; +import { FileUploadSectionComponent } from './components/file-upload-section'; +import { SimpleDemoComponent } from './components/file-upload/simple-demo'; + +@NgModule({ + imports: [BrowserModule, CommonModule, FileUploadModule, Ng2BootstrapModule, FormsModule], + declarations: [DemoComponent, FileUploadSectionComponent, SimpleDemoComponent], + bootstrap: [DemoComponent] +}) +export class NgFileUploadDemo { +} diff --git a/demo/polyfills.ts b/demo/polyfills.ts new file mode 100644 index 00000000..d27ff360 --- /dev/null +++ b/demo/polyfills.ts @@ -0,0 +1,28 @@ +// Polyfills +// (these modules are what are in 'angular2/bundles/angular2-polyfills' so don't use that here) + +// import 'ie-shim'; // Internet Explorer +// import 'es6-shim'; +// import 'es6-promise'; +// import 'es7-reflect-metadata'; + +// Prefer CoreJS over the polyfills above +import 'core-js/es6'; +import 'core-js/es7/reflect'; +require('zone.js/dist/zone'); +require('reflect-metadata'); + +// Typescript emit helpers polyfill +import 'ts-helpers'; + +if ('production' === ENV) { + // Production + +} else { + // Development + + (Error as any).stackTraceLimit = Infinity; + + require('zone.js/dist/long-stack-trace-zone'); + +} diff --git a/demo/vendor.ts b/demo/vendor.ts new file mode 100644 index 00000000..c06cab38 --- /dev/null +++ b/demo/vendor.ts @@ -0,0 +1,23 @@ +// For vendors for example jQuery, Lodash, angular2-jwt just import them here unless you plan on +// chunking vendors files for async loading. You would need to import the async loaded vendors +// at the entry point of the async loaded file. Also see custom-typings.d.ts as you also need to +// run `typings install x` where `x` is your module + +// Angular 2 +import '@angular/common'; +import '@angular/core'; +import '@angular/forms'; +import '@angular/platform-browser'; +import '@angular/platform-browser-dynamic'; + +// RxJS +import 'rxjs/add/operator/map'; +import 'rxjs/add/operator/mergeMap'; + +if ('production' === ENV) { + // Production + +} else { + // Development + +} diff --git a/gulp-tasks/lint.js b/gulp-tasks/lint.js index de91156a..1132abdf 100644 --- a/gulp-tasks/lint.js +++ b/gulp-tasks/lint.js @@ -2,17 +2,20 @@ const gulp = require('gulp'); const tslint = require('gulp-tslint'); -const paths = gulp.paths; +const gitignore = require('gitignore-to-glob')(); + +gitignore.push('**/*.ts'); gulp.task('tslint', () => -gulp - .src(paths.tssrc) - .pipe(tslint()) - .pipe(tslint.report('prose', { - emitError: true, - summarizeFailureOutput: true, - reportLimit: 50 - })) + gulp + .src(gitignore) + .pipe(tslint({ + formatter: 'verbose', + emitError: true, + summarizeFailureOutput: true, + reportLimit: 50 + })) + .pipe(tslint.report()) ); gulp.task('lint', ['tslint']); diff --git a/gulpfile.js b/gulpfile.js index a902fca6..3d44e09d 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -2,15 +2,6 @@ const gulp = require('gulp'); -gulp.paths = { - tssrc: [ - '**/*.ts', - '!**/*.d.ts', - '!node_modules/**/*', - '!bundles/**/*', - '!typings/**/*'] -}; - require('require-dir')('./gulp-tasks'); gulp.task('default', () => { diff --git a/karma.conf.js b/karma.conf.js index 31fec667..6c64f09d 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -1,101 +1,5 @@ 'use strict'; -const path = require('path'); -const cwd = process.cwd(); +const config = require('./.ng2-config'); -module.exports = config => { - config.set({ - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: '', - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ['jasmine'], - - // list of files / patterns to load in the browser - files: [ - {pattern: 'test.bundle.js', watched: false} - ], - - // list of files to exclude - exclude: [], - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - preprocessors: { - 'test.bundle.js': ['coverage', 'webpack', 'sourcemap'] - }, - - webpack: { - resolve: { - root: [path.resolve(cwd)], - modulesDirectories: ['node_modules', 'demo', 'components', 'test', '.'], - extensions: ['', '.ts', '.js', '.css'] - }, - module: { - loaders: [ - {test: /\.ts$/, loader: 'ts-loader', exclude: [/node_modules/]} - ], - postLoaders: [ - // instrument only testing sources with Istanbul - { - test: /\.(js|ts)$/, - include: root('components'), - loader: 'istanbul-instrumenter-loader', - exclude: [ - /\.e2e\.ts$/, - /node_modules/ - ] - } - ] - }, - stats: { - colors: true, - reasons: true - }, - watch: true, - debug: true - }, - - coverageReporter: { - dir: 'coverage/', - reporters: [ - {type: 'text'}, - {type: 'json'}, - {type: 'html'} - ] - }, - webpackServer: {noInfo: true}, - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ['spec', 'coverage'], - - // web server port - port: 9876, - - // enable / disable colors in the output (reporters and logs) - colors: true, - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || - // config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: false, - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - browsers: ['PhantomJS'], - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: true - }); -}; - -function root(partialPath) { - return path.join(__dirname, partialPath); -} +module.exports = require('ng2-webpack-config').karma(config); diff --git a/ng2-file-upload.ts b/ng2-file-upload.ts index 353f03cd..804af652 100644 --- a/ng2-file-upload.ts +++ b/ng2-file-upload.ts @@ -2,13 +2,4 @@ export * from './components/file-upload/file-select.directive'; export * from './components/file-upload/file-drop.directive'; export * from './components/file-upload/file-uploader.class'; -import {FileSelectDirective} from './components/file-upload/file-select.directive'; -import {FileDropDirective} from './components/file-upload/file-drop.directive'; - -export const FILE_UPLOAD_DIRECTIVES:[any] = [FileSelectDirective, FileDropDirective]; - -export default { - directives: [ - FILE_UPLOAD_DIRECTIVES - ] -}; +export { FileUploadModule } from './components/file-upload/file-upload.module'; diff --git a/package.json b/package.json index b8db3121..acee6d3c 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,8 @@ "description": "angular2 file upload directives", "scripts": { "flow.install:typings": "./node_modules/.bin/typings install", - "flow.compile": "npm run flow.install:typings && npm run flow.compile:common && npm run flow.compile:system ", - "flow.compile:common": "./node_modules/.bin/tsc", + "flow.compile": "npm run flow.install:typings && npm run flow.compile:common && npm run flow.compile:system", + "flow.compile:common": "./node_modules/.bin/tsc -p tsconfig.publish.json", "flow.compile:system": "./.config/bundle-system.js", "flow.copy:src": "./node_modules/.bin/cpy ng2-file-upload.ts \"components/*.ts\" ts --parents", "flow.clean": "./node_modules/.bin/del bundles coverage demo-build typings \"components/**/*.+(js|d.ts|js.map)\" dist \"ng2-file-upload.+(js|d.ts|js.map)\"", @@ -15,7 +15,7 @@ "flow.lint": "npm run flow.eslint && npm run flow.tslint", "flow.changelog": "./node_modules/.bin/conventional-changelog -i CHANGELOG.md -s -p angular -v", "flow.github-release": "./node_modules/.bin/conventional-github-releaser -p angular", - "flow.build:prod": "NODE_ENV=production ./node_modules/.bin/webpack --progress --color", + "flow.build:prod": "NODE_ENV=production ./node_modules/.bin/webpack --progress --color --display-error-details --display-cached", "flow.build:dev": "./node_modules/.bin/webpack --progress --color", "flow.serve:dev": "./node_modules/.bin/webpack-dev-server --hot --inline --colors --display-error-details --display-cached", "flow.serve:prod": "NODE_ENV=production ./node_modules/.bin/webpack-dev-server --hot --inline --colors --display-error-details --display-cached", @@ -24,9 +24,10 @@ "start": "npm run flow.serve:dev", "pretest": "npm run flow.lint", "test": "NODE_ENV=test ./node_modules/.bin/karma start", + "test:watch": "NODE_ENV=test ./node_modules/.bin/karma start --auto-watch --no-single-run", "preversion": "npm test", "version": "npm run flow.changelog && git add -A", - "postversion": "git push origin master && git push --tags" + "postversion": "git push origin development && git push --tags" }, "main": "ng2-file-upload.js", "typings": "ng2-file-upload.d.ts", @@ -34,7 +35,9 @@ "angular2", "bootstrap", "angularjs", - "twitter-bootstrap" + "twitter-bootstrap", + "file-upload", + "angular-file-upload" ], "author": "Vyacheslav Chub <vyacheslav.chub@valor-software.com>", "license": "MIT", @@ -48,69 +51,49 @@ "homepage": "https://github.com/valor-software/ng2-file-upload#readme", "dependencies": {}, "peerDependencies": { - "@angular/common": "^2.0.0-rc.1", - "@angular/core": "^2.0.0-rc.1" + "@angular/common": "2.0.0-rc.7", + "@angular/compiler": "2.0.0-rc.7", + "@angular/core": "2.0.0-rc.7", + "@angular/forms": "2.0.0-rc.7" }, "devDependencies": { - "@angular/common": "^2.0.0-rc.1", - "@angular/compiler": "^2.0.0-rc.1", - "@angular/core": "^2.0.0-rc.1", - "@angular/platform-browser": "^2.0.0-rc.1", - "@angular/platform-browser-dynamic": "^2.0.0-rc.1", - "async": "1.5.2", - "bootstrap": "3.3.6", + "@angular/common": "2.0.0-rc.7", + "@angular/compiler": "2.0.0-rc.7", + "@angular/core": "2.0.0-rc.7", + "@angular/forms": "2.0.0-rc.7", + "@angular/platform-browser": "2.0.0-rc.7", + "@angular/platform-browser-dynamic": "2.0.0-rc.7", + "async": "2.0.1", + "bootstrap": "3.3.7", "codecov": "1.0.1", - "compression-webpack-plugin": "0.3.1", "conventional-changelog-cli": "1.2.0", - "conventional-github-releaser": "1.1.2", - "copy-webpack-plugin": "3.0.1", + "conventional-github-releaser": "1.1.3", "cpy-cli": "1.0.1", - "del": "^2.2.0", "del-cli": "0.2.0", - "es6-promise": "3.1.2", - "es6-shim": "0.35.0", + "es6-promise": "3.3.1", + "es6-shim": "0.35.1", "es7-reflect-metadata": "1.6.0", - "eslint-config-valorsoft": "0.0.15", - "exports-loader": "0.6.3", - "file-loader": "0.8.5", + "eslint-config-valorsoft": "0.1.0", "gh-pages": "0.11.0", + "gitignore-to-glob": "0.2.1", "gulp": "3.9.1", "gulp-size": "2.1.0", - "gulp-tslint": "5.0.0", - "html-loader": "0.4.3", - "html-webpack-plugin": "2.19.0", - "istanbul-instrumenter-loader": "0.2.0", - "jasmine": "2.4.1", - "karma": "0.13.22", - "karma-chrome-launcher": "1.0.1", - "karma-coverage": "1.0.0", - "karma-jasmine": "1.0.2", - "karma-phantomjs-launcher": "1.0.0", - "karma-sourcemap-loader": "0.3.7", - "karma-spec-reporter": "0.0.26", - "karma-webpack": "1.7.0", - "lite-server": "2.2.0", - "markdown-loader": "0.1.7", - "marked": "0.3.5", - "ng2-bootstrap": "1.0.17", - "phantomjs-polyfill": "0.0.2", - "phantomjs-prebuilt": "2.1.7", + "gulp-tslint": "6.1.1", + "lite-server": "2.2.2", + "marked": "0.3.6", + "ng2-bootstrap": "1.1.3", + "ng2-webpack-config": "0.0.4", "pre-commit": "1.1.3", - "prismjs": "1.4.1", + "prismjs": "1.5.1", "prismjs-loader": "0.0.3", - "raw-loader": "0.5.1", - "reflect-metadata": "0.1.2", + "reflect-metadata": "0.1.8", "require-dir": "0.3.0", - "rxjs": "5.0.0-beta.6", - "source-map-loader": "0.1.5", - "systemjs-builder": "0.15.19", - "ts-loader": "0.8.2", - "tslint-config-valorsoft": "1.0.3", + "rxjs": "5.0.0-beta.11", + "systemjs-builder": "0.15.31", + "tslint-config-valorsoft": "1.1.1", "typescript": "1.8.10", - "typings": "0.8.1", - "webpack": "1.13.1", - "webpack-dev-server": "1.14.1", - "zone.js": "0.6.12" + "typings": "1.3.3", + "zone.js": "0.6.23" }, "contributors": [ { @@ -122,6 +105,16 @@ "name": "Dmitriy Shekhovtsov", "email": "valorkin@gmail.com", "url": "https://github.com/valorkin" + }, + { + "name": "Adrian Faciu", + "email": "adrian.faciu@gmail.com", + "url": "https://github.com/adrianfaciu" + }, + { + "name": "Oleksandr Telnov", + "email": "otelnov@gmail.com", + "url": "https://github.com/otelnov" } ] } diff --git a/protractor.conf.js b/protractor.conf.js new file mode 100644 index 00000000..2f1cac81 --- /dev/null +++ b/protractor.conf.js @@ -0,0 +1,5 @@ +'use strict'; + +const config = require('./.ng2-config'); + +module.exports.config = require('ng2-webpack-config').protractor(config); diff --git a/spec-bundle.js b/spec-bundle.js new file mode 100644 index 00000000..fb8a3922 --- /dev/null +++ b/spec-bundle.js @@ -0,0 +1,65 @@ +/* eslint no-var: 0, vars-on-top: 0 */ +/** + * @author: @AngularClass + */ + +/* + * When testing with webpack and ES6, we have to do some extra + * things to get testing to work right. Because we are gonna write tests + * in ES6 too, we have to compile those as well. That's handled in + * karma.conf.js with the karma-webpack plugin. This is the entry + * file for webpack test. Just like webpack will create a bundle.js + * file for our client, when we run test, it will compile and bundle them + * all here! Crazy huh. So we need to do some setup + */ +'use strict'; +Error.stackTraceLimit = Infinity; + +require('core-js'); + +// Typescript emit helpers polyfill +require('ts-helpers'); + +require('zone.js/dist/zone'); +require('zone.js/dist/long-stack-trace-zone'); +require('zone.js/dist/async-test'); +require('zone.js/dist/fake-async-test'); +require('zone.js/dist/sync-test'); +require('zone.js/dist/proxy'); +require('zone.js/dist/jasmine-patch'); + +// RxJS +require('rxjs/Rx'); + +var testing = require('@angular/core/testing'); +var browser = require('@angular/platform-browser-dynamic/testing'); + +testing.TestBed.initTestEnvironment( + browser.BrowserDynamicTestingModule, + browser.platformBrowserDynamicTesting() +); + +Object.assign(global, testing); + +/* + * Ok, this is kinda crazy. We can use the the context method on + * require that webpack created in order to tell webpack + * what files we actually want to require or import. + * Below, context will be an function/object with file names as keys. + * using that regex we are saying look in ./src/app and ./test then find + * any file that ends with spec.js and get its path. By passing in true + * we say do this recursively + */ +var testContext = require.context('./components', true, /\.spec\.ts/); + +/* + * get all the files, for each file, call the context function + * that will require the file and load it up here. Context will + * loop and require those spec files here + */ +function requireAll(requireContext) { + return requireContext.keys().map(requireContext); +} + +// requires and returns all modules that match +requireAll(testContext); diff --git a/test.bundle.js b/test.bundle.js deleted file mode 100644 index 9ade8579..00000000 --- a/test.bundle.js +++ /dev/null @@ -1,47 +0,0 @@ -'use strict'; - -/* eslint vars-on-top:0 no-var:0 */ -// @AngularClass -/* - * When testing with webpack and ES6, we have to do some extra - * things get testing to work right. Because we are gonna write test - * in ES6 to, we have to compile those as well. That's handled in - * karma.conf.js with the karma-webpack plugin. This is the entry - * file for webpack test. Just like webpack will create a bundle.js - * file for our client, when we run test, it well compile and bundle them - * all here! Crazy huh. So we need to do some setup - */ -Error.stackTraceLimit = Infinity; -require('phantomjs-polyfill'); -require('es6-promise'); -require('es6-shim'); -require('es7-reflect-metadata/dist/browser'); - -// require('zone.js'); -require('zone.js/dist/zone.js'); -require('zone.js/dist/long-stack-trace-zone.js'); -require('zone.js/dist/jasmine-patch.js'); -require('zone.js/dist/async-test.js'); - -var testing = require('@angular/core/testing'); -var browser = require('@angular/platform-browser-dynamic/testing'); - -testing.setBaseTestProviders( - browser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, - browser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS); - -/* - Ok, this is kinda crazy. We can use the the context method on - require that webpack created in order to tell webpack - what files we actually want to require or import. - Below, context will be an function/object with file names as keys. - using that regex we are saying look in ./src/app and ./test then find - any file that ends with spec.js and get its path. By passing in true - we say do this recursively - */ -var testContext = require.context('./components', true, /\.spec\.ts/); - -// get all the files, for each file, call the context function -// that will require the file and load it up here. Context will -// loop and require those spec files here -testContext.keys().forEach(testContext); diff --git a/tsconfig.json b/tsconfig.json index c02a3672..ce9889d3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,18 +2,22 @@ "compilerOptions": { "target": "es5", "module": "commonjs", - "moduleResolution": "node", "sourceMap": false, "declaration": true, - "removeComments": false, + "removeComments": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, - "noImplicitAny": true, "listFiles": false, - "noLib": false + "noLib": false, + "noImplicitAny": true, + "suppressImplicitAnyIndexErrors": true }, + "exclude": [ + "node_modules" + ], "files": [ - "./typings/browser.d.ts", - "./ng2-file-upload.ts" + "./ng2-file-upload.ts", + "./demo/custom-typings.d.ts", + "./typings/index.d.ts" ] -} \ No newline at end of file +} diff --git a/tsconfig.publish.json b/tsconfig.publish.json new file mode 100644 index 00000000..fe329c5b --- /dev/null +++ b/tsconfig.publish.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "sourceMap": false, + "noEmitHelpers": false, + "noImplicitAny": true, + "declaration": true + }, + "exclude": [ + "node_modules" + ], + "files": [ + "./typings/index.d.ts", + "./demo/custom-typings.d.ts", + "./ng2-file-upload.ts" + ] +} diff --git a/tslint.json b/tslint.json index ea3f7760..589765ab 100644 --- a/tslint.json +++ b/tslint.json @@ -1,4 +1,8 @@ { "extends": "tslint-config-valorsoft", - "rulesDirectory": "./node_modules/codelyzer" + "rulesDirectory": "./node_modules/codelyzer", + "rules": { + "component-selector-name": [false, ""], + "only-arrow-functions": false + } } diff --git a/typings.json b/typings.json index 592b524e..797944f4 100644 --- a/typings.json +++ b/typings.json @@ -1,12 +1,10 @@ { - "dependencies": { - "moment": "registry:npm/moment#2.10.5+20160211003958", - "webpack": "registry:npm/webpack#1.12.9+20160219013405" - }, - "devDependencies": {}, - "ambientDependencies": { - "es6-shim": "registry:dt/es6-shim#0.31.2+20160317120654", - "jasmine": "registry:dt/jasmine#2.2.0+20160317120654", + "globalDependencies": { + "es6-shim": "registry:dt/es6-shim#0.31.2+20160602141504", + "jasmine": "registry:dt/jasmine#2.2.0+20160621224255", "require": "registry:dt/require#2.1.20+20160316155526" + }, + "dependencies": { + "webpack": "registry:npm/webpack#1.12.9+20160418172948" } } diff --git a/webpack.config.js b/webpack.config.js index 2bb28437..39342032 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,15 +1,12 @@ -/* eslint global-require: 0 */ +/* eslint no-process-env: 0, global-require:0 */ +/** + * @author: @AngularClass + */ 'use strict'; -const path = require('path'); -const marked = require('marked'); -const webpack = require('webpack'); const reqPrism = require('prismjs'); -const CompressionPlugin = require('compression-webpack-plugin'); -const CopyWebpackPlugin = require('copy-webpack-plugin'); -const HtmlWebpackPlugin = require('html-webpack-plugin'); +const marked = require('marked'); -// marked renderer hack marked.Renderer.prototype.code = function renderCode(code, lang) { const out = this.options.highlight(code, lang); const classMap = this.options.langPrefix + lang; @@ -20,159 +17,35 @@ marked.Renderer.prototype.code = function renderCode(code, lang) { return `<pre class="${classMap}"><code class="${classMap}">${out}\n</code></pre>\n`; }; -/*eslint no-process-env:0, camelcase:0*/ -const isProduction = (process.env.NODE_ENV || 'development') === 'production'; -const devtool = process.env.NODE_ENV === 'test' ? 'inline-source-map' : 'source-map'; -const dest = 'demo-build'; -const absDest = root(dest); - -const config = { - // isProduction ? 'source-map' : 'evale', - devtool, - debug: false, - - verbose: true, - displayErrorDetails: true, - context: __dirname, - stats: { - colors: true, - reasons: true - }, - - resolve: { - cache: false, - root: __dirname, - extensions: ['', '.ts', '.js', '.json'] - }, - - entry: { - angular2: [ - // Angular 2 Deps - 'es6-shim', - 'es6-promise', - 'zone.js', - 'reflect-metadata', - '@angular/common', - '@angular/core' - ], - 'angular2-bootstrap': ['ng2-file-upload'], - 'angular2-bootstrap-demo': 'demo' - }, - - output: { - path: absDest, - filename: '[name].js', - sourceMapFilename: '[name].js.map', - chunkFilename: '[id].chunk.js' - }, +// Look in ./config folder for webpack.dev.js +const conf = getWebpackConfig(process.env.NODE_ENV, require('./.ng2-config')); - // our Development Server configs - devServer: { - inline: true, - colors: true, - historyApiFallback: true, - contentBase: dest, - //publicPath: dest, - outputPath: dest, - watchOptions: {aggregateTimeout: 300, poll: 1000} - }, +conf.markdownLoader = { + langPrefix: 'language-', + highlight(code, lang) { + const language = !lang || lang === 'html' ? 'markup' : lang; + const Prism = global.Prism || reqPrism; - markdownLoader: { - langPrefix: 'language-', - highlight(code, lang) { - const language = !lang || lang === 'html' ? 'markup' : lang; - const Prism = global.Prism || reqPrism; - - if (!Prism.languages[language]) { - require(`prismjs/components/prism-${language}.js`); - } - return Prism.highlight(code, Prism.languages[language]); - } - }, - module: { - loaders: [ - // support markdown - {test: /\.md$/, loader: 'html?minimize=false!markdown'}, - // Support for *.json files. - {test: /\.json$/, loader: 'json'}, - // Support for CSS as raw text - {test: /\.css$/, loader: 'raw'}, - // support for .html as raw text - {test: /\.html$/, loader: 'raw'}, - // Support for .ts files. - { - test: /\.ts$/, - loader: 'ts', - query: { - compilerOptions: { - removeComments: true, - noEmitHelpers: false - } - }, - exclude: [/\.(spec|e2e)\.ts$/] - } - ], - noParse: [ - /rtts_assert\/src\/rtts_assert/, - /reflect-metadata/, - /zone\.js\/dist\/zone-microtask/ - ] - }, - - plugins: [ - //new Clean([dest]), - new webpack.optimize.DedupePlugin(), - new webpack.optimize.OccurenceOrderPlugin(true), - new webpack.optimize.CommonsChunkPlugin({ - name: 'angular2', - minChunks: Infinity, - filename: 'angular2.js' - }), - // static assets - new CopyWebpackPlugin([{from: 'demo/favicon.ico', to: 'favicon.ico'}]), - new CopyWebpackPlugin([{from: 'demo/assets', to: 'assets'}]), - // generating html - new HtmlWebpackPlugin({template: 'demo/index.html'}) - ], - pushPlugins() { - if (!isProduction) { - return; + if (!Prism.languages[language]) { + require(`prismjs/components/prism-${language}.js`); } - const plugins = [ - //production only - new webpack.optimize.UglifyJsPlugin({ - beautify: false, - mangle: false, - comments: false, - compress: { - screw_ie8: true - //warnings: false, - //drop_debugger: false - } - //verbose: true, - //beautify: false, - //quote_style: 3 - }), - new CompressionPlugin({ - asset: '{file}.gz', - algorithm: 'gzip', - regExp: /\.js$|\.html|\.css|.map$/, - threshold: 10240, - minRatio: 0.8 - }) - ]; - - this - .plugins - .push - .apply(plugins); + return Prism.highlight(code, Prism.languages[language]); } }; -config.pushPlugins(); - -module.exports = config; - -function root(partialPath) { - return path.join(__dirname, partialPath); +module.exports = conf; + +function getWebpackConfig(env, config) { + switch (env) { + case 'prod': + case 'production': + return require('ng2-webpack-config').webpack.prod(config); + case 'test': + case 'testing': + return require('ng2-webpack-config').webpack.test(config); + case 'dev': + case 'development': + default: + return require('ng2-webpack-config').webpack.dev(config); + } }