@tryfinch/react-connect 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +9 -0
- package/.eslintignore +5 -0
- package/.eslintrc.js +43 -0
- package/.prettierrc.js +5 -0
- package/LICENSE +21 -0
- package/README.md +51 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.es.js +120 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.js +124 -0
- package/dist/index.js.map +1 -0
- package/example/README.md +2026 -0
- package/example/package-lock.json +55672 -0
- package/example/package.json +35 -0
- package/example/public/index.html +20 -0
- package/example/public/manifest.json +8 -0
- package/example/src/App.css +14 -0
- package/example/src/App.tsx +33 -0
- package/example/src/index.css +11 -0
- package/example/src/index.js +7 -0
- package/example/src/react-app-env.d.ts +1 -0
- package/example/tsconfig.json +26 -0
- package/package.json +78 -0
- package/rollup.config.js +49 -0
- package/src/index.d.ts +25 -0
- package/src/index.js +97 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-finch-connect-example",
|
|
3
|
+
"homepage": "https://.github.io/react-finch-connect",
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"private": true,
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"@types/react": "^17.0.37",
|
|
9
|
+
"prop-types": "^15.6.2",
|
|
10
|
+
"react": "file:../node_modules/react",
|
|
11
|
+
"react-dom": "^16.9.0",
|
|
12
|
+
"react-finch-connect": "file:.."
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"start": "react-scripts start",
|
|
16
|
+
"build": "react-scripts build",
|
|
17
|
+
"test": "react-scripts test --env=jsdom",
|
|
18
|
+
"eject": "react-scripts eject"
|
|
19
|
+
},
|
|
20
|
+
"eslintConfig": {
|
|
21
|
+
"extends": [
|
|
22
|
+
"react-app",
|
|
23
|
+
"react-app/jest"
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
"browserslist": [
|
|
27
|
+
">0.2%",
|
|
28
|
+
"not dead",
|
|
29
|
+
"not ie <= 11",
|
|
30
|
+
"not op_mini all"
|
|
31
|
+
],
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"react-scripts": "^5.0.1"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
|
6
|
+
<meta name="theme-color" content="#000000">
|
|
7
|
+
|
|
8
|
+
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
|
9
|
+
|
|
10
|
+
<title>react-finch-connect</title>
|
|
11
|
+
</head>
|
|
12
|
+
|
|
13
|
+
<body>
|
|
14
|
+
<noscript>
|
|
15
|
+
You need to enable JavaScript to run this app.
|
|
16
|
+
</noscript>
|
|
17
|
+
|
|
18
|
+
<div id="root"></div>
|
|
19
|
+
</body>
|
|
20
|
+
</html>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { useFinchConnect, SuccessEvent, ErrorEvent } from 'react-finch-connect';
|
|
3
|
+
import './App.css';
|
|
4
|
+
|
|
5
|
+
const App = () => {
|
|
6
|
+
const [code, setCode] = useState<string>();
|
|
7
|
+
|
|
8
|
+
const onSuccess = ({ code }: SuccessEvent) => setCode(code);
|
|
9
|
+
const onError = ({ errorMessage }: ErrorEvent) => console.error(errorMessage);
|
|
10
|
+
const onClose = () => console.log('User exited Finch Connect');
|
|
11
|
+
|
|
12
|
+
const { open } = useFinchConnect({
|
|
13
|
+
clientId: '<your-client-id>',
|
|
14
|
+
products: ['company', 'directory', 'individual', 'employment'],
|
|
15
|
+
// sandbox: false,
|
|
16
|
+
// payrollProvider: '<payroll-provider-id>',
|
|
17
|
+
onSuccess,
|
|
18
|
+
onError,
|
|
19
|
+
onClose,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<div className="App">
|
|
24
|
+
<header className="App-header">
|
|
25
|
+
<p>Code: {code}</p>
|
|
26
|
+
<button type="button" onClick={() => open()}>
|
|
27
|
+
Open Finch Connect
|
|
28
|
+
</button>
|
|
29
|
+
</header>
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
export default App;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
body {
|
|
2
|
+
margin: 0;
|
|
3
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',
|
|
4
|
+
'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
|
|
5
|
+
-webkit-font-smoothing: antialiased;
|
|
6
|
+
-moz-osx-font-smoothing: grayscale;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
code {
|
|
10
|
+
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="react-scripts" />
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "es5",
|
|
4
|
+
"lib": [
|
|
5
|
+
"dom",
|
|
6
|
+
"dom.iterable",
|
|
7
|
+
"esnext"
|
|
8
|
+
],
|
|
9
|
+
"allowJs": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"allowSyntheticDefaultImports": true,
|
|
13
|
+
"strict": true,
|
|
14
|
+
"forceConsistentCasingInFileNames": true,
|
|
15
|
+
"module": "esnext",
|
|
16
|
+
"moduleResolution": "node",
|
|
17
|
+
"resolveJsonModule": true,
|
|
18
|
+
"isolatedModules": true,
|
|
19
|
+
"noEmit": true,
|
|
20
|
+
"jsx": "react-jsx",
|
|
21
|
+
"noFallthroughCasesInSwitch": true
|
|
22
|
+
},
|
|
23
|
+
"include": [
|
|
24
|
+
"src"
|
|
25
|
+
]
|
|
26
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tryfinch/react-connect",
|
|
3
|
+
"version": "2.8.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"author": "",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": "Finch-API/react-finch-connect",
|
|
8
|
+
"main": "dist/index.js",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"module": "dist/index.es.js",
|
|
11
|
+
"jsnext:main": "dist/index.es.js",
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": ">=8",
|
|
14
|
+
"npm": ">=5"
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"test": "cross-env CI=1 react-scripts test --env=jsdom",
|
|
18
|
+
"test:watch": "react-scripts test --env=jsdom",
|
|
19
|
+
"build": "rollup -c",
|
|
20
|
+
"start": "rollup -c -w",
|
|
21
|
+
"prepare": "npm run build",
|
|
22
|
+
"predeploy": "cd example && npm install && npm run build"
|
|
23
|
+
},
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"react": ">=16.9.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@babel/core": "^7.0.0",
|
|
29
|
+
"@babel/plugin-external-helpers": "^7.0.0",
|
|
30
|
+
"@babel/plugin-proposal-class-properties": "^7.0.0",
|
|
31
|
+
"@babel/plugin-proposal-decorators": "^7.0.0",
|
|
32
|
+
"@babel/plugin-proposal-do-expressions": "^7.0.0",
|
|
33
|
+
"@babel/plugin-proposal-export-default-from": "^7.0.0",
|
|
34
|
+
"@babel/plugin-proposal-export-namespace-from": "^7.0.0",
|
|
35
|
+
"@babel/plugin-proposal-function-bind": "^7.0.0",
|
|
36
|
+
"@babel/plugin-proposal-function-sent": "^7.0.0",
|
|
37
|
+
"@babel/plugin-proposal-json-strings": "^7.0.0",
|
|
38
|
+
"@babel/plugin-proposal-logical-assignment-operators": "^7.0.0",
|
|
39
|
+
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
|
|
40
|
+
"@babel/plugin-proposal-numeric-separator": "^7.0.0",
|
|
41
|
+
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
|
|
42
|
+
"@babel/plugin-proposal-pipeline-operator": "^7.0.0",
|
|
43
|
+
"@babel/plugin-proposal-throw-expressions": "^7.0.0",
|
|
44
|
+
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
|
|
45
|
+
"@babel/plugin-syntax-import-meta": "^7.0.0",
|
|
46
|
+
"@babel/preset-env": "^7.0.0",
|
|
47
|
+
"@babel/preset-react": "^7.0.0",
|
|
48
|
+
"@rollup/plugin-replace": "^4.0.0",
|
|
49
|
+
"@testing-library/react-hooks": "^3.2.1",
|
|
50
|
+
"babel-eslint": "^10.0.1",
|
|
51
|
+
"cross-env": "^5.2.0",
|
|
52
|
+
"eslint": "^7.32.0",
|
|
53
|
+
"eslint-config-airbnb": "^18.2.0",
|
|
54
|
+
"eslint-config-prettier": "^6.11.0",
|
|
55
|
+
"eslint-config-standard": "^11.0.0",
|
|
56
|
+
"eslint-config-standard-react": "^6.0.0",
|
|
57
|
+
"eslint-plugin-import": "^2.22.0",
|
|
58
|
+
"eslint-plugin-jsx-a11y": "^6.3.1",
|
|
59
|
+
"eslint-plugin-node": "^7.0.1",
|
|
60
|
+
"eslint-plugin-prettier": "^3.1.4",
|
|
61
|
+
"eslint-plugin-promise": "^4.0.0",
|
|
62
|
+
"eslint-plugin-react": "^7.20.3",
|
|
63
|
+
"eslint-plugin-react-hooks": "^4.0.8",
|
|
64
|
+
"eslint-plugin-standard": "^3.1.0",
|
|
65
|
+
"gh-pages": "^2.0.1",
|
|
66
|
+
"prettier": "^2.0.5",
|
|
67
|
+
"react": "^16.9.0",
|
|
68
|
+
"react-scripts": "^5.0.1",
|
|
69
|
+
"react-test-renderer": "^16.9.0",
|
|
70
|
+
"rollup": "^2.75.7",
|
|
71
|
+
"rollup-plugin-babel": "^4.3.2",
|
|
72
|
+
"rollup-plugin-commonjs": "^9.2.0",
|
|
73
|
+
"rollup-plugin-dts": "^4.0.1",
|
|
74
|
+
"rollup-plugin-node-resolve": "^4.0.0",
|
|
75
|
+
"rollup-plugin-peer-deps-external": "^2.2.0",
|
|
76
|
+
"rollup-plugin-url": "^2.1.0"
|
|
77
|
+
}
|
|
78
|
+
}
|
package/rollup.config.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import babel from 'rollup-plugin-babel';
|
|
2
|
+
import commonjs from 'rollup-plugin-commonjs';
|
|
3
|
+
import dts from 'rollup-plugin-dts';
|
|
4
|
+
import external from 'rollup-plugin-peer-deps-external';
|
|
5
|
+
import resolve from 'rollup-plugin-node-resolve';
|
|
6
|
+
import url from 'rollup-plugin-url';
|
|
7
|
+
import replace from '@rollup/plugin-replace';
|
|
8
|
+
|
|
9
|
+
import pkg from './package.json';
|
|
10
|
+
|
|
11
|
+
export default [
|
|
12
|
+
{
|
|
13
|
+
input: 'src/index.js',
|
|
14
|
+
output: [
|
|
15
|
+
{
|
|
16
|
+
file: pkg.main,
|
|
17
|
+
format: 'cjs',
|
|
18
|
+
sourcemap: true,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
file: pkg.module,
|
|
22
|
+
format: 'es',
|
|
23
|
+
sourcemap: true,
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
plugins: [
|
|
27
|
+
external(),
|
|
28
|
+
url({ exclude: ['**/*.svg'] }),
|
|
29
|
+
babel({
|
|
30
|
+
exclude: 'node_modules/**',
|
|
31
|
+
}),
|
|
32
|
+
resolve(),
|
|
33
|
+
commonjs(),
|
|
34
|
+
replace({
|
|
35
|
+
SDK_VERSION: JSON.stringify(pkg.version), // has to be stringified somehow
|
|
36
|
+
}),
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
input: 'src/index.d.ts',
|
|
41
|
+
output: [
|
|
42
|
+
{
|
|
43
|
+
file: pkg.types,
|
|
44
|
+
format: 'es',
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
plugins: [dts()],
|
|
48
|
+
},
|
|
49
|
+
];
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
declare module 'react-finch-connect' {
|
|
2
|
+
export type SuccessEvent = {
|
|
3
|
+
code: string;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
export type ErrorEvent = {
|
|
7
|
+
errorMessage: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type ConnectOptions = {
|
|
11
|
+
clientId: string;
|
|
12
|
+
products?: string[];
|
|
13
|
+
mode?: string;
|
|
14
|
+
manual?: boolean;
|
|
15
|
+
payrollProvider?: string;
|
|
16
|
+
sandbox?: boolean;
|
|
17
|
+
category?: string;
|
|
18
|
+
onSuccess?: (e: SuccessEvent) => void;
|
|
19
|
+
onError?: (e: ErrorEvent) => void;
|
|
20
|
+
onClose?: () => void;
|
|
21
|
+
zIndex?: bigint | string;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export function useFinchConnect(opts: ConnectOptions): { open: () => void };
|
|
25
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
const BASE_FINCH_CONNECT_URI = 'https://connect.tryfinch.com';
|
|
4
|
+
const DEFAULT_FINCH_REDIRECT_URI = 'https://tryfinch.com';
|
|
5
|
+
const FINCH_CONNECT_IFRAME_ID = 'finch-connect-iframe';
|
|
6
|
+
const FINCH_AUTH_MESSAGE_NAME = 'finch-auth-message';
|
|
7
|
+
|
|
8
|
+
const noop = () => {};
|
|
9
|
+
|
|
10
|
+
// eslint-disable-next-line import/prefer-default-export
|
|
11
|
+
export const useFinchConnect = (options = {}) => {
|
|
12
|
+
const {
|
|
13
|
+
clientId,
|
|
14
|
+
products = [],
|
|
15
|
+
mode = 'employer',
|
|
16
|
+
category,
|
|
17
|
+
manual = false,
|
|
18
|
+
payrollProvider = null,
|
|
19
|
+
sandbox = false,
|
|
20
|
+
onSuccess = noop,
|
|
21
|
+
onError = noop,
|
|
22
|
+
onClose = noop,
|
|
23
|
+
zIndex = 999,
|
|
24
|
+
} = options;
|
|
25
|
+
|
|
26
|
+
const _constructAuthUrl = (clientId, products) => {
|
|
27
|
+
const authUrl = new URL(`${BASE_FINCH_CONNECT_URI}/authorize`);
|
|
28
|
+
|
|
29
|
+
if (clientId) authUrl.searchParams.append('client_id', clientId);
|
|
30
|
+
if (payrollProvider) authUrl.searchParams.append('payroll_provider', payrollProvider);
|
|
31
|
+
if (category) authUrl.searchParams.append('category', category);
|
|
32
|
+
authUrl.searchParams.append('products', products.join(' '));
|
|
33
|
+
authUrl.searchParams.append('app_type', 'spa');
|
|
34
|
+
authUrl.searchParams.append('redirect_uri', DEFAULT_FINCH_REDIRECT_URI);
|
|
35
|
+
authUrl.searchParams.append('mode', mode);
|
|
36
|
+
if (manual) authUrl.searchParams.append('manual', manual);
|
|
37
|
+
if (sandbox) authUrl.searchParams.append('sandbox', sandbox);
|
|
38
|
+
/* global SDK_VERSION */
|
|
39
|
+
if (SDK_VERSION) authUrl.searchParams.append('sdk_version', `react-${SDK_VERSION}`);
|
|
40
|
+
|
|
41
|
+
return authUrl.href;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const open = () => {
|
|
45
|
+
if (document.getElementById(FINCH_CONNECT_IFRAME_ID)) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const iframe = document.createElement('iframe');
|
|
50
|
+
iframe.src = _constructAuthUrl(clientId, products);
|
|
51
|
+
iframe.frameBorder = '0';
|
|
52
|
+
iframe.id = FINCH_CONNECT_IFRAME_ID;
|
|
53
|
+
iframe.style.position = 'fixed';
|
|
54
|
+
iframe.style.zIndex = zIndex.toString();
|
|
55
|
+
iframe.style.height = '100%';
|
|
56
|
+
iframe.style.width = '100%';
|
|
57
|
+
iframe.style.top = '0';
|
|
58
|
+
iframe.style.backgroundColor = 'none transparent';
|
|
59
|
+
iframe.style.border = 'none';
|
|
60
|
+
document.body.prepend(iframe);
|
|
61
|
+
document.body.style.overflow = 'hidden';
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const close = () => {
|
|
65
|
+
const frameToRemove = document.getElementById(FINCH_CONNECT_IFRAME_ID);
|
|
66
|
+
if (frameToRemove) {
|
|
67
|
+
frameToRemove.parentNode.removeChild(frameToRemove);
|
|
68
|
+
document.body.style.overflow = 'inherit';
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
function handleFinchAuth(event) {
|
|
74
|
+
const handleFinchAuthSuccess = (code) => onSuccess({ code });
|
|
75
|
+
const handleFinchAuthError = (error) => onError({ errorMessage: error });
|
|
76
|
+
const handleFinchAuthClose = () => onClose();
|
|
77
|
+
|
|
78
|
+
if (!event.data) return;
|
|
79
|
+
if (event.data.name !== FINCH_AUTH_MESSAGE_NAME) return;
|
|
80
|
+
if (!event.origin.startsWith(BASE_FINCH_CONNECT_URI)) return;
|
|
81
|
+
|
|
82
|
+
const { code, error, closed } = event.data;
|
|
83
|
+
|
|
84
|
+
close();
|
|
85
|
+
if (code) handleFinchAuthSuccess(code);
|
|
86
|
+
else if (error) handleFinchAuthError(error);
|
|
87
|
+
else if (closed) handleFinchAuthClose();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
window.addEventListener('message', handleFinchAuth);
|
|
91
|
+
return () => window.removeEventListener('message', handleFinchAuth);
|
|
92
|
+
}, [onClose, onError, onSuccess]);
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
open,
|
|
96
|
+
};
|
|
97
|
+
};
|