@cas-parser/connect 1.1.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/LICENSE +21 -0
- package/README.md +263 -0
- package/dist/PortfolioConnect.d.ts +5 -0
- package/dist/components/CDSLFetchMode.d.ts +13 -0
- package/dist/components/FetchMode.d.ts +12 -0
- package/dist/components/Modal.d.ts +12 -0
- package/dist/components/PortfolioConnectWidget.d.ts +14 -0
- package/dist/components/ShortcutLinks.d.ts +8 -0
- package/dist/components/UploadZone.d.ts +8 -0
- package/dist/imperative.d.ts +87 -0
- package/dist/index.cjs.js +1766 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.esm.js +1755 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/portfolio-connect.standalone.min.js +2 -0
- package/dist/portfolio-connect.standalone.min.js.map +1 -0
- package/dist/portfolio-connect.umd.js +1769 -0
- package/dist/portfolio-connect.umd.js.map +1 -0
- package/dist/portfolio-connect.umd.min.js +2 -0
- package/dist/portfolio-connect.umd.min.js.map +1 -0
- package/dist/types/index.d.ts +86 -0
- package/dist/utils/api.d.ts +57 -0
- package/package.json +84 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 CASParser
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
# Portfolio Connect SDK
|
|
2
|
+
|
|
3
|
+
> Drop-in widget for importing Indian investment statements (Mutual Funds, CDSL, NSDL).
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@cas-parser/connect)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Quick Start
|
|
9
|
+
|
|
10
|
+
Get your access token from [docs.casparser.in](https://docs.casparser.in)
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
### npm / yarn
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @cas-parser/connect
|
|
18
|
+
# or
|
|
19
|
+
yarn add @cas-parser/connect
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### CDN (Vanilla JS / Angular / Vue)
|
|
23
|
+
|
|
24
|
+
**Option 1: Standalone Bundle (Recommended)** - Includes React, no extra dependencies:
|
|
25
|
+
|
|
26
|
+
```html
|
|
27
|
+
<script src="https://unpkg.com/@cas-parser/connect/dist/portfolio-connect.standalone.min.js"></script>
|
|
28
|
+
|
|
29
|
+
<script>
|
|
30
|
+
// Simple imperative API - no React knowledge needed!
|
|
31
|
+
document.getElementById('import-btn').onclick = async () => {
|
|
32
|
+
try {
|
|
33
|
+
const { data, metadata } = await PortfolioConnect.open({
|
|
34
|
+
accessToken: 'your_access_token',
|
|
35
|
+
config: { enableCdslFetch: true }
|
|
36
|
+
});
|
|
37
|
+
console.log('Portfolio:', data);
|
|
38
|
+
} catch (error) {
|
|
39
|
+
if (error.message === 'Widget closed by user') {
|
|
40
|
+
console.log('User cancelled');
|
|
41
|
+
} else {
|
|
42
|
+
console.error('Error:', error);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
</script>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Option 2: Lightweight Bundle** - If you already have React on your page:
|
|
50
|
+
|
|
51
|
+
```html
|
|
52
|
+
<script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
|
|
53
|
+
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
|
|
54
|
+
<script src="https://unpkg.com/@cas-parser/connect/dist/portfolio-connect.umd.min.js"></script>
|
|
55
|
+
|
|
56
|
+
<script>
|
|
57
|
+
// Same imperative API works here too
|
|
58
|
+
document.getElementById('import-btn').onclick = () => {
|
|
59
|
+
PortfolioConnect.open({
|
|
60
|
+
accessToken: 'your_access_token',
|
|
61
|
+
}).then(({ data }) => console.log(data));
|
|
62
|
+
};
|
|
63
|
+
</script>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Bundle Sizes:**
|
|
67
|
+
- Standalone: ~54KB gzipped (includes React - no dependencies!)
|
|
68
|
+
- UMD: ~9KB gzipped (requires React 17+ on page)
|
|
69
|
+
|
|
70
|
+
## Quick Start
|
|
71
|
+
|
|
72
|
+
### React
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
import { PortfolioConnect } from '@cas-parser/connect';
|
|
76
|
+
|
|
77
|
+
function App() {
|
|
78
|
+
return (
|
|
79
|
+
<PortfolioConnect
|
|
80
|
+
accessToken="your_access_token"
|
|
81
|
+
onSuccess={(data) => console.log('Portfolio:', data)}
|
|
82
|
+
>
|
|
83
|
+
{({ open }) => (
|
|
84
|
+
<button onClick={open}>Import Portfolio</button>
|
|
85
|
+
)}
|
|
86
|
+
</PortfolioConnect>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Vanilla JS / Angular / Vue (Imperative API)
|
|
92
|
+
|
|
93
|
+
Use the simple `open()` function - returns a Promise:
|
|
94
|
+
|
|
95
|
+
```html
|
|
96
|
+
<!-- Standalone build - no React needed! -->
|
|
97
|
+
<script src="https://unpkg.com/@cas-parser/connect/dist/portfolio-connect.standalone.min.js"></script>
|
|
98
|
+
|
|
99
|
+
<button id="import-btn">Import Portfolio</button>
|
|
100
|
+
|
|
101
|
+
<script>
|
|
102
|
+
document.getElementById('import-btn').onclick = async () => {
|
|
103
|
+
try {
|
|
104
|
+
const { data, metadata } = await PortfolioConnect.open({
|
|
105
|
+
accessToken: 'your_access_token',
|
|
106
|
+
config: {
|
|
107
|
+
title: 'Import Your Portfolio',
|
|
108
|
+
enableCdslFetch: true,
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
console.log('Portfolio data:', data);
|
|
113
|
+
console.log('Metadata:', metadata);
|
|
114
|
+
|
|
115
|
+
} catch (error) {
|
|
116
|
+
if (error.message === 'Widget closed by user') {
|
|
117
|
+
console.log('User cancelled');
|
|
118
|
+
} else {
|
|
119
|
+
console.error('Error:', error);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
</script>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Configuration
|
|
127
|
+
|
|
128
|
+
```tsx
|
|
129
|
+
<PortfolioConnect
|
|
130
|
+
accessToken="your_access_token"
|
|
131
|
+
config={{
|
|
132
|
+
// Branding
|
|
133
|
+
logoUrl: 'https://yourapp.com/logo.png',
|
|
134
|
+
title: 'Import Your Investments',
|
|
135
|
+
subtitle: 'Mutual Funds, Stocks, Bonds — all in one place',
|
|
136
|
+
|
|
137
|
+
// Features
|
|
138
|
+
enableGenerator: true, // MF statement via email (KFintech)
|
|
139
|
+
enableCdslFetch: true, // CDSL statement via OTP
|
|
140
|
+
|
|
141
|
+
// Restrict portfolio types
|
|
142
|
+
allowedTypes: ['CAMS_KFINTECH', 'CDSL', 'NSDL'],
|
|
143
|
+
|
|
144
|
+
// Pre-fill user details
|
|
145
|
+
prefill: {
|
|
146
|
+
pan: 'ABCDE1234F', // Optional, for CAMS_KFINTECH, CDSL
|
|
147
|
+
email: 'user@example.com', // Optional, for CAMS_KFINTECH, CDSL
|
|
148
|
+
boId: '1234567890123456', // Optional, CDSL BO ID
|
|
149
|
+
dob: '1990-01-15', // Optional, CDSL DOB
|
|
150
|
+
},
|
|
151
|
+
|
|
152
|
+
// Generator options
|
|
153
|
+
generator: {
|
|
154
|
+
fromDate: '2020-01-01',
|
|
155
|
+
toDate: '2024-12-31',
|
|
156
|
+
},
|
|
157
|
+
|
|
158
|
+
// UI options
|
|
159
|
+
showShortcuts: true, // Email search shortcuts
|
|
160
|
+
showPortalLinks: true, // Links to download portals
|
|
161
|
+
}}
|
|
162
|
+
onSuccess={handleSuccess}
|
|
163
|
+
onError={handleError}
|
|
164
|
+
onEvent={(event, metadata) => analytics.track(event, metadata)}
|
|
165
|
+
>
|
|
166
|
+
{({ open, isReady }) => (
|
|
167
|
+
<button onClick={open} disabled={!isReady}>
|
|
168
|
+
Import Portfolio
|
|
169
|
+
</button>
|
|
170
|
+
)}
|
|
171
|
+
</PortfolioConnect>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Framework Support
|
|
175
|
+
|
|
176
|
+
| Framework | Support | Method |
|
|
177
|
+
|-----------|---------|--------|
|
|
178
|
+
| **React** | ✅ Native | npm package |
|
|
179
|
+
| **Next.js** | ✅ Native | npm package |
|
|
180
|
+
| **Angular** | ✅ Via CDN | UMD bundle |
|
|
181
|
+
| **Vue** | ✅ Via CDN | UMD bundle |
|
|
182
|
+
| **Vanilla JS** | ✅ Via CDN | UMD bundle |
|
|
183
|
+
| **React Native** | ✅ WebView | See examples |
|
|
184
|
+
| **Flutter** | ✅ WebView | See examples |
|
|
185
|
+
|
|
186
|
+
See [EXAMPLES.md](./EXAMPLES.md) for framework-specific integration guides.
|
|
187
|
+
|
|
188
|
+
## API Reference
|
|
189
|
+
|
|
190
|
+
### Props
|
|
191
|
+
|
|
192
|
+
| Prop | Type | Required | Description |
|
|
193
|
+
|------|------|----------|-------------|
|
|
194
|
+
| `accessToken` | `string` | Yes | Your access token ([get one](https://docs.casparser.in)) |
|
|
195
|
+
| `onSuccess` | `(data, metadata) => void` | Yes | Success callback with parsed data |
|
|
196
|
+
| `onError` | `(error) => void` | No | Error callback |
|
|
197
|
+
| `onExit` | `() => void` | No | Widget closed callback |
|
|
198
|
+
| `onEvent` | `(event, metadata) => void` | No | Analytics/tracking callback |
|
|
199
|
+
| `config` | `PortfolioConnectConfig` | No | Configuration options |
|
|
200
|
+
|
|
201
|
+
### Config Options
|
|
202
|
+
|
|
203
|
+
| Option | Type | Default | Description |
|
|
204
|
+
|--------|------|---------|-------------|
|
|
205
|
+
| `logoUrl` | `string` | CASParser logo | Your brand logo URL |
|
|
206
|
+
| `title` | `string` | "Import Your Investments" | Widget title |
|
|
207
|
+
| `subtitle` | `string` | "Mutual Funds, Stocks..." | Widget subtitle |
|
|
208
|
+
| `enableGenerator` | `boolean` | `false` | Enable MF fetch via email |
|
|
209
|
+
| `enableCdslFetch` | `boolean` | `false` | Enable CDSL fetch via OTP |
|
|
210
|
+
| `allowedTypes` | `PortfolioType[]` | All | Restrict to specific types |
|
|
211
|
+
| `prefill` | `object` | - | Pre-fill user details |
|
|
212
|
+
|
|
213
|
+
### Events
|
|
214
|
+
|
|
215
|
+
| Event | Description |
|
|
216
|
+
|-------|-------------|
|
|
217
|
+
| `WIDGET_OPENED` | Widget opened |
|
|
218
|
+
| `WIDGET_CLOSED` | Widget closed |
|
|
219
|
+
| `FILE_SELECTED` | User selected a file |
|
|
220
|
+
| `PARSE_STARTED` | Parsing started |
|
|
221
|
+
| `PARSE_SUCCESS` | Parsing completed |
|
|
222
|
+
| `PARSE_ERROR` | Parsing failed |
|
|
223
|
+
| `GENERATOR_STARTED` | MF email request started |
|
|
224
|
+
| `GENERATOR_SUCCESS` | MF email request sent |
|
|
225
|
+
| `CDSL_FETCH_STARTED` | CDSL fetch started |
|
|
226
|
+
| `CDSL_OTP_SENT` | CDSL OTP sent |
|
|
227
|
+
| `CDSL_FETCH_SUCCESS` | CDSL files retrieved |
|
|
228
|
+
|
|
229
|
+
### Response Data
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
interface ParsedData {
|
|
233
|
+
cas_type: 'CAMS_KFINTECH' | 'CDSL' | 'NSDL';
|
|
234
|
+
status: 'success' | 'failed';
|
|
235
|
+
investor_info?: {
|
|
236
|
+
name: string;
|
|
237
|
+
email?: string;
|
|
238
|
+
pan?: string;
|
|
239
|
+
};
|
|
240
|
+
folios?: [...]; // MF folios
|
|
241
|
+
holdings?: [...]; // Demat holdings
|
|
242
|
+
summary?: {
|
|
243
|
+
total_value: number;
|
|
244
|
+
as_on_date: string;
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Documentation
|
|
250
|
+
|
|
251
|
+
For full documentation, API reference, and examples:
|
|
252
|
+
|
|
253
|
+
📖 **[docs.casparser.in](https://docs.casparser.in)**
|
|
254
|
+
|
|
255
|
+
## Support
|
|
256
|
+
|
|
257
|
+
- 📧 sameer@casparser.in
|
|
258
|
+
- 📖 [docs.casparser.in](https://docs.casparser.in)
|
|
259
|
+
- 🐛 [GitHub Issues](https://github.com/CASParser/cas-connect/issues)
|
|
260
|
+
|
|
261
|
+
## License
|
|
262
|
+
|
|
263
|
+
MIT © [CASParser](https://casparser.in)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface CDSLFetchModeProps {
|
|
3
|
+
prefill?: {
|
|
4
|
+
pan?: string;
|
|
5
|
+
boId?: string;
|
|
6
|
+
dob?: string;
|
|
7
|
+
};
|
|
8
|
+
onRequestOtp: (pan: string, boId: string, dob: string) => Promise<string>;
|
|
9
|
+
onVerifyOtp: (sessionId: string, otp: string, pan: string) => Promise<void>;
|
|
10
|
+
onBack: () => void;
|
|
11
|
+
}
|
|
12
|
+
export declare const CDSLFetchMode: React.FC<CDSLFetchModeProps>;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface FetchModeProps {
|
|
3
|
+
prefill?: {
|
|
4
|
+
pan?: string;
|
|
5
|
+
email?: string;
|
|
6
|
+
};
|
|
7
|
+
onSubmit: (pan: string, email: string) => Promise<void>;
|
|
8
|
+
onBack: () => void;
|
|
9
|
+
isLoading: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare const FetchMode: React.FC<FetchModeProps>;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface ModalProps {
|
|
3
|
+
isOpen: boolean;
|
|
4
|
+
onClose: () => void;
|
|
5
|
+
onBack?: () => void;
|
|
6
|
+
showBackButton?: boolean;
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
width?: number;
|
|
9
|
+
isSandbox?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare const Modal: React.FC<ModalProps>;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { PortfolioConnectConfig, ParsedData, PortfolioConnectEvent, PortfolioConnectError } from '../types';
|
|
3
|
+
interface PortfolioConnectWidgetProps {
|
|
4
|
+
isOpen: boolean;
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
apiKey: string;
|
|
7
|
+
apiBaseUrl?: string;
|
|
8
|
+
config?: PortfolioConnectConfig;
|
|
9
|
+
onSuccess: (data: ParsedData, metadata: any) => void;
|
|
10
|
+
onError?: (error: PortfolioConnectError) => void;
|
|
11
|
+
onEvent?: (event: PortfolioConnectEvent, metadata: any) => void;
|
|
12
|
+
}
|
|
13
|
+
export declare const PortfolioConnectWidget: React.FC<PortfolioConnectWidgetProps>;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { PortfolioConnectConfig, ParsedData, ParseMetadata, PortfolioConnectError } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration for the imperative open() API.
|
|
4
|
+
* Used for non-React environments (Vanilla JS, Angular, Vue, etc.)
|
|
5
|
+
*/
|
|
6
|
+
export interface ImperativeConfig {
|
|
7
|
+
/** Access token for authentication. Get yours at docs.casparser.in */
|
|
8
|
+
accessToken?: string;
|
|
9
|
+
/** @deprecated Use accessToken instead */
|
|
10
|
+
apiKey?: string;
|
|
11
|
+
/** Widget configuration options */
|
|
12
|
+
config?: PortfolioConnectConfig;
|
|
13
|
+
/** Called when widget is opened */
|
|
14
|
+
onOpen?: () => void;
|
|
15
|
+
/** Called for all widget events (useful for analytics) */
|
|
16
|
+
onEvent?: (event: string, metadata: Record<string, any>) => void;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Result returned from the open() promise
|
|
20
|
+
*/
|
|
21
|
+
export interface OpenResult {
|
|
22
|
+
/** Parsed portfolio data */
|
|
23
|
+
data: ParsedData;
|
|
24
|
+
/** Parsing metadata (source, duration, etc.) */
|
|
25
|
+
metadata: ParseMetadata;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Handle returned from create() for manual control
|
|
29
|
+
*/
|
|
30
|
+
export interface WidgetHandle {
|
|
31
|
+
/** Open the widget modal */
|
|
32
|
+
open: () => void;
|
|
33
|
+
/** Close the widget and cleanup */
|
|
34
|
+
destroy: () => void;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Opens the Portfolio Connect widget and returns a promise that resolves with parsed data.
|
|
38
|
+
*
|
|
39
|
+
* This is the recommended API for non-React applications (Vanilla JS, Angular, Vue, etc.)
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```javascript
|
|
43
|
+
* // Vanilla JS
|
|
44
|
+
* document.getElementById('btn').onclick = async () => {
|
|
45
|
+
* try {
|
|
46
|
+
* const { data, metadata } = await PortfolioConnect.open({
|
|
47
|
+
* apiKey: 'your_api_key',
|
|
48
|
+
* config: { enableCdslFetch: true }
|
|
49
|
+
* });
|
|
50
|
+
* console.log('Portfolio data:', data);
|
|
51
|
+
* } catch (error) {
|
|
52
|
+
* if (error.message === 'Widget closed by user') {
|
|
53
|
+
* console.log('User cancelled');
|
|
54
|
+
* } else {
|
|
55
|
+
* console.error('Error:', error);
|
|
56
|
+
* }
|
|
57
|
+
* }
|
|
58
|
+
* };
|
|
59
|
+
* ```
|
|
60
|
+
*
|
|
61
|
+
* @param config - Configuration options
|
|
62
|
+
* @returns Promise that resolves with { data, metadata } on success, rejects on error/close
|
|
63
|
+
*/
|
|
64
|
+
export declare function open(config: ImperativeConfig): Promise<OpenResult>;
|
|
65
|
+
/**
|
|
66
|
+
* Creates a widget handle for manual control.
|
|
67
|
+
* Useful when you need to open/close the widget multiple times.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```javascript
|
|
71
|
+
* const widget = PortfolioConnect.create({
|
|
72
|
+
* apiKey: 'your_api_key',
|
|
73
|
+
* onSuccess: (data) => console.log(data),
|
|
74
|
+
* });
|
|
75
|
+
*
|
|
76
|
+
* document.getElementById('open-btn').onclick = () => widget.open();
|
|
77
|
+
* document.getElementById('close-btn').onclick = () => widget.destroy();
|
|
78
|
+
* ```
|
|
79
|
+
*
|
|
80
|
+
* @param config - Configuration options including callbacks
|
|
81
|
+
* @returns Handle with open() and destroy() methods
|
|
82
|
+
*/
|
|
83
|
+
export declare function create(config: ImperativeConfig & {
|
|
84
|
+
onSuccess: (data: ParsedData, metadata: ParseMetadata) => void;
|
|
85
|
+
onError?: (error: PortfolioConnectError) => void;
|
|
86
|
+
onClose?: () => void;
|
|
87
|
+
}): WidgetHandle;
|