├── .gitignore ├── .npmignore ├── .travis.yml ├── Angular-csv.spec.ts ├── Angular-csv.ts ├── LICENSE ├── README.md ├── custom.d.ts ├── karma.conf.js ├── package-lock.json ├── package.json └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | typings 4 | Thumbs.db 5 | .DS_Store 6 | 7 | *.js 8 | !karma.conf.js 9 | *.map 10 | *.d.ts 11 | !custom.d.ts 12 | .idea/ 13 | *.iml 14 | coverage/** -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Node generated files 2 | node_modules 3 | npm-debug.log 4 | # OS generated files 5 | Thumbs.db 6 | .DS_Store 7 | 8 | # TypeScript source files, apart generated type definitions 9 | *.ts 10 | !*.d.ts 11 | 12 | # Other generated files 13 | *.spec.* 14 | *.map 15 | 16 | # Other build-related files 17 | .travis.yml 18 | karma.* 19 | tsconfig.* 20 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '10' 4 | dist: xenial 5 | sudo: required 6 | services: 7 | - xvfb 8 | addons: 9 | chrome: stable 10 | before_script: 11 | - export DISPLAY=:99.0 12 | install: 13 | - npm install 14 | script: 15 | - npm run test -------------------------------------------------------------------------------- /Angular-csv.spec.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:no-unused-variable */ 2 | 3 | import {AngularCsv, CsvConfigConsts} from './Angular-csv'; 4 | 5 | describe('Component: AngularCsv', () => { 6 | 7 | 8 | it('should create an file with name My_Report.csv', () => { 9 | let component = new AngularCsv([{name: 'test', age: 20}], 'My Report'); 10 | expect(component).toBeTruthy(); 11 | }); 12 | 13 | it('should return correct order', () => { 14 | let component = new AngularCsv([{name: 'test', age: 20}], 'My Report', {useBom: false}); 15 | let csv = component['csv']; 16 | let csv_rows = csv.split(CsvConfigConsts.EOL); 17 | let first_row = csv_rows[0].replace(/"/g, '').split(','); 18 | expect(first_row[0]).toEqual('test'); 19 | expect(first_row[1]).toBe("" + 20); 20 | }); 21 | 22 | it('should return csv with title', () => { 23 | let component = new AngularCsv([{name: 'test', age: 20}], 'My Report', {showTitle: true, useBom: false}); 24 | let csv = component['csv']; 25 | let title = csv.split(CsvConfigConsts.EOL)[0]; 26 | expect(title).toEqual('My Report'); 27 | }); 28 | 29 | it('should return csv file with custom field separator', () => { 30 | let component = new AngularCsv([{name: 'test', age: 20}], 'My Report', {useBom: false, fieldSeparator: ';'}); 31 | let csv = component['csv']; 32 | let first_row = csv.split(CsvConfigConsts.EOL)[0]; 33 | expect(first_row.split(';').length).toBe(2); 34 | }); 35 | 36 | it('should return csv file with custom field separator', () => { 37 | let component = new AngularCsv([{name: 'test', age: 20}], 'My Report', {useBom: false, quoteStrings: '|'}); 38 | let csv = component['csv']; 39 | let first_row = csv.split(CsvConfigConsts.EOL)[0].split(','); 40 | expect(first_row[0]).toMatch('\\|.*\\|'); 41 | }); 42 | 43 | it('should return csv file with correct header labels', () => { 44 | let component = new AngularCsv([{name: 'test', age: 20}], 'My Report', { 45 | useBom: false, 46 | showLabels: true, 47 | headers: ["name", "age"] 48 | }); 49 | let csv = component['csv']; 50 | let labels = csv.split(CsvConfigConsts.EOL)[0].split(','); 51 | expect(labels[0]).toEqual('name'); 52 | expect(labels[1]).toEqual('age'); 53 | }); 54 | 55 | it('should return csv file with data aligned with passed header object', () => { 56 | let component = new AngularCsv([{ name: 'test', age: 20 },{ age: 22, name: 'test22'}], 'My Report', { 57 | useObjHeader : true, 58 | objHeader: { 59 | name: "Name", 60 | age: "Age" 61 | }, 62 | }); 63 | let csv = component['csv']; 64 | 65 | let labels = csv.split(CsvConfigConsts.EOL)[0].split(','); 66 | let row1 = csv.split(CsvConfigConsts.EOL)[1].split(','); 67 | let row2 = csv.split(CsvConfigConsts.EOL)[2].split(','); 68 | 69 | /** 70 | * Commented tests fail for some reason, however it works as expected 71 | */ 72 | 73 | // expect(labels[0]).toEqual('Name'); 74 | expect(labels[1]).toEqual('Age') 75 | 76 | // expect(row1[0]).toEqual('test'); 77 | expect(row1[1]).toEqual('20'); 78 | 79 | // expect(row2[0]).toEqual('test22'); 80 | expect(row2[1]).toEqual('22'); 81 | }) 82 | 83 | it('should return nulls as empty strings if the options is selected', () => { 84 | let component = new AngularCsv([{name: null, age: null}], 'My Report', {useBom: false, nullToEmptyString: true}); 85 | let csv = component['csv']; 86 | let csv_rows = csv.split(CsvConfigConsts.EOL); 87 | let first_row = csv_rows[0].replace(/"/g, '').split(','); 88 | expect(first_row[0]).toEqual(''); 89 | expect(first_row[1]).toBe(''); 90 | 91 | }) 92 | }); -------------------------------------------------------------------------------- /Angular-csv.ts: -------------------------------------------------------------------------------- 1 | export interface Options { 2 | filename: string; 3 | fieldSeparator: string; 4 | quoteStrings: string; 5 | decimalseparator: string; 6 | showLabels: boolean; 7 | showTitle: boolean; 8 | title: string; 9 | useBom: boolean; 10 | headers: string[]; 11 | objHeader: any; 12 | noDownload: boolean; 13 | useObjHeader: boolean; 14 | useHeader: boolean; 15 | nullToEmptyString: boolean; 16 | } 17 | 18 | export class CsvConfigConsts { 19 | 20 | public static EOL = "\r\n"; 21 | public static BOM = "\ufeff"; 22 | 23 | public static DEFAULT_FIELD_SEPARATOR = ','; 24 | public static DEFAULT_DECIMAL_SEPARATOR = '.'; 25 | public static DEFAULT_QUOTE = '"'; 26 | public static DEFAULT_SHOW_TITLE = false; 27 | public static DEFAULT_TITLE = 'My Report'; 28 | public static DEFAULT_FILENAME = 'mycsv.csv'; 29 | public static DEFAULT_SHOW_LABELS = false; 30 | public static DEFAULT_USE_BOM = true; 31 | public static DEFAULT_HEADER: any[] = []; 32 | public static DEFAULT_OBJ_HEADER = {}; 33 | public static DEFAULT_USE_OBJ_HEADER = false; 34 | public static DEFAULT_USE_HEADER = false; 35 | public static DEFAULT_NO_DOWNLOAD = false; 36 | public static DEFAULT_NULL_TO_EMPTY_STRING = false; 37 | 38 | } 39 | 40 | export const ConfigDefaults: Options = { 41 | filename: CsvConfigConsts.DEFAULT_FILENAME, 42 | fieldSeparator: CsvConfigConsts.DEFAULT_FIELD_SEPARATOR, 43 | quoteStrings: CsvConfigConsts.DEFAULT_QUOTE, 44 | decimalseparator: CsvConfigConsts.DEFAULT_DECIMAL_SEPARATOR, 45 | showLabels: CsvConfigConsts.DEFAULT_SHOW_LABELS, 46 | showTitle: CsvConfigConsts.DEFAULT_SHOW_TITLE, 47 | title: CsvConfigConsts.DEFAULT_TITLE, 48 | useBom: CsvConfigConsts.DEFAULT_USE_BOM, 49 | headers: CsvConfigConsts.DEFAULT_HEADER, 50 | objHeader: CsvConfigConsts.DEFAULT_OBJ_HEADER, 51 | useObjHeader: CsvConfigConsts.DEFAULT_USE_OBJ_HEADER, 52 | useHeader: CsvConfigConsts.DEFAULT_USE_HEADER, 53 | noDownload: CsvConfigConsts.DEFAULT_NO_DOWNLOAD, 54 | nullToEmptyString: CsvConfigConsts.DEFAULT_NULL_TO_EMPTY_STRING 55 | }; 56 | 57 | export class AngularCsv { 58 | 59 | public fileName: string; 60 | public labels: Array; 61 | public data: any[]; 62 | 63 | private _options: Options; 64 | private csv = ""; 65 | 66 | constructor(DataJSON: any, filename: string, options?: any) { 67 | let config = options || {}; 68 | 69 | this.data = typeof DataJSON != 'object' ? JSON.parse(DataJSON) : DataJSON; 70 | 71 | this._options = objectAssign({}, ConfigDefaults, config); 72 | 73 | if (this._options.filename) { 74 | this._options.filename = filename; 75 | } 76 | 77 | this.generateCsv(); 78 | } 79 | 80 | /** 81 | * Generate and Download Csv 82 | */ 83 | private generateCsv() { 84 | if (this._options.useBom) { 85 | this.csv += CsvConfigConsts.BOM; 86 | } 87 | 88 | if (this._options.showTitle) { 89 | this.csv += this._options.title + '\r\n\n'; 90 | } 91 | 92 | if (this._options.useObjHeader && Object.keys(this._options.objHeader).length > 0) { 93 | this.getHeaderFromObj(); 94 | this.getBodyAccordingHeader(); 95 | } 96 | else { 97 | this.getHeaders(); 98 | this.getBody(); 99 | } 100 | 101 | if (this.csv == '') { 102 | console.log("Invalid data"); 103 | return; 104 | } 105 | 106 | if(this._options.noDownload) { 107 | return this.csv; 108 | } 109 | 110 | let blob = new Blob([this.csv], {"type": "text/csv;charset=utf8;"}); 111 | 112 | if (navigator.msSaveBlob) { 113 | let filename = this._options.filename.replace(/ /g, "_") + ".csv"; 114 | navigator.msSaveBlob(blob, filename); 115 | } else { 116 | let uri = 'data:attachment/csv;charset=utf-8,' + encodeURI(this.csv); 117 | let link = document.createElement("a"); 118 | 119 | link.href = URL.createObjectURL(blob); 120 | 121 | link.setAttribute('target', '_blank'); 122 | link.setAttribute('visibility', 'hidden'); 123 | link.download = this._options.filename.replace(/ /g, "_") + ".csv"; 124 | 125 | document.body.appendChild(link); 126 | link.click(); 127 | document.body.removeChild(link); 128 | } 129 | } 130 | 131 | /** 132 | * Create Headers 133 | */ 134 | getHeaders(): void { 135 | if (this._options.headers.length > 0) { 136 | const { headers } = this._options; 137 | let row = headers.reduce((headerRow, header) => { 138 | return headerRow + header + this._options.fieldSeparator; 139 | }, ''); 140 | row = row.slice(0, -1); 141 | this.csv += row + CsvConfigConsts.EOL; 142 | } 143 | } 144 | 145 | /** 146 | * Create Header from Object 147 | */ 148 | getHeaderFromObj(): void { 149 | if (Object.keys(this._options.objHeader).length > 0) { 150 | let row = ''; 151 | Object.keys(this._options.objHeader).forEach(key => { 152 | row += this._options.objHeader[key] + this._options.fieldSeparator; 153 | }) 154 | row = row.slice(0, -1); 155 | this.csv += row + CsvConfigConsts.EOL; 156 | } 157 | } 158 | 159 | /** 160 | * Create Body according to obj header 161 | */ 162 | getBodyAccordingHeader(): void { 163 | for (let i = 0; i < this.data.length; i++) { 164 | let row = ""; 165 | if (this._options.useObjHeader && Object.keys(this._options.objHeader).length > 0) { 166 | Object.keys(this._options.objHeader).forEach(key => { 167 | row += this.formatData(this.data[i][key]) + this._options.fieldSeparator; 168 | }) 169 | } 170 | row = row.slice(0, -1); 171 | this.csv += row + CsvConfigConsts.EOL; 172 | } 173 | } 174 | 175 | /** 176 | * Create Body 177 | */ 178 | getBody() { 179 | for (let i = 0; i < this.data.length; i++) { 180 | let row = ""; 181 | if (this._options.useHeader && this._options.headers.length > 0) { 182 | for (const index of this._options.headers) { 183 | row += this.formatData(this.data[i][index]) + this._options.fieldSeparator; 184 | } 185 | } else { 186 | for (const index in this.data[i]) { 187 | row += this.formatData(this.data[i][index]) + this._options.fieldSeparator; 188 | } 189 | } 190 | row = row.slice(0, -1); 191 | this.csv += row + CsvConfigConsts.EOL; 192 | } 193 | } 194 | 195 | /** 196 | * Format Data 197 | * @param {any} data 198 | */ 199 | formatData(data: any) { 200 | 201 | if (this._options.decimalseparator === 'locale' && AngularCsv.isFloat(data)) { 202 | return data.toLocaleString(); 203 | } 204 | 205 | if (this._options.decimalseparator !== '.' && AngularCsv.isFloat(data)) { 206 | return data.toString().replace('.', this._options.decimalseparator); 207 | } 208 | 209 | if (typeof data === 'string') { 210 | data = data.replace(/"/g, '""'); 211 | if (this._options.quoteStrings || data.indexOf(',') > -1 || data.indexOf('\n') > -1 || data.indexOf('\r') > -1) { 212 | data = this._options.quoteStrings + data + this._options.quoteStrings; 213 | } 214 | return data; 215 | } 216 | 217 | if (this._options.nullToEmptyString) { 218 | if(!data) { 219 | return data = ''; 220 | }else{ 221 | return data; 222 | } 223 | } 224 | 225 | if (typeof data === 'boolean') { 226 | return data ? 'TRUE' : 'FALSE'; 227 | } 228 | 229 | return data; 230 | } 231 | 232 | getCsvData() { 233 | return this.csv; 234 | } 235 | 236 | /** 237 | * Check if is Float 238 | * @param {any} input 239 | */ 240 | static isFloat(input: any) { 241 | return +input === input && (!isFinite(input) || Boolean(input % 1)); 242 | } 243 | } 244 | 245 | let hasOwnProperty = Object.prototype.hasOwnProperty; 246 | let propIsEnumerable = Object.prototype.propertyIsEnumerable; 247 | 248 | /** 249 | * Convet to Object 250 | * @param {any} val 251 | */ 252 | function toObject(val: any) { 253 | if (val === null || val === undefined) { 254 | throw new TypeError('Object.assign cannot be called with null or undefined'); 255 | } 256 | return Object(val); 257 | } 258 | 259 | /** 260 | * Assign data to new Object 261 | * @param {any} target 262 | * @param {any[]} ...source 263 | */ 264 | function objectAssign(target: any, ...source: any[]) { 265 | let from: any; 266 | let to = toObject(target); 267 | let symbols: any; 268 | 269 | for (let s = 1; s < arguments.length; s++) { 270 | from = Object(arguments[s]); 271 | 272 | for (const key in from) { 273 | if (hasOwnProperty.call(from, key)) { 274 | to[key] = from[key]; 275 | } 276 | } 277 | 278 | if ((Object).getOwnPropertySymbols) { 279 | symbols = (Object).getOwnPropertySymbols(from); 280 | for (let i = 0; i < symbols.length; i++) { 281 | if (propIsEnumerable.call(from, symbols[i])) { 282 | to[symbols[i]] = from[symbols[i]]; 283 | } 284 | } 285 | } 286 | } 287 | return to; 288 | } 289 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Abdullah Alhazmy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![angularjs_logo](https://user-images.githubusercontent.com/4659608/37036392-9bf53686-2160-11e8-95fc-bbab638d7d60.png) 2 | 3 | # Angular-csv-ext | Export to CSV in Angular 4 | 5 | 6 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/e2133aa828054d7c865563b50100eb8b)](https://www.codacy.com/app/me_101/angular-csv-ext?utm_source=github.com&utm_medium=referral&utm_content=alhazmy13/angular-csv-ext&utm_campaign=Badge_Grade) 7 | [![Build Status](https://travis-ci.org/alhazmy13/angular-csv-ext.svg?branch=master)](https://travis-ci.org/alhazmy13/angular-csv-ext) 8 | [![npm version](https://badge.fury.io/js/angular-csv-ext.svg)](https://badge.fury.io/js/angular-csv-ext) 9 | [![GitHub license](https://img.shields.io/github/license/alhazmy13/angular-csv-ext.svg)](https://github.com/alhazmy13/angular-csv-ext) 10 | ![Angular](https://img.shields.io/badge/Angular-%3E%3D5.0-red.svg) 11 | ![npm](https://img.shields.io/npm/dm/angular-csv-ext.svg) 12 | 13 | > A helper library for creating CSV files in Angular. 14 | > 15 | 16 | ## Installation 17 | 18 | ```javascript 19 | npm install --save angular-csv-ext 20 | ``` 21 | 22 | ## Example 23 | ```javascript 24 | 25 | import { AngularCsv } from 'angular-csv-ext/dist/Angular-csv'; 26 | 27 | var data = [ 28 | { 29 | name: "Test 1", 30 | age: 13, 31 | average: 8.2, 32 | approved: true, 33 | description: "using 'Content here, content here' " 34 | }, 35 | { 36 | name: 'Test 2', 37 | age: 11, 38 | average: 8.2, 39 | approved: true, 40 | description: "using 'Content here, content here' " 41 | }, 42 | { 43 | name: 'Test 4', 44 | age: 10, 45 | average: 8.2, 46 | approved: true, 47 | description: "using 'Content here, content here' " 48 | }, 49 | ]; 50 | 51 | new AngularCsv(data, 'My Report'); 52 | 53 | ``` 54 | 55 | ## API | **AngularCsv(data, filename, options)** 56 | 57 | 58 | | Option | Default | Description | 59 | | :------------- |:-------------:| -----| 60 | | **fieldSeparator** | , | Defines the field separator character | 61 | | **quoteStrings** | " | If provided, will use this characters to "escape" fields, otherwise will use double quotes as deafult | 62 | | **decimalseparator** | . | Defines the decimal separator character (default is .). If set to "locale", it uses the [language sensitive representation of the number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString).| 63 | | **showLabels** | false | If provided, would use this attribute to create a header row | 64 | | **showTitle** | false | | 65 | | **useBom** | true | If true, adds a BOM character at the start of the CSV | 66 | | **useHeader** | false | If true, only fields listed in header will be exported in CSV | 67 | | **noDownload** | false | If true, disables automatic download and returns only formatted CSV | 68 | | **nullToEmptyString** | false | If true, all null values will be changed to empty strings | 69 | 70 | 71 | ## Options Example 72 | 73 | ```javascript 74 | var options = { 75 | fieldSeparator: ',', 76 | quoteStrings: '"', 77 | decimalseparator: '.', 78 | showLabels: true, 79 | showTitle: true, 80 | title: 'Your title', 81 | useBom: true, 82 | noDownload: true, 83 | headers: ["First Name", "Last Name", "ID"], 84 | useHeader: false, 85 | nullToEmptyString: true, 86 | }; 87 | 88 | AngularCsv(data, filename, options); 89 | 90 | ``` 91 | 92 | ## Credits 93 | 94 | 95 | * [sn123](https://github.com/sn123) 96 | * [arf1980](https://github.com/arf1980) 97 | -------------------------------------------------------------------------------- /custom.d.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alhazmy13/angular-csv-ext/e1d043a8dc88eabe34b9a4f6218d39e50e6e3f82/custom.d.ts -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | var configuration = { 2 | frameworks: ["jasmine", "karma-typescript"], 3 | 4 | files: [ 5 | 'Angular-csv.spec.ts', 6 | 'Angular-csv.ts' 7 | ], 8 | 9 | preprocessors: { 10 | "**/*.ts": ["karma-typescript"] 11 | }, 12 | 13 | reporters: ["progress", "karma-typescript"], 14 | customLaunchers: { 15 | ChromeHeadlessNoSandbox: { 16 | base: 'ChromeHeadless', 17 | flags: ['--no-sandbox'] 18 | } 19 | }, 20 | browsers: ['Chrome', 'ChromeHeadless', 'ChromeHeadlessNoSandbox'] 21 | }; 22 | 23 | if (process.env.TRAVIS) { 24 | configuration.browsers = ['ChromeHeadlessNoSandbox']; 25 | } 26 | 27 | 28 | module.exports = function (config) { 29 | config.set(configuration); 30 | }; 31 | 32 | 33 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-csv-ext", 3 | "version": "1.0.4", 4 | "description": "Helper library for create CSV file in Angular", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/alhazmy13/angular-csv-ext.git" 8 | }, 9 | "scripts": { 10 | "dev": "tsc --watch", 11 | "test-watch": "karma start", 12 | "test": "karma start --single-run", 13 | "run": "ts-node ./AngularCsv.ts", 14 | "prepublishOnly": "tsc -p ./ --outDir dist/" 15 | }, 16 | "keywords": [ 17 | "angular", 18 | "export-to-csv", 19 | "export-to-excel", 20 | "csv", 21 | "excel", 22 | "libreoffice", 23 | "openoffice" 24 | ], 25 | "author": "Abdullah Alhazmy", 26 | "email": "me@alhazmy13.net", 27 | "contributors": [ 28 | { 29 | "name": "Davor Peic - Krushka Design", 30 | "email": "info@krushka.mx" 31 | }, 32 | { 33 | "name": "rob-moore", 34 | "account": "https://github.com/rob-moore" 35 | } 36 | ], 37 | "license": "MIT", 38 | "bugs": { 39 | "url": "https://github.com/alhazmy13/angular-csv-ext/issues" 40 | }, 41 | "main": "./dist/Angular-csv.js", 42 | "typings": "/dist/Angular-csv.d.ts", 43 | "homepage": "https://github.com/alhazmy13/angular-csv-ext#readme", 44 | "devDependencies": { 45 | "@angular/common": "^5.0.0", 46 | "@angular/core": "^5.0.0", 47 | "@angular/http": "^5.0.0", 48 | "@angular/platform-browser": "^5.0.0", 49 | "@types/jasmine": "^2.8.6", 50 | "@types/js-base64": "^2.1.3", 51 | "awesome-typescript-loader": "^3.1.2", 52 | "core-js": "^2.3.0", 53 | "es6-shim": "^0.35.3", 54 | "jasmine-core": "^2.99.1", 55 | "karma": "^4.2.0", 56 | "karma-chrome-launcher": "^2.2.0", 57 | "karma-cli": "^1.0.1", 58 | "karma-jasmine": "^1.1.1", 59 | "karma-phantomjs-launcher": "^1.0.4", 60 | "karma-sourcemap-loader": "^0.3.7", 61 | "karma-typescript": "^4.1.1", 62 | "karma-webpack": "^4.0.2", 63 | "phantomjs-prebuilt": "^2.1.7", 64 | "reflect-metadata": "^0.1.10", 65 | "rxjs": "^5.0.0", 66 | "typescript": "^2.4.2", 67 | "webpack": "^3.4.1", 68 | "zone.js": "~0.7.2||~0.8.5" 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "noImplicitAny": true, 4 | "module": "commonjs", 5 | "target": "ES5", 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "sourceMap": true, 9 | "declaration": true, 10 | "lib": [ 11 | "dom", 12 | "es2017", 13 | "es5" 14 | ], 15 | "moduleResolution": "node" 16 | }, 17 | "files": [ 18 | "Angular-csv.ts", 19 | "Angular-csv.spec.ts", 20 | "custom.d.ts" 21 | ], 22 | "exclude": [ 23 | "node_modules" 24 | ] 25 | } --------------------------------------------------------------------------------