Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
mike-roberts committed Aug 15, 2018
0 parents commit 87cca9b
Show file tree
Hide file tree
Showing 15 changed files with 452 additions and 0 deletions.
31 changes: 31 additions & 0 deletions karma.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html

module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, '../../coverage'),
reports: ['html', 'lcovonly'],
fixWebpackSourcePaths: true
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
});
};
8 changes: 8 additions & 0 deletions ng-package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../dist/ngx-plaid-link",
"deleteDestPath": false,
"lib": {
"entryFile": "src/public_api.ts"
}
}
7 changes: 7 additions & 0 deletions ng-package.prod.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../dist/ngx-plaid-link",
"lib": {
"entryFile": "src/public_api.ts"
}
}
12 changes: 12 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "ngx-plaid-link",
"version": "0.1.0",
"author": {
"name": "Mike Roberts",
"url": "https://github.com/mike-roberts"
},
"peerDependencies": {
"@angular/common": "^6.0.0-rc.0 || ^6.0.0",
"@angular/core": "^6.0.0-rc.0 || ^6.0.0"
}
}
76 changes: 76 additions & 0 deletions src/lib/interfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
export interface PlaidSuccessMetadata {
link_session_id: string;
institution: PlaidInstitutionObject;
account: Array<PlaidAccountObject>;
}

export interface PlaidOnSuccessArgs {
token: string;
metadata: PlaidSuccessMetadata;
}

export interface PlaidInstitutionObject {
name: string;
institution_id: string;
}

export interface PlaidAccountObject {
id: string;
name: string;
mask: string;
type: string;
subtype: string;
}

export interface PlaidErrorObject {
display_message: string;
error_code: string;
error_message: string;
error_type: string;
}

export interface PlaidErrorMetadata {
link_session_id: string;
institution: PlaidInstitutionObject;
status: string;
}

export interface PlaidOnExitArgs {
error: PlaidErrorObject;
metadata: PlaidErrorMetadata;
}

export interface PlaidOnEventArgs {
eventName: string;
metadata: PlaidEventMetadata;
}

export interface PlaidEventMetadata {
error_code: string;
error_message: string;
error_type: string;
exit_status: string;
institution_id: string;
institution_name: string;
institution_search_query: string;
request_id: string;
link_session_id: string;
mfa_type: string;
view_name: string;
timestamp: string;
}

export interface PlaidConfig {
apiVersion?: string;
clientName?: string;
env: string;
forceIframe?: boolean;
key: string;
onLoad?: Function;
onSuccess: Function;
onExit: Function;
onEvent?: Function;
product: Array<string>;
token?: string;
webhook?: string;
}
25 changes: 25 additions & 0 deletions src/lib/ngx-plaid-link.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { NgxPlaidLinkComponent } from './ngx-plaid-link.component';

