Skip to content

Commit

Permalink
add new prop and change some of the props, add lint, update readme
Browse files Browse the repository at this point in the history
  • Loading branch information
erhangundogan committed Jul 25, 2020
1 parent c6ad205 commit 6c5ffe0
Show file tree
Hide file tree
Showing 9 changed files with 893 additions and 98 deletions.
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dist/**
coverage/**
66 changes: 66 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
const rules = {
"arrow-body-style": ["error", "as-needed"],
"object-curly-spacing": [
2,
"always",
{ objectsInObjects: false, objectsInObjects: true }
],
"jsx-quotes": ["error", "prefer-double"],
"no-multiple-empty-lines": "error",
"no-trailing-spaces": "error",
curly: "error",
};

const extendsConfigs = [
"eslint:recommended",
"plugin:react/recommended"
];

module.exports = {
parser: "babel-eslint",
env: {
browser: true,
amd: true,
node: true,
es6: true,
"jest/globals": true
},
extends: extendsConfigs,
overrides: [
{
files: ["*.ts", "*.tsx"],
parser: "@typescript-eslint/parser",
extends: [...extendsConfigs, "plugin:@typescript-eslint/recommended"],
rules: {
...rules,

"@typescript-eslint/no-use-before-define": "off",

"react/prop-types": "off",
"react/no-unescaped-entities": "off",
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",

"jest/no-disabled-tests": "warn",
"jest/no-focused-tests": "error",
"jest/no-identical-title": "error",
"jest/prefer-to-have-length": "warn",
"jest/valid-expect": "error"
}
}
],
plugins: ["react-hooks", "jest"],
parserOptions: {
ecmaVersion: 2018,
sourceType: "module",
ecmaFeatures: {
jsx: true
}
},
rules,
settings: {
react: {
version: "detect"
}
}
};
39 changes: 24 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,25 @@ Generate `accessToken` or `jwtToken` with your `clientId`, `secret` and `userNam
```jsx
import { useYodlee } from 'yodlee-react-hook';

const YodleeComponent = ({ accessToken }) => {
const MyComponent = () => {
const { ready, init } = useYodlee({
containerId: 'container-fastlink',
fastLinkOptions: {
accessToken
fastLinkURL: 'https://node.sandbox.yodlee.com/authenticate/restserver',
token: {
tokenType: 'AccessToken',
tokenValue: 'foo'
}
}
});

return (
<div className="container">
<div id="container-fastlink"></div>
{ ready ? <button onClick={init}>Open your account</button> : 'Loading...' }
{ ready ? <button onClick={() => init()}>Open Yodlee</button> : 'Loading...' }
</div>
);
};
}
```

Test
Expand All @@ -55,17 +59,20 @@ Details

### `useYodlee` hook arguments:

- containerId (string): Id for DOM Element to load iframe into.
- fastLinkURL (string): FastLink URL to be used. Please see some URLs from tutorials below.
- USA: https://node.sandbox.yodlee.com/authenticate/restserver
- UK: https://node.sandbox.yodlee.uk/authenticate/uksandbox
- ANZ: https://sandbox-node.yodlee.com.au/authenticate/anzdevexsandbox
- accessToken: (string): Pass this if you are using a client credential user access token.
- jwtToken: (string): Pass this if you are using a JWT user token.
- userExperienceFlow (UserExperienceFlowType):
- Verification (default): Aggregate account profile information required to perform user profile verification.
- Aggregation: Aggregate account summary-level information and transactions.
- Aggregation plus Verification: Aggregate account summary-level information and transactions, along with account profile information.
- containerId (`string`): Id for DOM Element to load iframe into.
- createScriptTag (`boolean`, default = true): If you set this to false then hook will not add script element to component. It's suitable for react apps having script element already added to the page e.g. `<script defer async src="https://cdn.yodlee.com/fastlink/v3/initialize.js"></script>`. If you receive [cross-origin error from React](https://reactjs.org/docs/cross-origin-errors.html) then this would be the preferred solution for you.
- fastLinkOptions (`FastLinkOptionsType`)
- fastLinkURL (`string`): FastLink URL to be used. Please see URLs below from Yodlee codepen solution.
- USA: https://node.sandbox.yodlee.com/authenticate/restserver
- UK: https://node.sandbox.yodlee.uk/authenticate/uksandbox
- ANZ: https://sandbox-node.yodlee.com.au/authenticate/anzdevexsandbox
- token: (`TokenType`):
- tokenType: (`'AccessToken' | 'JwtToken'`): Your token type
- tokenValue: (`string`): Your token value
- userExperienceFlow (`UserExperienceFlowType`, default = Verification):
- Verification: Aggregate account profile information required to perform user profile verification.
- Aggregation: Aggregate account summary-level information and transactions.
- Aggregation plus Verification: Aggregate account summary-level information and transactions, along with account profile information.
- onSuccess, onError, onExit, onEvent: Additional callback functions if you would like to add customer implementation.

Please consult to Yodlee fastlink.open() [instructions](https://developer.yodlee.com/docs/fastlink/3.0/getting-started) for details.
Expand All @@ -77,3 +84,5 @@ Please consult to Yodlee fastlink.open() [instructions](https://developer.yodlee
- active (boolean): Init method called or not
- data (any): Customer data received from onSuccess event
- error (any): This is the error if Yodlee FastLink intercepts with any error

You can find typescript definitions in `index.d.ts` file.
56 changes: 31 additions & 25 deletions dist/bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,39 +27,45 @@ var __assign = function() {
};

var useYodlee = function (_a) {
var containerId = _a.containerId, _b = _a.fastLinkOptions, fastLinkURL = _b.fastLinkURL, accessToken = _b.accessToken, jwtToken = _b.jwtToken, _c = _b.userExperienceFlow, userExperienceFlow = _c === void 0 ? 'Verification' : _c, onSuccess = _a.onSuccess, onError = _a.onError, onExit = _a.onExit, onEvent = _a.onEvent;
var _d = useState(false), ready = _d[0], setReady = _d[1];
var _e = useState(null), error = _e[0], setError = _e[1];
var _f = useState(null), data = _f[0], setData = _f[1];
var _g = useState(false), active = _g[0], setActive = _g[1];
var containerId = _a.containerId, _b = _a.createScriptTag, createScriptTag = _b === void 0 ? true : _b, _c = _a.fastLinkOptions, fastLinkURL = _c.fastLinkURL, token = _c.token, _d = _c.userExperienceFlow, userExperienceFlow = _d === void 0 ? 'Verification' : _d, onSuccess = _a.onSuccess, onError = _a.onError, onExit = _a.onExit, onEvent = _a.onEvent;
var _e = useState(false), ready = _e[0], setReady = _e[1];
var _f = useState(null), error = _f[0], setError = _f[1];
var _g = useState(null), data = _g[0], setData = _g[1];
var _h = useState(false), active = _h[0], setActive = _h[1];
useEffect(function () {
var script = document.createElement('script');
script.id = 'yodlee-fastlink-script';
script.src = 'https://cdn.yodlee.com/fastlink/v3/initialize.js';
script.async = true;
script.defer = true;
script.onload = function () { return setReady(true); };
script.onerror = function () { return setError('Yodlee FastLink library could not be loaded!'); };
document.body.appendChild(script);
var script;
if (createScriptTag) {
script = document.createElement('script');
script.id = 'yodlee-fastlink-script';
script.src = 'https://cdn.yodlee.com/fastlink/v3/initialize.js';
script.async = true;
script.defer = true;
script.onload = function () { return setReady(true); };
script.onerror = function () { return setError('Yodlee FastLink library could not be loaded!'); };
document.body.appendChild(script);
}
return function () {
var _a;
(_a = window.fastlink) === null || _a === void 0 ? void 0 : _a.close();
document.body.removeChild(script);
if (createScriptTag) {
document.body.removeChild(script);
}
};
}, []);
var init = function () {
var init = function (currentToken) {
var _a;
var token = {};
var getTokenString = function (t) {
switch (t.tokenType) {
case 'AccessToken': {
return { accessToken: "Bearer " + t.tokenValue };
}
case 'JwtToken': {
return { jwtToken: "Bearer " + t.tokenValue };
}
}
};
setActive(true);
if (accessToken) {
token.accessToken = "Bearer " + accessToken;
}
else {
token.jwtToken = "Bearer " + jwtToken;
}
(_a = window.fastlink) === null || _a === void 0 ? void 0 : _a.open(__assign(__assign({ fastLinkURL: fastLinkURL }, token), { params: {
userExperienceFlow: userExperienceFlow
}, onSuccess: function (customerData) {
(_a = window.fastlink) === null || _a === void 0 ? void 0 : _a.open(__assign(__assign({ fastLinkURL: fastLinkURL, params: { userExperienceFlow: userExperienceFlow } }, getTokenString(currentToken || token)), { onSuccess: function (customerData) {
setData(customerData);
onSuccess && onSuccess(customerData);
}, onError: function (fastLinkError) {
Expand Down
13 changes: 10 additions & 3 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
export type UserExperienceFlowType = 'Aggregation' | 'Verification' | 'Aggregation plus Verification';

export type TokenEnumType = 'AccessToken' | 'JwtToken';

export interface TokenType {
tokenType: TokenEnumType;
tokenValue: string;
}

export interface FastLinkOptionsType {
fastLinkURL: string;
accessToken?: string;
jwtToken?: string;
token?: TokenType;
userExperienceFlow?: UserExperienceFlowType;
}

export interface YodleeHookPropsType {
containerId: string;
createScriptTag?: boolean;
fastLinkOptions: FastLinkOptionsType;
onSuccess?: (args: any) => void;
onError?: (args: any) => void;
Expand All @@ -17,7 +24,7 @@ export interface YodleeHookPropsType {
}

export interface YodleeHookReturnType {
init: () => void;
init: (token?: TokenType) => void;
data: any;
error: any;
ready: boolean;
Expand Down
13 changes: 10 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "yodlee-react-hook",
"version": "0.1.4",
"version": "0.2.0",
"description": "Yodlee FastLink integration with React hooks",
"repository": "github:erhangundogan/yodlee-react-hook",
"keywords": [
Expand All @@ -16,6 +16,7 @@
"license": "MIT",
"main": "./dist/bundle.js",
"scripts": {
"lint": "eslint \"src/**/*.{js,ts,tsx}\"",
"test": "jest --config=jest.config.js",
"build": "rollup src/index.ts -c",
"watch": "rollup src/index.ts -cw"
Expand All @@ -28,6 +29,13 @@
"@types/react": "^16.9.43",
"@types/react-dom": "^16.9.8",
"@types/testing-library__react-hooks": "^3.3.0",
"@typescript-eslint/eslint-plugin": "^3.7.0",
"@typescript-eslint/parser": "^3.7.0",
"babel-eslint": "^10.1.0",
"eslint": "^7.5.0",
"eslint-plugin-jest": "^23.18.0",
"eslint-plugin-react": "^7.20.3",
"eslint-plugin-react-hooks": "^4.0.8",
"jest": "^26.1.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
Expand All @@ -41,7 +49,6 @@
},
"peerDependencies": {
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-test-renderer": "^16.13.1"
"react-dom": "^16.13.1"
}
}
7 changes: 5 additions & 2 deletions src/__tests__/useYodlee.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,17 @@ describe('useYodlee', () => {
containerId: 'container-fastlink',
fastLinkOptions: {
fastLinkURL: 'https://node.sandbox.yodlee.com/authenticate/restserver',
accessToken: 'foo'
token: {
tokenType: 'AccessToken',
tokenValue: 'foo'
}
}
});

