tiime-sdk 2.0.0 → 2.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 +30 -5
- package/dist/index.d.ts +26 -4
- package/dist/index.js +68 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,14 +8,39 @@ SDK TypeScript pour l'API de comptabilite [Tiime](https://www.tiime.fr) — inte
|
|
|
8
8
|
npm install tiime-sdk
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Authentification
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Le SDK fonctionne de maniere autonome. Plusieurs modes d'auth sont supportes :
|
|
14
|
+
|
|
15
|
+
### Via variables d'environnement (recommande)
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
export TIIME_EMAIL=vous@example.com
|
|
19
|
+
export TIIME_PASSWORD=votre-mot-de-passe
|
|
20
|
+
export TIIME_COMPANY_ID=12345
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { TiimeClient } from "tiime-sdk";
|
|
25
|
+
const client = new TiimeClient(); // tout est resolu automatiquement
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Via options explicites
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
const client = new TiimeClient({
|
|
32
|
+
email: "vous@example.com",
|
|
33
|
+
password: "votre-mot-de-passe",
|
|
34
|
+
companyId: 12345,
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Via le CLI (optionnel)
|
|
39
|
+
|
|
40
|
+
Si [`tiime-cli`](https://www.npmjs.com/package/tiime-cli) est installe, le SDK utilise ses tokens automatiquement :
|
|
14
41
|
|
|
15
42
|
```bash
|
|
16
|
-
|
|
17
|
-
tiime auth login
|
|
18
|
-
tiime company use --id 12345
|
|
43
|
+
tiime auth login && tiime company use --id 12345
|
|
19
44
|
```
|
|
20
45
|
|
|
21
46
|
## Utilisation
|
package/dist/index.d.ts
CHANGED
|
@@ -9,8 +9,10 @@ interface AuthConfig {
|
|
|
9
9
|
password: string;
|
|
10
10
|
}
|
|
11
11
|
interface TiimeClientOptions {
|
|
12
|
-
companyId
|
|
12
|
+
companyId?: number;
|
|
13
13
|
tokens?: AuthTokens;
|
|
14
|
+
email?: string;
|
|
15
|
+
password?: string;
|
|
14
16
|
}
|
|
15
17
|
interface Address {
|
|
16
18
|
street: string;
|
|
@@ -422,9 +424,29 @@ interface MatchableDocument {
|
|
|
422
424
|
}[];
|
|
423
425
|
}
|
|
424
426
|
|
|
427
|
+
/**
|
|
428
|
+
* Resolve companyId from multiple sources (in priority order):
|
|
429
|
+
* 1. Explicit option
|
|
430
|
+
* 2. TIIME_COMPANY_ID env var
|
|
431
|
+
* 3. ~/.config/tiime/config.json
|
|
432
|
+
*/
|
|
433
|
+
declare const resolveCompanyId: (explicit?: number) => number;
|
|
425
434
|
declare class TokenManager {
|
|
426
435
|
private tokens;
|
|
427
|
-
|
|
436
|
+
private credentials;
|
|
437
|
+
private persist;
|
|
438
|
+
/**
|
|
439
|
+
* @param options.tokens - Use these tokens directly (no disk I/O)
|
|
440
|
+
* @param options.email - Login with these credentials
|
|
441
|
+
* @param options.password - Login with these credentials
|
|
442
|
+
* @param options.persist - Save tokens/credentials to disk (default: true when no explicit auth)
|
|
443
|
+
*/
|
|
444
|
+
constructor(options?: {
|
|
445
|
+
tokens?: AuthTokens;
|
|
446
|
+
email?: string;
|
|
447
|
+
password?: string;
|
|
448
|
+
persist?: boolean;
|
|
449
|
+
});
|
|
428
450
|
login(email: string, password: string): Promise<AuthTokens>;
|
|
429
451
|
getValidToken(): Promise<string>;
|
|
430
452
|
isAuthenticated(): boolean;
|
|
@@ -604,7 +626,7 @@ declare class TiimeClient {
|
|
|
604
626
|
readonly fetch: $Fetch;
|
|
605
627
|
readonly tokenManager: TokenManager;
|
|
606
628
|
readonly companyId: number;
|
|
607
|
-
constructor(options
|
|
629
|
+
constructor(options?: TiimeClientOptions & {
|
|
608
630
|
tokenManager?: TokenManager;
|
|
609
631
|
});
|
|
610
632
|
listCompanies(): Promise<Company[]>;
|
|
@@ -634,4 +656,4 @@ declare class TiimeError extends Error {
|
|
|
634
656
|
};
|
|
635
657
|
}
|
|
636
658
|
|
|
637
|
-
export { type AccountingPeriod, type Address, type ApeCode, type AuthConfig, type AuthTokens, type Bank, type BankAccount, type BankTransaction, type BankTransactionsResponse, type Client, type Company, type Country, type DashboardBlock, type Document, type DocumentCategory, type DocumentMatching, type ExpenseReport, type ExpenseReportCreateParams, type Imputation, type ImputationLabel, type ImputationParams, type Invoice, type InvoiceCreateParams, type InvoiceLine, type InvoiceSendParams, type Label, type LabelSuggestion, type MatchableDocument, type PaginatedResponse, type Quotation, type QuotationCreateParams, type QuotationSendParams, type Tag, TiimeClient, type TiimeClientOptions, TiimeError, TokenManager, type User, type VatSystem };
|
|
659
|
+
export { type AccountingPeriod, type Address, type ApeCode, type AuthConfig, type AuthTokens, type Bank, type BankAccount, type BankTransaction, type BankTransactionsResponse, type Client, type Company, type Country, type DashboardBlock, type Document, type DocumentCategory, type DocumentMatching, type ExpenseReport, type ExpenseReportCreateParams, type Imputation, type ImputationLabel, type ImputationParams, type Invoice, type InvoiceCreateParams, type InvoiceLine, type InvoiceSendParams, type Label, type LabelSuggestion, type MatchableDocument, type PaginatedResponse, type Quotation, type QuotationCreateParams, type QuotationSendParams, type Tag, TiimeClient, type TiimeClientOptions, TiimeError, TokenManager, type User, type VatSystem, resolveCompanyId };
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ var AUTH0_CLIENT_ID = "iEbsbe3o66gcTBfGRa012kj1Rb6vjAND";
|
|
|
9
9
|
var AUTH0_AUDIENCE = "https://chronos/";
|
|
10
10
|
var CONFIG_DIR = join(homedir(), ".config", "tiime");
|
|
11
11
|
var AUTH_FILE = join(CONFIG_DIR, "auth.json");
|
|
12
|
+
var CONFIG_FILE = join(CONFIG_DIR, "config.json");
|
|
12
13
|
var KEYCHAIN_ACCOUNT = "tiime-cli";
|
|
13
14
|
var KEYCHAIN_SERVICE = "tiime-credentials";
|
|
14
15
|
var saveCredentialsToKeychain = (email, password) => {
|
|
@@ -68,9 +69,60 @@ var saveCredentials = (email, password) => {
|
|
|
68
69
|
var loadCredentials = () => {
|
|
69
70
|
return loadCredentialsFromKeychain() ?? loadCredentialsFromFile();
|
|
70
71
|
};
|
|
72
|
+
var resolveCompanyId = (explicit) => {
|
|
73
|
+
if (explicit) return explicit;
|
|
74
|
+
const envId = process.env.TIIME_COMPANY_ID;
|
|
75
|
+
if (envId) {
|
|
76
|
+
const parsed = Number.parseInt(envId, 10);
|
|
77
|
+
if (!Number.isNaN(parsed)) return parsed;
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
if (existsSync(CONFIG_FILE)) {
|
|
81
|
+
const config = JSON.parse(readFileSync(CONFIG_FILE, "utf-8"));
|
|
82
|
+
if (config.companyId) return config.companyId;
|
|
83
|
+
}
|
|
84
|
+
} catch {
|
|
85
|
+
}
|
|
86
|
+
throw new Error(
|
|
87
|
+
"No company ID configured. Set TIIME_COMPANY_ID env var, pass companyId option, or run `tiime company use --id <ID>`."
|
|
88
|
+
);
|
|
89
|
+
};
|
|
71
90
|
var TokenManager = class {
|
|
72
91
|
tokens = null;
|
|
73
|
-
|
|
92
|
+
credentials = null;
|
|
93
|
+
persist;
|
|
94
|
+
/**
|
|
95
|
+
* @param options.tokens - Use these tokens directly (no disk I/O)
|
|
96
|
+
* @param options.email - Login with these credentials
|
|
97
|
+
* @param options.password - Login with these credentials
|
|
98
|
+
* @param options.persist - Save tokens/credentials to disk (default: true when no explicit auth)
|
|
99
|
+
*/
|
|
100
|
+
constructor(options = {}) {
|
|
101
|
+
const hasExplicitAuth = options.tokens || options.email && options.password;
|
|
102
|
+
this.persist = options.persist ?? !hasExplicitAuth;
|
|
103
|
+
if (options.tokens) {
|
|
104
|
+
this.tokens = options.tokens;
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (options.email && options.password) {
|
|
108
|
+
this.credentials = { email: options.email, password: options.password };
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const envToken = process.env.TIIME_ACCESS_TOKEN;
|
|
112
|
+
if (envToken) {
|
|
113
|
+
this.tokens = {
|
|
114
|
+
access_token: envToken,
|
|
115
|
+
// No expiry info from env — assume valid, never auto-refresh
|
|
116
|
+
expires_at: Number.MAX_SAFE_INTEGER
|
|
117
|
+
};
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const envEmail = process.env.TIIME_EMAIL;
|
|
121
|
+
const envPassword = process.env.TIIME_PASSWORD;
|
|
122
|
+
if (envEmail && envPassword) {
|
|
123
|
+
this.credentials = { email: envEmail, password: envPassword };
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
74
126
|
this.loadFromDisk();
|
|
75
127
|
}
|
|
76
128
|
async login(email, password) {
|
|
@@ -89,19 +141,21 @@ var TokenManager = class {
|
|
|
89
141
|
access_token: response.access_token,
|
|
90
142
|
expires_at: Date.now() + response.expires_in * 1e3
|
|
91
143
|
};
|
|
92
|
-
this.
|
|
93
|
-
|
|
144
|
+
if (this.persist) {
|
|
145
|
+
this.saveToDisk();
|
|
146
|
+
saveCredentials(email, password);
|
|
147
|
+
}
|
|
94
148
|
return this.tokens;
|
|
95
149
|
}
|
|
96
150
|
async getValidToken() {
|
|
97
151
|
if (!this.tokens || this.isExpired()) {
|
|
98
|
-
const creds = loadCredentials();
|
|
152
|
+
const creds = this.credentials ?? loadCredentials();
|
|
99
153
|
if (creds) {
|
|
100
154
|
const tokens = await this.login(creds.email, creds.password);
|
|
101
155
|
return tokens.access_token;
|
|
102
156
|
}
|
|
103
157
|
throw new Error(
|
|
104
|
-
this.tokens ? "Token expired.
|
|
158
|
+
this.tokens ? "Token expired. Provide credentials via options, TIIME_EMAIL/TIIME_PASSWORD env vars, or run `tiime auth login`." : "Not authenticated. Provide credentials via options, TIIME_EMAIL/TIIME_PASSWORD env vars, or run `tiime auth login`."
|
|
105
159
|
);
|
|
106
160
|
}
|
|
107
161
|
return this.tokens.access_token;
|
|
@@ -679,9 +733,13 @@ var TiimeClient = class {
|
|
|
679
733
|
fetch;
|
|
680
734
|
tokenManager;
|
|
681
735
|
companyId;
|
|
682
|
-
constructor(options) {
|
|
683
|
-
this.companyId = options.companyId;
|
|
684
|
-
this.tokenManager = options.tokenManager ?? new TokenManager(
|
|
736
|
+
constructor(options = {}) {
|
|
737
|
+
this.companyId = resolveCompanyId(options.companyId);
|
|
738
|
+
this.tokenManager = options.tokenManager ?? new TokenManager({
|
|
739
|
+
tokens: options.tokens,
|
|
740
|
+
email: options.email,
|
|
741
|
+
password: options.password
|
|
742
|
+
});
|
|
685
743
|
this.fetch = ofetch2.create({
|
|
686
744
|
baseURL: BASE_URL,
|
|
687
745
|
retry: 2,
|
|
@@ -748,5 +806,6 @@ var TiimeClient = class {
|
|
|
748
806
|
export {
|
|
749
807
|
TiimeClient,
|
|
750
808
|
TiimeError,
|
|
751
|
-
TokenManager
|
|
809
|
+
TokenManager,
|
|
810
|
+
resolveCompanyId
|
|
752
811
|
};
|