@go-avro/avro-js 0.0.2-beta.143 → 0.0.2-beta.145
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 +3 -3
- package/dist/auth/AuthManager.js +11 -19
- package/dist/client/QueryClient.d.ts +18 -11
- package/dist/client/QueryClient.js +40 -58
- package/dist/client/core/fetch.js +4 -2
- package/dist/client/core/xhr.js +8 -2
- package/dist/client/hooks/companies.js +3 -0
- package/dist/client/hooks/proposal.d.ts +1 -0
- package/dist/client/hooks/proposal.js +15 -0
- package/dist/client/hooks/users.js +27 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/types/api.d.ts +1 -0
- package/dist/types/auth.d.ts +6 -0
- package/dist/types/auth.js +5 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Tokens } from '../types/auth';
|
|
1
|
+
import { AuthState, Tokens } from '../types/auth';
|
|
2
2
|
import { Cache, CacheData } from '../types/cache';
|
|
3
3
|
export declare class AuthManager {
|
|
4
4
|
private storages;
|
|
@@ -9,12 +9,12 @@ export declare class AuthManager {
|
|
|
9
9
|
baseUrl: string;
|
|
10
10
|
storage: Cache | Cache[];
|
|
11
11
|
});
|
|
12
|
-
isAuthenticated(): Promise<
|
|
12
|
+
isAuthenticated(): Promise<AuthState>;
|
|
13
13
|
fetchNewTokens(): Promise<Tokens>;
|
|
14
14
|
accessToken(): Promise<string | undefined>;
|
|
15
15
|
onTokenRefreshed(callback: (accessToken: string) => void): void;
|
|
16
16
|
onTokenRefreshFailed(callback: () => void): void;
|
|
17
|
-
refreshTokens(): Promise<Tokens
|
|
17
|
+
refreshTokens(): Promise<Tokens>;
|
|
18
18
|
setTokens(tokens: Tokens): Promise<void>;
|
|
19
19
|
setCache(data: Partial<CacheData>): Promise<void>;
|
|
20
20
|
getCache(key?: keyof CacheData): Promise<CacheData | string | null>;
|
package/dist/auth/AuthManager.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AuthState } from '../types/auth';
|
|
1
2
|
import { StandardError } from '../types/error';
|
|
2
3
|
export class AuthManager {
|
|
3
4
|
constructor({ baseUrl, storage, }) {
|
|
@@ -30,7 +31,7 @@ export class AuthManager {
|
|
|
30
31
|
},
|
|
31
32
|
});
|
|
32
33
|
if (response.ok) {
|
|
33
|
-
return
|
|
34
|
+
return AuthState.AUTHENTICATED;
|
|
34
35
|
}
|
|
35
36
|
else {
|
|
36
37
|
// Attempt token refresh if validation fails
|
|
@@ -43,7 +44,7 @@ export class AuthManager {
|
|
|
43
44
|
'Authorization': `Bearer ${newTokens.access_token}`,
|
|
44
45
|
},
|
|
45
46
|
});
|
|
46
|
-
return retryResponse.ok;
|
|
47
|
+
return retryResponse.ok ? AuthState.AUTHENTICATED : AuthState.UNAUTHENTICATED;
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
}
|
|
@@ -52,7 +53,7 @@ export class AuthManager {
|
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
55
|
}
|
|
55
|
-
return
|
|
56
|
+
return AuthState.UNAUTHENTICATED;
|
|
56
57
|
}
|
|
57
58
|
async fetchNewTokens() {
|
|
58
59
|
for (const storage of this.storages) {
|
|
@@ -98,22 +99,13 @@ export class AuthManager {
|
|
|
98
99
|
this.tokenRefreshFailedCallbacks.push(callback);
|
|
99
100
|
}
|
|
100
101
|
async refreshTokens() {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
return newToken;
|
|
109
|
-
}
|
|
110
|
-
catch (error) {
|
|
111
|
-
this.tokenRefreshFailedCallbacks.forEach(cb => cb());
|
|
112
|
-
if (error?.status !== 410) {
|
|
113
|
-
console.error('Failed to refresh tokens:', error);
|
|
114
|
-
}
|
|
115
|
-
return null;
|
|
116
|
-
}
|
|
102
|
+
const newToken = await this.fetchNewTokens();
|
|
103
|
+
await Promise.all(this.storages.map(s => s.set(newToken)));
|
|
104
|
+
this.tokenRefreshedCallbacks.forEach(cb => {
|
|
105
|
+
if (newToken?.access_token)
|
|
106
|
+
cb(newToken.access_token);
|
|
107
|
+
});
|
|
108
|
+
return newToken;
|
|
117
109
|
}
|
|
118
110
|
async setTokens(tokens) {
|
|
119
111
|
await Promise.all(this.storages.map(s => s.set(tokens)));
|
|
@@ -2,7 +2,7 @@ import { Socket } from 'socket.io-client';
|
|
|
2
2
|
import { InfiniteData, QueryClient, UseInfiniteQueryResult, useMutation, UseQueryResult } from '@tanstack/react-query';
|
|
3
3
|
import { AuthManager } from '../auth/AuthManager';
|
|
4
4
|
import { _Event, ApiInfo, Avro, Bill, Break, Chat, Company, FinancialInsightData, Job, EventInsightData, LoginResponse, Message, Plan, Route, ServiceMonth, Session, Team, User, UserCompanyAssociation, Skill, Group, Label } from '../types/api';
|
|
5
|
-
import { Tokens } from '../types/auth';
|
|
5
|
+
import { AuthState, Tokens } from '../types/auth';
|
|
6
6
|
import { CancelToken, RetryStrategy } from '../types/client';
|
|
7
7
|
import { StandardError } from '../types/error';
|
|
8
8
|
import { CacheData } from '../types/cache';
|
|
@@ -102,6 +102,7 @@ declare module '../client/QueryClient' {
|
|
|
102
102
|
}, total: number, onProgress?: (fraction: number) => void): UseQueryResult<Group[], StandardError>;
|
|
103
103
|
useGetPlans(code: string): UseQueryResult<Plan[], StandardError>;
|
|
104
104
|
useGetCompanies(options?: {}): UseQueryResult<Company[], StandardError>;
|
|
105
|
+
useGetProposal(proposal_id: string): UseQueryResult<any, StandardError>;
|
|
105
106
|
useGetAnalytics(): UseQueryResult<any, StandardError>;
|
|
106
107
|
useFinanceAnalytics({ periods, cumulative }: {
|
|
107
108
|
periods: number[][];
|
|
@@ -122,6 +123,12 @@ declare module '../client/QueryClient' {
|
|
|
122
123
|
useGetUserSessions(): UseQueryResult<Session[], StandardError>;
|
|
123
124
|
useGetAvro(): UseQueryResult<Avro, StandardError>;
|
|
124
125
|
useSearchUsers(searchUsername: string): UseQueryResult<User[], StandardError>;
|
|
126
|
+
useCreateProposal(): ReturnType<typeof useMutation<{
|
|
127
|
+
id: string;
|
|
128
|
+
}, StandardError, {
|
|
129
|
+
job_id: string;
|
|
130
|
+
data: Record<string, any>;
|
|
131
|
+
}>>;
|
|
125
132
|
useCreateGroup(): ReturnType<typeof useMutation<{
|
|
126
133
|
id: string;
|
|
127
134
|
}, StandardError, {
|
|
@@ -276,6 +283,9 @@ declare module '../client/QueryClient' {
|
|
|
276
283
|
breakId: string;
|
|
277
284
|
updates: Partial<Break>;
|
|
278
285
|
}>>;
|
|
286
|
+
useUpdateSelf(): ReturnType<typeof useMutation<{
|
|
287
|
+
msg: string;
|
|
288
|
+
}, StandardError, Partial<User>>>;
|
|
279
289
|
useDeleteJob(): ReturnType<typeof useMutation<{
|
|
280
290
|
msg: string;
|
|
281
291
|
}, StandardError, {
|
|
@@ -342,17 +352,11 @@ declare module '../client/QueryClient' {
|
|
|
342
352
|
export declare class AvroQueryClient {
|
|
343
353
|
protected config: Required<AvroQueryClientConfig>;
|
|
344
354
|
readonly socket: Socket;
|
|
345
|
-
|
|
355
|
+
_authState: AuthState;
|
|
346
356
|
companyId: string | null;
|
|
347
357
|
company: Company | null;
|
|
348
|
-
private
|
|
349
|
-
private initializedListeners;
|
|
358
|
+
private authStateListeners;
|
|
350
359
|
constructor(config: AvroQueryClientConfig);
|
|
351
|
-
private computeInitialized;
|
|
352
|
-
private updateInitialized;
|
|
353
|
-
onInitializedChange(cb: (v: boolean) => void): () => void;
|
|
354
|
-
offInitializedChange(cb: (v: boolean) => void): void;
|
|
355
|
-
isInitialized(): boolean;
|
|
356
360
|
emit(eventName: string, data: unknown): void;
|
|
357
361
|
on<T>(eventName: string, callback: (data: T) => void): void;
|
|
358
362
|
off(eventName: string, callback?: Function): void;
|
|
@@ -390,8 +394,11 @@ export declare class AvroQueryClient {
|
|
|
390
394
|
setCompanyId(companyId: string): Promise<void[]>;
|
|
391
395
|
getCompanyId(): Promise<string | null>;
|
|
392
396
|
clearCache(): Promise<void>;
|
|
393
|
-
|
|
394
|
-
|
|
397
|
+
onAuthStateChange(cb: (v: AuthState) => void): () => void;
|
|
398
|
+
offAuthStateChange(cb: (v: AuthState) => void): void;
|
|
399
|
+
setAuthState(state: AuthState): void;
|
|
400
|
+
getAuthState(): AuthState;
|
|
401
|
+
getAuthStateAsync(): Promise<AuthState>;
|
|
395
402
|
getQueryClient(): QueryClient;
|
|
396
403
|
useLogout(): ReturnType<typeof useMutation<void, StandardError, CancelToken | undefined>>;
|
|
397
404
|
fetchJobs(body?: {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import io from 'socket.io-client';
|
|
2
2
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
3
3
|
import { LoginResponse } from '../types/api';
|
|
4
|
+
import { AuthState } from '../types/auth';
|
|
4
5
|
import { StandardError } from '../types/error';
|
|
5
6
|
export class AvroQueryClient {
|
|
6
7
|
constructor(config) {
|
|
7
|
-
this.
|
|
8
|
+
this._authState = AuthState.UNKNOWN;
|
|
8
9
|
this.companyId = null;
|
|
9
10
|
this.company = null;
|
|
10
|
-
this.
|
|
11
|
-
this.initializedListeners = [];
|
|
11
|
+
this.authStateListeners = [];
|
|
12
12
|
this.config = {
|
|
13
13
|
baseUrl: config.baseUrl,
|
|
14
14
|
authManager: config.authManager,
|
|
@@ -18,80 +18,45 @@ export class AvroQueryClient {
|
|
|
18
18
|
};
|
|
19
19
|
this.socket = io(config.baseUrl, { autoConnect: false, transports: ["websocket"], });
|
|
20
20
|
config.authManager.isAuthenticated().then(isAuth => {
|
|
21
|
-
this.
|
|
21
|
+
this.setAuthState(isAuth);
|
|
22
22
|
this.getCompanyId().then(id => {
|
|
23
23
|
this.companyId = id;
|
|
24
|
-
this.updateInitialized();
|
|
25
24
|
});
|
|
25
|
+
if (!this.socket.connected && isAuth === AuthState.AUTHENTICATED) {
|
|
26
|
+
this.config.authManager.accessToken().then(token => {
|
|
27
|
+
console.log('Initializing socket connection with token:', token);
|
|
28
|
+
this.socket.auth = { token: token };
|
|
29
|
+
this.socket.connect();
|
|
30
|
+
}).catch(err => {
|
|
31
|
+
console.error('Not logged in:', err);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
26
34
|
});
|
|
27
|
-
if (!this.socket.connected) {
|
|
28
|
-
this.config.authManager.accessToken().then(token => {
|
|
29
|
-
console.log('Initializing socket connection with token...');
|
|
30
|
-
this.socket.auth = { token: token };
|
|
31
|
-
this.socket.connect();
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
35
|
this.socket.on('connect', () => {
|
|
35
|
-
this.
|
|
36
|
+
this.setAuthState(AuthState.AUTHENTICATED);
|
|
36
37
|
console.log(`Socket connected with ID: ${this.socket?.id}`);
|
|
37
|
-
this.updateInitialized();
|
|
38
38
|
});
|
|
39
39
|
this.socket.on('disconnect', (reason) => {
|
|
40
40
|
console.log(`Socket disconnected: ${reason}`);
|
|
41
|
-
this.updateInitialized();
|
|
42
41
|
});
|
|
43
42
|
this.socket.on('connect_error', (err) => {
|
|
44
43
|
console.error(`Socket connection error: ${err.message}`);
|
|
45
44
|
});
|
|
46
45
|
this.config.authManager.onTokenRefreshed((newAccessToken) => {
|
|
47
46
|
if (this.socket && newAccessToken) {
|
|
48
|
-
this.
|
|
47
|
+
this.setAuthState(AuthState.AUTHENTICATED);
|
|
49
48
|
console.log('Access token refreshed, updating socket auth...');
|
|
50
49
|
this.socket.auth = { token: newAccessToken };
|
|
51
50
|
this.socket.disconnect().connect();
|
|
52
51
|
}
|
|
53
52
|
});
|
|
54
53
|
config.authManager.onTokenRefreshFailed(() => {
|
|
55
|
-
this.
|
|
54
|
+
this.setAuthState(AuthState.UNAUTHENTICATED);
|
|
56
55
|
if (this.socket && this.socket.connected) {
|
|
57
56
|
this.socket.disconnect();
|
|
58
57
|
}
|
|
59
58
|
});
|
|
60
59
|
}
|
|
61
|
-
computeInitialized() {
|
|
62
|
-
return !!(this.socket?.connected && this.companyId !== null);
|
|
63
|
-
}
|
|
64
|
-
updateInitialized() {
|
|
65
|
-
const next = this.computeInitialized();
|
|
66
|
-
if (this.initialized !== next) {
|
|
67
|
-
this.initialized = next;
|
|
68
|
-
this.initializedListeners.forEach(cb => {
|
|
69
|
-
try {
|
|
70
|
-
cb(next);
|
|
71
|
-
}
|
|
72
|
-
catch (_) {
|
|
73
|
-
console.error(_);
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
onInitializedChange(cb) {
|
|
79
|
-
this.initializedListeners.push(cb);
|
|
80
|
-
// call immediately with current value
|
|
81
|
-
try {
|
|
82
|
-
cb(this.initialized);
|
|
83
|
-
}
|
|
84
|
-
catch (_) {
|
|
85
|
-
console.error(_);
|
|
86
|
-
}
|
|
87
|
-
return () => this.offInitializedChange(cb);
|
|
88
|
-
}
|
|
89
|
-
offInitializedChange(cb) {
|
|
90
|
-
this.initializedListeners = this.initializedListeners.filter(c => c !== cb);
|
|
91
|
-
}
|
|
92
|
-
isInitialized() {
|
|
93
|
-
return this.initialized;
|
|
94
|
-
}
|
|
95
60
|
emit(eventName, data) {
|
|
96
61
|
if (!this.socket?.connected) {
|
|
97
62
|
console.error('Socket is not connected. Cannot emit event.');
|
|
@@ -128,7 +93,7 @@ export class AvroQueryClient {
|
|
|
128
93
|
}
|
|
129
94
|
throw new StandardError(401, 'Invalid login response');
|
|
130
95
|
}
|
|
131
|
-
this.
|
|
96
|
+
this.setAuthState(AuthState.AUTHENTICATED);
|
|
132
97
|
this.socket.auth = { token: resp.access_token };
|
|
133
98
|
if (!this.socket.connected) {
|
|
134
99
|
this.socket.connect();
|
|
@@ -185,7 +150,7 @@ export class AvroQueryClient {
|
|
|
185
150
|
}
|
|
186
151
|
throw new StandardError(401, 'Invalid Google login response');
|
|
187
152
|
}
|
|
188
|
-
this.
|
|
153
|
+
this.setAuthState(AuthState.AUTHENTICATED);
|
|
189
154
|
this.socket.auth = { token: resp.access_token };
|
|
190
155
|
if (!this.socket.connected) {
|
|
191
156
|
this.socket.connect();
|
|
@@ -213,7 +178,6 @@ export class AvroQueryClient {
|
|
|
213
178
|
}
|
|
214
179
|
setCompanyId(companyId) {
|
|
215
180
|
this.companyId = companyId;
|
|
216
|
-
this.updateInitialized();
|
|
217
181
|
return this.config.authManager.setCompanyId(companyId);
|
|
218
182
|
}
|
|
219
183
|
getCompanyId() {
|
|
@@ -225,10 +189,28 @@ export class AvroQueryClient {
|
|
|
225
189
|
clearCache() {
|
|
226
190
|
return this.config.authManager.clearCache();
|
|
227
191
|
}
|
|
228
|
-
|
|
229
|
-
|
|
192
|
+
onAuthStateChange(cb) {
|
|
193
|
+
this.authStateListeners.push(cb);
|
|
194
|
+
// call immediately with current value
|
|
195
|
+
try {
|
|
196
|
+
cb(this._authState);
|
|
197
|
+
}
|
|
198
|
+
catch (_) {
|
|
199
|
+
console.error(_);
|
|
200
|
+
}
|
|
201
|
+
return () => this.offAuthStateChange(cb);
|
|
202
|
+
}
|
|
203
|
+
offAuthStateChange(cb) {
|
|
204
|
+
this.authStateListeners = this.authStateListeners.filter(c => c !== cb);
|
|
205
|
+
}
|
|
206
|
+
setAuthState(state) {
|
|
207
|
+
this.authStateListeners.forEach(cb => cb(state));
|
|
208
|
+
this._authState = state;
|
|
209
|
+
}
|
|
210
|
+
getAuthState() {
|
|
211
|
+
return this._authState;
|
|
230
212
|
}
|
|
231
|
-
|
|
213
|
+
getAuthStateAsync() {
|
|
232
214
|
return this.config.authManager.isAuthenticated();
|
|
233
215
|
}
|
|
234
216
|
getQueryClient() {
|
|
@@ -245,7 +227,7 @@ export class AvroQueryClient {
|
|
|
245
227
|
}
|
|
246
228
|
},
|
|
247
229
|
onSettled: () => {
|
|
248
|
-
this.
|
|
230
|
+
this.setAuthState(AuthState.UNAUTHENTICATED);
|
|
249
231
|
this.clearCache();
|
|
250
232
|
queryClient.invalidateQueries();
|
|
251
233
|
},
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AvroQueryClient } from '../../client/QueryClient';
|
|
2
2
|
import { StandardError } from '../../types/error';
|
|
3
|
+
import { AuthState } from '../../types/auth';
|
|
3
4
|
AvroQueryClient.prototype._fetch = async function (method, path, body, cancelToken, headers = {}, isIdempotent = false, retryCount = 0) {
|
|
4
5
|
const checkCancelled = () => {
|
|
5
6
|
try {
|
|
@@ -13,7 +14,7 @@ AvroQueryClient.prototype._fetch = async function (method, path, body, cancelTok
|
|
|
13
14
|
};
|
|
14
15
|
try {
|
|
15
16
|
checkCancelled();
|
|
16
|
-
const token = await this.config.authManager.accessToken();
|
|
17
|
+
const token = this.getAuthState() === AuthState.AUTHENTICATED ? await this.config.authManager.accessToken() : undefined;
|
|
17
18
|
checkCancelled();
|
|
18
19
|
const url = this.config.baseUrl + path;
|
|
19
20
|
const requestHeaders = {
|
|
@@ -37,7 +38,7 @@ AvroQueryClient.prototype._fetch = async function (method, path, body, cancelTok
|
|
|
37
38
|
await this.config.authManager.refreshTokens();
|
|
38
39
|
return this._fetch(method, path, body, cancelToken, headers, isIdempotent, 1);
|
|
39
40
|
}
|
|
40
|
-
if (retryCount < this.config.maxRetries) {
|
|
41
|
+
if (response.status !== 401 && retryCount < this.config.maxRetries) {
|
|
41
42
|
const delay = this.getDelay(this.config.retryStrategy, retryCount);
|
|
42
43
|
await this.sleep(delay);
|
|
43
44
|
return this._fetch(method, path, body, cancelToken, headers, isIdempotent, retryCount + 1);
|
|
@@ -57,6 +58,7 @@ AvroQueryClient.prototype._fetch = async function (method, path, body, cancelTok
|
|
|
57
58
|
throw error;
|
|
58
59
|
}
|
|
59
60
|
const message = error instanceof Error ? error.message : String(error);
|
|
61
|
+
console.error('Fetch error:', message);
|
|
60
62
|
throw new StandardError(0, `Request failed: ${message}`);
|
|
61
63
|
}
|
|
62
64
|
};
|
package/dist/client/core/xhr.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AvroQueryClient } from '../../client/QueryClient';
|
|
2
2
|
import { StandardError } from '../../types/error';
|
|
3
|
+
import { AuthState } from '../../types/auth';
|
|
3
4
|
AvroQueryClient.prototype._xhr = async function (method, path, body, cancelToken, headers = {}, isIdempotent = false, retryCount = 0, progressUpdateCallback) {
|
|
4
5
|
const checkCancelled = () => {
|
|
5
6
|
if (cancelToken?.isCancelled()) {
|
|
@@ -9,7 +10,7 @@ AvroQueryClient.prototype._xhr = async function (method, path, body, cancelToken
|
|
|
9
10
|
for (let attempt = 0; attempt <= this.config.maxRetries; attempt++) {
|
|
10
11
|
try {
|
|
11
12
|
checkCancelled();
|
|
12
|
-
const token = await this.config.authManager.accessToken();
|
|
13
|
+
const token = this.getAuthState() === AuthState.AUTHENTICATED ? await this.config.authManager.accessToken() : undefined;
|
|
13
14
|
checkCancelled();
|
|
14
15
|
const result = await new Promise((resolve, reject) => {
|
|
15
16
|
const xhr = new XMLHttpRequest();
|
|
@@ -60,11 +61,14 @@ AvroQueryClient.prototype._xhr = async function (method, path, body, cancelToken
|
|
|
60
61
|
return result;
|
|
61
62
|
}
|
|
62
63
|
catch (error) {
|
|
64
|
+
console.error('xhr error:', error);
|
|
63
65
|
if (!(error instanceof StandardError)) {
|
|
64
66
|
const message = error instanceof Error ? error.message : String(error);
|
|
67
|
+
console.error('Non-StandardError caught:', message);
|
|
65
68
|
throw new StandardError(0, `An unexpected error occurred: ${message}`);
|
|
66
69
|
}
|
|
67
70
|
if (error.status === 401 && this.config.authManager.refreshTokens && attempt === 0) {
|
|
71
|
+
console.log('Attempting to refresh tokens due to 401 response');
|
|
68
72
|
try {
|
|
69
73
|
await this.config.authManager.refreshTokens();
|
|
70
74
|
continue;
|
|
@@ -73,10 +77,12 @@ AvroQueryClient.prototype._xhr = async function (method, path, body, cancelToken
|
|
|
73
77
|
throw new StandardError(401, 'Unauthorized (refresh failed)');
|
|
74
78
|
}
|
|
75
79
|
}
|
|
76
|
-
if (attempt >= this.config.maxRetries) {
|
|
80
|
+
if (error.status === 401 || attempt >= this.config.maxRetries) {
|
|
81
|
+
console.error('Not retrying request, throwing error.');
|
|
77
82
|
throw error;
|
|
78
83
|
}
|
|
79
84
|
const delay = this.getDelay(this.config.retryStrategy, attempt);
|
|
85
|
+
console.error(`Retrying request in ${delay} ms...`);
|
|
80
86
|
await this.sleep(delay);
|
|
81
87
|
}
|
|
82
88
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { useMutation, useQuery } from '@tanstack/react-query';
|
|
2
2
|
import { AvroQueryClient } from '../../client/QueryClient';
|
|
3
|
+
import { AuthState } from '../../types/auth';
|
|
3
4
|
AvroQueryClient.prototype.useGetCompanies = function (options = {}) {
|
|
4
5
|
return useQuery({
|
|
5
6
|
queryKey: ['/company/list'],
|
|
6
7
|
queryFn: () => this.get('/company/list'),
|
|
8
|
+
enabled: this.getAuthState() === AuthState.AUTHENTICATED,
|
|
7
9
|
...options,
|
|
8
10
|
});
|
|
9
11
|
};
|
|
@@ -33,6 +35,7 @@ AvroQueryClient.prototype.useGetCurrentCompany = function () {
|
|
|
33
35
|
this.company = await this.get(`/company/${this.companyId}`);
|
|
34
36
|
return this.company;
|
|
35
37
|
},
|
|
38
|
+
enabled: this.getAuthState() === AuthState.AUTHENTICATED,
|
|
36
39
|
});
|
|
37
40
|
};
|
|
38
41
|
AvroQueryClient.prototype.useCreateCompany = function () {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { AvroQueryClient } from "../../client/QueryClient";
|
|
2
|
+
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
3
|
+
AvroQueryClient.prototype.useCreateProposal = function () {
|
|
4
|
+
return useMutation({
|
|
5
|
+
mutationFn: async ({ job_id, data }) => {
|
|
6
|
+
return this.post(`/job/${job_id}/proposal`, JSON.stringify(data), undefined, { "Content-Type": "application/json" });
|
|
7
|
+
},
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
AvroQueryClient.prototype.useGetProposal = function (proposal_id) {
|
|
11
|
+
return useQuery({
|
|
12
|
+
queryKey: ['proposal', proposal_id],
|
|
13
|
+
queryFn: async () => this.get(`/proposal/${proposal_id}`),
|
|
14
|
+
});
|
|
15
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
2
2
|
import { AvroQueryClient } from "../../client/QueryClient";
|
|
3
|
+
import { AuthState } from "../../types/auth";
|
|
3
4
|
AvroQueryClient.prototype.useGetUser = function (userId) {
|
|
4
5
|
return useQuery({
|
|
5
6
|
queryKey: ['user', userId],
|
|
@@ -22,7 +23,7 @@ AvroQueryClient.prototype.useGetSelf = function () {
|
|
|
22
23
|
return useQuery({
|
|
23
24
|
queryKey: ['user'],
|
|
24
25
|
queryFn: () => this.get(`/user`),
|
|
25
|
-
enabled:
|
|
26
|
+
enabled: this.getAuthState() === AuthState.AUTHENTICATED,
|
|
26
27
|
});
|
|
27
28
|
};
|
|
28
29
|
AvroQueryClient.prototype.useCreateSelf = function () {
|
|
@@ -36,6 +37,31 @@ AvroQueryClient.prototype.useCreateSelf = function () {
|
|
|
36
37
|
},
|
|
37
38
|
});
|
|
38
39
|
};
|
|
40
|
+
AvroQueryClient.prototype.useUpdateSelf = function () {
|
|
41
|
+
const queryClient = this.getQueryClient();
|
|
42
|
+
return useMutation({
|
|
43
|
+
mutationFn: async (data) => {
|
|
44
|
+
return this.put(`/user`, JSON.stringify(data), undefined, { "Content-Type": "application/json" });
|
|
45
|
+
},
|
|
46
|
+
// Optimistically update the user data in the cache
|
|
47
|
+
onMutate: async (data) => {
|
|
48
|
+
await queryClient.cancelQueries({ queryKey: ['user'] });
|
|
49
|
+
const previousUser = queryClient.getQueryData(['user']);
|
|
50
|
+
if (previousUser) {
|
|
51
|
+
queryClient.setQueryData(['user'], { ...previousUser, ...data });
|
|
52
|
+
}
|
|
53
|
+
return { previousUser };
|
|
54
|
+
},
|
|
55
|
+
onError: (err, _, context) => {
|
|
56
|
+
if (context?.previousUser) {
|
|
57
|
+
queryClient.setQueryData(['user'], context.previousUser);
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
onSettled: () => {
|
|
61
|
+
queryClient.invalidateQueries({ queryKey: ['user'] });
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
};
|
|
39
65
|
AvroQueryClient.prototype.useUpdateUserCompany = function () {
|
|
40
66
|
const queryClient = this.getQueryClient();
|
|
41
67
|
return useMutation({
|
package/dist/index.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ import './client/hooks/teams';
|
|
|
23
23
|
import './client/hooks/labels';
|
|
24
24
|
import './client/hooks/groups';
|
|
25
25
|
import './client/hooks/skills';
|
|
26
|
+
import './client/hooks/proposal';
|
|
26
27
|
export * from './types/api';
|
|
27
28
|
export * from './types/auth';
|
|
28
29
|
export * from './types/cache';
|
package/dist/index.js
CHANGED
|
@@ -23,6 +23,7 @@ import './client/hooks/teams';
|
|
|
23
23
|
import './client/hooks/labels';
|
|
24
24
|
import './client/hooks/groups';
|
|
25
25
|
import './client/hooks/skills';
|
|
26
|
+
import './client/hooks/proposal';
|
|
26
27
|
export * from './types/api';
|
|
27
28
|
export * from './types/auth';
|
|
28
29
|
export * from './types/cache';
|
package/dist/types/api.d.ts
CHANGED
|
@@ -213,6 +213,7 @@ export interface User {
|
|
|
213
213
|
phone_number: string | null;
|
|
214
214
|
time_created: number;
|
|
215
215
|
time_updated: number | null;
|
|
216
|
+
share_location: boolean;
|
|
216
217
|
can_send_emails: boolean | null;
|
|
217
218
|
payment_methods: PaymentMethod[];
|
|
218
219
|
autopay_payment_types: string[];
|
package/dist/types/auth.d.ts
CHANGED
|
@@ -2,3 +2,9 @@ export interface Tokens {
|
|
|
2
2
|
access_token: string;
|
|
3
3
|
refresh_token: string;
|
|
4
4
|
}
|
|
5
|
+
export declare const AuthState: {
|
|
6
|
+
readonly AUTHENTICATED: 1;
|
|
7
|
+
readonly UNAUTHENTICATED: 2;
|
|
8
|
+
readonly UNKNOWN: 3;
|
|
9
|
+
};
|
|
10
|
+
export type AuthState = typeof AuthState[keyof typeof AuthState];
|
package/dist/types/auth.js
CHANGED