1- import axios from "axios"
1+ import { Lock as MutexLock } from "async-await-mutex-lock"
2+ import axios , { AxiosError } from "axios"
23import {
34 AdminApi ,
45 DeploymentsApi ,
@@ -11,110 +12,71 @@ import {
1112} from "../generated/api"
1213
1314export const useApi = createGlobalState ( ( ) => {
14- const config = useRuntimeConfig ( )
15- const { apiBasePath } = config . public
16-
17- const accessToken = useLocalStorage < string > ( "accessToken" , "" , { writeDefaults : false } )
18- // const refreshToken = useLocalStorage<string>("refreshToken", "", { writeDefaults: false })
15+ const mu = new MutexLock ( )
16+ async function awaitLock ( ) {
17+ if ( mu . isAcquired ( ) ) {
18+ await mu . acquire ( )
19+ mu . release ( )
20+ }
21+ }
1922
2023 const instance = axios . create ( {
21- baseURL : apiBasePath ,
24+ baseURL : useRuntimeConfig ( ) . public . apiBasePath ,
2225 } )
2326
24- instance . interceptors . request . use ( ( config ) => {
27+ const admin = new AdminApi ( undefined , undefined , instance )
28+ const deployments = new DeploymentsApi ( undefined , undefined , instance )
29+ const invoices = new InvoicesApi ( undefined , undefined , instance )
30+ const nodes = new NodesApi ( undefined , undefined , instance )
31+ const notifications = new NotificationsApi ( undefined , undefined , instance )
32+ const twins = new TwinsApi ( undefined , undefined , instance )
33+ const users = new UsersApi ( undefined , undefined , instance )
34+ const workflow = new WorkflowApi ( undefined , undefined , instance )
35+
36+ const accessToken = useLocalStorage < string > ( "accessToken" , "" , { writeDefaults : false } )
37+ const refreshToken = useLocalStorage < string > ( "refreshToken" , "" , { writeDefaults : false } )
38+
39+ instance . interceptors . request . use ( async ( config ) => {
2540 if ( config . unauthenticated ) {
2641 return config
2742 }
2843
2944 // await lock to get access to accessToken
45+ await awaitLock ( )
3046 config . headers . Authorization = `Bearer ${ accessToken . value } `
3147
3248 return config
3349 } )
3450
35- class ApiHelpers {
36- constructor (
37- private readonly admin : AdminApi ,
38- private readonly deployments : DeploymentsApi ,
39- private readonly invoices : InvoicesApi ,
40- private readonly nodes : NodesApi ,
41- private readonly notifications : NotificationsApi ,
42- private readonly twins : TwinsApi ,
43- private readonly users : UsersApi ,
44- private readonly workflow : WorkflowApi
45- ) { }
46-
47- public async awaitWorkflowCompletion ( workflowId : string ) : Promise < boolean > {
48- const { data } = await this . workflow . getWorkflowStatus ( workflowId , {
49- unauthenticated : true ,
50- } )
51-
52- if ( data . data === "failed" ) {
53- return false
54- }
55-
56- if ( data . data === "completed" ) {
57- return true
58- }
59-
60- await new Promise ( ( res ) => setTimeout ( res , 2_000 ) )
61- return this . awaitWorkflowCompletion ( workflowId )
62- }
63- }
64-
65- /*
6651 instance . interceptors . response . use (
6752 ( response ) => response ,
68- (error: AxiosError) => {
69- if (error.response?.status === 401) {
70- // local access token expired, clear it
71- // request new access token
72- // update tokens
73- // unlock access to accessToken
74- // retry request
53+ async ( error ) => {
54+ if (
55+ error instanceof AxiosError &&
56+ error . response &&
57+ error . response . status === 401 &&
58+ error . config &&
59+ "Authorization" in error . config . headers
60+ ) {
61+ if ( ! mu . isAcquired ( ) ) {
62+ await mu . acquire ( )
63+ const { data } = await users . refreshToken (
64+ { refresh_token : refreshToken . value } ,
65+ { unauthenticated : true }
66+ )
67+
68+ accessToken . value = data . data ?. access_token ?? ""
69+ mu . release ( )
70+ } else {
71+ await awaitLock ( )
72+ }
73+
74+ return instance ( error . config )
7575 }
7676
77- // if (error.response?.status === 401) {
78- // // await lock to get access to refreshToken
79- // const newAccessToken = await refreshToken.value
80- // if (newAccessToken) {
81- // accessToken.value = newAccessToken
82- // }
83- // }
84-
8577 return Promise . reject ( error )
8678 }
87- ) */
88-
89- // instance.interceptors.request.use((config) => {
90- // console.log("[request] _internalFlags", config._internalFlags)
91- // return config
92- // })
93-
94- // instance.interceptors.response.use(
95- // (response) => {
96- // console.log("[response] _internalFlags", response.config._internalFlags)
97- // return response
98- // },
99- // (error: AxiosError) => {
100- // console.log(error.config?._internalFlags)
101- // console.log("[response] error", error)
102- // return Promise.reject(error)
103- // }
104- // )
105-
106- // const config = new Configuration({
107- // basePath: "https://staging.myceliumcloud.tf/api/v1",
108- // })
109-
110- const admin = new AdminApi ( undefined , undefined , instance )
111- const deployments = new DeploymentsApi ( undefined , undefined , instance )
112- const invoices = new InvoicesApi ( undefined , undefined , instance )
113- const nodes = new NodesApi ( undefined , undefined , instance )
114- const notifications = new NotificationsApi ( undefined , undefined , instance )
115- const twins = new TwinsApi ( undefined , undefined , instance )
116- const users = new UsersApi ( undefined , undefined , instance )
117- const workflow = new WorkflowApi ( undefined , undefined , instance )
79+ )
11880
11981 return {
12082 admin,
@@ -137,3 +99,33 @@ export const useApi = createGlobalState(() => {
13799 ) ,
138100 }
139101} )
102+
103+ class ApiHelpers {
104+ constructor (
105+ private readonly admin : AdminApi ,
106+ private readonly deployments : DeploymentsApi ,
107+ private readonly invoices : InvoicesApi ,
108+ private readonly nodes : NodesApi ,
109+ private readonly notifications : NotificationsApi ,
110+ private readonly twins : TwinsApi ,
111+ private readonly users : UsersApi ,
112+ private readonly workflow : WorkflowApi
113+ ) { }
114+
115+ public async awaitWorkflowCompletion ( workflowId : string ) : Promise < boolean > {
116+ const { data } = await this . workflow . getWorkflowStatus ( workflowId , {
117+ unauthenticated : true ,
118+ } )
119+
120+ if ( data . data === "failed" ) {
121+ return false
122+ }
123+
124+ if ( data . data === "completed" ) {
125+ return true
126+ }
127+
128+ await new Promise ( ( res ) => setTimeout ( res , 2_000 ) )
129+ return this . awaitWorkflowCompletion ( workflowId )
130+ }
131+ }
0 commit comments