1 | import toPlainObject from 'lodash/toPlainObject';
|
2 | import hash from 'hash-obj';
|
3 |
|
4 | import * as Cookies from 'es-cookie';
|
5 | import QuickLRU from 'quick-lru';
|
6 |
|
7 | const getCacheKey = config => {
|
8 | let headers = config.headers;
|
9 |
|
10 | if (config.headers.common) {
|
11 | headers = Object.assign(
|
12 | {},
|
13 | config.headers.common,
|
14 | config.headers[config.method]
|
15 | );
|
16 | }
|
17 |
|
18 | const hashObj = {
|
19 | method: config.method,
|
20 | url: config.url.replace(config.baseURL, ''),
|
21 | headers,
|
22 | params: config.params,
|
23 | data: config.data,
|
24 | };
|
25 |
|
26 | return hash(toPlainObject(hashObj));
|
27 | };
|
28 |
|
29 |
|
30 |
|
31 | const cacheGet = (cache, key, maxAge) => cache.get(key);
|
32 |
|
33 |
|
34 |
|
35 | const cacheSet = (cache, key, value, maxAge) => cache.set(key, value);
|
36 |
|
37 | export default ({ $axios, env, store, req, res, query }) => {
|
38 | env = Object.assign(
|
39 | {
|
40 | CACHE_ENABLED: true,
|
41 | CACHE_MAX_AGE: 30 * 60 * 1000,
|
42 |
|
43 |
|
44 | CACHE_MAX_SIZE: 1000,
|
45 | },
|
46 | env
|
47 | );
|
48 |
|
49 | let cache;
|
50 |
|
51 | if (env.CACHE_ENABLED) {
|
52 | cache = new QuickLRU({
|
53 | maxSize: env.CACHE_MAX_SIZE,
|
54 | });
|
55 | }
|
56 |
|
57 | $axios.onRequest(
|
58 | config => {
|
59 | let cookies = {};
|
60 | if (req && req.headers.cookie) {
|
61 | cookies = Cookies.parse(req.headers.cookie);
|
62 | }
|
63 |
|
64 | if (res && query.apiToken) {
|
65 | res.setHeader(
|
66 | 'Set-Cookie',
|
67 | Cookies.encode('apiToken', query.apiToken, { maxAge: 3600 })
|
68 | );
|
69 | }
|
70 |
|
71 | config.headers.common['x-api-token'] =
|
72 | query.apiToken || cookies.apiToken || env.API_TOKEN;
|
73 |
|
74 | const role = store.state.role || env.ROLE;
|
75 |
|
76 | if (env.CACHE_ENABLED && role === 'guest') {
|
77 | const key = getCacheKey(config);
|
78 |
|
79 | if (cache.has(key)) {
|
80 | const data = cacheGet(cache, key);
|
81 |
|
82 | config.data = data;
|
83 |
|
84 |
|
85 |
|
86 | config.adapter = () =>
|
87 | Promise.resolve({
|
88 | data,
|
89 | status: config.status,
|
90 | statusText: config.statusText,
|
91 | headers: config.headers,
|
92 | config,
|
93 | request: config,
|
94 | });
|
95 | }
|
96 | }
|
97 |
|
98 | return config;
|
99 | },
|
100 | error => {
|
101 |
|
102 | console.error(error);
|
103 | return Promise.reject(error);
|
104 | }
|
105 | );
|
106 |
|
107 | $axios.onResponse(
|
108 | response => {
|
109 | if (response.headers['x-role']) {
|
110 | store.commit('ROLE', response.headers['x-role']);
|
111 | }
|
112 |
|
113 | const role = store.state.role || env.ROLE;
|
114 |
|
115 | if (env.CACHE_ENABLED && role === 'guest') {
|
116 | let maxAge = env.CACHE_MAX_AGE;
|
117 |
|
118 | try {
|
119 | maxAge = JSON.parse(response.config.params.__cache);
|
120 | } catch (error) {
|
121 |
|
122 | }
|
123 |
|
124 | if (maxAge !== false) {
|
125 | const key = getCacheKey(response.config);
|
126 | cacheSet(cache, key, response.data, maxAge);
|
127 | }
|
128 | }
|
129 |
|
130 | return response;
|
131 | },
|
132 | error => {
|
133 |
|
134 | console.error(error);
|
135 | return Promise.reject(error);
|
136 | }
|
137 | );
|
138 | };
|