@go-avro/avro-js 0.0.2-beta.3 → 0.0.2-beta.31
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/dist/auth/AuthManager.d.ts +1 -1
- package/dist/auth/AuthManager.js +33 -2
- package/dist/client/QueryClient.d.ts +45 -1
- package/dist/client/QueryClient.js +90 -14
- package/dist/types/api.d.ts +15 -16
- package/package.json +1 -1
|
@@ -6,7 +6,7 @@ export declare class AuthManager {
|
|
|
6
6
|
baseUrl: string;
|
|
7
7
|
storage: TokenStorage | TokenStorage[];
|
|
8
8
|
});
|
|
9
|
-
|
|
9
|
+
isAuthenticated(): Promise<boolean>;
|
|
10
10
|
fetchNewTokens(): Promise<Tokens>;
|
|
11
11
|
accessToken(): Promise<string | undefined>;
|
|
12
12
|
refreshTokens(): Promise<Tokens | null>;
|
package/dist/auth/AuthManager.js
CHANGED
|
@@ -11,11 +11,42 @@ export class AuthManager {
|
|
|
11
11
|
});
|
|
12
12
|
this.baseUrl = baseUrl;
|
|
13
13
|
}
|
|
14
|
-
async
|
|
14
|
+
async isAuthenticated() {
|
|
15
|
+
if (!this.storages.length) {
|
|
16
|
+
throw new Error('No token storages initialized');
|
|
17
|
+
}
|
|
15
18
|
for (const storage of this.storages) {
|
|
16
19
|
const tokens = await storage.get();
|
|
17
20
|
if (tokens && tokens.access_token) {
|
|
18
|
-
|
|
21
|
+
try {
|
|
22
|
+
const response = await fetch(`${this.baseUrl}/validate`, {
|
|
23
|
+
method: 'POST',
|
|
24
|
+
headers: {
|
|
25
|
+
'Content-Type': 'application/json',
|
|
26
|
+
'Authorization': `Bearer ${tokens.access_token}`,
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
if (response.ok) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
// Attempt token refresh if validation fails
|
|
34
|
+
const newTokens = await this.refreshTokens();
|
|
35
|
+
if (newTokens && newTokens.access_token) {
|
|
36
|
+
const retryResponse = await fetch(`${this.baseUrl}/validate`, {
|
|
37
|
+
method: 'POST',
|
|
38
|
+
headers: {
|
|
39
|
+
'Content-Type': 'application/json',
|
|
40
|
+
'Authorization': `Bearer ${newTokens.access_token}`,
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
return retryResponse.ok;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.error('Error validating access token:', error);
|
|
49
|
+
}
|
|
19
50
|
}
|
|
20
51
|
}
|
|
21
52
|
return false;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AuthManager } from '../auth/AuthManager';
|
|
2
|
+
import { LineItem } from '../types/api';
|
|
2
3
|
import { CancelToken, RetryStrategy } from '../types/client';
|
|
3
4
|
export interface AvroQueryClientConfig {
|
|
4
5
|
baseUrl: string;
|
|
@@ -22,5 +23,48 @@ export declare class AvroQueryClient {
|
|
|
22
23
|
password: string;
|
|
23
24
|
}, cancelToken?: CancelToken): Promise<Boolean>;
|
|
24
25
|
logout(cancelToken?: CancelToken): Promise<void>;
|
|
25
|
-
fetchJobs(companyGuid: string,
|
|
26
|
+
fetchJobs(companyGuid: string, body?: {
|
|
27
|
+
amt?: number;
|
|
28
|
+
known_ids?: string[];
|
|
29
|
+
unknown_ids?: string[];
|
|
30
|
+
query?: string;
|
|
31
|
+
offset?: number;
|
|
32
|
+
}, cancelToken?: CancelToken, headers?: Record<string, string>): Promise<any>;
|
|
33
|
+
fetchEvents(companyGuid: string, body?: {
|
|
34
|
+
amt?: number;
|
|
35
|
+
known_ids?: string[];
|
|
36
|
+
unknown_ids?: string[];
|
|
37
|
+
query?: string;
|
|
38
|
+
offset?: number;
|
|
39
|
+
unbilled?: boolean;
|
|
40
|
+
billed?: boolean;
|
|
41
|
+
paid?: boolean;
|
|
42
|
+
jobId?: string | null;
|
|
43
|
+
}, cancelToken?: CancelToken, headers?: Record<string, string>): Promise<any>;
|
|
44
|
+
fetchMonths(companyGuid: string, body?: {
|
|
45
|
+
amt?: number;
|
|
46
|
+
known_ids?: string[];
|
|
47
|
+
unknown_ids?: string[];
|
|
48
|
+
query?: string;
|
|
49
|
+
offset?: number;
|
|
50
|
+
unbilled?: boolean;
|
|
51
|
+
billed?: boolean;
|
|
52
|
+
paid?: boolean;
|
|
53
|
+
jobId?: string | null;
|
|
54
|
+
}, cancelToken?: CancelToken, headers?: Record<string, string>): Promise<any>;
|
|
55
|
+
fetchBills(companyGuid: string, body?: {
|
|
56
|
+
amt?: number;
|
|
57
|
+
known_ids?: string[];
|
|
58
|
+
unknown_ids?: string[];
|
|
59
|
+
query?: string;
|
|
60
|
+
offset?: number;
|
|
61
|
+
paid?: boolean;
|
|
62
|
+
}, cancelToken?: CancelToken, headers?: Record<string, string>): Promise<any>;
|
|
63
|
+
sendEmail(emailId: string, formData: FormData): Promise<void>;
|
|
64
|
+
createBill(companyGuid: string, data: {
|
|
65
|
+
line_items: LineItem[];
|
|
66
|
+
due_date: number;
|
|
67
|
+
users: string[];
|
|
68
|
+
custom_emails: [string, string][];
|
|
69
|
+
}, cancelToken?: CancelToken): Promise<any>;
|
|
26
70
|
}
|
|
@@ -28,8 +28,8 @@ export class AvroQueryClient {
|
|
|
28
28
|
}
|
|
29
29
|
return null;
|
|
30
30
|
};
|
|
31
|
-
return
|
|
32
|
-
|
|
31
|
+
return new Promise((resolve, reject) => {
|
|
32
|
+
this.config.authManager.accessToken().then(token => {
|
|
33
33
|
const cancelErr = checkCancelled();
|
|
34
34
|
if (cancelErr)
|
|
35
35
|
return reject(cancelErr);
|
|
@@ -76,7 +76,7 @@ export class AvroQueryClient {
|
|
|
76
76
|
let msg = xhr.statusText;
|
|
77
77
|
try {
|
|
78
78
|
const parsed = JSON.parse(xhr.responseText);
|
|
79
|
-
msg = parsed.
|
|
79
|
+
msg = parsed.msg || msg;
|
|
80
80
|
}
|
|
81
81
|
catch {
|
|
82
82
|
console.warn('Failed to parse error response:', xhr.responseText);
|
|
@@ -106,8 +106,13 @@ export class AvroQueryClient {
|
|
|
106
106
|
}
|
|
107
107
|
_fetch(method, path, body, cancelToken, headers = {}, isIdempotent = false, retryCount = 0) {
|
|
108
108
|
const checkCancelled = () => {
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
try {
|
|
110
|
+
if (cancelToken?.isCancelled()) {
|
|
111
|
+
return new StandardError(0, 'Request cancelled');
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
throw new StandardError(0, `Error checking cancellation (${typeof cancelToken}): ${error}`);
|
|
111
116
|
}
|
|
112
117
|
return null;
|
|
113
118
|
};
|
|
@@ -197,17 +202,11 @@ export class AvroQueryClient {
|
|
|
197
202
|
throw new StandardError(500, 'Logout failed');
|
|
198
203
|
});
|
|
199
204
|
}
|
|
200
|
-
fetchJobs(companyGuid,
|
|
201
|
-
|
|
202
|
-
amt,
|
|
203
|
-
known_ids: knownIds,
|
|
204
|
-
unknown_ids: unknownIds,
|
|
205
|
-
query: keyword,
|
|
206
|
-
};
|
|
207
|
-
if (!companyGuid) {
|
|
205
|
+
fetchJobs(companyGuid, body = {}, cancelToken, headers = {}) {
|
|
206
|
+
if (!companyGuid || companyGuid.trim() === '') {
|
|
208
207
|
return Promise.reject(new StandardError(400, 'Company GUID is required'));
|
|
209
208
|
}
|
|
210
|
-
return this._fetch('POST', `/company/${companyGuid}/jobs
|
|
209
|
+
return this._fetch('POST', `/company/${companyGuid}/jobs`, body, cancelToken, headers)
|
|
211
210
|
.then(response => {
|
|
212
211
|
if (!response || !Array.isArray(response)) {
|
|
213
212
|
throw new StandardError(400, 'Invalid jobs response');
|
|
@@ -219,4 +218,81 @@ export class AvroQueryClient {
|
|
|
219
218
|
throw new StandardError(500, 'Failed to fetch jobs');
|
|
220
219
|
});
|
|
221
220
|
}
|
|
221
|
+
fetchEvents(companyGuid, body = {}, cancelToken, headers = {}) {
|
|
222
|
+
if (!companyGuid || companyGuid.trim() === '') {
|
|
223
|
+
return Promise.reject(new StandardError(400, 'Company GUID is required'));
|
|
224
|
+
}
|
|
225
|
+
return this._fetch('POST', `/company/${companyGuid}/events`, body, cancelToken, headers)
|
|
226
|
+
.then(response => {
|
|
227
|
+
if (!response || !Array.isArray(response)) {
|
|
228
|
+
throw new StandardError(400, 'Invalid events response');
|
|
229
|
+
}
|
|
230
|
+
return response;
|
|
231
|
+
})
|
|
232
|
+
.catch(err => {
|
|
233
|
+
console.error('Failed to fetch events:', err);
|
|
234
|
+
throw new StandardError(500, 'Failed to fetch events');
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
fetchMonths(companyGuid, body = {}, cancelToken, headers = {}) {
|
|
238
|
+
if (!companyGuid || companyGuid.trim() === '') {
|
|
239
|
+
return Promise.reject(new StandardError(400, 'Company GUID is required'));
|
|
240
|
+
}
|
|
241
|
+
return this._fetch('POST', `/company/${companyGuid}/months`, body, cancelToken, headers)
|
|
242
|
+
.then(response => {
|
|
243
|
+
if (!response || !Array.isArray(response)) {
|
|
244
|
+
throw new StandardError(400, 'Invalid months response');
|
|
245
|
+
}
|
|
246
|
+
return response;
|
|
247
|
+
})
|
|
248
|
+
.catch(err => {
|
|
249
|
+
console.error('Failed to fetch months:', err);
|
|
250
|
+
throw new StandardError(500, 'Failed to fetch months');
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
fetchBills(companyGuid, body = {}, cancelToken, headers = {}) {
|
|
254
|
+
if (!companyGuid || companyGuid.trim() === '') {
|
|
255
|
+
return Promise.reject(new StandardError(400, 'Company GUID is required'));
|
|
256
|
+
}
|
|
257
|
+
return this._fetch('POST', `/company/${companyGuid}/bills`, body, cancelToken, headers)
|
|
258
|
+
.then(response => {
|
|
259
|
+
if (!response || !Array.isArray(response)) {
|
|
260
|
+
throw new StandardError(400, 'Invalid bills response');
|
|
261
|
+
}
|
|
262
|
+
return response;
|
|
263
|
+
})
|
|
264
|
+
.catch(err => {
|
|
265
|
+
console.error('Failed to fetch bills:', err);
|
|
266
|
+
throw new StandardError(500, 'Failed to fetch bills');
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
sendEmail(emailId, formData) {
|
|
270
|
+
try {
|
|
271
|
+
return this._xhr('POST', `/email/${emailId}`, formData);
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
throw new StandardError(500, `Failed to send email: ${error}`);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
createBill(companyGuid, data, cancelToken) {
|
|
278
|
+
if (!companyGuid) {
|
|
279
|
+
return Promise.reject(new StandardError(400, 'Company GUID is required'));
|
|
280
|
+
}
|
|
281
|
+
const body = {
|
|
282
|
+
events: data.line_items.filter(item => item.line_item_type === 'EVENT').map(item => item.id),
|
|
283
|
+
months: data.line_items.filter(item => item.line_item_type === 'SERVICE_MONTH').map(item => item.id),
|
|
284
|
+
line_items: data.line_items.filter(item => item.line_item_type === 'CUSTOM'),
|
|
285
|
+
manual_emails: data.custom_emails,
|
|
286
|
+
users: data.users,
|
|
287
|
+
due_date: data.due_date,
|
|
288
|
+
};
|
|
289
|
+
try {
|
|
290
|
+
return this._xhr('POST', `/company/${companyGuid}/bill`, JSON.stringify(body), cancelToken, {
|
|
291
|
+
'Content-Type': 'application/json',
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
catch (error) {
|
|
295
|
+
throw new StandardError(500, `Failed to create bill: ${error}`);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
222
298
|
}
|
package/dist/types/api.d.ts
CHANGED
|
@@ -68,12 +68,16 @@ export interface MemberState {
|
|
|
68
68
|
}
|
|
69
69
|
export interface LineItem {
|
|
70
70
|
id: string;
|
|
71
|
+
line_item_type: "CUSTOM" | "ADDITIONAL_CHARGE" | "EVENT" | "SERVICE_MONTH";
|
|
71
72
|
name: string;
|
|
72
73
|
description: string;
|
|
73
74
|
cost: number | null;
|
|
74
75
|
amount: number | null;
|
|
75
76
|
time_created: number;
|
|
76
77
|
}
|
|
78
|
+
export interface CustomLineItem extends LineItem {
|
|
79
|
+
line_item_type: "CUSTOM";
|
|
80
|
+
}
|
|
77
81
|
export interface Reaction {
|
|
78
82
|
id: string;
|
|
79
83
|
message_id: string;
|
|
@@ -209,16 +213,16 @@ export interface Break {
|
|
|
209
213
|
company_billable: boolean;
|
|
210
214
|
client_billable: boolean;
|
|
211
215
|
}
|
|
212
|
-
export interface ServiceMonth {
|
|
213
|
-
|
|
216
|
+
export interface ServiceMonth extends LineItem {
|
|
217
|
+
line_item_type: "SERVICE_MONTH";
|
|
214
218
|
job_name: string;
|
|
215
219
|
job_id: string | null;
|
|
220
|
+
job_address: string;
|
|
221
|
+
job_labels: string[];
|
|
216
222
|
bill_id: string | null;
|
|
217
|
-
cost: number;
|
|
218
223
|
billed: boolean;
|
|
219
224
|
paid: boolean;
|
|
220
|
-
|
|
221
|
-
time_created: number;
|
|
225
|
+
tasks: string[];
|
|
222
226
|
time_updated: number | null;
|
|
223
227
|
}
|
|
224
228
|
export interface Session {
|
|
@@ -294,6 +298,7 @@ export interface Bill {
|
|
|
294
298
|
customer_email: string | null;
|
|
295
299
|
manual_emails: string[][];
|
|
296
300
|
users: BillUser[];
|
|
301
|
+
paid: boolean;
|
|
297
302
|
paid_at: number;
|
|
298
303
|
time_created: number;
|
|
299
304
|
time_updated: number;
|
|
@@ -301,7 +306,7 @@ export interface Bill {
|
|
|
301
306
|
intent_created_at: number;
|
|
302
307
|
intent_last_created_at: number;
|
|
303
308
|
payment: BillPayment | null;
|
|
304
|
-
line_items:
|
|
309
|
+
line_items: CustomLineItem[];
|
|
305
310
|
months: string[];
|
|
306
311
|
due_date: number;
|
|
307
312
|
}
|
|
@@ -471,22 +476,17 @@ export interface taskEndInfo {
|
|
|
471
476
|
internal_notes: string;
|
|
472
477
|
external_notes: string;
|
|
473
478
|
}
|
|
474
|
-
export interface AdditionalCharge {
|
|
475
|
-
|
|
476
|
-
time_created: number;
|
|
479
|
+
export interface AdditionalCharge extends LineItem {
|
|
480
|
+
line_item_type: "ADDITIONAL_CHARGE";
|
|
477
481
|
time_updated: number | null;
|
|
478
|
-
name: string;
|
|
479
|
-
amount: number;
|
|
480
482
|
}
|
|
481
|
-
export interface _Event {
|
|
483
|
+
export interface _Event extends LineItem {
|
|
482
484
|
breaks: string[];
|
|
483
|
-
|
|
484
|
-
name: string;
|
|
485
|
+
line_item_type: "EVENT";
|
|
485
486
|
internal_notes: string;
|
|
486
487
|
external_notes: string;
|
|
487
488
|
proofs: string[];
|
|
488
489
|
tasks: string[];
|
|
489
|
-
time_created: number;
|
|
490
490
|
time_ended: number;
|
|
491
491
|
time_started: number;
|
|
492
492
|
time_updated: number | null;
|
|
@@ -498,7 +498,6 @@ export interface _Event {
|
|
|
498
498
|
additional_charges: AdditionalCharge[];
|
|
499
499
|
user_id: string;
|
|
500
500
|
team_id: string;
|
|
501
|
-
cost: number;
|
|
502
501
|
billed: boolean;
|
|
503
502
|
paid: boolean;
|
|
504
503
|
autostart: boolean;
|