Debug issues with work item CRUD
This commit is contained in:
@@ -1,42 +1,42 @@
|
||||
import EventEmitter from 'eventemitter3'
|
||||
import io from 'socket.io-client'
|
||||
import { AsyncStorage } from 'react-native'
|
||||
import EventEmitter from "eventemitter3"
|
||||
import io from "socket.io-client"
|
||||
import { AsyncStorage } from "react-native"
|
||||
|
||||
const authTokenName = 'AuthToken'
|
||||
const authTokenName = "AuthToken"
|
||||
let baseURL = null
|
||||
let apiPath = null
|
||||
//
|
||||
if (__DEV__) {
|
||||
const localIPAddr = process.env.LOCAL_IP_ADDR
|
||||
|
||||
baseURL = `http://${localIPAddr || 'localhost'}:3001`
|
||||
apiPath = ''
|
||||
baseURL = `http://${localIPAddr || "localhost"}:3001`
|
||||
apiPath = ""
|
||||
} else {
|
||||
baseURL = 'https://dar.kss.us.com'
|
||||
apiPath = '/api'
|
||||
baseURL = "https://dar.kss.us.com"
|
||||
apiPath = "/api"
|
||||
}
|
||||
|
||||
class NetworkError extends Error {
|
||||
constructor(message) {
|
||||
super(message)
|
||||
this.name = this.constructor.name
|
||||
if (typeof Error.captureStackTrace === 'function') {
|
||||
if (typeof Error.captureStackTrace === "function") {
|
||||
Error.captureStackTrace(this, this.constructor)
|
||||
} else {
|
||||
this.stack = (new Error(message)).stack
|
||||
this.stack = new Error(message).stack
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class APIError extends Error {
|
||||
constructor(status, message) {
|
||||
super(message || '')
|
||||
super(message || "")
|
||||
this.status = status || 500
|
||||
this.name = this.constructor.name
|
||||
if (typeof Error.captureStackTrace === 'function') {
|
||||
if (typeof Error.captureStackTrace === "function") {
|
||||
Error.captureStackTrace(this, this.constructor)
|
||||
} else {
|
||||
this.stack = (new Error(message)).stack
|
||||
this.stack = new Error(message).stack
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,39 +46,42 @@ class API extends EventEmitter {
|
||||
super()
|
||||
this.user = { pending: true }
|
||||
|
||||
AsyncStorage.getItem(authTokenName).then((token) => {
|
||||
if (!token) {
|
||||
return Promise.reject()
|
||||
}
|
||||
AsyncStorage.getItem(authTokenName)
|
||||
.then((token) => {
|
||||
if (!token) {
|
||||
return Promise.reject()
|
||||
}
|
||||
|
||||
this.token = token
|
||||
return this.who()
|
||||
}).then((user) => {
|
||||
this.user = user
|
||||
this.connectSocket()
|
||||
this.emit('login')
|
||||
}).catch((err) => {
|
||||
console.error(err)
|
||||
AsyncStorage.removeItem(authTokenName)
|
||||
this.token = null
|
||||
this.user = {}
|
||||
this.socket = null
|
||||
this.emit('logout')
|
||||
})
|
||||
this.token = token
|
||||
return this.who()
|
||||
})
|
||||
.then((user) => {
|
||||
this.user = user
|
||||
this.connectSocket()
|
||||
this.emit("login")
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err)
|
||||
AsyncStorage.removeItem(authTokenName)
|
||||
this.token = null
|
||||
this.user = {}
|
||||
this.socket = null
|
||||
this.emit("logout")
|
||||
})
|
||||
}
|
||||
|
||||
connectSocket() {
|
||||
this.socket = io(baseURL, {
|
||||
path: apiPath + '/socketio',
|
||||
path: apiPath + "/socketio",
|
||||
query: {
|
||||
auth_token: this.token
|
||||
}
|
||||
auth_token: this.token,
|
||||
},
|
||||
})
|
||||
this.socket.on('disconnect', (reason) => {
|
||||
this.socket.on("disconnect", (reason) => {
|
||||
// Could happen if the auth_token is bad
|
||||
this.socket = null
|
||||
})
|
||||
this.socket.on('notify', (message) => {
|
||||
this.socket.on("notify", (message) => {
|
||||
const { eventName, eventData } = message
|
||||
|
||||
// Filter the few massages that affect our cached user data to avoid a server round trip
|
||||
@@ -109,22 +112,27 @@ class API extends EventEmitter {
|
||||
|
||||
makeImageUrl(id, size) {
|
||||
if (id) {
|
||||
return apiPath + '/assets/' + id + '?access_token=' + this.token
|
||||
return apiPath + "/assets/" + id + "?access_token=" + this.token
|
||||
} else if (size && size.width && size.height) {
|
||||
return `${apiPath}/placeholders/${size.width}x${size.height}?access_token=${this.token}`
|
||||
return `${apiPath}/placeholders/${size.width}x${
|
||||
size.height
|
||||
}?access_token=${this.token}`
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
makeAssetUrl(id) {
|
||||
return id ? apiPath + '/assets/' + id + '?access_token=' + this.token : null
|
||||
return id ? apiPath + "/assets/" + id + "?access_token=" + this.token : null
|
||||
}
|
||||
|
||||
static makeParams(params) {
|
||||
return params ? '?' + Object.keys(params).map((key) => (
|
||||
[key, params[key]].map(encodeURIComponent).join('=')
|
||||
)).join('&') : ''
|
||||
return params
|
||||
? "?" +
|
||||
Object.keys(params)
|
||||
.map((key) => [key, params[key]].map(encodeURIComponent).join("="))
|
||||
.join("&")
|
||||
: ""
|
||||
}
|
||||
|
||||
request(method, path, requestBody, requestOptions) {
|
||||
@@ -132,80 +140,88 @@ class API extends EventEmitter {
|
||||
var promise = new Promise((resolve, reject) => {
|
||||
let fetchOptions = {
|
||||
method: method,
|
||||
mode: 'cors',
|
||||
cache: 'no-store'
|
||||
mode: "cors",
|
||||
cache: "no-store",
|
||||
}
|
||||
let headers = new Headers()
|
||||
if (this.token) {
|
||||
headers.set('Authorization', 'Bearer ' + this.token)
|
||||
headers.set("Authorization", "Bearer " + this.token)
|
||||
}
|
||||
if (method === 'POST' || method === 'PUT') {
|
||||
if (method === "POST" || method === "PUT") {
|
||||
if (requestOptions.binary) {
|
||||
headers.set('Content-Type', 'application/octet-stream')
|
||||
headers.set('Content-Length', requestOptions.binary.length)
|
||||
headers.set('Range', 'byte ' + requestOptions.binary.offset)
|
||||
headers.set("Content-Type", "application/octet-stream")
|
||||
headers.set("Content-Length", requestOptions.binary.length)
|
||||
headers.set("Range", "byte " + requestOptions.binary.offset)
|
||||
fetchOptions.body = requestBody
|
||||
} else {
|
||||
headers.set('Content-Type', 'application/json')
|
||||
headers.set("Content-Type", "application/json")
|
||||
fetchOptions.body = JSON.stringify(requestBody)
|
||||
}
|
||||
}
|
||||
fetchOptions.headers = headers
|
||||
fetch(this.apiURL + path, fetchOptions).then((res) => {
|
||||
return Promise.all([ Promise.resolve(res), (requestOptions.binary && method === 'GET') ? res.blob() : res.json() ])
|
||||
}).then((arr) => {
|
||||
let [ res, responseBody ] = arr
|
||||
if (res.ok) {
|
||||
if (requestOptions.wantHeaders) {
|
||||
resolve({ body: responseBody, headers: res.headers })
|
||||
fetch(this.apiURL + path, fetchOptions)
|
||||
.then((res) => {
|
||||
return Promise.all([
|
||||
Promise.resolve(res),
|
||||
requestOptions.binary && method === "GET" ? res.blob() : res.json(),
|
||||
])
|
||||
})
|
||||
.then((arr) => {
|
||||
let [res, responseBody] = arr
|
||||
if (res.ok) {
|
||||
if (requestOptions.wantHeaders) {
|
||||
resolve({ body: responseBody, headers: res.headers })
|
||||
} else {
|
||||
resolve(responseBody)
|
||||
}
|
||||
} else {
|
||||
resolve(responseBody)
|
||||
reject(new APIError(res.status, responseBody.message))
|
||||
}
|
||||
} else {
|
||||
reject(new APIError(res.status, responseBody.message))
|
||||
}
|
||||
}).catch((error) => {
|
||||
reject(new NetworkError(error.message))
|
||||
})
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(new NetworkError(error.message))
|
||||
})
|
||||
})
|
||||
return promise
|
||||
}
|
||||
|
||||
post(path, requestBody, options) {
|
||||
return this.request('POST', path, requestBody, options)
|
||||
return this.request("POST", path, requestBody, options)
|
||||
}
|
||||
put(path, requestBody, options) {
|
||||
return this.request('PUT', path, requestBody, options)
|
||||
return this.request("PUT", path, requestBody, options)
|
||||
}
|
||||
get(path, options) {
|
||||
return this.request('GET', path, options)
|
||||
return this.request("GET", path, options)
|
||||
}
|
||||
delete(path, options) {
|
||||
return this.request('DELETE', path, options)
|
||||
return this.request("DELETE", path, options)
|
||||
}
|
||||
|
||||
login(email, password, remember) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.post('/auth/login', { email, password }, { wantHeaders: true }).then((response) => {
|
||||
// Save bearer token for later use
|
||||
const authValue = response.headers.get('Authorization')
|
||||
const [ scheme, token ] = authValue.split(' ')
|
||||
this.post("/auth/login", { email, password }, { wantHeaders: true })
|
||||
.then((response) => {
|
||||
// Save bearer token for later use
|
||||
const authValue = response.headers.get("Authorization")
|
||||
const [scheme, token] = authValue.split(" ")
|
||||
|
||||
if (scheme !== 'Bearer' || !token) {
|
||||
reject(new APIError('Unexpected Authorization scheme or token'))
|
||||
}
|
||||
if (scheme !== "Bearer" || !token) {
|
||||
reject(new APIError("Unexpected Authorization scheme or token"))
|
||||
}
|
||||
|
||||
if (remember) {
|
||||
AsyncStorage.setItem(authTokenName, token)
|
||||
}
|
||||
this.token = token
|
||||
this.user = response.body
|
||||
this.connectSocket()
|
||||
this.emit('login')
|
||||
resolve(response.body)
|
||||
}).catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
if (remember) {
|
||||
AsyncStorage.setItem(authTokenName, token)
|
||||
}
|
||||
this.token = token
|
||||
this.user = response.body
|
||||
this.connectSocket()
|
||||
this.emit("login")
|
||||
resolve(response.body)
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
logout() {
|
||||
@@ -215,61 +231,63 @@ class API extends EventEmitter {
|
||||
this.token = null
|
||||
this.user = {}
|
||||
this.disconnectSocket()
|
||||
this.emit('logout')
|
||||
this.emit("logout")
|
||||
}
|
||||
return this.delete('/auth/login').then(cb, cb)
|
||||
return this.delete("/auth/login").then(cb, cb)
|
||||
}
|
||||
who() {
|
||||
return this.get('/auth/who')
|
||||
return this.get("/auth/who")
|
||||
}
|
||||
|
||||
getUser(_id) {
|
||||
return this.get('/users/' + _id)
|
||||
return this.get("/users/" + _id)
|
||||
}
|
||||
listUsers() {
|
||||
return this.get('/users')
|
||||
return this.get("/users")
|
||||
}
|
||||
createUser(user) {
|
||||
return this.post('/users', user)
|
||||
return this.post("/users", user)
|
||||
}
|
||||
updateUser(user) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.put('/users', user).then((user) => {
|
||||
// If we just updated ourselves, update the internal cached copy
|
||||
if (user._id === this.user._id) {
|
||||
this.user = user
|
||||
this.emit('login')
|
||||
}
|
||||
resolve(user)
|
||||
}).catch((reason) => {
|
||||
reject(reason)
|
||||
})
|
||||
this.put("/users", user)
|
||||
.then((user) => {
|
||||
// If we just updated ourselves, update the internal cached copy
|
||||
if (user._id === this.user._id) {
|
||||
this.user = user
|
||||
this.emit("login")
|
||||
}
|
||||
resolve(user)
|
||||
})
|
||||
.catch((reason) => {
|
||||
reject(reason)
|
||||
})
|
||||
})
|
||||
}
|
||||
deleteUser(_id) {
|
||||
return this.delete('/users/' + _id)
|
||||
return this.delete("/users/" + _id)
|
||||
}
|
||||
enterRoom(roomName) {
|
||||
return this.put('/users/enter-room/' + (roomName || ''))
|
||||
return this.put("/users/enter-room/" + (roomName || ""))
|
||||
}
|
||||
leaveRoom() {
|
||||
return this.put('/users/leave-room')
|
||||
return this.put("/users/leave-room")
|
||||
}
|
||||
|
||||
getWorkItem(_id) {
|
||||
return this.get('/workitems/' + _id)
|
||||
return this.get("/workitems/" + _id)
|
||||
}
|
||||
listWorkItems() {
|
||||
return this.get('/workitems')
|
||||
return this.get("/workitems")
|
||||
}
|
||||
createWorkItem(workItem) {
|
||||
return this.post('/workitems', workItem)
|
||||
return this.post("/workitems", workItem)
|
||||
}
|
||||
updateWorkItem(workItem) {
|
||||
return this.put('/workitems', workItem)
|
||||
return this.put("/workitems", workItem)
|
||||
}
|
||||
deleteWorkItem(_id) {
|
||||
return this.delete('/workitems/' + _id)
|
||||
return this.delete("/workitems/" + _id)
|
||||
}
|
||||
|
||||
upload(file, progressCallback) {
|
||||
@@ -285,36 +303,40 @@ class API extends EventEmitter {
|
||||
const buffer = e.target.result
|
||||
const bytesRead = buffer.byteLength
|
||||
|
||||
this.post('/assets/upload/' + uploadId, buffer, {
|
||||
binary: { offset: chunk * chunkSize, length: bytesRead }
|
||||
}).then((uploadData) => {
|
||||
chunk++
|
||||
if (!progressCallback(uploadData)) {
|
||||
return Promise.reject(new Error('Upload was canceled'))
|
||||
}
|
||||
if (chunk < numberOfChunks) {
|
||||
let start = chunk * chunkSize
|
||||
let end = Math.min(fileSize, start + chunkSize)
|
||||
reader.readAsArrayBuffer(file.slice(start, end))
|
||||
} else {
|
||||
resolve(uploadData)
|
||||
}
|
||||
}).catch((err) => {
|
||||
reject(err)
|
||||
this.post("/assets/upload/" + uploadId, buffer, {
|
||||
binary: { offset: chunk * chunkSize, length: bytesRead },
|
||||
})
|
||||
.then((uploadData) => {
|
||||
chunk++
|
||||
if (!progressCallback(uploadData)) {
|
||||
return Promise.reject(new Error("Upload was canceled"))
|
||||
}
|
||||
if (chunk < numberOfChunks) {
|
||||
let start = chunk * chunkSize
|
||||
let end = Math.min(fileSize, start + chunkSize)
|
||||
reader.readAsArrayBuffer(file.slice(start, end))
|
||||
} else {
|
||||
resolve(uploadData)
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
}
|
||||
|
||||
this.post('/assets/upload', {
|
||||
this.post("/assets/upload", {
|
||||
fileName: file.name,
|
||||
fileSize,
|
||||
contentType: file.type,
|
||||
numberOfChunks
|
||||
}).then((uploadData) => {
|
||||
uploadId = uploadData.uploadId
|
||||
reader.readAsArrayBuffer(file.slice(0, chunkSize))
|
||||
}).catch((err) => {
|
||||
reject(err)
|
||||
numberOfChunks,
|
||||
})
|
||||
.then((uploadData) => {
|
||||
uploadId = uploadData.uploadId
|
||||
reader.readAsArrayBuffer(file.slice(0, chunkSize))
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user