case sensitive!
This commit is contained in:
97
src/utils/ApiClient.js
Normal file
97
src/utils/ApiClient.js
Normal file
@@ -0,0 +1,97 @@
|
||||
import _map from 'lodash/map';
|
||||
|
||||
import auth from './auth';
|
||||
import constants from '../constants';
|
||||
|
||||
class ApiClient {
|
||||
constructor(options = {}) {
|
||||
this.baseUrl = options.baseUrl || constants.API_BASE_URL;
|
||||
this.userAgent = options.userAgent || constants.API_USER_AGENT;
|
||||
}
|
||||
|
||||
fetch = (path, method, data) => {
|
||||
let body;
|
||||
let modifiedPath;
|
||||
|
||||
if (method === 'GET') {
|
||||
modifiedPath = path + this.constructQueryString(data);
|
||||
} else if (method === 'POST' || method === 'PUT') {
|
||||
body = JSON.stringify(data);
|
||||
}
|
||||
|
||||
// Construct headers
|
||||
const headers = new Headers({
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'User-Agent': this.userAgent,
|
||||
});
|
||||
if (auth.getToken()) {
|
||||
headers.set('Authorization', `Bearer ${auth.getToken()}`);
|
||||
}
|
||||
|
||||
// Construct request
|
||||
const request = fetch(this.baseUrl + (modifiedPath || path), {
|
||||
method,
|
||||
body,
|
||||
headers,
|
||||
redirect: 'follow',
|
||||
});
|
||||
|
||||
// Handle request promises and return a new promise
|
||||
return new Promise((resolve, reject) => {
|
||||
request
|
||||
.then((response) => {
|
||||
// Handle successful responses
|
||||
if (response.status >= 200 && response.status < 300) {
|
||||
return response;
|
||||
}
|
||||
|
||||
// Handle 401, log out user
|
||||
if (response.status === 401) {
|
||||
auth.logout(); // replace with dispatch+action
|
||||
}
|
||||
|
||||
// Handle failed responses
|
||||
let error;
|
||||
try {
|
||||
// Expect API to return JSON
|
||||
error = JSON.parse(response);
|
||||
} catch (e) {
|
||||
// Expect call to fail without JSON response
|
||||
error = { error: response.statusText };
|
||||
}
|
||||
|
||||
error.statusCode = response.status;
|
||||
error.response = response;
|
||||
reject(error);
|
||||
})
|
||||
.then((response) => {
|
||||
return response.json();
|
||||
})
|
||||
.then((json) => {
|
||||
resolve(json);
|
||||
})
|
||||
.catch(() => {
|
||||
reject({ error: 'Unknown error' });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
post = (path, data) => {
|
||||
return this.fetch(path, 'POST', data);
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
||||
constructQueryString = (data) => {
|
||||
return _map(data, (v, k) => {
|
||||
return `${encodeURIComponent(k)}=${encodeURIComponent(v)}`;
|
||||
}).join('&');
|
||||
};
|
||||
}
|
||||
|
||||
export default ApiClient;
|
||||
|
||||
// In case you don't want to always initiate, just import with `import { client } ...`
|
||||
const client = new ApiClient();
|
||||
export { client };
|
||||
3
src/utils/History.js
Normal file
3
src/utils/History.js
Normal file
@@ -0,0 +1,3 @@
|
||||
// https://github.com/reactjs/react-router/blob/master/docs/guides/NavigatingOutsideOfComponents.md
|
||||
import browserHistory from 'react-router/lib/browserHistory';
|
||||
export default browserHistory;
|
||||
40
src/utils/Markdown.js
Normal file
40
src/utils/Markdown.js
Normal file
@@ -0,0 +1,40 @@
|
||||
import toMd from 'to-markdown';
|
||||
|
||||
const liConverter = {
|
||||
filter: 'li',
|
||||
replacement: (content, node) => {
|
||||
// Change `replace(/\n/gm, '\n ')` to work with our case here :/
|
||||
content = content.replace(/^\s+/, '').replace(/\n/gm, '\n ');
|
||||
var prefix = '- ';
|
||||
var parent = node.parentNode;
|
||||
var index = Array.prototype.indexOf.call(parent.children, node) + 1;
|
||||
|
||||
prefix = /ol/i.test(parent.nodeName) ? index + '. ' : '- ';
|
||||
return prefix + content;
|
||||
}
|
||||
};
|
||||
|
||||
const ulConverter = {
|
||||
filter: ['ul', 'ol'],
|
||||
replacement: function (content, node) {
|
||||
var strings = [];
|
||||
for (var i = 0; i < node.childNodes.length; i++) {
|
||||
strings.push(node.childNodes[i]._replacement);
|
||||
}
|
||||
|
||||
if (/li/i.test(node.parentNode.nodeName)) {
|
||||
return '\n' + strings.join('\n');
|
||||
}
|
||||
return '\n\n' + strings.join('\n') + '\n\n';
|
||||
}
|
||||
};
|
||||
|
||||
export function toMarkdown(html) {
|
||||
const markdown = toMd(
|
||||
html, {
|
||||
gfm: true,
|
||||
converters: [ liConverter, ulConverter ],
|
||||
},
|
||||
);
|
||||
return markdown;
|
||||
}
|
||||
19
src/utils/auth.js
Normal file
19
src/utils/auth.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import constants from '../constants';
|
||||
|
||||
export default {
|
||||
setToken(token) {
|
||||
localStorage.setItem(constants.JWT_STORE_KEY, token);
|
||||
},
|
||||
|
||||
getToken() {
|
||||
return localStorage.getItem(constants.JWT_STORE_KEY);
|
||||
},
|
||||
|
||||
logout() {
|
||||
localStorage.removeItem(constants.JWT_STORE_KEY);
|
||||
},
|
||||
|
||||
loggedIn() {
|
||||
return !!localStorage.getItem(constants.JWT_STORE_KEY);
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user