├── .angular-cli.json
├── .gitignore
├── README.md
├── integration
├── app
│ ├── app-routing.module.ts
│ ├── app.component.css
│ ├── app.component.html
│ ├── app.component.spec.ts
│ ├── app.component.ts
│ ├── app.module.ts
│ └── page
│ │ ├── page.component.css
│ │ ├── page.component.html
│ │ └── page.component.ts
├── assets
│ └── .gitkeep
├── environments
│ ├── environment.prod.ts
│ └── environment.ts
├── favicon.ico
├── index.html
├── main.ts
├── polyfills.ts
├── styles.css
├── test.ts
├── tsconfig.app.json
├── tsconfig.spec.json
└── typings.d.ts
├── lib
├── README.md
├── package-lock.json
├── package.json
├── public_api.ts
├── spec
│ └── main.spec.ts
└── src
│ ├── gtag-event.directive.ts
│ ├── gtag.module.ts
│ ├── gtag.service.ts
│ └── interfaces.ts
├── package-lock.json
├── package.json
├── tsconfig.json
└── tslint.json
/.angular-cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "project": {
4 | "name": "myapp"
5 | },
6 | "apps": [
7 | {
8 | "root": "integration",
9 | "outDir": "dist",
10 | "assets": [
11 | "assets",
12 | "favicon.ico"
13 | ],
14 | "index": "index.html",
15 | "main": "main.ts",
16 | "polyfills": "polyfills.ts",
17 | "test": "test.ts",
18 | "tsconfig": "tsconfig.app.json",
19 | "testTsconfig": "tsconfig.spec.json",
20 | "prefix": "app",
21 | "styles": [
22 | "styles.css"
23 | ],
24 | "scripts": [],
25 | "environmentSource": "environments/environment.ts",
26 | "environments": {
27 | "dev": "environments/environment.ts",
28 | "prod": "environments/environment.prod.ts"
29 | }
30 | }
31 | ],
32 | "e2e": {
33 | "protractor": {
34 | "config": "./protractor.conf.js"
35 | }
36 | },
37 | "lint": [
38 | {
39 | "project": "integration/tsconfig.app.json",
40 | "exclude": "**/node_modules/**"
41 | },
42 | {
43 | "project": "integration/tsconfig.spec.json",
44 | "exclude": "**/node_modules/**"
45 | },
46 | {
47 | "project": "e2e/tsconfig.e2e.json",
48 | "exclude": "**/node_modules/**"
49 | }
50 | ],
51 | "test": {
52 | "karma": {
53 | "config": "./karma.conf.js"
54 | }
55 | },
56 | "defaults": {
57 | "styleExt": "css",
58 | "component": {}
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /dist-server
6 | /tmp
7 | /out-tsc
8 | /public
9 | /lib/dist
10 | /lib/dist.tgz
11 | /lib/node_modules
12 | integration/dist
13 |
14 | # dependencies
15 | /node_modules
16 |
17 | # IDEs and editors
18 | /.idea
19 | .project
20 | .classpath
21 | .c9/
22 | *.launch
23 | .settings/
24 | *.sublime-workspace
25 |
26 | # IDE - VSCode
27 | .vscode/*
28 | !.vscode/settings.json
29 | !.vscode/tasks.json
30 | !.vscode/launch.json
31 | !.vscode/extensions.json
32 |
33 | # misc
34 | /.sass-cache
35 | /connect.lock
36 | /coverage
37 | /libpeerconnection.log
38 | npm-debug.log
39 | yarn-error.log
40 | testem.log
41 | /typings
42 |
43 | # e2e
44 | /e2e/*.js
45 | /e2e/*.map
46 |
47 | # System Files
48 | .DS_Store
49 | Thumbs.db
50 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Angular gtag.js
2 |
3 | A simple Google Analytics [gtag.js](https://developers.google.com/analytics/devguides/collection/gtagjs/) package for Angular.
4 |
5 | ## Install
6 |
7 | ```
8 | npm install angular-gtag --save
9 | ```
10 |
11 | Add the the tracking code from GA admin dashboard to `index.html` and set _send_page_view_ to false.
12 |
13 | ```html
14 |
15 |
16 |
22 |
23 |
24 | ```
25 |
26 | Add the package to to your `app.module.ts`.
27 |
28 | ```ts
29 | import { GtagModule } from 'angular-gtag';
30 |
31 | @NgModule({
32 | imports: [
33 | GtagModule.forRoot({ trackingId: 'UA-YOUR_TRACKING_ID', trackPageviews: true })
34 | ]
35 | })
36 | ```
37 |
38 | **Options**
39 |
40 | - `trackingId: string (required)` Google Analytics UA tracking ID.
41 | - `trackPageviews: boolean` Default true.
42 | - `debug: boolean` Default false, console logs every gtag event/pageview.
43 |
44 | ## Pageviews
45 |
46 | The package will listen to route changes by default, you just need to instantiate service in the root of the project.
47 |
48 | ```ts
49 | export class AppComponent {
50 | constructor(gtag: Gtag) {}
51 | }
52 | ```
53 |
54 | Gtag is a serivce that also allows you to track pageviews manually.
55 |
56 | ```ts
57 | gtag.pageview();
58 |
59 | // or with custom params
60 |
61 | gtag.pageview({
62 | page_title: 'Lesson Feed',
63 | page_path: '/lessons',
64 | page_location: 'https://angularfirebase.com/lessons'
65 | });
66 | ```
67 |
68 | ## Events
69 |
70 | [Events](https://developers.google.com/analytics/devguides/collection/gtagjs/events) expect an action.
71 |
72 | ```ts
73 | gtag.event('view_promotion');
74 | ```
75 |
76 | You can optionally pass in addtional params.
77 |
78 | ```ts
79 | gtag.event('login', {
80 | method: 'Instagram',
81 | event_category: 'engagemnt',
82 | event_label: 'New user logged in via OAuth'
83 | });
84 | ```
85 |
86 | ## Event Directive
87 |
88 | Many analytics events are tracked based on user interaction, such as button clicks. Just tell it which DOM event to track.
89 |
90 | ```html
91 |
92 | ```
93 |
94 | This will register a general event in GA based on the event name.
95 |
96 | 
97 |
98 | You can pass optional params to the directive like so:
99 |
100 | ```html
101 |
106 |
107 | Some Product...
108 |
109 |
110 | ```
111 |
112 | The directive will produce the following event on dragstart.
113 | 
114 |
--------------------------------------------------------------------------------
/integration/app/app-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Routes, RouterModule } from '@angular/router';
3 | import { PageComponent } from './page/page.component';
4 |
5 | const routes: Routes = [
6 | { path: 'test', component: PageComponent },
7 | { path: 'deeply/nested/path/test', component: PageComponent }
8 | ];
9 |
10 | @NgModule({
11 | imports: [RouterModule.forRoot(routes)],
12 | exports: [RouterModule]
13 | })
14 | export class AppRoutingModule { }
15 |
--------------------------------------------------------------------------------
/integration/app/app.component.css:
--------------------------------------------------------------------------------
1 | .box {
2 | height: 300px;
3 | width: 300px;
4 | border: 1px solid grey;
5 | position: absolute;
6 | cursor: move;
7 | }
--------------------------------------------------------------------------------
/integration/app/app.component.html:
--------------------------------------------------------------------------------
1 |
2 | Route 1
3 | Route 2
4 |
5 |
6 |
7 | Some Product
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/integration/app/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed, async } from '@angular/core/testing';
2 | import { RouterTestingModule } from '@angular/router/testing';
3 | import { AppComponent } from './app.component';
4 | describe('AppComponent', () => {
5 | beforeEach(async(() => {
6 | TestBed.configureTestingModule({
7 | imports: [
8 | RouterTestingModule
9 | ],
10 | declarations: [
11 | AppComponent
12 | ],
13 | }).compileComponents();
14 | }));
15 | it('should create the app', async(() => {
16 | const fixture = TestBed.createComponent(AppComponent);
17 | const app = fixture.debugElement.componentInstance;
18 | expect(app).toBeTruthy();
19 | }));
20 | it(`should have as title 'app'`, async(() => {
21 | const fixture = TestBed.createComponent(AppComponent);
22 | const app = fixture.debugElement.componentInstance;
23 | expect(app.title).toEqual('app');
24 | }));
25 | it('should render title in a h1 tag', async(() => {
26 | const fixture = TestBed.createComponent(AppComponent);
27 | fixture.detectChanges();
28 | const compiled = fixture.debugElement.nativeElement;
29 | expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!');
30 | }));
31 | });
32 |
--------------------------------------------------------------------------------
/integration/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { Gtag } from 'angular-gtag';
3 |
4 | @Component({
5 | selector: 'app-root',
6 | templateUrl: './app.component.html',
7 | styleUrls: ['./app.component.css']
8 | })
9 | export class AppComponent {
10 | title = 'app';
11 |
12 | constructor(private gtag: Gtag) {
13 | gtag.event('init', { event_label: 'App Init'});
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/integration/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { BrowserModule } from '@angular/platform-browser';
2 | import { NgModule } from '@angular/core';
3 |
4 | import { AppRoutingModule } from './app-routing.module';
5 |
6 | import { AppComponent } from './app.component';
7 |
8 | import { GtagModule } from 'angular-gtag';
9 | import { PageComponent } from './page/page.component';
10 |
11 | import { environment } from '../environments/environment';
12 |
13 | @NgModule({
14 | declarations: [AppComponent, PageComponent],
15 | imports: [
16 | BrowserModule,
17 | AppRoutingModule,
18 | GtagModule.forRoot(environment.gaConfig)
19 | ],
20 | providers: [],
21 | bootstrap: [AppComponent]
22 | })
23 | export class AppModule {}
24 |
--------------------------------------------------------------------------------
/integration/app/page/page.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codediodeio/angular-gtag/874c1325a6d585b7436ab59aea3901b24f173a15/integration/app/page/page.component.css
--------------------------------------------------------------------------------
/integration/app/page/page.component.html:
--------------------------------------------------------------------------------
1 |
2 | page works!
3 |
4 |
--------------------------------------------------------------------------------
/integration/app/page/page.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-page',
5 | templateUrl: './page.component.html',
6 | styleUrls: ['./page.component.css']
7 | })
8 | export class PageComponent implements OnInit {
9 |
10 | constructor() { }
11 |
12 | ngOnInit() {
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/integration/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codediodeio/angular-gtag/874c1325a6d585b7436ab59aea3901b24f173a15/integration/assets/.gitkeep
--------------------------------------------------------------------------------
/integration/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true,
3 | gaConfig: {
4 | trackingId: 'UA-59099331-15',
5 | debug: true
6 | }
7 | };
8 |
--------------------------------------------------------------------------------
/integration/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // The file contents for the current environment will overwrite these during build.
2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do
3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead.
4 | // The list of which env maps to which file can be found in `.angular-cli.json`.
5 |
6 | export const environment = {
7 | production: false,
8 | gaConfig: {
9 | trackingId: 'UA-59099331-15',
10 | debug: true
11 | }
12 | };
13 |
--------------------------------------------------------------------------------
/integration/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codediodeio/angular-gtag/874c1325a6d585b7436ab59aea3901b24f173a15/integration/favicon.ico
--------------------------------------------------------------------------------
/integration/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
13 |
14 | Gtag
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/integration/main.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core';
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
3 |
4 | import { AppModule } from './app/app.module';
5 | import { environment } from './environments/environment';
6 |
7 | if (environment.production) {
8 | enableProdMode();
9 | }
10 |
11 | platformBrowserDynamic().bootstrapModule(AppModule)
12 | .catch(err => console.log(err));
13 |
--------------------------------------------------------------------------------
/integration/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file includes polyfills needed by Angular and is loaded before the app.
3 | * You can add your own extra polyfills to this file.
4 | *
5 | * This file is divided into 2 sections:
6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
8 | * file.
9 | *
10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
13 | *
14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
15 | */
16 |
17 | /***************************************************************************************************
18 | * BROWSER POLYFILLS
19 | */
20 |
21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/
22 | // import 'core-js/es6/symbol';
23 | // import 'core-js/es6/object';
24 | // import 'core-js/es6/function';
25 | // import 'core-js/es6/parse-int';
26 | // import 'core-js/es6/parse-float';
27 | // import 'core-js/es6/number';
28 | // import 'core-js/es6/math';
29 | // import 'core-js/es6/string';
30 | // import 'core-js/es6/date';
31 | // import 'core-js/es6/array';
32 | // import 'core-js/es6/regexp';
33 | // import 'core-js/es6/map';
34 | // import 'core-js/es6/weak-map';
35 | // import 'core-js/es6/set';
36 |
37 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */
38 | // import 'classlist.js'; // Run `npm install --save classlist.js`.
39 |
40 | /** IE10 and IE11 requires the following for the Reflect API. */
41 | // import 'core-js/es6/reflect';
42 |
43 |
44 | /** Evergreen browsers require these. **/
45 | // Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
46 | import 'core-js/es7/reflect';
47 |
48 |
49 | /**
50 | * Required to support Web Animations `@angular/platform-browser/animations`.
51 | * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
52 | **/
53 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
54 |
55 | /**
56 | * By default, zone.js will patch all possible macroTask and DomEvents
57 | * user can disable parts of macroTask/DomEvents patch by setting following flags
58 | */
59 |
60 | // (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
61 | // (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
62 | // (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
63 |
64 | /*
65 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
66 | * with the following flag, it will bypass `zone.js` patch for IE/Edge
67 | */
68 | // (window as any).__Zone_enable_cross_context_check = true;
69 |
70 | /***************************************************************************************************
71 | * Zone JS is required by default for Angular itself.
72 | */
73 | import 'zone.js/dist/zone'; // Included with Angular CLI.
74 |
75 |
76 |
77 | /***************************************************************************************************
78 | * APPLICATION IMPORTS
79 | */
80 |
--------------------------------------------------------------------------------
/integration/styles.css:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 |
--------------------------------------------------------------------------------
/integration/test.ts:
--------------------------------------------------------------------------------
1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files
2 |
3 | import 'zone.js/dist/zone-testing';
4 | import { getTestBed } from '@angular/core/testing';
5 | import {
6 | BrowserDynamicTestingModule,
7 | platformBrowserDynamicTesting
8 | } from '@angular/platform-browser-dynamic/testing';
9 |
10 | declare const require: any;
11 |
12 | // First, initialize the Angular testing environment.
13 | getTestBed().initTestEnvironment(
14 | BrowserDynamicTestingModule,
15 | platformBrowserDynamicTesting()
16 | );
17 | // Then we find all the tests.
18 | const context = require.context('./', true, /\.spec\.ts$/);
19 | // And load the modules.
20 | context.keys().map(context);
21 |
--------------------------------------------------------------------------------
/integration/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/app",
5 | "baseUrl": "./",
6 | "module": "es2015",
7 | "types": []
8 | },
9 | "exclude": [
10 | "test.ts",
11 | "**/*.spec.ts"
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/integration/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/spec",
5 | "baseUrl": "./",
6 | "module": "commonjs",
7 | "types": [
8 | "jasmine",
9 | "node"
10 | ]
11 | },
12 | "files": [
13 | "test.ts"
14 | ],
15 | "include": [
16 | "**/*.spec.ts",
17 | "**/*.d.ts"
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/integration/typings.d.ts:
--------------------------------------------------------------------------------
1 | /* SystemJS module definition */
2 | declare var module: NodeModule;
3 | interface NodeModule {
4 | id: string;
5 | }
6 |
--------------------------------------------------------------------------------
/lib/README.md:
--------------------------------------------------------------------------------
1 | # Angular gtag.js
2 |
3 | A simple Google Analytics [gtag.js](https://developers.google.com/analytics/devguides/collection/gtagjs/) package for Angular.
4 |
5 | ## Install
6 |
7 | ```
8 | npm install angular-gtag --save
9 | ```
10 |
11 | Add the the tracking code from GA admin dashboard to `index.html` and set *send_page_view* to false.
12 |
13 | ```html
14 |
15 |
21 |
22 |
23 | ```
24 |
25 | Add the package to to your `app.module.ts`.
26 |
27 | ```ts
28 | import { GtagModule } from 'angular-gtag';
29 |
30 | @NgModule({
31 | imports: [
32 | GtagModule.forRoot({ trackingId: 'UA-YOUR_TRACKING_ID', trackPageviews: true })
33 | ]
34 | })
35 | ```
36 |
37 | ## Pageviews
38 |
39 | The package will listen to route changes by default, you just need to instantiate service in the root of the project.
40 |
41 | ```ts
42 | export class AppComponent {
43 | constructor(gtag: Gtag) { }
44 | }
45 | ```
46 |
47 | Gtag is a serivce that also allows you to track pageviews manually.
48 |
49 | ```ts
50 | gtag.pageview();
51 |
52 | // or with custom params
53 |
54 | gtag.pageview({
55 | page_title: 'Lesson Feed',
56 | page_path: '/lessons',
57 | page_location: 'https://angularfirebase.com/lessons'
58 | });
59 | ```
60 |
61 | ## Events
62 |
63 | [Events](https://developers.google.com/analytics/devguides/collection/gtagjs/events) expect an action.
64 |
65 | ```ts
66 | gtag.event('view_promotion')
67 | ```
68 |
69 | You can optionally pass in addtional params.
70 |
71 |
72 | ```ts
73 | gtag.event('login', {
74 | method: 'Instagram',
75 | event_category: 'engagemnt',
76 | event_label: 'New user logged in via OAuth'
77 | });
78 | ```
79 |
80 |
81 | ## Event Directive
82 |
83 | Many analytics events are tracked based on user interaction, such as button clicks. Just tell it which DOM event to track.
84 |
85 | ```html
86 |
87 | ```
88 |
89 | This will register a general event in GA based on the event name.
90 |
91 | 
92 |
93 | You can pass optional params to the directive like so:
94 |
95 | ```html
96 |
101 |
102 | Some Product...
103 |
104 |
105 | ```
106 |
107 | The directive will produce the following event on dragstart.
108 | 
--------------------------------------------------------------------------------
/lib/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-gtag",
3 | "version": "1.0.0-alpha.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "ansi-regex": {
8 | "version": "2.1.1",
9 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
10 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
11 | "dev": true
12 | },
13 | "ansi-styles": {
14 | "version": "3.2.1",
15 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
16 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
17 | "dev": true,
18 | "requires": {
19 | "color-convert": "^1.9.0"
20 | }
21 | },
22 | "arrify": {
23 | "version": "1.0.1",
24 | "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
25 | "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
26 | "dev": true
27 | },
28 | "balanced-match": {
29 | "version": "1.0.0",
30 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
31 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
32 | "dev": true
33 | },
34 | "brace-expansion": {
35 | "version": "1.1.11",
36 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
37 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
38 | "dev": true,
39 | "requires": {
40 | "balanced-match": "^1.0.0",
41 | "concat-map": "0.0.1"
42 | }
43 | },
44 | "builtin-modules": {
45 | "version": "1.1.1",
46 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
47 | "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
48 | "dev": true
49 | },
50 | "camelcase": {
51 | "version": "4.1.0",
52 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
53 | "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
54 | "dev": true
55 | },
56 | "chalk": {
57 | "version": "2.4.1",
58 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
59 | "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
60 | "dev": true,
61 | "requires": {
62 | "ansi-styles": "^3.2.1",
63 | "escape-string-regexp": "^1.0.5",
64 | "supports-color": "^5.3.0"
65 | }
66 | },
67 | "cliui": {
68 | "version": "3.2.0",
69 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
70 | "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
71 | "dev": true,
72 | "requires": {
73 | "string-width": "^1.0.1",
74 | "strip-ansi": "^3.0.1",
75 | "wrap-ansi": "^2.0.0"
76 | },
77 | "dependencies": {
78 | "string-width": {
79 | "version": "1.0.2",
80 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
81 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
82 | "dev": true,
83 | "requires": {
84 | "code-point-at": "^1.0.0",
85 | "is-fullwidth-code-point": "^1.0.0",
86 | "strip-ansi": "^3.0.0"
87 | }
88 | }
89 | }
90 | },
91 | "code-point-at": {
92 | "version": "1.1.0",
93 | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
94 | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
95 | "dev": true
96 | },
97 | "color-convert": {
98 | "version": "1.9.1",
99 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
100 | "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
101 | "dev": true,
102 | "requires": {
103 | "color-name": "^1.1.1"
104 | }
105 | },
106 | "color-name": {
107 | "version": "1.1.3",
108 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
109 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
110 | "dev": true
111 | },
112 | "concat-map": {
113 | "version": "0.0.1",
114 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
115 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
116 | "dev": true
117 | },
118 | "cross-spawn": {
119 | "version": "5.1.0",
120 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
121 | "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
122 | "dev": true,
123 | "requires": {
124 | "lru-cache": "^4.0.1",
125 | "shebang-command": "^1.2.0",
126 | "which": "^1.2.9"
127 | }
128 | },
129 | "decamelize": {
130 | "version": "1.2.0",
131 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
132 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
133 | "dev": true
134 | },
135 | "diff": {
136 | "version": "3.5.0",
137 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
138 | "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
139 | "dev": true
140 | },
141 | "error-ex": {
142 | "version": "1.3.1",
143 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
144 | "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
145 | "dev": true,
146 | "requires": {
147 | "is-arrayish": "^0.2.1"
148 | }
149 | },
150 | "escape-string-regexp": {
151 | "version": "1.0.5",
152 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
153 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
154 | "dev": true
155 | },
156 | "execa": {
157 | "version": "0.7.0",
158 | "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
159 | "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
160 | "dev": true,
161 | "requires": {
162 | "cross-spawn": "^5.0.1",
163 | "get-stream": "^3.0.0",
164 | "is-stream": "^1.1.0",
165 | "npm-run-path": "^2.0.0",
166 | "p-finally": "^1.0.0",
167 | "signal-exit": "^3.0.0",
168 | "strip-eof": "^1.0.0"
169 | }
170 | },
171 | "exit": {
172 | "version": "0.1.2",
173 | "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
174 | "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
175 | "dev": true
176 | },
177 | "find-up": {
178 | "version": "2.1.0",
179 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
180 | "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
181 | "dev": true,
182 | "requires": {
183 | "locate-path": "^2.0.0"
184 | }
185 | },
186 | "fs.realpath": {
187 | "version": "1.0.0",
188 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
189 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
190 | "dev": true
191 | },
192 | "get-caller-file": {
193 | "version": "1.0.2",
194 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz",
195 | "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=",
196 | "dev": true
197 | },
198 | "get-stream": {
199 | "version": "3.0.0",
200 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
201 | "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
202 | "dev": true
203 | },
204 | "glob": {
205 | "version": "7.1.2",
206 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
207 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
208 | "dev": true,
209 | "requires": {
210 | "fs.realpath": "^1.0.0",
211 | "inflight": "^1.0.4",
212 | "inherits": "2",
213 | "minimatch": "^3.0.4",
214 | "once": "^1.3.0",
215 | "path-is-absolute": "^1.0.0"
216 | }
217 | },
218 | "graceful-fs": {
219 | "version": "4.1.11",
220 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
221 | "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
222 | "dev": true
223 | },
224 | "has-flag": {
225 | "version": "3.0.0",
226 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
227 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
228 | "dev": true
229 | },
230 | "homedir-polyfill": {
231 | "version": "1.0.1",
232 | "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz",
233 | "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=",
234 | "dev": true,
235 | "requires": {
236 | "parse-passwd": "^1.0.0"
237 | }
238 | },
239 | "hosted-git-info": {
240 | "version": "2.6.0",
241 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz",
242 | "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==",
243 | "dev": true
244 | },
245 | "inflight": {
246 | "version": "1.0.6",
247 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
248 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
249 | "dev": true,
250 | "requires": {
251 | "once": "^1.3.0",
252 | "wrappy": "1"
253 | }
254 | },
255 | "inherits": {
256 | "version": "2.0.3",
257 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
258 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
259 | "dev": true
260 | },
261 | "invert-kv": {
262 | "version": "1.0.0",
263 | "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
264 | "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
265 | "dev": true
266 | },
267 | "is-arrayish": {
268 | "version": "0.2.1",
269 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
270 | "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
271 | "dev": true
272 | },
273 | "is-builtin-module": {
274 | "version": "1.0.0",
275 | "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
276 | "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
277 | "dev": true,
278 | "requires": {
279 | "builtin-modules": "^1.0.0"
280 | }
281 | },
282 | "is-fullwidth-code-point": {
283 | "version": "1.0.0",
284 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
285 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
286 | "dev": true,
287 | "requires": {
288 | "number-is-nan": "^1.0.0"
289 | }
290 | },
291 | "is-stream": {
292 | "version": "1.1.0",
293 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
294 | "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
295 | "dev": true
296 | },
297 | "isexe": {
298 | "version": "2.0.0",
299 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
300 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
301 | "dev": true
302 | },
303 | "jasmine": {
304 | "version": "3.1.0",
305 | "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.1.0.tgz",
306 | "integrity": "sha1-K9Wf1+xuwOistk4J9Fpo7SrRlSo=",
307 | "dev": true,
308 | "requires": {
309 | "glob": "^7.0.6",
310 | "jasmine-core": "~3.1.0"
311 | }
312 | },
313 | "jasmine-core": {
314 | "version": "3.1.0",
315 | "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.1.0.tgz",
316 | "integrity": "sha1-pHheE11d9lAk38kiSVPfWFvSdmw=",
317 | "dev": true
318 | },
319 | "jasmine-ts": {
320 | "version": "0.2.1",
321 | "resolved": "https://registry.npmjs.org/jasmine-ts/-/jasmine-ts-0.2.1.tgz",
322 | "integrity": "sha512-Ljieg2aAfd8JHSmSQgQpGNTCWzD05LdbX21dkmRKuk9xqEz9ip17+033UiWKOUeIy2t+adiOfo0vZzEV61z96A==",
323 | "dev": true,
324 | "requires": {
325 | "jasmine": "^2.6.0",
326 | "ts-node": "^3.2.0",
327 | "typescript": "^2.4.1",
328 | "yargs": "^8.0.2"
329 | },
330 | "dependencies": {
331 | "jasmine": {
332 | "version": "2.99.0",
333 | "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.99.0.tgz",
334 | "integrity": "sha1-jKctEC5jm4Z8ZImFbg4YqceqQrc=",
335 | "dev": true,
336 | "requires": {
337 | "exit": "^0.1.2",
338 | "glob": "^7.0.6",
339 | "jasmine-core": "~2.99.0"
340 | }
341 | },
342 | "jasmine-core": {
343 | "version": "2.99.1",
344 | "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.99.1.tgz",
345 | "integrity": "sha1-5kAN8ea1bhMLYcS80JPap/boyhU=",
346 | "dev": true
347 | }
348 | }
349 | },
350 | "lcid": {
351 | "version": "1.0.0",
352 | "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
353 | "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
354 | "dev": true,
355 | "requires": {
356 | "invert-kv": "^1.0.0"
357 | }
358 | },
359 | "load-json-file": {
360 | "version": "2.0.0",
361 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
362 | "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
363 | "dev": true,
364 | "requires": {
365 | "graceful-fs": "^4.1.2",
366 | "parse-json": "^2.2.0",
367 | "pify": "^2.0.0",
368 | "strip-bom": "^3.0.0"
369 | }
370 | },
371 | "locate-path": {
372 | "version": "2.0.0",
373 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
374 | "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
375 | "dev": true,
376 | "requires": {
377 | "p-locate": "^2.0.0",
378 | "path-exists": "^3.0.0"
379 | }
380 | },
381 | "lru-cache": {
382 | "version": "4.1.2",
383 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.2.tgz",
384 | "integrity": "sha512-wgeVXhrDwAWnIF/yZARsFnMBtdFXOg1b8RIrhilp+0iDYN4mdQcNZElDZ0e4B64BhaxeQ5zN7PMyvu7we1kPeQ==",
385 | "dev": true,
386 | "requires": {
387 | "pseudomap": "^1.0.2",
388 | "yallist": "^2.1.2"
389 | }
390 | },
391 | "make-error": {
392 | "version": "1.3.4",
393 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz",
394 | "integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==",
395 | "dev": true
396 | },
397 | "mem": {
398 | "version": "1.1.0",
399 | "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz",
400 | "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=",
401 | "dev": true,
402 | "requires": {
403 | "mimic-fn": "^1.0.0"
404 | }
405 | },
406 | "mimic-fn": {
407 | "version": "1.2.0",
408 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
409 | "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
410 | "dev": true
411 | },
412 | "minimatch": {
413 | "version": "3.0.4",
414 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
415 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
416 | "dev": true,
417 | "requires": {
418 | "brace-expansion": "^1.1.7"
419 | }
420 | },
421 | "minimist": {
422 | "version": "1.2.0",
423 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
424 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
425 | "dev": true
426 | },
427 | "mkdirp": {
428 | "version": "0.5.1",
429 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
430 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
431 | "dev": true,
432 | "requires": {
433 | "minimist": "0.0.8"
434 | },
435 | "dependencies": {
436 | "minimist": {
437 | "version": "0.0.8",
438 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
439 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
440 | "dev": true
441 | }
442 | }
443 | },
444 | "normalize-package-data": {
445 | "version": "2.4.0",
446 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
447 | "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
448 | "dev": true,
449 | "requires": {
450 | "hosted-git-info": "^2.1.4",
451 | "is-builtin-module": "^1.0.0",
452 | "semver": "2 || 3 || 4 || 5",
453 | "validate-npm-package-license": "^3.0.1"
454 | }
455 | },
456 | "npm-run-path": {
457 | "version": "2.0.2",
458 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
459 | "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
460 | "dev": true,
461 | "requires": {
462 | "path-key": "^2.0.0"
463 | }
464 | },
465 | "number-is-nan": {
466 | "version": "1.0.1",
467 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
468 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
469 | "dev": true
470 | },
471 | "once": {
472 | "version": "1.4.0",
473 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
474 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
475 | "dev": true,
476 | "requires": {
477 | "wrappy": "1"
478 | }
479 | },
480 | "os-locale": {
481 | "version": "2.1.0",
482 | "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",
483 | "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==",
484 | "dev": true,
485 | "requires": {
486 | "execa": "^0.7.0",
487 | "lcid": "^1.0.0",
488 | "mem": "^1.1.0"
489 | }
490 | },
491 | "p-finally": {
492 | "version": "1.0.0",
493 | "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
494 | "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
495 | "dev": true
496 | },
497 | "p-limit": {
498 | "version": "1.2.0",
499 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz",
500 | "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==",
501 | "dev": true,
502 | "requires": {
503 | "p-try": "^1.0.0"
504 | }
505 | },
506 | "p-locate": {
507 | "version": "2.0.0",
508 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
509 | "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
510 | "dev": true,
511 | "requires": {
512 | "p-limit": "^1.1.0"
513 | }
514 | },
515 | "p-try": {
516 | "version": "1.0.0",
517 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
518 | "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
519 | "dev": true
520 | },
521 | "parse-json": {
522 | "version": "2.2.0",
523 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
524 | "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
525 | "dev": true,
526 | "requires": {
527 | "error-ex": "^1.2.0"
528 | }
529 | },
530 | "parse-passwd": {
531 | "version": "1.0.0",
532 | "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
533 | "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
534 | "dev": true
535 | },
536 | "path-exists": {
537 | "version": "3.0.0",
538 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
539 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
540 | "dev": true
541 | },
542 | "path-is-absolute": {
543 | "version": "1.0.1",
544 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
545 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
546 | "dev": true
547 | },
548 | "path-key": {
549 | "version": "2.0.1",
550 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
551 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
552 | "dev": true
553 | },
554 | "path-type": {
555 | "version": "2.0.0",
556 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
557 | "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
558 | "dev": true,
559 | "requires": {
560 | "pify": "^2.0.0"
561 | }
562 | },
563 | "pify": {
564 | "version": "2.3.0",
565 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
566 | "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
567 | "dev": true
568 | },
569 | "pseudomap": {
570 | "version": "1.0.2",
571 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
572 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
573 | "dev": true
574 | },
575 | "read-pkg": {
576 | "version": "2.0.0",
577 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
578 | "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
579 | "dev": true,
580 | "requires": {
581 | "load-json-file": "^2.0.0",
582 | "normalize-package-data": "^2.3.2",
583 | "path-type": "^2.0.0"
584 | }
585 | },
586 | "read-pkg-up": {
587 | "version": "2.0.0",
588 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
589 | "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
590 | "dev": true,
591 | "requires": {
592 | "find-up": "^2.0.0",
593 | "read-pkg": "^2.0.0"
594 | }
595 | },
596 | "require-directory": {
597 | "version": "2.1.1",
598 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
599 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
600 | "dev": true
601 | },
602 | "require-main-filename": {
603 | "version": "1.0.1",
604 | "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
605 | "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
606 | "dev": true
607 | },
608 | "semver": {
609 | "version": "5.5.0",
610 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
611 | "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
612 | "dev": true
613 | },
614 | "set-blocking": {
615 | "version": "2.0.0",
616 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
617 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
618 | "dev": true
619 | },
620 | "shebang-command": {
621 | "version": "1.2.0",
622 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
623 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
624 | "dev": true,
625 | "requires": {
626 | "shebang-regex": "^1.0.0"
627 | }
628 | },
629 | "shebang-regex": {
630 | "version": "1.0.0",
631 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
632 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
633 | "dev": true
634 | },
635 | "signal-exit": {
636 | "version": "3.0.2",
637 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
638 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
639 | "dev": true
640 | },
641 | "source-map": {
642 | "version": "0.5.7",
643 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
644 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
645 | "dev": true
646 | },
647 | "source-map-support": {
648 | "version": "0.4.18",
649 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
650 | "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
651 | "dev": true,
652 | "requires": {
653 | "source-map": "^0.5.6"
654 | }
655 | },
656 | "spdx-correct": {
657 | "version": "3.0.0",
658 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz",
659 | "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==",
660 | "dev": true,
661 | "requires": {
662 | "spdx-expression-parse": "^3.0.0",
663 | "spdx-license-ids": "^3.0.0"
664 | }
665 | },
666 | "spdx-exceptions": {
667 | "version": "2.1.0",
668 | "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz",
669 | "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==",
670 | "dev": true
671 | },
672 | "spdx-expression-parse": {
673 | "version": "3.0.0",
674 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
675 | "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
676 | "dev": true,
677 | "requires": {
678 | "spdx-exceptions": "^2.1.0",
679 | "spdx-license-ids": "^3.0.0"
680 | }
681 | },
682 | "spdx-license-ids": {
683 | "version": "3.0.0",
684 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz",
685 | "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==",
686 | "dev": true
687 | },
688 | "string-width": {
689 | "version": "2.1.1",
690 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
691 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
692 | "dev": true,
693 | "requires": {
694 | "is-fullwidth-code-point": "^2.0.0",
695 | "strip-ansi": "^4.0.0"
696 | },
697 | "dependencies": {
698 | "ansi-regex": {
699 | "version": "3.0.0",
700 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
701 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
702 | "dev": true
703 | },
704 | "is-fullwidth-code-point": {
705 | "version": "2.0.0",
706 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
707 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
708 | "dev": true
709 | },
710 | "strip-ansi": {
711 | "version": "4.0.0",
712 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
713 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
714 | "dev": true,
715 | "requires": {
716 | "ansi-regex": "^3.0.0"
717 | }
718 | }
719 | }
720 | },
721 | "strip-ansi": {
722 | "version": "3.0.1",
723 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
724 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
725 | "dev": true,
726 | "requires": {
727 | "ansi-regex": "^2.0.0"
728 | }
729 | },
730 | "strip-bom": {
731 | "version": "3.0.0",
732 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
733 | "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
734 | "dev": true
735 | },
736 | "strip-eof": {
737 | "version": "1.0.0",
738 | "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
739 | "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
740 | "dev": true
741 | },
742 | "strip-json-comments": {
743 | "version": "2.0.1",
744 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
745 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
746 | "dev": true
747 | },
748 | "supports-color": {
749 | "version": "5.4.0",
750 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
751 | "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
752 | "dev": true,
753 | "requires": {
754 | "has-flag": "^3.0.0"
755 | }
756 | },
757 | "ts-node": {
758 | "version": "3.3.0",
759 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-3.3.0.tgz",
760 | "integrity": "sha1-wTxqMCTjC+EYDdUwOPwgkonUv2k=",
761 | "dev": true,
762 | "requires": {
763 | "arrify": "^1.0.0",
764 | "chalk": "^2.0.0",
765 | "diff": "^3.1.0",
766 | "make-error": "^1.1.1",
767 | "minimist": "^1.2.0",
768 | "mkdirp": "^0.5.1",
769 | "source-map-support": "^0.4.0",
770 | "tsconfig": "^6.0.0",
771 | "v8flags": "^3.0.0",
772 | "yn": "^2.0.0"
773 | }
774 | },
775 | "tsconfig": {
776 | "version": "6.0.0",
777 | "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-6.0.0.tgz",
778 | "integrity": "sha1-aw6DdgA9evGGT434+J3QBZ/80DI=",
779 | "dev": true,
780 | "requires": {
781 | "strip-bom": "^3.0.0",
782 | "strip-json-comments": "^2.0.0"
783 | }
784 | },
785 | "typescript": {
786 | "version": "2.8.3",
787 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.8.3.tgz",
788 | "integrity": "sha512-K7g15Bb6Ra4lKf7Iq2l/I5/En+hLIHmxWZGq3D4DIRNFxMNV6j2SHSvDOqs2tGd4UvD/fJvrwopzQXjLrT7Itw==",
789 | "dev": true
790 | },
791 | "v8flags": {
792 | "version": "3.0.2",
793 | "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.0.2.tgz",
794 | "integrity": "sha512-6sgSKoFw1UpUPd3cFdF7QGnrH6tDeBgW1F3v9gy8gLY0mlbiBXq8soy8aQpY6xeeCjH5K+JvC62Acp7gtl7wWA==",
795 | "dev": true,
796 | "requires": {
797 | "homedir-polyfill": "^1.0.1"
798 | }
799 | },
800 | "validate-npm-package-license": {
801 | "version": "3.0.3",
802 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz",
803 | "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==",
804 | "dev": true,
805 | "requires": {
806 | "spdx-correct": "^3.0.0",
807 | "spdx-expression-parse": "^3.0.0"
808 | }
809 | },
810 | "which": {
811 | "version": "1.3.0",
812 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
813 | "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
814 | "dev": true,
815 | "requires": {
816 | "isexe": "^2.0.0"
817 | }
818 | },
819 | "which-module": {
820 | "version": "2.0.0",
821 | "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
822 | "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
823 | "dev": true
824 | },
825 | "wrap-ansi": {
826 | "version": "2.1.0",
827 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
828 | "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
829 | "dev": true,
830 | "requires": {
831 | "string-width": "^1.0.1",
832 | "strip-ansi": "^3.0.1"
833 | },
834 | "dependencies": {
835 | "string-width": {
836 | "version": "1.0.2",
837 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
838 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
839 | "dev": true,
840 | "requires": {
841 | "code-point-at": "^1.0.0",
842 | "is-fullwidth-code-point": "^1.0.0",
843 | "strip-ansi": "^3.0.0"
844 | }
845 | }
846 | }
847 | },
848 | "wrappy": {
849 | "version": "1.0.2",
850 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
851 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
852 | "dev": true
853 | },
854 | "y18n": {
855 | "version": "3.2.1",
856 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
857 | "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
858 | "dev": true
859 | },
860 | "yallist": {
861 | "version": "2.1.2",
862 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
863 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
864 | "dev": true
865 | },
866 | "yargs": {
867 | "version": "8.0.2",
868 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz",
869 | "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=",
870 | "dev": true,
871 | "requires": {
872 | "camelcase": "^4.1.0",
873 | "cliui": "^3.2.0",
874 | "decamelize": "^1.1.1",
875 | "get-caller-file": "^1.0.1",
876 | "os-locale": "^2.0.0",
877 | "read-pkg-up": "^2.0.0",
878 | "require-directory": "^2.1.1",
879 | "require-main-filename": "^1.0.1",
880 | "set-blocking": "^2.0.0",
881 | "string-width": "^2.0.0",
882 | "which-module": "^2.0.0",
883 | "y18n": "^3.2.1",
884 | "yargs-parser": "^7.0.0"
885 | }
886 | },
887 | "yargs-parser": {
888 | "version": "7.0.0",
889 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz",
890 | "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=",
891 | "dev": true,
892 | "requires": {
893 | "camelcase": "^4.1.0"
894 | }
895 | },
896 | "yn": {
897 | "version": "2.0.0",
898 | "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz",
899 | "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=",
900 | "dev": true
901 | }
902 | }
903 | }
904 |
--------------------------------------------------------------------------------
/lib/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-gtag",
3 | "version": "1.0.3",
4 | "author": "Jeff Delaney ",
5 | "repository": "https://github.com/codediodeio/angular-gtag",
6 | "license": "MIT",
7 | "private": false,
8 | "peerDependencies": {
9 | "@angular/core": ">=5.0.0",
10 | "@angular/common": ">=5.0.0",
11 | "@angular/router": ">=5.0.0"
12 | },
13 | "keywords": [
14 | "angular",
15 | "google analytics",
16 | "gtag.js"
17 | ],
18 | "ngPackage": {
19 | "$schema": "./node_modules/ng-packagr/ng-package.schema.json",
20 | "lib": {
21 | "entryFile": "public_api.ts"
22 | },
23 | "dest": "dist"
24 | }
25 | }
--------------------------------------------------------------------------------
/lib/public_api.ts:
--------------------------------------------------------------------------------
1 | export * from './src/gtag.service';
2 | export * from './src/gtag-event.directive';
3 | export * from './src/gtag.module';
4 | export * from './src/interfaces';
5 |
--------------------------------------------------------------------------------
/lib/spec/main.spec.ts:
--------------------------------------------------------------------------------
1 | import { Gtag } from '../src/gtag.service';
2 | import { Router } from '@angular/router';
3 |
4 | describe('Gtag', () => {
5 | let gtag;
6 |
7 | beforeEach(() => {
8 | gtag = new Gtag({ trackingId: 'testId' }, {} as Router);
9 | });
10 |
11 | it('should be defined', () => {
12 | expect(gtag).toBeDefined();
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/lib/src/gtag-event.directive.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Directive,
3 | HostListener,
4 | Renderer2,
5 | Input,
6 | AfterViewInit,
7 | ElementRef
8 | } from '@angular/core';
9 | import { Gtag } from './gtag.service';
10 |
11 | @Directive({
12 | selector: '[gtagEvent]'
13 | })
14 | export class GtagEventDirective implements AfterViewInit {
15 | @Input() trackOn: string;
16 | @Input() action: string;
17 | @Input() category: string;
18 | @Input() params: any;
19 |
20 | constructor(
21 | private gtag: Gtag,
22 | private renderer: Renderer2,
23 | private el: ElementRef
24 | ) {}
25 |
26 | ngAfterViewInit() {
27 | try {
28 | this.renderer.listen(this.el.nativeElement, this.trackOn, () => {
29 | this.gtag.event(this.action || this.trackOn, {
30 | event_category: this.category,
31 | ...this.params
32 | });
33 | });
34 | } catch (err) {
35 | console.error(err);
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/lib/src/gtag.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule, ModuleWithProviders } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { Gtag } from './gtag.service';
4 | import { GtagEventDirective } from './gtag-event.directive';
5 |
6 | import { RouterModule } from '@angular/router';
7 | import { GtagConfig } from './interfaces';
8 |
9 | @NgModule({
10 | declarations: [GtagEventDirective],
11 | exports: [GtagEventDirective]
12 | })
13 | export class GtagModule {
14 | public static forRoot(config: GtagConfig): ModuleWithProviders {
15 | return {
16 | ngModule: GtagModule,
17 | providers: [Gtag, { provide: 'config', useValue: config }]
18 | };
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/lib/src/gtag.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable, Inject } from '@angular/core';
2 | import { GtagPageview, GtagEvent, GtagConfig } from './interfaces';
3 | import { Router, NavigationEnd } from '@angular/router';
4 | import { tap, filter } from 'rxjs/operators';
5 | declare var gtag: any;
6 |
7 | @Injectable()
8 | export class Gtag {
9 | private mergedConfig: GtagConfig;
10 | constructor(@Inject('config') gaConfig: GtagConfig, private router: Router) {
11 | this.mergedConfig = { trackPageviews: true, ...gaConfig };
12 | if (this.mergedConfig.trackPageviews) {
13 | router.events
14 | .pipe(
15 | filter(event => event instanceof NavigationEnd),
16 | tap(event => {
17 | this.pageview();
18 | })
19 | )
20 | .subscribe();
21 | }
22 | }
23 |
24 | event(action: string, params: GtagEvent = {}) {
25 | // try/catch to avoid cross-platform issues
26 | try {
27 | gtag('event', action, params);
28 | this.debug('event', this.mergedConfig.trackingId, action, params);
29 | } catch (err) {
30 | console.error('Google Analytics event error', err);
31 | }
32 | }
33 |
34 | pageview(params?: GtagPageview) {
35 | try {
36 | const defaults = {
37 | page_path: this.router.url,
38 | page_title: 'Angular App',
39 | page_location: window.location.href
40 | };
41 |
42 | params = { ...defaults, ...params };
43 | gtag('config', this.mergedConfig.trackingId, params);
44 | this.debug('pageview', this.mergedConfig.trackingId, params);
45 | } catch (err) {
46 | console.error('Google Analytics pageview error', err);
47 | }
48 | }
49 |
50 | config(params: any) {
51 | try {
52 | gtag('config', this.mergedConfig.trackingId, (params = {}));
53 | } catch (err) {
54 | console.error('Google Analytics config error', err);
55 | }
56 | }
57 |
58 | set(params: any) {
59 | try {
60 | gtag('set', (params = {}));
61 | } catch (err) {
62 | console.error('Google Analytics set error', err);
63 | }
64 | }
65 |
66 | private debug(...msg) {
67 | if (this.mergedConfig.debug) {
68 | console.log('angular-gtag:', ...msg);
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/lib/src/interfaces.ts:
--------------------------------------------------------------------------------
1 | export interface GtagEvent {
2 | event_category?: string;
3 | event_label?: string;
4 | value?: any;
5 | [key: string]: any;
6 | }
7 |
8 | export interface GtagPageview {
9 | page_title?: string;
10 | page_path?: string;
11 | page_location?: string;
12 | [key: string]: any;
13 | }
14 |
15 | export interface GtagConfig {
16 | trackingId: string;
17 | trackPageviews?: boolean;
18 | debug?: boolean;
19 | }
20 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "myapp",
3 | "version": "0.0.3",
4 | "license": "MIT",
5 | "scripts": {
6 | "ng": "ng",
7 | "start": "ng serve",
8 | "build": "ng build --prod --stats-json",
9 | "lint": "ng lint",
10 | "e2e": "ng e2e",
11 | "analyze": "webpack-bundle-analyzer dist/stats.json",
12 | "test": "jasmine-ts \"lib/spec/**/*.spec.ts\"",
13 | "build:lib": "ng-packagr -p lib/package.json",
14 | "publish": "npm publish lib/dist"
15 | },
16 | "private": true,
17 | "dependencies": {
18 | "@angular/animations": "^5.2.0",
19 | "@angular/common": "^5.2.0",
20 | "@angular/compiler": "^5.2.0",
21 | "@angular/core": "^5.2.0",
22 | "@angular/forms": "^5.2.0",
23 | "@angular/http": "^5.2.0",
24 | "@angular/platform-browser": "^5.2.0",
25 | "@angular/platform-browser-dynamic": "^5.2.0",
26 | "@angular/router": "^5.2.0",
27 | "angular-gtag": "file:lib/dist",
28 | "core-js": "^2.4.1",
29 | "rxjs": "^5.5.6",
30 | "zone.js": "^0.8.19"
31 | },
32 | "devDependencies": {
33 | "@angular/cli": "~1.7.4",
34 | "@angular/compiler-cli": "^5.2.0",
35 | "@angular/language-service": "^5.2.0",
36 | "@types/jasmine": "~2.8.3",
37 | "@types/jasminewd2": "~2.0.2",
38 | "@types/node": "~6.0.60",
39 | "codelyzer": "^4.0.1",
40 | "jasmine-core": "~2.8.0",
41 | "jasmine-spec-reporter": "~4.2.1",
42 | "jasmine-ts": "^0.2.1",
43 | "karma": "~2.0.0",
44 | "karma-chrome-launcher": "~2.2.0",
45 | "karma-coverage-istanbul-reporter": "^1.2.1",
46 | "karma-jasmine": "~1.1.0",
47 | "karma-jasmine-html-reporter": "^0.2.2",
48 | "ng-packagr": "^2.4.2",
49 | "protractor": "~5.1.2",
50 | "ts-node": "~4.1.0",
51 | "tslint": "~5.9.1",
52 | "typescript": "~2.5.3",
53 | "webpack-bundle-analyzer": "^2.11.1"
54 | }
55 | }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "outDir": "./dist/out-tsc",
5 | "sourceMap": true,
6 | "declaration": false,
7 | "moduleResolution": "node",
8 | "emitDecoratorMetadata": true,
9 | "experimentalDecorators": true,
10 | "target": "es5",
11 | "typeRoots": [
12 | "node_modules/@types"
13 | ],
14 | "lib": [
15 | "es2017",
16 | "dom"
17 | ]
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rulesDirectory": [
3 | "node_modules/codelyzer"
4 | ],
5 | "rules": {
6 | "arrow-return-shorthand": true,
7 | "callable-types": true,
8 | "class-name": true,
9 | "comment-format": [
10 | true,
11 | "check-space"
12 | ],
13 | "curly": true,
14 | "deprecation": {
15 | "severity": "warn"
16 | },
17 | "eofline": true,
18 | "forin": true,
19 | "import-blacklist": [
20 | true,
21 | "rxjs",
22 | "rxjs/Rx"
23 | ],
24 | "import-spacing": true,
25 | "indent": [
26 | true,
27 | "spaces"
28 | ],
29 | "interface-over-type-literal": true,
30 | "label-position": true,
31 | "max-line-length": [
32 | true,
33 | 140
34 | ],
35 | "member-access": false,
36 | "member-ordering": [
37 | true,
38 | {
39 | "order": [
40 | "static-field",
41 | "instance-field",
42 | "static-method",
43 | "instance-method"
44 | ]
45 | }
46 | ],
47 | "no-arg": true,
48 | "no-bitwise": true,
49 | "no-console": [
50 | true,
51 | "debug",
52 | "info",
53 | "time",
54 | "timeEnd",
55 | "trace"
56 | ],
57 | "no-construct": true,
58 | "no-debugger": true,
59 | "no-duplicate-super": true,
60 | "no-empty": false,
61 | "no-empty-interface": true,
62 | "no-eval": true,
63 | "no-inferrable-types": [
64 | true,
65 | "ignore-params"
66 | ],
67 | "no-misused-new": true,
68 | "no-non-null-assertion": true,
69 | "no-shadowed-variable": true,
70 | "no-string-literal": false,
71 | "no-string-throw": true,
72 | "no-switch-case-fall-through": true,
73 | "no-trailing-whitespace": true,
74 | "no-unnecessary-initializer": true,
75 | "no-unused-expression": true,
76 | "no-use-before-declare": true,
77 | "no-var-keyword": true,
78 | "object-literal-sort-keys": false,
79 | "one-line": [
80 | true,
81 | "check-open-brace",
82 | "check-catch",
83 | "check-else",
84 | "check-whitespace"
85 | ],
86 | "prefer-const": true,
87 | "quotemark": [
88 | true,
89 | "single"
90 | ],
91 | "radix": true,
92 | "semicolon": [
93 | true,
94 | "always"
95 | ],
96 | "triple-equals": [
97 | true,
98 | "allow-null-check"
99 | ],
100 | "typedef-whitespace": [
101 | true,
102 | {
103 | "call-signature": "nospace",
104 | "index-signature": "nospace",
105 | "parameter": "nospace",
106 | "property-declaration": "nospace",
107 | "variable-declaration": "nospace"
108 | }
109 | ],
110 | "unified-signatures": true,
111 | "variable-name": false,
112 | "whitespace": [
113 | true,
114 | "check-branch",
115 | "check-decl",
116 | "check-operator",
117 | "check-separator",
118 | "check-type"
119 | ],
120 | "directive-selector": [
121 | true,
122 | "attribute",
123 | "",
124 | "camelCase"
125 | ],
126 | "component-selector": [
127 | true,
128 | "element",
129 | "",
130 | "kebab-case"
131 | ],
132 | "no-output-on-prefix": true,
133 | "use-input-property-decorator": true,
134 | "use-output-property-decorator": true,
135 | "use-host-property-decorator": true,
136 | "no-input-rename": true,
137 | "no-output-rename": true,
138 | "use-life-cycle-interface": true,
139 | "use-pipe-transform-interface": true,
140 | "component-class-suffix": true,
141 | "directive-class-suffix": true
142 | }
143 | }
144 |
--------------------------------------------------------------------------------