UNPKG

7.27 kBJavaScriptView Raw
1
2export default {
3
4 headers: null,
5 method: 'get',
6 mime: {
7 xml: 'text/xml; charset=utf-8',
8 html: 'text/html; charset=utf-8',
9 text: 'text/plain; charset=utf-8',
10 json: 'application/json; charset=utf-8',
11 js: 'application/javascript; charset=utf-8'
12 },
13
14 async setup (options) {
15 options = options || {};
16 this.path = options.path;
17 this.origin = options.origin;
18 this.request = options.request;
19 this.response = options.response;
20 this.acceptType = options.acceptType;
21 this.credentials = options.credentials;
22 this.contentType = options.contentType;
23 this.responseType = options.responseType;
24 this.method = options.method || this.method;
25 this.headers = options.headers || this.headers;
26 },
27
28 async serialize (data) {
29 let query = '';
30
31 for (let name in data) {
32 query = query.length > 0 ? query + '&' : query;
33 query = query + encodeURIComponent(name) + '=' + encodeURIComponent(data[name]);
34 }
35
36 return query;
37 },
38
39 async fetch (options) {
40 const data = Object.assign({}, options);
41
42 data.path = data.path || this.path;
43 data.origin = data.origin || this.origin;
44
45 if (data.path && typeof data.path === 'string' && data.path.charAt(0) === '/') data.path = data.path.slice(1);
46 if (data.origin && typeof data.origin === 'string' && data.origin.charAt(data.origin.length-1) === '/') data.origin = data.origin.slice(0, -1);
47 if (data.path && data.origin && !data.url) data.url = data.origin + '/' + data.path;
48
49 if (!data.method) throw new Error('Oxe.fetcher - requires method option');
50 if (!data.url) throw new Error('Oxe.fetcher - requires url or origin and path option');
51
52 if (!data.headers && this.headers) data.headers = this.headers;
53 if (typeof data.method === 'string') data.method = data.method.toUpperCase() || this.method;
54
55 if (!data.acceptType && this.acceptType) data.acceptType = this.acceptType;
56 if (!data.contentType && this.contentType) data.contentType = this.contentType;
57 if (!data.responseType && this.responseType) data.responseType = this.responseType;
58
59 // omit, same-origin, or include
60 if (!data.credentials && this.credentials) data.credentials = this.credentials;
61
62 // cors, no-cors, or same-origin
63 if (!data.mode && this.mode) data.mode = this.mode;
64
65 // default, no-store, reload, no-cache, force-cache, or only-if-cached
66 if (!data.cache && this.cache) data.cahce = this.cache;
67
68 // follow, error, or manual
69 if (!data.redirect && this.redirect) data.redirect = this.redirect;
70
71 // no-referrer, client, or a URL
72 if (!data.referrer && this.referrer) data.referrer = this.referrer;
73
74 // no-referrer, no-referrer-when-downgrade, origin, origin-when-cross-origin, unsafe-url
75 if (!data.referrerPolicy && this.referrerPolicy) data.referrerPolicy = this.referrerPolicy;
76
77 if (!data.signal && this.signal) data.signal = this.signal;
78 if (!data.integrity && this.integrity) data.integrity = this.integrity;
79 if (!data.keepAlive && this.keepAlive) data.keepAlive = this.keepAlive;
80
81 if (data.contentType) {
82 data.headers = data.headers || {};
83 switch (data.contentType) {
84 case 'js': data.headers['Content-Type'] = this.mime.js; break;
85 case 'xml': data.headers['Content-Type'] = this.mime.xml; break;
86 case 'html': data.headers['Content-Type'] = this.mime.html; break;
87 case 'json': data.headers['Content-Type'] = this.mime.json; break;
88 default: data.headers['Content-Type'] = data.contentType;
89 }
90 }
91
92 if (data.acceptType) {
93 data.headers = data.headers || {};
94 switch (data.acceptType) {
95 case 'js': data.headers['Accept'] = this.mime.js; break;
96 case 'xml': data.headers['Accept'] = this.mime.xml; break;
97 case 'html': data.headers['Accept'] = this.mime.html; break;
98 case 'json': data.headers['Accept'] = this.mime.json; break;
99 default: data.headers['Accept'] = data.acceptType;
100 }
101 }
102
103 // IDEA for auth tokens
104 // if (data.headers) {
105 // for (let name in data.headers) {
106 // if (typeof data.headers[name] === 'function') {
107 // data.headers[name] = await data.headers[name]();
108 // }
109 // }
110 // }
111
112 if (typeof this.request === 'function') {
113 const copy = Object.assign({}, data);
114 const result = await this.request(copy);
115
116 if (result === false) {
117 return data;
118 }
119
120 if (typeof result === 'object') {
121 Object.assign(data, result);
122 }
123
124 }
125
126 if (data.body) {
127
128 if (data.method === 'GET') {
129 data.url = data.url + '?' + await this.serialize(data.body);
130 } else if (data.contentType === 'json') {
131 data.body = JSON.stringify(data.body);
132 }
133
134 }
135
136 const fetched = await window.fetch(data.url, Object.assign({}, data));
137
138 data.code = fetched.status;
139 data.message = fetched.statusText;
140
141 if (!data.responseType) {
142 data.body = fetched.body;
143 } else {
144 data.body = await fetched[
145 data.responseType === 'buffer' ? 'arrayBuffer' : data.responseType
146 ]();
147 }
148
149 if (this.response) {
150 const copy = Object.assign({}, data);
151 const result = await this.response(copy);
152
153 if (result === false) {
154 return data;
155 }
156
157 if (typeof result === 'object') {
158 Object.assign(data, result);
159 }
160
161 }
162
163 return data;
164 },
165
166 async post (data) {
167 data = typeof data === 'string' ? { url: data } : data;
168 data.method = 'post';
169 return this.fetch(data);
170 },
171
172 async get (data) {
173 data = typeof data === 'string' ? { url: data } : data;
174 data.method = 'get';
175 return this.fetch(data);
176 },
177
178 async put (data) {
179 data = typeof data === 'string' ? { url: data } : data;
180 data.method = 'put';
181 return this.fetch(data);
182 },
183
184 async head (data) {
185 data = typeof data === 'string' ? { url: data } : data;
186 data.method = 'head';
187 return this.fetch(data);
188 },
189
190 async patch (data) {
191 data = typeof data === 'string' ? { url: data } : data;
192 data.method = 'patch';
193 return this.fetch(data);
194 },
195
196 async delete (data) {
197 data = typeof data === 'string' ? { url: data } : data;
198 data.method = 'delete';
199 return this.fetch(data);
200 },
201
202 async options (data) {
203 data = typeof data === 'string' ? { url: data } : data;
204 data.method = 'options';
205 return this.fetch(data);
206 },
207
208 async connect (data) {
209 data = typeof data === 'string' ? { url: data } : data;
210 data.method = 'connect';
211 return this.fetch(data);
212 }
213
214};