@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.
@@ -6,7 +6,7 @@ export declare class AuthManager {
6
6
  baseUrl: string;
7
7
  storage: TokenStorage | TokenStorage[];
8
8
  });
9
- hasTokens(): Promise<boolean>;
9
+ isAuthenticated(): Promise<boolean>;
10
10
  fetchNewTokens(): Promise<Tokens>;
11
11
  accessToken(): Promise<string | undefined>;
12
12
  refreshTokens(): Promise<Tokens | null>;
@@ -11,11 +11,42 @@ export class AuthManager {
11
11
  });
12
12
  this.baseUrl = baseUrl;
13
13
  }
14
- async hasTokens() {
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
- return true;
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, amt?: number, knownIds?: string[], unknownIds?: string[], keyword?: string, cancelToken?: CancelToken, headers?: Record<string, string>): Promise<any>;
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 this.config.authManager.accessToken().then(token => {
32
- return new Promise((resolve, reject) => {
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.message || msg;
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
- if (cancelToken?.isCancelled()) {
110
- return new StandardError(0, 'Request cancelled');
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, amt = 50, knownIds = [], unknownIds = [], keyword = '', cancelToken, headers = {}) {
201
- const body = {
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?amt=${amt}`, body, cancelToken, headers)
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
  }
@@ -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
- id: string;
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
- amount: number;
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: LineItem[];
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
- id: string;
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
- id: string;
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@go-avro/avro-js",
3
- "version": "0.0.2-beta.3",
3
+ "version": "0.0.2-beta.31",
4
4
  "description": "JS client for Avro backend integration.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",