@go-avro/avro-js 0.0.2-beta.6 → 0.0.2-beta.60
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 +1 -0
- package/dist/client/QueryClient.d.ts +254 -10
- package/dist/client/QueryClient.js +124 -178
- package/dist/client/core/fetch.d.ts +1 -0
- package/dist/client/core/fetch.js +67 -0
- package/dist/client/core/utils.d.ts +1 -0
- package/dist/client/core/utils.js +13 -0
- package/dist/client/core/xhr.d.ts +1 -0
- package/dist/client/core/xhr.js +87 -0
- package/dist/client/hooks/bills.d.ts +1 -0
- package/dist/client/hooks/bills.js +141 -0
- package/dist/client/hooks/companies.d.ts +1 -0
- package/dist/client/hooks/companies.js +51 -0
- package/dist/client/hooks/events.d.ts +1 -0
- package/dist/client/hooks/events.js +307 -0
- package/dist/client/hooks/jobs.d.ts +1 -0
- package/dist/client/hooks/jobs.js +184 -0
- package/dist/client/hooks/months.d.ts +1 -0
- package/dist/client/hooks/months.js +92 -0
- package/dist/client/hooks/root.d.ts +1 -0
- package/dist/client/hooks/root.js +8 -0
- package/dist/client/hooks/routes.d.ts +1 -0
- package/dist/client/hooks/routes.js +127 -0
- package/dist/client/hooks/sessions.d.ts +1 -0
- package/dist/client/hooks/sessions.js +154 -0
- package/dist/client/hooks/users.d.ts +1 -0
- package/dist/client/hooks/users.js +93 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +13 -0
- package/dist/types/api.d.ts +106 -23
- package/dist/types/api.js +6 -1
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@ This SDK provides:
|
|
|
10
10
|
- Typed API interfaces for Avro entities (users, jobs, teams, etc.)
|
|
11
11
|
- Pluggable token storage (in-memory, localStorage, SecureStore, etc.)
|
|
12
12
|
- XHR-based requests for compatibility with React Native WebViews and older environments
|
|
13
|
+
- Mutation and Data Hooks for easy plug-in use in React and React Native projects.
|
|
13
14
|
|
|
14
15
|
## Installation
|
|
15
16
|
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import { InfiniteData, UseInfiniteQueryResult, useMutation, UseQueryResult } from '@tanstack/react-query';
|
|
1
2
|
import { AuthManager } from '../auth/AuthManager';
|
|
3
|
+
import { _Event, ApiInfo, Bill, Break, Company, Job, LineItem, Route, ServiceMonth, Session, User, UserCompanyAssociation } from '../types/api';
|
|
4
|
+
import { Tokens } from '../types/auth';
|
|
2
5
|
import { CancelToken, RetryStrategy } from '../types/client';
|
|
6
|
+
import { StandardError } from '../types/error';
|
|
3
7
|
export interface AvroQueryClientConfig {
|
|
4
8
|
baseUrl: string;
|
|
5
9
|
authManager: AuthManager;
|
|
@@ -7,20 +11,260 @@ export interface AvroQueryClientConfig {
|
|
|
7
11
|
retryStrategy?: RetryStrategy;
|
|
8
12
|
timeout?: number;
|
|
9
13
|
}
|
|
14
|
+
declare module '../client/QueryClient' {
|
|
15
|
+
interface AvroQueryClient {
|
|
16
|
+
_xhr<T>(method: string, path: string, body: any, cancelToken?: CancelToken, headers?: Record<string, string>, isIdempotent?: boolean, retryCount?: number, progressUpdateCallback?: (loaded: number, total: number) => void): Promise<T>;
|
|
17
|
+
_fetch<T>(method: string, path: string, body: any, cancelToken?: CancelToken, headers?: Record<string, string>, isIdempotent?: boolean, retryCount?: number): Promise<T>;
|
|
18
|
+
getDelay(strategy: RetryStrategy, attempt: number): number;
|
|
19
|
+
useGetRoot(): UseQueryResult<ApiInfo, StandardError>;
|
|
20
|
+
useGetJobs(companyGuid: string, body: {
|
|
21
|
+
amt?: number;
|
|
22
|
+
query?: string;
|
|
23
|
+
}, total: number, onProgress?: (fraction: number) => void, isMainLoad?: boolean): UseQueryResult<Job[], StandardError>;
|
|
24
|
+
useGetRoutes(companyGuid: string, body: {
|
|
25
|
+
amt?: number;
|
|
26
|
+
query?: string;
|
|
27
|
+
}, total: number, onProgress?: (fraction: number) => void): UseQueryResult<any[], StandardError>;
|
|
28
|
+
useGetEvents(companyGuid: string, body: {
|
|
29
|
+
amt?: number;
|
|
30
|
+
known_ids?: string[];
|
|
31
|
+
unknown_ids?: string[];
|
|
32
|
+
query?: string;
|
|
33
|
+
unbilled?: boolean;
|
|
34
|
+
billed?: boolean;
|
|
35
|
+
paid?: boolean;
|
|
36
|
+
jobId?: string;
|
|
37
|
+
}): UseInfiniteQueryResult<InfiniteData<_Event[], unknown>, StandardError>;
|
|
38
|
+
useGetMonths(companyGuid: string, body: {
|
|
39
|
+
amt?: number;
|
|
40
|
+
known_ids?: string[];
|
|
41
|
+
unknown_ids?: string[];
|
|
42
|
+
query?: string;
|
|
43
|
+
unbilled?: boolean;
|
|
44
|
+
billed?: boolean;
|
|
45
|
+
paid?: boolean;
|
|
46
|
+
jobId?: string;
|
|
47
|
+
}): UseInfiniteQueryResult<InfiniteData<ServiceMonth[], unknown>, StandardError>;
|
|
48
|
+
useGetBills(companyGuid: string, body: {
|
|
49
|
+
amt?: number;
|
|
50
|
+
known_ids?: string[];
|
|
51
|
+
unknown_ids?: string[];
|
|
52
|
+
query?: string;
|
|
53
|
+
paid?: boolean;
|
|
54
|
+
}): UseInfiniteQueryResult<InfiniteData<Bill[], unknown>, StandardError>;
|
|
55
|
+
useGetCompanies(options?: {}): UseQueryResult<{
|
|
56
|
+
name: string;
|
|
57
|
+
id: string;
|
|
58
|
+
}[], StandardError>;
|
|
59
|
+
useGetCompany(companyId: string): UseQueryResult<Company, StandardError>;
|
|
60
|
+
useGetJob(jobId: string): UseQueryResult<Job, StandardError>;
|
|
61
|
+
useGetEvent(eventId: string): UseQueryResult<_Event, StandardError>;
|
|
62
|
+
useGetUser(userId: string): UseQueryResult<User, StandardError>;
|
|
63
|
+
useGetSelf(): UseQueryResult<User, StandardError>;
|
|
64
|
+
useGetBill(billId: string): UseQueryResult<Bill, StandardError>;
|
|
65
|
+
useGetRoute(routeId: string): UseQueryResult<Route, StandardError>;
|
|
66
|
+
useGetUserSessions(): UseQueryResult<Session[], StandardError>;
|
|
67
|
+
useCreateEvent(): ReturnType<typeof useMutation<{
|
|
68
|
+
id: string;
|
|
69
|
+
}, StandardError, {
|
|
70
|
+
companyId: string;
|
|
71
|
+
eventData: Partial<_Event>;
|
|
72
|
+
}>>;
|
|
73
|
+
useCreateUserSession(): ReturnType<typeof useMutation<{
|
|
74
|
+
id: string;
|
|
75
|
+
}, StandardError, {
|
|
76
|
+
companyId: string;
|
|
77
|
+
sessionData: Partial<Session>;
|
|
78
|
+
}>>;
|
|
79
|
+
useCreateBill(): ReturnType<typeof useMutation<{
|
|
80
|
+
id: string;
|
|
81
|
+
invoice_id: number;
|
|
82
|
+
}, StandardError, {
|
|
83
|
+
companyId: string;
|
|
84
|
+
data: {
|
|
85
|
+
line_items: LineItem[];
|
|
86
|
+
due_date: number;
|
|
87
|
+
users: string[];
|
|
88
|
+
custom_emails: [string, string][];
|
|
89
|
+
};
|
|
90
|
+
}>>;
|
|
91
|
+
useCreateJob(): ReturnType<typeof useMutation<{
|
|
92
|
+
id: string;
|
|
93
|
+
}, StandardError, {
|
|
94
|
+
companyId: string;
|
|
95
|
+
jobData: Partial<Job>;
|
|
96
|
+
}>>;
|
|
97
|
+
useCreateSelf(): ReturnType<typeof useMutation<{
|
|
98
|
+
msg: string;
|
|
99
|
+
}, StandardError, {
|
|
100
|
+
username: string;
|
|
101
|
+
name: string;
|
|
102
|
+
email: string;
|
|
103
|
+
password: string;
|
|
104
|
+
phone_number: string;
|
|
105
|
+
}>>;
|
|
106
|
+
useCreateSessionBreak(): ReturnType<typeof useMutation<{
|
|
107
|
+
id: string;
|
|
108
|
+
}, StandardError, {
|
|
109
|
+
sessionId: string;
|
|
110
|
+
breakData: {
|
|
111
|
+
start_time: string;
|
|
112
|
+
end_time?: string;
|
|
113
|
+
};
|
|
114
|
+
}>>;
|
|
115
|
+
useUpdateEvent(): ReturnType<typeof useMutation<{
|
|
116
|
+
msg: string;
|
|
117
|
+
}, StandardError, {
|
|
118
|
+
eventId: string;
|
|
119
|
+
updates: Partial<_Event>;
|
|
120
|
+
}>>;
|
|
121
|
+
useUpdateUserSession(): ReturnType<typeof useMutation<{
|
|
122
|
+
msg: string;
|
|
123
|
+
}, StandardError, {
|
|
124
|
+
sessionId: string;
|
|
125
|
+
updates: Partial<Session>;
|
|
126
|
+
}>>;
|
|
127
|
+
useUpdateJob(): ReturnType<typeof useMutation<{
|
|
128
|
+
msg: string;
|
|
129
|
+
}, StandardError, {
|
|
130
|
+
jobId: string;
|
|
131
|
+
updates: Partial<Job>;
|
|
132
|
+
}>>;
|
|
133
|
+
useUpdateBill(): ReturnType<typeof useMutation<{
|
|
134
|
+
msg: string;
|
|
135
|
+
}, StandardError, {
|
|
136
|
+
billId: string;
|
|
137
|
+
updates: Partial<Bill>;
|
|
138
|
+
}>>;
|
|
139
|
+
useUpdateRoute(): ReturnType<typeof useMutation<{
|
|
140
|
+
msg: string;
|
|
141
|
+
}, StandardError, {
|
|
142
|
+
routeId: string;
|
|
143
|
+
updates: Partial<Route>;
|
|
144
|
+
}>>;
|
|
145
|
+
useUpdateEvents(): ReturnType<typeof useMutation<void, StandardError, {
|
|
146
|
+
companyId: string;
|
|
147
|
+
events: (_Event & {
|
|
148
|
+
page?: number;
|
|
149
|
+
})[];
|
|
150
|
+
action: "billed" | "paid";
|
|
151
|
+
}>>;
|
|
152
|
+
useUpdateMonths(): ReturnType<typeof useMutation<void, StandardError, {
|
|
153
|
+
companyId: string;
|
|
154
|
+
months: (ServiceMonth & {
|
|
155
|
+
page?: number;
|
|
156
|
+
})[];
|
|
157
|
+
action: "billed" | "paid";
|
|
158
|
+
}>>;
|
|
159
|
+
useUpdateUserCompany(): ReturnType<typeof useMutation<{
|
|
160
|
+
msg: string;
|
|
161
|
+
}, StandardError, {
|
|
162
|
+
company_id: string;
|
|
163
|
+
user_id: string;
|
|
164
|
+
data: Partial<UserCompanyAssociation>;
|
|
165
|
+
}>>;
|
|
166
|
+
useUpdateSessionBreak(): ReturnType<typeof useMutation<{
|
|
167
|
+
msg: string;
|
|
168
|
+
}, StandardError, {
|
|
169
|
+
breakId: string;
|
|
170
|
+
updates: Partial<Break>;
|
|
171
|
+
}>>;
|
|
172
|
+
useDeleteJob(): ReturnType<typeof useMutation<{
|
|
173
|
+
msg: string;
|
|
174
|
+
}, StandardError, {
|
|
175
|
+
jobId: string;
|
|
176
|
+
}>>;
|
|
177
|
+
useUpdateCompany(): ReturnType<typeof useMutation<{
|
|
178
|
+
msg: string;
|
|
179
|
+
}, StandardError, {
|
|
180
|
+
companyId: string;
|
|
181
|
+
companyData: Partial<Company | {
|
|
182
|
+
logo: File | null;
|
|
183
|
+
}>;
|
|
184
|
+
}>>;
|
|
185
|
+
useDeleteEvent(): ReturnType<typeof useMutation<{
|
|
186
|
+
msg: string;
|
|
187
|
+
}, StandardError, {
|
|
188
|
+
eventId: string;
|
|
189
|
+
}>>;
|
|
190
|
+
useDeleteBill(): ReturnType<typeof useMutation<{
|
|
191
|
+
msg: string;
|
|
192
|
+
}, StandardError, {
|
|
193
|
+
billId: string;
|
|
194
|
+
}>>;
|
|
195
|
+
useDeleteRoute(): ReturnType<typeof useMutation<{
|
|
196
|
+
msg: string;
|
|
197
|
+
}, StandardError, {
|
|
198
|
+
routeId: string;
|
|
199
|
+
}>>;
|
|
200
|
+
useDeleteSelf(): ReturnType<typeof useMutation<{
|
|
201
|
+
msg: string;
|
|
202
|
+
}, StandardError, void>>;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
10
205
|
export declare class AvroQueryClient {
|
|
11
|
-
|
|
206
|
+
protected config: Required<AvroQueryClientConfig>;
|
|
12
207
|
constructor(config: AvroQueryClientConfig);
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
post<T>(path: string, data: any, cancelToken?: CancelToken, headers?: Record<string, string>): Promise<T>;
|
|
18
|
-
put<T>(path: string, data: any, cancelToken?: CancelToken, headers?: Record<string, string>): Promise<T>;
|
|
19
|
-
delete<T>(path: string, cancelToken?: CancelToken, headers?: Record<string, string>): Promise<T>;
|
|
208
|
+
get<T>(path: string, cancelToken?: CancelToken, headers?: Record<string, string>, progressUpdateCallback?: (loaded: number, total: number) => void): Promise<T>;
|
|
209
|
+
post<T>(path: string, data: any, cancelToken?: CancelToken, headers?: Record<string, string>, progressUpdateCallback?: (loaded: number, total: number) => void): Promise<T>;
|
|
210
|
+
put<T>(path: string, data: any, cancelToken?: CancelToken, headers?: Record<string, string>, progressUpdateCallback?: (loaded: number, total: number) => void): Promise<T>;
|
|
211
|
+
delete<T>(path: string, cancelToken?: CancelToken, headers?: Record<string, string>, progressUpdateCallback?: (loaded: number, total: number) => void): Promise<T>;
|
|
20
212
|
login(data: {
|
|
21
213
|
username: string;
|
|
22
214
|
password: string;
|
|
23
215
|
}, cancelToken?: CancelToken): Promise<Boolean>;
|
|
24
|
-
|
|
25
|
-
|
|
216
|
+
setTokens(tokens: Tokens): Promise<void>;
|
|
217
|
+
clearTokens(): Promise<void>;
|
|
218
|
+
useLogout(): ReturnType<typeof useMutation<void, StandardError, CancelToken | undefined>>;
|
|
219
|
+
fetchJobs(companyGuid: string, body?: {
|
|
220
|
+
amt?: number;
|
|
221
|
+
known_ids?: string[];
|
|
222
|
+
unknown_ids?: string[];
|
|
223
|
+
query?: string;
|
|
224
|
+
offset?: number;
|
|
225
|
+
}, cancelToken?: CancelToken, headers?: Record<string, string>): Promise<any>;
|
|
226
|
+
fetchEvents(companyGuid: string, body?: {
|
|
227
|
+
amt?: number;
|
|
228
|
+
known_ids?: string[];
|
|
229
|
+
unknown_ids?: string[];
|
|
230
|
+
query?: string;
|
|
231
|
+
offset?: number;
|
|
232
|
+
unbilled?: boolean;
|
|
233
|
+
billed?: boolean;
|
|
234
|
+
paid?: boolean;
|
|
235
|
+
jobId?: string | null;
|
|
236
|
+
}, cancelToken?: CancelToken, headers?: Record<string, string>): Promise<any>;
|
|
237
|
+
fetchMonths(companyGuid: string, body?: {
|
|
238
|
+
amt?: number;
|
|
239
|
+
known_ids?: string[];
|
|
240
|
+
unknown_ids?: string[];
|
|
241
|
+
query?: string;
|
|
242
|
+
offset?: number;
|
|
243
|
+
unbilled?: boolean;
|
|
244
|
+
billed?: boolean;
|
|
245
|
+
paid?: boolean;
|
|
246
|
+
jobId?: string | null;
|
|
247
|
+
}, cancelToken?: CancelToken, headers?: Record<string, string>): Promise<any>;
|
|
248
|
+
fetchBills(companyGuid: string, body?: {
|
|
249
|
+
amt?: number;
|
|
250
|
+
known_ids?: string[];
|
|
251
|
+
unknown_ids?: string[];
|
|
252
|
+
query?: string;
|
|
253
|
+
offset?: number;
|
|
254
|
+
paid?: boolean;
|
|
255
|
+
}, cancelToken?: CancelToken, headers?: Record<string, string>): Promise<any>;
|
|
256
|
+
fetchRoutes(companyGuid: string, body?: {
|
|
257
|
+
amt?: number;
|
|
258
|
+
known_ids?: string[];
|
|
259
|
+
unknown_ids?: string[];
|
|
260
|
+
query?: string;
|
|
261
|
+
offset?: number;
|
|
262
|
+
}, cancelToken?: CancelToken, headers?: Record<string, string>): Promise<any>;
|
|
263
|
+
sendEmail(emailId: string, formData: FormData, progressUpdateCallback?: (loaded: number, total: number) => void): Promise<void>;
|
|
264
|
+
createBill(companyGuid: string, data: {
|
|
265
|
+
line_items: LineItem[];
|
|
266
|
+
due_date: number;
|
|
267
|
+
users: string[];
|
|
268
|
+
custom_emails: [string, string][];
|
|
269
|
+
}, cancelToken?: CancelToken): Promise<any>;
|
|
26
270
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
1
2
|
import { StandardError } from '../types/error';
|
|
2
3
|
export class AvroQueryClient {
|
|
3
4
|
constructor(config) {
|
|
@@ -9,172 +10,17 @@ export class AvroQueryClient {
|
|
|
9
10
|
timeout: config.timeout ?? 0,
|
|
10
11
|
};
|
|
11
12
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return strategy(attempt);
|
|
15
|
-
}
|
|
16
|
-
else if (strategy === 'fixed') {
|
|
17
|
-
return 1000;
|
|
18
|
-
}
|
|
19
|
-
else if (strategy === 'exponential') {
|
|
20
|
-
return Math.pow(2, attempt) * 100;
|
|
21
|
-
}
|
|
22
|
-
throw new Error(`Invalid retry strategy: ${strategy}`);
|
|
13
|
+
get(path, cancelToken, headers = {}, progressUpdateCallback) {
|
|
14
|
+
return this._xhr('GET', path, null, cancelToken, headers, true, this.config.maxRetries, progressUpdateCallback);
|
|
23
15
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (cancelToken?.isCancelled()) {
|
|
27
|
-
return new StandardError(0, 'Request cancelled');
|
|
28
|
-
}
|
|
29
|
-
return null;
|
|
30
|
-
};
|
|
31
|
-
return this.config.authManager.accessToken().then(token => {
|
|
32
|
-
return new Promise((resolve, reject) => {
|
|
33
|
-
const cancelErr = checkCancelled();
|
|
34
|
-
if (cancelErr)
|
|
35
|
-
return reject(cancelErr);
|
|
36
|
-
const xhr = new XMLHttpRequest();
|
|
37
|
-
const url = this.config.baseUrl + path;
|
|
38
|
-
xhr.open(method, url, true);
|
|
39
|
-
if (token) {
|
|
40
|
-
xhr.setRequestHeader('Authorization', `Bearer ${token}`);
|
|
41
|
-
}
|
|
42
|
-
Object.entries(headers).forEach(([key, value]) => {
|
|
43
|
-
xhr.setRequestHeader(key, value);
|
|
44
|
-
});
|
|
45
|
-
xhr.onload = () => {
|
|
46
|
-
const cancelErr = checkCancelled();
|
|
47
|
-
if (cancelErr)
|
|
48
|
-
return reject(cancelErr);
|
|
49
|
-
if (xhr.status === 401 && this.config.authManager.refreshTokens && retryCount === 0) {
|
|
50
|
-
this.config.authManager
|
|
51
|
-
.refreshTokens()
|
|
52
|
-
.then(() => {
|
|
53
|
-
this._xhr(method, path, body, cancelToken, headers, isIdempotent, retryCount + 1).then(resolve, reject);
|
|
54
|
-
})
|
|
55
|
-
.catch(() => {
|
|
56
|
-
reject(new StandardError(401, 'Unauthorized (refresh failed)'));
|
|
57
|
-
});
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
if (xhr.status >= 200 && xhr.status < 300) {
|
|
61
|
-
try {
|
|
62
|
-
resolve(JSON.parse(xhr.responseText));
|
|
63
|
-
}
|
|
64
|
-
catch {
|
|
65
|
-
resolve(xhr.responseText);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
if (retryCount < this.config.maxRetries) {
|
|
70
|
-
const delay = this.getDelay(this.config.retryStrategy, retryCount);
|
|
71
|
-
setTimeout(() => {
|
|
72
|
-
this._xhr(method, path, body, cancelToken, headers, isIdempotent, retryCount + 1).then(resolve, reject);
|
|
73
|
-
}, delay);
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
let msg = xhr.statusText;
|
|
77
|
-
try {
|
|
78
|
-
const parsed = JSON.parse(xhr.responseText);
|
|
79
|
-
msg = parsed.message || msg;
|
|
80
|
-
}
|
|
81
|
-
catch {
|
|
82
|
-
console.warn('Failed to parse error response:', xhr.responseText);
|
|
83
|
-
}
|
|
84
|
-
reject(new StandardError(xhr.status, msg));
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
xhr.onerror = () => {
|
|
89
|
-
if (retryCount < this.config.maxRetries) {
|
|
90
|
-
const delay = this.getDelay(this.config.retryStrategy, retryCount);
|
|
91
|
-
setTimeout(() => {
|
|
92
|
-
this._xhr(method, path, body, cancelToken, headers, isIdempotent, retryCount + 1).then(resolve, reject);
|
|
93
|
-
}, delay);
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
reject(new StandardError(0, 'Network Error'));
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
if (this.config.timeout) {
|
|
100
|
-
xhr.timeout = this.config.timeout;
|
|
101
|
-
xhr.ontimeout = () => reject(new StandardError(0, 'Request timed out'));
|
|
102
|
-
}
|
|
103
|
-
xhr.send(body);
|
|
104
|
-
});
|
|
105
|
-
});
|
|
16
|
+
post(path, data, cancelToken, headers = {}, progressUpdateCallback) {
|
|
17
|
+
return this._xhr('POST', path, data, cancelToken, headers, false, this.config.maxRetries, progressUpdateCallback);
|
|
106
18
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
if (cancelToken?.isCancelled()) {
|
|
110
|
-
return new StandardError(0, 'Request cancelled');
|
|
111
|
-
}
|
|
112
|
-
return null;
|
|
113
|
-
};
|
|
114
|
-
return this.config.authManager.accessToken().then(token => {
|
|
115
|
-
const cancelErr = checkCancelled();
|
|
116
|
-
if (cancelErr)
|
|
117
|
-
return Promise.reject(cancelErr);
|
|
118
|
-
const url = this.config.baseUrl + path;
|
|
119
|
-
const requestHeaders = {
|
|
120
|
-
'Content-Type': 'application/json',
|
|
121
|
-
...headers,
|
|
122
|
-
};
|
|
123
|
-
if (token) {
|
|
124
|
-
requestHeaders['Authorization'] = `Bearer ${token}`;
|
|
125
|
-
}
|
|
126
|
-
const options = {
|
|
127
|
-
method,
|
|
128
|
-
headers: requestHeaders,
|
|
129
|
-
body: body ? JSON.stringify(body) : null,
|
|
130
|
-
};
|
|
131
|
-
return fetch(url, options).then(response => {
|
|
132
|
-
if (response.status === 401 && this.config.authManager.refreshTokens && retryCount === 0) {
|
|
133
|
-
return this.config.authManager
|
|
134
|
-
.refreshTokens()
|
|
135
|
-
.then(() => this._fetch(method, path, body, cancelToken, headers, isIdempotent, retryCount + 1))
|
|
136
|
-
.catch(() => Promise.reject(new StandardError(401, 'Unauthorized (refresh failed)')));
|
|
137
|
-
}
|
|
138
|
-
if (!response.ok) {
|
|
139
|
-
if (retryCount < this.config.maxRetries) {
|
|
140
|
-
const delay = this.getDelay(this.config.retryStrategy, retryCount);
|
|
141
|
-
return new Promise((resolve, reject) => {
|
|
142
|
-
setTimeout(() => {
|
|
143
|
-
this._fetch(method, path, body, cancelToken, headers, isIdempotent, retryCount + 1)
|
|
144
|
-
.then(resolve)
|
|
145
|
-
.catch(reject);
|
|
146
|
-
}, delay);
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
return response.text().then(text => {
|
|
151
|
-
let msg = response.statusText;
|
|
152
|
-
try {
|
|
153
|
-
const parsed = JSON.parse(text);
|
|
154
|
-
msg = parsed.message || msg;
|
|
155
|
-
}
|
|
156
|
-
catch {
|
|
157
|
-
console.warn('Failed to parse error response:', text);
|
|
158
|
-
}
|
|
159
|
-
throw new StandardError(response.status, msg);
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
return response.json();
|
|
164
|
-
});
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
get(path, cancelToken, headers = {}) {
|
|
168
|
-
return this._xhr('GET', path, null, cancelToken, headers, true);
|
|
169
|
-
}
|
|
170
|
-
post(path, data, cancelToken, headers = {}) {
|
|
171
|
-
return this._xhr('POST', path, data, cancelToken, headers, false);
|
|
19
|
+
put(path, data, cancelToken, headers = {}, progressUpdateCallback) {
|
|
20
|
+
return this._xhr('PUT', path, data, cancelToken, headers, true, this.config.maxRetries, progressUpdateCallback);
|
|
172
21
|
}
|
|
173
|
-
|
|
174
|
-
return this._xhr('
|
|
175
|
-
}
|
|
176
|
-
delete(path, cancelToken, headers = {}) {
|
|
177
|
-
return this._xhr('DELETE', path, null, cancelToken, headers, false);
|
|
22
|
+
delete(path, cancelToken, headers = {}, progressUpdateCallback) {
|
|
23
|
+
return this._xhr('DELETE', path, null, cancelToken, headers, false, this.config.maxRetries, progressUpdateCallback);
|
|
178
24
|
}
|
|
179
25
|
login(data, cancelToken) {
|
|
180
26
|
return this._fetch('POST', '/login', data, cancelToken)
|
|
@@ -189,25 +35,32 @@ export class AvroQueryClient {
|
|
|
189
35
|
throw new StandardError(401, 'Login failed');
|
|
190
36
|
});
|
|
191
37
|
}
|
|
192
|
-
|
|
193
|
-
return this.
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
38
|
+
setTokens(tokens) {
|
|
39
|
+
return this.config.authManager.setTokens(tokens);
|
|
40
|
+
}
|
|
41
|
+
clearTokens() {
|
|
42
|
+
return this.config.authManager.clearTokens();
|
|
43
|
+
}
|
|
44
|
+
useLogout() {
|
|
45
|
+
const queryClient = useQueryClient();
|
|
46
|
+
return useMutation({
|
|
47
|
+
mutationFn: (cancelToken) => this._fetch('POST', '/logout', null, cancelToken)
|
|
48
|
+
.then(() => this.config.authManager.clearTokens()),
|
|
49
|
+
onSettled: () => {
|
|
50
|
+
queryClient.invalidateQueries();
|
|
51
|
+
},
|
|
52
|
+
onError: (err) => {
|
|
53
|
+
this.config.authManager.clearTokens();
|
|
54
|
+
console.error('Logout failed:', err);
|
|
55
|
+
throw new StandardError(500, 'Logout failed');
|
|
56
|
+
}
|
|
198
57
|
});
|
|
199
58
|
}
|
|
200
|
-
fetchJobs(companyGuid,
|
|
201
|
-
|
|
202
|
-
amt,
|
|
203
|
-
known_ids: knownIds,
|
|
204
|
-
unknown_ids: unknownIds,
|
|
205
|
-
query: keyword,
|
|
206
|
-
};
|
|
207
|
-
if (!companyGuid) {
|
|
59
|
+
fetchJobs(companyGuid, body = {}, cancelToken, headers = {}) {
|
|
60
|
+
if (!companyGuid || companyGuid.trim() === '') {
|
|
208
61
|
return Promise.reject(new StandardError(400, 'Company GUID is required'));
|
|
209
62
|
}
|
|
210
|
-
return this._fetch('POST', `/company/${companyGuid}/jobs
|
|
63
|
+
return this._fetch('POST', `/company/${companyGuid}/jobs`, body, cancelToken, headers)
|
|
211
64
|
.then(response => {
|
|
212
65
|
if (!response || !Array.isArray(response)) {
|
|
213
66
|
throw new StandardError(400, 'Invalid jobs response');
|
|
@@ -219,4 +72,97 @@ export class AvroQueryClient {
|
|
|
219
72
|
throw new StandardError(500, 'Failed to fetch jobs');
|
|
220
73
|
});
|
|
221
74
|
}
|
|
75
|
+
fetchEvents(companyGuid, body = {}, cancelToken, headers = {}) {
|
|
76
|
+
if (!companyGuid || companyGuid.trim() === '') {
|
|
77
|
+
return Promise.reject(new StandardError(400, 'Company GUID is required'));
|
|
78
|
+
}
|
|
79
|
+
return this._fetch('POST', `/company/${companyGuid}/events`, body, cancelToken, headers)
|
|
80
|
+
.then(response => {
|
|
81
|
+
if (!response || !Array.isArray(response)) {
|
|
82
|
+
throw new StandardError(400, 'Invalid events response');
|
|
83
|
+
}
|
|
84
|
+
return response;
|
|
85
|
+
})
|
|
86
|
+
.catch(err => {
|
|
87
|
+
console.error('Failed to fetch events:', err);
|
|
88
|
+
throw new StandardError(500, 'Failed to fetch events');
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
fetchMonths(companyGuid, body = {}, cancelToken, headers = {}) {
|
|
92
|
+
if (!companyGuid || companyGuid.trim() === '') {
|
|
93
|
+
return Promise.reject(new StandardError(400, 'Company GUID is required'));
|
|
94
|
+
}
|
|
95
|
+
return this._fetch('POST', `/company/${companyGuid}/months`, body, cancelToken, headers)
|
|
96
|
+
.then(response => {
|
|
97
|
+
if (!response || !Array.isArray(response)) {
|
|
98
|
+
throw new StandardError(400, 'Invalid months response');
|
|
99
|
+
}
|
|
100
|
+
return response;
|
|
101
|
+
})
|
|
102
|
+
.catch(err => {
|
|
103
|
+
console.error('Failed to fetch months:', err);
|
|
104
|
+
throw new StandardError(500, 'Failed to fetch months');
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
fetchBills(companyGuid, body = {}, cancelToken, headers = {}) {
|
|
108
|
+
if (!companyGuid || companyGuid.trim() === '') {
|
|
109
|
+
return Promise.reject(new StandardError(400, 'Company GUID is required'));
|
|
110
|
+
}
|
|
111
|
+
return this._fetch('POST', `/company/${companyGuid}/bills`, body, cancelToken, headers)
|
|
112
|
+
.then(response => {
|
|
113
|
+
if (!response || !Array.isArray(response)) {
|
|
114
|
+
throw new StandardError(400, 'Invalid bills response');
|
|
115
|
+
}
|
|
116
|
+
return response;
|
|
117
|
+
})
|
|
118
|
+
.catch(err => {
|
|
119
|
+
console.error('Failed to fetch bills:', err);
|
|
120
|
+
throw new StandardError(500, 'Failed to fetch bills');
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
fetchRoutes(companyGuid, body = {}, cancelToken, headers = {}) {
|
|
124
|
+
if (!companyGuid || companyGuid.trim() === '') {
|
|
125
|
+
return Promise.reject(new StandardError(400, 'Company GUID is required'));
|
|
126
|
+
}
|
|
127
|
+
return this._fetch('POST', `/company/${companyGuid}/routes`, body, cancelToken, headers)
|
|
128
|
+
.then(response => {
|
|
129
|
+
if (!response || !Array.isArray(response)) {
|
|
130
|
+
throw new StandardError(400, 'Invalid routes response');
|
|
131
|
+
}
|
|
132
|
+
return response;
|
|
133
|
+
})
|
|
134
|
+
.catch(err => {
|
|
135
|
+
console.error('Failed to fetch routes:', err);
|
|
136
|
+
throw new StandardError(500, 'Failed to fetch routes');
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
sendEmail(emailId, formData, progressUpdateCallback) {
|
|
140
|
+
try {
|
|
141
|
+
return this.post(`/email/${emailId}`, formData, undefined, {}, progressUpdateCallback);
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
throw new StandardError(500, `Failed to send email: ${error}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
createBill(companyGuid, data, cancelToken) {
|
|
148
|
+
if (!companyGuid) {
|
|
149
|
+
return Promise.reject(new StandardError(400, 'Company GUID is required'));
|
|
150
|
+
}
|
|
151
|
+
const body = {
|
|
152
|
+
events: data.line_items.filter(item => item.line_item_type === 'EVENT').map(item => item.id),
|
|
153
|
+
months: data.line_items.filter(item => item.line_item_type === 'SERVICE_MONTH').map(item => item.id),
|
|
154
|
+
line_items: data.line_items.filter(item => item.line_item_type === 'CUSTOM'),
|
|
155
|
+
manual_emails: data.custom_emails,
|
|
156
|
+
users: data.users,
|
|
157
|
+
due_date: data.due_date,
|
|
158
|
+
};
|
|
159
|
+
try {
|
|
160
|
+
return this._xhr('POST', `/company/${companyGuid}/bill`, JSON.stringify(body), cancelToken, {
|
|
161
|
+
'Content-Type': 'application/json',
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
throw new StandardError(500, `Failed to create bill: ${error}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
222
168
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|