1
- import {
2
- QueryReturnValue
3
- } from '@reduxjs/toolkit/dist/query/baseQueryTypes' ;
1
+ import { QueryReturnValue } from "@reduxjs/toolkit/dist/query/baseQueryTypes"
4
2
import {
5
3
BaseQueryApi ,
6
4
BaseQueryFn ,
7
5
FetchArgs ,
8
6
FetchBaseQueryError ,
9
7
FetchBaseQueryMeta ,
10
- fetchBaseQuery
11
- } from ' @reduxjs/toolkit/query' ;
12
- import Cookies from ' js-cookie' ;
13
- import qs from 'qs' ;
8
+ fetchBaseQuery ,
9
+ } from " @reduxjs/toolkit/query"
10
+ import Cookies from " js-cookie"
11
+ import qs from "qs"
14
12
15
- import {
16
- API_BASE_URL ,
17
- PORTAL_BASE_URL ,
18
- SERVICE_NAME
19
- } from '../env' ;
20
- import {
21
- camelCaseToSnakeCase ,
22
- snakeCaseToCamelCase
23
- } from '../helpers/general' ;
13
+ import { API_BASE_URL , PORTAL_BASE_URL , SERVICE_NAME } from "../env"
14
+ import { camelCaseToSnakeCase , snakeCaseToCamelCase } from "../helpers/general"
24
15
25
16
export type FetchBaseQuery = BaseQueryFn <
26
17
FetchArgs ,
27
18
unknown ,
28
19
FetchBaseQueryError
29
- > ;
20
+ >
30
21
export type Result = QueryReturnValue <
31
22
unknown ,
32
23
FetchBaseQueryError ,
33
24
FetchBaseQueryMeta
34
- > ;
25
+ >
35
26
36
27
export const fetch = fetchBaseQuery ( {
37
28
baseUrl : API_BASE_URL ,
38
- credentials : ' include'
39
- } ) ;
29
+ credentials : " include" ,
30
+ } )
40
31
41
32
export function parseRequestBody ( args : FetchArgs ) : void {
42
33
// Check if the request has a body and its content type is specified.
43
- if ( typeof args . body !== ' object' || args . body === null ) return ;
34
+ if ( typeof args . body !== " object" || args . body === null ) return
44
35
45
- camelCaseToSnakeCase ( args . body ) ;
36
+ camelCaseToSnakeCase ( args . body )
46
37
47
- if ( args . headers !== undefined && ' Content-Type' in args . headers ) {
38
+ if ( args . headers !== undefined && " Content-Type" in args . headers ) {
48
39
// Stringify the request body based on its content type.
49
- switch ( args . headers [ ' Content-Type' ] ) {
50
- case ' application/x-www-form-urlencoded' :
51
- args . body = qs . stringify ( args . body ) ;
52
- break ;
53
- case ' application/json' :
54
- args . body = JSON . stringify ( args . body ) ;
55
- break ;
40
+ switch ( args . headers [ " Content-Type" ] ) {
41
+ case " application/x-www-form-urlencoded" :
42
+ args . body = qs . stringify ( args . body )
43
+ break
44
+ case " application/json" :
45
+ args . body = JSON . stringify ( args . body )
46
+ break
56
47
}
57
48
}
58
49
}
@@ -61,85 +52,91 @@ export async function injectCsrfToken(
61
52
fetch : FetchBaseQuery ,
62
53
args : FetchArgs ,
63
54
api : BaseQueryApi ,
64
- serviceName : string = SERVICE_NAME
55
+ serviceName : string = SERVICE_NAME ,
65
56
) : Promise < void > {
66
57
// Check if the request method is safe.
67
58
// https://datatracker.ietf.org/doc/html/rfc9110.html#section-9.2.1
68
- if ( args . method !== undefined &&
69
- [ 'GET' , 'HEAD' , 'OPTIONS' , 'TRACE' ] . includes ( args . method )
70
- ) return ;
59
+ if (
60
+ args . method !== undefined &&
61
+ [ "GET" , "HEAD" , "OPTIONS" , "TRACE" ] . includes ( args . method )
62
+ )
63
+ return
71
64
72
65
// https://docs.djangoproject.com/en/3.2/ref/csrf/
73
- const cookieName = `${ serviceName } _csrftoken` ;
74
- let csrfToken = Cookies . get ( cookieName ) ;
66
+ const cookieName = `${ serviceName } _csrftoken`
67
+ let csrfToken = Cookies . get ( cookieName )
75
68
if ( csrfToken === undefined ) {
76
69
// Get the CSRF token.
77
- const { error } = await fetch ( {
78
- url : 'csrf/cookie/' ,
79
- method : 'GET'
80
- } , api , { } ) ;
70
+ const { error } = await fetch (
71
+ {
72
+ url : "csrf/cookie/" ,
73
+ method : "GET" ,
74
+ } ,
75
+ api ,
76
+ { } ,
77
+ )
81
78
82
79
// Validate we got the CSRF token.
83
80
if ( error !== undefined ) {
84
- window . location . href = `${ PORTAL_BASE_URL } /error/500` ;
81
+ window . location . href = `${ PORTAL_BASE_URL } /error/500`
85
82
}
86
- csrfToken = Cookies . get ( cookieName ) ;
83
+ csrfToken = Cookies . get ( cookieName )
87
84
if ( csrfToken === undefined ) {
88
- window . location . href = `${ PORTAL_BASE_URL } /error/500` ;
85
+ window . location . href = `${ PORTAL_BASE_URL } /error/500`
89
86
}
90
- } ;
87
+ }
91
88
92
89
// Inject the CSRF token.
93
90
args . body = {
94
- ...( typeof args . body !== ' object' || args . body === null ? { } : args . body ) ,
95
- csrfmiddlewaretoken : csrfToken
96
- } ;
91
+ ...( typeof args . body !== " object" || args . body === null ? { } : args . body ) ,
92
+ csrfmiddlewaretoken : csrfToken ,
93
+ }
97
94
}
98
95
99
96
export function handleResponseError ( result : Result ) : void {
100
97
// Check if errors.
101
- if ( result . error === undefined ) return ;
98
+ if ( result . error === undefined ) return
102
99
103
- if ( result . error . status === 400 &&
104
- typeof result . error . data === 'object' &&
100
+ if (
101
+ result . error . status === 400 &&
102
+ typeof result . error . data === "object" &&
105
103
result . error . data !== null
106
104
) {
107
105
// Parse the error's data from snake_case to camelCase.
108
- snakeCaseToCamelCase ( result . error . data ) ;
106
+ snakeCaseToCamelCase ( result . error . data )
109
107
} else if ( result . error . status === 401 ) {
110
108
// TODO: redirect to appropriate login page based on user type.
111
- window . location . href = `${ PORTAL_BASE_URL } /login/teacher` ;
109
+ window . location . href = `${ PORTAL_BASE_URL } /login/teacher`
112
110
} else {
113
111
// Catch-all error pages by status-code.
114
- window . location . href = `${ PORTAL_BASE_URL } /error/${ [
115
- 403 ,
116
- 404
117
- ] . includes ( result . error . status as number )
118
- ? result . error . status
119
- : 500 } `;
112
+ window . location . href = `${ PORTAL_BASE_URL } /error/${
113
+ [ 403 , 404 ] . includes ( result . error . status as number )
114
+ ? result . error . status
115
+ : 500
116
+ } `
120
117
}
121
118
}
122
119
123
120
export function parseResponseBody ( result : Result ) : void {
124
121
// Parse the response's data from snake_case to camelCase.
125
- if ( typeof result . data !== ' object' || result . data === null ) return ;
122
+ if ( typeof result . data !== " object" || result . data === null ) return
126
123
127
- snakeCaseToCamelCase ( result . data ) ;
124
+ snakeCaseToCamelCase ( result . data )
128
125
}
129
126
130
127
const baseQuery : FetchBaseQuery = async ( args , api , extraOptions ) => {
131
- await injectCsrfToken ( fetch , args , api ) ;
128
+ await injectCsrfToken ( fetch , args , api )
132
129
133
- parseRequestBody ( args ) ;
130
+ parseRequestBody ( args )
134
131
135
132
// Send the HTTP request and fetch the response.
136
- const result = await fetch ( args , api , extraOptions ) ;
133
+ const result = await fetch ( args , api , extraOptions )
137
134
138
- handleResponseError ( result ) ;
135
+ handleResponseError ( result )
139
136
140
- parseResponseBody ( result ) ;
137
+ parseResponseBody ( result )
141
138
142
- return result ;
143
- } ;
139
+ return result
140
+ }
144
141
145
- export default baseQuery ;
142
+ export default baseQuery
0 commit comments