return (
<div className="container">
<div id="container-fastlink"></div>
{ ready ? <button onClick={ init }>Open Yodlee</button> : 'Loading...' }
{ ready ? <button onClick={() => init()}>Open Yodlee</button> : 'Loading...' }
</div>
);
}
Expand Down
72 changes: 39 additions & 33 deletions src/useYodlee.ts
Original file line number Diff line number Diff line change
@@ -1,59 +1,65 @@
import { useEffect, useState } from 'react';
import { YodleeHookType } from '../index';
import { TokenType, YodleeHookType } from '../index';

const useYodlee: YodleeHookType = ({
containerId,
fastLinkOptions: {
fastLinkURL,
accessToken,
jwtToken,
userExperienceFlow = 'Verification'
},
onSuccess,
onError,
onExit,
onEvent,
containerId,
createScriptTag = true,
fastLinkOptions: {
fastLinkURL,
token,
userExperienceFlow = 'Verification'
},
onSuccess,
onError,
onExit,
onEvent,
}) => {
const [ready, setReady] = useState(false);
const [error, setError] = useState(null);
const [data, setData] = useState(null);
const [active, setActive] = useState(false);

useEffect(() => {
const script = document.createElement('script');
let script: HTMLScriptElement;
if (createScriptTag) {
script = document.createElement('script');

script.id = 'yodlee-fastlink-script';
script.src = 'https://cdn.yodlee.com/fastlink/v3/initialize.js';
script.async = true;
script.defer = true;
script.onload = () => setReady(true);
script.onerror = () => setError('Yodlee FastLink library could not be loaded!');
script.id = 'yodlee-fastlink-script';
script.src = 'https://cdn.yodlee.com/fastlink/v3/initialize.js';
script.async = true;
script.defer = true;
script.onload = () => setReady(true);
script.onerror = () => setError('Yodlee FastLink library could not be loaded!');

document.body.appendChild(script);
document.body.appendChild(script);
}

return () => {
window.fastlink?.close();
document.body.removeChild(script);
if (createScriptTag) {
document.body.removeChild(script);
}
}
}, []);

const init = () => {
const token: { accessToken?: string; jwtToken?: string } = {};
const init = (currentToken?: TokenType) => {
const getTokenString = (t : TokenType) => {
switch (t.tokenType) {
case 'AccessToken': {
return { accessToken: `Bearer ${t.tokenValue}` };
}
case 'JwtToken': {
return { jwtToken: `Bearer ${t.tokenValue}` };
}
}
}

setActive(true);

if (accessToken) {
token.accessToken = `Bearer ${accessToken}`;
} else {
token.jwtToken = `Bearer ${jwtToken}`;
}

window.fastlink?.open({
fastLinkURL,
...token,
params: {
userExperienceFlow
},
params: { userExperienceFlow },
...getTokenString(currentToken || token),
onSuccess: (customerData: any) => {
setData(customerData);
onSuccess && onSuccess(customerData);
Expand Down
Loading

0 comments on commit 6c5ffe0

Please sign in to comment.