describe('NgxPlaidLinkComponent', () => {
let component: NgxPlaidLinkComponent;
let fixture: ComponentFixture<NgxPlaidLinkComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ NgxPlaidLinkComponent ]
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(NgxPlaidLinkComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
162 changes: 162 additions & 0 deletions src/lib/ngx-plaid-link.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import { Component, Input, Output, EventEmitter } from '@angular/core';
import {
PlaidErrorMetadata,
PlaidErrorObject,
PlaidEventMetadata,
PlaidOnEventArgs,
PlaidOnExitArgs,
PlaidOnSuccessArgs,
PlaidSuccessMetadata,
PlaidConfig
} from './interfaces';

import { DOCUMENT } from '@angular/platform-browser';

export interface ICustomWindow extends Window {
Plaid: {
create: Function;
};
}

function getWindow(): any {
return window;
}

@Component({
selector: 'mr-ngx-plaid-link',
template: `
<button
(click)="onClick($event)"
[class]="className"
[disabled]="disabledButton"
[ngStyle]="style">
{{buttonText}}
</button>
`,
styles: []
})
export class NgxPlaidLinkComponent {

private defaultProps = {
apiVersion: 'v2',
env: 'sandbox',
institution: null,
token: null,
style: {
'padding': '6px 4px',
'outline': 'none',
'background': '#FFFFFF',
'border': '2px solid #F1F1F1',
'border-radius': '4px',
},
buttonText: 'Link Your Bank Account',
webhook: '',
product: ['auth'],
className: 'plaid-link-button'
};

disabledButton: boolean;
linkLoaded: boolean;

linkHandler: any;

@Input() apiVersion?: string = this.defaultProps.apiVersion;
@Input() clientName?: string;
@Input() env?: string = this.defaultProps.env;
@Input() institution?: string = this.defaultProps.institution;
@Input() publicKey: string;
@Input() product?: Array<string> = this.defaultProps.product;
@Input() token?: string = this.defaultProps.token;
@Input() webhook?: string = this.defaultProps.webhook;
@Input() style?: any = this.defaultProps.style;
@Input() className?: string = this.defaultProps.className;
@Input() buttonText?: string = this.defaultProps.buttonText;

@Output() Event: EventEmitter<PlaidOnEventArgs> = new EventEmitter();
@Output() Click: EventEmitter<any> = new EventEmitter();
@Output() Load: EventEmitter<any> = new EventEmitter();
@Output() Exit: EventEmitter<PlaidOnExitArgs> = new EventEmitter();
@Output() Success: EventEmitter<PlaidOnSuccessArgs> = new EventEmitter();

get nativeWindow(): ICustomWindow {
return getWindow();
}

constructor() {
this.disabledButton = false;
this.linkLoaded = false;
}

onScriptError() {
console.error('There was an issue loading the link-initialize.js script');
}

public onExit(error: PlaidErrorObject, metadata: PlaidErrorMetadata) {
this.Exit.emit({
error: error,
metadata: metadata
});
}

public onEvent(eventName: string, metadata: PlaidEventMetadata) {
this.Event.emit({
eventName: eventName,
metadata: metadata
});
}

public onSuccess(public_token: string, metadata: PlaidSuccessMetadata) {
this.Success.emit({
token: public_token,
metadata: metadata
});
}

onClick($event) {
this.Click.emit($event);
const self = this;
const config: PlaidConfig = {
env: self.env,
key: self.publicKey,
product: self.product,
apiVersion: 'v2',
forceIframe: true,
onSuccess: function (public_token, metadata) {
self.onSuccess(public_token, metadata);
},
onExit: function (err, metadata) {
self.onExit(err, metadata);
},
onEvent: function (eventName, metadata) {
self.onEvent(eventName, metadata);
},
onLoad: function () {
self.onLoad();
}
};
// Set the optional items.
if (!!self.clientName) {
config.clientName = self.clientName;
}
if (!!self.token) {
config.token = self.token;
}
if (!!self.webhook) {
config.webhook = self.webhook;
}

this.linkHandler = this.nativeWindow.Plaid.create(config);

// Open to a specific institution if necessary;
const institution = this.institution || null;
if (this.linkHandler) {
this.linkHandler.open(institution);
}
}

public onLoad($event = 'link_loaded') {
this.Load.emit($event);
this.linkLoaded = true;
}

}
12 changes: 12 additions & 0 deletions src/lib/ngx-plaid-link.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { NgModule, ModuleWithProviders } from '@angular/core';
import { CommonModule } from '@angular/common';
import { NgxPlaidLinkComponent } from './ngx-plaid-link.component';

@NgModule({
imports: [
CommonModule
],
declarations: [NgxPlaidLinkComponent],
exports: [NgxPlaidLinkComponent]
})
export class NgxPlaidLinkModule { }
15 changes: 15 additions & 0 deletions src/lib/ngx-plaid-link.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { TestBed, inject } from '@angular/core/testing';

import { NgxPlaidLinkService } from './ngx-plaid-link.service';

describe('NgxPlaidLinkService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [NgxPlaidLinkService]
});
});

it('should be created', inject([NgxPlaidLinkService], (service: NgxPlaidLinkService) => {
expect(service).toBeTruthy();
}));
});
8 changes: 8 additions & 0 deletions src/lib/ngx-plaid-link.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Injectable } from '@angular/core';

@Injectable({
providedIn: 'root'
})
export class NgxPlaidLinkService {
constructor() { }
}
7 changes: 7 additions & 0 deletions src/public_api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* Public API Surface of ngx-plaid-link
*/

export * from './lib/ngx-plaid-link.service';
export * from './lib/ngx-plaid-link.component';
export * from './lib/ngx-plaid-link.module';
22 changes: 22 additions & 0 deletions src/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// This file is required by karma.conf.js and loads recursively all the .spec and framework files

import 'core-js/es7/reflect';
import 'zone.js/dist/zone';
import 'zone.js/dist/zone-testing';
import { getTestBed } from '@angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';

declare const require: any;

// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
);
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);
Loading

0 comments on commit 87cca9b

Please sign in to comment.