finary-community 0.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/README.md +229 -0
- package/dist/auth/auth-manager.d.ts +12 -0
- package/dist/auth/auth-manager.js +120 -0
- package/dist/auth/login-helper.d.ts +11 -0
- package/dist/auth/login-helper.js +163 -0
- package/dist/client/benchmarks.d.ts +7 -0
- package/dist/client/benchmarks.js +15 -0
- package/dist/client/checkings.d.ts +15 -0
- package/dist/client/checkings.js +46 -0
- package/dist/client/finary-client.d.ts +16 -0
- package/dist/client/finary-client.js +70 -0
- package/dist/client/investments.d.ts +20 -0
- package/dist/client/investments.js +67 -0
- package/dist/client/savings.d.ts +13 -0
- package/dist/client/savings.js +46 -0
- package/dist/greetings.d.ts +2 -0
- package/dist/greetings.js +12 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +25 -0
- package/dist/interfaces/benchmark.d.ts +10 -0
- package/dist/interfaces/benchmark.js +3 -0
- package/dist/interfaces/checking.d.ts +78 -0
- package/dist/interfaces/checking.js +3 -0
- package/dist/interfaces/common.d.ts +15 -0
- package/dist/interfaces/common.js +22 -0
- package/dist/interfaces/distribution.d.ts +9 -0
- package/dist/interfaces/distribution.js +3 -0
- package/dist/interfaces/index.d.ts +22 -0
- package/dist/interfaces/index.js +28 -0
- package/dist/interfaces/investment.d.ts +346 -0
- package/dist/interfaces/investment.js +8 -0
- package/dist/interfaces/organization.d.ts +9 -0
- package/dist/interfaces/organization.js +3 -0
- package/dist/interfaces/savings.d.ts +83 -0
- package/dist/interfaces/savings.js +3 -0
- package/dist/interfaces/timeseries.d.ts +9 -0
- package/dist/interfaces/timeseries.js +3 -0
- package/dist/interfaces/transaction.d.ts +78 -0
- package/dist/interfaces/transaction.js +3 -0
- package/dist/interfaces/user.d.ts +163 -0
- package/dist/interfaces/user.js +3 -0
- package/dist/scripts/setup-credentials.d.ts +1 -0
- package/dist/scripts/setup-credentials.js +38 -0
- package/dist/utils/console-logger.d.ts +6 -0
- package/dist/utils/console-logger.js +16 -0
- package/package.json +34 -0
package/README.md
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# Finary Community Library
|
|
2
|
+
|
|
3
|
+
Une bibliothèque non-officielle et communautaire pour s'interfacer avec l'API Finary. Elle permet de récupérer vos données de patrimoine, transactions, insights et bien plus encore de manière programmatique.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install finary-community
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Configuration & Authentification
|
|
12
|
+
|
|
13
|
+
L'authentification sur Finary étant complexe (protection anti-bot), cette librairie fonctionne actuellement en utilisant une session navigateur existante.
|
|
14
|
+
|
|
15
|
+
Vous devez créer un fichier `credentials.json` à la racine de votre projet.
|
|
16
|
+
Vous pouvez le générer automatiquement en lançant la commande interactive :
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm run setup
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Ou le créer manuellement :
|
|
23
|
+
|
|
24
|
+
### Structure du fichier `credentials.json`
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"token": "JWT_TOKEN_ICI",
|
|
29
|
+
"clerkSession": "CLERK_SESSION_ID_ICI",
|
|
30
|
+
"headers": {
|
|
31
|
+
"user-agent": "Mozilla/5.0 ...",
|
|
32
|
+
"cookie": "..."
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
> **Note :** Le `clerkSession` et les `headers` (cookie) sont essentiels pour permettre le rafraîchissement automatique du token.
|
|
38
|
+
|
|
39
|
+
## API Reference
|
|
40
|
+
|
|
41
|
+
Voici la documentation détaillée de chaque fonction disponible dans la librairie.
|
|
42
|
+
|
|
43
|
+
### Types et Enums Communs
|
|
44
|
+
|
|
45
|
+
Plusieurs fonctions utilisent les énumérations suivantes pour filtrer les données :
|
|
46
|
+
|
|
47
|
+
* **`FinaryPeriod`** : Période temporelle pour les graphiques et variations.
|
|
48
|
+
* `'1d'` (24h), `'1w'` (Semaine), `'1m'` (Mois), `'ytd'` (Depuis début d'année), `'1y'` (1 an), `'all'` (Tout).
|
|
49
|
+
* **`TimeseriesType`** : Type de série temporelle.
|
|
50
|
+
* `'sum'` (Valeur cumulée), `'all'` (Détail).
|
|
51
|
+
* **`DistributionType`** : Type de répartition.
|
|
52
|
+
* `'account'` (Par compte).
|
|
53
|
+
* **`InvestmentDistributionType`** : Type de répartition investissement.
|
|
54
|
+
* `'stock'` (Par action/actif).
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
### 1. Client Principal (`FinaryClient`)
|
|
59
|
+
|
|
60
|
+
Point d'entrée de la librairie.
|
|
61
|
+
|
|
62
|
+
#### `constructor(config)`
|
|
63
|
+
Initialise le client.
|
|
64
|
+
* **Paramètres** :
|
|
65
|
+
* `config` (`AuthConfig`) : Objet de configuration `{ credentialsPath: string }`.
|
|
66
|
+
|
|
67
|
+
#### `getUserProfile()`
|
|
68
|
+
Récupère les informations du profil utilisateur connecté.
|
|
69
|
+
* **Retourne** : `Promise<UserProfile>` (Nom, email, paramètres, etc.)
|
|
70
|
+
|
|
71
|
+
#### `getOrganizations()`
|
|
72
|
+
Liste les organisations (souvent appelées "familles" dans l'UI) associées à l'utilisateur. Vous aurez besoin de l'ID de l'organisation et du membre pour la plupart des autres appels.
|
|
73
|
+
* **Retourne** : `Promise<Organization[]>`
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
### 2. Investissements (`client.investments`)
|
|
78
|
+
|
|
79
|
+
Tous les appels nécessitent généralement `organizationId` et `membershipId`.
|
|
80
|
+
|
|
81
|
+
#### `getPortfolio(organizationId, membershipId, period)`
|
|
82
|
+
Vue d'ensemble du portefeuille d'investissements (Actions, Crypto, Immo, etc.).
|
|
83
|
+
* **Paramètres** :
|
|
84
|
+
* `organizationId` (`string`) : ID de l'organisation.
|
|
85
|
+
* `membershipId` (`string`) : ID du membre.
|
|
86
|
+
* `period` (`FinaryPeriod`, défaut: `YTD`) : Période de calcul des plus/moins-values.
|
|
87
|
+
* **Retourne** : `Promise<InvestmentPortfolio>`
|
|
88
|
+
|
|
89
|
+
#### `getTimeseries(organizationId, membershipId, period, type)`
|
|
90
|
+
Récupère l'historique de la valeur du portefeuille (graphique).
|
|
91
|
+
* **Paramètres** :
|
|
92
|
+
* `period` (`FinaryPeriod`, défaut: `YTD`).
|
|
93
|
+
* `type` (`TimeseriesType`, défaut: `SUM`).
|
|
94
|
+
* **Retourne** : `Promise<Timeseries[]>`
|
|
95
|
+
|
|
96
|
+
#### `getDistribution(organizationId, membershipId, type, period)`
|
|
97
|
+
Répartition des actifs.
|
|
98
|
+
* **Paramètres** :
|
|
99
|
+
* `type` (`InvestmentDistributionType`, défaut: `STOCK`).
|
|
100
|
+
* **Retourne** : `Promise<Distribution>`
|
|
101
|
+
|
|
102
|
+
#### `getDividends(organizationId, membershipId, withRealEstate)`
|
|
103
|
+
Liste les dividendes perçus et à venir.
|
|
104
|
+
* **Paramètres** :
|
|
105
|
+
* `withRealEstate` (`boolean`, défaut: `true`) : Inclure les loyers/dividendes immobiliers (SCPI).
|
|
106
|
+
* **Retourne** : `Promise<DividendsResponse>`
|
|
107
|
+
|
|
108
|
+
#### `getSectorAllocation(organizationId, membershipId)`
|
|
109
|
+
Répartition sectorielle du portefeuille (Technologie, Santé, Finance...).
|
|
110
|
+
* **Retourne** : `Promise<SectorAllocationResponse>`
|
|
111
|
+
|
|
112
|
+
#### `getGeographicalAllocation(organizationId, membershipId)`
|
|
113
|
+
Répartition géographique du portefeuille (USA, Europe, Asie...).
|
|
114
|
+
* **Retourne** : `Promise<GeographicalAllocationResponse>`
|
|
115
|
+
|
|
116
|
+
#### `getFees(organizationId, membershipId)`
|
|
117
|
+
Analyse des frais sur les enveloppes (PEA, CTO, AV...).
|
|
118
|
+
* **Retourne** : `Promise<FeesResponse>`
|
|
119
|
+
|
|
120
|
+
#### `getAccount(organizationId, membershipId, accountId, period)`
|
|
121
|
+
Détails d'un compte spécifique (ex: un PEA particulier).
|
|
122
|
+
* **Paramètres** :
|
|
123
|
+
* `accountId` (`string`) : ID du compte.
|
|
124
|
+
* **Retourne** : `Promise<InvestmentAccount>`
|
|
125
|
+
|
|
126
|
+
#### Méthodes "Account" Spécifiques
|
|
127
|
+
De la même manière que pour le portefeuille global, vous pouvez appeler ces méthodes pour un compte précis :
|
|
128
|
+
* `getAccountTimeseries(orgId, memId, accountId, period, type)`
|
|
129
|
+
* `getAccountDistribution(orgId, memId, accountId, type, period)`
|
|
130
|
+
* `getAccountDividends(orgId, memId, accountId, withRealEstate)`
|
|
131
|
+
* `getAccountSectorAllocation(orgId, memId, accountId)`
|
|
132
|
+
* `getAccountGeographicalAllocation(orgId, memId, accountId)`
|
|
133
|
+
* `getAccountFees(orgId, memId, accountId)`
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
### 3. Épargne (`client.savings`)
|
|
138
|
+
|
|
139
|
+
Concerne les livrets bancaires, fonds euros, etc.
|
|
140
|
+
|
|
141
|
+
#### `getPortfolio(organizationId, membershipId, period)`
|
|
142
|
+
Vue d'ensemble de l'épargne.
|
|
143
|
+
* **Retourne** : `Promise<SavingsPortfolio>`
|
|
144
|
+
|
|
145
|
+
#### `getAccounts(organizationId, membershipId, period)`
|
|
146
|
+
Liste tous les comptes d'épargne.
|
|
147
|
+
* **Retourne** : `Promise<SavingsAccount[]>`
|
|
148
|
+
|
|
149
|
+
#### `getAccount(organizationId, membershipId, accountId, period)`
|
|
150
|
+
Détails d'un compte épargne spécifique.
|
|
151
|
+
* **Retourne** : `Promise<SavingsAccount>`
|
|
152
|
+
|
|
153
|
+
#### `getTransaction(organizationId, membershipId, page, perPage, query, accountId)`
|
|
154
|
+
Récupère les transactions (virements, intérêts).
|
|
155
|
+
* **Paramètres** :
|
|
156
|
+
* `page` (`number`, défaut: `1`) : Numéro de page.
|
|
157
|
+
* `perPage` (`number`, défaut: `50`) : Nombre d'éléments par page.
|
|
158
|
+
* `query` (`string`, optionnel) : Recherche textuelle.
|
|
159
|
+
* `accountId` (`string`, optionnel) : Filtrer par compte spécifique.
|
|
160
|
+
* **Retourne** : `Promise<Transaction[]>`
|
|
161
|
+
|
|
162
|
+
#### `getTimeseries(...)` et `getAccountTimeseries(...)`
|
|
163
|
+
Historique de valeur.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
### 4. Comptes Courants (`client.checkings`)
|
|
168
|
+
|
|
169
|
+
#### `getPortfolio(organizationId, membershipId, period)`
|
|
170
|
+
Solde total des comptes courants.
|
|
171
|
+
* **Retourne** : `Promise<CheckingPortfolio>`
|
|
172
|
+
|
|
173
|
+
#### `getAccounts(organizationId, membershipId, period)`
|
|
174
|
+
Liste des comptes bancaires.
|
|
175
|
+
* **Retourne** : `Promise<CheckingAccount[]>`
|
|
176
|
+
|
|
177
|
+
#### `getTransactions(...)`
|
|
178
|
+
Récupère les transactions bancaires. Fonctionne identiquement à celle de l'épargne.
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
### 5. Benchmarks (`client.benchmarks`)
|
|
183
|
+
|
|
184
|
+
#### `getAvailableAssets(organizationId, membershipId, period)`
|
|
185
|
+
Récupère la liste des actifs disponibles pour faire des comparaisons de performance.
|
|
186
|
+
* **Retourne** : `Promise<BenchmarkAsset[]>`
|
|
187
|
+
|
|
188
|
+
## Exemple Complet
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
import { FinaryClient, FinaryPeriod } from 'finary-community';
|
|
192
|
+
|
|
193
|
+
const client = new FinaryClient({ credentialsPath: './credentials.json' });
|
|
194
|
+
|
|
195
|
+
async function main() {
|
|
196
|
+
// 1. Setup
|
|
197
|
+
const orgs = await client.getOrganizations();
|
|
198
|
+
const orgId = orgs[0].id;
|
|
199
|
+
const memberId = orgs[0].members[0].id;
|
|
200
|
+
|
|
201
|
+
console.log(`Utilisateur : ${orgs[0].name}`);
|
|
202
|
+
|
|
203
|
+
// 2. Investissements
|
|
204
|
+
const investments = await client.investments.getPortfolio(orgId, memberId, FinaryPeriod.YTD);
|
|
205
|
+
console.log(`--- Investissements ---`);
|
|
206
|
+
console.log(`Total : ${investments.total.amount} €`);
|
|
207
|
+
console.log(`Plus-value latente : ${investments.total.unrealized_pnl} €`);
|
|
208
|
+
|
|
209
|
+
// 3. Dividendes à venir
|
|
210
|
+
const dividends = await client.investments.getDividends(orgId, memberId);
|
|
211
|
+
if(dividends.upcoming_dividends.length > 0) {
|
|
212
|
+
console.log(`--- Prochains Dividendes ---`);
|
|
213
|
+
dividends.upcoming_dividends.forEach(div => {
|
|
214
|
+
console.log(`${div.date} : ${div.amount}€ (${div.asset.name})`);
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// 4. Recherche de transactions Livret A
|
|
219
|
+
const savings = await client.savings.getAccounts(orgId, memberId);
|
|
220
|
+
const livretA = savings.find(s => s.name.includes("Livret A"));
|
|
221
|
+
if (livretA) {
|
|
222
|
+
console.log(`--- Transactions Livret A ---`);
|
|
223
|
+
const txs = await client.savings.getTransactions(orgId, memberId, 1, 5, '', livretA.id);
|
|
224
|
+
txs.forEach(t => console.log(`${t.date} : ${t.amount}€ - ${t.description}`));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
main().catch(console.error);
|
|
229
|
+
```
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { AuthConfig, Credentials } from "../interfaces";
|
|
2
|
+
export declare class AuthManager {
|
|
3
|
+
private token;
|
|
4
|
+
private credentialsPath;
|
|
5
|
+
private cachedCredentials;
|
|
6
|
+
constructor(config: AuthConfig);
|
|
7
|
+
private loadCredentials;
|
|
8
|
+
getToken(): Promise<string>;
|
|
9
|
+
getCredentials(): Credentials;
|
|
10
|
+
refreshToken(): Promise<string>;
|
|
11
|
+
private parseJwt;
|
|
12
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AuthManager = void 0;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
class AuthManager {
|
|
6
|
+
constructor(config) {
|
|
7
|
+
this.token = null;
|
|
8
|
+
this.cachedCredentials = null;
|
|
9
|
+
this.credentialsPath = config.credentialsPath;
|
|
10
|
+
}
|
|
11
|
+
loadCredentials() {
|
|
12
|
+
if (this.cachedCredentials)
|
|
13
|
+
return this.cachedCredentials;
|
|
14
|
+
if ((0, node_fs_1.existsSync)(this.credentialsPath)) {
|
|
15
|
+
try {
|
|
16
|
+
const data = (0, node_fs_1.readFileSync)(this.credentialsPath, "utf-8");
|
|
17
|
+
this.cachedCredentials = JSON.parse(data);
|
|
18
|
+
return this.cachedCredentials;
|
|
19
|
+
}
|
|
20
|
+
catch (e) {
|
|
21
|
+
console.error(`Failed to parse credentials at ${this.credentialsPath}: ${e}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
throw new Error(`credentials.json not found at ${this.credentialsPath}`);
|
|
25
|
+
}
|
|
26
|
+
async getToken() {
|
|
27
|
+
if (this.token)
|
|
28
|
+
return this.token;
|
|
29
|
+
const creds = this.loadCredentials();
|
|
30
|
+
if (creds.token) {
|
|
31
|
+
this.token = creds.token;
|
|
32
|
+
return this.token;
|
|
33
|
+
}
|
|
34
|
+
throw new Error("No token found in credentials.");
|
|
35
|
+
}
|
|
36
|
+
getCredentials() {
|
|
37
|
+
return this.loadCredentials();
|
|
38
|
+
}
|
|
39
|
+
async refreshToken() {
|
|
40
|
+
const creds = this.loadCredentials();
|
|
41
|
+
// 1. Clerk Refresh
|
|
42
|
+
if (creds.clerkSession && this.token) {
|
|
43
|
+
try {
|
|
44
|
+
const decoded = this.parseJwt(this.token);
|
|
45
|
+
const sessionId = decoded ? decoded.sid : null;
|
|
46
|
+
if (sessionId) {
|
|
47
|
+
const clerkUrl = `https://clerk.finary.com/v1/client/sessions/${sessionId}/tokens?__clerk_api_version=2025-11-10&_clerk_js_version=5.117.0`;
|
|
48
|
+
const cookieHeader = creds.cookieHeader || `__session=${creds.clerkSession}`;
|
|
49
|
+
const response = await fetch(clerkUrl, {
|
|
50
|
+
method: "POST",
|
|
51
|
+
headers: {
|
|
52
|
+
"Cookie": cookieHeader,
|
|
53
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
54
|
+
"Origin": "https://app.finary.com",
|
|
55
|
+
"Referer": "https://app.finary.com/",
|
|
56
|
+
"User-Agent": creds.headers?.['user-agent'] || "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36"
|
|
57
|
+
},
|
|
58
|
+
body: "organization_id="
|
|
59
|
+
});
|
|
60
|
+
if (response.ok) {
|
|
61
|
+
const data = (await response.json());
|
|
62
|
+
if (data && data.jwt) {
|
|
63
|
+
this.token = data.jwt;
|
|
64
|
+
return this.token;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
console.warn(`Clerk refresh failed: ${response.status}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
catch (e) {
|
|
73
|
+
console.error(`Clerk refresh error: ${e}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// 2. Legacy Refresh
|
|
77
|
+
if (!creds.refreshUrl || !creds.headers) {
|
|
78
|
+
throw new Error("Missing info to refresh token (legacy).");
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
const headers = { ...creds.headers };
|
|
82
|
+
// Cleanup headers manually since we can't use arbitrary types easily on headers object
|
|
83
|
+
delete headers['content-length'];
|
|
84
|
+
delete headers['host'];
|
|
85
|
+
delete headers['connection'];
|
|
86
|
+
delete headers['origin'];
|
|
87
|
+
delete headers['referer'];
|
|
88
|
+
delete headers['cookie'];
|
|
89
|
+
Object.keys(headers).forEach(key => { if (key.startsWith(':'))
|
|
90
|
+
delete headers[key]; });
|
|
91
|
+
const response = await fetch(creds.refreshUrl, {
|
|
92
|
+
method: "POST",
|
|
93
|
+
headers: headers,
|
|
94
|
+
});
|
|
95
|
+
if (!response.ok) {
|
|
96
|
+
throw new Error(`Legacy refresh failed: ${response.status}`);
|
|
97
|
+
}
|
|
98
|
+
const data = (await response.json());
|
|
99
|
+
if (data && data.jwt) {
|
|
100
|
+
this.token = data.jwt;
|
|
101
|
+
return this.token;
|
|
102
|
+
}
|
|
103
|
+
throw new Error("No JWT in refresh response");
|
|
104
|
+
}
|
|
105
|
+
catch (e) {
|
|
106
|
+
console.error(`Token Refresh Error: ${e}`);
|
|
107
|
+
throw e;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
parseJwt(token) {
|
|
111
|
+
try {
|
|
112
|
+
return JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.AuthManager = AuthManager;
|
|
120
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC1tYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2F1dGgvYXV0aC1tYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFDQUFtRDtBQUduRCxNQUFhLFdBQVc7SUFLcEIsWUFBWSxNQUFrQjtRQUp0QixVQUFLLEdBQWtCLElBQUksQ0FBQztRQUU1QixzQkFBaUIsR0FBdUIsSUFBSSxDQUFDO1FBR2pELElBQUksQ0FBQyxlQUFlLEdBQUcsTUFBTSxDQUFDLGVBQWUsQ0FBQztJQUNsRCxDQUFDO0lBRU8sZUFBZTtRQUNuQixJQUFJLElBQUksQ0FBQyxpQkFBaUI7WUFBRSxPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQztRQUUxRCxJQUFJLElBQUEsb0JBQVUsRUFBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQztZQUNuQyxJQUFJLENBQUM7Z0JBQ0QsTUFBTSxJQUFJLEdBQUcsSUFBQSxzQkFBWSxFQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsT0FBTyxDQUFDLENBQUM7Z0JBQ3pELElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBZ0IsQ0FBQztnQkFDekQsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUM7WUFDbEMsQ0FBQztZQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ1QsT0FBTyxDQUFDLEtBQUssQ0FBQyxrQ0FBa0MsSUFBSSxDQUFDLGVBQWUsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2xGLENBQUM7UUFDTCxDQUFDO1FBRUQsTUFBTSxJQUFJLEtBQUssQ0FBQyxpQ0FBaUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDLENBQUM7SUFDN0UsQ0FBQztJQUVNLEtBQUssQ0FBQyxRQUFRO1FBQ2pCLElBQUksSUFBSSxDQUFDLEtBQUs7WUFBRSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7UUFFbEMsTUFBTSxLQUFLLEdBQUcsSUFB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TSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDN0UsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNMLE9BQU8sSUFBSSxDQUFDO1FBQ2hCLENBQUM7SUFDTCxDQUFDO0NBQ0o7QUEvSEQsa0NBK0hDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcmVhZEZpbGVTeW5jLCBleGlzdHNTeW5jIH0gZnJvbSBcIm5vZGU6ZnNcIjtcclxuaW1wb3J0IHsgQXV0aENvbmZpZywgQ3JlZGVudGlhbHMgfSBmcm9tIFwiLi4vaW50ZXJmYWNlc1wiO1xyXG5cclxuZXhwb3J0IGNsYXNzIEF1dGhNYW5hZ2VyIHtcclxuICAgIHByaXZhdGUgdG9rZW46IHN0cmluZyB8IG51bGwgPSBudWxsO1xyXG4gICAgcHJpdmF0ZSBjcmVkZW50aWFsc1BhdGg6IHN0cmluZztcclxuICAgIHByaXZhdGUgY2FjaGVkQ3JlZGVudGlhbHM6IENyZWRlbnRpYWxzIHwgbnVsbCA9IG51bGw7XHJcblxyXG4gICAgY29uc3RydWN0b3IoY29uZmlnOiBBdXRoQ29uZmlnKSB7XHJcbiAgICAgICAgdGhpcy5jcmVkZW50aWFsc1BhdGggPSBjb25maWcuY3JlZGVudGlhbHNQYXRoO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgbG9hZENyZWRlbnRpYWxzKCk6IENyZWRlbnRpYWxzIHtcclxuICAgICAgICBpZiAodGhpcy5jYWNoZWRDcmVkZW50aWFscykgcmV0dXJuIHRoaXMuY2FjaGVkQ3JlZGVudGlhbHM7XHJcblxyXG4gICAgICAgIGlmIChleGlzdHNTeW5jKHRoaXMuY3JlZGVudGlhbHNQYXRoKSkge1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IHJlYWRGaWxlU3luYyh0aGlzLmNyZWRlbnRpYWxzUGF0aCwgXCJ1dGYtOFwiKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuY2FjaGVkQ3JlZGVudGlhbHMgPSBKU09OLnBhcnNlKGRhdGEpIGFzIENyZWRlbnRpYWxzO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2FjaGVkQ3JlZGVudGlhbHM7XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEZhaWxlZCB0byBwYXJzZSBjcmVkZW50aWFscyBhdCAke3RoaXMuY3JlZGVudGlhbHNQYXRofTogJHtlfWApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGNyZWRlbnRpYWxzLmpzb24gbm90IGZvdW5kIGF0ICR7dGhpcy5jcmVkZW50aWFsc1BhdGh9YCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIGdldFRva2VuKCk6IFByb21pc2U8c3RyaW5nPiB7XHJcbiAgICAgICAgaWYgKHRoaXMudG9rZW4pIHJldHVybiB0aGlzLnRva2VuO1xyXG5cclxuICAgICAgICBjb25zdCBjcmVkcyA9IHRoaXMubG9hZENyZWRlbnRpYWxzKCk7XHJcbiAgICAgICAgaWYgKGNyZWRzLnRva2VuKSB7XHJcbiAgICAgICAgICAgIHRoaXMudG9rZW4gPSBjcmVkcy50b2tlbjtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9rZW47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyB0b2tlbiBmb3VuZCBpbiBjcmVkZW50aWFscy5cIik7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldENyZWRlbnRpYWxzKCk6IENyZWRlbnRpYWxzIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5sb2FkQ3JlZGVudGlhbHMoKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgcmVmcmVzaFRva2VuKCk6IFByb21pc2U8c3RyaW5nPiB7XHJcbiAgICAgICAgY29uc3QgY3JlZHMgPSB0aGlzLmxvYWRDcmVkZW50aWFscygpO1xyXG5cclxuICAgICAgICAvLyAxLiBDbGVyayBSZWZyZXNoXHJcbiAgICAgICAgaWYgKGNyZWRzLmNsZXJrU2Vzc2lvbiAmJiB0aGlzLnRva2VuKSB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBkZWNvZGVkID0gdGhpcy5wYXJzZUp3dCh0aGlzLnRva2VuKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHNlc3Npb25JZCA9IGRlY29kZWQgPyBkZWNvZGVkLnNpZCA6IG51bGw7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHNlc3Npb25JZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNsZXJrVXJsID0gYGh0dHBzOi8vY2xlcmsuZmluYXJ5LmNvbS92MS9jbGllbnQvc2Vzc2lvbnMvJHtzZXNzaW9uSWR9L3Rva2Vucz9fX2NsZXJrX2FwaV92ZXJzaW9uPTIwMjUtMTEtMTAmX2NsZXJrX2pzX3ZlcnNpb249NS4xMTcuMGA7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29va2llSGVhZGVyID0gY3JlZHMuY29va2llSGVhZGVyIHx8IGBfX3Nlc3Npb249JHtjcmVkcy5jbGVya1Nlc3Npb259YDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChjbGVya1VybCwge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q6IFwiUE9TVFwiLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBoZWFkZXJzOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIkNvb2tpZVwiOiBjb29raWVIZWFkZXIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFwiLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJPcmlnaW5cIjogXCJodHRwczovL2FwcC5maW5hcnkuY29tXCIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIlJlZmVyZXJcIjogXCJodHRwczovL2FwcC5maW5hcnkuY29tL1wiLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJVc2VyLUFnZW50XCI6IGNyZWRzLmhlYWRlcnM/LlsndXNlci1hZ2VudCddIHx8IFwiTW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NCkgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzE0My4wLjAuMCBTYWZhcmkvNTM3LjM2XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgYm9keTogXCJvcmdhbml6YXRpb25faWQ9XCJcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLm9rKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgPSAoYXdhaXQgcmVzcG9uc2UuanNvbigpKSBhcyBhbnk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkYXRhICYmIGRhdGEuand0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRva2VuID0gZGF0YS5qd3Q7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50b2tlbiBhcyBzdHJpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYENsZXJrIHJlZnJlc2ggZmFpbGVkOiAke3Jlc3BvbnNlLnN0YXR1c31gKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYENsZXJrIHJlZnJlc2ggZXJyb3I6ICR7ZX1gKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gMi4gTGVnYWN5IFJlZnJlc2hcclxuICAgICAgICBpZiAoIWNyZWRzLnJlZnJlc2hVcmwgfHwgIWNyZWRzLmhlYWRlcnMpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBpbmZvIHRvIHJlZnJlc2ggdG9rZW4gKGxlZ2FjeSkuXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgY29uc3QgaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHsgLi4uY3JlZHMuaGVhZGVycyB9O1xyXG4gICAgICAgICAgICAvLyBDbGVhbnVwIGhlYWRlcnMgbWFudWFsbHkgc2luY2Ugd2UgY2FuJ3QgdXNlIGFyYml0cmFyeSB0eXBlcyBlYXNpbHkgb24gaGVhZGVycyBvYmplY3RcclxuICAgICAgICAgICAgZGVsZXRlIGhlYWRlcnNbJ2NvbnRlbnQtbGVuZ3RoJ107XHJcbiAgICAgICAgICAgIGRlbGV0ZSBoZWFkZXJzWydob3N0J107XHJcbiAgICAgICAgICAgIGRlbGV0ZSBoZWFkZXJzWydjb25uZWN0aW9uJ107XHJcbiAgICAgICAgICAgIGRlbGV0ZSBoZWFkZXJzWydvcmlnaW4nXTtcclxuICAgICAgICAgICAgZGVsZXRlIGhlYWRlcnNbJ3JlZmVyZXInXTtcclxuICAgICAgICAgICAgZGVsZXRlIGhlYWRlcnNbJ2Nvb2tpZSddO1xyXG5cclxuICAgICAgICAgICAgT2JqZWN0LmtleXMoaGVhZGVycykuZm9yRWFjaChrZXkgPT4geyBpZiAoa2V5LnN0YXJ0c1dpdGgoJzonKSkgZGVsZXRlIGhlYWRlcnNba2V5XTsgfSk7XHJcblxyXG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGNyZWRzLnJlZnJlc2hVcmwsIHtcclxuICAgICAgICAgICAgICAgIG1ldGhvZDogXCJQT1NUXCIsXHJcbiAgICAgICAgICAgICAgICBoZWFkZXJzOiBoZWFkZXJzLFxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIGlmICghcmVzcG9uc2Uub2spIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgTGVnYWN5IHJlZnJlc2ggZmFpbGVkOiAke3Jlc3BvbnNlLnN0YXR1c31gKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgZGF0YSA9IChhd2FpdCByZXNwb25zZS5qc29uKCkpIGFzIGFueTtcclxuICAgICAgICAgICAgaWYgKGRhdGEgJiYgZGF0YS5qd3QpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMudG9rZW4gPSBkYXRhLmp3dDtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRva2VuIGFzIHN0cmluZztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBKV1QgaW4gcmVmcmVzaCByZXNwb25zZVwiKTtcclxuXHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBUb2tlbiBSZWZyZXNoIEVycm9yOiAke2V9YCk7XHJcbiAgICAgICAgICAgIHRocm93IGU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgcGFyc2VKd3QodG9rZW46IHN0cmluZyk6IGFueSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UoQnVmZmVyLmZyb20odG9rZW4uc3BsaXQoJy4nKVsxXSwgJ2Jhc2U2NCcpLnRvU3RyaW5nKCkpO1xyXG4gICAgICAgIH0gY2F0Y2gge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIl19
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface CreateSessionOptions {
|
|
2
|
+
headless?: boolean;
|
|
3
|
+
outputPath?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function createSession(options?: CreateSessionOptions): Promise<{
|
|
6
|
+
token: string;
|
|
7
|
+
refreshUrl: string;
|
|
8
|
+
headers: Record<string, string>;
|
|
9
|
+
clerkSession: string | null;
|
|
10
|
+
cookieHeader: string;
|
|
11
|
+
}>;
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createSession = createSession;
|
|
7
|
+
const puppeteer_1 = __importDefault(require("puppeteer"));
|
|
8
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
async function createSession(options = {}) {
|
|
11
|
+
const { headless = false, outputPath } = options;
|
|
12
|
+
console.log("------------------------------------------");
|
|
13
|
+
console.log(" Finary Setup - Browser Login");
|
|
14
|
+
console.log("------------------------------------------");
|
|
15
|
+
if (outputPath) {
|
|
16
|
+
// Ensure directory exists
|
|
17
|
+
const dir = node_path_1.default.dirname(outputPath);
|
|
18
|
+
if (!node_fs_1.default.existsSync(dir)) {
|
|
19
|
+
try {
|
|
20
|
+
node_fs_1.default.mkdirSync(dir, { recursive: true });
|
|
21
|
+
}
|
|
22
|
+
catch (e) {
|
|
23
|
+
throw new Error(`Error creating directory ${dir}: ${e.message}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
console.log(`Will save to: ${outputPath}`);
|
|
27
|
+
}
|
|
28
|
+
console.log("Launching browser for authentication...");
|
|
29
|
+
let browser;
|
|
30
|
+
try {
|
|
31
|
+
browser = await puppeteer_1.default.launch({
|
|
32
|
+
headless: headless,
|
|
33
|
+
defaultViewport: null,
|
|
34
|
+
args: ['--start-maximized'] // Find browser window easier
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
catch (e) {
|
|
38
|
+
console.error("Failed to launch browser. Make sure you installed puppeteer: npm install puppeteer");
|
|
39
|
+
throw e;
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
const page = await browser.newPage();
|
|
43
|
+
await page.setRequestInterception(false); // Ensure interception does not block unless intended
|
|
44
|
+
page.on('request', request => {
|
|
45
|
+
const url = request.url();
|
|
46
|
+
if (url.includes('clerk.finary.com')) {
|
|
47
|
+
// Optional: log or handle clerk requests
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
console.log("Navigating to Finary login page...");
|
|
51
|
+
await page.goto('https://app.finary.com/v2', { waitUntil: 'domcontentloaded' });
|
|
52
|
+
console.log("\nACTION REQUIRED: Please log in to your Finary account in the opened browser window.\n");
|
|
53
|
+
console.log("Scanning network traffic for authentication token...");
|
|
54
|
+
// Promise that resolves when the valid token is found
|
|
55
|
+
const waitForToken = new Promise((resolve) => {
|
|
56
|
+
page.on('response', response => {
|
|
57
|
+
const request = response.request();
|
|
58
|
+
const url = request.url();
|
|
59
|
+
// Filter API requests
|
|
60
|
+
if (url.includes('api.finary.com') || url.includes('clerk.finary.com')) {
|
|
61
|
+
// We only want successful requests to ensure the token is valid
|
|
62
|
+
if (response.status() === 200) {
|
|
63
|
+
const headers = request.headers();
|
|
64
|
+
const auth = headers['authorization'];
|
|
65
|
+
if (auth && auth.startsWith('Bearer ey')) {
|
|
66
|
+
const token = auth.replace('Bearer ', '');
|
|
67
|
+
console.log("✅ Valid token successfully detected from successful request!");
|
|
68
|
+
resolve({ token, headers });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
const { token, headers } = await waitForToken;
|
|
75
|
+
console.log("Token detected! capturing cookies...");
|
|
76
|
+
// Capture cookies for both the main app and the clerk subdomain to ensure we get __client, __session, etc.
|
|
77
|
+
const cookies = await page.cookies('https://app.finary.com', 'https://clerk.finary.com');
|
|
78
|
+
const cookieHeader = cookies.map(c => `${c.name}=${c.value}`).join('; ');
|
|
79
|
+
const sessionCookie = cookies.find(c => c.name === '__session');
|
|
80
|
+
const clerkSession = sessionCookie ? sessionCookie.value : null;
|
|
81
|
+
if (cookieHeader) {
|
|
82
|
+
console.log("✅ Cookies captured!");
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
console.warn("⚠️ No cookies found. Refresh verify might fail.");
|
|
86
|
+
}
|
|
87
|
+
console.log("Fetching user details...");
|
|
88
|
+
// Use the token to identify the user
|
|
89
|
+
let email = "unknown_user@example.com";
|
|
90
|
+
try {
|
|
91
|
+
const meResp = await fetch("https://api.finary.com/users/me", {
|
|
92
|
+
headers: {
|
|
93
|
+
"Authorization": `Bearer ${token}`,
|
|
94
|
+
"User-Agent": "Mozilla/5.0"
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
if (meResp.ok) {
|
|
98
|
+
const data = await meResp.json();
|
|
99
|
+
if (data.result && data.result.email) {
|
|
100
|
+
email = data.result.email;
|
|
101
|
+
console.log(`Identified as: ${email}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch (e) {
|
|
106
|
+
console.warn("Could not fetch user email (minor issue), proceeding anyway.");
|
|
107
|
+
}
|
|
108
|
+
// Filter headers based on user request ("only these specific headers")
|
|
109
|
+
const allowedHeaderKeys = [
|
|
110
|
+
"sec-ch-ua-platform",
|
|
111
|
+
"x-client-api-version",
|
|
112
|
+
"referer",
|
|
113
|
+
"accept-language",
|
|
114
|
+
"sec-ch-ua",
|
|
115
|
+
"sec-ch-ua-mobile",
|
|
116
|
+
"user-agent",
|
|
117
|
+
"x-finary-client-id",
|
|
118
|
+
":authority",
|
|
119
|
+
":method",
|
|
120
|
+
":scheme",
|
|
121
|
+
"accept",
|
|
122
|
+
"accept-encoding",
|
|
123
|
+
"origin",
|
|
124
|
+
"priority",
|
|
125
|
+
"sec-fetch-dest",
|
|
126
|
+
"sec-fetch-mode",
|
|
127
|
+
"sec-fetch-site"
|
|
128
|
+
];
|
|
129
|
+
const filteredHeaders = {};
|
|
130
|
+
for (const key of allowedHeaderKeys) {
|
|
131
|
+
if (headers[key]) {
|
|
132
|
+
filteredHeaders[key] = headers[key];
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const credentialsData = {
|
|
136
|
+
token: token,
|
|
137
|
+
refreshUrl: "https://clerk.finary.com/v1/client/sessions",
|
|
138
|
+
headers: filteredHeaders,
|
|
139
|
+
clerkSession: clerkSession, // Kept for backward compatibility
|
|
140
|
+
cookieHeader: cookieHeader,
|
|
141
|
+
};
|
|
142
|
+
if (outputPath) {
|
|
143
|
+
const jsonContent = JSON.stringify(credentialsData, null, 4);
|
|
144
|
+
try {
|
|
145
|
+
node_fs_1.default.writeFileSync(outputPath, jsonContent);
|
|
146
|
+
console.log(`[OK] Saved credentials to: ${outputPath}`);
|
|
147
|
+
}
|
|
148
|
+
catch (e) {
|
|
149
|
+
console.error(`[ERR] Failed to save to ${outputPath}: ${e.message}`);
|
|
150
|
+
throw e;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
console.log("\n------------------------------------------");
|
|
154
|
+
console.log("SUCCESS! Setup complete.");
|
|
155
|
+
console.log("------------------------------------------");
|
|
156
|
+
return credentialsData;
|
|
157
|
+
}
|
|
158
|
+
finally {
|
|
159
|
+
if (browser)
|
|
160
|
+
await browser.close();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9naW4taGVscGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2F1dGgvbG9naW4taGVscGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBU0Esc0NBMEtDO0FBbkxELDBEQUFrQztBQUNsQyxzREFBeUI7QUFDekIsMERBQTZCO0FBT3RCLEtBQUssVUFBVSxhQUFhLENBQUMsVUFBZ0MsRUFBRTtJQUNsRSxNQUFNLEVBQUUsUUFBUSxHQUFHLEtBQUssRUFBRSxVQUFVLEVBQUUsR0FBRyxPQUFPLENBQUM7SUFFakQsT0FBTyxDQUFDLEdBQUcsQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFDO0lBQzFELE9BQU8sQ0FBQyxHQUFHLENBQUMsaUNBQWlDLENBQUMsQ0FBQztJQUMvQyxPQUFPLENBQUMsR0FBRyxDQUFDLDRDQUE0QyxDQUFDLENBQUM7SUFFMUQsSUFBSSxVQUFVLEVBQUUsQ0FBQztRQUNiLDBCQUEwQjtRQUMxQixNQUFNLEdBQUcsR0FBRyxtQkFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNyQyxJQUFJLENBQUMsaUJBQUUsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN0QixJQUFJLENBQUM7Z0JBQ0QsaUJBQUUsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7WUFDM0MsQ0FBQztZQUFDLE9BQU8sQ0FBTSxFQUFFLENBQUM7Z0JBQ2QsTUFBTSxJQUFJLEtBQUssQ0FBQyw0QkFBNEIsR0FBRyxLQUFLLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1lBQ3JFLENBQUM7UUFDTCxDQUFDO1FBQ0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsVUFBVSxFQUFFLENBQUMsQ0FBQztJQUMvQyxDQUFDO0lBRUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFDO0lBRXZELElBQUksT0FBTyxDQUFD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TyxDQUFDLEdBQUcsQ0FBQyw4QkFBOEIsVUFBVSxFQUFFLENBQUMsQ0FBQztZQUM1RCxDQUFDO1lBQUMsT0FBTyxDQUFNLEVBQUUsQ0FBQztnQkFDZCxPQUFPLENBQUMsS0FBSyxDQUFDLDJCQUEyQixVQUFVLEtBQUssQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7Z0JBQ3JFLE1BQU0sQ0FBQyxDQUFDO1lBQ1osQ0FBQztRQUNMLENBQUM7UUFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLDhDQUE4QyxDQUFDLENBQUM7UUFDNUQsT0FBTyxDQUFDLEdBQUcsQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBQ3hDLE9BQU8sQ0FBQyxHQUFHLENBQUMsNENBQTRDLENBQUMsQ0FBQztRQUUxRCxPQUFPLGVBQWUsQ0FBQztJQUUzQixDQUFDO1lBQVMsQ0FBQztRQUNQLElBQUksT0FBTztZQUFFLE1BQU0sT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3ZDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHB1cHBldGVlciBmcm9tICdwdXBwZXRlZXInO1xyXG5pbXBvcnQgZnMgZnJvbSAnbm9kZTpmcyc7XHJcbmltcG9ydCBwYXRoIGZyb20gJ25vZGU6cGF0aCc7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIENyZWF0ZVNlc3Npb25PcHRpb25zIHtcclxuICAgIGhlYWRsZXNzPzogYm9vbGVhbjtcclxuICAgIG91dHB1dFBhdGg/OiBzdHJpbmc7XHJcbn1cclxuXHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGVTZXNzaW9uKG9wdGlvbnM6IENyZWF0ZVNlc3Npb25PcHRpb25zID0ge30pIHtcclxuICAgIGNvbnN0IHsgaGVhZGxlc3MgPSBmYWxzZSwgb3V0cHV0UGF0aCB9ID0gb3B0aW9ucztcclxuXHJcbiAgICBjb25zb2xlLmxvZyhcIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVwiKTtcclxuICAgIGNvbnNvbGUubG9nKFwiICAgRmluYXJ5IFNldHVwIC0gQnJvd3NlciBMb2dpblwiKTtcclxuICAgIGNvbnNvbGUubG9nKFwiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXCIpO1xyXG5cclxuICAgIGlmIChvdXRwdXRQYXRoKSB7XHJcbiAgICAgICAgLy8gRW5zdXJlIGRpcmVjdG9yeSBleGlzdHNcclxuICAgICAgICBjb25zdCBkaXIgPSBwYXRoLmRpcm5hbWUob3V0cHV0UGF0aCk7XHJcbiAgICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGRpcikpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIGZzLm1rZGlyU3luYyhkaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xyXG4gICAgICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRXJyb3IgY3JlYXRpbmcgZGlyZWN0b3J5ICR7ZGlyfTogJHtlLm1lc3NhZ2V9YCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc29sZS5sb2coYFdpbGwgc2F2ZSB0bzogJHtvdXRwdXRQYXRofWApO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnNvbGUubG9nKFwiTGF1bmNoaW5nIGJyb3dzZXIgZm9yIGF1dGhlbnRpY2F0aW9uLi4uXCIpO1xyXG5cclxuICAgIGxldCBicm93c2VyO1xyXG4gICAgdHJ5IHtcclxuICAgICAgICBicm93c2VyID0gYXdhaXQgcHVwcGV0ZWVyLmxhdW5jaCh7XHJcbiAgICAgICAgICAgIGhlYWRsZXNzOiBoZWFkbGVzcyxcclxuICAgICAgICAgICAgZGVmYXVsdFZpZXdwb3J0OiBudWxsLFxyXG4gICAgICAgICAgICBhcmdzOiBbJy0tc3RhcnQtbWF4aW1pemVkJ10gLy8gRmluZCBicm93c2VyIHdpbmRvdyBlYXNpZXJcclxuICAgICAgICB9KTtcclxuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXCJGYWlsZWQgdG8gbGF1bmNoIGJyb3dzZXIuIE1ha2Ugc3VyZSB5b3UgaW5zdGFsbGVkIHB1cHBldGVlcjogbnBtIGluc3RhbGwgcHVwcGV0ZWVyXCIpO1xyXG4gICAgICAgIHRocm93IGU7XHJcbiAgICB9XHJcblxyXG4gICAgdHJ5IHtcclxuICAgICAgICBjb25zdCBwYWdlID0gYXdhaXQgYnJvd3Nlci5uZXdQYWdlKCk7XHJcblxyXG4gICAgICAgIGF3YWl0IHBhZ2Uuc2V0UmVxdWVzdEludGVyY2VwdGlvbihmYWxzZSk7IC8vIEVuc3VyZSBpbnRlcmNlcHRpb24gZG9lcyBub3QgYmxvY2sgdW5sZXNzIGludGVuZGVkXHJcbiAgICAgICAgcGFnZS5vbigncmVxdWVzdCcsIHJlcXVlc3QgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCB1cmwgPSByZXF1ZXN0LnVybCgpO1xyXG4gICAgICAgICAgICBpZiAodXJsLmluY2x1ZGVzKCdjbGVyay5maW5hcnkuY29tJykpIHtcclxuICAgICAgICAgICAgICAgIC8vIE9wdGlvbmFsOiBsb2cgb3IgaGFuZGxlIGNsZXJrIHJlcXVlc3RzXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgY29uc29sZS5sb2coXCJOYXZpZ2F0aW5nIHRvIEZpbmFyeSBsb2dpbiBwYWdlLi4uXCIpO1xyXG4gICAgICAgIGF3YWl0IHBhZ2UuZ290bygnaHR0cHM6Ly9hcHAuZmluYXJ5LmNvbS92MicsIHsgd2FpdFVudGlsOiAnZG9tY29udGVudGxvYWRlZCcgfSk7XHJcblxyXG4gICAgICAgIGNvbnNvbGUubG9nKFwiXFxuQUNUSU9OIFJFUVVJUkVEOiBQbGVhc2UgbG9nIGluIHRvIHlvdXIgRmluYXJ5IGFjY291bnQgaW4gdGhlIG9wZW5lZCBicm93c2VyIHdpbmRvdy5cXG5cIik7XHJcbiAgICAgICAgY29uc29sZS5sb2coXCJTY2FubmluZyBuZXR3b3JrIHRyYWZmaWMgZm9yIGF1dGhlbnRpY2F0aW9uIHRva2VuLi4uXCIpO1xyXG5cclxuICAgICAgICAvLyBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgdmFsaWQgdG9rZW4gaXMgZm91bmRcclxuICAgICAgICBjb25zdCB3YWl0Rm9yVG9rZW4gPSBuZXcgUHJvbWlzZTx7IHRva2VuOiBzdHJpbmcsIGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gfT4oKHJlc29sdmUpID0+IHtcclxuICAgICAgICAgICAgcGFnZS5vbigncmVzcG9uc2UnLCByZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByZXF1ZXN0ID0gcmVzcG9uc2UucmVxdWVzdCgpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdXJsID0gcmVxdWVzdC51cmwoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBGaWx0ZXIgQVBJIHJlcXVlc3RzXHJcbiAgICAgICAgICAgICAgICBpZiAodXJsLmluY2x1ZGVzKCdhcGkuZmluYXJ5LmNvbScpIHx8IHVybC5pbmNsdWRlcygnY2xlcmsuZmluYXJ5LmNvbScpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gV2Ugb25seSB3YW50IHN1Y2Nlc3NmdWwgcmVxdWVzdHMgdG8gZW5zdXJlIHRoZSB0b2tlbiBpcyB2YWxpZFxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZS5zdGF0dXMoKSA9PT0gMjAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGhlYWRlcnMgPSByZXF1ZXN0LmhlYWRlcnMoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYXV0aCA9IGhlYWRlcnNbJ2F1dGhvcml6YXRpb24nXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdXRoICYmIGF1dGguc3RhcnRzV2l0aCgnQmVhcmVyIGV5JykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRva2VuID0gYXV0aC5yZXBsYWNlKCdCZWFyZXIgJywgJycpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCLinIUgVmFsaWQgdG9rZW4gc3VjY2Vzc2Z1bGx5IGRldGVjdGVkIGZyb20gc3VjY2Vzc2Z1bCByZXF1ZXN0IVwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoeyB0b2tlbiwgaGVhZGVycyB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGNvbnN0IHsgdG9rZW4sIGhlYWRlcnMgfSA9IGF3YWl0IHdhaXRGb3JUb2tlbjtcclxuXHJcbiAgICAgICAgY29uc29sZS5sb2coXCJUb2tlbiBkZXRlY3RlZCEgY2FwdHVyaW5nIGNvb2tpZXMuLi5cIik7XHJcbiAgICAgICAgLy8gQ2FwdHVyZSBjb29raWVzIGZvciBib3RoIHRoZSBtYWluIGFwcCBhbmQgdGhlIGNsZXJrIHN1YmRvbWFpbiB0byBlbnN1cmUgd2UgZ2V0IF9fY2xpZW50LCBfX3Nlc3Npb24sIGV0Yy5cclxuICAgICAgICBjb25zdCBjb29raWVzID0gYXdhaXQgcGFnZS5jb29raWVzKCdodHRwczovL2FwcC5maW5hcnkuY29tJywgJ2h0dHBzOi8vY2xlcmsuZmluYXJ5LmNvbScpO1xyXG4gICAgICAgIGNvbnN0IGNvb2tpZUhlYWRlciA9IGNvb2tpZXMubWFwKGMgPT4gYCR7Yy5uYW1lfT0ke2MudmFsdWV9YCkuam9pbignOyAnKTtcclxuXHJcbiAgICAgICAgY29uc3Qgc2Vzc2lvbkNvb2tpZSA9IGNvb2tpZXMuZmluZChjID0+IGMubmFtZSA9PT0gJ19fc2Vzc2lvbicpO1xyXG4gICAgICAgIGNvbnN0IGNsZXJrU2Vzc2lvbiA9IHNlc3Npb25Db29raWUgPyBzZXNzaW9uQ29va2llLnZhbHVlIDogbnVsbDtcclxuXHJcbiAgICAgICAgaWYgKGNvb2tpZUhlYWRlcikge1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcIuKchSBDb29raWVzIGNhcHR1cmVkIVwiKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oXCLimqDvuI8gTm8gY29va2llcyBmb3VuZC4gUmVmcmVzaCB2ZXJpZnkgbWlnaHQgZmFpbC5cIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zb2xlLmxvZyhcIkZldGNoaW5nIHVzZXIgZGV0YWlscy4uLlwiKTtcclxuXHJcbiAgICAgICAgLy8gVXNlIHRoZSB0b2tlbiB0byBpZGVudGlmeSB0aGUgdXNlclxyXG4gICAgICAgIGxldCBlbWFpbCA9IFwidW5rbm93bl91c2VyQGV4YW1wbGUuY29tXCI7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgY29uc3QgbWVSZXNwID0gYXdhaXQgZmV0Y2goXCJodHRwczovL2FwaS5maW5hcnkuY29tL3VzZXJzL21lXCIsIHtcclxuICAgICAgICAgICAgICAgIGhlYWRlcnM6IHtcclxuICAgICAgICAgICAgICAgICAgICBcIkF1dGhvcml6YXRpb25cIjogYEJlYXJlciAke3Rva2VufWAsXHJcbiAgICAgICAgICAgICAgICAgICAgXCJVc2VyLUFnZW50XCI6IFwiTW96aWxsYS81LjBcIlxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIGlmIChtZVJlc3Aub2spIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBtZVJlc3AuanNvbigpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGRhdGEucmVzdWx0ICYmIGRhdGEucmVzdWx0LmVtYWlsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZW1haWwgPSBkYXRhLnJlc3VsdC5lbWFpbDtcclxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgSWRlbnRpZmllZCBhczogJHtlbWFpbH1gKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oXCJDb3VsZCBub3QgZmV0Y2ggdXNlciBlbWFpbCAobWlub3IgaXNzdWUpLCBwcm9jZWVkaW5nIGFueXdheS5cIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBGaWx0ZXIgaGVhZGVycyBiYXNlZCBvbiB1c2VyIHJlcXVlc3QgKFwib25seSB0aGVzZSBzcGVjaWZpYyBoZWFkZXJzXCIpXHJcbiAgICAgICAgY29uc3QgYWxsb3dlZEhlYWRlcktleXMgPSBbXHJcbiAgICAgICAgICAgIFwic2VjLWNoLXVhLXBsYXRmb3JtXCIsXHJcbiAgICAgICAgICAgIFwieC1jbGllbnQtYXBpLXZlcnNpb25cIixcclxuICAgICAgICAgICAgXCJyZWZlcmVyXCIsXHJcbiAgICAgICAgICAgIFwiYWNjZXB0LWxhbmd1YWdlXCIsXHJcbiAgICAgICAgICAgIFwic2VjLWNoLXVhXCIsXHJcbiAgICAgICAgICAgIFwic2VjLWNoLXVhLW1vYmlsZVwiLFxyXG4gICAgICAgICAgICBcInVzZXItYWdlbnRcIixcclxuICAgICAgICAgICAgXCJ4LWZpbmFyeS1jbGllbnQtaWRcIixcclxuICAgICAgICAgICAgXCI6YXV0aG9yaXR5XCIsXHJcbiAgICAgICAgICAgIFwiOm1ldGhvZFwiLFxyXG4gICAgICAgICAgICBcIjpzY2hlbWVcIixcclxuICAgICAgICAgICAgXCJhY2NlcHRcIixcclxuICAgICAgICAgICAgXCJhY2NlcHQtZW5jb2RpbmdcIixcclxuICAgICAgICAgICAgXCJvcmlnaW5cIixcclxuICAgICAgICAgICAgXCJwcmlvcml0eVwiLFxyXG4gICAgICAgICAgICBcInNlYy1mZXRjaC1kZXN0XCIsXHJcbiAgICAgICAgICAgIFwic2VjLWZldGNoLW1vZGVcIixcclxuICAgICAgICAgICAgXCJzZWMtZmV0Y2gtc2l0ZVwiXHJcbiAgICAgICAgXTtcclxuXHJcbiAgICAgICAgY29uc3QgZmlsdGVyZWRIZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XHJcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgYWxsb3dlZEhlYWRlcktleXMpIHtcclxuICAgICAgICAgICAgaWYgKGhlYWRlcnNba2V5XSkge1xyXG4gICAgICAgICAgICAgICAgZmlsdGVyZWRIZWFkZXJzW2tleV0gPSBoZWFkZXJzW2tleV07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGNyZWRlbnRpYWxzRGF0YSA9IHtcclxuICAgICAgICAgICAgdG9rZW46IHRva2VuLFxyXG4gICAgICAgICAgICByZWZyZXNoVXJsOiBcImh0dHBzOi8vY2xlcmsuZmluYXJ5LmNvbS92MS9jbGllbnQvc2Vzc2lvbnNcIixcclxuICAgICAgICAgICAgaGVhZGVyczogZmlsdGVyZWRIZWFkZXJzLFxyXG4gICAgICAgICAgICBjbGVya1Nlc3Npb246IGNsZXJrU2Vzc2lvbiwgLy8gS2VwdCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eVxyXG4gICAgICAgICAgICBjb29raWVIZWFkZXI6IGNvb2tpZUhlYWRlcixcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBpZiAob3V0cHV0UGF0aCkge1xyXG4gICAgICAgICAgICBjb25zdCBqc29uQ29udGVudCA9IEpTT04uc3RyaW5naWZ5KGNyZWRlbnRpYWxzRGF0YSwgbnVsbCwgNCk7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBmcy53cml0ZUZpbGVTeW5jKG91dHB1dFBhdGgsIGpzb25Db250ZW50KTtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBbT0tdIFNhdmVkIGNyZWRlbnRpYWxzIHRvOiAke291dHB1dFBhdGh9YCk7XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgW0VSUl0gRmFpbGVkIHRvIHNhdmUgdG8gJHtvdXRwdXRQYXRofTogJHtlLm1lc3NhZ2V9YCk7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zb2xlLmxvZyhcIlxcbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVwiKTtcclxuICAgICAgICBjb25zb2xlLmxvZyhcIlNVQ0NFU1MhIFNldHVwIGNvbXBsZXRlLlwiKTtcclxuICAgICAgICBjb25zb2xlLmxvZyhcIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVwiKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGNyZWRlbnRpYWxzRGF0YTtcclxuXHJcbiAgICB9IGZpbmFsbHkge1xyXG4gICAgICAgIGlmIChicm93c2VyKSBhd2FpdCBicm93c2VyLmNsb3NlKCk7XHJcbiAgICB9XHJcbn1cclxuIl19
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { BenchmarkAsset, FinaryPeriod } from "../interfaces";
|
|
2
|
+
import { RequestHandler } from "./checkings";
|
|
3
|
+
export declare class BenchmarkClient {
|
|
4
|
+
private requestHandler;
|
|
5
|
+
constructor(requestHandler: RequestHandler);
|
|
6
|
+
getAvailableAssets(organizationId: string, membershipId: string, period?: FinaryPeriod): Promise<BenchmarkAsset[]>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BenchmarkClient = void 0;
|
|
4
|
+
const interfaces_1 = require("../interfaces");
|
|
5
|
+
class BenchmarkClient {
|
|
6
|
+
constructor(requestHandler) {
|
|
7
|
+
this.requestHandler = requestHandler;
|
|
8
|
+
}
|
|
9
|
+
async getAvailableAssets(organizationId, membershipId, period = interfaces_1.FinaryPeriod.YTD) {
|
|
10
|
+
const response = await this.requestHandler.authenticatedRequest(`/organizations/${organizationId}/memberships/${membershipId}/benchmarks/available_assets?period=${period}`);
|
|
11
|
+
return response.result;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.BenchmarkClient = BenchmarkClient;
|
|
15
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmVuY2htYXJrcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGllbnQvYmVuY2htYXJrcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw4Q0FBNkU7QUFHN0UsTUFBYSxlQUFlO0lBQ3hCLFlBQW9CLGNBQThCO1FBQTlCLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtJQUFJLENBQUM7SUFFaEQsS0FBSyxDQUFDLGtCQUFrQixDQUFDLGNBQXNCLEVBQUUsWUFBb0IsRUFBRSxTQUF1Qix5QkFBWSxDQUFDLEdBQUc7UUFDakgsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUFDLG9CQUFvQixDQUMzRCxrQkFBa0IsY0FBYyxnQkFBZ0IsWUFBWSx1Q0FBdUMsTUFBTSxFQUFFLENBQzlHLENBQUM7UUFDRixPQUFPLFFBQVEsQ0FBQyxNQUFNLENBQUM7SUFDM0IsQ0FBQztDQUNKO0FBVEQsMENBU0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBGaW5hcnlSZXNwb25zZSwgQmVuY2htYXJrQXNzZXQsIEZpbmFyeVBlcmlvZCB9IGZyb20gXCIuLi9pbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB7IFJlcXVlc3RIYW5kbGVyIH0gZnJvbSBcIi4vY2hlY2tpbmdzXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgQmVuY2htYXJrQ2xpZW50IHtcclxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVxdWVzdEhhbmRsZXI6IFJlcXVlc3RIYW5kbGVyKSB7IH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgZ2V0QXZhaWxhYmxlQXNzZXRzKG9yZ2FuaXphdGlvbklkOiBzdHJpbmcsIG1lbWJlcnNoaXBJZDogc3RyaW5nLCBwZXJpb2Q6IEZpbmFyeVBlcmlvZCA9IEZpbmFyeVBlcmlvZC5ZVEQpOiBQcm9taXNlPEJlbmNobWFya0Fzc2V0W10+IHtcclxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucmVxdWVzdEhhbmRsZXIuYXV0aGVudGljYXRlZFJlcXVlc3Q8RmluYXJ5UmVzcG9uc2U8QmVuY2htYXJrQXNzZXRbXT4+KFxyXG4gICAgICAgICAgICBgL29yZ2FuaXphdGlvbnMvJHtvcmdhbml6YXRpb25JZH0vbWVtYmVyc2hpcHMvJHttZW1iZXJzaGlwSWR9L2JlbmNobWFya3MvYXZhaWxhYmxlX2Fzc2V0cz9wZXJpb2Q9JHtwZXJpb2R9YFxyXG4gICAgICAgICk7XHJcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlLnJlc3VsdDtcclxuICAgIH1cclxufVxyXG4iXX0=
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { CheckingAccount, CheckingPortfolio, FinaryPeriod, Timeseries, TimeseriesType, Distribution, DistributionType, Transaction } from "../interfaces";
|
|
2
|
+
export interface RequestHandler {
|
|
3
|
+
authenticatedRequest<T>(endpoint: string, method?: string, body?: any): Promise<T>;
|
|
4
|
+
}
|
|
5
|
+
export declare class CheckingClient {
|
|
6
|
+
private requestHandler;
|
|
7
|
+
constructor(requestHandler: RequestHandler);
|
|
8
|
+
getAccounts(organizationId: string, membershipId: string, period?: FinaryPeriod): Promise<CheckingAccount[]>;
|
|
9
|
+
getAccount(organizationId: string, membershipId: string, accountId: string, period?: FinaryPeriod): Promise<CheckingAccount>;
|
|
10
|
+
getPortfolio(organizationId: string, membershipId: string, period?: FinaryPeriod): Promise<CheckingPortfolio>;
|
|
11
|
+
getTimeseries(organizationId: string, membershipId: string, period?: FinaryPeriod, type?: TimeseriesType): Promise<Timeseries[]>;
|
|
12
|
+
getAccountTimeseries(organizationId: string, membershipId: string, accountId: string, period?: FinaryPeriod, type?: TimeseriesType): Promise<Timeseries[]>;
|
|
13
|
+
getDistribution(organizationId: string, membershipId: string, type?: DistributionType): Promise<Distribution>;
|
|
14
|
+
getTransactions(organizationId: string, membershipId: string, page?: number, perPage?: number, query?: string, accountId?: string): Promise<Transaction[]>;
|
|
15
|
+
}
|